diff options
author | Michael Krufky <mkrufky@linuxtv.org> | 2007-04-27 11:31:14 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-04-27 14:43:35 -0400 |
commit | 8ce47dad8e2b9fcb899a67e6537337fa9c18c1f5 (patch) | |
tree | 8482515d25ebc98bf7ac74e47b78f576f23b753f /drivers | |
parent | 7c7fea669d77048b3013567dfb4c9171d536da05 (diff) |
V4L/DVB (5317): Create tda827x dvb tuner module
The patch moves the tda827x dvb tuning code to a separate module
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Hartmut Hackmann <hartmut.hackmann@t-online.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/dvb/frontends/Kconfig | 7 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda1004x.h | 3 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda827x.c | 476 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda827x.h | 62 | ||||
-rw-r--r-- | drivers/media/video/saa7134/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-cards.c | 2 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-dvb.c | 375 |
8 files changed, 568 insertions, 359 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 22c2cf2cea98..a205e0b45a54 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -290,6 +290,13 @@ config DVB_TDA826X | |||
290 | help | 290 | help |
291 | A DVB-S silicon tuner module. Say Y when you want to support this tuner. | 291 | A DVB-S silicon tuner module. Say Y when you want to support this tuner. |
292 | 292 | ||
293 | config DVB_TDA827X | ||
294 | tristate "Philips TDA827X silicon tuner" | ||
295 | depends on DVB_CORE && I2C | ||
296 | default m if DVB_FE_CUSTOMISE | ||
297 | help | ||
298 | A DVB-T silicon tuner module. Say Y when you want to support this tuner. | ||
299 | |||
293 | config DVB_TUNER_QT1010 | 300 | config DVB_TUNER_QT1010 |
294 | tristate "Quantek QT1010 silicon tuner" | 301 | tristate "Quantek QT1010 silicon tuner" |
295 | depends on DVB_CORE && I2C | 302 | depends on DVB_CORE && I2C |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index a646d9969b71..e038942a1d8a 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -37,6 +37,7 @@ obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | |||
37 | obj-$(CONFIG_DVB_ISL6421) += isl6421.o | 37 | obj-$(CONFIG_DVB_ISL6421) += isl6421.o |
38 | obj-$(CONFIG_DVB_TDA10086) += tda10086.o | 38 | obj-$(CONFIG_DVB_TDA10086) += tda10086.o |
39 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o | 39 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o |
40 | obj-$(CONFIG_DVB_TDA827X) += tda827x.o | ||
40 | obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o | 41 | obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o |
41 | obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o | 42 | obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o |
42 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o | 43 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o |
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h index 886db3f75d56..6badc81d4c33 100644 --- a/drivers/media/dvb/frontends/tda1004x.h +++ b/drivers/media/dvb/frontends/tda1004x.h | |||
@@ -106,9 +106,6 @@ struct tda1004x_state { | |||
106 | const struct tda1004x_config* config; | 106 | const struct tda1004x_config* config; |
107 | struct dvb_frontend frontend; | 107 | struct dvb_frontend frontend; |
108 | 108 | ||
109 | /* this allows to store probed board information */ | ||
110 | int conf_probed; | ||
111 | |||
112 | /* private demod data */ | 109 | /* private demod data */ |
113 | enum tda1004x_demod demod_type; | 110 | enum tda1004x_demod demod_type; |
114 | }; | 111 | }; |
diff --git a/drivers/media/dvb/frontends/tda827x.c b/drivers/media/dvb/frontends/tda827x.c new file mode 100644 index 000000000000..cff2d1fa4094 --- /dev/null +++ b/drivers/media/dvb/frontends/tda827x.c | |||
@@ -0,0 +1,476 @@ | |||
1 | /* | ||
2 | * | ||
3 | * (c) 2005 Hartmut Hackmann | ||
4 | * (c) 2007 Michael Krufky | ||
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 | #include <linux/module.h> | ||
22 | #include <linux/dvb/frontend.h> | ||
23 | #include <asm/types.h> | ||
24 | |||
25 | #include "tda827x.h" | ||
26 | |||
27 | static int debug = 0; | ||
28 | #define dprintk(args...) \ | ||
29 | do { \ | ||
30 | if (debug) printk(KERN_DEBUG "tda827x: " args); \ | ||
31 | } while (0) | ||
32 | |||
33 | struct tda827x_priv { | ||
34 | int i2c_addr; | ||
35 | struct i2c_adapter *i2c_adap; | ||
36 | struct tda827x_config *cfg; | ||
37 | u32 frequency; | ||
38 | u32 bandwidth; | ||
39 | }; | ||
40 | |||
41 | struct tda827x_data { | ||
42 | u32 lomax; | ||
43 | u8 spd; | ||
44 | u8 bs; | ||
45 | u8 bp; | ||
46 | u8 cp; | ||
47 | u8 gc3; | ||
48 | u8 div1p5; | ||
49 | }; | ||
50 | |||
51 | static const struct tda827x_data tda827x_dvbt[] = { | ||
52 | { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | ||
53 | { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | ||
54 | { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | ||
55 | { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | ||
56 | { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
57 | { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
58 | { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
59 | { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
60 | { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
61 | { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
62 | { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
63 | { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
64 | { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
65 | { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
66 | { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
67 | { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
68 | { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
69 | { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
70 | { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
71 | { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
72 | { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
73 | { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
74 | { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
75 | { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
76 | { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
77 | { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | ||
78 | { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
79 | { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | ||
80 | { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} | ||
81 | }; | ||
82 | |||
83 | static int tda827xo_set_params(struct dvb_frontend *fe, | ||
84 | struct dvb_frontend_parameters *params) | ||
85 | { | ||
86 | struct tda827x_priv *priv = fe->tuner_priv; | ||
87 | u8 buf[14]; | ||
88 | |||
89 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
90 | .buf = buf, .len = sizeof(buf) }; | ||
91 | int i, tuner_freq, if_freq; | ||
92 | u32 N; | ||
93 | |||
94 | switch (params->u.ofdm.bandwidth) { | ||
95 | case BANDWIDTH_6_MHZ: | ||
96 | if_freq = 4000000; | ||
97 | break; | ||
98 | case BANDWIDTH_7_MHZ: | ||
99 | if_freq = 4500000; | ||
100 | break; | ||
101 | default: /* 8 MHz or Auto */ | ||
102 | if_freq = 5000000; | ||
103 | break; | ||
104 | } | ||
105 | tuner_freq = params->frequency + if_freq; | ||
106 | |||
107 | i = 0; | ||
108 | while (tda827x_dvbt[i].lomax < tuner_freq) { | ||
109 | if(tda827x_dvbt[i + 1].lomax == 0) | ||
110 | break; | ||
111 | i++; | ||
112 | } | ||
113 | |||
114 | N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2); | ||
115 | buf[0] = 0; | ||
116 | buf[1] = (N>>8) | 0x40; | ||
117 | buf[2] = N & 0xff; | ||
118 | buf[3] = 0; | ||
119 | buf[4] = 0x52; | ||
120 | buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) + | ||
121 | (tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp; | ||
122 | buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f; | ||
123 | buf[7] = 0xbf; | ||
124 | buf[8] = 0x2a; | ||
125 | buf[9] = 0x05; | ||
126 | buf[10] = 0xff; | ||
127 | buf[11] = 0x00; | ||
128 | buf[12] = 0x00; | ||
129 | buf[13] = 0x40; | ||
130 | |||
131 | msg.len = 14; | ||
132 | if (fe->ops.i2c_gate_ctrl) | ||
133 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
134 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | ||
135 | printk("%s: could not write to tuner at addr: 0x%02x\n", | ||
136 | __FUNCTION__, priv->i2c_addr << 1); | ||
137 | return -EIO; | ||
138 | } | ||
139 | msleep(500); | ||
140 | /* correct CP value */ | ||
141 | buf[0] = 0x30; | ||
142 | buf[1] = 0x50 + tda827x_dvbt[i].cp; | ||
143 | msg.len = 2; | ||
144 | |||
145 | if (fe->ops.i2c_gate_ctrl) | ||
146 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
147 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
148 | |||
149 | priv->frequency = tuner_freq - if_freq; // FIXME | ||
150 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int tda827xo_sleep(struct dvb_frontend *fe) | ||
156 | { | ||
157 | struct tda827x_priv *priv = fe->tuner_priv; | ||
158 | static u8 buf[] = { 0x30, 0xd0 }; | ||
159 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
160 | .buf = buf, .len = sizeof(buf) }; | ||
161 | |||
162 | if (fe->ops.i2c_gate_ctrl) | ||
163 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
164 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
165 | |||
166 | if (priv->cfg && priv->cfg->sleep) | ||
167 | priv->cfg->sleep(fe); | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | /* ------------------------------------------------------------------ */ | ||
173 | |||
174 | struct tda827xa_data { | ||
175 | u32 lomax; | ||
176 | u8 svco; | ||
177 | u8 spd; | ||
178 | u8 scr; | ||
179 | u8 sbs; | ||
180 | u8 gc3; | ||
181 | }; | ||
182 | |||
183 | static const struct tda827xa_data tda827xa_dvbt[] = { | ||
184 | { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
185 | { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
186 | { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
187 | { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
188 | { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
189 | { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
190 | { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
191 | { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
192 | { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
193 | { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
194 | { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
195 | { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
196 | { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
197 | { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
198 | { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
199 | { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
200 | { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
201 | { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, | ||
202 | { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
203 | { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
204 | { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
205 | { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
206 | { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
207 | { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
208 | { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
209 | { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, | ||
210 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} | ||
211 | }; | ||
212 | |||
213 | static int tda827xa_set_params(struct dvb_frontend *fe, | ||
214 | struct dvb_frontend_parameters *params) | ||
215 | { | ||
216 | struct tda827x_priv *priv = fe->tuner_priv; | ||
217 | u8 buf[10]; | ||
218 | |||
219 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
220 | .buf = buf, .len = sizeof(buf) }; | ||
221 | |||
222 | int i, tuner_freq, if_freq; | ||
223 | u32 N; | ||
224 | |||
225 | if (priv->cfg && priv->cfg->lna_gain) | ||
226 | priv->cfg->lna_gain(fe, 1); | ||
227 | msleep(20); | ||
228 | |||
229 | switch (params->u.ofdm.bandwidth) { | ||
230 | case BANDWIDTH_6_MHZ: | ||
231 | if_freq = 4000000; | ||
232 | break; | ||
233 | case BANDWIDTH_7_MHZ: | ||
234 | if_freq = 4500000; | ||
235 | break; | ||
236 | default: /* 8 MHz or Auto */ | ||
237 | if_freq = 5000000; | ||
238 | break; | ||
239 | } | ||
240 | tuner_freq = params->frequency + if_freq; | ||
241 | |||
242 | i = 0; | ||
243 | while (tda827xa_dvbt[i].lomax < tuner_freq) { | ||
244 | if(tda827xa_dvbt[i + 1].lomax == 0) | ||
245 | break; | ||
246 | i++; | ||
247 | } | ||
248 | |||
249 | N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd; | ||
250 | buf[0] = 0; // subaddress | ||
251 | buf[1] = N >> 8; | ||
252 | buf[2] = N & 0xff; | ||
253 | buf[3] = 0; | ||
254 | buf[4] = 0x16; | ||
255 | buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) + | ||
256 | tda827xa_dvbt[i].sbs; | ||
257 | buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4); | ||
258 | buf[7] = 0x1c; | ||
259 | buf[8] = 0x06; | ||
260 | buf[9] = 0x24; | ||
261 | buf[10] = 0x00; | ||
262 | msg.len = 11; | ||
263 | if (fe->ops.i2c_gate_ctrl) | ||
264 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
265 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | ||
266 | printk("%s: could not write to tuner at addr: 0x%02x\n", | ||
267 | __FUNCTION__, priv->i2c_addr << 1); | ||
268 | return -EIO; | ||
269 | } | ||
270 | buf[0] = 0x90; | ||
271 | buf[1] = 0xff; | ||
272 | buf[2] = 0x60; | ||
273 | buf[3] = 0x00; | ||
274 | buf[4] = 0x59; // lpsel, for 6MHz + 2 | ||
275 | msg.len = 5; | ||
276 | if (fe->ops.i2c_gate_ctrl) | ||
277 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
278 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
279 | |||
280 | buf[0] = 0xa0; | ||
281 | buf[1] = 0x40; | ||
282 | msg.len = 2; | ||
283 | if (fe->ops.i2c_gate_ctrl) | ||
284 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
285 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
286 | |||
287 | msleep(11); | ||
288 | msg.flags = I2C_M_RD; | ||
289 | if (fe->ops.i2c_gate_ctrl) | ||
290 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
291 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
292 | msg.flags = 0; | ||
293 | |||
294 | buf[1] >>= 4; | ||
295 | dprintk("tda8275a AGC2 gain is: %d\n", buf[1]); | ||
296 | if ((buf[1]) < 2) { | ||
297 | if (priv->cfg && priv->cfg->lna_gain) | ||
298 | priv->cfg->lna_gain(fe, 0); | ||
299 | buf[0] = 0x60; | ||
300 | buf[1] = 0x0c; | ||
301 | if (fe->ops.i2c_gate_ctrl) | ||
302 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
303 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
304 | } | ||
305 | |||
306 | buf[0] = 0xc0; | ||
307 | buf[1] = 0x99; // lpsel, for 6MHz + 2 | ||
308 | if (fe->ops.i2c_gate_ctrl) | ||
309 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
310 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
311 | |||
312 | buf[0] = 0x60; | ||
313 | buf[1] = 0x3c; | ||
314 | if (fe->ops.i2c_gate_ctrl) | ||
315 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
316 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
317 | |||
318 | /* correct CP value */ | ||
319 | buf[0] = 0x30; | ||
320 | buf[1] = 0x10 + tda827xa_dvbt[i].scr; | ||
321 | if (fe->ops.i2c_gate_ctrl) | ||
322 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
323 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
324 | |||
325 | msleep(163); | ||
326 | buf[0] = 0xc0; | ||
327 | buf[1] = 0x39; // lpsel, for 6MHz + 2 | ||
328 | if (fe->ops.i2c_gate_ctrl) | ||
329 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
330 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
331 | |||
332 | msleep(3); | ||
333 | /* freeze AGC1 */ | ||
334 | buf[0] = 0x50; | ||
335 | buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); | ||
336 | if (fe->ops.i2c_gate_ctrl) | ||
337 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
338 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
339 | |||
340 | priv->frequency = tuner_freq - if_freq; // FIXME | ||
341 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static int tda827xa_sleep(struct dvb_frontend *fe) | ||
347 | { | ||
348 | struct tda827x_priv *priv = fe->tuner_priv; | ||
349 | static u8 buf[] = { 0x30, 0x90 }; | ||
350 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
351 | .buf = buf, .len = sizeof(buf) }; | ||
352 | |||
353 | if (fe->ops.i2c_gate_ctrl) | ||
354 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
355 | |||
356 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
357 | |||
358 | if (fe->ops.i2c_gate_ctrl) | ||
359 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
360 | |||
361 | if (priv->cfg && priv->cfg->sleep) | ||
362 | priv->cfg->sleep(fe); | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int tda827x_release(struct dvb_frontend *fe) | ||
368 | { | ||
369 | kfree(fe->tuner_priv); | ||
370 | fe->tuner_priv = NULL; | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
375 | { | ||
376 | struct tda827x_priv *priv = fe->tuner_priv; | ||
377 | *frequency = priv->frequency; | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | ||
382 | { | ||
383 | struct tda827x_priv *priv = fe->tuner_priv; | ||
384 | *bandwidth = priv->bandwidth; | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int tda827x_init(struct dvb_frontend *fe) | ||
389 | { | ||
390 | struct tda827x_priv *priv = fe->tuner_priv; | ||
391 | |||
392 | if (priv->cfg && priv->cfg->init) | ||
393 | priv->cfg->init(fe); | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | |||
399 | static struct dvb_tuner_ops tda827xo_tuner_ops = { | ||
400 | .info = { | ||
401 | .name = "Philips TDA827X", | ||
402 | }, | ||
403 | .release = tda827x_release, | ||
404 | .init = tda827x_init, | ||
405 | .sleep = tda827xo_sleep, | ||
406 | .set_params = tda827xo_set_params, | ||
407 | .get_frequency = tda827x_get_frequency, | ||
408 | .get_bandwidth = tda827x_get_bandwidth, | ||
409 | }; | ||
410 | |||
411 | static struct dvb_tuner_ops tda827xa_tuner_ops = { | ||
412 | .info = { | ||
413 | .name = "Philips TDA827XA", | ||
414 | }, | ||
415 | .release = tda827x_release, | ||
416 | .init = tda827x_init, | ||
417 | .sleep = tda827xa_sleep, | ||
418 | .set_params = tda827xa_set_params, | ||
419 | .get_frequency = tda827x_get_frequency, | ||
420 | .get_bandwidth = tda827x_get_bandwidth, | ||
421 | }; | ||
422 | |||
423 | struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr, | ||
424 | struct i2c_adapter *i2c, | ||
425 | struct tda827x_config *cfg) | ||
426 | { | ||
427 | struct tda827x_priv *priv = NULL; | ||
428 | u8 data; | ||
429 | struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, | ||
430 | .buf = &data, .len = 1 }; | ||
431 | dprintk("%s:\n", __FUNCTION__); | ||
432 | |||
433 | if (fe->ops.i2c_gate_ctrl) | ||
434 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
435 | |||
436 | if (i2c_transfer(i2c, &msg, 1) != 1) { | ||
437 | printk("%s: could not read from tuner at addr: 0x%02x\n", | ||
438 | __FUNCTION__, addr << 1); | ||
439 | return NULL; | ||
440 | } | ||
441 | |||
442 | priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL); | ||
443 | if (priv == NULL) | ||
444 | return NULL; | ||
445 | |||
446 | priv->i2c_addr = addr; | ||
447 | priv->i2c_adap = i2c; | ||
448 | priv->cfg = cfg; | ||
449 | if ((data & 0x3c) == 0) { | ||
450 | dprintk("tda827x tuner found\n"); | ||
451 | memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
452 | } else { | ||
453 | dprintk("tda827xa tuner found\n"); | ||
454 | memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
455 | } | ||
456 | fe->tuner_priv = priv; | ||
457 | |||
458 | return fe; | ||
459 | } | ||
460 | EXPORT_SYMBOL(tda827x_attach); | ||
461 | |||
462 | module_param(debug, int, 0644); | ||
463 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
464 | |||
465 | MODULE_DESCRIPTION("DVB TDA827x driver"); | ||
466 | MODULE_AUTHOR("Hartmut Hackmann"); | ||
467 | MODULE_AUTHOR("Michael Krufky"); | ||
468 | MODULE_LICENSE("GPL"); | ||
469 | |||
470 | /* | ||
471 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
472 | * --------------------------------------------------------------------------- | ||
473 | * Local variables: | ||
474 | * c-basic-offset: 8 | ||
475 | * End: | ||
476 | */ | ||
diff --git a/drivers/media/dvb/frontends/tda827x.h b/drivers/media/dvb/frontends/tda827x.h new file mode 100644 index 000000000000..69e8263d6d59 --- /dev/null +++ b/drivers/media/dvb/frontends/tda827x.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | DVB Driver for Philips tda827x / tda827xa Silicon tuners | ||
3 | |||
4 | (c) 2005 Hartmut Hackmann | ||
5 | (c) 2007 Michael Krufky | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | |||
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 | |||
24 | #ifndef __DVB_TDA827X_H__ | ||
25 | #define __DVB_TDA827X_H__ | ||
26 | |||
27 | #include <linux/i2c.h> | ||
28 | #include "dvb_frontend.h" | ||
29 | |||
30 | struct tda827x_config | ||
31 | { | ||
32 | void (*lna_gain) (struct dvb_frontend *fe, int high); | ||
33 | int (*init) (struct dvb_frontend *fe); | ||
34 | int (*sleep) (struct dvb_frontend *fe); | ||
35 | }; | ||
36 | |||
37 | |||
38 | /** | ||
39 | * Attach a tda827x tuner to the supplied frontend structure. | ||
40 | * | ||
41 | * @param fe Frontend to attach to. | ||
42 | * @param addr i2c address of the tuner. | ||
43 | * @param i2c i2c adapter to use. | ||
44 | * @param cfg optional callback function pointers. | ||
45 | * @return FE pointer on success, NULL on failure. | ||
46 | */ | ||
47 | #if defined(CONFIG_DVB_TDA827X) || (defined(CONFIG_DVB_TDA827X_MODULE) && defined(MODULE)) | ||
48 | extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr, | ||
49 | struct i2c_adapter *i2c, | ||
50 | struct tda827x_config *cfg); | ||
51 | #else | ||
52 | static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, | ||
53 | int addr, | ||
54 | struct i2c_adapter *i2c, | ||
55 | struct tda827x_config *cfg) | ||
56 | { | ||
57 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
58 | return NULL; | ||
59 | } | ||
60 | #endif // CONFIG_DVB_TDA827X | ||
61 | |||
62 | #endif // __DVB_TDA827X_H__ | ||
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 59da79ce2efd..309dca368f4a 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -46,6 +46,7 @@ config VIDEO_SAA7134_DVB | |||
46 | select DVB_NXT200X if !DVB_FE_CUSTOMISE | 46 | select DVB_NXT200X if !DVB_FE_CUSTOMISE |
47 | select DVB_TDA10086 if !DVB_FE_CUSTOMISE | 47 | select DVB_TDA10086 if !DVB_FE_CUSTOMISE |
48 | select DVB_TDA826X if !DVB_FE_CUSTOMISE | 48 | select DVB_TDA826X if !DVB_FE_CUSTOMISE |
49 | select DVB_TDA827X if !DVB_FE_CUSTOMISE | ||
49 | select DVB_ISL6421 if !DVB_FE_CUSTOMISE | 50 | select DVB_ISL6421 if !DVB_FE_CUSTOMISE |
50 | ---help--- | 51 | ---help--- |
51 | This adds support for DVB cards based on the | 52 | This adds support for DVB cards based on the |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 3f972ad3e443..f44e7c7e18a5 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -1785,7 +1785,7 @@ struct saa7134_board saa7134_boards[] = { | |||
1785 | .tuner_addr = ADDR_UNSET, | 1785 | .tuner_addr = ADDR_UNSET, |
1786 | .radio_addr = ADDR_UNSET, | 1786 | .radio_addr = ADDR_UNSET, |
1787 | .gpiomask = 0x00200000, | 1787 | .gpiomask = 0x00200000, |
1788 | .mpeg = SAA7134_MPEG_DVB, | 1788 | .mpeg = SAA7134_MPEG_DVB, |
1789 | .inputs = {{ | 1789 | .inputs = {{ |
1790 | .name = name_tv, | 1790 | .name = name_tv, |
1791 | .vmux = 1, | 1791 | .vmux = 1, |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 61a68c67c4ad..7985d9e860e9 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -41,7 +41,9 @@ | |||
41 | 41 | ||
42 | #include "tda10086.h" | 42 | #include "tda10086.h" |
43 | #include "tda826x.h" | 43 | #include "tda826x.h" |
44 | #include "tda827x.h" | ||
44 | #include "isl6421.h" | 45 | #include "isl6421.h" |
46 | |||
45 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 47 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
46 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
47 | 49 | ||
@@ -654,337 +656,11 @@ static int tda8290_i2c_gate_ctrl( struct dvb_frontend* fe, int enable) | |||
654 | 656 | ||
655 | /* ------------------------------------------------------------------ */ | 657 | /* ------------------------------------------------------------------ */ |
656 | 658 | ||
657 | struct tda827x_data { | ||
658 | u32 lomax; | ||
659 | u8 spd; | ||
660 | u8 bs; | ||
661 | u8 bp; | ||
662 | u8 cp; | ||
663 | u8 gc3; | ||
664 | u8 div1p5; | ||
665 | }; | ||
666 | |||
667 | static struct tda827x_data tda827x_dvbt[] = { | ||
668 | { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | ||
669 | { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | ||
670 | { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | ||
671 | { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | ||
672 | { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
673 | { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
674 | { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
675 | { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
676 | { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
677 | { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
678 | { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
679 | { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
680 | { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
681 | { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
682 | { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
683 | { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
684 | { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
685 | { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
686 | { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
687 | { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
688 | { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
689 | { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
690 | { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
691 | { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
692 | { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
693 | { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | ||
694 | { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
695 | { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | ||
696 | { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} | ||
697 | }; | ||
698 | |||
699 | static int philips_tda827xo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
700 | { | ||
701 | struct saa7134_dev *dev = fe->dvb->priv; | ||
702 | struct tda1004x_state *state = fe->demodulator_priv; | ||
703 | u8 addr = state->config->tuner_address; | ||
704 | u8 tuner_buf[14]; | ||
705 | |||
706 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf, | ||
707 | .len = sizeof(tuner_buf) }; | ||
708 | int i, tuner_freq, if_freq; | ||
709 | u32 N; | ||
710 | switch (params->u.ofdm.bandwidth) { | ||
711 | case BANDWIDTH_6_MHZ: | ||
712 | if_freq = 4000000; | ||
713 | break; | ||
714 | case BANDWIDTH_7_MHZ: | ||
715 | if_freq = 4500000; | ||
716 | break; | ||
717 | default: /* 8 MHz or Auto */ | ||
718 | if_freq = 5000000; | ||
719 | break; | ||
720 | } | ||
721 | tuner_freq = params->frequency + if_freq; | ||
722 | |||
723 | i = 0; | ||
724 | while (tda827x_dvbt[i].lomax < tuner_freq) { | ||
725 | if(tda827x_dvbt[i + 1].lomax == 0) | ||
726 | break; | ||
727 | i++; | ||
728 | } | ||
729 | |||
730 | N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2); | ||
731 | tuner_buf[0] = 0; | ||
732 | tuner_buf[1] = (N>>8) | 0x40; | ||
733 | tuner_buf[2] = N & 0xff; | ||
734 | tuner_buf[3] = 0; | ||
735 | tuner_buf[4] = 0x52; | ||
736 | tuner_buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) + | ||
737 | (tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp; | ||
738 | tuner_buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f; | ||
739 | tuner_buf[7] = 0xbf; | ||
740 | tuner_buf[8] = 0x2a; | ||
741 | tuner_buf[9] = 0x05; | ||
742 | tuner_buf[10] = 0xff; | ||
743 | tuner_buf[11] = 0x00; | ||
744 | tuner_buf[12] = 0x00; | ||
745 | tuner_buf[13] = 0x40; | ||
746 | |||
747 | tuner_msg.len = 14; | ||
748 | if (fe->ops.i2c_gate_ctrl) | ||
749 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
750 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) { | ||
751 | printk("%s/dvb: could not write to tuner at addr: 0x%02x\n",dev->name, addr << 1); | ||
752 | return -EIO; | ||
753 | } | ||
754 | msleep(500); | ||
755 | /* correct CP value */ | ||
756 | tuner_buf[0] = 0x30; | ||
757 | tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp; | ||
758 | tuner_msg.len = 2; | ||
759 | if (fe->ops.i2c_gate_ctrl) | ||
760 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
761 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | ||
762 | |||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | static int philips_tda827xo_tuner_sleep(struct dvb_frontend *fe) | ||
767 | { | ||
768 | struct saa7134_dev *dev = fe->dvb->priv; | ||
769 | struct tda1004x_state *state = fe->demodulator_priv; | ||
770 | u8 addr = state->config->tuner_address; | ||
771 | static u8 tda827x_sleep[] = { 0x30, 0xd0}; | ||
772 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827x_sleep, | ||
773 | .len = sizeof(tda827x_sleep) }; | ||
774 | if (fe->ops.i2c_gate_ctrl) | ||
775 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
776 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | ||
777 | return 0; | ||
778 | } | ||
779 | |||
780 | /* ------------------------------------------------------------------ */ | ||
781 | |||
782 | struct tda827xa_data { | ||
783 | u32 lomax; | ||
784 | u8 svco; | ||
785 | u8 spd; | ||
786 | u8 scr; | ||
787 | u8 sbs; | ||
788 | u8 gc3; | ||
789 | }; | ||
790 | |||
791 | static struct tda827xa_data tda827xa_dvbt[] = { | ||
792 | { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
793 | { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
794 | { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
795 | { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
796 | { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
797 | { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
798 | { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
799 | { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
800 | { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
801 | { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
802 | { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
803 | { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
804 | { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
805 | { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
806 | { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
807 | { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
808 | { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
809 | { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, | ||
810 | { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
811 | { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
812 | { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
813 | { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
814 | { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
815 | { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
816 | { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
817 | { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, | ||
818 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}}; | ||
819 | |||
820 | static int philips_tda827xa_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
821 | { | ||
822 | struct saa7134_dev *dev = fe->dvb->priv; | ||
823 | struct tda1004x_state *state = fe->demodulator_priv; | ||
824 | u8 addr = state->config->tuner_address; | ||
825 | u8 tuner_buf[10]; | ||
826 | |||
827 | struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = tuner_buf}; | ||
828 | int i, tuner_freq, if_freq; | ||
829 | u32 N; | ||
830 | |||
831 | philips_tda827x_lna_gain( fe, 1); | ||
832 | msleep(20); | ||
833 | |||
834 | switch (params->u.ofdm.bandwidth) { | ||
835 | case BANDWIDTH_6_MHZ: | ||
836 | if_freq = 4000000; | ||
837 | break; | ||
838 | case BANDWIDTH_7_MHZ: | ||
839 | if_freq = 4500000; | ||
840 | break; | ||
841 | default: /* 8 MHz or Auto */ | ||
842 | if_freq = 5000000; | ||
843 | break; | ||
844 | } | ||
845 | tuner_freq = params->frequency + if_freq; | ||
846 | |||
847 | i = 0; | ||
848 | while (tda827xa_dvbt[i].lomax < tuner_freq) { | ||
849 | if(tda827xa_dvbt[i + 1].lomax == 0) | ||
850 | break; | ||
851 | i++; | ||
852 | } | ||
853 | |||
854 | N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd; | ||
855 | tuner_buf[0] = 0; // subaddress | ||
856 | tuner_buf[1] = N >> 8; | ||
857 | tuner_buf[2] = N & 0xff; | ||
858 | tuner_buf[3] = 0; | ||
859 | tuner_buf[4] = 0x16; | ||
860 | tuner_buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) + | ||
861 | tda827xa_dvbt[i].sbs; | ||
862 | tuner_buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4); | ||
863 | tuner_buf[7] = 0x1c; | ||
864 | tuner_buf[8] = 0x06; | ||
865 | tuner_buf[9] = 0x24; | ||
866 | tuner_buf[10] = 0x00; | ||
867 | msg.len = 11; | ||
868 | if (fe->ops.i2c_gate_ctrl) | ||
869 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
870 | if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { | ||
871 | printk("%s/dvb: could not write to tuner at addr: 0x%02x\n",dev->name, addr << 1); | ||
872 | return -EIO; | ||
873 | } | ||
874 | tuner_buf[0] = 0x90; | ||
875 | tuner_buf[1] = 0xff; | ||
876 | tuner_buf[2] = 0x60; | ||
877 | tuner_buf[3] = 0x00; | ||
878 | tuner_buf[4] = 0x59; // lpsel, for 6MHz + 2 | ||
879 | msg.len = 5; | ||
880 | if (fe->ops.i2c_gate_ctrl) | ||
881 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
882 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
883 | |||
884 | tuner_buf[0] = 0xa0; | ||
885 | tuner_buf[1] = 0x40; | ||
886 | msg.len = 2; | ||
887 | if (fe->ops.i2c_gate_ctrl) | ||
888 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
889 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
890 | |||
891 | msleep(11); | ||
892 | msg.flags = I2C_M_RD; | ||
893 | if (fe->ops.i2c_gate_ctrl) | ||
894 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
895 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
896 | msg.flags = 0; | ||
897 | |||
898 | tuner_buf[1] >>= 4; | ||
899 | dprintk("tda8275a AGC2 gain is: %d\n", tuner_buf[1]); | ||
900 | if ((tuner_buf[1]) < 2) { | ||
901 | philips_tda827x_lna_gain(fe, 0); | ||
902 | tuner_buf[0] = 0x60; | ||
903 | tuner_buf[1] = 0x0c; | ||
904 | if (fe->ops.i2c_gate_ctrl) | ||
905 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
906 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
907 | } | ||
908 | |||
909 | tuner_buf[0] = 0xc0; | ||
910 | tuner_buf[1] = 0x99; // lpsel, for 6MHz + 2 | ||
911 | if (fe->ops.i2c_gate_ctrl) | ||
912 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
913 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
914 | |||
915 | tuner_buf[0] = 0x60; | ||
916 | tuner_buf[1] = 0x3c; | ||
917 | if (fe->ops.i2c_gate_ctrl) | ||
918 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
919 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
920 | |||
921 | /* correct CP value */ | ||
922 | tuner_buf[0] = 0x30; | ||
923 | tuner_buf[1] = 0x10 + tda827xa_dvbt[i].scr; | ||
924 | if (fe->ops.i2c_gate_ctrl) | ||
925 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
926 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
927 | |||
928 | msleep(163); | ||
929 | tuner_buf[0] = 0xc0; | ||
930 | tuner_buf[1] = 0x39; // lpsel, for 6MHz + 2 | ||
931 | if (fe->ops.i2c_gate_ctrl) | ||
932 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
933 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
934 | |||
935 | msleep(3); | ||
936 | /* freeze AGC1 */ | ||
937 | tuner_buf[0] = 0x50; | ||
938 | tuner_buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); | ||
939 | if (fe->ops.i2c_gate_ctrl) | ||
940 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
941 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
942 | |||
943 | return 0; | ||
944 | |||
945 | } | ||
946 | |||
947 | static int philips_tda827xa_tuner_sleep(struct dvb_frontend *fe) | ||
948 | { | ||
949 | struct saa7134_dev *dev = fe->dvb->priv; | ||
950 | struct tda1004x_state *state = fe->demodulator_priv; | ||
951 | u8 addr = state->config->tuner_address; | ||
952 | static u8 tda827xa_sleep[] = { 0x30, 0x90}; | ||
953 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep, | ||
954 | .len = sizeof(tda827xa_sleep) }; | ||
955 | if (fe->ops.i2c_gate_ctrl) | ||
956 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
957 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | ||
958 | if (fe->ops.i2c_gate_ctrl) | ||
959 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
960 | return 0; | ||
961 | } | ||
962 | |||
963 | /* ------------------------------------------------------------------ | ||
964 | * upper layer: distinguish the silicon tuner versions | ||
965 | */ | ||
966 | |||
967 | static int philips_tda827x_tuner_init(struct dvb_frontend *fe) | 659 | static int philips_tda827x_tuner_init(struct dvb_frontend *fe) |
968 | { | 660 | { |
969 | struct saa7134_dev *dev = fe->dvb->priv; | 661 | struct saa7134_dev *dev = fe->dvb->priv; |
970 | struct tda1004x_state *state = fe->demodulator_priv; | 662 | struct tda1004x_state *state = fe->demodulator_priv; |
971 | u8 addr = state->config->tuner_address; | 663 | |
972 | u8 data; | ||
973 | struct i2c_msg tuner_msg = {.addr = addr,.flags = I2C_M_RD,.buf = &data, .len = 1}; | ||
974 | state->conf_probed = 0; | ||
975 | if (fe->ops.i2c_gate_ctrl) | ||
976 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
977 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) { | ||
978 | printk("%s/dvb: could not read from tuner at addr: 0x%02x\n",dev->name, addr << 1); | ||
979 | return -EIO; | ||
980 | } | ||
981 | if ((data & 0x3c) == 0) { | ||
982 | dprintk("tda827x tuner found\n"); | ||
983 | state->conf_probed = 1; | ||
984 | } else { | ||
985 | dprintk("tda827xa tuner found\n"); | ||
986 | state->conf_probed = 2; | ||
987 | } | ||
988 | switch (state->config->antenna_switch) { | 664 | switch (state->config->antenna_switch) { |
989 | case 0: break; | 665 | case 0: break; |
990 | case 1: dprintk("setting GPIO21 to 0 (TV antenna?)\n"); | 666 | case 1: dprintk("setting GPIO21 to 0 (TV antenna?)\n"); |
@@ -1001,14 +677,7 @@ static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe) | |||
1001 | { | 677 | { |
1002 | struct saa7134_dev *dev = fe->dvb->priv; | 678 | struct saa7134_dev *dev = fe->dvb->priv; |
1003 | struct tda1004x_state *state = fe->demodulator_priv; | 679 | struct tda1004x_state *state = fe->demodulator_priv; |
1004 | switch (state->conf_probed) { | 680 | |
1005 | case 1: philips_tda827xo_tuner_sleep(fe); | ||
1006 | break; | ||
1007 | case 2: philips_tda827xa_tuner_sleep(fe); | ||
1008 | break; | ||
1009 | default: dprintk("Huh? unknown tda827x version!\n"); | ||
1010 | return -EIO; | ||
1011 | } | ||
1012 | switch (state->config->antenna_switch) { | 681 | switch (state->config->antenna_switch) { |
1013 | case 0: break; | 682 | case 0: break; |
1014 | case 1: dprintk("setting GPIO21 to 1 (Radio antenna?)\n"); | 683 | case 1: dprintk("setting GPIO21 to 1 (Radio antenna?)\n"); |
@@ -1021,20 +690,11 @@ static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe) | |||
1021 | return 0; | 690 | return 0; |
1022 | } | 691 | } |
1023 | 692 | ||
1024 | static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 693 | static struct tda827x_config tda827x_cfg = { |
1025 | { | 694 | .lna_gain = philips_tda827x_lna_gain, |
1026 | struct saa7134_dev *dev = fe->dvb->priv; | 695 | .init = philips_tda827x_tuner_init, |
1027 | struct tda1004x_state *state = fe->demodulator_priv; | 696 | .sleep = philips_tda827x_tuner_sleep |
1028 | switch (state->conf_probed) { | 697 | }; |
1029 | case 1: philips_tda827xo_pll_set(fe, params); | ||
1030 | break; | ||
1031 | case 2: philips_tda827xa_pll_set(fe, params); | ||
1032 | break; | ||
1033 | default: dprintk("Huh? unknown tda827x version!\n"); | ||
1034 | return -EIO; | ||
1035 | } | ||
1036 | return 0; | ||
1037 | } | ||
1038 | 698 | ||
1039 | static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *tda_conf, | 699 | static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *tda_conf, |
1040 | char *board_name) | 700 | char *board_name) |
@@ -1043,9 +703,8 @@ static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config | |||
1043 | if (dev->dvb.frontend) { | 703 | if (dev->dvb.frontend) { |
1044 | if (tda_conf->i2c_gate) | 704 | if (tda_conf->i2c_gate) |
1045 | dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; | 705 | dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; |
1046 | dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init; | 706 | dvb_attach(tda827x_attach,dev->dvb.frontend, |
1047 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep; | 707 | tda_conf->tuner_address,&dev->i2c_adap,&tda827x_cfg); |
1048 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_pll_set; | ||
1049 | } | 708 | } |
1050 | philips_tda1004x_set_board_name(dev->dvb.frontend, board_name); | 709 | philips_tda1004x_set_board_name(dev->dvb.frontend, board_name); |
1051 | } | 710 | } |
@@ -1223,6 +882,12 @@ static int ads_duo_tuner_sleep(struct dvb_frontend *fe) | |||
1223 | return 0; | 882 | return 0; |
1224 | } | 883 | } |
1225 | 884 | ||
885 | static struct tda827x_config ads_duo_cfg = { | ||
886 | .lna_gain = philips_tda827x_lna_gain, | ||
887 | .init = ads_duo_tuner_init, | ||
888 | .sleep = ads_duo_tuner_sleep | ||
889 | }; | ||
890 | |||
1226 | static struct tda1004x_config ads_tech_duo_config = { | 891 | static struct tda1004x_config ads_tech_duo_config = { |
1227 | .demod_address = 0x08, | 892 | .demod_address = 0x08, |
1228 | .invert = 1, | 893 | .invert = 1, |
@@ -1393,9 +1058,9 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1393 | &ads_tech_duo_config, | 1058 | &ads_tech_duo_config, |
1394 | &dev->i2c_adap); | 1059 | &dev->i2c_adap); |
1395 | if (dev->dvb.frontend) { | 1060 | if (dev->dvb.frontend) { |
1396 | dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init; | 1061 | dvb_attach(tda827x_attach,dev->dvb.frontend, |
1397 | dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep; | 1062 | ads_tech_duo_config.tuner_address, |
1398 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_pll_set; | 1063 | &dev->i2c_adap,&ads_duo_cfg); |
1399 | if (dev->board == SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331) | 1064 | if (dev->board == SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331) |
1400 | board_name = "DVB-T ADS DUO Cardbus PTV331"; | 1065 | board_name = "DVB-T ADS DUO Cardbus PTV331"; |
1401 | else | 1066 | else |