1 /* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
6 * Thanks to Steve Chang from WideView for providing support for the WT-220U.
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.
12 * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
17 int dvb_usb_dtt200u_debug
;
18 module_param_named(debug
,dvb_usb_dtt200u_debug
, int, 0644);
19 MODULE_PARM_DESC(debug
, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS
);
21 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
23 struct dtt200u_state
{
24 unsigned char data
[80];
27 static int dtt200u_power_ctrl(struct dvb_usb_device
*d
, int onoff
)
29 struct dtt200u_state
*st
= d
->priv
;
32 mutex_lock(&d
->data_mutex
);
34 st
->data
[0] = SET_INIT
;
37 ret
= dvb_usb_generic_write(d
, st
->data
, 2);
39 mutex_unlock(&d
->data_mutex
);
43 static int dtt200u_streaming_ctrl(struct dvb_usb_adapter
*adap
, int onoff
)
45 struct dvb_usb_device
*d
= adap
->dev
;
46 struct dtt200u_state
*st
= d
->priv
;
49 mutex_lock(&d
->data_mutex
);
50 st
->data
[0] = SET_STREAMING
;
53 ret
= dvb_usb_generic_write(adap
->dev
, st
->data
, 2);
60 st
->data
[0] = RESET_PID_FILTER
;
61 ret
= dvb_usb_generic_write(adap
->dev
, st
->data
, 1);
64 mutex_unlock(&d
->data_mutex
);
69 static int dtt200u_pid_filter(struct dvb_usb_adapter
*adap
, int index
, u16 pid
, int onoff
)
71 struct dvb_usb_device
*d
= adap
->dev
;
72 struct dtt200u_state
*st
= d
->priv
;
75 pid
= onoff
? pid
: 0;
77 mutex_lock(&d
->data_mutex
);
78 st
->data
[0] = SET_PID_FILTER
;
80 st
->data
[2] = pid
& 0xff;
81 st
->data
[3] = (pid
>> 8) & 0x1f;
83 ret
= dvb_usb_generic_write(adap
->dev
, st
->data
, 4);
84 mutex_unlock(&d
->data_mutex
);
89 static int dtt200u_rc_query(struct dvb_usb_device
*d
)
91 struct dtt200u_state
*st
= d
->priv
;
95 mutex_lock(&d
->data_mutex
);
96 st
->data
[0] = GET_RC_CODE
;
98 ret
= dvb_usb_generic_rw(d
, st
->data
, 1, st
->data
, 5, 0);
102 if (st
->data
[0] == 1) {
103 enum rc_proto proto
= RC_PROTO_NEC
;
105 scancode
= st
->data
[1];
106 if ((u8
) ~st
->data
[1] != st
->data
[2]) {
108 scancode
= scancode
<< 8;
109 scancode
|= st
->data
[2];
110 proto
= RC_PROTO_NECX
;
112 scancode
= scancode
<< 8;
113 scancode
|= st
->data
[3];
115 /* Check command checksum is ok */
116 if ((u8
) ~st
->data
[3] == st
->data
[4])
117 rc_keydown(d
->rc_dev
, proto
, scancode
, 0);
120 } else if (st
->data
[0] == 2) {
121 rc_repeat(d
->rc_dev
);
126 if (st
->data
[0] != 0)
127 deb_info("st->data: %*ph\n", 5, st
->data
);
130 mutex_unlock(&d
->data_mutex
);
134 static int dtt200u_frontend_attach(struct dvb_usb_adapter
*adap
)
136 adap
->fe_adap
[0].fe
= dtt200u_fe_attach(adap
->dev
);
140 static struct dvb_usb_device_properties dtt200u_properties
;
141 static struct dvb_usb_device_properties wt220u_fc_properties
;
142 static struct dvb_usb_device_properties wt220u_properties
;
143 static struct dvb_usb_device_properties wt220u_zl0353_properties
;
144 static struct dvb_usb_device_properties wt220u_miglia_properties
;
146 static int dtt200u_usb_probe(struct usb_interface
*intf
,
147 const struct usb_device_id
*id
)
149 if (0 == dvb_usb_device_init(intf
, &dtt200u_properties
,
150 THIS_MODULE
, NULL
, adapter_nr
) ||
151 0 == dvb_usb_device_init(intf
, &wt220u_properties
,
152 THIS_MODULE
, NULL
, adapter_nr
) ||
153 0 == dvb_usb_device_init(intf
, &wt220u_fc_properties
,
154 THIS_MODULE
, NULL
, adapter_nr
) ||
155 0 == dvb_usb_device_init(intf
, &wt220u_zl0353_properties
,
156 THIS_MODULE
, NULL
, adapter_nr
) ||
157 0 == dvb_usb_device_init(intf
, &wt220u_miglia_properties
,
158 THIS_MODULE
, NULL
, adapter_nr
))
164 static struct usb_device_id dtt200u_usb_table
[] = {
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
) },
169 { USB_DEVICE(USB_VID_WIDEVIEW
, USB_PID_WT220U_ZL0353_COLD
) },
170 { USB_DEVICE(USB_VID_WIDEVIEW
, USB_PID_WT220U_ZL0353_WARM
) },
171 { USB_DEVICE(USB_VID_WIDEVIEW
, USB_PID_WT220U_FC_COLD
) },
172 { USB_DEVICE(USB_VID_WIDEVIEW
, USB_PID_WT220U_FC_WARM
) },
173 { USB_DEVICE(USB_VID_WIDEVIEW
, USB_PID_WT220U_ZAP250_COLD
) },
174 { USB_DEVICE(USB_VID_MIGLIA
, USB_PID_WT220U_ZAP250_COLD
) },
177 MODULE_DEVICE_TABLE(usb
, dtt200u_usb_table
);
179 static struct dvb_usb_device_properties dtt200u_properties
= {
180 .usb_ctrl
= CYPRESS_FX2
,
181 .firmware
= "dvb-usb-dtt200u-01.fw",
183 .size_of_priv
= sizeof(struct dtt200u_state
),
190 .caps
= DVB_USB_ADAP_HAS_PID_FILTER
| DVB_USB_ADAP_NEED_PID_FILTERING
,
191 .pid_filter_count
= 15,
193 .streaming_ctrl
= dtt200u_streaming_ctrl
,
194 .pid_filter
= dtt200u_pid_filter
,
195 .frontend_attach
= dtt200u_frontend_attach
,
196 /* parameter for the MPEG2-data transfer */
210 .power_ctrl
= dtt200u_power_ctrl
,
214 .rc_codes
= RC_MAP_DTT200U
,
215 .rc_query
= dtt200u_rc_query
,
216 .allowed_protos
= RC_PROTO_BIT_NEC
,
219 .generic_bulk_ctrl_endpoint
= 0x01,
221 .num_device_descs
= 1,
223 { .name
= "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
224 .cold_ids
= { &dtt200u_usb_table
[0], NULL
},
225 .warm_ids
= { &dtt200u_usb_table
[1], NULL
},
231 static struct dvb_usb_device_properties wt220u_properties
= {
232 .usb_ctrl
= CYPRESS_FX2
,
233 .firmware
= "dvb-usb-wt220u-02.fw",
235 .size_of_priv
= sizeof(struct dtt200u_state
),
242 .caps
= DVB_USB_ADAP_HAS_PID_FILTER
| DVB_USB_ADAP_NEED_PID_FILTERING
,
243 .pid_filter_count
= 15,
245 .streaming_ctrl
= dtt200u_streaming_ctrl
,
246 .pid_filter
= dtt200u_pid_filter
,
247 .frontend_attach
= dtt200u_frontend_attach
,
248 /* parameter for the MPEG2-data transfer */
262 .power_ctrl
= dtt200u_power_ctrl
,
266 .rc_codes
= RC_MAP_DTT200U
,
267 .rc_query
= dtt200u_rc_query
,
268 .allowed_protos
= RC_PROTO_BIT_NEC
,
271 .generic_bulk_ctrl_endpoint
= 0x01,
273 .num_device_descs
= 1,
275 { .name
= "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
276 .cold_ids
= { &dtt200u_usb_table
[2], &dtt200u_usb_table
[8], NULL
},
277 .warm_ids
= { &dtt200u_usb_table
[3], NULL
},
283 static struct dvb_usb_device_properties wt220u_fc_properties
= {
284 .usb_ctrl
= CYPRESS_FX2
,
285 .firmware
= "dvb-usb-wt220u-fc03.fw",
287 .size_of_priv
= sizeof(struct dtt200u_state
),
294 .caps
= DVB_USB_ADAP_HAS_PID_FILTER
| DVB_USB_ADAP_NEED_PID_FILTERING
,
295 .pid_filter_count
= 15,
297 .streaming_ctrl
= dtt200u_streaming_ctrl
,
298 .pid_filter
= dtt200u_pid_filter
,
299 .frontend_attach
= dtt200u_frontend_attach
,
300 /* parameter for the MPEG2-data transfer */
314 .power_ctrl
= dtt200u_power_ctrl
,
318 .rc_codes
= RC_MAP_DTT200U
,
319 .rc_query
= dtt200u_rc_query
,
320 .allowed_protos
= RC_PROTO_BIT_NEC
,
323 .generic_bulk_ctrl_endpoint
= 0x01,
325 .num_device_descs
= 1,
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
},
335 static struct dvb_usb_device_properties wt220u_zl0353_properties
= {
336 .usb_ctrl
= CYPRESS_FX2
,
337 .firmware
= "dvb-usb-wt220u-zl0353-01.fw",
339 .size_of_priv
= sizeof(struct dtt200u_state
),
346 .caps
= DVB_USB_ADAP_HAS_PID_FILTER
| DVB_USB_ADAP_NEED_PID_FILTERING
,
347 .pid_filter_count
= 15,
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 */
366 .power_ctrl
= dtt200u_power_ctrl
,
370 .rc_codes
= RC_MAP_DTT200U
,
371 .rc_query
= dtt200u_rc_query
,
372 .allowed_protos
= RC_PROTO_BIT_NEC
,
375 .generic_bulk_ctrl_endpoint
= 0x01,
377 .num_device_descs
= 1,
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
},
387 static struct dvb_usb_device_properties wt220u_miglia_properties
= {
388 .usb_ctrl
= CYPRESS_FX2
,
389 .firmware
= "dvb-usb-wt220u-miglia-01.fw",
391 .size_of_priv
= sizeof(struct dtt200u_state
),
394 .generic_bulk_ctrl_endpoint
= 0x01,
396 .num_device_descs
= 1,
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
402 .warm_ids
= { NULL
},
408 /* usb specific object needed to register this driver with the usb subsystem */
409 static struct usb_driver dtt200u_usb_driver
= {
410 .name
= "dvb_usb_dtt200u",
411 .probe
= dtt200u_usb_probe
,
412 .disconnect
= dvb_usb_device_exit
,
413 .id_table
= dtt200u_usb_table
,
416 module_usb_driver(dtt200u_usb_driver
);
418 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
419 MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
420 MODULE_VERSION("1.0");
421 MODULE_LICENSE("GPL");