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