cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

opera1.c (14077B)


      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(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);
     81out:
     82	kfree(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->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
    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(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
    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 =
    176	    (struct dvb_usb_adapter *)(fe->dvb->priv);
    177	if (voltage == SEC_VOLTAGE_18) {
    178		msg[0].addr = ADDR_B601_VOLTAGE_18V;
    179		msg[0].buf = command_18v;
    180	}
    181	i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
    182	return 0;
    183}
    184
    185static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
    186					  u32 ratio)
    187{
    188	stv0299_writereg(fe, 0x13, 0x98);
    189	stv0299_writereg(fe, 0x14, 0x95);
    190	stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
    191	stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
    192	stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
    193	return 0;
    194
    195}
    196static u8 opera1_inittab[] = {
    197	0x00, 0xa1,
    198	0x01, 0x15,
    199	0x02, 0x30,
    200	0x03, 0x00,
    201	0x04, 0x7d,
    202	0x05, 0x05,
    203	0x06, 0x02,
    204	0x07, 0x00,
    205	0x0b, 0x00,
    206	0x0c, 0x01,
    207	0x0d, 0x81,
    208	0x0e, 0x44,
    209	0x0f, 0x19,
    210	0x10, 0x3f,
    211	0x11, 0x84,
    212	0x12, 0xda,
    213	0x13, 0x98,
    214	0x14, 0x95,
    215	0x15, 0xc9,
    216	0x16, 0xeb,
    217	0x17, 0x00,
    218	0x18, 0x19,
    219	0x19, 0x8b,
    220	0x1a, 0x00,
    221	0x1b, 0x82,
    222	0x1c, 0x7f,
    223	0x1d, 0x00,
    224	0x1e, 0x00,
    225	REG_1F_SYMBOLRATE_BYTE0, 0x06,
    226	REG_20_SYMBOLRATE_BYTE1, 0x50,
    227	REG_21_SYMBOLRATE_BYTE2, 0x10,
    228	0x22, 0x00,
    229	0x23, 0x00,
    230	0x24, 0x37,
    231	0x25, 0xbc,
    232	0x26, 0x00,
    233	0x27, 0x00,
    234	0x28, 0x00,
    235	0x29, 0x1e,
    236	0x2a, 0x14,
    237	0x2b, 0x1f,
    238	0x2c, 0x09,
    239	0x2d, 0x0a,
    240	0x2e, 0x00,
    241	0x2f, 0x00,
    242	0x30, 0x00,
    243	0x31, 0x1f,
    244	0x32, 0x19,
    245	0x33, 0xfc,
    246	0x34, 0x13,
    247	0xff, 0xff,
    248};
    249
    250static struct stv0299_config opera1_stv0299_config = {
    251	.demod_address = 0xd0>>1,
    252	.min_delay_ms = 100,
    253	.mclk = 88000000UL,
    254	.invert = 1,
    255	.skip_reinit = 0,
    256	.lock_output = STV0299_LOCKOUTPUT_0,
    257	.volt13_op0_op1 = STV0299_VOLT13_OP0,
    258	.inittab = opera1_inittab,
    259	.set_symbol_rate = opera1_stv0299_set_symbol_rate,
    260};
    261
    262static int opera1_frontend_attach(struct dvb_usb_adapter *d)
    263{
    264	d->fe_adap[0].fe = dvb_attach(stv0299_attach, &opera1_stv0299_config,
    265				      &d->dev->i2c_adap);
    266	if ((d->fe_adap[0].fe) != NULL) {
    267		d->fe_adap[0].fe->ops.set_voltage = opera1_set_voltage;
    268		return 0;
    269	}
    270	info("not attached stv0299");
    271	return -EIO;
    272}
    273
    274static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
    275{
    276	dvb_attach(
    277		dvb_pll_attach, adap->fe_adap[0].fe, 0xc0>>1,
    278		&adap->dev->i2c_adap, DVB_PLL_OPERA1
    279	);
    280	return 0;
    281}
    282
    283static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
    284{
    285	u8 val = onoff ? 0x01 : 0x00;
    286
    287	if (dvb_usb_opera1_debug)
    288		info("power %s", onoff ? "on" : "off");
    289	return opera1_xilinx_rw(d->udev, 0xb7, val,
    290				&val, 1, OPERA_WRITE_MSG);
    291}
    292
    293static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
    294{
    295	static u8 buf_start[2] = { 0xff, 0x03 };
    296	static u8 buf_stop[2] = { 0xff, 0x00 };
    297	struct i2c_msg start_tuner[] = {
    298		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
    299	};
    300	if (dvb_usb_opera1_debug)
    301		info("streaming %s", onoff ? "on" : "off");
    302	i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
    303	return 0;
    304}
    305
    306static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
    307			     int onoff)
    308{
    309	u8 b_pid[3];
    310	struct i2c_msg msg[] = {
    311		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
    312	};
    313	if (dvb_usb_opera1_debug)
    314		info("pidfilter index: %d pid: %d %s", index, pid,
    315			onoff ? "on" : "off");
    316	b_pid[0] = (2 * index) + 4;
    317	b_pid[1] = onoff ? (pid & 0xff) : (0x00);
    318	b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
    319	i2c_transfer(&adap->dev->i2c_adap, msg, 1);
    320	return 0;
    321}
    322
    323static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
    324{
    325	int u = 0x04;
    326	u8 b_pid[3];
    327	struct i2c_msg msg[] = {
    328		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
    329	};
    330	if (dvb_usb_opera1_debug)
    331		info("%s hw-pidfilter", onoff ? "enable" : "disable");
    332	for (; u < 0x7e; u += 2) {
    333		b_pid[0] = u;
    334		b_pid[1] = 0;
    335		b_pid[2] = 0x80;
    336		i2c_transfer(&adap->dev->i2c_adap, msg, 1);
    337	}
    338	return 0;
    339}
    340
    341static struct rc_map_table rc_map_opera1_table[] = {
    342	{0x5fa0, KEY_1},
    343	{0x51af, KEY_2},
    344	{0x5da2, KEY_3},
    345	{0x41be, KEY_4},
    346	{0x0bf5, KEY_5},
    347	{0x43bd, KEY_6},
    348	{0x47b8, KEY_7},
    349	{0x49b6, KEY_8},
    350	{0x05fa, KEY_9},
    351	{0x45ba, KEY_0},
    352	{0x09f6, KEY_CHANNELUP},	/*chanup */
    353	{0x1be5, KEY_CHANNELDOWN},	/*chandown */
    354	{0x5da3, KEY_VOLUMEDOWN},	/*voldown */
    355	{0x5fa1, KEY_VOLUMEUP},		/*volup */
    356	{0x07f8, KEY_SPACE},		/*tab */
    357	{0x1fe1, KEY_OK},		/*play ok */
    358	{0x1be4, KEY_ZOOM},		/*zoom */
    359	{0x59a6, KEY_MUTE},		/*mute */
    360	{0x5ba5, KEY_RADIO},		/*tv/f */
    361	{0x19e7, KEY_RECORD},		/*rec */
    362	{0x01fe, KEY_STOP},		/*Stop */
    363	{0x03fd, KEY_PAUSE},		/*pause */
    364	{0x03fc, KEY_SCREEN},		/*<- -> */
    365	{0x07f9, KEY_CAMERA},		/*capture */
    366	{0x47b9, KEY_ESC},		/*exit */
    367	{0x43bc, KEY_POWER2},		/*power */
    368};
    369
    370static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
    371{
    372	struct opera1_state *opst = dev->priv;
    373	u8 rcbuffer[32];
    374	const u16 startmarker1 = 0x10ed;
    375	const u16 startmarker2 = 0x11ec;
    376	struct i2c_msg read_remote[] = {
    377		{.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
    378	};
    379	int i = 0;
    380	u32 send_key = 0;
    381
    382	if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
    383		for (i = 0; i < 32; i++) {
    384			if (rcbuffer[i])
    385				send_key |= 1;
    386			if (i < 31)
    387				send_key = send_key << 1;
    388		}
    389		if (send_key & 0x8000)
    390			send_key = (send_key << 1) | (send_key >> 15 & 0x01);
    391
    392		if (send_key == 0xffff && opst->last_key_pressed != 0) {
    393			*state = REMOTE_KEY_REPEAT;
    394			*event = opst->last_key_pressed;
    395			return 0;
    396		}
    397		for (; send_key != 0;) {
    398			if (send_key >> 16 == startmarker2) {
    399				break;
    400			} else if (send_key >> 16 == startmarker1) {
    401				send_key =
    402					(send_key & 0xfffeffff) | (startmarker1 << 16);
    403				break;
    404			} else
    405				send_key >>= 1;
    406		}
    407
    408		if (send_key == 0)
    409			return 0;
    410
    411		send_key = (send_key & 0xffff) | 0x0100;
    412
    413		for (i = 0; i < ARRAY_SIZE(rc_map_opera1_table); i++) {
    414			if (rc5_scan(&rc_map_opera1_table[i]) == (send_key & 0xffff)) {
    415				*state = REMOTE_KEY_PRESSED;
    416				*event = rc_map_opera1_table[i].keycode;
    417				opst->last_key_pressed =
    418					rc_map_opera1_table[i].keycode;
    419				break;
    420			}
    421			opst->last_key_pressed = 0;
    422		}
    423	} else
    424		*state = REMOTE_NO_KEY_PRESSED;
    425	return 0;
    426}
    427
    428enum {
    429	CYPRESS_OPERA1_COLD,
    430	OPERA1_WARM,
    431};
    432
    433static struct usb_device_id opera1_table[] = {
    434	DVB_USB_DEV(CYPRESS, CYPRESS_OPERA1_COLD),
    435	DVB_USB_DEV(OPERA1, OPERA1_WARM),
    436	{ }
    437};
    438
    439MODULE_DEVICE_TABLE(usb, opera1_table);
    440
    441static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
    442{
    443	u8 command[] = { READ_MAC_ADDR };
    444	opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
    445	opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
    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");