aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/drxk_hard.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2011-07-10 08:36:30 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:55:50 -0400
commit90796acad0027db957a282787a4dab7d0bb52ef1 (patch)
tree15f62126a7285601c8880dfe2d73c19ec6925b84 /drivers/media/dvb/frontends/drxk_hard.c
parent9c6e18280091ee2cf78bfb33a1770b5b59c8afae (diff)
[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 <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/frontends/drxk_hard.c')
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.c123
1 files changed, 93 insertions, 30 deletions
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)
856 state->m_agcFastClipCtrlDelay = 0; 856 state->m_agcFastClipCtrlDelay = 0;
857 857
858 state->m_GPIOCfg = (ulGPIOCfg); 858 state->m_GPIOCfg = (ulGPIOCfg);
859 state->m_GPIO = (ulGPIO == 0 ? 0 : 1);
860 859
861 state->m_bPowerDown = false; 860 state->m_bPowerDown = false;
862 state->m_currentPowerMode = DRX_POWER_DOWN; 861 state->m_currentPowerMode = DRX_POWER_DOWN;
@@ -5795,24 +5794,63 @@ static int WriteGPIO(struct drxk_state *state)
5795 goto error; 5794 goto error;
5796 5795
5797 if (state->m_hasSAWSW) { 5796 if (state->m_hasSAWSW) {
5798 /* write to io pad configuration register - output mode */ 5797 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5799 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); 5798 /* write to io pad configuration register - output mode */
5800 if (status < 0) 5799 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5801 goto error; 5800 if (status < 0)
5801 goto error;
5802 5802
5803 /* use corresponding bit in io data output registar */ 5803 /* use corresponding bit in io data output registar */
5804 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value); 5804 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5805 if (status < 0) 5805 if (status < 0)
5806 goto error; 5806 goto error;
5807 if (state->m_GPIO == 0) 5807 if ((state->m_GPIO & 0x0001) == 0)
5808 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */ 5808 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5809 else 5809 else
5810 value |= 0x8000; /* write one to 15th bit - 1st UIO */ 5810 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5811 /* write back to io data output register */ 5811 /* write back to io data output register */
5812 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value); 5812 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5813 if (status < 0) 5813 if (status < 0)
5814 goto error; 5814 goto error;
5815 }
5816 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5817 /* write to io pad configuration register - output mode */
5818 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5819 if (status < 0)
5820 goto error;
5815 5821
5822 /* use corresponding bit in io data output registar */
5823 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5824 if (status < 0)
5825 goto error;
5826 if ((state->m_GPIO & 0x0002) == 0)
5827 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5828 else
5829 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5830 /* write back to io data output register */
5831 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5832 if (status < 0)
5833 goto error;
5834 }
5835 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5836 /* write to io pad configuration register - output mode */
5837 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5838 if (status < 0)
5839 goto error;
5840
5841 /* use corresponding bit in io data output registar */
5842 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5843 if (status < 0)
5844 goto error;
5845 if ((state->m_GPIO & 0x0004) == 0)
5846 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5847 else
5848 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5849 /* write back to io data output register */
5850 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5851 if (status < 0)
5852 goto error;
5853 }
5816 } 5854 }
5817 /* Write magic word to disable pdr reg write */ 5855 /* Write magic word to disable pdr reg write */
5818 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000); 5856 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
@@ -5825,14 +5863,22 @@ error:
5825static int SwitchAntennaToQAM(struct drxk_state *state) 5863static int SwitchAntennaToQAM(struct drxk_state *state)
5826{ 5864{
5827 int status = 0; 5865 int status = 0;
5866 bool gpio_state;
5828 5867
5829 dprintk(1, "\n"); 5868 dprintk(1, "\n");
5830 5869
5831 if (state->m_AntennaSwitchDVBTDVBC != 0) { 5870 if (!state->antenna_gpio)
5832 if (state->m_GPIO != state->m_AntennaDVBC) { 5871 return 0;
5833 state->m_GPIO = state->m_AntennaDVBC; 5872
5834 status = WriteGPIO(state); 5873 gpio_state = state->m_GPIO & state->antenna_gpio;
5835 } 5874
5875 if (state->antenna_dvbt ^ gpio_state) {
5876 /* Antenna is on DVB-T mode. Switch */
5877 if (state->antenna_dvbt)
5878 state->m_GPIO &= ~state->antenna_gpio;
5879 else
5880 state->m_GPIO |= state->antenna_gpio;
5881 status = WriteGPIO(state);
5836 } 5882 }
5837 if (status < 0) 5883 if (status < 0)
5838 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); 5884 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
@@ -5842,13 +5888,22 @@ static int SwitchAntennaToQAM(struct drxk_state *state)
5842static int SwitchAntennaToDVBT(struct drxk_state *state) 5888static int SwitchAntennaToDVBT(struct drxk_state *state)
5843{ 5889{
5844 int status = 0; 5890 int status = 0;
5891 bool gpio_state;
5845 5892
5846 dprintk(1, "\n"); 5893 dprintk(1, "\n");
5847 if (state->m_AntennaSwitchDVBTDVBC != 0) { 5894
5848 if (state->m_GPIO != state->m_AntennaDVBT) { 5895 if (!state->antenna_gpio)
5849 state->m_GPIO = state->m_AntennaDVBT; 5896 return 0;
5850 status = WriteGPIO(state); 5897
5851 } 5898 gpio_state = state->m_GPIO & state->antenna_gpio;
5899
5900 if (!(state->antenna_dvbt ^ gpio_state)) {
5901 /* Antenna is on DVB-C mode. Switch */
5902 if (state->antenna_dvbt)
5903 state->m_GPIO |= state->antenna_gpio;
5904 else
5905 state->m_GPIO &= ~state->antenna_gpio;
5906 status = WriteGPIO(state);
5852 } 5907 }
5853 if (status < 0) 5908 if (status < 0)
5854 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); 5909 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,
6350 state->single_master = config->single_master; 6405 state->single_master = config->single_master;
6351 state->microcode_name = config->microcode_name; 6406 state->microcode_name = config->microcode_name;
6352 state->no_i2c_bridge = config->no_i2c_bridge; 6407 state->no_i2c_bridge = config->no_i2c_bridge;
6353 state->m_AntennaSwitchDVBTDVBC = config->antenna_uses_gpio; 6408 state->antenna_gpio = config->antenna_gpio;
6354 state->m_AntennaDVBC = config->antenna_dvbc; 6409 state->antenna_dvbt = config->antenna_dvbt;
6355 state->m_AntennaDVBT = config->antenna_dvbt; 6410
6411 /* NOTE: as more UIO bits will be used, add them to the mask */
6412 state->UIO_mask = config->antenna_gpio;
6413
6414 /* Default gpio to DVB-C */
6415 if (!state->antenna_dvbt && state->antenna_gpio)
6416 state->m_GPIO |= state->antenna_gpio;
6417 else
6418 state->m_GPIO &= ~state->antenna_gpio;
6356 6419
6357 mutex_init(&state->mutex); 6420 mutex_init(&state->mutex);
6358 mutex_init(&state->ctlock); 6421 mutex_init(&state->ctlock);