1 diff -urN a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
2 --- a/drivers/media/dvb-frontends/Kconfig 2013-04-29 08:36:01.000000000 +0800
3 +++ b/drivers/media/dvb-frontends/Kconfig 2013-05-03 17:03:57.000000000 +0800
6 A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
9 + tristate "Montage M88DS3103 based"
10 + depends on DVB_CORE && I2C
11 + default m if !MEDIA_SUBDRV_AUTOSELECT
13 + A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
16 + tristate "Montage M88DC2800 based"
17 + depends on DVB_CORE && I2C
18 + default m if !MEDIA_SUBDRV_AUTOSELECT
20 + A DVB-C tuner module. Say Y when you want to support this frontend.
23 tristate "Silicon Labs SI21XX based"
24 depends on DVB_CORE && I2C
25 diff -urN a/drivers/media/dvb-frontends/m88dc2800.c b/drivers/media/dvb-frontends/m88dc2800.c
26 --- a/drivers/media/dvb-frontends/m88dc2800.c 1970-01-01 08:00:00.000000000 +0800
27 +++ b/drivers/media/dvb-frontends/m88dc2800.c 2013-01-26 16:03:21.000000000 +0800
30 + M88DC2800/M88TC2800 - DVB-C demodulator and tuner from Montage
32 + Copyright (C) 2012 Max nibble<nibble.max@gmail.com>
33 + Copyright (C) 2011 Montage Technology / www.montage-tech.com
35 + This program is free software; you can redistribute it and/or modify
36 + it under the terms of the GNU General Public License as published by
37 + the Free Software Foundation; either version 2 of the License, or
38 + (at your option) any later version.
40 + This program is distributed in the hope that it will be useful,
41 + but WITHOUT ANY WARRANTY; without even the implied warranty of
42 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43 + GNU General Public License for more details.
45 + You should have received a copy of the GNU General Public License
46 + along with this program; if not, write to the Free Software
47 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
50 +#include <linux/delay.h>
51 +#include <linux/errno.h>
52 +#include <linux/init.h>
53 +#include <linux/kernel.h>
54 +#include <linux/module.h>
55 +#include <linux/string.h>
56 +#include <linux/slab.h>
57 +#include <asm/div64.h>
58 +#include "dvb_frontend.h"
59 +#include "m88dc2800.h"
61 +struct m88dc2800_state {
62 + struct i2c_adapter *i2c;
63 + const struct m88dc2800_config *config;
64 + struct dvb_frontend frontend;
72 + u8 tuner_init_OK; /* Tuner initialize status */
73 + u8 tuner_dev_addr; /* Tuner device address */
74 + u32 tuner_freq; /* RF frequency to be set, unit: KHz */
75 + u16 tuner_qam; /* Reserved */
77 + u8 tuner_bandwidth; /* Bandwidth of the channel, unit: MHz, 6/7/8 */
78 + u8 tuner_loopthrough; /* Tuner loop through switch, 0/1 */
79 + u32 tuner_crystal; /* Tuner crystal frequency, unit: KHz */
80 + u32 tuner_dac; /* Tuner DAC frequency, unit: KHz */
81 + u16 tuner_mtt; /* Tuner chip version, D1: 0x0d, E0: 0x0e, E1: 0x8e */
82 + u16 tuner_custom_cfg;
83 + u32 tuner_version; /* Tuner driver version number */
88 +module_param(debug, int, 0644);
89 +MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
91 +#define dprintk(args...) \
94 + printk(KERN_INFO "m88dc2800: " args); \
98 +static int m88dc2800_i2c_write(struct m88dc2800_state *state, u8 addr,
99 + u8 * p_data, u8 len)
101 + struct i2c_msg msg = { .flags = 0 };
107 + return i2c_transfer(state->i2c, &msg, 1);
110 +static int m88dc2800_i2c_read(struct m88dc2800_state *state, u8 addr,
111 + u8 * p_data, u8 len)
113 + struct i2c_msg msg = { .flags = I2C_M_RD };
119 + return i2c_transfer(state->i2c, &msg, 1);
122 +/*demod register operations.*/
123 +static int WriteReg(struct m88dc2800_state *state, u8 reg, u8 data)
125 + u8 buf[] = { reg, data };
126 + u8 addr = state->config->demod_address;
129 + dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
131 + err = m88dc2800_i2c_write(state, addr, buf, 2);
135 + "%s: writereg error(err == %i, reg == 0x%02x,"
136 + " value == 0x%02x)\n", __func__, err, reg, data);
142 +static int ReadReg(struct m88dc2800_state *state, u8 reg)
147 + u8 addr = state->config->demod_address;
149 + ret = m88dc2800_i2c_write(state, addr, b0, 1);
152 + printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
153 + __func__, reg, ret);
157 + ret = m88dc2800_i2c_read(state, addr, b1, 1);
159 + dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
163 +static int _mt_fe_tn_set_reg(struct m88dc2800_state *state, u8 reg,
168 + u8 addr = state->tuner_dev_addr;
170 + buf[1] = ReadReg(state, 0x86);
172 + ret = WriteReg(state, 0x86, buf[1]);
177 + ret = m88dc2800_i2c_write(state, addr, buf, 2);
183 +static int _mt_fe_tn_get_reg(struct m88dc2800_state *state, u8 reg,
188 + u8 addr = state->tuner_dev_addr;
190 + buf[1] = ReadReg(state, 0x86);
192 + ret = WriteReg(state, 0x86, buf[1]);
195 + ret = m88dc2800_i2c_write(state, addr, buf, 1);
199 + buf[1] = ReadReg(state, 0x86);
201 + ret = WriteReg(state, 0x86, buf[1]);
203 + return m88dc2800_i2c_read(state, addr, p_data, 1);
206 +/* Tuner operation functions.*/
207 +static int _mt_fe_tn_set_RF_front_tc2800(struct m88dc2800_state *state)
209 + u32 freq_KHz = state->tuner_freq;
211 + if (state->tuner_mtt == 0xD1) { /* D1 */
212 + if (freq_KHz <= 123000) {
213 + if (freq_KHz <= 56000) {
214 + a = 0x00; b = 0x00; c = 0x00;
215 + } else if (freq_KHz <= 64000) {
216 + a = 0x10; b = 0x01; c = 0x08;
217 + } else if (freq_KHz <= 72000) {
218 + a = 0x20; b = 0x02; c = 0x10;
219 + } else if (freq_KHz <= 80000) {
220 + a = 0x30; b = 0x03; c = 0x18;
221 + } else if (freq_KHz <= 88000) {
222 + a = 0x40; b = 0x04; c = 0x20;
223 + } else if (freq_KHz <= 96000) {
224 + a = 0x50; b = 0x05; c = 0x28;
225 + } else if (freq_KHz <= 104000) {
226 + a = 0x60; b = 0x06; c = 0x30;
228 + a = 0x70; b = 0x07; c = 0x38;
230 + _mt_fe_tn_set_reg(state, 0x58, 0x9b);
231 + _mt_fe_tn_set_reg(state, 0x59, a);
232 + _mt_fe_tn_set_reg(state, 0x5d, b);
233 + _mt_fe_tn_set_reg(state, 0x5e, c);
234 + _mt_fe_tn_set_reg(state, 0x5a, 0x75);
235 + _mt_fe_tn_set_reg(state, 0x73, 0x0c);
236 + } else { /* if (freq_KHz > 112000) */
237 + _mt_fe_tn_set_reg(state, 0x58, 0x7b);
238 + if (freq_KHz <= 304000) {
239 + if (freq_KHz <= 136000) {
240 + _mt_fe_tn_set_reg(state, 0x5e, 0x40);
241 + } else if (freq_KHz <= 160000) {
242 + _mt_fe_tn_set_reg(state, 0x5e, 0x48);
243 + } else if (freq_KHz <= 184000) {
244 + _mt_fe_tn_set_reg(state, 0x5e, 0x50);
245 + } else if (freq_KHz <= 208000) {
246 + _mt_fe_tn_set_reg(state, 0x5e, 0x58);
247 + } else if (freq_KHz <= 232000) {
248 + _mt_fe_tn_set_reg(state, 0x5e, 0x60);
249 + } else if (freq_KHz <= 256000) {
250 + _mt_fe_tn_set_reg(state, 0x5e, 0x68);
251 + } else if (freq_KHz <= 280000) {
252 + _mt_fe_tn_set_reg(state, 0x5e, 0x70);
253 + } else { /* if (freq_KHz <= 304000) */
254 + _mt_fe_tn_set_reg(state, 0x5e, 0x78);
256 + if (freq_KHz <= 171000) {
257 + _mt_fe_tn_set_reg(state, 0x73, 0x08);
258 + } else if (freq_KHz <= 211000) {
259 + _mt_fe_tn_set_reg(state, 0x73, 0x0a);
261 + _mt_fe_tn_set_reg(state, 0x73, 0x0e);
263 + } else { /* if (freq_KHz > 304000) */
264 + _mt_fe_tn_set_reg(state, 0x5e, 0x88);
265 + if (freq_KHz <= 400000) {
266 + _mt_fe_tn_set_reg(state, 0x73, 0x0c);
267 + } else if (freq_KHz <= 450000) {
268 + _mt_fe_tn_set_reg(state, 0x73, 0x09);
269 + } else if (freq_KHz <= 550000) {
270 + _mt_fe_tn_set_reg(state, 0x73, 0x0e);
271 + } else if (freq_KHz <= 650000) {
272 + _mt_fe_tn_set_reg(state, 0x73, 0x0d);
273 + } else { /*if (freq_KHz > 650000) */
274 + _mt_fe_tn_set_reg(state, 0x73, 0x0e);
278 + if (freq_KHz > 800000)
279 + _mt_fe_tn_set_reg(state, 0x87, 0x24);
280 + else if (freq_KHz > 700000)
281 + _mt_fe_tn_set_reg(state, 0x87, 0x34);
282 + else if (freq_KHz > 500000)
283 + _mt_fe_tn_set_reg(state, 0x87, 0x44);
284 + else if (freq_KHz > 300000)
285 + _mt_fe_tn_set_reg(state, 0x87, 0x43);
286 + else if (freq_KHz > 220000)
287 + _mt_fe_tn_set_reg(state, 0x87, 0x54);
288 + else if (freq_KHz > 110000)
289 + _mt_fe_tn_set_reg(state, 0x87, 0x14);
291 + _mt_fe_tn_set_reg(state, 0x87, 0x54);
292 + if (freq_KHz > 600000)
293 + _mt_fe_tn_set_reg(state, 0x6a, 0x53);
294 + else if (freq_KHz > 500000)
295 + _mt_fe_tn_set_reg(state, 0x6a, 0x57);
297 + _mt_fe_tn_set_reg(state, 0x6a, 0x59);
298 + if (freq_KHz < 200000) {
299 + _mt_fe_tn_set_reg(state, 0x20, 0x5d);
300 + } else if (freq_KHz < 500000) {
301 + _mt_fe_tn_set_reg(state, 0x20, 0x7d);
303 + _mt_fe_tn_set_reg(state, 0x20, 0xfd);
304 + } /* end of 0xD1 */
305 + } else if (state->tuner_mtt == 0xE1) { /* E1 */
306 + if (freq_KHz <= 112000) { /* 123MHz */
307 + if (freq_KHz <= 56000) {
308 + _mt_fe_tn_set_reg(state, 0x5c, 0x01);
309 + } else if (freq_KHz <= 64000) {
310 + _mt_fe_tn_set_reg(state, 0x5c, 0x09);
311 + } else if (freq_KHz <= 72000) {
312 + _mt_fe_tn_set_reg(state, 0x5c, 0x11);
313 + } else if (freq_KHz <= 80000) {
314 + _mt_fe_tn_set_reg(state, 0x5c, 0x19);
315 + } else if (freq_KHz <= 88000) {
316 + _mt_fe_tn_set_reg(state, 0x5c, 0x21);
317 + } else if (freq_KHz <= 96000) {
318 + _mt_fe_tn_set_reg(state, 0x5c, 0x29);
319 + } else if (freq_KHz <= 104000) {
320 + _mt_fe_tn_set_reg(state, 0x5c, 0x31);
321 + } else { /* if (freq_KHz <= 112000) */
322 + _mt_fe_tn_set_reg(state, 0x5c, 0x39);
324 + _mt_fe_tn_set_reg(state, 0x5b, 0x30);
325 + } else { /* if (freq_KHz > 112000) */
326 + if (freq_KHz <= 304000) {
327 + if (freq_KHz <= 136000) {
328 + _mt_fe_tn_set_reg(state, 0x5c, 0x41);
329 + } else if (freq_KHz <= 160000) {
330 + _mt_fe_tn_set_reg(state, 0x5c, 0x49);
331 + } else if (freq_KHz <= 184000) {
332 + _mt_fe_tn_set_reg(state, 0x5c, 0x51);
333 + } else if (freq_KHz <= 208000) {
334 + _mt_fe_tn_set_reg(state, 0x5c, 0x59);
335 + } else if (freq_KHz <= 232000) {
336 + _mt_fe_tn_set_reg(state, 0x5c, 0x61);
337 + } else if (freq_KHz <= 256000) {
338 + _mt_fe_tn_set_reg(state, 0x5c, 0x69);
339 + } else if (freq_KHz <= 280000) {
340 + _mt_fe_tn_set_reg(state, 0x5c, 0x71);
341 + } else { /* if (freq_KHz <= 304000) */
342 + _mt_fe_tn_set_reg(state, 0x5c, 0x79);
344 + if (freq_KHz <= 150000) {
345 + _mt_fe_tn_set_reg(state, 0x5b, 0x28);
346 + } else if (freq_KHz <= 256000) {
347 + _mt_fe_tn_set_reg(state, 0x5b, 0x29);
349 + _mt_fe_tn_set_reg(state, 0x5b, 0x2a);
351 + } else { /* if (freq_KHz > 304000) */
352 + if (freq_KHz <= 400000) {
353 + _mt_fe_tn_set_reg(state, 0x5c, 0x89);
354 + } else if (freq_KHz <= 450000) {
355 + _mt_fe_tn_set_reg(state, 0x5c, 0x91);
356 + } else if (freq_KHz <= 650000) {
357 + _mt_fe_tn_set_reg(state, 0x5c, 0x98);
358 + } else if (freq_KHz <= 850000) {
359 + _mt_fe_tn_set_reg(state, 0x5c, 0xa0);
361 + _mt_fe_tn_set_reg(state, 0x5c, 0xa8);
363 + _mt_fe_tn_set_reg(state, 0x5b, 0x08);
366 + } /* end of 0xE1 */
370 +static int _mt_fe_tn_cali_PLL_tc2800(struct m88dc2800_state *state,
372 + u32 cali_freq_thres_div2,
373 + u32 cali_freq_thres_div3r,
374 + u32 cali_freq_thres_div3)
379 + const s32 crystal_KHz = state->tuner_crystal;
380 + if (state->tuner_mtt == 0xD1) {
381 + M = state->tuner_crystal / 4000;
382 + if (freq_KHz > cali_freq_thres_div2) {
385 + } else if (freq_KHz > 300000) {
388 + } else if (freq_KHz > (cali_freq_thres_div2 / 2)) {
391 + } else if (freq_KHz > (cali_freq_thres_div2 / 4)) {
394 + } else if (freq_KHz > (cali_freq_thres_div2 / 8)) {
397 + } else if (freq_KHz > (cali_freq_thres_div2 / 16)) {
400 + } else { /* invalid */
405 + } else if (state->tuner_mtt == 0xE1) {
406 + M = state->tuner_crystal / 1000;
407 + _mt_fe_tn_set_reg(state, 0x30, 0xff);
408 + _mt_fe_tn_set_reg(state, 0x32, 0xe0);
409 + _mt_fe_tn_set_reg(state, 0x33, 0x86);
410 + _mt_fe_tn_set_reg(state, 0x37, 0x70);
411 + _mt_fe_tn_set_reg(state, 0x38, 0x20);
412 + _mt_fe_tn_set_reg(state, 0x39, 0x18);
413 + _mt_fe_tn_set_reg(state, 0x89, 0x83);
414 + if (freq_KHz > cali_freq_thres_div2) {
418 + tmp2 = M + 16; /* 48 */
419 + } else if (freq_KHz > cali_freq_thres_div3r) {
423 + tmp2 = M + 32; /* 32 */
424 + } else if (freq_KHz > cali_freq_thres_div3) {
429 + } else if (freq_KHz > 304000) {
433 + tmp2 = M + 16; /* 48 */
434 + } else if (freq_KHz > (cali_freq_thres_div2 / 2)) {
438 + tmp2 = M + 16; /* 48 */
439 + } else if (freq_KHz > (cali_freq_thres_div3r / 2)) {
443 + tmp2 = M + 32; /* 32 */
444 + } else if (freq_KHz > (cali_freq_thres_div3 / 2)) {
449 + } else if (freq_KHz > (cali_freq_thres_div2 / 4)) {
453 + tmp2 = M + 16; /* 48 */
454 + } else if (freq_KHz > (cali_freq_thres_div3r / 4)) {
458 + tmp2 = M + 32; /* 32 */
459 + } else if (freq_KHz > (cali_freq_thres_div3 / 4)) {
464 + } else if (freq_KHz > (cali_freq_thres_div2 / 8)) {
468 + tmp2 = M + 16; /* 48 */
469 + } else if (freq_KHz > (cali_freq_thres_div3r / 8)) {
473 + tmp2 = M + 32; /* 32 */
474 + } else if (freq_KHz > (cali_freq_thres_div3 / 8)) {
479 + } else if (freq_KHz > (cali_freq_thres_div2 / 16)) {
483 + tmp2 = M + 16; /* 48 */
484 + } else if (freq_KHz > (cali_freq_thres_div3r / 16)) {
488 + tmp2 = M + 32; /* 32 */
489 + } else if (freq_KHz > (cali_freq_thres_div3 / 16)) {
494 + } else { /* invalid */
501 + if (freq_KHz == 291000) {
502 + M = state->tuner_crystal / 1000 / 3;
505 + tmp2 = M + 32; /* 32 */
508 + if (freq_KHz == 578000) {
509 + M = state->tuner_crystal / 1000 / 4;
512 + tmp2 = M + 16; // 48
515 + if (freq_KHz == 690000) {
516 + M = state->tuner_crystal / 1000 / 3;
519 + tmp2 = M + 16; /* 48 */
521 + _mt_fe_tn_get_reg(state, 0x33, &buf);
524 + _mt_fe_tn_set_reg(state, 0x33, buf);
528 + _mt_fe_tn_get_reg(state, 0x39, &buf);
531 + _mt_fe_tn_set_reg(state, 0x39, buf);
532 + N = (freq_KHz * MUL * M / crystal_KHz) / 2 * 2 - 256;
533 + buf = (N >> 8) & 0xcf;
534 + if (state->tuner_mtt == 0xE1) {
537 + _mt_fe_tn_set_reg(state, 0x34, buf);
539 + _mt_fe_tn_set_reg(state, 0x35, buf);
540 + F = ((freq_KHz * MUL * M / (crystal_KHz / 1000) / 2) -
541 + (freq_KHz * MUL * M / crystal_KHz / 2 * 1000)) * 64 / 1000;
543 + _mt_fe_tn_set_reg(state, 0x36, buf);
545 + if (state->tuner_mtt == 0xD1) {
546 + _mt_fe_tn_set_reg(state, 0x3d, 0xca);
547 + } else if (state->tuner_mtt == 0xE1) {
548 + _mt_fe_tn_set_reg(state, 0x3d, 0xfe);
552 + _mt_fe_tn_set_reg(state, 0x3e, 0x9c);
553 + _mt_fe_tn_set_reg(state, 0x3f, 0x34);
556 + if (state->tuner_mtt == 0xD1) {
557 + if ((F == 32) || (F == 16) || (F == 48)) {
558 + _mt_fe_tn_set_reg(state, 0x3e, 0xa4);
559 + _mt_fe_tn_set_reg(state, 0x3d, 0x4a);
560 + _mt_fe_tn_set_reg(state, 0x3f, 0x36);
562 + _mt_fe_tn_set_reg(state, 0x3e, 0xa4);
563 + _mt_fe_tn_set_reg(state, 0x3d, 0x4a);
564 + _mt_fe_tn_set_reg(state, 0x3f, 0x36);
566 + } else if (state->tuner_mtt == 0xE1) {
567 + _mt_fe_tn_set_reg(state, 0x3e, 0xa4);
568 + _mt_fe_tn_set_reg(state, 0x3d, 0x7e);
569 + _mt_fe_tn_set_reg(state, 0x3f, 0x36);
570 + _mt_fe_tn_set_reg(state, 0x89, 0x84);
571 + _mt_fe_tn_get_reg(state, 0x39, &buf);
573 + _mt_fe_tn_set_reg(state, 0x39, buf);
574 + _mt_fe_tn_get_reg(state, 0x32, &buf);
576 + _mt_fe_tn_set_reg(state, 0x32, buf);
581 + _mt_fe_tn_set_reg(state, 0x41, 0x00);
582 + if (state->tuner_mtt == 0xD1) {
584 + } else if (state->tuner_mtt == 0xE1) {
589 + _mt_fe_tn_set_reg(state, 0x41, 0x02);
590 + _mt_fe_tn_set_reg(state, 0x30, 0x7f);
591 + _mt_fe_tn_set_reg(state, 0x30, 0xff);
592 + _mt_fe_tn_set_reg(state, 0x31, 0x80);
593 + _mt_fe_tn_set_reg(state, 0x31, 0x00);
598 +static int _mt_fe_tn_set_PLL_freq_tc2800(struct m88dc2800_state *state)
601 + u32 freq_thres_div2_KHz, freq_thres_div3r_KHz,
602 + freq_thres_div3_KHz;
603 + const u32 freq_KHz = state->tuner_freq;
604 + if (state->tuner_mtt == 0xD1) {
605 + _mt_fe_tn_set_reg(state, 0x32, 0xe1);
606 + _mt_fe_tn_set_reg(state, 0x33, 0xa6);
607 + _mt_fe_tn_set_reg(state, 0x37, 0x7f);
608 + _mt_fe_tn_set_reg(state, 0x38, 0x20);
609 + _mt_fe_tn_set_reg(state, 0x39, 0x18);
610 + _mt_fe_tn_set_reg(state, 0x40, 0x40);
611 + freq_thres_div2_KHz = 520000;
612 + _mt_fe_tn_cali_PLL_tc2800(state, freq_KHz,
613 + freq_thres_div2_KHz, 0, 0);
615 + _mt_fe_tn_get_reg(state, 0x3a, &buf);
618 + buf1 = buf1 & 0x01;
619 + if ((buf1 == 0) || (buf == 3)) {
620 + freq_thres_div2_KHz = 420000;
621 + _mt_fe_tn_cali_PLL_tc2800(state, freq_KHz,
622 + freq_thres_div2_KHz, 0,
625 + _mt_fe_tn_get_reg(state, 0x3a, &buf);
628 + freq_thres_div2_KHz = 520000;
629 + _mt_fe_tn_cali_PLL_tc2800(state, freq_KHz,
630 + freq_thres_div2_KHz,
635 + _mt_fe_tn_get_reg(state, 0x38, &buf);
636 + _mt_fe_tn_set_reg(state, 0x38, buf);
637 + _mt_fe_tn_get_reg(state, 0x32, &buf);
639 + _mt_fe_tn_set_reg(state, 0x32, buf);
640 + _mt_fe_tn_set_reg(state, 0x30, 0x7f);
641 + _mt_fe_tn_set_reg(state, 0x30, 0xff);
642 + _mt_fe_tn_get_reg(state, 0x32, &buf);
644 + _mt_fe_tn_set_reg(state, 0x32, buf);
645 + _mt_fe_tn_set_reg(state, 0x40, 0x0);
646 + _mt_fe_tn_set_reg(state, 0x30, 0x7f);
647 + _mt_fe_tn_set_reg(state, 0x30, 0xff);
648 + _mt_fe_tn_set_reg(state, 0x31, 0x80);
649 + _mt_fe_tn_set_reg(state, 0x31, 0x00);
651 + _mt_fe_tn_get_reg(state, 0x39, &buf);
654 + _mt_fe_tn_get_reg(state, 0x39, &buf);
657 + _mt_fe_tn_set_reg(state, 0x39, buf);
658 + _mt_fe_tn_get_reg(state, 0x32, &buf);
660 + _mt_fe_tn_set_reg(state, 0x32, buf);
662 + _mt_fe_tn_get_reg(state, 0x37, &buf);
665 + _mt_fe_tn_set_reg(state, 0x40, 0x40);
667 + _mt_fe_tn_set_reg(state, 0x37, buf);
668 + _mt_fe_tn_get_reg(state, 0x38, &buf);
670 + buf = (buf & 0x0f) << 2;
672 + _mt_fe_tn_set_reg(state, 0x37, buf);
673 + } else if (buf < 0x1f) {
675 + _mt_fe_tn_set_reg(state, 0x37, buf);
677 + _mt_fe_tn_get_reg(state, 0x32, &buf);
678 + buf = (buf | 0x20) & 0xef;
679 + _mt_fe_tn_set_reg(state, 0x32, buf);
680 + _mt_fe_tn_set_reg(state, 0x41, 0x00);
682 + _mt_fe_tn_set_reg(state, 0x41, 0x02);
683 + } else if (state->tuner_mtt == 0xE1) {
684 + freq_thres_div2_KHz = 580000;
685 + freq_thres_div3r_KHz = 500000;
686 + freq_thres_div3_KHz = 440000;
687 + _mt_fe_tn_cali_PLL_tc2800(state, freq_KHz,
688 + freq_thres_div2_KHz,
689 + freq_thres_div3r_KHz,
690 + freq_thres_div3_KHz);
692 + _mt_fe_tn_get_reg(state, 0x38, &buf);
693 + _mt_fe_tn_set_reg(state, 0x38, buf);
694 + _mt_fe_tn_set_reg(state, 0x30, 0x7f);
695 + _mt_fe_tn_set_reg(state, 0x30, 0xff);
696 + _mt_fe_tn_set_reg(state, 0x31, 0x80);
697 + _mt_fe_tn_set_reg(state, 0x31, 0x00);
699 + _mt_fe_tn_get_reg(state, 0x38, &buf);
700 + _mt_fe_tn_set_reg(state, 0x38, buf);
701 + _mt_fe_tn_get_reg(state, 0x32, &buf);
703 + _mt_fe_tn_set_reg(state, 0x32, buf);
704 + _mt_fe_tn_set_reg(state, 0x30, 0x7f);
705 + _mt_fe_tn_set_reg(state, 0x30, 0xff);
706 + _mt_fe_tn_get_reg(state, 0x32, &buf);
708 + _mt_fe_tn_set_reg(state, 0x32, buf);
709 + _mt_fe_tn_set_reg(state, 0x31, 0x80);
710 + _mt_fe_tn_set_reg(state, 0x31, 0x00);
712 + _mt_fe_tn_get_reg(state, 0x37, &buf);
713 + _mt_fe_tn_set_reg(state, 0x37, buf);
715 + if ((freq_KHz == 802000) || (freq_KHz == 826000)) {
716 + _mt_fe_tn_set_reg(state, 0x37, 0x5e);
719 + _mt_fe_tn_get_reg(state, 0x32, &buf);
720 + buf = (buf & 0xef) | 0x30;
721 + _mt_fe_tn_set_reg(state, 0x32, buf);
722 + _mt_fe_tn_set_reg(state, 0x41, 0x00);
724 + _mt_fe_tn_set_reg(state, 0x41, 0x02);
731 +static int _mt_fe_tn_set_BB_tc2800(struct m88dc2800_state *state)
736 + static int _mt_fe_tn_set_appendix_tc2800(struct m88dc2800_state *state)
740 + const u32 freq_KHz = state->tuner_freq;
741 + if (state->tuner_mtt == 0xD1) {
742 + if ((freq_KHz == 123000) || (freq_KHz == 147000) ||
743 + (freq_KHz == 171000) || (freq_KHz == 195000)) {
744 + _mt_fe_tn_set_reg(state, 0x20, 0x1b);
746 + if ((freq_KHz == 371000) || (freq_KHz == 419000) ||
747 + (freq_KHz == 610000) || (freq_KHz == 730000) ||
748 + (freq_KHz == 754000) || (freq_KHz == 826000)) {
749 + _mt_fe_tn_get_reg(state, 0x0d, &buf);
750 + _mt_fe_tn_set_reg(state, 0x0d, (u8) (buf + 1));
752 + if ((freq_KHz == 522000) || (freq_KHz == 578000) ||
753 + (freq_KHz == 634000) || (freq_KHz == 690000) ||
754 + (freq_KHz == 834000)) {
755 + _mt_fe_tn_get_reg(state, 0x0d, &buf);
756 + _mt_fe_tn_set_reg(state, 0x0d, (u8) (buf - 1));
758 + } else if (state->tuner_mtt == 0xE1) {
759 + _mt_fe_tn_set_reg(state, 0x20, 0xfc);
760 + if (freq_KHz == 123000 || freq_KHz == 147000 ||
761 + freq_KHz == 171000 || freq_KHz == 195000 ||
762 + freq_KHz == 219000 || freq_KHz == 267000 ||
763 + freq_KHz == 291000 || freq_KHz == 339000 ||
764 + freq_KHz == 387000 || freq_KHz == 435000 ||
765 + freq_KHz == 482000 || freq_KHz == 530000 ||
766 + freq_KHz == 722000 ||
767 + (state->tuner_custom_cfg == 1 && freq_KHz == 315000)) {
768 + _mt_fe_tn_set_reg(state, 0x20, 0x5c);
774 + static int _mt_fe_tn_set_DAC_tc2800(struct m88dc2800_state *state)
776 + u8 buf, tempnumber;
778 + s32 f1f2number, f1, f2, delta1, Totalnum1;
779 + s32 cntT, cntin, NCOI, z0, z1, z2, tmp;
780 + u32 fc, fadc, fsd, f2d;
781 + u32 FreqTrue108_Hz;
782 + s32 M = state->tuner_crystal / 4000;
783 + /* const u8 bandwidth = state->tuner_bandwidth; */
784 + const u16 DAC_fre = 108;
785 + const u32 crystal_KHz = state->tuner_crystal;
786 + const u32 DACFreq_KHz = state->tuner_dac;
787 + const u32 freq_KHz = state->tuner_freq;
789 + if (state->tuner_mtt == 0xE1) {
790 + _mt_fe_tn_get_reg(state, 0x33, &buf);
795 + _mt_fe_tn_get_reg(state, 0x34, &buf);
797 + _mt_fe_tn_get_reg(state, 0x35, &buf);
798 + N = (N << 8) + buf;
799 + buf = ((N + 256) * crystal_KHz / M / DAC_fre + 500) / 1000;
800 + if (state->tuner_mtt == 0xE1) {
801 + _mt_fe_tn_set_appendix_tc2800(state);
802 + if (freq_KHz == 187000 || freq_KHz == 195000 ||
803 + freq_KHz == 131000 || freq_KHz == 211000 ||
804 + freq_KHz == 219000 || freq_KHz == 227000 ||
805 + freq_KHz == 267000 || freq_KHz == 299000 ||
806 + freq_KHz == 347000 || freq_KHz == 363000 ||
807 + freq_KHz == 395000 || freq_KHz == 403000 ||
808 + freq_KHz == 435000 || freq_KHz == 482000 ||
809 + freq_KHz == 474000 || freq_KHz == 490000 ||
810 + freq_KHz == 610000 || freq_KHz == 642000 ||
811 + freq_KHz == 666000 || freq_KHz == 722000 ||
812 + freq_KHz == 754000 ||
813 + ((freq_KHz == 379000 || freq_KHz == 467000 ||
814 + freq_KHz == 762000) && state->tuner_custom_cfg != 1)) {
817 + if (freq_KHz == 123000 || freq_KHz == 139000 ||
818 + freq_KHz == 147000 || freq_KHz == 171000 ||
819 + freq_KHz == 179000 || freq_KHz == 203000 ||
820 + freq_KHz == 235000 || freq_KHz == 251000 ||
821 + freq_KHz == 259000 || freq_KHz == 283000 ||
822 + freq_KHz == 331000 || freq_KHz == 363000 ||
823 + freq_KHz == 371000 || freq_KHz == 387000 ||
824 + freq_KHz == 411000 || freq_KHz == 427000 ||
825 + freq_KHz == 443000 || freq_KHz == 451000 ||
826 + freq_KHz == 459000 || freq_KHz == 506000 ||
827 + freq_KHz == 514000 || freq_KHz == 538000 ||
828 + freq_KHz == 546000 || freq_KHz == 554000 ||
829 + freq_KHz == 562000 || freq_KHz == 570000 ||
830 + freq_KHz == 578000 || freq_KHz == 602000 ||
831 + freq_KHz == 626000 || freq_KHz == 658000 ||
832 + freq_KHz == 690000 || freq_KHz == 714000 ||
833 + freq_KHz == 746000 || freq_KHz == 522000 ||
834 + freq_KHz == 826000 || freq_KHz == 155000 ||
835 + freq_KHz == 530000 ||
836 + ((freq_KHz == 275000 || freq_KHz == 355000) &&
837 + state->tuner_custom_cfg != 1) ||
838 + ((freq_KHz == 467000 || freq_KHz == 762000 ||
839 + freq_KHz == 778000 || freq_KHz == 818000) &&
840 + state->tuner_custom_cfg == 1)) {
844 + _mt_fe_tn_set_reg(state, 0x0e, buf);
845 + _mt_fe_tn_set_reg(state, 0x0d, buf);
847 + (((DACFreq_KHz * M * buf) / crystal_KHz) << 16) / (N + 256) +
848 + (((DACFreq_KHz * M * buf) % crystal_KHz) << 16) / ((N + 256) *
850 + _mt_fe_tn_set_reg(state, 0xf1, (f1f2number & 0xff00) >> 8);
851 + _mt_fe_tn_set_reg(state, 0xf2, f1f2number & 0x00ff);
853 + (N + 256) * crystal_KHz / (M * buf) * 1000 +
854 + (((N + 256) * crystal_KHz) % (M * buf)) * 1000 / (M * buf);
856 + fc = FreqTrue108_Hz;
859 + f2d = state->tuner_bandwidth * 1000 / 2 - 150;
860 + f2 = (fsd / 250) * f2d / ((fc + 500) / 1000);
861 + delta1 = ((f1 - f2) << 15) / f2;
862 + Totalnum1 = ((f1 - f2) << 15) - delta1 * f2;
869 + tempnumber = (z0 & 0xff00) >> 8;
870 + _mt_fe_tn_set_reg(state, 0xc9, (u8) (tempnumber & 0x0f));
871 + tempnumber = (z0 & 0xff);
872 + _mt_fe_tn_set_reg(state, 0xca, tempnumber);
873 + tempnumber = (z1 & 0xff00) >> 8;
874 + _mt_fe_tn_set_reg(state, 0xcb, tempnumber);
875 + tempnumber = (z1 & 0xff);
876 + _mt_fe_tn_set_reg(state, 0xcc, tempnumber);
877 + tempnumber = (z2 & 0xff00) >> 8;
878 + _mt_fe_tn_set_reg(state, 0xcd, tempnumber);
879 + tempnumber = (z2 & 0xff);
880 + _mt_fe_tn_set_reg(state, 0xce, tempnumber);
884 + delta1 = ((f1 - f2) << 15) / f2;
885 + Totalnum1 = ((f1 - f2) << 15) - delta1 * f2;
886 + NCOI = (f1 << 15) / f2 - (1 << 15);
892 + tempnumber = (z0 & 0xff00) >> 8;
893 + _mt_fe_tn_set_reg(state, 0xd9, (u8) (tempnumber & 0x0f));
894 + tempnumber = (z0 & 0xff);
895 + _mt_fe_tn_set_reg(state, 0xda, tempnumber);
896 + tempnumber = (z1 & 0xff00) >> 8;
897 + _mt_fe_tn_set_reg(state, 0xdb, tempnumber);
898 + tempnumber = (z1 & 0xff);
899 + _mt_fe_tn_set_reg(state, 0xdc, tempnumber);
900 + tempnumber = (z2 & 0xff00) >> 8;
901 + _mt_fe_tn_set_reg(state, 0xdd, tempnumber);
902 + tempnumber = (z2 & 0xff);
903 + _mt_fe_tn_set_reg(state, 0xde, tempnumber);
908 +static int _mt_fe_tn_preset_tc2800(struct m88dc2800_state *state)
910 + if (state->tuner_mtt == 0xD1) {
911 + _mt_fe_tn_set_reg(state, 0x19, 0x4a);
912 + _mt_fe_tn_set_reg(state, 0x1b, 0x4b);
913 + _mt_fe_tn_set_reg(state, 0x04, 0x04);
914 + _mt_fe_tn_set_reg(state, 0x17, 0x0d);
915 + _mt_fe_tn_set_reg(state, 0x62, 0x6c);
916 + _mt_fe_tn_set_reg(state, 0x63, 0xf4);
917 + _mt_fe_tn_set_reg(state, 0x1f, 0x0e);
918 + _mt_fe_tn_set_reg(state, 0x6b, 0xf4);
919 + _mt_fe_tn_set_reg(state, 0x14, 0x01);
920 + _mt_fe_tn_set_reg(state, 0x5a, 0x75);
921 + _mt_fe_tn_set_reg(state, 0x66, 0x74);
922 + _mt_fe_tn_set_reg(state, 0x72, 0xe0);
923 + _mt_fe_tn_set_reg(state, 0x70, 0x07);
924 + _mt_fe_tn_set_reg(state, 0x15, 0x7b);
925 + _mt_fe_tn_set_reg(state, 0x55, 0x71);
926 + _mt_fe_tn_set_reg(state, 0x75, 0x55);
927 + _mt_fe_tn_set_reg(state, 0x76, 0xac);
928 + _mt_fe_tn_set_reg(state, 0x77, 0x6c);
929 + _mt_fe_tn_set_reg(state, 0x78, 0x8b);
930 + _mt_fe_tn_set_reg(state, 0x79, 0x42);
931 + _mt_fe_tn_set_reg(state, 0x7a, 0xd2);
932 + _mt_fe_tn_set_reg(state, 0x81, 0x01);
933 + _mt_fe_tn_set_reg(state, 0x82, 0x00);
934 + _mt_fe_tn_set_reg(state, 0x82, 0x02);
935 + _mt_fe_tn_set_reg(state, 0x82, 0x04);
936 + _mt_fe_tn_set_reg(state, 0x82, 0x06);
937 + _mt_fe_tn_set_reg(state, 0x82, 0x08);
938 + _mt_fe_tn_set_reg(state, 0x82, 0x09);
939 + _mt_fe_tn_set_reg(state, 0x82, 0x29);
940 + _mt_fe_tn_set_reg(state, 0x82, 0x49);
941 + _mt_fe_tn_set_reg(state, 0x82, 0x58);
942 + _mt_fe_tn_set_reg(state, 0x82, 0x59);
943 + _mt_fe_tn_set_reg(state, 0x82, 0x98);
944 + _mt_fe_tn_set_reg(state, 0x82, 0x99);
945 + _mt_fe_tn_set_reg(state, 0x10, 0x05);
946 + _mt_fe_tn_set_reg(state, 0x10, 0x0d);
947 + _mt_fe_tn_set_reg(state, 0x11, 0x95);
948 + _mt_fe_tn_set_reg(state, 0x11, 0x9d);
949 + if (state->tuner_loopthrough != 0) {
950 + _mt_fe_tn_set_reg(state, 0x67, 0x25);
952 + _mt_fe_tn_set_reg(state, 0x67, 0x05);
954 + } else if (state->tuner_mtt == 0xE1) {
955 + _mt_fe_tn_set_reg(state, 0x1b, 0x47);
956 + if (state->tuner_mode == 0) { /* DVB-C */
957 + _mt_fe_tn_set_reg(state, 0x66, 0x74);
958 + _mt_fe_tn_set_reg(state, 0x62, 0x2c);
959 + _mt_fe_tn_set_reg(state, 0x63, 0x54);
960 + _mt_fe_tn_set_reg(state, 0x68, 0x0b);
961 + _mt_fe_tn_set_reg(state, 0x14, 0x00);
962 + } else { /* CTTB */
963 + _mt_fe_tn_set_reg(state, 0x66, 0x74);
964 + _mt_fe_tn_set_reg(state, 0x62, 0x0c);
965 + _mt_fe_tn_set_reg(state, 0x63, 0x54);
966 + _mt_fe_tn_set_reg(state, 0x68, 0x0b);
967 + _mt_fe_tn_set_reg(state, 0x14, 0x05);
969 + _mt_fe_tn_set_reg(state, 0x6f, 0x00);
970 + _mt_fe_tn_set_reg(state, 0x84, 0x04);
971 + _mt_fe_tn_set_reg(state, 0x5e, 0xbe);
972 + _mt_fe_tn_set_reg(state, 0x87, 0x07);
973 + _mt_fe_tn_set_reg(state, 0x8a, 0x1f);
974 + _mt_fe_tn_set_reg(state, 0x8b, 0x1f);
975 + _mt_fe_tn_set_reg(state, 0x88, 0x30);
976 + _mt_fe_tn_set_reg(state, 0x58, 0x34);
977 + _mt_fe_tn_set_reg(state, 0x61, 0x8c);
978 + _mt_fe_tn_set_reg(state, 0x6a, 0x42);
983 +static int mt_fe_tn_wakeup_tc2800(struct m88dc2800_state *state)
985 + _mt_fe_tn_set_reg(state, 0x16, 0xb1);
986 + _mt_fe_tn_set_reg(state, 0x09, 0x7d);
990 + static int mt_fe_tn_sleep_tc2800(struct m88dc2800_state *state)
992 + _mt_fe_tn_set_reg(state, 0x16, 0xb0);
993 + _mt_fe_tn_set_reg(state, 0x09, 0x6d);
997 + static int mt_fe_tn_init_tc2800(struct m88dc2800_state *state)
999 + if (state->tuner_init_OK != 1) {
1000 + state->tuner_dev_addr = 0x61; /* TUNER_I2C_ADDR_TC2800 */
1001 + state->tuner_freq = 650000;
1002 + state->tuner_qam = 0;
1003 + state->tuner_mode = 0; // 0: DVB-C, 1: CTTB
1004 + state->tuner_bandwidth = 8;
1005 + state->tuner_loopthrough = 0;
1006 + state->tuner_crystal = 24000;
1007 + state->tuner_dac = 7200;
1008 + state->tuner_mtt = 0x00;
1009 + state->tuner_custom_cfg = 0;
1010 + state->tuner_version = 30022; /* Driver version number */
1011 + state->tuner_time = 12092611;
1012 + state->tuner_init_OK = 1;
1014 + _mt_fe_tn_set_reg(state, 0x2b, 0x46);
1015 + _mt_fe_tn_set_reg(state, 0x2c, 0x75);
1016 + if (state->tuner_mtt == 0x00) {
1018 + _mt_fe_tn_get_reg(state, 0x01, &tmp);
1019 + printk(KERN_INFO "m88dc2800: tuner id = 0x%02x ", tmp);
1022 + state->tuner_mtt = 0xD1;
1026 + state->tuner_mtt = 0xE1;
1033 + static int mt_fe_tn_set_freq_tc2800(struct m88dc2800_state *state,
1039 + mt_fe_tn_init_tc2800(state);
1040 + state->tuner_freq = freq_KHz;
1041 + _mt_fe_tn_set_reg(state, 0x21, freq_KHz > 500000 ? 0xb9 : 0x99);
1042 + mt_fe_tn_wakeup_tc2800(state);
1043 + _mt_fe_tn_set_reg(state, 0x05, 0x7f);
1044 + _mt_fe_tn_set_reg(state, 0x06, 0xf8);
1045 + _mt_fe_tn_set_RF_front_tc2800(state);
1046 + _mt_fe_tn_set_PLL_freq_tc2800(state);
1047 + _mt_fe_tn_set_DAC_tc2800(state);
1048 + _mt_fe_tn_set_BB_tc2800(state);
1049 + _mt_fe_tn_preset_tc2800(state);
1050 + _mt_fe_tn_set_reg(state, 0x05, 0x00);
1051 + _mt_fe_tn_set_reg(state, 0x06, 0x00);
1052 + if (state->tuner_mtt == 0xD1) {
1053 + _mt_fe_tn_set_reg(state, 0x00, 0x01);
1054 + _mt_fe_tn_set_reg(state, 0x00, 0x00);
1056 + _mt_fe_tn_set_reg(state, 0x41, 0x00);
1058 + _mt_fe_tn_set_reg(state, 0x41, 0x02);
1060 + _mt_fe_tn_get_reg(state, 0x69, &buf1);
1061 + buf1 = buf1 & 0x0f;
1062 + _mt_fe_tn_get_reg(state, 0x61, &buf);
1065 + _mt_fe_tn_set_reg(state, 0x6a, 0x59);
1066 + if (buf1 > 0x02) {
1067 + if (freq_KHz > 600000)
1068 + _mt_fe_tn_set_reg(state, 0x66, 0x44);
1069 + else if (freq_KHz > 500000)
1070 + _mt_fe_tn_set_reg(state, 0x66, 0x64);
1072 + _mt_fe_tn_set_reg(state, 0x66, 0x74);
1074 + if (buf1 < 0x03) {
1075 + if (freq_KHz > 800000)
1076 + _mt_fe_tn_set_reg(state, 0x87, 0x64);
1077 + else if (freq_KHz > 600000)
1078 + _mt_fe_tn_set_reg(state, 0x87, 0x54);
1079 + else if (freq_KHz > 500000)
1080 + _mt_fe_tn_set_reg(state, 0x87, 0x54);
1081 + else if (freq_KHz > 300000)
1082 + _mt_fe_tn_set_reg(state, 0x87, 0x43);
1083 + else if (freq_KHz > 220000)
1084 + _mt_fe_tn_set_reg(state, 0x87, 0x54);
1085 + else if (freq_KHz > 110000)
1086 + _mt_fe_tn_set_reg(state, 0x87, 0x14);
1088 + _mt_fe_tn_set_reg(state, 0x87, 0x54);
1090 + } else if (buf < 0x0c) {
1091 + if (freq_KHz > 800000)
1092 + _mt_fe_tn_set_reg(state, 0x87, 0x14);
1093 + else if (freq_KHz > 600000)
1094 + _mt_fe_tn_set_reg(state, 0x87, 0x14);
1095 + else if (freq_KHz > 500000)
1096 + _mt_fe_tn_set_reg(state, 0x87, 0x34);
1097 + else if (freq_KHz > 300000)
1098 + _mt_fe_tn_set_reg(state, 0x87, 0x43);
1099 + else if (freq_KHz > 220000)
1100 + _mt_fe_tn_set_reg(state, 0x87, 0x54);
1101 + else if (freq_KHz > 110000)
1102 + _mt_fe_tn_set_reg(state, 0x87, 0x14);
1104 + _mt_fe_tn_set_reg(state, 0x87, 0x54);
1107 + } else if ((state->tuner_mtt == 0xE1)) {
1108 + _mt_fe_tn_set_reg(state, 0x00, 0x01);
1109 + _mt_fe_tn_set_reg(state, 0x00, 0x00);
1111 + _mt_fe_tn_get_reg(state, 0x32, &buf);
1112 + buf = (buf & 0xef) | 0x28;
1113 + _mt_fe_tn_set_reg(state, 0x32, buf);
1115 + _mt_fe_tn_get_reg(state, 0x38, &buf);
1116 + _mt_fe_tn_set_reg(state, 0x38, buf);
1117 + _mt_fe_tn_get_reg(state, 0x32, &buf);
1118 + buf = (buf & 0xf7) | 0x10;
1119 + _mt_fe_tn_set_reg(state, 0x32, buf);
1121 + _mt_fe_tn_get_reg(state, 0x69, &buf);
1123 + _mt_fe_tn_set_reg(state, 0x2a, buf);
1126 + _mt_fe_tn_get_reg(state, 0x84, &buf);
1128 + _mt_fe_tn_set_reg(state, 0x68, 0x0a);
1129 + _mt_fe_tn_get_reg(state, 0x88, &buf1);
1130 + buf1 = buf1 & 0x1f;
1132 + _mt_fe_tn_set_reg(state, 0x66, 0x44);
1134 + _mt_fe_tn_set_reg(state, 0x66, 0x74);
1136 + if (freq_KHz <= 600000)
1137 + _mt_fe_tn_set_reg(state, 0x68, 0x0c);
1139 + _mt_fe_tn_set_reg(state, 0x68, 0x0e);
1140 + _mt_fe_tn_set_reg(state, 0x30, 0xfb);
1141 + _mt_fe_tn_set_reg(state, 0x30, 0xff);
1142 + _mt_fe_tn_set_reg(state, 0x31, 0x04);
1143 + _mt_fe_tn_set_reg(state, 0x31, 0x00);
1145 + if (state->tuner_loopthrough != 0) {
1146 + _mt_fe_tn_get_reg(state, 0x28, &buf);
1148 + _mt_fe_tn_set_reg(state, 0x28, 0xff);
1149 + _mt_fe_tn_get_reg(state, 0x61, &buf);
1152 + _mt_fe_tn_set_reg(state, 0x67, 0x74);
1154 + _mt_fe_tn_set_reg(state, 0x67, 0x64);
1156 + _mt_fe_tn_set_reg(state, 0x67, 0x54);
1158 + _mt_fe_tn_set_reg(state, 0x67, 0x44);
1161 + _mt_fe_tn_set_reg(state, 0x67, 0x34);
1171 +static int mt_fe_tn_set_BB_filter_band_tc2800(struct m88dc2800_state *state,
1176 + _mt_fe_tn_get_reg(state, 0x53, &tmp);
1178 + if (bandwidth == 6)
1180 + else if (bandwidth == 7)
1182 + else if (bandwidth == 8)
1189 + _mt_fe_tn_set_reg(state, 0x53, tmp);
1190 + state->tuner_bandwidth = bandwidth;
1195 +static s32 mt_fe_tn_get_signal_strength_tc2800(struct m88dc2800_state
1199 + s32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
1200 + s32 val1, val2, val;
1201 + s32 result2, result3, result4, result5, result6;
1204 + s32 freq_KHz = (s32) state->tuner_freq;
1205 + if (state->tuner_mtt == 0xD1) {
1206 + _mt_fe_tn_get_reg(state, 0x61, &tmp);
1207 + tmp1 = tmp & 0x0f;
1208 + _mt_fe_tn_get_reg(state, 0x69, &tmp);
1209 + tmp2 = tmp & 0x0f;
1210 + _mt_fe_tn_get_reg(state, 0x73, &tmp);
1211 + tmp3 = tmp & 0x07;
1212 + _mt_fe_tn_get_reg(state, 0x7c, &tmp);
1213 + tmp4 = (tmp >> 4) & 0x0f;
1214 + _mt_fe_tn_get_reg(state, 0x7b, &tmp);
1215 + tmp5 = tmp & 0x0f;
1216 + _mt_fe_tn_get_reg(state, 0x7f, &tmp);
1217 + tmp6 = (tmp >> 5) & 0x01;
1220 + if (freq_KHz <= 200000) {
1221 + val2 = (tmp1 - 6) * 267;
1222 + } else if (freq_KHz <= 600000) {
1223 + val2 = (tmp1 - 6) * 280;
1225 + val2 = (tmp1 - 6) * 290;
1227 + val = val1 + val2;
1234 + if ((tmp1 < 4) && (freq_KHz >= 506000)) {
1238 + val = val1 + val2;
1240 + if (freq_KHz <= 95000) {
1241 + result2 = tmp2 * 289;
1242 + } else if (freq_KHz <= 155000) {
1243 + result2 = tmp2 * 278;
1244 + } else if (freq_KHz <= 245000) {
1245 + result2 = tmp2 * 267;
1246 + } else if (freq_KHz <= 305000) {
1247 + result2 = tmp2 * 256;
1248 + } else if (freq_KHz <= 335000) {
1249 + result2 = tmp2 * 244;
1250 + } else if (freq_KHz <= 425000) {
1251 + result2 = tmp2 * 233;
1252 + } else if (freq_KHz <= 575000) {
1253 + result2 = tmp2 * 222;
1254 + } else if (freq_KHz <= 665000) {
1255 + result2 = tmp2 * 211;
1257 + result2 = tmp2 * 200;
1259 + result3 = (6 - tmp3) * 100;
1260 + result4 = 300 * tmp4;
1261 + result5 = 50 * tmp5;
1262 + result6 = 300 * tmp6;
1263 + if (freq_KHz < 105000) {
1265 + } else if (freq_KHz <= 227000) {
1266 + append = -4 * (freq_KHz / 1000 - 100) + 150;
1267 + } else if (freq_KHz <= 305000) {
1268 + append = -4 * (freq_KHz / 1000 - 100);
1269 + } else if (freq_KHz <= 419000) {
1270 + append = 500 - 40 * (freq_KHz / 1000 - 300) / 17 + 130;
1271 + } else if (freq_KHz <= 640000) {
1272 + append = 500 - 40 * (freq_KHz / 1000 - 300) / 17;
1276 + level = append - (val + result2 + result3 + result4 +
1277 + result5 + result6);
1279 + } else if (state->tuner_mtt == 0xE1) {
1280 + _mt_fe_tn_get_reg(state, 0x61, &tmp);
1281 + tmp1 = tmp & 0x0f;
1282 + _mt_fe_tn_get_reg(state, 0x84, &tmp);
1283 + tmp2 = tmp & 0x1f;
1284 + _mt_fe_tn_get_reg(state, 0x69, &tmp);
1285 + tmp3 = tmp & 0x03;
1286 + _mt_fe_tn_get_reg(state, 0x73, &tmp);
1287 + tmp4 = tmp & 0x0f;
1288 + _mt_fe_tn_get_reg(state, 0x7c, &tmp);
1289 + tmp5 = (tmp >> 4) & 0x0f;
1290 + _mt_fe_tn_get_reg(state, 0x7b, &tmp);
1291 + tmp6 = tmp & 0x0f;
1292 + if (freq_KHz < 151000) {
1293 + result2 = (1150 - freq_KHz / 100) * 163 / 33 + 4230;
1294 + result3 = (1150 - freq_KHz / 100) * 115 / 33 + 1850;
1295 + result4 = -3676 * (freq_KHz / 1000) / 100 + 6115;
1296 + } else if (freq_KHz < 257000) {
1297 + result2 = (1540 - freq_KHz / 100) * 11 / 4 + 3870;
1298 + result3 = (1540 - freq_KHz / 100) * 205 / 96 + 2100;
1299 + result4 = -21 * freq_KHz / 1000 + 5084;
1300 + } else if (freq_KHz < 305000) {
1301 + result2 = (2620 - freq_KHz / 100) * 5 / 3 + 2770;
1302 + result3 = (2620 - freq_KHz / 100) * 10 / 7 + 1700;
1304 + } else if (freq_KHz < 449000) {
1305 + result2 = (307 - freq_KHz / 1000) * 82 / 27 + 11270;
1306 + result3 = (3100 - freq_KHz / 100) * 5 / 3 + 10000;
1307 + result4 = 134 * freq_KHz / 10000 + 11875;
1309 + result2 = (307 - freq_KHz / 1000) * 82 / 27 + 11270;
1317 + } else if (tmp1 > 0) {
1326 + level = val1 - (val2 * tmp1 + 500 * tmp2 + 3000 * tmp3 -
1327 + 500 * tmp4 + 3000 * tmp5 + val * tmp6) - 1000;
1334 +/* m88dc2800 operation functions */
1335 +u8 M88DC2000GetLock(struct m88dc2800_state * state)
1338 + if (ReadReg(state, 0x80) < 0x06) {
1339 + if ((ReadReg(state, 0xdf) & 0x80) == 0x80
1340 + &&(ReadReg(state, 0x91) & 0x23) == 0x03
1341 + &&(ReadReg(state, 0x43) & 0x08) == 0x08)
1346 + if ((ReadReg(state, 0x85) & 0x08) == 0x08)
1351 + dprintk("%s, lock=%d\n", __func__, u8ret);
1355 +static int M88DC2000SetTsType(struct m88dc2800_state *state, u8 type)
1360 + WriteReg(state, 0x84, 0x6A);
1361 + WriteReg(state, 0xC0, 0x43);
1362 + WriteReg(state, 0xE2, 0x06);
1363 + regC2H = ReadReg(state, 0xC2);
1366 + WriteReg(state, 0xC2, regC2H);
1367 + WriteReg(state, 0xC1, 0x60); /* common interface */
1368 + } else if (type == 1) {
1369 + WriteReg(state, 0x84, 0x6A);
1370 + WriteReg(state, 0xC0, 0x47); /* serial format */
1371 + WriteReg(state, 0xE2, 0x02);
1372 + regC2H = ReadReg(state, 0xC2);
1374 + WriteReg(state, 0xC2, regC2H);
1375 + WriteReg(state, 0xC1, 0x00);
1377 + WriteReg(state, 0x84, 0x6C);
1378 + WriteReg(state, 0xC0, 0x43); /* parallel format */
1379 + WriteReg(state, 0xE2, 0x06);
1380 + regC2H = ReadReg(state, 0xC2);
1382 + WriteReg(state, 0xC2, regC2H);
1383 + WriteReg(state, 0xC1, 0x00);
1388 +static int M88DC2000RegInitial_TC2800(struct m88dc2800_state *state)
1390 + u8 RegE3H, RegE4H;
1392 + WriteReg(state, 0x00, 0x48);
1393 + WriteReg(state, 0x01, 0x09);
1394 + WriteReg(state, 0xFB, 0x0A);
1395 + WriteReg(state, 0xFC, 0x0B);
1396 + WriteReg(state, 0x02, 0x0B);
1397 + WriteReg(state, 0x03, 0x18);
1398 + WriteReg(state, 0x05, 0x0D);
1399 + WriteReg(state, 0x36, 0x80);
1400 + WriteReg(state, 0x43, 0x40);
1401 + WriteReg(state, 0x55, 0x7A);
1402 + WriteReg(state, 0x56, 0xD9);
1403 + WriteReg(state, 0x57, 0xDF);
1404 + WriteReg(state, 0x58, 0x39);
1405 + WriteReg(state, 0x5A, 0x00);
1406 + WriteReg(state, 0x5C, 0x71);
1407 + WriteReg(state, 0x5D, 0x23);
1408 + WriteReg(state, 0x86, 0x40);
1409 + WriteReg(state, 0xF9, 0x08);
1410 + WriteReg(state, 0x61, 0x40);
1411 + WriteReg(state, 0x62, 0x0A);
1412 + WriteReg(state, 0x90, 0x06);
1413 + WriteReg(state, 0xDE, 0x00);
1414 + WriteReg(state, 0xA0, 0x03);
1415 + WriteReg(state, 0xDF, 0x81);
1416 + WriteReg(state, 0xFA, 0x40);
1417 + WriteReg(state, 0x37, 0x10);
1418 + WriteReg(state, 0xF0, 0x40);
1419 + WriteReg(state, 0xF2, 0x9C);
1420 + WriteReg(state, 0xF3, 0x40);
1421 + RegE3H = ReadReg(state, 0xE3);
1422 + RegE4H = ReadReg(state, 0xE4);
1423 + if (((RegE3H & 0xC0) == 0x00) && ((RegE4H & 0xC0) == 0x00)) {
1424 + WriteReg(state, 0x30, 0xFF);
1425 + WriteReg(state, 0x31, 0x00);
1426 + WriteReg(state, 0x32, 0x00);
1427 + WriteReg(state, 0x33, 0x00);
1428 + WriteReg(state, 0x35, 0x32);
1429 + WriteReg(state, 0x40, 0x00);
1430 + WriteReg(state, 0x41, 0x10);
1431 + WriteReg(state, 0xF1, 0x02);
1432 + WriteReg(state, 0xF4, 0x04);
1433 + WriteReg(state, 0xF5, 0x00);
1434 + WriteReg(state, 0x42, 0x14);
1435 + WriteReg(state, 0xE1, 0x25);
1436 + } else if (((RegE3H & 0xC0) == 0x80) && ((RegE4H & 0xC0) == 0x40)) {
1437 + WriteReg(state, 0x30, 0xFF);
1438 + WriteReg(state, 0x31, 0x00);
1439 + WriteReg(state, 0x32, 0x00);
1440 + WriteReg(state, 0x33, 0x00);
1441 + WriteReg(state, 0x35, 0x32);
1442 + WriteReg(state, 0x39, 0x00);
1443 + WriteReg(state, 0x3A, 0x00);
1444 + WriteReg(state, 0x40, 0x00);
1445 + WriteReg(state, 0x41, 0x10);
1446 + WriteReg(state, 0xF1, 0x00);
1447 + WriteReg(state, 0xF4, 0x00);
1448 + WriteReg(state, 0xF5, 0x40);
1449 + WriteReg(state, 0x42, 0x14);
1450 + WriteReg(state, 0xE1, 0x25);
1451 + } else if ((RegE3H == 0x80 || RegE3H == 0x81)
1452 + && (RegE4H == 0x80 || RegE4H == 0x81)) {
1453 + WriteReg(state, 0x30, 0xFF);
1454 + WriteReg(state, 0x31, 0x00);
1455 + WriteReg(state, 0x32, 0x00);
1456 + WriteReg(state, 0x33, 0x00);
1457 + WriteReg(state, 0x35, 0x32);
1458 + WriteReg(state, 0x39, 0x00);
1459 + WriteReg(state, 0x3A, 0x00);
1460 + WriteReg(state, 0xF1, 0x00);
1461 + WriteReg(state, 0xF4, 0x00);
1462 + WriteReg(state, 0xF5, 0x40);
1463 + WriteReg(state, 0x42, 0x24);
1464 + WriteReg(state, 0xE1, 0x25);
1465 + WriteReg(state, 0x92, 0x7F);
1466 + WriteReg(state, 0x93, 0x91);
1467 + WriteReg(state, 0x95, 0x00);
1468 + WriteReg(state, 0x2B, 0x33);
1469 + WriteReg(state, 0x2A, 0x2A);
1470 + WriteReg(state, 0x2E, 0x80);
1471 + WriteReg(state, 0x25, 0x25);
1472 + WriteReg(state, 0x2D, 0xFF);
1473 + WriteReg(state, 0x26, 0xFF);
1474 + WriteReg(state, 0x27, 0x00);
1475 + WriteReg(state, 0x24, 0x25);
1476 + WriteReg(state, 0xA4, 0xFF);
1477 + WriteReg(state, 0xA3, 0x0D);
1479 + WriteReg(state, 0x30, 0xFF);
1480 + WriteReg(state, 0x31, 0x00);
1481 + WriteReg(state, 0x32, 0x00);
1482 + WriteReg(state, 0x33, 0x00);
1483 + WriteReg(state, 0x35, 0x32);
1484 + WriteReg(state, 0x39, 0x00);
1485 + WriteReg(state, 0x3A, 0x00);
1486 + WriteReg(state, 0xF1, 0x00);
1487 + WriteReg(state, 0xF4, 0x00);
1488 + WriteReg(state, 0xF5, 0x40);
1489 + WriteReg(state, 0x42, 0x24);
1490 + WriteReg(state, 0xE1, 0x27);
1491 + WriteReg(state, 0x92, 0x7F);
1492 + WriteReg(state, 0x93, 0x91);
1493 + WriteReg(state, 0x95, 0x00);
1494 + WriteReg(state, 0x2B, 0x33);
1495 + WriteReg(state, 0x2A, 0x2A);
1496 + WriteReg(state, 0x2E, 0x80);
1497 + WriteReg(state, 0x25, 0x25);
1498 + WriteReg(state, 0x2D, 0xFF);
1499 + WriteReg(state, 0x26, 0xFF);
1500 + WriteReg(state, 0x27, 0x00);
1501 + WriteReg(state, 0x24, 0x25);
1502 + WriteReg(state, 0xA4, 0xFF);
1503 + WriteReg(state, 0xA3, 0x10);
1505 + WriteReg(state, 0xF6, 0x4E);
1506 + WriteReg(state, 0xF7, 0x20);
1507 + WriteReg(state, 0x89, 0x02);
1508 + WriteReg(state, 0x14, 0x08);
1509 + WriteReg(state, 0x6F, 0x0D);
1510 + WriteReg(state, 0x10, 0xFF);
1511 + WriteReg(state, 0x11, 0x00);
1512 + WriteReg(state, 0x12, 0x30);
1513 + WriteReg(state, 0x13, 0x23);
1514 + WriteReg(state, 0x60, 0x00);
1515 + WriteReg(state, 0x69, 0x00);
1516 + WriteReg(state, 0x6A, 0x03);
1517 + WriteReg(state, 0xE0, 0x75);
1518 + WriteReg(state, 0x8D, 0x29);
1519 + WriteReg(state, 0x4E, 0xD8);
1520 + WriteReg(state, 0x88, 0x80);
1521 + WriteReg(state, 0x52, 0x79);
1522 + WriteReg(state, 0x53, 0x03);
1523 + WriteReg(state, 0x59, 0x30);
1524 + WriteReg(state, 0x5E, 0x02);
1525 + WriteReg(state, 0x5F, 0x0F);
1526 + WriteReg(state, 0x71, 0x03);
1527 + WriteReg(state, 0x72, 0x12);
1528 + WriteReg(state, 0x73, 0x12);
1533 +static int M88DC2000AutoTSClock_P(struct m88dc2800_state *state, u32 sym,
1537 + u8 clk_div, value;
1539 + "m88dc2800: M88DC2000AutoTSClock_P, symrate=%d qam=%d\n",
1559 + dataRate *= sym * 105;
1561 + if (dataRate <= 4115)
1563 + else if (dataRate <= 4800)
1565 + else if (dataRate <= 5760)
1567 + else if (dataRate <= 7200)
1569 + else if (dataRate <= 9600)
1573 + value = ReadReg(state, 0xC2);
1576 + WriteReg(state, 0xC2, value);
1580 +static int M88DC2000AutoTSClock_C(struct m88dc2800_state *state, u32 sym,
1584 + u8 clk_div, value;
1586 + "m88dc2800: M88DC2000AutoTSClock_C, symrate=%d qam=%d\n",
1606 + dataRate *= sym * 105;
1608 + if (dataRate <= 4115)
1610 + else if (dataRate <= 4800)
1612 + else if (dataRate <= 5760)
1614 + else if (dataRate <= 7200)
1616 + else if (dataRate <= 9600)
1620 + value = ReadReg(state, 0xC2);
1623 + WriteReg(state, 0xC2, value);
1627 +static int M88DC2000SetTxMode(struct m88dc2800_state *state, u8 inverted,
1632 + value |= 0x08; /* spectrum inverted */
1634 + value |= 0x01; /* J83C */
1635 + WriteReg(state, 0x83, value);
1639 +static int M88DC2000SoftReset(struct m88dc2800_state *state)
1641 + WriteReg(state, 0x80, 0x01);
1642 + WriteReg(state, 0x82, 0x00);
1644 + WriteReg(state, 0x80, 0x00);
1648 +static int M88DC2000SetSym(struct m88dc2800_state *state, u32 sym, u32 xtal)
1651 + u8 reg6FH, reg12H;
1655 + printk(KERN_INFO "%s, sym=%d, xtal=%d\n", __func__, sym, xtal);
1656 + fValue = 4294967296 * (sym + 10);
1657 + do_div(fValue, xtal);
1659 + /* fValue = 4294967296 * (sym + 10) / xtal; */
1660 + dwValue = (u32) fValue;
1661 + printk(KERN_INFO "%s, fvalue1=%x\n", __func__, dwValue);
1662 + WriteReg(state, 0x58, (u8) ((dwValue >> 24) & 0xff));
1663 + WriteReg(state, 0x57, (u8) ((dwValue >> 16) & 0xff));
1664 + WriteReg(state, 0x56, (u8) ((dwValue >> 8) & 0xff));
1665 + WriteReg(state, 0x55, (u8) ((dwValue >> 0) & 0xff));
1667 + /* fValue = 2048 * xtal / sym; */
1668 + fValue = 2048 * xtal;
1669 + do_div(fValue, sym);
1670 + dwValue = (u32) fValue;
1671 + printk(KERN_INFO "%s, fvalue2=%x\n", __func__, dwValue);
1672 + WriteReg(state, 0x5D, (u8) ((dwValue >> 8) & 0xff));
1673 + WriteReg(state, 0x5C, (u8) ((dwValue >> 0) & 0xff));
1674 + value = ReadReg(state, 0x5A);
1675 + if (((dwValue >> 16) & 0x0001) == 0)
1679 + WriteReg(state, 0x5A, value);
1680 + value = ReadReg(state, 0x89);
1685 + WriteReg(state, 0x89, value);
1686 + if (sym >= 6700) {
1689 + } else if (sym >= 4000) {
1690 + fValue = 22 * 4096 / sym;
1691 + reg6FH = (u8) fValue;
1693 + } else if (sym >= 2000) {
1694 + fValue = 14 * 4096 / sym;
1695 + reg6FH = (u8) fValue;
1698 + fValue = 7 * 4096 / sym;
1699 + reg6FH = (u8) fValue;
1702 + WriteReg(state, 0x6F, reg6FH);
1703 + WriteReg(state, 0x12, reg12H);
1704 + if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1705 + && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1707 + WriteReg(state, 0x6C, 0x16);
1708 + WriteReg(state, 0x6D, 0x10);
1709 + WriteReg(state, 0x6E, 0x18);
1711 + WriteReg(state, 0x6C, 0x14);
1712 + WriteReg(state, 0x6D, 0x0E);
1713 + WriteReg(state, 0x6E, 0x36);
1716 + WriteReg(state, 0x6C, 0x16);
1717 + WriteReg(state, 0x6D, 0x10);
1718 + WriteReg(state, 0x6E, 0x18);
1723 +static int M88DC2000SetQAM(struct m88dc2800_state *state, u16 qam)
1725 + u8 reg00H, reg4AH, regC2H, reg44H, reg4CH, reg4DH, reg74H, value;
1726 + u8 reg8BH, reg8EH;
1727 + printk(KERN_INFO "%s, qam=%d\n", __func__, qam);
1728 + regC2H = ReadReg(state, 0xC2);
1731 + case 16: /* 16 QAM */
1739 + if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1740 + && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1747 + WriteReg(state, 0x6E, 0x18);
1749 + case 32: /* 32 QAM */
1757 + if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1758 + && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1765 + WriteReg(state, 0x6E, 0x18);
1767 + case 64: /* 64 QAM */
1775 + if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1776 + && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1784 + case 128: /* 128 QAM */
1795 + case 256: /* 256 QAM */
1798 + if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1799 + && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1811 + default: /* 64 QAM */
1819 + if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1820 + && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1829 + WriteReg(state, 0x00, reg00H);
1830 + value = ReadReg(state, 0x88);
1832 + WriteReg(state, 0x88, value);
1833 + WriteReg(state, 0x4B, 0xFF);
1834 + WriteReg(state, 0x4A, reg4AH);
1836 + WriteReg(state, 0x88, value);
1837 + WriteReg(state, 0xC2, regC2H);
1838 + WriteReg(state, 0x44, reg44H);
1839 + WriteReg(state, 0x4C, reg4CH);
1840 + WriteReg(state, 0x4D, reg4DH);
1841 + WriteReg(state, 0x74, reg74H);
1842 + WriteReg(state, 0x8B, reg8BH);
1843 + WriteReg(state, 0x8E, reg8EH);
1847 +static int M88DC2000WriteTuner_TC2800(struct m88dc2800_state *state,
1850 + printk(KERN_INFO "%s, freq=%d KHz\n", __func__, freq_KHz);
1851 + return mt_fe_tn_set_freq_tc2800(state, freq_KHz);
1854 +static int m88dc2800_init(struct dvb_frontend *fe)
1856 + dprintk("%s()\n", __func__);
1860 +static int m88dc2800_set_parameters(struct dvb_frontend *fe)
1862 + struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1863 + u8 is_annex_c, is_update;
1866 + struct m88dc2800_state *state = fe->demodulator_priv;
1868 + is_annex_c = c->delivery_system == SYS_DVBC_ANNEX_C ? 1 : 0;
1870 + switch (c->modulation) {
1883 + default: /* QAM_64 */
1888 + state->inverted = c->inversion == INVERSION_ON ? 1 : 0;
1891 + "m88dc2800: state, freq=%d qam=%d sym=%d inverted=%d xtal=%d\n",
1892 + state->freq, state->qam, state->sym, state->inverted,
1895 + "m88dc2800: set frequency to %d qam=%d symrate=%d annex-c=%d\n",
1896 + c->frequency, temp_qam, c->symbol_rate, is_annex_c);
1899 + WriteReg(state, 0x80, 0x01);
1900 + if (c->frequency != state->freq) {
1901 + M88DC2000WriteTuner_TC2800(state, c->frequency / 1000);
1902 + state->freq = c->frequency;
1904 + if (c->symbol_rate != state->sym) {
1905 + M88DC2000SetSym(state, c->symbol_rate / 1000, state->xtal);
1906 + state->sym = c->symbol_rate;
1909 + if (temp_qam != state->qam) {
1910 + M88DC2000SetQAM(state, temp_qam);
1911 + state->qam = temp_qam;
1915 + if (is_update != 0) {
1916 + if (state->config->ts_mode == 3)
1917 + M88DC2000AutoTSClock_C(state, state->sym / 1000,
1920 + M88DC2000AutoTSClock_P(state, state->sym / 1000,
1924 + M88DC2000SetTxMode(state, state->inverted, is_annex_c);
1925 + M88DC2000SoftReset(state);
1926 + if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1927 + && ((ReadReg(state, 0xE4) & 0x80) == 0x80))
1928 + waiting_time = 800;
1930 + waiting_time = 500;
1931 + while (waiting_time > 0) {
1933 + waiting_time -= 50;
1934 + if (M88DC2000GetLock(state))
1938 + state->inverted = (state->inverted != 0) ? 0 : 1;
1939 + M88DC2000SetTxMode(state, state->inverted, is_annex_c);
1940 + M88DC2000SoftReset(state);
1941 + if (((ReadReg(state, 0xE3) & 0x80) == 0x80) &&
1942 + ((ReadReg(state, 0xE4) & 0x80) == 0x80))
1943 + waiting_time = 800;
1945 + waiting_time = 500;
1946 + while (waiting_time > 0) {
1948 + waiting_time -= 50;
1949 + if (M88DC2000GetLock(state))
1955 +static int m88dc2800_read_status(struct dvb_frontend *fe,
1956 + fe_status_t * status)
1958 + struct m88dc2800_state *state = fe->demodulator_priv;
1961 + if (M88DC2000GetLock(state)) {
1962 + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER
1963 + |FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK;
1968 +static int m88dc2800_read_ber(struct dvb_frontend *fe, u32 * ber)
1970 + struct m88dc2800_state *state = fe->demodulator_priv;
1973 + if (M88DC2000GetLock(state) == 0) {
1975 + } else if ((ReadReg(state, 0xA0) & 0x80) != 0x80) {
1976 + tmp = ReadReg(state, 0xA2) << 8;
1977 + tmp += ReadReg(state, 0xA1);
1979 + WriteReg(state, 0xA0, 0x05);
1980 + WriteReg(state, 0xA0, 0x85);
1982 + *ber = state->ber;
1986 +static int m88dc2800_read_signal_strength(struct dvb_frontend *fe,
1989 + struct m88dc2800_state *state = fe->demodulator_priv;
1990 + s16 tuner_strength;
1992 + tuner_strength = mt_fe_tn_get_signal_strength_tc2800(state);
1993 + *strength = tuner_strength < -107 ? 0 : tuner_strength + 107;
1998 +static int m88dc2800_read_snr(struct dvb_frontend *fe, u16 * snr)
2000 + static const u32 mes_log[] = {
2001 + 0, 3010, 4771, 6021, 6990, 7781, 8451, 9031, 9542, 10000,
2002 + 10414, 10792, 11139, 11461, 11761, 12041, 12304, 12553, 12788,
2003 + 13010, 13222, 13424, 13617, 13802, 13979, 14150, 14314, 14472,
2004 + 14624, 14771, 14914, 15052, 15185, 15315, 15441, 15563, 15682,
2005 + 15798, 15911, 16021, 16128, 16232, 16335, 16435, 16532, 16628,
2006 + 16721, 16812, 16902, 16990, 17076, 17160, 17243, 17324, 17404,
2007 + 17482, 17559, 17634, 17709, 17782, 17853, 17924, 17993, 18062,
2008 + 18129, 18195, 18261, 18325, 18388, 18451, 18513, 18573, 18633,
2009 + 18692, 18751, 18808, 18865, 18921, 18976, 19031
2011 + struct m88dc2800_state *state = fe->demodulator_priv;
2015 + if ((ReadReg(state, 0x91) & 0x23) != 0x03) {
2020 + for (i = 0; i < 30; i++) {
2021 + mse += (ReadReg(state, 0x08) << 8) + ReadReg(state, 0x07);
2026 + switch (state->qam) {
2029 + break; /* 16QAM */
2032 + break; /* 32QAM */
2035 + break; /* 64QAM */
2038 + break; /* 128QAM */
2041 + break; /* 256QAM */
2046 + _snr -= mes_log[mse - 1]; /* C - 10*log10(MSE) */
2054 +static int m88dc2800_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
2056 + struct m88dc2800_state *state = fe->demodulator_priv;
2059 + u8Value = ReadReg(state, 0xdf);
2060 + u8Value |= 0x02; /* Hold */
2061 + WriteReg(state, 0xdf, u8Value);
2063 + *ucblocks = ReadReg(state, 0xd5);
2064 + *ucblocks = (*ucblocks << 8) | ReadReg(state, 0xd4);
2066 + u8Value &= 0xfe; /* Clear */
2067 + WriteReg(state, 0xdf, u8Value);
2068 + u8Value &= 0xfc; /* Update */
2070 + WriteReg(state, 0xdf, u8Value);
2075 +static int m88dc2800_sleep(struct dvb_frontend *fe)
2077 + struct m88dc2800_state *state = fe->demodulator_priv;
2079 + mt_fe_tn_sleep_tc2800(state);
2085 +static void m88dc2800_release(struct dvb_frontend *fe)
2087 + struct m88dc2800_state *state = fe->demodulator_priv;
2091 +static struct dvb_frontend_ops m88dc2800_ops;
2093 +struct dvb_frontend *m88dc2800_attach(const struct m88dc2800_config
2094 + *config, struct i2c_adapter *i2c)
2096 + struct m88dc2800_state *state = NULL;
2098 + /* allocate memory for the internal state */
2099 + state = kzalloc(sizeof(struct m88dc2800_state), GFP_KERNEL);
2100 + if (state == NULL)
2103 + /* setup the state */
2104 + state->config = config;
2106 + state->xtal = 28800;
2108 + WriteReg(state, 0x80, 0x01);
2109 + M88DC2000RegInitial_TC2800(state);
2110 + M88DC2000SetTsType(state, state->config->ts_mode);
2111 + mt_fe_tn_init_tc2800(state);
2113 + /* create dvb_frontend */
2114 + memcpy(&state->frontend.ops, &m88dc2800_ops,
2115 + sizeof(struct dvb_frontend_ops));
2116 + state->frontend.demodulator_priv = state;
2117 + return &state->frontend;
2124 +EXPORT_SYMBOL(m88dc2800_attach);
2126 +static struct dvb_frontend_ops m88dc2800_ops = {
2127 + .delsys = {SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C},
2129 + .name = "Montage M88DC2800 DVB-C",
2130 + .frequency_stepsize = 62500,
2131 + .frequency_min = 48000000,
2132 + .frequency_max = 870000000,
2133 + .symbol_rate_min = 870000,
2134 + .symbol_rate_max = 9000000,
2135 + .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
2136 + FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO
2138 + .release = m88dc2800_release,
2139 + .init = m88dc2800_init,
2140 + .sleep = m88dc2800_sleep,
2141 + .set_frontend = m88dc2800_set_parameters,
2142 + .read_status = m88dc2800_read_status,
2143 + .read_ber = m88dc2800_read_ber,
2144 + .read_signal_strength = m88dc2800_read_signal_strength,
2145 + .read_snr = m88dc2800_read_snr,
2146 + .read_ucblocks = m88dc2800_read_ucblocks,
2149 +MODULE_DESCRIPTION("Montage DVB-C demodulator driver");
2150 +MODULE_AUTHOR("Max Nibble <nibble.max@gmail.com>");
2151 +MODULE_LICENSE("GPL");
2152 +MODULE_VERSION("1.00");
2153 diff -urN a/drivers/media/dvb-frontends/m88dc2800.h b/drivers/media/dvb-frontends/m88dc2800.h
2154 --- a/drivers/media/dvb-frontends/m88dc2800.h 1970-01-01 08:00:00.000000000 +0800
2155 +++ b/drivers/media/dvb-frontends/m88dc2800.h 2013-01-26 14:57:32.000000000 +0800
2158 + M88DC2800/M88TC2800 - DVB-C demodulator and tuner from Montage
2160 + Copyright (C) 2012 Max Nibble <nibble.max@gmail.com>
2161 + Copyright (C) 2011 Montage Technology - www.montage-tech.com
2163 + This program is free software; you can redistribute it and/or modify
2164 + it under the terms of the GNU General Public License as published by
2165 + the Free Software Foundation; either version 2 of the License, or
2166 + (at your option) any later version.
2168 + This program is distributed in the hope that it will be useful,
2169 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2170 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2171 + GNU General Public License for more details.
2173 + You should have received a copy of the GNU General Public License
2174 + along with this program; if not, write to the Free Software
2175 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2178 +#ifndef M88DC2800_H
2179 +#define M88DC2800_H
2181 +#include <linux/dvb/frontend.h>
2183 +struct m88dc2800_config {
2188 +#if defined(CONFIG_DVB_M88DC2800) || (defined(CONFIG_DVB_M88DC2800_MODULE) && defined(MODULE))
2189 +extern struct dvb_frontend* m88dc2800_attach(const struct m88dc2800_config* config,
2190 + struct i2c_adapter* i2c);
2192 +static inline struct dvb_frontend* m88dc2800_attach(const struct m88dc2800_config* config,
2193 + struct i2c_adapter* i2c)
2195 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
2198 +#endif /* CONFIG_DVB_M88DC2800 */
2199 +#endif /* M88DC2800_H */
2200 diff -urN a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
2201 --- a/drivers/media/dvb-frontends/m88ds3103.c 1970-01-01 08:00:00.000000000 +0800
2202 +++ b/drivers/media/dvb-frontends/m88ds3103.c 2013-01-30 12:33:47.000000000 +0800
2205 + Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
2207 + Copyright (C) 2011 Max nibble<nibble.max@gmail.com>
2208 + Copyright (C) 2010 Montage Technology<www.montage-tech.com>
2209 + Copyright (C) 2009 Konstantin Dimitrov.
2211 + This program is free software; you can redistribute it and/or modify
2212 + it under the terms of the GNU General Public License as published by
2213 + the Free Software Foundation; either version 2 of the License, or
2214 + (at your option) any later version.
2216 + This program is distributed in the hope that it will be useful,
2217 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2218 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2219 + GNU General Public License for more details.
2221 + You should have received a copy of the GNU General Public License
2222 + along with this program; if not, write to the Free Software
2223 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2226 +#include <linux/slab.h>
2227 +#include <linux/kernel.h>
2228 +#include <linux/module.h>
2229 +#include <linux/moduleparam.h>
2230 +#include <linux/init.h>
2231 +#include <linux/firmware.h>
2233 +#include "dvb_frontend.h"
2234 +#include "m88ds3103.h"
2235 +#include "m88ds3103_priv.h"
2238 +module_param(debug, int, 0644);
2239 +MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
2241 +#define dprintk(args...) \
2244 + printk(KERN_INFO "m88ds3103: " args); \
2247 +/*demod register operations.*/
2248 +static int m88ds3103_writereg(struct m88ds3103_state *state, int reg, int data)
2250 + u8 buf[] = { reg, data };
2251 + struct i2c_msg msg = { .addr = state->config->demod_address,
2252 + .flags = 0, .buf = buf, .len = 2 };
2256 + printk("m88ds3103: %s: write reg 0x%02x, value 0x%02x\n",
2257 + __func__, reg, data);
2259 + err = i2c_transfer(state->i2c, &msg, 1);
2261 + printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
2262 + " value == 0x%02x)\n", __func__, err, reg, data);
2263 + return -EREMOTEIO;
2268 +static int m88ds3103_readreg(struct m88ds3103_state *state, u8 reg)
2271 + u8 b0[] = { reg };
2273 + struct i2c_msg msg[] = {
2274 + { .addr = state->config->demod_address, .flags = 0,
2275 + .buf = b0, .len = 1 },
2276 + { .addr = state->config->demod_address, .flags = I2C_M_RD,
2277 + .buf = b1, .len = 1 }
2279 + ret = i2c_transfer(state->i2c, msg, 2);
2282 + printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
2283 + __func__, reg, ret);
2288 + printk(KERN_INFO "m88ds3103: read reg 0x%02x, value 0x%02x\n",
2294 +/*tuner register operations.*/
2295 +static int m88ds3103_tuner_writereg(struct m88ds3103_state *state, int reg, int data)
2297 + u8 buf[] = { reg, data };
2298 + struct i2c_msg msg = { .addr = 0x60,
2299 + .flags = 0, .buf = buf, .len = 2 };
2302 + m88ds3103_writereg(state, 0x03, 0x11);
2303 + err = i2c_transfer(state->i2c, &msg, 1);
2306 + printk("%s: writereg error(err == %i, reg == 0x%02x,"
2307 + " value == 0x%02x)\n", __func__, err, reg, data);
2308 + return -EREMOTEIO;
2314 +static int m88ds3103_tuner_readreg(struct m88ds3103_state *state, u8 reg)
2317 + u8 b0[] = { reg };
2319 + struct i2c_msg msg[] = {
2320 + { .addr = 0x60, .flags = 0,
2321 + .buf = b0, .len = 1 },
2322 + { .addr = 0x60, .flags = I2C_M_RD,
2323 + .buf = b1, .len = 1 }
2326 + m88ds3103_writereg(state, 0x03, 0x11);
2327 + ret = i2c_transfer(state->i2c, msg, 2);
2330 + printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
2337 +/* Bulk demod I2C write, for firmware download. */
2338 +static int m88ds3103_writeregN(struct m88ds3103_state *state, int reg,
2339 + const u8 *data, u16 len)
2341 + int ret = -EREMOTEIO;
2342 + struct i2c_msg msg;
2345 + buf = kmalloc(len + 1, GFP_KERNEL);
2346 + if (buf == NULL) {
2347 + printk("Unable to kmalloc\n");
2353 + memcpy(buf + 1, data, len);
2355 + msg.addr = state->config->demod_address;
2358 + msg.len = len + 1;
2361 + printk(KERN_INFO "m88ds3103: %s: write regN 0x%02x, len = %d\n",
2362 + __func__, reg, len);
2364 + ret = i2c_transfer(state->i2c, &msg, 1);
2366 + printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
2367 + __func__, ret, reg);
2377 +static int m88ds3103_load_firmware(struct dvb_frontend *fe)
2379 + struct m88ds3103_state *state = fe->demodulator_priv;
2380 + const struct firmware *fw;
2383 + dprintk("%s()\n", __func__);
2385 + if (state->skip_fw_load)
2387 + /* Load firmware */
2388 + /* request the firmware, this will block until someone uploads it */
2389 + if(state->demod_id == DS3000_ID){
2390 + printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
2391 + DS3000_DEFAULT_FIRMWARE);
2392 + ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
2393 + state->i2c->dev.parent);
2394 + }else if(state->demod_id == DS3103_ID){
2395 + printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
2396 + DS3103_DEFAULT_FIRMWARE);
2397 + ret = request_firmware(&fw, DS3103_DEFAULT_FIRMWARE,
2398 + state->i2c->dev.parent);
2401 + printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
2403 + printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
2404 + "found?)\n", __func__);
2408 + /* Make sure we don't recurse back through here during loading */
2409 + state->skip_fw_load = 1;
2411 + dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
2415 + fw->data[fw->size - 2],
2416 + fw->data[fw->size - 1]);
2418 + /* stop internal mcu. */
2419 + m88ds3103_writereg(state, 0xb2, 0x01);
2420 + /* split firmware to download.*/
2421 + for(i = 0; i < FW_DOWN_LOOP; i++){
2422 + ret = m88ds3103_writeregN(state, 0xb0, &(fw->data[FW_DOWN_SIZE*i]), FW_DOWN_SIZE);
2423 + if(ret != 1) break;
2425 + /* start internal mcu. */
2427 + m88ds3103_writereg(state, 0xb2, 0x00);
2429 + release_firmware(fw);
2431 + dprintk("%s: Firmware upload %s\n", __func__,
2432 + ret == 1 ? "complete" : "failed");
2434 + if(ret == 1) ret = 0;
2436 + /* Ensure firmware is always loaded if required */
2437 + state->skip_fw_load = 0;
2443 +static int m88ds3103_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
2445 + struct m88ds3103_state *state = fe->demodulator_priv;
2448 + dprintk("%s(%d)\n", __func__, voltage);
2450 + dprintk("m88ds3103:pin_ctrl = (%02x)\n", state->config->pin_ctrl);
2452 + if(state->config->set_voltage)
2453 + state->config->set_voltage(fe, voltage);
2455 + data = m88ds3103_readreg(state, 0xa2);
2457 + if(state->config->pin_ctrl & 0x80){ /*If control pin is assigned.*/
2458 + data &= ~0x03; /* bit0 V/H, bit1 off/on */
2459 + if(state->config->pin_ctrl & 0x02)
2462 + switch (voltage) {
2463 + case SEC_VOLTAGE_18:
2464 + if((state->config->pin_ctrl & 0x01) == 0)
2467 + case SEC_VOLTAGE_13:
2468 + if(state->config->pin_ctrl & 0x01)
2471 + case SEC_VOLTAGE_OFF:
2472 + if(state->config->pin_ctrl & 0x02)
2480 + m88ds3103_writereg(state, 0xa2, data);
2485 +static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t* status)
2487 + struct m88ds3103_state *state = fe->demodulator_priv;
2492 + switch (state->delivery_system){
2494 + lock = m88ds3103_readreg(state, 0xd1);
2495 + dprintk("%s: SYS_DVBS status=%x.\n", __func__, lock);
2497 + if ((lock & 0x07) == 0x07){
2498 + /*if((m88ds3103_readreg(state, 0x0d) & 0x07) == 0x07)*/
2499 + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER
2500 + | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
2505 + lock = m88ds3103_readreg(state, 0x0d);
2506 + dprintk("%s: SYS_DVBS2 status=%x.\n", __func__, lock);
2508 + if ((lock & 0x8f) == 0x8f)
2509 + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER
2510 + | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
2520 +static int m88ds3103_read_ber(struct dvb_frontend *fe, u32* ber)
2522 + struct m88ds3103_state *state = fe->demodulator_priv;
2523 + u8 tmp1, tmp2, tmp3;
2524 + u32 ldpc_frame_cnt, pre_err_packags, code_rate_fac = 0;
2526 + dprintk("%s()\n", __func__);
2528 + switch (state->delivery_system) {
2530 + m88ds3103_writereg(state, 0xf9, 0x04);
2531 + tmp3 = m88ds3103_readreg(state, 0xf8);
2532 + if ((tmp3&0x10) == 0){
2533 + tmp1 = m88ds3103_readreg(state, 0xf7);
2534 + tmp2 = m88ds3103_readreg(state, 0xf6);
2536 + m88ds3103_writereg(state, 0xf8, tmp3);
2537 + state->preBer = (tmp1<<8) | tmp2;
2541 + tmp1 = m88ds3103_readreg(state, 0x7e) & 0x0f;
2543 + case 0: code_rate_fac = 16008 - 80; break;
2544 + case 1: code_rate_fac = 21408 - 80; break;
2545 + case 2: code_rate_fac = 25728 - 80; break;
2546 + case 3: code_rate_fac = 32208 - 80; break;
2547 + case 4: code_rate_fac = 38688 - 80; break;
2548 + case 5: code_rate_fac = 43040 - 80; break;
2549 + case 6: code_rate_fac = 48408 - 80; break;
2550 + case 7: code_rate_fac = 51648 - 80; break;
2551 + case 8: code_rate_fac = 53840 - 80; break;
2552 + case 9: code_rate_fac = 57472 - 80; break;
2553 + case 10: code_rate_fac = 58192 - 80; break;
2556 + tmp1 = m88ds3103_readreg(state, 0xd7) & 0xff;
2557 + tmp2 = m88ds3103_readreg(state, 0xd6) & 0xff;
2558 + tmp3 = m88ds3103_readreg(state, 0xd5) & 0xff;
2559 + ldpc_frame_cnt = (tmp1 << 16) | (tmp2 << 8) | tmp3;
2561 + tmp1 = m88ds3103_readreg(state, 0xf8) & 0xff;
2562 + tmp2 = m88ds3103_readreg(state, 0xf7) & 0xff;
2563 + pre_err_packags = tmp1<<8 | tmp2;
2565 + if (ldpc_frame_cnt > 1000){
2566 + m88ds3103_writereg(state, 0xd1, 0x01);
2567 + m88ds3103_writereg(state, 0xf9, 0x01);
2568 + m88ds3103_writereg(state, 0xf9, 0x00);
2569 + m88ds3103_writereg(state, 0xd1, 0x00);
2570 + state->preBer = pre_err_packags;
2576 + *ber = state->preBer;
2581 +static int m88ds3103_read_signal_strength(struct dvb_frontend *fe,
2582 + u16 *signal_strength)
2584 + struct m88ds3103_state *state = fe->demodulator_priv;
2586 + u8 gain1, gain2, gain3 = 0;
2588 + dprintk("%s()\n", __func__);
2590 + gain1 = m88ds3103_tuner_readreg(state, 0x3d) & 0x1f;
2591 + dprintk("%s: gain1 = 0x%02x \n", __func__, gain1);
2593 + if (gain1 > 15) gain1 = 15;
2594 + gain2 = m88ds3103_tuner_readreg(state, 0x21) & 0x1f;
2595 + dprintk("%s: gain2 = 0x%02x \n", __func__, gain2);
2597 + if(state->tuner_id == TS2022_ID){
2598 + gain3 = (m88ds3103_tuner_readreg(state, 0x66)>>3) & 0x07;
2599 + dprintk("%s: gain3 = 0x%02x \n", __func__, gain3);
2601 + if (gain2 > 16) gain2 = 16;
2602 + if (gain2 < 2) gain2 = 2;
2603 + if (gain3 > 6) gain3 = 6;
2605 + if (gain2 > 13) gain2 = 13;
2609 + gain = gain1*23 + gain2*35 + gain3*29;
2610 + *signal_strength = 60000 - gain*55;
2616 +static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *p_snr)
2618 + struct m88ds3103_state *state = fe->demodulator_priv;
2619 + u8 val, npow1, npow2, spow1, cnt;
2621 + u32 npow, spow, snr_total;
2622 + static const u16 mes_log10[] ={
2623 + 0, 3010, 4771, 6021, 6990, 7781, 8451, 9031, 9542, 10000,
2624 + 10414, 10792, 11139, 11461, 11761, 12041, 12304, 12553, 12788, 13010,
2625 + 13222, 13424, 13617, 13802, 13979, 14150, 14314, 14472, 14624, 14771,
2626 + 14914, 15052, 15185, 15315, 15441, 15563, 15682, 15798, 15911, 16021,
2627 + 16128, 16232, 16335, 16435, 16532, 16628, 16721, 16812, 16902, 16990,
2628 + 17076, 17160, 17243, 17324, 17404, 17482, 17559, 17634, 17709, 17782,
2629 + 17853, 17924, 17993, 18062, 18129, 18195, 18261, 18325, 18388, 18451,
2630 + 18513, 18573, 18633, 18692, 18751, 18808, 18865, 18921, 18976, 19031
2632 + static const u16 mes_loge[] ={
2633 + 0, 6931, 10986, 13863, 16094, 17918, 19459, 20794, 21972, 23026,
2634 + 23979, 24849, 25649, 26391, 27081, 27726, 28332, 28904, 29444, 29957,
2635 + 30445, 30910, 31355, 31781, 32189, 32581, 32958, 33322, 33673, 34012,
2639 + dprintk("%s()\n", __func__);
2643 + switch (state->delivery_system){
2645 + cnt = 10; snr_total = 0;
2647 + val = m88ds3103_readreg(state, 0xff);
2651 + tmp = (u16)(snr_total/80);
2653 + if (tmp > 32) tmp = 32;
2654 + snr = (mes_loge[tmp - 1] * 100) / 45;
2660 + cnt = 10; npow = 0; spow = 0;
2662 + npow1 = m88ds3103_readreg(state, 0x8c) & 0xff;
2663 + npow2 = m88ds3103_readreg(state, 0x8d) & 0xff;
2664 + npow += (((npow1 & 0x3f) + (u16)(npow2 << 6)) >> 2);
2666 + spow1 = m88ds3103_readreg(state, 0x8e) & 0xff;
2667 + spow += ((spow1 * spow1) >> 1);
2670 + npow /= 10; spow /= 10;
2673 + }else if(npow == 0){
2677 + tmp = (u16)(spow / npow);
2678 + if (tmp > 80) tmp = 80;
2679 + snr = mes_log10[tmp - 1]*3;
2681 + tmp = (u16)(npow / spow);
2682 + if (tmp > 80) tmp = 80;
2683 + snr = -(mes_log10[tmp - 1] / 1000);
2696 +static int m88ds3103_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
2698 + struct m88ds3103_state *state = fe->demodulator_priv;
2699 + u8 tmp1, tmp2, tmp3, data;
2701 + dprintk("%s()\n", __func__);
2703 + switch (state->delivery_system) {
2705 + data = m88ds3103_readreg(state, 0xf8);
2707 + m88ds3103_writereg(state, 0xf8, data);
2708 + tmp1 = m88ds3103_readreg(state, 0xf5);
2709 + tmp2 = m88ds3103_readreg(state, 0xf4);
2710 + *ucblocks = (tmp1 <<8) | tmp2;
2712 + m88ds3103_writereg(state, 0xf8, data);
2714 + m88ds3103_writereg(state, 0xf8, data);
2716 + m88ds3103_writereg(state, 0xf8, data);
2719 + tmp1 = m88ds3103_readreg(state, 0xda);
2720 + tmp2 = m88ds3103_readreg(state, 0xd9);
2721 + tmp3 = m88ds3103_readreg(state, 0xd8);
2722 + *ucblocks = (tmp1 <<16)|(tmp2 <<8)|tmp3;
2723 + data = m88ds3103_readreg(state, 0xd1);
2725 + m88ds3103_writereg(state, 0xd1, data);
2727 + m88ds3103_writereg(state, 0xd1, data);
2735 +static int m88ds3103_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
2737 + struct m88ds3103_state *state = fe->demodulator_priv;
2738 + u8 data_a1, data_a2;
2740 + dprintk("%s(%d)\n", __func__, tone);
2741 + if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
2742 + printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
2746 + data_a1 = m88ds3103_readreg(state, 0xa1);
2747 + data_a2 = m88ds3103_readreg(state, 0xa2);
2748 + if(state->demod_id == DS3103_ID)
2749 + data_a2 &= 0xdf; /* Normal mode */
2752 + dprintk("%s: SEC_TONE_ON\n", __func__);
2758 + case SEC_TONE_OFF:
2759 + dprintk("%s: SEC_TONE_OFF\n", __func__);
2764 + m88ds3103_writereg(state, 0xa2, data_a2);
2765 + m88ds3103_writereg(state, 0xa1, data_a1);
2769 +static int m88ds3103_send_diseqc_msg(struct dvb_frontend *fe,
2770 + struct dvb_diseqc_master_cmd *d)
2772 + struct m88ds3103_state *state = fe->demodulator_priv;
2776 + /* Dump DiSEqC message */
2778 + printk(KERN_INFO "m88ds3103: %s(", __func__);
2779 + for (i = 0 ; i < d->msg_len ;) {
2780 + printk(KERN_INFO "0x%02x", d->msg[i]);
2781 + if (++i < d->msg_len)
2782 + printk(KERN_INFO ", ");
2786 + tmp = m88ds3103_readreg(state, 0xa2);
2788 + if(state->demod_id == DS3103_ID)
2790 + m88ds3103_writereg(state, 0xa2, tmp);
2792 + for (i = 0; i < d->msg_len; i ++)
2793 + m88ds3103_writereg(state, (0xa3+i), d->msg[i]);
2795 + tmp = m88ds3103_readreg(state, 0xa1);
2798 + tmp |= ((d->msg_len-1) << 3) | 0x07;
2800 + m88ds3103_writereg(state, 0xa1, tmp);
2801 + /* 1.5 * 9 * 8 = 108ms */
2803 + while (time_out > 0){
2806 + tmp = m88ds3103_readreg(state, 0xa1);
2807 + if ((tmp & 0x40) == 0)
2810 + if (time_out == 0){
2811 + tmp = m88ds3103_readreg(state, 0xa1);
2814 + m88ds3103_writereg(state, 0xa1, tmp);
2817 + tmp = m88ds3103_readreg(state, 0xa2);
2820 + m88ds3103_writereg(state, 0xa2, tmp);
2825 +static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
2826 + fe_sec_mini_cmd_t burst)
2828 + struct m88ds3103_state *state = fe->demodulator_priv;
2831 + dprintk("%s()\n", __func__);
2833 + val = m88ds3103_readreg(state, 0xa2);
2835 + if(state->demod_id == DS3103_ID)
2836 + val &= 0xdf; /* Normal mode */
2837 + m88ds3103_writereg(state, 0xa2, val);
2838 + /* DiSEqC burst */
2839 + if (burst == SEC_MINI_B)
2840 + m88ds3103_writereg(state, 0xa1, 0x01);
2842 + m88ds3103_writereg(state, 0xa1, 0x02);
2848 + val = m88ds3103_readreg(state, 0xa1);
2849 + if ((val & 0x40) == 0)
2853 + } while (time_out > 0);
2855 + val = m88ds3103_readreg(state, 0xa2);
2858 + m88ds3103_writereg(state, 0xa2, val);
2863 +static void m88ds3103_release(struct dvb_frontend *fe)
2865 + struct m88ds3103_state *state = fe->demodulator_priv;
2867 + dprintk("%s\n", __func__);
2871 +static int m88ds3103_check_id(struct m88ds3103_state *state)
2873 + int val_00, val_01;
2875 + /*check demod id*/
2876 + val_01 = m88ds3103_readreg(state, 0x01);
2877 + printk(KERN_INFO "DS3000 chip version: %x attached.\n", val_01);
2879 + if(val_01 == 0xD0)
2880 + state->demod_id = DS3103_ID;
2881 + else if(val_01 == 0xC0)
2882 + state->demod_id = DS3000_ID;
2884 + state->demod_id = UNKNOW_ID;
2886 + /*check tuner id*/
2887 + val_00 = m88ds3103_tuner_readreg(state, 0x00);
2888 + printk(KERN_INFO "TS202x chip version[1]: %x attached.\n", val_00);
2892 + m88ds3103_tuner_writereg(state, 0x00, 0x01);
2895 + m88ds3103_tuner_writereg(state, 0x00, 0x03);
2898 + val_00 = m88ds3103_tuner_readreg(state, 0x00);
2899 + printk(KERN_INFO "TS202x chip version[2]: %x attached.\n", val_00);
2901 + if((val_00 == 0x01) || (val_00 == 0x41) || (val_00 == 0x81))
2902 + state->tuner_id = TS2020_ID;
2903 + else if(((val_00 & 0xc0)== 0xc0) || (val_00 == 0x83))
2904 + state->tuner_id = TS2022_ID;
2906 + state->tuner_id = UNKNOW_ID;
2908 + return state->demod_id;
2911 +static struct dvb_frontend_ops m88ds3103_ops;
2912 +static int m88ds3103_initilaze(struct dvb_frontend *fe);
2914 +struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *config,
2915 + struct i2c_adapter *i2c)
2917 + struct m88ds3103_state *state = NULL;
2919 + dprintk("%s\n", __func__);
2921 + /* allocate memory for the internal state */
2922 + state = kzalloc(sizeof(struct m88ds3103_state), GFP_KERNEL);
2923 + if (state == NULL) {
2924 + printk(KERN_ERR "Unable to kmalloc\n");
2928 + state->config = config;
2930 + state->preBer = 0xffff;
2931 + state->delivery_system = SYS_DVBS; /*Default to DVB-S.*/
2933 + /* check demod id */
2934 + if(m88ds3103_check_id(state) == UNKNOW_ID){
2935 + printk(KERN_ERR "Unable to find Montage chip\n");
2939 + memcpy(&state->frontend.ops, &m88ds3103_ops,
2940 + sizeof(struct dvb_frontend_ops));
2941 + state->frontend.demodulator_priv = state;
2943 + m88ds3103_initilaze(&state->frontend);
2945 + return &state->frontend;
2952 +EXPORT_SYMBOL(m88ds3103_attach);
2954 +static int m88ds3103_set_carrier_offset(struct dvb_frontend *fe,
2955 + s32 carrier_offset_khz)
2957 + struct m88ds3103_state *state = fe->demodulator_priv;
2960 + tmp = carrier_offset_khz;
2963 + tmp = (2*tmp + MT_FE_MCLK_KHZ) / (2*MT_FE_MCLK_KHZ);
2968 + m88ds3103_writereg(state, 0x5f, tmp >> 8);
2969 + m88ds3103_writereg(state, 0x5e, tmp & 0xff);
2974 +static int m88ds3103_set_symrate(struct dvb_frontend *fe)
2976 + struct m88ds3103_state *state = fe->demodulator_priv;
2977 + struct dtv_frontend_properties *c = &fe->dtv_property_cache;
2980 + value = (((c->symbol_rate / 1000) << 15) + (MT_FE_MCLK_KHZ / 4)) / (MT_FE_MCLK_KHZ / 2);
2981 + m88ds3103_writereg(state, 0x61, value & 0x00ff);
2982 + m88ds3103_writereg(state, 0x62, (value & 0xff00) >> 8);
2987 +static int m88ds3103_set_CCI(struct dvb_frontend *fe)
2989 + struct m88ds3103_state *state = fe->demodulator_priv;
2992 + tmp = m88ds3103_readreg(state, 0x56);
2994 + m88ds3103_writereg(state, 0x56, tmp);
2996 + tmp = m88ds3103_readreg(state, 0x76);
2998 + m88ds3103_writereg(state, 0x76, tmp);
3003 +static int m88ds3103_init_reg(struct m88ds3103_state *state, const u8 *p_reg_tab, u32 size)
3007 + for(i = 0; i < size; i+=2)
3008 + m88ds3103_writereg(state, p_reg_tab[i], p_reg_tab[i+1]);
3013 +static int m88ds3103_get_locked_sym_rate(struct m88ds3103_state *state, u32 *sym_rate_KSs)
3017 + u8 val_0x6d, val_0x6e;
3019 + val_0x6d = m88ds3103_readreg(state, 0x6d);
3020 + val_0x6e = m88ds3103_readreg(state, 0x6e);
3022 + tmp = (u16)((val_0x6e<<8) | val_0x6d);
3024 + sym_rate_tmp = (u32)(tmp * MT_FE_MCLK_KHZ);
3025 + sym_rate_tmp = (u32)(sym_rate_tmp / (1<<16));
3026 + *sym_rate_KSs = sym_rate_tmp;
3031 +static int m88ds3103_get_channel_info(struct m88ds3103_state *state, u8 *p_mode, u8 *p_coderate)
3035 + if(state->delivery_system == SYS_DVBS2){
3036 + val_0x7E = m88ds3103_readreg(state, 0x7e);
3037 + tmp = (u8)((val_0x7E&0xC0) >> 6);
3039 + tmp = (u8)(val_0x7E & 0x0f);
3040 + *p_coderate = tmp;
3043 + tmp = m88ds3103_readreg(state, 0xe6);
3044 + tmp = (u8)(tmp >> 5);
3045 + *p_coderate = tmp;
3051 +static int m88ds3103_set_clock_ratio(struct m88ds3103_state *state)
3053 + u8 val, mod_fac, tmp1, tmp2;
3054 + u32 input_datarate, locked_sym_rate_KSs;
3055 + u32 MClk_KHz = 96000;
3056 + u8 mod_mode, code_rate, divid_ratio = 0;
3058 + locked_sym_rate_KSs = 0;
3059 + m88ds3103_get_locked_sym_rate(state, &locked_sym_rate_KSs);
3060 + if(locked_sym_rate_KSs == 0)
3063 + m88ds3103_get_channel_info(state, &mod_mode, &code_rate);
3065 + if (state->delivery_system == SYS_DVBS2)
3067 + switch(mod_mode) {
3068 + case 1: mod_fac = 3; break;
3069 + case 2: mod_fac = 4; break;
3070 + case 3: mod_fac = 5; break;
3071 + default: mod_fac = 2; break;
3074 + switch(code_rate) {
3075 + case 0: input_datarate = locked_sym_rate_KSs*mod_fac/8/4; break;
3076 + case 1: input_datarate = locked_sym_rate_KSs*mod_fac/8/3; break;
3077 + case 2: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/5; break;
3078 + case 3: input_datarate = locked_sym_rate_KSs*mod_fac/8/2; break;
3079 + case 4: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/5; break;
3080 + case 5: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3; break;
3081 + case 6: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/4; break;
3082 + case 7: input_datarate = locked_sym_rate_KSs*mod_fac*4/8/5; break;
3083 + case 8: input_datarate = locked_sym_rate_KSs*mod_fac*5/8/6; break;
3084 + case 9: input_datarate = locked_sym_rate_KSs*mod_fac*8/8/9; break;
3085 + case 10: input_datarate = locked_sym_rate_KSs*mod_fac*9/8/10; break;
3086 + default: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3; break;
3089 + if(state->demod_id == DS3000_ID)
3090 + input_datarate = input_datarate * 115 / 100;
3092 + if(input_datarate < 4800) {tmp1 = 15;tmp2 = 15;} //4.8MHz TS clock
3093 + else if(input_datarate < 4966) {tmp1 = 14;tmp2 = 15;} //4.966MHz TS clock
3094 + else if(input_datarate < 5143) {tmp1 = 14;tmp2 = 14;} //5.143MHz TS clock
3095 + else if(input_datarate < 5333) {tmp1 = 13;tmp2 = 14;} //5.333MHz TS clock
3096 + else if(input_datarate < 5538) {tmp1 = 13;tmp2 = 13;} //5.538MHz TS clock
3097 + else if(input_datarate < 5760) {tmp1 = 12;tmp2 = 13;} //5.76MHz TS clock allan 0809
3098 + else if(input_datarate < 6000) {tmp1 = 12;tmp2 = 12;} //6MHz TS clock
3099 + else if(input_datarate < 6260) {tmp1 = 11;tmp2 = 12;} //6.26MHz TS clock
3100 + else if(input_datarate < 6545) {tmp1 = 11;tmp2 = 11;} //6.545MHz TS clock
3101 + else if(input_datarate < 6857) {tmp1 = 10;tmp2 = 11;} //6.857MHz TS clock
3102 + else if(input_datarate < 7200) {tmp1 = 10;tmp2 = 10;} //7.2MHz TS clock
3103 + else if(input_datarate < 7578) {tmp1 = 9;tmp2 = 10;} //7.578MHz TS clock
3104 + else if(input_datarate < 8000) {tmp1 = 9;tmp2 = 9;} //8MHz TS clock
3105 + else if(input_datarate < 8470) {tmp1 = 8;tmp2 = 9;} //8.47MHz TS clock
3106 + else if(input_datarate < 9000) {tmp1 = 8;tmp2 = 8;} //9MHz TS clock
3107 + else if(input_datarate < 9600) {tmp1 = 7;tmp2 = 8;} //9.6MHz TS clock
3108 + else if(input_datarate < 10285) {tmp1 = 7;tmp2 = 7;} //10.285MHz TS clock
3109 + else if(input_datarate < 12000) {tmp1 = 6;tmp2 = 6;} //12MHz TS clock
3110 + else if(input_datarate < 14400) {tmp1 = 5;tmp2 = 5;} //14.4MHz TS clock
3111 + else if(input_datarate < 18000) {tmp1 = 4;tmp2 = 4;} //18MHz TS clock
3112 + else {tmp1 = 3;tmp2 = 3;} //24MHz TS clock
3114 + if(state->demod_id == DS3000_ID) {
3115 + val = (u8)((tmp1<<4) + tmp2);
3116 + m88ds3103_writereg(state, 0xfe, val);
3118 + tmp1 = m88ds3103_readreg(state, 0x22);
3119 + tmp2 = m88ds3103_readreg(state, 0x24);
3126 + if((tmp1 == 0x00) && (tmp2 == 0x01))
3127 + MClk_KHz = 144000;
3128 + else if((tmp1 == 0x00) && (tmp2 == 0x03))
3130 + else if((tmp1 == 0x01) && (tmp2 == 0x01))
3131 + MClk_KHz = 115200;
3132 + else if((tmp1 == 0x02) && (tmp2 == 0x01))
3134 + else if((tmp1 == 0x03) && (tmp2 == 0x00))
3135 + MClk_KHz = 192000;
3139 + if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/
3140 + input_datarate = 5200;
3142 + if(input_datarate != 0)
3143 + divid_ratio = (u8)(MClk_KHz / input_datarate);
3145 + divid_ratio = 0xFF;
3147 + if(divid_ratio > 128)
3148 + divid_ratio = 128;
3150 + if(divid_ratio < 2)
3153 + tmp1 = (u8)(divid_ratio / 2);
3154 + tmp2 = (u8)(divid_ratio / 2);
3156 + if((divid_ratio % 2) != 0)
3165 + val = m88ds3103_readreg(state, 0xfe);
3167 + val |= (tmp2 >> 2) & 0x0f;
3168 + m88ds3103_writereg(state, 0xfe, val);
3170 + val = (u8)((tmp2 & 0x03) << 6);
3172 + m88ds3103_writereg(state, 0xea, val);
3177 + switch(code_rate) {
3178 + case 4: input_datarate = locked_sym_rate_KSs*mod_fac/2/8; break;
3179 + case 3: input_datarate = locked_sym_rate_KSs*mod_fac*2/3/8; break;
3180 + case 2: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8; break;
3181 + case 1: input_datarate = locked_sym_rate_KSs*mod_fac*5/6/8; break;
3182 + case 0: input_datarate = locked_sym_rate_KSs*mod_fac*7/8/8; break;
3183 + default: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8; break;
3186 + if(state->demod_id == DS3000_ID)
3187 + input_datarate = input_datarate * 115 / 100;
3189 + if(input_datarate < 6857) {tmp1 = 7;tmp2 = 7;} //6.857MHz TS clock
3190 + else if(input_datarate < 7384) {tmp1 = 6;tmp2 = 7;} //7.384MHz TS clock
3191 + else if(input_datarate < 8000) {tmp1 = 6;tmp2 = 6;} //8MHz TS clock
3192 + else if(input_datarate < 8727) {tmp1 = 5;tmp2 = 6;} //8.727MHz TS clock
3193 + else if(input_datarate < 9600) {tmp1 = 5;tmp2 = 5;} //9.6MHz TS clock
3194 + else if(input_datarate < 10666) {tmp1 = 4;tmp2 = 5;} //10.666MHz TS clock
3195 + else if(input_datarate < 12000) {tmp1 = 4;tmp2 = 4;} //12MHz TS clock
3196 + else if(input_datarate < 13714) {tmp1 = 3;tmp2 = 4;} //13.714MHz TS clock
3197 + else if(input_datarate < 16000) {tmp1 = 3;tmp2 = 3;} //16MHz TS clock
3198 + else if(input_datarate < 19200) {tmp1 = 2;tmp2 = 3;} //19.2MHz TS clock
3199 + else {tmp1 = 2;tmp2 = 2;} //24MHz TS clock
3201 + if(state->demod_id == DS3000_ID) {
3202 + val = m88ds3103_readreg(state, 0xfe);
3204 + val |= ((u8)((tmp1<<3) + tmp2));
3205 + m88ds3103_writereg(state, 0xfe, val);
3207 + if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/
3208 + input_datarate = 5200;
3210 + if(input_datarate != 0)
3211 + divid_ratio = (u8)(MClk_KHz / input_datarate);
3213 + divid_ratio = 0xFF;
3215 + if(divid_ratio > 128)
3216 + divid_ratio = 128;
3218 + if(divid_ratio < 2)
3221 + tmp1 = (u8)(divid_ratio / 2);
3222 + tmp2 = (u8)(divid_ratio / 2);
3224 + if((divid_ratio % 2) != 0)
3233 + val = m88ds3103_readreg(state, 0xfe);
3235 + val |= (tmp2 >> 2) & 0x0f;
3236 + m88ds3103_writereg(state, 0xfe, val);
3238 + val = (u8)((tmp2 & 0x03) << 6);
3240 + m88ds3103_writereg(state, 0xea, val);
3246 +static int m88ds3103_demod_connect(struct dvb_frontend *fe, s32 carrier_offset_khz)
3248 + struct m88ds3103_state *state = fe->demodulator_priv;
3249 + struct dtv_frontend_properties *c = &fe->dtv_property_cache;
3251 + u8 val1,val2,data;
3253 + dprintk("connect delivery system = %d\n", state->delivery_system);
3255 + /* ds3000 global reset */
3256 + m88ds3103_writereg(state, 0x07, 0x80);
3257 + m88ds3103_writereg(state, 0x07, 0x00);
3258 + /* ds3000 build-in uC reset */
3259 + m88ds3103_writereg(state, 0xb2, 0x01);
3260 + /* ds3000 software reset */
3261 + m88ds3103_writereg(state, 0x00, 0x01);
3263 + switch (state->delivery_system) {
3265 + /* initialise the demod in DVB-S mode */
3266 + if(state->demod_id == DS3000_ID){
3267 + m88ds3103_init_reg(state, ds3000_dvbs_init_tab, sizeof(ds3000_dvbs_init_tab));
3269 + value = m88ds3103_readreg(state, 0xfe);
3272 + m88ds3103_writereg(state, 0xfe, value);
3274 + if(state->config->ci_mode)
3276 + else if(state->config->ts_mode)
3280 + m88ds3103_writereg(state, 0xfd, val1);
3282 + }else if(state->demod_id == DS3103_ID){
3283 + m88ds3103_init_reg(state, ds3103_dvbs_init_tab, sizeof(ds3103_dvbs_init_tab));
3285 + /* set ts clock */
3286 + if(state->config->ci_mode == 2){
3287 + val1 = 6; val2 = 6;
3288 + }else if(state->config->ts_mode == 0) {
3289 + val1 = 3; val2 = 3;
3291 + val1 = 0; val2 = 0;
3293 + val1 -= 1; val2 -= 1;
3294 + val1 &= 0x3f; val2 &= 0x3f;
3295 + data = m88ds3103_readreg(state, 0xfe);
3297 + data |= (val2 >> 2) & 0x0f;
3298 + m88ds3103_writereg(state, 0xfe, data);
3299 + data = (val2 & 0x03) << 6;
3301 + m88ds3103_writereg(state, 0xea, data);
3303 + m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
3304 + m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
3306 + /* set master clock */
3307 + val1 = m88ds3103_readreg(state, 0x22);
3308 + val2 = m88ds3103_readreg(state, 0x24);
3315 + m88ds3103_writereg(state, 0x22, val1);
3316 + m88ds3103_writereg(state, 0x24, val2);
3318 + if(state->config->ci_mode)
3320 + else if(state->config->ts_mode)
3324 + m88ds3103_writereg(state, 0xfd, val1);
3328 + /* initialise the demod in DVB-S2 mode */
3329 + if(state->demod_id == DS3000_ID){
3330 + m88ds3103_init_reg(state, ds3000_dvbs2_init_tab, sizeof(ds3000_dvbs2_init_tab));
3332 + if (c->symbol_rate >= 30000000)
3333 + m88ds3103_writereg(state, 0xfe, 0x54);
3335 + m88ds3103_writereg(state, 0xfe, 0x98);
3337 + }else if(state->demod_id == DS3103_ID){
3338 + m88ds3103_init_reg(state, ds3103_dvbs2_init_tab, sizeof(ds3103_dvbs2_init_tab));
3340 + /* set ts clock */
3341 + if(state->config->ci_mode == 2){
3342 + val1 = 6; val2 = 6;
3343 + }else if(state->config->ts_mode == 0){
3344 + val1 = 5; val2 = 4;
3346 + val1 = 0; val2 = 0;
3348 + val1 -= 1; val2 -= 1;
3349 + val1 &= 0x3f; val2 &= 0x3f;
3350 + data = m88ds3103_readreg(state, 0xfe);
3352 + data |= (val2 >> 2) & 0x0f;
3353 + m88ds3103_writereg(state, 0xfe, data);
3354 + data = (val2 & 0x03) << 6;
3356 + m88ds3103_writereg(state, 0xea, data);
3358 + m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
3359 + m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
3361 + /* set master clock */
3362 + val1 = m88ds3103_readreg(state, 0x22);
3363 + val2 = m88ds3103_readreg(state, 0x24);
3367 + if((state->config->ci_mode == 2) || (state->config->ts_mode == 1)){
3371 + if (c->symbol_rate >= 28000000){
3373 + }else if (c->symbol_rate >= 18000000){
3380 + m88ds3103_writereg(state, 0x22, val1);
3381 + m88ds3103_writereg(state, 0x24, val2);
3384 + if(state->config->ci_mode)
3386 + else if(state->config->ts_mode)
3390 + m88ds3103_writereg(state, 0xfd, val1);
3396 + /* disable 27MHz clock output */
3397 + m88ds3103_writereg(state, 0x29, 0x80);
3398 + /* enable ac coupling */
3399 + m88ds3103_writereg(state, 0x25, 0x8a);
3401 + if ((c->symbol_rate / 1000) <= 3000){
3402 + m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 32 * 100 / 64 = 400*/
3403 + m88ds3103_writereg(state, 0xc8, 0x20);
3404 + m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/
3405 + m88ds3103_writereg(state, 0xc7, 0x00);
3406 + }else if((c->symbol_rate / 1000) <= 10000){
3407 + m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 16 * 100 / 64 = 200*/
3408 + m88ds3103_writereg(state, 0xc8, 0x10);
3409 + m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/
3410 + m88ds3103_writereg(state, 0xc7, 0x00);
3412 + m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 6 * 100 / 64 = 75*/
3413 + m88ds3103_writereg(state, 0xc8, 0x06);
3414 + m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/
3415 + m88ds3103_writereg(state, 0xc7, 0x00);
3418 + m88ds3103_set_symrate(fe);
3420 + m88ds3103_set_CCI(fe);
3422 + m88ds3103_set_carrier_offset(fe, carrier_offset_khz);
3424 + /* ds3000 out of software reset */
3425 + m88ds3103_writereg(state, 0x00, 0x00);
3426 + /* start ds3000 build-in uC */
3427 + m88ds3103_writereg(state, 0xb2, 0x00);
3432 +static int m88ds3103_set_frontend(struct dvb_frontend *fe)
3434 + struct m88ds3103_state *state = fe->demodulator_priv;
3435 + struct dtv_frontend_properties *c = &fe->dtv_property_cache;
3438 + fe_status_t status;
3439 + u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf, div4, capCode, changePLL;
3440 + s32 offset_khz, lpf_offset_KHz;
3441 + u16 value, ndiv, lpf_coeff;
3442 + u32 f3db, gdiv28, realFreq;
3445 + dprintk("%s() ", __func__);
3446 + dprintk("c frequency = %d\n", c->frequency);
3447 + dprintk("symbol rate = %d\n", c->symbol_rate);
3448 + dprintk("delivery system = %d\n", c->delivery_system);
3450 + realFreq = c->frequency;
3451 + lpf_offset_KHz = 0;
3452 + if(c->symbol_rate < 5000000){
3453 + lpf_offset_KHz = FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz;
3454 + realFreq += FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz;
3457 + if (state->config->set_ts_params)
3458 + state->config->set_ts_params(fe, 0);
3462 + if(state->tuner_id == TS2022_ID){
3463 + m88ds3103_tuner_writereg(state, 0x10, 0x0a);
3464 + m88ds3103_tuner_writereg(state, 0x11, 0x40);
3465 + if (realFreq < 1103000) {
3466 + m88ds3103_tuner_writereg(state, 0x10, 0x1b);
3468 + ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ;
3470 + ndiv = (realFreq * (6 + 8) * 2)/MT_FE_CRYSTAL_KHZ;
3472 + ndiv = ndiv + ndiv%2;
3474 + ndiv = ndiv - 1024;
3475 + else if (ndiv < 6143)
3476 + ndiv = ndiv + 1024;
3478 + ndiv = ndiv + 3072;
3480 + m88ds3103_tuner_writereg(state, 0x01, (ndiv & 0x3f00) >> 8);
3482 + m88ds3103_tuner_writereg(state, 0x10, 0x00);
3483 + if (realFreq < 1146000){
3484 + m88ds3103_tuner_writereg(state, 0x10, 0x11);
3486 + ndiv = (realFreq * (6 + 8) * 4) / MT_FE_CRYSTAL_KHZ;
3488 + m88ds3103_tuner_writereg(state, 0x10, 0x01);
3489 + ndiv = (realFreq * (6 + 8) * 2) / MT_FE_CRYSTAL_KHZ;
3491 + ndiv = ndiv + ndiv%2;
3492 + ndiv = ndiv - 1024;
3493 + m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8)&0x0f);
3496 + m88ds3103_tuner_writereg(state, 0x02, ndiv & 0x00ff);
3497 + m88ds3103_tuner_writereg(state, 0x03, 0x06);
3498 + m88ds3103_tuner_writereg(state, 0x51, 0x0f);
3499 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3500 + m88ds3103_tuner_writereg(state, 0x50, 0x10);
3501 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3503 + if(state->tuner_id == TS2022_ID){
3504 + if(( realFreq >= 1650000 ) && (realFreq <= 1850000)){
3506 + value = m88ds3103_tuner_readreg(state, 0x14);
3509 + m88ds3103_tuner_writereg(state, 0x10, 0x82);
3510 + m88ds3103_tuner_writereg(state, 0x11, 0x6f);
3512 + m88ds3103_tuner_writereg(state, 0x51, 0x0f);
3513 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3514 + m88ds3103_tuner_writereg(state, 0x50, 0x10);
3515 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3519 + value = m88ds3103_tuner_readreg(state, 0x14);
3523 + value = m88ds3103_tuner_readreg(state, 0x10);
3525 + m88ds3103_tuner_writereg(state, 0x10, value);
3529 + value = m88ds3103_tuner_readreg(state, 0x66);
3530 + changePLL = (((value & 0x80) >> 7) != div4);
3533 + m88ds3103_tuner_writereg(state, 0x10, 0x11);
3535 + ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ;
3536 + ndiv = ndiv + ndiv%2;
3537 + ndiv = ndiv - 1024;
3539 + m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8) & 0x0f);
3540 + m88ds3103_tuner_writereg(state, 0x02, ndiv & 0xff);
3542 + m88ds3103_tuner_writereg(state, 0x51, 0x0f);
3543 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3544 + m88ds3103_tuner_writereg(state, 0x50, 0x10);
3545 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3548 + /*set the RF gain*/
3549 + if(state->tuner_id == TS2020_ID)
3550 + m88ds3103_tuner_writereg(state, 0x60, 0x79);
3552 + m88ds3103_tuner_writereg(state, 0x51, 0x17);
3553 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3554 + m88ds3103_tuner_writereg(state, 0x50, 0x08);
3555 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3558 + if(state->tuner_id == TS2020_ID){
3559 + RFgain = m88ds3103_tuner_readreg(state, 0x3d);
3565 + RFgain = RFgain -3;
3566 + value = ((RFgain << 3) | 0x01) & 0x79;
3567 + m88ds3103_tuner_writereg(state, 0x60, value);
3568 + m88ds3103_tuner_writereg(state, 0x51, 0x17);
3569 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3570 + m88ds3103_tuner_writereg(state, 0x50, 0x08);
3571 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3576 + if(state->tuner_id == TS2022_ID){
3577 + m88ds3103_tuner_writereg(state, 0x25, 0x00);
3578 + m88ds3103_tuner_writereg(state, 0x27, 0x70);
3579 + m88ds3103_tuner_writereg(state, 0x41, 0x09);
3580 + m88ds3103_tuner_writereg(state, 0x08, 0x0b);
3583 + f3db = ((c->symbol_rate / 1000) *135) / 200 + 2000;
3584 + f3db += lpf_offset_KHz;
3590 + gdiv28 = (MT_FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000;
3591 + m88ds3103_tuner_writereg(state, 0x04, gdiv28 & 0xff);
3592 + m88ds3103_tuner_writereg(state, 0x51, 0x1b);
3593 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3594 + m88ds3103_tuner_writereg(state, 0x50, 0x04);
3595 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3598 + value = m88ds3103_tuner_readreg(state, 0x26);
3599 + capCode = value & 0x3f;
3600 + if(state->tuner_id == TS2022_ID){
3601 + m88ds3103_tuner_writereg(state, 0x41, 0x0d);
3603 + m88ds3103_tuner_writereg(state, 0x51, 0x1b);
3604 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3605 + m88ds3103_tuner_writereg(state, 0x50, 0x04);
3606 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3610 + value = m88ds3103_tuner_readreg(state, 0x26);
3612 + value = (capCode + value) / 2;
3617 + gdiv28 = gdiv28 * 207 / (value * 2 + 151);
3618 + mlpf_max = gdiv28 * 135 / 100;
3619 + mlpf_min = gdiv28 * 78 / 100;
3620 + if (mlpf_max > 63)
3623 + if(state->tuner_id == TS2022_ID)
3628 + nlpf = (f3db * gdiv28 * 2 / lpf_coeff / (MT_FE_CRYSTAL_KHZ / 1000) + 1) / 2 ;
3629 + if (nlpf > 23) nlpf = 23;
3630 + if (nlpf < 1) nlpf = 1;
3632 + lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2;
3634 + if (lpf_mxdiv < mlpf_min){
3636 + lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2;
3639 + if (lpf_mxdiv > mlpf_max)
3640 + lpf_mxdiv = mlpf_max;
3642 + m88ds3103_tuner_writereg(state, 0x04, lpf_mxdiv);
3643 + m88ds3103_tuner_writereg(state, 0x06, nlpf);
3644 + m88ds3103_tuner_writereg(state, 0x51, 0x1b);
3645 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3646 + m88ds3103_tuner_writereg(state, 0x50, 0x04);
3647 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3650 + if(state->tuner_id == TS2022_ID){
3652 + value = m88ds3103_tuner_readreg(state, 0x26);
3653 + capCode = value & 0x3f;
3655 + m88ds3103_tuner_writereg(state, 0x41, 0x09);
3657 + m88ds3103_tuner_writereg(state, 0x51, 0x1b);
3658 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3659 + m88ds3103_tuner_writereg(state, 0x50, 0x04);
3660 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3663 + value = m88ds3103_tuner_readreg(state, 0x26);
3665 + value = (capCode + value) / 2;
3667 + value = value | 0x80;
3668 + m88ds3103_tuner_writereg(state, 0x25, value);
3669 + m88ds3103_tuner_writereg(state, 0x27, 0x30);
3671 + m88ds3103_tuner_writereg(state, 0x08, 0x09);
3674 + /* Set the BB gain */
3675 + m88ds3103_tuner_writereg(state, 0x51, 0x1e);
3676 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3677 + m88ds3103_tuner_writereg(state, 0x50, 0x01);
3678 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3679 + if(state->tuner_id == TS2020_ID){
3682 + value = m88ds3103_tuner_readreg(state, 0x21);
3685 + m88ds3103_tuner_writereg(state, 0x60, 0x61);
3686 + m88ds3103_tuner_writereg(state, 0x51, 0x17);
3687 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
3688 + m88ds3103_tuner_writereg(state, 0x50, 0x08);
3689 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
3695 + offset_khz = (ndiv - ndiv % 2 + 1024) * MT_FE_CRYSTAL_KHZ
3696 + / (6 + 8) / (div4 + 1) / 2 - realFreq;
3698 + m88ds3103_demod_connect(fe, offset_khz+lpf_offset_KHz);
3700 + for (i = 0; i < 30 ; i++) {
3701 + m88ds3103_read_status(fe, &status);
3702 + if (status & FE_HAS_LOCK){
3708 + if((status & FE_HAS_LOCK) == 0){
3709 + state->delivery_system = (state->delivery_system == SYS_DVBS) ? SYS_DVBS2 : SYS_DVBS;
3710 + m88ds3103_demod_connect(fe, offset_khz);
3712 + for (i = 0; i < 30 ; i++) {
3713 + m88ds3103_read_status(fe, &status);
3714 + if (status & FE_HAS_LOCK){
3721 + if (status & FE_HAS_LOCK){
3722 + if(state->config->ci_mode == 2)
3723 + m88ds3103_set_clock_ratio(state);
3724 + if(state->config->start_ctrl){
3725 + if(state->first_lock == 0){
3726 + state->config->start_ctrl(fe);
3727 + state->first_lock = 1;
3735 +static int m88ds3103_tune(struct dvb_frontend *fe,
3737 + unsigned int mode_flags,
3738 + unsigned int *delay,
3739 + fe_status_t *status)
3743 + dprintk("%s() ", __func__);
3744 + dprintk("re_tune = %d\n", re_tune);
3747 + int ret = m88ds3103_set_frontend(fe);
3752 + return m88ds3103_read_status(fe, status);
3755 +static enum dvbfe_algo m88ds3103_get_algo(struct dvb_frontend *fe)
3757 + return DVBFE_ALGO_HW;
3761 + * Power config will reset and load initial firmware if required
3763 +static int m88ds3103_initilaze(struct dvb_frontend *fe)
3765 + struct m88ds3103_state *state = fe->demodulator_priv;
3768 + dprintk("%s()\n", __func__);
3770 + m88ds3103_writereg(state, 0x07, 0x80);
3771 + m88ds3103_writereg(state, 0x07, 0x00);
3774 + m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08));
3777 + if(state->tuner_id == TS2020_ID){
3779 + m88ds3103_tuner_writereg(state, 0x42, 0x73);
3781 + m88ds3103_tuner_writereg(state, 0x05, 0x01);
3782 + m88ds3103_tuner_writereg(state, 0x62, 0xb5);
3783 + m88ds3103_tuner_writereg(state, 0x07, 0x02);
3784 + m88ds3103_tuner_writereg(state, 0x08, 0x01);
3786 + else if(state->tuner_id == TS2022_ID){
3788 + m88ds3103_tuner_writereg(state, 0x62, 0x6c);
3790 + m88ds3103_tuner_writereg(state, 0x42, 0x6c);
3792 + m88ds3103_tuner_writereg(state, 0x7d, 0x9d);
3793 + m88ds3103_tuner_writereg(state, 0x7c, 0x9a);
3794 + m88ds3103_tuner_writereg(state, 0x7a, 0x76);
3796 + m88ds3103_tuner_writereg(state, 0x3b, 0x01);
3797 + m88ds3103_tuner_writereg(state, 0x63, 0x88);
3799 + m88ds3103_tuner_writereg(state, 0x61, 0x85);
3800 + m88ds3103_tuner_writereg(state, 0x22, 0x30);
3801 + m88ds3103_tuner_writereg(state, 0x30, 0x40);
3802 + m88ds3103_tuner_writereg(state, 0x20, 0x23);
3803 + m88ds3103_tuner_writereg(state, 0x24, 0x02);
3804 + m88ds3103_tuner_writereg(state, 0x12, 0xa0);
3807 + if(state->demod_id == DS3103_ID){
3808 + m88ds3103_writereg(state, 0x07, 0xe0);
3809 + m88ds3103_writereg(state, 0x07, 0x00);
3812 + m88ds3103_writereg(state, 0xb2, 0x01);
3814 + /* Load the firmware if required */
3815 + ret = m88ds3103_load_firmware(fe);
3817 + printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
3820 + if(state->demod_id == DS3103_ID){
3821 + m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
3822 + m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
3829 + * Initialise or wake up device
3831 +static int m88ds3103_initfe(struct dvb_frontend *fe)
3833 + struct m88ds3103_state *state = fe->demodulator_priv;
3836 + dprintk("%s()\n", __func__);
3838 + /* 1st step to wake up demod */
3839 + m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08));
3840 + m88ds3103_writereg(state, 0x04, 0xfe & m88ds3103_readreg(state, 0x04));
3841 + m88ds3103_writereg(state, 0x23, 0xef & m88ds3103_readreg(state, 0x23));
3843 + /* 2nd step to wake up tuner */
3844 + val = m88ds3103_tuner_readreg(state, 0x00) & 0xff;
3845 + if((val & 0x01) == 0){
3846 + m88ds3103_tuner_writereg(state, 0x00, 0x01);
3849 + m88ds3103_tuner_writereg(state, 0x00, 0x03);
3855 +/* Put device to sleep */
3856 +static int m88ds3103_sleep(struct dvb_frontend *fe)
3858 + struct m88ds3103_state *state = fe->demodulator_priv;
3860 + dprintk("%s()\n", __func__);
3862 + /* 1st step to sleep tuner */
3863 + m88ds3103_tuner_writereg(state, 0x00, 0x00);
3865 + /* 2nd step to sleep demod */
3866 + m88ds3103_writereg(state, 0x08, 0xfe & m88ds3103_readreg(state, 0x08));
3867 + m88ds3103_writereg(state, 0x04, 0x01 | m88ds3103_readreg(state, 0x04));
3868 + m88ds3103_writereg(state, 0x23, 0x10 | m88ds3103_readreg(state, 0x23));
3874 +static struct dvb_frontend_ops m88ds3103_ops = {
3875 + .delsys = { SYS_DVBS, SYS_DVBS2},
3877 + .name = "Montage DS3103/TS2022",
3879 + .frequency_min = 950000,
3880 + .frequency_max = 2150000,
3881 + .frequency_stepsize = 1011, /* kHz for QPSK frontends */
3882 + .frequency_tolerance = 5000,
3883 + .symbol_rate_min = 1000000,
3884 + .symbol_rate_max = 45000000,
3885 + .caps = FE_CAN_INVERSION_AUTO |
3886 + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
3887 + FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
3888 + FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
3889 + FE_CAN_2G_MODULATION |
3890 + FE_CAN_QPSK | FE_CAN_RECOVER
3893 + .release = m88ds3103_release,
3895 + .init = m88ds3103_initfe,
3896 + .sleep = m88ds3103_sleep,
3897 + .read_status = m88ds3103_read_status,
3898 + .read_ber = m88ds3103_read_ber,
3899 + .read_signal_strength = m88ds3103_read_signal_strength,
3900 + .read_snr = m88ds3103_read_snr,
3901 + .read_ucblocks = m88ds3103_read_ucblocks,
3902 + .set_tone = m88ds3103_set_tone,
3903 + .set_voltage = m88ds3103_set_voltage,
3904 + .diseqc_send_master_cmd = m88ds3103_send_diseqc_msg,
3905 + .diseqc_send_burst = m88ds3103_diseqc_send_burst,
3906 + .get_frontend_algo = m88ds3103_get_algo,
3907 + .tune = m88ds3103_tune,
3908 + .set_frontend = m88ds3103_set_frontend,
3911 +MODULE_DESCRIPTION("DVB Frontend module for Montage DS3103/TS2022 hardware");
3912 +MODULE_AUTHOR("Max nibble");
3913 +MODULE_LICENSE("GPL");
3914 diff -urN a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h
3915 --- a/drivers/media/dvb-frontends/m88ds3103.h 1970-01-01 08:00:00.000000000 +0800
3916 +++ b/drivers/media/dvb-frontends/m88ds3103.h 2013-01-30 12:33:51.000000000 +0800
3919 + Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
3921 + This program is free software; you can redistribute it and/or modify
3922 + it under the terms of the GNU General Public License as published by
3923 + the Free Software Foundation; either version 2 of the License, or
3924 + (at your option) any later version.
3926 + This program is distributed in the hope that it will be useful,
3927 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3928 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3929 + GNU General Public License for more details.
3931 + You should have received a copy of the GNU General Public License
3932 + along with this program; if not, write to the Free Software
3933 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3936 +#ifndef M88DS3103_H
3937 +#define M88DS3103_H
3939 +#include <linux/dvb/frontend.h>
3941 +struct m88ds3103_config {
3942 + /* the demodulator's i2c address */
3946 + u8 ts_mode; /* 0: Parallel, 1: Serial */
3948 + /* Set device param to start dma */
3949 + int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
3950 + /* Start to transfer data */
3951 + int (*start_ctrl)(struct dvb_frontend *fe);
3952 + /* Set LNB voltage */
3953 + int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
3956 +#if defined(CONFIG_DVB_M88DS3103) || \
3957 + (defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE))
3958 +extern struct dvb_frontend *m88ds3103_attach(
3959 + const struct m88ds3103_config *config,
3960 + struct i2c_adapter *i2c);
3962 +static inline struct dvb_frontend *m88ds3103_attach(
3963 + const struct m88ds3103_config *config,
3964 + struct i2c_adapter *i2c)
3966 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
3969 +#endif /* CONFIG_DVB_M88DS3103 */
3970 +#endif /* M88DS3103_H */
3971 diff -urN a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h
3972 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h 1970-01-01 08:00:00.000000000 +0800
3973 +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h 2013-01-30 12:33:56.000000000 +0800
3976 + Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
3978 + This program is free software; you can redistribute it and/or modify
3979 + it under the terms of the GNU General Public License as published by
3980 + the Free Software Foundation; either version 2 of the License, or
3981 + (at your option) any later version.
3983 + This program is distributed in the hope that it will be useful,
3984 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3985 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3986 + GNU General Public License for more details.
3988 + You should have received a copy of the GNU General Public License
3989 + along with this program; if not, write to the Free Software
3990 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3993 +#ifndef M88DS3103_PRIV_H
3994 +#define M88DS3103_PRIV_H
3996 +#define FW_DOWN_SIZE 32
3997 +#define FW_DOWN_LOOP (8192/FW_DOWN_SIZE)
3998 +#define DS3103_DEFAULT_FIRMWARE "dvb-fe-ds3103.fw"
3999 +#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds300x.fw"
4000 +#define MT_FE_MCLK_KHZ 96000 /* in kHz */
4001 +#define MT_FE_CRYSTAL_KHZ 27000 /* in kHz */
4002 +#define FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz 3000
4003 +#define DS3000_ID 0x3000
4004 +#define DS3103_ID 0x3103
4005 +#define TS2020_ID 0x2020
4006 +#define TS2022_ID 0x2022
4007 +#define UNKNOW_ID 0x0000
4009 +struct m88ds3103_state {
4010 + struct i2c_adapter *i2c;
4011 + const struct m88ds3103_config *config;
4013 + struct dvb_frontend frontend;
4017 + u8 first_lock; /* The first time of signal lock */
4018 + u16 demod_id; /* demod chip type */
4019 + u16 tuner_id; /* tuner chip type */
4020 + fe_delivery_system_t delivery_system;
4023 +/* For M88DS3103 demod dvbs mode.*/
4024 +static u8 ds3103_dvbs_init_tab[] = {
4106 +/* For M88DS3103 demod dvbs2 mode.*/
4107 +static u8 ds3103_dvbs2_init_tab[] = {
4193 +/* For M88DS3000 demod dvbs mode.*/
4194 +static u8 ds3000_dvbs_init_tab[] = {
4277 +/* For M88DS3000 demod dvbs2 mode.*/
4278 +static u8 ds3000_dvbs2_init_tab[] = {
4377 +#endif /* M88DS3103_PRIV_H */
4378 diff -urN a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
4379 --- a/drivers/media/dvb-frontends/Makefile 2013-04-29 08:36:01.000000000 +0800
4380 +++ b/drivers/media/dvb-frontends/Makefile 2013-05-03 17:04:31.000000000 +0800
4382 obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
4383 obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
4384 obj-$(CONFIG_DVB_AF9033) += af9033.o
4386 +obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o
4387 +obj-$(CONFIG_DVB_M88DC2800) += m88dc2800.o
4388 diff -urN a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c
4389 --- a/drivers/media/pci/cx23885/cimax2.c 2013-04-29 08:36:01.000000000 +0800
4390 +++ b/drivers/media/pci/cx23885/cimax2.c 2013-03-31 22:03:29.000000000 +0800
4392 return state->status;
4395 -int netup_ci_init(struct cx23885_tsport *port)
4396 +int netup_ci_init(struct cx23885_tsport *port, bool isDVBSky)
4398 struct netup_ci_state *state;
4399 u8 cimax_init[34] = {
4400 @@ -464,6 +464,11 @@
4405 + cimax_init[32] = 0x22;
4406 + cimax_init[33] = 0x00;
4409 port->port_priv = state;
4412 @@ -537,3 +542,19 @@
4413 dvb_ca_en50221_release(&state->ca);
4417 +/* CI irq handler for DVBSky board*/
4418 +int dvbsky_ci_slot_status(struct cx23885_dev *dev)
4420 + struct cx23885_tsport *port = NULL;
4421 + struct netup_ci_state *state = NULL;
4423 + ci_dbg_print("%s:\n", __func__);
4426 + state = port->port_priv;
4427 + schedule_work(&state->work);
4428 + ci_dbg_print("%s: Wakeup CI0\n", __func__);
4432 diff -urN a/drivers/media/pci/cx23885/cimax2.h b/drivers/media/pci/cx23885/cimax2.h
4433 --- a/drivers/media/pci/cx23885/cimax2.h 2013-04-29 08:36:01.000000000 +0800
4434 +++ b/drivers/media/pci/cx23885/cimax2.h 2013-01-30 12:34:37.000000000 +0800
4436 extern int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status);
4437 extern int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
4438 int slot, int open);
4439 -extern int netup_ci_init(struct cx23885_tsport *port);
4440 +extern int netup_ci_init(struct cx23885_tsport *port, bool isDVBSky);
4441 extern void netup_ci_exit(struct cx23885_tsport *port);
4443 +extern int dvbsky_ci_slot_status(struct cx23885_dev *dev);
4446 diff -urN a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
4447 --- a/drivers/media/pci/cx23885/cx23885-cards.c 2013-04-29 08:36:01.000000000 +0800
4448 +++ b/drivers/media/pci/cx23885/cx23885-cards.c 2013-05-03 17:34:46.000000000 +0800
4449 @@ -569,6 +569,34 @@
4450 .name = "TeVii S471",
4451 .portb = CX23885_MPEG_DVB,
4453 + [CX23885_BOARD_BST_PS8512] = {
4454 + .name = "Bestunar PS8512",
4455 + .portb = CX23885_MPEG_DVB,
4457 + [CX23885_BOARD_DVBSKY_S950] = {
4458 + .name = "DVBSKY S950",
4459 + .portb = CX23885_MPEG_DVB,
4461 + [CX23885_BOARD_DVBSKY_S952] = {
4462 + .name = "DVBSKY S952",
4463 + .portb = CX23885_MPEG_DVB,
4464 + .portc = CX23885_MPEG_DVB,
4466 + [CX23885_BOARD_DVBSKY_S950_CI] = {
4468 + .name = "DVBSKY S950CI DVB-S2 CI",
4469 + .portb = CX23885_MPEG_DVB,
4471 + [CX23885_BOARD_DVBSKY_C2800E_CI] = {
4473 + .name = "DVBSKY C2800E DVB-C CI",
4474 + .portb = CX23885_MPEG_DVB,
4476 + [CX23885_BOARD_DVBSKY_T9580] = {
4477 + .name = "DVBSKY T9580",
4478 + .portb = CX23885_MPEG_DVB,
4479 + .portc = CX23885_MPEG_DVB,
4481 [CX23885_BOARD_PROF_8000] = {
4482 .name = "Prof Revolution DVB-S2 8000",
4483 .portb = CX23885_MPEG_DVB,
4486 .amux = CX25840_AUDIO6,
4491 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
4493 @@ -818,6 +846,30 @@
4494 .subdevice = 0x9022,
4495 .card = CX23885_BOARD_TEVII_S471,
4497 + .subvendor = 0x14f1,
4498 + .subdevice = 0x8512,
4499 + .card = CX23885_BOARD_BST_PS8512,
4501 + .subvendor = 0x4254,
4502 + .subdevice = 0x0950,
4503 + .card = CX23885_BOARD_DVBSKY_S950,
4505 + .subvendor = 0x4254,
4506 + .subdevice = 0x0952,
4507 + .card = CX23885_BOARD_DVBSKY_S952,
4509 + .subvendor = 0x4254,
4510 + .subdevice = 0x950C,
4511 + .card = CX23885_BOARD_DVBSKY_S950_CI,
4513 + .subvendor = 0x4254,
4514 + .subdevice = 0x2800,
4515 + .card = CX23885_BOARD_DVBSKY_C2800E_CI,
4517 + .subvendor = 0x4254,
4518 + .subdevice = 0x9580,
4519 + .card = CX23885_BOARD_DVBSKY_T9580,
4521 .subvendor = 0x8000,
4522 .subdevice = 0x3034,
4523 .card = CX23885_BOARD_PROF_8000,
4524 @@ -1224,7 +1276,7 @@
4525 cx_set(GP0_IO, 0x00040004);
4527 case CX23885_BOARD_TBS_6920:
4528 - case CX23885_BOARD_PROF_8000:
4529 + case CX23885_BOARD_PROF_8000:
4530 cx_write(MC417_CTL, 0x00000036);
4531 cx_write(MC417_OEN, 0x00001000);
4532 cx_set(MC417_RWD, 0x00000002);
4533 @@ -1394,9 +1446,84 @@
4534 cx_set(GP0_IO, 0x00040004);
4537 + case CX23885_BOARD_DVBSKY_S950:
4538 + case CX23885_BOARD_BST_PS8512:
4539 + cx23885_gpio_enable(dev, GPIO_2, 1);
4540 + cx23885_gpio_clear(dev, GPIO_2);
4542 + cx23885_gpio_set(dev, GPIO_2);
4544 + case CX23885_BOARD_DVBSKY_S952:
4545 + case CX23885_BOARD_DVBSKY_T9580:
4546 + cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */
4548 + cx23885_gpio_enable(dev, GPIO_2, 1);
4549 + cx23885_gpio_enable(dev, GPIO_11, 1);
4551 + cx23885_gpio_clear(dev, GPIO_2);
4552 + cx23885_gpio_clear(dev, GPIO_11);
4554 + cx23885_gpio_set(dev, GPIO_2);
4555 + cx23885_gpio_set(dev, GPIO_11);
4557 + case CX23885_BOARD_DVBSKY_S950_CI:
4558 + case CX23885_BOARD_DVBSKY_C2800E_CI:
4559 + /* GPIO-0 INTA from CiMax, input
4560 + GPIO-1 reset CiMax, output, high active
4561 + GPIO-2 reset demod, output, low active
4562 + GPIO-3 to GPIO-10 data/addr for CAM
4563 + GPIO-11 ~CS0 to CiMax1
4564 + GPIO-12 ~CS1 to CiMax2
4565 + GPIO-13 ADL0 load LSB addr
4566 + GPIO-14 ADL1 load MSB addr
4567 + GPIO-15 ~RDY from CiMax
4568 + GPIO-17 ~RD to CiMax
4569 + GPIO-18 ~WR to CiMax
4571 + cx_set(GP0_IO, 0x00060002); /* GPIO 1/2 as output */
4572 + cx_clear(GP0_IO, 0x00010004); /*GPIO 0 as input*/
4573 + mdelay(100);/* reset delay */
4574 + cx_set(GP0_IO, 0x00060004); /* GPIO as out, reset high */
4575 + cx_clear(GP0_IO, 0x00010002);
4576 + cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */
4577 + /* GPIO-15 IN as ~ACK, rest as OUT */
4578 + cx_write(MC417_OEN, 0x00001000);
4579 + /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */
4580 + cx_write(MC417_RWD, 0x0000c300);
4582 + cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
4587 +static int cx23885_ir_patch(struct i2c_adapter *i2c, u8 reg, u8 mask)
4589 + struct i2c_msg msgs[2];
4590 + u8 tx_buf[2], rx_buf[1];
4591 + /* Write register address */
4593 + msgs[0].addr = 0x4c;
4594 + msgs[0].flags = 0;
4596 + msgs[0].buf = (char *) tx_buf;
4597 + /* Read data from register */
4598 + msgs[1].addr = 0x4c;
4599 + msgs[1].flags = I2C_M_RD;
4601 + msgs[1].buf = (char *) rx_buf;
4603 + i2c_transfer(i2c, msgs, 2);
4606 + tx_buf[1] = rx_buf[0] | mask;
4607 + msgs[0].addr = 0x4c;
4608 + msgs[0].flags = 0;
4610 + msgs[0].buf = (char *) tx_buf;
4612 + return i2c_transfer(i2c, msgs, 1);
4615 int cx23885_ir_init(struct cx23885_dev *dev)
4617 static struct v4l2_subdev_io_pin_config ir_rxtx_pin_cfg[] = {
4618 @@ -1482,6 +1609,23 @@
4619 v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config,
4620 ir_rx_pin_cfg_count, ir_rx_pin_cfg);
4622 + case CX23885_BOARD_BST_PS8512:
4623 + case CX23885_BOARD_DVBSKY_S950:
4624 + case CX23885_BOARD_DVBSKY_S952:
4625 + case CX23885_BOARD_DVBSKY_S950_CI:
4626 + case CX23885_BOARD_DVBSKY_C2800E_CI:
4627 + case CX23885_BOARD_DVBSKY_T9580:
4628 + dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE);
4629 + if (dev->sd_ir == NULL) {
4633 + v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config,
4634 + ir_rx_pin_cfg_count, ir_rx_pin_cfg);
4636 + cx23885_ir_patch(&(dev->i2c_bus[2].i2c_adap),0x1f,0x80);
4637 + cx23885_ir_patch(&(dev->i2c_bus[2].i2c_adap),0x23,0x80);
4639 case CX23885_BOARD_HAUPPAUGE_HVR1250:
4642 @@ -1511,9 +1655,15 @@
4643 cx23888_ir_remove(dev);
4646 + case CX23885_BOARD_BST_PS8512:
4647 + case CX23885_BOARD_DVBSKY_S950:
4648 + case CX23885_BOARD_DVBSKY_S952:
4649 + case CX23885_BOARD_DVBSKY_S950_CI:
4650 + case CX23885_BOARD_DVBSKY_C2800E_CI:
4651 + case CX23885_BOARD_DVBSKY_T9580:
4652 case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
4653 case CX23885_BOARD_TEVII_S470:
4654 - case CX23885_BOARD_HAUPPAUGE_HVR1250:
4655 + case CX23885_BOARD_HAUPPAUGE_HVR1250:
4656 case CX23885_BOARD_MYGICA_X8507:
4657 cx23885_irq_remove(dev, PCI_MSK_AV_CORE);
4658 /* sd_ir is a duplicate pointer to the AV Core, just clear it */
4659 @@ -1556,6 +1706,12 @@
4661 cx23885_irq_add_enable(dev, PCI_MSK_IR);
4663 + case CX23885_BOARD_BST_PS8512:
4664 + case CX23885_BOARD_DVBSKY_S950:
4665 + case CX23885_BOARD_DVBSKY_S952:
4666 + case CX23885_BOARD_DVBSKY_S950_CI:
4667 + case CX23885_BOARD_DVBSKY_C2800E_CI:
4668 + case CX23885_BOARD_DVBSKY_T9580:
4669 case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
4670 case CX23885_BOARD_TEVII_S470:
4671 case CX23885_BOARD_HAUPPAUGE_HVR1250:
4672 @@ -1657,6 +1813,10 @@
4673 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
4674 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
4676 + case CX23885_BOARD_BST_PS8512:
4677 + case CX23885_BOARD_DVBSKY_S950:
4678 + case CX23885_BOARD_DVBSKY_S950_CI:
4679 + case CX23885_BOARD_DVBSKY_C2800E_CI:
4680 case CX23885_BOARD_TEVII_S470:
4681 case CX23885_BOARD_TEVII_S471:
4682 case CX23885_BOARD_DVBWORLD_2005:
4683 @@ -1694,6 +1854,22 @@
4684 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
4685 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
4687 + case CX23885_BOARD_DVBSKY_S952:
4688 + ts1->gen_ctrl_val = 0x5; /* Parallel */
4689 + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
4690 + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
4691 + ts2->gen_ctrl_val = 0xe; /* Serial bus + punctured clock */
4692 + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
4693 + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
4695 + case CX23885_BOARD_DVBSKY_T9580:
4696 + ts1->gen_ctrl_val = 0x5; /* Parallel */
4697 + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
4698 + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
4699 + ts2->gen_ctrl_val = 0x8; /* Serial bus */
4700 + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
4701 + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
4703 case CX23885_BOARD_HAUPPAUGE_HVR1250:
4704 case CX23885_BOARD_HAUPPAUGE_HVR1500:
4705 case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
4706 @@ -1749,6 +1925,12 @@
4707 case CX23885_BOARD_MPX885:
4708 case CX23885_BOARD_MYGICA_X8507:
4709 case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
4710 + case CX23885_BOARD_BST_PS8512:
4711 + case CX23885_BOARD_DVBSKY_S950:
4712 + case CX23885_BOARD_DVBSKY_S952:
4713 + case CX23885_BOARD_DVBSKY_S950_CI:
4714 + case CX23885_BOARD_DVBSKY_C2800E_CI:
4715 + case CX23885_BOARD_DVBSKY_T9580:
4716 case CX23885_BOARD_AVERMEDIA_HC81R:
4717 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
4718 &dev->i2c_bus[2].i2c_adap,
4719 diff -urN a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
4720 --- a/drivers/media/pci/cx23885/cx23885-core.c 2013-04-29 08:36:01.000000000 +0800
4721 +++ b/drivers/media/pci/cx23885/cx23885-core.c 2013-05-03 17:36:31.000000000 +0800
4722 @@ -1909,6 +1909,10 @@
4723 (pci_status & PCI_MSK_GPIO0))
4724 handled += altera_ci_irq(dev);
4726 + if (cx23885_boards[dev->board].ci_type == 3 &&
4727 + (pci_status & PCI_MSK_GPIO0))
4728 + handled += dvbsky_ci_slot_status(dev);
4731 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
4732 handled += cx23885_irq_ts(ts1, ts1_status);
4733 @@ -2144,6 +2148,8 @@
4734 cx23885_irq_add_enable(dev, PCI_MSK_GPIO1 | PCI_MSK_GPIO0);
4736 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
4737 + case CX23885_BOARD_DVBSKY_S950_CI:
4738 + case CX23885_BOARD_DVBSKY_C2800E_CI:
4739 cx23885_irq_add_enable(dev, PCI_MSK_GPIO0);
4742 diff -urN a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
4743 --- a/drivers/media/pci/cx23885/cx23885-dvb.c 2013-04-29 08:36:01.000000000 +0800
4744 +++ b/drivers/media/pci/cx23885/cx23885-dvb.c 2013-05-03 17:38:34.000000000 +0800
4746 #include "stv6110.h"
4748 #include "cx24116.h"
4749 +#include "m88ds3103.h"
4750 +#include "m88dc2800.h"
4752 #include "lgs8gxx.h"
4753 #include "netup-eeprom.h"
4755 #include "stv0367.h"
4758 -#include "stv090x.h"
4759 -#include "stb6100.h"
4760 +#include "stv090x.h"
4761 +#include "stb6100.h"
4762 #include "stb6100_cfg.h"
4763 #include "tda10071.h"
4765 @@ -500,42 +502,130 @@
4769 -static struct stv090x_config prof_8000_stv090x_config = {
4770 - .device = STV0903,
4771 - .demod_mode = STV090x_SINGLE,
4772 - .clk_mode = STV090x_CLK_EXT,
4775 - .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED,
4776 - .repeater_level = STV090x_RPTLEVEL_64,
4777 - .adc1_range = STV090x_ADC_2Vpp,
4778 - .diseqc_envelope_mode = false,
4780 - .tuner_get_frequency = stb6100_get_frequency,
4781 - .tuner_set_frequency = stb6100_set_frequency,
4782 - .tuner_set_bandwidth = stb6100_set_bandwidth,
4783 - .tuner_get_bandwidth = stb6100_get_bandwidth,
4786 -static struct stb6100_config prof_8000_stb6100_config = {
4787 - .tuner_address = 0x60,
4788 - .refclock = 27000000,
4791 -static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
4793 +int bst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
4795 struct cx23885_tsport *port = fe->dvb->priv;
4796 struct cx23885_dev *dev = port->dev;
4798 + cx23885_gpio_enable(dev, GPIO_1, 1);
4799 + cx23885_gpio_enable(dev, GPIO_0, 1);
4801 + switch (voltage) {
4802 + case SEC_VOLTAGE_13:
4803 + cx23885_gpio_set(dev, GPIO_1);
4804 + cx23885_gpio_clear(dev, GPIO_0);
4806 + case SEC_VOLTAGE_18:
4807 + cx23885_gpio_set(dev, GPIO_1);
4808 + cx23885_gpio_set(dev, GPIO_0);
4810 + case SEC_VOLTAGE_OFF:
4811 + cx23885_gpio_clear(dev, GPIO_1);
4812 + cx23885_gpio_clear(dev, GPIO_0);
4818 - if (voltage == SEC_VOLTAGE_18)
4819 - cx_write(MC417_RWD, 0x00001e00);
4820 - else if (voltage == SEC_VOLTAGE_13)
4821 - cx_write(MC417_RWD, 0x00001a00);
4823 - cx_write(MC417_RWD, 0x00001800);
4824 +int dvbsky_set_voltage_sec(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
4826 + struct cx23885_tsport *port = fe->dvb->priv;
4827 + struct cx23885_dev *dev = port->dev;
4829 + cx23885_gpio_enable(dev, GPIO_12, 1);
4830 + cx23885_gpio_enable(dev, GPIO_13, 1);
4832 + switch (voltage) {
4833 + case SEC_VOLTAGE_13:
4834 + cx23885_gpio_set(dev, GPIO_13);
4835 + cx23885_gpio_clear(dev, GPIO_12);
4837 + case SEC_VOLTAGE_18:
4838 + cx23885_gpio_set(dev, GPIO_13);
4839 + cx23885_gpio_set(dev, GPIO_12);
4841 + case SEC_VOLTAGE_OFF:
4842 + cx23885_gpio_clear(dev, GPIO_13);
4843 + cx23885_gpio_clear(dev, GPIO_12);
4849 +/* bestunar single dvb-s2 */
4850 +static struct m88ds3103_config bst_ds3103_config = {
4851 + .demod_address = 0x68,
4855 + .set_voltage = bst_set_voltage,
4857 +/* DVBSKY dual dvb-s2 */
4858 +static struct m88ds3103_config dvbsky_ds3103_config_pri = {
4859 + .demod_address = 0x68,
4863 + .set_voltage = bst_set_voltage,
4865 +static struct m88ds3103_config dvbsky_ds3103_config_sec = {
4866 + .demod_address = 0x68,
4870 + .set_voltage = dvbsky_set_voltage_sec,
4873 +static struct m88ds3103_config dvbsky_ds3103_ci_config = {
4874 + .demod_address = 0x68,
4880 +static struct m88dc2800_config dvbsky_dc2800_config = {
4881 + .demod_address = 0x1c,
4885 +static struct stv090x_config prof_8000_stv090x_config = {
4886 + .device = STV0903,
4887 + .demod_mode = STV090x_SINGLE,
4888 + .clk_mode = STV090x_CLK_EXT,
4891 + .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED,
4892 + .repeater_level = STV090x_RPTLEVEL_64,
4893 + .adc1_range = STV090x_ADC_2Vpp,
4894 + .diseqc_envelope_mode = false,
4896 + .tuner_get_frequency = stb6100_get_frequency,
4897 + .tuner_set_frequency = stb6100_set_frequency,
4898 + .tuner_set_bandwidth = stb6100_set_bandwidth,
4899 + .tuner_get_bandwidth = stb6100_get_bandwidth,
4902 +static struct stb6100_config prof_8000_stb6100_config = {
4903 + .tuner_address = 0x60,
4904 + .refclock = 27000000,
4907 +static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
4909 + struct cx23885_tsport *port = fe->dvb->priv;
4910 + struct cx23885_dev *dev = port->dev;
4912 + if (voltage == SEC_VOLTAGE_18)
4913 + cx_write(MC417_RWD, 0x00001e00);
4914 + else if (voltage == SEC_VOLTAGE_13)
4915 + cx_write(MC417_RWD, 0x00001a00);
4917 + cx_write(MC417_RWD, 0x00001800);
4921 static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
4923 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
4924 @@ -1250,23 +1340,79 @@
4925 &tevii_ds3000_config,
4926 &i2c_bus->i2c_adap);
4928 - case CX23885_BOARD_PROF_8000:
4929 - i2c_bus = &dev->i2c_bus[0];
4930 + case CX23885_BOARD_BST_PS8512:
4931 + case CX23885_BOARD_DVBSKY_S950:
4932 + i2c_bus = &dev->i2c_bus[1];
4933 + fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
4934 + &bst_ds3103_config,
4935 + &i2c_bus->i2c_adap);
4938 + case CX23885_BOARD_DVBSKY_S952:
4939 + switch (port->nr) {
4942 + i2c_bus = &dev->i2c_bus[1];
4943 + fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
4944 + &dvbsky_ds3103_config_pri,
4945 + &i2c_bus->i2c_adap);
4949 + i2c_bus = &dev->i2c_bus[0];
4950 + fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
4951 + &dvbsky_ds3103_config_sec,
4952 + &i2c_bus->i2c_adap);
4957 - fe0->dvb.frontend = dvb_attach(stv090x_attach,
4958 - &prof_8000_stv090x_config,
4959 - &i2c_bus->i2c_adap,
4960 - STV090x_DEMODULATOR_0);
4961 - if (fe0->dvb.frontend != NULL) {
4962 - if (!dvb_attach(stb6100_attach,
4963 - fe0->dvb.frontend,
4964 - &prof_8000_stb6100_config,
4965 - &i2c_bus->i2c_adap))
4966 - goto frontend_detach;
4967 + case CX23885_BOARD_DVBSKY_S950_CI:
4968 + i2c_bus = &dev->i2c_bus[1];
4969 + fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
4970 + &dvbsky_ds3103_ci_config,
4971 + &i2c_bus->i2c_adap);
4974 + case CX23885_BOARD_DVBSKY_C2800E_CI:
4975 + i2c_bus = &dev->i2c_bus[1];
4976 + fe0->dvb.frontend = dvb_attach(m88dc2800_attach,
4977 + &dvbsky_dc2800_config,
4978 + &i2c_bus->i2c_adap);
4981 - fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage;
4982 + case CX23885_BOARD_DVBSKY_T9580:
4983 + switch (port->nr) {
4986 + i2c_bus = &dev->i2c_bus[1];
4987 + fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
4988 + &dvbsky_ds3103_config_pri,
4989 + &i2c_bus->i2c_adap);
4997 + case CX23885_BOARD_PROF_8000:
4998 + i2c_bus = &dev->i2c_bus[0];
5000 + fe0->dvb.frontend = dvb_attach(stv090x_attach,
5001 + &prof_8000_stv090x_config,
5002 + &i2c_bus->i2c_adap,
5003 + STV090x_DEMODULATOR_0);
5004 + if (fe0->dvb.frontend != NULL) {
5005 + if (!dvb_attach(stb6100_attach,
5006 + fe0->dvb.frontend,
5007 + &prof_8000_stb6100_config,
5008 + &i2c_bus->i2c_adap))
5009 + goto frontend_detach;
5011 + fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage;
5014 case CX23885_BOARD_HAUPPAUGE_HVR4400:
5015 i2c_bus = &dev->i2c_bus[0];
5016 fe0->dvb.frontend = dvb_attach(tda10071_attach,
5017 @@ -1325,7 +1471,7 @@
5018 printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n",
5019 port->nr, port->frontends.adapter.proposed_mac);
5021 - netup_ci_init(port);
5022 + netup_ci_init(port, false);
5025 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
5026 @@ -1352,6 +1498,41 @@
5027 memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6);
5030 + case CX23885_BOARD_BST_PS8512:
5031 + case CX23885_BOARD_DVBSKY_S950:
5032 + case CX23885_BOARD_DVBSKY_S952:
5033 + case CX23885_BOARD_DVBSKY_T9580:{
5034 + u8 eeprom[256]; /* 24C02 i2c eeprom */
5039 + dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
5040 + tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom));
5041 + printk(KERN_INFO "DVBSKY PCIe MAC= %pM\n", eeprom + 0xc0+(port->nr-1)*8);
5042 + memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0 +
5043 + (port->nr-1)*8, 6);
5046 + case CX23885_BOARD_DVBSKY_S950_CI: {
5047 + u8 eeprom[256]; /* 24C02 i2c eeprom */
5052 + dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
5053 + tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom));
5054 + printk(KERN_INFO "DVBSKY PCIe MAC= %pM\n", eeprom + 0xc0+(port->nr-1)*8);
5055 + memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0 +
5056 + (port->nr-1)*8, 6);
5058 + netup_ci_init(port, true);
5061 + case CX23885_BOARD_DVBSKY_C2800E_CI: {
5062 + netup_ci_init(port, true);
5068 @@ -1434,6 +1615,8 @@
5070 switch (port->dev->board) {
5071 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
5072 + case CX23885_BOARD_DVBSKY_S950_CI:
5073 + case CX23885_BOARD_DVBSKY_C2800E_CI:
5074 netup_ci_exit(port);
5076 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
5077 diff -urN a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
5078 --- a/drivers/media/pci/cx23885/cx23885.h 2013-04-29 08:36:01.000000000 +0800
5079 +++ b/drivers/media/pci/cx23885/cx23885.h 2013-05-03 17:14:20.000000000 +0800
5081 #define CX23885_BOARD_HAUPPAUGE_HVR4400 38
5082 #define CX23885_BOARD_AVERMEDIA_HC81R 39
5084 +#define CX23885_BOARD_BASE_INDEX 40
5085 +#define CX23885_BOARD_BST_PS8512 (CX23885_BOARD_BASE_INDEX)
5086 +#define CX23885_BOARD_DVBSKY_S952 (CX23885_BOARD_BASE_INDEX+1)
5087 +#define CX23885_BOARD_DVBSKY_S950 (CX23885_BOARD_BASE_INDEX+2)
5088 +#define CX23885_BOARD_DVBSKY_S950_CI (CX23885_BOARD_BASE_INDEX+3)
5089 +#define CX23885_BOARD_DVBSKY_C2800E_CI (CX23885_BOARD_BASE_INDEX+4)
5090 +#define CX23885_BOARD_DVBSKY_T9580 (CX23885_BOARD_BASE_INDEX+5)
5092 #define GPIO_0 0x00000001
5093 #define GPIO_1 0x00000002
5094 #define GPIO_2 0x00000004
5098 struct cx23885_input input[MAX_CX23885_INPUT];
5099 - int ci_type; /* for NetUP */
5100 + int ci_type; /* 1 and 2 for NetUP, 3 for DVBSky. */
5101 /* Force bottom field first during DMA (888 workaround) */
5104 diff -urN a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
5105 --- a/drivers/media/pci/cx23885/cx23885-input.c 2013-04-29 08:36:01.000000000 +0800
5106 +++ b/drivers/media/pci/cx23885/cx23885-input.c 2013-05-03 17:42:09.000000000 +0800
5108 case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
5109 case CX23885_BOARD_TEVII_S470:
5110 case CX23885_BOARD_HAUPPAUGE_HVR1250:
5111 + case CX23885_BOARD_BST_PS8512:
5112 + case CX23885_BOARD_DVBSKY_S950:
5113 + case CX23885_BOARD_DVBSKY_S952:
5114 + case CX23885_BOARD_DVBSKY_S950_CI:
5115 + case CX23885_BOARD_DVBSKY_C2800E_CI:
5116 + case CX23885_BOARD_DVBSKY_T9580:
5117 case CX23885_BOARD_MYGICA_X8507:
5119 * The only boards we handle right now. However other boards
5120 @@ -141,6 +147,12 @@
5121 case CX23885_BOARD_HAUPPAUGE_HVR1850:
5122 case CX23885_BOARD_HAUPPAUGE_HVR1290:
5123 case CX23885_BOARD_HAUPPAUGE_HVR1250:
5124 + case CX23885_BOARD_BST_PS8512:
5125 + case CX23885_BOARD_DVBSKY_S950:
5126 + case CX23885_BOARD_DVBSKY_S952:
5127 + case CX23885_BOARD_DVBSKY_S950_CI:
5128 + case CX23885_BOARD_DVBSKY_C2800E_CI:
5129 + case CX23885_BOARD_DVBSKY_T9580:
5130 case CX23885_BOARD_MYGICA_X8507:
5132 * The IR controller on this board only returns pulse widths.
5133 @@ -291,6 +303,18 @@
5134 /* A guess at the remote */
5135 rc_map = RC_MAP_TEVII_NEC;
5137 + case CX23885_BOARD_BST_PS8512:
5138 + case CX23885_BOARD_DVBSKY_S950:
5139 + case CX23885_BOARD_DVBSKY_S952:
5140 + case CX23885_BOARD_DVBSKY_S950_CI:
5141 + case CX23885_BOARD_DVBSKY_C2800E_CI:
5142 + case CX23885_BOARD_DVBSKY_T9580:
5143 + /* Integrated CX2388[58] IR controller */
5144 + driver_type = RC_DRIVER_IR_RAW;
5145 + allowed_protos = RC_BIT_ALL;
5146 + /* A guess at the remote */
5147 + rc_map = RC_MAP_DVBSKY;
5149 case CX23885_BOARD_MYGICA_X8507:
5150 /* Integrated CX23885 IR controller */
5151 driver_type = RC_DRIVER_IR_RAW;
5152 diff -urN a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig
5153 --- a/drivers/media/pci/cx23885/Kconfig 2013-04-29 08:36:01.000000000 +0800
5154 +++ b/drivers/media/pci/cx23885/Kconfig 2013-05-03 17:43:05.000000000 +0800
5156 select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT
5157 select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT
5158 select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
5159 + select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
5160 + select DVB_M88DC2800 if MEDIA_SUBDRV_AUTOSELECT
5161 select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT
5162 select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT
5163 select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT
5164 diff -urN a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c
5165 --- a/drivers/media/pci/cx88/cx88-cards.c 2013-04-29 08:36:01.000000000 +0800
5166 +++ b/drivers/media/pci/cx88/cx88-cards.c 2013-05-03 17:06:55.000000000 +0800
5167 @@ -2309,6 +2309,18 @@
5169 .mpeg = CX88_MPEG_DVB,
5171 + [CX88_BOARD_BST_PS8312] = {
5172 + .name = "Bestunar PS8312 DVB-S/S2",
5173 + .tuner_type = UNSET,
5174 + .radio_type = UNSET,
5175 + .tuner_addr = ADDR_UNSET,
5176 + .radio_addr = ADDR_UNSET,
5178 + .type = CX88_VMUX_DVB,
5181 + .mpeg = CX88_MPEG_DVB,
5185 /* ------------------------------------------------------------------ */
5186 @@ -2813,6 +2825,10 @@
5187 .subvendor = 0x1822,
5188 .subdevice = 0x0023,
5189 .card = CX88_BOARD_TWINHAN_VP1027_DVBS,
5191 + .subvendor = 0x14f1,
5192 + .subdevice = 0x8312,
5193 + .card = CX88_BOARD_BST_PS8312,
5197 @@ -3547,6 +3563,12 @@
5198 cx_write(MO_SRST_IO, 1);
5201 + case CX88_BOARD_BST_PS8312:
5202 + cx_write(MO_GP1_IO, 0x808000);
5204 + cx_write(MO_GP1_IO, 0x808080);
5210 diff -urN a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c
5211 --- a/drivers/media/pci/cx88/cx88-dvb.c 2013-04-29 08:36:01.000000000 +0800
5212 +++ b/drivers/media/pci/cx88/cx88-dvb.c 2013-05-03 17:09:09.000000000 +0800
5214 #include "stv0288.h"
5215 #include "stb6000.h"
5216 #include "cx24116.h"
5217 +#include "m88ds3103.h"
5218 #include "stv0900.h"
5219 #include "stb6100.h"
5220 #include "stb6100_proc.h"
5221 @@ -459,6 +460,56 @@
5222 return core->prev_set_voltage(fe, voltage);
5225 +/*CX88_BOARD_BST_PS8312*/
5226 +static int bst_dvbs_set_voltage(struct dvb_frontend *fe,
5227 + fe_sec_voltage_t voltage)
5229 + struct cx8802_dev *dev= fe->dvb->priv;
5230 + struct cx88_core *core = dev->core;
5232 + cx_write(MO_GP1_IO, 0x111111);
5233 + switch (voltage) {
5234 + case SEC_VOLTAGE_13:
5235 + cx_write(MO_GP1_IO, 0x020200);
5237 + case SEC_VOLTAGE_18:
5238 + cx_write(MO_GP1_IO, 0x020202);
5240 + case SEC_VOLTAGE_OFF:
5241 + cx_write(MO_GP1_IO, 0x111100);
5245 + if (core->prev_set_voltage)
5246 + return core->prev_set_voltage(fe, voltage);
5250 +static int bst_dvbs_set_voltage_v2(struct dvb_frontend *fe,
5251 + fe_sec_voltage_t voltage)
5253 + struct cx8802_dev *dev= fe->dvb->priv;
5254 + struct cx88_core *core = dev->core;
5256 + cx_write(MO_GP1_IO, 0x111101);
5257 + switch (voltage) {
5258 + case SEC_VOLTAGE_13:
5259 + cx_write(MO_GP1_IO, 0x020200);
5261 + case SEC_VOLTAGE_18:
5263 + cx_write(MO_GP1_IO, 0x020202);
5265 + case SEC_VOLTAGE_OFF:
5267 + cx_write(MO_GP1_IO, 0x111110);
5271 + if (core->prev_set_voltage)
5272 + return core->prev_set_voltage(fe, voltage);
5276 static int vp1027_set_voltage(struct dvb_frontend *fe,
5277 fe_sec_voltage_t voltage)
5278 @@ -706,6 +757,11 @@
5282 +static struct m88ds3103_config dvbsky_ds3103_config = {
5283 + .demod_address = 0x68,
5284 + .set_ts_params = ds3000_set_ts_param,
5287 static const struct stv0900_config prof_7301_stv0900_config = {
5288 .demod_address = 0x6a,
5289 /* demod_mode = 0,*/
5290 @@ -1477,6 +1533,35 @@
5291 &tevii_ts2020_config, &core->i2c_adap);
5292 fe0->dvb.frontend->ops.set_voltage =
5293 tevii_dvbs_set_voltage;
5296 + case CX88_BOARD_BST_PS8312:
5297 + fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
5298 + &dvbsky_ds3103_config,
5300 + if (fe0->dvb.frontend != NULL){
5302 + u8 b0[] = { 0x60 };
5304 + struct i2c_msg msg[] = {
5312 + .flags = I2C_M_RD,
5317 + ret = i2c_transfer(&core->i2c_adap, msg, 2);
5318 + printk("PS8312: config = %02x, %02x", b1[0],b1[1]);
5320 + fe0->dvb.frontend->ops.set_voltage = bst_dvbs_set_voltage_v2;
5322 + fe0->dvb.frontend->ops.set_voltage = bst_dvbs_set_voltage;
5325 case CX88_BOARD_OMICOM_SS4_PCI:
5326 diff -urN a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
5327 --- a/drivers/media/pci/cx88/cx88.h 2013-04-29 08:36:01.000000000 +0800
5328 +++ b/drivers/media/pci/cx88/cx88.h 2013-05-03 17:05:57.000000000 +0800
5330 #define CX88_BOARD_WINFAST_DTV1800H_XC4000 88
5331 #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36 89
5332 #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43 90
5333 +#define CX88_BOARD_BST_PS8312 91
5336 CX88_VMUX_COMPOSITE1 = 1,
5337 diff -urN a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c
5338 --- a/drivers/media/pci/cx88/cx88-input.c 2013-04-29 08:36:01.000000000 +0800
5339 +++ b/drivers/media/pci/cx88/cx88-input.c 2013-01-26 14:52:03.000000000 +0800
5340 @@ -419,6 +419,10 @@
5341 rc_type = RC_BIT_NEC;
5342 ir->sampling = 0xff00; /* address */
5344 + case CX88_BOARD_BST_PS8312:
5345 + ir_codes = RC_MAP_DVBSKY;
5346 + ir->sampling = 0xff00; /* address */
5351 diff -urN a/drivers/media/pci/cx88/Kconfig b/drivers/media/pci/cx88/Kconfig
5352 --- a/drivers/media/pci/cx88/Kconfig 2013-04-29 08:36:01.000000000 +0800
5353 +++ b/drivers/media/pci/cx88/Kconfig 2013-05-03 17:10:41.000000000 +0800
5355 select DVB_ISL6421 if MEDIA_SUBDRV_AUTOSELECT
5356 select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
5357 select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
5358 + select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
5359 select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
5360 select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
5361 select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT
5362 diff -urN a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
5363 --- a/drivers/media/rc/keymaps/Makefile 2013-04-29 08:36:01.000000000 +0800
5364 +++ b/drivers/media/rc/keymaps/Makefile 2013-05-03 17:43:41.000000000 +0800
5367 rc-dntv-live-dvb-t.o \
5368 rc-dntv-live-dvbt-pro.o \
5371 rc-encore-enltv2.o \
5373 diff -urN a/drivers/media/rc/keymaps/rc-dvbsky.c b/drivers/media/rc/keymaps/rc-dvbsky.c
5374 --- a/drivers/media/rc/keymaps/rc-dvbsky.c 1970-01-01 08:00:00.000000000 +0800
5375 +++ b/drivers/media/rc/keymaps/rc-dvbsky.c 2013-01-26 14:52:49.000000000 +0800
5377 +/* rc-dvbsky.c - Keytable for Dvbsky Remote Controllers
5379 + * keymap imported from ir-keymaps.c
5382 + * Copyright (c) 2010-2012 by Nibble Max <nibble.max@gmail.com>
5384 + * This program is free software; you can redistribute it and/or modify
5385 + * it under the terms of the GNU General Public License as published by
5386 + * the Free Software Foundation; either version 2 of the License, or
5387 + * (at your option) any later version.
5390 +#include <media/rc-map.h>
5391 +#include <linux/module.h>
5393 + * This table contains the complete RC5 code, instead of just the data part
5396 +static struct rc_map_table rc5_dvbsky[] = {
5397 + { 0x0000, KEY_0 },
5398 + { 0x0001, KEY_1 },
5399 + { 0x0002, KEY_2 },
5400 + { 0x0003, KEY_3 },
5401 + { 0x0004, KEY_4 },
5402 + { 0x0005, KEY_5 },
5403 + { 0x0006, KEY_6 },
5404 + { 0x0007, KEY_7 },
5405 + { 0x0008, KEY_8 },
5406 + { 0x0009, KEY_9 },
5407 + { 0x000a, KEY_MUTE },
5408 + { 0x000d, KEY_OK },
5409 + { 0x000b, KEY_STOP },
5410 + { 0x000c, KEY_EXIT },
5411 + { 0x000e, KEY_CAMERA }, /*Snap shot*/
5412 + { 0x000f, KEY_SUBTITLE }, /*PIP*/
5413 + { 0x0010, KEY_VOLUMEUP },
5414 + { 0x0011, KEY_VOLUMEDOWN },
5415 + { 0x0012, KEY_FAVORITES },
5416 + { 0x0013, KEY_LIST }, /*Info*/
5417 + { 0x0016, KEY_PAUSE },
5418 + { 0x0017, KEY_PLAY },
5419 + { 0x001f, KEY_RECORD },
5420 + { 0x0020, KEY_CHANNELDOWN },
5421 + { 0x0021, KEY_CHANNELUP },
5422 + { 0x0025, KEY_POWER2 },
5423 + { 0x0026, KEY_REWIND },
5424 + { 0x0027, KEY_FASTFORWARD },
5425 + { 0x0029, KEY_LAST },
5426 + { 0x002b, KEY_MENU },
5427 + { 0x002c, KEY_EPG },
5428 + { 0x002d, KEY_ZOOM },
5431 +static struct rc_map_list rc5_dvbsky_map = {
5433 + .scan = rc5_dvbsky,
5434 + .size = ARRAY_SIZE(rc5_dvbsky),
5435 + .rc_type = RC_TYPE_RC5,
5436 + .name = RC_MAP_DVBSKY,
5440 +static int __init init_rc_map_rc5_dvbsky(void)
5442 + return rc_map_register(&rc5_dvbsky_map);
5445 +static void __exit exit_rc_map_rc5_dvbsky(void)
5447 + rc_map_unregister(&rc5_dvbsky_map);
5450 +module_init(init_rc_map_rc5_dvbsky)
5451 +module_exit(exit_rc_map_rc5_dvbsky)
5453 +MODULE_LICENSE("GPL");
5454 +MODULE_AUTHOR("Nibble Max <nibble.max@gmail.com>");
5455 diff -urN a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
5456 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c 1970-01-01 08:00:00.000000000 +0800
5457 +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c 2013-05-03 17:47:38.000000000 +0800
5460 + * Driver for DVBSky USB2.0 receiver
5462 + * Copyright (C) 2013 Max nibble <nibble.max@gmail.com>
5464 + * CIMax code is copied and modified from:
5465 + * CIMax2(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
5466 + * Copyright (C) 2009 NetUP Inc.
5467 + * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
5468 + * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
5470 + * This program is free software; you can redistribute it and/or modify
5471 + * it under the terms of the GNU General Public License as published by
5472 + * the Free Software Foundation; either version 2 of the License, or
5473 + * (at your option) any later version.
5475 + * This program is distributed in the hope that it will be useful,
5476 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5477 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5478 + * GNU General Public License for more details.
5480 + * You should have received a copy of the GNU General Public License
5481 + * along with this program; if not, write to the Free Software
5482 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
5485 +#include "dvb_ca_en50221.h"
5486 +#include "dvb_usb.h"
5487 +#include "m88ds3103.h"
5489 +static int dvbsky_debug;
5490 +module_param(dvbsky_debug, int, 0644);
5491 +MODULE_PARM_DESC(dvbsky_debug, "Activates dvbsky usb debugging (default:0)");
5493 +#define DVBSKY_CI_CTL 0x04
5494 +#define DVBSKY_CI_RD 1
5496 +#define dprintk(args...) \
5498 + if (dvbsky_debug) \
5499 + printk(KERN_INFO "dvbsky_usb: " args); \
5502 +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
5504 +struct dvbsky_state {
5505 + struct mutex stream_mutex;
5508 + struct dvb_ca_en50221 ci;
5509 + unsigned long next_status_checked_time;
5511 + u8 current_ci_flag;
5515 +static int dvbsky_stream_ctrl(struct dvb_usb_device *d, u8 onoff)
5517 + struct dvbsky_state *state = d_to_priv(d);
5519 + u8 obuf_pre[3] = { 0x37, 0, 0 };
5520 + u8 obuf_post[3] = { 0x36, 3, 0 };
5521 + dprintk("%s() -off \n", __func__);
5522 + mutex_lock(&state->stream_mutex);
5523 + ret = dvb_usbv2_generic_write(d, obuf_pre, 3);
5524 + if (!ret && onoff) {
5526 + ret = dvb_usbv2_generic_write(d, obuf_post, 3);
5527 + dprintk("%s() -on \n", __func__);
5529 + mutex_unlock(&state->stream_mutex);
5533 +/* CI opertaions */
5534 +static int dvbsky_ci_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
5538 + struct i2c_msg msg[] = {
5546 + .flags = I2C_M_RD,
5552 + ret = i2c_transfer(i2c_adap, msg, 2);
5555 + dprintk("%s: error, Reg = 0x%02x, Status = %d\n", __func__, reg, ret);
5561 +static int dvbsky_ci_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
5565 + u8 buffer[len + 1];
5567 + struct i2c_msg msg = {
5570 + .buf = &buffer[0],
5575 + memcpy(&buffer[1], buf, len);
5577 + ret = i2c_transfer(i2c_adap, &msg, 1);
5580 + dprintk("%s: error, Reg=[0x%02x], Status=%d\n", __func__, reg, ret);
5586 +static int dvbsky_ci_op_cam(struct dvb_ca_en50221 *ci, int slot,
5587 + u8 flag, u8 read, int addr, u8 data)
5589 + struct dvb_usb_device *d = ci->data;
5590 + struct dvbsky_state *state = d_to_priv(d);
5593 + u8 command[4], respond[2], command_size, respond_size;
5595 + /*dprintk("%s()\n", __func__);*/
5599 + if (state->current_ci_flag != flag) {
5600 + ret = dvbsky_ci_read_i2c(&d->i2c_adap, state->ci_i2c_addr,
5608 + ret = dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5613 + state->current_ci_flag = flag;
5615 + command[1] = (u8)((addr >> 8) & 0xff); /*high part of address*/
5616 + command[2] = (u8)(addr & 0xff); /*low part of address*/
5618 + command[0] = 0x71;
5622 + command[0] = 0x70;
5623 + command[3] = data;
5627 + ret = dvb_usbv2_generic_rw(d, command, command_size, respond, respond_size);
5629 + return (read) ? respond[1] : 0;
5632 +static int dvbsky_ci_read_attribute_mem(struct dvb_ca_en50221 *ci,
5633 + int slot, int addr)
5635 + return dvbsky_ci_op_cam(ci, slot, 0, DVBSKY_CI_RD, addr, 0);
5638 +static int dvbsky_ci_write_attribute_mem(struct dvb_ca_en50221 *ci,
5639 + int slot, int addr, u8 data)
5641 + return dvbsky_ci_op_cam(ci, slot, 0, 0, addr, data);
5644 +static int dvbsky_ci_read_cam_ctl(struct dvb_ca_en50221 *ci, int slot, u8 addr)
5646 + return dvbsky_ci_op_cam(ci, slot, DVBSKY_CI_CTL, DVBSKY_CI_RD, addr, 0);
5649 +static int dvbsky_ci_write_cam_ctl(struct dvb_ca_en50221 *ci, int slot,
5652 + return dvbsky_ci_op_cam(ci, slot, DVBSKY_CI_CTL, 0, addr, data);
5655 +static int dvbsky_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
5657 + struct dvb_usb_device *d = ci->data;
5658 + struct dvbsky_state *state = d_to_priv(d);
5661 + dprintk("%s() slot=%d\n", __func__, slot);
5667 + ret = dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5676 + ret = dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5679 + dprintk("%s() slot=%d complete\n", __func__, slot);
5684 +static int dvbsky_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
5686 + /* not implemented */
5687 + dprintk("%s()\n", __func__);
5691 +static int dvbsky_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
5693 + struct dvb_usb_device *d = ci->data;
5694 + struct dvbsky_state *state = d_to_priv(d);
5698 + dprintk("%s()\n", __func__);
5702 + dvbsky_ci_read_i2c(&d->i2c_adap, state->ci_i2c_addr,
5706 + ret = dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5711 +static int dvbsky_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
5714 + struct dvb_usb_device *d = ci->data;
5715 + struct dvbsky_state *state = d_to_priv(d);
5718 + /*dprintk("%s()\n", __func__);*/
5720 + /* CAM module INSERT/REMOVE processing. slow operation because of i2c
5722 + if (time_after(jiffies, state->next_status_checked_time)) {
5723 + ret = dvbsky_ci_read_i2c(&d->i2c_adap, state->ci_i2c_addr,
5726 + /*dprintk("%s() status=%x\n", __func__, buf);*/
5728 + state->next_status_checked_time = jiffies
5729 + + msecs_to_jiffies(1000);
5735 + state->ci_status = DVB_CA_EN50221_POLL_CAM_PRESENT |
5736 + DVB_CA_EN50221_POLL_CAM_READY;
5739 + state->ci_status = 0;
5741 + /*dprintk("%s() ret=%x\n", __func__, state->ci_status);*/
5742 + return state->ci_status;
5745 +static int dvbsky_ci_init(struct dvb_usb_device *d)
5747 + struct dvbsky_state *state = d_to_priv(d);
5749 + u8 cimax_init[34] = {
5750 + 0x00, /* module A control*/
5751 + 0x00, /* auto select mask high A */
5752 + 0x00, /* auto select mask low A */
5753 + 0x00, /* auto select pattern high A */
5754 + 0x00, /* auto select pattern low A */
5755 + 0x44, /* memory access time A */
5756 + 0x00, /* invert input A */
5759 + 0x00, /* module B control*/
5760 + 0x00, /* auto select mask high B */
5761 + 0x00, /* auto select mask low B */
5762 + 0x00, /* auto select pattern high B */
5763 + 0x00, /* auto select pattern low B */
5764 + 0x44, /* memory access time B */
5765 + 0x00, /* invert input B */
5768 + 0x00, /* auto select mask high Ext */
5769 + 0x00, /* auto select mask low Ext */
5770 + 0x00, /* auto select pattern high Ext */
5771 + 0x00, /* auto select pattern low Ext */
5773 + 0x02, /* destination - module A */
5774 + 0x01, /* power on (use it like store place) */
5776 + 0x00, /* int status read only */
5777 + 0x00, /* Max: Disable the interrupt in USB solution.*/
5778 + 0x05, /* EXTINT=active-high, INT=push-pull */
5780 + 0x04, /* ack active low */
5781 + 0x00, /* LOCK = 0 */
5782 + 0x22, /* serial mode, rising in, rising out, MSB first*/
5783 + 0x00 /* synchronization */
5785 + dprintk("%s()\n", __func__);
5786 + state->current_ci_flag = 0xff;
5787 + state->ci_status = 0;
5788 + state->next_status_checked_time = jiffies + msecs_to_jiffies(1000);
5789 + state->ci_i2c_addr = 0x40;
5791 + state->ci.owner = THIS_MODULE;
5792 + state->ci.read_attribute_mem = dvbsky_ci_read_attribute_mem;
5793 + state->ci.write_attribute_mem = dvbsky_ci_write_attribute_mem;
5794 + state->ci.read_cam_control = dvbsky_ci_read_cam_ctl;
5795 + state->ci.write_cam_control = dvbsky_ci_write_cam_ctl;
5796 + state->ci.slot_reset = dvbsky_ci_slot_reset;
5797 + state->ci.slot_shutdown = dvbsky_ci_slot_shutdown;
5798 + state->ci.slot_ts_enable = dvbsky_ci_slot_ts_enable;
5799 + state->ci.poll_slot_status = dvbsky_ci_poll_slot_status;
5800 + state->ci.data = d;
5802 + ret = dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5803 + 0, &cimax_init[0], 34);
5804 + /* lock registers */
5805 + ret |= dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5806 + 0x1f, &cimax_init[0x18], 1);
5807 + /* power on slots */
5808 + ret |= dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5809 + 0x18, &cimax_init[0x18], 1);
5813 + ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
5816 + state->ci_attached = 1;
5817 + dprintk("%s() complete.\n", __func__);
5821 +static void dvbsky_ci_release(struct dvb_usb_device *d)
5823 + struct dvbsky_state *state = d_to_priv(d);
5826 + if (state->ci_attached)
5827 + dvb_ca_en50221_release(&state->ci);
5832 +static int dvbsky_streaming_ctrl(struct dvb_frontend *fe, int onoff)
5834 + struct dvb_usb_device *d = fe_to_d(fe);
5835 + /*dprintk("%s() %d\n", __func__, onoff);*/
5836 + return dvbsky_stream_ctrl(d, (onoff == 0) ? 0 : 1);
5840 +static int dvbsky_gpio_ctrl(struct dvb_usb_device *d, u8 gport, u8 value)
5842 + u8 obuf[64], ibuf[64];
5846 + return dvb_usbv2_generic_rw(d, obuf, 3, ibuf, 1);
5850 +static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
5853 + struct dvb_usb_device *d = i2c_get_adapdata(adap);
5855 + u8 ibuf[64], obuf[64];
5857 + if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
5861 + printk(KERN_ERR "dvbsky_usb: too many i2c messages[%d] than 2.", num);
5862 + ret = -EOPNOTSUPP;
5867 + if (msg[0].len > 60) {
5868 + printk(KERN_ERR "dvbsky_usb: too many i2c bytes[%d] than 60.", msg[0].len);
5869 + ret = -EOPNOTSUPP;
5872 + if (msg[0].flags & I2C_M_RD) {
5876 + obuf[2] = msg[0].len;
5877 + obuf[3] = msg[0].addr;
5878 + ret = dvb_usbv2_generic_rw(d, obuf, 4, ibuf, msg[0].len + 1);
5879 + /*dprintk("%s(): read status = %d\n", __func__, ibuf[0]);*/
5881 + memcpy(msg[0].buf, &ibuf[1], msg[0].len);
5885 + obuf[1] = msg[0].addr;
5886 + obuf[2] = msg[0].len;
5887 + memcpy(&obuf[3], msg[0].buf, msg[0].len);
5888 + ret = dvb_usbv2_generic_rw(d, obuf, msg[0].len + 3, ibuf, 1);
5889 + /*dprintk("%s(): write status = %d\n", __func__, ibuf[0]);*/
5892 + if ((msg[0].len > 60) || (msg[1].len > 60)) {
5893 + printk(KERN_ERR "dvbsky_usb: too many i2c bytes[w-%d][r-%d] than 60.", msg[0].len, msg[1].len);
5894 + ret = -EOPNOTSUPP;
5897 + /* write then read */
5899 + obuf[1] = msg[0].len;
5900 + obuf[2] = msg[1].len;
5901 + obuf[3] = msg[0].addr;
5902 + memcpy(&obuf[4], msg[0].buf, msg[0].len);
5903 + ret = dvb_usbv2_generic_rw(d, obuf, msg[0].len + 4, ibuf, msg[1].len + 1);
5904 + /*dprintk("%s(): write then read status = %d\n", __func__, ibuf[0]);*/
5906 + memcpy(msg[1].buf, &ibuf[1], msg[1].len);
5909 + mutex_unlock(&d->i2c_mutex);
5910 + return (ret) ? ret : num;
5913 +static u32 dvbsky_i2c_func(struct i2c_adapter *adapter)
5915 + return I2C_FUNC_I2C;
5918 +static struct i2c_algorithm dvbsky_i2c_algo = {
5919 + .master_xfer = dvbsky_i2c_xfer,
5920 + .functionality = dvbsky_i2c_func,
5923 +#if IS_ENABLED(CONFIG_RC_CORE)
5924 +static int dvbsky_rc_query(struct dvb_usb_device *d)
5926 + u32 code = 0xffff;
5927 + u8 obuf[2], ibuf[2], toggle;
5930 + ret = dvb_usbv2_generic_rw(d, obuf, 1, ibuf, 2);
5932 + code = (ibuf[0] << 8) | ibuf[1];
5934 + if (code != 0xffff) {
5935 + dprintk("rc code: %x", code);
5936 + toggle = (code & 0x800) ? 1 : 0;
5938 + rc_keydown(d->rc_dev, code, toggle);
5943 +static int dvbsky_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
5945 + rc->allowed_protos = RC_BIT_RC5;
5946 + rc->query = dvbsky_rc_query;
5947 + rc->interval = 300;
5951 + #define dvbsky_get_rc_config NULL
5954 +static int dvbsky_sync_ctrl(struct dvb_frontend *fe)
5956 + struct dvb_usb_device *d = fe_to_d(fe);
5957 + return dvbsky_stream_ctrl(d, 1);
5960 +static int dvbsky_usb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
5962 + struct dvb_usb_device *d = fe_to_d(fe);
5965 + if (voltage == SEC_VOLTAGE_OFF)
5969 + return dvbsky_gpio_ctrl(d, 0x80, value);
5972 +static int dvbsky_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6])
5974 + struct dvb_usb_device *d = adap_to_d(adap);
5975 + u8 obuf[] = { 0x1e, 0x00 };
5976 + u8 ibuf[6] = { 0 };
5977 + struct i2c_msg msg[] = {
5985 + .flags = I2C_M_RD,
5992 + if (i2c_transfer(&d->i2c_adap, msg, 2) == 2)
5993 + memcpy(mac, ibuf, 6);
5995 + printk(KERN_INFO "dvbsky_usb MAC address=%pM\n", mac);
6000 +static struct m88ds3103_config dvbsky_usb_ds3103_config = {
6001 + .demod_address = 0x68,
6005 + .start_ctrl = dvbsky_sync_ctrl,
6006 + .set_voltage = dvbsky_usb_set_voltage,
6009 +static int dvbsky_s960_attach(struct dvb_usb_adapter *adap)
6011 + struct dvbsky_state *state = adap_to_priv(adap);
6012 + struct dvb_usb_device *d = adap_to_d(adap);
6015 + dprintk("%s()\n", __func__);
6017 + dvbsky_gpio_ctrl(d, 0x04, 1);
6019 + dvbsky_gpio_ctrl(d, 0x83, 0);
6021 + dvbsky_gpio_ctrl(d, 0x83, 1);
6024 + adap->fe[0] = dvb_attach(m88ds3103_attach,
6025 + &dvbsky_usb_ds3103_config,
6027 + if (!adap->fe[0]) {
6028 + printk(KERN_ERR "dvbsky_s960_attach fail.");
6032 + state->has_ci = 0;
6037 +static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
6042 +static int dvbsky_init(struct dvb_usb_device *d)
6044 + struct dvbsky_state *state = d_to_priv(d);
6047 + /* use default interface */
6048 + ret = usb_set_interface(d->udev, 0, 0);
6052 + mutex_init(&state->stream_mutex);
6055 + if (state->has_ci) {
6056 + dvbsky_gpio_ctrl(d, 0xc0, 1);
6058 + dvbsky_gpio_ctrl(d, 0xc0, 0);
6060 + state->ci_attached = 0;
6061 + ret = dvbsky_ci_init(d);
6068 +static void dvbsky_exit(struct dvb_usb_device *d)
6070 + return dvbsky_ci_release(d);
6073 +/* DVB USB Driver stuff */
6074 +static struct dvb_usb_device_properties dvbsky_s960_props = {
6075 + .driver_name = KBUILD_MODNAME,
6076 + .owner = THIS_MODULE,
6077 + .adapter_nr = adapter_nr,
6078 + .size_of_priv = sizeof(struct dvbsky_state),
6080 + .generic_bulk_ctrl_endpoint = 0x01,
6081 + .generic_bulk_ctrl_endpoint_response = 0x81,
6083 + .i2c_algo = &dvbsky_i2c_algo,
6084 + .frontend_attach = dvbsky_s960_attach,
6085 + .init = dvbsky_init,
6086 + .get_rc_config = dvbsky_get_rc_config,
6087 + .streaming_ctrl = dvbsky_streaming_ctrl,
6088 + .identify_state = dvbsky_identify_state,
6089 + .exit = dvbsky_exit,
6090 + .read_mac_address = dvbsky_read_mac_addr,
6092 + .num_adapters = 1,
6095 + .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
6100 +static const struct usb_device_id dvbsky_id_table[] = {
6101 + { DVB_USB_DEVICE(0x0572, 0x6831,
6102 + &dvbsky_s960_props, "DVBSky S960/S860", RC_MAP_DVBSKY) },
6105 +MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
6107 +static struct usb_driver dvbsky_usb_driver = {
6108 + .name = KBUILD_MODNAME,
6109 + .id_table = dvbsky_id_table,
6110 + .probe = dvb_usbv2_probe,
6111 + .disconnect = dvb_usbv2_disconnect,
6112 + .suspend = dvb_usbv2_suspend,
6113 + .resume = dvb_usbv2_resume,
6114 + .reset_resume = dvb_usbv2_reset_resume,
6115 + .no_dynamic_id = 1,
6119 +module_usb_driver(dvbsky_usb_driver);
6121 +MODULE_AUTHOR("Max nibble <nibble.max@gmail.com>");
6122 +MODULE_DESCRIPTION("Driver for DVBSky USB2.0");
6123 +MODULE_LICENSE("GPL");
6124 diff -urN a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
6125 --- a/drivers/media/usb/dvb-usb-v2/Kconfig 2013-04-29 08:36:01.000000000 +0800
6126 +++ b/drivers/media/usb/dvb-usb-v2/Kconfig 2013-05-03 17:45:35.000000000 +0800
6127 @@ -149,3 +149,10 @@
6129 Say Y here to support the Realtek RTL28xxU DVB USB receiver.
6131 +config DVB_USB_DVBSKY
6132 + tristate "DVBSky USB2.0 support"
6133 + depends on DVB_USB_V2
6134 + select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
6136 + Say Y here to support the USB receivers from DVBSky.
6138 diff -urN a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
6139 --- a/drivers/media/usb/dvb-usb-v2/Makefile 2013-04-29 08:36:01.000000000 +0800
6140 +++ b/drivers/media/usb/dvb-usb-v2/Makefile 2013-02-17 12:03:00.000000000 +0800
6142 dvb-usb-rtl28xxu-objs := rtl28xxu.o
6143 obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
6145 +dvb-usb-dvbsky-objs := dvbsky.o
6146 +obj-$(CONFIG_DVB_USB_DVBSKY) += dvb-usb-dvbsky.o
6148 ccflags-y += -I$(srctree)/drivers/media/dvb-core
6149 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
6150 ccflags-y += -I$(srctree)/drivers/media/tuners
6151 diff -urN a/include/media/rc-map.h b/include/media/rc-map.h
6152 --- a/include/media/rc-map.h 2013-04-29 08:36:01.000000000 +0800
6153 +++ b/include/media/rc-map.h 2013-05-03 17:02:46.000000000 +0800
6155 #define RC_MAP_DM1105_NEC "rc-dm1105-nec"
6156 #define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro"
6157 #define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t"
6158 +#define RC_MAP_DVBSKY "rc-dvbsky"
6159 #define RC_MAP_EMPTY "rc-empty"
6160 #define RC_MAP_EM_TERRATEC "rc-em-terratec"
6161 #define RC_MAP_ENCORE_ENLTV2 "rc-encore-enltv2"