root/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mxl111sf_set_gpo_state
  2. mxl111sf_get_gpi_state
  3. mxl111sf_config_gpio_pins
  4. mxl111sf_hw_do_set_gpio
  5. mxl111sf_config_pin_mux_modes
  6. mxl111sf_hw_set_gpio
  7. mxl111sf_hw_gpio_initialize
  8. pca9534_set_gpio
  9. pca9534_init_port_expander
  10. mxl111sf_set_gpio
  11. mxl111sf_probe_port_expander
  12. mxl111sf_init_port_expander
  13. mxl111sf_gpio_mode_switch

   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                 /* fall-thru */
 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                 /* fall-thru */
 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 }

/* [<][>][^][v][top][bottom][index][help] */