linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] added support for DM040832731 DVB-S USB BOX - Correction
@ 2010-07-16 13:43 Malcolm Priestley
  2010-07-29 18:16 ` Mauro Carvalho Chehab
  2010-07-29 18:18 ` Mauro Carvalho Chehab
  0 siblings, 2 replies; 4+ messages in thread
From: Malcolm Priestley @ 2010-07-16 13:43 UTC (permalink / raw)
  To: linux-media

DVB USB Driver for DM04 LME2510 + LG TDQY - P001F =(TDA8263 + TDA10086H)

Corrected patch error.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>



diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/Kconfig
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig	Thu May 27 02:02:09 2010 -0300
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig	Fri Jul 16 14:30:02 2010 +0100
@@ -346,3 +346,13 @@
 	select DVB_STB6100 if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the AZ6027 device
+
+config DVB_USB_LME2510
+	tristate "LME DM04 (LME 2510 + TDQY-P001F) DVB-S USB2.0 support"
+	depends on DVB_USB
+	select DVB_TDA10086 if !DVB_FE_CUSTOMISE
+	select DVB_TDA826X if !DVB_FE_CUSTOMISE
+	help
+	  Say Y here to support the LME DM04 DVB-S USB2.0 .
+
+
diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/Makefile
--- a/linux/drivers/media/dvb/dvb-usb/Makefile	Thu May 27 02:02:09 2010 -0300
+++ b/linux/drivers/media/dvb/dvb-usb/Makefile	Fri Jul 16 14:30:02 2010 +0100
@@ -88,6 +88,9 @@
 dvb-usb-az6027-objs = az6027.o
 obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o

+dvb-usb-lmedm04-objs = lmedm04.o
+obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 # due to tuner-xc3028
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/lmedm04.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux/drivers/media/dvb/dvb-usb/lmedm04.c	Fri Jul 16 14:30:02 2010 +0100
@@ -0,0 +1,910 @@
+/* DVB USB compliant linux driver for
+ *
+ * DM040832731 DVB-S USB BOX (LME 2510 + TDQY-P001F)
+ *
+ * MV001F LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ * I2C addresses:
+ * 0x0e - TDA10086   - Demodulator
+ * 0x60 - TDA8263    - Tuner
+ *
+ * ***Please Note***
+ *		There are other variants of the DM04
+ *		***NOT SUPPORTED***
+ *		MVB0001F (LME2510C+LGTDQT-P001F)
+ *		MV0194 (LME2510+SHARP0194)
+ *		MVB0194 (LME2510C+SHARP0194)
+ *		MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
+ *
+ * The VID of 3344 and PID of 1122 has not been set until it is known not
+ * to be generic.
+ *
+ *
+ * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
+ * LME2510   (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 as published by the Free
+ * Software Foundation, version 2.
+ *
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ * Known Issue :
+ * 	Non Intel USB chipsets fail to maintain High Speed on Boot or Hot Plug
+ *
+  */
+#define DVB_USB_LOG_PREFIX "LME2510"
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include "dvb-usb.h"
+#include "lmedm04.h"
+#include "tda826x.h"
+#include "tda10086.h"
+
+/* debug */
+static int dvb_usb_lme2510_debug;
+#define l_dprintk(var, level, args...) \
+	do { if ((var >= level)) info(args);  } while (0)
+#define deb_info(level, args...) l_dprintk(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));
+
+
+module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."
+			DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+
+struct lme2510_state {
+	u8 id;
+	u8 signal_lock;
+	u8 signal_level;
+	u8 signal_sn;
+	u8 time_key;
+	u8 i2c_talk_onoff;
+	u16 pid_table[64];
+	u8 pid_count;
+	u8 pid_flag_enable;
+	u8 filter_data[256];
+	void *buffer;
+	struct urb *lme_urb;
+
+};
+
+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, 500);
+	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, 500);
+	return ret;
+}
+
+static int lme2510_usb_talk(struct dvb_usb_device *d,
+		u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+	u8 s[wlen+4], r[rlen+4];
+	int ret = 0;
+	memset(s, 0, wlen);
+	memset(r, 0, rlen);
+	memcpy(&s[0], wbuf, wlen);
+
+	ret = mutex_lock_interruptible(&d->usb_mutex);
+
+	if (ret < 0)
+		return -EAGAIN;
+
+	ret += usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
+	msleep(5);
+	ret += lme2510_bulk_write(d->udev, s, wlen , 0x1);
+
+	msleep(5);
+	ret += usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x1));
+
+	msleep(5);
+	ret += lme2510_bulk_read(d->udev, r, rlen , 0x1);
+
+	if (rlen > 0)
+		memcpy(rbuf, &r[0], rlen);
+
+	mutex_unlock(&d->usb_mutex);
+
+	return (ret < 0) ? -EAGAIN : 0;
+}
+
+static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
+{
+	struct dvb_usb_device *d = adap->dev;
+	u32 event = 0;
+
+		switch (keypress) {
+		KEYCASE(LME_R_1, KEY_1);
+		break;
+		KEYCASE(LME_R_2, KEY_2);
+		break;
+		KEYCASE(LME_R_3, KEY_3);
+		break;
+		KEYCASE(LME_R_4, KEY_4);
+		break;
+		KEYCASE(LME_R_5, KEY_5);
+		break;
+		KEYCASE(LME_R_6, KEY_6);
+		break;
+		KEYCASE(LME_R_7, KEY_7);
+		break;
+		KEYCASE(LME_R_8, KEY_8);
+		break;
+		KEYCASE(LME_R_9, KEY_9);
+		break;
+		KEYCASE(LME_R_0, KEY_0);
+		break;
+		KEYCASE(LME_R_POWER, KEY_POWER);
+		break;
+		KEYCASE(LME_R_SUB, KEY_SUBTITLE);
+		break;
+		KEYCASE(LME_R_CAPTURE, KEY_PAUSE);
+		break;
+		KEYCASE(LME_R_REPEAT, KEY_MEDIA_REPEAT);
+		break;
+		KEYCASE(LME_R_PAUSE, KEY_PAUSE);
+		break;
+		KEYCASE(LME_R_VOL_D, KEY_VOLUMEDOWN);
+		break;
+		KEYCASE(LME_R_VOL_U, KEY_VOLUMEUP);
+		break;
+		KEYCASE(LME_R_CH_D, KEY_CHANNELDOWN);
+		break;
+		KEYCASE(LME_R_CH_U, KEY_CHANNELUP);
+		break;
+		KEYCASE(LME_R_PLAYBACK, KEY_PLAY);
+		break;
+		KEYCASE(LME_R_ZOOM, KEY_ZOOM);
+		break;
+		KEYCASE(LME_R_MUTE, KEY_MUTE);
+		break;
+		KEYCASE(LME_R_LIVETV, KEY_TV);
+		break;
+		KEYCASE(LME_R_RECORD, KEY_RECORD);
+		break;
+		KEYCASE(LME_R_EPG, KEY_EPG);
+		break;
+		KEYCASE(LME_R_STOP, KEY_STOPCD);
+		break;
+		default:
+			event = 0;
+		break;
+
+
+
+	}
+
+		deb_info(1, "INT Key Pressed =%04x Event =%04x",
+			 keypress, event);
+	if (event > 0) {
+		input_event(d->rc_input_dev, EV_KEY, event, 1);
+
+		input_event(d->rc_input_dev, EV_KEY, event, 0);
+
+		}
+
+    return 0;
+}
+
+static int lme2510_enable_filter(struct dvb_usb_adapter *adap)
+{
+	struct lme2510_state *st = adap->dev->priv;
+	static u8 filter_init[] = LME_FILTER_INT;
+	static u8 filter_on[] = LME_ST_ON_W;
+	static u8 rbuf[1];
+	static u8 *sbuf;
+	int ret = 0, len = 5;
+	info("PID Setting Filter");
+
+	sbuf = (u8 *) st->filter_data;
+
+
+	ret += lme2510_usb_talk(adap->dev,  filter_init, len, rbuf, 1);
+
+	ret += lme2510_usb_talk(adap->dev, sbuf, 80 , rbuf, 1);
+
+	ret += lme2510_usb_talk(adap->dev, filter_on, len, rbuf, 1);
+
+	st->pid_count = 0;
+	st->pid_flag_enable = 0;
+
+	return ret;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
+static void lme2510_int_response(struct urb *lme_urb, struct pt_regs *ptregs)
+#else
+static void lme2510_int_response(struct urb *lme_urb)
+#endif
+{
+	struct dvb_usb_adapter *adap = lme_urb->context;
+	struct lme2510_state *st = adap->dev->priv;
+	static u8 *ibuf, *rbuf;
+	int i = 0, offset;
+
+		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 in", ibuf);
+			lme2510_remote_keypress(adap,
+				(u16)(ibuf[4]<<8)+ibuf[5]);
+			break;
+		case 0xbb:
+			st->signal_lock = ibuf[2];
+			st->signal_level = ibuf[4];
+			st->signal_sn = ibuf[3];
+			st->time_key = ibuf[7];
+		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 lme2510_state *lme_int = adap->dev->priv;
+	lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+	if (lme_int->lme_urb == NULL)
+			return -ENOMEM;
+
+	lme_int->buffer = usb_buffer_alloc(adap->dev->udev, 5000, GFP_ATOMIC,
+					&lme_int->lme_urb->transfer_dma);
+
+	if (lme_int->buffer == NULL)
+			return -ENOMEM;
+
+	usb_fill_int_urb(lme_int->lme_urb,
+				adap->dev->udev,
+				usb_rcvintpipe(adap->dev->udev, 0xa),
+				lme_int->buffer,
+				4096,
+				lme2510_int_response,
+				adap,
+				11);
+
+	lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
+	info("INT Interupt Service Started");
+
+	return 0;
+}
+
+static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	struct lme2510_state *st = adap->dev->priv;
+	static u8 clear_pid_reg_3[] = LME_CLEAR_PID;
+	static u8 rbuf[1];
+	int ret = 0;
+	deb_info(3, "PID ONOFF Filter talk =%04x onoff=%02x pid_flag%02x",
+			st->i2c_talk_onoff, onoff, st->pid_flag_enable);
+
+	if (onoff == 0)
+			return 0;
+	else {
+		deb_info(1, "PID Clearing Filter");
+		ret += lme2510_usb_talk(adap->dev,
+			clear_pid_reg_3, 4, rbuf, 1);
+		}
+	return 0;
+
+}
+
+static int lme2510_pidbuild_table(struct lme2510_state *st)
+{
+	u8 buffer_complete[] = {0x00, 0x00, 0x01, 0x00, 0x02,
+				0x00, 0x10, 0x00, 0x11, 0x00,
+				0x12, 0x00, 0x13, 0x00, 0x14,
+				0x00, 0x20, 0x9a};
+	u16 pid_out;
+	int j, i, b = 0, je, reg = 0;
+	u8 temp_buff[256];
+
+	deb_info(1, "PID Building Table");
+
+	j = 3;
+	temp_buff[0] = 0x03;
+	i = 2;
+	reg = 0;
+	while (j < 8) {
+		pid_out = st->pid_table[j++];
+			if (pid_out == 0x0012)
+				break;
+		temp_buff[i++] = reg++;
+		temp_buff[i++] = (u8) pid_out & 0xff;
+		temp_buff[i++] = reg++;
+		temp_buff[i++] = pid_out>>8;
+		};
+		temp_buff[i++] = reg++;
+		temp_buff[i++] = 0xfb;
+		temp_buff[i++] = reg++;
+		temp_buff[i++] = 0x1f;
+		temp_buff[i++] = reg++;
+		temp_buff[i++] = st->pid_table[3]&0xff;
+		temp_buff[i++] =  reg++;
+		temp_buff[i++] = st->pid_table[3]>>8;
+		temp_buff[i++] =  reg++;
+		temp_buff[i++] = st->pid_table[2]&0xff;
+		temp_buff[i++] =  reg++;
+		temp_buff[i++] = st->pid_table[2]>>8;
+	j = i;
+	je = i+16;
+	while (j++ < je) {
+		temp_buff[i++] =  reg++;
+		temp_buff[i++] = buffer_complete[b++];
+		};
+		temp_buff[i] = 0x20;
+		temp_buff[1] =  i ;
+		temp_buff[++i] = 0x9a;
+
+		memcpy(st->filter_data, &temp_buff[0], 255);
+
+	deb_info(2, "PID T RAW WRITE DUMP-----");
+	for (i = 0; i < 10; i++)
+		debug_data_snipet(2, ">", &st->filter_data[i*8]);
+
+
+	return 0;
+}
+
+static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+	int onoff)
+{
+	struct lme2510_state *st = adap->dev->priv;
+	int ret = 0, i;
+
+	deb_info(4, "PID F PID=%04x Inx=%04x onoff=%02x i2c_talk=%02x FC=%02x",
+			pid, index, onoff,
+			st->i2c_talk_onoff,  adap->feedcount);
+
+	if ((pid == 0)&(index == 0)&(onoff == 0))
+		st->pid_count = 0;
+
+
+	if (index < 30) {
+		st->pid_table[st->pid_count] = pid;
+
+		deb_info(3, "PID T PID=%04x Inx=%04x onoff=%02x,i2c_talk=%02x",
+			st->pid_table[st->pid_count],
+			st->pid_count, onoff,
+			st->i2c_talk_onoff);
+
+		if ((st->pid_table[st->pid_count] == 0x0012) &
+						(st->pid_count > 3)) {
+			deb_info(2, "PID Table Dump---------");
+			for (i = 0; i < st->pid_count; i++)
+				deb_info(2, "PID No %02x=(%04x)",
+						i, st->pid_table[i]);
+
+
+			if ((st->pid_count < 8) &
+				(st->pid_table[3] != 0x0012)) {
+				ret = lme2510_pidbuild_table(st);
+				st->pid_flag_enable = 1;
+				ret -= lme2510_enable_filter(adap);
+			}
+				else
+			info("PID more than 4 - passing full stream");
+		} else
+		st->pid_count++;
+	}
+
+
+	return ret;
+}
+
+static int lme2510_return_status(struct usb_device *dev)
+{
+	int i;
+	u8 data[10] = {0};
+	i =  usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
+	/*i = usb_get_descriptor(dev, 0x03, 0x02, data, 0x06);*/
+	info("Firmware Status: %x (%x)", i, data[2]);
+	i = data[2];
+	return i;
+}
+
+
+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) {
+		if ((wbuf[0] == 0x84) & (wbuf[1] == 0x03) &
+			(wbuf[2] == 0x1c) & (wbuf[3] == 0x0e))
+			msleep(80); /*take your time when waiting for tune*/
+
+		if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+			return -EAGAIN;
+
+		ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+
+		mutex_unlock(&d->i2c_mutex);
+		}	else	{
+		if ((wbuf[0] == 0x84) & (wbuf[1] == 0x03)
+					& (wbuf[2] == 0x1c)) {
+			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;
+			default:
+					break;
+			}
+		deb_info(4, "I2C From Interupt 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);
+	static u8 obuf[64], ibuf[512];
+	int i, read;
+	u16 len;
+
+	if (num > 2)
+		warn("more than 2 i2c messages"
+			"at a time is not handled yet.	TODO.");
+
+	for (i = 0; i < num; i++) {
+		read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
+		obuf[0] = 0x04 | (read << 7);
+		obuf[1] = (msg[i].addr < 0x40) ? LME_I2C_C_L : LME_I2C_C_H;
+		obuf[2] = (msg[i].addr << 1);
+		if (read) {
+			memcpy(&obuf[3], msg[i].buf, msg[i].len);
+			obuf[4] = msg[i].len;
+			len = msg[i].len+4;
+		} else {
+			memcpy(&obuf[3], msg[i].buf, msg[i].len);
+			len = 64;
+		}
+
+
+		if (lme2510_msg(d, obuf, len, ibuf, 512) < 0) {
+			deb_info(1, "i2c transfer failed.");
+			return -EAGAIN;
+		}
+
+		if (read) {
+			memcpy(msg[i+1].buf, &ibuf[1],
+				(msg[i+1].len > 512) ? 512 : msg[i+1].len);
+
+			i++;
+		}
+	}
+	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,
+#ifdef NEED_ALGO_CONTROL
+	.algo_control = dummy_algo_control,
+#endif
+};
+
+/* Callbacks for DVB USB */
+static int lme2510_identify_state(struct usb_device *udev,
+		struct dvb_usb_device_properties *props,
+		struct dvb_usb_device_description **desc,
+		int *cold)
+{
+	*cold = 0;
+	return 0;
+}
+
+static int lme2510_init(struct dvb_usb_device *d)
+{
+	static u8 command1[] = LME_ST_OFF_C;
+	static u8 ibuf[512];
+	int ret, len = 5, len_in = 512;
+	msleep(500);
+	ret = lme2510_usb_talk(d, command1, len, ibuf, len_in);
+	return ret;
+}
+
+static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	struct lme2510_state *st = adap->dev->priv;
+	static u8 stream_off[] = LME_ST_OFF_C;
+	static u8 clear_reg_3[] =  LME_CLEAR_PID;
+	static u8 stream_on[] = LME_ST_ON_W;
+	static u8 rbuf[1];
+	int ret = 0, len = 5;
+	deb_info(1, "STM  (%02x)", onoff);
+
+	if (onoff == 1)	{
+		ret += lme2510_usb_talk(adap->dev,
+				 stream_on,  len, rbuf, 1);
+		st->i2c_talk_onoff = 0;
+	} else {
+		st->i2c_talk_onoff = 1;
+		ret += lme2510_usb_talk(adap->dev,
+					stream_off, len, rbuf, 1);
+		deb_info(1, "STM Clearing PID Filter");
+		ret += lme2510_usb_talk(adap->dev,
+			 clear_reg_3, 4, rbuf, 1);
+	}
+
+	return 0;
+}
+
+static int lme2510_int_service(struct dvb_usb_adapter *adap)
+{
+	struct dvb_usb_device *d = adap->dev;
+	struct input_dev *input_dev;
+	int ret, i;
+	u32 keys[] =  LME_KEYS_USED;
+	info("STA Configuring Remote");
+
+	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+
+	strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
+
+	input_dev->evbit[0] = BIT_MASK(EV_KEY);
+	input_dev->name = "LME2510 Remote Control";
+	input_dev->phys = d->rc_phys;
+	usb_to_input_id(d->udev, &input_dev->id);
+
+	for (i = 0; i < sizeof(keys)/4 ; ++i)
+		set_bit(keys[i], input_dev->keybit);
+
+	deb_info(3, "STA Number of Keys %d", sizeof(keys)/4);
+
+	ret = input_register_device(input_dev);
+	if (ret) {
+		input_free_device(input_dev);
+		return ret;
+	}
+
+	d->rc_input_dev = input_dev;
+	/* Start the Interupt */
+	ret = lme2510_int_read(adap);
+
+	if (ret < 0)
+		input_free_device(input_dev);
+
+	return (ret < 0) ? -ENODEV : 0;
+}
+
+static struct tda10086_config tda10086_config = {
+	.demod_address = 0x0e,
+	.invert = 0,
+	.diseqc_tone = 1,
+	.xtal_freq = TDA10086_XTAL_16M,
+};
+
+static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
+					fe_sec_voltage_t voltage)
+{
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	static u8 voltage_low[]	= LME_VOLTAGE_L;
+	static u8 voltage_high[] = LME_VOLTAGE_H;
+	static u8 rbuf[1];
+	int ret, len = 5;
+
+		switch (voltage) {
+
+		case SEC_VOLTAGE_18:
+			ret = lme2510_usb_talk(adap->dev,
+				voltage_high, len, rbuf, 1);
+		break;
+
+		case SEC_VOLTAGE_OFF:
+		case SEC_VOLTAGE_13:
+		default:
+		ret = lme2510_usb_talk(adap->dev,
+				voltage_low, len, rbuf, 1);
+		break;
+
+
+	};
+	return 0;
+}
+
+static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	int ret = 0;
+	struct lme2510_state *st = adap->dev->priv;
+	st->pid_flag_enable = 0;
+	/* Interupt Start  */
+	ret = lme2510_int_service(adap);
+	if (ret < 0) {
+		info("INT Unable to start Interupt Service");
+		return -ENODEV;
+	}
+
+	st->i2c_talk_onoff = 1;
+
+	ret = lme2510_init(adap->dev);
+
+	adap->fe = dvb_attach(tda10086_attach, &tda10086_config,
+		&adap->dev->i2c_adap);
+
+	if (adap->fe != NULL) {
+		memcpy(&adap->fe->ops.info.name,
+				&"DM04_LG_TDQY-P001F DVB-S", 24);
+		adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
+	} else {
+		info("This DM04 Device is not supported");
+		return -ENODEV;
+	}
+
+	return ret;
+}
+
+static int dm04_lme2510_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	if (dvb_attach(tda826x_attach, adap->fe, 0x60,
+			&adap->dev->i2c_adap, 1) == NULL) {
+		deb_info(1, "TDA8263 attach failed\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
+{
+	struct lme2510_state *st = d->priv;
+	st->i2c_talk_onoff = 1;
+	return 0;
+}
+
+static struct lme_firmware_data lme_firmware[] =   LME_FIRMWARE_D;
+
+static int lme2510_firmware(struct usb_device *dev, const struct firmware *fw)
+{
+	int ret = 0, j;
+	u8 data[1000] = {0};
+	u16 wlen = 253;
+	info("FRM Starting Firmware Download");
+
+	for (j = 0; j < 17; ++j)	{
+		wlen = (int)lme_firmware[j].length;
+		memcpy(&data[0], &lme_firmware[j].bulk_data[0],
+				(wlen < 256) ? wlen : 256);
+		ret += lme2510_bulk_write(dev, data,  wlen, 1);
+		ret += lme2510_bulk_read(dev, data, 512 , 1);
+		ret += (data[0] == 0x88) ? 0 : -1;
+	}
+
+	usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
+
+
+	data[0] = 0x8a;
+	msleep(2000);
+	ret += lme2510_bulk_write(dev, data , 1, 1); /*Resetting*/
+	ret += lme2510_bulk_read(dev, data, 512 , 1);
+	msleep(400);
+
+	if (ret < 0)
+		info("FRM Firmware Download Failed (%04x)" , ret);
+	else
+		info("FRM Firmware Download Completed - Resetting Device");
+
+
+	return (ret < 0) ? -ENODEV : 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties lme2510_properties;
+
+static int lme2510_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	int ret = 0;
+
+	usb_reset_configuration(udev);
+
+	usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1);
+
+	if (udev->speed != USB_SPEED_HIGH) {
+		ret = usb_reset_device(udev);
+		info("DEV Failed to connect in HIGH SPEED mode");
+		return -ENODEV;
+	}
+
+
+	if (0x44 == lme2510_return_status(udev)) {
+		ret += lme2510_firmware(udev, NULL);
+		return 0; /* reset on way */
+	}
+
+
+	if (0 == dvb_usb_device_init(intf, &lme2510_properties,
+				     THIS_MODULE, NULL, adapter_nr)) {
+		info("DEV registering device driver");
+		return 0;
+	}
+
+	info("DEV lme2510 Error");
+	return -ENODEV;
+
+}
+
+static struct usb_device_id lme2510_table[] = {
+	{ USB_DEVICE(0x3344, 0x1122) },  /* generic China models */
+	{}		/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, lme2510_table);
+
+static struct dvb_usb_device_properties lme2510_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.size_of_priv = sizeof(struct lme2510_state),
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER|
+				DVB_USB_ADAP_NEED_PID_FILTERING|
+				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+			.streaming_ctrl   = lme2510_streaming_ctrl,
+			.pid_filter_count = 29,
+			.pid_filter = lme2510_pid_filter,
+			.pid_filter_ctrl  = lme2510_pid_filter_ctrl,
+			.frontend_attach  = dm04_lme2510_frontend_attach,
+			.tuner_attach     = dm04_lme2510_tuner_attach,
+			/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+				.count = 10,
+				.endpoint = 0x06,
+				.u = {
+					.bulk = {
+						.buffersize = 4096,
+
+					}
+				}
+			}
+		}
+	},
+	.power_ctrl       = lme2510_powerup,
+	.identify_state   = lme2510_identify_state,
+	.i2c_algo         = &lme2510_i2c_algo,
+	.generic_bulk_ctrl_endpoint = 0,
+	.num_device_descs = 1,
+	.devices = {
+		{   "LME2510 + LG TDQY-P001F DVB-S USB2.0",
+			{ &lme2510_table[0], NULL },
+			},
+
+	}
+};
+
+void lme2510_exit_int(struct dvb_usb_device *d)
+{
+	struct lme2510_state *st = d->priv;
+		if (st->lme_urb != NULL) {
+			usb_kill_urb(st->lme_urb);
+			usb_buffer_free(d->udev, 5000, st->buffer,
+					st->lme_urb->transfer_dma);
+			info("Interupt Service Stopped");
+		}
+	return;
+}
+
+void lme2510_exit(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+	if (d != NULL) {
+		lme2510_exit_int(d);
+		input_unregister_device(d->rc_input_dev);
+		info("Remote Stopped");
+		dvb_usb_device_exit(intf);
+	}
+
+}
+
+static struct usb_driver lme2510_driver = {
+	.name		= "LME_DVBS",
+	.probe		= lme2510_probe,
+	.disconnect 	= lme2510_exit,
+	.id_table	= lme2510_table,
+};
+
+/* module stuff */
+static int __init lme2510_module_init(void)
+{
+	int result = usb_register(&lme2510_driver);
+	if (result) {
+		err("usb_register failed. Error number %d", result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit lme2510_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&lme2510_driver);
+}
+
+module_init(lme2510_module_init);
+module_exit(lme2510_module_exit);
+
+MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
+MODULE_DESCRIPTION("LME DVB-S USB2.0");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/lmedm04.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux/drivers/media/dvb/dvb-usb/lmedm04.h	Fri Jul 16 14:30:02 2010 +0100
@@ -0,0 +1,682 @@
+/* DVB USB compliant linux driver for
+ *
+ * LME DM040832731 (LME 2510 + TDQY-P001F)
+ *
+ * MV001F LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ *
+ * 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_
+
+
+/* Interupt */
+
+#define LME_REMOTE	0xaa
+#define LME_STREAM	0xbb
+#define LME_IDLE	0xcc
+
+
+/* Remote */
+
+#define KEYCASE(key, id) \
+do { case key: \
+  event = id;\
+ } while (0)
+
+#define LME_R_1		0xa05f
+#define LME_R_2		0xaf50
+#define LME_R_3		0xa25d
+#define LME_R_4		0xbe41
+#define LME_R_5		0xf50a
+#define LME_R_6		0xbd42
+#define LME_R_7		0xb847
+#define LME_R_8		0xb649
+#define LME_R_9		0xfa05
+#define LME_R_0		0xba45
+#define LME_R_POWER	0xbc43
+#define LME_R_SUB	0xb946
+#define LME_R_CAPTURE	0xf906
+#define LME_R_REPEAT	0xfc03
+#define LME_R_PAUSE	0xfd02
+#define LME_R_VOL_D	0xa35c
+#define LME_R_VOL_U	0xa15e
+#define LME_R_CH_D	0xe51a
+#define LME_R_CH_U	0xf609
+#define LME_R_PLAYBACK	0xe11e
+#define LME_R_ZOOM	0xe41b
+#define LME_R_MUTE	0xa659
+#define LME_R_LIVETV	0xa55a
+#define LME_R_RECORD	0xe718
+#define LME_R_EPG	0xf807
+#define LME_R_STOP	0xfe01
+
+#define	LME_KEYS_USED {	KEY_1, 			KEY_2, \
+			KEY_3, 			KEY_4, \
+			KEY_5, 			KEY_6, \
+			KEY_7, 			KEY_8, \
+			KEY_9, 			KEY_0, \
+			KEY_POWER, 		KEY_PAUSE, \
+			KEY_VOLUMEDOWN, 		KEY_VOLUMEUP, \
+			KEY_CHANNELDOWN, 	KEY_CHANNELUP, \
+			KEY_PLAY, 		KEY_MUTE, KEY_TV, \
+			KEY_ZOOM, 		KEY_EPG, \
+			KEY_SUBTITLE, 		KEY_RECORD, \
+			KEY_MEDIA_REPEAT, 	KEY_STOPCD, \
+			0x0000}
+
+
+/* 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 XX XX XX
+ *  offset 1 = 00
+ *  offset 2 = default after warm start 52, otherwise greater than 40
+ *  offset 3 = default after warm start 80, =(power offset 3),  82,  88
+ *  offset 4 = 20,  before PID setting 5c, 1c, d0,  (tuning 8c)
+ *
+ *  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, 0x52, 0x80, 0x20}
+#define LME_FILTER_INT	{0x06, 0x00, 0x92, 0x88, 0x5c}
+#define LME_ST_OFF_C	{0x06, 0x00, 0x52, 0x80, 0xd0}
+#define LME_CLEAR_PID   {0x03, 0x02, 0x20, 0xa0}
+
+/*
+#define LME_ST_INIT	{0x06, 0x00, 0x72, 0xb3, 0x1c}
+#define LME_ST_ON_C	{0x06, 0x00, 0x52, 0x80, 0x20}
+#define LME_ST_ON	{0x06, 0x00, 0x40, 0x82, 0x50}
+*/
+
+/* LME Power Control
+ *  07 XX XX XX XX
+ *  offset 1 = 01  Power? my device cannot be powered down
+ *  offset 2 = 00=Voltage low 01=Voltage high
+ *  offset 3 = unknown but usually AE, B1-B3
+ *  offset 4 = mosty C8 but sometimes C9
+ */
+
+#define LME_VOLTAGE_L	{0x07, 0x01, 0x00, 0xb3, 0xc9}
+#define LME_VOLTAGE_H	{0x07, 0x01, 0x01, 0xb3, 0xc9}
+
+/* I2C */
+#define LME_I2C_C_L	0x03
+#define LME_I2C_C_H	0x0c
+#define LME_I2C_WRITE	0x04
+#define LME_I2C_READ	0x84
+
+/* Firmware */
+#define FWF1	{\
+		0x01, 0xf9, 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 	\
+		0x00, 0x40, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 	\
+		0x01, 0x02, 0x03, 0x01, 0x0a, 0x06, 0x00, 0x02, 	\
+		0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x09, 0x02, 	\
+		0x37, 0x00, 0x01, 0x01, 0x00, 0xc0, 0xfa, 0x09, 	\
+		0x04, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 	\
+		0x09, 0x04, 0x00, 0x01, 0x04, 0xff, 0x00, 0x00, 	\
+		0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x00, 	\
+		0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 	\
+		0x05, 0x8a, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 	\
+		0x0a, 0x02, 0x40, 0x00, 0x00, 0x09, 0x07, 0x53, 	\
+		0x00, 0x01, 0x01, 0x00, 0xc0, 0xfa, 0x09, 0x04, 	\
+		0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 	\
+		0x04, 0x00, 0x01, 0x08, 0xff, 0x00, 0x00, 0x00, 	\
+		0x07, 0x05, 0x81, 0x02, 0x00, 0x02, 0x00, 0x07, 	\
+		0x05, 0x01, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 	\
+		0x02, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x86, 	\
+		0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x87, 0x02, 	\
+		0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 	\
+		0x00, 0x00, 0x07, 0x05, 0x8a, 0x03, 0x40, 0x00, 	\
+		0x0b, 0x07, 0x05, 0x0a, 0x02, 0x40, 0x00, 0x00, 	\
+		0x08, 0x03, 0x09, 0x04, 0x03, 0x04, 0x15, 0x16, 	\
+		0x05, 0x03, 0x41, 0x42, 0x43, 0x06, 0x03, 0x44, 	\
+		0x44, 0x44, 0x44, 0x07, 0x03, 0x48, 0x49, 0x50, 	\
+		0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x75}
+
+#define FWF2	{\
+		0x01, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 	\
+		0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00, 	\
+		0x03, 0x01, 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 	\
+		0x00, 0x40, 0x01, 0x00, 0x09, 0x02, 0x53, 0x00, 	\
+		0x01, 0x01, 0x00, 0xc0, 0xfa, 0x09, 0x04, 0x00, 	\
+		0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x04, 	\
+		0x00, 0x01, 0x08, 0xff, 0x00, 0x00, 0x00, 0x07, 	\
+		0x05, 0x81, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 	\
+		0x01, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x02, 	\
+		0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x86, 0x02, 	\
+		0x00, 0x02, 0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 	\
+		0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 	\
+		0x00, 0x07, 0x05, 0x8a, 0x03, 0x40, 0x00, 0x0b, 	\
+		0x07, 0x05, 0x0a, 0x02, 0x40, 0x00, 0x00, 0x09, 	\
+		0x07, 0x37, 0x00, 0x01, 0x01, 0x00, 0xc0, 0xfa, 	\
+		0x09, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 	\
+		0x00, 0x09, 0x04, 0x00, 0x01, 0x04, 0xff, 0x00, 	\
+		0x00, 0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 	\
+		0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 	\
+		0x07, 0x05, 0x8a, 0x02, 0x40, 0x00, 0x00, 0x07, 	\
+		0x05, 0x0a, 0x02, 0x40, 0x00, 0x00, 0x08, 0x03, 	\
+		0x09, 0x04, 0x03, 0x04, 0x15, 0x16, 0x05, 0x03, 	\
+		0x41, 0x42, 0x43, 0x06, 0x03, 0x47, 0x47, 0x47, 	\
+		0x47, 0x07, 0x03, 0x48, 0x49, 0x50, 0x51, 0x52, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x7e}
+
+
+#define FWF3	{0x81, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+
+#define FWP1	{\
+		0x02, 0xf9, 0x02, 0x05, 0xc5, 0x30, 0x01, 0xfd, 	\
+		0x8f, 0x99, 0xc2, 0x01, 0x22, 0x02, 0x09, 0x9f, 	\
+		0x22, 0xff, 0xff, 0xff, 0xff, 0x02, 0x0a, 0x92, 	\
+		0x90, 0xc0, 0x0b, 0xe0, 0x30, 0xe1, 0x02, 0xc3, 	\
+		0x22, 0xd3, 0x22, 0xff, 0xff, 0x02, 0x0c, 0xdc, 	\
+		0xc2, 0x05, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xf5, 	\
+		0x09, 0x90, 0xc0, 0x84, 0xe0, 0xff, 0x74, 0x0f, 	\
+		0x25, 0x09, 0xf8, 0xa6, 0x07, 0x05, 0x09, 0xe5, 	\
+		0x09, 0xb4, 0x02, 0xed, 0xe5, 0x0f, 0x12, 0x07, 	\
+		0x27, 0x00, 0x8b, 0x02, 0x00, 0xe0, 0x03, 0x01, 	\
+		0x4e, 0x04, 0x01, 0xd1, 0x05, 0x02, 0x61, 0x06, 	\
+		0x02, 0x76, 0x07, 0x02, 0xd8, 0x08, 0x03, 0x32, 	\
+		0x09, 0x03, 0x5c, 0x0a, 0x00, 0xb9, 0x82, 0x01, 	\
+		0x16, 0x83, 0x01, 0x92, 0x84, 0x02, 0x05, 0x85, 	\
+		0x02, 0x87, 0x87, 0x00, 0x7e, 0xf1, 0x00, 0xb3, 	\
+		0xf2, 0x02, 0x41, 0xf5, 0x00, 0x00, 0x03, 0x79, 	\
+		0x90, 0xc0, 0x0b, 0x74, 0x02, 0xf0, 0x90, 0xc1, 	\
+		0xa3, 0x74, 0x50, 0xf0, 0x22, 0x90, 0xc0, 0x84, 	\
+		0xe0, 0xf5, 0x0b, 0xe0, 0xf5, 0x0c, 0x90, 0xc0, 	\
+		0x36, 0x74, 0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
+		0x16, 0xf0, 0x74, 0x76, 0xf0, 0x90, 0xc1, 0xa8, 	\
+		0x74, 0x96, 0xf0, 0xad, 0x0c, 0xaf, 0x0b, 0x12, 	\
+		0x0c, 0x21, 0x02, 0x02, 0x02, 0x12, 0x0c, 0xcc, 	\
+		0x02, 0x02, 0x02, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 	\
+		0xc3, 0xe5, 0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 	\
+		0x00, 0x50, 0x14, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 	\
+		0x0c, 0xff, 0x12, 0x00, 0x03, 0x05, 0x0e, 0xe5, 	\
+		0x0e, 0x70, 0xe5, 0x05, 0x0d, 0x80, 0xe1, 0x02, 	\
+		0x02, 0x02, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xc3, 	\
+		0xe5, 0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 0x00, 	\
+		0x50, 0x23, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 0x0b, 	\
+		0xe0, 0xf5, 0x0c, 0xe4, 0x5a}
+
+
+#define FWP2	{\
+		0x02, 0xf9, 0x25, 0x0b, 0xf5, 0x82, 0xe4, 0x34, 	\
+		0x90, 0xf5, 0x83, 0xe5, 0x0c, 0xf0, 0x74, 0x02, 	\
+		0x25, 0x0e, 0xf5, 0x0e, 0xe4, 0x35, 0x0d, 0xf5, 	\
+		0x0d, 0x80, 0xd2, 0x02, 0x02, 0x02, 0x90, 0xc0, 	\
+		0x84, 0x74, 0x55, 0xf0, 0xe4, 0xf5, 0x0d, 0xf5, 	\
+		0x0e, 0xc3, 0xe5, 0x0e, 0x95, 0x10, 0xe5, 0x0d, 	\
+		0x94, 0x00, 0x50, 0x1f, 0x90, 0xc0, 0x84, 0xe0, 	\
+		0xf5, 0x0b, 0xff, 0xe4, 0x2f, 0xf5, 0x82, 0xe4, 	\
+		0x34, 0x90, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x84, 	\
+		0xf0, 0x05, 0x0e, 0xe5, 0x0e, 0x70, 0xda, 0x05, 	\
+		0x0d, 0x80, 0xd6, 0x02, 0x02, 0x56, 0x90, 0xc0, 	\
+		0x84, 0xe0, 0xf5, 0x0a, 0xe0, 0xf5, 0x0b, 0xe5, 	\
+		0x10, 0x24, 0xfe, 0xf5, 0x0e, 0xe4, 0x34, 0xff, 	\
+		0xf5, 0x0d, 0xe4, 0xf5, 0x09, 0xc3, 0xe5, 0x09, 	\
+		0x95, 0x0e, 0xe4, 0x95, 0x0d, 0x50, 0x10, 0x90, 	\
+		0xc0, 0x84, 0xe0, 0xff, 0x74, 0x2a, 0x25, 0x09, 	\
+		0xf8, 0xa6, 0x07, 0x05, 0x09, 0x80, 0xe6, 0x7b, 	\
+		0x00, 0x7a, 0x00, 0x79, 0x2a, 0x85, 0x0e, 0x16, 	\
+		0xad, 0x0b, 0xaf, 0x0a, 0x12, 0x08, 0xec, 0x02, 	\
+		0x02, 0xd1, 0x90, 0xc0, 0x84, 0x74, 0x55, 0xf0, 	\
+		0xe0, 0xf5, 0x0a, 0xe0, 0xf5, 0x0b, 0xe0, 0x75, 	\
+		0x0d, 0x00, 0xf5, 0x0e, 0x7b, 0x00, 0x7a, 0x00, 	\
+		0x79, 0x22, 0xf5, 0x16, 0xad, 0x0b, 0xaf, 0x0a, 	\
+		0x12, 0x06, 0x51, 0xe4, 0xf5, 0x09, 0xc3, 0xe5, 	\
+		0x09, 0x95, 0x0e, 0xe4, 0x95, 0x0d, 0x50, 0x0e, 	\
+		0x74, 0x22, 0x25, 0x09, 0xf8, 0xe6, 0x90, 0xc0, 	\
+		0x84, 0xf0, 0x05, 0x09, 0x80, 0xe8, 0x02, 0x02, 	\
+		0x56, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xc3, 0xe5, 	\
+		0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 0x00, 0x50, 	\
+		0x21, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 0x0a, 0xe0, 	\
+		0xf5, 0x0b, 0xe0, 0xf5, 0x2a, 0xfb, 0xad, 0x0b, 	\
+		0xaf, 0x0a, 0x12, 0x0a, 0x7f}
+
+#define FWP3	{\
+		0x02, 0xf9, 0x4a, 0x74, 0x03, 0x25, 0x0e, 0xf5, 	\
+		0x0e, 0xe4, 0x35, 0x0d, 0xf5, 0x0d, 0x80, 0xd4, 	\
+		0x02, 0x02, 0xd1, 0x90, 0xc0, 0x84, 0x74, 0x55, 	\
+		0xf0, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xc3, 0xe5, 	\
+		0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 0x00, 0x50, 	\
+		0x24, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 0x0a, 0xe0, 	\
+		0xf5, 0x0b, 0xfd, 0xaf, 0x0a, 0x12, 0x08, 0x92, 	\
+		0x8f, 0x22, 0x90, 0xc0, 0x84, 0xe5, 0x22, 0xf0, 	\
+		0x74, 0x02, 0x25, 0x0e, 0xf5, 0x0e, 0xe4, 0x35, 	\
+		0x0d, 0xf5, 0x0d, 0x80, 0xd1, 0x80, 0x15, 0x90, 	\
+		0xc0, 0x84, 0x74, 0x55, 0xf0, 0xe0, 0xf5, 0x0a, 	\
+		0xff, 0x12, 0x0b, 0x7e, 0x8f, 0x22, 0x90, 0xc0, 	\
+		0x84, 0xe5, 0x22, 0xf0, 0x90, 0xc0, 0x0b, 0x74, 	\
+		0x02, 0xf0, 0x90, 0xc0, 0x0f, 0xf0, 0x22, 0xe4, 	\
+		0xf5, 0x3b, 0xf5, 0x3c, 0x7b, 0xff, 0x7a, 0x0b, 	\
+		0x79, 0x0f, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x0b, 	\
+		0xd9, 0x02, 0x03, 0x47, 0x90, 0xc0, 0x84, 0xe0, 	\
+		0xf5, 0x0c, 0x70, 0x04, 0xc2, 0x83, 0x80, 0x02, 	\
+		0xd2, 0x83, 0x02, 0x02, 0xd1, 0x90, 0xc0, 0x84, 	\
+		0xe0, 0xf5, 0x09, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 	\
+		0xc3, 0xe5, 0x0e, 0x95, 0x09, 0xe5, 0x0d, 0x94, 	\
+		0x00, 0x50, 0x34, 0xc2, 0xb7, 0xd2, 0xb6, 0xe4, 	\
+		0xf5, 0x0b, 0x7f, 0xc8, 0x12, 0x05, 0x9e, 0x05, 	\
+		0x0b, 0xe5, 0x0b, 0xc3, 0x94, 0xc8, 0x40, 0xf2, 	\
+		0xd2, 0xb7, 0xc2, 0xb6, 0xe4, 0xf5, 0x0b, 0x7f, 	\
+		0xc8, 0x12, 0x05, 0x9e, 0x05, 0x0b, 0xe5, 0x0b, 	\
+		0xc3, 0x94, 0xc8, 0x40, 0xf2, 0x05, 0x0e, 0xe5, 	\
+		0x0e, 0x70, 0xc5, 0x05, 0x0d, 0x80, 0xc1, 0x90, 	\
+		0xc0, 0x0b, 0x74, 0x02, 0x80, 0x52, 0x90, 0xc0, 	\
+		0x36, 0x74, 0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
+		0x16, 0xf0, 0x74, 0x76, 0xf0, 0x90, 0xc1, 0xa8, 	\
+		0x74, 0x96, 0xf0, 0x90, 0xbb}
+
+
+#define FWP4	{\
+		0x02, 0xf9, 0xc0, 0x98, 0x74, 0x66, 0xf0, 0x90, 	\
+		0xc0, 0x84, 0xe0, 0xf5, 0x0c, 0xe4, 0xf5, 0x0d, 	\
+		0xf5, 0x0e, 0xc3, 0xe5, 0x0e, 0x95, 0x0c, 0xe5, 	\
+		0x0d, 0x94, 0x00, 0x50, 0x14, 0x90, 0xc0, 0x88, 	\
+		0xe0, 0xf5, 0x0a, 0x90, 0xc0, 0x98, 0xf0, 0x05, 	\
+		0x0e, 0xe5, 0x0e, 0x70, 0xe5, 0x05, 0x0d, 0x80, 	\
+		0xe1, 0x90, 0xc0, 0x0b, 0x74, 0x02, 0xf0, 0x90, 	\
+		0xc0, 0x13, 0xf0, 0x90, 0xc0, 0x37, 0xf0, 0x90, 	\
+		0xc0, 0x84, 0x74, 0x88, 0x80, 0x52, 0x90, 0xc0, 	\
+		0x56, 0x74, 0x8c, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
+		0x1a, 0xf0, 0x74, 0x7a, 0xf0, 0x90, 0xc1, 0xa8, 	\
+		0x74, 0x9a, 0xf0, 0x90, 0xc0, 0x0b, 0x74, 0x02, 	\
+		0xf0, 0x90, 0xc0, 0x84, 0x74, 0x88, 0xf0, 0x90, 	\
+		0xc0, 0x0f, 0x74, 0x02, 0xf0, 0xd2, 0x04, 0x22, 	\
+		0x90, 0xc0, 0x0b, 0x74, 0x02, 0xf0, 0x90, 0xc0, 	\
+		0x84, 0x74, 0x88, 0xf0, 0x90, 0xc0, 0x0f, 0x74, 	\
+		0x02, 0xf0, 0x7f, 0xc8, 0x12, 0x05, 0xb9, 0x90, 	\
+		0xff, 0xff, 0xe4, 0xf0, 0x22, 0x90, 0xc0, 0x0b, 	\
+		0x74, 0x02, 0xf0, 0x90, 0xc0, 0x84, 0x74, 0x77, 	\
+		0xf0, 0x90, 0xc0, 0x0f, 0x74, 0x02, 0xf0, 0x22, 	\
+		0xe4, 0xff, 0xfe, 0xf5, 0x0b, 0x20, 0xb2, 0x07, 	\
+		0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x80, 0xf6, 0xc3, 	\
+		0xef, 0x94, 0x28, 0xee, 0x94, 0x23, 0x50, 0x03, 	\
+		0x02, 0x04, 0x76, 0xd3, 0xef, 0x94, 0xc8, 0xee, 	\
+		0x94, 0x32, 0x40, 0x03, 0x02, 0x04, 0x76, 0xe4, 	\
+		0xfe, 0xff, 0x30, 0xb2, 0x07, 0x0f, 0xbf, 0x00, 	\
+		0x01, 0x0e, 0x80, 0xf6, 0xc3, 0xef, 0x94, 0x94, 	\
+		0xee, 0x94, 0x11, 0x50, 0x03, 0x02, 0x04, 0x76, 	\
+		0xd3, 0xef, 0x94, 0x4c, 0xee, 0x94, 0x1d, 0x40, 	\
+		0x03, 0x02, 0x04, 0x76, 0xe4, 0xfe, 0x7f, 0x04, 	\
+		0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x03, 0x02, 0x04, 	\
+		0x76, 0xe4, 0xf5, 0x0a, 0x39}
+
+#define FWP5	{\
+		0x02, 0xf9, 0xe4, 0xf5, 0x09, 0x05, 0x0b, 0x30, 	\
+		0xb2, 0xfd, 0x74, 0x48, 0x25, 0x0a, 0xf8, 0xc0, 	\
+		0x00, 0xe6, 0xc3, 0x13, 0xd0, 0x00, 0xf6, 0x7f, 	\
+		0x06, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x05, 0x7f, 	\
+		0x04, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x05, 0x7f, 	\
+		0x02, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x05, 0x7f, 	\
+		0x06, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x07, 0x7f, 	\
+		0x08, 0x12, 0x0c, 0xbc, 0x80, 0x09, 0x74, 0x48, 	\
+		0x25, 0x0a, 0xf8, 0xe6, 0x44, 0x80, 0xf6, 0x20, 	\
+		0xb2, 0xfd, 0x05, 0x09, 0xe5, 0x09, 0xc3, 0x94, 	\
+		0x08, 0x40, 0xb2, 0x05, 0x0a, 0xe5, 0x0a, 0xc3, 	\
+		0x94, 0x04, 0x40, 0xa6, 0xe5, 0x0b, 0x64, 0x20, 	\
+		0x70, 0x2e, 0xf5, 0x0b, 0xe5, 0x4a, 0x25, 0x4b, 	\
+		0xff, 0xe4, 0x33, 0xfe, 0xef, 0xf4, 0x4e, 0x70, 	\
+		0x1f, 0xd2, 0x03, 0x75, 0x4c, 0xaa, 0x75, 0x47, 	\
+		0x04, 0xf5, 0x0a, 0x74, 0x48, 0x25, 0x0a, 0xf8, 	\
+		0xe6, 0xff, 0x74, 0x3f, 0x25, 0x0a, 0xf8, 0xa6, 	\
+		0x07, 0x05, 0x0a, 0xe5, 0x0a, 0xb4, 0x04, 0xeb, 	\
+		0x22, 0x90, 0xc1, 0xa3, 0x74, 0x10, 0xf0, 0x90, 	\
+		0xc0, 0x0e, 0x74, 0x88, 0xf0, 0x90, 0xc1, 0xa2, 	\
+		0x74, 0x11, 0xf0, 0x74, 0x71, 0xf0, 0x90, 0xc1, 	\
+		0xa8, 0x74, 0x31, 0xf0, 0x90, 0xc0, 0x36, 0x74, 	\
+		0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x16, 0xf0, 	\
+		0x74, 0x76, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 0x36, 	\
+		0xf0, 0x90, 0xc0, 0x0a, 0x74, 0x88, 0xf0, 0x90, 	\
+		0xc1, 0xa2, 0x74, 0x01, 0xf0, 0x74, 0x61, 0xf0, 	\
+		0x90, 0xc1, 0xa8, 0x74, 0x21, 0xf0, 0x90, 0xc0, 	\
+		0x12, 0x74, 0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
+		0x02, 0xf0, 0x74, 0x62, 0xf0, 0x90, 0xc1, 0xa8, 	\
+		0x74, 0x22, 0xf0, 0x90, 0xc0, 0x3e, 0x74, 0x8b, 	\
+		0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x17, 0xf0, 0x74, 	\
+		0x77, 0xf0, 0x90, 0xc1, 0x1b}
+
+#define FWP6	{\
+		0x02, 0xf9, 0xa8, 0x74, 0x37, 0xf0, 0x90, 0xc0, 	\
+		0x56, 0x74, 0x8c, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
+		0x1a, 0xf0, 0x74, 0x7a, 0xf0, 0x90, 0xc1, 0xa8, 	\
+		0x74, 0x3a, 0xf0, 0x90, 0xc0, 0x1a, 0x74, 0x8b, 	\
+		0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x03, 0xf0, 0x74, 	\
+		0x63, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 0x23, 0xf0, 	\
+		0x90, 0xc0, 0x52, 0x74, 0x88, 0xf0, 0x90, 0xc1, 	\
+		0xa2, 0x74, 0x0a, 0xf0, 0x74, 0x6a, 0xf0, 0x90, 	\
+		0xc1, 0xa8, 0x74, 0x2a, 0xf0, 0x22, 0x12, 0x05, 	\
+		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
+		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
+		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
+		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
+		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
+		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
+		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
+		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
+		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
+		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
+		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
+		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
+		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
+		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
+		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
+		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
+		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
+		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
+		0xb9, 0xe4, 0xfe, 0xee, 0xc3, 0x9f, 0x50, 0x04, 	\
+		0x00, 0x0e, 0x80, 0xf7, 0x22, 0x78, 0x7f, 0xe4, 	\
+		0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x54, 0x02, 0x06, 	\
+		0x0c, 0x02, 0x07, 0x53, 0xe4, 0x93, 0xa3, 0xf8, 	\
+		0xe4, 0x93, 0xa3, 0x40, 0xe8}
+
+#define FWP7	{\
+		0x02, 0xf9, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 	\
+		0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 	\
+		0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 	\
+		0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 	\
+		0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 	\
+		0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 	\
+		0x40, 0x80, 0x90, 0x0c, 0x3f, 0xe4, 0x7e, 0x01, 	\
+		0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 	\
+		0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 	\
+		0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 	\
+		0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 	\
+		0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 	\
+		0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 	\
+		0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 	\
+		0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0x8d, 	\
+		0x12, 0x8b, 0x13, 0x8a, 0x14, 0x89, 0x15, 0xef, 	\
+		0x54, 0xfe, 0xf5, 0x18, 0x12, 0x0c, 0x5c, 0xaf, 	\
+		0x18, 0x12, 0x09, 0xf5, 0x20, 0x02, 0x02, 0x80, 	\
+		0x69, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0xaf, 0x12, 	\
+		0x12, 0x09, 0xf5, 0x7f, 0x14, 0x12, 0x05, 0xb9, 	\
+		0x20, 0x02, 0x02, 0x80, 0x55, 0x12, 0x0c, 0x5c, 	\
+		0xe5, 0x18, 0x04, 0xff, 0x12, 0x09, 0xf5, 0x20, 	\
+		0x02, 0x02, 0x80, 0x46, 0xe4, 0xf5, 0x17, 0xe5, 	\
+		0x16, 0x14, 0xff, 0xe5, 0x17, 0xc3, 0x9f, 0x50, 	\
+		0x1c, 0x12, 0x0a, 0xd2, 0xab, 0x13, 0xaa, 0x14, 	\
+		0xa9, 0x15, 0x85, 0x17, 0x82, 0x75, 0x83, 0x00, 	\
+		0xef, 0x12, 0x07, 0x05, 0xc2, 0x06, 0x12, 0x0c, 	\
+		0x78, 0x05, 0x17, 0x80, 0xda, 0x12, 0x0a, 0xd2, 	\
+		0xab, 0x13, 0xaa, 0x14, 0xa9, 0x15, 0x85, 0x17, 	\
+		0x82, 0x75, 0x83, 0x00, 0xef, 0x12, 0x07, 0x05, 	\
+		0xd2, 0x06, 0x12, 0x0c, 0x78, 0x7f, 0x14, 0x12, 	\
+		0x05, 0xb9, 0x12, 0x0c, 0x29}
+
+#define FWP8	{\
+		0x02, 0xf9, 0x94, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 	\
+		0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 	\
+		0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 	\
+		0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 	\
+		0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 	\
+		0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 	\
+		0x22, 0xf8, 0xbb, 0x01, 0x0d, 0xe5, 0x82, 0x29, 	\
+		0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe8, 	\
+		0xf0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xc8, 	\
+		0xf6, 0x22, 0xbb, 0xfe, 0x05, 0xe9, 0x25, 0x82, 	\
+		0xc8, 0xf2, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 	\
+		0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 	\
+		0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 	\
+		0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 	\
+		0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 	\
+		0xdf, 0x8a, 0x83, 0x89, 0x82, 0xe4, 0x73, 0x12, 	\
+		0x0c, 0x01, 0x12, 0x0c, 0xa9, 0x7b, 0xff, 0x7a, 	\
+		0x0b, 0x79, 0xb0, 0x7d, 0x28, 0x7c, 0x00, 0x12, 	\
+		0x0b, 0x49, 0x12, 0x00, 0x16, 0x50, 0x11, 0xc2, 	\
+		0x85, 0xc2, 0x00, 0x90, 0xc1, 0xa8, 0x74, 0x91, 	\
+		0xf0, 0x12, 0x00, 0x26, 0xd2, 0x85, 0x80, 0xea, 	\
+		0x20, 0xb2, 0x0c, 0xc2, 0xaa, 0x12, 0x03, 0x8c, 	\
+		0xd2, 0xaa, 0x12, 0x08, 0x2c, 0x80, 0xdb, 0xe5, 	\
+		0x3e, 0x24, 0x38, 0xff, 0xe5, 0x3d, 0x34, 0xff, 	\
+		0xfe, 0xef, 0xb5, 0x3c, 0xcd, 0xee, 0xb5, 0x3b, 	\
+		0xc9, 0x75, 0x2a, 0x1c, 0x75, 0x2b, 0x0e, 0x12, 	\
+		0x08, 0x8e, 0x8f, 0x22, 0xe5, 0x22, 0x30, 0xe4, 	\
+		0x04, 0xc2, 0x85, 0x80, 0x02, 0xd2, 0x85, 0x75, 	\
+		0x2b, 0x43, 0x12, 0x08, 0x8e, 0x8f, 0x23, 0x75, 	\
+		0x2b, 0x1c, 0x12, 0x08, 0x8e, 0x8f, 0x24, 0x80, 	\
+		0xa1, 0x90, 0x90, 0x00, 0x74, 0x01, 0xf0, 0xe4, 	\
+		0xa3, 0xf0, 0xa3, 0xf0, 0xdc}
+
+
+#define FWP9	{\
+		0x02, 0xf9, 0xa3, 0xf0, 0xa3, 0x74, 0x03, 0xf0, 	\
+		0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 	\
+		0x74, 0x05, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 	\
+		0xa3, 0xf0, 0xa3, 0x74, 0x07, 0xf0, 0xe4, 0xa3, 	\
+		0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x09, 	\
+		0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 	\
+		0xa3, 0x74, 0x0b, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 	\
+		0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x0d, 0xf0, 0xe4, 	\
+		0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 	\
+		0x0f, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 	\
+		0xf0, 0xa3, 0x74, 0xb5, 0xf0, 0xa3, 0x74, 0x06, 	\
+		0xf0, 0xa3, 0x74, 0xbc, 0xf0, 0x22, 0xe5, 0x47, 	\
+		0x60, 0x5d, 0xc2, 0xaa, 0x75, 0xa0, 0x01, 0x85, 	\
+		0x4c, 0x33, 0x85, 0x47, 0x34, 0xe4, 0xff, 0xef, 	\
+		0xc3, 0x95, 0x47, 0x50, 0x0f, 0x74, 0x3f, 0x2f, 	\
+		0xf8, 0xe6, 0xfe, 0x74, 0x35, 0x2f, 0xf8, 0xa6, 	\
+		0x06, 0x0f, 0x80, 0xeb, 0x75, 0x21, 0x08, 0xe4, 	\
+		0xf5, 0x47, 0x20, 0x00, 0x2d, 0x90, 0xc1, 0xa8, 	\
+		0x74, 0x9a, 0xf0, 0x90, 0xc0, 0xa8, 0xe5, 0x33, 	\
+		0xf0, 0xe5, 0x34, 0xf0, 0xe5, 0x35, 0xf0, 0xe5, 	\
+		0x36, 0xf0, 0xe5, 0x37, 0xf0, 0xe5, 0x38, 0xf0, 	\
+		0xe5, 0x39, 0xf0, 0xe5, 0x3a, 0xf0, 0x90, 0xc0, 	\
+		0x57, 0x74, 0x02, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 	\
+		0x3a, 0xf0, 0xd2, 0xaa, 0x75, 0xa0, 0x02, 0x22, 	\
+		0xad, 0x2b, 0xaf, 0x2a, 0x8d, 0x11, 0xef, 0x54, 	\
+		0xfe, 0xf5, 0x13, 0x12, 0x0c, 0x5c, 0x7f, 0x14, 	\
+		0x12, 0x05, 0xb9, 0xaf, 0x13, 0x12, 0x09, 0xf5, 	\
+		0x20, 0x02, 0x02, 0x80, 0x21, 0x7f, 0x14, 0x12, 	\
+		0x05, 0xb9, 0xaf, 0x11, 0x12, 0x09, 0xf5, 0x20, 	\
+		0x02, 0x02, 0x80, 0x12, 0x7f, 0x14, 0x12, 0x05, 	\
+		0xb9, 0x12, 0x0c, 0x5c, 0xe5, 0x13, 0x04, 0xff, 	\
+		0x12, 0x09, 0xf5, 0x20, 0x9b}
+
+
+#define FWP10	{\
+		0x02, 0xf9, 0x02, 0x06, 0x12, 0x0c, 0x94, 0x7f, 	\
+		0x00, 0x22, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 	\
+		0x0a, 0xd2, 0x8f, 0x12, 0xd2, 0x06, 0x12, 0x0c, 	\
+		0x78, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x0c, 	\
+		0x94, 0xaf, 0x12, 0x22, 0x8d, 0x12, 0x8b, 0x13, 	\
+		0x8a, 0x14, 0x89, 0x15, 0xef, 0x54, 0xfe, 0xf5, 	\
+		0x18, 0x12, 0x0c, 0x5c, 0xaf, 0x18, 0x12, 0x09, 	\
+		0xf5, 0x20, 0x02, 0x02, 0x80, 0x3f, 0x7f, 0x14, 	\
+		0x12, 0x05, 0xb9, 0xaf, 0x12, 0x12, 0x09, 0xf5, 	\
+		0x20, 0x02, 0x02, 0x80, 0x30, 0x7f, 0x14, 0x12, 	\
+		0x05, 0xb9, 0xe4, 0xf5, 0x17, 0xe5, 0x17, 0xc3, 	\
+		0x95, 0x16, 0x50, 0x17, 0xab, 0x13, 0xaa, 0x14, 	\
+		0xa9, 0x15, 0x85, 0x17, 0x82, 0x75, 0x83, 0x00, 	\
+		0x12, 0x06, 0xd8, 0xff, 0x12, 0x09, 0xf5, 0x05, 	\
+		0x17, 0x80, 0xe2, 0x20, 0x02, 0x02, 0x80, 0x05, 	\
+		0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x0c, 0x94, 	\
+		0x22, 0x05, 0x3a, 0x30, 0x04, 0x50, 0xe5, 0x21, 	\
+		0x90, 0xc1, 0xa8, 0x70, 0x1c, 0x74, 0x9a, 0xf0, 	\
+		0x90, 0xc0, 0xa8, 0x74, 0xbb, 0xf0, 0x74, 0x03, 	\
+		0xf0, 0xe5, 0x22, 0xf0, 0xe5, 0x23, 0xf0, 0xe5, 	\
+		0x24, 0xf0, 0xe5, 0x25, 0xf0, 0xe5, 0x26, 0x80, 	\
+		0x1a, 0x74, 0x9a, 0xf0, 0x90, 0xc0, 0xa8, 0xe5, 	\
+		0x33, 0xf0, 0xe5, 0x34, 0xf0, 0xe5, 0x35, 0xf0, 	\
+		0xe5, 0x36, 0xf0, 0xe5, 0x37, 0xf0, 0xe5, 0x38, 	\
+		0xf0, 0xe5, 0x39, 0xf0, 0xe5, 0x3a, 0xf0, 0x90, 	\
+		0xc0, 0x57, 0x74, 0x02, 0xf0, 0x90, 0xc1, 0xa8, 	\
+		0x74, 0x3a, 0xf0, 0xe4, 0xf5, 0x21, 0x22, 0xc0, 	\
+		0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 	\
+		0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x01, 	\
+		0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 	\
+		0xc0, 0x06, 0xc0, 0x07, 0xc2, 0x8d, 0x05, 0x4f, 	\
+		0xe5, 0x4f, 0x70, 0x02, 0xf9}
+
+
+#define FWP11	{\
+		0x02, 0xf9, 0x05, 0x4e, 0xc3, 0x95, 0x54, 0xe5, 	\
+		0x4e, 0x95, 0x53, 0x40, 0x0b, 0xc2, 0x8c, 0xc2, 	\
+		0xa9, 0xaa, 0x51, 0xa9, 0x52, 0x12, 0x07, 0x4d, 	\
+		0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 	\
+		0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 	\
+		0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 	\
+		0xd0, 0xe0, 0x32, 0x8f, 0x19, 0xe4, 0xf5, 0x1a, 	\
+		0xaf, 0x1a, 0xe5, 0x19, 0xa8, 0x07, 0x08, 0x80, 	\
+		0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x30, 0xe7, 0x04, 	\
+		0xd2, 0x80, 0x80, 0x02, 0xc2, 0x80, 0x7f, 0x08, 	\
+		0x12, 0x05, 0xb9, 0xd2, 0x81, 0x7f, 0x0a, 0x12, 	\
+		0x05, 0xb9, 0xc2, 0x81, 0x05, 0x1a, 0xe5, 0x1a, 	\
+		0xc3, 0x94, 0x08, 0x40, 0xd3, 0x7f, 0x02, 0x12, 	\
+		0x05, 0xb9, 0xd2, 0x80, 0x7f, 0x0a, 0x12, 0x05, 	\
+		0xb9, 0xd2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 	\
+		0x30, 0x80, 0x04, 0xc2, 0x02, 0x80, 0x02, 0xd2, 	\
+		0x02, 0xc2, 0x81, 0x7f, 0x0a, 0x02, 0x05, 0xb9, 	\
+		0x8d, 0x11, 0x8b, 0x12, 0xef, 0x54, 0xfe, 0xf5, 	\
+		0x13, 0x12, 0x0c, 0x5c, 0x7f, 0x14, 0x12, 0x05, 	\
+		0xb9, 0xaf, 0x13, 0x12, 0x09, 0xf5, 0x20, 0x02, 	\
+		0x02, 0x80, 0x1c, 0x7f, 0x14, 0x12, 0x05, 0xb9, 	\
+		0xaf, 0x11, 0x12, 0x09, 0xf5, 0x20, 0x02, 0x02, 	\
+		0x80, 0x0d, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0xaf, 	\
+		0x12, 0x12, 0x09, 0xf5, 0x20, 0x02, 0x03, 0x02, 	\
+		0x0c, 0x94, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 	\
+		0x0c, 0x94, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x22, 	\
+		0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 	\
+		0x75, 0xd0, 0x00, 0xc0, 0x06, 0xc0, 0x07, 0xc2, 	\
+		0x8b, 0x05, 0x3c, 0xe5, 0x3c, 0x70, 0x02, 0x05, 	\
+		0x3b, 0x30, 0x00, 0x17, 0xc3, 0x95, 0x3e, 0xe5, 	\
+		0x3b, 0x95, 0x3d, 0x40, 0x0e, 0x75, 0x3b, 0x00, 	\
+		0x75, 0x3c, 0x00, 0x7f, 0xbc}
+
+
+#define FWP12	{\
+		0x02, 0xf9, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x09, 	\
+		0x49, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0xd0, 0xd0, 	\
+		0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xe4, 0xf5, 	\
+		0x19, 0xd2, 0x80, 0xf5, 0x1a, 0x7f, 0x01, 0x12, 	\
+		0x05, 0xb9, 0xc2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 	\
+		0xb9, 0xd2, 0x81, 0x7f, 0x08, 0x12, 0x05, 0xb9, 	\
+		0xe5, 0x19, 0x25, 0xe0, 0xf5, 0x19, 0x30, 0x80, 	\
+		0x02, 0x05, 0x19, 0x7f, 0x01, 0x12, 0x05, 0xb9, 	\
+		0x05, 0x1a, 0xe5, 0x1a, 0xc3, 0x94, 0x08, 0x40, 	\
+		0xd4, 0xc2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 	\
+		0xaf, 0x19, 0x22, 0x85, 0x3b, 0x3d, 0x85, 0x3c, 	\
+		0x3e, 0x90, 0xc0, 0xa8, 0x74, 0xcc, 0xf0, 0x74, 	\
+		0x02, 0xf0, 0xe5, 0x3d, 0xf0, 0xe5, 0x3e, 0xf0, 	\
+		0xe4, 0xf0, 0xf0, 0xf0, 0xf0, 0x90, 0xc0, 0x57, 	\
+		0x74, 0x02, 0xf0, 0x90, 0xc0, 0x36, 0x74, 0x8b, 	\
+		0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x16, 0xf0, 0x74, 	\
+		0x76, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 0x36, 0xf0, 	\
+		0xd2, 0x00, 0xc2, 0x85, 0x22, 0x8b, 0x09, 0x8a, 	\
+		0x0a, 0x89, 0x0b, 0x8c, 0x0c, 0x8d, 0x0d, 0xe4, 	\
+		0xfd, 0xfc, 0xc3, 0xed, 0x95, 0x0d, 0xe5, 0x0c, 	\
+		0x64, 0x80, 0xf8, 0xec, 0x64, 0x80, 0x98, 0x50, 	\
+		0x18, 0xab, 0x09, 0xaa, 0x0a, 0xa9, 0x0b, 0x8d, 	\
+		0x82, 0x8c, 0x83, 0x12, 0x06, 0xd8, 0xff, 0x12, 	\
+		0x00, 0x03, 0x0d, 0xbd, 0x00, 0x01, 0x0c, 0x80, 	\
+		0xd9, 0x22, 0x8f, 0x11, 0x12, 0x0c, 0x5c, 0x7f, 	\
+		0x14, 0x12, 0x05, 0xb9, 0xaf, 0x11, 0x12, 0x09, 	\
+		0xf5, 0x20, 0x02, 0x06, 0x12, 0x0c, 0x94, 0x7f, 	\
+		0x00, 0x22, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 	\
+		0x0a, 0xd2, 0x8f, 0x12, 0xd2, 0x06, 0x12, 0x0c, 	\
+		0x78, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x0c, 	\
+		0x94, 0xaf, 0x12, 0x22, 0x54, 0x44, 0x20, 0x69, 	\
+		0x6e, 0x69, 0x74, 0x20, 0x2d}
+
+
+#define FWP13	{\
+		0x02, 0xf9, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 	\
+		0x3a, 0x65, 0x78, 0x63, 0x75, 0x74, 0x65, 0x20, 	\
+		0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 	\
+		0x69, 0x6e, 0x20, 0x70, 0x64, 0x72, 0x61, 0x6d, 	\
+		0x0d, 0x0a, 0x00, 0xc2, 0xaf, 0xc2, 0x8c, 0xe5, 	\
+		0x89, 0x54, 0xf0, 0x44, 0x02, 0xf5, 0x89, 0x75, 	\
+		0x8c, 0x87, 0x75, 0x8a, 0x87, 0x8e, 0x53, 0x8f, 	\
+		0x54, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x8b, 0x50, 	\
+		0x8a, 0x51, 0x89, 0x52, 0xd2, 0xa9, 0xd2, 0x8c, 	\
+		0xd2, 0xaf, 0x22, 0x90, 0xc1, 0xa3, 0x74, 0x50, 	\
+		0xf0, 0x7f, 0xc8, 0x12, 0x05, 0x26, 0x12, 0x05, 	\
+		0x26, 0x74, 0x10, 0xf0, 0x90, 0x80, 0x90, 0x74, 	\
+		0x05, 0xf0, 0x12, 0x07, 0xc5, 0x12, 0x04, 0x77, 	\
+		0x02, 0x0c, 0xfa, 0x75, 0x98, 0x50, 0x75, 0x89, 	\
+		0x20, 0xef, 0x70, 0x05, 0x53, 0x87, 0x7f, 0x80, 	\
+		0x03, 0x43, 0x87, 0x80, 0x8d, 0x8d, 0xd2, 0x8e, 	\
+		0xc2, 0x98, 0xc2, 0x99, 0xd2, 0xac, 0xd2, 0xaf, 	\
+		0x22, 0xc1, 0x81, 0x02, 0x3b, 0x00, 0x00, 0x02, 	\
+		0x3d, 0x03, 0xe8, 0x01, 0x47, 0x00, 0x01, 0x21, 	\
+		0x00, 0xc1, 0x04, 0xc1, 0x00, 0x02, 0x53, 0x00, 	\
+		0x00, 0x02, 0x4e, 0x00, 0x00, 0x00, 0xd2, 0x80, 	\
+		0x7f, 0x14, 0x12, 0x05, 0xb9, 0xd2, 0x81, 0x7f, 	\
+		0x14, 0x12, 0x05, 0xb9, 0xc2, 0x80, 0x7f, 0x14, 	\
+		0x12, 0x05, 0xb9, 0xc2, 0x81, 0x7f, 0x14, 0x02, 	\
+		0x05, 0xb9, 0x20, 0x06, 0x04, 0xc2, 0x80, 0x80, 	\
+		0x02, 0xd2, 0x80, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 	\
+		0xd2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 0xc2, 	\
+		0x81, 0x7f, 0x0a, 0x02, 0x05, 0xb9, 0xc2, 0x80, 	\
+		0x7f, 0x14, 0x12, 0x05, 0xb9, 0xd2, 0x81, 0x7f, 	\
+		0x14, 0x12, 0x05, 0xb9, 0xd2, 0x80, 0x7f, 0x14, 	\
+		0x02, 0x05, 0xb9, 0x90, 0x80, 0x90, 0x74, 0x05, 	\
+		0xf0, 0xe4, 0xf5, 0xa0, 0x07}
+
+#define FWCT	{\
+		0x82, 0x4e, 0x12, 0x0c, 0xfa, 0xd2, 0x8a, 0xd2, 	\
+		0xaa, 0xd2, 0xaf, 0x22, 0xef, 0xd3, 0x94, 0x00, 	\
+		0x40, 0x09, 0xe4, 0xfe, 0x0e, 0xbe, 0x76, 0xfc, 	\
+		0x1f, 0x80, 0xf1, 0x22, 0xc2, 0xaf, 0xc2, 0xac, 	\
+		0xc2, 0x98, 0xc2, 0x99, 0x75, 0x98, 0x40, 0xc2, 	\
+		0xa9, 0xc2, 0x8e, 0x22, 0x30, 0x99, 0x04, 0xd2, 	\
+		0x01, 0xc2, 0x99, 0x30, 0x98, 0x05, 0x85, 0x99, 	\
+		0x08, 0xc2, 0x98, 0x32, 0xc2, 0x8c, 0xc2, 0xa9, 	\
+		0x75, 0x50, 0xff, 0x75, 0x51, 0x00, 0x75, 0x52, 	\
+		0x0e, 0x22, 0x7d, 0xf8, 0xe4, 0xff, 0x02, 0x0c, 	\
+		0x21, 0xfd}
+
+#define FWTRL	0xfd
+#define FWCTL	0x52
+#define FWF3L	0x0f
+#define LME_FIRMWARE_D	{{FWTRL, FWF1}, 	\
+			{FWTRL, FWF2}, 	\
+			{FWF3L, FWF3}, 	\
+			{FWTRL, FWP1}, 	\
+			{FWTRL, FWP2}, 	\
+			{FWTRL, FWP3}, 	\
+			{FWTRL, FWP4}, 	\
+			{FWTRL, FWP5}, 	\
+			{FWTRL, FWP6}, 	\
+			{FWTRL, FWP7}, 	\
+			{FWTRL, FWP8}, 	\
+			{FWTRL, FWP9}, 	\
+			{FWTRL, FWP10}, 	\
+			{FWTRL, FWP11}, 	\
+			{FWTRL, FWP12}, 	\
+			{FWTRL, FWP13}, 	\
+			{FWCTL, FWCT} }
+
+struct lme_firmware_data {
+	u8 length;
+	u8 bulk_data[256];       /* Address */
+};
+
+#endif

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] added support for DM040832731 DVB-S USB BOX - Correction
  2010-07-16 13:43 [PATCH] added support for DM040832731 DVB-S USB BOX - Correction Malcolm Priestley
@ 2010-07-29 18:16 ` Mauro Carvalho Chehab
  2010-09-08 21:08   ` Mauro Carvalho Chehab
  2010-07-29 18:18 ` Mauro Carvalho Chehab
  1 sibling, 1 reply; 4+ messages in thread
From: Mauro Carvalho Chehab @ 2010-07-29 18:16 UTC (permalink / raw)
  To: Malcolm Priestley; +Cc: linux-media

Em 16-07-2010 10:43, Malcolm Priestley escreveu:
> DVB USB Driver for DM04 LME2510 + LG TDQY - P001F =(TDA8263 + TDA10086H)
> 
> Corrected patch error.
> 
> Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>

Hi Malcom,

Please read the developers section of our Wiki page for instructions on how to submit
a driver:
	http://linuxtv.org/wiki/index.php/Developer_Section

In special, you need to read what's inside "Submiting your work" in order to fix some
troubles I identified on your driver.

> 
> 
> 
> diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/Kconfig
> --- a/linux/drivers/media/dvb/dvb-usb/Kconfig	Thu May 27 02:02:09 2010 -0300
> +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig	Fri Jul 16 14:30:02 2010 +0100
> @@ -346,3 +346,13 @@
>  	select DVB_STB6100 if !DVB_FE_CUSTOMISE
>  	help
>  	  Say Y here to support the AZ6027 device
> +
> +config DVB_USB_LME2510
> +	tristate "LME DM04 (LME 2510 + TDQY-P001F) DVB-S USB2.0 support"
> +	depends on DVB_USB

It needs to depend also on INPUT/IR_CORE

> +	select DVB_TDA10086 if !DVB_FE_CUSTOMISE
> +	select DVB_TDA826X if !DVB_FE_CUSTOMISE
> +	help
> +	  Say Y here to support the LME DM04 DVB-S USB2.0 .
> +
> +
> diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/Makefile
> --- a/linux/drivers/media/dvb/dvb-usb/Makefile	Thu May 27 02:02:09 2010 -0300
> +++ b/linux/drivers/media/dvb/dvb-usb/Makefile	Fri Jul 16 14:30:02 2010 +0100
> @@ -88,6 +88,9 @@
>  dvb-usb-az6027-objs = az6027.o
>  obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
> 
> +dvb-usb-lmedm04-objs = lmedm04.o
> +obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
> +
>  EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
>  # due to tuner-xc3028
>  EXTRA_CFLAGS += -Idrivers/media/common/tuners
> diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/lmedm04.c
> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
> +++ b/linux/drivers/media/dvb/dvb-usb/lmedm04.c	Fri Jul 16 14:30:02 2010 +0100
> @@ -0,0 +1,910 @@
> +/* DVB USB compliant linux driver for
> + *
> + * DM040832731 DVB-S USB BOX (LME 2510 + TDQY-P001F)
> + *
> + * MV001F LG TDQY - P001F =(TDA8263 + TDA10086H)
> + *
> + * I2C addresses:
> + * 0x0e - TDA10086   - Demodulator
> + * 0x60 - TDA8263    - Tuner
> + *
> + * ***Please Note***
> + *		There are other variants of the DM04
> + *		***NOT SUPPORTED***
> + *		MVB0001F (LME2510C+LGTDQT-P001F)
> + *		MV0194 (LME2510+SHARP0194)
> + *		MVB0194 (LME2510C+SHARP0194)
> + *		MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
> + *
> + * The VID of 3344 and PID of 1122 has not been set until it is known not
> + * to be generic.
> + *
> + *
> + * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
> + * LME2510   (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 as published by the Free
> + * Software Foundation, version 2.
> + *
> + *
> + * see Documentation/dvb/README.dvb-usb for more information
> + *
> + * Known Issue :
> + * 	Non Intel USB chipsets fail to maintain High Speed on Boot or Hot Plug
> + *
> +  */
> +#define DVB_USB_LOG_PREFIX "LME2510"
> +#include <linux/usb.h>
> +#include <linux/usb/input.h>
> +#include "dvb-usb.h"
> +#include "lmedm04.h"
> +#include "tda826x.h"
> +#include "tda10086.h"
> +
> +/* debug */
> +static int dvb_usb_lme2510_debug;
> +#define l_dprintk(var, level, args...) \
> +	do { if ((var >= level)) info(args);  } while (0)
> +#define deb_info(level, args...) l_dprintk(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));
> +
> +
> +module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
> +MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."
> +			DVB_USB_DEBUG_STATUS);
> +
> +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
> +
> +
> +struct lme2510_state {
> +	u8 id;
> +	u8 signal_lock;
> +	u8 signal_level;
> +	u8 signal_sn;
> +	u8 time_key;
> +	u8 i2c_talk_onoff;
> +	u16 pid_table[64];
> +	u8 pid_count;
> +	u8 pid_flag_enable;
> +	u8 filter_data[256];
> +	void *buffer;
> +	struct urb *lme_urb;
> +
> +};
> +
> +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, 500);
> +	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, 500);
> +	return ret;
> +}
> +
> +static int lme2510_usb_talk(struct dvb_usb_device *d,
> +		u8 *wbuf, int wlen, u8 *rbuf, int rlen)
> +{
> +	u8 s[wlen+4], r[rlen+4];

This won't work fine. You should not use a buffer at stack to communicate with
USB, as those memory areas may not be able do handle DMA transfers. Instead, you
need to allocate a buffer for such transfers.

Also, the stack area on kernel is very small. you should not allocate a dynamic area
there, as this might cause buffer overflows, if you don't carefully check all clients
of this function.

> +	int ret = 0;
> +	memset(s, 0, wlen);
> +	memset(r, 0, rlen);

No need, as you're copying data with memcpy bellow.

> +	memcpy(&s[0], wbuf, wlen);
> +
> +	ret = mutex_lock_interruptible(&d->usb_mutex);
> +
> +	if (ret < 0)
> +		return -EAGAIN;
> +
> +	ret += usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
> +	msleep(5);
> +	ret += lme2510_bulk_write(d->udev, s, wlen , 0x1);
> +
> +	msleep(5);
> +	ret += usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x1));
> +
> +	msleep(5);
> +	ret += lme2510_bulk_read(d->udev, r, rlen , 0x1);
> +
> +	if (rlen > 0)
> +		memcpy(rbuf, &r[0], rlen);
> +
> +	mutex_unlock(&d->usb_mutex);
> +
> +	return (ret < 0) ? -EAGAIN : 0;

returing -EAGAIN is not good, as one of the reasons for this error may be due to device removal.

> +}
> +
> +static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
> +{
> +	struct dvb_usb_device *d = adap->dev;
> +	u32 event = 0;
> +
> +		switch (keypress) {
> +		KEYCASE(LME_R_1, KEY_1);
> +		break;
> +		KEYCASE(LME_R_2, KEY_2);
> +		break;
> +		KEYCASE(LME_R_3, KEY_3);
> +		break;
> +		KEYCASE(LME_R_4, KEY_4);
> +		break;
> +		KEYCASE(LME_R_5, KEY_5);
> +		break;
> +		KEYCASE(LME_R_6, KEY_6);
> +		break;
> +		KEYCASE(LME_R_7, KEY_7);
> +		break;
> +		KEYCASE(LME_R_8, KEY_8);
> +		break;
> +		KEYCASE(LME_R_9, KEY_9);
> +		break;
> +		KEYCASE(LME_R_0, KEY_0);
> +		break;
> +		KEYCASE(LME_R_POWER, KEY_POWER);
> +		break;
> +		KEYCASE(LME_R_SUB, KEY_SUBTITLE);
> +		break;
> +		KEYCASE(LME_R_CAPTURE, KEY_PAUSE);
> +		break;
> +		KEYCASE(LME_R_REPEAT, KEY_MEDIA_REPEAT);
> +		break;
> +		KEYCASE(LME_R_PAUSE, KEY_PAUSE);
> +		break;
> +		KEYCASE(LME_R_VOL_D, KEY_VOLUMEDOWN);
> +		break;
> +		KEYCASE(LME_R_VOL_U, KEY_VOLUMEUP);
> +		break;
> +		KEYCASE(LME_R_CH_D, KEY_CHANNELDOWN);
> +		break;
> +		KEYCASE(LME_R_CH_U, KEY_CHANNELUP);
> +		break;
> +		KEYCASE(LME_R_PLAYBACK, KEY_PLAY);
> +		break;
> +		KEYCASE(LME_R_ZOOM, KEY_ZOOM);
> +		break;
> +		KEYCASE(LME_R_MUTE, KEY_MUTE);
> +		break;
> +		KEYCASE(LME_R_LIVETV, KEY_TV);
> +		break;
> +		KEYCASE(LME_R_RECORD, KEY_RECORD);
> +		break;
> +		KEYCASE(LME_R_EPG, KEY_EPG);
> +		break;
> +		KEYCASE(LME_R_STOP, KEY_STOPCD);
> +		break;
> +		default:
> +			event = 0;
> +		break;

This is ugly for several reasons:

1) it hides case reserved word;
2) the IR translation table cannot be customized;
3) we'll be moving all IR keytables to userspace.

The proper solution is to use the rc-core handler for IR. I'll be porting soon the DVB drivers
to use it, but you can find already some examples on some drivers under drivers/media/video (like
saa7134 and em28xx).

> +
> +
> +
> +	}
> +
> +		deb_info(1, "INT Key Pressed =%04x Event =%04x",
> +			 keypress, event);
> +	if (event > 0) {
> +		input_event(d->rc_input_dev, EV_KEY, event, 1);
> +
> +		input_event(d->rc_input_dev, EV_KEY, event, 0);
> +
> +		}
> +
> +    return 0;
> +}
> +
> +static int lme2510_enable_filter(struct dvb_usb_adapter *adap)
> +{
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 filter_init[] = LME_FILTER_INT;
> +	static u8 filter_on[] = LME_ST_ON_W;
> +	static u8 rbuf[1];
> +	static u8 *sbuf;
> +	int ret = 0, len = 5;
> +	info("PID Setting Filter");
> +
> +	sbuf = (u8 *) st->filter_data;
> +
> +
> +	ret += lme2510_usb_talk(adap->dev,  filter_init, len, rbuf, 1);
> +
> +	ret += lme2510_usb_talk(adap->dev, sbuf, 80 , rbuf, 1);
> +
> +	ret += lme2510_usb_talk(adap->dev, filter_on, len, rbuf, 1);

Please, don't use "magic numbers". Instead of using "1" for the rbuf size, use
sizeof(rbuf).

> +
> +	st->pid_count = 0;
> +	st->pid_flag_enable = 0;
> +
> +	return ret;
> +}
> +
> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
> +static void lme2510_int_response(struct urb *lme_urb, struct pt_regs *ptregs)
> +#else
> +static void lme2510_int_response(struct urb *lme_urb)
> +#endif
> +{
> +	struct dvb_usb_adapter *adap = lme_urb->context;
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 *ibuf, *rbuf;
> +	int i = 0, offset;
> +
> +		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 in", ibuf);
> +			lme2510_remote_keypress(adap,
> +				(u16)(ibuf[4]<<8)+ibuf[5]);
> +			break;
> +		case 0xbb:
> +			st->signal_lock = ibuf[2];
> +			st->signal_level = ibuf[4];
> +			st->signal_sn = ibuf[3];
> +			st->time_key = ibuf[7];
> +		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 lme2510_state *lme_int = adap->dev->priv;
> +	lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
> +
> +	if (lme_int->lme_urb == NULL)
> +			return -ENOMEM;
> +
> +	lme_int->buffer = usb_buffer_alloc(adap->dev->udev, 5000, GFP_ATOMIC,
> +					&lme_int->lme_urb->transfer_dma);
> +
> +	if (lme_int->buffer == NULL)
> +			return -ENOMEM;
> +
> +	usb_fill_int_urb(lme_int->lme_urb,
> +				adap->dev->udev,
> +				usb_rcvintpipe(adap->dev->udev, 0xa),
> +				lme_int->buffer,
> +				4096,
> +				lme2510_int_response,
> +				adap,
> +				11);
> +
> +	lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
> +
> +	usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
> +	info("INT Interupt Service Started");
> +
> +	return 0;
> +}
> +
> +static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
> +{
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 clear_pid_reg_3[] = LME_CLEAR_PID;
> +	static u8 rbuf[1];
> +	int ret = 0;
> +	deb_info(3, "PID ONOFF Filter talk =%04x onoff=%02x pid_flag%02x",
> +			st->i2c_talk_onoff, onoff, st->pid_flag_enable);
> +
> +	if (onoff == 0)
> +			return 0;
> +	else {

Don't need for an else block here.

> +		deb_info(1, "PID Clearing Filter");
> +		ret += lme2510_usb_talk(adap->dev,
> +			clear_pid_reg_3, 4, rbuf, 1);
> +		}
> +	return 0;
> +
> +}
> +
> +static int lme2510_pidbuild_table(struct lme2510_state *st)
> +{
> +	u8 buffer_complete[] = {0x00, 0x00, 0x01, 0x00, 0x02,
> +				0x00, 0x10, 0x00, 0x11, 0x00,
> +				0x12, 0x00, 0x13, 0x00, 0x14,
> +				0x00, 0x20, 0x9a};
> +	u16 pid_out;
> +	int j, i, b = 0, je, reg = 0;
> +	u8 temp_buff[256];
> +
> +	deb_info(1, "PID Building Table");
> +
> +	j = 3;
> +	temp_buff[0] = 0x03;
> +	i = 2;
> +	reg = 0;
> +	while (j < 8) {
> +		pid_out = st->pid_table[j++];
> +			if (pid_out == 0x0012)
> +				break;
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = (u8) pid_out & 0xff;
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = pid_out>>8;
> +		};
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = 0xfb;
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = 0x1f;
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = st->pid_table[3]&0xff;
> +		temp_buff[i++] =  reg++;
> +		temp_buff[i++] = st->pid_table[3]>>8;
> +		temp_buff[i++] =  reg++;
> +		temp_buff[i++] = st->pid_table[2]&0xff;
> +		temp_buff[i++] =  reg++;
> +		temp_buff[i++] = st->pid_table[2]>>8;
> +	j = i;
> +	je = i+16;
> +	while (j++ < je) {
> +		temp_buff[i++] =  reg++;
> +		temp_buff[i++] = buffer_complete[b++];
> +		};
> +		temp_buff[i] = 0x20;
> +		temp_buff[1] =  i ;
> +		temp_buff[++i] = 0x9a;
> +
> +		memcpy(st->filter_data, &temp_buff[0], 255);

Bad identation. Always use tabs for identation. A tab has 8 spaces. The identation should
look like:
	while (j++ < je) {
		temp_buff[i++] =  reg++;
		temp_buff[i++] = buffer_complete[b++];
	}

Also, don't use ; after }

Please check your patches with scripts/checkpatch.pl (found at the kernel tree).
There are Several CodingStyle troubles on your patch. You should also take a look
at 

> +
> +	deb_info(2, "PID T RAW WRITE DUMP-----");
> +	for (i = 0; i < 10; i++)
> +		debug_data_snipet(2, ">", &st->filter_data[i*8]);
> +
> +
> +	return 0;
> +}
> +
> +static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
> +	int onoff)
> +{
> +	struct lme2510_state *st = adap->dev->priv;
> +	int ret = 0, i;
> +
> +	deb_info(4, "PID F PID=%04x Inx=%04x onoff=%02x i2c_talk=%02x FC=%02x",
> +			pid, index, onoff,
> +			st->i2c_talk_onoff,  adap->feedcount);
> +
> +	if ((pid == 0)&(index == 0)&(onoff == 0))
> +		st->pid_count = 0;
> +
> +
> +	if (index < 30) {
> +		st->pid_table[st->pid_count] = pid;
> +
> +		deb_info(3, "PID T PID=%04x Inx=%04x onoff=%02x,i2c_talk=%02x",
> +			st->pid_table[st->pid_count],
> +			st->pid_count, onoff,
> +			st->i2c_talk_onoff);
> +
> +		if ((st->pid_table[st->pid_count] == 0x0012) &
> +						(st->pid_count > 3)) {
> +			deb_info(2, "PID Table Dump---------");
> +			for (i = 0; i < st->pid_count; i++)
> +				deb_info(2, "PID No %02x=(%04x)",
> +						i, st->pid_table[i]);
> +
> +
> +			if ((st->pid_count < 8) &
> +				(st->pid_table[3] != 0x0012)) {
> +				ret = lme2510_pidbuild_table(st);
> +				st->pid_flag_enable = 1;
> +				ret -= lme2510_enable_filter(adap);
> +			}
> +				else
> +			info("PID more than 4 - passing full stream");
> +		} else
> +		st->pid_count++;
> +	}
> +
> +
> +	return ret;
> +}
> +
> +static int lme2510_return_status(struct usb_device *dev)
> +{
> +	int i;
> +	u8 data[10] = {0};
> +	i =  usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
> +			0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
> +	/*i = usb_get_descriptor(dev, 0x03, 0x02, data, 0x06);*/
> +	info("Firmware Status: %x (%x)", i, data[2]);

Hmm... what happens if usb_control_msg returns an error?

> +	i = data[2];
> +	return i;
> +}
> +
> +
> +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) {
> +		if ((wbuf[0] == 0x84) & (wbuf[1] == 0x03) &
> +			(wbuf[2] == 0x1c) & (wbuf[3] == 0x0e))
> +			msleep(80); /*take your time when waiting for tune*/
> +
> +		if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
> +			return -EAGAIN;
> +
> +		ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
> +
> +		mutex_unlock(&d->i2c_mutex);
> +		}	else	{
> +		if ((wbuf[0] == 0x84) & (wbuf[1] == 0x03)
> +					& (wbuf[2] == 0x1c)) {
> +			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;
> +			default:
> +					break;
> +			}
> +		deb_info(4, "I2C From Interupt 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);
> +	static u8 obuf[64], ibuf[512];
> +	int i, read;
> +	u16 len;
> +
> +	if (num > 2)
> +		warn("more than 2 i2c messages"
> +			"at a time is not handled yet.	TODO.");
> +
> +	for (i = 0; i < num; i++) {
> +		read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
> +		obuf[0] = 0x04 | (read << 7);
> +		obuf[1] = (msg[i].addr < 0x40) ? LME_I2C_C_L : LME_I2C_C_H;
> +		obuf[2] = (msg[i].addr << 1);
> +		if (read) {
> +			memcpy(&obuf[3], msg[i].buf, msg[i].len);
> +			obuf[4] = msg[i].len;
> +			len = msg[i].len+4;
> +		} else {
> +			memcpy(&obuf[3], msg[i].buf, msg[i].len);
> +			len = 64;
> +		}
> +
> +
> +		if (lme2510_msg(d, obuf, len, ibuf, 512) < 0) {
> +			deb_info(1, "i2c transfer failed.");
> +			return -EAGAIN;
> +		}
> +
> +		if (read) {
> +			memcpy(msg[i+1].buf, &ibuf[1],
> +				(msg[i+1].len > 512) ? 512 : msg[i+1].len);
> +
> +			i++;
> +		}
> +	}
> +	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,
> +#ifdef NEED_ALGO_CONTROL
> +	.algo_control = dummy_algo_control,
> +#endif
> +};
> +
> +/* Callbacks for DVB USB */
> +static int lme2510_identify_state(struct usb_device *udev,
> +		struct dvb_usb_device_properties *props,
> +		struct dvb_usb_device_description **desc,
> +		int *cold)
> +{
> +	*cold = 0;
> +	return 0;
> +}
> +
> +static int lme2510_init(struct dvb_usb_device *d)
> +{
> +	static u8 command1[] = LME_ST_OFF_C;
> +	static u8 ibuf[512];
> +	int ret, len = 5, len_in = 512;
> +	msleep(500);
> +	ret = lme2510_usb_talk(d, command1, len, ibuf, len_in);
> +	return ret;
> +}
> +
> +static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
> +{
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 stream_off[] = LME_ST_OFF_C;
> +	static u8 clear_reg_3[] =  LME_CLEAR_PID;
> +	static u8 stream_on[] = LME_ST_ON_W;
> +	static u8 rbuf[1];
> +	int ret = 0, len = 5;
> +	deb_info(1, "STM  (%02x)", onoff);
> +
> +	if (onoff == 1)	{
> +		ret += lme2510_usb_talk(adap->dev,
> +				 stream_on,  len, rbuf, 1);
> +		st->i2c_talk_onoff = 0;
> +	} else {
> +		st->i2c_talk_onoff = 1;
> +		ret += lme2510_usb_talk(adap->dev,
> +					stream_off, len, rbuf, 1);
> +		deb_info(1, "STM Clearing PID Filter");
> +		ret += lme2510_usb_talk(adap->dev,
> +			 clear_reg_3, 4, rbuf, 1);
> +	}
> +
> +	return 0;
> +}
> +
> +static int lme2510_int_service(struct dvb_usb_adapter *adap)
> +{
> +	struct dvb_usb_device *d = adap->dev;
> +	struct input_dev *input_dev;
> +	int ret, i;
> +	u32 keys[] =  LME_KEYS_USED;
> +	info("STA Configuring Remote");
> +
> +	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
> +
> +	strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
> +
> +	input_dev = input_allocate_device();
> +	if (!input_dev)
> +		return -ENOMEM;
> +
> +	input_dev->evbit[0] = BIT_MASK(EV_KEY);
> +	input_dev->name = "LME2510 Remote Control";
> +	input_dev->phys = d->rc_phys;
> +	usb_to_input_id(d->udev, &input_dev->id);
> +
> +	for (i = 0; i < sizeof(keys)/4 ; ++i)
> +		set_bit(keys[i], input_dev->keybit);
> +
> +	deb_info(3, "STA Number of Keys %d", sizeof(keys)/4);
> +
> +	ret = input_register_device(input_dev);
> +	if (ret) {
> +		input_free_device(input_dev);
> +		return ret;
> +	}
> +
> +	d->rc_input_dev = input_dev;
> +	/* Start the Interupt */
> +	ret = lme2510_int_read(adap);
> +
> +	if (ret < 0)
> +		input_free_device(input_dev);
> +
> +	return (ret < 0) ? -ENODEV : 0;
> +}

Should use the IR register functions from ir-core.

> +
> +static struct tda10086_config tda10086_config = {
> +	.demod_address = 0x0e,
> +	.invert = 0,
> +	.diseqc_tone = 1,
> +	.xtal_freq = TDA10086_XTAL_16M,
> +};
> +
> +static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
> +					fe_sec_voltage_t voltage)
> +{
> +	struct dvb_usb_adapter *adap = fe->dvb->priv;
> +	static u8 voltage_low[]	= LME_VOLTAGE_L;
> +	static u8 voltage_high[] = LME_VOLTAGE_H;
> +	static u8 rbuf[1];
> +	int ret, len = 5;
> +
> +		switch (voltage) {
> +
> +		case SEC_VOLTAGE_18:
> +			ret = lme2510_usb_talk(adap->dev,
> +				voltage_high, len, rbuf, 1);
> +		break;
> +
> +		case SEC_VOLTAGE_OFF:
> +		case SEC_VOLTAGE_13:
> +		default:
> +		ret = lme2510_usb_talk(adap->dev,
> +				voltage_low, len, rbuf, 1);
> +		break;
> +
> +
> +	};
> +	return 0;
> +}
> +
> +static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
> +{
> +	int ret = 0;
> +	struct lme2510_state *st = adap->dev->priv;
> +	st->pid_flag_enable = 0;
> +	/* Interupt Start  */
> +	ret = lme2510_int_service(adap);
> +	if (ret < 0) {
> +		info("INT Unable to start Interupt Service");
> +		return -ENODEV;
> +	}
> +
> +	st->i2c_talk_onoff = 1;
> +
> +	ret = lme2510_init(adap->dev);
> +
> +	adap->fe = dvb_attach(tda10086_attach, &tda10086_config,
> +		&adap->dev->i2c_adap);
> +
> +	if (adap->fe != NULL) {
> +		memcpy(&adap->fe->ops.info.name,
> +				&"DM04_LG_TDQY-P001F DVB-S", 24);
> +		adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
> +	} else {
> +		info("This DM04 Device is not supported");
> +		return -ENODEV;
> +	}
> +
> +	return ret;
> +}
> +
> +static int dm04_lme2510_tuner_attach(struct dvb_usb_adapter *adap)
> +{
> +	if (dvb_attach(tda826x_attach, adap->fe, 0x60,
> +			&adap->dev->i2c_adap, 1) == NULL) {
> +		deb_info(1, "TDA8263 attach failed\n");
> +		return -ENODEV;
> +	}
> +
> +	return 0;
> +}
> +
> +static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
> +{
> +	struct lme2510_state *st = d->priv;
> +	st->i2c_talk_onoff = 1;
> +	return 0;
> +}
> +
> +static struct lme_firmware_data lme_firmware[] =   LME_FIRMWARE_D;
> +
> +static int lme2510_firmware(struct usb_device *dev, const struct firmware *fw)
> +{
> +	int ret = 0, j;
> +	u8 data[1000] = {0};
> +	u16 wlen = 253;
> +	info("FRM Starting Firmware Download");
> +
> +	for (j = 0; j < 17; ++j)	{
> +		wlen = (int)lme_firmware[j].length;
> +		memcpy(&data[0], &lme_firmware[j].bulk_data[0],
> +				(wlen < 256) ? wlen : 256);
> +		ret += lme2510_bulk_write(dev, data,  wlen, 1);
> +		ret += lme2510_bulk_read(dev, data, 512 , 1);
> +		ret += (data[0] == 0x88) ? 0 : -1;
> +	}
> +
> +	usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
> +			0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
> +
> +
> +	data[0] = 0x8a;
> +	msleep(2000);
> +	ret += lme2510_bulk_write(dev, data , 1, 1); /*Resetting*/
> +	ret += lme2510_bulk_read(dev, data, 512 , 1);
> +	msleep(400);
> +
> +	if (ret < 0)
> +		info("FRM Firmware Download Failed (%04x)" , ret);
> +	else
> +		info("FRM Firmware Download Completed - Resetting Device");
> +
> +
> +	return (ret < 0) ? -ENODEV : 0;
> +}
> +
> +/* DVB USB Driver stuff */
> +static struct dvb_usb_device_properties lme2510_properties;
> +
> +static int lme2510_probe(struct usb_interface *intf,
> +		const struct usb_device_id *id)
> +{
> +	struct usb_device *udev = interface_to_usbdev(intf);
> +	int ret = 0;
> +
> +	usb_reset_configuration(udev);
> +
> +	usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1);
> +
> +	if (udev->speed != USB_SPEED_HIGH) {
> +		ret = usb_reset_device(udev);
> +		info("DEV Failed to connect in HIGH SPEED mode");
> +		return -ENODEV;
> +	}
> +
> +
> +	if (0x44 == lme2510_return_status(udev)) {
> +		ret += lme2510_firmware(udev, NULL);
> +		return 0; /* reset on way */
> +	}
> +
> +
> +	if (0 == dvb_usb_device_init(intf, &lme2510_properties,
> +				     THIS_MODULE, NULL, adapter_nr)) {
> +		info("DEV registering device driver");
> +		return 0;
> +	}
> +
> +	info("DEV lme2510 Error");
> +	return -ENODEV;
> +
> +}
> +
> +static struct usb_device_id lme2510_table[] = {
> +	{ USB_DEVICE(0x3344, 0x1122) },  /* generic China models */
> +	{}		/* Terminating entry */
> +};
> +
> +MODULE_DEVICE_TABLE(usb, lme2510_table);
> +
> +static struct dvb_usb_device_properties lme2510_properties = {
> +	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
> +	.usb_ctrl = DEVICE_SPECIFIC,
> +	.size_of_priv = sizeof(struct lme2510_state),
> +	.num_adapters = 1,
> +	.adapter = {
> +		{
> +			.caps = DVB_USB_ADAP_HAS_PID_FILTER|
> +				DVB_USB_ADAP_NEED_PID_FILTERING|
> +				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
> +			.streaming_ctrl   = lme2510_streaming_ctrl,
> +			.pid_filter_count = 29,
> +			.pid_filter = lme2510_pid_filter,
> +			.pid_filter_ctrl  = lme2510_pid_filter_ctrl,
> +			.frontend_attach  = dm04_lme2510_frontend_attach,
> +			.tuner_attach     = dm04_lme2510_tuner_attach,
> +			/* parameter for the MPEG2-data transfer */
> +			.stream = {
> +				.type = USB_BULK,
> +				.count = 10,
> +				.endpoint = 0x06,
> +				.u = {
> +					.bulk = {
> +						.buffersize = 4096,
> +
> +					}
> +				}
> +			}
> +		}
> +	},
> +	.power_ctrl       = lme2510_powerup,
> +	.identify_state   = lme2510_identify_state,
> +	.i2c_algo         = &lme2510_i2c_algo,
> +	.generic_bulk_ctrl_endpoint = 0,
> +	.num_device_descs = 1,
> +	.devices = {
> +		{   "LME2510 + LG TDQY-P001F DVB-S USB2.0",
> +			{ &lme2510_table[0], NULL },
> +			},
> +
> +	}
> +};
> +
> +void lme2510_exit_int(struct dvb_usb_device *d)
> +{
> +	struct lme2510_state *st = d->priv;
> +		if (st->lme_urb != NULL) {
> +			usb_kill_urb(st->lme_urb);
> +			usb_buffer_free(d->udev, 5000, st->buffer,
> +					st->lme_urb->transfer_dma);
> +			info("Interupt Service Stopped");
> +		}
> +	return;
> +}
> +
> +void lme2510_exit(struct usb_interface *intf)
> +{
> +	struct dvb_usb_device *d = usb_get_intfdata(intf);
> +	if (d != NULL) {
> +		lme2510_exit_int(d);
> +		input_unregister_device(d->rc_input_dev);
> +		info("Remote Stopped");
> +		dvb_usb_device_exit(intf);
> +	}
> +
> +}
> +
> +static struct usb_driver lme2510_driver = {
> +	.name		= "LME_DVBS",
> +	.probe		= lme2510_probe,
> +	.disconnect 	= lme2510_exit,
> +	.id_table	= lme2510_table,
> +};
> +
> +/* module stuff */
> +static int __init lme2510_module_init(void)
> +{
> +	int result = usb_register(&lme2510_driver);
> +	if (result) {
> +		err("usb_register failed. Error number %d", result);
> +		return result;
> +	}
> +
> +	return 0;
> +}
> +
> +static void __exit lme2510_module_exit(void)
> +{
> +	/* deregister this driver from the USB subsystem */
> +	usb_deregister(&lme2510_driver);
> +}
> +
> +module_init(lme2510_module_init);
> +module_exit(lme2510_module_exit);
> +
> +MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
> +MODULE_DESCRIPTION("LME DVB-S USB2.0");
> +MODULE_VERSION("1.0");
> +MODULE_LICENSE("GPL");
> diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/lmedm04.h
> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
> +++ b/linux/drivers/media/dvb/dvb-usb/lmedm04.h	Fri Jul 16 14:30:02 2010 +0100
> @@ -0,0 +1,682 @@
> +/* DVB USB compliant linux driver for
> + *
> + * LME DM040832731 (LME 2510 + TDQY-P001F)
> + *
> + * MV001F LG TDQY - P001F =(TDA8263 + TDA10086H)
> + *
> + *
> + * 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_
> +
> +
> +/* Interupt */
> +
> +#define LME_REMOTE	0xaa
> +#define LME_STREAM	0xbb
> +#define LME_IDLE	0xcc
> +
> +
> +/* Remote */
> +
> +#define KEYCASE(key, id) \
> +do { case key: \
> +  event = id;\
> + } while (0)
> +
> +#define LME_R_1		0xa05f
> +#define LME_R_2		0xaf50
> +#define LME_R_3		0xa25d
> +#define LME_R_4		0xbe41
> +#define LME_R_5		0xf50a
> +#define LME_R_6		0xbd42
> +#define LME_R_7		0xb847
> +#define LME_R_8		0xb649
> +#define LME_R_9		0xfa05
> +#define LME_R_0		0xba45
> +#define LME_R_POWER	0xbc43
> +#define LME_R_SUB	0xb946
> +#define LME_R_CAPTURE	0xf906
> +#define LME_R_REPEAT	0xfc03
> +#define LME_R_PAUSE	0xfd02
> +#define LME_R_VOL_D	0xa35c
> +#define LME_R_VOL_U	0xa15e
> +#define LME_R_CH_D	0xe51a
> +#define LME_R_CH_U	0xf609
> +#define LME_R_PLAYBACK	0xe11e
> +#define LME_R_ZOOM	0xe41b
> +#define LME_R_MUTE	0xa659
> +#define LME_R_LIVETV	0xa55a
> +#define LME_R_RECORD	0xe718
> +#define LME_R_EPG	0xf807
> +#define LME_R_STOP	0xfe01
> +
> +#define	LME_KEYS_USED {	KEY_1, 			KEY_2, \
> +			KEY_3, 			KEY_4, \
> +			KEY_5, 			KEY_6, \
> +			KEY_7, 			KEY_8, \
> +			KEY_9, 			KEY_0, \
> +			KEY_POWER, 		KEY_PAUSE, \
> +			KEY_VOLUMEDOWN, 		KEY_VOLUMEUP, \
> +			KEY_CHANNELDOWN, 	KEY_CHANNELUP, \
> +			KEY_PLAY, 		KEY_MUTE, KEY_TV, \
> +			KEY_ZOOM, 		KEY_EPG, \
> +			KEY_SUBTITLE, 		KEY_RECORD, \
> +			KEY_MEDIA_REPEAT, 	KEY_STOPCD, \
> +			0x0000}
> +
> +
> +/* 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 XX XX XX
> + *  offset 1 = 00
> + *  offset 2 = default after warm start 52, otherwise greater than 40
> + *  offset 3 = default after warm start 80, =(power offset 3),  82,  88
> + *  offset 4 = 20,  before PID setting 5c, 1c, d0,  (tuning 8c)
> + *
> + *  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, 0x52, 0x80, 0x20}
> +#define LME_FILTER_INT	{0x06, 0x00, 0x92, 0x88, 0x5c}
> +#define LME_ST_OFF_C	{0x06, 0x00, 0x52, 0x80, 0xd0}
> +#define LME_CLEAR_PID   {0x03, 0x02, 0x20, 0xa0}
> +
> +/*
> +#define LME_ST_INIT	{0x06, 0x00, 0x72, 0xb3, 0x1c}
> +#define LME_ST_ON_C	{0x06, 0x00, 0x52, 0x80, 0x20}
> +#define LME_ST_ON	{0x06, 0x00, 0x40, 0x82, 0x50}
> +*/
> +
> +/* LME Power Control
> + *  07 XX XX XX XX
> + *  offset 1 = 01  Power? my device cannot be powered down
> + *  offset 2 = 00=Voltage low 01=Voltage high
> + *  offset 3 = unknown but usually AE, B1-B3
> + *  offset 4 = mosty C8 but sometimes C9
> + */
> +
> +#define LME_VOLTAGE_L	{0x07, 0x01, 0x00, 0xb3, 0xc9}
> +#define LME_VOLTAGE_H	{0x07, 0x01, 0x01, 0xb3, 0xc9}
> +
> +/* I2C */
> +#define LME_I2C_C_L	0x03
> +#define LME_I2C_C_H	0x0c
> +#define LME_I2C_WRITE	0x04
> +#define LME_I2C_READ	0x84
> +
> +/* Firmware */
> +#define FWF1	{\
> +		0x01, 0xf9, 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 	\
> +		0x00, 0x40, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 	\
> +		0x01, 0x02, 0x03, 0x01, 0x0a, 0x06, 0x00, 0x02, 	\
> +		0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x09, 0x02, 	\
> +		0x37, 0x00, 0x01, 0x01, 0x00, 0xc0, 0xfa, 0x09, 	\
> +		0x04, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 	\
> +		0x09, 0x04, 0x00, 0x01, 0x04, 0xff, 0x00, 0x00, 	\
> +		0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x00, 	\
> +		0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 	\
> +		0x05, 0x8a, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 	\
> +		0x0a, 0x02, 0x40, 0x00, 0x00, 0x09, 0x07, 0x53, 	\
> +		0x00, 0x01, 0x01, 0x00, 0xc0, 0xfa, 0x09, 0x04, 	\
> +		0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 	\
> +		0x04, 0x00, 0x01, 0x08, 0xff, 0x00, 0x00, 0x00, 	\
> +		0x07, 0x05, 0x81, 0x02, 0x00, 0x02, 0x00, 0x07, 	\
> +		0x05, 0x01, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 	\
> +		0x02, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x86, 	\
> +		0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x87, 0x02, 	\
> +		0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 	\
> +		0x00, 0x00, 0x07, 0x05, 0x8a, 0x03, 0x40, 0x00, 	\
> +		0x0b, 0x07, 0x05, 0x0a, 0x02, 0x40, 0x00, 0x00, 	\
> +		0x08, 0x03, 0x09, 0x04, 0x03, 0x04, 0x15, 0x16, 	\
> +		0x05, 0x03, 0x41, 0x42, 0x43, 0x06, 0x03, 0x44, 	\
> +		0x44, 0x44, 0x44, 0x07, 0x03, 0x48, 0x49, 0x50, 	\
> +		0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x75}
> +
> +#define FWF2	{\
> +		0x01, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 	\
> +		0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x03, 0x01, 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 	\
> +		0x00, 0x40, 0x01, 0x00, 0x09, 0x02, 0x53, 0x00, 	\
> +		0x01, 0x01, 0x00, 0xc0, 0xfa, 0x09, 0x04, 0x00, 	\
> +		0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x04, 	\
> +		0x00, 0x01, 0x08, 0xff, 0x00, 0x00, 0x00, 0x07, 	\
> +		0x05, 0x81, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 	\
> +		0x01, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x02, 	\
> +		0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x86, 0x02, 	\
> +		0x00, 0x02, 0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 	\
> +		0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 	\
> +		0x00, 0x07, 0x05, 0x8a, 0x03, 0x40, 0x00, 0x0b, 	\
> +		0x07, 0x05, 0x0a, 0x02, 0x40, 0x00, 0x00, 0x09, 	\
> +		0x07, 0x37, 0x00, 0x01, 0x01, 0x00, 0xc0, 0xfa, 	\
> +		0x09, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 	\
> +		0x00, 0x09, 0x04, 0x00, 0x01, 0x04, 0xff, 0x00, 	\
> +		0x00, 0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 	\
> +		0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 	\
> +		0x07, 0x05, 0x8a, 0x02, 0x40, 0x00, 0x00, 0x07, 	\
> +		0x05, 0x0a, 0x02, 0x40, 0x00, 0x00, 0x08, 0x03, 	\
> +		0x09, 0x04, 0x03, 0x04, 0x15, 0x16, 0x05, 0x03, 	\
> +		0x41, 0x42, 0x43, 0x06, 0x03, 0x47, 0x47, 0x47, 	\
> +		0x47, 0x07, 0x03, 0x48, 0x49, 0x50, 0x51, 0x52, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x7e}
> +
> +
> +#define FWF3	{0x81, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
> +
> +
> +#define FWP1	{\
> +		0x02, 0xf9, 0x02, 0x05, 0xc5, 0x30, 0x01, 0xfd, 	\
> +		0x8f, 0x99, 0xc2, 0x01, 0x22, 0x02, 0x09, 0x9f, 	\
> +		0x22, 0xff, 0xff, 0xff, 0xff, 0x02, 0x0a, 0x92, 	\
> +		0x90, 0xc0, 0x0b, 0xe0, 0x30, 0xe1, 0x02, 0xc3, 	\
> +		0x22, 0xd3, 0x22, 0xff, 0xff, 0x02, 0x0c, 0xdc, 	\
> +		0xc2, 0x05, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xf5, 	\
> +		0x09, 0x90, 0xc0, 0x84, 0xe0, 0xff, 0x74, 0x0f, 	\
> +		0x25, 0x09, 0xf8, 0xa6, 0x07, 0x05, 0x09, 0xe5, 	\
> +		0x09, 0xb4, 0x02, 0xed, 0xe5, 0x0f, 0x12, 0x07, 	\
> +		0x27, 0x00, 0x8b, 0x02, 0x00, 0xe0, 0x03, 0x01, 	\
> +		0x4e, 0x04, 0x01, 0xd1, 0x05, 0x02, 0x61, 0x06, 	\
> +		0x02, 0x76, 0x07, 0x02, 0xd8, 0x08, 0x03, 0x32, 	\
> +		0x09, 0x03, 0x5c, 0x0a, 0x00, 0xb9, 0x82, 0x01, 	\
> +		0x16, 0x83, 0x01, 0x92, 0x84, 0x02, 0x05, 0x85, 	\
> +		0x02, 0x87, 0x87, 0x00, 0x7e, 0xf1, 0x00, 0xb3, 	\
> +		0xf2, 0x02, 0x41, 0xf5, 0x00, 0x00, 0x03, 0x79, 	\
> +		0x90, 0xc0, 0x0b, 0x74, 0x02, 0xf0, 0x90, 0xc1, 	\
> +		0xa3, 0x74, 0x50, 0xf0, 0x22, 0x90, 0xc0, 0x84, 	\
> +		0xe0, 0xf5, 0x0b, 0xe0, 0xf5, 0x0c, 0x90, 0xc0, 	\
> +		0x36, 0x74, 0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x16, 0xf0, 0x74, 0x76, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x96, 0xf0, 0xad, 0x0c, 0xaf, 0x0b, 0x12, 	\
> +		0x0c, 0x21, 0x02, 0x02, 0x02, 0x12, 0x0c, 0xcc, 	\
> +		0x02, 0x02, 0x02, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 	\
> +		0xc3, 0xe5, 0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 	\
> +		0x00, 0x50, 0x14, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 	\
> +		0x0c, 0xff, 0x12, 0x00, 0x03, 0x05, 0x0e, 0xe5, 	\
> +		0x0e, 0x70, 0xe5, 0x05, 0x0d, 0x80, 0xe1, 0x02, 	\
> +		0x02, 0x02, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xc3, 	\
> +		0xe5, 0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 0x00, 	\
> +		0x50, 0x23, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 0x0b, 	\
> +		0xe0, 0xf5, 0x0c, 0xe4, 0x5a}
> +
> +
> +#define FWP2	{\
> +		0x02, 0xf9, 0x25, 0x0b, 0xf5, 0x82, 0xe4, 0x34, 	\
> +		0x90, 0xf5, 0x83, 0xe5, 0x0c, 0xf0, 0x74, 0x02, 	\
> +		0x25, 0x0e, 0xf5, 0x0e, 0xe4, 0x35, 0x0d, 0xf5, 	\
> +		0x0d, 0x80, 0xd2, 0x02, 0x02, 0x02, 0x90, 0xc0, 	\
> +		0x84, 0x74, 0x55, 0xf0, 0xe4, 0xf5, 0x0d, 0xf5, 	\
> +		0x0e, 0xc3, 0xe5, 0x0e, 0x95, 0x10, 0xe5, 0x0d, 	\
> +		0x94, 0x00, 0x50, 0x1f, 0x90, 0xc0, 0x84, 0xe0, 	\
> +		0xf5, 0x0b, 0xff, 0xe4, 0x2f, 0xf5, 0x82, 0xe4, 	\
> +		0x34, 0x90, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x84, 	\
> +		0xf0, 0x05, 0x0e, 0xe5, 0x0e, 0x70, 0xda, 0x05, 	\
> +		0x0d, 0x80, 0xd6, 0x02, 0x02, 0x56, 0x90, 0xc0, 	\
> +		0x84, 0xe0, 0xf5, 0x0a, 0xe0, 0xf5, 0x0b, 0xe5, 	\
> +		0x10, 0x24, 0xfe, 0xf5, 0x0e, 0xe4, 0x34, 0xff, 	\
> +		0xf5, 0x0d, 0xe4, 0xf5, 0x09, 0xc3, 0xe5, 0x09, 	\
> +		0x95, 0x0e, 0xe4, 0x95, 0x0d, 0x50, 0x10, 0x90, 	\
> +		0xc0, 0x84, 0xe0, 0xff, 0x74, 0x2a, 0x25, 0x09, 	\
> +		0xf8, 0xa6, 0x07, 0x05, 0x09, 0x80, 0xe6, 0x7b, 	\
> +		0x00, 0x7a, 0x00, 0x79, 0x2a, 0x85, 0x0e, 0x16, 	\
> +		0xad, 0x0b, 0xaf, 0x0a, 0x12, 0x08, 0xec, 0x02, 	\
> +		0x02, 0xd1, 0x90, 0xc0, 0x84, 0x74, 0x55, 0xf0, 	\
> +		0xe0, 0xf5, 0x0a, 0xe0, 0xf5, 0x0b, 0xe0, 0x75, 	\
> +		0x0d, 0x00, 0xf5, 0x0e, 0x7b, 0x00, 0x7a, 0x00, 	\
> +		0x79, 0x22, 0xf5, 0x16, 0xad, 0x0b, 0xaf, 0x0a, 	\
> +		0x12, 0x06, 0x51, 0xe4, 0xf5, 0x09, 0xc3, 0xe5, 	\
> +		0x09, 0x95, 0x0e, 0xe4, 0x95, 0x0d, 0x50, 0x0e, 	\
> +		0x74, 0x22, 0x25, 0x09, 0xf8, 0xe6, 0x90, 0xc0, 	\
> +		0x84, 0xf0, 0x05, 0x09, 0x80, 0xe8, 0x02, 0x02, 	\
> +		0x56, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xc3, 0xe5, 	\
> +		0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 0x00, 0x50, 	\
> +		0x21, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 0x0a, 0xe0, 	\
> +		0xf5, 0x0b, 0xe0, 0xf5, 0x2a, 0xfb, 0xad, 0x0b, 	\
> +		0xaf, 0x0a, 0x12, 0x0a, 0x7f}
> +
> +#define FWP3	{\
> +		0x02, 0xf9, 0x4a, 0x74, 0x03, 0x25, 0x0e, 0xf5, 	\
> +		0x0e, 0xe4, 0x35, 0x0d, 0xf5, 0x0d, 0x80, 0xd4, 	\
> +		0x02, 0x02, 0xd1, 0x90, 0xc0, 0x84, 0x74, 0x55, 	\
> +		0xf0, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xc3, 0xe5, 	\
> +		0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 0x00, 0x50, 	\
> +		0x24, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 0x0a, 0xe0, 	\
> +		0xf5, 0x0b, 0xfd, 0xaf, 0x0a, 0x12, 0x08, 0x92, 	\
> +		0x8f, 0x22, 0x90, 0xc0, 0x84, 0xe5, 0x22, 0xf0, 	\
> +		0x74, 0x02, 0x25, 0x0e, 0xf5, 0x0e, 0xe4, 0x35, 	\
> +		0x0d, 0xf5, 0x0d, 0x80, 0xd1, 0x80, 0x15, 0x90, 	\
> +		0xc0, 0x84, 0x74, 0x55, 0xf0, 0xe0, 0xf5, 0x0a, 	\
> +		0xff, 0x12, 0x0b, 0x7e, 0x8f, 0x22, 0x90, 0xc0, 	\
> +		0x84, 0xe5, 0x22, 0xf0, 0x90, 0xc0, 0x0b, 0x74, 	\
> +		0x02, 0xf0, 0x90, 0xc0, 0x0f, 0xf0, 0x22, 0xe4, 	\
> +		0xf5, 0x3b, 0xf5, 0x3c, 0x7b, 0xff, 0x7a, 0x0b, 	\
> +		0x79, 0x0f, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x0b, 	\
> +		0xd9, 0x02, 0x03, 0x47, 0x90, 0xc0, 0x84, 0xe0, 	\
> +		0xf5, 0x0c, 0x70, 0x04, 0xc2, 0x83, 0x80, 0x02, 	\
> +		0xd2, 0x83, 0x02, 0x02, 0xd1, 0x90, 0xc0, 0x84, 	\
> +		0xe0, 0xf5, 0x09, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 	\
> +		0xc3, 0xe5, 0x0e, 0x95, 0x09, 0xe5, 0x0d, 0x94, 	\
> +		0x00, 0x50, 0x34, 0xc2, 0xb7, 0xd2, 0xb6, 0xe4, 	\
> +		0xf5, 0x0b, 0x7f, 0xc8, 0x12, 0x05, 0x9e, 0x05, 	\
> +		0x0b, 0xe5, 0x0b, 0xc3, 0x94, 0xc8, 0x40, 0xf2, 	\
> +		0xd2, 0xb7, 0xc2, 0xb6, 0xe4, 0xf5, 0x0b, 0x7f, 	\
> +		0xc8, 0x12, 0x05, 0x9e, 0x05, 0x0b, 0xe5, 0x0b, 	\
> +		0xc3, 0x94, 0xc8, 0x40, 0xf2, 0x05, 0x0e, 0xe5, 	\
> +		0x0e, 0x70, 0xc5, 0x05, 0x0d, 0x80, 0xc1, 0x90, 	\
> +		0xc0, 0x0b, 0x74, 0x02, 0x80, 0x52, 0x90, 0xc0, 	\
> +		0x36, 0x74, 0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x16, 0xf0, 0x74, 0x76, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x96, 0xf0, 0x90, 0xbb}
> +
> +
> +#define FWP4	{\
> +		0x02, 0xf9, 0xc0, 0x98, 0x74, 0x66, 0xf0, 0x90, 	\
> +		0xc0, 0x84, 0xe0, 0xf5, 0x0c, 0xe4, 0xf5, 0x0d, 	\
> +		0xf5, 0x0e, 0xc3, 0xe5, 0x0e, 0x95, 0x0c, 0xe5, 	\
> +		0x0d, 0x94, 0x00, 0x50, 0x14, 0x90, 0xc0, 0x88, 	\
> +		0xe0, 0xf5, 0x0a, 0x90, 0xc0, 0x98, 0xf0, 0x05, 	\
> +		0x0e, 0xe5, 0x0e, 0x70, 0xe5, 0x05, 0x0d, 0x80, 	\
> +		0xe1, 0x90, 0xc0, 0x0b, 0x74, 0x02, 0xf0, 0x90, 	\
> +		0xc0, 0x13, 0xf0, 0x90, 0xc0, 0x37, 0xf0, 0x90, 	\
> +		0xc0, 0x84, 0x74, 0x88, 0x80, 0x52, 0x90, 0xc0, 	\
> +		0x56, 0x74, 0x8c, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x1a, 0xf0, 0x74, 0x7a, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x9a, 0xf0, 0x90, 0xc0, 0x0b, 0x74, 0x02, 	\
> +		0xf0, 0x90, 0xc0, 0x84, 0x74, 0x88, 0xf0, 0x90, 	\
> +		0xc0, 0x0f, 0x74, 0x02, 0xf0, 0xd2, 0x04, 0x22, 	\
> +		0x90, 0xc0, 0x0b, 0x74, 0x02, 0xf0, 0x90, 0xc0, 	\
> +		0x84, 0x74, 0x88, 0xf0, 0x90, 0xc0, 0x0f, 0x74, 	\
> +		0x02, 0xf0, 0x7f, 0xc8, 0x12, 0x05, 0xb9, 0x90, 	\
> +		0xff, 0xff, 0xe4, 0xf0, 0x22, 0x90, 0xc0, 0x0b, 	\
> +		0x74, 0x02, 0xf0, 0x90, 0xc0, 0x84, 0x74, 0x77, 	\
> +		0xf0, 0x90, 0xc0, 0x0f, 0x74, 0x02, 0xf0, 0x22, 	\
> +		0xe4, 0xff, 0xfe, 0xf5, 0x0b, 0x20, 0xb2, 0x07, 	\
> +		0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x80, 0xf6, 0xc3, 	\
> +		0xef, 0x94, 0x28, 0xee, 0x94, 0x23, 0x50, 0x03, 	\
> +		0x02, 0x04, 0x76, 0xd3, 0xef, 0x94, 0xc8, 0xee, 	\
> +		0x94, 0x32, 0x40, 0x03, 0x02, 0x04, 0x76, 0xe4, 	\
> +		0xfe, 0xff, 0x30, 0xb2, 0x07, 0x0f, 0xbf, 0x00, 	\
> +		0x01, 0x0e, 0x80, 0xf6, 0xc3, 0xef, 0x94, 0x94, 	\
> +		0xee, 0x94, 0x11, 0x50, 0x03, 0x02, 0x04, 0x76, 	\
> +		0xd3, 0xef, 0x94, 0x4c, 0xee, 0x94, 0x1d, 0x40, 	\
> +		0x03, 0x02, 0x04, 0x76, 0xe4, 0xfe, 0x7f, 0x04, 	\
> +		0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x03, 0x02, 0x04, 	\
> +		0x76, 0xe4, 0xf5, 0x0a, 0x39}
> +
> +#define FWP5	{\
> +		0x02, 0xf9, 0xe4, 0xf5, 0x09, 0x05, 0x0b, 0x30, 	\
> +		0xb2, 0xfd, 0x74, 0x48, 0x25, 0x0a, 0xf8, 0xc0, 	\
> +		0x00, 0xe6, 0xc3, 0x13, 0xd0, 0x00, 0xf6, 0x7f, 	\
> +		0x06, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x05, 0x7f, 	\
> +		0x04, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x05, 0x7f, 	\
> +		0x02, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x05, 0x7f, 	\
> +		0x06, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x07, 0x7f, 	\
> +		0x08, 0x12, 0x0c, 0xbc, 0x80, 0x09, 0x74, 0x48, 	\
> +		0x25, 0x0a, 0xf8, 0xe6, 0x44, 0x80, 0xf6, 0x20, 	\
> +		0xb2, 0xfd, 0x05, 0x09, 0xe5, 0x09, 0xc3, 0x94, 	\
> +		0x08, 0x40, 0xb2, 0x05, 0x0a, 0xe5, 0x0a, 0xc3, 	\
> +		0x94, 0x04, 0x40, 0xa6, 0xe5, 0x0b, 0x64, 0x20, 	\
> +		0x70, 0x2e, 0xf5, 0x0b, 0xe5, 0x4a, 0x25, 0x4b, 	\
> +		0xff, 0xe4, 0x33, 0xfe, 0xef, 0xf4, 0x4e, 0x70, 	\
> +		0x1f, 0xd2, 0x03, 0x75, 0x4c, 0xaa, 0x75, 0x47, 	\
> +		0x04, 0xf5, 0x0a, 0x74, 0x48, 0x25, 0x0a, 0xf8, 	\
> +		0xe6, 0xff, 0x74, 0x3f, 0x25, 0x0a, 0xf8, 0xa6, 	\
> +		0x07, 0x05, 0x0a, 0xe5, 0x0a, 0xb4, 0x04, 0xeb, 	\
> +		0x22, 0x90, 0xc1, 0xa3, 0x74, 0x10, 0xf0, 0x90, 	\
> +		0xc0, 0x0e, 0x74, 0x88, 0xf0, 0x90, 0xc1, 0xa2, 	\
> +		0x74, 0x11, 0xf0, 0x74, 0x71, 0xf0, 0x90, 0xc1, 	\
> +		0xa8, 0x74, 0x31, 0xf0, 0x90, 0xc0, 0x36, 0x74, 	\
> +		0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x16, 0xf0, 	\
> +		0x74, 0x76, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 0x36, 	\
> +		0xf0, 0x90, 0xc0, 0x0a, 0x74, 0x88, 0xf0, 0x90, 	\
> +		0xc1, 0xa2, 0x74, 0x01, 0xf0, 0x74, 0x61, 0xf0, 	\
> +		0x90, 0xc1, 0xa8, 0x74, 0x21, 0xf0, 0x90, 0xc0, 	\
> +		0x12, 0x74, 0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x02, 0xf0, 0x74, 0x62, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x22, 0xf0, 0x90, 0xc0, 0x3e, 0x74, 0x8b, 	\
> +		0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x17, 0xf0, 0x74, 	\
> +		0x77, 0xf0, 0x90, 0xc1, 0x1b}
> +
> +#define FWP6	{\
> +		0x02, 0xf9, 0xa8, 0x74, 0x37, 0xf0, 0x90, 0xc0, 	\
> +		0x56, 0x74, 0x8c, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x1a, 0xf0, 0x74, 0x7a, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x3a, 0xf0, 0x90, 0xc0, 0x1a, 0x74, 0x8b, 	\
> +		0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x03, 0xf0, 0x74, 	\
> +		0x63, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 0x23, 0xf0, 	\
> +		0x90, 0xc0, 0x52, 0x74, 0x88, 0xf0, 0x90, 0xc1, 	\
> +		0xa2, 0x74, 0x0a, 0xf0, 0x74, 0x6a, 0xf0, 0x90, 	\
> +		0xc1, 0xa8, 0x74, 0x2a, 0xf0, 0x22, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0xe4, 0xfe, 0xee, 0xc3, 0x9f, 0x50, 0x04, 	\
> +		0x00, 0x0e, 0x80, 0xf7, 0x22, 0x78, 0x7f, 0xe4, 	\
> +		0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x54, 0x02, 0x06, 	\
> +		0x0c, 0x02, 0x07, 0x53, 0xe4, 0x93, 0xa3, 0xf8, 	\
> +		0xe4, 0x93, 0xa3, 0x40, 0xe8}
> +
> +#define FWP7	{\
> +		0x02, 0xf9, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 	\
> +		0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 	\
> +		0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 	\
> +		0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 	\
> +		0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 	\
> +		0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 	\
> +		0x40, 0x80, 0x90, 0x0c, 0x3f, 0xe4, 0x7e, 0x01, 	\
> +		0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 	\
> +		0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 	\
> +		0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 	\
> +		0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 	\
> +		0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 	\
> +		0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 	\
> +		0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 	\
> +		0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0x8d, 	\
> +		0x12, 0x8b, 0x13, 0x8a, 0x14, 0x89, 0x15, 0xef, 	\
> +		0x54, 0xfe, 0xf5, 0x18, 0x12, 0x0c, 0x5c, 0xaf, 	\
> +		0x18, 0x12, 0x09, 0xf5, 0x20, 0x02, 0x02, 0x80, 	\
> +		0x69, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0xaf, 0x12, 	\
> +		0x12, 0x09, 0xf5, 0x7f, 0x14, 0x12, 0x05, 0xb9, 	\
> +		0x20, 0x02, 0x02, 0x80, 0x55, 0x12, 0x0c, 0x5c, 	\
> +		0xe5, 0x18, 0x04, 0xff, 0x12, 0x09, 0xf5, 0x20, 	\
> +		0x02, 0x02, 0x80, 0x46, 0xe4, 0xf5, 0x17, 0xe5, 	\
> +		0x16, 0x14, 0xff, 0xe5, 0x17, 0xc3, 0x9f, 0x50, 	\
> +		0x1c, 0x12, 0x0a, 0xd2, 0xab, 0x13, 0xaa, 0x14, 	\
> +		0xa9, 0x15, 0x85, 0x17, 0x82, 0x75, 0x83, 0x00, 	\
> +		0xef, 0x12, 0x07, 0x05, 0xc2, 0x06, 0x12, 0x0c, 	\
> +		0x78, 0x05, 0x17, 0x80, 0xda, 0x12, 0x0a, 0xd2, 	\
> +		0xab, 0x13, 0xaa, 0x14, 0xa9, 0x15, 0x85, 0x17, 	\
> +		0x82, 0x75, 0x83, 0x00, 0xef, 0x12, 0x07, 0x05, 	\
> +		0xd2, 0x06, 0x12, 0x0c, 0x78, 0x7f, 0x14, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x0c, 0x29}
> +
> +#define FWP8	{\
> +		0x02, 0xf9, 0x94, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 	\
> +		0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 	\
> +		0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 	\
> +		0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 	\
> +		0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 	\
> +		0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 	\
> +		0x22, 0xf8, 0xbb, 0x01, 0x0d, 0xe5, 0x82, 0x29, 	\
> +		0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe8, 	\
> +		0xf0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xc8, 	\
> +		0xf6, 0x22, 0xbb, 0xfe, 0x05, 0xe9, 0x25, 0x82, 	\
> +		0xc8, 0xf2, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 	\
> +		0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 	\
> +		0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 	\
> +		0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 	\
> +		0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 	\
> +		0xdf, 0x8a, 0x83, 0x89, 0x82, 0xe4, 0x73, 0x12, 	\
> +		0x0c, 0x01, 0x12, 0x0c, 0xa9, 0x7b, 0xff, 0x7a, 	\
> +		0x0b, 0x79, 0xb0, 0x7d, 0x28, 0x7c, 0x00, 0x12, 	\
> +		0x0b, 0x49, 0x12, 0x00, 0x16, 0x50, 0x11, 0xc2, 	\
> +		0x85, 0xc2, 0x00, 0x90, 0xc1, 0xa8, 0x74, 0x91, 	\
> +		0xf0, 0x12, 0x00, 0x26, 0xd2, 0x85, 0x80, 0xea, 	\
> +		0x20, 0xb2, 0x0c, 0xc2, 0xaa, 0x12, 0x03, 0x8c, 	\
> +		0xd2, 0xaa, 0x12, 0x08, 0x2c, 0x80, 0xdb, 0xe5, 	\
> +		0x3e, 0x24, 0x38, 0xff, 0xe5, 0x3d, 0x34, 0xff, 	\
> +		0xfe, 0xef, 0xb5, 0x3c, 0xcd, 0xee, 0xb5, 0x3b, 	\
> +		0xc9, 0x75, 0x2a, 0x1c, 0x75, 0x2b, 0x0e, 0x12, 	\
> +		0x08, 0x8e, 0x8f, 0x22, 0xe5, 0x22, 0x30, 0xe4, 	\
> +		0x04, 0xc2, 0x85, 0x80, 0x02, 0xd2, 0x85, 0x75, 	\
> +		0x2b, 0x43, 0x12, 0x08, 0x8e, 0x8f, 0x23, 0x75, 	\
> +		0x2b, 0x1c, 0x12, 0x08, 0x8e, 0x8f, 0x24, 0x80, 	\
> +		0xa1, 0x90, 0x90, 0x00, 0x74, 0x01, 0xf0, 0xe4, 	\
> +		0xa3, 0xf0, 0xa3, 0xf0, 0xdc}
> +
> +
> +#define FWP9	{\
> +		0x02, 0xf9, 0xa3, 0xf0, 0xa3, 0x74, 0x03, 0xf0, 	\
> +		0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 	\
> +		0x74, 0x05, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 	\
> +		0xa3, 0xf0, 0xa3, 0x74, 0x07, 0xf0, 0xe4, 0xa3, 	\
> +		0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x09, 	\
> +		0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 	\
> +		0xa3, 0x74, 0x0b, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 	\
> +		0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x0d, 0xf0, 0xe4, 	\
> +		0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 	\
> +		0x0f, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 	\
> +		0xf0, 0xa3, 0x74, 0xb5, 0xf0, 0xa3, 0x74, 0x06, 	\
> +		0xf0, 0xa3, 0x74, 0xbc, 0xf0, 0x22, 0xe5, 0x47, 	\
> +		0x60, 0x5d, 0xc2, 0xaa, 0x75, 0xa0, 0x01, 0x85, 	\
> +		0x4c, 0x33, 0x85, 0x47, 0x34, 0xe4, 0xff, 0xef, 	\
> +		0xc3, 0x95, 0x47, 0x50, 0x0f, 0x74, 0x3f, 0x2f, 	\
> +		0xf8, 0xe6, 0xfe, 0x74, 0x35, 0x2f, 0xf8, 0xa6, 	\
> +		0x06, 0x0f, 0x80, 0xeb, 0x75, 0x21, 0x08, 0xe4, 	\
> +		0xf5, 0x47, 0x20, 0x00, 0x2d, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x9a, 0xf0, 0x90, 0xc0, 0xa8, 0xe5, 0x33, 	\
> +		0xf0, 0xe5, 0x34, 0xf0, 0xe5, 0x35, 0xf0, 0xe5, 	\
> +		0x36, 0xf0, 0xe5, 0x37, 0xf0, 0xe5, 0x38, 0xf0, 	\
> +		0xe5, 0x39, 0xf0, 0xe5, 0x3a, 0xf0, 0x90, 0xc0, 	\
> +		0x57, 0x74, 0x02, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 	\
> +		0x3a, 0xf0, 0xd2, 0xaa, 0x75, 0xa0, 0x02, 0x22, 	\
> +		0xad, 0x2b, 0xaf, 0x2a, 0x8d, 0x11, 0xef, 0x54, 	\
> +		0xfe, 0xf5, 0x13, 0x12, 0x0c, 0x5c, 0x7f, 0x14, 	\
> +		0x12, 0x05, 0xb9, 0xaf, 0x13, 0x12, 0x09, 0xf5, 	\
> +		0x20, 0x02, 0x02, 0x80, 0x21, 0x7f, 0x14, 0x12, 	\
> +		0x05, 0xb9, 0xaf, 0x11, 0x12, 0x09, 0xf5, 0x20, 	\
> +		0x02, 0x02, 0x80, 0x12, 0x7f, 0x14, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x0c, 0x5c, 0xe5, 0x13, 0x04, 0xff, 	\
> +		0x12, 0x09, 0xf5, 0x20, 0x9b}
> +
> +
> +#define FWP10	{\
> +		0x02, 0xf9, 0x02, 0x06, 0x12, 0x0c, 0x94, 0x7f, 	\
> +		0x00, 0x22, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x0a, 0xd2, 0x8f, 0x12, 0xd2, 0x06, 0x12, 0x0c, 	\
> +		0x78, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x0c, 	\
> +		0x94, 0xaf, 0x12, 0x22, 0x8d, 0x12, 0x8b, 0x13, 	\
> +		0x8a, 0x14, 0x89, 0x15, 0xef, 0x54, 0xfe, 0xf5, 	\
> +		0x18, 0x12, 0x0c, 0x5c, 0xaf, 0x18, 0x12, 0x09, 	\
> +		0xf5, 0x20, 0x02, 0x02, 0x80, 0x3f, 0x7f, 0x14, 	\
> +		0x12, 0x05, 0xb9, 0xaf, 0x12, 0x12, 0x09, 0xf5, 	\
> +		0x20, 0x02, 0x02, 0x80, 0x30, 0x7f, 0x14, 0x12, 	\
> +		0x05, 0xb9, 0xe4, 0xf5, 0x17, 0xe5, 0x17, 0xc3, 	\
> +		0x95, 0x16, 0x50, 0x17, 0xab, 0x13, 0xaa, 0x14, 	\
> +		0xa9, 0x15, 0x85, 0x17, 0x82, 0x75, 0x83, 0x00, 	\
> +		0x12, 0x06, 0xd8, 0xff, 0x12, 0x09, 0xf5, 0x05, 	\
> +		0x17, 0x80, 0xe2, 0x20, 0x02, 0x02, 0x80, 0x05, 	\
> +		0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x0c, 0x94, 	\
> +		0x22, 0x05, 0x3a, 0x30, 0x04, 0x50, 0xe5, 0x21, 	\
> +		0x90, 0xc1, 0xa8, 0x70, 0x1c, 0x74, 0x9a, 0xf0, 	\
> +		0x90, 0xc0, 0xa8, 0x74, 0xbb, 0xf0, 0x74, 0x03, 	\
> +		0xf0, 0xe5, 0x22, 0xf0, 0xe5, 0x23, 0xf0, 0xe5, 	\
> +		0x24, 0xf0, 0xe5, 0x25, 0xf0, 0xe5, 0x26, 0x80, 	\
> +		0x1a, 0x74, 0x9a, 0xf0, 0x90, 0xc0, 0xa8, 0xe5, 	\
> +		0x33, 0xf0, 0xe5, 0x34, 0xf0, 0xe5, 0x35, 0xf0, 	\
> +		0xe5, 0x36, 0xf0, 0xe5, 0x37, 0xf0, 0xe5, 0x38, 	\
> +		0xf0, 0xe5, 0x39, 0xf0, 0xe5, 0x3a, 0xf0, 0x90, 	\
> +		0xc0, 0x57, 0x74, 0x02, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x3a, 0xf0, 0xe4, 0xf5, 0x21, 0x22, 0xc0, 	\
> +		0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 	\
> +		0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x01, 	\
> +		0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 	\
> +		0xc0, 0x06, 0xc0, 0x07, 0xc2, 0x8d, 0x05, 0x4f, 	\
> +		0xe5, 0x4f, 0x70, 0x02, 0xf9}
> +
> +
> +#define FWP11	{\
> +		0x02, 0xf9, 0x05, 0x4e, 0xc3, 0x95, 0x54, 0xe5, 	\
> +		0x4e, 0x95, 0x53, 0x40, 0x0b, 0xc2, 0x8c, 0xc2, 	\
> +		0xa9, 0xaa, 0x51, 0xa9, 0x52, 0x12, 0x07, 0x4d, 	\
> +		0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 	\
> +		0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 	\
> +		0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 	\
> +		0xd0, 0xe0, 0x32, 0x8f, 0x19, 0xe4, 0xf5, 0x1a, 	\
> +		0xaf, 0x1a, 0xe5, 0x19, 0xa8, 0x07, 0x08, 0x80, 	\
> +		0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x30, 0xe7, 0x04, 	\
> +		0xd2, 0x80, 0x80, 0x02, 0xc2, 0x80, 0x7f, 0x08, 	\
> +		0x12, 0x05, 0xb9, 0xd2, 0x81, 0x7f, 0x0a, 0x12, 	\
> +		0x05, 0xb9, 0xc2, 0x81, 0x05, 0x1a, 0xe5, 0x1a, 	\
> +		0xc3, 0x94, 0x08, 0x40, 0xd3, 0x7f, 0x02, 0x12, 	\
> +		0x05, 0xb9, 0xd2, 0x80, 0x7f, 0x0a, 0x12, 0x05, 	\
> +		0xb9, 0xd2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 	\
> +		0x30, 0x80, 0x04, 0xc2, 0x02, 0x80, 0x02, 0xd2, 	\
> +		0x02, 0xc2, 0x81, 0x7f, 0x0a, 0x02, 0x05, 0xb9, 	\
> +		0x8d, 0x11, 0x8b, 0x12, 0xef, 0x54, 0xfe, 0xf5, 	\
> +		0x13, 0x12, 0x0c, 0x5c, 0x7f, 0x14, 0x12, 0x05, 	\
> +		0xb9, 0xaf, 0x13, 0x12, 0x09, 0xf5, 0x20, 0x02, 	\
> +		0x02, 0x80, 0x1c, 0x7f, 0x14, 0x12, 0x05, 0xb9, 	\
> +		0xaf, 0x11, 0x12, 0x09, 0xf5, 0x20, 0x02, 0x02, 	\
> +		0x80, 0x0d, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0xaf, 	\
> +		0x12, 0x12, 0x09, 0xf5, 0x20, 0x02, 0x03, 0x02, 	\
> +		0x0c, 0x94, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x0c, 0x94, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x22, 	\
> +		0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 	\
> +		0x75, 0xd0, 0x00, 0xc0, 0x06, 0xc0, 0x07, 0xc2, 	\
> +		0x8b, 0x05, 0x3c, 0xe5, 0x3c, 0x70, 0x02, 0x05, 	\
> +		0x3b, 0x30, 0x00, 0x17, 0xc3, 0x95, 0x3e, 0xe5, 	\
> +		0x3b, 0x95, 0x3d, 0x40, 0x0e, 0x75, 0x3b, 0x00, 	\
> +		0x75, 0x3c, 0x00, 0x7f, 0xbc}
> +
> +
> +#define FWP12	{\
> +		0x02, 0xf9, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x09, 	\
> +		0x49, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0xd0, 0xd0, 	\
> +		0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xe4, 0xf5, 	\
> +		0x19, 0xd2, 0x80, 0xf5, 0x1a, 0x7f, 0x01, 0x12, 	\
> +		0x05, 0xb9, 0xc2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 	\
> +		0xb9, 0xd2, 0x81, 0x7f, 0x08, 0x12, 0x05, 0xb9, 	\
> +		0xe5, 0x19, 0x25, 0xe0, 0xf5, 0x19, 0x30, 0x80, 	\
> +		0x02, 0x05, 0x19, 0x7f, 0x01, 0x12, 0x05, 0xb9, 	\
> +		0x05, 0x1a, 0xe5, 0x1a, 0xc3, 0x94, 0x08, 0x40, 	\
> +		0xd4, 0xc2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 	\
> +		0xaf, 0x19, 0x22, 0x85, 0x3b, 0x3d, 0x85, 0x3c, 	\
> +		0x3e, 0x90, 0xc0, 0xa8, 0x74, 0xcc, 0xf0, 0x74, 	\
> +		0x02, 0xf0, 0xe5, 0x3d, 0xf0, 0xe5, 0x3e, 0xf0, 	\
> +		0xe4, 0xf0, 0xf0, 0xf0, 0xf0, 0x90, 0xc0, 0x57, 	\
> +		0x74, 0x02, 0xf0, 0x90, 0xc0, 0x36, 0x74, 0x8b, 	\
> +		0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x16, 0xf0, 0x74, 	\
> +		0x76, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 0x36, 0xf0, 	\
> +		0xd2, 0x00, 0xc2, 0x85, 0x22, 0x8b, 0x09, 0x8a, 	\
> +		0x0a, 0x89, 0x0b, 0x8c, 0x0c, 0x8d, 0x0d, 0xe4, 	\
> +		0xfd, 0xfc, 0xc3, 0xed, 0x95, 0x0d, 0xe5, 0x0c, 	\
> +		0x64, 0x80, 0xf8, 0xec, 0x64, 0x80, 0x98, 0x50, 	\
> +		0x18, 0xab, 0x09, 0xaa, 0x0a, 0xa9, 0x0b, 0x8d, 	\
> +		0x82, 0x8c, 0x83, 0x12, 0x06, 0xd8, 0xff, 0x12, 	\
> +		0x00, 0x03, 0x0d, 0xbd, 0x00, 0x01, 0x0c, 0x80, 	\
> +		0xd9, 0x22, 0x8f, 0x11, 0x12, 0x0c, 0x5c, 0x7f, 	\
> +		0x14, 0x12, 0x05, 0xb9, 0xaf, 0x11, 0x12, 0x09, 	\
> +		0xf5, 0x20, 0x02, 0x06, 0x12, 0x0c, 0x94, 0x7f, 	\
> +		0x00, 0x22, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x0a, 0xd2, 0x8f, 0x12, 0xd2, 0x06, 0x12, 0x0c, 	\
> +		0x78, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x0c, 	\
> +		0x94, 0xaf, 0x12, 0x22, 0x54, 0x44, 0x20, 0x69, 	\
> +		0x6e, 0x69, 0x74, 0x20, 0x2d}
> +
> +
> +#define FWP13	{\
> +		0x02, 0xf9, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 	\
> +		0x3a, 0x65, 0x78, 0x63, 0x75, 0x74, 0x65, 0x20, 	\
> +		0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 	\
> +		0x69, 0x6e, 0x20, 0x70, 0x64, 0x72, 0x61, 0x6d, 	\
> +		0x0d, 0x0a, 0x00, 0xc2, 0xaf, 0xc2, 0x8c, 0xe5, 	\
> +		0x89, 0x54, 0xf0, 0x44, 0x02, 0xf5, 0x89, 0x75, 	\
> +		0x8c, 0x87, 0x75, 0x8a, 0x87, 0x8e, 0x53, 0x8f, 	\
> +		0x54, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x8b, 0x50, 	\
> +		0x8a, 0x51, 0x89, 0x52, 0xd2, 0xa9, 0xd2, 0x8c, 	\
> +		0xd2, 0xaf, 0x22, 0x90, 0xc1, 0xa3, 0x74, 0x50, 	\
> +		0xf0, 0x7f, 0xc8, 0x12, 0x05, 0x26, 0x12, 0x05, 	\
> +		0x26, 0x74, 0x10, 0xf0, 0x90, 0x80, 0x90, 0x74, 	\
> +		0x05, 0xf0, 0x12, 0x07, 0xc5, 0x12, 0x04, 0x77, 	\
> +		0x02, 0x0c, 0xfa, 0x75, 0x98, 0x50, 0x75, 0x89, 	\
> +		0x20, 0xef, 0x70, 0x05, 0x53, 0x87, 0x7f, 0x80, 	\
> +		0x03, 0x43, 0x87, 0x80, 0x8d, 0x8d, 0xd2, 0x8e, 	\
> +		0xc2, 0x98, 0xc2, 0x99, 0xd2, 0xac, 0xd2, 0xaf, 	\
> +		0x22, 0xc1, 0x81, 0x02, 0x3b, 0x00, 0x00, 0x02, 	\
> +		0x3d, 0x03, 0xe8, 0x01, 0x47, 0x00, 0x01, 0x21, 	\
> +		0x00, 0xc1, 0x04, 0xc1, 0x00, 0x02, 0x53, 0x00, 	\
> +		0x00, 0x02, 0x4e, 0x00, 0x00, 0x00, 0xd2, 0x80, 	\
> +		0x7f, 0x14, 0x12, 0x05, 0xb9, 0xd2, 0x81, 0x7f, 	\
> +		0x14, 0x12, 0x05, 0xb9, 0xc2, 0x80, 0x7f, 0x14, 	\
> +		0x12, 0x05, 0xb9, 0xc2, 0x81, 0x7f, 0x14, 0x02, 	\
> +		0x05, 0xb9, 0x20, 0x06, 0x04, 0xc2, 0x80, 0x80, 	\
> +		0x02, 0xd2, 0x80, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 	\
> +		0xd2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 0xc2, 	\
> +		0x81, 0x7f, 0x0a, 0x02, 0x05, 0xb9, 0xc2, 0x80, 	\
> +		0x7f, 0x14, 0x12, 0x05, 0xb9, 0xd2, 0x81, 0x7f, 	\
> +		0x14, 0x12, 0x05, 0xb9, 0xd2, 0x80, 0x7f, 0x14, 	\
> +		0x02, 0x05, 0xb9, 0x90, 0x80, 0x90, 0x74, 0x05, 	\
> +		0xf0, 0xe4, 0xf5, 0xa0, 0x07}
> +
> +#define FWCT	{\
> +		0x82, 0x4e, 0x12, 0x0c, 0xfa, 0xd2, 0x8a, 0xd2, 	\
> +		0xaa, 0xd2, 0xaf, 0x22, 0xef, 0xd3, 0x94, 0x00, 	\
> +		0x40, 0x09, 0xe4, 0xfe, 0x0e, 0xbe, 0x76, 0xfc, 	\
> +		0x1f, 0x80, 0xf1, 0x22, 0xc2, 0xaf, 0xc2, 0xac, 	\
> +		0xc2, 0x98, 0xc2, 0x99, 0x75, 0x98, 0x40, 0xc2, 	\
> +		0xa9, 0xc2, 0x8e, 0x22, 0x30, 0x99, 0x04, 0xd2, 	\
> +		0x01, 0xc2, 0x99, 0x30, 0x98, 0x05, 0x85, 0x99, 	\
> +		0x08, 0xc2, 0x98, 0x32, 0xc2, 0x8c, 0xc2, 0xa9, 	\
> +		0x75, 0x50, 0xff, 0x75, 0x51, 0x00, 0x75, 0x52, 	\
> +		0x0e, 0x22, 0x7d, 0xf8, 0xe4, 0xff, 0x02, 0x0c, 	\
> +		0x21, 0xfd}

Binding the firmware binary inside the a GPL code violates GPL license. Instead, please
split the firmware into a firmware file, and use the request_firmware() to load it from
userspace.

We need also manufacturer's ack to distribute their firmwares in a binary form, or, if this
is not possible, we'll need some script to extract the firmare from the original driver.

> +
> +#define FWTRL	0xfd
> +#define FWCTL	0x52
> +#define FWF3L	0x0f
> +#define LME_FIRMWARE_D	{{FWTRL, FWF1}, 	\
> +			{FWTRL, FWF2}, 	\
> +			{FWF3L, FWF3}, 	\
> +			{FWTRL, FWP1}, 	\
> +			{FWTRL, FWP2}, 	\
> +			{FWTRL, FWP3}, 	\
> +			{FWTRL, FWP4}, 	\
> +			{FWTRL, FWP5}, 	\
> +			{FWTRL, FWP6}, 	\
> +			{FWTRL, FWP7}, 	\
> +			{FWTRL, FWP8}, 	\
> +			{FWTRL, FWP9}, 	\
> +			{FWTRL, FWP10}, 	\
> +			{FWTRL, FWP11}, 	\
> +			{FWTRL, FWP12}, 	\
> +			{FWTRL, FWP13}, 	\
> +			{FWCTL, FWCT} }
> +
> +struct lme_firmware_data {
> +	u8 length;
> +	u8 bulk_data[256];       /* Address */
> +};
> +
> +#endif
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] added support for DM040832731 DVB-S USB BOX - Correction
  2010-07-16 13:43 [PATCH] added support for DM040832731 DVB-S USB BOX - Correction Malcolm Priestley
  2010-07-29 18:16 ` Mauro Carvalho Chehab
@ 2010-07-29 18:18 ` Mauro Carvalho Chehab
  1 sibling, 0 replies; 4+ messages in thread
From: Mauro Carvalho Chehab @ 2010-07-29 18:18 UTC (permalink / raw)
  To: Malcolm Priestley; +Cc: linux-media

Em 16-07-2010 10:43, Malcolm Priestley escreveu:
> DVB USB Driver for DM04 LME2510 + LG TDQY - P001F =(TDA8263 + TDA10086H)
> 
> Corrected patch error.
> 
> Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>

Hi Malcolm,

Please read the developers section of our Wiki page for instructions on how to submit
a driver:
	http://linuxtv.org/wiki/index.php/Developer_Section

In special, you need to read what's inside "Submiting your work" in order to fix some
troubles I identified on your driver.

Cheers,
Mauro

> 
> 
> 
> diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/Kconfig
> --- a/linux/drivers/media/dvb/dvb-usb/Kconfig	Thu May 27 02:02:09 2010 -0300
> +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig	Fri Jul 16 14:30:02 2010 +0100
> @@ -346,3 +346,13 @@
>  	select DVB_STB6100 if !DVB_FE_CUSTOMISE
>  	help
>  	  Say Y here to support the AZ6027 device
> +
> +config DVB_USB_LME2510
> +	tristate "LME DM04 (LME 2510 + TDQY-P001F) DVB-S USB2.0 support"
> +	depends on DVB_USB

It needs to depend also on INPUT/IR_CORE

> +	select DVB_TDA10086 if !DVB_FE_CUSTOMISE
> +	select DVB_TDA826X if !DVB_FE_CUSTOMISE
> +	help
> +	  Say Y here to support the LME DM04 DVB-S USB2.0 .
> +
> +
> diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/Makefile
> --- a/linux/drivers/media/dvb/dvb-usb/Makefile	Thu May 27 02:02:09 2010 -0300
> +++ b/linux/drivers/media/dvb/dvb-usb/Makefile	Fri Jul 16 14:30:02 2010 +0100
> @@ -88,6 +88,9 @@
>  dvb-usb-az6027-objs = az6027.o
>  obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
> 
> +dvb-usb-lmedm04-objs = lmedm04.o
> +obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
> +
>  EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
>  # due to tuner-xc3028
>  EXTRA_CFLAGS += -Idrivers/media/common/tuners
> diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/lmedm04.c
> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
> +++ b/linux/drivers/media/dvb/dvb-usb/lmedm04.c	Fri Jul 16 14:30:02 2010 +0100
> @@ -0,0 +1,910 @@
> +/* DVB USB compliant linux driver for
> + *
> + * DM040832731 DVB-S USB BOX (LME 2510 + TDQY-P001F)
> + *
> + * MV001F LG TDQY - P001F =(TDA8263 + TDA10086H)
> + *
> + * I2C addresses:
> + * 0x0e - TDA10086   - Demodulator
> + * 0x60 - TDA8263    - Tuner
> + *
> + * ***Please Note***
> + *		There are other variants of the DM04
> + *		***NOT SUPPORTED***
> + *		MVB0001F (LME2510C+LGTDQT-P001F)
> + *		MV0194 (LME2510+SHARP0194)
> + *		MVB0194 (LME2510C+SHARP0194)
> + *		MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
> + *
> + * The VID of 3344 and PID of 1122 has not been set until it is known not
> + * to be generic.
> + *
> + *
> + * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
> + * LME2510   (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 as published by the Free
> + * Software Foundation, version 2.
> + *
> + *
> + * see Documentation/dvb/README.dvb-usb for more information
> + *
> + * Known Issue :
> + * 	Non Intel USB chipsets fail to maintain High Speed on Boot or Hot Plug
> + *
> +  */
> +#define DVB_USB_LOG_PREFIX "LME2510"
> +#include <linux/usb.h>
> +#include <linux/usb/input.h>
> +#include "dvb-usb.h"
> +#include "lmedm04.h"
> +#include "tda826x.h"
> +#include "tda10086.h"
> +
> +/* debug */
> +static int dvb_usb_lme2510_debug;
> +#define l_dprintk(var, level, args...) \
> +	do { if ((var >= level)) info(args);  } while (0)
> +#define deb_info(level, args...) l_dprintk(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));
> +
> +
> +module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
> +MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."
> +			DVB_USB_DEBUG_STATUS);
> +
> +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
> +
> +
> +struct lme2510_state {
> +	u8 id;
> +	u8 signal_lock;
> +	u8 signal_level;
> +	u8 signal_sn;
> +	u8 time_key;
> +	u8 i2c_talk_onoff;
> +	u16 pid_table[64];
> +	u8 pid_count;
> +	u8 pid_flag_enable;
> +	u8 filter_data[256];
> +	void *buffer;
> +	struct urb *lme_urb;
> +
> +};
> +
> +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, 500);
> +	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, 500);
> +	return ret;
> +}
> +
> +static int lme2510_usb_talk(struct dvb_usb_device *d,
> +		u8 *wbuf, int wlen, u8 *rbuf, int rlen)
> +{
> +	u8 s[wlen+4], r[rlen+4];

This won't work fine. You should not use a buffer at stack to communicate with
USB, as those memory areas may not be able do handle DMA transfers. Instead, you
need to allocate a buffer for such transfers.

Also, the stack area on kernel is very small. you should not allocate a dynamic area
there, as this might cause buffer overflows, if you don't carefully check all clients
of this function.

> +	int ret = 0;
> +	memset(s, 0, wlen);
> +	memset(r, 0, rlen);

No need, as you're copying data with memcpy bellow.

> +	memcpy(&s[0], wbuf, wlen);
> +
> +	ret = mutex_lock_interruptible(&d->usb_mutex);
> +
> +	if (ret < 0)
> +		return -EAGAIN;
> +
> +	ret += usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
> +	msleep(5);
> +	ret += lme2510_bulk_write(d->udev, s, wlen , 0x1);
> +
> +	msleep(5);
> +	ret += usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x1));
> +
> +	msleep(5);
> +	ret += lme2510_bulk_read(d->udev, r, rlen , 0x1);
> +
> +	if (rlen > 0)
> +		memcpy(rbuf, &r[0], rlen);
> +
> +	mutex_unlock(&d->usb_mutex);
> +
> +	return (ret < 0) ? -EAGAIN : 0;

returing -EAGAIN is not good, as one of the reasons for this error may be due to device removal.

> +}
> +
> +static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
> +{
> +	struct dvb_usb_device *d = adap->dev;
> +	u32 event = 0;
> +
> +		switch (keypress) {
> +		KEYCASE(LME_R_1, KEY_1);
> +		break;
> +		KEYCASE(LME_R_2, KEY_2);
> +		break;
> +		KEYCASE(LME_R_3, KEY_3);
> +		break;
> +		KEYCASE(LME_R_4, KEY_4);
> +		break;
> +		KEYCASE(LME_R_5, KEY_5);
> +		break;
> +		KEYCASE(LME_R_6, KEY_6);
> +		break;
> +		KEYCASE(LME_R_7, KEY_7);
> +		break;
> +		KEYCASE(LME_R_8, KEY_8);
> +		break;
> +		KEYCASE(LME_R_9, KEY_9);
> +		break;
> +		KEYCASE(LME_R_0, KEY_0);
> +		break;
> +		KEYCASE(LME_R_POWER, KEY_POWER);
> +		break;
> +		KEYCASE(LME_R_SUB, KEY_SUBTITLE);
> +		break;
> +		KEYCASE(LME_R_CAPTURE, KEY_PAUSE);
> +		break;
> +		KEYCASE(LME_R_REPEAT, KEY_MEDIA_REPEAT);
> +		break;
> +		KEYCASE(LME_R_PAUSE, KEY_PAUSE);
> +		break;
> +		KEYCASE(LME_R_VOL_D, KEY_VOLUMEDOWN);
> +		break;
> +		KEYCASE(LME_R_VOL_U, KEY_VOLUMEUP);
> +		break;
> +		KEYCASE(LME_R_CH_D, KEY_CHANNELDOWN);
> +		break;
> +		KEYCASE(LME_R_CH_U, KEY_CHANNELUP);
> +		break;
> +		KEYCASE(LME_R_PLAYBACK, KEY_PLAY);
> +		break;
> +		KEYCASE(LME_R_ZOOM, KEY_ZOOM);
> +		break;
> +		KEYCASE(LME_R_MUTE, KEY_MUTE);
> +		break;
> +		KEYCASE(LME_R_LIVETV, KEY_TV);
> +		break;
> +		KEYCASE(LME_R_RECORD, KEY_RECORD);
> +		break;
> +		KEYCASE(LME_R_EPG, KEY_EPG);
> +		break;
> +		KEYCASE(LME_R_STOP, KEY_STOPCD);
> +		break;
> +		default:
> +			event = 0;
> +		break;

This is ugly for several reasons:

1) it hides case reserved word;
2) the IR translation table cannot be customized;
3) we'll be moving all IR keytables to userspace.

The proper solution is to use the rc-core handler for IR. I'll be porting soon the DVB drivers
to use it, but you can find already some examples on some drivers under drivers/media/video (like
saa7134 and em28xx).

> +
> +
> +
> +	}
> +
> +		deb_info(1, "INT Key Pressed =%04x Event =%04x",
> +			 keypress, event);
> +	if (event > 0) {
> +		input_event(d->rc_input_dev, EV_KEY, event, 1);
> +
> +		input_event(d->rc_input_dev, EV_KEY, event, 0);
> +
> +		}
> +
> +    return 0;
> +}
> +
> +static int lme2510_enable_filter(struct dvb_usb_adapter *adap)
> +{
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 filter_init[] = LME_FILTER_INT;
> +	static u8 filter_on[] = LME_ST_ON_W;
> +	static u8 rbuf[1];
> +	static u8 *sbuf;
> +	int ret = 0, len = 5;
> +	info("PID Setting Filter");
> +
> +	sbuf = (u8 *) st->filter_data;
> +
> +
> +	ret += lme2510_usb_talk(adap->dev,  filter_init, len, rbuf, 1);
> +
> +	ret += lme2510_usb_talk(adap->dev, sbuf, 80 , rbuf, 1);
> +
> +	ret += lme2510_usb_talk(adap->dev, filter_on, len, rbuf, 1);

Please, don't use "magic numbers". Instead of using "1" for the rbuf size, use
sizeof(rbuf).

> +
> +	st->pid_count = 0;
> +	st->pid_flag_enable = 0;
> +
> +	return ret;
> +}
> +
> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
> +static void lme2510_int_response(struct urb *lme_urb, struct pt_regs *ptregs)
> +#else
> +static void lme2510_int_response(struct urb *lme_urb)
> +#endif
> +{
> +	struct dvb_usb_adapter *adap = lme_urb->context;
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 *ibuf, *rbuf;
> +	int i = 0, offset;
> +
> +		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 in", ibuf);
> +			lme2510_remote_keypress(adap,
> +				(u16)(ibuf[4]<<8)+ibuf[5]);
> +			break;
> +		case 0xbb:
> +			st->signal_lock = ibuf[2];
> +			st->signal_level = ibuf[4];
> +			st->signal_sn = ibuf[3];
> +			st->time_key = ibuf[7];
> +		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 lme2510_state *lme_int = adap->dev->priv;
> +	lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
> +
> +	if (lme_int->lme_urb == NULL)
> +			return -ENOMEM;
> +
> +	lme_int->buffer = usb_buffer_alloc(adap->dev->udev, 5000, GFP_ATOMIC,
> +					&lme_int->lme_urb->transfer_dma);
> +
> +	if (lme_int->buffer == NULL)
> +			return -ENOMEM;
> +
> +	usb_fill_int_urb(lme_int->lme_urb,
> +				adap->dev->udev,
> +				usb_rcvintpipe(adap->dev->udev, 0xa),
> +				lme_int->buffer,
> +				4096,
> +				lme2510_int_response,
> +				adap,
> +				11);
> +
> +	lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
> +
> +	usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
> +	info("INT Interupt Service Started");
> +
> +	return 0;
> +}
> +
> +static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
> +{
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 clear_pid_reg_3[] = LME_CLEAR_PID;
> +	static u8 rbuf[1];
> +	int ret = 0;
> +	deb_info(3, "PID ONOFF Filter talk =%04x onoff=%02x pid_flag%02x",
> +			st->i2c_talk_onoff, onoff, st->pid_flag_enable);
> +
> +	if (onoff == 0)
> +			return 0;
> +	else {

Don't need for an else block here.

> +		deb_info(1, "PID Clearing Filter");
> +		ret += lme2510_usb_talk(adap->dev,
> +			clear_pid_reg_3, 4, rbuf, 1);
> +		}
> +	return 0;
> +
> +}
> +
> +static int lme2510_pidbuild_table(struct lme2510_state *st)
> +{
> +	u8 buffer_complete[] = {0x00, 0x00, 0x01, 0x00, 0x02,
> +				0x00, 0x10, 0x00, 0x11, 0x00,
> +				0x12, 0x00, 0x13, 0x00, 0x14,
> +				0x00, 0x20, 0x9a};
> +	u16 pid_out;
> +	int j, i, b = 0, je, reg = 0;
> +	u8 temp_buff[256];
> +
> +	deb_info(1, "PID Building Table");
> +
> +	j = 3;
> +	temp_buff[0] = 0x03;
> +	i = 2;
> +	reg = 0;
> +	while (j < 8) {
> +		pid_out = st->pid_table[j++];
> +			if (pid_out == 0x0012)
> +				break;
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = (u8) pid_out & 0xff;
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = pid_out>>8;
> +		};
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = 0xfb;
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = 0x1f;
> +		temp_buff[i++] = reg++;
> +		temp_buff[i++] = st->pid_table[3]&0xff;
> +		temp_buff[i++] =  reg++;
> +		temp_buff[i++] = st->pid_table[3]>>8;
> +		temp_buff[i++] =  reg++;
> +		temp_buff[i++] = st->pid_table[2]&0xff;
> +		temp_buff[i++] =  reg++;
> +		temp_buff[i++] = st->pid_table[2]>>8;
> +	j = i;
> +	je = i+16;
> +	while (j++ < je) {
> +		temp_buff[i++] =  reg++;
> +		temp_buff[i++] = buffer_complete[b++];
> +		};
> +		temp_buff[i] = 0x20;
> +		temp_buff[1] =  i ;
> +		temp_buff[++i] = 0x9a;
> +
> +		memcpy(st->filter_data, &temp_buff[0], 255);

Bad identation. Always use tabs for identation. A tab has 8 spaces. The identation should
look like:
	while (j++ < je) {
		temp_buff[i++] =  reg++;
		temp_buff[i++] = buffer_complete[b++];
	}

Also, don't use ; after }

Please check your patches with scripts/checkpatch.pl (found at the kernel tree).
There are Several CodingStyle troubles on your patch. You should also take a look
at 

> +
> +	deb_info(2, "PID T RAW WRITE DUMP-----");
> +	for (i = 0; i < 10; i++)
> +		debug_data_snipet(2, ">", &st->filter_data[i*8]);
> +
> +
> +	return 0;
> +}
> +
> +static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
> +	int onoff)
> +{
> +	struct lme2510_state *st = adap->dev->priv;
> +	int ret = 0, i;
> +
> +	deb_info(4, "PID F PID=%04x Inx=%04x onoff=%02x i2c_talk=%02x FC=%02x",
> +			pid, index, onoff,
> +			st->i2c_talk_onoff,  adap->feedcount);
> +
> +	if ((pid == 0)&(index == 0)&(onoff == 0))
> +		st->pid_count = 0;
> +
> +
> +	if (index < 30) {
> +		st->pid_table[st->pid_count] = pid;
> +
> +		deb_info(3, "PID T PID=%04x Inx=%04x onoff=%02x,i2c_talk=%02x",
> +			st->pid_table[st->pid_count],
> +			st->pid_count, onoff,
> +			st->i2c_talk_onoff);
> +
> +		if ((st->pid_table[st->pid_count] == 0x0012) &
> +						(st->pid_count > 3)) {
> +			deb_info(2, "PID Table Dump---------");
> +			for (i = 0; i < st->pid_count; i++)
> +				deb_info(2, "PID No %02x=(%04x)",
> +						i, st->pid_table[i]);
> +
> +
> +			if ((st->pid_count < 8) &
> +				(st->pid_table[3] != 0x0012)) {
> +				ret = lme2510_pidbuild_table(st);
> +				st->pid_flag_enable = 1;
> +				ret -= lme2510_enable_filter(adap);
> +			}
> +				else
> +			info("PID more than 4 - passing full stream");
> +		} else
> +		st->pid_count++;
> +	}
> +
> +
> +	return ret;
> +}
> +
> +static int lme2510_return_status(struct usb_device *dev)
> +{
> +	int i;
> +	u8 data[10] = {0};
> +	i =  usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
> +			0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
> +	/*i = usb_get_descriptor(dev, 0x03, 0x02, data, 0x06);*/
> +	info("Firmware Status: %x (%x)", i, data[2]);

Hmm... what happens if usb_control_msg returns an error?

> +	i = data[2];
> +	return i;
> +}
> +
> +
> +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) {
> +		if ((wbuf[0] == 0x84) & (wbuf[1] == 0x03) &
> +			(wbuf[2] == 0x1c) & (wbuf[3] == 0x0e))
> +			msleep(80); /*take your time when waiting for tune*/
> +
> +		if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
> +			return -EAGAIN;
> +
> +		ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
> +
> +		mutex_unlock(&d->i2c_mutex);
> +		}	else	{
> +		if ((wbuf[0] == 0x84) & (wbuf[1] == 0x03)
> +					& (wbuf[2] == 0x1c)) {
> +			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;
> +			default:
> +					break;
> +			}
> +		deb_info(4, "I2C From Interupt 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);
> +	static u8 obuf[64], ibuf[512];
> +	int i, read;
> +	u16 len;
> +
> +	if (num > 2)
> +		warn("more than 2 i2c messages"
> +			"at a time is not handled yet.	TODO.");
> +
> +	for (i = 0; i < num; i++) {
> +		read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
> +		obuf[0] = 0x04 | (read << 7);
> +		obuf[1] = (msg[i].addr < 0x40) ? LME_I2C_C_L : LME_I2C_C_H;
> +		obuf[2] = (msg[i].addr << 1);
> +		if (read) {
> +			memcpy(&obuf[3], msg[i].buf, msg[i].len);
> +			obuf[4] = msg[i].len;
> +			len = msg[i].len+4;
> +		} else {
> +			memcpy(&obuf[3], msg[i].buf, msg[i].len);
> +			len = 64;
> +		}
> +
> +
> +		if (lme2510_msg(d, obuf, len, ibuf, 512) < 0) {
> +			deb_info(1, "i2c transfer failed.");
> +			return -EAGAIN;
> +		}
> +
> +		if (read) {
> +			memcpy(msg[i+1].buf, &ibuf[1],
> +				(msg[i+1].len > 512) ? 512 : msg[i+1].len);
> +
> +			i++;
> +		}
> +	}
> +	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,
> +#ifdef NEED_ALGO_CONTROL
> +	.algo_control = dummy_algo_control,
> +#endif
> +};
> +
> +/* Callbacks for DVB USB */
> +static int lme2510_identify_state(struct usb_device *udev,
> +		struct dvb_usb_device_properties *props,
> +		struct dvb_usb_device_description **desc,
> +		int *cold)
> +{
> +	*cold = 0;
> +	return 0;
> +}
> +
> +static int lme2510_init(struct dvb_usb_device *d)
> +{
> +	static u8 command1[] = LME_ST_OFF_C;
> +	static u8 ibuf[512];
> +	int ret, len = 5, len_in = 512;
> +	msleep(500);
> +	ret = lme2510_usb_talk(d, command1, len, ibuf, len_in);
> +	return ret;
> +}
> +
> +static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
> +{
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 stream_off[] = LME_ST_OFF_C;
> +	static u8 clear_reg_3[] =  LME_CLEAR_PID;
> +	static u8 stream_on[] = LME_ST_ON_W;
> +	static u8 rbuf[1];
> +	int ret = 0, len = 5;
> +	deb_info(1, "STM  (%02x)", onoff);
> +
> +	if (onoff == 1)	{
> +		ret += lme2510_usb_talk(adap->dev,
> +				 stream_on,  len, rbuf, 1);
> +		st->i2c_talk_onoff = 0;
> +	} else {
> +		st->i2c_talk_onoff = 1;
> +		ret += lme2510_usb_talk(adap->dev,
> +					stream_off, len, rbuf, 1);
> +		deb_info(1, "STM Clearing PID Filter");
> +		ret += lme2510_usb_talk(adap->dev,
> +			 clear_reg_3, 4, rbuf, 1);
> +	}
> +
> +	return 0;
> +}
> +
> +static int lme2510_int_service(struct dvb_usb_adapter *adap)
> +{
> +	struct dvb_usb_device *d = adap->dev;
> +	struct input_dev *input_dev;
> +	int ret, i;
> +	u32 keys[] =  LME_KEYS_USED;
> +	info("STA Configuring Remote");
> +
> +	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
> +
> +	strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
> +
> +	input_dev = input_allocate_device();
> +	if (!input_dev)
> +		return -ENOMEM;
> +
> +	input_dev->evbit[0] = BIT_MASK(EV_KEY);
> +	input_dev->name = "LME2510 Remote Control";
> +	input_dev->phys = d->rc_phys;
> +	usb_to_input_id(d->udev, &input_dev->id);
> +
> +	for (i = 0; i < sizeof(keys)/4 ; ++i)
> +		set_bit(keys[i], input_dev->keybit);
> +
> +	deb_info(3, "STA Number of Keys %d", sizeof(keys)/4);
> +
> +	ret = input_register_device(input_dev);
> +	if (ret) {
> +		input_free_device(input_dev);
> +		return ret;
> +	}
> +
> +	d->rc_input_dev = input_dev;
> +	/* Start the Interupt */
> +	ret = lme2510_int_read(adap);
> +
> +	if (ret < 0)
> +		input_free_device(input_dev);
> +
> +	return (ret < 0) ? -ENODEV : 0;
> +}

Should use the IR register functions from ir-core.

> +
> +static struct tda10086_config tda10086_config = {
> +	.demod_address = 0x0e,
> +	.invert = 0,
> +	.diseqc_tone = 1,
> +	.xtal_freq = TDA10086_XTAL_16M,
> +};
> +
> +static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
> +					fe_sec_voltage_t voltage)
> +{
> +	struct dvb_usb_adapter *adap = fe->dvb->priv;
> +	static u8 voltage_low[]	= LME_VOLTAGE_L;
> +	static u8 voltage_high[] = LME_VOLTAGE_H;
> +	static u8 rbuf[1];
> +	int ret, len = 5;
> +
> +		switch (voltage) {
> +
> +		case SEC_VOLTAGE_18:
> +			ret = lme2510_usb_talk(adap->dev,
> +				voltage_high, len, rbuf, 1);
> +		break;
> +
> +		case SEC_VOLTAGE_OFF:
> +		case SEC_VOLTAGE_13:
> +		default:
> +		ret = lme2510_usb_talk(adap->dev,
> +				voltage_low, len, rbuf, 1);
> +		break;
> +
> +
> +	};
> +	return 0;
> +}
> +
> +static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
> +{
> +	int ret = 0;
> +	struct lme2510_state *st = adap->dev->priv;
> +	st->pid_flag_enable = 0;
> +	/* Interupt Start  */
> +	ret = lme2510_int_service(adap);
> +	if (ret < 0) {
> +		info("INT Unable to start Interupt Service");
> +		return -ENODEV;
> +	}
> +
> +	st->i2c_talk_onoff = 1;
> +
> +	ret = lme2510_init(adap->dev);
> +
> +	adap->fe = dvb_attach(tda10086_attach, &tda10086_config,
> +		&adap->dev->i2c_adap);
> +
> +	if (adap->fe != NULL) {
> +		memcpy(&adap->fe->ops.info.name,
> +				&"DM04_LG_TDQY-P001F DVB-S", 24);
> +		adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
> +	} else {
> +		info("This DM04 Device is not supported");
> +		return -ENODEV;
> +	}
> +
> +	return ret;
> +}
> +
> +static int dm04_lme2510_tuner_attach(struct dvb_usb_adapter *adap)
> +{
> +	if (dvb_attach(tda826x_attach, adap->fe, 0x60,
> +			&adap->dev->i2c_adap, 1) == NULL) {
> +		deb_info(1, "TDA8263 attach failed\n");
> +		return -ENODEV;
> +	}
> +
> +	return 0;
> +}
> +
> +static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
> +{
> +	struct lme2510_state *st = d->priv;
> +	st->i2c_talk_onoff = 1;
> +	return 0;
> +}
> +
> +static struct lme_firmware_data lme_firmware[] =   LME_FIRMWARE_D;
> +
> +static int lme2510_firmware(struct usb_device *dev, const struct firmware *fw)
> +{
> +	int ret = 0, j;
> +	u8 data[1000] = {0};
> +	u16 wlen = 253;
> +	info("FRM Starting Firmware Download");
> +
> +	for (j = 0; j < 17; ++j)	{
> +		wlen = (int)lme_firmware[j].length;
> +		memcpy(&data[0], &lme_firmware[j].bulk_data[0],
> +				(wlen < 256) ? wlen : 256);
> +		ret += lme2510_bulk_write(dev, data,  wlen, 1);
> +		ret += lme2510_bulk_read(dev, data, 512 , 1);
> +		ret += (data[0] == 0x88) ? 0 : -1;
> +	}
> +
> +	usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
> +			0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
> +
> +
> +	data[0] = 0x8a;
> +	msleep(2000);
> +	ret += lme2510_bulk_write(dev, data , 1, 1); /*Resetting*/
> +	ret += lme2510_bulk_read(dev, data, 512 , 1);
> +	msleep(400);
> +
> +	if (ret < 0)
> +		info("FRM Firmware Download Failed (%04x)" , ret);
> +	else
> +		info("FRM Firmware Download Completed - Resetting Device");
> +
> +
> +	return (ret < 0) ? -ENODEV : 0;
> +}
> +
> +/* DVB USB Driver stuff */
> +static struct dvb_usb_device_properties lme2510_properties;
> +
> +static int lme2510_probe(struct usb_interface *intf,
> +		const struct usb_device_id *id)
> +{
> +	struct usb_device *udev = interface_to_usbdev(intf);
> +	int ret = 0;
> +
> +	usb_reset_configuration(udev);
> +
> +	usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1);
> +
> +	if (udev->speed != USB_SPEED_HIGH) {
> +		ret = usb_reset_device(udev);
> +		info("DEV Failed to connect in HIGH SPEED mode");
> +		return -ENODEV;
> +	}
> +
> +
> +	if (0x44 == lme2510_return_status(udev)) {
> +		ret += lme2510_firmware(udev, NULL);
> +		return 0; /* reset on way */
> +	}
> +
> +
> +	if (0 == dvb_usb_device_init(intf, &lme2510_properties,
> +				     THIS_MODULE, NULL, adapter_nr)) {
> +		info("DEV registering device driver");
> +		return 0;
> +	}
> +
> +	info("DEV lme2510 Error");
> +	return -ENODEV;
> +
> +}
> +
> +static struct usb_device_id lme2510_table[] = {
> +	{ USB_DEVICE(0x3344, 0x1122) },  /* generic China models */
> +	{}		/* Terminating entry */
> +};
> +
> +MODULE_DEVICE_TABLE(usb, lme2510_table);
> +
> +static struct dvb_usb_device_properties lme2510_properties = {
> +	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
> +	.usb_ctrl = DEVICE_SPECIFIC,
> +	.size_of_priv = sizeof(struct lme2510_state),
> +	.num_adapters = 1,
> +	.adapter = {
> +		{
> +			.caps = DVB_USB_ADAP_HAS_PID_FILTER|
> +				DVB_USB_ADAP_NEED_PID_FILTERING|
> +				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
> +			.streaming_ctrl   = lme2510_streaming_ctrl,
> +			.pid_filter_count = 29,
> +			.pid_filter = lme2510_pid_filter,
> +			.pid_filter_ctrl  = lme2510_pid_filter_ctrl,
> +			.frontend_attach  = dm04_lme2510_frontend_attach,
> +			.tuner_attach     = dm04_lme2510_tuner_attach,
> +			/* parameter for the MPEG2-data transfer */
> +			.stream = {
> +				.type = USB_BULK,
> +				.count = 10,
> +				.endpoint = 0x06,
> +				.u = {
> +					.bulk = {
> +						.buffersize = 4096,
> +
> +					}
> +				}
> +			}
> +		}
> +	},
> +	.power_ctrl       = lme2510_powerup,
> +	.identify_state   = lme2510_identify_state,
> +	.i2c_algo         = &lme2510_i2c_algo,
> +	.generic_bulk_ctrl_endpoint = 0,
> +	.num_device_descs = 1,
> +	.devices = {
> +		{   "LME2510 + LG TDQY-P001F DVB-S USB2.0",
> +			{ &lme2510_table[0], NULL },
> +			},
> +
> +	}
> +};
> +
> +void lme2510_exit_int(struct dvb_usb_device *d)
> +{
> +	struct lme2510_state *st = d->priv;
> +		if (st->lme_urb != NULL) {
> +			usb_kill_urb(st->lme_urb);
> +			usb_buffer_free(d->udev, 5000, st->buffer,
> +					st->lme_urb->transfer_dma);
> +			info("Interupt Service Stopped");
> +		}
> +	return;
> +}
> +
> +void lme2510_exit(struct usb_interface *intf)
> +{
> +	struct dvb_usb_device *d = usb_get_intfdata(intf);
> +	if (d != NULL) {
> +		lme2510_exit_int(d);
> +		input_unregister_device(d->rc_input_dev);
> +		info("Remote Stopped");
> +		dvb_usb_device_exit(intf);
> +	}
> +
> +}
> +
> +static struct usb_driver lme2510_driver = {
> +	.name		= "LME_DVBS",
> +	.probe		= lme2510_probe,
> +	.disconnect 	= lme2510_exit,
> +	.id_table	= lme2510_table,
> +};
> +
> +/* module stuff */
> +static int __init lme2510_module_init(void)
> +{
> +	int result = usb_register(&lme2510_driver);
> +	if (result) {
> +		err("usb_register failed. Error number %d", result);
> +		return result;
> +	}
> +
> +	return 0;
> +}
> +
> +static void __exit lme2510_module_exit(void)
> +{
> +	/* deregister this driver from the USB subsystem */
> +	usb_deregister(&lme2510_driver);
> +}
> +
> +module_init(lme2510_module_init);
> +module_exit(lme2510_module_exit);
> +
> +MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
> +MODULE_DESCRIPTION("LME DVB-S USB2.0");
> +MODULE_VERSION("1.0");
> +MODULE_LICENSE("GPL");
> diff -r 9652f85e688a linux/drivers/media/dvb/dvb-usb/lmedm04.h
> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
> +++ b/linux/drivers/media/dvb/dvb-usb/lmedm04.h	Fri Jul 16 14:30:02 2010 +0100
> @@ -0,0 +1,682 @@
> +/* DVB USB compliant linux driver for
> + *
> + * LME DM040832731 (LME 2510 + TDQY-P001F)
> + *
> + * MV001F LG TDQY - P001F =(TDA8263 + TDA10086H)
> + *
> + *
> + * 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_
> +
> +
> +/* Interupt */
> +
> +#define LME_REMOTE	0xaa
> +#define LME_STREAM	0xbb
> +#define LME_IDLE	0xcc
> +
> +
> +/* Remote */
> +
> +#define KEYCASE(key, id) \
> +do { case key: \
> +  event = id;\
> + } while (0)
> +
> +#define LME_R_1		0xa05f
> +#define LME_R_2		0xaf50
> +#define LME_R_3		0xa25d
> +#define LME_R_4		0xbe41
> +#define LME_R_5		0xf50a
> +#define LME_R_6		0xbd42
> +#define LME_R_7		0xb847
> +#define LME_R_8		0xb649
> +#define LME_R_9		0xfa05
> +#define LME_R_0		0xba45
> +#define LME_R_POWER	0xbc43
> +#define LME_R_SUB	0xb946
> +#define LME_R_CAPTURE	0xf906
> +#define LME_R_REPEAT	0xfc03
> +#define LME_R_PAUSE	0xfd02
> +#define LME_R_VOL_D	0xa35c
> +#define LME_R_VOL_U	0xa15e
> +#define LME_R_CH_D	0xe51a
> +#define LME_R_CH_U	0xf609
> +#define LME_R_PLAYBACK	0xe11e
> +#define LME_R_ZOOM	0xe41b
> +#define LME_R_MUTE	0xa659
> +#define LME_R_LIVETV	0xa55a
> +#define LME_R_RECORD	0xe718
> +#define LME_R_EPG	0xf807
> +#define LME_R_STOP	0xfe01
> +
> +#define	LME_KEYS_USED {	KEY_1, 			KEY_2, \
> +			KEY_3, 			KEY_4, \
> +			KEY_5, 			KEY_6, \
> +			KEY_7, 			KEY_8, \
> +			KEY_9, 			KEY_0, \
> +			KEY_POWER, 		KEY_PAUSE, \
> +			KEY_VOLUMEDOWN, 		KEY_VOLUMEUP, \
> +			KEY_CHANNELDOWN, 	KEY_CHANNELUP, \
> +			KEY_PLAY, 		KEY_MUTE, KEY_TV, \
> +			KEY_ZOOM, 		KEY_EPG, \
> +			KEY_SUBTITLE, 		KEY_RECORD, \
> +			KEY_MEDIA_REPEAT, 	KEY_STOPCD, \
> +			0x0000}
> +
> +
> +/* 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 XX XX XX
> + *  offset 1 = 00
> + *  offset 2 = default after warm start 52, otherwise greater than 40
> + *  offset 3 = default after warm start 80, =(power offset 3),  82,  88
> + *  offset 4 = 20,  before PID setting 5c, 1c, d0,  (tuning 8c)
> + *
> + *  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, 0x52, 0x80, 0x20}
> +#define LME_FILTER_INT	{0x06, 0x00, 0x92, 0x88, 0x5c}
> +#define LME_ST_OFF_C	{0x06, 0x00, 0x52, 0x80, 0xd0}
> +#define LME_CLEAR_PID   {0x03, 0x02, 0x20, 0xa0}
> +
> +/*
> +#define LME_ST_INIT	{0x06, 0x00, 0x72, 0xb3, 0x1c}
> +#define LME_ST_ON_C	{0x06, 0x00, 0x52, 0x80, 0x20}
> +#define LME_ST_ON	{0x06, 0x00, 0x40, 0x82, 0x50}
> +*/
> +
> +/* LME Power Control
> + *  07 XX XX XX XX
> + *  offset 1 = 01  Power? my device cannot be powered down
> + *  offset 2 = 00=Voltage low 01=Voltage high
> + *  offset 3 = unknown but usually AE, B1-B3
> + *  offset 4 = mosty C8 but sometimes C9
> + */
> +
> +#define LME_VOLTAGE_L	{0x07, 0x01, 0x00, 0xb3, 0xc9}
> +#define LME_VOLTAGE_H	{0x07, 0x01, 0x01, 0xb3, 0xc9}
> +
> +/* I2C */
> +#define LME_I2C_C_L	0x03
> +#define LME_I2C_C_H	0x0c
> +#define LME_I2C_WRITE	0x04
> +#define LME_I2C_READ	0x84
> +
> +/* Firmware */
> +#define FWF1	{\
> +		0x01, 0xf9, 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 	\
> +		0x00, 0x40, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 	\
> +		0x01, 0x02, 0x03, 0x01, 0x0a, 0x06, 0x00, 0x02, 	\
> +		0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x09, 0x02, 	\
> +		0x37, 0x00, 0x01, 0x01, 0x00, 0xc0, 0xfa, 0x09, 	\
> +		0x04, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 	\
> +		0x09, 0x04, 0x00, 0x01, 0x04, 0xff, 0x00, 0x00, 	\
> +		0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x00, 	\
> +		0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 	\
> +		0x05, 0x8a, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 	\
> +		0x0a, 0x02, 0x40, 0x00, 0x00, 0x09, 0x07, 0x53, 	\
> +		0x00, 0x01, 0x01, 0x00, 0xc0, 0xfa, 0x09, 0x04, 	\
> +		0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 	\
> +		0x04, 0x00, 0x01, 0x08, 0xff, 0x00, 0x00, 0x00, 	\
> +		0x07, 0x05, 0x81, 0x02, 0x00, 0x02, 0x00, 0x07, 	\
> +		0x05, 0x01, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 	\
> +		0x02, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x86, 	\
> +		0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x87, 0x02, 	\
> +		0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 	\
> +		0x00, 0x00, 0x07, 0x05, 0x8a, 0x03, 0x40, 0x00, 	\
> +		0x0b, 0x07, 0x05, 0x0a, 0x02, 0x40, 0x00, 0x00, 	\
> +		0x08, 0x03, 0x09, 0x04, 0x03, 0x04, 0x15, 0x16, 	\
> +		0x05, 0x03, 0x41, 0x42, 0x43, 0x06, 0x03, 0x44, 	\
> +		0x44, 0x44, 0x44, 0x07, 0x03, 0x48, 0x49, 0x50, 	\
> +		0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x75}
> +
> +#define FWF2	{\
> +		0x01, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 	\
> +		0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x03, 0x01, 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 	\
> +		0x00, 0x40, 0x01, 0x00, 0x09, 0x02, 0x53, 0x00, 	\
> +		0x01, 0x01, 0x00, 0xc0, 0xfa, 0x09, 0x04, 0x00, 	\
> +		0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x04, 	\
> +		0x00, 0x01, 0x08, 0xff, 0x00, 0x00, 0x00, 0x07, 	\
> +		0x05, 0x81, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 	\
> +		0x01, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x02, 	\
> +		0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x86, 0x02, 	\
> +		0x00, 0x02, 0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 	\
> +		0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 	\
> +		0x00, 0x07, 0x05, 0x8a, 0x03, 0x40, 0x00, 0x0b, 	\
> +		0x07, 0x05, 0x0a, 0x02, 0x40, 0x00, 0x00, 0x09, 	\
> +		0x07, 0x37, 0x00, 0x01, 0x01, 0x00, 0xc0, 0xfa, 	\
> +		0x09, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 	\
> +		0x00, 0x09, 0x04, 0x00, 0x01, 0x04, 0xff, 0x00, 	\
> +		0x00, 0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 	\
> +		0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 	\
> +		0x07, 0x05, 0x8a, 0x02, 0x40, 0x00, 0x00, 0x07, 	\
> +		0x05, 0x0a, 0x02, 0x40, 0x00, 0x00, 0x08, 0x03, 	\
> +		0x09, 0x04, 0x03, 0x04, 0x15, 0x16, 0x05, 0x03, 	\
> +		0x41, 0x42, 0x43, 0x06, 0x03, 0x47, 0x47, 0x47, 	\
> +		0x47, 0x07, 0x03, 0x48, 0x49, 0x50, 0x51, 0x52, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x7e}
> +
> +
> +#define FWF3	{0x81, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	\
> +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
> +
> +
> +#define FWP1	{\
> +		0x02, 0xf9, 0x02, 0x05, 0xc5, 0x30, 0x01, 0xfd, 	\
> +		0x8f, 0x99, 0xc2, 0x01, 0x22, 0x02, 0x09, 0x9f, 	\
> +		0x22, 0xff, 0xff, 0xff, 0xff, 0x02, 0x0a, 0x92, 	\
> +		0x90, 0xc0, 0x0b, 0xe0, 0x30, 0xe1, 0x02, 0xc3, 	\
> +		0x22, 0xd3, 0x22, 0xff, 0xff, 0x02, 0x0c, 0xdc, 	\
> +		0xc2, 0x05, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xf5, 	\
> +		0x09, 0x90, 0xc0, 0x84, 0xe0, 0xff, 0x74, 0x0f, 	\
> +		0x25, 0x09, 0xf8, 0xa6, 0x07, 0x05, 0x09, 0xe5, 	\
> +		0x09, 0xb4, 0x02, 0xed, 0xe5, 0x0f, 0x12, 0x07, 	\
> +		0x27, 0x00, 0x8b, 0x02, 0x00, 0xe0, 0x03, 0x01, 	\
> +		0x4e, 0x04, 0x01, 0xd1, 0x05, 0x02, 0x61, 0x06, 	\
> +		0x02, 0x76, 0x07, 0x02, 0xd8, 0x08, 0x03, 0x32, 	\
> +		0x09, 0x03, 0x5c, 0x0a, 0x00, 0xb9, 0x82, 0x01, 	\
> +		0x16, 0x83, 0x01, 0x92, 0x84, 0x02, 0x05, 0x85, 	\
> +		0x02, 0x87, 0x87, 0x00, 0x7e, 0xf1, 0x00, 0xb3, 	\
> +		0xf2, 0x02, 0x41, 0xf5, 0x00, 0x00, 0x03, 0x79, 	\
> +		0x90, 0xc0, 0x0b, 0x74, 0x02, 0xf0, 0x90, 0xc1, 	\
> +		0xa3, 0x74, 0x50, 0xf0, 0x22, 0x90, 0xc0, 0x84, 	\
> +		0xe0, 0xf5, 0x0b, 0xe0, 0xf5, 0x0c, 0x90, 0xc0, 	\
> +		0x36, 0x74, 0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x16, 0xf0, 0x74, 0x76, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x96, 0xf0, 0xad, 0x0c, 0xaf, 0x0b, 0x12, 	\
> +		0x0c, 0x21, 0x02, 0x02, 0x02, 0x12, 0x0c, 0xcc, 	\
> +		0x02, 0x02, 0x02, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 	\
> +		0xc3, 0xe5, 0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 	\
> +		0x00, 0x50, 0x14, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 	\
> +		0x0c, 0xff, 0x12, 0x00, 0x03, 0x05, 0x0e, 0xe5, 	\
> +		0x0e, 0x70, 0xe5, 0x05, 0x0d, 0x80, 0xe1, 0x02, 	\
> +		0x02, 0x02, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xc3, 	\
> +		0xe5, 0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 0x00, 	\
> +		0x50, 0x23, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 0x0b, 	\
> +		0xe0, 0xf5, 0x0c, 0xe4, 0x5a}
> +
> +
> +#define FWP2	{\
> +		0x02, 0xf9, 0x25, 0x0b, 0xf5, 0x82, 0xe4, 0x34, 	\
> +		0x90, 0xf5, 0x83, 0xe5, 0x0c, 0xf0, 0x74, 0x02, 	\
> +		0x25, 0x0e, 0xf5, 0x0e, 0xe4, 0x35, 0x0d, 0xf5, 	\
> +		0x0d, 0x80, 0xd2, 0x02, 0x02, 0x02, 0x90, 0xc0, 	\
> +		0x84, 0x74, 0x55, 0xf0, 0xe4, 0xf5, 0x0d, 0xf5, 	\
> +		0x0e, 0xc3, 0xe5, 0x0e, 0x95, 0x10, 0xe5, 0x0d, 	\
> +		0x94, 0x00, 0x50, 0x1f, 0x90, 0xc0, 0x84, 0xe0, 	\
> +		0xf5, 0x0b, 0xff, 0xe4, 0x2f, 0xf5, 0x82, 0xe4, 	\
> +		0x34, 0x90, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x84, 	\
> +		0xf0, 0x05, 0x0e, 0xe5, 0x0e, 0x70, 0xda, 0x05, 	\
> +		0x0d, 0x80, 0xd6, 0x02, 0x02, 0x56, 0x90, 0xc0, 	\
> +		0x84, 0xe0, 0xf5, 0x0a, 0xe0, 0xf5, 0x0b, 0xe5, 	\
> +		0x10, 0x24, 0xfe, 0xf5, 0x0e, 0xe4, 0x34, 0xff, 	\
> +		0xf5, 0x0d, 0xe4, 0xf5, 0x09, 0xc3, 0xe5, 0x09, 	\
> +		0x95, 0x0e, 0xe4, 0x95, 0x0d, 0x50, 0x10, 0x90, 	\
> +		0xc0, 0x84, 0xe0, 0xff, 0x74, 0x2a, 0x25, 0x09, 	\
> +		0xf8, 0xa6, 0x07, 0x05, 0x09, 0x80, 0xe6, 0x7b, 	\
> +		0x00, 0x7a, 0x00, 0x79, 0x2a, 0x85, 0x0e, 0x16, 	\
> +		0xad, 0x0b, 0xaf, 0x0a, 0x12, 0x08, 0xec, 0x02, 	\
> +		0x02, 0xd1, 0x90, 0xc0, 0x84, 0x74, 0x55, 0xf0, 	\
> +		0xe0, 0xf5, 0x0a, 0xe0, 0xf5, 0x0b, 0xe0, 0x75, 	\
> +		0x0d, 0x00, 0xf5, 0x0e, 0x7b, 0x00, 0x7a, 0x00, 	\
> +		0x79, 0x22, 0xf5, 0x16, 0xad, 0x0b, 0xaf, 0x0a, 	\
> +		0x12, 0x06, 0x51, 0xe4, 0xf5, 0x09, 0xc3, 0xe5, 	\
> +		0x09, 0x95, 0x0e, 0xe4, 0x95, 0x0d, 0x50, 0x0e, 	\
> +		0x74, 0x22, 0x25, 0x09, 0xf8, 0xe6, 0x90, 0xc0, 	\
> +		0x84, 0xf0, 0x05, 0x09, 0x80, 0xe8, 0x02, 0x02, 	\
> +		0x56, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xc3, 0xe5, 	\
> +		0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 0x00, 0x50, 	\
> +		0x21, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 0x0a, 0xe0, 	\
> +		0xf5, 0x0b, 0xe0, 0xf5, 0x2a, 0xfb, 0xad, 0x0b, 	\
> +		0xaf, 0x0a, 0x12, 0x0a, 0x7f}
> +
> +#define FWP3	{\
> +		0x02, 0xf9, 0x4a, 0x74, 0x03, 0x25, 0x0e, 0xf5, 	\
> +		0x0e, 0xe4, 0x35, 0x0d, 0xf5, 0x0d, 0x80, 0xd4, 	\
> +		0x02, 0x02, 0xd1, 0x90, 0xc0, 0x84, 0x74, 0x55, 	\
> +		0xf0, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 0xc3, 0xe5, 	\
> +		0x0e, 0x95, 0x10, 0xe5, 0x0d, 0x94, 0x00, 0x50, 	\
> +		0x24, 0x90, 0xc0, 0x84, 0xe0, 0xf5, 0x0a, 0xe0, 	\
> +		0xf5, 0x0b, 0xfd, 0xaf, 0x0a, 0x12, 0x08, 0x92, 	\
> +		0x8f, 0x22, 0x90, 0xc0, 0x84, 0xe5, 0x22, 0xf0, 	\
> +		0x74, 0x02, 0x25, 0x0e, 0xf5, 0x0e, 0xe4, 0x35, 	\
> +		0x0d, 0xf5, 0x0d, 0x80, 0xd1, 0x80, 0x15, 0x90, 	\
> +		0xc0, 0x84, 0x74, 0x55, 0xf0, 0xe0, 0xf5, 0x0a, 	\
> +		0xff, 0x12, 0x0b, 0x7e, 0x8f, 0x22, 0x90, 0xc0, 	\
> +		0x84, 0xe5, 0x22, 0xf0, 0x90, 0xc0, 0x0b, 0x74, 	\
> +		0x02, 0xf0, 0x90, 0xc0, 0x0f, 0xf0, 0x22, 0xe4, 	\
> +		0xf5, 0x3b, 0xf5, 0x3c, 0x7b, 0xff, 0x7a, 0x0b, 	\
> +		0x79, 0x0f, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x0b, 	\
> +		0xd9, 0x02, 0x03, 0x47, 0x90, 0xc0, 0x84, 0xe0, 	\
> +		0xf5, 0x0c, 0x70, 0x04, 0xc2, 0x83, 0x80, 0x02, 	\
> +		0xd2, 0x83, 0x02, 0x02, 0xd1, 0x90, 0xc0, 0x84, 	\
> +		0xe0, 0xf5, 0x09, 0xe4, 0xf5, 0x0d, 0xf5, 0x0e, 	\
> +		0xc3, 0xe5, 0x0e, 0x95, 0x09, 0xe5, 0x0d, 0x94, 	\
> +		0x00, 0x50, 0x34, 0xc2, 0xb7, 0xd2, 0xb6, 0xe4, 	\
> +		0xf5, 0x0b, 0x7f, 0xc8, 0x12, 0x05, 0x9e, 0x05, 	\
> +		0x0b, 0xe5, 0x0b, 0xc3, 0x94, 0xc8, 0x40, 0xf2, 	\
> +		0xd2, 0xb7, 0xc2, 0xb6, 0xe4, 0xf5, 0x0b, 0x7f, 	\
> +		0xc8, 0x12, 0x05, 0x9e, 0x05, 0x0b, 0xe5, 0x0b, 	\
> +		0xc3, 0x94, 0xc8, 0x40, 0xf2, 0x05, 0x0e, 0xe5, 	\
> +		0x0e, 0x70, 0xc5, 0x05, 0x0d, 0x80, 0xc1, 0x90, 	\
> +		0xc0, 0x0b, 0x74, 0x02, 0x80, 0x52, 0x90, 0xc0, 	\
> +		0x36, 0x74, 0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x16, 0xf0, 0x74, 0x76, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x96, 0xf0, 0x90, 0xbb}
> +
> +
> +#define FWP4	{\
> +		0x02, 0xf9, 0xc0, 0x98, 0x74, 0x66, 0xf0, 0x90, 	\
> +		0xc0, 0x84, 0xe0, 0xf5, 0x0c, 0xe4, 0xf5, 0x0d, 	\
> +		0xf5, 0x0e, 0xc3, 0xe5, 0x0e, 0x95, 0x0c, 0xe5, 	\
> +		0x0d, 0x94, 0x00, 0x50, 0x14, 0x90, 0xc0, 0x88, 	\
> +		0xe0, 0xf5, 0x0a, 0x90, 0xc0, 0x98, 0xf0, 0x05, 	\
> +		0x0e, 0xe5, 0x0e, 0x70, 0xe5, 0x05, 0x0d, 0x80, 	\
> +		0xe1, 0x90, 0xc0, 0x0b, 0x74, 0x02, 0xf0, 0x90, 	\
> +		0xc0, 0x13, 0xf0, 0x90, 0xc0, 0x37, 0xf0, 0x90, 	\
> +		0xc0, 0x84, 0x74, 0x88, 0x80, 0x52, 0x90, 0xc0, 	\
> +		0x56, 0x74, 0x8c, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x1a, 0xf0, 0x74, 0x7a, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x9a, 0xf0, 0x90, 0xc0, 0x0b, 0x74, 0x02, 	\
> +		0xf0, 0x90, 0xc0, 0x84, 0x74, 0x88, 0xf0, 0x90, 	\
> +		0xc0, 0x0f, 0x74, 0x02, 0xf0, 0xd2, 0x04, 0x22, 	\
> +		0x90, 0xc0, 0x0b, 0x74, 0x02, 0xf0, 0x90, 0xc0, 	\
> +		0x84, 0x74, 0x88, 0xf0, 0x90, 0xc0, 0x0f, 0x74, 	\
> +		0x02, 0xf0, 0x7f, 0xc8, 0x12, 0x05, 0xb9, 0x90, 	\
> +		0xff, 0xff, 0xe4, 0xf0, 0x22, 0x90, 0xc0, 0x0b, 	\
> +		0x74, 0x02, 0xf0, 0x90, 0xc0, 0x84, 0x74, 0x77, 	\
> +		0xf0, 0x90, 0xc0, 0x0f, 0x74, 0x02, 0xf0, 0x22, 	\
> +		0xe4, 0xff, 0xfe, 0xf5, 0x0b, 0x20, 0xb2, 0x07, 	\
> +		0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x80, 0xf6, 0xc3, 	\
> +		0xef, 0x94, 0x28, 0xee, 0x94, 0x23, 0x50, 0x03, 	\
> +		0x02, 0x04, 0x76, 0xd3, 0xef, 0x94, 0xc8, 0xee, 	\
> +		0x94, 0x32, 0x40, 0x03, 0x02, 0x04, 0x76, 0xe4, 	\
> +		0xfe, 0xff, 0x30, 0xb2, 0x07, 0x0f, 0xbf, 0x00, 	\
> +		0x01, 0x0e, 0x80, 0xf6, 0xc3, 0xef, 0x94, 0x94, 	\
> +		0xee, 0x94, 0x11, 0x50, 0x03, 0x02, 0x04, 0x76, 	\
> +		0xd3, 0xef, 0x94, 0x4c, 0xee, 0x94, 0x1d, 0x40, 	\
> +		0x03, 0x02, 0x04, 0x76, 0xe4, 0xfe, 0x7f, 0x04, 	\
> +		0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x03, 0x02, 0x04, 	\
> +		0x76, 0xe4, 0xf5, 0x0a, 0x39}
> +
> +#define FWP5	{\
> +		0x02, 0xf9, 0xe4, 0xf5, 0x09, 0x05, 0x0b, 0x30, 	\
> +		0xb2, 0xfd, 0x74, 0x48, 0x25, 0x0a, 0xf8, 0xc0, 	\
> +		0x00, 0xe6, 0xc3, 0x13, 0xd0, 0x00, 0xf6, 0x7f, 	\
> +		0x06, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x05, 0x7f, 	\
> +		0x04, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x05, 0x7f, 	\
> +		0x02, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x05, 0x7f, 	\
> +		0x06, 0x12, 0x0c, 0xbc, 0x30, 0xb2, 0x07, 0x7f, 	\
> +		0x08, 0x12, 0x0c, 0xbc, 0x80, 0x09, 0x74, 0x48, 	\
> +		0x25, 0x0a, 0xf8, 0xe6, 0x44, 0x80, 0xf6, 0x20, 	\
> +		0xb2, 0xfd, 0x05, 0x09, 0xe5, 0x09, 0xc3, 0x94, 	\
> +		0x08, 0x40, 0xb2, 0x05, 0x0a, 0xe5, 0x0a, 0xc3, 	\
> +		0x94, 0x04, 0x40, 0xa6, 0xe5, 0x0b, 0x64, 0x20, 	\
> +		0x70, 0x2e, 0xf5, 0x0b, 0xe5, 0x4a, 0x25, 0x4b, 	\
> +		0xff, 0xe4, 0x33, 0xfe, 0xef, 0xf4, 0x4e, 0x70, 	\
> +		0x1f, 0xd2, 0x03, 0x75, 0x4c, 0xaa, 0x75, 0x47, 	\
> +		0x04, 0xf5, 0x0a, 0x74, 0x48, 0x25, 0x0a, 0xf8, 	\
> +		0xe6, 0xff, 0x74, 0x3f, 0x25, 0x0a, 0xf8, 0xa6, 	\
> +		0x07, 0x05, 0x0a, 0xe5, 0x0a, 0xb4, 0x04, 0xeb, 	\
> +		0x22, 0x90, 0xc1, 0xa3, 0x74, 0x10, 0xf0, 0x90, 	\
> +		0xc0, 0x0e, 0x74, 0x88, 0xf0, 0x90, 0xc1, 0xa2, 	\
> +		0x74, 0x11, 0xf0, 0x74, 0x71, 0xf0, 0x90, 0xc1, 	\
> +		0xa8, 0x74, 0x31, 0xf0, 0x90, 0xc0, 0x36, 0x74, 	\
> +		0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x16, 0xf0, 	\
> +		0x74, 0x76, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 0x36, 	\
> +		0xf0, 0x90, 0xc0, 0x0a, 0x74, 0x88, 0xf0, 0x90, 	\
> +		0xc1, 0xa2, 0x74, 0x01, 0xf0, 0x74, 0x61, 0xf0, 	\
> +		0x90, 0xc1, 0xa8, 0x74, 0x21, 0xf0, 0x90, 0xc0, 	\
> +		0x12, 0x74, 0x8b, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x02, 0xf0, 0x74, 0x62, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x22, 0xf0, 0x90, 0xc0, 0x3e, 0x74, 0x8b, 	\
> +		0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x17, 0xf0, 0x74, 	\
> +		0x77, 0xf0, 0x90, 0xc1, 0x1b}
> +
> +#define FWP6	{\
> +		0x02, 0xf9, 0xa8, 0x74, 0x37, 0xf0, 0x90, 0xc0, 	\
> +		0x56, 0x74, 0x8c, 0xf0, 0x90, 0xc1, 0xa2, 0x74, 	\
> +		0x1a, 0xf0, 0x74, 0x7a, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x3a, 0xf0, 0x90, 0xc0, 0x1a, 0x74, 0x8b, 	\
> +		0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x03, 0xf0, 0x74, 	\
> +		0x63, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 0x23, 0xf0, 	\
> +		0x90, 0xc0, 0x52, 0x74, 0x88, 0xf0, 0x90, 0xc1, 	\
> +		0xa2, 0x74, 0x0a, 0xf0, 0x74, 0x6a, 0xf0, 0x90, 	\
> +		0xc1, 0xa8, 0x74, 0x2a, 0xf0, 0x22, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 	\
> +		0x12, 0x05, 0xb9, 0x12, 0x05, 0xb9, 0x12, 0x05, 	\
> +		0xb9, 0xe4, 0xfe, 0xee, 0xc3, 0x9f, 0x50, 0x04, 	\
> +		0x00, 0x0e, 0x80, 0xf7, 0x22, 0x78, 0x7f, 0xe4, 	\
> +		0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x54, 0x02, 0x06, 	\
> +		0x0c, 0x02, 0x07, 0x53, 0xe4, 0x93, 0xa3, 0xf8, 	\
> +		0xe4, 0x93, 0xa3, 0x40, 0xe8}
> +
> +#define FWP7	{\
> +		0x02, 0xf9, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 	\
> +		0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 	\
> +		0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 	\
> +		0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 	\
> +		0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 	\
> +		0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 	\
> +		0x40, 0x80, 0x90, 0x0c, 0x3f, 0xe4, 0x7e, 0x01, 	\
> +		0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 	\
> +		0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 	\
> +		0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 	\
> +		0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 	\
> +		0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 	\
> +		0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 	\
> +		0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 	\
> +		0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0x8d, 	\
> +		0x12, 0x8b, 0x13, 0x8a, 0x14, 0x89, 0x15, 0xef, 	\
> +		0x54, 0xfe, 0xf5, 0x18, 0x12, 0x0c, 0x5c, 0xaf, 	\
> +		0x18, 0x12, 0x09, 0xf5, 0x20, 0x02, 0x02, 0x80, 	\
> +		0x69, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0xaf, 0x12, 	\
> +		0x12, 0x09, 0xf5, 0x7f, 0x14, 0x12, 0x05, 0xb9, 	\
> +		0x20, 0x02, 0x02, 0x80, 0x55, 0x12, 0x0c, 0x5c, 	\
> +		0xe5, 0x18, 0x04, 0xff, 0x12, 0x09, 0xf5, 0x20, 	\
> +		0x02, 0x02, 0x80, 0x46, 0xe4, 0xf5, 0x17, 0xe5, 	\
> +		0x16, 0x14, 0xff, 0xe5, 0x17, 0xc3, 0x9f, 0x50, 	\
> +		0x1c, 0x12, 0x0a, 0xd2, 0xab, 0x13, 0xaa, 0x14, 	\
> +		0xa9, 0x15, 0x85, 0x17, 0x82, 0x75, 0x83, 0x00, 	\
> +		0xef, 0x12, 0x07, 0x05, 0xc2, 0x06, 0x12, 0x0c, 	\
> +		0x78, 0x05, 0x17, 0x80, 0xda, 0x12, 0x0a, 0xd2, 	\
> +		0xab, 0x13, 0xaa, 0x14, 0xa9, 0x15, 0x85, 0x17, 	\
> +		0x82, 0x75, 0x83, 0x00, 0xef, 0x12, 0x07, 0x05, 	\
> +		0xd2, 0x06, 0x12, 0x0c, 0x78, 0x7f, 0x14, 0x12, 	\
> +		0x05, 0xb9, 0x12, 0x0c, 0x29}
> +
> +#define FWP8	{\
> +		0x02, 0xf9, 0x94, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 	\
> +		0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 	\
> +		0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 	\
> +		0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 	\
> +		0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 	\
> +		0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 	\
> +		0x22, 0xf8, 0xbb, 0x01, 0x0d, 0xe5, 0x82, 0x29, 	\
> +		0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe8, 	\
> +		0xf0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xc8, 	\
> +		0xf6, 0x22, 0xbb, 0xfe, 0x05, 0xe9, 0x25, 0x82, 	\
> +		0xc8, 0xf2, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 	\
> +		0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 	\
> +		0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 	\
> +		0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 	\
> +		0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 	\
> +		0xdf, 0x8a, 0x83, 0x89, 0x82, 0xe4, 0x73, 0x12, 	\
> +		0x0c, 0x01, 0x12, 0x0c, 0xa9, 0x7b, 0xff, 0x7a, 	\
> +		0x0b, 0x79, 0xb0, 0x7d, 0x28, 0x7c, 0x00, 0x12, 	\
> +		0x0b, 0x49, 0x12, 0x00, 0x16, 0x50, 0x11, 0xc2, 	\
> +		0x85, 0xc2, 0x00, 0x90, 0xc1, 0xa8, 0x74, 0x91, 	\
> +		0xf0, 0x12, 0x00, 0x26, 0xd2, 0x85, 0x80, 0xea, 	\
> +		0x20, 0xb2, 0x0c, 0xc2, 0xaa, 0x12, 0x03, 0x8c, 	\
> +		0xd2, 0xaa, 0x12, 0x08, 0x2c, 0x80, 0xdb, 0xe5, 	\
> +		0x3e, 0x24, 0x38, 0xff, 0xe5, 0x3d, 0x34, 0xff, 	\
> +		0xfe, 0xef, 0xb5, 0x3c, 0xcd, 0xee, 0xb5, 0x3b, 	\
> +		0xc9, 0x75, 0x2a, 0x1c, 0x75, 0x2b, 0x0e, 0x12, 	\
> +		0x08, 0x8e, 0x8f, 0x22, 0xe5, 0x22, 0x30, 0xe4, 	\
> +		0x04, 0xc2, 0x85, 0x80, 0x02, 0xd2, 0x85, 0x75, 	\
> +		0x2b, 0x43, 0x12, 0x08, 0x8e, 0x8f, 0x23, 0x75, 	\
> +		0x2b, 0x1c, 0x12, 0x08, 0x8e, 0x8f, 0x24, 0x80, 	\
> +		0xa1, 0x90, 0x90, 0x00, 0x74, 0x01, 0xf0, 0xe4, 	\
> +		0xa3, 0xf0, 0xa3, 0xf0, 0xdc}
> +
> +
> +#define FWP9	{\
> +		0x02, 0xf9, 0xa3, 0xf0, 0xa3, 0x74, 0x03, 0xf0, 	\
> +		0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 	\
> +		0x74, 0x05, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 	\
> +		0xa3, 0xf0, 0xa3, 0x74, 0x07, 0xf0, 0xe4, 0xa3, 	\
> +		0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x09, 	\
> +		0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 	\
> +		0xa3, 0x74, 0x0b, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 	\
> +		0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x0d, 0xf0, 0xe4, 	\
> +		0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 	\
> +		0x0f, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 	\
> +		0xf0, 0xa3, 0x74, 0xb5, 0xf0, 0xa3, 0x74, 0x06, 	\
> +		0xf0, 0xa3, 0x74, 0xbc, 0xf0, 0x22, 0xe5, 0x47, 	\
> +		0x60, 0x5d, 0xc2, 0xaa, 0x75, 0xa0, 0x01, 0x85, 	\
> +		0x4c, 0x33, 0x85, 0x47, 0x34, 0xe4, 0xff, 0xef, 	\
> +		0xc3, 0x95, 0x47, 0x50, 0x0f, 0x74, 0x3f, 0x2f, 	\
> +		0xf8, 0xe6, 0xfe, 0x74, 0x35, 0x2f, 0xf8, 0xa6, 	\
> +		0x06, 0x0f, 0x80, 0xeb, 0x75, 0x21, 0x08, 0xe4, 	\
> +		0xf5, 0x47, 0x20, 0x00, 0x2d, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x9a, 0xf0, 0x90, 0xc0, 0xa8, 0xe5, 0x33, 	\
> +		0xf0, 0xe5, 0x34, 0xf0, 0xe5, 0x35, 0xf0, 0xe5, 	\
> +		0x36, 0xf0, 0xe5, 0x37, 0xf0, 0xe5, 0x38, 0xf0, 	\
> +		0xe5, 0x39, 0xf0, 0xe5, 0x3a, 0xf0, 0x90, 0xc0, 	\
> +		0x57, 0x74, 0x02, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 	\
> +		0x3a, 0xf0, 0xd2, 0xaa, 0x75, 0xa0, 0x02, 0x22, 	\
> +		0xad, 0x2b, 0xaf, 0x2a, 0x8d, 0x11, 0xef, 0x54, 	\
> +		0xfe, 0xf5, 0x13, 0x12, 0x0c, 0x5c, 0x7f, 0x14, 	\
> +		0x12, 0x05, 0xb9, 0xaf, 0x13, 0x12, 0x09, 0xf5, 	\
> +		0x20, 0x02, 0x02, 0x80, 0x21, 0x7f, 0x14, 0x12, 	\
> +		0x05, 0xb9, 0xaf, 0x11, 0x12, 0x09, 0xf5, 0x20, 	\
> +		0x02, 0x02, 0x80, 0x12, 0x7f, 0x14, 0x12, 0x05, 	\
> +		0xb9, 0x12, 0x0c, 0x5c, 0xe5, 0x13, 0x04, 0xff, 	\
> +		0x12, 0x09, 0xf5, 0x20, 0x9b}
> +
> +
> +#define FWP10	{\
> +		0x02, 0xf9, 0x02, 0x06, 0x12, 0x0c, 0x94, 0x7f, 	\
> +		0x00, 0x22, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x0a, 0xd2, 0x8f, 0x12, 0xd2, 0x06, 0x12, 0x0c, 	\
> +		0x78, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x0c, 	\
> +		0x94, 0xaf, 0x12, 0x22, 0x8d, 0x12, 0x8b, 0x13, 	\
> +		0x8a, 0x14, 0x89, 0x15, 0xef, 0x54, 0xfe, 0xf5, 	\
> +		0x18, 0x12, 0x0c, 0x5c, 0xaf, 0x18, 0x12, 0x09, 	\
> +		0xf5, 0x20, 0x02, 0x02, 0x80, 0x3f, 0x7f, 0x14, 	\
> +		0x12, 0x05, 0xb9, 0xaf, 0x12, 0x12, 0x09, 0xf5, 	\
> +		0x20, 0x02, 0x02, 0x80, 0x30, 0x7f, 0x14, 0x12, 	\
> +		0x05, 0xb9, 0xe4, 0xf5, 0x17, 0xe5, 0x17, 0xc3, 	\
> +		0x95, 0x16, 0x50, 0x17, 0xab, 0x13, 0xaa, 0x14, 	\
> +		0xa9, 0x15, 0x85, 0x17, 0x82, 0x75, 0x83, 0x00, 	\
> +		0x12, 0x06, 0xd8, 0xff, 0x12, 0x09, 0xf5, 0x05, 	\
> +		0x17, 0x80, 0xe2, 0x20, 0x02, 0x02, 0x80, 0x05, 	\
> +		0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x0c, 0x94, 	\
> +		0x22, 0x05, 0x3a, 0x30, 0x04, 0x50, 0xe5, 0x21, 	\
> +		0x90, 0xc1, 0xa8, 0x70, 0x1c, 0x74, 0x9a, 0xf0, 	\
> +		0x90, 0xc0, 0xa8, 0x74, 0xbb, 0xf0, 0x74, 0x03, 	\
> +		0xf0, 0xe5, 0x22, 0xf0, 0xe5, 0x23, 0xf0, 0xe5, 	\
> +		0x24, 0xf0, 0xe5, 0x25, 0xf0, 0xe5, 0x26, 0x80, 	\
> +		0x1a, 0x74, 0x9a, 0xf0, 0x90, 0xc0, 0xa8, 0xe5, 	\
> +		0x33, 0xf0, 0xe5, 0x34, 0xf0, 0xe5, 0x35, 0xf0, 	\
> +		0xe5, 0x36, 0xf0, 0xe5, 0x37, 0xf0, 0xe5, 0x38, 	\
> +		0xf0, 0xe5, 0x39, 0xf0, 0xe5, 0x3a, 0xf0, 0x90, 	\
> +		0xc0, 0x57, 0x74, 0x02, 0xf0, 0x90, 0xc1, 0xa8, 	\
> +		0x74, 0x3a, 0xf0, 0xe4, 0xf5, 0x21, 0x22, 0xc0, 	\
> +		0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 	\
> +		0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x01, 	\
> +		0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 	\
> +		0xc0, 0x06, 0xc0, 0x07, 0xc2, 0x8d, 0x05, 0x4f, 	\
> +		0xe5, 0x4f, 0x70, 0x02, 0xf9}
> +
> +
> +#define FWP11	{\
> +		0x02, 0xf9, 0x05, 0x4e, 0xc3, 0x95, 0x54, 0xe5, 	\
> +		0x4e, 0x95, 0x53, 0x40, 0x0b, 0xc2, 0x8c, 0xc2, 	\
> +		0xa9, 0xaa, 0x51, 0xa9, 0x52, 0x12, 0x07, 0x4d, 	\
> +		0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 	\
> +		0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 	\
> +		0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 	\
> +		0xd0, 0xe0, 0x32, 0x8f, 0x19, 0xe4, 0xf5, 0x1a, 	\
> +		0xaf, 0x1a, 0xe5, 0x19, 0xa8, 0x07, 0x08, 0x80, 	\
> +		0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x30, 0xe7, 0x04, 	\
> +		0xd2, 0x80, 0x80, 0x02, 0xc2, 0x80, 0x7f, 0x08, 	\
> +		0x12, 0x05, 0xb9, 0xd2, 0x81, 0x7f, 0x0a, 0x12, 	\
> +		0x05, 0xb9, 0xc2, 0x81, 0x05, 0x1a, 0xe5, 0x1a, 	\
> +		0xc3, 0x94, 0x08, 0x40, 0xd3, 0x7f, 0x02, 0x12, 	\
> +		0x05, 0xb9, 0xd2, 0x80, 0x7f, 0x0a, 0x12, 0x05, 	\
> +		0xb9, 0xd2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 	\
> +		0x30, 0x80, 0x04, 0xc2, 0x02, 0x80, 0x02, 0xd2, 	\
> +		0x02, 0xc2, 0x81, 0x7f, 0x0a, 0x02, 0x05, 0xb9, 	\
> +		0x8d, 0x11, 0x8b, 0x12, 0xef, 0x54, 0xfe, 0xf5, 	\
> +		0x13, 0x12, 0x0c, 0x5c, 0x7f, 0x14, 0x12, 0x05, 	\
> +		0xb9, 0xaf, 0x13, 0x12, 0x09, 0xf5, 0x20, 0x02, 	\
> +		0x02, 0x80, 0x1c, 0x7f, 0x14, 0x12, 0x05, 0xb9, 	\
> +		0xaf, 0x11, 0x12, 0x09, 0xf5, 0x20, 0x02, 0x02, 	\
> +		0x80, 0x0d, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0xaf, 	\
> +		0x12, 0x12, 0x09, 0xf5, 0x20, 0x02, 0x03, 0x02, 	\
> +		0x0c, 0x94, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x0c, 0x94, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x22, 	\
> +		0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 	\
> +		0x75, 0xd0, 0x00, 0xc0, 0x06, 0xc0, 0x07, 0xc2, 	\
> +		0x8b, 0x05, 0x3c, 0xe5, 0x3c, 0x70, 0x02, 0x05, 	\
> +		0x3b, 0x30, 0x00, 0x17, 0xc3, 0x95, 0x3e, 0xe5, 	\
> +		0x3b, 0x95, 0x3d, 0x40, 0x0e, 0x75, 0x3b, 0x00, 	\
> +		0x75, 0x3c, 0x00, 0x7f, 0xbc}
> +
> +
> +#define FWP12	{\
> +		0x02, 0xf9, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x09, 	\
> +		0x49, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0xd0, 0xd0, 	\
> +		0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xe4, 0xf5, 	\
> +		0x19, 0xd2, 0x80, 0xf5, 0x1a, 0x7f, 0x01, 0x12, 	\
> +		0x05, 0xb9, 0xc2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 	\
> +		0xb9, 0xd2, 0x81, 0x7f, 0x08, 0x12, 0x05, 0xb9, 	\
> +		0xe5, 0x19, 0x25, 0xe0, 0xf5, 0x19, 0x30, 0x80, 	\
> +		0x02, 0x05, 0x19, 0x7f, 0x01, 0x12, 0x05, 0xb9, 	\
> +		0x05, 0x1a, 0xe5, 0x1a, 0xc3, 0x94, 0x08, 0x40, 	\
> +		0xd4, 0xc2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 	\
> +		0xaf, 0x19, 0x22, 0x85, 0x3b, 0x3d, 0x85, 0x3c, 	\
> +		0x3e, 0x90, 0xc0, 0xa8, 0x74, 0xcc, 0xf0, 0x74, 	\
> +		0x02, 0xf0, 0xe5, 0x3d, 0xf0, 0xe5, 0x3e, 0xf0, 	\
> +		0xe4, 0xf0, 0xf0, 0xf0, 0xf0, 0x90, 0xc0, 0x57, 	\
> +		0x74, 0x02, 0xf0, 0x90, 0xc0, 0x36, 0x74, 0x8b, 	\
> +		0xf0, 0x90, 0xc1, 0xa2, 0x74, 0x16, 0xf0, 0x74, 	\
> +		0x76, 0xf0, 0x90, 0xc1, 0xa8, 0x74, 0x36, 0xf0, 	\
> +		0xd2, 0x00, 0xc2, 0x85, 0x22, 0x8b, 0x09, 0x8a, 	\
> +		0x0a, 0x89, 0x0b, 0x8c, 0x0c, 0x8d, 0x0d, 0xe4, 	\
> +		0xfd, 0xfc, 0xc3, 0xed, 0x95, 0x0d, 0xe5, 0x0c, 	\
> +		0x64, 0x80, 0xf8, 0xec, 0x64, 0x80, 0x98, 0x50, 	\
> +		0x18, 0xab, 0x09, 0xaa, 0x0a, 0xa9, 0x0b, 0x8d, 	\
> +		0x82, 0x8c, 0x83, 0x12, 0x06, 0xd8, 0xff, 0x12, 	\
> +		0x00, 0x03, 0x0d, 0xbd, 0x00, 0x01, 0x0c, 0x80, 	\
> +		0xd9, 0x22, 0x8f, 0x11, 0x12, 0x0c, 0x5c, 0x7f, 	\
> +		0x14, 0x12, 0x05, 0xb9, 0xaf, 0x11, 0x12, 0x09, 	\
> +		0xf5, 0x20, 0x02, 0x06, 0x12, 0x0c, 0x94, 0x7f, 	\
> +		0x00, 0x22, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 	\
> +		0x0a, 0xd2, 0x8f, 0x12, 0xd2, 0x06, 0x12, 0x0c, 	\
> +		0x78, 0x7f, 0x14, 0x12, 0x05, 0xb9, 0x12, 0x0c, 	\
> +		0x94, 0xaf, 0x12, 0x22, 0x54, 0x44, 0x20, 0x69, 	\
> +		0x6e, 0x69, 0x74, 0x20, 0x2d}
> +
> +
> +#define FWP13	{\
> +		0x02, 0xf9, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 	\
> +		0x3a, 0x65, 0x78, 0x63, 0x75, 0x74, 0x65, 0x20, 	\
> +		0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 	\
> +		0x69, 0x6e, 0x20, 0x70, 0x64, 0x72, 0x61, 0x6d, 	\
> +		0x0d, 0x0a, 0x00, 0xc2, 0xaf, 0xc2, 0x8c, 0xe5, 	\
> +		0x89, 0x54, 0xf0, 0x44, 0x02, 0xf5, 0x89, 0x75, 	\
> +		0x8c, 0x87, 0x75, 0x8a, 0x87, 0x8e, 0x53, 0x8f, 	\
> +		0x54, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x8b, 0x50, 	\
> +		0x8a, 0x51, 0x89, 0x52, 0xd2, 0xa9, 0xd2, 0x8c, 	\
> +		0xd2, 0xaf, 0x22, 0x90, 0xc1, 0xa3, 0x74, 0x50, 	\
> +		0xf0, 0x7f, 0xc8, 0x12, 0x05, 0x26, 0x12, 0x05, 	\
> +		0x26, 0x74, 0x10, 0xf0, 0x90, 0x80, 0x90, 0x74, 	\
> +		0x05, 0xf0, 0x12, 0x07, 0xc5, 0x12, 0x04, 0x77, 	\
> +		0x02, 0x0c, 0xfa, 0x75, 0x98, 0x50, 0x75, 0x89, 	\
> +		0x20, 0xef, 0x70, 0x05, 0x53, 0x87, 0x7f, 0x80, 	\
> +		0x03, 0x43, 0x87, 0x80, 0x8d, 0x8d, 0xd2, 0x8e, 	\
> +		0xc2, 0x98, 0xc2, 0x99, 0xd2, 0xac, 0xd2, 0xaf, 	\
> +		0x22, 0xc1, 0x81, 0x02, 0x3b, 0x00, 0x00, 0x02, 	\
> +		0x3d, 0x03, 0xe8, 0x01, 0x47, 0x00, 0x01, 0x21, 	\
> +		0x00, 0xc1, 0x04, 0xc1, 0x00, 0x02, 0x53, 0x00, 	\
> +		0x00, 0x02, 0x4e, 0x00, 0x00, 0x00, 0xd2, 0x80, 	\
> +		0x7f, 0x14, 0x12, 0x05, 0xb9, 0xd2, 0x81, 0x7f, 	\
> +		0x14, 0x12, 0x05, 0xb9, 0xc2, 0x80, 0x7f, 0x14, 	\
> +		0x12, 0x05, 0xb9, 0xc2, 0x81, 0x7f, 0x14, 0x02, 	\
> +		0x05, 0xb9, 0x20, 0x06, 0x04, 0xc2, 0x80, 0x80, 	\
> +		0x02, 0xd2, 0x80, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 	\
> +		0xd2, 0x81, 0x7f, 0x0a, 0x12, 0x05, 0xb9, 0xc2, 	\
> +		0x81, 0x7f, 0x0a, 0x02, 0x05, 0xb9, 0xc2, 0x80, 	\
> +		0x7f, 0x14, 0x12, 0x05, 0xb9, 0xd2, 0x81, 0x7f, 	\
> +		0x14, 0x12, 0x05, 0xb9, 0xd2, 0x80, 0x7f, 0x14, 	\
> +		0x02, 0x05, 0xb9, 0x90, 0x80, 0x90, 0x74, 0x05, 	\
> +		0xf0, 0xe4, 0xf5, 0xa0, 0x07}
> +
> +#define FWCT	{\
> +		0x82, 0x4e, 0x12, 0x0c, 0xfa, 0xd2, 0x8a, 0xd2, 	\
> +		0xaa, 0xd2, 0xaf, 0x22, 0xef, 0xd3, 0x94, 0x00, 	\
> +		0x40, 0x09, 0xe4, 0xfe, 0x0e, 0xbe, 0x76, 0xfc, 	\
> +		0x1f, 0x80, 0xf1, 0x22, 0xc2, 0xaf, 0xc2, 0xac, 	\
> +		0xc2, 0x98, 0xc2, 0x99, 0x75, 0x98, 0x40, 0xc2, 	\
> +		0xa9, 0xc2, 0x8e, 0x22, 0x30, 0x99, 0x04, 0xd2, 	\
> +		0x01, 0xc2, 0x99, 0x30, 0x98, 0x05, 0x85, 0x99, 	\
> +		0x08, 0xc2, 0x98, 0x32, 0xc2, 0x8c, 0xc2, 0xa9, 	\
> +		0x75, 0x50, 0xff, 0x75, 0x51, 0x00, 0x75, 0x52, 	\
> +		0x0e, 0x22, 0x7d, 0xf8, 0xe4, 0xff, 0x02, 0x0c, 	\
> +		0x21, 0xfd}

Binding the firmware binary inside the a GPL code violates GPL license. Instead, please
split the firmware into a firmware file, and use the request_firmware() to load it from
userspace.

We need also manufacturer's ack to distribute their firmwares in a binary form, or, if this
is not possible, we'll need some script to extract the firmare from the original driver.

> +
> +#define FWTRL	0xfd
> +#define FWCTL	0x52
> +#define FWF3L	0x0f
> +#define LME_FIRMWARE_D	{{FWTRL, FWF1}, 	\
> +			{FWTRL, FWF2}, 	\
> +			{FWF3L, FWF3}, 	\
> +			{FWTRL, FWP1}, 	\
> +			{FWTRL, FWP2}, 	\
> +			{FWTRL, FWP3}, 	\
> +			{FWTRL, FWP4}, 	\
> +			{FWTRL, FWP5}, 	\
> +			{FWTRL, FWP6}, 	\
> +			{FWTRL, FWP7}, 	\
> +			{FWTRL, FWP8}, 	\
> +			{FWTRL, FWP9}, 	\
> +			{FWTRL, FWP10}, 	\
> +			{FWTRL, FWP11}, 	\
> +			{FWTRL, FWP12}, 	\
> +			{FWTRL, FWP13}, 	\
> +			{FWCTL, FWCT} }
> +
> +struct lme_firmware_data {
> +	u8 length;
> +	u8 bulk_data[256];       /* Address */
> +};
> +
> +#endif
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] added support for DM040832731 DVB-S USB BOX - Correction
  2010-07-29 18:16 ` Mauro Carvalho Chehab
@ 2010-09-08 21:08   ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 4+ messages in thread
From: Mauro Carvalho Chehab @ 2010-09-08 21:08 UTC (permalink / raw)
  To: Malcolm Priestley; +Cc: linux-media

Em 29-07-2010 15:16, Mauro Carvalho Chehab escreveu:
> Em 16-07-2010 10:43, Malcolm Priestley escreveu:
>> DVB USB Driver for DM04 LME2510 + LG TDQY - P001F =(TDA8263 + TDA10086H)
>>
>> Corrected patch error.
>>
>> Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
> 
> Hi Malcom,
> 
> Please read the developers section of our Wiki page for instructions on how to submit
> a driver:
> 	http://linuxtv.org/wiki/index.php/Developer_Section
> 
> In special, you need to read what's inside "Submiting your work" in order to fix some
> troubles I identified on your driver.

Not sure why, but I lost the email where you submitted your new driver on my inbox. I got it
from patchwork and applied.

Em 08-09-2010 18:01, Mauro Carvalho Chehab escreveu:
> This is an automatic generated email to let you know that the following patch were queued at the 
> http://git.linuxtv.org/media-tree.git tree:
> 
> Subject: V4L/DVB: Support or LME2510(C) DM04/QQBOX USB DVB-S BOXES
> Author:  Malcolm Priestley <tvboxspy@gmail.com>
> Date:    Thu Sep 2 17:29:30 2010 -0300
> 
> DM04/QQBOX DVB-S USB BOX with LME2510C+SHARP:BS2F7HZ7395 or LME2510+LGTDQT-P001F tuner.
> 
> [mchehab@redhat.com: Fix merge conflicts/compilation and CodingStyle issues]

There were some API changes at USB, and a few trivial CodingStyle issues.

I didn't double checked if all those patchwork patches you've mentioned were applied. For sure
I've applied the other patch from you adding the frontend.

Please double check if everything is ok and ping me, if I missed something.

> Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
> 
>  Documentation/dvb/get_dvb_firmware    |   46 ++-
>  Documentation/dvb/lmedm04.txt         |   55 ++
>  drivers/media/IR/keymaps/Makefile     |    1 +
>  drivers/media/IR/keymaps/rc-lme2510.c |   68 +++
>  drivers/media/dvb/dvb-usb/Kconfig     |   11 +
>  drivers/media/dvb/dvb-usb/Makefile    |    3 +
>  drivers/media/dvb/dvb-usb/lmedm04.c   |  936 +++++++++++++++++++++++++++++++++
>  drivers/media/dvb/dvb-usb/lmedm04.h   |  187 +++++++
>  include/media/rc-map.h                |    1 +
>  9 files changed, 1307 insertions(+), 1 deletions(-)
> 
> ---
> 
> http://git.linuxtv.org/media-tree.git?a=commitdiff;h=0a11672a8a3431296ed99be16e7cb57bc004e080
> 
> diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
> index 350959f..59690de 100644
> --- a/Documentation/dvb/get_dvb_firmware
> +++ b/Documentation/dvb/get_dvb_firmware
> @@ -26,7 +26,8 @@ use IO::Handle;
>  		"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
>  		"or51211", "or51132_qam", "or51132_vsb", "bluebird",
>  		"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
> -		"af9015", "ngene", "az6027");
> +		"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
> +		"lme2510c_s7395_old");
>  
>  # Check args
>  syntax() if (scalar(@ARGV) != 1);
> @@ -584,6 +585,49 @@ sub az6027{
>  
>      $firmware;
>  }
> +
> +sub lme2510_lg {
> +    my $sourcefile = "LMEBDA_DVBS.sys";
> +    my $hash = "fc6017ad01e79890a97ec53bea157ed2";
> +    my $outfile = "dvb-usb-lme2510-lg.fw";
> +    my $hasho = "caa065d5fdbd2c09ad57b399bbf55cad";
> +
> +    checkstandard();
> +
> +    verify($sourcefile, $hash);
> +    extract($sourcefile, 4168, 3841, $outfile);
> +    verify($outfile, $hasho);
> +    $outfile;
> +}
> +
> +sub lme2510c_s7395 {
> +    my $sourcefile = "US2A0D.sys";
> +    my $hash = "b0155a8083fb822a3bd47bc360e74601";
> +    my $outfile = "dvb-usb-lme2510c-s7395.fw";
> +    my $hasho = "3a3cf1aeebd17b6ddc04cebe131e94cf";
> +
> +    checkstandard();
> +
> +    verify($sourcefile, $hash);
> +    extract($sourcefile, 37248, 3720, $outfile);
> +    verify($outfile, $hasho);
> +    $outfile;
> +}
> +
> +sub lme2510c_s7395_old {
> +    my $sourcefile = "LMEBDA_DVBS7395C.sys";
> +    my $hash = "7572ae0eb9cdf91baabd7c0ba9e09b31";
> +    my $outfile = "dvb-usb-lme2510c-s7395.fw";
> +    my $hasho = "90430c5b435eb5c6f88fd44a9d950674";
> +
> +    checkstandard();
> +
> +    verify($sourcefile, $hash);
> +    extract($sourcefile, 4208, 3881, $outfile);
> +    verify($outfile, $hasho);
> +    $outfile;
> +}
> +
>  # ---------------------------------------------------------------
>  # Utilities
>  
> diff --git a/Documentation/dvb/lmedm04.txt b/Documentation/dvb/lmedm04.txt
> new file mode 100644
> index 0000000..4bde457
> --- /dev/null
> +++ b/Documentation/dvb/lmedm04.txt
> @@ -0,0 +1,55 @@
> +To extract firmware for the DM04/QQBOX you need to copy the
> +following file(s) to this directory.
> +
> +for DM04+/QQBOX LME2510C (Sharp 7395 Tuner)
> +-------------------------------------------
> +
> +The Sharp 7395 driver can be found in windows/system32/driver
> +
> +US2A0D.sys (dated 17 Mar 2009)
> +
> +
> +and run
> +./get_dvb_firmware lme2510c_s7395
> +
> +	will produce
> +	dvb-usb-lme2510c-s7395.fw
> +
> +An alternative but older firmware can be found on the driver
> +disk DVB-S_EN_3.5A in BDADriver/driver
> +
> +LMEBDA_DVBS7395C.sys (dated 18 Jan 2008)
> +
> +and run
> +./get_dvb_firmware lme2510c_s7395_old
> +
> +	will produce
> +	dvb-usb-lme2510c-s7395.fw
> +
> +--------------------------------------------------------------------
> +
> +The LG firmware can be found on the driver
> +disk DM04+_5.1A[LG] in BDADriver/driver
> +
> +for DM04 LME2510 (LG Tuner)
> +---------------------------
> +
> +LMEBDA_DVBS.sys (dated 13 Nov 2007)
> +
> +and run
> +./get_dvb_firmware lme2510_lg
> +
> +	will produce
> +	dvb-usb-lme2510-lg.fw
> +
> +
> +Other LG firmware can be extracted manually from US280D.sys
> +only found in windows/system32/driver.
> +However, this firmware does not run very well under Windows
> +or with the Linux driver.
> +
> +dd if=US280D.sys ibs=1 skip=36856 count=3976 of=dvb-usb-lme2510-lg.fw
> +
> +---------------------------------------------------------------------
> +
> +Copy the firmware file(s) to /lib/firmware
> diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile
> index c032b9d..f755b21 100644
> --- a/drivers/media/IR/keymaps/Makefile
> +++ b/drivers/media/IR/keymaps/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
>  			rc-kworld-315u.o \
>  			rc-kworld-plus-tv-analog.o \
>  			rc-lirc.o \
> +			rc-lme2510.o \
>  			rc-manli.o \
>  			rc-msi-tvanywhere.o \
>  			rc-msi-tvanywhere-plus.o \
> diff --git a/drivers/media/IR/keymaps/rc-lme2510.c b/drivers/media/IR/keymaps/rc-lme2510.c
> new file mode 100644
> index 0000000..40dcf0b
> --- /dev/null
> +++ b/drivers/media/IR/keymaps/rc-lme2510.c
> @@ -0,0 +1,68 @@
> +/* LME2510 remote control
> + *
> + *
> + * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include <media/rc-map.h>
> +
> +
> +static struct ir_scancode lme2510_rc[] = {
> +	{ 0xba45, KEY_0 },
> +	{ 0xa05f, KEY_1 },
> +	{ 0xaf50, KEY_2 },
> +	{ 0xa25d, KEY_3 },
> +	{ 0xbe41, KEY_4 },
> +	{ 0xf50a, KEY_5 },
> +	{ 0xbd42, KEY_6 },
> +	{ 0xb847, KEY_7 },
> +	{ 0xb649, KEY_8 },
> +	{ 0xfa05, KEY_9 },
> +	{ 0xbc43, KEY_POWER },
> +	{ 0xb946, KEY_SUBTITLE },
> +	{ 0xf906, KEY_PAUSE },
> +	{ 0xfc03, KEY_MEDIA_REPEAT},
> +	{ 0xfd02, KEY_PAUSE },
> +	{ 0xa15e, KEY_VOLUMEUP },
> +	{ 0xa35c, KEY_VOLUMEDOWN },
> +	{ 0xf609, KEY_CHANNELUP },
> +	{ 0xe51a, KEY_CHANNELDOWN },
> +	{ 0xe11e, KEY_PLAY },
> +	{ 0xe41b, KEY_ZOOM },
> +	{ 0xa659, KEY_MUTE },
> +	{ 0xa55a, KEY_TV },
> +	{ 0xe718, KEY_RECORD },
> +	{ 0xf807, KEY_EPG },
> +	{ 0xfe01, KEY_STOP },
> +
> +};
> +
> +static struct rc_keymap lme2510_map = {
> +	.map = {
> +		.scan    = lme2510_rc,
> +		.size    = ARRAY_SIZE(lme2510_rc),
> +		.ir_type = IR_TYPE_UNKNOWN,
> +		.name    = RC_MAP_LME2510,
> +	}
> +};
> +
> +static int __init init_rc_lme2510_map(void)
> +{
> +	return ir_register_map(&lme2510_map);
> +}
> +
> +static void __exit exit_rc_lme2510_map(void)
> +{
> +	ir_unregister_map(&lme2510_map);
> +}
> +
> +module_init(init_rc_lme2510_map)
> +module_exit(exit_rc_lme2510_map)
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
> diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
> index c57f828..4734ec0 100644
> --- a/drivers/media/dvb/dvb-usb/Kconfig
> +++ b/drivers/media/dvb/dvb-usb/Kconfig
> @@ -347,3 +347,14 @@ config DVB_USB_AZ6027
>  	select DVB_STB6100 if !DVB_FE_CUSTOMISE
>  	help
>  	  Say Y here to support the AZ6027 device
> +
> +config DVB_USB_LME2510
> +	tristate "LME DM04/QQBOX DVB-S USB2.0 support"
> +	depends on DVB_USB
> +	select DVB_TDA10086 if !DVB_FE_CUSTOMISE
> +	select DVB_TDA826X if !DVB_FE_CUSTOMISE
> +	select DVB_STV0288 if !DVB_FE_CUSTOMISE
> +	select DVB_IX2505V if !DVB_FE_CUSTOMISE
> +	depends on IR_CORE
> +	help
> +	  Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
> diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
> index 1a19245..5b1d12f 100644
> --- a/drivers/media/dvb/dvb-usb/Makefile
> +++ b/drivers/media/dvb/dvb-usb/Makefile
> @@ -88,6 +88,9 @@ obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
>  dvb-usb-az6027-objs = az6027.o
>  obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
>  
> +dvb-usb-lmedm04-objs = lmedm04.o
> +obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
> +
>  EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
>  # due to tuner-xc3028
>  EXTRA_CFLAGS += -Idrivers/media/common/tuners
> diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
> new file mode 100644
> index 0000000..d5374ac
> --- /dev/null
> +++ b/drivers/media/dvb/dvb-usb/lmedm04.c
> @@ -0,0 +1,936 @@
> +/* DVB USB compliant linux driver for
> + *
> + * DM04/QQBOX DVB-S USB BOX	LME2510C + SHARP:BS2F7HZ7395
> + *				LME2510 + LGTDQT-P001F
> + *
> + * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
> + * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
> + *
> + * MV001F (LME2510 +LGTDQY-P001F)
> + * LG TDQY - P001F =(TDA8263 + TDA10086H)
> + *
> + * For firmware see Documentation/dvb/lmedm04.txt
> + *
> + * I2C addresses:
> + * 0xd0 - STV0288	- Demodulator
> + * 0xc0 - Sharp IX2505V	- Tuner
> + * --or--
> + * 0x1c - TDA10086   - Demodulator
> + * 0xc0 - TDA8263    - Tuner
> + *
> + * ***Please Note***
> + *		There are other variants of the DM04
> + *		***NOT SUPPORTED***
> + *		MVB0001F (LME2510C+LGTDQT-P001F)
> + *		MV0194 (LME2510+SHARP0194)
> + *		MVB0194 (LME2510C+SHARP0194)
> + *
> + *
> + * 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.
> + *
> + *	DiSEqC functions are not fully supported in this driver. The main
> + * reason is the frontend is cut off during streaming. Allowing frontend
> + * access will stall the driver. Applications that attempt to this, the
> + * commands are ignored.
> + *
> + *	PID functions have been removed from this driver version due to
> + * problems with different firmware and application versions.
> + */
> +#define DVB_USB_LOG_PREFIX "LME2510(C)"
> +#include <linux/usb.h>
> +#include <linux/usb/input.h>
> +#include <media/ir-core.h>
> +
> +#include "dvb-usb.h"
> +#include "lmedm04.h"
> +#include "tda826x.h"
> +#include "tda10086.h"
> +#include "stv0288.h"
> +#include "ix2505v.h"
> +
> +
> +
> +/* debug */
> +static int dvb_usb_lme2510_debug;
> +#define l_dprintk(var, level, args...) do { \
> +	if ((var >= level)) \
> +		printk(KERN_DEBUG DVB_USB_LOG_PREFIX ": " args); \
> +} while (0)
> +
> +#define deb_info(level, args...) l_dprintk(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));
> +
> +
> +module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
> +MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."
> +			DVB_USB_DEBUG_STATUS);
> +
> +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
> +#define TUNER_LG 0x1
> +#define TUNER_S7395 0x2
> +
> +struct lme2510_state {
> +	u8 id;
> +	u8 tuner_config;
> +	u8 signal_lock;
> +	u8 signal_level;
> +	u8 signal_sn;
> +	u8 time_key;
> +	u8 i2c_talk_onoff;
> +	u8 i2c_gate;
> +	u8 i2c_tuner_gate_w;
> +	u8 i2c_tuner_gate_r;
> +	u8 i2c_tuner_addr;
> +	void *buffer;
> +	struct urb *lme_urb;
> +	void *usb_buffer;
> +
> +};
> +
> +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, 500);
> +	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, 500);
> +	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(512, GFP_KERNEL);
> +		if (st->usb_buffer == NULL) {
> +			info("MEM Error no memory");
> +			return -ENOMEM;
> +		}
> +	}
> +	buff = st->usb_buffer;
> +
> +	/* the read/write capped at 512 */
> +	memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen);
> +
> +
> +	ret = mutex_lock_interruptible(&d->usb_mutex);
> +
> +	if (ret < 0)
> +		return -EAGAIN;
> +
> +	ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
> +	msleep(5);
> +	ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x1);
> +
> +	msleep(5);
> +	ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x1));
> +
> +	msleep(5);
> +	ret |= lme2510_bulk_read(d->udev, buff, (rlen > 512) ?
> +			512 : rlen , 0x1);
> +
> +	if (rlen > 0)
> +		memcpy(rbuf, buff, rlen);
> +
> +	mutex_unlock(&d->usb_mutex);
> +
> +	return (ret < 0) ? -ENODEV : 0;
> +}
> +
> +static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
> +{
> +	struct dvb_usb_device *d = adap->dev;
> +
> +	deb_info(1, "INT Key Keypress =%04x", keypress);
> +
> +	if (keypress > 0)
> +		ir_keydown(d->rc_input_dev, keypress, 0);
> +
> +	return 0;
> +}
> +
> +static void lme2510_int_response(struct urb *lme_urb)
> +{
> +	struct dvb_usb_adapter *adap = lme_urb->context;
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 *ibuf, *rbuf;
> +	int i = 0, offset;
> +
> +	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 in", ibuf);
> +			lme2510_remote_keypress(adap,
> +				(u16)(ibuf[4]<<8)+ibuf[5]);
> +			break;
> +		case 0xbb:
> +			switch (st->tuner_config) {
> +			case TUNER_LG:
> +				st->signal_lock = ibuf[2];
> +				st->signal_level = ibuf[4];
> +				st->signal_sn = ibuf[3];
> +				st->time_key = ibuf[7];
> +				break;
> +			case TUNER_S7395:
> +				/* Tweak for earlier firmware*/
> +				if (ibuf[1] == 0x03) {
> +					st->signal_level = ibuf[3];
> +					st->signal_sn = ibuf[2];
> +				} else {
> +					st->signal_level = ibuf[4];
> +					st->signal_sn = ibuf[5];
> +				}
> +				break;
> +			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 lme2510_state *lme_int = adap->dev->priv;
> +
> +	lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
> +
> +	if (lme_int->lme_urb == NULL)
> +			return -ENOMEM;
> +
> +	lme_int->buffer = usb_alloc_coherent(adap->dev->udev, 5000, GFP_ATOMIC,
> +					&lme_int->lme_urb->transfer_dma);
> +
> +	if (lme_int->buffer == NULL)
> +			return -ENOMEM;
> +
> +	usb_fill_int_urb(lme_int->lme_urb,
> +				adap->dev->udev,
> +				usb_rcvintpipe(adap->dev->udev, 0xa),
> +				lme_int->buffer,
> +				4096,
> +				lme2510_int_response,
> +				adap,
> +				11);
> +
> +	lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
> +
> +	usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
> +	info("INT Interupt Service Started");
> +
> +	return 0;
> +}
> +
> +static int lme2510_return_status(struct usb_device *dev)
> +{
> +	int ret = 0;
> +	u8 data[10] = {0};
> +	ret |= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
> +			0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
> +	info("Firmware Status: %x (%x)", ret , data[2]);
> +
> +	return (ret < 0) ? -ENODEV : data[2];
> +}
> +
> +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) {
> +		if ((wbuf[2] == 0x1c) & (wbuf[3] == 0x0e))
> +			msleep(80); /*take your time when waiting for tune*/
> +
> +		if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
> +			return -EAGAIN;
> +
> +		ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
> +
> +		mutex_unlock(&d->i2c_mutex);
> +		switch (st->tuner_config) {
> +		case TUNER_S7395:
> +			if (wbuf[3] == 0x24)
> +				st->signal_lock = rbuf[1];
> +			break;
> +		default:
> +			break;
> +		}
> +
> +	} else {
> +		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;
> +			default:
> +				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_level & 0x80)
> +						? 0 : st->signal_lock;
> +			default:
> +				break;
> +			}
> +			break;
> +		default:
> +			break;
> +
> +		}
> +
> +		deb_info(4, "I2C From Interupt 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[512];
> +	int i, read, read_o;
> +	u16 len;
> +	u8 gate = st->i2c_gate;
> +
> +	if (gate == 0)
> +		gate = 5;
> +
> +	if (num > 2)
> +		warn("more than 2 i2c messages"
> +			"at a time is not handled yet.	TODO.");
> +
> +	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, 512) < 0) {
> +			deb_info(1, "i2c transfer failed.");
> +			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++;
> +			}
> +		}
> +	}
> +	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,
> +};
> +
> +/* Callbacks for DVB USB */
> +static int lme2510_identify_state(struct usb_device *udev,
> +		struct dvb_usb_device_properties *props,
> +		struct dvb_usb_device_description **desc,
> +		int *cold)
> +{
> +	if (lme2510_return_status(udev) == 0x44)
> +		*cold = 1;
> +	else
> +		*cold = 0;
> +	return 0;
> +}
> +
> +static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
> +{
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 reset[] =  LME_RESET;
> +	static u8 stream_on[] = LME_ST_ON_W;
> +	static u8 clear_reg_3[] =  LME_CLEAR_PID;
> +	static u8 rbuf[1];
> +	int ret = 0, len = 2, rlen = sizeof(rbuf);
> +
> +	deb_info(1, "STM  (%02x)", onoff);
> +
> +	if (onoff == 1)	{
> +		st->i2c_talk_onoff = 0;
> +		msleep(400); /* give enough time for i2c to stop */
> +		ret |= lme2510_usb_talk(adap->dev,
> +				 stream_on,  len, rbuf, rlen);
> +	} else {
> +		deb_info(1, "STM Steam Off");
> +		if  (st->tuner_config == TUNER_LG)
> +			ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
> +				sizeof(clear_reg_3), rbuf, rlen);
> +		else
> +			ret |= lme2510_usb_talk(adap->dev,
> +				 reset, sizeof(reset), rbuf, rlen);
> +
> +		msleep(400);
> +		st->i2c_talk_onoff = 1;
> +	}
> +
> +	return (ret < 0) ? -ENODEV : 0;
> +}
> +
> +static int lme2510_int_service(struct dvb_usb_adapter *adap)
> +{
> +	struct dvb_usb_device *d = adap->dev;
> +	struct input_dev *input_dev;
> +	char *ir_codes = RC_MAP_LME2510;
> +	int ret = 0;
> +
> +	info("STA Configuring Remote");
> +
> +	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
> +
> +	strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
> +
> +	input_dev = input_allocate_device();
> +	if (!input_dev)
> +		return -ENOMEM;
> +
> +	input_dev->name = "LME2510 Remote Control";
> +	input_dev->phys = d->rc_phys;
> +
> +	usb_to_input_id(d->udev, &input_dev->id);
> +
> +	ret |= ir_input_register(input_dev, ir_codes, NULL, "LME 2510");
> +
> +	if (ret) {
> +		input_free_device(input_dev);
> +		return ret;
> +	}
> +
> +	d->rc_input_dev = input_dev;
> +	/* Start the Interupt */
> +	ret = lme2510_int_read(adap);
> +
> +	if (ret < 0) {
> +		ir_input_unregister(input_dev);
> +		input_free_device(input_dev);
> +	}
> +	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 usb_device *dev,
> +					const struct firmware *fw)
> +{
> +	int ret = 0;
> +	u8 data[512] = {0};
> +	u16 j, wlen, len_in, start, end;
> +	u8 packet_size, dlen, i;
> +	u8 *fw_data;
> +
> +	packet_size = 0x31;
> +	len_in = 1;
> +
> +
> +	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]);
> +		ret |= lme2510_bulk_write(dev, data,  wlen, 1);
> +		ret |= lme2510_bulk_read(dev, data, len_in , 1);
> +		ret |= (data[0] == 0x88) ? 0 : -1;
> +		}
> +	}
> +	usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
> +			0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
> +
> +
> +	data[0] = 0x8a;
> +	len_in = 1;
> +	msleep(2000);
> +	ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Resetting*/
> +	ret |= lme2510_bulk_read(dev, data, len_in, 1);
> +	msleep(400);
> +
> +	if (ret < 0)
> +		info("FRM Firmware Download Failed (%04x)" , ret);
> +	else
> +		info("FRM Firmware Download Completed - Resetting Device");
> +
> +
> +	return (ret < 0) ? -ENODEV : 0;
> +}
> +
> +
> +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 int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
> +					fe_sec_voltage_t voltage)
> +{
> +	struct dvb_usb_adapter *adap = fe->dvb->priv;
> +	struct lme2510_state *st = adap->dev->priv;
> +	static u8 voltage_low[]	= LME_VOLTAGE_L;
> +	static u8 voltage_high[] = LME_VOLTAGE_H;
> +	static u8 reset[] = LME_RESET;
> +	static u8 clear_reg_3[] =  LME_CLEAR_PID;
> +	static u8 rbuf[1];
> +	int ret = 0, len = 3, rlen = 1;
> +
> +	msleep(100);
> +
> +	if  (st->tuner_config == TUNER_LG)
> +		ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
> +			sizeof(clear_reg_3), rbuf, rlen);
> +	else
> +		ret |= lme2510_usb_talk(adap->dev,
> +			 reset, sizeof(reset), rbuf, rlen);
> +
> +	/*always check & stop streaming*/
> +	lme2510_kill_urb(&adap->stream);
> +	adap->feedcount = 0;
> +
> +		switch (voltage) {
> +
> +		case SEC_VOLTAGE_18:
> +			ret |= lme2510_usb_talk(adap->dev,
> +				voltage_high, len, rbuf, rlen);
> +		break;
> +
> +		case SEC_VOLTAGE_OFF:
> +		case SEC_VOLTAGE_13:
> +		default:
> +			ret |= lme2510_usb_talk(adap->dev,
> +				voltage_low, len, rbuf, rlen);
> +		break;
> +
> +
> +	};
> +	st->i2c_talk_onoff = 1;
> +	return (ret < 0) ? -ENODEV : 0;
> +}
> +
> +static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
> +{
> +	int ret = 0;
> +	struct lme2510_state *st = adap->dev->priv;
> +
> +	/* Interupt Start  */
> +	ret = lme2510_int_service(adap);
> +	if (ret < 0) {
> +		info("INT Unable to start Interupt Service");
> +		return -ENODEV;
> +	}
> +
> +	st->i2c_talk_onoff = 1;
> +	st->i2c_gate = 4;
> +
> +	adap->fe = dvb_attach(tda10086_attach, &tda10086_config,
> +		&adap->dev->i2c_adap);
> +
> +	if (adap->fe) {
> +		info("TUN Found Frontend TDA10086");
> +		memcpy(&adap->fe->ops.info.name,
> +				&"DM04_LG_TDQY-P001F DVB-S", 24);
> +		adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
> +		st->i2c_tuner_gate_w = 4;
> +		st->i2c_tuner_gate_r = 4;
> +		st->i2c_tuner_addr = 0xc0;
> +		if (dvb_attach(tda826x_attach, adap->fe, 0xc0,
> +			&adap->dev->i2c_adap, 1)) {
> +			info("TUN TDA8263 Found");
> +			st->tuner_config = TUNER_LG;
> +			return 0;
> +		}
> +		kfree(adap->fe);
> +		adap->fe = NULL;
> +	}
> +	st->i2c_gate = 5;
> +	adap->fe = dvb_attach(stv0288_attach, &lme_config,
> +			&adap->dev->i2c_adap);
> +
> +	if (adap->fe) {
> +		info("FE Found Stv0288");
> +		memcpy(&adap->fe->ops.info.name,
> +				&"DM04_SHARP:BS2F7HZ7395", 22);
> +		adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
> +		st->i2c_tuner_gate_w = 4;
> +		st->i2c_tuner_gate_r = 5;
> +		st->i2c_tuner_addr = 0xc0;
> +		if (dvb_attach(ix2505v_attach , adap->fe, &lme_tuner,
> +					&adap->dev->i2c_adap)) {
> +			st->tuner_config = TUNER_S7395;
> +			info("TUN Sharp IX2505V silicon tuner");
> +			return 0;
> +		}
> +		kfree(adap->fe);
> +		adap->fe = NULL;
> +	}
> +
> +	info("DM04 Not Supported");
> +	return -ENODEV;
> +}
> +
> +static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
> +{
> +	struct lme2510_state *st = d->priv;
> +	st->i2c_talk_onoff = 1;
> +	return 0;
> +}
> +
> +/* DVB USB Driver stuff */
> +static struct dvb_usb_device_properties lme2510_properties;
> +static struct dvb_usb_device_properties lme2510c_properties;
> +
> +static int lme2510_probe(struct usb_interface *intf,
> +		const struct usb_device_id *id)
> +{
> +	struct usb_device *udev = interface_to_usbdev(intf);
> +	int ret = 0;
> +
> +	usb_reset_configuration(udev);
> +
> +	usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1);
> +
> +	if (udev->speed != USB_SPEED_HIGH) {
> +		ret = usb_reset_device(udev);
> +		info("DEV Failed to connect in HIGH SPEED mode");
> +		return -ENODEV;
> +	}
> +
> +	if (0 == dvb_usb_device_init(intf, &lme2510_properties,
> +				     THIS_MODULE, NULL, adapter_nr)) {
> +		info("DEV registering device driver");
> +		return 0;
> +	}
> +	if (0 == dvb_usb_device_init(intf, &lme2510c_properties,
> +				     THIS_MODULE, NULL, adapter_nr)) {
> +		info("DEV registering device driver");
> +		return 0;
> +	}
> +
> +	info("DEV lme2510 Error");
> +	return -ENODEV;
> +
> +}
> +
> +static struct usb_device_id lme2510_table[] = {
> +	{ USB_DEVICE(0x3344, 0x1122) },  /* LME2510 */
> +	{ USB_DEVICE(0x3344, 0x1120) },  /* LME2510C */
> +	{}		/* Terminating entry */
> +};
> +
> +MODULE_DEVICE_TABLE(usb, lme2510_table);
> +
> +static struct dvb_usb_device_properties lme2510_properties = {
> +	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
> +	.usb_ctrl = DEVICE_SPECIFIC,
> +	.download_firmware = lme2510_download_firmware,
> +	.firmware = "dvb-usb-lme2510-lg.fw",
> +
> +	.size_of_priv = sizeof(struct lme2510_state),
> +	.num_adapters = 1,
> +	.adapter = {
> +		{
> +			.streaming_ctrl   = lme2510_streaming_ctrl,
> +			.frontend_attach  = dm04_lme2510_frontend_attach,
> +			/* parameter for the MPEG2-data transfer */
> +			.stream = {
> +				.type = USB_BULK,
> +				.count = 10,
> +				.endpoint = 0x06,
> +				.u = {
> +					.bulk = {
> +						.buffersize = 4096,
> +
> +					}
> +				}
> +			}
> +		}
> +	},
> +	.power_ctrl       = lme2510_powerup,
> +	.identify_state   = lme2510_identify_state,
> +	.i2c_algo         = &lme2510_i2c_algo,
> +	.generic_bulk_ctrl_endpoint = 0,
> +	.num_device_descs = 1,
> +	.devices = {
> +		{   "DM04 LME2510 DVB-S USB 2.0",
> +			{ &lme2510_table[0], NULL },
> +			},
> +
> +	}
> +};
> +
> +static struct dvb_usb_device_properties lme2510c_properties = {
> +	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
> +	.usb_ctrl = DEVICE_SPECIFIC,
> +	.download_firmware = lme2510_download_firmware,
> +	.firmware = "dvb-usb-lme2510c-s7395.fw",
> +	.size_of_priv = sizeof(struct lme2510_state),
> +	.num_adapters = 1,
> +	.adapter = {
> +		{
> +			.streaming_ctrl   = lme2510_streaming_ctrl,
> +			.frontend_attach  = dm04_lme2510_frontend_attach,
> +			/* parameter for the MPEG2-data transfer */
> +			.stream = {
> +				.type = USB_BULK,
> +				.count = 8,
> +				.endpoint = 0x8,
> +				.u = {
> +					.bulk = {
> +						.buffersize = 4096,
> +
> +					}
> +				}
> +			}
> +		}
> +	},
> +	.power_ctrl       = lme2510_powerup,
> +	.identify_state   = lme2510_identify_state,
> +	.i2c_algo         = &lme2510_i2c_algo,
> +	.generic_bulk_ctrl_endpoint = 0,
> +	.num_device_descs = 1,
> +	.devices = {
> +		{   "DM04 LME2510C USB2.0",
> +			{ &lme2510_table[1], NULL },
> +			},
> +	}
> +};
> +
> +void lme2510_exit_int(struct dvb_usb_device *d)
> +{
> +	struct lme2510_state *st = d->priv;
> +	if (st->lme_urb != NULL) {
> +		st->i2c_talk_onoff = 0;
> +		st->signal_lock = 0;
> +		st->signal_level = 0;
> +		st->signal_sn = 0;
> +		kfree(st->usb_buffer);
> +		usb_kill_urb(st->lme_urb);
> +		usb_free_coherent(d->udev, 5000, st->buffer,
> +				  st->lme_urb->transfer_dma);
> +		info("Interupt Service Stopped");
> +		ir_input_unregister(d->rc_input_dev);
> +		info("Remote Stopped");
> +	}
> +	return;
> +}
> +
> +void lme2510_exit(struct usb_interface *intf)
> +{
> +	struct dvb_usb_device *d = usb_get_intfdata(intf);
> +	if (d != NULL) {
> +		d->adapter[0].feedcount = 0;
> +		lme2510_exit_int(d);
> +		dvb_usb_device_exit(intf);
> +	}
> +
> +}
> +
> +static struct usb_driver lme2510_driver = {
> +	.name		= "LME2510C_DVBS",
> +	.probe		= lme2510_probe,
> +	.disconnect	= lme2510_exit,
> +	.id_table	= lme2510_table,
> +};
> +
> +/* module stuff */
> +static int __init lme2510_module_init(void)
> +{
> +	int result = usb_register(&lme2510_driver);
> +	if (result) {
> +		err("usb_register failed. Error number %d", result);
> +		return result;
> +	}
> +
> +	return 0;
> +}
> +
> +static void __exit lme2510_module_exit(void)
> +{
> +	/* deregister this driver from the USB subsystem */
> +	usb_deregister(&lme2510_driver);
> +}
> +
> +module_init(lme2510_module_init);
> +module_exit(lme2510_module_exit);
> +
> +MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
> +MODULE_DESCRIPTION("LM2510(C) DVB-S USB2.0");
> +MODULE_VERSION("1.4");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/media/dvb/dvb-usb/lmedm04.h b/drivers/media/dvb/dvb-usb/lmedm04.h
> new file mode 100644
> index 0000000..5a66c7e
> --- /dev/null
> +++ b/drivers/media/dvb/dvb-usb/lmedm04.h
> @@ -0,0 +1,187 @@
> +/* DVB USB compliant linux driver for
> + *
> + * DM04/QQBOX DVB-S USB BOX	LME2510C + SHARP:BS2F7HZ7395
> + *				LME2510C + LGTDQT-P001F
> + *
> + * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
> + * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
> + *
> + * MVB0001F (LME2510C+LGTDQT-P001F)
> + * LG TDQY - P001F =(TDA8263 + TDA10086H)
> + *
> + *
> + * 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 ??
> + *
> + *  RESET (also clears PID filter)
> + *  3a 01 00
> +*/
> +#define LME_ST_ON_W	{0x06, 0x00}
> +#define LME_RESET   {0x3a, 0x01, 0x00}
> +#define LME_CLEAR_PID   {0x03, 0x02, 0x20, 0xa0}
> +
> +
> +/* LME Power Control
> + *  07 XX XX
> + *  offset 1 = 01  Power? my device cannot be powered down
> + *  offset 2 = 00=Voltage low 01=Voltage high
> + */
> +
> +#define LME_VOLTAGE_L	{0x07, 0x01, 0x00}
> +#define LME_VOLTAGE_H	{0x07, 0x01, 0x01}
> +
> +
> +/* Initial stv0288 settings for 7395 Frontend */
> +static u8 s7395_inittab[] = {
> +	0x00, 0x11,
> +	0x01, 0x15,
> +	0x02, 0x20,
> +	0x03, 0x8e,
> +	0x04, 0x8e,
> +	0x05, 0x12,
> +	0x06, 0xff,
> +	0x07, 0x20,
> +	0x08, 0x00,
> +	0x09, 0x00,
> +	0x0a, 0x04,
> +	0x0b, 0x00,
> +	0x0c, 0x00,
> +	0x0d, 0x00,
> +	0x0e, 0xc1,
> +	0x0f, 0x54,
> +	0x10, 0x40,
> +	0x11, 0x7a,
> +	0x12, 0x03,
> +	0x13, 0x48,
> +	0x14, 0x84,
> +	0x15, 0xc5,
> +	0x16, 0xb8,
> +	0x17, 0x9c,
> +	0x18, 0x00,
> +	0x19, 0xa6,
> +	0x1a, 0x88,
> +	0x1b, 0x8f,
> +	0x1c, 0xf0,
> +	0x1e, 0x80,
> +	0x20, 0x0b,
> +	0x21, 0x54,
> +	0x22, 0xff,
> +	0x23, 0x01,
> +	0x24, 0x9a,
> +	0x25, 0x7f,
> +	0x26, 0x00,
> +	0x27, 0x00,
> +	0x28, 0x46,
> +	0x29, 0x66,
> +	0x2a, 0x90,
> +	0x2b, 0xfa,
> +	0x2c, 0xd9,
> +	0x2d, 0x02,
> +	0x2e, 0xb1,
> +	0x2f, 0x00,
> +	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,
> +	0x3e, 0x00,
> +	0x3f, 0x00,
> +	0x40, 0x63,
> +	0x41, 0x04,
> +	0x42, 0x60,
> +	0x43, 0x00,
> +	0x44, 0x00,
> +	0x45, 0x00,
> +	0x46, 0x00,
> +	0x47, 0x00,
> +	0x4a, 0x00,
> +	0x4b, 0xd1,
> +	0x4c, 0x33,
> +	0x50, 0x12,
> +	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/include/media/rc-map.h b/include/media/rc-map.h
> index 6c0324e..57281b1 100644
> --- a/include/media/rc-map.h
> +++ b/include/media/rc-map.h
> @@ -96,6 +96,7 @@ void rc_map_init(void);
>  #define RC_MAP_KWORLD_315U               "rc-kworld-315u"
>  #define RC_MAP_KWORLD_PLUS_TV_ANALOG     "rc-kworld-plus-tv-analog"
>  #define RC_MAP_LIRC                      "rc-lirc"
> +#define RC_MAP_LME2510                   "rc-lme2510"
>  #define RC_MAP_MANLI                     "rc-manli"
>  #define RC_MAP_MSI_TVANYWHERE_PLUS       "rc-msi-tvanywhere-plus"
>  #define RC_MAP_MSI_TVANYWHERE            "rc-msi-tvanywhere"
> 
> _______________________________________________
> linuxtv-commits mailing list
> linuxtv-commits@linuxtv.org
> http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-09-08 21:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-16 13:43 [PATCH] added support for DM040832731 DVB-S USB BOX - Correction Malcolm Priestley
2010-07-29 18:16 ` Mauro Carvalho Chehab
2010-09-08 21:08   ` Mauro Carvalho Chehab
2010-07-29 18:18 ` Mauro Carvalho Chehab

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).