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