diff options
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r-- | drivers/media/dvb/frontends/Kconfig | 46 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/bcm3510.c | 6 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cx22702.c | 22 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cx24110.c | 23 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cx24123.c | 889 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cx24123.h | 51 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dvb-pll.c | 15 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dvb-pll.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/lgdt330x.c | 3 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/nxt2002.c | 3 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/nxt6000.c | 10 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/or51211.c | 5 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/s5h1420.c | 4 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/sp8870.c | 3 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/sp887x.c | 5 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/stv0299.c | 12 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/stv0299.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda10021.c | 4 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda1004x.c | 141 |
20 files changed, 1138 insertions, 108 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 8e269e1c1f9d..db3a8b40031e 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -16,6 +16,12 @@ config DVB_CX24110 | |||
16 | help | 16 | help |
17 | A DVB-S tuner module. Say Y when you want to support this frontend. | 17 | A DVB-S tuner module. Say Y when you want to support this frontend. |
18 | 18 | ||
19 | config DVB_CX24123 | ||
20 | tristate "Conexant CX24123 based" | ||
21 | depends on DVB_CORE | ||
22 | help | ||
23 | A DVB-S tuner module. Say Y when you want to support this frontend. | ||
24 | |||
19 | config DVB_TDA8083 | 25 | config DVB_TDA8083 |
20 | tristate "Philips TDA8083 based" | 26 | tristate "Philips TDA8083 based" |
21 | depends on DVB_CORE | 27 | depends on DVB_CORE |
@@ -50,18 +56,19 @@ comment "DVB-T (terrestrial) frontends" | |||
50 | depends on DVB_CORE | 56 | depends on DVB_CORE |
51 | 57 | ||
52 | config DVB_SP8870 | 58 | config DVB_SP8870 |
53 | tristate "Spase sp8870 based" | 59 | tristate "Spase sp8870 based" |
54 | depends on DVB_CORE | 60 | depends on DVB_CORE |
55 | select FW_LOADER | 61 | select FW_LOADER |
56 | help | 62 | help |
57 | A DVB-T tuner module. Say Y when you want to support this frontend. | 63 | A DVB-T tuner module. Say Y when you want to support this frontend. |
58 | 64 | ||
59 | This driver needs external firmware. Please use the command | 65 | This driver needs external firmware. Please use the command |
60 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to | 66 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to |
61 | download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 67 | download/extract it, and then copy it to /usr/lib/hotplug/firmware |
68 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
62 | 69 | ||
63 | config DVB_SP887X | 70 | config DVB_SP887X |
64 | tristate "Spase sp887x based" | 71 | tristate "Spase sp887x based" |
65 | depends on DVB_CORE | 72 | depends on DVB_CORE |
66 | select FW_LOADER | 73 | select FW_LOADER |
67 | help | 74 | help |
@@ -69,7 +76,8 @@ config DVB_SP887X | |||
69 | 76 | ||
70 | This driver needs external firmware. Please use the command | 77 | This driver needs external firmware. Please use the command |
71 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to | 78 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to |
72 | download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 79 | download/extract it, and then copy it to /usr/lib/hotplug/firmware |
80 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
73 | 81 | ||
74 | config DVB_CX22700 | 82 | config DVB_CX22700 |
75 | tristate "Conexant CX22700 based" | 83 | tristate "Conexant CX22700 based" |
@@ -78,10 +86,10 @@ config DVB_CX22700 | |||
78 | A DVB-T tuner module. Say Y when you want to support this frontend. | 86 | A DVB-T tuner module. Say Y when you want to support this frontend. |
79 | 87 | ||
80 | config DVB_CX22702 | 88 | config DVB_CX22702 |
81 | tristate "Conexant cx22702 demodulator (OFDM)" | 89 | tristate "Conexant cx22702 demodulator (OFDM)" |
82 | depends on DVB_CORE | 90 | depends on DVB_CORE |
83 | help | 91 | help |
84 | A DVB-T tuner module. Say Y when you want to support this frontend. | 92 | A DVB-T tuner module. Say Y when you want to support this frontend. |
85 | 93 | ||
86 | config DVB_L64781 | 94 | config DVB_L64781 |
87 | tristate "LSI L64781" | 95 | tristate "LSI L64781" |
@@ -98,8 +106,9 @@ config DVB_TDA1004X | |||
98 | 106 | ||
99 | This driver needs external firmware. Please use the commands | 107 | This driver needs external firmware. Please use the commands |
100 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", | 108 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", |
101 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to | 109 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to |
102 | download/extract them, and then copy them to /usr/lib/hotplug/firmware. | 110 | download/extract them, and then copy them to /usr/lib/hotplug/firmware |
111 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
103 | 112 | ||
104 | config DVB_NXT6000 | 113 | config DVB_NXT6000 |
105 | tristate "NxtWave Communications NXT6000 based" | 114 | tristate "NxtWave Communications NXT6000 based" |
@@ -140,13 +149,13 @@ config DVB_VES1820 | |||
140 | tristate "VLSI VES1820 based" | 149 | tristate "VLSI VES1820 based" |
141 | depends on DVB_CORE | 150 | depends on DVB_CORE |
142 | help | 151 | help |
143 | A DVB-C tuner module. Say Y when you want to support this frontend. | 152 | A DVB-C tuner module. Say Y when you want to support this frontend. |
144 | 153 | ||
145 | config DVB_TDA10021 | 154 | config DVB_TDA10021 |
146 | tristate "Philips TDA10021 based" | 155 | tristate "Philips TDA10021 based" |
147 | depends on DVB_CORE | 156 | depends on DVB_CORE |
148 | help | 157 | help |
149 | A DVB-C tuner module. Say Y when you want to support this frontend. | 158 | A DVB-C tuner module. Say Y when you want to support this frontend. |
150 | 159 | ||
151 | config DVB_STV0297 | 160 | config DVB_STV0297 |
152 | tristate "ST STV0297 based" | 161 | tristate "ST STV0297 based" |
@@ -164,6 +173,11 @@ config DVB_NXT2002 | |||
164 | help | 173 | help |
165 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. | 174 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. |
166 | 175 | ||
176 | This driver needs external firmware. Please use the command | ||
177 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | ||
178 | download/extract it, and then copy it to /usr/lib/hotplug/firmware | ||
179 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
180 | |||
167 | config DVB_NXT200X | 181 | config DVB_NXT200X |
168 | tristate "Nextwave NXT2002/NXT2004 based" | 182 | tristate "Nextwave NXT2002/NXT2004 based" |
169 | depends on DVB_CORE | 183 | depends on DVB_CORE |
@@ -172,6 +186,12 @@ config DVB_NXT200X | |||
172 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 186 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want |
173 | to support this frontend. | 187 | to support this frontend. |
174 | 188 | ||
189 | This driver needs external firmware. Please use the commands | ||
190 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and | ||
191 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to | ||
192 | download/extract them, and then copy them to /usr/lib/hotplug/firmware | ||
193 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
194 | |||
175 | config DVB_OR51211 | 195 | config DVB_OR51211 |
176 | tristate "or51211 based (pcHDTV HD2000 card)" | 196 | tristate "or51211 based (pcHDTV HD2000 card)" |
177 | depends on DVB_CORE | 197 | depends on DVB_CORE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index a98760fe08a1..615ec830e1c9 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -32,3 +32,4 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o | |||
32 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | 32 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o |
33 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o | 33 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o |
34 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o | 34 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o |
35 | obj-$(CONFIG_DVB_CX24123) += cx24123.o | ||
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index 8ceb9a33c7af..3b132bafd4de 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c | |||
@@ -255,7 +255,7 @@ static int bcm3510_bert_reset(struct bcm3510_state *st) | |||
255 | bcm3510_register_value b; | 255 | bcm3510_register_value b; |
256 | int ret; | 256 | int ret; |
257 | 257 | ||
258 | if ((ret < bcm3510_readB(st,0xfa,&b)) < 0) | 258 | if ((ret = bcm3510_readB(st,0xfa,&b)) < 0) |
259 | return ret; | 259 | return ret; |
260 | 260 | ||
261 | b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); | 261 | b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); |
@@ -623,13 +623,13 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe) | |||
623 | err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); | 623 | err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); |
624 | return ret; | 624 | return ret; |
625 | } | 625 | } |
626 | deb_info("got firmware: %d\n",fw->size); | 626 | deb_info("got firmware: %zd\n",fw->size); |
627 | 627 | ||
628 | b = fw->data; | 628 | b = fw->data; |
629 | for (i = 0; i < fw->size;) { | 629 | for (i = 0; i < fw->size;) { |
630 | addr = le16_to_cpu( *( (u16 *)&b[i] ) ); | 630 | addr = le16_to_cpu( *( (u16 *)&b[i] ) ); |
631 | len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); | 631 | len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); |
632 | deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size); | 632 | deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size); |
633 | if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { | 633 | if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { |
634 | err("firmware download failed: %d\n",ret); | 634 | err("firmware download failed: %d\n",ret); |
635 | return ret; | 635 | return ret; |
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 5de0e6d350b1..0fc899f81c5e 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -195,6 +195,16 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet | |||
195 | return 0; | 195 | return 0; |
196 | } | 196 | } |
197 | 197 | ||
198 | static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
199 | { | ||
200 | struct cx22702_state* state = fe->demodulator_priv; | ||
201 | dprintk ("%s(%d)\n", __FUNCTION__, enable); | ||
202 | if (enable) | ||
203 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe); | ||
204 | else | ||
205 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1); | ||
206 | } | ||
207 | |||
198 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ | 208 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ |
199 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 209 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
200 | { | 210 | { |
@@ -202,7 +212,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
202 | struct cx22702_state* state = fe->demodulator_priv; | 212 | struct cx22702_state* state = fe->demodulator_priv; |
203 | 213 | ||
204 | /* set PLL */ | 214 | /* set PLL */ |
205 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); | 215 | cx22702_i2c_gate_ctrl(fe, 1); |
206 | if (state->config->pll_set) { | 216 | if (state->config->pll_set) { |
207 | state->config->pll_set(fe, p); | 217 | state->config->pll_set(fe, p); |
208 | } else if (state->config->pll_desc) { | 218 | } else if (state->config->pll_desc) { |
@@ -216,7 +226,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
216 | } else { | 226 | } else { |
217 | BUG(); | 227 | BUG(); |
218 | } | 228 | } |
219 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); | 229 | cx22702_i2c_gate_ctrl(fe, 0); |
220 | 230 | ||
221 | /* set inversion */ | 231 | /* set inversion */ |
222 | cx22702_set_inversion (state, p->inversion); | 232 | cx22702_set_inversion (state, p->inversion); |
@@ -349,11 +359,10 @@ static int cx22702_init (struct dvb_frontend* fe) | |||
349 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); | 359 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); |
350 | 360 | ||
351 | /* init PLL */ | 361 | /* init PLL */ |
352 | if (state->config->pll_init) { | 362 | if (state->config->pll_init) |
353 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe); | ||
354 | state->config->pll_init(fe); | 363 | state->config->pll_init(fe); |
355 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); | 364 | |
356 | } | 365 | cx22702_i2c_gate_ctrl(fe, 0); |
357 | 366 | ||
358 | return 0; | 367 | return 0; |
359 | } | 368 | } |
@@ -531,6 +540,7 @@ static struct dvb_frontend_ops cx22702_ops = { | |||
531 | .read_signal_strength = cx22702_read_signal_strength, | 540 | .read_signal_strength = cx22702_read_signal_strength, |
532 | .read_snr = cx22702_read_snr, | 541 | .read_snr = cx22702_read_snr, |
533 | .read_ucblocks = cx22702_read_ucblocks, | 542 | .read_ucblocks = cx22702_read_ucblocks, |
543 | .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, | ||
534 | }; | 544 | }; |
535 | 545 | ||
536 | module_param(debug, int, 0644); | 546 | module_param(debug, int, 0644); |
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 0c4db80ec332..d15d32c51dc5 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/jiffies.h> | ||
31 | 30 | ||
32 | #include "dvb_frontend.h" | 31 | #include "dvb_frontend.h" |
33 | #include "cx24110.h" | 32 | #include "cx24110.h" |
@@ -56,7 +55,7 @@ static int debug; | |||
56 | 55 | ||
57 | static struct {u8 reg; u8 data;} cx24110_regdata[]= | 56 | static struct {u8 reg; u8 data;} cx24110_regdata[]= |
58 | /* Comments beginning with @ denote this value should | 57 | /* Comments beginning with @ denote this value should |
59 | be the default */ | 58 | be the default */ |
60 | {{0x09,0x01}, /* SoftResetAll */ | 59 | {{0x09,0x01}, /* SoftResetAll */ |
61 | {0x09,0x00}, /* release reset */ | 60 | {0x09,0x00}, /* release reset */ |
62 | {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ | 61 | {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ |
@@ -67,26 +66,26 @@ static struct {u8 reg; u8 data;} cx24110_regdata[]= | |||
67 | {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ | 66 | {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ |
68 | {0x0a,0x00}, /* @ partial chip disables, do not set */ | 67 | {0x0a,0x00}, /* @ partial chip disables, do not set */ |
69 | {0x0b,0x01}, /* set output clock in gapped mode, start signal low | 68 | {0x0b,0x01}, /* set output clock in gapped mode, start signal low |
70 | active for first byte */ | 69 | active for first byte */ |
71 | {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ | 70 | {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ |
72 | {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ | 71 | {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ |
73 | {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 | 72 | {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 |
74 | to avoid starting the BER counter. Reset the | 73 | to avoid starting the BER counter. Reset the |
75 | CRC test bit. Finite counting selected */ | 74 | CRC test bit. Finite counting selected */ |
76 | {0x15,0xff}, /* @ size of the limited time window for RS BER | 75 | {0x15,0xff}, /* @ size of the limited time window for RS BER |
77 | estimation. It is <value>*256 RS blocks, this | 76 | estimation. It is <value>*256 RS blocks, this |
78 | gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ | 77 | gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ |
79 | {0x16,0x00}, /* @ enable all RS output ports */ | 78 | {0x16,0x00}, /* @ enable all RS output ports */ |
80 | {0x17,0x04}, /* @ time window allowed for the RS to sync */ | 79 | {0x17,0x04}, /* @ time window allowed for the RS to sync */ |
81 | {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned | 80 | {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned |
82 | for automatically */ | 81 | for automatically */ |
83 | /* leave the current code rate and normalization | 82 | /* leave the current code rate and normalization |
84 | registers as they are after reset... */ | 83 | registers as they are after reset... */ |
85 | {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting | 84 | {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting |
86 | only once */ | 85 | only once */ |
87 | {0x23,0x18}, /* @ size of the limited time window for Viterbi BER | 86 | {0x23,0x18}, /* @ size of the limited time window for Viterbi BER |
88 | estimation. It is <value>*65536 channel bits, i.e. | 87 | estimation. It is <value>*65536 channel bits, i.e. |
89 | approx. 38ms at 27.5MS/s, rate 3/4 */ | 88 | approx. 38ms at 27.5MS/s, rate 3/4 */ |
90 | {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ | 89 | {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ |
91 | /* leave front-end AGC parameters at default values */ | 90 | /* leave front-end AGC parameters at default values */ |
92 | /* leave decimation AGC parameters at default values */ | 91 | /* leave decimation AGC parameters at default values */ |
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c new file mode 100644 index 000000000000..d661c6f9cbe5 --- /dev/null +++ b/drivers/media/dvb/frontends/cx24123.c | |||
@@ -0,0 +1,889 @@ | |||
1 | /* | ||
2 | Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver | ||
3 | |||
4 | Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> | ||
5 | |||
6 | Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/slab.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/moduleparam.h> | ||
27 | #include <linux/init.h> | ||
28 | |||
29 | #include "dvb_frontend.h" | ||
30 | #include "cx24123.h" | ||
31 | |||
32 | static int debug; | ||
33 | #define dprintk(args...) \ | ||
34 | do { \ | ||
35 | if (debug) printk (KERN_DEBUG "cx24123: " args); \ | ||
36 | } while (0) | ||
37 | |||
38 | struct cx24123_state | ||
39 | { | ||
40 | struct i2c_adapter* i2c; | ||
41 | struct dvb_frontend_ops ops; | ||
42 | const struct cx24123_config* config; | ||
43 | |||
44 | struct dvb_frontend frontend; | ||
45 | |||
46 | u32 lastber; | ||
47 | u16 snr; | ||
48 | u8 lnbreg; | ||
49 | |||
50 | /* Some PLL specifics for tuning */ | ||
51 | u32 VCAarg; | ||
52 | u32 VGAarg; | ||
53 | u32 bandselectarg; | ||
54 | u32 pllarg; | ||
55 | |||
56 | /* The Demod/Tuner can't easily provide these, we cache them */ | ||
57 | u32 currentfreq; | ||
58 | u32 currentsymbolrate; | ||
59 | }; | ||
60 | |||
61 | /* Various tuner defaults need to be established for a given symbol rate Sps */ | ||
62 | static struct | ||
63 | { | ||
64 | u32 symbolrate_low; | ||
65 | u32 symbolrate_high; | ||
66 | u32 VCAslope; | ||
67 | u32 VCAoffset; | ||
68 | u32 VGA1offset; | ||
69 | u32 VGA2offset; | ||
70 | u32 VCAprogdata; | ||
71 | u32 VGAprogdata; | ||
72 | } cx24123_AGC_vals[] = | ||
73 | { | ||
74 | { | ||
75 | .symbolrate_low = 1000000, | ||
76 | .symbolrate_high = 4999999, | ||
77 | .VCAslope = 0x07, | ||
78 | .VCAoffset = 0x0f, | ||
79 | .VGA1offset = 0x1f8, | ||
80 | .VGA2offset = 0x1f8, | ||
81 | .VGAprogdata = (2 << 18) | (0x1f8 << 9) | 0x1f8, | ||
82 | .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x07, | ||
83 | }, | ||
84 | { | ||
85 | .symbolrate_low = 5000000, | ||
86 | .symbolrate_high = 14999999, | ||
87 | .VCAslope = 0x1f, | ||
88 | .VCAoffset = 0x1f, | ||
89 | .VGA1offset = 0x1e0, | ||
90 | .VGA2offset = 0x180, | ||
91 | .VGAprogdata = (2 << 18) | (0x180 << 9) | 0x1e0, | ||
92 | .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x1f, | ||
93 | }, | ||
94 | { | ||
95 | .symbolrate_low = 15000000, | ||
96 | .symbolrate_high = 45000000, | ||
97 | .VCAslope = 0x3f, | ||
98 | .VCAoffset = 0x3f, | ||
99 | .VGA1offset = 0x180, | ||
100 | .VGA2offset = 0x100, | ||
101 | .VGAprogdata = (2 << 18) | (0x100 << 9) | 0x180, | ||
102 | .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x3f, | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | /* | ||
107 | * Various tuner defaults need to be established for a given frequency kHz. | ||
108 | * fixme: The bounds on the bands do not match the doc in real life. | ||
109 | * fixme: Some of them have been moved, other might need adjustment. | ||
110 | */ | ||
111 | static struct | ||
112 | { | ||
113 | u32 freq_low; | ||
114 | u32 freq_high; | ||
115 | u32 bandselect; | ||
116 | u32 VCOdivider; | ||
117 | u32 VCOnumber; | ||
118 | u32 progdata; | ||
119 | } cx24123_bandselect_vals[] = | ||
120 | { | ||
121 | { | ||
122 | .freq_low = 950000, | ||
123 | .freq_high = 1018999, | ||
124 | .bandselect = 0x40, | ||
125 | .VCOdivider = 4, | ||
126 | .VCOnumber = 7, | ||
127 | .progdata = (0 << 18) | (0 << 9) | 0x40, | ||
128 | }, | ||
129 | { | ||
130 | .freq_low = 1019000, | ||
131 | .freq_high = 1074999, | ||
132 | .bandselect = 0x80, | ||
133 | .VCOdivider = 4, | ||
134 | .VCOnumber = 8, | ||
135 | .progdata = (0 << 18) | (0 << 9) | 0x80, | ||
136 | }, | ||
137 | { | ||
138 | .freq_low = 1075000, | ||
139 | .freq_high = 1227999, | ||
140 | .bandselect = 0x01, | ||
141 | .VCOdivider = 2, | ||
142 | .VCOnumber = 1, | ||
143 | .progdata = (0 << 18) | (1 << 9) | 0x01, | ||
144 | }, | ||
145 | { | ||
146 | .freq_low = 1228000, | ||
147 | .freq_high = 1349999, | ||
148 | .bandselect = 0x02, | ||
149 | .VCOdivider = 2, | ||
150 | .VCOnumber = 2, | ||
151 | .progdata = (0 << 18) | (1 << 9) | 0x02, | ||
152 | }, | ||
153 | { | ||
154 | .freq_low = 1350000, | ||
155 | .freq_high = 1481999, | ||
156 | .bandselect = 0x04, | ||
157 | .VCOdivider = 2, | ||
158 | .VCOnumber = 3, | ||
159 | .progdata = (0 << 18) | (1 << 9) | 0x04, | ||
160 | }, | ||
161 | { | ||
162 | .freq_low = 1482000, | ||
163 | .freq_high = 1595999, | ||
164 | .bandselect = 0x08, | ||
165 | .VCOdivider = 2, | ||
166 | .VCOnumber = 4, | ||
167 | .progdata = (0 << 18) | (1 << 9) | 0x08, | ||
168 | }, | ||
169 | { | ||
170 | .freq_low = 1596000, | ||
171 | .freq_high = 1717999, | ||
172 | .bandselect = 0x10, | ||
173 | .VCOdivider = 2, | ||
174 | .VCOnumber = 5, | ||
175 | .progdata = (0 << 18) | (1 << 9) | 0x10, | ||
176 | }, | ||
177 | { | ||
178 | .freq_low = 1718000, | ||
179 | .freq_high = 1855999, | ||
180 | .bandselect = 0x20, | ||
181 | .VCOdivider = 2, | ||
182 | .VCOnumber = 6, | ||
183 | .progdata = (0 << 18) | (1 << 9) | 0x20, | ||
184 | }, | ||
185 | { | ||
186 | .freq_low = 1856000, | ||
187 | .freq_high = 2035999, | ||
188 | .bandselect = 0x40, | ||
189 | .VCOdivider = 2, | ||
190 | .VCOnumber = 7, | ||
191 | .progdata = (0 << 18) | (1 << 9) | 0x40, | ||
192 | }, | ||
193 | { | ||
194 | .freq_low = 2036000, | ||
195 | .freq_high = 2149999, | ||
196 | .bandselect = 0x80, | ||
197 | .VCOdivider = 2, | ||
198 | .VCOnumber = 8, | ||
199 | .progdata = (0 << 18) | (1 << 9) | 0x80, | ||
200 | }, | ||
201 | }; | ||
202 | |||
203 | static struct { | ||
204 | u8 reg; | ||
205 | u8 data; | ||
206 | } cx24123_regdata[] = | ||
207 | { | ||
208 | {0x00, 0x03}, /* Reset system */ | ||
209 | {0x00, 0x00}, /* Clear reset */ | ||
210 | {0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */ | ||
211 | {0x03, 0x07}, | ||
212 | {0x04, 0x10}, | ||
213 | {0x05, 0x04}, | ||
214 | {0x06, 0x31}, | ||
215 | {0x0d, 0x02}, | ||
216 | {0x0e, 0x03}, | ||
217 | {0x0f, 0xfe}, | ||
218 | {0x10, 0x01}, | ||
219 | {0x14, 0x01}, | ||
220 | {0x15, 0x98}, | ||
221 | {0x16, 0x00}, | ||
222 | {0x17, 0x01}, | ||
223 | {0x1b, 0x05}, | ||
224 | {0x1c, 0x80}, | ||
225 | {0x1d, 0x00}, | ||
226 | {0x1e, 0x00}, | ||
227 | {0x20, 0x41}, | ||
228 | {0x21, 0x15}, | ||
229 | {0x27, 0x14}, | ||
230 | {0x28, 0x46}, | ||
231 | {0x29, 0x00}, | ||
232 | {0x2a, 0xb0}, | ||
233 | {0x2b, 0x73}, | ||
234 | {0x2c, 0x00}, | ||
235 | {0x2d, 0x00}, | ||
236 | {0x2e, 0x00}, | ||
237 | {0x2f, 0x00}, | ||
238 | {0x30, 0x00}, | ||
239 | {0x31, 0x00}, | ||
240 | {0x32, 0x8c}, | ||
241 | {0x33, 0x00}, | ||
242 | {0x34, 0x00}, | ||
243 | {0x35, 0x03}, | ||
244 | {0x36, 0x02}, | ||
245 | {0x37, 0x3a}, | ||
246 | {0x3a, 0x00}, /* Enable AGC accumulator */ | ||
247 | {0x44, 0x00}, | ||
248 | {0x45, 0x00}, | ||
249 | {0x46, 0x05}, | ||
250 | {0x56, 0x41}, | ||
251 | {0x57, 0xff}, | ||
252 | {0x67, 0x83}, | ||
253 | }; | ||
254 | |||
255 | static int cx24123_writereg(struct cx24123_state* state, int reg, int data) | ||
256 | { | ||
257 | u8 buf[] = { reg, data }; | ||
258 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | ||
259 | int err; | ||
260 | |||
261 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
262 | printk("%s: writereg error(err == %i, reg == 0x%02x," | ||
263 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); | ||
264 | return -EREMOTEIO; | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data) | ||
271 | { | ||
272 | u8 buf[] = { reg, data }; | ||
273 | /* fixme: put the intersil addr int the config */ | ||
274 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 }; | ||
275 | int err; | ||
276 | |||
277 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
278 | printk("%s: writelnbreg error (err == %i, reg == 0x%02x," | ||
279 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); | ||
280 | return -EREMOTEIO; | ||
281 | } | ||
282 | |||
283 | /* cache the write, no way to read back */ | ||
284 | state->lnbreg = data; | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int cx24123_readreg(struct cx24123_state* state, u8 reg) | ||
290 | { | ||
291 | int ret; | ||
292 | u8 b0[] = { reg }; | ||
293 | u8 b1[] = { 0 }; | ||
294 | struct i2c_msg msg[] = { | ||
295 | { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | ||
296 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } | ||
297 | }; | ||
298 | |||
299 | ret = i2c_transfer(state->i2c, msg, 2); | ||
300 | |||
301 | if (ret != 2) { | ||
302 | printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret); | ||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | return b1[0]; | ||
307 | } | ||
308 | |||
309 | static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) | ||
310 | { | ||
311 | return state->lnbreg; | ||
312 | } | ||
313 | |||
314 | static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) | ||
315 | { | ||
316 | switch (inversion) { | ||
317 | case INVERSION_OFF: | ||
318 | cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f); | ||
319 | cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); | ||
320 | break; | ||
321 | case INVERSION_ON: | ||
322 | cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80); | ||
323 | cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); | ||
324 | break; | ||
325 | case INVERSION_AUTO: | ||
326 | cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f); | ||
327 | break; | ||
328 | default: | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion) | ||
336 | { | ||
337 | u8 val; | ||
338 | |||
339 | val = cx24123_readreg(state, 0x1b) >> 7; | ||
340 | |||
341 | if (val == 0) | ||
342 | *inversion = INVERSION_OFF; | ||
343 | else | ||
344 | *inversion = INVERSION_ON; | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) | ||
350 | { | ||
351 | if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) | ||
352 | fec = FEC_AUTO; | ||
353 | |||
354 | /* Hardware has 5/11 and 3/5 but are never unused */ | ||
355 | switch (fec) { | ||
356 | case FEC_NONE: | ||
357 | return cx24123_writereg(state, 0x0f, 0x01); | ||
358 | case FEC_1_2: | ||
359 | return cx24123_writereg(state, 0x0f, 0x02); | ||
360 | case FEC_2_3: | ||
361 | return cx24123_writereg(state, 0x0f, 0x04); | ||
362 | case FEC_3_4: | ||
363 | return cx24123_writereg(state, 0x0f, 0x08); | ||
364 | case FEC_5_6: | ||
365 | return cx24123_writereg(state, 0x0f, 0x20); | ||
366 | case FEC_7_8: | ||
367 | return cx24123_writereg(state, 0x0f, 0x80); | ||
368 | case FEC_AUTO: | ||
369 | return cx24123_writereg(state, 0x0f, 0xae); | ||
370 | default: | ||
371 | return -EOPNOTSUPP; | ||
372 | } | ||
373 | } | ||
374 | |||
375 | static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec) | ||
376 | { | ||
377 | int ret; | ||
378 | u8 val; | ||
379 | |||
380 | ret = cx24123_readreg (state, 0x1b); | ||
381 | if (ret < 0) | ||
382 | return ret; | ||
383 | val = ret & 0x07; | ||
384 | switch (val) { | ||
385 | case 1: | ||
386 | *fec = FEC_1_2; | ||
387 | break; | ||
388 | case 3: | ||
389 | *fec = FEC_2_3; | ||
390 | break; | ||
391 | case 4: | ||
392 | *fec = FEC_3_4; | ||
393 | break; | ||
394 | case 5: | ||
395 | *fec = FEC_4_5; | ||
396 | break; | ||
397 | case 6: | ||
398 | *fec = FEC_5_6; | ||
399 | break; | ||
400 | case 7: | ||
401 | *fec = FEC_7_8; | ||
402 | break; | ||
403 | case 2: /* *fec = FEC_3_5; break; */ | ||
404 | case 0: /* *fec = FEC_5_11; break; */ | ||
405 | *fec = FEC_AUTO; | ||
406 | break; | ||
407 | default: | ||
408 | *fec = FEC_NONE; // can't happen | ||
409 | } | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /* fixme: Symbol rates < 3MSps may not work because of precision loss */ | ||
415 | static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) | ||
416 | { | ||
417 | u32 val; | ||
418 | |||
419 | val = (srate / 1185) * 100; | ||
420 | |||
421 | /* Compensate for scaling up, by removing 17 symbols per 1Msps */ | ||
422 | val = val - (17 * (srate / 1000000)); | ||
423 | |||
424 | cx24123_writereg(state, 0x08, (val >> 16) & 0xff ); | ||
425 | cx24123_writereg(state, 0x09, (val >> 8) & 0xff ); | ||
426 | cx24123_writereg(state, 0x0a, (val ) & 0xff ); | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Based on the required frequency and symbolrate, the tuner AGC has to be configured | ||
433 | * and the correct band selected. Calculate those values | ||
434 | */ | ||
435 | static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
436 | { | ||
437 | struct cx24123_state *state = fe->demodulator_priv; | ||
438 | u32 ndiv = 0, adiv = 0, vco_div = 0; | ||
439 | int i = 0; | ||
440 | |||
441 | /* Defaults for low freq, low rate */ | ||
442 | state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; | ||
443 | state->VGAarg = cx24123_AGC_vals[0].VGAprogdata; | ||
444 | state->bandselectarg = cx24123_bandselect_vals[0].progdata; | ||
445 | vco_div = cx24123_bandselect_vals[0].VCOdivider; | ||
446 | |||
447 | /* For the given symbolerate, determine the VCA and VGA programming bits */ | ||
448 | for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) | ||
449 | { | ||
450 | if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && | ||
451 | (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { | ||
452 | state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; | ||
453 | state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | /* For the given frequency, determine the bandselect programming bits */ | ||
458 | for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++) | ||
459 | { | ||
460 | if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && | ||
461 | (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) { | ||
462 | state->bandselectarg = cx24123_bandselect_vals[i].progdata; | ||
463 | vco_div = cx24123_bandselect_vals[i].VCOdivider; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | /* Determine the N/A dividers for the requested lband freq (in kHz). */ | ||
468 | /* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */ | ||
469 | ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff; | ||
470 | adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f; | ||
471 | |||
472 | if (adiv == 0) | ||
473 | adiv++; | ||
474 | |||
475 | /* determine the correct pll frequency values. */ | ||
476 | /* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */ | ||
477 | state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14); | ||
478 | state->pllarg |= (ndiv << 5) | adiv; | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* | ||
484 | * Tuner data is 21 bits long, must be left-aligned in data. | ||
485 | * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip. | ||
486 | */ | ||
487 | static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data) | ||
488 | { | ||
489 | struct cx24123_state *state = fe->demodulator_priv; | ||
490 | unsigned long timeout; | ||
491 | |||
492 | /* align the 21 bytes into to bit23 boundary */ | ||
493 | data = data << 3; | ||
494 | |||
495 | /* Reset the demod pll word length to 0x15 bits */ | ||
496 | cx24123_writereg(state, 0x21, 0x15); | ||
497 | |||
498 | /* write the msb 8 bits, wait for the send to be completed */ | ||
499 | timeout = jiffies + msecs_to_jiffies(40); | ||
500 | cx24123_writereg(state, 0x22, (data >> 16) & 0xff); | ||
501 | while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { | ||
502 | if (time_after(jiffies, timeout)) { | ||
503 | printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); | ||
504 | return -EREMOTEIO; | ||
505 | } | ||
506 | msleep(10); | ||
507 | } | ||
508 | |||
509 | /* send another 8 bytes, wait for the send to be completed */ | ||
510 | timeout = jiffies + msecs_to_jiffies(40); | ||
511 | cx24123_writereg(state, 0x22, (data>>8) & 0xff ); | ||
512 | while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { | ||
513 | if (time_after(jiffies, timeout)) { | ||
514 | printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); | ||
515 | return -EREMOTEIO; | ||
516 | } | ||
517 | msleep(10); | ||
518 | } | ||
519 | |||
520 | /* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */ | ||
521 | timeout = jiffies + msecs_to_jiffies(40); | ||
522 | cx24123_writereg(state, 0x22, (data) & 0xff ); | ||
523 | while ((cx24123_readreg(state, 0x20) & 0x80)) { | ||
524 | if (time_after(jiffies, timeout)) { | ||
525 | printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); | ||
526 | return -EREMOTEIO; | ||
527 | } | ||
528 | msleep(10); | ||
529 | } | ||
530 | |||
531 | /* Trigger the demod to configure the tuner */ | ||
532 | cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2); | ||
533 | cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
539 | { | ||
540 | struct cx24123_state *state = fe->demodulator_priv; | ||
541 | |||
542 | if (cx24123_pll_calculate(fe, p) != 0) { | ||
543 | printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__); | ||
544 | return -EINVAL; | ||
545 | } | ||
546 | |||
547 | /* Write the new VCO/VGA */ | ||
548 | cx24123_pll_writereg(fe, p, state->VCAarg); | ||
549 | cx24123_pll_writereg(fe, p, state->VGAarg); | ||
550 | |||
551 | /* Write the new bandselect and pll args */ | ||
552 | cx24123_pll_writereg(fe, p, state->bandselectarg); | ||
553 | cx24123_pll_writereg(fe, p, state->pllarg); | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static int cx24123_initfe(struct dvb_frontend* fe) | ||
559 | { | ||
560 | struct cx24123_state *state = fe->demodulator_priv; | ||
561 | int i; | ||
562 | |||
563 | /* Configure the demod to a good set of defaults */ | ||
564 | for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) | ||
565 | cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); | ||
566 | |||
567 | if (state->config->pll_init) | ||
568 | state->config->pll_init(fe); | ||
569 | |||
570 | /* Configure the LNB for 14V */ | ||
571 | if (state->config->use_isl6421) | ||
572 | cx24123_writelnbreg(state, 0x0, 0x2a); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
578 | { | ||
579 | struct cx24123_state *state = fe->demodulator_priv; | ||
580 | u8 val; | ||
581 | |||
582 | switch (state->config->use_isl6421) { | ||
583 | |||
584 | case 1: | ||
585 | |||
586 | val = cx24123_readlnbreg(state, 0x0); | ||
587 | |||
588 | switch (voltage) { | ||
589 | case SEC_VOLTAGE_13: | ||
590 | return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ | ||
591 | case SEC_VOLTAGE_18: | ||
592 | return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ | ||
593 | case SEC_VOLTAGE_OFF: | ||
594 | return cx24123_writelnbreg(state, 0x0, val & 0x30); | ||
595 | default: | ||
596 | return -EINVAL; | ||
597 | }; | ||
598 | |||
599 | case 0: | ||
600 | |||
601 | val = cx24123_readreg(state, 0x29); | ||
602 | |||
603 | switch (voltage) { | ||
604 | case SEC_VOLTAGE_13: | ||
605 | dprintk("%s: setting voltage 13V\n", __FUNCTION__); | ||
606 | if (state->config->enable_lnb_voltage) | ||
607 | state->config->enable_lnb_voltage(fe, 1); | ||
608 | return cx24123_writereg(state, 0x29, val | 0x80); | ||
609 | case SEC_VOLTAGE_18: | ||
610 | dprintk("%s: setting voltage 18V\n", __FUNCTION__); | ||
611 | if (state->config->enable_lnb_voltage) | ||
612 | state->config->enable_lnb_voltage(fe, 1); | ||
613 | return cx24123_writereg(state, 0x29, val & 0x7f); | ||
614 | case SEC_VOLTAGE_OFF: | ||
615 | dprintk("%s: setting voltage off\n", __FUNCTION__); | ||
616 | if (state->config->enable_lnb_voltage) | ||
617 | state->config->enable_lnb_voltage(fe, 0); | ||
618 | return 0; | ||
619 | default: | ||
620 | return -EINVAL; | ||
621 | }; | ||
622 | } | ||
623 | |||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, | ||
628 | struct dvb_diseqc_master_cmd *cmd) | ||
629 | { | ||
630 | /* fixme: Implement diseqc */ | ||
631 | printk("%s: No support yet\n",__FUNCTION__); | ||
632 | |||
633 | return -ENOTSUPP; | ||
634 | } | ||
635 | |||
636 | static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
637 | { | ||
638 | struct cx24123_state *state = fe->demodulator_priv; | ||
639 | |||
640 | int sync = cx24123_readreg(state, 0x14); | ||
641 | int lock = cx24123_readreg(state, 0x20); | ||
642 | |||
643 | *status = 0; | ||
644 | if (lock & 0x01) | ||
645 | *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; | ||
646 | if (sync & 0x04) | ||
647 | *status |= FE_HAS_VITERBI; | ||
648 | if (sync & 0x08) | ||
649 | *status |= FE_HAS_CARRIER; | ||
650 | if (sync & 0x80) | ||
651 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * Configured to return the measurement of errors in blocks, because no UCBLOCKS value | ||
658 | * is available, so this value doubles up to satisfy both measurements | ||
659 | */ | ||
660 | static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber) | ||
661 | { | ||
662 | struct cx24123_state *state = fe->demodulator_priv; | ||
663 | |||
664 | state->lastber = | ||
665 | ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) | | ||
666 | (cx24123_readreg(state, 0x1d) << 8 | | ||
667 | cx24123_readreg(state, 0x1e)); | ||
668 | |||
669 | /* Do the signal quality processing here, it's derived from the BER. */ | ||
670 | /* Scale the BER from a 24bit to a SNR 16 bit where higher = better */ | ||
671 | if (state->lastber < 5000) | ||
672 | state->snr = 655*100; | ||
673 | else if ( (state->lastber >= 5000) && (state->lastber < 55000) ) | ||
674 | state->snr = 655*90; | ||
675 | else if ( (state->lastber >= 55000) && (state->lastber < 150000) ) | ||
676 | state->snr = 655*80; | ||
677 | else if ( (state->lastber >= 150000) && (state->lastber < 250000) ) | ||
678 | state->snr = 655*70; | ||
679 | else if ( (state->lastber >= 250000) && (state->lastber < 450000) ) | ||
680 | state->snr = 655*65; | ||
681 | else | ||
682 | state->snr = 0; | ||
683 | |||
684 | *ber = state->lastber; | ||
685 | |||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | ||
690 | { | ||
691 | struct cx24123_state *state = fe->demodulator_priv; | ||
692 | *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) | ||
698 | { | ||
699 | struct cx24123_state *state = fe->demodulator_priv; | ||
700 | *snr = state->snr; | ||
701 | |||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
706 | { | ||
707 | struct cx24123_state *state = fe->demodulator_priv; | ||
708 | *ucblocks = state->lastber; | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
714 | { | ||
715 | struct cx24123_state *state = fe->demodulator_priv; | ||
716 | |||
717 | if (state->config->set_ts_params) | ||
718 | state->config->set_ts_params(fe, 0); | ||
719 | |||
720 | state->currentfreq=p->frequency; | ||
721 | state->currentsymbolrate = p->u.qpsk.symbol_rate; | ||
722 | |||
723 | cx24123_set_inversion(state, p->inversion); | ||
724 | cx24123_set_fec(state, p->u.qpsk.fec_inner); | ||
725 | cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate); | ||
726 | cx24123_pll_tune(fe, p); | ||
727 | |||
728 | /* Enable automatic aquisition and reset cycle */ | ||
729 | cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07)); | ||
730 | cx24123_writereg(state, 0x00, 0x10); | ||
731 | cx24123_writereg(state, 0x00, 0); | ||
732 | |||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
737 | { | ||
738 | struct cx24123_state *state = fe->demodulator_priv; | ||
739 | |||
740 | if (cx24123_get_inversion(state, &p->inversion) != 0) { | ||
741 | printk("%s: Failed to get inversion status\n",__FUNCTION__); | ||
742 | return -EREMOTEIO; | ||
743 | } | ||
744 | if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) { | ||
745 | printk("%s: Failed to get fec status\n",__FUNCTION__); | ||
746 | return -EREMOTEIO; | ||
747 | } | ||
748 | p->frequency = state->currentfreq; | ||
749 | p->u.qpsk.symbol_rate = state->currentsymbolrate; | ||
750 | |||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
755 | { | ||
756 | struct cx24123_state *state = fe->demodulator_priv; | ||
757 | u8 val; | ||
758 | |||
759 | switch (state->config->use_isl6421) { | ||
760 | case 1: | ||
761 | |||
762 | val = cx24123_readlnbreg(state, 0x0); | ||
763 | |||
764 | switch (tone) { | ||
765 | case SEC_TONE_ON: | ||
766 | return cx24123_writelnbreg(state, 0x0, val | 0x10); | ||
767 | case SEC_TONE_OFF: | ||
768 | return cx24123_writelnbreg(state, 0x0, val & 0x2f); | ||
769 | default: | ||
770 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | ||
771 | return -EINVAL; | ||
772 | } | ||
773 | |||
774 | case 0: | ||
775 | |||
776 | val = cx24123_readreg(state, 0x29); | ||
777 | |||
778 | switch (tone) { | ||
779 | case SEC_TONE_ON: | ||
780 | dprintk("%s: setting tone on\n", __FUNCTION__); | ||
781 | return cx24123_writereg(state, 0x29, val | 0x10); | ||
782 | case SEC_TONE_OFF: | ||
783 | dprintk("%s: setting tone off\n",__FUNCTION__); | ||
784 | return cx24123_writereg(state, 0x29, val & 0xef); | ||
785 | default: | ||
786 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | ||
787 | return -EINVAL; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | static void cx24123_release(struct dvb_frontend* fe) | ||
795 | { | ||
796 | struct cx24123_state* state = fe->demodulator_priv; | ||
797 | dprintk("%s\n",__FUNCTION__); | ||
798 | kfree(state); | ||
799 | } | ||
800 | |||
801 | static struct dvb_frontend_ops cx24123_ops; | ||
802 | |||
803 | struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | ||
804 | struct i2c_adapter* i2c) | ||
805 | { | ||
806 | struct cx24123_state* state = NULL; | ||
807 | int ret; | ||
808 | |||
809 | dprintk("%s\n",__FUNCTION__); | ||
810 | |||
811 | /* allocate memory for the internal state */ | ||
812 | state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL); | ||
813 | if (state == NULL) { | ||
814 | printk("Unable to kmalloc\n"); | ||
815 | goto error; | ||
816 | } | ||
817 | |||
818 | /* setup the state */ | ||
819 | state->config = config; | ||
820 | state->i2c = i2c; | ||
821 | memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); | ||
822 | state->lastber = 0; | ||
823 | state->snr = 0; | ||
824 | state->lnbreg = 0; | ||
825 | state->VCAarg = 0; | ||
826 | state->VGAarg = 0; | ||
827 | state->bandselectarg = 0; | ||
828 | state->pllarg = 0; | ||
829 | state->currentfreq = 0; | ||
830 | state->currentsymbolrate = 0; | ||
831 | |||
832 | /* check if the demod is there */ | ||
833 | ret = cx24123_readreg(state, 0x00); | ||
834 | if ((ret != 0xd1) && (ret != 0xe1)) { | ||
835 | printk("Version != d1 or e1\n"); | ||
836 | goto error; | ||
837 | } | ||
838 | |||
839 | /* create dvb_frontend */ | ||
840 | state->frontend.ops = &state->ops; | ||
841 | state->frontend.demodulator_priv = state; | ||
842 | return &state->frontend; | ||
843 | |||
844 | error: | ||
845 | kfree(state); | ||
846 | |||
847 | return NULL; | ||
848 | } | ||
849 | |||
850 | static struct dvb_frontend_ops cx24123_ops = { | ||
851 | |||
852 | .info = { | ||
853 | .name = "Conexant CX24123/CX24109", | ||
854 | .type = FE_QPSK, | ||
855 | .frequency_min = 950000, | ||
856 | .frequency_max = 2150000, | ||
857 | .frequency_stepsize = 1011, /* kHz for QPSK frontends */ | ||
858 | .frequency_tolerance = 29500, | ||
859 | .symbol_rate_min = 1000000, | ||
860 | .symbol_rate_max = 45000000, | ||
861 | .caps = FE_CAN_INVERSION_AUTO | | ||
862 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
863 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
864 | FE_CAN_QPSK | FE_CAN_RECOVER | ||
865 | }, | ||
866 | |||
867 | .release = cx24123_release, | ||
868 | |||
869 | .init = cx24123_initfe, | ||
870 | .set_frontend = cx24123_set_frontend, | ||
871 | .get_frontend = cx24123_get_frontend, | ||
872 | .read_status = cx24123_read_status, | ||
873 | .read_ber = cx24123_read_ber, | ||
874 | .read_signal_strength = cx24123_read_signal_strength, | ||
875 | .read_snr = cx24123_read_snr, | ||
876 | .read_ucblocks = cx24123_read_ucblocks, | ||
877 | .diseqc_send_master_cmd = cx24123_send_diseqc_msg, | ||
878 | .set_tone = cx24123_set_tone, | ||
879 | .set_voltage = cx24123_set_voltage, | ||
880 | }; | ||
881 | |||
882 | module_param(debug, int, 0644); | ||
883 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
884 | |||
885 | MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware"); | ||
886 | MODULE_AUTHOR("Steven Toth"); | ||
887 | MODULE_LICENSE("GPL"); | ||
888 | |||
889 | EXPORT_SYMBOL(cx24123_attach); | ||
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h new file mode 100644 index 000000000000..0c922b5e9263 --- /dev/null +++ b/drivers/media/dvb/frontends/cx24123.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver | ||
3 | |||
4 | Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> | ||
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 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef CX24123_H | ||
22 | #define CX24123_H | ||
23 | |||
24 | #include <linux/dvb/frontend.h> | ||
25 | |||
26 | struct cx24123_config | ||
27 | { | ||
28 | /* the demodulator's i2c address */ | ||
29 | u8 demod_address; | ||
30 | |||
31 | /* | ||
32 | cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip | ||
33 | for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits | ||
34 | from register 0x29 of the CX24123 demodulator | ||
35 | */ | ||
36 | int use_isl6421; | ||
37 | |||
38 | /* PLL maintenance */ | ||
39 | int (*pll_init)(struct dvb_frontend* fe); | ||
40 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
41 | |||
42 | /* Need to set device param for start_dma */ | ||
43 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | ||
44 | |||
45 | void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on); | ||
46 | }; | ||
47 | |||
48 | extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | ||
49 | struct i2c_adapter* i2c); | ||
50 | |||
51 | #endif /* CX24123_H */ | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index f857b869616c..a3d57ce9dd12 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -107,18 +107,19 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = { | |||
107 | }; | 107 | }; |
108 | EXPORT_SYMBOL(dvb_pll_microtune_4042); | 108 | EXPORT_SYMBOL(dvb_pll_microtune_4042); |
109 | 109 | ||
110 | struct dvb_pll_desc dvb_pll_thomson_dtt7611 = { | 110 | struct dvb_pll_desc dvb_pll_thomson_dtt761x = { |
111 | .name = "Thomson dtt7611", | 111 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ |
112 | .min = 44000000, | 112 | .name = "Thomson dtt761x", |
113 | .max = 958000000, | 113 | .min = 57000000, |
114 | .max = 863000000, | ||
114 | .count = 3, | 115 | .count = 3, |
115 | .entries = { | 116 | .entries = { |
116 | { 157250000, 44000000, 62500, 0x8e, 0x39 }, | 117 | { 147000000, 44000000, 62500, 0x8e, 0x39 }, |
117 | { 454000000, 44000000, 62500, 0x8e, 0x3a }, | 118 | { 417000000, 44000000, 62500, 0x8e, 0x3a }, |
118 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, | 119 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, |
119 | }, | 120 | }, |
120 | }; | 121 | }; |
121 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7611); | 122 | EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); |
122 | 123 | ||
123 | struct dvb_pll_desc dvb_pll_unknown_1 = { | 124 | struct dvb_pll_desc dvb_pll_unknown_1 = { |
124 | .name = "unknown 1", /* used by dntv live dvb-t */ | 125 | .name = "unknown 1", /* used by dntv live dvb-t */ |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 497d31dcf41e..24d4d2e9acd8 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -25,7 +25,7 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt759x; | |||
25 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; | 25 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; |
26 | extern struct dvb_pll_desc dvb_pll_lg_z201; | 26 | extern struct dvb_pll_desc dvb_pll_lg_z201; |
27 | extern struct dvb_pll_desc dvb_pll_microtune_4042; | 27 | extern struct dvb_pll_desc dvb_pll_microtune_4042; |
28 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7611; | 28 | extern struct dvb_pll_desc dvb_pll_thomson_dtt761x; |
29 | extern struct dvb_pll_desc dvb_pll_unknown_1; | 29 | extern struct dvb_pll_desc dvb_pll_unknown_1; |
30 | 30 | ||
31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; | 31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; |
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index cb5301865d07..9d214643b87a 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c | |||
@@ -27,6 +27,7 @@ | |||
27 | * DViCO FusionHDTV 3 Gold-T | 27 | * DViCO FusionHDTV 3 Gold-T |
28 | * DViCO FusionHDTV 5 Gold | 28 | * DViCO FusionHDTV 5 Gold |
29 | * DViCO FusionHDTV 5 Lite | 29 | * DViCO FusionHDTV 5 Lite |
30 | * DViCO FusionHDTV 5 USB Gold | ||
30 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) | 31 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) |
31 | * | 32 | * |
32 | * TODO: | 33 | * TODO: |
@@ -402,6 +403,8 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, | |||
402 | state->config->pll_set(fe, param); | 403 | state->config->pll_set(fe, param); |
403 | 404 | ||
404 | /* Keep track of the new frequency */ | 405 | /* Keep track of the new frequency */ |
406 | /* FIXME this is the wrong way to do this... */ | ||
407 | /* The tuner is shared with the video4linux analog API */ | ||
405 | state->current_frequency = param->frequency; | 408 | state->current_frequency = param->frequency; |
406 | 409 | ||
407 | lgdt330x_SwReset(state); | 410 | lgdt330x_SwReset(state); |
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c index 52c416043a62..4f263e65ba14 100644 --- a/drivers/media/dvb/frontends/nxt2002.c +++ b/drivers/media/dvb/frontends/nxt2002.c | |||
@@ -22,7 +22,8 @@ | |||
22 | /* | 22 | /* |
23 | * This driver needs external firmware. Please use the command | 23 | * This driver needs external firmware. Please use the command |
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to |
25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
26 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
26 | */ | 27 | */ |
27 | #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" | 28 | #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" |
28 | #define CRC_CCIT_MASK 0x1021 | 29 | #define CRC_CCIT_MASK 0x1021 |
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c index a458a3bfff70..a16eeba0020d 100644 --- a/drivers/media/dvb/frontends/nxt6000.c +++ b/drivers/media/dvb/frontends/nxt6000.c | |||
@@ -574,11 +574,11 @@ static struct dvb_frontend_ops nxt6000_ops = { | |||
574 | .symbol_rate_max = 9360000, /* FIXME */ | 574 | .symbol_rate_max = 9360000, /* FIXME */ |
575 | .symbol_rate_tolerance = 4000, | 575 | .symbol_rate_tolerance = 4000, |
576 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 576 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
577 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | | 577 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | |
578 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | | 578 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | |
579 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | 579 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | |
580 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | 580 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | |
581 | FE_CAN_HIERARCHY_AUTO, | 581 | FE_CAN_HIERARCHY_AUTO, |
582 | }, | 582 | }, |
583 | 583 | ||
584 | .release = nxt6000_release, | 584 | .release = nxt6000_release, |
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c index 531f76246e5f..7c3aed1f546b 100644 --- a/drivers/media/dvb/frontends/or51211.c +++ b/drivers/media/dvb/frontends/or51211.c | |||
@@ -25,7 +25,8 @@ | |||
25 | /* | 25 | /* |
26 | * This driver needs external firmware. Please use the command | 26 | * This driver needs external firmware. Please use the command |
27 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to | 27 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to |
28 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 28 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
29 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
29 | */ | 30 | */ |
30 | #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" | 31 | #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" |
31 | 32 | ||
@@ -112,7 +113,7 @@ static int or51211_load_firmware (struct dvb_frontend* fe, | |||
112 | u8 tudata[585]; | 113 | u8 tudata[585]; |
113 | int i; | 114 | int i; |
114 | 115 | ||
115 | dprintk("Firmware is %d bytes\n",fw->size); | 116 | dprintk("Firmware is %zd bytes\n",fw->size); |
116 | 117 | ||
117 | /* Get eprom data */ | 118 | /* Get eprom data */ |
118 | tudata[0] = 17; | 119 | tudata[0] = 17; |
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index 18715091aed8..d69477596921 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c | |||
@@ -521,8 +521,8 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state, | |||
521 | 521 | ||
522 | case FEC_3_4: | 522 | case FEC_3_4: |
523 | s5h1420_writereg(state, 0x30, 0x04); | 523 | s5h1420_writereg(state, 0x30, 0x04); |
524 | s5h1420_writereg(state, 0x31, 0x12 | inversion); | 524 | s5h1420_writereg(state, 0x31, 0x12 | inversion); |
525 | break; | 525 | break; |
526 | 526 | ||
527 | case FEC_5_6: | 527 | case FEC_5_6: |
528 | s5h1420_writereg(state, 0x30, 0x08); | 528 | s5h1420_writereg(state, 0x30, 0x08); |
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c index fc06cd6b46c3..73829e647e50 100644 --- a/drivers/media/dvb/frontends/sp8870.c +++ b/drivers/media/dvb/frontends/sp8870.c | |||
@@ -22,7 +22,8 @@ | |||
22 | /* | 22 | /* |
23 | * This driver needs external firmware. Please use the command | 23 | * This driver needs external firmware. Please use the command |
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to | 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to |
25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
26 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
26 | */ | 27 | */ |
27 | #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" | 28 | #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" |
28 | 29 | ||
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c index e3b665782243..eb8a602198ca 100644 --- a/drivers/media/dvb/frontends/sp887x.c +++ b/drivers/media/dvb/frontends/sp887x.c | |||
@@ -5,7 +5,8 @@ | |||
5 | /* | 5 | /* |
6 | * This driver needs external firmware. Please use the command | 6 | * This driver needs external firmware. Please use the command |
7 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to | 7 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to |
8 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 8 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
9 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
9 | */ | 10 | */ |
10 | #define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" | 11 | #define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" |
11 | 12 | ||
@@ -581,7 +582,7 @@ static struct dvb_frontend_ops sp887x_ops = { | |||
581 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 582 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
582 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | 583 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
583 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | | 584 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | |
584 | FE_CAN_RECOVER | 585 | FE_CAN_RECOVER |
585 | }, | 586 | }, |
586 | 587 | ||
587 | .release = sp887x_release, | 588 | .release = sp887x_release, |
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 177d71d56b67..5bcd00f792e6 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c | |||
@@ -131,6 +131,13 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len | |||
131 | return ret == 2 ? 0 : ret; | 131 | return ret == 2 ? 0 : ret; |
132 | } | 132 | } |
133 | 133 | ||
134 | int stv0299_enable_plli2c (struct dvb_frontend* fe) | ||
135 | { | ||
136 | struct stv0299_state* state = fe->demodulator_priv; | ||
137 | |||
138 | return stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | ||
139 | } | ||
140 | |||
134 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) | 141 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) |
135 | { | 142 | { |
136 | dprintk ("%s\n", __FUNCTION__); | 143 | dprintk ("%s\n", __FUNCTION__); |
@@ -387,7 +394,7 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag | |||
387 | }; | 394 | }; |
388 | } | 395 | } |
389 | 396 | ||
390 | static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | 397 | static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd) |
391 | { | 398 | { |
392 | struct stv0299_state* state = fe->demodulator_priv; | 399 | struct stv0299_state* state = fe->demodulator_priv; |
393 | u8 reg0x08; | 400 | u8 reg0x08; |
@@ -407,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | |||
407 | 414 | ||
408 | cmd = cmd << 1; | 415 | cmd = cmd << 1; |
409 | if (debug_legacy_dish_switch) | 416 | if (debug_legacy_dish_switch) |
410 | printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd); | 417 | printk ("%s switch command: 0x%04lx\n",__FUNCTION__, cmd); |
411 | 418 | ||
412 | do_gettimeofday (&nexttime); | 419 | do_gettimeofday (&nexttime); |
413 | if (debug_legacy_dish_switch) | 420 | if (debug_legacy_dish_switch) |
@@ -717,5 +724,6 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " | |||
717 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); | 724 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); |
718 | MODULE_LICENSE("GPL"); | 725 | MODULE_LICENSE("GPL"); |
719 | 726 | ||
727 | EXPORT_SYMBOL(stv0299_enable_plli2c); | ||
720 | EXPORT_SYMBOL(stv0299_writereg); | 728 | EXPORT_SYMBOL(stv0299_writereg); |
721 | EXPORT_SYMBOL(stv0299_attach); | 729 | EXPORT_SYMBOL(stv0299_attach); |
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index 9af3d71c89db..32c87b4c2f13 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h | |||
@@ -94,6 +94,7 @@ struct stv0299_config | |||
94 | }; | 94 | }; |
95 | 95 | ||
96 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); | 96 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); |
97 | extern int stv0299_enable_plli2c (struct dvb_frontend* fe); | ||
97 | 98 | ||
98 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | 99 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, |
99 | struct i2c_adapter* i2c); | 100 | struct i2c_adapter* i2c); |
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 425cd19136fe..21255cac9793 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -95,7 +95,7 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) | |||
95 | u8 b0 [] = { reg }; | 95 | u8 b0 [] = { reg }; |
96 | u8 b1 [] = { 0 }; | 96 | u8 b1 [] = { 0 }; |
97 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | 97 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, |
98 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; | 98 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; |
99 | int ret; | 99 | int ret; |
100 | 100 | ||
101 | ret = i2c_transfer (state->i2c, msg, 2); | 101 | ret = i2c_transfer (state->i2c, msg, 2); |
@@ -434,7 +434,7 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
434 | .frequency_max = 858000000, | 434 | .frequency_max = 858000000, |
435 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ | 435 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ |
436 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ | 436 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ |
437 | #if 0 | 437 | #if 0 |
438 | .frequency_tolerance = ???, | 438 | .frequency_tolerance = ???, |
439 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ | 439 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ |
440 | #endif | 440 | #endif |
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index dd02aff467fe..c63e9a5084eb 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -23,7 +23,8 @@ | |||
23 | * This driver needs external firmware. Please use the commands | 23 | * This driver needs external firmware. Please use the commands |
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", | 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", |
25 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to | 25 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to |
26 | * download/extract them, and then copy them to /usr/lib/hotplug/firmware. | 26 | * download/extract them, and then copy them to /usr/lib/hotplug/firmware |
27 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
27 | */ | 28 | */ |
28 | #define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" | 29 | #define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" |
29 | #define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" | 30 | #define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" |
@@ -271,32 +272,57 @@ static int tda10045h_set_bandwidth(struct tda1004x_state *state, | |||
271 | static int tda10046h_set_bandwidth(struct tda1004x_state *state, | 272 | static int tda10046h_set_bandwidth(struct tda1004x_state *state, |
272 | fe_bandwidth_t bandwidth) | 273 | fe_bandwidth_t bandwidth) |
273 | { | 274 | { |
274 | static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e }; | 275 | static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 }; |
275 | static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 }; | 276 | static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f }; |
276 | static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd }; | 277 | static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d }; |
277 | 278 | ||
279 | static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 }; | ||
280 | static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab }; | ||
281 | static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 }; | ||
282 | int tda10046_clk53m; | ||
283 | |||
284 | if ((state->config->if_freq == TDA10046_FREQ_045) || | ||
285 | (state->config->if_freq == TDA10046_FREQ_052)) | ||
286 | tda10046_clk53m = 0; | ||
287 | else | ||
288 | tda10046_clk53m = 1; | ||
278 | switch (bandwidth) { | 289 | switch (bandwidth) { |
279 | case BANDWIDTH_6_MHZ: | 290 | case BANDWIDTH_6_MHZ: |
280 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz)); | 291 | if (tda10046_clk53m) |
292 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M, | ||
293 | sizeof(bandwidth_6mhz_53M)); | ||
294 | else | ||
295 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M, | ||
296 | sizeof(bandwidth_6mhz_48M)); | ||
281 | if (state->config->if_freq == TDA10046_FREQ_045) { | 297 | if (state->config->if_freq == TDA10046_FREQ_045) { |
282 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09); | 298 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); |
283 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f); | 299 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab); |
284 | } | 300 | } |
285 | break; | 301 | break; |
286 | 302 | ||
287 | case BANDWIDTH_7_MHZ: | 303 | case BANDWIDTH_7_MHZ: |
288 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz)); | 304 | if (tda10046_clk53m) |
305 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M, | ||
306 | sizeof(bandwidth_7mhz_53M)); | ||
307 | else | ||
308 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M, | ||
309 | sizeof(bandwidth_7mhz_48M)); | ||
289 | if (state->config->if_freq == TDA10046_FREQ_045) { | 310 | if (state->config->if_freq == TDA10046_FREQ_045) { |
290 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); | 311 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); |
291 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79); | 312 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); |
292 | } | 313 | } |
293 | break; | 314 | break; |
294 | 315 | ||
295 | case BANDWIDTH_8_MHZ: | 316 | case BANDWIDTH_8_MHZ: |
296 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz)); | 317 | if (tda10046_clk53m) |
318 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M, | ||
319 | sizeof(bandwidth_8mhz_53M)); | ||
320 | else | ||
321 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M, | ||
322 | sizeof(bandwidth_8mhz_48M)); | ||
297 | if (state->config->if_freq == TDA10046_FREQ_045) { | 323 | if (state->config->if_freq == TDA10046_FREQ_045) { |
298 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); | 324 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); |
299 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); | 325 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55); |
300 | } | 326 | } |
301 | break; | 327 | break; |
302 | 328 | ||
@@ -418,9 +444,22 @@ static int tda10045_fwupload(struct dvb_frontend* fe) | |||
418 | static void tda10046_init_plls(struct dvb_frontend* fe) | 444 | static void tda10046_init_plls(struct dvb_frontend* fe) |
419 | { | 445 | { |
420 | struct tda1004x_state* state = fe->demodulator_priv; | 446 | struct tda1004x_state* state = fe->demodulator_priv; |
447 | int tda10046_clk53m; | ||
448 | |||
449 | if ((state->config->if_freq == TDA10046_FREQ_045) || | ||
450 | (state->config->if_freq == TDA10046_FREQ_052)) | ||
451 | tda10046_clk53m = 0; | ||
452 | else | ||
453 | tda10046_clk53m = 1; | ||
421 | 454 | ||
422 | tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); | 455 | tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); |
423 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10 | 456 | if(tda10046_clk53m) { |
457 | printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n"); | ||
458 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8 | ||
459 | } else { | ||
460 | printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n"); | ||
461 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3 | ||
462 | } | ||
424 | if (state->config->xtal_freq == TDA10046_XTAL_4M ) { | 463 | if (state->config->xtal_freq == TDA10046_XTAL_4M ) { |
425 | dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); | 464 | dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); |
426 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 | 465 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 |
@@ -428,26 +467,32 @@ static void tda10046_init_plls(struct dvb_frontend* fe) | |||
428 | dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); | 467 | dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); |
429 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 | 468 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 |
430 | } | 469 | } |
431 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); | 470 | if(tda10046_clk53m) |
471 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67); | ||
472 | else | ||
473 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72); | ||
474 | /* Note clock frequency is handled implicitly */ | ||
432 | switch (state->config->if_freq) { | 475 | switch (state->config->if_freq) { |
433 | case TDA10046_FREQ_3617: | ||
434 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); | ||
435 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); | ||
436 | break; | ||
437 | case TDA10046_FREQ_3613: | ||
438 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); | ||
439 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13); | ||
440 | break; | ||
441 | case TDA10046_FREQ_045: | 476 | case TDA10046_FREQ_045: |
442 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); | 477 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); |
443 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); | 478 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); |
444 | break; | 479 | break; |
445 | case TDA10046_FREQ_052: | 480 | case TDA10046_FREQ_052: |
446 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); | 481 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); |
447 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06); | 482 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7); |
483 | break; | ||
484 | case TDA10046_FREQ_3617: | ||
485 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); | ||
486 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59); | ||
487 | break; | ||
488 | case TDA10046_FREQ_3613: | ||
489 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); | ||
490 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f); | ||
448 | break; | 491 | break; |
449 | } | 492 | } |
450 | tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz | 493 | tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz |
494 | /* let the PLLs settle */ | ||
495 | msleep(120); | ||
451 | } | 496 | } |
452 | 497 | ||
453 | static int tda10046_fwupload(struct dvb_frontend* fe) | 498 | static int tda10046_fwupload(struct dvb_frontend* fe) |
@@ -462,13 +507,13 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
462 | /* let the clocks recover from sleep */ | 507 | /* let the clocks recover from sleep */ |
463 | msleep(5); | 508 | msleep(5); |
464 | 509 | ||
510 | /* The PLLs need to be reprogrammed after sleep */ | ||
511 | tda10046_init_plls(fe); | ||
512 | |||
465 | /* don't re-upload unless necessary */ | 513 | /* don't re-upload unless necessary */ |
466 | if (tda1004x_check_upload_ok(state) == 0) | 514 | if (tda1004x_check_upload_ok(state) == 0) |
467 | return 0; | 515 | return 0; |
468 | 516 | ||
469 | /* set parameters */ | ||
470 | tda10046_init_plls(fe); | ||
471 | |||
472 | if (state->config->request_firmware != NULL) { | 517 | if (state->config->request_firmware != NULL) { |
473 | /* request the firmware, this will block until someone uploads it */ | 518 | /* request the firmware, this will block until someone uploads it */ |
474 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); | 519 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); |
@@ -484,7 +529,6 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
484 | return ret; | 529 | return ret; |
485 | } else { | 530 | } else { |
486 | /* boot from firmware eeprom */ | 531 | /* boot from firmware eeprom */ |
487 | /* Hac Note: we might need to do some GPIO Magic here */ | ||
488 | printk(KERN_INFO "tda1004x: booting from eeprom\n"); | 532 | printk(KERN_INFO "tda1004x: booting from eeprom\n"); |
489 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); | 533 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); |
490 | msleep(300); | 534 | msleep(300); |
@@ -606,10 +650,9 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
606 | 650 | ||
607 | // tda setup | 651 | // tda setup |
608 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer | 652 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer |
609 | tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream | 653 | tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream |
610 | tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer | 654 | tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer |
611 | 655 | ||
612 | tda10046_init_plls(fe); | ||
613 | switch (state->config->agc_config) { | 656 | switch (state->config->agc_config) { |
614 | case TDA10046_AGC_DEFAULT: | 657 | case TDA10046_AGC_DEFAULT: |
615 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup | 658 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup |
@@ -626,25 +669,22 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
626 | case TDA10046_AGC_TDA827X: | 669 | case TDA10046_AGC_TDA827X: |
627 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | 670 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup |
628 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | 671 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold |
629 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize | 672 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize |
630 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | 673 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities |
631 | break; | 674 | break; |
632 | } | 675 | } |
676 | tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); | ||
633 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on | 677 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on |
634 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } | 678 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } |
635 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values | 679 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values |
636 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } | 680 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } |
637 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } | 681 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } |
638 | tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1 | 682 | tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1 |
639 | tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits | 683 | tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits |
640 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config | 684 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config |
641 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config | 685 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config |
642 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); | 686 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); |
643 | 687 | ||
644 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup | ||
645 | tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config | ||
646 | tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select | ||
647 | |||
648 | state->initialised = 1; | 688 | state->initialised = 1; |
649 | return 0; | 689 | return 0; |
650 | } | 690 | } |
@@ -686,9 +726,9 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
686 | 726 | ||
687 | // Set standard params.. or put them to auto | 727 | // Set standard params.. or put them to auto |
688 | if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || | 728 | if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || |
689 | (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || | 729 | (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || |
690 | (fe_params->u.ofdm.constellation == QAM_AUTO) || | 730 | (fe_params->u.ofdm.constellation == QAM_AUTO) || |
691 | (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { | 731 | (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { |
692 | tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto | 732 | tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto |
693 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits | 733 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits |
694 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits | 734 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits |
@@ -851,6 +891,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
851 | static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) | 891 | static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) |
852 | { | 892 | { |
853 | struct tda1004x_state* state = fe->demodulator_priv; | 893 | struct tda1004x_state* state = fe->demodulator_priv; |
894 | |||
854 | dprintk("%s\n", __FUNCTION__); | 895 | dprintk("%s\n", __FUNCTION__); |
855 | 896 | ||
856 | // inversion status | 897 | // inversion status |
@@ -875,16 +916,18 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
875 | break; | 916 | break; |
876 | } | 917 | } |
877 | break; | 918 | break; |
878 | |||
879 | case TDA1004X_DEMOD_TDA10046: | 919 | case TDA1004X_DEMOD_TDA10046: |
880 | switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { | 920 | switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { |
881 | case 0x60: | 921 | case 0x5c: |
922 | case 0x54: | ||
882 | fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; | 923 | fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; |
883 | break; | 924 | break; |
884 | case 0x6e: | 925 | case 0x6a: |
926 | case 0x60: | ||
885 | fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; | 927 | fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; |
886 | break; | 928 | break; |
887 | case 0x80: | 929 | case 0x7b: |
930 | case 0x70: | ||
888 | fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; | 931 | fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; |
889 | break; | 932 | break; |
890 | } | 933 | } |