brintos

brintos / linux-shallow public Read only

0
0
Text · 10.5 KiB · e6ee56b Raw
433 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* 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 information10 */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		else116			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 fw412		     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");433