Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  mxl111sf-gpio.c - driver for the MaxLinear MXL111SF
0004  *
0005  *  Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org>
0006  */
0007 
0008 #include "mxl111sf-gpio.h"
0009 #include "mxl111sf-i2c.h"
0010 #include "mxl111sf.h"
0011 
0012 /* ------------------------------------------------------------------------- */
0013 
0014 #define MXL_GPIO_MUX_REG_0 0x84
0015 #define MXL_GPIO_MUX_REG_1 0x89
0016 #define MXL_GPIO_MUX_REG_2 0x82
0017 
0018 #define MXL_GPIO_DIR_INPUT  0
0019 #define MXL_GPIO_DIR_OUTPUT 1
0020 
0021 
0022 static int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val)
0023 {
0024     int ret;
0025     u8 tmp;
0026 
0027     mxl_debug_adv("(%d, %d)", pin, val);
0028 
0029     if ((pin > 0) && (pin < 8)) {
0030         ret = mxl111sf_read_reg(state, 0x19, &tmp);
0031         if (mxl_fail(ret))
0032             goto fail;
0033         tmp &= ~(1 << (pin - 1));
0034         tmp |= (val << (pin - 1));
0035         ret = mxl111sf_write_reg(state, 0x19, tmp);
0036         if (mxl_fail(ret))
0037             goto fail;
0038     } else if (pin <= 10) {
0039         if (pin == 0)
0040             pin += 7;
0041         ret = mxl111sf_read_reg(state, 0x30, &tmp);
0042         if (mxl_fail(ret))
0043             goto fail;
0044         tmp &= ~(1 << (pin - 3));
0045         tmp |= (val << (pin - 3));
0046         ret = mxl111sf_write_reg(state, 0x30, tmp);
0047         if (mxl_fail(ret))
0048             goto fail;
0049     } else
0050         ret = -EINVAL;
0051 fail:
0052     return ret;
0053 }
0054 
0055 static int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val)
0056 {
0057     int ret;
0058     u8 tmp;
0059 
0060     mxl_debug("(0x%02x)", pin);
0061 
0062     *val = 0;
0063 
0064     switch (pin) {
0065     case 0:
0066     case 1:
0067     case 2:
0068     case 3:
0069         ret = mxl111sf_read_reg(state, 0x23, &tmp);
0070         if (mxl_fail(ret))
0071             goto fail;
0072         *val = (tmp >> (pin + 4)) & 0x01;
0073         break;
0074     case 4:
0075     case 5:
0076     case 6:
0077     case 7:
0078         ret = mxl111sf_read_reg(state, 0x2f, &tmp);
0079         if (mxl_fail(ret))
0080             goto fail;
0081         *val = (tmp >> pin) & 0x01;
0082         break;
0083     case 8:
0084     case 9:
0085     case 10:
0086         ret = mxl111sf_read_reg(state, 0x22, &tmp);
0087         if (mxl_fail(ret))
0088             goto fail;
0089         *val = (tmp >> (pin - 3)) & 0x01;
0090         break;
0091     default:
0092         return -EINVAL; /* invalid pin */
0093     }
0094 fail:
0095     return ret;
0096 }
0097 
0098 struct mxl_gpio_cfg {
0099     u8 pin;
0100     u8 dir;
0101     u8 val;
0102 };
0103 
0104 static int mxl111sf_config_gpio_pins(struct mxl111sf_state *state,
0105                      struct mxl_gpio_cfg *gpio_cfg)
0106 {
0107     int ret;
0108     u8 tmp;
0109 
0110     mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir);
0111 
0112     switch (gpio_cfg->pin) {
0113     case 0:
0114     case 1:
0115     case 2:
0116     case 3:
0117         ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp);
0118         if (mxl_fail(ret))
0119             goto fail;
0120         tmp &= ~(1 << (gpio_cfg->pin + 4));
0121         tmp |= (gpio_cfg->dir << (gpio_cfg->pin + 4));
0122         ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_0, tmp);
0123         if (mxl_fail(ret))
0124             goto fail;
0125         break;
0126     case 4:
0127     case 5:
0128     case 6:
0129     case 7:
0130         ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp);
0131         if (mxl_fail(ret))
0132             goto fail;
0133         tmp &= ~(1 << gpio_cfg->pin);
0134         tmp |= (gpio_cfg->dir << gpio_cfg->pin);
0135         ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_1, tmp);
0136         if (mxl_fail(ret))
0137             goto fail;
0138         break;
0139     case 8:
0140     case 9:
0141     case 10:
0142         ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp);
0143         if (mxl_fail(ret))
0144             goto fail;
0145         tmp &= ~(1 << (gpio_cfg->pin - 3));
0146         tmp |= (gpio_cfg->dir << (gpio_cfg->pin - 3));
0147         ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_2, tmp);
0148         if (mxl_fail(ret))
0149             goto fail;
0150         break;
0151     default:
0152         return -EINVAL; /* invalid pin */
0153     }
0154 
0155     ret = (MXL_GPIO_DIR_OUTPUT == gpio_cfg->dir) ?
0156         mxl111sf_set_gpo_state(state,
0157                        gpio_cfg->pin, gpio_cfg->val) :
0158         mxl111sf_get_gpi_state(state,
0159                        gpio_cfg->pin, &gpio_cfg->val);
0160     mxl_fail(ret);
0161 fail:
0162     return ret;
0163 }
0164 
0165 static int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state,
0166                    int gpio, int direction, int val)
0167 {
0168     struct mxl_gpio_cfg gpio_config = {
0169         .pin = gpio,
0170         .dir = direction,
0171         .val = val,
0172     };
0173 
0174     mxl_debug("(%d, %d, %d)", gpio, direction, val);
0175 
0176     return mxl111sf_config_gpio_pins(state, &gpio_config);
0177 }
0178 
0179 /* ------------------------------------------------------------------------- */
0180 
0181 #define PIN_MUX_MPEG_MODE_MASK          0x40   /* 0x17 <6> */
0182 #define PIN_MUX_MPEG_PAR_EN_MASK        0x01   /* 0x18 <0> */
0183 #define PIN_MUX_MPEG_SER_EN_MASK        0x02   /* 0x18 <1> */
0184 #define PIN_MUX_MPG_IN_MUX_MASK         0x80   /* 0x3D <7> */
0185 #define PIN_MUX_BT656_ENABLE_MASK       0x04   /* 0x12 <2> */
0186 #define PIN_MUX_I2S_ENABLE_MASK         0x40   /* 0x15 <6> */
0187 #define PIN_MUX_SPI_MODE_MASK           0x10   /* 0x3D <4> */
0188 #define PIN_MUX_MCLK_EN_CTRL_MASK       0x10   /* 0x82 <4> */
0189 #define PIN_MUX_MPSYN_EN_CTRL_MASK      0x20   /* 0x82 <5> */
0190 #define PIN_MUX_MDVAL_EN_CTRL_MASK      0x40   /* 0x82 <6> */
0191 #define PIN_MUX_MPERR_EN_CTRL_MASK      0x80   /* 0x82 <7> */
0192 #define PIN_MUX_MDAT_EN_0_MASK          0x10   /* 0x84 <4> */
0193 #define PIN_MUX_MDAT_EN_1_MASK          0x20   /* 0x84 <5> */
0194 #define PIN_MUX_MDAT_EN_2_MASK          0x40   /* 0x84 <6> */
0195 #define PIN_MUX_MDAT_EN_3_MASK          0x80   /* 0x84 <7> */
0196 #define PIN_MUX_MDAT_EN_4_MASK          0x10   /* 0x89 <4> */
0197 #define PIN_MUX_MDAT_EN_5_MASK          0x20   /* 0x89 <5> */
0198 #define PIN_MUX_MDAT_EN_6_MASK          0x40   /* 0x89 <6> */
0199 #define PIN_MUX_MDAT_EN_7_MASK          0x80   /* 0x89 <7> */
0200 
0201 int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
0202                   enum mxl111sf_mux_config pin_mux_config)
0203 {
0204     u8 r12, r15, r17, r18, r3D, r82, r84, r89;
0205     int ret;
0206 
0207     mxl_debug("(%d)", pin_mux_config);
0208 
0209     ret = mxl111sf_read_reg(state, 0x17, &r17);
0210     if (mxl_fail(ret))
0211         goto fail;
0212     ret = mxl111sf_read_reg(state, 0x18, &r18);
0213     if (mxl_fail(ret))
0214         goto fail;
0215     ret = mxl111sf_read_reg(state, 0x12, &r12);
0216     if (mxl_fail(ret))
0217         goto fail;
0218     ret = mxl111sf_read_reg(state, 0x15, &r15);
0219     if (mxl_fail(ret))
0220         goto fail;
0221     ret = mxl111sf_read_reg(state, 0x82, &r82);
0222     if (mxl_fail(ret))
0223         goto fail;
0224     ret = mxl111sf_read_reg(state, 0x84, &r84);
0225     if (mxl_fail(ret))
0226         goto fail;
0227     ret = mxl111sf_read_reg(state, 0x89, &r89);
0228     if (mxl_fail(ret))
0229         goto fail;
0230     ret = mxl111sf_read_reg(state, 0x3D, &r3D);
0231     if (mxl_fail(ret))
0232         goto fail;
0233 
0234     switch (pin_mux_config) {
0235     case PIN_MUX_TS_OUT_PARALLEL:
0236         /* mpeg_mode = 1 */
0237         r17 |= PIN_MUX_MPEG_MODE_MASK;
0238         /* mpeg_par_en = 1 */
0239         r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
0240         /* mpeg_ser_en = 0 */
0241         r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
0242         /* mpg_in_mux = 0 */
0243         r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
0244         /* bt656_enable = 0 */
0245         r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
0246         /* i2s_enable = 0 */
0247         r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
0248         /* spi_mode = 0 */
0249         r3D &= ~PIN_MUX_SPI_MODE_MASK;
0250         /* mclk_en_ctrl = 1 */
0251         r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
0252         /* mperr_en_ctrl = 1 */
0253         r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
0254         /* mdval_en_ctrl = 1 */
0255         r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
0256         /* mpsyn_en_ctrl = 1 */
0257         r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
0258         /* mdat_en_ctrl[3:0] = 0xF */
0259         r84 |= 0xF0;
0260         /* mdat_en_ctrl[7:4] = 0xF */
0261         r89 |= 0xF0;
0262         break;
0263     case PIN_MUX_TS_OUT_SERIAL:
0264         /* mpeg_mode = 1 */
0265         r17 |= PIN_MUX_MPEG_MODE_MASK;
0266         /* mpeg_par_en = 0 */
0267         r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
0268         /* mpeg_ser_en = 1 */
0269         r18 |= PIN_MUX_MPEG_SER_EN_MASK;
0270         /* mpg_in_mux = 0 */
0271         r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
0272         /* bt656_enable = 0 */
0273         r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
0274         /* i2s_enable = 0 */
0275         r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
0276         /* spi_mode = 0 */
0277         r3D &= ~PIN_MUX_SPI_MODE_MASK;
0278         /* mclk_en_ctrl = 1 */
0279         r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
0280         /* mperr_en_ctrl = 1 */
0281         r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
0282         /* mdval_en_ctrl = 1 */
0283         r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
0284         /* mpsyn_en_ctrl = 1 */
0285         r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
0286         /* mdat_en_ctrl[3:0] = 0xF */
0287         r84 |= 0xF0;
0288         /* mdat_en_ctrl[7:4] = 0xF */
0289         r89 |= 0xF0;
0290         break;
0291     case PIN_MUX_GPIO_MODE:
0292         /* mpeg_mode = 0 */
0293         r17 &= ~PIN_MUX_MPEG_MODE_MASK;
0294         /* mpeg_par_en = 0 */
0295         r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
0296         /* mpeg_ser_en = 0 */
0297         r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
0298         /* mpg_in_mux = 0 */
0299         r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
0300         /* bt656_enable = 0 */
0301         r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
0302         /* i2s_enable = 0 */
0303         r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
0304         /* spi_mode = 0 */
0305         r3D &= ~PIN_MUX_SPI_MODE_MASK;
0306         /* mclk_en_ctrl = 0 */
0307         r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
0308         /* mperr_en_ctrl = 0 */
0309         r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
0310         /* mdval_en_ctrl = 0 */
0311         r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
0312         /* mpsyn_en_ctrl = 0 */
0313         r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
0314         /* mdat_en_ctrl[3:0] = 0x0 */
0315         r84 &= 0x0F;
0316         /* mdat_en_ctrl[7:4] = 0x0 */
0317         r89 &= 0x0F;
0318         break;
0319     case PIN_MUX_TS_SERIAL_IN_MODE_0:
0320         /* mpeg_mode = 0 */
0321         r17 &= ~PIN_MUX_MPEG_MODE_MASK;
0322         /* mpeg_par_en = 0 */
0323         r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
0324         /* mpeg_ser_en = 1 */
0325         r18 |= PIN_MUX_MPEG_SER_EN_MASK;
0326         /* mpg_in_mux = 0 */
0327         r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
0328         /* bt656_enable = 0 */
0329         r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
0330         /* i2s_enable = 0 */
0331         r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
0332         /* spi_mode = 0 */
0333         r3D &= ~PIN_MUX_SPI_MODE_MASK;
0334         /* mclk_en_ctrl = 0 */
0335         r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
0336         /* mperr_en_ctrl = 0 */
0337         r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
0338         /* mdval_en_ctrl = 0 */
0339         r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
0340         /* mpsyn_en_ctrl = 0 */
0341         r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
0342         /* mdat_en_ctrl[3:0] = 0x0 */
0343         r84 &= 0x0F;
0344         /* mdat_en_ctrl[7:4] = 0x0 */
0345         r89 &= 0x0F;
0346         break;
0347     case PIN_MUX_TS_SERIAL_IN_MODE_1:
0348         /* mpeg_mode = 0 */
0349         r17 &= ~PIN_MUX_MPEG_MODE_MASK;
0350         /* mpeg_par_en = 0 */
0351         r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
0352         /* mpeg_ser_en = 1 */
0353         r18 |= PIN_MUX_MPEG_SER_EN_MASK;
0354         /* mpg_in_mux = 1 */
0355         r3D |= PIN_MUX_MPG_IN_MUX_MASK;
0356         /* bt656_enable = 0 */
0357         r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
0358         /* i2s_enable = 0 */
0359         r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
0360         /* spi_mode = 0 */
0361         r3D &= ~PIN_MUX_SPI_MODE_MASK;
0362         /* mclk_en_ctrl = 0 */
0363         r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
0364         /* mperr_en_ctrl = 0 */
0365         r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
0366         /* mdval_en_ctrl = 0 */
0367         r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
0368         /* mpsyn_en_ctrl = 0 */
0369         r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
0370         /* mdat_en_ctrl[3:0] = 0x0 */
0371         r84 &= 0x0F;
0372         /* mdat_en_ctrl[7:4] = 0x0 */
0373         r89 &= 0x0F;
0374         break;
0375     case PIN_MUX_TS_SPI_IN_MODE_1:
0376         /* mpeg_mode = 0 */
0377         r17 &= ~PIN_MUX_MPEG_MODE_MASK;
0378         /* mpeg_par_en = 0 */
0379         r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
0380         /* mpeg_ser_en = 1 */
0381         r18 |= PIN_MUX_MPEG_SER_EN_MASK;
0382         /* mpg_in_mux = 1 */
0383         r3D |= PIN_MUX_MPG_IN_MUX_MASK;
0384         /* bt656_enable = 0 */
0385         r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
0386         /* i2s_enable = 1 */
0387         r15 |= PIN_MUX_I2S_ENABLE_MASK;
0388         /* spi_mode = 1 */
0389         r3D |= PIN_MUX_SPI_MODE_MASK;
0390         /* mclk_en_ctrl = 0 */
0391         r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
0392         /* mperr_en_ctrl = 0 */
0393         r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
0394         /* mdval_en_ctrl = 0 */
0395         r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
0396         /* mpsyn_en_ctrl = 0 */
0397         r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
0398         /* mdat_en_ctrl[3:0] = 0x0 */
0399         r84 &= 0x0F;
0400         /* mdat_en_ctrl[7:4] = 0x0 */
0401         r89 &= 0x0F;
0402         break;
0403     case PIN_MUX_TS_SPI_IN_MODE_0:
0404         /* mpeg_mode = 0 */
0405         r17 &= ~PIN_MUX_MPEG_MODE_MASK;
0406         /* mpeg_par_en = 0 */
0407         r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
0408         /* mpeg_ser_en = 1 */
0409         r18 |= PIN_MUX_MPEG_SER_EN_MASK;
0410         /* mpg_in_mux = 0 */
0411         r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
0412         /* bt656_enable = 0 */
0413         r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
0414         /* i2s_enable = 1 */
0415         r15 |= PIN_MUX_I2S_ENABLE_MASK;
0416         /* spi_mode = 1 */
0417         r3D |= PIN_MUX_SPI_MODE_MASK;
0418         /* mclk_en_ctrl = 0 */
0419         r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
0420         /* mperr_en_ctrl = 0 */
0421         r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
0422         /* mdval_en_ctrl = 0 */
0423         r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
0424         /* mpsyn_en_ctrl = 0 */
0425         r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
0426         /* mdat_en_ctrl[3:0] = 0x0 */
0427         r84 &= 0x0F;
0428         /* mdat_en_ctrl[7:4] = 0x0 */
0429         r89 &= 0x0F;
0430         break;
0431     case PIN_MUX_TS_PARALLEL_IN:
0432         /* mpeg_mode = 0 */
0433         r17 &= ~PIN_MUX_MPEG_MODE_MASK;
0434         /* mpeg_par_en = 1 */
0435         r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
0436         /* mpeg_ser_en = 0 */
0437         r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
0438         /* mpg_in_mux = 0 */
0439         r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
0440         /* bt656_enable = 0 */
0441         r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
0442         /* i2s_enable = 0 */
0443         r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
0444         /* spi_mode = 0 */
0445         r3D &= ~PIN_MUX_SPI_MODE_MASK;
0446         /* mclk_en_ctrl = 0 */
0447         r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
0448         /* mperr_en_ctrl = 0 */
0449         r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
0450         /* mdval_en_ctrl = 0 */
0451         r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
0452         /* mpsyn_en_ctrl = 0 */
0453         r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
0454         /* mdat_en_ctrl[3:0] = 0x0 */
0455         r84 &= 0x0F;
0456         /* mdat_en_ctrl[7:4] = 0x0 */
0457         r89 &= 0x0F;
0458         break;
0459     case PIN_MUX_BT656_I2S_MODE:
0460         /* mpeg_mode = 0 */
0461         r17 &= ~PIN_MUX_MPEG_MODE_MASK;
0462         /* mpeg_par_en = 0 */
0463         r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
0464         /* mpeg_ser_en = 0 */
0465         r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
0466         /* mpg_in_mux = 0 */
0467         r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
0468         /* bt656_enable = 1 */
0469         r12 |= PIN_MUX_BT656_ENABLE_MASK;
0470         /* i2s_enable = 1 */
0471         r15 |= PIN_MUX_I2S_ENABLE_MASK;
0472         /* spi_mode = 0 */
0473         r3D &= ~PIN_MUX_SPI_MODE_MASK;
0474         /* mclk_en_ctrl = 0 */
0475         r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
0476         /* mperr_en_ctrl = 0 */
0477         r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
0478         /* mdval_en_ctrl = 0 */
0479         r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
0480         /* mpsyn_en_ctrl = 0 */
0481         r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
0482         /* mdat_en_ctrl[3:0] = 0x0 */
0483         r84 &= 0x0F;
0484         /* mdat_en_ctrl[7:4] = 0x0 */
0485         r89 &= 0x0F;
0486         break;
0487     case PIN_MUX_DEFAULT:
0488     default:
0489         /* mpeg_mode = 1 */
0490         r17 |= PIN_MUX_MPEG_MODE_MASK;
0491         /* mpeg_par_en = 0 */
0492         r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
0493         /* mpeg_ser_en = 0 */
0494         r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
0495         /* mpg_in_mux = 0 */
0496         r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
0497         /* bt656_enable = 0 */
0498         r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
0499         /* i2s_enable = 0 */
0500         r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
0501         /* spi_mode = 0 */
0502         r3D &= ~PIN_MUX_SPI_MODE_MASK;
0503         /* mclk_en_ctrl = 0 */
0504         r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
0505         /* mperr_en_ctrl = 0 */
0506         r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
0507         /* mdval_en_ctrl = 0 */
0508         r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
0509         /* mpsyn_en_ctrl = 0 */
0510         r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
0511         /* mdat_en_ctrl[3:0] = 0x0 */
0512         r84 &= 0x0F;
0513         /* mdat_en_ctrl[7:4] = 0x0 */
0514         r89 &= 0x0F;
0515         break;
0516     }
0517 
0518     ret = mxl111sf_write_reg(state, 0x17, r17);
0519     if (mxl_fail(ret))
0520         goto fail;
0521     ret = mxl111sf_write_reg(state, 0x18, r18);
0522     if (mxl_fail(ret))
0523         goto fail;
0524     ret = mxl111sf_write_reg(state, 0x12, r12);
0525     if (mxl_fail(ret))
0526         goto fail;
0527     ret = mxl111sf_write_reg(state, 0x15, r15);
0528     if (mxl_fail(ret))
0529         goto fail;
0530     ret = mxl111sf_write_reg(state, 0x82, r82);
0531     if (mxl_fail(ret))
0532         goto fail;
0533     ret = mxl111sf_write_reg(state, 0x84, r84);
0534     if (mxl_fail(ret))
0535         goto fail;
0536     ret = mxl111sf_write_reg(state, 0x89, r89);
0537     if (mxl_fail(ret))
0538         goto fail;
0539     ret = mxl111sf_write_reg(state, 0x3D, r3D);
0540     if (mxl_fail(ret))
0541         goto fail;
0542 fail:
0543     return ret;
0544 }
0545 
0546 /* ------------------------------------------------------------------------- */
0547 
0548 static int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val)
0549 {
0550     return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val);
0551 }
0552 
0553 static int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state)
0554 {
0555     u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */
0556     int i, ret;
0557 
0558     mxl_debug("()");
0559 
0560     for (i = 3; i < 8; i++) {
0561         ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01);
0562         if (mxl_fail(ret))
0563             break;
0564     }
0565 
0566     return ret;
0567 }
0568 
0569 #define PCA9534_I2C_ADDR (0x40 >> 1)
0570 static int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val)
0571 {
0572     u8 w[2] = { 1, 0 };
0573     u8 r = 0;
0574     struct i2c_msg msg[] = {
0575         { .addr = PCA9534_I2C_ADDR,
0576           .flags = 0, .buf = w, .len = 1 },
0577         { .addr = PCA9534_I2C_ADDR,
0578           .flags = I2C_M_RD, .buf = &r, .len = 1 },
0579     };
0580 
0581     mxl_debug("(%d, %d)", gpio, val);
0582 
0583     /* read current GPIO levels from flip-flop */
0584     i2c_transfer(&state->d->i2c_adap, msg, 2);
0585 
0586     /* prepare write buffer with current GPIO levels */
0587     msg[0].len = 2;
0588 #if 0
0589     w[0] = 1;
0590 #endif
0591     w[1] = r;
0592 
0593     /* clear the desired GPIO */
0594     w[1] &= ~(1 << gpio);
0595 
0596     /* set the desired GPIO value */
0597     w[1] |= ((val ? 1 : 0) << gpio);
0598 
0599     /* write new GPIO levels to flip-flop */
0600     i2c_transfer(&state->d->i2c_adap, &msg[0], 1);
0601 
0602     return 0;
0603 }
0604 
0605 static int pca9534_init_port_expander(struct mxl111sf_state *state)
0606 {
0607     u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */
0608 
0609     struct i2c_msg msg = {
0610         .addr = PCA9534_I2C_ADDR,
0611         .flags = 0, .buf = w, .len = 2
0612     };
0613 
0614     mxl_debug("()");
0615 
0616     i2c_transfer(&state->d->i2c_adap, &msg, 1);
0617 
0618     /* configure all pins as outputs */
0619     w[0] = 3;
0620     w[1] = 0;
0621 
0622     i2c_transfer(&state->d->i2c_adap, &msg, 1);
0623 
0624     return 0;
0625 }
0626 
0627 int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val)
0628 {
0629     mxl_debug("(%d, %d)", gpio, val);
0630 
0631     switch (state->gpio_port_expander) {
0632     default:
0633         mxl_printk(KERN_ERR,
0634                "gpio_port_expander undefined, assuming PCA9534");
0635         fallthrough;
0636     case mxl111sf_PCA9534:
0637         return pca9534_set_gpio(state, gpio, val);
0638     case mxl111sf_gpio_hw:
0639         return mxl111sf_hw_set_gpio(state, gpio, val);
0640     }
0641 }
0642 
0643 static int mxl111sf_probe_port_expander(struct mxl111sf_state *state)
0644 {
0645     int ret;
0646     u8 w = 1;
0647     u8 r = 0;
0648     struct i2c_msg msg[] = {
0649         { .flags = 0,        .buf = &w, .len = 1 },
0650         { .flags = I2C_M_RD, .buf = &r, .len = 1 },
0651     };
0652 
0653     mxl_debug("()");
0654 
0655     msg[0].addr = 0x70 >> 1;
0656     msg[1].addr = 0x70 >> 1;
0657 
0658     /* read current GPIO levels from flip-flop */
0659     ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
0660     if (ret == 2) {
0661         state->port_expander_addr = msg[0].addr;
0662         state->gpio_port_expander = mxl111sf_PCA9534;
0663         mxl_debug("found port expander at 0x%02x",
0664               state->port_expander_addr);
0665         return 0;
0666     }
0667 
0668     msg[0].addr = 0x40 >> 1;
0669     msg[1].addr = 0x40 >> 1;
0670 
0671     ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
0672     if (ret == 2) {
0673         state->port_expander_addr = msg[0].addr;
0674         state->gpio_port_expander = mxl111sf_PCA9534;
0675         mxl_debug("found port expander at 0x%02x",
0676               state->port_expander_addr);
0677         return 0;
0678     }
0679     state->port_expander_addr = 0xff;
0680     state->gpio_port_expander = mxl111sf_gpio_hw;
0681     mxl_debug("using hardware gpio");
0682     return 0;
0683 }
0684 
0685 int mxl111sf_init_port_expander(struct mxl111sf_state *state)
0686 {
0687     mxl_debug("()");
0688 
0689     if (0x00 == state->port_expander_addr)
0690         mxl111sf_probe_port_expander(state);
0691 
0692     switch (state->gpio_port_expander) {
0693     default:
0694         mxl_printk(KERN_ERR,
0695                "gpio_port_expander undefined, assuming PCA9534");
0696         fallthrough;
0697     case mxl111sf_PCA9534:
0698         return pca9534_init_port_expander(state);
0699     case mxl111sf_gpio_hw:
0700         return mxl111sf_hw_gpio_initialize(state);
0701     }
0702 }
0703 
0704 /* ------------------------------------------------------------------------ */
0705 
0706 int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode)
0707 {
0708 /*  GPO:
0709  *  3 - ATSC/MH#   | 1 = ATSC transport, 0 = MH transport      | default 0
0710  *  4 - ATSC_RST## | 1 = ATSC enable, 0 = ATSC Reset           | default 0
0711  *  5 - ATSC_EN    | 1 = ATSC power enable, 0 = ATSC power off | default 0
0712  *  6 - MH_RESET#  | 1 = MH enable, 0 = MH Reset               | default 0
0713  *  7 - MH_EN      | 1 = MH power enable, 0 = MH power off     | default 0
0714  */
0715     mxl_debug("(%d)", mode);
0716 
0717     switch (mode) {
0718     case MXL111SF_GPIO_MOD_MH:
0719         mxl111sf_set_gpio(state, 4, 0);
0720         mxl111sf_set_gpio(state, 5, 0);
0721         msleep(50);
0722         mxl111sf_set_gpio(state, 7, 1);
0723         msleep(50);
0724         mxl111sf_set_gpio(state, 6, 1);
0725         msleep(50);
0726 
0727         mxl111sf_set_gpio(state, 3, 0);
0728         break;
0729     case MXL111SF_GPIO_MOD_ATSC:
0730         mxl111sf_set_gpio(state, 6, 0);
0731         mxl111sf_set_gpio(state, 7, 0);
0732         msleep(50);
0733         mxl111sf_set_gpio(state, 5, 1);
0734         msleep(50);
0735         mxl111sf_set_gpio(state, 4, 1);
0736         msleep(50);
0737         mxl111sf_set_gpio(state, 3, 1);
0738         break;
0739     default: /* DVBT / STANDBY */
0740         mxl111sf_init_port_expander(state);
0741         break;
0742     }
0743     return 0;
0744 }