xref: /linux/drivers/media/usb/dvb-usb/opera1.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
3 *
4 * Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
5 * Copyright (C) 2006 Marco Gittler (g.marco@freenet.de)
6 *
7 * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
8 */
9 
10 #define DVB_USB_LOG_PREFIX "opera"
11 
12 #include "dvb-usb.h"
13 #include "stv0299.h"
14 
15 #define OPERA_READ_MSG 0
16 #define OPERA_WRITE_MSG 1
17 #define OPERA_I2C_TUNER 0xd1
18 
19 #define READ_FX2_REG_REQ  0xba
20 #define READ_MAC_ADDR 0x08
21 #define OPERA_WRITE_FX2 0xbb
22 #define OPERA_TUNER_REQ 0xb1
23 #define REG_1F_SYMBOLRATE_BYTE0 0x1f
24 #define REG_20_SYMBOLRATE_BYTE1 0x20
25 #define REG_21_SYMBOLRATE_BYTE2 0x21
26 
27 #define ADDR_B600_VOLTAGE_13V (0x02)
28 #define ADDR_B601_VOLTAGE_18V (0x03)
29 #define ADDR_B1A6_STREAM_CTRL (0x04)
30 #define ADDR_B880_READ_REMOTE (0x05)
31 
32 struct opera1_state {
33 	u32 last_key_pressed;
34 };
35 
36 static int dvb_usb_opera1_debug;
37 module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
38 MODULE_PARM_DESC(debug,
39 		 "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
40 		 DVB_USB_DEBUG_STATUS);
41 
42 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43 
44 
opera1_xilinx_rw(struct usb_device * dev,u8 request,u16 value,u8 * data,u16 len,int flags)45 static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
46 			    u8 * data, u16 len, int flags)
47 {
48 	int ret;
49 	u8 tmp;
50 	u8 *buf;
51 	unsigned int pipe = (flags == OPERA_READ_MSG) ?
52 		usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
53 	u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
54 
55 	buf = kmalloc(len, GFP_KERNEL);
56 	if (!buf)
57 		return -ENOMEM;
58 
59 	if (flags == OPERA_WRITE_MSG)
60 		memcpy(buf, data, len);
61 	ret = usb_control_msg(dev, pipe, request,
62 			request_type | USB_TYPE_VENDOR, value, 0x0,
63 			buf, len, 2000);
64 
65 	if (request == OPERA_TUNER_REQ) {
66 		tmp = buf[0];
67 		if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
68 			    OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
69 			    0x01, 0x0, buf, 1, 2000) < 1 || buf[0] != 0x08) {
70 			ret = 0;
71 			goto out;
72 		}
73 		buf[0] = tmp;
74 	}
75 	if (flags == OPERA_READ_MSG)
76 		memcpy(data, buf, len);
77 out:
78 	kfree(buf);
79 	return ret;
80 }
81 
82 /* I2C */
83 
opera1_usb_i2c_msgxfer(struct dvb_usb_device * dev,u16 addr,u8 * buf,u16 len)84 static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
85 				  u8 * buf, u16 len)
86 {
87 	int ret = 0;
88 	u8 request;
89 	u16 value;
90 
91 	if (!dev) {
92 		info("no usb_device");
93 		return -EINVAL;
94 	}
95 	if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
96 		return -EAGAIN;
97 
98 	switch (addr>>1){
99 		case ADDR_B600_VOLTAGE_13V:
100 			request=0xb6;
101 			value=0x00;
102 			break;
103 		case ADDR_B601_VOLTAGE_18V:
104 			request=0xb6;
105 			value=0x01;
106 			break;
107 		case ADDR_B1A6_STREAM_CTRL:
108 			request=0xb1;
109 			value=0xa6;
110 			break;
111 		case ADDR_B880_READ_REMOTE:
112 			request=0xb8;
113 			value=0x80;
114 			break;
115 		default:
116 			request=0xb1;
117 			value=addr;
118 	}
119 	ret = opera1_xilinx_rw(dev->udev, request,
120 		value, buf, len,
121 		addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
122 
123 	mutex_unlock(&dev->usb_mutex);
124 	return ret;
125 }
126 
opera1_i2c_xfer(struct i2c_adapter * adap,struct i2c_msg msg[],int num)127 static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
128 			   int num)
129 {
130 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
131 	int i = 0, tmp = 0;
132 
133 	if (!d)
134 		return -ENODEV;
135 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
136 		return -EAGAIN;
137 
138 	for (i = 0; i < num; i++) {
139 		if ((tmp = opera1_usb_i2c_msgxfer(d,
140 					(msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
141 					msg[i].buf,
142 					msg[i].len
143 					)) != msg[i].len) {
144 			break;
145 		}
146 		if (dvb_usb_opera1_debug & 0x10)
147 			info("sending i2c message %d %d", tmp, msg[i].len);
148 	}
149 	mutex_unlock(&d->i2c_mutex);
150 	return num;
151 }
152 
opera1_i2c_func(struct i2c_adapter * adapter)153 static u32 opera1_i2c_func(struct i2c_adapter *adapter)
154 {
155 	return I2C_FUNC_I2C;
156 }
157 
158 static struct i2c_algorithm opera1_i2c_algo = {
159 	.master_xfer = opera1_i2c_xfer,
160 	.functionality = opera1_i2c_func,
161 };
162 
opera1_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)163 static int opera1_set_voltage(struct dvb_frontend *fe,
164 			      enum fe_sec_voltage voltage)
165 {
166 	static u8 command_13v[1]={0x00};
167 	static u8 command_18v[1]={0x01};
168 	struct i2c_msg msg[] = {
169 		{.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
170 	};
171 	struct dvb_usb_adapter *udev_adap = fe->dvb->priv;
172 	if (voltage == SEC_VOLTAGE_18) {
173 		msg[0].addr = ADDR_B601_VOLTAGE_18V;
174 		msg[0].buf = command_18v;
175 	}
176 	i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
177 	return 0;
178 }
179 
opera1_stv0299_set_symbol_rate(struct dvb_frontend * fe,u32 srate,u32 ratio)180 static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
181 					  u32 ratio)
182 {
183 	stv0299_writereg(fe, 0x13, 0x98);
184 	stv0299_writereg(fe, 0x14, 0x95);
185 	stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
186 	stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
187 	stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
188 	return 0;
189 
190 }
191 static u8 opera1_inittab[] = {
192 	0x00, 0xa1,
193 	0x01, 0x15,
194 	0x02, 0x30,
195 	0x03, 0x00,
196 	0x04, 0x7d,
197 	0x05, 0x05,
198 	0x06, 0x02,
199 	0x07, 0x00,
200 	0x0b, 0x00,
201 	0x0c, 0x01,
202 	0x0d, 0x81,
203 	0x0e, 0x44,
204 	0x0f, 0x19,
205 	0x10, 0x3f,
206 	0x11, 0x84,
207 	0x12, 0xda,
208 	0x13, 0x98,
209 	0x14, 0x95,
210 	0x15, 0xc9,
211 	0x16, 0xeb,
212 	0x17, 0x00,
213 	0x18, 0x19,
214 	0x19, 0x8b,
215 	0x1a, 0x00,
216 	0x1b, 0x82,
217 	0x1c, 0x7f,
218 	0x1d, 0x00,
219 	0x1e, 0x00,
220 	REG_1F_SYMBOLRATE_BYTE0, 0x06,
221 	REG_20_SYMBOLRATE_BYTE1, 0x50,
222 	REG_21_SYMBOLRATE_BYTE2, 0x10,
223 	0x22, 0x00,
224 	0x23, 0x00,
225 	0x24, 0x37,
226 	0x25, 0xbc,
227 	0x26, 0x00,
228 	0x27, 0x00,
229 	0x28, 0x00,
230 	0x29, 0x1e,
231 	0x2a, 0x14,
232 	0x2b, 0x1f,
233 	0x2c, 0x09,
234 	0x2d, 0x0a,
235 	0x2e, 0x00,
236 	0x2f, 0x00,
237 	0x30, 0x00,
238 	0x31, 0x1f,
239 	0x32, 0x19,
240 	0x33, 0xfc,
241 	0x34, 0x13,
242 	0xff, 0xff,
243 };
244 
245 static struct stv0299_config opera1_stv0299_config = {
246 	.demod_address = 0xd0>>1,
247 	.min_delay_ms = 100,
248 	.mclk = 88000000UL,
249 	.invert = 1,
250 	.skip_reinit = 0,
251 	.lock_output = STV0299_LOCKOUTPUT_0,
252 	.volt13_op0_op1 = STV0299_VOLT13_OP0,
253 	.inittab = opera1_inittab,
254 	.set_symbol_rate = opera1_stv0299_set_symbol_rate,
255 };
256 
opera1_frontend_attach(struct dvb_usb_adapter * d)257 static int opera1_frontend_attach(struct dvb_usb_adapter *d)
258 {
259 	d->fe_adap[0].fe = dvb_attach(stv0299_attach, &opera1_stv0299_config,
260 				      &d->dev->i2c_adap);
261 	if ((d->fe_adap[0].fe) != NULL) {
262 		d->fe_adap[0].fe->ops.set_voltage = opera1_set_voltage;
263 		return 0;
264 	}
265 	info("not attached stv0299");
266 	return -EIO;
267 }
268 
opera1_tuner_attach(struct dvb_usb_adapter * adap)269 static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
270 {
271 	dvb_attach(
272 		dvb_pll_attach, adap->fe_adap[0].fe, 0xc0>>1,
273 		&adap->dev->i2c_adap, DVB_PLL_OPERA1
274 	);
275 	return 0;
276 }
277 
opera1_power_ctrl(struct dvb_usb_device * d,int onoff)278 static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
279 {
280 	u8 val = onoff ? 0x01 : 0x00;
281 
282 	if (dvb_usb_opera1_debug)
283 		info("power %s", onoff ? "on" : "off");
284 	return opera1_xilinx_rw(d->udev, 0xb7, val,
285 				&val, 1, OPERA_WRITE_MSG);
286 }
287 
opera1_streaming_ctrl(struct dvb_usb_adapter * adap,int onoff)288 static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
289 {
290 	static u8 buf_start[2] = { 0xff, 0x03 };
291 	static u8 buf_stop[2] = { 0xff, 0x00 };
292 	struct i2c_msg start_tuner[] = {
293 		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
294 	};
295 	if (dvb_usb_opera1_debug)
296 		info("streaming %s", onoff ? "on" : "off");
297 	i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
298 	return 0;
299 }
300 
opera1_pid_filter(struct dvb_usb_adapter * adap,int index,u16 pid,int onoff)301 static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
302 			     int onoff)
303 {
304 	u8 b_pid[3];
305 	struct i2c_msg msg[] = {
306 		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
307 	};
308 	if (dvb_usb_opera1_debug)
309 		info("pidfilter index: %d pid: %d %s", index, pid,
310 			onoff ? "on" : "off");
311 	b_pid[0] = (2 * index) + 4;
312 	b_pid[1] = onoff ? (pid & 0xff) : (0x00);
313 	b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
314 	i2c_transfer(&adap->dev->i2c_adap, msg, 1);
315 	return 0;
316 }
317 
opera1_pid_filter_control(struct dvb_usb_adapter * adap,int onoff)318 static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
319 {
320 	int u = 0x04;
321 	u8 b_pid[3];
322 	struct i2c_msg msg[] = {
323 		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
324 	};
325 	if (dvb_usb_opera1_debug)
326 		info("%s hw-pidfilter", onoff ? "enable" : "disable");
327 	for (; u < 0x7e; u += 2) {
328 		b_pid[0] = u;
329 		b_pid[1] = 0;
330 		b_pid[2] = 0x80;
331 		i2c_transfer(&adap->dev->i2c_adap, msg, 1);
332 	}
333 	return 0;
334 }
335 
336 static struct rc_map_table rc_map_opera1_table[] = {
337 	{0x5fa0, KEY_1},
338 	{0x51af, KEY_2},
339 	{0x5da2, KEY_3},
340 	{0x41be, KEY_4},
341 	{0x0bf5, KEY_5},
342 	{0x43bd, KEY_6},
343 	{0x47b8, KEY_7},
344 	{0x49b6, KEY_8},
345 	{0x05fa, KEY_9},
346 	{0x45ba, KEY_0},
347 	{0x09f6, KEY_CHANNELUP},	/*chanup */
348 	{0x1be5, KEY_CHANNELDOWN},	/*chandown */
349 	{0x5da3, KEY_VOLUMEDOWN},	/*voldown */
350 	{0x5fa1, KEY_VOLUMEUP},		/*volup */
351 	{0x07f8, KEY_SPACE},		/*tab */
352 	{0x1fe1, KEY_OK},		/*play ok */
353 	{0x1be4, KEY_ZOOM},		/*zoom */
354 	{0x59a6, KEY_MUTE},		/*mute */
355 	{0x5ba5, KEY_RADIO},		/*tv/f */
356 	{0x19e7, KEY_RECORD},		/*rec */
357 	{0x01fe, KEY_STOP},		/*Stop */
358 	{0x03fd, KEY_PAUSE},		/*pause */
359 	{0x03fc, KEY_SCREEN},		/*<- -> */
360 	{0x07f9, KEY_CAMERA},		/*capture */
361 	{0x47b9, KEY_ESC},		/*exit */
362 	{0x43bc, KEY_POWER2},		/*power */
363 };
364 
opera1_rc_query(struct dvb_usb_device * dev,u32 * event,int * state)365 static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
366 {
367 	struct opera1_state *opst = dev->priv;
368 	u8 rcbuffer[32];
369 	const u16 startmarker1 = 0x10ed;
370 	const u16 startmarker2 = 0x11ec;
371 	struct i2c_msg read_remote[] = {
372 		{.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
373 	};
374 	int i = 0;
375 	u32 send_key = 0;
376 
377 	if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
378 		for (i = 0; i < 32; i++) {
379 			if (rcbuffer[i])
380 				send_key |= 1;
381 			if (i < 31)
382 				send_key = send_key << 1;
383 		}
384 		if (send_key & 0x8000)
385 			send_key = (send_key << 1) | (send_key >> 15 & 0x01);
386 
387 		if (send_key == 0xffff && opst->last_key_pressed != 0) {
388 			*state = REMOTE_KEY_REPEAT;
389 			*event = opst->last_key_pressed;
390 			return 0;
391 		}
392 		for (; send_key != 0;) {
393 			if (send_key >> 16 == startmarker2) {
394 				break;
395 			} else if (send_key >> 16 == startmarker1) {
396 				send_key =
397 					(send_key & 0xfffeffff) | (startmarker1 << 16);
398 				break;
399 			} else
400 				send_key >>= 1;
401 		}
402 
403 		if (send_key == 0)
404 			return 0;
405 
406 		send_key = (send_key & 0xffff) | 0x0100;
407 
408 		for (i = 0; i < ARRAY_SIZE(rc_map_opera1_table); i++) {
409 			if (rc5_scan(&rc_map_opera1_table[i]) == (send_key & 0xffff)) {
410 				*state = REMOTE_KEY_PRESSED;
411 				*event = rc_map_opera1_table[i].keycode;
412 				opst->last_key_pressed =
413 					rc_map_opera1_table[i].keycode;
414 				break;
415 			}
416 			opst->last_key_pressed = 0;
417 		}
418 	} else
419 		*state = REMOTE_NO_KEY_PRESSED;
420 	return 0;
421 }
422 
423 enum {
424 	CYPRESS_OPERA1_COLD,
425 	OPERA1_WARM,
426 };
427 
428 static struct usb_device_id opera1_table[] = {
429 	DVB_USB_DEV(CYPRESS, CYPRESS_OPERA1_COLD),
430 	DVB_USB_DEV(OPERA1, OPERA1_WARM),
431 	{ }
432 };
433 
434 MODULE_DEVICE_TABLE(usb, opera1_table);
435 
opera1_read_mac_address(struct dvb_usb_device * d,u8 mac[6])436 static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
437 {
438 	int ret;
439 	u8 command[] = { READ_MAC_ADDR };
440 	ret = opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
441 	if (ret)
442 		return ret;
443 	ret = opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
444 	if (ret)
445 		return ret;
446 	return 0;
447 }
opera1_xilinx_load_firmware(struct usb_device * dev,const char * filename)448 static int opera1_xilinx_load_firmware(struct usb_device *dev,
449 				       const char *filename)
450 {
451 	const struct firmware *fw = NULL;
452 	u8 *b, *p;
453 	int ret = 0, i,fpgasize=40;
454 	u8 testval;
455 	info("start downloading fpga firmware %s",filename);
456 
457 	if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
458 		err("did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware",
459 			filename);
460 		return ret;
461 	} else {
462 		p = kmalloc(fw->size, GFP_KERNEL);
463 		opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
464 		if (p != NULL && testval != 0x67) {
465 
466 			u8 reset = 0, fpga_command = 0;
467 			memcpy(p, fw->data, fw->size);
468 			/* clear fpga ? */
469 			opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
470 					 OPERA_WRITE_MSG);
471 			for (i = 0; i < fw->size;) {
472 				if ( (fw->size - i) <fpgasize){
473 				    fpgasize=fw->size-i;
474 				}
475 				b = (u8 *) p + i;
476 				if (opera1_xilinx_rw
477 					(dev, OPERA_WRITE_FX2, 0x0, b , fpgasize,
478 						OPERA_WRITE_MSG) != fpgasize
479 					) {
480 					err("error while transferring firmware");
481 					ret = -EINVAL;
482 					break;
483 				}
484 				i = i + fpgasize;
485 			}
486 			/* restart the CPU */
487 			if (ret || opera1_xilinx_rw
488 					(dev, 0xa0, 0xe600, &reset, 1,
489 					OPERA_WRITE_MSG) != 1) {
490 				err("could not restart the USB controller CPU.");
491 				ret = -EINVAL;
492 			}
493 		}
494 	}
495 	kfree(p);
496 	release_firmware(fw);
497 	return ret;
498 }
499 
500 static struct dvb_usb_device_properties opera1_properties = {
501 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
502 	.usb_ctrl = CYPRESS_FX2,
503 	.firmware = "dvb-usb-opera-01.fw",
504 	.size_of_priv = sizeof(struct opera1_state),
505 
506 	.power_ctrl = opera1_power_ctrl,
507 	.i2c_algo = &opera1_i2c_algo,
508 
509 	.rc.legacy = {
510 		.rc_map_table = rc_map_opera1_table,
511 		.rc_map_size = ARRAY_SIZE(rc_map_opera1_table),
512 		.rc_interval = 200,
513 		.rc_query = opera1_rc_query,
514 	},
515 	.read_mac_address = opera1_read_mac_address,
516 	.generic_bulk_ctrl_endpoint = 0x00,
517 	/* parameter for the MPEG2-data transfer */
518 	.num_adapters = 1,
519 	.adapter = {
520 		{
521 		.num_frontends = 1,
522 		.fe = {{
523 			.frontend_attach = opera1_frontend_attach,
524 			.streaming_ctrl = opera1_streaming_ctrl,
525 			.tuner_attach = opera1_tuner_attach,
526 			.caps =
527 				DVB_USB_ADAP_HAS_PID_FILTER |
528 				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
529 			.pid_filter = opera1_pid_filter,
530 			.pid_filter_ctrl = opera1_pid_filter_control,
531 			.pid_filter_count = 252,
532 			.stream = {
533 				.type = USB_BULK,
534 				.count = 10,
535 				.endpoint = 0x82,
536 				.u = {
537 					.bulk = {
538 						.buffersize = 4096,
539 					}
540 				}
541 			},
542 		}},
543 		}
544 	},
545 	.num_device_descs = 1,
546 	.devices = {
547 		{"Opera1 DVB-S USB2.0",
548 			{&opera1_table[CYPRESS_OPERA1_COLD], NULL},
549 			{&opera1_table[OPERA1_WARM], NULL},
550 		},
551 	}
552 };
553 
opera1_probe(struct usb_interface * intf,const struct usb_device_id * id)554 static int opera1_probe(struct usb_interface *intf,
555 			const struct usb_device_id *id)
556 {
557 	struct usb_device *udev = interface_to_usbdev(intf);
558 
559 	if (le16_to_cpu(udev->descriptor.idProduct) == USB_PID_OPERA1_WARM &&
560 	    le16_to_cpu(udev->descriptor.idVendor) == USB_VID_OPERA1 &&
561 		opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0
562 	    ) {
563 		return -EINVAL;
564 	}
565 
566 	if (0 != dvb_usb_device_init(intf, &opera1_properties,
567 				     THIS_MODULE, NULL, adapter_nr))
568 		return -EINVAL;
569 	return 0;
570 }
571 
572 static struct usb_driver opera1_driver = {
573 	.name = "opera1",
574 	.probe = opera1_probe,
575 	.disconnect = dvb_usb_device_exit,
576 	.id_table = opera1_table,
577 };
578 
579 module_usb_driver(opera1_driver);
580 
581 MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
582 MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
583 MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
584 MODULE_VERSION("0.1");
585 MODULE_LICENSE("GPL");
586