GNU Linux-libre 4.19.295-gnu1
[releases.git] / drivers / media / usb / dvb-usb-v2 / mxl111sf-gpio.c
1 /*
2  *  mxl111sf-gpio.c - driver for the MaxLinear MXL111SF
3  *
4  *  Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org>
5  *
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.
10  *
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.
15  */
16
17 #include "mxl111sf-gpio.h"
18 #include "mxl111sf-i2c.h"
19 #include "mxl111sf.h"
20
21 /* ------------------------------------------------------------------------- */
22
23 #define MXL_GPIO_MUX_REG_0 0x84
24 #define MXL_GPIO_MUX_REG_1 0x89
25 #define MXL_GPIO_MUX_REG_2 0x82
26
27 #define MXL_GPIO_DIR_INPUT  0
28 #define MXL_GPIO_DIR_OUTPUT 1
29
30
31 static int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val)
32 {
33         int ret;
34         u8 tmp;
35
36         mxl_debug_adv("(%d, %d)", pin, val);
37
38         if ((pin > 0) && (pin < 8)) {
39                 ret = mxl111sf_read_reg(state, 0x19, &tmp);
40                 if (mxl_fail(ret))
41                         goto fail;
42                 tmp &= ~(1 << (pin - 1));
43                 tmp |= (val << (pin - 1));
44                 ret = mxl111sf_write_reg(state, 0x19, tmp);
45                 if (mxl_fail(ret))
46                         goto fail;
47         } else if (pin <= 10) {
48                 if (pin == 0)
49                         pin += 7;
50                 ret = mxl111sf_read_reg(state, 0x30, &tmp);
51                 if (mxl_fail(ret))
52                         goto fail;
53                 tmp &= ~(1 << (pin - 3));
54                 tmp |= (val << (pin - 3));
55                 ret = mxl111sf_write_reg(state, 0x30, tmp);
56                 if (mxl_fail(ret))
57                         goto fail;
58         } else
59                 ret = -EINVAL;
60 fail:
61         return ret;
62 }
63
64 static int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val)
65 {
66         int ret;
67         u8 tmp;
68
69         mxl_debug("(0x%02x)", pin);
70
71         *val = 0;
72
73         switch (pin) {
74         case 0:
75         case 1:
76         case 2:
77         case 3:
78                 ret = mxl111sf_read_reg(state, 0x23, &tmp);
79                 if (mxl_fail(ret))
80                         goto fail;
81                 *val = (tmp >> (pin + 4)) & 0x01;
82                 break;
83         case 4:
84         case 5:
85         case 6:
86         case 7:
87                 ret = mxl111sf_read_reg(state, 0x2f, &tmp);
88                 if (mxl_fail(ret))
89                         goto fail;
90                 *val = (tmp >> pin) & 0x01;
91                 break;
92         case 8:
93         case 9:
94         case 10:
95                 ret = mxl111sf_read_reg(state, 0x22, &tmp);
96                 if (mxl_fail(ret))
97                         goto fail;
98                 *val = (tmp >> (pin - 3)) & 0x01;
99                 break;
100         default:
101                 return -EINVAL; /* invalid pin */
102         }
103 fail:
104         return ret;
105 }
106
107 struct mxl_gpio_cfg {
108         u8 pin;
109         u8 dir;
110         u8 val;
111 };
112
113 static int mxl111sf_config_gpio_pins(struct mxl111sf_state *state,
114                                      struct mxl_gpio_cfg *gpio_cfg)
115 {
116         int ret;
117         u8 tmp;
118
119         mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir);
120
121         switch (gpio_cfg->pin) {
122         case 0:
123         case 1:
124         case 2:
125         case 3:
126                 ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp);
127                 if (mxl_fail(ret))
128                         goto fail;
129                 tmp &= ~(1 << (gpio_cfg->pin + 4));
130                 tmp |= (gpio_cfg->dir << (gpio_cfg->pin + 4));
131                 ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_0, tmp);
132                 if (mxl_fail(ret))
133                         goto fail;
134                 break;
135         case 4:
136         case 5:
137         case 6:
138         case 7:
139                 ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp);
140                 if (mxl_fail(ret))
141                         goto fail;
142                 tmp &= ~(1 << gpio_cfg->pin);
143                 tmp |= (gpio_cfg->dir << gpio_cfg->pin);
144                 ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_1, tmp);
145                 if (mxl_fail(ret))
146                         goto fail;
147                 break;
148         case 8:
149         case 9:
150         case 10:
151                 ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp);
152                 if (mxl_fail(ret))
153                         goto fail;
154                 tmp &= ~(1 << (gpio_cfg->pin - 3));
155                 tmp |= (gpio_cfg->dir << (gpio_cfg->pin - 3));
156                 ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_2, tmp);
157                 if (mxl_fail(ret))
158                         goto fail;
159                 break;
160         default:
161                 return -EINVAL; /* invalid pin */
162         }
163
164         ret = (MXL_GPIO_DIR_OUTPUT == gpio_cfg->dir) ?
165                 mxl111sf_set_gpo_state(state,
166                                        gpio_cfg->pin, gpio_cfg->val) :
167                 mxl111sf_get_gpi_state(state,
168                                        gpio_cfg->pin, &gpio_cfg->val);
169         mxl_fail(ret);
170 fail:
171         return ret;
172 }
173
174 static int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state,
175                                    int gpio, int direction, int val)
176 {
177         struct mxl_gpio_cfg gpio_config = {
178                 .pin = gpio,
179                 .dir = direction,
180                 .val = val,
181         };
182
183         mxl_debug("(%d, %d, %d)", gpio, direction, val);
184
185         return mxl111sf_config_gpio_pins(state, &gpio_config);
186 }
187
188 /* ------------------------------------------------------------------------- */
189
190 #define PIN_MUX_MPEG_MODE_MASK          0x40   /* 0x17 <6> */
191 #define PIN_MUX_MPEG_PAR_EN_MASK        0x01   /* 0x18 <0> */
192 #define PIN_MUX_MPEG_SER_EN_MASK        0x02   /* 0x18 <1> */
193 #define PIN_MUX_MPG_IN_MUX_MASK         0x80   /* 0x3D <7> */
194 #define PIN_MUX_BT656_ENABLE_MASK       0x04   /* 0x12 <2> */
195 #define PIN_MUX_I2S_ENABLE_MASK         0x40   /* 0x15 <6> */
196 #define PIN_MUX_SPI_MODE_MASK           0x10   /* 0x3D <4> */
197 #define PIN_MUX_MCLK_EN_CTRL_MASK       0x10   /* 0x82 <4> */
198 #define PIN_MUX_MPSYN_EN_CTRL_MASK      0x20   /* 0x82 <5> */
199 #define PIN_MUX_MDVAL_EN_CTRL_MASK      0x40   /* 0x82 <6> */
200 #define PIN_MUX_MPERR_EN_CTRL_MASK      0x80   /* 0x82 <7> */
201 #define PIN_MUX_MDAT_EN_0_MASK          0x10   /* 0x84 <4> */
202 #define PIN_MUX_MDAT_EN_1_MASK          0x20   /* 0x84 <5> */
203 #define PIN_MUX_MDAT_EN_2_MASK          0x40   /* 0x84 <6> */
204 #define PIN_MUX_MDAT_EN_3_MASK          0x80   /* 0x84 <7> */
205 #define PIN_MUX_MDAT_EN_4_MASK          0x10   /* 0x89 <4> */
206 #define PIN_MUX_MDAT_EN_5_MASK          0x20   /* 0x89 <5> */
207 #define PIN_MUX_MDAT_EN_6_MASK          0x40   /* 0x89 <6> */
208 #define PIN_MUX_MDAT_EN_7_MASK          0x80   /* 0x89 <7> */
209
210 int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
211                                   enum mxl111sf_mux_config pin_mux_config)
212 {
213         u8 r12, r15, r17, r18, r3D, r82, r84, r89;
214         int ret;
215
216         mxl_debug("(%d)", pin_mux_config);
217
218         ret = mxl111sf_read_reg(state, 0x17, &r17);
219         if (mxl_fail(ret))
220                 goto fail;
221         ret = mxl111sf_read_reg(state, 0x18, &r18);
222         if (mxl_fail(ret))
223                 goto fail;
224         ret = mxl111sf_read_reg(state, 0x12, &r12);
225         if (mxl_fail(ret))
226                 goto fail;
227         ret = mxl111sf_read_reg(state, 0x15, &r15);
228         if (mxl_fail(ret))
229                 goto fail;
230         ret = mxl111sf_read_reg(state, 0x82, &r82);
231         if (mxl_fail(ret))
232                 goto fail;
233         ret = mxl111sf_read_reg(state, 0x84, &r84);
234         if (mxl_fail(ret))
235                 goto fail;
236         ret = mxl111sf_read_reg(state, 0x89, &r89);
237         if (mxl_fail(ret))
238                 goto fail;
239         ret = mxl111sf_read_reg(state, 0x3D, &r3D);
240         if (mxl_fail(ret))
241                 goto fail;
242
243         switch (pin_mux_config) {
244         case PIN_MUX_TS_OUT_PARALLEL:
245                 /* mpeg_mode = 1 */
246                 r17 |= PIN_MUX_MPEG_MODE_MASK;
247                 /* mpeg_par_en = 1 */
248                 r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
249                 /* mpeg_ser_en = 0 */
250                 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
251                 /* mpg_in_mux = 0 */
252                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
253                 /* bt656_enable = 0 */
254                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
255                 /* i2s_enable = 0 */
256                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
257                 /* spi_mode = 0 */
258                 r3D &= ~PIN_MUX_SPI_MODE_MASK;
259                 /* mclk_en_ctrl = 1 */
260                 r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
261                 /* mperr_en_ctrl = 1 */
262                 r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
263                 /* mdval_en_ctrl = 1 */
264                 r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
265                 /* mpsyn_en_ctrl = 1 */
266                 r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
267                 /* mdat_en_ctrl[3:0] = 0xF */
268                 r84 |= 0xF0;
269                 /* mdat_en_ctrl[7:4] = 0xF */
270                 r89 |= 0xF0;
271                 break;
272         case PIN_MUX_TS_OUT_SERIAL:
273                 /* mpeg_mode = 1 */
274                 r17 |= PIN_MUX_MPEG_MODE_MASK;
275                 /* mpeg_par_en = 0 */
276                 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
277                 /* mpeg_ser_en = 1 */
278                 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
279                 /* mpg_in_mux = 0 */
280                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
281                 /* bt656_enable = 0 */
282                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
283                 /* i2s_enable = 0 */
284                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
285                 /* spi_mode = 0 */
286                 r3D &= ~PIN_MUX_SPI_MODE_MASK;
287                 /* mclk_en_ctrl = 1 */
288                 r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
289                 /* mperr_en_ctrl = 1 */
290                 r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
291                 /* mdval_en_ctrl = 1 */
292                 r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
293                 /* mpsyn_en_ctrl = 1 */
294                 r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
295                 /* mdat_en_ctrl[3:0] = 0xF */
296                 r84 |= 0xF0;
297                 /* mdat_en_ctrl[7:4] = 0xF */
298                 r89 |= 0xF0;
299                 break;
300         case PIN_MUX_GPIO_MODE:
301                 /* mpeg_mode = 0 */
302                 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
303                 /* mpeg_par_en = 0 */
304                 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
305                 /* mpeg_ser_en = 0 */
306                 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
307                 /* mpg_in_mux = 0 */
308                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
309                 /* bt656_enable = 0 */
310                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
311                 /* i2s_enable = 0 */
312                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
313                 /* spi_mode = 0 */
314                 r3D &= ~PIN_MUX_SPI_MODE_MASK;
315                 /* mclk_en_ctrl = 0 */
316                 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
317                 /* mperr_en_ctrl = 0 */
318                 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
319                 /* mdval_en_ctrl = 0 */
320                 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
321                 /* mpsyn_en_ctrl = 0 */
322                 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
323                 /* mdat_en_ctrl[3:0] = 0x0 */
324                 r84 &= 0x0F;
325                 /* mdat_en_ctrl[7:4] = 0x0 */
326                 r89 &= 0x0F;
327                 break;
328         case PIN_MUX_TS_SERIAL_IN_MODE_0:
329                 /* mpeg_mode = 0 */
330                 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
331                 /* mpeg_par_en = 0 */
332                 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
333                 /* mpeg_ser_en = 1 */
334                 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
335                 /* mpg_in_mux = 0 */
336                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
337                 /* bt656_enable = 0 */
338                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
339                 /* i2s_enable = 0 */
340                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
341                 /* spi_mode = 0 */
342                 r3D &= ~PIN_MUX_SPI_MODE_MASK;
343                 /* mclk_en_ctrl = 0 */
344                 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
345                 /* mperr_en_ctrl = 0 */
346                 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
347                 /* mdval_en_ctrl = 0 */
348                 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
349                 /* mpsyn_en_ctrl = 0 */
350                 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
351                 /* mdat_en_ctrl[3:0] = 0x0 */
352                 r84 &= 0x0F;
353                 /* mdat_en_ctrl[7:4] = 0x0 */
354                 r89 &= 0x0F;
355                 break;
356         case PIN_MUX_TS_SERIAL_IN_MODE_1:
357                 /* mpeg_mode = 0 */
358                 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
359                 /* mpeg_par_en = 0 */
360                 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
361                 /* mpeg_ser_en = 1 */
362                 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
363                 /* mpg_in_mux = 1 */
364                 r3D |= PIN_MUX_MPG_IN_MUX_MASK;
365                 /* bt656_enable = 0 */
366                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
367                 /* i2s_enable = 0 */
368                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
369                 /* spi_mode = 0 */
370                 r3D &= ~PIN_MUX_SPI_MODE_MASK;
371                 /* mclk_en_ctrl = 0 */
372                 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
373                 /* mperr_en_ctrl = 0 */
374                 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
375                 /* mdval_en_ctrl = 0 */
376                 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
377                 /* mpsyn_en_ctrl = 0 */
378                 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
379                 /* mdat_en_ctrl[3:0] = 0x0 */
380                 r84 &= 0x0F;
381                 /* mdat_en_ctrl[7:4] = 0x0 */
382                 r89 &= 0x0F;
383                 break;
384         case PIN_MUX_TS_SPI_IN_MODE_1:
385                 /* mpeg_mode = 0 */
386                 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
387                 /* mpeg_par_en = 0 */
388                 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
389                 /* mpeg_ser_en = 1 */
390                 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
391                 /* mpg_in_mux = 1 */
392                 r3D |= PIN_MUX_MPG_IN_MUX_MASK;
393                 /* bt656_enable = 0 */
394                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
395                 /* i2s_enable = 1 */
396                 r15 |= PIN_MUX_I2S_ENABLE_MASK;
397                 /* spi_mode = 1 */
398                 r3D |= PIN_MUX_SPI_MODE_MASK;
399                 /* mclk_en_ctrl = 0 */
400                 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
401                 /* mperr_en_ctrl = 0 */
402                 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
403                 /* mdval_en_ctrl = 0 */
404                 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
405                 /* mpsyn_en_ctrl = 0 */
406                 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
407                 /* mdat_en_ctrl[3:0] = 0x0 */
408                 r84 &= 0x0F;
409                 /* mdat_en_ctrl[7:4] = 0x0 */
410                 r89 &= 0x0F;
411                 break;
412         case PIN_MUX_TS_SPI_IN_MODE_0:
413                 /* mpeg_mode = 0 */
414                 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
415                 /* mpeg_par_en = 0 */
416                 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
417                 /* mpeg_ser_en = 1 */
418                 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
419                 /* mpg_in_mux = 0 */
420                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
421                 /* bt656_enable = 0 */
422                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
423                 /* i2s_enable = 1 */
424                 r15 |= PIN_MUX_I2S_ENABLE_MASK;
425                 /* spi_mode = 1 */
426                 r3D |= PIN_MUX_SPI_MODE_MASK;
427                 /* mclk_en_ctrl = 0 */
428                 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
429                 /* mperr_en_ctrl = 0 */
430                 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
431                 /* mdval_en_ctrl = 0 */
432                 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
433                 /* mpsyn_en_ctrl = 0 */
434                 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
435                 /* mdat_en_ctrl[3:0] = 0x0 */
436                 r84 &= 0x0F;
437                 /* mdat_en_ctrl[7:4] = 0x0 */
438                 r89 &= 0x0F;
439                 break;
440         case PIN_MUX_TS_PARALLEL_IN:
441                 /* mpeg_mode = 0 */
442                 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
443                 /* mpeg_par_en = 1 */
444                 r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
445                 /* mpeg_ser_en = 0 */
446                 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
447                 /* mpg_in_mux = 0 */
448                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
449                 /* bt656_enable = 0 */
450                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
451                 /* i2s_enable = 0 */
452                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
453                 /* spi_mode = 0 */
454                 r3D &= ~PIN_MUX_SPI_MODE_MASK;
455                 /* mclk_en_ctrl = 0 */
456                 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
457                 /* mperr_en_ctrl = 0 */
458                 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
459                 /* mdval_en_ctrl = 0 */
460                 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
461                 /* mpsyn_en_ctrl = 0 */
462                 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
463                 /* mdat_en_ctrl[3:0] = 0x0 */
464                 r84 &= 0x0F;
465                 /* mdat_en_ctrl[7:4] = 0x0 */
466                 r89 &= 0x0F;
467                 break;
468         case PIN_MUX_BT656_I2S_MODE:
469                 /* mpeg_mode = 0 */
470                 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
471                 /* mpeg_par_en = 0 */
472                 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
473                 /* mpeg_ser_en = 0 */
474                 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
475                 /* mpg_in_mux = 0 */
476                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
477                 /* bt656_enable = 1 */
478                 r12 |= PIN_MUX_BT656_ENABLE_MASK;
479                 /* i2s_enable = 1 */
480                 r15 |= PIN_MUX_I2S_ENABLE_MASK;
481                 /* spi_mode = 0 */
482                 r3D &= ~PIN_MUX_SPI_MODE_MASK;
483                 /* mclk_en_ctrl = 0 */
484                 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
485                 /* mperr_en_ctrl = 0 */
486                 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
487                 /* mdval_en_ctrl = 0 */
488                 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
489                 /* mpsyn_en_ctrl = 0 */
490                 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
491                 /* mdat_en_ctrl[3:0] = 0x0 */
492                 r84 &= 0x0F;
493                 /* mdat_en_ctrl[7:4] = 0x0 */
494                 r89 &= 0x0F;
495                 break;
496         case PIN_MUX_DEFAULT:
497         default:
498                 /* mpeg_mode = 1 */
499                 r17 |= PIN_MUX_MPEG_MODE_MASK;
500                 /* mpeg_par_en = 0 */
501                 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
502                 /* mpeg_ser_en = 0 */
503                 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
504                 /* mpg_in_mux = 0 */
505                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
506                 /* bt656_enable = 0 */
507                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
508                 /* i2s_enable = 0 */
509                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
510                 /* spi_mode = 0 */
511                 r3D &= ~PIN_MUX_SPI_MODE_MASK;
512                 /* mclk_en_ctrl = 0 */
513                 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
514                 /* mperr_en_ctrl = 0 */
515                 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
516                 /* mdval_en_ctrl = 0 */
517                 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
518                 /* mpsyn_en_ctrl = 0 */
519                 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
520                 /* mdat_en_ctrl[3:0] = 0x0 */
521                 r84 &= 0x0F;
522                 /* mdat_en_ctrl[7:4] = 0x0 */
523                 r89 &= 0x0F;
524                 break;
525         }
526
527         ret = mxl111sf_write_reg(state, 0x17, r17);
528         if (mxl_fail(ret))
529                 goto fail;
530         ret = mxl111sf_write_reg(state, 0x18, r18);
531         if (mxl_fail(ret))
532                 goto fail;
533         ret = mxl111sf_write_reg(state, 0x12, r12);
534         if (mxl_fail(ret))
535                 goto fail;
536         ret = mxl111sf_write_reg(state, 0x15, r15);
537         if (mxl_fail(ret))
538                 goto fail;
539         ret = mxl111sf_write_reg(state, 0x82, r82);
540         if (mxl_fail(ret))
541                 goto fail;
542         ret = mxl111sf_write_reg(state, 0x84, r84);
543         if (mxl_fail(ret))
544                 goto fail;
545         ret = mxl111sf_write_reg(state, 0x89, r89);
546         if (mxl_fail(ret))
547                 goto fail;
548         ret = mxl111sf_write_reg(state, 0x3D, r3D);
549         if (mxl_fail(ret))
550                 goto fail;
551 fail:
552         return ret;
553 }
554
555 /* ------------------------------------------------------------------------- */
556
557 static int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val)
558 {
559         return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val);
560 }
561
562 static int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state)
563 {
564         u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */
565         int i, ret;
566
567         mxl_debug("()");
568
569         for (i = 3; i < 8; i++) {
570                 ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01);
571                 if (mxl_fail(ret))
572                         break;
573         }
574
575         return ret;
576 }
577
578 #define PCA9534_I2C_ADDR (0x40 >> 1)
579 static int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val)
580 {
581         u8 w[2] = { 1, 0 };
582         u8 r = 0;
583         struct i2c_msg msg[] = {
584                 { .addr = PCA9534_I2C_ADDR,
585                   .flags = 0, .buf = w, .len = 1 },
586                 { .addr = PCA9534_I2C_ADDR,
587                   .flags = I2C_M_RD, .buf = &r, .len = 1 },
588         };
589
590         mxl_debug("(%d, %d)", gpio, val);
591
592         /* read current GPIO levels from flip-flop */
593         i2c_transfer(&state->d->i2c_adap, msg, 2);
594
595         /* prepare write buffer with current GPIO levels */
596         msg[0].len = 2;
597 #if 0
598         w[0] = 1;
599 #endif
600         w[1] = r;
601
602         /* clear the desired GPIO */
603         w[1] &= ~(1 << gpio);
604
605         /* set the desired GPIO value */
606         w[1] |= ((val ? 1 : 0) << gpio);
607
608         /* write new GPIO levels to flip-flop */
609         i2c_transfer(&state->d->i2c_adap, &msg[0], 1);
610
611         return 0;
612 }
613
614 static int pca9534_init_port_expander(struct mxl111sf_state *state)
615 {
616         u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */
617
618         struct i2c_msg msg = {
619                 .addr = PCA9534_I2C_ADDR,
620                 .flags = 0, .buf = w, .len = 2
621         };
622
623         mxl_debug("()");
624
625         i2c_transfer(&state->d->i2c_adap, &msg, 1);
626
627         /* configure all pins as outputs */
628         w[0] = 3;
629         w[1] = 0;
630
631         i2c_transfer(&state->d->i2c_adap, &msg, 1);
632
633         return 0;
634 }
635
636 int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val)
637 {
638         mxl_debug("(%d, %d)", gpio, val);
639
640         switch (state->gpio_port_expander) {
641         default:
642                 mxl_printk(KERN_ERR,
643                            "gpio_port_expander undefined, assuming PCA9534");
644                 /* fall-thru */
645         case mxl111sf_PCA9534:
646                 return pca9534_set_gpio(state, gpio, val);
647         case mxl111sf_gpio_hw:
648                 return mxl111sf_hw_set_gpio(state, gpio, val);
649         }
650 }
651
652 static int mxl111sf_probe_port_expander(struct mxl111sf_state *state)
653 {
654         int ret;
655         u8 w = 1;
656         u8 r = 0;
657         struct i2c_msg msg[] = {
658                 { .flags = 0,        .buf = &w, .len = 1 },
659                 { .flags = I2C_M_RD, .buf = &r, .len = 1 },
660         };
661
662         mxl_debug("()");
663
664         msg[0].addr = 0x70 >> 1;
665         msg[1].addr = 0x70 >> 1;
666
667         /* read current GPIO levels from flip-flop */
668         ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
669         if (ret == 2) {
670                 state->port_expander_addr = msg[0].addr;
671                 state->gpio_port_expander = mxl111sf_PCA9534;
672                 mxl_debug("found port expander at 0x%02x",
673                           state->port_expander_addr);
674                 return 0;
675         }
676
677         msg[0].addr = 0x40 >> 1;
678         msg[1].addr = 0x40 >> 1;
679
680         ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
681         if (ret == 2) {
682                 state->port_expander_addr = msg[0].addr;
683                 state->gpio_port_expander = mxl111sf_PCA9534;
684                 mxl_debug("found port expander at 0x%02x",
685                           state->port_expander_addr);
686                 return 0;
687         }
688         state->port_expander_addr = 0xff;
689         state->gpio_port_expander = mxl111sf_gpio_hw;
690         mxl_debug("using hardware gpio");
691         return 0;
692 }
693
694 int mxl111sf_init_port_expander(struct mxl111sf_state *state)
695 {
696         mxl_debug("()");
697
698         if (0x00 == state->port_expander_addr)
699                 mxl111sf_probe_port_expander(state);
700
701         switch (state->gpio_port_expander) {
702         default:
703                 mxl_printk(KERN_ERR,
704                            "gpio_port_expander undefined, assuming PCA9534");
705                 /* fall-thru */
706         case mxl111sf_PCA9534:
707                 return pca9534_init_port_expander(state);
708         case mxl111sf_gpio_hw:
709                 return mxl111sf_hw_gpio_initialize(state);
710         }
711 }
712
713 /* ------------------------------------------------------------------------ */
714
715 int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode)
716 {
717 /*      GPO:
718  *      3 - ATSC/MH#   | 1 = ATSC transport, 0 = MH transport      | default 0
719  *      4 - ATSC_RST## | 1 = ATSC enable, 0 = ATSC Reset           | default 0
720  *      5 - ATSC_EN    | 1 = ATSC power enable, 0 = ATSC power off | default 0
721  *      6 - MH_RESET#  | 1 = MH enable, 0 = MH Reset               | default 0
722  *      7 - MH_EN      | 1 = MH power enable, 0 = MH power off     | default 0
723  */
724         mxl_debug("(%d)", mode);
725
726         switch (mode) {
727         case MXL111SF_GPIO_MOD_MH:
728                 mxl111sf_set_gpio(state, 4, 0);
729                 mxl111sf_set_gpio(state, 5, 0);
730                 msleep(50);
731                 mxl111sf_set_gpio(state, 7, 1);
732                 msleep(50);
733                 mxl111sf_set_gpio(state, 6, 1);
734                 msleep(50);
735
736                 mxl111sf_set_gpio(state, 3, 0);
737                 break;
738         case MXL111SF_GPIO_MOD_ATSC:
739                 mxl111sf_set_gpio(state, 6, 0);
740                 mxl111sf_set_gpio(state, 7, 0);
741                 msleep(50);
742                 mxl111sf_set_gpio(state, 5, 1);
743                 msleep(50);
744                 mxl111sf_set_gpio(state, 4, 1);
745                 msleep(50);
746                 mxl111sf_set_gpio(state, 3, 1);
747                 break;
748         default: /* DVBT / STANDBY */
749                 mxl111sf_init_port_expander(state);
750                 break;
751         }
752         return 0;
753 }