aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorIgor M. Liplianin <liplianin@me.by>2009-11-24 18:16:04 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:42:08 -0500
commit09ea33e5c696958e8b1ae6d5ab184476b16592f1 (patch)
tree2543aefab407abd23e1070e626c6f7a1333f83b5 /drivers/media
parent6afd2aa856eba0706176cecea1f989b1081c96dc (diff)
V4L/DVB (13493): TeVii S470 and TBS 6920 fixes
The new hardware design applied for this cards. Silicon Labs C8051F300 microcontroller is used for LNB power control. It connected to cx23885 GPIO pins: GPIO0 - P0.3 data GPIO1 - P0.2 reset GPIO2 - P0.1 clk GPIO3 - P0.0 busy Tevii S470 based on Montage Technology M88TS2020 digital satellite tuner and M88DS3000 advanced DVB-S/S2 demodulator. Signed-off-by: Igor M. Liplianin <liplianin@me.by> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/frontends/Kconfig7
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/ds3000.c1367
-rw-r--r--drivers/media/dvb/frontends/ds3000.h45
-rw-r--r--drivers/media/video/cx23885/Kconfig2
-rw-r--r--drivers/media/video/cx23885/Makefile2
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c14
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c20
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c38
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.c177
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.h2
-rw-r--r--drivers/media/video/cx23885/cx23885.h1
12 files changed, 1647 insertions, 29 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index fdc7926cb2db..58aac018f109 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -201,6 +201,13 @@ config DVB_SI21XX
201 help 201 help
202 A DVB-S tuner module. Say Y when you want to support this frontend. 202 A DVB-S tuner module. Say Y when you want to support this frontend.
203 203
204config DVB_DS3000
205 tristate "Montage Tehnology DS3000 based"
206 depends on DVB_CORE && I2C
207 default m if DVB_FE_CUSTOMISE
208 help
209 A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
210
204comment "DVB-T (terrestrial) frontends" 211comment "DVB-T (terrestrial) frontends"
205 depends on DVB_CORE 212 depends on DVB_CORE
206 213
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 390eec6d5d84..823482535d11 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -78,3 +78,4 @@ obj-$(CONFIG_DVB_STV090x) += stv090x.o
78obj-$(CONFIG_DVB_STV6110x) += stv6110x.o 78obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
79obj-$(CONFIG_DVB_ISL6423) += isl6423.o 79obj-$(CONFIG_DVB_ISL6423) += isl6423.o
80obj-$(CONFIG_DVB_EC100) += ec100.o 80obj-$(CONFIG_DVB_EC100) += ec100.o
81obj-$(CONFIG_DVB_DS3000) += ds3000.o
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
new file mode 100644
index 000000000000..cff3535566fe
--- /dev/null
+++ b/drivers/media/dvb/frontends/ds3000.c
@@ -0,0 +1,1367 @@
1/*
2 Montage Technology DS3000/TS2020 - DVBS/S2 Demodulator/Tuner driver
3 Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
4
5 Copyright (C) 2009 TurboSight.com
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/slab.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/firmware.h>
28
29#include "dvb_frontend.h"
30#include "ds3000.h"
31
32static int debug;
33
34#define dprintk(args...) \
35 do { \
36 if (debug) \
37 printk(args); \
38 } while (0)
39
40/* as of March 2009 current DS3000 firmware version is 1.78 */
41/* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */
42#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw"
43
44#define DS3000_SAMPLE_RATE 96000 /* in kHz */
45#define DS3000_XTAL_FREQ 27000 /* in kHz */
46
47/* Register values to initialise the demod in DVB-S mode */
48static u8 ds3000_dvbs_init_tab[] = {
49 0x23, 0x05,
50 0x08, 0x03,
51 0x0c, 0x00,
52 0x21, 0x54,
53 0x25, 0x82,
54 0x27, 0x31,
55 0x30, 0x08,
56 0x31, 0x40,
57 0x32, 0x32,
58 0x33, 0x35,
59 0x35, 0xff,
60 0x3a, 0x00,
61 0x37, 0x10,
62 0x38, 0x10,
63 0x39, 0x02,
64 0x42, 0x60,
65 0x4a, 0x40,
66 0x4b, 0x04,
67 0x4d, 0x91,
68 0x5d, 0xc8,
69 0x50, 0x77,
70 0x51, 0x77,
71 0x52, 0x36,
72 0x53, 0x36,
73 0x56, 0x01,
74 0x63, 0x43,
75 0x64, 0x30,
76 0x65, 0x40,
77 0x68, 0x26,
78 0x69, 0x4c,
79 0x70, 0x20,
80 0x71, 0x70,
81 0x72, 0x04,
82 0x73, 0x00,
83 0x70, 0x40,
84 0x71, 0x70,
85 0x72, 0x04,
86 0x73, 0x00,
87 0x70, 0x60,
88 0x71, 0x70,
89 0x72, 0x04,
90 0x73, 0x00,
91 0x70, 0x80,
92 0x71, 0x70,
93 0x72, 0x04,
94 0x73, 0x00,
95 0x70, 0xa0,
96 0x71, 0x70,
97 0x72, 0x04,
98 0x73, 0x00,
99 0x70, 0x1f,
100 0x76, 0x00,
101 0x77, 0xd1,
102 0x78, 0x0c,
103 0x79, 0x80,
104 0x7f, 0x04,
105 0x7c, 0x00,
106 0x80, 0x86,
107 0x81, 0xa6,
108 0x85, 0x04,
109 0xcd, 0xf4,
110 0x90, 0x33,
111 0xa0, 0x44,
112 0xc0, 0x18,
113 0xc3, 0x10,
114 0xc4, 0x08,
115 0xc5, 0x80,
116 0xc6, 0x80,
117 0xc7, 0x0a,
118 0xc8, 0x1a,
119 0xc9, 0x80,
120 0xfe, 0x92,
121 0xe0, 0xf8,
122 0xe6, 0x8b,
123 0xd0, 0x40,
124 0xf8, 0x20,
125 0xfa, 0x0f,
126 0xfd, 0x20,
127 0xad, 0x20,
128 0xae, 0x07,
129 0xb8, 0x00,
130};
131
132/* Register values to initialise the demod in DVB-S2 mode */
133static u8 ds3000_dvbs2_init_tab[] = {
134 0x23, 0x0f,
135 0x08, 0x07,
136 0x0c, 0x00,
137 0x21, 0x54,
138 0x25, 0x82,
139 0x27, 0x31,
140 0x30, 0x08,
141 0x31, 0x32,
142 0x32, 0x32,
143 0x33, 0x35,
144 0x35, 0xff,
145 0x3a, 0x00,
146 0x37, 0x10,
147 0x38, 0x10,
148 0x39, 0x02,
149 0x42, 0x60,
150 0x4a, 0x80,
151 0x4b, 0x04,
152 0x4d, 0x81,
153 0x5d, 0x88,
154 0x50, 0x36,
155 0x51, 0x36,
156 0x52, 0x36,
157 0x53, 0x36,
158 0x63, 0x60,
159 0x64, 0x10,
160 0x65, 0x10,
161 0x68, 0x04,
162 0x69, 0x29,
163 0x70, 0x20,
164 0x71, 0x70,
165 0x72, 0x04,
166 0x73, 0x00,
167 0x70, 0x40,
168 0x71, 0x70,
169 0x72, 0x04,
170 0x73, 0x00,
171 0x70, 0x60,
172 0x71, 0x70,
173 0x72, 0x04,
174 0x73, 0x00,
175 0x70, 0x80,
176 0x71, 0x70,
177 0x72, 0x04,
178 0x73, 0x00,
179 0x70, 0xa0,
180 0x71, 0x70,
181 0x72, 0x04,
182 0x73, 0x00,
183 0x70, 0x1f,
184 0xa0, 0x44,
185 0xc0, 0x08,
186 0xc1, 0x10,
187 0xc2, 0x08,
188 0xc3, 0x10,
189 0xc4, 0x08,
190 0xc5, 0xf0,
191 0xc6, 0xf0,
192 0xc7, 0x0a,
193 0xc8, 0x1a,
194 0xc9, 0x80,
195 0xca, 0x23,
196 0xcb, 0x24,
197 0xce, 0x74,
198 0x90, 0x03,
199 0x76, 0x80,
200 0x77, 0x42,
201 0x78, 0x0a,
202 0x79, 0x80,
203 0xad, 0x40,
204 0xae, 0x07,
205 0x7f, 0xd4,
206 0x7c, 0x00,
207 0x80, 0xa8,
208 0x81, 0xda,
209 0x7c, 0x01,
210 0x80, 0xda,
211 0x81, 0xec,
212 0x7c, 0x02,
213 0x80, 0xca,
214 0x81, 0xeb,
215 0x7c, 0x03,
216 0x80, 0xba,
217 0x81, 0xdb,
218 0x85, 0x08,
219 0x86, 0x00,
220 0x87, 0x02,
221 0x89, 0x80,
222 0x8b, 0x44,
223 0x8c, 0xaa,
224 0x8a, 0x10,
225 0xba, 0x00,
226 0xf5, 0x04,
227 0xfe, 0x44,
228 0xd2, 0x32,
229 0xb8, 0x00,
230};
231
232/* DS3000 doesn't need some parameters as input and auto-detects them */
233/* save input from the application of those parameters */
234struct ds3000_tuning {
235 u32 frequency;
236 u32 symbol_rate;
237 fe_spectral_inversion_t inversion;
238 enum fe_code_rate fec;
239
240 /* input values */
241 u8 inversion_val;
242 fe_modulation_t delivery;
243 u8 rolloff;
244};
245
246struct ds3000_state {
247 struct i2c_adapter *i2c;
248 const struct ds3000_config *config;
249
250 struct dvb_frontend frontend;
251
252 struct ds3000_tuning dcur;
253 struct ds3000_tuning dnxt;
254
255 u8 skip_fw_load;
256
257 /* previous uncorrected block counter for DVB-S2 */
258 u16 prevUCBS2;
259};
260
261static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
262{
263 u8 buf[] = { reg, data };
264 struct i2c_msg msg = { .addr = state->config->demod_address,
265 .flags = 0, .buf = buf, .len = 2 };
266 int err;
267
268 dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
269
270 err = i2c_transfer(state->i2c, &msg, 1);
271 if (err != 1) {
272 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
273 " value == 0x%02x)\n", __func__, err, reg, data);
274 return -EREMOTEIO;
275 }
276
277 return 0;
278}
279
280static int ds3000_tuner_writereg(struct ds3000_state *state, int reg, int data)
281{
282 u8 buf[] = { reg, data };
283 struct i2c_msg msg = { .addr = 0x60,
284 .flags = 0, .buf = buf, .len = 2 };
285 int err;
286
287 dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
288
289 ds3000_writereg(state, 0x03, 0x11);
290 err = i2c_transfer(state->i2c, &msg, 1);
291 if (err != 1) {
292 printk("%s: writereg error(err == %i, reg == 0x%02x,"
293 " value == 0x%02x)\n", __func__, err, reg, data);
294 return -EREMOTEIO;
295 }
296
297 return 0;
298}
299
300/* I2C write for 8k firmware load */
301static int ds3000_writeFW(struct ds3000_state *state, int reg,
302 const u8 *data, u16 len)
303{
304 int i, ret = -EREMOTEIO;
305 struct i2c_msg msg;
306 u8 *buf;
307
308 buf = kmalloc(3, GFP_KERNEL);
309 if (buf == NULL) {
310 printk(KERN_ERR "Unable to kmalloc\n");
311 ret = -ENOMEM;
312 goto error;
313 }
314
315 *(buf) = reg;
316
317 msg.addr = state->config->demod_address;
318 msg.flags = 0;
319 msg.buf = buf;
320 msg.len = 3;
321
322 for (i = 0; i < len; i += 2) {
323 memcpy(buf + 1, data + i, 2);
324
325 dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
326
327 ret = i2c_transfer(state->i2c, &msg, 1);
328 if (ret != 1) {
329 printk(KERN_ERR "%s: write error(err == %i, "
330 "reg == 0x%02x\n", __func__, ret, reg);
331 ret = -EREMOTEIO;
332 }
333 }
334
335error:
336 kfree(buf);
337
338 return ret;
339}
340
341static int ds3000_readreg(struct ds3000_state *state, u8 reg)
342{
343 int ret;
344 u8 b0[] = { reg };
345 u8 b1[] = { 0 };
346 struct i2c_msg msg[] = {
347 {
348 .addr = state->config->demod_address,
349 .flags = 0,
350 .buf = b0,
351 .len = 1
352 }, {
353 .addr = state->config->demod_address,
354 .flags = I2C_M_RD,
355 .buf = b1,
356 .len = 1
357 }
358 };
359
360 ret = i2c_transfer(state->i2c, msg, 2);
361
362 if (ret != 2) {
363 printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
364 return ret;
365 }
366
367 dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
368
369 return b1[0];
370}
371
372static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
373{
374 int ret;
375 u8 b0[] = { reg };
376 u8 b1[] = { 0 };
377 struct i2c_msg msg[] = {
378 {
379 .addr = 0x60,
380 .flags = 0,
381 .buf = b0,
382 .len = 1
383 }, {
384 .addr = 0x60,
385 .flags = I2C_M_RD,
386 .buf = b1,
387 .len = 1
388 }
389 };
390
391 ds3000_writereg(state, 0x03, 0x12);
392 ret = i2c_transfer(state->i2c, msg, 2);
393
394 if (ret != 2) {
395 printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
396 return ret;
397 }
398
399 dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
400
401 return b1[0];
402}
403
404static int ds3000_set_inversion(struct ds3000_state *state,
405 fe_spectral_inversion_t inversion)
406{
407 dprintk("%s(%d)\n", __func__, inversion);
408
409 switch (inversion) {
410 case INVERSION_OFF:
411 case INVERSION_ON:
412 case INVERSION_AUTO:
413 break;
414 default:
415 return -EINVAL;
416 }
417
418 state->dnxt.inversion = inversion;
419
420 return 0;
421}
422
423static int ds3000_set_symbolrate(struct ds3000_state *state, u32 rate)
424{
425 int ret = 0;
426
427 dprintk("%s()\n", __func__);
428
429 dprintk("%s() symbol_rate = %d\n", __func__, state->dnxt.symbol_rate);
430
431 /* check if symbol rate is within limits */
432 if ((state->dnxt.symbol_rate >
433 state->frontend.ops.info.symbol_rate_max) ||
434 (state->dnxt.symbol_rate <
435 state->frontend.ops.info.symbol_rate_min))
436 ret = -EOPNOTSUPP;
437
438 state->dnxt.symbol_rate = rate;
439
440 return ret;
441}
442
443static int ds3000_load_firmware(struct dvb_frontend *fe,
444 const struct firmware *fw);
445
446static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
447{
448 struct ds3000_state *state = fe->demodulator_priv;
449 const struct firmware *fw;
450 int ret = 0;
451
452 dprintk("%s()\n", __func__);
453
454 if (ds3000_readreg(state, 0xb2) <= 0)
455 return ret;
456
457 if (state->skip_fw_load)
458 return 0;
459 /* Load firmware */
460 /* request the firmware, this will block until someone uploads it */
461 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
462 DS3000_DEFAULT_FIRMWARE);
463 ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
464 state->i2c->dev.parent);
465 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
466 if (ret) {
467 printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
468 "found?)\n", __func__);
469 return ret;
470 }
471
472 /* Make sure we don't recurse back through here during loading */
473 state->skip_fw_load = 1;
474
475 ret = ds3000_load_firmware(fe, fw);
476 if (ret)
477 printk("%s: Writing firmware to device failed\n", __func__);
478
479 release_firmware(fw);
480
481 dprintk("%s: Firmware upload %s\n", __func__,
482 ret == 0 ? "complete" : "failed");
483
484 /* Ensure firmware is always loaded if required */
485 state->skip_fw_load = 0;
486
487 return ret;
488}
489
490static int ds3000_load_firmware(struct dvb_frontend *fe,
491 const struct firmware *fw)
492{
493 struct ds3000_state *state = fe->demodulator_priv;
494
495 dprintk("%s\n", __func__);
496 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
497 fw->size,
498 fw->data[0],
499 fw->data[1],
500 fw->data[fw->size - 2],
501 fw->data[fw->size - 1]);
502
503 /* Begin the firmware load process */
504 ds3000_writereg(state, 0xb2, 0x01);
505 /* write the entire firmware */
506 ds3000_writeFW(state, 0xb0, fw->data, fw->size);
507 ds3000_writereg(state, 0xb2, 0x00);
508
509 return 0;
510}
511
512static void ds3000_dump_registers(struct dvb_frontend *fe)
513{
514 struct ds3000_state *state = fe->demodulator_priv;
515 int x, y, reg = 0, val;
516
517 for (y = 0; y < 16; y++) {
518 dprintk("%s: %02x: ", __func__, y);
519 for (x = 0; x < 16; x++) {
520 reg = (y << 4) + x;
521 val = ds3000_readreg(state, reg);
522 if (x != 15)
523 dprintk("%02x ", val);
524 else
525 dprintk("%02x\n", val);
526 }
527 }
528 dprintk("%s: -- DS3000 DUMP DONE --\n", __func__);
529}
530
531static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
532{
533 struct ds3000_state *state = fe->demodulator_priv;
534 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
535 int lock;
536
537 *status = 0;
538
539 switch (c->delivery_system) {
540 case SYS_DVBS:
541 lock = ds3000_readreg(state, 0xd1);
542 if ((lock & 0x07) == 0x07)
543 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
544 FE_HAS_VITERBI | FE_HAS_SYNC |
545 FE_HAS_LOCK;
546
547 break;
548 case SYS_DVBS2:
549 lock = ds3000_readreg(state, 0x0d);
550 if ((lock & 0x8f) == 0x8f)
551 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
552 FE_HAS_VITERBI | FE_HAS_SYNC |
553 FE_HAS_LOCK;
554
555 break;
556 default:
557 return 1;
558 }
559
560 dprintk("%s: status = 0x%02x\n", __func__, lock);
561
562 return 0;
563}
564
565#define FE_IS_TUNED (FE_HAS_SIGNAL + FE_HAS_LOCK)
566static int ds3000_is_tuned(struct dvb_frontend *fe)
567{
568 fe_status_t tunerstat;
569
570 ds3000_read_status(fe, &tunerstat);
571
572 return ((tunerstat & FE_IS_TUNED) == FE_IS_TUNED);
573}
574
575/* read DS3000 BER value */
576static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
577{
578 struct ds3000_state *state = fe->demodulator_priv;
579 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
580 u8 data;
581 u32 ber_reading, lpdc_frames;
582
583 dprintk("%s()\n", __func__);
584
585 switch (c->delivery_system) {
586 case SYS_DVBS:
587 /* set the number of bytes checked during
588 BER estimation */
589 ds3000_writereg(state, 0xf9, 0x04);
590 /* read BER estimation status */
591 data = ds3000_readreg(state, 0xf8);
592 /* check if BER estimation is ready */
593 if ((data & 0x10) == 0) {
594 /* this is the number of error bits,
595 to calculate the bit error rate
596 divide to 8388608 */
597 *ber = (ds3000_readreg(state, 0xf7) << 8) |
598 ds3000_readreg(state, 0xf6);
599 /* start counting error bits */
600 /* need to be set twice
601 otherwise it fails sometimes */
602 data |= 0x10;
603 ds3000_writereg(state, 0xf8, data);
604 ds3000_writereg(state, 0xf8, data);
605 } else
606 /* used to indicate that BER estimation
607 is not ready, i.e. BER is unknown */
608 *ber = 0xffffffff;
609 break;
610 case SYS_DVBS2:
611 /* read the number of LPDC decoded frames */
612 lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
613 (ds3000_readreg(state, 0xd6) << 8) |
614 ds3000_readreg(state, 0xd5);
615 /* read the number of packets with bad CRC */
616 ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
617 ds3000_readreg(state, 0xf7);
618 if (lpdc_frames > 750) {
619 /* clear LPDC frame counters */
620 ds3000_writereg(state, 0xd1, 0x01);
621 /* clear bad packets counter */
622 ds3000_writereg(state, 0xf9, 0x01);
623 /* enable bad packets counter */
624 ds3000_writereg(state, 0xf9, 0x00);
625 /* enable LPDC frame counters */
626 ds3000_writereg(state, 0xd1, 0x00);
627 *ber = ber_reading;
628 } else
629 /* used to indicate that BER estimation is not ready,
630 i.e. BER is unknown */
631 *ber = 0xffffffff;
632 break;
633 default:
634 return 1;
635 }
636
637 return 0;
638}
639
640/* read TS2020 signal strength */
641static int ds3000_read_signal_strength(struct dvb_frontend *fe,
642 u16 *signal_strength)
643{
644 struct ds3000_state *state = fe->demodulator_priv;
645 u16 sig_reading, sig_strength;
646 u8 rfgain, bbgain;
647
648 dprintk("%s()\n", __func__);
649
650 rfgain = ds3000_tuner_readreg(state, 0x3d) & 0x1f;
651 bbgain = ds3000_tuner_readreg(state, 0x21) & 0x1f;
652
653 if (rfgain > 15)
654 rfgain = 15;
655 if (bbgain > 13)
656 bbgain = 13;
657
658 sig_reading = rfgain * 2 + bbgain * 3;
659
660 sig_strength = 40 + (64 - sig_reading) * 50 / 64 ;
661
662 /* cook the value to be suitable for szap-s2 human readable output */
663 *signal_strength = sig_strength * 1000;
664
665 dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__,
666 sig_reading, *signal_strength);
667
668 return 0;
669}
670
671/* calculate DS3000 snr value in dB */
672static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
673{
674 struct ds3000_state *state = fe->demodulator_priv;
675 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
676 u8 snr_reading, snr_value;
677 u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
678 static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
679 0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
680 0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
681 0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
682 };
683 static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
684 0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
685 0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
686 0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
687 0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
688 0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
689 0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
690 0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
691 0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
692 0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
693 0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
694 0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
695 0x49e9, 0x4a20, 0x4a57
696 };
697
698 dprintk("%s()\n", __func__);
699
700 switch (c->delivery_system) {
701 case SYS_DVBS:
702 snr_reading = ds3000_readreg(state, 0xff);
703 snr_reading /= 8;
704 if (snr_reading == 0)
705 *snr = 0x0000;
706 else {
707 if (snr_reading > 20)
708 snr_reading = 20;
709 snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
710 /* cook the value to be suitable for szap-s2
711 human readable output */
712 *snr = snr_value * 8 * 655;
713 }
714 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
715 snr_reading, *snr);
716 break;
717 case SYS_DVBS2:
718 dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
719 (ds3000_readreg(state, 0x8d) << 4);
720 dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
721 tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
722 if (dvbs2_signal_reading == 0) {
723 *snr = 0x0000;
724 return 0;
725 }
726 if (dvbs2_noise_reading == 0) {
727 snr_value = 0x0013;
728 /* cook the value to be suitable for szap-s2
729 human readable output */
730 *snr = 0xffff;
731 return 0;
732 }
733 if (tmp > dvbs2_noise_reading) {
734 snr_reading = tmp / dvbs2_noise_reading;
735 if (snr_reading > 80)
736 snr_reading = 80;
737 snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
738 /* cook the value to be suitable for szap-s2
739 human readable output */
740 *snr = snr_value * 5 * 655;
741 } else {
742 snr_reading = dvbs2_noise_reading / tmp;
743 if (snr_reading > 80)
744 snr_reading = 80;
745 *snr = -(dvbs2_snr_tab[snr_reading] / 1000);
746 }
747 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
748 snr_reading, *snr);
749 break;
750 default:
751 return 1;
752 }
753
754 return 0;
755}
756
757/* read DS3000 uncorrected blocks */
758static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
759{
760 struct ds3000_state *state = fe->demodulator_priv;
761 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
762 u8 data;
763 u16 _ucblocks;
764
765 dprintk("%s()\n", __func__);
766
767 switch (c->delivery_system) {
768 case SYS_DVBS:
769 *ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
770 ds3000_readreg(state, 0xf4);
771 data = ds3000_readreg(state, 0xf8);
772 /* clear packet counters */
773 data &= ~0x20;
774 ds3000_writereg(state, 0xf8, data);
775 /* enable packet counters */
776 data |= 0x20;
777 ds3000_writereg(state, 0xf8, data);
778 break;
779 case SYS_DVBS2:
780 _ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
781 ds3000_readreg(state, 0xe1);
782 if (_ucblocks > state->prevUCBS2)
783 *ucblocks = _ucblocks - state->prevUCBS2;
784 else
785 *ucblocks = state->prevUCBS2 - _ucblocks;
786 state->prevUCBS2 = _ucblocks;
787 break;
788 default:
789 return 1;
790 }
791
792 return 0;
793}
794
795/* Overwrite the current tuning params, we are about to tune */
796static void ds3000_clone_params(struct dvb_frontend *fe)
797{
798 struct ds3000_state *state = fe->demodulator_priv;
799 memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
800}
801
802static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
803{
804 struct ds3000_state *state = fe->demodulator_priv;
805 u8 data;
806
807 dprintk("%s(%d)\n", __func__, tone);
808 if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
809 printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
810 return -EINVAL;
811 }
812
813 data = ds3000_readreg(state, 0xa2);
814 data &= ~0xc0;
815 ds3000_writereg(state, 0xa2, data);
816
817 switch (tone) {
818 case SEC_TONE_ON:
819 dprintk("%s: setting tone on\n", __func__);
820 data = ds3000_readreg(state, 0xa1);
821 data &= ~0x43;
822 data |= 0x04;
823 ds3000_writereg(state, 0xa1, data);
824 break;
825 case SEC_TONE_OFF:
826 dprintk("%s: setting tone off\n", __func__);
827 data = ds3000_readreg(state, 0xa2);
828 data |= 0x80;
829 ds3000_writereg(state, 0xa2, data);
830 break;
831 }
832
833 return 0;
834}
835
836static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
837 struct dvb_diseqc_master_cmd *d)
838{
839 struct ds3000_state *state = fe->demodulator_priv;
840 int i;
841 u8 data;
842
843 /* Dump DiSEqC message */
844 dprintk("%s(", __func__);
845 for (i = 0 ; i < d->msg_len;) {
846 dprintk("0x%02x", d->msg[i]);
847 if (++i < d->msg_len)
848 dprintk(", ");
849 }
850
851 /* enable DiSEqC message send pin */
852 data = ds3000_readreg(state, 0xa2);
853 data &= ~0xc0;
854 ds3000_writereg(state, 0xa2, data);
855
856 /* DiSEqC message */
857 for (i = 0; i < d->msg_len; i++)
858 ds3000_writereg(state, 0xa3 + i, d->msg[i]);
859
860 data = ds3000_readreg(state, 0xa1);
861 /* clear DiSEqC message length and status,
862 enable DiSEqC message send */
863 data &= ~0xf8;
864 /* set DiSEqC mode, modulation active during 33 pulses,
865 set DiSEqC message length */
866 data |= ((d->msg_len - 1) << 3) | 0x07;
867 ds3000_writereg(state, 0xa1, data);
868
869 /* wait up to 150ms for DiSEqC transmission to complete */
870 for (i = 0; i < 15; i++) {
871 data = ds3000_readreg(state, 0xa1);
872 if ((data & 0x40) == 0)
873 break;
874 msleep(10);
875 }
876
877 /* DiSEqC timeout after 150ms */
878 if (i == 15) {
879 data = ds3000_readreg(state, 0xa1);
880 data &= ~0x80;
881 data |= 0x40;
882 ds3000_writereg(state, 0xa1, data);
883
884 data = ds3000_readreg(state, 0xa2);
885 data &= ~0xc0;
886 data |= 0x80;
887 ds3000_writereg(state, 0xa2, data);
888
889 return 1;
890 }
891
892 data = ds3000_readreg(state, 0xa2);
893 data &= ~0xc0;
894 data |= 0x80;
895 ds3000_writereg(state, 0xa2, data);
896
897 return 0;
898}
899
900/* Send DiSEqC burst */
901static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
902 fe_sec_mini_cmd_t burst)
903{
904 struct ds3000_state *state = fe->demodulator_priv;
905 int i;
906 u8 data;
907
908 dprintk("%s()\n", __func__);
909
910 data = ds3000_readreg(state, 0xa2);
911 data &= ~0xc0;
912 ds3000_writereg(state, 0xa2, data);
913
914 /* DiSEqC burst */
915 if (burst == SEC_MINI_A)
916 /* Unmodulated tone burst */
917 ds3000_writereg(state, 0xa1, 0x02);
918 else if (burst == SEC_MINI_B)
919 /* Modulated tone burst */
920 ds3000_writereg(state, 0xa1, 0x01);
921 else
922 return -EINVAL;
923
924 msleep(13);
925 for (i = 0; i < 5; i++) {
926 data = ds3000_readreg(state, 0xa1);
927 if ((data & 0x40) == 0)
928 break;
929 msleep(1);
930 }
931
932 if (i == 5) {
933 data = ds3000_readreg(state, 0xa1);
934 data &= ~0x80;
935 data |= 0x40;
936 ds3000_writereg(state, 0xa1, data);
937
938 data = ds3000_readreg(state, 0xa2);
939 data &= ~0xc0;
940 data |= 0x80;
941 ds3000_writereg(state, 0xa2, data);
942
943 return 1;
944 }
945
946 data = ds3000_readreg(state, 0xa2);
947 data &= ~0xc0;
948 data |= 0x80;
949 ds3000_writereg(state, 0xa2, data);
950
951 return 0;
952}
953
954static void ds3000_release(struct dvb_frontend *fe)
955{
956 struct ds3000_state *state = fe->demodulator_priv;
957 dprintk("%s\n", __func__);
958 kfree(state);
959}
960
961static struct dvb_frontend_ops ds3000_ops;
962
963struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
964 struct i2c_adapter *i2c)
965{
966 struct ds3000_state *state = NULL;
967 int ret;
968
969 dprintk("%s\n", __func__);
970
971 /* allocate memory for the internal state */
972 state = kmalloc(sizeof(struct ds3000_state), GFP_KERNEL);
973 if (state == NULL) {
974 printk(KERN_ERR "Unable to kmalloc\n");
975 goto error2;
976 }
977
978 /* setup the state */
979 memset(state, 0, sizeof(struct ds3000_state));
980
981 state->config = config;
982 state->i2c = i2c;
983 state->prevUCBS2 = 0;
984
985 /* check if the demod is present */
986 ret = ds3000_readreg(state, 0x00) & 0xfe;
987 if (ret != 0xe0) {
988 printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
989 goto error3;
990 }
991
992 printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
993 ds3000_readreg(state, 0x02),
994 ds3000_readreg(state, 0x01));
995
996 memcpy(&state->frontend.ops, &ds3000_ops,
997 sizeof(struct dvb_frontend_ops));
998 state->frontend.demodulator_priv = state;
999 return &state->frontend;
1000
1001error3:
1002 kfree(state);
1003error2:
1004 return NULL;
1005}
1006EXPORT_SYMBOL(ds3000_attach);
1007
1008static int ds3000_set_property(struct dvb_frontend *fe,
1009 struct dtv_property *tvp)
1010{
1011 dprintk("%s(..)\n", __func__);
1012 return 0;
1013}
1014
1015static int ds3000_get_property(struct dvb_frontend *fe,
1016 struct dtv_property *tvp)
1017{
1018 dprintk("%s(..)\n", __func__);
1019 return 0;
1020}
1021
1022static int ds3000_tune(struct dvb_frontend *fe,
1023 struct dvb_frontend_parameters *p)
1024{
1025 struct ds3000_state *state = fe->demodulator_priv;
1026 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1027
1028 int ret = 0, retune, i;
1029 u8 status, mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf;
1030 u16 value, ndiv;
1031 u32 f3db;
1032
1033 dprintk("%s() ", __func__);
1034
1035 /* Load the firmware if required */
1036 ret = ds3000_firmware_ondemand(fe);
1037 if (ret != 0) {
1038 printk(KERN_ERR "%s: Unable initialise the firmware\n",
1039 __func__);
1040 return ret;
1041 }
1042
1043 state->dnxt.delivery = c->modulation;
1044 state->dnxt.frequency = c->frequency;
1045 state->dnxt.rolloff = 2; /* fixme */
1046 state->dnxt.fec = c->fec_inner;
1047
1048 ret = ds3000_set_inversion(state, p->inversion);
1049 if (ret != 0)
1050 return ret;
1051
1052 ret = ds3000_set_symbolrate(state, c->symbol_rate);
1053 if (ret != 0)
1054 return ret;
1055
1056 /* discard the 'current' tuning parameters and prepare to tune */
1057 ds3000_clone_params(fe);
1058
1059 retune = 1; /* try 1 times */
1060 dprintk("%s: retune = %d\n", __func__, retune);
1061 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1062 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1063 dprintk("%s: FEC = %d \n", __func__,
1064 state->dcur.fec);
1065 dprintk("%s: Inversion = %d\n", __func__, state->dcur.inversion);
1066
1067 do {
1068 /* Reset status register */
1069 status = 0;
1070 /* Tune */
1071 /* TS2020 init */
1072 ds3000_tuner_writereg(state, 0x42, 0x73);
1073 ds3000_tuner_writereg(state, 0x05, 0x01);
1074 ds3000_tuner_writereg(state, 0x62, 0xf5);
1075 /* unknown */
1076 ds3000_tuner_writereg(state, 0x07, 0x02);
1077 ds3000_tuner_writereg(state, 0x10, 0x00);
1078 ds3000_tuner_writereg(state, 0x60, 0x79);
1079 ds3000_tuner_writereg(state, 0x08, 0x01);
1080 ds3000_tuner_writereg(state, 0x00, 0x01);
1081 /* calculate and set freq divider */
1082 if (state->dcur.frequency < 1146000) {
1083 ds3000_tuner_writereg(state, 0x10, 0x11);
1084 ndiv = ((state->dcur.frequency * (6 + 8) * 4) +
1085 (DS3000_XTAL_FREQ / 2)) /
1086 DS3000_XTAL_FREQ - 1024;
1087 } else {
1088 ds3000_tuner_writereg(state, 0x10, 0x01);
1089 ndiv = ((state->dcur.frequency * (6 + 8) * 2) +
1090 (DS3000_XTAL_FREQ / 2)) /
1091 DS3000_XTAL_FREQ - 1024;
1092 }
1093
1094 ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
1095 ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
1096
1097 /* set pll */
1098 ds3000_tuner_writereg(state, 0x03, 0x06);
1099 ds3000_tuner_writereg(state, 0x51, 0x0f);
1100 ds3000_tuner_writereg(state, 0x51, 0x1f);
1101 ds3000_tuner_writereg(state, 0x50, 0x10);
1102 ds3000_tuner_writereg(state, 0x50, 0x00);
1103 msleep(5);
1104
1105 /* unknown */
1106 ds3000_tuner_writereg(state, 0x51, 0x17);
1107 ds3000_tuner_writereg(state, 0x51, 0x1f);
1108 ds3000_tuner_writereg(state, 0x50, 0x08);
1109 ds3000_tuner_writereg(state, 0x50, 0x00);
1110 msleep(5);
1111
1112 value = ds3000_tuner_readreg(state, 0x3d);
1113 value &= 0x0f;
1114 if ((value > 4) && (value < 15)) {
1115 value -= 3;
1116 if (value < 4)
1117 value = 4;
1118 value = ((value << 3) | 0x01) & 0x79;
1119 }
1120
1121 ds3000_tuner_writereg(state, 0x60, value);
1122 ds3000_tuner_writereg(state, 0x51, 0x17);
1123 ds3000_tuner_writereg(state, 0x51, 0x1f);
1124 ds3000_tuner_writereg(state, 0x50, 0x08);
1125 ds3000_tuner_writereg(state, 0x50, 0x00);
1126
1127 /* set low-pass filter period */
1128 ds3000_tuner_writereg(state, 0x04, 0x2e);
1129 ds3000_tuner_writereg(state, 0x51, 0x1b);
1130 ds3000_tuner_writereg(state, 0x51, 0x1f);
1131 ds3000_tuner_writereg(state, 0x50, 0x04);
1132 ds3000_tuner_writereg(state, 0x50, 0x00);
1133 msleep(5);
1134
1135 f3db = ((state->dcur.symbol_rate / 1000) << 2) / 5 + 2000;
1136 if ((state->dcur.symbol_rate / 1000) < 5000)
1137 f3db += 3000;
1138 if (f3db < 7000)
1139 f3db = 7000;
1140 if (f3db > 40000)
1141 f3db = 40000;
1142
1143 /* set low-pass filter baseband */
1144 value = ds3000_tuner_readreg(state, 0x26);
1145 mlpf = 0x2e * 207 / ((value << 1) + 151);
1146 mlpf_max = mlpf * 135 / 100;
1147 mlpf_min = mlpf * 78 / 100;
1148 if (mlpf_max > 63)
1149 mlpf_max = 63;
1150
1151 /* rounded to the closest integer */
1152 nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
1153 / (2766 * DS3000_XTAL_FREQ);
1154 if (nlpf > 23)
1155 nlpf = 23;
1156 if (nlpf < 1)
1157 nlpf = 1;
1158
1159 /* rounded to the closest integer */
1160 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1161 (1000 * f3db / 2)) / (1000 * f3db);
1162
1163 if (mlpf_new < mlpf_min) {
1164 nlpf++;
1165 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1166 (1000 * f3db / 2)) / (1000 * f3db);
1167 }
1168
1169 if (mlpf_new > mlpf_max)
1170 mlpf_new = mlpf_max;
1171
1172 ds3000_tuner_writereg(state, 0x04, mlpf_new);
1173 ds3000_tuner_writereg(state, 0x06, nlpf);
1174 ds3000_tuner_writereg(state, 0x51, 0x1b);
1175 ds3000_tuner_writereg(state, 0x51, 0x1f);
1176 ds3000_tuner_writereg(state, 0x50, 0x04);
1177 ds3000_tuner_writereg(state, 0x50, 0x00);
1178 msleep(5);
1179
1180 /* unknown */
1181 ds3000_tuner_writereg(state, 0x51, 0x1e);
1182 ds3000_tuner_writereg(state, 0x51, 0x1f);
1183 ds3000_tuner_writereg(state, 0x50, 0x01);
1184 ds3000_tuner_writereg(state, 0x50, 0x00);
1185 msleep(60);
1186
1187 /* ds3000 global reset */
1188 ds3000_writereg(state, 0x07, 0x80);
1189 ds3000_writereg(state, 0x07, 0x00);
1190 /* ds3000 build-in uC reset */
1191 ds3000_writereg(state, 0xb2, 0x01);
1192 /* ds3000 software reset */
1193 ds3000_writereg(state, 0x00, 0x01);
1194
1195 switch (c->delivery_system) {
1196 case SYS_DVBS:
1197 /* initialise the demod in DVB-S mode */
1198 for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
1199 ds3000_writereg(state,
1200 ds3000_dvbs_init_tab[i],
1201 ds3000_dvbs_init_tab[i + 1]);
1202 value = ds3000_readreg(state, 0xfe);
1203 value &= 0xc0;
1204 value |= 0x1b;
1205 ds3000_writereg(state, 0xfe, value);
1206 break;
1207 case SYS_DVBS2:
1208 /* initialise the demod in DVB-S2 mode */
1209 for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
1210 ds3000_writereg(state,
1211 ds3000_dvbs2_init_tab[i],
1212 ds3000_dvbs2_init_tab[i + 1]);
1213 ds3000_writereg(state, 0xfe, 0x54);
1214 break;
1215 default:
1216 return 1;
1217 }
1218
1219 /* enable 27MHz clock output */
1220 ds3000_writereg(state, 0x29, 0x80);
1221 /* enable ac coupling */
1222 ds3000_writereg(state, 0x25, 0x8a);
1223
1224 /* enhance symbol rate performance */
1225 if ((state->dcur.symbol_rate / 1000) <= 5000) {
1226 value = 29777 / (state->dcur.symbol_rate / 1000) + 1;
1227 if (value % 2 != 0)
1228 value++;
1229 ds3000_writereg(state, 0xc3, 0x0d);
1230 ds3000_writereg(state, 0xc8, value);
1231 ds3000_writereg(state, 0xc4, 0x10);
1232 ds3000_writereg(state, 0xc7, 0x0e);
1233 } else if ((state->dcur.symbol_rate / 1000) <= 10000) {
1234 value = 92166 / (state->dcur.symbol_rate / 1000) + 1;
1235 if (value % 2 != 0)
1236 value++;
1237 ds3000_writereg(state, 0xc3, 0x07);
1238 ds3000_writereg(state, 0xc8, value);
1239 ds3000_writereg(state, 0xc4, 0x09);
1240 ds3000_writereg(state, 0xc7, 0x12);
1241 } else if ((state->dcur.symbol_rate / 1000) <= 20000) {
1242 value = 64516 / (state->dcur.symbol_rate / 1000) + 1;
1243 ds3000_writereg(state, 0xc3, value);
1244 ds3000_writereg(state, 0xc8, 0x0e);
1245 ds3000_writereg(state, 0xc4, 0x07);
1246 ds3000_writereg(state, 0xc7, 0x18);
1247 } else {
1248 value = 129032 / (state->dcur.symbol_rate / 1000) + 1;
1249 ds3000_writereg(state, 0xc3, value);
1250 ds3000_writereg(state, 0xc8, 0x0a);
1251 ds3000_writereg(state, 0xc4, 0x05);
1252 ds3000_writereg(state, 0xc7, 0x24);
1253 }
1254
1255 /* normalized symbol rate rounded to the closest integer */
1256 value = (((state->dcur.symbol_rate / 1000) << 16) +
1257 (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
1258 ds3000_writereg(state, 0x61, value & 0x00ff);
1259 ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
1260
1261 /* co-channel interference cancellation disabled */
1262 ds3000_writereg(state, 0x56, 0x00);
1263
1264 /* equalizer disabled */
1265 ds3000_writereg(state, 0x76, 0x00);
1266
1267 /*ds3000_writereg(state, 0x08, 0x03);
1268 ds3000_writereg(state, 0xfd, 0x22);
1269 ds3000_writereg(state, 0x08, 0x07);
1270 ds3000_writereg(state, 0xfd, 0x42);
1271 ds3000_writereg(state, 0x08, 0x07);*/
1272
1273 /* ds3000 out of software reset */
1274 ds3000_writereg(state, 0x00, 0x00);
1275 /* start ds3000 build-in uC */
1276 ds3000_writereg(state, 0xb2, 0x00);
1277
1278 /* TODO: calculate and set carrier offset */
1279
1280 /* wait before retrying */
1281 for (i = 0; i < 30 ; i++) {
1282 if (ds3000_is_tuned(fe)) {
1283 dprintk("%s: Tuned\n", __func__);
1284 ds3000_dump_registers(fe);
1285 goto tuned;
1286 }
1287 msleep(1);
1288 }
1289
1290 dprintk("%s: Not tuned\n", __func__);
1291 ds3000_dump_registers(fe);
1292
1293 } while (--retune);
1294
1295tuned:
1296 return ret;
1297}
1298
1299static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
1300{
1301 dprintk("%s()\n", __func__);
1302 return DVBFE_ALGO_SW;
1303}
1304
1305/*
1306 * Initialise or wake up device
1307 *
1308 * Power config will reset and load initial firmware if required
1309 */
1310static int ds3000_initfe(struct dvb_frontend *fe)
1311{
1312 dprintk("%s()\n", __func__);
1313 return 0;
1314}
1315
1316/* Put device to sleep */
1317static int ds3000_sleep(struct dvb_frontend *fe)
1318{
1319 dprintk("%s()\n", __func__);
1320 return 0;
1321}
1322
1323static struct dvb_frontend_ops ds3000_ops = {
1324
1325 .info = {
1326 .name = "Montage Technology DS3000/TS2020",
1327 .type = FE_QPSK,
1328 .frequency_min = 950000,
1329 .frequency_max = 2150000,
1330 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1331 .frequency_tolerance = 5000,
1332 .symbol_rate_min = 1000000,
1333 .symbol_rate_max = 45000000,
1334 .caps = FE_CAN_INVERSION_AUTO |
1335 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1336 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1337 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1338 FE_CAN_2G_MODULATION |
1339 FE_CAN_QPSK | FE_CAN_RECOVER
1340 },
1341
1342 .release = ds3000_release,
1343
1344 .init = ds3000_initfe,
1345 .sleep = ds3000_sleep,
1346 .read_status = ds3000_read_status,
1347 .read_ber = ds3000_read_ber,
1348 .read_signal_strength = ds3000_read_signal_strength,
1349 .read_snr = ds3000_read_snr,
1350 .read_ucblocks = ds3000_read_ucblocks,
1351 .set_tone = ds3000_set_tone,
1352 .diseqc_send_master_cmd = ds3000_send_diseqc_msg,
1353 .diseqc_send_burst = ds3000_diseqc_send_burst,
1354 .get_frontend_algo = ds3000_get_algo,
1355
1356 .set_property = ds3000_set_property,
1357 .get_property = ds3000_get_property,
1358 .set_frontend = ds3000_tune,
1359};
1360
1361module_param(debug, int, 0644);
1362MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
1363
1364MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
1365 "DS3000/TS2020 hardware");
1366MODULE_AUTHOR("Konstantin Dimitrov");
1367MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h
new file mode 100644
index 000000000000..67f67038740a
--- /dev/null
+++ b/drivers/media/dvb/frontends/ds3000.h
@@ -0,0 +1,45 @@
1/*
2 Montage Technology DS3000/TS2020 - DVBS/S2 Satellite demod/tuner driver
3 Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
4
5 Copyright (C) 2009 TurboSight.com
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef DS3000_H
23#define DS3000_H
24
25#include <linux/dvb/frontend.h>
26
27struct ds3000_config {
28 /* the demodulator's i2c address */
29 u8 demod_address;
30};
31
32#if defined(CONFIG_DVB_DS3000) || \
33 (defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE))
34extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
35 struct i2c_adapter *i2c);
36#else
37static inline
38struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
39 struct i2c_adapter *i2c)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44#endif /* CONFIG_DVB_DS3000 */
45#endif /* DS3000_H */
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index fd3fc3e3198a..bcdda9a9aa96 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -18,7 +18,9 @@ config VIDEO_CX23885
18 select DVB_TDA10048 if !DVB_FE_CUSTOMISE 18 select DVB_TDA10048 if !DVB_FE_CUSTOMISE
19 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 19 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
20 select DVB_STV6110 if !DVB_FE_CUSTOMISE 20 select DVB_STV6110 if !DVB_FE_CUSTOMISE
21 select DVB_CX24116 if !DVB_FE_CUSTOMISE
21 select DVB_STV0900 if !DVB_FE_CUSTOMISE 22 select DVB_STV0900 if !DVB_FE_CUSTOMISE
23 select DVB_DS3000 if !DVB_FE_CUSTOMISE
22 select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE 24 select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
23 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE 25 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
24 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE 26 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index bb462589b53b..5787ae243631 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -1,7 +1,7 @@
1cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ 1cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
2 cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ 2 cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
3 cx23885-ioctl.o cx23885-ir.o cx23885-input.o cx23888-ir.o \ 3 cx23885-ioctl.o cx23885-ir.o cx23885-input.o cx23888-ir.o \
4 netup-init.o cimax2.o netup-eeprom.o 4 netup-init.o cimax2.o netup-eeprom.o cx23885-f300.o
5 5
6obj-$(CONFIG_VIDEO_CX23885) += cx23885.o 6obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
7 7
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 23302ddf4187..1ec48169277d 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -782,10 +782,14 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
782 cx_set(GP0_IO, 0x00040004); 782 cx_set(GP0_IO, 0x00040004);
783 break; 783 break;
784 case CX23885_BOARD_TBS_6920: 784 case CX23885_BOARD_TBS_6920:
785 case CX23885_BOARD_TEVII_S470:
786 cx_write(MC417_CTL, 0x00000036); 785 cx_write(MC417_CTL, 0x00000036);
787 cx_write(MC417_OEN, 0x00001000); 786 cx_write(MC417_OEN, 0x00001000);
788 cx_write(MC417_RWD, 0x00001800); 787 cx_set(MC417_RWD, 0x00000002);
788 mdelay(200);
789 cx_clear(MC417_RWD, 0x00000800);
790 mdelay(200);
791 cx_set(MC417_RWD, 0x00000800);
792 mdelay(200);
789 break; 793 break;
790 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 794 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
791 /* GPIO-0 INTA from CiMax1 795 /* GPIO-0 INTA from CiMax1
@@ -1002,8 +1006,12 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1002 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1006 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1003 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1007 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1004 break; 1008 break;
1005 case CX23885_BOARD_TEVII_S470:
1006 case CX23885_BOARD_TBS_6920: 1009 case CX23885_BOARD_TBS_6920:
1010 ts1->gen_ctrl_val = 0x4; /* Parallel */
1011 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1012 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1013 break;
1014 case CX23885_BOARD_TEVII_S470:
1007 case CX23885_BOARD_DVBWORLD_2005: 1015 case CX23885_BOARD_DVBWORLD_2005:
1008 ts1->gen_ctrl_val = 0x5; /* Parallel */ 1016 ts1->gen_ctrl_val = 0x5; /* Parallel */
1009 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1017 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index e8eb4ec0c30a..04b12d27bc13 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1871,6 +1871,26 @@ void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask)
1871 printk(KERN_INFO "%s: Unsupported\n", dev->name); 1871 printk(KERN_INFO "%s: Unsupported\n", dev->name);
1872} 1872}
1873 1873
1874u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask)
1875{
1876 if (mask & 0x00000007)
1877 return (cx_read(GP0_IO) >> 8) & mask & 0x7;
1878
1879 if (mask & 0x0007fff8) {
1880 if (encoder_on_portb(dev) || encoder_on_portc(dev))
1881 printk(KERN_ERR
1882 "%s: Reading GPIO moving on encoder ports\n",
1883 dev->name);
1884 return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3;
1885 }
1886
1887 /* TODO: 23-19 */
1888 if (mask & 0x00f80000)
1889 printk(KERN_INFO "%s: Unsupported\n", dev->name);
1890
1891 return 0;
1892}
1893
1874void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput) 1894void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
1875{ 1895{
1876 if ((mask & 0x00000007) && asoutput) 1896 if ((mask & 0x00000007) && asoutput)
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index bf24e86293c6..2607de134fa6 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -56,6 +56,8 @@
56#include "netup-init.h" 56#include "netup-init.h"
57#include "lgdt3305.h" 57#include "lgdt3305.h"
58#include "atbm8830.h" 58#include "atbm8830.h"
59#include "ds3000.h"
60#include "cx23885-f300.h"
59 61
60static unsigned int debug; 62static unsigned int debug;
61 63
@@ -427,26 +429,12 @@ static struct stv6110_config netup_stv6110_tunerconfig_b = {
427 .gain = 8, /* +16 dB - maximum gain */ 429 .gain = 8, /* +16 dB - maximum gain */
428}; 430};
429 431
430static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
431{
432 struct cx23885_tsport *port = fe->dvb->priv;
433 struct cx23885_dev *dev = port->dev;
434
435 if (voltage == SEC_VOLTAGE_18)
436 cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
437 else if (voltage == SEC_VOLTAGE_13)
438 cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
439 else
440 cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
441 return 0;
442}
443
444static struct cx24116_config tbs_cx24116_config = { 432static struct cx24116_config tbs_cx24116_config = {
445 .demod_address = 0x05, 433 .demod_address = 0x55,
446}; 434};
447 435
448static struct cx24116_config tevii_cx24116_config = { 436static struct ds3000_config tevii_ds3000_config = {
449 .demod_address = 0x55, 437 .demod_address = 0x68,
450}; 438};
451 439
452static struct cx24116_config dvbworld_cx24116_config = { 440static struct cx24116_config dvbworld_cx24116_config = {
@@ -832,23 +820,23 @@ static int dvb_register(struct cx23885_tsport *port)
832 } 820 }
833 break; 821 break;
834 case CX23885_BOARD_TBS_6920: 822 case CX23885_BOARD_TBS_6920:
835 i2c_bus = &dev->i2c_bus[0]; 823 i2c_bus = &dev->i2c_bus[1];
836 824
837 fe0->dvb.frontend = dvb_attach(cx24116_attach, 825 fe0->dvb.frontend = dvb_attach(cx24116_attach,
838 &tbs_cx24116_config, 826 &tbs_cx24116_config,
839 &i2c_bus->i2c_adap); 827 &i2c_bus->i2c_adap);
840 if (fe0->dvb.frontend != NULL) 828 if (fe0->dvb.frontend != NULL)
841 fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; 829 fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
842 830
843 break; 831 break;
844 case CX23885_BOARD_TEVII_S470: 832 case CX23885_BOARD_TEVII_S470:
845 i2c_bus = &dev->i2c_bus[1]; 833 i2c_bus = &dev->i2c_bus[1];
846 834
847 fe0->dvb.frontend = dvb_attach(cx24116_attach, 835 fe0->dvb.frontend = dvb_attach(ds3000_attach,
848 &tevii_cx24116_config, 836 &tevii_ds3000_config,
849 &i2c_bus->i2c_adap); 837 &i2c_bus->i2c_adap);
850 if (fe0->dvb.frontend != NULL) 838 if (fe0->dvb.frontend != NULL)
851 fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; 839 fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
852 840
853 break; 841 break;
854 case CX23885_BOARD_DVBWORLD_2005: 842 case CX23885_BOARD_DVBWORLD_2005:
diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/video/cx23885/cx23885-f300.c
new file mode 100644
index 000000000000..93998f220986
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.c
@@ -0,0 +1,177 @@
1/*
2 * Driver for Silicon Labs C8051F300 microcontroller.
3 *
4 * It is used for LNB power control in TeVii S470,
5 * TBS 6920 PCIe DVB-S2 cards.
6 *
7 * Microcontroller connected to cx23885 GPIO pins:
8 * GPIO0 - data - P0.3 F300
9 * GPIO1 - reset - P0.2 F300
10 * GPIO2 - clk - P0.1 F300
11 * GPIO3 - busy - P0.0 F300
12 *
13 * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 *
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include "cx23885.h"
32
33#define F300_DATA GPIO_0
34#define F300_RESET GPIO_1
35#define F300_CLK GPIO_2
36#define F300_BUSY GPIO_3
37
38static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
39{
40 cx23885_gpio_enable(dev, line, 1);
41 if (lvl == 1)
42 cx23885_gpio_set(dev, line);
43 else
44 cx23885_gpio_clear(dev, line);
45}
46
47static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
48{
49 cx23885_gpio_enable(dev, line, 0);
50
51 return cx23885_gpio_get(dev, line);
52}
53
54static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
55{
56 u8 i;
57
58 for (i = 0; i < 8; i++) {
59 f300_set_line(dev, F300_CLK, 0);
60 udelay(30);
61 f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
62 udelay(30);
63 dta <<= 1;
64 f300_set_line(dev, F300_CLK, 1);
65 udelay(30);
66 }
67}
68
69static u8 f300_get_byte(struct cx23885_dev *dev)
70{
71 u8 i, dta = 0;
72
73 for (i = 0; i < 8; i++) {
74 f300_set_line(dev, F300_CLK, 0);
75 udelay(30);
76 dta <<= 1;
77 f300_set_line(dev, F300_CLK, 1);
78 udelay(30);
79 dta |= f300_get_line(dev, F300_DATA);/* msb first */
80
81 }
82
83 return dta;
84}
85
86static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
87{
88 struct cx23885_tsport *port = fe->dvb->priv;
89 struct cx23885_dev *dev = port->dev;
90 u8 i, temp, ret = 0;
91
92 temp = buf[0];
93 for (i = 0; i < buf[0]; i++)
94 temp += buf[i + 1];
95 temp = (~temp + 1);/* get check sum */
96 buf[1 + buf[0]] = temp;
97
98 f300_set_line(dev, F300_RESET, 1);
99 f300_set_line(dev, F300_CLK, 1);
100 udelay(30);
101 f300_set_line(dev, F300_DATA, 1);
102 msleep(1);
103
104 /* question: */
105 f300_set_line(dev, F300_RESET, 0);/* begin to send data */
106 msleep(1);
107
108 f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
109 msleep(1);
110
111 temp = buf[0];
112 temp += 2;
113 for (i = 0; i < temp; i++)
114 f300_send_byte(dev, buf[i]);
115
116 f300_set_line(dev, F300_RESET, 1);/* sent data over */
117 f300_set_line(dev, F300_DATA, 1);
118
119 /* answer: */
120 temp = 0;
121 for (i = 0; ((i < 8) & (temp == 0)); i++) {
122 msleep(1);
123 if (f300_get_line(dev, F300_BUSY) == 0)
124 temp = 1;
125 }
126
127 if (i > 7) {
128 printk(KERN_ERR "%s: timeout, the slave no response\n",
129 __func__);
130 ret = 1; /* timeout, the slave no response */
131 } else { /* the slave not busy, prepare for getting data */
132 f300_set_line(dev, F300_RESET, 0);/*ready...*/
133 msleep(1);
134 f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
135 msleep(1);
136 temp = f300_get_byte(dev);/*get the data length */
137 if (temp > 14)
138 temp = 14;
139
140 for (i = 0; i < (temp + 1); i++)
141 f300_get_byte(dev);/* get data to empty buffer */
142
143 f300_set_line(dev, F300_RESET, 1);/* received data over */
144 f300_set_line(dev, F300_DATA, 1);
145 }
146
147 return ret;
148}
149
150int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
151{
152 u8 buf[16];
153
154 buf[0] = 0x05;
155 buf[1] = 0x38;/* write port */
156 buf[2] = 0x01;/* A port, lnb power */
157
158 switch (voltage) {
159 case SEC_VOLTAGE_13:
160 buf[3] = 0x01;/* power on */
161 buf[4] = 0x02;/* B port, H/V */
162 buf[5] = 0x00;/*13V v*/
163 break;
164 case SEC_VOLTAGE_18:
165 buf[3] = 0x01;
166 buf[4] = 0x02;
167 buf[5] = 0x01;/* 18V h*/
168 break;
169 case SEC_VOLTAGE_OFF:
170 buf[3] = 0x00;/* power off */
171 buf[4] = 0x00;
172 buf[5] = 0x00;
173 break;
174 }
175
176 return f300_xfer(fe, buf);
177}
diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/video/cx23885/cx23885-f300.h
new file mode 100644
index 000000000000..e73344c94963
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.h
@@ -0,0 +1,2 @@
1extern int f300_set_voltage(struct dvb_frontend *fe,
2 fe_sec_voltage_t voltage);
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 338320025529..fa744764dc8b 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -471,6 +471,7 @@ extern void cx23885_wakeup(struct cx23885_tsport *port,
471 471
472extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask); 472extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
473extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask); 473extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
474extern u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask);
474extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, 475extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
475 int asoutput); 476 int asoutput);
476 477