aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorIgor M. Liplianin <liplianin@me.by>2008-10-05 08:11:21 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-13 10:27:03 -0400
commit8a4949b7e98cbb9e304416ecf6da978e1fb1fb9e (patch)
tree917c8b740a5a7bbfc63afe05869abeb956973ce8 /drivers/media
parentceab2fe84987a9b2dbe6107f83ac99c98040abcc (diff)
V4L/DVB (9176): Add support for DvbWorld USB cards with STV0288 demodulator.
Add support for DvbWorld USB cards with STV0288 demodulator. Those cards use Earda EDS-1547 tuner. Signed-off-by: Igor M. Liplianin <liplianin@me.by> Signed-off-by: Steven Toth <stoth@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig2
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c123
-rw-r--r--drivers/media/dvb/frontends/eds1547.h133
3 files changed, 254 insertions, 4 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 57bb470bd064..3c13bcfa6385 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -253,6 +253,8 @@ config DVB_USB_DW2102
253 depends on DVB_USB 253 depends on DVB_USB
254 select DVB_PLL if !DVB_FE_CUSTOMISE 254 select DVB_PLL if !DVB_FE_CUSTOMISE
255 select DVB_STV0299 if !DVB_FE_CUSTOMISE 255 select DVB_STV0299 if !DVB_FE_CUSTOMISE
256 select DVB_STV0288 if !DVB_FE_CUSTOMISE
257 select DVB_STB6000 if !DVB_FE_CUSTOMISE
256 select DVB_CX24116 if !DVB_FE_CUSTOMISE 258 select DVB_CX24116 if !DVB_FE_CUSTOMISE
257 select DVB_SI21XX if !DVB_FE_CUSTOMISE 259 select DVB_SI21XX if !DVB_FE_CUSTOMISE
258 help 260 help
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 20ba3f129001..ca53df61caa8 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -14,6 +14,9 @@
14#include "si21xx.h" 14#include "si21xx.h"
15#include "stv0299.h" 15#include "stv0299.h"
16#include "z0194a.h" 16#include "z0194a.h"
17#include "stv0288.h"
18#include "stb6000.h"
19#include "eds1547.h"
17#include "cx24116.h" 20#include "cx24116.h"
18 21
19#ifndef USB_PID_DW2102 22#ifndef USB_PID_DW2102
@@ -199,6 +202,78 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
199 mutex_unlock(&d->i2c_mutex); 202 mutex_unlock(&d->i2c_mutex);
200 return num; 203 return num;
201} 204}
205static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
206{
207 struct dvb_usb_device *d = i2c_get_adapdata(adap);
208 int ret = 0;
209
210 if (!d)
211 return -ENODEV;
212 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
213 return -EAGAIN;
214
215 switch (num) {
216 case 2: {
217 /* read */
218 /* first write first register number */
219 u8 ibuf [msg[1].len + 2], obuf[3];
220 obuf[0] = 0xd0;
221 obuf[1] = msg[0].len;
222 obuf[2] = msg[0].buf[0];
223 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
224 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
225 /* second read registers */
226 ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
227 ibuf, msg[1].len + 2, DW210X_READ_MSG);
228 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
229
230 break;
231 }
232 case 1:
233 switch (msg[0].addr) {
234 case 0x68: {
235 /* write to register */
236 u8 obuf[msg[0].len + 2];
237 obuf[0] = 0xd0;
238 obuf[1] = msg[0].len;
239 memcpy(obuf + 2, msg[0].buf, msg[0].len);
240 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
241 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
242 break;
243 }
244 case 0x61: {
245 /* write to tuner */
246 u8 obuf[msg[0].len + 2];
247 obuf[0] = 0xc2;
248 obuf[1] = msg[0].len;
249 memcpy(obuf + 2, msg[0].buf, msg[0].len);
250 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
251 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
252 break;
253 }
254 case(DW2102_RC_QUERY): {
255 u8 ibuf[2];
256 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
257 ibuf, 2, DW210X_READ_MSG);
258 memcpy(msg[0].buf, ibuf , 2);
259 break;
260 }
261 case(DW2102_VOLTAGE_CTRL): {
262 u8 obuf[2];
263 obuf[0] = 0x30;
264 obuf[1] = msg[0].buf[0];
265 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
266 obuf, 2, DW210X_WRITE_MSG);
267 break;
268 }
269 }
270
271 break;
272 }
273
274 mutex_unlock(&d->i2c_mutex);
275 return num;
276}
202 277
203static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 278static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
204{ 279{
@@ -297,6 +372,11 @@ static struct i2c_algorithm dw2102_serit_i2c_algo = {
297 .functionality = dw210x_i2c_func, 372 .functionality = dw210x_i2c_func,
298}; 373};
299 374
375static struct i2c_algorithm dw2102_earda_i2c_algo = {
376 .master_xfer = dw2102_earda_i2c_transfer,
377 .functionality = dw210x_i2c_func,
378};
379
300static struct i2c_algorithm dw2104_i2c_algo = { 380static struct i2c_algorithm dw2104_i2c_algo = {
301 .master_xfer = dw2104_i2c_transfer, 381 .master_xfer = dw2104_i2c_transfer,
302 .functionality = dw210x_i2c_func, 382 .functionality = dw210x_i2c_func,
@@ -378,6 +458,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
378 return 0; 458 return 0;
379 } 459 }
380 } 460 }
461 if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
462 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
463 d->fe = dvb_attach(stv0288_attach, &earda_config,
464 &d->dev->i2c_adap);
465 if (d->fe != NULL) {
466 d->fe->ops.set_voltage = dw210x_set_voltage;
467 info("Attached stv0288!\n");
468 return 0;
469 }
470 }
471
381 if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) { 472 if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
382 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ 473 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
383 d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, 474 d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
@@ -398,6 +489,14 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
398 return 0; 489 return 0;
399} 490}
400 491
492static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
493{
494 dvb_attach(stb6000_attach, adap->fe, 0x61,
495 &adap->dev->i2c_adap);
496
497 return 0;
498}
499
401static struct dvb_usb_rc_key dw210x_rc_keys[] = { 500static struct dvb_usb_rc_key dw210x_rc_keys[] = {
402 { 0xf8, 0x0a, KEY_Q }, /*power*/ 501 { 0xf8, 0x0a, KEY_Q }, /*power*/
403 { 0xf8, 0x0c, KEY_M }, /*mute*/ 502 { 0xf8, 0x0c, KEY_M }, /*mute*/
@@ -478,7 +577,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
478 u8 *b, *p; 577 u8 *b, *p;
479 int ret = 0, i; 578 int ret = 0, i;
480 u8 reset; 579 u8 reset;
481 u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0}; 580 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
482 const struct firmware *fw; 581 const struct firmware *fw;
483 const char *filename = "dvb-usb-dw2101.fw"; 582 const char *filename = "dvb-usb-dw2101.fw";
484 switch (dev->descriptor.idProduct) { 583 switch (dev->descriptor.idProduct) {
@@ -544,9 +643,25 @@ static int dw2102_load_firmware(struct usb_device *dev,
544 /* check STV0299 frontend */ 643 /* check STV0299 frontend */
545 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2, 644 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
546 DW210X_READ_MSG); 645 DW210X_READ_MSG);
547 if (reset16[0] == 0xa1) 646 if (reset16[0] == 0xa1) {
548 dw2102_properties.i2c_algo = &dw2102_i2c_algo; 647 dw2102_properties.i2c_algo = &dw2102_i2c_algo;
549 break; 648 dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach;
649 break;
650 } else {
651 /* check STV0288 frontend */
652 reset16[0] = 0xd0;
653 reset16[1] = 1;
654 reset16[2] = 0;
655 dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
656 DW210X_WRITE_MSG);
657 dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
658 DW210X_READ_MSG);
659 if (reset16[2] == 0x11) {
660 dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
661 dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
662 break;
663 }
664 }
550 case 0x2101: 665 case 0x2101:
551 dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2, 666 dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
552 DW210X_READ_MSG); 667 DW210X_READ_MSG);
@@ -586,7 +701,7 @@ static struct dvb_usb_device_properties dw2102_properties = {
586 { 701 {
587 .frontend_attach = dw2102_frontend_attach, 702 .frontend_attach = dw2102_frontend_attach,
588 .streaming_ctrl = NULL, 703 .streaming_ctrl = NULL,
589 .tuner_attach = dw2102_tuner_attach, 704 .tuner_attach = NULL,
590 .stream = { 705 .stream = {
591 .type = USB_BULK, 706 .type = USB_BULK,
592 .count = 8, 707 .count = 8,
diff --git a/drivers/media/dvb/frontends/eds1547.h b/drivers/media/dvb/frontends/eds1547.h
new file mode 100644
index 000000000000..fa79b7c83dd2
--- /dev/null
+++ b/drivers/media/dvb/frontends/eds1547.h
@@ -0,0 +1,133 @@
1/* eds1547.h Earda EDS-1547 tuner support
2*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4*
5* This program is free software; you can redistribute it and/or modify it
6* under the terms of the GNU General Public License as published by the
7* Free Software Foundation, version 2.
8*
9* see Documentation/dvb/README.dvb-usb for more information
10*/
11
12#ifndef EDS1547
13#define EDS1547
14
15static u8 stv0288_earda_inittab[] = {
16 0x01, 0x57,
17 0x02, 0x20,
18 0x03, 0x8e,
19 0x04, 0x8e,
20 0x05, 0x12,
21 0x06, 0x00,
22 0x07, 0x00,
23 0x09, 0x00,
24 0x0a, 0x04,
25 0x0b, 0x00,
26 0x0c, 0x00,
27 0x0d, 0x00,
28 0x0e, 0xd4,
29 0x0f, 0x30,
30 0x11, 0x44,
31 0x12, 0x03,
32 0x13, 0x48,
33 0x14, 0x84,
34 0x15, 0x45,
35 0x16, 0xb7,
36 0x17, 0x9c,
37 0x18, 0x00,
38 0x19, 0xa6,
39 0x1a, 0x88,
40 0x1b, 0x8f,
41 0x1c, 0xf0,
42 0x20, 0x0b,
43 0x21, 0x54,
44 0x22, 0x00,
45 0x23, 0x00,
46 0x2b, 0xff,
47 0x2c, 0xf7,
48 0x30, 0x00,
49 0x31, 0x1e,
50 0x32, 0x14,
51 0x33, 0x0f,
52 0x34, 0x09,
53 0x35, 0x0c,
54 0x36, 0x05,
55 0x37, 0x2f,
56 0x38, 0x16,
57 0x39, 0xbd,
58 0x3a, 0x00,
59 0x3b, 0x13,
60 0x3c, 0x11,
61 0x3d, 0x30,
62 0x40, 0x63,
63 0x41, 0x04,
64 0x42, 0x60,
65 0x43, 0x00,
66 0x44, 0x00,
67 0x45, 0x00,
68 0x46, 0x00,
69 0x47, 0x00,
70 0x4a, 0x00,
71 0x50, 0x10,
72 0x51, 0x36,
73 0x52, 0x09,
74 0x53, 0x94,
75 0x54, 0x62,
76 0x55, 0x29,
77 0x56, 0x64,
78 0x57, 0x2b,
79 0x58, 0x54,
80 0x59, 0x86,
81 0x5a, 0x00,
82 0x5b, 0x9b,
83 0x5c, 0x08,
84 0x5d, 0x7f,
85 0x5e, 0x00,
86 0x5f, 0xff,
87 0x70, 0x00,
88 0x71, 0x00,
89 0x72, 0x00,
90 0x74, 0x00,
91 0x75, 0x00,
92 0x76, 0x00,
93 0x81, 0x00,
94 0x82, 0x3f,
95 0x83, 0x3f,
96 0x84, 0x00,
97 0x85, 0x00,
98 0x88, 0x00,
99 0x89, 0x00,
100 0x8a, 0x00,
101 0x8b, 0x00,
102 0x8c, 0x00,
103 0x90, 0x00,
104 0x91, 0x00,
105 0x92, 0x00,
106 0x93, 0x00,
107 0x94, 0x1c,
108 0x97, 0x00,
109 0xa0, 0x48,
110 0xa1, 0x00,
111 0xb0, 0xb8,
112 0xb1, 0x3a,
113 0xb2, 0x10,
114 0xb3, 0x82,
115 0xb4, 0x80,
116 0xb5, 0x82,
117 0xb6, 0x82,
118 0xb7, 0x82,
119 0xb8, 0x20,
120 0xb9, 0x00,
121 0xf0, 0x00,
122 0xf1, 0x00,
123 0xf2, 0xc0,
124 0xff,0xff,
125};
126
127static struct stv0288_config earda_config = {
128 .demod_address = 0x68,
129 .min_delay_ms = 100,
130 .inittab = stv0288_earda_inittab,
131};
132
133#endif