blob: 21935bf7059ee34f976914d82aaf22cd88fadb5d [file] [log] [blame]
Marco Gittler941491f2007-04-19 11:26:47 -03001/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
2*
3* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
4* Copyright (C) 2006 Marco Gittler (g.marco@freenet.de)
5*
6* This program is free software; you can redistribute it and/or modify it
7* under the terms of the GNU General Public License as published by the Free
8* Software Foundation, version 2.
9*
10* see Documentation/dvb/README.dvb-usb for more information
11*/
12
Adrian Bunk53133af2007-11-05 14:07:06 -030013#define DVB_USB_LOG_PREFIX "opera"
14
15#include "dvb-usb.h"
Marco Gittler941491f2007-04-19 11:26:47 -030016#include "stv0299.h"
17
18#define OPERA_READ_MSG 0
19#define OPERA_WRITE_MSG 1
20#define OPERA_I2C_TUNER 0xd1
21
22#define READ_FX2_REG_REQ 0xba
23#define READ_MAC_ADDR 0x08
24#define OPERA_WRITE_FX2 0xbb
25#define OPERA_TUNER_REQ 0xb1
26#define REG_1F_SYMBOLRATE_BYTE0 0x1f
27#define REG_20_SYMBOLRATE_BYTE1 0x20
28#define REG_21_SYMBOLRATE_BYTE2 0x21
29
Marco Gittler86534e52007-04-23 17:52:58 -030030#define ADDR_B600_VOLTAGE_13V (0x02)
31#define ADDR_B601_VOLTAGE_18V (0x03)
32#define ADDR_B1A6_STREAM_CTRL (0x04)
33#define ADDR_B880_READ_REMOTE (0x05)
34
Marco Gittler941491f2007-04-19 11:26:47 -030035struct opera1_state {
36 u32 last_key_pressed;
37};
38struct opera_rc_keys {
39 u32 keycode;
40 u32 event;
41};
42
Adrian Bunk53133af2007-11-05 14:07:06 -030043static int dvb_usb_opera1_debug;
Marco Gittler941491f2007-04-19 11:26:47 -030044module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
45MODULE_PARM_DESC(debug,
46 "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
47 DVB_USB_DEBUG_STATUS);
48
49static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
50 u8 * data, u16 len, int flags)
51{
52 int ret;
53 u8 r;
54 u8 u8buf[len];
55
56 unsigned int pipe = (flags == OPERA_READ_MSG) ?
57 usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
58 u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
59
60 if (flags == OPERA_WRITE_MSG)
61 memcpy(u8buf, data, len);
62 ret =
63 usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
64 value, 0x0, u8buf, len, 2000);
65
66 if (request == OPERA_TUNER_REQ) {
67 if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
68 OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
69 0x01, 0x0, &r, 1, 2000)<1 || r!=0x08)
70 return 0;
71 }
72 if (flags == OPERA_READ_MSG)
73 memcpy(data, u8buf, len);
74 return ret;
75}
76
77/* I2C */
78
79static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
Marco Gittler86534e52007-04-23 17:52:58 -030080 u8 * buf, u16 len)
Marco Gittler941491f2007-04-19 11:26:47 -030081{
82 int ret = 0;
83 u8 request;
84 u16 value;
85
86 if (!dev) {
87 info("no usb_device");
88 return -EINVAL;
89 }
90 if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
91 return -EAGAIN;
92
Marco Gittler86534e52007-04-23 17:52:58 -030093 switch (addr>>1){
94 case ADDR_B600_VOLTAGE_13V:
95 request=0xb6;
96 value=0x00;
97 break;
98 case ADDR_B601_VOLTAGE_18V:
99 request=0xb6;
100 value=0x01;
101 break;
102 case ADDR_B1A6_STREAM_CTRL:
103 request=0xb1;
104 value=0xa6;
105 break;
106 case ADDR_B880_READ_REMOTE:
107 request=0xb8;
108 value=0x80;
109 break;
110 default:
111 request=0xb1;
112 value=addr;
Marco Gittler941491f2007-04-19 11:26:47 -0300113 }
Marco Gittler86534e52007-04-23 17:52:58 -0300114 ret = opera1_xilinx_rw(dev->udev, request,
115 value, buf, len,
116 addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
Marco Gittler941491f2007-04-19 11:26:47 -0300117
118 mutex_unlock(&dev->usb_mutex);
119 return ret;
120}
121
122static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
123 int num)
124{
125 struct dvb_usb_device *d = i2c_get_adapdata(adap);
126 int i = 0, tmp = 0;
127
128 if (!d)
129 return -ENODEV;
130 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
131 return -EAGAIN;
132
133 for (i = 0; i < num; i++) {
134 if ((tmp = opera1_usb_i2c_msgxfer(d,
Marco Gittler86534e52007-04-23 17:52:58 -0300135 (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
Marco Gittler941491f2007-04-19 11:26:47 -0300136 msg[i].buf,
Marco Gittler86534e52007-04-23 17:52:58 -0300137 msg[i].len
138 )!= msg[i].len)) {
Marco Gittler941491f2007-04-19 11:26:47 -0300139 break;
140 }
141 if (dvb_usb_opera1_debug & 0x10)
142 info("sending i2c mesage %d %d", tmp, msg[i].len);
143 }
144 mutex_unlock(&d->i2c_mutex);
145 return num;
146}
147
148static u32 opera1_i2c_func(struct i2c_adapter *adapter)
149{
150 return I2C_FUNC_I2C;
151}
152
153static struct i2c_algorithm opera1_i2c_algo = {
154 .master_xfer = opera1_i2c_xfer,
155 .functionality = opera1_i2c_func,
156};
157
158static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
159{
160 static u8 command_13v[1]={0x00};
161 static u8 command_18v[1]={0x01};
162 struct i2c_msg msg[] = {
Marco Gittler86534e52007-04-23 17:52:58 -0300163 {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
Marco Gittler941491f2007-04-19 11:26:47 -0300164 };
165 struct dvb_usb_adapter *udev_adap =
166 (struct dvb_usb_adapter *)(fe->dvb->priv);
167 if (voltage == SEC_VOLTAGE_18) {
Marco Gittler86534e52007-04-23 17:52:58 -0300168 msg[0].addr = ADDR_B601_VOLTAGE_18V;
Marco Gittler941491f2007-04-19 11:26:47 -0300169 msg[0].buf = command_18v;
170 }
171 i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
172 return 0;
173}
174
175static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
176 u32 ratio)
177{
178 stv0299_writereg(fe, 0x13, 0x98);
179 stv0299_writereg(fe, 0x14, 0x95);
180 stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
181 stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
182 stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
183 return 0;
184
185}
186static u8 opera1_inittab[] = {
187 0x00, 0xa1,
188 0x01, 0x15,
189 0x02, 0x00,
190 0x03, 0x00,
191 0x04, 0x7d,
192 0x05, 0x05,
193 0x06, 0x02,
194 0x07, 0x00,
195 0x0b, 0x00,
196 0x0c, 0x01,
197 0x0d, 0x81,
198 0x0e, 0x44,
199 0x0f, 0x19,
200 0x10, 0x3f,
201 0x11, 0x84,
202 0x12, 0xda,
203 0x13, 0x98,
204 0x14, 0x95,
205 0x15, 0xc9,
206 0x16, 0xeb,
207 0x17, 0x00,
208 0x18, 0x19,
209 0x19, 0x8b,
210 0x1a, 0x00,
211 0x1b, 0x82,
212 0x1c, 0x7f,
213 0x1d, 0x00,
214 0x1e, 0x00,
215 REG_1F_SYMBOLRATE_BYTE0, 0x06,
216 REG_20_SYMBOLRATE_BYTE1, 0x50,
217 REG_21_SYMBOLRATE_BYTE2, 0x10,
218 0x22, 0x00,
219 0x23, 0x00,
220 0x24, 0x37,
221 0x25, 0xbc,
222 0x26, 0x00,
223 0x27, 0x00,
224 0x28, 0x00,
225 0x29, 0x1e,
226 0x2a, 0x14,
227 0x2b, 0x1f,
228 0x2c, 0x09,
229 0x2d, 0x0a,
230 0x2e, 0x00,
231 0x2f, 0x00,
232 0x30, 0x00,
233 0x31, 0x1f,
234 0x32, 0x19,
235 0x33, 0xfc,
236 0x34, 0x13,
237 0xff, 0xff,
238};
239
240static struct stv0299_config opera1_stv0299_config = {
Marco Gittler86534e52007-04-23 17:52:58 -0300241 .demod_address = 0xd0>>1,
Marco Gittler941491f2007-04-19 11:26:47 -0300242 .min_delay_ms = 100,
243 .mclk = 88000000UL,
244 .invert = 1,
245 .skip_reinit = 0,
246 .lock_output = STV0229_LOCKOUTPUT_0,
247 .volt13_op0_op1 = STV0299_VOLT13_OP0,
248 .inittab = opera1_inittab,
249 .set_symbol_rate = opera1_stv0299_set_symbol_rate,
250};
251
252static int opera1_frontend_attach(struct dvb_usb_adapter *d)
253{
254 if ((d->fe =
255 dvb_attach(stv0299_attach, &opera1_stv0299_config,
256 &d->dev->i2c_adap)) != NULL) {
257 d->fe->ops.set_voltage = opera1_set_voltage;
258 return 0;
259 }
260 info("not attached stv0299");
261 return -EIO;
262}
263
264static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
265{
Marco Gittler86534e52007-04-23 17:52:58 -0300266 dvb_attach(
267 dvb_pll_attach, adap->fe, 0xc0>>1,
Michael Krufky47a99912007-06-12 16:10:51 -0300268 &adap->dev->i2c_adap, DVB_PLL_OPERA1
Marco Gittler86534e52007-04-23 17:52:58 -0300269 );
Marco Gittler941491f2007-04-19 11:26:47 -0300270 return 0;
271}
272
273static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
274{
Marco Gittler941491f2007-04-19 11:26:47 -0300275 u8 val = onoff ? 0x01 : 0x00;
Marco Gittler86534e52007-04-23 17:52:58 -0300276
Marco Gittler941491f2007-04-19 11:26:47 -0300277 if (dvb_usb_opera1_debug)
278 info("power %s", onoff ? "on" : "off");
Marco Gittler86534e52007-04-23 17:52:58 -0300279 return opera1_xilinx_rw(d->udev, 0xb7, val,
280 &val, 1, OPERA_WRITE_MSG);
Marco Gittler941491f2007-04-19 11:26:47 -0300281}
282
283static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
284{
285 static u8 buf_start[2] = { 0xff, 0x03 };
286 static u8 buf_stop[2] = { 0xff, 0x00 };
287 struct i2c_msg start_tuner[] = {
Marco Gittler86534e52007-04-23 17:52:58 -0300288 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
Marco Gittler941491f2007-04-19 11:26:47 -0300289 };
290 if (dvb_usb_opera1_debug)
291 info("streaming %s", onoff ? "on" : "off");
292 i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
293 return 0;
294}
295
296static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
297 int onoff)
298{
299 u8 b_pid[3];
300 struct i2c_msg msg[] = {
Marco Gittler86534e52007-04-23 17:52:58 -0300301 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
Marco Gittler941491f2007-04-19 11:26:47 -0300302 };
303 if (dvb_usb_opera1_debug)
304 info("pidfilter index: %d pid: %d %s", index, pid,
305 onoff ? "on" : "off");
306 b_pid[0] = (2 * index) + 4;
307 b_pid[1] = onoff ? (pid & 0xff) : (0x00);
308 b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
309 i2c_transfer(&adap->dev->i2c_adap, msg, 1);
310 return 0;
311}
312
313static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
314{
315 int u = 0x04;
316 u8 b_pid[3];
317 struct i2c_msg msg[] = {
Marco Gittler86534e52007-04-23 17:52:58 -0300318 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
Marco Gittler941491f2007-04-19 11:26:47 -0300319 };
320 if (dvb_usb_opera1_debug)
321 info("%s hw-pidfilter", onoff ? "enable" : "disable");
322 for (; u < 0x7e; u += 2) {
323 b_pid[0] = u;
324 b_pid[1] = 0;
325 b_pid[2] = 0x80;
326 i2c_transfer(&adap->dev->i2c_adap, msg, 1);
327 }
328 return 0;
329}
330
331static struct dvb_usb_rc_key opera1_rc_keys[] = {
332 {0x5f, 0xa0, KEY_1},
333 {0x51, 0xaf, KEY_2},
334 {0x5d, 0xa2, KEY_3},
335 {0x41, 0xbe, KEY_4},
336 {0x0b, 0xf5, KEY_5},
337 {0x43, 0xbd, KEY_6},
338 {0x47, 0xb8, KEY_7},
339 {0x49, 0xb6, KEY_8},
340 {0x05, 0xfa, KEY_9},
341 {0x45, 0xba, KEY_0},
342 {0x09, 0xf6, KEY_UP}, /*chanup */
343 {0x1b, 0xe5, KEY_DOWN}, /*chandown */
344 {0x5d, 0xa3, KEY_LEFT}, /*voldown */
345 {0x5f, 0xa1, KEY_RIGHT}, /*volup */
346 {0x07, 0xf8, KEY_SPACE}, /*tab */
347 {0x1f, 0xe1, KEY_ENTER}, /*play ok */
348 {0x1b, 0xe4, KEY_Z}, /*zoom */
349 {0x59, 0xa6, KEY_M}, /*mute */
350 {0x5b, 0xa5, KEY_F}, /*tv/f */
351 {0x19, 0xe7, KEY_R}, /*rec */
352 {0x01, 0xfe, KEY_S}, /*Stop */
353 {0x03, 0xfd, KEY_P}, /*pause */
354 {0x03, 0xfc, KEY_W}, /*<- -> */
355 {0x07, 0xf9, KEY_C}, /*capture */
356 {0x47, 0xb9, KEY_Q}, /*exit */
357 {0x43, 0xbc, KEY_O}, /*power */
358
359};
360
361static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
362{
363 struct opera1_state *opst = dev->priv;
364 u8 rcbuffer[32];
365 const u16 startmarker1 = 0x10ed;
366 const u16 startmarker2 = 0x11ec;
367 struct i2c_msg read_remote[] = {
Marco Gittler86534e52007-04-23 17:52:58 -0300368 {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
Marco Gittler941491f2007-04-19 11:26:47 -0300369 };
370 int i = 0;
371 u32 send_key = 0;
372
373 if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
374 for (i = 0; i < 32; i++) {
375 if (rcbuffer[i])
376 send_key |= 1;
377 if (i < 31)
378 send_key = send_key << 1;
379 }
380 if (send_key & 0x8000)
381 send_key = (send_key << 1) | (send_key >> 15 & 0x01);
382
383 if (send_key == 0xffff && opst->last_key_pressed != 0) {
384 *state = REMOTE_KEY_REPEAT;
385 *event = opst->last_key_pressed;
386 return 0;
387 }
388 for (; send_key != 0;) {
389 if (send_key >> 16 == startmarker2) {
390 break;
391 } else if (send_key >> 16 == startmarker1) {
392 send_key =
393 (send_key & 0xfffeffff) | (startmarker1 << 16);
394 break;
395 } else
396 send_key >>= 1;
397 }
398
399 if (send_key == 0)
400 return 0;
401
402 send_key = (send_key & 0xffff) | 0x0100;
403
404 for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) {
405 if ((opera1_rc_keys[i].custom * 256 +
406 opera1_rc_keys[i].data) == (send_key & 0xffff)) {
407 *state = REMOTE_KEY_PRESSED;
408 *event = opera1_rc_keys[i].event;
409 opst->last_key_pressed =
410 opera1_rc_keys[i].event;
411 break;
412 }
413 opst->last_key_pressed = 0;
414 }
415 } else
416 *state = REMOTE_NO_KEY_PRESSED;
417 return 0;
418}
419
420static struct usb_device_id opera1_table[] = {
421 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)},
422 {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)},
423 {}
424};
425
426MODULE_DEVICE_TABLE(usb, opera1_table);
427
428static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
429{
430 u8 command[] = { READ_MAC_ADDR };
431 opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
432 opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
433 return 0;
434}
435static int opera1_xilinx_load_firmware(struct usb_device *dev,
436 const char *filename)
437{
438 const struct firmware *fw = NULL;
439 u8 *b, *p;
Marco Gittler59800552007-07-04 19:18:34 -0300440 int ret = 0, i,fpgasize=40;
Marco Gittler941491f2007-04-19 11:26:47 -0300441 u8 testval;
Marco Gittler59800552007-07-04 19:18:34 -0300442 info("start downloading fpga firmware %s",filename);
Marco Gittler941491f2007-04-19 11:26:47 -0300443
444 if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
445 err("did not find the firmware file. (%s) "
446 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
447 filename);
448 return ret;
449 } else {
450 p = kmalloc(fw->size, GFP_KERNEL);
451 opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
452 if (p != NULL && testval != 0x67) {
453
454 u8 reset = 0, fpga_command = 0;
455 memcpy(p, fw->data, fw->size);
456 /* clear fpga ? */
457 opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
458 OPERA_WRITE_MSG);
Marco Gittler59800552007-07-04 19:18:34 -0300459 for (i = 0; i < fw->size;) {
460 if ( (fw->size - i) <fpgasize){
461 fpgasize=fw->size-i;
462 }
Marco Gittler941491f2007-04-19 11:26:47 -0300463 b = (u8 *) p + i;
464 if (opera1_xilinx_rw
Marco Gittler59800552007-07-04 19:18:34 -0300465 (dev, OPERA_WRITE_FX2, 0x0, b , fpgasize,
466 OPERA_WRITE_MSG) != fpgasize
Marco Gittler941491f2007-04-19 11:26:47 -0300467 ) {
468 err("error while transferring firmware");
469 ret = -EINVAL;
470 break;
471 }
Marco Gittler59800552007-07-04 19:18:34 -0300472 i = i + fpgasize;
Marco Gittler941491f2007-04-19 11:26:47 -0300473 }
474 /* restart the CPU */
475 if (ret || opera1_xilinx_rw
476 (dev, 0xa0, 0xe600, &reset, 1,
477 OPERA_WRITE_MSG) != 1) {
478 err("could not restart the USB controller CPU.");
479 ret = -EINVAL;
480 }
481 kfree(p);
482 }
483 }
484 if (fw) {
485 release_firmware(fw);
486 }
487 return ret;
488}
489
490static struct dvb_usb_device_properties opera1_properties = {
491 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
492 .usb_ctrl = CYPRESS_FX2,
Marco Gittler86534e52007-04-23 17:52:58 -0300493 .firmware = "dvb-usb-opera-01.fw",
Marco Gittler941491f2007-04-19 11:26:47 -0300494 .size_of_priv = sizeof(struct opera1_state),
495
496 .power_ctrl = opera1_power_ctrl,
497 .i2c_algo = &opera1_i2c_algo,
498
499 .rc_key_map = opera1_rc_keys,
500 .rc_key_map_size = ARRAY_SIZE(opera1_rc_keys),
501 .rc_interval = 200,
502 .rc_query = opera1_rc_query,
503 .read_mac_address = opera1_read_mac_address,
504 .generic_bulk_ctrl_endpoint = 0x00,
505 /* parameter for the MPEG2-data transfer */
506 .num_adapters = 1,
507 .adapter = {
508 {
509 .frontend_attach = opera1_frontend_attach,
510 .streaming_ctrl = opera1_streaming_ctrl,
511 .tuner_attach = opera1_tuner_attach,
512 .caps =
513 DVB_USB_ADAP_HAS_PID_FILTER |
514 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
515 .pid_filter = opera1_pid_filter,
516 .pid_filter_ctrl = opera1_pid_filter_control,
517 .pid_filter_count = 252,
518 .stream = {
519 .type = USB_BULK,
520 .count = 10,
521 .endpoint = 0x82,
522 .u = {
523 .bulk = {
524 .buffersize = 4096,
525 }
526 }
527 },
528 }
529 },
530 .num_device_descs = 1,
531 .devices = {
532 {"Opera1 DVB-S USB2.0",
533 {&opera1_table[0], NULL},
534 {&opera1_table[1], NULL},
535 },
536 }
537};
538
539static int opera1_probe(struct usb_interface *intf,
540 const struct usb_device_id *id)
541{
Marco Gittler941491f2007-04-19 11:26:47 -0300542 struct usb_device *udev = interface_to_usbdev(intf);
543
544 if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
545 udev->descriptor.idVendor == USB_VID_OPERA1 &&
Marco Gittler59800552007-07-04 19:18:34 -0300546 opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0
Marco Gittlerd06cdbe2007-06-28 10:10:00 -0300547 ) {
Marco Gittler941491f2007-04-19 11:26:47 -0300548 return -EINVAL;
549 }
550
Marco Gittlerd06cdbe2007-06-28 10:10:00 -0300551 if (dvb_usb_device_init(intf, &opera1_properties, THIS_MODULE, NULL) != 0)
Marco Gittler941491f2007-04-19 11:26:47 -0300552 return -EINVAL;
553 return 0;
554}
555
556static struct usb_driver opera1_driver = {
557 .name = "opera1",
558 .probe = opera1_probe,
559 .disconnect = dvb_usb_device_exit,
560 .id_table = opera1_table,
561};
562
563static int __init opera1_module_init(void)
564{
565 int result = 0;
566 if ((result = usb_register(&opera1_driver))) {
567 err("usb_register failed. Error number %d", result);
568 }
569 return result;
570}
571
572static void __exit opera1_module_exit(void)
573{
574 usb_deregister(&opera1_driver);
575}
576
577module_init(opera1_module_init);
578module_exit(opera1_module_exit);
579
580MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
581MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
582MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
583MODULE_VERSION("0.1");
584MODULE_LICENSE("GPL");