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