diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/Kconfig | 12 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.c | 394 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.h | 735 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/anysee.c | 87 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 6 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/friio-fe.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/gp8psk-fe.c | 4 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/gp8psk.c | 9 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/lmedm04.c | 1088 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/lmedm04.h | 173 |
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 |