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

dtt200u.c (10715B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
      3 * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
      4 *
      5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
      6 *
      7 * Thanks to Steve Chang from WideView for providing support for the WT-220U.
      8 *
      9 * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
     10 */
     11#include "dtt200u.h"
     12
     13/* debug */
     14int dvb_usb_dtt200u_debug;
     15module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
     16MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
     17
     18DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
     19
     20struct dtt200u_state {
     21	unsigned char data[80];
     22};
     23
     24static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
     25{
     26	struct dtt200u_state *st = d->priv;
     27	int ret = 0;
     28
     29	mutex_lock(&d->data_mutex);
     30
     31	st->data[0] = SET_INIT;
     32
     33	if (onoff)
     34		ret = dvb_usb_generic_write(d, st->data, 2);
     35
     36	mutex_unlock(&d->data_mutex);
     37	return ret;
     38}
     39
     40static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
     41{
     42	struct dvb_usb_device *d = adap->dev;
     43	struct dtt200u_state *st = d->priv;
     44	int ret;
     45
     46	mutex_lock(&d->data_mutex);
     47	st->data[0] = SET_STREAMING;
     48	st->data[1] = onoff;
     49
     50	ret = dvb_usb_generic_write(adap->dev, st->data, 2);
     51	if (ret < 0)
     52		goto ret;
     53
     54	if (onoff)
     55		goto ret;
     56
     57	st->data[0] = RESET_PID_FILTER;
     58	ret = dvb_usb_generic_write(adap->dev, st->data, 1);
     59
     60ret:
     61	mutex_unlock(&d->data_mutex);
     62
     63	return ret;
     64}
     65
     66static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
     67{
     68	struct dvb_usb_device *d = adap->dev;
     69	struct dtt200u_state *st = d->priv;
     70	int ret;
     71
     72	pid = onoff ? pid : 0;
     73
     74	mutex_lock(&d->data_mutex);
     75	st->data[0] = SET_PID_FILTER;
     76	st->data[1] = index;
     77	st->data[2] = pid & 0xff;
     78	st->data[3] = (pid >> 8) & 0x1f;
     79
     80	ret = dvb_usb_generic_write(adap->dev, st->data, 4);
     81	mutex_unlock(&d->data_mutex);
     82
     83	return ret;
     84}
     85
     86static int dtt200u_rc_query(struct dvb_usb_device *d)
     87{
     88	struct dtt200u_state *st = d->priv;
     89	u32 scancode;
     90	int ret;
     91
     92	mutex_lock(&d->data_mutex);
     93	st->data[0] = GET_RC_CODE;
     94
     95	ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0);
     96	if (ret < 0)
     97		goto ret;
     98
     99	if (st->data[0] == 1) {
    100		enum rc_proto proto = RC_PROTO_NEC;
    101
    102		scancode = st->data[1];
    103		if ((u8) ~st->data[1] != st->data[2]) {
    104			/* Extended NEC */
    105			scancode = scancode << 8;
    106			scancode |= st->data[2];
    107			proto = RC_PROTO_NECX;
    108		}
    109		scancode = scancode << 8;
    110		scancode |= st->data[3];
    111
    112		/* Check command checksum is ok */
    113		if ((u8) ~st->data[3] == st->data[4])
    114			rc_keydown(d->rc_dev, proto, scancode, 0);
    115		else
    116			rc_keyup(d->rc_dev);
    117	} else if (st->data[0] == 2) {
    118		rc_repeat(d->rc_dev);
    119	} else {
    120		rc_keyup(d->rc_dev);
    121	}
    122
    123	if (st->data[0] != 0)
    124		deb_info("st->data: %*ph\n", 5, st->data);
    125
    126ret:
    127	mutex_unlock(&d->data_mutex);
    128	return ret;
    129}
    130
    131static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap)
    132{
    133	adap->fe_adap[0].fe = dtt200u_fe_attach(adap->dev);
    134	return 0;
    135}
    136
    137static struct dvb_usb_device_properties dtt200u_properties;
    138static struct dvb_usb_device_properties wt220u_fc_properties;
    139static struct dvb_usb_device_properties wt220u_properties;
    140static struct dvb_usb_device_properties wt220u_zl0353_properties;
    141static struct dvb_usb_device_properties wt220u_miglia_properties;
    142
    143static int dtt200u_usb_probe(struct usb_interface *intf,
    144		const struct usb_device_id *id)
    145{
    146	if (0 == dvb_usb_device_init(intf, &dtt200u_properties,
    147				     THIS_MODULE, NULL, adapter_nr) ||
    148	    0 == dvb_usb_device_init(intf, &wt220u_properties,
    149				     THIS_MODULE, NULL, adapter_nr) ||
    150	    0 == dvb_usb_device_init(intf, &wt220u_fc_properties,
    151				     THIS_MODULE, NULL, adapter_nr) ||
    152	    0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties,
    153				     THIS_MODULE, NULL, adapter_nr) ||
    154	    0 == dvb_usb_device_init(intf, &wt220u_miglia_properties,
    155				     THIS_MODULE, NULL, adapter_nr))
    156		return 0;
    157
    158	return -ENODEV;
    159}
    160
    161enum {
    162	WIDEVIEW_DTT200U_COLD,
    163	WIDEVIEW_DTT200U_WARM,
    164	WIDEVIEW_WT220U_COLD,
    165	WIDEVIEW_WT220U_WARM,
    166	WIDEVIEW_WT220U_ZL0353_COLD,
    167	WIDEVIEW_WT220U_ZL0353_WARM,
    168	WIDEVIEW_WT220U_FC_COLD,
    169	WIDEVIEW_WT220U_FC_WARM,
    170	WIDEVIEW_WT220U_ZAP250_COLD,
    171	MIGLIA_WT220U_ZAP250_COLD,
    172};
    173
    174static struct usb_device_id dtt200u_usb_table[] = {
    175	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DTT200U_COLD),
    176	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DTT200U_WARM),
    177	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_WT220U_COLD),
    178	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_WT220U_WARM),
    179	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_WT220U_ZL0353_COLD),
    180	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_WT220U_ZL0353_WARM),
    181	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_WT220U_FC_COLD),
    182	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_WT220U_FC_WARM),
    183	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_WT220U_ZAP250_COLD),
    184	DVB_USB_DEV(MIGLIA, MIGLIA_WT220U_ZAP250_COLD),
    185	{ }
    186};
    187
    188MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
    189
    190static struct dvb_usb_device_properties dtt200u_properties = {
    191	.usb_ctrl = CYPRESS_FX2,
    192	.firmware = "dvb-usb-dtt200u-01.fw",
    193
    194	.size_of_priv     = sizeof(struct dtt200u_state),
    195
    196	.num_adapters = 1,
    197	.adapter = {
    198		{
    199		.num_frontends = 1,
    200		.fe = {{
    201			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
    202			.pid_filter_count = 15,
    203
    204	.streaming_ctrl  = dtt200u_streaming_ctrl,
    205	.pid_filter      = dtt200u_pid_filter,
    206	.frontend_attach = dtt200u_frontend_attach,
    207	/* parameter for the MPEG2-data transfer */
    208			.stream = {
    209				.type = USB_BULK,
    210		.count = 7,
    211		.endpoint = 0x02,
    212		.u = {
    213			.bulk = {
    214				.buffersize = 4096,
    215			}
    216		}
    217	},
    218		}},
    219		}
    220	},
    221	.power_ctrl      = dtt200u_power_ctrl,
    222
    223	.rc.core = {
    224		.rc_interval     = 300,
    225		.rc_codes        = RC_MAP_DTT200U,
    226		.rc_query        = dtt200u_rc_query,
    227		.allowed_protos  = RC_PROTO_BIT_NEC,
    228	},
    229
    230	.generic_bulk_ctrl_endpoint = 0x01,
    231
    232	.num_device_descs = 1,
    233	.devices = {
    234		{ .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
    235		  .cold_ids = { &dtt200u_usb_table[WIDEVIEW_DTT200U_COLD], NULL },
    236		  .warm_ids = { &dtt200u_usb_table[WIDEVIEW_DTT200U_WARM], NULL },
    237		},
    238		{ NULL },
    239	}
    240};
    241
    242static struct dvb_usb_device_properties wt220u_properties = {
    243	.usb_ctrl = CYPRESS_FX2,
    244	.firmware = "dvb-usb-wt220u-02.fw",
    245
    246	.size_of_priv     = sizeof(struct dtt200u_state),
    247
    248	.num_adapters = 1,
    249	.adapter = {
    250		{
    251		.num_frontends = 1,
    252		.fe = {{
    253			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
    254			.pid_filter_count = 15,
    255
    256	.streaming_ctrl  = dtt200u_streaming_ctrl,
    257	.pid_filter      = dtt200u_pid_filter,
    258	.frontend_attach = dtt200u_frontend_attach,
    259	/* parameter for the MPEG2-data transfer */
    260			.stream = {
    261				.type = USB_BULK,
    262		.count = 7,
    263		.endpoint = 0x02,
    264		.u = {
    265			.bulk = {
    266				.buffersize = 4096,
    267			}
    268		}
    269	},
    270		}},
    271		}
    272	},
    273	.power_ctrl      = dtt200u_power_ctrl,
    274
    275	.rc.core = {
    276		.rc_interval     = 300,
    277		.rc_codes        = RC_MAP_DTT200U,
    278		.rc_query        = dtt200u_rc_query,
    279		.allowed_protos  = RC_PROTO_BIT_NEC,
    280	},
    281
    282	.generic_bulk_ctrl_endpoint = 0x01,
    283
    284	.num_device_descs = 1,
    285	.devices = {
    286		{ .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
    287		  .cold_ids = { &dtt200u_usb_table[WIDEVIEW_WT220U_COLD], &dtt200u_usb_table[WIDEVIEW_WT220U_ZAP250_COLD], NULL },
    288		  .warm_ids = { &dtt200u_usb_table[WIDEVIEW_WT220U_WARM], NULL },
    289		},
    290		{ NULL },
    291	}
    292};
    293
    294static struct dvb_usb_device_properties wt220u_fc_properties = {
    295	.usb_ctrl = CYPRESS_FX2,
    296	.firmware = "dvb-usb-wt220u-fc03.fw",
    297
    298	.size_of_priv     = sizeof(struct dtt200u_state),
    299
    300	.num_adapters = 1,
    301	.adapter = {
    302		{
    303		.num_frontends = 1,
    304		.fe = {{
    305			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
    306			.pid_filter_count = 15,
    307
    308	.streaming_ctrl  = dtt200u_streaming_ctrl,
    309	.pid_filter      = dtt200u_pid_filter,
    310	.frontend_attach = dtt200u_frontend_attach,
    311	/* parameter for the MPEG2-data transfer */
    312			.stream = {
    313				.type = USB_BULK,
    314		.count = 7,
    315				.endpoint = 0x06,
    316		.u = {
    317			.bulk = {
    318				.buffersize = 4096,
    319			}
    320		}
    321	},
    322		}},
    323		}
    324	},
    325	.power_ctrl      = dtt200u_power_ctrl,
    326
    327	.rc.core = {
    328		.rc_interval     = 300,
    329		.rc_codes        = RC_MAP_DTT200U,
    330		.rc_query        = dtt200u_rc_query,
    331		.allowed_protos  = RC_PROTO_BIT_NEC,
    332	},
    333
    334	.generic_bulk_ctrl_endpoint = 0x01,
    335
    336	.num_device_descs = 1,
    337	.devices = {
    338		{ .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
    339		  .cold_ids = { &dtt200u_usb_table[WIDEVIEW_WT220U_FC_COLD], NULL },
    340		  .warm_ids = { &dtt200u_usb_table[WIDEVIEW_WT220U_FC_WARM], NULL },
    341		},
    342		{ NULL },
    343	}
    344};
    345
    346static struct dvb_usb_device_properties wt220u_zl0353_properties = {
    347	.usb_ctrl = CYPRESS_FX2,
    348	.firmware = "dvb-usb-wt220u-zl0353-01.fw",
    349
    350	.size_of_priv     = sizeof(struct dtt200u_state),
    351
    352	.num_adapters = 1,
    353	.adapter = {
    354		{
    355		.num_frontends = 1,
    356		.fe = {{
    357			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
    358			.pid_filter_count = 15,
    359
    360			.streaming_ctrl  = dtt200u_streaming_ctrl,
    361			.pid_filter      = dtt200u_pid_filter,
    362			.frontend_attach = dtt200u_frontend_attach,
    363			/* parameter for the MPEG2-data transfer */
    364			.stream = {
    365				.type = USB_BULK,
    366				.count = 7,
    367				.endpoint = 0x02,
    368				.u = {
    369					.bulk = {
    370						.buffersize = 4096,
    371					}
    372				}
    373			},
    374		}},
    375		}
    376	},
    377	.power_ctrl      = dtt200u_power_ctrl,
    378
    379	.rc.core = {
    380		.rc_interval     = 300,
    381		.rc_codes        = RC_MAP_DTT200U,
    382		.rc_query        = dtt200u_rc_query,
    383		.allowed_protos  = RC_PROTO_BIT_NEC,
    384	},
    385
    386	.generic_bulk_ctrl_endpoint = 0x01,
    387
    388	.num_device_descs = 1,
    389	.devices = {
    390		{ .name = "WideView WT-220U PenType Receiver (based on ZL353)",
    391		  .cold_ids = { &dtt200u_usb_table[WIDEVIEW_WT220U_ZL0353_COLD], NULL },
    392		  .warm_ids = { &dtt200u_usb_table[WIDEVIEW_WT220U_ZL0353_WARM], NULL },
    393		},
    394		{ NULL },
    395	}
    396};
    397
    398static struct dvb_usb_device_properties wt220u_miglia_properties = {
    399	.usb_ctrl = CYPRESS_FX2,
    400	.firmware = "dvb-usb-wt220u-miglia-01.fw",
    401
    402	.size_of_priv     = sizeof(struct dtt200u_state),
    403
    404	.num_adapters = 1,
    405	.generic_bulk_ctrl_endpoint = 0x01,
    406
    407	.num_device_descs = 1,
    408	.devices = {
    409		{ .name = "WideView WT-220U PenType Receiver (Miglia)",
    410		  .cold_ids = { &dtt200u_usb_table[MIGLIA_WT220U_ZAP250_COLD], NULL },
    411		  /* This device turns into WT220U_ZL0353_WARM when fw
    412		     has been uploaded */
    413		  .warm_ids = { NULL },
    414		},
    415		{ NULL },
    416	}
    417};
    418
    419/* usb specific object needed to register this driver with the usb subsystem */
    420static struct usb_driver dtt200u_usb_driver = {
    421	.name		= "dvb_usb_dtt200u",
    422	.probe		= dtt200u_usb_probe,
    423	.disconnect = dvb_usb_device_exit,
    424	.id_table	= dtt200u_usb_table,
    425};
    426
    427module_usb_driver(dtt200u_usb_driver);
    428
    429MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
    430MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
    431MODULE_VERSION("1.0");
    432MODULE_LICENSE("GPL");