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};
35struct rc_map_opera_table {
36 u32 keycode;
37 u32 event;
38};
39
40static int dvb_usb_opera1_debug;
41module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
42MODULE_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
46DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
47
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 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(size: 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 requesttype: request_type | USB_TYPE_VENDOR, value, index: 0x0,
67 data: buf, size: len, timeout: 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 value: 0x01, index: 0x0, data: buf, size: 1, timeout: 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);
81out:
82 kfree(objp: buf);
83 return ret;
84}
85
86/* I2C */
87
88static 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: dev->udev, request,
124 value, data: buf, len,
125 flags: addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
126
127 mutex_unlock(lock: &dev->usb_mutex);
128 return ret;
129}
130
131static 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(dev: d,
144 addr: (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
145 buf: msg[i].buf,
146 len: 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(lock: &d->i2c_mutex);
154 return num;
155}
156
157static u32 opera1_i2c_func(struct i2c_adapter *adapter)
158{
159 return I2C_FUNC_I2C;
160}
161
162static struct i2c_algorithm opera1_i2c_algo = {
163 .master_xfer = opera1_i2c_xfer,
164 .functionality = opera1_i2c_func,
165};
166
167static 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(adap: &udev_adap->dev->i2c_adap, msgs: msg, num: 1);
181 return 0;
182}
183
184static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
185 u32 ratio)
186{
187 stv0299_writereg(fe, reg: 0x13, val: 0x98);
188 stv0299_writereg(fe, reg: 0x14, val: 0x95);
189 stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, val: (ratio >> 16) & 0xff);
190 stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, val: (ratio >> 8) & 0xff);
191 stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, val: (ratio) & 0xf0);
192 return 0;
193
194}
195static 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
249static 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
261static 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
273static 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
282static 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(dev: d->udev, request: 0xb7, value: val,
289 data: &val, len: 1, OPERA_WRITE_MSG);
290}
291
292static 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: &adap->dev->i2c_adap, msgs: start_tuner, num: 1);
302 return 0;
303}
304
305static 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: &adap->dev->i2c_adap, msgs: msg, num: 1);
319 return 0;
320}
321
322static 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: &adap->dev->i2c_adap, msgs: msg, num: 1);
336 }
337 return 0;
338}
339
340static 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
369static 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(adap: &dev->i2c_adap, msgs: read_remote, num: 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(key: &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
427enum {
428 CYPRESS_OPERA1_COLD,
429 OPERA1_WARM,
430};
431
432static struct usb_device_id opera1_table[] = {
433 DVB_USB_DEV(CYPRESS, CYPRESS_OPERA1_COLD),
434 DVB_USB_DEV(OPERA1, OPERA1_WARM),
435 { }
436};
437
438MODULE_DEVICE_TABLE(usb, opera1_table);
439
440static 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(dev: d->udev, request: 0xb1, value: 0xa0, data: command, len: 1, OPERA_WRITE_MSG);
445 if (ret)
446 return ret;
447 ret = opera1_xilinx_rw(dev: d->udev, request: 0xb1, value: 0xa1, data: mac, len: 6, OPERA_READ_MSG);
448 if (ret)
449 return ret;
450 return 0;
451}
452static 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: &fw, name: filename, device: &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(size: fw->size, GFP_KERNEL);
467 opera1_xilinx_rw(dev, request: 0xbc, value: 0x00, data: &testval, len: 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, request: 0xbc, value: 0xaa, data: &fpga_command, len: 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, value: 0x0, data: b , len: 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, request: 0xa0, value: 0xe600, data: &reset, len: 1,
493 OPERA_WRITE_MSG) != 1) {
494 err("could not restart the USB controller CPU.");
495 ret = -EINVAL;
496 }
497 }
498 }
499 kfree(objp: p);
500 release_firmware(fw);
501 return ret;
502}
503
504static 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
558static 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(dev: udev, filename: "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_nums: adapter_nr))
572 return -EINVAL;
573 return 0;
574}
575
576static 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
583module_usb_driver(opera1_driver);
584
585MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
586MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
587MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
588MODULE_VERSION("0.1");
589MODULE_LICENSE("GPL");
590

source code of linux/drivers/media/usb/dvb-usb/opera1.c