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