blob: 2930a5d6768a71d89d38ecf8d4a85b87c55a9905 [file] [log] [blame]
Igor M. Liplianine4aab642008-09-23 15:43:57 -03001/*
2 Driver for ST STV0288 demodulator
3 Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
4 for Reel Multimedia
5 Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
6 Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
7 Removed stb6000 specific tuner code and revised some
8 procedures.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/jiffies.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "stv0288.h"
36
37struct stv0288_state {
38 struct i2c_adapter *i2c;
39 const struct stv0288_config *config;
40 struct dvb_frontend frontend;
41
42 u8 initialised:1;
43 u32 tuner_frequency;
44 u32 symbol_rate;
45 fe_code_rate_t fec_inner;
46 int errmode;
47};
48
49#define STATUS_BER 0
50#define STATUS_UCBLOCKS 1
51
52static int debug;
53static int debug_legacy_dish_switch;
54#define dprintk(args...) \
55 do { \
56 if (debug) \
57 printk(KERN_DEBUG "stv0288: " args); \
58 } while (0)
59
60
61static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
62{
63 int ret;
64 u8 buf[] = { reg, data };
65 struct i2c_msg msg = {
66 .addr = state->config->demod_address,
67 .flags = 0,
68 .buf = buf,
69 .len = 2
70 };
71
72 ret = i2c_transfer(state->i2c, &msg, 1);
73
74 if (ret != 1)
75 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
76 "ret == %i)\n", __func__, reg, data, ret);
77
78 return (ret != 1) ? -EREMOTEIO : 0;
79}
80
81static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len)
82{
83 struct stv0288_state *state = fe->demodulator_priv;
84
85 if (len != 2)
86 return -EINVAL;
87
88 return stv0288_writeregI(state, buf[0], buf[1]);
89}
90
91static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
92{
93 int ret;
94 u8 b0[] = { reg };
95 u8 b1[] = { 0 };
96 struct i2c_msg msg[] = {
97 {
98 .addr = state->config->demod_address,
99 .flags = 0,
100 .buf = b0,
101 .len = 1
102 }, {
103 .addr = state->config->demod_address,
104 .flags = I2C_M_RD,
105 .buf = b1,
106 .len = 1
107 }
108 };
109
110 ret = i2c_transfer(state->i2c, msg, 2);
111
112 if (ret != 2)
113 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
114 __func__, reg, ret);
115
116 return b1[0];
117}
118
119static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
120{
121 struct stv0288_state *state = fe->demodulator_priv;
122 unsigned int temp;
123 unsigned char b[3];
124
125 if ((srate < 1000000) || (srate > 45000000))
126 return -EINVAL;
127
128 temp = (unsigned int)srate / 1000;
129
130 temp = temp * 32768;
131 temp = temp / 25;
132 temp = temp / 125;
133 b[0] = (unsigned char)((temp >> 12) & 0xff);
134 b[1] = (unsigned char)((temp >> 4) & 0xff);
135 b[2] = (unsigned char)((temp << 4) & 0xf0);
136 stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
137 stv0288_writeregI(state, 0x29, 0); /* SFRM */
138 stv0288_writeregI(state, 0x2a, 0); /* SFRL */
139
140 stv0288_writeregI(state, 0x28, b[0]);
141 stv0288_writeregI(state, 0x29, b[1]);
142 stv0288_writeregI(state, 0x2a, b[2]);
143 dprintk("stv0288: stv0288_set_symbolrate\n");
144
145 return 0;
146}
147
148static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
149 struct dvb_diseqc_master_cmd *m)
150{
151 struct stv0288_state *state = fe->demodulator_priv;
152
153 int i;
154
155 dprintk("%s\n", __func__);
156
157 stv0288_writeregI(state, 0x09, 0);
158 msleep(30);
159 stv0288_writeregI(state, 0x05, 0x16);
160
161 for (i = 0; i < m->msg_len; i++) {
162 if (stv0288_writeregI(state, 0x06, m->msg[i]))
163 return -EREMOTEIO;
164 msleep(12);
165 }
166
167 return 0;
168}
169
170static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
171 fe_sec_mini_cmd_t burst)
172{
173 struct stv0288_state *state = fe->demodulator_priv;
174
175 dprintk("%s\n", __func__);
176
177 if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */
178 return -EREMOTEIO;
179
180 if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
181 return -EREMOTEIO;
182
183 if (stv0288_writeregI(state, 0x06, 0x12))
184 return -EREMOTEIO;
185
186 return 0;
187}
188
189static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
190{
191 struct stv0288_state *state = fe->demodulator_priv;
192
193 switch (tone) {
194 case SEC_TONE_ON:
195 if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */
196 return -EREMOTEIO;
197 return stv0288_writeregI(state, 0x06, 0xff);
198
199 case SEC_TONE_OFF:
200 if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */
201 return -EREMOTEIO;
202 return stv0288_writeregI(state, 0x06, 0x00);
203
204 default:
205 return -EINVAL;
206 }
207}
208
209static u8 stv0288_inittab[] = {
210 0x01, 0x15,
211 0x02, 0x20,
212 0x09, 0x0,
213 0x0a, 0x4,
214 0x0b, 0x0,
215 0x0c, 0x0,
216 0x0d, 0x0,
217 0x0e, 0xd4,
218 0x0f, 0x30,
219 0x11, 0x80,
220 0x12, 0x03,
221 0x13, 0x48,
222 0x14, 0x84,
223 0x15, 0x45,
224 0x16, 0xb7,
225 0x17, 0x9c,
226 0x18, 0x0,
227 0x19, 0xa6,
228 0x1a, 0x88,
229 0x1b, 0x8f,
230 0x1c, 0xf0,
231 0x20, 0x0b,
232 0x21, 0x54,
233 0x22, 0x0,
234 0x23, 0x0,
235 0x2b, 0xff,
236 0x2c, 0xf7,
237 0x30, 0x0,
238 0x31, 0x1e,
239 0x32, 0x14,
240 0x33, 0x0f,
241 0x34, 0x09,
242 0x35, 0x0c,
243 0x36, 0x05,
244 0x37, 0x2f,
245 0x38, 0x16,
246 0x39, 0xbe,
247 0x3a, 0x0,
248 0x3b, 0x13,
249 0x3c, 0x11,
250 0x3d, 0x30,
251 0x40, 0x63,
252 0x41, 0x04,
253 0x42, 0x60,
254 0x43, 0x00,
255 0x44, 0x00,
256 0x45, 0x00,
257 0x46, 0x00,
258 0x47, 0x00,
259 0x4a, 0x00,
260 0x50, 0x10,
261 0x51, 0x38,
262 0x52, 0x21,
263 0x58, 0x54,
264 0x59, 0x86,
265 0x5a, 0x0,
266 0x5b, 0x9b,
267 0x5c, 0x08,
268 0x5d, 0x7f,
269 0x5e, 0x0,
270 0x5f, 0xff,
271 0x70, 0x0,
272 0x71, 0x0,
273 0x72, 0x0,
274 0x74, 0x0,
275 0x75, 0x0,
276 0x76, 0x0,
277 0x81, 0x0,
278 0x82, 0x3f,
279 0x83, 0x3f,
280 0x84, 0x0,
281 0x85, 0x0,
282 0x88, 0x0,
283 0x89, 0x0,
284 0x8a, 0x0,
285 0x8b, 0x0,
286 0x8c, 0x0,
287 0x90, 0x0,
288 0x91, 0x0,
289 0x92, 0x0,
290 0x93, 0x0,
291 0x94, 0x1c,
292 0x97, 0x0,
293 0xa0, 0x48,
294 0xa1, 0x0,
295 0xb0, 0xb8,
296 0xb1, 0x3a,
297 0xb2, 0x10,
298 0xb3, 0x82,
299 0xb4, 0x80,
300 0xb5, 0x82,
301 0xb6, 0x82,
302 0xb7, 0x82,
303 0xb8, 0x20,
304 0xb9, 0x0,
305 0xf0, 0x0,
306 0xf1, 0x0,
307 0xf2, 0xc0,
308 0x51, 0x36,
309 0x52, 0x09,
310 0x53, 0x94,
311 0x54, 0x62,
312 0x55, 0x29,
313 0x56, 0x64,
314 0x57, 0x2b,
315 0xff, 0xff,
316};
317
318static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
319{
320 dprintk("%s: %s\n", __func__,
321 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
322 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
323
324 return 0;
325}
326
327static int stv0288_init(struct dvb_frontend *fe)
328{
329 struct stv0288_state *state = fe->demodulator_priv;
330 int i;
Igor M. Liplianinde9be0e2008-10-05 08:52:18 -0300331 u8 reg;
332 u8 val;
Igor M. Liplianine4aab642008-09-23 15:43:57 -0300333
334 dprintk("stv0288: init chip\n");
335 stv0288_writeregI(state, 0x41, 0x04);
336 msleep(50);
337
Igor M. Liplianinde9be0e2008-10-05 08:52:18 -0300338 /* we have default inittab */
339 if (state->config->inittab == NULL) {
340 for (i = 0; !(stv0288_inittab[i] == 0xff &&
Igor M. Liplianine4aab642008-09-23 15:43:57 -0300341 stv0288_inittab[i + 1] == 0xff); i += 2)
Igor M. Liplianinde9be0e2008-10-05 08:52:18 -0300342 stv0288_writeregI(state, stv0288_inittab[i],
343 stv0288_inittab[i + 1]);
344 } else {
345 for (i = 0; ; i += 2) {
346 reg = state->config->inittab[i];
347 val = state->config->inittab[i+1];
348 if (reg == 0xff && val == 0xff)
349 break;
350 stv0288_writeregI(state, reg, val);
351 }
352 }
Igor M. Liplianine4aab642008-09-23 15:43:57 -0300353 return 0;
354}
355
356static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
357{
358 struct stv0288_state *state = fe->demodulator_priv;
359
360 u8 sync = stv0288_readreg(state, 0x24);
361 if (sync == 255)
362 sync = 0;
363
364 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
365
366 *status = 0;
367
368 if ((sync & 0x08) == 0x08) {
369 *status |= FE_HAS_LOCK;
370 dprintk("stv0288 has locked\n");
371 }
372
373 return 0;
374}
375
376static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
377{
378 struct stv0288_state *state = fe->demodulator_priv;
379
380 if (state->errmode != STATUS_BER)
381 return 0;
382 *ber = (stv0288_readreg(state, 0x26) << 8) |
383 stv0288_readreg(state, 0x27);
384 dprintk("stv0288_read_ber %d\n", *ber);
385
386 return 0;
387}
388
389
390static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
391{
392 struct stv0288_state *state = fe->demodulator_priv;
393
394 s32 signal = 0xffff - ((stv0288_readreg(state, 0x10) << 8));
395
396
397 signal = signal * 5 / 4;
398 *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
399 dprintk("stv0288_read_signal_strength %d\n", *strength);
400
401 return 0;
402}
403static int stv0288_sleep(struct dvb_frontend *fe)
404{
405 struct stv0288_state *state = fe->demodulator_priv;
406
407 stv0288_writeregI(state, 0x41, 0x84);
408 state->initialised = 0;
409
410 return 0;
411}
412static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
413{
414 struct stv0288_state *state = fe->demodulator_priv;
415
416 s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
417 | stv0288_readreg(state, 0x2e));
418 xsnr = 3 * (xsnr - 0xa100);
419 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
420 dprintk("stv0288_read_snr %d\n", *snr);
421
422 return 0;
423}
424
425static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
426{
427 struct stv0288_state *state = fe->demodulator_priv;
428
429 if (state->errmode != STATUS_BER)
430 return 0;
431 *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
432 stv0288_readreg(state, 0x27);
433 dprintk("stv0288_read_ber %d\n", *ucblocks);
434
435 return 0;
436}
437
438static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
439{
440 dprintk("%s(..)\n", __func__);
441 return 0;
442}
443
444static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p)
445{
446 dprintk("%s(..)\n", __func__);
447 return 0;
448}
449
450static int stv0288_set_frontend(struct dvb_frontend *fe,
451 struct dvb_frontend_parameters *dfp)
452{
453 struct stv0288_state *state = fe->demodulator_priv;
454 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
455
456 char tm;
457 unsigned char tda[3];
458
459 dprintk("%s : FE_SET_FRONTEND\n", __func__);
460
461 if (c->delivery_system != SYS_DVBS) {
462 dprintk("%s: unsupported delivery "
463 "system selected (%d)\n",
464 __func__, c->delivery_system);
465 return -EOPNOTSUPP;
466 }
467
468 if (state->config->set_ts_params)
469 state->config->set_ts_params(fe, 0);
470
471 /* only frequency & symbol_rate are used for tuner*/
472 dfp->frequency = c->frequency;
473 dfp->u.qpsk.symbol_rate = c->symbol_rate;
474 if (fe->ops.tuner_ops.set_params) {
475 fe->ops.tuner_ops.set_params(fe, dfp);
476 if (fe->ops.i2c_gate_ctrl)
477 fe->ops.i2c_gate_ctrl(fe, 0);
478 }
479
480 udelay(10);
481 stv0288_set_symbolrate(fe, c->symbol_rate);
482 /* Carrier lock control register */
483 stv0288_writeregI(state, 0x15, 0xc5);
484
485 tda[0] = 0x2b; /* CFRM */
486 tda[2] = 0x0; /* CFRL */
487 for (tm = -6; tm < 7;) {
488 /* Viterbi status */
489 if (stv0288_readreg(state, 0x24) & 0x80)
490 break;
491
492 tda[2] += 40;
493 if (tda[2] < 40)
494 tm++;
495 tda[1] = (unsigned char)tm;
496 stv0288_writeregI(state, 0x2b, tda[1]);
497 stv0288_writeregI(state, 0x2c, tda[2]);
498 udelay(30);
499 }
500
501 state->tuner_frequency = c->frequency;
502 state->fec_inner = FEC_AUTO;
503 state->symbol_rate = c->symbol_rate;
504
505 return 0;
506}
507
508static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
509{
510 struct stv0288_state *state = fe->demodulator_priv;
511
512 if (enable)
513 stv0288_writeregI(state, 0x01, 0xb5);
514 else
515 stv0288_writeregI(state, 0x01, 0x35);
516
517 udelay(1);
518
519 return 0;
520}
521
522static void stv0288_release(struct dvb_frontend *fe)
523{
524 struct stv0288_state *state = fe->demodulator_priv;
525 kfree(state);
526}
527
528static struct dvb_frontend_ops stv0288_ops = {
529
530 .info = {
531 .name = "ST STV0288 DVB-S",
532 .type = FE_QPSK,
533 .frequency_min = 950000,
534 .frequency_max = 2150000,
535 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
536 .frequency_tolerance = 0,
537 .symbol_rate_min = 1000000,
538 .symbol_rate_max = 45000000,
539 .symbol_rate_tolerance = 500, /* ppm */
540 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
541 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
542 FE_CAN_QPSK |
543 FE_CAN_FEC_AUTO
544 },
545
546 .release = stv0288_release,
547 .init = stv0288_init,
548 .sleep = stv0288_sleep,
549 .write = stv0288_write,
550 .i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
551 .read_status = stv0288_read_status,
552 .read_ber = stv0288_read_ber,
553 .read_signal_strength = stv0288_read_signal_strength,
554 .read_snr = stv0288_read_snr,
555 .read_ucblocks = stv0288_read_ucblocks,
556 .diseqc_send_master_cmd = stv0288_send_diseqc_msg,
557 .diseqc_send_burst = stv0288_send_diseqc_burst,
558 .set_tone = stv0288_set_tone,
559 .set_voltage = stv0288_set_voltage,
560
561 .set_property = stv0288_set_property,
562 .get_property = stv0288_get_property,
563 .set_frontend = stv0288_set_frontend,
564};
565
566struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
567 struct i2c_adapter *i2c)
568{
569 struct stv0288_state *state = NULL;
570 int id;
571
572 /* allocate memory for the internal state */
Matthias Schwarzott084e24a2009-08-10 22:51:01 -0300573 state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
Igor M. Liplianine4aab642008-09-23 15:43:57 -0300574 if (state == NULL)
575 goto error;
576
577 /* setup the state */
578 state->config = config;
579 state->i2c = i2c;
580 state->initialised = 0;
581 state->tuner_frequency = 0;
582 state->symbol_rate = 0;
583 state->fec_inner = 0;
584 state->errmode = STATUS_BER;
585
586 stv0288_writeregI(state, 0x41, 0x04);
587 msleep(200);
588 id = stv0288_readreg(state, 0x00);
589 dprintk("stv0288 id %x\n", id);
590
591 /* register 0x00 contains 0x11 for STV0288 */
592 if (id != 0x11)
593 goto error;
594
595 /* create dvb_frontend */
596 memcpy(&state->frontend.ops, &stv0288_ops,
597 sizeof(struct dvb_frontend_ops));
598 state->frontend.demodulator_priv = state;
599 return &state->frontend;
600
601error:
602 kfree(state);
603
604 return NULL;
605}
606EXPORT_SYMBOL(stv0288_attach);
607
608module_param(debug_legacy_dish_switch, int, 0444);
609MODULE_PARM_DESC(debug_legacy_dish_switch,
610 "Enable timing analysis for Dish Network legacy switches");
611
612module_param(debug, int, 0644);
613MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
614
615MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
616MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
617MODULE_LICENSE("GPL");
618