]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/media/usb/dvb-usb/dtt200u.c
Merge remote-tracking branches 'asoc/topic/inntel', 'asoc/topic/input', 'asoc/topic...
[mirror_ubuntu-bionic-kernel.git] / drivers / media / usb / dvb-usb / dtt200u.c
CommitLineData
fb41f5a7 1/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
d3c35acf 2 * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
776338e1 3 *
99e44da7 4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
776338e1 5 *
d590f9c2
PB
6 * Thanks to Steve Chang from WideView for providing support for the WT-220U.
7 *
776338e1
JS
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dtt200u.h"
15
16/* debug */
17int dvb_usb_dtt200u_debug;
18module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
20
78e92006
JG
21DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
22
ab883e2d
MCC
23struct dtt200u_state {
24 unsigned char data[80];
ab883e2d
MCC
25};
26
d590f9c2
PB
27static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
28{
ab883e2d 29 struct dtt200u_state *st = d->priv;
a3f9f07e 30 int ret = 0;
ab883e2d 31
7724325a 32 mutex_lock(&d->data_mutex);
ab883e2d
MCC
33
34 st->data[0] = SET_INIT;
d590f9c2
PB
35
36 if (onoff)
a3f9f07e 37 ret = dvb_usb_generic_write(d, st->data, 2);
d590f9c2 38
7724325a 39 mutex_unlock(&d->data_mutex);
a3f9f07e 40 return ret;
d590f9c2
PB
41}
42
4d43e13f 43static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
776338e1 44{
7724325a
MCC
45 struct dvb_usb_device *d = adap->dev;
46 struct dtt200u_state *st = d->priv;
a3f9f07e 47 int ret;
ab883e2d 48
7724325a 49 mutex_lock(&d->data_mutex);
ab883e2d
MCC
50 st->data[0] = SET_STREAMING;
51 st->data[1] = onoff;
776338e1 52
a3f9f07e
MCC
53 ret = dvb_usb_generic_write(adap->dev, st->data, 2);
54 if (ret < 0)
55 goto ret;
ab883e2d
MCC
56
57 if (onoff)
a3f9f07e 58 goto ret;
ab883e2d
MCC
59
60 st->data[0] = RESET_PID_FILTER;
a3f9f07e 61 ret = dvb_usb_generic_write(adap->dev, st->data, 1);
ab883e2d 62
a3f9f07e 63ret:
7724325a 64 mutex_unlock(&d->data_mutex);
776338e1 65
a3f9f07e 66 return ret;
776338e1
JS
67}
68
4d43e13f 69static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
776338e1 70{
7724325a
MCC
71 struct dvb_usb_device *d = adap->dev;
72 struct dtt200u_state *st = d->priv;
ab883e2d
MCC
73 int ret;
74
776338e1
JS
75 pid = onoff ? pid : 0;
76
7724325a 77 mutex_lock(&d->data_mutex);
ab883e2d
MCC
78 st->data[0] = SET_PID_FILTER;
79 st->data[1] = index;
80 st->data[2] = pid & 0xff;
81 st->data[3] = (pid >> 8) & 0x1f;
776338e1 82
ab883e2d 83 ret = dvb_usb_generic_write(adap->dev, st->data, 4);
7724325a 84 mutex_unlock(&d->data_mutex);
ab883e2d
MCC
85
86 return ret;
776338e1
JS
87}
88
a4d020e9 89static int dtt200u_rc_query(struct dvb_usb_device *d)
776338e1 90{
ab883e2d 91 struct dtt200u_state *st = d->priv;
a4d020e9 92 u32 scancode;
a3f9f07e 93 int ret;
a4d020e9 94
7724325a 95 mutex_lock(&d->data_mutex);
ab883e2d
MCC
96 st->data[0] = GET_RC_CODE;
97
a3f9f07e
MCC
98 ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0);
99 if (ret < 0)
100 goto ret;
101
ab883e2d 102 if (st->data[0] == 1) {
2ceeca04
SY
103 enum rc_type proto = RC_TYPE_NEC;
104
ab883e2d
MCC
105 scancode = st->data[1];
106 if ((u8) ~st->data[1] != st->data[2]) {
a4d020e9
JM
107 /* Extended NEC */
108 scancode = scancode << 8;
ab883e2d 109 scancode |= st->data[2];
2ceeca04 110 proto = RC_TYPE_NECX;
a4d020e9
JM
111 }
112 scancode = scancode << 8;
ab883e2d 113 scancode |= st->data[3];
a4d020e9
JM
114
115 /* Check command checksum is ok */
ab883e2d 116 if ((u8) ~st->data[3] == st->data[4])
2ceeca04 117 rc_keydown(d->rc_dev, proto, scancode, 0);
a4d020e9
JM
118 else
119 rc_keyup(d->rc_dev);
ab883e2d 120 } else if (st->data[0] == 2) {
a4d020e9
JM
121 rc_repeat(d->rc_dev);
122 } else {
123 rc_keyup(d->rc_dev);
124 }
125
ab883e2d
MCC
126 if (st->data[0] != 0)
127 deb_info("st->data: %*ph\n", 5, st->data);
a4d020e9 128
a3f9f07e 129ret:
7724325a 130 mutex_unlock(&d->data_mutex);
a3f9f07e 131 return ret;
776338e1
JS
132}
133
4d43e13f 134static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap)
776338e1 135{
77eed219 136 adap->fe_adap[0].fe = dtt200u_fe_attach(adap->dev);
776338e1
JS
137 return 0;
138}
139
4d43e13f
PB
140static struct dvb_usb_device_properties dtt200u_properties;
141static struct dvb_usb_device_properties wt220u_fc_properties;
142static struct dvb_usb_device_properties wt220u_properties;
143static struct dvb_usb_device_properties wt220u_zl0353_properties;
d3c35acf 144static struct dvb_usb_device_properties wt220u_miglia_properties;
776338e1
JS
145
146static int dtt200u_usb_probe(struct usb_interface *intf,
147 const struct usb_device_id *id)
148{
78e92006 149 if (0 == dvb_usb_device_init(intf, &dtt200u_properties,
7724325a 150 THIS_MODULE, NULL, adapter_nr) ||
78e92006 151 0 == dvb_usb_device_init(intf, &wt220u_properties,
7724325a 152 THIS_MODULE, NULL, adapter_nr) ||
78e92006 153 0 == dvb_usb_device_init(intf, &wt220u_fc_properties,
7724325a 154 THIS_MODULE, NULL, adapter_nr) ||
78e92006 155 0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties,
7724325a 156 THIS_MODULE, NULL, adapter_nr) ||
78e92006 157 0 == dvb_usb_device_init(intf, &wt220u_miglia_properties,
7724325a 158 THIS_MODULE, NULL, adapter_nr))
d590f9c2
PB
159 return 0;
160
161 return -ENODEV;
776338e1
JS
162}
163
164static struct usb_device_id dtt200u_usb_table [] = {
62703b9d
PB
165 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
166 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
167 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
168 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
d46e6451
PB
169 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) },
170 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) },
19e22576
AT
171 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD) },
172 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM) },
ded38d28 173 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD) },
d3c35acf 174 { USB_DEVICE(USB_VID_MIGLIA, USB_PID_WT220U_ZAP250_COLD) },
62703b9d 175 { 0 },
776338e1
JS
176};
177MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
178
4d43e13f 179static struct dvb_usb_device_properties dtt200u_properties = {
776338e1
JS
180 .usb_ctrl = CYPRESS_FX2,
181 .firmware = "dvb-usb-dtt200u-01.fw",
182
ab883e2d
MCC
183 .size_of_priv = sizeof(struct dtt200u_state),
184
4d43e13f
PB
185 .num_adapters = 1,
186 .adapter = {
187 {
77eed219
MK
188 .num_frontends = 1,
189 .fe = {{
4d43e13f
PB
190 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
191 .pid_filter_count = 15,
192
776338e1
JS
193 .streaming_ctrl = dtt200u_streaming_ctrl,
194 .pid_filter = dtt200u_pid_filter,
195 .frontend_attach = dtt200u_frontend_attach,
776338e1 196 /* parameter for the MPEG2-data transfer */
4d43e13f
PB
197 .stream = {
198 .type = USB_BULK,
776338e1
JS
199 .count = 7,
200 .endpoint = 0x02,
201 .u = {
202 .bulk = {
203 .buffersize = 4096,
204 }
205 }
206 },
77eed219 207 }},
4d43e13f
PB
208 }
209 },
210 .power_ctrl = dtt200u_power_ctrl,
211
a4d020e9 212 .rc.core = {
f72a27b8 213 .rc_interval = 300,
a4d020e9 214 .rc_codes = RC_MAP_DTT200U,
f72a27b8 215 .rc_query = dtt200u_rc_query,
a4d020e9 216 .allowed_protos = RC_BIT_NEC,
f72a27b8 217 },
4d43e13f
PB
218
219 .generic_bulk_ctrl_endpoint = 0x01,
776338e1
JS
220
221 .num_device_descs = 1,
222 .devices = {
d590f9c2 223 { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
fb41f5a7 224 .cold_ids = { &dtt200u_usb_table[0], NULL },
776338e1
JS
225 .warm_ids = { &dtt200u_usb_table[1], NULL },
226 },
dad08dfc 227 { NULL },
776338e1
JS
228 }
229};
230
4d43e13f 231static struct dvb_usb_device_properties wt220u_properties = {
d590f9c2 232 .usb_ctrl = CYPRESS_FX2,
6ce17c57 233 .firmware = "dvb-usb-wt220u-02.fw",
d590f9c2 234
ab883e2d
MCC
235 .size_of_priv = sizeof(struct dtt200u_state),
236
4d43e13f
PB
237 .num_adapters = 1,
238 .adapter = {
239 {
77eed219
MK
240 .num_frontends = 1,
241 .fe = {{
4d43e13f
PB
242 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
243 .pid_filter_count = 15,
244
d590f9c2
PB
245 .streaming_ctrl = dtt200u_streaming_ctrl,
246 .pid_filter = dtt200u_pid_filter,
247 .frontend_attach = dtt200u_frontend_attach,
d590f9c2 248 /* parameter for the MPEG2-data transfer */
4d43e13f
PB
249 .stream = {
250 .type = USB_BULK,
d590f9c2
PB
251 .count = 7,
252 .endpoint = 0x02,
253 .u = {
254 .bulk = {
255 .buffersize = 4096,
256 }
257 }
258 },
77eed219 259 }},
4d43e13f
PB
260 }
261 },
262 .power_ctrl = dtt200u_power_ctrl,
263
a4d020e9 264 .rc.core = {
f72a27b8 265 .rc_interval = 300,
a4d020e9 266 .rc_codes = RC_MAP_DTT200U,
f72a27b8 267 .rc_query = dtt200u_rc_query,
a4d020e9 268 .allowed_protos = RC_BIT_NEC,
f72a27b8 269 },
4d43e13f
PB
270
271 .generic_bulk_ctrl_endpoint = 0x01,
d590f9c2
PB
272
273 .num_device_descs = 1,
274 .devices = {
62703b9d 275 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
ded38d28 276 .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL },
d590f9c2
PB
277 .warm_ids = { &dtt200u_usb_table[3], NULL },
278 },
dad08dfc 279 { NULL },
d590f9c2
PB
280 }
281};
282
4d43e13f 283static struct dvb_usb_device_properties wt220u_fc_properties = {
19e22576
AT
284 .usb_ctrl = CYPRESS_FX2,
285 .firmware = "dvb-usb-wt220u-fc03.fw",
286
ab883e2d
MCC
287 .size_of_priv = sizeof(struct dtt200u_state),
288
4d43e13f
PB
289 .num_adapters = 1,
290 .adapter = {
291 {
77eed219
MK
292 .num_frontends = 1,
293 .fe = {{
4d43e13f
PB
294 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
295 .pid_filter_count = 15,
296
19e22576
AT
297 .streaming_ctrl = dtt200u_streaming_ctrl,
298 .pid_filter = dtt200u_pid_filter,
299 .frontend_attach = dtt200u_frontend_attach,
19e22576 300 /* parameter for the MPEG2-data transfer */
4d43e13f
PB
301 .stream = {
302 .type = USB_BULK,
19e22576 303 .count = 7,
4d43e13f 304 .endpoint = 0x06,
19e22576
AT
305 .u = {
306 .bulk = {
307 .buffersize = 4096,
308 }
309 }
310 },
77eed219 311 }},
4d43e13f
PB
312 }
313 },
314 .power_ctrl = dtt200u_power_ctrl,
315
a4d020e9 316 .rc.core = {
f72a27b8 317 .rc_interval = 300,
a4d020e9 318 .rc_codes = RC_MAP_DTT200U,
f72a27b8 319 .rc_query = dtt200u_rc_query,
a4d020e9 320 .allowed_protos = RC_BIT_NEC,
f72a27b8 321 },
4d43e13f
PB
322
323 .generic_bulk_ctrl_endpoint = 0x01,
19e22576
AT
324
325 .num_device_descs = 1,
326 .devices = {
327 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
328 .cold_ids = { &dtt200u_usb_table[6], NULL },
329 .warm_ids = { &dtt200u_usb_table[7], NULL },
330 },
331 { NULL },
332 }
333};
334
4d43e13f 335static struct dvb_usb_device_properties wt220u_zl0353_properties = {
d46e6451
PB
336 .usb_ctrl = CYPRESS_FX2,
337 .firmware = "dvb-usb-wt220u-zl0353-01.fw",
338
ab883e2d
MCC
339 .size_of_priv = sizeof(struct dtt200u_state),
340
4d43e13f
PB
341 .num_adapters = 1,
342 .adapter = {
343 {
77eed219
MK
344 .num_frontends = 1,
345 .fe = {{
4d43e13f
PB
346 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
347 .pid_filter_count = 15,
348
01451e72
PB
349 .streaming_ctrl = dtt200u_streaming_ctrl,
350 .pid_filter = dtt200u_pid_filter,
351 .frontend_attach = dtt200u_frontend_attach,
352 /* parameter for the MPEG2-data transfer */
4d43e13f
PB
353 .stream = {
354 .type = USB_BULK,
01451e72
PB
355 .count = 7,
356 .endpoint = 0x02,
357 .u = {
358 .bulk = {
359 .buffersize = 4096,
360 }
361 }
362 },
77eed219 363 }},
4d43e13f
PB
364 }
365 },
366 .power_ctrl = dtt200u_power_ctrl,
367
a4d020e9 368 .rc.core = {
f72a27b8 369 .rc_interval = 300,
a4d020e9 370 .rc_codes = RC_MAP_DTT200U,
f72a27b8 371 .rc_query = dtt200u_rc_query,
a4d020e9 372 .allowed_protos = RC_BIT_NEC,
f72a27b8 373 },
4d43e13f
PB
374
375 .generic_bulk_ctrl_endpoint = 0x01,
d46e6451
PB
376
377 .num_device_descs = 1,
378 .devices = {
379 { .name = "WideView WT-220U PenType Receiver (based on ZL353)",
380 .cold_ids = { &dtt200u_usb_table[4], NULL },
381 .warm_ids = { &dtt200u_usb_table[5], NULL },
382 },
383 { NULL },
384 }
385};
386
d3c35acf
RR
387static struct dvb_usb_device_properties wt220u_miglia_properties = {
388 .usb_ctrl = CYPRESS_FX2,
389 .firmware = "dvb-usb-wt220u-miglia-01.fw",
390
ab883e2d
MCC
391 .size_of_priv = sizeof(struct dtt200u_state),
392
d3c35acf
RR
393 .num_adapters = 1,
394 .generic_bulk_ctrl_endpoint = 0x01,
395
396 .num_device_descs = 1,
397 .devices = {
398 { .name = "WideView WT-220U PenType Receiver (Miglia)",
399 .cold_ids = { &dtt200u_usb_table[9], NULL },
400 /* This device turns into WT220U_ZL0353_WARM when fw
401 has been uploaded */
402 .warm_ids = { NULL },
403 },
404 { NULL },
405 }
406};
407
776338e1
JS
408/* usb specific object needed to register this driver with the usb subsystem */
409static struct usb_driver dtt200u_usb_driver = {
d590f9c2 410 .name = "dvb_usb_dtt200u",
62703b9d 411 .probe = dtt200u_usb_probe,
776338e1 412 .disconnect = dvb_usb_device_exit,
62703b9d 413 .id_table = dtt200u_usb_table,
776338e1
JS
414};
415
ecb3b2b3 416module_usb_driver(dtt200u_usb_driver);
776338e1 417
99e44da7 418MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
d3c35acf 419MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
776338e1
JS
420MODULE_VERSION("1.0");
421MODULE_LICENSE("GPL");