From patchwork Thu Jul 15 18:26:08 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Malcolm Priestley X-Patchwork-Id: 112276 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6FIQF4o003873 for ; Thu, 15 Jul 2010 18:26:16 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934055Ab0GOS0N (ORCPT ); Thu, 15 Jul 2010 14:26:13 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:48235 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933977Ab0GOS0M (ORCPT ); Thu, 15 Jul 2010 14:26:12 -0400 Received: by wyb42 with SMTP id 42so995491wyb.19 for ; Thu, 15 Jul 2010 11:26:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:date:message-id :subject:from:to:content-type; bh=LbmDJ+Y9ZfUYB4Eafg357Qgl6zONOM5biHRZuJ0UZsM=; b=gT61VncmnsaHz50gGv0Io8vUyjLp2aTLP+/7DZn0bUuBF5UsZQmeWjaM/zRAw9VbLK Q2lqw71rmw9GE1nN0JjnQ4APYXfuUy70hL++eNDuYtk7AnUFyzUqEjt9ttfe2hn74tqe 8FbFu2SYzu7z1HmtsRI+x3ON/FwHHGhMtcwdY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=fyXF5sf0LQn4/53dBPrgT5HEiKuKiM06s/+MUxN2CImWyIopbVQu3RZ+LNWoA1ACoU 6qz35PbxoKN40mxzm8mZdYrHqnQU6b07uLk1AHUTxmbv1MW9X9b4JUrbrGwFuEFRPlk7 V82TK0XWu0mhx0MmVW6NZXJhVuWY+dt8FPUWc= MIME-Version: 1.0 Received: by 10.227.157.198 with SMTP id c6mr9292021wbx.144.1279218368986; Thu, 15 Jul 2010 11:26:08 -0700 (PDT) Received: by 10.227.93.202 with HTTP; Thu, 15 Jul 2010 11:26:08 -0700 (PDT) Date: Thu, 15 Jul 2010 19:26:08 +0100 Message-ID: Subject: [PATCH] added support for DM040832731 DVB-S USB BOX From: Malcolm Priestley To: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 15 Jul 2010 18:26:16 +0000 (UTC) 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 Thu Jul 15 18:45:47 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 Thu Jul 15 18:45:47 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 Thu Jul 15 18:45:47 2010 +0100 @@ -0,0 +1,908 @@ +/* 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 +#include +#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 "); +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 Thu Jul 15 18:45:47 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