⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttusb2.c

📁 trident tm5600的linux驱动
💻 C
字号:
/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones * (e.g. Pinnacle 400e DVB-S USB2.0). * * The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes. * * TDA8263 + TDA10086 * * I2C addresses: * 0x08 - LNBP21PD   - LNB power supply * 0x0e - TDA10086   - Demodulator * 0x50 - FX2 eeprom * 0x60 - TDA8263    - Tuner * 0x78 ??? * * Copyright (c) 2002 Holger Waechtler <holger@convergence.de> * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net> * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.org> * *	This program is free software; you can redistribute it and/or modify it *	under the terms of the GNU General Public License as published by the Free *	Software Foundation, version 2. * * see Documentation/dvb/README.dvb-usb for more information */#define DVB_USB_LOG_PREFIX "ttusb2"#include "dvb-usb.h"#include "ttusb2.h"#include "tda826x.h"#include "tda10086.h"#include "lnbp21.h"/* debug */static int dvb_usb_ttusb2_debug;#define deb_info(args...)   dprintk(dvb_usb_ttusb2_debug,0x01,args)module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644);MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS);DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);struct ttusb2_state {	u8 id;};static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,		u8 *wbuf, int wlen, u8 *rbuf, int rlen){	struct ttusb2_state *st = d->priv;	u8 s[wlen+4],r[64] = { 0 };	int ret = 0;	memset(s,0,wlen+4);	s[0] = 0xaa;	s[1] = ++st->id;	s[2] = cmd;	s[3] = wlen;	memcpy(&s[4],wbuf,wlen);	ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0);	if (ret  != 0 ||		r[0] != 0x55 ||		r[1] != s[1] ||		r[2] != cmd ||		(rlen > 0 && r[3] != rlen)) {		warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);		return -EIO;	}	if (rlen > 0)		memcpy(rbuf, &r[4], rlen);	return 0;}static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num){	struct dvb_usb_device *d = i2c_get_adapdata(adap);	static u8 obuf[60], ibuf[60];	int i,read;	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)		return -EAGAIN;	if (num > 2)		warn("more than 2 i2c messages at a time is not handled yet. TODO.");	for (i = 0; i < num; i++) {		read = i+1 < num && (msg[i+1].flags & I2C_M_RD);		obuf[0] = (msg[i].addr << 1) | read;		obuf[1] = msg[i].len;		/* read request */		if (read)			obuf[2] = msg[i+1].len;		else			obuf[2] = 0;		memcpy(&obuf[3],msg[i].buf,msg[i].len);		if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) {			err("i2c transfer failed.");			break;		}		if (read) {			memcpy(msg[i+1].buf,&ibuf[3],msg[i+1].len);			i++;		}	}	mutex_unlock(&d->i2c_mutex);	return i;}static u32 ttusb2_i2c_func(struct i2c_adapter *adapter){	return I2C_FUNC_I2C;}static struct i2c_algorithm ttusb2_i2c_algo = {	.master_xfer   = ttusb2_i2c_xfer,	.functionality = ttusb2_i2c_func,};/* Callbacks for DVB USB */static int ttusb2_identify_state (struct usb_device *udev, struct		dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,		int *cold){	*cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;	return 0;}static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff){	u8 b = onoff;	ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);	return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);}#if 0static int ttusb2_streaming_ctrl(struct dvb_usb_device *d, int onoff){	return 0;}#endifstatic struct tda10086_config tda10086_config = {	.demod_address = 0x0e,	.invert = 0,	.diseqc_tone = 1,	.xtal_freq = TDA10086_XTAL_16M,};static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap){	if (usb_set_interface(adap->dev->udev,0,3) < 0)		err("set interface to alts=3 failed");	if ((adap->fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) {		deb_info("TDA10086 attach failed\n");		return -ENODEV;	}	return 0;}static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap){	if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {		deb_info("TDA8263 attach failed\n");		return -ENODEV;	}	if (dvb_attach(lnbp21_attach, adap->fe, &adap->dev->i2c_adap, 0, 0) == NULL) {		deb_info("LNBP21 attach failed\n");		return -ENODEV;	}	return 0;}/* DVB USB Driver stuff */static struct dvb_usb_device_properties ttusb2_properties;static struct dvb_usb_device_properties ttusb2_properties_s2400;static int ttusb2_probe(struct usb_interface *intf,		const struct usb_device_id *id){	if (0 == dvb_usb_device_init(intf, &ttusb2_properties,				     THIS_MODULE, NULL, adapter_nr) ||	    0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,				     THIS_MODULE, NULL, adapter_nr))		return 0;	return -ENODEV;}static struct usb_device_id ttusb2_table [] = {	{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },	{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },	{ USB_DEVICE(USB_VID_TECHNOTREND,		USB_PID_TECHNOTREND_CONNECT_S2400) },	{}		/* Terminating entry */};MODULE_DEVICE_TABLE (usb, ttusb2_table);static struct dvb_usb_device_properties ttusb2_properties = {	.caps = DVB_USB_IS_AN_I2C_ADAPTER,	.usb_ctrl = CYPRESS_FX2,	.firmware = "dvb-usb-pctv-400e-01.fw",	.size_of_priv = sizeof(struct ttusb2_state),	.num_adapters = 1,	.adapter = {		{			.streaming_ctrl   = NULL, // ttusb2_streaming_ctrl,			.frontend_attach  = ttusb2_frontend_attach,			.tuner_attach     = ttusb2_tuner_attach,			/* parameter for the MPEG2-data transfer */			.stream = {				.type = USB_ISOC,				.count = 5,				.endpoint = 0x02,				.u = {					.isoc = {						.framesperurb = 4,						.framesize = 940,						.interval = 1,					}				}			}		}	},	.power_ctrl       = ttusb2_power_ctrl,	.identify_state   = ttusb2_identify_state,	.i2c_algo         = &ttusb2_i2c_algo,	.generic_bulk_ctrl_endpoint = 0x01,	.num_device_descs = 2,	.devices = {		{   "Pinnacle 400e DVB-S USB2.0",			{ &ttusb2_table[0], NULL },			{ NULL },		},		{   "Pinnacle 450e DVB-S USB2.0",			{ &ttusb2_table[1], NULL },			{ NULL },		},	}};static struct dvb_usb_device_properties ttusb2_properties_s2400 = {	.caps = DVB_USB_IS_AN_I2C_ADAPTER,	.usb_ctrl = CYPRESS_FX2,	.firmware = "dvb-usb-tt-s2400-01.fw",	.size_of_priv = sizeof(struct ttusb2_state),	.num_adapters = 1,	.adapter = {		{			.streaming_ctrl   = NULL,			.frontend_attach  = ttusb2_frontend_attach,			.tuner_attach     = ttusb2_tuner_attach,			/* parameter for the MPEG2-data transfer */			.stream = {				.type = USB_ISOC,				.count = 5,				.endpoint = 0x02,				.u = {					.isoc = {						.framesperurb = 4,						.framesize = 940,						.interval = 1,					}				}			}		}	},	.power_ctrl       = ttusb2_power_ctrl,	.identify_state   = ttusb2_identify_state,	.i2c_algo         = &ttusb2_i2c_algo,	.generic_bulk_ctrl_endpoint = 0x01,	.num_device_descs = 1,	.devices = {		{   "Technotrend TT-connect S-2400",			{ &ttusb2_table[2], NULL },			{ NULL },		},	}};static struct usb_driver ttusb2_driver = {	.name		= "dvb_usb_ttusb2",	.probe		= ttusb2_probe,	.disconnect = dvb_usb_device_exit,	.id_table	= ttusb2_table,};/* module stuff */static int __init ttusb2_module_init(void){	int result;	if ((result = usb_register(&ttusb2_driver))) {		err("usb_register failed. Error number %d",result);		return result;	}	return 0;}static void __exit ttusb2_module_exit(void){	/* deregister this driver from the USB subsystem */	usb_deregister(&ttusb2_driver);}module_init (ttusb2_module_init);module_exit (ttusb2_module_exit);MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");MODULE_VERSION("1.0");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -