2
* mxl111sf-gpio.c - driver for the MaxLinear MXL111SF
4
* Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
#include "mxl111sf-gpio.h"
22
#include "mxl111sf-i2c.h"
25
/* ------------------------------------------------------------------------- */
27
#define MXL_GPIO_MUX_REG_0 0x84
28
#define MXL_GPIO_MUX_REG_1 0x89
29
#define MXL_GPIO_MUX_REG_2 0x82
31
#define MXL_GPIO_DIR_INPUT 0
32
#define MXL_GPIO_DIR_OUTPUT 1
35
static int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val)
40
mxl_debug_adv("(%d, %d)", pin, val);
42
if ((pin > 0) && (pin < 8)) {
43
ret = mxl111sf_read_reg(state, 0x19, &tmp);
46
tmp &= ~(1 << (pin - 1));
47
tmp |= (val << (pin - 1));
48
ret = mxl111sf_write_reg(state, 0x19, tmp);
51
} else if (pin <= 10) {
54
ret = mxl111sf_read_reg(state, 0x30, &tmp);
57
tmp &= ~(1 << (pin - 3));
58
tmp |= (val << (pin - 3));
59
ret = mxl111sf_write_reg(state, 0x30, tmp);
68
static int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val)
73
mxl_debug("(0x%02x)", pin);
82
ret = mxl111sf_read_reg(state, 0x23, &tmp);
85
*val = (tmp >> (pin + 4)) & 0x01;
91
ret = mxl111sf_read_reg(state, 0x2f, &tmp);
94
*val = (tmp >> pin) & 0x01;
99
ret = mxl111sf_read_reg(state, 0x22, &tmp);
102
*val = (tmp >> (pin - 3)) & 0x01;
105
return -EINVAL; /* invalid pin */
111
struct mxl_gpio_cfg {
117
static int mxl111sf_config_gpio_pins(struct mxl111sf_state *state,
118
struct mxl_gpio_cfg *gpio_cfg)
123
mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir);
125
switch (gpio_cfg->pin) {
130
ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp);
133
tmp &= ~(1 << (gpio_cfg->pin + 4));
134
tmp |= (gpio_cfg->dir << (gpio_cfg->pin + 4));
135
ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_0, tmp);
143
ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp);
146
tmp &= ~(1 << gpio_cfg->pin);
147
tmp |= (gpio_cfg->dir << gpio_cfg->pin);
148
ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_1, tmp);
155
ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp);
158
tmp &= ~(1 << (gpio_cfg->pin - 3));
159
tmp |= (gpio_cfg->dir << (gpio_cfg->pin - 3));
160
ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_2, tmp);
165
return -EINVAL; /* invalid pin */
168
ret = (MXL_GPIO_DIR_OUTPUT == gpio_cfg->dir) ?
169
mxl111sf_set_gpo_state(state,
170
gpio_cfg->pin, gpio_cfg->val) :
171
mxl111sf_get_gpi_state(state,
172
gpio_cfg->pin, &gpio_cfg->val);
178
static int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state,
179
int gpio, int direction, int val)
181
struct mxl_gpio_cfg gpio_config = {
187
mxl_debug("(%d, %d, %d)", gpio, direction, val);
189
return mxl111sf_config_gpio_pins(state, &gpio_config);
192
/* ------------------------------------------------------------------------- */
194
#define PIN_MUX_MPEG_MODE_MASK 0x40 /* 0x17 <6> */
195
#define PIN_MUX_MPEG_PAR_EN_MASK 0x01 /* 0x18 <0> */
196
#define PIN_MUX_MPEG_SER_EN_MASK 0x02 /* 0x18 <1> */
197
#define PIN_MUX_MPG_IN_MUX_MASK 0x80 /* 0x3D <7> */
198
#define PIN_MUX_BT656_ENABLE_MASK 0x04 /* 0x12 <2> */
199
#define PIN_MUX_I2S_ENABLE_MASK 0x40 /* 0x15 <6> */
200
#define PIN_MUX_SPI_MODE_MASK 0x10 /* 0x3D <4> */
201
#define PIN_MUX_MCLK_EN_CTRL_MASK 0x10 /* 0x82 <4> */
202
#define PIN_MUX_MPSYN_EN_CTRL_MASK 0x20 /* 0x82 <5> */
203
#define PIN_MUX_MDVAL_EN_CTRL_MASK 0x40 /* 0x82 <6> */
204
#define PIN_MUX_MPERR_EN_CTRL_MASK 0x80 /* 0x82 <7> */
205
#define PIN_MUX_MDAT_EN_0_MASK 0x10 /* 0x84 <4> */
206
#define PIN_MUX_MDAT_EN_1_MASK 0x20 /* 0x84 <5> */
207
#define PIN_MUX_MDAT_EN_2_MASK 0x40 /* 0x84 <6> */
208
#define PIN_MUX_MDAT_EN_3_MASK 0x80 /* 0x84 <7> */
209
#define PIN_MUX_MDAT_EN_4_MASK 0x10 /* 0x89 <4> */
210
#define PIN_MUX_MDAT_EN_5_MASK 0x20 /* 0x89 <5> */
211
#define PIN_MUX_MDAT_EN_6_MASK 0x40 /* 0x89 <6> */
212
#define PIN_MUX_MDAT_EN_7_MASK 0x80 /* 0x89 <7> */
214
int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
215
enum mxl111sf_mux_config pin_mux_config)
217
u8 r12, r15, r17, r18, r3D, r82, r84, r89;
220
mxl_debug("(%d)", pin_mux_config);
222
ret = mxl111sf_read_reg(state, 0x17, &r17);
225
ret = mxl111sf_read_reg(state, 0x18, &r18);
228
ret = mxl111sf_read_reg(state, 0x12, &r12);
231
ret = mxl111sf_read_reg(state, 0x15, &r15);
234
ret = mxl111sf_read_reg(state, 0x82, &r82);
237
ret = mxl111sf_read_reg(state, 0x84, &r84);
240
ret = mxl111sf_read_reg(state, 0x89, &r89);
243
ret = mxl111sf_read_reg(state, 0x3D, &r3D);
247
switch (pin_mux_config) {
248
case PIN_MUX_TS_OUT_PARALLEL:
250
r17 |= PIN_MUX_MPEG_MODE_MASK;
251
/* mpeg_par_en = 1 */
252
r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
253
/* mpeg_ser_en = 0 */
254
r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
256
r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
257
/* bt656_enable = 0 */
258
r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
260
r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
262
r3D &= ~PIN_MUX_SPI_MODE_MASK;
263
/* mclk_en_ctrl = 1 */
264
r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
265
/* mperr_en_ctrl = 1 */
266
r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
267
/* mdval_en_ctrl = 1 */
268
r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
269
/* mpsyn_en_ctrl = 1 */
270
r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
271
/* mdat_en_ctrl[3:0] = 0xF */
273
/* mdat_en_ctrl[7:4] = 0xF */
276
case PIN_MUX_TS_OUT_SERIAL:
278
r17 |= PIN_MUX_MPEG_MODE_MASK;
279
/* mpeg_par_en = 0 */
280
r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
281
/* mpeg_ser_en = 1 */
282
r18 |= PIN_MUX_MPEG_SER_EN_MASK;
284
r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
285
/* bt656_enable = 0 */
286
r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
288
r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
290
r3D &= ~PIN_MUX_SPI_MODE_MASK;
291
/* mclk_en_ctrl = 1 */
292
r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
293
/* mperr_en_ctrl = 1 */
294
r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
295
/* mdval_en_ctrl = 1 */
296
r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
297
/* mpsyn_en_ctrl = 1 */
298
r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
299
/* mdat_en_ctrl[3:0] = 0xF */
301
/* mdat_en_ctrl[7:4] = 0xF */
304
case PIN_MUX_GPIO_MODE:
306
r17 &= ~PIN_MUX_MPEG_MODE_MASK;
307
/* mpeg_par_en = 0 */
308
r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
309
/* mpeg_ser_en = 0 */
310
r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
312
r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
313
/* bt656_enable = 0 */
314
r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
316
r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
318
r3D &= ~PIN_MUX_SPI_MODE_MASK;
319
/* mclk_en_ctrl = 0 */
320
r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
321
/* mperr_en_ctrl = 0 */
322
r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
323
/* mdval_en_ctrl = 0 */
324
r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
325
/* mpsyn_en_ctrl = 0 */
326
r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
327
/* mdat_en_ctrl[3:0] = 0x0 */
329
/* mdat_en_ctrl[7:4] = 0x0 */
332
case PIN_MUX_TS_SERIAL_IN_MODE_0:
334
r17 &= ~PIN_MUX_MPEG_MODE_MASK;
335
/* mpeg_par_en = 0 */
336
r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
337
/* mpeg_ser_en = 1 */
338
r18 |= PIN_MUX_MPEG_SER_EN_MASK;
340
r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
341
/* bt656_enable = 0 */
342
r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
344
r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
346
r3D &= ~PIN_MUX_SPI_MODE_MASK;
347
/* mclk_en_ctrl = 0 */
348
r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
349
/* mperr_en_ctrl = 0 */
350
r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
351
/* mdval_en_ctrl = 0 */
352
r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
353
/* mpsyn_en_ctrl = 0 */
354
r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
355
/* mdat_en_ctrl[3:0] = 0x0 */
357
/* mdat_en_ctrl[7:4] = 0x0 */
360
case PIN_MUX_TS_SERIAL_IN_MODE_1:
362
r17 &= ~PIN_MUX_MPEG_MODE_MASK;
363
/* mpeg_par_en = 0 */
364
r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
365
/* mpeg_ser_en = 1 */
366
r18 |= PIN_MUX_MPEG_SER_EN_MASK;
368
r3D |= PIN_MUX_MPG_IN_MUX_MASK;
369
/* bt656_enable = 0 */
370
r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
372
r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
374
r3D &= ~PIN_MUX_SPI_MODE_MASK;
375
/* mclk_en_ctrl = 0 */
376
r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
377
/* mperr_en_ctrl = 0 */
378
r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
379
/* mdval_en_ctrl = 0 */
380
r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
381
/* mpsyn_en_ctrl = 0 */
382
r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
383
/* mdat_en_ctrl[3:0] = 0x0 */
385
/* mdat_en_ctrl[7:4] = 0x0 */
388
case PIN_MUX_TS_SPI_IN_MODE_1:
390
r17 &= ~PIN_MUX_MPEG_MODE_MASK;
391
/* mpeg_par_en = 0 */
392
r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
393
/* mpeg_ser_en = 1 */
394
r18 |= PIN_MUX_MPEG_SER_EN_MASK;
396
r3D |= PIN_MUX_MPG_IN_MUX_MASK;
397
/* bt656_enable = 0 */
398
r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
400
r15 |= PIN_MUX_I2S_ENABLE_MASK;
402
r3D |= PIN_MUX_SPI_MODE_MASK;
403
/* mclk_en_ctrl = 0 */
404
r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
405
/* mperr_en_ctrl = 0 */
406
r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
407
/* mdval_en_ctrl = 0 */
408
r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
409
/* mpsyn_en_ctrl = 0 */
410
r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
411
/* mdat_en_ctrl[3:0] = 0x0 */
413
/* mdat_en_ctrl[7:4] = 0x0 */
416
case PIN_MUX_TS_SPI_IN_MODE_0:
418
r17 &= ~PIN_MUX_MPEG_MODE_MASK;
419
/* mpeg_par_en = 0 */
420
r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
421
/* mpeg_ser_en = 1 */
422
r18 |= PIN_MUX_MPEG_SER_EN_MASK;
424
r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
425
/* bt656_enable = 0 */
426
r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
428
r15 |= PIN_MUX_I2S_ENABLE_MASK;
430
r3D |= PIN_MUX_SPI_MODE_MASK;
431
/* mclk_en_ctrl = 0 */
432
r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
433
/* mperr_en_ctrl = 0 */
434
r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
435
/* mdval_en_ctrl = 0 */
436
r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
437
/* mpsyn_en_ctrl = 0 */
438
r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
439
/* mdat_en_ctrl[3:0] = 0x0 */
441
/* mdat_en_ctrl[7:4] = 0x0 */
444
case PIN_MUX_TS_PARALLEL_IN:
446
r17 &= ~PIN_MUX_MPEG_MODE_MASK;
447
/* mpeg_par_en = 1 */
448
r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
449
/* mpeg_ser_en = 0 */
450
r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
452
r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
453
/* bt656_enable = 0 */
454
r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
456
r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
458
r3D &= ~PIN_MUX_SPI_MODE_MASK;
459
/* mclk_en_ctrl = 0 */
460
r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
461
/* mperr_en_ctrl = 0 */
462
r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
463
/* mdval_en_ctrl = 0 */
464
r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
465
/* mpsyn_en_ctrl = 0 */
466
r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
467
/* mdat_en_ctrl[3:0] = 0x0 */
469
/* mdat_en_ctrl[7:4] = 0x0 */
472
case PIN_MUX_BT656_I2S_MODE:
474
r17 &= ~PIN_MUX_MPEG_MODE_MASK;
475
/* mpeg_par_en = 0 */
476
r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
477
/* mpeg_ser_en = 0 */
478
r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
480
r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
481
/* bt656_enable = 1 */
482
r12 |= PIN_MUX_BT656_ENABLE_MASK;
484
r15 |= PIN_MUX_I2S_ENABLE_MASK;
486
r3D &= ~PIN_MUX_SPI_MODE_MASK;
487
/* mclk_en_ctrl = 0 */
488
r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
489
/* mperr_en_ctrl = 0 */
490
r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
491
/* mdval_en_ctrl = 0 */
492
r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
493
/* mpsyn_en_ctrl = 0 */
494
r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
495
/* mdat_en_ctrl[3:0] = 0x0 */
497
/* mdat_en_ctrl[7:4] = 0x0 */
500
case PIN_MUX_DEFAULT:
503
r17 |= PIN_MUX_MPEG_MODE_MASK;
504
/* mpeg_par_en = 0 */
505
r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
506
/* mpeg_ser_en = 0 */
507
r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
509
r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
510
/* bt656_enable = 0 */
511
r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
513
r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
515
r3D &= ~PIN_MUX_SPI_MODE_MASK;
516
/* mclk_en_ctrl = 0 */
517
r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
518
/* mperr_en_ctrl = 0 */
519
r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
520
/* mdval_en_ctrl = 0 */
521
r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
522
/* mpsyn_en_ctrl = 0 */
523
r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
524
/* mdat_en_ctrl[3:0] = 0x0 */
526
/* mdat_en_ctrl[7:4] = 0x0 */
531
ret = mxl111sf_write_reg(state, 0x17, r17);
534
ret = mxl111sf_write_reg(state, 0x18, r18);
537
ret = mxl111sf_write_reg(state, 0x12, r12);
540
ret = mxl111sf_write_reg(state, 0x15, r15);
543
ret = mxl111sf_write_reg(state, 0x82, r82);
546
ret = mxl111sf_write_reg(state, 0x84, r84);
549
ret = mxl111sf_write_reg(state, 0x89, r89);
552
ret = mxl111sf_write_reg(state, 0x3D, r3D);
559
/* ------------------------------------------------------------------------- */
561
static int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val)
563
return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val);
566
static int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state)
568
u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */
573
for (i = 3; i < 8; i++) {
574
ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01);
582
#define PCA9534_I2C_ADDR (0x40 >> 1)
583
static int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val)
587
struct i2c_msg msg[] = {
588
{ .addr = PCA9534_I2C_ADDR,
589
.flags = 0, .buf = w, .len = 1 },
590
{ .addr = PCA9534_I2C_ADDR,
591
.flags = I2C_M_RD, .buf = &r, .len = 1 },
594
mxl_debug("(%d, %d)", gpio, val);
596
/* read current GPIO levels from flip-flop */
597
i2c_transfer(&state->d->i2c_adap, msg, 2);
599
/* prepare write buffer with current GPIO levels */
606
/* clear the desired GPIO */
607
w[1] &= ~(1 << gpio);
609
/* set the desired GPIO value */
610
w[1] |= ((val ? 1 : 0) << gpio);
612
/* write new GPIO levels to flip-flop */
613
i2c_transfer(&state->d->i2c_adap, &msg[0], 1);
618
static int pca9534_init_port_expander(struct mxl111sf_state *state)
620
u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */
622
struct i2c_msg msg = {
623
.addr = PCA9534_I2C_ADDR,
624
.flags = 0, .buf = w, .len = 2
629
i2c_transfer(&state->d->i2c_adap, &msg, 1);
631
/* configure all pins as outputs */
635
i2c_transfer(&state->d->i2c_adap, &msg, 1);
640
int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val)
642
mxl_debug("(%d, %d)", gpio, val);
644
switch (state->gpio_port_expander) {
647
"gpio_port_expander undefined, assuming PCA9534");
649
case mxl111sf_PCA9534:
650
return pca9534_set_gpio(state, gpio, val);
651
case mxl111sf_gpio_hw:
652
return mxl111sf_hw_set_gpio(state, gpio, val);
656
static int mxl111sf_probe_port_expander(struct mxl111sf_state *state)
661
struct i2c_msg msg[] = {
662
{ .flags = 0, .buf = &w, .len = 1 },
663
{ .flags = I2C_M_RD, .buf = &r, .len = 1 },
668
msg[0].addr = 0x70 >> 1;
669
msg[1].addr = 0x70 >> 1;
671
/* read current GPIO levels from flip-flop */
672
ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
674
state->port_expander_addr = msg[0].addr;
675
state->gpio_port_expander = mxl111sf_PCA9534;
676
mxl_debug("found port expander at 0x%02x",
677
state->port_expander_addr);
681
msg[0].addr = 0x40 >> 1;
682
msg[1].addr = 0x40 >> 1;
684
ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
686
state->port_expander_addr = msg[0].addr;
687
state->gpio_port_expander = mxl111sf_PCA9534;
688
mxl_debug("found port expander at 0x%02x",
689
state->port_expander_addr);
692
state->port_expander_addr = 0xff;
693
state->gpio_port_expander = mxl111sf_gpio_hw;
694
mxl_debug("using hardware gpio");
698
int mxl111sf_init_port_expander(struct mxl111sf_state *state)
702
if (0x00 == state->port_expander_addr)
703
mxl111sf_probe_port_expander(state);
705
switch (state->gpio_port_expander) {
708
"gpio_port_expander undefined, assuming PCA9534");
710
case mxl111sf_PCA9534:
711
return pca9534_init_port_expander(state);
712
case mxl111sf_gpio_hw:
713
return mxl111sf_hw_gpio_initialize(state);
717
/* ------------------------------------------------------------------------ */
719
int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode)
722
* 3 - ATSC/MH# | 1 = ATSC transport, 0 = MH transport | default 0
723
* 4 - ATSC_RST## | 1 = ATSC enable, 0 = ATSC Reset | default 0
724
* 5 - ATSC_EN | 1 = ATSC power enable, 0 = ATSC power off | default 0
725
* 6 - MH_RESET# | 1 = MH enable, 0 = MH Reset | default 0
726
* 7 - MH_EN | 1 = MH power enable, 0 = MH power off | default 0
728
mxl_debug("(%d)", mode);
731
case MXL111SF_GPIO_MOD_MH:
732
mxl111sf_set_gpio(state, 4, 0);
733
mxl111sf_set_gpio(state, 5, 0);
735
mxl111sf_set_gpio(state, 7, 1);
737
mxl111sf_set_gpio(state, 6, 1);
740
mxl111sf_set_gpio(state, 3, 0);
742
case MXL111SF_GPIO_MOD_ATSC:
743
mxl111sf_set_gpio(state, 6, 0);
744
mxl111sf_set_gpio(state, 7, 0);
746
mxl111sf_set_gpio(state, 5, 1);
748
mxl111sf_set_gpio(state, 4, 1);
750
mxl111sf_set_gpio(state, 3, 1);
752
default: /* DVBT / STANDBY */
753
mxl111sf_init_port_expander(state);