]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - src/patches/linux-3.9-dvbsky-wot2.patch
tor: Bump package version to 6 and fix backup.
[people/teissler/ipfire-2.x.git] / src / patches / linux-3.9-dvbsky-wot2.patch
CommitLineData
e2b79cd1
AF
1diff -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
4@@ -200,6 +200,20 @@
5 help
6 A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
7
8+config DVB_M88DS3103
9+ tristate "Montage M88DS3103 based"
10+ depends on DVB_CORE && I2C
11+ default m if !MEDIA_SUBDRV_AUTOSELECT
12+ help
13+ A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
14+
15+config DVB_M88DC2800
16+ tristate "Montage M88DC2800 based"
17+ depends on DVB_CORE && I2C
18+ default m if !MEDIA_SUBDRV_AUTOSELECT
19+ help
20+ A DVB-C tuner module. Say Y when you want to support this frontend.
21+
22 config DVB_SI21XX
23 tristate "Silicon Labs SI21XX based"
24 depends on DVB_CORE && I2C
25diff -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
28@@ -0,0 +1,2124 @@
29+/*
30+ M88DC2800/M88TC2800 - DVB-C demodulator and tuner from Montage
31+
32+ Copyright (C) 2012 Max nibble<nibble.max@gmail.com>
33+ Copyright (C) 2011 Montage Technology / www.montage-tech.com
34+
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.
39+
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.
44+
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.
48+*/
49+
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"
60+
61+struct m88dc2800_state {
62+ struct i2c_adapter *i2c;
63+ const struct m88dc2800_config *config;
64+ struct dvb_frontend frontend;
65+ u32 freq;
66+ u32 ber;
67+ u32 sym;
68+ u16 qam;
69+ u8 inverted;
70+ u32 xtal;
71+ /* tuner state */
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 */
76+ u16 tuner_mode;
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 */
84+ u32 tuner_time;
85+};
86+
87+static int debug;
88+module_param(debug, int, 0644);
89+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
90+
91+#define dprintk(args...) \
92+ do { \
93+ if (debug) \
94+ printk(KERN_INFO "m88dc2800: " args); \
95+ } while (0)
96+
97+
98+static int m88dc2800_i2c_write(struct m88dc2800_state *state, u8 addr,
99+ u8 * p_data, u8 len)
100+{
101+ struct i2c_msg msg = { .flags = 0 };
102+
103+ msg.addr = addr;
104+ msg.buf = p_data;
105+ msg.len = len;
106+
107+ return i2c_transfer(state->i2c, &msg, 1);
108+}
109+
110+static int m88dc2800_i2c_read(struct m88dc2800_state *state, u8 addr,
111+ u8 * p_data, u8 len)
112+{
113+ struct i2c_msg msg = { .flags = I2C_M_RD };
114+
115+ msg.addr = addr;
116+ msg.buf = p_data;
117+ msg.len = len;
118+
119+ return i2c_transfer(state->i2c, &msg, 1);
120+}
121+
122+/*demod register operations.*/
123+static int WriteReg(struct m88dc2800_state *state, u8 reg, u8 data)
124+{
125+ u8 buf[] = { reg, data };
126+ u8 addr = state->config->demod_address;
127+ int err;
128+
129+ dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
130+
131+ err = m88dc2800_i2c_write(state, addr, buf, 2);
132+
133+ if (err != 1) {
134+ printk(KERN_ERR
135+ "%s: writereg error(err == %i, reg == 0x%02x,"
136+ " value == 0x%02x)\n", __func__, err, reg, data);
137+ return -EIO;
138+ }
139+ return 0;
140+}
141+
142+static int ReadReg(struct m88dc2800_state *state, u8 reg)
143+{
144+ int ret;
145+ u8 b0[] = { reg };
146+ u8 b1[] = { 0 };
147+ u8 addr = state->config->demod_address;
148+
149+ ret = m88dc2800_i2c_write(state, addr, b0, 1);
150+
151+ if (ret != 1) {
152+ printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
153+ __func__, reg, ret);
154+ return -EIO;
155+ }
156+
157+ ret = m88dc2800_i2c_read(state, addr, b1, 1);
158+
159+ dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
160+ return b1[0];
161+}
162+
163+static int _mt_fe_tn_set_reg(struct m88dc2800_state *state, u8 reg,
164+ u8 data)
165+{
166+ int ret;
167+ u8 buf[2];
168+ u8 addr = state->tuner_dev_addr;
169+
170+ buf[1] = ReadReg(state, 0x86);
171+ buf[1] |= 0x80;
172+ ret = WriteReg(state, 0x86, buf[1]);
173+
174+ buf[0] = reg;
175+ buf[1] = data;
176+
177+ ret = m88dc2800_i2c_write(state, addr, buf, 2);
178+ if (ret != 1)
179+ return -EIO;
180+ return 0;
181+}
182+
183+static int _mt_fe_tn_get_reg(struct m88dc2800_state *state, u8 reg,
184+ u8 * p_data)
185+{
186+ int ret;
187+ u8 buf[2];
188+ u8 addr = state->tuner_dev_addr;
189+
190+ buf[1] = ReadReg(state, 0x86);
191+ buf[1] |= 0x80;
192+ ret = WriteReg(state, 0x86, buf[1]);
193+
194+ buf[0] = reg;
195+ ret = m88dc2800_i2c_write(state, addr, buf, 1);
196+
197+ msleep(1);
198+
199+ buf[1] = ReadReg(state, 0x86);
200+ buf[1] |= 0x80;
201+ ret = WriteReg(state, 0x86, buf[1]);
202+
203+ return m88dc2800_i2c_read(state, addr, p_data, 1);
204+}
205+
206+/* Tuner operation functions.*/
207+static int _mt_fe_tn_set_RF_front_tc2800(struct m88dc2800_state *state)
208+{
209+ u32 freq_KHz = state->tuner_freq;
210+ u8 a, b, c;
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;
227+ } else {
228+ a = 0x70; b = 0x07; c = 0x38;
229+ }
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);
255+ }
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);
260+ } else {
261+ _mt_fe_tn_set_reg(state, 0x73, 0x0e);
262+ }
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);
275+ }
276+ }
277+ }
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);
290+ else
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);
296+ else
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);
302+ } else {
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);
323+ }
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);
343+ }
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);
348+ } else {
349+ _mt_fe_tn_set_reg(state, 0x5b, 0x2a);
350+ }
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);
360+ } else {
361+ _mt_fe_tn_set_reg(state, 0x5c, 0xa8);
362+ }
363+ _mt_fe_tn_set_reg(state, 0x5b, 0x08);
364+ }
365+ }
366+ } /* end of 0xE1 */
367+ return 0;
368+}
369+
370+static int _mt_fe_tn_cali_PLL_tc2800(struct m88dc2800_state *state,
371+ u32 freq_KHz,
372+ u32 cali_freq_thres_div2,
373+ u32 cali_freq_thres_div3r,
374+ u32 cali_freq_thres_div3)
375+{
376+ s32 N, F, MUL;
377+ u8 buf, tmp, tmp2;
378+ s32 M;
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) {
383+ MUL = 4;
384+ tmp = 2;
385+ } else if (freq_KHz > 300000) {
386+ MUL = 8;
387+ tmp = 3;
388+ } else if (freq_KHz > (cali_freq_thres_div2 / 2)) {
389+ MUL = 8;
390+ tmp = 4;
391+ } else if (freq_KHz > (cali_freq_thres_div2 / 4)) {
392+ MUL = 16;
393+ tmp = 5;
394+ } else if (freq_KHz > (cali_freq_thres_div2 / 8)) {
395+ MUL = 32;
396+ tmp = 6;
397+ } else if (freq_KHz > (cali_freq_thres_div2 / 16)) {
398+ MUL = 64;
399+ tmp = 7;
400+ } else { /* invalid */
401+ MUL = 0;
402+ tmp = 0;
403+ return 1;
404+ }
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) {
415+ M = M / 4;
416+ MUL = 4;
417+ tmp = 2;
418+ tmp2 = M + 16; /* 48 */
419+ } else if (freq_KHz > cali_freq_thres_div3r) {
420+ M = M / 3;
421+ MUL = 6;
422+ tmp = 2;
423+ tmp2 = M + 32; /* 32 */
424+ } else if (freq_KHz > cali_freq_thres_div3) {
425+ M = M / 3;
426+ MUL = 6;
427+ tmp = 2;
428+ tmp2 = M; /* 16 */
429+ } else if (freq_KHz > 304000) {
430+ M = M / 4;
431+ MUL = 8;
432+ tmp = 3;
433+ tmp2 = M + 16; /* 48 */
434+ } else if (freq_KHz > (cali_freq_thres_div2 / 2)) {
435+ M = M / 4;
436+ MUL = 8;
437+ tmp = 4;
438+ tmp2 = M + 16; /* 48 */
439+ } else if (freq_KHz > (cali_freq_thres_div3r / 2)) {
440+ M = M / 3;
441+ MUL = 12;
442+ tmp = 4;
443+ tmp2 = M + 32; /* 32 */
444+ } else if (freq_KHz > (cali_freq_thres_div3 / 2)) {
445+ M = M / 3;
446+ MUL = 12;
447+ tmp = 4;
448+ tmp2 = M; /* 16 */
449+ } else if (freq_KHz > (cali_freq_thres_div2 / 4)) {
450+ M = M / 4;
451+ MUL = 16;
452+ tmp = 5;
453+ tmp2 = M + 16; /* 48 */
454+ } else if (freq_KHz > (cali_freq_thres_div3r / 4)) {
455+ M = M / 3;
456+ MUL = 24;
457+ tmp = 5;
458+ tmp2 = M + 32; /* 32 */
459+ } else if (freq_KHz > (cali_freq_thres_div3 / 4)) {
460+ M = M / 3;
461+ MUL = 24;
462+ tmp = 5;
463+ tmp2 = M; /* 16 */
464+ } else if (freq_KHz > (cali_freq_thres_div2 / 8)) {
465+ M = M / 4;
466+ MUL = 32;
467+ tmp = 6;
468+ tmp2 = M + 16; /* 48 */
469+ } else if (freq_KHz > (cali_freq_thres_div3r / 8)) {
470+ M = M / 3;
471+ MUL = 48;
472+ tmp = 6;
473+ tmp2 = M + 32; /* 32 */
474+ } else if (freq_KHz > (cali_freq_thres_div3 / 8)) {
475+ M = M / 3;
476+ MUL = 48;
477+ tmp = 6;
478+ tmp2 = M; /* 16 */
479+ } else if (freq_KHz > (cali_freq_thres_div2 / 16)) {
480+ M = M / 4;
481+ MUL = 64;
482+ tmp = 7;
483+ tmp2 = M + 16; /* 48 */
484+ } else if (freq_KHz > (cali_freq_thres_div3r / 16)) {
485+ M = M / 3;
486+ MUL = 96;
487+ tmp = 7;
488+ tmp2 = M + 32; /* 32 */
489+ } else if (freq_KHz > (cali_freq_thres_div3 / 16)) {
490+ M = M / 3;
491+ MUL = 96;
492+ tmp = 7;
493+ tmp2 = M; /* 16 */
494+ } else { /* invalid */
495+ M = M / 4;
496+ MUL = 0;
497+ tmp = 0;
498+ tmp2 = 48;
499+ return 1;
500+ }
501+ if (freq_KHz == 291000) {
502+ M = state->tuner_crystal / 1000 / 3;
503+ MUL = 12;
504+ tmp = 4;
505+ tmp2 = M + 32; /* 32 */
506+ }
507+ /*
508+ if (freq_KHz == 578000) {
509+ M = state->tuner_crystal / 1000 / 4;
510+ MUL = 4;
511+ tmp = 2;
512+ tmp2 = M + 16; // 48
513+ }
514+ */
515+ if (freq_KHz == 690000) {
516+ M = state->tuner_crystal / 1000 / 3;
517+ MUL = 4;
518+ tmp = 2;
519+ tmp2 = M + 16; /* 48 */
520+ }
521+ _mt_fe_tn_get_reg(state, 0x33, &buf);
522+ buf &= 0xc0;
523+ buf += tmp2;
524+ _mt_fe_tn_set_reg(state, 0x33, buf);
525+ } else {
526+ return 1;
527+ }
528+ _mt_fe_tn_get_reg(state, 0x39, &buf);
529+ buf &= 0xf8;
530+ buf += tmp;
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) {
535+ buf |= 0x30;
536+ }
537+ _mt_fe_tn_set_reg(state, 0x34, buf);
538+ buf = N & 0xff;
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;
542+ buf = F & 0xff;
543+ _mt_fe_tn_set_reg(state, 0x36, buf);
544+ if (F == 0) {
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);
549+ } else {
550+ return 1;
551+ }
552+ _mt_fe_tn_set_reg(state, 0x3e, 0x9c);
553+ _mt_fe_tn_set_reg(state, 0x3f, 0x34);
554+ }
555+ if (F > 0) {
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);
561+ } else {
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);
565+ }
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);
572+ buf = buf & 0x1f;
573+ _mt_fe_tn_set_reg(state, 0x39, buf);
574+ _mt_fe_tn_get_reg(state, 0x32, &buf);
575+ buf = buf | 0x02;
576+ _mt_fe_tn_set_reg(state, 0x32, buf);
577+ } else {
578+ return 1;
579+ }
580+ }
581+ _mt_fe_tn_set_reg(state, 0x41, 0x00);
582+ if (state->tuner_mtt == 0xD1) {
583+ msleep(5);
584+ } else if (state->tuner_mtt == 0xE1) {
585+ msleep(2);
586+ } else {
587+ return 1;
588+ }
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);
594+
595+ return 0;
596+}
597+
598+static int _mt_fe_tn_set_PLL_freq_tc2800(struct m88dc2800_state *state)
599+{
600+ u8 buf, buf1;
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);
614+ msleep(5);
615+ _mt_fe_tn_get_reg(state, 0x3a, &buf);
616+ buf1 = buf;
617+ buf = buf & 0x03;
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,
623+ 0);
624+ msleep(5);
625+ _mt_fe_tn_get_reg(state, 0x3a, &buf);
626+ buf = buf & 0x07;
627+ if (buf == 5) {
628+ freq_thres_div2_KHz = 520000;
629+ _mt_fe_tn_cali_PLL_tc2800(state, freq_KHz,
630+ freq_thres_div2_KHz,
631+ 0, 0);
632+ msleep(5);
633+ }
634+ }
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);
638+ buf = buf | 0x10;
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);
643+ buf = buf & 0xdf;
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);
650+ msleep(5);
651+ _mt_fe_tn_get_reg(state, 0x39, &buf);
652+ buf = buf >> 5;
653+ if (buf < 5) {
654+ _mt_fe_tn_get_reg(state, 0x39, &buf);
655+ buf = buf | 0xa0;
656+ buf = buf & 0xbf;
657+ _mt_fe_tn_set_reg(state, 0x39, buf);
658+ _mt_fe_tn_get_reg(state, 0x32, &buf);
659+ buf = buf | 0x02;
660+ _mt_fe_tn_set_reg(state, 0x32, buf);
661+ }
662+ _mt_fe_tn_get_reg(state, 0x37, &buf);
663+ if (buf > 0x70) {
664+ buf = 0x7f;
665+ _mt_fe_tn_set_reg(state, 0x40, 0x40);
666+ }
667+ _mt_fe_tn_set_reg(state, 0x37, buf);
668+ _mt_fe_tn_get_reg(state, 0x38, &buf);
669+ if (buf < 0x0f) {
670+ buf = (buf & 0x0f) << 2;
671+ buf = buf + 0x0f;
672+ _mt_fe_tn_set_reg(state, 0x37, buf);
673+ } else if (buf < 0x1f) {
674+ buf = buf + 0x0f;
675+ _mt_fe_tn_set_reg(state, 0x37, buf);
676+ }
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);
681+ msleep(5);
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);
691+ msleep(3);
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);
698+ msleep(3);
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);
702+ buf = buf | 0x10;
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);
707+ buf = buf & 0xdf;
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);
711+ msleep(3);
712+ _mt_fe_tn_get_reg(state, 0x37, &buf);
713+ _mt_fe_tn_set_reg(state, 0x37, buf);
714+ /*
715+ if ((freq_KHz == 802000) || (freq_KHz == 826000)) {
716+ _mt_fe_tn_set_reg(state, 0x37, 0x5e);
717+ }
718+ */
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);
723+ msleep(2);
724+ _mt_fe_tn_set_reg(state, 0x41, 0x02);
725+ } else {
726+ return 1;
727+ }
728+ return 0;
729+}
730+
731+static int _mt_fe_tn_set_BB_tc2800(struct m88dc2800_state *state)
732+{
733+ return 0;
734+}
735+
736+ static int _mt_fe_tn_set_appendix_tc2800(struct m88dc2800_state *state)
737+
738+{
739+ u8 buf;
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);
745+ }
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));
751+ }
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));
757+ }
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);
769+ }
770+ }
771+ return 0;
772+}
773+
774+ static int _mt_fe_tn_set_DAC_tc2800(struct m88dc2800_state *state)
775+{
776+ u8 buf, tempnumber;
777+ s32 N;
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;
788+
789+ if (state->tuner_mtt == 0xE1) {
790+ _mt_fe_tn_get_reg(state, 0x33, &buf);
791+ M = buf & 0x0f;
792+ if (M == 0)
793+ M = 6;
794+ }
795+ _mt_fe_tn_get_reg(state, 0x34, &buf);
796+ N = buf & 0x07;
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)) {
815+ buf = buf + 1;
816+ }
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)) {
841+ buf = buf - 1;
842+ }
843+ }
844+ _mt_fe_tn_set_reg(state, 0x0e, buf);
845+ _mt_fe_tn_set_reg(state, 0x0d, buf);
846+ f1f2number =
847+ (((DACFreq_KHz * M * buf) / crystal_KHz) << 16) / (N + 256) +
848+ (((DACFreq_KHz * M * buf) % crystal_KHz) << 16) / ((N + 256) *
849+ crystal_KHz);
850+ _mt_fe_tn_set_reg(state, 0xf1, (f1f2number & 0xff00) >> 8);
851+ _mt_fe_tn_set_reg(state, 0xf2, f1f2number & 0x00ff);
852+ FreqTrue108_Hz =
853+ (N + 256) * crystal_KHz / (M * buf) * 1000 +
854+ (((N + 256) * crystal_KHz) % (M * buf)) * 1000 / (M * buf);
855+ f1 = 4096;
856+ fc = FreqTrue108_Hz;
857+ fadc = fc / 4;
858+ fsd = 27000000;
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;
863+ cntT = f2;
864+ cntin = Totalnum1;
865+ NCOI = delta1;
866+ z0 = cntin;
867+ z1 = cntT;
868+ z2 = NCOI;
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);
881+ tmp = f1;
882+ f1 = f2;
883+ f2 = tmp / 2;
884+ delta1 = ((f1 - f2) << 15) / f2;
885+ Totalnum1 = ((f1 - f2) << 15) - delta1 * f2;
886+ NCOI = (f1 << 15) / f2 - (1 << 15);
887+ cntT = f2;
888+ cntin = Totalnum1;
889+ z0 = cntin;
890+ z1 = cntT;
891+ z2 = NCOI;
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);
904+
905+ return 0;
906+}
907+
908+static int _mt_fe_tn_preset_tc2800(struct m88dc2800_state *state)
909+{
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);
951+ } else {
952+ _mt_fe_tn_set_reg(state, 0x67, 0x05);
953+ }
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);
968+ }
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);
979+ }
980+ return 0;
981+}
982+
983+static int mt_fe_tn_wakeup_tc2800(struct m88dc2800_state *state)
984+{
985+ _mt_fe_tn_set_reg(state, 0x16, 0xb1);
986+ _mt_fe_tn_set_reg(state, 0x09, 0x7d);
987+ return 0;
988+}
989+
990+ static int mt_fe_tn_sleep_tc2800(struct m88dc2800_state *state)
991+{
992+ _mt_fe_tn_set_reg(state, 0x16, 0xb0);
993+ _mt_fe_tn_set_reg(state, 0x09, 0x6d);
994+ return 0;
995+}
996+
997+ static int mt_fe_tn_init_tc2800(struct m88dc2800_state *state)
998+{
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;
1013+ }
1014+ _mt_fe_tn_set_reg(state, 0x2b, 0x46);
1015+ _mt_fe_tn_set_reg(state, 0x2c, 0x75);
1016+ if (state->tuner_mtt == 0x00) {
1017+ u8 tmp = 0;
1018+ _mt_fe_tn_get_reg(state, 0x01, &tmp);
1019+ printk(KERN_INFO "m88dc2800: tuner id = 0x%02x ", tmp);
1020+ switch (tmp) {
1021+ case 0x0d:
1022+ state->tuner_mtt = 0xD1;
1023+ break;
1024+ case 0x8e:
1025+ default:
1026+ state->tuner_mtt = 0xE1;
1027+ break;
1028+ }
1029+ }
1030+ return 0;
1031+}
1032+
1033+ static int mt_fe_tn_set_freq_tc2800(struct m88dc2800_state *state,
1034+ u32 freq_KHz)
1035+{
1036+ u8 buf;
1037+ u8 buf1;
1038+
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);
1055+ msleep(5);
1056+ _mt_fe_tn_set_reg(state, 0x41, 0x00);
1057+ msleep(5);
1058+ _mt_fe_tn_set_reg(state, 0x41, 0x02);
1059+
1060+ _mt_fe_tn_get_reg(state, 0x69, &buf1);
1061+ buf1 = buf1 & 0x0f;
1062+ _mt_fe_tn_get_reg(state, 0x61, &buf);
1063+ buf = buf & 0x0f;
1064+ if (buf == 0x0c)
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);
1071+ else
1072+ _mt_fe_tn_set_reg(state, 0x66, 0x74);
1073+ }
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);
1087+ else
1088+ _mt_fe_tn_set_reg(state, 0x87, 0x54);
1089+ msleep(5);
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);
1103+ else
1104+ _mt_fe_tn_set_reg(state, 0x87, 0x54);
1105+ msleep(5);
1106+ }
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);
1110+ msleep(20);
1111+ _mt_fe_tn_get_reg(state, 0x32, &buf);
1112+ buf = (buf & 0xef) | 0x28;
1113+ _mt_fe_tn_set_reg(state, 0x32, buf);
1114+ msleep(50);
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);
1120+ msleep(10);
1121+ _mt_fe_tn_get_reg(state, 0x69, &buf);
1122+ buf = buf & 0x03;
1123+ _mt_fe_tn_set_reg(state, 0x2a, buf);
1124+ if (buf > 0) {
1125+ msleep(20);
1126+ _mt_fe_tn_get_reg(state, 0x84, &buf);
1127+ buf = buf & 0x1f;
1128+ _mt_fe_tn_set_reg(state, 0x68, 0x0a);
1129+ _mt_fe_tn_get_reg(state, 0x88, &buf1);
1130+ buf1 = buf1 & 0x1f;
1131+ if (buf <= buf1)
1132+ _mt_fe_tn_set_reg(state, 0x66, 0x44);
1133+ else
1134+ _mt_fe_tn_set_reg(state, 0x66, 0x74);
1135+ } else {
1136+ if (freq_KHz <= 600000)
1137+ _mt_fe_tn_set_reg(state, 0x68, 0x0c);
1138+ else
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);
1144+ }
1145+ if (state->tuner_loopthrough != 0) {
1146+ _mt_fe_tn_get_reg(state, 0x28, &buf);
1147+ if (buf == 0) {
1148+ _mt_fe_tn_set_reg(state, 0x28, 0xff);
1149+ _mt_fe_tn_get_reg(state, 0x61, &buf);
1150+ buf = buf & 0x0f;
1151+ if (buf > 9)
1152+ _mt_fe_tn_set_reg(state, 0x67, 0x74);
1153+ else if (buf > 6)
1154+ _mt_fe_tn_set_reg(state, 0x67, 0x64);
1155+ else if (buf > 3)
1156+ _mt_fe_tn_set_reg(state, 0x67, 0x54);
1157+ else
1158+ _mt_fe_tn_set_reg(state, 0x67, 0x44);
1159+ }
1160+ } else {
1161+ _mt_fe_tn_set_reg(state, 0x67, 0x34);
1162+ }
1163+ } else {
1164+ return 1;
1165+ }
1166+ return 0;
1167+}
1168+
1169+
1170+/*
1171+static int mt_fe_tn_set_BB_filter_band_tc2800(struct m88dc2800_state *state,
1172+ u8 bandwidth)
1173+{
1174+ u8 buf, tmp;
1175+
1176+ _mt_fe_tn_get_reg(state, 0x53, &tmp);
1177+
1178+ if (bandwidth == 6)
1179+ buf = 0x01 << 1;
1180+ else if (bandwidth == 7)
1181+ buf = 0x02 << 1;
1182+ else if (bandwidth == 8)
1183+ buf = 0x04 << 1;
1184+ else
1185+ buf = 0x04 << 1;
1186+
1187+ tmp &= 0xf1;
1188+ tmp |= buf;
1189+ _mt_fe_tn_set_reg(state, 0x53, tmp);
1190+ state->tuner_bandwidth = bandwidth;
1191+ return 0;
1192+}
1193+*/
1194+
1195+static s32 mt_fe_tn_get_signal_strength_tc2800(struct m88dc2800_state
1196+ *state)
1197+{
1198+ s32 level = -107;
1199+ s32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
1200+ s32 val1, val2, val;
1201+ s32 result2, result3, result4, result5, result6;
1202+ s32 append;
1203+ u8 tmp;
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;
1218+ if (tmp1 > 6) {
1219+ val1 = 0;
1220+ if (freq_KHz <= 200000) {
1221+ val2 = (tmp1 - 6) * 267;
1222+ } else if (freq_KHz <= 600000) {
1223+ val2 = (tmp1 - 6) * 280;
1224+ } else {
1225+ val2 = (tmp1 - 6) * 290;
1226+ }
1227+ val = val1 + val2;
1228+ } else {
1229+ if (tmp1 == 0) {
1230+ val1 = -550;
1231+ } else {
1232+ val1 = 0;
1233+ }
1234+ if ((tmp1 < 4) && (freq_KHz >= 506000)) {
1235+ val1 = -850;
1236+ }
1237+ val2 = 0;
1238+ val = val1 + val2;
1239+ }
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;
1256+ } else {
1257+ result2 = tmp2 * 200;
1258+ }
1259+ result3 = (6 - tmp3) * 100;
1260+ result4 = 300 * tmp4;
1261+ result5 = 50 * tmp5;
1262+ result6 = 300 * tmp6;
1263+ if (freq_KHz < 105000) {
1264+ append = -450;
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;
1273+ } else {
1274+ append = -500;
1275+ }
1276+ level = append - (val + result2 + result3 + result4 +
1277+ result5 + result6);
1278+ level /= 100;
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;
1303+ result4 = 650;
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;
1308+ } else {
1309+ result2 = (307 - freq_KHz / 1000) * 82 / 27 + 11270;
1310+ result3 = 8400;
1311+ result4 = 5300;
1312+ }
1313+ if (tmp1 > 6) {
1314+ val1 = result2;
1315+ val2 = 2900;
1316+ val = 500;
1317+ } else if (tmp1 > 0) {
1318+ val1 = result3;
1319+ val2 = 2700;
1320+ val = 500;
1321+ } else {
1322+ val1 = result4;
1323+ val2 = 2700;
1324+ val = 400;
1325+ }
1326+ level = val1 - (val2 * tmp1 + 500 * tmp2 + 3000 * tmp3 -
1327+ 500 * tmp4 + 3000 * tmp5 + val * tmp6) - 1000;
1328+ level /= 1000;
1329+ }
1330+ return level;
1331+}
1332+
1333+
1334+/* m88dc2800 operation functions */
1335+u8 M88DC2000GetLock(struct m88dc2800_state * state)
1336+{
1337+ u8 u8ret = 0;
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)
1342+ u8ret = 1;
1343+ else
1344+ u8ret = 0;
1345+ } else {
1346+ if ((ReadReg(state, 0x85) & 0x08) == 0x08)
1347+ u8ret = 1;
1348+ else
1349+ u8ret = 0;
1350+ }
1351+ dprintk("%s, lock=%d\n", __func__, u8ret);
1352+ return u8ret;
1353+}
1354+
1355+static int M88DC2000SetTsType(struct m88dc2800_state *state, u8 type)
1356+{
1357+ u8 regC2H;
1358+
1359+ if (type == 3) {
1360+ WriteReg(state, 0x84, 0x6A);
1361+ WriteReg(state, 0xC0, 0x43);
1362+ WriteReg(state, 0xE2, 0x06);
1363+ regC2H = ReadReg(state, 0xC2);
1364+ regC2H &= 0xC0;
1365+ regC2H |= 0x1B;
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);
1373+ regC2H &= 0xC7;
1374+ WriteReg(state, 0xC2, regC2H);
1375+ WriteReg(state, 0xC1, 0x00);
1376+ } else {
1377+ WriteReg(state, 0x84, 0x6C);
1378+ WriteReg(state, 0xC0, 0x43); /* parallel format */
1379+ WriteReg(state, 0xE2, 0x06);
1380+ regC2H = ReadReg(state, 0xC2);
1381+ regC2H &= 0xC7;
1382+ WriteReg(state, 0xC2, regC2H);
1383+ WriteReg(state, 0xC1, 0x00);
1384+ }
1385+ return 0;
1386+}
1387+
1388+static int M88DC2000RegInitial_TC2800(struct m88dc2800_state *state)
1389+{
1390+ u8 RegE3H, RegE4H;
1391+
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);
1478+ } else {
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);
1504+ }
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);
1529+
1530+ return 0;
1531+}
1532+
1533+static int M88DC2000AutoTSClock_P(struct m88dc2800_state *state, u32 sym,
1534+ u16 qam)
1535+{
1536+ u32 dataRate;
1537+ u8 clk_div, value;
1538+ printk(KERN_INFO
1539+ "m88dc2800: M88DC2000AutoTSClock_P, symrate=%d qam=%d\n",
1540+ sym, qam);
1541+ switch (qam) {
1542+ case 16:
1543+ dataRate = 4;
1544+ break;
1545+ case 32:
1546+ dataRate = 5;
1547+ break;
1548+ case 128:
1549+ dataRate = 7;
1550+ break;
1551+ case 256:
1552+ dataRate = 8;
1553+ break;
1554+ case 64:
1555+ default:
1556+ dataRate = 6;
1557+ break;
1558+ }
1559+ dataRate *= sym * 105;
1560+ dataRate /= 800;
1561+ if (dataRate <= 4115)
1562+ clk_div = 0x05;
1563+ else if (dataRate <= 4800)
1564+ clk_div = 0x04;
1565+ else if (dataRate <= 5760)
1566+ clk_div = 0x03;
1567+ else if (dataRate <= 7200)
1568+ clk_div = 0x02;
1569+ else if (dataRate <= 9600)
1570+ clk_div = 0x01;
1571+ else
1572+ clk_div = 0x00;
1573+ value = ReadReg(state, 0xC2);
1574+ value &= 0xc0;
1575+ value |= clk_div;
1576+ WriteReg(state, 0xC2, value);
1577+ return 0;
1578+}
1579+
1580+static int M88DC2000AutoTSClock_C(struct m88dc2800_state *state, u32 sym,
1581+ u16 qam)
1582+{
1583+ u32 dataRate;
1584+ u8 clk_div, value;
1585+ printk(KERN_INFO
1586+ "m88dc2800: M88DC2000AutoTSClock_C, symrate=%d qam=%d\n",
1587+ sym, qam);
1588+ switch (qam) {
1589+ case 16:
1590+ dataRate = 4;
1591+ break;
1592+ case 32:
1593+ dataRate = 5;
1594+ break;
1595+ case 128:
1596+ dataRate = 7;
1597+ break;
1598+ case 256:
1599+ dataRate = 8;
1600+ break;
1601+ case 64:
1602+ default:
1603+ dataRate = 6;
1604+ break;
1605+ }
1606+ dataRate *= sym * 105;
1607+ dataRate /= 800;
1608+ if (dataRate <= 4115)
1609+ clk_div = 0x3F;
1610+ else if (dataRate <= 4800)
1611+ clk_div = 0x36;
1612+ else if (dataRate <= 5760)
1613+ clk_div = 0x2D;
1614+ else if (dataRate <= 7200)
1615+ clk_div = 0x24;
1616+ else if (dataRate <= 9600)
1617+ clk_div = 0x1B;
1618+ else
1619+ clk_div = 0x12;
1620+ value = ReadReg(state, 0xC2);
1621+ value &= 0xc0;
1622+ value |= clk_div;
1623+ WriteReg(state, 0xC2, value);
1624+ return 0;
1625+}
1626+
1627+static int M88DC2000SetTxMode(struct m88dc2800_state *state, u8 inverted,
1628+ u8 j83)
1629+{
1630+ u8 value = 0;
1631+ if (inverted)
1632+ value |= 0x08; /* spectrum inverted */
1633+ if (j83)
1634+ value |= 0x01; /* J83C */
1635+ WriteReg(state, 0x83, value);
1636+ return 0;
1637+}
1638+
1639+static int M88DC2000SoftReset(struct m88dc2800_state *state)
1640+{
1641+ WriteReg(state, 0x80, 0x01);
1642+ WriteReg(state, 0x82, 0x00);
1643+ msleep(1);
1644+ WriteReg(state, 0x80, 0x00);
1645+ return 0;
1646+}
1647+
1648+static int M88DC2000SetSym(struct m88dc2800_state *state, u32 sym, u32 xtal)
1649+{
1650+ u8 value;
1651+ u8 reg6FH, reg12H;
1652+ u64 fValue;
1653+ u32 dwValue;
1654+
1655+ printk(KERN_INFO "%s, sym=%d, xtal=%d\n", __func__, sym, xtal);
1656+ fValue = 4294967296 * (sym + 10);
1657+ do_div(fValue, xtal);
1658+
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));
1666+
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)
1676+ value &= 0x7F;
1677+ else
1678+ value |= 0x80;
1679+ WriteReg(state, 0x5A, value);
1680+ value = ReadReg(state, 0x89);
1681+ if (sym <= 1800)
1682+ value |= 0x01;
1683+ else
1684+ value &= 0xFE;
1685+ WriteReg(state, 0x89, value);
1686+ if (sym >= 6700) {
1687+ reg6FH = 0x0D;
1688+ reg12H = 0x30;
1689+ } else if (sym >= 4000) {
1690+ fValue = 22 * 4096 / sym;
1691+ reg6FH = (u8) fValue;
1692+ reg12H = 0x30;
1693+ } else if (sym >= 2000) {
1694+ fValue = 14 * 4096 / sym;
1695+ reg6FH = (u8) fValue;
1696+ reg12H = 0x20;
1697+ } else {
1698+ fValue = 7 * 4096 / sym;
1699+ reg6FH = (u8) fValue;
1700+ reg12H = 0x10;
1701+ }
1702+ WriteReg(state, 0x6F, reg6FH);
1703+ WriteReg(state, 0x12, reg12H);
1704+ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1705+ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1706+ if (sym < 3000) {
1707+ WriteReg(state, 0x6C, 0x16);
1708+ WriteReg(state, 0x6D, 0x10);
1709+ WriteReg(state, 0x6E, 0x18);
1710+ } else {
1711+ WriteReg(state, 0x6C, 0x14);
1712+ WriteReg(state, 0x6D, 0x0E);
1713+ WriteReg(state, 0x6E, 0x36);
1714+ }
1715+ } else {
1716+ WriteReg(state, 0x6C, 0x16);
1717+ WriteReg(state, 0x6D, 0x10);
1718+ WriteReg(state, 0x6E, 0x18);
1719+ }
1720+ return 0;
1721+}
1722+
1723+static int M88DC2000SetQAM(struct m88dc2800_state *state, u16 qam)
1724+{
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);
1729+ regC2H &= 0xF8;
1730+ switch (qam) {
1731+ case 16: /* 16 QAM */
1732+ reg00H = 0x08;
1733+ reg4AH = 0x0F;
1734+ regC2H |= 0x02;
1735+ reg44H = 0xAA;
1736+ reg4CH = 0x0C;
1737+ reg4DH = 0xF7;
1738+ reg74H = 0x0E;
1739+ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1740+ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1741+ reg8BH = 0x5A;
1742+ reg8EH = 0xBD;
1743+ } else {
1744+ reg8BH = 0x5B;
1745+ reg8EH = 0x9D;
1746+ }
1747+ WriteReg(state, 0x6E, 0x18);
1748+ break;
1749+ case 32: /* 32 QAM */
1750+ reg00H = 0x18;
1751+ reg4AH = 0xFB;
1752+ regC2H |= 0x02;
1753+ reg44H = 0xAA;
1754+ reg4CH = 0x0C;
1755+ reg4DH = 0xF7;
1756+ reg74H = 0x0E;
1757+ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1758+ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1759+ reg8BH = 0x5A;
1760+ reg8EH = 0xBD;
1761+ } else {
1762+ reg8BH = 0x5B;
1763+ reg8EH = 0x9D;
1764+ }
1765+ WriteReg(state, 0x6E, 0x18);
1766+ break;
1767+ case 64: /* 64 QAM */
1768+ reg00H = 0x48;
1769+ reg4AH = 0xCD;
1770+ regC2H |= 0x02;
1771+ reg44H = 0xAA;
1772+ reg4CH = 0x0C;
1773+ reg4DH = 0xF7;
1774+ reg74H = 0x0E;
1775+ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1776+ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1777+ reg8BH = 0x5A;
1778+ reg8EH = 0xBD;
1779+ } else {
1780+ reg8BH = 0x5B;
1781+ reg8EH = 0x9D;
1782+ }
1783+ break;
1784+ case 128: /* 128 QAM */
1785+ reg00H = 0x28;
1786+ reg4AH = 0xFF;
1787+ regC2H |= 0x02;
1788+ reg44H = 0xA9;
1789+ reg4CH = 0x08;
1790+ reg4DH = 0xF5;
1791+ reg74H = 0x0E;
1792+ reg8BH = 0x5B;
1793+ reg8EH = 0x9D;
1794+ break;
1795+ case 256: /* 256 QAM */
1796+ reg00H = 0x38;
1797+ reg4AH = 0xCD;
1798+ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1799+ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1800+ regC2H |= 0x02;
1801+ } else {
1802+ regC2H |= 0x01;
1803+ }
1804+ reg44H = 0xA9;
1805+ reg4CH = 0x08;
1806+ reg4DH = 0xF5;
1807+ reg74H = 0x0E;
1808+ reg8BH = 0x5B;
1809+ reg8EH = 0x9D;
1810+ break;
1811+ default: /* 64 QAM */
1812+ reg00H = 0x48;
1813+ reg4AH = 0xCD;
1814+ regC2H |= 0x02;
1815+ reg44H = 0xAA;
1816+ reg4CH = 0x0C;
1817+ reg4DH = 0xF7;
1818+ reg74H = 0x0E;
1819+ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
1820+ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
1821+ reg8BH = 0x5A;
1822+ reg8EH = 0xBD;
1823+ } else {
1824+ reg8BH = 0x5B;
1825+ reg8EH = 0x9D;
1826+ }
1827+ break;
1828+ }
1829+ WriteReg(state, 0x00, reg00H);
1830+ value = ReadReg(state, 0x88);
1831+ value |= 0x08;
1832+ WriteReg(state, 0x88, value);
1833+ WriteReg(state, 0x4B, 0xFF);
1834+ WriteReg(state, 0x4A, reg4AH);
1835+ value &= 0xF7;
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);
1844+ return 0;
1845+}
1846+
1847+static int M88DC2000WriteTuner_TC2800(struct m88dc2800_state *state,
1848+ u32 freq_KHz)
1849+{
1850+ printk(KERN_INFO "%s, freq=%d KHz\n", __func__, freq_KHz);
1851+ return mt_fe_tn_set_freq_tc2800(state, freq_KHz);
1852+}
1853+
1854+static int m88dc2800_init(struct dvb_frontend *fe)
1855+{
1856+ dprintk("%s()\n", __func__);
1857+ return 0;
1858+}
1859+
1860+static int m88dc2800_set_parameters(struct dvb_frontend *fe)
1861+{
1862+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1863+ u8 is_annex_c, is_update;
1864+ u16 temp_qam;
1865+ s32 waiting_time;
1866+ struct m88dc2800_state *state = fe->demodulator_priv;
1867+
1868+ is_annex_c = c->delivery_system == SYS_DVBC_ANNEX_C ? 1 : 0;
1869+
1870+ switch (c->modulation) {
1871+ case QAM_16:
1872+ temp_qam = 16;
1873+ break;
1874+ case QAM_32:
1875+ temp_qam = 32;
1876+ break;
1877+ case QAM_128:
1878+ temp_qam = 128;
1879+ break;
1880+ case QAM_256:
1881+ temp_qam = 256;
1882+ break;
1883+ default: /* QAM_64 */
1884+ temp_qam = 64;
1885+ break;
1886+ }
1887+
1888+ state->inverted = c->inversion == INVERSION_ON ? 1 : 0;
1889+
1890+ printk(KERN_INFO
1891+ "m88dc2800: state, freq=%d qam=%d sym=%d inverted=%d xtal=%d\n",
1892+ state->freq, state->qam, state->sym, state->inverted,
1893+ state->xtal);
1894+ printk(KERN_INFO
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);
1897+
1898+ is_update = 0;
1899+ WriteReg(state, 0x80, 0x01);
1900+ if (c->frequency != state->freq) {
1901+ M88DC2000WriteTuner_TC2800(state, c->frequency / 1000);
1902+ state->freq = c->frequency;
1903+ }
1904+ if (c->symbol_rate != state->sym) {
1905+ M88DC2000SetSym(state, c->symbol_rate / 1000, state->xtal);
1906+ state->sym = c->symbol_rate;
1907+ is_update = 1;
1908+ }
1909+ if (temp_qam != state->qam) {
1910+ M88DC2000SetQAM(state, temp_qam);
1911+ state->qam = temp_qam;
1912+ is_update = 1;
1913+ }
1914+
1915+ if (is_update != 0) {
1916+ if (state->config->ts_mode == 3)
1917+ M88DC2000AutoTSClock_C(state, state->sym / 1000,
1918+ temp_qam);
1919+ else
1920+ M88DC2000AutoTSClock_P(state, state->sym / 1000,
1921+ temp_qam);
1922+ }
1923+
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;
1929+ else
1930+ waiting_time = 500;
1931+ while (waiting_time > 0) {
1932+ msleep(50);
1933+ waiting_time -= 50;
1934+ if (M88DC2000GetLock(state))
1935+ return 0;
1936+ }
1937+
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;
1944+ else
1945+ waiting_time = 500;
1946+ while (waiting_time > 0) {
1947+ msleep(50);
1948+ waiting_time -= 50;
1949+ if (M88DC2000GetLock(state))
1950+ return 0;
1951+ }
1952+ return 0;
1953+}
1954+
1955+static int m88dc2800_read_status(struct dvb_frontend *fe,
1956+ fe_status_t * status)
1957+{
1958+ struct m88dc2800_state *state = fe->demodulator_priv;
1959+ *status = 0;
1960+
1961+ if (M88DC2000GetLock(state)) {
1962+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER
1963+ |FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK;
1964+ }
1965+ return 0;
1966+}
1967+
1968+static int m88dc2800_read_ber(struct dvb_frontend *fe, u32 * ber)
1969+{
1970+ struct m88dc2800_state *state = fe->demodulator_priv;
1971+ u16 tmp;
1972+
1973+ if (M88DC2000GetLock(state) == 0) {
1974+ state->ber = 0;
1975+ } else if ((ReadReg(state, 0xA0) & 0x80) != 0x80) {
1976+ tmp = ReadReg(state, 0xA2) << 8;
1977+ tmp += ReadReg(state, 0xA1);
1978+ state->ber = tmp;
1979+ WriteReg(state, 0xA0, 0x05);
1980+ WriteReg(state, 0xA0, 0x85);
1981+ }
1982+ *ber = state->ber;
1983+ return 0;
1984+}
1985+
1986+static int m88dc2800_read_signal_strength(struct dvb_frontend *fe,
1987+ u16 * strength)
1988+{
1989+ struct m88dc2800_state *state = fe->demodulator_priv;
1990+ s16 tuner_strength;
1991+
1992+ tuner_strength = mt_fe_tn_get_signal_strength_tc2800(state);
1993+ *strength = tuner_strength < -107 ? 0 : tuner_strength + 107;
1994+
1995+ return 0;
1996+}
1997+
1998+static int m88dc2800_read_snr(struct dvb_frontend *fe, u16 * snr)
1999+{
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
2010+ };
2011+ struct m88dc2800_state *state = fe->demodulator_priv;
2012+ u8 i;
2013+ u32 _snr, mse;
2014+
2015+ if ((ReadReg(state, 0x91) & 0x23) != 0x03) {
2016+ *snr = 0;
2017+ return 0;
2018+ }
2019+ mse = 0;
2020+ for (i = 0; i < 30; i++) {
2021+ mse += (ReadReg(state, 0x08) << 8) + ReadReg(state, 0x07);
2022+ }
2023+ mse /= 30;
2024+ if (mse > 80)
2025+ mse = 80;
2026+ switch (state->qam) {
2027+ case 16:
2028+ _snr = 34080;
2029+ break; /* 16QAM */
2030+ case 32:
2031+ _snr = 37600;
2032+ break; /* 32QAM */
2033+ case 64:
2034+ _snr = 40310;
2035+ break; /* 64QAM */
2036+ case 128:
2037+ _snr = 43720;
2038+ break; /* 128QAM */
2039+ case 256:
2040+ _snr = 46390;
2041+ break; /* 256QAM */
2042+ default:
2043+ _snr = 40310;
2044+ break;
2045+ }
2046+ _snr -= mes_log[mse - 1]; /* C - 10*log10(MSE) */
2047+ _snr /= 1000;
2048+ if (_snr > 0xff)
2049+ _snr = 0xff;
2050+ *snr = _snr;
2051+ return 0;
2052+}
2053+
2054+static int m88dc2800_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
2055+{
2056+ struct m88dc2800_state *state = fe->demodulator_priv;
2057+ u8 u8Value;
2058+
2059+ u8Value = ReadReg(state, 0xdf);
2060+ u8Value |= 0x02; /* Hold */
2061+ WriteReg(state, 0xdf, u8Value);
2062+
2063+ *ucblocks = ReadReg(state, 0xd5);
2064+ *ucblocks = (*ucblocks << 8) | ReadReg(state, 0xd4);
2065+
2066+ u8Value &= 0xfe; /* Clear */
2067+ WriteReg(state, 0xdf, u8Value);
2068+ u8Value &= 0xfc; /* Update */
2069+ u8Value |= 0x01;
2070+ WriteReg(state, 0xdf, u8Value);
2071+
2072+ return 0;
2073+}
2074+
2075+static int m88dc2800_sleep(struct dvb_frontend *fe)
2076+{
2077+ struct m88dc2800_state *state = fe->demodulator_priv;
2078+
2079+ mt_fe_tn_sleep_tc2800(state);
2080+ state->freq = 0;
2081+
2082+ return 0;
2083+}
2084+
2085+static void m88dc2800_release(struct dvb_frontend *fe)
2086+{
2087+ struct m88dc2800_state *state = fe->demodulator_priv;
2088+ kfree(state);
2089+}
2090+
2091+static struct dvb_frontend_ops m88dc2800_ops;
2092+
2093+struct dvb_frontend *m88dc2800_attach(const struct m88dc2800_config
2094+ *config, struct i2c_adapter *i2c)
2095+{
2096+ struct m88dc2800_state *state = NULL;
2097+
2098+ /* allocate memory for the internal state */
2099+ state = kzalloc(sizeof(struct m88dc2800_state), GFP_KERNEL);
2100+ if (state == NULL)
2101+ goto error;
2102+
2103+ /* setup the state */
2104+ state->config = config;
2105+ state->i2c = i2c;
2106+ state->xtal = 28800;
2107+
2108+ WriteReg(state, 0x80, 0x01);
2109+ M88DC2000RegInitial_TC2800(state);
2110+ M88DC2000SetTsType(state, state->config->ts_mode);
2111+ mt_fe_tn_init_tc2800(state);
2112+
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;
2118+
2119+ error:
2120+ kfree(state);
2121+ return NULL;
2122+}
2123+
2124+EXPORT_SYMBOL(m88dc2800_attach);
2125+
2126+static struct dvb_frontend_ops m88dc2800_ops = {
2127+ .delsys = {SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C},
2128+ .info = {
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
2137+ },
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,
2147+};
2148+
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");
2153diff -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
2156@@ -0,0 +1,43 @@
2157+/*
2158+ M88DC2800/M88TC2800 - DVB-C demodulator and tuner from Montage
2159+
2160+ Copyright (C) 2012 Max Nibble <nibble.max@gmail.com>
2161+ Copyright (C) 2011 Montage Technology - www.montage-tech.com
2162+
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.
2167+
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.
2172+
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.
2176+*/
2177+
2178+#ifndef M88DC2800_H
2179+#define M88DC2800_H
2180+
2181+#include <linux/dvb/frontend.h>
2182+
2183+struct m88dc2800_config {
2184+ u8 demod_address;
2185+ u8 ts_mode;
2186+};
2187+
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);
2191+#else
2192+static inline struct dvb_frontend* m88dc2800_attach(const struct m88dc2800_config* config,
2193+ struct i2c_adapter* i2c)
2194+{
2195+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
2196+ return NULL;
2197+}
2198+#endif /* CONFIG_DVB_M88DC2800 */
2199+#endif /* M88DC2800_H */
2200diff -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
2203@@ -0,0 +1,1710 @@
2204+/*
2205+ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
2206+
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.
2210+
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.
2215+
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.
2220+
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.
2224+ */
2225+
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>
2232+
2233+#include "dvb_frontend.h"
2234+#include "m88ds3103.h"
2235+#include "m88ds3103_priv.h"
2236+
2237+static int debug;
2238+module_param(debug, int, 0644);
2239+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
2240+
2241+#define dprintk(args...) \
2242+ do { \
2243+ if (debug) \
2244+ printk(KERN_INFO "m88ds3103: " args); \
2245+ } while (0)
2246+
2247+/*demod register operations.*/
2248+static int m88ds3103_writereg(struct m88ds3103_state *state, int reg, int data)
2249+{
2250+ u8 buf[] = { reg, data };
2251+ struct i2c_msg msg = { .addr = state->config->demod_address,
2252+ .flags = 0, .buf = buf, .len = 2 };
2253+ int err;
2254+
2255+ if (debug > 1)
2256+ printk("m88ds3103: %s: write reg 0x%02x, value 0x%02x\n",
2257+ __func__, reg, data);
2258+
2259+ err = i2c_transfer(state->i2c, &msg, 1);
2260+ if (err != 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;
2264+ }
2265+ return 0;
2266+}
2267+
2268+static int m88ds3103_readreg(struct m88ds3103_state *state, u8 reg)
2269+{
2270+ int ret;
2271+ u8 b0[] = { reg };
2272+ u8 b1[] = { 0 };
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 }
2278+ };
2279+ ret = i2c_transfer(state->i2c, msg, 2);
2280+
2281+ if (ret != 2) {
2282+ printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
2283+ __func__, reg, ret);
2284+ return ret;
2285+ }
2286+
2287+ if (debug > 1)
2288+ printk(KERN_INFO "m88ds3103: read reg 0x%02x, value 0x%02x\n",
2289+ reg, b1[0]);
2290+
2291+ return b1[0];
2292+}
2293+
2294+/*tuner register operations.*/
2295+static int m88ds3103_tuner_writereg(struct m88ds3103_state *state, int reg, int data)
2296+{
2297+ u8 buf[] = { reg, data };
2298+ struct i2c_msg msg = { .addr = 0x60,
2299+ .flags = 0, .buf = buf, .len = 2 };
2300+ int err;
2301+
2302+ m88ds3103_writereg(state, 0x03, 0x11);
2303+ err = i2c_transfer(state->i2c, &msg, 1);
2304+
2305+ if (err != 1) {
2306+ printk("%s: writereg error(err == %i, reg == 0x%02x,"
2307+ " value == 0x%02x)\n", __func__, err, reg, data);
2308+ return -EREMOTEIO;
2309+ }
2310+
2311+ return 0;
2312+}
2313+
2314+static int m88ds3103_tuner_readreg(struct m88ds3103_state *state, u8 reg)
2315+{
2316+ int ret;
2317+ u8 b0[] = { reg };
2318+ u8 b1[] = { 0 };
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 }
2324+ };
2325+
2326+ m88ds3103_writereg(state, 0x03, 0x11);
2327+ ret = i2c_transfer(state->i2c, msg, 2);
2328+
2329+ if (ret != 2) {
2330+ printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
2331+ return ret;
2332+ }
2333+
2334+ return b1[0];
2335+}
2336+
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)
2340+{
2341+ int ret = -EREMOTEIO;
2342+ struct i2c_msg msg;
2343+ u8 *buf;
2344+
2345+ buf = kmalloc(len + 1, GFP_KERNEL);
2346+ if (buf == NULL) {
2347+ printk("Unable to kmalloc\n");
2348+ ret = -ENOMEM;
2349+ goto error;
2350+ }
2351+
2352+ *(buf) = reg;
2353+ memcpy(buf + 1, data, len);
2354+
2355+ msg.addr = state->config->demod_address;
2356+ msg.flags = 0;
2357+ msg.buf = buf;
2358+ msg.len = len + 1;
2359+
2360+ if (debug > 1)
2361+ printk(KERN_INFO "m88ds3103: %s: write regN 0x%02x, len = %d\n",
2362+ __func__, reg, len);
2363+
2364+ ret = i2c_transfer(state->i2c, &msg, 1);
2365+ if (ret != 1) {
2366+ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
2367+ __func__, ret, reg);
2368+ ret = -EREMOTEIO;
2369+ }
2370+
2371+error:
2372+ kfree(buf);
2373+
2374+ return ret;
2375+}
2376+
2377+static int m88ds3103_load_firmware(struct dvb_frontend *fe)
2378+{
2379+ struct m88ds3103_state *state = fe->demodulator_priv;
2380+ const struct firmware *fw;
2381+ int i, ret = 0;
2382+
2383+ dprintk("%s()\n", __func__);
2384+
2385+ if (state->skip_fw_load)
2386+ return 0;
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);
2399+ }
2400+
2401+ printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
2402+ if (ret) {
2403+ printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
2404+ "found?)\n", __func__);
2405+ return ret;
2406+ }
2407+
2408+ /* Make sure we don't recurse back through here during loading */
2409+ state->skip_fw_load = 1;
2410+
2411+ dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
2412+ fw->size,
2413+ fw->data[0],
2414+ fw->data[1],
2415+ fw->data[fw->size - 2],
2416+ fw->data[fw->size - 1]);
2417+
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;
2424+ }
2425+ /* start internal mcu. */
2426+ if(ret == 1)
2427+ m88ds3103_writereg(state, 0xb2, 0x00);
2428+
2429+ release_firmware(fw);
2430+
2431+ dprintk("%s: Firmware upload %s\n", __func__,
2432+ ret == 1 ? "complete" : "failed");
2433+
2434+ if(ret == 1) ret = 0;
2435+
2436+ /* Ensure firmware is always loaded if required */
2437+ state->skip_fw_load = 0;
2438+
2439+ return ret;
2440+}
2441+
2442+
2443+static int m88ds3103_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
2444+{
2445+ struct m88ds3103_state *state = fe->demodulator_priv;
2446+ u8 data;
2447+
2448+ dprintk("%s(%d)\n", __func__, voltage);
2449+
2450+ dprintk("m88ds3103:pin_ctrl = (%02x)\n", state->config->pin_ctrl);
2451+
2452+ if(state->config->set_voltage)
2453+ state->config->set_voltage(fe, voltage);
2454+
2455+ data = m88ds3103_readreg(state, 0xa2);
2456+
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)
2460+ data |= 0x02;
2461+
2462+ switch (voltage) {
2463+ case SEC_VOLTAGE_18:
2464+ if((state->config->pin_ctrl & 0x01) == 0)
2465+ data |= 0x01;
2466+ break;
2467+ case SEC_VOLTAGE_13:
2468+ if(state->config->pin_ctrl & 0x01)
2469+ data |= 0x01;
2470+ break;
2471+ case SEC_VOLTAGE_OFF:
2472+ if(state->config->pin_ctrl & 0x02)
2473+ data &= ~0x02;
2474+ else
2475+ data |= 0x02;
2476+ break;
2477+ }
2478+ }
2479+
2480+ m88ds3103_writereg(state, 0xa2, data);
2481+
2482+ return 0;
2483+}
2484+
2485+static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t* status)
2486+{
2487+ struct m88ds3103_state *state = fe->demodulator_priv;
2488+ int lock = 0;
2489+
2490+ *status = 0;
2491+
2492+ switch (state->delivery_system){
2493+ case SYS_DVBS:
2494+ lock = m88ds3103_readreg(state, 0xd1);
2495+ dprintk("%s: SYS_DVBS status=%x.\n", __func__, lock);
2496+
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;
2501+
2502+ }
2503+ break;
2504+ case SYS_DVBS2:
2505+ lock = m88ds3103_readreg(state, 0x0d);
2506+ dprintk("%s: SYS_DVBS2 status=%x.\n", __func__, lock);
2507+
2508+ if ((lock & 0x8f) == 0x8f)
2509+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER
2510+ | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
2511+
2512+ break;
2513+ default:
2514+ break;
2515+ }
2516+
2517+ return 0;
2518+}
2519+
2520+static int m88ds3103_read_ber(struct dvb_frontend *fe, u32* ber)
2521+{
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;
2525+
2526+ dprintk("%s()\n", __func__);
2527+
2528+ switch (state->delivery_system) {
2529+ case SYS_DVBS:
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);
2535+ tmp3 |= 0x10;
2536+ m88ds3103_writereg(state, 0xf8, tmp3);
2537+ state->preBer = (tmp1<<8) | tmp2;
2538+ }
2539+ break;
2540+ case SYS_DVBS2:
2541+ tmp1 = m88ds3103_readreg(state, 0x7e) & 0x0f;
2542+ switch(tmp1){
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;
2554+ }
2555+
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;
2560+
2561+ tmp1 = m88ds3103_readreg(state, 0xf8) & 0xff;
2562+ tmp2 = m88ds3103_readreg(state, 0xf7) & 0xff;
2563+ pre_err_packags = tmp1<<8 | tmp2;
2564+
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;
2571+ }
2572+ break;
2573+ default:
2574+ break;
2575+ }
2576+ *ber = state->preBer;
2577+
2578+ return 0;
2579+}
2580+
2581+static int m88ds3103_read_signal_strength(struct dvb_frontend *fe,
2582+ u16 *signal_strength)
2583+{
2584+ struct m88ds3103_state *state = fe->demodulator_priv;
2585+ u16 gain;
2586+ u8 gain1, gain2, gain3 = 0;
2587+
2588+ dprintk("%s()\n", __func__);
2589+
2590+ gain1 = m88ds3103_tuner_readreg(state, 0x3d) & 0x1f;
2591+ dprintk("%s: gain1 = 0x%02x \n", __func__, gain1);
2592+
2593+ if (gain1 > 15) gain1 = 15;
2594+ gain2 = m88ds3103_tuner_readreg(state, 0x21) & 0x1f;
2595+ dprintk("%s: gain2 = 0x%02x \n", __func__, gain2);
2596+
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);
2600+
2601+ if (gain2 > 16) gain2 = 16;
2602+ if (gain2 < 2) gain2 = 2;
2603+ if (gain3 > 6) gain3 = 6;
2604+ }else{
2605+ if (gain2 > 13) gain2 = 13;
2606+ gain3 = 0;
2607+ }
2608+
2609+ gain = gain1*23 + gain2*35 + gain3*29;
2610+ *signal_strength = 60000 - gain*55;
2611+
2612+ return 0;
2613+}
2614+
2615+
2616+static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *p_snr)
2617+{
2618+ struct m88ds3103_state *state = fe->demodulator_priv;
2619+ u8 val, npow1, npow2, spow1, cnt;
2620+ u16 tmp, snr;
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
2631+ };
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,
2636+ 34340, 34657,
2637+ };
2638+
2639+ dprintk("%s()\n", __func__);
2640+
2641+ snr = 0;
2642+
2643+ switch (state->delivery_system){
2644+ case SYS_DVBS:
2645+ cnt = 10; snr_total = 0;
2646+ while(cnt > 0){
2647+ val = m88ds3103_readreg(state, 0xff);
2648+ snr_total += val;
2649+ cnt--;
2650+ }
2651+ tmp = (u16)(snr_total/80);
2652+ if(tmp > 0){
2653+ if (tmp > 32) tmp = 32;
2654+ snr = (mes_loge[tmp - 1] * 100) / 45;
2655+ }else{
2656+ snr = 0;
2657+ }
2658+ break;
2659+ case SYS_DVBS2:
2660+ cnt = 10; npow = 0; spow = 0;
2661+ while(cnt >0){
2662+ npow1 = m88ds3103_readreg(state, 0x8c) & 0xff;
2663+ npow2 = m88ds3103_readreg(state, 0x8d) & 0xff;
2664+ npow += (((npow1 & 0x3f) + (u16)(npow2 << 6)) >> 2);
2665+
2666+ spow1 = m88ds3103_readreg(state, 0x8e) & 0xff;
2667+ spow += ((spow1 * spow1) >> 1);
2668+ cnt--;
2669+ }
2670+ npow /= 10; spow /= 10;
2671+ if(spow == 0){
2672+ snr = 0;
2673+ }else if(npow == 0){
2674+ snr = 19;
2675+ }else{
2676+ if(spow > npow){
2677+ tmp = (u16)(spow / npow);
2678+ if (tmp > 80) tmp = 80;
2679+ snr = mes_log10[tmp - 1]*3;
2680+ }else{
2681+ tmp = (u16)(npow / spow);
2682+ if (tmp > 80) tmp = 80;
2683+ snr = -(mes_log10[tmp - 1] / 1000);
2684+ }
2685+ }
2686+ break;
2687+ default:
2688+ break;
2689+ }
2690+ *p_snr = snr;
2691+
2692+ return 0;
2693+}
2694+
2695+
2696+static int m88ds3103_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
2697+{
2698+ struct m88ds3103_state *state = fe->demodulator_priv;
2699+ u8 tmp1, tmp2, tmp3, data;
2700+
2701+ dprintk("%s()\n", __func__);
2702+
2703+ switch (state->delivery_system) {
2704+ case SYS_DVBS:
2705+ data = m88ds3103_readreg(state, 0xf8);
2706+ data |= 0x40;
2707+ m88ds3103_writereg(state, 0xf8, data);
2708+ tmp1 = m88ds3103_readreg(state, 0xf5);
2709+ tmp2 = m88ds3103_readreg(state, 0xf4);
2710+ *ucblocks = (tmp1 <<8) | tmp2;
2711+ data &= ~0x20;
2712+ m88ds3103_writereg(state, 0xf8, data);
2713+ data |= 0x20;
2714+ m88ds3103_writereg(state, 0xf8, data);
2715+ data &= ~0x40;
2716+ m88ds3103_writereg(state, 0xf8, data);
2717+ break;
2718+ case SYS_DVBS2:
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);
2724+ data |= 0x01;
2725+ m88ds3103_writereg(state, 0xd1, data);
2726+ data &= ~0x01;
2727+ m88ds3103_writereg(state, 0xd1, data);
2728+ break;
2729+ default:
2730+ break;
2731+ }
2732+ return 0;
2733+}
2734+
2735+static int m88ds3103_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
2736+{
2737+ struct m88ds3103_state *state = fe->demodulator_priv;
2738+ u8 data_a1, data_a2;
2739+
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);
2743+ return -EINVAL;
2744+ }
2745+
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 */
2750+ switch (tone) {
2751+ case SEC_TONE_ON:
2752+ dprintk("%s: SEC_TONE_ON\n", __func__);
2753+ data_a1 |= 0x04;
2754+ data_a1 &= ~0x03;
2755+ data_a1 &= ~0x40;
2756+ data_a2 &= ~0xc0;
2757+ break;
2758+ case SEC_TONE_OFF:
2759+ dprintk("%s: SEC_TONE_OFF\n", __func__);
2760+ data_a2 &= ~0xc0;
2761+ data_a2 |= 0x80;
2762+ break;
2763+ }
2764+ m88ds3103_writereg(state, 0xa2, data_a2);
2765+ m88ds3103_writereg(state, 0xa1, data_a1);
2766+ return 0;
2767+}
2768+
2769+static int m88ds3103_send_diseqc_msg(struct dvb_frontend *fe,
2770+ struct dvb_diseqc_master_cmd *d)
2771+{
2772+ struct m88ds3103_state *state = fe->demodulator_priv;
2773+ int i, ret = 0;
2774+ u8 tmp, time_out;
2775+
2776+ /* Dump DiSEqC message */
2777+ if (debug) {
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 ", ");
2783+ }
2784+ }
2785+
2786+ tmp = m88ds3103_readreg(state, 0xa2);
2787+ tmp &= ~0xc0;
2788+ if(state->demod_id == DS3103_ID)
2789+ tmp &= ~0x20;
2790+ m88ds3103_writereg(state, 0xa2, tmp);
2791+
2792+ for (i = 0; i < d->msg_len; i ++)
2793+ m88ds3103_writereg(state, (0xa3+i), d->msg[i]);
2794+
2795+ tmp = m88ds3103_readreg(state, 0xa1);
2796+ tmp &= ~0x38;
2797+ tmp &= ~0x40;
2798+ tmp |= ((d->msg_len-1) << 3) | 0x07;
2799+ tmp &= ~0x80;
2800+ m88ds3103_writereg(state, 0xa1, tmp);
2801+ /* 1.5 * 9 * 8 = 108ms */
2802+ time_out = 150;
2803+ while (time_out > 0){
2804+ msleep(10);
2805+ time_out -= 10;
2806+ tmp = m88ds3103_readreg(state, 0xa1);
2807+ if ((tmp & 0x40) == 0)
2808+ break;
2809+ }
2810+ if (time_out == 0){
2811+ tmp = m88ds3103_readreg(state, 0xa1);
2812+ tmp &= ~0x80;
2813+ tmp |= 0x40;
2814+ m88ds3103_writereg(state, 0xa1, tmp);
2815+ ret = 1;
2816+ }
2817+ tmp = m88ds3103_readreg(state, 0xa2);
2818+ tmp &= ~0xc0;
2819+ tmp |= 0x80;
2820+ m88ds3103_writereg(state, 0xa2, tmp);
2821+ return ret;
2822+}
2823+
2824+
2825+static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
2826+ fe_sec_mini_cmd_t burst)
2827+{
2828+ struct m88ds3103_state *state = fe->demodulator_priv;
2829+ u8 val, time_out;
2830+
2831+ dprintk("%s()\n", __func__);
2832+
2833+ val = m88ds3103_readreg(state, 0xa2);
2834+ val &= ~0xc0;
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);
2841+ else
2842+ m88ds3103_writereg(state, 0xa1, 0x02);
2843+
2844+ msleep(13);
2845+
2846+ time_out = 5;
2847+ do{
2848+ val = m88ds3103_readreg(state, 0xa1);
2849+ if ((val & 0x40) == 0)
2850+ break;
2851+ msleep(1);
2852+ time_out --;
2853+ } while (time_out > 0);
2854+
2855+ val = m88ds3103_readreg(state, 0xa2);
2856+ val &= ~0xc0;
2857+ val |= 0x80;
2858+ m88ds3103_writereg(state, 0xa2, val);
2859+
2860+ return 0;
2861+}
2862+
2863+static void m88ds3103_release(struct dvb_frontend *fe)
2864+{
2865+ struct m88ds3103_state *state = fe->demodulator_priv;
2866+
2867+ dprintk("%s\n", __func__);
2868+ kfree(state);
2869+}
2870+
2871+static int m88ds3103_check_id(struct m88ds3103_state *state)
2872+{
2873+ int val_00, val_01;
2874+
2875+ /*check demod id*/
2876+ val_01 = m88ds3103_readreg(state, 0x01);
2877+ printk(KERN_INFO "DS3000 chip version: %x attached.\n", val_01);
2878+
2879+ if(val_01 == 0xD0)
2880+ state->demod_id = DS3103_ID;
2881+ else if(val_01 == 0xC0)
2882+ state->demod_id = DS3000_ID;
2883+ else
2884+ state->demod_id = UNKNOW_ID;
2885+
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);
2889+ val_00 &= 0x03;
2890+ if(val_00 == 0)
2891+ {
2892+ m88ds3103_tuner_writereg(state, 0x00, 0x01);
2893+ msleep(3);
2894+ }
2895+ m88ds3103_tuner_writereg(state, 0x00, 0x03);
2896+ msleep(5);
2897+
2898+ val_00 = m88ds3103_tuner_readreg(state, 0x00);
2899+ printk(KERN_INFO "TS202x chip version[2]: %x attached.\n", val_00);
2900+ val_00 &= 0xff;
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;
2905+ else
2906+ state->tuner_id = UNKNOW_ID;
2907+
2908+ return state->demod_id;
2909+}
2910+
2911+static struct dvb_frontend_ops m88ds3103_ops;
2912+static int m88ds3103_initilaze(struct dvb_frontend *fe);
2913+
2914+struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *config,
2915+ struct i2c_adapter *i2c)
2916+{
2917+ struct m88ds3103_state *state = NULL;
2918+
2919+ dprintk("%s\n", __func__);
2920+
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");
2925+ goto error2;
2926+ }
2927+
2928+ state->config = config;
2929+ state->i2c = i2c;
2930+ state->preBer = 0xffff;
2931+ state->delivery_system = SYS_DVBS; /*Default to DVB-S.*/
2932+
2933+ /* check demod id */
2934+ if(m88ds3103_check_id(state) == UNKNOW_ID){
2935+ printk(KERN_ERR "Unable to find Montage chip\n");
2936+ goto error3;
2937+ }
2938+
2939+ memcpy(&state->frontend.ops, &m88ds3103_ops,
2940+ sizeof(struct dvb_frontend_ops));
2941+ state->frontend.demodulator_priv = state;
2942+
2943+ m88ds3103_initilaze(&state->frontend);
2944+
2945+ return &state->frontend;
2946+
2947+error3:
2948+ kfree(state);
2949+error2:
2950+ return NULL;
2951+}
2952+EXPORT_SYMBOL(m88ds3103_attach);
2953+
2954+static int m88ds3103_set_carrier_offset(struct dvb_frontend *fe,
2955+ s32 carrier_offset_khz)
2956+{
2957+ struct m88ds3103_state *state = fe->demodulator_priv;
2958+ s32 tmp;
2959+
2960+ tmp = carrier_offset_khz;
2961+ tmp *= 65536;
2962+
2963+ tmp = (2*tmp + MT_FE_MCLK_KHZ) / (2*MT_FE_MCLK_KHZ);
2964+
2965+ if (tmp < 0)
2966+ tmp += 65536;
2967+
2968+ m88ds3103_writereg(state, 0x5f, tmp >> 8);
2969+ m88ds3103_writereg(state, 0x5e, tmp & 0xff);
2970+
2971+ return 0;
2972+}
2973+
2974+static int m88ds3103_set_symrate(struct dvb_frontend *fe)
2975+{
2976+ struct m88ds3103_state *state = fe->demodulator_priv;
2977+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
2978+ u16 value;
2979+
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);
2983+
2984+ return 0;
2985+}
2986+
2987+static int m88ds3103_set_CCI(struct dvb_frontend *fe)
2988+{
2989+ struct m88ds3103_state *state = fe->demodulator_priv;
2990+ u8 tmp;
2991+
2992+ tmp = m88ds3103_readreg(state, 0x56);
2993+ tmp &= ~0x01;
2994+ m88ds3103_writereg(state, 0x56, tmp);
2995+
2996+ tmp = m88ds3103_readreg(state, 0x76);
2997+ tmp &= ~0x80;
2998+ m88ds3103_writereg(state, 0x76, tmp);
2999+
3000+ return 0;
3001+}
3002+
3003+static int m88ds3103_init_reg(struct m88ds3103_state *state, const u8 *p_reg_tab, u32 size)
3004+{
3005+ u32 i;
3006+
3007+ for(i = 0; i < size; i+=2)
3008+ m88ds3103_writereg(state, p_reg_tab[i], p_reg_tab[i+1]);
3009+
3010+ return 0;
3011+}
3012+
3013+static int m88ds3103_get_locked_sym_rate(struct m88ds3103_state *state, u32 *sym_rate_KSs)
3014+{
3015+ u16 tmp;
3016+ u32 sym_rate_tmp;
3017+ u8 val_0x6d, val_0x6e;
3018+
3019+ val_0x6d = m88ds3103_readreg(state, 0x6d);
3020+ val_0x6e = m88ds3103_readreg(state, 0x6e);
3021+
3022+ tmp = (u16)((val_0x6e<<8) | val_0x6d);
3023+
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;
3027+
3028+ return 0;
3029+}
3030+
3031+static int m88ds3103_get_channel_info(struct m88ds3103_state *state, u8 *p_mode, u8 *p_coderate)
3032+{
3033+ u8 tmp, val_0x7E;
3034+
3035+ if(state->delivery_system == SYS_DVBS2){
3036+ val_0x7E = m88ds3103_readreg(state, 0x7e);
3037+ tmp = (u8)((val_0x7E&0xC0) >> 6);
3038+ *p_mode = tmp;
3039+ tmp = (u8)(val_0x7E & 0x0f);
3040+ *p_coderate = tmp;
3041+ } else {
3042+ *p_mode = 0;
3043+ tmp = m88ds3103_readreg(state, 0xe6);
3044+ tmp = (u8)(tmp >> 5);
3045+ *p_coderate = tmp;
3046+ }
3047+
3048+ return 0;
3049+}
3050+
3051+static int m88ds3103_set_clock_ratio(struct m88ds3103_state *state)
3052+{
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;
3057+
3058+ locked_sym_rate_KSs = 0;
3059+ m88ds3103_get_locked_sym_rate(state, &locked_sym_rate_KSs);
3060+ if(locked_sym_rate_KSs == 0)
3061+ return 0;
3062+
3063+ m88ds3103_get_channel_info(state, &mod_mode, &code_rate);
3064+
3065+ if (state->delivery_system == SYS_DVBS2)
3066+ {
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;
3072+ }
3073+
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;
3087+ }
3088+
3089+ if(state->demod_id == DS3000_ID)
3090+ input_datarate = input_datarate * 115 / 100;
3091+
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
3113+
3114+ if(state->demod_id == DS3000_ID) {
3115+ val = (u8)((tmp1<<4) + tmp2);
3116+ m88ds3103_writereg(state, 0xfe, val);
3117+ } else {
3118+ tmp1 = m88ds3103_readreg(state, 0x22);
3119+ tmp2 = m88ds3103_readreg(state, 0x24);
3120+
3121+ tmp1 >>= 6;
3122+ tmp1 &= 0x03;
3123+ tmp2 >>= 6;
3124+ tmp2 &= 0x03;
3125+
3126+ if((tmp1 == 0x00) && (tmp2 == 0x01))
3127+ MClk_KHz = 144000;
3128+ else if((tmp1 == 0x00) && (tmp2 == 0x03))
3129+ MClk_KHz = 72000;
3130+ else if((tmp1 == 0x01) && (tmp2 == 0x01))
3131+ MClk_KHz = 115200;
3132+ else if((tmp1 == 0x02) && (tmp2 == 0x01))
3133+ MClk_KHz = 96000;
3134+ else if((tmp1 == 0x03) && (tmp2 == 0x00))
3135+ MClk_KHz = 192000;
3136+ else
3137+ return 0;
3138+
3139+ if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/
3140+ input_datarate = 5200;
3141+
3142+ if(input_datarate != 0)
3143+ divid_ratio = (u8)(MClk_KHz / input_datarate);
3144+ else
3145+ divid_ratio = 0xFF;
3146+
3147+ if(divid_ratio > 128)
3148+ divid_ratio = 128;
3149+
3150+ if(divid_ratio < 2)
3151+ divid_ratio = 2;
3152+
3153+ tmp1 = (u8)(divid_ratio / 2);
3154+ tmp2 = (u8)(divid_ratio / 2);
3155+
3156+ if((divid_ratio % 2) != 0)
3157+ tmp2 += 1;
3158+
3159+ tmp1 -= 1;
3160+ tmp2 -= 1;
3161+
3162+ tmp1 &= 0x3f;
3163+ tmp2 &= 0x3f;
3164+
3165+ val = m88ds3103_readreg(state, 0xfe);
3166+ val &= 0xF0;
3167+ val |= (tmp2 >> 2) & 0x0f;
3168+ m88ds3103_writereg(state, 0xfe, val);
3169+
3170+ val = (u8)((tmp2 & 0x03) << 6);
3171+ val |= tmp1;
3172+ m88ds3103_writereg(state, 0xea, val);
3173+ }
3174+ } else {
3175+ mod_fac = 2;
3176+
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;
3184+ }
3185+
3186+ if(state->demod_id == DS3000_ID)
3187+ input_datarate = input_datarate * 115 / 100;
3188+
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
3200+
3201+ if(state->demod_id == DS3000_ID) {
3202+ val = m88ds3103_readreg(state, 0xfe);
3203+ val &= 0xc0;
3204+ val |= ((u8)((tmp1<<3) + tmp2));
3205+ m88ds3103_writereg(state, 0xfe, val);
3206+ } else {
3207+ if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/
3208+ input_datarate = 5200;
3209+
3210+ if(input_datarate != 0)
3211+ divid_ratio = (u8)(MClk_KHz / input_datarate);
3212+ else
3213+ divid_ratio = 0xFF;
3214+
3215+ if(divid_ratio > 128)
3216+ divid_ratio = 128;
3217+
3218+ if(divid_ratio < 2)
3219+ divid_ratio = 2;
3220+
3221+ tmp1 = (u8)(divid_ratio / 2);
3222+ tmp2 = (u8)(divid_ratio / 2);
3223+
3224+ if((divid_ratio % 2) != 0)
3225+ tmp2 += 1;
3226+
3227+ tmp1 -= 1;
3228+ tmp2 -= 1;
3229+
3230+ tmp1 &= 0x3f;
3231+ tmp2 &= 0x3f;
3232+
3233+ val = m88ds3103_readreg(state, 0xfe);
3234+ val &= 0xF0;
3235+ val |= (tmp2 >> 2) & 0x0f;
3236+ m88ds3103_writereg(state, 0xfe, val);
3237+
3238+ val = (u8)((tmp2 & 0x03) << 6);
3239+ val |= tmp1;
3240+ m88ds3103_writereg(state, 0xea, val);
3241+ }
3242+ }
3243+ return 0;
3244+}
3245+
3246+static int m88ds3103_demod_connect(struct dvb_frontend *fe, s32 carrier_offset_khz)
3247+{
3248+ struct m88ds3103_state *state = fe->demodulator_priv;
3249+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
3250+ u16 value;
3251+ u8 val1,val2,data;
3252+
3253+ dprintk("connect delivery system = %d\n", state->delivery_system);
3254+
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);
3262+
3263+ switch (state->delivery_system) {
3264+ case SYS_DVBS:
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));
3268+
3269+ value = m88ds3103_readreg(state, 0xfe);
3270+ value &= 0xc0;
3271+ value |= 0x1b;
3272+ m88ds3103_writereg(state, 0xfe, value);
3273+
3274+ if(state->config->ci_mode)
3275+ val1 = 0x80;
3276+ else if(state->config->ts_mode)
3277+ val1 = 0x60;
3278+ else
3279+ val1 = 0x20;
3280+ m88ds3103_writereg(state, 0xfd, val1);
3281+
3282+ }else if(state->demod_id == DS3103_ID){
3283+ m88ds3103_init_reg(state, ds3103_dvbs_init_tab, sizeof(ds3103_dvbs_init_tab));
3284+
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;
3290+ }else{
3291+ val1 = 0; val2 = 0;
3292+ }
3293+ val1 -= 1; val2 -= 1;
3294+ val1 &= 0x3f; val2 &= 0x3f;
3295+ data = m88ds3103_readreg(state, 0xfe);
3296+ data &= 0xf0;
3297+ data |= (val2 >> 2) & 0x0f;
3298+ m88ds3103_writereg(state, 0xfe, data);
3299+ data = (val2 & 0x03) << 6;
3300+ data |= val1;
3301+ m88ds3103_writereg(state, 0xea, data);
3302+
3303+ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
3304+ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
3305+
3306+ /* set master clock */
3307+ val1 = m88ds3103_readreg(state, 0x22);
3308+ val2 = m88ds3103_readreg(state, 0x24);
3309+
3310+ val1 &= 0x3f;
3311+ val2 &= 0x3f;
3312+ val1 |= 0x80;
3313+ val2 |= 0x40;
3314+
3315+ m88ds3103_writereg(state, 0x22, val1);
3316+ m88ds3103_writereg(state, 0x24, val2);
3317+
3318+ if(state->config->ci_mode)
3319+ val1 = 0x03;
3320+ else if(state->config->ts_mode)
3321+ val1 = 0x06;
3322+ else
3323+ val1 = 0x42;
3324+ m88ds3103_writereg(state, 0xfd, val1);
3325+ }
3326+ break;
3327+ case SYS_DVBS2:
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));
3331+
3332+ if (c->symbol_rate >= 30000000)
3333+ m88ds3103_writereg(state, 0xfe, 0x54);
3334+ else
3335+ m88ds3103_writereg(state, 0xfe, 0x98);
3336+
3337+ }else if(state->demod_id == DS3103_ID){
3338+ m88ds3103_init_reg(state, ds3103_dvbs2_init_tab, sizeof(ds3103_dvbs2_init_tab));
3339+
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;
3345+ }else{
3346+ val1 = 0; val2 = 0;
3347+ }
3348+ val1 -= 1; val2 -= 1;
3349+ val1 &= 0x3f; val2 &= 0x3f;
3350+ data = m88ds3103_readreg(state, 0xfe);
3351+ data &= 0xf0;
3352+ data |= (val2 >> 2) & 0x0f;
3353+ m88ds3103_writereg(state, 0xfe, data);
3354+ data = (val2 & 0x03) << 6;
3355+ data |= val1;
3356+ m88ds3103_writereg(state, 0xea, data);
3357+
3358+ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
3359+ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
3360+
3361+ /* set master clock */
3362+ val1 = m88ds3103_readreg(state, 0x22);
3363+ val2 = m88ds3103_readreg(state, 0x24);
3364+
3365+ val1 &= 0x3f;
3366+ val2 &= 0x3f;
3367+ if((state->config->ci_mode == 2) || (state->config->ts_mode == 1)){
3368+ val1 |= 0x80;
3369+ val2 |= 0x40;
3370+ }else{
3371+ if (c->symbol_rate >= 28000000){
3372+ val1 |= 0xc0;
3373+ }else if (c->symbol_rate >= 18000000){
3374+ val2 |= 0x40;
3375+ }else{
3376+ val1 |= 0x80;
3377+ val2 |= 0x40;
3378+ }
3379+ }
3380+ m88ds3103_writereg(state, 0x22, val1);
3381+ m88ds3103_writereg(state, 0x24, val2);
3382+ }
3383+
3384+ if(state->config->ci_mode)
3385+ val1 = 0x03;
3386+ else if(state->config->ts_mode)
3387+ val1 = 0x06;
3388+ else
3389+ val1 = 0x42;
3390+ m88ds3103_writereg(state, 0xfd, val1);
3391+
3392+ break;
3393+ default:
3394+ return 1;
3395+ }
3396+ /* disable 27MHz clock output */
3397+ m88ds3103_writereg(state, 0x29, 0x80);
3398+ /* enable ac coupling */
3399+ m88ds3103_writereg(state, 0x25, 0x8a);
3400+
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);
3411+ }else{
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);
3416+ }
3417+
3418+ m88ds3103_set_symrate(fe);
3419+
3420+ m88ds3103_set_CCI(fe);
3421+
3422+ m88ds3103_set_carrier_offset(fe, carrier_offset_khz);
3423+
3424+ /* ds3000 out of software reset */
3425+ m88ds3103_writereg(state, 0x00, 0x00);
3426+ /* start ds3000 build-in uC */
3427+ m88ds3103_writereg(state, 0xb2, 0x00);
3428+
3429+ return 0;
3430+}
3431+
3432+static int m88ds3103_set_frontend(struct dvb_frontend *fe)
3433+{
3434+ struct m88ds3103_state *state = fe->demodulator_priv;
3435+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
3436+
3437+ int i;
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;
3443+ u8 RFgain;
3444+
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);
3449+
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;
3455+ }
3456+
3457+ if (state->config->set_ts_params)
3458+ state->config->set_ts_params(fe, 0);
3459+
3460+ div4 = 0;
3461+ RFgain = 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);
3467+ div4 = 1;
3468+ ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ;
3469+ }else {
3470+ ndiv = (realFreq * (6 + 8) * 2)/MT_FE_CRYSTAL_KHZ;
3471+ }
3472+ ndiv = ndiv + ndiv%2;
3473+ if(ndiv < 4095)
3474+ ndiv = ndiv - 1024;
3475+ else if (ndiv < 6143)
3476+ ndiv = ndiv + 1024;
3477+ else
3478+ ndiv = ndiv + 3072;
3479+
3480+ m88ds3103_tuner_writereg(state, 0x01, (ndiv & 0x3f00) >> 8);
3481+ }else{
3482+ m88ds3103_tuner_writereg(state, 0x10, 0x00);
3483+ if (realFreq < 1146000){
3484+ m88ds3103_tuner_writereg(state, 0x10, 0x11);
3485+ div4 = 1;
3486+ ndiv = (realFreq * (6 + 8) * 4) / MT_FE_CRYSTAL_KHZ;
3487+ }else{
3488+ m88ds3103_tuner_writereg(state, 0x10, 0x01);
3489+ ndiv = (realFreq * (6 + 8) * 2) / MT_FE_CRYSTAL_KHZ;
3490+ }
3491+ ndiv = ndiv + ndiv%2;
3492+ ndiv = ndiv - 1024;
3493+ m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8)&0x0f);
3494+ }
3495+ /* set pll */
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);
3502+
3503+ if(state->tuner_id == TS2022_ID){
3504+ if(( realFreq >= 1650000 ) && (realFreq <= 1850000)){
3505+ msleep(5);
3506+ value = m88ds3103_tuner_readreg(state, 0x14);
3507+ value &= 0x7f;
3508+ if(value < 64){
3509+ m88ds3103_tuner_writereg(state, 0x10, 0x82);
3510+ m88ds3103_tuner_writereg(state, 0x11, 0x6f);
3511+
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);
3516+ }
3517+ }
3518+ msleep(5);
3519+ value = m88ds3103_tuner_readreg(state, 0x14);
3520+ value &= 0x1f;
3521+
3522+ if(value > 19){
3523+ value = m88ds3103_tuner_readreg(state, 0x10);
3524+ value &= 0x1d;
3525+ m88ds3103_tuner_writereg(state, 0x10, value);
3526+ }
3527+ }else{
3528+ msleep(5);
3529+ value = m88ds3103_tuner_readreg(state, 0x66);
3530+ changePLL = (((value & 0x80) >> 7) != div4);
3531+
3532+ if(changePLL){
3533+ m88ds3103_tuner_writereg(state, 0x10, 0x11);
3534+ div4 = 1;
3535+ ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ;
3536+ ndiv = ndiv + ndiv%2;
3537+ ndiv = ndiv - 1024;
3538+
3539+ m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8) & 0x0f);
3540+ m88ds3103_tuner_writereg(state, 0x02, ndiv & 0xff);
3541+
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);
3546+ }
3547+ }
3548+ /*set the RF gain*/
3549+ if(state->tuner_id == TS2020_ID)
3550+ m88ds3103_tuner_writereg(state, 0x60, 0x79);
3551+
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);
3556+ msleep(5);
3557+
3558+ if(state->tuner_id == TS2020_ID){
3559+ RFgain = m88ds3103_tuner_readreg(state, 0x3d);
3560+ RFgain &= 0x0f;
3561+ if(RFgain < 15){
3562+ if(RFgain < 4)
3563+ RFgain = 0;
3564+ else
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);
3572+ }
3573+ }
3574+
3575+ /* set the LPF */
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);
3581+ }
3582+
3583+ f3db = ((c->symbol_rate / 1000) *135) / 200 + 2000;
3584+ f3db += lpf_offset_KHz;
3585+ if (f3db < 7000)
3586+ f3db = 7000;
3587+ if (f3db > 40000)
3588+ f3db = 40000;
3589+
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);
3596+ msleep(5);
3597+
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);
3602+
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);
3607+
3608+ msleep(2);
3609+
3610+ value = m88ds3103_tuner_readreg(state, 0x26);
3611+ value &= 0x3f;
3612+ value = (capCode + value) / 2;
3613+ }
3614+ else
3615+ value = capCode;
3616+
3617+ gdiv28 = gdiv28 * 207 / (value * 2 + 151);
3618+ mlpf_max = gdiv28 * 135 / 100;
3619+ mlpf_min = gdiv28 * 78 / 100;
3620+ if (mlpf_max > 63)
3621+ mlpf_max = 63;
3622+
3623+ if(state->tuner_id == TS2022_ID)
3624+ lpf_coeff = 3200;
3625+ else
3626+ lpf_coeff = 2766;
3627+
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;
3631+
3632+ lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2;
3633+
3634+ if (lpf_mxdiv < mlpf_min){
3635+ nlpf++;
3636+ lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2;
3637+ }
3638+
3639+ if (lpf_mxdiv > mlpf_max)
3640+ lpf_mxdiv = mlpf_max;
3641+
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);
3648+ msleep(5);
3649+
3650+ if(state->tuner_id == TS2022_ID){
3651+ msleep(2);
3652+ value = m88ds3103_tuner_readreg(state, 0x26);
3653+ capCode = value & 0x3f;
3654+
3655+ m88ds3103_tuner_writereg(state, 0x41, 0x09);
3656+
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);
3661+
3662+ msleep(2);
3663+ value = m88ds3103_tuner_readreg(state, 0x26);
3664+ value &= 0x3f;
3665+ value = (capCode + value) / 2;
3666+
3667+ value = value | 0x80;
3668+ m88ds3103_tuner_writereg(state, 0x25, value);
3669+ m88ds3103_tuner_writereg(state, 0x27, 0x30);
3670+
3671+ m88ds3103_tuner_writereg(state, 0x08, 0x09);
3672+ }
3673+
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){
3680+ if(RFgain == 15){
3681+ msleep(40);
3682+ value = m88ds3103_tuner_readreg(state, 0x21);
3683+ value &= 0x0f;
3684+ if(value < 3){
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);
3690+ }
3691+ }
3692+ }
3693+ msleep(60);
3694+
3695+ offset_khz = (ndiv - ndiv % 2 + 1024) * MT_FE_CRYSTAL_KHZ
3696+ / (6 + 8) / (div4 + 1) / 2 - realFreq;
3697+
3698+ m88ds3103_demod_connect(fe, offset_khz+lpf_offset_KHz);
3699+
3700+ for (i = 0; i < 30 ; i++) {
3701+ m88ds3103_read_status(fe, &status);
3702+ if (status & FE_HAS_LOCK){
3703+ break;
3704+ }
3705+ msleep(20);
3706+ }
3707+
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);
3711+
3712+ for (i = 0; i < 30 ; i++) {
3713+ m88ds3103_read_status(fe, &status);
3714+ if (status & FE_HAS_LOCK){
3715+ break;
3716+ }
3717+ msleep(20);
3718+ }
3719+ }
3720+
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;
3728+ }
3729+ }
3730+ }
3731+
3732+ return 0;
3733+}
3734+
3735+static int m88ds3103_tune(struct dvb_frontend *fe,
3736+ bool re_tune,
3737+ unsigned int mode_flags,
3738+ unsigned int *delay,
3739+ fe_status_t *status)
3740+{
3741+ *delay = HZ / 5;
3742+
3743+ dprintk("%s() ", __func__);
3744+ dprintk("re_tune = %d\n", re_tune);
3745+
3746+ if (re_tune) {
3747+ int ret = m88ds3103_set_frontend(fe);
3748+ if (ret)
3749+ return ret;
3750+ }
3751+
3752+ return m88ds3103_read_status(fe, status);
3753+}
3754+
3755+static enum dvbfe_algo m88ds3103_get_algo(struct dvb_frontend *fe)
3756+{
3757+ return DVBFE_ALGO_HW;
3758+}
3759+
3760+ /*
3761+ * Power config will reset and load initial firmware if required
3762+ */
3763+static int m88ds3103_initilaze(struct dvb_frontend *fe)
3764+{
3765+ struct m88ds3103_state *state = fe->demodulator_priv;
3766+ int ret;
3767+
3768+ dprintk("%s()\n", __func__);
3769+ /* hard reset */
3770+ m88ds3103_writereg(state, 0x07, 0x80);
3771+ m88ds3103_writereg(state, 0x07, 0x00);
3772+ msleep(1);
3773+
3774+ m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08));
3775+ msleep(1);
3776+
3777+ if(state->tuner_id == TS2020_ID){
3778+ /* TS2020 init */
3779+ m88ds3103_tuner_writereg(state, 0x42, 0x73);
3780+ msleep(2);
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);
3785+ }
3786+ else if(state->tuner_id == TS2022_ID){
3787+ /* TS2022 init */
3788+ m88ds3103_tuner_writereg(state, 0x62, 0x6c);
3789+ msleep(2);
3790+ m88ds3103_tuner_writereg(state, 0x42, 0x6c);
3791+ msleep(2);
3792+ m88ds3103_tuner_writereg(state, 0x7d, 0x9d);
3793+ m88ds3103_tuner_writereg(state, 0x7c, 0x9a);
3794+ m88ds3103_tuner_writereg(state, 0x7a, 0x76);
3795+
3796+ m88ds3103_tuner_writereg(state, 0x3b, 0x01);
3797+ m88ds3103_tuner_writereg(state, 0x63, 0x88);
3798+
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);
3805+ }
3806+
3807+ if(state->demod_id == DS3103_ID){
3808+ m88ds3103_writereg(state, 0x07, 0xe0);
3809+ m88ds3103_writereg(state, 0x07, 0x00);
3810+ msleep(1);
3811+ }
3812+ m88ds3103_writereg(state, 0xb2, 0x01);
3813+
3814+ /* Load the firmware if required */
3815+ ret = m88ds3103_load_firmware(fe);
3816+ if (ret != 0){
3817+ printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
3818+ return ret;
3819+ }
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));
3823+ }
3824+
3825+ return 0;
3826+}
3827+
3828+/*
3829+ * Initialise or wake up device
3830+ */
3831+static int m88ds3103_initfe(struct dvb_frontend *fe)
3832+{
3833+ struct m88ds3103_state *state = fe->demodulator_priv;
3834+ u8 val;
3835+
3836+ dprintk("%s()\n", __func__);
3837+
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));
3842+
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);
3847+ msleep(50);
3848+ }
3849+ m88ds3103_tuner_writereg(state, 0x00, 0x03);
3850+ msleep(50);
3851+
3852+ return 0;
3853+}
3854+
3855+/* Put device to sleep */
3856+static int m88ds3103_sleep(struct dvb_frontend *fe)
3857+{
3858+ struct m88ds3103_state *state = fe->demodulator_priv;
3859+
3860+ dprintk("%s()\n", __func__);
3861+
3862+ /* 1st step to sleep tuner */
3863+ m88ds3103_tuner_writereg(state, 0x00, 0x00);
3864+
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));
3869+
3870+
3871+ return 0;
3872+}
3873+
3874+static struct dvb_frontend_ops m88ds3103_ops = {
3875+ .delsys = { SYS_DVBS, SYS_DVBS2},
3876+ .info = {
3877+ .name = "Montage DS3103/TS2022",
3878+ .type = FE_QPSK,
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
3891+ },
3892+
3893+ .release = m88ds3103_release,
3894+
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,
3909+};
3910+
3911+MODULE_DESCRIPTION("DVB Frontend module for Montage DS3103/TS2022 hardware");
3912+MODULE_AUTHOR("Max nibble");
3913+MODULE_LICENSE("GPL");
3914diff -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
3917@@ -0,0 +1,53 @@
3918+/*
3919+ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
3920+
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.
3925+
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.
3930+
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.
3934+ */
3935+
3936+#ifndef M88DS3103_H
3937+#define M88DS3103_H
3938+
3939+#include <linux/dvb/frontend.h>
3940+
3941+struct m88ds3103_config {
3942+ /* the demodulator's i2c address */
3943+ u8 demod_address;
3944+ u8 ci_mode;
3945+ u8 pin_ctrl;
3946+ u8 ts_mode; /* 0: Parallel, 1: Serial */
3947+
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);
3954+};
3955+
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);
3961+#else
3962+static inline struct dvb_frontend *m88ds3103_attach(
3963+ const struct m88ds3103_config *config,
3964+ struct i2c_adapter *i2c)
3965+{
3966+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
3967+ return NULL;
3968+}
3969+#endif /* CONFIG_DVB_M88DS3103 */
3970+#endif /* M88DS3103_H */
3971diff -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
3974@@ -0,0 +1,403 @@
3975+/*
3976+ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
3977+
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.
3982+
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.
3987+
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.
3991+ */
3992+
3993+#ifndef M88DS3103_PRIV_H
3994+#define M88DS3103_PRIV_H
3995+
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
4008+
4009+struct m88ds3103_state {
4010+ struct i2c_adapter *i2c;
4011+ const struct m88ds3103_config *config;
4012+
4013+ struct dvb_frontend frontend;
4014+
4015+ u32 preBer;
4016+ u8 skip_fw_load;
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;
4021+};
4022+
4023+/* For M88DS3103 demod dvbs mode.*/
4024+static u8 ds3103_dvbs_init_tab[] = {
4025+ 0x23, 0x07,
4026+ 0x08, 0x03,
4027+ 0x0c, 0x02,
4028+ 0x21, 0x54,
4029+ 0x25, 0x82,
4030+ 0x27, 0x31,
4031+ 0x30, 0x08,
4032+ 0x31, 0x40,
4033+ 0x32, 0x32,
4034+ 0x33, 0x35,
4035+ 0x35, 0xff,
4036+ 0x3a, 0x00,
4037+ 0x37, 0x10,
4038+ 0x38, 0x10,
4039+ 0x39, 0x02,
4040+ 0x42, 0x60,
4041+ 0x4a, 0x80,
4042+ 0x4b, 0x04,
4043+ 0x4d, 0x91,
4044+ 0x5d, 0xc8,
4045+ 0x50, 0x36,
4046+ 0x51, 0x36,
4047+ 0x52, 0x36,
4048+ 0x53, 0x36,
4049+ 0x63, 0x0f,
4050+ 0x64, 0x30,
4051+ 0x65, 0x40,
4052+ 0x68, 0x26,
4053+ 0x69, 0x4c,
4054+ 0x70, 0x20,
4055+ 0x71, 0x70,
4056+ 0x72, 0x04,
4057+ 0x73, 0x00,
4058+ 0x70, 0x40,
4059+ 0x71, 0x70,
4060+ 0x72, 0x04,
4061+ 0x73, 0x00,
4062+ 0x70, 0x60,
4063+ 0x71, 0x70,
4064+ 0x72, 0x04,
4065+ 0x73, 0x00,
4066+ 0x70, 0x80,
4067+ 0x71, 0x70,
4068+ 0x72, 0x04,
4069+ 0x73, 0x00,
4070+ 0x70, 0xa0,
4071+ 0x71, 0x70,
4072+ 0x72, 0x04,
4073+ 0x73, 0x00,
4074+ 0x70, 0x1f,
4075+ 0x76, 0x38,
4076+ 0x77, 0xa6,
4077+ 0x78, 0x0c,
4078+ 0x79, 0x80,
4079+ 0x7f, 0x14,
4080+ 0x7c, 0x00,
4081+ 0xae, 0x82,
4082+ 0x80, 0x64,
4083+ 0x81, 0x66,
4084+ 0x82, 0x44,
4085+ 0x85, 0x04,
4086+ 0xcd, 0xf4,
4087+ 0x90, 0x33,
4088+ 0xa0, 0x44,
4089+ 0xc0, 0x08,
4090+ 0xc3, 0x10,
4091+ 0xc4, 0x08,
4092+ 0xc5, 0xf0,
4093+ 0xc6, 0xff,
4094+ 0xc7, 0x00,
4095+ 0xc8, 0x1a,
4096+ 0xc9, 0x80,
4097+ 0xe0, 0xf8,
4098+ 0xe6, 0x8b,
4099+ 0xd0, 0x40,
4100+ 0xf8, 0x20,
4101+ 0xfa, 0x0f,
4102+ 0x00, 0x00,
4103+ 0xbd, 0x01,
4104+ 0xb8, 0x00,
4105+};
4106+/* For M88DS3103 demod dvbs2 mode.*/
4107+static u8 ds3103_dvbs2_init_tab[] = {
4108+ 0x23, 0x07,
4109+ 0x08, 0x07,
4110+ 0x0c, 0x02,
4111+ 0x21, 0x54,
4112+ 0x25, 0x82,
4113+ 0x27, 0x31,
4114+ 0x30, 0x08,
4115+ 0x32, 0x32,
4116+ 0x33, 0x35,
4117+ 0x35, 0xff,
4118+ 0x3a, 0x00,
4119+ 0x37, 0x10,
4120+ 0x38, 0x10,
4121+ 0x39, 0x02,
4122+ 0x42, 0x60,
4123+ 0x4a, 0x80,
4124+ 0x4b, 0x04,
4125+ 0x4d, 0x91,
4126+ 0x5d, 0xc8,
4127+ 0x50, 0x36,
4128+ 0x51, 0x36,
4129+ 0x52, 0x36,
4130+ 0x53, 0x36,
4131+ 0x63, 0x0f,
4132+ 0x64, 0x10,
4133+ 0x65, 0x20,
4134+ 0x68, 0x46,
4135+ 0x69, 0xcd,
4136+ 0x70, 0x20,
4137+ 0x71, 0x70,
4138+ 0x72, 0x04,
4139+ 0x73, 0x00,
4140+ 0x70, 0x40,
4141+ 0x71, 0x70,
4142+ 0x72, 0x04,
4143+ 0x73, 0x00,
4144+ 0x70, 0x60,
4145+ 0x71, 0x70,
4146+ 0x72, 0x04,
4147+ 0x73, 0x00,
4148+ 0x70, 0x80,
4149+ 0x71, 0x70,
4150+ 0x72, 0x04,
4151+ 0x73, 0x00,
4152+ 0x70, 0xa0,
4153+ 0x71, 0x70,
4154+ 0x72, 0x04,
4155+ 0x73, 0x00,
4156+ 0x70, 0x1f,
4157+ 0x76, 0x38,
4158+ 0x77, 0xa6,
4159+ 0x78, 0x0c,
4160+ 0x79, 0x80,
4161+ 0x7f, 0x14,
4162+ 0x85, 0x08,
4163+ 0xcd, 0xf4,
4164+ 0x90, 0x33,
4165+ 0x86, 0x00,
4166+ 0x87, 0x0f,
4167+ 0x89, 0x00,
4168+ 0x8b, 0x44,
4169+ 0x8c, 0x66,
4170+ 0x9d, 0xc1,
4171+ 0x8a, 0x10,
4172+ 0xad, 0x40,
4173+ 0xa0, 0x44,
4174+ 0xc0, 0x08,
4175+ 0xc1, 0x10,
4176+ 0xc2, 0x08,
4177+ 0xc3, 0x10,
4178+ 0xc4, 0x08,
4179+ 0xc5, 0xf0,
4180+ 0xc6, 0xff,
4181+ 0xc7, 0x00,
4182+ 0xc8, 0x1a,
4183+ 0xc9, 0x80,
4184+ 0xca, 0x23,
4185+ 0xcb, 0x24,
4186+ 0xcc, 0xf4,
4187+ 0xce, 0x74,
4188+ 0x00, 0x00,
4189+ 0xbd, 0x01,
4190+ 0xb8, 0x00,
4191+};
4192+
4193+/* For M88DS3000 demod dvbs mode.*/
4194+static u8 ds3000_dvbs_init_tab[] = {
4195+ 0x23, 0x05,
4196+ 0x08, 0x03,
4197+ 0x0c, 0x02,
4198+ 0x21, 0x54,
4199+ 0x25, 0x82,
4200+ 0x27, 0x31,
4201+ 0x30, 0x08,
4202+ 0x31, 0x40,
4203+ 0x32, 0x32,
4204+ 0x33, 0x35,
4205+ 0x35, 0xff,
4206+ 0x3a, 0x00,
4207+ 0x37, 0x10,
4208+ 0x38, 0x10,
4209+ 0x39, 0x02,
4210+ 0x42, 0x60,
4211+ 0x4a, 0x40,
4212+ 0x4b, 0x04,
4213+ 0x4d, 0x91,
4214+ 0x5d, 0xc8,
4215+ 0x50, 0x77,
4216+ 0x51, 0x77,
4217+ 0x52, 0x36,
4218+ 0x53, 0x36,
4219+ 0x56, 0x01,
4220+ 0x63, 0x47,
4221+ 0x64, 0x30,
4222+ 0x65, 0x40,
4223+ 0x68, 0x26,
4224+ 0x69, 0x4c,
4225+ 0x70, 0x20,
4226+ 0x71, 0x70,
4227+ 0x72, 0x04,
4228+ 0x73, 0x00,
4229+ 0x70, 0x40,
4230+ 0x71, 0x70,
4231+ 0x72, 0x04,
4232+ 0x73, 0x00,
4233+ 0x70, 0x60,
4234+ 0x71, 0x70,
4235+ 0x72, 0x04,
4236+ 0x73, 0x00,
4237+ 0x70, 0x80,
4238+ 0x71, 0x70,
4239+ 0x72, 0x04,
4240+ 0x73, 0x00,
4241+ 0x70, 0xa0,
4242+ 0x71, 0x70,
4243+ 0x72, 0x04,
4244+ 0x73, 0x00,
4245+ 0x70, 0x1f,
4246+ 0x76, 0x00,
4247+ 0x77, 0xd1,
4248+ 0x78, 0x0c,
4249+ 0x79, 0x80,
4250+ 0x7f, 0x04,
4251+ 0x7c, 0x00,
4252+ 0x80, 0x86,
4253+ 0x81, 0xa6,
4254+ 0x85, 0x04,
4255+ 0xcd, 0xf4,
4256+ 0x90, 0x33,
4257+ 0xa0, 0x44,
4258+ 0xc0, 0x18,
4259+ 0xc3, 0x10,
4260+ 0xc4, 0x08,
4261+ 0xc5, 0x80,
4262+ 0xc6, 0x80,
4263+ 0xc7, 0x0a,
4264+ 0xc8, 0x1a,
4265+ 0xc9, 0x80,
4266+ 0xfe, 0xb6,
4267+ 0xe0, 0xf8,
4268+ 0xe6, 0x8b,
4269+ 0xd0, 0x40,
4270+ 0xf8, 0x20,
4271+ 0xfa, 0x0f,
4272+ 0xad, 0x20,
4273+ 0xae, 0x07,
4274+ 0xb8, 0x00,
4275+};
4276+
4277+/* For M88DS3000 demod dvbs2 mode.*/
4278+static u8 ds3000_dvbs2_init_tab[] = {
4279+ 0x23, 0x0f,
4280+ 0x08, 0x07,
4281+ 0x0c, 0x02,
4282+ 0x21, 0x54,
4283+ 0x25, 0x82,
4284+ 0x27, 0x31,
4285+ 0x30, 0x08,
4286+ 0x31, 0x32,
4287+ 0x32, 0x32,
4288+ 0x33, 0x35,
4289+ 0x35, 0xff,
4290+ 0x3a, 0x00,
4291+ 0x37, 0x10,
4292+ 0x38, 0x10,
4293+ 0x39, 0x02,
4294+ 0x42, 0x60,
4295+ 0x4a, 0x80,
4296+ 0x4b, 0x04,
4297+ 0x4d, 0x91,
4298+ 0x5d, 0x88,
4299+ 0x50, 0x36,
4300+ 0x51, 0x36,
4301+ 0x52, 0x36,
4302+ 0x53, 0x36,
4303+ 0x63, 0x60,
4304+ 0x64, 0x10,
4305+ 0x65, 0x10,
4306+ 0x68, 0x04,
4307+ 0x69, 0x29,
4308+ 0x70, 0x20,
4309+ 0x71, 0x70,
4310+ 0x72, 0x04,
4311+ 0x73, 0x00,
4312+ 0x70, 0x40,
4313+ 0x71, 0x70,
4314+ 0x72, 0x04,
4315+ 0x73, 0x00,
4316+ 0x70, 0x60,
4317+ 0x71, 0x70,
4318+ 0x72, 0x04,
4319+ 0x73, 0x00,
4320+ 0x70, 0x80,
4321+ 0x71, 0x70,
4322+ 0x72, 0x04,
4323+ 0x73, 0x00,
4324+ 0x70, 0xa0,
4325+ 0x71, 0x70,
4326+ 0x72, 0x04,
4327+ 0x73, 0x00,
4328+ 0x70, 0x1f,
4329+ 0xa0, 0x44,
4330+ 0xc0, 0x08,
4331+ 0xc1, 0x10,
4332+ 0xc2, 0x08,
4333+ 0xc3, 0x10,
4334+ 0xc4, 0x08,
4335+ 0xc5, 0xf0,
4336+ 0xc6, 0xf0,
4337+ 0xc7, 0x0a,
4338+ 0xc8, 0x1a,
4339+ 0xc9, 0x80,
4340+ 0xca, 0x23,
4341+ 0xcb, 0x24,
4342+ 0xce, 0x74,
4343+ 0x56, 0x01,
4344+ 0x90, 0x03,
4345+ 0x76, 0x80,
4346+ 0x77, 0x42,
4347+ 0x78, 0x0a,
4348+ 0x79, 0x80,
4349+ 0xad, 0x40,
4350+ 0xae, 0x07,
4351+ 0x7f, 0xd4,
4352+ 0x7c, 0x00,
4353+ 0x80, 0xa8,
4354+ 0x81, 0xda,
4355+ 0x7c, 0x01,
4356+ 0x80, 0xda,
4357+ 0x81, 0xec,
4358+ 0x7c, 0x02,
4359+ 0x80, 0xca,
4360+ 0x81, 0xeb,
4361+ 0x7c, 0x03,
4362+ 0x80, 0xba,
4363+ 0x81, 0xdb,
4364+ 0x85, 0x08,
4365+ 0x86, 0x00,
4366+ 0x87, 0x02,
4367+ 0x89, 0x80,
4368+ 0x8b, 0x44,
4369+ 0x8c, 0xaa,
4370+ 0x8a, 0x10,
4371+ 0xba, 0x00,
4372+ 0xf5, 0x04,
4373+ 0xd2, 0x32,
4374+ 0xb8, 0x00,
4375+};
4376+
4377+#endif /* M88DS3103_PRIV_H */
4378diff -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
4381@@ -103,4 +103,5 @@
4382 obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
4383 obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
4384 obj-$(CONFIG_DVB_AF9033) += af9033.o
4385-
4386+obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o
4387+obj-$(CONFIG_DVB_M88DC2800) += m88dc2800.o
4388diff -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
4391@@ -415,7 +415,7 @@
4392 return state->status;
4393 }
4394
4395-int netup_ci_init(struct cx23885_tsport *port)
4396+int netup_ci_init(struct cx23885_tsport *port, bool isDVBSky)
4397 {
4398 struct netup_ci_state *state;
4399 u8 cimax_init[34] = {
4400@@ -464,6 +464,11 @@
4401 goto err;
4402 }
4403
4404+ if(isDVBSky) {
4405+ cimax_init[32] = 0x22;
4406+ cimax_init[33] = 0x00;
4407+ }
4408+
4409 port->port_priv = state;
4410
4411 switch (port->nr) {
4412@@ -537,3 +542,19 @@
4413 dvb_ca_en50221_release(&state->ca);
4414 kfree(state);
4415 }
4416+
4417+/* CI irq handler for DVBSky board*/
4418+int dvbsky_ci_slot_status(struct cx23885_dev *dev)
4419+{
4420+ struct cx23885_tsport *port = NULL;
4421+ struct netup_ci_state *state = NULL;
4422+
4423+ ci_dbg_print("%s:\n", __func__);
4424+
4425+ port = &dev->ts1;
4426+ state = port->port_priv;
4427+ schedule_work(&state->work);
4428+ ci_dbg_print("%s: Wakeup CI0\n", __func__);
4429+
4430+ return 1;
4431+}
4432diff -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
4435@@ -41,7 +41,9 @@
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);
4442
4443+extern int dvbsky_ci_slot_status(struct cx23885_dev *dev);
4444+
4445 #endif
4446diff -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,
4452 },
4453+ [CX23885_BOARD_BST_PS8512] = {
4454+ .name = "Bestunar PS8512",
4455+ .portb = CX23885_MPEG_DVB,
4456+ },
4457+ [CX23885_BOARD_DVBSKY_S950] = {
4458+ .name = "DVBSKY S950",
4459+ .portb = CX23885_MPEG_DVB,
4460+ },
4461+ [CX23885_BOARD_DVBSKY_S952] = {
4462+ .name = "DVBSKY S952",
4463+ .portb = CX23885_MPEG_DVB,
4464+ .portc = CX23885_MPEG_DVB,
4465+ },
4466+ [CX23885_BOARD_DVBSKY_S950_CI] = {
4467+ .ci_type = 3,
4468+ .name = "DVBSKY S950CI DVB-S2 CI",
4469+ .portb = CX23885_MPEG_DVB,
4470+ },
4471+ [CX23885_BOARD_DVBSKY_C2800E_CI] = {
4472+ .ci_type = 3,
4473+ .name = "DVBSKY C2800E DVB-C CI",
4474+ .portb = CX23885_MPEG_DVB,
4475+ },
4476+ [CX23885_BOARD_DVBSKY_T9580] = {
4477+ .name = "DVBSKY T9580",
4478+ .portb = CX23885_MPEG_DVB,
4479+ .portc = CX23885_MPEG_DVB,
4480+ },
4481 [CX23885_BOARD_PROF_8000] = {
4482 .name = "Prof Revolution DVB-S2 8000",
4483 .portb = CX23885_MPEG_DVB,
4484@@ -605,7 +633,7 @@
4485 CX25840_NONE1_CH3,
4486 .amux = CX25840_AUDIO6,
4487 } },
4488- }
4489+ }
4490 };
4491 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
4492
4493@@ -818,6 +846,30 @@
4494 .subdevice = 0x9022,
4495 .card = CX23885_BOARD_TEVII_S471,
4496 }, {
4497+ .subvendor = 0x14f1,
4498+ .subdevice = 0x8512,
4499+ .card = CX23885_BOARD_BST_PS8512,
4500+ }, {
4501+ .subvendor = 0x4254,
4502+ .subdevice = 0x0950,
4503+ .card = CX23885_BOARD_DVBSKY_S950,
4504+ }, {
4505+ .subvendor = 0x4254,
4506+ .subdevice = 0x0952,
4507+ .card = CX23885_BOARD_DVBSKY_S952,
4508+ }, {
4509+ .subvendor = 0x4254,
4510+ .subdevice = 0x950C,
4511+ .card = CX23885_BOARD_DVBSKY_S950_CI,
4512+ }, {
4513+ .subvendor = 0x4254,
4514+ .subdevice = 0x2800,
4515+ .card = CX23885_BOARD_DVBSKY_C2800E_CI,
4516+ }, {
4517+ .subvendor = 0x4254,
4518+ .subdevice = 0x9580,
4519+ .card = CX23885_BOARD_DVBSKY_T9580,
4520+ }, {
4521 .subvendor = 0x8000,
4522 .subdevice = 0x3034,
4523 .card = CX23885_BOARD_PROF_8000,
4524@@ -1224,7 +1276,7 @@
4525 cx_set(GP0_IO, 0x00040004);
4526 break;
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);
4535 mdelay(60);
4536 break;
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);
4541+ msleep(100);
4542+ cx23885_gpio_set(dev, GPIO_2);
4543+ break;
4544+ case CX23885_BOARD_DVBSKY_S952:
4545+ case CX23885_BOARD_DVBSKY_T9580:
4546+ cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */
4547+
4548+ cx23885_gpio_enable(dev, GPIO_2, 1);
4549+ cx23885_gpio_enable(dev, GPIO_11, 1);
4550+
4551+ cx23885_gpio_clear(dev, GPIO_2);
4552+ cx23885_gpio_clear(dev, GPIO_11);
4553+ msleep(100);
4554+ cx23885_gpio_set(dev, GPIO_2);
4555+ cx23885_gpio_set(dev, GPIO_11);
4556+ break;
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
4570+ */
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);
4581+ /* enable irq */
4582+ cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
4583+ break;
4584 }
4585 }
4586
4587+static int cx23885_ir_patch(struct i2c_adapter *i2c, u8 reg, u8 mask)
4588+{
4589+ struct i2c_msg msgs[2];
4590+ u8 tx_buf[2], rx_buf[1];
4591+ /* Write register address */
4592+ tx_buf[0] = reg;
4593+ msgs[0].addr = 0x4c;
4594+ msgs[0].flags = 0;
4595+ msgs[0].len = 1;
4596+ msgs[0].buf = (char *) tx_buf;
4597+ /* Read data from register */
4598+ msgs[1].addr = 0x4c;
4599+ msgs[1].flags = I2C_M_RD;
4600+ msgs[1].len = 1;
4601+ msgs[1].buf = (char *) rx_buf;
4602+
4603+ i2c_transfer(i2c, msgs, 2);
4604+
4605+ tx_buf[0] = reg;
4606+ tx_buf[1] = rx_buf[0] | mask;
4607+ msgs[0].addr = 0x4c;
4608+ msgs[0].flags = 0;
4609+ msgs[0].len = 2;
4610+ msgs[0].buf = (char *) tx_buf;
4611+
4612+ return i2c_transfer(i2c, msgs, 1);
4613+}
4614+
4615 int cx23885_ir_init(struct cx23885_dev *dev)
4616 {
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);
4621 break;
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) {
4630+ ret = -ENODEV;
4631+ break;
4632+ }
4633+ v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config,
4634+ ir_rx_pin_cfg_count, ir_rx_pin_cfg);
4635+
4636+ cx23885_ir_patch(&(dev->i2c_bus[2].i2c_adap),0x1f,0x80);
4637+ cx23885_ir_patch(&(dev->i2c_bus[2].i2c_adap),0x23,0x80);
4638+ break;
4639 case CX23885_BOARD_HAUPPAUGE_HVR1250:
4640 if (!enable_885_ir)
4641 break;
4642@@ -1511,9 +1655,15 @@
4643 cx23888_ir_remove(dev);
4644 dev->sd_ir = NULL;
4645 break;
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 @@
4660 if (dev->sd_ir)
4661 cx23885_irq_add_enable(dev, PCI_MSK_IR);
4662 break;
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;
4675 break;
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;
4686 break;
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;
4694+ break;
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;
4702+ break;
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,
4719diff -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);
4725
4726+ if (cx23885_boards[dev->board].ci_type == 3 &&
4727+ (pci_status & PCI_MSK_GPIO0))
4728+ handled += dvbsky_ci_slot_status(dev);
4729+
4730 if (ts1_status) {
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);
4735 break;
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);
4740 break;
4741 }
4742diff -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
4745@@ -51,6 +51,8 @@
4746 #include "stv6110.h"
4747 #include "lnbh24.h"
4748 #include "cx24116.h"
4749+#include "m88ds3103.h"
4750+#include "m88dc2800.h"
4751 #include "cimax2.h"
4752 #include "lgs8gxx.h"
4753 #include "netup-eeprom.h"
4754@@ -64,8 +66,8 @@
4755 #include "stv0367.h"
4756 #include "drxk.h"
4757 #include "mt2063.h"
4758-#include "stv090x.h"
4759-#include "stb6100.h"
4760+#include "stv090x.h"\r
4761+#include "stb6100.h"\r
4762 #include "stb6100_cfg.h"
4763 #include "tda10071.h"
4764 #include "a8293.h"
4765@@ -500,42 +502,130 @@
4766 .if_khz = 5380,
4767 };
4768
4769-static struct stv090x_config prof_8000_stv090x_config = {
4770- .device = STV0903,
4771- .demod_mode = STV090x_SINGLE,
4772- .clk_mode = STV090x_CLK_EXT,
4773- .xtal = 27000000,
4774- .address = 0x6A,
4775- .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED,
4776- .repeater_level = STV090x_RPTLEVEL_64,
4777- .adc1_range = STV090x_ADC_2Vpp,
4778- .diseqc_envelope_mode = false,
4779-
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,
4784-};
4785
4786-static struct stb6100_config prof_8000_stb6100_config = {
4787- .tuner_address = 0x60,
4788- .refclock = 27000000,
4789-};
4790-
4791-static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
4792+/* bst control */
4793+int bst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
4794 {
4795 struct cx23885_tsport *port = fe->dvb->priv;
4796 struct cx23885_dev *dev = port->dev;
4797+
4798+ cx23885_gpio_enable(dev, GPIO_1, 1);
4799+ cx23885_gpio_enable(dev, GPIO_0, 1);
4800+
4801+ switch (voltage) {
4802+ case SEC_VOLTAGE_13:
4803+ cx23885_gpio_set(dev, GPIO_1);
4804+ cx23885_gpio_clear(dev, GPIO_0);
4805+ break;
4806+ case SEC_VOLTAGE_18:
4807+ cx23885_gpio_set(dev, GPIO_1);
4808+ cx23885_gpio_set(dev, GPIO_0);
4809+ break;
4810+ case SEC_VOLTAGE_OFF:
4811+ cx23885_gpio_clear(dev, GPIO_1);
4812+ cx23885_gpio_clear(dev, GPIO_0);
4813+ break;
4814+ }
4815+ return 0;
4816+}
4817
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);
4822- else
4823- cx_write(MC417_RWD, 0x00001800);
4824+int dvbsky_set_voltage_sec(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
4825+{
4826+ struct cx23885_tsport *port = fe->dvb->priv;
4827+ struct cx23885_dev *dev = port->dev;
4828+
4829+ cx23885_gpio_enable(dev, GPIO_12, 1);
4830+ cx23885_gpio_enable(dev, GPIO_13, 1);
4831+
4832+ switch (voltage) {
4833+ case SEC_VOLTAGE_13:
4834+ cx23885_gpio_set(dev, GPIO_13);
4835+ cx23885_gpio_clear(dev, GPIO_12);
4836+ break;
4837+ case SEC_VOLTAGE_18:
4838+ cx23885_gpio_set(dev, GPIO_13);
4839+ cx23885_gpio_set(dev, GPIO_12);
4840+ break;
4841+ case SEC_VOLTAGE_OFF:
4842+ cx23885_gpio_clear(dev, GPIO_13);
4843+ cx23885_gpio_clear(dev, GPIO_12);
4844+ break;
4845+ }
4846 return 0;
4847 }
4848
4849+/* bestunar single dvb-s2 */
4850+static struct m88ds3103_config bst_ds3103_config = {
4851+ .demod_address = 0x68,
4852+ .ci_mode = 0,
4853+ .pin_ctrl = 0x82,
4854+ .ts_mode = 0,
4855+ .set_voltage = bst_set_voltage,
4856+};
4857+/* DVBSKY dual dvb-s2 */
4858+static struct m88ds3103_config dvbsky_ds3103_config_pri = {
4859+ .demod_address = 0x68,
4860+ .ci_mode = 0,
4861+ .pin_ctrl = 0x82,
4862+ .ts_mode = 0,
4863+ .set_voltage = bst_set_voltage,
4864+};
4865+static struct m88ds3103_config dvbsky_ds3103_config_sec = {
4866+ .demod_address = 0x68,
4867+ .ci_mode = 0,
4868+ .pin_ctrl = 0x82,
4869+ .ts_mode = 1,
4870+ .set_voltage = dvbsky_set_voltage_sec,
4871+};
4872+
4873+static struct m88ds3103_config dvbsky_ds3103_ci_config = {
4874+ .demod_address = 0x68,
4875+ .ci_mode = 2,
4876+ .pin_ctrl = 0x82,
4877+ .ts_mode = 0,
4878+};
4879+
4880+static struct m88dc2800_config dvbsky_dc2800_config = {
4881+ .demod_address = 0x1c,
4882+ .ts_mode = 3,
4883+};
4884+
4885+static struct stv090x_config prof_8000_stv090x_config = {\r
4886+ .device = STV0903,\r
4887+ .demod_mode = STV090x_SINGLE,\r
4888+ .clk_mode = STV090x_CLK_EXT,\r
4889+ .xtal = 27000000,\r
4890+ .address = 0x6A,\r
4891+ .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED,\r
4892+ .repeater_level = STV090x_RPTLEVEL_64,\r
4893+ .adc1_range = STV090x_ADC_2Vpp,\r
4894+ .diseqc_envelope_mode = false,\r
4895+\r
4896+ .tuner_get_frequency = stb6100_get_frequency,\r
4897+ .tuner_set_frequency = stb6100_set_frequency,\r
4898+ .tuner_set_bandwidth = stb6100_set_bandwidth,\r
4899+ .tuner_get_bandwidth = stb6100_get_bandwidth,\r
4900+};\r
4901+\r
4902+static struct stb6100_config prof_8000_stb6100_config = {\r
4903+ .tuner_address = 0x60,\r
4904+ .refclock = 27000000,\r
4905+};\r
4906+\r
4907+static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)\r
4908+{\r
4909+ struct cx23885_tsport *port = fe->dvb->priv;\r
4910+ struct cx23885_dev *dev = port->dev;\r
4911+\r
4912+ if (voltage == SEC_VOLTAGE_18)\r
4913+ cx_write(MC417_RWD, 0x00001e00);\r
4914+ else if (voltage == SEC_VOLTAGE_13)\r
4915+ cx_write(MC417_RWD, 0x00001a00);\r
4916+ else\r
4917+ cx_write(MC417_RWD, 0x00001800);\r
4918+ return 0;\r
4919+}
4920+
4921 static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
4922 {
4923 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
4924@@ -1250,23 +1340,79 @@
4925 &tevii_ds3000_config,
4926 &i2c_bus->i2c_adap);
4927 break;
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);
4936+ break;
4937+
4938+ case CX23885_BOARD_DVBSKY_S952:
4939+ switch (port->nr) {
4940+ /* port B */
4941+ case 1:
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);
4946+ break;
4947+ /* port C */
4948+ case 2:
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);
4953+ break;
4954+ }
4955+ break;
4956
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);
4972+ break;
4973+
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);
4979+ break;
4980
4981- fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage;
4982+ case CX23885_BOARD_DVBSKY_T9580:
4983+ switch (port->nr) {
4984+ /* port B */
4985+ case 1:
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);
4990+ break;
4991+ /* port C */
4992+ case 2:
4993+ break;
4994 }
4995 break;
4996+
4997+ case CX23885_BOARD_PROF_8000:\r
4998+ i2c_bus = &dev->i2c_bus[0];\r
4999+\r
5000+ fe0->dvb.frontend = dvb_attach(stv090x_attach,\r
5001+ &prof_8000_stv090x_config,\r
5002+ &i2c_bus->i2c_adap,\r
5003+ STV090x_DEMODULATOR_0);\r
5004+ if (fe0->dvb.frontend != NULL) {\r
5005+ if (!dvb_attach(stb6100_attach,\r
5006+ fe0->dvb.frontend,\r
5007+ &prof_8000_stb6100_config,\r
5008+ &i2c_bus->i2c_adap))\r
5009+ goto frontend_detach;\r
5010+\r
5011+ fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage;\r
5012+ }\r
5013+ break;
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);
5020
5021- netup_ci_init(port);
5022+ netup_ci_init(port, false);
5023 break;
5024 }
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);
5028 break;
5029 }
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 */
5035+
5036+ if(port->nr > 2)
5037+ break;
5038+
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);
5044+ break;
5045+ }
5046+ case CX23885_BOARD_DVBSKY_S950_CI: {
5047+ u8 eeprom[256]; /* 24C02 i2c eeprom */
5048+
5049+ if(port->nr > 2)
5050+ break;
5051+
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);
5057+
5058+ netup_ci_init(port, true);
5059+ break;
5060+ }
5061+ case CX23885_BOARD_DVBSKY_C2800E_CI: {
5062+ netup_ci_init(port, true);
5063+ break;
5064+ }
5065 }
5066
5067 return ret;
5068@@ -1434,6 +1615,8 @@
5069
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);
5075 break;
5076 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
5077diff -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
5080@@ -94,6 +94,14 @@
5081 #define CX23885_BOARD_HAUPPAUGE_HVR4400 38
5082 #define CX23885_BOARD_AVERMEDIA_HC81R 39
5083
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)
5091+
5092 #define GPIO_0 0x00000001
5093 #define GPIO_1 0x00000002
5094 #define GPIO_2 0x00000004
5095@@ -231,7 +239,7 @@
5096 */
5097 u32 clk_freq;
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) */
5102 u32 force_bff;
5103 };
5104diff -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
5107@@ -89,6 +89,12 @@
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:
5118 /*
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:
5131 /*
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;
5136 break;
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;
5148+ break;
5149 case CX23885_BOARD_MYGICA_X8507:
5150 /* Integrated CX23885 IR controller */
5151 driver_type = RC_DRIVER_IR_RAW;
5152diff -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
5155@@ -23,6 +23,8 @@
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
5164diff -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 @@
5168 } },
5169 .mpeg = CX88_MPEG_DVB,
5170 },
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,
5177+ .input = { {
5178+ .type = CX88_VMUX_DVB,
5179+ .vmux = 0,
5180+ } },
5181+ .mpeg = CX88_MPEG_DVB,
5182+ },
5183 };
5184
5185 /* ------------------------------------------------------------------ */
5186@@ -2813,6 +2825,10 @@
5187 .subvendor = 0x1822,
5188 .subdevice = 0x0023,
5189 .card = CX88_BOARD_TWINHAN_VP1027_DVBS,
5190+ }, {
5191+ .subvendor = 0x14f1,
5192+ .subdevice = 0x8312,
5193+ .card = CX88_BOARD_BST_PS8312,
5194 },
5195 };
5196
5197@@ -3547,6 +3563,12 @@
5198 cx_write(MO_SRST_IO, 1);
5199 msleep(100);
5200 break;
5201+ case CX88_BOARD_BST_PS8312:
5202+ cx_write(MO_GP1_IO, 0x808000);
5203+ msleep(100);
5204+ cx_write(MO_GP1_IO, 0x808080);
5205+ msleep(100);
5206+ break;
5207 } /*end switch() */
5208
5209
5210diff -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
5213@@ -54,6 +54,7 @@
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);
5223 return 0;
5224 }
5225+/*CX88_BOARD_BST_PS8312*/
5226+static int bst_dvbs_set_voltage(struct dvb_frontend *fe,
5227+ fe_sec_voltage_t voltage)
5228+{
5229+ struct cx8802_dev *dev= fe->dvb->priv;
5230+ struct cx88_core *core = dev->core;
5231+
5232+ cx_write(MO_GP1_IO, 0x111111);
5233+ switch (voltage) {
5234+ case SEC_VOLTAGE_13:
5235+ cx_write(MO_GP1_IO, 0x020200);
5236+ break;
5237+ case SEC_VOLTAGE_18:
5238+ cx_write(MO_GP1_IO, 0x020202);
5239+ break;
5240+ case SEC_VOLTAGE_OFF:
5241+ cx_write(MO_GP1_IO, 0x111100);
5242+ break;
5243+ }
5244+
5245+ if (core->prev_set_voltage)
5246+ return core->prev_set_voltage(fe, voltage);
5247+ return 0;
5248+}
5249+
5250+static int bst_dvbs_set_voltage_v2(struct dvb_frontend *fe,
5251+ fe_sec_voltage_t voltage)
5252+{
5253+ struct cx8802_dev *dev= fe->dvb->priv;
5254+ struct cx88_core *core = dev->core;
5255+
5256+ cx_write(MO_GP1_IO, 0x111101);
5257+ switch (voltage) {
5258+ case SEC_VOLTAGE_13:
5259+ cx_write(MO_GP1_IO, 0x020200);
5260+ break;
5261+ case SEC_VOLTAGE_18:
5262+
5263+ cx_write(MO_GP1_IO, 0x020202);
5264+ break;
5265+ case SEC_VOLTAGE_OFF:
5266+
5267+ cx_write(MO_GP1_IO, 0x111110);
5268+ break;
5269+ }
5270+
5271+ if (core->prev_set_voltage)
5272+ return core->prev_set_voltage(fe, voltage);
5273+ return 0;
5274+}
5275
5276 static int vp1027_set_voltage(struct dvb_frontend *fe,
5277 fe_sec_voltage_t voltage)
5278@@ -706,6 +757,11 @@
5279 .clk_out_div = 1,
5280 };
5281
5282+static struct m88ds3103_config dvbsky_ds3103_config = {
5283+ .demod_address = 0x68,
5284+ .set_ts_params = ds3000_set_ts_param,
5285+};
5286+
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;
5294+ }
5295+ break;
5296+ case CX88_BOARD_BST_PS8312:
5297+ fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
5298+ &dvbsky_ds3103_config,
5299+ &core->i2c_adap);
5300+ if (fe0->dvb.frontend != NULL){
5301+ int ret;
5302+ u8 b0[] = { 0x60 };
5303+ u8 b1[2] = { 0 };
5304+ struct i2c_msg msg[] = {
5305+ {
5306+ .addr = 0x50,
5307+ .flags = 0,
5308+ .buf = b0,
5309+ .len = 1
5310+ }, {
5311+ .addr = 0x50,
5312+ .flags = I2C_M_RD,
5313+ .buf = b1,
5314+ .len = 2
5315+ }
5316+ };
5317+ ret = i2c_transfer(&core->i2c_adap, msg, 2);
5318+ printk("PS8312: config = %02x, %02x", b1[0],b1[1]);
5319+ if(b1[0] == 0xaa)
5320+ fe0->dvb.frontend->ops.set_voltage = bst_dvbs_set_voltage_v2;
5321+ else
5322+ fe0->dvb.frontend->ops.set_voltage = bst_dvbs_set_voltage;
5323 }
5324 break;
5325 case CX88_BOARD_OMICOM_SS4_PCI:
5326diff -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
5329@@ -238,6 +238,7 @@
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
5334
5335 enum cx88_itype {
5336 CX88_VMUX_COMPOSITE1 = 1,
5337diff -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 */
5343 break;
5344+ case CX88_BOARD_BST_PS8312:
5345+ ir_codes = RC_MAP_DVBSKY;
5346+ ir->sampling = 0xff00; /* address */
5347+ break;
5348 }
5349
5350 if (!ir_codes) {
5351diff -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
5354@@ -57,6 +57,7 @@
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
5362diff -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
5365@@ -27,6 +27,7 @@
5366 rc-dm1105-nec.o \
5367 rc-dntv-live-dvb-t.o \
5368 rc-dntv-live-dvbt-pro.o \
5369+ rc-dvbsky.o \
5370 rc-em-terratec.o \
5371 rc-encore-enltv2.o \
5372 rc-encore-enltv.o \
5373diff -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
5376@@ -0,0 +1,78 @@
5377+/* rc-dvbsky.c - Keytable for Dvbsky Remote Controllers
5378+ *
5379+ * keymap imported from ir-keymaps.c
5380+ *
5381+ *
5382+ * Copyright (c) 2010-2012 by Nibble Max <nibble.max@gmail.com>
5383+ *
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.
5388+ */
5389+
5390+#include <media/rc-map.h>
5391+#include <linux/module.h>
5392+/*
5393+ * This table contains the complete RC5 code, instead of just the data part
5394+ */
5395+
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 },
5429+};
5430+
5431+static struct rc_map_list rc5_dvbsky_map = {
5432+ .map = {
5433+ .scan = rc5_dvbsky,
5434+ .size = ARRAY_SIZE(rc5_dvbsky),
5435+ .rc_type = RC_TYPE_RC5,
5436+ .name = RC_MAP_DVBSKY,
5437+ }
5438+};
5439+
5440+static int __init init_rc_map_rc5_dvbsky(void)
5441+{
5442+ return rc_map_register(&rc5_dvbsky_map);
5443+}
5444+
5445+static void __exit exit_rc_map_rc5_dvbsky(void)
5446+{
5447+ rc_map_unregister(&rc5_dvbsky_map);
5448+}
5449+
5450+module_init(init_rc_map_rc5_dvbsky)
5451+module_exit(exit_rc_map_rc5_dvbsky)
5452+
5453+MODULE_LICENSE("GPL");
5454+MODULE_AUTHOR("Nibble Max <nibble.max@gmail.com>");
5455diff -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
5458@@ -0,0 +1,665 @@
5459+/*
5460+ * Driver for DVBSky USB2.0 receiver
5461+ *
5462+ * Copyright (C) 2013 Max nibble <nibble.max@gmail.com>
5463+ *
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>
5469+ *
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.
5474+ *
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.
5479+ *
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.
5483+ */
5484+
5485+#include "dvb_ca_en50221.h"
5486+#include "dvb_usb.h"
5487+#include "m88ds3103.h"
5488+
5489+static int dvbsky_debug;
5490+module_param(dvbsky_debug, int, 0644);
5491+MODULE_PARM_DESC(dvbsky_debug, "Activates dvbsky usb debugging (default:0)");
5492+
5493+#define DVBSKY_CI_CTL 0x04
5494+#define DVBSKY_CI_RD 1
5495+
5496+#define dprintk(args...) \
5497+ do { \
5498+ if (dvbsky_debug) \
5499+ printk(KERN_INFO "dvbsky_usb: " args); \
5500+ } while (0)
5501+
5502+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
5503+
5504+struct dvbsky_state {
5505+ struct mutex stream_mutex;
5506+ u8 has_ci;
5507+ u8 ci_attached;
5508+ struct dvb_ca_en50221 ci;
5509+ unsigned long next_status_checked_time;
5510+ u8 ci_i2c_addr;
5511+ u8 current_ci_flag;
5512+ int ci_status;
5513+};
5514+
5515+static int dvbsky_stream_ctrl(struct dvb_usb_device *d, u8 onoff)
5516+{
5517+ struct dvbsky_state *state = d_to_priv(d);
5518+ int ret;
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) {
5525+ msleep(10);
5526+ ret = dvb_usbv2_generic_write(d, obuf_post, 3);
5527+ dprintk("%s() -on \n", __func__);
5528+ }
5529+ mutex_unlock(&state->stream_mutex);
5530+ return ret;
5531+}
5532+
5533+/* CI opertaions */
5534+static int dvbsky_ci_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
5535+ u8 *buf, int len)
5536+{
5537+ int ret;
5538+ struct i2c_msg msg[] = {
5539+ {
5540+ .addr = addr,
5541+ .flags = 0,
5542+ .buf = &reg,
5543+ .len = 1
5544+ }, {
5545+ .addr = addr,
5546+ .flags = I2C_M_RD,
5547+ .buf = buf,
5548+ .len = len
5549+ }
5550+ };
5551+
5552+ ret = i2c_transfer(i2c_adap, msg, 2);
5553+
5554+ if (ret != 2) {
5555+ dprintk("%s: error, Reg = 0x%02x, Status = %d\n", __func__, reg, ret);
5556+ return -1;
5557+ }
5558+ return 0;
5559+}
5560+
5561+static int dvbsky_ci_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
5562+ u8 *buf, int len)
5563+{
5564+ int ret;
5565+ u8 buffer[len + 1];
5566+
5567+ struct i2c_msg msg = {
5568+ .addr = addr,
5569+ .flags = 0,
5570+ .buf = &buffer[0],
5571+ .len = len + 1
5572+ };
5573+
5574+ buffer[0] = reg;
5575+ memcpy(&buffer[1], buf, len);
5576+
5577+ ret = i2c_transfer(i2c_adap, &msg, 1);
5578+
5579+ if (ret != 1) {
5580+ dprintk("%s: error, Reg=[0x%02x], Status=%d\n", __func__, reg, ret);
5581+ return -1;
5582+ }
5583+ return 0;
5584+}
5585+
5586+static int dvbsky_ci_op_cam(struct dvb_ca_en50221 *ci, int slot,
5587+ u8 flag, u8 read, int addr, u8 data)
5588+{
5589+ struct dvb_usb_device *d = ci->data;
5590+ struct dvbsky_state *state = d_to_priv(d);
5591+ u8 store;
5592+ int ret;
5593+ u8 command[4], respond[2], command_size, respond_size;
5594+
5595+ /*dprintk("%s()\n", __func__);*/
5596+ if (0 != slot)
5597+ return -EINVAL;
5598+
5599+ if (state->current_ci_flag != flag) {
5600+ ret = dvbsky_ci_read_i2c(&d->i2c_adap, state->ci_i2c_addr,
5601+ 0, &store, 1);
5602+ if (ret != 0)
5603+ return ret;
5604+
5605+ store &= ~0x0c;
5606+ store |= flag;
5607+
5608+ ret = dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5609+ 0, &store, 1);
5610+ if (ret != 0)
5611+ return ret;
5612+ }
5613+ state->current_ci_flag = flag;
5614+
5615+ command[1] = (u8)((addr >> 8) & 0xff); /*high part of address*/
5616+ command[2] = (u8)(addr & 0xff); /*low part of address*/
5617+ if (read) {
5618+ command[0] = 0x71;
5619+ command_size = 3;
5620+ respond_size = 2;
5621+ } else {
5622+ command[0] = 0x70;
5623+ command[3] = data;
5624+ command_size = 4;
5625+ respond_size = 1;
5626+ }
5627+ ret = dvb_usbv2_generic_rw(d, command, command_size, respond, respond_size);
5628+
5629+ return (read) ? respond[1] : 0;
5630+}
5631+
5632+static int dvbsky_ci_read_attribute_mem(struct dvb_ca_en50221 *ci,
5633+ int slot, int addr)
5634+{
5635+ return dvbsky_ci_op_cam(ci, slot, 0, DVBSKY_CI_RD, addr, 0);
5636+}
5637+
5638+static int dvbsky_ci_write_attribute_mem(struct dvb_ca_en50221 *ci,
5639+ int slot, int addr, u8 data)
5640+{
5641+ return dvbsky_ci_op_cam(ci, slot, 0, 0, addr, data);
5642+}
5643+
5644+static int dvbsky_ci_read_cam_ctl(struct dvb_ca_en50221 *ci, int slot, u8 addr)
5645+{
5646+ return dvbsky_ci_op_cam(ci, slot, DVBSKY_CI_CTL, DVBSKY_CI_RD, addr, 0);
5647+}
5648+
5649+static int dvbsky_ci_write_cam_ctl(struct dvb_ca_en50221 *ci, int slot,
5650+ u8 addr, u8 data)
5651+{
5652+ return dvbsky_ci_op_cam(ci, slot, DVBSKY_CI_CTL, 0, addr, data);
5653+}
5654+
5655+static int dvbsky_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
5656+{
5657+ struct dvb_usb_device *d = ci->data;
5658+ struct dvbsky_state *state = d_to_priv(d);
5659+ u8 buf = 0x80;
5660+ int ret;
5661+ dprintk("%s() slot=%d\n", __func__, slot);
5662+
5663+ if (0 != slot)
5664+ return -EINVAL;
5665+
5666+ udelay(500);
5667+ ret = dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5668+ 0, &buf, 1);
5669+
5670+ if (ret != 0)
5671+ return ret;
5672+
5673+ udelay(500);
5674+
5675+ buf = 0x00;
5676+ ret = dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5677+ 0, &buf, 1);
5678+ msleep(1000);
5679+ dprintk("%s() slot=%d complete\n", __func__, slot);
5680+ return 0;
5681+
5682+}
5683+
5684+static int dvbsky_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
5685+{
5686+ /* not implemented */
5687+ dprintk("%s()\n", __func__);
5688+ return 0;
5689+}
5690+
5691+static int dvbsky_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
5692+{
5693+ struct dvb_usb_device *d = ci->data;
5694+ struct dvbsky_state *state = d_to_priv(d);
5695+ u8 buf;
5696+ int ret;
5697+
5698+ dprintk("%s()\n", __func__);
5699+ if (0 != slot)
5700+ return -EINVAL;
5701+
5702+ dvbsky_ci_read_i2c(&d->i2c_adap, state->ci_i2c_addr,
5703+ 0, &buf, 1);
5704+ buf |= 0x60;
5705+
5706+ ret = dvbsky_ci_write_i2c(&d->i2c_adap, state->ci_i2c_addr,
5707+ 0, &buf, 1);
5708+ return ret;
5709+}
5710+
5711+static int dvbsky_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
5712+ int open)
5713+{
5714+ struct dvb_usb_device *d = ci->data;
5715+ struct dvbsky_state *state = d_to_priv(d);
5716+ int ret = 0;
5717+ u8 buf = 0;
5718+ /*dprintk("%s()\n", __func__);*/
5719+
5720+ /* CAM module INSERT/REMOVE processing. slow operation because of i2c
5721+ * transfers */
5722+ if (time_after(jiffies, state->next_status_checked_time)) {
5723+ ret = dvbsky_ci_read_i2c(&d->i2c_adap, state->ci_i2c_addr,
5724+ 0, &buf, 1);
5725+
5726+ /*dprintk("%s() status=%x\n", __func__, buf);*/
5727+
5728+ state->next_status_checked_time = jiffies
5729+ + msecs_to_jiffies(1000);
5730+
5731+ if (ret != 0)
5732+ return 0;
5733+
5734+ if (buf & 1) {
5735+ state->ci_status = DVB_CA_EN50221_POLL_CAM_PRESENT |
5736+ DVB_CA_EN50221_POLL_CAM_READY;
5737+ }
5738+ else
5739+ state->ci_status = 0;
5740+ }
5741+ /*dprintk("%s() ret=%x\n", __func__, state->ci_status);*/
5742+ return state->ci_status;
5743+}
5744+
5745+static int dvbsky_ci_init(struct dvb_usb_device *d)
5746+{
5747+ struct dvbsky_state *state = d_to_priv(d);
5748+ int ret;
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 */
5757+ 0x00, /* RFU */
5758+ 0x00, /* RFU */
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 */
5766+ 0x00, /* RFU */
5767+ 0x00, /* RFU */
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 */
5772+ 0x00, /* RFU */
5773+ 0x02, /* destination - module A */
5774+ 0x01, /* power on (use it like store place) */
5775+ 0x00, /* RFU */
5776+ 0x00, /* int status read only */
5777+ 0x00, /* Max: Disable the interrupt in USB solution.*/
5778+ 0x05, /* EXTINT=active-high, INT=push-pull */
5779+ 0x00, /* USCG1 */
5780+ 0x04, /* ack active low */
5781+ 0x00, /* LOCK = 0 */
5782+ 0x22, /* serial mode, rising in, rising out, MSB first*/
5783+ 0x00 /* synchronization */
5784+ };
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;
5790+
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;
5801+
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);
5810+ if (0 != ret)
5811+ return ret;
5812+
5813+ ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
5814+ if (ret)
5815+ return ret;
5816+ state->ci_attached = 1;
5817+ dprintk("%s() complete.\n", __func__);
5818+ return 0;
5819+}
5820+
5821+static void dvbsky_ci_release(struct dvb_usb_device *d)
5822+{
5823+ struct dvbsky_state *state = d_to_priv(d);
5824+
5825+ /* detach CI */
5826+ if (state->ci_attached)
5827+ dvb_ca_en50221_release(&state->ci);
5828+
5829+ return;
5830+}
5831+
5832+static int dvbsky_streaming_ctrl(struct dvb_frontend *fe, int onoff)
5833+{
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);
5837+}
5838+
5839+/* GPIO */
5840+static int dvbsky_gpio_ctrl(struct dvb_usb_device *d, u8 gport, u8 value)
5841+{
5842+ u8 obuf[64], ibuf[64];
5843+ obuf[0] = 0x0e;
5844+ obuf[1] = gport;
5845+ obuf[2] = value;
5846+ return dvb_usbv2_generic_rw(d, obuf, 3, ibuf, 1);
5847+}
5848+
5849+/* I2C */
5850+static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
5851+ int num)
5852+{
5853+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
5854+ int ret = 0;
5855+ u8 ibuf[64], obuf[64];
5856+
5857+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
5858+ return -EAGAIN;
5859+
5860+ if (num > 2) {
5861+ printk(KERN_ERR "dvbsky_usb: too many i2c messages[%d] than 2.", num);
5862+ ret = -EOPNOTSUPP;
5863+ goto i2c_error;
5864+ }
5865+
5866+ if(num == 1) {
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;
5870+ goto i2c_error;
5871+ }
5872+ if (msg[0].flags & I2C_M_RD) {
5873+ /* single read */
5874+ obuf[0] = 0x09;
5875+ obuf[1] = 0;
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]);*/
5880+ if (!ret)
5881+ memcpy(msg[0].buf, &ibuf[1], msg[0].len);
5882+ } else {
5883+ /* write */
5884+ obuf[0] = 0x08;
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]);*/
5890+ }
5891+ } else {
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;
5895+ goto i2c_error;
5896+ }
5897+ /* write then read */
5898+ obuf[0] = 0x09;
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]);*/
5905+ if (!ret)
5906+ memcpy(msg[1].buf, &ibuf[1], msg[1].len);
5907+ }
5908+i2c_error:
5909+ mutex_unlock(&d->i2c_mutex);
5910+ return (ret) ? ret : num;
5911+}
5912+
5913+static u32 dvbsky_i2c_func(struct i2c_adapter *adapter)
5914+{
5915+ return I2C_FUNC_I2C;
5916+}
5917+
5918+static struct i2c_algorithm dvbsky_i2c_algo = {
5919+ .master_xfer = dvbsky_i2c_xfer,
5920+ .functionality = dvbsky_i2c_func,
5921+};
5922+
5923+#if IS_ENABLED(CONFIG_RC_CORE)
5924+static int dvbsky_rc_query(struct dvb_usb_device *d)
5925+{
5926+ u32 code = 0xffff;
5927+ u8 obuf[2], ibuf[2], toggle;
5928+ int ret;
5929+ obuf[0] = 0x10;
5930+ ret = dvb_usbv2_generic_rw(d, obuf, 1, ibuf, 2);
5931+ if(ret == 0)
5932+ code = (ibuf[0] << 8) | ibuf[1];
5933+
5934+ if (code != 0xffff) {
5935+ dprintk("rc code: %x", code);
5936+ toggle = (code & 0x800) ? 1 : 0;
5937+ code &= 0x3f;
5938+ rc_keydown(d->rc_dev, code, toggle);
5939+ }
5940+ return 0;
5941+}
5942+
5943+static int dvbsky_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
5944+{
5945+ rc->allowed_protos = RC_BIT_RC5;
5946+ rc->query = dvbsky_rc_query;
5947+ rc->interval = 300;
5948+ return 0;
5949+}
5950+#else
5951+ #define dvbsky_get_rc_config NULL
5952+#endif
5953+
5954+static int dvbsky_sync_ctrl(struct dvb_frontend *fe)
5955+{
5956+ struct dvb_usb_device *d = fe_to_d(fe);
5957+ return dvbsky_stream_ctrl(d, 1);
5958+}
5959+
5960+static int dvbsky_usb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
5961+{
5962+ struct dvb_usb_device *d = fe_to_d(fe);
5963+ u8 value;
5964+
5965+ if (voltage == SEC_VOLTAGE_OFF)
5966+ value = 0;
5967+ else
5968+ value = 1;
5969+ return dvbsky_gpio_ctrl(d, 0x80, value);
5970+}
5971+
5972+static int dvbsky_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6])
5973+{
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[] = {
5978+ {
5979+ .addr = 0x51,
5980+ .flags = 0,
5981+ .buf = obuf,
5982+ .len = 2,
5983+ }, {
5984+ .addr = 0x51,
5985+ .flags = I2C_M_RD,
5986+ .buf = ibuf,
5987+ .len = 6,
5988+
5989+ }
5990+ };
5991+
5992+ if (i2c_transfer(&d->i2c_adap, msg, 2) == 2)
5993+ memcpy(mac, ibuf, 6);
5994+
5995+ printk(KERN_INFO "dvbsky_usb MAC address=%pM\n", mac);
5996+
5997+ return 0;
5998+}
5999+
6000+static struct m88ds3103_config dvbsky_usb_ds3103_config = {
6001+ .demod_address = 0x68,
6002+ .ci_mode = 1,
6003+ .pin_ctrl = 0x83,
6004+ .ts_mode = 0,
6005+ .start_ctrl = dvbsky_sync_ctrl,
6006+ .set_voltage = dvbsky_usb_set_voltage,
6007+};
6008+
6009+static int dvbsky_s960_attach(struct dvb_usb_adapter *adap)
6010+{
6011+ struct dvbsky_state *state = adap_to_priv(adap);
6012+ struct dvb_usb_device *d = adap_to_d(adap);
6013+ int ret = 0;
6014+
6015+ dprintk("%s()\n", __func__);
6016+
6017+ dvbsky_gpio_ctrl(d, 0x04, 1);
6018+
6019+ dvbsky_gpio_ctrl(d, 0x83, 0);
6020+ msleep(50);
6021+ dvbsky_gpio_ctrl(d, 0x83, 1);
6022+ msleep(20);
6023+
6024+ adap->fe[0] = dvb_attach(m88ds3103_attach,
6025+ &dvbsky_usb_ds3103_config,
6026+ &d->i2c_adap);
6027+ if (!adap->fe[0]) {
6028+ printk(KERN_ERR "dvbsky_s960_attach fail.");
6029+ ret = -ENODEV;
6030+ }
6031+
6032+ state->has_ci = 0;
6033+
6034+ return ret;
6035+}
6036+
6037+static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
6038+{
6039+ return WARM;
6040+}
6041+
6042+static int dvbsky_init(struct dvb_usb_device *d)
6043+{
6044+ struct dvbsky_state *state = d_to_priv(d);
6045+ int ret;
6046+
6047+ /* use default interface */
6048+ ret = usb_set_interface(d->udev, 0, 0);
6049+ if (ret)
6050+ return ret;
6051+
6052+ mutex_init(&state->stream_mutex);
6053+
6054+ /* attach CI */
6055+ if (state->has_ci) {
6056+ dvbsky_gpio_ctrl(d, 0xc0, 1);
6057+ msleep(100);
6058+ dvbsky_gpio_ctrl(d, 0xc0, 0);
6059+ msleep(50);
6060+ state->ci_attached = 0;
6061+ ret = dvbsky_ci_init(d);
6062+ if (ret)
6063+ return ret;
6064+ }
6065+ return 0;
6066+}
6067+
6068+static void dvbsky_exit(struct dvb_usb_device *d)
6069+{
6070+ return dvbsky_ci_release(d);
6071+}
6072+
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),
6079+
6080+ .generic_bulk_ctrl_endpoint = 0x01,
6081+ .generic_bulk_ctrl_endpoint_response = 0x81,
6082+
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,
6091+
6092+ .num_adapters = 1,
6093+ .adapter = {
6094+ {
6095+ .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
6096+ }
6097+ }
6098+};
6099+
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) },
6103+ { }
6104+};
6105+MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
6106+
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,
6116+ .soft_unbind = 1,
6117+};
6118+
6119+module_usb_driver(dvbsky_usb_driver);
6120+
6121+MODULE_AUTHOR("Max nibble <nibble.max@gmail.com>");
6122+MODULE_DESCRIPTION("Driver for DVBSky USB2.0");
6123+MODULE_LICENSE("GPL");
6124diff -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 @@
6128 help
6129 Say Y here to support the Realtek RTL28xxU DVB USB receiver.
6130
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
6135+ help
6136+ Say Y here to support the USB receivers from DVBSky.
6137+
6138diff -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
6141@@ -43,6 +43,9 @@
6142 dvb-usb-rtl28xxu-objs := rtl28xxu.o
6143 obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
6144
6145+dvb-usb-dvbsky-objs := dvbsky.o
6146+obj-$(CONFIG_DVB_USB_DVBSKY) += dvb-usb-dvbsky.o
6147+
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
6151diff -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
6154@@ -118,6 +118,7 @@
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"