xref: /openbmc/linux/drivers/media/usb/dvb-usb-v2/dvbsky.c (revision fec2e415cb18f98c736539e0f971e93a0598c1b2)
1 /*
2  * Driver for DVBSky USB2.0 receiver
3  *
4  * Copyright (C) 2013 Max nibble <nibble.max@gmail.com>
5  *
6  *    This program is free software; you can redistribute it and/or modify
7  *    it under the terms of the GNU General Public License as published by
8  *    the Free Software Foundation; either version 2 of the License, or
9  *    (at your option) any later version.
10  *
11  *    This program is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    GNU General Public License for more details.
15  */
16 
17 #include "dvb_usb.h"
18 #include "m88ds3103.h"
19 #include "ts2020.h"
20 #include "sp2.h"
21 #include "si2168.h"
22 #include "si2157.h"
23 
24 #define DVBSKY_MSG_DELAY	0/*2000*/
25 #define DVBSKY_BUF_LEN	64
26 
27 static int dvb_usb_dvbsky_disable_rc;
28 module_param_named(disable_rc, dvb_usb_dvbsky_disable_rc, int, 0644);
29 MODULE_PARM_DESC(disable_rc, "Disable inbuilt IR receiver.");
30 
31 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
32 
33 struct dvbsky_state {
34 	struct mutex stream_mutex;
35 	u8 ibuf[DVBSKY_BUF_LEN];
36 	u8 obuf[DVBSKY_BUF_LEN];
37 	u8 last_lock;
38 	struct i2c_client *i2c_client_demod;
39 	struct i2c_client *i2c_client_tuner;
40 	struct i2c_client *i2c_client_ci;
41 
42 	/* fe hook functions*/
43 	int (*fe_set_voltage)(struct dvb_frontend *fe,
44 		enum fe_sec_voltage voltage);
45 	int (*fe_read_status)(struct dvb_frontend *fe,
46 		enum fe_status *status);
47 };
48 
49 static int dvbsky_usb_generic_rw(struct dvb_usb_device *d,
50 		u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
51 {
52 	int ret;
53 	struct dvbsky_state *state = d_to_priv(d);
54 
55 	mutex_lock(&d->usb_mutex);
56 	if (wlen != 0)
57 		memcpy(state->obuf, wbuf, wlen);
58 
59 	ret = dvb_usbv2_generic_rw_locked(d, state->obuf, wlen,
60 			state->ibuf, rlen);
61 
62 	if (!ret && (rlen != 0))
63 		memcpy(rbuf, state->ibuf, rlen);
64 
65 	mutex_unlock(&d->usb_mutex);
66 	return ret;
67 }
68 
69 static int dvbsky_stream_ctrl(struct dvb_usb_device *d, u8 onoff)
70 {
71 	struct dvbsky_state *state = d_to_priv(d);
72 	int ret;
73 	u8 obuf_pre[3] = { 0x37, 0, 0 };
74 	u8 obuf_post[3] = { 0x36, 3, 0 };
75 
76 	mutex_lock(&state->stream_mutex);
77 	ret = dvbsky_usb_generic_rw(d, obuf_pre, 3, NULL, 0);
78 	if (!ret && onoff) {
79 		msleep(20);
80 		ret = dvbsky_usb_generic_rw(d, obuf_post, 3, NULL, 0);
81 	}
82 	mutex_unlock(&state->stream_mutex);
83 	return ret;
84 }
85 
86 static int dvbsky_streaming_ctrl(struct dvb_frontend *fe, int onoff)
87 {
88 	struct dvb_usb_device *d = fe_to_d(fe);
89 
90 	return dvbsky_stream_ctrl(d, (onoff == 0) ? 0 : 1);
91 }
92 
93 /* GPIO */
94 static int dvbsky_gpio_ctrl(struct dvb_usb_device *d, u8 gport, u8 value)
95 {
96 	int ret;
97 	u8 obuf[3], ibuf[2];
98 
99 	obuf[0] = 0x0e;
100 	obuf[1] = gport;
101 	obuf[2] = value;
102 	ret = dvbsky_usb_generic_rw(d, obuf, 3, ibuf, 1);
103 	return ret;
104 }
105 
106 /* I2C */
107 static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
108 	int num)
109 {
110 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
111 	int ret = 0;
112 	u8 ibuf[64], obuf[64];
113 
114 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
115 		return -EAGAIN;
116 
117 	if (num > 2) {
118 		dev_err(&d->udev->dev,
119 		"too many i2c messages[%d], max 2.", num);
120 		ret = -EOPNOTSUPP;
121 		goto i2c_error;
122 	}
123 
124 	if (num == 1) {
125 		if (msg[0].len > 60) {
126 			dev_err(&d->udev->dev,
127 			"too many i2c bytes[%d], max 60.",
128 			msg[0].len);
129 			ret = -EOPNOTSUPP;
130 			goto i2c_error;
131 		}
132 		if (msg[0].flags & I2C_M_RD) {
133 			/* single read */
134 			obuf[0] = 0x09;
135 			obuf[1] = 0;
136 			obuf[2] = msg[0].len;
137 			obuf[3] = msg[0].addr;
138 			ret = dvbsky_usb_generic_rw(d, obuf, 4,
139 					ibuf, msg[0].len + 1);
140 			if (!ret)
141 				memcpy(msg[0].buf, &ibuf[1], msg[0].len);
142 		} else {
143 			/* write */
144 			obuf[0] = 0x08;
145 			obuf[1] = msg[0].addr;
146 			obuf[2] = msg[0].len;
147 			memcpy(&obuf[3], msg[0].buf, msg[0].len);
148 			ret = dvbsky_usb_generic_rw(d, obuf,
149 					msg[0].len + 3, ibuf, 1);
150 		}
151 	} else {
152 		if ((msg[0].len > 60) || (msg[1].len > 60)) {
153 			dev_err(&d->udev->dev,
154 			"too many i2c bytes[w-%d][r-%d], max 60.",
155 			msg[0].len, msg[1].len);
156 			ret = -EOPNOTSUPP;
157 			goto i2c_error;
158 		}
159 		/* write then read */
160 		obuf[0] = 0x09;
161 		obuf[1] = msg[0].len;
162 		obuf[2] = msg[1].len;
163 		obuf[3] = msg[0].addr;
164 		memcpy(&obuf[4], msg[0].buf, msg[0].len);
165 		ret = dvbsky_usb_generic_rw(d, obuf,
166 			msg[0].len + 4, ibuf, msg[1].len + 1);
167 		if (!ret)
168 			memcpy(msg[1].buf, &ibuf[1], msg[1].len);
169 	}
170 i2c_error:
171 	mutex_unlock(&d->i2c_mutex);
172 	return (ret) ? ret : num;
173 }
174 
175 static u32 dvbsky_i2c_func(struct i2c_adapter *adapter)
176 {
177 	return I2C_FUNC_I2C;
178 }
179 
180 static struct i2c_algorithm dvbsky_i2c_algo = {
181 	.master_xfer   = dvbsky_i2c_xfer,
182 	.functionality = dvbsky_i2c_func,
183 };
184 
185 #if IS_ENABLED(CONFIG_RC_CORE)
186 static int dvbsky_rc_query(struct dvb_usb_device *d)
187 {
188 	u32 code = 0xffff, scancode;
189 	u8 rc5_command, rc5_system;
190 	u8 obuf[2], ibuf[2], toggle;
191 	int ret;
192 
193 	obuf[0] = 0x10;
194 	ret = dvbsky_usb_generic_rw(d, obuf, 1, ibuf, 2);
195 	if (ret == 0)
196 		code = (ibuf[0] << 8) | ibuf[1];
197 	if (code != 0xffff) {
198 		dev_dbg(&d->udev->dev, "rc code: %x\n", code);
199 		rc5_command = code & 0x3F;
200 		rc5_system = (code & 0x7C0) >> 6;
201 		toggle = (code & 0x800) ? 1 : 0;
202 		scancode = rc5_system << 8 | rc5_command;
203 		rc_keydown(d->rc_dev, RC_PROTO_RC5, scancode, toggle);
204 	}
205 	return 0;
206 }
207 
208 static int dvbsky_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
209 {
210 	if (dvb_usb_dvbsky_disable_rc) {
211 		rc->map_name = NULL;
212 		return 0;
213 	}
214 
215 	rc->allowed_protos = RC_PROTO_BIT_RC5;
216 	rc->query          = dvbsky_rc_query;
217 	rc->interval       = 300;
218 	return 0;
219 }
220 #else
221 	#define dvbsky_get_rc_config NULL
222 #endif
223 
224 static int dvbsky_usb_set_voltage(struct dvb_frontend *fe,
225 	enum fe_sec_voltage voltage)
226 {
227 	struct dvb_usb_device *d = fe_to_d(fe);
228 	struct dvbsky_state *state = d_to_priv(d);
229 	u8 value;
230 
231 	if (voltage == SEC_VOLTAGE_OFF)
232 		value = 0;
233 	else
234 		value = 1;
235 	dvbsky_gpio_ctrl(d, 0x80, value);
236 
237 	return state->fe_set_voltage(fe, voltage);
238 }
239 
240 static int dvbsky_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6])
241 {
242 	struct dvb_usb_device *d = adap_to_d(adap);
243 	u8 obuf[] = { 0x1e, 0x00 };
244 	u8 ibuf[6] = { 0 };
245 	struct i2c_msg msg[] = {
246 		{
247 			.addr = 0x51,
248 			.flags = 0,
249 			.buf = obuf,
250 			.len = 2,
251 		}, {
252 			.addr = 0x51,
253 			.flags = I2C_M_RD,
254 			.buf = ibuf,
255 			.len = 6,
256 		}
257 	};
258 
259 	if (i2c_transfer(&d->i2c_adap, msg, 2) == 2)
260 		memcpy(mac, ibuf, 6);
261 
262 	return 0;
263 }
264 
265 static int dvbsky_usb_read_status(struct dvb_frontend *fe,
266 				  enum fe_status *status)
267 {
268 	struct dvb_usb_device *d = fe_to_d(fe);
269 	struct dvbsky_state *state = d_to_priv(d);
270 	int ret;
271 
272 	ret = state->fe_read_status(fe, status);
273 
274 	/* it need resync slave fifo when signal change from unlock to lock.*/
275 	if ((*status & FE_HAS_LOCK) && (!state->last_lock))
276 		dvbsky_stream_ctrl(d, 1);
277 
278 	state->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0;
279 	return ret;
280 }
281 
282 static int dvbsky_s960_attach(struct dvb_usb_adapter *adap)
283 {
284 	struct dvbsky_state *state = adap_to_priv(adap);
285 	struct dvb_usb_device *d = adap_to_d(adap);
286 	struct i2c_adapter *i2c_adapter;
287 	struct m88ds3103_platform_data m88ds3103_pdata = {};
288 	struct ts2020_config ts2020_config = {};
289 
290 	/* attach demod */
291 	m88ds3103_pdata.clk = 27000000;
292 	m88ds3103_pdata.i2c_wr_max = 33;
293 	m88ds3103_pdata.clk_out = 0;
294 	m88ds3103_pdata.ts_mode = M88DS3103_TS_CI;
295 	m88ds3103_pdata.ts_clk = 16000;
296 	m88ds3103_pdata.ts_clk_pol = 0;
297 	m88ds3103_pdata.agc = 0x99;
298 	m88ds3103_pdata.lnb_hv_pol = 1,
299 	m88ds3103_pdata.lnb_en_pol = 1,
300 
301 	state->i2c_client_demod = dvb_module_probe("m88ds3103", NULL,
302 						   &d->i2c_adap,
303 						   0x68, &m88ds3103_pdata);
304 	if (!state->i2c_client_demod)
305 		return -ENODEV;
306 
307 	adap->fe[0] = m88ds3103_pdata.get_dvb_frontend(state->i2c_client_demod);
308 	i2c_adapter = m88ds3103_pdata.get_i2c_adapter(state->i2c_client_demod);
309 
310 	/* attach tuner */
311 	ts2020_config.fe = adap->fe[0];
312 	ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
313 
314 	state->i2c_client_tuner = dvb_module_probe("ts2020", NULL,
315 						   i2c_adapter,
316 						   0x60, &ts2020_config);
317 	if (!state->i2c_client_tuner) {
318 		dvb_module_release(state->i2c_client_demod);
319 		return -ENODEV;
320 	}
321 
322 	/* delegate signal strength measurement to tuner */
323 	adap->fe[0]->ops.read_signal_strength =
324 			adap->fe[0]->ops.tuner_ops.get_rf_strength;
325 
326 	/* hook fe: need to resync the slave fifo when signal locks. */
327 	state->fe_read_status = adap->fe[0]->ops.read_status;
328 	adap->fe[0]->ops.read_status = dvbsky_usb_read_status;
329 
330 	/* hook fe: LNB off/on is control by Cypress usb chip. */
331 	state->fe_set_voltage = adap->fe[0]->ops.set_voltage;
332 	adap->fe[0]->ops.set_voltage = dvbsky_usb_set_voltage;
333 
334 	return 0;
335 }
336 
337 static int dvbsky_usb_ci_set_voltage(struct dvb_frontend *fe,
338 	enum fe_sec_voltage voltage)
339 {
340 	struct dvb_usb_device *d = fe_to_d(fe);
341 	struct dvbsky_state *state = d_to_priv(d);
342 	u8 value;
343 
344 	if (voltage == SEC_VOLTAGE_OFF)
345 		value = 0;
346 	else
347 		value = 1;
348 	dvbsky_gpio_ctrl(d, 0x00, value);
349 
350 	return state->fe_set_voltage(fe, voltage);
351 }
352 
353 static int dvbsky_ci_ctrl(void *priv, u8 read, int addr,
354 					u8 data, int *mem)
355 {
356 	struct dvb_usb_device *d = priv;
357 	int ret = 0;
358 	u8 command[4], respond[2], command_size, respond_size;
359 
360 	command[1] = (u8)((addr >> 8) & 0xff); /*high part of address*/
361 	command[2] = (u8)(addr & 0xff); /*low part of address*/
362 	if (read) {
363 		command[0] = 0x71;
364 		command_size = 3;
365 		respond_size = 2;
366 	} else {
367 		command[0] = 0x70;
368 		command[3] = data;
369 		command_size = 4;
370 		respond_size = 1;
371 	}
372 	ret = dvbsky_usb_generic_rw(d, command, command_size,
373 			respond, respond_size);
374 	if (ret)
375 		goto err;
376 	if (read)
377 		*mem = respond[1];
378 	return ret;
379 err:
380 	dev_err(&d->udev->dev, "ci control failed=%d\n", ret);
381 	return ret;
382 }
383 
384 static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap)
385 {
386 	struct dvbsky_state *state = adap_to_priv(adap);
387 	struct dvb_usb_device *d = adap_to_d(adap);
388 	struct i2c_adapter *i2c_adapter;
389 	struct m88ds3103_platform_data m88ds3103_pdata = {};
390 	struct ts2020_config ts2020_config = {};
391 	struct sp2_config sp2_config = {};
392 
393 	/* attach demod */
394 	m88ds3103_pdata.clk = 27000000,
395 	m88ds3103_pdata.i2c_wr_max = 33,
396 	m88ds3103_pdata.clk_out = 0,
397 	m88ds3103_pdata.ts_mode = M88DS3103_TS_CI,
398 	m88ds3103_pdata.ts_clk = 10000,
399 	m88ds3103_pdata.ts_clk_pol = 1,
400 	m88ds3103_pdata.agc = 0x99,
401 	m88ds3103_pdata.lnb_hv_pol = 0,
402 	m88ds3103_pdata.lnb_en_pol = 1,
403 
404 	state->i2c_client_demod = dvb_module_probe("m88ds3103", NULL,
405 						   &d->i2c_adap,
406 						   0x68, &m88ds3103_pdata);
407 	if (!state->i2c_client_demod)
408 		return -ENODEV;
409 
410 	adap->fe[0] = m88ds3103_pdata.get_dvb_frontend(state->i2c_client_demod);
411 	i2c_adapter = m88ds3103_pdata.get_i2c_adapter(state->i2c_client_demod);
412 
413 	/* attach tuner */
414 	ts2020_config.fe = adap->fe[0];
415 	ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
416 
417 	state->i2c_client_tuner = dvb_module_probe("ts2020", NULL,
418 						   i2c_adapter,
419 						   0x60, &ts2020_config);
420 	if (!state->i2c_client_tuner) {
421 		dvb_module_release(state->i2c_client_demod);
422 		return -ENODEV;
423 	}
424 
425 	/* attach ci controller */
426 	sp2_config.dvb_adap = &adap->dvb_adap;
427 	sp2_config.priv = d;
428 	sp2_config.ci_control = dvbsky_ci_ctrl;
429 
430 	state->i2c_client_ci = dvb_module_probe("sp2", NULL,
431 						&d->i2c_adap,
432 						0x40, &sp2_config);
433 
434 	if (!state->i2c_client_ci) {
435 		dvb_module_release(state->i2c_client_tuner);
436 		dvb_module_release(state->i2c_client_demod);
437 		return -ENODEV;
438 	}
439 
440 	/* delegate signal strength measurement to tuner */
441 	adap->fe[0]->ops.read_signal_strength =
442 			adap->fe[0]->ops.tuner_ops.get_rf_strength;
443 
444 	/* hook fe: need to resync the slave fifo when signal locks. */
445 	state->fe_read_status = adap->fe[0]->ops.read_status;
446 	adap->fe[0]->ops.read_status = dvbsky_usb_read_status;
447 
448 	/* hook fe: LNB off/on is control by Cypress usb chip. */
449 	state->fe_set_voltage = adap->fe[0]->ops.set_voltage;
450 	adap->fe[0]->ops.set_voltage = dvbsky_usb_ci_set_voltage;
451 
452 	return 0;
453 }
454 
455 static int dvbsky_t680c_attach(struct dvb_usb_adapter *adap)
456 {
457 	struct dvbsky_state *state = adap_to_priv(adap);
458 	struct dvb_usb_device *d = adap_to_d(adap);
459 	struct i2c_adapter *i2c_adapter;
460 	struct si2168_config si2168_config = {};
461 	struct si2157_config si2157_config = {};
462 	struct sp2_config sp2_config = {};
463 
464 	/* attach demod */
465 	si2168_config.i2c_adapter = &i2c_adapter;
466 	si2168_config.fe = &adap->fe[0];
467 	si2168_config.ts_mode = SI2168_TS_PARALLEL;
468 
469 	state->i2c_client_demod = dvb_module_probe("si2168", NULL,
470 						   &d->i2c_adap,
471 						   0x64, &si2168_config);
472 	if (!state->i2c_client_demod)
473 		return -ENODEV;
474 
475 	/* attach tuner */
476 	si2157_config.fe = adap->fe[0];
477 	si2157_config.if_port = 1;
478 
479 	state->i2c_client_tuner = dvb_module_probe("si2157", NULL,
480 						   i2c_adapter,
481 						   0x60, &si2157_config);
482 	if (!state->i2c_client_tuner) {
483 		dvb_module_release(state->i2c_client_demod);
484 		return -ENODEV;
485 	}
486 
487 	/* attach ci controller */
488 	sp2_config.dvb_adap = &adap->dvb_adap;
489 	sp2_config.priv = d;
490 	sp2_config.ci_control = dvbsky_ci_ctrl;
491 
492 	state->i2c_client_ci = dvb_module_probe("sp2", NULL,
493 						&d->i2c_adap,
494 						0x40, &sp2_config);
495 
496 	if (!state->i2c_client_ci) {
497 		dvb_module_release(state->i2c_client_tuner);
498 		dvb_module_release(state->i2c_client_demod);
499 		return -ENODEV;
500 	}
501 
502 	return 0;
503 }
504 
505 static int dvbsky_t330_attach(struct dvb_usb_adapter *adap)
506 {
507 	struct dvbsky_state *state = adap_to_priv(adap);
508 	struct dvb_usb_device *d = adap_to_d(adap);
509 	struct i2c_adapter *i2c_adapter;
510 	struct si2168_config si2168_config = {};
511 	struct si2157_config si2157_config = {};
512 
513 	/* attach demod */
514 	si2168_config.i2c_adapter = &i2c_adapter;
515 	si2168_config.fe = &adap->fe[0];
516 	si2168_config.ts_mode = SI2168_TS_PARALLEL;
517 	si2168_config.ts_clock_gapped = true;
518 
519 	state->i2c_client_demod = dvb_module_probe("si2168", NULL,
520 						   &d->i2c_adap,
521 						   0x64, &si2168_config);
522 	if (!state->i2c_client_demod)
523 		return -ENODEV;
524 
525 	/* attach tuner */
526 	si2157_config.fe = adap->fe[0];
527 	si2157_config.if_port = 1;
528 
529 	state->i2c_client_tuner = dvb_module_probe("si2157", NULL,
530 						   i2c_adapter,
531 						   0x60, &si2157_config);
532 	if (!state->i2c_client_tuner) {
533 		dvb_module_release(state->i2c_client_demod);
534 		return -ENODEV;
535 	}
536 
537 	return 0;
538 }
539 
540 static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap)
541 {
542 	struct dvbsky_state *state = adap_to_priv(adap);
543 	struct dvb_usb_device *d = adap_to_d(adap);
544 	struct i2c_adapter *i2c_adapter;
545 	struct si2168_config si2168_config = {};
546 	struct si2157_config si2157_config = {};
547 
548 	/* attach demod */
549 	si2168_config.i2c_adapter = &i2c_adapter;
550 	si2168_config.fe = &adap->fe[0];
551 	si2168_config.ts_mode = SI2168_TS_PARALLEL;
552 	si2168_config.ts_clock_inv = 1;
553 
554 	state->i2c_client_demod = dvb_module_probe("si2168", NULL,
555 						   &d->i2c_adap,
556 						   0x64, &si2168_config);
557 	if (!state->i2c_client_demod)
558 		return -ENODEV;
559 
560 	/* attach tuner */
561 	si2157_config.fe = adap->fe[0];
562 	si2157_config.if_port = 0;
563 
564 	state->i2c_client_tuner = dvb_module_probe("si2157", "si2141",
565 						   i2c_adapter,
566 						   0x60, &si2157_config);
567 	if (!state->i2c_client_tuner) {
568 		dvb_module_release(state->i2c_client_demod);
569 		return -ENODEV;
570 	}
571 
572 	return 0;
573 }
574 
575 
576 static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
577 {
578 	dvbsky_gpio_ctrl(d, 0x04, 1);
579 	msleep(20);
580 	dvbsky_gpio_ctrl(d, 0x83, 0);
581 	dvbsky_gpio_ctrl(d, 0xc0, 1);
582 	msleep(100);
583 	dvbsky_gpio_ctrl(d, 0x83, 1);
584 	dvbsky_gpio_ctrl(d, 0xc0, 0);
585 	msleep(50);
586 
587 	return WARM;
588 }
589 
590 static int dvbsky_init(struct dvb_usb_device *d)
591 {
592 	struct dvbsky_state *state = d_to_priv(d);
593 
594 	/* use default interface */
595 	/*
596 	ret = usb_set_interface(d->udev, 0, 0);
597 	if (ret)
598 		return ret;
599 	*/
600 	mutex_init(&state->stream_mutex);
601 
602 	state->last_lock = 0;
603 
604 	return 0;
605 }
606 
607 static int dvbsky_frontend_detach(struct dvb_usb_adapter *adap)
608 {
609 	struct dvb_usb_device *d = adap_to_d(adap);
610 	struct dvbsky_state *state = d_to_priv(d);
611 
612 	dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
613 
614 	dvb_module_release(state->i2c_client_tuner);
615 	dvb_module_release(state->i2c_client_demod);
616 	dvb_module_release(state->i2c_client_ci);
617 
618 	return 0;
619 }
620 
621 /* DVB USB Driver stuff */
622 static struct dvb_usb_device_properties dvbsky_s960_props = {
623 	.driver_name = KBUILD_MODNAME,
624 	.owner = THIS_MODULE,
625 	.adapter_nr = adapter_nr,
626 	.size_of_priv = sizeof(struct dvbsky_state),
627 
628 	.generic_bulk_ctrl_endpoint = 0x01,
629 	.generic_bulk_ctrl_endpoint_response = 0x81,
630 	.generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
631 
632 	.i2c_algo         = &dvbsky_i2c_algo,
633 	.frontend_attach  = dvbsky_s960_attach,
634 	.frontend_detach  = dvbsky_frontend_detach,
635 	.init             = dvbsky_init,
636 	.get_rc_config    = dvbsky_get_rc_config,
637 	.streaming_ctrl   = dvbsky_streaming_ctrl,
638 	.identify_state	  = dvbsky_identify_state,
639 	.read_mac_address = dvbsky_read_mac_addr,
640 
641 	.num_adapters = 1,
642 	.adapter = {
643 		{
644 			.stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
645 		}
646 	}
647 };
648 
649 static struct dvb_usb_device_properties dvbsky_s960c_props = {
650 	.driver_name = KBUILD_MODNAME,
651 	.owner = THIS_MODULE,
652 	.adapter_nr = adapter_nr,
653 	.size_of_priv = sizeof(struct dvbsky_state),
654 
655 	.generic_bulk_ctrl_endpoint = 0x01,
656 	.generic_bulk_ctrl_endpoint_response = 0x81,
657 	.generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
658 
659 	.i2c_algo         = &dvbsky_i2c_algo,
660 	.frontend_attach  = dvbsky_s960c_attach,
661 	.frontend_detach  = dvbsky_frontend_detach,
662 	.init             = dvbsky_init,
663 	.get_rc_config    = dvbsky_get_rc_config,
664 	.streaming_ctrl   = dvbsky_streaming_ctrl,
665 	.identify_state	  = dvbsky_identify_state,
666 	.read_mac_address = dvbsky_read_mac_addr,
667 
668 	.num_adapters = 1,
669 	.adapter = {
670 		{
671 			.stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
672 		}
673 	}
674 };
675 
676 static struct dvb_usb_device_properties dvbsky_t680c_props = {
677 	.driver_name = KBUILD_MODNAME,
678 	.owner = THIS_MODULE,
679 	.adapter_nr = adapter_nr,
680 	.size_of_priv = sizeof(struct dvbsky_state),
681 
682 	.generic_bulk_ctrl_endpoint = 0x01,
683 	.generic_bulk_ctrl_endpoint_response = 0x81,
684 	.generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
685 
686 	.i2c_algo         = &dvbsky_i2c_algo,
687 	.frontend_attach  = dvbsky_t680c_attach,
688 	.frontend_detach  = dvbsky_frontend_detach,
689 	.init             = dvbsky_init,
690 	.get_rc_config    = dvbsky_get_rc_config,
691 	.streaming_ctrl   = dvbsky_streaming_ctrl,
692 	.identify_state	  = dvbsky_identify_state,
693 	.read_mac_address = dvbsky_read_mac_addr,
694 
695 	.num_adapters = 1,
696 	.adapter = {
697 		{
698 			.stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
699 		}
700 	}
701 };
702 
703 static struct dvb_usb_device_properties dvbsky_t330_props = {
704 	.driver_name = KBUILD_MODNAME,
705 	.owner = THIS_MODULE,
706 	.adapter_nr = adapter_nr,
707 	.size_of_priv = sizeof(struct dvbsky_state),
708 
709 	.generic_bulk_ctrl_endpoint = 0x01,
710 	.generic_bulk_ctrl_endpoint_response = 0x81,
711 	.generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
712 
713 	.i2c_algo         = &dvbsky_i2c_algo,
714 	.frontend_attach  = dvbsky_t330_attach,
715 	.frontend_detach  = dvbsky_frontend_detach,
716 	.init             = dvbsky_init,
717 	.get_rc_config    = dvbsky_get_rc_config,
718 	.streaming_ctrl   = dvbsky_streaming_ctrl,
719 	.identify_state	  = dvbsky_identify_state,
720 	.read_mac_address = dvbsky_read_mac_addr,
721 
722 	.num_adapters = 1,
723 	.adapter = {
724 		{
725 			.stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
726 		}
727 	}
728 };
729 
730 static struct dvb_usb_device_properties mygica_t230c_props = {
731 	.driver_name = KBUILD_MODNAME,
732 	.owner = THIS_MODULE,
733 	.adapter_nr = adapter_nr,
734 	.size_of_priv = sizeof(struct dvbsky_state),
735 
736 	.generic_bulk_ctrl_endpoint = 0x01,
737 	.generic_bulk_ctrl_endpoint_response = 0x81,
738 	.generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
739 
740 	.i2c_algo         = &dvbsky_i2c_algo,
741 	.frontend_attach  = dvbsky_mygica_t230c_attach,
742 	.frontend_detach  = dvbsky_frontend_detach,
743 	.init             = dvbsky_init,
744 	.get_rc_config    = dvbsky_get_rc_config,
745 	.streaming_ctrl   = dvbsky_streaming_ctrl,
746 	.identify_state	  = dvbsky_identify_state,
747 
748 	.num_adapters = 1,
749 	.adapter = {
750 		{
751 			.stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
752 		}
753 	}
754 };
755 
756 static const struct usb_device_id dvbsky_id_table[] = {
757 	{ DVB_USB_DEVICE(0x0572, 0x6831,
758 		&dvbsky_s960_props, "DVBSky S960/S860", RC_MAP_DVBSKY) },
759 	{ DVB_USB_DEVICE(0x0572, 0x960c,
760 		&dvbsky_s960c_props, "DVBSky S960CI", RC_MAP_DVBSKY) },
761 	{ DVB_USB_DEVICE(0x0572, 0x680c,
762 		&dvbsky_t680c_props, "DVBSky T680CI", RC_MAP_DVBSKY) },
763 	{ DVB_USB_DEVICE(0x0572, 0x0320,
764 		&dvbsky_t330_props, "DVBSky T330", RC_MAP_DVBSKY) },
765 	{ DVB_USB_DEVICE(USB_VID_TECHNOTREND,
766 		USB_PID_TECHNOTREND_TVSTICK_CT2_4400,
767 		&dvbsky_t330_props, "TechnoTrend TVStick CT2-4400",
768 		RC_MAP_TT_1500) },
769 	{ DVB_USB_DEVICE(USB_VID_TECHNOTREND,
770 		USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI,
771 		&dvbsky_t680c_props, "TechnoTrend TT-connect CT2-4650 CI",
772 		RC_MAP_TT_1500) },
773 	{ DVB_USB_DEVICE(USB_VID_TECHNOTREND,
774 		USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI_2,
775 		&dvbsky_t680c_props, "TechnoTrend TT-connect CT2-4650 CI v1.1",
776 		RC_MAP_TT_1500) },
777 	{ DVB_USB_DEVICE(USB_VID_TECHNOTREND,
778 		USB_PID_TECHNOTREND_CONNECT_S2_4650_CI,
779 		&dvbsky_s960c_props, "TechnoTrend TT-connect S2-4650 CI",
780 		RC_MAP_TT_1500) },
781 	{ DVB_USB_DEVICE(USB_VID_TERRATEC,
782 		USB_PID_TERRATEC_H7_3,
783 		&dvbsky_t680c_props, "Terratec H7 Rev.4",
784 		RC_MAP_TT_1500) },
785 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R4,
786 		&dvbsky_s960_props, "Terratec Cinergy S2 Rev.4",
787 		RC_MAP_DVBSKY) },
788 	{ DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C,
789 		&mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C",
790 		RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
791 	{ }
792 };
793 MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
794 
795 static struct usb_driver dvbsky_usb_driver = {
796 	.name = KBUILD_MODNAME,
797 	.id_table = dvbsky_id_table,
798 	.probe = dvb_usbv2_probe,
799 	.disconnect = dvb_usbv2_disconnect,
800 	.suspend = dvb_usbv2_suspend,
801 	.resume = dvb_usbv2_resume,
802 	.reset_resume = dvb_usbv2_reset_resume,
803 	.no_dynamic_id = 1,
804 	.soft_unbind = 1,
805 };
806 
807 module_usb_driver(dvbsky_usb_driver);
808 
809 MODULE_AUTHOR("Max nibble <nibble.max@gmail.com>");
810 MODULE_DESCRIPTION("Driver for DVBSky USB");
811 MODULE_LICENSE("GPL");
812