diff options
-rw-r--r-- | drivers/media/dvb/frontends/drxk.h | 13 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/drxk_hard.c | 123 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/drxk_hard.h | 16 |
3 files changed, 110 insertions, 42 deletions
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index 67589b607c4e..a756e4562fe2 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h | |||
@@ -10,18 +10,21 @@ | |||
10 | * adr: I2C Address of the DRX-K | 10 | * adr: I2C Address of the DRX-K |
11 | * single_master: Device is on the single master mode | 11 | * single_master: Device is on the single master mode |
12 | * no_i2c_bridge: Don't switch the I2C bridge to talk with tuner | 12 | * no_i2c_bridge: Don't switch the I2C bridge to talk with tuner |
13 | * antenna_uses_gpio: Use GPIO to control the antenna | 13 | * antenna_gpio: GPIO bit used to control the antenna |
14 | * antenna_dvbc: GPIO for changing antenna to DVB-C | 14 | * antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 |
15 | * antenna_dvbt: GPIO for changing antenna to DVB-T | 15 | * means that 1=DVBC, 0 = DVBT. Zero means the opposite. |
16 | * microcode_name: Name of the firmware file with the microcode | 16 | * microcode_name: Name of the firmware file with the microcode |
17 | * | ||
18 | * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is | ||
19 | * UIO-3. | ||
17 | */ | 20 | */ |
18 | struct drxk_config { | 21 | struct drxk_config { |
19 | u8 adr; | 22 | u8 adr; |
20 | bool single_master; | 23 | bool single_master; |
21 | bool no_i2c_bridge; | 24 | bool no_i2c_bridge; |
22 | 25 | ||
23 | bool antenna_uses_gpio; | 26 | bool antenna_dvbt; |
24 | u16 antenna_dvbc, antenna_dvbt; | 27 | u16 antenna_gpio; |
25 | 28 | ||
26 | const char *microcode_name; | 29 | const char *microcode_name; |
27 | }; | 30 | }; |
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 0d288a7f0163..aaef8e35698b 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: | |||
5825 | static int SwitchAntennaToQAM(struct drxk_state *state) | 5863 | static 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) | |||
5842 | static int SwitchAntennaToDVBT(struct drxk_state *state) | 5888 | static 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); |
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h index 8b29dc89f58b..a20a19d9aff6 100644 --- a/drivers/media/dvb/frontends/drxk_hard.h +++ b/drivers/media/dvb/frontends/drxk_hard.h | |||
@@ -323,17 +323,19 @@ struct drxk_state { | |||
323 | 323 | ||
324 | enum DRXPowerMode m_currentPowerMode; | 324 | enum DRXPowerMode m_currentPowerMode; |
325 | 325 | ||
326 | /* Configurable parameters at the driver */ | 326 | /* |
327 | * Configurable parameters at the driver. They stores the values found | ||
328 | * at struct drxk_config. | ||
329 | */ | ||
327 | 330 | ||
328 | bool m_AntennaSwitchDVBTDVBC; | 331 | u16 UIO_mask; /* Bits used by UIO */ |
329 | u16 m_AntennaDVBC; | ||
330 | u16 m_AntennaDVBT; | ||
331 | 332 | ||
332 | u32 single_master : 1; /* Use single master i2c mode */ | 333 | bool single_master; |
333 | u32 no_i2c_bridge : 1; /* Tuner is not on port 1, don't use I2C bridge */ | 334 | bool no_i2c_bridge; |
335 | bool antenna_dvbt; | ||
336 | u16 antenna_gpio; | ||
334 | 337 | ||
335 | const char *microcode_name; | 338 | const char *microcode_name; |
336 | |||
337 | }; | 339 | }; |
338 | 340 | ||
339 | #define NEVER_LOCK 0 | 341 | #define NEVER_LOCK 0 |