File Index
Files and directories
Sign in
FILE

opera1.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/usb/dvb-usb/opera1.c C
  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
 32struct opera1_state {
 33	u32 last_key_pressed;
 34};
 35
 36static int dvb_usb_opera1_debug;
 37module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
 38MODULE_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
 42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 43
 44
 45static 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);
 77out:
 78	kfree(buf);
 79	return ret;
 80}
 81
 82/* I2C */
 83
 84static 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
127static 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
153static u32 opera1_i2c_func(struct i2c_adapter *adapter)
154{
155	return I2C_FUNC_I2C;
156}
157
158static const struct i2c_algorithm opera1_i2c_algo = {
159	.master_xfer = opera1_i2c_xfer,
160	.functionality = opera1_i2c_func,
161};
162
163static 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
180static 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}
191static 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
245static 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
257static 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
269static 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
278static 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
288static 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
301static 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
318static 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
336static 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
365static 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
423enum {
424	CYPRESS_OPERA1_COLD,
425	OPERA1_WARM,
426};
427
428static const struct usb_device_id opera1_table[] = {
429	DVB_USB_DEV(CYPRESS, CYPRESS_OPERA1_COLD),
430	DVB_USB_DEV(OPERA1, OPERA1_WARM),
431	{ }
432};
433
434MODULE_DEVICE_TABLE(usb, opera1_table);
435
436static 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}
448static 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
500static 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
554static 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
572static 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
579module_usb_driver(opera1_driver);
580
581MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
582MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
583MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
584MODULE_VERSION("0.1");
585MODULE_LICENSE("GPL");
~/ Read-only file preview.