Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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  *  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.
19  */
20
21 #include "mxl111sf-gpio.h"
22 #include "mxl111sf-i2c.h"
23 #include "mxl111sf.h"
24
25 /* ------------------------------------------------------------------------- */
26
27 #define MXL_GPIO_MUX_REG_0 0x84
28 #define MXL_GPIO_MUX_REG_1 0x89
29 #define MXL_GPIO_MUX_REG_2 0x82
30
31 #define MXL_GPIO_DIR_INPUT  0
32 #define MXL_GPIO_DIR_OUTPUT 1
33
34
35 static int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val)
36 {
37         int ret;
38         u8 tmp;
39
40         mxl_debug_adv("(%d, %d)", pin, val);
41
42         if ((pin > 0) && (pin < 8)) {
43                 ret = mxl111sf_read_reg(state, 0x19, &tmp);
44                 if (mxl_fail(ret))
45                         goto fail;
46                 tmp &= ~(1 << (pin - 1));
47                 tmp |= (val << (pin - 1));
48                 ret = mxl111sf_write_reg(state, 0x19, tmp);
49                 if (mxl_fail(ret))
50                         goto fail;
51         } else if (pin <= 10) {
52                 if (pin == 0)
53                         pin += 7;
54                 ret = mxl111sf_read_reg(state, 0x30, &tmp);
55                 if (mxl_fail(ret))
56                         goto fail;
57                 tmp &= ~(1 << (pin - 3));
58                 tmp |= (val << (pin - 3));
59                 ret = mxl111sf_write_reg(state, 0x30, tmp);
60                 if (mxl_fail(ret))
61                         goto fail;
62         } else
63                 ret = -EINVAL;
64 fail:
65         return ret;
66 }
67
68 static int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val)
69 {
70         int ret;
71         u8 tmp;
72
73         mxl_debug("(0x%02x)", pin);
74
75         *val = 0;
76
77         switch (pin) {
78         case 0:
79         case 1:
80         case 2:
81         case 3:
82                 ret = mxl111sf_read_reg(state, 0x23, &tmp);
83                 if (mxl_fail(ret))
84                         goto fail;
85                 *val = (tmp >> (pin + 4)) & 0x01;
86                 break;
87         case 4:
88         case 5:
89         case 6:
90         case 7:
91                 ret = mxl111sf_read_reg(state, 0x2f, &tmp);
92                 if (mxl_fail(ret))
93                         goto fail;
94                 *val = (tmp >> pin) & 0x01;
95                 break;
96         case 8:
97         case 9:
98         case 10:
99                 ret = mxl111sf_read_reg(state, 0x22, &tmp);
100                 if (mxl_fail(ret))
101                         goto fail;
102                 *val = (tmp >> (pin - 3)) & 0x01;
103                 break;
104         default:
105                 return -EINVAL; /* invalid pin */
106         }
107 fail:
108         return ret;
109 }
110
111 struct mxl_gpio_cfg {
112         u8 pin;
113         u8 dir;
114         u8 val;
115 };
116
117 static int mxl111sf_config_gpio_pins(struct mxl111sf_state *state,
118                                      struct mxl_gpio_cfg *gpio_cfg)
119 {
120         int ret;
121         u8 tmp;
122
123         mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir);
124
125         switch (gpio_cfg->pin) {
126         case 0:
127         case 1:
128         case 2:
129         case 3:
130                 ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp);
131                 if (mxl_fail(ret))
132                         goto fail;
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);
136                 if (mxl_fail(ret))
137                         goto fail;
138                 break;
139         case 4:
140         case 5:
141         case 6:
142         case 7:
143                 ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp);
144                 if (mxl_fail(ret))
145                         goto fail;
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);
149                 if (mxl_fail(ret))
150                         goto fail;
151                 break;
152         case 8:
153         case 9:
154         case 10:
155                 ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp);
156                 if (mxl_fail(ret))
157                         goto fail;
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);
161                 if (mxl_fail(ret))
162                         goto fail;
163                 break;
164         default:
165                 return -EINVAL; /* invalid pin */
166         }
167
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);
173         mxl_fail(ret);
174 fail:
175         return ret;
176 }
177
178 static int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state,
179                                    int gpio, int direction, int val)
180 {
181         struct mxl_gpio_cfg gpio_config = {
182                 .pin = gpio,
183                 .dir = direction,
184                 .val = val,
185         };
186
187         mxl_debug("(%d, %d, %d)", gpio, direction, val);
188
189         return mxl111sf_config_gpio_pins(state, &gpio_config);
190 }
191
192 /* ------------------------------------------------------------------------- */
193
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> */
213
214 int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
215                                   enum mxl111sf_mux_config pin_mux_config)
216 {
217         u8 r12, r15, r17, r18, r3D, r82, r84, r89;
218         int ret;
219
220         mxl_debug("(%d)", pin_mux_config);
221
222         ret = mxl111sf_read_reg(state, 0x17, &r17);
223         if (mxl_fail(ret))
224                 goto fail;
225         ret = mxl111sf_read_reg(state, 0x18, &r18);
226         if (mxl_fail(ret))
227                 goto fail;
228         ret = mxl111sf_read_reg(state, 0x12, &r12);
229         if (mxl_fail(ret))
230                 goto fail;
231         ret = mxl111sf_read_reg(state, 0x15, &r15);
232         if (mxl_fail(ret))
233                 goto fail;
234         ret = mxl111sf_read_reg(state, 0x82, &r82);
235         if (mxl_fail(ret))
236                 goto fail;
237         ret = mxl111sf_read_reg(state, 0x84, &r84);
238         if (mxl_fail(ret))
239                 goto fail;
240         ret = mxl111sf_read_reg(state, 0x89, &r89);
241         if (mxl_fail(ret))
242                 goto fail;
243         ret = mxl111sf_read_reg(state, 0x3D, &r3D);
244         if (mxl_fail(ret))
245                 goto fail;
246
247         switch (pin_mux_config) {
248         case PIN_MUX_TS_OUT_PARALLEL:
249                 /* mpeg_mode = 1 */
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;
255                 /* mpg_in_mux = 0 */
256                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
257                 /* bt656_enable = 0 */
258                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
259                 /* i2s_enable = 0 */
260                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
261                 /* spi_mode = 0 */
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 */
272                 r84 |= 0xF0;
273                 /* mdat_en_ctrl[7:4] = 0xF */
274                 r89 |= 0xF0;
275                 break;
276         case PIN_MUX_TS_OUT_SERIAL:
277                 /* mpeg_mode = 1 */
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;
283                 /* mpg_in_mux = 0 */
284                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
285                 /* bt656_enable = 0 */
286                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
287                 /* i2s_enable = 0 */
288                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
289                 /* spi_mode = 0 */
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 */
300                 r84 |= 0xF0;
301                 /* mdat_en_ctrl[7:4] = 0xF */
302                 r89 |= 0xF0;
303                 break;
304         case PIN_MUX_GPIO_MODE:
305                 /* mpeg_mode = 0 */
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;
311                 /* mpg_in_mux = 0 */
312                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
313                 /* bt656_enable = 0 */
314                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
315                 /* i2s_enable = 0 */
316                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
317                 /* spi_mode = 0 */
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 */
328                 r84 &= 0x0F;
329                 /* mdat_en_ctrl[7:4] = 0x0 */
330                 r89 &= 0x0F;
331                 break;
332         case PIN_MUX_TS_SERIAL_IN_MODE_0:
333                 /* mpeg_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;
339                 /* mpg_in_mux = 0 */
340                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
341                 /* bt656_enable = 0 */
342                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
343                 /* i2s_enable = 0 */
344                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
345                 /* spi_mode = 0 */
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 */
356                 r84 &= 0x0F;
357                 /* mdat_en_ctrl[7:4] = 0x0 */
358                 r89 &= 0x0F;
359                 break;
360         case PIN_MUX_TS_SERIAL_IN_MODE_1:
361                 /* mpeg_mode = 0 */
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;
367                 /* mpg_in_mux = 1 */
368                 r3D |= PIN_MUX_MPG_IN_MUX_MASK;
369                 /* bt656_enable = 0 */
370                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
371                 /* i2s_enable = 0 */
372                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
373                 /* spi_mode = 0 */
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 */
384                 r84 &= 0x0F;
385                 /* mdat_en_ctrl[7:4] = 0x0 */
386                 r89 &= 0x0F;
387                 break;
388         case PIN_MUX_TS_SPI_IN_MODE_1:
389                 /* mpeg_mode = 0 */
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;
395                 /* mpg_in_mux = 1 */
396                 r3D |= PIN_MUX_MPG_IN_MUX_MASK;
397                 /* bt656_enable = 0 */
398                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
399                 /* i2s_enable = 1 */
400                 r15 |= PIN_MUX_I2S_ENABLE_MASK;
401                 /* spi_mode = 1 */
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 */
412                 r84 &= 0x0F;
413                 /* mdat_en_ctrl[7:4] = 0x0 */
414                 r89 &= 0x0F;
415                 break;
416         case PIN_MUX_TS_SPI_IN_MODE_0:
417                 /* mpeg_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;
423                 /* mpg_in_mux = 0 */
424                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
425                 /* bt656_enable = 0 */
426                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
427                 /* i2s_enable = 1 */
428                 r15 |= PIN_MUX_I2S_ENABLE_MASK;
429                 /* spi_mode = 1 */
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 */
440                 r84 &= 0x0F;
441                 /* mdat_en_ctrl[7:4] = 0x0 */
442                 r89 &= 0x0F;
443                 break;
444         case PIN_MUX_TS_PARALLEL_IN:
445                 /* mpeg_mode = 0 */
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;
451                 /* mpg_in_mux = 0 */
452                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
453                 /* bt656_enable = 0 */
454                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
455                 /* i2s_enable = 0 */
456                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
457                 /* spi_mode = 0 */
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 */
468                 r84 &= 0x0F;
469                 /* mdat_en_ctrl[7:4] = 0x0 */
470                 r89 &= 0x0F;
471                 break;
472         case PIN_MUX_BT656_I2S_MODE:
473                 /* mpeg_mode = 0 */
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;
479                 /* mpg_in_mux = 0 */
480                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
481                 /* bt656_enable = 1 */
482                 r12 |= PIN_MUX_BT656_ENABLE_MASK;
483                 /* i2s_enable = 1 */
484                 r15 |= PIN_MUX_I2S_ENABLE_MASK;
485                 /* spi_mode = 0 */
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 */
496                 r84 &= 0x0F;
497                 /* mdat_en_ctrl[7:4] = 0x0 */
498                 r89 &= 0x0F;
499                 break;
500         case PIN_MUX_DEFAULT:
501         default:
502                 /* mpeg_mode = 1 */
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;
508                 /* mpg_in_mux = 0 */
509                 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
510                 /* bt656_enable = 0 */
511                 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
512                 /* i2s_enable = 0 */
513                 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
514                 /* spi_mode = 0 */
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 */
525                 r84 &= 0x0F;
526                 /* mdat_en_ctrl[7:4] = 0x0 */
527                 r89 &= 0x0F;
528                 break;
529         }
530
531         ret = mxl111sf_write_reg(state, 0x17, r17);
532         if (mxl_fail(ret))
533                 goto fail;
534         ret = mxl111sf_write_reg(state, 0x18, r18);
535         if (mxl_fail(ret))
536                 goto fail;
537         ret = mxl111sf_write_reg(state, 0x12, r12);
538         if (mxl_fail(ret))
539                 goto fail;
540         ret = mxl111sf_write_reg(state, 0x15, r15);
541         if (mxl_fail(ret))
542                 goto fail;
543         ret = mxl111sf_write_reg(state, 0x82, r82);
544         if (mxl_fail(ret))
545                 goto fail;
546         ret = mxl111sf_write_reg(state, 0x84, r84);
547         if (mxl_fail(ret))
548                 goto fail;
549         ret = mxl111sf_write_reg(state, 0x89, r89);
550         if (mxl_fail(ret))
551                 goto fail;
552         ret = mxl111sf_write_reg(state, 0x3D, r3D);
553         if (mxl_fail(ret))
554                 goto fail;
555 fail:
556         return ret;
557 }
558
559 /* ------------------------------------------------------------------------- */
560
561 static int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val)
562 {
563         return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val);
564 }
565
566 static int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state)
567 {
568         u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */
569         int i, ret;
570
571         mxl_debug("()");
572
573         for (i = 3; i < 8; i++) {
574                 ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01);
575                 if (mxl_fail(ret))
576                         break;
577         }
578
579         return ret;
580 }
581
582 #define PCA9534_I2C_ADDR (0x40 >> 1)
583 static int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val)
584 {
585         u8 w[2] = { 1, 0 };
586         u8 r = 0;
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 },
592         };
593
594         mxl_debug("(%d, %d)", gpio, val);
595
596         /* read current GPIO levels from flip-flop */
597         i2c_transfer(&state->d->i2c_adap, msg, 2);
598
599         /* prepare write buffer with current GPIO levels */
600         msg[0].len = 2;
601 #if 0
602         w[0] = 1;
603 #endif
604         w[1] = r;
605
606         /* clear the desired GPIO */
607         w[1] &= ~(1 << gpio);
608
609         /* set the desired GPIO value */
610         w[1] |= ((val ? 1 : 0) << gpio);
611
612         /* write new GPIO levels to flip-flop */
613         i2c_transfer(&state->d->i2c_adap, &msg[0], 1);
614
615         return 0;
616 }
617
618 static int pca9534_init_port_expander(struct mxl111sf_state *state)
619 {
620         u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */
621
622         struct i2c_msg msg = {
623                 .addr = PCA9534_I2C_ADDR,
624                 .flags = 0, .buf = w, .len = 2
625         };
626
627         mxl_debug("()");
628
629         i2c_transfer(&state->d->i2c_adap, &msg, 1);
630
631         /* configure all pins as outputs */
632         w[0] = 3;
633         w[1] = 0;
634
635         i2c_transfer(&state->d->i2c_adap, &msg, 1);
636
637         return 0;
638 }
639
640 int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val)
641 {
642         mxl_debug("(%d, %d)", gpio, val);
643
644         switch (state->gpio_port_expander) {
645         default:
646                 mxl_printk(KERN_ERR,
647                            "gpio_port_expander undefined, assuming PCA9534");
648                 /* fall-thru */
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);
653         }
654 }
655
656 static int mxl111sf_probe_port_expander(struct mxl111sf_state *state)
657 {
658         int ret;
659         u8 w = 1;
660         u8 r = 0;
661         struct i2c_msg msg[] = {
662                 { .flags = 0,        .buf = &w, .len = 1 },
663                 { .flags = I2C_M_RD, .buf = &r, .len = 1 },
664         };
665
666         mxl_debug("()");
667
668         msg[0].addr = 0x70 >> 1;
669         msg[1].addr = 0x70 >> 1;
670
671         /* read current GPIO levels from flip-flop */
672         ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
673         if (ret == 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);
678                 return 0;
679         }
680
681         msg[0].addr = 0x40 >> 1;
682         msg[1].addr = 0x40 >> 1;
683
684         ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
685         if (ret == 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);
690                 return 0;
691         }
692         state->port_expander_addr = 0xff;
693         state->gpio_port_expander = mxl111sf_gpio_hw;
694         mxl_debug("using hardware gpio");
695         return 0;
696 }
697
698 int mxl111sf_init_port_expander(struct mxl111sf_state *state)
699 {
700         mxl_debug("()");
701
702         if (0x00 == state->port_expander_addr)
703                 mxl111sf_probe_port_expander(state);
704
705         switch (state->gpio_port_expander) {
706         default:
707                 mxl_printk(KERN_ERR,
708                            "gpio_port_expander undefined, assuming PCA9534");
709                 /* fall-thru */
710         case mxl111sf_PCA9534:
711                 return pca9534_init_port_expander(state);
712         case mxl111sf_gpio_hw:
713                 return mxl111sf_hw_gpio_initialize(state);
714         }
715 }
716
717 /* ------------------------------------------------------------------------ */
718
719 int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode)
720 {
721 /*      GPO:
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
727  */
728         mxl_debug("(%d)", mode);
729
730         switch (mode) {
731         case MXL111SF_GPIO_MOD_MH:
732                 mxl111sf_set_gpio(state, 4, 0);
733                 mxl111sf_set_gpio(state, 5, 0);
734                 msleep(50);
735                 mxl111sf_set_gpio(state, 7, 1);
736                 msleep(50);
737                 mxl111sf_set_gpio(state, 6, 1);
738                 msleep(50);
739
740                 mxl111sf_set_gpio(state, 3, 0);
741                 break;
742         case MXL111SF_GPIO_MOD_ATSC:
743                 mxl111sf_set_gpio(state, 6, 0);
744                 mxl111sf_set_gpio(state, 7, 0);
745                 msleep(50);
746                 mxl111sf_set_gpio(state, 5, 1);
747                 msleep(50);
748                 mxl111sf_set_gpio(state, 4, 1);
749                 msleep(50);
750                 mxl111sf_set_gpio(state, 3, 1);
751                 break;
752         default: /* DVBT / STANDBY */
753                 mxl111sf_init_port_expander(state);
754                 break;
755         }
756         return 0;
757 }