[media] dvb_usb_v2: move from dvb-usb to dvb-usb-v2
authorAntti Palosaari <crope@iki.fi>
Mon, 9 Jul 2012 17:59:28 +0000 (14:59 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 4 Aug 2012 10:56:40 +0000 (07:56 -0300)
Move to own directory.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
74 files changed:
drivers/media/dvb/Kconfig
drivers/media/dvb/Makefile
drivers/media/dvb/dvb-usb-v2/Kconfig [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/Makefile [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/af9015.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/af9015.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/af9035.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/af9035.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/anysee.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/anysee.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/au6610.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/au6610.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/ce6230.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/ce6230.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/dvb_usb.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/dvb_usb_common.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/dvb_usb_core.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/dvb_usb_firmware.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/dvb_usb_firmware.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/dvb_usb_urb.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/ec168.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/ec168.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/gl861.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/gl861.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-reg.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/mxl111sf.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/usb_urb.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/Makefile
drivers/media/dvb/dvb-usb/af9015.c [deleted file]
drivers/media/dvb/dvb-usb/af9015.h [deleted file]
drivers/media/dvb/dvb-usb/af9035.c [deleted file]
drivers/media/dvb/dvb-usb/af9035.h [deleted file]
drivers/media/dvb/dvb-usb/anysee.c [deleted file]
drivers/media/dvb/dvb-usb/anysee.h [deleted file]
drivers/media/dvb/dvb-usb/au6610.c [deleted file]
drivers/media/dvb/dvb-usb/au6610.h [deleted file]
drivers/media/dvb/dvb-usb/ce6230.c [deleted file]
drivers/media/dvb/dvb-usb/ce6230.h [deleted file]
drivers/media/dvb/dvb-usb/dvb_usb.h [deleted file]
drivers/media/dvb/dvb-usb/dvb_usb_common.h [deleted file]
drivers/media/dvb/dvb-usb/dvb_usb_core.c [deleted file]
drivers/media/dvb/dvb-usb/dvb_usb_firmware.c [deleted file]
drivers/media/dvb/dvb-usb/dvb_usb_firmware.h [deleted file]
drivers/media/dvb/dvb-usb/dvb_usb_urb.c [deleted file]
drivers/media/dvb/dvb-usb/ec168.c [deleted file]
drivers/media/dvb/dvb-usb/ec168.h [deleted file]
drivers/media/dvb/dvb-usb/gl861.c [deleted file]
drivers/media/dvb/dvb-usb/gl861.h [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-demod.c [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-demod.h [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-gpio.c [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-gpio.h [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-i2c.c [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-i2c.h [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-phy.c [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-phy.h [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-reg.h [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-tuner.c [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf-tuner.h [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf.c [deleted file]
drivers/media/dvb/dvb-usb/mxl111sf.h [deleted file]
drivers/media/dvb/dvb-usb/usb_urb.c [deleted file]

index f6e40b3a44cc2204f842969deec3ea72c3170b21..3a6ccbc02addcc9e247b76984f9779e261869abb 100644 (file)
@@ -44,6 +44,7 @@ source "drivers/media/dvb/ttpci/Kconfig"
 comment "Supported USB Adapters"
        depends on DVB_CORE && USB && I2C
 source "drivers/media/dvb/dvb-usb/Kconfig"
+source "drivers/media/dvb/dvb-usb-v2/Kconfig"
 source "drivers/media/dvb/ttusb-budget/Kconfig"
 source "drivers/media/dvb/ttusb-dec/Kconfig"
 source "drivers/media/dvb/siano/Kconfig"
index b2cefe637a6410e42bb3ccc762beaa3c3b28901f..8f7e0129d70e3840f1cfda8162228238a454d01a 100644 (file)
@@ -10,6 +10,7 @@ obj-y        := dvb-core/     \
                b2c2/           \
                bt8xx/          \
                dvb-usb/        \
+               dvb-usb-v2/     \
                pluto2/         \
                siano/          \
                dm1105/         \
diff --git a/drivers/media/dvb/dvb-usb-v2/Kconfig b/drivers/media/dvb/dvb-usb-v2/Kconfig
new file mode 100644 (file)
index 0000000..bef2ffa
--- /dev/null
@@ -0,0 +1,104 @@
+config DVB_USB_V2
+       tristate "Support for various USB DVB devices v2"
+       depends on DVB_CORE && USB && I2C && RC_CORE
+       help
+         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
+         <file:Documentation/dvb/README.dvb-usb>.
+
+         For a complete list of supported USB devices see the LinuxTV DVB Wiki:
+         <http://www.linuxtv.org/wiki/index.php/DVB_USB>
+
+         Say Y if you own a USB DVB device.
+
+config DVB_USB_FIRMWARE
+       tristate "Firmware helper routines"
+       depends on DVB_USB_V2
+
+config DVB_USB_AF9015
+       tristate "Afatech AF9015 DVB-T USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_AF9013
+       select DVB_PLL              if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_MT2060   if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_QT1010   if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
+
+config DVB_USB_AF9035
+       tristate "Afatech AF9035 DVB-T USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_AF9033
+       select MEDIA_TUNER_TUA9001 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_FC0011 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Afatech AF9035 based DVB USB receiver.
+
+config DVB_USB_ANYSEE
+       tristate "Anysee DVB-T/C USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       select DVB_MT352 if !DVB_FE_CUSTOMISE
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
+       select DVB_CX24116 if !DVB_FE_CUSTOMISE
+       select DVB_STV0900 if !DVB_FE_CUSTOMISE
+       select DVB_STV6110 if !DVB_FE_CUSTOMISE
+       select DVB_ISL6423 if !DVB_FE_CUSTOMISE
+       select DVB_CXD2820R if !DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the Anysee E30, Anysee E30 Plus or
+         Anysee E30 C Plus DVB USB2.0 receiver.
+
+config DVB_USB_AU6610
+       tristate "Alcor Micro AU6610 USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
+
+config DVB_USB_CE6230
+       tristate "Intel CE6230 DVB-T USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_ZL10353
+       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
+
+config DVB_USB_EC168
+       tristate "E3C EC168 DVB-T USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_EC100
+       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
+
+config DVB_USB_GL861
+       tristate "Genesys Logic GL861 USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
+         receiver with USB ID 0db0:5581.
+
+config DVB_USB_MXL111SF
+       tristate "MxL111SF DTV USB2.0 support"
+       depends on DVB_USB_V2
+       select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+       select DVB_LG2160 if !DVB_FE_CUSTOMISE
+       select VIDEO_TVEEPROM
+       help
+         Say Y here to support the MxL111SF USB2.0 DTV receiver.
+
diff --git a/drivers/media/dvb/dvb-usb-v2/Makefile b/drivers/media/dvb/dvb-usb-v2/Makefile
new file mode 100644 (file)
index 0000000..6080ec8
--- /dev/null
@@ -0,0 +1,35 @@
+dvb_usbv2-objs = dvb_usb_core.o dvb_usb_urb.o usb_urb.o
+obj-$(CONFIG_DVB_USB_V2) += dvb_usbv2.o
+
+obj-$(CONFIG_DVB_USB_FIRMWARE) += dvb_usb_firmware.o
+
+dvb-usb-af9015-objs = af9015.o
+obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
+
+dvb-usb-af9035-objs = af9035.o
+obj-$(CONFIG_DVB_USB_AF9035) += dvb-usb-af9035.o
+
+dvb-usb-anysee-objs = anysee.o
+obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
+
+dvb-usb-au6610-objs = au6610.o
+obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o
+
+dvb-usb-ce6230-objs = ce6230.o
+obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
+
+dvb-usb-ec168-objs = ec168.o
+obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
+
+dvb-usb-gl861-objs = gl861.o
+obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o
+
+dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
+
+ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/
+ccflags-y += -I$(srctree)/drivers/media/common/tuners
+
diff --git a/drivers/media/dvb/dvb-usb-v2/af9015.c b/drivers/media/dvb/dvb-usb-v2/af9015.c
new file mode 100644 (file)
index 0000000..bbe1d33
--- /dev/null
@@ -0,0 +1,1426 @@
+/*
+ * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ * Thanks to Afatech who kindly provided 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; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "af9015.h"
+
+static int dvb_usb_af9015_debug;
+module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+static int dvb_usb_af9015_remote;
+module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
+MODULE_PARM_DESC(remote, "select remote");
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
+{
+#define BUF_LEN 63
+#define REQ_HDR_LEN 8 /* send header size */
+#define ACK_HDR_LEN 2 /* rece header size */
+       struct af9015_state *state = d_to_priv(d);
+       int ret, wlen, rlen;
+       u8 buf[BUF_LEN];
+       u8 write = 1;
+
+       buf[0] = req->cmd;
+       buf[1] = state->seq++;
+       buf[2] = req->i2c_addr;
+       buf[3] = req->addr >> 8;
+       buf[4] = req->addr & 0xff;
+       buf[5] = req->mbox;
+       buf[6] = req->addr_len;
+       buf[7] = req->data_len;
+
+       switch (req->cmd) {
+       case GET_CONFIG:
+       case READ_MEMORY:
+       case RECONNECT_USB:
+               write = 0;
+               break;
+       case READ_I2C:
+               write = 0;
+               buf[2] |= 0x01; /* set I2C direction */
+       case WRITE_I2C:
+               buf[0] = READ_WRITE_I2C;
+               break;
+       case WRITE_MEMORY:
+               if (((req->addr & 0xff00) == 0xff00) ||
+                   ((req->addr & 0xff00) == 0xae00))
+                       buf[0] = WRITE_VIRTUAL_MEMORY;
+       case WRITE_VIRTUAL_MEMORY:
+       case COPY_FIRMWARE:
+       case DOWNLOAD_FIRMWARE:
+       case BOOT:
+               break;
+       default:
+               err("unknown command:%d", req->cmd);
+               ret = -1;
+               goto error;
+       }
+
+       /* buffer overflow check */
+       if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
+               (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
+               err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* write receives seq + status = 2 bytes
+          read receives seq + status + data = 2 + N bytes */
+       wlen = REQ_HDR_LEN;
+       rlen = ACK_HDR_LEN;
+       if (write) {
+               wlen += req->data_len;
+               memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
+       } else {
+               rlen += req->data_len;
+       }
+
+       /* no ack for these packets */
+       if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
+               rlen = 0;
+
+       ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
+       if (ret)
+               goto error;
+
+       /* check status */
+       if (rlen && buf[1]) {
+               err("command failed:%d", buf[1]);
+               ret = -1;
+               goto error;
+       }
+
+       /* read request, copy returned data to return buf */
+       if (!write)
+               memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
+error:
+       return ret;
+}
+
+static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
+       u8 len)
+{
+       struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
+               val};
+       return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
+{
+       struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
+               val};
+       return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
+{
+       return af9015_write_regs(d, addr, &val, 1);
+}
+
+static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
+{
+       return af9015_read_regs(d, addr, val, 1);
+}
+
+static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
+       u8 val)
+{
+       struct af9015_state *state = d_to_priv(d);
+       struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
+
+       if (addr == state->af9013_config[0].i2c_addr ||
+           addr == state->af9013_config[1].i2c_addr)
+               req.addr_len = 3;
+
+       return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
+       u8 *val)
+{
+       struct af9015_state *state = d_to_priv(d);
+       struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
+
+       if (addr == state->af9013_config[0].i2c_addr ||
+           addr == state->af9013_config[1].i2c_addr)
+               req.addr_len = 3;
+
+       return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
+{
+       int ret;
+       u8 val, mask = 0x01;
+
+       ret = af9015_read_reg(d, addr, &val);
+       if (ret)
+               return ret;
+
+       mask <<= bit;
+       if (op) {
+               /* set bit */
+               val |= mask;
+       } else {
+               /* clear bit */
+               mask ^= 0xff;
+               val &= mask;
+       }
+
+       return af9015_write_reg(d, addr, val);
+}
+
+static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
+{
+       return af9015_do_reg_bit(d, addr, bit, 1);
+}
+
+static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
+{
+       return af9015_do_reg_bit(d, addr, bit, 0);
+}
+
+static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+       int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct af9015_state *state = d_to_priv(d);
+       int ret = 0, i = 0;
+       u16 addr;
+       u8 uninitialized_var(mbox), addr_len;
+       struct req_t req;
+
+/*
+The bus lock is needed because there is two tuners both using same I2C-address.
+Due to that the only way to select correct tuner is use demodulator I2C-gate.
+
+................................................
+. AF9015 includes integrated AF9013 demodulator.
+. ____________                   ____________  .                ____________
+.|     uC     |                 |   demod    | .               |    tuner   |
+.|------------|                 |------------| .               |------------|
+.|   AF9015   |                 |  AF9013/5  | .               |   MXL5003  |
+.|            |--+----I2C-------|-----/ -----|-.-----I2C-------|            |
+.|            |  |              | addr 0x38  | .               |  addr 0xc6 |
+.|____________|  |              |____________| .               |____________|
+.................|..............................
+                |               ____________                   ____________
+                |              |   demod    |                 |    tuner   |
+                |              |------------|                 |------------|
+                |              |   AF9013   |                 |   MXL5003  |
+                +----I2C-------|-----/ -----|-------I2C-------|            |
+                               | addr 0x3a  |                 |  addr 0xc6 |
+                               |____________|                 |____________|
+*/
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       while (i < num) {
+               if (msg[i].addr == state->af9013_config[0].i2c_addr ||
+                   msg[i].addr == state->af9013_config[1].i2c_addr) {
+                       addr = msg[i].buf[0] << 8;
+                       addr += msg[i].buf[1];
+                       mbox = msg[i].buf[2];
+                       addr_len = 3;
+               } else {
+                       addr = msg[i].buf[0];
+                       addr_len = 1;
+                       /* mbox is don't care in that case */
+               }
+
+               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+                       if (msg[i].len > 3 || msg[i+1].len > 61) {
+                               ret = -EOPNOTSUPP;
+                               goto error;
+                       }
+                       if (msg[i].addr == state->af9013_config[0].i2c_addr)
+                               req.cmd = READ_MEMORY;
+                       else
+                               req.cmd = READ_I2C;
+                       req.i2c_addr = msg[i].addr;
+                       req.addr = addr;
+                       req.mbox = mbox;
+                       req.addr_len = addr_len;
+                       req.data_len = msg[i+1].len;
+                       req.data = &msg[i+1].buf[0];
+                       ret = af9015_ctrl_msg(d, &req);
+                       i += 2;
+               } else if (msg[i].flags & I2C_M_RD) {
+                       if (msg[i].len > 61) {
+                               ret = -EOPNOTSUPP;
+                               goto error;
+                       }
+                       if (msg[i].addr == state->af9013_config[0].i2c_addr) {
+                               ret = -EINVAL;
+                               goto error;
+                       }
+                       req.cmd = READ_I2C;
+                       req.i2c_addr = msg[i].addr;
+                       req.addr = addr;
+                       req.mbox = mbox;
+                       req.addr_len = addr_len;
+                       req.data_len = msg[i].len;
+                       req.data = &msg[i].buf[0];
+                       ret = af9015_ctrl_msg(d, &req);
+                       i += 1;
+               } else {
+                       if (msg[i].len > 21) {
+                               ret = -EOPNOTSUPP;
+                               goto error;
+                       }
+                       if (msg[i].addr == state->af9013_config[0].i2c_addr)
+                               req.cmd = WRITE_MEMORY;
+                       else
+                               req.cmd = WRITE_I2C;
+                       req.i2c_addr = msg[i].addr;
+                       req.addr = addr;
+                       req.mbox = mbox;
+                       req.addr_len = addr_len;
+                       req.data_len = msg[i].len-addr_len;
+                       req.data = &msg[i].buf[addr_len];
+                       ret = af9015_ctrl_msg(d, &req);
+                       i += 1;
+               }
+               if (ret)
+                       goto error;
+
+       }
+       ret = i;
+
+error:
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret;
+}
+
+static u32 af9015_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm af9015_i2c_algo = {
+       .master_xfer = af9015_i2c_xfer,
+       .functionality = af9015_i2c_func,
+};
+
+static int af9015_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       int ret;
+       u8 reply;
+       struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
+
+       ret = af9015_ctrl_msg(d, &req);
+       if (ret)
+               return ret;
+
+       deb_info("%s: reply:%02x\n", __func__, reply);
+       if (reply == 0x02)
+               ret = WARM;
+       else
+               ret = COLD;
+
+       return ret;
+}
+
+static int af9015_download_firmware(struct dvb_usb_device *d,
+       const struct firmware *fw)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int i, len, remaining, ret;
+       struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
+       u16 checksum = 0;
+
+       deb_info("%s:\n", __func__);
+
+       /* calc checksum */
+       for (i = 0; i < fw->size; i++)
+               checksum += fw->data[i];
+
+       state->firmware_size = fw->size;
+       state->firmware_checksum = checksum;
+
+       #define FW_ADDR 0x5100 /* firmware start address */
+       #define LEN_MAX 55 /* max packet size */
+       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
+               len = remaining;
+               if (len > LEN_MAX)
+                       len = LEN_MAX;
+
+               req.data_len = len;
+               req.data = (u8 *) &fw->data[fw->size - remaining];
+               req.addr = FW_ADDR + fw->size - remaining;
+
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret) {
+                       err("firmware download failed:%d", ret);
+                       goto error;
+               }
+       }
+
+       /* firmware loaded, request boot */
+       req.cmd = BOOT;
+       req.data_len = 0;
+       ret = af9015_ctrl_msg(d, &req);
+       if (ret) {
+               err("firmware boot failed:%d", ret);
+               goto error;
+       }
+
+error:
+       return ret;
+}
+
+/* hash (and dump) eeprom */
+static int af9015_eeprom_hash(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       static const unsigned int eeprom_size = 256;
+       unsigned int reg;
+       u8 val, *eeprom;
+       struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
+
+       eeprom = kmalloc(eeprom_size, GFP_KERNEL);
+       if (eeprom == NULL)
+               return -ENOMEM;
+
+       for (reg = 0; reg < eeprom_size; reg++) {
+               req.addr = reg;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto free;
+
+               eeprom[reg] = val;
+       }
+
+       if (dvb_usb_af9015_debug & 0x01)
+               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
+                               eeprom_size);
+
+       BUG_ON(eeprom_size % 4);
+
+       state->eeprom_sum = 0;
+       for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
+               state->eeprom_sum *= GOLDEN_RATIO_PRIME_32;
+               state->eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
+       }
+
+       deb_info("%s: eeprom sum=%.8x\n", __func__, state->eeprom_sum);
+
+       ret = 0;
+free:
+       kfree(eeprom);
+       return ret;
+}
+
+static int af9015_read_config(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       u8 val, i, offset = 0;
+       struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
+
+       deb_info("%s:\n", __func__);
+
+       /* IR remote controller */
+       req.addr = AF9015_EEPROM_IR_MODE;
+       /* first message will timeout often due to possible hw bug */
+       for (i = 0; i < 4; i++) {
+               ret = af9015_ctrl_msg(d, &req);
+               if (!ret)
+                       break;
+       }
+       if (ret)
+               goto error;
+
+       ret = af9015_eeprom_hash(d);
+       if (ret)
+               goto error;
+
+       deb_info("%s: IR mode=%d\n", __func__, val);
+       state->ir_mode = val;
+
+       /* TS mode - one or two receivers */
+       req.addr = AF9015_EEPROM_TS_MODE;
+       ret = af9015_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       state->dual_mode = val;
+       deb_info("%s: TS mode=%d\n", __func__, state->dual_mode);
+
+       /* disable 2nd adapter because we don't have PID-filters */
+       if (d->udev->speed == USB_SPEED_FULL)
+               state->dual_mode = 0;
+
+       if (state->dual_mode) {
+               /* read 2nd demodulator I2C address */
+               req.addr = AF9015_EEPROM_DEMOD2_I2C;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+
+               state->af9013_config[1].i2c_addr = val;
+       }
+
+       for (i = 0; i < state->dual_mode + 1; i++) {
+               if (i == 1)
+                       offset = AF9015_EEPROM_OFFSET;
+               /* xtal */
+               req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+               switch (val) {
+               case 0:
+                       state->af9013_config[i].clock = 28800000;
+                       break;
+               case 1:
+                       state->af9013_config[i].clock = 20480000;
+                       break;
+               case 2:
+                       state->af9013_config[i].clock = 28000000;
+                       break;
+               case 3:
+                       state->af9013_config[i].clock = 25000000;
+                       break;
+               };
+               deb_info("%s: [%d] xtal=%d set clock=%d\n", __func__, i,
+                               val, state->af9013_config[i].clock);
+
+               /* IF frequency */
+               req.addr = AF9015_EEPROM_IF1H + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+
+               state->af9013_config[i].if_frequency = val << 8;
+
+               req.addr = AF9015_EEPROM_IF1L + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+
+               state->af9013_config[i].if_frequency += val;
+               state->af9013_config[i].if_frequency *= 1000;
+               deb_info("%s: [%d] IF frequency=%d\n", __func__, i,
+                               state->af9013_config[i].if_frequency);
+
+               /* MT2060 IF1 */
+               req.addr = AF9015_EEPROM_MT2060_IF1H  + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+               state->mt2060_if1[i] = val << 8;
+               req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+               state->mt2060_if1[i] += val;
+               deb_info("%s: [%d] MT2060 IF1=%d\n", __func__, i,
+                               state->mt2060_if1[i]);
+
+               /* tuner */
+               req.addr =  AF9015_EEPROM_TUNER_ID1 + offset;
+               ret = af9015_ctrl_msg(d, &req);
+               if (ret)
+                       goto error;
+               switch (val) {
+               case AF9013_TUNER_ENV77H11D5:
+               case AF9013_TUNER_MT2060:
+               case AF9013_TUNER_QT1010:
+               case AF9013_TUNER_UNKNOWN:
+               case AF9013_TUNER_MT2060_2:
+               case AF9013_TUNER_TDA18271:
+               case AF9013_TUNER_QT1010A:
+               case AF9013_TUNER_TDA18218:
+                       state->af9013_config[i].spec_inv = 1;
+                       break;
+               case AF9013_TUNER_MXL5003D:
+               case AF9013_TUNER_MXL5005D:
+               case AF9013_TUNER_MXL5005R:
+               case AF9013_TUNER_MXL5007T:
+                       state->af9013_config[i].spec_inv = 0;
+                       break;
+               case AF9013_TUNER_MC44S803:
+                       state->af9013_config[i].gpio[1] = AF9013_GPIO_LO;
+                       state->af9013_config[i].spec_inv = 1;
+                       break;
+               default:
+                       warn("tuner id=%d not supported, please report!", val);
+                       return -ENODEV;
+               };
+
+               state->af9013_config[i].tuner = val;
+               deb_info("%s: [%d] tuner id=%d\n", __func__, i, val);
+       }
+
+error:
+       if (ret)
+               err("eeprom read failed=%d", ret);
+
+       /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
+          content :-( Override some wrong values here. Ditto for the
+          AVerTV Red HD+ (A850T) device. */
+       if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
+               ((le16_to_cpu(d->udev->descriptor.idProduct) ==
+                       USB_PID_AVERMEDIA_A850) ||
+               (le16_to_cpu(d->udev->descriptor.idProduct) ==
+                       USB_PID_AVERMEDIA_A850T))) {
+               deb_info("%s: AverMedia A850: overriding config\n", __func__);
+               /* disable dual mode */
+               state->dual_mode = 0;
+
+               /* set correct IF */
+               state->af9013_config[0].if_frequency = 4570000;
+       }
+
+       return ret;
+}
+
+static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
+               struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: adap=%d\n", __func__, fe_to_adap(fe)->id);
+
+       if (fe_to_d(fe)->udev->speed == USB_SPEED_FULL)
+               stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE;
+
+       return 0;
+}
+
+static int af9015_get_adapter_count(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       return state->dual_mode + 1;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_set_frontend(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->set_frontend[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_read_status(struct dvb_frontend *fe,
+       fe_status_t *status)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->read_status[fe_to_adap(fe)->id](fe, status);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_init(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->init[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->sleep[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override tuner callbacks for resource locking */
+static int af9015_tuner_init(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->tuner_init[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+/* override tuner callbacks for resource locking */
+static int af9015_tuner_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+       struct af9015_state *state = fe_to_priv(fe);
+
+       if (mutex_lock_interruptible(&state->fe_mutex))
+               return -EAGAIN;
+
+       ret = state->tuner_sleep[fe_to_adap(fe)->id](fe);
+
+       mutex_unlock(&state->fe_mutex);
+
+       return ret;
+}
+
+static int af9015_copy_firmware(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       u8 fw_params[4];
+       u8 val, i;
+       struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
+               fw_params };
+       deb_info("%s:\n", __func__);
+
+       fw_params[0] = state->firmware_size >> 8;
+       fw_params[1] = state->firmware_size & 0xff;
+       fw_params[2] = state->firmware_checksum >> 8;
+       fw_params[3] = state->firmware_checksum & 0xff;
+
+       /* wait 2nd demodulator ready */
+       msleep(100);
+
+       ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
+                       0x98be, &val);
+       if (ret)
+               goto error;
+       else
+               deb_info("%s: firmware status:%02x\n", __func__, val);
+
+       if (val == 0x0c) /* fw is running, no need for download */
+               goto exit;
+
+       /* set I2C master clock to fast (to speed up firmware copy) */
+       ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
+       if (ret)
+               goto error;
+
+       msleep(50);
+
+       /* copy firmware */
+       ret = af9015_ctrl_msg(d, &req);
+       if (ret)
+               err("firmware copy cmd failed:%d", ret);
+       deb_info("%s: firmware copy done\n", __func__);
+
+       /* set I2C master clock back to normal */
+       ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
+       if (ret)
+               goto error;
+
+       /* request boot firmware */
+       ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr,
+                       0xe205, 1);
+       deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
+       if (ret)
+               goto error;
+
+       for (i = 0; i < 15; i++) {
+               msleep(100);
+
+               /* check firmware status */
+               ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
+                               0x98be, &val);
+               deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
+                       __func__, ret, val);
+               if (ret)
+                       goto error;
+
+               if (val == 0x0c || val == 0x04) /* success or fail */
+                       break;
+       }
+
+       if (val == 0x04) {
+               err("firmware did not run");
+               ret = -1;
+       } else if (val != 0x0c) {
+               err("firmware boot timeout");
+               ret = -1;
+       }
+
+error:
+exit:
+       return ret;
+}
+
+static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       struct af9015_state *state = adap_to_priv(adap);
+
+       if (adap->id == 0) {
+               state->af9013_config[0].ts_mode = AF9013_TS_USB;
+               memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4);
+               state->af9013_config[0].gpio[0] = AF9013_GPIO_HI;
+               state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON;
+       } else if (adap->id == 1) {
+               state->af9013_config[1].ts_mode = AF9013_TS_SERIAL;
+               memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4);
+               state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON;
+               state->af9013_config[1].gpio[1] = AF9013_GPIO_LO;
+
+               /* copy firmware to 2nd demodulator */
+               if (state->dual_mode) {
+                       ret = af9015_copy_firmware(adap_to_d(adap));
+                       if (ret) {
+                               err("firmware copy to 2nd frontend " \
+                                       "failed, will disable it");
+                               state->dual_mode = 0;
+                               return -ENODEV;
+                       }
+               } else {
+                       return -ENODEV;
+               }
+       }
+
+       /* attach demodulator */
+       adap->fe[0] = dvb_attach(af9013_attach,
+               &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap);
+
+       /*
+        * AF9015 firmware does not like if it gets interrupted by I2C adapter
+        * request on some critical phases. During normal operation I2C adapter
+        * is used only 2nd demodulator and tuner on dual tuner devices.
+        * Override demodulator callbacks and use mutex for limit access to
+        * those "critical" paths to keep AF9015 happy.
+        */
+       if (adap->fe[0]) {
+               state->set_frontend[adap->id] =
+                       adap->fe[0]->ops.set_frontend;
+               adap->fe[0]->ops.set_frontend =
+                       af9015_af9013_set_frontend;
+
+               state->read_status[adap->id] =
+                       adap->fe[0]->ops.read_status;
+               adap->fe[0]->ops.read_status =
+                       af9015_af9013_read_status;
+
+               state->init[adap->id] = adap->fe[0]->ops.init;
+               adap->fe[0]->ops.init = af9015_af9013_init;
+
+               state->sleep[adap->id] = adap->fe[0]->ops.sleep;
+               adap->fe[0]->ops.sleep = af9015_af9013_sleep;
+       }
+
+       return adap->fe[0] == NULL ? -ENODEV : 0;
+}
+
+static struct mt2060_config af9015_mt2060_config = {
+       .i2c_address = 0xc0,
+       .clock_out = 0,
+};
+
+static struct qt1010_config af9015_qt1010_config = {
+       .i2c_address = 0xc4,
+};
+
+static struct tda18271_config af9015_tda18271_config = {
+       .gate = TDA18271_GATE_DIGITAL,
+       .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
+};
+
+static struct mxl5005s_config af9015_mxl5003_config = {
+       .i2c_address     = 0xc6,
+       .if_freq         = IF_FREQ_4570000HZ,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_DEFAULT,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static struct mxl5005s_config af9015_mxl5005_config = {
+       .i2c_address     = 0xc6,
+       .if_freq         = IF_FREQ_4570000HZ,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_OFF,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static struct mc44s803_config af9015_mc44s803_config = {
+       .i2c_address = 0xc0,
+       .dig_out = 1,
+};
+
+static struct tda18218_config af9015_tda18218_config = {
+       .i2c_address = 0xc0,
+       .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
+};
+
+static struct mxl5007t_config af9015_mxl5007t_config = {
+       .xtal_freq_hz = MxL_XTAL_24_MHZ,
+       .if_freq_hz = MxL_IF_4_57_MHZ,
+};
+
+static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct af9015_state *state = adap_to_priv(adap);
+       int ret;
+       deb_info("%s:\n", __func__);
+
+       switch (state->af9013_config[adap->id].tuner) {
+       case AF9013_TUNER_MT2060:
+       case AF9013_TUNER_MT2060_2:
+               ret = dvb_attach(mt2060_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config,
+                       state->mt2060_if1[adap->id])
+                       == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_QT1010:
+       case AF9013_TUNER_QT1010A:
+               ret = dvb_attach(qt1010_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_qt1010_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_TDA18271:
+               ret = dvb_attach(tda18271_attach, adap->fe[0], 0xc0,
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_tda18271_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_TDA18218:
+               ret = dvb_attach(tda18218_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_tda18218_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_MXL5003D:
+               ret = dvb_attach(mxl5005s_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_MXL5005D:
+       case AF9013_TUNER_MXL5005R:
+               ret = dvb_attach(mxl5005s_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_ENV77H11D5:
+               ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0xc0,
+                       &adap_to_d(adap)->i2c_adap,
+                       DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_MC44S803:
+               ret = dvb_attach(mc44s803_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_MXL5007T:
+               ret = dvb_attach(mxl5007t_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
+               break;
+       case AF9013_TUNER_UNKNOWN:
+       default:
+               ret = -ENODEV;
+               err("Unknown tuner id:%d",
+                       state->af9013_config[adap->id].tuner);
+       }
+
+       if (adap->fe[0]->ops.tuner_ops.init) {
+               state->tuner_init[adap->id] =
+                       adap->fe[0]->ops.tuner_ops.init;
+               adap->fe[0]->ops.tuner_ops.init = af9015_tuner_init;
+       }
+
+       if (adap->fe[0]->ops.tuner_ops.sleep) {
+               state->tuner_sleep[adap->id] =
+                       adap->fe[0]->ops.tuner_ops.sleep;
+               adap->fe[0]->ops.tuner_ops.sleep = af9015_tuner_sleep;
+       }
+
+       return ret;
+}
+
+static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       int ret;
+       deb_info("%s: onoff:%d\n", __func__, onoff);
+
+       if (onoff)
+               ret = af9015_set_reg_bit(adap_to_d(adap), 0xd503, 0);
+       else
+               ret = af9015_clear_reg_bit(adap_to_d(adap), 0xd503, 0);
+
+       return ret;
+}
+
+static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+       int onoff)
+{
+       int ret;
+       u8 idx;
+
+       deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
+               __func__, index, pid, onoff);
+
+       ret = af9015_write_reg(adap_to_d(adap), 0xd505, (pid & 0xff));
+       if (ret)
+               goto error;
+
+       ret = af9015_write_reg(adap_to_d(adap), 0xd506, (pid >> 8));
+       if (ret)
+               goto error;
+
+       idx = ((index & 0x1f) | (1 << 5));
+       ret = af9015_write_reg(adap_to_d(adap), 0xd504, idx);
+
+error:
+       return ret;
+}
+
+static int af9015_init_endpoint(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       u16 frame_size;
+       u8  packet_size;
+       deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
+
+       if (d->udev->speed == USB_SPEED_FULL) {
+               frame_size = TS_USB11_FRAME_SIZE/4;
+               packet_size = TS_USB11_MAX_PACKET_SIZE/4;
+       } else {
+               frame_size = TS_USB20_FRAME_SIZE/4;
+               packet_size = TS_USB20_MAX_PACKET_SIZE/4;
+       }
+
+       ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
+       if (ret)
+               goto error;
+       ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
+       if (ret)
+               goto error;
+       ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
+       if (ret)
+               goto error;
+       ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
+       if (ret)
+               goto error;
+       ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
+       if (ret)
+               goto error;
+       if (state->dual_mode) {
+               ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
+               if (ret)
+                       goto error;
+       }
+       ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
+       if (ret)
+               goto error;
+       if (state->dual_mode) {
+               ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
+               if (ret)
+                       goto error;
+       }
+       /* EP4 xfer length */
+       ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
+       if (ret)
+               goto error;
+       ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
+       if (ret)
+               goto error;
+       /* EP5 xfer length */
+       ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
+       if (ret)
+               goto error;
+       ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
+       if (ret)
+               goto error;
+       ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
+       if (ret)
+               goto error;
+       ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
+       if (ret)
+               goto error;
+       ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
+       if (ret)
+               goto error;
+       if (state->dual_mode) {
+               ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
+               if (ret)
+                       goto error;
+       }
+
+       /* enable / disable mp2if2 */
+       if (state->dual_mode)
+               ret = af9015_set_reg_bit(d, 0xd50b, 0);
+       else
+               ret = af9015_clear_reg_bit(d, 0xd50b, 0);
+
+error:
+       if (ret)
+               err("endpoint init failed:%d", ret);
+       return ret;
+}
+
+static int af9015_init(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       deb_info("%s:\n", __func__);
+
+       mutex_init(&state->fe_mutex);
+
+       /* init RC canary */
+       ret = af9015_write_reg(d, 0x98e9, 0xff);
+       if (ret)
+               goto error;
+
+       ret = af9015_init_endpoint(d);
+       if (ret)
+               goto error;
+
+error:
+       return ret;
+}
+
+struct af9015_rc_setup {
+       unsigned int id;
+       char *rc_codes;
+};
+
+static char *af9015_rc_setup_match(unsigned int id,
+       const struct af9015_rc_setup *table)
+{
+       for (; table->rc_codes; table++)
+               if (table->id == id)
+                       return table->rc_codes;
+       return NULL;
+}
+
+static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
+       { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
+       { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
+       { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
+       { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
+       { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
+       { }
+};
+
+static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
+       { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
+       { 0xa3703d00, RC_MAP_ALINK_DTU_M },
+       { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
+       { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */
+       { }
+};
+
+static int af9015_rc_query(struct dvb_usb_device *d)
+{
+       struct af9015_state *state = d_to_priv(d);
+       int ret;
+       u8 buf[17];
+
+       deb_info("%s:\n", __func__);
+
+       /* read registers needed to detect remote controller code */
+       ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       /* If any of these are non-zero, assume invalid data */
+       if (buf[1] || buf[2] || buf[3])
+               return ret;
+
+       /* Check for repeat of previous code */
+       if ((state->rc_repeat != buf[6] || buf[0]) &&
+                       !memcmp(&buf[12], state->rc_last, 4)) {
+               deb_rc("%s: key repeated\n", __func__);
+               rc_keydown(d->rc_dev, state->rc_keycode, 0);
+               state->rc_repeat = buf[6];
+               return ret;
+       }
+
+       /* Only process key if canary killed */
+       if (buf[16] != 0xff && buf[0] != 0x01) {
+               deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
+                       buf[12], buf[13], buf[14], buf[15]);
+
+               /* Reset the canary */
+               ret = af9015_write_reg(d, 0x98e9, 0xff);
+               if (ret)
+                       goto error;
+
+               /* Remember this key */
+               memcpy(state->rc_last, &buf[12], 4);
+               if (buf[14] == (u8) ~buf[15]) {
+                       if (buf[12] == (u8) ~buf[13]) {
+                               /* NEC */
+                               state->rc_keycode = buf[12] << 8 | buf[14];
+                       } else {
+                               /* NEC extended*/
+                               state->rc_keycode = buf[12] << 16 |
+                                       buf[13] << 8 | buf[14];
+                       }
+               } else {
+                       /* 32 bit NEC */
+                       state->rc_keycode = buf[12] << 24 | buf[13] << 16 |
+                                       buf[14] << 8 | buf[15];
+               }
+               rc_keydown(d->rc_dev, state->rc_keycode, 0);
+       } else {
+               deb_rc("%s: no key press\n", __func__);
+               /* Invalidate last keypress */
+               /* Not really needed, but helps with debug */
+               state->rc_last[2] = state->rc_last[3];
+       }
+
+       state->rc_repeat = buf[6];
+
+error:
+       if (ret)
+               err("%s: failed:%d", __func__, ret);
+
+       return ret;
+}
+
+static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+       struct af9015_state *state = d_to_priv(d);
+       u16 vid = le16_to_cpu(d->udev->descriptor.idVendor);
+
+       if (state->ir_mode == AF9015_IR_MODE_DISABLED)
+               return 0;
+
+       /* try to load remote based module param */
+       rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote,
+                       af9015_rc_setup_modparam);
+
+       /* try to load remote based eeprom hash */
+       if (!rc->map_name)
+               rc->map_name = af9015_rc_setup_match(state->eeprom_sum,
+                               af9015_rc_setup_hashes);
+
+       /* try to load remote based USB iManufacturer string */
+       if (!rc->map_name && vid == USB_VID_AFATECH) {
+               /* Check USB manufacturer and product strings and try
+                  to determine correct remote in case of chip vendor
+                  reference IDs are used.
+                  DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
+               char manufacturer[10];
+               memset(manufacturer, 0, sizeof(manufacturer));
+               usb_string(d->udev, d->udev->descriptor.iManufacturer,
+                       manufacturer, sizeof(manufacturer));
+               if (!strcmp("MSI", manufacturer)) {
+                       /* iManufacturer 1 MSI
+                          iProduct      2 MSI K-VOX */
+                       rc->map_name = af9015_rc_setup_match(
+                                       AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
+                                       af9015_rc_setup_modparam);
+               }
+       }
+
+       /* load empty to enable rc */
+       if (!rc->map_name)
+               rc->map_name = RC_MAP_EMPTY;
+
+       rc->allowed_protos = RC_TYPE_NEC;
+       rc->query = af9015_rc_query;
+       rc->interval = 500;
+
+       return 0;
+}
+
+/* interface 0 is used by DVB-T receiver and
+   interface 1 is for remote controller (HID) */
+static struct dvb_usb_device_properties af9015_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct af9015_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .identify_state = af9015_identify_state,
+       .firmware = "dvb-usb-af9015.fw",
+       .download_firmware = af9015_download_firmware,
+
+       .i2c_algo = &af9015_i2c_algo,
+       .read_config = af9015_read_config,
+       .frontend_attach = af9015_af9013_frontend_attach,
+       .tuner_attach = af9015_tuner_attach,
+       .init = af9015_init,
+       .get_rc_config = af9015_get_rc_config,
+       .get_stream_config = af9015_get_stream_config,
+
+       .get_adapter_count = af9015_get_adapter_count,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 32,
+                       .pid_filter = af9015_pid_filter,
+                       .pid_filter_ctrl = af9015_pid_filter_ctrl,
+
+                       .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE),
+               }, {
+                       .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE),
+               },
+       },
+};
+
+static const struct usb_device_id af9015_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015,
+               &af9015_props, "Afatech AF9015 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016,
+               &af9015_props, "Afatech AF9015 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD,
+               &af9015_props, "Leadtek WinFast DTV Dongle Gold", RC_MAP_LEADTEK_Y04G0051) },
+       { DVB_USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E,
+               &af9015_props, "Pinnacle PCTV 71e", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U,
+               &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN,
+               &af9015_props, "DigitalNow TinyTwin", RC_MAP_AZUREWAVE_AD_TU700) },
+       { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700,
+               &af9015_props, "TwinHan AzureWave AD-TU700(704J)", RC_MAP_AZUREWAVE_AD_TU700) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2,
+               &af9015_props, "TerraTec Cinergy T USB XE", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T,
+               &af9015_props, "KWorld PlusTV Dual DVB-T PCI (DVB-T PC160-2T)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X,
+               &af9015_props, "AVerMedia AVerTV DVB-T Volar X", RC_MAP_AVERMEDIA_M135A) },
+       { DVB_USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380,
+               &af9015_props, "Xtensions XD-380", NULL) },
+       { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO,
+               &af9015_props, "MSI DIGIVOX Duo", RC_MAP_MSI_DIGIVOX_III) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2,
+               &af9015_props, "Fujitsu-Siemens Slim Mobile USB DVB-T", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TELESTAR,  USB_PID_TELESTAR_STARSTICK_2,
+               &af9015_props, "Telestar Starstick 2", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309,
+               &af9015_props, "AVerMedia A309", NULL) },
+       { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III,
+               &af9015_props, "MSI Digi VOX mini III", RC_MAP_MSI_DIGIVOX_III) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U,
+               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2,
+               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3,
+               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT,
+               &af9015_props, "TrekStor DVB-T USB Stick", RC_MAP_TREKSTOR) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850,
+               &af9015_props, "AverMedia AVerTV Volar Black HD (A850)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805,
+               &af9015_props, "AverMedia AVerTV Volar GPS 805 (A805)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU,
+               &af9015_props, "Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810,
+               &af9015_props, "KWorld Digial MC-810", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03,
+               &af9015_props, "Genius TVGo DVB-T03", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2,
+               &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T,
+               &af9015_props, "KWorld PlusTV DVB-T PCI Pro Card (DVB-T PC160-T)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20,
+               &af9015_props, "Sveon STV20 Tuner USB DVB-T HDTV", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2,
+               &af9015_props, "DigitalNow TinyTwin v2", RC_MAP_DIGITALNOW_TINYTWIN) },
+       { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS,
+               &af9015_props, "Leadtek WinFast DTV2000DS", RC_MAP_LEADTEK_Y04G0051) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T,
+               &af9015_props, "KWorld USB DVB-T Stick Mobile (UB383-T)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4,
+               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M,
+               &af9015_props, "AverMedia AVerTV Volar M (A815Mac)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC,
+               &af9015_props, "TerraTec Cinergy T Stick RC", RC_MAP_TERRATEC_SLIM_2) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
+               &af9015_props, "TerraTec Cinergy T Stick Dual RC", RC_MAP_TERRATEC_SLIM) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T,
+               &af9015_props, "AverMedia AVerTV Red HD+ (A850T)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3,
+               &af9015_props, "DigitalNow TinyTwin v3", RC_MAP_DIGITALNOW_TINYTWIN) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22,
+               &af9015_props, "Sveon STV22 Dual USB DVB-T Tuner HDTV", RC_MAP_MSI_DIGIVOX_III) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, af9015_id_table);
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver af9015_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = af9015_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(af9015_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Afatech AF9015 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/af9015.h b/drivers/media/dvb/dvb-usb-v2/af9015.h
new file mode 100644 (file)
index 0000000..b41ee73
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ * Thanks to Afatech who kindly provided 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; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef AF9015_H
+#define AF9015_H
+
+#include <linux/hash.h>
+#include "dvb_usb.h"
+#include "af9013.h"
+#include "dvb-pll.h"
+#include "mt2060.h"
+#include "qt1010.h"
+#include "tda18271.h"
+#include "mxl5005s.h"
+#include "mc44s803.h"
+#include "tda18218.h"
+#include "mxl5007t.h"
+
+#define DVB_USB_LOG_PREFIX "af9015"
+
+#ifdef CONFIG_DVB_USB_DEBUG
+#define dprintk(var, level, args...) \
+       do { if ((var & level)) printk(args); } while (0)
+#define DVB_USB_DEBUG_STATUS
+#else
+#define dprintk(args...)
+#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
+#endif
+
+#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
+#define deb_rc(args...)   dprintk(dvb_usb_af9015_debug, 0x02, args)
+
+#undef err
+#define err(format, arg...) \
+       printk(KERN_ERR     DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) \
+       printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+
+/* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
+   We use smaller - about 1/4 from the original, 5 and 87. */
+#define TS_PACKET_SIZE            188
+
+#define TS_USB20_PACKET_COUNT      87
+#define TS_USB20_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
+
+#define TS_USB11_PACKET_COUNT       5
+#define TS_USB11_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
+
+#define TS_USB20_MAX_PACKET_SIZE  512
+#define TS_USB11_MAX_PACKET_SIZE   64
+
+#define AF9015_I2C_EEPROM  0xa0
+#define AF9015_I2C_DEMOD   0x38
+#define AF9015_USB_TIMEOUT 2000
+
+/* EEPROM locations */
+#define AF9015_EEPROM_IR_MODE        0x18
+#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34
+#define AF9015_EEPROM_TS_MODE        0x31
+#define AF9015_EEPROM_DEMOD2_I2C     0x32
+
+#define AF9015_EEPROM_SAW_BW1        0x35
+#define AF9015_EEPROM_XTAL_TYPE1     0x36
+#define AF9015_EEPROM_SPEC_INV1      0x37
+#define AF9015_EEPROM_IF1L           0x38
+#define AF9015_EEPROM_IF1H           0x39
+#define AF9015_EEPROM_MT2060_IF1L    0x3a
+#define AF9015_EEPROM_MT2060_IF1H    0x3b
+#define AF9015_EEPROM_TUNER_ID1      0x3c
+
+#define AF9015_EEPROM_SAW_BW2        0x45
+#define AF9015_EEPROM_XTAL_TYPE2     0x46
+#define AF9015_EEPROM_SPEC_INV2      0x47
+#define AF9015_EEPROM_IF2L           0x48
+#define AF9015_EEPROM_IF2H           0x49
+#define AF9015_EEPROM_MT2060_IF2L    0x4a
+#define AF9015_EEPROM_MT2060_IF2H    0x4b
+#define AF9015_EEPROM_TUNER_ID2      0x4c
+
+#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
+
+struct req_t {
+       u8  cmd;       /* [0] */
+       /*  seq */     /* [1] */
+       u8  i2c_addr;  /* [2] */
+       u16 addr;      /* [3|4] */
+       u8  mbox;      /* [5] */
+       u8  addr_len;  /* [6] */
+       u8  data_len;  /* [7] */
+       u8  *data;
+};
+
+enum af9015_cmd {
+       GET_CONFIG           = 0x10,
+       DOWNLOAD_FIRMWARE    = 0x11,
+       BOOT                 = 0x13,
+       READ_MEMORY          = 0x20,
+       WRITE_MEMORY         = 0x21,
+       READ_WRITE_I2C       = 0x22,
+       COPY_FIRMWARE        = 0x23,
+       RECONNECT_USB        = 0x5a,
+       WRITE_VIRTUAL_MEMORY = 0x26,
+       GET_IR_CODE          = 0x27,
+       READ_I2C,
+       WRITE_I2C,
+};
+
+enum af9015_ir_mode {
+       AF9015_IR_MODE_DISABLED = 0,
+       AF9015_IR_MODE_HID,
+       AF9015_IR_MODE_RLC,
+       AF9015_IR_MODE_RC6,
+       AF9015_IR_MODE_POLLING, /* just guess */
+};
+
+struct af9015_state {
+       u8 ir_mode;
+       u8 rc_repeat;
+       u32 rc_keycode;
+       u8 rc_last[4];
+       u8 dual_mode;
+       u8 seq; /* packet sequence number */
+       u16 mt2060_if1[2];
+       u16 firmware_size;
+       u16 firmware_checksum;
+       u32 eeprom_sum;
+       struct af9013_config af9013_config[2];
+
+       /* for demod callback override */
+       int (*set_frontend[2]) (struct dvb_frontend *fe);
+       int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status);
+       int (*init[2]) (struct dvb_frontend *fe);
+       int (*sleep[2]) (struct dvb_frontend *fe);
+       int (*tuner_init[2]) (struct dvb_frontend *fe);
+       int (*tuner_sleep[2]) (struct dvb_frontend *fe);
+       struct mutex fe_mutex;
+};
+
+enum af9015_remote {
+       AF9015_REMOTE_NONE                    = 0,
+/* 1 */        AF9015_REMOTE_A_LINK_DTU_M,
+       AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
+       AF9015_REMOTE_MYGICTV_U718,
+       AF9015_REMOTE_DIGITTRADE_DVB_T,
+/* 5 */        AF9015_REMOTE_AVERMEDIA_KS,
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/af9035.c b/drivers/media/dvb/dvb-usb-v2/af9035.c
new file mode 100644 (file)
index 0000000..79197f4
--- /dev/null
@@ -0,0 +1,1087 @@
+/*
+ * Afatech AF9035 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "af9035.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static u16 af9035_checksum(const u8 *buf, size_t len)
+{
+       size_t i;
+       u16 checksum = 0;
+
+       for (i = 1; i < len; i++) {
+               if (i % 2)
+                       checksum += buf[i] << 8;
+               else
+                       checksum += buf[i];
+       }
+       checksum = ~checksum;
+
+       return checksum;
+}
+
+static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
+{
+#define BUF_LEN 64
+#define REQ_HDR_LEN 4 /* send header size */
+#define ACK_HDR_LEN 3 /* rece header size */
+#define CHECKSUM_LEN 2
+#define USB_TIMEOUT 2000
+       struct state *state = d_to_priv(d);
+       int ret, wlen, rlen;
+       u8 buf[BUF_LEN];
+       u16 checksum, tmp_checksum;
+
+       /* buffer overflow check */
+       if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
+               req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
+               pr_debug("%s: too much data wlen=%d rlen=%d\n", __func__,
+                               req->wlen, req->rlen);
+               return -EINVAL;
+       }
+
+       buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1;
+       buf[1] = req->mbox;
+       buf[2] = req->cmd;
+       buf[3] = state->seq++;
+       memcpy(&buf[REQ_HDR_LEN], req->wbuf, req->wlen);
+
+       wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN;
+       rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN;
+
+       /* calc and add checksum */
+       checksum = af9035_checksum(buf, buf[0] - 1);
+       buf[buf[0] - 1] = (checksum >> 8);
+       buf[buf[0] - 0] = (checksum & 0xff);
+
+       /* no ack for these packets */
+       if (req->cmd == CMD_FW_DL)
+               rlen = 0;
+
+       ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
+       if (ret)
+               goto err;
+
+       /* no ack for those packets */
+       if (req->cmd == CMD_FW_DL)
+               goto exit;
+
+       /* verify checksum */
+       checksum = af9035_checksum(buf, rlen - 2);
+       tmp_checksum = (buf[rlen - 2] << 8) | buf[rlen - 1];
+       if (tmp_checksum != checksum) {
+               pr_err("%s: command=%02x checksum mismatch (%04x != %04x)\n",
+                               KBUILD_MODNAME, req->cmd, tmp_checksum,
+                               checksum);
+               ret = -EIO;
+               goto err;
+       }
+
+       /* check status */
+       if (buf[2]) {
+               pr_debug("%s: command=%02x failed fw error=%d\n", __func__,
+                               req->cmd, buf[2]);
+               ret = -EIO;
+               goto err;
+       }
+
+       /* read request, copy returned data to return buf */
+       if (req->rlen)
+               memcpy(req->rbuf, &buf[ACK_HDR_LEN], req->rlen);
+
+exit:
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+/* write multiple registers */
+static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
+{
+       u8 wbuf[6 + len];
+       u8 mbox = (reg >> 16) & 0xff;
+       struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL };
+
+       wbuf[0] = len;
+       wbuf[1] = 2;
+       wbuf[2] = 0;
+       wbuf[3] = 0;
+       wbuf[4] = (reg >> 8) & 0xff;
+       wbuf[5] = (reg >> 0) & 0xff;
+       memcpy(&wbuf[6], val, len);
+
+       return af9035_ctrl_msg(d, &req);
+}
+
+/* read multiple registers */
+static int af9035_rd_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
+{
+       u8 wbuf[] = { len, 2, 0, 0, (reg >> 8) & 0xff, reg & 0xff };
+       u8 mbox = (reg >> 16) & 0xff;
+       struct usb_req req = { CMD_MEM_RD, mbox, sizeof(wbuf), wbuf, len, val };
+
+       return af9035_ctrl_msg(d, &req);
+}
+
+/* write single register */
+static int af9035_wr_reg(struct dvb_usb_device *d, u32 reg, u8 val)
+{
+       return af9035_wr_regs(d, reg, &val, 1);
+}
+
+/* read single register */
+static int af9035_rd_reg(struct dvb_usb_device *d, u32 reg, u8 *val)
+{
+       return af9035_rd_regs(d, reg, val, 1);
+}
+
+/* write single register with mask */
+static int af9035_wr_reg_mask(struct dvb_usb_device *d, u32 reg, u8 val,
+               u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = af9035_rd_regs(d, reg, &tmp, 1);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return af9035_wr_regs(d, reg, &val, 1);
+}
+
+static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
+               struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct state *state = d_to_priv(d);
+       int ret;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       /*
+        * I2C sub header is 5 bytes long. Meaning of those bytes are:
+        * 0: data len
+        * 1: I2C addr << 1
+        * 2: reg addr len
+        *    byte 3 and 4 can be used as reg addr
+        * 3: reg addr MSB
+        *    used when reg addr len is set to 2
+        * 4: reg addr LSB
+        *    used when reg addr len is set to 1 or 2
+        *
+        * For the simplify we do not use register addr at all.
+        * NOTE: As a firmware knows tuner type there is very small possibility
+        * there could be some tuner I2C hacks done by firmware and this may
+        * lead problems if firmware expects those bytes are used.
+        */
+       if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
+                       (msg[1].flags & I2C_M_RD)) {
+               if (msg[0].len > 40 || msg[1].len > 40) {
+                       /* TODO: correct limits > 40 */
+                       ret = -EOPNOTSUPP;
+               } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
+                       /* integrated demod */
+                       u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+                                       msg[0].buf[2];
+                       ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
+                                       msg[1].len);
+               } else {
+                       /* I2C */
+                       u8 buf[5 + msg[0].len];
+                       struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
+                                       buf, msg[1].len, msg[1].buf };
+                       buf[0] = msg[1].len;
+                       buf[1] = msg[0].addr << 1;
+                       buf[2] = 0x00; /* reg addr len */
+                       buf[3] = 0x00; /* reg addr MSB */
+                       buf[4] = 0x00; /* reg addr LSB */
+                       memcpy(&buf[5], msg[0].buf, msg[0].len);
+                       ret = af9035_ctrl_msg(d, &req);
+               }
+       } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
+               if (msg[0].len > 40) {
+                       /* TODO: correct limits > 40 */
+                       ret = -EOPNOTSUPP;
+               } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
+                       /* integrated demod */
+                       u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+                                       msg[0].buf[2];
+                       ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
+                                       msg[0].len - 3);
+               } else {
+                       /* I2C */
+                       u8 buf[5 + msg[0].len];
+                       struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf,
+                                       0, NULL };
+                       buf[0] = msg[0].len;
+                       buf[1] = msg[0].addr << 1;
+                       buf[2] = 0x00; /* reg addr len */
+                       buf[3] = 0x00; /* reg addr MSB */
+                       buf[4] = 0x00; /* reg addr LSB */
+                       memcpy(&buf[5], msg[0].buf, msg[0].len);
+                       ret = af9035_ctrl_msg(d, &req);
+               }
+       } else {
+               /*
+                * We support only two kind of I2C transactions:
+                * 1) 1 x read + 1 x write
+                * 2) 1 x write
+                */
+               ret = -EOPNOTSUPP;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+
+       if (ret < 0)
+               return ret;
+       else
+               return num;
+}
+
+static u32 af9035_i2c_functionality(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm af9035_i2c_algo = {
+       .master_xfer = af9035_i2c_master_xfer,
+       .functionality = af9035_i2c_functionality,
+};
+
+static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       int ret;
+       u8 wbuf[1] = { 1 };
+       u8 rbuf[4];
+       struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf,
+                       sizeof(rbuf), rbuf };
+
+       ret = af9035_ctrl_msg(d, &req);
+       if (ret < 0)
+               goto err;
+
+       pr_debug("%s: reply=%02x %02x %02x %02x\n", __func__,
+               rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
+       if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
+               ret = WARM;
+       else
+               ret = COLD;
+
+       return ret;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_download_firmware(struct dvb_usb_device *d,
+               const struct firmware *fw)
+{
+       int ret, i, j, len;
+       u8 wbuf[1];
+       u8 rbuf[4];
+       struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
+       struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL };
+       struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
+       u8 hdr_core;
+       u16 hdr_addr, hdr_data_len, hdr_checksum;
+       #define MAX_DATA 58
+       #define HDR_SIZE 7
+
+       /*
+        * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info!
+        *
+        * byte 0: MCS 51 core
+        *  There are two inside the AF9035 (1=Link and 2=OFDM) with separate
+        *  address spaces
+        * byte 1-2: Big endian destination address
+        * byte 3-4: Big endian number of data bytes following the header
+        * byte 5-6: Big endian header checksum, apparently ignored by the chip
+        *  Calculated as ~(h[0]*256+h[1]+h[2]*256+h[3]+h[4]*256)
+        */
+
+       for (i = fw->size; i > HDR_SIZE;) {
+               hdr_core = fw->data[fw->size - i + 0];
+               hdr_addr = fw->data[fw->size - i + 1] << 8;
+               hdr_addr |= fw->data[fw->size - i + 2] << 0;
+               hdr_data_len = fw->data[fw->size - i + 3] << 8;
+               hdr_data_len |= fw->data[fw->size - i + 4] << 0;
+               hdr_checksum = fw->data[fw->size - i + 5] << 8;
+               hdr_checksum |= fw->data[fw->size - i + 6] << 0;
+
+               pr_debug("%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
+                               __func__, hdr_core, hdr_addr, hdr_data_len,
+                               hdr_checksum);
+
+               if (((hdr_core != 1) && (hdr_core != 2)) ||
+                               (hdr_data_len > i)) {
+                       pr_debug("%s: bad firmware\n", __func__);
+                       break;
+               }
+
+               /* download begin packet */
+               req.cmd = CMD_FW_DL_BEGIN;
+               ret = af9035_ctrl_msg(d, &req);
+               if (ret < 0)
+                       goto err;
+
+               /* download firmware packet(s) */
+               for (j = HDR_SIZE + hdr_data_len; j > 0; j -= MAX_DATA) {
+                       len = j;
+                       if (len > MAX_DATA)
+                               len = MAX_DATA;
+                       req_fw_dl.wlen = len;
+                       req_fw_dl.wbuf = (u8 *) &fw->data[fw->size - i +
+                                       HDR_SIZE + hdr_data_len - j];
+                       ret = af9035_ctrl_msg(d, &req_fw_dl);
+                       if (ret < 0)
+                               goto err;
+               }
+
+               /* download end packet */
+               req.cmd = CMD_FW_DL_END;
+               ret = af9035_ctrl_msg(d, &req);
+               if (ret < 0)
+                       goto err;
+
+               i -= hdr_data_len + HDR_SIZE;
+
+               pr_debug("%s: data uploaded=%zu\n", __func__, fw->size - i);
+       }
+
+       /* firmware loaded, request boot */
+       req.cmd = CMD_FW_BOOT;
+       ret = af9035_ctrl_msg(d, &req);
+       if (ret < 0)
+               goto err;
+
+       /* ensure firmware starts */
+       wbuf[0] = 1;
+       ret = af9035_ctrl_msg(d, &req_fw_ver);
+       if (ret < 0)
+               goto err;
+
+       if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
+               pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
+               ret = -ENODEV;
+               goto err;
+       }
+
+       pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
+                       rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_download_firmware_it9135(struct dvb_usb_device *d,
+               const struct firmware *fw)
+{
+       int ret, i, i_prev;
+       u8 wbuf[1];
+       u8 rbuf[4];
+       struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
+       struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL };
+       struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
+       #define HDR_SIZE 7
+
+       /*
+        * There seems to be following firmware header. Meaning of bytes 0-3
+        * is unknown.
+        *
+        * 0: 3
+        * 1: 0, 1
+        * 2: 0
+        * 3: 1, 2, 3
+        * 4: addr MSB
+        * 5: addr LSB
+        * 6: count of data bytes ?
+        */
+
+       for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) {
+               if (i == fw->size ||
+                               (fw->data[i + 0] == 0x03 &&
+                               (fw->data[i + 1] == 0x00 ||
+                               fw->data[i + 1] == 0x01) &&
+                               fw->data[i + 2] == 0x00)) {
+                       req_fw_dl.wlen = i - i_prev;
+                       req_fw_dl.wbuf = (u8 *) &fw->data[i_prev];
+                       i_prev = i;
+                       ret = af9035_ctrl_msg(d, &req_fw_dl);
+                       if (ret < 0)
+                               goto err;
+
+                       pr_debug("%s: data uploaded=%d\n", __func__, i);
+               }
+       }
+
+       /* firmware loaded, request boot */
+       req.cmd = CMD_FW_BOOT;
+       ret = af9035_ctrl_msg(d, &req);
+       if (ret < 0)
+               goto err;
+
+       /* ensure firmware starts */
+       wbuf[0] = 1;
+       ret = af9035_ctrl_msg(d, &req_fw_ver);
+       if (ret < 0)
+               goto err;
+
+       if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
+               pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
+               ret = -ENODEV;
+               goto err;
+       }
+
+       pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
+                       rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_read_config(struct dvb_usb_device *d)
+{
+       struct state *state = d_to_priv(d);
+       int ret, i, eeprom_shift = 0;
+       u8 tmp;
+       u16 tmp16;
+
+       /* check if there is dual tuners */
+       ret = af9035_rd_reg(d, EEPROM_DUAL_MODE, &tmp);
+       if (ret < 0)
+               goto err;
+
+       state->dual_mode = tmp;
+       pr_debug("%s: dual mode=%d\n", __func__, state->dual_mode);
+
+       for (i = 0; i < state->dual_mode + 1; i++) {
+               /* tuner */
+               ret = af9035_rd_reg(d, EEPROM_1_TUNER_ID + eeprom_shift, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               state->af9033_config[i].tuner = tmp;
+               pr_debug("%s: [%d]tuner=%02x\n", __func__, i, tmp);
+
+               switch (tmp) {
+               case AF9033_TUNER_TUA9001:
+               case AF9033_TUNER_FC0011:
+               case AF9033_TUNER_MXL5007T:
+               case AF9033_TUNER_TDA18218:
+                       state->af9033_config[i].spec_inv = 1;
+                       break;
+               default:
+                       pr_info("%s: tuner ID=%02x not supported, please " \
+                                       "report!", KBUILD_MODNAME, tmp);
+               };
+
+               /* tuner IF frequency */
+               ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_L + eeprom_shift, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               tmp16 = tmp;
+
+               ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_H + eeprom_shift, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               tmp16 |= tmp << 8;
+
+               pr_debug("%s: [%d]IF=%d\n", __func__, i, tmp16);
+
+               eeprom_shift = 0x10; /* shift for the 2nd tuner params */
+       }
+
+       /* get demod clock */
+       ret = af9035_rd_reg(d, 0x00d800, &tmp);
+       if (ret < 0)
+               goto err;
+
+       tmp = (tmp >> 0) & 0x0f;
+
+       for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
+               state->af9033_config[i].clock = clock_lut[tmp];
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_read_config_it9135(struct dvb_usb_device *d)
+{
+       struct state *state = d_to_priv(d);
+       int ret, i;
+       u8 tmp;
+
+       state->dual_mode = false;
+
+       /* get demod clock */
+       ret = af9035_rd_reg(d, 0x00d800, &tmp);
+       if (ret < 0)
+               goto err;
+
+       tmp = (tmp >> 0) & 0x0f;
+
+       for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
+               state->af9033_config[i].clock = clock_lut_it9135[tmp];
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
+               int cmd, int arg)
+{
+       int ret;
+
+       switch (cmd) {
+       case FC0011_FE_CALLBACK_POWER:
+               /* Tuner enable */
+               ret = af9035_wr_reg_mask(d, 0xd8eb, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0xd8ec, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0xd8ed, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               /* LED */
+               ret = af9035_wr_reg_mask(d, 0xd8d0, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0xd8d1, 1, 1);
+               if (ret < 0)
+                       goto err;
+
+               usleep_range(10000, 50000);
+               break;
+       case FC0011_FE_CALLBACK_RESET:
+               ret = af9035_wr_reg(d, 0xd8e9, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg(d, 0xd8e8, 1);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg(d, 0xd8e7, 1);
+               if (ret < 0)
+                       goto err;
+
+               usleep_range(10000, 20000);
+
+               ret = af9035_wr_reg(d, 0xd8e7, 0);
+               if (ret < 0)
+                       goto err;
+
+               usleep_range(10000, 20000);
+               break;
+       default:
+               ret = -EINVAL;
+               goto err;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
+{
+       struct state *state = d_to_priv(d);
+
+       switch (state->af9033_config[0].tuner) {
+       case AF9033_TUNER_FC0011:
+               return af9035_fc0011_tuner_callback(d, cmd, arg);
+       default:
+               break;
+       }
+
+       return -ENODEV;
+}
+
+static int af9035_frontend_callback(void *adapter_priv, int component,
+                                   int cmd, int arg)
+{
+       struct i2c_adapter *adap = adapter_priv;
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+
+       switch (component) {
+       case DVB_FRONTEND_COMPONENT_TUNER:
+               return af9035_tuner_callback(d, cmd, arg);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct state *state = adap_to_priv(adap);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret;
+
+       if (!state->af9033_config[adap->id].tuner) {
+               /* unsupported tuner */
+               ret = -ENODEV;
+               goto err;
+       }
+
+       if (adap->id == 0) {
+               state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
+               state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL;
+
+               ret = af9035_wr_reg(d, 0x00417f,
+                               state->af9033_config[1].i2c_addr);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg(d, 0x00d81a,
+                               state->dual_mode);
+               if (ret < 0)
+                       goto err;
+       }
+
+       /* attach demodulator */
+       adap->fe[0] = dvb_attach(af9033_attach,
+                       &state->af9033_config[adap->id], &d->i2c_adap);
+       if (adap->fe[0] == NULL) {
+               ret = -ENODEV;
+               goto err;
+       }
+
+       /* disable I2C-gate */
+       adap->fe[0]->ops.i2c_gate_ctrl = NULL;
+       adap->fe[0]->callback = af9035_frontend_callback;
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static struct tua9001_config af9035_tua9001_config = {
+       .i2c_addr = 0x60,
+};
+
+static const struct fc0011_config af9035_fc0011_config = {
+       .i2c_address = 0x60,
+};
+
+static struct mxl5007t_config af9035_mxl5007t_config = {
+       .xtal_freq_hz = MxL_XTAL_24_MHZ,
+       .if_freq_hz = MxL_IF_4_57_MHZ,
+       .invert_if = 0,
+       .loop_thru_enable = 0,
+       .clk_out_enable = 0,
+       .clk_out_amp = MxL_CLKOUT_AMP_0_94V,
+};
+
+static struct tda18218_config af9035_tda18218_config = {
+       .i2c_address = 0x60,
+       .i2c_wr_max = 21,
+};
+
+static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct state *state = adap_to_priv(adap);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret;
+       struct dvb_frontend *fe;
+
+       switch (state->af9033_config[adap->id].tuner) {
+       case AF9033_TUNER_TUA9001:
+               /* AF9035 gpiot3 = TUA9001 RESETN
+                  AF9035 gpiot2 = TUA9001 RXEN */
+
+               /* configure gpiot2 and gpiot2 as output */
+               ret = af9035_wr_reg_mask(d, 0x00d8ec, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0x00d8ed, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0x00d8e8, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9035_wr_reg_mask(d, 0x00d8e9, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               /* reset tuner */
+               ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x00, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               usleep_range(2000, 20000);
+
+               ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               /* activate tuner RX */
+               /* TODO: use callback for TUA9001 RXEN */
+               ret = af9035_wr_reg_mask(d, 0x00d8eb, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               /* attach tuner */
+               fe = dvb_attach(tua9001_attach, adap->fe[0],
+                               &d->i2c_adap, &af9035_tua9001_config);
+               break;
+       case AF9033_TUNER_FC0011:
+               fe = dvb_attach(fc0011_attach, adap->fe[0],
+                               &d->i2c_adap, &af9035_fc0011_config);
+               break;
+       case AF9033_TUNER_MXL5007T:
+               ret = af9035_wr_reg(d, 0x00d8e0, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8e1, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8df, 0);
+               if (ret < 0)
+                       goto err;
+
+               msleep(30);
+
+               ret = af9035_wr_reg(d, 0x00d8df, 1);
+               if (ret < 0)
+                       goto err;
+
+               msleep(300);
+
+               ret = af9035_wr_reg(d, 0x00d8c0, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8c1, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8bf, 0);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8b4, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8b5, 1);
+               if (ret < 0)
+                       goto err;
+               ret = af9035_wr_reg(d, 0x00d8b3, 1);
+               if (ret < 0)
+                       goto err;
+
+               /* attach tuner */
+               fe = dvb_attach(mxl5007t_attach, adap->fe[0],
+                               &d->i2c_adap, 0x60, &af9035_mxl5007t_config);
+               break;
+       case AF9033_TUNER_TDA18218:
+               /* attach tuner */
+               fe = dvb_attach(tda18218_attach, adap->fe[0],
+                               &d->i2c_adap, &af9035_tda18218_config);
+               break;
+       default:
+               fe = NULL;
+       }
+
+       if (fe == NULL) {
+               ret = -ENODEV;
+               goto err;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_init(struct dvb_usb_device *d)
+{
+       struct state *state = d_to_priv(d);
+       int ret, i;
+       u16 frame_size = 87 * 188 / 4;
+       u8  packet_size = 512 / 4;
+       struct reg_val_mask tab[] = {
+               { 0x80f99d, 0x01, 0x01 },
+               { 0x80f9a4, 0x01, 0x01 },
+               { 0x00dd11, 0x00, 0x20 },
+               { 0x00dd11, 0x00, 0x40 },
+               { 0x00dd13, 0x00, 0x20 },
+               { 0x00dd13, 0x00, 0x40 },
+               { 0x00dd11, 0x20, 0x20 },
+               { 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
+               { 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
+               { 0x00dd0c, packet_size, 0xff},
+               { 0x00dd11, state->dual_mode << 6, 0x40 },
+               { 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
+               { 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
+               { 0x00dd0d, packet_size, 0xff },
+               { 0x80f9a3, 0x00, 0x01 },
+               { 0x80f9cd, 0x00, 0x01 },
+               { 0x80f99d, 0x00, 0x01 },
+               { 0x80f9a4, 0x00, 0x01 },
+       };
+
+       pr_debug("%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
+               __func__, d->udev->speed, frame_size, packet_size);
+
+       /* init endpoints */
+       for (i = 0; i < ARRAY_SIZE(tab); i++) {
+               ret = af9035_wr_reg_mask(d, tab[i].reg, tab[i].val,
+                               tab[i].mask);
+               if (ret < 0)
+                       goto err;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9035_rc_query(struct dvb_usb_device *d)
+{
+       unsigned int key;
+       unsigned char b[4];
+       int ret;
+       struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, b };
+
+       ret = af9035_ctrl_msg(d, &req);
+       if (ret < 0)
+               goto err;
+
+       if ((b[2] + b[3]) == 0xff) {
+               if ((b[0] + b[1]) == 0xff) {
+                       /* NEC */
+                       key = b[0] << 8 | b[2];
+               } else {
+                       /* ext. NEC */
+                       key = b[0] << 16 | b[1] << 8 | b[2];
+               }
+       } else {
+               key = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
+       }
+
+       rc_keydown(d->rc_dev, key, 0);
+
+err:
+       /* ignore errors */
+       return 0;
+}
+
+static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+       int ret;
+       u8 tmp;
+
+       ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp);
+       if (ret < 0)
+               goto err;
+
+       pr_debug("%s: ir_mode=%02x\n", __func__, tmp);
+
+       /* don't activate rc if in HID mode or if not available */
+       if (tmp == 5) {
+               ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               pr_debug("%s: ir_type=%02x\n", __func__, tmp);
+
+               switch (tmp) {
+               case 0: /* NEC */
+               default:
+                       rc->allowed_protos = RC_TYPE_NEC;
+                       break;
+               case 1: /* RC6 */
+                       rc->allowed_protos = RC_TYPE_RC6;
+                       break;
+               }
+
+               rc->query = af9035_rc_query;
+               rc->interval = 500;
+
+               /* load empty to enable rc */
+               if (!rc->map_name)
+                       rc->map_name = RC_MAP_EMPTY;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+/* interface 0 is used by DVB-T receiver and
+   interface 1 is for remote controller (HID) */
+static const struct dvb_usb_device_properties af9035_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .identify_state = af9035_identify_state,
+       .firmware = "dvb-usb-af9035-02.fw",
+       .download_firmware = af9035_download_firmware,
+
+       .i2c_algo = &af9035_i2c_algo,
+       .read_config = af9035_read_config,
+       .frontend_attach = af9035_frontend_attach,
+       .tuner_attach = af9035_tuner_attach,
+       .init = af9035_init,
+       .get_rc_config = af9035_get_rc_config,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
+               }, {
+                       .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
+               },
+       },
+};
+
+static const struct dvb_usb_device_properties it9135_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .identify_state = af9035_identify_state,
+       .firmware = "dvb-usb-it9135-01.fw",
+       .download_firmware = af9035_download_firmware_it9135,
+
+       .i2c_algo = &af9035_i2c_algo,
+       .read_config = af9035_read_config_it9135,
+       .frontend_attach = af9035_frontend_attach,
+       .tuner_attach = af9035_tuner_attach,
+       .init = af9035_init,
+       .get_rc_config = af9035_get_rc_config,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
+               }, {
+                       .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
+               },
+       },
+};
+
+static const struct usb_device_id af9035_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1000,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1001,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1002,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1003,
+               &af9035_props, "Afatech AF9035 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK,
+               &af9035_props, "TerraTec Cinergy T Stick", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835,
+               &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_B835,
+               &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_1867,
+               &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A867,
+               &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TWINSTAR,
+               &af9035_props, "AVerMedia Twinstar (A825)", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, af9035_id_table);
+
+static struct usb_driver af9035_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = af9035_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(af9035_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Afatech AF9035 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/af9035.h b/drivers/media/dvb/dvb-usb-v2/af9035.h
new file mode 100644 (file)
index 0000000..59ff69e
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Afatech AF9035 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef AF9035_H
+#define AF9035_H
+
+#include "dvb_usb.h"
+#include "af9033.h"
+#include "tua9001.h"
+#include "fc0011.h"
+#include "mxl5007t.h"
+#include "tda18218.h"
+
+struct reg_val {
+       u32 reg;
+       u8  val;
+};
+
+struct reg_val_mask {
+       u32 reg;
+       u8  val;
+       u8  mask;
+};
+
+struct usb_req {
+       u8  cmd;
+       u8  mbox;
+       u8  wlen;
+       u8  *wbuf;
+       u8  rlen;
+       u8  *rbuf;
+};
+
+struct state {
+       u8 seq; /* packet sequence number */
+       bool dual_mode;
+
+       struct af9033_config af9033_config[2];
+};
+
+u32 clock_lut[] = {
+       20480000, /*      FPGA */
+       16384000, /* 16.38 MHz */
+       20480000, /* 20.48 MHz */
+       36000000, /* 36.00 MHz */
+       30000000, /* 30.00 MHz */
+       26000000, /* 26.00 MHz */
+       28000000, /* 28.00 MHz */
+       32000000, /* 32.00 MHz */
+       34000000, /* 34.00 MHz */
+       24000000, /* 24.00 MHz */
+       22000000, /* 22.00 MHz */
+       12000000, /* 12.00 MHz */
+};
+
+u32 clock_lut_it9135[] = {
+       12000000, /* 12.00 MHz */
+       20480000, /* 20.48 MHz */
+       36000000, /* 36.00 MHz */
+       30000000, /* 30.00 MHz */
+       26000000, /* 26.00 MHz */
+       28000000, /* 28.00 MHz */
+       32000000, /* 32.00 MHz */
+       34000000, /* 34.00 MHz */
+       24000000, /* 24.00 MHz */
+       22000000, /* 22.00 MHz */
+};
+
+/* EEPROM locations */
+#define EEPROM_IR_MODE            0x430d
+#define EEPROM_DUAL_MODE          0x4326
+#define EEPROM_IR_TYPE            0x4329
+#define EEPROM_1_IFFREQ_L         0x432d
+#define EEPROM_1_IFFREQ_H         0x432e
+#define EEPROM_1_TUNER_ID         0x4331
+#define EEPROM_2_IFFREQ_L         0x433d
+#define EEPROM_2_IFFREQ_H         0x433e
+#define EEPROM_2_TUNER_ID         0x4341
+
+/* USB commands */
+#define CMD_MEM_RD                  0x00
+#define CMD_MEM_WR                  0x01
+#define CMD_I2C_RD                  0x02
+#define CMD_I2C_WR                  0x03
+#define CMD_IR_GET                  0x18
+#define CMD_FW_DL                   0x21
+#define CMD_FW_QUERYINFO            0x22
+#define CMD_FW_BOOT                 0x23
+#define CMD_FW_DL_BEGIN             0x24
+#define CMD_FW_DL_END               0x25
+#define CMD_FW_SCATTER_WR           0x29
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/anysee.c b/drivers/media/dvb/dvb-usb-v2/anysee.c
new file mode 100644 (file)
index 0000000..fb3829a
--- /dev/null
@@ -0,0 +1,1324 @@
+/*
+ * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * TODO:
+ * - add smart card reader support for Conditional Access (CA)
+ *
+ * Card reader in Anysee is nothing more than ISO 7816 card reader.
+ * There is no hardware CAM in any Anysee device sold.
+ * In my understanding it should be implemented by making own module
+ * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
+ * module registers serial interface that can be used to communicate
+ * with any ISO 7816 smart card.
+ *
+ * Any help according to implement serial smart card reader support
+ * is highly welcome!
+ */
+
+#include "anysee.h"
+#include "dvb-pll.h"
+#include "tda1002x.h"
+#include "mt352.h"
+#include "mt352_priv.h"
+#include "zl10353.h"
+#include "tda18212.h"
+#include "cx24116.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "isl6423.h"
+#include "cxd2820r.h"
+
+/* debug */
+static int dvb_usb_anysee_debug;
+module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static DEFINE_MUTEX(anysee_usb_mutex);
+
+static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
+       u8 *rbuf, u8 rlen)
+{
+       struct anysee_state *state = d_to_priv(d);
+       int act_len, ret, i;
+       u8 buf[64];
+
+       memcpy(&buf[0], sbuf, slen);
+       buf[60] = state->seq++;
+
+       mutex_lock(&anysee_usb_mutex);
+
+       deb_xfer(">>> ");
+       debug_dump(buf, slen, deb_xfer);
+
+       /* We need receive one message more after dvb_usb_generic_rw due
+          to weird transaction flow, which is 1 x send + 2 x receive. */
+       ret = dvb_usbv2_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf));
+       if (ret)
+               goto error_unlock;
+
+       /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
+        * (EPIPE, Broken pipe). Function supports currently msleep() as a
+        * parameter but I would not like to use it, since according to
+        * Documentation/timers/timers-howto.txt it should not be used such
+        * short, under < 20ms, sleeps. Repeating failed message would be
+        * better choice as not to add unwanted delays...
+        * Fixing that correctly is one of those or both;
+        * 1) use repeat if possible
+        * 2) add suitable delay
+        */
+
+       /* get answer, retry few times if error returned */
+       for (i = 0; i < 3; i++) {
+               /* receive 2nd answer */
+               ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
+                       d->props->generic_bulk_ctrl_endpoint), buf, sizeof(buf),
+                       &act_len, 2000);
+
+               if (ret) {
+                       deb_info("%s: recv bulk message failed: %d",
+                                       __func__, ret);
+               } else {
+                       deb_xfer("<<< ");
+                       debug_dump(buf, rlen, deb_xfer);
+
+                       if (buf[63] != 0x4f)
+                               deb_info("%s: cmd failed\n", __func__);
+
+                       break;
+               }
+       }
+
+       if (ret) {
+               /* all retries failed, it is fatal */
+               err("%s: recv bulk message failed: %d", __func__, ret);
+               goto error_unlock;
+       }
+
+       /* read request, copy returned data to return buf */
+       if (rbuf && rlen)
+               memcpy(rbuf, buf, rlen);
+
+error_unlock:
+       mutex_unlock(&anysee_usb_mutex);
+
+       return ret;
+}
+
+static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
+{
+       u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
+       int ret;
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
+       deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
+       return ret;
+}
+
+static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
+{
+       u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
+       deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
+       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+}
+
+/* write single register with mask */
+static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
+       u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = anysee_read_reg(d, reg, &tmp);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return anysee_write_reg(d, reg, val);
+}
+
+/* read single register with mask */
+static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
+       u8 mask)
+{
+       int ret, i;
+       u8 tmp;
+
+       ret = anysee_read_reg(d, reg, &tmp);
+       if (ret)
+               return ret;
+
+       tmp &= mask;
+
+       /* find position of the first bit */
+       for (i = 0; i < 8; i++) {
+               if ((mask >> i) & 0x01)
+                       break;
+       }
+       *val = tmp >> i;
+
+       return 0;
+}
+
+static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
+{
+       u8 buf[] = {CMD_GET_HW_INFO};
+       return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
+}
+
+static int anysee_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
+       deb_info("%s: onoff:%02x\n", __func__, onoff);
+       return anysee_ctrl_msg(fe_to_d(fe), buf, sizeof(buf), NULL, 0);
+}
+
+static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
+{
+       u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
+       deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
+       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+}
+
+static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
+{
+       u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
+       deb_info("%s: onoff:%02x\n", __func__, onoff);
+       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+}
+
+/* I2C */
+static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+       int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int ret = 0, inc, i = 0;
+       u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       while (i < num) {
+               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+                       if (msg[i].len > 2 || msg[i+1].len > 60) {
+                               ret = -EOPNOTSUPP;
+                               break;
+                       }
+                       buf[0] = CMD_I2C_READ;
+                       buf[1] = (msg[i].addr << 1) | 0x01;
+                       buf[2] = msg[i].buf[0];
+                       buf[3] = msg[i].buf[1];
+                       buf[4] = msg[i].len-1;
+                       buf[5] = msg[i+1].len;
+                       ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
+                               msg[i+1].len);
+                       inc = 2;
+               } else {
+                       if (msg[i].len > 48) {
+                               ret = -EOPNOTSUPP;
+                               break;
+                       }
+                       buf[0] = CMD_I2C_WRITE;
+                       buf[1] = (msg[i].addr << 1);
+                       buf[2] = msg[i].len;
+                       buf[3] = 0x01;
+                       memcpy(&buf[4], msg[i].buf, msg[i].len);
+                       ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
+                       inc = 1;
+               }
+               if (ret)
+                       break;
+
+               i += inc;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret ? ret : i;
+}
+
+static u32 anysee_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm anysee_i2c_algo = {
+       .master_xfer   = anysee_master_xfer,
+       .functionality = anysee_i2c_func,
+};
+
+static int anysee_mt352_demod_init(struct dvb_frontend *fe)
+{
+       static u8 clock_config[]   = { CLOCK_CTL,  0x38, 0x28 };
+       static u8 reset[]          = { RESET,      0x80 };
+       static u8 adc_ctl_1_cfg[]  = { ADC_CTL_1,  0x40 };
+       static u8 agc_cfg[]        = { AGC_TARGET, 0x28, 0x20 };
+       static u8 gpp_ctl_cfg[]    = { GPP_CTL,    0x33 };
+       static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+
+       mt352_write(fe, clock_config,   sizeof(clock_config));
+       udelay(200);
+       mt352_write(fe, reset,          sizeof(reset));
+       mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
+
+       mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
+       mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
+       mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
+
+       return 0;
+}
+
+/* Callbacks for DVB USB */
+static struct tda10023_config anysee_tda10023_config = {
+       .demod_address = (0x1a >> 1),
+       .invert = 0,
+       .xtal   = 16000000,
+       .pll_m  = 11,
+       .pll_p  = 3,
+       .pll_n  = 1,
+       .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
+       .deltaf = 0xfeeb,
+};
+
+static struct mt352_config anysee_mt352_config = {
+       .demod_address = (0x1e >> 1),
+       .demod_init    = anysee_mt352_demod_init,
+};
+
+static struct zl10353_config anysee_zl10353_config = {
+       .demod_address = (0x1e >> 1),
+       .parallel_ts = 1,
+};
+
+static struct zl10353_config anysee_zl10353_tda18212_config2 = {
+       .demod_address = (0x1e >> 1),
+       .parallel_ts = 1,
+       .disable_i2c_gate_ctrl = 1,
+       .no_tuner = 1,
+       .if2 = 41500,
+};
+
+static struct zl10353_config anysee_zl10353_tda18212_config = {
+       .demod_address = (0x18 >> 1),
+       .parallel_ts = 1,
+       .disable_i2c_gate_ctrl = 1,
+       .no_tuner = 1,
+       .if2 = 41500,
+};
+
+static struct tda10023_config anysee_tda10023_tda18212_config = {
+       .demod_address = (0x1a >> 1),
+       .xtal   = 16000000,
+       .pll_m  = 12,
+       .pll_p  = 3,
+       .pll_n  = 1,
+       .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
+       .deltaf = 0xba02,
+};
+
+static struct tda18212_config anysee_tda18212_config = {
+       .i2c_address = (0xc0 >> 1),
+       .if_dvbt_6 = 4150,
+       .if_dvbt_7 = 4150,
+       .if_dvbt_8 = 4150,
+       .if_dvbc = 5000,
+};
+
+static struct tda18212_config anysee_tda18212_config2 = {
+       .i2c_address = 0x60 /* (0xc0 >> 1) */,
+       .if_dvbt_6 = 3550,
+       .if_dvbt_7 = 3700,
+       .if_dvbt_8 = 4150,
+       .if_dvbt2_6 = 3250,
+       .if_dvbt2_7 = 4000,
+       .if_dvbt2_8 = 4000,
+       .if_dvbc = 5000,
+};
+
+static struct cx24116_config anysee_cx24116_config = {
+       .demod_address = (0xaa >> 1),
+       .mpg_clk_pos_pol = 0x00,
+       .i2c_wr_max = 48,
+};
+
+static struct stv0900_config anysee_stv0900_config = {
+       .demod_address = (0xd0 >> 1),
+       .demod_mode = 0,
+       .xtal = 8000000,
+       .clkmode = 3,
+       .diseqc_mode = 2,
+       .tun1_maddress = 0,
+       .tun1_adc = 1, /* 1 Vpp */
+       .path1_mode = 3,
+};
+
+static struct stv6110_config anysee_stv6110_config = {
+       .i2c_address = (0xc0 >> 1),
+       .mclk = 16000000,
+       .clk_div = 1,
+};
+
+static struct isl6423_config anysee_isl6423_config = {
+       .current_max = SEC_CURRENT_800m,
+       .curlim  = SEC_CURRENT_LIM_OFF,
+       .mod_extern = 1,
+       .addr = (0x10 >> 1),
+};
+
+static struct cxd2820r_config anysee_cxd2820r_config = {
+       .i2c_address = 0x6d, /* (0xda >> 1) */
+       .ts_mode = 0x38,
+};
+
+/*
+ * New USB device strings: Mfr=1, Product=2, SerialNumber=0
+ * Manufacturer: AMT.CO.KR
+ *
+ * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
+ * PCB: ?
+ * parts: DNOS404ZH102A(MT352, DTT7579(?))
+ *
+ * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
+ * PCB: PCB 507T (rev1.61)
+ * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
+ * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
+ * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
+ *
+ * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
+ * PCB: 507CD (rev1.1)
+ * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
+ * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
+ * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
+ * IOD[0] ZL10353 1=enabled
+ * IOA[7] TS 0=enabled
+ * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
+ *
+ * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
+ * PCB: 507DC (rev0.2)
+ * parts: TDA10023, DTOS403IH102B TM, CST56I01
+ * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
+ * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
+ * IOD[0] TDA10023 1=enabled
+ *
+ * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
+ * PCB: 507SI (rev2.1)
+ * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
+ * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
+ * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
+ * IOD[0] CX24116 1=enabled
+ *
+ * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
+ * PCB: 507FA (rev0.4)
+ * parts: TDA10023, DTOS403IH102B TM, TDA8024
+ * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
+ * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] tuner 1=enabled
+ *
+ * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
+ * PCB: 507FA (rev1.1)
+ * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
+ * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
+ * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
+ * DVB-C:
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] tuner 1=enabled
+ * DVB-T:
+ * IOD[0] ZL10353 1=enabled
+ * IOE[0] tuner 0=enabled
+ * tuner is behind ZL10353 I2C-gate
+ *
+ * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
+ * PCB: 508TC (rev0.6)
+ * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[4] TDA18212 1=enabled
+ * DVB-C:
+ * IOD[6] ZL10353 0=disabled
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] IF 1=enabled
+ * DVB-T:
+ * IOD[5] TDA10023 0=disabled
+ * IOD[6] ZL10353 1=enabled
+ * IOE[0] IF 0=enabled
+ *
+ * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
+ * PCB: 508S2 (rev0.7)
+ * parts: DNBU10512IST(STV0903, STV6110), ISL6423
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[5] STV0903 1=enabled
+ *
+ * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
+ * PCB: 508T2C (rev0.3)
+ * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[5] CXD2820R 1=enabled
+ *
+ * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
+ * PCB: 508PTC (rev0.5)
+ * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[4] TDA18212 1=enabled
+ * DVB-C:
+ * IOD[6] ZL10353 0=disabled
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] IF 1=enabled
+ * DVB-T:
+ * IOD[5] TDA10023 0=disabled
+ * IOD[6] ZL10353 1=enabled
+ * IOE[0] IF 0=enabled
+ *
+ * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
+ * PCB: 508PS2 (rev0.4)
+ * parts: DNBU10512IST(STV0903, STV6110), ISL6423
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[5] STV0903 1=enabled
+ */
+
+static int anysee_read_config(struct dvb_usb_device *d)
+{
+       struct anysee_state *state = d_to_priv(d);
+       int ret;
+       u8 hw_info[3];
+
+       /*
+        * Check which hardware we have.
+        * We must do this call two times to get reliable values (hw/fw bug).
+        */
+       ret = anysee_get_hw_info(d, hw_info);
+       if (ret)
+               goto error;
+
+       ret = anysee_get_hw_info(d, hw_info);
+       if (ret)
+               goto error;
+
+       /* Meaning of these info bytes are guessed. */
+       info("firmware version:%d.%d hardware id:%d",
+               hw_info[1], hw_info[2], hw_info[0]);
+
+       state->hw = hw_info[0];
+error:
+       return ret;
+}
+
+/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
+static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       /* enable / disable tuner access on IOE[4] */
+       return anysee_wr_reg_mask(fe_to_d(fe), REG_IOE, (enable << 4), 0x10);
+}
+
+static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct anysee_state *state = fe_to_priv(fe);
+       struct dvb_usb_device *d = fe_to_d(fe);
+       int ret;
+
+       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+       /* no frontend sleep control */
+       if (onoff == 0)
+               return 0;
+
+       switch (state->hw) {
+       case ANYSEE_HW_507FA: /* 15 */
+               /* E30 Combo Plus */
+               /* E30 C Plus */
+
+               if (fe->id == 0)  {
+                       /* disable DVB-T demod on IOD[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-C demod on IOD[5] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-C tuner on IOE[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
+                       if (ret)
+                               goto error;
+               } else {
+                       /* disable DVB-C demod on IOD[5] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-T demod on IOD[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-T tuner on IOE[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
+                       if (ret)
+                               goto error;
+               }
+
+               break;
+       case ANYSEE_HW_508TC: /* 18 */
+       case ANYSEE_HW_508PTC: /* 21 */
+               /* E7 TC */
+               /* E7 PTC */
+
+               if (fe->id == 0)  {
+                       /* disable DVB-T demod on IOD[6] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-C demod on IOD[5] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+                       if (ret)
+                               goto error;
+
+                       /* enable IF route on IOE[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
+                       if (ret)
+                               goto error;
+               } else {
+                       /* disable DVB-C demod on IOD[5] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+                       if (ret)
+                               goto error;
+
+                       /* enable DVB-T demod on IOD[6] */
+                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
+                       if (ret)
+                               goto error;
+
+                       /* enable IF route on IOE[0] */
+                       ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
+                       if (ret)
+                               goto error;
+               }
+
+               break;
+       default:
+               ret = 0;
+       }
+
+error:
+       return ret;
+}
+
+static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct anysee_state *state = adap_to_priv(adap);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret;
+       u8 tmp;
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = anysee_tda18212_config.i2c_address,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = "\x00",
+               }, {
+                       .addr = anysee_tda18212_config.i2c_address,
+                       .flags = I2C_M_RD,
+                       .len = 1,
+                       .buf = &tmp,
+               }
+       };
+
+       switch (state->hw) {
+       case ANYSEE_HW_507T: /* 2 */
+               /* E30 */
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(mt352_attach, &anysee_mt352_config,
+                               &d->i2c_adap);
+               if (adap->fe[0])
+                       break;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
+                               &d->i2c_adap);
+
+               break;
+       case ANYSEE_HW_507CD: /* 6 */
+               /* E30 Plus */
+
+               /* enable DVB-T demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* enable transport stream on IOA[7] */
+               ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
+                               &d->i2c_adap);
+
+               break;
+       case ANYSEE_HW_507DC: /* 10 */
+               /* E30 C Plus */
+
+               /* enable DVB-C demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(tda10023_attach,
+                               &anysee_tda10023_config, &d->i2c_adap, 0x48);
+
+               break;
+       case ANYSEE_HW_507SI: /* 11 */
+               /* E30 S2 Plus */
+
+               /* enable DVB-S/S2 demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(cx24116_attach, &anysee_cx24116_config,
+                               &d->i2c_adap);
+
+               break;
+       case ANYSEE_HW_507FA: /* 15 */
+               /* E30 Combo Plus */
+               /* E30 C Plus */
+
+               /* enable tuner on IOE[4] */
+               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 4), 0x10);
+               if (ret)
+                       goto error;
+
+               /* probe TDA18212 */
+               tmp = 0;
+               ret = i2c_transfer(&d->i2c_adap, msg, 2);
+               if (ret == 2 && tmp == 0xc7)
+                       deb_info("%s: TDA18212 found\n", __func__);
+               else
+                       tmp = 0;
+
+               /* disable tuner on IOE[4] */
+               ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 4), 0x10);
+               if (ret)
+                       goto error;
+
+               /* disable DVB-T demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* enable DVB-C demod on IOD[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               if (tmp == 0xc7) {
+                       /* TDA18212 config */
+                       adap->fe[0] = dvb_attach(tda10023_attach,
+                                       &anysee_tda10023_tda18212_config,
+                                       &d->i2c_adap, 0x48);
+
+                       /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+                       if (adap->fe[0])
+                               adap->fe[0]->ops.i2c_gate_ctrl =
+                                               anysee_i2c_gate_ctrl;
+               } else {
+                       /* PLL config */
+                       adap->fe[0] = dvb_attach(tda10023_attach,
+                                       &anysee_tda10023_config,
+                                       &d->i2c_adap, 0x48);
+               }
+
+               /* break out if first frontend attaching fails */
+               if (!adap->fe[0])
+                       break;
+
+               /* disable DVB-C demod on IOD[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* enable DVB-T demod on IOD[0] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               if (tmp == 0xc7) {
+                       /* TDA18212 config */
+                       adap->fe[1] = dvb_attach(zl10353_attach,
+                                       &anysee_zl10353_tda18212_config2,
+                                       &d->i2c_adap);
+
+                       /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+                       if (adap->fe[1])
+                               adap->fe[1]->ops.i2c_gate_ctrl =
+                                               anysee_i2c_gate_ctrl;
+               } else {
+                       /* PLL config */
+                       adap->fe[1] = dvb_attach(zl10353_attach,
+                                       &anysee_zl10353_config,
+                                       &d->i2c_adap);
+               }
+
+               break;
+       case ANYSEE_HW_508TC: /* 18 */
+       case ANYSEE_HW_508PTC: /* 21 */
+               /* E7 TC */
+               /* E7 PTC */
+
+               /* disable DVB-T demod on IOD[6] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
+               if (ret)
+                       goto error;
+
+               /* enable DVB-C demod on IOD[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(tda10023_attach,
+                               &anysee_tda10023_tda18212_config,
+                               &d->i2c_adap, 0x48);
+
+               /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+               if (adap->fe[0])
+                       adap->fe[0]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
+
+               /* break out if first frontend attaching fails */
+               if (!adap->fe[0])
+                       break;
+
+               /* disable DVB-C demod on IOD[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* enable DVB-T demod on IOD[6] */
+               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[1] = dvb_attach(zl10353_attach,
+                               &anysee_zl10353_tda18212_config,
+                               &d->i2c_adap);
+
+               /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+               if (adap->fe[1])
+                       adap->fe[1]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
+
+               state->has_ci = true;
+
+               break;
+       case ANYSEE_HW_508S2: /* 19 */
+       case ANYSEE_HW_508PS2: /* 22 */
+               /* E7 S2 */
+               /* E7 PS2 */
+
+               /* enable DVB-S/S2 demod on IOE[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(stv0900_attach,
+                               &anysee_stv0900_config, &d->i2c_adap, 0);
+
+               state->has_ci = true;
+
+               break;
+       case ANYSEE_HW_508T2C: /* 20 */
+               /* E7 T2C */
+
+               /* enable DVB-T/T2/C demod on IOE[5] */
+               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
+               if (ret)
+                       goto error;
+
+               /* attach demod */
+               adap->fe[0] = dvb_attach(cxd2820r_attach,
+                               &anysee_cxd2820r_config, &d->i2c_adap);
+
+               state->has_ci = true;
+
+               break;
+       }
+
+       if (!adap->fe[0]) {
+               /* we have no frontend :-( */
+               ret = -ENODEV;
+               err("Unsupported Anysee version. " \
+                       "Please report the <linux-media@vger.kernel.org>.");
+       }
+error:
+       return ret;
+}
+
+static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct anysee_state *state = adap_to_priv(adap);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct dvb_frontend *fe;
+       int ret;
+       deb_info("%s: adap=%d\n", __func__, adap->id);
+
+       switch (state->hw) {
+       case ANYSEE_HW_507T: /* 2 */
+               /* E30 */
+
+               /* attach tuner */
+               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1), NULL,
+                               DVB_PLL_THOMSON_DTT7579);
+
+               break;
+       case ANYSEE_HW_507CD: /* 6 */
+               /* E30 Plus */
+
+               /* attach tuner */
+               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1),
+                               &d->i2c_adap, DVB_PLL_THOMSON_DTT7579);
+
+               break;
+       case ANYSEE_HW_507DC: /* 10 */
+               /* E30 C Plus */
+
+               /* attach tuner */
+               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
+                               &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+
+               break;
+       case ANYSEE_HW_507SI: /* 11 */
+               /* E30 S2 Plus */
+
+               /* attach LNB controller */
+               fe = dvb_attach(isl6423_attach, adap->fe[0], &d->i2c_adap,
+                               &anysee_isl6423_config);
+
+               break;
+       case ANYSEE_HW_507FA: /* 15 */
+               /* E30 Combo Plus */
+               /* E30 C Plus */
+
+               /* Try first attach TDA18212 silicon tuner on IOE[4], if that
+                * fails attach old simple PLL. */
+
+               /* attach tuner */
+               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
+                               &anysee_tda18212_config);
+
+               if (fe && adap->fe[1]) {
+                       /* attach tuner for 2nd FE */
+                       fe = dvb_attach(tda18212_attach, adap->fe[1],
+                                       &d->i2c_adap, &anysee_tda18212_config);
+                       break;
+               } else if (fe) {
+                       break;
+               }
+
+               /* attach tuner */
+               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
+                               &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+
+               if (fe && adap->fe[1]) {
+                       /* attach tuner for 2nd FE */
+                       fe = dvb_attach(dvb_pll_attach, adap->fe[0],
+                                       (0xc0 >> 1), &d->i2c_adap,
+                                       DVB_PLL_SAMSUNG_DTOS403IH102A);
+               }
+
+               break;
+       case ANYSEE_HW_508TC: /* 18 */
+       case ANYSEE_HW_508PTC: /* 21 */
+               /* E7 TC */
+               /* E7 PTC */
+
+               /* attach tuner */
+               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
+                               &anysee_tda18212_config);
+
+               if (fe) {
+                       /* attach tuner for 2nd FE */
+                       fe = dvb_attach(tda18212_attach, adap->fe[1],
+                                       &d->i2c_adap, &anysee_tda18212_config);
+               }
+
+               break;
+       case ANYSEE_HW_508S2: /* 19 */
+       case ANYSEE_HW_508PS2: /* 22 */
+               /* E7 S2 */
+               /* E7 PS2 */
+
+               /* attach tuner */
+               fe = dvb_attach(stv6110_attach, adap->fe[0],
+                               &anysee_stv6110_config, &d->i2c_adap);
+
+               if (fe) {
+                       /* attach LNB controller */
+                       fe = dvb_attach(isl6423_attach, adap->fe[0],
+                                       &d->i2c_adap, &anysee_isl6423_config);
+               }
+
+               break;
+
+       case ANYSEE_HW_508T2C: /* 20 */
+               /* E7 T2C */
+
+               /* attach tuner */
+               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
+                               &anysee_tda18212_config2);
+
+               break;
+       default:
+               fe = NULL;
+       }
+
+       if (fe)
+               ret = 0;
+       else
+               ret = -ENODEV;
+
+       return ret;
+}
+
+static int anysee_rc_query(struct dvb_usb_device *d)
+{
+       u8 buf[] = {CMD_GET_IR_CODE};
+       u8 ircode[2];
+       int ret;
+
+       /* Remote controller is basic NEC using address byte 0x08.
+          Anysee device RC query returns only two bytes, status and code,
+          address byte is dropped. Also it does not return any value for
+          NEC RCs having address byte other than 0x08. Due to that, we
+          cannot use that device as standard NEC receiver.
+          It could be possible make hack which reads whole code directly
+          from device memory... */
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
+       if (ret)
+               return ret;
+
+       if (ircode[0]) {
+               deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
+               rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
+       }
+
+       return 0;
+}
+
+static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+       rc->allowed_protos = RC_TYPE_NEC;
+       rc->query          = anysee_rc_query;
+       rc->interval       = 250;  /* windows driver uses 500ms */
+
+       return 0;
+}
+
+static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
+       int addr)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
+       u8 val;
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
+       if (ret)
+               return ret;
+
+       return val;
+}
+
+static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
+       int addr, u8 val)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
+       u8 addr)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
+       u8 val;
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
+       if (ret)
+               return ret;
+
+       return val;
+}
+
+static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
+       u8 addr, u8 val)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
+
+       ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+       struct anysee_state *state = d_to_priv(d);
+
+       state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       msleep(300);
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       msleep(30);
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
+{
+       struct dvb_usb_device *d = ci->data;
+       int ret;
+
+       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
+       int open)
+{
+       struct dvb_usb_device *d = ci->data;
+       struct anysee_state *state = d_to_priv(d);
+       int ret;
+       u8 tmp;
+
+       ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
+       if (ret)
+               return ret;
+
+       if (tmp == 0) {
+               ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
+               if (time_after(jiffies, state->ci_cam_ready))
+                       ret |= DVB_CA_EN50221_POLL_CAM_READY;
+       }
+
+       return ret;
+}
+
+static int anysee_ci_init(struct dvb_usb_device *d)
+{
+       struct anysee_state *state = d_to_priv(d);
+       int ret;
+
+       state->ci.owner               = THIS_MODULE;
+       state->ci.read_attribute_mem  = anysee_ci_read_attribute_mem;
+       state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
+       state->ci.read_cam_control    = anysee_ci_read_cam_control;
+       state->ci.write_cam_control   = anysee_ci_write_cam_control;
+       state->ci.slot_reset          = anysee_ci_slot_reset;
+       state->ci.slot_shutdown       = anysee_ci_slot_shutdown;
+       state->ci.slot_ts_enable      = anysee_ci_slot_ts_enable;
+       state->ci.poll_slot_status    = anysee_ci_poll_slot_status;
+       state->ci.data                = d;
+
+       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
+       if (ret)
+               return ret;
+
+       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 2)|(0 << 1)|(0 << 0), 0x07);
+       if (ret)
+               return ret;
+
+       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 2)|(1 << 1)|(1 << 0), 0x07);
+       if (ret)
+               return ret;
+
+       ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static void anysee_ci_release(struct dvb_usb_device *d)
+{
+       struct anysee_state *state = d_to_priv(d);
+
+       /* detach CI */
+       if (state->has_ci)
+               dvb_ca_en50221_release(&state->ci);
+
+       return;
+}
+
+static int anysee_init(struct dvb_usb_device *d)
+{
+       struct anysee_state *state = d_to_priv(d);
+       int ret;
+
+       /* There is one interface with two alternate settings.
+          Alternate setting 0 is for bulk transfer.
+          Alternate setting 1 is for isochronous transfer.
+          We use bulk transfer (alternate setting 0). */
+       ret = usb_set_interface(d->udev, 0, 0);
+       if (ret)
+               return ret;
+
+       /* LED light */
+       ret = anysee_led_ctrl(d, 0x01, 0x03);
+       if (ret)
+               return ret;
+
+       /* enable IR */
+       ret = anysee_ir_ctrl(d, 1);
+       if (ret)
+               return ret;
+
+       /* attach CI */
+       if (state->has_ci) {
+               ret = anysee_ci_init(d);
+               if (ret) {
+                       state->has_ci = false;
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static void anysee_exit(struct dvb_usb_device *d)
+{
+       return anysee_ci_release(d);
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties anysee_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct anysee_state),
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo         = &anysee_i2c_algo,
+       .read_config      = anysee_read_config,
+       .frontend_attach  = anysee_frontend_attach,
+       .tuner_attach     = anysee_tuner_attach,
+       .init             = anysee_init,
+       .get_rc_config    = anysee_get_rc_config,
+       .frontend_ctrl    = anysee_frontend_ctrl,
+       .streaming_ctrl   = anysee_streaming_ctrl,
+       .exit             = anysee_exit,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x82, 8, 16 * 512),
+               }
+       }
+};
+
+static const struct usb_device_id anysee_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE,
+               &anysee_props, "Anysee", RC_MAP_ANYSEE) },
+       { DVB_USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE,
+               &anysee_props, "Anysee", RC_MAP_ANYSEE) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, anysee_id_table);
+
+static struct usb_driver anysee_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = anysee_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(anysee_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/anysee.h b/drivers/media/dvb/dvb-usb-v2/anysee.h
new file mode 100644 (file)
index 0000000..dc40dcf
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * TODO:
+ * - add smart card reader support for Conditional Access (CA)
+ *
+ * Card reader in Anysee is nothing more than ISO 7816 card reader.
+ * There is no hardware CAM in any Anysee device sold.
+ * In my understanding it should be implemented by making own module
+ * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
+ * module registers serial interface that can be used to communicate
+ * with any ISO 7816 smart card.
+ *
+ * Any help according to implement serial smart card reader support
+ * is highly welcome!
+ */
+
+#ifndef _DVB_USB_ANYSEE_H_
+#define _DVB_USB_ANYSEE_H_
+
+#define DVB_USB_LOG_PREFIX "anysee"
+#include "dvb_usb.h"
+#include "dvb_ca_en50221.h"
+
+#ifdef CONFIG_DVB_USB_DEBUG
+#define dprintk(var, level, args...) \
+       do { if ((var & level)) printk(args); } while (0)
+#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
+
+#define debug_dump(b, l, func) {\
+       int loop_; \
+       for (loop_ = 0; loop_ < l; loop_++) \
+               func("%02x ", b[loop_]); \
+       func("\n");\
+}
+
+#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
+#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
+#define deb_rc(args...)   dprintk(dvb_usb_anysee_debug, 0x04, args)
+#define deb_reg(args...)  dprintk(dvb_usb_anysee_debug, 0x08, args)
+#define deb_i2c(args...)  dprintk(dvb_usb_anysee_debug, 0x10, args)
+#define deb_fw(args...)   dprintk(dvb_usb_anysee_debug, 0x20, args)
+
+#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)
+
+enum cmd {
+       CMD_I2C_READ            = 0x33,
+       CMD_I2C_WRITE           = 0x31,
+       CMD_REG_READ            = 0xb0,
+       CMD_REG_WRITE           = 0xb1,
+       CMD_STREAMING_CTRL      = 0x12,
+       CMD_LED_AND_IR_CTRL     = 0x16,
+       CMD_GET_IR_CODE         = 0x41,
+       CMD_GET_HW_INFO         = 0x19,
+       CMD_SMARTCARD           = 0x34,
+       CMD_CI                  = 0x37,
+};
+
+struct anysee_state {
+       u8 hw; /* PCB ID */
+       u8 seq;
+       u8 fe_id:1; /* frondend ID */
+       u8 has_ci:1;
+       struct dvb_ca_en50221 ci;
+       unsigned long ci_cam_ready; /* jiffies */
+};
+
+#define ANYSEE_HW_507T    2 /* E30 */
+#define ANYSEE_HW_507CD   6 /* E30 Plus */
+#define ANYSEE_HW_507DC  10 /* E30 C Plus */
+#define ANYSEE_HW_507SI  11 /* E30 S2 Plus */
+#define ANYSEE_HW_507FA  15 /* E30 Combo Plus / E30 C Plus */
+#define ANYSEE_HW_508TC  18 /* E7 TC */
+#define ANYSEE_HW_508S2  19 /* E7 S2 */
+#define ANYSEE_HW_508T2C 20 /* E7 T2C */
+#define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */
+#define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */
+
+#define REG_IOA       0x80 /* Port A (bit addressable) */
+#define REG_IOB       0x90 /* Port B (bit addressable) */
+#define REG_IOC       0xa0 /* Port C (bit addressable) */
+#define REG_IOD       0xb0 /* Port D (bit addressable) */
+#define REG_IOE       0xb1 /* Port E (NOT bit addressable) */
+#define REG_OEA       0xb2 /* Port A Output Enable */
+#define REG_OEB       0xb3 /* Port B Output Enable */
+#define REG_OEC       0xb4 /* Port C Output Enable */
+#define REG_OED       0xb5 /* Port D Output Enable */
+#define REG_OEE       0xb6 /* Port E Output Enable */
+
+#endif
+
+/***************************************************************************
+ * USB API description (reverse engineered)
+ ***************************************************************************
+
+Transaction flow:
+=================
+BULK[00001] >>> REQUEST PACKET 64 bytes
+BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY)
+BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY)
+
+General reply packet(s) are always used if not own reply defined.
+
+============================================================================
+| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY)
+============================================================================
+|    00 | reply data (if any) from previous transaction
+|       | Just same reply packet as returned during previous transaction.
+|       | Needed only if reply is missed in previous transaction.
+|       | Just skip normally.
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY)
+============================================================================
+|    00 | reply data (if any)
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | I2C WRITE REQUEST PACKET
+============================================================================
+|    00 | 0x31 I2C write command
+----------------------------------------------------------------------------
+|    01 | i2c address
+----------------------------------------------------------------------------
+|    02 | data length
+|       | 0x02 (for typical I2C reg / val pair)
+----------------------------------------------------------------------------
+|    03 | 0x01
+----------------------------------------------------------------------------
+| 04-   | data
+----------------------------------------------------------------------------
+|   -59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | I2C READ REQUEST PACKET
+============================================================================
+|    00 | 0x33 I2C read command
+----------------------------------------------------------------------------
+|    01 | i2c address + 1
+----------------------------------------------------------------------------
+|    02 | register
+----------------------------------------------------------------------------
+|    03 | 0x00
+----------------------------------------------------------------------------
+|    04 | 0x00
+----------------------------------------------------------------------------
+|    05 | data length
+----------------------------------------------------------------------------
+| 06-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET
+============================================================================
+|    00 | 0xb1 register write command
+----------------------------------------------------------------------------
+| 01-02 | register
+----------------------------------------------------------------------------
+|    03 | 0x01
+----------------------------------------------------------------------------
+|    04 | value
+----------------------------------------------------------------------------
+| 05-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET
+============================================================================
+|    00 | 0xb0 register read command
+----------------------------------------------------------------------------
+| 01-02 | register
+----------------------------------------------------------------------------
+|    03 | 0x01
+----------------------------------------------------------------------------
+| 04-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | LED CONTROL REQUEST PACKET
+============================================================================
+|    00 | 0x16 LED and IR control command
+----------------------------------------------------------------------------
+|    01 | 0x01 (LED)
+----------------------------------------------------------------------------
+|    03 | 0x00 blink
+|       | 0x01 lights continuously
+----------------------------------------------------------------------------
+|    04 | blink interval
+|       | 0x00 fastest (looks like LED lights continuously)
+|       | 0xff slowest
+----------------------------------------------------------------------------
+| 05-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | IR CONTROL REQUEST PACKET
+============================================================================
+|    00 | 0x16 LED and IR control command
+----------------------------------------------------------------------------
+|    01 | 0x02 (IR)
+----------------------------------------------------------------------------
+|    03 | 0x00 IR disabled
+|       | 0x01 IR enabled
+----------------------------------------------------------------------------
+| 04-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | STREAMING CONTROL REQUEST PACKET
+============================================================================
+|    00 | 0x12 streaming control command
+----------------------------------------------------------------------------
+|    01 | 0x00 streaming disabled
+|       | 0x01 streaming enabled
+----------------------------------------------------------------------------
+|    02 | 0x00
+----------------------------------------------------------------------------
+| 03-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | REMOTE CONTROL REQUEST PACKET
+============================================================================
+|    00 | 0x41 remote control command
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | REMOTE CONTROL REPLY PACKET
+============================================================================
+|    00 | 0x00 code not received
+|       | 0x01 code received
+----------------------------------------------------------------------------
+|    01 | remote control code
+----------------------------------------------------------------------------
+| 02-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | GET HARDWARE INFO REQUEST PACKET
+============================================================================
+|    00 | 0x19 get hardware info command
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | GET HARDWARE INFO REPLY PACKET
+============================================================================
+|    00 | hardware id
+----------------------------------------------------------------------------
+| 01-02 | firmware version
+----------------------------------------------------------------------------
+| 03-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | SMART CARD READER PACKET
+============================================================================
+|    00 | 0x34 smart card reader command
+----------------------------------------------------------------------------
+|    xx |
+----------------------------------------------------------------------------
+| xx-59 | don't care
+----------------------------------------------------------------------------
+|    60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+*/
diff --git a/drivers/media/dvb/dvb-usb-v2/au6610.c b/drivers/media/dvb/dvb-usb-v2/au6610.c
new file mode 100644 (file)
index 0000000..05f2a86
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
+ *
+ * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "au6610.h"
+#include "zl10353.h"
+#include "qt1010.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
+                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       int ret;
+       u16 index;
+       u8 *usb_buf;
+
+       /*
+        * allocate enough for all known requests,
+        * read returns 5 and write 6 bytes
+        */
+       usb_buf = kmalloc(6, GFP_KERNEL);
+       if (!usb_buf)
+               return -ENOMEM;
+
+       switch (wlen) {
+       case 1:
+               index = wbuf[0] << 8;
+               break;
+       case 2:
+               index = wbuf[0] << 8;
+               index += wbuf[1];
+               break;
+       default:
+               pr_err("%s: wlen = %d, aborting\n", KBUILD_MODNAME, wlen);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
+                             USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
+                             usb_buf, 6, AU6610_USB_TIMEOUT);
+       if (ret < 0)
+               goto error;
+
+       switch (operation) {
+       case AU6610_REQ_I2C_READ:
+       case AU6610_REQ_USB_READ:
+               /* requested value is always 5th byte in buffer */
+               rbuf[0] = usb_buf[4];
+       }
+error:
+       kfree(usb_buf);
+       return ret;
+}
+
+static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr,
+                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       u8 request;
+       u8 wo = (rbuf == NULL || rlen == 0); /* write-only */
+
+       if (wo) {
+               request = AU6610_REQ_I2C_WRITE;
+       } else { /* rw */
+               request = AU6610_REQ_I2C_READ;
+       }
+
+       return au6610_usb_msg(d, request, addr, wbuf, wlen, rbuf, rlen);
+}
+
+
+/* I2C */
+static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                          int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+       if (num > 2)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               /* write/read request */
+               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+                       if (au6610_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 (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
+                                              msg[i].len, NULL, 0) < 0)
+                               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+
+static u32 au6610_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm au6610_i2c_algo = {
+       .master_xfer   = au6610_i2c_xfer,
+       .functionality = au6610_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config au6610_zl10353_config = {
+       .demod_address = 0x0f,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+};
+
+static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       adap->fe[0] = dvb_attach(zl10353_attach, &au6610_zl10353_config,
+                       &adap_to_d(adap)->i2c_adap);
+       if (adap->fe[0] == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static struct qt1010_config au6610_qt1010_config = {
+       .i2c_address = 0x62
+};
+
+static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       return dvb_attach(qt1010_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &au6610_qt1010_config) == NULL ? -ENODEV : 0;
+}
+
+static int au6610_init(struct dvb_usb_device *d)
+{
+       /* TODO: this functionality belongs likely to the streaming control */
+       /* bInterfaceNumber 0, bAlternateSetting 5 */
+       return usb_set_interface(d->udev, 0, 5);
+}
+
+static struct dvb_usb_device_properties au6610_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+
+       .i2c_algo = &au6610_i2c_algo,
+       .frontend_attach = au6610_zl10353_frontend_attach,
+       .tuner_attach = au6610_qt1010_tuner_attach,
+       .init = au6610_init,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(0x82, 5, 40, 942, 1),
+               },
+       },
+};
+
+static const struct usb_device_id au6610_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110,
+               &au6610_props, "Sigmatek DVB-110", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, au6610_id_table);
+
+static struct usb_driver au6610_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = au6610_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(au6610_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/au6610.h b/drivers/media/dvb/dvb-usb-v2/au6610.h
new file mode 100644 (file)
index 0000000..ea337bf
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
+ *
+ * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef AU6610_H
+#define AU6610_H
+#include "dvb_usb.h"
+
+#define AU6610_REQ_I2C_WRITE   0x14
+#define AU6610_REQ_I2C_READ    0x13
+#define AU6610_REQ_USB_WRITE   0x16
+#define AU6610_REQ_USB_READ    0x15
+
+#define AU6610_USB_TIMEOUT 1000
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/ce6230.c b/drivers/media/dvb/dvb-usb-v2/ce6230.c
new file mode 100644 (file)
index 0000000..84ff4a9
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Intel CE6230 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "ce6230.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
+{
+       int ret;
+       unsigned int pipe;
+       u8 request;
+       u8 requesttype;
+       u16 value;
+       u16 index;
+       u8 *buf;
+
+       request = req->cmd;
+       value = req->value;
+       index = req->index;
+
+       switch (req->cmd) {
+       case I2C_READ:
+       case DEMOD_READ:
+       case REG_READ:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+               break;
+       case I2C_WRITE:
+       case DEMOD_WRITE:
+       case REG_WRITE:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+               break;
+       default:
+               pr_debug("%s: unknown command=%02x\n", __func__, req->cmd);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       buf = kmalloc(req->data_len, GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
+               /* write */
+               memcpy(buf, req->data, req->data_len);
+               pipe = usb_sndctrlpipe(d->udev, 0);
+       } else {
+               /* read */
+               pipe = usb_rcvctrlpipe(d->udev, 0);
+       }
+
+       msleep(1); /* avoid I2C errors */
+
+       ret = usb_control_msg(d->udev, pipe, request, requesttype, value, index,
+                       buf, req->data_len, CE6230_USB_TIMEOUT);
+
+       ce6230_debug_dump(request, requesttype, value, index, buf,
+                       req->data_len);
+
+       if (ret < 0)
+               pr_err("%s: usb_control_msg() failed=%d\n", KBUILD_MODNAME,
+                               ret);
+       else
+               ret = 0;
+
+       /* read request, copy returned data to return buf */
+       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+               memcpy(req->data, buf, req->data_len);
+
+       kfree(buf);
+error:
+       return ret;
+}
+
+/* I2C */
+static struct zl10353_config ce6230_zl10353_config;
+
+static int ce6230_i2c_master_xfer(struct i2c_adapter *adap,
+               struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int ret = 0, i = 0;
+       struct usb_req req;
+
+       if (num > 2)
+               return -EOPNOTSUPP;
+
+       memset(&req, 0, sizeof(req));
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       while (i < num) {
+               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+                       if (msg[i].addr ==
+                               ce6230_zl10353_config.demod_address) {
+                               req.cmd = DEMOD_READ;
+                               req.value = msg[i].addr >> 1;
+                               req.index = msg[i].buf[0];
+                               req.data_len = msg[i+1].len;
+                               req.data = &msg[i+1].buf[0];
+                               ret = ce6230_ctrl_msg(d, &req);
+                       } else {
+                               pr_err("%s: I2C read not implemented\n",
+                                               KBUILD_MODNAME);
+                               ret = -EOPNOTSUPP;
+                       }
+                       i += 2;
+               } else {
+                       if (msg[i].addr ==
+                               ce6230_zl10353_config.demod_address) {
+                               req.cmd = DEMOD_WRITE;
+                               req.value = msg[i].addr >> 1;
+                               req.index = msg[i].buf[0];
+                               req.data_len = msg[i].len-1;
+                               req.data = &msg[i].buf[1];
+                               ret = ce6230_ctrl_msg(d, &req);
+                       } else {
+                               req.cmd = I2C_WRITE;
+                               req.value = 0x2000 + (msg[i].addr >> 1);
+                               req.index = 0x0000;
+                               req.data_len = msg[i].len;
+                               req.data = &msg[i].buf[0];
+                               ret = ce6230_ctrl_msg(d, &req);
+                       }
+                       i += 1;
+               }
+               if (ret)
+                       break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return ret ? ret : i;
+}
+
+static u32 ce6230_i2c_functionality(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ce6230_i2c_algorithm = {
+       .master_xfer   = ce6230_i2c_master_xfer,
+       .functionality = ce6230_i2c_functionality,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config ce6230_zl10353_config = {
+       .demod_address = 0x1e,
+       .adc_clock = 450000,
+       .if2 = 45700,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+       .clock_ctl_1 = 0x34,
+       .pll_0 = 0x0e,
+};
+
+static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       pr_debug("%s:\n", __func__);
+
+       adap->fe[0] = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
+                       &adap_to_d(adap)->i2c_adap);
+       if (adap->fe[0] == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static struct mxl5005s_config ce6230_mxl5003s_config = {
+       .i2c_address     = 0xc6,
+       .if_freq         = IF_FREQ_4570000HZ,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_DEFAULT,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       int ret;
+
+       pr_debug("%s:\n", __func__);
+
+       ret = dvb_attach(mxl5005s_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
+       return ret;
+}
+
+static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       int ret;
+
+       pr_debug("%s: onoff=%d\n", __func__, onoff);
+
+       /* InterfaceNumber 1 / AlternateSetting 0     idle
+          InterfaceNumber 1 / AlternateSetting 1     streaming */
+       ret = usb_set_interface(d->udev, 1, onoff);
+       if (ret)
+               pr_err("%s: usb_set_interface() failed=%d\n", KBUILD_MODNAME,
+                               ret);
+
+       return ret;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ce6230_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .bInterfaceNumber = 1,
+
+       .i2c_algo = &ce6230_i2c_algorithm,
+       .power_ctrl = ce6230_power_ctrl,
+       .frontend_attach = ce6230_zl10353_frontend_attach,
+       .tuner_attach = ce6230_mxl5003s_tuner_attach,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 6,
+                               .endpoint = 0x82,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = (16 * 512),
+                                       }
+                               }
+                       },
+               }
+       },
+};
+
+static const struct usb_device_id ce6230_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500,
+               &ce6230_props, "Intel CE9500 reference design", NULL) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310,
+               &ce6230_props, "AVerMedia A310 USB 2.0 DVB-T tuner", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, ce6230_id_table);
+
+static struct usb_driver ce6230_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = ce6230_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(ce6230_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Intel CE6230 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/ce6230.h b/drivers/media/dvb/dvb-usb-v2/ce6230.h
new file mode 100644 (file)
index 0000000..42d7544
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Intel CE6230 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef CE6230_H
+#define CE6230_H
+
+#include "dvb_usb.h"
+#include "zl10353.h"
+#include "mxl5005s.h"
+
+#define ce6230_debug_dump(r, t, v, i, b, l) { \
+       char *direction; \
+       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+               direction = ">>>"; \
+       else \
+               direction = "<<<"; \
+       pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s [%d bytes]\n", \
+                        __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
+                       l & 0xff, l >> 8, direction, l); \
+}
+
+#define CE6230_USB_TIMEOUT 1000
+
+struct usb_req {
+       u8  cmd;       /* [1] */
+       u16 value;     /* [2|3] */
+       u16 index;     /* [4|5] */
+       u16 data_len;  /* [6|7] */
+       u8  *data;
+};
+
+enum ce6230_cmd {
+       CONFIG_READ          = 0xd0, /* rd 0 (unclear) */
+       UNKNOWN_WRITE        = 0xc7, /* wr 7 (unclear) */
+       I2C_READ             = 0xd9, /* rd 9 (unclear) */
+       I2C_WRITE            = 0xca, /* wr a */
+       DEMOD_READ           = 0xdb, /* rd b */
+       DEMOD_WRITE          = 0xcc, /* wr c */
+       REG_READ             = 0xde, /* rd e */
+       REG_WRITE            = 0xcf, /* wr f */
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb.h b/drivers/media/dvb/dvb-usb-v2/dvb_usb.h
new file mode 100644 (file)
index 0000000..4db591b
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef DVB_USB_H
+#define DVB_USB_H
+
+#include <linux/usb/input.h>
+#include <linux/firmware.h>
+#include <media/rc-core.h>
+
+#include "dvb_frontend.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+#include "dmxdev.h"
+#include "../dvb-usb/dvb-usb-ids.h"
+
+/*
+ * device file: /dev/dvb/adapter[0-1]/frontend[0-2]
+ *
+ * |-- device
+ * |   |-- adapter0
+ * |   |   |-- frontend0
+ * |   |   |-- frontend1
+ * |   |   `-- frontend2
+ * |   `-- adapter1
+ * |       |-- frontend0
+ * |       |-- frontend1
+ * |       `-- frontend2
+ *
+ *
+ * Commonly used variable names:
+ * d = pointer to device (struct dvb_usb_device *)
+ * adap = pointer to adapter (struct dvb_usb_adapter *)
+ * fe = pointer to frontend (struct dvb_frontend *)
+ *
+ * Use macros defined in that file to resolve needed pointers.
+ */
+
+/* helper macros for every DVB USB driver use */
+#define adap_to_d(adap) (container_of(adap, struct dvb_usb_device, \
+               adapter[adap->id]))
+#define adap_to_priv(adap) (adap_to_d(adap)->priv)
+#define fe_to_adap(fe) ((struct dvb_usb_adapter *) ((fe)->dvb->priv))
+#define fe_to_d(fe) (adap_to_d(fe_to_adap(fe)))
+#define fe_to_priv(fe) (fe_to_d(fe)->priv)
+#define d_to_priv(d) (d->priv)
+
+#define DVB_USB_STREAM_BULK(endpoint_, count_, size_) { \
+       .type = USB_BULK, \
+       .count = count_, \
+       .endpoint = endpoint_, \
+       .u = { \
+               .bulk = { \
+                       .buffersize = size_, \
+               } \
+       } \
+}
+
+#define DVB_USB_STREAM_ISOC(endpoint_, count_, frames_, size_, interval_) { \
+       .type = USB_ISOC, \
+       .count = count_, \
+       .endpoint = endpoint_, \
+       .u = { \
+               .isoc = { \
+                       .framesperurb = frames_, \
+                       .framesize = size_,\
+                       .interval = interval_, \
+               } \
+       } \
+}
+
+#define DVB_USB_DEVICE(vend, prod, props_, name_, rc) \
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
+       .idVendor = (vend), \
+       .idProduct = (prod), \
+       .driver_info = (kernel_ulong_t) &((const struct dvb_usb_driver_info) { \
+               .props = (props_), \
+               .name = (name_), \
+               .rc_map = (rc), \
+       })
+
+struct dvb_usb_device;
+struct dvb_usb_adapter;
+
+/**
+ * structure for carrying all needed data from the device driver to the general
+ * dvb usb routines
+ * @name: device name
+ * @rc_map: name of rc codes table
+ * @props: structure containing all device properties
+ */
+struct dvb_usb_driver_info {
+       const char *name;
+       const char *rc_map;
+       const struct dvb_usb_device_properties *props;
+};
+
+/**
+ * structure for remote controller configuration
+ * @map_name: name of rc codes table
+ * @allowed_protos: protocol(s) supported by the driver
+ * @change_protocol: callback to change protocol
+ * @query: called to query an event from the device
+ * @interval: time in ms between two queries
+ * @driver_type: used to point if a device supports raw mode
+ * @bulk_mode: device supports bulk mode for rc (disable polling mode)
+ */
+struct dvb_usb_rc {
+       const char *map_name;
+       u64 allowed_protos;
+       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+       int (*query) (struct dvb_usb_device *d);
+       unsigned int interval;
+       const enum rc_driver_type driver_type;
+       bool bulk_mode;
+};
+
+/**
+ * usb streaming configration for adapter
+ * @type: urb type
+ * @count: count of used urbs
+ * @endpoint: stream usb endpoint number
+ */
+struct usb_data_stream_properties {
+#define USB_BULK  1
+#define USB_ISOC  2
+       u8 type;
+       u8 count;
+       u8 endpoint;
+
+       union {
+               struct {
+                       unsigned int buffersize; /* per URB */
+               } bulk;
+               struct {
+                       int framesperurb;
+                       int framesize;
+                       int interval;
+               } isoc;
+       } u;
+};
+
+/**
+ * properties of dvb usb device adapter
+ * @caps: adapter capabilities
+ * @pid_filter_count: pid count of adapter pid-filter
+ * @pid_filter_ctrl: called to enable/disable pid-filter
+ * @pid_filter: called to set/unset pid for filtering
+ * @stream: adapter usb stream configuration
+ */
+#define MAX_NO_OF_FE_PER_ADAP 3
+struct dvb_usb_adapter_properties {
+#define DVB_USB_ADAP_HAS_PID_FILTER               0x01
+#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
+#define DVB_USB_ADAP_NEED_PID_FILTERING           0x04
+       u8 caps;
+
+       u8 pid_filter_count;
+       int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
+       int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
+
+       struct usb_data_stream_properties stream;
+};
+
+/**
+ * struct dvb_usb_device_properties - properties of a dvb-usb-device
+ * @driver_name: name of the owning driver module
+ * @owner: owner of the dvb_adapter
+ * @adapter_nr: values from the DVB_DEFINE_MOD_OPT_ADAPTER_NR() macro
+ * @bInterfaceNumber: usb interface number driver binds
+ * @size_of_priv: bytes allocated for the driver private data
+ * @generic_bulk_ctrl_endpoint: bulk control endpoint number for sent
+ * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for
+ *  receive
+ * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message
+ * @identify_state: called to determine the firmware state (cold or warm) and
+ *  return possible firmware file name to be loaded
+ * @firmware: name of the firmware file to be loaded
+ * @download_firmware: called to download the firmware
+ * @i2c_algo: i2c_algorithm if the device has i2c-adapter
+ * @num_adapters: dvb usb device adapter count
+ * @get_adapter_count: called to resolve adapter count
+ * @adapter: array of all adapter properties of device
+ * @power_ctrl: called to enable/disable power of the device
+ * @read_config: called to resolve device configuration
+ * @read_mac_address: called to resolve adapter mac-address
+ * @frontend_attach: called to attach the possible frontends
+ * @tuner_attach: called to attach the possible tuners
+ * @frontend_ctrl: called to power on/off active frontend
+ * @streaming_ctrl: called to start/stop the usb streaming of adapter
+ * @fe_ioctl_override: frontend ioctl override. avoid using that is possible
+ * @init: called after adapters are created in order to finalize device
+ *  configuration
+ * @exit: called when driver is unloaded
+ * @get_rc_config: called to resolve used remote controller configuration
+ * @get_stream_config: called to resolve input and output stream configuration
+ *  of the adapter just before streaming is started. input stream is transport
+ *  stream from the demodulator and output stream is usb stream to host.
+ */
+#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
+struct dvb_usb_device_properties {
+       const char *driver_name;
+       struct module *owner;
+       short *adapter_nr;
+
+       u8 bInterfaceNumber;
+       unsigned int size_of_priv;
+       u8 generic_bulk_ctrl_endpoint;
+       u8 generic_bulk_ctrl_endpoint_response;
+       unsigned int generic_bulk_ctrl_delay;
+
+#define WARM                  0
+#define COLD                  1
+       int (*identify_state) (struct dvb_usb_device *, const char **);
+       const char *firmware;
+#define RECONNECTS_USB        1
+       int (*download_firmware) (struct dvb_usb_device *,
+                       const struct firmware *);
+
+       struct i2c_algorithm *i2c_algo;
+
+       unsigned int num_adapters;
+       int (*get_adapter_count) (struct dvb_usb_device *);
+       struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
+       int (*power_ctrl) (struct dvb_usb_device *, int);
+       int (*read_config) (struct dvb_usb_device *d);
+       int (*read_mac_address) (struct dvb_usb_adapter *, u8 []);
+       int (*frontend_attach) (struct dvb_usb_adapter *);
+       int (*tuner_attach) (struct dvb_usb_adapter *);
+       int (*frontend_ctrl) (struct dvb_frontend *, int);
+       int (*streaming_ctrl) (struct dvb_frontend *, int);
+       int (*fe_ioctl_override) (struct dvb_frontend *,
+                       unsigned int, void *, unsigned int);
+       int (*init) (struct dvb_usb_device *);
+       void (*exit) (struct dvb_usb_device *);
+       int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *);
+#define DVB_USB_FE_TS_TYPE_188        0
+#define DVB_USB_FE_TS_TYPE_204        1
+#define DVB_USB_FE_TS_TYPE_RAW        2
+       int (*get_stream_config) (struct dvb_frontend *,  u8 *,
+                       struct usb_data_stream_properties *);
+};
+
+/**
+ * generic object of an usb stream
+ * @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
+ */
+#define MAX_NO_URBS_FOR_DATA_STREAM 10
+struct usb_data_stream {
+       struct usb_device *udev;
+       struct usb_data_stream_properties props;
+
+#define USB_STATE_INIT    0x00
+#define USB_STATE_URB_BUF 0x01
+       u8 state;
+
+       void (*complete) (struct usb_data_stream *, u8 *, size_t);
+
+       struct urb    *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
+       int            buf_num;
+       unsigned long  buf_size;
+       u8            *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
+       dma_addr_t     dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
+
+       int urbs_initialized;
+       int urbs_submitted;
+
+       void *user_priv;
+};
+
+/**
+ * dvb adapter object on dvb usb device
+ * @props: pointer to adapter properties
+ * @stream: adapter the usb data stream
+ * @id: index of this adapter (starting with 0)
+ * @ts_type: transport stream, input stream, type
+ * @pid_filtering: is hardware pid_filtering used or not
+ * @feed_count: current feed count
+ * @max_feed_count: maimum feed count device can handle
+ * @dvb_adap: adapter dvb_adapter
+ * @dmxdev: adapter dmxdev
+ * @demux: adapter software demuxer
+ * @dvb_net: adapter dvb_net interfaces
+ * @sync_mutex: mutex used to sync control and streaming of the adapter
+ * @fe: adapter frontends
+ * @fe_init: rerouted frontend-init function
+ * @fe_sleep: rerouted frontend-sleep function
+ */
+struct dvb_usb_adapter {
+       const struct dvb_usb_adapter_properties *props;
+       struct usb_data_stream stream;
+       u8 id;
+       u8 ts_type;
+       bool pid_filtering;
+       u8 feed_count;
+       u8 max_feed_count;
+       s8 active_fe;
+
+       /* dvb */
+       struct dvb_adapter   dvb_adap;
+       struct dmxdev        dmxdev;
+       struct dvb_demux     demux;
+       struct dvb_net       dvb_net;
+       struct mutex         sync_mutex;
+
+       struct dvb_frontend *fe[MAX_NO_OF_FE_PER_ADAP];
+       int (*fe_init[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
+       int (*fe_sleep[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
+};
+
+/**
+ * dvb usb device object
+ * @props: device properties
+ * @name: device name
+ * @rc_map: name of rc codes table
+ * @udev: pointer to the device's struct usb_device
+ * @intf: pointer to the device's usb interface
+ * @rc: remote controller configuration
+ * @probe_work: work to defer .probe()
+ * @powered: indicated whether the device is power or not
+ * @usb_mutex: mutex for usb control messages
+ * @i2c_mutex: mutex for i2c-transfers
+ * @i2c_adap: device's i2c-adapter
+ * @rc_dev: rc device for the remote control
+ * @rc_query_work: work for polling remote
+ * @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 {
+       const struct dvb_usb_device_properties *props;
+       const char *name;
+       const char *rc_map;
+
+       struct usb_device *udev;
+       struct usb_interface *intf;
+       struct dvb_usb_rc rc;
+       struct work_struct probe_work;
+       pid_t work_pid;
+       int powered;
+
+       /* locking */
+       struct mutex usb_mutex;
+
+       /* i2c */
+       struct mutex i2c_mutex;
+       struct i2c_adapter i2c_adap;
+
+       struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
+
+       /* remote control */
+       struct rc_dev *rc_dev;
+       char rc_phys[64];
+       struct delayed_work rc_query_work;
+
+       void *priv;
+};
+
+extern int dvb_usbv2_probe(struct usb_interface *,
+               const struct usb_device_id *);
+extern void dvb_usbv2_disconnect(struct usb_interface *);
+extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t);
+extern int dvb_usbv2_resume(struct usb_interface *);
+
+/* the generic read/write method for device control */
+extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16);
+extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb_common.h b/drivers/media/dvb/dvb-usb-v2/dvb_usb_common.h
new file mode 100644 (file)
index 0000000..45f0709
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef DVB_USB_COMMON_H
+#define DVB_USB_COMMON_H
+
+#include "dvb_usb.h"
+
+/* commonly used  methods */
+extern int usb_urb_initv2(struct usb_data_stream *stream,
+               const struct usb_data_stream_properties *props);
+extern int usb_urb_exitv2(struct usb_data_stream *stream);
+extern int usb_urb_submitv2(struct usb_data_stream *stream,
+               struct usb_data_stream_properties *props);
+extern int usb_urb_killv2(struct usb_data_stream *stream);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/dvb/dvb-usb-v2/dvb_usb_core.c
new file mode 100644 (file)
index 0000000..3224621
--- /dev/null
@@ -0,0 +1,999 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dvb_usb_common.h"
+
+int dvb_usbv2_disable_rc_polling;
+module_param_named(disable_rc_polling, dvb_usbv2_disable_rc_polling, int, 0644);
+MODULE_PARM_DESC(disable_rc_polling,
+               "disable remote control polling (default: 0)");
+static int dvb_usb_force_pid_filter_usage;
+module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage,
+               int, 0444);
+MODULE_PARM_DESC(force_pid_filter_usage, "force all DVB USB devices to use a " \
+               "PID filter, if any (default: 0)");
+
+static int dvb_usbv2_download_firmware(struct dvb_usb_device *d, const char *name)
+{
+       int ret;
+       const struct firmware *fw;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (!d->props->download_firmware) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       ret = request_firmware(&fw, name, &d->udev->dev);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: Did not find the firmware file "\
+                               "'%s'. Please see linux/Documentation/dvb/ " \
+                               "for more details on firmware-problems. " \
+                               "Status %d\n", KBUILD_MODNAME, name, ret);
+               goto err;
+       }
+
+       dev_info(&d->udev->dev, "%s: downloading firmware from file '%s'\n",
+                       KBUILD_MODNAME, name);
+
+       ret = d->props->download_firmware(d, fw);
+       release_firmware(fw);
+       if (ret < 0)
+               goto err;
+
+       return ret;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usbv2_i2c_init(struct dvb_usb_device *d)
+{
+       int ret;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (!d->props->i2c_algo)
+               return 0;
+
+       strlcpy(d->i2c_adap.name, d->name, sizeof(d->i2c_adap.name));
+       d->i2c_adap.algo = d->props->i2c_algo;
+       d->i2c_adap.dev.parent = &d->udev->dev;
+       i2c_set_adapdata(&d->i2c_adap, d);
+
+       ret = i2c_add_adapter(&d->i2c_adap);
+       if (ret < 0) {
+               d->i2c_adap.algo = NULL;
+               dev_err(&d->udev->dev, "%s: i2c_add_adapter() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               goto err;
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usbv2_i2c_exit(struct dvb_usb_device *d)
+{
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (d->i2c_adap.algo)
+               i2c_del_adapter(&d->i2c_adap);
+
+       return 0;
+}
+
+static void dvb_usb_read_remote_control(struct work_struct *work)
+{
+       struct dvb_usb_device *d = container_of(work,
+                       struct dvb_usb_device, rc_query_work.work);
+       int ret;
+
+       /*
+        * When the parameter has been set to 1 via sysfs while the
+        * driver was running, or when bulk mode is enabled after IR init.
+        */
+       if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
+               return;
+
+       ret = d->rc.query(d);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: rc.query() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               return; /* stop polling */
+       }
+
+       schedule_delayed_work(&d->rc_query_work,
+                       msecs_to_jiffies(d->rc.interval));
+}
+
+static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
+{
+       int ret;
+       struct rc_dev *dev;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
+               return 0;
+
+       d->rc.map_name = d->rc_map;
+       ret = d->props->get_rc_config(d, &d->rc);
+       if (ret < 0)
+               goto err;
+
+       /* disable rc when there is no keymap defined */
+       if (!d->rc.map_name)
+               return 0;
+
+       dev = rc_allocate_device();
+       if (!dev) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       dev->dev.parent = &d->udev->dev;
+       dev->input_name = d->name;
+       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+       dev->input_phys = d->rc_phys;
+       usb_to_input_id(d->udev, &dev->input_id);
+       /* TODO: likely RC-core should took const char * */
+       dev->driver_name = (char *) d->props->driver_name;
+       dev->map_name = d->rc.map_name;
+       dev->driver_type = d->rc.driver_type;
+       dev->allowed_protos = d->rc.allowed_protos;
+       dev->change_protocol = d->rc.change_protocol;
+       dev->priv = d;
+
+       ret = rc_register_device(dev);
+       if (ret < 0) {
+               rc_free_device(dev);
+               goto err;
+       }
+
+       d->rc_dev = dev;
+
+       /* start polling if needed */
+       if (d->rc.query && !d->rc.bulk_mode) {
+               /* initialize a work queue for handling polling */
+               INIT_DELAYED_WORK(&d->rc_query_work,
+                               dvb_usb_read_remote_control);
+               dev_info(&d->udev->dev, "%s: schedule remote query interval " \
+                               "to %d msecs\n", KBUILD_MODNAME,
+                               d->rc.interval);
+               schedule_delayed_work(&d->rc_query_work,
+                               msecs_to_jiffies(d->rc.interval));
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
+{
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       if (d->rc_dev) {
+               cancel_delayed_work_sync(&d->rc_query_work);
+               rc_unregister_device(d->rc_dev);
+               d->rc_dev = NULL;
+       }
+
+       return 0;
+}
+
+static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
+               size_t len)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       dvb_dmx_swfilter(&adap->demux, buf, len);
+}
+
+static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
+               size_t len)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       dvb_dmx_swfilter_204(&adap->demux, buf, len);
+}
+
+static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
+               size_t len)
+{
+       struct dvb_usb_adapter *adap = stream->user_priv;
+       dvb_dmx_swfilter_raw(&adap->demux, buf, len);
+}
+
+int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
+{
+       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+                       adap->id);
+
+       adap->stream.udev = adap_to_d(adap)->udev;
+       adap->stream.user_priv = adap;
+       adap->stream.complete = dvb_usb_data_complete;
+
+       return usb_urb_initv2(&adap->stream, &adap->props->stream);
+}
+
+int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
+{
+       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+                       adap->id);
+
+       return usb_urb_exitv2(&adap->stream);
+}
+
+static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
+               int count)
+{
+       struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret;
+       dev_dbg(&d->udev->dev, "%s: adap=%d active_fe=%d feed_type=%d " \
+                       "setting pid [%s]: %04x (%04d) at index %d '%s'\n",
+                       __func__, adap->id, adap->active_fe, dvbdmxfeed->type,
+                       adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
+                       dvbdmxfeed->pid, dvbdmxfeed->index,
+                       (count == 1) ? "on" : "off");
+
+       if (adap->active_fe == -1)
+               return -EINVAL;
+
+       adap->feed_count += count;
+
+       /* stop feeding if it is last pid */
+       if (adap->feed_count == 0) {
+               dev_dbg(&d->udev->dev, "%s: stop feeding\n", __func__);
+               usb_urb_killv2(&adap->stream);
+
+               if (d->props->streaming_ctrl) {
+                       ret = d->props->streaming_ctrl(
+                                       adap->fe[adap->active_fe], 0);
+                       if (ret < 0) {
+                               dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
+                                               "failed=%d\n", KBUILD_MODNAME,
+                                               ret);
+                               goto err_mutex_unlock;
+                       }
+               }
+               mutex_unlock(&adap->sync_mutex);
+       }
+
+       /* activate the pid on the device pid filter */
+       if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+                       adap->pid_filtering &&
+                       adap->props->pid_filter)
+               ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
+                               dvbdmxfeed->pid, (count == 1) ? 1 : 0);
+                       if (ret < 0)
+                               dev_err(&d->udev->dev, "%s: pid_filter() " \
+                                               "failed=%d\n", KBUILD_MODNAME,
+                                               ret);
+
+       /* start feeding if it is first pid */
+       if (adap->feed_count == 1 && count == 1) {
+               struct usb_data_stream_properties stream_props;
+               mutex_lock(&adap->sync_mutex);
+               dev_dbg(&d->udev->dev, "%s: start feeding\n", __func__);
+
+               /* resolve input and output streaming paramters */
+               if (d->props->get_stream_config) {
+                       memcpy(&stream_props, &adap->props->stream,
+                               sizeof(struct usb_data_stream_properties));
+                       ret = d->props->get_stream_config(
+                                       adap->fe[adap->active_fe],
+                                       &adap->ts_type, &stream_props);
+                       if (ret < 0)
+                               goto err_mutex_unlock;
+               } else {
+                       stream_props = adap->props->stream;
+               }
+
+               switch (adap->ts_type) {
+               case DVB_USB_FE_TS_TYPE_204:
+                       adap->stream.complete = dvb_usb_data_complete_204;
+                       break;
+               case DVB_USB_FE_TS_TYPE_RAW:
+                       adap->stream.complete = dvb_usb_data_complete_raw;
+                       break;
+               case DVB_USB_FE_TS_TYPE_188:
+               default:
+                       adap->stream.complete = dvb_usb_data_complete;
+                       break;
+               }
+
+               usb_urb_submitv2(&adap->stream, &stream_props);
+
+               if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+                               adap->props->caps &
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
+                               adap->props->pid_filter_ctrl) {
+                       ret = adap->props->pid_filter_ctrl(adap,
+                                       adap->pid_filtering);
+                       if (ret < 0) {
+                               dev_err(&d->udev->dev, "%s: " \
+                                               "pid_filter_ctrl() failed=%d\n",
+                                               KBUILD_MODNAME, ret);
+                               goto err_mutex_unlock;
+                       }
+               }
+
+               if (d->props->streaming_ctrl) {
+                       ret = d->props->streaming_ctrl(
+                                       adap->fe[adap->active_fe], 1);
+                       if (ret < 0) {
+                               dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
+                                               "failed=%d\n", KBUILD_MODNAME,
+                                               ret);
+                               goto err_mutex_unlock;
+                       }
+               }
+       }
+
+       return 0;
+err_mutex_unlock:
+       mutex_unlock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
+}
+
+static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
+}
+
+int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
+
+       ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
+                       &d->udev->dev, d->props->adapter_nr);
+       if (ret < 0) {
+               dev_dbg(&d->udev->dev, "%s: dvb_register_adapter() failed=%d\n",
+                               __func__, ret);
+               goto err_dvb_register_adapter;
+       }
+
+       adap->dvb_adap.priv = adap;
+
+       if (d->props->read_mac_address) {
+               ret = d->props->read_mac_address(adap,
+                               adap->dvb_adap.proposed_mac);
+               if (ret < 0)
+                       goto err_dvb_dmx_init;
+
+               dev_info(&d->udev->dev, "%s: MAC address: %pM\n",
+                               KBUILD_MODNAME, adap->dvb_adap.proposed_mac);
+       }
+
+       adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+       adap->demux.priv             = adap;
+       adap->demux.filternum        = 0;
+       adap->demux.filternum        = adap->max_feed_count;
+       adap->demux.feednum          = adap->demux.filternum;
+       adap->demux.start_feed       = dvb_usb_start_feed;
+       adap->demux.stop_feed        = dvb_usb_stop_feed;
+       adap->demux.write_to_decoder = NULL;
+       ret = dvb_dmx_init(&adap->demux);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: dvb_dmx_init() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               goto err_dvb_dmx_init;
+       }
+
+       adap->dmxdev.filternum       = adap->demux.filternum;
+       adap->dmxdev.demux           = &adap->demux.dmx;
+       adap->dmxdev.capabilities    = 0;
+       ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: dvb_dmxdev_init() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               goto err_dvb_dmxdev_init;
+       }
+
+       ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: dvb_net_init() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+               goto err_dvb_net_init;
+       }
+
+       mutex_init(&adap->sync_mutex);
+
+       return 0;
+err_dvb_net_init:
+       dvb_dmxdev_release(&adap->dmxdev);
+err_dvb_dmxdev_init:
+       dvb_dmx_release(&adap->demux);
+err_dvb_dmx_init:
+       dvb_unregister_adapter(&adap->dvb_adap);
+err_dvb_register_adapter:
+       adap->dvb_adap.priv = NULL;
+       return ret;
+}
+
+int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
+{
+       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+                       adap->id);
+
+       if (adap->dvb_adap.priv) {
+               dvb_net_release(&adap->dvb_net);
+               adap->demux.dmx.close(&adap->demux.dmx);
+               dvb_dmxdev_release(&adap->dmxdev);
+               dvb_dmx_release(&adap->demux);
+               dvb_unregister_adapter(&adap->dvb_adap);
+       }
+
+       return 0;
+}
+
+int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       int ret;
+
+       if (onoff)
+               d->powered++;
+       else
+               d->powered--;
+
+       if (d->powered == 0 || (onoff && d->powered == 1)) {
+               /* when switching from 1 to 0 or from 0 to 1 */
+               dev_dbg(&d->udev->dev, "%s: power=%d\n", __func__, onoff);
+               if (d->props->power_ctrl) {
+                       ret = d->props->power_ctrl(d, onoff);
+                       if (ret < 0)
+                               goto err;
+               }
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usb_fe_init(struct dvb_frontend *fe)
+{
+       int ret;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       mutex_lock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
+                       fe->id);
+
+       ret = dvb_usbv2_device_power_ctrl(d, 1);
+       if (ret < 0)
+               goto err;
+
+       if (d->props->frontend_ctrl) {
+               ret = d->props->frontend_ctrl(fe, 1);
+               if (ret < 0)
+                       goto err;
+       }
+
+       if (adap->fe_init[fe->id]) {
+               ret = adap->fe_init[fe->id](fe);
+               if (ret < 0)
+                       goto err;
+       }
+
+       adap->active_fe = fe->id;
+       mutex_unlock(&adap->sync_mutex);
+
+       return 0;
+err:
+       mutex_unlock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       mutex_lock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
+                       fe->id);
+
+       if (adap->fe_sleep[fe->id]) {
+               ret = adap->fe_sleep[fe->id](fe);
+               if (ret < 0)
+                       goto err;
+       }
+
+       if (d->props->frontend_ctrl) {
+               ret = d->props->frontend_ctrl(fe, 0);
+               if (ret < 0)
+                       goto err;
+       }
+
+       ret = dvb_usbv2_device_power_ctrl(d, 0);
+       if (ret < 0)
+               goto err;
+
+       adap->active_fe = -1;
+       mutex_unlock(&adap->sync_mutex);
+
+       return 0;
+err:
+       mutex_unlock(&adap->sync_mutex);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
+{
+       int ret, i, count_registered = 0;
+       struct dvb_usb_device *d = adap_to_d(adap);
+       dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
+
+       memset(adap->fe, 0, sizeof(adap->fe));
+       adap->active_fe = -1;
+
+       if (d->props->frontend_attach) {
+               ret = d->props->frontend_attach(adap);
+               if (ret < 0) {
+                       dev_dbg(&d->udev->dev, "%s: frontend_attach() " \
+                                       "failed=%d\n", __func__, ret);
+                       goto err_dvb_frontend_detach;
+               }
+       } else {
+               dev_dbg(&d->udev->dev, "%s: frontend_attach() do not exists\n",
+                               __func__);
+               ret = 0;
+               goto err;
+       }
+
+       for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
+               adap->fe[i]->id = i;
+               /* re-assign sleep and wakeup functions */
+               adap->fe_init[i] = adap->fe[i]->ops.init;
+               adap->fe[i]->ops.init = dvb_usb_fe_init;
+               adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
+               adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
+
+               ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
+               if (ret < 0) {
+                       dev_err(&d->udev->dev, "%s: frontend%d registration " \
+                                       "failed\n", KBUILD_MODNAME, i);
+                       goto err_dvb_unregister_frontend;
+               }
+
+               count_registered++;
+       }
+
+       if (d->props->tuner_attach) {
+               ret = d->props->tuner_attach(adap);
+               if (ret < 0) {
+                       dev_dbg(&d->udev->dev, "%s: tuner_attach() failed=%d\n",
+                                       __func__, ret);
+                       goto err_dvb_unregister_frontend;
+               }
+       }
+
+       return 0;
+
+err_dvb_unregister_frontend:
+       for (i = count_registered - 1; i >= 0; i--)
+               dvb_unregister_frontend(adap->fe[i]);
+
+err_dvb_frontend_detach:
+       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
+               if (adap->fe[i])
+                       dvb_frontend_detach(adap->fe[i]);
+       }
+
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
+{
+       int i;
+       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+                       adap->id);
+
+       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
+               if (adap->fe[i]) {
+                       dvb_unregister_frontend(adap->fe[i]);
+                       dvb_frontend_detach(adap->fe[i]);
+               }
+       }
+
+       return 0;
+}
+
+static int dvb_usbv2_adapter_init(struct dvb_usb_device *d)
+{
+       struct dvb_usb_adapter *adap;
+       int ret, i, adapter_count;
+
+       /* resolve adapter count */
+       adapter_count = d->props->num_adapters;
+       if (d->props->get_adapter_count) {
+               ret = d->props->get_adapter_count(d);
+               if (ret < 0)
+                       goto err;
+
+               adapter_count = ret;
+       }
+
+       for (i = 0; i < adapter_count; i++) {
+               adap = &d->adapter[i];
+               adap->id = i;
+               adap->props = &d->props->adapter[i];
+
+               /* speed - when running at FULL speed we need a HW PID filter */
+               if (d->udev->speed == USB_SPEED_FULL &&
+                               !(adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
+                       dev_err(&d->udev->dev, "%s: this USB2.0 device " \
+                                       "cannot be run on a USB1.1 port (it " \
+                                       "lacks a hardware PID filter)\n",
+                                       KBUILD_MODNAME);
+                       ret = -ENODEV;
+                       goto err;
+               } else if ((d->udev->speed == USB_SPEED_FULL &&
+                               adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
+                               (adap->props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
+                       dev_info(&d->udev->dev, "%s: will use the device's " \
+                                       "hardware PID filter " \
+                                       "(table count: %d)\n", KBUILD_MODNAME,
+                                       adap->props->pid_filter_count);
+                       adap->pid_filtering  = 1;
+                       adap->max_feed_count = adap->props->pid_filter_count;
+               } else {
+                       dev_info(&d->udev->dev, "%s: will pass the complete " \
+                                       "MPEG2 transport stream to the " \
+                                       "software demuxer\n", KBUILD_MODNAME);
+                       adap->pid_filtering  = 0;
+                       adap->max_feed_count = 255;
+               }
+
+               if (!adap->pid_filtering && dvb_usb_force_pid_filter_usage &&
+                               adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
+                       dev_info(&d->udev->dev, "%s: PID filter enabled by " \
+                                       "module option\n", KBUILD_MODNAME);
+                       adap->pid_filtering  = 1;
+                       adap->max_feed_count = adap->props->pid_filter_count;
+               }
+
+               ret = dvb_usbv2_adapter_stream_init(adap);
+               if (ret)
+                       goto err;
+
+               ret = dvb_usbv2_adapter_dvb_init(adap);
+               if (ret)
+                       goto err;
+
+               ret = dvb_usbv2_adapter_frontend_init(adap);
+               if (ret)
+                       goto err;
+
+               /* use exclusive FE lock if there is multiple shared FEs */
+               if (adap->fe[1])
+                       adap->dvb_adap.mfe_shared = 1;
+
+               adap->dvb_adap.fe_ioctl_override = d->props->fe_ioctl_override;
+       }
+
+       return 0;
+err:
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int dvb_usbv2_adapter_exit(struct dvb_usb_device *d)
+{
+       int i;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
+               if (d->adapter[i].props) {
+                       dvb_usbv2_adapter_frontend_exit(&d->adapter[i]);
+                       dvb_usbv2_adapter_dvb_exit(&d->adapter[i]);
+                       dvb_usbv2_adapter_stream_exit(&d->adapter[i]);
+               }
+       }
+
+       return 0;
+}
+
+/* general initialization functions */
+static int dvb_usbv2_exit(struct dvb_usb_device *d)
+{
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       dvb_usbv2_remote_exit(d);
+       dvb_usbv2_adapter_exit(d);
+       dvb_usbv2_i2c_exit(d);
+       kfree(d->priv);
+       kfree(d);
+
+       return 0;
+}
+
+static int dvb_usbv2_init(struct dvb_usb_device *d)
+{
+       int ret;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       dvb_usbv2_device_power_ctrl(d, 1);
+
+       if (d->props->read_config) {
+               ret = d->props->read_config(d);
+               if (ret < 0)
+                       goto err;
+       }
+
+       ret = dvb_usbv2_i2c_init(d);
+       if (ret < 0)
+               goto err;
+
+       ret = dvb_usbv2_adapter_init(d);
+       if (ret < 0)
+               goto err;
+
+       if (d->props->init) {
+               ret = d->props->init(d);
+               if (ret < 0)
+                       goto err;
+       }
+
+       ret = dvb_usbv2_remote_init(d);
+       if (ret < 0)
+               goto err;
+
+       dvb_usbv2_device_power_ctrl(d, 0);
+
+       return 0;
+err:
+       dvb_usbv2_device_power_ctrl(d, 0);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+/*
+ * udev, which is used for the firmware downloading, requires we cannot
+ * block during module_init(). module_init() calls USB probe() which
+ * is this routine. Due to that we delay actual operation using workqueue
+ * and return always success here.
+ */
+static void dvb_usbv2_init_work(struct work_struct *work)
+{
+       int ret;
+       struct dvb_usb_device *d =
+                       container_of(work, struct dvb_usb_device, probe_work);
+
+       d->work_pid = current->pid;
+       dev_dbg(&d->udev->dev, "%s: work_pid=%d\n", __func__, d->work_pid);
+
+       if (d->props->size_of_priv) {
+               d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL);
+               if (!d->priv) {
+                       dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
+                                       KBUILD_MODNAME);
+                       ret = -ENOMEM;
+                       goto err_usb_driver_release_interface;
+               }
+       }
+
+       if (d->props->identify_state) {
+               const char *name = NULL;
+               ret = d->props->identify_state(d, &name);
+               if (ret == 0) {
+                       ;
+               } else if (ret == COLD) {
+                       dev_info(&d->udev->dev, "%s: found a '%s' in cold " \
+                                       "state\n", KBUILD_MODNAME, d->name);
+
+                       if (!name)
+                               name = d->props->firmware;
+
+                       ret = dvb_usbv2_download_firmware(d, name);
+                       if (ret == 0) {
+                               /* device is warm, continue initialization */
+                               ;
+                       } else if (ret == RECONNECTS_USB) {
+                               /*
+                                * USB core will call disconnect() and then
+                                * probe() as device reconnects itself from the
+                                * USB bus. disconnect() will release all driver
+                                * resources and probe() is called for 'new'
+                                * device. As 'new' device is warm we should
+                                * never go here again.
+                                */
+                               return;
+                       } else {
+                               /*
+                                * Unexpected error. We must unregister driver
+                                * manually from the device, because device is
+                                * already register by returning from probe()
+                                * with success. usb_driver_release_interface()
+                                * finally calls disconnect() in order to free
+                                * resources.
+                                */
+                               goto err_usb_driver_release_interface;
+                       }
+               } else {
+                       goto err_usb_driver_release_interface;
+               }
+       }
+
+       dev_info(&d->udev->dev, "%s: found a '%s' in warm state\n",
+                       KBUILD_MODNAME, d->name);
+
+       ret = dvb_usbv2_init(d);
+       if (ret < 0)
+               goto err_usb_driver_release_interface;
+
+       dev_info(&d->udev->dev, "%s: '%s' successfully initialized and " \
+                       "connected\n", KBUILD_MODNAME, d->name);
+
+       return;
+err_usb_driver_release_interface:
+       dev_info(&d->udev->dev, "%s: '%s' error while loading driver (%d)\n",
+                       KBUILD_MODNAME, d->name, ret);
+       usb_driver_release_interface(to_usb_driver(d->intf->dev.driver),
+                       d->intf);
+       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       return;
+}
+
+int dvb_usbv2_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       int ret;
+       struct dvb_usb_device *d;
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct dvb_usb_driver_info *driver_info =
+                       (struct dvb_usb_driver_info *) id->driver_info;
+
+       dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
+                       intf->cur_altsetting->desc.bInterfaceNumber);
+
+       if (!id->driver_info) {
+               dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME);
+               ret = -ENODEV;
+               goto err;
+       }
+
+       d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
+       if (!d) {
+               dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       d->name = driver_info->name;
+       d->rc_map = driver_info->rc_map;
+       d->udev = udev;
+       d->intf = intf;
+       d->props = driver_info->props;
+
+       if (d->intf->cur_altsetting->desc.bInterfaceNumber !=
+                       d->props->bInterfaceNumber) {
+               ret = -ENODEV;
+               goto err_kfree;
+       }
+
+       mutex_init(&d->usb_mutex);
+       mutex_init(&d->i2c_mutex);
+       INIT_WORK(&d->probe_work, dvb_usbv2_init_work);
+       usb_set_intfdata(intf, d);
+       ret = schedule_work(&d->probe_work);
+       if (ret < 0) {
+               dev_err(&d->udev->dev, "%s: schedule_work() failed\n",
+                               KBUILD_MODNAME);
+               goto err_kfree;
+       }
+
+       return 0;
+err_kfree:
+       kfree(d);
+err:
+       dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+EXPORT_SYMBOL(dvb_usbv2_probe);
+
+void dvb_usbv2_disconnect(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       const char *name = d->name;
+       struct device dev = d->udev->dev;
+       dev_dbg(&d->udev->dev, "%s: pid=%d work_pid=%d\n", __func__,
+                       current->pid, d->work_pid);
+
+       /* ensure initialization work is finished until release resources */
+       if (d->work_pid != current->pid)
+               cancel_work_sync(&d->probe_work);
+
+       if (d->props->exit)
+               d->props->exit(d);
+
+       dvb_usbv2_exit(d);
+
+       dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
+                       KBUILD_MODNAME, name);
+}
+EXPORT_SYMBOL(dvb_usbv2_disconnect);
+
+int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       int i;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       /* stop remote controller poll */
+       if (d->rc.query && !d->rc.bulk_mode)
+               cancel_delayed_work_sync(&d->rc_query_work);
+
+       /* stop streaming */
+       for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
+               if (d->adapter[i].dvb_adap.priv &&
+                               d->adapter[i].active_fe != -1)
+                       usb_urb_killv2(&d->adapter[i].stream);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(dvb_usbv2_suspend);
+
+int dvb_usbv2_resume(struct usb_interface *intf)
+{
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+       int i;
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       /* start streaming */
+       for (i = 0; i < MAX_NO_OF_ADAPTER_PER_DEVICE; i++) {
+               if (d->adapter[i].dvb_adap.priv &&
+                               d->adapter[i].active_fe != -1)
+                       usb_urb_submitv2(&d->adapter[i].stream, NULL);
+       }
+
+       /* start remote controller poll */
+       if (d->rc.query && !d->rc.bulk_mode)
+               schedule_delayed_work(&d->rc_query_work,
+                               msecs_to_jiffies(d->rc.interval));
+
+       return 0;
+}
+EXPORT_SYMBOL(dvb_usbv2_resume);
+
+MODULE_VERSION("2.0");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("DVB USB common");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb_firmware.c b/drivers/media/dvb/dvb-usb-v2/dvb_usb_firmware.c
new file mode 100644 (file)
index 0000000..61c3fe9
--- /dev/null
@@ -0,0 +1,125 @@
+/* dvb_usb_firmware.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 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.
+ *
+ */
+
+#include "dvb_usb.h"
+#include "dvb_usb_firmware.h"
+
+struct usb_cypress_controller {
+       u8 id;
+       const char *name;       /* name of the usb controller */
+       u16 cs_reg;             /* needs to be restarted,
+                                * when the firmware has been downloaded */
+};
+
+static const struct usb_cypress_controller cypress[] = {
+       { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cs_reg = 0x7f92 },
+       { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cs_reg = 0x7f92 },
+       { .id = CYPRESS_FX2,    .name = "Cypress FX2",    .cs_reg = 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, 5000);
+}
+
+int usbv2_cypress_load_firmware(struct usb_device *udev,
+               const struct firmware *fw, int type)
+{
+       struct hexline hx;
+       u8 reset;
+       int ret, pos = 0;
+
+       /* stop the CPU */
+       reset = 1;
+       ret = usb_cypress_writemem(udev, cypress[type].cs_reg, &reset, 1);
+       if (ret != 1)
+               pr_err("%s: could not stop the USB controller CPU",
+                               KBUILD_MODNAME);
+
+       while ((ret = dvb_usbv2_get_hexline(fw, &hx, &pos)) > 0) {
+               pr_debug("%s: writing to address %04x (buffer: %02x %02x)\n",
+                               __func__, hx.addr, hx.len, hx.chk);
+
+               ret = usb_cypress_writemem(udev, hx.addr, hx.data, hx.len);
+               if (ret != hx.len) {
+                       pr_err("%s: error while transferring firmware " \
+                                       "(transferred size=%d, block size=%d)",
+                                       KBUILD_MODNAME, ret, hx.len);
+                       ret = -EINVAL;
+                       break;
+               }
+       }
+       if (ret < 0) {
+               pr_err("%s: firmware download failed at %d with %d",
+                               KBUILD_MODNAME, pos, ret);
+               return ret;
+       }
+
+       if (ret == 0) {
+               /* restart the CPU */
+               reset = 0;
+               if (ret || usb_cypress_writemem(
+                               udev, cypress[type].cs_reg, &reset, 1) != 1) {
+                       pr_err("%s: could not restart the USB controller CPU",
+                                       KBUILD_MODNAME);
+                       ret = -EINVAL;
+               }
+       } else
+               ret = -EIO;
+
+       return ret;
+}
+EXPORT_SYMBOL(usbv2_cypress_load_firmware);
+
+int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
+               int *pos)
+{
+       u8 *b = (u8 *) &fw->data[*pos];
+       int data_offs = 4;
+
+       if (*pos >= fw->size)
+               return 0;
+
+       memset(hx, 0, sizeof(struct hexline));
+
+       hx->len = b[0];
+
+       if ((*pos + hx->len + 4) >= fw->size)
+               return -EINVAL;
+
+       hx->addr = b[1] | (b[2] << 8);
+       hx->type = b[3];
+
+       if (hx->type == 0x04) {
+               /* b[4] and b[5] are the Extended linear address record data
+                * field */
+               hx->addr |= (b[4] << 24) | (b[5] << 16);
+               /*
+               hx->len -= 2;
+               data_offs += 2;
+               */
+       }
+       memcpy(hx->data, &b[data_offs], hx->len);
+       hx->chk = b[hx->len + data_offs];
+
+       *pos += hx->len + 5;
+
+       return *pos;
+}
+EXPORT_SYMBOL(dvb_usbv2_get_hexline);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Cypress firmware download");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb_firmware.h b/drivers/media/dvb/dvb-usb-v2/dvb_usb_firmware.h
new file mode 100644 (file)
index 0000000..358d9d0
--- /dev/null
@@ -0,0 +1,31 @@
+/* dvb_usb_firmware.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 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.
+ *
+ */
+
+#ifndef DVB_USB_FIRMWARE_H
+#define DVB_USB_FIRMWARE_H
+
+#define CYPRESS_AN2135  0
+#define CYPRESS_AN2235  1
+#define CYPRESS_FX2     2
+
+/* commonly used firmware download types and function */
+struct hexline {
+       u8 len;
+       u32 addr;
+       u8 type;
+       u8 data[255];
+       u8 chk;
+};
+extern int usbv2_cypress_load_firmware(struct usb_device *,
+               const struct firmware *, int);
+extern int dvb_usbv2_get_hexline(const struct firmware *,
+               struct hexline *, int *);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/dvb_usb_urb.c b/drivers/media/dvb/dvb-usb-v2/dvb_usb_urb.c
new file mode 100644 (file)
index 0000000..5f5bdd0
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dvb_usb_common.h"
+
+#undef DVB_USB_XFER_DEBUG
+int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
+               u16 rlen)
+{
+       int ret, actual_length;
+
+       if (!d || !wbuf || !wlen || !d->props->generic_bulk_ctrl_endpoint ||
+                       !d->props->generic_bulk_ctrl_endpoint_response) {
+               dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, -EINVAL);
+               return -EINVAL;
+       }
+
+       ret = mutex_lock_interruptible(&d->usb_mutex);
+       if (ret < 0)
+               return ret;
+
+#ifdef DVB_USB_XFER_DEBUG
+       print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": >>> ", DUMP_PREFIX_NONE,
+                       32, 1, wbuf, wlen, 0);
+#endif
+       ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
+                       d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
+                       &actual_length, 2000);
+       if (ret < 0)
+               dev_err(&d->udev->dev, "%s: usb_bulk_msg() failed=%d\n",
+                               KBUILD_MODNAME, ret);
+       else
+               ret = actual_length != wlen ? -EIO : 0;
+
+       /* an answer is expected, and no error before */
+       if (!ret && rbuf && rlen) {
+               if (d->props->generic_bulk_ctrl_delay)
+                       usleep_range(d->props->generic_bulk_ctrl_delay,
+                                       d->props->generic_bulk_ctrl_delay
+                                       + 20000);
+
+               ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
+                               d->props->generic_bulk_ctrl_endpoint_response),
+                               rbuf, rlen, &actual_length, 2000);
+               if (ret)
+                       dev_err(&d->udev->dev, "%s: 2nd usb_bulk_msg() " \
+                                       "failed=%d\n", KBUILD_MODNAME, ret);
+
+#ifdef DVB_USB_XFER_DEBUG
+               print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": <<< ",
+                               DUMP_PREFIX_NONE, 32, 1, rbuf, actual_length,
+                               0);
+#endif
+       }
+
+       mutex_unlock(&d->usb_mutex);
+       return ret;
+}
+EXPORT_SYMBOL(dvb_usbv2_generic_rw);
+
+int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
+{
+       return dvb_usbv2_generic_rw(d, buf, len, NULL, 0);
+}
+EXPORT_SYMBOL(dvb_usbv2_generic_write);
diff --git a/drivers/media/dvb/dvb-usb-v2/ec168.c b/drivers/media/dvb/dvb-usb-v2/ec168.c
new file mode 100644 (file)
index 0000000..ab77622
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * E3C EC168 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "ec168.h"
+#include "ec100.h"
+#include "mxl5005s.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
+{
+       int ret;
+       unsigned int pipe;
+       u8 request, requesttype;
+       u8 *buf;
+
+       switch (req->cmd) {
+       case DOWNLOAD_FIRMWARE:
+       case GPIO:
+       case WRITE_I2C:
+       case STREAMING_CTRL:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+               request = req->cmd;
+               break;
+       case READ_I2C:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+               request = req->cmd;
+               break;
+       case GET_CONFIG:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+               request = CONFIG;
+               break;
+       case SET_CONFIG:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+               request = CONFIG;
+               break;
+       case WRITE_DEMOD:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+               request = DEMOD_RW;
+               break;
+       case READ_DEMOD:
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+               request = DEMOD_RW;
+               break;
+       default:
+               pr_err("%s: unknown command=%02x\n", KBUILD_MODNAME, req->cmd);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       buf = kmalloc(req->size, GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
+               /* write */
+               memcpy(buf, req->data, req->size);
+               pipe = usb_sndctrlpipe(d->udev, 0);
+       } else {
+               /* read */
+               pipe = usb_rcvctrlpipe(d->udev, 0);
+       }
+
+       msleep(1); /* avoid I2C errors */
+
+       ret = usb_control_msg(d->udev, pipe, request, requesttype, req->value,
+               req->index, buf, req->size, EC168_USB_TIMEOUT);
+
+       ec168_debug_dump(request, requesttype, req->value, req->index, buf,
+               req->size);
+
+       if (ret < 0)
+               goto err_dealloc;
+       else
+               ret = 0;
+
+       /* read request, copy returned data to return buf */
+       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+               memcpy(req->data, buf, req->size);
+
+       kfree(buf);
+       return ret;
+
+err_dealloc:
+       kfree(buf);
+error:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+/* I2C */
+static struct ec100_config ec168_ec100_config;
+
+static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+       int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct ec168_req req;
+       int i = 0;
+       int ret;
+
+       if (num > 2)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       while (i < num) {
+               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+                       if (msg[i].addr == ec168_ec100_config.demod_address) {
+                               req.cmd = READ_DEMOD;
+                               req.value = 0;
+                               req.index = 0xff00 + msg[i].buf[0]; /* reg */
+                               req.size = msg[i+1].len; /* bytes to read */
+                               req.data = &msg[i+1].buf[0];
+                               ret = ec168_ctrl_msg(d, &req);
+                               i += 2;
+                       } else {
+                               pr_err("%s: I2C read not implemented\n",
+                                               KBUILD_MODNAME);
+                               ret = -EOPNOTSUPP;
+                               i += 2;
+                       }
+               } else {
+                       if (msg[i].addr == ec168_ec100_config.demod_address) {
+                               req.cmd = WRITE_DEMOD;
+                               req.value = msg[i].buf[1]; /* val */
+                               req.index = 0xff00 + msg[i].buf[0]; /* reg */
+                               req.size = 0;
+                               req.data = NULL;
+                               ret = ec168_ctrl_msg(d, &req);
+                               i += 1;
+                       } else {
+                               req.cmd = WRITE_I2C;
+                               req.value = msg[i].buf[0]; /* val */
+                               req.index = 0x0100 + msg[i].addr; /* I2C addr */
+                               req.size = msg[i].len-1;
+                               req.data = &msg[i].buf[1];
+                               ret = ec168_ctrl_msg(d, &req);
+                               i += 1;
+                       }
+               }
+               if (ret)
+                       goto error;
+
+       }
+       ret = i;
+
+error:
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 ec168_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ec168_i2c_algo = {
+       .master_xfer   = ec168_i2c_xfer,
+       .functionality = ec168_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static int ec168_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       int ret;
+       u8 reply;
+       struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
+       pr_debug("%s:\n", __func__);
+
+       ret = ec168_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       pr_debug("%s: reply=%02x\n", __func__, reply);
+
+       if (reply == 0x01)
+               ret = WARM;
+       else
+               ret = COLD;
+
+       return ret;
+error:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int ec168_download_firmware(struct dvb_usb_device *d,
+               const struct firmware *fw)
+{
+       int ret, len, remaining;
+       struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
+       pr_debug("%s:\n", __func__);
+
+       #define LEN_MAX 2048 /* max packet size */
+       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
+               len = remaining;
+               if (len > LEN_MAX)
+                       len = LEN_MAX;
+
+               req.size = len;
+               req.data = (u8 *) &fw->data[fw->size - remaining];
+               req.index = fw->size - remaining;
+
+               ret = ec168_ctrl_msg(d, &req);
+               if (ret) {
+                       pr_err("%s: firmware download failed=%d\n",
+                                       KBUILD_MODNAME, ret);
+                       goto error;
+               }
+       }
+
+       req.size = 0;
+
+       /* set "warm"? */
+       req.cmd = SET_CONFIG;
+       req.value = 0;
+       req.index = 0x0001;
+       ret = ec168_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       /* really needed - no idea what does */
+       req.cmd = GPIO;
+       req.value = 0;
+       req.index = 0x0206;
+       ret = ec168_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       /* activate tuner I2C? */
+       req.cmd = WRITE_I2C;
+       req.value = 0;
+       req.index = 0x00c6;
+       ret = ec168_ctrl_msg(d, &req);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static struct ec100_config ec168_ec100_config = {
+       .demod_address = 0xff, /* not real address, demod is integrated */
+};
+
+static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       pr_debug("%s:\n", __func__);
+       adap->fe[0] = dvb_attach(ec100_attach, &ec168_ec100_config,
+                       &adap_to_d(adap)->i2c_adap);
+       if (adap->fe[0] == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static struct mxl5005s_config ec168_mxl5003s_config = {
+       .i2c_address     = 0xc6,
+       .if_freq         = IF_FREQ_4570000HZ,
+       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+       .agc_mode        = MXL_SINGLE_AGC,
+       .tracking_filter = MXL_TF_OFF,
+       .rssi_enable     = MXL_RSSI_ENABLE,
+       .cap_select      = MXL_CAP_SEL_ENABLE,
+       .div_out         = MXL_DIV_OUT_4,
+       .clock_out       = MXL_CLOCK_OUT_DISABLE,
+       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+       .top             = MXL5005S_TOP_25P2,
+       .mod_mode        = MXL_DIGITAL_MODE,
+       .if_mode         = MXL_ZERO_IF,
+       .AgcMasterByte   = 0x00,
+};
+
+static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       pr_debug("%s:\n", __func__);
+       return dvb_attach(mxl5005s_attach, adap->fe[0],
+                       &adap_to_d(adap)->i2c_adap,
+                       &ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
+}
+
+static int ec168_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
+       pr_debug("%s: onoff=%d\n", __func__, onoff);
+       if (onoff)
+               req.index = 0x0102;
+       return ec168_ctrl_msg(fe_to_d(fe), &req);
+}
+
+/* DVB USB Driver stuff */
+/* bInterfaceNumber 0 is HID
+ * bInterfaceNumber 1 is DVB-T */
+static struct dvb_usb_device_properties ec168_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .bInterfaceNumber = 1,
+
+       .identify_state = ec168_identify_state,
+       .firmware = "dvb-usb-ec168.fw",
+       .download_firmware = ec168_download_firmware,
+
+       .i2c_algo = &ec168_i2c_algo,
+       .frontend_attach = ec168_ec100_frontend_attach,
+       .tuner_attach = ec168_mxl5003s_tuner_attach,
+       .streaming_ctrl = ec168_streaming_ctrl,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x82, 6, 32 * 512),
+               }
+       },
+};
+
+static const struct dvb_usb_driver_info ec168_driver_info = {
+       .name = "E3C EC168 reference design",
+       .props = &ec168_props,
+};
+
+static const struct usb_device_id ec168_id[] = {
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5),
+               .driver_info = (kernel_ulong_t) &ec168_driver_info },
+       {}
+};
+MODULE_DEVICE_TABLE(usb, ec168_id);
+
+static struct usb_driver ec168_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = ec168_id,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(ec168_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("E3C EC168 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/ec168.h b/drivers/media/dvb/dvb-usb-v2/ec168.h
new file mode 100644 (file)
index 0000000..9181236
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * E3C EC168 DVB USB driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef EC168_H
+#define EC168_H
+
+#include "dvb_usb.h"
+
+#define ec168_debug_dump(r, t, v, i, b, l) { \
+       char *direction; \
+       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+               direction = ">>>"; \
+       else \
+               direction = "<<<"; \
+       pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s\n", \
+                        __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
+                       l & 0xff, l >> 8, direction); \
+}
+
+#define EC168_USB_TIMEOUT 1000
+
+struct ec168_req {
+       u8  cmd;       /* [1] */
+       u16 value;     /* [2|3] */
+       u16 index;     /* [4|5] */
+       u16 size;      /* [6|7] */
+       u8  *data;
+};
+
+enum ec168_cmd {
+       DOWNLOAD_FIRMWARE    = 0x00,
+       CONFIG               = 0x01,
+       DEMOD_RW             = 0x03,
+       GPIO                 = 0x04,
+       STREAMING_CTRL       = 0x10,
+       READ_I2C             = 0x20,
+       WRITE_I2C            = 0x21,
+       HID_DOWNLOAD         = 0x30,
+       GET_CONFIG,
+       SET_CONFIG,
+       READ_DEMOD,
+       WRITE_DEMOD,
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/gl861.c b/drivers/media/dvb/dvb-usb-v2/gl861.c
new file mode 100644 (file)
index 0000000..cf29f43
--- /dev/null
@@ -0,0 +1,175 @@
+/* DVB USB compliant linux driver for GL861 USB2.0 devices.
+ *
+ *     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 "gl861.h"
+
+#include "zl10353.h"
+#include "qt1010.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
+                        u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+       u16 index;
+       u16 value = addr << (8 + 1);
+       int wo = (rbuf == NULL || rlen == 0); /* write-only */
+       u8 req, type;
+
+       if (wo) {
+               req = GL861_REQ_I2C_WRITE;
+               type = GL861_WRITE;
+       } else { /* rw */
+               req = GL861_REQ_I2C_READ;
+               type = GL861_READ;
+       }
+
+       switch (wlen) {
+       case 1:
+               index = wbuf[0];
+               break;
+       case 2:
+               index = wbuf[0];
+               value = value + wbuf[1];
+               break;
+       default:
+               pr_err("%s: wlen=%d, aborting\n", KBUILD_MODNAME, wlen);
+               return -EINVAL;
+       }
+
+       msleep(1); /* avoid I2C errors */
+
+       return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
+                              value, index, rbuf, rlen, 2000);
+}
+
+/* I2C */
+static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                         int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       int i;
+
+       if (num > 2)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               /* write/read request */
+               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+                       if (gl861_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 (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
+                                         msg[i].len, NULL, 0) < 0)
+                               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 gl861_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm gl861_i2c_algo = {
+       .master_xfer   = gl861_i2c_xfer,
+       .functionality = gl861_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config gl861_zl10353_config = {
+       .demod_address = 0x0f,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+};
+
+static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
+{
+
+       adap->fe[0] = dvb_attach(zl10353_attach, &gl861_zl10353_config,
+               &adap_to_d(adap)->i2c_adap);
+       if (adap->fe[0] == NULL)
+               return -EIO;
+
+       return 0;
+}
+
+static struct qt1010_config gl861_qt1010_config = {
+       .i2c_address = 0x62
+};
+
+static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       return dvb_attach(qt1010_attach,
+                         adap->fe[0], &adap_to_d(adap)->i2c_adap,
+                         &gl861_qt1010_config) == NULL ? -ENODEV : 0;
+}
+
+static int gl861_init(struct dvb_usb_device *d)
+{
+       /*
+        * There is 2 interfaces. Interface 0 is for TV and interface 1 is
+        * for HID remote controller. Interface 0 has 2 alternate settings.
+        * For some reason we need to set interface explicitly, defaulted
+        * as alternate setting 1?
+        */
+       return usb_set_interface(d->udev, 0, 0);
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties gl861_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+
+       .i2c_algo = &gl861_i2c_algo,
+       .frontend_attach = gl861_frontend_attach,
+       .tuner_attach = gl861_tuner_attach,
+       .init = gl861_init,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x81, 7, 512),
+               }
+       }
+};
+
+static const struct usb_device_id gl861_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801,
+               &gl861_props, "MSI Mega Sky 55801 DVB-T USB2.0", NULL) },
+       { DVB_USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU,
+               &gl861_props, "A-LINK DTU DVB-T USB2.0", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, gl861_id_table);
+
+static struct usb_driver gl861_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = gl861_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(gl861_usb_driver);
+
+MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
+MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb-v2/gl861.h b/drivers/media/dvb/dvb-usb-v2/gl861.h
new file mode 100644 (file)
index 0000000..b0b80d8
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _DVB_USB_GL861_H_
+#define _DVB_USB_GL861_H_
+
+#include "dvb_usb.h"
+
+#define GL861_WRITE            0x40
+#define GL861_READ             0xc0
+
+#define GL861_REQ_I2C_WRITE    0x01
+#define GL861_REQ_I2C_READ     0x02
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.c
new file mode 100644 (file)
index 0000000..d83df4b
--- /dev/null
@@ -0,0 +1,612 @@
+/*
+ *  mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "mxl111sf-demod.h"
+#include "mxl111sf-reg.h"
+
+/* debug */
+static int mxl111sf_demod_debug;
+module_param_named(debug, mxl111sf_demod_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+#define mxl_dbg(fmt, arg...) \
+       if (mxl111sf_demod_debug) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+/* ------------------------------------------------------------------------ */
+
+struct mxl111sf_demod_state {
+       struct mxl111sf_state *mxl_state;
+
+       struct mxl111sf_demod_config *cfg;
+
+       struct dvb_frontend fe;
+};
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_demod_read_reg(struct mxl111sf_demod_state *state,
+                                  u8 addr, u8 *data)
+{
+       return (state->cfg->read_reg) ?
+               state->cfg->read_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static int mxl111sf_demod_write_reg(struct mxl111sf_demod_state *state,
+                                   u8 addr, u8 data)
+{
+       return (state->cfg->write_reg) ?
+               state->cfg->write_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static
+int mxl111sf_demod_program_regs(struct mxl111sf_demod_state *state,
+                               struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
+{
+       return (state->cfg->program_regs) ?
+               state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
+               -EINVAL;
+}
+
+/* ------------------------------------------------------------------------ */
+/* TPS */
+
+static
+int mxl1x1sf_demod_get_tps_code_rate(struct mxl111sf_demod_state *state,
+                                    fe_code_rate_t *code_rate)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_CODE_RATE_TPS_REG, &val);
+       /* bit<2:0> - 000:1/2, 001:2/3, 010:3/4, 011:5/6, 100:7/8 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch (val & V6_CODE_RATE_TPS_MASK) {
+       case 0:
+               *code_rate = FEC_1_2;
+               break;
+       case 1:
+               *code_rate = FEC_2_3;
+               break;
+       case 2:
+               *code_rate = FEC_3_4;
+               break;
+       case 3:
+               *code_rate = FEC_5_6;
+               break;
+       case 4:
+               *code_rate = FEC_7_8;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_modulation(struct mxl111sf_demod_state *state,
+                                        fe_modulation_t *modulation)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val);
+       /* Constellation, 00 : QPSK, 01 : 16QAM, 10:64QAM */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) {
+       case 0:
+               *modulation = QPSK;
+               break;
+       case 1:
+               *modulation = QAM_16;
+               break;
+       case 2:
+               *modulation = QAM_64;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_guard_fft_mode(struct mxl111sf_demod_state *state,
+                                         fe_transmit_mode_t *fft_mode)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_MODE_TPS_REG, &val);
+       /* FFT Mode, 00:2K, 01:8K, 10:4K */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_PARAM_FFT_MODE_MASK) >> 2) {
+       case 0:
+               *fft_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               *fft_mode = TRANSMISSION_MODE_8K;
+               break;
+       case 2:
+               *fft_mode = TRANSMISSION_MODE_4K;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_guard_interval(struct mxl111sf_demod_state *state,
+                                         fe_guard_interval_t *guard)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_CP_TPS_REG, &val);
+       /* 00:1/32, 01:1/16, 10:1/8, 11:1/4 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_PARAM_GI_MASK) >> 4) {
+       case 0:
+               *guard = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               *guard = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               *guard = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               *guard = GUARD_INTERVAL_1_4;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_hierarchy(struct mxl111sf_demod_state *state,
+                                    fe_hierarchy_t *hierarchy)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_TPS_HIERACHY_REG, &val);
+       /* bit<6:4> - 000:Non hierarchy, 001:1, 010:2, 011:4 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_TPS_HIERARCHY_INFO_MASK) >> 6) {
+       case 0:
+               *hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               *hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               *hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               *hierarchy = HIERARCHY_4;
+               break;
+       }
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+/* LOCKS */
+
+static
+int mxl1x1sf_demod_get_sync_lock_status(struct mxl111sf_demod_state *state,
+                                       int *sync_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_SYNC_LOCK_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *sync_lock = (val & SYNC_LOCK_MASK) >> 4;
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_rs_lock_status(struct mxl111sf_demod_state *state,
+                                     int *rs_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_RS_LOCK_DET_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *rs_lock = (val & RS_LOCK_DET_MASK) >> 3;
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_lock_status(struct mxl111sf_demod_state *state,
+                                      int *tps_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_TPS_LOCK_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *tps_lock = (val & V6_PARAM_TPS_LOCK_MASK) >> 6;
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_fec_lock_status(struct mxl111sf_demod_state *state,
+                                      int *fec_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_IRQ_STATUS_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *fec_lock = (val & IRQ_MASK_FEC_LOCK) >> 4;
+fail:
+       return ret;
+}
+
+#if 0
+static
+int mxl1x1sf_demod_get_cp_lock_status(struct mxl111sf_demod_state *state,
+                                     int *cp_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_CP_LOCK_DET_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *cp_lock = (val & V6_CP_LOCK_DET_MASK) >> 2;
+fail:
+       return ret;
+}
+#endif
+
+static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state)
+{
+       return mxl111sf_demod_write_reg(state, 0x0e, 0xff);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       int ret = 0;
+
+       struct mxl111sf_reg_ctrl_info phy_pll_patch[] = {
+               {0x00, 0xff, 0x01}, /* change page to 1 */
+               {0x40, 0xff, 0x05},
+               {0x40, 0xff, 0x01},
+               {0x41, 0xff, 0xca},
+               {0x41, 0xff, 0xc0},
+               {0x00, 0xff, 0x00}, /* change page to 0 */
+               {0,    0,    0}
+       };
+
+       mxl_dbg("()");
+
+       if (fe->ops.tuner_ops.set_params) {
+               ret = fe->ops.tuner_ops.set_params(fe);
+               if (mxl_fail(ret))
+                       goto fail;
+               msleep(50);
+       }
+       ret = mxl111sf_demod_program_regs(state, phy_pll_patch);
+       mxl_fail(ret);
+       msleep(50);
+       ret = mxl1x1sf_demod_reset_irq_status(state);
+       mxl_fail(ret);
+       msleep(100);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#if 0
+/* resets TS Packet error count */
+/* After setting 7th bit of V5_PER_COUNT_RESET_REG, it should be reset to 0. */
+static
+int mxl1x1sf_demod_reset_packet_error_count(struct mxl111sf_demod_state *state)
+{
+       struct mxl111sf_reg_ctrl_info reset_per_count[] = {
+               {0x20, 0x01, 0x01},
+               {0x20, 0x01, 0x00},
+               {0,    0,    0}
+       };
+       return mxl111sf_demod_program_regs(state, reset_per_count);
+}
+#endif
+
+/* returns TS Packet error count */
+/* PER Count = FEC_PER_COUNT * (2 ** (FEC_PER_SCALE * 4)) */
+static int mxl111sf_demod_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       u32 fec_per_count, fec_per_scale;
+       u8 val;
+       int ret;
+
+       *ucblocks = 0;
+
+       /* FEC_PER_COUNT Register */
+       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_COUNT_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       fec_per_count = val;
+
+       /* FEC_PER_SCALE Register */
+       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_SCALE_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       val &= V6_FEC_PER_SCALE_MASK;
+       val *= 4;
+
+       fec_per_scale = 1 << val;
+
+       fec_per_count *= fec_per_scale;
+
+       *ucblocks = fec_per_count;
+fail:
+       return ret;
+}
+
+#ifdef MXL111SF_DEMOD_ENABLE_CALCULATIONS
+/* FIXME: leaving this enabled breaks the build on some architectures,
+ * and we shouldn't have any floating point math in the kernel, anyway.
+ *
+ * These macros need to be re-written, but it's harmless to simply
+ * return zero for now. */
+#define CALCULATE_BER(avg_errors, count) \
+       ((u32)(avg_errors * 4)/(count*64*188*8))
+#define CALCULATE_SNR(data) \
+       ((u32)((10 * (u32)data / 64) - 2.5))
+#else
+#define CALCULATE_BER(avg_errors, count) 0
+#define CALCULATE_SNR(data) 0
+#endif
+
+static int mxl111sf_demod_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       u8 val1, val2, val3;
+       int ret;
+
+       *ber = 0;
+
+       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_LSB_REG, &val1);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_MSB_REG, &val2);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_demod_read_reg(state, V6_N_ACCUMULATE_REG, &val3);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *ber = CALCULATE_BER((val1 | (val2 << 8)), val3);
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_calc_snr(struct mxl111sf_demod_state *state,
+                                  u16 *snr)
+{
+       u8 val1, val2;
+       int ret;
+
+       *snr = 0;
+
+       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_LSB_REG, &val1);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_MSB_REG, &val2);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *snr = CALCULATE_SNR(val1 | ((val2 & 0x03) << 8));
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+
+       int ret = mxl111sf_demod_calc_snr(state, snr);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *snr /= 10; /* 0.1 dB */
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_read_status(struct dvb_frontend *fe,
+                                     fe_status_t *status)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       int ret, locked, cr_lock, sync_lock, fec_lock;
+
+       *status = 0;
+
+       ret = mxl1x1sf_demod_get_rs_lock_status(state, &locked);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_demod_get_tps_lock_status(state, &cr_lock);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_demod_get_sync_lock_status(state, &sync_lock);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_demod_get_fec_lock_status(state, &fec_lock);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if (locked)
+               *status |= FE_HAS_SIGNAL;
+       if (cr_lock)
+               *status |= FE_HAS_CARRIER;
+       if (sync_lock)
+               *status |= FE_HAS_SYNC;
+       if (fec_lock) /* false positives? */
+               *status |= FE_HAS_VITERBI;
+
+       if ((locked) && (cr_lock) && (sync_lock))
+               *status |= FE_HAS_LOCK;
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
+                                              u16 *signal_strength)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       fe_modulation_t modulation;
+       u16 snr;
+
+       mxl111sf_demod_calc_snr(state, &snr);
+       mxl1x1sf_demod_get_tps_modulation(state, &modulation);
+
+       switch (modulation) {
+       case QPSK:
+               *signal_strength = (snr >= 1300) ?
+                       min(65535, snr * 44) : snr * 38;
+               break;
+       case QAM_16:
+               *signal_strength = (snr >= 1500) ?
+                       min(65535, snr * 38) : snr * 33;
+               break;
+       case QAM_64:
+               *signal_strength = (snr >= 2000) ?
+                       min(65535, snr * 29) : snr * 25;
+               break;
+       default:
+               *signal_strength = 0;
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+
+       mxl_dbg("()");
+#if 0
+       p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF;
+#endif
+       if (fe->ops.tuner_ops.get_bandwidth)
+               fe->ops.tuner_ops.get_bandwidth(fe, &p->bandwidth_hz);
+       if (fe->ops.tuner_ops.get_frequency)
+               fe->ops.tuner_ops.get_frequency(fe, &p->frequency);
+       mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_HP);
+       mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_LP);
+       mxl1x1sf_demod_get_tps_modulation(state, &p->modulation);
+       mxl1x1sf_demod_get_tps_guard_fft_mode(state,
+                                             &p->transmission_mode);
+       mxl1x1sf_demod_get_tps_guard_interval(state,
+                                             &p->guard_interval);
+       mxl1x1sf_demod_get_tps_hierarchy(state,
+                                        &p->hierarchy);
+
+       return 0;
+}
+
+static
+int mxl111sf_demod_get_tune_settings(struct dvb_frontend *fe,
+                                    struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void mxl111sf_demod_release(struct dvb_frontend *fe)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       mxl_dbg("()");
+       kfree(state);
+       fe->demodulator_priv = NULL;
+}
+
+static struct dvb_frontend_ops mxl111sf_demod_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name               = "MaxLinear MxL111SF DVB-T demodulator",
+               .frequency_min      = 177000000,
+               .frequency_max      = 858000000,
+               .frequency_stepsize = 166666,
+               .caps = 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_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
+       },
+       .release              = mxl111sf_demod_release,
+#if 0
+       .init                 = mxl111sf_init,
+       .i2c_gate_ctrl        = mxl111sf_i2c_gate_ctrl,
+#endif
+       .set_frontend         = mxl111sf_demod_set_frontend,
+       .get_frontend         = mxl111sf_demod_get_frontend,
+       .get_tune_settings    = mxl111sf_demod_get_tune_settings,
+       .read_status          = mxl111sf_demod_read_status,
+       .read_signal_strength = mxl111sf_demod_read_signal_strength,
+       .read_ber             = mxl111sf_demod_read_ber,
+       .read_snr             = mxl111sf_demod_read_snr,
+       .read_ucblocks        = mxl111sf_demod_read_ucblocks,
+};
+
+struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_demod_config *cfg)
+{
+       struct mxl111sf_demod_state *state = NULL;
+
+       mxl_dbg("()");
+
+       state = kzalloc(sizeof(struct mxl111sf_demod_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       state->mxl_state = mxl_state;
+       state->cfg = cfg;
+
+       memcpy(&state->fe.ops, &mxl111sf_demod_ops,
+              sizeof(struct dvb_frontend_ops));
+
+       state->fe.demodulator_priv = state;
+       return &state->fe;
+}
+EXPORT_SYMBOL_GPL(mxl111sf_demod_attach);
+
+MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-demod.h
new file mode 100644 (file)
index 0000000..432706a
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MXL111SF_DEMOD_H__
+#define __MXL111SF_DEMOD_H__
+
+#include "dvb_frontend.h"
+#include "mxl111sf.h"
+
+struct mxl111sf_demod_config {
+       int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
+       int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
+       int (*program_regs)(struct mxl111sf_state *state,
+                           struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
+};
+
+#if defined(CONFIG_DVB_USB_MXL111SF) || \
+       (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
+extern
+struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_demod_config *cfg);
+#else
+static inline
+struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_demod_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_USB_MXL111SF */
+
+#endif /* __MXL111SF_DEMOD_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.c
new file mode 100644 (file)
index 0000000..e4121cb
--- /dev/null
@@ -0,0 +1,763 @@
+/*
+ *  mxl111sf-gpio.c - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "mxl111sf-gpio.h"
+#include "mxl111sf-i2c.h"
+#include "mxl111sf.h"
+
+/* ------------------------------------------------------------------------- */
+
+#define MXL_GPIO_MUX_REG_0 0x84
+#define MXL_GPIO_MUX_REG_1 0x89
+#define MXL_GPIO_MUX_REG_2 0x82
+
+#define MXL_GPIO_DIR_INPUT  0
+#define MXL_GPIO_DIR_OUTPUT 1
+
+
+static int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val)
+{
+       int ret;
+       u8 tmp;
+
+       mxl_debug_adv("(%d, %d)", pin, val);
+
+       if ((pin > 0) && (pin < 8)) {
+               ret = mxl111sf_read_reg(state, 0x19, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << (pin - 1));
+               tmp |= (val << (pin - 1));
+               ret = mxl111sf_write_reg(state, 0x19, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+       } else if (pin <= 10) {
+               if (pin == 0)
+                       pin += 7;
+               ret = mxl111sf_read_reg(state, 0x30, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << (pin - 3));
+               tmp |= (val << (pin - 3));
+               ret = mxl111sf_write_reg(state, 0x30, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+       } else
+               ret = -EINVAL;
+fail:
+       return ret;
+}
+
+static int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val)
+{
+       int ret;
+       u8 tmp;
+
+       mxl_debug("(0x%02x)", pin);
+
+       *val = 0;
+
+       switch (pin) {
+       case 0:
+       case 1:
+       case 2:
+       case 3:
+               ret = mxl111sf_read_reg(state, 0x23, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               *val = (tmp >> (pin + 4)) & 0x01;
+               break;
+       case 4:
+       case 5:
+       case 6:
+       case 7:
+               ret = mxl111sf_read_reg(state, 0x2f, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               *val = (tmp >> pin) & 0x01;
+               break;
+       case 8:
+       case 9:
+       case 10:
+               ret = mxl111sf_read_reg(state, 0x22, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               *val = (tmp >> (pin - 3)) & 0x01;
+               break;
+       default:
+               return -EINVAL; /* invalid pin */
+       }
+fail:
+       return ret;
+}
+
+struct mxl_gpio_cfg {
+       u8 pin;
+       u8 dir;
+       u8 val;
+};
+
+static int mxl111sf_config_gpio_pins(struct mxl111sf_state *state,
+                                    struct mxl_gpio_cfg *gpio_cfg)
+{
+       int ret;
+       u8 tmp;
+
+       mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir);
+
+       switch (gpio_cfg->pin) {
+       case 0:
+       case 1:
+       case 2:
+       case 3:
+               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << (gpio_cfg->pin + 4));
+               tmp |= (gpio_cfg->dir << (gpio_cfg->pin + 4));
+               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_0, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               break;
+       case 4:
+       case 5:
+       case 6:
+       case 7:
+               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << gpio_cfg->pin);
+               tmp |= (gpio_cfg->dir << gpio_cfg->pin);
+               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_1, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               break;
+       case 8:
+       case 9:
+       case 10:
+               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               tmp &= ~(1 << (gpio_cfg->pin - 3));
+               tmp |= (gpio_cfg->dir << (gpio_cfg->pin - 3));
+               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_2, tmp);
+               if (mxl_fail(ret))
+                       goto fail;
+               break;
+       default:
+               return -EINVAL; /* invalid pin */
+       }
+
+       ret = (MXL_GPIO_DIR_OUTPUT == gpio_cfg->dir) ?
+               mxl111sf_set_gpo_state(state,
+                                      gpio_cfg->pin, gpio_cfg->val) :
+               mxl111sf_get_gpi_state(state,
+                                      gpio_cfg->pin, &gpio_cfg->val);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+static int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state,
+                                  int gpio, int direction, int val)
+{
+       struct mxl_gpio_cfg gpio_config = {
+               .pin = gpio,
+               .dir = direction,
+               .val = val,
+       };
+
+       mxl_debug("(%d, %d, %d)", gpio, direction, val);
+
+       return mxl111sf_config_gpio_pins(state, &gpio_config);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#define PIN_MUX_MPEG_MODE_MASK          0x40   /* 0x17 <6> */
+#define PIN_MUX_MPEG_PAR_EN_MASK        0x01   /* 0x18 <0> */
+#define PIN_MUX_MPEG_SER_EN_MASK        0x02   /* 0x18 <1> */
+#define PIN_MUX_MPG_IN_MUX_MASK         0x80   /* 0x3D <7> */
+#define PIN_MUX_BT656_ENABLE_MASK       0x04   /* 0x12 <2> */
+#define PIN_MUX_I2S_ENABLE_MASK         0x40   /* 0x15 <6> */
+#define PIN_MUX_SPI_MODE_MASK           0x10   /* 0x3D <4> */
+#define PIN_MUX_MCLK_EN_CTRL_MASK       0x10   /* 0x82 <4> */
+#define PIN_MUX_MPSYN_EN_CTRL_MASK      0x20   /* 0x82 <5> */
+#define PIN_MUX_MDVAL_EN_CTRL_MASK      0x40   /* 0x82 <6> */
+#define PIN_MUX_MPERR_EN_CTRL_MASK      0x80   /* 0x82 <7> */
+#define PIN_MUX_MDAT_EN_0_MASK          0x10   /* 0x84 <4> */
+#define PIN_MUX_MDAT_EN_1_MASK          0x20   /* 0x84 <5> */
+#define PIN_MUX_MDAT_EN_2_MASK          0x40   /* 0x84 <6> */
+#define PIN_MUX_MDAT_EN_3_MASK          0x80   /* 0x84 <7> */
+#define PIN_MUX_MDAT_EN_4_MASK          0x10   /* 0x89 <4> */
+#define PIN_MUX_MDAT_EN_5_MASK          0x20   /* 0x89 <5> */
+#define PIN_MUX_MDAT_EN_6_MASK          0x40   /* 0x89 <6> */
+#define PIN_MUX_MDAT_EN_7_MASK          0x80   /* 0x89 <7> */
+
+int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
+                                 enum mxl111sf_mux_config pin_mux_config)
+{
+       u8 r12, r15, r17, r18, r3D, r82, r84, r89;
+       int ret;
+
+       mxl_debug("(%d)", pin_mux_config);
+
+       ret = mxl111sf_read_reg(state, 0x17, &r17);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x18, &r18);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x12, &r12);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x15, &r15);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x82, &r82);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x84, &r84);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x89, &r89);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_read_reg(state, 0x3D, &r3D);
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch (pin_mux_config) {
+       case PIN_MUX_TS_OUT_PARALLEL:
+               /* mpeg_mode = 1 */
+               r17 |= PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 1 */
+               r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 1 */
+               r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 1 */
+               r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 1 */
+               r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 1 */
+               r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0xF */
+               r84 |= 0xF0;
+               /* mdat_en_ctrl[7:4] = 0xF */
+               r89 |= 0xF0;
+               break;
+       case PIN_MUX_TS_OUT_SERIAL:
+               /* mpeg_mode = 1 */
+               r17 |= PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 1 */
+               r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 1 */
+               r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 1 */
+               r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 1 */
+               r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0xF */
+               r84 |= 0xF0;
+               /* mdat_en_ctrl[7:4] = 0xF */
+               r89 |= 0xF0;
+               break;
+       case PIN_MUX_GPIO_MODE:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_SERIAL_IN_MODE_0:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_SERIAL_IN_MODE_1:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 1 */
+               r3D |= PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_SPI_IN_MODE_1:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 1 */
+               r3D |= PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 1 */
+               r15 |= PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 1 */
+               r3D |= PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_SPI_IN_MODE_0:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 1 */
+               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 1 */
+               r15 |= PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 1 */
+               r3D |= PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_TS_PARALLEL_IN:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 1 */
+               r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_BT656_I2S_MODE:
+               /* mpeg_mode = 0 */
+               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 1 */
+               r12 |= PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 1 */
+               r15 |= PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       case PIN_MUX_DEFAULT:
+       default:
+               /* mpeg_mode = 1 */
+               r17 |= PIN_MUX_MPEG_MODE_MASK;
+               /* mpeg_par_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
+               /* mpeg_ser_en = 0 */
+               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
+               /* mpg_in_mux = 0 */
+               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
+               /* bt656_enable = 0 */
+               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
+               /* i2s_enable = 0 */
+               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
+               /* spi_mode = 0 */
+               r3D &= ~PIN_MUX_SPI_MODE_MASK;
+               /* mclk_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
+               /* mperr_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
+               /* mdval_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
+               /* mpsyn_en_ctrl = 0 */
+               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
+               /* mdat_en_ctrl[3:0] = 0x0 */
+               r84 &= 0x0F;
+               /* mdat_en_ctrl[7:4] = 0x0 */
+               r89 &= 0x0F;
+               break;
+       }
+
+       ret = mxl111sf_write_reg(state, 0x17, r17);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x18, r18);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x12, r12);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x15, r15);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x82, r82);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x84, r84);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x89, r89);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x3D, r3D);
+       if (mxl_fail(ret))
+               goto fail;
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val)
+{
+       return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val);
+}
+
+static int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state)
+{
+       u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */
+       int i, ret;
+
+       mxl_debug("()");
+
+       for (i = 3; i < 8; i++) {
+               ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01);
+               if (mxl_fail(ret))
+                       break;
+       }
+
+       return ret;
+}
+
+#define PCA9534_I2C_ADDR (0x40 >> 1)
+static int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val)
+{
+       u8 w[2] = { 1, 0 };
+       u8 r = 0;
+       struct i2c_msg msg[] = {
+               { .addr = PCA9534_I2C_ADDR,
+                 .flags = 0, .buf = w, .len = 1 },
+               { .addr = PCA9534_I2C_ADDR,
+                 .flags = I2C_M_RD, .buf = &r, .len = 1 },
+       };
+
+       mxl_debug("(%d, %d)", gpio, val);
+
+       /* read current GPIO levels from flip-flop */
+       i2c_transfer(&state->d->i2c_adap, msg, 2);
+
+       /* prepare write buffer with current GPIO levels */
+       msg[0].len = 2;
+#if 0
+       w[0] = 1;
+#endif
+       w[1] = r;
+
+       /* clear the desired GPIO */
+       w[1] &= ~(1 << gpio);
+
+       /* set the desired GPIO value */
+       w[1] |= ((val ? 1 : 0) << gpio);
+
+       /* write new GPIO levels to flip-flop */
+       i2c_transfer(&state->d->i2c_adap, &msg[0], 1);
+
+       return 0;
+}
+
+static int pca9534_init_port_expander(struct mxl111sf_state *state)
+{
+       u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */
+
+       struct i2c_msg msg = {
+               .addr = PCA9534_I2C_ADDR,
+               .flags = 0, .buf = w, .len = 2
+       };
+
+       mxl_debug("()");
+
+       i2c_transfer(&state->d->i2c_adap, &msg, 1);
+
+       /* configure all pins as outputs */
+       w[0] = 3;
+       w[1] = 0;
+
+       i2c_transfer(&state->d->i2c_adap, &msg, 1);
+
+       return 0;
+}
+
+int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val)
+{
+       mxl_debug("(%d, %d)", gpio, val);
+
+       switch (state->gpio_port_expander) {
+       default:
+               mxl_printk(KERN_ERR,
+                          "gpio_port_expander undefined, assuming PCA9534");
+               /* fall-thru */
+       case mxl111sf_PCA9534:
+               return pca9534_set_gpio(state, gpio, val);
+       case mxl111sf_gpio_hw:
+               return mxl111sf_hw_set_gpio(state, gpio, val);
+       }
+}
+
+static int mxl111sf_probe_port_expander(struct mxl111sf_state *state)
+{
+       int ret;
+       u8 w = 1;
+       u8 r = 0;
+       struct i2c_msg msg[] = {
+               { .flags = 0,        .buf = &w, .len = 1 },
+               { .flags = I2C_M_RD, .buf = &r, .len = 1 },
+       };
+
+       mxl_debug("()");
+
+       msg[0].addr = 0x70 >> 1;
+       msg[1].addr = 0x70 >> 1;
+
+       /* read current GPIO levels from flip-flop */
+       ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
+       if (ret == 2) {
+               state->port_expander_addr = msg[0].addr;
+               state->gpio_port_expander = mxl111sf_PCA9534;
+               mxl_debug("found port expander at 0x%02x",
+                         state->port_expander_addr);
+               return 0;
+       }
+
+       msg[0].addr = 0x40 >> 1;
+       msg[1].addr = 0x40 >> 1;
+
+       ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
+       if (ret == 2) {
+               state->port_expander_addr = msg[0].addr;
+               state->gpio_port_expander = mxl111sf_PCA9534;
+               mxl_debug("found port expander at 0x%02x",
+                         state->port_expander_addr);
+               return 0;
+       }
+       state->port_expander_addr = 0xff;
+       state->gpio_port_expander = mxl111sf_gpio_hw;
+       mxl_debug("using hardware gpio");
+       return 0;
+}
+
+int mxl111sf_init_port_expander(struct mxl111sf_state *state)
+{
+       mxl_debug("()");
+
+       if (0x00 == state->port_expander_addr)
+               mxl111sf_probe_port_expander(state);
+
+       switch (state->gpio_port_expander) {
+       default:
+               mxl_printk(KERN_ERR,
+                          "gpio_port_expander undefined, assuming PCA9534");
+               /* fall-thru */
+       case mxl111sf_PCA9534:
+               return pca9534_init_port_expander(state);
+       case mxl111sf_gpio_hw:
+               return mxl111sf_hw_gpio_initialize(state);
+       }
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode)
+{
+/*     GPO:
+ *     3 - ATSC/MH#   | 1 = ATSC transport, 0 = MH transport      | default 0
+ *     4 - ATSC_RST## | 1 = ATSC enable, 0 = ATSC Reset           | default 0
+ *     5 - ATSC_EN    | 1 = ATSC power enable, 0 = ATSC power off | default 0
+ *     6 - MH_RESET#  | 1 = MH enable, 0 = MH Reset               | default 0
+ *     7 - MH_EN      | 1 = MH power enable, 0 = MH power off     | default 0
+ */
+       mxl_debug("(%d)", mode);
+
+       switch (mode) {
+       case MXL111SF_GPIO_MOD_MH:
+               mxl111sf_set_gpio(state, 4, 0);
+               mxl111sf_set_gpio(state, 5, 0);
+               msleep(50);
+               mxl111sf_set_gpio(state, 7, 1);
+               msleep(50);
+               mxl111sf_set_gpio(state, 6, 1);
+               msleep(50);
+
+               mxl111sf_set_gpio(state, 3, 0);
+               break;
+       case MXL111SF_GPIO_MOD_ATSC:
+               mxl111sf_set_gpio(state, 6, 0);
+               mxl111sf_set_gpio(state, 7, 0);
+               msleep(50);
+               mxl111sf_set_gpio(state, 5, 1);
+               msleep(50);
+               mxl111sf_set_gpio(state, 4, 1);
+               msleep(50);
+               mxl111sf_set_gpio(state, 3, 1);
+               break;
+       default: /* DVBT / STANDBY */
+               mxl111sf_init_port_expander(state);
+               break;
+       }
+       return 0;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-gpio.h
new file mode 100644 (file)
index 0000000..0220f54
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  mxl111sf-gpio.h - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _DVB_USB_MXL111SF_GPIO_H_
+#define _DVB_USB_MXL111SF_GPIO_H_
+
+#include "mxl111sf.h"
+
+int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val);
+int mxl111sf_init_port_expander(struct mxl111sf_state *state);
+
+#define MXL111SF_GPIO_MOD_DVBT 0
+#define MXL111SF_GPIO_MOD_MH   1
+#define MXL111SF_GPIO_MOD_ATSC 2
+int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode);
+
+enum mxl111sf_mux_config {
+       PIN_MUX_DEFAULT = 0,
+       PIN_MUX_TS_OUT_PARALLEL,
+       PIN_MUX_TS_OUT_SERIAL,
+       PIN_MUX_GPIO_MODE,
+       PIN_MUX_TS_SERIAL_IN_MODE_0,
+       PIN_MUX_TS_SERIAL_IN_MODE_1,
+       PIN_MUX_TS_SPI_IN_MODE_0,
+       PIN_MUX_TS_SPI_IN_MODE_1,
+       PIN_MUX_TS_PARALLEL_IN,
+       PIN_MUX_BT656_I2S_MODE,
+};
+
+int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
+                                 enum mxl111sf_mux_config pin_mux_config);
+
+#endif /* _DVB_USB_MXL111SF_GPIO_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.c
new file mode 100644 (file)
index 0000000..3443455
--- /dev/null
@@ -0,0 +1,850 @@
+/*
+ *  mxl111sf-i2c.c - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "mxl111sf-i2c.h"
+#include "mxl111sf.h"
+
+/* SW-I2C ----------------------------------------------------------------- */
+
+#define SW_I2C_ADDR            0x1a
+#define SW_I2C_EN              0x02
+#define SW_SCL_OUT             0x04
+#define SW_SDA_OUT             0x08
+#define SW_SDA_IN              0x04
+
+#define SW_I2C_BUSY_ADDR       0x2f
+#define SW_I2C_BUSY            0x02
+
+static int mxl111sf_i2c_bitbang_sendbyte(struct mxl111sf_state *state,
+                                        u8 byte)
+{
+       int i, ret;
+       u8 data = 0;
+
+       mxl_i2c("(0x%02x)", byte);
+
+       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
+       if (mxl_fail(ret))
+               goto fail;
+
+       for (i = 0; i < 8; i++) {
+
+               data = (byte & (0x80 >> i)) ? SW_SDA_OUT : 0;
+
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | data);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | data | SW_SCL_OUT);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | data);
+               if (mxl_fail(ret))
+                       goto fail;
+       }
+
+       /* last bit was 0 so we need to release SDA */
+       if (!(byte & 1)) {
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | SW_SDA_OUT);
+               if (mxl_fail(ret))
+                       goto fail;
+       }
+
+       /* CLK high for ACK readback */
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* drop the CLK after getting ACK, SDA will go high right away */
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if (data & SW_SDA_IN)
+               ret = -EIO;
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_bitbang_recvbyte(struct mxl111sf_state *state,
+                                        u8 *pbyte)
+{
+       int i, ret;
+       u8 byte = 0;
+       u8 data = 0;
+
+       mxl_i2c("()");
+
+       *pbyte = 0;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       for (i = 0; i < 8; i++) {
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN |
+                                        SW_SCL_OUT | SW_SDA_OUT);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               if (data & SW_SDA_IN)
+                       byte |= (0x80 >> i);
+
+               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                        0x10 | SW_I2C_EN | SW_SDA_OUT);
+               if (mxl_fail(ret))
+                       goto fail;
+       }
+       *pbyte = byte;
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_start(struct mxl111sf_state *state)
+{
+       int ret;
+
+       mxl_i2c("()");
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN); /* start */
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_stop(struct mxl111sf_state *state)
+{
+       int ret;
+
+       mxl_i2c("()");
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN); /* stop */
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_SCL_OUT | SW_SDA_OUT);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_ack(struct mxl111sf_state *state)
+{
+       int ret;
+       u8 b = 0;
+
+       mxl_i2c("()");
+
+       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &b);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* pull SDA low */
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SDA_OUT);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+static int mxl111sf_i2c_nack(struct mxl111sf_state *state)
+{
+       int ret;
+
+       mxl_i2c("()");
+
+       /* SDA high to signal last byte read from slave */
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
+                                0x10 | SW_I2C_EN | SW_SDA_OUT);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_i2c_sw_xfer_msg(struct mxl111sf_state *state,
+                                   struct i2c_msg *msg)
+{
+       int i, ret;
+
+       mxl_i2c("()");
+
+       if (msg->flags & I2C_M_RD) {
+
+               ret = mxl111sf_i2c_start(state);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_i2c_bitbang_sendbyte(state,
+                                                   (msg->addr << 1) | 0x01);
+               if (mxl_fail(ret)) {
+                       mxl111sf_i2c_stop(state);
+                       goto fail;
+               }
+
+               for (i = 0; i < msg->len; i++) {
+                       ret = mxl111sf_i2c_bitbang_recvbyte(state,
+                                                           &msg->buf[i]);
+                       if (mxl_fail(ret)) {
+                               mxl111sf_i2c_stop(state);
+                               goto fail;
+                       }
+
+                       if (i < msg->len - 1)
+                               mxl111sf_i2c_ack(state);
+               }
+
+               mxl111sf_i2c_nack(state);
+
+               ret = mxl111sf_i2c_stop(state);
+               if (mxl_fail(ret))
+                       goto fail;
+
+       } else {
+
+               ret = mxl111sf_i2c_start(state);
+               if (mxl_fail(ret))
+                       goto fail;
+
+               ret = mxl111sf_i2c_bitbang_sendbyte(state,
+                                                   (msg->addr << 1) & 0xfe);
+               if (mxl_fail(ret)) {
+                       mxl111sf_i2c_stop(state);
+                       goto fail;
+               }
+
+               for (i = 0; i < msg->len; i++) {
+                       ret = mxl111sf_i2c_bitbang_sendbyte(state,
+                                                           msg->buf[i]);
+                       if (mxl_fail(ret)) {
+                               mxl111sf_i2c_stop(state);
+                               goto fail;
+                       }
+               }
+
+               /* FIXME: we only want to do this on the last transaction */
+               mxl111sf_i2c_stop(state);
+       }
+fail:
+       return ret;
+}
+
+/* HW-I2C ----------------------------------------------------------------- */
+
+#define USB_WRITE_I2C_CMD     0x99
+#define USB_READ_I2C_CMD      0xdd
+#define USB_END_I2C_CMD       0xfe
+
+#define USB_WRITE_I2C_CMD_LEN   26
+#define USB_READ_I2C_CMD_LEN    24
+
+#define I2C_MUX_REG           0x30
+#define I2C_CONTROL_REG       0x00
+#define I2C_SLAVE_ADDR_REG    0x08
+#define I2C_DATA_REG          0x0c
+#define I2C_INT_STATUS_REG    0x10
+
+static int mxl111sf_i2c_send_data(struct mxl111sf_state *state,
+                                 u8 index, u8 *wdata)
+{
+       int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
+                                   &wdata[1], 25, NULL, 0);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+static int mxl111sf_i2c_get_data(struct mxl111sf_state *state,
+                                u8 index, u8 *wdata, u8 *rdata)
+{
+       int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
+                                   &wdata[1], 25, rdata, 24);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+static u8 mxl111sf_i2c_check_status(struct mxl111sf_state *state)
+{
+       u8 status = 0;
+       u8 buf[26];
+
+       mxl_i2c_adv("()");
+
+       buf[0] = USB_READ_I2C_CMD;
+       buf[1] = 0x00;
+
+       buf[2] = I2C_INT_STATUS_REG;
+       buf[3] = 0x00;
+       buf[4] = 0x00;
+
+       buf[5] = USB_END_I2C_CMD;
+
+       mxl111sf_i2c_get_data(state, 0, buf, buf);
+
+       if (buf[1] & 0x04)
+               status = 1;
+
+       return status;
+}
+
+static u8 mxl111sf_i2c_check_fifo(struct mxl111sf_state *state)
+{
+       u8 status = 0;
+       u8 buf[26];
+
+       mxl_i2c("()");
+
+       buf[0] = USB_READ_I2C_CMD;
+       buf[1] = 0x00;
+
+       buf[2] = I2C_MUX_REG;
+       buf[3] = 0x00;
+       buf[4] = 0x00;
+
+       buf[5] = I2C_INT_STATUS_REG;
+       buf[6] = 0x00;
+       buf[7] = 0x00;
+       buf[8] = USB_END_I2C_CMD;
+
+       mxl111sf_i2c_get_data(state, 0, buf, buf);
+
+       if (0x08 == (buf[1] & 0x08))
+               status = 1;
+
+       if ((buf[5] & 0x02) == 0x02)
+               mxl_i2c("(buf[5] & 0x02) == 0x02"); /* FIXME */
+
+       return status;
+}
+
+static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
+                                 u8 count, u8 *rbuf)
+{
+       u8 i2c_w_data[26];
+       u8 i2c_r_data[24];
+       u8 i = 0;
+       u8 fifo_status = 0;
+       int status = 0;
+
+       mxl_i2c("read %d bytes", count);
+
+       while ((fifo_status == 0) && (i++ < 5))
+               fifo_status = mxl111sf_i2c_check_fifo(state);
+
+       i2c_w_data[0] = 0xDD;
+       i2c_w_data[1] = 0x00;
+
+       for (i = 2; i < 26; i++)
+               i2c_w_data[i] = 0xFE;
+
+       for (i = 0; i < count; i++) {
+               i2c_w_data[2+(i*3)] = 0x0C;
+               i2c_w_data[3+(i*3)] = 0x00;
+               i2c_w_data[4+(i*3)] = 0x00;
+       }
+
+       mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
+
+       /* Check for I2C NACK status */
+       if (mxl111sf_i2c_check_status(state) == 1) {
+               mxl_i2c("error!");
+       } else {
+               for (i = 0; i < count; i++) {
+                       rbuf[i] = i2c_r_data[(i*3)+1];
+                       mxl_i2c("%02x\t %02x",
+                               i2c_r_data[(i*3)+1],
+                               i2c_r_data[(i*3)+2]);
+               }
+
+               status = 1;
+       }
+
+       return status;
+}
+
+#define HWI2C400 1
+static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state,
+                                   struct i2c_msg *msg)
+{
+       int i, k, ret = 0;
+       u16 index = 0;
+       u8 buf[26];
+       u8 i2c_r_data[24];
+       u16 block_len;
+       u16 left_over_len;
+       u8 rd_status[8];
+       u8 ret_status;
+       u8 readbuff[26];
+
+       mxl_i2c("addr: 0x%02x, read buff len: %d, write buff len: %d",
+               msg->addr, (msg->flags & I2C_M_RD) ? msg->len : 0,
+               (!(msg->flags & I2C_M_RD)) ? msg->len : 0);
+
+       for (index = 0; index < 26; index++)
+               buf[index] = USB_END_I2C_CMD;
+
+       /* command to indicate data payload is destined for I2C interface */
+       buf[0] = USB_WRITE_I2C_CMD;
+       buf[1] = 0x00;
+
+       /* enable I2C interface */
+       buf[2] = I2C_MUX_REG;
+       buf[3] = 0x80;
+       buf[4] = 0x00;
+
+       /* enable I2C interface */
+       buf[5] = I2C_MUX_REG;
+       buf[6] = 0x81;
+       buf[7] = 0x00;
+
+       /* set Timeout register on I2C interface */
+       buf[8] = 0x14;
+       buf[9] = 0xff;
+       buf[10] = 0x00;
+#if 0
+       /* enable Interrupts on I2C interface */
+       buf[8] = 0x24;
+       buf[9] = 0xF7;
+       buf[10] = 0x00;
+#endif
+       buf[11] = 0x24;
+       buf[12] = 0xF7;
+       buf[13] = 0x00;
+
+       ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+       /* write data on I2C bus */
+       if (!(msg->flags & I2C_M_RD) && (msg->len > 0)) {
+               mxl_i2c("%d\t%02x", msg->len, msg->buf[0]);
+
+               /* control register on I2C interface to initialize I2C bus */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0x5E;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+               /* I2C Slave device Address */
+               buf[5] = I2C_SLAVE_ADDR_REG;
+               buf[6] = (msg->addr);
+               buf[7] = 0x00;
+               buf[8] = USB_END_I2C_CMD;
+               ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+               /* check for slave device status */
+               if (mxl111sf_i2c_check_status(state) == 1) {
+                       mxl_i2c("NACK writing slave address %02x",
+                               msg->addr);
+                       /* if NACK, stop I2C bus and exit */
+                       buf[2] = I2C_CONTROL_REG;
+                       buf[3] = 0x4E;
+                       buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                       ret = -EIO;
+                       goto exit;
+               }
+
+               /* I2C interface can do I2C operations in block of 8 bytes of
+                  I2C data. calculation to figure out number of blocks of i2c
+                  data required to program */
+               block_len = (msg->len / 8);
+               left_over_len = (msg->len % 8);
+               index = 0;
+
+               mxl_i2c("block_len %d, left_over_len %d",
+                       block_len, left_over_len);
+
+               for (index = 0; index < block_len; index++) {
+                       for (i = 0; i < 8; i++) {
+                               /* write data on I2C interface */
+                               buf[2+(i*3)] = I2C_DATA_REG;
+                               buf[3+(i*3)] = msg->buf[(index*8)+i];
+                               buf[4+(i*3)] = 0x00;
+                       }
+
+                       ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+                       /* check for I2C NACK status */
+                       if (mxl111sf_i2c_check_status(state) == 1) {
+                               mxl_i2c("NACK writing slave address %02x",
+                                       msg->addr);
+
+                               /* if NACK, stop I2C bus and exit */
+                               buf[2] = I2C_CONTROL_REG;
+                               buf[3] = 0x4E;
+                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                               ret = -EIO;
+                               goto exit;
+                       }
+
+               }
+
+               if (left_over_len) {
+                       for (k = 0; k < 26; k++)
+                               buf[k] = USB_END_I2C_CMD;
+
+                       buf[0] = 0x99;
+                       buf[1] = 0x00;
+
+                       for (i = 0; i < left_over_len; i++) {
+                               buf[2+(i*3)] = I2C_DATA_REG;
+                               buf[3+(i*3)] = msg->buf[(index*8)+i];
+                               mxl_i2c("index = %d %d data %d",
+                                       index, i, msg->buf[(index*8)+i]);
+                               buf[4+(i*3)] = 0x00;
+                       }
+                       ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+                       /* check for I2C NACK status */
+                       if (mxl111sf_i2c_check_status(state) == 1) {
+                               mxl_i2c("NACK writing slave address %02x",
+                                       msg->addr);
+
+                               /* if NACK, stop I2C bus and exit */
+                               buf[2] = I2C_CONTROL_REG;
+                               buf[3] = 0x4E;
+                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                               ret = -EIO;
+                               goto exit;
+                       }
+
+               }
+
+               /* issue I2C STOP after write */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0x4E;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+       }
+
+       /* read data from I2C bus */
+       if ((msg->flags & I2C_M_RD) && (msg->len > 0)) {
+               mxl_i2c("read buf len %d", msg->len);
+
+               /* command to indicate data payload is
+                  destined for I2C interface */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0xDF;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+               /* I2C xfer length */
+               buf[5] = 0x14;
+               buf[6] = (msg->len & 0xFF);
+               buf[7] = 0;
+
+               /* I2C slave device Address */
+               buf[8] = I2C_SLAVE_ADDR_REG;
+               buf[9] = msg->addr;
+               buf[10] = 0x00;
+               buf[11] = USB_END_I2C_CMD;
+               ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+               /* check for I2C NACK status */
+               if (mxl111sf_i2c_check_status(state) == 1) {
+                       mxl_i2c("NACK reading slave address %02x",
+                               msg->addr);
+
+                       /* if NACK, stop I2C bus and exit */
+                       buf[2] = I2C_CONTROL_REG;
+                       buf[3] = 0xC7;
+                       buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                       ret = -EIO;
+                       goto exit;
+               }
+
+               /* I2C interface can do I2C operations in block of 8 bytes of
+                  I2C data. calculation to figure out number of blocks of
+                  i2c data required to program */
+               block_len = ((msg->len) / 8);
+               left_over_len = ((msg->len) % 8);
+               index = 0;
+
+               mxl_i2c("block_len %d, left_over_len %d",
+                       block_len, left_over_len);
+
+               /* command to read data from I2C interface */
+               buf[0] = USB_READ_I2C_CMD;
+               buf[1] = 0x00;
+
+               for (index = 0; index < block_len; index++) {
+                       /* setup I2C read request packet on I2C interface */
+                       for (i = 0; i < 8; i++) {
+                               buf[2+(i*3)] = I2C_DATA_REG;
+                               buf[3+(i*3)] = 0x00;
+                               buf[4+(i*3)] = 0x00;
+                       }
+
+                       ret = mxl111sf_i2c_get_data(state, 0, buf, i2c_r_data);
+
+                       /* check for I2C NACK status */
+                       if (mxl111sf_i2c_check_status(state) == 1) {
+                               mxl_i2c("NACK reading slave address %02x",
+                                       msg->addr);
+
+                               /* if NACK, stop I2C bus and exit */
+                               buf[2] = I2C_CONTROL_REG;
+                               buf[3] = 0xC7;
+                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                               ret = -EIO;
+                               goto exit;
+                       }
+
+                       /* copy data from i2c data payload to read buffer */
+                       for (i = 0; i < 8; i++) {
+                               rd_status[i] = i2c_r_data[(i*3)+2];
+
+                               if (rd_status[i] == 0x04) {
+                                       if (i < 7) {
+                                               mxl_i2c("i2c fifo empty!"
+                                                       " @ %d", i);
+                                               msg->buf[(index*8)+i] =
+                                                       i2c_r_data[(i*3)+1];
+                                               /* read again */
+                                               ret_status =
+                                                       mxl111sf_i2c_readagain(
+                                                               state, 8-(i+1),
+                                                               readbuff);
+                                               if (ret_status == 1) {
+                                                       for (k = 0;
+                                                            k < 8-(i+1);
+                                                            k++) {
+
+                                       msg->buf[(index*8)+(k+i+1)] =
+                                               readbuff[k];
+                                       mxl_i2c("read data: %02x\t %02x",
+                                               msg->buf[(index*8)+(k+i)],
+                                               (index*8)+(k+i));
+                                       mxl_i2c("read data: %02x\t %02x",
+                                               msg->buf[(index*8)+(k+i+1)],
+                                               readbuff[k]);
+
+                                                       }
+                                                       goto stop_copy;
+                                               } else {
+                                                       mxl_i2c("readagain "
+                                                               "ERROR!");
+                                               }
+                                       } else {
+                                               msg->buf[(index*8)+i] =
+                                                       i2c_r_data[(i*3)+1];
+                                       }
+                               } else {
+                                       msg->buf[(index*8)+i] =
+                                               i2c_r_data[(i*3)+1];
+                               }
+                       }
+stop_copy:
+                       ;
+
+               }
+
+               if (left_over_len) {
+                       for (k = 0; k < 26; k++)
+                               buf[k] = USB_END_I2C_CMD;
+
+                       buf[0] = 0xDD;
+                       buf[1] = 0x00;
+
+                       for (i = 0; i < left_over_len; i++) {
+                               buf[2+(i*3)] = I2C_DATA_REG;
+                               buf[3+(i*3)] = 0x00;
+                               buf[4+(i*3)] = 0x00;
+                       }
+                       ret = mxl111sf_i2c_get_data(state, 0, buf,
+                                                   i2c_r_data);
+
+                       /* check for I2C NACK status */
+                       if (mxl111sf_i2c_check_status(state) == 1) {
+                               mxl_i2c("NACK reading slave address %02x",
+                                       msg->addr);
+
+                               /* if NACK, stop I2C bus and exit */
+                               buf[2] = I2C_CONTROL_REG;
+                               buf[3] = 0xC7;
+                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+                               ret = -EIO;
+                               goto exit;
+                       }
+
+                       for (i = 0; i < left_over_len; i++) {
+                               msg->buf[(block_len*8)+i] =
+                                       i2c_r_data[(i*3)+1];
+                               mxl_i2c("read data: %02x\t %02x",
+                                       i2c_r_data[(i*3)+1],
+                                       i2c_r_data[(i*3)+2]);
+                       }
+               }
+
+               /* indicate I2C interface to issue NACK
+                  after next I2C read op */
+               buf[0] = USB_WRITE_I2C_CMD;
+               buf[1] = 0x00;
+
+               /* control register */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0x17;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+               buf[5] = USB_END_I2C_CMD;
+               ret = mxl111sf_i2c_send_data(state, 0, buf);
+
+               /* control register */
+               buf[2] = I2C_CONTROL_REG;
+               buf[3] = 0xC7;
+               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
+
+       }
+exit:
+       /* STOP and disable I2C MUX */
+       buf[0] = USB_WRITE_I2C_CMD;
+       buf[1] = 0x00;
+
+       /* de-initilize I2C BUS */
+       buf[5] = USB_END_I2C_CMD;
+       mxl111sf_i2c_send_data(state, 0, buf);
+
+       /* Control Register */
+       buf[2] = I2C_CONTROL_REG;
+       buf[3] = 0xDF;
+       buf[4] = 0x03;
+
+       /* disable I2C interface */
+       buf[5] = I2C_MUX_REG;
+       buf[6] = 0x00;
+       buf[7] = 0x00;
+
+       /* de-initilize I2C BUS */
+       buf[8] = USB_END_I2C_CMD;
+       mxl111sf_i2c_send_data(state, 0, buf);
+
+       /* disable I2C interface */
+       buf[2] = I2C_MUX_REG;
+       buf[3] = 0x81;
+       buf[4] = 0x00;
+
+       /* disable I2C interface */
+       buf[5] = I2C_MUX_REG;
+       buf[6] = 0x00;
+       buf[7] = 0x00;
+
+       /* disable I2C interface */
+       buf[8] = I2C_MUX_REG;
+       buf[9] = 0x00;
+       buf[10] = 0x00;
+
+       buf[11] = USB_END_I2C_CMD;
+       mxl111sf_i2c_send_data(state, 0, buf);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
+                     struct i2c_msg msg[], int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct mxl111sf_state *state = d->priv;
+       int hwi2c = (state->chip_rev > MXL111SF_V6);
+       int i, ret;
+
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+
+       for (i = 0; i < num; i++) {
+               ret = (hwi2c) ?
+                       mxl111sf_i2c_hw_xfer_msg(state, &msg[i]) :
+                       mxl111sf_i2c_sw_xfer_msg(state, &msg[i]);
+               if (mxl_fail(ret)) {
+                       mxl_debug_adv("failed with error %d on i2c "
+                                     "transaction %d of %d, %sing %d bytes "
+                                     "to/from 0x%02x", ret, i+1, num,
+                                     (msg[i].flags & I2C_M_RD) ?
+                                     "read" : "writ",
+                                     msg[i].len, msg[i].addr);
+
+                       break;
+               }
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return i == num ? num : -EREMOTEIO;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-i2c.h
new file mode 100644 (file)
index 0000000..a57a45f
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  mxl111sf-i2c.h - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _DVB_USB_MXL111SF_I2C_H_
+#define _DVB_USB_MXL111SF_I2C_H_
+
+#include <linux/i2c.h>
+
+int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
+                     struct i2c_msg msg[], int num);
+
+#endif /* _DVB_USB_MXL111SF_I2C_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.c
new file mode 100644 (file)
index 0000000..b741b3a
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ *  mxl111sf-phy.c - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "mxl111sf-phy.h"
+#include "mxl111sf-reg.h"
+
+int mxl111sf_init_tuner_demod(struct mxl111sf_state *state)
+{
+       struct mxl111sf_reg_ctrl_info mxl_111_overwrite_default[] = {
+               {0x07, 0xff, 0x0c},
+               {0x58, 0xff, 0x9d},
+               {0x09, 0xff, 0x00},
+               {0x06, 0xff, 0x06},
+               {0xc8, 0xff, 0x40}, /* ED_LE_WIN_OLD = 0 */
+               {0x8d, 0x01, 0x01}, /* NEGATE_Q */
+               {0x32, 0xff, 0xac}, /* DIG_RFREFSELECT = 12 */
+               {0x42, 0xff, 0x43}, /* DIG_REG_AMP = 4 */
+               {0x74, 0xff, 0xc4}, /* SSPUR_FS_PRIO = 4 */
+               {0x71, 0xff, 0xe6}, /* SPUR_ROT_PRIO_VAL = 1 */
+               {0x83, 0xff, 0x64}, /* INF_FILT1_THD_SC = 100 */
+               {0x85, 0xff, 0x64}, /* INF_FILT2_THD_SC = 100 */
+               {0x88, 0xff, 0xf0}, /* INF_THD = 240 */
+               {0x6f, 0xf0, 0xb0}, /* DFE_DLY = 11 */
+               {0x00, 0xff, 0x01}, /* Change to page 1 */
+               {0x81, 0xff, 0x11}, /* DSM_FERR_BYPASS = 1 */
+               {0xf4, 0xff, 0x07}, /* DIG_FREQ_CORR = 1 */
+               {0xd4, 0x1f, 0x0f}, /* SPUR_TEST_NOISE_TH = 15 */
+               {0xd6, 0xff, 0x0c}, /* SPUR_TEST_NOISE_PAPR = 12 */
+               {0x00, 0xff, 0x00}, /* Change to page 0 */
+               {0,    0,    0}
+       };
+
+       mxl_debug("()");
+
+       return mxl111sf_ctrl_program_regs(state, mxl_111_overwrite_default);
+}
+
+int mxl1x1sf_soft_reset(struct mxl111sf_state *state)
+{
+       int ret;
+       mxl_debug("()");
+
+       ret = mxl111sf_write_reg(state, 0xff, 0x00); /* AIC */
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_write_reg(state, 0x02, 0x01); /* get out of reset */
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode)
+{
+       int ret;
+
+       mxl_debug("(%s)", MXL_SOC_MODE == mode ?
+               "MXL_SOC_MODE" : "MXL_TUNER_MODE");
+
+       /* set device mode */
+       ret = mxl111sf_write_reg(state, 0x03,
+                                MXL_SOC_MODE == mode ? 0x01 : 0x00);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg_mask(state,
+                                     0x7d, 0x40, MXL_SOC_MODE == mode ?
+                                     0x00 : /* enable impulse noise filter,
+                                               INF_BYP = 0 */
+                                     0x40); /* disable impulse noise filter,
+                                               INF_BYP = 1 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       state->device_mode = mode;
+fail:
+       return ret;
+}
+
+/* power up tuner */
+int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff)
+{
+       mxl_debug("(%d)", onoff);
+
+       return mxl111sf_write_reg(state, 0x01, onoff ? 0x01 : 0x00);
+}
+
+int mxl111sf_disable_656_port(struct mxl111sf_state *state)
+{
+       mxl_debug("()");
+
+       return mxl111sf_write_reg_mask(state, 0x12, 0x04, 0x00);
+}
+
+int mxl111sf_enable_usb_output(struct mxl111sf_state *state)
+{
+       mxl_debug("()");
+
+       return mxl111sf_write_reg_mask(state, 0x17, 0x40, 0x00);
+}
+
+/* initialize TSIF as input port of MxL1X1SF for MPEG2 data transfer */
+int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
+                           unsigned int parallel_serial,
+                           unsigned int msb_lsb_1st,
+                           unsigned int clock_phase,
+                           unsigned int mpeg_valid_pol,
+                           unsigned int mpeg_sync_pol)
+{
+       int ret;
+       u8 mode, tmp;
+
+       mxl_debug("(%u,%u,%u,%u,%u)", parallel_serial, msb_lsb_1st,
+                 clock_phase, mpeg_valid_pol, mpeg_sync_pol);
+
+       /* Enable PIN MUX */
+       ret = mxl111sf_write_reg(state, V6_PIN_MUX_MODE_REG, V6_ENABLE_PIN_MUX);
+       mxl_fail(ret);
+
+       /* Configure MPEG Clock phase */
+       mxl111sf_read_reg(state, V6_MPEG_IN_CLK_INV_REG, &mode);
+
+       if (clock_phase == TSIF_NORMAL)
+               mode &= ~V6_INVERTED_CLK_PHASE;
+       else
+               mode |= V6_INVERTED_CLK_PHASE;
+
+       ret = mxl111sf_write_reg(state, V6_MPEG_IN_CLK_INV_REG, mode);
+       mxl_fail(ret);
+
+       /* Configure data input mode, MPEG Valid polarity, MPEG Sync polarity
+        * Get current configuration */
+       ret = mxl111sf_read_reg(state, V6_MPEG_IN_CTRL_REG, &mode);
+       mxl_fail(ret);
+
+       /* Data Input mode */
+       if (parallel_serial == TSIF_INPUT_PARALLEL) {
+               /* Disable serial mode */
+               mode &= ~V6_MPEG_IN_DATA_SERIAL;
+
+               /* Enable Parallel mode */
+               mode |= V6_MPEG_IN_DATA_PARALLEL;
+       } else {
+               /* Disable Parallel mode */
+               mode &= ~V6_MPEG_IN_DATA_PARALLEL;
+
+               /* Enable Serial Mode */
+               mode |= V6_MPEG_IN_DATA_SERIAL;
+
+               /* If serial interface is chosen, configure
+                  MSB or LSB order in transmission */
+               ret = mxl111sf_read_reg(state,
+                                       V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
+                                       &tmp);
+               mxl_fail(ret);
+
+               if (msb_lsb_1st == MPEG_SER_MSB_FIRST_ENABLED)
+                       tmp |= V6_MPEG_SER_MSB_FIRST;
+               else
+                       tmp &= ~V6_MPEG_SER_MSB_FIRST;
+
+               ret = mxl111sf_write_reg(state,
+                                        V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
+                                        tmp);
+               mxl_fail(ret);
+       }
+
+       /* MPEG Sync polarity */
+       if (mpeg_sync_pol == TSIF_NORMAL)
+               mode &= ~V6_INVERTED_MPEG_SYNC;
+       else
+               mode |= V6_INVERTED_MPEG_SYNC;
+
+       /* MPEG Valid polarity */
+       if (mpeg_valid_pol == 0)
+               mode &= ~V6_INVERTED_MPEG_VALID;
+       else
+               mode |= V6_INVERTED_MPEG_VALID;
+
+       ret = mxl111sf_write_reg(state, V6_MPEG_IN_CTRL_REG, mode);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size)
+{
+       static struct mxl111sf_reg_ctrl_info init_i2s[] = {
+               {0x1b, 0xff, 0x1e}, /* pin mux mode, Choose 656/I2S input */
+               {0x15, 0x60, 0x60}, /* Enable I2S */
+               {0x17, 0xe0, 0x20}, /* Input, MPEG MODE USB,
+                                      Inverted 656 Clock, I2S_SOFT_RESET,
+                                      0 : Normal operation, 1 : Reset State */
+#if 0
+               {0x12, 0x01, 0x00}, /* AUDIO_IRQ_CLR (Overflow Indicator) */
+#endif
+               {0x00, 0xff, 0x02}, /* Change to Control Page */
+               {0x26, 0x0d, 0x0d}, /* I2S_MODE & BT656_SRC_SEL for FPGA only */
+               {0x00, 0xff, 0x00},
+               {0,    0,    0}
+       };
+       int ret;
+
+       mxl_debug("(0x%02x)", sample_size);
+
+       ret = mxl111sf_ctrl_program_regs(state, init_i2s);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, V6_I2S_NUM_SAMPLES_REG, sample_size);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+int mxl111sf_disable_i2s_port(struct mxl111sf_state *state)
+{
+       static struct mxl111sf_reg_ctrl_info disable_i2s[] = {
+               {0x15, 0x40, 0x00},
+               {0,    0,    0}
+       };
+
+       mxl_debug("()");
+
+       return mxl111sf_ctrl_program_regs(state, disable_i2s);
+}
+
+int mxl111sf_config_i2s(struct mxl111sf_state *state,
+                       u8 msb_start_pos, u8 data_width)
+{
+       int ret;
+       u8 tmp;
+
+       mxl_debug("(0x%02x, 0x%02x)", msb_start_pos, data_width);
+
+       ret = mxl111sf_read_reg(state, V6_I2S_STREAM_START_BIT_REG, &tmp);
+       if (mxl_fail(ret))
+               goto fail;
+
+       tmp &= 0xe0;
+       tmp |= msb_start_pos;
+       ret = mxl111sf_write_reg(state, V6_I2S_STREAM_START_BIT_REG, tmp);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_read_reg(state, V6_I2S_STREAM_END_BIT_REG, &tmp);
+       if (mxl_fail(ret))
+               goto fail;
+
+       tmp &= 0xe0;
+       tmp |= data_width;
+       ret = mxl111sf_write_reg(state, V6_I2S_STREAM_END_BIT_REG, tmp);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)
+{
+       u8 val;
+       int ret;
+
+       mxl_debug("(%d)", onoff);
+
+       ret = mxl111sf_write_reg(state, 0x00, 0x02);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_read_reg(state, V8_SPI_MODE_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if (onoff)
+               val |= 0x04;
+       else
+               val &= ~0x04;
+
+       ret = mxl111sf_write_reg(state, V8_SPI_MODE_REG, val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_write_reg(state, 0x00, 0x00);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+int mxl111sf_idac_config(struct mxl111sf_state *state,
+                        u8 control_mode, u8 current_setting,
+                        u8 current_value, u8 hysteresis_value)
+{
+       int ret;
+       u8 val;
+       /* current value will be set for both automatic & manual IDAC control */
+       val = current_value;
+
+       if (control_mode == IDAC_MANUAL_CONTROL) {
+               /* enable manual control of IDAC */
+               val |= IDAC_MANUAL_CONTROL_BIT_MASK;
+
+               if (current_setting == IDAC_CURRENT_SINKING_ENABLE)
+                       /* enable current sinking in manual mode */
+                       val |= IDAC_CURRENT_SINKING_BIT_MASK;
+               else
+                       /* disable current sinking in manual mode */
+                       val &= ~IDAC_CURRENT_SINKING_BIT_MASK;
+       } else {
+               /* disable manual control of IDAC */
+               val &= ~IDAC_MANUAL_CONTROL_BIT_MASK;
+
+               /* set hysteresis value  reg: 0x0B<5:0> */
+               ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,
+                                        (hysteresis_value & 0x3F));
+               mxl_fail(ret);
+       }
+
+       ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-phy.h
new file mode 100644 (file)
index 0000000..f075607
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  mxl111sf-phy.h - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _DVB_USB_MXL111SF_PHY_H_
+#define _DVB_USB_MXL111SF_PHY_H_
+
+#include "mxl111sf.h"
+
+int mxl1x1sf_soft_reset(struct mxl111sf_state *state);
+int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode);
+int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff);
+int mxl111sf_disable_656_port(struct mxl111sf_state *state);
+int mxl111sf_init_tuner_demod(struct mxl111sf_state *state);
+int mxl111sf_enable_usb_output(struct mxl111sf_state *state);
+int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
+                           unsigned int parallel_serial,
+                           unsigned int msb_lsb_1st,
+                           unsigned int clock_phase,
+                           unsigned int mpeg_valid_pol,
+                           unsigned int mpeg_sync_pol);
+int mxl111sf_config_i2s(struct mxl111sf_state *state,
+                       u8 msb_start_pos, u8 data_width);
+int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size);
+int mxl111sf_disable_i2s_port(struct mxl111sf_state *state);
+int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff);
+int mxl111sf_idac_config(struct mxl111sf_state *state,
+                        u8 control_mode, u8 current_setting,
+                        u8 current_value, u8 hysteresis_value);
+
+#endif /* _DVB_USB_MXL111SF_PHY_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-reg.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-reg.h
new file mode 100644 (file)
index 0000000..17831b0
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ *  mxl111sf-reg.h - driver for the MaxLinear MXL111SF
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _DVB_USB_MXL111SF_REG_H_
+#define _DVB_USB_MXL111SF_REG_H_
+
+#define CHIP_ID_REG                  0xFC
+#define TOP_CHIP_REV_ID_REG          0xFA
+
+#define V6_SNR_RB_LSB_REG            0x27
+#define V6_SNR_RB_MSB_REG            0x28
+
+#define V6_N_ACCUMULATE_REG          0x11
+#define V6_RS_AVG_ERRORS_LSB_REG     0x2C
+#define V6_RS_AVG_ERRORS_MSB_REG     0x2D
+
+#define V6_IRQ_STATUS_REG            0x24
+#define  IRQ_MASK_FEC_LOCK       0x10
+
+#define V6_SYNC_LOCK_REG             0x28
+#define SYNC_LOCK_MASK           0x10
+
+#define V6_RS_LOCK_DET_REG           0x28
+#define  RS_LOCK_DET_MASK        0x08
+
+#define V6_INITACQ_NODETECT_REG    0x20
+#define V6_FORCE_NFFT_CPSIZE_REG   0x20
+
+#define V6_CODE_RATE_TPS_REG       0x29
+#define V6_CODE_RATE_TPS_MASK      0x07
+
+
+#define V6_CP_LOCK_DET_REG        0x28
+#define V6_CP_LOCK_DET_MASK       0x04
+
+#define V6_TPS_HIERACHY_REG        0x29
+#define V6_TPS_HIERARCHY_INFO_MASK  0x40
+
+#define V6_MODORDER_TPS_REG        0x2A
+#define V6_PARAM_CONSTELLATION_MASK   0x30
+
+#define V6_MODE_TPS_REG            0x2A
+#define V6_PARAM_FFT_MODE_MASK        0x0C
+
+
+#define V6_CP_TPS_REG             0x29
+#define V6_PARAM_GI_MASK              0x30
+
+#define V6_TPS_LOCK_REG           0x2A
+#define V6_PARAM_TPS_LOCK_MASK        0x40
+
+#define V6_FEC_PER_COUNT_REG      0x2E
+#define V6_FEC_PER_SCALE_REG      0x2B
+#define V6_FEC_PER_SCALE_MASK        0x03
+#define V6_FEC_PER_CLR_REG        0x20
+#define V6_FEC_PER_CLR_MASK          0x01
+
+#define V6_PIN_MUX_MODE_REG       0x1B
+#define V6_ENABLE_PIN_MUX            0x1E
+
+#define V6_I2S_NUM_SAMPLES_REG    0x16
+
+#define V6_MPEG_IN_CLK_INV_REG    0x17
+#define V6_MPEG_IN_CTRL_REG       0x18
+
+#define V6_INVERTED_CLK_PHASE       0x20
+#define V6_MPEG_IN_DATA_PARALLEL    0x01
+#define V6_MPEG_IN_DATA_SERIAL      0x02
+
+#define V6_INVERTED_MPEG_SYNC       0x04
+#define V6_INVERTED_MPEG_VALID      0x08
+
+#define TSIF_INPUT_PARALLEL         0
+#define TSIF_INPUT_SERIAL           1
+#define TSIF_NORMAL                 0
+
+#define V6_MPEG_INOUT_BIT_ORDER_CTRL_REG  0x19
+#define V6_MPEG_SER_MSB_FIRST                0x80
+#define MPEG_SER_MSB_FIRST_ENABLED        0x01
+
+#define V6_656_I2S_BUFF_STATUS_REG   0x2F
+#define V6_656_OVERFLOW_MASK_BIT         0x08
+#define V6_I2S_OVERFLOW_MASK_BIT         0x01
+
+#define V6_I2S_STREAM_START_BIT_REG  0x14
+#define V6_I2S_STREAM_END_BIT_REG    0x15
+#define I2S_RIGHT_JUSTIFIED     0
+#define I2S_LEFT_JUSTIFIED      1
+#define I2S_DATA_FORMAT         2
+
+#define V6_TUNER_LOOP_THRU_CONTROL_REG  0x09
+#define V6_ENABLE_LOOP_THRU               0x01
+
+#define TOTAL_NUM_IF_OUTPUT_FREQ       16
+
+#define TUNER_NORMAL_IF_SPECTRUM       0x0
+#define TUNER_INVERT_IF_SPECTRUM       0x10
+
+#define V6_TUNER_IF_SEL_REG              0x06
+#define V6_TUNER_IF_FCW_REG              0x3C
+#define V6_TUNER_IF_FCW_BYP_REG          0x3D
+#define V6_RF_LOCK_STATUS_REG            0x23
+
+#define NUM_DIG_TV_CHANNEL     1000
+
+#define V6_DIG_CLK_FREQ_SEL_REG  0x07
+#define V6_REF_SYNTH_INT_REG     0x5C
+#define V6_REF_SYNTH_REMAIN_REG  0x58
+#define V6_DIG_RFREFSELECT_REG   0x32
+#define V6_XTAL_CLK_OUT_GAIN_REG   0x31
+#define V6_TUNER_LOOP_THRU_CTRL_REG      0x09
+#define V6_DIG_XTAL_ENABLE_REG  0x06
+#define V6_DIG_XTAL_BIAS_REG  0x66
+#define V6_XTAL_CAP_REG    0x08
+
+#define V6_GPO_CTRL_REG     0x18
+#define MXL_GPO_0           0x00
+#define MXL_GPO_1           0x01
+#define V6_GPO_0_MASK       0x10
+#define V6_GPO_1_MASK       0x20
+
+#define V6_111SF_GPO_CTRL_REG     0x19
+#define MXL_111SF_GPO_1               0x00
+#define MXL_111SF_GPO_2               0x01
+#define MXL_111SF_GPO_3               0x02
+#define MXL_111SF_GPO_4               0x03
+#define MXL_111SF_GPO_5               0x04
+#define MXL_111SF_GPO_6               0x05
+#define MXL_111SF_GPO_7               0x06
+
+#define MXL_111SF_GPO_0_MASK          0x01
+#define MXL_111SF_GPO_1_MASK          0x02
+#define MXL_111SF_GPO_2_MASK          0x04
+#define MXL_111SF_GPO_3_MASK          0x08
+#define MXL_111SF_GPO_4_MASK          0x10
+#define MXL_111SF_GPO_5_MASK          0x20
+#define MXL_111SF_GPO_6_MASK          0x40
+
+#define V6_ATSC_CONFIG_REG  0x0A
+
+#define MXL_MODE_REG    0x03
+#define START_TUNE_REG  0x1C
+
+#define V6_IDAC_HYSTERESIS_REG    0x0B
+#define V6_IDAC_SETTINGS_REG      0x0C
+#define IDAC_MANUAL_CONTROL             1
+#define IDAC_CURRENT_SINKING_ENABLE     1
+#define IDAC_MANUAL_CONTROL_BIT_MASK      0x80
+#define IDAC_CURRENT_SINKING_BIT_MASK     0x40
+
+#define V8_SPI_MODE_REG  0xE9
+
+#define V6_DIG_RF_PWR_LSB_REG  0x46
+#define V6_DIG_RF_PWR_MSB_REG  0x47
+
+#endif /* _DVB_USB_MXL111SF_REG_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.c
new file mode 100644 (file)
index 0000000..ef4c65f
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ *  mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "mxl111sf-tuner.h"
+#include "mxl111sf-phy.h"
+#include "mxl111sf-reg.h"
+
+/* debug */
+static int mxl111sf_tuner_debug;
+module_param_named(debug, mxl111sf_tuner_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+#define mxl_dbg(fmt, arg...) \
+       if (mxl111sf_tuner_debug) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+#define err pr_err
+
+/* ------------------------------------------------------------------------ */
+
+struct mxl111sf_tuner_state {
+       struct mxl111sf_state *mxl_state;
+
+       struct mxl111sf_tuner_config *cfg;
+
+       enum mxl_if_freq if_freq;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+static int mxl111sf_tuner_read_reg(struct mxl111sf_tuner_state *state,
+                                  u8 addr, u8 *data)
+{
+       return (state->cfg->read_reg) ?
+               state->cfg->read_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static int mxl111sf_tuner_write_reg(struct mxl111sf_tuner_state *state,
+                                   u8 addr, u8 data)
+{
+       return (state->cfg->write_reg) ?
+               state->cfg->write_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static int mxl111sf_tuner_program_regs(struct mxl111sf_tuner_state *state,
+                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
+{
+       return (state->cfg->program_regs) ?
+               state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
+               -EINVAL;
+}
+
+static int mxl1x1sf_tuner_top_master_ctrl(struct mxl111sf_tuner_state *state,
+                                         int onoff)
+{
+       return (state->cfg->top_master_ctrl) ?
+               state->cfg->top_master_ctrl(state->mxl_state, onoff) :
+               -EINVAL;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct mxl111sf_reg_ctrl_info mxl_phy_tune_rf[] = {
+       {0x1d, 0x7f, 0x00}, /* channel bandwidth section 1/2/3,
+                              DIG_MODEINDEX, _A, _CSF, */
+       {0x1e, 0xff, 0x00}, /* channel frequency (lo and fractional) */
+       {0x1f, 0xff, 0x00}, /* channel frequency (hi for integer portion) */
+       {0,    0,    0}
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct mxl111sf_reg_ctrl_info *mxl111sf_calc_phy_tune_regs(u32 freq,
+                                                                 u8 bw)
+{
+       u8 filt_bw;
+
+       /* set channel bandwidth */
+       switch (bw) {
+       case 0: /* ATSC */
+               filt_bw = 25;
+               break;
+       case 1: /* QAM */
+               filt_bw = 69;
+               break;
+       case 6:
+               filt_bw = 21;
+               break;
+       case 7:
+               filt_bw = 42;
+               break;
+       case 8:
+               filt_bw = 63;
+               break;
+       default:
+               err("%s: invalid bandwidth setting!", __func__);
+               return NULL;
+       }
+
+       /* calculate RF channel */
+       freq /= 1000000;
+
+       freq *= 64;
+#if 0
+       /* do round */
+       freq += 0.5;
+#endif
+       /* set bandwidth */
+       mxl_phy_tune_rf[0].data = filt_bw;
+
+       /* set RF */
+       mxl_phy_tune_rf[1].data = (freq & 0xff);
+       mxl_phy_tune_rf[2].data = (freq >> 8) & 0xff;
+
+       /* start tune */
+       return mxl_phy_tune_rf;
+}
+
+static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state)
+{
+       int ret;
+       u8 ctrl;
+#if 0
+       u16 iffcw;
+       u32 if_freq;
+#endif
+       mxl_dbg("(IF polarity = %d, IF freq = 0x%02x)",
+               state->cfg->invert_spectrum, state->cfg->if_freq);
+
+       /* set IF polarity */
+       ctrl = state->cfg->invert_spectrum;
+
+       ctrl |= state->cfg->if_freq;
+
+       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_SEL_REG, ctrl);
+       if (mxl_fail(ret))
+               goto fail;
+
+#if 0
+       if_freq /= 1000000;
+
+       /* do round */
+       if_freq += 0.5;
+
+       if (MXL_IF_LO == state->cfg->if_freq) {
+               ctrl = 0x08;
+               iffcw = (u16)(if_freq / (108 * 4096));
+       } else if (MXL_IF_HI == state->cfg->if_freq) {
+               ctrl = 0x08;
+               iffcw = (u16)(if_freq / (216 * 4096));
+       } else {
+               ctrl = 0;
+               iffcw = 0;
+       }
+
+       ctrl |= (iffcw >> 8);
+#endif
+       ret = mxl111sf_tuner_read_reg(state, V6_TUNER_IF_FCW_BYP_REG, &ctrl);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ctrl &= 0xf0;
+       ctrl |= 0x90;
+
+       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_BYP_REG, ctrl);
+       if (mxl_fail(ret))
+               goto fail;
+
+#if 0
+       ctrl = iffcw & 0x00ff;
+#endif
+       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl);
+       if (mxl_fail(ret))
+               goto fail;
+
+       state->if_freq = state->cfg->if_freq;
+fail:
+       return ret;
+}
+
+static int mxl1x1sf_tune_rf(struct dvb_frontend *fe, u32 freq, u8 bw)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       static struct mxl111sf_reg_ctrl_info *reg_ctrl_array;
+       int ret;
+       u8 mxl_mode;
+
+       mxl_dbg("(freq = %d, bw = 0x%x)", freq, bw);
+
+       /* stop tune */
+       ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 0);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* check device mode */
+       ret = mxl111sf_tuner_read_reg(state, MXL_MODE_REG, &mxl_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* Fill out registers for channel tune */
+       reg_ctrl_array = mxl111sf_calc_phy_tune_regs(freq, bw);
+       if (!reg_ctrl_array)
+               return -EINVAL;
+
+       ret = mxl111sf_tuner_program_regs(state, reg_ctrl_array);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if ((mxl_mode & MXL_DEV_MODE_MASK) == MXL_TUNER_MODE) {
+               /* IF tuner mode only */
+               mxl1x1sf_tuner_top_master_ctrl(state, 0);
+               mxl1x1sf_tuner_top_master_ctrl(state, 1);
+               mxl1x1sf_tuner_set_if_output_freq(state);
+       }
+
+       ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if (state->cfg->ant_hunt)
+               state->cfg->ant_hunt(fe);
+fail:
+       return ret;
+}
+
+static int mxl1x1sf_tuner_get_lock_status(struct mxl111sf_tuner_state *state,
+                                         int *rf_synth_lock,
+                                         int *ref_synth_lock)
+{
+       int ret;
+       u8 data;
+
+       *rf_synth_lock = 0;
+       *ref_synth_lock = 0;
+
+       ret = mxl111sf_tuner_read_reg(state, V6_RF_LOCK_STATUS_REG, &data);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *ref_synth_lock = ((data & 0x03) == 0x03) ? 1 : 0;
+       *rf_synth_lock  = ((data & 0x0c) == 0x0c) ? 1 : 0;
+fail:
+       return ret;
+}
+
+#if 0
+static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state *state,
+                                        int onoff)
+{
+       return mxl111sf_tuner_write_reg(state, V6_TUNER_LOOP_THRU_CTRL_REG,
+                                       onoff ? 1 : 0);
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys  = c->delivery_system;
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       int ret;
+       u8 bw;
+
+       mxl_dbg("()");
+
+       switch (delsys) {
+       case SYS_ATSC:
+       case SYS_ATSCMH:
+               bw = 0; /* ATSC */
+               break;
+       case SYS_DVBC_ANNEX_B:
+               bw = 1; /* US CABLE */
+               break;
+       case SYS_DVBT:
+               switch (c->bandwidth_hz) {
+               case 6000000:
+                       bw = 6;
+                       break;
+               case 7000000:
+                       bw = 7;
+                       break;
+               case 8000000:
+                       bw = 8;
+                       break;
+               default:
+                       err("%s: bandwidth not set!", __func__);
+                       return -EINVAL;
+               }
+               break;
+       default:
+               err("%s: modulation type not supported!", __func__);
+               return -EINVAL;
+       }
+       ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
+       if (mxl_fail(ret))
+               goto fail;
+
+       state->frequency = c->frequency;
+       state->bandwidth = c->bandwidth_hz;
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#if 0
+static int mxl111sf_tuner_init(struct dvb_frontend *fe)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       int ret;
+
+       /* wake from standby handled by usb driver */
+
+       return ret;
+}
+
+static int mxl111sf_tuner_sleep(struct dvb_frontend *fe)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       int ret;
+
+       /* enter standby mode handled by usb driver */
+
+       return ret;
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_tuner_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       int rf_locked, ref_locked, ret;
+
+       *status = 0;
+
+       ret = mxl1x1sf_tuner_get_lock_status(state, &rf_locked, &ref_locked);
+       if (mxl_fail(ret))
+               goto fail;
+       mxl_info("%s%s", rf_locked ? "rf locked " : "",
+                ref_locked ? "ref locked" : "");
+
+       if ((rf_locked) || (ref_locked))
+               *status |= TUNER_STATUS_LOCKED;
+fail:
+       return ret;
+}
+
+static int mxl111sf_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       u8 val1, val2;
+       int ret;
+
+       *strength = 0;
+
+       ret = mxl111sf_tuner_write_reg(state, 0x00, 0x02);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_LSB_REG, &val1);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_MSB_REG, &val2);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *strength = val1 | ((val2 & 0x07) << 8);
+fail:
+       ret = mxl111sf_tuner_write_reg(state, 0x00, 0x00);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_tuner_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       *frequency = state->frequency;
+       return 0;
+}
+
+static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       *bandwidth = state->bandwidth;
+       return 0;
+}
+
+static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe,
+                                          u32 *frequency)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+
+       *frequency = 0;
+
+       switch (state->if_freq) {
+       case MXL_IF_4_0:   /* 4.0   MHz */
+               *frequency = 4000000;
+               break;
+       case MXL_IF_4_5:   /* 4.5   MHz */
+               *frequency = 4500000;
+               break;
+       case MXL_IF_4_57:  /* 4.57  MHz */
+               *frequency = 4570000;
+               break;
+       case MXL_IF_5_0:   /* 5.0   MHz */
+               *frequency = 5000000;
+               break;
+       case MXL_IF_5_38:  /* 5.38  MHz */
+               *frequency = 5380000;
+               break;
+       case MXL_IF_6_0:   /* 6.0   MHz */
+               *frequency = 6000000;
+               break;
+       case MXL_IF_6_28:  /* 6.28  MHz */
+               *frequency = 6280000;
+               break;
+       case MXL_IF_7_2:   /* 7.2   MHz */
+               *frequency = 7200000;
+               break;
+       case MXL_IF_35_25: /* 35.25 MHz */
+               *frequency = 35250000;
+               break;
+       case MXL_IF_36:    /* 36    MHz */
+               *frequency = 36000000;
+               break;
+       case MXL_IF_36_15: /* 36.15 MHz */
+               *frequency = 36150000;
+               break;
+       case MXL_IF_44:    /* 44    MHz */
+               *frequency = 44000000;
+               break;
+       }
+       return 0;
+}
+
+static int mxl111sf_tuner_release(struct dvb_frontend *fe)
+{
+       struct mxl111sf_tuner_state *state = fe->tuner_priv;
+       mxl_dbg("()");
+       kfree(state);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
+       .info = {
+               .name = "MaxLinear MxL111SF",
+#if 0
+               .frequency_min  = ,
+               .frequency_max  = ,
+               .frequency_step = ,
+#endif
+       },
+#if 0
+       .init              = mxl111sf_tuner_init,
+       .sleep             = mxl111sf_tuner_sleep,
+#endif
+       .set_params        = mxl111sf_tuner_set_params,
+       .get_status        = mxl111sf_tuner_get_status,
+       .get_rf_strength   = mxl111sf_get_rf_strength,
+       .get_frequency     = mxl111sf_tuner_get_frequency,
+       .get_bandwidth     = mxl111sf_tuner_get_bandwidth,
+       .get_if_frequency  = mxl111sf_tuner_get_if_frequency,
+       .release           = mxl111sf_tuner_release,
+};
+
+struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
+                                          struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_tuner_config *cfg)
+{
+       struct mxl111sf_tuner_state *state = NULL;
+
+       mxl_dbg("()");
+
+       state = kzalloc(sizeof(struct mxl111sf_tuner_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       state->mxl_state = mxl_state;
+       state->cfg = cfg;
+
+       memcpy(&fe->ops.tuner_ops, &mxl111sf_tuner_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = state;
+       return fe;
+}
+EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach);
+
+MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf-tuner.h
new file mode 100644 (file)
index 0000000..ff33396
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  mxl111sf-tuner.h - driver for the MaxLinear MXL111SF CMOS tuner
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MXL111SF_TUNER_H__
+#define __MXL111SF_TUNER_H__
+
+#include "dvb_frontend.h"
+
+#include "mxl111sf.h"
+
+enum mxl_if_freq {
+#if 0
+       MXL_IF_LO    = 0x00, /* other IF < 9MHz */
+#endif
+       MXL_IF_4_0   = 0x01, /* 4.0   MHz */
+       MXL_IF_4_5   = 0x02, /* 4.5   MHz */
+       MXL_IF_4_57  = 0x03, /* 4.57  MHz */
+       MXL_IF_5_0   = 0x04, /* 5.0   MHz */
+       MXL_IF_5_38  = 0x05, /* 5.38  MHz */
+       MXL_IF_6_0   = 0x06, /* 6.0   MHz */
+       MXL_IF_6_28  = 0x07, /* 6.28  MHz */
+       MXL_IF_7_2   = 0x08, /* 7.2   MHz */
+       MXL_IF_35_25 = 0x09, /* 35.25 MHz */
+       MXL_IF_36    = 0x0a, /* 36    MHz */
+       MXL_IF_36_15 = 0x0b, /* 36.15 MHz */
+       MXL_IF_44    = 0x0c, /* 44    MHz */
+#if 0
+       MXL_IF_HI    = 0x0f, /* other IF > 35 MHz and < 45 MHz */
+#endif
+};
+
+struct mxl111sf_tuner_config {
+       enum mxl_if_freq if_freq;
+       unsigned int invert_spectrum:1;
+
+       int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
+       int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
+       int (*program_regs)(struct mxl111sf_state *state,
+                           struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
+       int (*top_master_ctrl)(struct mxl111sf_state *state, int onoff);
+       int (*ant_hunt)(struct dvb_frontend *fe);
+};
+
+/* ------------------------------------------------------------------------ */
+
+#if defined(CONFIG_DVB_USB_MXL111SF) || \
+       (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
+extern
+struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
+                                          struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_tuner_config *cfg);
+#else
+static inline
+struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
+                                          struct mxl111sf_state *mxl_state
+                                          struct mxl111sf_tuner_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __MXL111SF_TUNER_H__ */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf.c b/drivers/media/dvb/dvb-usb-v2/mxl111sf.c
new file mode 100644 (file)
index 0000000..1fb017e
--- /dev/null
@@ -0,0 +1,1463 @@
+/*
+ * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
+ *
+ *   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 <linux/vmalloc.h>
+#include <linux/i2c.h>
+
+#include "mxl111sf.h"
+#include "mxl111sf-reg.h"
+#include "mxl111sf-phy.h"
+#include "mxl111sf-i2c.h"
+#include "mxl111sf-gpio.h"
+
+#include "mxl111sf-demod.h"
+#include "mxl111sf-tuner.h"
+
+#include "lgdt3305.h"
+#include "lg2160.h"
+
+int dvb_usb_mxl111sf_debug;
+module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level "
+                "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
+
+int dvb_usb_mxl111sf_isoc;
+module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
+MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
+
+int dvb_usb_mxl111sf_spi;
+module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644);
+MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi).");
+
+#define ANT_PATH_AUTO 0
+#define ANT_PATH_EXTERNAL 1
+#define ANT_PATH_INTERNAL 2
+
+int dvb_usb_mxl111sf_rfswitch =
+#if 0
+               ANT_PATH_AUTO;
+#else
+               ANT_PATH_EXTERNAL;
+#endif
+
+module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
+MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define deb_info pr_debug
+#define deb_reg pr_debug
+#define deb_adv pr_debug
+#define err pr_err
+#define info pr_info
+
+int mxl111sf_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 */
+       int ret;
+       u8 sndbuf[1+wlen];
+
+       deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
+
+       memset(sndbuf, 0, 1+wlen);
+
+       sndbuf[0] = cmd;
+       memcpy(&sndbuf[1], wbuf, wlen);
+
+       ret = (wo) ? dvb_usbv2_generic_write(d, sndbuf, 1+wlen) :
+               dvb_usbv2_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#define MXL_CMD_REG_READ       0xaa
+#define MXL_CMD_REG_WRITE      0x55
+
+int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
+{
+       u8 buf[2];
+       int ret;
+
+       ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
+       if (mxl_fail(ret)) {
+               mxl_debug("error reading reg: 0x%02x", addr);
+               goto fail;
+       }
+
+       if (buf[0] == addr)
+               *data = buf[1];
+       else {
+               err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
+                   addr, buf[0], buf[1]);
+               ret = -EINVAL;
+       }
+
+       deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
+fail:
+       return ret;
+}
+
+int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
+{
+       u8 buf[] = { addr, data };
+       int ret;
+
+       deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
+
+       ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
+       if (mxl_fail(ret))
+               err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
+                                  u8 addr, u8 mask, u8 data)
+{
+       int ret;
+       u8 val;
+
+       if (mask != 0xff) {
+               ret = mxl111sf_read_reg(state, addr, &val);
+#if 1
+               /* dont know why this usually errors out on the first try */
+               if (mxl_fail(ret))
+                       err("error writing addr: 0x%02x, mask: 0x%02x, "
+                           "data: 0x%02x, retrying...", addr, mask, data);
+
+               ret = mxl111sf_read_reg(state, addr, &val);
+#endif
+               if (mxl_fail(ret))
+                       goto fail;
+       }
+       val &= ~mask;
+       val |= data;
+
+       ret = mxl111sf_write_reg(state, addr, val);
+       mxl_fail(ret);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
+                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
+{
+       int i, ret = 0;
+
+       for (i = 0;  ctrl_reg_info[i].addr |
+                    ctrl_reg_info[i].mask |
+                    ctrl_reg_info[i].data;  i++) {
+
+               ret = mxl111sf_write_reg_mask(state,
+                                             ctrl_reg_info[i].addr,
+                                             ctrl_reg_info[i].mask,
+                                             ctrl_reg_info[i].data);
+               if (mxl_fail(ret)) {
+                       err("failed on reg #%d (0x%02x)", i,
+                           ctrl_reg_info[i].addr);
+                       break;
+               }
+       }
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
+{
+       int ret;
+       u8 id, ver;
+       char *mxl_chip, *mxl_rev;
+
+       if ((state->chip_id) && (state->chip_ver))
+               return 0;
+
+       ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
+       if (mxl_fail(ret))
+               goto fail;
+       state->chip_id = id;
+
+       ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
+       if (mxl_fail(ret))
+               goto fail;
+       state->chip_ver = ver;
+
+       switch (id) {
+       case 0x61:
+               mxl_chip = "MxL101SF";
+               break;
+       case 0x63:
+               mxl_chip = "MxL111SF";
+               break;
+       default:
+               mxl_chip = "UNKNOWN MxL1X1";
+               break;
+       }
+       switch (ver) {
+       case 0x36:
+               state->chip_rev = MXL111SF_V6;
+               mxl_rev = "v6";
+               break;
+       case 0x08:
+               state->chip_rev = MXL111SF_V8_100;
+               mxl_rev = "v8_100";
+               break;
+       case 0x18:
+               state->chip_rev = MXL111SF_V8_200;
+               mxl_rev = "v8_200";
+               break;
+       default:
+               state->chip_rev = 0;
+               mxl_rev = "UNKNOWN REVISION";
+               break;
+       }
+       info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
+fail:
+       return ret;
+}
+
+#define get_chip_info(state)                                           \
+({                                                                     \
+       int ___ret;                                                     \
+       ___ret = mxl1x1sf_get_chip_info(state);                         \
+       if (mxl_fail(___ret)) {                                         \
+               mxl_debug("failed to get chip info"                     \
+                         " on first probe attempt");                   \
+               ___ret = mxl1x1sf_get_chip_info(state);                 \
+               if (mxl_fail(___ret))                                   \
+                       err("failed to get chip info during probe");    \
+               else                                                    \
+                       mxl_debug("probe needed a retry "               \
+                                 "in order to succeed.");              \
+       }                                                               \
+       ___ret;                                                         \
+})
+
+/* ------------------------------------------------------------------------ */
+#if 0
+static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       /* power control depends on which adapter is being woken:
+        * save this for init, instead, via mxl111sf_adap_fe_init */
+       return 0;
+}
+#endif
+
+static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
+{
+       struct dvb_usb_device *d = fe_to_d(fe);
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
+       int err;
+
+       /* exit if we didnt initialize the driver yet */
+       if (!state->chip_id) {
+               mxl_debug("driver not yet initialized, exit.");
+               goto fail;
+       }
+
+       deb_info("%s()\n", __func__);
+
+       mutex_lock(&state->fe_lock);
+
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       err = mxl1x1sf_soft_reset(state);
+       mxl_fail(err);
+       err = mxl111sf_init_tuner_demod(state);
+       mxl_fail(err);
+       err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+
+       mxl_fail(err);
+       mxl111sf_enable_usb_output(state);
+       mxl_fail(err);
+       mxl1x1sf_top_master_ctrl(state, 1);
+       mxl_fail(err);
+
+       if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
+           (state->chip_rev > MXL111SF_V6)) {
+               mxl111sf_config_pin_mux_modes(state,
+                                             PIN_MUX_TS_SPI_IN_MODE_1);
+               mxl_fail(err);
+       }
+       err = mxl111sf_init_port_expander(state);
+       if (!mxl_fail(err)) {
+               state->gpio_mode = adap_state->gpio_mode;
+               err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+               mxl_fail(err);
+#if 0
+               err = fe->ops.init(fe);
+#endif
+               msleep(100); /* add short delay after enabling
+                             * the demod before touching it */
+       }
+
+       return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
+fail:
+       return -ENODEV;
+}
+
+static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
+       int err;
+
+       /* exit if we didnt initialize the driver yet */
+       if (!state->chip_id) {
+               mxl_debug("driver not yet initialized, exit.");
+               goto fail;
+       }
+
+       deb_info("%s()\n", __func__);
+
+       err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
+
+       mutex_unlock(&state->fe_lock);
+
+       return err;
+fail:
+       return -ENODEV;
+}
+
+
+static int mxl111sf_ep6_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
+       int ret = 0;
+
+       deb_info("%s(%d)\n", __func__, onoff);
+
+       if (onoff) {
+               ret = mxl111sf_enable_usb_output(state);
+               mxl_fail(ret);
+               ret = mxl111sf_config_mpeg_in(state, 1, 1,
+                                             adap_state->ep6_clockphase,
+                                             0, 0);
+               mxl_fail(ret);
+#if 0
+       } else {
+               ret = mxl111sf_disable_656_port(state);
+               mxl_fail(ret);
+#endif
+       }
+
+       return ret;
+}
+
+static int mxl111sf_ep5_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       int ret = 0;
+
+       deb_info("%s(%d)\n", __func__, onoff);
+
+       if (onoff) {
+               ret = mxl111sf_enable_usb_output(state);
+               mxl_fail(ret);
+
+               ret = mxl111sf_init_i2s_port(state, 200);
+               mxl_fail(ret);
+               ret = mxl111sf_config_i2s(state, 0, 15);
+               mxl_fail(ret);
+       } else {
+               ret = mxl111sf_disable_i2s_port(state);
+               mxl_fail(ret);
+       }
+       if (state->chip_rev > MXL111SF_V6)
+               ret = mxl111sf_config_spi(state, onoff);
+       mxl_fail(ret);
+
+       return ret;
+}
+
+static int mxl111sf_ep4_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       int ret = 0;
+
+       deb_info("%s(%d)\n", __func__, onoff);
+
+       if (onoff) {
+               ret = mxl111sf_enable_usb_output(state);
+               mxl_fail(ret);
+       }
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct lgdt3305_config hauppauge_lgdt3305_config = {
+       .i2c_addr           = 0xb2 >> 1,
+       .mpeg_mode          = LGDT3305_MPEG_SERIAL,
+       .tpclk_edge         = LGDT3305_TPCLK_RISING_EDGE,
+       .tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .qam_if_khz         = 6000,
+       .vsb_if_khz         = 6000,
+};
+
+static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_TUNER_MODE;
+       adap_state->ep6_clockphase = 1;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_init_port_expander(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       adap->fe[fe_id] = dvb_attach(lgdt3305_attach,
+                                &hauppauge_lgdt3305_config,
+                                &d->i2c_adap);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static struct lg2160_config hauppauge_lg2160_config = {
+       .lg_chip            = LG2160,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+};
+
+static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_TUNER_MODE;
+       adap_state->ep6_clockphase = 1;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_init_port_expander(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = get_chip_info(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       adap->fe[fe_id] = dvb_attach(lg2160_attach,
+                             &hauppauge_lg2160_config,
+                             &d->i2c_adap);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static struct lg2160_config hauppauge_lg2161_1019_config = {
+       .lg_chip            = LG2161_1019,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+       .output_if          = 2, /* LG2161_OIF_SPI_MAS */
+};
+
+static struct lg2160_config hauppauge_lg2161_1040_config = {
+       .lg_chip            = LG2161_1040,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+       .output_if          = 4, /* LG2161_OIF_SPI_MAS */
+};
+
+static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_TUNER_MODE;
+       adap_state->ep6_clockphase = 1;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_init_port_expander(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = get_chip_info(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       adap->fe[fe_id] = dvb_attach(lg2160_attach,
+                             (MXL111SF_V8_200 == state->chip_rev) ?
+                             &hauppauge_lg2161_1040_config :
+                             &hauppauge_lg2161_1019_config,
+                             &d->i2c_adap);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static struct lg2160_config hauppauge_lg2161_1019_ep6_config = {
+       .lg_chip            = LG2161_1019,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+       .output_if          = 1, /* LG2161_OIF_SERIAL_TS */
+};
+
+static struct lg2160_config hauppauge_lg2161_1040_ep6_config = {
+       .lg_chip            = LG2161_1040,
+       .i2c_addr           = 0x1c >> 1,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 0,
+       .if_khz             = 6000,
+       .output_if          = 7, /* LG2161_OIF_SERIAL_TS */
+};
+
+static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_TUNER_MODE;
+       adap_state->ep6_clockphase = 0;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_init_port_expander(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = get_chip_info(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       adap->fe[fe_id] = dvb_attach(lg2160_attach,
+                             (MXL111SF_V8_200 == state->chip_rev) ?
+                             &hauppauge_lg2161_1040_ep6_config :
+                             &hauppauge_lg2161_1019_ep6_config,
+                             &d->i2c_adap);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static struct mxl111sf_demod_config mxl_demod_config = {
+       .read_reg        = mxl111sf_read_reg,
+       .write_reg       = mxl111sf_write_reg,
+       .program_regs    = mxl111sf_ctrl_program_regs,
+};
+
+static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct mxl111sf_state *state = d_to_priv(d);
+       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_SOC_MODE;
+       adap_state->ep6_clockphase = 1;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* dont care if this fails */
+       mxl111sf_init_port_expander(state);
+
+       adap->fe[fe_id] = dvb_attach(mxl111sf_demod_attach, state,
+                             &mxl_demod_config);
+       if (adap->fe[fe_id]) {
+               state->num_frontends++;
+               adap_state->fe_init = adap->fe[fe_id]->ops.init;
+               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
+static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
+                                       int antpath)
+{
+       return mxl111sf_idac_config(state, 1, 1,
+                                   (antpath == ANT_PATH_INTERNAL) ?
+                                   0x3f : 0x00, 0);
+}
+
+#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
+       err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
+           __func__, __LINE__, \
+           (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
+           pwr0, pwr1, pwr2, pwr3)
+
+#define ANT_HUNT_SLEEP 90
+#define ANT_EXT_TWEAK 0
+
+static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
+{
+       struct mxl111sf_state *state = fe_to_priv(fe);
+       int antctrl = dvb_usb_mxl111sf_rfswitch;
+
+       u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
+
+       /* FIXME: must force EXTERNAL for QAM - done elsewhere */
+       mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
+                             ANT_PATH_EXTERNAL : antctrl);
+
+       if (antctrl == ANT_PATH_AUTO) {
+#if 0
+               msleep(ANT_HUNT_SLEEP);
+#endif
+               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
+
+               mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
+               msleep(ANT_HUNT_SLEEP);
+               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
+
+               mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
+               msleep(ANT_HUNT_SLEEP);
+               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
+
+               mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
+               msleep(ANT_HUNT_SLEEP);
+               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
+
+               if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
+                       /* return with EXTERNAL enabled */
+                       mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
+                       DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
+                                  rxPwr0, rxPwr1, rxPwr2);
+               } else {
+                       /* return with INTERNAL enabled */
+                       DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
+                                  rxPwr0, rxPwr1, rxPwr2);
+               }
+       }
+       return 0;
+}
+
+static struct mxl111sf_tuner_config mxl_tuner_config = {
+       .if_freq         = MXL_IF_6_0, /* applies to external IF output, only */
+       .invert_spectrum = 0,
+       .read_reg        = mxl111sf_read_reg,
+       .write_reg       = mxl111sf_write_reg,
+       .program_regs    = mxl111sf_ctrl_program_regs,
+       .top_master_ctrl = mxl1x1sf_top_master_ctrl,
+       .ant_hunt        = mxl111sf_ant_hunt,
+};
+
+static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
+{
+       struct mxl111sf_state *state = adap_to_priv(adap);
+       int i;
+
+       deb_adv("%s()\n", __func__);
+
+       for (i = 0; i < state->num_frontends; i++) {
+               if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,
+                               &mxl_tuner_config) == NULL)
+                       return -EIO;
+       }
+
+       return 0;
+}
+
+static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe,
+                                     unsigned int cmd, void *parg,
+                                     unsigned int stage)
+{
+       int err = 0;
+
+       switch (stage) {
+       case DVB_FE_IOCTL_PRE:
+
+               switch (cmd) {
+               case FE_READ_SIGNAL_STRENGTH:
+                       err = fe->ops.tuner_ops.get_rf_strength(fe, parg);
+                       /* If no error occurs, prevent dvb-core from handling
+                        * this IOCTL, otherwise return the error */
+                       if (0 == err)
+                               err = 1;
+                       break;
+               }
+               break;
+
+       case DVB_FE_IOCTL_POST:
+               /* no post-ioctl handling required */
+               break;
+       }
+       return err;
+};
+
+static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm mxl111sf_i2c_algo = {
+       .master_xfer   = mxl111sf_i2c_xfer,
+       .functionality = mxl111sf_i2c_func,
+#ifdef NEED_ALGO_CONTROL
+       .algo_control = dummy_algo_control,
+#endif
+};
+
+static int mxl111sf_init(struct dvb_usb_device *d)
+{
+       struct mxl111sf_state *state = d_to_priv(d);
+       int ret;
+       static u8 eeprom[256];
+       struct i2c_client c;
+
+       ret = get_chip_info(state);
+       if (mxl_fail(ret))
+               err("failed to get chip info during probe");
+
+       mutex_init(&state->fe_lock);
+
+       if (state->chip_rev > MXL111SF_V6)
+               mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1);
+
+       c.adapter = &d->i2c_adap;
+       c.addr = 0xa0 >> 1;
+
+       ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
+       if (mxl_fail(ret))
+               return 0;
+       tveeprom_hauppauge_analog(&c, &state->tv, (0x84 == eeprom[0xa0]) ?
+                       eeprom + 0xa0 : eeprom + 0x80);
+#if 0
+       switch (state->tv.model) {
+       case 117001:
+       case 126001:
+       case 138001:
+               break;
+       default:
+               printk(KERN_WARNING "%s: warning: "
+                      "unknown hauppauge model #%d\n",
+                      __func__, state->tv.model);
+       }
+#endif
+       return 0;
+}
+
+static int mxl111sf_frontend_attach_dvbt(struct dvb_usb_adapter *adap)
+{
+       return mxl111sf_attach_demod(adap, 0);
+}
+
+static int mxl111sf_frontend_attach_atsc(struct dvb_usb_adapter *adap)
+{
+       return mxl111sf_lgdt3305_frontend_attach(adap, 0);
+}
+
+static int mxl111sf_frontend_attach_mh(struct dvb_usb_adapter *adap)
+{
+       return mxl111sf_lg2160_frontend_attach(adap, 0);
+}
+
+static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       deb_info("%s\n", __func__);
+
+       ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
+       if (ret < 0)
+               return ret;
+
+       ret = mxl111sf_attach_demod(adap, 1);
+       if (ret < 0)
+               return ret;
+
+       ret = mxl111sf_lg2160_frontend_attach(adap, 2);
+       if (ret < 0)
+               return ret;
+
+       return ret;
+}
+
+static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       deb_info("%s\n", __func__);
+
+       ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
+       if (ret < 0)
+               return ret;
+
+       ret = mxl111sf_attach_demod(adap, 1);
+       if (ret < 0)
+               return ret;
+
+       ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
+       if (ret < 0)
+               return ret;
+
+       return ret;
+}
+
+static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
+{
+       int ret;
+       deb_info("%s\n", __func__);
+
+       ret = mxl111sf_attach_demod(adap, 0);
+       if (ret < 0)
+               return ret;
+
+       if (dvb_usb_mxl111sf_spi)
+               ret = mxl111sf_lg2161_frontend_attach(adap, 1);
+       else
+               ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 1);
+
+       return ret;
+}
+
+static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)
+{
+       deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint);
+       stream->type = USB_BULK;
+       stream->count = 5;
+       stream->endpoint = endpoint;
+       stream->u.bulk.buffersize = 8192;
+}
+
+static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,
+               u8 endpoint, int framesperurb, int framesize)
+{
+       deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint,
+                       framesperurb * framesize);
+       stream->type = USB_ISOC;
+       stream->count = 5;
+       stream->endpoint = endpoint;
+       stream->u.isoc.framesperurb = framesperurb;
+       stream->u.isoc.framesize = framesize;
+       stream->u.isoc.interval = 1;
+}
+
+/* DVB USB Driver stuff */
+
+/* dvbt       mxl111sf
+ * bulk       EP4/BULK/5/8192
+ * isoc       EP4/ISOC/5/96/564
+ */
+static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       *ts_type = DVB_USB_FE_TS_TYPE_188;
+       if (dvb_usb_mxl111sf_isoc)
+               mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+       else
+               mxl111sf_stream_config_bulk(stream, 4);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_dvbt = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_dvbt,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_ep4_streaming_ctrl,
+       .get_stream_config = mxl111sf_get_stream_config_dvbt,
+       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* atsc       lgdt3305
+ * bulk       EP6/BULK/5/8192
+ * isoc       EP6/ISOC/5/24/3072
+ */
+static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       *ts_type = DVB_USB_FE_TS_TYPE_188;
+       if (dvb_usb_mxl111sf_isoc)
+               mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+       else
+               mxl111sf_stream_config_bulk(stream, 6);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_atsc = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_atsc,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_ep6_streaming_ctrl,
+       .get_stream_config = mxl111sf_get_stream_config_atsc,
+       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* mh         lg2160
+ * bulk       EP5/BULK/5/8192/RAW
+ * isoc       EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+       if (dvb_usb_mxl111sf_isoc)
+               mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+       else
+               mxl111sf_stream_config_bulk(stream, 5);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_mh = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_mh,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_ep5_streaming_ctrl,
+       .get_stream_config = mxl111sf_get_stream_config_mh,
+       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* atsc mh    lgdt3305           mxl111sf          lg2160
+ * bulk       EP6/BULK/5/8192    EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
+ * isoc       EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       if (fe->id == 0) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+               else
+                       mxl111sf_stream_config_bulk(stream, 6);
+       } else if (fe->id == 1) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+               else
+                       mxl111sf_stream_config_bulk(stream, 4);
+       } else if (fe->id == 2) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+               else
+                       mxl111sf_stream_config_bulk(stream, 5);
+       }
+       return 0;
+}
+
+static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)
+{
+       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+       if (fe->id == 0)
+               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+       else if (fe->id == 1)
+               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
+       else if (fe->id == 2)
+               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_atsc_mh = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_atsc_mh,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_streaming_ctrl_atsc_mh,
+       .get_stream_config = mxl111sf_get_stream_config_atsc_mh,
+       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* mercury    lgdt3305           mxl111sf          lg2161
+ * tp bulk    EP6/BULK/5/8192    EP4/BULK/5/8192   EP6/BULK/5/8192/RAW
+ * tp isoc    EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
+ * spi bulk   EP6/BULK/5/8192    EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
+ * spi isoc   EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       if (fe->id == 0) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+               else
+                       mxl111sf_stream_config_bulk(stream, 6);
+       } else if (fe->id == 1) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+               else
+                       mxl111sf_stream_config_bulk(stream, 4);
+       } else if (fe->id == 2 && dvb_usb_mxl111sf_spi) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+               else
+                       mxl111sf_stream_config_bulk(stream, 5);
+       } else if (fe->id == 2 && !dvb_usb_mxl111sf_spi) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+               else
+                       mxl111sf_stream_config_bulk(stream, 6);
+       }
+       return 0;
+}
+
+static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)
+{
+       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+       if (fe->id == 0)
+               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+       else if (fe->id == 1)
+               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
+       else if (fe->id == 2 && dvb_usb_mxl111sf_spi)
+               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
+       else if (fe->id == 2 && !dvb_usb_mxl111sf_spi)
+               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_mercury = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_mercury,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_streaming_ctrl_mercury,
+       .get_stream_config = mxl111sf_get_stream_config_mercury,
+       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+/* mercury mh mxl111sf          lg2161
+ * tp bulk    EP4/BULK/5/8192   EP6/BULK/5/8192/RAW
+ * tp isoc    EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
+ * spi bulk   EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
+ * spi isoc   EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,
+               u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+       deb_info("%s: fe=%d\n", __func__, fe->id);
+
+       if (fe->id == 0) {
+               *ts_type = DVB_USB_FE_TS_TYPE_188;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+               else
+                       mxl111sf_stream_config_bulk(stream, 4);
+       } else if (fe->id == 1 && dvb_usb_mxl111sf_spi) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+               else
+                       mxl111sf_stream_config_bulk(stream, 5);
+       } else if (fe->id == 1 && !dvb_usb_mxl111sf_spi) {
+               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+               if (dvb_usb_mxl111sf_isoc)
+                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+               else
+                       mxl111sf_stream_config_bulk(stream, 6);
+       }
+       return 0;
+}
+
+static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)
+{
+       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+       if (fe->id == 0)
+               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
+       else if (fe->id == 1  && dvb_usb_mxl111sf_spi)
+               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
+       else if (fe->id == 1 && !dvb_usb_mxl111sf_spi)
+               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+       return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_mercury_mh = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct mxl111sf_state),
+
+       .generic_bulk_ctrl_endpoint = 0x02,
+       .generic_bulk_ctrl_endpoint_response = 0x81,
+
+       .i2c_algo          = &mxl111sf_i2c_algo,
+       .frontend_attach   = mxl111sf_frontend_attach_mercury_mh,
+       .tuner_attach      = mxl111sf_attach_tuner,
+       .init              = mxl111sf_init,
+       .streaming_ctrl    = mxl111sf_streaming_ctrl_mercury_mh,
+       .get_stream_config = mxl111sf_get_stream_config_mercury_mh,
+       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+               }
+       }
+};
+
+static const struct usb_device_id mxl111sf_id_table[] = {
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702, &mxl111sf_props_mh, "HCW 117xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, mxl111sf_id_table);
+
+static struct usb_driver mxl111sf_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = mxl111sf_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(mxl111sf_usb_driver);
+
+MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
+MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/mxl111sf.h b/drivers/media/dvb/dvb-usb-v2/mxl111sf.h
new file mode 100644 (file)
index 0000000..9816de8
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
+ *
+ *   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_MXL111SF_H_
+#define _DVB_USB_MXL111SF_H_
+
+#ifdef DVB_USB_LOG_PREFIX
+#undef DVB_USB_LOG_PREFIX
+#endif
+#define DVB_USB_LOG_PREFIX "mxl111sf"
+#include "dvb_usb.h"
+#include <media/tveeprom.h>
+
+#define MXL_EP1_REG_READ     1
+#define MXL_EP2_REG_WRITE    2
+#define MXL_EP3_INTERRUPT    3
+#define MXL_EP4_MPEG2        4
+#define MXL_EP5_I2S          5
+#define MXL_EP6_656          6
+#define MXL_EP6_MPEG2        6
+
+#ifdef USING_ENUM_mxl111sf_current_mode
+enum mxl111sf_current_mode {
+       mxl_mode_dvbt = MXL_EP4_MPEG2,
+       mxl_mode_mh   = MXL_EP5_I2S,
+       mxl_mode_atsc = MXL_EP6_MPEG2,
+};
+#endif
+
+enum mxl111sf_gpio_port_expander {
+       mxl111sf_gpio_hw,
+       mxl111sf_PCA9534,
+};
+
+struct mxl111sf_adap_state {
+       int alt_mode;
+       int gpio_mode;
+       int device_mode;
+       int ep6_clockphase;
+       int (*fe_init)(struct dvb_frontend *);
+       int (*fe_sleep)(struct dvb_frontend *);
+};
+
+struct mxl111sf_state {
+       struct dvb_usb_device *d;
+
+       enum mxl111sf_gpio_port_expander gpio_port_expander;
+       u8 port_expander_addr;
+
+       u8 chip_id;
+       u8 chip_ver;
+#define MXL111SF_V6     1
+#define MXL111SF_V8_100 2
+#define MXL111SF_V8_200 3
+       u8 chip_rev;
+
+#ifdef USING_ENUM_mxl111sf_current_mode
+       enum mxl111sf_current_mode current_mode;
+#endif
+
+#define MXL_TUNER_MODE         0
+#define MXL_SOC_MODE           1
+#define MXL_DEV_MODE_MASK      0x01
+#if 1
+       int device_mode;
+#endif
+       /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t),
+                                    EP5 BULK transfer (atsc-mh),
+                                    EP6 BULK transfer (atsc/qam),
+          use usb alt setting 2 for EP4 BULK transfer (dvb-t),
+                                    EP5 ISOC transfer (atsc-mh),
+                                    EP6 ISOC transfer (atsc/qam),
+        */
+       int alt_mode;
+       int gpio_mode;
+       struct tveeprom tv;
+
+       struct mutex fe_lock;
+       u8 num_frontends;
+       struct mxl111sf_adap_state adap_state[3];
+};
+
+int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data);
+int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data);
+
+struct mxl111sf_reg_ctrl_info {
+       u8 addr;
+       u8 mask;
+       u8 data;
+};
+
+int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
+                           u8 addr, u8 mask, u8 data);
+int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
+                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
+
+/* needed for hardware i2c functions in mxl111sf-i2c.c:
+ * mxl111sf_i2c_send_data / mxl111sf_i2c_get_data */
+int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
+                     u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen);
+
+#define mxl_printk(kern, fmt, arg...) \
+       printk(kern "%s: " fmt "\n", __func__, ##arg)
+
+#define mxl_info(fmt, arg...) \
+       mxl_printk(KERN_INFO, fmt, ##arg)
+
+extern int dvb_usb_mxl111sf_debug;
+#define mxl_debug(fmt, arg...) \
+       if (dvb_usb_mxl111sf_debug) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+#define MXL_I2C_DBG 0x04
+#define MXL_ADV_DBG 0x10
+#define mxl_debug_adv(fmt, arg...) \
+       if (dvb_usb_mxl111sf_debug & MXL_ADV_DBG) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+#define mxl_i2c(fmt, arg...) \
+       if (dvb_usb_mxl111sf_debug & MXL_I2C_DBG) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+#define mxl_i2c_adv(fmt, arg...) \
+       if ((dvb_usb_mxl111sf_debug & (MXL_I2C_DBG | MXL_ADV_DBG)) == \
+               (MXL_I2C_DBG | MXL_ADV_DBG)) \
+                       mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+/* The following allows the mxl_fail() macro defined below to work
+ * in externel modules, such as mxl111sf-tuner.ko, even though
+ * dvb_usb_mxl111sf_debug is not defined within those modules */
+#if (defined(__MXL111SF_TUNER_H__)) || (defined(__MXL111SF_DEMOD_H__))
+#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG
+#else
+#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug
+#endif
+
+#define mxl_fail(ret)                                                  \
+({                                                                     \
+       int __ret;                                                      \
+       __ret = (ret < 0);                                              \
+       if ((__ret) && (MXL_ADV_DEBUG_ENABLED & MXL_ADV_DBG))           \
+               mxl_printk(KERN_ERR, "error %d on line %d",             \
+                          ret, __LINE__);                              \
+       __ret;                                                          \
+})
+
+#endif /* _DVB_USB_MXL111SF_H_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb-v2/usb_urb.c b/drivers/media/dvb/dvb-usb-v2/usb_urb.c
new file mode 100644 (file)
index 0000000..eaf673a
--- /dev/null
@@ -0,0 +1,357 @@
+/* usb-urb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file keeps functions for initializing and handling the
+ * BULK and ISOC USB data transfers in a generic way.
+ * Can be used for DVB-only and also, that's the plan, for
+ * Hybrid USB devices (analog and DVB).
+ */
+#include "dvb_usb_common.h"
+
+/* URB stuff for streaming */
+
+int usb_urb_reconfig(struct usb_data_stream *stream,
+               struct usb_data_stream_properties *props);
+
+static void usb_urb_complete(struct urb *urb)
+{
+       struct usb_data_stream *stream = urb->context;
+       int ptype = usb_pipetype(urb->pipe);
+       int i;
+       u8 *b;
+
+       dev_dbg(&stream->udev->dev, "%s: %s urb completed status=%d " \
+                       "length=%d/%d pack_num=%d errors=%d\n", __func__,
+                       ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
+                       urb->status, urb->actual_length,
+                       urb->transfer_buffer_length,
+                       urb->number_of_packets, urb->error_count);
+
+       switch (urb->status) {
+       case 0:         /* success */
+       case -ETIMEDOUT:    /* NAK */
+               break;
+       case -ECONNRESET:   /* kill */
+       case -ENOENT:
+       case -ESHUTDOWN:
+               return;
+       default:        /* error */
+               dev_dbg(&stream->udev->dev, "%s: urb completition failed=%d\n",
+                               __func__, urb->status);
+               break;
+       }
+
+       b = (u8 *) urb->transfer_buffer;
+       switch (ptype) {
+       case PIPE_ISOCHRONOUS:
+               for (i = 0; i < urb->number_of_packets; i++) {
+                       if (urb->iso_frame_desc[i].status != 0)
+                               dev_dbg(&stream->udev->dev, "%s: iso frame " \
+                                               "descriptor has an error=%d\n",
+                                               __func__,
+                                               urb->iso_frame_desc[i].status);
+                       else if (urb->iso_frame_desc[i].actual_length > 0)
+                               stream->complete(stream,
+                                       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;
+               }
+               break;
+       case PIPE_BULK:
+               if (urb->actual_length > 0)
+                       stream->complete(stream, b, urb->actual_length);
+               break;
+       default:
+               dev_err(&stream->udev->dev, "%s: unknown endpoint type in " \
+                               "completition handler\n", KBUILD_MODNAME);
+               return;
+       }
+       usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+int usb_urb_killv2(struct usb_data_stream *stream)
+{
+       int i;
+       for (i = 0; i < stream->urbs_submitted; i++) {
+               dev_dbg(&stream->udev->dev, "%s: kill urb=%d\n", __func__, i);
+               /* stop the URB */
+               usb_kill_urb(stream->urb_list[i]);
+       }
+       stream->urbs_submitted = 0;
+       return 0;
+}
+
+int usb_urb_submitv2(struct usb_data_stream *stream,
+               struct usb_data_stream_properties *props)
+{
+       int i, ret;
+
+       if (props) {
+               ret = usb_urb_reconfig(stream, props);
+               if (ret < 0)
+                       return ret;
+       }
+
+       for (i = 0; i < stream->urbs_initialized; i++) {
+               dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i);
+               ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC);
+               if (ret) {
+                       dev_err(&stream->udev->dev, "%s: could not submit " \
+                                       "urb no. %d - get them all back\n",
+                                       KBUILD_MODNAME, i);
+                       usb_urb_killv2(stream);
+                       return ret;
+               }
+               stream->urbs_submitted++;
+       }
+       return 0;
+}
+
+int usb_urb_free_urbs(struct usb_data_stream *stream)
+{
+       int i;
+
+       usb_urb_killv2(stream);
+
+       for (i = stream->urbs_initialized - 1; i >= 0; i--) {
+               if (stream->urb_list[i]) {
+                       dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
+                                       __func__, i);
+                       /* free the URBs */
+                       usb_free_urb(stream->urb_list[i]);
+               }
+       }
+       stream->urbs_initialized = 0;
+
+       return 0;
+}
+
+static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream)
+{
+       int i, j;
+
+       /* allocate the URBs */
+       for (i = 0; i < stream->props.count; i++) {
+               dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+               stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
+               if (!stream->urb_list[i]) {
+                       dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
+                       for (j = 0; j < i; j++)
+                               usb_free_urb(stream->urb_list[j]);
+                       return -ENOMEM;
+               }
+               usb_fill_bulk_urb(stream->urb_list[i],
+                               stream->udev,
+                               usb_rcvbulkpipe(stream->udev,
+                                               stream->props.endpoint),
+                               stream->buf_list[i],
+                               stream->props.u.bulk.buffersize,
+                               usb_urb_complete, stream);
+
+               stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+               stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
+               stream->urbs_initialized++;
+       }
+       return 0;
+}
+
+static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
+{
+       int i, j;
+
+       /* allocate the URBs */
+       for (i = 0; i < stream->props.count; i++) {
+               struct urb *urb;
+               int frame_offset = 0;
+               dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+               stream->urb_list[i] = usb_alloc_urb(
+                               stream->props.u.isoc.framesperurb, GFP_ATOMIC);
+               if (!stream->urb_list[i]) {
+                       dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
+                       for (j = 0; j < i; j++)
+                               usb_free_urb(stream->urb_list[j]);
+                       return -ENOMEM;
+               }
+
+               urb = stream->urb_list[i];
+
+               urb->dev = stream->udev;
+               urb->context = stream;
+               urb->complete = usb_urb_complete;
+               urb->pipe = usb_rcvisocpipe(stream->udev,
+                               stream->props.endpoint);
+               urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+               urb->interval = stream->props.u.isoc.interval;
+               urb->number_of_packets = stream->props.u.isoc.framesperurb;
+               urb->transfer_buffer_length = stream->props.u.isoc.framesize *
+                               stream->props.u.isoc.framesperurb;
+               urb->transfer_buffer = stream->buf_list[i];
+               urb->transfer_dma = stream->dma_addr[i];
+
+               for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
+                       urb->iso_frame_desc[j].offset = frame_offset;
+                       urb->iso_frame_desc[j].length =
+                                       stream->props.u.isoc.framesize;
+                       frame_offset += stream->props.u.isoc.framesize;
+               }
+
+               stream->urbs_initialized++;
+       }
+       return 0;
+}
+
+int usb_free_stream_buffers(struct usb_data_stream *stream)
+{
+       if (stream->state & USB_STATE_URB_BUF) {
+               while (stream->buf_num) {
+                       stream->buf_num--;
+                       dev_dbg(&stream->udev->dev, "%s: free buf=%d\n",
+                               __func__, stream->buf_num);
+                       usb_free_coherent(stream->udev, stream->buf_size,
+                                         stream->buf_list[stream->buf_num],
+                                         stream->dma_addr[stream->buf_num]);
+               }
+       }
+
+       stream->state &= ~USB_STATE_URB_BUF;
+
+       return 0;
+}
+
+int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
+               unsigned long size)
+{
+       stream->buf_num = 0;
+       stream->buf_size = size;
+
+       dev_dbg(&stream->udev->dev, "%s: all in all I will use %lu bytes for " \
+                       "streaming\n", __func__,  num * size);
+
+       for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
+               stream->buf_list[stream->buf_num] = usb_alloc_coherent(
+                               stream->udev, size, GFP_ATOMIC,
+                               &stream->dma_addr[stream->buf_num]);
+               if (!stream->buf_list[stream->buf_num]) {
+                       dev_dbg(&stream->udev->dev, "%s: alloc buf=%d failed\n",
+                                       __func__, stream->buf_num);
+                       usb_free_stream_buffers(stream);
+                       return -ENOMEM;
+               }
+
+               dev_dbg(&stream->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
+                               __func__, stream->buf_num,
+                               stream->buf_list[stream->buf_num],
+                               (long long)stream->dma_addr[stream->buf_num]);
+               memset(stream->buf_list[stream->buf_num], 0, size);
+               stream->state |= USB_STATE_URB_BUF;
+       }
+
+       return 0;
+}
+
+int usb_urb_reconfig(struct usb_data_stream *stream,
+               struct usb_data_stream_properties *props)
+{
+       int buf_size;
+
+       if (!props)
+               return 0;
+
+       /* check allocated buffers are large enough for the request */
+       if (props->type == USB_BULK) {
+               buf_size = stream->props.u.bulk.buffersize;
+       } else if (props->type == USB_ISOC) {
+               buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb;
+       } else {
+               dev_err(&stream->udev->dev, "%s: invalid endpoint type=%d\n",
+                               KBUILD_MODNAME, props->type);
+               return -EINVAL;
+       }
+
+       if (stream->buf_num < props->count || stream->buf_size < buf_size) {
+               dev_err(&stream->udev->dev, "%s: cannot reconfigure as " \
+                               "allocated buffers are too small\n",
+                               KBUILD_MODNAME);
+               return -EINVAL;
+       }
+
+       /* check if all fields are same */
+       if (stream->props.type == props->type &&
+                       stream->props.count == props->count &&
+                       stream->props.endpoint == props->endpoint) {
+               if (props->type == USB_BULK &&
+                               props->u.bulk.buffersize ==
+                               stream->props.u.bulk.buffersize)
+                       return 0;
+               else if (props->type == USB_ISOC &&
+                               props->u.isoc.framesperurb ==
+                               stream->props.u.isoc.framesperurb &&
+                               props->u.isoc.framesize ==
+                               stream->props.u.isoc.framesize &&
+                               props->u.isoc.interval ==
+                               stream->props.u.isoc.interval)
+                       return 0;
+       }
+
+       dev_dbg(&stream->udev->dev, "%s: re-alloc urbs\n", __func__);
+
+       usb_urb_free_urbs(stream);
+       memcpy(&stream->props, props, sizeof(*props));
+       if (props->type == USB_BULK)
+               return usb_urb_alloc_bulk_urbs(stream);
+       else if (props->type == USB_ISOC)
+               return usb_urb_alloc_isoc_urbs(stream);
+
+       return 0;
+}
+
+int usb_urb_initv2(struct usb_data_stream *stream,
+               const struct usb_data_stream_properties *props)
+{
+       int ret;
+
+       if (!stream || !props)
+               return -EINVAL;
+
+       memcpy(&stream->props, props, sizeof(*props));
+
+       if (!stream->complete) {
+               dev_err(&stream->udev->dev, "%s: there is no data callback - " \
+                               "this doesn't make sense\n", KBUILD_MODNAME);
+               return -EINVAL;
+       }
+
+       switch (stream->props.type) {
+       case USB_BULK:
+               ret = usb_alloc_stream_buffers(stream, stream->props.count,
+                               stream->props.u.bulk.buffersize);
+               if (ret < 0)
+                       return ret;
+
+               return usb_urb_alloc_bulk_urbs(stream);
+       case USB_ISOC:
+               ret = usb_alloc_stream_buffers(stream, stream->props.count,
+                               stream->props.u.isoc.framesize *
+                               stream->props.u.isoc.framesperurb);
+               if (ret < 0)
+                       return ret;
+
+               return usb_urb_alloc_isoc_urbs(stream);
+       default:
+               dev_err(&stream->udev->dev, "%s: unknown urb-type for data " \
+                               "transfer\n", KBUILD_MODNAME);
+               return -EINVAL;
+       }
+}
+
+int usb_urb_exitv2(struct usb_data_stream *stream)
+{
+       usb_urb_free_urbs(stream);
+       usb_free_stream_buffers(stream);
+
+       return 0;
+}
index 09fded4eb0b42334393e4289a7d57cb5e978b7da..67b91b74976f82afd7601f3190dd55f2bd8aa534 100644 (file)
@@ -13,25 +13,6 @@ config DVB_USB
 
          Say Y if you own a USB DVB device.
 
-config DVB_USB_V2
-       tristate "Support for various USB DVB devices v2"
-       depends on DVB_CORE && USB && I2C && RC_CORE
-       help
-         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
-         <file:Documentation/dvb/README.dvb-usb>.
-
-         For a complete list of supported USB devices see the LinuxTV DVB Wiki:
-         <http://www.linuxtv.org/wiki/index.php/DVB_USB>
-
-         Say Y if you own a USB DVB device.
-
-config DVB_USB_FIRMWARE
-       tristate "Firmware helper routines"
-       depends on DVB_USB
-
 config DVB_USB_DEBUG
        bool "Enable extended debug support for all DVB-USB devices"
        depends on DVB_USB
@@ -162,23 +143,6 @@ config DVB_USB_M920X
          "DTV USB MINI" (in cold state) are supported.
          Firmware required.
 
-config DVB_USB_GL861
-       tristate "Genesys Logic GL861 USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
-         receiver with USB ID 0db0:5581.
-
-config DVB_USB_AU6610
-       tristate "Alcor Micro AU6610 USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
-
 config DVB_USB_DIGITV
        tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
        depends on DVB_USB
@@ -318,23 +282,6 @@ config DVB_USB_CINERGY_T2
 
          Say Y if you own such a device and want to use it.
 
-config DVB_USB_ANYSEE
-       tristate "Anysee DVB-T/C USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_PLL if !DVB_FE_CUSTOMISE
-       select DVB_MT352 if !DVB_FE_CUSTOMISE
-       select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-       select DVB_TDA10023 if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
-       select DVB_CX24116 if !DVB_FE_CUSTOMISE
-       select DVB_STV0900 if !DVB_FE_CUSTOMISE
-       select DVB_STV6110 if !DVB_FE_CUSTOMISE
-       select DVB_ISL6423 if !DVB_FE_CUSTOMISE
-       select DVB_CXD2820R if !DVB_FE_CUSTOMISE
-       help
-         Say Y here to support the Anysee E30, Anysee E30 Plus or
-         Anysee E30 C Plus DVB USB2.0 receiver.
-
 config DVB_USB_DTV5100
        tristate "AME DTV-5100 USB2.0 DVB-T support"
        depends on DVB_USB
@@ -343,43 +290,12 @@ config DVB_USB_DTV5100
        help
          Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
 
-config DVB_USB_AF9015
-       tristate "Afatech AF9015 DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_AF9013
-       select DVB_PLL              if !DVB_FE_CUSTOMISE
-       select MEDIA_TUNER_MT2060   if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_QT1010   if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
-
-config DVB_USB_CE6230
-       tristate "Intel CE6230 DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_ZL10353
-       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
-
 config DVB_USB_FRIIO
        tristate "Friio ISDB-T USB2.0 Receiver support"
        depends on DVB_USB
        help
          Say Y here to support the Japanese DTV receiver Friio.
 
-config DVB_USB_EC168
-       tristate "E3C EC168 DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_EC100
-       select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
-
 config DVB_USB_AZ6007
        tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support"
        depends on DVB_USB
@@ -424,15 +340,6 @@ config DVB_USB_IT913X
        help
          Say Y here to support the it913x device
 
-config DVB_USB_MXL111SF
-       tristate "MxL111SF DTV USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
-       select DVB_LG2160 if !DVB_FE_CUSTOMISE
-       select VIDEO_TVEEPROM
-       help
-         Say Y here to support the MxL111SF USB2.0 DTV receiver.
-
 config DVB_USB_RTL28XXU
        tristate "Realtek RTL28xxU DVB USB support"
        depends on DVB_USB && EXPERIMENTAL
@@ -446,14 +353,3 @@ config DVB_USB_RTL28XXU
        help
          Say Y here to support the Realtek RTL28xxU DVB USB receiver.
 
-config DVB_USB_AF9035
-       tristate "Afatech AF9035 DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_AF9033
-       select MEDIA_TUNER_TUA9001 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_FC0011 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Afatech AF9035 based DVB USB receiver.
-
index 50f506e0632a0a9996c3a496d985bb151a74bfde..29fa0f0637e5479b626fd93296c1b0c056c0bb63 100644 (file)
@@ -1,11 +1,6 @@
 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 usb-urb.o
 obj-$(CONFIG_DVB_USB) += dvb-usb.o
 
-dvb_usbv2-objs = dvb_usb_core.o dvb_usb_urb.o usb_urb.o
-obj-$(CONFIG_DVB_USB_V2) += dvb_usbv2.o
-
-obj-$(CONFIG_DVB_USB_FIRMWARE) += dvb_usb_firmware.o
-
 dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
 obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
 
@@ -38,12 +33,6 @@ obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
 dvb-usb-m920x-objs = m920x.o
 obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o
 
-dvb-usb-gl861-objs = gl861.o
-obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o
-
-dvb-usb-au6610-objs = au6610.o
-obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o
-
 dvb-usb-digitv-objs = digitv.o
 obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
 
@@ -65,9 +54,6 @@ obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
 dvb-usb-af9005-remote-objs = af9005-remote.o
 obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
 
-dvb-usb-anysee-objs = anysee.o
-obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
-
 dvb-usb-pctv452e-objs = pctv452e.o
 obj-$(CONFIG_DVB_USB_PCTV452E) += dvb-usb-pctv452e.o
 
@@ -77,21 +63,12 @@ obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
 dvb-usb-dtv5100-objs = dtv5100.o
 obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
 
-dvb-usb-af9015-objs = af9015.o
-obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
-
 dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
 obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
 
-dvb-usb-ce6230-objs = ce6230.o
-obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
-
 dvb-usb-friio-objs = friio.o friio-fe.o
 obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
 
-dvb-usb-ec168-objs = ec168.o
-obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
-
 dvb-usb-az6007-objs = az6007.o
 obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o
 
@@ -107,17 +84,9 @@ obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
 dvb-usb-it913x-objs := it913x.o
 obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
 
-dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
-obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
-obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
-obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
-
 dvb-usb-rtl28xxu-objs = rtl28xxu.o
 obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
 
-dvb-usb-af9035-objs = af9035.o
-obj-$(CONFIG_DVB_USB_AF9035) += dvb-usb-af9035.o
-
 ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/
 # due to tuner-xc3028
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
deleted file mode 100644 (file)
index bbe1d33..0000000
+++ /dev/null
@@ -1,1426 +0,0 @@
-/*
- * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- *
- * Thanks to Afatech who kindly provided 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; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "af9015.h"
-
-static int dvb_usb_af9015_debug;
-module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
-static int dvb_usb_af9015_remote;
-module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
-MODULE_PARM_DESC(remote, "select remote");
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
-{
-#define BUF_LEN 63
-#define REQ_HDR_LEN 8 /* send header size */
-#define ACK_HDR_LEN 2 /* rece header size */
-       struct af9015_state *state = d_to_priv(d);
-       int ret, wlen, rlen;
-       u8 buf[BUF_LEN];
-       u8 write = 1;
-
-       buf[0] = req->cmd;
-       buf[1] = state->seq++;
-       buf[2] = req->i2c_addr;
-       buf[3] = req->addr >> 8;
-       buf[4] = req->addr & 0xff;
-       buf[5] = req->mbox;
-       buf[6] = req->addr_len;
-       buf[7] = req->data_len;
-
-       switch (req->cmd) {
-       case GET_CONFIG:
-       case READ_MEMORY:
-       case RECONNECT_USB:
-               write = 0;
-               break;
-       case READ_I2C:
-               write = 0;
-               buf[2] |= 0x01; /* set I2C direction */
-       case WRITE_I2C:
-               buf[0] = READ_WRITE_I2C;
-               break;
-       case WRITE_MEMORY:
-               if (((req->addr & 0xff00) == 0xff00) ||
-                   ((req->addr & 0xff00) == 0xae00))
-                       buf[0] = WRITE_VIRTUAL_MEMORY;
-       case WRITE_VIRTUAL_MEMORY:
-       case COPY_FIRMWARE:
-       case DOWNLOAD_FIRMWARE:
-       case BOOT:
-               break;
-       default:
-               err("unknown command:%d", req->cmd);
-               ret = -1;
-               goto error;
-       }
-
-       /* buffer overflow check */
-       if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
-               (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
-               err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       /* write receives seq + status = 2 bytes
-          read receives seq + status + data = 2 + N bytes */
-       wlen = REQ_HDR_LEN;
-       rlen = ACK_HDR_LEN;
-       if (write) {
-               wlen += req->data_len;
-               memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
-       } else {
-               rlen += req->data_len;
-       }
-
-       /* no ack for these packets */
-       if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
-               rlen = 0;
-
-       ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
-       if (ret)
-               goto error;
-
-       /* check status */
-       if (rlen && buf[1]) {
-               err("command failed:%d", buf[1]);
-               ret = -1;
-               goto error;
-       }
-
-       /* read request, copy returned data to return buf */
-       if (!write)
-               memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
-error:
-       return ret;
-}
-
-static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
-       u8 len)
-{
-       struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
-               val};
-       return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
-{
-       struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
-               val};
-       return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
-{
-       return af9015_write_regs(d, addr, &val, 1);
-}
-
-static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
-{
-       return af9015_read_regs(d, addr, val, 1);
-}
-
-static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
-       u8 val)
-{
-       struct af9015_state *state = d_to_priv(d);
-       struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
-
-       if (addr == state->af9013_config[0].i2c_addr ||
-           addr == state->af9013_config[1].i2c_addr)
-               req.addr_len = 3;
-
-       return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
-       u8 *val)
-{
-       struct af9015_state *state = d_to_priv(d);
-       struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
-
-       if (addr == state->af9013_config[0].i2c_addr ||
-           addr == state->af9013_config[1].i2c_addr)
-               req.addr_len = 3;
-
-       return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
-{
-       int ret;
-       u8 val, mask = 0x01;
-
-       ret = af9015_read_reg(d, addr, &val);
-       if (ret)
-               return ret;
-
-       mask <<= bit;
-       if (op) {
-               /* set bit */
-               val |= mask;
-       } else {
-               /* clear bit */
-               mask ^= 0xff;
-               val &= mask;
-       }
-
-       return af9015_write_reg(d, addr, val);
-}
-
-static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
-{
-       return af9015_do_reg_bit(d, addr, bit, 1);
-}
-
-static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
-{
-       return af9015_do_reg_bit(d, addr, bit, 0);
-}
-
-static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-       int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct af9015_state *state = d_to_priv(d);
-       int ret = 0, i = 0;
-       u16 addr;
-       u8 uninitialized_var(mbox), addr_len;
-       struct req_t req;
-
-/*
-The bus lock is needed because there is two tuners both using same I2C-address.
-Due to that the only way to select correct tuner is use demodulator I2C-gate.
-
-................................................
-. AF9015 includes integrated AF9013 demodulator.
-. ____________                   ____________  .                ____________
-.|     uC     |                 |   demod    | .               |    tuner   |
-.|------------|                 |------------| .               |------------|
-.|   AF9015   |                 |  AF9013/5  | .               |   MXL5003  |
-.|            |--+----I2C-------|-----/ -----|-.-----I2C-------|            |
-.|            |  |              | addr 0x38  | .               |  addr 0xc6 |
-.|____________|  |              |____________| .               |____________|
-.................|..............................
-                |               ____________                   ____________
-                |              |   demod    |                 |    tuner   |
-                |              |------------|                 |------------|
-                |              |   AF9013   |                 |   MXL5003  |
-                +----I2C-------|-----/ -----|-------I2C-------|            |
-                               | addr 0x3a  |                 |  addr 0xc6 |
-                               |____________|                 |____________|
-*/
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       while (i < num) {
-               if (msg[i].addr == state->af9013_config[0].i2c_addr ||
-                   msg[i].addr == state->af9013_config[1].i2c_addr) {
-                       addr = msg[i].buf[0] << 8;
-                       addr += msg[i].buf[1];
-                       mbox = msg[i].buf[2];
-                       addr_len = 3;
-               } else {
-                       addr = msg[i].buf[0];
-                       addr_len = 1;
-                       /* mbox is don't care in that case */
-               }
-
-               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-                       if (msg[i].len > 3 || msg[i+1].len > 61) {
-                               ret = -EOPNOTSUPP;
-                               goto error;
-                       }
-                       if (msg[i].addr == state->af9013_config[0].i2c_addr)
-                               req.cmd = READ_MEMORY;
-                       else
-                               req.cmd = READ_I2C;
-                       req.i2c_addr = msg[i].addr;
-                       req.addr = addr;
-                       req.mbox = mbox;
-                       req.addr_len = addr_len;
-                       req.data_len = msg[i+1].len;
-                       req.data = &msg[i+1].buf[0];
-                       ret = af9015_ctrl_msg(d, &req);
-                       i += 2;
-               } else if (msg[i].flags & I2C_M_RD) {
-                       if (msg[i].len > 61) {
-                               ret = -EOPNOTSUPP;
-                               goto error;
-                       }
-                       if (msg[i].addr == state->af9013_config[0].i2c_addr) {
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       req.cmd = READ_I2C;
-                       req.i2c_addr = msg[i].addr;
-                       req.addr = addr;
-                       req.mbox = mbox;
-                       req.addr_len = addr_len;
-                       req.data_len = msg[i].len;
-                       req.data = &msg[i].buf[0];
-                       ret = af9015_ctrl_msg(d, &req);
-                       i += 1;
-               } else {
-                       if (msg[i].len > 21) {
-                               ret = -EOPNOTSUPP;
-                               goto error;
-                       }
-                       if (msg[i].addr == state->af9013_config[0].i2c_addr)
-                               req.cmd = WRITE_MEMORY;
-                       else
-                               req.cmd = WRITE_I2C;
-                       req.i2c_addr = msg[i].addr;
-                       req.addr = addr;
-                       req.mbox = mbox;
-                       req.addr_len = addr_len;
-                       req.data_len = msg[i].len-addr_len;
-                       req.data = &msg[i].buf[addr_len];
-                       ret = af9015_ctrl_msg(d, &req);
-                       i += 1;
-               }
-               if (ret)
-                       goto error;
-
-       }
-       ret = i;
-
-error:
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static u32 af9015_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm af9015_i2c_algo = {
-       .master_xfer = af9015_i2c_xfer,
-       .functionality = af9015_i2c_func,
-};
-
-static int af9015_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       int ret;
-       u8 reply;
-       struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
-
-       ret = af9015_ctrl_msg(d, &req);
-       if (ret)
-               return ret;
-
-       deb_info("%s: reply:%02x\n", __func__, reply);
-       if (reply == 0x02)
-               ret = WARM;
-       else
-               ret = COLD;
-
-       return ret;
-}
-
-static int af9015_download_firmware(struct dvb_usb_device *d,
-       const struct firmware *fw)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int i, len, remaining, ret;
-       struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
-       u16 checksum = 0;
-
-       deb_info("%s:\n", __func__);
-
-       /* calc checksum */
-       for (i = 0; i < fw->size; i++)
-               checksum += fw->data[i];
-
-       state->firmware_size = fw->size;
-       state->firmware_checksum = checksum;
-
-       #define FW_ADDR 0x5100 /* firmware start address */
-       #define LEN_MAX 55 /* max packet size */
-       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
-               len = remaining;
-               if (len > LEN_MAX)
-                       len = LEN_MAX;
-
-               req.data_len = len;
-               req.data = (u8 *) &fw->data[fw->size - remaining];
-               req.addr = FW_ADDR + fw->size - remaining;
-
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret) {
-                       err("firmware download failed:%d", ret);
-                       goto error;
-               }
-       }
-
-       /* firmware loaded, request boot */
-       req.cmd = BOOT;
-       req.data_len = 0;
-       ret = af9015_ctrl_msg(d, &req);
-       if (ret) {
-               err("firmware boot failed:%d", ret);
-               goto error;
-       }
-
-error:
-       return ret;
-}
-
-/* hash (and dump) eeprom */
-static int af9015_eeprom_hash(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       static const unsigned int eeprom_size = 256;
-       unsigned int reg;
-       u8 val, *eeprom;
-       struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
-
-       eeprom = kmalloc(eeprom_size, GFP_KERNEL);
-       if (eeprom == NULL)
-               return -ENOMEM;
-
-       for (reg = 0; reg < eeprom_size; reg++) {
-               req.addr = reg;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto free;
-
-               eeprom[reg] = val;
-       }
-
-       if (dvb_usb_af9015_debug & 0x01)
-               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
-                               eeprom_size);
-
-       BUG_ON(eeprom_size % 4);
-
-       state->eeprom_sum = 0;
-       for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
-               state->eeprom_sum *= GOLDEN_RATIO_PRIME_32;
-               state->eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
-       }
-
-       deb_info("%s: eeprom sum=%.8x\n", __func__, state->eeprom_sum);
-
-       ret = 0;
-free:
-       kfree(eeprom);
-       return ret;
-}
-
-static int af9015_read_config(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       u8 val, i, offset = 0;
-       struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
-
-       deb_info("%s:\n", __func__);
-
-       /* IR remote controller */
-       req.addr = AF9015_EEPROM_IR_MODE;
-       /* first message will timeout often due to possible hw bug */
-       for (i = 0; i < 4; i++) {
-               ret = af9015_ctrl_msg(d, &req);
-               if (!ret)
-                       break;
-       }
-       if (ret)
-               goto error;
-
-       ret = af9015_eeprom_hash(d);
-       if (ret)
-               goto error;
-
-       deb_info("%s: IR mode=%d\n", __func__, val);
-       state->ir_mode = val;
-
-       /* TS mode - one or two receivers */
-       req.addr = AF9015_EEPROM_TS_MODE;
-       ret = af9015_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       state->dual_mode = val;
-       deb_info("%s: TS mode=%d\n", __func__, state->dual_mode);
-
-       /* disable 2nd adapter because we don't have PID-filters */
-       if (d->udev->speed == USB_SPEED_FULL)
-               state->dual_mode = 0;
-
-       if (state->dual_mode) {
-               /* read 2nd demodulator I2C address */
-               req.addr = AF9015_EEPROM_DEMOD2_I2C;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-
-               state->af9013_config[1].i2c_addr = val;
-       }
-
-       for (i = 0; i < state->dual_mode + 1; i++) {
-               if (i == 1)
-                       offset = AF9015_EEPROM_OFFSET;
-               /* xtal */
-               req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-               switch (val) {
-               case 0:
-                       state->af9013_config[i].clock = 28800000;
-                       break;
-               case 1:
-                       state->af9013_config[i].clock = 20480000;
-                       break;
-               case 2:
-                       state->af9013_config[i].clock = 28000000;
-                       break;
-               case 3:
-                       state->af9013_config[i].clock = 25000000;
-                       break;
-               };
-               deb_info("%s: [%d] xtal=%d set clock=%d\n", __func__, i,
-                               val, state->af9013_config[i].clock);
-
-               /* IF frequency */
-               req.addr = AF9015_EEPROM_IF1H + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-
-               state->af9013_config[i].if_frequency = val << 8;
-
-               req.addr = AF9015_EEPROM_IF1L + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-
-               state->af9013_config[i].if_frequency += val;
-               state->af9013_config[i].if_frequency *= 1000;
-               deb_info("%s: [%d] IF frequency=%d\n", __func__, i,
-                               state->af9013_config[i].if_frequency);
-
-               /* MT2060 IF1 */
-               req.addr = AF9015_EEPROM_MT2060_IF1H  + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-               state->mt2060_if1[i] = val << 8;
-               req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-               state->mt2060_if1[i] += val;
-               deb_info("%s: [%d] MT2060 IF1=%d\n", __func__, i,
-                               state->mt2060_if1[i]);
-
-               /* tuner */
-               req.addr =  AF9015_EEPROM_TUNER_ID1 + offset;
-               ret = af9015_ctrl_msg(d, &req);
-               if (ret)
-                       goto error;
-               switch (val) {
-               case AF9013_TUNER_ENV77H11D5:
-               case AF9013_TUNER_MT2060:
-               case AF9013_TUNER_QT1010:
-               case AF9013_TUNER_UNKNOWN:
-               case AF9013_TUNER_MT2060_2:
-               case AF9013_TUNER_TDA18271:
-               case AF9013_TUNER_QT1010A:
-               case AF9013_TUNER_TDA18218:
-                       state->af9013_config[i].spec_inv = 1;
-                       break;
-               case AF9013_TUNER_MXL5003D:
-               case AF9013_TUNER_MXL5005D:
-               case AF9013_TUNER_MXL5005R:
-               case AF9013_TUNER_MXL5007T:
-                       state->af9013_config[i].spec_inv = 0;
-                       break;
-               case AF9013_TUNER_MC44S803:
-                       state->af9013_config[i].gpio[1] = AF9013_GPIO_LO;
-                       state->af9013_config[i].spec_inv = 1;
-                       break;
-               default:
-                       warn("tuner id=%d not supported, please report!", val);
-                       return -ENODEV;
-               };
-
-               state->af9013_config[i].tuner = val;
-               deb_info("%s: [%d] tuner id=%d\n", __func__, i, val);
-       }
-
-error:
-       if (ret)
-               err("eeprom read failed=%d", ret);
-
-       /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
-          content :-( Override some wrong values here. Ditto for the
-          AVerTV Red HD+ (A850T) device. */
-       if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
-               ((le16_to_cpu(d->udev->descriptor.idProduct) ==
-                       USB_PID_AVERMEDIA_A850) ||
-               (le16_to_cpu(d->udev->descriptor.idProduct) ==
-                       USB_PID_AVERMEDIA_A850T))) {
-               deb_info("%s: AverMedia A850: overriding config\n", __func__);
-               /* disable dual mode */
-               state->dual_mode = 0;
-
-               /* set correct IF */
-               state->af9013_config[0].if_frequency = 4570000;
-       }
-
-       return ret;
-}
-
-static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
-               struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: adap=%d\n", __func__, fe_to_adap(fe)->id);
-
-       if (fe_to_d(fe)->udev->speed == USB_SPEED_FULL)
-               stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE;
-
-       return 0;
-}
-
-static int af9015_get_adapter_count(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       return state->dual_mode + 1;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_set_frontend(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->set_frontend[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_read_status(struct dvb_frontend *fe,
-       fe_status_t *status)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->read_status[fe_to_adap(fe)->id](fe, status);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_init(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->init[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->sleep[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override tuner callbacks for resource locking */
-static int af9015_tuner_init(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->tuner_init[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-/* override tuner callbacks for resource locking */
-static int af9015_tuner_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-       struct af9015_state *state = fe_to_priv(fe);
-
-       if (mutex_lock_interruptible(&state->fe_mutex))
-               return -EAGAIN;
-
-       ret = state->tuner_sleep[fe_to_adap(fe)->id](fe);
-
-       mutex_unlock(&state->fe_mutex);
-
-       return ret;
-}
-
-static int af9015_copy_firmware(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       u8 fw_params[4];
-       u8 val, i;
-       struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
-               fw_params };
-       deb_info("%s:\n", __func__);
-
-       fw_params[0] = state->firmware_size >> 8;
-       fw_params[1] = state->firmware_size & 0xff;
-       fw_params[2] = state->firmware_checksum >> 8;
-       fw_params[3] = state->firmware_checksum & 0xff;
-
-       /* wait 2nd demodulator ready */
-       msleep(100);
-
-       ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
-                       0x98be, &val);
-       if (ret)
-               goto error;
-       else
-               deb_info("%s: firmware status:%02x\n", __func__, val);
-
-       if (val == 0x0c) /* fw is running, no need for download */
-               goto exit;
-
-       /* set I2C master clock to fast (to speed up firmware copy) */
-       ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
-       if (ret)
-               goto error;
-
-       msleep(50);
-
-       /* copy firmware */
-       ret = af9015_ctrl_msg(d, &req);
-       if (ret)
-               err("firmware copy cmd failed:%d", ret);
-       deb_info("%s: firmware copy done\n", __func__);
-
-       /* set I2C master clock back to normal */
-       ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
-       if (ret)
-               goto error;
-
-       /* request boot firmware */
-       ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr,
-                       0xe205, 1);
-       deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
-       if (ret)
-               goto error;
-
-       for (i = 0; i < 15; i++) {
-               msleep(100);
-
-               /* check firmware status */
-               ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
-                               0x98be, &val);
-               deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
-                       __func__, ret, val);
-               if (ret)
-                       goto error;
-
-               if (val == 0x0c || val == 0x04) /* success or fail */
-                       break;
-       }
-
-       if (val == 0x04) {
-               err("firmware did not run");
-               ret = -1;
-       } else if (val != 0x0c) {
-               err("firmware boot timeout");
-               ret = -1;
-       }
-
-error:
-exit:
-       return ret;
-}
-
-static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       struct af9015_state *state = adap_to_priv(adap);
-
-       if (adap->id == 0) {
-               state->af9013_config[0].ts_mode = AF9013_TS_USB;
-               memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4);
-               state->af9013_config[0].gpio[0] = AF9013_GPIO_HI;
-               state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON;
-       } else if (adap->id == 1) {
-               state->af9013_config[1].ts_mode = AF9013_TS_SERIAL;
-               memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4);
-               state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON;
-               state->af9013_config[1].gpio[1] = AF9013_GPIO_LO;
-
-               /* copy firmware to 2nd demodulator */
-               if (state->dual_mode) {
-                       ret = af9015_copy_firmware(adap_to_d(adap));
-                       if (ret) {
-                               err("firmware copy to 2nd frontend " \
-                                       "failed, will disable it");
-                               state->dual_mode = 0;
-                               return -ENODEV;
-                       }
-               } else {
-                       return -ENODEV;
-               }
-       }
-
-       /* attach demodulator */
-       adap->fe[0] = dvb_attach(af9013_attach,
-               &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap);
-
-       /*
-        * AF9015 firmware does not like if it gets interrupted by I2C adapter
-        * request on some critical phases. During normal operation I2C adapter
-        * is used only 2nd demodulator and tuner on dual tuner devices.
-        * Override demodulator callbacks and use mutex for limit access to
-        * those "critical" paths to keep AF9015 happy.
-        */
-       if (adap->fe[0]) {
-               state->set_frontend[adap->id] =
-                       adap->fe[0]->ops.set_frontend;
-               adap->fe[0]->ops.set_frontend =
-                       af9015_af9013_set_frontend;
-
-               state->read_status[adap->id] =
-                       adap->fe[0]->ops.read_status;
-               adap->fe[0]->ops.read_status =
-                       af9015_af9013_read_status;
-
-               state->init[adap->id] = adap->fe[0]->ops.init;
-               adap->fe[0]->ops.init = af9015_af9013_init;
-
-               state->sleep[adap->id] = adap->fe[0]->ops.sleep;
-               adap->fe[0]->ops.sleep = af9015_af9013_sleep;
-       }
-
-       return adap->fe[0] == NULL ? -ENODEV : 0;
-}
-
-static struct mt2060_config af9015_mt2060_config = {
-       .i2c_address = 0xc0,
-       .clock_out = 0,
-};
-
-static struct qt1010_config af9015_qt1010_config = {
-       .i2c_address = 0xc4,
-};
-
-static struct tda18271_config af9015_tda18271_config = {
-       .gate = TDA18271_GATE_DIGITAL,
-       .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
-};
-
-static struct mxl5005s_config af9015_mxl5003_config = {
-       .i2c_address     = 0xc6,
-       .if_freq         = IF_FREQ_4570000HZ,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_DEFAULT,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static struct mxl5005s_config af9015_mxl5005_config = {
-       .i2c_address     = 0xc6,
-       .if_freq         = IF_FREQ_4570000HZ,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_OFF,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static struct mc44s803_config af9015_mc44s803_config = {
-       .i2c_address = 0xc0,
-       .dig_out = 1,
-};
-
-static struct tda18218_config af9015_tda18218_config = {
-       .i2c_address = 0xc0,
-       .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
-};
-
-static struct mxl5007t_config af9015_mxl5007t_config = {
-       .xtal_freq_hz = MxL_XTAL_24_MHZ,
-       .if_freq_hz = MxL_IF_4_57_MHZ,
-};
-
-static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct af9015_state *state = adap_to_priv(adap);
-       int ret;
-       deb_info("%s:\n", __func__);
-
-       switch (state->af9013_config[adap->id].tuner) {
-       case AF9013_TUNER_MT2060:
-       case AF9013_TUNER_MT2060_2:
-               ret = dvb_attach(mt2060_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config,
-                       state->mt2060_if1[adap->id])
-                       == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_QT1010:
-       case AF9013_TUNER_QT1010A:
-               ret = dvb_attach(qt1010_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_qt1010_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_TDA18271:
-               ret = dvb_attach(tda18271_attach, adap->fe[0], 0xc0,
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_tda18271_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_TDA18218:
-               ret = dvb_attach(tda18218_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_tda18218_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_MXL5003D:
-               ret = dvb_attach(mxl5005s_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_MXL5005D:
-       case AF9013_TUNER_MXL5005R:
-               ret = dvb_attach(mxl5005s_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_ENV77H11D5:
-               ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0xc0,
-                       &adap_to_d(adap)->i2c_adap,
-                       DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_MC44S803:
-               ret = dvb_attach(mc44s803_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_MXL5007T:
-               ret = dvb_attach(mxl5007t_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
-               break;
-       case AF9013_TUNER_UNKNOWN:
-       default:
-               ret = -ENODEV;
-               err("Unknown tuner id:%d",
-                       state->af9013_config[adap->id].tuner);
-       }
-
-       if (adap->fe[0]->ops.tuner_ops.init) {
-               state->tuner_init[adap->id] =
-                       adap->fe[0]->ops.tuner_ops.init;
-               adap->fe[0]->ops.tuner_ops.init = af9015_tuner_init;
-       }
-
-       if (adap->fe[0]->ops.tuner_ops.sleep) {
-               state->tuner_sleep[adap->id] =
-                       adap->fe[0]->ops.tuner_ops.sleep;
-               adap->fe[0]->ops.tuner_ops.sleep = af9015_tuner_sleep;
-       }
-
-       return ret;
-}
-
-static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       int ret;
-       deb_info("%s: onoff:%d\n", __func__, onoff);
-
-       if (onoff)
-               ret = af9015_set_reg_bit(adap_to_d(adap), 0xd503, 0);
-       else
-               ret = af9015_clear_reg_bit(adap_to_d(adap), 0xd503, 0);
-
-       return ret;
-}
-
-static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
-       int onoff)
-{
-       int ret;
-       u8 idx;
-
-       deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
-               __func__, index, pid, onoff);
-
-       ret = af9015_write_reg(adap_to_d(adap), 0xd505, (pid & 0xff));
-       if (ret)
-               goto error;
-
-       ret = af9015_write_reg(adap_to_d(adap), 0xd506, (pid >> 8));
-       if (ret)
-               goto error;
-
-       idx = ((index & 0x1f) | (1 << 5));
-       ret = af9015_write_reg(adap_to_d(adap), 0xd504, idx);
-
-error:
-       return ret;
-}
-
-static int af9015_init_endpoint(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       u16 frame_size;
-       u8  packet_size;
-       deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
-
-       if (d->udev->speed == USB_SPEED_FULL) {
-               frame_size = TS_USB11_FRAME_SIZE/4;
-               packet_size = TS_USB11_MAX_PACKET_SIZE/4;
-       } else {
-               frame_size = TS_USB20_FRAME_SIZE/4;
-               packet_size = TS_USB20_MAX_PACKET_SIZE/4;
-       }
-
-       ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
-       if (ret)
-               goto error;
-       ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
-       if (ret)
-               goto error;
-       ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
-       if (ret)
-               goto error;
-       ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
-       if (ret)
-               goto error;
-       ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
-       if (ret)
-               goto error;
-       if (state->dual_mode) {
-               ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
-               if (ret)
-                       goto error;
-       }
-       ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
-       if (ret)
-               goto error;
-       if (state->dual_mode) {
-               ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
-               if (ret)
-                       goto error;
-       }
-       /* EP4 xfer length */
-       ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
-       if (ret)
-               goto error;
-       ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
-       if (ret)
-               goto error;
-       /* EP5 xfer length */
-       ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
-       if (ret)
-               goto error;
-       ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
-       if (ret)
-               goto error;
-       ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
-       if (ret)
-               goto error;
-       ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
-       if (ret)
-               goto error;
-       ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
-       if (ret)
-               goto error;
-       if (state->dual_mode) {
-               ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
-               if (ret)
-                       goto error;
-       }
-
-       /* enable / disable mp2if2 */
-       if (state->dual_mode)
-               ret = af9015_set_reg_bit(d, 0xd50b, 0);
-       else
-               ret = af9015_clear_reg_bit(d, 0xd50b, 0);
-
-error:
-       if (ret)
-               err("endpoint init failed:%d", ret);
-       return ret;
-}
-
-static int af9015_init(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       deb_info("%s:\n", __func__);
-
-       mutex_init(&state->fe_mutex);
-
-       /* init RC canary */
-       ret = af9015_write_reg(d, 0x98e9, 0xff);
-       if (ret)
-               goto error;
-
-       ret = af9015_init_endpoint(d);
-       if (ret)
-               goto error;
-
-error:
-       return ret;
-}
-
-struct af9015_rc_setup {
-       unsigned int id;
-       char *rc_codes;
-};
-
-static char *af9015_rc_setup_match(unsigned int id,
-       const struct af9015_rc_setup *table)
-{
-       for (; table->rc_codes; table++)
-               if (table->id == id)
-                       return table->rc_codes;
-       return NULL;
-}
-
-static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
-       { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
-       { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
-       { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
-       { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
-       { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
-       { }
-};
-
-static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
-       { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
-       { 0xa3703d00, RC_MAP_ALINK_DTU_M },
-       { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
-       { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */
-       { }
-};
-
-static int af9015_rc_query(struct dvb_usb_device *d)
-{
-       struct af9015_state *state = d_to_priv(d);
-       int ret;
-       u8 buf[17];
-
-       deb_info("%s:\n", __func__);
-
-       /* read registers needed to detect remote controller code */
-       ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       /* If any of these are non-zero, assume invalid data */
-       if (buf[1] || buf[2] || buf[3])
-               return ret;
-
-       /* Check for repeat of previous code */
-       if ((state->rc_repeat != buf[6] || buf[0]) &&
-                       !memcmp(&buf[12], state->rc_last, 4)) {
-               deb_rc("%s: key repeated\n", __func__);
-               rc_keydown(d->rc_dev, state->rc_keycode, 0);
-               state->rc_repeat = buf[6];
-               return ret;
-       }
-
-       /* Only process key if canary killed */
-       if (buf[16] != 0xff && buf[0] != 0x01) {
-               deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
-                       buf[12], buf[13], buf[14], buf[15]);
-
-               /* Reset the canary */
-               ret = af9015_write_reg(d, 0x98e9, 0xff);
-               if (ret)
-                       goto error;
-
-               /* Remember this key */
-               memcpy(state->rc_last, &buf[12], 4);
-               if (buf[14] == (u8) ~buf[15]) {
-                       if (buf[12] == (u8) ~buf[13]) {
-                               /* NEC */
-                               state->rc_keycode = buf[12] << 8 | buf[14];
-                       } else {
-                               /* NEC extended*/
-                               state->rc_keycode = buf[12] << 16 |
-                                       buf[13] << 8 | buf[14];
-                       }
-               } else {
-                       /* 32 bit NEC */
-                       state->rc_keycode = buf[12] << 24 | buf[13] << 16 |
-                                       buf[14] << 8 | buf[15];
-               }
-               rc_keydown(d->rc_dev, state->rc_keycode, 0);
-       } else {
-               deb_rc("%s: no key press\n", __func__);
-               /* Invalidate last keypress */
-               /* Not really needed, but helps with debug */
-               state->rc_last[2] = state->rc_last[3];
-       }
-
-       state->rc_repeat = buf[6];
-
-error:
-       if (ret)
-               err("%s: failed:%d", __func__, ret);
-
-       return ret;
-}
-
-static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
-{
-       struct af9015_state *state = d_to_priv(d);
-       u16 vid = le16_to_cpu(d->udev->descriptor.idVendor);
-
-       if (state->ir_mode == AF9015_IR_MODE_DISABLED)
-               return 0;
-
-       /* try to load remote based module param */
-       rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote,
-                       af9015_rc_setup_modparam);
-
-       /* try to load remote based eeprom hash */
-       if (!rc->map_name)
-               rc->map_name = af9015_rc_setup_match(state->eeprom_sum,
-                               af9015_rc_setup_hashes);
-
-       /* try to load remote based USB iManufacturer string */
-       if (!rc->map_name && vid == USB_VID_AFATECH) {
-               /* Check USB manufacturer and product strings and try
-                  to determine correct remote in case of chip vendor
-                  reference IDs are used.
-                  DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
-               char manufacturer[10];
-               memset(manufacturer, 0, sizeof(manufacturer));
-               usb_string(d->udev, d->udev->descriptor.iManufacturer,
-                       manufacturer, sizeof(manufacturer));
-               if (!strcmp("MSI", manufacturer)) {
-                       /* iManufacturer 1 MSI
-                          iProduct      2 MSI K-VOX */
-                       rc->map_name = af9015_rc_setup_match(
-                                       AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
-                                       af9015_rc_setup_modparam);
-               }
-       }
-
-       /* load empty to enable rc */
-       if (!rc->map_name)
-               rc->map_name = RC_MAP_EMPTY;
-
-       rc->allowed_protos = RC_TYPE_NEC;
-       rc->query = af9015_rc_query;
-       rc->interval = 500;
-
-       return 0;
-}
-
-/* interface 0 is used by DVB-T receiver and
-   interface 1 is for remote controller (HID) */
-static struct dvb_usb_device_properties af9015_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct af9015_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .identify_state = af9015_identify_state,
-       .firmware = "dvb-usb-af9015.fw",
-       .download_firmware = af9015_download_firmware,
-
-       .i2c_algo = &af9015_i2c_algo,
-       .read_config = af9015_read_config,
-       .frontend_attach = af9015_af9013_frontend_attach,
-       .tuner_attach = af9015_tuner_attach,
-       .init = af9015_init,
-       .get_rc_config = af9015_get_rc_config,
-       .get_stream_config = af9015_get_stream_config,
-
-       .get_adapter_count = af9015_get_adapter_count,
-       .adapter = {
-               {
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER |
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 32,
-                       .pid_filter = af9015_pid_filter,
-                       .pid_filter_ctrl = af9015_pid_filter_ctrl,
-
-                       .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE),
-               }, {
-                       .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE),
-               },
-       },
-};
-
-static const struct usb_device_id af9015_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015,
-               &af9015_props, "Afatech AF9015 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016,
-               &af9015_props, "Afatech AF9015 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD,
-               &af9015_props, "Leadtek WinFast DTV Dongle Gold", RC_MAP_LEADTEK_Y04G0051) },
-       { DVB_USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E,
-               &af9015_props, "Pinnacle PCTV 71e", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U,
-               &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN,
-               &af9015_props, "DigitalNow TinyTwin", RC_MAP_AZUREWAVE_AD_TU700) },
-       { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700,
-               &af9015_props, "TwinHan AzureWave AD-TU700(704J)", RC_MAP_AZUREWAVE_AD_TU700) },
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2,
-               &af9015_props, "TerraTec Cinergy T USB XE", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T,
-               &af9015_props, "KWorld PlusTV Dual DVB-T PCI (DVB-T PC160-2T)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X,
-               &af9015_props, "AVerMedia AVerTV DVB-T Volar X", RC_MAP_AVERMEDIA_M135A) },
-       { DVB_USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380,
-               &af9015_props, "Xtensions XD-380", NULL) },
-       { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO,
-               &af9015_props, "MSI DIGIVOX Duo", RC_MAP_MSI_DIGIVOX_III) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2,
-               &af9015_props, "Fujitsu-Siemens Slim Mobile USB DVB-T", NULL) },
-       { DVB_USB_DEVICE(USB_VID_TELESTAR,  USB_PID_TELESTAR_STARSTICK_2,
-               &af9015_props, "Telestar Starstick 2", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309,
-               &af9015_props, "AVerMedia A309", NULL) },
-       { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III,
-               &af9015_props, "MSI Digi VOX mini III", RC_MAP_MSI_DIGIVOX_III) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U,
-               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2,
-               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3,
-               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT,
-               &af9015_props, "TrekStor DVB-T USB Stick", RC_MAP_TREKSTOR) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850,
-               &af9015_props, "AverMedia AVerTV Volar Black HD (A850)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805,
-               &af9015_props, "AverMedia AVerTV Volar GPS 805 (A805)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU,
-               &af9015_props, "Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810,
-               &af9015_props, "KWorld Digial MC-810", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03,
-               &af9015_props, "Genius TVGo DVB-T03", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2,
-               &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T,
-               &af9015_props, "KWorld PlusTV DVB-T PCI Pro Card (DVB-T PC160-T)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20,
-               &af9015_props, "Sveon STV20 Tuner USB DVB-T HDTV", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2,
-               &af9015_props, "DigitalNow TinyTwin v2", RC_MAP_DIGITALNOW_TINYTWIN) },
-       { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS,
-               &af9015_props, "Leadtek WinFast DTV2000DS", RC_MAP_LEADTEK_Y04G0051) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T,
-               &af9015_props, "KWorld USB DVB-T Stick Mobile (UB383-T)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4,
-               &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M,
-               &af9015_props, "AverMedia AVerTV Volar M (A815Mac)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC,
-               &af9015_props, "TerraTec Cinergy T Stick RC", RC_MAP_TERRATEC_SLIM_2) },
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
-               &af9015_props, "TerraTec Cinergy T Stick Dual RC", RC_MAP_TERRATEC_SLIM) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T,
-               &af9015_props, "AverMedia AVerTV Red HD+ (A850T)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3,
-               &af9015_props, "DigitalNow TinyTwin v3", RC_MAP_DIGITALNOW_TINYTWIN) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22,
-               &af9015_props, "Sveon STV22 Dual USB DVB-T Tuner HDTV", RC_MAP_MSI_DIGIVOX_III) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, af9015_id_table);
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver af9015_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = af9015_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(af9015_usb_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Afatech AF9015 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
deleted file mode 100644 (file)
index b41ee73..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- *
- * Thanks to Afatech who kindly provided 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; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef AF9015_H
-#define AF9015_H
-
-#include <linux/hash.h>
-#include "dvb_usb.h"
-#include "af9013.h"
-#include "dvb-pll.h"
-#include "mt2060.h"
-#include "qt1010.h"
-#include "tda18271.h"
-#include "mxl5005s.h"
-#include "mc44s803.h"
-#include "tda18218.h"
-#include "mxl5007t.h"
-
-#define DVB_USB_LOG_PREFIX "af9015"
-
-#ifdef CONFIG_DVB_USB_DEBUG
-#define dprintk(var, level, args...) \
-       do { if ((var & level)) printk(args); } while (0)
-#define DVB_USB_DEBUG_STATUS
-#else
-#define dprintk(args...)
-#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
-#endif
-
-#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
-#define deb_rc(args...)   dprintk(dvb_usb_af9015_debug, 0x02, args)
-
-#undef err
-#define err(format, arg...) \
-       printk(KERN_ERR     DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-#undef warn
-#define warn(format, arg...) \
-       printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
-
-/* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
-   We use smaller - about 1/4 from the original, 5 and 87. */
-#define TS_PACKET_SIZE            188
-
-#define TS_USB20_PACKET_COUNT      87
-#define TS_USB20_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
-
-#define TS_USB11_PACKET_COUNT       5
-#define TS_USB11_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
-
-#define TS_USB20_MAX_PACKET_SIZE  512
-#define TS_USB11_MAX_PACKET_SIZE   64
-
-#define AF9015_I2C_EEPROM  0xa0
-#define AF9015_I2C_DEMOD   0x38
-#define AF9015_USB_TIMEOUT 2000
-
-/* EEPROM locations */
-#define AF9015_EEPROM_IR_MODE        0x18
-#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34
-#define AF9015_EEPROM_TS_MODE        0x31
-#define AF9015_EEPROM_DEMOD2_I2C     0x32
-
-#define AF9015_EEPROM_SAW_BW1        0x35
-#define AF9015_EEPROM_XTAL_TYPE1     0x36
-#define AF9015_EEPROM_SPEC_INV1      0x37
-#define AF9015_EEPROM_IF1L           0x38
-#define AF9015_EEPROM_IF1H           0x39
-#define AF9015_EEPROM_MT2060_IF1L    0x3a
-#define AF9015_EEPROM_MT2060_IF1H    0x3b
-#define AF9015_EEPROM_TUNER_ID1      0x3c
-
-#define AF9015_EEPROM_SAW_BW2        0x45
-#define AF9015_EEPROM_XTAL_TYPE2     0x46
-#define AF9015_EEPROM_SPEC_INV2      0x47
-#define AF9015_EEPROM_IF2L           0x48
-#define AF9015_EEPROM_IF2H           0x49
-#define AF9015_EEPROM_MT2060_IF2L    0x4a
-#define AF9015_EEPROM_MT2060_IF2H    0x4b
-#define AF9015_EEPROM_TUNER_ID2      0x4c
-
-#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
-
-struct req_t {
-       u8  cmd;       /* [0] */
-       /*  seq */     /* [1] */
-       u8  i2c_addr;  /* [2] */
-       u16 addr;      /* [3|4] */
-       u8  mbox;      /* [5] */
-       u8  addr_len;  /* [6] */
-       u8  data_len;  /* [7] */
-       u8  *data;
-};
-
-enum af9015_cmd {
-       GET_CONFIG           = 0x10,
-       DOWNLOAD_FIRMWARE    = 0x11,
-       BOOT                 = 0x13,
-       READ_MEMORY          = 0x20,
-       WRITE_MEMORY         = 0x21,
-       READ_WRITE_I2C       = 0x22,
-       COPY_FIRMWARE        = 0x23,
-       RECONNECT_USB        = 0x5a,
-       WRITE_VIRTUAL_MEMORY = 0x26,
-       GET_IR_CODE          = 0x27,
-       READ_I2C,
-       WRITE_I2C,
-};
-
-enum af9015_ir_mode {
-       AF9015_IR_MODE_DISABLED = 0,
-       AF9015_IR_MODE_HID,
-       AF9015_IR_MODE_RLC,
-       AF9015_IR_MODE_RC6,
-       AF9015_IR_MODE_POLLING, /* just guess */
-};
-
-struct af9015_state {
-       u8 ir_mode;
-       u8 rc_repeat;
-       u32 rc_keycode;
-       u8 rc_last[4];
-       u8 dual_mode;
-       u8 seq; /* packet sequence number */
-       u16 mt2060_if1[2];
-       u16 firmware_size;
-       u16 firmware_checksum;
-       u32 eeprom_sum;
-       struct af9013_config af9013_config[2];
-
-       /* for demod callback override */
-       int (*set_frontend[2]) (struct dvb_frontend *fe);
-       int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status);
-       int (*init[2]) (struct dvb_frontend *fe);
-       int (*sleep[2]) (struct dvb_frontend *fe);
-       int (*tuner_init[2]) (struct dvb_frontend *fe);
-       int (*tuner_sleep[2]) (struct dvb_frontend *fe);
-       struct mutex fe_mutex;
-};
-
-enum af9015_remote {
-       AF9015_REMOTE_NONE                    = 0,
-/* 1 */        AF9015_REMOTE_A_LINK_DTU_M,
-       AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
-       AF9015_REMOTE_MYGICTV_U718,
-       AF9015_REMOTE_DIGITTRADE_DVB_T,
-/* 5 */        AF9015_REMOTE_AVERMEDIA_KS,
-};
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/af9035.c b/drivers/media/dvb/dvb-usb/af9035.c
deleted file mode 100644 (file)
index 79197f4..0000000
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
- * Afatech AF9035 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License along
- *    with this program; if not, write to the Free Software Foundation, Inc.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "af9035.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static u16 af9035_checksum(const u8 *buf, size_t len)
-{
-       size_t i;
-       u16 checksum = 0;
-
-       for (i = 1; i < len; i++) {
-               if (i % 2)
-                       checksum += buf[i] << 8;
-               else
-                       checksum += buf[i];
-       }
-       checksum = ~checksum;
-
-       return checksum;
-}
-
-static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
-{
-#define BUF_LEN 64
-#define REQ_HDR_LEN 4 /* send header size */
-#define ACK_HDR_LEN 3 /* rece header size */
-#define CHECKSUM_LEN 2
-#define USB_TIMEOUT 2000
-       struct state *state = d_to_priv(d);
-       int ret, wlen, rlen;
-       u8 buf[BUF_LEN];
-       u16 checksum, tmp_checksum;
-
-       /* buffer overflow check */
-       if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
-               req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
-               pr_debug("%s: too much data wlen=%d rlen=%d\n", __func__,
-                               req->wlen, req->rlen);
-               return -EINVAL;
-       }
-
-       buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1;
-       buf[1] = req->mbox;
-       buf[2] = req->cmd;
-       buf[3] = state->seq++;
-       memcpy(&buf[REQ_HDR_LEN], req->wbuf, req->wlen);
-
-       wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN;
-       rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN;
-
-       /* calc and add checksum */
-       checksum = af9035_checksum(buf, buf[0] - 1);
-       buf[buf[0] - 1] = (checksum >> 8);
-       buf[buf[0] - 0] = (checksum & 0xff);
-
-       /* no ack for these packets */
-       if (req->cmd == CMD_FW_DL)
-               rlen = 0;
-
-       ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
-       if (ret)
-               goto err;
-
-       /* no ack for those packets */
-       if (req->cmd == CMD_FW_DL)
-               goto exit;
-
-       /* verify checksum */
-       checksum = af9035_checksum(buf, rlen - 2);
-       tmp_checksum = (buf[rlen - 2] << 8) | buf[rlen - 1];
-       if (tmp_checksum != checksum) {
-               pr_err("%s: command=%02x checksum mismatch (%04x != %04x)\n",
-                               KBUILD_MODNAME, req->cmd, tmp_checksum,
-                               checksum);
-               ret = -EIO;
-               goto err;
-       }
-
-       /* check status */
-       if (buf[2]) {
-               pr_debug("%s: command=%02x failed fw error=%d\n", __func__,
-                               req->cmd, buf[2]);
-               ret = -EIO;
-               goto err;
-       }
-
-       /* read request, copy returned data to return buf */
-       if (req->rlen)
-               memcpy(req->rbuf, &buf[ACK_HDR_LEN], req->rlen);
-
-exit:
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-/* write multiple registers */
-static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
-{
-       u8 wbuf[6 + len];
-       u8 mbox = (reg >> 16) & 0xff;
-       struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL };
-
-       wbuf[0] = len;
-       wbuf[1] = 2;
-       wbuf[2] = 0;
-       wbuf[3] = 0;
-       wbuf[4] = (reg >> 8) & 0xff;
-       wbuf[5] = (reg >> 0) & 0xff;
-       memcpy(&wbuf[6], val, len);
-
-       return af9035_ctrl_msg(d, &req);
-}
-
-/* read multiple registers */
-static int af9035_rd_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
-{
-       u8 wbuf[] = { len, 2, 0, 0, (reg >> 8) & 0xff, reg & 0xff };
-       u8 mbox = (reg >> 16) & 0xff;
-       struct usb_req req = { CMD_MEM_RD, mbox, sizeof(wbuf), wbuf, len, val };
-
-       return af9035_ctrl_msg(d, &req);
-}
-
-/* write single register */
-static int af9035_wr_reg(struct dvb_usb_device *d, u32 reg, u8 val)
-{
-       return af9035_wr_regs(d, reg, &val, 1);
-}
-
-/* read single register */
-static int af9035_rd_reg(struct dvb_usb_device *d, u32 reg, u8 *val)
-{
-       return af9035_rd_regs(d, reg, val, 1);
-}
-
-/* write single register with mask */
-static int af9035_wr_reg_mask(struct dvb_usb_device *d, u32 reg, u8 val,
-               u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = af9035_rd_regs(d, reg, &tmp, 1);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return af9035_wr_regs(d, reg, &val, 1);
-}
-
-static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
-               struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct state *state = d_to_priv(d);
-       int ret;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       /*
-        * I2C sub header is 5 bytes long. Meaning of those bytes are:
-        * 0: data len
-        * 1: I2C addr << 1
-        * 2: reg addr len
-        *    byte 3 and 4 can be used as reg addr
-        * 3: reg addr MSB
-        *    used when reg addr len is set to 2
-        * 4: reg addr LSB
-        *    used when reg addr len is set to 1 or 2
-        *
-        * For the simplify we do not use register addr at all.
-        * NOTE: As a firmware knows tuner type there is very small possibility
-        * there could be some tuner I2C hacks done by firmware and this may
-        * lead problems if firmware expects those bytes are used.
-        */
-       if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
-                       (msg[1].flags & I2C_M_RD)) {
-               if (msg[0].len > 40 || msg[1].len > 40) {
-                       /* TODO: correct limits > 40 */
-                       ret = -EOPNOTSUPP;
-               } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
-                       /* integrated demod */
-                       u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
-                                       msg[0].buf[2];
-                       ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
-                                       msg[1].len);
-               } else {
-                       /* I2C */
-                       u8 buf[5 + msg[0].len];
-                       struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
-                                       buf, msg[1].len, msg[1].buf };
-                       buf[0] = msg[1].len;
-                       buf[1] = msg[0].addr << 1;
-                       buf[2] = 0x00; /* reg addr len */
-                       buf[3] = 0x00; /* reg addr MSB */
-                       buf[4] = 0x00; /* reg addr LSB */
-                       memcpy(&buf[5], msg[0].buf, msg[0].len);
-                       ret = af9035_ctrl_msg(d, &req);
-               }
-       } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
-               if (msg[0].len > 40) {
-                       /* TODO: correct limits > 40 */
-                       ret = -EOPNOTSUPP;
-               } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
-                       /* integrated demod */
-                       u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
-                                       msg[0].buf[2];
-                       ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
-                                       msg[0].len - 3);
-               } else {
-                       /* I2C */
-                       u8 buf[5 + msg[0].len];
-                       struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf,
-                                       0, NULL };
-                       buf[0] = msg[0].len;
-                       buf[1] = msg[0].addr << 1;
-                       buf[2] = 0x00; /* reg addr len */
-                       buf[3] = 0x00; /* reg addr MSB */
-                       buf[4] = 0x00; /* reg addr LSB */
-                       memcpy(&buf[5], msg[0].buf, msg[0].len);
-                       ret = af9035_ctrl_msg(d, &req);
-               }
-       } else {
-               /*
-                * We support only two kind of I2C transactions:
-                * 1) 1 x read + 1 x write
-                * 2) 1 x write
-                */
-               ret = -EOPNOTSUPP;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       if (ret < 0)
-               return ret;
-       else
-               return num;
-}
-
-static u32 af9035_i2c_functionality(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm af9035_i2c_algo = {
-       .master_xfer = af9035_i2c_master_xfer,
-       .functionality = af9035_i2c_functionality,
-};
-
-static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       int ret;
-       u8 wbuf[1] = { 1 };
-       u8 rbuf[4];
-       struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf,
-                       sizeof(rbuf), rbuf };
-
-       ret = af9035_ctrl_msg(d, &req);
-       if (ret < 0)
-               goto err;
-
-       pr_debug("%s: reply=%02x %02x %02x %02x\n", __func__,
-               rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
-       if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
-               ret = WARM;
-       else
-               ret = COLD;
-
-       return ret;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_download_firmware(struct dvb_usb_device *d,
-               const struct firmware *fw)
-{
-       int ret, i, j, len;
-       u8 wbuf[1];
-       u8 rbuf[4];
-       struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
-       struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL };
-       struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
-       u8 hdr_core;
-       u16 hdr_addr, hdr_data_len, hdr_checksum;
-       #define MAX_DATA 58
-       #define HDR_SIZE 7
-
-       /*
-        * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info!
-        *
-        * byte 0: MCS 51 core
-        *  There are two inside the AF9035 (1=Link and 2=OFDM) with separate
-        *  address spaces
-        * byte 1-2: Big endian destination address
-        * byte 3-4: Big endian number of data bytes following the header
-        * byte 5-6: Big endian header checksum, apparently ignored by the chip
-        *  Calculated as ~(h[0]*256+h[1]+h[2]*256+h[3]+h[4]*256)
-        */
-
-       for (i = fw->size; i > HDR_SIZE;) {
-               hdr_core = fw->data[fw->size - i + 0];
-               hdr_addr = fw->data[fw->size - i + 1] << 8;
-               hdr_addr |= fw->data[fw->size - i + 2] << 0;
-               hdr_data_len = fw->data[fw->size - i + 3] << 8;
-               hdr_data_len |= fw->data[fw->size - i + 4] << 0;
-               hdr_checksum = fw->data[fw->size - i + 5] << 8;
-               hdr_checksum |= fw->data[fw->size - i + 6] << 0;
-
-               pr_debug("%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
-                               __func__, hdr_core, hdr_addr, hdr_data_len,
-                               hdr_checksum);
-
-               if (((hdr_core != 1) && (hdr_core != 2)) ||
-                               (hdr_data_len > i)) {
-                       pr_debug("%s: bad firmware\n", __func__);
-                       break;
-               }
-
-               /* download begin packet */
-               req.cmd = CMD_FW_DL_BEGIN;
-               ret = af9035_ctrl_msg(d, &req);
-               if (ret < 0)
-                       goto err;
-
-               /* download firmware packet(s) */
-               for (j = HDR_SIZE + hdr_data_len; j > 0; j -= MAX_DATA) {
-                       len = j;
-                       if (len > MAX_DATA)
-                               len = MAX_DATA;
-                       req_fw_dl.wlen = len;
-                       req_fw_dl.wbuf = (u8 *) &fw->data[fw->size - i +
-                                       HDR_SIZE + hdr_data_len - j];
-                       ret = af9035_ctrl_msg(d, &req_fw_dl);
-                       if (ret < 0)
-                               goto err;
-               }
-
-               /* download end packet */
-               req.cmd = CMD_FW_DL_END;
-               ret = af9035_ctrl_msg(d, &req);
-               if (ret < 0)
-                       goto err;
-
-               i -= hdr_data_len + HDR_SIZE;
-
-               pr_debug("%s: data uploaded=%zu\n", __func__, fw->size - i);
-       }
-
-       /* firmware loaded, request boot */
-       req.cmd = CMD_FW_BOOT;
-       ret = af9035_ctrl_msg(d, &req);
-       if (ret < 0)
-               goto err;
-
-       /* ensure firmware starts */
-       wbuf[0] = 1;
-       ret = af9035_ctrl_msg(d, &req_fw_ver);
-       if (ret < 0)
-               goto err;
-
-       if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
-               pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
-               ret = -ENODEV;
-               goto err;
-       }
-
-       pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
-                       rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_download_firmware_it9135(struct dvb_usb_device *d,
-               const struct firmware *fw)
-{
-       int ret, i, i_prev;
-       u8 wbuf[1];
-       u8 rbuf[4];
-       struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
-       struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL };
-       struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
-       #define HDR_SIZE 7
-
-       /*
-        * There seems to be following firmware header. Meaning of bytes 0-3
-        * is unknown.
-        *
-        * 0: 3
-        * 1: 0, 1
-        * 2: 0
-        * 3: 1, 2, 3
-        * 4: addr MSB
-        * 5: addr LSB
-        * 6: count of data bytes ?
-        */
-
-       for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) {
-               if (i == fw->size ||
-                               (fw->data[i + 0] == 0x03 &&
-                               (fw->data[i + 1] == 0x00 ||
-                               fw->data[i + 1] == 0x01) &&
-                               fw->data[i + 2] == 0x00)) {
-                       req_fw_dl.wlen = i - i_prev;
-                       req_fw_dl.wbuf = (u8 *) &fw->data[i_prev];
-                       i_prev = i;
-                       ret = af9035_ctrl_msg(d, &req_fw_dl);
-                       if (ret < 0)
-                               goto err;
-
-                       pr_debug("%s: data uploaded=%d\n", __func__, i);
-               }
-       }
-
-       /* firmware loaded, request boot */
-       req.cmd = CMD_FW_BOOT;
-       ret = af9035_ctrl_msg(d, &req);
-       if (ret < 0)
-               goto err;
-
-       /* ensure firmware starts */
-       wbuf[0] = 1;
-       ret = af9035_ctrl_msg(d, &req_fw_ver);
-       if (ret < 0)
-               goto err;
-
-       if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
-               pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
-               ret = -ENODEV;
-               goto err;
-       }
-
-       pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
-                       rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_read_config(struct dvb_usb_device *d)
-{
-       struct state *state = d_to_priv(d);
-       int ret, i, eeprom_shift = 0;
-       u8 tmp;
-       u16 tmp16;
-
-       /* check if there is dual tuners */
-       ret = af9035_rd_reg(d, EEPROM_DUAL_MODE, &tmp);
-       if (ret < 0)
-               goto err;
-
-       state->dual_mode = tmp;
-       pr_debug("%s: dual mode=%d\n", __func__, state->dual_mode);
-
-       for (i = 0; i < state->dual_mode + 1; i++) {
-               /* tuner */
-               ret = af9035_rd_reg(d, EEPROM_1_TUNER_ID + eeprom_shift, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               state->af9033_config[i].tuner = tmp;
-               pr_debug("%s: [%d]tuner=%02x\n", __func__, i, tmp);
-
-               switch (tmp) {
-               case AF9033_TUNER_TUA9001:
-               case AF9033_TUNER_FC0011:
-               case AF9033_TUNER_MXL5007T:
-               case AF9033_TUNER_TDA18218:
-                       state->af9033_config[i].spec_inv = 1;
-                       break;
-               default:
-                       pr_info("%s: tuner ID=%02x not supported, please " \
-                                       "report!", KBUILD_MODNAME, tmp);
-               };
-
-               /* tuner IF frequency */
-               ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_L + eeprom_shift, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               tmp16 = tmp;
-
-               ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_H + eeprom_shift, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               tmp16 |= tmp << 8;
-
-               pr_debug("%s: [%d]IF=%d\n", __func__, i, tmp16);
-
-               eeprom_shift = 0x10; /* shift for the 2nd tuner params */
-       }
-
-       /* get demod clock */
-       ret = af9035_rd_reg(d, 0x00d800, &tmp);
-       if (ret < 0)
-               goto err;
-
-       tmp = (tmp >> 0) & 0x0f;
-
-       for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
-               state->af9033_config[i].clock = clock_lut[tmp];
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_read_config_it9135(struct dvb_usb_device *d)
-{
-       struct state *state = d_to_priv(d);
-       int ret, i;
-       u8 tmp;
-
-       state->dual_mode = false;
-
-       /* get demod clock */
-       ret = af9035_rd_reg(d, 0x00d800, &tmp);
-       if (ret < 0)
-               goto err;
-
-       tmp = (tmp >> 0) & 0x0f;
-
-       for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
-               state->af9033_config[i].clock = clock_lut_it9135[tmp];
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
-               int cmd, int arg)
-{
-       int ret;
-
-       switch (cmd) {
-       case FC0011_FE_CALLBACK_POWER:
-               /* Tuner enable */
-               ret = af9035_wr_reg_mask(d, 0xd8eb, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0xd8ec, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0xd8ed, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               /* LED */
-               ret = af9035_wr_reg_mask(d, 0xd8d0, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0xd8d1, 1, 1);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(10000, 50000);
-               break;
-       case FC0011_FE_CALLBACK_RESET:
-               ret = af9035_wr_reg(d, 0xd8e9, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg(d, 0xd8e8, 1);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg(d, 0xd8e7, 1);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(10000, 20000);
-
-               ret = af9035_wr_reg(d, 0xd8e7, 0);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(10000, 20000);
-               break;
-       default:
-               ret = -EINVAL;
-               goto err;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
-{
-       struct state *state = d_to_priv(d);
-
-       switch (state->af9033_config[0].tuner) {
-       case AF9033_TUNER_FC0011:
-               return af9035_fc0011_tuner_callback(d, cmd, arg);
-       default:
-               break;
-       }
-
-       return -ENODEV;
-}
-
-static int af9035_frontend_callback(void *adapter_priv, int component,
-                                   int cmd, int arg)
-{
-       struct i2c_adapter *adap = adapter_priv;
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-
-       switch (component) {
-       case DVB_FRONTEND_COMPONENT_TUNER:
-               return af9035_tuner_callback(d, cmd, arg);
-       default:
-               break;
-       }
-
-       return -EINVAL;
-}
-
-static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct state *state = adap_to_priv(adap);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-
-       if (!state->af9033_config[adap->id].tuner) {
-               /* unsupported tuner */
-               ret = -ENODEV;
-               goto err;
-       }
-
-       if (adap->id == 0) {
-               state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
-               state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL;
-
-               ret = af9035_wr_reg(d, 0x00417f,
-                               state->af9033_config[1].i2c_addr);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg(d, 0x00d81a,
-                               state->dual_mode);
-               if (ret < 0)
-                       goto err;
-       }
-
-       /* attach demodulator */
-       adap->fe[0] = dvb_attach(af9033_attach,
-                       &state->af9033_config[adap->id], &d->i2c_adap);
-       if (adap->fe[0] == NULL) {
-               ret = -ENODEV;
-               goto err;
-       }
-
-       /* disable I2C-gate */
-       adap->fe[0]->ops.i2c_gate_ctrl = NULL;
-       adap->fe[0]->callback = af9035_frontend_callback;
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static struct tua9001_config af9035_tua9001_config = {
-       .i2c_addr = 0x60,
-};
-
-static const struct fc0011_config af9035_fc0011_config = {
-       .i2c_address = 0x60,
-};
-
-static struct mxl5007t_config af9035_mxl5007t_config = {
-       .xtal_freq_hz = MxL_XTAL_24_MHZ,
-       .if_freq_hz = MxL_IF_4_57_MHZ,
-       .invert_if = 0,
-       .loop_thru_enable = 0,
-       .clk_out_enable = 0,
-       .clk_out_amp = MxL_CLKOUT_AMP_0_94V,
-};
-
-static struct tda18218_config af9035_tda18218_config = {
-       .i2c_address = 0x60,
-       .i2c_wr_max = 21,
-};
-
-static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct state *state = adap_to_priv(adap);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-       struct dvb_frontend *fe;
-
-       switch (state->af9033_config[adap->id].tuner) {
-       case AF9033_TUNER_TUA9001:
-               /* AF9035 gpiot3 = TUA9001 RESETN
-                  AF9035 gpiot2 = TUA9001 RXEN */
-
-               /* configure gpiot2 and gpiot2 as output */
-               ret = af9035_wr_reg_mask(d, 0x00d8ec, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0x00d8ed, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0x00d8e8, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9035_wr_reg_mask(d, 0x00d8e9, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               /* reset tuner */
-               ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x00, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(2000, 20000);
-
-               ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               /* activate tuner RX */
-               /* TODO: use callback for TUA9001 RXEN */
-               ret = af9035_wr_reg_mask(d, 0x00d8eb, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               /* attach tuner */
-               fe = dvb_attach(tua9001_attach, adap->fe[0],
-                               &d->i2c_adap, &af9035_tua9001_config);
-               break;
-       case AF9033_TUNER_FC0011:
-               fe = dvb_attach(fc0011_attach, adap->fe[0],
-                               &d->i2c_adap, &af9035_fc0011_config);
-               break;
-       case AF9033_TUNER_MXL5007T:
-               ret = af9035_wr_reg(d, 0x00d8e0, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8e1, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8df, 0);
-               if (ret < 0)
-                       goto err;
-
-               msleep(30);
-
-               ret = af9035_wr_reg(d, 0x00d8df, 1);
-               if (ret < 0)
-                       goto err;
-
-               msleep(300);
-
-               ret = af9035_wr_reg(d, 0x00d8c0, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8c1, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8bf, 0);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8b4, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8b5, 1);
-               if (ret < 0)
-                       goto err;
-               ret = af9035_wr_reg(d, 0x00d8b3, 1);
-               if (ret < 0)
-                       goto err;
-
-               /* attach tuner */
-               fe = dvb_attach(mxl5007t_attach, adap->fe[0],
-                               &d->i2c_adap, 0x60, &af9035_mxl5007t_config);
-               break;
-       case AF9033_TUNER_TDA18218:
-               /* attach tuner */
-               fe = dvb_attach(tda18218_attach, adap->fe[0],
-                               &d->i2c_adap, &af9035_tda18218_config);
-               break;
-       default:
-               fe = NULL;
-       }
-
-       if (fe == NULL) {
-               ret = -ENODEV;
-               goto err;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_init(struct dvb_usb_device *d)
-{
-       struct state *state = d_to_priv(d);
-       int ret, i;
-       u16 frame_size = 87 * 188 / 4;
-       u8  packet_size = 512 / 4;
-       struct reg_val_mask tab[] = {
-               { 0x80f99d, 0x01, 0x01 },
-               { 0x80f9a4, 0x01, 0x01 },
-               { 0x00dd11, 0x00, 0x20 },
-               { 0x00dd11, 0x00, 0x40 },
-               { 0x00dd13, 0x00, 0x20 },
-               { 0x00dd13, 0x00, 0x40 },
-               { 0x00dd11, 0x20, 0x20 },
-               { 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
-               { 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
-               { 0x00dd0c, packet_size, 0xff},
-               { 0x00dd11, state->dual_mode << 6, 0x40 },
-               { 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
-               { 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
-               { 0x00dd0d, packet_size, 0xff },
-               { 0x80f9a3, 0x00, 0x01 },
-               { 0x80f9cd, 0x00, 0x01 },
-               { 0x80f99d, 0x00, 0x01 },
-               { 0x80f9a4, 0x00, 0x01 },
-       };
-
-       pr_debug("%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
-               __func__, d->udev->speed, frame_size, packet_size);
-
-       /* init endpoints */
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = af9035_wr_reg_mask(d, tab[i].reg, tab[i].val,
-                               tab[i].mask);
-               if (ret < 0)
-                       goto err;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9035_rc_query(struct dvb_usb_device *d)
-{
-       unsigned int key;
-       unsigned char b[4];
-       int ret;
-       struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, b };
-
-       ret = af9035_ctrl_msg(d, &req);
-       if (ret < 0)
-               goto err;
-
-       if ((b[2] + b[3]) == 0xff) {
-               if ((b[0] + b[1]) == 0xff) {
-                       /* NEC */
-                       key = b[0] << 8 | b[2];
-               } else {
-                       /* ext. NEC */
-                       key = b[0] << 16 | b[1] << 8 | b[2];
-               }
-       } else {
-               key = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
-       }
-
-       rc_keydown(d->rc_dev, key, 0);
-
-err:
-       /* ignore errors */
-       return 0;
-}
-
-static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
-{
-       int ret;
-       u8 tmp;
-
-       ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp);
-       if (ret < 0)
-               goto err;
-
-       pr_debug("%s: ir_mode=%02x\n", __func__, tmp);
-
-       /* don't activate rc if in HID mode or if not available */
-       if (tmp == 5) {
-               ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               pr_debug("%s: ir_type=%02x\n", __func__, tmp);
-
-               switch (tmp) {
-               case 0: /* NEC */
-               default:
-                       rc->allowed_protos = RC_TYPE_NEC;
-                       break;
-               case 1: /* RC6 */
-                       rc->allowed_protos = RC_TYPE_RC6;
-                       break;
-               }
-
-               rc->query = af9035_rc_query;
-               rc->interval = 500;
-
-               /* load empty to enable rc */
-               if (!rc->map_name)
-                       rc->map_name = RC_MAP_EMPTY;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-/* interface 0 is used by DVB-T receiver and
-   interface 1 is for remote controller (HID) */
-static const struct dvb_usb_device_properties af9035_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .identify_state = af9035_identify_state,
-       .firmware = "dvb-usb-af9035-02.fw",
-       .download_firmware = af9035_download_firmware,
-
-       .i2c_algo = &af9035_i2c_algo,
-       .read_config = af9035_read_config,
-       .frontend_attach = af9035_frontend_attach,
-       .tuner_attach = af9035_tuner_attach,
-       .init = af9035_init,
-       .get_rc_config = af9035_get_rc_config,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
-               }, {
-                       .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
-               },
-       },
-};
-
-static const struct dvb_usb_device_properties it9135_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .identify_state = af9035_identify_state,
-       .firmware = "dvb-usb-it9135-01.fw",
-       .download_firmware = af9035_download_firmware_it9135,
-
-       .i2c_algo = &af9035_i2c_algo,
-       .read_config = af9035_read_config_it9135,
-       .frontend_attach = af9035_frontend_attach,
-       .tuner_attach = af9035_tuner_attach,
-       .init = af9035_init,
-       .get_rc_config = af9035_get_rc_config,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
-               }, {
-                       .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
-               },
-       },
-};
-
-static const struct usb_device_id af9035_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1000,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1001,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1002,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1003,
-               &af9035_props, "Afatech AF9035 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK,
-               &af9035_props, "TerraTec Cinergy T Stick", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835,
-               &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_B835,
-               &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_1867,
-               &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A867,
-               &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TWINSTAR,
-               &af9035_props, "AVerMedia Twinstar (A825)", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, af9035_id_table);
-
-static struct usb_driver af9035_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = af9035_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(af9035_usb_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Afatech AF9035 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9035.h b/drivers/media/dvb/dvb-usb/af9035.h
deleted file mode 100644 (file)
index 59ff69e..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Afatech AF9035 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License along
- *    with this program; if not, write to the Free Software Foundation, Inc.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef AF9035_H
-#define AF9035_H
-
-#include "dvb_usb.h"
-#include "af9033.h"
-#include "tua9001.h"
-#include "fc0011.h"
-#include "mxl5007t.h"
-#include "tda18218.h"
-
-struct reg_val {
-       u32 reg;
-       u8  val;
-};
-
-struct reg_val_mask {
-       u32 reg;
-       u8  val;
-       u8  mask;
-};
-
-struct usb_req {
-       u8  cmd;
-       u8  mbox;
-       u8  wlen;
-       u8  *wbuf;
-       u8  rlen;
-       u8  *rbuf;
-};
-
-struct state {
-       u8 seq; /* packet sequence number */
-       bool dual_mode;
-
-       struct af9033_config af9033_config[2];
-};
-
-u32 clock_lut[] = {
-       20480000, /*      FPGA */
-       16384000, /* 16.38 MHz */
-       20480000, /* 20.48 MHz */
-       36000000, /* 36.00 MHz */
-       30000000, /* 30.00 MHz */
-       26000000, /* 26.00 MHz */
-       28000000, /* 28.00 MHz */
-       32000000, /* 32.00 MHz */
-       34000000, /* 34.00 MHz */
-       24000000, /* 24.00 MHz */
-       22000000, /* 22.00 MHz */
-       12000000, /* 12.00 MHz */
-};
-
-u32 clock_lut_it9135[] = {
-       12000000, /* 12.00 MHz */
-       20480000, /* 20.48 MHz */
-       36000000, /* 36.00 MHz */
-       30000000, /* 30.00 MHz */
-       26000000, /* 26.00 MHz */
-       28000000, /* 28.00 MHz */
-       32000000, /* 32.00 MHz */
-       34000000, /* 34.00 MHz */
-       24000000, /* 24.00 MHz */
-       22000000, /* 22.00 MHz */
-};
-
-/* EEPROM locations */
-#define EEPROM_IR_MODE            0x430d
-#define EEPROM_DUAL_MODE          0x4326
-#define EEPROM_IR_TYPE            0x4329
-#define EEPROM_1_IFFREQ_L         0x432d
-#define EEPROM_1_IFFREQ_H         0x432e
-#define EEPROM_1_TUNER_ID         0x4331
-#define EEPROM_2_IFFREQ_L         0x433d
-#define EEPROM_2_IFFREQ_H         0x433e
-#define EEPROM_2_TUNER_ID         0x4341
-
-/* USB commands */
-#define CMD_MEM_RD                  0x00
-#define CMD_MEM_WR                  0x01
-#define CMD_I2C_RD                  0x02
-#define CMD_I2C_WR                  0x03
-#define CMD_IR_GET                  0x18
-#define CMD_FW_DL                   0x21
-#define CMD_FW_QUERYINFO            0x22
-#define CMD_FW_BOOT                 0x23
-#define CMD_FW_DL_BEGIN             0x24
-#define CMD_FW_DL_END               0x25
-#define CMD_FW_SCATTER_WR           0x29
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
deleted file mode 100644 (file)
index fb3829a..0000000
+++ /dev/null
@@ -1,1324 +0,0 @@
-/*
- * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * TODO:
- * - add smart card reader support for Conditional Access (CA)
- *
- * Card reader in Anysee is nothing more than ISO 7816 card reader.
- * There is no hardware CAM in any Anysee device sold.
- * In my understanding it should be implemented by making own module
- * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
- * module registers serial interface that can be used to communicate
- * with any ISO 7816 smart card.
- *
- * Any help according to implement serial smart card reader support
- * is highly welcome!
- */
-
-#include "anysee.h"
-#include "dvb-pll.h"
-#include "tda1002x.h"
-#include "mt352.h"
-#include "mt352_priv.h"
-#include "zl10353.h"
-#include "tda18212.h"
-#include "cx24116.h"
-#include "stv0900.h"
-#include "stv6110.h"
-#include "isl6423.h"
-#include "cxd2820r.h"
-
-/* debug */
-static int dvb_usb_anysee_debug;
-module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static DEFINE_MUTEX(anysee_usb_mutex);
-
-static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
-       u8 *rbuf, u8 rlen)
-{
-       struct anysee_state *state = d_to_priv(d);
-       int act_len, ret, i;
-       u8 buf[64];
-
-       memcpy(&buf[0], sbuf, slen);
-       buf[60] = state->seq++;
-
-       mutex_lock(&anysee_usb_mutex);
-
-       deb_xfer(">>> ");
-       debug_dump(buf, slen, deb_xfer);
-
-       /* We need receive one message more after dvb_usb_generic_rw due
-          to weird transaction flow, which is 1 x send + 2 x receive. */
-       ret = dvb_usbv2_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf));
-       if (ret)
-               goto error_unlock;
-
-       /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
-        * (EPIPE, Broken pipe). Function supports currently msleep() as a
-        * parameter but I would not like to use it, since according to
-        * Documentation/timers/timers-howto.txt it should not be used such
-        * short, under < 20ms, sleeps. Repeating failed message would be
-        * better choice as not to add unwanted delays...
-        * Fixing that correctly is one of those or both;
-        * 1) use repeat if possible
-        * 2) add suitable delay
-        */
-
-       /* get answer, retry few times if error returned */
-       for (i = 0; i < 3; i++) {
-               /* receive 2nd answer */
-               ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
-                       d->props->generic_bulk_ctrl_endpoint), buf, sizeof(buf),
-                       &act_len, 2000);
-
-               if (ret) {
-                       deb_info("%s: recv bulk message failed: %d",
-                                       __func__, ret);
-               } else {
-                       deb_xfer("<<< ");
-                       debug_dump(buf, rlen, deb_xfer);
-
-                       if (buf[63] != 0x4f)
-                               deb_info("%s: cmd failed\n", __func__);
-
-                       break;
-               }
-       }
-
-       if (ret) {
-               /* all retries failed, it is fatal */
-               err("%s: recv bulk message failed: %d", __func__, ret);
-               goto error_unlock;
-       }
-
-       /* read request, copy returned data to return buf */
-       if (rbuf && rlen)
-               memcpy(rbuf, buf, rlen);
-
-error_unlock:
-       mutex_unlock(&anysee_usb_mutex);
-
-       return ret;
-}
-
-static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
-{
-       u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
-       int ret;
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
-       deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
-       return ret;
-}
-
-static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
-{
-       u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
-       deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
-       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-}
-
-/* write single register with mask */
-static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
-       u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = anysee_read_reg(d, reg, &tmp);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return anysee_write_reg(d, reg, val);
-}
-
-/* read single register with mask */
-static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
-       u8 mask)
-{
-       int ret, i;
-       u8 tmp;
-
-       ret = anysee_read_reg(d, reg, &tmp);
-       if (ret)
-               return ret;
-
-       tmp &= mask;
-
-       /* find position of the first bit */
-       for (i = 0; i < 8; i++) {
-               if ((mask >> i) & 0x01)
-                       break;
-       }
-       *val = tmp >> i;
-
-       return 0;
-}
-
-static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
-{
-       u8 buf[] = {CMD_GET_HW_INFO};
-       return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
-}
-
-static int anysee_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
-       deb_info("%s: onoff:%02x\n", __func__, onoff);
-       return anysee_ctrl_msg(fe_to_d(fe), buf, sizeof(buf), NULL, 0);
-}
-
-static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
-{
-       u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
-       deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
-       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-}
-
-static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
-{
-       u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
-       deb_info("%s: onoff:%02x\n", __func__, onoff);
-       return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-}
-
-/* I2C */
-static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
-       int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int ret = 0, inc, i = 0;
-       u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       while (i < num) {
-               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-                       if (msg[i].len > 2 || msg[i+1].len > 60) {
-                               ret = -EOPNOTSUPP;
-                               break;
-                       }
-                       buf[0] = CMD_I2C_READ;
-                       buf[1] = (msg[i].addr << 1) | 0x01;
-                       buf[2] = msg[i].buf[0];
-                       buf[3] = msg[i].buf[1];
-                       buf[4] = msg[i].len-1;
-                       buf[5] = msg[i+1].len;
-                       ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
-                               msg[i+1].len);
-                       inc = 2;
-               } else {
-                       if (msg[i].len > 48) {
-                               ret = -EOPNOTSUPP;
-                               break;
-                       }
-                       buf[0] = CMD_I2C_WRITE;
-                       buf[1] = (msg[i].addr << 1);
-                       buf[2] = msg[i].len;
-                       buf[3] = 0x01;
-                       memcpy(&buf[4], msg[i].buf, msg[i].len);
-                       ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
-                       inc = 1;
-               }
-               if (ret)
-                       break;
-
-               i += inc;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret ? ret : i;
-}
-
-static u32 anysee_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm anysee_i2c_algo = {
-       .master_xfer   = anysee_master_xfer,
-       .functionality = anysee_i2c_func,
-};
-
-static int anysee_mt352_demod_init(struct dvb_frontend *fe)
-{
-       static u8 clock_config[]   = { CLOCK_CTL,  0x38, 0x28 };
-       static u8 reset[]          = { RESET,      0x80 };
-       static u8 adc_ctl_1_cfg[]  = { ADC_CTL_1,  0x40 };
-       static u8 agc_cfg[]        = { AGC_TARGET, 0x28, 0x20 };
-       static u8 gpp_ctl_cfg[]    = { GPP_CTL,    0x33 };
-       static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
-
-       mt352_write(fe, clock_config,   sizeof(clock_config));
-       udelay(200);
-       mt352_write(fe, reset,          sizeof(reset));
-       mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
-
-       mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
-       mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
-       mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-
-       return 0;
-}
-
-/* Callbacks for DVB USB */
-static struct tda10023_config anysee_tda10023_config = {
-       .demod_address = (0x1a >> 1),
-       .invert = 0,
-       .xtal   = 16000000,
-       .pll_m  = 11,
-       .pll_p  = 3,
-       .pll_n  = 1,
-       .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
-       .deltaf = 0xfeeb,
-};
-
-static struct mt352_config anysee_mt352_config = {
-       .demod_address = (0x1e >> 1),
-       .demod_init    = anysee_mt352_demod_init,
-};
-
-static struct zl10353_config anysee_zl10353_config = {
-       .demod_address = (0x1e >> 1),
-       .parallel_ts = 1,
-};
-
-static struct zl10353_config anysee_zl10353_tda18212_config2 = {
-       .demod_address = (0x1e >> 1),
-       .parallel_ts = 1,
-       .disable_i2c_gate_ctrl = 1,
-       .no_tuner = 1,
-       .if2 = 41500,
-};
-
-static struct zl10353_config anysee_zl10353_tda18212_config = {
-       .demod_address = (0x18 >> 1),
-       .parallel_ts = 1,
-       .disable_i2c_gate_ctrl = 1,
-       .no_tuner = 1,
-       .if2 = 41500,
-};
-
-static struct tda10023_config anysee_tda10023_tda18212_config = {
-       .demod_address = (0x1a >> 1),
-       .xtal   = 16000000,
-       .pll_m  = 12,
-       .pll_p  = 3,
-       .pll_n  = 1,
-       .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
-       .deltaf = 0xba02,
-};
-
-static struct tda18212_config anysee_tda18212_config = {
-       .i2c_address = (0xc0 >> 1),
-       .if_dvbt_6 = 4150,
-       .if_dvbt_7 = 4150,
-       .if_dvbt_8 = 4150,
-       .if_dvbc = 5000,
-};
-
-static struct tda18212_config anysee_tda18212_config2 = {
-       .i2c_address = 0x60 /* (0xc0 >> 1) */,
-       .if_dvbt_6 = 3550,
-       .if_dvbt_7 = 3700,
-       .if_dvbt_8 = 4150,
-       .if_dvbt2_6 = 3250,
-       .if_dvbt2_7 = 4000,
-       .if_dvbt2_8 = 4000,
-       .if_dvbc = 5000,
-};
-
-static struct cx24116_config anysee_cx24116_config = {
-       .demod_address = (0xaa >> 1),
-       .mpg_clk_pos_pol = 0x00,
-       .i2c_wr_max = 48,
-};
-
-static struct stv0900_config anysee_stv0900_config = {
-       .demod_address = (0xd0 >> 1),
-       .demod_mode = 0,
-       .xtal = 8000000,
-       .clkmode = 3,
-       .diseqc_mode = 2,
-       .tun1_maddress = 0,
-       .tun1_adc = 1, /* 1 Vpp */
-       .path1_mode = 3,
-};
-
-static struct stv6110_config anysee_stv6110_config = {
-       .i2c_address = (0xc0 >> 1),
-       .mclk = 16000000,
-       .clk_div = 1,
-};
-
-static struct isl6423_config anysee_isl6423_config = {
-       .current_max = SEC_CURRENT_800m,
-       .curlim  = SEC_CURRENT_LIM_OFF,
-       .mod_extern = 1,
-       .addr = (0x10 >> 1),
-};
-
-static struct cxd2820r_config anysee_cxd2820r_config = {
-       .i2c_address = 0x6d, /* (0xda >> 1) */
-       .ts_mode = 0x38,
-};
-
-/*
- * New USB device strings: Mfr=1, Product=2, SerialNumber=0
- * Manufacturer: AMT.CO.KR
- *
- * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
- * PCB: ?
- * parts: DNOS404ZH102A(MT352, DTT7579(?))
- *
- * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
- * PCB: PCB 507T (rev1.61)
- * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
- * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
- * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
- *
- * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
- * PCB: 507CD (rev1.1)
- * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
- * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
- * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
- * IOD[0] ZL10353 1=enabled
- * IOA[7] TS 0=enabled
- * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
- *
- * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
- * PCB: 507DC (rev0.2)
- * parts: TDA10023, DTOS403IH102B TM, CST56I01
- * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
- * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
- * IOD[0] TDA10023 1=enabled
- *
- * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
- * PCB: 507SI (rev2.1)
- * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
- * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
- * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
- * IOD[0] CX24116 1=enabled
- *
- * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
- * PCB: 507FA (rev0.4)
- * parts: TDA10023, DTOS403IH102B TM, TDA8024
- * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
- * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
- * IOD[5] TDA10023 1=enabled
- * IOE[0] tuner 1=enabled
- *
- * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
- * PCB: 507FA (rev1.1)
- * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
- * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
- * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
- * DVB-C:
- * IOD[5] TDA10023 1=enabled
- * IOE[0] tuner 1=enabled
- * DVB-T:
- * IOD[0] ZL10353 1=enabled
- * IOE[0] tuner 0=enabled
- * tuner is behind ZL10353 I2C-gate
- *
- * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
- * PCB: 508TC (rev0.6)
- * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[4] TDA18212 1=enabled
- * DVB-C:
- * IOD[6] ZL10353 0=disabled
- * IOD[5] TDA10023 1=enabled
- * IOE[0] IF 1=enabled
- * DVB-T:
- * IOD[5] TDA10023 0=disabled
- * IOD[6] ZL10353 1=enabled
- * IOE[0] IF 0=enabled
- *
- * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
- * PCB: 508S2 (rev0.7)
- * parts: DNBU10512IST(STV0903, STV6110), ISL6423
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[5] STV0903 1=enabled
- *
- * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
- * PCB: 508T2C (rev0.3)
- * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[5] CXD2820R 1=enabled
- *
- * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
- * PCB: 508PTC (rev0.5)
- * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[4] TDA18212 1=enabled
- * DVB-C:
- * IOD[6] ZL10353 0=disabled
- * IOD[5] TDA10023 1=enabled
- * IOE[0] IF 1=enabled
- * DVB-T:
- * IOD[5] TDA10023 0=disabled
- * IOD[6] ZL10353 1=enabled
- * IOE[0] IF 0=enabled
- *
- * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
- * PCB: 508PS2 (rev0.4)
- * parts: DNBU10512IST(STV0903, STV6110), ISL6423
- * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
- * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
- * IOA[7] TS 1=enabled
- * IOE[5] STV0903 1=enabled
- */
-
-static int anysee_read_config(struct dvb_usb_device *d)
-{
-       struct anysee_state *state = d_to_priv(d);
-       int ret;
-       u8 hw_info[3];
-
-       /*
-        * Check which hardware we have.
-        * We must do this call two times to get reliable values (hw/fw bug).
-        */
-       ret = anysee_get_hw_info(d, hw_info);
-       if (ret)
-               goto error;
-
-       ret = anysee_get_hw_info(d, hw_info);
-       if (ret)
-               goto error;
-
-       /* Meaning of these info bytes are guessed. */
-       info("firmware version:%d.%d hardware id:%d",
-               hw_info[1], hw_info[2], hw_info[0]);
-
-       state->hw = hw_info[0];
-error:
-       return ret;
-}
-
-/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
-static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       /* enable / disable tuner access on IOE[4] */
-       return anysee_wr_reg_mask(fe_to_d(fe), REG_IOE, (enable << 4), 0x10);
-}
-
-static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct anysee_state *state = fe_to_priv(fe);
-       struct dvb_usb_device *d = fe_to_d(fe);
-       int ret;
-
-       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
-
-       /* no frontend sleep control */
-       if (onoff == 0)
-               return 0;
-
-       switch (state->hw) {
-       case ANYSEE_HW_507FA: /* 15 */
-               /* E30 Combo Plus */
-               /* E30 C Plus */
-
-               if (fe->id == 0)  {
-                       /* disable DVB-T demod on IOD[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-C demod on IOD[5] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-C tuner on IOE[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
-                       if (ret)
-                               goto error;
-               } else {
-                       /* disable DVB-C demod on IOD[5] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-T demod on IOD[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-T tuner on IOE[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
-                       if (ret)
-                               goto error;
-               }
-
-               break;
-       case ANYSEE_HW_508TC: /* 18 */
-       case ANYSEE_HW_508PTC: /* 21 */
-               /* E7 TC */
-               /* E7 PTC */
-
-               if (fe->id == 0)  {
-                       /* disable DVB-T demod on IOD[6] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-C demod on IOD[5] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
-                       if (ret)
-                               goto error;
-
-                       /* enable IF route on IOE[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
-                       if (ret)
-                               goto error;
-               } else {
-                       /* disable DVB-C demod on IOD[5] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
-                       if (ret)
-                               goto error;
-
-                       /* enable DVB-T demod on IOD[6] */
-                       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
-                       if (ret)
-                               goto error;
-
-                       /* enable IF route on IOE[0] */
-                       ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
-                       if (ret)
-                               goto error;
-               }
-
-               break;
-       default:
-               ret = 0;
-       }
-
-error:
-       return ret;
-}
-
-static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct anysee_state *state = adap_to_priv(adap);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-       u8 tmp;
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = anysee_tda18212_config.i2c_address,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = "\x00",
-               }, {
-                       .addr = anysee_tda18212_config.i2c_address,
-                       .flags = I2C_M_RD,
-                       .len = 1,
-                       .buf = &tmp,
-               }
-       };
-
-       switch (state->hw) {
-       case ANYSEE_HW_507T: /* 2 */
-               /* E30 */
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(mt352_attach, &anysee_mt352_config,
-                               &d->i2c_adap);
-               if (adap->fe[0])
-                       break;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
-                               &d->i2c_adap);
-
-               break;
-       case ANYSEE_HW_507CD: /* 6 */
-               /* E30 Plus */
-
-               /* enable DVB-T demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* enable transport stream on IOA[7] */
-               ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
-                               &d->i2c_adap);
-
-               break;
-       case ANYSEE_HW_507DC: /* 10 */
-               /* E30 C Plus */
-
-               /* enable DVB-C demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(tda10023_attach,
-                               &anysee_tda10023_config, &d->i2c_adap, 0x48);
-
-               break;
-       case ANYSEE_HW_507SI: /* 11 */
-               /* E30 S2 Plus */
-
-               /* enable DVB-S/S2 demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(cx24116_attach, &anysee_cx24116_config,
-                               &d->i2c_adap);
-
-               break;
-       case ANYSEE_HW_507FA: /* 15 */
-               /* E30 Combo Plus */
-               /* E30 C Plus */
-
-               /* enable tuner on IOE[4] */
-               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 4), 0x10);
-               if (ret)
-                       goto error;
-
-               /* probe TDA18212 */
-               tmp = 0;
-               ret = i2c_transfer(&d->i2c_adap, msg, 2);
-               if (ret == 2 && tmp == 0xc7)
-                       deb_info("%s: TDA18212 found\n", __func__);
-               else
-                       tmp = 0;
-
-               /* disable tuner on IOE[4] */
-               ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 4), 0x10);
-               if (ret)
-                       goto error;
-
-               /* disable DVB-T demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* enable DVB-C demod on IOD[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               if (tmp == 0xc7) {
-                       /* TDA18212 config */
-                       adap->fe[0] = dvb_attach(tda10023_attach,
-                                       &anysee_tda10023_tda18212_config,
-                                       &d->i2c_adap, 0x48);
-
-                       /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
-                       if (adap->fe[0])
-                               adap->fe[0]->ops.i2c_gate_ctrl =
-                                               anysee_i2c_gate_ctrl;
-               } else {
-                       /* PLL config */
-                       adap->fe[0] = dvb_attach(tda10023_attach,
-                                       &anysee_tda10023_config,
-                                       &d->i2c_adap, 0x48);
-               }
-
-               /* break out if first frontend attaching fails */
-               if (!adap->fe[0])
-                       break;
-
-               /* disable DVB-C demod on IOD[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* enable DVB-T demod on IOD[0] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               if (tmp == 0xc7) {
-                       /* TDA18212 config */
-                       adap->fe[1] = dvb_attach(zl10353_attach,
-                                       &anysee_zl10353_tda18212_config2,
-                                       &d->i2c_adap);
-
-                       /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
-                       if (adap->fe[1])
-                               adap->fe[1]->ops.i2c_gate_ctrl =
-                                               anysee_i2c_gate_ctrl;
-               } else {
-                       /* PLL config */
-                       adap->fe[1] = dvb_attach(zl10353_attach,
-                                       &anysee_zl10353_config,
-                                       &d->i2c_adap);
-               }
-
-               break;
-       case ANYSEE_HW_508TC: /* 18 */
-       case ANYSEE_HW_508PTC: /* 21 */
-               /* E7 TC */
-               /* E7 PTC */
-
-               /* disable DVB-T demod on IOD[6] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
-               if (ret)
-                       goto error;
-
-               /* enable DVB-C demod on IOD[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(tda10023_attach,
-                               &anysee_tda10023_tda18212_config,
-                               &d->i2c_adap, 0x48);
-
-               /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
-               if (adap->fe[0])
-                       adap->fe[0]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
-
-               /* break out if first frontend attaching fails */
-               if (!adap->fe[0])
-                       break;
-
-               /* disable DVB-C demod on IOD[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* enable DVB-T demod on IOD[6] */
-               ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[1] = dvb_attach(zl10353_attach,
-                               &anysee_zl10353_tda18212_config,
-                               &d->i2c_adap);
-
-               /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
-               if (adap->fe[1])
-                       adap->fe[1]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
-
-               state->has_ci = true;
-
-               break;
-       case ANYSEE_HW_508S2: /* 19 */
-       case ANYSEE_HW_508PS2: /* 22 */
-               /* E7 S2 */
-               /* E7 PS2 */
-
-               /* enable DVB-S/S2 demod on IOE[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(stv0900_attach,
-                               &anysee_stv0900_config, &d->i2c_adap, 0);
-
-               state->has_ci = true;
-
-               break;
-       case ANYSEE_HW_508T2C: /* 20 */
-               /* E7 T2C */
-
-               /* enable DVB-T/T2/C demod on IOE[5] */
-               ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
-               if (ret)
-                       goto error;
-
-               /* attach demod */
-               adap->fe[0] = dvb_attach(cxd2820r_attach,
-                               &anysee_cxd2820r_config, &d->i2c_adap);
-
-               state->has_ci = true;
-
-               break;
-       }
-
-       if (!adap->fe[0]) {
-               /* we have no frontend :-( */
-               ret = -ENODEV;
-               err("Unsupported Anysee version. " \
-                       "Please report the <linux-media@vger.kernel.org>.");
-       }
-error:
-       return ret;
-}
-
-static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       struct anysee_state *state = adap_to_priv(adap);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct dvb_frontend *fe;
-       int ret;
-       deb_info("%s: adap=%d\n", __func__, adap->id);
-
-       switch (state->hw) {
-       case ANYSEE_HW_507T: /* 2 */
-               /* E30 */
-
-               /* attach tuner */
-               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1), NULL,
-                               DVB_PLL_THOMSON_DTT7579);
-
-               break;
-       case ANYSEE_HW_507CD: /* 6 */
-               /* E30 Plus */
-
-               /* attach tuner */
-               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1),
-                               &d->i2c_adap, DVB_PLL_THOMSON_DTT7579);
-
-               break;
-       case ANYSEE_HW_507DC: /* 10 */
-               /* E30 C Plus */
-
-               /* attach tuner */
-               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
-                               &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
-
-               break;
-       case ANYSEE_HW_507SI: /* 11 */
-               /* E30 S2 Plus */
-
-               /* attach LNB controller */
-               fe = dvb_attach(isl6423_attach, adap->fe[0], &d->i2c_adap,
-                               &anysee_isl6423_config);
-
-               break;
-       case ANYSEE_HW_507FA: /* 15 */
-               /* E30 Combo Plus */
-               /* E30 C Plus */
-
-               /* Try first attach TDA18212 silicon tuner on IOE[4], if that
-                * fails attach old simple PLL. */
-
-               /* attach tuner */
-               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
-                               &anysee_tda18212_config);
-
-               if (fe && adap->fe[1]) {
-                       /* attach tuner for 2nd FE */
-                       fe = dvb_attach(tda18212_attach, adap->fe[1],
-                                       &d->i2c_adap, &anysee_tda18212_config);
-                       break;
-               } else if (fe) {
-                       break;
-               }
-
-               /* attach tuner */
-               fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
-                               &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
-
-               if (fe && adap->fe[1]) {
-                       /* attach tuner for 2nd FE */
-                       fe = dvb_attach(dvb_pll_attach, adap->fe[0],
-                                       (0xc0 >> 1), &d->i2c_adap,
-                                       DVB_PLL_SAMSUNG_DTOS403IH102A);
-               }
-
-               break;
-       case ANYSEE_HW_508TC: /* 18 */
-       case ANYSEE_HW_508PTC: /* 21 */
-               /* E7 TC */
-               /* E7 PTC */
-
-               /* attach tuner */
-               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
-                               &anysee_tda18212_config);
-
-               if (fe) {
-                       /* attach tuner for 2nd FE */
-                       fe = dvb_attach(tda18212_attach, adap->fe[1],
-                                       &d->i2c_adap, &anysee_tda18212_config);
-               }
-
-               break;
-       case ANYSEE_HW_508S2: /* 19 */
-       case ANYSEE_HW_508PS2: /* 22 */
-               /* E7 S2 */
-               /* E7 PS2 */
-
-               /* attach tuner */
-               fe = dvb_attach(stv6110_attach, adap->fe[0],
-                               &anysee_stv6110_config, &d->i2c_adap);
-
-               if (fe) {
-                       /* attach LNB controller */
-                       fe = dvb_attach(isl6423_attach, adap->fe[0],
-                                       &d->i2c_adap, &anysee_isl6423_config);
-               }
-
-               break;
-
-       case ANYSEE_HW_508T2C: /* 20 */
-               /* E7 T2C */
-
-               /* attach tuner */
-               fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
-                               &anysee_tda18212_config2);
-
-               break;
-       default:
-               fe = NULL;
-       }
-
-       if (fe)
-               ret = 0;
-       else
-               ret = -ENODEV;
-
-       return ret;
-}
-
-static int anysee_rc_query(struct dvb_usb_device *d)
-{
-       u8 buf[] = {CMD_GET_IR_CODE};
-       u8 ircode[2];
-       int ret;
-
-       /* Remote controller is basic NEC using address byte 0x08.
-          Anysee device RC query returns only two bytes, status and code,
-          address byte is dropped. Also it does not return any value for
-          NEC RCs having address byte other than 0x08. Due to that, we
-          cannot use that device as standard NEC receiver.
-          It could be possible make hack which reads whole code directly
-          from device memory... */
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
-       if (ret)
-               return ret;
-
-       if (ircode[0]) {
-               deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
-               rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
-       }
-
-       return 0;
-}
-
-static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
-{
-       rc->allowed_protos = RC_TYPE_NEC;
-       rc->query          = anysee_rc_query;
-       rc->interval       = 250;  /* windows driver uses 500ms */
-
-       return 0;
-}
-
-static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
-       int addr)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
-       u8 val;
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
-       if (ret)
-               return ret;
-
-       return val;
-}
-
-static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
-       int addr, u8 val)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
-       u8 addr)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
-       u8 val;
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
-       if (ret)
-               return ret;
-
-       return val;
-}
-
-static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
-       u8 addr, u8 val)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
-
-       ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-       struct anysee_state *state = d_to_priv(d);
-
-       state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       msleep(300);
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       msleep(30);
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
-{
-       struct dvb_usb_device *d = ci->data;
-       int ret;
-
-       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
-       int open)
-{
-       struct dvb_usb_device *d = ci->data;
-       struct anysee_state *state = d_to_priv(d);
-       int ret;
-       u8 tmp;
-
-       ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
-       if (ret)
-               return ret;
-
-       if (tmp == 0) {
-               ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
-               if (time_after(jiffies, state->ci_cam_ready))
-                       ret |= DVB_CA_EN50221_POLL_CAM_READY;
-       }
-
-       return ret;
-}
-
-static int anysee_ci_init(struct dvb_usb_device *d)
-{
-       struct anysee_state *state = d_to_priv(d);
-       int ret;
-
-       state->ci.owner               = THIS_MODULE;
-       state->ci.read_attribute_mem  = anysee_ci_read_attribute_mem;
-       state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
-       state->ci.read_cam_control    = anysee_ci_read_cam_control;
-       state->ci.write_cam_control   = anysee_ci_write_cam_control;
-       state->ci.slot_reset          = anysee_ci_slot_reset;
-       state->ci.slot_shutdown       = anysee_ci_slot_shutdown;
-       state->ci.slot_ts_enable      = anysee_ci_slot_ts_enable;
-       state->ci.poll_slot_status    = anysee_ci_poll_slot_status;
-       state->ci.data                = d;
-
-       ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
-       if (ret)
-               return ret;
-
-       ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 2)|(0 << 1)|(0 << 0), 0x07);
-       if (ret)
-               return ret;
-
-       ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 2)|(1 << 1)|(1 << 0), 0x07);
-       if (ret)
-               return ret;
-
-       ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static void anysee_ci_release(struct dvb_usb_device *d)
-{
-       struct anysee_state *state = d_to_priv(d);
-
-       /* detach CI */
-       if (state->has_ci)
-               dvb_ca_en50221_release(&state->ci);
-
-       return;
-}
-
-static int anysee_init(struct dvb_usb_device *d)
-{
-       struct anysee_state *state = d_to_priv(d);
-       int ret;
-
-       /* There is one interface with two alternate settings.
-          Alternate setting 0 is for bulk transfer.
-          Alternate setting 1 is for isochronous transfer.
-          We use bulk transfer (alternate setting 0). */
-       ret = usb_set_interface(d->udev, 0, 0);
-       if (ret)
-               return ret;
-
-       /* LED light */
-       ret = anysee_led_ctrl(d, 0x01, 0x03);
-       if (ret)
-               return ret;
-
-       /* enable IR */
-       ret = anysee_ir_ctrl(d, 1);
-       if (ret)
-               return ret;
-
-       /* attach CI */
-       if (state->has_ci) {
-               ret = anysee_ci_init(d);
-               if (ret) {
-                       state->has_ci = false;
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-static void anysee_exit(struct dvb_usb_device *d)
-{
-       return anysee_ci_release(d);
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties anysee_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct anysee_state),
-
-       .generic_bulk_ctrl_endpoint = 0x01,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo         = &anysee_i2c_algo,
-       .read_config      = anysee_read_config,
-       .frontend_attach  = anysee_frontend_attach,
-       .tuner_attach     = anysee_tuner_attach,
-       .init             = anysee_init,
-       .get_rc_config    = anysee_get_rc_config,
-       .frontend_ctrl    = anysee_frontend_ctrl,
-       .streaming_ctrl   = anysee_streaming_ctrl,
-       .exit             = anysee_exit,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x82, 8, 16 * 512),
-               }
-       }
-};
-
-static const struct usb_device_id anysee_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE,
-               &anysee_props, "Anysee", RC_MAP_ANYSEE) },
-       { DVB_USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE,
-               &anysee_props, "Anysee", RC_MAP_ANYSEE) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, anysee_id_table);
-
-static struct usb_driver anysee_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = anysee_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(anysee_usb_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h
deleted file mode 100644 (file)
index dc40dcf..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * TODO:
- * - add smart card reader support for Conditional Access (CA)
- *
- * Card reader in Anysee is nothing more than ISO 7816 card reader.
- * There is no hardware CAM in any Anysee device sold.
- * In my understanding it should be implemented by making own module
- * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
- * module registers serial interface that can be used to communicate
- * with any ISO 7816 smart card.
- *
- * Any help according to implement serial smart card reader support
- * is highly welcome!
- */
-
-#ifndef _DVB_USB_ANYSEE_H_
-#define _DVB_USB_ANYSEE_H_
-
-#define DVB_USB_LOG_PREFIX "anysee"
-#include "dvb_usb.h"
-#include "dvb_ca_en50221.h"
-
-#ifdef CONFIG_DVB_USB_DEBUG
-#define dprintk(var, level, args...) \
-       do { if ((var & level)) printk(args); } while (0)
-#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
-
-#define debug_dump(b, l, func) {\
-       int loop_; \
-       for (loop_ = 0; loop_ < l; loop_++) \
-               func("%02x ", b[loop_]); \
-       func("\n");\
-}
-
-#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
-#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
-#define deb_rc(args...)   dprintk(dvb_usb_anysee_debug, 0x04, args)
-#define deb_reg(args...)  dprintk(dvb_usb_anysee_debug, 0x08, args)
-#define deb_i2c(args...)  dprintk(dvb_usb_anysee_debug, 0x10, args)
-#define deb_fw(args...)   dprintk(dvb_usb_anysee_debug, 0x20, args)
-
-#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)
-
-enum cmd {
-       CMD_I2C_READ            = 0x33,
-       CMD_I2C_WRITE           = 0x31,
-       CMD_REG_READ            = 0xb0,
-       CMD_REG_WRITE           = 0xb1,
-       CMD_STREAMING_CTRL      = 0x12,
-       CMD_LED_AND_IR_CTRL     = 0x16,
-       CMD_GET_IR_CODE         = 0x41,
-       CMD_GET_HW_INFO         = 0x19,
-       CMD_SMARTCARD           = 0x34,
-       CMD_CI                  = 0x37,
-};
-
-struct anysee_state {
-       u8 hw; /* PCB ID */
-       u8 seq;
-       u8 fe_id:1; /* frondend ID */
-       u8 has_ci:1;
-       struct dvb_ca_en50221 ci;
-       unsigned long ci_cam_ready; /* jiffies */
-};
-
-#define ANYSEE_HW_507T    2 /* E30 */
-#define ANYSEE_HW_507CD   6 /* E30 Plus */
-#define ANYSEE_HW_507DC  10 /* E30 C Plus */
-#define ANYSEE_HW_507SI  11 /* E30 S2 Plus */
-#define ANYSEE_HW_507FA  15 /* E30 Combo Plus / E30 C Plus */
-#define ANYSEE_HW_508TC  18 /* E7 TC */
-#define ANYSEE_HW_508S2  19 /* E7 S2 */
-#define ANYSEE_HW_508T2C 20 /* E7 T2C */
-#define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */
-#define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */
-
-#define REG_IOA       0x80 /* Port A (bit addressable) */
-#define REG_IOB       0x90 /* Port B (bit addressable) */
-#define REG_IOC       0xa0 /* Port C (bit addressable) */
-#define REG_IOD       0xb0 /* Port D (bit addressable) */
-#define REG_IOE       0xb1 /* Port E (NOT bit addressable) */
-#define REG_OEA       0xb2 /* Port A Output Enable */
-#define REG_OEB       0xb3 /* Port B Output Enable */
-#define REG_OEC       0xb4 /* Port C Output Enable */
-#define REG_OED       0xb5 /* Port D Output Enable */
-#define REG_OEE       0xb6 /* Port E Output Enable */
-
-#endif
-
-/***************************************************************************
- * USB API description (reverse engineered)
- ***************************************************************************
-
-Transaction flow:
-=================
-BULK[00001] >>> REQUEST PACKET 64 bytes
-BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY)
-BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY)
-
-General reply packet(s) are always used if not own reply defined.
-
-============================================================================
-| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY)
-============================================================================
-|    00 | reply data (if any) from previous transaction
-|       | Just same reply packet as returned during previous transaction.
-|       | Needed only if reply is missed in previous transaction.
-|       | Just skip normally.
-----------------------------------------------------------------------------
-| 01-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY)
-============================================================================
-|    00 | reply data (if any)
-----------------------------------------------------------------------------
-| 01-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | I2C WRITE REQUEST PACKET
-============================================================================
-|    00 | 0x31 I2C write command
-----------------------------------------------------------------------------
-|    01 | i2c address
-----------------------------------------------------------------------------
-|    02 | data length
-|       | 0x02 (for typical I2C reg / val pair)
-----------------------------------------------------------------------------
-|    03 | 0x01
-----------------------------------------------------------------------------
-| 04-   | data
-----------------------------------------------------------------------------
-|   -59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | I2C READ REQUEST PACKET
-============================================================================
-|    00 | 0x33 I2C read command
-----------------------------------------------------------------------------
-|    01 | i2c address + 1
-----------------------------------------------------------------------------
-|    02 | register
-----------------------------------------------------------------------------
-|    03 | 0x00
-----------------------------------------------------------------------------
-|    04 | 0x00
-----------------------------------------------------------------------------
-|    05 | data length
-----------------------------------------------------------------------------
-| 06-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET
-============================================================================
-|    00 | 0xb1 register write command
-----------------------------------------------------------------------------
-| 01-02 | register
-----------------------------------------------------------------------------
-|    03 | 0x01
-----------------------------------------------------------------------------
-|    04 | value
-----------------------------------------------------------------------------
-| 05-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET
-============================================================================
-|    00 | 0xb0 register read command
-----------------------------------------------------------------------------
-| 01-02 | register
-----------------------------------------------------------------------------
-|    03 | 0x01
-----------------------------------------------------------------------------
-| 04-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | LED CONTROL REQUEST PACKET
-============================================================================
-|    00 | 0x16 LED and IR control command
-----------------------------------------------------------------------------
-|    01 | 0x01 (LED)
-----------------------------------------------------------------------------
-|    03 | 0x00 blink
-|       | 0x01 lights continuously
-----------------------------------------------------------------------------
-|    04 | blink interval
-|       | 0x00 fastest (looks like LED lights continuously)
-|       | 0xff slowest
-----------------------------------------------------------------------------
-| 05-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | IR CONTROL REQUEST PACKET
-============================================================================
-|    00 | 0x16 LED and IR control command
-----------------------------------------------------------------------------
-|    01 | 0x02 (IR)
-----------------------------------------------------------------------------
-|    03 | 0x00 IR disabled
-|       | 0x01 IR enabled
-----------------------------------------------------------------------------
-| 04-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | STREAMING CONTROL REQUEST PACKET
-============================================================================
-|    00 | 0x12 streaming control command
-----------------------------------------------------------------------------
-|    01 | 0x00 streaming disabled
-|       | 0x01 streaming enabled
-----------------------------------------------------------------------------
-|    02 | 0x00
-----------------------------------------------------------------------------
-| 03-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | REMOTE CONTROL REQUEST PACKET
-============================================================================
-|    00 | 0x41 remote control command
-----------------------------------------------------------------------------
-| 01-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | REMOTE CONTROL REPLY PACKET
-============================================================================
-|    00 | 0x00 code not received
-|       | 0x01 code received
-----------------------------------------------------------------------------
-|    01 | remote control code
-----------------------------------------------------------------------------
-| 02-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | GET HARDWARE INFO REQUEST PACKET
-============================================================================
-|    00 | 0x19 get hardware info command
-----------------------------------------------------------------------------
-| 01-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | GET HARDWARE INFO REPLY PACKET
-============================================================================
-|    00 | hardware id
-----------------------------------------------------------------------------
-| 01-02 | firmware version
-----------------------------------------------------------------------------
-| 03-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-============================================================================
-| 00-63 | SMART CARD READER PACKET
-============================================================================
-|    00 | 0x34 smart card reader command
-----------------------------------------------------------------------------
-|    xx |
-----------------------------------------------------------------------------
-| xx-59 | don't care
-----------------------------------------------------------------------------
-|    60 | packet sequence number
-----------------------------------------------------------------------------
-| 61-63 | don't care
-----------------------------------------------------------------------------
-
-*/
diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c
deleted file mode 100644 (file)
index 05f2a86..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
- *
- * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "au6610.h"
-#include "zl10353.h"
-#include "qt1010.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
-                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       int ret;
-       u16 index;
-       u8 *usb_buf;
-
-       /*
-        * allocate enough for all known requests,
-        * read returns 5 and write 6 bytes
-        */
-       usb_buf = kmalloc(6, GFP_KERNEL);
-       if (!usb_buf)
-               return -ENOMEM;
-
-       switch (wlen) {
-       case 1:
-               index = wbuf[0] << 8;
-               break;
-       case 2:
-               index = wbuf[0] << 8;
-               index += wbuf[1];
-               break;
-       default:
-               pr_err("%s: wlen = %d, aborting\n", KBUILD_MODNAME, wlen);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
-                             USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
-                             usb_buf, 6, AU6610_USB_TIMEOUT);
-       if (ret < 0)
-               goto error;
-
-       switch (operation) {
-       case AU6610_REQ_I2C_READ:
-       case AU6610_REQ_USB_READ:
-               /* requested value is always 5th byte in buffer */
-               rbuf[0] = usb_buf[4];
-       }
-error:
-       kfree(usb_buf);
-       return ret;
-}
-
-static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr,
-                         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       u8 request;
-       u8 wo = (rbuf == NULL || rlen == 0); /* write-only */
-
-       if (wo) {
-               request = AU6610_REQ_I2C_WRITE;
-       } else { /* rw */
-               request = AU6610_REQ_I2C_READ;
-       }
-
-       return au6610_usb_msg(d, request, addr, wbuf, wlen, rbuf, rlen);
-}
-
-
-/* I2C */
-static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                          int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-       if (num > 2)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               /* write/read request */
-               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-                       if (au6610_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 (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
-                                              msg[i].len, NULL, 0) < 0)
-                               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-
-static u32 au6610_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm au6610_i2c_algo = {
-       .master_xfer   = au6610_i2c_xfer,
-       .functionality = au6610_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-static struct zl10353_config au6610_zl10353_config = {
-       .demod_address = 0x0f,
-       .no_tuner = 1,
-       .parallel_ts = 1,
-};
-
-static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       adap->fe[0] = dvb_attach(zl10353_attach, &au6610_zl10353_config,
-                       &adap_to_d(adap)->i2c_adap);
-       if (adap->fe[0] == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-
-static struct qt1010_config au6610_qt1010_config = {
-       .i2c_address = 0x62
-};
-
-static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       return dvb_attach(qt1010_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &au6610_qt1010_config) == NULL ? -ENODEV : 0;
-}
-
-static int au6610_init(struct dvb_usb_device *d)
-{
-       /* TODO: this functionality belongs likely to the streaming control */
-       /* bInterfaceNumber 0, bAlternateSetting 5 */
-       return usb_set_interface(d->udev, 0, 5);
-}
-
-static struct dvb_usb_device_properties au6610_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-
-       .i2c_algo = &au6610_i2c_algo,
-       .frontend_attach = au6610_zl10353_frontend_attach,
-       .tuner_attach = au6610_qt1010_tuner_attach,
-       .init = au6610_init,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(0x82, 5, 40, 942, 1),
-               },
-       },
-};
-
-static const struct usb_device_id au6610_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110,
-               &au6610_props, "Sigmatek DVB-110", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, au6610_id_table);
-
-static struct usb_driver au6610_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = au6610_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(au6610_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/au6610.h b/drivers/media/dvb/dvb-usb/au6610.h
deleted file mode 100644 (file)
index ea337bf..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
- *
- * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef AU6610_H
-#define AU6610_H
-#include "dvb_usb.h"
-
-#define AU6610_REQ_I2C_WRITE   0x14
-#define AU6610_REQ_I2C_READ    0x13
-#define AU6610_REQ_USB_WRITE   0x16
-#define AU6610_REQ_USB_READ    0x15
-
-#define AU6610_USB_TIMEOUT 1000
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
deleted file mode 100644 (file)
index 84ff4a9..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Intel CE6230 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "ce6230.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
-{
-       int ret;
-       unsigned int pipe;
-       u8 request;
-       u8 requesttype;
-       u16 value;
-       u16 index;
-       u8 *buf;
-
-       request = req->cmd;
-       value = req->value;
-       index = req->index;
-
-       switch (req->cmd) {
-       case I2C_READ:
-       case DEMOD_READ:
-       case REG_READ:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
-               break;
-       case I2C_WRITE:
-       case DEMOD_WRITE:
-       case REG_WRITE:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
-               break;
-       default:
-               pr_debug("%s: unknown command=%02x\n", __func__, req->cmd);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       buf = kmalloc(req->data_len, GFP_KERNEL);
-       if (!buf) {
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
-               /* write */
-               memcpy(buf, req->data, req->data_len);
-               pipe = usb_sndctrlpipe(d->udev, 0);
-       } else {
-               /* read */
-               pipe = usb_rcvctrlpipe(d->udev, 0);
-       }
-
-       msleep(1); /* avoid I2C errors */
-
-       ret = usb_control_msg(d->udev, pipe, request, requesttype, value, index,
-                       buf, req->data_len, CE6230_USB_TIMEOUT);
-
-       ce6230_debug_dump(request, requesttype, value, index, buf,
-                       req->data_len);
-
-       if (ret < 0)
-               pr_err("%s: usb_control_msg() failed=%d\n", KBUILD_MODNAME,
-                               ret);
-       else
-               ret = 0;
-
-       /* read request, copy returned data to return buf */
-       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
-               memcpy(req->data, buf, req->data_len);
-
-       kfree(buf);
-error:
-       return ret;
-}
-
-/* I2C */
-static struct zl10353_config ce6230_zl10353_config;
-
-static int ce6230_i2c_master_xfer(struct i2c_adapter *adap,
-               struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int ret = 0, i = 0;
-       struct usb_req req;
-
-       if (num > 2)
-               return -EOPNOTSUPP;
-
-       memset(&req, 0, sizeof(req));
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       while (i < num) {
-               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-                       if (msg[i].addr ==
-                               ce6230_zl10353_config.demod_address) {
-                               req.cmd = DEMOD_READ;
-                               req.value = msg[i].addr >> 1;
-                               req.index = msg[i].buf[0];
-                               req.data_len = msg[i+1].len;
-                               req.data = &msg[i+1].buf[0];
-                               ret = ce6230_ctrl_msg(d, &req);
-                       } else {
-                               pr_err("%s: I2C read not implemented\n",
-                                               KBUILD_MODNAME);
-                               ret = -EOPNOTSUPP;
-                       }
-                       i += 2;
-               } else {
-                       if (msg[i].addr ==
-                               ce6230_zl10353_config.demod_address) {
-                               req.cmd = DEMOD_WRITE;
-                               req.value = msg[i].addr >> 1;
-                               req.index = msg[i].buf[0];
-                               req.data_len = msg[i].len-1;
-                               req.data = &msg[i].buf[1];
-                               ret = ce6230_ctrl_msg(d, &req);
-                       } else {
-                               req.cmd = I2C_WRITE;
-                               req.value = 0x2000 + (msg[i].addr >> 1);
-                               req.index = 0x0000;
-                               req.data_len = msg[i].len;
-                               req.data = &msg[i].buf[0];
-                               ret = ce6230_ctrl_msg(d, &req);
-                       }
-                       i += 1;
-               }
-               if (ret)
-                       break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return ret ? ret : i;
-}
-
-static u32 ce6230_i2c_functionality(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm ce6230_i2c_algorithm = {
-       .master_xfer   = ce6230_i2c_master_xfer,
-       .functionality = ce6230_i2c_functionality,
-};
-
-/* Callbacks for DVB USB */
-static struct zl10353_config ce6230_zl10353_config = {
-       .demod_address = 0x1e,
-       .adc_clock = 450000,
-       .if2 = 45700,
-       .no_tuner = 1,
-       .parallel_ts = 1,
-       .clock_ctl_1 = 0x34,
-       .pll_0 = 0x0e,
-};
-
-static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       pr_debug("%s:\n", __func__);
-
-       adap->fe[0] = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
-                       &adap_to_d(adap)->i2c_adap);
-       if (adap->fe[0] == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-
-static struct mxl5005s_config ce6230_mxl5003s_config = {
-       .i2c_address     = 0xc6,
-       .if_freq         = IF_FREQ_4570000HZ,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_DEFAULT,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       int ret;
-
-       pr_debug("%s:\n", __func__);
-
-       ret = dvb_attach(mxl5005s_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
-       return ret;
-}
-
-static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       int ret;
-
-       pr_debug("%s: onoff=%d\n", __func__, onoff);
-
-       /* InterfaceNumber 1 / AlternateSetting 0     idle
-          InterfaceNumber 1 / AlternateSetting 1     streaming */
-       ret = usb_set_interface(d->udev, 1, onoff);
-       if (ret)
-               pr_err("%s: usb_set_interface() failed=%d\n", KBUILD_MODNAME,
-                               ret);
-
-       return ret;
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties ce6230_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .bInterfaceNumber = 1,
-
-       .i2c_algo = &ce6230_i2c_algorithm,
-       .power_ctrl = ce6230_power_ctrl,
-       .frontend_attach = ce6230_zl10353_frontend_attach,
-       .tuner_attach = ce6230_mxl5003s_tuner_attach,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = {
-                               .type = USB_BULK,
-                               .count = 6,
-                               .endpoint = 0x82,
-                               .u = {
-                                       .bulk = {
-                                               .buffersize = (16 * 512),
-                                       }
-                               }
-                       },
-               }
-       },
-};
-
-static const struct usb_device_id ce6230_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500,
-               &ce6230_props, "Intel CE9500 reference design", NULL) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310,
-               &ce6230_props, "AVerMedia A310 USB 2.0 DVB-T tuner", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, ce6230_id_table);
-
-static struct usb_driver ce6230_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = ce6230_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(ce6230_usb_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Intel CE6230 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ce6230.h b/drivers/media/dvb/dvb-usb/ce6230.h
deleted file mode 100644 (file)
index 42d7544..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Intel CE6230 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef CE6230_H
-#define CE6230_H
-
-#include "dvb_usb.h"
-#include "zl10353.h"
-#include "mxl5005s.h"
-
-#define ce6230_debug_dump(r, t, v, i, b, l) { \
-       char *direction; \
-       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
-               direction = ">>>"; \
-       else \
-               direction = "<<<"; \
-       pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s [%d bytes]\n", \
-                        __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
-                       l & 0xff, l >> 8, direction, l); \
-}
-
-#define CE6230_USB_TIMEOUT 1000
-
-struct usb_req {
-       u8  cmd;       /* [1] */
-       u16 value;     /* [2|3] */
-       u16 index;     /* [4|5] */
-       u16 data_len;  /* [6|7] */
-       u8  *data;
-};
-
-enum ce6230_cmd {
-       CONFIG_READ          = 0xd0, /* rd 0 (unclear) */
-       UNKNOWN_WRITE        = 0xc7, /* wr 7 (unclear) */
-       I2C_READ             = 0xd9, /* rd 9 (unclear) */
-       I2C_WRITE            = 0xca, /* wr a */
-       DEMOD_READ           = 0xdb, /* rd b */
-       DEMOD_WRITE          = 0xcc, /* wr c */
-       REG_READ             = 0xde, /* rd e */
-       REG_WRITE            = 0xcf, /* wr f */
-};
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb.h b/drivers/media/dvb/dvb-usb/dvb_usb.h
deleted file mode 100644 (file)
index 773817b..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * DVB USB framework
- *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License along
- *    with this program; if not, write to the Free Software Foundation, Inc.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DVB_USB_H
-#define DVB_USB_H
-
-#include <linux/usb/input.h>
-#include <linux/firmware.h>
-#include <media/rc-core.h>
-
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
-#include "dvb-usb-ids.h"
-
-/*
- * device file: /dev/dvb/adapter[0-1]/frontend[0-2]
- *
- * |-- device
- * |   |-- adapter0
- * |   |   |-- frontend0
- * |   |   |-- frontend1
- * |   |   `-- frontend2
- * |   `-- adapter1
- * |       |-- frontend0
- * |       |-- frontend1
- * |       `-- frontend2
- *
- *
- * Commonly used variable names:
- * d = pointer to device (struct dvb_usb_device *)
- * adap = pointer to adapter (struct dvb_usb_adapter *)
- * fe = pointer to frontend (struct dvb_frontend *)
- *
- * Use macros defined in that file to resolve needed pointers.
- */
-
-/* helper macros for every DVB USB driver use */
-#define adap_to_d(adap) (container_of(adap, struct dvb_usb_device, \
-               adapter[adap->id]))
-#define adap_to_priv(adap) (adap_to_d(adap)->priv)
-#define fe_to_adap(fe) ((struct dvb_usb_adapter *) ((fe)->dvb->priv))
-#define fe_to_d(fe) (adap_to_d(fe_to_adap(fe)))
-#define fe_to_priv(fe) (fe_to_d(fe)->priv)
-#define d_to_priv(d) (d->priv)
-
-#define DVB_USB_STREAM_BULK(endpoint_, count_, size_) { \
-       .type = USB_BULK, \
-       .count = count_, \
-       .endpoint = endpoint_, \
-       .u = { \
-               .bulk = { \
-                       .buffersize = size_, \
-               } \
-       } \
-}
-
-#define DVB_USB_STREAM_ISOC(endpoint_, count_, frames_, size_, interval_) { \
-       .type = USB_ISOC, \
-       .count = count_, \
-       .endpoint = endpoint_, \
-       .u = { \
-               .isoc = { \
-                       .framesperurb = frames_, \
-                       .framesize = size_,\
-                       .interval = interval_, \
-               } \
-       } \
-}
-
-#define DVB_USB_DEVICE(vend, prod, props_, name_, rc) \
-       .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
-       .idVendor = (vend), \
-       .idProduct = (prod), \
-       .driver_info = (kernel_ulong_t) &((const struct dvb_usb_driver_info) { \
-               .props = (props_), \
-               .name = (name_), \
-               .rc_map = (rc), \
-       })
-
-struct dvb_usb_device;
-struct dvb_usb_adapter;
-
-/**
- * structure for carrying all needed data from the device driver to the general
- * dvb usb routines
- * @name: device name
- * @rc_map: name of rc codes table
- * @props: structure containing all device properties
- */
-struct dvb_usb_driver_info {
-       const char *name;
-       const char *rc_map;
-       const struct dvb_usb_device_properties *props;
-};
-
-/**
- * structure for remote controller configuration
- * @map_name: name of rc codes table
- * @allowed_protos: protocol(s) supported by the driver
- * @change_protocol: callback to change protocol
- * @query: called to query an event from the device
- * @interval: time in ms between two queries
- * @driver_type: used to point if a device supports raw mode
- * @bulk_mode: device supports bulk mode for rc (disable polling mode)
- */
-struct dvb_usb_rc {
-       const char *map_name;
-       u64 allowed_protos;
-       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
-       int (*query) (struct dvb_usb_device *d);
-       unsigned int interval;
-       const enum rc_driver_type driver_type;
-       bool bulk_mode;
-};
-
-/**
- * usb streaming configration for adapter
- * @type: urb type
- * @count: count of used urbs
- * @endpoint: stream usb endpoint number
- */
-struct usb_data_stream_properties {
-#define USB_BULK  1
-#define USB_ISOC  2
-       u8 type;
-       u8 count;
-       u8 endpoint;
-
-       union {
-               struct {
-                       unsigned int buffersize; /* per URB */
-               } bulk;
-               struct {
-                       int framesperurb;
-                       int framesize;
-                       int interval;
-               } isoc;
-       } u;
-};
-
-/**
- * properties of dvb usb device adapter
- * @caps: adapter capabilities
- * @pid_filter_count: pid count of adapter pid-filter
- * @pid_filter_ctrl: called to enable/disable pid-filter
- * @pid_filter: called to set/unset pid for filtering
- * @stream: adapter usb stream configuration
- */
-#define MAX_NO_OF_FE_PER_ADAP 3
-struct dvb_usb_adapter_properties {
-#define DVB_USB_ADAP_HAS_PID_FILTER               0x01
-#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
-#define DVB_USB_ADAP_NEED_PID_FILTERING           0x04
-       u8 caps;
-
-       u8 pid_filter_count;
-       int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
-       int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
-
-       struct usb_data_stream_properties stream;
-};
-
-/**
- * struct dvb_usb_device_properties - properties of a dvb-usb-device
- * @driver_name: name of the owning driver module
- * @owner: owner of the dvb_adapter
- * @adapter_nr: values from the DVB_DEFINE_MOD_OPT_ADAPTER_NR() macro
- * @bInterfaceNumber: usb interface number driver binds
- * @size_of_priv: bytes allocated for the driver private data
- * @generic_bulk_ctrl_endpoint: bulk control endpoint number for sent
- * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for
- *  receive
- * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message
- * @identify_state: called to determine the firmware state (cold or warm) and
- *  return possible firmware file name to be loaded
- * @firmware: name of the firmware file to be loaded
- * @download_firmware: called to download the firmware
- * @i2c_algo: i2c_algorithm if the device has i2c-adapter
- * @num_adapters: dvb usb device adapter count
- * @get_adapter_count: called to resolve adapter count
- * @adapter: array of all adapter properties of device
- * @power_ctrl: called to enable/disable power of the device
- * @read_config: called to resolve device configuration
- * @read_mac_address: called to resolve adapter mac-address
- * @frontend_attach: called to attach the possible frontends
- * @tuner_attach: called to attach the possible tuners
- * @frontend_ctrl: called to power on/off active frontend
- * @streaming_ctrl: called to start/stop the usb streaming of adapter
- * @fe_ioctl_override: frontend ioctl override. avoid using that is possible
- * @init: called after adapters are created in order to finalize device
- *  configuration
- * @exit: called when driver is unloaded
- * @get_rc_config: called to resolve used remote controller configuration
- * @get_stream_config: called to resolve input and output stream configuration
- *  of the adapter just before streaming is started. input stream is transport
- *  stream from the demodulator and output stream is usb stream to host.
- */
-#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
-struct dvb_usb_device_properties {
-       const char *driver_name;
-       struct module *owner;
-       short *adapter_nr;
-
-       u8 bInterfaceNumber;
-       unsigned int size_of_priv;
-       u8 generic_bulk_ctrl_endpoint;
-       u8 generic_bulk_ctrl_endpoint_response;
-       unsigned int generic_bulk_ctrl_delay;
-
-#define WARM                  0
-#define COLD                  1
-       int (*identify_state) (struct dvb_usb_device *, const char **);
-       const char *firmware;
-#define RECONNECTS_USB        1
-       int (*download_firmware) (struct dvb_usb_device *,
-                       const struct firmware *);
-
-       struct i2c_algorithm *i2c_algo;
-
-       unsigned int num_adapters;
-       int (*get_adapter_count) (struct dvb_usb_device *);
-       struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
-       int (*power_ctrl) (struct dvb_usb_device *, int);
-       int (*read_config) (struct dvb_usb_device *d);
-       int (*read_mac_address) (struct dvb_usb_adapter *, u8 []);
-       int (*frontend_attach) (struct dvb_usb_adapter *);
-       int (*tuner_attach) (struct dvb_usb_adapter *);
-       int (*frontend_ctrl) (struct dvb_frontend *, int);
-       int (*streaming_ctrl) (struct dvb_frontend *, int);
-       int (*fe_ioctl_override) (struct dvb_frontend *,
-                       unsigned int, void *, unsigned int);
-       int (*init) (struct dvb_usb_device *);
-       void (*exit) (struct dvb_usb_device *);
-       int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *);
-#define DVB_USB_FE_TS_TYPE_188        0
-#define DVB_USB_FE_TS_TYPE_204        1
-#define DVB_USB_FE_TS_TYPE_RAW        2
-       int (*get_stream_config) (struct dvb_frontend *,  u8 *,
-                       struct usb_data_stream_properties *);
-};
-
-/**
- * generic object of an usb stream
- * @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
- */
-#define MAX_NO_URBS_FOR_DATA_STREAM 10
-struct usb_data_stream {
-       struct usb_device *udev;
-       struct usb_data_stream_properties props;
-
-#define USB_STATE_INIT    0x00
-#define USB_STATE_URB_BUF 0x01
-       u8 state;
-
-       void (*complete) (struct usb_data_stream *, u8 *, size_t);
-
-       struct urb    *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
-       int            buf_num;
-       unsigned long  buf_size;
-       u8            *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
-       dma_addr_t     dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
-
-       int urbs_initialized;
-       int urbs_submitted;
-
-       void *user_priv;
-};
-
-/**
- * dvb adapter object on dvb usb device
- * @props: pointer to adapter properties
- * @stream: adapter the usb data stream
- * @id: index of this adapter (starting with 0)
- * @ts_type: transport stream, input stream, type
- * @pid_filtering: is hardware pid_filtering used or not
- * @feed_count: current feed count
- * @max_feed_count: maimum feed count device can handle
- * @dvb_adap: adapter dvb_adapter
- * @dmxdev: adapter dmxdev
- * @demux: adapter software demuxer
- * @dvb_net: adapter dvb_net interfaces
- * @sync_mutex: mutex used to sync control and streaming of the adapter
- * @fe: adapter frontends
- * @fe_init: rerouted frontend-init function
- * @fe_sleep: rerouted frontend-sleep function
- */
-struct dvb_usb_adapter {
-       const struct dvb_usb_adapter_properties *props;
-       struct usb_data_stream stream;
-       u8 id;
-       u8 ts_type;
-       bool pid_filtering;
-       u8 feed_count;
-       u8 max_feed_count;
-       s8 active_fe;
-
-       /* dvb */
-       struct dvb_adapter   dvb_adap;
-       struct dmxdev        dmxdev;
-       struct dvb_demux     demux;
-       struct dvb_net       dvb_net;
-       struct mutex         sync_mutex;
-
-       struct dvb_frontend *fe[MAX_NO_OF_FE_PER_ADAP];
-       int (*fe_init[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
-       int (*fe_sleep[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
-};
-
-/**
- * dvb usb device object
- * @props: device properties
- * @name: device name
- * @rc_map: name of rc codes table
- * @udev: pointer to the device's struct usb_device
- * @intf: pointer to the device's usb interface
- * @rc: remote controller configuration
- * @probe_work: work to defer .probe()
- * @powered: indicated whether the device is power or not
- * @usb_mutex: mutex for usb control messages
- * @i2c_mutex: mutex for i2c-transfers
- * @i2c_adap: device's i2c-adapter
- * @rc_dev: rc device for the remote control
- * @rc_query_work: work for polling remote
- * @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 {
-       const struct dvb_usb_device_properties *props;
-       const char *name;
-       const char *rc_map;
-
-       struct usb_device *udev;
-       struct usb_interface *intf;
-       struct dvb_usb_rc rc;
-       struct work_struct probe_work;
-       pid_t work_pid;
-       int powered;
-
-       /* locking */
-       struct mutex usb_mutex;
-
-       /* i2c */
-       struct mutex i2c_mutex;
-       struct i2c_adapter i2c_adap;
-
-       struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
-
-       /* remote control */
-       struct rc_dev *rc_dev;
-       char rc_phys[64];
-       struct delayed_work rc_query_work;
-
-       void *priv;
-};
-
-extern int dvb_usbv2_probe(struct usb_interface *,
-               const struct usb_device_id *);
-extern void dvb_usbv2_disconnect(struct usb_interface *);
-extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t);
-extern int dvb_usbv2_resume(struct usb_interface *);
-
-/* the generic read/write method for device control */
-extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16);
-extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_common.h b/drivers/media/dvb/dvb-usb/dvb_usb_common.h
deleted file mode 100644 (file)
index 45f0709..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * DVB USB framework
- *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License along
- *    with this program; if not, write to the Free Software Foundation, Inc.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DVB_USB_COMMON_H
-#define DVB_USB_COMMON_H
-
-#include "dvb_usb.h"
-
-/* commonly used  methods */
-extern int usb_urb_initv2(struct usb_data_stream *stream,
-               const struct usb_data_stream_properties *props);
-extern int usb_urb_exitv2(struct usb_data_stream *stream);
-extern int usb_urb_submitv2(struct usb_data_stream *stream,
-               struct usb_data_stream_properties *props);
-extern int usb_urb_killv2(struct usb_data_stream *stream);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_core.c b/drivers/media/dvb/dvb-usb/dvb_usb_core.c
deleted file mode 100644 (file)
index 3224621..0000000
+++ /dev/null
@@ -1,999 +0,0 @@
-/*
- * DVB USB framework
- *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License along
- *    with this program; if not, write to the Free Software Foundation, Inc.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "dvb_usb_common.h"
-
-int dvb_usbv2_disable_rc_polling;
-module_param_named(disable_rc_polling, dvb_usbv2_disable_rc_polling, int, 0644);
-MODULE_PARM_DESC(disable_rc_polling,
-               "disable remote control polling (default: 0)");
-static int dvb_usb_force_pid_filter_usage;
-module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage,
-               int, 0444);
-MODULE_PARM_DESC(force_pid_filter_usage, "force all DVB USB devices to use a " \
-               "PID filter, if any (default: 0)");
-
-static int dvb_usbv2_download_firmware(struct dvb_usb_device *d, const char *name)
-{
-       int ret;
-       const struct firmware *fw;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (!d->props->download_firmware) {
-               ret = -EINVAL;
-               goto err;
-       }
-
-       ret = request_firmware(&fw, name, &d->udev->dev);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: Did not find the firmware file "\
-                               "'%s'. Please see linux/Documentation/dvb/ " \
-                               "for more details on firmware-problems. " \
-                               "Status %d\n", KBUILD_MODNAME, name, ret);
-               goto err;
-       }
-
-       dev_info(&d->udev->dev, "%s: downloading firmware from file '%s'\n",
-                       KBUILD_MODNAME, name);
-
-       ret = d->props->download_firmware(d, fw);
-       release_firmware(fw);
-       if (ret < 0)
-               goto err;
-
-       return ret;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usbv2_i2c_init(struct dvb_usb_device *d)
-{
-       int ret;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (!d->props->i2c_algo)
-               return 0;
-
-       strlcpy(d->i2c_adap.name, d->name, sizeof(d->i2c_adap.name));
-       d->i2c_adap.algo = d->props->i2c_algo;
-       d->i2c_adap.dev.parent = &d->udev->dev;
-       i2c_set_adapdata(&d->i2c_adap, d);
-
-       ret = i2c_add_adapter(&d->i2c_adap);
-       if (ret < 0) {
-               d->i2c_adap.algo = NULL;
-               dev_err(&d->udev->dev, "%s: i2c_add_adapter() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               goto err;
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usbv2_i2c_exit(struct dvb_usb_device *d)
-{
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (d->i2c_adap.algo)
-               i2c_del_adapter(&d->i2c_adap);
-
-       return 0;
-}
-
-static void dvb_usb_read_remote_control(struct work_struct *work)
-{
-       struct dvb_usb_device *d = container_of(work,
-                       struct dvb_usb_device, rc_query_work.work);
-       int ret;
-
-       /*
-        * When the parameter has been set to 1 via sysfs while the
-        * driver was running, or when bulk mode is enabled after IR init.
-        */
-       if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
-               return;
-
-       ret = d->rc.query(d);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: rc.query() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               return; /* stop polling */
-       }
-
-       schedule_delayed_work(&d->rc_query_work,
-                       msecs_to_jiffies(d->rc.interval));
-}
-
-static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
-{
-       int ret;
-       struct rc_dev *dev;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
-               return 0;
-
-       d->rc.map_name = d->rc_map;
-       ret = d->props->get_rc_config(d, &d->rc);
-       if (ret < 0)
-               goto err;
-
-       /* disable rc when there is no keymap defined */
-       if (!d->rc.map_name)
-               return 0;
-
-       dev = rc_allocate_device();
-       if (!dev) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       dev->dev.parent = &d->udev->dev;
-       dev->input_name = d->name;
-       usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
-       strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
-       dev->input_phys = d->rc_phys;
-       usb_to_input_id(d->udev, &dev->input_id);
-       /* TODO: likely RC-core should took const char * */
-       dev->driver_name = (char *) d->props->driver_name;
-       dev->map_name = d->rc.map_name;
-       dev->driver_type = d->rc.driver_type;
-       dev->allowed_protos = d->rc.allowed_protos;
-       dev->change_protocol = d->rc.change_protocol;
-       dev->priv = d;
-
-       ret = rc_register_device(dev);
-       if (ret < 0) {
-               rc_free_device(dev);
-               goto err;
-       }
-
-       d->rc_dev = dev;
-
-       /* start polling if needed */
-       if (d->rc.query && !d->rc.bulk_mode) {
-               /* initialize a work queue for handling polling */
-               INIT_DELAYED_WORK(&d->rc_query_work,
-                               dvb_usb_read_remote_control);
-               dev_info(&d->udev->dev, "%s: schedule remote query interval " \
-                               "to %d msecs\n", KBUILD_MODNAME,
-                               d->rc.interval);
-               schedule_delayed_work(&d->rc_query_work,
-                               msecs_to_jiffies(d->rc.interval));
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
-{
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       if (d->rc_dev) {
-               cancel_delayed_work_sync(&d->rc_query_work);
-               rc_unregister_device(d->rc_dev);
-               d->rc_dev = NULL;
-       }
-
-       return 0;
-}
-
-static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
-               size_t len)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       dvb_dmx_swfilter(&adap->demux, buf, len);
-}
-
-static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
-               size_t len)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       dvb_dmx_swfilter_204(&adap->demux, buf, len);
-}
-
-static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
-               size_t len)
-{
-       struct dvb_usb_adapter *adap = stream->user_priv;
-       dvb_dmx_swfilter_raw(&adap->demux, buf, len);
-}
-
-int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
-{
-       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
-                       adap->id);
-
-       adap->stream.udev = adap_to_d(adap)->udev;
-       adap->stream.user_priv = adap;
-       adap->stream.complete = dvb_usb_data_complete;
-
-       return usb_urb_initv2(&adap->stream, &adap->props->stream);
-}
-
-int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
-{
-       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
-                       adap->id);
-
-       return usb_urb_exitv2(&adap->stream);
-}
-
-static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
-               int count)
-{
-       struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-       dev_dbg(&d->udev->dev, "%s: adap=%d active_fe=%d feed_type=%d " \
-                       "setting pid [%s]: %04x (%04d) at index %d '%s'\n",
-                       __func__, adap->id, adap->active_fe, dvbdmxfeed->type,
-                       adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
-                       dvbdmxfeed->pid, dvbdmxfeed->index,
-                       (count == 1) ? "on" : "off");
-
-       if (adap->active_fe == -1)
-               return -EINVAL;
-
-       adap->feed_count += count;
-
-       /* stop feeding if it is last pid */
-       if (adap->feed_count == 0) {
-               dev_dbg(&d->udev->dev, "%s: stop feeding\n", __func__);
-               usb_urb_killv2(&adap->stream);
-
-               if (d->props->streaming_ctrl) {
-                       ret = d->props->streaming_ctrl(
-                                       adap->fe[adap->active_fe], 0);
-                       if (ret < 0) {
-                               dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
-                                               "failed=%d\n", KBUILD_MODNAME,
-                                               ret);
-                               goto err_mutex_unlock;
-                       }
-               }
-               mutex_unlock(&adap->sync_mutex);
-       }
-
-       /* activate the pid on the device pid filter */
-       if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-                       adap->pid_filtering &&
-                       adap->props->pid_filter)
-               ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
-                               dvbdmxfeed->pid, (count == 1) ? 1 : 0);
-                       if (ret < 0)
-                               dev_err(&d->udev->dev, "%s: pid_filter() " \
-                                               "failed=%d\n", KBUILD_MODNAME,
-                                               ret);
-
-       /* start feeding if it is first pid */
-       if (adap->feed_count == 1 && count == 1) {
-               struct usb_data_stream_properties stream_props;
-               mutex_lock(&adap->sync_mutex);
-               dev_dbg(&d->udev->dev, "%s: start feeding\n", __func__);
-
-               /* resolve input and output streaming paramters */
-               if (d->props->get_stream_config) {
-                       memcpy(&stream_props, &adap->props->stream,
-                               sizeof(struct usb_data_stream_properties));
-                       ret = d->props->get_stream_config(
-                                       adap->fe[adap->active_fe],
-                                       &adap->ts_type, &stream_props);
-                       if (ret < 0)
-                               goto err_mutex_unlock;
-               } else {
-                       stream_props = adap->props->stream;
-               }
-
-               switch (adap->ts_type) {
-               case DVB_USB_FE_TS_TYPE_204:
-                       adap->stream.complete = dvb_usb_data_complete_204;
-                       break;
-               case DVB_USB_FE_TS_TYPE_RAW:
-                       adap->stream.complete = dvb_usb_data_complete_raw;
-                       break;
-               case DVB_USB_FE_TS_TYPE_188:
-               default:
-                       adap->stream.complete = dvb_usb_data_complete;
-                       break;
-               }
-
-               usb_urb_submitv2(&adap->stream, &stream_props);
-
-               if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-                               adap->props->caps &
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
-                               adap->props->pid_filter_ctrl) {
-                       ret = adap->props->pid_filter_ctrl(adap,
-                                       adap->pid_filtering);
-                       if (ret < 0) {
-                               dev_err(&d->udev->dev, "%s: " \
-                                               "pid_filter_ctrl() failed=%d\n",
-                                               KBUILD_MODNAME, ret);
-                               goto err_mutex_unlock;
-                       }
-               }
-
-               if (d->props->streaming_ctrl) {
-                       ret = d->props->streaming_ctrl(
-                                       adap->fe[adap->active_fe], 1);
-                       if (ret < 0) {
-                               dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
-                                               "failed=%d\n", KBUILD_MODNAME,
-                                               ret);
-                               goto err_mutex_unlock;
-                       }
-               }
-       }
-
-       return 0;
-err_mutex_unlock:
-       mutex_unlock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
-}
-
-static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-       return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
-}
-
-int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
-
-       ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
-                       &d->udev->dev, d->props->adapter_nr);
-       if (ret < 0) {
-               dev_dbg(&d->udev->dev, "%s: dvb_register_adapter() failed=%d\n",
-                               __func__, ret);
-               goto err_dvb_register_adapter;
-       }
-
-       adap->dvb_adap.priv = adap;
-
-       if (d->props->read_mac_address) {
-               ret = d->props->read_mac_address(adap,
-                               adap->dvb_adap.proposed_mac);
-               if (ret < 0)
-                       goto err_dvb_dmx_init;
-
-               dev_info(&d->udev->dev, "%s: MAC address: %pM\n",
-                               KBUILD_MODNAME, adap->dvb_adap.proposed_mac);
-       }
-
-       adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-       adap->demux.priv             = adap;
-       adap->demux.filternum        = 0;
-       adap->demux.filternum        = adap->max_feed_count;
-       adap->demux.feednum          = adap->demux.filternum;
-       adap->demux.start_feed       = dvb_usb_start_feed;
-       adap->demux.stop_feed        = dvb_usb_stop_feed;
-       adap->demux.write_to_decoder = NULL;
-       ret = dvb_dmx_init(&adap->demux);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: dvb_dmx_init() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               goto err_dvb_dmx_init;
-       }
-
-       adap->dmxdev.filternum       = adap->demux.filternum;
-       adap->dmxdev.demux           = &adap->demux.dmx;
-       adap->dmxdev.capabilities    = 0;
-       ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: dvb_dmxdev_init() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               goto err_dvb_dmxdev_init;
-       }
-
-       ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: dvb_net_init() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-               goto err_dvb_net_init;
-       }
-
-       mutex_init(&adap->sync_mutex);
-
-       return 0;
-err_dvb_net_init:
-       dvb_dmxdev_release(&adap->dmxdev);
-err_dvb_dmxdev_init:
-       dvb_dmx_release(&adap->demux);
-err_dvb_dmx_init:
-       dvb_unregister_adapter(&adap->dvb_adap);
-err_dvb_register_adapter:
-       adap->dvb_adap.priv = NULL;
-       return ret;
-}
-
-int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
-{
-       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
-                       adap->id);
-
-       if (adap->dvb_adap.priv) {
-               dvb_net_release(&adap->dvb_net);
-               adap->demux.dmx.close(&adap->demux.dmx);
-               dvb_dmxdev_release(&adap->dmxdev);
-               dvb_dmx_release(&adap->demux);
-               dvb_unregister_adapter(&adap->dvb_adap);
-       }
-
-       return 0;
-}
-
-int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       int ret;
-
-       if (onoff)
-               d->powered++;
-       else
-               d->powered--;
-
-       if (d->powered == 0 || (onoff && d->powered == 1)) {
-               /* when switching from 1 to 0 or from 0 to 1 */
-               dev_dbg(&d->udev->dev, "%s: power=%d\n", __func__, onoff);
-               if (d->props->power_ctrl) {
-                       ret = d->props->power_ctrl(d, onoff);
-                       if (ret < 0)
-                               goto err;
-               }
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usb_fe_init(struct dvb_frontend *fe)
-{
-       int ret;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       mutex_lock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
-                       fe->id);
-
-       ret = dvb_usbv2_device_power_ctrl(d, 1);
-       if (ret < 0)
-               goto err;
-
-       if (d->props->frontend_ctrl) {
-               ret = d->props->frontend_ctrl(fe, 1);
-               if (ret < 0)
-                       goto err;
-       }
-
-       if (adap->fe_init[fe->id]) {
-               ret = adap->fe_init[fe->id](fe);
-               if (ret < 0)
-                       goto err;
-       }
-
-       adap->active_fe = fe->id;
-       mutex_unlock(&adap->sync_mutex);
-
-       return 0;
-err:
-       mutex_unlock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       mutex_lock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
-                       fe->id);
-
-       if (adap->fe_sleep[fe->id]) {
-               ret = adap->fe_sleep[fe->id](fe);
-               if (ret < 0)
-                       goto err;
-       }
-
-       if (d->props->frontend_ctrl) {
-               ret = d->props->frontend_ctrl(fe, 0);
-               if (ret < 0)
-                       goto err;
-       }
-
-       ret = dvb_usbv2_device_power_ctrl(d, 0);
-       if (ret < 0)
-               goto err;
-
-       adap->active_fe = -1;
-       mutex_unlock(&adap->sync_mutex);
-
-       return 0;
-err:
-       mutex_unlock(&adap->sync_mutex);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
-{
-       int ret, i, count_registered = 0;
-       struct dvb_usb_device *d = adap_to_d(adap);
-       dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
-
-       memset(adap->fe, 0, sizeof(adap->fe));
-       adap->active_fe = -1;
-
-       if (d->props->frontend_attach) {
-               ret = d->props->frontend_attach(adap);
-               if (ret < 0) {
-                       dev_dbg(&d->udev->dev, "%s: frontend_attach() " \
-                                       "failed=%d\n", __func__, ret);
-                       goto err_dvb_frontend_detach;
-               }
-       } else {
-               dev_dbg(&d->udev->dev, "%s: frontend_attach() do not exists\n",
-                               __func__);
-               ret = 0;
-               goto err;
-       }
-
-       for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
-               adap->fe[i]->id = i;
-               /* re-assign sleep and wakeup functions */
-               adap->fe_init[i] = adap->fe[i]->ops.init;
-               adap->fe[i]->ops.init = dvb_usb_fe_init;
-               adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
-               adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
-
-               ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
-               if (ret < 0) {
-                       dev_err(&d->udev->dev, "%s: frontend%d registration " \
-                                       "failed\n", KBUILD_MODNAME, i);
-                       goto err_dvb_unregister_frontend;
-               }
-
-               count_registered++;
-       }
-
-       if (d->props->tuner_attach) {
-               ret = d->props->tuner_attach(adap);
-               if (ret < 0) {
-                       dev_dbg(&d->udev->dev, "%s: tuner_attach() failed=%d\n",
-                                       __func__, ret);
-                       goto err_dvb_unregister_frontend;
-               }
-       }
-
-       return 0;
-
-err_dvb_unregister_frontend:
-       for (i = count_registered - 1; i >= 0; i--)
-               dvb_unregister_frontend(adap->fe[i]);
-
-err_dvb_frontend_detach:
-       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
-               if (adap->fe[i])
-                       dvb_frontend_detach(adap->fe[i]);
-       }
-
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
-{
-       int i;
-       dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
-                       adap->id);
-
-       for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
-               if (adap->fe[i]) {
-                       dvb_unregister_frontend(adap->fe[i]);
-                       dvb_frontend_detach(adap->fe[i]);
-               }
-       }
-
-       return 0;
-}
-
-static int dvb_usbv2_adapter_init(struct dvb_usb_device *d)
-{
-       struct dvb_usb_adapter *adap;
-       int ret, i, adapter_count;
-
-       /* resolve adapter count */
-       adapter_count = d->props->num_adapters;
-       if (d->props->get_adapter_count) {
-               ret = d->props->get_adapter_count(d);
-               if (ret < 0)
-                       goto err;
-
-               adapter_count = ret;
-       }
-
-       for (i = 0; i < adapter_count; i++) {
-               adap = &d->adapter[i];
-               adap->id = i;
-               adap->props = &d->props->adapter[i];
-
-               /* speed - when running at FULL speed we need a HW PID filter */
-               if (d->udev->speed == USB_SPEED_FULL &&
-                               !(adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
-                       dev_err(&d->udev->dev, "%s: this USB2.0 device " \
-                                       "cannot be run on a USB1.1 port (it " \
-                                       "lacks a hardware PID filter)\n",
-                                       KBUILD_MODNAME);
-                       ret = -ENODEV;
-                       goto err;
-               } else if ((d->udev->speed == USB_SPEED_FULL &&
-                               adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
-                               (adap->props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
-                       dev_info(&d->udev->dev, "%s: will use the device's " \
-                                       "hardware PID filter " \
-                                       "(table count: %d)\n", KBUILD_MODNAME,
-                                       adap->props->pid_filter_count);
-                       adap->pid_filtering  = 1;
-                       adap->max_feed_count = adap->props->pid_filter_count;
-               } else {
-                       dev_info(&d->udev->dev, "%s: will pass the complete " \
-                                       "MPEG2 transport stream to the " \
-                                       "software demuxer\n", KBUILD_MODNAME);
-                       adap->pid_filtering  = 0;
-                       adap->max_feed_count = 255;
-               }
-
-               if (!adap->pid_filtering && dvb_usb_force_pid_filter_usage &&
-                               adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
-                       dev_info(&d->udev->dev, "%s: PID filter enabled by " \
-                                       "module option\n", KBUILD_MODNAME);
-                       adap->pid_filtering  = 1;
-                       adap->max_feed_count = adap->props->pid_filter_count;
-               }
-
-               ret = dvb_usbv2_adapter_stream_init(adap);
-               if (ret)
-                       goto err;
-
-               ret = dvb_usbv2_adapter_dvb_init(adap);
-               if (ret)
-                       goto err;
-
-               ret = dvb_usbv2_adapter_frontend_init(adap);
-               if (ret)
-                       goto err;
-
-               /* use exclusive FE lock if there is multiple shared FEs */
-               if (adap->fe[1])
-                       adap->dvb_adap.mfe_shared = 1;
-
-               adap->dvb_adap.fe_ioctl_override = d->props->fe_ioctl_override;
-       }
-
-       return 0;
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int dvb_usbv2_adapter_exit(struct dvb_usb_device *d)
-{
-       int i;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
-               if (d->adapter[i].props) {
-                       dvb_usbv2_adapter_frontend_exit(&d->adapter[i]);
-                       dvb_usbv2_adapter_dvb_exit(&d->adapter[i]);
-                       dvb_usbv2_adapter_stream_exit(&d->adapter[i]);
-               }
-       }
-
-       return 0;
-}
-
-/* general initialization functions */
-static int dvb_usbv2_exit(struct dvb_usb_device *d)
-{
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       dvb_usbv2_remote_exit(d);
-       dvb_usbv2_adapter_exit(d);
-       dvb_usbv2_i2c_exit(d);
-       kfree(d->priv);
-       kfree(d);
-
-       return 0;
-}
-
-static int dvb_usbv2_init(struct dvb_usb_device *d)
-{
-       int ret;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       dvb_usbv2_device_power_ctrl(d, 1);
-
-       if (d->props->read_config) {
-               ret = d->props->read_config(d);
-               if (ret < 0)
-                       goto err;
-       }
-
-       ret = dvb_usbv2_i2c_init(d);
-       if (ret < 0)
-               goto err;
-
-       ret = dvb_usbv2_adapter_init(d);
-       if (ret < 0)
-               goto err;
-
-       if (d->props->init) {
-               ret = d->props->init(d);
-               if (ret < 0)
-                       goto err;
-       }
-
-       ret = dvb_usbv2_remote_init(d);
-       if (ret < 0)
-               goto err;
-
-       dvb_usbv2_device_power_ctrl(d, 0);
-
-       return 0;
-err:
-       dvb_usbv2_device_power_ctrl(d, 0);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-/*
- * udev, which is used for the firmware downloading, requires we cannot
- * block during module_init(). module_init() calls USB probe() which
- * is this routine. Due to that we delay actual operation using workqueue
- * and return always success here.
- */
-static void dvb_usbv2_init_work(struct work_struct *work)
-{
-       int ret;
-       struct dvb_usb_device *d =
-                       container_of(work, struct dvb_usb_device, probe_work);
-
-       d->work_pid = current->pid;
-       dev_dbg(&d->udev->dev, "%s: work_pid=%d\n", __func__, d->work_pid);
-
-       if (d->props->size_of_priv) {
-               d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL);
-               if (!d->priv) {
-                       dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
-                                       KBUILD_MODNAME);
-                       ret = -ENOMEM;
-                       goto err_usb_driver_release_interface;
-               }
-       }
-
-       if (d->props->identify_state) {
-               const char *name = NULL;
-               ret = d->props->identify_state(d, &name);
-               if (ret == 0) {
-                       ;
-               } else if (ret == COLD) {
-                       dev_info(&d->udev->dev, "%s: found a '%s' in cold " \
-                                       "state\n", KBUILD_MODNAME, d->name);
-
-                       if (!name)
-                               name = d->props->firmware;
-
-                       ret = dvb_usbv2_download_firmware(d, name);
-                       if (ret == 0) {
-                               /* device is warm, continue initialization */
-                               ;
-                       } else if (ret == RECONNECTS_USB) {
-                               /*
-                                * USB core will call disconnect() and then
-                                * probe() as device reconnects itself from the
-                                * USB bus. disconnect() will release all driver
-                                * resources and probe() is called for 'new'
-                                * device. As 'new' device is warm we should
-                                * never go here again.
-                                */
-                               return;
-                       } else {
-                               /*
-                                * Unexpected error. We must unregister driver
-                                * manually from the device, because device is
-                                * already register by returning from probe()
-                                * with success. usb_driver_release_interface()
-                                * finally calls disconnect() in order to free
-                                * resources.
-                                */
-                               goto err_usb_driver_release_interface;
-                       }
-               } else {
-                       goto err_usb_driver_release_interface;
-               }
-       }
-
-       dev_info(&d->udev->dev, "%s: found a '%s' in warm state\n",
-                       KBUILD_MODNAME, d->name);
-
-       ret = dvb_usbv2_init(d);
-       if (ret < 0)
-               goto err_usb_driver_release_interface;
-
-       dev_info(&d->udev->dev, "%s: '%s' successfully initialized and " \
-                       "connected\n", KBUILD_MODNAME, d->name);
-
-       return;
-err_usb_driver_release_interface:
-       dev_info(&d->udev->dev, "%s: '%s' error while loading driver (%d)\n",
-                       KBUILD_MODNAME, d->name, ret);
-       usb_driver_release_interface(to_usb_driver(d->intf->dev.driver),
-                       d->intf);
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
-       return;
-}
-
-int dvb_usbv2_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       int ret;
-       struct dvb_usb_device *d;
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct dvb_usb_driver_info *driver_info =
-                       (struct dvb_usb_driver_info *) id->driver_info;
-
-       dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
-                       intf->cur_altsetting->desc.bInterfaceNumber);
-
-       if (!id->driver_info) {
-               dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME);
-               ret = -ENODEV;
-               goto err;
-       }
-
-       d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
-       if (!d) {
-               dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       d->name = driver_info->name;
-       d->rc_map = driver_info->rc_map;
-       d->udev = udev;
-       d->intf = intf;
-       d->props = driver_info->props;
-
-       if (d->intf->cur_altsetting->desc.bInterfaceNumber !=
-                       d->props->bInterfaceNumber) {
-               ret = -ENODEV;
-               goto err_kfree;
-       }
-
-       mutex_init(&d->usb_mutex);
-       mutex_init(&d->i2c_mutex);
-       INIT_WORK(&d->probe_work, dvb_usbv2_init_work);
-       usb_set_intfdata(intf, d);
-       ret = schedule_work(&d->probe_work);
-       if (ret < 0) {
-               dev_err(&d->udev->dev, "%s: schedule_work() failed\n",
-                               KBUILD_MODNAME);
-               goto err_kfree;
-       }
-
-       return 0;
-err_kfree:
-       kfree(d);
-err:
-       dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-EXPORT_SYMBOL(dvb_usbv2_probe);
-
-void dvb_usbv2_disconnect(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       const char *name = d->name;
-       struct device dev = d->udev->dev;
-       dev_dbg(&d->udev->dev, "%s: pid=%d work_pid=%d\n", __func__,
-                       current->pid, d->work_pid);
-
-       /* ensure initialization work is finished until release resources */
-       if (d->work_pid != current->pid)
-               cancel_work_sync(&d->probe_work);
-
-       if (d->props->exit)
-               d->props->exit(d);
-
-       dvb_usbv2_exit(d);
-
-       dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
-                       KBUILD_MODNAME, name);
-}
-EXPORT_SYMBOL(dvb_usbv2_disconnect);
-
-int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       int i;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       /* stop remote controller poll */
-       if (d->rc.query && !d->rc.bulk_mode)
-               cancel_delayed_work_sync(&d->rc_query_work);
-
-       /* stop streaming */
-       for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
-               if (d->adapter[i].dvb_adap.priv &&
-                               d->adapter[i].active_fe != -1)
-                       usb_urb_killv2(&d->adapter[i].stream);
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(dvb_usbv2_suspend);
-
-int dvb_usbv2_resume(struct usb_interface *intf)
-{
-       struct dvb_usb_device *d = usb_get_intfdata(intf);
-       int i;
-       dev_dbg(&d->udev->dev, "%s:\n", __func__);
-
-       /* start streaming */
-       for (i = 0; i < MAX_NO_OF_ADAPTER_PER_DEVICE; i++) {
-               if (d->adapter[i].dvb_adap.priv &&
-                               d->adapter[i].active_fe != -1)
-                       usb_urb_submitv2(&d->adapter[i].stream, NULL);
-       }
-
-       /* start remote controller poll */
-       if (d->rc.query && !d->rc.bulk_mode)
-               schedule_delayed_work(&d->rc_query_work,
-                               msecs_to_jiffies(d->rc.interval));
-
-       return 0;
-}
-EXPORT_SYMBOL(dvb_usbv2_resume);
-
-MODULE_VERSION("2.0");
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("DVB USB common");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_firmware.c b/drivers/media/dvb/dvb-usb/dvb_usb_firmware.c
deleted file mode 100644 (file)
index 61c3fe9..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/* dvb_usb_firmware.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 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.
- *
- */
-
-#include "dvb_usb.h"
-#include "dvb_usb_firmware.h"
-
-struct usb_cypress_controller {
-       u8 id;
-       const char *name;       /* name of the usb controller */
-       u16 cs_reg;             /* needs to be restarted,
-                                * when the firmware has been downloaded */
-};
-
-static const struct usb_cypress_controller cypress[] = {
-       { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cs_reg = 0x7f92 },
-       { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cs_reg = 0x7f92 },
-       { .id = CYPRESS_FX2,    .name = "Cypress FX2",    .cs_reg = 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, 5000);
-}
-
-int usbv2_cypress_load_firmware(struct usb_device *udev,
-               const struct firmware *fw, int type)
-{
-       struct hexline hx;
-       u8 reset;
-       int ret, pos = 0;
-
-       /* stop the CPU */
-       reset = 1;
-       ret = usb_cypress_writemem(udev, cypress[type].cs_reg, &reset, 1);
-       if (ret != 1)
-               pr_err("%s: could not stop the USB controller CPU",
-                               KBUILD_MODNAME);
-
-       while ((ret = dvb_usbv2_get_hexline(fw, &hx, &pos)) > 0) {
-               pr_debug("%s: writing to address %04x (buffer: %02x %02x)\n",
-                               __func__, hx.addr, hx.len, hx.chk);
-
-               ret = usb_cypress_writemem(udev, hx.addr, hx.data, hx.len);
-               if (ret != hx.len) {
-                       pr_err("%s: error while transferring firmware " \
-                                       "(transferred size=%d, block size=%d)",
-                                       KBUILD_MODNAME, ret, hx.len);
-                       ret = -EINVAL;
-                       break;
-               }
-       }
-       if (ret < 0) {
-               pr_err("%s: firmware download failed at %d with %d",
-                               KBUILD_MODNAME, pos, ret);
-               return ret;
-       }
-
-       if (ret == 0) {
-               /* restart the CPU */
-               reset = 0;
-               if (ret || usb_cypress_writemem(
-                               udev, cypress[type].cs_reg, &reset, 1) != 1) {
-                       pr_err("%s: could not restart the USB controller CPU",
-                                       KBUILD_MODNAME);
-                       ret = -EINVAL;
-               }
-       } else
-               ret = -EIO;
-
-       return ret;
-}
-EXPORT_SYMBOL(usbv2_cypress_load_firmware);
-
-int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
-               int *pos)
-{
-       u8 *b = (u8 *) &fw->data[*pos];
-       int data_offs = 4;
-
-       if (*pos >= fw->size)
-               return 0;
-
-       memset(hx, 0, sizeof(struct hexline));
-
-       hx->len = b[0];
-
-       if ((*pos + hx->len + 4) >= fw->size)
-               return -EINVAL;
-
-       hx->addr = b[1] | (b[2] << 8);
-       hx->type = b[3];
-
-       if (hx->type == 0x04) {
-               /* b[4] and b[5] are the Extended linear address record data
-                * field */
-               hx->addr |= (b[4] << 24) | (b[5] << 16);
-               /*
-               hx->len -= 2;
-               data_offs += 2;
-               */
-       }
-       memcpy(hx->data, &b[data_offs], hx->len);
-       hx->chk = b[hx->len + data_offs];
-
-       *pos += hx->len + 5;
-
-       return *pos;
-}
-EXPORT_SYMBOL(dvb_usbv2_get_hexline);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Cypress firmware download");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_firmware.h b/drivers/media/dvb/dvb-usb/dvb_usb_firmware.h
deleted file mode 100644 (file)
index 358d9d0..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* dvb_usb_firmware.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 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.
- *
- */
-
-#ifndef DVB_USB_FIRMWARE_H
-#define DVB_USB_FIRMWARE_H
-
-#define CYPRESS_AN2135  0
-#define CYPRESS_AN2235  1
-#define CYPRESS_FX2     2
-
-/* commonly used firmware download types and function */
-struct hexline {
-       u8 len;
-       u32 addr;
-       u8 type;
-       u8 data[255];
-       u8 chk;
-};
-extern int usbv2_cypress_load_firmware(struct usb_device *,
-               const struct firmware *, int);
-extern int dvb_usbv2_get_hexline(const struct firmware *,
-               struct hexline *, int *);
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_urb.c b/drivers/media/dvb/dvb-usb/dvb_usb_urb.c
deleted file mode 100644 (file)
index 5f5bdd0..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * DVB USB framework
- *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License along
- *    with this program; if not, write to the Free Software Foundation, Inc.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "dvb_usb_common.h"
-
-#undef DVB_USB_XFER_DEBUG
-int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
-               u16 rlen)
-{
-       int ret, actual_length;
-
-       if (!d || !wbuf || !wlen || !d->props->generic_bulk_ctrl_endpoint ||
-                       !d->props->generic_bulk_ctrl_endpoint_response) {
-               dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, -EINVAL);
-               return -EINVAL;
-       }
-
-       ret = mutex_lock_interruptible(&d->usb_mutex);
-       if (ret < 0)
-               return ret;
-
-#ifdef DVB_USB_XFER_DEBUG
-       print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": >>> ", DUMP_PREFIX_NONE,
-                       32, 1, wbuf, wlen, 0);
-#endif
-       ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
-                       d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
-                       &actual_length, 2000);
-       if (ret < 0)
-               dev_err(&d->udev->dev, "%s: usb_bulk_msg() failed=%d\n",
-                               KBUILD_MODNAME, ret);
-       else
-               ret = actual_length != wlen ? -EIO : 0;
-
-       /* an answer is expected, and no error before */
-       if (!ret && rbuf && rlen) {
-               if (d->props->generic_bulk_ctrl_delay)
-                       usleep_range(d->props->generic_bulk_ctrl_delay,
-                                       d->props->generic_bulk_ctrl_delay
-                                       + 20000);
-
-               ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
-                               d->props->generic_bulk_ctrl_endpoint_response),
-                               rbuf, rlen, &actual_length, 2000);
-               if (ret)
-                       dev_err(&d->udev->dev, "%s: 2nd usb_bulk_msg() " \
-                                       "failed=%d\n", KBUILD_MODNAME, ret);
-
-#ifdef DVB_USB_XFER_DEBUG
-               print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": <<< ",
-                               DUMP_PREFIX_NONE, 32, 1, rbuf, actual_length,
-                               0);
-#endif
-       }
-
-       mutex_unlock(&d->usb_mutex);
-       return ret;
-}
-EXPORT_SYMBOL(dvb_usbv2_generic_rw);
-
-int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
-{
-       return dvb_usbv2_generic_rw(d, buf, len, NULL, 0);
-}
-EXPORT_SYMBOL(dvb_usbv2_generic_write);
diff --git a/drivers/media/dvb/dvb-usb/ec168.c b/drivers/media/dvb/dvb-usb/ec168.c
deleted file mode 100644 (file)
index ab77622..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * E3C EC168 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "ec168.h"
-#include "ec100.h"
-#include "mxl5005s.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
-{
-       int ret;
-       unsigned int pipe;
-       u8 request, requesttype;
-       u8 *buf;
-
-       switch (req->cmd) {
-       case DOWNLOAD_FIRMWARE:
-       case GPIO:
-       case WRITE_I2C:
-       case STREAMING_CTRL:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
-               request = req->cmd;
-               break;
-       case READ_I2C:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
-               request = req->cmd;
-               break;
-       case GET_CONFIG:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
-               request = CONFIG;
-               break;
-       case SET_CONFIG:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
-               request = CONFIG;
-               break;
-       case WRITE_DEMOD:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
-               request = DEMOD_RW;
-               break;
-       case READ_DEMOD:
-               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
-               request = DEMOD_RW;
-               break;
-       default:
-               pr_err("%s: unknown command=%02x\n", KBUILD_MODNAME, req->cmd);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       buf = kmalloc(req->size, GFP_KERNEL);
-       if (!buf) {
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
-               /* write */
-               memcpy(buf, req->data, req->size);
-               pipe = usb_sndctrlpipe(d->udev, 0);
-       } else {
-               /* read */
-               pipe = usb_rcvctrlpipe(d->udev, 0);
-       }
-
-       msleep(1); /* avoid I2C errors */
-
-       ret = usb_control_msg(d->udev, pipe, request, requesttype, req->value,
-               req->index, buf, req->size, EC168_USB_TIMEOUT);
-
-       ec168_debug_dump(request, requesttype, req->value, req->index, buf,
-               req->size);
-
-       if (ret < 0)
-               goto err_dealloc;
-       else
-               ret = 0;
-
-       /* read request, copy returned data to return buf */
-       if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
-               memcpy(req->data, buf, req->size);
-
-       kfree(buf);
-       return ret;
-
-err_dealloc:
-       kfree(buf);
-error:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-/* I2C */
-static struct ec100_config ec168_ec100_config;
-
-static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-       int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct ec168_req req;
-       int i = 0;
-       int ret;
-
-       if (num > 2)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       while (i < num) {
-               if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-                       if (msg[i].addr == ec168_ec100_config.demod_address) {
-                               req.cmd = READ_DEMOD;
-                               req.value = 0;
-                               req.index = 0xff00 + msg[i].buf[0]; /* reg */
-                               req.size = msg[i+1].len; /* bytes to read */
-                               req.data = &msg[i+1].buf[0];
-                               ret = ec168_ctrl_msg(d, &req);
-                               i += 2;
-                       } else {
-                               pr_err("%s: I2C read not implemented\n",
-                                               KBUILD_MODNAME);
-                               ret = -EOPNOTSUPP;
-                               i += 2;
-                       }
-               } else {
-                       if (msg[i].addr == ec168_ec100_config.demod_address) {
-                               req.cmd = WRITE_DEMOD;
-                               req.value = msg[i].buf[1]; /* val */
-                               req.index = 0xff00 + msg[i].buf[0]; /* reg */
-                               req.size = 0;
-                               req.data = NULL;
-                               ret = ec168_ctrl_msg(d, &req);
-                               i += 1;
-                       } else {
-                               req.cmd = WRITE_I2C;
-                               req.value = msg[i].buf[0]; /* val */
-                               req.index = 0x0100 + msg[i].addr; /* I2C addr */
-                               req.size = msg[i].len-1;
-                               req.data = &msg[i].buf[1];
-                               ret = ec168_ctrl_msg(d, &req);
-                               i += 1;
-                       }
-               }
-               if (ret)
-                       goto error;
-
-       }
-       ret = i;
-
-error:
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 ec168_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm ec168_i2c_algo = {
-       .master_xfer   = ec168_i2c_xfer,
-       .functionality = ec168_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-static int ec168_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       int ret;
-       u8 reply;
-       struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
-       pr_debug("%s:\n", __func__);
-
-       ret = ec168_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       pr_debug("%s: reply=%02x\n", __func__, reply);
-
-       if (reply == 0x01)
-               ret = WARM;
-       else
-               ret = COLD;
-
-       return ret;
-error:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int ec168_download_firmware(struct dvb_usb_device *d,
-               const struct firmware *fw)
-{
-       int ret, len, remaining;
-       struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
-       pr_debug("%s:\n", __func__);
-
-       #define LEN_MAX 2048 /* max packet size */
-       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
-               len = remaining;
-               if (len > LEN_MAX)
-                       len = LEN_MAX;
-
-               req.size = len;
-               req.data = (u8 *) &fw->data[fw->size - remaining];
-               req.index = fw->size - remaining;
-
-               ret = ec168_ctrl_msg(d, &req);
-               if (ret) {
-                       pr_err("%s: firmware download failed=%d\n",
-                                       KBUILD_MODNAME, ret);
-                       goto error;
-               }
-       }
-
-       req.size = 0;
-
-       /* set "warm"? */
-       req.cmd = SET_CONFIG;
-       req.value = 0;
-       req.index = 0x0001;
-       ret = ec168_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       /* really needed - no idea what does */
-       req.cmd = GPIO;
-       req.value = 0;
-       req.index = 0x0206;
-       ret = ec168_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       /* activate tuner I2C? */
-       req.cmd = WRITE_I2C;
-       req.value = 0;
-       req.index = 0x00c6;
-       ret = ec168_ctrl_msg(d, &req);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static struct ec100_config ec168_ec100_config = {
-       .demod_address = 0xff, /* not real address, demod is integrated */
-};
-
-static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       pr_debug("%s:\n", __func__);
-       adap->fe[0] = dvb_attach(ec100_attach, &ec168_ec100_config,
-                       &adap_to_d(adap)->i2c_adap);
-       if (adap->fe[0] == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-
-static struct mxl5005s_config ec168_mxl5003s_config = {
-       .i2c_address     = 0xc6,
-       .if_freq         = IF_FREQ_4570000HZ,
-       .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
-       .agc_mode        = MXL_SINGLE_AGC,
-       .tracking_filter = MXL_TF_OFF,
-       .rssi_enable     = MXL_RSSI_ENABLE,
-       .cap_select      = MXL_CAP_SEL_ENABLE,
-       .div_out         = MXL_DIV_OUT_4,
-       .clock_out       = MXL_CLOCK_OUT_DISABLE,
-       .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
-       .top             = MXL5005S_TOP_25P2,
-       .mod_mode        = MXL_DIGITAL_MODE,
-       .if_mode         = MXL_ZERO_IF,
-       .AgcMasterByte   = 0x00,
-};
-
-static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       pr_debug("%s:\n", __func__);
-       return dvb_attach(mxl5005s_attach, adap->fe[0],
-                       &adap_to_d(adap)->i2c_adap,
-                       &ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
-}
-
-static int ec168_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
-       pr_debug("%s: onoff=%d\n", __func__, onoff);
-       if (onoff)
-               req.index = 0x0102;
-       return ec168_ctrl_msg(fe_to_d(fe), &req);
-}
-
-/* DVB USB Driver stuff */
-/* bInterfaceNumber 0 is HID
- * bInterfaceNumber 1 is DVB-T */
-static struct dvb_usb_device_properties ec168_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .bInterfaceNumber = 1,
-
-       .identify_state = ec168_identify_state,
-       .firmware = "dvb-usb-ec168.fw",
-       .download_firmware = ec168_download_firmware,
-
-       .i2c_algo = &ec168_i2c_algo,
-       .frontend_attach = ec168_ec100_frontend_attach,
-       .tuner_attach = ec168_mxl5003s_tuner_attach,
-       .streaming_ctrl = ec168_streaming_ctrl,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x82, 6, 32 * 512),
-               }
-       },
-};
-
-static const struct dvb_usb_driver_info ec168_driver_info = {
-       .name = "E3C EC168 reference design",
-       .props = &ec168_props,
-};
-
-static const struct usb_device_id ec168_id[] = {
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5),
-               .driver_info = (kernel_ulong_t) &ec168_driver_info },
-       {}
-};
-MODULE_DEVICE_TABLE(usb, ec168_id);
-
-static struct usb_driver ec168_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = ec168_id,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(ec168_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("E3C EC168 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ec168.h b/drivers/media/dvb/dvb-usb/ec168.h
deleted file mode 100644 (file)
index 9181236..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * E3C EC168 DVB USB driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef EC168_H
-#define EC168_H
-
-#include "dvb_usb.h"
-
-#define ec168_debug_dump(r, t, v, i, b, l) { \
-       char *direction; \
-       if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
-               direction = ">>>"; \
-       else \
-               direction = "<<<"; \
-       pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s\n", \
-                        __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
-                       l & 0xff, l >> 8, direction); \
-}
-
-#define EC168_USB_TIMEOUT 1000
-
-struct ec168_req {
-       u8  cmd;       /* [1] */
-       u16 value;     /* [2|3] */
-       u16 index;     /* [4|5] */
-       u16 size;      /* [6|7] */
-       u8  *data;
-};
-
-enum ec168_cmd {
-       DOWNLOAD_FIRMWARE    = 0x00,
-       CONFIG               = 0x01,
-       DEMOD_RW             = 0x03,
-       GPIO                 = 0x04,
-       STREAMING_CTRL       = 0x10,
-       READ_I2C             = 0x20,
-       WRITE_I2C            = 0x21,
-       HID_DOWNLOAD         = 0x30,
-       GET_CONFIG,
-       SET_CONFIG,
-       READ_DEMOD,
-       WRITE_DEMOD,
-};
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c
deleted file mode 100644 (file)
index cf29f43..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/* DVB USB compliant linux driver for GL861 USB2.0 devices.
- *
- *     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 "gl861.h"
-
-#include "zl10353.h"
-#include "qt1010.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
-                        u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-       u16 index;
-       u16 value = addr << (8 + 1);
-       int wo = (rbuf == NULL || rlen == 0); /* write-only */
-       u8 req, type;
-
-       if (wo) {
-               req = GL861_REQ_I2C_WRITE;
-               type = GL861_WRITE;
-       } else { /* rw */
-               req = GL861_REQ_I2C_READ;
-               type = GL861_READ;
-       }
-
-       switch (wlen) {
-       case 1:
-               index = wbuf[0];
-               break;
-       case 2:
-               index = wbuf[0];
-               value = value + wbuf[1];
-               break;
-       default:
-               pr_err("%s: wlen=%d, aborting\n", KBUILD_MODNAME, wlen);
-               return -EINVAL;
-       }
-
-       msleep(1); /* avoid I2C errors */
-
-       return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
-                              value, index, rbuf, rlen, 2000);
-}
-
-/* I2C */
-static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                         int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       int i;
-
-       if (num > 2)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               /* write/read request */
-               if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-                       if (gl861_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 (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
-                                         msg[i].len, NULL, 0) < 0)
-                               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 gl861_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm gl861_i2c_algo = {
-       .master_xfer   = gl861_i2c_xfer,
-       .functionality = gl861_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-static struct zl10353_config gl861_zl10353_config = {
-       .demod_address = 0x0f,
-       .no_tuner = 1,
-       .parallel_ts = 1,
-};
-
-static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
-{
-
-       adap->fe[0] = dvb_attach(zl10353_attach, &gl861_zl10353_config,
-               &adap_to_d(adap)->i2c_adap);
-       if (adap->fe[0] == NULL)
-               return -EIO;
-
-       return 0;
-}
-
-static struct qt1010_config gl861_qt1010_config = {
-       .i2c_address = 0x62
-};
-
-static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
-{
-       return dvb_attach(qt1010_attach,
-                         adap->fe[0], &adap_to_d(adap)->i2c_adap,
-                         &gl861_qt1010_config) == NULL ? -ENODEV : 0;
-}
-
-static int gl861_init(struct dvb_usb_device *d)
-{
-       /*
-        * There is 2 interfaces. Interface 0 is for TV and interface 1 is
-        * for HID remote controller. Interface 0 has 2 alternate settings.
-        * For some reason we need to set interface explicitly, defaulted
-        * as alternate setting 1?
-        */
-       return usb_set_interface(d->udev, 0, 0);
-}
-
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties gl861_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-
-       .i2c_algo = &gl861_i2c_algo,
-       .frontend_attach = gl861_frontend_attach,
-       .tuner_attach = gl861_tuner_attach,
-       .init = gl861_init,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_BULK(0x81, 7, 512),
-               }
-       }
-};
-
-static const struct usb_device_id gl861_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801,
-               &gl861_props, "MSI Mega Sky 55801 DVB-T USB2.0", NULL) },
-       { DVB_USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU,
-               &gl861_props, "A-LINK DTU DVB-T USB2.0", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, gl861_id_table);
-
-static struct usb_driver gl861_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = gl861_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(gl861_usb_driver);
-
-MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
-MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/gl861.h b/drivers/media/dvb/dvb-usb/gl861.h
deleted file mode 100644 (file)
index b0b80d8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _DVB_USB_GL861_H_
-#define _DVB_USB_GL861_H_
-
-#include "dvb_usb.h"
-
-#define GL861_WRITE            0x40
-#define GL861_READ             0xc0
-
-#define GL861_REQ_I2C_WRITE    0x01
-#define GL861_REQ_I2C_READ     0x02
-
-#endif
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c
deleted file mode 100644 (file)
index d83df4b..0000000
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- *  mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "mxl111sf-demod.h"
-#include "mxl111sf-reg.h"
-
-/* debug */
-static int mxl111sf_demod_debug;
-module_param_named(debug, mxl111sf_demod_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-#define mxl_dbg(fmt, arg...) \
-       if (mxl111sf_demod_debug) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-/* ------------------------------------------------------------------------ */
-
-struct mxl111sf_demod_state {
-       struct mxl111sf_state *mxl_state;
-
-       struct mxl111sf_demod_config *cfg;
-
-       struct dvb_frontend fe;
-};
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_demod_read_reg(struct mxl111sf_demod_state *state,
-                                  u8 addr, u8 *data)
-{
-       return (state->cfg->read_reg) ?
-               state->cfg->read_reg(state->mxl_state, addr, data) :
-               -EINVAL;
-}
-
-static int mxl111sf_demod_write_reg(struct mxl111sf_demod_state *state,
-                                   u8 addr, u8 data)
-{
-       return (state->cfg->write_reg) ?
-               state->cfg->write_reg(state->mxl_state, addr, data) :
-               -EINVAL;
-}
-
-static
-int mxl111sf_demod_program_regs(struct mxl111sf_demod_state *state,
-                               struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
-{
-       return (state->cfg->program_regs) ?
-               state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
-               -EINVAL;
-}
-
-/* ------------------------------------------------------------------------ */
-/* TPS */
-
-static
-int mxl1x1sf_demod_get_tps_code_rate(struct mxl111sf_demod_state *state,
-                                    fe_code_rate_t *code_rate)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_CODE_RATE_TPS_REG, &val);
-       /* bit<2:0> - 000:1/2, 001:2/3, 010:3/4, 011:5/6, 100:7/8 */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch (val & V6_CODE_RATE_TPS_MASK) {
-       case 0:
-               *code_rate = FEC_1_2;
-               break;
-       case 1:
-               *code_rate = FEC_2_3;
-               break;
-       case 2:
-               *code_rate = FEC_3_4;
-               break;
-       case 3:
-               *code_rate = FEC_5_6;
-               break;
-       case 4:
-               *code_rate = FEC_7_8;
-               break;
-       }
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_modulation(struct mxl111sf_demod_state *state,
-                                        fe_modulation_t *modulation)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val);
-       /* Constellation, 00 : QPSK, 01 : 16QAM, 10:64QAM */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) {
-       case 0:
-               *modulation = QPSK;
-               break;
-       case 1:
-               *modulation = QAM_16;
-               break;
-       case 2:
-               *modulation = QAM_64;
-               break;
-       }
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_guard_fft_mode(struct mxl111sf_demod_state *state,
-                                         fe_transmit_mode_t *fft_mode)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_MODE_TPS_REG, &val);
-       /* FFT Mode, 00:2K, 01:8K, 10:4K */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch ((val & V6_PARAM_FFT_MODE_MASK) >> 2) {
-       case 0:
-               *fft_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               *fft_mode = TRANSMISSION_MODE_8K;
-               break;
-       case 2:
-               *fft_mode = TRANSMISSION_MODE_4K;
-               break;
-       }
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_guard_interval(struct mxl111sf_demod_state *state,
-                                         fe_guard_interval_t *guard)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_CP_TPS_REG, &val);
-       /* 00:1/32, 01:1/16, 10:1/8, 11:1/4 */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch ((val & V6_PARAM_GI_MASK) >> 4) {
-       case 0:
-               *guard = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               *guard = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               *guard = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               *guard = GUARD_INTERVAL_1_4;
-               break;
-       }
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_hierarchy(struct mxl111sf_demod_state *state,
-                                    fe_hierarchy_t *hierarchy)
-{
-       u8 val;
-       int ret = mxl111sf_demod_read_reg(state, V6_TPS_HIERACHY_REG, &val);
-       /* bit<6:4> - 000:Non hierarchy, 001:1, 010:2, 011:4 */
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch ((val & V6_TPS_HIERARCHY_INFO_MASK) >> 6) {
-       case 0:
-               *hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               *hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               *hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               *hierarchy = HIERARCHY_4;
-               break;
-       }
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-/* LOCKS */
-
-static
-int mxl1x1sf_demod_get_sync_lock_status(struct mxl111sf_demod_state *state,
-                                       int *sync_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_SYNC_LOCK_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *sync_lock = (val & SYNC_LOCK_MASK) >> 4;
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_rs_lock_status(struct mxl111sf_demod_state *state,
-                                     int *rs_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_RS_LOCK_DET_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *rs_lock = (val & RS_LOCK_DET_MASK) >> 3;
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_tps_lock_status(struct mxl111sf_demod_state *state,
-                                      int *tps_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_TPS_LOCK_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *tps_lock = (val & V6_PARAM_TPS_LOCK_MASK) >> 6;
-fail:
-       return ret;
-}
-
-static
-int mxl1x1sf_demod_get_fec_lock_status(struct mxl111sf_demod_state *state,
-                                      int *fec_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_IRQ_STATUS_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *fec_lock = (val & IRQ_MASK_FEC_LOCK) >> 4;
-fail:
-       return ret;
-}
-
-#if 0
-static
-int mxl1x1sf_demod_get_cp_lock_status(struct mxl111sf_demod_state *state,
-                                     int *cp_lock)
-{
-       u8 val = 0;
-       int ret = mxl111sf_demod_read_reg(state, V6_CP_LOCK_DET_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-       *cp_lock = (val & V6_CP_LOCK_DET_MASK) >> 2;
-fail:
-       return ret;
-}
-#endif
-
-static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state)
-{
-       return mxl111sf_demod_write_reg(state, 0x0e, 0xff);
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       int ret = 0;
-
-       struct mxl111sf_reg_ctrl_info phy_pll_patch[] = {
-               {0x00, 0xff, 0x01}, /* change page to 1 */
-               {0x40, 0xff, 0x05},
-               {0x40, 0xff, 0x01},
-               {0x41, 0xff, 0xca},
-               {0x41, 0xff, 0xc0},
-               {0x00, 0xff, 0x00}, /* change page to 0 */
-               {0,    0,    0}
-       };
-
-       mxl_dbg("()");
-
-       if (fe->ops.tuner_ops.set_params) {
-               ret = fe->ops.tuner_ops.set_params(fe);
-               if (mxl_fail(ret))
-                       goto fail;
-               msleep(50);
-       }
-       ret = mxl111sf_demod_program_regs(state, phy_pll_patch);
-       mxl_fail(ret);
-       msleep(50);
-       ret = mxl1x1sf_demod_reset_irq_status(state);
-       mxl_fail(ret);
-       msleep(100);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-#if 0
-/* resets TS Packet error count */
-/* After setting 7th bit of V5_PER_COUNT_RESET_REG, it should be reset to 0. */
-static
-int mxl1x1sf_demod_reset_packet_error_count(struct mxl111sf_demod_state *state)
-{
-       struct mxl111sf_reg_ctrl_info reset_per_count[] = {
-               {0x20, 0x01, 0x01},
-               {0x20, 0x01, 0x00},
-               {0,    0,    0}
-       };
-       return mxl111sf_demod_program_regs(state, reset_per_count);
-}
-#endif
-
-/* returns TS Packet error count */
-/* PER Count = FEC_PER_COUNT * (2 ** (FEC_PER_SCALE * 4)) */
-static int mxl111sf_demod_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       u32 fec_per_count, fec_per_scale;
-       u8 val;
-       int ret;
-
-       *ucblocks = 0;
-
-       /* FEC_PER_COUNT Register */
-       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_COUNT_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-
-       fec_per_count = val;
-
-       /* FEC_PER_SCALE Register */
-       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_SCALE_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-
-       val &= V6_FEC_PER_SCALE_MASK;
-       val *= 4;
-
-       fec_per_scale = 1 << val;
-
-       fec_per_count *= fec_per_scale;
-
-       *ucblocks = fec_per_count;
-fail:
-       return ret;
-}
-
-#ifdef MXL111SF_DEMOD_ENABLE_CALCULATIONS
-/* FIXME: leaving this enabled breaks the build on some architectures,
- * and we shouldn't have any floating point math in the kernel, anyway.
- *
- * These macros need to be re-written, but it's harmless to simply
- * return zero for now. */
-#define CALCULATE_BER(avg_errors, count) \
-       ((u32)(avg_errors * 4)/(count*64*188*8))
-#define CALCULATE_SNR(data) \
-       ((u32)((10 * (u32)data / 64) - 2.5))
-#else
-#define CALCULATE_BER(avg_errors, count) 0
-#define CALCULATE_SNR(data) 0
-#endif
-
-static int mxl111sf_demod_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       u8 val1, val2, val3;
-       int ret;
-
-       *ber = 0;
-
-       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_LSB_REG, &val1);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_MSB_REG, &val2);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_demod_read_reg(state, V6_N_ACCUMULATE_REG, &val3);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *ber = CALCULATE_BER((val1 | (val2 << 8)), val3);
-fail:
-       return ret;
-}
-
-static int mxl111sf_demod_calc_snr(struct mxl111sf_demod_state *state,
-                                  u16 *snr)
-{
-       u8 val1, val2;
-       int ret;
-
-       *snr = 0;
-
-       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_LSB_REG, &val1);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_MSB_REG, &val2);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *snr = CALCULATE_SNR(val1 | ((val2 & 0x03) << 8));
-fail:
-       return ret;
-}
-
-static int mxl111sf_demod_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-
-       int ret = mxl111sf_demod_calc_snr(state, snr);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *snr /= 10; /* 0.1 dB */
-fail:
-       return ret;
-}
-
-static int mxl111sf_demod_read_status(struct dvb_frontend *fe,
-                                     fe_status_t *status)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       int ret, locked, cr_lock, sync_lock, fec_lock;
-
-       *status = 0;
-
-       ret = mxl1x1sf_demod_get_rs_lock_status(state, &locked);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_demod_get_tps_lock_status(state, &cr_lock);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_demod_get_sync_lock_status(state, &sync_lock);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_demod_get_fec_lock_status(state, &fec_lock);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if (locked)
-               *status |= FE_HAS_SIGNAL;
-       if (cr_lock)
-               *status |= FE_HAS_CARRIER;
-       if (sync_lock)
-               *status |= FE_HAS_SYNC;
-       if (fec_lock) /* false positives? */
-               *status |= FE_HAS_VITERBI;
-
-       if ((locked) && (cr_lock) && (sync_lock))
-               *status |= FE_HAS_LOCK;
-fail:
-       return ret;
-}
-
-static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
-                                              u16 *signal_strength)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       fe_modulation_t modulation;
-       u16 snr;
-
-       mxl111sf_demod_calc_snr(state, &snr);
-       mxl1x1sf_demod_get_tps_modulation(state, &modulation);
-
-       switch (modulation) {
-       case QPSK:
-               *signal_strength = (snr >= 1300) ?
-                       min(65535, snr * 44) : snr * 38;
-               break;
-       case QAM_16:
-               *signal_strength = (snr >= 1500) ?
-                       min(65535, snr * 38) : snr * 33;
-               break;
-       case QAM_64:
-               *signal_strength = (snr >= 2000) ?
-                       min(65535, snr * 29) : snr * 25;
-               break;
-       default:
-               *signal_strength = 0;
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-
-       mxl_dbg("()");
-#if 0
-       p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF;
-#endif
-       if (fe->ops.tuner_ops.get_bandwidth)
-               fe->ops.tuner_ops.get_bandwidth(fe, &p->bandwidth_hz);
-       if (fe->ops.tuner_ops.get_frequency)
-               fe->ops.tuner_ops.get_frequency(fe, &p->frequency);
-       mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_HP);
-       mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_LP);
-       mxl1x1sf_demod_get_tps_modulation(state, &p->modulation);
-       mxl1x1sf_demod_get_tps_guard_fft_mode(state,
-                                             &p->transmission_mode);
-       mxl1x1sf_demod_get_tps_guard_interval(state,
-                                             &p->guard_interval);
-       mxl1x1sf_demod_get_tps_hierarchy(state,
-                                        &p->hierarchy);
-
-       return 0;
-}
-
-static
-int mxl111sf_demod_get_tune_settings(struct dvb_frontend *fe,
-                                    struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static void mxl111sf_demod_release(struct dvb_frontend *fe)
-{
-       struct mxl111sf_demod_state *state = fe->demodulator_priv;
-       mxl_dbg("()");
-       kfree(state);
-       fe->demodulator_priv = NULL;
-}
-
-static struct dvb_frontend_ops mxl111sf_demod_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name               = "MaxLinear MxL111SF DVB-T demodulator",
-               .frequency_min      = 177000000,
-               .frequency_max      = 858000000,
-               .frequency_stepsize = 166666,
-               .caps = 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_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
-       },
-       .release              = mxl111sf_demod_release,
-#if 0
-       .init                 = mxl111sf_init,
-       .i2c_gate_ctrl        = mxl111sf_i2c_gate_ctrl,
-#endif
-       .set_frontend         = mxl111sf_demod_set_frontend,
-       .get_frontend         = mxl111sf_demod_get_frontend,
-       .get_tune_settings    = mxl111sf_demod_get_tune_settings,
-       .read_status          = mxl111sf_demod_read_status,
-       .read_signal_strength = mxl111sf_demod_read_signal_strength,
-       .read_ber             = mxl111sf_demod_read_ber,
-       .read_snr             = mxl111sf_demod_read_snr,
-       .read_ucblocks        = mxl111sf_demod_read_ucblocks,
-};
-
-struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_demod_config *cfg)
-{
-       struct mxl111sf_demod_state *state = NULL;
-
-       mxl_dbg("()");
-
-       state = kzalloc(sizeof(struct mxl111sf_demod_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       state->mxl_state = mxl_state;
-       state->cfg = cfg;
-
-       memcpy(&state->fe.ops, &mxl111sf_demod_ops,
-              sizeof(struct dvb_frontend_ops));
-
-       state->fe.demodulator_priv = state;
-       return &state->fe;
-}
-EXPORT_SYMBOL_GPL(mxl111sf_demod_attach);
-
-MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver");
-MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.h b/drivers/media/dvb/dvb-usb/mxl111sf-demod.h
deleted file mode 100644 (file)
index 432706a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __MXL111SF_DEMOD_H__
-#define __MXL111SF_DEMOD_H__
-
-#include "dvb_frontend.h"
-#include "mxl111sf.h"
-
-struct mxl111sf_demod_config {
-       int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
-       int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
-       int (*program_regs)(struct mxl111sf_state *state,
-                           struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
-};
-
-#if defined(CONFIG_DVB_USB_MXL111SF) || \
-       (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
-extern
-struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_demod_config *cfg);
-#else
-static inline
-struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_demod_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_USB_MXL111SF */
-
-#endif /* __MXL111SF_DEMOD_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-gpio.c b/drivers/media/dvb/dvb-usb/mxl111sf-gpio.c
deleted file mode 100644 (file)
index e4121cb..0000000
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- *  mxl111sf-gpio.c - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "mxl111sf-gpio.h"
-#include "mxl111sf-i2c.h"
-#include "mxl111sf.h"
-
-/* ------------------------------------------------------------------------- */
-
-#define MXL_GPIO_MUX_REG_0 0x84
-#define MXL_GPIO_MUX_REG_1 0x89
-#define MXL_GPIO_MUX_REG_2 0x82
-
-#define MXL_GPIO_DIR_INPUT  0
-#define MXL_GPIO_DIR_OUTPUT 1
-
-
-static int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val)
-{
-       int ret;
-       u8 tmp;
-
-       mxl_debug_adv("(%d, %d)", pin, val);
-
-       if ((pin > 0) && (pin < 8)) {
-               ret = mxl111sf_read_reg(state, 0x19, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << (pin - 1));
-               tmp |= (val << (pin - 1));
-               ret = mxl111sf_write_reg(state, 0x19, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-       } else if (pin <= 10) {
-               if (pin == 0)
-                       pin += 7;
-               ret = mxl111sf_read_reg(state, 0x30, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << (pin - 3));
-               tmp |= (val << (pin - 3));
-               ret = mxl111sf_write_reg(state, 0x30, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-       } else
-               ret = -EINVAL;
-fail:
-       return ret;
-}
-
-static int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val)
-{
-       int ret;
-       u8 tmp;
-
-       mxl_debug("(0x%02x)", pin);
-
-       *val = 0;
-
-       switch (pin) {
-       case 0:
-       case 1:
-       case 2:
-       case 3:
-               ret = mxl111sf_read_reg(state, 0x23, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               *val = (tmp >> (pin + 4)) & 0x01;
-               break;
-       case 4:
-       case 5:
-       case 6:
-       case 7:
-               ret = mxl111sf_read_reg(state, 0x2f, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               *val = (tmp >> pin) & 0x01;
-               break;
-       case 8:
-       case 9:
-       case 10:
-               ret = mxl111sf_read_reg(state, 0x22, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               *val = (tmp >> (pin - 3)) & 0x01;
-               break;
-       default:
-               return -EINVAL; /* invalid pin */
-       }
-fail:
-       return ret;
-}
-
-struct mxl_gpio_cfg {
-       u8 pin;
-       u8 dir;
-       u8 val;
-};
-
-static int mxl111sf_config_gpio_pins(struct mxl111sf_state *state,
-                                    struct mxl_gpio_cfg *gpio_cfg)
-{
-       int ret;
-       u8 tmp;
-
-       mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir);
-
-       switch (gpio_cfg->pin) {
-       case 0:
-       case 1:
-       case 2:
-       case 3:
-               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << (gpio_cfg->pin + 4));
-               tmp |= (gpio_cfg->dir << (gpio_cfg->pin + 4));
-               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_0, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               break;
-       case 4:
-       case 5:
-       case 6:
-       case 7:
-               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << gpio_cfg->pin);
-               tmp |= (gpio_cfg->dir << gpio_cfg->pin);
-               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_1, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               break;
-       case 8:
-       case 9:
-       case 10:
-               ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               tmp &= ~(1 << (gpio_cfg->pin - 3));
-               tmp |= (gpio_cfg->dir << (gpio_cfg->pin - 3));
-               ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_2, tmp);
-               if (mxl_fail(ret))
-                       goto fail;
-               break;
-       default:
-               return -EINVAL; /* invalid pin */
-       }
-
-       ret = (MXL_GPIO_DIR_OUTPUT == gpio_cfg->dir) ?
-               mxl111sf_set_gpo_state(state,
-                                      gpio_cfg->pin, gpio_cfg->val) :
-               mxl111sf_get_gpi_state(state,
-                                      gpio_cfg->pin, &gpio_cfg->val);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-static int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state,
-                                  int gpio, int direction, int val)
-{
-       struct mxl_gpio_cfg gpio_config = {
-               .pin = gpio,
-               .dir = direction,
-               .val = val,
-       };
-
-       mxl_debug("(%d, %d, %d)", gpio, direction, val);
-
-       return mxl111sf_config_gpio_pins(state, &gpio_config);
-}
-
-/* ------------------------------------------------------------------------- */
-
-#define PIN_MUX_MPEG_MODE_MASK          0x40   /* 0x17 <6> */
-#define PIN_MUX_MPEG_PAR_EN_MASK        0x01   /* 0x18 <0> */
-#define PIN_MUX_MPEG_SER_EN_MASK        0x02   /* 0x18 <1> */
-#define PIN_MUX_MPG_IN_MUX_MASK         0x80   /* 0x3D <7> */
-#define PIN_MUX_BT656_ENABLE_MASK       0x04   /* 0x12 <2> */
-#define PIN_MUX_I2S_ENABLE_MASK         0x40   /* 0x15 <6> */
-#define PIN_MUX_SPI_MODE_MASK           0x10   /* 0x3D <4> */
-#define PIN_MUX_MCLK_EN_CTRL_MASK       0x10   /* 0x82 <4> */
-#define PIN_MUX_MPSYN_EN_CTRL_MASK      0x20   /* 0x82 <5> */
-#define PIN_MUX_MDVAL_EN_CTRL_MASK      0x40   /* 0x82 <6> */
-#define PIN_MUX_MPERR_EN_CTRL_MASK      0x80   /* 0x82 <7> */
-#define PIN_MUX_MDAT_EN_0_MASK          0x10   /* 0x84 <4> */
-#define PIN_MUX_MDAT_EN_1_MASK          0x20   /* 0x84 <5> */
-#define PIN_MUX_MDAT_EN_2_MASK          0x40   /* 0x84 <6> */
-#define PIN_MUX_MDAT_EN_3_MASK          0x80   /* 0x84 <7> */
-#define PIN_MUX_MDAT_EN_4_MASK          0x10   /* 0x89 <4> */
-#define PIN_MUX_MDAT_EN_5_MASK          0x20   /* 0x89 <5> */
-#define PIN_MUX_MDAT_EN_6_MASK          0x40   /* 0x89 <6> */
-#define PIN_MUX_MDAT_EN_7_MASK          0x80   /* 0x89 <7> */
-
-int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
-                                 enum mxl111sf_mux_config pin_mux_config)
-{
-       u8 r12, r15, r17, r18, r3D, r82, r84, r89;
-       int ret;
-
-       mxl_debug("(%d)", pin_mux_config);
-
-       ret = mxl111sf_read_reg(state, 0x17, &r17);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x18, &r18);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x12, &r12);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x15, &r15);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x82, &r82);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x84, &r84);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x89, &r89);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_read_reg(state, 0x3D, &r3D);
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch (pin_mux_config) {
-       case PIN_MUX_TS_OUT_PARALLEL:
-               /* mpeg_mode = 1 */
-               r17 |= PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 1 */
-               r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 1 */
-               r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 1 */
-               r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 1 */
-               r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 1 */
-               r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0xF */
-               r84 |= 0xF0;
-               /* mdat_en_ctrl[7:4] = 0xF */
-               r89 |= 0xF0;
-               break;
-       case PIN_MUX_TS_OUT_SERIAL:
-               /* mpeg_mode = 1 */
-               r17 |= PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 1 */
-               r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 1 */
-               r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 1 */
-               r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 1 */
-               r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0xF */
-               r84 |= 0xF0;
-               /* mdat_en_ctrl[7:4] = 0xF */
-               r89 |= 0xF0;
-               break;
-       case PIN_MUX_GPIO_MODE:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_SERIAL_IN_MODE_0:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_SERIAL_IN_MODE_1:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 1 */
-               r3D |= PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_SPI_IN_MODE_1:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 1 */
-               r3D |= PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 1 */
-               r15 |= PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 1 */
-               r3D |= PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_SPI_IN_MODE_0:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 1 */
-               r18 |= PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 1 */
-               r15 |= PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 1 */
-               r3D |= PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_TS_PARALLEL_IN:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 1 */
-               r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_BT656_I2S_MODE:
-               /* mpeg_mode = 0 */
-               r17 &= ~PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 1 */
-               r12 |= PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 1 */
-               r15 |= PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       case PIN_MUX_DEFAULT:
-       default:
-               /* mpeg_mode = 1 */
-               r17 |= PIN_MUX_MPEG_MODE_MASK;
-               /* mpeg_par_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
-               /* mpeg_ser_en = 0 */
-               r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
-               /* mpg_in_mux = 0 */
-               r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
-               /* bt656_enable = 0 */
-               r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
-               /* i2s_enable = 0 */
-               r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
-               /* spi_mode = 0 */
-               r3D &= ~PIN_MUX_SPI_MODE_MASK;
-               /* mclk_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
-               /* mperr_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
-               /* mdval_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
-               /* mpsyn_en_ctrl = 0 */
-               r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
-               /* mdat_en_ctrl[3:0] = 0x0 */
-               r84 &= 0x0F;
-               /* mdat_en_ctrl[7:4] = 0x0 */
-               r89 &= 0x0F;
-               break;
-       }
-
-       ret = mxl111sf_write_reg(state, 0x17, r17);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x18, r18);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x12, r12);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x15, r15);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x82, r82);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x84, r84);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x89, r89);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x3D, r3D);
-       if (mxl_fail(ret))
-               goto fail;
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val)
-{
-       return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val);
-}
-
-static int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state)
-{
-       u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */
-       int i, ret;
-
-       mxl_debug("()");
-
-       for (i = 3; i < 8; i++) {
-               ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01);
-               if (mxl_fail(ret))
-                       break;
-       }
-
-       return ret;
-}
-
-#define PCA9534_I2C_ADDR (0x40 >> 1)
-static int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val)
-{
-       u8 w[2] = { 1, 0 };
-       u8 r = 0;
-       struct i2c_msg msg[] = {
-               { .addr = PCA9534_I2C_ADDR,
-                 .flags = 0, .buf = w, .len = 1 },
-               { .addr = PCA9534_I2C_ADDR,
-                 .flags = I2C_M_RD, .buf = &r, .len = 1 },
-       };
-
-       mxl_debug("(%d, %d)", gpio, val);
-
-       /* read current GPIO levels from flip-flop */
-       i2c_transfer(&state->d->i2c_adap, msg, 2);
-
-       /* prepare write buffer with current GPIO levels */
-       msg[0].len = 2;
-#if 0
-       w[0] = 1;
-#endif
-       w[1] = r;
-
-       /* clear the desired GPIO */
-       w[1] &= ~(1 << gpio);
-
-       /* set the desired GPIO value */
-       w[1] |= ((val ? 1 : 0) << gpio);
-
-       /* write new GPIO levels to flip-flop */
-       i2c_transfer(&state->d->i2c_adap, &msg[0], 1);
-
-       return 0;
-}
-
-static int pca9534_init_port_expander(struct mxl111sf_state *state)
-{
-       u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */
-
-       struct i2c_msg msg = {
-               .addr = PCA9534_I2C_ADDR,
-               .flags = 0, .buf = w, .len = 2
-       };
-
-       mxl_debug("()");
-
-       i2c_transfer(&state->d->i2c_adap, &msg, 1);
-
-       /* configure all pins as outputs */
-       w[0] = 3;
-       w[1] = 0;
-
-       i2c_transfer(&state->d->i2c_adap, &msg, 1);
-
-       return 0;
-}
-
-int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val)
-{
-       mxl_debug("(%d, %d)", gpio, val);
-
-       switch (state->gpio_port_expander) {
-       default:
-               mxl_printk(KERN_ERR,
-                          "gpio_port_expander undefined, assuming PCA9534");
-               /* fall-thru */
-       case mxl111sf_PCA9534:
-               return pca9534_set_gpio(state, gpio, val);
-       case mxl111sf_gpio_hw:
-               return mxl111sf_hw_set_gpio(state, gpio, val);
-       }
-}
-
-static int mxl111sf_probe_port_expander(struct mxl111sf_state *state)
-{
-       int ret;
-       u8 w = 1;
-       u8 r = 0;
-       struct i2c_msg msg[] = {
-               { .flags = 0,        .buf = &w, .len = 1 },
-               { .flags = I2C_M_RD, .buf = &r, .len = 1 },
-       };
-
-       mxl_debug("()");
-
-       msg[0].addr = 0x70 >> 1;
-       msg[1].addr = 0x70 >> 1;
-
-       /* read current GPIO levels from flip-flop */
-       ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
-       if (ret == 2) {
-               state->port_expander_addr = msg[0].addr;
-               state->gpio_port_expander = mxl111sf_PCA9534;
-               mxl_debug("found port expander at 0x%02x",
-                         state->port_expander_addr);
-               return 0;
-       }
-
-       msg[0].addr = 0x40 >> 1;
-       msg[1].addr = 0x40 >> 1;
-
-       ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
-       if (ret == 2) {
-               state->port_expander_addr = msg[0].addr;
-               state->gpio_port_expander = mxl111sf_PCA9534;
-               mxl_debug("found port expander at 0x%02x",
-                         state->port_expander_addr);
-               return 0;
-       }
-       state->port_expander_addr = 0xff;
-       state->gpio_port_expander = mxl111sf_gpio_hw;
-       mxl_debug("using hardware gpio");
-       return 0;
-}
-
-int mxl111sf_init_port_expander(struct mxl111sf_state *state)
-{
-       mxl_debug("()");
-
-       if (0x00 == state->port_expander_addr)
-               mxl111sf_probe_port_expander(state);
-
-       switch (state->gpio_port_expander) {
-       default:
-               mxl_printk(KERN_ERR,
-                          "gpio_port_expander undefined, assuming PCA9534");
-               /* fall-thru */
-       case mxl111sf_PCA9534:
-               return pca9534_init_port_expander(state);
-       case mxl111sf_gpio_hw:
-               return mxl111sf_hw_gpio_initialize(state);
-       }
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode)
-{
-/*     GPO:
- *     3 - ATSC/MH#   | 1 = ATSC transport, 0 = MH transport      | default 0
- *     4 - ATSC_RST## | 1 = ATSC enable, 0 = ATSC Reset           | default 0
- *     5 - ATSC_EN    | 1 = ATSC power enable, 0 = ATSC power off | default 0
- *     6 - MH_RESET#  | 1 = MH enable, 0 = MH Reset               | default 0
- *     7 - MH_EN      | 1 = MH power enable, 0 = MH power off     | default 0
- */
-       mxl_debug("(%d)", mode);
-
-       switch (mode) {
-       case MXL111SF_GPIO_MOD_MH:
-               mxl111sf_set_gpio(state, 4, 0);
-               mxl111sf_set_gpio(state, 5, 0);
-               msleep(50);
-               mxl111sf_set_gpio(state, 7, 1);
-               msleep(50);
-               mxl111sf_set_gpio(state, 6, 1);
-               msleep(50);
-
-               mxl111sf_set_gpio(state, 3, 0);
-               break;
-       case MXL111SF_GPIO_MOD_ATSC:
-               mxl111sf_set_gpio(state, 6, 0);
-               mxl111sf_set_gpio(state, 7, 0);
-               msleep(50);
-               mxl111sf_set_gpio(state, 5, 1);
-               msleep(50);
-               mxl111sf_set_gpio(state, 4, 1);
-               msleep(50);
-               mxl111sf_set_gpio(state, 3, 1);
-               break;
-       default: /* DVBT / STANDBY */
-               mxl111sf_init_port_expander(state);
-               break;
-       }
-       return 0;
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-gpio.h b/drivers/media/dvb/dvb-usb/mxl111sf-gpio.h
deleted file mode 100644 (file)
index 0220f54..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  mxl111sf-gpio.h - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _DVB_USB_MXL111SF_GPIO_H_
-#define _DVB_USB_MXL111SF_GPIO_H_
-
-#include "mxl111sf.h"
-
-int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val);
-int mxl111sf_init_port_expander(struct mxl111sf_state *state);
-
-#define MXL111SF_GPIO_MOD_DVBT 0
-#define MXL111SF_GPIO_MOD_MH   1
-#define MXL111SF_GPIO_MOD_ATSC 2
-int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode);
-
-enum mxl111sf_mux_config {
-       PIN_MUX_DEFAULT = 0,
-       PIN_MUX_TS_OUT_PARALLEL,
-       PIN_MUX_TS_OUT_SERIAL,
-       PIN_MUX_GPIO_MODE,
-       PIN_MUX_TS_SERIAL_IN_MODE_0,
-       PIN_MUX_TS_SERIAL_IN_MODE_1,
-       PIN_MUX_TS_SPI_IN_MODE_0,
-       PIN_MUX_TS_SPI_IN_MODE_1,
-       PIN_MUX_TS_PARALLEL_IN,
-       PIN_MUX_BT656_I2S_MODE,
-};
-
-int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
-                                 enum mxl111sf_mux_config pin_mux_config);
-
-#endif /* _DVB_USB_MXL111SF_GPIO_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c
deleted file mode 100644 (file)
index 3443455..0000000
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- *  mxl111sf-i2c.c - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "mxl111sf-i2c.h"
-#include "mxl111sf.h"
-
-/* SW-I2C ----------------------------------------------------------------- */
-
-#define SW_I2C_ADDR            0x1a
-#define SW_I2C_EN              0x02
-#define SW_SCL_OUT             0x04
-#define SW_SDA_OUT             0x08
-#define SW_SDA_IN              0x04
-
-#define SW_I2C_BUSY_ADDR       0x2f
-#define SW_I2C_BUSY            0x02
-
-static int mxl111sf_i2c_bitbang_sendbyte(struct mxl111sf_state *state,
-                                        u8 byte)
-{
-       int i, ret;
-       u8 data = 0;
-
-       mxl_i2c("(0x%02x)", byte);
-
-       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
-       if (mxl_fail(ret))
-               goto fail;
-
-       for (i = 0; i < 8; i++) {
-
-               data = (byte & (0x80 >> i)) ? SW_SDA_OUT : 0;
-
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | data);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | data | SW_SCL_OUT);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | data);
-               if (mxl_fail(ret))
-                       goto fail;
-       }
-
-       /* last bit was 0 so we need to release SDA */
-       if (!(byte & 1)) {
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | SW_SDA_OUT);
-               if (mxl_fail(ret))
-                       goto fail;
-       }
-
-       /* CLK high for ACK readback */
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* drop the CLK after getting ACK, SDA will go high right away */
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if (data & SW_SDA_IN)
-               ret = -EIO;
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_bitbang_recvbyte(struct mxl111sf_state *state,
-                                        u8 *pbyte)
-{
-       int i, ret;
-       u8 byte = 0;
-       u8 data = 0;
-
-       mxl_i2c("()");
-
-       *pbyte = 0;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       for (i = 0; i < 8; i++) {
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN |
-                                        SW_SCL_OUT | SW_SDA_OUT);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               if (data & SW_SDA_IN)
-                       byte |= (0x80 >> i);
-
-               ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                        0x10 | SW_I2C_EN | SW_SDA_OUT);
-               if (mxl_fail(ret))
-                       goto fail;
-       }
-       *pbyte = byte;
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_start(struct mxl111sf_state *state)
-{
-       int ret;
-
-       mxl_i2c("()");
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN); /* start */
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_stop(struct mxl111sf_state *state)
-{
-       int ret;
-
-       mxl_i2c("()");
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN); /* stop */
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_SCL_OUT | SW_SDA_OUT);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_ack(struct mxl111sf_state *state)
-{
-       int ret;
-       u8 b = 0;
-
-       mxl_i2c("()");
-
-       ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &b);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* pull SDA low */
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SDA_OUT);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-static int mxl111sf_i2c_nack(struct mxl111sf_state *state)
-{
-       int ret;
-
-       mxl_i2c("()");
-
-       /* SDA high to signal last byte read from slave */
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
-                                0x10 | SW_I2C_EN | SW_SDA_OUT);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_i2c_sw_xfer_msg(struct mxl111sf_state *state,
-                                   struct i2c_msg *msg)
-{
-       int i, ret;
-
-       mxl_i2c("()");
-
-       if (msg->flags & I2C_M_RD) {
-
-               ret = mxl111sf_i2c_start(state);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_i2c_bitbang_sendbyte(state,
-                                                   (msg->addr << 1) | 0x01);
-               if (mxl_fail(ret)) {
-                       mxl111sf_i2c_stop(state);
-                       goto fail;
-               }
-
-               for (i = 0; i < msg->len; i++) {
-                       ret = mxl111sf_i2c_bitbang_recvbyte(state,
-                                                           &msg->buf[i]);
-                       if (mxl_fail(ret)) {
-                               mxl111sf_i2c_stop(state);
-                               goto fail;
-                       }
-
-                       if (i < msg->len - 1)
-                               mxl111sf_i2c_ack(state);
-               }
-
-               mxl111sf_i2c_nack(state);
-
-               ret = mxl111sf_i2c_stop(state);
-               if (mxl_fail(ret))
-                       goto fail;
-
-       } else {
-
-               ret = mxl111sf_i2c_start(state);
-               if (mxl_fail(ret))
-                       goto fail;
-
-               ret = mxl111sf_i2c_bitbang_sendbyte(state,
-                                                   (msg->addr << 1) & 0xfe);
-               if (mxl_fail(ret)) {
-                       mxl111sf_i2c_stop(state);
-                       goto fail;
-               }
-
-               for (i = 0; i < msg->len; i++) {
-                       ret = mxl111sf_i2c_bitbang_sendbyte(state,
-                                                           msg->buf[i]);
-                       if (mxl_fail(ret)) {
-                               mxl111sf_i2c_stop(state);
-                               goto fail;
-                       }
-               }
-
-               /* FIXME: we only want to do this on the last transaction */
-               mxl111sf_i2c_stop(state);
-       }
-fail:
-       return ret;
-}
-
-/* HW-I2C ----------------------------------------------------------------- */
-
-#define USB_WRITE_I2C_CMD     0x99
-#define USB_READ_I2C_CMD      0xdd
-#define USB_END_I2C_CMD       0xfe
-
-#define USB_WRITE_I2C_CMD_LEN   26
-#define USB_READ_I2C_CMD_LEN    24
-
-#define I2C_MUX_REG           0x30
-#define I2C_CONTROL_REG       0x00
-#define I2C_SLAVE_ADDR_REG    0x08
-#define I2C_DATA_REG          0x0c
-#define I2C_INT_STATUS_REG    0x10
-
-static int mxl111sf_i2c_send_data(struct mxl111sf_state *state,
-                                 u8 index, u8 *wdata)
-{
-       int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
-                                   &wdata[1], 25, NULL, 0);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-static int mxl111sf_i2c_get_data(struct mxl111sf_state *state,
-                                u8 index, u8 *wdata, u8 *rdata)
-{
-       int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
-                                   &wdata[1], 25, rdata, 24);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-static u8 mxl111sf_i2c_check_status(struct mxl111sf_state *state)
-{
-       u8 status = 0;
-       u8 buf[26];
-
-       mxl_i2c_adv("()");
-
-       buf[0] = USB_READ_I2C_CMD;
-       buf[1] = 0x00;
-
-       buf[2] = I2C_INT_STATUS_REG;
-       buf[3] = 0x00;
-       buf[4] = 0x00;
-
-       buf[5] = USB_END_I2C_CMD;
-
-       mxl111sf_i2c_get_data(state, 0, buf, buf);
-
-       if (buf[1] & 0x04)
-               status = 1;
-
-       return status;
-}
-
-static u8 mxl111sf_i2c_check_fifo(struct mxl111sf_state *state)
-{
-       u8 status = 0;
-       u8 buf[26];
-
-       mxl_i2c("()");
-
-       buf[0] = USB_READ_I2C_CMD;
-       buf[1] = 0x00;
-
-       buf[2] = I2C_MUX_REG;
-       buf[3] = 0x00;
-       buf[4] = 0x00;
-
-       buf[5] = I2C_INT_STATUS_REG;
-       buf[6] = 0x00;
-       buf[7] = 0x00;
-       buf[8] = USB_END_I2C_CMD;
-
-       mxl111sf_i2c_get_data(state, 0, buf, buf);
-
-       if (0x08 == (buf[1] & 0x08))
-               status = 1;
-
-       if ((buf[5] & 0x02) == 0x02)
-               mxl_i2c("(buf[5] & 0x02) == 0x02"); /* FIXME */
-
-       return status;
-}
-
-static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
-                                 u8 count, u8 *rbuf)
-{
-       u8 i2c_w_data[26];
-       u8 i2c_r_data[24];
-       u8 i = 0;
-       u8 fifo_status = 0;
-       int status = 0;
-
-       mxl_i2c("read %d bytes", count);
-
-       while ((fifo_status == 0) && (i++ < 5))
-               fifo_status = mxl111sf_i2c_check_fifo(state);
-
-       i2c_w_data[0] = 0xDD;
-       i2c_w_data[1] = 0x00;
-
-       for (i = 2; i < 26; i++)
-               i2c_w_data[i] = 0xFE;
-
-       for (i = 0; i < count; i++) {
-               i2c_w_data[2+(i*3)] = 0x0C;
-               i2c_w_data[3+(i*3)] = 0x00;
-               i2c_w_data[4+(i*3)] = 0x00;
-       }
-
-       mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
-
-       /* Check for I2C NACK status */
-       if (mxl111sf_i2c_check_status(state) == 1) {
-               mxl_i2c("error!");
-       } else {
-               for (i = 0; i < count; i++) {
-                       rbuf[i] = i2c_r_data[(i*3)+1];
-                       mxl_i2c("%02x\t %02x",
-                               i2c_r_data[(i*3)+1],
-                               i2c_r_data[(i*3)+2]);
-               }
-
-               status = 1;
-       }
-
-       return status;
-}
-
-#define HWI2C400 1
-static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state,
-                                   struct i2c_msg *msg)
-{
-       int i, k, ret = 0;
-       u16 index = 0;
-       u8 buf[26];
-       u8 i2c_r_data[24];
-       u16 block_len;
-       u16 left_over_len;
-       u8 rd_status[8];
-       u8 ret_status;
-       u8 readbuff[26];
-
-       mxl_i2c("addr: 0x%02x, read buff len: %d, write buff len: %d",
-               msg->addr, (msg->flags & I2C_M_RD) ? msg->len : 0,
-               (!(msg->flags & I2C_M_RD)) ? msg->len : 0);
-
-       for (index = 0; index < 26; index++)
-               buf[index] = USB_END_I2C_CMD;
-
-       /* command to indicate data payload is destined for I2C interface */
-       buf[0] = USB_WRITE_I2C_CMD;
-       buf[1] = 0x00;
-
-       /* enable I2C interface */
-       buf[2] = I2C_MUX_REG;
-       buf[3] = 0x80;
-       buf[4] = 0x00;
-
-       /* enable I2C interface */
-       buf[5] = I2C_MUX_REG;
-       buf[6] = 0x81;
-       buf[7] = 0x00;
-
-       /* set Timeout register on I2C interface */
-       buf[8] = 0x14;
-       buf[9] = 0xff;
-       buf[10] = 0x00;
-#if 0
-       /* enable Interrupts on I2C interface */
-       buf[8] = 0x24;
-       buf[9] = 0xF7;
-       buf[10] = 0x00;
-#endif
-       buf[11] = 0x24;
-       buf[12] = 0xF7;
-       buf[13] = 0x00;
-
-       ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-       /* write data on I2C bus */
-       if (!(msg->flags & I2C_M_RD) && (msg->len > 0)) {
-               mxl_i2c("%d\t%02x", msg->len, msg->buf[0]);
-
-               /* control register on I2C interface to initialize I2C bus */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0x5E;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-               /* I2C Slave device Address */
-               buf[5] = I2C_SLAVE_ADDR_REG;
-               buf[6] = (msg->addr);
-               buf[7] = 0x00;
-               buf[8] = USB_END_I2C_CMD;
-               ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-               /* check for slave device status */
-               if (mxl111sf_i2c_check_status(state) == 1) {
-                       mxl_i2c("NACK writing slave address %02x",
-                               msg->addr);
-                       /* if NACK, stop I2C bus and exit */
-                       buf[2] = I2C_CONTROL_REG;
-                       buf[3] = 0x4E;
-                       buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                       ret = -EIO;
-                       goto exit;
-               }
-
-               /* I2C interface can do I2C operations in block of 8 bytes of
-                  I2C data. calculation to figure out number of blocks of i2c
-                  data required to program */
-               block_len = (msg->len / 8);
-               left_over_len = (msg->len % 8);
-               index = 0;
-
-               mxl_i2c("block_len %d, left_over_len %d",
-                       block_len, left_over_len);
-
-               for (index = 0; index < block_len; index++) {
-                       for (i = 0; i < 8; i++) {
-                               /* write data on I2C interface */
-                               buf[2+(i*3)] = I2C_DATA_REG;
-                               buf[3+(i*3)] = msg->buf[(index*8)+i];
-                               buf[4+(i*3)] = 0x00;
-                       }
-
-                       ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-                       /* check for I2C NACK status */
-                       if (mxl111sf_i2c_check_status(state) == 1) {
-                               mxl_i2c("NACK writing slave address %02x",
-                                       msg->addr);
-
-                               /* if NACK, stop I2C bus and exit */
-                               buf[2] = I2C_CONTROL_REG;
-                               buf[3] = 0x4E;
-                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                               ret = -EIO;
-                               goto exit;
-                       }
-
-               }
-
-               if (left_over_len) {
-                       for (k = 0; k < 26; k++)
-                               buf[k] = USB_END_I2C_CMD;
-
-                       buf[0] = 0x99;
-                       buf[1] = 0x00;
-
-                       for (i = 0; i < left_over_len; i++) {
-                               buf[2+(i*3)] = I2C_DATA_REG;
-                               buf[3+(i*3)] = msg->buf[(index*8)+i];
-                               mxl_i2c("index = %d %d data %d",
-                                       index, i, msg->buf[(index*8)+i]);
-                               buf[4+(i*3)] = 0x00;
-                       }
-                       ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-                       /* check for I2C NACK status */
-                       if (mxl111sf_i2c_check_status(state) == 1) {
-                               mxl_i2c("NACK writing slave address %02x",
-                                       msg->addr);
-
-                               /* if NACK, stop I2C bus and exit */
-                               buf[2] = I2C_CONTROL_REG;
-                               buf[3] = 0x4E;
-                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                               ret = -EIO;
-                               goto exit;
-                       }
-
-               }
-
-               /* issue I2C STOP after write */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0x4E;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-       }
-
-       /* read data from I2C bus */
-       if ((msg->flags & I2C_M_RD) && (msg->len > 0)) {
-               mxl_i2c("read buf len %d", msg->len);
-
-               /* command to indicate data payload is
-                  destined for I2C interface */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0xDF;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-               /* I2C xfer length */
-               buf[5] = 0x14;
-               buf[6] = (msg->len & 0xFF);
-               buf[7] = 0;
-
-               /* I2C slave device Address */
-               buf[8] = I2C_SLAVE_ADDR_REG;
-               buf[9] = msg->addr;
-               buf[10] = 0x00;
-               buf[11] = USB_END_I2C_CMD;
-               ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-               /* check for I2C NACK status */
-               if (mxl111sf_i2c_check_status(state) == 1) {
-                       mxl_i2c("NACK reading slave address %02x",
-                               msg->addr);
-
-                       /* if NACK, stop I2C bus and exit */
-                       buf[2] = I2C_CONTROL_REG;
-                       buf[3] = 0xC7;
-                       buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                       ret = -EIO;
-                       goto exit;
-               }
-
-               /* I2C interface can do I2C operations in block of 8 bytes of
-                  I2C data. calculation to figure out number of blocks of
-                  i2c data required to program */
-               block_len = ((msg->len) / 8);
-               left_over_len = ((msg->len) % 8);
-               index = 0;
-
-               mxl_i2c("block_len %d, left_over_len %d",
-                       block_len, left_over_len);
-
-               /* command to read data from I2C interface */
-               buf[0] = USB_READ_I2C_CMD;
-               buf[1] = 0x00;
-
-               for (index = 0; index < block_len; index++) {
-                       /* setup I2C read request packet on I2C interface */
-                       for (i = 0; i < 8; i++) {
-                               buf[2+(i*3)] = I2C_DATA_REG;
-                               buf[3+(i*3)] = 0x00;
-                               buf[4+(i*3)] = 0x00;
-                       }
-
-                       ret = mxl111sf_i2c_get_data(state, 0, buf, i2c_r_data);
-
-                       /* check for I2C NACK status */
-                       if (mxl111sf_i2c_check_status(state) == 1) {
-                               mxl_i2c("NACK reading slave address %02x",
-                                       msg->addr);
-
-                               /* if NACK, stop I2C bus and exit */
-                               buf[2] = I2C_CONTROL_REG;
-                               buf[3] = 0xC7;
-                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                               ret = -EIO;
-                               goto exit;
-                       }
-
-                       /* copy data from i2c data payload to read buffer */
-                       for (i = 0; i < 8; i++) {
-                               rd_status[i] = i2c_r_data[(i*3)+2];
-
-                               if (rd_status[i] == 0x04) {
-                                       if (i < 7) {
-                                               mxl_i2c("i2c fifo empty!"
-                                                       " @ %d", i);
-                                               msg->buf[(index*8)+i] =
-                                                       i2c_r_data[(i*3)+1];
-                                               /* read again */
-                                               ret_status =
-                                                       mxl111sf_i2c_readagain(
-                                                               state, 8-(i+1),
-                                                               readbuff);
-                                               if (ret_status == 1) {
-                                                       for (k = 0;
-                                                            k < 8-(i+1);
-                                                            k++) {
-
-                                       msg->buf[(index*8)+(k+i+1)] =
-                                               readbuff[k];
-                                       mxl_i2c("read data: %02x\t %02x",
-                                               msg->buf[(index*8)+(k+i)],
-                                               (index*8)+(k+i));
-                                       mxl_i2c("read data: %02x\t %02x",
-                                               msg->buf[(index*8)+(k+i+1)],
-                                               readbuff[k]);
-
-                                                       }
-                                                       goto stop_copy;
-                                               } else {
-                                                       mxl_i2c("readagain "
-                                                               "ERROR!");
-                                               }
-                                       } else {
-                                               msg->buf[(index*8)+i] =
-                                                       i2c_r_data[(i*3)+1];
-                                       }
-                               } else {
-                                       msg->buf[(index*8)+i] =
-                                               i2c_r_data[(i*3)+1];
-                               }
-                       }
-stop_copy:
-                       ;
-
-               }
-
-               if (left_over_len) {
-                       for (k = 0; k < 26; k++)
-                               buf[k] = USB_END_I2C_CMD;
-
-                       buf[0] = 0xDD;
-                       buf[1] = 0x00;
-
-                       for (i = 0; i < left_over_len; i++) {
-                               buf[2+(i*3)] = I2C_DATA_REG;
-                               buf[3+(i*3)] = 0x00;
-                               buf[4+(i*3)] = 0x00;
-                       }
-                       ret = mxl111sf_i2c_get_data(state, 0, buf,
-                                                   i2c_r_data);
-
-                       /* check for I2C NACK status */
-                       if (mxl111sf_i2c_check_status(state) == 1) {
-                               mxl_i2c("NACK reading slave address %02x",
-                                       msg->addr);
-
-                               /* if NACK, stop I2C bus and exit */
-                               buf[2] = I2C_CONTROL_REG;
-                               buf[3] = 0xC7;
-                               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-                               ret = -EIO;
-                               goto exit;
-                       }
-
-                       for (i = 0; i < left_over_len; i++) {
-                               msg->buf[(block_len*8)+i] =
-                                       i2c_r_data[(i*3)+1];
-                               mxl_i2c("read data: %02x\t %02x",
-                                       i2c_r_data[(i*3)+1],
-                                       i2c_r_data[(i*3)+2]);
-                       }
-               }
-
-               /* indicate I2C interface to issue NACK
-                  after next I2C read op */
-               buf[0] = USB_WRITE_I2C_CMD;
-               buf[1] = 0x00;
-
-               /* control register */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0x17;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-               buf[5] = USB_END_I2C_CMD;
-               ret = mxl111sf_i2c_send_data(state, 0, buf);
-
-               /* control register */
-               buf[2] = I2C_CONTROL_REG;
-               buf[3] = 0xC7;
-               buf[4] = (HWI2C400) ? 0x03 : 0x0D;
-
-       }
-exit:
-       /* STOP and disable I2C MUX */
-       buf[0] = USB_WRITE_I2C_CMD;
-       buf[1] = 0x00;
-
-       /* de-initilize I2C BUS */
-       buf[5] = USB_END_I2C_CMD;
-       mxl111sf_i2c_send_data(state, 0, buf);
-
-       /* Control Register */
-       buf[2] = I2C_CONTROL_REG;
-       buf[3] = 0xDF;
-       buf[4] = 0x03;
-
-       /* disable I2C interface */
-       buf[5] = I2C_MUX_REG;
-       buf[6] = 0x00;
-       buf[7] = 0x00;
-
-       /* de-initilize I2C BUS */
-       buf[8] = USB_END_I2C_CMD;
-       mxl111sf_i2c_send_data(state, 0, buf);
-
-       /* disable I2C interface */
-       buf[2] = I2C_MUX_REG;
-       buf[3] = 0x81;
-       buf[4] = 0x00;
-
-       /* disable I2C interface */
-       buf[5] = I2C_MUX_REG;
-       buf[6] = 0x00;
-       buf[7] = 0x00;
-
-       /* disable I2C interface */
-       buf[8] = I2C_MUX_REG;
-       buf[9] = 0x00;
-       buf[10] = 0x00;
-
-       buf[11] = USB_END_I2C_CMD;
-       mxl111sf_i2c_send_data(state, 0, buf);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
-                     struct i2c_msg msg[], int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct mxl111sf_state *state = d->priv;
-       int hwi2c = (state->chip_rev > MXL111SF_V6);
-       int i, ret;
-
-       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
-               return -EAGAIN;
-
-       for (i = 0; i < num; i++) {
-               ret = (hwi2c) ?
-                       mxl111sf_i2c_hw_xfer_msg(state, &msg[i]) :
-                       mxl111sf_i2c_sw_xfer_msg(state, &msg[i]);
-               if (mxl_fail(ret)) {
-                       mxl_debug_adv("failed with error %d on i2c "
-                                     "transaction %d of %d, %sing %d bytes "
-                                     "to/from 0x%02x", ret, i+1, num,
-                                     (msg[i].flags & I2C_M_RD) ?
-                                     "read" : "writ",
-                                     msg[i].len, msg[i].addr);
-
-                       break;
-               }
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return i == num ? num : -EREMOTEIO;
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.h b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.h
deleted file mode 100644 (file)
index a57a45f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  mxl111sf-i2c.h - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _DVB_USB_MXL111SF_I2C_H_
-#define _DVB_USB_MXL111SF_I2C_H_
-
-#include <linux/i2c.h>
-
-int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
-                     struct i2c_msg msg[], int num);
-
-#endif /* _DVB_USB_MXL111SF_I2C_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c
deleted file mode 100644 (file)
index b741b3a..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- *  mxl111sf-phy.c - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "mxl111sf-phy.h"
-#include "mxl111sf-reg.h"
-
-int mxl111sf_init_tuner_demod(struct mxl111sf_state *state)
-{
-       struct mxl111sf_reg_ctrl_info mxl_111_overwrite_default[] = {
-               {0x07, 0xff, 0x0c},
-               {0x58, 0xff, 0x9d},
-               {0x09, 0xff, 0x00},
-               {0x06, 0xff, 0x06},
-               {0xc8, 0xff, 0x40}, /* ED_LE_WIN_OLD = 0 */
-               {0x8d, 0x01, 0x01}, /* NEGATE_Q */
-               {0x32, 0xff, 0xac}, /* DIG_RFREFSELECT = 12 */
-               {0x42, 0xff, 0x43}, /* DIG_REG_AMP = 4 */
-               {0x74, 0xff, 0xc4}, /* SSPUR_FS_PRIO = 4 */
-               {0x71, 0xff, 0xe6}, /* SPUR_ROT_PRIO_VAL = 1 */
-               {0x83, 0xff, 0x64}, /* INF_FILT1_THD_SC = 100 */
-               {0x85, 0xff, 0x64}, /* INF_FILT2_THD_SC = 100 */
-               {0x88, 0xff, 0xf0}, /* INF_THD = 240 */
-               {0x6f, 0xf0, 0xb0}, /* DFE_DLY = 11 */
-               {0x00, 0xff, 0x01}, /* Change to page 1 */
-               {0x81, 0xff, 0x11}, /* DSM_FERR_BYPASS = 1 */
-               {0xf4, 0xff, 0x07}, /* DIG_FREQ_CORR = 1 */
-               {0xd4, 0x1f, 0x0f}, /* SPUR_TEST_NOISE_TH = 15 */
-               {0xd6, 0xff, 0x0c}, /* SPUR_TEST_NOISE_PAPR = 12 */
-               {0x00, 0xff, 0x00}, /* Change to page 0 */
-               {0,    0,    0}
-       };
-
-       mxl_debug("()");
-
-       return mxl111sf_ctrl_program_regs(state, mxl_111_overwrite_default);
-}
-
-int mxl1x1sf_soft_reset(struct mxl111sf_state *state)
-{
-       int ret;
-       mxl_debug("()");
-
-       ret = mxl111sf_write_reg(state, 0xff, 0x00); /* AIC */
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_write_reg(state, 0x02, 0x01); /* get out of reset */
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode)
-{
-       int ret;
-
-       mxl_debug("(%s)", MXL_SOC_MODE == mode ?
-               "MXL_SOC_MODE" : "MXL_TUNER_MODE");
-
-       /* set device mode */
-       ret = mxl111sf_write_reg(state, 0x03,
-                                MXL_SOC_MODE == mode ? 0x01 : 0x00);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg_mask(state,
-                                     0x7d, 0x40, MXL_SOC_MODE == mode ?
-                                     0x00 : /* enable impulse noise filter,
-                                               INF_BYP = 0 */
-                                     0x40); /* disable impulse noise filter,
-                                               INF_BYP = 1 */
-       if (mxl_fail(ret))
-               goto fail;
-
-       state->device_mode = mode;
-fail:
-       return ret;
-}
-
-/* power up tuner */
-int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff)
-{
-       mxl_debug("(%d)", onoff);
-
-       return mxl111sf_write_reg(state, 0x01, onoff ? 0x01 : 0x00);
-}
-
-int mxl111sf_disable_656_port(struct mxl111sf_state *state)
-{
-       mxl_debug("()");
-
-       return mxl111sf_write_reg_mask(state, 0x12, 0x04, 0x00);
-}
-
-int mxl111sf_enable_usb_output(struct mxl111sf_state *state)
-{
-       mxl_debug("()");
-
-       return mxl111sf_write_reg_mask(state, 0x17, 0x40, 0x00);
-}
-
-/* initialize TSIF as input port of MxL1X1SF for MPEG2 data transfer */
-int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
-                           unsigned int parallel_serial,
-                           unsigned int msb_lsb_1st,
-                           unsigned int clock_phase,
-                           unsigned int mpeg_valid_pol,
-                           unsigned int mpeg_sync_pol)
-{
-       int ret;
-       u8 mode, tmp;
-
-       mxl_debug("(%u,%u,%u,%u,%u)", parallel_serial, msb_lsb_1st,
-                 clock_phase, mpeg_valid_pol, mpeg_sync_pol);
-
-       /* Enable PIN MUX */
-       ret = mxl111sf_write_reg(state, V6_PIN_MUX_MODE_REG, V6_ENABLE_PIN_MUX);
-       mxl_fail(ret);
-
-       /* Configure MPEG Clock phase */
-       mxl111sf_read_reg(state, V6_MPEG_IN_CLK_INV_REG, &mode);
-
-       if (clock_phase == TSIF_NORMAL)
-               mode &= ~V6_INVERTED_CLK_PHASE;
-       else
-               mode |= V6_INVERTED_CLK_PHASE;
-
-       ret = mxl111sf_write_reg(state, V6_MPEG_IN_CLK_INV_REG, mode);
-       mxl_fail(ret);
-
-       /* Configure data input mode, MPEG Valid polarity, MPEG Sync polarity
-        * Get current configuration */
-       ret = mxl111sf_read_reg(state, V6_MPEG_IN_CTRL_REG, &mode);
-       mxl_fail(ret);
-
-       /* Data Input mode */
-       if (parallel_serial == TSIF_INPUT_PARALLEL) {
-               /* Disable serial mode */
-               mode &= ~V6_MPEG_IN_DATA_SERIAL;
-
-               /* Enable Parallel mode */
-               mode |= V6_MPEG_IN_DATA_PARALLEL;
-       } else {
-               /* Disable Parallel mode */
-               mode &= ~V6_MPEG_IN_DATA_PARALLEL;
-
-               /* Enable Serial Mode */
-               mode |= V6_MPEG_IN_DATA_SERIAL;
-
-               /* If serial interface is chosen, configure
-                  MSB or LSB order in transmission */
-               ret = mxl111sf_read_reg(state,
-                                       V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
-                                       &tmp);
-               mxl_fail(ret);
-
-               if (msb_lsb_1st == MPEG_SER_MSB_FIRST_ENABLED)
-                       tmp |= V6_MPEG_SER_MSB_FIRST;
-               else
-                       tmp &= ~V6_MPEG_SER_MSB_FIRST;
-
-               ret = mxl111sf_write_reg(state,
-                                        V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
-                                        tmp);
-               mxl_fail(ret);
-       }
-
-       /* MPEG Sync polarity */
-       if (mpeg_sync_pol == TSIF_NORMAL)
-               mode &= ~V6_INVERTED_MPEG_SYNC;
-       else
-               mode |= V6_INVERTED_MPEG_SYNC;
-
-       /* MPEG Valid polarity */
-       if (mpeg_valid_pol == 0)
-               mode &= ~V6_INVERTED_MPEG_VALID;
-       else
-               mode |= V6_INVERTED_MPEG_VALID;
-
-       ret = mxl111sf_write_reg(state, V6_MPEG_IN_CTRL_REG, mode);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size)
-{
-       static struct mxl111sf_reg_ctrl_info init_i2s[] = {
-               {0x1b, 0xff, 0x1e}, /* pin mux mode, Choose 656/I2S input */
-               {0x15, 0x60, 0x60}, /* Enable I2S */
-               {0x17, 0xe0, 0x20}, /* Input, MPEG MODE USB,
-                                      Inverted 656 Clock, I2S_SOFT_RESET,
-                                      0 : Normal operation, 1 : Reset State */
-#if 0
-               {0x12, 0x01, 0x00}, /* AUDIO_IRQ_CLR (Overflow Indicator) */
-#endif
-               {0x00, 0xff, 0x02}, /* Change to Control Page */
-               {0x26, 0x0d, 0x0d}, /* I2S_MODE & BT656_SRC_SEL for FPGA only */
-               {0x00, 0xff, 0x00},
-               {0,    0,    0}
-       };
-       int ret;
-
-       mxl_debug("(0x%02x)", sample_size);
-
-       ret = mxl111sf_ctrl_program_regs(state, init_i2s);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, V6_I2S_NUM_SAMPLES_REG, sample_size);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-int mxl111sf_disable_i2s_port(struct mxl111sf_state *state)
-{
-       static struct mxl111sf_reg_ctrl_info disable_i2s[] = {
-               {0x15, 0x40, 0x00},
-               {0,    0,    0}
-       };
-
-       mxl_debug("()");
-
-       return mxl111sf_ctrl_program_regs(state, disable_i2s);
-}
-
-int mxl111sf_config_i2s(struct mxl111sf_state *state,
-                       u8 msb_start_pos, u8 data_width)
-{
-       int ret;
-       u8 tmp;
-
-       mxl_debug("(0x%02x, 0x%02x)", msb_start_pos, data_width);
-
-       ret = mxl111sf_read_reg(state, V6_I2S_STREAM_START_BIT_REG, &tmp);
-       if (mxl_fail(ret))
-               goto fail;
-
-       tmp &= 0xe0;
-       tmp |= msb_start_pos;
-       ret = mxl111sf_write_reg(state, V6_I2S_STREAM_START_BIT_REG, tmp);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_read_reg(state, V6_I2S_STREAM_END_BIT_REG, &tmp);
-       if (mxl_fail(ret))
-               goto fail;
-
-       tmp &= 0xe0;
-       tmp |= data_width;
-       ret = mxl111sf_write_reg(state, V6_I2S_STREAM_END_BIT_REG, tmp);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)
-{
-       u8 val;
-       int ret;
-
-       mxl_debug("(%d)", onoff);
-
-       ret = mxl111sf_write_reg(state, 0x00, 0x02);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_read_reg(state, V8_SPI_MODE_REG, &val);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if (onoff)
-               val |= 0x04;
-       else
-               val &= ~0x04;
-
-       ret = mxl111sf_write_reg(state, V8_SPI_MODE_REG, val);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_write_reg(state, 0x00, 0x00);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-int mxl111sf_idac_config(struct mxl111sf_state *state,
-                        u8 control_mode, u8 current_setting,
-                        u8 current_value, u8 hysteresis_value)
-{
-       int ret;
-       u8 val;
-       /* current value will be set for both automatic & manual IDAC control */
-       val = current_value;
-
-       if (control_mode == IDAC_MANUAL_CONTROL) {
-               /* enable manual control of IDAC */
-               val |= IDAC_MANUAL_CONTROL_BIT_MASK;
-
-               if (current_setting == IDAC_CURRENT_SINKING_ENABLE)
-                       /* enable current sinking in manual mode */
-                       val |= IDAC_CURRENT_SINKING_BIT_MASK;
-               else
-                       /* disable current sinking in manual mode */
-                       val &= ~IDAC_CURRENT_SINKING_BIT_MASK;
-       } else {
-               /* disable manual control of IDAC */
-               val &= ~IDAC_MANUAL_CONTROL_BIT_MASK;
-
-               /* set hysteresis value  reg: 0x0B<5:0> */
-               ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,
-                                        (hysteresis_value & 0x3F));
-               mxl_fail(ret);
-       }
-
-       ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.h b/drivers/media/dvb/dvb-usb/mxl111sf-phy.h
deleted file mode 100644 (file)
index f075607..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  mxl111sf-phy.h - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _DVB_USB_MXL111SF_PHY_H_
-#define _DVB_USB_MXL111SF_PHY_H_
-
-#include "mxl111sf.h"
-
-int mxl1x1sf_soft_reset(struct mxl111sf_state *state);
-int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode);
-int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff);
-int mxl111sf_disable_656_port(struct mxl111sf_state *state);
-int mxl111sf_init_tuner_demod(struct mxl111sf_state *state);
-int mxl111sf_enable_usb_output(struct mxl111sf_state *state);
-int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
-                           unsigned int parallel_serial,
-                           unsigned int msb_lsb_1st,
-                           unsigned int clock_phase,
-                           unsigned int mpeg_valid_pol,
-                           unsigned int mpeg_sync_pol);
-int mxl111sf_config_i2s(struct mxl111sf_state *state,
-                       u8 msb_start_pos, u8 data_width);
-int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size);
-int mxl111sf_disable_i2s_port(struct mxl111sf_state *state);
-int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff);
-int mxl111sf_idac_config(struct mxl111sf_state *state,
-                        u8 control_mode, u8 current_setting,
-                        u8 current_value, u8 hysteresis_value);
-
-#endif /* _DVB_USB_MXL111SF_PHY_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-reg.h b/drivers/media/dvb/dvb-usb/mxl111sf-reg.h
deleted file mode 100644 (file)
index 17831b0..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *  mxl111sf-reg.h - driver for the MaxLinear MXL111SF
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _DVB_USB_MXL111SF_REG_H_
-#define _DVB_USB_MXL111SF_REG_H_
-
-#define CHIP_ID_REG                  0xFC
-#define TOP_CHIP_REV_ID_REG          0xFA
-
-#define V6_SNR_RB_LSB_REG            0x27
-#define V6_SNR_RB_MSB_REG            0x28
-
-#define V6_N_ACCUMULATE_REG          0x11
-#define V6_RS_AVG_ERRORS_LSB_REG     0x2C
-#define V6_RS_AVG_ERRORS_MSB_REG     0x2D
-
-#define V6_IRQ_STATUS_REG            0x24
-#define  IRQ_MASK_FEC_LOCK       0x10
-
-#define V6_SYNC_LOCK_REG             0x28
-#define SYNC_LOCK_MASK           0x10
-
-#define V6_RS_LOCK_DET_REG           0x28
-#define  RS_LOCK_DET_MASK        0x08
-
-#define V6_INITACQ_NODETECT_REG    0x20
-#define V6_FORCE_NFFT_CPSIZE_REG   0x20
-
-#define V6_CODE_RATE_TPS_REG       0x29
-#define V6_CODE_RATE_TPS_MASK      0x07
-
-
-#define V6_CP_LOCK_DET_REG        0x28
-#define V6_CP_LOCK_DET_MASK       0x04
-
-#define V6_TPS_HIERACHY_REG        0x29
-#define V6_TPS_HIERARCHY_INFO_MASK  0x40
-
-#define V6_MODORDER_TPS_REG        0x2A
-#define V6_PARAM_CONSTELLATION_MASK   0x30
-
-#define V6_MODE_TPS_REG            0x2A
-#define V6_PARAM_FFT_MODE_MASK        0x0C
-
-
-#define V6_CP_TPS_REG             0x29
-#define V6_PARAM_GI_MASK              0x30
-
-#define V6_TPS_LOCK_REG           0x2A
-#define V6_PARAM_TPS_LOCK_MASK        0x40
-
-#define V6_FEC_PER_COUNT_REG      0x2E
-#define V6_FEC_PER_SCALE_REG      0x2B
-#define V6_FEC_PER_SCALE_MASK        0x03
-#define V6_FEC_PER_CLR_REG        0x20
-#define V6_FEC_PER_CLR_MASK          0x01
-
-#define V6_PIN_MUX_MODE_REG       0x1B
-#define V6_ENABLE_PIN_MUX            0x1E
-
-#define V6_I2S_NUM_SAMPLES_REG    0x16
-
-#define V6_MPEG_IN_CLK_INV_REG    0x17
-#define V6_MPEG_IN_CTRL_REG       0x18
-
-#define V6_INVERTED_CLK_PHASE       0x20
-#define V6_MPEG_IN_DATA_PARALLEL    0x01
-#define V6_MPEG_IN_DATA_SERIAL      0x02
-
-#define V6_INVERTED_MPEG_SYNC       0x04
-#define V6_INVERTED_MPEG_VALID      0x08
-
-#define TSIF_INPUT_PARALLEL         0
-#define TSIF_INPUT_SERIAL           1
-#define TSIF_NORMAL                 0
-
-#define V6_MPEG_INOUT_BIT_ORDER_CTRL_REG  0x19
-#define V6_MPEG_SER_MSB_FIRST                0x80
-#define MPEG_SER_MSB_FIRST_ENABLED        0x01
-
-#define V6_656_I2S_BUFF_STATUS_REG   0x2F
-#define V6_656_OVERFLOW_MASK_BIT         0x08
-#define V6_I2S_OVERFLOW_MASK_BIT         0x01
-
-#define V6_I2S_STREAM_START_BIT_REG  0x14
-#define V6_I2S_STREAM_END_BIT_REG    0x15
-#define I2S_RIGHT_JUSTIFIED     0
-#define I2S_LEFT_JUSTIFIED      1
-#define I2S_DATA_FORMAT         2
-
-#define V6_TUNER_LOOP_THRU_CONTROL_REG  0x09
-#define V6_ENABLE_LOOP_THRU               0x01
-
-#define TOTAL_NUM_IF_OUTPUT_FREQ       16
-
-#define TUNER_NORMAL_IF_SPECTRUM       0x0
-#define TUNER_INVERT_IF_SPECTRUM       0x10
-
-#define V6_TUNER_IF_SEL_REG              0x06
-#define V6_TUNER_IF_FCW_REG              0x3C
-#define V6_TUNER_IF_FCW_BYP_REG          0x3D
-#define V6_RF_LOCK_STATUS_REG            0x23
-
-#define NUM_DIG_TV_CHANNEL     1000
-
-#define V6_DIG_CLK_FREQ_SEL_REG  0x07
-#define V6_REF_SYNTH_INT_REG     0x5C
-#define V6_REF_SYNTH_REMAIN_REG  0x58
-#define V6_DIG_RFREFSELECT_REG   0x32
-#define V6_XTAL_CLK_OUT_GAIN_REG   0x31
-#define V6_TUNER_LOOP_THRU_CTRL_REG      0x09
-#define V6_DIG_XTAL_ENABLE_REG  0x06
-#define V6_DIG_XTAL_BIAS_REG  0x66
-#define V6_XTAL_CAP_REG    0x08
-
-#define V6_GPO_CTRL_REG     0x18
-#define MXL_GPO_0           0x00
-#define MXL_GPO_1           0x01
-#define V6_GPO_0_MASK       0x10
-#define V6_GPO_1_MASK       0x20
-
-#define V6_111SF_GPO_CTRL_REG     0x19
-#define MXL_111SF_GPO_1               0x00
-#define MXL_111SF_GPO_2               0x01
-#define MXL_111SF_GPO_3               0x02
-#define MXL_111SF_GPO_4               0x03
-#define MXL_111SF_GPO_5               0x04
-#define MXL_111SF_GPO_6               0x05
-#define MXL_111SF_GPO_7               0x06
-
-#define MXL_111SF_GPO_0_MASK          0x01
-#define MXL_111SF_GPO_1_MASK          0x02
-#define MXL_111SF_GPO_2_MASK          0x04
-#define MXL_111SF_GPO_3_MASK          0x08
-#define MXL_111SF_GPO_4_MASK          0x10
-#define MXL_111SF_GPO_5_MASK          0x20
-#define MXL_111SF_GPO_6_MASK          0x40
-
-#define V6_ATSC_CONFIG_REG  0x0A
-
-#define MXL_MODE_REG    0x03
-#define START_TUNE_REG  0x1C
-
-#define V6_IDAC_HYSTERESIS_REG    0x0B
-#define V6_IDAC_SETTINGS_REG      0x0C
-#define IDAC_MANUAL_CONTROL             1
-#define IDAC_CURRENT_SINKING_ENABLE     1
-#define IDAC_MANUAL_CONTROL_BIT_MASK      0x80
-#define IDAC_CURRENT_SINKING_BIT_MASK     0x40
-
-#define V8_SPI_MODE_REG  0xE9
-
-#define V6_DIG_RF_PWR_LSB_REG  0x46
-#define V6_DIG_RF_PWR_MSB_REG  0x47
-
-#endif /* _DVB_USB_MXL111SF_REG_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c
deleted file mode 100644 (file)
index ef4c65f..0000000
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- *  mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "mxl111sf-tuner.h"
-#include "mxl111sf-phy.h"
-#include "mxl111sf-reg.h"
-
-/* debug */
-static int mxl111sf_tuner_debug;
-module_param_named(debug, mxl111sf_tuner_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-#define mxl_dbg(fmt, arg...) \
-       if (mxl111sf_tuner_debug) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-#define err pr_err
-
-/* ------------------------------------------------------------------------ */
-
-struct mxl111sf_tuner_state {
-       struct mxl111sf_state *mxl_state;
-
-       struct mxl111sf_tuner_config *cfg;
-
-       enum mxl_if_freq if_freq;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-static int mxl111sf_tuner_read_reg(struct mxl111sf_tuner_state *state,
-                                  u8 addr, u8 *data)
-{
-       return (state->cfg->read_reg) ?
-               state->cfg->read_reg(state->mxl_state, addr, data) :
-               -EINVAL;
-}
-
-static int mxl111sf_tuner_write_reg(struct mxl111sf_tuner_state *state,
-                                   u8 addr, u8 data)
-{
-       return (state->cfg->write_reg) ?
-               state->cfg->write_reg(state->mxl_state, addr, data) :
-               -EINVAL;
-}
-
-static int mxl111sf_tuner_program_regs(struct mxl111sf_tuner_state *state,
-                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
-{
-       return (state->cfg->program_regs) ?
-               state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
-               -EINVAL;
-}
-
-static int mxl1x1sf_tuner_top_master_ctrl(struct mxl111sf_tuner_state *state,
-                                         int onoff)
-{
-       return (state->cfg->top_master_ctrl) ?
-               state->cfg->top_master_ctrl(state->mxl_state, onoff) :
-               -EINVAL;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static struct mxl111sf_reg_ctrl_info mxl_phy_tune_rf[] = {
-       {0x1d, 0x7f, 0x00}, /* channel bandwidth section 1/2/3,
-                              DIG_MODEINDEX, _A, _CSF, */
-       {0x1e, 0xff, 0x00}, /* channel frequency (lo and fractional) */
-       {0x1f, 0xff, 0x00}, /* channel frequency (hi for integer portion) */
-       {0,    0,    0}
-};
-
-/* ------------------------------------------------------------------------ */
-
-static struct mxl111sf_reg_ctrl_info *mxl111sf_calc_phy_tune_regs(u32 freq,
-                                                                 u8 bw)
-{
-       u8 filt_bw;
-
-       /* set channel bandwidth */
-       switch (bw) {
-       case 0: /* ATSC */
-               filt_bw = 25;
-               break;
-       case 1: /* QAM */
-               filt_bw = 69;
-               break;
-       case 6:
-               filt_bw = 21;
-               break;
-       case 7:
-               filt_bw = 42;
-               break;
-       case 8:
-               filt_bw = 63;
-               break;
-       default:
-               err("%s: invalid bandwidth setting!", __func__);
-               return NULL;
-       }
-
-       /* calculate RF channel */
-       freq /= 1000000;
-
-       freq *= 64;
-#if 0
-       /* do round */
-       freq += 0.5;
-#endif
-       /* set bandwidth */
-       mxl_phy_tune_rf[0].data = filt_bw;
-
-       /* set RF */
-       mxl_phy_tune_rf[1].data = (freq & 0xff);
-       mxl_phy_tune_rf[2].data = (freq >> 8) & 0xff;
-
-       /* start tune */
-       return mxl_phy_tune_rf;
-}
-
-static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state)
-{
-       int ret;
-       u8 ctrl;
-#if 0
-       u16 iffcw;
-       u32 if_freq;
-#endif
-       mxl_dbg("(IF polarity = %d, IF freq = 0x%02x)",
-               state->cfg->invert_spectrum, state->cfg->if_freq);
-
-       /* set IF polarity */
-       ctrl = state->cfg->invert_spectrum;
-
-       ctrl |= state->cfg->if_freq;
-
-       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_SEL_REG, ctrl);
-       if (mxl_fail(ret))
-               goto fail;
-
-#if 0
-       if_freq /= 1000000;
-
-       /* do round */
-       if_freq += 0.5;
-
-       if (MXL_IF_LO == state->cfg->if_freq) {
-               ctrl = 0x08;
-               iffcw = (u16)(if_freq / (108 * 4096));
-       } else if (MXL_IF_HI == state->cfg->if_freq) {
-               ctrl = 0x08;
-               iffcw = (u16)(if_freq / (216 * 4096));
-       } else {
-               ctrl = 0;
-               iffcw = 0;
-       }
-
-       ctrl |= (iffcw >> 8);
-#endif
-       ret = mxl111sf_tuner_read_reg(state, V6_TUNER_IF_FCW_BYP_REG, &ctrl);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ctrl &= 0xf0;
-       ctrl |= 0x90;
-
-       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_BYP_REG, ctrl);
-       if (mxl_fail(ret))
-               goto fail;
-
-#if 0
-       ctrl = iffcw & 0x00ff;
-#endif
-       ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl);
-       if (mxl_fail(ret))
-               goto fail;
-
-       state->if_freq = state->cfg->if_freq;
-fail:
-       return ret;
-}
-
-static int mxl1x1sf_tune_rf(struct dvb_frontend *fe, u32 freq, u8 bw)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       static struct mxl111sf_reg_ctrl_info *reg_ctrl_array;
-       int ret;
-       u8 mxl_mode;
-
-       mxl_dbg("(freq = %d, bw = 0x%x)", freq, bw);
-
-       /* stop tune */
-       ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 0);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* check device mode */
-       ret = mxl111sf_tuner_read_reg(state, MXL_MODE_REG, &mxl_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* Fill out registers for channel tune */
-       reg_ctrl_array = mxl111sf_calc_phy_tune_regs(freq, bw);
-       if (!reg_ctrl_array)
-               return -EINVAL;
-
-       ret = mxl111sf_tuner_program_regs(state, reg_ctrl_array);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if ((mxl_mode & MXL_DEV_MODE_MASK) == MXL_TUNER_MODE) {
-               /* IF tuner mode only */
-               mxl1x1sf_tuner_top_master_ctrl(state, 0);
-               mxl1x1sf_tuner_top_master_ctrl(state, 1);
-               mxl1x1sf_tuner_set_if_output_freq(state);
-       }
-
-       ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if (state->cfg->ant_hunt)
-               state->cfg->ant_hunt(fe);
-fail:
-       return ret;
-}
-
-static int mxl1x1sf_tuner_get_lock_status(struct mxl111sf_tuner_state *state,
-                                         int *rf_synth_lock,
-                                         int *ref_synth_lock)
-{
-       int ret;
-       u8 data;
-
-       *rf_synth_lock = 0;
-       *ref_synth_lock = 0;
-
-       ret = mxl111sf_tuner_read_reg(state, V6_RF_LOCK_STATUS_REG, &data);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *ref_synth_lock = ((data & 0x03) == 0x03) ? 1 : 0;
-       *rf_synth_lock  = ((data & 0x0c) == 0x0c) ? 1 : 0;
-fail:
-       return ret;
-}
-
-#if 0
-static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state *state,
-                                        int onoff)
-{
-       return mxl111sf_tuner_write_reg(state, V6_TUNER_LOOP_THRU_CTRL_REG,
-                                       onoff ? 1 : 0);
-}
-#endif
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys  = c->delivery_system;
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       int ret;
-       u8 bw;
-
-       mxl_dbg("()");
-
-       switch (delsys) {
-       case SYS_ATSC:
-       case SYS_ATSCMH:
-               bw = 0; /* ATSC */
-               break;
-       case SYS_DVBC_ANNEX_B:
-               bw = 1; /* US CABLE */
-               break;
-       case SYS_DVBT:
-               switch (c->bandwidth_hz) {
-               case 6000000:
-                       bw = 6;
-                       break;
-               case 7000000:
-                       bw = 7;
-                       break;
-               case 8000000:
-                       bw = 8;
-                       break;
-               default:
-                       err("%s: bandwidth not set!", __func__);
-                       return -EINVAL;
-               }
-               break;
-       default:
-               err("%s: modulation type not supported!", __func__);
-               return -EINVAL;
-       }
-       ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
-       if (mxl_fail(ret))
-               goto fail;
-
-       state->frequency = c->frequency;
-       state->bandwidth = c->bandwidth_hz;
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-#if 0
-static int mxl111sf_tuner_init(struct dvb_frontend *fe)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       int ret;
-
-       /* wake from standby handled by usb driver */
-
-       return ret;
-}
-
-static int mxl111sf_tuner_sleep(struct dvb_frontend *fe)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       int ret;
-
-       /* enter standby mode handled by usb driver */
-
-       return ret;
-}
-#endif
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_tuner_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       int rf_locked, ref_locked, ret;
-
-       *status = 0;
-
-       ret = mxl1x1sf_tuner_get_lock_status(state, &rf_locked, &ref_locked);
-       if (mxl_fail(ret))
-               goto fail;
-       mxl_info("%s%s", rf_locked ? "rf locked " : "",
-                ref_locked ? "ref locked" : "");
-
-       if ((rf_locked) || (ref_locked))
-               *status |= TUNER_STATUS_LOCKED;
-fail:
-       return ret;
-}
-
-static int mxl111sf_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       u8 val1, val2;
-       int ret;
-
-       *strength = 0;
-
-       ret = mxl111sf_tuner_write_reg(state, 0x00, 0x02);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_LSB_REG, &val1);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_MSB_REG, &val2);
-       if (mxl_fail(ret))
-               goto fail;
-
-       *strength = val1 | ((val2 & 0x07) << 8);
-fail:
-       ret = mxl111sf_tuner_write_reg(state, 0x00, 0x00);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_tuner_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       *frequency = state->frequency;
-       return 0;
-}
-
-static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       *bandwidth = state->bandwidth;
-       return 0;
-}
-
-static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe,
-                                          u32 *frequency)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-
-       *frequency = 0;
-
-       switch (state->if_freq) {
-       case MXL_IF_4_0:   /* 4.0   MHz */
-               *frequency = 4000000;
-               break;
-       case MXL_IF_4_5:   /* 4.5   MHz */
-               *frequency = 4500000;
-               break;
-       case MXL_IF_4_57:  /* 4.57  MHz */
-               *frequency = 4570000;
-               break;
-       case MXL_IF_5_0:   /* 5.0   MHz */
-               *frequency = 5000000;
-               break;
-       case MXL_IF_5_38:  /* 5.38  MHz */
-               *frequency = 5380000;
-               break;
-       case MXL_IF_6_0:   /* 6.0   MHz */
-               *frequency = 6000000;
-               break;
-       case MXL_IF_6_28:  /* 6.28  MHz */
-               *frequency = 6280000;
-               break;
-       case MXL_IF_7_2:   /* 7.2   MHz */
-               *frequency = 7200000;
-               break;
-       case MXL_IF_35_25: /* 35.25 MHz */
-               *frequency = 35250000;
-               break;
-       case MXL_IF_36:    /* 36    MHz */
-               *frequency = 36000000;
-               break;
-       case MXL_IF_36_15: /* 36.15 MHz */
-               *frequency = 36150000;
-               break;
-       case MXL_IF_44:    /* 44    MHz */
-               *frequency = 44000000;
-               break;
-       }
-       return 0;
-}
-
-static int mxl111sf_tuner_release(struct dvb_frontend *fe)
-{
-       struct mxl111sf_tuner_state *state = fe->tuner_priv;
-       mxl_dbg("()");
-       kfree(state);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
-       .info = {
-               .name = "MaxLinear MxL111SF",
-#if 0
-               .frequency_min  = ,
-               .frequency_max  = ,
-               .frequency_step = ,
-#endif
-       },
-#if 0
-       .init              = mxl111sf_tuner_init,
-       .sleep             = mxl111sf_tuner_sleep,
-#endif
-       .set_params        = mxl111sf_tuner_set_params,
-       .get_status        = mxl111sf_tuner_get_status,
-       .get_rf_strength   = mxl111sf_get_rf_strength,
-       .get_frequency     = mxl111sf_tuner_get_frequency,
-       .get_bandwidth     = mxl111sf_tuner_get_bandwidth,
-       .get_if_frequency  = mxl111sf_tuner_get_if_frequency,
-       .release           = mxl111sf_tuner_release,
-};
-
-struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
-                                          struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_tuner_config *cfg)
-{
-       struct mxl111sf_tuner_state *state = NULL;
-
-       mxl_dbg("()");
-
-       state = kzalloc(sizeof(struct mxl111sf_tuner_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       state->mxl_state = mxl_state;
-       state->cfg = cfg;
-
-       memcpy(&fe->ops.tuner_ops, &mxl111sf_tuner_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = state;
-       return fe;
-}
-EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach);
-
-MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver");
-MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.h b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.h
deleted file mode 100644 (file)
index ff33396..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  mxl111sf-tuner.h - driver for the MaxLinear MXL111SF CMOS tuner
- *
- *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __MXL111SF_TUNER_H__
-#define __MXL111SF_TUNER_H__
-
-#include "dvb_frontend.h"
-
-#include "mxl111sf.h"
-
-enum mxl_if_freq {
-#if 0
-       MXL_IF_LO    = 0x00, /* other IF < 9MHz */
-#endif
-       MXL_IF_4_0   = 0x01, /* 4.0   MHz */
-       MXL_IF_4_5   = 0x02, /* 4.5   MHz */
-       MXL_IF_4_57  = 0x03, /* 4.57  MHz */
-       MXL_IF_5_0   = 0x04, /* 5.0   MHz */
-       MXL_IF_5_38  = 0x05, /* 5.38  MHz */
-       MXL_IF_6_0   = 0x06, /* 6.0   MHz */
-       MXL_IF_6_28  = 0x07, /* 6.28  MHz */
-       MXL_IF_7_2   = 0x08, /* 7.2   MHz */
-       MXL_IF_35_25 = 0x09, /* 35.25 MHz */
-       MXL_IF_36    = 0x0a, /* 36    MHz */
-       MXL_IF_36_15 = 0x0b, /* 36.15 MHz */
-       MXL_IF_44    = 0x0c, /* 44    MHz */
-#if 0
-       MXL_IF_HI    = 0x0f, /* other IF > 35 MHz and < 45 MHz */
-#endif
-};
-
-struct mxl111sf_tuner_config {
-       enum mxl_if_freq if_freq;
-       unsigned int invert_spectrum:1;
-
-       int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
-       int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
-       int (*program_regs)(struct mxl111sf_state *state,
-                           struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
-       int (*top_master_ctrl)(struct mxl111sf_state *state, int onoff);
-       int (*ant_hunt)(struct dvb_frontend *fe);
-};
-
-/* ------------------------------------------------------------------------ */
-
-#if defined(CONFIG_DVB_USB_MXL111SF) || \
-       (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
-extern
-struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
-                                          struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_tuner_config *cfg);
-#else
-static inline
-struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
-                                          struct mxl111sf_state *mxl_state
-                                          struct mxl111sf_tuner_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __MXL111SF_TUNER_H__ */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c
deleted file mode 100644 (file)
index 1fb017e..0000000
+++ /dev/null
@@ -1,1463 +0,0 @@
-/*
- * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
- *
- *   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 <linux/vmalloc.h>
-#include <linux/i2c.h>
-
-#include "mxl111sf.h"
-#include "mxl111sf-reg.h"
-#include "mxl111sf-phy.h"
-#include "mxl111sf-i2c.h"
-#include "mxl111sf-gpio.h"
-
-#include "mxl111sf-demod.h"
-#include "mxl111sf-tuner.h"
-
-#include "lgdt3305.h"
-#include "lg2160.h"
-
-int dvb_usb_mxl111sf_debug;
-module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level "
-                "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
-
-int dvb_usb_mxl111sf_isoc;
-module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
-MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
-
-int dvb_usb_mxl111sf_spi;
-module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644);
-MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi).");
-
-#define ANT_PATH_AUTO 0
-#define ANT_PATH_EXTERNAL 1
-#define ANT_PATH_INTERNAL 2
-
-int dvb_usb_mxl111sf_rfswitch =
-#if 0
-               ANT_PATH_AUTO;
-#else
-               ANT_PATH_EXTERNAL;
-#endif
-
-module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
-MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define deb_info pr_debug
-#define deb_reg pr_debug
-#define deb_adv pr_debug
-#define err pr_err
-#define info pr_info
-
-int mxl111sf_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 */
-       int ret;
-       u8 sndbuf[1+wlen];
-
-       deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
-
-       memset(sndbuf, 0, 1+wlen);
-
-       sndbuf[0] = cmd;
-       memcpy(&sndbuf[1], wbuf, wlen);
-
-       ret = (wo) ? dvb_usbv2_generic_write(d, sndbuf, 1+wlen) :
-               dvb_usbv2_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-#define MXL_CMD_REG_READ       0xaa
-#define MXL_CMD_REG_WRITE      0x55
-
-int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
-{
-       u8 buf[2];
-       int ret;
-
-       ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
-       if (mxl_fail(ret)) {
-               mxl_debug("error reading reg: 0x%02x", addr);
-               goto fail;
-       }
-
-       if (buf[0] == addr)
-               *data = buf[1];
-       else {
-               err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
-                   addr, buf[0], buf[1]);
-               ret = -EINVAL;
-       }
-
-       deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
-fail:
-       return ret;
-}
-
-int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
-{
-       u8 buf[] = { addr, data };
-       int ret;
-
-       deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
-
-       ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
-       if (mxl_fail(ret))
-               err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
-                                  u8 addr, u8 mask, u8 data)
-{
-       int ret;
-       u8 val;
-
-       if (mask != 0xff) {
-               ret = mxl111sf_read_reg(state, addr, &val);
-#if 1
-               /* dont know why this usually errors out on the first try */
-               if (mxl_fail(ret))
-                       err("error writing addr: 0x%02x, mask: 0x%02x, "
-                           "data: 0x%02x, retrying...", addr, mask, data);
-
-               ret = mxl111sf_read_reg(state, addr, &val);
-#endif
-               if (mxl_fail(ret))
-                       goto fail;
-       }
-       val &= ~mask;
-       val |= data;
-
-       ret = mxl111sf_write_reg(state, addr, val);
-       mxl_fail(ret);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
-                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
-{
-       int i, ret = 0;
-
-       for (i = 0;  ctrl_reg_info[i].addr |
-                    ctrl_reg_info[i].mask |
-                    ctrl_reg_info[i].data;  i++) {
-
-               ret = mxl111sf_write_reg_mask(state,
-                                             ctrl_reg_info[i].addr,
-                                             ctrl_reg_info[i].mask,
-                                             ctrl_reg_info[i].data);
-               if (mxl_fail(ret)) {
-                       err("failed on reg #%d (0x%02x)", i,
-                           ctrl_reg_info[i].addr);
-                       break;
-               }
-       }
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
-{
-       int ret;
-       u8 id, ver;
-       char *mxl_chip, *mxl_rev;
-
-       if ((state->chip_id) && (state->chip_ver))
-               return 0;
-
-       ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
-       if (mxl_fail(ret))
-               goto fail;
-       state->chip_id = id;
-
-       ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
-       if (mxl_fail(ret))
-               goto fail;
-       state->chip_ver = ver;
-
-       switch (id) {
-       case 0x61:
-               mxl_chip = "MxL101SF";
-               break;
-       case 0x63:
-               mxl_chip = "MxL111SF";
-               break;
-       default:
-               mxl_chip = "UNKNOWN MxL1X1";
-               break;
-       }
-       switch (ver) {
-       case 0x36:
-               state->chip_rev = MXL111SF_V6;
-               mxl_rev = "v6";
-               break;
-       case 0x08:
-               state->chip_rev = MXL111SF_V8_100;
-               mxl_rev = "v8_100";
-               break;
-       case 0x18:
-               state->chip_rev = MXL111SF_V8_200;
-               mxl_rev = "v8_200";
-               break;
-       default:
-               state->chip_rev = 0;
-               mxl_rev = "UNKNOWN REVISION";
-               break;
-       }
-       info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
-fail:
-       return ret;
-}
-
-#define get_chip_info(state)                                           \
-({                                                                     \
-       int ___ret;                                                     \
-       ___ret = mxl1x1sf_get_chip_info(state);                         \
-       if (mxl_fail(___ret)) {                                         \
-               mxl_debug("failed to get chip info"                     \
-                         " on first probe attempt");                   \
-               ___ret = mxl1x1sf_get_chip_info(state);                 \
-               if (mxl_fail(___ret))                                   \
-                       err("failed to get chip info during probe");    \
-               else                                                    \
-                       mxl_debug("probe needed a retry "               \
-                                 "in order to succeed.");              \
-       }                                                               \
-       ___ret;                                                         \
-})
-
-/* ------------------------------------------------------------------------ */
-#if 0
-static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
-       /* power control depends on which adapter is being woken:
-        * save this for init, instead, via mxl111sf_adap_fe_init */
-       return 0;
-}
-#endif
-
-static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
-{
-       struct dvb_usb_device *d = fe_to_d(fe);
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
-       int err;
-
-       /* exit if we didnt initialize the driver yet */
-       if (!state->chip_id) {
-               mxl_debug("driver not yet initialized, exit.");
-               goto fail;
-       }
-
-       deb_info("%s()\n", __func__);
-
-       mutex_lock(&state->fe_lock);
-
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       err = mxl1x1sf_soft_reset(state);
-       mxl_fail(err);
-       err = mxl111sf_init_tuner_demod(state);
-       mxl_fail(err);
-       err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-
-       mxl_fail(err);
-       mxl111sf_enable_usb_output(state);
-       mxl_fail(err);
-       mxl1x1sf_top_master_ctrl(state, 1);
-       mxl_fail(err);
-
-       if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
-           (state->chip_rev > MXL111SF_V6)) {
-               mxl111sf_config_pin_mux_modes(state,
-                                             PIN_MUX_TS_SPI_IN_MODE_1);
-               mxl_fail(err);
-       }
-       err = mxl111sf_init_port_expander(state);
-       if (!mxl_fail(err)) {
-               state->gpio_mode = adap_state->gpio_mode;
-               err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-               mxl_fail(err);
-#if 0
-               err = fe->ops.init(fe);
-#endif
-               msleep(100); /* add short delay after enabling
-                             * the demod before touching it */
-       }
-
-       return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
-fail:
-       return -ENODEV;
-}
-
-static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
-       int err;
-
-       /* exit if we didnt initialize the driver yet */
-       if (!state->chip_id) {
-               mxl_debug("driver not yet initialized, exit.");
-               goto fail;
-       }
-
-       deb_info("%s()\n", __func__);
-
-       err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
-
-       mutex_unlock(&state->fe_lock);
-
-       return err;
-fail:
-       return -ENODEV;
-}
-
-
-static int mxl111sf_ep6_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
-       int ret = 0;
-
-       deb_info("%s(%d)\n", __func__, onoff);
-
-       if (onoff) {
-               ret = mxl111sf_enable_usb_output(state);
-               mxl_fail(ret);
-               ret = mxl111sf_config_mpeg_in(state, 1, 1,
-                                             adap_state->ep6_clockphase,
-                                             0, 0);
-               mxl_fail(ret);
-#if 0
-       } else {
-               ret = mxl111sf_disable_656_port(state);
-               mxl_fail(ret);
-#endif
-       }
-
-       return ret;
-}
-
-static int mxl111sf_ep5_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       int ret = 0;
-
-       deb_info("%s(%d)\n", __func__, onoff);
-
-       if (onoff) {
-               ret = mxl111sf_enable_usb_output(state);
-               mxl_fail(ret);
-
-               ret = mxl111sf_init_i2s_port(state, 200);
-               mxl_fail(ret);
-               ret = mxl111sf_config_i2s(state, 0, 15);
-               mxl_fail(ret);
-       } else {
-               ret = mxl111sf_disable_i2s_port(state);
-               mxl_fail(ret);
-       }
-       if (state->chip_rev > MXL111SF_V6)
-               ret = mxl111sf_config_spi(state, onoff);
-       mxl_fail(ret);
-
-       return ret;
-}
-
-static int mxl111sf_ep4_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       int ret = 0;
-
-       deb_info("%s(%d)\n", __func__, onoff);
-
-       if (onoff) {
-               ret = mxl111sf_enable_usb_output(state);
-               mxl_fail(ret);
-       }
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static struct lgdt3305_config hauppauge_lgdt3305_config = {
-       .i2c_addr           = 0xb2 >> 1,
-       .mpeg_mode          = LGDT3305_MPEG_SERIAL,
-       .tpclk_edge         = LGDT3305_TPCLK_RISING_EDGE,
-       .tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .qam_if_khz         = 6000,
-       .vsb_if_khz         = 6000,
-};
-
-static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_TUNER_MODE;
-       adap_state->ep6_clockphase = 1;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_init_port_expander(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       adap->fe[fe_id] = dvb_attach(lgdt3305_attach,
-                                &hauppauge_lgdt3305_config,
-                                &d->i2c_adap);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static struct lg2160_config hauppauge_lg2160_config = {
-       .lg_chip            = LG2160,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-};
-
-static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_TUNER_MODE;
-       adap_state->ep6_clockphase = 1;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_init_port_expander(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = get_chip_info(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       adap->fe[fe_id] = dvb_attach(lg2160_attach,
-                             &hauppauge_lg2160_config,
-                             &d->i2c_adap);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static struct lg2160_config hauppauge_lg2161_1019_config = {
-       .lg_chip            = LG2161_1019,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-       .output_if          = 2, /* LG2161_OIF_SPI_MAS */
-};
-
-static struct lg2160_config hauppauge_lg2161_1040_config = {
-       .lg_chip            = LG2161_1040,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-       .output_if          = 4, /* LG2161_OIF_SPI_MAS */
-};
-
-static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_TUNER_MODE;
-       adap_state->ep6_clockphase = 1;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_init_port_expander(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = get_chip_info(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       adap->fe[fe_id] = dvb_attach(lg2160_attach,
-                             (MXL111SF_V8_200 == state->chip_rev) ?
-                             &hauppauge_lg2161_1040_config :
-                             &hauppauge_lg2161_1019_config,
-                             &d->i2c_adap);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static struct lg2160_config hauppauge_lg2161_1019_ep6_config = {
-       .lg_chip            = LG2161_1019,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-       .output_if          = 1, /* LG2161_OIF_SERIAL_TS */
-};
-
-static struct lg2160_config hauppauge_lg2161_1040_ep6_config = {
-       .lg_chip            = LG2161_1040,
-       .i2c_addr           = 0x1c >> 1,
-       .deny_i2c_rptr      = 1,
-       .spectral_inversion = 0,
-       .if_khz             = 6000,
-       .output_if          = 7, /* LG2161_OIF_SERIAL_TS */
-};
-
-static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_MH;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_TUNER_MODE;
-       adap_state->ep6_clockphase = 0;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_init_port_expander(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = get_chip_info(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       adap->fe[fe_id] = dvb_attach(lg2160_attach,
-                             (MXL111SF_V8_200 == state->chip_rev) ?
-                             &hauppauge_lg2161_1040_ep6_config :
-                             &hauppauge_lg2161_1019_ep6_config,
-                             &d->i2c_adap);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static struct mxl111sf_demod_config mxl_demod_config = {
-       .read_reg        = mxl111sf_read_reg,
-       .write_reg       = mxl111sf_write_reg,
-       .program_regs    = mxl111sf_ctrl_program_regs,
-};
-
-static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap, u8 fe_id)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct mxl111sf_state *state = d_to_priv(d);
-       struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
-       int ret;
-
-       deb_adv("%s()\n", __func__);
-
-       /* save a pointer to the dvb_usb_device in device state */
-       state->d = d;
-       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
-       state->alt_mode = adap_state->alt_mode;
-
-       if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-               err("set interface failed");
-
-       state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
-       adap_state->gpio_mode = state->gpio_mode;
-       adap_state->device_mode = MXL_SOC_MODE;
-       adap_state->ep6_clockphase = 1;
-
-       ret = mxl1x1sf_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl111sf_init_tuner_demod(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl111sf_enable_usb_output(state);
-       if (mxl_fail(ret))
-               goto fail;
-       ret = mxl1x1sf_top_master_ctrl(state, 1);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* dont care if this fails */
-       mxl111sf_init_port_expander(state);
-
-       adap->fe[fe_id] = dvb_attach(mxl111sf_demod_attach, state,
-                             &mxl_demod_config);
-       if (adap->fe[fe_id]) {
-               state->num_frontends++;
-               adap_state->fe_init = adap->fe[fe_id]->ops.init;
-               adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
-               adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
-               adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
-               return 0;
-       }
-       ret = -EIO;
-fail:
-       return ret;
-}
-
-static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
-                                       int antpath)
-{
-       return mxl111sf_idac_config(state, 1, 1,
-                                   (antpath == ANT_PATH_INTERNAL) ?
-                                   0x3f : 0x00, 0);
-}
-
-#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
-       err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
-           __func__, __LINE__, \
-           (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
-           pwr0, pwr1, pwr2, pwr3)
-
-#define ANT_HUNT_SLEEP 90
-#define ANT_EXT_TWEAK 0
-
-static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
-{
-       struct mxl111sf_state *state = fe_to_priv(fe);
-       int antctrl = dvb_usb_mxl111sf_rfswitch;
-
-       u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
-
-       /* FIXME: must force EXTERNAL for QAM - done elsewhere */
-       mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
-                             ANT_PATH_EXTERNAL : antctrl);
-
-       if (antctrl == ANT_PATH_AUTO) {
-#if 0
-               msleep(ANT_HUNT_SLEEP);
-#endif
-               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
-
-               mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
-               msleep(ANT_HUNT_SLEEP);
-               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
-
-               mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
-               msleep(ANT_HUNT_SLEEP);
-               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
-
-               mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
-               msleep(ANT_HUNT_SLEEP);
-               fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
-
-               if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
-                       /* return with EXTERNAL enabled */
-                       mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
-                       DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
-                                  rxPwr0, rxPwr1, rxPwr2);
-               } else {
-                       /* return with INTERNAL enabled */
-                       DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
-                                  rxPwr0, rxPwr1, rxPwr2);
-               }
-       }
-       return 0;
-}
-
-static struct mxl111sf_tuner_config mxl_tuner_config = {
-       .if_freq         = MXL_IF_6_0, /* applies to external IF output, only */
-       .invert_spectrum = 0,
-       .read_reg        = mxl111sf_read_reg,
-       .write_reg       = mxl111sf_write_reg,
-       .program_regs    = mxl111sf_ctrl_program_regs,
-       .top_master_ctrl = mxl1x1sf_top_master_ctrl,
-       .ant_hunt        = mxl111sf_ant_hunt,
-};
-
-static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
-{
-       struct mxl111sf_state *state = adap_to_priv(adap);
-       int i;
-
-       deb_adv("%s()\n", __func__);
-
-       for (i = 0; i < state->num_frontends; i++) {
-               if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,
-                               &mxl_tuner_config) == NULL)
-                       return -EIO;
-       }
-
-       return 0;
-}
-
-static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe,
-                                     unsigned int cmd, void *parg,
-                                     unsigned int stage)
-{
-       int err = 0;
-
-       switch (stage) {
-       case DVB_FE_IOCTL_PRE:
-
-               switch (cmd) {
-               case FE_READ_SIGNAL_STRENGTH:
-                       err = fe->ops.tuner_ops.get_rf_strength(fe, parg);
-                       /* If no error occurs, prevent dvb-core from handling
-                        * this IOCTL, otherwise return the error */
-                       if (0 == err)
-                               err = 1;
-                       break;
-               }
-               break;
-
-       case DVB_FE_IOCTL_POST:
-               /* no post-ioctl handling required */
-               break;
-       }
-       return err;
-};
-
-static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-struct i2c_algorithm mxl111sf_i2c_algo = {
-       .master_xfer   = mxl111sf_i2c_xfer,
-       .functionality = mxl111sf_i2c_func,
-#ifdef NEED_ALGO_CONTROL
-       .algo_control = dummy_algo_control,
-#endif
-};
-
-static int mxl111sf_init(struct dvb_usb_device *d)
-{
-       struct mxl111sf_state *state = d_to_priv(d);
-       int ret;
-       static u8 eeprom[256];
-       struct i2c_client c;
-
-       ret = get_chip_info(state);
-       if (mxl_fail(ret))
-               err("failed to get chip info during probe");
-
-       mutex_init(&state->fe_lock);
-
-       if (state->chip_rev > MXL111SF_V6)
-               mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1);
-
-       c.adapter = &d->i2c_adap;
-       c.addr = 0xa0 >> 1;
-
-       ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
-       if (mxl_fail(ret))
-               return 0;
-       tveeprom_hauppauge_analog(&c, &state->tv, (0x84 == eeprom[0xa0]) ?
-                       eeprom + 0xa0 : eeprom + 0x80);
-#if 0
-       switch (state->tv.model) {
-       case 117001:
-       case 126001:
-       case 138001:
-               break;
-       default:
-               printk(KERN_WARNING "%s: warning: "
-                      "unknown hauppauge model #%d\n",
-                      __func__, state->tv.model);
-       }
-#endif
-       return 0;
-}
-
-static int mxl111sf_frontend_attach_dvbt(struct dvb_usb_adapter *adap)
-{
-       return mxl111sf_attach_demod(adap, 0);
-}
-
-static int mxl111sf_frontend_attach_atsc(struct dvb_usb_adapter *adap)
-{
-       return mxl111sf_lgdt3305_frontend_attach(adap, 0);
-}
-
-static int mxl111sf_frontend_attach_mh(struct dvb_usb_adapter *adap)
-{
-       return mxl111sf_lg2160_frontend_attach(adap, 0);
-}
-
-static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       deb_info("%s\n", __func__);
-
-       ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
-       if (ret < 0)
-               return ret;
-
-       ret = mxl111sf_attach_demod(adap, 1);
-       if (ret < 0)
-               return ret;
-
-       ret = mxl111sf_lg2160_frontend_attach(adap, 2);
-       if (ret < 0)
-               return ret;
-
-       return ret;
-}
-
-static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       deb_info("%s\n", __func__);
-
-       ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
-       if (ret < 0)
-               return ret;
-
-       ret = mxl111sf_attach_demod(adap, 1);
-       if (ret < 0)
-               return ret;
-
-       ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
-       if (ret < 0)
-               return ret;
-
-       return ret;
-}
-
-static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
-{
-       int ret;
-       deb_info("%s\n", __func__);
-
-       ret = mxl111sf_attach_demod(adap, 0);
-       if (ret < 0)
-               return ret;
-
-       if (dvb_usb_mxl111sf_spi)
-               ret = mxl111sf_lg2161_frontend_attach(adap, 1);
-       else
-               ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 1);
-
-       return ret;
-}
-
-static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)
-{
-       deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint);
-       stream->type = USB_BULK;
-       stream->count = 5;
-       stream->endpoint = endpoint;
-       stream->u.bulk.buffersize = 8192;
-}
-
-static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,
-               u8 endpoint, int framesperurb, int framesize)
-{
-       deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint,
-                       framesperurb * framesize);
-       stream->type = USB_ISOC;
-       stream->count = 5;
-       stream->endpoint = endpoint;
-       stream->u.isoc.framesperurb = framesperurb;
-       stream->u.isoc.framesize = framesize;
-       stream->u.isoc.interval = 1;
-}
-
-/* DVB USB Driver stuff */
-
-/* dvbt       mxl111sf
- * bulk       EP4/BULK/5/8192
- * isoc       EP4/ISOC/5/96/564
- */
-static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       *ts_type = DVB_USB_FE_TS_TYPE_188;
-       if (dvb_usb_mxl111sf_isoc)
-               mxl111sf_stream_config_isoc(stream, 4, 96, 564);
-       else
-               mxl111sf_stream_config_bulk(stream, 4);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_dvbt = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_dvbt,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_ep4_streaming_ctrl,
-       .get_stream_config = mxl111sf_get_stream_config_dvbt,
-       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* atsc       lgdt3305
- * bulk       EP6/BULK/5/8192
- * isoc       EP6/ISOC/5/24/3072
- */
-static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       *ts_type = DVB_USB_FE_TS_TYPE_188;
-       if (dvb_usb_mxl111sf_isoc)
-               mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-       else
-               mxl111sf_stream_config_bulk(stream, 6);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_atsc = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_atsc,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_ep6_streaming_ctrl,
-       .get_stream_config = mxl111sf_get_stream_config_atsc,
-       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* mh         lg2160
- * bulk       EP5/BULK/5/8192/RAW
- * isoc       EP5/ISOC/5/96/200/RAW
- */
-static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-       if (dvb_usb_mxl111sf_isoc)
-               mxl111sf_stream_config_isoc(stream, 5, 96, 200);
-       else
-               mxl111sf_stream_config_bulk(stream, 5);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_mh = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_mh,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_ep5_streaming_ctrl,
-       .get_stream_config = mxl111sf_get_stream_config_mh,
-       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* atsc mh    lgdt3305           mxl111sf          lg2160
- * bulk       EP6/BULK/5/8192    EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
- * isoc       EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
- */
-static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       if (fe->id == 0) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-               else
-                       mxl111sf_stream_config_bulk(stream, 6);
-       } else if (fe->id == 1) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
-               else
-                       mxl111sf_stream_config_bulk(stream, 4);
-       } else if (fe->id == 2) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
-               else
-                       mxl111sf_stream_config_bulk(stream, 5);
-       }
-       return 0;
-}
-
-static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)
-{
-       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
-
-       if (fe->id == 0)
-               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
-       else if (fe->id == 1)
-               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
-       else if (fe->id == 2)
-               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_atsc_mh = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_atsc_mh,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_streaming_ctrl_atsc_mh,
-       .get_stream_config = mxl111sf_get_stream_config_atsc_mh,
-       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* mercury    lgdt3305           mxl111sf          lg2161
- * tp bulk    EP6/BULK/5/8192    EP4/BULK/5/8192   EP6/BULK/5/8192/RAW
- * tp isoc    EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
- * spi bulk   EP6/BULK/5/8192    EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
- * spi isoc   EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
- */
-static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       if (fe->id == 0) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-               else
-                       mxl111sf_stream_config_bulk(stream, 6);
-       } else if (fe->id == 1) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
-               else
-                       mxl111sf_stream_config_bulk(stream, 4);
-       } else if (fe->id == 2 && dvb_usb_mxl111sf_spi) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
-               else
-                       mxl111sf_stream_config_bulk(stream, 5);
-       } else if (fe->id == 2 && !dvb_usb_mxl111sf_spi) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-               else
-                       mxl111sf_stream_config_bulk(stream, 6);
-       }
-       return 0;
-}
-
-static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)
-{
-       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
-
-       if (fe->id == 0)
-               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
-       else if (fe->id == 1)
-               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
-       else if (fe->id == 2 && dvb_usb_mxl111sf_spi)
-               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
-       else if (fe->id == 2 && !dvb_usb_mxl111sf_spi)
-               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_mercury = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_mercury,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_streaming_ctrl_mercury,
-       .get_stream_config = mxl111sf_get_stream_config_mercury,
-       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-/* mercury mh mxl111sf          lg2161
- * tp bulk    EP4/BULK/5/8192   EP6/BULK/5/8192/RAW
- * tp isoc    EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
- * spi bulk   EP4/BULK/5/8192   EP5/BULK/5/8192/RAW
- * spi isoc   EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
- */
-static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,
-               u8 *ts_type, struct usb_data_stream_properties *stream)
-{
-       deb_info("%s: fe=%d\n", __func__, fe->id);
-
-       if (fe->id == 0) {
-               *ts_type = DVB_USB_FE_TS_TYPE_188;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 4, 96, 564);
-               else
-                       mxl111sf_stream_config_bulk(stream, 4);
-       } else if (fe->id == 1 && dvb_usb_mxl111sf_spi) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 5, 96, 200);
-               else
-                       mxl111sf_stream_config_bulk(stream, 5);
-       } else if (fe->id == 1 && !dvb_usb_mxl111sf_spi) {
-               *ts_type = DVB_USB_FE_TS_TYPE_RAW;
-               if (dvb_usb_mxl111sf_isoc)
-                       mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
-               else
-                       mxl111sf_stream_config_bulk(stream, 6);
-       }
-       return 0;
-}
-
-static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)
-{
-       deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
-
-       if (fe->id == 0)
-               return mxl111sf_ep4_streaming_ctrl(fe, onoff);
-       else if (fe->id == 1  && dvb_usb_mxl111sf_spi)
-               return mxl111sf_ep5_streaming_ctrl(fe, onoff);
-       else if (fe->id == 1 && !dvb_usb_mxl111sf_spi)
-               return mxl111sf_ep6_streaming_ctrl(fe, onoff);
-       return 0;
-}
-
-static struct dvb_usb_device_properties mxl111sf_props_mercury_mh = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct mxl111sf_state),
-
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .i2c_algo          = &mxl111sf_i2c_algo,
-       .frontend_attach   = mxl111sf_frontend_attach_mercury_mh,
-       .tuner_attach      = mxl111sf_attach_tuner,
-       .init              = mxl111sf_init,
-       .streaming_ctrl    = mxl111sf_streaming_ctrl_mercury_mh,
-       .get_stream_config = mxl111sf_get_stream_config_mercury_mh,
-       .fe_ioctl_override = mxl111sf_fe_ioctl_override,
-
-       .num_adapters = 1,
-       .adapter = {
-               {
-                       .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
-               }
-       }
-};
-
-static const struct usb_device_id mxl111sf_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702, &mxl111sf_props_mh, "HCW 117xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
-       { }
-};
-MODULE_DEVICE_TABLE(usb, mxl111sf_id_table);
-
-static struct usb_driver mxl111sf_usb_driver = {
-       .name = KBUILD_MODNAME,
-       .id_table = mxl111sf_id_table,
-       .probe = dvb_usbv2_probe,
-       .disconnect = dvb_usbv2_disconnect,
-       .suspend = dvb_usbv2_suspend,
-       .resume = dvb_usbv2_resume,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(mxl111sf_usb_driver);
-
-MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
-MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.h b/drivers/media/dvb/dvb-usb/mxl111sf.h
deleted file mode 100644 (file)
index 9816de8..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
- *
- *   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_MXL111SF_H_
-#define _DVB_USB_MXL111SF_H_
-
-#ifdef DVB_USB_LOG_PREFIX
-#undef DVB_USB_LOG_PREFIX
-#endif
-#define DVB_USB_LOG_PREFIX "mxl111sf"
-#include "dvb_usb.h"
-#include <media/tveeprom.h>
-
-#define MXL_EP1_REG_READ     1
-#define MXL_EP2_REG_WRITE    2
-#define MXL_EP3_INTERRUPT    3
-#define MXL_EP4_MPEG2        4
-#define MXL_EP5_I2S          5
-#define MXL_EP6_656          6
-#define MXL_EP6_MPEG2        6
-
-#ifdef USING_ENUM_mxl111sf_current_mode
-enum mxl111sf_current_mode {
-       mxl_mode_dvbt = MXL_EP4_MPEG2,
-       mxl_mode_mh   = MXL_EP5_I2S,
-       mxl_mode_atsc = MXL_EP6_MPEG2,
-};
-#endif
-
-enum mxl111sf_gpio_port_expander {
-       mxl111sf_gpio_hw,
-       mxl111sf_PCA9534,
-};
-
-struct mxl111sf_adap_state {
-       int alt_mode;
-       int gpio_mode;
-       int device_mode;
-       int ep6_clockphase;
-       int (*fe_init)(struct dvb_frontend *);
-       int (*fe_sleep)(struct dvb_frontend *);
-};
-
-struct mxl111sf_state {
-       struct dvb_usb_device *d;
-
-       enum mxl111sf_gpio_port_expander gpio_port_expander;
-       u8 port_expander_addr;
-
-       u8 chip_id;
-       u8 chip_ver;
-#define MXL111SF_V6     1
-#define MXL111SF_V8_100 2
-#define MXL111SF_V8_200 3
-       u8 chip_rev;
-
-#ifdef USING_ENUM_mxl111sf_current_mode
-       enum mxl111sf_current_mode current_mode;
-#endif
-
-#define MXL_TUNER_MODE         0
-#define MXL_SOC_MODE           1
-#define MXL_DEV_MODE_MASK      0x01
-#if 1
-       int device_mode;
-#endif
-       /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t),
-                                    EP5 BULK transfer (atsc-mh),
-                                    EP6 BULK transfer (atsc/qam),
-          use usb alt setting 2 for EP4 BULK transfer (dvb-t),
-                                    EP5 ISOC transfer (atsc-mh),
-                                    EP6 ISOC transfer (atsc/qam),
-        */
-       int alt_mode;
-       int gpio_mode;
-       struct tveeprom tv;
-
-       struct mutex fe_lock;
-       u8 num_frontends;
-       struct mxl111sf_adap_state adap_state[3];
-};
-
-int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data);
-int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data);
-
-struct mxl111sf_reg_ctrl_info {
-       u8 addr;
-       u8 mask;
-       u8 data;
-};
-
-int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
-                           u8 addr, u8 mask, u8 data);
-int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
-                              struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
-
-/* needed for hardware i2c functions in mxl111sf-i2c.c:
- * mxl111sf_i2c_send_data / mxl111sf_i2c_get_data */
-int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
-                     u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen);
-
-#define mxl_printk(kern, fmt, arg...) \
-       printk(kern "%s: " fmt "\n", __func__, ##arg)
-
-#define mxl_info(fmt, arg...) \
-       mxl_printk(KERN_INFO, fmt, ##arg)
-
-extern int dvb_usb_mxl111sf_debug;
-#define mxl_debug(fmt, arg...) \
-       if (dvb_usb_mxl111sf_debug) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-#define MXL_I2C_DBG 0x04
-#define MXL_ADV_DBG 0x10
-#define mxl_debug_adv(fmt, arg...) \
-       if (dvb_usb_mxl111sf_debug & MXL_ADV_DBG) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-#define mxl_i2c(fmt, arg...) \
-       if (dvb_usb_mxl111sf_debug & MXL_I2C_DBG) \
-               mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-#define mxl_i2c_adv(fmt, arg...) \
-       if ((dvb_usb_mxl111sf_debug & (MXL_I2C_DBG | MXL_ADV_DBG)) == \
-               (MXL_I2C_DBG | MXL_ADV_DBG)) \
-                       mxl_printk(KERN_DEBUG, fmt, ##arg)
-
-/* The following allows the mxl_fail() macro defined below to work
- * in externel modules, such as mxl111sf-tuner.ko, even though
- * dvb_usb_mxl111sf_debug is not defined within those modules */
-#if (defined(__MXL111SF_TUNER_H__)) || (defined(__MXL111SF_DEMOD_H__))
-#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG
-#else
-#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug
-#endif
-
-#define mxl_fail(ret)                                                  \
-({                                                                     \
-       int __ret;                                                      \
-       __ret = (ret < 0);                                              \
-       if ((__ret) && (MXL_ADV_DEBUG_ENABLED & MXL_ADV_DBG))           \
-               mxl_printk(KERN_ERR, "error %d on line %d",             \
-                          ret, __LINE__);                              \
-       __ret;                                                          \
-})
-
-#endif /* _DVB_USB_MXL111SF_H_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/dvb-usb/usb_urb.c b/drivers/media/dvb/dvb-usb/usb_urb.c
deleted file mode 100644 (file)
index eaf673a..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/* usb-urb.c is part of the DVB USB library.
- *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
- * see dvb-usb-init.c for copyright information.
- *
- * This file keeps functions for initializing and handling the
- * BULK and ISOC USB data transfers in a generic way.
- * Can be used for DVB-only and also, that's the plan, for
- * Hybrid USB devices (analog and DVB).
- */
-#include "dvb_usb_common.h"
-
-/* URB stuff for streaming */
-
-int usb_urb_reconfig(struct usb_data_stream *stream,
-               struct usb_data_stream_properties *props);
-
-static void usb_urb_complete(struct urb *urb)
-{
-       struct usb_data_stream *stream = urb->context;
-       int ptype = usb_pipetype(urb->pipe);
-       int i;
-       u8 *b;
-
-       dev_dbg(&stream->udev->dev, "%s: %s urb completed status=%d " \
-                       "length=%d/%d pack_num=%d errors=%d\n", __func__,
-                       ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
-                       urb->status, urb->actual_length,
-                       urb->transfer_buffer_length,
-                       urb->number_of_packets, urb->error_count);
-
-       switch (urb->status) {
-       case 0:         /* success */
-       case -ETIMEDOUT:    /* NAK */
-               break;
-       case -ECONNRESET:   /* kill */
-       case -ENOENT:
-       case -ESHUTDOWN:
-               return;
-       default:        /* error */
-               dev_dbg(&stream->udev->dev, "%s: urb completition failed=%d\n",
-                               __func__, urb->status);
-               break;
-       }
-
-       b = (u8 *) urb->transfer_buffer;
-       switch (ptype) {
-       case PIPE_ISOCHRONOUS:
-               for (i = 0; i < urb->number_of_packets; i++) {
-                       if (urb->iso_frame_desc[i].status != 0)
-                               dev_dbg(&stream->udev->dev, "%s: iso frame " \
-                                               "descriptor has an error=%d\n",
-                                               __func__,
-                                               urb->iso_frame_desc[i].status);
-                       else if (urb->iso_frame_desc[i].actual_length > 0)
-                               stream->complete(stream,
-                                       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;
-               }
-               break;
-       case PIPE_BULK:
-               if (urb->actual_length > 0)
-                       stream->complete(stream, b, urb->actual_length);
-               break;
-       default:
-               dev_err(&stream->udev->dev, "%s: unknown endpoint type in " \
-                               "completition handler\n", KBUILD_MODNAME);
-               return;
-       }
-       usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-int usb_urb_killv2(struct usb_data_stream *stream)
-{
-       int i;
-       for (i = 0; i < stream->urbs_submitted; i++) {
-               dev_dbg(&stream->udev->dev, "%s: kill urb=%d\n", __func__, i);
-               /* stop the URB */
-               usb_kill_urb(stream->urb_list[i]);
-       }
-       stream->urbs_submitted = 0;
-       return 0;
-}
-
-int usb_urb_submitv2(struct usb_data_stream *stream,
-               struct usb_data_stream_properties *props)
-{
-       int i, ret;
-
-       if (props) {
-               ret = usb_urb_reconfig(stream, props);
-               if (ret < 0)
-                       return ret;
-       }
-
-       for (i = 0; i < stream->urbs_initialized; i++) {
-               dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i);
-               ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC);
-               if (ret) {
-                       dev_err(&stream->udev->dev, "%s: could not submit " \
-                                       "urb no. %d - get them all back\n",
-                                       KBUILD_MODNAME, i);
-                       usb_urb_killv2(stream);
-                       return ret;
-               }
-               stream->urbs_submitted++;
-       }
-       return 0;
-}
-
-int usb_urb_free_urbs(struct usb_data_stream *stream)
-{
-       int i;
-
-       usb_urb_killv2(stream);
-
-       for (i = stream->urbs_initialized - 1; i >= 0; i--) {
-               if (stream->urb_list[i]) {
-                       dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
-                                       __func__, i);
-                       /* free the URBs */
-                       usb_free_urb(stream->urb_list[i]);
-               }
-       }
-       stream->urbs_initialized = 0;
-
-       return 0;
-}
-
-static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream)
-{
-       int i, j;
-
-       /* allocate the URBs */
-       for (i = 0; i < stream->props.count; i++) {
-               dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
-               stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
-               if (!stream->urb_list[i]) {
-                       dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
-                       for (j = 0; j < i; j++)
-                               usb_free_urb(stream->urb_list[j]);
-                       return -ENOMEM;
-               }
-               usb_fill_bulk_urb(stream->urb_list[i],
-                               stream->udev,
-                               usb_rcvbulkpipe(stream->udev,
-                                               stream->props.endpoint),
-                               stream->buf_list[i],
-                               stream->props.u.bulk.buffersize,
-                               usb_urb_complete, stream);
-
-               stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
-               stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
-               stream->urbs_initialized++;
-       }
-       return 0;
-}
-
-static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
-{
-       int i, j;
-
-       /* allocate the URBs */
-       for (i = 0; i < stream->props.count; i++) {
-               struct urb *urb;
-               int frame_offset = 0;
-               dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
-               stream->urb_list[i] = usb_alloc_urb(
-                               stream->props.u.isoc.framesperurb, GFP_ATOMIC);
-               if (!stream->urb_list[i]) {
-                       dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
-                       for (j = 0; j < i; j++)
-                               usb_free_urb(stream->urb_list[j]);
-                       return -ENOMEM;
-               }
-
-               urb = stream->urb_list[i];
-
-               urb->dev = stream->udev;
-               urb->context = stream;
-               urb->complete = usb_urb_complete;
-               urb->pipe = usb_rcvisocpipe(stream->udev,
-                               stream->props.endpoint);
-               urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
-               urb->interval = stream->props.u.isoc.interval;
-               urb->number_of_packets = stream->props.u.isoc.framesperurb;
-               urb->transfer_buffer_length = stream->props.u.isoc.framesize *
-                               stream->props.u.isoc.framesperurb;
-               urb->transfer_buffer = stream->buf_list[i];
-               urb->transfer_dma = stream->dma_addr[i];
-
-               for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
-                       urb->iso_frame_desc[j].offset = frame_offset;
-                       urb->iso_frame_desc[j].length =
-                                       stream->props.u.isoc.framesize;
-                       frame_offset += stream->props.u.isoc.framesize;
-               }
-
-               stream->urbs_initialized++;
-       }
-       return 0;
-}
-
-int usb_free_stream_buffers(struct usb_data_stream *stream)
-{
-       if (stream->state & USB_STATE_URB_BUF) {
-               while (stream->buf_num) {
-                       stream->buf_num--;
-                       dev_dbg(&stream->udev->dev, "%s: free buf=%d\n",
-                               __func__, stream->buf_num);
-                       usb_free_coherent(stream->udev, stream->buf_size,
-                                         stream->buf_list[stream->buf_num],
-                                         stream->dma_addr[stream->buf_num]);
-               }
-       }
-
-       stream->state &= ~USB_STATE_URB_BUF;
-
-       return 0;
-}
-
-int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
-               unsigned long size)
-{
-       stream->buf_num = 0;
-       stream->buf_size = size;
-
-       dev_dbg(&stream->udev->dev, "%s: all in all I will use %lu bytes for " \
-                       "streaming\n", __func__,  num * size);
-
-       for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
-               stream->buf_list[stream->buf_num] = usb_alloc_coherent(
-                               stream->udev, size, GFP_ATOMIC,
-                               &stream->dma_addr[stream->buf_num]);
-               if (!stream->buf_list[stream->buf_num]) {
-                       dev_dbg(&stream->udev->dev, "%s: alloc buf=%d failed\n",
-                                       __func__, stream->buf_num);
-                       usb_free_stream_buffers(stream);
-                       return -ENOMEM;
-               }
-
-               dev_dbg(&stream->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
-                               __func__, stream->buf_num,
-                               stream->buf_list[stream->buf_num],
-                               (long long)stream->dma_addr[stream->buf_num]);
-               memset(stream->buf_list[stream->buf_num], 0, size);
-               stream->state |= USB_STATE_URB_BUF;
-       }
-
-       return 0;
-}
-
-int usb_urb_reconfig(struct usb_data_stream *stream,
-               struct usb_data_stream_properties *props)
-{
-       int buf_size;
-
-       if (!props)
-               return 0;
-
-       /* check allocated buffers are large enough for the request */
-       if (props->type == USB_BULK) {
-               buf_size = stream->props.u.bulk.buffersize;
-       } else if (props->type == USB_ISOC) {
-               buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb;
-       } else {
-               dev_err(&stream->udev->dev, "%s: invalid endpoint type=%d\n",
-                               KBUILD_MODNAME, props->type);
-               return -EINVAL;
-       }
-
-       if (stream->buf_num < props->count || stream->buf_size < buf_size) {
-               dev_err(&stream->udev->dev, "%s: cannot reconfigure as " \
-                               "allocated buffers are too small\n",
-                               KBUILD_MODNAME);
-               return -EINVAL;
-       }
-
-       /* check if all fields are same */
-       if (stream->props.type == props->type &&
-                       stream->props.count == props->count &&
-                       stream->props.endpoint == props->endpoint) {
-               if (props->type == USB_BULK &&
-                               props->u.bulk.buffersize ==
-                               stream->props.u.bulk.buffersize)
-                       return 0;
-               else if (props->type == USB_ISOC &&
-                               props->u.isoc.framesperurb ==
-                               stream->props.u.isoc.framesperurb &&
-                               props->u.isoc.framesize ==
-                               stream->props.u.isoc.framesize &&
-                               props->u.isoc.interval ==
-                               stream->props.u.isoc.interval)
-                       return 0;
-       }
-
-       dev_dbg(&stream->udev->dev, "%s: re-alloc urbs\n", __func__);
-
-       usb_urb_free_urbs(stream);
-       memcpy(&stream->props, props, sizeof(*props));
-       if (props->type == USB_BULK)
-               return usb_urb_alloc_bulk_urbs(stream);
-       else if (props->type == USB_ISOC)
-               return usb_urb_alloc_isoc_urbs(stream);
-
-       return 0;
-}
-
-int usb_urb_initv2(struct usb_data_stream *stream,
-               const struct usb_data_stream_properties *props)
-{
-       int ret;
-
-       if (!stream || !props)
-               return -EINVAL;
-
-       memcpy(&stream->props, props, sizeof(*props));
-
-       if (!stream->complete) {
-               dev_err(&stream->udev->dev, "%s: there is no data callback - " \
-                               "this doesn't make sense\n", KBUILD_MODNAME);
-               return -EINVAL;
-       }
-
-       switch (stream->props.type) {
-       case USB_BULK:
-               ret = usb_alloc_stream_buffers(stream, stream->props.count,
-                               stream->props.u.bulk.buffersize);
-               if (ret < 0)
-                       return ret;
-
-               return usb_urb_alloc_bulk_urbs(stream);
-       case USB_ISOC:
-               ret = usb_alloc_stream_buffers(stream, stream->props.count,
-                               stream->props.u.isoc.framesize *
-                               stream->props.u.isoc.framesperurb);
-               if (ret < 0)
-                       return ret;
-
-               return usb_urb_alloc_isoc_urbs(stream);
-       default:
-               dev_err(&stream->udev->dev, "%s: unknown urb-type for data " \
-                               "transfer\n", KBUILD_MODNAME);
-               return -EINVAL;
-       }
-}
-
-int usb_urb_exitv2(struct usb_data_stream *stream)
-{
-       usb_urb_free_urbs(stream);
-       usb_free_stream_buffers(stream);
-
-       return 0;
-}