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