From 90796acad0027db957a282787a4dab7d0bb52ef1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 10 Jul 2011 09:36:30 -0300 Subject: [media] drxk: Improves the UIO handling The driver is too limited: it assumes that UIO is used only for controlling the antenna, and that only UIO-1 is in usage. However, from Terratec H7 driver [1], 3 UIO's can be used. In fact, it seems that H7 needs to use all 3. So, make the code generic enough to handle the most complex scenario. For now, only antena GPIO can be specified, but is is easier now to add the other GPIO/UIO needs. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drxk_hard.c | 123 ++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 30 deletions(-) (limited to 'drivers/media/dvb/frontends/drxk_hard.c') diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 0d288a7f016..aaef8e35698 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -856,7 +856,6 @@ static int init_state(struct drxk_state *state) state->m_agcFastClipCtrlDelay = 0; state->m_GPIOCfg = (ulGPIOCfg); - state->m_GPIO = (ulGPIO == 0 ? 0 : 1); state->m_bPowerDown = false; state->m_currentPowerMode = DRX_POWER_DOWN; @@ -5795,24 +5794,63 @@ static int WriteGPIO(struct drxk_state *state) goto error; if (state->m_hasSAWSW) { - /* write to io pad configuration register - output mode */ - status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); - if (status < 0) - goto error; + if (state->UIO_mask & 0x0001) { /* UIO-1 */ + /* write to io pad configuration register - output mode */ + status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); + if (status < 0) + goto error; - /* use corresponding bit in io data output registar */ - status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); - if (status < 0) - goto error; - if (state->m_GPIO == 0) - value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */ - else - value |= 0x8000; /* write one to 15th bit - 1st UIO */ - /* write back to io data output register */ - status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); - if (status < 0) - goto error; + /* use corresponding bit in io data output registar */ + status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); + if (status < 0) + goto error; + if ((state->m_GPIO & 0x0001) == 0) + value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */ + else + value |= 0x8000; /* write one to 15th bit - 1st UIO */ + /* write back to io data output register */ + status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); + if (status < 0) + goto error; + } + if (state->UIO_mask & 0x0002) { /* UIO-2 */ + /* write to io pad configuration register - output mode */ + status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); + if (status < 0) + goto error; + /* use corresponding bit in io data output registar */ + status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); + if (status < 0) + goto error; + if ((state->m_GPIO & 0x0002) == 0) + value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */ + else + value |= 0x4000; /* write one to 14th bit - 2st UIO */ + /* write back to io data output register */ + status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); + if (status < 0) + goto error; + } + if (state->UIO_mask & 0x0004) { /* UIO-3 */ + /* write to io pad configuration register - output mode */ + status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); + if (status < 0) + goto error; + + /* use corresponding bit in io data output registar */ + status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); + if (status < 0) + goto error; + if ((state->m_GPIO & 0x0004) == 0) + value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */ + else + value |= 0x0004; /* write one to 2nd bit - 3rd UIO */ + /* write back to io data output register */ + status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); + if (status < 0) + goto error; + } } /* Write magic word to disable pdr reg write */ status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); @@ -5825,14 +5863,22 @@ error: static int SwitchAntennaToQAM(struct drxk_state *state) { int status = 0; + bool gpio_state; dprintk(1, "\n"); - if (state->m_AntennaSwitchDVBTDVBC != 0) { - if (state->m_GPIO != state->m_AntennaDVBC) { - state->m_GPIO = state->m_AntennaDVBC; - status = WriteGPIO(state); - } + if (!state->antenna_gpio) + return 0; + + gpio_state = state->m_GPIO & state->antenna_gpio; + + if (state->antenna_dvbt ^ gpio_state) { + /* Antenna is on DVB-T mode. Switch */ + if (state->antenna_dvbt) + state->m_GPIO &= ~state->antenna_gpio; + else + state->m_GPIO |= state->antenna_gpio; + status = WriteGPIO(state); } if (status < 0) printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); @@ -5842,13 +5888,22 @@ static int SwitchAntennaToQAM(struct drxk_state *state) static int SwitchAntennaToDVBT(struct drxk_state *state) { int status = 0; + bool gpio_state; dprintk(1, "\n"); - if (state->m_AntennaSwitchDVBTDVBC != 0) { - if (state->m_GPIO != state->m_AntennaDVBT) { - state->m_GPIO = state->m_AntennaDVBT; - status = WriteGPIO(state); - } + + if (!state->antenna_gpio) + return 0; + + gpio_state = state->m_GPIO & state->antenna_gpio; + + if (!(state->antenna_dvbt ^ gpio_state)) { + /* Antenna is on DVB-C mode. Switch */ + if (state->antenna_dvbt) + state->m_GPIO |= state->antenna_gpio; + else + state->m_GPIO &= ~state->antenna_gpio; + status = WriteGPIO(state); } if (status < 0) printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); @@ -6350,9 +6405,17 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->single_master = config->single_master; state->microcode_name = config->microcode_name; state->no_i2c_bridge = config->no_i2c_bridge; - state->m_AntennaSwitchDVBTDVBC = config->antenna_uses_gpio; - state->m_AntennaDVBC = config->antenna_dvbc; - state->m_AntennaDVBT = config->antenna_dvbt; + state->antenna_gpio = config->antenna_gpio; + state->antenna_dvbt = config->antenna_dvbt; + + /* NOTE: as more UIO bits will be used, add them to the mask */ + state->UIO_mask = config->antenna_gpio; + + /* Default gpio to DVB-C */ + if (!state->antenna_dvbt && state->antenna_gpio) + state->m_GPIO |= state->antenna_gpio; + else + state->m_GPIO &= ~state->antenna_gpio; mutex_init(&state->mutex); mutex_init(&state->ctlock); -- cgit v1.2.3-70-g09d2