aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends
diff options
context:
space:
mode:
authorIgor M. Liplianin <liplianin@me.by>2012-12-28 17:40:33 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-12-28 18:37:36 -0500
commitb858c331cdf402853be2c48c8f4f77173ef04da8 (patch)
tree456fdd9581b3416fa17b359b3e417af4cf4dd73e /drivers/media/dvb-frontends
parent43385c8a645a25ddef7a45df8786ff26806f7e5d (diff)
[media] m88rs2000: make use ts2020
Tuner part of Montage rs2000 chip is similar to ts2020 tuner. Patch to use ts2020 code. [mchehab@redhat.com: a few CodingStyle fixes] Signed-off-by: Igor M. Liplianin <liplianin@me.by> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb-frontends')
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.c408
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.h6
-rw-r--r--drivers/media/dvb-frontends/ts2020.c381
-rw-r--r--drivers/media/dvb-frontends/ts2020.h1
4 files changed, 318 insertions, 478 deletions
diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c
index df9e7dd6fe74..283c90fee374 100644
--- a/drivers/media/dvb-frontends/m88rs2000.c
+++ b/drivers/media/dvb-frontends/m88rs2000.c
@@ -60,15 +60,13 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
60#define info(format, arg...) \ 60#define info(format, arg...) \
61 printk(KERN_INFO "m88rs2000-fe: " format "\n" , ## arg) 61 printk(KERN_INFO "m88rs2000-fe: " format "\n" , ## arg)
62 62
63static int m88rs2000_writereg(struct m88rs2000_state *state, u8 tuner, 63static int m88rs2000_writereg(struct m88rs2000_state *state,
64 u8 reg, u8 data) 64 u8 reg, u8 data)
65{ 65{
66 int ret; 66 int ret;
67 u8 addr = (tuner == 0) ? state->config->tuner_addr :
68 state->config->demod_addr;
69 u8 buf[] = { reg, data }; 67 u8 buf[] = { reg, data };
70 struct i2c_msg msg = { 68 struct i2c_msg msg = {
71 .addr = addr, 69 .addr = state->config->demod_addr,
72 .flags = 0, 70 .flags = 0,
73 .buf = buf, 71 .buf = buf,
74 .len = 2 72 .len = 2
@@ -83,44 +81,20 @@ static int m88rs2000_writereg(struct m88rs2000_state *state, u8 tuner,
83 return (ret != 1) ? -EREMOTEIO : 0; 81 return (ret != 1) ? -EREMOTEIO : 0;
84} 82}
85 83
86static int m88rs2000_demod_write(struct m88rs2000_state *state, u8 reg, u8 data) 84static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 reg)
87{
88 return m88rs2000_writereg(state, 1, reg, data);
89}
90
91static int m88rs2000_tuner_write(struct m88rs2000_state *state, u8 reg, u8 data)
92{
93 m88rs2000_demod_write(state, 0x81, 0x84);
94 udelay(10);
95 return m88rs2000_writereg(state, 0, reg, data);
96
97}
98
99static int m88rs2000_write(struct dvb_frontend *fe, const u8 buf[], int len)
100{
101 struct m88rs2000_state *state = fe->demodulator_priv;
102
103 if (len != 2)
104 return -EINVAL;
105
106 return m88rs2000_writereg(state, 1, buf[0], buf[1]);
107}
108
109static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 tuner, u8 reg)
110{ 85{
111 int ret; 86 int ret;
112 u8 b0[] = { reg }; 87 u8 b0[] = { reg };
113 u8 b1[] = { 0 }; 88 u8 b1[] = { 0 };
114 u8 addr = (tuner == 0) ? state->config->tuner_addr : 89
115 state->config->demod_addr;
116 struct i2c_msg msg[] = { 90 struct i2c_msg msg[] = {
117 { 91 {
118 .addr = addr, 92 .addr = state->config->demod_addr,
119 .flags = 0, 93 .flags = 0,
120 .buf = b0, 94 .buf = b0,
121 .len = 1 95 .len = 1
122 }, { 96 }, {
123 .addr = addr, 97 .addr = state->config->demod_addr,
124 .flags = I2C_M_RD, 98 .flags = I2C_M_RD,
125 .buf = b1, 99 .buf = b1,
126 .len = 1 100 .len = 1
@@ -136,18 +110,6 @@ static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 tuner, u8 reg)
136 return b1[0]; 110 return b1[0];
137} 111}
138 112
139static u8 m88rs2000_demod_read(struct m88rs2000_state *state, u8 reg)
140{
141 return m88rs2000_readreg(state, 1, reg);
142}
143
144static u8 m88rs2000_tuner_read(struct m88rs2000_state *state, u8 reg)
145{
146 m88rs2000_demod_write(state, 0x81, 0x85);
147 udelay(10);
148 return m88rs2000_readreg(state, 0, reg);
149}
150
151static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate) 113static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
152{ 114{
153 struct m88rs2000_state *state = fe->demodulator_priv; 115 struct m88rs2000_state *state = fe->demodulator_priv;
@@ -166,9 +128,9 @@ static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
166 b[0] = (u8) (temp >> 16) & 0xff; 128 b[0] = (u8) (temp >> 16) & 0xff;
167 b[1] = (u8) (temp >> 8) & 0xff; 129 b[1] = (u8) (temp >> 8) & 0xff;
168 b[2] = (u8) temp & 0xff; 130 b[2] = (u8) temp & 0xff;
169 ret = m88rs2000_demod_write(state, 0x93, b[2]); 131 ret = m88rs2000_writereg(state, 0x93, b[2]);
170 ret |= m88rs2000_demod_write(state, 0x94, b[1]); 132 ret |= m88rs2000_writereg(state, 0x94, b[1]);
171 ret |= m88rs2000_demod_write(state, 0x95, b[0]); 133 ret |= m88rs2000_writereg(state, 0x95, b[0]);
172 134
173 deb_info("m88rs2000: m88rs2000_set_symbolrate\n"); 135 deb_info("m88rs2000: m88rs2000_set_symbolrate\n");
174 return ret; 136 return ret;
@@ -182,37 +144,37 @@ static int m88rs2000_send_diseqc_msg(struct dvb_frontend *fe,
182 int i; 144 int i;
183 u8 reg; 145 u8 reg;
184 deb_info("%s\n", __func__); 146 deb_info("%s\n", __func__);
185 m88rs2000_demod_write(state, 0x9a, 0x30); 147 m88rs2000_writereg(state, 0x9a, 0x30);
186 reg = m88rs2000_demod_read(state, 0xb2); 148 reg = m88rs2000_readreg(state, 0xb2);
187 reg &= 0x3f; 149 reg &= 0x3f;
188 m88rs2000_demod_write(state, 0xb2, reg); 150 m88rs2000_writereg(state, 0xb2, reg);
189 for (i = 0; i < m->msg_len; i++) 151 for (i = 0; i < m->msg_len; i++)
190 m88rs2000_demod_write(state, 0xb3 + i, m->msg[i]); 152 m88rs2000_writereg(state, 0xb3 + i, m->msg[i]);
191 153
192 reg = m88rs2000_demod_read(state, 0xb1); 154 reg = m88rs2000_readreg(state, 0xb1);
193 reg &= 0x87; 155 reg &= 0x87;
194 reg |= ((m->msg_len - 1) << 3) | 0x07; 156 reg |= ((m->msg_len - 1) << 3) | 0x07;
195 reg &= 0x7f; 157 reg &= 0x7f;
196 m88rs2000_demod_write(state, 0xb1, reg); 158 m88rs2000_writereg(state, 0xb1, reg);
197 159
198 for (i = 0; i < 15; i++) { 160 for (i = 0; i < 15; i++) {
199 if ((m88rs2000_demod_read(state, 0xb1) & 0x40) == 0x0) 161 if ((m88rs2000_readreg(state, 0xb1) & 0x40) == 0x0)
200 break; 162 break;
201 msleep(20); 163 msleep(20);
202 } 164 }
203 165
204 reg = m88rs2000_demod_read(state, 0xb1); 166 reg = m88rs2000_readreg(state, 0xb1);
205 if ((reg & 0x40) > 0x0) { 167 if ((reg & 0x40) > 0x0) {
206 reg &= 0x7f; 168 reg &= 0x7f;
207 reg |= 0x40; 169 reg |= 0x40;
208 m88rs2000_demod_write(state, 0xb1, reg); 170 m88rs2000_writereg(state, 0xb1, reg);
209 } 171 }
210 172
211 reg = m88rs2000_demod_read(state, 0xb2); 173 reg = m88rs2000_readreg(state, 0xb2);
212 reg &= 0x3f; 174 reg &= 0x3f;
213 reg |= 0x80; 175 reg |= 0x80;
214 m88rs2000_demod_write(state, 0xb2, reg); 176 m88rs2000_writereg(state, 0xb2, reg);
215 m88rs2000_demod_write(state, 0x9a, 0xb0); 177 m88rs2000_writereg(state, 0x9a, 0xb0);
216 178
217 179
218 return 0; 180 return 0;
@@ -224,14 +186,14 @@ static int m88rs2000_send_diseqc_burst(struct dvb_frontend *fe,
224 struct m88rs2000_state *state = fe->demodulator_priv; 186 struct m88rs2000_state *state = fe->demodulator_priv;
225 u8 reg0, reg1; 187 u8 reg0, reg1;
226 deb_info("%s\n", __func__); 188 deb_info("%s\n", __func__);
227 m88rs2000_demod_write(state, 0x9a, 0x30); 189 m88rs2000_writereg(state, 0x9a, 0x30);
228 msleep(50); 190 msleep(50);
229 reg0 = m88rs2000_demod_read(state, 0xb1); 191 reg0 = m88rs2000_readreg(state, 0xb1);
230 reg1 = m88rs2000_demod_read(state, 0xb2); 192 reg1 = m88rs2000_readreg(state, 0xb2);
231 /* TODO complete this section */ 193 /* TODO complete this section */
232 m88rs2000_demod_write(state, 0xb2, reg1); 194 m88rs2000_writereg(state, 0xb2, reg1);
233 m88rs2000_demod_write(state, 0xb1, reg0); 195 m88rs2000_writereg(state, 0xb1, reg0);
234 m88rs2000_demod_write(state, 0x9a, 0xb0); 196 m88rs2000_writereg(state, 0x9a, 0xb0);
235 197
236 return 0; 198 return 0;
237} 199}
@@ -240,9 +202,9 @@ static int m88rs2000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
240{ 202{
241 struct m88rs2000_state *state = fe->demodulator_priv; 203 struct m88rs2000_state *state = fe->demodulator_priv;
242 u8 reg0, reg1; 204 u8 reg0, reg1;
243 m88rs2000_demod_write(state, 0x9a, 0x30); 205 m88rs2000_writereg(state, 0x9a, 0x30);
244 reg0 = m88rs2000_demod_read(state, 0xb1); 206 reg0 = m88rs2000_readreg(state, 0xb1);
245 reg1 = m88rs2000_demod_read(state, 0xb2); 207 reg1 = m88rs2000_readreg(state, 0xb2);
246 208
247 reg1 &= 0x3f; 209 reg1 &= 0x3f;
248 210
@@ -257,9 +219,9 @@ static int m88rs2000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
257 default: 219 default:
258 break; 220 break;
259 } 221 }
260 m88rs2000_demod_write(state, 0xb2, reg1); 222 m88rs2000_writereg(state, 0xb2, reg1);
261 m88rs2000_demod_write(state, 0xb1, reg0); 223 m88rs2000_writereg(state, 0xb1, reg0);
262 m88rs2000_demod_write(state, 0x9a, 0xb0); 224 m88rs2000_writereg(state, 0x9a, 0xb0);
263 return 0; 225 return 0;
264} 226}
265 227
@@ -276,14 +238,6 @@ struct inittab m88rs2000_setup[] = {
276 {DEMOD_WRITE, 0x00, 0x00}, 238 {DEMOD_WRITE, 0x00, 0x00},
277 {DEMOD_WRITE, 0x9a, 0xb0}, 239 {DEMOD_WRITE, 0x9a, 0xb0},
278 {DEMOD_WRITE, 0x81, 0xc1}, 240 {DEMOD_WRITE, 0x81, 0xc1},
279 {TUNER_WRITE, 0x42, 0x73},
280 {TUNER_WRITE, 0x05, 0x07},
281 {TUNER_WRITE, 0x20, 0x27},
282 {TUNER_WRITE, 0x07, 0x02},
283 {TUNER_WRITE, 0x11, 0xff},
284 {TUNER_WRITE, 0x60, 0xf9},
285 {TUNER_WRITE, 0x08, 0x01},
286 {TUNER_WRITE, 0x00, 0x41},
287 {DEMOD_WRITE, 0x81, 0x81}, 241 {DEMOD_WRITE, 0x81, 0x81},
288 {DEMOD_WRITE, 0x86, 0xc6}, 242 {DEMOD_WRITE, 0x86, 0xc6},
289 {DEMOD_WRITE, 0x9a, 0x30}, 243 {DEMOD_WRITE, 0x9a, 0x30},
@@ -301,23 +255,10 @@ struct inittab m88rs2000_shutdown[] = {
301 {DEMOD_WRITE, 0xf1, 0x89}, 255 {DEMOD_WRITE, 0xf1, 0x89},
302 {DEMOD_WRITE, 0x00, 0x01}, 256 {DEMOD_WRITE, 0x00, 0x01},
303 {DEMOD_WRITE, 0x9a, 0xb0}, 257 {DEMOD_WRITE, 0x9a, 0xb0},
304 {TUNER_WRITE, 0x00, 0x40},
305 {DEMOD_WRITE, 0x81, 0x81}, 258 {DEMOD_WRITE, 0x81, 0x81},
306 {0xff, 0xaa, 0xff} 259 {0xff, 0xaa, 0xff}
307}; 260};
308 261
309struct inittab tuner_reset[] = {
310 {TUNER_WRITE, 0x42, 0x73},
311 {TUNER_WRITE, 0x05, 0x07},
312 {TUNER_WRITE, 0x20, 0x27},
313 {TUNER_WRITE, 0x07, 0x02},
314 {TUNER_WRITE, 0x11, 0xff},
315 {TUNER_WRITE, 0x60, 0xf9},
316 {TUNER_WRITE, 0x08, 0x01},
317 {TUNER_WRITE, 0x00, 0x41},
318 {0xff, 0xaa, 0xff}
319};
320
321struct inittab fe_reset[] = { 262struct inittab fe_reset[] = {
322 {DEMOD_WRITE, 0x00, 0x01}, 263 {DEMOD_WRITE, 0x00, 0x01},
323 {DEMOD_WRITE, 0xf1, 0xbf}, 264 {DEMOD_WRITE, 0xf1, 0xbf},
@@ -389,11 +330,7 @@ static int m88rs2000_tab_set(struct m88rs2000_state *state,
389 for (i = 0; i < 255; i++) { 330 for (i = 0; i < 255; i++) {
390 switch (tab[i].cmd) { 331 switch (tab[i].cmd) {
391 case 0x01: 332 case 0x01:
392 ret = m88rs2000_demod_write(state, tab[i].reg, 333 ret = m88rs2000_writereg(state, tab[i].reg,
393 tab[i].val);
394 break;
395 case 0x02:
396 ret = m88rs2000_tuner_write(state, tab[i].reg,
397 tab[i].val); 334 tab[i].val);
398 break; 335 break;
399 case 0x10: 336 case 0x10:
@@ -419,7 +356,7 @@ static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
419 struct m88rs2000_state *state = fe->demodulator_priv; 356 struct m88rs2000_state *state = fe->demodulator_priv;
420 u8 data; 357 u8 data;
421 358
422 data = m88rs2000_demod_read(state, 0xb2); 359 data = m88rs2000_readreg(state, 0xb2);
423 data |= 0x03; /* bit0 V/H, bit1 off/on */ 360 data |= 0x03; /* bit0 V/H, bit1 off/on */
424 361
425 switch (volt) { 362 switch (volt) {
@@ -434,23 +371,11 @@ static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
434 break; 371 break;
435 } 372 }
436 373
437 m88rs2000_demod_write(state, 0xb2, data); 374 m88rs2000_writereg(state, 0xb2, data);
438 375
439 return 0; 376 return 0;
440} 377}
441 378
442static int m88rs2000_startup(struct m88rs2000_state *state)
443{
444 int ret = 0;
445 u8 reg;
446
447 reg = m88rs2000_tuner_read(state, 0x00);
448 if ((reg & 0x40) == 0)
449 ret = -ENODEV;
450
451 return ret;
452}
453
454static int m88rs2000_init(struct dvb_frontend *fe) 379static int m88rs2000_init(struct dvb_frontend *fe)
455{ 380{
456 struct m88rs2000_state *state = fe->demodulator_priv; 381 struct m88rs2000_state *state = fe->demodulator_priv;
@@ -479,7 +404,7 @@ static int m88rs2000_sleep(struct dvb_frontend *fe)
479static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status) 404static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
480{ 405{
481 struct m88rs2000_state *state = fe->demodulator_priv; 406 struct m88rs2000_state *state = fe->demodulator_priv;
482 u8 reg = m88rs2000_demod_read(state, 0x8c); 407 u8 reg = m88rs2000_readreg(state, 0x8c);
483 408
484 *status = 0; 409 *status = 0;
485 410
@@ -497,23 +422,23 @@ static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber)
497 struct m88rs2000_state *state = fe->demodulator_priv; 422 struct m88rs2000_state *state = fe->demodulator_priv;
498 u8 tmp0, tmp1; 423 u8 tmp0, tmp1;
499 424
500 m88rs2000_demod_write(state, 0x9a, 0x30); 425 m88rs2000_writereg(state, 0x9a, 0x30);
501 tmp0 = m88rs2000_demod_read(state, 0xd8); 426 tmp0 = m88rs2000_readreg(state, 0xd8);
502 if ((tmp0 & 0x10) != 0) { 427 if ((tmp0 & 0x10) != 0) {
503 m88rs2000_demod_write(state, 0x9a, 0xb0); 428 m88rs2000_writereg(state, 0x9a, 0xb0);
504 *ber = 0xffffffff; 429 *ber = 0xffffffff;
505 return 0; 430 return 0;
506 } 431 }
507 432
508 *ber = (m88rs2000_demod_read(state, 0xd7) << 8) | 433 *ber = (m88rs2000_readreg(state, 0xd7) << 8) |
509 m88rs2000_demod_read(state, 0xd6); 434 m88rs2000_readreg(state, 0xd6);
510 435
511 tmp1 = m88rs2000_demod_read(state, 0xd9); 436 tmp1 = m88rs2000_readreg(state, 0xd9);
512 m88rs2000_demod_write(state, 0xd9, (tmp1 & ~7) | 4); 437 m88rs2000_writereg(state, 0xd9, (tmp1 & ~7) | 4);
513 /* needs twice */ 438 /* needs twice */
514 m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30); 439 m88rs2000_writereg(state, 0xd8, (tmp0 & ~8) | 0x30);
515 m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30); 440 m88rs2000_writereg(state, 0xd8, (tmp0 & ~8) | 0x30);
516 m88rs2000_demod_write(state, 0x9a, 0xb0); 441 m88rs2000_writereg(state, 0x9a, 0xb0);
517 442
518 return 0; 443 return 0;
519} 444}
@@ -529,7 +454,7 @@ static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
529{ 454{
530 struct m88rs2000_state *state = fe->demodulator_priv; 455 struct m88rs2000_state *state = fe->demodulator_priv;
531 456
532 *snr = 512 * m88rs2000_demod_read(state, 0x65); 457 *snr = 512 * m88rs2000_readreg(state, 0x65);
533 458
534 return 0; 459 return 0;
535} 460}
@@ -539,166 +464,17 @@ static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
539 struct m88rs2000_state *state = fe->demodulator_priv; 464 struct m88rs2000_state *state = fe->demodulator_priv;
540 u8 tmp; 465 u8 tmp;
541 466
542 *ucblocks = (m88rs2000_demod_read(state, 0xd5) << 8) | 467 *ucblocks = (m88rs2000_readreg(state, 0xd5) << 8) |
543 m88rs2000_demod_read(state, 0xd4); 468 m88rs2000_readreg(state, 0xd4);
544 tmp = m88rs2000_demod_read(state, 0xd8); 469 tmp = m88rs2000_readreg(state, 0xd8);
545 m88rs2000_demod_write(state, 0xd8, tmp & ~0x20); 470 m88rs2000_writereg(state, 0xd8, tmp & ~0x20);
546 /* needs two times */ 471 /* needs two times */
547 m88rs2000_demod_write(state, 0xd8, tmp | 0x20); 472 m88rs2000_writereg(state, 0xd8, tmp | 0x20);
548 m88rs2000_demod_write(state, 0xd8, tmp | 0x20); 473 m88rs2000_writereg(state, 0xd8, tmp | 0x20);
549 474
550 return 0; 475 return 0;
551} 476}
552 477
553static int m88rs2000_tuner_gate_ctrl(struct m88rs2000_state *state, u8 offset)
554{
555 int ret;
556 ret = m88rs2000_tuner_write(state, 0x51, 0x1f - offset);
557 ret |= m88rs2000_tuner_write(state, 0x51, 0x1f);
558 ret |= m88rs2000_tuner_write(state, 0x50, offset);
559 ret |= m88rs2000_tuner_write(state, 0x50, 0x00);
560 msleep(20);
561 return ret;
562}
563
564static int m88rs2000_set_tuner_rf(struct dvb_frontend *fe)
565{
566 struct m88rs2000_state *state = fe->demodulator_priv;
567 int reg;
568 reg = m88rs2000_tuner_read(state, 0x3d);
569 reg &= 0x7f;
570 if (reg < 0x16)
571 reg = 0xa1;
572 else if (reg == 0x16)
573 reg = 0x99;
574 else
575 reg = 0xf9;
576
577 m88rs2000_tuner_write(state, 0x60, reg);
578 reg = m88rs2000_tuner_gate_ctrl(state, 0x08);
579
580 if (fe->ops.i2c_gate_ctrl)
581 fe->ops.i2c_gate_ctrl(fe, 0);
582 return reg;
583}
584
585static int m88rs2000_set_tuner(struct dvb_frontend *fe, u16 *offset)
586{
587 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
588 struct m88rs2000_state *state = fe->demodulator_priv;
589 int ret;
590 u32 frequency = c->frequency;
591 s32 offset_khz;
592 s32 tmp;
593 u32 symbol_rate = (c->symbol_rate / 1000);
594 u32 f3db, gdiv28;
595 u16 value, ndiv, lpf_coeff;
596 u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf;
597 u8 lo = 0x01, div4 = 0x0;
598
599 /* Reset Tuner */
600 ret = m88rs2000_tab_set(state, tuner_reset);
601
602 /* Calculate frequency divider */
603 if (frequency < 1060000) {
604 lo |= 0x10;
605 div4 = 0x1;
606 ndiv = (frequency * 14 * 4) / FE_CRYSTAL_KHZ;
607 } else
608 ndiv = (frequency * 14 * 2) / FE_CRYSTAL_KHZ;
609 ndiv = ndiv + ndiv % 2;
610 ndiv = ndiv - 1024;
611
612 ret = m88rs2000_tuner_write(state, 0x10, 0x80 | lo);
613
614 /* Set frequency divider */
615 ret |= m88rs2000_tuner_write(state, 0x01, (ndiv >> 8) & 0xf);
616 ret |= m88rs2000_tuner_write(state, 0x02, ndiv & 0xff);
617
618 ret |= m88rs2000_tuner_write(state, 0x03, 0x06);
619 ret |= m88rs2000_tuner_gate_ctrl(state, 0x10);
620 if (ret < 0)
621 return -ENODEV;
622
623 /* Tuner Frequency Range */
624 ret = m88rs2000_tuner_write(state, 0x10, lo);
625
626 ret |= m88rs2000_tuner_gate_ctrl(state, 0x08);
627
628 /* Tuner RF */
629 ret |= m88rs2000_set_tuner_rf(fe);
630
631 gdiv28 = (FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000;
632 ret |= m88rs2000_tuner_write(state, 0x04, gdiv28 & 0xff);
633 ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);
634 if (ret < 0)
635 return -ENODEV;
636
637 value = m88rs2000_tuner_read(state, 0x26);
638
639 f3db = (symbol_rate * 135) / 200 + 2000;
640 f3db += FREQ_OFFSET_LOW_SYM_RATE;
641 if (f3db < 7000)
642 f3db = 7000;
643 if (f3db > 40000)
644 f3db = 40000;
645
646 gdiv28 = gdiv28 * 207 / (value * 2 + 151);
647 mlpf_max = gdiv28 * 135 / 100;
648 mlpf_min = gdiv28 * 78 / 100;
649 if (mlpf_max > 63)
650 mlpf_max = 63;
651
652 lpf_coeff = 2766;
653
654 nlpf = (f3db * gdiv28 * 2 / lpf_coeff /
655 (FE_CRYSTAL_KHZ / 1000) + 1) / 2;
656 if (nlpf > 23)
657 nlpf = 23;
658 if (nlpf < 1)
659 nlpf = 1;
660
661 lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
662 * lpf_coeff * 2 / f3db + 1) / 2;
663
664 if (lpf_mxdiv < mlpf_min) {
665 nlpf++;
666 lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
667 * lpf_coeff * 2 / f3db + 1) / 2;
668 }
669
670 if (lpf_mxdiv > mlpf_max)
671 lpf_mxdiv = mlpf_max;
672
673 ret = m88rs2000_tuner_write(state, 0x04, lpf_mxdiv);
674 ret |= m88rs2000_tuner_write(state, 0x06, nlpf);
675
676 ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);
677
678 ret |= m88rs2000_tuner_gate_ctrl(state, 0x01);
679
680 msleep(80);
681 /* calculate offset assuming 96000kHz*/
682 offset_khz = (ndiv - ndiv % 2 + 1024) * FE_CRYSTAL_KHZ
683 / 14 / (div4 + 1) / 2;
684
685 offset_khz -= frequency;
686
687 tmp = offset_khz;
688 tmp *= 65536;
689
690 tmp = (2 * tmp + 96000) / (2 * 96000);
691 if (tmp < 0)
692 tmp += 65536;
693
694 *offset = tmp & 0xffff;
695
696 if (fe->ops.i2c_gate_ctrl)
697 fe->ops.i2c_gate_ctrl(fe, 0);
698
699 return (ret < 0) ? -EINVAL : 0;
700}
701
702static int m88rs2000_set_fec(struct m88rs2000_state *state, 478static int m88rs2000_set_fec(struct m88rs2000_state *state,
703 fe_code_rate_t fec) 479 fe_code_rate_t fec)
704{ 480{
@@ -724,7 +500,7 @@ static int m88rs2000_set_fec(struct m88rs2000_state *state,
724 default: 500 default:
725 fec_set = 0x08; 501 fec_set = 0x08;
726 } 502 }
727 m88rs2000_demod_write(state, 0x76, fec_set); 503 m88rs2000_writereg(state, 0x76, fec_set);
728 504
729 return 0; 505 return 0;
730} 506}
@@ -733,9 +509,9 @@ static int m88rs2000_set_fec(struct m88rs2000_state *state,
733static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state) 509static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state)
734{ 510{
735 u8 reg; 511 u8 reg;
736 m88rs2000_demod_write(state, 0x9a, 0x30); 512 m88rs2000_writereg(state, 0x9a, 0x30);
737 reg = m88rs2000_demod_read(state, 0x76); 513 reg = m88rs2000_readreg(state, 0x76);
738 m88rs2000_demod_write(state, 0x9a, 0xb0); 514 m88rs2000_writereg(state, 0x9a, 0xb0);
739 515
740 switch (reg) { 516 switch (reg) {
741 case 0x88: 517 case 0x88:
@@ -761,7 +537,9 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
761 struct m88rs2000_state *state = fe->demodulator_priv; 537 struct m88rs2000_state *state = fe->demodulator_priv;
762 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 538 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
763 fe_status_t status; 539 fe_status_t status;
764 int i, ret; 540 int i, ret = 0;
541 s32 tmp;
542 u32 tuner_freq;
765 u16 offset = 0; 543 u16 offset = 0;
766 u8 reg; 544 u8 reg;
767 545
@@ -775,17 +553,37 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
775 } 553 }
776 554
777 /* Set Tuner */ 555 /* Set Tuner */
778 ret = m88rs2000_set_tuner(fe, &offset); 556 if (fe->ops.tuner_ops.set_params)
557 ret = fe->ops.tuner_ops.set_params(fe);
558
559 if (ret < 0)
560 return -ENODEV;
561
562 if (fe->ops.tuner_ops.get_frequency)
563 ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_freq);
564
779 if (ret < 0) 565 if (ret < 0)
780 return -ENODEV; 566 return -ENODEV;
781 567
782 ret = m88rs2000_demod_write(state, 0x9a, 0x30); 568 offset = tuner_freq - c->frequency;
569
570 /* calculate offset assuming 96000kHz*/
571 tmp = offset;
572 tmp *= 65536;
573
574 tmp = (2 * tmp + 96000) / (2 * 96000);
575 if (tmp < 0)
576 tmp += 65536;
577
578 offset = tmp & 0xffff;
579
580 ret = m88rs2000_writereg(state, 0x9a, 0x30);
783 /* Unknown usually 0xc6 sometimes 0xc1 */ 581 /* Unknown usually 0xc6 sometimes 0xc1 */
784 reg = m88rs2000_demod_read(state, 0x86); 582 reg = m88rs2000_readreg(state, 0x86);
785 ret |= m88rs2000_demod_write(state, 0x86, reg); 583 ret |= m88rs2000_writereg(state, 0x86, reg);
786 /* Offset lower nibble always 0 */ 584 /* Offset lower nibble always 0 */
787 ret |= m88rs2000_demod_write(state, 0x9c, (offset >> 8)); 585 ret |= m88rs2000_writereg(state, 0x9c, (offset >> 8));
788 ret |= m88rs2000_demod_write(state, 0x9d, offset & 0xf0); 586 ret |= m88rs2000_writereg(state, 0x9d, offset & 0xf0);
789 587
790 588
791 /* Reset Demod */ 589 /* Reset Demod */
@@ -794,16 +592,16 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
794 return -ENODEV; 592 return -ENODEV;
795 593
796 /* Unknown */ 594 /* Unknown */
797 reg = m88rs2000_demod_read(state, 0x70); 595 reg = m88rs2000_readreg(state, 0x70);
798 ret = m88rs2000_demod_write(state, 0x70, reg); 596 ret = m88rs2000_writereg(state, 0x70, reg);
799 597
800 /* Set FEC */ 598 /* Set FEC */
801 ret |= m88rs2000_set_fec(state, c->fec_inner); 599 ret |= m88rs2000_set_fec(state, c->fec_inner);
802 ret |= m88rs2000_demod_write(state, 0x85, 0x1); 600 ret |= m88rs2000_writereg(state, 0x85, 0x1);
803 ret |= m88rs2000_demod_write(state, 0x8a, 0xbf); 601 ret |= m88rs2000_writereg(state, 0x8a, 0xbf);
804 ret |= m88rs2000_demod_write(state, 0x8d, 0x1e); 602 ret |= m88rs2000_writereg(state, 0x8d, 0x1e);
805 ret |= m88rs2000_demod_write(state, 0x90, 0xf1); 603 ret |= m88rs2000_writereg(state, 0x90, 0xf1);
806 ret |= m88rs2000_demod_write(state, 0x91, 0x08); 604 ret |= m88rs2000_writereg(state, 0x91, 0x08);
807 605
808 if (ret < 0) 606 if (ret < 0)
809 return -ENODEV; 607 return -ENODEV;
@@ -819,27 +617,25 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
819 return -ENODEV; 617 return -ENODEV;
820 618
821 for (i = 0; i < 25; i++) { 619 for (i = 0; i < 25; i++) {
822 reg = m88rs2000_demod_read(state, 0x8c); 620 reg = m88rs2000_readreg(state, 0x8c);
823 if ((reg & 0x7) == 0x7) { 621 if ((reg & 0x7) == 0x7) {
824 status = FE_HAS_LOCK; 622 status = FE_HAS_LOCK;
825 break; 623 break;
826 } 624 }
827 state->no_lock_count++; 625 state->no_lock_count++;
828 if (state->no_lock_count == 15) { 626 if (state->no_lock_count == 15) {
829 reg = m88rs2000_demod_read(state, 0x70); 627 reg = m88rs2000_readreg(state, 0x70);
830 reg ^= 0x4; 628 reg ^= 0x4;
831 m88rs2000_demod_write(state, 0x70, reg); 629 m88rs2000_writereg(state, 0x70, reg);
832 state->no_lock_count = 0; 630 state->no_lock_count = 0;
833 } 631 }
834 if (state->no_lock_count == 20)
835 m88rs2000_set_tuner_rf(fe);
836 msleep(20); 632 msleep(20);
837 } 633 }
838 634
839 if (status & FE_HAS_LOCK) { 635 if (status & FE_HAS_LOCK) {
840 state->fec_inner = m88rs2000_get_fec(state); 636 state->fec_inner = m88rs2000_get_fec(state);
841 /* Uknown suspect SNR level */ 637 /* Uknown suspect SNR level */
842 reg = m88rs2000_demod_read(state, 0x65); 638 reg = m88rs2000_readreg(state, 0x65);
843 } 639 }
844 640
845 state->tuner_frequency = c->frequency; 641 state->tuner_frequency = c->frequency;
@@ -862,9 +658,9 @@ static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
862 struct m88rs2000_state *state = fe->demodulator_priv; 658 struct m88rs2000_state *state = fe->demodulator_priv;
863 659
864 if (enable) 660 if (enable)
865 m88rs2000_demod_write(state, 0x81, 0x84); 661 m88rs2000_writereg(state, 0x81, 0x84);
866 else 662 else
867 m88rs2000_demod_write(state, 0x81, 0x81); 663 m88rs2000_writereg(state, 0x81, 0x81);
868 udelay(10); 664 udelay(10);
869 return 0; 665 return 0;
870} 666}
@@ -895,7 +691,6 @@ static struct dvb_frontend_ops m88rs2000_ops = {
895 .release = m88rs2000_release, 691 .release = m88rs2000_release,
896 .init = m88rs2000_init, 692 .init = m88rs2000_init,
897 .sleep = m88rs2000_sleep, 693 .sleep = m88rs2000_sleep,
898 .write = m88rs2000_write,
899 .i2c_gate_ctrl = m88rs2000_i2c_gate_ctrl, 694 .i2c_gate_ctrl = m88rs2000_i2c_gate_ctrl,
900 .read_status = m88rs2000_read_status, 695 .read_status = m88rs2000_read_status,
901 .read_ber = m88rs2000_read_ber, 696 .read_ber = m88rs2000_read_ber,
@@ -928,9 +723,6 @@ struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config,
928 state->symbol_rate = 0; 723 state->symbol_rate = 0;
929 state->fec_inner = 0; 724 state->fec_inner = 0;
930 725
931 if (m88rs2000_startup(state) < 0)
932 goto error;
933
934 /* create dvb_frontend */ 726 /* create dvb_frontend */
935 memcpy(&state->frontend.ops, &m88rs2000_ops, 727 memcpy(&state->frontend.ops, &m88rs2000_ops,
936 sizeof(struct dvb_frontend_ops)); 728 sizeof(struct dvb_frontend_ops));
diff --git a/drivers/media/dvb-frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h
index 59acdb696873..5a8023e5a4b8 100644
--- a/drivers/media/dvb-frontends/m88rs2000.h
+++ b/drivers/media/dvb-frontends/m88rs2000.h
@@ -26,8 +26,6 @@
26struct m88rs2000_config { 26struct m88rs2000_config {
27 /* Demodulator i2c address */ 27 /* Demodulator i2c address */
28 u8 demod_addr; 28 u8 demod_addr;
29 /* Tuner address */
30 u8 tuner_addr;
31 29
32 u8 *inittab; 30 u8 *inittab;
33 31
@@ -55,12 +53,8 @@ static inline struct dvb_frontend *m88rs2000_attach(
55} 53}
56#endif /* CONFIG_DVB_M88RS2000 */ 54#endif /* CONFIG_DVB_M88RS2000 */
57 55
58#define FE_CRYSTAL_KHZ 27000
59#define FREQ_OFFSET_LOW_SYM_RATE 3000
60
61enum { 56enum {
62 DEMOD_WRITE = 0x1, 57 DEMOD_WRITE = 0x1,
63 TUNER_WRITE,
64 WRITE_DELAY = 0x10, 58 WRITE_DELAY = 0x10,
65}; 59};
66#endif /* M88RS2000_H */ 60#endif /* M88RS2000_H */
diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c
index 73010ecb9866..94e3fe21eefb 100644
--- a/drivers/media/dvb-frontends/ts2020.c
+++ b/drivers/media/dvb-frontends/ts2020.c
@@ -23,27 +23,68 @@
23#include "ts2020.h" 23#include "ts2020.h"
24 24
25#define TS2020_XTAL_FREQ 27000 /* in kHz */ 25#define TS2020_XTAL_FREQ 27000 /* in kHz */
26#define FREQ_OFFSET_LOW_SYM_RATE 3000
26 27
27struct ts2020_state { 28struct ts2020_priv {
28 u8 tuner_address; 29 /* i2c details */
30 int i2c_address;
29 struct i2c_adapter *i2c; 31 struct i2c_adapter *i2c;
32 u8 clk_out_div;
33 u32 frequency;
30}; 34};
31 35
32static int ts2020_readreg(struct dvb_frontend *fe, u8 reg) 36static int ts2020_release(struct dvb_frontend *fe)
33{ 37{
34 struct ts2020_state *state = fe->tuner_priv; 38 kfree(fe->tuner_priv);
39 fe->tuner_priv = NULL;
40 return 0;
41}
42
43static int ts2020_writereg(struct dvb_frontend *fe, int reg, int data)
44{
45 struct ts2020_priv *priv = fe->tuner_priv;
46 u8 buf[] = { reg, data };
47 struct i2c_msg msg[] = {
48 {
49 .addr = priv->i2c_address,
50 .flags = 0,
51 .buf = buf,
52 .len = 2
53 }
54 };
55 int err;
56
57 if (fe->ops.i2c_gate_ctrl)
58 fe->ops.i2c_gate_ctrl(fe, 1);
59
60 err = i2c_transfer(priv->i2c, msg, 1);
61 if (err != 1) {
62 printk(KERN_ERR
63 "%s: writereg error(err == %i, reg == 0x%02x, value == 0x%02x)\n",
64 __func__, err, reg, data);
65 return -EREMOTEIO;
66 }
35 67
68 if (fe->ops.i2c_gate_ctrl)
69 fe->ops.i2c_gate_ctrl(fe, 0);
70
71 return 0;
72}
73
74static int ts2020_readreg(struct dvb_frontend *fe, u8 reg)
75{
76 struct ts2020_priv *priv = fe->tuner_priv;
36 int ret; 77 int ret;
37 u8 b0[] = { reg }; 78 u8 b0[] = { reg };
38 u8 b1[] = { 0 }; 79 u8 b1[] = { 0 };
39 struct i2c_msg msg[] = { 80 struct i2c_msg msg[] = {
40 { 81 {
41 .addr = state->tuner_address, 82 .addr = priv->i2c_address,
42 .flags = 0, 83 .flags = 0,
43 .buf = b0, 84 .buf = b0,
44 .len = 1 85 .len = 1
45 }, { 86 }, {
46 .addr = state->tuner_address, 87 .addr = priv->i2c_address,
47 .flags = I2C_M_RD, 88 .flags = I2C_M_RD,
48 .buf = b1, 89 .buf = b1,
49 .len = 1 90 .len = 1
@@ -53,212 +94,202 @@ static int ts2020_readreg(struct dvb_frontend *fe, u8 reg)
53 if (fe->ops.i2c_gate_ctrl) 94 if (fe->ops.i2c_gate_ctrl)
54 fe->ops.i2c_gate_ctrl(fe, 1); 95 fe->ops.i2c_gate_ctrl(fe, 1);
55 96
56 ret = i2c_transfer(state->i2c, msg, 2); 97 ret = i2c_transfer(priv->i2c, msg, 2);
57
58 if (fe->ops.i2c_gate_ctrl)
59 fe->ops.i2c_gate_ctrl(fe, 0);
60 98
61 if (ret != 2) { 99 if (ret != 2) {
62 printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret); 100 printk(KERN_ERR "%s: reg=0x%x(error=%d)\n",
101 __func__, reg, ret);
63 return ret; 102 return ret;
64 } 103 }
65 104
105 if (fe->ops.i2c_gate_ctrl)
106 fe->ops.i2c_gate_ctrl(fe, 0);
107
66 return b1[0]; 108 return b1[0];
67} 109}
68 110
69static int ts2020_writereg(struct dvb_frontend *fe, int reg, int data) 111static int ts2020_sleep(struct dvb_frontend *fe)
70{ 112{
71 struct ts2020_state *state = fe->tuner_priv; 113 struct ts2020_priv *priv = fe->tuner_priv;
72 114 int ret;
73 u8 buf[] = { reg, data }; 115 u8 buf[] = { 10, 0 };
74 struct i2c_msg msg = { .addr = state->tuner_address, 116 struct i2c_msg msg = {
75 .flags = 0, .buf = buf, .len = 2 }; 117 .addr = priv->i2c_address,
76 int err; 118 .flags = 0,
77 119 .buf = buf,
120 .len = 2
121 };
78 122
79 if (fe->ops.i2c_gate_ctrl) 123 if (fe->ops.i2c_gate_ctrl)
80 fe->ops.i2c_gate_ctrl(fe, 1); 124 fe->ops.i2c_gate_ctrl(fe, 1);
81 125
82 err = i2c_transfer(state->i2c, &msg, 1); 126 ret = i2c_transfer(priv->i2c, &msg, 1);
127 if (ret != 1)
128 printk(KERN_ERR "%s: i2c error\n", __func__);
83 129
84 if (fe->ops.i2c_gate_ctrl) 130 if (fe->ops.i2c_gate_ctrl)
85 fe->ops.i2c_gate_ctrl(fe, 0); 131 fe->ops.i2c_gate_ctrl(fe, 0);
86 132
87 if (err != 1) { 133 return (ret == 1) ? 0 : ret;
88 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
89 " value == 0x%02x)\n", __func__, err, reg, data);
90 return -EREMOTEIO;
91 }
92
93 return 0;
94} 134}
95 135
96static int ts2020_init(struct dvb_frontend *fe) 136static int ts2020_init(struct dvb_frontend *fe)
97{ 137{
138 struct ts2020_priv *priv = fe->tuner_priv;
139
98 ts2020_writereg(fe, 0x42, 0x73); 140 ts2020_writereg(fe, 0x42, 0x73);
99 ts2020_writereg(fe, 0x05, 0x01); 141 ts2020_writereg(fe, 0x05, priv->clk_out_div);
100 ts2020_writereg(fe, 0x62, 0xf5); 142 ts2020_writereg(fe, 0x20, 0x27);
143 ts2020_writereg(fe, 0x07, 0x02);
144 ts2020_writereg(fe, 0x11, 0xff);
145 ts2020_writereg(fe, 0x60, 0xf9);
146 ts2020_writereg(fe, 0x08, 0x01);
147 ts2020_writereg(fe, 0x00, 0x41);
148
101 return 0; 149 return 0;
102} 150}
103 151
104static int ts2020_get_frequency(struct dvb_frontend *fe, u32 *frequency) 152static int ts2020_tuner_gate_ctrl(struct dvb_frontend *fe, u8 offset)
105{ 153{
106 u16 ndiv, div4; 154 int ret;
155 ret = ts2020_writereg(fe, 0x51, 0x1f - offset);
156 ret |= ts2020_writereg(fe, 0x51, 0x1f);
157 ret |= ts2020_writereg(fe, 0x50, offset);
158 ret |= ts2020_writereg(fe, 0x50, 0x00);
159 msleep(20);
160 return ret;
161}
107 162
108 div4 = (ts2020_readreg(fe, 0x10) & 0x10) >> 4; 163static int ts2020_set_tuner_rf(struct dvb_frontend *fe)
164{
165 int reg;
109 166
110 ndiv = ts2020_readreg(fe, 0x01); 167 reg = ts2020_readreg(fe, 0x3d);
111 ndiv &= 0x0f; 168 reg &= 0x7f;
112 ndiv <<= 8; 169 if (reg < 0x16)
113 ndiv |= ts2020_readreg(fe, 0x02); 170 reg = 0xa1;
171 else if (reg == 0x16)
172 reg = 0x99;
173 else
174 reg = 0xf9;
114 175
115 /* actual tuned frequency, i.e. including the offset */ 176 ts2020_writereg(fe, 0x60, reg);
116 *frequency = (ndiv - ndiv % 2 + 1024) * TS2020_XTAL_FREQ 177 reg = ts2020_tuner_gate_ctrl(fe, 0x08);
117 / (6 + 8) / (div4 + 1) / 2;
118 178
119 return 0; 179 return reg;
120} 180}
121 181
122static int ts2020_set_params(struct dvb_frontend *fe) 182static int ts2020_set_params(struct dvb_frontend *fe)
123{ 183{
124 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 184 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
185 struct ts2020_priv *priv = fe->demodulator_priv;
186 int ret;
187 u32 frequency = c->frequency;
188 s32 offset_khz;
189 u32 symbol_rate = (c->symbol_rate / 1000);
190 u32 f3db, gdiv28;
191 u16 value, ndiv, lpf_coeff;
192 u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf;
193 u8 lo = 0x01, div4 = 0x0;
194
195 /* Calculate frequency divider */
196 if (frequency < 1060000) {
197 lo |= 0x10;
198 div4 = 0x1;
199 ndiv = (frequency * 14 * 4) / TS2020_XTAL_FREQ;
200 } else
201 ndiv = (frequency * 14 * 2) / TS2020_XTAL_FREQ;
202 ndiv = ndiv + ndiv % 2;
203 ndiv = ndiv - 1024;
204
205 ret = ts2020_writereg(fe, 0x10, 0x80 | lo);
206
207 /* Set frequency divider */
208 ret |= ts2020_writereg(fe, 0x01, (ndiv >> 8) & 0xf);
209 ret |= ts2020_writereg(fe, 0x02, ndiv & 0xff);
210
211 ret |= ts2020_writereg(fe, 0x03, 0x06);
212 ret |= ts2020_tuner_gate_ctrl(fe, 0x10);
213 if (ret < 0)
214 return -ENODEV;
215
216 /* Tuner Frequency Range */
217 ret = ts2020_writereg(fe, 0x10, lo);
218
219 ret |= ts2020_tuner_gate_ctrl(fe, 0x08);
220
221 /* Tuner RF */
222 ret |= ts2020_set_tuner_rf(fe);
223
224 gdiv28 = (TS2020_XTAL_FREQ / 1000 * 1694 + 500) / 1000;
225 ret |= ts2020_writereg(fe, 0x04, gdiv28 & 0xff);
226 ret |= ts2020_tuner_gate_ctrl(fe, 0x04);
227 if (ret < 0)
228 return -ENODEV;
125 229
126 u8 mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf; 230 value = ts2020_readreg(fe, 0x26);
127 u16 value, ndiv;
128 u32 srate = 0, f3db;
129
130 ts2020_init(fe);
131
132 /* unknown */
133 ts2020_writereg(fe, 0x07, 0x02);
134 ts2020_writereg(fe, 0x10, 0x00);
135 ts2020_writereg(fe, 0x60, 0x79);
136 ts2020_writereg(fe, 0x08, 0x01);
137 ts2020_writereg(fe, 0x00, 0x01);
138
139 /* calculate and set freq divider */
140 if (c->frequency < 1146000) {
141 ts2020_writereg(fe, 0x10, 0x11);
142 ndiv = ((c->frequency * (6 + 8) * 4) +
143 (TS2020_XTAL_FREQ / 2)) /
144 TS2020_XTAL_FREQ - 1024;
145 } else {
146 ts2020_writereg(fe, 0x10, 0x01);
147 ndiv = ((c->frequency * (6 + 8) * 2) +
148 (TS2020_XTAL_FREQ / 2)) /
149 TS2020_XTAL_FREQ - 1024;
150 }
151
152 ts2020_writereg(fe, 0x01, (ndiv & 0x0f00) >> 8);
153 ts2020_writereg(fe, 0x02, ndiv & 0x00ff);
154
155 /* set pll */
156 ts2020_writereg(fe, 0x03, 0x06);
157 ts2020_writereg(fe, 0x51, 0x0f);
158 ts2020_writereg(fe, 0x51, 0x1f);
159 ts2020_writereg(fe, 0x50, 0x10);
160 ts2020_writereg(fe, 0x50, 0x00);
161 msleep(5);
162
163 /* unknown */
164 ts2020_writereg(fe, 0x51, 0x17);
165 ts2020_writereg(fe, 0x51, 0x1f);
166 ts2020_writereg(fe, 0x50, 0x08);
167 ts2020_writereg(fe, 0x50, 0x00);
168 msleep(5);
169
170 value = ts2020_readreg(fe, 0x3d);
171 value &= 0x0f;
172 if ((value > 4) && (value < 15)) {
173 value -= 3;
174 if (value < 4)
175 value = 4;
176 value = ((value << 3) | 0x01) & 0x79;
177 }
178 231
179 ts2020_writereg(fe, 0x60, value); 232 f3db = (symbol_rate * 135) / 200 + 2000;
180 ts2020_writereg(fe, 0x51, 0x17); 233 f3db += FREQ_OFFSET_LOW_SYM_RATE;
181 ts2020_writereg(fe, 0x51, 0x1f);
182 ts2020_writereg(fe, 0x50, 0x08);
183 ts2020_writereg(fe, 0x50, 0x00);
184
185 /* set low-pass filter period */
186 ts2020_writereg(fe, 0x04, 0x2e);
187 ts2020_writereg(fe, 0x51, 0x1b);
188 ts2020_writereg(fe, 0x51, 0x1f);
189 ts2020_writereg(fe, 0x50, 0x04);
190 ts2020_writereg(fe, 0x50, 0x00);
191 msleep(5);
192
193 srate = c->symbol_rate / 1000;
194
195 f3db = (srate << 2) / 5 + 2000;
196 if (srate < 5000)
197 f3db += 3000;
198 if (f3db < 7000) 234 if (f3db < 7000)
199 f3db = 7000; 235 f3db = 7000;
200 if (f3db > 40000) 236 if (f3db > 40000)
201 f3db = 40000; 237 f3db = 40000;
202 238
203 /* set low-pass filter baseband */ 239 gdiv28 = gdiv28 * 207 / (value * 2 + 151);
204 value = ts2020_readreg(fe, 0x26); 240 mlpf_max = gdiv28 * 135 / 100;
205 mlpf = 0x2e * 207 / ((value << 1) + 151); 241 mlpf_min = gdiv28 * 78 / 100;
206 mlpf_max = mlpf * 135 / 100;
207 mlpf_min = mlpf * 78 / 100;
208 if (mlpf_max > 63) 242 if (mlpf_max > 63)
209 mlpf_max = 63; 243 mlpf_max = 63;
210 244
211 /* rounded to the closest integer */ 245 lpf_coeff = 2766;
212 nlpf = ((mlpf * f3db * 1000) + (2766 * TS2020_XTAL_FREQ / 2)) 246
213 / (2766 * TS2020_XTAL_FREQ); 247 nlpf = (f3db * gdiv28 * 2 / lpf_coeff /
248 (TS2020_XTAL_FREQ / 1000) + 1) / 2;
214 if (nlpf > 23) 249 if (nlpf > 23)
215 nlpf = 23; 250 nlpf = 23;
216 if (nlpf < 1) 251 if (nlpf < 1)
217 nlpf = 1; 252 nlpf = 1;
218 253
219 /* rounded to the closest integer */ 254 lpf_mxdiv = (nlpf * (TS2020_XTAL_FREQ / 1000)
220 mlpf_new = ((TS2020_XTAL_FREQ * nlpf * 2766) + 255 * lpf_coeff * 2 / f3db + 1) / 2;
221 (1000 * f3db / 2)) / (1000 * f3db);
222 256
223 if (mlpf_new < mlpf_min) { 257 if (lpf_mxdiv < mlpf_min) {
224 nlpf++; 258 nlpf++;
225 mlpf_new = ((TS2020_XTAL_FREQ * nlpf * 2766) + 259 lpf_mxdiv = (nlpf * (TS2020_XTAL_FREQ / 1000)
226 (1000 * f3db / 2)) / (1000 * f3db); 260 * lpf_coeff * 2 / f3db + 1) / 2;
227 } 261 }
228 262
229 if (mlpf_new > mlpf_max) 263 if (lpf_mxdiv > mlpf_max)
230 mlpf_new = mlpf_max; 264 lpf_mxdiv = mlpf_max;
231 265
232 ts2020_writereg(fe, 0x04, mlpf_new); 266 ret = ts2020_writereg(fe, 0x04, lpf_mxdiv);
233 ts2020_writereg(fe, 0x06, nlpf); 267 ret |= ts2020_writereg(fe, 0x06, nlpf);
234 ts2020_writereg(fe, 0x51, 0x1b);
235 ts2020_writereg(fe, 0x51, 0x1f);
236 ts2020_writereg(fe, 0x50, 0x04);
237 ts2020_writereg(fe, 0x50, 0x00);
238 msleep(5);
239 268
240 /* unknown */ 269 ret |= ts2020_tuner_gate_ctrl(fe, 0x04);
241 ts2020_writereg(fe, 0x51, 0x1e);
242 ts2020_writereg(fe, 0x51, 0x1f);
243 ts2020_writereg(fe, 0x50, 0x01);
244 ts2020_writereg(fe, 0x50, 0x00);
245 msleep(60);
246 270
247 return 0; 271 ret |= ts2020_tuner_gate_ctrl(fe, 0x01);
248}
249 272
250static int ts2020_release(struct dvb_frontend *fe) 273 msleep(80);
251{ 274 /* calculate offset assuming 96000kHz*/
252 struct ts2020_state *state = fe->tuner_priv; 275 offset_khz = (ndiv - ndiv % 2 + 1024) * TS2020_XTAL_FREQ
276 / (6 + 8) / (div4 + 1) / 2;
253 277
254 fe->tuner_priv = NULL; 278 priv->frequency = offset_khz;
255 kfree(state); 279
280 return (ret < 0) ? -EINVAL : 0;
281}
256 282
283static int ts2020_get_frequency(struct dvb_frontend *fe, u32 *frequency)
284{
285 struct ts2020_priv *priv = fe->tuner_priv;
286 *frequency = priv->frequency;
257 return 0; 287 return 0;
258} 288}
259 289
260static int ts2020_get_signal_strength(struct dvb_frontend *fe, 290/* read TS2020 signal strength */
261 u16 *signal_strength) 291static int ts2020_read_signal_strength(struct dvb_frontend *fe,
292 u16 *signal_strength)
262{ 293{
263 u16 sig_reading, sig_strength; 294 u16 sig_reading, sig_strength;
264 u8 rfgain, bbgain; 295 u8 rfgain, bbgain;
@@ -281,35 +312,57 @@ static int ts2020_get_signal_strength(struct dvb_frontend *fe,
281 return 0; 312 return 0;
282} 313}
283 314
284static struct dvb_tuner_ops ts2020_ops = { 315static struct dvb_tuner_ops ts2020_tuner_ops = {
285 .info = { 316 .info = {
286 .name = "Montage Technology TS2020 Silicon Tuner", 317 .name = "TS2020",
287 .frequency_min = 950000, 318 .frequency_min = 950000,
288 .frequency_max = 2150000, 319 .frequency_max = 2150000
289 }, 320 },
290
291 .init = ts2020_init, 321 .init = ts2020_init,
292 .release = ts2020_release, 322 .release = ts2020_release,
323 .sleep = ts2020_sleep,
293 .set_params = ts2020_set_params, 324 .set_params = ts2020_set_params,
294 .get_frequency = ts2020_get_frequency, 325 .get_frequency = ts2020_get_frequency,
295 .get_rf_strength = ts2020_get_signal_strength 326 .get_rf_strength = ts2020_read_signal_strength,
296}; 327};
297 328
298struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe, 329struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
299 const struct ts2020_config *config, struct i2c_adapter *i2c) 330 const struct ts2020_config *config,
331 struct i2c_adapter *i2c)
300{ 332{
301 struct ts2020_state *state = NULL; 333 struct ts2020_priv *priv = NULL;
334 u8 buf;
335
336 priv = kzalloc(sizeof(struct ts2020_priv), GFP_KERNEL);
337 if (priv == NULL)
338 return NULL;
302 339
303 /* allocate memory for the internal state */ 340 priv->i2c_address = config->tuner_address;
304 state = kzalloc(sizeof(struct ts2020_state), GFP_KERNEL); 341 priv->i2c = i2c;
305 if (!state) 342 priv->clk_out_div = config->clk_out_div;
343 fe->tuner_priv = priv;
344
345 /* Wake Up the tuner */
346 if ((0x03 & ts2020_readreg(fe, 0x00)) == 0x00) {
347 ts2020_writereg(fe, 0x00, 0x01);
348 msleep(2);
349 }
350
351 ts2020_writereg(fe, 0x00, 0x03);
352 msleep(2);
353
354 /* Check the tuner version */
355 buf = ts2020_readreg(fe, 0x00);
356 if ((buf == 0x01) || (buf == 0x41) || (buf == 0x81))
357 printk(KERN_INFO "%s: Find tuner TS2020!\n", __func__);
358 else {
359 printk(KERN_ERR "%s: Read tuner reg[0] = %d\n", __func__, buf);
360 kfree(priv);
306 return NULL; 361 return NULL;
362 }
307 363
308 /* setup the state */ 364 memcpy(&fe->ops.tuner_ops, &ts2020_tuner_ops,
309 state->tuner_address = config->tuner_address; 365 sizeof(struct dvb_tuner_ops));
310 state->i2c = i2c;
311 fe->tuner_priv = state;
312 fe->ops.tuner_ops = ts2020_ops;
313 fe->ops.read_signal_strength = fe->ops.tuner_ops.get_rf_strength; 366 fe->ops.read_signal_strength = fe->ops.tuner_ops.get_rf_strength;
314 367
315 return fe; 368 return fe;
diff --git a/drivers/media/dvb-frontends/ts2020.h b/drivers/media/dvb-frontends/ts2020.h
index 13a172dfd582..c7e64afa614a 100644
--- a/drivers/media/dvb-frontends/ts2020.h
+++ b/drivers/media/dvb-frontends/ts2020.h
@@ -26,6 +26,7 @@
26 26
27struct ts2020_config { 27struct ts2020_config {
28 u8 tuner_address; 28 u8 tuner_address;
29 u8 clk_out_div;
29}; 30};
30 31
31#if defined(CONFIG_DVB_TS2020) || \ 32#if defined(CONFIG_DVB_TS2020) || \