diff options
author | Igor M. Liplianin <liplianin@me.by> | 2008-09-08 16:16:40 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 07:37:04 -0400 |
commit | fe03d5ee6758a2533dbc5e69a693d264d270d04b (patch) | |
tree | 268886c03c0c3d7cfd5f9a1bcab81d1adea69800 /drivers | |
parent | 2cf801e3e38f649d25fe3b4e236976f45e26289f (diff) |
V4L/DVB (8991): Added support for DVBWorld 2104 and TeVii S650 USB DVB-S2 cards
Added support for DVBWorld 2104 and TeVii S650 USB DVB-S2 cards
This cards based on cx24116 demodulator.
Signed-off-by: Igor M. Liplianin <liplianin@me.by>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/dvb/dvb-usb/dw2102.c | 305 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dw2102.h | 1 |
2 files changed, 248 insertions, 58 deletions
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index a4d898b44e55..0f3f962b35bf 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -1,4 +1,5 @@ | |||
1 | /* DVB USB framework compliant Linux driver for the DVBWorld DVB-S 2102 Card | 1 | /* DVB USB framework compliant Linux driver for the |
2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104 Card | ||
2 | * | 3 | * |
3 | * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) | 4 | * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) |
4 | * | 5 | * |
@@ -12,18 +13,23 @@ | |||
12 | #include "dw2102.h" | 13 | #include "dw2102.h" |
13 | #include "stv0299.h" | 14 | #include "stv0299.h" |
14 | #include "z0194a.h" | 15 | #include "z0194a.h" |
16 | #include "cx24116.h" | ||
15 | 17 | ||
16 | #ifndef USB_PID_DW2102 | 18 | #ifndef USB_PID_DW2102 |
17 | #define USB_PID_DW2102 0x2102 | 19 | #define USB_PID_DW2102 0x2102 |
18 | #endif | 20 | #endif |
19 | 21 | ||
22 | #ifndef USB_PID_DW2104 | ||
23 | #define USB_PID_DW2104 0x2104 | ||
24 | #endif | ||
25 | |||
20 | #define DW2102_READ_MSG 0 | 26 | #define DW2102_READ_MSG 0 |
21 | #define DW2102_WRITE_MSG 1 | 27 | #define DW2102_WRITE_MSG 1 |
22 | 28 | ||
23 | #define REG_1F_SYMBOLRATE_BYTE0 0x1f | 29 | #define REG_1F_SYMBOLRATE_BYTE0 0x1f |
24 | #define REG_20_SYMBOLRATE_BYTE1 0x20 | 30 | #define REG_20_SYMBOLRATE_BYTE1 0x20 |
25 | #define REG_21_SYMBOLRATE_BYTE2 0x21 | 31 | #define REG_21_SYMBOLRATE_BYTE2 0x21 |
26 | 32 | /* on my own*/ | |
27 | #define DW2102_VOLTAGE_CTRL (0x1800) | 33 | #define DW2102_VOLTAGE_CTRL (0x1800) |
28 | #define DW2102_RC_QUERY (0x1a00) | 34 | #define DW2102_RC_QUERY (0x1a00) |
29 | 35 | ||
@@ -35,22 +41,27 @@ struct dw2102_rc_keys { | |||
35 | u32 event; | 41 | u32 event; |
36 | }; | 42 | }; |
37 | 43 | ||
44 | /* debug */ | ||
45 | static int dvb_usb_dw2102_debug; | ||
46 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); | ||
47 | MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); | ||
48 | |||
38 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 49 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
39 | 50 | ||
40 | static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value, | 51 | static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value, |
41 | u8 *data, u16 len, int flags) | 52 | u16 index, u8 * data, u16 len, int flags) |
42 | { | 53 | { |
43 | int ret; | 54 | int ret; |
44 | u8 u8buf[len]; | 55 | u8 u8buf[len]; |
45 | 56 | ||
46 | unsigned int pipe = (flags == DW2102_READ_MSG) ? | 57 | unsigned int pipe = (flags == DW2102_READ_MSG) ? |
47 | usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); | 58 | usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); |
48 | u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; | 59 | u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; |
49 | 60 | ||
50 | if (flags == DW2102_WRITE_MSG) | 61 | if (flags == DW2102_WRITE_MSG) |
51 | memcpy(u8buf, data, len); | 62 | memcpy(u8buf, data, len); |
52 | ret = usb_control_msg(dev, pipe, request, | 63 | ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, |
53 | request_type | USB_TYPE_VENDOR, value, 0 , u8buf, len, 2000); | 64 | value, index , u8buf, len, 2000); |
54 | 65 | ||
55 | if (flags == DW2102_READ_MSG) | 66 | if (flags == DW2102_READ_MSG) |
56 | memcpy(data, u8buf, len); | 67 | memcpy(data, u8buf, len); |
@@ -65,7 +76,6 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
65 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 76 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
66 | int i = 0, ret = 0; | 77 | int i = 0, ret = 0; |
67 | u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; | 78 | u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; |
68 | u8 request; | ||
69 | u16 value; | 79 | u16 value; |
70 | 80 | ||
71 | if (!d) | 81 | if (!d) |
@@ -76,12 +86,11 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); | |||
76 | switch (num) { | 86 | switch (num) { |
77 | case 2: | 87 | case 2: |
78 | /* read stv0299 register */ | 88 | /* read stv0299 register */ |
79 | request = 0xb5; | ||
80 | value = msg[0].buf[0];/* register */ | 89 | value = msg[0].buf[0];/* register */ |
81 | for (i = 0; i < msg[1].len; i++) { | 90 | for (i = 0; i < msg[1].len; i++) { |
82 | value = value + i; | 91 | value = value + i; |
83 | ret = dw2102_op_rw(d->udev, 0xb5, | 92 | ret = dw2102_op_rw(d->udev, 0xb5, value, 0, |
84 | value, buf6, 2, DW2102_READ_MSG); | 93 | buf6, 2, DW2102_READ_MSG); |
85 | msg[1].buf[i] = buf6[0]; | 94 | msg[1].buf[i] = buf6[0]; |
86 | 95 | ||
87 | } | 96 | } |
@@ -93,8 +102,8 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); | |||
93 | buf6[0] = 0x2a; | 102 | buf6[0] = 0x2a; |
94 | buf6[1] = msg[0].buf[0]; | 103 | buf6[1] = msg[0].buf[0]; |
95 | buf6[2] = msg[0].buf[1]; | 104 | buf6[2] = msg[0].buf[1]; |
96 | ret = dw2102_op_rw(d->udev, 0xb2, | 105 | ret = dw2102_op_rw(d->udev, 0xb2, 0, 0, |
97 | 0, buf6, 3, DW2102_WRITE_MSG); | 106 | buf6, 3, DW2102_WRITE_MSG); |
98 | break; | 107 | break; |
99 | case 0x60: | 108 | case 0x60: |
100 | if (msg[0].flags == 0) { | 109 | if (msg[0].flags == 0) { |
@@ -106,26 +115,26 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); | |||
106 | buf6[4] = msg[0].buf[1]; | 115 | buf6[4] = msg[0].buf[1]; |
107 | buf6[5] = msg[0].buf[2]; | 116 | buf6[5] = msg[0].buf[2]; |
108 | buf6[6] = msg[0].buf[3]; | 117 | buf6[6] = msg[0].buf[3]; |
109 | ret = dw2102_op_rw(d->udev, 0xb2, | 118 | ret = dw2102_op_rw(d->udev, 0xb2, 0, 0, |
110 | 0, buf6, 7, DW2102_WRITE_MSG); | 119 | buf6, 7, DW2102_WRITE_MSG); |
111 | } else { | 120 | } else { |
112 | /* write to tuner pll */ | 121 | /* read from tuner */ |
113 | ret = dw2102_op_rw(d->udev, 0xb5, | 122 | ret = dw2102_op_rw(d->udev, 0xb5, 0,0, |
114 | 0, buf6, 1, DW2102_READ_MSG); | 123 | buf6, 1, DW2102_READ_MSG); |
115 | msg[0].buf[0] = buf6[0]; | 124 | msg[0].buf[0] = buf6[0]; |
116 | } | 125 | } |
117 | break; | 126 | break; |
118 | case (DW2102_RC_QUERY): | 127 | case (DW2102_RC_QUERY): |
119 | ret = dw2102_op_rw(d->udev, 0xb8, | 128 | ret = dw2102_op_rw(d->udev, 0xb8, 0, 0, |
120 | 0, buf6, 2, DW2102_READ_MSG); | 129 | buf6, 2, DW2102_READ_MSG); |
121 | msg[0].buf[0] = buf6[0]; | 130 | msg[0].buf[0] = buf6[0]; |
122 | msg[0].buf[1] = buf6[1]; | 131 | msg[0].buf[1] = buf6[1]; |
123 | break; | 132 | break; |
124 | case (DW2102_VOLTAGE_CTRL): | 133 | case (DW2102_VOLTAGE_CTRL): |
125 | buf6[0] = 0x30; | 134 | buf6[0] = 0x30; |
126 | buf6[1] = msg[0].buf[0]; | 135 | buf6[1] = msg[0].buf[0]; |
127 | ret = dw2102_op_rw(d->udev, 0xb2, | 136 | ret = dw2102_op_rw(d->udev, 0xb2, 0, 0, |
128 | 0, buf6, 2, DW2102_WRITE_MSG); | 137 | buf6, 2, DW2102_WRITE_MSG); |
129 | break; | 138 | break; |
130 | } | 139 | } |
131 | 140 | ||
@@ -136,6 +145,88 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); | |||
136 | return num; | 145 | return num; |
137 | } | 146 | } |
138 | 147 | ||
148 | static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) | ||
149 | { | ||
150 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
151 | int ret = 0; | ||
152 | int len, i; | ||
153 | |||
154 | if (!d) | ||
155 | return -ENODEV; | ||
156 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
157 | return -EAGAIN; | ||
158 | |||
159 | switch (num) { | ||
160 | case 2: { | ||
161 | /* read */ | ||
162 | /* first write first register number */ | ||
163 | u8 ibuf [msg[1].len + 2], obuf[3]; | ||
164 | obuf[0] = 0xaa; | ||
165 | obuf[1] = msg[0].len; | ||
166 | obuf[2] = msg[0].buf[0]; | ||
167 | ret = dw2102_op_rw(d->udev, 0xc2, 0, 0, | ||
168 | obuf, msg[0].len + 2, DW2102_WRITE_MSG); | ||
169 | /* second read registers */ | ||
170 | ret = dw2102_op_rw(d->udev, 0xc3, 0xab , 0, | ||
171 | ibuf, msg[1].len + 2, DW2102_READ_MSG); | ||
172 | memcpy(msg[1].buf, ibuf + 2, msg[1].len); | ||
173 | |||
174 | break; | ||
175 | } | ||
176 | case 1: | ||
177 | switch (msg[0].addr) { | ||
178 | case 0x55: { | ||
179 | if (msg[0].buf[0] == 0xf7) { | ||
180 | /* firmware */ | ||
181 | /* Write in small blocks */ | ||
182 | u8 obuf[19]; | ||
183 | obuf[0] = 0xaa; | ||
184 | obuf[1] = 0x11; | ||
185 | obuf[2] = 0xf7; | ||
186 | len = msg[0].len - 1; | ||
187 | i = 1; | ||
188 | do { | ||
189 | memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len)); | ||
190 | ret = dw2102_op_rw(d->udev, 0xc2, 0, 0, | ||
191 | obuf, (len > 16 ? 16 : len) + 3, DW2102_WRITE_MSG); | ||
192 | i += 16; | ||
193 | len -= 16; | ||
194 | } while (len > 0); | ||
195 | } else { | ||
196 | /* write to register */ | ||
197 | u8 obuf[msg[0].len + 2]; | ||
198 | obuf[0] = 0xaa; | ||
199 | obuf[1] = msg[0].len; | ||
200 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | ||
201 | ret = dw2102_op_rw(d->udev, 0xc2, 0, 0, | ||
202 | obuf, msg[0].len + 2, DW2102_WRITE_MSG); | ||
203 | } | ||
204 | break; | ||
205 | } | ||
206 | case(DW2102_RC_QUERY): { | ||
207 | u8 ibuf[2]; | ||
208 | ret = dw2102_op_rw(d->udev, 0xb8, 0, 0, | ||
209 | ibuf, 2, DW2102_READ_MSG); | ||
210 | memcpy(msg[0].buf, ibuf , 2); | ||
211 | break; | ||
212 | } | ||
213 | case(DW2102_VOLTAGE_CTRL): { | ||
214 | u8 obuf[2]; | ||
215 | obuf[0] = 0x30; | ||
216 | obuf[1] = msg[0].buf[0]; | ||
217 | ret = dw2102_op_rw(d->udev, 0xb2, 0, 0, | ||
218 | obuf, 2, DW2102_WRITE_MSG); | ||
219 | break; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | break; | ||
224 | } | ||
225 | |||
226 | mutex_unlock(&d->i2c_mutex); | ||
227 | return num; | ||
228 | } | ||
229 | |||
139 | static u32 dw2102_i2c_func(struct i2c_adapter *adapter) | 230 | static u32 dw2102_i2c_func(struct i2c_adapter *adapter) |
140 | { | 231 | { |
141 | return I2C_FUNC_I2C; | 232 | return I2C_FUNC_I2C; |
@@ -146,6 +237,34 @@ static struct i2c_algorithm dw2102_i2c_algo = { | |||
146 | .functionality = dw2102_i2c_func, | 237 | .functionality = dw2102_i2c_func, |
147 | }; | 238 | }; |
148 | 239 | ||
240 | static struct i2c_algorithm dw2104_i2c_algo = { | ||
241 | .master_xfer = dw2104_i2c_transfer, | ||
242 | .functionality = dw2102_i2c_func, | ||
243 | }; | ||
244 | |||
245 | static int dw2102_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | ||
246 | { | ||
247 | int i; | ||
248 | u8 ibuf[] = {0, 0}; | ||
249 | u8 eeprom[256], eepromline[16]; | ||
250 | |||
251 | for (i = 0; i < 256; i++) { | ||
252 | if (dw2102_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW2102_READ_MSG) < 0) { | ||
253 | err("read eeprom failed."); | ||
254 | return -1; | ||
255 | } else { | ||
256 | eepromline[i%16] = ibuf[0]; | ||
257 | eeprom[i] = ibuf[0]; | ||
258 | } | ||
259 | if ((i % 16) == 15) { | ||
260 | deb_xfer("%02x: ", i - 15); | ||
261 | debug_dump(eepromline, 16, deb_xfer); | ||
262 | } | ||
263 | } | ||
264 | memcpy(mac, eeprom + 8, 6); | ||
265 | return 0; | ||
266 | }; | ||
267 | |||
149 | static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 268 | static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
150 | { | 269 | { |
151 | static u8 command_13v[1] = {0x00}; | 270 | static u8 command_13v[1] = {0x00}; |
@@ -163,6 +282,22 @@ static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | |||
163 | return 0; | 282 | return 0; |
164 | } | 283 | } |
165 | 284 | ||
285 | static struct cx24116_config dw2104_config = { | ||
286 | .demod_address = 0x55, | ||
287 | /*.mpg_clk_pos_pol = 0x01,*/ | ||
288 | }; | ||
289 | |||
290 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | ||
291 | { | ||
292 | if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, | ||
293 | &d->dev->i2c_adap)) != NULL) { | ||
294 | d->fe->ops.set_voltage = dw2102_set_voltage; | ||
295 | info("Attached cx24116!\n"); | ||
296 | return 0; | ||
297 | } | ||
298 | return -EIO; | ||
299 | } | ||
300 | |||
166 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) | 301 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) |
167 | { | 302 | { |
168 | d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, | 303 | d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, |
@@ -249,6 +384,8 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
249 | static struct usb_device_id dw2102_table[] = { | 384 | static struct usb_device_id dw2102_table[] = { |
250 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, | 385 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, |
251 | {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, | 386 | {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, |
387 | {USB_DEVICE(USB_VID_CYPRESS, 0x2104)}, | ||
388 | {USB_DEVICE(0x9022, 0xd650)}, | ||
252 | { } | 389 | { } |
253 | }; | 390 | }; |
254 | 391 | ||
@@ -273,25 +410,23 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
273 | return ret; | 410 | return ret; |
274 | } | 411 | } |
275 | break; | 412 | break; |
276 | case USB_PID_DW2102: | 413 | default: |
277 | fw = frmwr; | 414 | fw = frmwr; |
278 | break; | 415 | break; |
279 | } | 416 | } |
280 | info("start downloading DW2102 firmware"); | 417 | info("start downloading DW210X firmware"); |
281 | p = kmalloc(fw->size, GFP_KERNEL); | 418 | p = kmalloc(fw->size, GFP_KERNEL); |
282 | reset = 1; | 419 | reset = 1; |
283 | /*stop the CPU*/ | 420 | /*stop the CPU*/ |
284 | dw2102_op_rw(dev, 0xa0, 0x7f92, &reset, 1, DW2102_WRITE_MSG); | 421 | dw2102_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW2102_WRITE_MSG); |
285 | dw2102_op_rw(dev, 0xa0, 0xe600, &reset, 1, DW2102_WRITE_MSG); | 422 | dw2102_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW2102_WRITE_MSG); |
286 | 423 | ||
287 | if (p != NULL) { | 424 | if (p != NULL) { |
288 | memcpy(p, fw->data, fw->size); | 425 | memcpy(p, fw->data, fw->size); |
289 | for (i = 0; i < fw->size; i += 0x40) { | 426 | for (i = 0; i < fw->size; i += 0x40) { |
290 | b = (u8 *) p + i; | 427 | b = (u8 *) p + i; |
291 | if (dw2102_op_rw | 428 | if (dw2102_op_rw(dev, 0xa0, i, 0, b , 0x40, |
292 | (dev, 0xa0, i, b , 0x40, | 429 | DW2102_WRITE_MSG) != 0x40) { |
293 | DW2102_WRITE_MSG) != 0x40 | ||
294 | ) { | ||
295 | err("error while transferring firmware"); | 430 | err("error while transferring firmware"); |
296 | ret = -EINVAL; | 431 | ret = -EINVAL; |
297 | break; | 432 | break; |
@@ -299,43 +434,45 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
299 | } | 434 | } |
300 | /* restart the CPU */ | 435 | /* restart the CPU */ |
301 | reset = 0; | 436 | reset = 0; |
302 | if (ret || dw2102_op_rw | 437 | if (ret || dw2102_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, |
303 | (dev, 0xa0, 0x7f92, &reset, 1, | 438 | DW2102_WRITE_MSG) != 1) { |
304 | DW2102_WRITE_MSG) != 1) { | ||
305 | err("could not restart the USB controller CPU."); | 439 | err("could not restart the USB controller CPU."); |
306 | ret = -EINVAL; | 440 | ret = -EINVAL; |
307 | } | 441 | } |
308 | if (ret || dw2102_op_rw | 442 | if (ret || dw2102_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, |
309 | (dev, 0xa0, 0xe600, &reset, 1, | 443 | DW2102_WRITE_MSG) != 1) { |
310 | DW2102_WRITE_MSG) != 1) { | ||
311 | err("could not restart the USB controller CPU."); | 444 | err("could not restart the USB controller CPU."); |
312 | ret = -EINVAL; | 445 | ret = -EINVAL; |
313 | } | 446 | } |
314 | /* init registers */ | 447 | /* init registers */ |
315 | switch (dev->descriptor.idProduct) { | 448 | switch (dev->descriptor.idProduct) { |
449 | case USB_PID_DW2104: | ||
450 | case 0xd650: | ||
451 | reset = 1; | ||
452 | dw2102_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, | ||
453 | DW2102_WRITE_MSG); | ||
454 | reset = 0; | ||
455 | dw2102_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, | ||
456 | DW2102_WRITE_MSG); | ||
457 | break; | ||
316 | case USB_PID_DW2102: | 458 | case USB_PID_DW2102: |
317 | dw2102_op_rw | 459 | dw2102_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, |
318 | (dev, 0xbf, 0x0040, &reset, 0, | 460 | DW2102_WRITE_MSG); |
319 | DW2102_WRITE_MSG); | 461 | dw2102_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, |
320 | dw2102_op_rw | 462 | DW2102_READ_MSG); |
321 | (dev, 0xb9, 0x0000, &reset16[0], 2, | ||
322 | DW2102_READ_MSG); | ||
323 | break; | 463 | break; |
324 | case 0x2101: | 464 | case 0x2101: |
325 | dw2102_op_rw | 465 | dw2102_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2, |
326 | (dev, 0xbc, 0x0030, &reset16[0], 2, | 466 | DW2102_READ_MSG); |
327 | DW2102_READ_MSG); | 467 | dw2102_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, |
328 | dw2102_op_rw | 468 | DW2102_READ_MSG); |
329 | (dev, 0xba, 0x0000, &reset16[0], 7, | 469 | dw2102_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, |
330 | DW2102_READ_MSG); | 470 | DW2102_READ_MSG); |
331 | dw2102_op_rw | 471 | dw2102_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, |
332 | (dev, 0xba, 0x0000, &reset16[0], 7, | 472 | DW2102_READ_MSG); |
333 | DW2102_READ_MSG); | ||
334 | dw2102_op_rw | ||
335 | (dev, 0xb9, 0x0000, &reset16[0], 2, | ||
336 | DW2102_READ_MSG); | ||
337 | break; | 473 | break; |
338 | } | 474 | } |
475 | msleep(100); | ||
339 | kfree(p); | 476 | kfree(p); |
340 | } | 477 | } |
341 | return ret; | 478 | return ret; |
@@ -358,7 +495,8 @@ static struct dvb_usb_device_properties dw2102_properties = { | |||
358 | /* parameter for the MPEG2-data transfer */ | 495 | /* parameter for the MPEG2-data transfer */ |
359 | .num_adapters = 1, | 496 | .num_adapters = 1, |
360 | .download_firmware = dw2102_load_firmware, | 497 | .download_firmware = dw2102_load_firmware, |
361 | .adapter = { | 498 | .read_mac_address = dw2102_read_mac_address, |
499 | .adapter = { | ||
362 | { | 500 | { |
363 | .frontend_attach = dw2102_frontend_attach, | 501 | .frontend_attach = dw2102_frontend_attach, |
364 | .streaming_ctrl = NULL, | 502 | .streaming_ctrl = NULL, |
@@ -388,11 +526,64 @@ static struct dvb_usb_device_properties dw2102_properties = { | |||
388 | } | 526 | } |
389 | }; | 527 | }; |
390 | 528 | ||
529 | static struct dvb_usb_device_properties dw2104_properties = { | ||
530 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
531 | .usb_ctrl = DEVICE_SPECIFIC, | ||
532 | .firmware = "dvb-usb-dw2104.fw", | ||
533 | .size_of_priv = sizeof(struct dw2102_state), | ||
534 | .no_reconnect = 1, | ||
535 | |||
536 | .i2c_algo = &dw2104_i2c_algo, | ||
537 | .rc_key_map = dw2102_rc_keys, | ||
538 | .rc_key_map_size = ARRAY_SIZE(dw2102_rc_keys), | ||
539 | .rc_interval = 150, | ||
540 | .rc_query = dw2102_rc_query, | ||
541 | |||
542 | .generic_bulk_ctrl_endpoint = 0x81, | ||
543 | /* parameter for the MPEG2-data transfer */ | ||
544 | .num_adapters = 1, | ||
545 | .download_firmware = dw2102_load_firmware, | ||
546 | .read_mac_address = dw2102_read_mac_address, | ||
547 | .adapter = { | ||
548 | { | ||
549 | .frontend_attach = dw2104_frontend_attach, | ||
550 | .streaming_ctrl = NULL, | ||
551 | /*.tuner_attach = dw2104_tuner_attach,*/ | ||
552 | .stream = { | ||
553 | .type = USB_BULK, | ||
554 | .count = 8, | ||
555 | .endpoint = 0x82, | ||
556 | .u = { | ||
557 | .bulk = { | ||
558 | .buffersize = 4096, | ||
559 | } | ||
560 | } | ||
561 | }, | ||
562 | } | ||
563 | }, | ||
564 | .num_device_descs = 2, | ||
565 | .devices = { | ||
566 | { "DVBWorld DW2104 USB2.0", | ||
567 | {&dw2102_table[2], NULL}, | ||
568 | {NULL}, | ||
569 | }, | ||
570 | { "TeVii S650 USB2.0", | ||
571 | {&dw2102_table[3], NULL}, | ||
572 | {NULL}, | ||
573 | }, | ||
574 | } | ||
575 | }; | ||
576 | |||
391 | static int dw2102_probe(struct usb_interface *intf, | 577 | static int dw2102_probe(struct usb_interface *intf, |
392 | const struct usb_device_id *id) | 578 | const struct usb_device_id *id) |
393 | { | 579 | { |
394 | return dvb_usb_device_init(intf, &dw2102_properties, | 580 | if (0 == dvb_usb_device_init(intf, &dw2102_properties, |
395 | THIS_MODULE, NULL, adapter_nr); | 581 | THIS_MODULE, NULL, adapter_nr) || |
582 | 0 == dvb_usb_device_init(intf, &dw2104_properties, | ||
583 | THIS_MODULE, NULL, adapter_nr)) { | ||
584 | return 0; | ||
585 | } | ||
586 | return -ENODEV; | ||
396 | } | 587 | } |
397 | 588 | ||
398 | static struct usb_driver dw2102_driver = { | 589 | static struct usb_driver dw2102_driver = { |
@@ -420,6 +611,6 @@ module_init(dw2102_module_init); | |||
420 | module_exit(dw2102_module_exit); | 611 | module_exit(dw2102_module_exit); |
421 | 612 | ||
422 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | 613 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); |
423 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101 2102 USB2.0 device"); | 614 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device"); |
424 | MODULE_VERSION("0.1"); | 615 | MODULE_VERSION("0.1"); |
425 | MODULE_LICENSE("GPL"); | 616 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h index 7a310f906837..e3370734e95a 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.h +++ b/drivers/media/dvb/dvb-usb/dw2102.h | |||
@@ -4,6 +4,5 @@ | |||
4 | #define DVB_USB_LOG_PREFIX "dw2102" | 4 | #define DVB_USB_LOG_PREFIX "dw2102" |
5 | #include "dvb-usb.h" | 5 | #include "dvb-usb.h" |
6 | 6 | ||
7 | extern int dvb_usb_dw2102_debug; | ||
8 | #define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) | 7 | #define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) |
9 | #endif | 8 | #endif |