aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig12
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c394
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h735
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c87
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c1
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h6
-rw-r--r--drivers/media/dvb/dvb-usb/friio-fe.c2
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk-fe.c4
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.c9
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c1088
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.h173
12 files changed, 1522 insertions, 992 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index fdc19bba2128..2525d3b3c88d 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -314,6 +314,8 @@ config DVB_USB_AF9015
select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
@@ -346,3 +348,13 @@ 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
+ 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 1a192453b0e7..5b1d12f2d591 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/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index ea1ed3b4592a..31c0a0ed39f5 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -31,6 +31,8 @@
#include "tda18271.h"
#include "mxl5005s.h"
#include "mc44s803.h"
+#include "tda18218.h"
+#include "mxl5007t.h"
static int dvb_usb_af9015_debug;
module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
@@ -205,12 +207,18 @@ static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
return af9015_write_regs(d, addr, &val, 1);
}
-static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
+static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
{
- struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val};
+ struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
+ val};
return af9015_ctrl_msg(d, &req);
}
+static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
+{
+ return af9015_read_regs(d, addr, val, 1);
+}
+
static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
u8 val)
{
@@ -241,7 +249,7 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int ret = 0, i = 0;
u16 addr;
- u8 mbox, addr_len;
+ u8 uninitialized_var(mbox), addr_len;
struct req_t req;
/* TODO: implement bus lock
@@ -280,7 +288,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate.
} else {
addr = msg[i].buf[0];
addr_len = 1;
- mbox = 0;
+ /* mbox is don't care in that case */
}
if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
@@ -494,7 +502,8 @@ static int af9015_copy_firmware(struct dvb_usb_device *d)
/* wait 2nd demodulator ready */
msleep(100);
- ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val);
+ ret = af9015_read_reg_i2c(d,
+ af9015_af9013_config[1].demod_address, 0x98be, &val);
if (ret)
goto error;
else
@@ -597,37 +606,6 @@ free:
return ret;
}
-static int af9015_download_ir_table(struct dvb_usb_device *d)
-{
- int i, packets = 0, ret;
- u16 addr = 0x9a56; /* ir-table start address */
- struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL};
- u8 *data = NULL;
- deb_info("%s:\n", __func__);
-
- data = af9015_config.ir_table;
- packets = af9015_config.ir_table_size;
-
- /* no remote */
- if (!packets)
- goto exit;
-
- /* load remote ir-table */
- for (i = 0; i < packets; i++) {
- req.addr = addr + i;
- req.data = &data[i];
- ret = af9015_ctrl_msg(d, &req);
- if (ret) {
- err("ir-table download failed at packet %d with " \
- "code %d", i, ret);
- return ret;
- }
- }
-
-exit:
- return 0;
-}
-
static int af9015_init(struct dvb_usb_device *d)
{
int ret;
@@ -637,10 +615,6 @@ static int af9015_init(struct dvb_usb_device *d)
if (ret)
goto error;
- ret = af9015_download_ir_table(d);
- if (ret)
- goto error;
-
error:
return ret;
}
@@ -733,125 +707,102 @@ error:
return ret;
}
-struct af9015_setup {
+struct af9015_rc_setup {
unsigned int id;
- struct ir_scancode *rc_key_map;
- unsigned int rc_key_map_size;
- u8 *ir_table;
- unsigned int ir_table_size;
+ char *rc_codes;
};
-static const struct af9015_setup *af9015_setup_match(unsigned int id,
- const struct af9015_setup *table)
+static char *af9015_rc_setup_match(unsigned int id,
+ const struct af9015_rc_setup *table)
{
- for (; table->rc_key_map; table++)
+ for (; table->rc_codes; table++)
if (table->id == id)
- return table;
+ return table->rc_codes;
return NULL;
}
-static const struct af9015_setup af9015_setup_modparam[] = {
- { AF9015_REMOTE_A_LINK_DTU_M,
- ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link),
- af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
- { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
- ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi),
- af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
- { AF9015_REMOTE_MYGICTV_U718,
- ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv),
- af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
- { AF9015_REMOTE_DIGITTRADE_DVB_T,
- ir_codes_af9015_table_digittrade, ARRAY_SIZE(ir_codes_af9015_table_digittrade),
- af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) },
- { AF9015_REMOTE_AVERMEDIA_KS,
- ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia),
- af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) },
+static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
+ { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
+ { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
+ { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
+ { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
+ { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
{ }
};
-/* don't add new entries here anymore, use hashes instead */
-static const struct af9015_setup af9015_setup_usbids[] = {
- { USB_VID_LEADTEK,
- ir_codes_af9015_table_leadtek, ARRAY_SIZE(ir_codes_af9015_table_leadtek),
- af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) },
- { USB_VID_VISIONPLUS,
- ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan),
- af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) },
- { USB_VID_KWORLD_2, /* TODO: use correct rc keys */
- ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan),
- af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) },
- { USB_VID_AVERMEDIA,
- ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia),
- af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) },
- { USB_VID_MSI_2,
- ir_codes_af9015_table_msi_digivox_iii, ARRAY_SIZE(ir_codes_af9015_table_msi_digivox_iii),
- af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) },
+static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
+ { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
+ { 0xa3703d00, RC_MAP_ALINK_DTU_M },
+ { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
{ }
};
-static const struct af9015_setup af9015_setup_hashes[] = {
- { 0xb8feb708,
- ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi),
- af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
- { 0xa3703d00,
- ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link),
- af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
- { 0x9b7dc64e,
- ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv),
- af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
+static const struct af9015_rc_setup af9015_rc_setup_usbids[] = {
+ { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
+ RC_MAP_TERRATEC_SLIM },
+ { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700,
+ RC_MAP_AZUREWAVE_AD_TU700 },
+ { (USB_VID_VISIONPLUS << 16) + USB_PID_TINYTWIN,
+ RC_MAP_AZUREWAVE_AD_TU700 },
+ { (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGI_VOX_MINI_III,
+ RC_MAP_MSI_DIGIVOX_III },
+ { (USB_VID_LEADTEK << 16) + USB_PID_WINFAST_DTV_DONGLE_GOLD,
+ RC_MAP_LEADTEK_Y04G0051 },
+ { (USB_VID_AVERMEDIA << 16) + USB_PID_AVERMEDIA_VOLAR_X,
+ RC_MAP_AVERMEDIA_M135A },
+ { (USB_VID_AFATECH << 16) + USB_PID_TREKSTOR_DVBT,
+ RC_MAP_TREKSTOR },
+ { (USB_VID_KWORLD_2 << 16) + USB_PID_TINYTWIN_2,
+ RC_MAP_DIGITALNOW_TINYTWIN },
+ { (USB_VID_GTEK << 16) + USB_PID_TINYTWIN_3,
+ RC_MAP_DIGITALNOW_TINYTWIN },
{ }
};
static void af9015_set_remote_config(struct usb_device *udev,
struct dvb_usb_device_properties *props)
{
- const struct af9015_setup *table = NULL;
-
- if (dvb_usb_af9015_remote) {
- /* load remote defined as module param */
- table = af9015_setup_match(dvb_usb_af9015_remote,
- af9015_setup_modparam);
- } else {
- u16 vendor = le16_to_cpu(udev->descriptor.idVendor);
-
- table = af9015_setup_match(af9015_config.eeprom_sum,
- af9015_setup_hashes);
-
- if (!table && vendor == USB_VID_AFATECH) {
- /* Check USB manufacturer and product strings and try
- to determine correct remote in case of chip vendor
- reference IDs are used.
- DO NOT ADD ANYTHING NEW HERE. Use hashes instead.
- */
- char manufacturer[10];
- memset(manufacturer, 0, sizeof(manufacturer));
- usb_string(udev, udev->descriptor.iManufacturer,
- manufacturer, sizeof(manufacturer));
- if (!strcmp("MSI", manufacturer)) {
- /* iManufacturer 1 MSI
- iProduct 2 MSI K-VOX */
- table = af9015_setup_match(
- AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
- af9015_setup_modparam);
- } else if (udev->descriptor.idProduct ==
- cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
- table = &(const struct af9015_setup){ 0,
- ir_codes_af9015_table_trekstor,
- ARRAY_SIZE(ir_codes_af9015_table_trekstor),
- af9015_ir_table_trekstor,
- ARRAY_SIZE(af9015_ir_table_trekstor)
- };
- }
- } else if (!table)
- table = af9015_setup_match(vendor, af9015_setup_usbids);
+ u16 vid = le16_to_cpu(udev->descriptor.idVendor);
+ u16 pid = le16_to_cpu(udev->descriptor.idProduct);
+
+ /* try to load remote based module param */
+ props->rc.core.rc_codes = af9015_rc_setup_match(
+ dvb_usb_af9015_remote, af9015_rc_setup_modparam);
+
+ /* try to load remote based eeprom hash */
+ if (!props->rc.core.rc_codes)
+ props->rc.core.rc_codes = af9015_rc_setup_match(
+ af9015_config.eeprom_sum, af9015_rc_setup_hashes);
+
+ /* try to load remote based USB ID */
+ if (!props->rc.core.rc_codes)
+ props->rc.core.rc_codes = af9015_rc_setup_match(
+ (vid << 16) + pid, af9015_rc_setup_usbids);
+
+ /* try to load remote based USB iManufacturer string */
+ if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) {
+ /* Check USB manufacturer and product strings and try
+ to determine correct remote in case of chip vendor
+ reference IDs are used.
+ DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
+ char manufacturer[10];
+ memset(manufacturer, 0, sizeof(manufacturer));
+ usb_string(udev, udev->descriptor.iManufacturer,
+ manufacturer, sizeof(manufacturer));
+ if (!strcmp("MSI", manufacturer)) {
+ /* iManufacturer 1 MSI
+ iProduct 2 MSI K-VOX */
+ props->rc.core.rc_codes = af9015_rc_setup_match(
+ AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
+ af9015_rc_setup_modparam);
+ }
}
- if (table) {
- props->rc.legacy.rc_key_map = table->rc_key_map;
- props->rc.legacy.rc_key_map_size = table->rc_key_map_size;
- af9015_config.ir_table = table->ir_table;
- af9015_config.ir_table_size = table->ir_table_size;
- }
+ /* finally load "empty" just for leaving IR receiver enabled */
+ if (!props->rc.core.rc_codes)
+ props->rc.core.rc_codes = RC_MAP_EMPTY;
+
+ return;
}
static int af9015_read_config(struct usb_device *udev)
@@ -877,10 +828,9 @@ static int af9015_read_config(struct usb_device *udev)
deb_info("%s: IR mode:%d\n", __func__, val);
for (i = 0; i < af9015_properties_count; i++) {
- if (val == AF9015_IR_MODE_DISABLED) {
- af9015_properties[i].rc.legacy.rc_key_map = NULL;
- af9015_properties[i].rc.legacy.rc_key_map_size = 0;
- } else
+ if (val == AF9015_IR_MODE_DISABLED)
+ af9015_properties[i].rc.core.rc_codes = NULL;
+ else
af9015_set_remote_config(udev, &af9015_properties[i]);
}
@@ -992,20 +942,19 @@ static int af9015_read_config(struct usb_device *udev)
case AF9013_TUNER_MT2060_2:
case AF9013_TUNER_TDA18271:
case AF9013_TUNER_QT1010A:
+ case AF9013_TUNER_TDA18218:
af9015_af9013_config[i].rf_spec_inv = 1;
break;
case AF9013_TUNER_MXL5003D:
case AF9013_TUNER_MXL5005D:
case AF9013_TUNER_MXL5005R:
+ case AF9013_TUNER_MXL5007T:
af9015_af9013_config[i].rf_spec_inv = 0;
break;
case AF9013_TUNER_MC44S803:
af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
af9015_af9013_config[i].rf_spec_inv = 1;
break;
- case AF9013_TUNER_TDA18218:
- warn("tuner NXP TDA18218 not supported yet");
- return -ENODEV;
default:
warn("tuner id:%d not supported, please report!", val);
return -ENODEV;
@@ -1020,9 +969,13 @@ error:
err("eeprom read failed:%d", ret);
/* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
- content :-( Override some wrong values here. */
+ content :-( Override some wrong values here. Ditto for the
+ AVerTV Red HD+ (A850T) device. */
if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
- le16_to_cpu(udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) {
+ ((le16_to_cpu(udev->descriptor.idProduct) ==
+ USB_PID_AVERMEDIA_A850) ||
+ (le16_to_cpu(udev->descriptor.idProduct) ==
+ USB_PID_AVERMEDIA_A850T))) {
deb_info("%s: AverMedia A850: overriding config\n", __func__);
/* disable dual mode */
af9015_config.dual_mode = 0;
@@ -1059,36 +1012,53 @@ static int af9015_identify_state(struct usb_device *udev,
return ret;
}
-static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int af9015_rc_query(struct dvb_usb_device *d)
{
- u8 buf[8];
- struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf};
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
- int i, ret;
-
- memset(buf, 0, sizeof(buf));
+ struct af9015_state *priv = d->priv;
+ int ret;
+ u8 buf[16];
- ret = af9015_ctrl_msg(d, &req);
+ /* read registers needed to detect remote controller code */
+ ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
if (ret)
- return ret;
+ goto error;
- *event = 0;
- *state = REMOTE_NO_KEY_PRESSED;
+ if (buf[14] || buf[15]) {
+ deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
+ buf[12], buf[13], buf[14], buf[15]);
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
- if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] &&
- rc5_data(&keymap[i]) == buf[2]) {
- *event = keymap[i].keycode;
- *state = REMOTE_KEY_PRESSED;
- break;
+ /* clean IR code from mem */
+ ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4);
+ if (ret)
+ goto error;
+
+ if (buf[14] == (u8) ~buf[15]) {
+ if (buf[12] == (u8) ~buf[13]) {
+ /* NEC */
+ priv->rc_keycode = buf[12] << 8 | buf[14];
+ } else {
+ /* NEC extended*/
+ priv->rc_keycode = buf[12] << 16 |
+ buf[13] << 8 | buf[14];
+ }
+ ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
+ } else {
+ priv->rc_keycode = 0; /* clear just for sure */
}
+ } else if (priv->rc_repeat != buf[6] || buf[0]) {
+ deb_rc("%s: key repeated\n", __func__);
+ ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
+ } else {
+ deb_rc("%s: no key press\n", __func__);
}
- if (!buf[1])
- deb_rc("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n",
- __func__, buf[0], buf[1], buf[2], buf[3], buf[4],
- buf[5], buf[6], buf[7]);
- return 0;
+ priv->rc_repeat = buf[6];
+
+error:
+ if (ret)
+ err("%s: failed:%d", __func__, ret);
+
+ return ret;
}
/* init 2nd I2C adapter */
@@ -1100,11 +1070,6 @@ static int af9015_i2c_init(struct dvb_usb_device *d)
strncpy(state->i2c_adap.name, d->desc->name,
sizeof(state->i2c_adap.name));
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- state->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
-#else
- state->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
-#endif
state->i2c_adap.algo = d->props.i2c_algo;
state->i2c_adap.algo_data = NULL;
state->i2c_adap.dev.parent = &d->udev->dev;
@@ -1166,7 +1131,7 @@ static struct qt1010_config af9015_qt1010_config = {
static struct tda18271_config af9015_tda18271_config = {
.gate = TDA18271_GATE_DIGITAL,
- .small_i2c = 1,
+ .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
};
static struct mxl5005s_config af9015_mxl5003_config = {
@@ -1208,12 +1173,22 @@ static struct mc44s803_config af9015_mc44s803_config = {
.dig_out = 1,
};
+static struct tda18218_config af9015_tda18218_config = {
+ .i2c_address = 0xc0,
+ .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
+};
+
+static struct mxl5007t_config af9015_mxl5007t_config = {
+ .xtal_freq_hz = MxL_XTAL_24_MHZ,
+ .if_freq_hz = MxL_IF_4_57_MHZ,
+};
+
static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
{
struct af9015_state *state = adap->dev->priv;
struct i2c_adapter *i2c_adap;
int ret;
- deb_info("%s: \n", __func__);
+ deb_info("%s:\n", __func__);
/* select I2C adapter */
if (adap->id == 0)
@@ -1238,6 +1213,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap,
&af9015_tda18271_config) == NULL ? -ENODEV : 0;
break;
+ case AF9013_TUNER_TDA18218:
+ ret = dvb_attach(tda18218_attach, adap->fe, i2c_adap,
+ &af9015_tda18218_config) == NULL ? -ENODEV : 0;
+ break;
case AF9013_TUNER_MXL5003D:
ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap,
&af9015_mxl5003_config) == NULL ? -ENODEV : 0;
@@ -1255,6 +1234,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
&af9015_mc44s803_config) == NULL ? -ENODEV : 0;
break;
+ case AF9013_TUNER_MXL5007T:
+ ret = dvb_attach(mxl5007t_attach, adap->fe, i2c_adap,
+ 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
+ break;
case AF9013_TUNER_UNKNOWN:
default:
ret = -ENODEV;
@@ -1300,10 +1283,16 @@ static struct usb_device_id af9015_usb_table[] = {
/* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
+ {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
+ {USB_DEVICE(USB_VID_TERRATEC,
+ USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)},
+/* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)},
+ {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
+#define AF9015_RC_INTERVAL 500
static struct dvb_usb_device_properties af9015_properties[] = {
{
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
@@ -1354,14 +1343,19 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
- .rc.legacy = {
+ .rc.core = {
+ .protocol = IR_TYPE_NEC,
+ .module_name = "af9015",
.rc_query = af9015_rc_query,
- .rc_interval = 150,
+ .rc_interval = AF9015_RC_INTERVAL,
+ .rc_props = {
+ .allowed_protos = IR_TYPE_NEC,
+ },
},
.i2c_algo = &af9015_i2c_algo,
- .num_device_descs = 9, /* max 9 */
+ .num_device_descs = 12, /* check max from dvb-usb.h */
.devices = {
{
.name = "Afatech AF9015 DVB-T USB2.0 stick",
@@ -1389,7 +1383,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
{
.name = "DigitalNow TinyTwin DVB-T Receiver",
.cold_ids = {&af9015_usb_table[5],
- &af9015_usb_table[28], NULL},
+ &af9015_usb_table[28],
+ &af9015_usb_table[36], NULL},
.warm_ids = {NULL},
},
{
@@ -1413,6 +1408,21 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.cold_ids = {&af9015_usb_table[9], NULL},
.warm_ids = {NULL},
},
+ {
+ .name = "TerraTec Cinergy T Stick RC",
+ .cold_ids = {&af9015_usb_table[33], NULL},
+ .warm_ids = {NULL},
+ },
+ {
+ .name = "TerraTec Cinergy T Stick Dual RC",
+ .cold_ids = {&af9015_usb_table[34], NULL},
+ .warm_ids = {NULL},
+ },
+ {
+ .name = "AverMedia AVerTV Red HD+ (A850T)",
+ .cold_ids = {&af9015_usb_table[35], NULL},
+ .warm_ids = {NULL},
+ },
}
}, {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
@@ -1463,14 +1473,19 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
- .rc.legacy = {
+ .rc.core = {
+ .protocol = IR_TYPE_NEC,
+ .module_name = "af9015",
.rc_query = af9015_rc_query,
- .rc_interval = 150,
+ .rc_interval = AF9015_RC_INTERVAL,
+ .rc_props = {
+ .allowed_protos = IR_TYPE_NEC,
+ },
},
.i2c_algo = &af9015_i2c_algo,
- .num_device_descs = 9, /* max 9 */
+ .num_device_descs = 9, /* check max from dvb-usb.h */
.devices = {
{
.name = "Xtensions XD-380",
@@ -1572,14 +1587,19 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
- .rc.legacy = {
+ .rc.core = {
+ .protocol = IR_TYPE_NEC,
+ .module_name = "af9015",
.rc_query = af9015_rc_query,
- .rc_interval = 150,
+ .rc_interval = AF9015_RC_INTERVAL,
+ .rc_props = {
+ .allowed_protos = IR_TYPE_NEC,
+ },
},
.i2c_algo = &af9015_i2c_algo,
- .num_device_descs = 9, /* max 9 */
+ .num_device_descs = 9, /* check max from dvb-usb.h */
.devices = {
{
.name = "AverMedia AVerTV Volar GPS 805 (A805)",
@@ -1672,7 +1692,7 @@ static int af9015_usb_probe(struct usb_interface *intf,
static void af9015_i2c_exit(struct dvb_usb_device *d)
{
struct af9015_state *state = d->priv;
- deb_info("%s: \n", __func__);
+ deb_info("%s:\n", __func__);
/* remove 2nd I2C adapter */
if (d->state & DVB_USB_STATE_I2C)
@@ -1682,7 +1702,7 @@ static void af9015_i2c_exit(struct dvb_usb_device *d)
static void af9015_usb_device_exit(struct usb_interface *intf)
{
struct dvb_usb_device *d = usb_get_intfdata(intf);
- deb_info("%s: \n", __func__);
+ deb_info("%s:\n", __func__);
/* remove 2nd I2C adapter */
if (d != NULL && d->desc != NULL)
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index c8e9349742ee..f20cfa6ed690 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -100,6 +100,8 @@ enum af9015_ir_mode {
struct af9015_state {
struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */
+ u8 rc_repeat;
+ u32 rc_keycode;
};
struct af9015_config {
@@ -108,8 +110,6 @@ struct af9015_config {
u16 firmware_size;
u16 firmware_checksum;
u32 eeprom_sum;
- u8 *ir_table;
- u16 ir_table_size;
};
enum af9015_remote {
@@ -121,735 +121,4 @@ enum af9015_remote {
/* 5 */ AF9015_REMOTE_AVERMEDIA_KS,
};
-/* LeadTek - Y04G0051 */
-/* Leadtek WinFast DTV Dongle Gold */
-static struct ir_scancode ir_codes_af9015_table_leadtek[] = {
- { 0x001e, KEY_1 },
- { 0x001f, KEY_2 },
- { 0x0020, KEY_3 },
- { 0x0021, KEY_4 },
- { 0x0022, KEY_5 },
- { 0x0023, KEY_6 },
- { 0x0024, KEY_7 },
- { 0x0025, KEY_8 },
- { 0x0026, KEY_9 },
- { 0x0027, KEY_0 },
- { 0x0028, KEY_OK },
- { 0x004f, KEY_RIGHT },
- { 0x0050, KEY_LEFT },
- { 0x0051, KEY_DOWN },
- { 0x0052, KEY_UP },
- { 0x011a, KEY_POWER2 },
- { 0x04b4, KEY_TV },
- { 0x04b3, KEY_RED },
- { 0x04b2, KEY_GREEN },
- { 0x04b1, KEY_YELLOW },
- { 0x04b0, KEY_BLUE },
- { 0x003d, KEY_TEXT },
- { 0x0113, KEY_SLEEP },
- { 0x0010, KEY_MUTE },
- { 0x0105, KEY_ESC },
- { 0x0009, KEY_SCREEN },
- { 0x010f, KEY_MENU },
- { 0x003f, KEY_CHANNEL },
- { 0x0013, KEY_REWIND },
- { 0x0012, KEY_PLAY },
- { 0x0011, KEY_FASTFORWARD },
- { 0x0005, KEY_PREVIOUS },
- { 0x0029, KEY_STOP },
- { 0x002b, KEY_NEXT },
- { 0x0041, KEY_EPG },
- { 0x0019, KEY_VIDEO },
- { 0x0016, KEY_AUDIO },
- { 0x0037, KEY_DOT },
- { 0x002a, KEY_AGAIN },
- { 0x002c, KEY_CAMERA },
- { 0x003c, KEY_NEW },
- { 0x0115, KEY_RECORD },
- { 0x010b, KEY_TIME },
- { 0x0043, KEY_VOLUMEUP },
- { 0x0042, KEY_VOLUMEDOWN },
- { 0x004b, KEY_CHANNELUP },
- { 0x004e, KEY_CHANNELDOWN },
-};
-
-static u8 af9015_ir_table_leadtek[] = {
- 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, /* KEY_POWER2 */
- 0x03, 0xfc, 0x56, 0xa9, 0xb4, 0x04, 0x00, /* KEY_TV */
- 0x03, 0xfc, 0x4b, 0xb4, 0xb3, 0x04, 0x00, /* KEY_RED */
- 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, /* KEY_GREEN */
- 0x03, 0xfc, 0x4d, 0xb2, 0xb1, 0x04, 0x00, /* KEY_YELLOW */
- 0x03, 0xfc, 0x4e, 0xb1, 0xb0, 0x04, 0x00, /* KEY_BLUE */
- 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, /* KEY_TEXT */
- 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, /* KEY_SLEEP */
- 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, /* KEY_MUTE */
- 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, /* KEY_ESC */
- 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, /* KEY_STOP (1)*/
- 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, /* KEY_UP */
- 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, /* KEY_SCREEN */
- 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, /* KEY_LEFT */
- 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, /* KEY_OK (1) */
- 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, /* KEY_RIGHT */
- 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, /* KEY_MENU */
- 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, /* KEY_DOWN */
- 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, /* KEY_CHANNEL */
- 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, /* KEY_REWIND */
- 0x03, 0xfc, 0x43, 0xbc, 0x12, 0x00, 0x00, /* KEY_PLAY */
- 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, /* KEY_FASTFORWARD */
- 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, /* KEY_VIDEO (1) */
- 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, /* KEY_PREVIOUS */
- 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, /* KEY_STOP (2) */
- 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, /* KEY_NEXT */
- 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, /* KEY_EPG */
- 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, /* KEY_1 */
- 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, /* KEY_2 */
- 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, /* KEY_3 */
- 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, /* KEY_VIDEO (2) */
- 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, /* KEY_4 */
- 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, /* KEY_5 */
- 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, /* KEY_6 */
- 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, /* KEY_AUDIO */
- 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, /* KEY_7 */
- 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, /* KEY_8 */
- 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, /* KEY_9 */
- 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* KEY_OK (2) */
- 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, /* KEY_DOT */
- 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, /* KEY_0 */
- 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, /* KEY_AGAIN */
- 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, /* KEY_CAMERA */
- 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, /* KEY_NEW */
- 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, /* KEY_RECORD */
- 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, /* KEY_TIME */
- 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, /* KEY_VOLUMEUP */
- 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, /* KEY_VOLUMEDOWN */
- 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, /* KEY_CHANNELUP */
- 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, /* KEY_CHANNELDOWN */
-};
-
-/* TwinHan AzureWave AD-TU700(704J) */
-static struct ir_scancode ir_codes_af9015_table_twinhan[] = {
- { 0x053f, KEY_POWER },
- { 0x0019, KEY_FAVORITES }, /* Favorite List */
- { 0x0004, KEY_TEXT }, /* Teletext */
- { 0x000e, KEY_POWER },
- { 0x000e, KEY_INFO }, /* Preview */
- { 0x0008, KEY_EPG }, /* Info/EPG */
- { 0x000f, KEY_LIST }, /* Record List */
- { 0x001e, KEY_1 },
- { 0x001f, KEY_2 },
- { 0x0020, KEY_3 },
- { 0x0021, KEY_4 },
- { 0x0022, KEY_5 },
- { 0x0023, KEY_6 },
- { 0x0024, KEY_7 },
- { 0x0025, KEY_8 },
- { 0x0026, KEY_9 },
- { 0x0027, KEY_0 },
- { 0x0029, KEY_CANCEL }, /* Cancel */
- { 0x004c, KEY_CLEAR }, /* Clear */
- { 0x002a, KEY_BACK }, /* Back */
- { 0x002b, KEY_TAB }, /* Tab */
- { 0x0052, KEY_UP }, /* up arrow */
- { 0x0051, KEY_DOWN }, /* down arrow */
- { 0x004f, KEY_RIGHT }, /* right arrow */
- { 0x0050, KEY_LEFT }, /* left arrow */
- { 0x0028, KEY_ENTER }, /* Enter / ok */
- { 0x0252, KEY_VOLUMEUP },
- { 0x0251, KEY_VOLUMEDOWN },
- { 0x004e, KEY_CHANNELDOWN },
- { 0x004b, KEY_CHANNELUP },
- { 0x004a, KEY_RECORD },
- { 0x0111, KEY_PLAY },
- { 0x0017, KEY_PAUSE },
- { 0x000c, KEY_REWIND }, /* FR << */
- { 0x0011, KEY_FASTFORWARD }, /* FF >> */
- { 0x0115, KEY_PREVIOUS }, /* Replay */
- { 0x010e, KEY_NEXT }, /* Skip */
- { 0x0013, KEY_CAMERA }, /* Capture */
- { 0x010f, KEY_LANGUAGE }, /* SAP */
- { 0x0113, KEY_TV2 }, /* PIP */
- { 0x001d, KEY_ZOOM }, /* Full Screen */
- { 0x0117, KEY_SUBTITLE }, /* Subtitle / CC */
- { 0x0010, KEY_MUTE },
- { 0x0119, KEY_AUDIO }, /* L/R */ /* TODO better event */
- { 0x0116, KEY_SLEEP }, /* Hibernate */
- { 0x0116, KEY_SWITCHVIDEOMODE },
- /* A/V */ /* TODO does not work */
- { 0x0006, KEY_AGAIN }, /* Recall */
- { 0x0116, KEY_KPPLUS }, /* Zoom+ */ /* TODO does not work */
- { 0x0116, KEY_KPMINUS }, /* Zoom- */ /* TODO does not work */
- { 0x0215, KEY_RED },
- { 0x020a, KEY_GREEN },
- { 0x021c, KEY_YELLOW },
- { 0x0205, KEY_BLUE },
-};
-
-static u8 af9015_ir_table_twinhan[] = {
- 0x00, 0xff, 0x16, 0xe9, 0x3f, 0x05, 0x00,
- 0x00, 0xff, 0x07, 0xf8, 0x16, 0x01, 0x00,
- 0x00, 0xff, 0x14, 0xeb, 0x11, 0x01, 0x00,
- 0x00, 0xff, 0x1a, 0xe5, 0x4d, 0x00, 0x00,
- 0x00, 0xff, 0x4c, 0xb3, 0x17, 0x00, 0x00,
- 0x00, 0xff, 0x12, 0xed, 0x11, 0x00, 0x00,
- 0x00, 0xff, 0x40, 0xbf, 0x0c, 0x00, 0x00,
- 0x00, 0xff, 0x11, 0xee, 0x4a, 0x00, 0x00,
- 0x00, 0xff, 0x54, 0xab, 0x13, 0x00, 0x00,
- 0x00, 0xff, 0x41, 0xbe, 0x15, 0x01, 0x00,
- 0x00, 0xff, 0x42, 0xbd, 0x0e, 0x01, 0x00,
- 0x00, 0xff, 0x43, 0xbc, 0x17, 0x01, 0x00,
- 0x00, 0xff, 0x50, 0xaf, 0x0f, 0x01, 0x00,
- 0x00, 0xff, 0x4d, 0xb2, 0x1d, 0x00, 0x00,
- 0x00, 0xff, 0x47, 0xb8, 0x13, 0x01, 0x00,
- 0x00, 0xff, 0x05, 0xfa, 0x4b, 0x00, 0x00,
- 0x00, 0xff, 0x02, 0xfd, 0x4e, 0x00, 0x00,
- 0x00, 0xff, 0x0e, 0xf1, 0x06, 0x00, 0x00,
- 0x00, 0xff, 0x1e, 0xe1, 0x52, 0x02, 0x00,
- 0x00, 0xff, 0x0a, 0xf5, 0x51, 0x02, 0x00,
- 0x00, 0xff, 0x10, 0xef, 0x10, 0x00, 0x00,
- 0x00, 0xff, 0x49, 0xb6, 0x19, 0x01, 0x00,
- 0x00, 0xff, 0x15, 0xea, 0x27, 0x00, 0x00,
- 0x00, 0xff, 0x03, 0xfc, 0x1e, 0x00, 0x00,
- 0x00, 0xff, 0x01, 0xfe, 0x1f, 0x00, 0x00,
- 0x00, 0xff, 0x06, 0xf9, 0x20, 0x00, 0x00,
- 0x00, 0xff, 0x09, 0xf6, 0x21, 0x00, 0x00,
- 0x00, 0xff, 0x1d, 0xe2, 0x22, 0x00, 0x00,
- 0x00, 0xff, 0x1f, 0xe0, 0x23, 0x00, 0x00,
- 0x00, 0xff, 0x0d, 0xf2, 0x24, 0x00, 0x00,
- 0x00, 0xff, 0x19, 0xe6, 0x25, 0x00, 0x00,
- 0x00, 0xff, 0x1b, 0xe4, 0x26, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0xff, 0x2b, 0x00, 0x00,
- 0x00, 0xff, 0x4a, 0xb5, 0x4c, 0x00, 0x00,
- 0x00, 0xff, 0x4b, 0xb4, 0x52, 0x00, 0x00,
- 0x00, 0xff, 0x51, 0xae, 0x51, 0x00, 0x00,
- 0x00, 0xff, 0x52, 0xad, 0x4f, 0x00, 0x00,
- 0x00, 0xff, 0x4e, 0xb1, 0x50, 0x00, 0x00,
- 0x00, 0xff, 0x0c, 0xf3, 0x29, 0x00, 0x00,
- 0x00, 0xff, 0x4f, 0xb0, 0x28, 0x00, 0x00,
- 0x00, 0xff, 0x13, 0xec, 0x2a, 0x00, 0x00,
- 0x00, 0xff, 0x17, 0xe8, 0x19, 0x00, 0x00,
- 0x00, 0xff, 0x04, 0xfb, 0x0f, 0x00, 0x00,
- 0x00, 0xff, 0x48, 0xb7, 0x0e, 0x00, 0x00,
- 0x00, 0xff, 0x0f, 0xf0, 0x04, 0x00, 0x00,
- 0x00, 0xff, 0x1c, 0xe3, 0x08, 0x00, 0x00,
- 0x00, 0xff, 0x18, 0xe7, 0x15, 0x02, 0x00,
- 0x00, 0xff, 0x53, 0xac, 0x0a, 0x02, 0x00,
- 0x00, 0xff, 0x5e, 0xa1, 0x1c, 0x02, 0x00,
- 0x00, 0xff, 0x5f, 0xa0, 0x05, 0x02, 0x00,
-};
-
-/* A-Link DTU(m) */
-static struct ir_scancode ir_codes_af9015_table_a_link[] = {
- { 0x001e, KEY_1 },
- { 0x001f, KEY_2 },
- { 0x0020, KEY_3 },
- { 0x0021, KEY_4 },
- { 0x0022, KEY_5 },
- { 0x0023, KEY_6 },
- { 0x0024, KEY_7 },
- { 0x0025, KEY_8 },
- { 0x0026, KEY_9 },
- { 0x0027, KEY_0 },
- { 0x002e, KEY_CHANNELUP },
- { 0x002d, KEY_CHANNELDOWN },
- { 0x0428, KEY_ZOOM },
- { 0x0041, KEY_MUTE },
- { 0x0042, KEY_VOLUMEDOWN },
- { 0x0043, KEY_VOLUMEUP },
- { 0x0044, KEY_GOTO }, /* jump */
- { 0x0545, KEY_POWER },
-};
-
-static u8 af9015_ir_table_a_link[] = {
- 0x08, 0xf7, 0x12, 0xed, 0x45, 0x05, 0x00, /* power */
- 0x08, 0xf7, 0x1a, 0xe5, 0x41, 0x00, 0x00, /* mute */
- 0x08, 0xf7, 0x01, 0xfe, 0x1e, 0x00, 0x00, /* 1 */
- 0x08, 0xf7, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */
- 0x08, 0xf7, 0x03, 0xfc, 0x24, 0x00, 0x00, /* 7 */
- 0x08, 0xf7, 0x05, 0xfa, 0x28, 0x04, 0x00, /* zoom */
- 0x08, 0xf7, 0x00, 0xff, 0x43, 0x00, 0x00, /* volume up */
- 0x08, 0xf7, 0x16, 0xe9, 0x42, 0x00, 0x00, /* volume down */
- 0x08, 0xf7, 0x0f, 0xf0, 0x1f, 0x00, 0x00, /* 2 */
- 0x08, 0xf7, 0x0d, 0xf2, 0x22, 0x00, 0x00, /* 5 */
- 0x08, 0xf7, 0x1b, 0xe4, 0x25, 0x00, 0x00, /* 8 */
- 0x08, 0xf7, 0x06, 0xf9, 0x27, 0x00, 0x00, /* 0 */
- 0x08, 0xf7, 0x14, 0xeb, 0x2e, 0x00, 0x00, /* channel up */
- 0x08, 0xf7, 0x1d, 0xe2, 0x2d, 0x00, 0x00, /* channel down */
- 0x08, 0xf7, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */
- 0x08, 0xf7, 0x18, 0xe7, 0x23, 0x00, 0x00, /* 6 */
- 0x08, 0xf7, 0x04, 0xfb, 0x26, 0x00, 0x00, /* 9 */
- 0x08, 0xf7, 0x07, 0xf8, 0x44, 0x00, 0x00, /* jump */
-};
-
-/* MSI DIGIVOX mini II V3.0 */
-static struct ir_scancode ir_codes_af9015_table_msi[] = {
- { 0x001e, KEY_1 },
- { 0x001f, KEY_2 },
- { 0x0020, KEY_3 },
- { 0x0021, KEY_4 },
- { 0x0022, KEY_5 },
- { 0x0023, KEY_6 },
- { 0x0024, KEY_7 },
- { 0x0025, KEY_8 },
- { 0x0026, KEY_9 },
- { 0x0027, KEY_0 },
- { 0x030f, KEY_CHANNELUP },
- { 0x030e, KEY_CHANNELDOWN },
- { 0x0042, KEY_VOLUMEDOWN },
- { 0x0043, KEY_VOLUMEUP },
- { 0x0545, KEY_POWER },
- { 0x0052, KEY_UP }, /* up */
- { 0x0051, KEY_DOWN }, /* down */
- { 0x0028, KEY_ENTER },
-};
-
-static u8 af9015_ir_table_msi[] = {
- 0x03, 0xfc, 0x17, 0xe8, 0x45, 0x05, 0x00, /* power */
- 0x03, 0xfc, 0x0d, 0xf2, 0x51, 0x00, 0x00, /* down */
- 0x03, 0xfc, 0x03, 0xfc, 0x52, 0x00, 0x00, /* up */
- 0x03, 0xfc, 0x1a, 0xe5, 0x1e, 0x00, 0x00, /* 1 */
- 0x03, 0xfc, 0x02, 0xfd, 0x1f, 0x00, 0x00, /* 2 */
- 0x03, 0xfc, 0x04, 0xfb, 0x20, 0x00, 0x00, /* 3 */
- 0x03, 0xfc, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */
- 0x03, 0xfc, 0x08, 0xf7, 0x22, 0x00, 0x00, /* 5 */
- 0x03, 0xfc, 0x1d, 0xe2, 0x23, 0x00, 0x00, /* 6 */
- 0x03, 0xfc, 0x11, 0xee, 0x24, 0x00, 0x00, /* 7 */
- 0x03, 0xfc, 0x0b, 0xf4, 0x25, 0x00, 0x00, /* 8 */
- 0x03, 0xfc, 0x10, 0xef, 0x26, 0x00, 0x00, /* 9 */
- 0x03, 0xfc, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */
- 0x03, 0xfc, 0x14, 0xeb, 0x43, 0x00, 0x00, /* volume up */
- 0x03, 0xfc, 0x1f, 0xe0, 0x42, 0x00, 0x00, /* volume down */
- 0x03, 0xfc, 0x15, 0xea, 0x0f, 0x03, 0x00, /* channel up */
- 0x03, 0xfc, 0x05, 0xfa, 0x0e, 0x03, 0x00, /* channel down */
- 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* enter */
-};
-
-/* MYGICTV U718 */
-static struct ir_scancode ir_codes_af9015_table_mygictv[] = {
- { 0x003d, KEY_SWITCHVIDEOMODE },
- /* TV / AV */
- { 0x0545, KEY_POWER },
- { 0x001e, KEY_1 },
- { 0x001f, KEY_2 },
- { 0x0020, KEY_3 },
- { 0x0021, KEY_4 },
- { 0x0022, KEY_5 },
- { 0x0023, KEY_6 },
- { 0x0024, KEY_7 },
- { 0x0025, KEY_8 },
- { 0x0026, KEY_9 },
- { 0x0027, KEY_0 },
- { 0x0041, KEY_MUTE },
- { 0x002a, KEY_ESC }, /* Esc */
- { 0x002e, KEY_CHANNELUP },
- { 0x002d, KEY_CHANNELDOWN },
- { 0x0042, KEY_VOLUMEDOWN },
- { 0x0043, KEY_VOLUMEUP },
- { 0x0052, KEY_UP }, /* up arrow */
- { 0x0051, KEY_DOWN }, /* down arrow */
- { 0x004f, KEY_RIGHT }, /* right arrow */
- { 0x0050, KEY_LEFT }, /* left arrow */
- { 0x0028, KEY_ENTER }, /* ok */
- { 0x0115, KEY_RECORD },
- { 0x0313, KEY_PLAY },
- { 0x0113, KEY_PAUSE },
- { 0x0116, KEY_STOP },
- { 0x0307, KEY_REWIND }, /* FR << */
- { 0x0309, KEY_FASTFORWARD }, /* FF >> */
- { 0x003b, KEY_TIME }, /* TimeShift */
- { 0x003e, KEY_CAMERA }, /* Snapshot */
- { 0x0316, KEY_CYCLEWINDOWS }, /* yellow, min / max */
- { 0x0000, KEY_ZOOM }, /* 'select' (?) */
- { 0x0316, KEY_SHUFFLE }, /* Shuffle */
- { 0x0345, KEY_POWER },
-};
-
-static u8 af9015_ir_table_mygictv[] = {
- 0x02, 0xbd, 0x0c, 0xf3, 0x3d, 0x00, 0x00, /* TV / AV */
- 0x02, 0xbd, 0x14, 0xeb, 0x45, 0x05, 0x00, /* power */
- 0x02, 0xbd, 0x00, 0xff, 0x1e, 0x00, 0x00, /* 1 */
- 0x02, 0xbd, 0x01, 0xfe, 0x1f, 0x00, 0x00, /* 2 */
- 0x02, 0xbd, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */
- 0x02, 0xbd, 0x03, 0xfc, 0x21, 0x00, 0x00, /* 4 */
- 0x02, 0xbd, 0x04, 0xfb, 0x22, 0x00, 0x00, /* 5 */
- 0x02, 0xbd, 0x05, 0xfa, 0x23, 0x00, 0x00, /* 6 */
- 0x02, 0xbd, 0x06, 0xf9, 0x24, 0x00, 0x00, /* 7 */
- 0x02, 0xbd, 0x07, 0xf8, 0x25, 0x00, 0x00, /* 8 */
- 0x02, 0xbd, 0x08, 0xf7, 0x26, 0x00, 0x00, /* 9 */
- 0x02, 0xbd, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */
- 0x02, 0xbd, 0x0a, 0xf5, 0x41, 0x00, 0x00, /* mute */
- 0x02, 0xbd, 0x1c, 0xe3, 0x2a, 0x00, 0x00, /* esc */
- 0x02, 0xbd, 0x1f, 0xe0, 0x43, 0x00, 0x00, /* volume up */
- 0x02, 0xbd, 0x12, 0xed, 0x52, 0x00, 0x00, /* up arrow */
- 0x02, 0xbd, 0x11, 0xee, 0x50, 0x00, 0x00, /* left arrow */
- 0x02, 0xbd, 0x15, 0xea, 0x28, 0x00, 0x00, /* ok */
- 0x02, 0xbd, 0x10, 0xef, 0x4f, 0x00, 0x00, /* right arrow */
- 0x02, 0xbd, 0x13, 0xec, 0x51, 0x00, 0x00, /* down arrow */
- 0x02, 0xbd, 0x0e, 0xf1, 0x42, 0x00, 0x00, /* volume down */
- 0x02, 0xbd, 0x19, 0xe6, 0x15, 0x01, 0x00, /* record */
- 0x02, 0xbd, 0x1e, 0xe1, 0x13, 0x03, 0x00, /* play */
- 0x02, 0xbd, 0x16, 0xe9, 0x16, 0x01, 0x00, /* stop */
- 0x02, 0xbd, 0x0b, 0xf4, 0x28, 0x04, 0x00, /* yellow, min / max */
- 0x02, 0xbd, 0x0f, 0xf0, 0x3b, 0x00, 0x00, /* time shift */
- 0x02, 0xbd, 0x18, 0xe7, 0x2e, 0x00, 0x00, /* channel up */
- 0x02, 0xbd, 0x1a, 0xe5, 0x2d, 0x00, 0x00, /* channel down */
- 0x02, 0xbd, 0x17, 0xe8, 0x3e, 0x00, 0x00, /* snapshot */
- 0x02, 0xbd, 0x40, 0xbf, 0x13, 0x01, 0x00, /* pause */
- 0x02, 0xbd, 0x41, 0xbe, 0x09, 0x03, 0x00, /* FF >> */
- 0x02, 0xbd, 0x42, 0xbd, 0x07, 0x03, 0x00, /* FR << */
- 0x02, 0xbd, 0x43, 0xbc, 0x00, 0x00, 0x00, /* 'select' (?) */
- 0x02, 0xbd, 0x44, 0xbb, 0x16, 0x03, 0x00, /* shuffle */
- 0x02, 0xbd, 0x45, 0xba, 0x45, 0x03, 0x00, /* power */
-};
-
-/* KWorld PlusTV Dual DVB-T Stick (DVB-T 399U) */
-static u8 af9015_ir_table_kworld[] = {
- 0x86, 0x6b, 0x0c, 0xf3, 0x2e, 0x07, 0x00,
- 0x86, 0x6b, 0x16, 0xe9, 0x2d, 0x07, 0x00,
- 0x86, 0x6b, 0x1d, 0xe2, 0x37, 0x07, 0x00,
- 0x86, 0x6b, 0x00, 0xff, 0x1e, 0x07, 0x00,
- 0x86, 0x6b, 0x01, 0xfe, 0x1f, 0x07, 0x00,
- 0x86, 0x6b, 0x02, 0xfd, 0x20, 0x07, 0x00,
- 0x86, 0x6b, 0x03, 0xfc, 0x21, 0x07, 0x00,
- 0x86, 0x6b, 0x04, 0xfb, 0x22, 0x07, 0x00,
- 0x86, 0x6b, 0x05, 0xfa, 0x23, 0x07, 0x00,
- 0x86, 0x6b, 0x06, 0xf9, 0x24, 0x07, 0x00,
- 0x86, 0x6b, 0x07, 0xf8, 0x25, 0x07, 0x00,
- 0x86, 0x6b, 0x08, 0xf7, 0x26, 0x07, 0x00,
- 0x86, 0x6b, 0x09, 0xf6, 0x4d, 0x07, 0x00,
- 0x86, 0x6b, 0x0a, 0xf5, 0x4e, 0x07, 0x00,
- 0x86, 0x6b, 0x14, 0xeb, 0x4f, 0x07, 0x00,
- 0x86, 0x6b, 0x1e, 0xe1, 0x50, 0x07, 0x00,
- 0x86, 0x6b, 0x17, 0xe8, 0x52, 0x07, 0x00,
- 0x86, 0x6b, 0x1f, 0xe0, 0x51, 0x07, 0x00,
- 0x86, 0x6b, 0x0e, 0xf1, 0x0b, 0x07, 0x00,
- 0x86, 0x6b, 0x20, 0xdf, 0x0c, 0x07, 0x00,
- 0x86, 0x6b, 0x42, 0xbd, 0x0d, 0x07, 0x00,
- 0x86, 0x6b, 0x0b, 0xf4, 0x0e, 0x07, 0x00,
- 0x86, 0x6b, 0x43, 0xbc, 0x0f, 0x07, 0x00,
- 0x86, 0x6b, 0x10, 0xef, 0x10, 0x07, 0x00,
- 0x86, 0x6b, 0x21, 0xde, 0x11, 0x07, 0x00,
- 0x86, 0x6b, 0x13, 0xec, 0x12, 0x07, 0x00,
- 0x86, 0x6b, 0x11, 0xee, 0x13, 0x07, 0x00,
- 0x86, 0x6b, 0x12, 0xed, 0x14, 0x07, 0x00,
- 0x86, 0x6b, 0x19, 0xe6, 0x15, 0x07, 0x00,
- 0x86, 0x6b, 0x1a, 0xe5, 0x16, 0x07, 0x00,
- 0x86, 0x6b, 0x1b, 0xe4, 0x17, 0x07, 0x00,
- 0x86, 0x6b, 0x4b, 0xb4, 0x18, 0x07, 0x00,
- 0x86, 0x6b, 0x40, 0xbf, 0x19, 0x07, 0x00,
- 0x86, 0x6b, 0x44, 0xbb, 0x1a, 0x07, 0x00,
- 0x86, 0x6b, 0x41, 0xbe, 0x1b, 0x07, 0x00,
- 0x86, 0x6b, 0x22, 0xdd, 0x1c, 0x07, 0x00,
- 0x86, 0x6b, 0x15, 0xea, 0x1d, 0x07, 0x00,
- 0x86, 0x6b, 0x0f, 0xf0, 0x3f, 0x07, 0x00,
- 0x86, 0x6b, 0x1c, 0xe3, 0x40, 0x07, 0x00,
- 0x86, 0x6b, 0x4a, 0xb5, 0x41, 0x07, 0x00,
- 0x86, 0x6b, 0x48, 0xb7, 0x42, 0x07, 0x00,
- 0x86, 0x6b, 0x49, 0xb6, 0x43, 0x07, 0x00,
- 0x86, 0x6b, 0x18, 0xe7, 0x44, 0x07, 0x00,
- 0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00,
-};
-
-/* AverMedia Volar X */
-static struct ir_scancode ir_codes_af9015_table_avermedia[] = {
- { 0x053d, KEY_PROG1 }, /* SOURCE */
- { 0x0512, KEY_POWER }, /* POWER */
- { 0x051e, KEY_1 }, /* 1 */
- { 0x051f, KEY_2 }, /* 2 */
- { 0x0520, KEY_3 }, /* 3 */
- { 0x0521, KEY_4 }, /* 4 */
- { 0x0522, KEY_5 }, /* 5 */
- { 0x0523, KEY_6 }, /* 6 */
- { 0x0524, KEY_7 }, /* 7 */
- { 0x0525, KEY_8 }, /* 8 */
- { 0x0526, KEY_9 }, /* 9 */
- { 0x053f, KEY_LEFT }, /* L / DISPLAY */
- { 0x0527, KEY_0 }, /* 0 */
- { 0x050f, KEY_RIGHT }, /* R / CH RTN */
- { 0x0518, KEY_PROG2 }, /* SNAP SHOT */
- { 0x051c, KEY_PROG3 }, /* 16-CH PREV */
- { 0x052d, KEY_VOLUMEDOWN }, /* VOL DOWN */
- { 0x053e, KEY_ZOOM }, /* FULL SCREEN */
- { 0x052e, KEY_VOLUMEUP }, /* VOL UP */
- { 0x0510, KEY_MUTE }, /* MUTE */
- { 0x0504, KEY_AUDIO }, /* AUDIO */
- { 0x0515, KEY_RECORD }, /* RECORD */
- { 0x0511, KEY_PLAY }, /* PLAY */
- { 0x0516, KEY_STOP }, /* STOP */
- { 0x050c, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
- { 0x0505, KEY_BACK }, /* << / RED */
- { 0x0509, KEY_FORWARD }, /* >> / YELLOW */
- { 0x0517, KEY_TEXT }, /* TELETEXT */
- { 0x050a, KEY_EPG }, /* EPG */
- { 0x0513, KEY_MENU }, /* MENU */
-
- { 0x050e, KEY_CHANNELUP }, /* CH UP */
- { 0x050d, KEY_CHANNELDOWN }, /* CH DOWN */
- { 0x0519, KEY_FIRST }, /* |<< / GREEN */
- { 0x0508, KEY_LAST }, /* >>| / BLUE */
-};
-
-static u8 af9015_ir_table_avermedia[] = {
- 0x02, 0xfd, 0x00, 0xff, 0x12, 0x05, 0x00,
- 0x02, 0xfd, 0x01, 0xfe, 0x3d, 0x05, 0x00,
- 0x02, 0xfd, 0x03, 0xfc, 0x17, 0x05, 0x00,
- 0x02, 0xfd, 0x04, 0xfb, 0x0a, 0x05, 0x00,
- 0x02, 0xfd, 0x05, 0xfa, 0x1e, 0x05, 0x00,
- 0x02, 0xfd, 0x06, 0xf9, 0x1f, 0x05, 0x00,
- 0x02, 0xfd, 0x07, 0xf8, 0x20, 0x05, 0x00,
- 0x02, 0xfd, 0x09, 0xf6, 0x21, 0x05, 0x00,
- 0x02, 0xfd, 0x0a, 0xf5, 0x22, 0x05, 0x00,
- 0x02, 0xfd, 0x0b, 0xf4, 0x23, 0x05, 0x00,
- 0x02, 0xfd, 0x0d, 0xf2, 0x24, 0x05, 0x00,
- 0x02, 0xfd, 0x0e, 0xf1, 0x25, 0x05, 0x00,
- 0x02, 0xfd, 0x0f, 0xf0, 0x26, 0x05, 0x00,
- 0x02, 0xfd, 0x11, 0xee, 0x27, 0x05, 0x00,
- 0x02, 0xfd, 0x08, 0xf7, 0x04, 0x05, 0x00,
- 0x02, 0xfd, 0x0c, 0xf3, 0x3e, 0x05, 0x00,
- 0x02, 0xfd, 0x10, 0xef, 0x1c, 0x05, 0x00,
- 0x02, 0xfd, 0x12, 0xed, 0x3f, 0x05, 0x00,
- 0x02, 0xfd, 0x13, 0xec, 0x0f, 0x05, 0x00,
- 0x02, 0xfd, 0x14, 0xeb, 0x10, 0x05, 0x00,
- 0x02, 0xfd, 0x15, 0xea, 0x13, 0x05, 0x00,
- 0x02, 0xfd, 0x17, 0xe8, 0x18, 0x05, 0x00,
- 0x02, 0xfd, 0x18, 0xe7, 0x11, 0x05, 0x00,
- 0x02, 0xfd, 0x19, 0xe6, 0x15, 0x05, 0x00,
- 0x02, 0xfd, 0x1a, 0xe5, 0x0c, 0x05, 0x00,
- 0x02, 0xfd, 0x1b, 0xe4, 0x16, 0x05, 0x00,
- 0x02, 0xfd, 0x1c, 0xe3, 0x09, 0x05, 0x00,
- 0x02, 0xfd, 0x1d, 0xe2, 0x05, 0x05, 0x00,
- 0x02, 0xfd, 0x1e, 0xe1, 0x2d, 0x05, 0x00,
- 0x02, 0xfd, 0x1f, 0xe0, 0x2e, 0x05, 0x00,
- 0x03, 0xfc, 0x00, 0xff, 0x08, 0x05, 0x00,
- 0x03, 0xfc, 0x01, 0xfe, 0x19, 0x05, 0x00,
- 0x03, 0xfc, 0x02, 0xfd, 0x0d, 0x05, 0x00,
- 0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00,
-};
-
-static u8 af9015_ir_table_avermedia_ks[] = {
- 0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00,
- 0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00,
- 0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00,
- 0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00,
- 0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00,
- 0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00,
- 0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00,
- 0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00,
- 0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00,
- 0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00,
- 0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00,
- 0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00,
- 0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00,
- 0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00,
- 0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00,
- 0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00,
- 0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00,
- 0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00,
- 0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00,
- 0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00,
- 0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00,
- 0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00,
- 0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00,
- 0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00,
- 0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00,
- 0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00,
- 0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00
-};
-
-/* Digittrade DVB-T USB Stick */
-static struct ir_scancode ir_codes_af9015_table_digittrade[] = {
- { 0x010f, KEY_LAST }, /* RETURN */
- { 0x0517, KEY_TEXT }, /* TELETEXT */
- { 0x0108, KEY_EPG }, /* EPG */
- { 0x0513, KEY_POWER }, /* POWER */
- { 0x0109, KEY_ZOOM }, /* FULLSCREEN */
- { 0x0040, KEY_AUDIO }, /* DUAL SOUND */
- { 0x002c, KEY_PRINT }, /* SNAPSHOT */
- { 0x0516, KEY_SUBTITLE }, /* SUBTITLE */
- { 0x0052, KEY_CHANNELUP }, /* CH Up */
- { 0x0051, KEY_CHANNELDOWN },/* Ch Dn */
- { 0x0057, KEY_VOLUMEUP }, /* Vol Up */
- { 0x0056, KEY_VOLUMEDOWN }, /* Vol Dn */
- { 0x0110, KEY_MUTE }, /* MUTE */
- { 0x0027, KEY_0 },
- { 0x001e, KEY_1 },
- { 0x001f, KEY_2 },
- { 0x0020, KEY_3 },
- { 0x0021, KEY_4 },
- { 0x0022, KEY_5 },
- { 0x0023, KEY_6 },
- { 0x0024, KEY_7 },
- { 0x0025, KEY_8 },
- { 0x0026, KEY_9 },
- { 0x0117, KEY_PLAYPAUSE }, /* TIMESHIFT */
- { 0x0115, KEY_RECORD }, /* RECORD */
- { 0x0313, KEY_PLAY }, /* PLAY */
- { 0x0116, KEY_STOP }, /* STOP */
- { 0x0113, KEY_PAUSE }, /* PAUSE */
-};
-
-static u8 af9015_ir_table_digittrade[] = {
- 0x00, 0xff, 0x06, 0xf9, 0x13, 0x05, 0x00,
- 0x00, 0xff, 0x4d, 0xb2, 0x17, 0x01, 0x00,
- 0x00, 0xff, 0x1f, 0xe0, 0x2c, 0x00, 0x00,
- 0x00, 0xff, 0x0a, 0xf5, 0x15, 0x01, 0x00,
- 0x00, 0xff, 0x0e, 0xf1, 0x16, 0x01, 0x00,
- 0x00, 0xff, 0x09, 0xf6, 0x09, 0x01, 0x00,
- 0x00, 0xff, 0x01, 0xfe, 0x08, 0x01, 0x00,
- 0x00, 0xff, 0x05, 0xfa, 0x10, 0x01, 0x00,
- 0x00, 0xff, 0x02, 0xfd, 0x56, 0x00, 0x00,
- 0x00, 0xff, 0x40, 0xbf, 0x57, 0x00, 0x00,
- 0x00, 0xff, 0x19, 0xe6, 0x52, 0x00, 0x00,
- 0x00, 0xff, 0x17, 0xe8, 0x51, 0x00, 0x00,
- 0x00, 0xff, 0x10, 0xef, 0x0f, 0x01, 0x00,
- 0x00, 0xff, 0x54, 0xab, 0x27, 0x00, 0x00,
- 0x00, 0xff, 0x1b, 0xe4, 0x1e, 0x00, 0x00,
- 0x00, 0xff, 0x11, 0xee, 0x1f, 0x00, 0x00,
- 0x00, 0xff, 0x15, 0xea, 0x20, 0x00, 0x00,
- 0x00, 0xff, 0x12, 0xed, 0x21, 0x00, 0x00,
- 0x00, 0xff, 0x16, 0xe9, 0x22, 0x00, 0x00,
- 0x00, 0xff, 0x4c, 0xb3, 0x23, 0x00, 0x00,
- 0x00, 0xff, 0x48, 0xb7, 0x24, 0x00, 0x00,
- 0x00, 0xff, 0x04, 0xfb, 0x25, 0x00, 0x00,
- 0x00, 0xff, 0x00, 0xff, 0x26, 0x00, 0x00,
- 0x00, 0xff, 0x1e, 0xe1, 0x13, 0x03, 0x00,
- 0x00, 0xff, 0x1a, 0xe5, 0x13, 0x01, 0x00,
- 0x00, 0xff, 0x03, 0xfc, 0x17, 0x05, 0x00,
- 0x00, 0xff, 0x0d, 0xf2, 0x16, 0x05, 0x00,
- 0x00, 0xff, 0x1d, 0xe2, 0x40, 0x00, 0x00,
-};
-
-/* TREKSTOR DVB-T USB Stick */
-static struct ir_scancode ir_codes_af9015_table_trekstor[] = {
- { 0x0704, KEY_AGAIN }, /* Home */
- { 0x0705, KEY_MUTE }, /* Mute */
- { 0x0706, KEY_UP }, /* Up */
- { 0x0707, KEY_DOWN }, /* Down */
- { 0x0709, KEY_RIGHT }, /* Right */
- { 0x070a, KEY_ENTER }, /* OK */
- { 0x070b, KEY_FASTFORWARD }, /* Fast forward */
- { 0x070c, KEY_REWIND }, /* Rewind */
- { 0x070d, KEY_PLAY }, /* Play/Pause */
- { 0x070e, KEY_VOLUMEUP }, /* Volume + */
- { 0x070f, KEY_VOLUMEDOWN }, /* Volume - */
- { 0x0710, KEY_RECORD }, /* Record */
- { 0x0711, KEY_STOP }, /* Stop */
- { 0x0712, KEY_ZOOM }, /* TV */
- { 0x0713, KEY_EPG }, /* Info/EPG */
- { 0x0714, KEY_CHANNELDOWN }, /* Channel - */
- { 0x0715, KEY_CHANNELUP }, /* Channel + */
- { 0x071e, KEY_1 },
- { 0x071f, KEY_2 },
- { 0x0720, KEY_3 },
- { 0x0721, KEY_4 },
- { 0x0722, KEY_5 },
- { 0x0723, KEY_6 },
- { 0x0724, KEY_7 },
- { 0x0725, KEY_8 },
- { 0x0726, KEY_9 },
- { 0x0708, KEY_LEFT }, /* LEFT */
- { 0x0727, KEY_0 },
-};
-
-static u8 af9015_ir_table_trekstor[] = {
- 0x00, 0xff, 0x86, 0x79, 0x04, 0x07, 0x00,
- 0x00, 0xff, 0x85, 0x7a, 0x05, 0x07, 0x00,
- 0x00, 0xff, 0x87, 0x78, 0x06, 0x07, 0x00,
- 0x00, 0xff, 0x8c, 0x73, 0x07, 0x07, 0x00,
- 0x00, 0xff, 0x89, 0x76, 0x09, 0x07, 0x00,
- 0x00, 0xff, 0x88, 0x77, 0x0a, 0x07, 0x00,
- 0x00, 0xff, 0x8a, 0x75, 0x0b, 0x07, 0x00,
- 0x00, 0xff, 0x9e, 0x61, 0x0c, 0x07, 0x00,
- 0x00, 0xff, 0x8d, 0x72, 0x0d, 0x07, 0x00,
- 0x00, 0xff, 0x8b, 0x74, 0x0e, 0x07, 0x00,
- 0x00, 0xff, 0x9b, 0x64, 0x0f, 0x07, 0x00,
- 0x00, 0xff, 0x9d, 0x62, 0x10, 0x07, 0x00,
- 0x00, 0xff, 0x8e, 0x71, 0x11, 0x07, 0x00,
- 0x00, 0xff, 0x9c, 0x63, 0x12, 0x07, 0x00,
- 0x00, 0xff, 0x8f, 0x70, 0x13, 0x07, 0x00,
- 0x00, 0xff, 0x93, 0x6c, 0x14, 0x07, 0x00,
- 0x00, 0xff, 0x97, 0x68, 0x15, 0x07, 0x00,
- 0x00, 0xff, 0x92, 0x6d, 0x1e, 0x07, 0x00,
- 0x00, 0xff, 0x96, 0x69, 0x1f, 0x07, 0x00,
- 0x00, 0xff, 0x9a, 0x65, 0x20, 0x07, 0x00,
- 0x00, 0xff, 0x91, 0x6e, 0x21, 0x07, 0x00,
- 0x00, 0xff, 0x95, 0x6a, 0x22, 0x07, 0x00,
- 0x00, 0xff, 0x99, 0x66, 0x23, 0x07, 0x00,
- 0x00, 0xff, 0x90, 0x6f, 0x24, 0x07, 0x00,
- 0x00, 0xff, 0x94, 0x6b, 0x25, 0x07, 0x00,
- 0x00, 0xff, 0x98, 0x67, 0x26, 0x07, 0x00,
- 0x00, 0xff, 0x9f, 0x60, 0x08, 0x07, 0x00,
- 0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00,
-};
-
-/* MSI DIGIVOX mini III */
-static struct ir_scancode ir_codes_af9015_table_msi_digivox_iii[] = {
- { 0x0713, KEY_POWER }, /* [red power button] */
- { 0x073b, KEY_VIDEO }, /* Source */
- { 0x073e, KEY_ZOOM }, /* Zoom */
- { 0x070b, KEY_POWER2 }, /* ShutDown */
- { 0x071e, KEY_1 },
- { 0x071f, KEY_2 },
- { 0x0720, KEY_3 },
- { 0x0721, KEY_4 },
- { 0x0722, KEY_5 },
- { 0x0723, KEY_6 },
- { 0x0724, KEY_7 },
- { 0x0725, KEY_8 },
- { 0x0726, KEY_9 },
- { 0x0727, KEY_0 },
- { 0x0752, KEY_CHANNELUP }, /* CH+ */
- { 0x0751, KEY_CHANNELDOWN }, /* CH- */
- { 0x0750, KEY_VOLUMEUP }, /* Vol+ */
- { 0x074f, KEY_VOLUMEDOWN }, /* Vol- */
- { 0x0705, KEY_ESC }, /* [back up arrow] */
- { 0x0708, KEY_OK }, /* [enter arrow] */
- { 0x073f, KEY_RECORD }, /* Rec */
- { 0x0716, KEY_STOP }, /* Stop */
- { 0x072a, KEY_PLAY }, /* Play */
- { 0x073c, KEY_MUTE }, /* Mute */
- { 0x0718, KEY_UP },
- { 0x0707, KEY_DOWN },
- { 0x070f, KEY_LEFT },
- { 0x0715, KEY_RIGHT },
- { 0x0736, KEY_RED },
- { 0x0737, KEY_GREEN },
- { 0x072d, KEY_YELLOW },
- { 0x072e, KEY_BLUE },
-};
-
-static u8 af9015_ir_table_msi_digivox_iii[] = {
- 0x61, 0xd6, 0x43, 0xbc, 0x13, 0x07, 0x00, /* KEY_POWER */
- 0x61, 0xd6, 0x01, 0xfe, 0x3b, 0x07, 0x00, /* KEY_VIDEO */
- 0x61, 0xd6, 0x0b, 0xf4, 0x3e, 0x07, 0x00, /* KEY_ZOOM */
- 0x61, 0xd6, 0x03, 0xfc, 0x0b, 0x07, 0x00, /* KEY_POWER2 */
- 0x61, 0xd6, 0x04, 0xfb, 0x1e, 0x07, 0x00, /* KEY_1 */
- 0x61, 0xd6, 0x08, 0xf7, 0x1f, 0x07, 0x00, /* KEY_2 */
- 0x61, 0xd6, 0x02, 0xfd, 0x20, 0x07, 0x00, /* KEY_3 */
- 0x61, 0xd6, 0x0f, 0xf0, 0x21, 0x07, 0x00, /* KEY_4 */
- 0x61, 0xd6, 0x05, 0xfa, 0x22, 0x07, 0x00, /* KEY_5 */
- 0x61, 0xd6, 0x06, 0xf9, 0x23, 0x07, 0x00, /* KEY_6 */
- 0x61, 0xd6, 0x0c, 0xf3, 0x24, 0x07, 0x00, /* KEY_7 */
- 0x61, 0xd6, 0x0d, 0xf2, 0x25, 0x07, 0x00, /* KEY_8 */
- 0x61, 0xd6, 0x0a, 0xf5, 0x26, 0x07, 0x00, /* KEY_9 */
- 0x61, 0xd6, 0x11, 0xee, 0x27, 0x07, 0x00, /* KEY_0 */
- 0x61, 0xd6, 0x09, 0xf6, 0x52, 0x07, 0x00, /* KEY_CHANNELUP */
- 0x61, 0xd6, 0x07, 0xf8, 0x51, 0x07, 0x00, /* KEY_CHANNELDOWN */
- 0x61, 0xd6, 0x0e, 0xf1, 0x50, 0x07, 0x00, /* KEY_VOLUMEUP */
- 0x61, 0xd6, 0x13, 0xec, 0x4f, 0x07, 0x00, /* KEY_VOLUMEDOWN */
- 0x61, 0xd6, 0x10, 0xef, 0x05, 0x07, 0x00, /* KEY_ESC */
- 0x61, 0xd6, 0x12, 0xed, 0x08, 0x07, 0x00, /* KEY_OK */
- 0x61, 0xd6, 0x14, 0xeb, 0x3f, 0x07, 0x00, /* KEY_RECORD */
- 0x61, 0xd6, 0x15, 0xea, 0x16, 0x07, 0x00, /* KEY_STOP */
- 0x61, 0xd6, 0x16, 0xe9, 0x2a, 0x07, 0x00, /* KEY_PLAY */
- 0x61, 0xd6, 0x17, 0xe8, 0x3c, 0x07, 0x00, /* KEY_MUTE */
- 0x61, 0xd6, 0x18, 0xe7, 0x18, 0x07, 0x00, /* KEY_UP */
- 0x61, 0xd6, 0x19, 0xe6, 0x07, 0x07, 0x00, /* KEY_DOWN */
- 0x61, 0xd6, 0x1a, 0xe5, 0x0f, 0x07, 0x00, /* KEY_LEFT */
- 0x61, 0xd6, 0x1b, 0xe4, 0x15, 0x07, 0x00, /* KEY_RIGHT */
- 0x61, 0xd6, 0x1c, 0xe3, 0x36, 0x07, 0x00, /* KEY_RED */
- 0x61, 0xd6, 0x1d, 0xe2, 0x37, 0x07, 0x00, /* KEY_GREEN */
- 0x61, 0xd6, 0x1e, 0xe1, 0x2d, 0x07, 0x00, /* KEY_YELLOW */
- 0x61, 0xd6, 0x1f, 0xe0, 0x2e, 0x07, 0x00, /* KEY_BLUE */
-};
-
#endif
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 4685259e1614..1759d26bca42 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -354,7 +354,7 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
{
struct anysee_state *state = adap->dev->priv;
- deb_info("%s: \n", __func__);
+ deb_info("%s:\n", __func__);
switch (state->tuner) {
case DVB_PLL_THOMSON_DTT7579:
@@ -374,78 +374,32 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
-static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int anysee_rc_query(struct dvb_usb_device *d)
{
u8 buf[] = {CMD_GET_IR_CODE};
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
u8 ircode[2];
- int i, ret;
+ int ret;
+
+ /* Remote controller is basic NEC using address byte 0x08.
+ Anysee device RC query returns only two bytes, status and code,
+ address byte is dropped. Also it does not return any value for
+ NEC RCs having address byte other than 0x08. Due to that, we
+ cannot use that device as standard NEC receiver.
+ It could be possible make hack which reads whole code directly
+ from device memory... */
- ret = anysee_ctrl_msg(d, buf, sizeof(buf), &ircode[0], 2);
+ ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
if (ret)
return ret;
- *event = 0;
- *state = REMOTE_NO_KEY_PRESSED;
-
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
- if (rc5_custom(&keymap[i]) == ircode[0] &&
- rc5_data(&keymap[i]) == ircode[1]) {
- *event = keymap[i].keycode;
- *state = REMOTE_KEY_PRESSED;
- return 0;
- }
+ if (ircode[0]) {
+ deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
+ ir_keydown(d->rc_input_dev, 0x08 << 8 | ircode[1], 0);
}
+
return 0;
}
-static struct ir_scancode ir_codes_anysee_table[] = {
- { 0x0100, KEY_0 },
- { 0x0101, KEY_1 },
- { 0x0102, KEY_2 },
- { 0x0103, KEY_3 },
- { 0x0104, KEY_4 },
- { 0x0105, KEY_5 },
- { 0x0106, KEY_6 },
- { 0x0107, KEY_7 },
- { 0x0108, KEY_8 },
- { 0x0109, KEY_9 },
- { 0x010a, KEY_POWER },
- { 0x010b, KEY_DOCUMENTS }, /* * */
- { 0x0119, KEY_FAVORITES },
- { 0x0120, KEY_SLEEP },
- { 0x0121, KEY_MODE }, /* 4:3 / 16:9 select */
- { 0x0122, KEY_ZOOM },
- { 0x0147, KEY_TEXT },
- { 0x0116, KEY_TV }, /* TV / radio select */
- { 0x011e, KEY_LANGUAGE }, /* Second Audio Program */
- { 0x011a, KEY_SUBTITLE },
- { 0x011b, KEY_CAMERA }, /* screenshot */
- { 0x0142, KEY_MUTE },
- { 0x010e, KEY_MENU },
- { 0x010f, KEY_EPG },
- { 0x0117, KEY_INFO },
- { 0x0110, KEY_EXIT },
- { 0x0113, KEY_VOLUMEUP },
- { 0x0112, KEY_VOLUMEDOWN },
- { 0x0111, KEY_CHANNELUP },
- { 0x0114, KEY_CHANNELDOWN },
- { 0x0115, KEY_OK },
- { 0x011d, KEY_RED },
- { 0x011f, KEY_GREEN },
- { 0x011c, KEY_YELLOW },
- { 0x0144, KEY_BLUE },
- { 0x010c, KEY_SHUFFLE }, /* snapshot */
- { 0x0148, KEY_STOP },
- { 0x0150, KEY_PLAY },
- { 0x0151, KEY_PAUSE },
- { 0x0149, KEY_RECORD },
- { 0x0118, KEY_PREVIOUS }, /* |<< */
- { 0x010d, KEY_NEXT }, /* >>| */
- { 0x0124, KEY_PROG1 }, /* F1 */
- { 0x0125, KEY_PROG2 }, /* F2 */
-};
-
/* DVB USB Driver stuff */
static struct dvb_usb_device_properties anysee_properties;
@@ -520,11 +474,12 @@ static struct dvb_usb_device_properties anysee_properties = {
}
},
- .rc.legacy = {
- .rc_key_map = ir_codes_anysee_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_anysee_table),
+ .rc.core = {
+ .rc_codes = RC_MAP_ANYSEE,
+ .protocol = IR_TYPE_OTHER,
+ .module_name = "anysee",
.rc_query = anysee_rc_query,
- .rc_interval = 200, /* windows driver uses 500ms */
+ .rc_interval = 250, /* windows driver uses 500ms */
},
.i2c_algo = &anysee_i2c_algo,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index cead089bbb4f..88e4a62abc44 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -20,7 +20,6 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
}
strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
- d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
d->i2c_adap.algo = d->props.i2c_algo;
d->i2c_adap.algo_data = NULL;
d->i2c_adap.dev.parent = &d->udev->dev;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 1a774d58d664..192a40ce583d 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -32,6 +32,7 @@
#define USB_VID_EMPIA 0xeb1a
#define USB_VID_GENPIX 0x09c0
#define USB_VID_GRANDTEC 0x5032
+#define USB_VID_GTEK 0x1f4d
#define USB_VID_HANFTEK 0x15f4
#define USB_VID_HAUPPAUGE 0x2040
#define USB_VID_HYPER_PALTEK 0x1025
@@ -133,6 +134,8 @@
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069
+#define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097
+#define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC 0x0099
#define USB_PID_TWINHAN_VP7041_COLD 0x3201
#define USB_PID_TWINHAN_VP7041_WARM 0x3202
#define USB_PID_TWINHAN_VP7020_COLD 0x3203
@@ -143,6 +146,7 @@
#define USB_PID_TWINHAN_VP7021_WARM 0x3208
#define USB_PID_TINYTWIN 0x3226
#define USB_PID_TINYTWIN_2 0xe402
+#define USB_PID_TINYTWIN_3 0x9016
#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
@@ -196,6 +200,7 @@
#define USB_PID_AVERMEDIA_A309 0xa309
#define USB_PID_AVERMEDIA_A310 0xa310
#define USB_PID_AVERMEDIA_A850 0x850a
+#define USB_PID_AVERMEDIA_A850T 0x850b
#define USB_PID_AVERMEDIA_A805 0xa805
#define USB_PID_AVERMEDIA_A815M 0x815a
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
@@ -268,6 +273,7 @@
#define USB_PID_GENPIX_8PSK_REV_2 0x0202
#define USB_PID_GENPIX_SKYWALKER_1 0x0203
#define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204
+#define USB_PID_GENPIX_SKYWALKER_2 0x0206
#define USB_PID_SIGMATEK_DVB_110 0x6610
#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
#define USB_PID_MSI_DIGIVOX_DUO 0x8801
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
index 93c21ddd0b77..015b4e8af1a5 100644
--- a/drivers/media/dvb/dvb-usb/friio-fe.c
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -75,7 +75,7 @@ static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
return 0;
}
-static int _jdvbt90502_write(struct dvb_frontend *fe, u8 *buf, int len)
+static int _jdvbt90502_write(struct dvb_frontend *fe, const u8 buf[], int len)
{
struct jdvbt90502_state *state = fe->demodulator_priv;
int err, i;
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
index dbdb5347b2a8..60d11e57e7d0 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
@@ -109,7 +109,7 @@ static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength
static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
{
- tune->min_delay_ms = 200;
+ tune->min_delay_ms = 800;
return 0;
}
@@ -334,7 +334,7 @@ success:
static struct dvb_frontend_ops gp8psk_fe_ops = {
.info = {
- .name = "Genpix 8psk-to-USB2 DVB-S",
+ .name = "Genpix DVB-S",
.type = FE_QPSK,
.frequency_min = 800000,
.frequency_max = 2250000,
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
index 45106ac49674..c821293dbc22 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -227,6 +227,7 @@ static struct usb_device_id gp8psk_usb_table [] = {
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
+ { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_2) },
/* { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */
{ 0 },
};
@@ -258,7 +259,7 @@ static struct dvb_usb_device_properties gp8psk_properties = {
.generic_bulk_ctrl_endpoint = 0x01,
- .num_device_descs = 3,
+ .num_device_descs = 4,
.devices = {
{ .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
.cold_ids = { &gp8psk_usb_table[0], NULL },
@@ -272,6 +273,10 @@ static struct dvb_usb_device_properties gp8psk_properties = {
.cold_ids = { NULL },
.warm_ids = { &gp8psk_usb_table[3], NULL },
},
+ { .name = "Genpix SkyWalker-2 DVB-S receiver",
+ .cold_ids = { NULL },
+ .warm_ids = { &gp8psk_usb_table[4], NULL },
+ },
{ NULL },
}
};
@@ -306,6 +311,6 @@ module_init(gp8psk_usb_module_init);
module_exit(gp8psk_usb_module_exit);
MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
-MODULE_DESCRIPTION("Driver for Genpix 8psk-to-USB2 DVB-S");
+MODULE_DESCRIPTION("Driver for Genpix DVB-S");
MODULE_VERSION("1.1");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
new file mode 100644
index 000000000000..d939fbbf9fe6
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -0,0 +1,1088 @@
+/* DVB USB compliant linux driver for
+ *
+ * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
+ * LME2510C + LG TDQY-P001F
+ * LME2510 + LG TDQY-P001F
+ *
+ * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
+ * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
+ *
+ * MV001F (LME2510+LGTDQY-P001F)
+ * LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ * MVB0001F (LME2510C+LGTDQT-P001F)
+ *
+ * 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***
+ * 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.
+ *
+ * QQbox suffers from noise on LNB voltage.
+ *
+ * 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);
+
+static int dvb_usb_lme2510_firmware;
+module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
+MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
+
+
+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;
+ u8 stream_on;
+ u8 one_tune;
+ 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));
+
+ ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
+
+ msleep(12);
+
+ ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01));
+
+ ret |= lme2510_bulk_read(d->udev, buff, (rlen > 512) ?
+ 512 : rlen , 0x01);
+
+ if (rlen > 0)
+ memcpy(rbuf, buff, rlen);
+
+ mutex_unlock(&d->usb_mutex);
+
+ return (ret < 0) ? -ENODEV : 0;
+}
+
+static int lme2510_usb_talk_restart(struct dvb_usb_device *d,
+ u8 *wbuf, int wlen, u8 *rbuf, int rlen) {
+ static u8 stream_on[] = LME_ST_ON_W;
+ int ret;
+ u8 rbuff[10];
+ /*Send Normal Command*/
+ ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+ /*Restart Stream Command*/
+ ret |= lme2510_usb_talk(d, stream_on, sizeof(stream_on),
+ rbuff, sizeof(rbuff));
+ return ret;
+}
+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:
+ if (ibuf[2] > 0)
+ st->signal_lock = ibuf[2];
+ st->signal_level = ibuf[4];
+ st->signal_sn = ibuf[3];
+ st->time_key = ibuf[7];
+ break;
+ case TUNER_S7395:
+ /* Tweak for earlier firmware*/
+ if (ibuf[1] == 0x03) {
+ st->signal_level = ibuf[3];
+ st->signal_sn = ibuf[4];
+ } 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 (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ if (st->i2c_talk_onoff == 1) {
+
+ ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+
+ switch (st->tuner_config) {
+ case TUNER_LG:
+ if (wbuf[2] == 0x1c) {
+ if (wbuf[3] == 0x0e) {
+ st->signal_lock = rbuf[1];
+ if ((st->stream_on & 1) &&
+ (st->signal_lock & 0x10)) {
+ lme2510_usb_talk_restart(d,
+ wbuf, wlen, rbuf, rlen);
+ st->i2c_talk_onoff = 0;
+ }
+ msleep(80);
+ }
+ }
+ break;
+ case TUNER_S7395:
+ if (wbuf[2] == 0xd0) {
+ if (wbuf[3] == 0x24) {
+ st->signal_lock = rbuf[1];
+ if ((st->stream_on & 1) &&
+ (st->signal_lock & 0x8)) {
+ lme2510_usb_talk_restart(d,
+ wbuf, wlen, rbuf, rlen);
+ st->i2c_talk_onoff = 0;
+ }
+ }
+ if ((wbuf[3] != 0x6) & (wbuf[3] != 0x5))
+ msleep(5);
+
+
+ }
+ 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;
+ /*DiSEqC functions as per TDA10086*/
+ case 0x36:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ if (wbuf[2] == 0x1c)
+ lme2510_usb_talk_restart(d,
+ wbuf, wlen, rbuf, rlen);
+ 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;
+ break;
+ case 0x6:
+ if (wbuf[2] == 0xd0)
+ lme2510_usb_talk(d,
+ wbuf, wlen, rbuf, rlen);
+ break;
+ case 0x1:
+ if (st->one_tune > 0)
+ break;
+ st->one_tune++;
+ st->i2c_talk_onoff = 1;
+ /*DiSEqC functions as per STV0288*/
+ case 0x5:
+ case 0x7:
+ case 0x8:
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ if (wbuf[2] == 0xd0)
+ lme2510_usb_talk_restart(d,
+ wbuf, wlen, rbuf, rlen);
+ break;
+ default:
+ rbuf[0] = 0x55;
+ rbuf[1] = 0x00;
+ break;
+ }
+ break;
+ default:
+ break;
+
+ }
+
+ deb_info(4, "I2C From Interupt Message out(%02x) in(%02x)",
+ wbuf[3], rbuf[1]);
+
+ }
+
+ mutex_unlock(&d->i2c_mutex);
+
+ 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 stream_on[] = LME_ST_ON_W;
+ static u8 clear_reg_3[] = LME_CLEAR_PID;
+ static u8 rbuf[1];
+ static u8 timeout;
+ int ret = 0, len = 2, rlen = sizeof(rbuf);
+
+ deb_info(1, "STM (%02x)", onoff);
+
+ if (onoff == 1) {
+ st->i2c_talk_onoff = 0;
+ timeout = 0;
+ /* wait for i2C to be free */
+ while (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) {
+ timeout++;
+ if (timeout > 5)
+ return -ENODEV;
+ }
+ msleep(100);
+ ret |= lme2510_usb_talk(adap->dev,
+ stream_on, len, rbuf, rlen);
+ st->stream_on = 1;
+ st->one_tune = 0;
+ mutex_unlock(&adap->dev->i2c_mutex);
+ } else {
+ deb_info(1, "STM Steam Off");
+ ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
+ sizeof(clear_reg_3), rbuf, rlen);
+ st->stream_on = 0;
+ 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;
+}
+
+/* Default firmware for LME2510C */
+const char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw";
+
+static void lme_coldreset(struct usb_device *dev)
+{
+ int ret = 0, len_in;
+ u8 data[512] = {0};
+
+ data[0] = 0x0a;
+ len_in = 1;
+ info("FRM Firmware Cold Reset");
+ ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Cold Resetting*/
+ ret |= lme2510_bulk_read(dev, data, len_in, 1);
+ return;
+}
+
+static void lme_firmware_switch(struct usb_device *udev, int cold)
+{
+ const struct firmware *fw = NULL;
+ char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
+ char lme2510c_lg[] = "dvb-usb-lme2510c-lg.fw";
+ char *firm_msg[] = {"Loading", "Switching to"};
+ int ret;
+
+ if (udev->descriptor.idProduct == 0x1122)
+ return;
+
+ switch (dvb_usb_lme2510_firmware) {
+ case 0:
+ default:
+ memcpy(&lme_firmware, lme2510c_s7395, sizeof(lme2510c_s7395));
+ ret = request_firmware(&fw, lme_firmware, &udev->dev);
+ if (ret == 0) {
+ info("FRM %s S7395 Firmware", firm_msg[cold]);
+ break;
+ }
+ if (cold == 0)
+ dvb_usb_lme2510_firmware = 1;
+ else
+ cold = 0;
+ case 1:
+ memcpy(&lme_firmware, lme2510c_lg, sizeof(lme2510c_lg));
+ ret = request_firmware(&fw, lme_firmware, &udev->dev);
+ if (ret == 0) {
+ info("FRM %s LG Firmware", firm_msg[cold]);
+ break;
+ }
+ info("FRM No Firmware Found - please install");
+ dvb_usb_lme2510_firmware = 0;
+ cold = 0;
+ break;
+ }
+ release_firmware(fw);
+ if (cold)
+ lme_coldreset(udev);
+ return;
+}
+
+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 lnb_on[] = LNB_ON;
+ static u8 lnb_off[] = LNB_OFF;
+ static u8 rbuf[1];
+ int ret = 0, len = 3, rlen = 1;
+
+ if (st->stream_on == 1)
+ return 0;
+
+ ret |= lme2510_usb_talk(adap->dev, lnb_on, len, rbuf, rlen);
+
+ switch (voltage) {
+ case SEC_VOLTAGE_18:
+ ret |= lme2510_usb_talk(adap->dev,
+ voltage_high, len, rbuf, rlen);
+ break;
+
+ case SEC_VOLTAGE_OFF:
+ ret |= lme2510_usb_talk(adap->dev,
+ lnb_off, len, rbuf, rlen);
+ 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;
+ if (dvb_usb_lme2510_firmware != 1) {
+ dvb_usb_lme2510_firmware = 1;
+ lme_firmware_switch(adap->dev->udev, 1);
+ }
+ 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");
+ if (dvb_usb_lme2510_firmware != 0) {
+ dvb_usb_lme2510_firmware = 0;
+ lme_firmware_switch(adap->dev->udev, 1);
+ }
+ 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;
+ }
+
+ lme_firmware_switch(udev, 0);
+
+ 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 = lme_firmware,
+ .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 = 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;
+ struct dvb_usb_adapter *adap = &d->adapter[0];
+ void *buffer = NULL;
+
+ if (adap != NULL) {
+ lme2510_kill_urb(&adap->stream);
+ adap->feedcount = 0;
+ }
+
+ if (st->lme_urb != NULL) {
+ st->i2c_talk_onoff = 1;
+ st->signal_lock = 0;
+ st->signal_level = 0;
+ st->signal_sn = 0;
+ buffer = 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 buffer;
+}
+
+void lme2510_exit(struct usb_interface *intf)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ void *usb_buffer;
+
+ if (d != NULL) {
+ usb_buffer = lme2510_exit_int(d);
+ dvb_usb_device_exit(intf);
+ kfree(usb_buffer);
+ }
+}
+
+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.60");
+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 000000000000..e6af16c1e3e5
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/lmedm04.h
@@ -0,0 +1,173 @@
+/* DVB USB compliant linux driver for
+ *
+ * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
+ * LME2510C + LG TDQY-P001F
+ * LME2510 + LG TDQY-P001F
+ *
+ * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
+ * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
+ *
+ * MVB001F (LME2510+LGTDQT-P001F)
+ * LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ * MVB0001F (LME2510C+LGTDQT-P001F)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ * *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_LME2510_H_
+#define _DVB_USB_LME2510_H_
+
+/* Streamer & PID
+ *
+ * Note: These commands do not actually stop the streaming
+ * but form some kind of packet filtering/stream count
+ * or tuning related functions.
+ * 06 XX
+ * offset 1 = 00 Enable Streaming
+ *
+ *
+ * PID
+ * 03 XX XX ----> reg number ---> setting....20 XX
+ * offset 1 = length
+ * offset 2 = start of data
+ * end byte -1 = 20
+ * end byte = clear pid always a0, other wise 9c, 9a ??
+ *
+*/
+#define LME_ST_ON_W {0x06, 0x00}
+#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0}
+
+/* LNB Voltage
+ * 07 XX XX
+ * offset 1 = 01
+ * offset 2 = 00=Voltage low 01=Voltage high
+ *
+ * LNB Power
+ * 03 01 XX
+ * offset 2 = 00=ON 01=OFF
+ */
+
+#define LME_VOLTAGE_L {0x07, 0x01, 0x00}
+#define LME_VOLTAGE_H {0x07, 0x01, 0x01}
+#define LNB_ON {0x3a, 0x01, 0x00}
+#define LNB_OFF {0x3a, 0x01, 0x01}
+
+/* Initial stv0288 settings for 7395 Frontend */
+static u8 s7395_inittab[] = {
+ 0x01, 0x15,
+ 0x02, 0x20,
+ 0x03, 0xa0,
+ 0x04, 0xa0,
+ 0x05, 0x12,
+ 0x06, 0x00,
+ 0x09, 0x00,
+ 0x0a, 0x04,
+ 0x0b, 0x00,
+ 0x0c, 0x00,
+ 0x0d, 0x00,
+ 0x0e, 0xc1,
+ 0x0f, 0x54,
+ 0x11, 0x7a,
+ 0x12, 0x03,
+ 0x13, 0x48,
+ 0x14, 0x84,
+ 0x15, 0xc5,
+ 0x16, 0xb8,
+ 0x17, 0x9c,
+ 0x18, 0x00,
+ 0x19, 0xa6,
+ 0x1a, 0x88,
+ 0x1b, 0x8f,
+ 0x1c, 0xf0,
+ 0x20, 0x0b,
+ 0x21, 0x54,
+ 0x22, 0xff,
+ 0x23, 0x01,
+ 0x28, 0x46,
+ 0x29, 0x66,
+ 0x2a, 0x90,
+ 0x2b, 0xfa,
+ 0x2c, 0xd9,
+ 0x30, 0x0,
+ 0x31, 0x1e,
+ 0x32, 0x14,
+ 0x33, 0x0f,
+ 0x34, 0x09,
+ 0x35, 0x0c,
+ 0x36, 0x05,
+ 0x37, 0x2f,
+ 0x38, 0x16,
+ 0x39, 0xbd,
+ 0x3a, 0x0,
+ 0x3b, 0x13,
+ 0x3c, 0x11,
+ 0x3d, 0x30,
+ 0x40, 0x63,
+ 0x41, 0x04,
+ 0x42, 0x60,
+ 0x43, 0x00,
+ 0x44, 0x00,
+ 0x45, 0x00,
+ 0x46, 0x00,
+ 0x47, 0x00,
+ 0x4a, 0x00,
+ 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