blob: 4685259e16141d52b35127e4c14df642daf9b99d [file] [log] [blame]
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001/*
2 * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
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 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * TODO:
21 * - add smart card reader support for Conditional Access (CA)
22 *
23 * Card reader in Anysee is nothing more than ISO 7816 card reader.
24 * There is no hardware CAM in any Anysee device sold.
25 * In my understanding it should be implemented by making own module
Antti Palosaari9fdd9ca2008-06-11 11:43:19 -030026 * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
27 * module registers serial interface that can be used to communicate
Antti Palosaaria51e34d2008-05-17 23:05:48 -030028 * with any ISO 7816 smart card.
29 *
30 * Any help according to implement serial smart card reader support
31 * is highly welcome!
32 */
33
34#include "anysee.h"
35#include "tda1002x.h"
36#include "mt352.h"
37#include "mt352_priv.h"
38#include "zl10353.h"
39
40/* debug */
41static int dvb_usb_anysee_debug;
42module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
Mauro Carvalho Chehabffbc5f82009-01-05 01:34:20 -030044static int dvb_usb_anysee_delsys;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -030045module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644);
46MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");
Antti Palosaaria51e34d2008-05-17 23:05:48 -030047DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
48
Akinobu Mitadec0c462008-10-29 21:16:04 -030049static DEFINE_MUTEX(anysee_usb_mutex);
Antti Palosaaria51e34d2008-05-17 23:05:48 -030050
51static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
52 u8 *rbuf, u8 rlen)
53{
54 struct anysee_state *state = d->priv;
55 int act_len, ret;
56 u8 buf[64];
57
58 if (slen > sizeof(buf))
59 slen = sizeof(buf);
60 memcpy(&buf[0], sbuf, slen);
61 buf[60] = state->seq++;
62
63 if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
64 return -EAGAIN;
65
66 /* We need receive one message more after dvb_usb_generic_rw due
67 to weird transaction flow, which is 1 x send + 2 x receive. */
68 ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
69
70 if (!ret) {
71 /* receive 2nd answer */
72 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
73 d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
74 &act_len, 2000);
75 if (ret)
76 err("%s: recv bulk message failed: %d", __func__, ret);
77 else {
78 deb_xfer("<<< ");
79 debug_dump(buf, act_len, deb_xfer);
80 }
81 }
82
83 /* read request, copy returned data to return buf */
84 if (!ret && rbuf && rlen)
85 memcpy(rbuf, buf, rlen);
86
87 mutex_unlock(&anysee_usb_mutex);
88
89 return ret;
90}
91
92static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
93{
94 u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
95 int ret;
96 ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
97 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
98 return ret;
99}
100
101static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
102{
103 u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
104 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
105 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
106}
107
108static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
109{
110 u8 buf[] = {CMD_GET_HW_INFO};
111 return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
112}
113
114static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
115{
116 u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
117 deb_info("%s: onoff:%02x\n", __func__, onoff);
118 return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);
119}
120
121static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
122{
123 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
124 deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
125 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
126}
127
128static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
129{
130 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
131 deb_info("%s: onoff:%02x\n", __func__, onoff);
132 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
133}
134
135static int anysee_init(struct dvb_usb_device *d)
136{
137 int ret;
138 /* LED light */
139 ret = anysee_led_ctrl(d, 0x01, 0x03);
140 if (ret)
141 return ret;
142
143 /* enable IR */
144 ret = anysee_ir_ctrl(d, 1);
145 if (ret)
146 return ret;
147
148 return 0;
149}
150
151/* I2C */
152static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
153 int num)
154{
155 struct dvb_usb_device *d = i2c_get_adapdata(adap);
Mauro Carvalho Chehab902571a2008-12-29 19:02:24 -0300156 int ret = 0, inc, i = 0;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300157
158 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
159 return -EAGAIN;
160
161 while (i < num) {
162 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
163 u8 buf[6];
164 buf[0] = CMD_I2C_READ;
165 buf[1] = msg[i].addr + 1;
166 buf[2] = msg[i].buf[0];
167 buf[3] = 0x00;
168 buf[4] = 0x00;
169 buf[5] = 0x01;
170 ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf,
171 msg[i+1].len);
172 inc = 2;
173 } else {
174 u8 buf[4+msg[i].len];
175 buf[0] = CMD_I2C_WRITE;
176 buf[1] = msg[i].addr;
177 buf[2] = msg[i].len;
178 buf[3] = 0x01;
179 memcpy(&buf[4], msg[i].buf, msg[i].len);
180 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
181 inc = 1;
182 }
183 if (ret)
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300184 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300185
186 i += inc;
187 }
188
189 mutex_unlock(&d->i2c_mutex);
190
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300191 return ret ? ret : i;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300192}
193
194static u32 anysee_i2c_func(struct i2c_adapter *adapter)
195{
196 return I2C_FUNC_I2C;
197}
198
199static struct i2c_algorithm anysee_i2c_algo = {
200 .master_xfer = anysee_master_xfer,
201 .functionality = anysee_i2c_func,
202};
203
204static int anysee_mt352_demod_init(struct dvb_frontend *fe)
205{
Antti Palosaariae3745f2009-09-16 19:50:25 -0300206 static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 };
207 static u8 reset[] = { RESET, 0x80 };
208 static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
209 static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
210 static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300211 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
212
213 mt352_write(fe, clock_config, sizeof(clock_config));
214 udelay(200);
215 mt352_write(fe, reset, sizeof(reset));
216 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
217
218 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
219 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
220 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
221
222 return 0;
223}
224
225/* Callbacks for DVB USB */
226static struct tda10023_config anysee_tda10023_config = {
227 .demod_address = 0x1a,
228 .invert = 0,
229 .xtal = 16000000,
230 .pll_m = 11,
231 .pll_p = 3,
232 .pll_n = 1,
Antti Palosaari5ae2fca2008-06-09 22:58:22 -0300233 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
234 .deltaf = 0xfeeb,
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300235};
236
237static struct mt352_config anysee_mt352_config = {
238 .demod_address = 0x1e,
239 .demod_init = anysee_mt352_demod_init,
240};
241
242static struct zl10353_config anysee_zl10353_config = {
243 .demod_address = 0x1e,
244 .parallel_ts = 1,
245};
246
247static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
248{
249 int ret;
250 struct anysee_state *state = adap->dev->priv;
251 u8 hw_info[3];
252 u8 io_d; /* IO port D */
253
254 /* check which hardware we have
255 We must do this call two times to get reliable values (hw bug). */
256 ret = anysee_get_hw_info(adap->dev, hw_info);
257 if (ret)
258 return ret;
259 ret = anysee_get_hw_info(adap->dev, hw_info);
260 if (ret)
261 return ret;
262
263 /* Meaning of these info bytes are guessed. */
264 info("firmware version:%d.%d.%d hardware id:%d",
265 0, hw_info[1], hw_info[2], hw_info[0]);
266
267 ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */
268 if (ret)
269 return ret;
270 deb_info("%s: IO port D:%02x\n", __func__, io_d);
271
272 /* Select demod using trial and error method. */
273
274 /* Try to attach demodulator in following order:
275 model demod hw firmware
276 1. E30 MT352 02 0.2.1
277 2. E30 ZL10353 02 0.2.1
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300278 3. E30 Combo ZL10353 0f 0.1.2 DVB-T/C combo
279 4. E30 Plus ZL10353 06 0.1.0
280 5. E30C Plus TDA10023 0a 0.1.0 rev 0.2
281 E30C Plus TDA10023 0f 0.1.2 rev 0.4
282 E30 Combo TDA10023 0f 0.1.2 DVB-T/C combo
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300283 */
284
285 /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */
286 adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
287 &adap->dev->i2c_adap);
288 if (adap->fe != NULL) {
289 state->tuner = DVB_PLL_THOMSON_DTT7579;
290 return 0;
291 }
292
293 /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
294 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
295 &adap->dev->i2c_adap);
296 if (adap->fe != NULL) {
297 state->tuner = DVB_PLL_THOMSON_DTT7579;
298 return 0;
299 }
300
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300301 /* for E30 Combo Plus DVB-T demodulator */
302 if (dvb_usb_anysee_delsys) {
303 ret = anysee_write_reg(adap->dev, 0xb0, 0x01);
304 if (ret)
305 return ret;
306
307 /* Zarlink ZL10353 DVB-T demod */
308 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
309 &adap->dev->i2c_adap);
310 if (adap->fe != NULL) {
311 state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
312 return 0;
313 }
314 }
315
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300316 /* connect demod on IO port D for TDA10023 & ZL10353 */
317 ret = anysee_write_reg(adap->dev, 0xb0, 0x25);
318 if (ret)
319 return ret;
320
321 /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
322 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
323 &adap->dev->i2c_adap);
324 if (adap->fe != NULL) {
325 state->tuner = DVB_PLL_THOMSON_DTT7579;
326 return 0;
327 }
328
Antti Palosaari5ae2fca2008-06-09 22:58:22 -0300329 /* IO port E - E30C rev 0.4 board requires this */
330 ret = anysee_write_reg(adap->dev, 0xb1, 0xa7);
331 if (ret)
332 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300333
334 /* Philips TDA10023 DVB-C demod */
335 adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
336 &adap->dev->i2c_adap, 0x48);
337 if (adap->fe != NULL) {
338 state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
339 return 0;
340 }
341
342 /* return IO port D to init value for safe */
343 ret = anysee_write_reg(adap->dev, 0xb0, io_d);
344 if (ret)
345 return ret;
346
André Goddard Rosaaf901ca2009-11-14 13:09:05 -0200347 err("Unknown Anysee version: %02x %02x %02x. "\
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300348 "Please report the <linux-dvb@linuxtv.org>.",
349 hw_info[0], hw_info[1], hw_info[2]);
350
351 return -ENODEV;
352}
353
354static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
355{
356 struct anysee_state *state = adap->dev->priv;
357 deb_info("%s: \n", __func__);
358
359 switch (state->tuner) {
360 case DVB_PLL_THOMSON_DTT7579:
361 /* Thomson dtt7579 (not sure) PLL inside of:
362 Samsung DNOS404ZH102A NIM
363 Samsung DNOS404ZH103A NIM */
364 dvb_attach(dvb_pll_attach, adap->fe, 0x61,
365 NULL, DVB_PLL_THOMSON_DTT7579);
366 break;
367 case DVB_PLL_SAMSUNG_DTOS403IH102A:
368 /* Unknown PLL inside of Samsung DTOS403IH102A tuner module */
369 dvb_attach(dvb_pll_attach, adap->fe, 0xc0,
370 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
371 break;
372 }
373
374 return 0;
375}
376
377static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
378{
379 u8 buf[] = {CMD_GET_IR_CODE};
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -0300380 struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300381 u8 ircode[2];
382 int i, ret;
383
384 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &ircode[0], 2);
385 if (ret)
386 return ret;
387
388 *event = 0;
389 *state = REMOTE_NO_KEY_PRESSED;
390
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -0300391 for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300392 if (rc5_custom(&keymap[i]) == ircode[0] &&
393 rc5_data(&keymap[i]) == ircode[1]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300394 *event = keymap[i].keycode;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300395 *state = REMOTE_KEY_PRESSED;
396 return 0;
397 }
398 }
399 return 0;
400}
401
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300402static struct ir_scancode ir_codes_anysee_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300403 { 0x0100, KEY_0 },
404 { 0x0101, KEY_1 },
405 { 0x0102, KEY_2 },
406 { 0x0103, KEY_3 },
407 { 0x0104, KEY_4 },
408 { 0x0105, KEY_5 },
409 { 0x0106, KEY_6 },
410 { 0x0107, KEY_7 },
411 { 0x0108, KEY_8 },
412 { 0x0109, KEY_9 },
413 { 0x010a, KEY_POWER },
414 { 0x010b, KEY_DOCUMENTS }, /* * */
415 { 0x0119, KEY_FAVORITES },
416 { 0x0120, KEY_SLEEP },
417 { 0x0121, KEY_MODE }, /* 4:3 / 16:9 select */
418 { 0x0122, KEY_ZOOM },
419 { 0x0147, KEY_TEXT },
420 { 0x0116, KEY_TV }, /* TV / radio select */
421 { 0x011e, KEY_LANGUAGE }, /* Second Audio Program */
422 { 0x011a, KEY_SUBTITLE },
423 { 0x011b, KEY_CAMERA }, /* screenshot */
424 { 0x0142, KEY_MUTE },
425 { 0x010e, KEY_MENU },
426 { 0x010f, KEY_EPG },
427 { 0x0117, KEY_INFO },
428 { 0x0110, KEY_EXIT },
429 { 0x0113, KEY_VOLUMEUP },
430 { 0x0112, KEY_VOLUMEDOWN },
431 { 0x0111, KEY_CHANNELUP },
432 { 0x0114, KEY_CHANNELDOWN },
433 { 0x0115, KEY_OK },
434 { 0x011d, KEY_RED },
435 { 0x011f, KEY_GREEN },
436 { 0x011c, KEY_YELLOW },
437 { 0x0144, KEY_BLUE },
438 { 0x010c, KEY_SHUFFLE }, /* snapshot */
439 { 0x0148, KEY_STOP },
440 { 0x0150, KEY_PLAY },
441 { 0x0151, KEY_PAUSE },
442 { 0x0149, KEY_RECORD },
443 { 0x0118, KEY_PREVIOUS }, /* |<< */
444 { 0x010d, KEY_NEXT }, /* >>| */
445 { 0x0124, KEY_PROG1 }, /* F1 */
446 { 0x0125, KEY_PROG2 }, /* F2 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300447};
448
449/* DVB USB Driver stuff */
450static struct dvb_usb_device_properties anysee_properties;
451
452static int anysee_probe(struct usb_interface *intf,
453 const struct usb_device_id *id)
454{
455 struct dvb_usb_device *d;
456 struct usb_host_interface *alt;
457 int ret;
458
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300459 /* There is one interface with two alternate settings.
460 Alternate setting 0 is for bulk transfer.
461 Alternate setting 1 is for isochronous transfer.
462 We use bulk transfer (alternate setting 0). */
463 if (intf->num_altsetting < 1)
464 return -ENODEV;
465
Dan Carpenter8b0d7042010-05-31 16:27:39 -0300466 /*
467 * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
468 * firmware from eeprom). If dvb_usb_device_init() succeeds that
469 * means d is a valid pointer.
470 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300471 ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
472 adapter_nr);
473 if (ret)
474 return ret;
475
476 alt = usb_altnum_to_altsetting(intf, 0);
477 if (alt == NULL) {
478 deb_info("%s: no alt found!\n", __func__);
479 return -ENODEV;
480 }
481
482 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
483 alt->desc.bAlternateSetting);
484 if (ret)
485 return ret;
486
Dan Carpenter8b0d7042010-05-31 16:27:39 -0300487 return anysee_init(d);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300488}
489
Antti Palosaariae3745f2009-09-16 19:50:25 -0300490static struct usb_device_id anysee_table[] = {
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300491 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
492 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
493 { } /* Terminating entry */
494};
495MODULE_DEVICE_TABLE(usb, anysee_table);
496
497static struct dvb_usb_device_properties anysee_properties = {
498 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
499
500 .usb_ctrl = DEVICE_SPECIFIC,
501
502 .size_of_priv = sizeof(struct anysee_state),
503
504 .num_adapters = 1,
505 .adapter = {
506 {
507 .streaming_ctrl = anysee_streaming_ctrl,
508 .frontend_attach = anysee_frontend_attach,
509 .tuner_attach = anysee_tuner_attach,
510 .stream = {
511 .type = USB_BULK,
512 .count = 8,
513 .endpoint = 0x82,
514 .u = {
515 .bulk = {
Antti Palosaariab693332009-09-16 19:47:01 -0300516 .buffersize = (16*512),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300517 }
518 }
519 },
520 }
521 },
522
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -0300523 .rc.legacy = {
524 .rc_key_map = ir_codes_anysee_table,
525 .rc_key_map_size = ARRAY_SIZE(ir_codes_anysee_table),
526 .rc_query = anysee_rc_query,
527 .rc_interval = 200, /* windows driver uses 500ms */
528 },
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300529
530 .i2c_algo = &anysee_i2c_algo,
531
532 .generic_bulk_ctrl_endpoint = 1,
533
534 .num_device_descs = 1,
535 .devices = {
536 {
537 .name = "Anysee DVB USB2.0",
538 .cold_ids = {NULL},
539 .warm_ids = {&anysee_table[0],
540 &anysee_table[1], NULL},
541 },
542 }
543};
544
545static struct usb_driver anysee_driver = {
546 .name = "dvb_usb_anysee",
547 .probe = anysee_probe,
548 .disconnect = dvb_usb_device_exit,
549 .id_table = anysee_table,
550};
551
552/* module stuff */
553static int __init anysee_module_init(void)
554{
555 int ret;
556
557 ret = usb_register(&anysee_driver);
558 if (ret)
559 err("%s: usb_register failed. Error number %d", __func__, ret);
560
561 return ret;
562}
563
564static void __exit anysee_module_exit(void)
565{
566 /* deregister this driver from the USB subsystem */
567 usb_deregister(&anysee_driver);
568}
569
570module_init(anysee_module_init);
571module_exit(anysee_module_exit);
572
573MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
574MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
575MODULE_LICENSE("GPL");