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