]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/v4l-dvb_bestunar_us638x.patch
kernel: update to 3.10.23.
[people/teissler/ipfire-2.x.git] / src / patches / v4l-dvb_bestunar_us638x.patch
1 diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Kconfig v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Kconfig
2 --- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Kconfig 2012-08-22 05:45:23.000000000 +0200
3 +++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Kconfig 2012-11-24 13:35:19.220030262 +0100
4 @@ -200,6 +200,13 @@
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 DS3103 based"
10 + depends on DVB_CORE && I2C
11 + default m if DVB_FE_CUSTOMISE
12 + help
13 + A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
14 +
15 config DVB_SI21XX
16 tristate "Silicon Labs SI21XX based"
17 depends on DVB_CORE && I2C
18 diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.c v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.c
19 --- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.c 1970-01-01 01:00:00.000000000 +0100
20 +++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.c 2012-11-24 13:34:43.713346302 +0100
21 @@ -0,0 +1,1710 @@
22 +/*
23 + Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
24 +
25 + Copyright (C) 2011 Max nibble<nibble.max@gmail.com>
26 + Copyright (C) 2010 Montage Technology<www.montage-tech.com>
27 + Copyright (C) 2009 Konstantin Dimitrov.
28 +
29 + This program is free software; you can redistribute it and/or modify
30 + it under the terms of the GNU General Public License as published by
31 + the Free Software Foundation; either version 2 of the License, or
32 + (at your option) any later version.
33 +
34 + This program is distributed in the hope that it will be useful,
35 + but WITHOUT ANY WARRANTY; without even the implied warranty of
36 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 + GNU General Public License for more details.
38 +
39 + You should have received a copy of the GNU General Public License
40 + along with this program; if not, write to the Free Software
41 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 + */
43 +
44 +#include <linux/slab.h>
45 +#include <linux/kernel.h>
46 +#include <linux/module.h>
47 +#include <linux/moduleparam.h>
48 +#include <linux/init.h>
49 +#include <linux/firmware.h>
50 +
51 +#include "dvb_frontend.h"
52 +#include "m88ds3103.h"
53 +#include "m88ds3103_priv.h"
54 +
55 +static int debug;
56 +module_param(debug, int, 0644);
57 +MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
58 +
59 +#define dprintk(args...) \
60 + do { \
61 + if (debug) \
62 + printk(KERN_INFO "m88ds3103: " args); \
63 + } while (0)
64 +
65 +/*demod register operations.*/
66 +static int m88ds3103_writereg(struct m88ds3103_state *state, int reg, int data)
67 +{
68 + u8 buf[] = { reg, data };
69 + struct i2c_msg msg = { .addr = state->config->demod_address,
70 + .flags = 0, .buf = buf, .len = 2 };
71 + int err;
72 +
73 + if (debug > 1)
74 + printk("m88ds3103: %s: write reg 0x%02x, value 0x%02x\n",
75 + __func__, reg, data);
76 +
77 + err = i2c_transfer(state->i2c, &msg, 1);
78 + if (err != 1) {
79 + printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
80 + " value == 0x%02x)\n", __func__, err, reg, data);
81 + return -EREMOTEIO;
82 + }
83 + return 0;
84 +}
85 +
86 +static int m88ds3103_readreg(struct m88ds3103_state *state, u8 reg)
87 +{
88 + int ret;
89 + u8 b0[] = { reg };
90 + u8 b1[] = { 0 };
91 + struct i2c_msg msg[] = {
92 + { .addr = state->config->demod_address, .flags = 0,
93 + .buf = b0, .len = 1 },
94 + { .addr = state->config->demod_address, .flags = I2C_M_RD,
95 + .buf = b1, .len = 1 }
96 + };
97 + ret = i2c_transfer(state->i2c, msg, 2);
98 +
99 + if (ret != 2) {
100 + printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
101 + __func__, reg, ret);
102 + return ret;
103 + }
104 +
105 + if (debug > 1)
106 + printk(KERN_INFO "m88ds3103: read reg 0x%02x, value 0x%02x\n",
107 + reg, b1[0]);
108 +
109 + return b1[0];
110 +}
111 +
112 +/*tuner register operations.*/
113 +static int m88ds3103_tuner_writereg(struct m88ds3103_state *state, int reg, int data)
114 +{
115 + u8 buf[] = { reg, data };
116 + struct i2c_msg msg = { .addr = 0x60,
117 + .flags = 0, .buf = buf, .len = 2 };
118 + int err;
119 +
120 + m88ds3103_writereg(state, 0x03, 0x11);
121 + err = i2c_transfer(state->i2c, &msg, 1);
122 +
123 + if (err != 1) {
124 + printk("%s: writereg error(err == %i, reg == 0x%02x,"
125 + " value == 0x%02x)\n", __func__, err, reg, data);
126 + return -EREMOTEIO;
127 + }
128 +
129 + return 0;
130 +}
131 +
132 +static int m88ds3103_tuner_readreg(struct m88ds3103_state *state, u8 reg)
133 +{
134 + int ret;
135 + u8 b0[] = { reg };
136 + u8 b1[] = { 0 };
137 + struct i2c_msg msg[] = {
138 + { .addr = 0x60, .flags = 0,
139 + .buf = b0, .len = 1 },
140 + { .addr = 0x60, .flags = I2C_M_RD,
141 + .buf = b1, .len = 1 }
142 + };
143 +
144 + m88ds3103_writereg(state, 0x03, 0x11);
145 + ret = i2c_transfer(state->i2c, msg, 2);
146 +
147 + if (ret != 2) {
148 + printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
149 + return ret;
150 + }
151 +
152 + return b1[0];
153 +}
154 +
155 +/* Bulk demod I2C write, for firmware download. */
156 +static int m88ds3103_writeregN(struct m88ds3103_state *state, int reg,
157 + const u8 *data, u16 len)
158 +{
159 + int ret = -EREMOTEIO;
160 + struct i2c_msg msg;
161 + u8 *buf;
162 +
163 + buf = kmalloc(len + 1, GFP_KERNEL);
164 + if (buf == NULL) {
165 + printk("Unable to kmalloc\n");
166 + ret = -ENOMEM;
167 + goto error;
168 + }
169 +
170 + *(buf) = reg;
171 + memcpy(buf + 1, data, len);
172 +
173 + msg.addr = state->config->demod_address;
174 + msg.flags = 0;
175 + msg.buf = buf;
176 + msg.len = len + 1;
177 +
178 + if (debug > 1)
179 + printk(KERN_INFO "m88ds3103: %s: write regN 0x%02x, len = %d\n",
180 + __func__, reg, len);
181 +
182 + ret = i2c_transfer(state->i2c, &msg, 1);
183 + if (ret != 1) {
184 + printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
185 + __func__, ret, reg);
186 + ret = -EREMOTEIO;
187 + }
188 +
189 +error:
190 + kfree(buf);
191 +
192 + return ret;
193 +}
194 +
195 +static int m88ds3103_load_firmware(struct dvb_frontend *fe)
196 +{
197 + struct m88ds3103_state *state = fe->demodulator_priv;
198 + const struct firmware *fw;
199 + int i, ret = 0;
200 +
201 + dprintk("%s()\n", __func__);
202 +
203 + if (state->skip_fw_load)
204 + return 0;
205 + /* Load firmware */
206 + /* request the firmware, this will block until someone uploads it */
207 + if(state->demod_id == DS3000_ID){
208 + printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
209 + DS3000_DEFAULT_FIRMWARE);
210 + ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
211 + state->i2c->dev.parent);
212 + }else if(state->demod_id == DS3103_ID){
213 + printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
214 + DS3103_DEFAULT_FIRMWARE);
215 + ret = request_firmware(&fw, DS3103_DEFAULT_FIRMWARE,
216 + state->i2c->dev.parent);
217 + }
218 +
219 + printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
220 + if (ret) {
221 + printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
222 + "found?)\n", __func__);
223 + return ret;
224 + }
225 +
226 + /* Make sure we don't recurse back through here during loading */
227 + state->skip_fw_load = 1;
228 +
229 + dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
230 + fw->size,
231 + fw->data[0],
232 + fw->data[1],
233 + fw->data[fw->size - 2],
234 + fw->data[fw->size - 1]);
235 +
236 + /* stop internal mcu. */
237 + m88ds3103_writereg(state, 0xb2, 0x01);
238 + /* split firmware to download.*/
239 + for(i = 0; i < FW_DOWN_LOOP; i++){
240 + ret = m88ds3103_writeregN(state, 0xb0, &(fw->data[FW_DOWN_SIZE*i]), FW_DOWN_SIZE);
241 + if(ret != 1) break;
242 + }
243 + /* start internal mcu. */
244 + if(ret == 1)
245 + m88ds3103_writereg(state, 0xb2, 0x00);
246 +
247 + release_firmware(fw);
248 +
249 + dprintk("%s: Firmware upload %s\n", __func__,
250 + ret == 1 ? "complete" : "failed");
251 +
252 + if(ret == 1) ret = 0;
253 +
254 + /* Ensure firmware is always loaded if required */
255 + state->skip_fw_load = 0;
256 +
257 + return ret;
258 +}
259 +
260 +
261 +static int m88ds3103_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
262 +{
263 + struct m88ds3103_state *state = fe->demodulator_priv;
264 + u8 data;
265 +
266 + dprintk("%s(%d)\n", __func__, voltage);
267 +
268 + dprintk("m88ds3103:pin_ctrl = (%02x)\n", state->config->pin_ctrl);
269 +
270 + if(state->config->set_voltage)
271 + state->config->set_voltage(fe, voltage);
272 +
273 + data = m88ds3103_readreg(state, 0xa2);
274 +
275 + if(state->config->pin_ctrl & 0x80){ /*If control pin is assigned.*/
276 + data &= ~0x03; /* bit0 V/H, bit1 off/on */
277 + if(state->config->pin_ctrl & 0x02)
278 + data |= 0x02;
279 +
280 + switch (voltage) {
281 + case SEC_VOLTAGE_18:
282 + if((state->config->pin_ctrl & 0x01) == 0)
283 + data |= 0x01;
284 + break;
285 + case SEC_VOLTAGE_13:
286 + if(state->config->pin_ctrl & 0x01)
287 + data |= 0x01;
288 + break;
289 + case SEC_VOLTAGE_OFF:
290 + if(state->config->pin_ctrl & 0x02)
291 + data &= ~0x02;
292 + else
293 + data |= 0x02;
294 + break;
295 + }
296 + }
297 +
298 + m88ds3103_writereg(state, 0xa2, data);
299 +
300 + return 0;
301 +}
302 +
303 +static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t* status)
304 +{
305 + struct m88ds3103_state *state = fe->demodulator_priv;
306 + int lock = 0;
307 +
308 + *status = 0;
309 +
310 + switch (state->delivery_system){
311 + case SYS_DVBS:
312 + lock = m88ds3103_readreg(state, 0xd1);
313 + dprintk("%s: SYS_DVBS status=%x.\n", __func__, lock);
314 +
315 + if ((lock & 0x07) == 0x07){
316 + /*if((m88ds3103_readreg(state, 0x0d) & 0x07) == 0x07)*/
317 + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER
318 + | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
319 +
320 + }
321 + break;
322 + case SYS_DVBS2:
323 + lock = m88ds3103_readreg(state, 0x0d);
324 + dprintk("%s: SYS_DVBS2 status=%x.\n", __func__, lock);
325 +
326 + if ((lock & 0x8f) == 0x8f)
327 + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER
328 + | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
329 +
330 + break;
331 + default:
332 + break;
333 + }
334 +
335 + return 0;
336 +}
337 +
338 +static int m88ds3103_read_ber(struct dvb_frontend *fe, u32* ber)
339 +{
340 + struct m88ds3103_state *state = fe->demodulator_priv;
341 + u8 tmp1, tmp2, tmp3;
342 + u32 ldpc_frame_cnt, pre_err_packags, code_rate_fac = 0;
343 +
344 + dprintk("%s()\n", __func__);
345 +
346 + switch (state->delivery_system) {
347 + case SYS_DVBS:
348 + m88ds3103_writereg(state, 0xf9, 0x04);
349 + tmp3 = m88ds3103_readreg(state, 0xf8);
350 + if ((tmp3&0x10) == 0){
351 + tmp1 = m88ds3103_readreg(state, 0xf7);
352 + tmp2 = m88ds3103_readreg(state, 0xf6);
353 + tmp3 |= 0x10;
354 + m88ds3103_writereg(state, 0xf8, tmp3);
355 + state->preBer = (tmp1<<8) | tmp2;
356 + }
357 + break;
358 + case SYS_DVBS2:
359 + tmp1 = m88ds3103_readreg(state, 0x7e) & 0x0f;
360 + switch(tmp1){
361 + case 0: code_rate_fac = 16008 - 80; break;
362 + case 1: code_rate_fac = 21408 - 80; break;
363 + case 2: code_rate_fac = 25728 - 80; break;
364 + case 3: code_rate_fac = 32208 - 80; break;
365 + case 4: code_rate_fac = 38688 - 80; break;
366 + case 5: code_rate_fac = 43040 - 80; break;
367 + case 6: code_rate_fac = 48408 - 80; break;
368 + case 7: code_rate_fac = 51648 - 80; break;
369 + case 8: code_rate_fac = 53840 - 80; break;
370 + case 9: code_rate_fac = 57472 - 80; break;
371 + case 10: code_rate_fac = 58192 - 80; break;
372 + }
373 +
374 + tmp1 = m88ds3103_readreg(state, 0xd7) & 0xff;
375 + tmp2 = m88ds3103_readreg(state, 0xd6) & 0xff;
376 + tmp3 = m88ds3103_readreg(state, 0xd5) & 0xff;
377 + ldpc_frame_cnt = (tmp1 << 16) | (tmp2 << 8) | tmp3;
378 +
379 + tmp1 = m88ds3103_readreg(state, 0xf8) & 0xff;
380 + tmp2 = m88ds3103_readreg(state, 0xf7) & 0xff;
381 + pre_err_packags = tmp1<<8 | tmp2;
382 +
383 + if (ldpc_frame_cnt > 1000){
384 + m88ds3103_writereg(state, 0xd1, 0x01);
385 + m88ds3103_writereg(state, 0xf9, 0x01);
386 + m88ds3103_writereg(state, 0xf9, 0x00);
387 + m88ds3103_writereg(state, 0xd1, 0x00);
388 + state->preBer = pre_err_packags;
389 + }
390 + break;
391 + default:
392 + break;
393 + }
394 + *ber = state->preBer;
395 +
396 + return 0;
397 +}
398 +
399 +static int m88ds3103_read_signal_strength(struct dvb_frontend *fe,
400 + u16 *signal_strength)
401 +{
402 + struct m88ds3103_state *state = fe->demodulator_priv;
403 + u16 gain;
404 + u8 gain1, gain2, gain3 = 0;
405 +
406 + dprintk("%s()\n", __func__);
407 +
408 + gain1 = m88ds3103_tuner_readreg(state, 0x3d) & 0x1f;
409 + dprintk("%s: gain1 = 0x%02x \n", __func__, gain1);
410 +
411 + if (gain1 > 15) gain1 = 15;
412 + gain2 = m88ds3103_tuner_readreg(state, 0x21) & 0x1f;
413 + dprintk("%s: gain2 = 0x%02x \n", __func__, gain2);
414 +
415 + if(state->tuner_id == TS2022_ID){
416 + gain3 = (m88ds3103_tuner_readreg(state, 0x66)>>3) & 0x07;
417 + dprintk("%s: gain3 = 0x%02x \n", __func__, gain3);
418 +
419 + if (gain2 > 16) gain2 = 16;
420 + if (gain2 < 2) gain2 = 2;
421 + if (gain3 > 6) gain3 = 6;
422 + }else{
423 + if (gain2 > 13) gain2 = 13;
424 + gain3 = 0;
425 + }
426 +
427 + gain = gain1*23 + gain2*35 + gain3*29;
428 + *signal_strength = 60000 - gain*55;
429 +
430 + return 0;
431 +}
432 +
433 +
434 +static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *p_snr)
435 +{
436 + struct m88ds3103_state *state = fe->demodulator_priv;
437 + u8 val, npow1, npow2, spow1, cnt;
438 + u16 tmp, snr;
439 + u32 npow, spow, snr_total;
440 + static const u16 mes_log10[] ={
441 + 0, 3010, 4771, 6021, 6990, 7781, 8451, 9031, 9542, 10000,
442 + 10414, 10792, 11139, 11461, 11761, 12041, 12304, 12553, 12788, 13010,
443 + 13222, 13424, 13617, 13802, 13979, 14150, 14314, 14472, 14624, 14771,
444 + 14914, 15052, 15185, 15315, 15441, 15563, 15682, 15798, 15911, 16021,
445 + 16128, 16232, 16335, 16435, 16532, 16628, 16721, 16812, 16902, 16990,
446 + 17076, 17160, 17243, 17324, 17404, 17482, 17559, 17634, 17709, 17782,
447 + 17853, 17924, 17993, 18062, 18129, 18195, 18261, 18325, 18388, 18451,
448 + 18513, 18573, 18633, 18692, 18751, 18808, 18865, 18921, 18976, 19031
449 + };
450 + static const u16 mes_loge[] ={
451 + 0, 6931, 10986, 13863, 16094, 17918, 19459, 20794, 21972, 23026,
452 + 23979, 24849, 25649, 26391, 27081, 27726, 28332, 28904, 29444, 29957,
453 + 30445, 30910, 31355, 31781, 32189, 32581, 32958, 33322, 33673, 34012,
454 + 34340, 34657,
455 + };
456 +
457 + dprintk("%s()\n", __func__);
458 +
459 + snr = 0;
460 +
461 + switch (state->delivery_system){
462 + case SYS_DVBS:
463 + cnt = 10; snr_total = 0;
464 + while(cnt > 0){
465 + val = m88ds3103_readreg(state, 0xff);
466 + snr_total += val;
467 + cnt--;
468 + }
469 + tmp = (u16)(snr_total/80);
470 + if(tmp > 0){
471 + if (tmp > 32) tmp = 32;
472 + snr = (mes_loge[tmp - 1] * 100) / 45;
473 + }else{
474 + snr = 0;
475 + }
476 + break;
477 + case SYS_DVBS2:
478 + cnt = 10; npow = 0; spow = 0;
479 + while(cnt >0){
480 + npow1 = m88ds3103_readreg(state, 0x8c) & 0xff;
481 + npow2 = m88ds3103_readreg(state, 0x8d) & 0xff;
482 + npow += (((npow1 & 0x3f) + (u16)(npow2 << 6)) >> 2);
483 +
484 + spow1 = m88ds3103_readreg(state, 0x8e) & 0xff;
485 + spow += ((spow1 * spow1) >> 1);
486 + cnt--;
487 + }
488 + npow /= 10; spow /= 10;
489 + if(spow == 0){
490 + snr = 0;
491 + }else if(npow == 0){
492 + snr = 19;
493 + }else{
494 + if(spow > npow){
495 + tmp = (u16)(spow / npow);
496 + if (tmp > 80) tmp = 80;
497 + snr = mes_log10[tmp - 1]*3;
498 + }else{
499 + tmp = (u16)(npow / spow);
500 + if (tmp > 80) tmp = 80;
501 + snr = -(mes_log10[tmp - 1] / 1000);
502 + }
503 + }
504 + break;
505 + default:
506 + break;
507 + }
508 + *p_snr = snr;
509 +
510 + return 0;
511 +}
512 +
513 +
514 +static int m88ds3103_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
515 +{
516 + struct m88ds3103_state *state = fe->demodulator_priv;
517 + u8 tmp1, tmp2, tmp3, data;
518 +
519 + dprintk("%s()\n", __func__);
520 +
521 + switch (state->delivery_system) {
522 + case SYS_DVBS:
523 + data = m88ds3103_readreg(state, 0xf8);
524 + data |= 0x40;
525 + m88ds3103_writereg(state, 0xf8, data);
526 + tmp1 = m88ds3103_readreg(state, 0xf5);
527 + tmp2 = m88ds3103_readreg(state, 0xf4);
528 + *ucblocks = (tmp1 <<8) | tmp2;
529 + data &= ~0x20;
530 + m88ds3103_writereg(state, 0xf8, data);
531 + data |= 0x20;
532 + m88ds3103_writereg(state, 0xf8, data);
533 + data &= ~0x40;
534 + m88ds3103_writereg(state, 0xf8, data);
535 + break;
536 + case SYS_DVBS2:
537 + tmp1 = m88ds3103_readreg(state, 0xda);
538 + tmp2 = m88ds3103_readreg(state, 0xd9);
539 + tmp3 = m88ds3103_readreg(state, 0xd8);
540 + *ucblocks = (tmp1 <<16)|(tmp2 <<8)|tmp3;
541 + data = m88ds3103_readreg(state, 0xd1);
542 + data |= 0x01;
543 + m88ds3103_writereg(state, 0xd1, data);
544 + data &= ~0x01;
545 + m88ds3103_writereg(state, 0xd1, data);
546 + break;
547 + default:
548 + break;
549 + }
550 + return 0;
551 +}
552 +
553 +static int m88ds3103_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
554 +{
555 + struct m88ds3103_state *state = fe->demodulator_priv;
556 + u8 data_a1, data_a2;
557 +
558 + dprintk("%s(%d)\n", __func__, tone);
559 + if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
560 + printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
561 + return -EINVAL;
562 + }
563 +
564 + data_a1 = m88ds3103_readreg(state, 0xa1);
565 + data_a2 = m88ds3103_readreg(state, 0xa2);
566 + if(state->demod_id == DS3103_ID)
567 + data_a2 &= 0xdf; /* Normal mode */
568 + switch (tone) {
569 + case SEC_TONE_ON:
570 + dprintk("%s: SEC_TONE_ON\n", __func__);
571 + data_a1 |= 0x04;
572 + data_a1 &= ~0x03;
573 + data_a1 &= ~0x40;
574 + data_a2 &= ~0xc0;
575 + break;
576 + case SEC_TONE_OFF:
577 + dprintk("%s: SEC_TONE_OFF\n", __func__);
578 + data_a2 &= ~0xc0;
579 + data_a2 |= 0x80;
580 + break;
581 + }
582 + m88ds3103_writereg(state, 0xa2, data_a2);
583 + m88ds3103_writereg(state, 0xa1, data_a1);
584 + return 0;
585 +}
586 +
587 +static int m88ds3103_send_diseqc_msg(struct dvb_frontend *fe,
588 + struct dvb_diseqc_master_cmd *d)
589 +{
590 + struct m88ds3103_state *state = fe->demodulator_priv;
591 + int i, ret = 0;
592 + u8 tmp, time_out;
593 +
594 + /* Dump DiSEqC message */
595 + if (debug) {
596 + printk(KERN_INFO "m88ds3103: %s(", __func__);
597 + for (i = 0 ; i < d->msg_len ;) {
598 + printk(KERN_INFO "0x%02x", d->msg[i]);
599 + if (++i < d->msg_len)
600 + printk(KERN_INFO ", ");
601 + }
602 + }
603 +
604 + tmp = m88ds3103_readreg(state, 0xa2);
605 + tmp &= ~0xc0;
606 + if(state->demod_id == DS3103_ID)
607 + tmp &= ~0x20;
608 + m88ds3103_writereg(state, 0xa2, tmp);
609 +
610 + for (i = 0; i < d->msg_len; i ++)
611 + m88ds3103_writereg(state, (0xa3+i), d->msg[i]);
612 +
613 + tmp = m88ds3103_readreg(state, 0xa1);
614 + tmp &= ~0x38;
615 + tmp &= ~0x40;
616 + tmp |= ((d->msg_len-1) << 3) | 0x07;
617 + tmp &= ~0x80;
618 + m88ds3103_writereg(state, 0xa1, tmp);
619 + /* 1.5 * 9 * 8 = 108ms */
620 + time_out = 150;
621 + while (time_out > 0){
622 + msleep(10);
623 + time_out -= 10;
624 + tmp = m88ds3103_readreg(state, 0xa1);
625 + if ((tmp & 0x40) == 0)
626 + break;
627 + }
628 + if (time_out == 0){
629 + tmp = m88ds3103_readreg(state, 0xa1);
630 + tmp &= ~0x80;
631 + tmp |= 0x40;
632 + m88ds3103_writereg(state, 0xa1, tmp);
633 + ret = 1;
634 + }
635 + tmp = m88ds3103_readreg(state, 0xa2);
636 + tmp &= ~0xc0;
637 + tmp |= 0x80;
638 + m88ds3103_writereg(state, 0xa2, tmp);
639 + return ret;
640 +}
641 +
642 +
643 +static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
644 + fe_sec_mini_cmd_t burst)
645 +{
646 + struct m88ds3103_state *state = fe->demodulator_priv;
647 + u8 val, time_out;
648 +
649 + dprintk("%s()\n", __func__);
650 +
651 + val = m88ds3103_readreg(state, 0xa2);
652 + val &= ~0xc0;
653 + if(state->demod_id == DS3103_ID)
654 + val &= 0xdf; /* Normal mode */
655 + m88ds3103_writereg(state, 0xa2, val);
656 + /* DiSEqC burst */
657 + if (burst == SEC_MINI_B)
658 + m88ds3103_writereg(state, 0xa1, 0x01);
659 + else
660 + m88ds3103_writereg(state, 0xa1, 0x02);
661 +
662 + msleep(13);
663 +
664 + time_out = 5;
665 + do{
666 + val = m88ds3103_readreg(state, 0xa1);
667 + if ((val & 0x40) == 0)
668 + break;
669 + msleep(1);
670 + time_out --;
671 + } while (time_out > 0);
672 +
673 + val = m88ds3103_readreg(state, 0xa2);
674 + val &= ~0xc0;
675 + val |= 0x80;
676 + m88ds3103_writereg(state, 0xa2, val);
677 +
678 + return 0;
679 +}
680 +
681 +static void m88ds3103_release(struct dvb_frontend *fe)
682 +{
683 + struct m88ds3103_state *state = fe->demodulator_priv;
684 +
685 + dprintk("%s\n", __func__);
686 + kfree(state);
687 +}
688 +
689 +static int m88ds3103_check_id(struct m88ds3103_state *state)
690 +{
691 + int val_00, val_01;
692 +
693 + /*check demod id*/
694 + val_01 = m88ds3103_readreg(state, 0x01);
695 + printk(KERN_INFO "DS3000 chip version: %x attached.\n", val_01);
696 +
697 + if(val_01 == 0xD0)
698 + state->demod_id = DS3103_ID;
699 + else if(val_01 == 0xC0)
700 + state->demod_id = DS3000_ID;
701 + else
702 + state->demod_id = UNKNOW_ID;
703 +
704 + /*check tuner id*/
705 + val_00 = m88ds3103_tuner_readreg(state, 0x00);
706 + printk(KERN_INFO "TS202x chip version[1]: %x attached.\n", val_00);
707 + val_00 &= 0x03;
708 + if(val_00 == 0)
709 + {
710 + m88ds3103_tuner_writereg(state, 0x00, 0x01);
711 + msleep(3);
712 + }
713 + m88ds3103_tuner_writereg(state, 0x00, 0x03);
714 + msleep(5);
715 +
716 + val_00 = m88ds3103_tuner_readreg(state, 0x00);
717 + printk(KERN_INFO "TS202x chip version[2]: %x attached.\n", val_00);
718 + val_00 &= 0xff;
719 + if((val_00 == 0x01) || (val_00 == 0x41) || (val_00 == 0x81))
720 + state->tuner_id = TS2020_ID;
721 + else if(((val_00 & 0xc0)== 0xc0) || (val_00 == 0x83))
722 + state->tuner_id = TS2022_ID;
723 + else
724 + state->tuner_id = UNKNOW_ID;
725 +
726 + return state->demod_id;
727 +}
728 +
729 +static struct dvb_frontend_ops m88ds3103_ops;
730 +static int m88ds3103_initilaze(struct dvb_frontend *fe);
731 +
732 +struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *config,
733 + struct i2c_adapter *i2c)
734 +{
735 + struct m88ds3103_state *state = NULL;
736 +
737 + dprintk("%s\n", __func__);
738 +
739 + /* allocate memory for the internal state */
740 + state = kzalloc(sizeof(struct m88ds3103_state), GFP_KERNEL);
741 + if (state == NULL) {
742 + printk(KERN_ERR "Unable to kmalloc\n");
743 + goto error2;
744 + }
745 +
746 + state->config = config;
747 + state->i2c = i2c;
748 + state->preBer = 0xffff;
749 + state->delivery_system = SYS_DVBS; /*Default to DVB-S.*/
750 +
751 + /* check demod id */
752 + if(m88ds3103_check_id(state) == UNKNOW_ID){
753 + printk(KERN_ERR "Unable to find Montage chip\n");
754 + goto error3;
755 + }
756 +
757 + memcpy(&state->frontend.ops, &m88ds3103_ops,
758 + sizeof(struct dvb_frontend_ops));
759 + state->frontend.demodulator_priv = state;
760 +
761 + m88ds3103_initilaze(&state->frontend);
762 +
763 + return &state->frontend;
764 +
765 +error3:
766 + kfree(state);
767 +error2:
768 + return NULL;
769 +}
770 +EXPORT_SYMBOL(m88ds3103_attach);
771 +
772 +static int m88ds3103_set_carrier_offset(struct dvb_frontend *fe,
773 + s32 carrier_offset_khz)
774 +{
775 + struct m88ds3103_state *state = fe->demodulator_priv;
776 + s32 tmp;
777 +
778 + tmp = carrier_offset_khz;
779 + tmp *= 65536;
780 +
781 + tmp = (2*tmp + MT_FE_MCLK_KHZ) / (2*MT_FE_MCLK_KHZ);
782 +
783 + if (tmp < 0)
784 + tmp += 65536;
785 +
786 + m88ds3103_writereg(state, 0x5f, tmp >> 8);
787 + m88ds3103_writereg(state, 0x5e, tmp & 0xff);
788 +
789 + return 0;
790 +}
791 +
792 +static int m88ds3103_set_symrate(struct dvb_frontend *fe)
793 +{
794 + struct m88ds3103_state *state = fe->demodulator_priv;
795 + struct dtv_frontend_properties *c = &fe->dtv_property_cache;
796 + u16 value;
797 +
798 + value = (((c->symbol_rate / 1000) << 15) + (MT_FE_MCLK_KHZ / 4)) / (MT_FE_MCLK_KHZ / 2);
799 + m88ds3103_writereg(state, 0x61, value & 0x00ff);
800 + m88ds3103_writereg(state, 0x62, (value & 0xff00) >> 8);
801 +
802 + return 0;
803 +}
804 +
805 +static int m88ds3103_set_CCI(struct dvb_frontend *fe)
806 +{
807 + struct m88ds3103_state *state = fe->demodulator_priv;
808 + u8 tmp;
809 +
810 + tmp = m88ds3103_readreg(state, 0x56);
811 + tmp &= ~0x01;
812 + m88ds3103_writereg(state, 0x56, tmp);
813 +
814 + tmp = m88ds3103_readreg(state, 0x76);
815 + tmp &= ~0x80;
816 + m88ds3103_writereg(state, 0x76, tmp);
817 +
818 + return 0;
819 +}
820 +
821 +static int m88ds3103_init_reg(struct m88ds3103_state *state, const u8 *p_reg_tab, u32 size)
822 +{
823 + u32 i;
824 +
825 + for(i = 0; i < size; i+=2)
826 + m88ds3103_writereg(state, p_reg_tab[i], p_reg_tab[i+1]);
827 +
828 + return 0;
829 +}
830 +
831 +static int m88ds3103_get_locked_sym_rate(struct m88ds3103_state *state, u32 *sym_rate_KSs)
832 +{
833 + u16 tmp;
834 + u32 sym_rate_tmp;
835 + u8 val_0x6d, val_0x6e;
836 +
837 + val_0x6d = m88ds3103_readreg(state, 0x6d);
838 + val_0x6e = m88ds3103_readreg(state, 0x6e);
839 +
840 + tmp = (u16)((val_0x6e<<8) | val_0x6d);
841 +
842 + sym_rate_tmp = (u32)(tmp * MT_FE_MCLK_KHZ);
843 + sym_rate_tmp = (u32)(sym_rate_tmp / (1<<16));
844 + *sym_rate_KSs = sym_rate_tmp;
845 +
846 + return 0;
847 +}
848 +
849 +static int m88ds3103_get_channel_info(struct m88ds3103_state *state, u8 *p_mode, u8 *p_coderate)
850 +{
851 + u8 tmp, val_0x7E;
852 +
853 + if(state->delivery_system == SYS_DVBS2){
854 + val_0x7E = m88ds3103_readreg(state, 0x7e);
855 + tmp = (u8)((val_0x7E&0xC0) >> 6);
856 + *p_mode = tmp;
857 + tmp = (u8)(val_0x7E & 0x0f);
858 + *p_coderate = tmp;
859 + } else {
860 + *p_mode = 0;
861 + tmp = m88ds3103_readreg(state, 0xe6);
862 + tmp = (u8)(tmp >> 5);
863 + *p_coderate = tmp;
864 + }
865 +
866 + return 0;
867 +}
868 +
869 +static int m88ds3103_set_clock_ratio(struct m88ds3103_state *state)
870 +{
871 + u8 val, mod_fac, tmp1, tmp2;
872 + u32 input_datarate, locked_sym_rate_KSs;
873 + u32 MClk_KHz = 96000;
874 + u8 mod_mode, code_rate, divid_ratio = 0;
875 +
876 + locked_sym_rate_KSs = 0;
877 + m88ds3103_get_locked_sym_rate(state, &locked_sym_rate_KSs);
878 + if(locked_sym_rate_KSs == 0)
879 + return 0;
880 +
881 + m88ds3103_get_channel_info(state, &mod_mode, &code_rate);
882 +
883 + if (state->delivery_system == SYS_DVBS2)
884 + {
885 + switch(mod_mode) {
886 + case 1: mod_fac = 3; break;
887 + case 2: mod_fac = 4; break;
888 + case 3: mod_fac = 5; break;
889 + default: mod_fac = 2; break;
890 + }
891 +
892 + switch(code_rate) {
893 + case 0: input_datarate = locked_sym_rate_KSs*mod_fac/8/4; break;
894 + case 1: input_datarate = locked_sym_rate_KSs*mod_fac/8/3; break;
895 + case 2: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/5; break;
896 + case 3: input_datarate = locked_sym_rate_KSs*mod_fac/8/2; break;
897 + case 4: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/5; break;
898 + case 5: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3; break;
899 + case 6: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/4; break;
900 + case 7: input_datarate = locked_sym_rate_KSs*mod_fac*4/8/5; break;
901 + case 8: input_datarate = locked_sym_rate_KSs*mod_fac*5/8/6; break;
902 + case 9: input_datarate = locked_sym_rate_KSs*mod_fac*8/8/9; break;
903 + case 10: input_datarate = locked_sym_rate_KSs*mod_fac*9/8/10; break;
904 + default: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3; break;
905 + }
906 +
907 + if(state->demod_id == DS3000_ID)
908 + input_datarate = input_datarate * 115 / 100;
909 +
910 + if(input_datarate < 4800) {tmp1 = 15;tmp2 = 15;} //4.8MHz TS clock
911 + else if(input_datarate < 4966) {tmp1 = 14;tmp2 = 15;} //4.966MHz TS clock
912 + else if(input_datarate < 5143) {tmp1 = 14;tmp2 = 14;} //5.143MHz TS clock
913 + else if(input_datarate < 5333) {tmp1 = 13;tmp2 = 14;} //5.333MHz TS clock
914 + else if(input_datarate < 5538) {tmp1 = 13;tmp2 = 13;} //5.538MHz TS clock
915 + else if(input_datarate < 5760) {tmp1 = 12;tmp2 = 13;} //5.76MHz TS clock allan 0809
916 + else if(input_datarate < 6000) {tmp1 = 12;tmp2 = 12;} //6MHz TS clock
917 + else if(input_datarate < 6260) {tmp1 = 11;tmp2 = 12;} //6.26MHz TS clock
918 + else if(input_datarate < 6545) {tmp1 = 11;tmp2 = 11;} //6.545MHz TS clock
919 + else if(input_datarate < 6857) {tmp1 = 10;tmp2 = 11;} //6.857MHz TS clock
920 + else if(input_datarate < 7200) {tmp1 = 10;tmp2 = 10;} //7.2MHz TS clock
921 + else if(input_datarate < 7578) {tmp1 = 9;tmp2 = 10;} //7.578MHz TS clock
922 + else if(input_datarate < 8000) {tmp1 = 9;tmp2 = 9;} //8MHz TS clock
923 + else if(input_datarate < 8470) {tmp1 = 8;tmp2 = 9;} //8.47MHz TS clock
924 + else if(input_datarate < 9000) {tmp1 = 8;tmp2 = 8;} //9MHz TS clock
925 + else if(input_datarate < 9600) {tmp1 = 7;tmp2 = 8;} //9.6MHz TS clock
926 + else if(input_datarate < 10285) {tmp1 = 7;tmp2 = 7;} //10.285MHz TS clock
927 + else if(input_datarate < 12000) {tmp1 = 6;tmp2 = 6;} //12MHz TS clock
928 + else if(input_datarate < 14400) {tmp1 = 5;tmp2 = 5;} //14.4MHz TS clock
929 + else if(input_datarate < 18000) {tmp1 = 4;tmp2 = 4;} //18MHz TS clock
930 + else {tmp1 = 3;tmp2 = 3;} //24MHz TS clock
931 +
932 + if(state->demod_id == DS3000_ID) {
933 + val = (u8)((tmp1<<4) + tmp2);
934 + m88ds3103_writereg(state, 0xfe, val);
935 + } else {
936 + tmp1 = m88ds3103_readreg(state, 0x22);
937 + tmp2 = m88ds3103_readreg(state, 0x24);
938 +
939 + tmp1 >>= 6;
940 + tmp1 &= 0x03;
941 + tmp2 >>= 6;
942 + tmp2 &= 0x03;
943 +
944 + if((tmp1 == 0x00) && (tmp2 == 0x01))
945 + MClk_KHz = 144000;
946 + else if((tmp1 == 0x00) && (tmp2 == 0x03))
947 + MClk_KHz = 72000;
948 + else if((tmp1 == 0x01) && (tmp2 == 0x01))
949 + MClk_KHz = 115200;
950 + else if((tmp1 == 0x02) && (tmp2 == 0x01))
951 + MClk_KHz = 96000;
952 + else if((tmp1 == 0x03) && (tmp2 == 0x00))
953 + MClk_KHz = 192000;
954 + else
955 + return 0;
956 +
957 + if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/
958 + input_datarate = 5200;
959 +
960 + if(input_datarate != 0)
961 + divid_ratio = (u8)(MClk_KHz / input_datarate);
962 + else
963 + divid_ratio = 0xFF;
964 +
965 + if(divid_ratio > 128)
966 + divid_ratio = 128;
967 +
968 + if(divid_ratio < 2)
969 + divid_ratio = 2;
970 +
971 + tmp1 = (u8)(divid_ratio / 2);
972 + tmp2 = (u8)(divid_ratio / 2);
973 +
974 + if((divid_ratio % 2) != 0)
975 + tmp2 += 1;
976 +
977 + tmp1 -= 1;
978 + tmp2 -= 1;
979 +
980 + tmp1 &= 0x3f;
981 + tmp2 &= 0x3f;
982 +
983 + val = m88ds3103_readreg(state, 0xfe);
984 + val &= 0xF0;
985 + val |= (tmp2 >> 2) & 0x0f;
986 + m88ds3103_writereg(state, 0xfe, val);
987 +
988 + val = (u8)((tmp2 & 0x03) << 6);
989 + val |= tmp1;
990 + m88ds3103_writereg(state, 0xea, val);
991 + }
992 + } else {
993 + mod_fac = 2;
994 +
995 + switch(code_rate) {
996 + case 4: input_datarate = locked_sym_rate_KSs*mod_fac/2/8; break;
997 + case 3: input_datarate = locked_sym_rate_KSs*mod_fac*2/3/8; break;
998 + case 2: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8; break;
999 + case 1: input_datarate = locked_sym_rate_KSs*mod_fac*5/6/8; break;
1000 + case 0: input_datarate = locked_sym_rate_KSs*mod_fac*7/8/8; break;
1001 + default: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8; break;
1002 + }
1003 +
1004 + if(state->demod_id == DS3000_ID)
1005 + input_datarate = input_datarate * 115 / 100;
1006 +
1007 + if(input_datarate < 6857) {tmp1 = 7;tmp2 = 7;} //6.857MHz TS clock
1008 + else if(input_datarate < 7384) {tmp1 = 6;tmp2 = 7;} //7.384MHz TS clock
1009 + else if(input_datarate < 8000) {tmp1 = 6;tmp2 = 6;} //8MHz TS clock
1010 + else if(input_datarate < 8727) {tmp1 = 5;tmp2 = 6;} //8.727MHz TS clock
1011 + else if(input_datarate < 9600) {tmp1 = 5;tmp2 = 5;} //9.6MHz TS clock
1012 + else if(input_datarate < 10666) {tmp1 = 4;tmp2 = 5;} //10.666MHz TS clock
1013 + else if(input_datarate < 12000) {tmp1 = 4;tmp2 = 4;} //12MHz TS clock
1014 + else if(input_datarate < 13714) {tmp1 = 3;tmp2 = 4;} //13.714MHz TS clock
1015 + else if(input_datarate < 16000) {tmp1 = 3;tmp2 = 3;} //16MHz TS clock
1016 + else if(input_datarate < 19200) {tmp1 = 2;tmp2 = 3;} //19.2MHz TS clock
1017 + else {tmp1 = 2;tmp2 = 2;} //24MHz TS clock
1018 +
1019 + if(state->demod_id == DS3000_ID) {
1020 + val = m88ds3103_readreg(state, 0xfe);
1021 + val &= 0xc0;
1022 + val |= ((u8)((tmp1<<3) + tmp2));
1023 + m88ds3103_writereg(state, 0xfe, val);
1024 + } else {
1025 + if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/
1026 + input_datarate = 5200;
1027 +
1028 + if(input_datarate != 0)
1029 + divid_ratio = (u8)(MClk_KHz / input_datarate);
1030 + else
1031 + divid_ratio = 0xFF;
1032 +
1033 + if(divid_ratio > 128)
1034 + divid_ratio = 128;
1035 +
1036 + if(divid_ratio < 2)
1037 + divid_ratio = 2;
1038 +
1039 + tmp1 = (u8)(divid_ratio / 2);
1040 + tmp2 = (u8)(divid_ratio / 2);
1041 +
1042 + if((divid_ratio % 2) != 0)
1043 + tmp2 += 1;
1044 +
1045 + tmp1 -= 1;
1046 + tmp2 -= 1;
1047 +
1048 + tmp1 &= 0x3f;
1049 + tmp2 &= 0x3f;
1050 +
1051 + val = m88ds3103_readreg(state, 0xfe);
1052 + val &= 0xF0;
1053 + val |= (tmp2 >> 2) & 0x0f;
1054 + m88ds3103_writereg(state, 0xfe, val);
1055 +
1056 + val = (u8)((tmp2 & 0x03) << 6);
1057 + val |= tmp1;
1058 + m88ds3103_writereg(state, 0xea, val);
1059 + }
1060 + }
1061 + return 0;
1062 +}
1063 +
1064 +static int m88ds3103_demod_connect(struct dvb_frontend *fe, s32 carrier_offset_khz)
1065 +{
1066 + struct m88ds3103_state *state = fe->demodulator_priv;
1067 + struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1068 + u16 value;
1069 + u8 val1,val2,data;
1070 +
1071 + dprintk("connect delivery system = %d\n", state->delivery_system);
1072 +
1073 + /* ds3000 global reset */
1074 + m88ds3103_writereg(state, 0x07, 0x80);
1075 + m88ds3103_writereg(state, 0x07, 0x00);
1076 + /* ds3000 build-in uC reset */
1077 + m88ds3103_writereg(state, 0xb2, 0x01);
1078 + /* ds3000 software reset */
1079 + m88ds3103_writereg(state, 0x00, 0x01);
1080 +
1081 + switch (state->delivery_system) {
1082 + case SYS_DVBS:
1083 + /* initialise the demod in DVB-S mode */
1084 + if(state->demod_id == DS3000_ID){
1085 + m88ds3103_init_reg(state, ds3000_dvbs_init_tab, sizeof(ds3000_dvbs_init_tab));
1086 +
1087 + value = m88ds3103_readreg(state, 0xfe);
1088 + value &= 0xc0;
1089 + value |= 0x1b;
1090 + m88ds3103_writereg(state, 0xfe, value);
1091 +
1092 + if(state->config->ci_mode)
1093 + val1 = 0x80;
1094 + else if(state->config->ts_mode)
1095 + val1 = 0x60;
1096 + else
1097 + val1 = 0x20;
1098 + m88ds3103_writereg(state, 0xfd, val1);
1099 +
1100 + }else if(state->demod_id == DS3103_ID){
1101 + m88ds3103_init_reg(state, ds3103_dvbs_init_tab, sizeof(ds3103_dvbs_init_tab));
1102 +
1103 + /* set ts clock */
1104 + if(state->config->ci_mode == 2){
1105 + val1 = 6; val2 = 6;
1106 + }else if(state->config->ts_mode == 0) {
1107 + val1 = 3; val2 = 3;
1108 + }else{
1109 + val1 = 0; val2 = 0;
1110 + }
1111 + val1 -= 1; val2 -= 1;
1112 + val1 &= 0x3f; val2 &= 0x3f;
1113 + data = m88ds3103_readreg(state, 0xfe);
1114 + data &= 0xf0;
1115 + data |= (val2 >> 2) & 0x0f;
1116 + m88ds3103_writereg(state, 0xfe, data);
1117 + data = (val2 & 0x03) << 6;
1118 + data |= val1;
1119 + m88ds3103_writereg(state, 0xea, data);
1120 +
1121 + m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
1122 + m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
1123 +
1124 + /* set master clock */
1125 + val1 = m88ds3103_readreg(state, 0x22);
1126 + val2 = m88ds3103_readreg(state, 0x24);
1127 +
1128 + val1 &= 0x3f;
1129 + val2 &= 0x3f;
1130 + val1 |= 0x80;
1131 + val2 |= 0x40;
1132 +
1133 + m88ds3103_writereg(state, 0x22, val1);
1134 + m88ds3103_writereg(state, 0x24, val2);
1135 +
1136 + if(state->config->ci_mode)
1137 + val1 = 0x03;
1138 + else if(state->config->ts_mode)
1139 + val1 = 0x06;
1140 + else
1141 + val1 = 0x42;
1142 + m88ds3103_writereg(state, 0xfd, val1);
1143 + }
1144 + break;
1145 + case SYS_DVBS2:
1146 + /* initialise the demod in DVB-S2 mode */
1147 + if(state->demod_id == DS3000_ID){
1148 + m88ds3103_init_reg(state, ds3000_dvbs2_init_tab, sizeof(ds3000_dvbs2_init_tab));
1149 +
1150 + if (c->symbol_rate >= 30000000)
1151 + m88ds3103_writereg(state, 0xfe, 0x54);
1152 + else
1153 + m88ds3103_writereg(state, 0xfe, 0x98);
1154 +
1155 + }else if(state->demod_id == DS3103_ID){
1156 + m88ds3103_init_reg(state, ds3103_dvbs2_init_tab, sizeof(ds3103_dvbs2_init_tab));
1157 +
1158 + /* set ts clock */
1159 + if(state->config->ci_mode == 2){
1160 + val1 = 6; val2 = 6;
1161 + }else if(state->config->ts_mode == 0){
1162 + val1 = 5; val2 = 4;
1163 + }else{
1164 + val1 = 0; val2 = 0;
1165 + }
1166 + val1 -= 1; val2 -= 1;
1167 + val1 &= 0x3f; val2 &= 0x3f;
1168 + data = m88ds3103_readreg(state, 0xfe);
1169 + data &= 0xf0;
1170 + data |= (val2 >> 2) & 0x0f;
1171 + m88ds3103_writereg(state, 0xfe, data);
1172 + data = (val2 & 0x03) << 6;
1173 + data |= val1;
1174 + m88ds3103_writereg(state, 0xea, data);
1175 +
1176 + m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
1177 + m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
1178 +
1179 + /* set master clock */
1180 + val1 = m88ds3103_readreg(state, 0x22);
1181 + val2 = m88ds3103_readreg(state, 0x24);
1182 +
1183 + val1 &= 0x3f;
1184 + val2 &= 0x3f;
1185 + if((state->config->ci_mode == 2) || (state->config->ts_mode == 1)){
1186 + val1 |= 0x80;
1187 + val2 |= 0x40;
1188 + }else{
1189 + if (c->symbol_rate >= 28000000){
1190 + val1 |= 0xc0;
1191 + }else if (c->symbol_rate >= 18000000){
1192 + val2 |= 0x40;
1193 + }else{
1194 + val1 |= 0x80;
1195 + val2 |= 0x40;
1196 + }
1197 + }
1198 + m88ds3103_writereg(state, 0x22, val1);
1199 + m88ds3103_writereg(state, 0x24, val2);
1200 + }
1201 +
1202 + if(state->config->ci_mode)
1203 + val1 = 0x03;
1204 + else if(state->config->ts_mode)
1205 + val1 = 0x06;
1206 + else
1207 + val1 = 0x42;
1208 + m88ds3103_writereg(state, 0xfd, val1);
1209 +
1210 + break;
1211 + default:
1212 + return 1;
1213 + }
1214 + /* disable 27MHz clock output */
1215 + m88ds3103_writereg(state, 0x29, 0x80);
1216 + /* enable ac coupling */
1217 + m88ds3103_writereg(state, 0x25, 0x8a);
1218 +
1219 + if ((c->symbol_rate / 1000) <= 3000){
1220 + m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 32 * 100 / 64 = 400*/
1221 + m88ds3103_writereg(state, 0xc8, 0x20);
1222 + m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/
1223 + m88ds3103_writereg(state, 0xc7, 0x00);
1224 + }else if((c->symbol_rate / 1000) <= 10000){
1225 + m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 16 * 100 / 64 = 200*/
1226 + m88ds3103_writereg(state, 0xc8, 0x10);
1227 + m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/
1228 + m88ds3103_writereg(state, 0xc7, 0x00);
1229 + }else{
1230 + m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 6 * 100 / 64 = 75*/
1231 + m88ds3103_writereg(state, 0xc8, 0x06);
1232 + m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/
1233 + m88ds3103_writereg(state, 0xc7, 0x00);
1234 + }
1235 +
1236 + m88ds3103_set_symrate(fe);
1237 +
1238 + m88ds3103_set_CCI(fe);
1239 +
1240 + m88ds3103_set_carrier_offset(fe, carrier_offset_khz);
1241 +
1242 + /* ds3000 out of software reset */
1243 + m88ds3103_writereg(state, 0x00, 0x00);
1244 + /* start ds3000 build-in uC */
1245 + m88ds3103_writereg(state, 0xb2, 0x00);
1246 +
1247 + return 0;
1248 +}
1249 +
1250 +static int m88ds3103_set_frontend(struct dvb_frontend *fe)
1251 +{
1252 + struct m88ds3103_state *state = fe->demodulator_priv;
1253 + struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1254 +
1255 + int i;
1256 + fe_status_t status;
1257 + u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf, div4, capCode, changePLL;
1258 + s32 offset_khz, lpf_offset_KHz;
1259 + u16 value, ndiv, lpf_coeff;
1260 + u32 f3db, gdiv28, realFreq;
1261 + u8 RFgain;
1262 +
1263 + dprintk("%s() ", __func__);
1264 + dprintk("c frequency = %d\n", c->frequency);
1265 + dprintk("symbol rate = %d\n", c->symbol_rate);
1266 + dprintk("delivery system = %d\n", c->delivery_system);
1267 +
1268 + realFreq = c->frequency;
1269 + lpf_offset_KHz = 0;
1270 + if(c->symbol_rate < 5000000){
1271 + lpf_offset_KHz = FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz;
1272 + realFreq += FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz;
1273 + }
1274 +
1275 + if (state->config->set_ts_params)
1276 + state->config->set_ts_params(fe, 0);
1277 +
1278 + div4 = 0;
1279 + RFgain = 0;
1280 + if(state->tuner_id == TS2022_ID){
1281 + m88ds3103_tuner_writereg(state, 0x10, 0x0a);
1282 + m88ds3103_tuner_writereg(state, 0x11, 0x40);
1283 + if (realFreq < 1103000) {
1284 + m88ds3103_tuner_writereg(state, 0x10, 0x1b);
1285 + div4 = 1;
1286 + ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ;
1287 + }else {
1288 + ndiv = (realFreq * (6 + 8) * 2)/MT_FE_CRYSTAL_KHZ;
1289 + }
1290 + ndiv = ndiv + ndiv%2;
1291 + if(ndiv < 4095)
1292 + ndiv = ndiv - 1024;
1293 + else if (ndiv < 6143)
1294 + ndiv = ndiv + 1024;
1295 + else
1296 + ndiv = ndiv + 3072;
1297 +
1298 + m88ds3103_tuner_writereg(state, 0x01, (ndiv & 0x3f00) >> 8);
1299 + }else{
1300 + m88ds3103_tuner_writereg(state, 0x10, 0x00);
1301 + if (realFreq < 1146000){
1302 + m88ds3103_tuner_writereg(state, 0x10, 0x11);
1303 + div4 = 1;
1304 + ndiv = (realFreq * (6 + 8) * 4) / MT_FE_CRYSTAL_KHZ;
1305 + }else{
1306 + m88ds3103_tuner_writereg(state, 0x10, 0x01);
1307 + ndiv = (realFreq * (6 + 8) * 2) / MT_FE_CRYSTAL_KHZ;
1308 + }
1309 + ndiv = ndiv + ndiv%2;
1310 + ndiv = ndiv - 1024;
1311 + m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8)&0x0f);
1312 + }
1313 + /* set pll */
1314 + m88ds3103_tuner_writereg(state, 0x02, ndiv & 0x00ff);
1315 + m88ds3103_tuner_writereg(state, 0x03, 0x06);
1316 + m88ds3103_tuner_writereg(state, 0x51, 0x0f);
1317 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1318 + m88ds3103_tuner_writereg(state, 0x50, 0x10);
1319 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1320 +
1321 + if(state->tuner_id == TS2022_ID){
1322 + if(( realFreq >= 1650000 ) && (realFreq <= 1850000)){
1323 + msleep(5);
1324 + value = m88ds3103_tuner_readreg(state, 0x14);
1325 + value &= 0x7f;
1326 + if(value < 64){
1327 + m88ds3103_tuner_writereg(state, 0x10, 0x82);
1328 + m88ds3103_tuner_writereg(state, 0x11, 0x6f);
1329 +
1330 + m88ds3103_tuner_writereg(state, 0x51, 0x0f);
1331 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1332 + m88ds3103_tuner_writereg(state, 0x50, 0x10);
1333 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1334 + }
1335 + }
1336 + msleep(5);
1337 + value = m88ds3103_tuner_readreg(state, 0x14);
1338 + value &= 0x1f;
1339 +
1340 + if(value > 19){
1341 + value = m88ds3103_tuner_readreg(state, 0x10);
1342 + value &= 0x1d;
1343 + m88ds3103_tuner_writereg(state, 0x10, value);
1344 + }
1345 + }else{
1346 + msleep(5);
1347 + value = m88ds3103_tuner_readreg(state, 0x66);
1348 + changePLL = (((value & 0x80) >> 7) != div4);
1349 +
1350 + if(changePLL){
1351 + m88ds3103_tuner_writereg(state, 0x10, 0x11);
1352 + div4 = 1;
1353 + ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ;
1354 + ndiv = ndiv + ndiv%2;
1355 + ndiv = ndiv - 1024;
1356 +
1357 + m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8) & 0x0f);
1358 + m88ds3103_tuner_writereg(state, 0x02, ndiv & 0xff);
1359 +
1360 + m88ds3103_tuner_writereg(state, 0x51, 0x0f);
1361 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1362 + m88ds3103_tuner_writereg(state, 0x50, 0x10);
1363 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1364 + }
1365 + }
1366 + /*set the RF gain*/
1367 + if(state->tuner_id == TS2020_ID)
1368 + m88ds3103_tuner_writereg(state, 0x60, 0x79);
1369 +
1370 + m88ds3103_tuner_writereg(state, 0x51, 0x17);
1371 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1372 + m88ds3103_tuner_writereg(state, 0x50, 0x08);
1373 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1374 + msleep(5);
1375 +
1376 + if(state->tuner_id == TS2020_ID){
1377 + RFgain = m88ds3103_tuner_readreg(state, 0x3d);
1378 + RFgain &= 0x0f;
1379 + if(RFgain < 15){
1380 + if(RFgain < 4)
1381 + RFgain = 0;
1382 + else
1383 + RFgain = RFgain -3;
1384 + value = ((RFgain << 3) | 0x01) & 0x79;
1385 + m88ds3103_tuner_writereg(state, 0x60, value);
1386 + m88ds3103_tuner_writereg(state, 0x51, 0x17);
1387 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1388 + m88ds3103_tuner_writereg(state, 0x50, 0x08);
1389 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1390 + }
1391 + }
1392 +
1393 + /* set the LPF */
1394 + if(state->tuner_id == TS2022_ID){
1395 + m88ds3103_tuner_writereg(state, 0x25, 0x00);
1396 + m88ds3103_tuner_writereg(state, 0x27, 0x70);
1397 + m88ds3103_tuner_writereg(state, 0x41, 0x09);
1398 + m88ds3103_tuner_writereg(state, 0x08, 0x0b);
1399 + }
1400 +
1401 + f3db = ((c->symbol_rate / 1000) *135) / 200 + 2000;
1402 + f3db += lpf_offset_KHz;
1403 + if (f3db < 7000)
1404 + f3db = 7000;
1405 + if (f3db > 40000)
1406 + f3db = 40000;
1407 +
1408 + gdiv28 = (MT_FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000;
1409 + m88ds3103_tuner_writereg(state, 0x04, gdiv28 & 0xff);
1410 + m88ds3103_tuner_writereg(state, 0x51, 0x1b);
1411 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1412 + m88ds3103_tuner_writereg(state, 0x50, 0x04);
1413 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1414 + msleep(5);
1415 +
1416 + value = m88ds3103_tuner_readreg(state, 0x26);
1417 + capCode = value & 0x3f;
1418 + if(state->tuner_id == TS2022_ID){
1419 + m88ds3103_tuner_writereg(state, 0x41, 0x0d);
1420 +
1421 + m88ds3103_tuner_writereg(state, 0x51, 0x1b);
1422 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1423 + m88ds3103_tuner_writereg(state, 0x50, 0x04);
1424 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1425 +
1426 + msleep(2);
1427 +
1428 + value = m88ds3103_tuner_readreg(state, 0x26);
1429 + value &= 0x3f;
1430 + value = (capCode + value) / 2;
1431 + }
1432 + else
1433 + value = capCode;
1434 +
1435 + gdiv28 = gdiv28 * 207 / (value * 2 + 151);
1436 + mlpf_max = gdiv28 * 135 / 100;
1437 + mlpf_min = gdiv28 * 78 / 100;
1438 + if (mlpf_max > 63)
1439 + mlpf_max = 63;
1440 +
1441 + if(state->tuner_id == TS2022_ID)
1442 + lpf_coeff = 3200;
1443 + else
1444 + lpf_coeff = 2766;
1445 +
1446 + nlpf = (f3db * gdiv28 * 2 / lpf_coeff / (MT_FE_CRYSTAL_KHZ / 1000) + 1) / 2 ;
1447 + if (nlpf > 23) nlpf = 23;
1448 + if (nlpf < 1) nlpf = 1;
1449 +
1450 + lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2;
1451 +
1452 + if (lpf_mxdiv < mlpf_min){
1453 + nlpf++;
1454 + lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2;
1455 + }
1456 +
1457 + if (lpf_mxdiv > mlpf_max)
1458 + lpf_mxdiv = mlpf_max;
1459 +
1460 + m88ds3103_tuner_writereg(state, 0x04, lpf_mxdiv);
1461 + m88ds3103_tuner_writereg(state, 0x06, nlpf);
1462 + m88ds3103_tuner_writereg(state, 0x51, 0x1b);
1463 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1464 + m88ds3103_tuner_writereg(state, 0x50, 0x04);
1465 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1466 + msleep(5);
1467 +
1468 + if(state->tuner_id == TS2022_ID){
1469 + msleep(2);
1470 + value = m88ds3103_tuner_readreg(state, 0x26);
1471 + capCode = value & 0x3f;
1472 +
1473 + m88ds3103_tuner_writereg(state, 0x41, 0x09);
1474 +
1475 + m88ds3103_tuner_writereg(state, 0x51, 0x1b);
1476 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1477 + m88ds3103_tuner_writereg(state, 0x50, 0x04);
1478 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1479 +
1480 + msleep(2);
1481 + value = m88ds3103_tuner_readreg(state, 0x26);
1482 + value &= 0x3f;
1483 + value = (capCode + value) / 2;
1484 +
1485 + value = value | 0x80;
1486 + m88ds3103_tuner_writereg(state, 0x25, value);
1487 + m88ds3103_tuner_writereg(state, 0x27, 0x30);
1488 +
1489 + m88ds3103_tuner_writereg(state, 0x08, 0x09);
1490 + }
1491 +
1492 + /* Set the BB gain */
1493 + m88ds3103_tuner_writereg(state, 0x51, 0x1e);
1494 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1495 + m88ds3103_tuner_writereg(state, 0x50, 0x01);
1496 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1497 + if(state->tuner_id == TS2020_ID){
1498 + if(RFgain == 15){
1499 + msleep(40);
1500 + value = m88ds3103_tuner_readreg(state, 0x21);
1501 + value &= 0x0f;
1502 + if(value < 3){
1503 + m88ds3103_tuner_writereg(state, 0x60, 0x61);
1504 + m88ds3103_tuner_writereg(state, 0x51, 0x17);
1505 + m88ds3103_tuner_writereg(state, 0x51, 0x1f);
1506 + m88ds3103_tuner_writereg(state, 0x50, 0x08);
1507 + m88ds3103_tuner_writereg(state, 0x50, 0x00);
1508 + }
1509 + }
1510 + }
1511 + msleep(60);
1512 +
1513 + offset_khz = (ndiv - ndiv % 2 + 1024) * MT_FE_CRYSTAL_KHZ
1514 + / (6 + 8) / (div4 + 1) / 2 - realFreq;
1515 +
1516 + m88ds3103_demod_connect(fe, offset_khz+lpf_offset_KHz);
1517 +
1518 + for (i = 0; i < 30 ; i++) {
1519 + m88ds3103_read_status(fe, &status);
1520 + if (status & FE_HAS_LOCK){
1521 + break;
1522 + }
1523 + msleep(20);
1524 + }
1525 +
1526 + if((status & FE_HAS_LOCK) == 0){
1527 + state->delivery_system = (state->delivery_system == SYS_DVBS) ? SYS_DVBS2 : SYS_DVBS;
1528 + m88ds3103_demod_connect(fe, offset_khz);
1529 +
1530 + for (i = 0; i < 30 ; i++) {
1531 + m88ds3103_read_status(fe, &status);
1532 + if (status & FE_HAS_LOCK){
1533 + break;
1534 + }
1535 + msleep(20);
1536 + }
1537 + }
1538 +
1539 + if (status & FE_HAS_LOCK){
1540 + if(state->config->ci_mode == 2)
1541 + m88ds3103_set_clock_ratio(state);
1542 + if(state->config->start_ctrl){
1543 + if(state->first_lock == 0){
1544 + state->config->start_ctrl(fe);
1545 + state->first_lock = 1;
1546 + }
1547 + }
1548 + }
1549 +
1550 + return 0;
1551 +}
1552 +
1553 +static int m88ds3103_tune(struct dvb_frontend *fe,
1554 + bool re_tune,
1555 + unsigned int mode_flags,
1556 + unsigned int *delay,
1557 + fe_status_t *status)
1558 +{
1559 + *delay = HZ / 5;
1560 +
1561 + dprintk("%s() ", __func__);
1562 + dprintk("re_tune = %d\n", re_tune);
1563 +
1564 + if (re_tune) {
1565 + int ret = m88ds3103_set_frontend(fe);
1566 + if (ret)
1567 + return ret;
1568 + }
1569 +
1570 + return m88ds3103_read_status(fe, status);
1571 +}
1572 +
1573 +static enum dvbfe_algo m88ds3103_get_algo(struct dvb_frontend *fe)
1574 +{
1575 + return DVBFE_ALGO_HW;
1576 +}
1577 +
1578 + /*
1579 + * Power config will reset and load initial firmware if required
1580 + */
1581 +static int m88ds3103_initilaze(struct dvb_frontend *fe)
1582 +{
1583 + struct m88ds3103_state *state = fe->demodulator_priv;
1584 + int ret;
1585 +
1586 + dprintk("%s()\n", __func__);
1587 + /* hard reset */
1588 + m88ds3103_writereg(state, 0x07, 0x80);
1589 + m88ds3103_writereg(state, 0x07, 0x00);
1590 + msleep(1);
1591 +
1592 + m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08));
1593 + msleep(1);
1594 +
1595 + if(state->tuner_id == TS2020_ID){
1596 + /* TS2020 init */
1597 + m88ds3103_tuner_writereg(state, 0x42, 0x73);
1598 + msleep(2);
1599 + m88ds3103_tuner_writereg(state, 0x05, 0x01);
1600 + m88ds3103_tuner_writereg(state, 0x62, 0xb5);
1601 + m88ds3103_tuner_writereg(state, 0x07, 0x02);
1602 + m88ds3103_tuner_writereg(state, 0x08, 0x01);
1603 + }
1604 + else if(state->tuner_id == TS2022_ID){
1605 + /* TS2022 init */
1606 + m88ds3103_tuner_writereg(state, 0x62, 0x6c);
1607 + msleep(2);
1608 + m88ds3103_tuner_writereg(state, 0x42, 0x6c);
1609 + msleep(2);
1610 + m88ds3103_tuner_writereg(state, 0x7d, 0x9d);
1611 + m88ds3103_tuner_writereg(state, 0x7c, 0x9a);
1612 + m88ds3103_tuner_writereg(state, 0x7a, 0x76);
1613 +
1614 + m88ds3103_tuner_writereg(state, 0x3b, 0x01);
1615 + m88ds3103_tuner_writereg(state, 0x63, 0x88);
1616 +
1617 + m88ds3103_tuner_writereg(state, 0x61, 0x85);
1618 + m88ds3103_tuner_writereg(state, 0x22, 0x30);
1619 + m88ds3103_tuner_writereg(state, 0x30, 0x40);
1620 + m88ds3103_tuner_writereg(state, 0x20, 0x23);
1621 + m88ds3103_tuner_writereg(state, 0x24, 0x02);
1622 + m88ds3103_tuner_writereg(state, 0x12, 0xa0);
1623 + }
1624 +
1625 + if(state->demod_id == DS3103_ID){
1626 + m88ds3103_writereg(state, 0x07, 0xe0);
1627 + m88ds3103_writereg(state, 0x07, 0x00);
1628 + msleep(1);
1629 + }
1630 + m88ds3103_writereg(state, 0xb2, 0x01);
1631 +
1632 + /* Load the firmware if required */
1633 + ret = m88ds3103_load_firmware(fe);
1634 + if (ret != 0){
1635 + printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
1636 + return ret;
1637 + }
1638 + if(state->demod_id == DS3103_ID){
1639 + m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
1640 + m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
1641 + }
1642 +
1643 + return 0;
1644 +}
1645 +
1646 +/*
1647 + * Initialise or wake up device
1648 + */
1649 +static int m88ds3103_initfe(struct dvb_frontend *fe)
1650 +{
1651 + struct m88ds3103_state *state = fe->demodulator_priv;
1652 + u8 val;
1653 +
1654 + dprintk("%s()\n", __func__);
1655 +
1656 + /* 1st step to wake up demod */
1657 + m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08));
1658 + m88ds3103_writereg(state, 0x04, 0xfe & m88ds3103_readreg(state, 0x04));
1659 + m88ds3103_writereg(state, 0x23, 0xef & m88ds3103_readreg(state, 0x23));
1660 +
1661 + /* 2nd step to wake up tuner */
1662 + val = m88ds3103_tuner_readreg(state, 0x00) & 0xff;
1663 + if((val & 0x01) == 0){
1664 + m88ds3103_tuner_writereg(state, 0x00, 0x01);
1665 + msleep(50);
1666 + }
1667 + m88ds3103_tuner_writereg(state, 0x00, 0x03);
1668 + msleep(50);
1669 +
1670 + return 0;
1671 +}
1672 +
1673 +/* Put device to sleep */
1674 +static int m88ds3103_sleep(struct dvb_frontend *fe)
1675 +{
1676 + struct m88ds3103_state *state = fe->demodulator_priv;
1677 +
1678 + dprintk("%s()\n", __func__);
1679 +
1680 + /* 1st step to sleep tuner */
1681 + m88ds3103_tuner_writereg(state, 0x00, 0x00);
1682 +
1683 + /* 2nd step to sleep demod */
1684 + m88ds3103_writereg(state, 0x08, 0xfe & m88ds3103_readreg(state, 0x08));
1685 + m88ds3103_writereg(state, 0x04, 0x01 | m88ds3103_readreg(state, 0x04));
1686 + m88ds3103_writereg(state, 0x23, 0x10 | m88ds3103_readreg(state, 0x23));
1687 +
1688 +
1689 + return 0;
1690 +}
1691 +
1692 +static struct dvb_frontend_ops m88ds3103_ops = {
1693 + .delsys = { SYS_DVBS, SYS_DVBS2},
1694 + .info = {
1695 + .name = "Montage DS3103/TS2022",
1696 + .type = FE_QPSK,
1697 + .frequency_min = 950000,
1698 + .frequency_max = 2150000,
1699 + .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1700 + .frequency_tolerance = 5000,
1701 + .symbol_rate_min = 1000000,
1702 + .symbol_rate_max = 45000000,
1703 + .caps = FE_CAN_INVERSION_AUTO |
1704 + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1705 + FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1706 + FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1707 + FE_CAN_2G_MODULATION |
1708 + FE_CAN_QPSK | FE_CAN_RECOVER
1709 + },
1710 +
1711 + .release = m88ds3103_release,
1712 +
1713 + .init = m88ds3103_initfe,
1714 + .sleep = m88ds3103_sleep,
1715 + .read_status = m88ds3103_read_status,
1716 + .read_ber = m88ds3103_read_ber,
1717 + .read_signal_strength = m88ds3103_read_signal_strength,
1718 + .read_snr = m88ds3103_read_snr,
1719 + .read_ucblocks = m88ds3103_read_ucblocks,
1720 + .set_tone = m88ds3103_set_tone,
1721 + .set_voltage = m88ds3103_set_voltage,
1722 + .diseqc_send_master_cmd = m88ds3103_send_diseqc_msg,
1723 + .diseqc_send_burst = m88ds3103_diseqc_send_burst,
1724 + .get_frontend_algo = m88ds3103_get_algo,
1725 + .tune = m88ds3103_tune,
1726 + .set_frontend = m88ds3103_set_frontend,
1727 +};
1728 +
1729 +MODULE_DESCRIPTION("DVB Frontend module for Montage DS3103/TS2022 hardware");
1730 +MODULE_AUTHOR("Max nibble");
1731 +MODULE_LICENSE("GPL");
1732 diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.h v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.h
1733 --- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.h 1970-01-01 01:00:00.000000000 +0100
1734 +++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.h 2012-11-24 13:34:43.716679774 +0100
1735 @@ -0,0 +1,53 @@
1736 +/*
1737 + Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
1738 +
1739 + This program is free software; you can redistribute it and/or modify
1740 + it under the terms of the GNU General Public License as published by
1741 + the Free Software Foundation; either version 2 of the License, or
1742 + (at your option) any later version.
1743 +
1744 + This program is distributed in the hope that it will be useful,
1745 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1746 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1747 + GNU General Public License for more details.
1748 +
1749 + You should have received a copy of the GNU General Public License
1750 + along with this program; if not, write to the Free Software
1751 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1752 + */
1753 +
1754 +#ifndef M88DS3103_H
1755 +#define M88DS3103_H
1756 +
1757 +#include <linux/dvb/frontend.h>
1758 +
1759 +struct m88ds3103_config {
1760 + /* the demodulator's i2c address */
1761 + u8 demod_address;
1762 + u8 ci_mode;
1763 + u8 pin_ctrl;
1764 + u8 ts_mode; /* 0: Parallel, 1: Serial */
1765 +
1766 + /* Set device param to start dma */
1767 + int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
1768 + /* Start to transfer data */
1769 + int (*start_ctrl)(struct dvb_frontend *fe);
1770 + /* Set LNB voltage */
1771 + int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
1772 +};
1773 +
1774 +#if defined(CONFIG_DVB_M88DS3103) || \
1775 + (defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE))
1776 +extern struct dvb_frontend *m88ds3103_attach(
1777 + const struct m88ds3103_config *config,
1778 + struct i2c_adapter *i2c);
1779 +#else
1780 +static inline struct dvb_frontend *m88ds3103_attach(
1781 + const struct m88ds3103_config *config,
1782 + struct i2c_adapter *i2c)
1783 +{
1784 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
1785 + return NULL;
1786 +}
1787 +#endif /* CONFIG_DVB_M88DS3103 */
1788 +#endif /* M88DS3103_H */
1789 diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103_priv.h v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103_priv.h
1790 --- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103_priv.h 1970-01-01 01:00:00.000000000 +0100
1791 +++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103_priv.h 2012-11-24 13:34:43.716679774 +0100
1792 @@ -0,0 +1,403 @@
1793 +/*
1794 + Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
1795 +
1796 + This program is free software; you can redistribute it and/or modify
1797 + it under the terms of the GNU General Public License as published by
1798 + the Free Software Foundation; either version 2 of the License, or
1799 + (at your option) any later version.
1800 +
1801 + This program is distributed in the hope that it will be useful,
1802 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1803 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1804 + GNU General Public License for more details.
1805 +
1806 + You should have received a copy of the GNU General Public License
1807 + along with this program; if not, write to the Free Software
1808 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1809 + */
1810 +
1811 +#ifndef M88DS3103_PRIV_H
1812 +#define M88DS3103_PRIV_H
1813 +
1814 +#define FW_DOWN_SIZE 32
1815 +#define FW_DOWN_LOOP (8192/FW_DOWN_SIZE)
1816 +#define DS3103_DEFAULT_FIRMWARE "dvb-fe-ds3103.fw"
1817 +#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds300x.fw"
1818 +#define MT_FE_MCLK_KHZ 96000 /* in kHz */
1819 +#define MT_FE_CRYSTAL_KHZ 27000 /* in kHz */
1820 +#define FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz 3000
1821 +#define DS3000_ID 0x3000
1822 +#define DS3103_ID 0x3103
1823 +#define TS2020_ID 0x2020
1824 +#define TS2022_ID 0x2022
1825 +#define UNKNOW_ID 0x0000
1826 +
1827 +struct m88ds3103_state {
1828 + struct i2c_adapter *i2c;
1829 + const struct m88ds3103_config *config;
1830 +
1831 + struct dvb_frontend frontend;
1832 +
1833 + u32 preBer;
1834 + u8 skip_fw_load;
1835 + u8 first_lock; /* The first time of signal lock */
1836 + u16 demod_id; /* demod chip type */
1837 + u16 tuner_id; /* tuner chip type */
1838 + fe_delivery_system_t delivery_system;
1839 +};
1840 +
1841 +/* For M88DS3103 demod dvbs mode.*/
1842 +static u8 ds3103_dvbs_init_tab[] = {
1843 + 0x23, 0x07,
1844 + 0x08, 0x03,
1845 + 0x0c, 0x02,
1846 + 0x21, 0x54,
1847 + 0x25, 0x82,
1848 + 0x27, 0x31,
1849 + 0x30, 0x08,
1850 + 0x31, 0x40,
1851 + 0x32, 0x32,
1852 + 0x33, 0x35,
1853 + 0x35, 0xff,
1854 + 0x3a, 0x00,
1855 + 0x37, 0x10,
1856 + 0x38, 0x10,
1857 + 0x39, 0x02,
1858 + 0x42, 0x60,
1859 + 0x4a, 0x80,
1860 + 0x4b, 0x04,
1861 + 0x4d, 0x91,
1862 + 0x5d, 0xc8,
1863 + 0x50, 0x36,
1864 + 0x51, 0x36,
1865 + 0x52, 0x36,
1866 + 0x53, 0x36,
1867 + 0x63, 0x0f,
1868 + 0x64, 0x30,
1869 + 0x65, 0x40,
1870 + 0x68, 0x26,
1871 + 0x69, 0x4c,
1872 + 0x70, 0x20,
1873 + 0x71, 0x70,
1874 + 0x72, 0x04,
1875 + 0x73, 0x00,
1876 + 0x70, 0x40,
1877 + 0x71, 0x70,
1878 + 0x72, 0x04,
1879 + 0x73, 0x00,
1880 + 0x70, 0x60,
1881 + 0x71, 0x70,
1882 + 0x72, 0x04,
1883 + 0x73, 0x00,
1884 + 0x70, 0x80,
1885 + 0x71, 0x70,
1886 + 0x72, 0x04,
1887 + 0x73, 0x00,
1888 + 0x70, 0xa0,
1889 + 0x71, 0x70,
1890 + 0x72, 0x04,
1891 + 0x73, 0x00,
1892 + 0x70, 0x1f,
1893 + 0x76, 0x38,
1894 + 0x77, 0xa6,
1895 + 0x78, 0x0c,
1896 + 0x79, 0x80,
1897 + 0x7f, 0x14,
1898 + 0x7c, 0x00,
1899 + 0xae, 0x82,
1900 + 0x80, 0x64,
1901 + 0x81, 0x66,
1902 + 0x82, 0x44,
1903 + 0x85, 0x04,
1904 + 0xcd, 0xf4,
1905 + 0x90, 0x33,
1906 + 0xa0, 0x44,
1907 + 0xc0, 0x08,
1908 + 0xc3, 0x10,
1909 + 0xc4, 0x08,
1910 + 0xc5, 0xf0,
1911 + 0xc6, 0xff,
1912 + 0xc7, 0x00,
1913 + 0xc8, 0x1a,
1914 + 0xc9, 0x80,
1915 + 0xe0, 0xf8,
1916 + 0xe6, 0x8b,
1917 + 0xd0, 0x40,
1918 + 0xf8, 0x20,
1919 + 0xfa, 0x0f,
1920 + 0x00, 0x00,
1921 + 0xbd, 0x01,
1922 + 0xb8, 0x00,
1923 +};
1924 +/* For M88DS3103 demod dvbs2 mode.*/
1925 +static u8 ds3103_dvbs2_init_tab[] = {
1926 + 0x23, 0x07,
1927 + 0x08, 0x07,
1928 + 0x0c, 0x02,
1929 + 0x21, 0x54,
1930 + 0x25, 0x82,
1931 + 0x27, 0x31,
1932 + 0x30, 0x08,
1933 + 0x32, 0x32,
1934 + 0x33, 0x35,
1935 + 0x35, 0xff,
1936 + 0x3a, 0x00,
1937 + 0x37, 0x10,
1938 + 0x38, 0x10,
1939 + 0x39, 0x02,
1940 + 0x42, 0x60,
1941 + 0x4a, 0x80,
1942 + 0x4b, 0x04,
1943 + 0x4d, 0x91,
1944 + 0x5d, 0xc8,
1945 + 0x50, 0x36,
1946 + 0x51, 0x36,
1947 + 0x52, 0x36,
1948 + 0x53, 0x36,
1949 + 0x63, 0x0f,
1950 + 0x64, 0x10,
1951 + 0x65, 0x20,
1952 + 0x68, 0x46,
1953 + 0x69, 0xcd,
1954 + 0x70, 0x20,
1955 + 0x71, 0x70,
1956 + 0x72, 0x04,
1957 + 0x73, 0x00,
1958 + 0x70, 0x40,
1959 + 0x71, 0x70,
1960 + 0x72, 0x04,
1961 + 0x73, 0x00,
1962 + 0x70, 0x60,
1963 + 0x71, 0x70,
1964 + 0x72, 0x04,
1965 + 0x73, 0x00,
1966 + 0x70, 0x80,
1967 + 0x71, 0x70,
1968 + 0x72, 0x04,
1969 + 0x73, 0x00,
1970 + 0x70, 0xa0,
1971 + 0x71, 0x70,
1972 + 0x72, 0x04,
1973 + 0x73, 0x00,
1974 + 0x70, 0x1f,
1975 + 0x76, 0x38,
1976 + 0x77, 0xa6,
1977 + 0x78, 0x0c,
1978 + 0x79, 0x80,
1979 + 0x7f, 0x14,
1980 + 0x85, 0x08,
1981 + 0xcd, 0xf4,
1982 + 0x90, 0x33,
1983 + 0x86, 0x00,
1984 + 0x87, 0x0f,
1985 + 0x89, 0x00,
1986 + 0x8b, 0x44,
1987 + 0x8c, 0x66,
1988 + 0x9d, 0xc1,
1989 + 0x8a, 0x10,
1990 + 0xad, 0x40,
1991 + 0xa0, 0x44,
1992 + 0xc0, 0x08,
1993 + 0xc1, 0x10,
1994 + 0xc2, 0x08,
1995 + 0xc3, 0x10,
1996 + 0xc4, 0x08,
1997 + 0xc5, 0xf0,
1998 + 0xc6, 0xff,
1999 + 0xc7, 0x00,
2000 + 0xc8, 0x1a,
2001 + 0xc9, 0x80,
2002 + 0xca, 0x23,
2003 + 0xcb, 0x24,
2004 + 0xcc, 0xf4,
2005 + 0xce, 0x74,
2006 + 0x00, 0x00,
2007 + 0xbd, 0x01,
2008 + 0xb8, 0x00,
2009 +};
2010 +
2011 +/* For M88DS3000 demod dvbs mode.*/
2012 +static u8 ds3000_dvbs_init_tab[] = {
2013 + 0x23, 0x05,
2014 + 0x08, 0x03,
2015 + 0x0c, 0x02,
2016 + 0x21, 0x54,
2017 + 0x25, 0x82,
2018 + 0x27, 0x31,
2019 + 0x30, 0x08,
2020 + 0x31, 0x40,
2021 + 0x32, 0x32,
2022 + 0x33, 0x35,
2023 + 0x35, 0xff,
2024 + 0x3a, 0x00,
2025 + 0x37, 0x10,
2026 + 0x38, 0x10,
2027 + 0x39, 0x02,
2028 + 0x42, 0x60,
2029 + 0x4a, 0x40,
2030 + 0x4b, 0x04,
2031 + 0x4d, 0x91,
2032 + 0x5d, 0xc8,
2033 + 0x50, 0x77,
2034 + 0x51, 0x77,
2035 + 0x52, 0x36,
2036 + 0x53, 0x36,
2037 + 0x56, 0x01,
2038 + 0x63, 0x47,
2039 + 0x64, 0x30,
2040 + 0x65, 0x40,
2041 + 0x68, 0x26,
2042 + 0x69, 0x4c,
2043 + 0x70, 0x20,
2044 + 0x71, 0x70,
2045 + 0x72, 0x04,
2046 + 0x73, 0x00,
2047 + 0x70, 0x40,
2048 + 0x71, 0x70,
2049 + 0x72, 0x04,
2050 + 0x73, 0x00,
2051 + 0x70, 0x60,
2052 + 0x71, 0x70,
2053 + 0x72, 0x04,
2054 + 0x73, 0x00,
2055 + 0x70, 0x80,
2056 + 0x71, 0x70,
2057 + 0x72, 0x04,
2058 + 0x73, 0x00,
2059 + 0x70, 0xa0,
2060 + 0x71, 0x70,
2061 + 0x72, 0x04,
2062 + 0x73, 0x00,
2063 + 0x70, 0x1f,
2064 + 0x76, 0x00,
2065 + 0x77, 0xd1,
2066 + 0x78, 0x0c,
2067 + 0x79, 0x80,
2068 + 0x7f, 0x04,
2069 + 0x7c, 0x00,
2070 + 0x80, 0x86,
2071 + 0x81, 0xa6,
2072 + 0x85, 0x04,
2073 + 0xcd, 0xf4,
2074 + 0x90, 0x33,
2075 + 0xa0, 0x44,
2076 + 0xc0, 0x18,
2077 + 0xc3, 0x10,
2078 + 0xc4, 0x08,
2079 + 0xc5, 0x80,
2080 + 0xc6, 0x80,
2081 + 0xc7, 0x0a,
2082 + 0xc8, 0x1a,
2083 + 0xc9, 0x80,
2084 + 0xfe, 0xb6,
2085 + 0xe0, 0xf8,
2086 + 0xe6, 0x8b,
2087 + 0xd0, 0x40,
2088 + 0xf8, 0x20,
2089 + 0xfa, 0x0f,
2090 + 0xad, 0x20,
2091 + 0xae, 0x07,
2092 + 0xb8, 0x00,
2093 +};
2094 +
2095 +/* For M88DS3000 demod dvbs2 mode.*/
2096 +static u8 ds3000_dvbs2_init_tab[] = {
2097 + 0x23, 0x0f,
2098 + 0x08, 0x07,
2099 + 0x0c, 0x02,
2100 + 0x21, 0x54,
2101 + 0x25, 0x82,
2102 + 0x27, 0x31,
2103 + 0x30, 0x08,
2104 + 0x31, 0x32,
2105 + 0x32, 0x32,
2106 + 0x33, 0x35,
2107 + 0x35, 0xff,
2108 + 0x3a, 0x00,
2109 + 0x37, 0x10,
2110 + 0x38, 0x10,
2111 + 0x39, 0x02,
2112 + 0x42, 0x60,
2113 + 0x4a, 0x80,
2114 + 0x4b, 0x04,
2115 + 0x4d, 0x91,
2116 + 0x5d, 0x88,
2117 + 0x50, 0x36,
2118 + 0x51, 0x36,
2119 + 0x52, 0x36,
2120 + 0x53, 0x36,
2121 + 0x63, 0x60,
2122 + 0x64, 0x10,
2123 + 0x65, 0x10,
2124 + 0x68, 0x04,
2125 + 0x69, 0x29,
2126 + 0x70, 0x20,
2127 + 0x71, 0x70,
2128 + 0x72, 0x04,
2129 + 0x73, 0x00,
2130 + 0x70, 0x40,
2131 + 0x71, 0x70,
2132 + 0x72, 0x04,
2133 + 0x73, 0x00,
2134 + 0x70, 0x60,
2135 + 0x71, 0x70,
2136 + 0x72, 0x04,
2137 + 0x73, 0x00,
2138 + 0x70, 0x80,
2139 + 0x71, 0x70,
2140 + 0x72, 0x04,
2141 + 0x73, 0x00,
2142 + 0x70, 0xa0,
2143 + 0x71, 0x70,
2144 + 0x72, 0x04,
2145 + 0x73, 0x00,
2146 + 0x70, 0x1f,
2147 + 0xa0, 0x44,
2148 + 0xc0, 0x08,
2149 + 0xc1, 0x10,
2150 + 0xc2, 0x08,
2151 + 0xc3, 0x10,
2152 + 0xc4, 0x08,
2153 + 0xc5, 0xf0,
2154 + 0xc6, 0xf0,
2155 + 0xc7, 0x0a,
2156 + 0xc8, 0x1a,
2157 + 0xc9, 0x80,
2158 + 0xca, 0x23,
2159 + 0xcb, 0x24,
2160 + 0xce, 0x74,
2161 + 0x56, 0x01,
2162 + 0x90, 0x03,
2163 + 0x76, 0x80,
2164 + 0x77, 0x42,
2165 + 0x78, 0x0a,
2166 + 0x79, 0x80,
2167 + 0xad, 0x40,
2168 + 0xae, 0x07,
2169 + 0x7f, 0xd4,
2170 + 0x7c, 0x00,
2171 + 0x80, 0xa8,
2172 + 0x81, 0xda,
2173 + 0x7c, 0x01,
2174 + 0x80, 0xda,
2175 + 0x81, 0xec,
2176 + 0x7c, 0x02,
2177 + 0x80, 0xca,
2178 + 0x81, 0xeb,
2179 + 0x7c, 0x03,
2180 + 0x80, 0xba,
2181 + 0x81, 0xdb,
2182 + 0x85, 0x08,
2183 + 0x86, 0x00,
2184 + 0x87, 0x02,
2185 + 0x89, 0x80,
2186 + 0x8b, 0x44,
2187 + 0x8c, 0xaa,
2188 + 0x8a, 0x10,
2189 + 0xba, 0x00,
2190 + 0xf5, 0x04,
2191 + 0xd2, 0x32,
2192 + 0xb8, 0x00,
2193 +};
2194 +
2195 +#endif /* M88DS3103_PRIV_H */
2196 diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Makefile v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Makefile
2197 --- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Makefile 2012-08-17 05:45:27.000000000 +0200
2198 +++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Makefile 2012-11-24 13:34:43.716679774 +0100
2199 @@ -102,4 +102,7 @@
2200 obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
2201 obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
2202 obj-$(CONFIG_DVB_AF9033) += af9033.o
2203 +obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o
2204 +
2205 +
2206
2207 diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/Makefile v4l-dvb-20120916/linux/drivers/media/rc/keymaps/Makefile
2208 --- v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/Makefile 2012-05-21 05:45:41.000000000 +0200
2209 +++ v4l-dvb-20120916/linux/drivers/media/rc/keymaps/Makefile 2012-11-24 13:34:43.716679774 +0100
2210 @@ -27,6 +27,7 @@
2211 rc-dm1105-nec.o \
2212 rc-dntv-live-dvb-t.o \
2213 rc-dntv-live-dvbt-pro.o \
2214 + rc-dvbsky.o \
2215 rc-em-terratec.o \
2216 rc-encore-enltv2.o \
2217 rc-encore-enltv.o \
2218 diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/rc-dvbsky.c v4l-dvb-20120916/linux/drivers/media/rc/keymaps/rc-dvbsky.c
2219 --- v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/rc-dvbsky.c 1970-01-01 01:00:00.000000000 +0100
2220 +++ v4l-dvb-20120916/linux/drivers/media/rc/keymaps/rc-dvbsky.c 2012-11-24 13:34:43.716679774 +0100
2221 @@ -0,0 +1,78 @@
2222 +/* rc-dvbsky.c - Keytable for Dvbsky Remote Controllers
2223 + *
2224 + * keymap imported from ir-keymaps.c
2225 + *
2226 + *
2227 + * Copyright (c) 2010-2011 by Mauro Carvalho Chehab <mchehab@redhat.com>
2228 + *
2229 + * This program is free software; you can redistribute it and/or modify
2230 + * it under the terms of the GNU General Public License as published by
2231 + * the Free Software Foundation; either version 2 of the License, or
2232 + * (at your option) any later version.
2233 + */
2234 +
2235 +#include <media/rc-map.h>
2236 +#include <linux/module.h>
2237 +/*
2238 + * This table contains the complete RC5 code, instead of just the data part
2239 + */
2240 +
2241 +static struct rc_map_table rc5_dvbsky[] = {
2242 + { 0x0000, KEY_0 },
2243 + { 0x0001, KEY_1 },
2244 + { 0x0002, KEY_2 },
2245 + { 0x0003, KEY_3 },
2246 + { 0x0004, KEY_4 },
2247 + { 0x0005, KEY_5 },
2248 + { 0x0006, KEY_6 },
2249 + { 0x0007, KEY_7 },
2250 + { 0x0008, KEY_8 },
2251 + { 0x0009, KEY_9 },
2252 + { 0x000a, KEY_MUTE },
2253 + { 0x000d, KEY_OK },
2254 + { 0x000b, KEY_STOP },
2255 + { 0x000c, KEY_EXIT },
2256 + { 0x000e, KEY_CAMERA }, /*Snap shot*/
2257 + { 0x000f, KEY_SUBTITLE }, /*PIP*/
2258 + { 0x0010, KEY_VOLUMEUP },
2259 + { 0x0011, KEY_VOLUMEDOWN },
2260 + { 0x0012, KEY_FAVORITES },
2261 + { 0x0013, KEY_LIST }, /*Info*/
2262 + { 0x0016, KEY_PAUSE },
2263 + { 0x0017, KEY_PLAY },
2264 + { 0x001f, KEY_RECORD },
2265 + { 0x0020, KEY_CHANNELDOWN },
2266 + { 0x0021, KEY_CHANNELUP },
2267 + { 0x0025, KEY_POWER2 },
2268 + { 0x0026, KEY_REWIND },
2269 + { 0x0027, KEY_FASTFORWARD },
2270 + { 0x0029, KEY_LAST },
2271 + { 0x002b, KEY_MENU },
2272 + { 0x002c, KEY_EPG },
2273 + { 0x002d, KEY_ZOOM },
2274 +};
2275 +
2276 +static struct rc_map_list rc5_dvbsky_map = {
2277 + .map = {
2278 + .scan = rc5_dvbsky,
2279 + .size = ARRAY_SIZE(rc5_dvbsky),
2280 + .rc_type = RC_TYPE_RC5,
2281 + .name = RC_MAP_DVBSKY,
2282 + }
2283 +};
2284 +
2285 +static int __init init_rc_map_rc5_dvbsky(void)
2286 +{
2287 + return rc_map_register(&rc5_dvbsky_map);
2288 +}
2289 +
2290 +static void __exit exit_rc_map_rc5_dvbsky(void)
2291 +{
2292 + rc_map_unregister(&rc5_dvbsky_map);
2293 +}
2294 +
2295 +module_init(init_rc_map_rc5_dvbsky)
2296 +module_exit(exit_rc_map_rc5_dvbsky)
2297 +
2298 +MODULE_LICENSE("GPL");
2299 +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
2300 diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/dw2102.c v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/dw2102.c
2301 --- v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/dw2102.c 2012-08-14 05:45:22.000000000 +0200
2302 +++ v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/dw2102.c 2012-11-24 15:44:13.269971182 +0100
2303 @@ -3,6 +3,7 @@
2304 * TeVii S600, S630, S650, S660, S480,
2305 * Prof 1100, 7500,
2306 * Geniatech SU3000 Cards
2307 + * Bestunar US683x HD, DVBsky S860, S960 USB
2308 * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by)
2309 *
2310 * This program is free software; you can redistribute it and/or modify it
2311 @@ -19,6 +20,7 @@
2312 #include "stb6000.h"
2313 #include "eds1547.h"
2314 #include "cx24116.h"
2315 +#include "m88ds3103.h"
2316 #include "tda1002x.h"
2317 #include "mt312.h"
2318 #include "zl10039.h"
2319 @@ -786,7 +788,7 @@
2320 struct su3000_state *state = (struct su3000_state *)d->priv;
2321 u8 obuf[] = {0xde, 0};
2322
2323 - info("%s: %d, initialized %d\n", __func__, i, state->initialized);
2324 + info("%s: %d, initialized %d", __func__, i, state->initialized);
2325
2326 if (i && !state->initialized) {
2327 state->initialized = 1;
2328 @@ -824,7 +826,40 @@
2329 else
2330 mac[i] = ibuf[0];
2331
2332 - debug_dump(mac, 6, printk);
2333 + debug_dump(mac, 6, deb_xfer);
2334 + }
2335 +
2336 + return 0;
2337 +}
2338 +
2339 +static int dvbsky_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
2340 +{
2341 + int i;
2342 + u8 obuf[] = { 0x1e, 0x00 };
2343 + u8 ibuf[] = { 0 };
2344 + struct i2c_msg msg[] = {
2345 + {
2346 + .addr = 0x51,
2347 + .flags = 0,
2348 + .buf = obuf,
2349 + .len = 2,
2350 + }, {
2351 + .addr = 0x51,
2352 + .flags = I2C_M_RD,
2353 + .buf = ibuf,
2354 + .len = 1,
2355 +
2356 + }
2357 + };
2358 +
2359 + for (i = 0; i < 6; i++) {
2360 + obuf[1] = i;
2361 + if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
2362 + break;
2363 + else
2364 + mac[i] = ibuf[0];
2365 +
2366 + debug_dump(mac, 6, deb_xfer);
2367 }
2368
2369 return 0;
2370 @@ -835,7 +870,7 @@
2371 struct dvb_usb_device_description **desc,
2372 int *cold)
2373 {
2374 - info("%s\n", __func__);
2375 + info("%s", __func__);
2376
2377 *cold = 0;
2378 return 0;
2379 @@ -878,6 +913,43 @@
2380 return 0;
2381 }
2382
2383 +static int bstusb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
2384 +{
2385 +
2386 + struct dvb_usb_adapter *udev_adap =
2387 + (struct dvb_usb_adapter *)(fe->dvb->priv);
2388 +
2389 + u8 obuf[3] = { 0xe, 0x80, 0 };
2390 + u8 ibuf[] = { 0 };
2391 +
2392 + //info("US6830: %s!", __func__);
2393 +
2394 + if (voltage == SEC_VOLTAGE_OFF)
2395 + obuf[2] = 0;
2396 + else
2397 + obuf[2] = 1;
2398 +
2399 + if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 1, 0) < 0)
2400 + err("command 0x0e transfer failed.");
2401 +
2402 + return 0;
2403 +}
2404 +
2405 +static int bstusb_restart(struct dvb_frontend *fe)
2406 +{
2407 +
2408 + struct dvb_usb_adapter *udev_adap =
2409 + (struct dvb_usb_adapter *)(fe->dvb->priv);
2410 +
2411 + u8 obuf[3] = { 0x36, 3, 0 };
2412 + u8 ibuf[] = { 0 };
2413 +
2414 + if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 0, 0) < 0)
2415 + err("command 0x36 transfer failed.");
2416 +
2417 + return 0;
2418 +}
2419 +
2420 static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
2421 {
2422 static u8 led_off[] = { 0 };
2423 @@ -983,6 +1055,24 @@
2424 .ci_mode = 1,
2425 };
2426
2427 +static struct m88ds3103_config US6830_ds3103_config = {
2428 + .demod_address = 0x68,
2429 + .ci_mode = 1,
2430 + .pin_ctrl = 0x83,
2431 + .ts_mode = 0,
2432 + .start_ctrl = bstusb_restart,
2433 + .set_voltage = bstusb_set_voltage,
2434 +};
2435 +
2436 +static struct m88ds3103_config US6832_ds3103_config = {
2437 + .demod_address = 0x68,
2438 + .ci_mode = 1,
2439 + .pin_ctrl = 0x80,
2440 + .ts_mode = 0,
2441 + .start_ctrl = bstusb_restart,
2442 + .set_voltage = bstusb_set_voltage,
2443 +};
2444 +
2445 static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
2446 {
2447 struct dvb_tuner_ops *tuner_ops = NULL;
2448 @@ -1000,7 +1090,7 @@
2449 tuner_ops->set_bandwidth = stb6100_set_bandw;
2450 tuner_ops->get_bandwidth = stb6100_get_bandw;
2451 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
2452 - info("Attached STV0900+STB6100!\n");
2453 + info("Attached STV0900+STB6100!");
2454 return 0;
2455 }
2456 }
2457 @@ -1014,7 +1104,7 @@
2458 &dw2104_stv6110_config,
2459 &d->dev->i2c_adap)) {
2460 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
2461 - info("Attached STV0900+STV6110A!\n");
2462 + info("Attached STV0900+STV6110A!");
2463 return 0;
2464 }
2465 }
2466 @@ -1025,7 +1115,7 @@
2467 &d->dev->i2c_adap);
2468 if (d->fe_adap[0].fe != NULL) {
2469 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
2470 - info("Attached cx24116!\n");
2471 + info("Attached cx24116!");
2472 return 0;
2473 }
2474 }
2475 @@ -1034,7 +1124,7 @@
2476 &d->dev->i2c_adap);
2477 if (d->fe_adap[0].fe != NULL) {
2478 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
2479 - info("Attached DS3000!\n");
2480 + info("Attached DS3000!");
2481 return 0;
2482 }
2483
2484 @@ -1053,7 +1143,7 @@
2485 &d->dev->i2c_adap);
2486 if (d->fe_adap[0].fe != NULL) {
2487 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
2488 - info("Attached si21xx!\n");
2489 + info("Attached si21xx!");
2490 return 0;
2491 }
2492 }
2493 @@ -1065,7 +1155,7 @@
2494 if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
2495 &d->dev->i2c_adap)) {
2496 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
2497 - info("Attached stv0288!\n");
2498 + info("Attached stv0288!");
2499 return 0;
2500 }
2501 }
2502 @@ -1077,7 +1167,7 @@
2503 &d->dev->i2c_adap);
2504 if (d->fe_adap[0].fe != NULL) {
2505 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
2506 - info("Attached stv0299!\n");
2507 + info("Attached stv0299!");
2508 return 0;
2509 }
2510 }
2511 @@ -1089,7 +1179,7 @@
2512 d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
2513 &d->dev->i2c_adap, 0x48);
2514 if (d->fe_adap[0].fe != NULL) {
2515 - info("Attached tda10023!\n");
2516 + info("Attached tda10023!");
2517 return 0;
2518 }
2519 return -EIO;
2520 @@ -1103,7 +1193,7 @@
2521 if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
2522 &d->dev->i2c_adap)) {
2523 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
2524 - info("Attached zl100313+zl10039!\n");
2525 + info("Attached zl100313+zl10039!");
2526 return 0;
2527 }
2528 }
2529 @@ -1128,7 +1218,7 @@
2530
2531 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
2532
2533 - info("Attached stv0288+stb6000!\n");
2534 + info("Attached stv0288+stb6000!");
2535
2536 return 0;
2537
2538 @@ -1150,7 +1240,7 @@
2539
2540 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
2541
2542 - info("Attached ds3000+ds2020!\n");
2543 + info("Attached ds3000+ds2020!");
2544
2545 return 0;
2546 }
2547 @@ -1168,7 +1258,7 @@
2548
2549 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
2550
2551 - info("Attached STV0900+STB6100A!\n");
2552 + info("Attached STV0900+STB6100A!");
2553
2554 return 0;
2555 }
2556 @@ -1205,7 +1295,88 @@
2557 if (d->fe_adap[0].fe == NULL)
2558 return -EIO;
2559
2560 - info("Attached DS3000!\n");
2561 + info("Attached DS3000!");
2562 +
2563 + return 0;
2564 +}
2565 +
2566 +static int US6830_frontend_attach(struct dvb_usb_adapter *d)
2567 +{
2568 + u8 obuf[3] = { 0xe, 0x04, 1 };
2569 + u8 ibuf[] = { 0 };
2570 +
2571 + info("US6830: %s!\n", __func__);
2572 +
2573 + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
2574 + err("command 0x0e transfer failed.");
2575 +
2576 + obuf[0] = 0xe;
2577 + obuf[1] = 0x83;
2578 + obuf[2] = 0;
2579 +
2580 + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
2581 + err("command 0x0e transfer failed.");
2582 +
2583 + msleep(20);
2584 +
2585 + obuf[0] = 0xe;
2586 + obuf[1] = 0x83;
2587 + obuf[2] = 1;
2588 +
2589 + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
2590 + err("command 0x0e transfer failed.");
2591 +
2592 + obuf[0] = 0x51;
2593 +
2594 + if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
2595 + err("command 0x51 transfer failed.");
2596 +
2597 + d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6830_ds3103_config,
2598 + &d->dev->i2c_adap);
2599 + if (d->fe_adap[0].fe == NULL)
2600 + return -EIO;
2601 +
2602 + info("Attached M88DS3103!");
2603 +
2604 + return 0;
2605 +}
2606 +
2607 +static int US6832_frontend_attach(struct dvb_usb_adapter *d)
2608 +{
2609 + u8 obuf[3] = { 0xe, 0x04, 1 };
2610 + u8 ibuf[] = { 0 };
2611 +
2612 + info("US6832: %s!", __func__);
2613 +
2614 + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
2615 + err("command 0x0e transfer failed.");
2616 +
2617 + obuf[0] = 0xe;
2618 + obuf[1] = 0x83;
2619 + obuf[2] = 0;
2620 +
2621 + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
2622 + err("command 0x0e transfer failed.");
2623 +
2624 + msleep(20);
2625 + obuf[0] = 0xe;
2626 + obuf[1] = 0x83;
2627 + obuf[2] = 1;
2628 +
2629 + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
2630 + err("command 0x0e transfer failed.");
2631 +
2632 + obuf[0] = 0x51;
2633 +
2634 + if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
2635 + err("command 0x51 transfer failed.");
2636 +
2637 + d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6832_ds3103_config,
2638 + &d->dev->i2c_adap);
2639 + if (d->fe_adap[0].fe == NULL)
2640 + return -EIO;
2641 +
2642 + info("Attached M88DS3103!");
2643
2644 return 0;
2645 }
2646 @@ -1447,6 +1618,9 @@
2647 TEVII_S480_1,
2648 TEVII_S480_2,
2649 X3M_SPC1400HD,
2650 + BST_US6830HD,
2651 + BST_US6831HD,
2652 + BST_US6832HD,
2653 };
2654
2655 static struct usb_device_id dw2102_table[] = {
2656 @@ -1465,6 +1639,9 @@
2657 [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
2658 [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
2659 [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
2660 + [BST_US6830HD] = {USB_DEVICE(0x0572, 0x6830)},
2661 + [BST_US6831HD] = {USB_DEVICE(0x0572, 0x6831)},
2662 + [BST_US6832HD] = {USB_DEVICE(0x0572, 0x6832)},
2663 { }
2664 };
2665
2666 @@ -1870,6 +2047,106 @@
2667 }
2668 };
2669
2670 +static struct dvb_usb_device_properties US6830_properties = {
2671 + .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2672 + .usb_ctrl = DEVICE_SPECIFIC,
2673 + .size_of_priv = sizeof(struct su3000_state),
2674 + .power_ctrl = su3000_power_ctrl,
2675 + .num_adapters = 1,
2676 + .identify_state = su3000_identify_state,
2677 + .i2c_algo = &su3000_i2c_algo,
2678 +
2679 + .rc.legacy = {
2680 + .rc_map_table = rc_map_su3000_table,
2681 + .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
2682 + .rc_interval = 150,
2683 + .rc_query = dw2102_rc_query,
2684 + },
2685 +
2686 + .read_mac_address = dvbsky_read_mac_address,
2687 +
2688 + .generic_bulk_ctrl_endpoint = 0x01,
2689 +
2690 + .adapter = {
2691 + {
2692 + .num_frontends = 1,
2693 + .fe = {{
2694 + .streaming_ctrl = su3000_streaming_ctrl,
2695 + .frontend_attach = US6830_frontend_attach,
2696 + .stream = {
2697 + .type = USB_BULK,
2698 + .count = 8,
2699 + .endpoint = 0x82,
2700 + .u = {
2701 + .bulk = {
2702 + .buffersize = 4096,
2703 + }
2704 + }
2705 + }
2706 + }},
2707 + }
2708 + },
2709 + .num_device_descs = 2,
2710 + .devices = {
2711 + { "Bestunar US6830 HD",
2712 + { &dw2102_table[BST_US6830HD], NULL },
2713 + { NULL },
2714 + },
2715 + { "Bestunar US6831 HD",
2716 + { &dw2102_table[BST_US6831HD], NULL },
2717 + { NULL },
2718 + },
2719 + }
2720 +};
2721 +
2722 +static struct dvb_usb_device_properties US6832_properties = {
2723 + .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2724 + .usb_ctrl = DEVICE_SPECIFIC,
2725 + .size_of_priv = sizeof(struct su3000_state),
2726 + .power_ctrl = su3000_power_ctrl,
2727 + .num_adapters = 1,
2728 + .identify_state = su3000_identify_state,
2729 + .i2c_algo = &su3000_i2c_algo,
2730 +
2731 + .rc.legacy = {
2732 + .rc_map_table = rc_map_su3000_table,
2733 + .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
2734 + .rc_interval = 150,
2735 + .rc_query = dw2102_rc_query,
2736 + },
2737 +
2738 + .read_mac_address = dvbsky_read_mac_address,
2739 +
2740 + .generic_bulk_ctrl_endpoint = 0x01,
2741 +
2742 + .adapter = {
2743 + {
2744 + .num_frontends = 1,
2745 + .fe = {{
2746 + .streaming_ctrl = su3000_streaming_ctrl,
2747 + .frontend_attach = US6832_frontend_attach,
2748 + .stream = {
2749 + .type = USB_BULK,
2750 + .count = 8,
2751 + .endpoint = 0x82,
2752 + .u = {
2753 + .bulk = {
2754 + .buffersize = 4096,
2755 + }
2756 + }
2757 + }
2758 + }},
2759 + }
2760 + },
2761 + .num_device_descs = 1,
2762 + .devices = {
2763 + { "Bestunar US6832 HD",
2764 + { &dw2102_table[BST_US6832HD], NULL },
2765 + { NULL },
2766 + },
2767 + }
2768 +};
2769 +
2770 static int dw2102_probe(struct usb_interface *intf,
2771 const struct usb_device_id *id)
2772 {
2773 @@ -1926,6 +2203,10 @@
2774 0 == dvb_usb_device_init(intf, p7500,
2775 THIS_MODULE, NULL, adapter_nr) ||
2776 0 == dvb_usb_device_init(intf, &su3000_properties,
2777 + THIS_MODULE, NULL, adapter_nr) ||
2778 + 0 == dvb_usb_device_init(intf, &US6830_properties,
2779 + THIS_MODULE, NULL, adapter_nr) ||
2780 + 0 == dvb_usb_device_init(intf, &US6832_properties,
2781 THIS_MODULE, NULL, adapter_nr))
2782 return 0;
2783
2784 diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/Kconfig v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/Kconfig
2785 --- v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/Kconfig 2012-08-22 05:45:23.000000000 +0200
2786 +++ v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/Kconfig 2012-11-24 13:34:43.716679774 +0100
2787 @@ -1,3 +1,4 @@
2788 ++ select DVB_M88DS3103 if !DVB_FE_CUSTOMISE
2789 config DVB_USB
2790 tristate "Support for various USB DVB devices"
2791 depends on DVB_CORE && USB && I2C && RC_CORE
2792 @@ -261,6 +262,7 @@
2793 select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
2794 select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
2795 select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT
2796 + select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
2797 select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
2798 select DVB_SI21XX if MEDIA_SUBDRV_AUTOSELECT
2799 select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT
2800 diff -Naur v4l-dvb-20120916.ORG/linux/include/media/rc-map.h v4l-dvb-20120916/linux/include/media/rc-map.h
2801 --- v4l-dvb-20120916.ORG/linux/include/media/rc-map.h 2012-05-21 05:45:41.000000000 +0200
2802 +++ v4l-dvb-20120916/linux/include/media/rc-map.h 2012-11-24 13:34:43.716679774 +0100
2803 @@ -86,6 +86,7 @@
2804 #define RC_MAP_DM1105_NEC "rc-dm1105-nec"
2805 #define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro"
2806 #define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t"
2807 +#define RC_MAP_DVBSKY "rc-dvbsky"
2808 #define RC_MAP_EMPTY "rc-empty"
2809 #define RC_MAP_EM_TERRATEC "rc-em-terratec"
2810 #define RC_MAP_ENCORE_ENLTV2 "rc-encore-enltv2"