18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * mxl111sf-gpio.c - driver for the MaxLinear MXL111SF 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "mxl111sf-gpio.h" 98c2ecf20Sopenharmony_ci#include "mxl111sf-i2c.h" 108c2ecf20Sopenharmony_ci#include "mxl111sf.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* ------------------------------------------------------------------------- */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define MXL_GPIO_MUX_REG_0 0x84 158c2ecf20Sopenharmony_ci#define MXL_GPIO_MUX_REG_1 0x89 168c2ecf20Sopenharmony_ci#define MXL_GPIO_MUX_REG_2 0x82 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define MXL_GPIO_DIR_INPUT 0 198c2ecf20Sopenharmony_ci#define MXL_GPIO_DIR_OUTPUT 1 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci int ret; 258c2ecf20Sopenharmony_ci u8 tmp; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci mxl_debug_adv("(%d, %d)", pin, val); 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci if ((pin > 0) && (pin < 8)) { 308c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x19, &tmp); 318c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 328c2ecf20Sopenharmony_ci goto fail; 338c2ecf20Sopenharmony_ci tmp &= ~(1 << (pin - 1)); 348c2ecf20Sopenharmony_ci tmp |= (val << (pin - 1)); 358c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x19, tmp); 368c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 378c2ecf20Sopenharmony_ci goto fail; 388c2ecf20Sopenharmony_ci } else if (pin <= 10) { 398c2ecf20Sopenharmony_ci if (pin == 0) 408c2ecf20Sopenharmony_ci pin += 7; 418c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x30, &tmp); 428c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 438c2ecf20Sopenharmony_ci goto fail; 448c2ecf20Sopenharmony_ci tmp &= ~(1 << (pin - 3)); 458c2ecf20Sopenharmony_ci tmp |= (val << (pin - 3)); 468c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x30, tmp); 478c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 488c2ecf20Sopenharmony_ci goto fail; 498c2ecf20Sopenharmony_ci } else 508c2ecf20Sopenharmony_ci ret = -EINVAL; 518c2ecf20Sopenharmony_cifail: 528c2ecf20Sopenharmony_ci return ret; 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci int ret; 588c2ecf20Sopenharmony_ci u8 tmp; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci mxl_debug("(0x%02x)", pin); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci *val = 0; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci switch (pin) { 658c2ecf20Sopenharmony_ci case 0: 668c2ecf20Sopenharmony_ci case 1: 678c2ecf20Sopenharmony_ci case 2: 688c2ecf20Sopenharmony_ci case 3: 698c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x23, &tmp); 708c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 718c2ecf20Sopenharmony_ci goto fail; 728c2ecf20Sopenharmony_ci *val = (tmp >> (pin + 4)) & 0x01; 738c2ecf20Sopenharmony_ci break; 748c2ecf20Sopenharmony_ci case 4: 758c2ecf20Sopenharmony_ci case 5: 768c2ecf20Sopenharmony_ci case 6: 778c2ecf20Sopenharmony_ci case 7: 788c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x2f, &tmp); 798c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 808c2ecf20Sopenharmony_ci goto fail; 818c2ecf20Sopenharmony_ci *val = (tmp >> pin) & 0x01; 828c2ecf20Sopenharmony_ci break; 838c2ecf20Sopenharmony_ci case 8: 848c2ecf20Sopenharmony_ci case 9: 858c2ecf20Sopenharmony_ci case 10: 868c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x22, &tmp); 878c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 888c2ecf20Sopenharmony_ci goto fail; 898c2ecf20Sopenharmony_ci *val = (tmp >> (pin - 3)) & 0x01; 908c2ecf20Sopenharmony_ci break; 918c2ecf20Sopenharmony_ci default: 928c2ecf20Sopenharmony_ci return -EINVAL; /* invalid pin */ 938c2ecf20Sopenharmony_ci } 948c2ecf20Sopenharmony_cifail: 958c2ecf20Sopenharmony_ci return ret; 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistruct mxl_gpio_cfg { 998c2ecf20Sopenharmony_ci u8 pin; 1008c2ecf20Sopenharmony_ci u8 dir; 1018c2ecf20Sopenharmony_ci u8 val; 1028c2ecf20Sopenharmony_ci}; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistatic int mxl111sf_config_gpio_pins(struct mxl111sf_state *state, 1058c2ecf20Sopenharmony_ci struct mxl_gpio_cfg *gpio_cfg) 1068c2ecf20Sopenharmony_ci{ 1078c2ecf20Sopenharmony_ci int ret; 1088c2ecf20Sopenharmony_ci u8 tmp; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci switch (gpio_cfg->pin) { 1138c2ecf20Sopenharmony_ci case 0: 1148c2ecf20Sopenharmony_ci case 1: 1158c2ecf20Sopenharmony_ci case 2: 1168c2ecf20Sopenharmony_ci case 3: 1178c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp); 1188c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 1198c2ecf20Sopenharmony_ci goto fail; 1208c2ecf20Sopenharmony_ci tmp &= ~(1 << (gpio_cfg->pin + 4)); 1218c2ecf20Sopenharmony_ci tmp |= (gpio_cfg->dir << (gpio_cfg->pin + 4)); 1228c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_0, tmp); 1238c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 1248c2ecf20Sopenharmony_ci goto fail; 1258c2ecf20Sopenharmony_ci break; 1268c2ecf20Sopenharmony_ci case 4: 1278c2ecf20Sopenharmony_ci case 5: 1288c2ecf20Sopenharmony_ci case 6: 1298c2ecf20Sopenharmony_ci case 7: 1308c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp); 1318c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 1328c2ecf20Sopenharmony_ci goto fail; 1338c2ecf20Sopenharmony_ci tmp &= ~(1 << gpio_cfg->pin); 1348c2ecf20Sopenharmony_ci tmp |= (gpio_cfg->dir << gpio_cfg->pin); 1358c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_1, tmp); 1368c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 1378c2ecf20Sopenharmony_ci goto fail; 1388c2ecf20Sopenharmony_ci break; 1398c2ecf20Sopenharmony_ci case 8: 1408c2ecf20Sopenharmony_ci case 9: 1418c2ecf20Sopenharmony_ci case 10: 1428c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp); 1438c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 1448c2ecf20Sopenharmony_ci goto fail; 1458c2ecf20Sopenharmony_ci tmp &= ~(1 << (gpio_cfg->pin - 3)); 1468c2ecf20Sopenharmony_ci tmp |= (gpio_cfg->dir << (gpio_cfg->pin - 3)); 1478c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_2, tmp); 1488c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 1498c2ecf20Sopenharmony_ci goto fail; 1508c2ecf20Sopenharmony_ci break; 1518c2ecf20Sopenharmony_ci default: 1528c2ecf20Sopenharmony_ci return -EINVAL; /* invalid pin */ 1538c2ecf20Sopenharmony_ci } 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci ret = (MXL_GPIO_DIR_OUTPUT == gpio_cfg->dir) ? 1568c2ecf20Sopenharmony_ci mxl111sf_set_gpo_state(state, 1578c2ecf20Sopenharmony_ci gpio_cfg->pin, gpio_cfg->val) : 1588c2ecf20Sopenharmony_ci mxl111sf_get_gpi_state(state, 1598c2ecf20Sopenharmony_ci gpio_cfg->pin, &gpio_cfg->val); 1608c2ecf20Sopenharmony_ci mxl_fail(ret); 1618c2ecf20Sopenharmony_cifail: 1628c2ecf20Sopenharmony_ci return ret; 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state, 1668c2ecf20Sopenharmony_ci int gpio, int direction, int val) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci struct mxl_gpio_cfg gpio_config = { 1698c2ecf20Sopenharmony_ci .pin = gpio, 1708c2ecf20Sopenharmony_ci .dir = direction, 1718c2ecf20Sopenharmony_ci .val = val, 1728c2ecf20Sopenharmony_ci }; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci mxl_debug("(%d, %d, %d)", gpio, direction, val); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci return mxl111sf_config_gpio_pins(state, &gpio_config); 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci/* ------------------------------------------------------------------------- */ 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci#define PIN_MUX_MPEG_MODE_MASK 0x40 /* 0x17 <6> */ 1828c2ecf20Sopenharmony_ci#define PIN_MUX_MPEG_PAR_EN_MASK 0x01 /* 0x18 <0> */ 1838c2ecf20Sopenharmony_ci#define PIN_MUX_MPEG_SER_EN_MASK 0x02 /* 0x18 <1> */ 1848c2ecf20Sopenharmony_ci#define PIN_MUX_MPG_IN_MUX_MASK 0x80 /* 0x3D <7> */ 1858c2ecf20Sopenharmony_ci#define PIN_MUX_BT656_ENABLE_MASK 0x04 /* 0x12 <2> */ 1868c2ecf20Sopenharmony_ci#define PIN_MUX_I2S_ENABLE_MASK 0x40 /* 0x15 <6> */ 1878c2ecf20Sopenharmony_ci#define PIN_MUX_SPI_MODE_MASK 0x10 /* 0x3D <4> */ 1888c2ecf20Sopenharmony_ci#define PIN_MUX_MCLK_EN_CTRL_MASK 0x10 /* 0x82 <4> */ 1898c2ecf20Sopenharmony_ci#define PIN_MUX_MPSYN_EN_CTRL_MASK 0x20 /* 0x82 <5> */ 1908c2ecf20Sopenharmony_ci#define PIN_MUX_MDVAL_EN_CTRL_MASK 0x40 /* 0x82 <6> */ 1918c2ecf20Sopenharmony_ci#define PIN_MUX_MPERR_EN_CTRL_MASK 0x80 /* 0x82 <7> */ 1928c2ecf20Sopenharmony_ci#define PIN_MUX_MDAT_EN_0_MASK 0x10 /* 0x84 <4> */ 1938c2ecf20Sopenharmony_ci#define PIN_MUX_MDAT_EN_1_MASK 0x20 /* 0x84 <5> */ 1948c2ecf20Sopenharmony_ci#define PIN_MUX_MDAT_EN_2_MASK 0x40 /* 0x84 <6> */ 1958c2ecf20Sopenharmony_ci#define PIN_MUX_MDAT_EN_3_MASK 0x80 /* 0x84 <7> */ 1968c2ecf20Sopenharmony_ci#define PIN_MUX_MDAT_EN_4_MASK 0x10 /* 0x89 <4> */ 1978c2ecf20Sopenharmony_ci#define PIN_MUX_MDAT_EN_5_MASK 0x20 /* 0x89 <5> */ 1988c2ecf20Sopenharmony_ci#define PIN_MUX_MDAT_EN_6_MASK 0x40 /* 0x89 <6> */ 1998c2ecf20Sopenharmony_ci#define PIN_MUX_MDAT_EN_7_MASK 0x80 /* 0x89 <7> */ 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ciint mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state, 2028c2ecf20Sopenharmony_ci enum mxl111sf_mux_config pin_mux_config) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci u8 r12, r15, r17, r18, r3D, r82, r84, r89; 2058c2ecf20Sopenharmony_ci int ret; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci mxl_debug("(%d)", pin_mux_config); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x17, &r17); 2108c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 2118c2ecf20Sopenharmony_ci goto fail; 2128c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x18, &r18); 2138c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 2148c2ecf20Sopenharmony_ci goto fail; 2158c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x12, &r12); 2168c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 2178c2ecf20Sopenharmony_ci goto fail; 2188c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x15, &r15); 2198c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 2208c2ecf20Sopenharmony_ci goto fail; 2218c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x82, &r82); 2228c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 2238c2ecf20Sopenharmony_ci goto fail; 2248c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x84, &r84); 2258c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 2268c2ecf20Sopenharmony_ci goto fail; 2278c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x89, &r89); 2288c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 2298c2ecf20Sopenharmony_ci goto fail; 2308c2ecf20Sopenharmony_ci ret = mxl111sf_read_reg(state, 0x3D, &r3D); 2318c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 2328c2ecf20Sopenharmony_ci goto fail; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci switch (pin_mux_config) { 2358c2ecf20Sopenharmony_ci case PIN_MUX_TS_OUT_PARALLEL: 2368c2ecf20Sopenharmony_ci /* mpeg_mode = 1 */ 2378c2ecf20Sopenharmony_ci r17 |= PIN_MUX_MPEG_MODE_MASK; 2388c2ecf20Sopenharmony_ci /* mpeg_par_en = 1 */ 2398c2ecf20Sopenharmony_ci r18 |= PIN_MUX_MPEG_PAR_EN_MASK; 2408c2ecf20Sopenharmony_ci /* mpeg_ser_en = 0 */ 2418c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_SER_EN_MASK; 2428c2ecf20Sopenharmony_ci /* mpg_in_mux = 0 */ 2438c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_MPG_IN_MUX_MASK; 2448c2ecf20Sopenharmony_ci /* bt656_enable = 0 */ 2458c2ecf20Sopenharmony_ci r12 &= ~PIN_MUX_BT656_ENABLE_MASK; 2468c2ecf20Sopenharmony_ci /* i2s_enable = 0 */ 2478c2ecf20Sopenharmony_ci r15 &= ~PIN_MUX_I2S_ENABLE_MASK; 2488c2ecf20Sopenharmony_ci /* spi_mode = 0 */ 2498c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_SPI_MODE_MASK; 2508c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 1 */ 2518c2ecf20Sopenharmony_ci r82 |= PIN_MUX_MCLK_EN_CTRL_MASK; 2528c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 1 */ 2538c2ecf20Sopenharmony_ci r82 |= PIN_MUX_MPERR_EN_CTRL_MASK; 2548c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 1 */ 2558c2ecf20Sopenharmony_ci r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK; 2568c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 1 */ 2578c2ecf20Sopenharmony_ci r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK; 2588c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0xF */ 2598c2ecf20Sopenharmony_ci r84 |= 0xF0; 2608c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0xF */ 2618c2ecf20Sopenharmony_ci r89 |= 0xF0; 2628c2ecf20Sopenharmony_ci break; 2638c2ecf20Sopenharmony_ci case PIN_MUX_TS_OUT_SERIAL: 2648c2ecf20Sopenharmony_ci /* mpeg_mode = 1 */ 2658c2ecf20Sopenharmony_ci r17 |= PIN_MUX_MPEG_MODE_MASK; 2668c2ecf20Sopenharmony_ci /* mpeg_par_en = 0 */ 2678c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK; 2688c2ecf20Sopenharmony_ci /* mpeg_ser_en = 1 */ 2698c2ecf20Sopenharmony_ci r18 |= PIN_MUX_MPEG_SER_EN_MASK; 2708c2ecf20Sopenharmony_ci /* mpg_in_mux = 0 */ 2718c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_MPG_IN_MUX_MASK; 2728c2ecf20Sopenharmony_ci /* bt656_enable = 0 */ 2738c2ecf20Sopenharmony_ci r12 &= ~PIN_MUX_BT656_ENABLE_MASK; 2748c2ecf20Sopenharmony_ci /* i2s_enable = 0 */ 2758c2ecf20Sopenharmony_ci r15 &= ~PIN_MUX_I2S_ENABLE_MASK; 2768c2ecf20Sopenharmony_ci /* spi_mode = 0 */ 2778c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_SPI_MODE_MASK; 2788c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 1 */ 2798c2ecf20Sopenharmony_ci r82 |= PIN_MUX_MCLK_EN_CTRL_MASK; 2808c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 1 */ 2818c2ecf20Sopenharmony_ci r82 |= PIN_MUX_MPERR_EN_CTRL_MASK; 2828c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 1 */ 2838c2ecf20Sopenharmony_ci r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK; 2848c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 1 */ 2858c2ecf20Sopenharmony_ci r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK; 2868c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0xF */ 2878c2ecf20Sopenharmony_ci r84 |= 0xF0; 2888c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0xF */ 2898c2ecf20Sopenharmony_ci r89 |= 0xF0; 2908c2ecf20Sopenharmony_ci break; 2918c2ecf20Sopenharmony_ci case PIN_MUX_GPIO_MODE: 2928c2ecf20Sopenharmony_ci /* mpeg_mode = 0 */ 2938c2ecf20Sopenharmony_ci r17 &= ~PIN_MUX_MPEG_MODE_MASK; 2948c2ecf20Sopenharmony_ci /* mpeg_par_en = 0 */ 2958c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK; 2968c2ecf20Sopenharmony_ci /* mpeg_ser_en = 0 */ 2978c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_SER_EN_MASK; 2988c2ecf20Sopenharmony_ci /* mpg_in_mux = 0 */ 2998c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_MPG_IN_MUX_MASK; 3008c2ecf20Sopenharmony_ci /* bt656_enable = 0 */ 3018c2ecf20Sopenharmony_ci r12 &= ~PIN_MUX_BT656_ENABLE_MASK; 3028c2ecf20Sopenharmony_ci /* i2s_enable = 0 */ 3038c2ecf20Sopenharmony_ci r15 &= ~PIN_MUX_I2S_ENABLE_MASK; 3048c2ecf20Sopenharmony_ci /* spi_mode = 0 */ 3058c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_SPI_MODE_MASK; 3068c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 0 */ 3078c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK; 3088c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 0 */ 3098c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK; 3108c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 0 */ 3118c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK; 3128c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 0 */ 3138c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK; 3148c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0x0 */ 3158c2ecf20Sopenharmony_ci r84 &= 0x0F; 3168c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0x0 */ 3178c2ecf20Sopenharmony_ci r89 &= 0x0F; 3188c2ecf20Sopenharmony_ci break; 3198c2ecf20Sopenharmony_ci case PIN_MUX_TS_SERIAL_IN_MODE_0: 3208c2ecf20Sopenharmony_ci /* mpeg_mode = 0 */ 3218c2ecf20Sopenharmony_ci r17 &= ~PIN_MUX_MPEG_MODE_MASK; 3228c2ecf20Sopenharmony_ci /* mpeg_par_en = 0 */ 3238c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK; 3248c2ecf20Sopenharmony_ci /* mpeg_ser_en = 1 */ 3258c2ecf20Sopenharmony_ci r18 |= PIN_MUX_MPEG_SER_EN_MASK; 3268c2ecf20Sopenharmony_ci /* mpg_in_mux = 0 */ 3278c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_MPG_IN_MUX_MASK; 3288c2ecf20Sopenharmony_ci /* bt656_enable = 0 */ 3298c2ecf20Sopenharmony_ci r12 &= ~PIN_MUX_BT656_ENABLE_MASK; 3308c2ecf20Sopenharmony_ci /* i2s_enable = 0 */ 3318c2ecf20Sopenharmony_ci r15 &= ~PIN_MUX_I2S_ENABLE_MASK; 3328c2ecf20Sopenharmony_ci /* spi_mode = 0 */ 3338c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_SPI_MODE_MASK; 3348c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 0 */ 3358c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK; 3368c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 0 */ 3378c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK; 3388c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 0 */ 3398c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK; 3408c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 0 */ 3418c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK; 3428c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0x0 */ 3438c2ecf20Sopenharmony_ci r84 &= 0x0F; 3448c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0x0 */ 3458c2ecf20Sopenharmony_ci r89 &= 0x0F; 3468c2ecf20Sopenharmony_ci break; 3478c2ecf20Sopenharmony_ci case PIN_MUX_TS_SERIAL_IN_MODE_1: 3488c2ecf20Sopenharmony_ci /* mpeg_mode = 0 */ 3498c2ecf20Sopenharmony_ci r17 &= ~PIN_MUX_MPEG_MODE_MASK; 3508c2ecf20Sopenharmony_ci /* mpeg_par_en = 0 */ 3518c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK; 3528c2ecf20Sopenharmony_ci /* mpeg_ser_en = 1 */ 3538c2ecf20Sopenharmony_ci r18 |= PIN_MUX_MPEG_SER_EN_MASK; 3548c2ecf20Sopenharmony_ci /* mpg_in_mux = 1 */ 3558c2ecf20Sopenharmony_ci r3D |= PIN_MUX_MPG_IN_MUX_MASK; 3568c2ecf20Sopenharmony_ci /* bt656_enable = 0 */ 3578c2ecf20Sopenharmony_ci r12 &= ~PIN_MUX_BT656_ENABLE_MASK; 3588c2ecf20Sopenharmony_ci /* i2s_enable = 0 */ 3598c2ecf20Sopenharmony_ci r15 &= ~PIN_MUX_I2S_ENABLE_MASK; 3608c2ecf20Sopenharmony_ci /* spi_mode = 0 */ 3618c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_SPI_MODE_MASK; 3628c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 0 */ 3638c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK; 3648c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 0 */ 3658c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK; 3668c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 0 */ 3678c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK; 3688c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 0 */ 3698c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK; 3708c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0x0 */ 3718c2ecf20Sopenharmony_ci r84 &= 0x0F; 3728c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0x0 */ 3738c2ecf20Sopenharmony_ci r89 &= 0x0F; 3748c2ecf20Sopenharmony_ci break; 3758c2ecf20Sopenharmony_ci case PIN_MUX_TS_SPI_IN_MODE_1: 3768c2ecf20Sopenharmony_ci /* mpeg_mode = 0 */ 3778c2ecf20Sopenharmony_ci r17 &= ~PIN_MUX_MPEG_MODE_MASK; 3788c2ecf20Sopenharmony_ci /* mpeg_par_en = 0 */ 3798c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK; 3808c2ecf20Sopenharmony_ci /* mpeg_ser_en = 1 */ 3818c2ecf20Sopenharmony_ci r18 |= PIN_MUX_MPEG_SER_EN_MASK; 3828c2ecf20Sopenharmony_ci /* mpg_in_mux = 1 */ 3838c2ecf20Sopenharmony_ci r3D |= PIN_MUX_MPG_IN_MUX_MASK; 3848c2ecf20Sopenharmony_ci /* bt656_enable = 0 */ 3858c2ecf20Sopenharmony_ci r12 &= ~PIN_MUX_BT656_ENABLE_MASK; 3868c2ecf20Sopenharmony_ci /* i2s_enable = 1 */ 3878c2ecf20Sopenharmony_ci r15 |= PIN_MUX_I2S_ENABLE_MASK; 3888c2ecf20Sopenharmony_ci /* spi_mode = 1 */ 3898c2ecf20Sopenharmony_ci r3D |= PIN_MUX_SPI_MODE_MASK; 3908c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 0 */ 3918c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK; 3928c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 0 */ 3938c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK; 3948c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 0 */ 3958c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK; 3968c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 0 */ 3978c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK; 3988c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0x0 */ 3998c2ecf20Sopenharmony_ci r84 &= 0x0F; 4008c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0x0 */ 4018c2ecf20Sopenharmony_ci r89 &= 0x0F; 4028c2ecf20Sopenharmony_ci break; 4038c2ecf20Sopenharmony_ci case PIN_MUX_TS_SPI_IN_MODE_0: 4048c2ecf20Sopenharmony_ci /* mpeg_mode = 0 */ 4058c2ecf20Sopenharmony_ci r17 &= ~PIN_MUX_MPEG_MODE_MASK; 4068c2ecf20Sopenharmony_ci /* mpeg_par_en = 0 */ 4078c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK; 4088c2ecf20Sopenharmony_ci /* mpeg_ser_en = 1 */ 4098c2ecf20Sopenharmony_ci r18 |= PIN_MUX_MPEG_SER_EN_MASK; 4108c2ecf20Sopenharmony_ci /* mpg_in_mux = 0 */ 4118c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_MPG_IN_MUX_MASK; 4128c2ecf20Sopenharmony_ci /* bt656_enable = 0 */ 4138c2ecf20Sopenharmony_ci r12 &= ~PIN_MUX_BT656_ENABLE_MASK; 4148c2ecf20Sopenharmony_ci /* i2s_enable = 1 */ 4158c2ecf20Sopenharmony_ci r15 |= PIN_MUX_I2S_ENABLE_MASK; 4168c2ecf20Sopenharmony_ci /* spi_mode = 1 */ 4178c2ecf20Sopenharmony_ci r3D |= PIN_MUX_SPI_MODE_MASK; 4188c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 0 */ 4198c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK; 4208c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 0 */ 4218c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK; 4228c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 0 */ 4238c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK; 4248c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 0 */ 4258c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK; 4268c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0x0 */ 4278c2ecf20Sopenharmony_ci r84 &= 0x0F; 4288c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0x0 */ 4298c2ecf20Sopenharmony_ci r89 &= 0x0F; 4308c2ecf20Sopenharmony_ci break; 4318c2ecf20Sopenharmony_ci case PIN_MUX_TS_PARALLEL_IN: 4328c2ecf20Sopenharmony_ci /* mpeg_mode = 0 */ 4338c2ecf20Sopenharmony_ci r17 &= ~PIN_MUX_MPEG_MODE_MASK; 4348c2ecf20Sopenharmony_ci /* mpeg_par_en = 1 */ 4358c2ecf20Sopenharmony_ci r18 |= PIN_MUX_MPEG_PAR_EN_MASK; 4368c2ecf20Sopenharmony_ci /* mpeg_ser_en = 0 */ 4378c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_SER_EN_MASK; 4388c2ecf20Sopenharmony_ci /* mpg_in_mux = 0 */ 4398c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_MPG_IN_MUX_MASK; 4408c2ecf20Sopenharmony_ci /* bt656_enable = 0 */ 4418c2ecf20Sopenharmony_ci r12 &= ~PIN_MUX_BT656_ENABLE_MASK; 4428c2ecf20Sopenharmony_ci /* i2s_enable = 0 */ 4438c2ecf20Sopenharmony_ci r15 &= ~PIN_MUX_I2S_ENABLE_MASK; 4448c2ecf20Sopenharmony_ci /* spi_mode = 0 */ 4458c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_SPI_MODE_MASK; 4468c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 0 */ 4478c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK; 4488c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 0 */ 4498c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK; 4508c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 0 */ 4518c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK; 4528c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 0 */ 4538c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK; 4548c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0x0 */ 4558c2ecf20Sopenharmony_ci r84 &= 0x0F; 4568c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0x0 */ 4578c2ecf20Sopenharmony_ci r89 &= 0x0F; 4588c2ecf20Sopenharmony_ci break; 4598c2ecf20Sopenharmony_ci case PIN_MUX_BT656_I2S_MODE: 4608c2ecf20Sopenharmony_ci /* mpeg_mode = 0 */ 4618c2ecf20Sopenharmony_ci r17 &= ~PIN_MUX_MPEG_MODE_MASK; 4628c2ecf20Sopenharmony_ci /* mpeg_par_en = 0 */ 4638c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK; 4648c2ecf20Sopenharmony_ci /* mpeg_ser_en = 0 */ 4658c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_SER_EN_MASK; 4668c2ecf20Sopenharmony_ci /* mpg_in_mux = 0 */ 4678c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_MPG_IN_MUX_MASK; 4688c2ecf20Sopenharmony_ci /* bt656_enable = 1 */ 4698c2ecf20Sopenharmony_ci r12 |= PIN_MUX_BT656_ENABLE_MASK; 4708c2ecf20Sopenharmony_ci /* i2s_enable = 1 */ 4718c2ecf20Sopenharmony_ci r15 |= PIN_MUX_I2S_ENABLE_MASK; 4728c2ecf20Sopenharmony_ci /* spi_mode = 0 */ 4738c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_SPI_MODE_MASK; 4748c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 0 */ 4758c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK; 4768c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 0 */ 4778c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK; 4788c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 0 */ 4798c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK; 4808c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 0 */ 4818c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK; 4828c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0x0 */ 4838c2ecf20Sopenharmony_ci r84 &= 0x0F; 4848c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0x0 */ 4858c2ecf20Sopenharmony_ci r89 &= 0x0F; 4868c2ecf20Sopenharmony_ci break; 4878c2ecf20Sopenharmony_ci case PIN_MUX_DEFAULT: 4888c2ecf20Sopenharmony_ci default: 4898c2ecf20Sopenharmony_ci /* mpeg_mode = 1 */ 4908c2ecf20Sopenharmony_ci r17 |= PIN_MUX_MPEG_MODE_MASK; 4918c2ecf20Sopenharmony_ci /* mpeg_par_en = 0 */ 4928c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK; 4938c2ecf20Sopenharmony_ci /* mpeg_ser_en = 0 */ 4948c2ecf20Sopenharmony_ci r18 &= ~PIN_MUX_MPEG_SER_EN_MASK; 4958c2ecf20Sopenharmony_ci /* mpg_in_mux = 0 */ 4968c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_MPG_IN_MUX_MASK; 4978c2ecf20Sopenharmony_ci /* bt656_enable = 0 */ 4988c2ecf20Sopenharmony_ci r12 &= ~PIN_MUX_BT656_ENABLE_MASK; 4998c2ecf20Sopenharmony_ci /* i2s_enable = 0 */ 5008c2ecf20Sopenharmony_ci r15 &= ~PIN_MUX_I2S_ENABLE_MASK; 5018c2ecf20Sopenharmony_ci /* spi_mode = 0 */ 5028c2ecf20Sopenharmony_ci r3D &= ~PIN_MUX_SPI_MODE_MASK; 5038c2ecf20Sopenharmony_ci /* mclk_en_ctrl = 0 */ 5048c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK; 5058c2ecf20Sopenharmony_ci /* mperr_en_ctrl = 0 */ 5068c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK; 5078c2ecf20Sopenharmony_ci /* mdval_en_ctrl = 0 */ 5088c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK; 5098c2ecf20Sopenharmony_ci /* mpsyn_en_ctrl = 0 */ 5108c2ecf20Sopenharmony_ci r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK; 5118c2ecf20Sopenharmony_ci /* mdat_en_ctrl[3:0] = 0x0 */ 5128c2ecf20Sopenharmony_ci r84 &= 0x0F; 5138c2ecf20Sopenharmony_ci /* mdat_en_ctrl[7:4] = 0x0 */ 5148c2ecf20Sopenharmony_ci r89 &= 0x0F; 5158c2ecf20Sopenharmony_ci break; 5168c2ecf20Sopenharmony_ci } 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x17, r17); 5198c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 5208c2ecf20Sopenharmony_ci goto fail; 5218c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x18, r18); 5228c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 5238c2ecf20Sopenharmony_ci goto fail; 5248c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x12, r12); 5258c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 5268c2ecf20Sopenharmony_ci goto fail; 5278c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x15, r15); 5288c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 5298c2ecf20Sopenharmony_ci goto fail; 5308c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x82, r82); 5318c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 5328c2ecf20Sopenharmony_ci goto fail; 5338c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x84, r84); 5348c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 5358c2ecf20Sopenharmony_ci goto fail; 5368c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x89, r89); 5378c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 5388c2ecf20Sopenharmony_ci goto fail; 5398c2ecf20Sopenharmony_ci ret = mxl111sf_write_reg(state, 0x3D, r3D); 5408c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 5418c2ecf20Sopenharmony_ci goto fail; 5428c2ecf20Sopenharmony_cifail: 5438c2ecf20Sopenharmony_ci return ret; 5448c2ecf20Sopenharmony_ci} 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_ci/* ------------------------------------------------------------------------- */ 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_cistatic int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val) 5498c2ecf20Sopenharmony_ci{ 5508c2ecf20Sopenharmony_ci return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val); 5518c2ecf20Sopenharmony_ci} 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_cistatic int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state) 5548c2ecf20Sopenharmony_ci{ 5558c2ecf20Sopenharmony_ci u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */ 5568c2ecf20Sopenharmony_ci int i, ret; 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci mxl_debug("()"); 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci for (i = 3; i < 8; i++) { 5618c2ecf20Sopenharmony_ci ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01); 5628c2ecf20Sopenharmony_ci if (mxl_fail(ret)) 5638c2ecf20Sopenharmony_ci break; 5648c2ecf20Sopenharmony_ci } 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci return ret; 5678c2ecf20Sopenharmony_ci} 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci#define PCA9534_I2C_ADDR (0x40 >> 1) 5708c2ecf20Sopenharmony_cistatic int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val) 5718c2ecf20Sopenharmony_ci{ 5728c2ecf20Sopenharmony_ci u8 w[2] = { 1, 0 }; 5738c2ecf20Sopenharmony_ci u8 r = 0; 5748c2ecf20Sopenharmony_ci struct i2c_msg msg[] = { 5758c2ecf20Sopenharmony_ci { .addr = PCA9534_I2C_ADDR, 5768c2ecf20Sopenharmony_ci .flags = 0, .buf = w, .len = 1 }, 5778c2ecf20Sopenharmony_ci { .addr = PCA9534_I2C_ADDR, 5788c2ecf20Sopenharmony_ci .flags = I2C_M_RD, .buf = &r, .len = 1 }, 5798c2ecf20Sopenharmony_ci }; 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci mxl_debug("(%d, %d)", gpio, val); 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci /* read current GPIO levels from flip-flop */ 5848c2ecf20Sopenharmony_ci i2c_transfer(&state->d->i2c_adap, msg, 2); 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci /* prepare write buffer with current GPIO levels */ 5878c2ecf20Sopenharmony_ci msg[0].len = 2; 5888c2ecf20Sopenharmony_ci#if 0 5898c2ecf20Sopenharmony_ci w[0] = 1; 5908c2ecf20Sopenharmony_ci#endif 5918c2ecf20Sopenharmony_ci w[1] = r; 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci /* clear the desired GPIO */ 5948c2ecf20Sopenharmony_ci w[1] &= ~(1 << gpio); 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci /* set the desired GPIO value */ 5978c2ecf20Sopenharmony_ci w[1] |= ((val ? 1 : 0) << gpio); 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci /* write new GPIO levels to flip-flop */ 6008c2ecf20Sopenharmony_ci i2c_transfer(&state->d->i2c_adap, &msg[0], 1); 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci return 0; 6038c2ecf20Sopenharmony_ci} 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_cistatic int pca9534_init_port_expander(struct mxl111sf_state *state) 6068c2ecf20Sopenharmony_ci{ 6078c2ecf20Sopenharmony_ci u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */ 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci struct i2c_msg msg = { 6108c2ecf20Sopenharmony_ci .addr = PCA9534_I2C_ADDR, 6118c2ecf20Sopenharmony_ci .flags = 0, .buf = w, .len = 2 6128c2ecf20Sopenharmony_ci }; 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci mxl_debug("()"); 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci i2c_transfer(&state->d->i2c_adap, &msg, 1); 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci /* configure all pins as outputs */ 6198c2ecf20Sopenharmony_ci w[0] = 3; 6208c2ecf20Sopenharmony_ci w[1] = 0; 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci i2c_transfer(&state->d->i2c_adap, &msg, 1); 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci return 0; 6258c2ecf20Sopenharmony_ci} 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ciint mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val) 6288c2ecf20Sopenharmony_ci{ 6298c2ecf20Sopenharmony_ci mxl_debug("(%d, %d)", gpio, val); 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci switch (state->gpio_port_expander) { 6328c2ecf20Sopenharmony_ci default: 6338c2ecf20Sopenharmony_ci mxl_printk(KERN_ERR, 6348c2ecf20Sopenharmony_ci "gpio_port_expander undefined, assuming PCA9534"); 6358c2ecf20Sopenharmony_ci fallthrough; 6368c2ecf20Sopenharmony_ci case mxl111sf_PCA9534: 6378c2ecf20Sopenharmony_ci return pca9534_set_gpio(state, gpio, val); 6388c2ecf20Sopenharmony_ci case mxl111sf_gpio_hw: 6398c2ecf20Sopenharmony_ci return mxl111sf_hw_set_gpio(state, gpio, val); 6408c2ecf20Sopenharmony_ci } 6418c2ecf20Sopenharmony_ci} 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_cistatic int mxl111sf_probe_port_expander(struct mxl111sf_state *state) 6448c2ecf20Sopenharmony_ci{ 6458c2ecf20Sopenharmony_ci int ret; 6468c2ecf20Sopenharmony_ci u8 w = 1; 6478c2ecf20Sopenharmony_ci u8 r = 0; 6488c2ecf20Sopenharmony_ci struct i2c_msg msg[] = { 6498c2ecf20Sopenharmony_ci { .flags = 0, .buf = &w, .len = 1 }, 6508c2ecf20Sopenharmony_ci { .flags = I2C_M_RD, .buf = &r, .len = 1 }, 6518c2ecf20Sopenharmony_ci }; 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_ci mxl_debug("()"); 6548c2ecf20Sopenharmony_ci 6558c2ecf20Sopenharmony_ci msg[0].addr = 0x70 >> 1; 6568c2ecf20Sopenharmony_ci msg[1].addr = 0x70 >> 1; 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci /* read current GPIO levels from flip-flop */ 6598c2ecf20Sopenharmony_ci ret = i2c_transfer(&state->d->i2c_adap, msg, 2); 6608c2ecf20Sopenharmony_ci if (ret == 2) { 6618c2ecf20Sopenharmony_ci state->port_expander_addr = msg[0].addr; 6628c2ecf20Sopenharmony_ci state->gpio_port_expander = mxl111sf_PCA9534; 6638c2ecf20Sopenharmony_ci mxl_debug("found port expander at 0x%02x", 6648c2ecf20Sopenharmony_ci state->port_expander_addr); 6658c2ecf20Sopenharmony_ci return 0; 6668c2ecf20Sopenharmony_ci } 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ci msg[0].addr = 0x40 >> 1; 6698c2ecf20Sopenharmony_ci msg[1].addr = 0x40 >> 1; 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci ret = i2c_transfer(&state->d->i2c_adap, msg, 2); 6728c2ecf20Sopenharmony_ci if (ret == 2) { 6738c2ecf20Sopenharmony_ci state->port_expander_addr = msg[0].addr; 6748c2ecf20Sopenharmony_ci state->gpio_port_expander = mxl111sf_PCA9534; 6758c2ecf20Sopenharmony_ci mxl_debug("found port expander at 0x%02x", 6768c2ecf20Sopenharmony_ci state->port_expander_addr); 6778c2ecf20Sopenharmony_ci return 0; 6788c2ecf20Sopenharmony_ci } 6798c2ecf20Sopenharmony_ci state->port_expander_addr = 0xff; 6808c2ecf20Sopenharmony_ci state->gpio_port_expander = mxl111sf_gpio_hw; 6818c2ecf20Sopenharmony_ci mxl_debug("using hardware gpio"); 6828c2ecf20Sopenharmony_ci return 0; 6838c2ecf20Sopenharmony_ci} 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ciint mxl111sf_init_port_expander(struct mxl111sf_state *state) 6868c2ecf20Sopenharmony_ci{ 6878c2ecf20Sopenharmony_ci mxl_debug("()"); 6888c2ecf20Sopenharmony_ci 6898c2ecf20Sopenharmony_ci if (0x00 == state->port_expander_addr) 6908c2ecf20Sopenharmony_ci mxl111sf_probe_port_expander(state); 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci switch (state->gpio_port_expander) { 6938c2ecf20Sopenharmony_ci default: 6948c2ecf20Sopenharmony_ci mxl_printk(KERN_ERR, 6958c2ecf20Sopenharmony_ci "gpio_port_expander undefined, assuming PCA9534"); 6968c2ecf20Sopenharmony_ci fallthrough; 6978c2ecf20Sopenharmony_ci case mxl111sf_PCA9534: 6988c2ecf20Sopenharmony_ci return pca9534_init_port_expander(state); 6998c2ecf20Sopenharmony_ci case mxl111sf_gpio_hw: 7008c2ecf20Sopenharmony_ci return mxl111sf_hw_gpio_initialize(state); 7018c2ecf20Sopenharmony_ci } 7028c2ecf20Sopenharmony_ci} 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci/* ------------------------------------------------------------------------ */ 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ciint mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode) 7078c2ecf20Sopenharmony_ci{ 7088c2ecf20Sopenharmony_ci/* GPO: 7098c2ecf20Sopenharmony_ci * 3 - ATSC/MH# | 1 = ATSC transport, 0 = MH transport | default 0 7108c2ecf20Sopenharmony_ci * 4 - ATSC_RST## | 1 = ATSC enable, 0 = ATSC Reset | default 0 7118c2ecf20Sopenharmony_ci * 5 - ATSC_EN | 1 = ATSC power enable, 0 = ATSC power off | default 0 7128c2ecf20Sopenharmony_ci * 6 - MH_RESET# | 1 = MH enable, 0 = MH Reset | default 0 7138c2ecf20Sopenharmony_ci * 7 - MH_EN | 1 = MH power enable, 0 = MH power off | default 0 7148c2ecf20Sopenharmony_ci */ 7158c2ecf20Sopenharmony_ci mxl_debug("(%d)", mode); 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci switch (mode) { 7188c2ecf20Sopenharmony_ci case MXL111SF_GPIO_MOD_MH: 7198c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 4, 0); 7208c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 5, 0); 7218c2ecf20Sopenharmony_ci msleep(50); 7228c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 7, 1); 7238c2ecf20Sopenharmony_ci msleep(50); 7248c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 6, 1); 7258c2ecf20Sopenharmony_ci msleep(50); 7268c2ecf20Sopenharmony_ci 7278c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 3, 0); 7288c2ecf20Sopenharmony_ci break; 7298c2ecf20Sopenharmony_ci case MXL111SF_GPIO_MOD_ATSC: 7308c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 6, 0); 7318c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 7, 0); 7328c2ecf20Sopenharmony_ci msleep(50); 7338c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 5, 1); 7348c2ecf20Sopenharmony_ci msleep(50); 7358c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 4, 1); 7368c2ecf20Sopenharmony_ci msleep(50); 7378c2ecf20Sopenharmony_ci mxl111sf_set_gpio(state, 3, 1); 7388c2ecf20Sopenharmony_ci break; 7398c2ecf20Sopenharmony_ci default: /* DVBT / STANDBY */ 7408c2ecf20Sopenharmony_ci mxl111sf_init_port_expander(state); 7418c2ecf20Sopenharmony_ci break; 7428c2ecf20Sopenharmony_ci } 7438c2ecf20Sopenharmony_ci return 0; 7448c2ecf20Sopenharmony_ci} 745