diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/dvb-usb/dibusb-common.c | 131 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dibusb-mb.c | 7 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dibusb.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | 11 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/Makefile | 4 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib3000.h | 23 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib3000mb_priv.h | 3 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib3000mc.c | 1472 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib3000mc_priv.h | 404 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/mt2060.c | 4 |
10 files changed, 879 insertions, 1181 deletions
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 78a604dfadfc..390ced9ae4bc 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c | |||
@@ -131,9 +131,6 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num | |||
131 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 131 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
132 | return -EAGAIN; | 132 | return -EAGAIN; |
133 | 133 | ||
134 | if (num > 2) | ||
135 | warn("more than 2 i2c messages at a time is not handled yet. TODO."); | ||
136 | |||
137 | for (i = 0; i < num; i++) { | 134 | for (i = 0; i < num; i++) { |
138 | /* write/read request */ | 135 | /* write/read request */ |
139 | if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { | 136 | if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { |
@@ -168,31 +165,137 @@ int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val) | |||
168 | } | 165 | } |
169 | EXPORT_SYMBOL(dibusb_read_eeprom_byte); | 166 | EXPORT_SYMBOL(dibusb_read_eeprom_byte); |
170 | 167 | ||
171 | static const struct dib3000p_agc_config dib3000p_agc_panasonic_env57h1xd5 = { | 168 | /* 3000MC/P stuff */ |
172 | { 0x51, 0x301d, 0x0, 0x1cc7, 0xdc29, 0x570a, | 169 | // Config Adjacent channels Perf -cal22 |
173 | 0xbae1, 0x8ccd, 0x3b6d, 0x551d, 0xa, 0x951e } | 170 | static struct dibx000_agc_config dib3000p_mt2060_agc_config = { |
171 | .band_caps = BAND_VHF | BAND_UHF, | ||
172 | .setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0), | ||
173 | |||
174 | .agc1_max = 48497, | ||
175 | .agc1_min = 23593, | ||
176 | .agc2_max = 46531, | ||
177 | .agc2_min = 24904, | ||
178 | |||
179 | .agc1_pt1 = 0x65, | ||
180 | .agc1_pt2 = 0x69, | ||
181 | |||
182 | .agc1_slope1 = 0x51, | ||
183 | .agc1_slope2 = 0x27, | ||
184 | |||
185 | .agc2_pt1 = 0, | ||
186 | .agc2_pt2 = 0x33, | ||
187 | |||
188 | .agc2_slope1 = 0x35, | ||
189 | .agc2_slope2 = 0x37, | ||
174 | }; | 190 | }; |
175 | 191 | ||
176 | static const struct dib3000p_agc_config dib3000p_agc_microtune_mt2060 = { | 192 | static struct dib3000mc_config stk3000p_dib3000p_config = { |
177 | { 0x196, 0x301d, 0x0, 0x1cc7, 0xffff, 0x5c29, | 193 | &dib3000p_mt2060_agc_config, |
178 | 0xa8f6, 0x5eb8, 0x65ff, 0x40ff, 0x8a, 0x1114 } | 194 | |
195 | .max_time = 0x196, | ||
196 | .ln_adc_level = 0x1cc7, | ||
197 | |||
198 | .output_mpeg2_in_188_bytes = 1, | ||
179 | }; | 199 | }; |
180 | 200 | ||
181 | static struct mt2060_config stk3000p_mt2060_config = { | 201 | static struct dibx000_agc_config dib3000p_panasonic_agc_config = { |
182 | .i2c_address = 0x60, | 202 | .setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0), |
203 | |||
204 | .agc1_max = 56361, | ||
205 | .agc1_min = 22282, | ||
206 | .agc2_max = 43254, | ||
207 | .agc2_min = 36045, | ||
208 | |||
209 | .agc1_pt1 = 0x65, | ||
210 | .agc1_pt2 = 0xff, | ||
211 | |||
212 | .agc1_slope1 = 0x40, | ||
213 | .agc1_slope2 = 0xff, | ||
214 | |||
215 | .agc2_pt1 = 0, | ||
216 | .agc2_pt2 = 0x8a, | ||
217 | |||
218 | .agc2_slope1 = 0x11, | ||
219 | .agc2_slope2 = 0x14, | ||
220 | }; | ||
221 | |||
222 | static struct dib3000mc_config mod3000p_dib3000p_config = { | ||
223 | &dib3000p_panasonic_agc_config, | ||
224 | |||
225 | .max_time = 0x51, | ||
226 | .ln_adc_level = 0x1cc7, | ||
227 | |||
228 | .output_mpeg2_in_188_bytes = 1, | ||
183 | }; | 229 | }; |
184 | 230 | ||
185 | int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) | 231 | int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) |
186 | { | 232 | { |
187 | struct dib3000_config demod_cfg; | 233 | if (dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000P_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0) { |
188 | struct dibusb_state *st = d->priv; | 234 | if (d->priv != NULL) { |
235 | struct dibusb_state *st = d->priv; | ||
236 | st->ops.pid_parse = dib3000mc_pid_parse; | ||
237 | st->ops.pid_ctrl = dib3000mc_pid_control; | ||
238 | } | ||
239 | return 0; | ||
240 | } | ||
189 | return -ENODEV; | 241 | return -ENODEV; |
190 | } | 242 | } |
191 | EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach); | 243 | EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach); |
192 | 244 | ||
245 | static struct mt2060_config stk3000p_mt2060_config = { | ||
246 | 0x60 | ||
247 | }; | ||
248 | |||
193 | int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d) | 249 | int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d) |
194 | { | 250 | { |
195 | return -ENODEV; | 251 | struct dibusb_state *st = d->priv; |
252 | int ret; | ||
253 | u8 a,b; | ||
254 | u16 if1 = 1220; | ||
255 | struct i2c_adapter *tun_i2c; | ||
256 | |||
257 | // First IF calibration for Liteon Sticks | ||
258 | if (d->udev->descriptor.idVendor == USB_VID_LITEON && | ||
259 | d->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) { | ||
260 | |||
261 | dibusb_read_eeprom_byte(d,0x7E,&a); | ||
262 | dibusb_read_eeprom_byte(d,0x7F,&b); | ||
263 | |||
264 | if (a == 0x00) | ||
265 | if1 += b; | ||
266 | else if (a == 0x80) | ||
267 | if1 -= b; | ||
268 | else | ||
269 | warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b); | ||
270 | |||
271 | } else if (d->udev->descriptor.idVendor == USB_VID_DIBCOM && | ||
272 | d->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) { | ||
273 | u8 desc; | ||
274 | dibusb_read_eeprom_byte(d, 7, &desc); | ||
275 | if (desc == 2) { | ||
276 | a = 127; | ||
277 | do { | ||
278 | dibusb_read_eeprom_byte(d, a, &desc); | ||
279 | a--; | ||
280 | } while (a > 7 && (desc == 0xff || desc == 0x00)); | ||
281 | if (desc & 0x80) | ||
282 | if1 -= (0xff - desc); | ||
283 | else | ||
284 | if1 += desc; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | tun_i2c = dib3000mc_get_tuner_i2c_master(d->fe, 1); | ||
289 | if ((ret = mt2060_attach(d->fe, tun_i2c, &stk3000p_mt2060_config, if1)) != 0) { | ||
290 | /* not found - use panasonic pll parameters */ | ||
291 | if (dvb_pll_attach(d->fe, 0x60, tun_i2c, &dvb_pll_env57h1xd5) == NULL) | ||
292 | return -ENOMEM; | ||
293 | } else { | ||
294 | st->mt2060_present = 1; | ||
295 | /* set the correct parameters for the dib3000p */ | ||
296 | dib3000mc_set_config(d->fe, &stk3000p_dib3000p_config); | ||
297 | } | ||
298 | return 0; | ||
196 | } | 299 | } |
197 | EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); | 300 | EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); |
198 | 301 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 64ad5b606c2a..f181d10fd88d 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c | |||
@@ -20,11 +20,12 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) | |||
20 | struct dibusb_state *st = d->priv; | 20 | struct dibusb_state *st = d->priv; |
21 | 21 | ||
22 | demod_cfg.demod_address = 0x8; | 22 | demod_cfg.demod_address = 0x8; |
23 | demod_cfg.pll_set = dvb_usb_pll_set_i2c; | ||
24 | demod_cfg.pll_init = dvb_usb_pll_init_i2c; | ||
25 | 23 | ||
26 | if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) | 24 | if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) { |
25 | d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; | ||
26 | d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; | ||
27 | return -ENODEV; | 27 | return -ENODEV; |
28 | } | ||
28 | 29 | ||
29 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; | 30 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; |
30 | 31 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h index e21de8b668f6..a43f87480cf6 100644 --- a/drivers/media/dvb/dvb-usb/dibusb.h +++ b/drivers/media/dvb/dvb-usb/dibusb.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include "dvb-usb.h" | 17 | #include "dvb-usb.h" |
18 | 18 | ||
19 | #include "dib3000.h" | 19 | #include "dib3000.h" |
20 | #include "dib3000mc.h" | ||
20 | #include "mt2060.h" | 21 | #include "mt2060.h" |
21 | 22 | ||
22 | /* | 23 | /* |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index 9f8d3f0ca5a1..71a754e2287e 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | |||
@@ -179,16 +179,15 @@ int dvb_usb_fe_init(struct dvb_usb_device* d) | |||
179 | return 0; | 179 | return 0; |
180 | } | 180 | } |
181 | 181 | ||
182 | d->props.frontend_attach(d); | ||
183 | |||
184 | /* re-assign sleep and wakeup functions */ | 182 | /* re-assign sleep and wakeup functions */ |
185 | if (d->fe != NULL) { | 183 | if (d->props.frontend_attach(d) == 0 && d->fe != NULL) { |
186 | d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup; | 184 | d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup; |
187 | d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep; | 185 | d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep; |
188 | 186 | ||
189 | if (dvb_register_frontend(&d->dvb_adap, d->fe)) { | 187 | if (dvb_register_frontend(&d->dvb_adap, d->fe)) { |
190 | err("Frontend registration failed."); | 188 | err("Frontend registration failed."); |
191 | dvb_frontend_detach(d->fe); | 189 | if (d->fe->ops.release) |
190 | d->fe->ops.release(d->fe); | ||
192 | d->fe = NULL; | 191 | d->fe = NULL; |
193 | return -ENODEV; | 192 | return -ENODEV; |
194 | } | 193 | } |
@@ -203,9 +202,7 @@ int dvb_usb_fe_init(struct dvb_usb_device* d) | |||
203 | 202 | ||
204 | int dvb_usb_fe_exit(struct dvb_usb_device *d) | 203 | int dvb_usb_fe_exit(struct dvb_usb_device *d) |
205 | { | 204 | { |
206 | if (d->fe != NULL) { | 205 | if (d->fe != NULL) |
207 | dvb_unregister_frontend(d->fe); | 206 | dvb_unregister_frontend(d->fe); |
208 | dvb_frontend_detach(d->fe); | ||
209 | } | ||
210 | return 0; | 207 | return 0; |
211 | } | 208 | } |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 2985d7d5e976..0b43942d8b54 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -12,7 +12,7 @@ obj-$(CONFIG_DVB_CX24110) += cx24110.o | |||
12 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o | 12 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o |
13 | obj-$(CONFIG_DVB_L64781) += l64781.o | 13 | obj-$(CONFIG_DVB_L64781) += l64781.o |
14 | obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o | 14 | obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o |
15 | obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o | 15 | obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o |
16 | obj-$(CONFIG_DVB_MT312) += mt312.o | 16 | obj-$(CONFIG_DVB_MT312) += mt312.o |
17 | obj-$(CONFIG_DVB_VES1820) += ves1820.o | 17 | obj-$(CONFIG_DVB_VES1820) += ves1820.o |
18 | obj-$(CONFIG_DVB_VES1X93) += ves1x93.o | 18 | obj-$(CONFIG_DVB_VES1X93) += ves1x93.o |
@@ -31,6 +31,8 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | |||
31 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o | 31 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o |
32 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o | 32 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o |
33 | obj-$(CONFIG_DVB_CX24123) += cx24123.o | 33 | obj-$(CONFIG_DVB_CX24123) += cx24123.o |
34 | obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | ||
35 | obj-$(CONFIG_DVB_ISL6421) += isl6421.o | ||
34 | obj-$(CONFIG_DVB_TDA10086) += tda10086.o | 36 | obj-$(CONFIG_DVB_TDA10086) += tda10086.o |
35 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o | 37 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o |
36 | obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o | 38 | obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o |
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h index bd0e663cf6f3..0caac3f0f279 100644 --- a/drivers/media/dvb/frontends/dib3000.h +++ b/drivers/media/dvb/frontends/dib3000.h | |||
@@ -26,20 +26,10 @@ | |||
26 | 26 | ||
27 | #include <linux/dvb/frontend.h> | 27 | #include <linux/dvb/frontend.h> |
28 | 28 | ||
29 | struct dib3000p_agc_config { | ||
30 | u16 val[12]; | ||
31 | }; | ||
32 | |||
33 | struct dib3000_config | 29 | struct dib3000_config |
34 | { | 30 | { |
35 | /* the demodulator's i2c address */ | 31 | /* the demodulator's i2c address */ |
36 | u8 demod_address; | 32 | u8 demod_address; |
37 | |||
38 | const struct dib3000p_agc_config *agc; | ||
39 | |||
40 | /* PLL maintenance and the i2c address of the PLL */ | ||
41 | int (*pll_init)(struct dvb_frontend *fe); | ||
42 | int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params); | ||
43 | }; | 33 | }; |
44 | 34 | ||
45 | struct dib_fe_xfer_ops | 35 | struct dib_fe_xfer_ops |
@@ -51,11 +41,16 @@ struct dib_fe_xfer_ops | |||
51 | int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); | 41 | int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); |
52 | }; | 42 | }; |
53 | 43 | ||
44 | #if defined(CONFIG_DVB_DIB3000MB) || defined(CONFIG_DVB_DIB3000MB_MODULE) | ||
54 | extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, | 45 | extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, |
55 | struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); | 46 | struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); |
47 | #else | ||
48 | static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, | ||
49 | struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) | ||
50 | { | ||
51 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
52 | return NULL; | ||
53 | } | ||
54 | #endif // CONFIG_DVB_DIB3000MB | ||
56 | 55 | ||
57 | extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, | ||
58 | struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); | ||
59 | |||
60 | extern int dib3000mc_set_agc_config(struct dvb_frontend *fe, const struct dib3000p_agc_config *agc); | ||
61 | #endif // DIB3000_H | 56 | #endif // DIB3000_H |
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h index 2b0771e824eb..1a12747fdc91 100644 --- a/drivers/media/dvb/frontends/dib3000mb_priv.h +++ b/drivers/media/dvb/frontends/dib3000mb_priv.h | |||
@@ -83,9 +83,6 @@ | |||
83 | #define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8)) | 83 | #define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8)) |
84 | #define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7))) | 84 | #define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7))) |
85 | 85 | ||
86 | /* for auto search */ | ||
87 | extern u16 dib3000_seq[2][2][2]; | ||
88 | |||
89 | #define DIB3000_REG_MANUFACTOR_ID ( 1025) | 86 | #define DIB3000_REG_MANUFACTOR_ID ( 1025) |
90 | #define DIB3000_I2C_ID_DIBCOM (0x01b3) | 87 | #define DIB3000_I2C_ID_DIBCOM (0x01b3) |
91 | 88 | ||
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index 41710f43975a..cc41c6bcdaf6 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c | |||
@@ -1,939 +1,945 @@ | |||
1 | /* | 1 | /* |
2 | * Frontend driver for mobile DVB-T demodulator DiBcom 3000P/M-C | 2 | * Driver for DiBcom DiB3000MC/P-demodulator. |
3 | * DiBcom (http://www.dibcom.fr/) | ||
4 | * | 3 | * |
4 | * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/) | ||
5 | * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) | 5 | * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) |
6 | * | 6 | * |
7 | * based on GPL code from DiBCom, which has | 7 | * This code is partially based on the previous dib3000mc.c . |
8 | * | 8 | * |
9 | * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) | 9 | * This program is free software; you can redistribute it and/or |
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License as | 10 | * modify it under the terms of the GNU General Public License as |
13 | * published by the Free Software Foundation, version 2. | 11 | * published by the Free Software Foundation, version 2. |
14 | * | ||
15 | * Acknowledgements | ||
16 | * | ||
17 | * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver | ||
18 | * sources, on which this driver (and the dvb-dibusb) are based. | ||
19 | * | ||
20 | * see Documentation/dvb/README.dibusb for more information | ||
21 | * | ||
22 | */ | 12 | */ |
23 | #include <linux/config.h> | 13 | |
24 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 15 | #include <linux/i2c.h> |
26 | #include <linux/moduleparam.h> | 16 | //#include <linux/init.h> |
27 | #include <linux/init.h> | 17 | //#include <linux/delay.h> |
28 | #include <linux/delay.h> | 18 | //#include <linux/string.h> |
29 | #include <linux/string.h> | 19 | //#include <linux/slab.h> |
30 | #include <linux/slab.h> | 20 | |
31 | 21 | #include "dvb_frontend.h" | |
32 | #include "dib3000-common.h" | 22 | |
33 | #include "dib3000mc_priv.h" | 23 | #include "dib3000mc.h" |
34 | #include "dib3000.h" | 24 | |
35 | |||
36 | /* Version information */ | ||
37 | #define DRIVER_VERSION "0.1" | ||
38 | #define DRIVER_DESC "DiBcom 3000M-C DVB-T demodulator" | ||
39 | #define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" | ||
40 | |||
41 | #ifdef CONFIG_DVB_DIBCOM_DEBUG | ||
42 | static int debug; | 25 | static int debug; |
43 | module_param(debug, int, 0644); | 26 | module_param(debug, int, 0644); |
44 | MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=stat (|-able))."); | 27 | MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); |
45 | #endif | ||
46 | #define deb_info(args...) dprintk(0x01,args) | ||
47 | #define deb_xfer(args...) dprintk(0x02,args) | ||
48 | #define deb_setf(args...) dprintk(0x04,args) | ||
49 | #define deb_getf(args...) dprintk(0x08,args) | ||
50 | #define deb_stat(args...) dprintk(0x10,args) | ||
51 | |||
52 | static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode, | ||
53 | fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth) | ||
54 | { | ||
55 | switch (transmission_mode) { | ||
56 | case TRANSMISSION_MODE_2K: | ||
57 | wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[0]); | ||
58 | break; | ||
59 | case TRANSMISSION_MODE_8K: | ||
60 | wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[1]); | ||
61 | break; | ||
62 | default: | ||
63 | break; | ||
64 | } | ||
65 | 28 | ||
66 | switch (bandwidth) { | 29 | #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0) |
67 | /* case BANDWIDTH_5_MHZ: | 30 | |
68 | wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]); | 31 | struct dib3000mc_state { |
69 | break; */ | 32 | struct dvb_frontend demod; |
70 | case BANDWIDTH_6_MHZ: | 33 | struct dib3000mc_config *cfg; |
71 | wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]); | 34 | |
72 | break; | 35 | u8 i2c_addr; |
73 | case BANDWIDTH_7_MHZ: | 36 | struct i2c_adapter *i2c_adap; |
74 | wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]); | 37 | |
75 | break; | 38 | struct dibx000_i2c_master i2c_master; |
76 | case BANDWIDTH_8_MHZ: | 39 | |
77 | wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]); | 40 | fe_bandwidth_t current_bandwidth; |
78 | break; | 41 | |
79 | default: | 42 | u16 dev_id; |
80 | break; | 43 | }; |
44 | |||
45 | static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg) | ||
46 | { | ||
47 | u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; | ||
48 | u8 rb[2]; | ||
49 | struct i2c_msg msg[2] = { | ||
50 | { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, | ||
51 | { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, | ||
52 | }; | ||
53 | |||
54 | if (i2c_transfer(state->i2c_adap, msg, 2) != 2) | ||
55 | dprintk("i2c read error on %d\n",reg); | ||
56 | |||
57 | return (rb[0] << 8) | rb[1]; | ||
58 | } | ||
59 | |||
60 | static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val) | ||
61 | { | ||
62 | u8 b[4] = { | ||
63 | (reg >> 8) & 0xff, reg & 0xff, | ||
64 | (val >> 8) & 0xff, val & 0xff, | ||
65 | }; | ||
66 | struct i2c_msg msg = { | ||
67 | .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 | ||
68 | }; | ||
69 | return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; | ||
70 | } | ||
71 | |||
72 | static void dump_fep(struct dibx000_ofdm_channel *cd) | ||
73 | { | ||
74 | printk(KERN_DEBUG "DiB3000MC: "); | ||
75 | switch (cd->nfft) { | ||
76 | case 1: printk("8K "); break; | ||
77 | case 2: printk("4K "); break; | ||
78 | case 0: printk("2K "); break; | ||
79 | default: printk("FFT_UNK "); break; | ||
81 | } | 80 | } |
82 | 81 | ||
83 | switch (mode) { | 82 | printk("1/%i ", 32 / (1 << cd->guard)); |
84 | case 0: /* no impulse */ /* fall through */ | 83 | switch (cd->nqam) { |
85 | wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]); | 84 | case 0: printk("QPSK "); break; |
86 | break; | 85 | case 1: printk("16QAM "); break; |
87 | case 1: /* new algo */ | 86 | case 2: printk("64QAM "); break; |
88 | wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]); | 87 | default: printk("QAM_UNK "); break; |
89 | set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */ | ||
90 | break; | ||
91 | default: /* old algo */ | ||
92 | wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]); | ||
93 | break; | ||
94 | } | 88 | } |
95 | return 0; | 89 | printk("ALPHA %i ", cd->vit_alpha); |
90 | printk("Code Rate HP %i/%i ", cd->vit_code_rate_hp, cd->vit_code_rate_hp + 1); | ||
91 | printk("Code Rate LP %i/%i ", cd->vit_code_rate_lp, cd->vit_code_rate_lp + 1); | ||
92 | printk("HRCH %i\n", cd->vit_hrch); | ||
96 | } | 93 | } |
97 | 94 | ||
98 | static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset, | 95 | |
99 | fe_transmit_mode_t fft, fe_bandwidth_t bw) | 96 | static int dib3000mc_identify(struct dib3000mc_state *state) |
100 | { | 97 | { |
101 | u16 timf_msb,timf_lsb; | 98 | u16 value; |
102 | s32 tim_offset,tim_sgn; | 99 | if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) { |
103 | u64 comp1,comp2,comp=0; | 100 | dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value); |
101 | return -EREMOTEIO; | ||
102 | } | ||
104 | 103 | ||
105 | switch (bw) { | 104 | value = dib3000mc_read_word(state, 1026); |
106 | case BANDWIDTH_8_MHZ: comp = DIB3000MC_CLOCK_REF*8; break; | 105 | if (value != 0x3001 && value != 0x3002) { |
107 | case BANDWIDTH_7_MHZ: comp = DIB3000MC_CLOCK_REF*7; break; | 106 | dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value); |
108 | case BANDWIDTH_6_MHZ: comp = DIB3000MC_CLOCK_REF*6; break; | 107 | return -EREMOTEIO; |
109 | default: err("unknown bandwidth (%d)",bw); break; | ||
110 | } | 108 | } |
111 | timf_msb = (comp >> 16) & 0xff; | 109 | state->dev_id = value; |
112 | timf_lsb = (comp & 0xffff); | 110 | |
111 | dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id); | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset) | ||
117 | { | ||
118 | /* | ||
119 | u32 timf_msb, timf_lsb, i; | ||
120 | int tim_sgn ; | ||
121 | LUInt comp1, comp2, comp ; | ||
122 | // u32 tim_offset ; | ||
123 | comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000; | ||
124 | timf_msb = (comp >> 16) & 0x00FF; | ||
125 | timf_lsb = comp & 0xFFFF; | ||
113 | 126 | ||
114 | // Update the timing offset ; | 127 | // Update the timing offset ; |
115 | if (upd_offset > 0) { | 128 | if (update_offset) { |
116 | if (!state->timing_offset_comp_done) { | 129 | if (state->timing_offset_comp_done == 0) { |
117 | msleep(200); | 130 | usleep(200000); |
118 | state->timing_offset_comp_done = 1; | 131 | state->timing_offset_comp_done = 1; |
119 | } | 132 | } |
120 | tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB); | 133 | tim_offset = dib3000mc_read_word(state, 416); |
121 | if ((tim_offset & 0x2000) == 0x2000) | 134 | if ((tim_offset & 0x2000) == 0x2000) |
122 | tim_offset |= 0xC000; | 135 | tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird |
123 | if (fft == TRANSMISSION_MODE_2K) | 136 | |
124 | tim_offset <<= 2; | 137 | if (nfft == 0) |
138 | tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable | ||
125 | state->timing_offset += tim_offset; | 139 | state->timing_offset += tim_offset; |
126 | } | 140 | } |
127 | |||
128 | tim_offset = state->timing_offset; | 141 | tim_offset = state->timing_offset; |
142 | |||
129 | if (tim_offset < 0) { | 143 | if (tim_offset < 0) { |
130 | tim_sgn = 1; | 144 | tim_sgn = 1; |
131 | tim_offset = -tim_offset; | 145 | tim_offset = -tim_offset; |
132 | } else | 146 | } else |
133 | tim_sgn = 0; | 147 | tim_sgn = 0; |
134 | 148 | ||
135 | comp1 = (u32)tim_offset * (u32)timf_lsb ; | 149 | comp1 = tim_offset * timf_lsb; |
136 | comp2 = (u32)tim_offset * (u32)timf_msb ; | 150 | comp2 = tim_offset * timf_msb; |
137 | comp = ((comp1 >> 16) + comp2) >> 7; | 151 | comp = ((comp1 >> 16) + comp2) >> 7; |
138 | 152 | ||
139 | if (tim_sgn == 0) | 153 | if (tim_sgn == 0) |
140 | comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp; | 154 | comp = timf_msb * (1<<16) + timf_lsb + comp; |
141 | else | 155 | else |
142 | comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ; | 156 | comp = timf_msb * (1<<16) + timf_lsb - comp; |
157 | |||
158 | timf_msb = (comp>>16)&0xFF ; | ||
159 | timf_lsb = comp&0xFFFF; | ||
160 | */ | ||
161 | u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000); | ||
143 | 162 | ||
144 | timf_msb = (comp >> 16) & 0xff; | 163 | dib3000mc_write_word(state, 23, timf >> 16); |
145 | timf_lsb = comp & 0xffff; | 164 | dib3000mc_write_word(state, 24, timf & 0xffff); |
146 | 165 | ||
147 | wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb); | ||
148 | wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb); | ||
149 | return 0; | 166 | return 0; |
150 | } | 167 | } |
151 | 168 | ||
152 | static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost) | 169 | static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state) |
153 | { | 170 | { |
154 | if (boost) { | 171 | if (state->cfg->pwm3_inversion) { |
155 | wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON); | 172 | dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0)); |
173 | dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0)); | ||
156 | } else { | 174 | } else { |
157 | wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_OFF); | 175 | dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0)); |
158 | } | 176 | dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0)); |
159 | switch (bw) { | ||
160 | case BANDWIDTH_8_MHZ: | ||
161 | wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz); | ||
162 | break; | ||
163 | case BANDWIDTH_7_MHZ: | ||
164 | wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz); | ||
165 | break; | ||
166 | case BANDWIDTH_6_MHZ: | ||
167 | wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_6mhz); | ||
168 | break; | ||
169 | /* case BANDWIDTH_5_MHZ: | ||
170 | wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz); | ||
171 | break;*/ | ||
172 | case BANDWIDTH_AUTO: | ||
173 | return -EOPNOTSUPP; | ||
174 | default: | ||
175 | err("unknown bandwidth value (%d).",bw); | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | if (boost) { | ||
179 | u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) + | ||
180 | rd(DIB3000MC_REG_BW_TIMOUT_LSB); | ||
181 | timeout *= 85; timeout >>= 7; | ||
182 | wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff); | ||
183 | wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff); | ||
184 | } | 177 | } |
178 | |||
179 | if (state->cfg->use_pwm3) | ||
180 | dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0)); | ||
181 | else | ||
182 | dib3000mc_write_word(state, 245, 0); | ||
183 | |||
184 | dib3000mc_write_word(state, 1040, 0x3); | ||
185 | return 0; | 185 | return 0; |
186 | } | 186 | } |
187 | 187 | ||
188 | static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con) | 188 | static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode) |
189 | { | 189 | { |
190 | switch (con) { | 190 | int ret = 0; |
191 | case QAM_64: | 191 | u16 fifo_threshold = 1792; |
192 | wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]); | 192 | u16 outreg = 0; |
193 | break; | 193 | u16 outmode = 0; |
194 | case QAM_16: | 194 | u16 elecout = 1; |
195 | wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]); | 195 | u16 smo_reg = (0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 1) | 0 ; //smo_mode = 1 |
196 | break; | 196 | |
197 | case QPSK: | 197 | dprintk("-I- Setting output mode for demod %p to %d\n", |
198 | wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]); | 198 | &state->demod, mode); |
199 | break; | 199 | |
200 | case QAM_AUTO: | 200 | switch (mode) { |
201 | case OUTMODE_HIGH_Z: // disable | ||
202 | elecout = 0; | ||
203 | break; | ||
204 | case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock | ||
205 | outmode = 0; | ||
206 | break; | ||
207 | case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock | ||
208 | outmode = 1; | ||
209 | break; | ||
210 | case OUTMODE_MPEG2_SERIAL: // STBs with serial input | ||
211 | outmode = 2; | ||
212 | break; | ||
213 | case OUTMODE_MPEG2_FIFO: // e.g. USB feeding | ||
214 | elecout = 3; | ||
215 | /*ADDR @ 206 : | ||
216 | P_smo_error_discard [1;6:6] = 0 | ||
217 | P_smo_rs_discard [1;5:5] = 0 | ||
218 | P_smo_pid_parse [1;4:4] = 0 | ||
219 | P_smo_fifo_flush [1;3:3] = 0 | ||
220 | P_smo_mode [2;2:1] = 11 | ||
221 | P_smo_ovf_prot [1;0:0] = 0 | ||
222 | */ | ||
223 | smo_reg = (0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) |(3 << 1) | 0; | ||
224 | fifo_threshold = 512; | ||
225 | outmode = 5; | ||
226 | break; | ||
227 | case OUTMODE_DIVERSITY: | ||
228 | outmode = 4; | ||
229 | elecout = 1; | ||
201 | break; | 230 | break; |
202 | default: | 231 | default: |
203 | warn("unkown constellation."); | 232 | dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod); |
233 | outmode = 0; | ||
204 | break; | 234 | break; |
205 | } | 235 | } |
206 | return 0; | 236 | |
237 | if ((state->cfg->output_mpeg2_in_188_bytes)) | ||
238 | smo_reg |= (1 << 5) ; //P_smo_rs_discard [1;5:5] = 1 | ||
239 | |||
240 | outreg = dib3000mc_read_word(state, 244) & 0x07FF; | ||
241 | outreg |= (outmode << 11); | ||
242 | ret |= dib3000mc_write_word(state, 244, outreg); | ||
243 | ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/ | ||
244 | ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */ | ||
245 | ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */ | ||
246 | return ret; | ||
207 | } | 247 | } |
208 | 248 | ||
209 | static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val) | 249 | static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw) |
210 | { | 250 | { |
211 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; | 251 | struct dib3000mc_state *state = demod->demodulator_priv; |
212 | fe_code_rate_t fe_cr = FEC_NONE; | 252 | u16 bw_cfg[6] = { 0 }; |
213 | u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0; | 253 | u16 imp_bw_cfg[3] = { 0 }; |
214 | int seq; | 254 | u16 reg; |
215 | 255 | ||
216 | switch (ofdm->transmission_mode) { | 256 | /* settings here are for 27.7MHz */ |
217 | case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break; | 257 | switch (bw) { |
218 | case TRANSMISSION_MODE_8K: fft = DIB3000_TRANSMISSION_MODE_8K; break; | 258 | case BANDWIDTH_8_MHZ: |
219 | case TRANSMISSION_MODE_AUTO: break; | 259 | bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20; |
220 | default: return -EINVAL; | 260 | imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7; |
221 | } | 261 | break; |
222 | switch (ofdm->guard_interval) { | ||
223 | case GUARD_INTERVAL_1_32: guard = DIB3000_GUARD_TIME_1_32; break; | ||
224 | case GUARD_INTERVAL_1_16: guard = DIB3000_GUARD_TIME_1_16; break; | ||
225 | case GUARD_INTERVAL_1_8: guard = DIB3000_GUARD_TIME_1_8; break; | ||
226 | case GUARD_INTERVAL_1_4: guard = DIB3000_GUARD_TIME_1_4; break; | ||
227 | case GUARD_INTERVAL_AUTO: break; | ||
228 | default: return -EINVAL; | ||
229 | } | ||
230 | switch (ofdm->constellation) { | ||
231 | case QPSK: qam = DIB3000_CONSTELLATION_QPSK; break; | ||
232 | case QAM_16: qam = DIB3000_CONSTELLATION_16QAM; break; | ||
233 | case QAM_64: qam = DIB3000_CONSTELLATION_64QAM; break; | ||
234 | case QAM_AUTO: break; | ||
235 | default: return -EINVAL; | ||
236 | } | ||
237 | switch (ofdm->hierarchy_information) { | ||
238 | case HIERARCHY_NONE: /* fall through */ | ||
239 | case HIERARCHY_1: alpha = DIB3000_ALPHA_1; break; | ||
240 | case HIERARCHY_2: alpha = DIB3000_ALPHA_2; break; | ||
241 | case HIERARCHY_4: alpha = DIB3000_ALPHA_4; break; | ||
242 | case HIERARCHY_AUTO: break; | ||
243 | default: return -EINVAL; | ||
244 | } | ||
245 | if (ofdm->hierarchy_information == HIERARCHY_NONE) { | ||
246 | hrch = DIB3000_HRCH_OFF; | ||
247 | sel_hp = DIB3000_SELECT_HP; | ||
248 | fe_cr = ofdm->code_rate_HP; | ||
249 | } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) { | ||
250 | hrch = DIB3000_HRCH_ON; | ||
251 | sel_hp = DIB3000_SELECT_LP; | ||
252 | fe_cr = ofdm->code_rate_LP; | ||
253 | } | ||
254 | switch (fe_cr) { | ||
255 | case FEC_1_2: cr = DIB3000_FEC_1_2; break; | ||
256 | case FEC_2_3: cr = DIB3000_FEC_2_3; break; | ||
257 | case FEC_3_4: cr = DIB3000_FEC_3_4; break; | ||
258 | case FEC_5_6: cr = DIB3000_FEC_5_6; break; | ||
259 | case FEC_7_8: cr = DIB3000_FEC_7_8; break; | ||
260 | case FEC_NONE: break; | ||
261 | case FEC_AUTO: break; | ||
262 | default: return -EINVAL; | ||
263 | } | ||
264 | 262 | ||
265 | wr(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_PARM(alpha,qam,guard,fft)); | 263 | case BANDWIDTH_7_MHZ: |
266 | wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp,cr,hrch)); | 264 | bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7; |
265 | imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0; | ||
266 | break; | ||
267 | 267 | ||
268 | switch (fep->inversion) { | 268 | case BANDWIDTH_6_MHZ: |
269 | case INVERSION_OFF: | 269 | bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5; |
270 | wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); | 270 | imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089; |
271 | break; | 271 | break; |
272 | case INVERSION_AUTO: /* fall through */ | 272 | |
273 | case INVERSION_ON: | 273 | case 255 /* BANDWIDTH_5_MHZ */: |
274 | wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON); | 274 | bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500; |
275 | imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072; | ||
275 | break; | 276 | break; |
276 | default: | 277 | |
277 | return -EINVAL; | 278 | default: return -EINVAL; |
278 | } | 279 | } |
279 | 280 | ||
280 | seq = dib3000_seq | 281 | for (reg = 6; reg < 12; reg++) |
281 | [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO] | 282 | dib3000mc_write_word(state, reg, bw_cfg[reg - 6]); |
282 | [ofdm->guard_interval == GUARD_INTERVAL_AUTO] | 283 | dib3000mc_write_word(state, 12, 0x0000); |
283 | [fep->inversion == INVERSION_AUTO]; | 284 | dib3000mc_write_word(state, 13, 0x03e8); |
284 | 285 | dib3000mc_write_word(state, 14, 0x0000); | |
285 | deb_setf("seq? %d\n", seq); | 286 | dib3000mc_write_word(state, 15, 0x03f2); |
286 | wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1)); | 287 | dib3000mc_write_word(state, 16, 0x0001); |
287 | *auto_val = ofdm->constellation == QAM_AUTO || | 288 | dib3000mc_write_word(state, 17, 0xb0d0); |
288 | ofdm->hierarchy_information == HIERARCHY_AUTO || | 289 | // P_sec_len |
289 | ofdm->guard_interval == GUARD_INTERVAL_AUTO || | 290 | dib3000mc_write_word(state, 18, 0x0393); |
290 | ofdm->transmission_mode == TRANSMISSION_MODE_AUTO || | 291 | dib3000mc_write_word(state, 19, 0x8700); |
291 | fe_cr == FEC_AUTO || | ||
292 | fep->inversion == INVERSION_AUTO; | ||
293 | return 0; | ||
294 | } | ||
295 | 292 | ||
296 | static int dib3000mc_get_frontend(struct dvb_frontend* fe, | 293 | for (reg = 55; reg < 58; reg++) |
297 | struct dvb_frontend_parameters *fep) | 294 | dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]); |
298 | { | ||
299 | struct dib3000_state* state = fe->demodulator_priv; | ||
300 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; | ||
301 | fe_code_rate_t *cr; | ||
302 | u16 tps_val,cr_val; | ||
303 | int inv_test1,inv_test2; | ||
304 | u32 dds_val, threshold = 0x1000000; | ||
305 | |||
306 | if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507)) | ||
307 | return 0; | ||
308 | |||
309 | dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB); | ||
310 | deb_getf("DDS_FREQ: %6x\n",dds_val); | ||
311 | if (dds_val < threshold) | ||
312 | inv_test1 = 0; | ||
313 | else if (dds_val == threshold) | ||
314 | inv_test1 = 1; | ||
315 | else | ||
316 | inv_test1 = 2; | ||
317 | |||
318 | dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB); | ||
319 | deb_getf("DDS_SET_FREQ: %6x\n",dds_val); | ||
320 | if (dds_val < threshold) | ||
321 | inv_test2 = 0; | ||
322 | else if (dds_val == threshold) | ||
323 | inv_test2 = 1; | ||
324 | else | ||
325 | inv_test2 = 2; | ||
326 | 295 | ||
327 | fep->inversion = | 296 | // Timing configuration |
328 | ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) || | 297 | dib3000mc_set_timing(state, 0, bw, 0); |
329 | ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ? | ||
330 | INVERSION_ON : INVERSION_OFF; | ||
331 | 298 | ||
332 | deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion); | 299 | return 0; |
300 | } | ||
333 | 301 | ||
334 | fep->frequency = state->last_tuned_freq; | 302 | static u16 impulse_noise_val[29] = |
335 | fep->u.ofdm.bandwidth= state->last_tuned_bw; | ||
336 | 303 | ||
337 | tps_val = rd(DIB3000MC_REG_TUNING_PARM); | 304 | { |
305 | 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3, | ||
306 | 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2, | ||
307 | 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd | ||
308 | }; | ||
338 | 309 | ||
339 | switch (DIB3000MC_TP_QAM(tps_val)) { | 310 | static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft) |
340 | case DIB3000_CONSTELLATION_QPSK: | 311 | { |
341 | deb_getf("QPSK "); | 312 | u16 i; |
342 | ofdm->constellation = QPSK; | 313 | for (i = 58; i < 87; i++) |
343 | break; | 314 | dib3000mc_write_word(state, i, impulse_noise_val[i-58]); |
344 | case DIB3000_CONSTELLATION_16QAM: | 315 | |
345 | deb_getf("QAM16 "); | 316 | if (nfft == 1) { |
346 | ofdm->constellation = QAM_16; | 317 | dib3000mc_write_word(state, 58, 0x3b); |
347 | break; | 318 | dib3000mc_write_word(state, 84, 0x00); |
348 | case DIB3000_CONSTELLATION_64QAM: | 319 | dib3000mc_write_word(state, 85, 0x8200); |
349 | deb_getf("QAM64 "); | ||
350 | ofdm->constellation = QAM_64; | ||
351 | break; | ||
352 | default: | ||
353 | err("Unexpected constellation returned by TPS (%d)", tps_val); | ||
354 | break; | ||
355 | } | 320 | } |
356 | 321 | ||
357 | if (DIB3000MC_TP_HRCH(tps_val)) { | 322 | dib3000mc_write_word(state, 34, 0x1294); |
358 | deb_getf("HRCH ON "); | 323 | dib3000mc_write_word(state, 35, 0x1ff8); |
359 | cr = &ofdm->code_rate_LP; | 324 | if (mode == 1) |
360 | ofdm->code_rate_HP = FEC_NONE; | 325 | dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10)); |
361 | switch (DIB3000MC_TP_ALPHA(tps_val)) { | 326 | } |
362 | case DIB3000_ALPHA_0: | 327 | |
363 | deb_getf("HIERARCHY_NONE "); | 328 | static int dib3000mc_init(struct dvb_frontend *demod) |
364 | ofdm->hierarchy_information = HIERARCHY_NONE; | 329 | { |
365 | break; | 330 | struct dib3000mc_state *state = demod->demodulator_priv; |
366 | case DIB3000_ALPHA_1: | 331 | struct dibx000_agc_config *agc = state->cfg->agc; |
367 | deb_getf("HIERARCHY_1 "); | 332 | |
368 | ofdm->hierarchy_information = HIERARCHY_1; | 333 | // Restart Configuration |
369 | break; | 334 | dib3000mc_write_word(state, 1027, 0x8000); |
370 | case DIB3000_ALPHA_2: | 335 | dib3000mc_write_word(state, 1027, 0x0000); |
371 | deb_getf("HIERARCHY_2 "); | 336 | |
372 | ofdm->hierarchy_information = HIERARCHY_2; | 337 | // power up the demod + mobility configuration |
373 | break; | 338 | dib3000mc_write_word(state, 140, 0x0000); |
374 | case DIB3000_ALPHA_4: | 339 | dib3000mc_write_word(state, 1031, 0); |
375 | deb_getf("HIERARCHY_4 "); | 340 | |
376 | ofdm->hierarchy_information = HIERARCHY_4; | 341 | if (state->cfg->mobile_mode) { |
377 | break; | 342 | dib3000mc_write_word(state, 139, 0x0000); |
378 | default: | 343 | dib3000mc_write_word(state, 141, 0x0000); |
379 | err("Unexpected ALPHA value returned by TPS (%d)", tps_val); | 344 | dib3000mc_write_word(state, 175, 0x0002); |
380 | break; | 345 | dib3000mc_write_word(state, 1032, 0x0000); |
381 | } | ||
382 | cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val); | ||
383 | } else { | 346 | } else { |
384 | deb_getf("HRCH OFF "); | 347 | dib3000mc_write_word(state, 139, 0x0001); |
385 | cr = &ofdm->code_rate_HP; | 348 | dib3000mc_write_word(state, 141, 0x0000); |
386 | ofdm->code_rate_LP = FEC_NONE; | 349 | dib3000mc_write_word(state, 175, 0x0000); |
387 | ofdm->hierarchy_information = HIERARCHY_NONE; | 350 | dib3000mc_write_word(state, 1032, 0x012C); |
388 | cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val); | ||
389 | } | 351 | } |
352 | dib3000mc_write_word(state, 1033, 0); | ||
390 | 353 | ||
391 | switch (cr_val) { | 354 | // P_clk_cfg |
392 | case DIB3000_FEC_1_2: | 355 | dib3000mc_write_word(state, 1037, 12592); |
393 | deb_getf("FEC_1_2 "); | ||
394 | *cr = FEC_1_2; | ||
395 | break; | ||
396 | case DIB3000_FEC_2_3: | ||
397 | deb_getf("FEC_2_3 "); | ||
398 | *cr = FEC_2_3; | ||
399 | break; | ||
400 | case DIB3000_FEC_3_4: | ||
401 | deb_getf("FEC_3_4 "); | ||
402 | *cr = FEC_3_4; | ||
403 | break; | ||
404 | case DIB3000_FEC_5_6: | ||
405 | deb_getf("FEC_5_6 "); | ||
406 | *cr = FEC_4_5; | ||
407 | break; | ||
408 | case DIB3000_FEC_7_8: | ||
409 | deb_getf("FEC_7_8 "); | ||
410 | *cr = FEC_7_8; | ||
411 | break; | ||
412 | default: | ||
413 | err("Unexpected FEC returned by TPS (%d)", tps_val); | ||
414 | break; | ||
415 | } | ||
416 | 356 | ||
417 | switch (DIB3000MC_TP_GUARD(tps_val)) { | 357 | // other configurations |
418 | case DIB3000_GUARD_TIME_1_32: | ||
419 | deb_getf("GUARD_INTERVAL_1_32 "); | ||
420 | ofdm->guard_interval = GUARD_INTERVAL_1_32; | ||
421 | break; | ||
422 | case DIB3000_GUARD_TIME_1_16: | ||
423 | deb_getf("GUARD_INTERVAL_1_16 "); | ||
424 | ofdm->guard_interval = GUARD_INTERVAL_1_16; | ||
425 | break; | ||
426 | case DIB3000_GUARD_TIME_1_8: | ||
427 | deb_getf("GUARD_INTERVAL_1_8 "); | ||
428 | ofdm->guard_interval = GUARD_INTERVAL_1_8; | ||
429 | break; | ||
430 | case DIB3000_GUARD_TIME_1_4: | ||
431 | deb_getf("GUARD_INTERVAL_1_4 "); | ||
432 | ofdm->guard_interval = GUARD_INTERVAL_1_4; | ||
433 | break; | ||
434 | default: | ||
435 | err("Unexpected Guard Time returned by TPS (%d)", tps_val); | ||
436 | break; | ||
437 | } | ||
438 | 358 | ||
439 | switch (DIB3000MC_TP_FFT(tps_val)) { | 359 | // P_ctrl_sfreq |
440 | case DIB3000_TRANSMISSION_MODE_2K: | 360 | dib3000mc_write_word(state, 33, (5 << 0)); |
441 | deb_getf("TRANSMISSION_MODE_2K "); | 361 | dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0)); |
442 | ofdm->transmission_mode = TRANSMISSION_MODE_2K; | ||
443 | break; | ||
444 | case DIB3000_TRANSMISSION_MODE_8K: | ||
445 | deb_getf("TRANSMISSION_MODE_8K "); | ||
446 | ofdm->transmission_mode = TRANSMISSION_MODE_8K; | ||
447 | break; | ||
448 | default: | ||
449 | err("unexpected transmission mode return by TPS (%d)", tps_val); | ||
450 | break; | ||
451 | } | ||
452 | deb_getf("\n"); | ||
453 | 362 | ||
454 | return 0; | 363 | // Phase noise control |
455 | } | 364 | // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange |
365 | dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0)); | ||
456 | 366 | ||
457 | static int dib3000mc_set_frontend(struct dvb_frontend* fe, | 367 | if (state->cfg->phase_noise_mode == 0) |
458 | struct dvb_frontend_parameters *fep, int tuner) | 368 | dib3000mc_write_word(state, 111, 0x00); |
459 | { | 369 | else |
460 | struct dib3000_state* state = fe->demodulator_priv; | 370 | dib3000mc_write_word(state, 111, 0x02); |
461 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; | 371 | |
462 | int search_state,auto_val; | 372 | // P_agc_global |
463 | u16 val; | 373 | dib3000mc_write_word(state, 50, 0x8000); |
464 | 374 | ||
465 | if (tuner && state->config.pll_set) { /* initial call from dvb */ | 375 | // agc setup misc |
466 | state->config.pll_set(fe,fep); | 376 | dib3000mc_setup_pwm3_state(state); |
467 | 377 | ||
468 | state->last_tuned_freq = fep->frequency; | 378 | // P_agc_counter_lock |
469 | // if (!scanboost) { | 379 | dib3000mc_write_word(state, 53, 0x87); |
470 | dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth); | 380 | // P_agc_counter_unlock |
471 | dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0); | 381 | dib3000mc_write_word(state, 54, 0x87); |
472 | state->last_tuned_bw = ofdm->bandwidth; | 382 | |
473 | 383 | /* agc */ | |
474 | wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth); | 384 | dib3000mc_write_word(state, 36, state->cfg->max_time); |
475 | wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC); | 385 | dib3000mc_write_word(state, 37, agc->setup); |
476 | wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF); | 386 | dib3000mc_write_word(state, 38, state->cfg->pwm3_value); |
477 | 387 | dib3000mc_write_word(state, 39, state->cfg->ln_adc_level); | |
478 | /* Default cfg isi offset adp */ | 388 | |
479 | wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]); | 389 | // set_agc_loop_Bw |
480 | 390 | dib3000mc_write_word(state, 40, 0x0179); | |
481 | wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT); | 391 | dib3000mc_write_word(state, 41, 0x03f0); |
482 | dib3000mc_set_adp_cfg(state,ofdm->constellation); | 392 | |
483 | wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133); | 393 | dib3000mc_write_word(state, 42, agc->agc1_max); |
484 | 394 | dib3000mc_write_word(state, 43, agc->agc1_min); | |
485 | wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general); | 395 | dib3000mc_write_word(state, 44, agc->agc2_max); |
486 | /* power smoothing */ | 396 | dib3000mc_write_word(state, 45, agc->agc2_min); |
487 | if (ofdm->bandwidth != BANDWIDTH_8_MHZ) { | 397 | dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2); |
488 | wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]); | 398 | dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2); |
489 | } else { | 399 | dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2); |
490 | wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]); | 400 | dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2); |
491 | } | 401 | |
492 | auto_val = 0; | 402 | // Begin: TimeOut registers |
493 | dib3000mc_set_general_cfg(state,fep,&auto_val); | 403 | // P_pha3_thres |
494 | dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth); | 404 | dib3000mc_write_word(state, 110, 3277); |
495 | 405 | // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80 | |
496 | val = rd(DIB3000MC_REG_DEMOD_PARM); | 406 | dib3000mc_write_word(state, 26, 0x6680); |
497 | wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON); | 407 | // lock_mask0 |
498 | wr(DIB3000MC_REG_DEMOD_PARM,val); | 408 | dib3000mc_write_word(state, 1, 4); |
499 | // } | 409 | // lock_mask1 |
500 | msleep(70); | 410 | dib3000mc_write_word(state, 2, 4); |
501 | 411 | // lock_mask2 | |
502 | /* something has to be auto searched */ | 412 | dib3000mc_write_word(state, 3, 0x1000); |
503 | if (auto_val) { | 413 | // P_search_maxtrial=1 |
504 | int as_count=0; | 414 | dib3000mc_write_word(state, 5, 1); |
505 | 415 | ||
506 | deb_setf("autosearch enabled.\n"); | 416 | dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ); |
507 | 417 | ||
508 | val = rd(DIB3000MC_REG_DEMOD_PARM); | 418 | // div_lock_mask |
509 | wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); | 419 | dib3000mc_write_word(state, 4, 0x814); |
510 | wr(DIB3000MC_REG_DEMOD_PARM,val); | 420 | |
511 | 421 | dib3000mc_write_word(state, 21, (1 << 9) | 0x164); | |
512 | while ((search_state = dib3000_search_status( | 422 | dib3000mc_write_word(state, 22, 0x463d); |
513 | rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100) | 423 | |
514 | msleep(10); | 424 | // Spurious rm cfg |
515 | 425 | // P_cspu_regul, P_cspu_win_cut | |
516 | deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count); | 426 | dib3000mc_write_word(state, 120, 0x200f); |
517 | 427 | // P_adp_selec_monit | |
518 | if (search_state == 1) { | 428 | dib3000mc_write_word(state, 134, 0); |
519 | struct dvb_frontend_parameters feps; | 429 | |
520 | if (dib3000mc_get_frontend(fe, &feps) == 0) { | 430 | // Fec cfg |
521 | deb_setf("reading tuning data from frontend succeeded.\n"); | 431 | dib3000mc_write_word(state, 195, 0x10); |
522 | return dib3000mc_set_frontend(fe, &feps, 0); | 432 | |
523 | } | 433 | // diversity register: P_dvsy_sync_wait.. |
524 | } | 434 | dib3000mc_write_word(state, 180, 0x2FF0); |
525 | } else { | 435 | |
526 | dib3000mc_set_impulse_noise(state,0,ofdm->transmission_mode,ofdm->bandwidth); | 436 | // Impulse noise configuration |
527 | wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE); | 437 | dib3000mc_set_impulse_noise(state, 0, 1); |
528 | dib3000mc_set_adp_cfg(state,ofdm->constellation); | 438 | |
529 | 439 | // output mode set-up | |
530 | /* set_offset_cfg */ | 440 | dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); |
531 | wr_foreach(dib3000mc_reg_offset, | 441 | |
532 | dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); | 442 | /* close the i2c-gate */ |
533 | } | 443 | dib3000mc_write_word(state, 769, (1 << 7) ); |
534 | } else { /* second call, after autosearch (fka: set_WithKnownParams) */ | ||
535 | // dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth); | ||
536 | 444 | ||
537 | auto_val = 0; | 445 | return 0; |
538 | dib3000mc_set_general_cfg(state,fep,&auto_val); | 446 | } |
539 | if (auto_val) | ||
540 | deb_info("auto_val is true, even though an auto search was already performed.\n"); | ||
541 | 447 | ||
542 | dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth); | 448 | static int dib3000mc_sleep(struct dvb_frontend *demod) |
449 | { | ||
450 | struct dib3000mc_state *state = demod->demodulator_priv; | ||
543 | 451 | ||
544 | val = rd(DIB3000MC_REG_DEMOD_PARM); | 452 | dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003); |
545 | wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); | 453 | dib3000mc_write_word(state, 1031, 0xFFFF); |
546 | wr(DIB3000MC_REG_DEMOD_PARM,val); | 454 | dib3000mc_write_word(state, 1032, 0xFFFF); |
455 | dib3000mc_write_word(state, 1033, 0xFFF4); // **** Bin2 | ||
547 | 456 | ||
548 | msleep(30); | 457 | return 0; |
458 | } | ||
549 | 459 | ||
550 | wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE); | 460 | static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam) |
551 | dib3000mc_set_adp_cfg(state,ofdm->constellation); | 461 | { |
552 | wr_foreach(dib3000mc_reg_offset, | 462 | u16 cfg[4] = { 0 },reg; |
553 | dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); | 463 | switch (qam) { |
464 | case 0: | ||
465 | cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0; | ||
466 | break; | ||
467 | case 1: | ||
468 | cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0; | ||
469 | break; | ||
470 | case 2: | ||
471 | cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8; | ||
472 | break; | ||
554 | } | 473 | } |
555 | return 0; | 474 | for (reg = 129; reg < 133; reg++) |
475 | dib3000mc_write_word(state, reg, cfg[reg - 129]); | ||
556 | } | 476 | } |
557 | 477 | ||
558 | static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) | 478 | static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq) |
559 | { | 479 | { |
560 | struct dib3000_state *state = fe->demodulator_priv; | 480 | u16 tmp; |
561 | const struct dib3000p_agc_config *agc = state->config.agc; | ||
562 | deb_info("init start\n"); | ||
563 | 481 | ||
564 | state->timing_offset = 0; | 482 | dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0); |
565 | state->timing_offset_comp_done = 0; | ||
566 | 483 | ||
567 | wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG); | 484 | // if (boost) |
568 | wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF); | 485 | // dib3000mc_write_word(state, 100, (11 << 6) + 6); |
569 | wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP); | 486 | // else |
570 | wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE); | 487 | dib3000mc_write_word(state, 100, (16 << 6) + 9); |
571 | wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP); | ||
572 | wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT); | ||
573 | 488 | ||
574 | wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF); | 489 | dib3000mc_write_word(state, 1027, 0x0800); |
575 | wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19); | 490 | dib3000mc_write_word(state, 1027, 0x0000); |
576 | 491 | ||
577 | wr(33,5); | 492 | //Default cfg isi offset adp |
578 | wr(36,81); | 493 | dib3000mc_write_word(state, 26, 0x6680); |
579 | wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88); | 494 | dib3000mc_write_word(state, 29, 0x1273); |
495 | dib3000mc_write_word(state, 33, 5); | ||
496 | dib3000mc_set_adp_cfg(state, 1); | ||
497 | dib3000mc_write_word(state, 133, 15564); | ||
580 | 498 | ||
581 | wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99); | 499 | dib3000mc_write_word(state, 12 , 0x0); |
582 | wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */ | 500 | dib3000mc_write_word(state, 13 , 0x3e8); |
501 | dib3000mc_write_word(state, 14 , 0x0); | ||
502 | dib3000mc_write_word(state, 15 , 0x3f2); | ||
583 | 503 | ||
584 | /* mobile mode - portable reception */ | 504 | dib3000mc_write_word(state, 93,0); |
585 | wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]); | 505 | dib3000mc_write_word(state, 94,0); |
506 | dib3000mc_write_word(state, 95,0); | ||
507 | dib3000mc_write_word(state, 96,0); | ||
508 | dib3000mc_write_word(state, 97,0); | ||
509 | dib3000mc_write_word(state, 98,0); | ||
586 | 510 | ||
587 | /* AGC settings for all tuners */ | 511 | dib3000mc_set_impulse_noise(state, 0, chan->nfft); |
588 | wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth); | ||
589 | wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general); | ||
590 | 512 | ||
591 | /* AGC setting - specific to the tuners */ | 513 | tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha; |
592 | wr(36, agc->val[0]); | 514 | dib3000mc_write_word(state, 0, tmp); |
593 | wr(37, agc->val[1]); | ||
594 | wr(38, agc->val[2]); | ||
595 | wr(39, agc->val[3]); | ||
596 | 515 | ||
597 | wr(42, agc->val[4]); | 516 | dib3000mc_write_word(state, 5, seq); |
598 | wr(43, agc->val[5]); | ||
599 | wr(44, agc->val[6]); | ||
600 | wr(45, agc->val[7]); | ||
601 | wr(46, agc->val[8]); | ||
602 | wr(47, agc->val[9]); | ||
603 | wr(48, agc->val[10]); | ||
604 | wr(49, agc->val[11]); | ||
605 | 517 | ||
606 | wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110); | 518 | tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp); |
607 | wr(26,0x6680); | 519 | if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp)) |
608 | wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1); | 520 | tmp |= chan->vit_code_rate_hp << 1; |
609 | wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2); | 521 | else |
610 | wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3); | 522 | tmp |= chan->vit_code_rate_lp << 1; |
611 | wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT); | 523 | dib3000mc_write_word(state, 181, tmp); |
612 | 524 | ||
613 | wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz); | 525 | // diversity synchro delay |
614 | wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general); | 526 | tmp = dib3000mc_read_word(state, 180) & 0x000f; |
527 | tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin | ||
528 | dib3000mc_write_word(state, 180, tmp); | ||
615 | 529 | ||
616 | wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4); | 530 | // restart demod |
531 | tmp = dib3000mc_read_word(state, 0); | ||
532 | dib3000mc_write_word(state, 0, tmp | (1 << 9)); | ||
533 | dib3000mc_write_word(state, 0, tmp); | ||
617 | 534 | ||
618 | wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); | 535 | msleep(30); |
619 | wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB); | ||
620 | 536 | ||
621 | dib3000mc_set_timing(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); | 537 | dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft); |
622 | // wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]); | 538 | } |
623 | 539 | ||
624 | wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120); | 540 | static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan) |
625 | wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134); | 541 | { |
626 | wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG); | 542 | struct dib3000mc_state *state = demod->demodulator_priv; |
543 | u16 reg; | ||
544 | // u32 val; | ||
545 | struct dibx000_ofdm_channel fchan; | ||
627 | 546 | ||
628 | wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF); | 547 | INIT_OFDM_CHANNEL(&fchan); |
548 | fchan = *chan; | ||
629 | 549 | ||
630 | dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); | ||
631 | 550 | ||
632 | /* output mode control, just the MPEG2_SLAVE */ | 551 | /* a channel for autosearch */ |
633 | // set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); | 552 | reg = 0; |
634 | wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); | 553 | if (chan->nfft == -1 && chan->guard == -1) reg = 7; |
635 | wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE); | 554 | if (chan->nfft == -1 && chan->guard != -1) reg = 2; |
636 | wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE); | 555 | if (chan->nfft != -1 && chan->guard == -1) reg = 3; |
637 | wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE); | ||
638 | 556 | ||
639 | /* MPEG2_PARALLEL_CONTINUOUS_CLOCK | 557 | fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2; |
640 | wr(DIB3000MC_REG_OUTMODE, | 558 | fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2; |
641 | DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK, | 559 | fchan.vit_hrch = 0; fchan.vit_select_hp = 1; |
642 | rd(DIB3000MC_REG_OUTMODE))); | ||
643 | 560 | ||
644 | wr(DIB3000MC_REG_SMO_MODE, | 561 | dib3000mc_set_channel_cfg(state, &fchan, reg); |
645 | DIB3000MC_SMO_MODE_DEFAULT | | ||
646 | DIB3000MC_SMO_MODE_188); | ||
647 | 562 | ||
648 | wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT); | 563 | reg = dib3000mc_read_word(state, 0); |
649 | wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON); | 564 | dib3000mc_write_word(state, 0, reg | (1 << 8)); |
650 | */ | 565 | dib3000mc_write_word(state, 0, reg); |
651 | 566 | ||
652 | /* diversity */ | 567 | return 0; |
653 | wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT); | 568 | } |
654 | wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT); | ||
655 | 569 | ||
656 | set_and(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF); | 570 | static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod) |
571 | { | ||
572 | struct dib3000mc_state *state = demod->demodulator_priv; | ||
573 | u16 irq_pending = dib3000mc_read_word(state, 511); | ||
657 | 574 | ||
658 | set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); | 575 | if (irq_pending & 0x1) // failed |
576 | return 1; | ||
659 | 577 | ||
660 | if (state->config.pll_init) | 578 | if (irq_pending & 0x2) // succeeded |
661 | state->config.pll_init(fe); | 579 | return 2; |
662 | 580 | ||
663 | deb_info("init end\n"); | 581 | return 0; // still pending |
664 | return 0; | ||
665 | } | 582 | } |
666 | static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat) | 583 | |
584 | static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch) | ||
667 | { | 585 | { |
668 | struct dib3000_state* state = fe->demodulator_priv; | 586 | struct dib3000mc_state *state = demod->demodulator_priv; |
669 | u16 lock = rd(DIB3000MC_REG_LOCKING); | ||
670 | 587 | ||
671 | *stat = 0; | 588 | // ** configure demod ** |
672 | if (DIB3000MC_AGC_LOCK(lock)) | 589 | dib3000mc_set_channel_cfg(state, ch, 0); |
673 | *stat |= FE_HAS_SIGNAL; | 590 | |
674 | if (DIB3000MC_CARRIER_LOCK(lock)) | 591 | // activates isi |
675 | *stat |= FE_HAS_CARRIER; | 592 | dib3000mc_write_word(state, 29, 0x1073); |
676 | if (DIB3000MC_TPS_LOCK(lock)) | ||
677 | *stat |= FE_HAS_VITERBI; | ||
678 | if (DIB3000MC_MPEG_SYNC_LOCK(lock)) | ||
679 | *stat |= (FE_HAS_SYNC | FE_HAS_LOCK); | ||
680 | 593 | ||
681 | deb_stat("actual status is %2x fifo_level: %x,244: %x, 206: %x, 207: %x, 1040: %x\n",*stat,rd(510),rd(244),rd(206),rd(207),rd(1040)); | 594 | dib3000mc_set_adp_cfg(state, (u8)ch->nqam); |
595 | |||
596 | if (ch->nfft == 1) { | ||
597 | dib3000mc_write_word(state, 26, 38528); | ||
598 | dib3000mc_write_word(state, 33, 8); | ||
599 | } else { | ||
600 | dib3000mc_write_word(state, 26, 30336); | ||
601 | dib3000mc_write_word(state, 33, 6); | ||
602 | } | ||
603 | |||
604 | // if (lock) | ||
605 | // dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1); | ||
682 | 606 | ||
683 | return 0; | 607 | return 0; |
684 | } | 608 | } |
685 | 609 | ||
686 | static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber) | 610 | static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode) |
687 | { | 611 | { |
688 | struct dib3000_state* state = fe->demodulator_priv; | 612 | struct dib3000mc_state *state = demod->demodulator_priv; |
689 | *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB)); | 613 | return dib3000mc_set_output_mode(state, mode); |
690 | return 0; | ||
691 | } | 614 | } |
692 | 615 | ||
693 | static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) | 616 | static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr) |
694 | { | 617 | { |
695 | struct dib3000_state* state = fe->demodulator_priv; | 618 | struct dib3000mc_state *st; |
619 | int k,ret=0; | ||
620 | u8 new_addr; | ||
621 | |||
622 | static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26}; | ||
623 | |||
624 | for (k = no_of_demods-1; k >= 0; k--) { | ||
625 | st = demod[k]->demodulator_priv; | ||
626 | |||
627 | /* designated i2c address */ | ||
628 | new_addr = DIB3000MC_I2C_ADDRESS[k]; | ||
629 | |||
630 | st->i2c_addr = new_addr; | ||
631 | if (dib3000mc_identify(st) != 0) { | ||
632 | st->i2c_addr = default_addr; | ||
633 | if (dib3000mc_identify(st) != 0) { | ||
634 | dprintk("-E- DiB3000P/MC #%d: not identified\n", k); | ||
635 | return -EINVAL; | ||
636 | } | ||
637 | } | ||
638 | |||
639 | /* turn on div_out */ | ||
640 | dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK); | ||
641 | |||
642 | // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0) | ||
643 | ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1); | ||
644 | st->i2c_addr = new_addr; | ||
645 | } | ||
696 | 646 | ||
697 | *unc = rd(DIB3000MC_REG_PACKET_ERRORS); | 647 | for (k = 0; k < no_of_demods; k++) { |
648 | st = demod[k]->demodulator_priv; | ||
649 | |||
650 | ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3); | ||
651 | |||
652 | /* turn off data output */ | ||
653 | dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z); | ||
654 | dib3000mc_write_word(st, 769, (1 << 7) ); | ||
655 | |||
656 | } | ||
698 | return 0; | 657 | return 0; |
699 | } | 658 | } |
700 | 659 | ||
701 | /* see dib3000mb.c for calculation comments */ | 660 | struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating) |
702 | static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength) | ||
703 | { | 661 | { |
704 | struct dib3000_state* state = fe->demodulator_priv; | 662 | struct dib3000mc_state *st = demod->demodulator_priv; |
705 | u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB); | 663 | return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating); |
706 | *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f); | ||
707 | |||
708 | deb_stat("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff); | ||
709 | return 0; | ||
710 | } | 664 | } |
711 | 665 | ||
712 | /* see dib3000mb.c for calculation comments */ | 666 | EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master); |
713 | static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) | 667 | |
668 | static int dib3000mc_get_frontend(struct dvb_frontend* fe, | ||
669 | struct dvb_frontend_parameters *fep) | ||
714 | { | 670 | { |
715 | struct dib3000_state* state = fe->demodulator_priv; | 671 | struct dib3000mc_state *state = fe->demodulator_priv; |
716 | u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB), | 672 | u16 tps = dib3000mc_read_word(state,458); |
717 | val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB); | ||
718 | u16 sig,noise; | ||
719 | 673 | ||
720 | sig = (((val >> 6) & 0xff) << 8) + (val & 0x3f); | 674 | fep->inversion = INVERSION_AUTO; |
721 | noise = (((val >> 4) & 0xff) << 8) + ((val & 0xf) << 2) + ((val2 >> 14) & 0x3); | 675 | |
722 | if (noise == 0) | 676 | fep->u.ofdm.bandwidth = state->current_bandwidth; |
723 | *snr = 0xffff; | 677 | |
724 | else | 678 | switch ((tps >> 8) & 0x1) { |
725 | *snr = (u16) sig/noise; | 679 | case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; |
680 | case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; | ||
681 | } | ||
682 | |||
683 | switch (tps & 0x3) { | ||
684 | case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; | ||
685 | case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; | ||
686 | case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; | ||
687 | case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; | ||
688 | } | ||
689 | |||
690 | switch ((tps >> 13) & 0x3) { | ||
691 | case 0: fep->u.ofdm.constellation = QPSK; break; | ||
692 | case 1: fep->u.ofdm.constellation = QAM_16; break; | ||
693 | case 2: | ||
694 | default: fep->u.ofdm.constellation = QAM_64; break; | ||
695 | } | ||
696 | |||
697 | /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ | ||
698 | /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */ | ||
699 | |||
700 | fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; | ||
701 | switch ((tps >> 5) & 0x7) { | ||
702 | case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; | ||
703 | case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; | ||
704 | case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; | ||
705 | case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; | ||
706 | case 7: | ||
707 | default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; | ||
708 | |||
709 | } | ||
710 | |||
711 | switch ((tps >> 2) & 0x7) { | ||
712 | case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; | ||
713 | case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; | ||
714 | case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; | ||
715 | case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; | ||
716 | case 7: | ||
717 | default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; | ||
718 | } | ||
726 | 719 | ||
727 | deb_stat("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff); | ||
728 | deb_stat("noise: mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff); | ||
729 | deb_stat("snr: %d\n",*snr); | ||
730 | return 0; | 720 | return 0; |
731 | } | 721 | } |
732 | 722 | ||
733 | static int dib3000mc_sleep(struct dvb_frontend* fe) | 723 | static int dib3000mc_set_frontend(struct dvb_frontend* fe, |
724 | struct dvb_frontend_parameters *fep) | ||
734 | { | 725 | { |
735 | struct dib3000_state* state = fe->demodulator_priv; | 726 | struct dib3000mc_state *state = fe->demodulator_priv; |
727 | struct dibx000_ofdm_channel ch; | ||
736 | 728 | ||
737 | set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN); | 729 | INIT_OFDM_CHANNEL(&ch); |
738 | wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN); | 730 | FEP2DIB(fep,&ch); |
739 | wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_POWER_DOWN); | 731 | |
740 | wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_DOWN); | 732 | dump_fep(&ch); |
741 | return 0; | 733 | |
734 | state->current_bandwidth = fep->u.ofdm.bandwidth; | ||
735 | dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth); | ||
736 | |||
737 | if (fe->ops.tuner_ops.set_params) { | ||
738 | fe->ops.tuner_ops.set_params(fe, fep); | ||
739 | msleep(100); | ||
740 | } | ||
741 | |||
742 | if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || | ||
743 | fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || | ||
744 | fep->u.ofdm.constellation == QAM_AUTO || | ||
745 | fep->u.ofdm.code_rate_HP == FEC_AUTO) { | ||
746 | int i = 100, found; | ||
747 | |||
748 | dib3000mc_autosearch_start(fe, &ch); | ||
749 | do { | ||
750 | msleep(1); | ||
751 | found = dib3000mc_autosearch_is_irq(fe); | ||
752 | } while (found == 0 && i--); | ||
753 | |||
754 | dprintk("autosearch returns: %d\n",found); | ||
755 | if (found == 0 || found == 1) | ||
756 | return 0; // no channel found | ||
757 | |||
758 | dib3000mc_get_frontend(fe, fep); | ||
759 | FEP2DIB(fep,&ch); | ||
760 | } | ||
761 | |||
762 | /* make this a config parameter */ | ||
763 | dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO); | ||
764 | |||
765 | return dib3000mc_tune(fe, &ch); | ||
742 | } | 766 | } |
743 | 767 | ||
744 | static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) | 768 | static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat) |
745 | { | 769 | { |
746 | tune->min_delay_ms = 1000; | 770 | struct dib3000mc_state *state = fe->demodulator_priv; |
771 | u16 lock = dib3000mc_read_word(state, 509); | ||
772 | |||
773 | *stat = 0; | ||
774 | |||
775 | if (lock & 0x8000) | ||
776 | *stat |= FE_HAS_SIGNAL; | ||
777 | if (lock & 0x3000) | ||
778 | *stat |= FE_HAS_CARRIER; | ||
779 | if (lock & 0x0100) | ||
780 | *stat |= FE_HAS_VITERBI; | ||
781 | if (lock & 0x0010) | ||
782 | *stat |= FE_HAS_SYNC; | ||
783 | if (lock & 0x0008) | ||
784 | *stat |= FE_HAS_LOCK; | ||
785 | |||
747 | return 0; | 786 | return 0; |
748 | } | 787 | } |
749 | 788 | ||
750 | static int dib3000mc_fe_init_nonmobile(struct dvb_frontend* fe) | 789 | static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber) |
751 | { | 790 | { |
752 | return dib3000mc_fe_init(fe, 0); | 791 | struct dib3000mc_state *state = fe->demodulator_priv; |
792 | *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501); | ||
793 | return 0; | ||
753 | } | 794 | } |
754 | 795 | ||
755 | static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) | 796 | static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) |
756 | { | 797 | { |
757 | return dib3000mc_set_frontend(fe, fep, 1); | 798 | struct dib3000mc_state *state = fe->demodulator_priv; |
799 | *unc = dib3000mc_read_word(state, 508); | ||
800 | return 0; | ||
758 | } | 801 | } |
759 | 802 | ||
760 | static void dib3000mc_release(struct dvb_frontend* fe) | 803 | static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength) |
761 | { | 804 | { |
762 | struct dib3000_state *state = fe->demodulator_priv; | 805 | struct dib3000mc_state *state = fe->demodulator_priv; |
763 | kfree(state); | 806 | u16 val = dib3000mc_read_word(state, 392); |
807 | *strength = 65535 - val; | ||
808 | return 0; | ||
764 | } | 809 | } |
765 | 810 | ||
766 | /* pid filter and transfer stuff */ | 811 | static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) |
767 | static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff) | ||
768 | { | 812 | { |
769 | struct dib3000_state *state = fe->demodulator_priv; | 813 | *snr = 0x0000; |
770 | pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0); | ||
771 | wr(index+DIB3000MC_REG_FIRST_PID,pid); | ||
772 | return 0; | 814 | return 0; |
773 | } | 815 | } |
774 | 816 | ||
775 | static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff) | 817 | static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) |
776 | { | 818 | { |
777 | struct dib3000_state *state = fe->demodulator_priv; | 819 | tune->min_delay_ms = 1000; |
778 | u16 tmp = rd(DIB3000MC_REG_SMO_MODE); | ||
779 | |||
780 | deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); | ||
781 | |||
782 | if (onoff) { | ||
783 | deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH); | ||
784 | wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH); | ||
785 | } else { | ||
786 | deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH); | ||
787 | wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH); | ||
788 | } | ||
789 | return 0; | 820 | return 0; |
790 | } | 821 | } |
791 | 822 | ||
792 | static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) | 823 | static void dib3000mc_release(struct dvb_frontend *fe) |
793 | { | 824 | { |
794 | struct dib3000_state *state = fe->demodulator_priv; | 825 | struct dib3000mc_state *state = fe->demodulator_priv; |
795 | u16 tmp = rd(DIB3000MC_REG_SMO_MODE); | 826 | dibx000_exit_i2c_master(&state->i2c_master); |
796 | 827 | kfree(state); | |
797 | deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling"); | ||
798 | |||
799 | if (onoff) { | ||
800 | wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE); | ||
801 | } else { | ||
802 | wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE); | ||
803 | } | ||
804 | return 0; | ||
805 | } | 828 | } |
806 | 829 | ||
807 | static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) | 830 | int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff) |
808 | { | 831 | { |
809 | struct dib3000_state *state = fe->demodulator_priv; | 832 | struct dib3000mc_state *state = fe->demodulator_priv; |
810 | if (onoff) { | 833 | dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0); |
811 | wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); | ||
812 | } else { | ||
813 | wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr)); | ||
814 | } | ||
815 | return 0; | 834 | return 0; |
816 | } | 835 | } |
836 | EXPORT_SYMBOL(dib3000mc_pid_control); | ||
817 | 837 | ||
818 | static int dib3000mc_demod_init(struct dib3000_state *state) | 838 | int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) |
819 | { | 839 | { |
820 | u16 default_addr = 0x0a; | 840 | struct dib3000mc_state *state = fe->demodulator_priv; |
821 | /* first init */ | 841 | u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4); |
822 | if (state->config.demod_address != default_addr) { | 842 | tmp |= (onoff << 4); |
823 | deb_info("initializing the demod the first time. Setting demod addr to 0x%x\n",default_addr); | 843 | return dib3000mc_write_word(state, 206, tmp); |
824 | wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON); | ||
825 | wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK); | ||
826 | |||
827 | wr(DIB3000MC_REG_RST_I2C_ADDR, | ||
828 | DIB3000MC_DEMOD_ADDR(default_addr) | | ||
829 | DIB3000MC_DEMOD_ADDR_ON); | ||
830 | |||
831 | state->config.demod_address = default_addr; | ||
832 | |||
833 | wr(DIB3000MC_REG_RST_I2C_ADDR, | ||
834 | DIB3000MC_DEMOD_ADDR(default_addr)); | ||
835 | } else | ||
836 | deb_info("demod is already initialized. Demod addr: 0x%x\n",state->config.demod_address); | ||
837 | return 0; | ||
838 | } | 844 | } |
845 | EXPORT_SYMBOL(dib3000mc_pid_parse); | ||
839 | 846 | ||
840 | int dib3000mc_set_agc_config(struct dvb_frontend *fe, const struct dib3000p_agc_config *agc) | 847 | void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg) |
841 | { | 848 | { |
842 | struct dib3000_state *st = fe->demodulator_priv; | 849 | struct dib3000mc_state *state = fe->demodulator_priv; |
843 | st->config.agc = agc; | 850 | state->cfg = cfg; |
844 | return 0; | ||
845 | } | 851 | } |
846 | EXPORT_SYMBOL(dib3000mc_set_agc_config); | 852 | EXPORT_SYMBOL(dib3000mc_set_config); |
847 | 853 | ||
848 | static struct dvb_frontend_ops dib3000mc_ops; | 854 | static struct dvb_frontend_ops dib3000mc_ops; |
849 | 855 | ||
850 | struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, | 856 | int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr, u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[]) |
851 | struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) | ||
852 | { | 857 | { |
853 | struct dib3000_state* state = NULL; | 858 | struct dib3000mc_state *st; |
854 | u16 devid; | 859 | int k, num=0; |
855 | 860 | ||
856 | /* allocate memory for the internal state */ | 861 | if (no_of_demods < 1) |
857 | state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL); | 862 | return -EINVAL; |
858 | if (state == NULL) | ||
859 | goto error; | ||
860 | 863 | ||
861 | /* setup the state */ | 864 | for (k = 0; k < no_of_demods; k++) { |
862 | state->i2c = i2c; | 865 | st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL); |
863 | memcpy(&state->config,config,sizeof(struct dib3000_config)); | 866 | if (st == NULL) |
864 | memcpy(&state->ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); | 867 | goto error; |
865 | 868 | ||
866 | /* check for the correct demod */ | 869 | num++; |
867 | if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) | ||
868 | goto error; | ||
869 | 870 | ||
870 | devid = rd(DIB3000_REG_DEVICE_ID); | 871 | st->cfg = &cfg[k]; |
871 | if (devid != DIB3000MC_DEVICE_ID && devid != DIB3000P_DEVICE_ID) | 872 | // st->gpio_val = cfg[k].gpio_val; |
872 | goto error; | 873 | // st->gpio_dir = cfg[k].gpio_dir; |
874 | st->i2c_adap = i2c_adap; | ||
873 | 875 | ||
874 | switch (devid) { | 876 | demod[k] = &st->demod; |
875 | case DIB3000MC_DEVICE_ID: | 877 | demod[k]->demodulator_priv = st; |
876 | info("Found a DiBcom 3000M-C, interesting..."); | 878 | memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); |
877 | break; | ||
878 | case DIB3000P_DEVICE_ID: | ||
879 | info("Found a DiBcom 3000P."); | ||
880 | break; | ||
881 | } | ||
882 | 879 | ||
883 | /* create dvb_frontend */ | 880 | // INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st); |
884 | state->frontend.ops = &state->ops; | 881 | // demod[k]->register_access = &st->register_access; |
885 | state->frontend.demodulator_priv = state; | 882 | } |
886 | 883 | ||
887 | /* set the xfer operations */ | 884 | if (do_i2c_enum) { |
888 | xfer_ops->pid_parse = dib3000mc_pid_parse; | 885 | if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0) |
889 | xfer_ops->fifo_ctrl = dib3000mc_fifo_control; | 886 | goto error; |
890 | xfer_ops->pid_ctrl = dib3000mc_pid_control; | 887 | } else { |
891 | xfer_ops->tuner_pass_ctrl = dib3000mc_tuner_pass_ctrl; | 888 | st = demod[0]->demodulator_priv; |
889 | st->i2c_addr = default_addr; | ||
890 | if (dib3000mc_identify(st) != 0) | ||
891 | goto error; | ||
892 | } | ||
892 | 893 | ||
893 | dib3000mc_demod_init(state); | 894 | for (k = 0; k < num; k++) { |
895 | st = demod[k]->demodulator_priv; | ||
896 | dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr); | ||
897 | } | ||
894 | 898 | ||
895 | return &state->frontend; | 899 | return 0; |
896 | 900 | ||
897 | error: | 901 | error: |
898 | kfree(state); | 902 | for (k = 0; k < num; k++) |
899 | return NULL; | 903 | kfree(demod[k]->demodulator_priv); |
904 | |||
905 | return -EINVAL; | ||
900 | } | 906 | } |
907 | |||
901 | EXPORT_SYMBOL(dib3000mc_attach); | 908 | EXPORT_SYMBOL(dib3000mc_attach); |
902 | 909 | ||
903 | static struct dvb_frontend_ops dib3000mc_ops = { | 910 | static struct dvb_frontend_ops dib3000mc_ops = { |
904 | |||
905 | .info = { | 911 | .info = { |
906 | .name = "DiBcom 3000P/M-C DVB-T", | 912 | .name = "DiBcom 3000MC/P", |
907 | .type = FE_OFDM, | 913 | .type = FE_OFDM, |
908 | .frequency_min = 44250000, | 914 | .frequency_min = 44250000, |
909 | .frequency_max = 867250000, | 915 | .frequency_max = 867250000, |
910 | .frequency_stepsize = 62500, | 916 | .frequency_stepsize = 62500, |
911 | .caps = FE_CAN_INVERSION_AUTO | | 917 | .caps = FE_CAN_INVERSION_AUTO | |
912 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 918 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
913 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | 919 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
914 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | 920 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | |
915 | FE_CAN_TRANSMISSION_MODE_AUTO | | 921 | FE_CAN_TRANSMISSION_MODE_AUTO | |
916 | FE_CAN_GUARD_INTERVAL_AUTO | | 922 | FE_CAN_GUARD_INTERVAL_AUTO | |
917 | FE_CAN_RECOVER | | 923 | FE_CAN_RECOVER | |
918 | FE_CAN_HIERARCHY_AUTO, | 924 | FE_CAN_HIERARCHY_AUTO, |
919 | }, | 925 | }, |
920 | 926 | ||
921 | .release = dib3000mc_release, | 927 | .release = dib3000mc_release, |
922 | 928 | ||
923 | .init = dib3000mc_fe_init_nonmobile, | 929 | .init = dib3000mc_init, |
924 | .sleep = dib3000mc_sleep, | 930 | .sleep = dib3000mc_sleep, |
925 | 931 | ||
926 | .set_frontend = dib3000mc_set_frontend_and_tuner, | 932 | .set_frontend = dib3000mc_set_frontend, |
927 | .get_frontend = dib3000mc_get_frontend, | 933 | .get_tune_settings = dib3000mc_fe_get_tune_settings, |
928 | .get_tune_settings = dib3000mc_fe_get_tune_settings, | 934 | .get_frontend = dib3000mc_get_frontend, |
929 | 935 | ||
930 | .read_status = dib3000mc_read_status, | 936 | .read_status = dib3000mc_read_status, |
931 | .read_ber = dib3000mc_read_ber, | 937 | .read_ber = dib3000mc_read_ber, |
932 | .read_signal_strength = dib3000mc_read_signal_strength, | 938 | .read_signal_strength = dib3000mc_read_signal_strength, |
933 | .read_snr = dib3000mc_read_snr, | 939 | .read_snr = dib3000mc_read_snr, |
934 | .read_ucblocks = dib3000mc_read_unc_blocks, | 940 | .read_ucblocks = dib3000mc_read_unc_blocks, |
935 | }; | 941 | }; |
936 | 942 | ||
937 | MODULE_AUTHOR(DRIVER_AUTHOR); | 943 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); |
938 | MODULE_DESCRIPTION(DRIVER_DESC); | 944 | MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator"); |
939 | MODULE_LICENSE("GPL"); | 945 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/frontends/dib3000mc_priv.h b/drivers/media/dvb/frontends/dib3000mc_priv.h deleted file mode 100644 index a0c8f1c911de..000000000000 --- a/drivers/media/dvb/frontends/dib3000mc_priv.h +++ /dev/null | |||
@@ -1,404 +0,0 @@ | |||
1 | /* | ||
2 | * dib3000mc_priv.h | ||
3 | * | ||
4 | * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | * for more information see dib3000mc.c . | ||
11 | */ | ||
12 | |||
13 | #ifndef __DIB3000MC_PRIV_H__ | ||
14 | #define __DIB3000MC_PRIV_H__ | ||
15 | |||
16 | /* | ||
17 | * Demodulator parameters | ||
18 | * reg: 0 1 1 1 11 11 111 | ||
19 | * | | | | | | | ||
20 | * | | | | | +-- alpha (000=0, 001=1, 010=2, 100=4) | ||
21 | * | | | | +----- constellation (00=QPSK, 01=16QAM, 10=64QAM) | ||
22 | * | | | +-------- guard (00=1/32, 01=1/16, 10=1/8, 11=1/4) | ||
23 | * | | +----------- transmission mode (0=2k, 1=8k) | ||
24 | * | | | ||
25 | * | +-------------- restart autosearch for parameters | ||
26 | * +---------------- restart the demodulator | ||
27 | * reg: 181 1 111 1 | ||
28 | * | | | | ||
29 | * | | +- FEC applies for HP or LP (0=LP, 1=HP) | ||
30 | * | +---- FEC rate (001=1/2, 010=2/3, 011=3/4, 101=5/6, 111=7/8) | ||
31 | * +------- hierarchy on (0=no, 1=yes) | ||
32 | */ | ||
33 | |||
34 | /* demodulator tuning parameter and restart options */ | ||
35 | #define DIB3000MC_REG_DEMOD_PARM ( 0) | ||
36 | #define DIB3000MC_DEMOD_PARM(a,c,g,t) ( \ | ||
37 | (0x7 & a) | \ | ||
38 | ((0x3 & c) << 3) | \ | ||
39 | ((0x3 & g) << 5) | \ | ||
40 | ((0x1 & t) << 7) ) | ||
41 | #define DIB3000MC_DEMOD_RST_AUTO_SRCH_ON (1 << 8) | ||
42 | #define DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF (0 << 8) | ||
43 | #define DIB3000MC_DEMOD_RST_DEMOD_ON (1 << 9) | ||
44 | #define DIB3000MC_DEMOD_RST_DEMOD_OFF (0 << 9) | ||
45 | |||
46 | /* register for hierarchy parameters */ | ||
47 | #define DIB3000MC_REG_HRCH_PARM ( 181) | ||
48 | #define DIB3000MC_HRCH_PARM(s,f,h) ( \ | ||
49 | (0x1 & s) | \ | ||
50 | ((0x7 & f) << 1) | \ | ||
51 | ((0x1 & h) << 4) ) | ||
52 | |||
53 | /* timeout ??? */ | ||
54 | #define DIB3000MC_REG_UNK_1 ( 1) | ||
55 | #define DIB3000MC_UNK_1 ( 0x04) | ||
56 | |||
57 | /* timeout ??? */ | ||
58 | #define DIB3000MC_REG_UNK_2 ( 2) | ||
59 | #define DIB3000MC_UNK_2 ( 0x04) | ||
60 | |||
61 | /* timeout ??? */ | ||
62 | #define DIB3000MC_REG_UNK_3 ( 3) | ||
63 | #define DIB3000MC_UNK_3 (0x1000) | ||
64 | |||
65 | #define DIB3000MC_REG_UNK_4 ( 4) | ||
66 | #define DIB3000MC_UNK_4 (0x0814) | ||
67 | |||
68 | /* timeout ??? */ | ||
69 | #define DIB3000MC_REG_SEQ_TPS ( 5) | ||
70 | #define DIB3000MC_SEQ_TPS_DEFAULT ( 1) | ||
71 | #define DIB3000MC_SEQ_TPS(s,t) ( \ | ||
72 | ((s & 0x0f) << 4) | \ | ||
73 | ((t & 0x01) << 8) ) | ||
74 | #define DIB3000MC_IS_TPS(v) ((v << 8) & 0x1) | ||
75 | #define DIB3000MC_IS_AS(v) ((v >> 4) & 0xf) | ||
76 | |||
77 | /* parameters for the bandwidth */ | ||
78 | #define DIB3000MC_REG_BW_TIMOUT_MSB ( 6) | ||
79 | #define DIB3000MC_REG_BW_TIMOUT_LSB ( 7) | ||
80 | |||
81 | static u16 dib3000mc_reg_bandwidth[] = { 6,7,8,9,10,11,16,17 }; | ||
82 | |||
83 | /*static u16 dib3000mc_bandwidth_5mhz[] = | ||
84 | { 0x28, 0x9380, 0x87, 0x4100, 0x2a4, 0x4500, 0x1, 0xb0d0 };*/ | ||
85 | |||
86 | static u16 dib3000mc_bandwidth_6mhz[] = | ||
87 | { 0x21, 0xd040, 0x70, 0xb62b, 0x233, 0x8ed5, 0x1, 0xb0d0 }; | ||
88 | |||
89 | static u16 dib3000mc_bandwidth_7mhz[] = | ||
90 | { 0x1c, 0xfba5, 0x60, 0x9c25, 0x1e3, 0x0cb7, 0x1, 0xb0d0 }; | ||
91 | |||
92 | static u16 dib3000mc_bandwidth_8mhz[] = | ||
93 | { 0x19, 0x5c30, 0x54, 0x88a0, 0x1a6, 0xab20, 0x1, 0xb0d0 }; | ||
94 | |||
95 | static u16 dib3000mc_reg_bandwidth_general[] = { 12,13,14,15 }; | ||
96 | static u16 dib3000mc_bandwidth_general[] = { 0x0000, 0x03e8, 0x0000, 0x03f2 }; | ||
97 | |||
98 | /* lock mask */ | ||
99 | #define DIB3000MC_REG_LOCK_MASK ( 15) | ||
100 | #define DIB3000MC_ACTIVATE_LOCK_MASK (0x0800) | ||
101 | |||
102 | /* reset the uncorrected packet count (??? do it 5 times) */ | ||
103 | #define DIB3000MC_REG_RST_UNC ( 18) | ||
104 | #define DIB3000MC_RST_UNC_ON ( 1) | ||
105 | #define DIB3000MC_RST_UNC_OFF ( 0) | ||
106 | |||
107 | #define DIB3000MC_REG_UNK_19 ( 19) | ||
108 | #define DIB3000MC_UNK_19 ( 0) | ||
109 | |||
110 | /* DDS frequency value (IF position) and inversion bit */ | ||
111 | #define DIB3000MC_REG_INVERSION ( 21) | ||
112 | #define DIB3000MC_REG_SET_DDS_FREQ_MSB ( 21) | ||
113 | #define DIB3000MC_DDS_FREQ_MSB_INV_OFF (0x0164) | ||
114 | #define DIB3000MC_DDS_FREQ_MSB_INV_ON (0x0364) | ||
115 | |||
116 | #define DIB3000MC_REG_SET_DDS_FREQ_LSB ( 22) | ||
117 | #define DIB3000MC_DDS_FREQ_LSB (0x463d) | ||
118 | |||
119 | /* timing frequencies setting */ | ||
120 | #define DIB3000MC_REG_TIMING_FREQ_MSB ( 23) | ||
121 | #define DIB3000MC_REG_TIMING_FREQ_LSB ( 24) | ||
122 | #define DIB3000MC_CLOCK_REF (0x151fd1) | ||
123 | |||
124 | //static u16 dib3000mc_reg_timing_freq[] = { 23,24 }; | ||
125 | |||
126 | //static u16 dib3000mc_timing_freq[][2] = { | ||
127 | // { 0x69, 0x9f18 }, /* 5 MHz */ | ||
128 | // { 0x7e ,0xbee9 }, /* 6 MHz */ | ||
129 | // { 0x93 ,0xdebb }, /* 7 MHz */ | ||
130 | // { 0xa8 ,0xfe8c }, /* 8 MHz */ | ||
131 | //}; | ||
132 | |||
133 | /* timeout ??? */ | ||
134 | static u16 dib3000mc_reg_offset[] = { 26,33 }; | ||
135 | |||
136 | static u16 dib3000mc_offset[][2] = { | ||
137 | { 26240, 5 }, /* default */ | ||
138 | { 30336, 6 }, /* 8K */ | ||
139 | { 38528, 8 }, /* 2K */ | ||
140 | }; | ||
141 | |||
142 | #define DIB3000MC_REG_ISI ( 29) | ||
143 | #define DIB3000MC_ISI_DEFAULT (0x1073) | ||
144 | #define DIB3000MC_ISI_ACTIVATE (0x0000) | ||
145 | #define DIB3000MC_ISI_INHIBIT (0x0200) | ||
146 | |||
147 | /* impulse noise control */ | ||
148 | static u16 dib3000mc_reg_imp_noise_ctl[] = { 34,35 }; | ||
149 | |||
150 | static u16 dib3000mc_imp_noise_ctl[][2] = { | ||
151 | { 0x1294, 0x1ff8 }, /* mode 0 */ | ||
152 | { 0x1294, 0x1ff8 }, /* mode 1 */ | ||
153 | { 0x1294, 0x1ff8 }, /* mode 2 */ | ||
154 | { 0x1294, 0x1ff8 }, /* mode 3 */ | ||
155 | { 0x1294, 0x1ff8 }, /* mode 4 */ | ||
156 | }; | ||
157 | |||
158 | /* AGC loop bandwidth */ | ||
159 | static u16 dib3000mc_reg_agc_bandwidth[] = { 40,41 }; | ||
160 | static u16 dib3000mc_agc_bandwidth[] = { 0x119,0x330 }; | ||
161 | |||
162 | static u16 dib3000mc_reg_agc_bandwidth_general[] = { 50,51,52,53,54 }; | ||
163 | static u16 dib3000mc_agc_bandwidth_general[] = | ||
164 | { 0x8000, 0x91ca, 0x01ba, 0x0087, 0x0087 }; | ||
165 | |||
166 | #define DIB3000MC_REG_IMP_NOISE_55 ( 55) | ||
167 | #define DIB3000MC_IMP_NEW_ALGO(w) (w | (1<<10)) | ||
168 | |||
169 | /* Impulse noise params */ | ||
170 | static u16 dib3000mc_reg_impulse_noise[] = { 55,56,57 }; | ||
171 | static u16 dib3000mc_impluse_noise[][3] = { | ||
172 | { 0x489, 0x89, 0x72 }, /* 5 MHz */ | ||
173 | { 0x4a5, 0xa5, 0x89 }, /* 6 MHz */ | ||
174 | { 0x4c0, 0xc0, 0xa0 }, /* 7 MHz */ | ||
175 | { 0x4db, 0xdb, 0xb7 }, /* 8 Mhz */ | ||
176 | }; | ||
177 | |||
178 | static u16 dib3000mc_reg_fft[] = { | ||
179 | 58,59,60,61,62,63,64,65,66,67,68,69, | ||
180 | 70,71,72,73,74,75,76,77,78,79,80,81, | ||
181 | 82,83,84,85,86 | ||
182 | }; | ||
183 | |||
184 | static u16 dib3000mc_fft_modes[][29] = { | ||
185 | { 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, | ||
186 | 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d, | ||
187 | 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, | ||
188 | 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c, | ||
189 | 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0, 0xd | ||
190 | }, /* fft mode 0 */ | ||
191 | { 0x3b, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, | ||
192 | 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d, | ||
193 | 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, | ||
194 | 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c, | ||
195 | 0x3ffe, 0x5b3, 0x3feb, 0x0, 0x8200, 0xd | ||
196 | }, /* fft mode 1 */ | ||
197 | }; | ||
198 | |||
199 | #define DIB3000MC_REG_UNK_88 ( 88) | ||
200 | #define DIB3000MC_UNK_88 (0x0410) | ||
201 | |||
202 | static u16 dib3000mc_reg_bw[] = { 93,94,95,96,97,98 }; | ||
203 | static u16 dib3000mc_bw[][6] = { | ||
204 | { 0,0,0,0,0,0 }, /* 5 MHz */ | ||
205 | { 0,0,0,0,0,0 }, /* 6 MHz */ | ||
206 | { 0,0,0,0,0,0 }, /* 7 MHz */ | ||
207 | { 0x20, 0x21, 0x20, 0x23, 0x20, 0x27 }, /* 8 MHz */ | ||
208 | }; | ||
209 | |||
210 | |||
211 | /* phase noise control */ | ||
212 | #define DIB3000MC_REG_UNK_99 ( 99) | ||
213 | #define DIB3000MC_UNK_99 (0x0220) | ||
214 | |||
215 | #define DIB3000MC_REG_SCAN_BOOST ( 100) | ||
216 | #define DIB3000MC_SCAN_BOOST_ON ((11 << 6) + 6) | ||
217 | #define DIB3000MC_SCAN_BOOST_OFF ((16 << 6) + 9) | ||
218 | |||
219 | /* timeout ??? */ | ||
220 | #define DIB3000MC_REG_UNK_110 ( 110) | ||
221 | #define DIB3000MC_UNK_110 ( 3277) | ||
222 | |||
223 | #define DIB3000MC_REG_UNK_111 ( 111) | ||
224 | #define DIB3000MC_UNK_111_PH_N_MODE_0 ( 0) | ||
225 | #define DIB3000MC_UNK_111_PH_N_MODE_1 (1 << 1) | ||
226 | |||
227 | /* superious rm config */ | ||
228 | #define DIB3000MC_REG_UNK_120 ( 120) | ||
229 | #define DIB3000MC_UNK_120 ( 8207) | ||
230 | |||
231 | #define DIB3000MC_REG_UNK_133 ( 133) | ||
232 | #define DIB3000MC_UNK_133 ( 15564) | ||
233 | |||
234 | #define DIB3000MC_REG_UNK_134 ( 134) | ||
235 | #define DIB3000MC_UNK_134 ( 0) | ||
236 | |||
237 | /* adapter config for constellation */ | ||
238 | static u16 dib3000mc_reg_adp_cfg[] = { 129, 130, 131, 132 }; | ||
239 | |||
240 | static u16 dib3000mc_adp_cfg[][4] = { | ||
241 | { 0x99a, 0x7fae, 0x333, 0x7ff0 }, /* QPSK */ | ||
242 | { 0x23d, 0x7fdf, 0x0a4, 0x7ff0 }, /* 16-QAM */ | ||
243 | { 0x148, 0x7ff0, 0x0a4, 0x7ff8 }, /* 64-QAM */ | ||
244 | }; | ||
245 | |||
246 | static u16 dib3000mc_reg_mobile_mode[] = { 139, 140, 141, 175, 1032 }; | ||
247 | |||
248 | static u16 dib3000mc_mobile_mode[][5] = { | ||
249 | { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* fixed */ | ||
250 | { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* portable */ | ||
251 | { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* mobile */ | ||
252 | { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* auto */ | ||
253 | }; | ||
254 | |||
255 | #define DIB3000MC_REG_DIVERSITY1 ( 177) | ||
256 | #define DIB3000MC_DIVERSITY1_DEFAULT ( 1) | ||
257 | |||
258 | #define DIB3000MC_REG_DIVERSITY2 ( 178) | ||
259 | #define DIB3000MC_DIVERSITY2_DEFAULT ( 1) | ||
260 | |||
261 | #define DIB3000MC_REG_DIVERSITY3 ( 180) | ||
262 | #define DIB3000MC_DIVERSITY3_IN_OFF (0xfff0) | ||
263 | #define DIB3000MC_DIVERSITY3_IN_ON (0xfff6) | ||
264 | |||
265 | #define DIB3000MC_REG_FEC_CFG ( 195) | ||
266 | #define DIB3000MC_FEC_CFG ( 0x10) | ||
267 | |||
268 | /* | ||
269 | * reg 206, output mode | ||
270 | * 1111 1111 | ||
271 | * |||| |||| | ||
272 | * |||| |||+- unk | ||
273 | * |||| ||+-- unk | ||
274 | * |||| |+--- unk (on by default) | ||
275 | * |||| +---- fifo_ctrl (1 = inhibit (flushed), 0 = active (unflushed)) | ||
276 | * |||+------ pid_parse (1 = enabled, 0 = disabled) | ||
277 | * ||+------- outp_188 (1 = TS packet size 188, 0 = packet size 204) | ||
278 | * |+-------- unk | ||
279 | * +--------- unk | ||
280 | */ | ||
281 | |||
282 | #define DIB3000MC_REG_SMO_MODE ( 206) | ||
283 | #define DIB3000MC_SMO_MODE_DEFAULT (1 << 2) | ||
284 | #define DIB3000MC_SMO_MODE_FIFO_FLUSH (1 << 3) | ||
285 | #define DIB3000MC_SMO_MODE_FIFO_UNFLUSH (0xfff7) | ||
286 | #define DIB3000MC_SMO_MODE_PID_PARSE (1 << 4) | ||
287 | #define DIB3000MC_SMO_MODE_NO_PID_PARSE (0xffef) | ||
288 | #define DIB3000MC_SMO_MODE_188 (1 << 5) | ||
289 | #define DIB3000MC_SMO_MODE_SLAVE (DIB3000MC_SMO_MODE_DEFAULT | \ | ||
290 | DIB3000MC_SMO_MODE_188 | DIB3000MC_SMO_MODE_PID_PARSE | (1<<1)) | ||
291 | |||
292 | #define DIB3000MC_REG_FIFO_THRESHOLD ( 207) | ||
293 | #define DIB3000MC_FIFO_THRESHOLD_DEFAULT ( 1792) | ||
294 | #define DIB3000MC_FIFO_THRESHOLD_SLAVE ( 512) | ||
295 | /* | ||
296 | * pidfilter | ||
297 | * it is not a hardware pidfilter but a filter which drops all pids | ||
298 | * except the ones set. When connected to USB1.1 bandwidth this is important. | ||
299 | * DiB3000P/M-C can filter up to 32 PIDs | ||
300 | */ | ||
301 | #define DIB3000MC_REG_FIRST_PID ( 212) | ||
302 | #define DIB3000MC_NUM_PIDS ( 32) | ||
303 | |||
304 | #define DIB3000MC_REG_OUTMODE ( 244) | ||
305 | #define DIB3000MC_OM_PARALLEL_GATED_CLK ( 0) | ||
306 | #define DIB3000MC_OM_PAR_CONT_CLK (1 << 11) | ||
307 | #define DIB3000MC_OM_SERIAL (2 << 11) | ||
308 | #define DIB3000MC_OM_DIVOUT_ON (4 << 11) | ||
309 | #define DIB3000MC_OM_SLAVE (DIB3000MC_OM_DIVOUT_ON | DIB3000MC_OM_PAR_CONT_CLK) | ||
310 | |||
311 | #define DIB3000MC_REG_RF_POWER ( 392) | ||
312 | |||
313 | #define DIB3000MC_REG_FFT_POSITION ( 407) | ||
314 | |||
315 | #define DIB3000MC_REG_DDS_FREQ_MSB ( 414) | ||
316 | #define DIB3000MC_REG_DDS_FREQ_LSB ( 415) | ||
317 | |||
318 | #define DIB3000MC_REG_TIMING_OFFS_MSB ( 416) | ||
319 | #define DIB3000MC_REG_TIMING_OFFS_LSB ( 417) | ||
320 | |||
321 | #define DIB3000MC_REG_TUNING_PARM ( 458) | ||
322 | #define DIB3000MC_TP_QAM(v) ((v >> 13) & 0x03) | ||
323 | #define DIB3000MC_TP_HRCH(v) ((v >> 12) & 0x01) | ||
324 | #define DIB3000MC_TP_ALPHA(v) ((v >> 9) & 0x07) | ||
325 | #define DIB3000MC_TP_FFT(v) ((v >> 8) & 0x01) | ||
326 | #define DIB3000MC_TP_FEC_CR_HP(v) ((v >> 5) & 0x07) | ||
327 | #define DIB3000MC_TP_FEC_CR_LP(v) ((v >> 2) & 0x07) | ||
328 | #define DIB3000MC_TP_GUARD(v) (v & 0x03) | ||
329 | |||
330 | #define DIB3000MC_REG_SIGNAL_NOISE_MSB ( 483) | ||
331 | #define DIB3000MC_REG_SIGNAL_NOISE_LSB ( 484) | ||
332 | |||
333 | #define DIB3000MC_REG_MER ( 485) | ||
334 | |||
335 | #define DIB3000MC_REG_BER_MSB ( 500) | ||
336 | #define DIB3000MC_REG_BER_LSB ( 501) | ||
337 | |||
338 | #define DIB3000MC_REG_PACKET_ERRORS ( 503) | ||
339 | |||
340 | #define DIB3000MC_REG_PACKET_ERROR_COUNT ( 506) | ||
341 | |||
342 | #define DIB3000MC_REG_LOCK_507 ( 507) | ||
343 | #define DIB3000MC_LOCK_507 (0x0002) // ? name correct ? | ||
344 | |||
345 | #define DIB3000MC_REG_LOCKING ( 509) | ||
346 | #define DIB3000MC_AGC_LOCK(v) (v & 0x8000) | ||
347 | #define DIB3000MC_CARRIER_LOCK(v) (v & 0x2000) | ||
348 | #define DIB3000MC_MPEG_SYNC_LOCK(v) (v & 0x0080) | ||
349 | #define DIB3000MC_MPEG_DATA_LOCK(v) (v & 0x0040) | ||
350 | #define DIB3000MC_TPS_LOCK(v) (v & 0x0004) | ||
351 | |||
352 | #define DIB3000MC_REG_AS_IRQ ( 511) | ||
353 | #define DIB3000MC_AS_IRQ_SUCCESS (1 << 1) | ||
354 | #define DIB3000MC_AS_IRQ_FAIL ( 1) | ||
355 | |||
356 | #define DIB3000MC_REG_TUNER ( 769) | ||
357 | |||
358 | #define DIB3000MC_REG_RST_I2C_ADDR ( 1024) | ||
359 | #define DIB3000MC_DEMOD_ADDR_ON ( 1) | ||
360 | #define DIB3000MC_DEMOD_ADDR(a) ((a << 4) & 0x03F0) | ||
361 | |||
362 | #define DIB3000MC_REG_RESTART ( 1027) | ||
363 | #define DIB3000MC_RESTART_OFF (0x0000) | ||
364 | #define DIB3000MC_RESTART_AGC (0x0800) | ||
365 | #define DIB3000MC_RESTART_CONFIG (0x8000) | ||
366 | |||
367 | #define DIB3000MC_REG_RESTART_VIT ( 1028) | ||
368 | #define DIB3000MC_RESTART_VIT_OFF ( 0) | ||
369 | #define DIB3000MC_RESTART_VIT_ON ( 1) | ||
370 | |||
371 | #define DIB3000MC_REG_CLK_CFG_1 ( 1031) | ||
372 | #define DIB3000MC_CLK_CFG_1_POWER_UP ( 0) | ||
373 | #define DIB3000MC_CLK_CFG_1_POWER_DOWN (0xffff) | ||
374 | |||
375 | #define DIB3000MC_REG_CLK_CFG_2 ( 1032) | ||
376 | #define DIB3000MC_CLK_CFG_2_PUP_FIXED (0x012c) | ||
377 | #define DIB3000MC_CLK_CFG_2_PUP_PORT (0x0104) | ||
378 | #define DIB3000MC_CLK_CFG_2_PUP_MOBILE (0x0000) | ||
379 | #define DIB3000MC_CLK_CFG_2_POWER_DOWN (0xffff) | ||
380 | |||
381 | #define DIB3000MC_REG_CLK_CFG_3 ( 1033) | ||
382 | #define DIB3000MC_CLK_CFG_3_POWER_UP ( 0) | ||
383 | #define DIB3000MC_CLK_CFG_3_POWER_DOWN (0xfff5) | ||
384 | |||
385 | #define DIB3000MC_REG_CLK_CFG_7 ( 1037) | ||
386 | #define DIB3000MC_CLK_CFG_7_INIT ( 12592) | ||
387 | #define DIB3000MC_CLK_CFG_7_POWER_UP (~0x0003) | ||
388 | #define DIB3000MC_CLK_CFG_7_PWR_DOWN (0x0003) | ||
389 | #define DIB3000MC_CLK_CFG_7_DIV_IN_OFF (1 << 8) | ||
390 | |||
391 | /* was commented out ??? */ | ||
392 | #define DIB3000MC_REG_CLK_CFG_8 ( 1038) | ||
393 | #define DIB3000MC_CLK_CFG_8_POWER_UP (0x160c) | ||
394 | |||
395 | #define DIB3000MC_REG_CLK_CFG_9 ( 1039) | ||
396 | #define DIB3000MC_CLK_CFG_9_POWER_UP ( 0) | ||
397 | |||
398 | /* also clock ??? */ | ||
399 | #define DIB3000MC_REG_ELEC_OUT ( 1040) | ||
400 | #define DIB3000MC_ELEC_OUT_HIGH_Z ( 0) | ||
401 | #define DIB3000MC_ELEC_OUT_DIV_OUT_ON ( 1) | ||
402 | #define DIB3000MC_ELEC_OUT_SLAVE ( 3) | ||
403 | |||
404 | #endif | ||
diff --git a/drivers/media/dvb/frontends/mt2060.c b/drivers/media/dvb/frontends/mt2060.c index cc38e7077a0b..aa0f0e576d62 100644 --- a/drivers/media/dvb/frontends/mt2060.c +++ b/drivers/media/dvb/frontends/mt2060.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "mt2060.h" | 32 | #include "mt2060.h" |
33 | #include "mt2060_priv.h" | 33 | #include "mt2060_priv.h" |
34 | 34 | ||
35 | static int debug=0; | 35 | static int debug; |
36 | module_param(debug, int, 0644); | 36 | module_param(debug, int, 0644); |
37 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | 37 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); |
38 | 38 | ||
@@ -350,7 +350,7 @@ int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt206 | |||
350 | kfree(priv); | 350 | kfree(priv); |
351 | return -ENODEV; | 351 | return -ENODEV; |
352 | } | 352 | } |
353 | printk(KERN_INFO "MT2060: successfully identified\n"); | 353 | printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1); |
354 | memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops)); | 354 | memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops)); |
355 | 355 | ||
356 | fe->tuner_priv = priv; | 356 | fe->tuner_priv = priv; |