blob: c6ae5bfae5b114d6ff9dd5374613fc826af69399 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001 /*
2 Driver for Philips tda1004xh OFDM Demodulator
3
4 (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach
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
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22/*
23 * This driver needs external firmware. Please use the commands
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
25 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
26 * download/extract them, and then copy them to /usr/lib/hotplug/firmware.
27 */
28#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw"
29#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw"
30
31#include <linux/init.h>
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/device.h>
Tim Schmielau4e57b682005-10-30 15:03:48 -080035#include <linux/jiffies.h>
36#include <linux/string.h>
37#include <linux/slab.h>
38
Linus Torvalds1da177e2005-04-16 15:20:36 -070039#include "dvb_frontend.h"
40#include "tda1004x.h"
41
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -070042enum tda1004x_demod {
43 TDA1004X_DEMOD_TDA10045,
44 TDA1004X_DEMOD_TDA10046,
45};
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
47struct tda1004x_state {
48 struct i2c_adapter* i2c;
49 struct dvb_frontend_ops ops;
50 const struct tda1004x_config* config;
51 struct dvb_frontend frontend;
52
53 /* private demod data */
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -070054 u8 initialised;
55 enum tda1004x_demod demod_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -070056};
57
Linus Torvalds1da177e2005-04-16 15:20:36 -070058static int debug;
59#define dprintk(args...) \
60 do { \
61 if (debug) printk(KERN_DEBUG "tda1004x: " args); \
62 } while (0)
63
64#define TDA1004X_CHIPID 0x00
65#define TDA1004X_AUTO 0x01
66#define TDA1004X_IN_CONF1 0x02
67#define TDA1004X_IN_CONF2 0x03
68#define TDA1004X_OUT_CONF1 0x04
69#define TDA1004X_OUT_CONF2 0x05
70#define TDA1004X_STATUS_CD 0x06
71#define TDA1004X_CONFC4 0x07
72#define TDA1004X_DSSPARE2 0x0C
73#define TDA10045H_CODE_IN 0x0D
74#define TDA10045H_FWPAGE 0x0E
75#define TDA1004X_SCAN_CPT 0x10
76#define TDA1004X_DSP_CMD 0x11
77#define TDA1004X_DSP_ARG 0x12
78#define TDA1004X_DSP_DATA1 0x13
79#define TDA1004X_DSP_DATA2 0x14
80#define TDA1004X_CONFADC1 0x15
81#define TDA1004X_CONFC1 0x16
82#define TDA10045H_S_AGC 0x1a
83#define TDA10046H_AGC_TUN_LEVEL 0x1a
84#define TDA1004X_SNR 0x1c
85#define TDA1004X_CONF_TS1 0x1e
86#define TDA1004X_CONF_TS2 0x1f
87#define TDA1004X_CBER_RESET 0x20
88#define TDA1004X_CBER_MSB 0x21
89#define TDA1004X_CBER_LSB 0x22
90#define TDA1004X_CVBER_LUT 0x23
91#define TDA1004X_VBER_MSB 0x24
92#define TDA1004X_VBER_MID 0x25
93#define TDA1004X_VBER_LSB 0x26
94#define TDA1004X_UNCOR 0x27
95
96#define TDA10045H_CONFPLL_P 0x2D
97#define TDA10045H_CONFPLL_M_MSB 0x2E
98#define TDA10045H_CONFPLL_M_LSB 0x2F
99#define TDA10045H_CONFPLL_N 0x30
100
101#define TDA10046H_CONFPLL1 0x2D
102#define TDA10046H_CONFPLL2 0x2F
103#define TDA10046H_CONFPLL3 0x30
104#define TDA10046H_TIME_WREF1 0x31
105#define TDA10046H_TIME_WREF2 0x32
106#define TDA10046H_TIME_WREF3 0x33
107#define TDA10046H_TIME_WREF4 0x34
108#define TDA10046H_TIME_WREF5 0x35
109
110#define TDA10045H_UNSURW_MSB 0x31
111#define TDA10045H_UNSURW_LSB 0x32
112#define TDA10045H_WREF_MSB 0x33
113#define TDA10045H_WREF_MID 0x34
114#define TDA10045H_WREF_LSB 0x35
115#define TDA10045H_MUXOUT 0x36
116#define TDA1004X_CONFADC2 0x37
117
118#define TDA10045H_IOFFSET 0x38
119
120#define TDA10046H_CONF_TRISTATE1 0x3B
121#define TDA10046H_CONF_TRISTATE2 0x3C
122#define TDA10046H_CONF_POLARITY 0x3D
123#define TDA10046H_FREQ_OFFSET 0x3E
124#define TDA10046H_GPIO_OUT_SEL 0x41
125#define TDA10046H_GPIO_SELECT 0x42
126#define TDA10046H_AGC_CONF 0x43
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700127#define TDA10046H_AGC_THR 0x44
128#define TDA10046H_AGC_RENORM 0x45
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129#define TDA10046H_AGC_GAINS 0x46
130#define TDA10046H_AGC_TUN_MIN 0x47
131#define TDA10046H_AGC_TUN_MAX 0x48
132#define TDA10046H_AGC_IF_MIN 0x49
133#define TDA10046H_AGC_IF_MAX 0x4A
134
135#define TDA10046H_FREQ_PHY2_MSB 0x4D
136#define TDA10046H_FREQ_PHY2_LSB 0x4E
137
138#define TDA10046H_CVBER_CTRL 0x4F
139#define TDA10046H_AGC_IF_LEVEL 0x52
140#define TDA10046H_CODE_CPT 0x57
141#define TDA10046H_CODE_IN 0x58
142
143
144static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data)
145{
146 int ret;
147 u8 buf[] = { reg, data };
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700148 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149
150 dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data);
151
152 msg.addr = state->config->demod_address;
153 ret = i2c_transfer(state->i2c, &msg, 1);
154
155 if (ret != 1)
156 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
157 __FUNCTION__, reg, data, ret);
158
159 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
160 reg, data, ret);
161 return (ret != 1) ? -1 : 0;
162}
163
164static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
165{
166 int ret;
167 u8 b0[] = { reg };
168 u8 b1[] = { 0 };
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700169 struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
170 { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171
172 dprintk("%s: reg=0x%x\n", __FUNCTION__, reg);
173
174 msg[0].addr = state->config->demod_address;
175 msg[1].addr = state->config->demod_address;
176 ret = i2c_transfer(state->i2c, msg, 2);
177
178 if (ret != 2) {
179 dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,
180 ret);
181 return -1;
182 }
183
184 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
185 reg, b1[0], ret);
186 return b1[0];
187}
188
189static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data)
190{
191 int val;
192 dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __FUNCTION__, reg,
193 mask, data);
194
195 // read a byte and check
196 val = tda1004x_read_byte(state, reg);
197 if (val < 0)
198 return val;
199
200 // mask if off
201 val = val & ~mask;
202 val |= data & 0xff;
203
204 // write it out again
205 return tda1004x_write_byteI(state, reg, val);
206}
207
208static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned char *buf, int len)
209{
210 int i;
211 int result;
212
213 dprintk("%s: reg=0x%x, len=0x%x\n", __FUNCTION__, reg, len);
214
215 result = 0;
216 for (i = 0; i < len; i++) {
217 result = tda1004x_write_byteI(state, reg + i, buf[i]);
218 if (result != 0)
219 break;
220 }
221
222 return result;
223}
224
225static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
226{
227 int result;
228 dprintk("%s\n", __FUNCTION__);
229
230 result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
231 msleep(1);
232 return result;
233}
234
235static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state)
236{
237 dprintk("%s\n", __FUNCTION__);
238
239 return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0);
240}
241
242static int tda10045h_set_bandwidth(struct tda1004x_state *state,
243 fe_bandwidth_t bandwidth)
244{
245 static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f };
246 static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb };
247 static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 };
248
249 switch (bandwidth) {
250 case BANDWIDTH_6_MHZ:
251 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
252 break;
253
254 case BANDWIDTH_7_MHZ:
255 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
256 break;
257
258 case BANDWIDTH_8_MHZ:
259 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
260 break;
261
262 default:
263 return -EINVAL;
264 }
265
266 tda1004x_write_byteI(state, TDA10045H_IOFFSET, 0);
267
268 return 0;
269}
270
271static int tda10046h_set_bandwidth(struct tda1004x_state *state,
272 fe_bandwidth_t bandwidth)
273{
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200274 static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 };
275 static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f };
276 static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200278 static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 };
279 static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab };
280 static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 };
281 int tda10046_clk53m;
282
283 if ((state->config->if_freq == TDA10046_FREQ_045) ||
284 (state->config->if_freq == TDA10046_FREQ_052))
285 tda10046_clk53m = 0;
286 else
287 tda10046_clk53m = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 switch (bandwidth) {
289 case BANDWIDTH_6_MHZ:
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200290 if (tda10046_clk53m)
291 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M,
292 sizeof(bandwidth_6mhz_53M));
293 else
294 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M,
295 sizeof(bandwidth_6mhz_48M));
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700296 if (state->config->if_freq == TDA10046_FREQ_045) {
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200297 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
298 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab);
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700299 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 break;
301
302 case BANDWIDTH_7_MHZ:
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200303 if (tda10046_clk53m)
304 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M,
305 sizeof(bandwidth_7mhz_53M));
306 else
307 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M,
308 sizeof(bandwidth_7mhz_48M));
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700309 if (state->config->if_freq == TDA10046_FREQ_045) {
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200310 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
311 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700312 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 break;
314
315 case BANDWIDTH_8_MHZ:
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200316 if (tda10046_clk53m)
317 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M,
318 sizeof(bandwidth_8mhz_53M));
319 else
320 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M,
321 sizeof(bandwidth_8mhz_48M));
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700322 if (state->config->if_freq == TDA10046_FREQ_045) {
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200323 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
324 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55);
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700325 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 break;
327
328 default:
329 return -EINVAL;
330 }
331
332 return 0;
333}
334
335static int tda1004x_do_upload(struct tda1004x_state *state,
336 unsigned char *mem, unsigned int len,
337 u8 dspCodeCounterReg, u8 dspCodeInReg)
338{
339 u8 buf[65];
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700340 struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 int tx_size;
342 int pos = 0;
343
344 /* clear code counter */
345 tda1004x_write_byteI(state, dspCodeCounterReg, 0);
346 fw_msg.addr = state->config->demod_address;
347
348 buf[0] = dspCodeInReg;
349 while (pos != len) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 // work out how much to send this time
351 tx_size = len - pos;
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700352 if (tx_size > 0x10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 tx_size = 0x10;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
355 // send the chunk
356 memcpy(buf + 1, mem + pos, tx_size);
357 fw_msg.len = tx_size + 1;
358 if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700359 printk(KERN_ERR "tda1004x: Error during firmware upload\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 return -EIO;
361 }
362 pos += tx_size;
363
364 dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
365 }
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700366 // give the DSP a chance to settle 03/10/05 Hac
367 msleep(100);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700368
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 return 0;
370}
371
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700372static int tda1004x_check_upload_ok(struct tda1004x_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373{
374 u8 data1, data2;
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700375 unsigned long timeout;
376
377 if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
378 timeout = jiffies + 2 * HZ;
379 while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
380 if (time_after(jiffies, timeout)) {
381 printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
382 break;
383 }
384 msleep(1);
385 }
386 } else
387 msleep(100);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
389 // check upload was OK
390 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
391 tda1004x_write_byteI(state, TDA1004X_DSP_CMD, 0x67);
392
393 data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
394 data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
Hartmut Hackmann3faadbb2005-07-07 17:57:42 -0700395 if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) {
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700396 printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 return -EIO;
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700398 }
399 printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 return 0;
401}
402
403static int tda10045_fwupload(struct dvb_frontend* fe)
404{
405 struct tda1004x_state* state = fe->demodulator_priv;
406 int ret;
407 const struct firmware *fw;
408
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 /* don't re-upload unless necessary */
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700410 if (tda1004x_check_upload_ok(state) == 0)
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700411 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
413 /* request the firmware, this will block until someone uploads it */
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700414 printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
416 if (ret) {
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700417 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 return ret;
419 }
420
421 /* reset chip */
422 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0);
423 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
424 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
425 msleep(10);
426
427 /* set parameters */
428 tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ);
429
430 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
Anssi Hannula0c744b02005-07-07 17:57:42 -0700431 release_firmware(fw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 if (ret)
433 return ret;
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700434 printk(KERN_INFO "tda1004x: firmware upload complete\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435
436 /* wait for DSP to initialise */
437 /* DSPREADY doesn't seem to work on the TDA10045H */
438 msleep(100);
439
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700440 return tda1004x_check_upload_ok(state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441}
442
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700443static void tda10046_init_plls(struct dvb_frontend* fe)
Johannes Stezenbach71e34202005-05-16 21:54:36 -0700444{
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700445 struct tda1004x_state* state = fe->demodulator_priv;
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200446 int tda10046_clk53m;
447
448 if ((state->config->if_freq == TDA10046_FREQ_045) ||
449 (state->config->if_freq == TDA10046_FREQ_052))
450 tda10046_clk53m = 0;
451 else
452 tda10046_clk53m = 1;
Johannes Stezenbach71e34202005-05-16 21:54:36 -0700453
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700454 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200455 if(tda10046_clk53m) {
456 printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n");
457 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8
458 } else {
459 printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n");
460 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3
461 }
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700462 if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
463 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
464 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
465 } else {
466 dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__);
467 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
Johannes Stezenbach71e34202005-05-16 21:54:36 -0700468 }
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200469 if(tda10046_clk53m)
470 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67);
471 else
472 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72);
473 /* Note clock frequency is handled implicitly */
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700474 switch (state->config->if_freq) {
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700475 case TDA10046_FREQ_045:
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200476 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
477 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700478 break;
479 case TDA10046_FREQ_052:
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200480 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
481 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7);
482 break;
483 case TDA10046_FREQ_3617:
484 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
485 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59);
486 break;
487 case TDA10046_FREQ_3613:
488 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
489 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f);
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700490 break;
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700491 }
492 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200493 /* let the PLLs settle */
494 msleep(120);
Johannes Stezenbach71e34202005-05-16 21:54:36 -0700495}
496
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497static int tda10046_fwupload(struct dvb_frontend* fe)
498{
499 struct tda1004x_state* state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 int ret;
501 const struct firmware *fw;
502
503 /* reset + wake up chip */
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700504 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700506 /* let the clocks recover from sleep */
507 msleep(5);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200509 /* The PLLs need to be reprogrammed after sleep */
510 tda10046_init_plls(fe);
511
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 /* don't re-upload unless necessary */
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700513 if (tda1004x_check_upload_ok(state) == 0)
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700514 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700516 if (state->config->request_firmware != NULL) {
517 /* request the firmware, this will block until someone uploads it */
518 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
519 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
520 if (ret) {
521 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800522 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 }
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700524 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
525 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
Anssi Hannula0c744b02005-07-07 17:57:42 -0700526 release_firmware(fw);
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700527 if (ret)
528 return ret;
529 } else {
530 /* boot from firmware eeprom */
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700531 printk(KERN_INFO "tda1004x: booting from eeprom\n");
532 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
533 msleep(300);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 }
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700535 return tda1004x_check_upload_ok(state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536}
537
538static int tda1004x_encode_fec(int fec)
539{
540 // convert known FEC values
541 switch (fec) {
542 case FEC_1_2:
543 return 0;
544 case FEC_2_3:
545 return 1;
546 case FEC_3_4:
547 return 2;
548 case FEC_5_6:
549 return 3;
550 case FEC_7_8:
551 return 4;
552 }
553
554 // unsupported
555 return -EINVAL;
556}
557
558static int tda1004x_decode_fec(int tdafec)
559{
560 // convert known FEC values
561 switch (tdafec) {
562 case 0:
563 return FEC_1_2;
564 case 1:
565 return FEC_2_3;
566 case 2:
567 return FEC_3_4;
568 case 3:
569 return FEC_5_6;
570 case 4:
571 return FEC_7_8;
572 }
573
574 // unsupported
575 return -1;
576}
577
578int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data)
579{
580 struct tda1004x_state* state = fe->demodulator_priv;
581
582 return tda1004x_write_byteI(state, reg, data);
583}
584
585static int tda10045_init(struct dvb_frontend* fe)
586{
587 struct tda1004x_state* state = fe->demodulator_priv;
588
589 dprintk("%s\n", __FUNCTION__);
590
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700591 if (state->initialised)
592 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593
594 if (tda10045_fwupload(fe)) {
595 printk("tda1004x: firmware upload failed\n");
596 return -EIO;
597 }
598
599 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC
600
601 // Init the PLL
602 if (state->config->pll_init) {
603 tda1004x_enable_tuner_i2c(state);
604 state->config->pll_init(fe);
605 tda1004x_disable_tuner_i2c(state);
606 }
607
608 // tda setup
609 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
610 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
611 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal
612 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer
613 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset
614 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset
615 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface
616 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface
617 tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits
618 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity
619 tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e);
620
621 tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
622
623 state->initialised = 1;
624 return 0;
625}
626
627static int tda10046_init(struct dvb_frontend* fe)
628{
629 struct tda1004x_state* state = fe->demodulator_priv;
630 dprintk("%s\n", __FUNCTION__);
631
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700632 if (state->initialised)
633 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
635 if (tda10046_fwupload(fe)) {
636 printk("tda1004x: firmware upload failed\n");
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700637 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 }
639
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700640 // Init the tuner PLL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 if (state->config->pll_init) {
642 tda1004x_enable_tuner_i2c(state);
Hartmut Hackmann634623d2005-11-08 21:35:13 -0800643 if (state->config->pll_init(fe)) {
644 printk(KERN_ERR "tda1004x: pll init failed\n");
645 return -EIO;
646 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647 tda1004x_disable_tuner_i2c(state);
648 }
649
650 // tda setup
651 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200652 tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream
653 tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700654
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700655 switch (state->config->agc_config) {
656 case TDA10046_AGC_DEFAULT:
657 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
658 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
659 break;
660 case TDA10046_AGC_IFO_AUTO_NEG:
661 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
662 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
663 break;
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700664 case TDA10046_AGC_IFO_AUTO_POS:
665 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
666 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities
667 break;
668 case TDA10046_AGC_TDA827X:
669 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
670 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200671 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
672 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -0700673 break;
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700674 }
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200675 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700676 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
678 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
679 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
680 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // }
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200681 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700682 tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700684 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
685 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
686
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 state->initialised = 1;
688 return 0;
689}
690
691static int tda1004x_set_fe(struct dvb_frontend* fe,
692 struct dvb_frontend_parameters *fe_params)
693{
694 struct tda1004x_state* state = fe->demodulator_priv;
695 int tmp;
696 int inversion;
697
698 dprintk("%s\n", __FUNCTION__);
699
700 if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
701 // setup auto offset
702 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10);
703 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0);
704 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0);
705
706 // disable agc_conf[2]
707 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0);
708 }
709
710 // set frequency
711 tda1004x_enable_tuner_i2c(state);
Hartmut Hackmann634623d2005-11-08 21:35:13 -0800712 if (state->config->pll_set(fe, fe_params)) {
713 printk(KERN_ERR "tda1004x: pll set failed\n");
714 return -EIO;
715 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 tda1004x_disable_tuner_i2c(state);
717
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 // Hardcoded to use auto as much as possible on the TDA10045 as it
719 // is very unreliable if AUTO mode is _not_ used.
720 if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
721 fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
722 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
723 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
724 }
725
726 // Set standard params.. or put them to auto
727 if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200728 (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||
729 (fe_params->u.ofdm.constellation == QAM_AUTO) ||
730 (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto
732 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits
733 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits
734 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits
735 } else {
736 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0); // disable auto
737
738 // set HP FEC
739 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700740 if (tmp < 0)
741 return tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp);
743
744 // set LP FEC
745 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700746 if (tmp < 0)
747 return tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3);
749
750 // set constellation
751 switch (fe_params->u.ofdm.constellation) {
752 case QPSK:
753 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0);
754 break;
755
756 case QAM_16:
757 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1);
758 break;
759
760 case QAM_64:
761 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2);
762 break;
763
764 default:
765 return -EINVAL;
766 }
767
768 // set hierarchy
769 switch (fe_params->u.ofdm.hierarchy_information) {
770 case HIERARCHY_NONE:
771 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5);
772 break;
773
774 case HIERARCHY_1:
775 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5);
776 break;
777
778 case HIERARCHY_2:
779 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5);
780 break;
781
782 case HIERARCHY_4:
783 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5);
784 break;
785
786 default:
787 return -EINVAL;
788 }
789 }
790
791 // set bandwidth
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700792 switch (state->demod_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 case TDA1004X_DEMOD_TDA10045:
794 tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
795 break;
796
797 case TDA1004X_DEMOD_TDA10046:
798 tda10046h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
799 break;
800 }
801
802 // set inversion
803 inversion = fe_params->inversion;
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700804 if (state->config->invert)
805 inversion = inversion ? INVERSION_OFF : INVERSION_ON;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 switch (inversion) {
807 case INVERSION_OFF:
808 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0);
809 break;
810
811 case INVERSION_ON:
812 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20);
813 break;
814
815 default:
816 return -EINVAL;
817 }
818
819 // set guard interval
820 switch (fe_params->u.ofdm.guard_interval) {
821 case GUARD_INTERVAL_1_32:
822 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
823 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
824 break;
825
826 case GUARD_INTERVAL_1_16:
827 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
828 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);
829 break;
830
831 case GUARD_INTERVAL_1_8:
832 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
833 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);
834 break;
835
836 case GUARD_INTERVAL_1_4:
837 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
838 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);
839 break;
840
841 case GUARD_INTERVAL_AUTO:
842 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2);
843 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
844 break;
845
846 default:
847 return -EINVAL;
848 }
849
850 // set transmission mode
851 switch (fe_params->u.ofdm.transmission_mode) {
852 case TRANSMISSION_MODE_2K:
853 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
854 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4);
855 break;
856
857 case TRANSMISSION_MODE_8K:
858 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
859 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4);
860 break;
861
862 case TRANSMISSION_MODE_AUTO:
863 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4);
864 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0);
865 break;
866
867 default:
868 return -EINVAL;
869 }
870
871 // start the lock
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700872 switch (state->demod_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 case TDA1004X_DEMOD_TDA10045:
874 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
875 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 break;
877
878 case TDA1004X_DEMOD_TDA10046:
879 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
Hartmut Hackmann634623d2005-11-08 21:35:13 -0800880 msleep(1);
881 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 break;
883 }
884
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700885 msleep(10);
886
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 return 0;
888}
889
890static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
891{
892 struct tda1004x_state* state = fe->demodulator_priv;
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200893
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 dprintk("%s\n", __FUNCTION__);
895
896 // inversion status
897 fe_params->inversion = INVERSION_OFF;
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700898 if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 fe_params->inversion = INVERSION_ON;
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700900 if (state->config->invert)
901 fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902
903 // bandwidth
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700904 switch (state->demod_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 case TDA1004X_DEMOD_TDA10045:
906 switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) {
907 case 0x14:
908 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
909 break;
910 case 0xdb:
911 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
912 break;
913 case 0x4f:
914 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
915 break;
916 }
917 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 case TDA1004X_DEMOD_TDA10046:
919 switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200920 case 0x5c:
921 case 0x54:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
923 break;
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200924 case 0x6a:
925 case 0x60:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
927 break;
Hartmut Hackmann8a8e9c22006-01-09 15:25:04 -0200928 case 0x7b:
929 case 0x70:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
931 break;
932 }
933 break;
934 }
935
936 // FEC
937 fe_params->u.ofdm.code_rate_HP =
938 tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7);
939 fe_params->u.ofdm.code_rate_LP =
940 tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7);
941
942 // constellation
943 switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) {
944 case 0:
945 fe_params->u.ofdm.constellation = QPSK;
946 break;
947 case 1:
948 fe_params->u.ofdm.constellation = QAM_16;
949 break;
950 case 2:
951 fe_params->u.ofdm.constellation = QAM_64;
952 break;
953 }
954
955 // transmission mode
956 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -0700957 if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
960 // guard interval
961 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {
962 case 0:
963 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
964 break;
965 case 1:
966 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
967 break;
968 case 2:
969 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
970 break;
971 case 3:
972 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
973 break;
974 }
975
976 // hierarchy
977 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) {
978 case 0:
979 fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
980 break;
981 case 1:
982 fe_params->u.ofdm.hierarchy_information = HIERARCHY_1;
983 break;
984 case 2:
985 fe_params->u.ofdm.hierarchy_information = HIERARCHY_2;
986 break;
987 case 3:
988 fe_params->u.ofdm.hierarchy_information = HIERARCHY_4;
989 break;
990 }
991
992 return 0;
993}
994
995static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status)
996{
997 struct tda1004x_state* state = fe->demodulator_priv;
998 int status;
999 int cber;
1000 int vber;
1001
1002 dprintk("%s\n", __FUNCTION__);
1003
1004 // read status
1005 status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001006 if (status == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
1009 // decode
1010 *fe_status = 0;
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001011 if (status & 4)
1012 *fe_status |= FE_HAS_SIGNAL;
1013 if (status & 2)
1014 *fe_status |= FE_HAS_CARRIER;
1015 if (status & 8)
1016 *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
1018 // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi
1019 // is getting anything valid
1020 if (!(*fe_status & FE_HAS_VITERBI)) {
1021 // read the CBER
1022 cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001023 if (cber == -1)
1024 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 status = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001026 if (status == -1)
1027 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 cber |= (status << 8);
1029 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
1030
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001031 if (cber != 65535)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 *fe_status |= FE_HAS_VITERBI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 }
1034
1035 // if we DO have some valid VITERBI output, but don't already have SYNC
1036 // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid.
1037 if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {
1038 // read the VBER
1039 vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001040 if (vber == -1)
1041 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 status = tda1004x_read_byte(state, TDA1004X_VBER_MID);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001043 if (status == -1)
1044 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 vber |= (status << 8);
1046 status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001047 if (status == -1)
1048 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 vber |= ((status << 16) & 0x0f);
1050 tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
1051
1052 // if RS has passed some valid TS packets, then we must be
1053 // getting some SYNC bytes
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001054 if (vber < 16632)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 *fe_status |= FE_HAS_SYNC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 }
1057
1058 // success
1059 dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status);
1060 return 0;
1061}
1062
1063static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
1064{
1065 struct tda1004x_state* state = fe->demodulator_priv;
1066 int tmp;
1067 int reg = 0;
1068
1069 dprintk("%s\n", __FUNCTION__);
1070
1071 // determine the register to use
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001072 switch (state->demod_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 case TDA1004X_DEMOD_TDA10045:
1074 reg = TDA10045H_S_AGC;
1075 break;
1076
1077 case TDA1004X_DEMOD_TDA10046:
1078 reg = TDA10046H_AGC_IF_LEVEL;
1079 break;
1080 }
1081
1082 // read it
1083 tmp = tda1004x_read_byte(state, reg);
1084 if (tmp < 0)
1085 return -EIO;
1086
1087 *signal = (tmp << 8) | tmp;
1088 dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal);
1089 return 0;
1090}
1091
1092static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
1093{
1094 struct tda1004x_state* state = fe->demodulator_priv;
1095 int tmp;
1096
1097 dprintk("%s\n", __FUNCTION__);
1098
1099 // read it
1100 tmp = tda1004x_read_byte(state, TDA1004X_SNR);
1101 if (tmp < 0)
1102 return -EIO;
Andrew de Quinceyc2026b32005-09-09 13:02:33 -07001103 tmp = 255 - tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104
1105 *snr = ((tmp << 8) | tmp);
1106 dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);
1107 return 0;
1108}
1109
1110static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
1111{
1112 struct tda1004x_state* state = fe->demodulator_priv;
1113 int tmp;
1114 int tmp2;
1115 int counter;
1116
1117 dprintk("%s\n", __FUNCTION__);
1118
1119 // read the UCBLOCKS and reset
1120 counter = 0;
1121 tmp = tda1004x_read_byte(state, TDA1004X_UNCOR);
1122 if (tmp < 0)
1123 return -EIO;
1124 tmp &= 0x7f;
1125 while (counter++ < 5) {
1126 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1127 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1128 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1129
1130 tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR);
1131 if (tmp2 < 0)
1132 return -EIO;
1133 tmp2 &= 0x7f;
1134 if ((tmp2 < tmp) || (tmp2 == 0))
1135 break;
1136 }
1137
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001138 if (tmp != 0x7f)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 *ucblocks = tmp;
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001140 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 *ucblocks = 0xffffffff;
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001142
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks);
1144 return 0;
1145}
1146
1147static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
1148{
1149 struct tda1004x_state* state = fe->demodulator_priv;
1150 int tmp;
1151
1152 dprintk("%s\n", __FUNCTION__);
1153
1154 // read it in
1155 tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001156 if (tmp < 0)
1157 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 *ber = tmp << 1;
1159 tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001160 if (tmp < 0)
1161 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 *ber |= (tmp << 9);
1163 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
1164
1165 dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
1166 return 0;
1167}
1168
1169static int tda1004x_sleep(struct dvb_frontend* fe)
1170{
1171 struct tda1004x_state* state = fe->demodulator_priv;
1172
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001173 switch (state->demod_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174 case TDA1004X_DEMOD_TDA10045:
1175 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10);
1176 break;
1177
1178 case TDA1004X_DEMOD_TDA10046:
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -07001179 if (state->config->pll_sleep != NULL) {
1180 tda1004x_enable_tuner_i2c(state);
Hartmut Hackmannecb60de2005-07-07 17:57:40 -07001181 state->config->pll_sleep(fe);
Hartmut Hackmann634623d2005-11-08 21:35:13 -08001182 if (state->config->if_freq != TDA10046_FREQ_052) {
1183 /* special hack for Philips EUROPA Based boards:
1184 * keep the I2c bridge open for tuner access in analog mode
1185 */
1186 tda1004x_disable_tuner_i2c(state);
1187 }
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -07001188 }
1189 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 break;
1191 }
1192 state->initialised = 0;
1193
1194 return 0;
1195}
1196
1197static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1198{
1199 fesettings->min_delay_ms = 800;
Hartmut Hackmannf03cbea2005-07-07 17:57:43 -07001200 /* Drift compensation makes no sense for DVB-T */
1201 fesettings->step_size = 0;
1202 fesettings->max_drift = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 return 0;
1204}
1205
1206static void tda1004x_release(struct dvb_frontend* fe)
1207{
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001208 struct tda1004x_state *state = fe->demodulator_priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 kfree(state);
1210}
1211
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212static struct dvb_frontend_ops tda10045_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 .info = {
1214 .name = "Philips TDA10045H DVB-T",
1215 .type = FE_OFDM,
1216 .frequency_min = 51000000,
1217 .frequency_max = 858000000,
1218 .frequency_stepsize = 166667,
1219 .caps =
1220 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1221 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1222 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1223 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1224 },
1225
1226 .release = tda1004x_release,
1227
1228 .init = tda10045_init,
1229 .sleep = tda1004x_sleep,
1230
1231 .set_frontend = tda1004x_set_fe,
1232 .get_frontend = tda1004x_get_fe,
1233 .get_tune_settings = tda1004x_get_tune_settings,
1234
1235 .read_status = tda1004x_read_status,
1236 .read_ber = tda1004x_read_ber,
1237 .read_signal_strength = tda1004x_read_signal_strength,
1238 .read_snr = tda1004x_read_snr,
1239 .read_ucblocks = tda1004x_read_ucblocks,
1240};
1241
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001242struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1243 struct i2c_adapter* i2c)
1244{
1245 struct tda1004x_state *state;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001247 /* allocate memory for the internal state */
1248 state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1249 if (!state)
1250 return NULL;
1251
1252 /* setup the state */
1253 state->config = config;
1254 state->i2c = i2c;
1255 memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
1256 state->initialised = 0;
1257 state->demod_type = TDA1004X_DEMOD_TDA10045;
1258
1259 /* check if the demod is there */
1260 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) {
1261 kfree(state);
1262 return NULL;
1263 }
1264
1265 /* create dvb_frontend */
1266 state->frontend.ops = &state->ops;
1267 state->frontend.demodulator_priv = state;
1268 return &state->frontend;
1269}
1270
1271static struct dvb_frontend_ops tda10046_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272 .info = {
1273 .name = "Philips TDA10046H DVB-T",
1274 .type = FE_OFDM,
1275 .frequency_min = 51000000,
1276 .frequency_max = 858000000,
1277 .frequency_stepsize = 166667,
1278 .caps =
1279 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1280 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1281 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1282 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1283 },
1284
1285 .release = tda1004x_release,
1286
1287 .init = tda10046_init,
1288 .sleep = tda1004x_sleep,
1289
1290 .set_frontend = tda1004x_set_fe,
1291 .get_frontend = tda1004x_get_fe,
1292 .get_tune_settings = tda1004x_get_tune_settings,
1293
1294 .read_status = tda1004x_read_status,
1295 .read_ber = tda1004x_read_ber,
1296 .read_signal_strength = tda1004x_read_signal_strength,
1297 .read_snr = tda1004x_read_snr,
1298 .read_ucblocks = tda1004x_read_ucblocks,
1299};
1300
Johannes Stezenbach7f5e02d2005-05-16 21:54:30 -07001301struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1302 struct i2c_adapter* i2c)
1303{
1304 struct tda1004x_state *state;
1305
1306 /* allocate memory for the internal state */
1307 state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1308 if (!state)
1309 return NULL;
1310
1311 /* setup the state */
1312 state->config = config;
1313 state->i2c = i2c;
1314 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1315 state->initialised = 0;
1316 state->demod_type = TDA1004X_DEMOD_TDA10046;
1317
1318 /* check if the demod is there */
1319 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {
1320 kfree(state);
1321 return NULL;
1322 }
1323
1324 /* create dvb_frontend */
1325 state->frontend.ops = &state->ops;
1326 state->frontend.demodulator_priv = state;
1327 return &state->frontend;
1328}
1329
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330module_param(debug, int, 0644);
1331MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1332
1333MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator");
1334MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
1335MODULE_LICENSE("GPL");
1336
1337EXPORT_SYMBOL(tda10045_attach);
1338EXPORT_SYMBOL(tda10046_attach);
1339EXPORT_SYMBOL(tda1004x_write_byte);