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