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

📄 anysee.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver * * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> * *    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; either version 2 of the License, or *    (at your option) any later version. * *    This program is distributed in the hope that it will be useful, *    but WITHOUT ANY WARRANTY; without even the implied warranty of *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *    GNU General Public License for more details. * *    You should have received a copy of the GNU General Public License *    along with this program; if not, write to the Free Software *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * TODO: * - add smart card reader support for Conditional Access (CA) * * Card reader in Anysee is nothing more than ISO 7816 card reader. * There is no hardware CAM in any Anysee device sold. * In my understanding it should be implemented by making own module * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This * module registers serial interface that can be used to communicate * with any ISO 7816 smart card. * * Any help according to implement serial smart card reader support * is highly welcome! */#include "anysee.h"#include "tda1002x.h"#include "mt352.h"#include "mt352_priv.h"#include "zl10353.h"/* debug */static int dvb_usb_anysee_debug;module_param_named(debug, dvb_usb_anysee_debug, int, 0644);MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);int dvb_usb_anysee_delsys;module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644);MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);static struct mutex anysee_usb_mutex;static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,	u8 *rbuf, u8 rlen){	struct anysee_state *state = d->priv;	int act_len, ret;	u8 buf[64];	if (slen > sizeof(buf))		slen = sizeof(buf);	memcpy(&buf[0], sbuf, slen);	buf[60] = state->seq++;	if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)		return -EAGAIN;	/* We need receive one message more after dvb_usb_generic_rw due	   to weird transaction flow, which is 1 x send + 2 x receive. */	ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);	if (!ret) {		/* receive 2nd answer */		ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,			d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),			&act_len, 2000);		if (ret)			err("%s: recv bulk message failed: %d", __func__, ret);		else {			deb_xfer("<<< ");			debug_dump(buf, act_len, deb_xfer);		}	}	/* read request, copy returned data to return buf */	if (!ret && rbuf && rlen)		memcpy(rbuf, buf, rlen);	mutex_unlock(&anysee_usb_mutex);	return ret;}static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val){	u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};	int ret;	ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);	deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);	return ret;}static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val){	u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};	deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);	return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);}static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id){	u8 buf[] = {CMD_GET_HW_INFO};	return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);}static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff){	u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};	deb_info("%s: onoff:%02x\n", __func__, onoff);	return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);}static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval){	u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};	deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);	return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);}static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff){	u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};	deb_info("%s: onoff:%02x\n", __func__, onoff);	return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);}static int anysee_init(struct dvb_usb_device *d){	int ret;	/* LED light */	ret = anysee_led_ctrl(d, 0x01, 0x03);	if (ret)		return ret;	/* enable IR */	ret = anysee_ir_ctrl(d, 1);	if (ret)		return ret;	return 0;}/* I2C */static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,	int num){	struct dvb_usb_device *d = i2c_get_adapdata(adap);	int ret, inc, i = 0;	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)		return -EAGAIN;	while (i < num) {		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {			u8 buf[6];			buf[0] = CMD_I2C_READ;			buf[1] = msg[i].addr + 1;			buf[2] = msg[i].buf[0];			buf[3] = 0x00;			buf[4] = 0x00;			buf[5] = 0x01;			ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf,				msg[i+1].len);			inc = 2;		} else {			u8 buf[4+msg[i].len];			buf[0] = CMD_I2C_WRITE;			buf[1] = msg[i].addr;			buf[2] = msg[i].len;			buf[3] = 0x01;			memcpy(&buf[4], msg[i].buf, msg[i].len);			ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);			inc = 1;		}		if (ret)			break;		i += inc;	}	mutex_unlock(&d->i2c_mutex);	return ret ? ret : i;}static u32 anysee_i2c_func(struct i2c_adapter *adapter){	return I2C_FUNC_I2C;}static struct i2c_algorithm anysee_i2c_algo = {	.master_xfer   = anysee_master_xfer,	.functionality = anysee_i2c_func,};static int anysee_mt352_demod_init(struct dvb_frontend *fe){	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };	static u8 reset []         = { RESET,      0x80 };	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };	static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };	static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };	static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };	mt352_write(fe, clock_config,   sizeof(clock_config));	udelay(200);	mt352_write(fe, reset,          sizeof(reset));	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));	mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));	return 0;}/* Callbacks for DVB USB */static struct tda10023_config anysee_tda10023_config = {	.demod_address = 0x1a,	.invert = 0,	.xtal   = 16000000,	.pll_m  = 11,	.pll_p  = 3,	.pll_n  = 1,	.output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,	.deltaf = 0xfeeb,};static struct mt352_config anysee_mt352_config = {	.demod_address = 0x1e,	.demod_init    = anysee_mt352_demod_init,};static struct zl10353_config anysee_zl10353_config = {	.demod_address = 0x1e,	.parallel_ts = 1,};static int anysee_frontend_attach(struct dvb_usb_adapter *adap){	int ret;	struct anysee_state *state = adap->dev->priv;	u8 hw_info[3];	u8 io_d; /* IO port D */	/* check which hardware we have	   We must do this call two times to get reliable values (hw bug). */	ret = anysee_get_hw_info(adap->dev, hw_info);	if (ret)		return ret;	ret = anysee_get_hw_info(adap->dev, hw_info);	if (ret)		return ret;	/* Meaning of these info bytes are guessed. */	info("firmware version:%d.%d.%d hardware id:%d",		0, hw_info[1], hw_info[2], hw_info[0]);	ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */	if (ret)		return ret;	deb_info("%s: IO port D:%02x\n", __func__, io_d);	/* Select demod using trial and error method. */	/* Try to attach demodulator in following order:	      model      demod     hw  firmware	   1. E30        MT352     02  0.2.1	   2. E30        ZL10353   02  0.2.1	   3. E30 Combo  ZL10353   0f  0.1.2    DVB-T/C combo	   4. E30 Plus   ZL10353   06  0.1.0	   5. E30C Plus  TDA10023  0a  0.1.0    rev 0.2	      E30C Plus  TDA10023  0f  0.1.2    rev 0.4	      E30 Combo  TDA10023  0f  0.1.2    DVB-T/C combo	*/	/* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */	adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,			      &adap->dev->i2c_adap);

⌨️ 快捷键说明

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