[media] lmedm04: fix build
authorMauro Carvalho Chehab <mchehab@redhat.com>
Sun, 12 Aug 2012 10:53:33 +0000 (07:53 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sun, 12 Aug 2012 10:53:33 +0000 (07:53 -0300)
Those files were at the wrong place, probably due to the usage of a
previous version of dvb-usb-v2 tree.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/dvb-usb-v2/lmedm04.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb-v2/lmedm04.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb/lmedm04.c [deleted file]
drivers/media/dvb/dvb-usb/lmedm04.h [deleted file]

diff --git a/drivers/media/dvb/dvb-usb-v2/lmedm04.c b/drivers/media/dvb/dvb-usb-v2/lmedm04.c
new file mode 100644 (file)
index 0000000..c6bc1b8
--- /dev/null
@@ -0,0 +1,1373 @@
+/* DVB USB compliant linux driver for
+ *
+ * DM04/QQBOX DVB-S USB BOX    LME2510C + SHARP:BS2F7HZ7395
+ *                             LME2510C + LG TDQY-P001F
+ *                             LME2510C + BS2F7HZ0194
+ *                             LME2510 + LG TDQY-P001F
+ *                             LME2510 + BS2F7HZ0194
+ *
+ * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
+ * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
+ *
+ * MV001F (LME2510+LGTDQY-P001F)
+ * LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ * MVB0001F (LME2510C+LGTDQT-P001F)
+ *
+ * MV0194 (LME2510+SHARP:BS2F7HZ0194)
+ * SHARP:BS2F7HZ0194 = (STV0299+IX2410)
+ *
+ * MVB0194 (LME2510C+SHARP0194)
+ *
+ * LME2510C + M88RS2000
+ *
+ * For firmware see Documentation/dvb/lmedm04.txt
+ *
+ * I2C addresses:
+ * 0xd0 - STV0288      - Demodulator
+ * 0xc0 - Sharp IX2505V        - Tuner
+ * --
+ * 0x1c - TDA10086   - Demodulator
+ * 0xc0 - TDA8263    - Tuner
+ * --
+ * 0xd0 - STV0299      - Demodulator
+ * 0xc0 - IX2410       - Tuner
+ *
+ *
+ * VID = 3344  PID LME2510=1122 LME2510C=1120
+ *
+ * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
+ * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ * Known Issues :
+ *     LME2510: Non Intel USB chipsets fail to maintain High Speed on
+ * Boot or Hot Plug.
+ *
+ * QQbox suffers from noise on LNB voltage.
+ *
+ *     LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
+ * with other tuners. After a cold reset streaming will not start.
+ *
+ * M88RS2000 suffers from loss of lock.
+ */
+#define DVB_USB_LOG_PREFIX "LME2510(C)"
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <media/rc-core.h>
+
+#include "dvb_usb.h"
+#include "lmedm04.h"
+#include "tda826x.h"
+#include "tda10086.h"
+#include "stv0288.h"
+#include "ix2505v.h"
+#include "stv0299.h"
+#include "dvb-pll.h"
+#include "z0194a.h"
+#include "m88rs2000.h"
+
+
+#define LME2510_C_S7395        "dvb-usb-lme2510c-s7395.fw";
+#define LME2510_C_LG   "dvb-usb-lme2510c-lg.fw";
+#define LME2510_C_S0194        "dvb-usb-lme2510c-s0194.fw";
+#define LME2510_C_RS2000 "dvb-usb-lme2510c-rs2000.fw";
+#define LME2510_LG     "dvb-usb-lme2510-lg.fw";
+#define LME2510_S0194  "dvb-usb-lme2510-s0194.fw";
+
+/* debug */
+static int dvb_usb_lme2510_debug;
+#define lme_debug(var, level, args...) do { \
+       if ((var >= level)) \
+               pr_debug(DVB_USB_LOG_PREFIX": " args); \
+} while (0)
+#define deb_info(level, args...) lme_debug(dvb_usb_lme2510_debug, level, args)
+#define debug_data_snipet(level, name, p) \
+        deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
+               *p, *(p+1), *(p+2), *(p+3), *(p+4), \
+                       *(p+5), *(p+6), *(p+7));
+#define info(args...) pr_info(DVB_USB_LOG_PREFIX": "args)
+
+module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+static int dvb_usb_lme2510_firmware;
+module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
+MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
+
+static int pid_filter;
+module_param_named(pid, pid_filter, int, 0644);
+MODULE_PARM_DESC(pid, "set default 0=default 1=off 2=on");
+
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define TUNER_DEFAULT  0x0
+#define TUNER_LG       0x1
+#define TUNER_S7395    0x2
+#define TUNER_S0194    0x3
+#define TUNER_RS2000   0x4
+
+struct lme2510_state {
+       u8 id;
+       u8 tuner_config;
+       u8 signal_lock;
+       u8 signal_level;
+       u8 signal_sn;
+       u8 time_key;
+       u8 last_key;
+       u8 key_timeout;
+       u8 i2c_talk_onoff;
+       u8 i2c_gate;
+       u8 i2c_tuner_gate_w;
+       u8 i2c_tuner_gate_r;
+       u8 i2c_tuner_addr;
+       u8 stream_on;
+       u8 pid_size;
+       u8 pid_off;
+       void *buffer;
+       struct urb *lme_urb;
+       void *usb_buffer;
+       int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t);
+       u8 dvb_usb_lme2510_firmware;
+};
+
+static int lme2510_bulk_write(struct usb_device *dev,
+                               u8 *snd, int len, u8 pipe)
+{
+       int ret, actual_l;
+
+       ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
+                               snd, len , &actual_l, 100);
+       return ret;
+}
+
+static int lme2510_bulk_read(struct usb_device *dev,
+                               u8 *rev, int len, u8 pipe)
+{
+       int ret, actual_l;
+
+       ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
+                                rev, len , &actual_l, 200);
+       return ret;
+}
+
+static int lme2510_usb_talk(struct dvb_usb_device *d,
+               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+       struct lme2510_state *st = d->priv;
+       u8 *buff;
+       int ret = 0;
+
+       if (st->usb_buffer == NULL) {
+               st->usb_buffer = kmalloc(64, GFP_KERNEL);
+               if (st->usb_buffer == NULL) {
+                       info("MEM Error no memory");
+                       return -ENOMEM;
+               }
+       }
+       buff = st->usb_buffer;
+
+       ret = mutex_lock_interruptible(&d->usb_mutex);
+
+       if (ret < 0)
+               return -EAGAIN;
+
+       /* the read/write capped at 64 */
+       memcpy(buff, wbuf, (wlen < 64) ? wlen : 64);
+
+       ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
+
+       ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ?
+                       rlen : 64 , 0x01);
+
+       if (rlen > 0)
+               memcpy(rbuf, buff, rlen);
+
+       mutex_unlock(&d->usb_mutex);
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static int lme2510_stream_restart(struct dvb_usb_device *d)
+{
+       struct lme2510_state *st = d->priv;
+       u8 all_pids[] = LME_ALL_PIDS;
+       u8 stream_on[] = LME_ST_ON_W;
+       int ret;
+       u8 rbuff[1];
+       if (st->pid_off)
+               ret = lme2510_usb_talk(d, all_pids, sizeof(all_pids),
+                       rbuff, sizeof(rbuff));
+       /*Restart Stream Command*/
+       ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
+                       rbuff, sizeof(rbuff));
+       return ret;
+}
+
+static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
+{
+       struct lme2510_state *st = d->priv;
+       static u8 pid_buff[] = LME_ZERO_PID;
+       static u8 rbuf[1];
+       u8 pid_no = index * 2;
+       u8 pid_len = pid_no + 2;
+       int ret = 0;
+       deb_info(1, "PID Setting Pid %04x", pid_out);
+
+       if (st->pid_size == 0)
+               ret |= lme2510_stream_restart(d);
+
+       pid_buff[2] = pid_no;
+       pid_buff[3] = (u8)pid_out & 0xff;
+       pid_buff[4] = pid_no + 1;
+       pid_buff[5] = (u8)(pid_out >> 8);
+
+       if (pid_len > st->pid_size)
+               st->pid_size = pid_len;
+       pid_buff[7] = 0x80 + st->pid_size;
+
+       ret |= lme2510_usb_talk(d, pid_buff ,
+               sizeof(pid_buff) , rbuf, sizeof(rbuf));
+
+       if (st->stream_on)
+               ret |= lme2510_stream_restart(d);
+
+       return ret;
+}
+
+static void lme2510_int_response(struct urb *lme_urb)
+{
+       struct dvb_usb_adapter *adap = lme_urb->context;
+       struct lme2510_state *st = adap_to_priv(adap);
+       static u8 *ibuf, *rbuf;
+       int i = 0, offset;
+       u32 key;
+
+       switch (lme_urb->status) {
+       case 0:
+       case -ETIMEDOUT:
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               return;
+       default:
+               info("Error %x", lme_urb->status);
+               break;
+       }
+
+       rbuf = (u8 *) lme_urb->transfer_buffer;
+
+       offset = ((lme_urb->actual_length/8) > 4)
+                       ? 4 : (lme_urb->actual_length/8) ;
+
+       for (i = 0; i < offset; ++i) {
+               ibuf = (u8 *)&rbuf[i*8];
+               deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x",
+               offset, i, ibuf[0], ibuf[1]);
+
+               switch (ibuf[0]) {
+               case 0xaa:
+                       debug_data_snipet(1, "INT Remote data snipet", ibuf);
+                       if ((ibuf[4] + ibuf[5]) == 0xff) {
+                               key = ibuf[5];
+                               key += (ibuf[3] > 0)
+                                       ? (ibuf[3] ^ 0xff) << 8 : 0;
+                               key += (ibuf[2] ^ 0xff) << 16;
+                               deb_info(1, "INT Key =%08x", key);
+                               if (adap_to_d(adap)->rc_dev != NULL)
+                                       rc_keydown(adap_to_d(adap)->rc_dev,
+                                               key, 0);
+                       }
+                       break;
+               case 0xbb:
+                       switch (st->tuner_config) {
+                       case TUNER_LG:
+                               if (ibuf[2] > 0)
+                                       st->signal_lock = ibuf[2];
+                               st->signal_level = ibuf[4];
+                               st->signal_sn = ibuf[3];
+                               st->time_key = ibuf[7];
+                               break;
+                       case TUNER_S7395:
+                       case TUNER_S0194:
+                               /* Tweak for earlier firmware*/
+                               if (ibuf[1] == 0x03) {
+                                       if (ibuf[2] > 1)
+                                               st->signal_lock = ibuf[2];
+                                       st->signal_level = ibuf[3];
+                                       st->signal_sn = ibuf[4];
+                               } else {
+                                       st->signal_level = ibuf[4];
+                                       st->signal_sn = ibuf[5];
+                                       st->signal_lock =
+                                               (st->signal_lock & 0xf7) +
+                                               ((ibuf[2] & 0x01) << 0x03);
+                               }
+                               break;
+                       case TUNER_RS2000:
+                               if (ibuf[1] == 0x3 &&  ibuf[6] == 0xff)
+                                       st->signal_lock = 0xff;
+                               else
+                                       st->signal_lock = 0x00;
+                               st->signal_level = ibuf[5];
+                               st->signal_sn = ibuf[4];
+                               st->time_key = ibuf[7];
+                       default:
+                               break;
+                       }
+                       debug_data_snipet(5, "INT Remote data snipet in", ibuf);
+               break;
+               case 0xcc:
+                       debug_data_snipet(1, "INT Control data snipet", ibuf);
+                       break;
+               default:
+                       debug_data_snipet(1, "INT Unknown data snipet", ibuf);
+               break;
+               }
+       }
+       usb_submit_urb(lme_urb, GFP_ATOMIC);
+}
+
+static int lme2510_int_read(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *lme_int = adap_to_priv(adap);
+
+       lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+       if (lme_int->lme_urb == NULL)
+                       return -ENOMEM;
+
+       lme_int->buffer = usb_alloc_coherent(d->udev, 128, GFP_ATOMIC,
+                                       &lme_int->lme_urb->transfer_dma);
+
+       if (lme_int->buffer == NULL)
+                       return -ENOMEM;
+
+       usb_fill_int_urb(lme_int->lme_urb,
+                               d->udev,
+                               usb_rcvintpipe(d->udev, 0xa),
+                               lme_int->buffer,
+                               128,
+                               lme2510_int_response,
+                               adap,
+                               8);
+
+       lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
+       info("INT Interrupt Service Started");
+
+       return 0;
+}
+
+static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = adap_to_priv(adap);
+       static u8 clear_pid_reg[] = LME_ALL_PIDS;
+       static u8 rbuf[1];
+       int ret = 0;
+
+       deb_info(1, "PID Clearing Filter");
+
+       mutex_lock(&d->i2c_mutex);
+
+       if (!onoff) {
+               ret |= lme2510_usb_talk(d, clear_pid_reg,
+                       sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
+               st->pid_off = true;
+       } else
+               st->pid_off = false;
+
+       st->pid_size = 0;
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return 0;
+}
+
+static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+       int onoff)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       int ret = 0;
+
+       deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
+               pid, index, onoff);
+
+       if (onoff) {
+               mutex_lock(&d->i2c_mutex);
+               ret |= lme2510_enable_pid(d, index, pid);
+               mutex_unlock(&d->i2c_mutex);
+       }
+
+
+       return ret;
+}
+
+
+static int lme2510_return_status(struct dvb_usb_device *d)
+{
+       int ret = 0;
+       u8 *data;
+
+       data = kzalloc(10, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+                       0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
+       info("Firmware Status: %x (%x)", ret , data[2]);
+
+       ret = (ret < 0) ? -ENODEV : data[2];
+       kfree(data);
+       return ret;
+}
+
+static int lme2510_msg(struct dvb_usb_device *d,
+               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+       int ret = 0;
+       struct lme2510_state *st = d->priv;
+
+       if (st->i2c_talk_onoff == 1) {
+
+               ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+
+               switch (st->tuner_config) {
+               case TUNER_LG:
+                       if (wbuf[2] == 0x1c) {
+                               if (wbuf[3] == 0x0e) {
+                                       st->signal_lock = rbuf[1];
+                                       if ((st->stream_on & 1) &&
+                                               (st->signal_lock & 0x10)) {
+                                               lme2510_stream_restart(d);
+                                               st->i2c_talk_onoff = 0;
+                                       }
+                                       msleep(80);
+                               }
+                       }
+                       break;
+               case TUNER_S7395:
+                       if (wbuf[2] == 0xd0) {
+                               if (wbuf[3] == 0x24) {
+                                       st->signal_lock = rbuf[1];
+                                       if ((st->stream_on & 1) &&
+                                               (st->signal_lock & 0x8)) {
+                                               lme2510_stream_restart(d);
+                                               st->i2c_talk_onoff = 0;
+                                       }
+                               }
+                       }
+                       break;
+               case TUNER_S0194:
+                       if (wbuf[2] == 0xd0) {
+                               if (wbuf[3] == 0x1b) {
+                                       st->signal_lock = rbuf[1];
+                                       if ((st->stream_on & 1) &&
+                                               (st->signal_lock & 0x8)) {
+                                               lme2510_stream_restart(d);
+                                               st->i2c_talk_onoff = 0;
+                                       }
+                               }
+                       }
+                       break;
+               case TUNER_RS2000:
+               default:
+                       break;
+               }
+       } else {
+               /* TODO rewrite this section */
+               switch (st->tuner_config) {
+               case TUNER_LG:
+                       switch (wbuf[3]) {
+                       case 0x0e:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_lock;
+                               break;
+                       case 0x43:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_level;
+                               break;
+                       case 0x1c:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_sn;
+                               break;
+                       case 0x15:
+                       case 0x16:
+                       case 0x17:
+                       case 0x18:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = 0x00;
+                               break;
+                       default:
+                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+                               st->i2c_talk_onoff = 1;
+                               break;
+                       }
+                       break;
+               case TUNER_S7395:
+                       switch (wbuf[3]) {
+                       case 0x10:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = (st->signal_level & 0x80)
+                                               ? 0 : (st->signal_level * 2);
+                               break;
+                       case 0x2d:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_sn;
+                               break;
+                       case 0x24:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_lock;
+                               break;
+                       case 0x2e:
+                       case 0x26:
+                       case 0x27:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = 0x00;
+                               break;
+                       default:
+                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+                               st->i2c_talk_onoff = 1;
+                               break;
+                       }
+                       break;
+               case TUNER_S0194:
+                       switch (wbuf[3]) {
+                       case 0x18:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = (st->signal_level & 0x80)
+                                               ? 0 : (st->signal_level * 2);
+                               break;
+                       case 0x24:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_sn;
+                               break;
+                       case 0x1b:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = st->signal_lock;
+                               break;
+                       case 0x19:
+                       case 0x25:
+                       case 0x1e:
+                       case 0x1d:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = 0x00;
+                               break;
+                       default:
+                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+                               st->i2c_talk_onoff = 1;
+                               break;
+                       }
+                       break;
+               case TUNER_RS2000:
+                       switch (wbuf[3]) {
+                       case 0x8c:
+                               rbuf[0] = 0x55;
+                               rbuf[1] = 0xff;
+                               if (st->last_key == st->time_key) {
+                                       st->key_timeout++;
+                                       if (st->key_timeout > 5)
+                                               rbuf[1] = 0;
+                               } else
+                                       st->key_timeout = 0;
+                               st->last_key = st->time_key;
+                               break;
+                       default:
+                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+                               st->i2c_talk_onoff = 1;
+                               break;
+                       }
+               default:
+                       break;
+               }
+
+               deb_info(4, "I2C From Interrupt Message out(%02x) in(%02x)",
+                               wbuf[3], rbuf[1]);
+
+       }
+
+       return ret;
+}
+
+
+static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+                                int num)
+{
+       struct dvb_usb_device *d = i2c_get_adapdata(adap);
+       struct lme2510_state *st = d->priv;
+       static u8 obuf[64], ibuf[64];
+       int i, read, read_o;
+       u16 len;
+       u8 gate = st->i2c_gate;
+
+       mutex_lock(&d->i2c_mutex);
+
+       if (gate == 0)
+               gate = 5;
+
+       for (i = 0; i < num; i++) {
+               read_o = 1 & (msg[i].flags & I2C_M_RD);
+               read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
+               read |= read_o;
+               gate = (msg[i].addr == st->i2c_tuner_addr)
+                       ? (read)        ? st->i2c_tuner_gate_r
+                                       : st->i2c_tuner_gate_w
+                       : st->i2c_gate;
+               obuf[0] = gate | (read << 7);
+
+               if (gate == 5)
+                       obuf[1] = (read) ? 2 : msg[i].len + 1;
+               else
+                       obuf[1] = msg[i].len + read + 1;
+
+               obuf[2] = msg[i].addr;
+               if (read) {
+                       if (read_o)
+                               len = 3;
+                       else {
+                               memcpy(&obuf[3], msg[i].buf, msg[i].len);
+                               obuf[msg[i].len+3] = msg[i+1].len;
+                               len = msg[i].len+4;
+                       }
+               } else {
+                       memcpy(&obuf[3], msg[i].buf, msg[i].len);
+                       len = msg[i].len+3;
+               }
+
+               if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) {
+                       deb_info(1, "i2c transfer failed.");
+                       mutex_unlock(&d->i2c_mutex);
+                       return -EAGAIN;
+               }
+
+               if (read) {
+                       if (read_o)
+                               memcpy(msg[i].buf, &ibuf[1], msg[i].len);
+                       else {
+                               memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
+                               i++;
+                       }
+               }
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+       return i;
+}
+
+static u32 lme2510_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm lme2510_i2c_algo = {
+       .master_xfer   = lme2510_i2c_xfer,
+       .functionality = lme2510_i2c_func,
+};
+
+static int lme2510_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct dvb_usb_adapter *adap = fe_to_adap(fe);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = adap_to_priv(adap);
+       static u8 clear_reg_3[] = LME_ALL_PIDS;
+       static u8 rbuf[1];
+       int ret = 0, rlen = sizeof(rbuf);
+
+       deb_info(1, "STM  (%02x)", onoff);
+
+       /* Streaming is started by FE_HAS_LOCK */
+       if (onoff == 1)
+               st->stream_on = 1;
+       else {
+               deb_info(1, "STM Steam Off");
+               /* mutex is here only to avoid collision with I2C */
+               mutex_lock(&d->i2c_mutex);
+
+               ret = lme2510_usb_talk(d, clear_reg_3,
+                               sizeof(clear_reg_3), rbuf, rlen);
+               st->stream_on = 0;
+               st->i2c_talk_onoff = 1;
+
+               mutex_unlock(&d->i2c_mutex);
+       }
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static u8 check_sum(u8 *p, u8 len)
+{
+       u8 sum = 0;
+       while (len--)
+               sum += *p++;
+       return sum;
+}
+
+static int lme2510_download_firmware(struct dvb_usb_device *d,
+                                       const struct firmware *fw)
+{
+       int ret = 0;
+       u8 *data;
+       u16 j, wlen, len_in, start, end;
+       u8 packet_size, dlen, i;
+       u8 *fw_data;
+
+       packet_size = 0x31;
+       len_in = 1;
+
+       data = kzalloc(128, GFP_KERNEL);
+       if (!data) {
+               info("FRM Could not start Firmware Download"\
+                       "(Buffer allocation failed)");
+               return -ENOMEM;
+       }
+
+       info("FRM Starting Firmware Download");
+
+       for (i = 1; i < 3; i++) {
+               start = (i == 1) ? 0 : 512;
+               end = (i == 1) ? 512 : fw->size;
+               for (j = start; j < end; j += (packet_size+1)) {
+                       fw_data = (u8 *)(fw->data + j);
+                       if ((end - j) > packet_size) {
+                               data[0] = i;
+                               dlen = packet_size;
+                       } else {
+                               data[0] = i | 0x80;
+                               dlen = (u8)(end - j)-1;
+                       }
+                       data[1] = dlen;
+                       memcpy(&data[2], fw_data, dlen+1);
+                       wlen = (u8) dlen + 4;
+                       data[wlen-1] = check_sum(fw_data, dlen+1);
+                       deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
+                               data[dlen+2], data[dlen+3]);
+                       lme2510_usb_talk(d, data, wlen, data, len_in);
+                       ret |= (data[0] == 0x88) ? 0 : -1;
+               }
+       }
+
+       usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+                       0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
+
+
+       data[0] = 0x8a;
+       len_in = 1;
+       msleep(2000);
+       lme2510_usb_talk(d, data, len_in, data, len_in);
+       msleep(400);
+
+       if (ret < 0)
+               info("FRM Firmware Download Failed (%04x)" , ret);
+       else
+               info("FRM Firmware Download Completed - Resetting Device");
+
+       kfree(data);
+       return RECONNECTS_USB;
+}
+
+static void lme_coldreset(struct dvb_usb_device *d)
+{
+       u8 data[1] = {0};
+       data[0] = 0x0a;
+       info("FRM Firmware Cold Reset");
+
+       lme2510_usb_talk(d, data, sizeof(data), data, sizeof(data));
+
+       return;
+}
+
+static const char fw_c_s7395[] = LME2510_C_S7395;
+static const char fw_c_lg[] = LME2510_C_LG;
+static const char fw_c_s0194[] = LME2510_C_S0194;
+static const char fw_c_rs2000[] = LME2510_C_RS2000;
+static const char fw_lg[] = LME2510_LG;
+static const char fw_s0194[] = LME2510_S0194;
+
+const char *lme_firmware_switch(struct dvb_usb_device *d, int cold)
+{
+       struct lme2510_state *st = d->priv;
+       struct usb_device *udev = d->udev;
+       const struct firmware *fw = NULL;
+       const char *fw_lme;
+       int ret = 0;
+
+       cold = (cold > 0) ? (cold & 1) : 0;
+
+       switch (le16_to_cpu(udev->descriptor.idProduct)) {
+       case 0x1122:
+               switch (st->dvb_usb_lme2510_firmware) {
+               default:
+                       st->dvb_usb_lme2510_firmware = TUNER_S0194;
+               case TUNER_S0194:
+                       fw_lme = fw_s0194;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0) {
+                               cold = 0;
+                               break;
+                       }
+                       st->dvb_usb_lme2510_firmware = TUNER_LG;
+               case TUNER_LG:
+                       fw_lme = fw_lg;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0)
+                               break;
+                       st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
+                       break;
+               }
+               break;
+       case 0x1120:
+               switch (st->dvb_usb_lme2510_firmware) {
+               default:
+                       st->dvb_usb_lme2510_firmware = TUNER_S7395;
+               case TUNER_S7395:
+                       fw_lme = fw_c_s7395;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0) {
+                               cold = 0;
+                               break;
+                       }
+                       st->dvb_usb_lme2510_firmware = TUNER_LG;
+               case TUNER_LG:
+                       fw_lme = fw_c_lg;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0)
+                               break;
+                       st->dvb_usb_lme2510_firmware = TUNER_S0194;
+               case TUNER_S0194:
+                       fw_lme = fw_c_s0194;
+                       ret = request_firmware(&fw, fw_lme, &udev->dev);
+                       if (ret == 0)
+                               break;
+                       st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
+                       cold = 0;
+                       break;
+               }
+               break;
+       case 0x22f0:
+               fw_lme = fw_c_rs2000;
+               st->dvb_usb_lme2510_firmware = TUNER_RS2000;
+               break;
+       default:
+               fw_lme = fw_c_s7395;
+       }
+
+       release_firmware(fw);
+
+       if (cold) {
+               dvb_usb_lme2510_firmware = st->dvb_usb_lme2510_firmware;
+               info("FRM Changing to %s firmware", fw_lme);
+               lme_coldreset(d);
+               return NULL;
+       }
+
+       return fw_lme;
+}
+
+static int lme2510_kill_urb(struct usb_data_stream *stream)
+{
+       int i;
+
+       for (i = 0; i < stream->urbs_submitted; i++) {
+               deb_info(3, "killing URB no. %d.", i);
+               /* stop the URB */
+               usb_kill_urb(stream->urb_list[i]);
+       }
+       stream->urbs_submitted = 0;
+
+       return 0;
+}
+
+static struct tda10086_config tda10086_config = {
+       .demod_address = 0x1c,
+       .invert = 0,
+       .diseqc_tone = 1,
+       .xtal_freq = TDA10086_XTAL_16M,
+};
+
+static struct stv0288_config lme_config = {
+       .demod_address = 0xd0,
+       .min_delay_ms = 15,
+       .inittab = s7395_inittab,
+};
+
+static struct ix2505v_config lme_tuner = {
+       .tuner_address = 0xc0,
+       .min_delay_ms = 100,
+       .tuner_gain = 0x0,
+       .tuner_chargepump = 0x3,
+};
+
+static struct stv0299_config sharp_z0194_config = {
+       .demod_address = 0xd0,
+       .inittab = sharp_z0194a_inittab,
+       .mclk = 88000000UL,
+       .invert = 0,
+       .skip_reinit = 0,
+       .lock_output = STV0299_LOCKOUTPUT_1,
+       .volt13_op0_op1 = STV0299_VOLT13_OP1,
+       .min_delay_ms = 100,
+       .set_symbol_rate = sharp_z0194a_set_symbol_rate,
+};
+
+static int dm04_rs2000_set_ts_param(struct dvb_frontend *fe,
+       int caller)
+{
+       struct dvb_usb_adapter *adap = fe_to_adap(fe);
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = d->priv;
+
+       mutex_lock(&d->i2c_mutex);
+       if ((st->i2c_talk_onoff == 1) && (st->stream_on & 1)) {
+               st->i2c_talk_onoff = 0;
+               lme2510_stream_restart(d);
+       }
+       mutex_unlock(&d->i2c_mutex);
+
+       return 0;
+}
+
+static struct m88rs2000_config m88rs2000_config = {
+       .demod_addr = 0xd0,
+       .tuner_addr = 0xc0,
+       .set_ts_params = dm04_rs2000_set_ts_param,
+};
+
+static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
+                                       fe_sec_voltage_t voltage)
+{
+       struct dvb_usb_device *d = fe_to_d(fe);
+       struct lme2510_state *st = fe_to_priv(fe);
+       static u8 voltage_low[] = LME_VOLTAGE_L;
+       static u8 voltage_high[] = LME_VOLTAGE_H;
+       static u8 rbuf[1];
+       int ret = 0, len = 3, rlen = 1;
+
+       mutex_lock(&d->i2c_mutex);
+
+       switch (voltage) {
+       case SEC_VOLTAGE_18:
+               ret |= lme2510_usb_talk(d,
+                       voltage_high, len, rbuf, rlen);
+               break;
+
+       case SEC_VOLTAGE_OFF:
+       case SEC_VOLTAGE_13:
+       default:
+               ret |= lme2510_usb_talk(d,
+                               voltage_low, len, rbuf, rlen);
+               break;
+       }
+
+       mutex_unlock(&d->i2c_mutex);
+
+       if (st->tuner_config == TUNER_RS2000)
+               if (st->fe_set_voltage)
+                       st->fe_set_voltage(fe, voltage);
+
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static int dm04_rs2000_read_signal_strength(struct dvb_frontend *fe,
+       u16 *strength)
+{
+       struct lme2510_state *st = fe_to_priv(fe);
+
+       *strength = (u16)((u32)st->signal_level * 0xffff / 0xff);
+
+       return 0;
+}
+
+static int dm04_rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct lme2510_state *st = fe_to_priv(fe);
+
+       *snr = (u16)((u32)st->signal_sn * 0xffff / 0x7f);
+
+       return 0;
+}
+
+static int dm04_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       *ber = 0;
+
+       return 0;
+}
+
+static int dm04_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+
+       return 0;
+}
+
+static int lme_name(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = adap_to_priv(adap);
+       const char *desc = d->name;
+       char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
+                               " SHARP:BS2F7HZ0194", " RS2000"};
+       char *name = adap->fe[0]->ops.info.name;
+
+       strlcpy(name, desc, 128);
+       strlcat(name, fe_name[st->tuner_config], 128);
+
+       return 0;
+}
+
+static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = d->priv;
+       int ret = 0;
+
+       st->i2c_talk_onoff = 1;
+       switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
+       case 0x1122:
+       case 0x1120:
+               st->i2c_gate = 4;
+               adap->fe[0] = dvb_attach(tda10086_attach,
+                       &tda10086_config, &d->i2c_adap);
+               if (adap->fe[0]) {
+                       info("TUN Found Frontend TDA10086");
+                       st->i2c_tuner_gate_w = 4;
+                       st->i2c_tuner_gate_r = 4;
+                       st->i2c_tuner_addr = 0xc0;
+                       st->tuner_config = TUNER_LG;
+                       if (st->dvb_usb_lme2510_firmware != TUNER_LG) {
+                               st->dvb_usb_lme2510_firmware = TUNER_LG;
+                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
+                       }
+                       break;
+               }
+
+               st->i2c_gate = 4;
+               adap->fe[0] = dvb_attach(stv0299_attach,
+                               &sharp_z0194_config, &d->i2c_adap);
+               if (adap->fe[0]) {
+                       info("FE Found Stv0299");
+                       st->i2c_tuner_gate_w = 4;
+                       st->i2c_tuner_gate_r = 5;
+                       st->i2c_tuner_addr = 0xc0;
+                       st->tuner_config = TUNER_S0194;
+                       if (st->dvb_usb_lme2510_firmware != TUNER_S0194) {
+                               st->dvb_usb_lme2510_firmware = TUNER_S0194;
+                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
+                       }
+                       break;
+               }
+
+               st->i2c_gate = 5;
+               adap->fe[0] = dvb_attach(stv0288_attach, &lme_config,
+                       &d->i2c_adap);
+
+               if (adap->fe[0]) {
+                       info("FE Found Stv0288");
+                       st->i2c_tuner_gate_w = 4;
+                       st->i2c_tuner_gate_r = 5;
+                       st->i2c_tuner_addr = 0xc0;
+                       st->tuner_config = TUNER_S7395;
+                       if (st->dvb_usb_lme2510_firmware != TUNER_S7395) {
+                               st->dvb_usb_lme2510_firmware = TUNER_S7395;
+                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
+                       }
+                       break;
+               }
+       case 0x22f0:
+               st->i2c_gate = 5;
+               adap->fe[0] = dvb_attach(m88rs2000_attach,
+                       &m88rs2000_config, &d->i2c_adap);
+
+               if (adap->fe[0]) {
+                       info("FE Found M88RS2000");
+                       st->i2c_tuner_gate_w = 5;
+                       st->i2c_tuner_gate_r = 5;
+                       st->i2c_tuner_addr = 0xc0;
+                       st->tuner_config = TUNER_RS2000;
+                       st->fe_set_voltage =
+                               adap->fe[0]->ops.set_voltage;
+
+                       adap->fe[0]->ops.read_signal_strength =
+                               dm04_rs2000_read_signal_strength;
+                       adap->fe[0]->ops.read_snr =
+                               dm04_rs2000_read_snr;
+                       adap->fe[0]->ops.read_ber =
+                               dm04_read_ber;
+                       adap->fe[0]->ops.read_ucblocks =
+                               dm04_read_ucblocks;
+               }
+               break;
+       }
+
+       if (adap->fe[0] == NULL) {
+               info("DM04/QQBOX Not Powered up or not Supported");
+               return -ENODEV;
+       }
+
+       if (ret) {
+               if (adap->fe[0]) {
+                       dvb_frontend_detach(adap->fe[0]);
+                       adap->fe[0] = NULL;
+               }
+               d->rc_map = NULL;
+               return -ENODEV;
+       }
+
+       adap->fe[0]->ops.set_voltage = dm04_lme2510_set_voltage;
+       ret = lme_name(adap);
+       return ret;
+}
+
+static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct lme2510_state *st = adap_to_priv(adap);
+       char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
+       int ret = 0;
+
+       switch (st->tuner_config) {
+       case TUNER_LG:
+               if (dvb_attach(tda826x_attach, adap->fe[0], 0xc0,
+                       &d->i2c_adap, 1))
+                       ret = st->tuner_config;
+               break;
+       case TUNER_S7395:
+               if (dvb_attach(ix2505v_attach , adap->fe[0], &lme_tuner,
+                       &d->i2c_adap))
+                       ret = st->tuner_config;
+               break;
+       case TUNER_S0194:
+               if (dvb_attach(dvb_pll_attach , adap->fe[0], 0xc0,
+                       &d->i2c_adap, DVB_PLL_OPERA1))
+                       ret = st->tuner_config;
+               break;
+       case TUNER_RS2000:
+               ret = st->tuner_config;
+               break;
+       default:
+               break;
+       }
+
+       if (ret)
+               info("TUN Found %s tuner", tun_msg[ret]);
+       else {
+               info("TUN No tuner found --- resetting device");
+               lme_coldreset(d);
+               return -ENODEV;
+       }
+
+       /* Start the Interrupt*/
+       ret = lme2510_int_read(adap);
+       if (ret < 0) {
+               info("INT Unable to start Interrupt Service");
+               return -ENODEV;
+       }
+
+       return ret;
+}
+
+static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
+{
+       struct lme2510_state *st = d->priv;
+       static u8 lnb_on[] = LNB_ON;
+       static u8 lnb_off[] = LNB_OFF;
+       static u8 rbuf[1];
+       int ret = 0, len = 3, rlen = 1;
+
+       mutex_lock(&d->i2c_mutex);
+
+       if (onoff)
+               ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
+       else
+               ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
+
+       st->i2c_talk_onoff = 1;
+
+       mutex_unlock(&d->i2c_mutex);
+
+       return ret;
+}
+
+static int lme2510_get_adapter_count(struct dvb_usb_device *d)
+{
+       return 1;
+}
+
+static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
+{
+       struct lme2510_state *st = d->priv;
+
+       usb_reset_configuration(d->udev);
+
+       usb_set_interface(d->udev,
+               d->intf->cur_altsetting->desc.bInterfaceNumber, 1);
+
+       st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
+
+       if (lme2510_return_status(d) == 0x44) {
+               *name = lme_firmware_switch(d, 0);
+               return COLD;
+       }
+
+       return 0;
+}
+
+static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
+               struct usb_data_stream_properties *stream)
+{
+       struct dvb_usb_adapter *adap = fe_to_adap(fe);
+       struct dvb_usb_device *d = adap_to_d(adap);
+
+       if (adap == NULL)
+               return 0;
+       /* Turn PID filter on the fly by module option */
+       if (pid_filter == 2) {
+               adap->pid_filtering  = 1;
+               adap->max_feed_count = 15;
+       }
+
+       if (!(le16_to_cpu(d->udev->descriptor.idProduct)
+               == 0x1122))
+               stream->endpoint = 0x8;
+
+       return 0;
+}
+
+static int lme2510_get_rc_config(struct dvb_usb_device *d,
+       struct dvb_usb_rc *rc)
+{
+       rc->allowed_protos = RC_TYPE_NEC;
+       return 0;
+}
+
+static void *lme2510_exit_int(struct dvb_usb_device *d)
+{
+       struct lme2510_state *st = d->priv;
+       struct dvb_usb_adapter *adap = &d->adapter[0];
+       void *buffer = NULL;
+
+       if (adap != NULL) {
+               lme2510_kill_urb(&adap->stream);
+       }
+
+       if (st->usb_buffer != NULL) {
+               st->i2c_talk_onoff = 1;
+               st->signal_lock = 0;
+               st->signal_level = 0;
+               st->signal_sn = 0;
+               buffer = st->usb_buffer;
+       }
+
+       if (st->lme_urb != NULL) {
+               usb_kill_urb(st->lme_urb);
+               usb_free_coherent(d->udev, 128, st->buffer,
+                                 st->lme_urb->transfer_dma);
+               info("Interrupt Service Stopped");
+       }
+
+       return buffer;
+}
+
+static void lme2510_exit(struct dvb_usb_device *d)
+{
+       void *usb_buffer;
+
+       if (d != NULL) {
+               usb_buffer = lme2510_exit_int(d);
+               if (usb_buffer != NULL)
+                       kfree(usb_buffer);
+       }
+}
+
+static struct dvb_usb_device_properties lme2510_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .bInterfaceNumber = 0,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct lme2510_state),
+
+       .download_firmware = lme2510_download_firmware,
+
+       .power_ctrl       = lme2510_powerup,
+       .identify_state   = lme2510_identify_state,
+       .i2c_algo         = &lme2510_i2c_algo,
+
+       .frontend_attach  = dm04_lme2510_frontend_attach,
+       .tuner_attach = dm04_lme2510_tuner,
+       .get_stream_config = lme2510_get_stream_config,
+       .get_adapter_count = lme2510_get_adapter_count,
+       .streaming_ctrl   = lme2510_streaming_ctrl,
+
+       .get_rc_config = lme2510_get_rc_config,
+
+       .exit = lme2510_exit,
+       .adapter = {
+               {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       .pid_filter_count = 15,
+                       .pid_filter = lme2510_pid_filter,
+                       .pid_filter_ctrl  = lme2510_pid_filter_ctrl,
+                       .stream =
+                       DVB_USB_STREAM_BULK(0x86, 10, 4096),
+               },
+               {
+               }
+       },
+};
+
+static const struct usb_device_id lme2510_id_table[] = {
+       {       DVB_USB_DEVICE(0x3344, 0x1122, &lme2510_props,
+               "DM04_LME2510_DVB-S", RC_MAP_LME2510)   },
+       {       DVB_USB_DEVICE(0x3344, 0x1120, &lme2510_props,
+               "DM04_LME2510C_DVB-S", RC_MAP_LME2510)  },
+       {       DVB_USB_DEVICE(0x3344, 0x22f0, &lme2510_props,
+               "DM04_LME2510C_DVB-S RS2000", RC_MAP_LME2510)   },
+       {}              /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, lme2510_id_table);
+
+static struct usb_driver lme2510_driver = {
+       .name           = KBUILD_MODNAME,
+       .probe          = dvb_usbv2_probe,
+       .disconnect     = dvb_usbv2_disconnect,
+       .id_table       = lme2510_id_table,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+
+module_usb_driver(lme2510_driver);
+
+MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
+MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
+MODULE_VERSION("2.06");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(LME2510_C_S7395);
+MODULE_FIRMWARE(LME2510_C_LG);
+MODULE_FIRMWARE(LME2510_C_S0194);
+MODULE_FIRMWARE(LME2510_C_RS2000);
+MODULE_FIRMWARE(LME2510_LG);
+MODULE_FIRMWARE(LME2510_S0194);
+
diff --git a/drivers/media/dvb/dvb-usb-v2/lmedm04.h b/drivers/media/dvb/dvb-usb-v2/lmedm04.h
new file mode 100644 (file)
index 0000000..e9c2072
--- /dev/null
@@ -0,0 +1,175 @@
+/* DVB USB compliant linux driver for
+ *
+ * DM04/QQBOX DVB-S USB BOX    LME2510C + SHARP:BS2F7HZ7395
+ *                             LME2510C + LG TDQY-P001F
+ *                             LME2510 + LG TDQY-P001F
+ *
+ * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
+ * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
+ *
+ * MVB001F (LME2510+LGTDQT-P001F)
+ * LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ * MVB0001F (LME2510C+LGTDQT-P001F)
+ *
+ * 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_LME2510_H_
+#define _DVB_USB_LME2510_H_
+
+/* Streamer &  PID
+ *
+ * Note:       These commands do not actually stop the streaming
+ *             but form some kind of packet filtering/stream count
+ *             or tuning related functions.
+ *  06 XX
+ *  offset 1 = 00 Enable Streaming
+ *
+ *
+ *  PID
+ *  03 XX XX  ----> reg number ---> setting....20 XX
+ *  offset 1 = length
+ *  offset 2 = start of data
+ *  end byte -1 = 20
+ *  end byte = clear pid always a0, other wise 9c, 9a ??
+ *
+*/
+#define LME_ST_ON_W    {0x06, 0x00}
+#define LME_CLEAR_PID   {0x03, 0x02, 0x20, 0xa0}
+#define LME_ZERO_PID   {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
+#define LME_ALL_PIDS   {0x03, 0x06, 0x00, 0xff, 0x01, 0x1f, 0x20, 0x81}
+
+/*  LNB Voltage
+ *  07 XX XX
+ *  offset 1 = 01
+ *  offset 2 = 00=Voltage low 01=Voltage high
+ *
+ *  LNB Power
+ *  03 01 XX
+ *  offset 2 = 00=ON 01=OFF
+ */
+
+#define LME_VOLTAGE_L  {0x07, 0x01, 0x00}
+#define LME_VOLTAGE_H  {0x07, 0x01, 0x01}
+#define LNB_ON         {0x3a, 0x01, 0x00}
+#define LNB_OFF                {0x3a, 0x01, 0x01}
+
+/* Initial stv0288 settings for 7395 Frontend */
+static u8 s7395_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x20,
+       0x03, 0xa0,
+       0x04, 0xa0,
+       0x05, 0x12,
+       0x06, 0x00,
+       0x09, 0x00,
+       0x0a, 0x04,
+       0x0b, 0x00,
+       0x0c, 0x00,
+       0x0d, 0x00,
+       0x0e, 0xc1,
+       0x0f, 0x54,
+       0x11, 0x7a,
+       0x12, 0x03,
+       0x13, 0x48,
+       0x14, 0x84,
+       0x15, 0xc5,
+       0x16, 0xb8,
+       0x17, 0x9c,
+       0x18, 0x00,
+       0x19, 0xa6,
+       0x1a, 0x88,
+       0x1b, 0x8f,
+       0x1c, 0xf0,
+       0x20, 0x0b,
+       0x21, 0x54,
+       0x22, 0xff,
+       0x23, 0x01,
+       0x28, 0x46,
+       0x29, 0x66,
+       0x2a, 0x90,
+       0x2b, 0xfa,
+       0x2c, 0xd9,
+       0x30, 0x0,
+       0x31, 0x1e,
+       0x32, 0x14,
+       0x33, 0x0f,
+       0x34, 0x09,
+       0x35, 0x0c,
+       0x36, 0x05,
+       0x37, 0x2f,
+       0x38, 0x16,
+       0x39, 0xbd,
+       0x3a, 0x0,
+       0x3b, 0x13,
+       0x3c, 0x11,
+       0x3d, 0x30,
+       0x40, 0x63,
+       0x41, 0x04,
+       0x42, 0x20,
+       0x43, 0x00,
+       0x44, 0x00,
+       0x45, 0x00,
+       0x46, 0x00,
+       0x47, 0x00,
+       0x4a, 0x00,
+       0x50, 0x10,
+       0x51, 0x36,
+       0x52, 0x21,
+       0x53, 0x94,
+       0x54, 0xb2,
+       0x55, 0x29,
+       0x56, 0x64,
+       0x57, 0x2b,
+       0x58, 0x54,
+       0x59, 0x86,
+       0x5a, 0x00,
+       0x5b, 0x9b,
+       0x5c, 0x08,
+       0x5d, 0x7f,
+       0x5e, 0xff,
+       0x5f, 0x8d,
+       0x70, 0x0,
+       0x71, 0x0,
+       0x72, 0x0,
+       0x74, 0x0,
+       0x75, 0x0,
+       0x76, 0x0,
+       0x81, 0x0,
+       0x82, 0x3f,
+       0x83, 0x3f,
+       0x84, 0x0,
+       0x85, 0x0,
+       0x88, 0x0,
+       0x89, 0x0,
+       0x8a, 0x0,
+       0x8b, 0x0,
+       0x8c, 0x0,
+       0x90, 0x0,
+       0x91, 0x0,
+       0x92, 0x0,
+       0x93, 0x0,
+       0x94, 0x1c,
+       0x97, 0x0,
+       0xa0, 0x48,
+       0xa1, 0x0,
+       0xb0, 0xb8,
+       0xb1, 0x3a,
+       0xb2, 0x10,
+       0xb3, 0x82,
+       0xb4, 0x80,
+       0xb5, 0x82,
+       0xb6, 0x82,
+       0xb7, 0x82,
+       0xb8, 0x20,
+       0xb9, 0x0,
+       0xf0, 0x0,
+       0xf1, 0x0,
+       0xf2, 0xc0,
+       0xff, 0xff,
+};
+#endif
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
deleted file mode 100644 (file)
index c6bc1b8..0000000
+++ /dev/null
@@ -1,1373 +0,0 @@
-/* DVB USB compliant linux driver for
- *
- * DM04/QQBOX DVB-S USB BOX    LME2510C + SHARP:BS2F7HZ7395
- *                             LME2510C + LG TDQY-P001F
- *                             LME2510C + BS2F7HZ0194
- *                             LME2510 + LG TDQY-P001F
- *                             LME2510 + BS2F7HZ0194
- *
- * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
- * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
- *
- * MV001F (LME2510+LGTDQY-P001F)
- * LG TDQY - P001F =(TDA8263 + TDA10086H)
- *
- * MVB0001F (LME2510C+LGTDQT-P001F)
- *
- * MV0194 (LME2510+SHARP:BS2F7HZ0194)
- * SHARP:BS2F7HZ0194 = (STV0299+IX2410)
- *
- * MVB0194 (LME2510C+SHARP0194)
- *
- * LME2510C + M88RS2000
- *
- * For firmware see Documentation/dvb/lmedm04.txt
- *
- * I2C addresses:
- * 0xd0 - STV0288      - Demodulator
- * 0xc0 - Sharp IX2505V        - Tuner
- * --
- * 0x1c - TDA10086   - Demodulator
- * 0xc0 - TDA8263    - Tuner
- * --
- * 0xd0 - STV0299      - Demodulator
- * 0xc0 - IX2410       - Tuner
- *
- *
- * VID = 3344  PID LME2510=1122 LME2510C=1120
- *
- * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
- * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2, as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- *
- * see Documentation/dvb/README.dvb-usb for more information
- *
- * Known Issues :
- *     LME2510: Non Intel USB chipsets fail to maintain High Speed on
- * Boot or Hot Plug.
- *
- * QQbox suffers from noise on LNB voltage.
- *
- *     LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
- * with other tuners. After a cold reset streaming will not start.
- *
- * M88RS2000 suffers from loss of lock.
- */
-#define DVB_USB_LOG_PREFIX "LME2510(C)"
-#include <linux/usb.h>
-#include <linux/usb/input.h>
-#include <media/rc-core.h>
-
-#include "dvb_usb.h"
-#include "lmedm04.h"
-#include "tda826x.h"
-#include "tda10086.h"
-#include "stv0288.h"
-#include "ix2505v.h"
-#include "stv0299.h"
-#include "dvb-pll.h"
-#include "z0194a.h"
-#include "m88rs2000.h"
-
-
-#define LME2510_C_S7395        "dvb-usb-lme2510c-s7395.fw";
-#define LME2510_C_LG   "dvb-usb-lme2510c-lg.fw";
-#define LME2510_C_S0194        "dvb-usb-lme2510c-s0194.fw";
-#define LME2510_C_RS2000 "dvb-usb-lme2510c-rs2000.fw";
-#define LME2510_LG     "dvb-usb-lme2510-lg.fw";
-#define LME2510_S0194  "dvb-usb-lme2510-s0194.fw";
-
-/* debug */
-static int dvb_usb_lme2510_debug;
-#define lme_debug(var, level, args...) do { \
-       if ((var >= level)) \
-               pr_debug(DVB_USB_LOG_PREFIX": " args); \
-} while (0)
-#define deb_info(level, args...) lme_debug(dvb_usb_lme2510_debug, level, args)
-#define debug_data_snipet(level, name, p) \
-        deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
-               *p, *(p+1), *(p+2), *(p+3), *(p+4), \
-                       *(p+5), *(p+6), *(p+7));
-#define info(args...) pr_info(DVB_USB_LOG_PREFIX": "args)
-
-module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-static int dvb_usb_lme2510_firmware;
-module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
-MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
-
-static int pid_filter;
-module_param_named(pid, pid_filter, int, 0644);
-MODULE_PARM_DESC(pid, "set default 0=default 1=off 2=on");
-
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define TUNER_DEFAULT  0x0
-#define TUNER_LG       0x1
-#define TUNER_S7395    0x2
-#define TUNER_S0194    0x3
-#define TUNER_RS2000   0x4
-
-struct lme2510_state {
-       u8 id;
-       u8 tuner_config;
-       u8 signal_lock;
-       u8 signal_level;
-       u8 signal_sn;
-       u8 time_key;
-       u8 last_key;
-       u8 key_timeout;
-       u8 i2c_talk_onoff;
-       u8 i2c_gate;
-       u8 i2c_tuner_gate_w;
-       u8 i2c_tuner_gate_r;
-       u8 i2c_tuner_addr;
-       u8 stream_on;
-       u8 pid_size;
-       u8 pid_off;
-       void *buffer;
-       struct urb *lme_urb;
-       void *usb_buffer;
-       int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t);
-       u8 dvb_usb_lme2510_firmware;
-};
-
-static int lme2510_bulk_write(struct usb_device *dev,
-                               u8 *snd, int len, u8 pipe)
-{
-       int ret, actual_l;
-
-       ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
-                               snd, len , &actual_l, 100);
-       return ret;
-}
-
-static int lme2510_bulk_read(struct usb_device *dev,
-                               u8 *rev, int len, u8 pipe)
-{
-       int ret, actual_l;
-
-       ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
-                                rev, len , &actual_l, 200);
-       return ret;
-}
-
-static int lme2510_usb_talk(struct dvb_usb_device *d,
-               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
-{
-       struct lme2510_state *st = d->priv;
-       u8 *buff;
-       int ret = 0;
-
-       if (st->usb_buffer == NULL) {
-               st->usb_buffer = kmalloc(64, GFP_KERNEL);
-               if (st->usb_buffer == NULL) {
-                       info("MEM Error no memory");
-                       return -ENOMEM;
-               }
-       }
-       buff = st->usb_buffer;
-
-       ret = mutex_lock_interruptible(&d->usb_mutex);
-
-       if (ret < 0)
-               return -EAGAIN;
-
-       /* the read/write capped at 64 */
-       memcpy(buff, wbuf, (wlen < 64) ? wlen : 64);
-
-       ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
-
-       ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ?
-                       rlen : 64 , 0x01);
-
-       if (rlen > 0)
-               memcpy(rbuf, buff, rlen);
-
-       mutex_unlock(&d->usb_mutex);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int lme2510_stream_restart(struct dvb_usb_device *d)
-{
-       struct lme2510_state *st = d->priv;
-       u8 all_pids[] = LME_ALL_PIDS;
-       u8 stream_on[] = LME_ST_ON_W;
-       int ret;
-       u8 rbuff[1];
-       if (st->pid_off)
-               ret = lme2510_usb_talk(d, all_pids, sizeof(all_pids),
-                       rbuff, sizeof(rbuff));
-       /*Restart Stream Command*/
-       ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
-                       rbuff, sizeof(rbuff));
-       return ret;
-}
-
-static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
-{
-       struct lme2510_state *st = d->priv;
-       static u8 pid_buff[] = LME_ZERO_PID;
-       static u8 rbuf[1];
-       u8 pid_no = index * 2;
-       u8 pid_len = pid_no + 2;
-       int ret = 0;
-       deb_info(1, "PID Setting Pid %04x", pid_out);
-
-       if (st->pid_size == 0)
-               ret |= lme2510_stream_restart(d);
-
-       pid_buff[2] = pid_no;
-       pid_buff[3] = (u8)pid_out & 0xff;
-       pid_buff[4] = pid_no + 1;
-       pid_buff[5] = (u8)(pid_out >> 8);
-
-       if (pid_len > st->pid_size)
-               st->pid_size = pid_len;
-       pid_buff[7] = 0x80 + st->pid_size;
-
-       ret |= lme2510_usb_talk(d, pid_buff ,
-               sizeof(pid_buff) , rbuf, sizeof(rbuf));
-
-       if (st->stream_on)
-               ret |= lme2510_stream_restart(d);
-
-       return ret;
-}
-
-static void lme2510_int_response(struct urb *lme_urb)
-{
-       struct dvb_usb_adapter *adap = lme_urb->context;
-       struct lme2510_state *st = adap_to_priv(adap);
-       static u8 *ibuf, *rbuf;
-       int i = 0, offset;
-       u32 key;
-
-       switch (lme_urb->status) {
-       case 0:
-       case -ETIMEDOUT:
-               break;
-       case -ECONNRESET:
-       case -ENOENT:
-       case -ESHUTDOWN:
-               return;
-       default:
-               info("Error %x", lme_urb->status);
-               break;
-       }
-
-       rbuf = (u8 *) lme_urb->transfer_buffer;
-
-       offset = ((lme_urb->actual_length/8) > 4)
-                       ? 4 : (lme_urb->actual_length/8) ;
-
-       for (i = 0; i < offset; ++i) {
-               ibuf = (u8 *)&rbuf[i*8];
-               deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x",
-               offset, i, ibuf[0], ibuf[1]);
-
-               switch (ibuf[0]) {
-               case 0xaa:
-                       debug_data_snipet(1, "INT Remote data snipet", ibuf);
-                       if ((ibuf[4] + ibuf[5]) == 0xff) {
-                               key = ibuf[5];
-                               key += (ibuf[3] > 0)
-                                       ? (ibuf[3] ^ 0xff) << 8 : 0;
-                               key += (ibuf[2] ^ 0xff) << 16;
-                               deb_info(1, "INT Key =%08x", key);
-                               if (adap_to_d(adap)->rc_dev != NULL)
-                                       rc_keydown(adap_to_d(adap)->rc_dev,
-                                               key, 0);
-                       }
-                       break;
-               case 0xbb:
-                       switch (st->tuner_config) {
-                       case TUNER_LG:
-                               if (ibuf[2] > 0)
-                                       st->signal_lock = ibuf[2];
-                               st->signal_level = ibuf[4];
-                               st->signal_sn = ibuf[3];
-                               st->time_key = ibuf[7];
-                               break;
-                       case TUNER_S7395:
-                       case TUNER_S0194:
-                               /* Tweak for earlier firmware*/
-                               if (ibuf[1] == 0x03) {
-                                       if (ibuf[2] > 1)
-                                               st->signal_lock = ibuf[2];
-                                       st->signal_level = ibuf[3];
-                                       st->signal_sn = ibuf[4];
-                               } else {
-                                       st->signal_level = ibuf[4];
-                                       st->signal_sn = ibuf[5];
-                                       st->signal_lock =
-                                               (st->signal_lock & 0xf7) +
-                                               ((ibuf[2] & 0x01) << 0x03);
-                               }
-                               break;
-                       case TUNER_RS2000:
-                               if (ibuf[1] == 0x3 &&  ibuf[6] == 0xff)
-                                       st->signal_lock = 0xff;
-                               else
-                                       st->signal_lock = 0x00;
-                               st->signal_level = ibuf[5];
-                               st->signal_sn = ibuf[4];
-                               st->time_key = ibuf[7];
-                       default:
-                               break;
-                       }
-                       debug_data_snipet(5, "INT Remote data snipet in", ibuf);
-               break;
-               case 0xcc:
-                       debug_data_snipet(1, "INT Control data snipet", ibuf);
-                       break;
-               default:
-                       debug_data_snipet(1, "INT Unknown data snipet", ibuf);
-               break;
-               }
-       }
-       usb_submit_urb(lme_urb, GFP_ATOMIC);
-}
-
-static int lme2510_int_read(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *lme_int = adap_to_priv(adap);
-
-       lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
-
-       if (lme_int->lme_urb == NULL)
-                       return -ENOMEM;
-
-       lme_int->buffer = usb_alloc_coherent(d->udev, 128, GFP_ATOMIC,
-                                       &lme_int->lme_urb->transfer_dma);
-
-       if (lme_int->buffer == NULL)
-                       return -ENOMEM;
-
-       usb_fill_int_urb(lme_int->lme_urb,
-                               d->udev,
-                               usb_rcvintpipe(d->udev, 0xa),
-                               lme_int->buffer,
-                               128,
-                               lme2510_int_response,
-                               adap,
-                               8);
-
-       lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-       usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
-       info("INT Interrupt Service Started");
-
-       return 0;
-}
-
-static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = adap_to_priv(adap);
-       static u8 clear_pid_reg[] = LME_ALL_PIDS;
-       static u8 rbuf[1];
-       int ret = 0;
-
-       deb_info(1, "PID Clearing Filter");
-
-       mutex_lock(&d->i2c_mutex);
-
-       if (!onoff) {
-               ret |= lme2510_usb_talk(d, clear_pid_reg,
-                       sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
-               st->pid_off = true;
-       } else
-               st->pid_off = false;
-
-       st->pid_size = 0;
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return 0;
-}
-
-static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
-       int onoff)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret = 0;
-
-       deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
-               pid, index, onoff);
-
-       if (onoff) {
-               mutex_lock(&d->i2c_mutex);
-               ret |= lme2510_enable_pid(d, index, pid);
-               mutex_unlock(&d->i2c_mutex);
-       }
-
-
-       return ret;
-}
-
-
-static int lme2510_return_status(struct dvb_usb_device *d)
-{
-       int ret = 0;
-       u8 *data;
-
-       data = kzalloc(10, GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
-                       0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
-       info("Firmware Status: %x (%x)", ret , data[2]);
-
-       ret = (ret < 0) ? -ENODEV : data[2];
-       kfree(data);
-       return ret;
-}
-
-static int lme2510_msg(struct dvb_usb_device *d,
-               u8 *wbuf, int wlen, u8 *rbuf, int rlen)
-{
-       int ret = 0;
-       struct lme2510_state *st = d->priv;
-
-       if (st->i2c_talk_onoff == 1) {
-
-               ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-
-               switch (st->tuner_config) {
-               case TUNER_LG:
-                       if (wbuf[2] == 0x1c) {
-                               if (wbuf[3] == 0x0e) {
-                                       st->signal_lock = rbuf[1];
-                                       if ((st->stream_on & 1) &&
-                                               (st->signal_lock & 0x10)) {
-                                               lme2510_stream_restart(d);
-                                               st->i2c_talk_onoff = 0;
-                                       }
-                                       msleep(80);
-                               }
-                       }
-                       break;
-               case TUNER_S7395:
-                       if (wbuf[2] == 0xd0) {
-                               if (wbuf[3] == 0x24) {
-                                       st->signal_lock = rbuf[1];
-                                       if ((st->stream_on & 1) &&
-                                               (st->signal_lock & 0x8)) {
-                                               lme2510_stream_restart(d);
-                                               st->i2c_talk_onoff = 0;
-                                       }
-                               }
-                       }
-                       break;
-               case TUNER_S0194:
-                       if (wbuf[2] == 0xd0) {
-                               if (wbuf[3] == 0x1b) {
-                                       st->signal_lock = rbuf[1];
-                                       if ((st->stream_on & 1) &&
-                                               (st->signal_lock & 0x8)) {
-                                               lme2510_stream_restart(d);
-                                               st->i2c_talk_onoff = 0;
-                                       }
-                               }
-                       }
-                       break;
-               case TUNER_RS2000:
-               default:
-                       break;
-               }
-       } else {
-               /* TODO rewrite this section */
-               switch (st->tuner_config) {
-               case TUNER_LG:
-                       switch (wbuf[3]) {
-                       case 0x0e:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_lock;
-                               break;
-                       case 0x43:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_level;
-                               break;
-                       case 0x1c:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_sn;
-                               break;
-                       case 0x15:
-                       case 0x16:
-                       case 0x17:
-                       case 0x18:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = 0x00;
-                               break;
-                       default:
-                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-                               st->i2c_talk_onoff = 1;
-                               break;
-                       }
-                       break;
-               case TUNER_S7395:
-                       switch (wbuf[3]) {
-                       case 0x10:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = (st->signal_level & 0x80)
-                                               ? 0 : (st->signal_level * 2);
-                               break;
-                       case 0x2d:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_sn;
-                               break;
-                       case 0x24:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_lock;
-                               break;
-                       case 0x2e:
-                       case 0x26:
-                       case 0x27:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = 0x00;
-                               break;
-                       default:
-                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-                               st->i2c_talk_onoff = 1;
-                               break;
-                       }
-                       break;
-               case TUNER_S0194:
-                       switch (wbuf[3]) {
-                       case 0x18:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = (st->signal_level & 0x80)
-                                               ? 0 : (st->signal_level * 2);
-                               break;
-                       case 0x24:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_sn;
-                               break;
-                       case 0x1b:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = st->signal_lock;
-                               break;
-                       case 0x19:
-                       case 0x25:
-                       case 0x1e:
-                       case 0x1d:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = 0x00;
-                               break;
-                       default:
-                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-                               st->i2c_talk_onoff = 1;
-                               break;
-                       }
-                       break;
-               case TUNER_RS2000:
-                       switch (wbuf[3]) {
-                       case 0x8c:
-                               rbuf[0] = 0x55;
-                               rbuf[1] = 0xff;
-                               if (st->last_key == st->time_key) {
-                                       st->key_timeout++;
-                                       if (st->key_timeout > 5)
-                                               rbuf[1] = 0;
-                               } else
-                                       st->key_timeout = 0;
-                               st->last_key = st->time_key;
-                               break;
-                       default:
-                               lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
-                               st->i2c_talk_onoff = 1;
-                               break;
-                       }
-               default:
-                       break;
-               }
-
-               deb_info(4, "I2C From Interrupt Message out(%02x) in(%02x)",
-                               wbuf[3], rbuf[1]);
-
-       }
-
-       return ret;
-}
-
-
-static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                                int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       struct lme2510_state *st = d->priv;
-       static u8 obuf[64], ibuf[64];
-       int i, read, read_o;
-       u16 len;
-       u8 gate = st->i2c_gate;
-
-       mutex_lock(&d->i2c_mutex);
-
-       if (gate == 0)
-               gate = 5;
-
-       for (i = 0; i < num; i++) {
-               read_o = 1 & (msg[i].flags & I2C_M_RD);
-               read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
-               read |= read_o;
-               gate = (msg[i].addr == st->i2c_tuner_addr)
-                       ? (read)        ? st->i2c_tuner_gate_r
-                                       : st->i2c_tuner_gate_w
-                       : st->i2c_gate;
-               obuf[0] = gate | (read << 7);
-
-               if (gate == 5)
-                       obuf[1] = (read) ? 2 : msg[i].len + 1;
-               else
-                       obuf[1] = msg[i].len + read + 1;
-
-               obuf[2] = msg[i].addr;
-               if (read) {
-                       if (read_o)
-                               len = 3;
-                       else {
-                               memcpy(&obuf[3], msg[i].buf, msg[i].len);
-                               obuf[msg[i].len+3] = msg[i+1].len;
-                               len = msg[i].len+4;
-                       }
-               } else {
-                       memcpy(&obuf[3], msg[i].buf, msg[i].len);
-                       len = msg[i].len+3;
-               }
-
-               if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) {
-                       deb_info(1, "i2c transfer failed.");
-                       mutex_unlock(&d->i2c_mutex);
-                       return -EAGAIN;
-               }
-
-               if (read) {
-                       if (read_o)
-                               memcpy(msg[i].buf, &ibuf[1], msg[i].len);
-                       else {
-                               memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
-                               i++;
-                       }
-               }
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-       return i;
-}
-
-static u32 lme2510_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm lme2510_i2c_algo = {
-       .master_xfer   = lme2510_i2c_xfer,
-       .functionality = lme2510_i2c_func,
-};
-
-static int lme2510_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = adap_to_priv(adap);
-       static u8 clear_reg_3[] = LME_ALL_PIDS;
-       static u8 rbuf[1];
-       int ret = 0, rlen = sizeof(rbuf);
-
-       deb_info(1, "STM  (%02x)", onoff);
-
-       /* Streaming is started by FE_HAS_LOCK */
-       if (onoff == 1)
-               st->stream_on = 1;
-       else {
-               deb_info(1, "STM Steam Off");
-               /* mutex is here only to avoid collision with I2C */
-               mutex_lock(&d->i2c_mutex);
-
-               ret = lme2510_usb_talk(d, clear_reg_3,
-                               sizeof(clear_reg_3), rbuf, rlen);
-               st->stream_on = 0;
-               st->i2c_talk_onoff = 1;
-
-               mutex_unlock(&d->i2c_mutex);
-       }
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static u8 check_sum(u8 *p, u8 len)
-{
-       u8 sum = 0;
-       while (len--)
-               sum += *p++;
-       return sum;
-}
-
-static int lme2510_download_firmware(struct dvb_usb_device *d,
-                                       const struct firmware *fw)
-{
-       int ret = 0;
-       u8 *data;
-       u16 j, wlen, len_in, start, end;
-       u8 packet_size, dlen, i;
-       u8 *fw_data;
-
-       packet_size = 0x31;
-       len_in = 1;
-
-       data = kzalloc(128, GFP_KERNEL);
-       if (!data) {
-               info("FRM Could not start Firmware Download"\
-                       "(Buffer allocation failed)");
-               return -ENOMEM;
-       }
-
-       info("FRM Starting Firmware Download");
-
-       for (i = 1; i < 3; i++) {
-               start = (i == 1) ? 0 : 512;
-               end = (i == 1) ? 512 : fw->size;
-               for (j = start; j < end; j += (packet_size+1)) {
-                       fw_data = (u8 *)(fw->data + j);
-                       if ((end - j) > packet_size) {
-                               data[0] = i;
-                               dlen = packet_size;
-                       } else {
-                               data[0] = i | 0x80;
-                               dlen = (u8)(end - j)-1;
-                       }
-                       data[1] = dlen;
-                       memcpy(&data[2], fw_data, dlen+1);
-                       wlen = (u8) dlen + 4;
-                       data[wlen-1] = check_sum(fw_data, dlen+1);
-                       deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
-                               data[dlen+2], data[dlen+3]);
-                       lme2510_usb_talk(d, data, wlen, data, len_in);
-                       ret |= (data[0] == 0x88) ? 0 : -1;
-               }
-       }
-
-       usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
-                       0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
-
-
-       data[0] = 0x8a;
-       len_in = 1;
-       msleep(2000);
-       lme2510_usb_talk(d, data, len_in, data, len_in);
-       msleep(400);
-
-       if (ret < 0)
-               info("FRM Firmware Download Failed (%04x)" , ret);
-       else
-               info("FRM Firmware Download Completed - Resetting Device");
-
-       kfree(data);
-       return RECONNECTS_USB;
-}
-
-static void lme_coldreset(struct dvb_usb_device *d)
-{
-       u8 data[1] = {0};
-       data[0] = 0x0a;
-       info("FRM Firmware Cold Reset");
-
-       lme2510_usb_talk(d, data, sizeof(data), data, sizeof(data));
-
-       return;
-}
-
-static const char fw_c_s7395[] = LME2510_C_S7395;
-static const char fw_c_lg[] = LME2510_C_LG;
-static const char fw_c_s0194[] = LME2510_C_S0194;
-static const char fw_c_rs2000[] = LME2510_C_RS2000;
-static const char fw_lg[] = LME2510_LG;
-static const char fw_s0194[] = LME2510_S0194;
-
-const char *lme_firmware_switch(struct dvb_usb_device *d, int cold)
-{
-       struct lme2510_state *st = d->priv;
-       struct usb_device *udev = d->udev;
-       const struct firmware *fw = NULL;
-       const char *fw_lme;
-       int ret = 0;
-
-       cold = (cold > 0) ? (cold & 1) : 0;
-
-       switch (le16_to_cpu(udev->descriptor.idProduct)) {
-       case 0x1122:
-               switch (st->dvb_usb_lme2510_firmware) {
-               default:
-                       st->dvb_usb_lme2510_firmware = TUNER_S0194;
-               case TUNER_S0194:
-                       fw_lme = fw_s0194;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0) {
-                               cold = 0;
-                               break;
-                       }
-                       st->dvb_usb_lme2510_firmware = TUNER_LG;
-               case TUNER_LG:
-                       fw_lme = fw_lg;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0)
-                               break;
-                       st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
-                       break;
-               }
-               break;
-       case 0x1120:
-               switch (st->dvb_usb_lme2510_firmware) {
-               default:
-                       st->dvb_usb_lme2510_firmware = TUNER_S7395;
-               case TUNER_S7395:
-                       fw_lme = fw_c_s7395;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0) {
-                               cold = 0;
-                               break;
-                       }
-                       st->dvb_usb_lme2510_firmware = TUNER_LG;
-               case TUNER_LG:
-                       fw_lme = fw_c_lg;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0)
-                               break;
-                       st->dvb_usb_lme2510_firmware = TUNER_S0194;
-               case TUNER_S0194:
-                       fw_lme = fw_c_s0194;
-                       ret = request_firmware(&fw, fw_lme, &udev->dev);
-                       if (ret == 0)
-                               break;
-                       st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
-                       cold = 0;
-                       break;
-               }
-               break;
-       case 0x22f0:
-               fw_lme = fw_c_rs2000;
-               st->dvb_usb_lme2510_firmware = TUNER_RS2000;
-               break;
-       default:
-               fw_lme = fw_c_s7395;
-       }
-
-       release_firmware(fw);
-
-       if (cold) {
-               dvb_usb_lme2510_firmware = st->dvb_usb_lme2510_firmware;
-               info("FRM Changing to %s firmware", fw_lme);
-               lme_coldreset(d);
-               return NULL;
-       }
-
-       return fw_lme;
-}
-
-static int lme2510_kill_urb(struct usb_data_stream *stream)
-{
-       int i;
-
-       for (i = 0; i < stream->urbs_submitted; i++) {
-               deb_info(3, "killing URB no. %d.", i);
-               /* stop the URB */
-               usb_kill_urb(stream->urb_list[i]);
-       }
-       stream->urbs_submitted = 0;
-
-       return 0;
-}
-
-static struct tda10086_config tda10086_config = {
-       .demod_address = 0x1c,
-       .invert = 0,
-       .diseqc_tone = 1,
-       .xtal_freq = TDA10086_XTAL_16M,
-};
-
-static struct stv0288_config lme_config = {
-       .demod_address = 0xd0,
-       .min_delay_ms = 15,
-       .inittab = s7395_inittab,
-};
-
-static struct ix2505v_config lme_tuner = {
-       .tuner_address = 0xc0,
-       .min_delay_ms = 100,
-       .tuner_gain = 0x0,
-       .tuner_chargepump = 0x3,
-};
-
-static struct stv0299_config sharp_z0194_config = {
-       .demod_address = 0xd0,
-       .inittab = sharp_z0194a_inittab,
-       .mclk = 88000000UL,
-       .invert = 0,
-       .skip_reinit = 0,
-       .lock_output = STV0299_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = sharp_z0194a_set_symbol_rate,
-};
-
-static int dm04_rs2000_set_ts_param(struct dvb_frontend *fe,
-       int caller)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = d->priv;
-
-       mutex_lock(&d->i2c_mutex);
-       if ((st->i2c_talk_onoff == 1) && (st->stream_on & 1)) {
-               st->i2c_talk_onoff = 0;
-               lme2510_stream_restart(d);
-       }
-       mutex_unlock(&d->i2c_mutex);
-
-       return 0;
-}
-
-static struct m88rs2000_config m88rs2000_config = {
-       .demod_addr = 0xd0,
-       .tuner_addr = 0xc0,
-       .set_ts_params = dm04_rs2000_set_ts_param,
-};
-
-static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
-                                       fe_sec_voltage_t voltage)
-{
-       struct dvb_usb_device *d = fe_to_d(fe);
-       struct lme2510_state *st = fe_to_priv(fe);
-       static u8 voltage_low[] = LME_VOLTAGE_L;
-       static u8 voltage_high[] = LME_VOLTAGE_H;
-       static u8 rbuf[1];
-       int ret = 0, len = 3, rlen = 1;
-
-       mutex_lock(&d->i2c_mutex);
-
-       switch (voltage) {
-       case SEC_VOLTAGE_18:
-               ret |= lme2510_usb_talk(d,
-                       voltage_high, len, rbuf, rlen);
-               break;
-
-       case SEC_VOLTAGE_OFF:
-       case SEC_VOLTAGE_13:
-       default:
-               ret |= lme2510_usb_talk(d,
-                               voltage_low, len, rbuf, rlen);
-               break;
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       if (st->tuner_config == TUNER_RS2000)
-               if (st->fe_set_voltage)
-                       st->fe_set_voltage(fe, voltage);
-
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int dm04_rs2000_read_signal_strength(struct dvb_frontend *fe,
-       u16 *strength)
-{
-       struct lme2510_state *st = fe_to_priv(fe);
-
-       *strength = (u16)((u32)st->signal_level * 0xffff / 0xff);
-
-       return 0;
-}
-
-static int dm04_rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct lme2510_state *st = fe_to_priv(fe);
-
-       *snr = (u16)((u32)st->signal_sn * 0xffff / 0x7f);
-
-       return 0;
-}
-
-static int dm04_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       *ber = 0;
-
-       return 0;
-}
-
-static int dm04_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-
-       return 0;
-}
-
-static int lme_name(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = adap_to_priv(adap);
-       const char *desc = d->name;
-       char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
-                               " SHARP:BS2F7HZ0194", " RS2000"};
-       char *name = adap->fe[0]->ops.info.name;
-
-       strlcpy(name, desc, 128);
-       strlcat(name, fe_name[st->tuner_config], 128);
-
-       return 0;
-}
-
-static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = d->priv;
-       int ret = 0;
-
-       st->i2c_talk_onoff = 1;
-       switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
-       case 0x1122:
-       case 0x1120:
-               st->i2c_gate = 4;
-               adap->fe[0] = dvb_attach(tda10086_attach,
-                       &tda10086_config, &d->i2c_adap);
-               if (adap->fe[0]) {
-                       info("TUN Found Frontend TDA10086");
-                       st->i2c_tuner_gate_w = 4;
-                       st->i2c_tuner_gate_r = 4;
-                       st->i2c_tuner_addr = 0xc0;
-                       st->tuner_config = TUNER_LG;
-                       if (st->dvb_usb_lme2510_firmware != TUNER_LG) {
-                               st->dvb_usb_lme2510_firmware = TUNER_LG;
-                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
-                       }
-                       break;
-               }
-
-               st->i2c_gate = 4;
-               adap->fe[0] = dvb_attach(stv0299_attach,
-                               &sharp_z0194_config, &d->i2c_adap);
-               if (adap->fe[0]) {
-                       info("FE Found Stv0299");
-                       st->i2c_tuner_gate_w = 4;
-                       st->i2c_tuner_gate_r = 5;
-                       st->i2c_tuner_addr = 0xc0;
-                       st->tuner_config = TUNER_S0194;
-                       if (st->dvb_usb_lme2510_firmware != TUNER_S0194) {
-                               st->dvb_usb_lme2510_firmware = TUNER_S0194;
-                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
-                       }
-                       break;
-               }
-
-               st->i2c_gate = 5;
-               adap->fe[0] = dvb_attach(stv0288_attach, &lme_config,
-                       &d->i2c_adap);
-
-               if (adap->fe[0]) {
-                       info("FE Found Stv0288");
-                       st->i2c_tuner_gate_w = 4;
-                       st->i2c_tuner_gate_r = 5;
-                       st->i2c_tuner_addr = 0xc0;
-                       st->tuner_config = TUNER_S7395;
-                       if (st->dvb_usb_lme2510_firmware != TUNER_S7395) {
-                               st->dvb_usb_lme2510_firmware = TUNER_S7395;
-                               ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
-                       }
-                       break;
-               }
-       case 0x22f0:
-               st->i2c_gate = 5;
-               adap->fe[0] = dvb_attach(m88rs2000_attach,
-                       &m88rs2000_config, &d->i2c_adap);
-
-               if (adap->fe[0]) {
-                       info("FE Found M88RS2000");
-                       st->i2c_tuner_gate_w = 5;
-                       st->i2c_tuner_gate_r = 5;
-                       st->i2c_tuner_addr = 0xc0;
-                       st->tuner_config = TUNER_RS2000;
-                       st->fe_set_voltage =
-                               adap->fe[0]->ops.set_voltage;
-
-                       adap->fe[0]->ops.read_signal_strength =
-                               dm04_rs2000_read_signal_strength;
-                       adap->fe[0]->ops.read_snr =
-                               dm04_rs2000_read_snr;
-                       adap->fe[0]->ops.read_ber =
-                               dm04_read_ber;
-                       adap->fe[0]->ops.read_ucblocks =
-                               dm04_read_ucblocks;
-               }
-               break;
-       }
-
-       if (adap->fe[0] == NULL) {
-               info("DM04/QQBOX Not Powered up or not Supported");
-               return -ENODEV;
-       }
-
-       if (ret) {
-               if (adap->fe[0]) {
-                       dvb_frontend_detach(adap->fe[0]);
-                       adap->fe[0] = NULL;
-               }
-               d->rc_map = NULL;
-               return -ENODEV;
-       }
-
-       adap->fe[0]->ops.set_voltage = dm04_lme2510_set_voltage;
-       ret = lme_name(adap);
-       return ret;
-}
-
-static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct lme2510_state *st = adap_to_priv(adap);
-       char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
-       int ret = 0;
-
-       switch (st->tuner_config) {
-       case TUNER_LG:
-               if (dvb_attach(tda826x_attach, adap->fe[0], 0xc0,
-                       &d->i2c_adap, 1))
-                       ret = st->tuner_config;
-               break;
-       case TUNER_S7395:
-               if (dvb_attach(ix2505v_attach , adap->fe[0], &lme_tuner,
-                       &d->i2c_adap))
-                       ret = st->tuner_config;
-               break;
-       case TUNER_S0194:
-               if (dvb_attach(dvb_pll_attach , adap->fe[0], 0xc0,
-                       &d->i2c_adap, DVB_PLL_OPERA1))
-                       ret = st->tuner_config;
-               break;
-       case TUNER_RS2000:
-               ret = st->tuner_config;
-               break;
-       default:
-               break;
-       }
-
-       if (ret)
-               info("TUN Found %s tuner", tun_msg[ret]);
-       else {
-               info("TUN No tuner found --- resetting device");
-               lme_coldreset(d);
-               return -ENODEV;
-       }
-
-       /* Start the Interrupt*/
-       ret = lme2510_int_read(adap);
-       if (ret < 0) {
-               info("INT Unable to start Interrupt Service");
-               return -ENODEV;
-       }
-
-       return ret;
-}
-
-static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
-{
-       struct lme2510_state *st = d->priv;
-       static u8 lnb_on[] = LNB_ON;
-       static u8 lnb_off[] = LNB_OFF;
-       static u8 rbuf[1];
-       int ret = 0, len = 3, rlen = 1;
-
-       mutex_lock(&d->i2c_mutex);
-
-       if (onoff)
-               ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
-       else
-               ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
-
-       st->i2c_talk_onoff = 1;
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static int lme2510_get_adapter_count(struct dvb_usb_device *d)
-{
-       return 1;
-}
-
-static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       struct lme2510_state *st = d->priv;
-
-       usb_reset_configuration(d->udev);
-
-       usb_set_interface(d->udev,
-               d->intf->cur_altsetting->desc.bInterfaceNumber, 1);
-
-       st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
-
-       if (lme2510_return_status(d) == 0x44) {
-               *name = lme_firmware_switch(d, 0);
-               return COLD;
-       }
-
-       return 0;
-}
-
-static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
-               struct usb_data_stream_properties *stream)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       struct dvb_usb_device *d = adap_to_d(adap);
-
-       if (adap == NULL)
-               return 0;
-       /* Turn PID filter on the fly by module option */
-       if (pid_filter == 2) {
-               adap->pid_filtering  = 1;
-               adap->max_feed_count = 15;
-       }
-
-       if (!(le16_to_cpu(d->udev->descriptor.idProduct)
-               == 0x1122))
-               stream->endpoint = 0x8;
-
-       return 0;
-}
-
-static int lme2510_get_rc_config(struct dvb_usb_device *d,
-       struct dvb_usb_rc *rc)
-{
-       rc->allowed_protos = RC_TYPE_NEC;
-       return 0;
-}
-
-static void *lme2510_exit_int(struct dvb_usb_device *d)
-{
-       struct lme2510_state *st = d->priv;
-       struct dvb_usb_adapter *adap = &d->adapter[0];
-       void *buffer = NULL;
-
-       if (adap != NULL) {
-               lme2510_kill_urb(&adap->stream);
-       }
-
-       if (st->usb_buffer != NULL) {
-               st->i2c_talk_onoff = 1;
-               st->signal_lock = 0;
-               st->signal_level = 0;
-               st->signal_sn = 0;
-               buffer = st->usb_buffer;
-       }
-
-       if (st->lme_urb != NULL) {
-               usb_kill_urb(st->lme_urb);
-               usb_free_coherent(d->udev, 128, st->buffer,
-                                 st->lme_urb->transfer_dma);
-               info("Interrupt Service Stopped");
-       }
-
-       return buffer;
-}
-
-static void lme2510_exit(struct dvb_usb_device *d)
-{
-       void *usb_buffer;
-
-       if (d != NULL) {
-               usb_buffer = lme2510_exit_int(d);
-               if (usb_buffer != NULL)
-                       kfree(usb_buffer);
-       }
-}
-
-static struct dvb_usb_device_properties lme2510_props = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .bInterfaceNumber = 0,
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct lme2510_state),
-
-       .download_firmware = lme2510_download_firmware,
-
-       .power_ctrl       = lme2510_powerup,
-       .identify_state   = lme2510_identify_state,
-       .i2c_algo         = &lme2510_i2c_algo,
-
-       .frontend_attach  = dm04_lme2510_frontend_attach,
-       .tuner_attach = dm04_lme2510_tuner,
-       .get_stream_config = lme2510_get_stream_config,
-       .get_adapter_count = lme2510_get_adapter_count,
-       .streaming_ctrl   = lme2510_streaming_ctrl,
-
-       .get_rc_config = lme2510_get_rc_config,
-
-       .exit = lme2510_exit,
-       .adapter = {
-               {
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 15,
-                       .pid_filter = lme2510_pid_filter,
-                       .pid_filter_ctrl  = lme2510_pid_filter_ctrl,
-                       .stream =
-                       DVB_USB_STREAM_BULK(0x86, 10, 4096),
-               },
-               {
-               }
-       },
-};
-
-static const struct usb_device_id lme2510_id_table[] = {
-       {       DVB_USB_DEVICE(0x3344, 0x1122, &lme2510_props,
-               "DM04_LME2510_DVB-S", RC_MAP_LME2510)   },
-       {       DVB_USB_DEVICE(0x3344, 0x1120, &lme2510_props,
-               "DM04_LME2510C_DVB-S", RC_MAP_LME2510)  },
-       {       DVB_USB_DEVICE(0x3344, 0x22f0, &lme2510_props,
-               "DM04_LME2510C_DVB-S RS2000", RC_MAP_LME2510)   },
-       {}              /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, lme2510_id_table);
-
-static struct usb_driver lme2510_driver = {
-       .name           = KBUILD_MODNAME,
-       .probe          = dvb_usbv2_probe,
-       .disconnect     = dvb_usbv2_disconnect,
-       .id_table       = lme2510_id_table,
-       .no_dynamic_id = 1,
-       .soft_unbind = 1,
-};
-
-module_usb_driver(lme2510_driver);
-
-MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
-MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
-MODULE_VERSION("2.06");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(LME2510_C_S7395);
-MODULE_FIRMWARE(LME2510_C_LG);
-MODULE_FIRMWARE(LME2510_C_S0194);
-MODULE_FIRMWARE(LME2510_C_RS2000);
-MODULE_FIRMWARE(LME2510_LG);
-MODULE_FIRMWARE(LME2510_S0194);
-
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.h b/drivers/media/dvb/dvb-usb/lmedm04.h
deleted file mode 100644 (file)
index e9c2072..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/* DVB USB compliant linux driver for
- *
- * DM04/QQBOX DVB-S USB BOX    LME2510C + SHARP:BS2F7HZ7395
- *                             LME2510C + LG TDQY-P001F
- *                             LME2510 + LG TDQY-P001F
- *
- * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
- * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
- *
- * MVB001F (LME2510+LGTDQT-P001F)
- * LG TDQY - P001F =(TDA8263 + TDA10086H)
- *
- * MVB0001F (LME2510C+LGTDQT-P001F)
- *
- * 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_LME2510_H_
-#define _DVB_USB_LME2510_H_
-
-/* Streamer &  PID
- *
- * Note:       These commands do not actually stop the streaming
- *             but form some kind of packet filtering/stream count
- *             or tuning related functions.
- *  06 XX
- *  offset 1 = 00 Enable Streaming
- *
- *
- *  PID
- *  03 XX XX  ----> reg number ---> setting....20 XX
- *  offset 1 = length
- *  offset 2 = start of data
- *  end byte -1 = 20
- *  end byte = clear pid always a0, other wise 9c, 9a ??
- *
-*/
-#define LME_ST_ON_W    {0x06, 0x00}
-#define LME_CLEAR_PID   {0x03, 0x02, 0x20, 0xa0}
-#define LME_ZERO_PID   {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
-#define LME_ALL_PIDS   {0x03, 0x06, 0x00, 0xff, 0x01, 0x1f, 0x20, 0x81}
-
-/*  LNB Voltage
- *  07 XX XX
- *  offset 1 = 01
- *  offset 2 = 00=Voltage low 01=Voltage high
- *
- *  LNB Power
- *  03 01 XX
- *  offset 2 = 00=ON 01=OFF
- */
-
-#define LME_VOLTAGE_L  {0x07, 0x01, 0x00}
-#define LME_VOLTAGE_H  {0x07, 0x01, 0x01}
-#define LNB_ON         {0x3a, 0x01, 0x00}
-#define LNB_OFF                {0x3a, 0x01, 0x01}
-
-/* Initial stv0288 settings for 7395 Frontend */
-static u8 s7395_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x20,
-       0x03, 0xa0,
-       0x04, 0xa0,
-       0x05, 0x12,
-       0x06, 0x00,
-       0x09, 0x00,
-       0x0a, 0x04,
-       0x0b, 0x00,
-       0x0c, 0x00,
-       0x0d, 0x00,
-       0x0e, 0xc1,
-       0x0f, 0x54,
-       0x11, 0x7a,
-       0x12, 0x03,
-       0x13, 0x48,
-       0x14, 0x84,
-       0x15, 0xc5,
-       0x16, 0xb8,
-       0x17, 0x9c,
-       0x18, 0x00,
-       0x19, 0xa6,
-       0x1a, 0x88,
-       0x1b, 0x8f,
-       0x1c, 0xf0,
-       0x20, 0x0b,
-       0x21, 0x54,
-       0x22, 0xff,
-       0x23, 0x01,
-       0x28, 0x46,
-       0x29, 0x66,
-       0x2a, 0x90,
-       0x2b, 0xfa,
-       0x2c, 0xd9,
-       0x30, 0x0,
-       0x31, 0x1e,
-       0x32, 0x14,
-       0x33, 0x0f,
-       0x34, 0x09,
-       0x35, 0x0c,
-       0x36, 0x05,
-       0x37, 0x2f,
-       0x38, 0x16,
-       0x39, 0xbd,
-       0x3a, 0x0,
-       0x3b, 0x13,
-       0x3c, 0x11,
-       0x3d, 0x30,
-       0x40, 0x63,
-       0x41, 0x04,
-       0x42, 0x20,
-       0x43, 0x00,
-       0x44, 0x00,
-       0x45, 0x00,
-       0x46, 0x00,
-       0x47, 0x00,
-       0x4a, 0x00,
-       0x50, 0x10,
-       0x51, 0x36,
-       0x52, 0x21,
-       0x53, 0x94,
-       0x54, 0xb2,
-       0x55, 0x29,
-       0x56, 0x64,
-       0x57, 0x2b,
-       0x58, 0x54,
-       0x59, 0x86,
-       0x5a, 0x00,
-       0x5b, 0x9b,
-       0x5c, 0x08,
-       0x5d, 0x7f,
-       0x5e, 0xff,
-       0x5f, 0x8d,
-       0x70, 0x0,
-       0x71, 0x0,
-       0x72, 0x0,
-       0x74, 0x0,
-       0x75, 0x0,
-       0x76, 0x0,
-       0x81, 0x0,
-       0x82, 0x3f,
-       0x83, 0x3f,
-       0x84, 0x0,
-       0x85, 0x0,
-       0x88, 0x0,
-       0x89, 0x0,
-       0x8a, 0x0,
-       0x8b, 0x0,
-       0x8c, 0x0,
-       0x90, 0x0,
-       0x91, 0x0,
-       0x92, 0x0,
-       0x93, 0x0,
-       0x94, 0x1c,
-       0x97, 0x0,
-       0xa0, 0x48,
-       0xa1, 0x0,
-       0xb0, 0xb8,
-       0xb1, 0x3a,
-       0xb2, 0x10,
-       0xb3, 0x82,
-       0xb4, 0x80,
-       0xb5, 0x82,
-       0xb6, 0x82,
-       0xb7, 0x82,
-       0xb8, 0x20,
-       0xb9, 0x0,
-       0xf0, 0x0,
-       0xf1, 0x0,
-       0xf2, 0xc0,
-       0xff, 0xff,
-};
-#endif