From 776338e121b9db3156bfb4e21622a0219bbab9d4 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Thu, 23 Jun 2005 22:02:35 -0700 Subject: [PATCH] dvb: Add generalized dvb-usb driver Add generalized dvb-usb driver which supports a wide variety of devices. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/Kconfig | 99 +++++++++ drivers/media/dvb/dvb-usb/Makefile | 30 +++ drivers/media/dvb/dvb-usb/a800.c | 176 +++++++++++++++ drivers/media/dvb/dvb-usb/dibusb-common.c | 272 +++++++++++++++++++++++ drivers/media/dvb/dvb-usb/dibusb-mb.c | 316 +++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/dibusb-mc.c | 116 ++++++++++ drivers/media/dvb/dvb-usb/dibusb.h | 122 +++++++++++ drivers/media/dvb/dvb-usb/digitv.c | 282 ++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/digitv.h | 65 ++++++ drivers/media/dvb/dvb-usb/dtt200u-fe.c | 206 +++++++++++++++++ drivers/media/dvb/dvb-usb/dtt200u.c | 171 +++++++++++++++ drivers/media/dvb/dvb-usb/dtt200u.h | 66 ++++++ drivers/media/dvb/dvb-usb/dvb-usb-common.h | 44 ++++ drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | 210 ++++++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-firmware.c | 100 +++++++++ drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | 118 ++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 83 +++++++ drivers/media/dvb/dvb-usb/dvb-usb-init.c | 211 ++++++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 175 +++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-urb.c | 211 ++++++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb.h | 315 ++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/nova-t-usb2.c | 236 ++++++++++++++++++++ drivers/media/dvb/dvb-usb/umt-010.c | 162 ++++++++++++++ drivers/media/dvb/dvb-usb/vp7045-fe.c | 196 +++++++++++++++++ drivers/media/dvb/dvb-usb/vp7045.c | 263 ++++++++++++++++++++++ drivers/media/dvb/dvb-usb/vp7045.h | 78 +++++++ 26 files changed, 4323 insertions(+) create mode 100644 drivers/media/dvb/dvb-usb/Kconfig create mode 100644 drivers/media/dvb/dvb-usb/Makefile create mode 100644 drivers/media/dvb/dvb-usb/a800.c create mode 100644 drivers/media/dvb/dvb-usb/dibusb-common.c create mode 100644 drivers/media/dvb/dvb-usb/dibusb-mb.c create mode 100644 drivers/media/dvb/dvb-usb/dibusb-mc.c create mode 100644 drivers/media/dvb/dvb-usb/dibusb.h create mode 100644 drivers/media/dvb/dvb-usb/digitv.c create mode 100644 drivers/media/dvb/dvb-usb/digitv.h create mode 100644 drivers/media/dvb/dvb-usb/dtt200u-fe.c create mode 100644 drivers/media/dvb/dvb-usb/dtt200u.c create mode 100644 drivers/media/dvb/dvb-usb/dtt200u.h create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-common.h create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-dvb.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-firmware.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-i2c.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-ids.h create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-init.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-remote.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb-urb.c create mode 100644 drivers/media/dvb/dvb-usb/dvb-usb.h create mode 100644 drivers/media/dvb/dvb-usb/nova-t-usb2.c create mode 100644 drivers/media/dvb/dvb-usb/umt-010.c create mode 100644 drivers/media/dvb/dvb-usb/vp7045-fe.c create mode 100644 drivers/media/dvb/dvb-usb/vp7045.c create mode 100644 drivers/media/dvb/dvb-usb/vp7045.h (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig new file mode 100644 index 00000000000..8aa32f6e447 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -0,0 +1,99 @@ +config DVB_USB + tristate "Support for various USB DVB devices" + depends on DVB_CORE && USB + select FW_LOADER + help + By enabling this you will be able to choose the various USB 1.1 and + USB2.0 DVB devices. + + Almost every USB device needs a firmware, please look into + + + Say Y if you own an USB DVB device. + +config DVB_USB_DEBUG + bool "Enable extended debug support for all DVB-USB devices" + depends on DVB_USB + help + Say Y if you want to enable debuging. See modinfo dvb-usb (and the + appropriate drivers) for debug levels. + +config DVB_USB_A800 + tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" + depends on DVB_USB + help + Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. + +config DVB_USB_DIBUSB_MB + tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" + depends on DVB_USB + help + Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by + DiBcom () equipped with a DiB3000M-B demodulator. + + Devices supported by this driver: + TwinhanDTV USB-Ter (VP7041) + TwinhanDTV Magic Box (VP7041e) + KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0 + Hama DVB-T USB1.1-Box + DiBcom USB1.1 reference devices (non-public) + Ultima Electronic/Artec T1 USB TVBOX + Compro Videomate DVB-U2000 - DVB-T USB + Grandtec DVB-T USB + Avermedia AverTV DVBT USB1.1 + Artec T1 USB1.1 boxes + + The VP7041 seems to be identical to "CTS Portable" (Chinese + Television System). + + Say Y if you own such a device and want to use it. You should build it as + a module. + +config DVB_USB_DIBUSB_MC + tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" + depends on DVB_USB + help + Support for 2.0 DVB-T receivers based on reference designs made by + DiBcom () equipped with a DiB3000M-C/P demodulator. + + Devices supported by this driver: + DiBcom USB2.0 reference devices (non-public) + Artec T1 USB2.0 boxes + + Say Y if you own such a device and want to use it. You should build it as + a module. + +config DVB_USB_UMT_010 + tristate "HanfTek UMT-010 DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. + +config DVB_USB_DIGITV + tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver. + +config DVB_USB_VP7045 + tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the + TwinhanDTV Alpha (stick) (VP-7045), + TwinhanDTV MagicBox II (VP-7046) and + DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers. + +config DVB_USB_NOVA_T_USB2 + tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. + +config DVB_USB_DTT200U + tristate "Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support" + depends on DVB_USB + help + Say Y here to support the Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver. + + The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile new file mode 100644 index 00000000000..d65b50f9abb --- /dev/null +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -0,0 +1,30 @@ +dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o +obj-$(CONFIG_DVB_USB) += dvb-usb.o + +dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o +obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o + +dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o +obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o + +dvb-usb-dibusb-common-objs = dibusb-common.o + +dvb-usb-a800-objs = a800.o +obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o + +dvb-usb-dibusb-mb-objs = dibusb-mb.o +obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o + +dvb-usb-dibusb-mc-objs = dibusb-mc.o +obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o + +dvb-usb-nova-t-usb2-objs = nova-t-usb2.o +obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o + +dvb-usb-umt-010-objs = umt-010.o +obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o + +dvb-usb-digitv-objs = digitv.o +obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o + +EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c new file mode 100644 index 00000000000..a3542935604 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/a800.c @@ -0,0 +1,176 @@ +/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T + * USB2.0 (A800) DVB-T receiver. + * + * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) + * + * Thanks to + * - AVerMedia who kindly provided information and + * - Glen Harris who suffered from my mistakes during development. + * + * 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 + */ +#include "dibusb.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS); +#define deb_rc(args...) dprintk(debug,0x01,args) + +static int a800_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + /* do nothing for the AVerMedia */ + return 0; +} + +static struct dvb_usb_rc_key a800_rc_keys[] = { + { 0x02, 0x01, KEY_PROG1 }, /* SOURCE */ + { 0x02, 0x00, KEY_POWER }, /* POWER */ + { 0x02, 0x05, KEY_1 }, /* 1 */ + { 0x02, 0x06, KEY_2 }, /* 2 */ + { 0x02, 0x07, KEY_3 }, /* 3 */ + { 0x02, 0x09, KEY_4 }, /* 4 */ + { 0x02, 0x0a, KEY_5 }, /* 5 */ + { 0x02, 0x0b, KEY_6 }, /* 6 */ + { 0x02, 0x0d, KEY_7 }, /* 7 */ + { 0x02, 0x0e, KEY_8 }, /* 8 */ + { 0x02, 0x0f, KEY_9 }, /* 9 */ + { 0x02, 0x12, KEY_LEFT }, /* L / DISPLAY */ + { 0x02, 0x11, KEY_0 }, /* 0 */ + { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */ + { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */ + { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */ + { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */ + { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ + { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ + { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ + { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */ + { 0x02, 0x14, KEY_MUTE }, /* MUTE */ + { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */ + { 0x02, 0x19, KEY_RECORD }, /* RECORD */ + { 0x02, 0x18, KEY_PLAY }, /* PLAY */ + { 0x02, 0x1b, KEY_STOP }, /* STOP */ + { 0x02, 0x1a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */ + { 0x02, 0x1d, KEY_BACK }, /* << / RED */ + { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */ + { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */ + { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */ + { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */ + { 0x02, 0x04, KEY_EPG }, /* EPG */ + { 0x02, 0x15, KEY_MENU }, /* MENU */ +}; + +int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5]; + if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0), + 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5, + 2*HZ) != 5) + return -ENODEV; + + /* call the universal NEC remote processor, to find out the key's state and event */ + dvb_usb_nec_rc_key_to_event(d,key,event,state); + if (key[0] != 0) + deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); + return 0; +} + +/* USB Driver stuff */ +static struct dvb_usb_properties a800_properties; + +static int a800_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE); +} + +/* do not change the order of the ID table */ +static struct usb_device_id a800_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) }, +/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, a800_table); + +static struct dvb_usb_properties a800_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 32, + + .usb_ctrl = CYPRESS_FX2, + + .firmware = "dvb-usb-avertv-a800-02.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = a800_power_ctrl, + .frontend_attach = dibusb_dib3000mc_frontend_attach, + .tuner_attach = dibusb_dib3000mc_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = a800_rc_keys, + .rc_key_map_size = ARRAY_SIZE(a800_rc_keys), + .rc_query = a800_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 1, + .devices = { + { "AVerMedia AverTV DVB-T USB 2.0 (A800)", + { &a800_table[0], NULL }, + { &a800_table[1], NULL }, + }, + } +}; + +static struct usb_driver a800_driver = { + .owner = THIS_MODULE, + .name = "AVerMedia AverTV DVB-T USB 2.0 (A800)", + .probe = a800_probe, + .disconnect = dvb_usb_device_exit, + .id_table = a800_table, +}; + +/* module stuff */ +static int __init a800_module_init(void) +{ + int result; + if ((result = usb_register(&a800_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit a800_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&a800_driver); +} + +module_init (a800_module_init); +module_exit (a800_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c new file mode 100644 index 00000000000..63b626f70c8 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -0,0 +1,272 @@ +/* Common methods for dibusb-based-receivers. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * 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 + */ +#include "dibusb.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS); +MODULE_LICENSE("GPL"); + +#define deb_info(args...) dprintk(debug,0x01,args) + +/* common stuff used by the different dibusb modules */ +int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) +{ + if (d->priv != NULL) { + struct dib_fe_xfer_ops *ops = d->priv; + if (ops->fifo_ctrl != NULL) + if (ops->fifo_ctrl(d->fe,onoff)) { + err("error while controlling the fifo of the demod."); + return -ENODEV; + } + } + return 0; +} +EXPORT_SYMBOL(dibusb_streaming_ctrl); + +int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff) +{ + if (d->priv != NULL) { + struct dib_fe_xfer_ops *ops = d->priv; + if (d->pid_filtering && ops->pid_ctrl != NULL) + ops->pid_ctrl(d->fe,index,pid,onoff); + } + return 0; +} +EXPORT_SYMBOL(dibusb_pid_filter); + +int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff) +{ + if (d->priv != NULL) { + struct dib_fe_xfer_ops *ops = d->priv; + if (ops->pid_parse != NULL) + if (ops->pid_parse(d->fe,onoff) < 0) + err("could not handle pid_parser"); + } + return 0; +} +EXPORT_SYMBOL(dibusb_pid_filter_ctrl); + +int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 b[3]; + int ret; + b[0] = DIBUSB_REQ_SET_IOCTL; + b[1] = DIBUSB_IOCTL_CMD_POWER_MODE; + b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP; + ret = dvb_usb_generic_write(d,b,3); + msleep(10); + return ret; +} +EXPORT_SYMBOL(dibusb_power_ctrl); + +int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 b[2]; + b[0] = DIBUSB_REQ_SET_IOCTL; + b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM; + + dvb_usb_generic_write(d,b,3); + + return dibusb_streaming_ctrl(d,onoff); +} +EXPORT_SYMBOL(dibusb2_0_streaming_ctrl); + +int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + if (onoff) { + u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP }; + return dvb_usb_generic_write(d,b,3); + } else + return 0; +} +EXPORT_SYMBOL(dibusb2_0_power_ctrl); + +static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr, + u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) +{ + u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */ + /* write only ? */ + int wo = (rbuf == NULL || rlen == 0), + len = 2 + wlen + (wo ? 0 : 2); + + sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ; + sndbuf[1] = (addr << 1) | (wo ? 0 : 1); + + memcpy(&sndbuf[2],wbuf,wlen); + + if (!wo) { + sndbuf[wlen+2] = (rlen >> 8) & 0xff; + sndbuf[wlen+3] = rlen & 0xff; + } + + return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0); +} + +/* + * I2C master xfer function + */ +static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i; + + if (down_interruptible(&d->i2c_sem) < 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++) { + /* write/read request */ + if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len, + msg[i+1].buf,msg[i+1].len) < 0) + break; + i++; + } else + if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) + break; + } + + up(&d->i2c_sem); + return i; +} + +static u32 dibusb_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +struct i2c_algorithm dibusb_i2c_algo = { + .name = "DiBcom USB I2C algorithm", + .id = I2C_ALGO_BIT, + .master_xfer = dibusb_i2c_xfer, + .functionality = dibusb_i2c_func, +}; +EXPORT_SYMBOL(dibusb_i2c_algo); + +int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val) +{ + u8 wbuf[1] = { offs }; + return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1); +} +EXPORT_SYMBOL(dibusb_read_eeprom_byte); + +int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) +{ + struct dib3000_config demod_cfg; + struct dibusb_state *st = d->priv; + + demod_cfg.pll_set = dvb_usb_pll_set_i2c; + demod_cfg.pll_init = dvb_usb_pll_init_i2c; + + for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) + if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { + d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; + return 0; + } + + return -ENODEV; +} +EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach); + +int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d) +{ + d->pll_addr = 0x60; + d->pll_desc = &dvb_pll_env57h1xd5; + return 0; +} +EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); + +/* + * common remote control stuff + */ +struct dvb_usb_rc_key dibusb_rc_keys[] = { + /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */ + { 0x00, 0x16, KEY_POWER }, + { 0x00, 0x10, KEY_MUTE }, + { 0x00, 0x03, KEY_1 }, + { 0x00, 0x01, KEY_2 }, + { 0x00, 0x06, KEY_3 }, + { 0x00, 0x09, KEY_4 }, + { 0x00, 0x1d, KEY_5 }, + { 0x00, 0x1f, KEY_6 }, + { 0x00, 0x0d, KEY_7 }, + { 0x00, 0x19, KEY_8 }, + { 0x00, 0x1b, KEY_9 }, + { 0x00, 0x15, KEY_0 }, + { 0x00, 0x05, KEY_CHANNELUP }, + { 0x00, 0x02, KEY_CHANNELDOWN }, + { 0x00, 0x1e, KEY_VOLUMEUP }, + { 0x00, 0x0a, KEY_VOLUMEDOWN }, + { 0x00, 0x11, KEY_RECORD }, + { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */ + { 0x00, 0x14, KEY_PLAY }, + { 0x00, 0x1a, KEY_STOP }, + { 0x00, 0x40, KEY_REWIND }, + { 0x00, 0x12, KEY_FASTFORWARD }, + { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */ + { 0x00, 0x4c, KEY_PAUSE }, + { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */ + { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ + /* additional keys TwinHan VisionPlus, the Artec seemingly not have */ + { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */ + { 0x00, 0x1c, KEY_EPG }, /* EPG */ + { 0x00, 0x00, KEY_TAB }, /* Tab */ + { 0x00, 0x48, KEY_INFO }, /* Preview */ + { 0x00, 0x04, KEY_LIST }, /* RecordList */ + { 0x00, 0x0f, KEY_TEXT }, /* Teletext */ + /* Key codes for the KWorld/ADSTech/JetWay remote. */ + { 0x86, 0x12, KEY_POWER }, + { 0x86, 0x0f, KEY_SELECT }, /* source */ + { 0x86, 0x0c, KEY_UNKNOWN }, /* scan */ + { 0x86, 0x0b, KEY_EPG }, + { 0x86, 0x10, KEY_MUTE }, + { 0x86, 0x01, KEY_1 }, + { 0x86, 0x02, KEY_2 }, + { 0x86, 0x03, KEY_3 }, + { 0x86, 0x04, KEY_4 }, + { 0x86, 0x05, KEY_5 }, + { 0x86, 0x06, KEY_6 }, + { 0x86, 0x07, KEY_7 }, + { 0x86, 0x08, KEY_8 }, + { 0x86, 0x09, KEY_9 }, + { 0x86, 0x0a, KEY_0 }, + { 0x86, 0x18, KEY_ZOOM }, + { 0x86, 0x1c, KEY_UNKNOWN }, /* preview */ + { 0x86, 0x13, KEY_UNKNOWN }, /* snap */ + { 0x86, 0x00, KEY_UNDO }, + { 0x86, 0x1d, KEY_RECORD }, + { 0x86, 0x0d, KEY_STOP }, + { 0x86, 0x0e, KEY_PAUSE }, + { 0x86, 0x16, KEY_PLAY }, + { 0x86, 0x11, KEY_BACK }, + { 0x86, 0x19, KEY_FORWARD }, + { 0x86, 0x14, KEY_UNKNOWN }, /* pip */ + { 0x86, 0x15, KEY_ESC }, + { 0x86, 0x1a, KEY_UP }, + { 0x86, 0x1e, KEY_DOWN }, + { 0x86, 0x1f, KEY_LEFT }, + { 0x86, 0x1b, KEY_RIGHT }, +}; +EXPORT_SYMBOL(dibusb_rc_keys); + +int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE; + dvb_usb_generic_rw(d,&cmd,1,key,5,0); + dvb_usb_nec_rc_key_to_event(d,key,event,state); + if (key[0] != 0) + deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); + return 0; +} +EXPORT_SYMBOL(dibusb_rc_query); diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c new file mode 100644 index 00000000000..fd103e4746e --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -0,0 +1,316 @@ +/* DVB USB compliant linux driver for mobile DVB-T USB devices based on + * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B) + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * based on GPL code from DiBcom, which has + * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) + * + * 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 + */ +#include "dibusb.h" + +static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) +{ + struct dib3000_config demod_cfg; + struct dibusb_state *st = d->priv; + + demod_cfg.demod_address = 0x8; + demod_cfg.pll_set = dvb_usb_pll_set_i2c; + demod_cfg.pll_init = dvb_usb_pll_init_i2c; + + if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) + return -ENODEV; + + d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; + + return 0; +} + +/* some of the dibusb 1.1 device aren't equipped with the default tuner + * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures + * this out. */ +static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d) +{ + u8 b[2] = { 0,0 }, b2[1]; + int ret = 0; + struct i2c_msg msg[2] = { + { .flags = 0, .buf = b, .len = 2 }, + { .flags = I2C_M_RD, .buf = b2, .len = 1 }, + }; + + /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */ + msg[0].addr = msg[1].addr = 0x60; + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(d->fe,1,msg[0].addr); + + if (i2c_transfer (&d->i2c_adap, msg, 2) != 2) { + err("tuner i2c write failed."); + ret = -EREMOTEIO; + } + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(d->fe,0,msg[0].addr); + + if (b2[0] == 0xfe) { + info("this device has the Thomson Cable onboard. Which is default."); + d->pll_addr = 0x61; + d->pll_desc = &dvb_pll_tua6010xs; + } else { + u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; + info("this device has the Panasonic ENV77H11D5 onboard."); + d->pll_addr = 0x60; + memcpy(d->pll_init,bpll,4); + d->pll_desc = &dvb_pll_tda665x; + } + + return ret; +} + +/* USB Driver stuff */ +static struct dvb_usb_properties dibusb1_1_properties; +static struct dvb_usb_properties dibusb1_1_an2235_properties; +static struct dvb_usb_properties dibusb2_0b_properties; + +static int dibusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 || + dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) || + dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0) + return 0; + + return -EINVAL; +} + +/* do not change the order of the ID table */ +static struct usb_device_id dibusb_dib3000mb_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, +/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, +/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, +/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, +/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, +/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, +/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, +/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, +/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, +/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, +/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, +/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, +/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) }, +/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) }, +/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) }, +/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) }, +/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, +/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, +/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, +/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, +/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, +/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, +/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, +/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, +/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); + +static struct dvb_usb_properties dibusb1_1_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 16, + + .usb_ctrl = CYPRESS_AN2135, + + .firmware = "dvb-usb-dibusb-5.0.0.11.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb_power_ctrl, + .frontend_attach = dibusb_dib3000mb_frontend_attach, + .tuner_attach = dibusb_dib3000mb_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dibusb_rc_keys, + .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 8, + .devices = { + { "AVerMedia AverTV DVBT USB1.1", + { &dibusb_dib3000mb_table[0], NULL }, + { &dibusb_dib3000mb_table[1], NULL }, + }, + { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)", + { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL}, + { &dibusb_dib3000mb_table[3], NULL }, + }, + { "DiBcom USB1.1 DVB-T reference design (MOD3000)", + { &dibusb_dib3000mb_table[5], NULL }, + { &dibusb_dib3000mb_table[6], NULL }, + }, + { "KWorld V-Stream XPERT DTV - DVB-T USB1.1", + { &dibusb_dib3000mb_table[7], NULL }, + { &dibusb_dib3000mb_table[8], NULL }, + }, + { "Grandtec USB1.1 DVB-T", + { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL }, + { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL }, + }, + { "Unkown USB1.1 DVB-T device ???? please report the name to the author", + { &dibusb_dib3000mb_table[13], NULL }, + { &dibusb_dib3000mb_table[14], NULL }, + }, + { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device", + { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL}, + { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL}, + }, + { "Artec T1 USB1.1 TVBOX with AN2135", + { &dibusb_dib3000mb_table[19], NULL }, + { &dibusb_dib3000mb_table[20], NULL }, + }, + } +}; + +static struct dvb_usb_properties dibusb1_1_an2235_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = CYPRESS_AN2235, + + .firmware = "dvb-usb-dibusb-an2235-01.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb_power_ctrl, + .frontend_attach = dibusb_dib3000mb_frontend_attach, + .tuner_attach = dibusb_dib3000mb_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dibusb_rc_keys, + .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 1, + .devices = { + { "Artec T1 USB1.1 TVBOX with AN2235", + { &dibusb_dib3000mb_table[20], NULL }, + { &dibusb_dib3000mb_table[21], NULL }, + }, + } +}; + +static struct dvb_usb_properties dibusb2_0b_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = CYPRESS_FX2, + + .firmware = "dvb-usb-adstech-usb2-01.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb2_0_power_ctrl, + .frontend_attach = dibusb_dib3000mb_frontend_attach, + .tuner_attach = dibusb_dib3000mb_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dibusb_rc_keys, + .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ + .rc_query = dibusb_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 2, + .devices = { + { "KWorld/ADSTech Instant DVB-T USB 2.0", + { &dibusb_dib3000mb_table[23], NULL }, + { &dibusb_dib3000mb_table[24], NULL }, /* device ID with default DIBUSB2_0-firmware */ + }, + } +}; + +static struct usb_driver dibusb_driver = { + .owner = THIS_MODULE, + .name = "DiBcom based USB DVB-T devices (DiB3000M-B based)", + .probe = dibusb_probe, + .disconnect = dvb_usb_device_exit, + .id_table = dibusb_dib3000mb_table, +}; + +/* module stuff */ +static int __init dibusb_module_init(void) +{ + int result; + if ((result = usb_register(&dibusb_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit dibusb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&dibusb_driver); +} + +module_init (dibusb_module_init); +module_exit (dibusb_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c new file mode 100644 index 00000000000..aad8ed3fe00 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c @@ -0,0 +1,116 @@ +/* DVB USB compliant linux driver for mobile DVB-T USB devices based on + * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P) + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * based on GPL code from DiBcom, which has + * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) + * + * 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 + */ +#include "dibusb.h" + +/* USB Driver stuff */ +static struct dvb_usb_properties dibusb_mc_properties; + +static int dibusb_mc_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE); +} + +/* do not change the order of the ID table */ +static struct usb_device_id dibusb_dib3000mc_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) }, +/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) }, +/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table); + +static struct dvb_usb_properties dibusb_mc_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 32, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-dibusb-6.0.0.8.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb2_0_power_ctrl, + .frontend_attach = dibusb_dib3000mc_frontend_attach, + .tuner_attach = dibusb_dib3000mc_tuner_attach, + + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dibusb_rc_keys, + .rc_key_map_size = 63, /* FIXME */ + .rc_query = dibusb_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 2, + .devices = { + { "DiBcom USB2.0 DVB-T reference design (MOD3000P)", + { &dibusb_dib3000mc_table[0], NULL }, + { &dibusb_dib3000mc_table[1], NULL }, + }, + { "Artec T1 USB2.0 TVBOX (please report the warm ID)", + { &dibusb_dib3000mc_table[2], NULL }, + { NULL }, + }, + } +}; + +static struct usb_driver dibusb_mc_driver = { + .owner = THIS_MODULE, + .name = "DiBcom based USB2.0 DVB-T (DiB3000M-C/P based) devices", + .probe = dibusb_mc_probe, + .disconnect = dvb_usb_device_exit, + .id_table = dibusb_dib3000mc_table, +}; + +/* module stuff */ +static int __init dibusb_mc_module_init(void) +{ + int result; + if ((result = usb_register(&dibusb_mc_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit dibusb_mc_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&dibusb_mc_driver); +} + +module_init (dibusb_mc_module_init); +module_exit (dibusb_mc_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h new file mode 100644 index 00000000000..6611f62977c --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dibusb.h @@ -0,0 +1,122 @@ +/* Header file for all dibusb-based-receivers. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * 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 + */ +#ifndef _DVB_USB_DIBUSB_H_ +#define _DVB_USB_DIBUSB_H_ + +#define DVB_USB_LOG_PREFIX "dibusb" +#include "dvb-usb.h" + +#include "dib3000.h" + +/* + * protocol of all dibusb related devices + */ + +/* + * bulk msg to/from endpoint 0x01 + * + * general structure: + * request_byte parameter_bytes + */ + +#define DIBUSB_REQ_START_READ 0x00 +#define DIBUSB_REQ_START_DEMOD 0x01 + +/* + * i2c read + * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word + * bulk read: byte_buffer (length_word bytes) + */ +#define DIBUSB_REQ_I2C_READ 0x02 + +/* + * i2c write + * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes + */ +#define DIBUSB_REQ_I2C_WRITE 0x03 + +/* + * polling the value of the remote control + * bulk write: 0x04 + * bulk read: byte_buffer (5 bytes) + */ +#define DIBUSB_REQ_POLL_REMOTE 0x04 + +/* additional status values for Hauppauge Remote Control Protocol */ +#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01 +#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03 + +/* streaming mode: + * bulk write: 0x05 mode_byte + * + * mode_byte is mostly 0x00 + */ +#define DIBUSB_REQ_SET_STREAMING_MODE 0x05 + +/* interrupt the internal read loop, when blocking */ +#define DIBUSB_REQ_INTR_READ 0x06 + +/* io control + * 0x07 cmd_byte param_bytes + * + * param_bytes can be up to 32 bytes + * + * cmd_byte function parameter name + * 0x00 power mode + * 0x00 sleep + * 0x01 wakeup + * + * 0x01 enable streaming + * 0x02 disable streaming + * + * + */ +#define DIBUSB_REQ_SET_IOCTL 0x07 + +/* IOCTL commands */ + +/* change the power mode in firmware */ +#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00 +#define DIBUSB_IOCTL_POWER_SLEEP 0x00 +#define DIBUSB_IOCTL_POWER_WAKEUP 0x01 + +/* modify streaming of the FX2 */ +#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01 +#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02 + +struct dibusb_state { + struct dib_fe_xfer_ops ops; + + /* for RC5 remote control */ + int old_toggle; + int last_repeat_count; +}; + +extern struct i2c_algorithm dibusb_i2c_algo; + +extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *); +extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *); + +extern int dibusb_streaming_ctrl(struct dvb_usb_device *, int); +extern int dibusb_pid_filter(struct dvb_usb_device *, int, u16, int); +extern int dibusb_pid_filter_ctrl(struct dvb_usb_device *, int); +extern int dibusb_power_ctrl(struct dvb_usb_device *, int); +extern int dibusb2_0_streaming_ctrl(struct dvb_usb_device *, int); +extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int); + +#define DEFAULT_RC_INTERVAL 150 +//#define DEFAULT_RC_INTERVAL 100000 + +extern struct dvb_usb_rc_key dibusb_rc_keys[]; +extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *); +extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *); + +#endif diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c new file mode 100644 index 00000000000..5acf3fde952 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -0,0 +1,282 @@ +/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0 + * receiver + * + * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) and + * Allan Third (allan.third@cs.man.ac.uk) + * + * partly based on the SDK published by Nebula Electronics (TODO do we want this line ?) + * + * 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 + */ +#include "digitv.h" + +#include "mt352.h" +#include "nxt6000.h" + +/* debug */ +int dvb_usb_digitv_debug; +module_param_named(debug,dvb_usb_digitv_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); + +static int digitv_ctrl_msg(struct dvb_usb_device *d, + u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen) +{ + int wo = (rbuf == NULL || rlen == 0); /* write-only */ + u8 sndbuf[7],rcvbuf[7]; + memset(sndbuf,0,7); memset(rcvbuf,0,7); + + sndbuf[0] = cmd; + sndbuf[1] = vv; + sndbuf[2] = wo ? wlen : rlen; + + if (!wo) { + memcpy(&sndbuf[3],wbuf,wlen); + dvb_usb_generic_write(d,sndbuf,7); + } else { + dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10); + memcpy(&rbuf,&rcvbuf[3],rlen); + } + return 0; +} + +/* I2C */ +static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i; + + if (down_interruptible(&d->i2c_sem) < 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++) { + /* write/read request */ + if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0, + msg[i+1].buf,msg[i+1].len) < 0) + break; + i++; + } else + if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0], + &msg[i].buf[1],msg[i].len-1,NULL,0) < 0) + break; + } + + up(&d->i2c_sem); + return i; +} + +static u32 digitv_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm digitv_i2c_algo = { + .name = "Nebula DigiTV USB I2C algorithm", + .id = I2C_ALGO_BIT, + .master_xfer = digitv_i2c_xfer, + .functionality = digitv_i2c_func, +}; + +/* Callbacks for DVB USB */ +static int digitv_identify_state (struct usb_device *udev, struct + dvb_usb_properties *props, struct dvb_usb_device_description **desc, + int *cold) +{ + *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0; + return 0; +} + +static int digitv_mt352_demod_init(struct dvb_frontend *fe) +{ + static u8 mt352_clock_config[] = { 0x89, 0x38, 0x2d }; + static u8 mt352_reset[] = { 0x50, 0x80 }; + static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 }; + + static u8 mt352_agc_cfg[] = { 0x68, 0xa0 }; + static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0xa0 }; + static u8 mt352_acq_ctl[] = { 0x53, 0x50 }; + static u8 mt352_agc_target[] = { 0x67, 0x20 }; + + static u8 mt352_rs_err_per[] = { 0x7c, 0x00, 0x01 }; + static u8 mt352_snr_select[] = { 0x79, 0x00, 0x20 }; + + static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x05 }; + + static u8 mt352_scan_ctl[] = { 0x88, 0x0f }; + static u8 mt352_capt_range[] = { 0x75, 0x32 }; + + mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); + mt352_write(fe, mt352_reset, sizeof(mt352_reset)); + msleep(1); + mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio)); + + mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); + mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); + mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl)); + mt352_write(fe, mt352_agc_target, sizeof(mt352_agc_target)); + + + mt352_write(fe, mt352_rs_err_per, sizeof(mt352_rs_err_per)); + mt352_write(fe, mt352_snr_select, sizeof(mt352_snr_select)); + + mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1)); + + mt352_write(fe, mt352_scan_ctl, sizeof(mt352_scan_ctl)); + mt352_write(fe, mt352_capt_range, sizeof(mt352_capt_range)); + + return 0; +} + +static struct mt352_config digitv_mt352_config = { + .demod_address = 0x0, /* ignored by the digitv anyway */ + .demod_init = digitv_mt352_demod_init, + .pll_set = NULL, /* TODO */ +}; + +static struct nxt6000_config digitv_nxt6000_config = { + .demod_address = 0x0, /* ignored by the digitv anyway */ + .clock_inversion = 0x0, + + .pll_init = NULL, + .pll_set = NULL, +}; + +static int digitv_frontend_attach(struct dvb_usb_device *d) +{ + if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) == NULL) + return 0; + if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) == NULL) { + + warn("nxt6000 support is not done yet, in fact you are one of the first " + "person who wants to use this device in Linux. Please report to " + "linux-dvb@linuxtv.org"); + + return 0; + } + return -EIO; +} + +static struct dvb_usb_rc_key digitv_rc_keys[] = { + { 0x00, 0x16, KEY_POWER }, /* dummy key */ +}; + +/* TODO is it really the NEC protocol ? */ +int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5]; + + digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4); + /* TODO state, maybe it is VV ? */ + if (key[1] != 0) + key[0] = 0x01; /* if something is inside the buffer, simulate key press */ + + /* call the universal NEC remote processor, to find out the key's state and event */ + dvb_usb_nec_rc_key_to_event(d,key,event,state); + if (key[0] != 0) + deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); + return 0; +} + + +/* DVB USB Driver stuff */ +static struct dvb_usb_properties digitv_properties; + +static int digitv_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE); +} + +static struct usb_device_id digitv_table [] = { + { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, digitv_table); + +static struct dvb_usb_properties digitv_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-digitv-01.fw", + + .size_of_priv = 0, + + .streaming_ctrl = NULL, + .pid_filter = NULL, + .pid_filter_ctrl = NULL, + .power_ctrl = NULL, + .frontend_attach = digitv_frontend_attach, + .tuner_attach = NULL, // digitv_tuner_attach, + .read_mac_address = NULL, + + .rc_interval = 1000, + .rc_key_map = digitv_rc_keys, + .rc_key_map_size = ARRAY_SIZE(digitv_rc_keys), + .rc_query = digitv_rc_query, + + .identify_state = digitv_identify_state, + + .i2c_algo = &digitv_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 2, + .devices = { + { "Nebula Electronics uDigiTV DVB-T USB2.0)", + { &digitv_table[0], NULL }, + { NULL }, + }, + } +}; + +static struct usb_driver digitv_driver = { + .owner = THIS_MODULE, + .name = "Nebula Electronics uDigiTV DVB-T USB2.0 device", + .probe = digitv_probe, + .disconnect = dvb_usb_device_exit, + .id_table = digitv_table, +}; + +/* module stuff */ +static int __init digitv_module_init(void) +{ + int result; + if ((result = usb_register(&digitv_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit digitv_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&digitv_driver); +} + +module_init (digitv_module_init); +module_exit (digitv_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0"); +MODULE_VERSION("1.0-alpha"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h new file mode 100644 index 00000000000..477ee428a70 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/digitv.h @@ -0,0 +1,65 @@ +#ifndef _DVB_USB_DIGITV_H_ +#define _DVB_USB_DIGITV_H_ + +#define DVB_USB_LOG_PREFIX "digitv" +#include "dvb-usb.h" + +extern int dvb_usb_digitv_debug; +#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args) + +/* protocol (from usblogging and the SDK: + * + * Always 7 bytes bulk message(s) for controlling + * + * First byte describes the command. Reads are 2 consecutive transfer (as always). + * + * General structure: + * + * write or first message of a read: + * VV B0 B1 B2 B3 + * + * second message of a read + * VV R0 R1 R2 R3 + * + * whereas 0 < len <= 4 + * + * I2C address is stored somewhere inside the device. + * + * 0x01 read from EEPROM + * VV = offset; B* = 0; R* = value(s) + * + * 0x02 read register of the COFDM + * VV = register; B* = 0; R* = value(s) + * + * 0x05 write register of the COFDM + * VV = register; B* = value(s); + * + * 0x06 write to the tuner (only for NXT6000) + * VV = 0; B* = PLL data; len = 4; + * + * 0x03 read remote control + * VV = 0; B* = 0; len = 4; R* = key + * + * 0x07 write to the remote (don't know why one should this, resetting ?) + * VV = 0; B* = key; len = 4; + * + * 0x08 write remote type + * VV = 0; B[0] = 0x01, len = 4 + * + * 0x09 write device init + * TODO + */ +#define USB_READ_EEPROM 1 + +#define USB_READ_COFDM 2 +#define USB_WRITE_COFDM 5 + +#define USB_WRITE_TUNER 6 + +#define USB_READ_REMOTE 3 +#define USB_WRITE_REMOTE 7 +#define USB_WRITE_REMOTE_TYPE 8 + +#define USB_DEV_INIT 9 + +#endif diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c new file mode 100644 index 00000000000..d17d768038c --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c @@ -0,0 +1,206 @@ +/* Frontend part of the Linux driver for the Yakumo/Hama/Typhoon DVB-T + * USB2.0 receiver. + * + * Copyright (C) 2005 Patrick Boettcher + * + * 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 + */ +#include "dtt200u.h" + +struct dtt200u_fe_state { + struct dvb_usb_device *d; + + struct dvb_frontend_parameters fep; + struct dvb_frontend frontend; +}; + +#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what) + +static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_TUNE_STAT; + u8 br[3] = { 0 }; +// u8 bdeb[5] = { 0 }; + + dvb_usb_generic_rw(state->d,&bw,1,br,3,0); + switch (br[0]) { + case 0x01: + *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + break; + case 0x00: + *stat = 0; + break; + default: + moan("br[0]",GET_TUNE_STAT); + break; + } + +// bw[0] = 0x88; +// dvb_usb_generic_rw(state->d,bw,1,bdeb,5,0); + +// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]); + + return 0; +} +static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_BER; + *ber = 0; + dvb_usb_generic_rw(state->d,&bw,1,(u8*) ber,3,0); + return 0; +} + +static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_UNK; + *unc = 0; + dvb_usb_generic_rw(state->d,&bw,1,(u8*) unc,3,0); + return 0; +} + +static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_SIG_STRENGTH, b; + dvb_usb_generic_rw(state->d,&bw,1,&b,1,0); + *strength = (b << 8) | b; + return 0; +} + +static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 bw = GET_SNR,br; + dvb_usb_generic_rw(state->d,&bw,1,&br,1,0); + *snr = ~((br << 8) | br); + return 0; +} + +static int dtt200u_fe_init(struct dvb_frontend* fe) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u8 b = RESET_DEMOD; + return dvb_usb_generic_write(state->d,&b,1); +} + +static int dtt200u_fe_sleep(struct dvb_frontend* fe) +{ + return dtt200u_fe_init(fe); +} + +static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) +{ + tune->min_delay_ms = 1500; + tune->step_size = 166667; + tune->max_drift = 166667 * 2; + return 0; +} + +static int dtt200u_fe_set_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + u16 freq = fep->frequency / 250000; + u8 bw,bwbuf[2] = { SET_BANDWIDTH, 0 }, freqbuf[3] = { SET_FREQUENCY, 0, 0 }; + + switch (fep->u.ofdm.bandwidth) { + case BANDWIDTH_8_MHZ: bw = 8; break; + case BANDWIDTH_7_MHZ: bw = 7; break; + case BANDWIDTH_6_MHZ: bw = 6; break; + case BANDWIDTH_AUTO: return -EOPNOTSUPP; + default: + return -EINVAL; + } + deb_info("set_frontend\n"); + + bwbuf[1] = bw; + dvb_usb_generic_write(state->d,bwbuf,2); + + freqbuf[1] = freq & 0xff; + freqbuf[2] = (freq >> 8) & 0xff; + dvb_usb_generic_write(state->d,freqbuf,3); + + memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters)); + + return 0; +} + +static int dtt200u_fe_get_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + struct dtt200u_fe_state *state = fe->demodulator_priv; + memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters)); + return 0; +} + +static void dtt200u_fe_release(struct dvb_frontend* fe) +{ + struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops dtt200u_fe_ops; + +struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d) +{ + struct dtt200u_fe_state* state = NULL; + + /* allocate memory for the internal state */ + state = (struct dtt200u_fe_state*) kmalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL); + if (state == NULL) + goto error; + memset(state,0,sizeof(struct dtt200u_fe_state)); + + deb_info("attaching frontend dtt200u\n"); + + state->d = d; + + state->frontend.ops = &dtt200u_fe_ops; + state->frontend.demodulator_priv = state; + + goto success; +error: + return NULL; +success: + return &state->frontend; +} + +static struct dvb_frontend_ops dtt200u_fe_ops = { + .info = { + .name = "DTT200U (Yakumo/Typhoon/Hama) DVB-T", + .type = FE_OFDM, + .frequency_min = 44250000, + .frequency_max = 867250000, + .frequency_stepsize = 250000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | + FE_CAN_HIERARCHY_AUTO, + }, + + .release = dtt200u_fe_release, + + .init = dtt200u_fe_init, + .sleep = dtt200u_fe_sleep, + + .set_frontend = dtt200u_fe_set_frontend, + .get_frontend = dtt200u_fe_get_frontend, + .get_tune_settings = dtt200u_fe_get_tune_settings, + + .read_status = dtt200u_fe_read_status, + .read_ber = dtt200u_fe_read_ber, + .read_signal_strength = dtt200u_fe_read_signal_strength, + .read_snr = dtt200u_fe_read_snr, + .read_ucblocks = dtt200u_fe_read_unc_blocks, +}; diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c new file mode 100644 index 00000000000..fb2b5a2da13 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dtt200u.c @@ -0,0 +1,171 @@ +/* DVB USB library compliant Linux driver for the Yakumo/Hama/Typhoon DVB-T + * USB2.0 receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * 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 + */ +#include "dtt200u.h" + +/* debug */ +int dvb_usb_dtt200u_debug; +module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS); + +static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 b_streaming[2] = { SET_TS_CTRL, onoff }; + u8 b_rst_pid = RESET_PID_FILTER; + + dvb_usb_generic_write(d,b_streaming,2); + + if (!onoff) + dvb_usb_generic_write(d,&b_rst_pid,1); + return 0; +} + +static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff) +{ + u8 b_pid[4]; + pid = onoff ? pid : 0; + + b_pid[0] = SET_PID_FILTER; + b_pid[1] = index; + b_pid[2] = pid & 0xff; + b_pid[3] = (pid >> 8) & 0xff; + + return dvb_usb_generic_write(d,b_pid,4); +} + +/* remote control */ +/* key list for the tiny remote control (Yakumo, don't know about the others) */ +static struct dvb_usb_rc_key dtt200u_rc_keys[] = { + { 0x80, 0x01, KEY_MUTE }, + { 0x80, 0x02, KEY_CHANNELDOWN }, + { 0x80, 0x03, KEY_VOLUMEDOWN }, + { 0x80, 0x04, KEY_1 }, + { 0x80, 0x05, KEY_2 }, + { 0x80, 0x06, KEY_3 }, + { 0x80, 0x07, KEY_4 }, + { 0x80, 0x08, KEY_5 }, + { 0x80, 0x09, KEY_6 }, + { 0x80, 0x0a, KEY_7 }, + { 0x00, 0x0c, KEY_ZOOM }, + { 0x80, 0x0d, KEY_0 }, + { 0x00, 0x0e, KEY_SELECT }, + { 0x80, 0x12, KEY_POWER }, + { 0x80, 0x1a, KEY_CHANNELUP }, + { 0x80, 0x1b, KEY_8 }, + { 0x80, 0x1e, KEY_VOLUMEUP }, + { 0x80, 0x1f, KEY_9 }, +}; + +static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5],cmd = GET_RC_KEY; + dvb_usb_generic_rw(d,&cmd,1,key,5,0); + dvb_usb_nec_rc_key_to_event(d,key,event,state); + if (key[0] != 0) + deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); + return 0; +} + +static int dtt200u_frontend_attach(struct dvb_usb_device *d) +{ + d->fe = dtt200u_fe_attach(d); + return 0; +} + +static struct dvb_usb_properties dtt200u_properties; + +static int dtt200u_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE); +} + +static struct usb_device_id dtt200u_usb_table [] = { + { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_COLD) }, + { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_WARM) }, + { 0 }, +}; +MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); + +static struct dvb_usb_properties dtt200u_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING, + .pid_filter_count = 255, /* It is a guess, but there are at least 10 */ + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-dtt200u-01.fw", + + .streaming_ctrl = dtt200u_streaming_ctrl, + .pid_filter = dtt200u_pid_filter, + .frontend_attach = dtt200u_frontend_attach, + + .rc_interval = 200, + .rc_key_map = dtt200u_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), + .rc_query = dtt200u_rc_query, + + .generic_bulk_ctrl_endpoint = 0x01, + + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 1, + .devices = { + { .name = "Yakumo/Hama/Typhoon DVB-T USB2.0)", + .cold_ids = { &dtt200u_usb_table[0], &dtt200u_usb_table[2] }, + .warm_ids = { &dtt200u_usb_table[1], NULL }, + }, + { 0 }, + } +}; + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver dtt200u_usb_driver = { + .owner = THIS_MODULE, + .name = "Yakumo/Hama/Typhoon DVB-T USB2.0", + .probe = dtt200u_usb_probe, + .disconnect = dvb_usb_device_exit, + .id_table = dtt200u_usb_table, +}; + +/* module stuff */ +static int __init dtt200u_usb_module_init(void) +{ + int result; + if ((result = usb_register(&dtt200u_usb_driver))) { + err("usb_register failed. (%d)",result); + return result; + } + + return 0; +} + +static void __exit dtt200u_usb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&dtt200u_usb_driver); +} + +module_init(dtt200u_usb_module_init); +module_exit(dtt200u_usb_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for the Yakumo/Hama/Typhoon DVB-T USB2.0 device"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h new file mode 100644 index 00000000000..ed414207151 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dtt200u.h @@ -0,0 +1,66 @@ +/* Common header file of Linux driver for the Yakumo/Hama/Typhoon DVB-T + * USB2.0 receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * 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 + */ +#ifndef _DVB_USB_DTT200U_H_ +#define _DVB_USB_DTT200U_H_ + +#define DVB_USB_LOG_PREFIX "dtt200u" +#include "dvb-usb.h" + +extern int dvb_usb_dtt200u_debug; +#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args) +#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args) + +/* guessed protocol description (reverse engineered): + * read + * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1 + * 81 - + * 82 - crash - do not touch + * 83 - crash - do not touch + * 84 - remote control + * 85 - crash - do not touch (OK, stop testing here) + * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) + * 89 - noise-to-signal + * 8a - unkown 1 byte - signal_strength + * 8c - ber ??? + * 8d - ber + * 8e - unc + */ + +#define GET_SPEED 0x00 +#define GET_TUNE_STAT 0x81 +#define GET_RC_KEY 0x84 +#define GET_STATUS 0x88 +#define GET_SNR 0x89 +#define GET_SIG_STRENGTH 0x8a +#define GET_UNK 0x8c +#define GET_BER 0x8d +#define GET_UNC 0x8e + +/* write + * 01 - reset the demod + * 02 - frequency (divided by 250000) + * 03 - bandwidth + * 04 - pid table (index pid(7:0) pid(12:8)) + * 05 - reset the pid table + * 08 - demod transfer enabled or not (FX2 transfer is enabled by default) + */ + +#define RESET_DEMOD 0x01 +#define SET_FREQUENCY 0x02 +#define SET_BANDWIDTH 0x03 +#define SET_PID_FILTER 0x04 +#define RESET_PID_FILTER 0x05 +#define SET_TS_CTRL 0x08 + +extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); + +#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h new file mode 100644 index 00000000000..67e0d73fbce --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h @@ -0,0 +1,44 @@ +/* dvb-usb-common.h is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * a header file containing prototypes and types for internal use of the dvb-usb-lib + */ +#ifndef _DVB_USB_COMMON_H_ +#define _DVB_USB_COMMON_H_ + +#define DVB_USB_LOG_PREFIX "dvb-usb" +#include "dvb-usb.h" + +extern int dvb_usb_debug; + +#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args) +#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args) +#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args) +#define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args) +#define deb_err(args...) dprintk(dvb_usb_debug,0x10,args) +#define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args) +#define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args) + +/* commonly used methods */ +extern int usb_cypress_load_firmware(struct usb_device *, const char *, int); + +extern int dvb_usb_urb_submit(struct dvb_usb_device *); +extern int dvb_usb_urb_kill(struct dvb_usb_device *); +extern int dvb_usb_urb_init(struct dvb_usb_device *); +extern int dvb_usb_urb_exit(struct dvb_usb_device *); + +extern int dvb_usb_i2c_init(struct dvb_usb_device *); +extern int dvb_usb_i2c_exit(struct dvb_usb_device *); + +extern int dvb_usb_dvb_init(struct dvb_usb_device *); +extern int dvb_usb_dvb_exit(struct dvb_usb_device *); + +extern int dvb_usb_fe_init(struct dvb_usb_device *); +extern int dvb_usb_fe_exit(struct dvb_usb_device *); + +extern int dvb_usb_remote_init(struct dvb_usb_device *); +extern int dvb_usb_remote_exit(struct dvb_usb_device *); + +#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c new file mode 100644 index 00000000000..bdd72f77970 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c @@ -0,0 +1,210 @@ +/* dvb-usb-dvb.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for initializing and handling the + * linux-dvb API. + */ +#include "dvb-usb-common.h" + +static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) +{ + struct dvb_usb_device *d = dvbdmxfeed->demux->priv; + int newfeedcount,ret; + + if (d == NULL) + return -ENODEV; + + newfeedcount = d->feedcount + (onoff ? 1 : -1); + + /* + * stop feed before setting a new pid if there will be no pid anymore + */ + if (newfeedcount == 0) { + deb_ts("stop feeding\n"); + + if (d->props.streaming_ctrl != NULL) + if ((ret = d->props.streaming_ctrl(d,0))) + err("error while stopping stream."); + + dvb_usb_urb_kill(d); + } + + d->feedcount = newfeedcount; + + /* activate the pid on the device specific pid_filter */ + deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off"); + if (d->props.caps & DVB_USB_HAS_PID_FILTER && + d->pid_filtering && + d->props.pid_filter != NULL) + d->props.pid_filter(d,dvbdmxfeed->index,dvbdmxfeed->pid,onoff); + + /* start the feed if this was the first feed and there is still a feed + * for reception. + */ + if (d->feedcount == onoff && d->feedcount > 0) { + + deb_ts("controlling pid parser\n"); + if (d->props.caps & DVB_USB_HAS_PID_FILTER && + d->props.caps & DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF && + d->props.pid_filter_ctrl != NULL) + if (d->props.pid_filter_ctrl(d,d->pid_filtering) < 0) + err("could not handle pid_parser"); + + deb_ts("start feeding\n"); + if (d->props.streaming_ctrl != NULL) + if (d->props.streaming_ctrl(d,1)) { + err("error while enabling fifo."); + return -ENODEV; + } + + dvb_usb_urb_submit(d); + } + return 0; +} + +static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type); + return dvb_usb_ctrl_feed(dvbdmxfeed,1); +} + +static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type); + return dvb_usb_ctrl_feed(dvbdmxfeed,0); +} + +int dvb_usb_dvb_init(struct dvb_usb_device *d) +{ + int ret; + + if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name, + d->owner)) < 0) { + deb_info("dvb_register_adapter failed: error %d", ret); + goto err; + } + d->dvb_adap.priv = d; + + if (d->props.read_mac_address) { + if (d->props.read_mac_address(d,d->dvb_adap.proposed_mac) == 0) + info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",d->dvb_adap.proposed_mac[0], + d->dvb_adap.proposed_mac[1],d->dvb_adap.proposed_mac[2], + d->dvb_adap.proposed_mac[3],d->dvb_adap.proposed_mac[4], + d->dvb_adap.proposed_mac[5]); + else + err("MAC address reading failed."); + } + + + d->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; + d->demux.priv = d; + + d->demux.feednum = d->demux.filternum = d->max_feed_count; + d->demux.start_feed = dvb_usb_start_feed; + d->demux.stop_feed = dvb_usb_stop_feed; + d->demux.write_to_decoder = NULL; + if ((ret = dvb_dmx_init(&d->demux)) < 0) { + err("dvb_dmx_init failed: error %d",ret); + goto err_dmx; + } + + d->dmxdev.filternum = d->demux.filternum; + d->dmxdev.demux = &d->demux.dmx; + d->dmxdev.capabilities = 0; + if ((ret = dvb_dmxdev_init(&d->dmxdev, &d->dvb_adap)) < 0) { + err("dvb_dmxdev_init failed: error %d",ret); + goto err_dmx_dev; + } + + dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx); + + goto success; +err_dmx_dev: + dvb_dmx_release(&d->demux); +err_dmx: + dvb_unregister_adapter(&d->dvb_adap); +err: + return ret; +success: + d->state |= DVB_USB_STATE_DVB; + return 0; +} + +int dvb_usb_dvb_exit(struct dvb_usb_device *d) +{ + if (d->state & DVB_USB_STATE_DVB) { + deb_info("unregistering DVB part\n"); + dvb_net_release(&d->dvb_net); + d->demux.dmx.close(&d->demux.dmx); + dvb_dmxdev_release(&d->dmxdev); + dvb_dmx_release(&d->demux); + dvb_unregister_adapter(&d->dvb_adap); + d->state &= ~DVB_USB_STATE_DVB; + } + return 0; +} + +static int dvb_usb_fe_wakeup(struct dvb_frontend *fe) +{ + struct dvb_usb_device *d = fe->dvb->priv; + + if (d->props.power_ctrl) + d->props.power_ctrl(d,1); + + if (d->fe_init) + d->fe_init(fe); + + return 0; +} + +static int dvb_usb_fe_sleep(struct dvb_frontend *fe) +{ + struct dvb_usb_device *d = fe->dvb->priv; + + if (d->fe_sleep) + d->fe_sleep(fe); + + if (d->props.power_ctrl) + d->props.power_ctrl(d,0); + + return 0; +} + +int dvb_usb_fe_init(struct dvb_usb_device* d) +{ + if (d->props.frontend_attach == NULL) { + err("strange '%s' don't want to attach a frontend.",d->desc->name); + return 0; + } + + d->props.frontend_attach(d); + + /* re-assign sleep and wakeup functions */ + if (d->fe != NULL) { + d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup; + d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep; + + if (dvb_register_frontend(&d->dvb_adap, d->fe)) { + err("Frontend registration failed."); + if (d->fe->ops->release) + d->fe->ops->release(d->fe); + d->fe = NULL; + return -ENODEV; + } + } else + err("no frontend was attached by '%s'",d->desc->name); + + if (d->props.tuner_attach != NULL) + d->props.tuner_attach(d); + + return 0; +} + +int dvb_usb_fe_exit(struct dvb_usb_device *d) +{ + if (d->fe != NULL) + dvb_unregister_frontend(d->fe); + return 0; +} diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c new file mode 100644 index 00000000000..5244e39770a --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c @@ -0,0 +1,100 @@ +/* dvb-usb-firmware.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices. + * + * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem. + */ +#include "dvb-usb-common.h" + +#include +#include + +struct usb_cypress_controller { + int id; + const char *name; /* name of the usb controller */ + u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */ +}; + +static struct usb_cypress_controller cypress[] = { + { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, + { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, + { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, +}; + +/* + * load a firmware packet to the device + */ +static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) +{ + return usb_control_msg(udev, usb_sndctrlpipe(udev,0), + 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ); +} + +int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type) +{ + const struct firmware *fw = NULL; + u16 addr; + u8 *b,*p; + int ret = 0,i; + + if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) { + err("did not find the firmware file. (%s) " + "Please see linux/Documentation/dvb/ for more details on firmware-problems.", + filename); + return ret; + } + + info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name); + + p = kmalloc(fw->size,GFP_KERNEL); + if (p != NULL) { + u8 reset; + /* + * you cannot use the fw->data as buffer for + * usb_control_msg, a new buffer has to be + * created + */ + memcpy(p,fw->data,fw->size); + + /* stop the CPU */ + reset = 1; + if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) + err("could not stop the USB controller CPU."); + for(i = 0; p[i+3] == 0 && i < fw->size; ) { + b = (u8 *) &p[i]; + addr = cpu_to_le16( *((u16 *) &b[1]) ); + + deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]); + + ret = usb_cypress_writemem(udev,addr,&b[4],b[0]); + + if (ret != b[0]) { + err("error while transferring firmware " + "(transferred size: %d, block size: %d)", + ret,b[0]); + ret = -EINVAL; + break; + } + i += 5 + b[0]; + } + /* length in ret */ + if (ret > 0) + ret = 0; + /* restart the CPU */ + reset = 0; + if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { + err("could not restart the USB controller CPU."); + ret = -EINVAL; + } + + kfree(p); + } else { + ret = -ENOMEM; + } + release_firmware(fw); + + return ret; +} diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c new file mode 100644 index 00000000000..9f0a8d90d14 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c @@ -0,0 +1,118 @@ +/* dvb-usb-i2c.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for (de-)initializing an I2C adapter. + */ +#include "dvb-usb-common.h" + +int dvb_usb_i2c_init(struct dvb_usb_device *d) +{ + int ret = 0; + + if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER)) + return 0; + + if (d->props.i2c_algo == NULL) { + err("no i2c algorithm specified"); + return -EINVAL; + } + + strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE); +#ifdef I2C_ADAP_CLASS_TV_DIGITAL + d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, +#else + d->i2c_adap.class = I2C_CLASS_TV_DIGITAL, +#endif + d->i2c_adap.algo = d->props.i2c_algo; + d->i2c_adap.algo_data = NULL; + d->i2c_adap.id = I2C_ALGO_BIT; + + i2c_set_adapdata(&d->i2c_adap, d); + + if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0) + err("could not add i2c adapter"); + + d->state |= DVB_USB_STATE_I2C; + + return ret; +} + +int dvb_usb_i2c_exit(struct dvb_usb_device *d) +{ + if (d->state & DVB_USB_STATE_I2C) + i2c_del_adapter(&d->i2c_adap); + d->state &= ~DVB_USB_STATE_I2C; + return 0; +} + +int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) +{ + struct dvb_usb_device *d = fe->dvb->priv; + struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; + int ret = 0; + + /* if there is nothing to initialize */ + if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 && + d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00) + return 0; + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(fe,1,d->pll_addr); + + deb_pll("pll init: %x\n",d->pll_addr); + deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1], + d->pll_init[2],d->pll_init[3]); + + if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { + err("tuner i2c write failed for pll_init."); + ret = -EREMOTEIO; + } + msleep(1); + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(fe,0,d->pll_addr); + return ret; +} +EXPORT_SYMBOL(dvb_usb_pll_init_i2c); + +int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5]) +{ + struct dvb_usb_device *d = fe->dvb->priv; + + deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); + + b[0] = d->pll_addr << 1; + dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth); + + deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]); + + return 0; +} +EXPORT_SYMBOL(dvb_usb_pll_set); + +int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +{ + struct dvb_usb_device *d = fe->dvb->priv; + int ret = 0; + u8 b[5]; + struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 }; + + dvb_usb_pll_set(fe,fep,b); + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(fe,1,d->pll_addr); + + if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { + err("tuner i2c write failed for pll_set."); + ret = -EREMOTEIO; + } + msleep(1); + + if (d->tuner_pass_ctrl) + d->tuner_pass_ctrl(fe,0,d->pll_addr); + + return ret; +} +EXPORT_SYMBOL(dvb_usb_pll_set_i2c); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h new file mode 100644 index 00000000000..bcb34191868 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -0,0 +1,83 @@ +/* dvb-usb-ids.h is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) see + * dvb-usb-init.c for copyright information. + * + * a header file containing define's for the USB device supported by the + * various drivers. + */ +#ifndef _DVB_USB_IDS_H_ +#define _DVB_USB_IDS_H_ + +/* Vendor IDs */ +#define USB_VID_ADSTECH 0x06e1 +#define USB_VID_ANCHOR 0x0547 +#define USB_VID_AVERMEDIA_UNK 0x14aa +#define USB_VID_AVERMEDIA 0x07ca +#define USB_VID_COMPRO 0x185b +#define USB_VID_COMPRO_UNK 0x145f +#define USB_VID_CYPRESS 0x04b4 +#define USB_VID_DIBCOM 0x10b8 +#define USB_VID_DVICO 0x0fe9 +#define USB_VID_EMPIA 0xeb1a +#define USB_VID_GRANDTEC 0x5032 +#define USB_VID_HANFTEK 0x15f4 +#define USB_VID_HAUPPAUGE 0x2040 +#define USB_VID_HYPER_PALTEK 0x1025 +#define USB_VID_VISIONPLUS 0x13d3 +#define USB_VID_TWINHAN 0x1822 +#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 + +/* Product IDs */ +#define USB_PID_ADSTECH_USB2_COLD 0xa333 +#define USB_PID_ADSTECH_USB2_WARM 0xa334 +#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 +#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 +#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 +#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801 +#define USB_PID_COMPRO_DVBU2000_COLD 0xd000 +#define USB_PID_COMPRO_DVBU2000_WARM 0xd001 +#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c +#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d +#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 +#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 +#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 +#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 +#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 +#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 +#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 +#define USB_PID_KWORLD_VSTREAM_COLD 0x17de +#define USB_PID_KWORLD_VSTREAM_WARM 0x17df +#define USB_PID_TWINHAN_VP7041_COLD 0x3201 +#define USB_PID_TWINHAN_VP7041_WARM 0x3202 +#define USB_PID_TWINHAN_VP7045_COLD 0x3205 +#define USB_PID_TWINHAN_VP7045_WARM 0x3206 +#define USB_PID_DNTV_TINYUSB2_COLD 0x3223 +#define USB_PID_DNTV_TINYUSB2_WARM 0x3224 +#define USB_PID_TWINHAN_VP7021_COLD 0x3207 +#define USB_PID_TWINHAN_VP7021_WARM 0x3208 +#define USB_PID_ULTIMA_TVBOX_COLD 0x8105 +#define USB_PID_ULTIMA_TVBOX_WARM 0x8106 +#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107 +#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 +#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 +#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 +#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 +#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 +#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e +#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f +#define USB_PID_HANFTEK_UMT_010_COLD 0x0001 +#define USB_PID_HANFTEK_UMT_010_WARM 0x0015 +#define USB_PID_DTT200U_COLD 0x0201 +#define USB_PID_DTT200U_WARM 0x0301 +#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 +#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 +#define USB_PID_NEBULA_DIGITV 0x0201 +#define USB_PID_DVICO_BLUEBIRD_LGZ201 0xdb00 +#define USB_PID_DVICO_BLUEBIRD_TH7579 0xdb10 +#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 +#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01 +#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11 + + +#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c new file mode 100644 index 00000000000..3aadec974cf --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -0,0 +1,211 @@ +/* + * DVB USB library - provides a generic interface for a DVB USB device driver. + * + * dvb-usb-init.c + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * 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 + */ +#include "dvb-usb-common.h" + +/* debug */ +int dvb_usb_debug; +module_param_named(debug,dvb_usb_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS); + +/* general initialization functions */ +int dvb_usb_exit(struct dvb_usb_device *d) +{ + deb_info("state before exiting everything: %x\n",d->state); + dvb_usb_remote_exit(d); + dvb_usb_fe_exit(d); + dvb_usb_i2c_exit(d); + dvb_usb_dvb_exit(d); + dvb_usb_urb_exit(d); + deb_info("state should be zero now: %x\n",d->state); + d->state = DVB_USB_STATE_INIT; + kfree(d->priv); + kfree(d); + return 0; +} + +static int dvb_usb_init(struct dvb_usb_device *d) +{ + int ret = 0; + + sema_init(&d->usb_sem, 1); + sema_init(&d->i2c_sem, 1); + + d->state = DVB_USB_STATE_INIT; + +/* check the capabilites and set appropriate variables */ + +/* speed - when running at FULL speed we need a HW PID filter */ + if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) { + err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a HW PID filter)"); + return -ENODEV; + } + + if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) || + (d->props.caps & DVB_USB_NEED_PID_FILTERING)) { + info("will use the device's hw PID filter."); + d->pid_filtering = 1; + d->max_feed_count = d->props.pid_filter_count; + } else { + info("will pass the complete MPEG2 transport stream to the demuxer."); + d->pid_filtering = 0; + d->max_feed_count = 255; + } + + if (d->props.power_ctrl) + d->props.power_ctrl(d,1); + + if ((ret = dvb_usb_urb_init(d)) || + (ret = dvb_usb_dvb_init(d)) || + (ret = dvb_usb_i2c_init(d)) || + (ret = dvb_usb_fe_init(d))) { + dvb_usb_exit(d); + return ret; + } + + if ((ret = dvb_usb_remote_init(d))) + err("could not initialize remote control."); + + if (d->props.power_ctrl) + d->props.power_ctrl(d,0); + + return 0; +} + +/* determine the name and the state of the just found USB device */ +static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_properties *props, int *cold) +{ + int i,j; + struct dvb_usb_device_description *desc = NULL; + *cold = -1; + + for (i = 0; i < props->num_device_descs; i++) { + + for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) { + deb_info("check for cold %x %x\n",props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct); + if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && + props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { + *cold = 1; + desc = &props->devices[i]; + break; + } + } + + if (desc != NULL) + break; + + for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) { + deb_info("check for warm %x %x\n",props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct); + if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && + props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { + *cold = 0; + desc = &props->devices[i]; + break; + } + } + } + + if (desc != NULL && props->identify_state != NULL) + props->identify_state(udev,props,&desc,cold); + + return desc; +} + +/* + * USB + */ +int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct dvb_usb_device *d = NULL; + struct dvb_usb_device_description *desc = NULL; + + int ret = -ENOMEM,cold=0; + + if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { + deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); + return -ENODEV; + } + + if (cold) { + info("found a '%s' in cold state, will try to load a firmware",desc->name); + ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl); + } else { + info("found a '%s' in warm state.",desc->name); + d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); + if (d == NULL) { + err("no memory for 'struct dvb_usb_device'"); + return ret; + } + memset(d,0,sizeof(struct dvb_usb_device)); + + d->udev = udev; + memcpy(&d->props,props,sizeof(struct dvb_usb_properties)); + d->desc = desc; + d->owner = owner; + + if (d->props.size_of_priv > 0) { + d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL); + if (d->priv == NULL) { + err("no memory for priv in 'struct dvb_usb_device'"); + kfree(d); + return -ENOMEM; + } + memset(d->priv,0,d->props.size_of_priv); + } + + usb_set_intfdata(intf, d); + + ret = dvb_usb_init(d); + } + + if (ret == 0) + info("%s successfully initialized and connected.",desc->name); + else + info("%s error while loading driver (%d)",desc->name,ret); + return ret; +} +EXPORT_SYMBOL(dvb_usb_device_init); + +void dvb_usb_device_exit(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + const char *name = "generic DVB-USB module"; + + usb_set_intfdata(intf,NULL); + if (d != NULL && d->desc != NULL) { + name = d->desc->name; + dvb_usb_exit(d); + } + info("%s successfully deinitialized and disconnected.",name); + +} +EXPORT_SYMBOL(dvb_usb_device_exit); + +/* module stuff */ +static int __init dvb_usb_module_init(void) +{ + return 0; +} + +static void __exit dvb_usb_module_exit(void) +{ +} + +module_init (dvb_usb_module_init); +module_exit (dvb_usb_module_exit); + +MODULE_VERSION("0.3"); +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c new file mode 100644 index 00000000000..9f1e23f82ba --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -0,0 +1,175 @@ +/* dvb-usb-remote.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for initializing the the input-device and for handling remote-control-queries. + */ +#include "dvb-usb-common.h" + +/* Remote-control poll function - called every dib->rc_query_interval ms to see + * whether the remote control has received anything. + * + * TODO: Fix the repeat rate of the input device. + */ +static void dvb_usb_read_remote_control(void *data) +{ + struct dvb_usb_device *d = data; + u32 event; + int state; + + /* TODO: need a lock here. We can simply skip checking for the remote control + if we're busy. */ + + if (d->props.rc_query(d,&event,&state)) { + err("error while querying for an remote control event."); + goto schedule; + } + + + switch (state) { + case REMOTE_NO_KEY_PRESSED: + break; + case REMOTE_KEY_PRESSED: + deb_rc("key pressed\n"); + d->last_event = event; + case REMOTE_KEY_REPEAT: + deb_rc("key repeated\n"); + input_event(&d->rc_input_dev, EV_KEY, event, 1); + input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0); + input_sync(&d->rc_input_dev); + break; + default: + break; + } + +/* improved repeat handling ??? + switch (state) { + case REMOTE_NO_KEY_PRESSED: + deb_rc("NO KEY PRESSED\n"); + if (d->last_state != REMOTE_NO_KEY_PRESSED) { + deb_rc("releasing event %d\n",d->last_event); + input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0); + input_sync(&d->rc_input_dev); + } + d->last_state = REMOTE_NO_KEY_PRESSED; + d->last_event = 0; + break; + case REMOTE_KEY_PRESSED: + deb_rc("KEY PRESSED\n"); + deb_rc("pressing event %d\n",event); + + input_event(&d->rc_input_dev, EV_KEY, event, 1); + input_sync(&d->rc_input_dev); + + d->last_event = event; + d->last_state = REMOTE_KEY_PRESSED; + break; + case REMOTE_KEY_REPEAT: + deb_rc("KEY_REPEAT\n"); + if (d->last_state != REMOTE_NO_KEY_PRESSED) { + deb_rc("repeating event %d\n",d->last_event); + input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2); + input_sync(&d->rc_input_dev); + d->last_state = REMOTE_KEY_REPEAT; + } + default: + break; + } +*/ + +schedule: + schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); +} + +int dvb_usb_remote_init(struct dvb_usb_device *d) +{ + int i; + if (d->props.rc_key_map == NULL) + return 0; + + /* Initialise the remote-control structures.*/ + init_input_dev(&d->rc_input_dev); + + d->rc_input_dev.evbit[0] = BIT(EV_KEY); + d->rc_input_dev.keycodesize = sizeof(unsigned char); + d->rc_input_dev.keycodemax = KEY_MAX; + d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver"; + + /* set the bits for the keys */ + deb_rc("key map size: %d\n",d->props.rc_key_map_size); + for (i = 0; i < d->props.rc_key_map_size; i++) { + deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i); + set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit); + } + + /* Start the remote-control polling. */ + if (d->props.rc_interval < 40) + d->props.rc_interval = 100; /* default */ + + /* setting these two values to non-zero, we have to manage key repeats */ + d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval; + d->rc_input_dev.rep[REP_DELAY] = d->props.rc_interval + 150; + + input_register_device(&d->rc_input_dev); + + INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d); + + info("schedule remote query interval to %d msecs.",d->props.rc_interval); + schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); + + d->state |= DVB_USB_STATE_REMOTE; + + return 0; +} + +int dvb_usb_remote_exit(struct dvb_usb_device *d) +{ + if (d->state & DVB_USB_STATE_REMOTE) { + cancel_delayed_work(&d->rc_query_work); + flush_scheduled_work(); + input_unregister_device(&d->rc_input_dev); + } + d->state &= ~DVB_USB_STATE_REMOTE; + return 0; +} + +#define DVB_USB_RC_NEC_EMPTY 0x00 +#define DVB_USB_RC_NEC_KEY_PRESSED 0x01 +#define DVB_USB_RC_NEC_KEY_REPEATED 0x02 +int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, + u8 keybuf[5], u32 *event, int *state) +{ + int i; + struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + *event = 0; + *state = REMOTE_NO_KEY_PRESSED; + switch (keybuf[0]) { + case DVB_USB_RC_NEC_EMPTY: + break; + case DVB_USB_RC_NEC_KEY_PRESSED: + if ((u8) ~keybuf[1] != keybuf[2] || + (u8) ~keybuf[3] != keybuf[4]) { + deb_err("remote control checksum failed.\n"); + break; + } + /* See if we can match the raw key code. */ + for (i = 0; i < sizeof(keymap)/sizeof(struct dvb_usb_rc_key); i++) + if (keymap[i].custom == keybuf[1] && + keymap[i].data == keybuf[3]) { + *event = keymap[i].event; + *state = REMOTE_KEY_PRESSED; + break; + } + deb_err("key mapping failed - no appropriate key found in keymapping\n"); + break; + case DVB_USB_RC_NEC_KEY_REPEATED: + *state = REMOTE_KEY_REPEAT; + break; + default: + deb_err("unkown type of remote status: %d\n",keybuf[0]); + break; + } + return 0; +} +EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c new file mode 100644 index 00000000000..83d476fb410 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c @@ -0,0 +1,211 @@ +/* dvb-usb-urb.c is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * This file contains functions for initializing and handling the + * USB and URB stuff. + */ +#include "dvb-usb-common.h" + +int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, + u16 rlen, int delay_ms) +{ + int actlen,ret = -ENOMEM; + + if (d->props.generic_bulk_ctrl_endpoint == 0) { + err("endpoint for generic control not specified."); + return -EINVAL; + } + + if (wbuf == NULL || wlen == 0) + return -EINVAL; + + if ((ret = down_interruptible(&d->usb_sem))) + return ret; + + debug_dump(wbuf,wlen,deb_xfer); + + ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev, + d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen, + 2*HZ); + + if (ret) + err("bulk message failed: %d (%d/%d)",ret,wlen,actlen); + else + ret = actlen != wlen ? -1 : 0; + + /* an answer is expected, and no error before */ + if (!ret && rbuf && rlen) { + if (delay_ms) + msleep(delay_ms); + + ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev, + d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen, + 2*HZ); + + if (ret) + err("recv bulk message failed: %d",ret); + else + debug_dump(rbuf,actlen,deb_xfer); + } + + up(&d->usb_sem); + return ret; +} +EXPORT_SYMBOL(dvb_usb_generic_rw); + +int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len) +{ + return dvb_usb_generic_rw(d,buf,len,NULL,0,0); +} +EXPORT_SYMBOL(dvb_usb_generic_write); + +static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs) +{ + struct dvb_usb_device *d = urb->context; + + deb_ts("bulk urb completed. feedcount: %d, status: %d, length: %d\n",d->feedcount,urb->status, + urb->actual_length); + + switch (urb->status) { + case 0: /* success */ + case -ETIMEDOUT: /* NAK */ + break; + case -ECONNRESET: /* kill */ + case -ENOENT: + case -ESHUTDOWN: + return; + default: /* error */ + deb_ts("urb completition error %d.", urb->status); + break; + } + + if (d->feedcount > 0 && urb->actual_length > 0) { + if (d->state & DVB_USB_STATE_DVB) + dvb_dmx_swfilter(&d->demux, (u8*) urb->transfer_buffer,urb->actual_length); + } else + deb_ts("URB dropped because of feedcount.\n"); + + usb_submit_urb(urb,GFP_ATOMIC); +} + +int dvb_usb_urb_kill(struct dvb_usb_device *d) +{ + int i; + for (i = 0; i < d->urbs_submitted; i++) { + deb_info("killing URB no. %d.\n",i); + + /* stop the URB */ + usb_kill_urb(d->urb_list[i]); + } + d->urbs_submitted = 0; + return 0; +} + +int dvb_usb_urb_submit(struct dvb_usb_device *d) +{ + int i,ret; + for (i = 0; i < d->urbs_initialized; i++) { + deb_info("submitting URB no. %d\n",i); + if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) { + err("could not submit URB no. %d - get them all back\n",i); + dvb_usb_urb_kill(d); + return ret; + } + d->urbs_submitted++; + } + return 0; +} + +static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d) +{ + int i,bufsize = d->props.urb.count * d->props.urb.u.bulk.buffersize; + + deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize); + /* allocate the actual buffer for the URBs */ + if ((d->buffer = usb_buffer_alloc(d->udev, bufsize, SLAB_ATOMIC, &d->dma_handle)) == NULL) { + deb_info("not enough memory for urb-buffer allocation.\n"); + return -ENOMEM; + } + deb_info("allocation successful\n"); + memset(d->buffer,0,bufsize); + + d->state |= DVB_USB_STATE_URB_BUF; + + /* allocate the URBs */ + for (i = 0; i < d->props.urb.count; i++) { + if (!(d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) { + return -ENOMEM; + } + + usb_fill_bulk_urb( d->urb_list[i], d->udev, + usb_rcvbulkpipe(d->udev,d->props.urb.endpoint), + &d->buffer[i*d->props.urb.u.bulk.buffersize], + d->props.urb.u.bulk.buffersize, + dvb_usb_bulk_urb_complete, d); + + d->urb_list[i]->transfer_flags = 0; + d->urbs_initialized++; + } + return 0; +} + +int dvb_usb_urb_init(struct dvb_usb_device *d) +{ + /* + * when reloading the driver w/o replugging the device + * sometimes a timeout occures, this helps + */ + if (d->props.generic_bulk_ctrl_endpoint != 0) { + usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint)); + } + usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint)); + + /* allocate the array for the data transfer URBs */ + d->urb_list = kmalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL); + if (d->urb_list == NULL) + return -ENOMEM; + memset(d->urb_list,0,d->props.urb.count * sizeof(struct urb *)); + d->state |= DVB_USB_STATE_URB_LIST; + + switch (d->props.urb.type) { + case DVB_USB_BULK: + return dvb_usb_bulk_urb_init(d); + case DVB_USB_ISOC: + err("isochronous transfer not yet implemented in dvb-usb."); + return -EINVAL; + default: + err("unkown URB-type for data transfer."); + return -EINVAL; + } +} + +int dvb_usb_urb_exit(struct dvb_usb_device *d) +{ + int i; + + dvb_usb_urb_kill(d); + + if (d->state & DVB_USB_STATE_URB_LIST) { + for (i = 0; i < d->urbs_initialized; i++) { + if (d->urb_list[i] != NULL) { + deb_info("freeing URB no. %d.\n",i); + /* free the URBs */ + usb_free_urb(d->urb_list[i]); + } + } + d->urbs_initialized = 0; + /* free the urb array */ + kfree(d->urb_list); + d->state &= ~DVB_USB_STATE_URB_LIST; + } + + if (d->state & DVB_USB_STATE_URB_BUF) + usb_buffer_free(d->udev, d->props.urb.u.bulk.buffersize * d->props.urb.count, + d->buffer, d->dma_handle); + + d->state &= ~DVB_USB_STATE_URB_BUF; + return 0; +} diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h new file mode 100644 index 00000000000..abcee1943f6 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -0,0 +1,315 @@ +/* dvb-usb.h is part of the DVB USB library. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * see dvb-usb-init.c for copyright information. + * + * the headerfile, all dvb-usb-drivers have to include. + */ +#ifndef __DVB_USB_H__ +#define __DVB_USB_H__ + +#include +#include +#include +#include + +#include "dvb_frontend.h" +#include "dvb_demux.h" +#include "dvb_net.h" +#include "dmxdev.h" + +#include "dvb-pll.h" + +#include "dvb-usb-ids.h" + +/* debug */ +#ifdef CONFIG_DVB_USB_DEBUG +#define dprintk(var,level,args...) \ + do { if ((var & level)) { printk(args); } } while (0) + +#define debug_dump(b,l,func) {\ + int loop_; \ + for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \ + func("\n");\ +} +#define DVB_USB_DEBUG_STATUS +#else +#define dprintk(args...) +#define debug_dump(b,l,func) + +#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)" + +#endif + +/* generic log methods - taken from usb.h */ +#ifndef DVB_USB_LOG_PREFIX + #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)" +#endif + +#undef err +#define err(format, arg...) printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg) +#undef info +#define info(format, arg...) printk(KERN_INFO DVB_USB_LOG_PREFIX ": " format "\n" , ## arg) +#undef warn +#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg) + +/** + * struct dvb_usb_device_description - name and its according USB IDs + * @name: real name of the box, regardless which DVB USB device class is in use + * @cold_ids: array of struct usb_device_id which describe the device in + * pre-firmware state + * @warm_ids: array of struct usb_device_id which describe the device in + * post-firmware state + * + * Each DVB USB device class can have one or more actual devices, this struct + * assigns a name to it. + */ +struct dvb_usb_device_description { + const char *name; + +#define DVB_USB_ID_MAX_NUM 15 + struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM]; + struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM]; +}; + +/** + * struct dvb_usb_rc_key - a remote control key and its input-event + * @custom: the vendor/custom part of the key + * @data: the actual key part + * @event: the input event assigned to key identified by custom and data + */ +struct dvb_usb_rc_key { + u8 custom,data; + u32 event; +}; + +struct dvb_usb_device; + +/** + * struct dvb_usb_properties - properties of a dvb-usb-device + * @caps: capabilites of the DVB USB device. + * @pid_filter_count: number of PID filter position in the optional hardware + * PID-filter. + * + * @usb_ctrl: which USB device-side controller is in use. Needed for firmware + * download. + * @firmware: name of the firmware file. + * + * @size_of_priv: how many bytes shall be allocated for the private field + * of struct dvb_usb_device. + * + * @power_ctrl: called to enable/disable power of the device. + * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the + * device (not URB submitting/killing). + * @pid_filter_ctrl: called to en/disable the PID filter, if any. + * @pid_filter: called to set/unset a PID for filtering. + * + * @read_mac_address: called to read the MAC address of the device. + * + * @frontend_attach: called to attach the possible frontends (fill fe-field + * of struct dvb_usb_device). + * @tuner_attach: called to attach the correct tuner and to fill pll_addr, + * pll_desc and pll_init_buf of struct dvb_usb_device). + * @identify_state: called to determine the state (cold or warm), when it + * is not distinguishable by the USB IDs. + * + * @rc_key_map: a hard-wired array of struct dvb_usb_rc_key (NULL to disable + * remote control handling). + * @rc_key_map_size: number of items in @rc_key_map. + * @rc_query: called to query an event event. + * @rc_interval: time in ms between two queries. + * + * @i2c_algo: i2c_algorithm if the device has I2CoverUSB. + * + * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic + * endpoint which received control messages with bulk transfers. When this + * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write- + * helper functions. + * + * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming. + * Currently only BULK is implemented + * + * @num_device_descs: number of struct dvb_usb_device_description in @devices + * @devices: array of struct dvb_usb_device_description compatibles with these + * properties. + */ +struct dvb_usb_properties { + +#define DVB_USB_HAS_PID_FILTER 0x01 +#define DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF 0x02 +#define DVB_USB_NEED_PID_FILTERING 0x04 +#define DVB_USB_IS_AN_I2C_ADAPTER 0x08 + int caps; + int pid_filter_count; + +#define CYPRESS_AN2135 0 +#define CYPRESS_AN2235 1 +#define CYPRESS_FX2 2 + int usb_ctrl; + const char *firmware; + + int size_of_priv; + + int (*power_ctrl) (struct dvb_usb_device *, int); + int (*streaming_ctrl) (struct dvb_usb_device *, int); + int (*pid_filter_ctrl) (struct dvb_usb_device *, int); + int (*pid_filter) (struct dvb_usb_device *, int, u16, int); + + int (*read_mac_address) (struct dvb_usb_device *, u8 []); + int (*frontend_attach) (struct dvb_usb_device *); + int (*tuner_attach) (struct dvb_usb_device *); + + int (*identify_state) (struct usb_device *, struct dvb_usb_properties *, + struct dvb_usb_device_description **, int *); + +/* remote control properties */ +#define REMOTE_NO_KEY_PRESSED 0x00 +#define REMOTE_KEY_PRESSED 0x01 +#define REMOTE_KEY_REPEAT 0x02 + struct dvb_usb_rc_key *rc_key_map; + int rc_key_map_size; + int (*rc_query) (struct dvb_usb_device *, u32 *, int *); + int rc_interval; + + struct i2c_algorithm *i2c_algo; + + int generic_bulk_ctrl_endpoint; + + struct { +#define DVB_USB_BULK 1 +#define DVB_USB_ISOC 2 + int type; + int count; + int endpoint; + + union { + struct { + int buffersize; /* per URB */ + } bulk; + struct { + int framesperurb; + int framesize; + } isoc; + } u; + } urb; + + int num_device_descs; + struct dvb_usb_device_description devices[8]; +}; + + +/** + * struct dvb_usb_device - object of a DVB USB device + * @props: copy of the struct dvb_usb_properties this device belongs to. + * @desc: pointer to the device's struct dvb_usb_device_description. + * @state: initialization and runtime state of the device. + * + * @udev: pointer to the device's struct usb_device. + * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS- + * streaming. + * @buffer: buffer used to streaming. + * @dma_handle: dma_addr_t for buffer. + * @urbs_initialized: number of URBs initialized. + * @urbs_submitted: number of URBs submitted. + * @feedcount: number of reqested feeds (used for streaming-activation) + * @pid_filtering: is hardware pid_filtering used or not. + * @usb_sem: semaphore of USB control messages (reading needs two messages) + * @i2c_sem: semaphore for i2c-transfers + * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB + * @pll_addr: I2C address of the tuner for programming + * @pll_init: array containing the initialization buffer + * @pll_desc: pointer to the appropriate struct dvb_pll_desc + * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod + * @dvb_adap: device's dvb_adapter. + * @dmxdev: device's dmxdev. + * @demux: device's software demuxer. + * @dvb_net: device's dvb_net interfaces. + * @dvb_frontend: device's frontend. + * @max_feed_count: how many feeds can be handled simultaneously by this + * device + * @fe_sleep: rerouted frontend-sleep function. + * @fe_init: rerouted frontend-init (wakeup) function. + * @rc_input_dev: input device for the remote control. + * @rc_query_work: struct work_struct frequent rc queries + * @last_event: last triggered event + * @last_state: last state (no, pressed, repeat) + * @owner: owner of the dvb_adapter + * @priv: private data of the actual driver (allocate by dvb-usb, size defined + * in size_of_priv of dvb_usb_properties). + */ +struct dvb_usb_device { + struct dvb_usb_properties props; + struct dvb_usb_device_description *desc; + +#define DVB_USB_STATE_INIT 0x000 +#define DVB_USB_STATE_URB_LIST 0x001 +#define DVB_USB_STATE_URB_BUF 0x002 +#define DVB_USB_STATE_DVB 0x004 +#define DVB_USB_STATE_I2C 0x008 +#define DVB_USB_STATE_REMOTE 0x010 +#define DVB_USB_STATE_URB_SUBMIT 0x020 + int state; + + /* usb */ + struct usb_device *udev; + struct urb **urb_list; + u8 *buffer; + dma_addr_t dma_handle; + int urbs_initialized; + int urbs_submitted; + + int feedcount; + int pid_filtering; + + /* locking */ + struct semaphore usb_sem; + + /* i2c */ + struct semaphore i2c_sem; + struct i2c_adapter i2c_adap; + + /* tuner programming information */ + u8 pll_addr; + u8 pll_init[4]; + struct dvb_pll_desc *pll_desc; + int (*tuner_pass_ctrl)(struct dvb_frontend *, int, u8); + + /* dvb */ + struct dvb_adapter dvb_adap; + struct dmxdev dmxdev; + struct dvb_demux demux; + struct dvb_net dvb_net; + struct dvb_frontend* fe; + int max_feed_count; + + int (*fe_sleep) (struct dvb_frontend *); + int (*fe_init) (struct dvb_frontend *); + + /* remote control */ + struct input_dev rc_input_dev; + struct work_struct rc_query_work; + u32 last_event; + int last_state; + + struct module *owner; + + void *priv; +}; + +extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *); +extern void dvb_usb_device_exit(struct usb_interface *); + +/* the generic read/write method for device control */ +extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int); +extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); + +/* commonly used remote control parsing */ +extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); + +/* commonly used pll init and set functions */ +extern int dvb_usb_pll_init_i2c(struct dvb_frontend *); +extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); +extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); + + +#endif diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c new file mode 100644 index 00000000000..9d83781aef9 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -0,0 +1,236 @@ +/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2 + * DVB-T receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * 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 + */ +#include "dibusb.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS); + +#define deb_rc(args...) dprintk(debug,0x01,args) +#define deb_ee(args...) dprintk(debug,0x02,args) + +/* Hauppauge NOVA-T USB2 keys */ +static struct dvb_usb_rc_key haupp_rc_keys [] = { + { 0x1e, 0x00, KEY_0 }, + { 0x1e, 0x01, KEY_1 }, + { 0x1e, 0x02, KEY_2 }, + { 0x1e, 0x03, KEY_3 }, + { 0x1e, 0x04, KEY_4 }, + { 0x1e, 0x05, KEY_5 }, + { 0x1e, 0x06, KEY_6 }, + { 0x1e, 0x07, KEY_7 }, + { 0x1e, 0x08, KEY_8 }, + { 0x1e, 0x09, KEY_9 }, + { 0x1e, 0x0a, KEY_KPASTERISK }, + { 0x1e, 0x0b, KEY_RED }, + { 0x1e, 0x0c, KEY_RADIO }, + { 0x1e, 0x0d, KEY_MENU }, + { 0x1e, 0x0e, KEY_GRAVE }, /* # */ + { 0x1e, 0x0f, KEY_MUTE }, + { 0x1e, 0x10, KEY_VOLUMEUP }, + { 0x1e, 0x11, KEY_VOLUMEDOWN }, + { 0x1e, 0x12, KEY_CHANNEL }, + { 0x1e, 0x14, KEY_UP }, + { 0x1e, 0x15, KEY_DOWN }, + { 0x1e, 0x16, KEY_LEFT }, + { 0x1e, 0x17, KEY_RIGHT }, + { 0x1e, 0x18, KEY_VIDEO }, + { 0x1e, 0x19, KEY_AUDIO }, + { 0x1e, 0x1a, KEY_MEDIA }, + { 0x1e, 0x1b, KEY_EPG }, + { 0x1e, 0x1c, KEY_TV }, + { 0x1e, 0x1e, KEY_NEXT }, + { 0x1e, 0x1f, KEY_BACK }, + { 0x1e, 0x20, KEY_CHANNELUP }, + { 0x1e, 0x21, KEY_CHANNELDOWN }, + { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */ + { 0x1e, 0x25, KEY_OK }, + { 0x1e, 0x29, KEY_BLUE}, + { 0x1e, 0x2e, KEY_GREEN }, + { 0x1e, 0x30, KEY_PAUSE }, + { 0x1e, 0x32, KEY_REWIND }, + { 0x1e, 0x34, KEY_FASTFORWARD }, + { 0x1e, 0x35, KEY_PLAY }, + { 0x1e, 0x36, KEY_STOP }, + { 0x1e, 0x37, KEY_RECORD }, + { 0x1e, 0x38, KEY_YELLOW }, + { 0x1e, 0x3b, KEY_GOTO }, + { 0x1e, 0x3d, KEY_POWER }, +}; + +/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key + * is delivered. No workaround yet, maybe a new firmware. + */ +static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom; + u16 raw; + int i; + struct dibusb_state *st = d->priv; + + dvb_usb_generic_rw(d,cmd,2,key,5,0); + + *state = REMOTE_NO_KEY_PRESSED; + switch (key[0]) { + case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED: + raw = ((key[1] << 8) | key[2]) >> 3; + toggle = !!(raw & 0x800); + data = raw & 0x3f; + custom = (raw >> 6) & 0x1f; + + deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle); + + for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) { + deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom); + if (haupp_rc_keys[i].data == data && + haupp_rc_keys[i].custom == custom) { + *event = haupp_rc_keys[i].event; + *state = REMOTE_KEY_PRESSED; + if (st->old_toggle == toggle) { + if (st->last_repeat_count++ < 2) + *state = REMOTE_NO_KEY_PRESSED; + } else { + st->last_repeat_count = 0; + st->old_toggle = toggle; + } + break; + } + } + + break; + case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY: + default: + break; + } + + return 0; +} + +static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6]) +{ + int i; + u8 b; + + mac[0] = 0x00; + mac[1] = 0x0d; + mac[2] = 0xfe; + + /* this is a complete guess, but works for my box */ + for (i = 136; i < 139; i++) { + dibusb_read_eeprom_byte(d,i, &b); + + mac[5 - (i - 136)] = b; + +/* deb_ee("%02x ",b); + if ((i+1) % 16 == 0) + deb_ee("\n");*/ + } + + return 0; +} + +/* USB Driver stuff */ +static struct dvb_usb_properties nova_t_properties; + +static int nova_t_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE); +} + +/* do not change the order of the ID table */ +static struct usb_device_id nova_t_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) }, +/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, nova_t_table); + +static struct dvb_usb_properties nova_t_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 32, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-nova-t-usb2-01.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .pid_filter = dibusb_pid_filter, + .pid_filter_ctrl = dibusb_pid_filter_ctrl, + .power_ctrl = dibusb2_0_power_ctrl, + .frontend_attach = dibusb_dib3000mc_frontend_attach, + .tuner_attach = dibusb_dib3000mc_tuner_attach, + .read_mac_address = nova_t_read_mac_address, + + .rc_interval = 100, + .rc_key_map = haupp_rc_keys, + .rc_key_map_size = ARRAY_SIZE(haupp_rc_keys), + .rc_query = nova_t_rc_query, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 1, + .devices = { + { "Hauppauge WinTV-NOVA-T usb2", + { &nova_t_table[0], NULL }, + { &nova_t_table[1], NULL }, + }, + } +}; + +static struct usb_driver nova_t_driver = { + .owner = THIS_MODULE, + .name = "Hauppauge WinTV-NOVA-T usb2", + .probe = nova_t_probe, + .disconnect = dvb_usb_device_exit, + .id_table = nova_t_table, +}; + +/* module stuff */ +static int __init nova_t_module_init(void) +{ + int result; + if ((result = usb_register(&nova_t_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit nova_t_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&nova_t_driver); +} + +module_init (nova_t_module_init); +module_exit (nova_t_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c new file mode 100644 index 00000000000..aa560422ce7 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/umt-010.c @@ -0,0 +1,162 @@ +/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0 + * DVB-T receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * 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 + */ +#include "dibusb.h" + +#include "mt352.h" + +static int umt_mt352_demod_init(struct dvb_frontend *fe) +{ + static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d }; + static u8 mt352_reset[] = { 0x50, 0x80 }; + static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 }; + static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 }; + static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 }; + + static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff }; + static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff }; + static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 }; + static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 }; + static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f }; + + static u8 mt352_acq_ctl[] = { 0x53, 0x50 }; + static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 }; + + mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); + udelay(2000); + mt352_write(fe, mt352_reset, sizeof(mt352_reset)); + mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio)); + + mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); + mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); + + mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1)); + mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2)); + mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3)); + mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4)); + mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5)); + + mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl)); + mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1)); + + return 0; +} + +static int umt_mt352_frontend_attach(struct dvb_usb_device *d) +{ + struct mt352_config umt_config; + + memset(&umt_config,0,sizeof(struct mt352_config)); + umt_config.demod_init = umt_mt352_demod_init; + umt_config.demod_address = 0xf; + umt_config.pll_set = dvb_usb_pll_set; + + d->fe = mt352_attach(&umt_config, &d->i2c_adap); + + return 0; +} + +static int umt_tuner_attach (struct dvb_usb_device *d) +{ + d->pll_addr = 0x61; + d->pll_desc = &dvb_pll_tua6034; + return 0; +} + +/* USB Driver stuff */ +static struct dvb_usb_properties umt_properties; + +static int umt_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0) + return 0; + return -EINVAL; +} + +/* do not change the order of the ID table */ +static struct usb_device_id umt_table [] = { +/* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) }, +/* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, umt_table); + +static struct dvb_usb_properties umt_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-umt-010-02.fw", + + .size_of_priv = sizeof(struct dibusb_state), + + .streaming_ctrl = dibusb2_0_streaming_ctrl, + .power_ctrl = dibusb_power_ctrl, + .frontend_attach = umt_mt352_frontend_attach, + .tuner_attach = umt_tuner_attach, + + .i2c_algo = &dibusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 20, + .endpoint = 0x06, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + + .num_device_descs = 1, + .devices = { + { "Hanftek UMT-010 DVB-T USB2.0", + { &umt_table[0], NULL }, + { &umt_table[1], NULL }, + }, + } +}; + +static struct usb_driver umt_driver = { + .owner = THIS_MODULE, + .name = "HanfTek UMT-010 USB2.0 DVB-T devices", + .probe = umt_probe, + .disconnect = dvb_usb_device_exit, + .id_table = umt_table, +}; + +/* module stuff */ +static int __init umt_module_init(void) +{ + int result; + if ((result = usb_register(&umt_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit umt_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&umt_driver); +} + +module_init (umt_module_init); +module_exit (umt_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c new file mode 100644 index 00000000000..2746edfeccb --- /dev/null +++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c @@ -0,0 +1,196 @@ +/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0 + * DVB-T receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * Thanks to Twinhan who kindly provided hardware and information. + * + * 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 + * + */ +#include "vp7045.h" + +/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT + * + * Programming is hidden inside the firmware, so set_frontend is very easy. + * Even though there is a Firmware command that one can use to access the demod + * via its registers. This is used for status information. + */ + +struct vp7045_fe_state { + struct dvb_frontend fe; + struct dvb_usb_device *d; +}; + + +static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + u8 s0 = vp7045_read_reg(state->d,0x00), + s1 = vp7045_read_reg(state->d,0x01), + s3 = vp7045_read_reg(state->d,0x03); + + *status = 0; + if (s0 & (1 << 4)) + *status |= FE_HAS_CARRIER; + if (s0 & (1 << 1)) + *status |= FE_HAS_VITERBI; + if (s0 & (1 << 5)) + *status |= FE_HAS_LOCK; + if (s1 & (1 << 1)) + *status |= FE_HAS_SYNC; + if (s3 & (1 << 6)) + *status |= FE_HAS_SIGNAL; + + if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != + (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) + *status &= ~FE_HAS_LOCK; + + return 0; +} + +static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + *ber = (vp7045_read_reg(state->d, 0x0D) << 16) | + (vp7045_read_reg(state->d, 0x0E) << 8) | + vp7045_read_reg(state->d, 0x0F); + return 0; +} + +static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + *unc = (vp7045_read_reg(state->d, 0x10) << 8) | + vp7045_read_reg(state->d, 0x11); + return 0; +} + +static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) | + vp7045_read_reg(state->d, 0x15); + + *strength = ~signal; + return 0; +} + +static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + u8 _snr = vp7045_read_reg(state->d, 0x09); + *snr = (_snr << 8) | _snr; + return 0; +} + +static int vp7045_fe_init(struct dvb_frontend* fe) +{ + return 0; +} + +static int vp7045_fe_sleep(struct dvb_frontend* fe) +{ + return 0; +} + +static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) +{ + tune->min_delay_ms = 800; + return 0; +} + +static int vp7045_fe_set_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + u8 buf[5]; + u32 freq = fep->frequency / 1000; + + buf[0] = (freq >> 16) & 0xff; + buf[1] = (freq >> 8) & 0xff; + buf[2] = freq & 0xff; + buf[3] = 0; + + switch (fep->u.ofdm.bandwidth) { + case BANDWIDTH_8_MHZ: buf[4] = 8; break; + case BANDWIDTH_7_MHZ: buf[4] = 7; break; + case BANDWIDTH_6_MHZ: buf[4] = 6; break; + case BANDWIDTH_AUTO: return -EOPNOTSUPP; + default: + return -EINVAL; + } + + vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200); + return 0; +} + +static int vp7045_fe_get_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + return 0; +} + +static void vp7045_fe_release(struct dvb_frontend* fe) +{ + struct vp7045_fe_state *state = fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops vp7045_fe_ops; + +struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) +{ + struct vp7045_fe_state *s = kmalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL); + if (s == NULL) + goto error; + memset(s,0,sizeof(struct vp7045_fe_state)); + + s->d = d; + s->fe.ops = &vp7045_fe_ops; + s->fe.demodulator_priv = s; + + goto success; +error: + return NULL; +success: + return &s->fe; +} + + +static struct dvb_frontend_ops vp7045_fe_ops = { + .info = { + .name = "Twinhan VP7045/46 USB DVB-T", + .type = FE_OFDM, + .frequency_min = 44250000, + .frequency_max = 867250000, + .frequency_stepsize = 1000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | + FE_CAN_HIERARCHY_AUTO, + }, + + .release = vp7045_fe_release, + + .init = vp7045_fe_init, + .sleep = vp7045_fe_sleep, + + .set_frontend = vp7045_fe_set_frontend, + .get_frontend = vp7045_fe_get_frontend, + .get_tune_settings = vp7045_fe_get_tune_settings, + + .read_status = vp7045_fe_read_status, + .read_ber = vp7045_fe_read_ber, + .read_signal_strength = vp7045_fe_read_signal_strength, + .read_snr = vp7045_fe_read_snr, + .read_ucblocks = vp7045_fe_read_unc_blocks, +}; diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c new file mode 100644 index 00000000000..02ecc9a8e3b --- /dev/null +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -0,0 +1,263 @@ +/* DVB USB compliant Linux driver for the + * - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver + * - DigitalNow TinyUSB2 DVB-t receiver + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * Thanks to Twinhan who kindly provided hardware and information. + * + * 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 + */ +#include "vp7045.h" + +/* debug */ +int dvb_usb_vp7045_debug; +module_param_named(debug,dvb_usb_vp7045_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); + +int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec) +{ + int ret = 0; + u8 inbuf[12] = { 0 }, outbuf[20] = { 0 }; + + outbuf[0] = cmd; + + if (outlen > 19) + outlen = 19; + + if (inlen > 11) + inlen = 11; + + if (out != NULL && outlen > 0) + memcpy(&outbuf[1], out, outlen); + + deb_xfer("out buffer: "); + debug_dump(outbuf,outlen+1,deb_xfer); + + if ((ret = down_interruptible(&d->usb_sem))) + return ret; + + if (usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev,0), + TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, + outbuf, 20, 2*HZ) != 20) { + err("USB control message 'out' went wrong."); + ret = -EIO; + goto unlock; + } + + msleep(msec); + + if (usb_control_msg(d->udev, + usb_rcvctrlpipe(d->udev,0), + TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, + inbuf, 12, 2*HZ) != 12) { + err("USB control message 'in' went wrong."); + ret = -EIO; + goto unlock; + } + + deb_xfer("in buffer: "); + debug_dump(inbuf,12,deb_xfer); + + if (in != NULL && inlen > 0) + memcpy(in,&inbuf[1],inlen); + +unlock: + up(&d->usb_sem); + + return ret; +} + +u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg) +{ + u8 obuf[2] = { 0 },v; + obuf[1] = reg; + + vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30); + + return v; +} + +static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 v = onoff; + return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150); +} + +/* remote control stuff */ + +/* The keymapping struct. Somehow this should be loaded to the driver, but + * currently it is hardcoded. */ +static struct dvb_usb_rc_key vp7045_rc_keys[] = { + /* insert the keys like this. to make the raw keys visible, enable + * debug=0x04 when loading dvb-usb-vp7045. */ + + /* these keys are probably wrong. I don't have a working IR-receiver on my + * vp7045, so I can't test it. Patches are welcome. */ + { 0x00, 0x01, KEY_1 }, + { 0x00, 0x02, KEY_2 }, +}; + +static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state) +{ + u8 key; + int i; + vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20); + + deb_rc("remote query key: %x %d\n",key,key); + + if (key == 0x44) { + *state = REMOTE_NO_KEY_PRESSED; + return 0; + } + + for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++) + if (vp7045_rc_keys[i].data == key) { + *state = REMOTE_KEY_PRESSED; + *key_buf = vp7045_rc_keys[i].event; + break; + } + return 0; +} + +static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset) +{ + int i = 0; + u8 v,br[2]; + for (i=0; i < len; i++) { + v = offset + i; + vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5); + buf[i] = br[1]; + } + deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i); + debug_dump(buf,i,deb_info); + return 0; +} + + +static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) +{ + return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR); +} + +static int vp7045_frontend_attach(struct dvb_usb_device *d) +{ + u8 buf[255] = { 0 }; + + vp7045_usb_op(d,VENDOR_STRING_READ,NULL,0,buf,20,0); + buf[10] = '\0'; + deb_info("firmware says: %s ",buf); + + vp7045_usb_op(d,PRODUCT_STRING_READ,NULL,0,buf,20,0); + buf[10] = '\0'; + deb_info("%s ",buf); + + vp7045_usb_op(d,FW_VERSION_READ,NULL,0,buf,20,0); + buf[10] = '\0'; + deb_info("v%s\n",buf); + +/* Dump the EEPROM */ +/* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */ + + d->fe = vp7045_fe_attach(d); + + return 0; +} + +static struct dvb_usb_properties vp7045_properties; + +static int vp7045_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE); +} + +static struct usb_device_id vp7045_usb_table [] = { + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) }, + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) }, + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) }, + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) }, + { 0 }, +}; +MODULE_DEVICE_TABLE(usb, vp7045_usb_table); + +static struct dvb_usb_properties vp7045_properties = { + .caps = 0, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-vp7045-01.fw", + + .power_ctrl = vp7045_power_ctrl, + .frontend_attach = vp7045_frontend_attach, + .read_mac_address = vp7045_read_mac_addr, + + .rc_interval = 400, + .rc_key_map = vp7045_rc_keys, + .rc_key_map_size = ARRAY_SIZE(vp7045_rc_keys), + .rc_query = vp7045_rc_query, + + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 2, + .devices = { + { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)", + .cold_ids = { &vp7045_usb_table[0], NULL }, + .warm_ids = { &vp7045_usb_table[1], NULL }, + }, + { .name = "DigitalNow TinyUSB 2 DVB-t Receiver", + .cold_ids = { &vp7045_usb_table[2], NULL }, + .warm_ids = { &vp7045_usb_table[3], NULL }, + }, + { 0 }, + } +}; + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver vp7045_usb_driver = { + .owner = THIS_MODULE, + .name = "dvb-usb-vp7045", + .probe = vp7045_usb_probe, + .disconnect = dvb_usb_device_exit, + .id_table = vp7045_usb_table, +}; + +/* module stuff */ +static int __init vp7045_usb_module_init(void) +{ + int result; + if ((result = usb_register(&vp7045_usb_driver))) { + err("usb_register failed. (%d)",result); + return result; + } + + return 0; +} + +static void __exit vp7045_usb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&vp7045_usb_driver); +} + +module_init(vp7045_usb_module_init); +module_exit(vp7045_usb_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h new file mode 100644 index 00000000000..9ce21a20fa8 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/vp7045.h @@ -0,0 +1,78 @@ +/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII + * USB2.0 DVB-T receiver. + * + * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) + * + * Thanks to Twinhan who kindly provided hardware and information. + * + * 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 + */ +#ifndef _DVB_USB_VP7045_H_ +#define _DVB_USB_VP7045_H_ + +#define DVB_USB_LOG_PREFIX "vp7045" +#include "dvb-usb.h" + +extern int dvb_usb_vp7045_debug; +#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args) +#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args) +#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args) + +/* vp7045 commands */ + +/* Twinhan Vendor requests */ +#define TH_COMMAND_IN 0xC0 +#define TH_COMMAND_OUT 0xC1 + +/* command bytes */ +#define TUNER_REG_READ 0x03 +#define TUNER_REG_WRITE 0x04 + +#define RC_VAL_READ 0x05 + #define RC_NO_KEY 0x44 + +#define SET_TUNER_POWER 0x06 +#define CHECK_TUNER_POWER 0x12 + #define Tuner_Power_ON 1 + #define Tuner_Power_OFF 0 + +#define GET_USB_SPEED 0x07 + #define USB_SPEED_LOW 0 + #define USB_SPEED_FULL 1 + #define USB_SPEED_HIGH 2 + +#define LOCK_TUNER_COMMAND 0x09 + +#define TUNER_SIGNAL_READ 0x0A + +/* FX2 eeprom */ +#define SET_EE_VALUE 0x10 +#define GET_EE_VALUE 0x11 + #define FX2_ID_ADDR 0x00 + #define VID_MSB_ADDR 0x02 + #define VID_LSB_ADDR 0x01 + #define PID_MSB_ADDR 0x04 + #define PID_LSB_ADDR 0x03 + #define MAC_0_ADDR 0x07 + #define MAC_1_ADDR 0x08 + #define MAC_2_ADDR 0x09 + #define MAC_3_ADDR 0x0a + #define MAC_4_ADDR 0x0b + #define MAC_5_ADDR 0x0c + +#define RESET_FX2 0x13 + +#define FW_VERSION_READ 0x0B +#define VENDOR_STRING_READ 0x0C +#define PRODUCT_STRING_READ 0x0D +#define FW_BCD_VERSION_READ 0x14 + +extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d); +extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec); +extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg); + +#endif -- cgit v1.2.3-70-g09d2 From f756ead1366092b73467fe3b1fb23f61034e94f9 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Thu, 23 Jun 2005 22:02:38 -0700 Subject: [PATCH] dvb-usb: fix init error checking Fix error checking during initialization. Thanks to Gerolf Wendland for discovering. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dibusb-mb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index fd103e4746e..a0ffbb59fa1 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -81,7 +81,7 @@ static int dibusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 || - dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) || + dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) == 0 || dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0) return 0; -- cgit v1.2.3-70-g09d2 From 68293ddbabb26a58ddb0a84aa5058a7acd7127e7 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Thu, 7 Jul 2005 17:58:06 -0700 Subject: [PATCH] dvb: dvb-usb: support Artect T1 with broken USB ids Add #define for device with broken USB ids. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dibusb-mb.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index a0ffbb59fa1..494e1227cb7 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -115,6 +115,12 @@ static struct usb_device_id dibusb_dib3000mb_table [] = { /* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, /* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, /* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, + +// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs + +#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs +/* 25 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, +#endif { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); @@ -228,12 +234,22 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { } }, +#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs + .num_device_descs = 2, +#else .num_device_descs = 1, +#endif .devices = { { "Artec T1 USB1.1 TVBOX with AN2235", { &dibusb_dib3000mb_table[20], NULL }, { &dibusb_dib3000mb_table[21], NULL }, }, +#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs + { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", + { &dibusb_dib3000mb_table[25], NULL }, + { NULL }, + }, +#endif } }; -- cgit v1.2.3-70-g09d2 From 8945c8c3d207c7a69024c02d164f5ae790c5b7ba Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:07 -0700 Subject: [PATCH] dvb: usb: fix ADSTech Instant TV DVB-T USB2.0 support Fixed support for the ADSTech Instant TV DVB-T USB (2.0 version). Thanks to Gerolf Wendland for his support. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dibusb-mb.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 494e1227cb7..aee6263f07c 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -31,10 +31,17 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) return 0; } -/* some of the dibusb 1.1 device aren't equipped with the default tuner +static int dibusb_thomson_tuner_attach(struct dvb_usb_device *d) +{ + d->pll_addr = 0x61; + d->pll_desc = &dvb_pll_tua6010xs; + return 0; +} + +/* Some of the Artec 1.1 device aren't equipped with the default tuner * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures * this out. */ -static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d) +static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d) { u8 b[2] = { 0,0 }, b2[1]; int ret = 0; @@ -59,8 +66,7 @@ static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d) if (b2[0] == 0xfe) { info("this device has the Thomson Cable onboard. Which is default."); - d->pll_addr = 0x61; - d->pll_desc = &dvb_pll_tua6010xs; + dibusb_thomson_tuner_attach(d); } else { u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; info("this device has the Panasonic ENV77H11D5 onboard."); @@ -114,6 +120,8 @@ static struct usb_device_id dibusb_dib3000mb_table [] = { /* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, /* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, /* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, + +/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ /* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, // #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs @@ -140,7 +148,7 @@ static struct dvb_usb_properties dibusb1_1_properties = { .pid_filter_ctrl = dibusb_pid_filter_ctrl, .power_ctrl = dibusb_power_ctrl, .frontend_attach = dibusb_dib3000mb_frontend_attach, - .tuner_attach = dibusb_dib3000mb_tuner_attach, + .tuner_attach = dibusb_tuner_probe_and_attach, .rc_interval = DEFAULT_RC_INTERVAL, .rc_key_map = dibusb_rc_keys, @@ -212,7 +220,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { .pid_filter_ctrl = dibusb_pid_filter_ctrl, .power_ctrl = dibusb_power_ctrl, .frontend_attach = dibusb_dib3000mb_frontend_attach, - .tuner_attach = dibusb_dib3000mb_tuner_attach, + .tuner_attach = dibusb_tuner_probe_and_attach, .rc_interval = DEFAULT_RC_INTERVAL, .rc_key_map = dibusb_rc_keys, @@ -257,7 +265,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = { .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-adstech-usb2-01.fw", + .firmware = "dvb-usb-adstech-usb2-02.fw", .size_of_priv = sizeof(struct dibusb_state), @@ -266,7 +274,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = { .pid_filter_ctrl = dibusb_pid_filter_ctrl, .power_ctrl = dibusb2_0_power_ctrl, .frontend_attach = dibusb_dib3000mb_frontend_attach, - .tuner_attach = dibusb_dib3000mb_tuner_attach, + .tuner_attach = dibusb_thomson_tuner_attach, .rc_interval = DEFAULT_RC_INTERVAL, .rc_key_map = dibusb_rc_keys, @@ -288,11 +296,11 @@ static struct dvb_usb_properties dibusb2_0b_properties = { } }, - .num_device_descs = 2, + .num_device_descs = 1, .devices = { { "KWorld/ADSTech Instant DVB-T USB 2.0", { &dibusb_dib3000mb_table[23], NULL }, - { &dibusb_dib3000mb_table[24], NULL }, /* device ID with default DIBUSB2_0-firmware */ + { &dibusb_dib3000mb_table[24], NULL }, }, } }; -- cgit v1.2.3-70-g09d2 From 7f5fee57812c99c95edf6794a50413c75e99fd4d Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:08 -0700 Subject: [PATCH] dvb: usb: add isochronous streaming method Added isochronous-streaming method. Changed memory (de)allocation behaviour accordingly. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dvb-usb-common.h | 3 +- drivers/media/dvb/dvb-usb/dvb-usb-urb.c | 178 +++++++++++++++++++++++------ drivers/media/dvb/dvb-usb/dvb-usb.h | 24 +++- 3 files changed, 167 insertions(+), 38 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h index 67e0d73fbce..abf7d2f562b 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h @@ -15,11 +15,12 @@ extern int dvb_usb_debug; #define deb_info(args...) dprintk(dvb_usb_debug,0x01,args) #define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args) -#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args) +#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args) #define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args) #define deb_err(args...) dprintk(dvb_usb_debug,0x10,args) #define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args) #define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args) +#define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args) /* commonly used methods */ extern int usb_cypress_load_firmware(struct usb_device *, const char *, int); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c index 83d476fb410..dcd8c2f915f 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c @@ -24,6 +24,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, if ((ret = down_interruptible(&d->usb_sem))) return ret; + deb_xfer(">>> "); debug_dump(wbuf,wlen,deb_xfer); ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev, @@ -46,8 +47,10 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, if (ret) err("recv bulk message failed: %d",ret); - else + else { + deb_xfer("<<< "); debug_dump(rbuf,actlen,deb_xfer); + } } up(&d->usb_sem); @@ -61,12 +64,19 @@ int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len) } EXPORT_SYMBOL(dvb_usb_generic_write); -static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs) + +/* URB stuff for streaming */ +static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) { struct dvb_usb_device *d = urb->context; + int ptype = usb_pipetype(urb->pipe); + int i; + u8 *b; - deb_ts("bulk urb completed. feedcount: %d, status: %d, length: %d\n",d->feedcount,urb->status, - urb->actual_length); + deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n", + ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount, + urb->status,urb->actual_length,urb->transfer_buffer_length, + urb->number_of_packets,urb->error_count); switch (urb->status) { case 0: /* success */ @@ -81,11 +91,33 @@ static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs) break; } - if (d->feedcount > 0 && urb->actual_length > 0) { - if (d->state & DVB_USB_STATE_DVB) - dvb_dmx_swfilter(&d->demux, (u8*) urb->transfer_buffer,urb->actual_length); - } else - deb_ts("URB dropped because of feedcount.\n"); + if (d->feedcount > 0) { + if (d->state & DVB_USB_STATE_DVB) { + switch (ptype) { + case PIPE_ISOCHRONOUS: + b = (u8 *) urb->transfer_buffer; + for (i = 0; i < urb->number_of_packets; i++) { + if (urb->iso_frame_desc[i].status != 0) + deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status); + else if (urb->iso_frame_desc[i].actual_length > 0) { + dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset, + urb->iso_frame_desc[i].actual_length); + } + urb->iso_frame_desc[i].status = 0; + urb->iso_frame_desc[i].actual_length = 0; + } + debug_dump(b,20,deb_ts); + break; + case PIPE_BULK: + if (urb->actual_length > 0) + dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length); + break; + default: + err("unkown endpoint type in completition handler."); + return; + } + } + } usb_submit_urb(urb,GFP_ATOMIC); } @@ -94,7 +126,7 @@ int dvb_usb_urb_kill(struct dvb_usb_device *d) { int i; for (i = 0; i < d->urbs_submitted; i++) { - deb_info("killing URB no. %d.\n",i); + deb_ts("killing URB no. %d.\n",i); /* stop the URB */ usb_kill_urb(d->urb_list[i]); @@ -107,9 +139,9 @@ int dvb_usb_urb_submit(struct dvb_usb_device *d) { int i,ret; for (i = 0; i < d->urbs_initialized; i++) { - deb_info("submitting URB no. %d\n",i); + deb_ts("submitting URB no. %d\n",i); if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) { - err("could not submit URB no. %d - get them all back\n",i); + err("could not submit URB no. %d - get them all back",i); dvb_usb_urb_kill(d); return ret; } @@ -118,32 +150,78 @@ int dvb_usb_urb_submit(struct dvb_usb_device *d) return 0; } -static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d) +static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d) { - int i,bufsize = d->props.urb.count * d->props.urb.u.bulk.buffersize; + if (d->state & DVB_USB_STATE_URB_BUF) { + while (d->buf_num) { + d->buf_num--; + deb_mem("freeing buffer %d\n",d->buf_num); + usb_buffer_free(d->udev, d->buf_size, + d->buf_list[d->buf_num], d->dma_addr[d->buf_num]); + } + kfree(d->buf_list); + kfree(d->dma_addr); + } + + d->state &= ~DVB_USB_STATE_URB_BUF; - deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize); - /* allocate the actual buffer for the URBs */ - if ((d->buffer = usb_buffer_alloc(d->udev, bufsize, SLAB_ATOMIC, &d->dma_handle)) == NULL) { - deb_info("not enough memory for urb-buffer allocation.\n"); + return 0; +} + +static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size) +{ + d->buf_num = 0; + d->buf_size = size; + + deb_mem("all in all I will use %lu bytes for streaming\n",num*size); + + if ((d->buf_list = kmalloc(num*sizeof(u8 *), GFP_ATOMIC)) == NULL) + return -ENOMEM; + + if ((d->dma_addr = kmalloc(num*sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) { + kfree(d->buf_list); return -ENOMEM; } - deb_info("allocation successful\n"); - memset(d->buffer,0,bufsize); + memset(d->buf_list,0,num*sizeof(u8 *)); + memset(d->dma_addr,0,num*sizeof(dma_addr_t)); d->state |= DVB_USB_STATE_URB_BUF; + for (d->buf_num = 0; d->buf_num < num; d->buf_num++) { + deb_mem("allocating buffer %d\n",d->buf_num); + if (( d->buf_list[d->buf_num] = + usb_buffer_alloc(d->udev, size, SLAB_ATOMIC, + &d->dma_addr[d->buf_num]) ) == NULL) { + deb_mem("not enough memory for urb-buffer allocation.\n"); + dvb_usb_free_stream_buffers(d); + return -ENOMEM; + } + deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]); + memset(d->buf_list[d->buf_num],0,size); + } + deb_mem("allocation successful\n"); + + return 0; +} + +static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d) +{ + int i; + + if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count, + d->props.urb.u.bulk.buffersize)) < 0) + return i; + /* allocate the URBs */ for (i = 0; i < d->props.urb.count; i++) { - if (!(d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) { + if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL) return -ENOMEM; - } usb_fill_bulk_urb( d->urb_list[i], d->udev, usb_rcvbulkpipe(d->udev,d->props.urb.endpoint), - &d->buffer[i*d->props.urb.u.bulk.buffersize], + d->buf_list[i], d->props.urb.u.bulk.buffersize, - dvb_usb_bulk_urb_complete, d); + dvb_usb_urb_complete, d); d->urb_list[i]->transfer_flags = 0; d->urbs_initialized++; @@ -151,6 +229,47 @@ static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d) return 0; } +static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d) +{ + int i,j; + + if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count, + d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0) + return i; + + /* allocate the URBs */ + for (i = 0; i < d->props.urb.count; i++) { + struct urb *urb; + int frame_offset = 0; + if ((d->urb_list[i] = + usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL) + return -ENOMEM; + + urb = d->urb_list[i]; + + urb->dev = d->udev; + urb->context = d; + urb->complete = dvb_usb_urb_complete; + urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint); + urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; + urb->interval = d->props.urb.u.isoc.interval; + urb->number_of_packets = d->props.urb.u.isoc.framesperurb; + urb->transfer_buffer_length = d->buf_size; + urb->transfer_buffer = d->buf_list[i]; + urb->transfer_dma = d->dma_addr[i]; + + for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) { + urb->iso_frame_desc[j].offset = frame_offset; + urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize; + frame_offset += d->props.urb.u.isoc.framesize; + } + + d->urbs_initialized++; + } + return 0; + +} + int dvb_usb_urb_init(struct dvb_usb_device *d) { /* @@ -174,8 +293,7 @@ int dvb_usb_urb_init(struct dvb_usb_device *d) case DVB_USB_BULK: return dvb_usb_bulk_urb_init(d); case DVB_USB_ISOC: - err("isochronous transfer not yet implemented in dvb-usb."); - return -EINVAL; + return dvb_usb_isoc_urb_init(d); default: err("unkown URB-type for data transfer."); return -EINVAL; @@ -191,7 +309,7 @@ int dvb_usb_urb_exit(struct dvb_usb_device *d) if (d->state & DVB_USB_STATE_URB_LIST) { for (i = 0; i < d->urbs_initialized; i++) { if (d->urb_list[i] != NULL) { - deb_info("freeing URB no. %d.\n",i); + deb_mem("freeing URB no. %d.\n",i); /* free the URBs */ usb_free_urb(d->urb_list[i]); } @@ -202,10 +320,6 @@ int dvb_usb_urb_exit(struct dvb_usb_device *d) d->state &= ~DVB_USB_STATE_URB_LIST; } - if (d->state & DVB_USB_STATE_URB_BUF) - usb_buffer_free(d->udev, d->props.urb.u.bulk.buffersize * d->props.urb.count, - d->buffer, d->dma_handle); - - d->state &= ~DVB_USB_STATE_URB_BUF; + dvb_usb_free_stream_buffers(d); return 0; } diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index abcee1943f6..6c627e9ea64 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -189,6 +189,7 @@ struct dvb_usb_properties { struct { int framesperurb; int framesize; + int interval; } isoc; } u; } urb; @@ -207,19 +208,28 @@ struct dvb_usb_properties { * @udev: pointer to the device's struct usb_device. * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS- * streaming. - * @buffer: buffer used to streaming. - * @dma_handle: dma_addr_t for buffer. + * + * @buf_num: number of buffer allocated. + * @buf_size: size of each buffer in buf_list. + * @buf_list: array containing all allocate buffers for streaming. + * @dma_addr: list of dma_addr_t for each buffer in buf_list. + * * @urbs_initialized: number of URBs initialized. * @urbs_submitted: number of URBs submitted. + * * @feedcount: number of reqested feeds (used for streaming-activation) * @pid_filtering: is hardware pid_filtering used or not. + * * @usb_sem: semaphore of USB control messages (reading needs two messages) * @i2c_sem: semaphore for i2c-transfers + * * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB * @pll_addr: I2C address of the tuner for programming * @pll_init: array containing the initialization buffer * @pll_desc: pointer to the appropriate struct dvb_pll_desc - * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod + * + * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board + * * @dvb_adap: device's dvb_adapter. * @dmxdev: device's dmxdev. * @demux: device's software demuxer. @@ -253,8 +263,12 @@ struct dvb_usb_device { /* usb */ struct usb_device *udev; struct urb **urb_list; - u8 *buffer; - dma_addr_t dma_handle; + + int buf_num; + unsigned long buf_size; + u8 **buf_list; + dma_addr_t *dma_addr; + int urbs_initialized; int urbs_submitted; -- cgit v1.2.3-70-g09d2 From 22c6d93a73105fddd58796d7cb10f5f90ee2a338 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:10 -0700 Subject: [PATCH] dvb: usb: support Medion hybrid USB2.0 DVB-T/analogue box Add preliminary support for the Medion Hybrid USB2.0 DVB-T/Analogue box. Analogue part is not working yet (cx25842 --> ivtv?). Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/Kconfig | 16 ++ drivers/media/dvb/dvb-usb/Makefile | 3 + drivers/media/dvb/dvb-usb/cxusb.c | 287 ++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/cxusb.h | 30 ++++ drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 + 5 files changed, 338 insertions(+) create mode 100644 drivers/media/dvb/dvb-usb/cxusb.c create mode 100644 drivers/media/dvb/dvb-usb/cxusb.h (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 8aa32f6e447..1a69130a846 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -21,12 +21,14 @@ config DVB_USB_DEBUG config DVB_USB_A800 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" depends on DVB_USB + select DVB_DIB3000MC help Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. config DVB_USB_DIBUSB_MB tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" depends on DVB_USB + select DVB_DIB3000MB help Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-B demodulator. @@ -52,6 +54,7 @@ config DVB_USB_DIBUSB_MB config DVB_USB_DIBUSB_MC tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" depends on DVB_USB + select DVB_DIB3000MC help Support for 2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-C/P demodulator. @@ -66,12 +69,24 @@ config DVB_USB_DIBUSB_MC config DVB_USB_UMT_010 tristate "HanfTek UMT-010 DVB-T USB2.0 support" depends on DVB_USB + select DVB_DIB3000MC help Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. +config DVB_USB_CXUSB + tristate "Medion MD95700 hybrid USB2.0 (Conexant) support" + depends on DVB_USB + select DVB_CX22702 + help + Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently + only the DVB-T part is supported and MPEG2 data transfer are not working + :(. + config DVB_USB_DIGITV tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" depends on DVB_USB + select DVB_NXT6000 + select DVB_MT352 help Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver. @@ -87,6 +102,7 @@ config DVB_USB_VP7045 config DVB_USB_NOVA_T_USB2 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" depends on DVB_USB + select DVB_DIB3000MC help Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index d65b50f9abb..746d87ed6f3 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -27,4 +27,7 @@ obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o dvb-usb-digitv-objs = digitv.o obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o +dvb-usb-cxusb-objs = cxusb.o +obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o + EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c new file mode 100644 index 00000000000..0324807376c --- /dev/null +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -0,0 +1,287 @@ +/* DVB USB compliant linux driver for Conexant USB reference design. + * + * The Conexant reference design I saw on their website was only for analogue + * capturing (using the cx25842). The box I took to write this driver (reverse + * engineered) is the one labeled Medion MD95700. In addition to the cx25842 + * for analogue capturing it also has a cx22702 DVB-T demodulator on the main + * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard. + * + * Maybe it is a little bit premature to call this driver cxusb, but I assume + * the USB protocol is identical or at least inherited from the reference + * design, so it can be reused for the "analogue-only" device (if it will + * appear at all). + * + * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue + * part + * + * FIXME: We're getting a lock and signal, but the isochronous transfer is empty + * for DVB-T. + * + * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) + * + * 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 + */ +#include "cxusb.h" + +#include "cx22702.h" + +/* debug */ +int dvb_usb_cxusb_debug; +module_param_named(debug,dvb_usb_cxusb_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); + +static int cxusb_ctrl_msg(struct dvb_usb_device *d, + u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) +{ + int wo = (rbuf == NULL || rlen == 0); /* write-only */ + u8 sndbuf[1+wlen]; + memset(sndbuf,0,1+wlen); + + sndbuf[0] = cmd; + memcpy(&sndbuf[1],wbuf,wlen); + if (wo) + dvb_usb_generic_write(d,sndbuf,1+wlen); + else + dvb_usb_generic_rw(d,sndbuf,1+wlen,rbuf,rlen,0); + + return 0; +} + +/* I2C */ +static void cxusb_set_i2c_path(struct dvb_usb_device *d, enum cxusb_i2c_pathes path) +{ + struct cxusb_state *st = d->priv; + u8 o[2],i; + + if (path == st->cur_i2c_path) + return; + + o[0] = IOCTL_SET_I2C_PATH; + switch (path) { + case PATH_CX22702: + o[1] = 0; + break; + case PATH_TUNER_OTHER: + o[1] = 1; + break; + default: + err("unkown i2c path"); + return; + } + cxusb_ctrl_msg(d,CMD_IOCTL,o,2,&i,1); + + if (i != 0x01) + deb_info("i2c_path setting failed.\n"); + + st->cur_i2c_path = path; +} + +static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i; + + if (down_interruptible(&d->i2c_sem) < 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++) { + + switch (msg[i].addr) { + case 0x63: + cxusb_set_i2c_path(d,PATH_CX22702); + break; + default: + cxusb_set_i2c_path(d,PATH_TUNER_OTHER); + break; + } + + /* read request */ + if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len]; + obuf[0] = msg[i].len; + obuf[1] = msg[i+1].len; + obuf[2] = msg[i].addr; + memcpy(&obuf[3],msg[i].buf,msg[i].len); + + if (cxusb_ctrl_msg(d, CMD_I2C_READ, + obuf, 3+msg[i].len, + ibuf, 1+msg[i+1].len) < 0) + break; + + if (ibuf[0] != 0x08) + deb_info("i2c read could have been failed\n"); + + memcpy(msg[i+1].buf,&ibuf[1],msg[i+1].len); + + i++; + } else { /* write */ + u8 obuf[2+msg[i].len], ibuf; + obuf[0] = msg[i].addr; + obuf[1] = msg[i].len; + memcpy(&obuf[2],msg[i].buf,msg[i].len); + + if (cxusb_ctrl_msg(d,CMD_I2C_WRITE, obuf, 2+msg[i].len, &ibuf,1) < 0) + break; + if (ibuf != 0x08) + deb_info("i2c write could have been failed\n"); + } + } + + up(&d->i2c_sem); + return i; +} + +static u32 cxusb_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm cxusb_i2c_algo = { + .name = "Conexant USB I2C algorithm", + .id = I2C_ALGO_BIT, + .master_xfer = cxusb_i2c_xfer, + .functionality = cxusb_i2c_func, +}; + +static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + return 0; +} + +static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) +{ + return 0; +} + +struct cx22702_config cxusb_cx22702_config = { + .demod_address = 0x63, + + .pll_init = dvb_usb_pll_init_i2c, + .pll_set = dvb_usb_pll_set_i2c, +}; + +/* Callbacks for DVB USB */ +static int cxusb_tuner_attach(struct dvb_usb_device *d) +{ + u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 }; + d->pll_addr = 0x61; + memcpy(d->pll_init,bpll,4); + d->pll_desc = &dvb_pll_fmd1216me; + return 0; +} + +static int cxusb_frontend_attach(struct dvb_usb_device *d) +{ + u8 buf[2] = { 0x03, 0x00 }; + u8 b = 0; + + cxusb_ctrl_msg(d,0xde,&b,0,NULL,0); + cxusb_set_i2c_path(d,PATH_TUNER_OTHER); + cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1); + + if (usb_set_interface(d->udev,0,6) < 0) + err("set interface failed\n"); + + cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0); + cxusb_set_i2c_path(d,PATH_CX22702); + cxusb_ctrl_msg(d,CMD_POWER_ON, NULL, 0, &b, 1); + + if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL) + return 0; + + return -EIO; +} + +/* DVB USB Driver stuff */ +static struct dvb_usb_properties cxusb_properties; + +static int cxusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE); +} + +static struct usb_device_id cxusb_table [] = { + { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, + {} /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, cxusb_table); + +static struct dvb_usb_properties cxusb_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + + .size_of_priv = sizeof(struct cxusb_state), + + .streaming_ctrl = cxusb_streaming_ctrl, + .power_ctrl = cxusb_power_ctrl, + .frontend_attach = cxusb_frontend_attach, + .tuner_attach = cxusb_tuner_attach, + + .i2c_algo = &cxusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_ISOC, + .count = 5, + .endpoint = 0x02, + .u = { + .isoc = { + .framesperurb = 64, + .framesize = 940*3, + .interval = 1, + } + } + }, + + .num_device_descs = 1, + .devices = { + { "Medion MD95700 (MDUSBTV-HYBRID)", + { NULL }, + { &cxusb_table[0], NULL }, + }, + } +}; + +static struct usb_driver cxusb_driver = { + .owner = THIS_MODULE, + .name = "cxusb", + .probe = cxusb_probe, + .disconnect = dvb_usb_device_exit, + .id_table = cxusb_table, +}; + +/* module stuff */ +static int __init cxusb_module_init(void) +{ + int result; + if ((result = usb_register(&cxusb_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit cxusb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&cxusb_driver); +} + +module_init (cxusb_module_init); +module_exit (cxusb_module_exit); + +MODULE_AUTHOR("Patrick Boettcher "); +MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design"); +MODULE_VERSION("1.0-alpha"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h new file mode 100644 index 00000000000..1d79016e319 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/cxusb.h @@ -0,0 +1,30 @@ +#ifndef _DVB_USB_CXUSB_H_ +#define _DVB_USB_CXUSB_H_ + +#define DVB_USB_LOG_PREFIX "digitv" +#include "dvb-usb.h" + +extern int dvb_usb_cxusb_debug; +#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args) + +/* usb commands - some of it are guesses, don't have a reference yet */ +#define CMD_I2C_WRITE 0x08 +#define CMD_I2C_READ 0x09 + +#define CMD_IOCTL 0x0e +#define IOCTL_SET_I2C_PATH 0x02 + +#define CMD_POWER_OFF 0x50 +#define CMD_POWER_ON 0x51 + +enum cxusb_i2c_pathes { + PATH_UNDEF = 0x00, + PATH_CX22702 = 0x01, + PATH_TUNER_OTHER = 0x02, +}; + +struct cxusb_state { + enum cxusb_i2c_pathes cur_i2c_path; +}; + +#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index bcb34191868..de2463bae22 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -24,6 +24,7 @@ #define USB_VID_HANFTEK 0x15f4 #define USB_VID_HAUPPAUGE 0x2040 #define USB_VID_HYPER_PALTEK 0x1025 +#define USB_VID_MEDION 0x1660 #define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_TWINHAN 0x1822 #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 @@ -78,6 +79,7 @@ #define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 #define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01 #define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11 +#define USB_PID_MEDION_MD95700 0x0932 #endif -- cgit v1.2.3-70-g09d2 From c9b06fa47e1c1ff8704461c7fd6a99e3621ba0e6 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:11 -0700 Subject: [PATCH] dvb: usb: add module parm to disable remote control polling Add module parameter to deactive remote control polling. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dvb-usb-common.h | 1 + drivers/media/dvb/dvb-usb/dvb-usb-init.c | 4 ++++ drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 8 +++++++- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h index abf7d2f562b..7300489d3e2 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h @@ -12,6 +12,7 @@ #include "dvb-usb.h" extern int dvb_usb_debug; +extern int dvb_usb_disable_rc_polling; #define deb_info(args...) dprintk(dvb_usb_debug,0x01,args) #define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args) diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index 3aadec974cf..c3b3ae4f3ec 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -18,6 +18,10 @@ int dvb_usb_debug; module_param_named(debug,dvb_usb_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS); +int dvb_usb_disable_rc_polling; +module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644); +MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0)."); + /* general initialization functions */ int dvb_usb_exit(struct dvb_usb_device *d) { diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 9f1e23f82ba..f4038bf21c9 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -21,6 +21,10 @@ static void dvb_usb_read_remote_control(void *data) /* TODO: need a lock here. We can simply skip checking for the remote control if we're busy. */ + /* when the parameter has been set to 1 via sysfs while the driver was running */ + if (dvb_usb_disable_rc_polling) + return; + if (d->props.rc_query(d,&event,&state)) { err("error while querying for an remote control event."); goto schedule; @@ -85,7 +89,9 @@ schedule: int dvb_usb_remote_init(struct dvb_usb_device *d) { int i; - if (d->props.rc_key_map == NULL) + if (d->props.rc_key_map == NULL || + d->props.rc_query == NULL || + dvb_usb_disable_rc_polling) return 0; /* Initialise the remote-control structures.*/ -- cgit v1.2.3-70-g09d2 From 78c6e73f5a27f01e45e86a4e3d13863c9cce6374 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:13 -0700 Subject: [PATCH] dvb: usb: digitv-usb fixes Some more work on the digitv-usb driver: o MT352 initialization and PLL-programming o I2c-transfer fixed. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/digitv.c | 69 +++++++++++++------------------------- 1 file changed, 24 insertions(+), 45 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 5acf3fde952..f272d34f772 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -1,10 +1,9 @@ /* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0 * receiver * - * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) and - * Allan Third (allan.third@cs.man.ac.uk) + * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) * - * partly based on the SDK published by Nebula Electronics (TODO do we want this line ?) + * partly based on the SDK published by Nebula Electronics * * 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 @@ -95,41 +94,20 @@ static int digitv_identify_state (struct usb_device *udev, struct static int digitv_mt352_demod_init(struct dvb_frontend *fe) { - static u8 mt352_clock_config[] = { 0x89, 0x38, 0x2d }; - static u8 mt352_reset[] = { 0x50, 0x80 }; - static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 }; - - static u8 mt352_agc_cfg[] = { 0x68, 0xa0 }; - static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0xa0 }; - static u8 mt352_acq_ctl[] = { 0x53, 0x50 }; - static u8 mt352_agc_target[] = { 0x67, 0x20 }; - - static u8 mt352_rs_err_per[] = { 0x7c, 0x00, 0x01 }; - static u8 mt352_snr_select[] = { 0x79, 0x00, 0x20 }; - - static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x05 }; + static u8 reset_buf[] = { 0x89, 0x38, 0x8a, 0x2d, 0x50, 0x80 }; + static u8 init_buf[] = { 0x68, 0xa0, 0x8e, 0x40, 0x53, 0x50, + 0x67, 0x20, 0x7d, 0x01, 0x7c, 0x00, 0x7a, 0x00, + 0x79, 0x20, 0x57, 0x05, 0x56, 0x31, 0x88, 0x0f, + 0x75, 0x32 }; + int i; - static u8 mt352_scan_ctl[] = { 0x88, 0x0f }; - static u8 mt352_capt_range[] = { 0x75, 0x32 }; + for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2) + mt352_write(fe, &reset_buf[i], 2); - mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); - mt352_write(fe, mt352_reset, sizeof(mt352_reset)); msleep(1); - mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio)); - - mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); - mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); - mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl)); - mt352_write(fe, mt352_agc_target, sizeof(mt352_agc_target)); - - - mt352_write(fe, mt352_rs_err_per, sizeof(mt352_rs_err_per)); - mt352_write(fe, mt352_snr_select, sizeof(mt352_snr_select)); - mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1)); - - mt352_write(fe, mt352_scan_ctl, sizeof(mt352_scan_ctl)); - mt352_write(fe, mt352_capt_range, sizeof(mt352_capt_range)); + for (i = 0; i < ARRAY_SIZE(init_buf); i += 2) + mt352_write(fe, &init_buf[i], 2); return 0; } @@ -137,7 +115,7 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe) static struct mt352_config digitv_mt352_config = { .demod_address = 0x0, /* ignored by the digitv anyway */ .demod_init = digitv_mt352_demod_init, - .pll_set = NULL, /* TODO */ + .pll_set = dvb_usb_pll_set, }; static struct nxt6000_config digitv_nxt6000_config = { @@ -150,9 +128,9 @@ static struct nxt6000_config digitv_nxt6000_config = { static int digitv_frontend_attach(struct dvb_usb_device *d) { - if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) == NULL) + if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) return 0; - if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) == NULL) { + if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) { warn("nxt6000 support is not done yet, in fact you are one of the first " "person who wants to use this device in Linux. Please report to " @@ -163,6 +141,13 @@ static int digitv_frontend_attach(struct dvb_usb_device *d) return -EIO; } +static int digitv_tuner_attach(struct dvb_usb_device *d) +{ + d->pll_addr = 0x60; + d->pll_desc = &dvb_pll_tded4; + return 0; +} + static struct dvb_usb_rc_key digitv_rc_keys[] = { { 0x00, 0x16, KEY_POWER }, /* dummy key */ }; @@ -184,7 +169,6 @@ int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) return 0; } - /* DVB USB Driver stuff */ static struct dvb_usb_properties digitv_properties; @@ -208,13 +192,8 @@ static struct dvb_usb_properties digitv_properties = { .size_of_priv = 0, - .streaming_ctrl = NULL, - .pid_filter = NULL, - .pid_filter_ctrl = NULL, - .power_ctrl = NULL, .frontend_attach = digitv_frontend_attach, - .tuner_attach = NULL, // digitv_tuner_attach, - .read_mac_address = NULL, + .tuner_attach = digitv_tuner_attach, .rc_interval = 1000, .rc_key_map = digitv_rc_keys, @@ -238,7 +217,7 @@ static struct dvb_usb_properties digitv_properties = { } }, - .num_device_descs = 2, + .num_device_descs = 1, .devices = { { "Nebula Electronics uDigiTV DVB-T USB2.0)", { &digitv_table[0], NULL }, -- cgit v1.2.3-70-g09d2 From c251ef6167c46152e247fc41628a4ac2d0aca33e Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:14 -0700 Subject: [PATCH] dvb: usb: dvb_usb_properties init fix There was no pid-filter-count set for some devices - led to an error. Thanks to Gerolf Wendland. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dibusb-mb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index aee6263f07c..691900578ee 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -209,6 +209,8 @@ static struct dvb_usb_properties dibusb1_1_properties = { static struct dvb_usb_properties dibusb1_1_an2235_properties = { .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 16, + .usb_ctrl = CYPRESS_AN2235, .firmware = "dvb-usb-dibusb-an2235-01.fw", @@ -263,6 +265,8 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { static struct dvb_usb_properties dibusb2_0b_properties = { .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, + .pid_filter_count = 32, + .usb_ctrl = CYPRESS_FX2, .firmware = "dvb-usb-adstech-usb2-02.fw", -- cgit v1.2.3-70-g09d2 From 8257e8a444a2b81952de9f8bfeb3a4726c0f7d5b Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:15 -0700 Subject: [PATCH] dvb: usb: cxusb DVB-T fixes cxusb DVB-T fixes. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/cxusb.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 0324807376c..b4bb206a510 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -14,9 +14,6 @@ * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue * part * - * FIXME: We're getting a lock and signal, but the isochronous transfer is empty - * for DVB-T. - * * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) * * This program is free software; you can redistribute it and/or modify it @@ -157,12 +154,20 @@ static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) { + u8 buf[2] = { 0x03, 0x00 }; + if (onoff) + cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0); + else + cxusb_ctrl_msg(d,0x37, NULL, 0, NULL, 0); + return 0; } struct cx22702_config cxusb_cx22702_config = { .demod_address = 0x63, + .output_mode = CX22702_PARALLEL_OUTPUT, + .pll_init = dvb_usb_pll_init_i2c, .pll_set = dvb_usb_pll_set_i2c, }; @@ -182,12 +187,15 @@ static int cxusb_frontend_attach(struct dvb_usb_device *d) u8 buf[2] = { 0x03, 0x00 }; u8 b = 0; + if (usb_set_interface(d->udev,0,0) < 0) + err("set interface to alts=0 failed"); + cxusb_ctrl_msg(d,0xde,&b,0,NULL,0); cxusb_set_i2c_path(d,PATH_TUNER_OTHER); cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1); if (usb_set_interface(d->udev,0,6) < 0) - err("set interface failed\n"); + err("set interface failed"); cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0); cxusb_set_i2c_path(d,PATH_CX22702); @@ -236,9 +244,9 @@ static struct dvb_usb_properties cxusb_properties = { .endpoint = 0x02, .u = { .isoc = { - .framesperurb = 64, - .framesize = 940*3, - .interval = 1, + .framesperurb = 32, + .framesize = 940, + .interval = 5, } } }, -- cgit v1.2.3-70-g09d2 From 2f7f96b95991bcbe52dee5aa50a19130873738bf Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:16 -0700 Subject: [PATCH] dvb: usb: add VideoWalker DVB-T USB ids Add another USB ID pair for the VideoWalker USB DVB-T. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dibusb-mb.c | 12 +++++++++--- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 3 +++ drivers/media/dvb/dvb-usb/dvb-usb.h | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 691900578ee..1cd49025289 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -123,11 +123,13 @@ static struct usb_device_id dibusb_dib3000mb_table [] = { /* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ /* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, +/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, +/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, // #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs -/* 25 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, +/* 27 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, #endif { } /* Terminating entry */ }; @@ -170,7 +172,7 @@ static struct dvb_usb_properties dibusb1_1_properties = { } }, - .num_device_descs = 8, + .num_device_descs = 9, .devices = { { "AVerMedia AverTV DVBT USB1.1", { &dibusb_dib3000mb_table[0], NULL }, @@ -204,6 +206,10 @@ static struct dvb_usb_properties dibusb1_1_properties = { { &dibusb_dib3000mb_table[19], NULL }, { &dibusb_dib3000mb_table[20], NULL }, }, + { "VideoWalker DVB-T USB", + { &dibusb_dib3000mb_table[25], NULL }, + { &dibusb_dib3000mb_table[26], NULL }, + }, } }; @@ -256,7 +262,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { }, #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", - { &dibusb_dib3000mb_table[25], NULL }, + { &dibusb_dib3000mb_table[27], NULL }, { NULL }, }, #endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index de2463bae22..9fea93df6ab 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -24,6 +24,7 @@ #define USB_VID_HANFTEK 0x15f4 #define USB_VID_HAUPPAUGE 0x2040 #define USB_VID_HYPER_PALTEK 0x1025 +#define USB_VID_KYE 0x0458 #define USB_VID_MEDION 0x1660 #define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_TWINHAN 0x1822 @@ -80,6 +81,8 @@ #define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01 #define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11 #define USB_PID_MEDION_MD95700 0x0932 +#define USB_PID_KYE_DVB_T_COLD 0x701e +#define USB_PID_KYE_DVB_T_WARM 0x701f #endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 6c627e9ea64..a80567caf50 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -195,7 +195,7 @@ struct dvb_usb_properties { } urb; int num_device_descs; - struct dvb_usb_device_description devices[8]; + struct dvb_usb_device_description devices[9]; }; -- cgit v1.2.3-70-g09d2 From 97432808ee367e15485e55c734ba04ca290a306d Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:17 -0700 Subject: [PATCH] dvb: usb: digitv memcpy fix Fix memcpy copying into the wrong destination. Thanks to Allan Third for reporting. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/digitv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index f272d34f772..8155a26f0dd 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -37,7 +37,7 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d, dvb_usb_generic_write(d,sndbuf,7); } else { dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10); - memcpy(&rbuf,&rcvbuf[3],rlen); + memcpy(rbuf,&rcvbuf[3],rlen); } return 0; } -- cgit v1.2.3-70-g09d2 From d72fa1c91d721bf4c68a18f2d8fed820a8f1611e Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:20 -0700 Subject: [PATCH] dvb: usb Kconfig help text update o corrected some typos o added the Wikilink pointing to the USB device list Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/Kconfig | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 1a69130a846..d4deb75352c 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -3,19 +3,22 @@ config DVB_USB depends on DVB_CORE && USB select FW_LOADER help - By enabling this you will be able to choose the various USB 1.1 and - USB2.0 DVB devices. + By enabling this you will be able to choose the various supported + USB1.1 and USB2.0 DVB devices. Almost every USB device needs a firmware, please look into - + . - Say Y if you own an USB DVB device. + For a complete list of supported USB devices see the LinuxTV DVB Wiki: + + + Say Y if you own a USB DVB device. config DVB_USB_DEBUG bool "Enable extended debug support for all DVB-USB devices" depends on DVB_USB help - Say Y if you want to enable debuging. See modinfo dvb-usb (and the + Say Y if you want to enable debugging. See modinfo dvb-usb (and the appropriate drivers) for debug levels. config DVB_USB_A800 @@ -79,8 +82,7 @@ config DVB_USB_CXUSB select DVB_CX22702 help Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently - only the DVB-T part is supported and MPEG2 data transfer are not working - :(. + only the DVB-T part is supported. config DVB_USB_DIGITV tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" -- cgit v1.2.3-70-g09d2 From 2d188c68a04d89d9351c3130226d0e8af9439dda Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:21 -0700 Subject: [PATCH] dvb: usb: add vp7045 IR keymap Add keymap for Twinhan vp7045 remote control. Signed-off-by: Michael Paxton Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/dvb/README.dvb-usb | 4 +++- drivers/media/dvb/dvb-usb/vp7045.c | 39 +++++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 8 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb index 5811d48e4d7..4dfe812ca33 100644 --- a/Documentation/dvb/README.dvb-usb +++ b/Documentation/dvb/README.dvb-usb @@ -226,7 +226,9 @@ Patches, comments and suggestions are very very welcome. Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by writing the vp7045-driver. - Some guys on the linux-dvb mailing list for encouraging me + Michael Paxton for submitting remote control keymaps. + + Some guys on the linux-dvb mailing list for encouraging me. Peter Schildmann >peter.schildmann-nospam-at-web.de< for his user-level firmware loader, which saves a lot of time diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 02ecc9a8e3b..bb99cbc098f 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -94,13 +94,38 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff) /* The keymapping struct. Somehow this should be loaded to the driver, but * currently it is hardcoded. */ static struct dvb_usb_rc_key vp7045_rc_keys[] = { - /* insert the keys like this. to make the raw keys visible, enable - * debug=0x04 when loading dvb-usb-vp7045. */ - - /* these keys are probably wrong. I don't have a working IR-receiver on my - * vp7045, so I can't test it. Patches are welcome. */ - { 0x00, 0x01, KEY_1 }, - { 0x00, 0x02, KEY_2 }, + { 0x00, 0x16, KEY_POWER }, + { 0x00, 0x10, KEY_MUTE }, + { 0x00, 0x03, KEY_1 }, + { 0x00, 0x01, KEY_2 }, + { 0x00, 0x06, KEY_3 }, + { 0x00, 0x09, KEY_4 }, + { 0x00, 0x1d, KEY_5 }, + { 0x00, 0x1f, KEY_6 }, + { 0x00, 0x0d, KEY_7 }, + { 0x00, 0x19, KEY_8 }, + { 0x00, 0x1b, KEY_9 }, + { 0x00, 0x15, KEY_0 }, + { 0x00, 0x05, KEY_CHANNELUP }, + { 0x00, 0x02, KEY_CHANNELDOWN }, + { 0x00, 0x1e, KEY_VOLUMEUP }, + { 0x00, 0x0a, KEY_VOLUMEDOWN }, + { 0x00, 0x11, KEY_RECORD }, + { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */ + { 0x00, 0x14, KEY_PLAY }, + { 0x00, 0x1a, KEY_STOP }, + { 0x00, 0x40, KEY_REWIND }, + { 0x00, 0x12, KEY_FASTFORWARD }, + { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */ + { 0x00, 0x4c, KEY_PAUSE }, + { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */ + { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ + { 0x00, 0xa1, KEY_CANCEL }, /* Cancel */ + { 0x00, 0x1c, KEY_EPG }, /* EPG */ + { 0x00, 0x40, KEY_TAB }, /* Tab */ + { 0x00, 0x48, KEY_INFO }, /* Preview */ + { 0x00, 0x04, KEY_LIST }, /* RecordList */ + { 0x00, 0x0f, KEY_TEXT } /* Teletext */ }; static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state) -- cgit v1.2.3-70-g09d2 From fb41f5a725d052d7542e0e966e5799b95c2648c8 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:23 -0700 Subject: [PATCH] dvb: usb: fix WideView USB ids o Steve Chang reported the real name behind 0x14aa: WideView, changed USB IDs accordingly. o fixed an assignment Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/Kconfig | 4 ++-- drivers/media/dvb/dvb-usb/dibusb-mb.c | 4 ++-- drivers/media/dvb/dvb-usb/dtt200u-fe.c | 4 ++-- drivers/media/dvb/dvb-usb/dtt200u.c | 16 ++++++++-------- drivers/media/dvb/dvb-usb/dtt200u.h | 4 ++-- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index d4deb75352c..91e88b2ed5d 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -109,9 +109,9 @@ config DVB_USB_NOVA_T_USB2 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. config DVB_USB_DTT200U - tristate "Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support" + tristate "WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support" depends on DVB_USB help - Say Y here to support the Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver. + Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver. The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 1cd49025289..cda2179d61a 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -96,8 +96,8 @@ static int dibusb_probe(struct usb_interface *intf, /* do not change the order of the ID table */ static struct usb_device_id dibusb_dib3000mb_table [] = { -/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, -/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, +/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, +/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, /* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, /* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, /* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c index d17d768038c..7807f33573b 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c @@ -1,5 +1,5 @@ -/* Frontend part of the Linux driver for the Yakumo/Hama/Typhoon DVB-T - * USB2.0 receiver. +/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/ + * Typhoon/ Yuan DVB-T USB2.0 receiver. * * Copyright (C) 2005 Patrick Boettcher * diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index fb2b5a2da13..1ebd3eff96d 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c @@ -1,5 +1,5 @@ -/* DVB USB library compliant Linux driver for the Yakumo/Hama/Typhoon DVB-T - * USB2.0 receiver. +/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/ + * Typhoon/ Yuan DVB-T USB2.0 receiver. * * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) * @@ -89,8 +89,8 @@ static int dtt200u_usb_probe(struct usb_interface *intf, } static struct usb_device_id dtt200u_usb_table [] = { - { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_COLD) }, - { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_WARM) }, + { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) }, + { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) }, { 0 }, }; MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); @@ -127,8 +127,8 @@ static struct dvb_usb_properties dtt200u_properties = { .num_device_descs = 1, .devices = { - { .name = "Yakumo/Hama/Typhoon DVB-T USB2.0)", - .cold_ids = { &dtt200u_usb_table[0], &dtt200u_usb_table[2] }, + { .name = "WideView/Yakumo/Hama/Typhoon DVB-T USB2.0)", + .cold_ids = { &dtt200u_usb_table[0], NULL }, .warm_ids = { &dtt200u_usb_table[1], NULL }, }, { 0 }, @@ -138,7 +138,7 @@ static struct dvb_usb_properties dtt200u_properties = { /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver dtt200u_usb_driver = { .owner = THIS_MODULE, - .name = "Yakumo/Hama/Typhoon DVB-T USB2.0", + .name = "dtt200u", .probe = dtt200u_usb_probe, .disconnect = dvb_usb_device_exit, .id_table = dtt200u_usb_table, @@ -166,6 +166,6 @@ module_init(dtt200u_usb_module_init); module_exit(dtt200u_usb_module_exit); MODULE_AUTHOR("Patrick Boettcher "); -MODULE_DESCRIPTION("Driver for the Yakumo/Hama/Typhoon DVB-T USB2.0 device"); +MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 device"); MODULE_VERSION("1.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h index ed414207151..9ab081a55b8 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.h +++ b/drivers/media/dvb/dvb-usb/dtt200u.h @@ -1,5 +1,5 @@ -/* Common header file of Linux driver for the Yakumo/Hama/Typhoon DVB-T - * USB2.0 receiver. +/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/ + * Typhoon/ Yuan DVB-T USB2.0 receiver. * * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) * diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 9fea93df6ab..75f4cb18a63 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -12,7 +12,7 @@ /* Vendor IDs */ #define USB_VID_ADSTECH 0x06e1 #define USB_VID_ANCHOR 0x0547 -#define USB_VID_AVERMEDIA_UNK 0x14aa +#define USB_VID_WIDEVIEW 0x14aa #define USB_VID_AVERMEDIA 0x07ca #define USB_VID_COMPRO 0x185b #define USB_VID_COMPRO_UNK 0x145f -- cgit v1.2.3-70-g09d2 From 04f3e5ea51248ff974a13ef2dd0145125c76204c Mon Sep 17 00:00:00 2001 From: Michael Paxton Date: Thu, 7 Jul 2005 17:58:24 -0700 Subject: [PATCH] dvb: usb: vp7045 IR map fix Correct two keys of the vp7045 remote control key mapping. Signed-off-by: Michael Paxton Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/vp7045.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index bb99cbc098f..72d5d3f7446 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -120,9 +120,9 @@ static struct dvb_usb_rc_key vp7045_rc_keys[] = { { 0x00, 0x4c, KEY_PAUSE }, { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */ { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ - { 0x00, 0xa1, KEY_CANCEL }, /* Cancel */ + { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */ { 0x00, 0x1c, KEY_EPG }, /* EPG */ - { 0x00, 0x40, KEY_TAB }, /* Tab */ + { 0x00, 0x00, KEY_TAB }, /* Tab */ { 0x00, 0x48, KEY_INFO }, /* Preview */ { 0x00, 0x04, KEY_LIST }, /* RecordList */ { 0x00, 0x0f, KEY_TEXT } /* Teletext */ -- cgit v1.2.3-70-g09d2 From 1df896aa239caf72483655290c40b21da536d85e Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:24 -0700 Subject: [PATCH] dvb: usb: IR input fixes o fixed usage of the correct number of events in keymapping-array o better place for return Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index f4038bf21c9..fc7800f1743 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -39,7 +39,7 @@ static void dvb_usb_read_remote_control(void *data) d->last_event = event; case REMOTE_KEY_REPEAT: deb_rc("key repeated\n"); - input_event(&d->rc_input_dev, EV_KEY, event, 1); + input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1); input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0); input_sync(&d->rc_input_dev); break; @@ -160,12 +160,12 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, break; } /* See if we can match the raw key code. */ - for (i = 0; i < sizeof(keymap)/sizeof(struct dvb_usb_rc_key); i++) + for (i = 0; i < d->props.rc_key_map_size; i++) if (keymap[i].custom == keybuf[1] && keymap[i].data == keybuf[3]) { *event = keymap[i].event; *state = REMOTE_KEY_PRESSED; - break; + return 0; } deb_err("key mapping failed - no appropriate key found in keymapping\n"); break; -- cgit v1.2.3-70-g09d2 From 58769a5486bec8ed44b3b51029f8df8f13cddd5a Mon Sep 17 00:00:00 2001 From: Andrew Hodgson Date: Thu, 7 Jul 2005 17:58:26 -0700 Subject: [PATCH] dvb: usb: A800 rc and timeout fixes o add some remote control codes o not using HZ for control_msg-timeout Signed-off-by: Andrew Hodgson Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/a800.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index a3542935604..672037c2281 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c @@ -61,6 +61,12 @@ static struct dvb_usb_rc_key a800_rc_keys[] = { { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */ { 0x02, 0x04, KEY_EPG }, /* EPG */ { 0x02, 0x15, KEY_MENU }, /* MENU */ + + { 0x03, 0x03, KEY_CHANNELUP }, /* CH UP */ + { 0x03, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */ + { 0x03, 0x01, KEY_FIRST }, /* |<< / GREEN */ + { 0x03, 0x00, KEY_LAST }, /* >>| / BLUE */ + }; int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) @@ -68,7 +74,7 @@ int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) u8 key[5]; if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0), 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5, - 2*HZ) != 5) + 2000) != 5) return -ENODEV; /* call the universal NEC remote processor, to find out the key's state and event */ -- cgit v1.2.3-70-g09d2 From e161f817bebecc1c1cc461dc83cce2eafbed9ee9 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:27 -0700 Subject: [PATCH] dvb: usb: dont use HZ for timeouts Don't use HZ for usb-transfer-timeouts. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dvb-usb-urb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c index dcd8c2f915f..f5799a4c228 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c @@ -29,7 +29,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen, - 2*HZ); + 2000); if (ret) err("bulk message failed: %d (%d/%d)",ret,wlen,actlen); @@ -43,7 +43,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen, - 2*HZ); + 2000); if (ret) err("recv bulk message failed: %d",ret); -- cgit v1.2.3-70-g09d2 From 63b5c1c47fd6c5ae26d279756e8a050c721ea379 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:30 -0700 Subject: [PATCH] dvb: usb/pci: correct syntax of driver name fields Change the name-field of the pci_driver and usb_driver structs to the name of the module after compilation. It seems that this field is used in some places where special characters are not allowed. Thanks to Alan Halverson for finding this problem. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/b2c2/flexcop-pci.c | 2 +- drivers/media/dvb/b2c2/flexcop-usb.c | 2 +- drivers/media/dvb/dvb-usb/a800.c | 2 +- drivers/media/dvb/dvb-usb/cxusb.c | 2 +- drivers/media/dvb/dvb-usb/dibusb-mb.c | 2 +- drivers/media/dvb/dvb-usb/dibusb-mc.c | 2 +- drivers/media/dvb/dvb-usb/digitv.c | 2 +- drivers/media/dvb/dvb-usb/nova-t-usb2.c | 2 +- drivers/media/dvb/dvb-usb/umt-010.c | 2 +- drivers/media/dvb/dvb-usb/vp7045.c | 6 +++--- 10 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index a436d5584ea..2f76eb3fea4 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c @@ -409,7 +409,7 @@ static struct pci_device_id flexcop_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl); static struct pci_driver flexcop_pci_driver = { - .name = "Technisat/B2C2 FlexCop II/IIb PCI", + .name = "b2c2_flexcop_pci", .id_table = flexcop_pci_tbl, .probe = flexcop_pci_probe, .remove = flexcop_pci_remove, diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 0113449abd1..0a78ba3737a 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c @@ -545,7 +545,7 @@ static struct usb_device_id flexcop_usb_table [] = { /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver flexcop_usb_driver = { .owner = THIS_MODULE, - .name = "Technisat/B2C2 FlexCop II/IIb/III USB", + .name = "b2c2_flexcop_usb", .probe = flexcop_usb_probe, .disconnect = flexcop_usb_disconnect, .id_table = flexcop_usb_table, diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index 672037c2281..f2fcc2f1f84 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c @@ -149,7 +149,7 @@ static struct dvb_usb_properties a800_properties = { static struct usb_driver a800_driver = { .owner = THIS_MODULE, - .name = "AVerMedia AverTV DVB-T USB 2.0 (A800)", + .name = "dvb_usb_a800", .probe = a800_probe, .disconnect = dvb_usb_device_exit, .id_table = a800_table, diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index b4bb206a510..c3e1b661aae 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -262,7 +262,7 @@ static struct dvb_usb_properties cxusb_properties = { static struct usb_driver cxusb_driver = { .owner = THIS_MODULE, - .name = "cxusb", + .name = "dvb_usb_cxusb", .probe = cxusb_probe, .disconnect = dvb_usb_device_exit, .id_table = cxusb_table, diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index cda2179d61a..828b5182e16 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -317,7 +317,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = { static struct usb_driver dibusb_driver = { .owner = THIS_MODULE, - .name = "DiBcom based USB DVB-T devices (DiB3000M-B based)", + .name = "dvb_usb_dibusb_mb", .probe = dibusb_probe, .disconnect = dvb_usb_device_exit, .id_table = dibusb_dib3000mb_table, diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c index aad8ed3fe00..e9dac430f37 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mc.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c @@ -83,7 +83,7 @@ static struct dvb_usb_properties dibusb_mc_properties = { static struct usb_driver dibusb_mc_driver = { .owner = THIS_MODULE, - .name = "DiBcom based USB2.0 DVB-T (DiB3000M-C/P based) devices", + .name = "dvb_usb_dibusb_mc", .probe = dibusb_mc_probe, .disconnect = dvb_usb_device_exit, .id_table = dibusb_dib3000mc_table, diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 8155a26f0dd..9a676afc1d6 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -228,7 +228,7 @@ static struct dvb_usb_properties digitv_properties = { static struct usb_driver digitv_driver = { .owner = THIS_MODULE, - .name = "Nebula Electronics uDigiTV DVB-T USB2.0 device", + .name = "dvb_usb_digitv", .probe = digitv_probe, .disconnect = dvb_usb_device_exit, .id_table = digitv_table, diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index 9d83781aef9..258a92bfbcc 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -203,7 +203,7 @@ static struct dvb_usb_properties nova_t_properties = { static struct usb_driver nova_t_driver = { .owner = THIS_MODULE, - .name = "Hauppauge WinTV-NOVA-T usb2", + .name = "dvb_usb_nova_t_usb2", .probe = nova_t_probe, .disconnect = dvb_usb_device_exit, .id_table = nova_t_table, diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c index aa560422ce7..2112ac3cf5e 100644 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ b/drivers/media/dvb/dvb-usb/umt-010.c @@ -129,7 +129,7 @@ static struct dvb_usb_properties umt_properties = { static struct usb_driver umt_driver = { .owner = THIS_MODULE, - .name = "HanfTek UMT-010 USB2.0 DVB-T devices", + .name = "dvb_usb_umt_010", .probe = umt_probe, .disconnect = dvb_usb_device_exit, .id_table = umt_table, diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 72d5d3f7446..5adc5d69ec8 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -44,7 +44,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, if (usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0), TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, - outbuf, 20, 2*HZ) != 20) { + outbuf, 20, 2000) != 20) { err("USB control message 'out' went wrong."); ret = -EIO; goto unlock; @@ -55,7 +55,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, if (usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, - inbuf, 12, 2*HZ) != 12) { + inbuf, 12, 2000) != 12) { err("USB control message 'in' went wrong."); ret = -EIO; goto unlock; @@ -255,7 +255,7 @@ static struct dvb_usb_properties vp7045_properties = { /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver vp7045_usb_driver = { .owner = THIS_MODULE, - .name = "dvb-usb-vp7045", + .name = "dvb_usb_vp7045", .probe = vp7045_usb_probe, .disconnect = dvb_usb_device_exit, .id_table = vp7045_usb_table, -- cgit v1.2.3-70-g09d2 From d590f9c20e15620ba708e5bd71d345bf1b7b0d73 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Thu, 7 Jul 2005 17:58:33 -0700 Subject: [PATCH] dvb: usb: add supprt for WideView WT-220U Add support and rewrote some parts with the help of vendor information (Thanks to Steve Chang from WideView, Inc.): o added support for the WT-220U (Pensize DVB-T receiver) o corrected byte order for unc,ber and the pid filter o corrected number of pids that can be fetched at the same time. o added some comments in Kconfig-file o added USB IDs for the WT-220U Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/Kconfig | 4 +- drivers/media/dvb/dvb-usb/dtt200u-fe.c | 72 +++++++++++++-------------- drivers/media/dvb/dvb-usb/dtt200u.c | 86 ++++++++++++++++++++++++++++----- drivers/media/dvb/dvb-usb/dtt200u.h | 38 ++++++--------- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 3 +- 5 files changed, 130 insertions(+), 73 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 91e88b2ed5d..612e5b087b1 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -109,9 +109,11 @@ config DVB_USB_NOVA_T_USB2 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. config DVB_USB_DTT200U - tristate "WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support" + tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)" depends on DVB_USB help Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver. The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). + + The WT-220U and its clones are pen-sized. diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c index 7807f33573b..b032523b07b 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c @@ -14,61 +14,58 @@ struct dtt200u_fe_state { struct dvb_usb_device *d; + fe_status_t stat; + struct dvb_frontend_parameters fep; struct dvb_frontend frontend; }; -#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what) - static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) { struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw = GET_TUNE_STAT; - u8 br[3] = { 0 }; -// u8 bdeb[5] = { 0 }; + u8 st = GET_TUNE_STATUS, b[3]; + + dvb_usb_generic_rw(state->d,&st,1,b,3,0); - dvb_usb_generic_rw(state->d,&bw,1,br,3,0); - switch (br[0]) { + switch (b[0]) { case 0x01: - *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; break; - case 0x00: - *stat = 0; + case 0x00: /* pending */ + *stat = FE_TIMEDOUT; /* during set_frontend */ break; default: - moan("br[0]",GET_TUNE_STAT); + case 0x02: /* failed */ + *stat = 0; break; } - -// bw[0] = 0x88; -// dvb_usb_generic_rw(state->d,bw,1,bdeb,5,0); - -// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]); - return 0; } + static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber) { struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw = GET_BER; - *ber = 0; - dvb_usb_generic_rw(state->d,&bw,1,(u8*) ber,3,0); + u8 bw = GET_VIT_ERR_CNT,b[3]; + dvb_usb_generic_rw(state->d,&bw,1,b,3,0); + *ber = (b[0] << 16) | (b[1] << 8) | b[2]; return 0; } static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) { struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw = GET_UNK; - *unc = 0; - dvb_usb_generic_rw(state->d,&bw,1,(u8*) unc,3,0); + u8 bw = GET_RS_UNCOR_BLK_CNT,b[2]; + + dvb_usb_generic_rw(state->d,&bw,1,b,2,0); + *unc = (b[0] << 8) | b[1]; return 0; } static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) { struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw = GET_SIG_STRENGTH, b; + u8 bw = GET_AGC, b; dvb_usb_generic_rw(state->d,&bw,1,&b,1,0); *strength = (b << 8) | b; return 0; @@ -86,7 +83,7 @@ static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr) static int dtt200u_fe_init(struct dvb_frontend* fe) { struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 b = RESET_DEMOD; + u8 b = SET_INIT; return dvb_usb_generic_write(state->d,&b,1); } @@ -98,8 +95,8 @@ static int dtt200u_fe_sleep(struct dvb_frontend* fe) static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) { tune->min_delay_ms = 1500; - tune->step_size = 166667; - tune->max_drift = 166667 * 2; + tune->step_size = 0; + tune->max_drift = 0; return 0; } @@ -107,27 +104,32 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { struct dtt200u_fe_state *state = fe->demodulator_priv; + int i; + fe_status_t st; u16 freq = fep->frequency / 250000; - u8 bw,bwbuf[2] = { SET_BANDWIDTH, 0 }, freqbuf[3] = { SET_FREQUENCY, 0, 0 }; + u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 }; switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: bw = 8; break; - case BANDWIDTH_7_MHZ: bw = 7; break; - case BANDWIDTH_6_MHZ: bw = 6; break; + case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break; + case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break; + case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break; case BANDWIDTH_AUTO: return -EOPNOTSUPP; default: return -EINVAL; } - deb_info("set_frontend\n"); - bwbuf[1] = bw; dvb_usb_generic_write(state->d,bwbuf,2); freqbuf[1] = freq & 0xff; freqbuf[2] = (freq >> 8) & 0xff; dvb_usb_generic_write(state->d,freqbuf,3); - memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters)); + for (i = 0; i < 30; i++) { + msleep(20); + dtt200u_fe_read_status(fe, &st); + if (st & FE_TIMEDOUT) + continue; + } return 0; } @@ -174,7 +176,7 @@ success: static struct dvb_frontend_ops dtt200u_fe_ops = { .info = { - .name = "DTT200U (Yakumo/Typhoon/Hama) DVB-T", + .name = "WideView USB DVB-T", .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index 1ebd3eff96d..47dba6e4596 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c @@ -3,6 +3,8 @@ * * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) * + * Thanks to Steve Chang from WideView for providing support for the WT-220U. + * * 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. @@ -16,14 +18,24 @@ int dvb_usb_dtt200u_debug; module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS); +static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 b = SET_INIT; + + if (onoff) + dvb_usb_generic_write(d,&b,2); + + return 0; +} + static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff) { - u8 b_streaming[2] = { SET_TS_CTRL, onoff }; + u8 b_streaming[2] = { SET_STREAMING, onoff }; u8 b_rst_pid = RESET_PID_FILTER; dvb_usb_generic_write(d,b_streaming,2); - if (!onoff) + if (onoff == 0) dvb_usb_generic_write(d,&b_rst_pid,1); return 0; } @@ -36,7 +48,7 @@ static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int b_pid[0] = SET_PID_FILTER; b_pid[1] = index; b_pid[2] = pid & 0xff; - b_pid[3] = (pid >> 8) & 0xff; + b_pid[3] = (pid >> 8) & 0x1f; return dvb_usb_generic_write(d,b_pid,4); } @@ -54,9 +66,9 @@ static struct dvb_usb_rc_key dtt200u_rc_keys[] = { { 0x80, 0x08, KEY_5 }, { 0x80, 0x09, KEY_6 }, { 0x80, 0x0a, KEY_7 }, - { 0x00, 0x0c, KEY_ZOOM }, + { 0x80, 0x0c, KEY_ZOOM }, { 0x80, 0x0d, KEY_0 }, - { 0x00, 0x0e, KEY_SELECT }, + { 0x80, 0x0e, KEY_SELECT }, { 0x80, 0x12, KEY_POWER }, { 0x80, 0x1a, KEY_CHANNELUP }, { 0x80, 0x1b, KEY_8 }, @@ -66,7 +78,7 @@ static struct dvb_usb_rc_key dtt200u_rc_keys[] = { static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - u8 key[5],cmd = GET_RC_KEY; + u8 key[5],cmd = GET_RC_CODE; dvb_usb_generic_rw(d,&cmd,1,key,5,0); dvb_usb_nec_rc_key_to_event(d,key,event,state); if (key[0] != 0) @@ -81,32 +93,41 @@ static int dtt200u_frontend_attach(struct dvb_usb_device *d) } static struct dvb_usb_properties dtt200u_properties; +static struct dvb_usb_properties wt220u_properties; static int dtt200u_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE); + if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 || + dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0) + return 0; + + return -ENODEV; } static struct usb_device_id dtt200u_usb_table [] = { +// { USB_DEVICE(0x04b4,0x8613) }, { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) }, { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) }, + { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) }, + { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) }, { 0 }, }; MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); static struct dvb_usb_properties dtt200u_properties = { .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING, - .pid_filter_count = 255, /* It is a guess, but there are at least 10 */ + .pid_filter_count = 15, .usb_ctrl = CYPRESS_FX2, .firmware = "dvb-usb-dtt200u-01.fw", + .power_ctrl = dtt200u_power_ctrl, .streaming_ctrl = dtt200u_streaming_ctrl, .pid_filter = dtt200u_pid_filter, .frontend_attach = dtt200u_frontend_attach, - .rc_interval = 200, + .rc_interval = 300, .rc_key_map = dtt200u_rc_keys, .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), .rc_query = dtt200u_rc_query, @@ -127,7 +148,7 @@ static struct dvb_usb_properties dtt200u_properties = { .num_device_descs = 1, .devices = { - { .name = "WideView/Yakumo/Hama/Typhoon DVB-T USB2.0)", + { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)", .cold_ids = { &dtt200u_usb_table[0], NULL }, .warm_ids = { &dtt200u_usb_table[1], NULL }, }, @@ -135,10 +156,51 @@ static struct dvb_usb_properties dtt200u_properties = { } }; +static struct dvb_usb_properties wt220u_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING, + .pid_filter_count = 15, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-wt220u-01.fw", + + .power_ctrl = dtt200u_power_ctrl, + .streaming_ctrl = dtt200u_streaming_ctrl, + .pid_filter = dtt200u_pid_filter, + .frontend_attach = dtt200u_frontend_attach, + + .rc_interval = 300, + .rc_key_map = dtt200u_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), + .rc_query = dtt200u_rc_query, + + .generic_bulk_ctrl_endpoint = 0x01, + + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 1, + .devices = { + { .name = "WideView WT-220U PenType Receiver (and clones)", + .cold_ids = { &dtt200u_usb_table[2], NULL }, + .warm_ids = { &dtt200u_usb_table[3], NULL }, + }, + { 0 }, + } +}; + /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver dtt200u_usb_driver = { .owner = THIS_MODULE, - .name = "dtt200u", + .name = "dvb_usb_dtt200u", .probe = dtt200u_usb_probe, .disconnect = dvb_usb_device_exit, .id_table = dtt200u_usb_table, @@ -166,6 +228,6 @@ module_init(dtt200u_usb_module_init); module_exit(dtt200u_usb_module_exit); MODULE_AUTHOR("Patrick Boettcher "); -MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 device"); +MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 devices"); MODULE_VERSION("1.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h index 9ab081a55b8..6f1f3042e21 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.h +++ b/drivers/media/dvb/dvb-usb/dtt200u.h @@ -22,44 +22,34 @@ extern int dvb_usb_dtt200u_debug; /* guessed protocol description (reverse engineered): * read * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1 - * 81 - - * 82 - crash - do not touch - * 83 - crash - do not touch - * 84 - remote control - * 85 - crash - do not touch (OK, stop testing here) * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) - * 89 - noise-to-signal - * 8a - unkown 1 byte - signal_strength - * 8c - ber ??? - * 8d - ber - * 8e - unc */ -#define GET_SPEED 0x00 -#define GET_TUNE_STAT 0x81 -#define GET_RC_KEY 0x84 -#define GET_STATUS 0x88 -#define GET_SNR 0x89 -#define GET_SIG_STRENGTH 0x8a -#define GET_UNK 0x8c -#define GET_BER 0x8d -#define GET_UNC 0x8e +#define GET_SPEED 0x00 +#define GET_TUNE_STATUS 0x81 +#define GET_RC_CODE 0x84 +#define GET_CONFIGURATION 0x88 +#define GET_AGC 0x89 +#define GET_SNR 0x8a +#define GET_VIT_ERR_CNT 0x8c +#define GET_RS_ERR_CNT 0x8d +#define GET_RS_UNCOR_BLK_CNT 0x8e /* write - * 01 - reset the demod + * 01 - init * 02 - frequency (divided by 250000) * 03 - bandwidth * 04 - pid table (index pid(7:0) pid(12:8)) * 05 - reset the pid table - * 08 - demod transfer enabled or not (FX2 transfer is enabled by default) + * 08 - transfer switch */ -#define RESET_DEMOD 0x01 -#define SET_FREQUENCY 0x02 +#define SET_INIT 0x01 +#define SET_RF_FREQ 0x02 #define SET_BANDWIDTH 0x03 #define SET_PID_FILTER 0x04 #define RESET_PID_FILTER 0x05 -#define SET_TS_CTRL 0x08 +#define SET_STREAMING 0x08 extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 75f4cb18a63..794d513a848 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -72,6 +72,8 @@ #define USB_PID_HANFTEK_UMT_010_WARM 0x0015 #define USB_PID_DTT200U_COLD 0x0201 #define USB_PID_DTT200U_WARM 0x0301 +#define USB_PID_WT220U_COLD 0x0222 +#define USB_PID_WT220U_WARM 0x0221 #define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 #define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 #define USB_PID_NEBULA_DIGITV 0x0201 @@ -84,5 +86,4 @@ #define USB_PID_KYE_DVB_T_COLD 0x701e #define USB_PID_KYE_DVB_T_WARM 0x701f - #endif -- cgit v1.2.3-70-g09d2 From 8df3d46077e63ab87f954eb6e827689cdfe97155 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Tue, 12 Jul 2005 13:58:38 -0700 Subject: [PATCH] dvb: usb: fix some typos corrected some typos. Signed-off-by: Patrick Boettcher Signed-off-by: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | 2 +- drivers/media/dvb/dvb-usb/dvb-usb-init.c | 6 +++--- drivers/media/dvb/dvb-usb/vp7045.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/media/dvb/dvb-usb') diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index bdd72f77970..3491ff40885 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c @@ -175,7 +175,7 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe) int dvb_usb_fe_init(struct dvb_usb_device* d) { if (d->props.frontend_attach == NULL) { - err("strange '%s' don't want to attach a frontend.",d->desc->name); + err("strange '%s' doesn't want to attach a frontend.",d->desc->name); return 0; } diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index c3b3ae4f3ec..65f0c095abc 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -51,17 +51,17 @@ static int dvb_usb_init(struct dvb_usb_device *d) /* speed - when running at FULL speed we need a HW PID filter */ if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) { - err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a HW PID filter)"); + err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)"); return -ENODEV; } if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) || (d->props.caps & DVB_USB_NEED_PID_FILTERING)) { - info("will use the device's hw PID filter."); + info("will use the device's hardware PID filter (table count: %d).",d->props.pid_filter_count); d->pid_filtering = 1; d->max_feed_count = d->props.pid_filter_count; } else { - info("will pass the complete MPEG2 transport stream to the demuxer."); + info("will pass the complete MPEG2 transport stream to the software demuxer."); d->pid_filtering = 0; d->max_feed_count = 255; } diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 5adc5d69ec8..9ac95f54f9f 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -128,7 +128,7 @@ static struct dvb_usb_rc_key vp7045_rc_keys[] = { { 0x00, 0x0f, KEY_TEXT } /* Teletext */ }; -static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state) +static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { u8 key; int i; @@ -144,7 +144,7 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state) for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++) if (vp7045_rc_keys[i].data == key) { *state = REMOTE_KEY_PRESSED; - *key_buf = vp7045_rc_keys[i].event; + *event = vp7045_rc_keys[i].event; break; } return 0; -- cgit v1.2.3-70-g09d2