diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-28 09:35:11 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-28 09:35:11 -0700 |
commit | 0851668fdd97e526b2a41f794b785c204dd3d3e0 (patch) | |
tree | 4ef7c20a8be8393006c6fe9627eb29dd30877d61 /drivers/media/dvb | |
parent | 00ebb6382b8d9c7c15b5f8ad230670d8161d38dd (diff) | |
parent | 7655e594945289b418af39f6669fea4666a7b520 (diff) | |
download | op-kernel-dev-0851668fdd97e526b2a41f794b785c204dd3d3e0.zip op-kernel-dev-0851668fdd97e526b2a41f794b785c204dd3d3e0.tar.gz |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (505 commits)
[media] af9015: Fix max I2C message size when used with tda18271
[media] IR: initialize ir_raw_event in few more drivers
[media] Guard a divide in v4l1 compat layer
[media] imon: fix nomouse modprobe option
[media] imon: remove redundant change_protocol call
[media] imon: fix my egregious brown paper bag w/rdev/idev split
[media] cafe_ccic: Configure ov7670 correctly
[media] ov7670: allow configuration of image size, clock speed, and I/O method
[media] af9015: support for DigitalNow TinyTwin v3 [1f4d:9016]
[media] af9015: map DigitalNow TinyTwin v2 remote
[media] DigitalNow TinyTwin remote controller
[media] af9015: RC fixes and improvements
videodev2.h.xml: Update to reflect the latest changes at videodev2.h
[media] v4l: document new Bayer and monochrome pixel formats
[media] DocBook/v4l: Add missing formats used on gspca cpia1 and sn9c2028
[media] firedtv: add parameter to fake ca_system_ids in CA_INFO
[media] tm6000: fix a macro coding style issue
tm6000: Remove some ugly debug code
[media] Nova-S-Plus audio line input
[media] [RFC,1/1] V4L2: Use new CAP bits in existing RDS capable drivers
...
Diffstat (limited to 'drivers/media/dvb')
59 files changed, 2760 insertions, 1756 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index fd1df23..965d5eb 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -245,9 +245,6 @@ int flexcop_i2c_init(struct flexcop_device *fc) i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]); i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]); - fc->fc_i2c_adap[0].i2c_adap.class = - fc->fc_i2c_adap[1].i2c_adap.class = - fc->fc_i2c_adap[2].i2c_adap.class = I2C_CLASS_TV_DIGITAL; fc->fc_i2c_adap[0].i2c_adap.algo = fc->fc_i2c_adap[1].i2c_adap.algo = fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo; diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index bca07c0..5d404f1 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -862,7 +862,6 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, i2c_set_adapdata(&dev->i2c_adap, dev); strcpy(dev->i2c_adap.name, DRIVER_NAME); dev->i2c_adap.owner = THIS_MODULE; - dev->i2c_adap.class = I2C_CLASS_TV_DIGITAL; dev->i2c_adap.dev.parent = &pdev->dev; dev->i2c_adap.algo = &dm1105_algo; dev->i2c_adap.algo_data = dev; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 970c9b8..1589d5a 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -702,7 +702,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) kthread_stop(fepriv->thread); - init_MUTEX (&fepriv->sem); + sema_init(&fepriv->sem, 1); fepriv->state = FESTATE_IDLE; /* paranoia check in case a signal arrived */ @@ -2062,7 +2062,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, } fepriv = fe->frontend_priv; - init_MUTEX (&fepriv->sem); + sema_init(&fepriv->sem, 1); init_waitqueue_head (&fepriv->wait_queue); init_waitqueue_head (&fepriv->events.wait_queue); mutex_init(&fepriv->events.mtx); diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index bf0e6be..f9f19be 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -260,7 +260,7 @@ struct dvb_frontend_ops { int (*init)(struct dvb_frontend* fe); int (*sleep)(struct dvb_frontend* fe); - int (*write)(struct dvb_frontend* fe, u8* buf, int len); + int (*write)(struct dvb_frontend* fe, const u8 buf[], int len); /* if this is set, it overrides the default swzigzag */ int (*tune)(struct dvb_frontend* fe, diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index fdc19bb..2525d3b 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 1a192453..5b1d12f 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -88,6 +88,9 @@ obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o dvb-usb-az6027-objs = az6027.o obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o +dvb-usb-lmedm04-objs = lmedm04.o +obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o + EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index ea1ed3b..31c0a0e 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 c8e9349..f20cfa6 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 4685259..1759d26 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 cead089b..88e4a62 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 1a774d5..192a40c 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 93c21dd..015b4e8 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 dbdb534..60d11e5 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 45106ac..c821293 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 0000000..d939fbb --- /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 0000000..e6af16c --- /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 diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 28294af..f0f1842 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c @@ -24,6 +24,8 @@ #include <linux/wait.h> #include <linux/workqueue.h> +#include <dvb_frontend.h> + #include "firedtv.h" #define FCP_COMMAND_REGISTER 0xfffff0000b00ULL @@ -130,6 +132,20 @@ MODULE_PARM_DESC(debug, "Verbose logging (none = 0" ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS) ", or a combination, or all = -1)"); +/* + * This is a workaround since there is no vendor specific command to retrieve + * ca_info using AVC. If this parameter is not used, ca_system_id will be + * filled with application_manufacturer from ca_app_info. + * Digital Everywhere have said that adding ca_info is on their TODO list. + */ +static unsigned int num_fake_ca_system_ids; +static int fake_ca_system_ids[4] = { -1, -1, -1, -1 }; +module_param_array(fake_ca_system_ids, int, &num_fake_ca_system_ids, 0644); +MODULE_PARM_DESC(fake_ca_system_ids, "If your CAM application manufacturer " + "does not have the same ca_system_id as your CAS, you can " + "override what ca_system_ids are presented to the " + "application by setting this field to an array of ids."); + static const char *debug_fcp_ctype(unsigned int ctype) { static const char *ctypes[] = { @@ -368,10 +384,30 @@ static int avc_tuner_tuneqpsk(struct firedtv *fdtv, c->operand[12] = 0; if (fdtv->type == FIREDTV_DVB_S2) { - c->operand[13] = 0x1; - c->operand[14] = 0xff; - c->operand[15] = 0xff; - + if (fdtv->fe.dtv_property_cache.delivery_system == SYS_DVBS2) { + switch (fdtv->fe.dtv_property_cache.modulation) { + case QAM_16: c->operand[13] = 0x1; break; + case QPSK: c->operand[13] = 0x2; break; + case PSK_8: c->operand[13] = 0x3; break; + default: c->operand[13] = 0x2; break; + } + switch (fdtv->fe.dtv_property_cache.rolloff) { + case ROLLOFF_AUTO: c->operand[14] = 0x2; break; + case ROLLOFF_35: c->operand[14] = 0x2; break; + case ROLLOFF_20: c->operand[14] = 0x0; break; + case ROLLOFF_25: c->operand[14] = 0x1; break; + /* case ROLLOFF_NONE: c->operand[14] = 0xff; break; */ + } + switch (fdtv->fe.dtv_property_cache.pilot) { + case PILOT_AUTO: c->operand[15] = 0x0; break; + case PILOT_OFF: c->operand[15] = 0x0; break; + case PILOT_ON: c->operand[15] = 0x1; break; + } + } else { + c->operand[13] = 0x1; /* auto modulation */ + c->operand[14] = 0xff; /* disable rolloff */ + c->operand[15] = 0xff; /* disable pilot */ + } return 16; } else { return 13; @@ -977,7 +1013,7 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) { struct avc_command_frame *c = (void *)fdtv->avc_data; struct avc_response_frame *r = (void *)fdtv->avc_data; - int pos, ret; + int i, pos, ret; mutex_lock(&fdtv->avc_mutex); @@ -1004,9 +1040,18 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff; app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff; - app_info[3] = 2; - app_info[4] = r->operand[pos + 0]; - app_info[5] = r->operand[pos + 1]; + if (num_fake_ca_system_ids == 0) { + app_info[3] = 2; + app_info[4] = r->operand[pos + 0]; + app_info[5] = r->operand[pos + 1]; + } else { + app_info[3] = num_fake_ca_system_ids * 2; + for (i = 0; i < num_fake_ca_system_ids; i++) { + app_info[4 + i * 2] = + (fake_ca_system_ids[i] >> 8) & 0xff; + app_info[5 + i * 2] = fake_ca_system_ids[i] & 0xff; + } + } *len = app_info[3] + 4; out: mutex_unlock(&fdtv->avc_mutex); diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c index e49cdc8..d10920e 100644 --- a/drivers/media/dvb/firewire/firedtv-fe.c +++ b/drivers/media/dvb/firewire/firedtv-fe.c @@ -155,6 +155,16 @@ static int fdtv_get_frontend(struct dvb_frontend *fe, return -EOPNOTSUPP; } +static int fdtv_get_property(struct dvb_frontend *fe, struct dtv_property *tvp) +{ + return 0; +} + +static int fdtv_set_property(struct dvb_frontend *fe, struct dtv_property *tvp) +{ + return 0; +} + void fdtv_frontend_init(struct firedtv *fdtv) { struct dvb_frontend_ops *ops = &fdtv->fe.ops; @@ -166,6 +176,9 @@ void fdtv_frontend_init(struct firedtv *fdtv) ops->set_frontend = fdtv_set_frontend; ops->get_frontend = fdtv_get_frontend; + ops->get_property = fdtv_get_property; + ops->set_property = fdtv_set_property; + ops->read_status = fdtv_read_status; ops->read_ber = fdtv_read_ber; ops->read_signal_strength = fdtv_read_signal_strength; @@ -179,7 +192,6 @@ void fdtv_frontend_init(struct firedtv *fdtv) switch (fdtv->type) { case FIREDTV_DVB_S: - case FIREDTV_DVB_S2: fi->type = FE_QPSK; fi->frequency_min = 950000; @@ -188,7 +200,7 @@ void fdtv_frontend_init(struct firedtv *fdtv) fi->symbol_rate_min = 1000000; fi->symbol_rate_max = 40000000; - fi->caps = FE_CAN_INVERSION_AUTO | + fi->caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | @@ -198,6 +210,26 @@ void fdtv_frontend_init(struct firedtv *fdtv) FE_CAN_QPSK; break; + case FIREDTV_DVB_S2: + fi->type = FE_QPSK; + + fi->frequency_min = 950000; + fi->frequency_max = 2150000; + fi->frequency_stepsize = 125; + fi->symbol_rate_min = 1000000; + fi->symbol_rate_max = 40000000; + + fi->caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_2G_MODULATION; + break; + case FIREDTV_DVB_C: fi->type = FE_QAM; diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index b5f6a04..e9062b0 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -257,6 +257,13 @@ config DVB_CX22702 help A DVB-T tuner module. Say Y when you want to support this frontend. +config DVB_S5H1432 + tristate "Samsung s5h1432 demodulator (OFDM)" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DVB-T tuner module. Say Y when you want to support this frontend. + config DVB_DRX397XD tristate "Micronas DRX3975D/DRX3977D based" depends on DVB_CORE && I2C @@ -455,16 +462,8 @@ config DVB_LGDT330X An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. -config DVB_LGDT3304 - tristate "LG Electronics LGDT3304" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - config DVB_LGDT3305 - tristate "LG Electronics LGDT3305 based" + tristate "LG Electronics LGDT3304 and LGDT3305 based" depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help @@ -607,6 +606,13 @@ config DVB_TDA665x Currently supported tuners: * Panasonic ENV57H12D5 (ET-50DT) +config DVB_IX2505V + tristate "Sharp IX2505V silicon tuner" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DVB-S tuner module. Say Y when you want to support this frontend. + comment "Tools to develop new frontends" config DVB_DUMMY_FE diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 874e8ad..9a31985 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_DVB_STB0899) += stb0899.o obj-$(CONFIG_DVB_STB6100) += stb6100.o obj-$(CONFIG_DVB_SP8870) += sp8870.o obj-$(CONFIG_DVB_CX22700) += cx22700.o +obj-$(CONFIG_DVB_S5H1432) += s5h1432.o obj-$(CONFIG_DVB_CX24110) += cx24110.o obj-$(CONFIG_DVB_TDA8083) += tda8083.o obj-$(CONFIG_DVB_L64781) += l64781.o @@ -45,7 +46,6 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o obj-$(CONFIG_DVB_BCM3510) += bcm3510.o obj-$(CONFIG_DVB_S5H1420) += s5h1420.o obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o -obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o obj-$(CONFIG_DVB_CX24123) += cx24123.o obj-$(CONFIG_DVB_LNBP21) += lnbp21.o @@ -82,3 +82,4 @@ obj-$(CONFIG_DVB_ISL6423) += isl6423.o obj-$(CONFIG_DVB_EC100) += ec100.o obj-$(CONFIG_DVB_DS3000) += ds3000.o obj-$(CONFIG_DVB_MB86A16) += mb86a16.o +obj-$(CONFIG_DVB_IX2505V) += ix2505v.o diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index dac917f..e2a95c0 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c @@ -42,6 +42,8 @@ struct af9013_state { struct af9013_config config; + /* tuner/demod RF and IF AGC limits used for signal strength calc */ + u8 signal_strength_en, rf_50, rf_80, if_50, if_80; u16 signal_strength; u32 ber; u32 ucblocks; @@ -220,184 +222,37 @@ static u32 af913_div(u32 a, u32 b, u32 x) static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) { - int ret = 0; - u8 i = 0; - u8 buf[24]; - u32 uninitialized_var(ns_coeff1_2048nu); - u32 uninitialized_var(ns_coeff1_8191nu); - u32 uninitialized_var(ns_coeff1_8192nu); - u32 uninitialized_var(ns_coeff1_8193nu); - u32 uninitialized_var(ns_coeff2_2k); - u32 uninitialized_var(ns_coeff2_8k); - + int ret, i, j, found; deb_info("%s: adc_clock:%d bw:%d\n", __func__, state->config.adc_clock, bw); - switch (state->config.adc_clock) { - case 28800: /* 28.800 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x01e79e7a; - ns_coeff1_8191nu = 0x0079eb6e; - ns_coeff1_8192nu = 0x0079e79e; - ns_coeff1_8193nu = 0x0079e3cf; - ns_coeff2_2k = 0x00f3cf3d; - ns_coeff2_8k = 0x003cf3cf; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x0238e38e; - ns_coeff1_8191nu = 0x008e3d55; - ns_coeff1_8192nu = 0x008e38e4; - ns_coeff1_8193nu = 0x008e3472; - ns_coeff2_2k = 0x011c71c7; - ns_coeff2_8k = 0x00471c72; + /* lookup coeff from table */ + for (i = 0, found = 0; i < ARRAY_SIZE(coeff_table); i++) { + if (coeff_table[i].adc_clock == state->config.adc_clock && + coeff_table[i].bw == bw) { + found = 1; break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x028a28a3; - ns_coeff1_8191nu = 0x00a28f3d; - ns_coeff1_8192nu = 0x00a28a29; - ns_coeff1_8193nu = 0x00a28514; - ns_coeff2_2k = 0x01451451; - ns_coeff2_8k = 0x00514514; - break; - default: - ret = -EINVAL; } - break; - case 20480: /* 20.480 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x02adb6dc; - ns_coeff1_8191nu = 0x00ab7313; - ns_coeff1_8192nu = 0x00ab6db7; - ns_coeff1_8193nu = 0x00ab685c; - ns_coeff2_2k = 0x0156db6e; - ns_coeff2_8k = 0x0055b6dc; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x03200001; - ns_coeff1_8191nu = 0x00c80640; - ns_coeff1_8192nu = 0x00c80000; - ns_coeff1_8193nu = 0x00c7f9c0; - ns_coeff2_2k = 0x01900000; - ns_coeff2_8k = 0x00640000; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x03924926; - ns_coeff1_8191nu = 0x00e4996e; - ns_coeff1_8192nu = 0x00e49249; - ns_coeff1_8193nu = 0x00e48b25; - ns_coeff2_2k = 0x01c92493; - ns_coeff2_8k = 0x00724925; - break; - default: - ret = -EINVAL; - } - break; - case 28000: /* 28.000 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x01f58d10; - ns_coeff1_8191nu = 0x007d672f; - ns_coeff1_8192nu = 0x007d6344; - ns_coeff1_8193nu = 0x007d5f59; - ns_coeff2_2k = 0x00fac688; - ns_coeff2_8k = 0x003eb1a2; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x02492492; - ns_coeff1_8191nu = 0x00924db7; - ns_coeff1_8192nu = 0x00924925; - ns_coeff1_8193nu = 0x00924492; - ns_coeff2_2k = 0x01249249; - ns_coeff2_8k = 0x00492492; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x029cbc15; - ns_coeff1_8191nu = 0x00a7343f; - ns_coeff1_8192nu = 0x00a72f05; - ns_coeff1_8193nu = 0x00a729cc; - ns_coeff2_2k = 0x014e5e0a; - ns_coeff2_8k = 0x00539783; - break; - default: - ret = -EINVAL; - } - break; - case 25000: /* 25.000 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x0231bcb5; - ns_coeff1_8191nu = 0x008c7391; - ns_coeff1_8192nu = 0x008c6f2d; - ns_coeff1_8193nu = 0x008c6aca; - ns_coeff2_2k = 0x0118de5b; - ns_coeff2_8k = 0x00463797; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x028f5c29; - ns_coeff1_8191nu = 0x00a3dc29; - ns_coeff1_8192nu = 0x00a3d70a; - ns_coeff1_8193nu = 0x00a3d1ec; - ns_coeff2_2k = 0x0147ae14; - ns_coeff2_8k = 0x0051eb85; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x02ecfb9d; - ns_coeff1_8191nu = 0x00bb44c1; - ns_coeff1_8192nu = 0x00bb3ee7; - ns_coeff1_8193nu = 0x00bb390d; - ns_coeff2_2k = 0x01767dce; - ns_coeff2_8k = 0x005d9f74; - break; - default: - ret = -EINVAL; - } - break; - default: - err("invalid xtal"); - return -EINVAL; } - if (ret) { - err("invalid bandwidth"); - return ret; + + if (!found) { + err("invalid bw or clock"); + ret = -EINVAL; + goto error; } - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x00ff0000) >> 16); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff2_2k & 0x01c00000) >> 22); - buf[i++] = (u8) ((ns_coeff2_2k & 0x003fc000) >> 14); - buf[i++] = (u8) ((ns_coeff2_2k & 0x00003fc0) >> 6); - buf[i++] = (u8) ((ns_coeff2_2k & 0x0000003f)); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff2_8k & 0x01c00000) >> 22); - buf[i++] = (u8) ((ns_coeff2_8k & 0x003fc000) >> 14); - buf[i++] = (u8) ((ns_coeff2_8k & 0x00003fc0) >> 6); - buf[i++] = (u8) ((ns_coeff2_8k & 0x0000003f)); - - deb_info("%s: coeff:", __func__); - debug_dump(buf, sizeof(buf), deb_info); + deb_info("%s: coeff: ", __func__); + debug_dump(coeff_table[i].val, sizeof(coeff_table[i].val), deb_info); /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xae00 + i, buf[i]); + for (j = 0; j < sizeof(coeff_table[i].val); j++) { + ret = af9013_write_reg(state, 0xae00 + j, + coeff_table[i].val[j]); if (ret) break; } +error: return ret; } @@ -486,6 +341,19 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) if_sample_freq = 4300000; /* 4.3 MHz */ break; } + } else if (state->config.tuner == AF9013_TUNER_TDA18218) { + switch (bw) { + case BANDWIDTH_6_MHZ: + if_sample_freq = 3000000; /* 3 MHz */ + break; + case BANDWIDTH_7_MHZ: + if_sample_freq = 3500000; /* 3.5 MHz */ + break; + case BANDWIDTH_8_MHZ: + default: + if_sample_freq = 4000000; /* 4 MHz */ + break; + } } while (if_sample_freq > (adc_freq / 2)) @@ -1097,45 +965,31 @@ static int af9013_update_signal_strength(struct dvb_frontend *fe) { struct af9013_state *state = fe->demodulator_priv; int ret; - u8 tmp0; - u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80; + u8 rf_gain, if_gain; int signal_strength; deb_info("%s\n", __func__); - state->signal_strength = 0; - - ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0); - if (ret) - goto error; - if (tmp0) { - ret = af9013_read_reg(state, 0x9bbd, &rf_50); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9bd0, &rf_80); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be2, &if_50); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be4, &if_80); - if (ret) - goto error; + if (state->signal_strength_en) { ret = af9013_read_reg(state, 0xd07c, &rf_gain); if (ret) goto error; ret = af9013_read_reg(state, 0xd07d, &if_gain); if (ret) goto error; - signal_strength = (0xffff / (9 * (rf_50 + if_50) - \ - 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \ - 11 * (rf_80 + if_80)); + signal_strength = (0xffff / \ + (9 * (state->rf_50 + state->if_50) - \ + 11 * (state->rf_80 + state->if_80))) * \ + (10 * (rf_gain + if_gain) - \ + 11 * (state->rf_80 + state->if_80)); if (signal_strength < 0) signal_strength = 0; else if (signal_strength > 0xffff) signal_strength = 0xffff; state->signal_strength = signal_strength; + } else { + state->signal_strength = 0; } error: @@ -1368,6 +1222,7 @@ static int af9013_init(struct dvb_frontend *fe) break; case AF9013_TUNER_MXL5005D: case AF9013_TUNER_MXL5005R: + case AF9013_TUNER_MXL5007T: len = ARRAY_SIZE(tuner_init_mxl5005); init = tuner_init_mxl5005; break; @@ -1393,6 +1248,7 @@ static int af9013_init(struct dvb_frontend *fe) init = tuner_init_mt2060_2; break; case AF9013_TUNER_TDA18271: + case AF9013_TUNER_TDA18218: len = ARRAY_SIZE(tuner_init_tda18271); init = tuner_init_tda18271; break; @@ -1438,6 +1294,27 @@ static int af9013_init(struct dvb_frontend *fe) if (ret) goto error; + /* read values needed for signal strength calculation */ + ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, + &state->signal_strength_en); + if (ret) + goto error; + + if (state->signal_strength_en) { + ret = af9013_read_reg(state, 0x9bbd, &state->rf_50); + if (ret) + goto error; + ret = af9013_read_reg(state, 0x9bd0, &state->rf_80); + if (ret) + goto error; + ret = af9013_read_reg(state, 0x9be2, &state->if_50); + if (ret) + goto error; + ret = af9013_read_reg(state, 0x9be4, &state->if_80); + if (ret) + goto error; + } + error: return ret; } diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h index 72c71bb..e53d873 100644 --- a/drivers/media/dvb/frontends/af9013.h +++ b/drivers/media/dvb/frontends/af9013.h @@ -44,6 +44,7 @@ enum af9013_tuner { AF9013_TUNER_MT2060_2 = 147, /* Microtune */ AF9013_TUNER_TDA18271 = 156, /* NXP */ AF9013_TUNER_QT1010A = 162, /* Quantek */ + AF9013_TUNER_MXL5007T = 177, /* MaxLinear */ AF9013_TUNER_TDA18218 = 179, /* NXP */ }; diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h index 0fd42b7..e00b2a4 100644 --- a/drivers/media/dvb/frontends/af9013_priv.h +++ b/drivers/media/dvb/frontends/af9013_priv.h @@ -60,6 +60,56 @@ struct snr_table { u8 snr; }; +struct coeff { + u32 adc_clock; + fe_bandwidth_t bw; + u8 val[24]; +}; + +/* pre-calculated coeff lookup table */ +static struct coeff coeff_table[] = { + /* 28.800 MHz */ + { 28800, BANDWIDTH_8_MHZ, { 0x02, 0x8a, 0x28, 0xa3, 0x05, 0x14, + 0x51, 0x11, 0x00, 0xa2, 0x8f, 0x3d, 0x00, 0xa2, 0x8a, + 0x29, 0x00, 0xa2, 0x85, 0x14, 0x01, 0x45, 0x14, 0x14 } }, + { 28800, BANDWIDTH_7_MHZ, { 0x02, 0x38, 0xe3, 0x8e, 0x04, 0x71, + 0xc7, 0x07, 0x00, 0x8e, 0x3d, 0x55, 0x00, 0x8e, 0x38, + 0xe4, 0x00, 0x8e, 0x34, 0x72, 0x01, 0x1c, 0x71, 0x32 } }, + { 28800, BANDWIDTH_6_MHZ, { 0x01, 0xe7, 0x9e, 0x7a, 0x03, 0xcf, + 0x3c, 0x3d, 0x00, 0x79, 0xeb, 0x6e, 0x00, 0x79, 0xe7, + 0x9e, 0x00, 0x79, 0xe3, 0xcf, 0x00, 0xf3, 0xcf, 0x0f } }, + /* 20.480 MHz */ + { 20480, BANDWIDTH_8_MHZ, { 0x03, 0x92, 0x49, 0x26, 0x07, 0x24, + 0x92, 0x13, 0x00, 0xe4, 0x99, 0x6e, 0x00, 0xe4, 0x92, + 0x49, 0x00, 0xe4, 0x8b, 0x25, 0x01, 0xc9, 0x24, 0x25 } }, + { 20480, BANDWIDTH_7_MHZ, { 0x03, 0x20, 0x00, 0x01, 0x06, 0x40, + 0x00, 0x00, 0x00, 0xc8, 0x06, 0x40, 0x00, 0xc8, 0x00, + 0x00, 0x00, 0xc7, 0xf9, 0xc0, 0x01, 0x90, 0x00, 0x00 } }, + { 20480, BANDWIDTH_6_MHZ, { 0x02, 0xad, 0xb6, 0xdc, 0x05, 0x5b, + 0x6d, 0x2e, 0x00, 0xab, 0x73, 0x13, 0x00, 0xab, 0x6d, + 0xb7, 0x00, 0xab, 0x68, 0x5c, 0x01, 0x56, 0xdb, 0x1c } }, + /* 28.000 MHz */ + { 28000, BANDWIDTH_8_MHZ, { 0x02, 0x9c, 0xbc, 0x15, 0x05, 0x39, + 0x78, 0x0a, 0x00, 0xa7, 0x34, 0x3f, 0x00, 0xa7, 0x2f, + 0x05, 0x00, 0xa7, 0x29, 0xcc, 0x01, 0x4e, 0x5e, 0x03 } }, + { 28000, BANDWIDTH_7_MHZ, { 0x02, 0x49, 0x24, 0x92, 0x04, 0x92, + 0x49, 0x09, 0x00, 0x92, 0x4d, 0xb7, 0x00, 0x92, 0x49, + 0x25, 0x00, 0x92, 0x44, 0x92, 0x01, 0x24, 0x92, 0x12 } }, + { 28000, BANDWIDTH_6_MHZ, { 0x01, 0xf5, 0x8d, 0x10, 0x03, 0xeb, + 0x1a, 0x08, 0x00, 0x7d, 0x67, 0x2f, 0x00, 0x7d, 0x63, + 0x44, 0x00, 0x7d, 0x5f, 0x59, 0x00, 0xfa, 0xc6, 0x22 } }, + /* 25.000 MHz */ + { 25000, BANDWIDTH_8_MHZ, { 0x02, 0xec, 0xfb, 0x9d, 0x05, 0xd9, + 0xf7, 0x0e, 0x00, 0xbb, 0x44, 0xc1, 0x00, 0xbb, 0x3e, + 0xe7, 0x00, 0xbb, 0x39, 0x0d, 0x01, 0x76, 0x7d, 0x34 } }, + { 25000, BANDWIDTH_7_MHZ, { 0x02, 0x8f, 0x5c, 0x29, 0x05, 0x1e, + 0xb8, 0x14, 0x00, 0xa3, 0xdc, 0x29, 0x00, 0xa3, 0xd7, + 0x0a, 0x00, 0xa3, 0xd1, 0xec, 0x01, 0x47, 0xae, 0x05 } }, + { 25000, BANDWIDTH_6_MHZ, { 0x02, 0x31, 0xbc, 0xb5, 0x04, 0x63, + 0x79, 0x1b, 0x00, 0x8c, 0x73, 0x91, 0x00, 0x8c, 0x6f, + 0x2d, 0x00, 0x8c, 0x6a, 0xca, 0x01, 0x18, 0xde, 0x17 } }, +}; + /* QPSK SNR lookup table */ static struct snr_table qpsk_snr_table[] = { { 0x0b4771, 0 }, @@ -480,9 +530,10 @@ static struct regdesc tuner_init_mxl5003d[] = { { 0x9bd9, 0, 8, 0x08 }, }; -/* MaxLinear MXL5005 tuner init +/* MaxLinear MXL5005S & MXL5007T tuner init AF9013_TUNER_MXL5005D = 13 - AF9013_TUNER_MXL5005R = 30 */ + AF9013_TUNER_MXL5005R = 30 + AF9013_TUNER_MXL5007T = 177 */ static struct regdesc tuner_init_mxl5005[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x07 }, @@ -791,8 +842,9 @@ static struct regdesc tuner_init_unknown[] = { { 0x9bd9, 0, 8, 0x08 }, }; -/* NXP TDA18271 tuner init - AF9013_TUNER_TDA18271 = 156 */ +/* NXP TDA18271 & TDA18218 tuner init + AF9013_TUNER_TDA18271 = 156 + AF9013_TUNER_TDA18218 = 179 */ static struct regdesc tuner_init_tda18271[] = { { 0x9bd5, 0, 8, 0x01 }, { 0x9bd6, 0, 8, 0x04 }, diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index 29cdbfe..6d9c594 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -36,7 +36,6 @@ #include <linux/delay.h> #include <media/v4l2-common.h> #include <media/v4l2-chip-ident.h> -#include <media/v4l2-i2c-drv.h> #include <media/v4l2-device.h> #include "au8522.h" #include "au8522_priv.h" @@ -831,9 +830,25 @@ static const struct i2c_device_id au8522_id[] = { MODULE_DEVICE_TABLE(i2c, au8522_id); -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "au8522", - .probe = au8522_probe, - .remove = au8522_remove, - .id_table = au8522_id, +static struct i2c_driver au8522_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "au8522", + }, + .probe = au8522_probe, + .remove = au8522_remove, + .id_table = au8522_id, }; + +static __init int init_au8522(void) +{ + return i2c_add_driver(&au8522_driver); +} + +static __exit void exit_au8522(void) +{ + i2c_del_driver(&au8522_driver); +} + +module_init(init_au8522); +module_exit(exit_au8522); diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 00b5c7e..ff6c498 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c @@ -54,7 +54,7 @@ MODULE_PARM_DESC(debug, "Enable verbose debug messages"); #define dprintk if (debug) printk /* Register values to initialise the demod */ -static u8 init_tab[] = { +static const u8 init_tab[] = { 0x00, 0x00, /* Stop aquisition */ 0x0B, 0x06, 0x09, 0x01, @@ -92,52 +92,56 @@ static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data) ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) + if (unlikely(ret != 1)) { printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", __func__, reg, data, ret); + return -1; + } - return (ret != 1) ? -1 : 0; + return 0; } static u8 cx22702_readreg(struct cx22702_state *state, u8 reg) { int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; + u8 data; struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 1 }, + .buf = ®, .len = 1 }, { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; + .buf = &data, .len = 1 } }; ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) - printk(KERN_ERR "%s: readreg error (ret == %i)\n", - __func__, ret); + if (unlikely(ret != 2)) { + printk(KERN_ERR "%s: error (reg == 0x%02x, ret == %i)\n", + __func__, reg, ret); + return 0; + } - return b1[0]; + return data; } static int cx22702_set_inversion(struct cx22702_state *state, int inversion) { u8 val; + val = cx22702_readreg(state, 0x0C); switch (inversion) { case INVERSION_AUTO: return -EOPNOTSUPP; case INVERSION_ON: - val = cx22702_readreg(state, 0x0C); - return cx22702_writereg(state, 0x0C, val | 0x01); + val |= 0x01; + break; case INVERSION_OFF: - val = cx22702_readreg(state, 0x0C); - return cx22702_writereg(state, 0x0C, val & 0xfe); + val &= 0xfe; + break; default: return -EINVAL; } - + return cx22702_writereg(state, 0x0C, val); } /* Retrieve the demod settings */ @@ -244,13 +248,15 @@ static int cx22702_get_tps(struct cx22702_state *state, static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { struct cx22702_state *state = fe->demodulator_priv; + u8 val; + dprintk("%s(%d)\n", __func__, enable); + val = cx22702_readreg(state, 0x0D); if (enable) - return cx22702_writereg(state, 0x0D, - cx22702_readreg(state, 0x0D) & 0xfe); + val &= 0xfe; else - return cx22702_writereg(state, 0x0D, - cx22702_readreg(state, 0x0D) | 1); + val |= 0x01; + return cx22702_writereg(state, 0x0D, val); } /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ @@ -270,23 +276,21 @@ static int cx22702_set_tps(struct dvb_frontend *fe, cx22702_set_inversion(state, p->inversion); /* set bandwidth */ + val = cx22702_readreg(state, 0x0C) & 0xcf; switch (p->u.ofdm.bandwidth) { case BANDWIDTH_6_MHZ: - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20); + val |= 0x20; break; case BANDWIDTH_7_MHZ: - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10); + val |= 0x10; break; case BANDWIDTH_8_MHZ: - cx22702_writereg(state, 0x0C, - cx22702_readreg(state, 0x0C) & 0xcf); break; default: dprintk("%s: invalid bandwidth\n", __func__); return -EINVAL; } + cx22702_writereg(state, 0x0C, val); p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ @@ -312,33 +316,31 @@ static int cx22702_set_tps(struct dvb_frontend *fe, } /* manually programmed values */ - val = 0; - switch (p->u.ofdm.constellation) { + switch (p->u.ofdm.constellation) { /* mask 0x18 */ case QPSK: - val = (val & 0xe7); + val = 0x00; break; case QAM_16: - val = (val & 0xe7) | 0x08; + val = 0x08; break; case QAM_64: - val = (val & 0xe7) | 0x10; + val = 0x10; break; default: dprintk("%s: invalid constellation\n", __func__); return -EINVAL; } - switch (p->u.ofdm.hierarchy_information) { + switch (p->u.ofdm.hierarchy_information) { /* mask 0x07 */ case HIERARCHY_NONE: - val = (val & 0xf8); break; case HIERARCHY_1: - val = (val & 0xf8) | 1; + val |= 0x01; break; case HIERARCHY_2: - val = (val & 0xf8) | 2; + val |= 0x02; break; case HIERARCHY_4: - val = (val & 0xf8) | 3; + val |= 0x03; break; default: dprintk("%s: invalid hierarchy\n", __func__); @@ -346,44 +348,42 @@ static int cx22702_set_tps(struct dvb_frontend *fe, } cx22702_writereg(state, 0x06, val); - val = 0; - switch (p->u.ofdm.code_rate_HP) { + switch (p->u.ofdm.code_rate_HP) { /* mask 0x38 */ case FEC_NONE: case FEC_1_2: - val = (val & 0xc7); + val = 0x00; break; case FEC_2_3: - val = (val & 0xc7) | 0x08; + val = 0x08; break; case FEC_3_4: - val = (val & 0xc7) | 0x10; + val = 0x10; break; case FEC_5_6: - val = (val & 0xc7) | 0x18; + val = 0x18; break; case FEC_7_8: - val = (val & 0xc7) | 0x20; + val = 0x20; break; default: dprintk("%s: invalid code_rate_HP\n", __func__); return -EINVAL; } - switch (p->u.ofdm.code_rate_LP) { + switch (p->u.ofdm.code_rate_LP) { /* mask 0x07 */ case FEC_NONE: case FEC_1_2: - val = (val & 0xf8); break; case FEC_2_3: - val = (val & 0xf8) | 1; + val |= 0x01; break; case FEC_3_4: - val = (val & 0xf8) | 2; + val |= 0x02; break; case FEC_5_6: - val = (val & 0xf8) | 3; + val |= 0x03; break; case FEC_7_8: - val = (val & 0xf8) | 4; + val |= 0x04; break; default: dprintk("%s: invalid code_rate_LP\n", __func__); @@ -391,30 +391,28 @@ static int cx22702_set_tps(struct dvb_frontend *fe, } cx22702_writereg(state, 0x07, val); - val = 0; - switch (p->u.ofdm.guard_interval) { + switch (p->u.ofdm.guard_interval) { /* mask 0x0c */ case GUARD_INTERVAL_1_32: - val = (val & 0xf3); + val = 0x00; break; case GUARD_INTERVAL_1_16: - val = (val & 0xf3) | 0x04; + val = 0x04; break; case GUARD_INTERVAL_1_8: - val = (val & 0xf3) | 0x08; + val = 0x08; break; case GUARD_INTERVAL_1_4: - val = (val & 0xf3) | 0x0c; + val = 0x0c; break; default: dprintk("%s: invalid guard_interval\n", __func__); return -EINVAL; } - switch (p->u.ofdm.transmission_mode) { + switch (p->u.ofdm.transmission_mode) { /* mask 0x03 */ case TRANSMISSION_MODE_2K: - val = (val & 0xfc); break; case TRANSMISSION_MODE_8K: - val = (val & 0xfc) | 1; + val |= 0x1; break; default: dprintk("%s: invalid transmission_mode\n", __func__); @@ -505,7 +503,7 @@ static int cx22702_read_signal_strength(struct dvb_frontend *fe, { struct cx22702_state *state = fe->demodulator_priv; - u16 rs_ber = 0; + u16 rs_ber; rs_ber = cx22702_readreg(state, 0x23); *signal_strength = (rs_ber << 8) | rs_ber; @@ -516,7 +514,7 @@ static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr) { struct cx22702_state *state = fe->demodulator_priv; - u16 rs_ber = 0; + u16 rs_ber; if (cx22702_readreg(state, 0xE4) & 0x02) { /* Realtime statistics */ rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 @@ -572,7 +570,7 @@ static void cx22702_release(struct dvb_frontend *fe) kfree(state); } -static struct dvb_frontend_ops cx22702_ops; +static const struct dvb_frontend_ops cx22702_ops; struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, struct i2c_adapter *i2c) @@ -587,7 +585,6 @@ struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, /* setup the state */ state->config = config; state->i2c = i2c; - state->prevUCBlocks = 0; /* check if the demod is there */ if (cx22702_readreg(state, 0x1f) != 0x3) @@ -605,7 +602,7 @@ error: } EXPORT_SYMBOL(cx22702_attach); -static struct dvb_frontend_ops cx22702_ops = { +static const struct dvb_frontend_ops cx22702_ops = { .info = { .name = "Conexant CX22702 DVB-T", diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 00a4e8f..7a1a5bc 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c @@ -310,7 +310,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) } -static int _cx24110_pll_write (struct dvb_frontend* fe, u8 *buf, int len) +static int _cx24110_pll_write (struct dvb_frontend* fe, const u8 buf[], int len) { struct cx24110_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index d8f921b..fad6a99 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c @@ -1108,7 +1108,6 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus", sizeof(state->tuner_i2c_adapter.name)); - state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo; state->tuner_i2c_adapter.algo_data = NULL; i2c_set_adapdata(&state->tuner_i2c_adapter, state); diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index 980e02f..a499102 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c @@ -130,7 +130,6 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct dibx000_i2c_master *mst) { strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); - i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->algo = algo; i2c_adap->algo_data = NULL; i2c_set_adapdata(i2c_adap, mst); if (i2c_add_adapter(i2c_adap) < 0) diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index f74cca6..a05007c 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c @@ -232,7 +232,7 @@ static int write_fw(struct drx397xD_state *s, enum blob_ix ix) exit_rc: read_unlock(&fw[s->chip_rev].lock); - return 0; + return rc; } /* Function is not endian safe, use the RD16 wrapper below */ diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c new file mode 100644 index 0000000..55f2eba --- /dev/null +++ b/drivers/media/dvb/frontends/ix2505v.c @@ -0,0 +1,323 @@ +/** + * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner + * + * Copyright (C) 2010 Malcolm Priestley + * + * 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. + * + */ + +#include <linux/module.h> +#include <linux/dvb/frontend.h> +#include <linux/slab.h> +#include <linux/types.h> + +#include "ix2505v.h" + +static int ix2505v_debug; +#define dprintk(level, args...) do { \ + if (ix2505v_debug & level) \ + printk(KERN_DEBUG "ix2505v: " args); \ +} while (0) + +#define deb_info(args...) dprintk(0x01, args) +#define deb_i2c(args...) dprintk(0x02, args) + +struct ix2505v_state { + struct i2c_adapter *i2c; + const struct ix2505v_config *config; + u32 frequency; +}; + +/** + * Data read format of the Sharp IX2505V B0017 + * + * byte1: 1 | 1 | 0 | 0 | 0 | MA1 | MA0 | 1 + * byte2: POR | FL | RD2 | RD1 | RD0 | X | X | X + * + * byte1 = address + * byte2; + * POR = Power on Reset (VCC H=<2.2v L=>2.2v) + * FL = Phase Lock (H=lock L=unlock) + * RD0-2 = Reserved internal operations + * + * Only POR can be used to check the tuner is present + * + * Caution: after byte2 the I2C reverts to write mode continuing to read + * may corrupt tuning data. + * + */ + +static int ix2505v_read_status_reg(struct ix2505v_state *state) +{ + u8 addr = state->config->tuner_address; + u8 b2[] = {0}; + int ret; + + struct i2c_msg msg[1] = { + { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 } + }; + + ret = i2c_transfer(state->i2c, msg, 1); + deb_i2c("Read %s ", __func__); + + return (ret = 1) ? (int) b2[0] : -1; +} + +static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count) +{ + struct i2c_msg msg[1] = { + { .addr = state->config->tuner_address, .flags = 0, + .buf = buf, .len = count }, + }; + + int ret; + + ret = i2c_transfer(state->i2c, msg, 1); + + if (ret != 1) { + deb_i2c("%s: i2c error, ret=%d\n", __func__, ret); + return -EIO; + } + + return 0; +} + +static int ix2505v_release(struct dvb_frontend *fe) +{ + struct ix2505v_state *state = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(state); + + return 0; +} + +/** + * Data write format of the Sharp IX2505V B0017 + * + * byte1: 1 | 1 | 0 | 0 | 0 | 0(MA1)| 0(MA0)| 0 + * byte2: 0 | BG1 | BG2 | N8 | N7 | N6 | N5 | N4 + * byte3: N3 | N2 | N1 | A5 | A4 | A3 | A2 | A1 + * byte4: 1 | 1(C1) | 1(C0) | PD5 | PD4 | TM | 0(RTS)| 1(REF) + * byte5: BA2 | BA1 | BA0 | PSC | PD3 |PD2/TS2|DIV/TS1|PD0/TS0 + * + * byte1 = address + * + * Write order + * 1) byte1 -> byte2 -> byte3 -> byte4 -> byte5 + * 2) byte1 -> byte4 -> byte5 -> byte2 -> byte3 + * 3) byte1 -> byte2 -> byte3 -> byte4 + * 4) byte1 -> byte4 -> byte5 -> byte2 + * 5) byte1 -> byte2 -> byte3 + * 6) byte1 -> byte4 -> byte5 + * 7) byte1 -> byte2 + * 8) byte1 -> byte4 + * + * Recommended Setup + * 1 -> 8 -> 6 + */ + +static int ix2505v_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct ix2505v_state *state = fe->tuner_priv; + u32 frequency = params->frequency; + u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000; + u32 div_factor, N , A, x; + int ret = 0, len; + u8 gain, cc, ref, psc, local_osc, lpf; + u8 data[4] = {0}; + + if ((frequency < fe->ops.info.frequency_min) + || (frequency > fe->ops.info.frequency_max)) + return -EINVAL; + + if (state->config->tuner_gain) + gain = (state->config->tuner_gain < 4) + ? state->config->tuner_gain : 0; + else + gain = 0x0; + + if (state->config->tuner_chargepump) + cc = state->config->tuner_chargepump; + else + cc = 0x3; + + ref = 8; /* REF =1 */ + psc = 32; /* PSC = 0 */ + + div_factor = (frequency * ref) / 40; /* local osc = 4Mhz */ + x = div_factor / psc; + N = x/100; + A = ((x - (N * 100)) * psc) / 100; + + data[0] = ((gain & 0x3) << 5) | (N >> 3); + data[1] = (N << 5) | (A & 0x1f); + data[2] = 0x81 | ((cc & 0x3) << 5) ; /*PD5,PD4 & TM = 0|C1,C0|REF=1*/ + + deb_info("Frq=%d x=%d N=%d A=%d\n", frequency, x, N, A); + + if (frequency <= 1065000) + local_osc = (6 << 5) | 2; + else if (frequency <= 1170000) + local_osc = (7 << 5) | 2; + else if (frequency <= 1300000) + local_osc = (1 << 5); + else if (frequency <= 1445000) + local_osc = (2 << 5); + else if (frequency <= 1607000) + local_osc = (3 << 5); + else if (frequency <= 1778000) + local_osc = (4 << 5); + else if (frequency <= 1942000) + local_osc = (5 << 5); + else /*frequency up to 2150000*/ + local_osc = (6 << 5); + + data[3] = local_osc; /* all other bits set 0 */ + + if (b_w <= 10000) + lpf = 0xc; + else if (b_w <= 12000) + lpf = 0x2; + else if (b_w <= 14000) + lpf = 0xa; + else if (b_w <= 16000) + lpf = 0x6; + else if (b_w <= 18000) + lpf = 0xe; + else if (b_w <= 20000) + lpf = 0x1; + else if (b_w <= 22000) + lpf = 0x9; + else if (b_w <= 24000) + lpf = 0x5; + else if (b_w <= 26000) + lpf = 0xd; + else if (b_w <= 28000) + lpf = 0x3; + else + lpf = 0xb; + + deb_info("Osc=%x b_w=%x lpf=%x\n", local_osc, b_w, lpf); + deb_info("Data 0=[%x%x%x%x]\n", data[0], data[1], data[2], data[3]); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + len = sizeof(data); + + ret |= ix2505v_write(state, data, len); + + data[2] |= 0x4; /* set TM = 1 other bits same */ + + len = 1; + ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */ + + msleep(10); + + data[2] |= ((lpf >> 2) & 0x3) << 3; /* lpf */ + data[3] |= (lpf & 0x3) << 2; + + deb_info("Data 2=[%x%x]\n", data[2], data[3]); + + len = 2; + ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */ + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (state->config->min_delay_ms) + msleep(state->config->min_delay_ms); + + state->frequency = frequency; + + return ret; +} + +static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct ix2505v_state *state = fe->tuner_priv; + + *frequency = state->frequency; + + return 0; +} + +static struct dvb_tuner_ops ix2505v_tuner_ops = { + .info = { + .name = "Sharp IX2505V (B0017)", + .frequency_min = 950000, + .frequency_max = 2175000 + }, + .release = ix2505v_release, + .set_params = ix2505v_set_params, + .get_frequency = ix2505v_get_frequency, +}; + +struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, + const struct ix2505v_config *config, + struct i2c_adapter *i2c) +{ + struct ix2505v_state *state = NULL; + int ret; + + if (NULL == config) { + deb_i2c("%s: no config ", __func__); + goto error; + } + + state = kzalloc(sizeof(struct ix2505v_state), GFP_KERNEL); + if (NULL == state) + return NULL; + + state->config = config; + state->i2c = i2c; + + if (state->config->tuner_write_only) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = ix2505v_read_status_reg(state); + + if (ret & 0x80) { + deb_i2c("%s: No IX2505V found\n", __func__); + goto error; + } + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + fe->tuner_priv = state; + + memcpy(&fe->ops.tuner_ops, &ix2505v_tuner_ops, + sizeof(struct dvb_tuner_ops)); + deb_i2c("%s: initialization (%s addr=0x%02x) ok\n", + __func__, fe->ops.tuner_ops.info.name, config->tuner_address); + + return fe; + +error: + ix2505v_release(fe); + return NULL; +} +EXPORT_SYMBOL(ix2505v_attach); + +module_param_named(debug, ix2505v_debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); +MODULE_DESCRIPTION("DVB IX2505V tuner driver"); +MODULE_AUTHOR("Malcolm Priestley"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/ix2505v.h b/drivers/media/dvb/frontends/ix2505v.h new file mode 100644 index 0000000..67e89d6 --- /dev/null +++ b/drivers/media/dvb/frontends/ix2505v.h @@ -0,0 +1,64 @@ +/** + * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner + * + * Copyright (C) 2010 Malcolm Priestley + * + * 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. + */ + +#ifndef DVB_IX2505V_H +#define DVB_IX2505V_H + +#include <linux/i2c.h> +#include "dvb_frontend.h" + +/** + * Attach a ix2505v tuner to the supplied frontend structure. + * + * @param fe Frontend to attach to. + * @param config ix2505v_config structure + * @return FE pointer on success, NULL on failure. + */ + +struct ix2505v_config { + u8 tuner_address; + + /*Baseband AMP gain control 0/1=0dB(default) 2=-2bB 3=-4dB */ + u8 tuner_gain; + + /*Charge pump output +/- 0=120 1=260 2=555 3=1200(default) */ + u8 tuner_chargepump; + + /* delay after tune */ + int min_delay_ms; + + /* disables reads*/ + u8 tuner_write_only; + +}; + +#if defined(CONFIG_DVB_IX2505V) || \ + (defined(CONFIG_DVB_IX2505V_MODULE) && defined(MODULE)) +extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, + const struct ix2505v_config *config, struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, + const struct ix2505v_config *config, struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif /* DVB_IX2505V_H */ diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c deleted file mode 100644 index 45a529b..0000000 --- a/drivers/media/dvb/frontends/lgdt3304.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Driver for LG ATSC lgdt3304 driver - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "lgdt3304.h" - -static unsigned int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)"); - -#define dprintk(fmt, args...) if (debug) do {\ - printk("lgdt3304 debug: " fmt, ##args); } while (0) - -struct lgdt3304_state -{ - struct dvb_frontend frontend; - fe_modulation_t current_modulation; - __u32 snr; - __u32 current_frequency; - __u8 addr; - struct i2c_adapter *i2c; -}; - -static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 3, - .buf = buf - }; - int i; - int err; - - for (i=0; i<len-1; i+=3){ - if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { - printk("%s i2c_transfer error %d\n", __func__, err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - i2cmsgs.buf += 3; - } - return 0; -} - -static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - struct i2c_msg i2cmsgs[2]; - int ret; - __u8 buf; - - __u8 regbuf[2] = { reg>>8, reg&0xff }; - - i2cmsgs[0].addr = state->addr; - i2cmsgs[0].flags = 0; - i2cmsgs[0].len = 2; - i2cmsgs[0].buf = regbuf; - - i2cmsgs[1].addr = state->addr; - i2cmsgs[1].flags = I2C_M_RD; - i2cmsgs[1].len = 1; - i2cmsgs[1].buf = &buf; - - if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) { - printk("%s i2c_transfer error %d\n", __func__, ret); - return ret; - } - - return buf; -} - -static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - char buffer[3] = { reg>>8, reg&0xff, val }; - int ret; - - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 3, - .buf=buffer - }; - ret = i2c_transfer(state->i2c, &i2cmsgs, 1); - if (ret != 1) { - printk("%s i2c_transfer error %d\n", __func__, ret); - return ret; - } - - return 0; -} - - -static int lgdt3304_soft_Reset(struct dvb_frontend *fe) -{ - lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a); - lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b); - mdelay(200); - return 0; -} - -static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { - int err = 0; - - static __u8 lgdt3304_vsb8_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x02, - 0x00, 0x00, 0x13, - 0x00, 0x0d, 0x02, - 0x00, 0x0e, 0x02, - 0x00, 0x12, 0x32, - 0x00, 0x13, 0xc4, - 0x01, 0x12, 0x17, - 0x01, 0x13, 0x15, - 0x01, 0x14, 0x18, - 0x01, 0x15, 0xff, - 0x01, 0x16, 0x2c, - 0x02, 0x14, 0x67, - 0x02, 0x24, 0x8d, - 0x04, 0x27, 0x12, - 0x04, 0x28, 0x4f, - 0x03, 0x08, 0x80, - 0x03, 0x09, 0x00, - 0x03, 0x0d, 0x00, - 0x03, 0x0e, 0x1c, - 0x03, 0x14, 0xe1, - 0x05, 0x0e, 0x5b, - }; - - /* not yet tested .. */ - static __u8 lgdt3304_qam64_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x18, - 0x00, 0x0d, 0x02, - //0x00, 0x0e, 0x02, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x00, - 0x03, 0x14, 0xe3, - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - 0x05, 0x0e, 0x5b, - }; - - - /* tested with KWorld a340 */ - static __u8 lgdt3304_qam256_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x01, //0x19, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x80, - 0x00, 0x0d, 0x02, - 0x03, 0x14, 0xe3, - - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - - 0x03, 0x0d, 0x14, - //0x05, 0x0e, 0x5b, - 0x01, 0x06, 0x4a, - 0x01, 0x07, 0x3d, - 0x01, 0x08, 0x70, - 0x01, 0x09, 0xa3, - - 0x05, 0x04, 0xfd, - - 0x00, 0x0d, 0x82, - - 0x05, 0x0e, 0x5b, - - 0x05, 0x0e, 0x5b, - - 0x00, 0x02, 0x9a, - - 0x00, 0x02, 0x9b, - - 0x00, 0x00, 0x01, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x80, - 0x00, 0x0d, 0x02, - 0x03, 0x14, 0xe3, - - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - - 0x03, 0x0d, 0x14, - 0x01, 0x06, 0x4a, - 0x01, 0x07, 0x3d, - 0x01, 0x08, 0x70, - 0x01, 0x09, 0xa3, - - 0x05, 0x04, 0xfd, - - 0x00, 0x0d, 0x82, - - 0x05, 0x0e, 0x5b, - }; - - struct lgdt3304_state *state = fe->demodulator_priv; - if (state->current_modulation != param->u.vsb.modulation) { - switch(param->u.vsb.modulation) { - case VSB_8: - err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data, - sizeof(lgdt3304_vsb8_data)); - break; - case QAM_64: - err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data, - sizeof(lgdt3304_qam64_data)); - break; - case QAM_256: - err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data, - sizeof(lgdt3304_qam256_data)); - break; - default: - break; - } - - if (err) { - printk("%s error setting modulation\n", __func__); - } else { - state->current_modulation = param->u.vsb.modulation; - } - } - state->current_frequency = param->frequency; - - lgdt3304_soft_Reset(fe); - - - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, param); - - return 0; -} - -static int lgdt3304_init(struct dvb_frontend *fe) { - return 0; -} - -static int lgdt3304_sleep(struct dvb_frontend *fe) { - return 0; -} - - -static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - int r011d; - int qam_lck; - - *status = 0; - dprintk("lgdt read status\n"); - - r011d = lgdt3304_i2c_read_reg(fe, 0x011d); - - dprintk("%02x\n", r011d); - - switch(state->current_modulation) { - case VSB_8: - if (r011d & 0x80) { - dprintk("VSB Locked\n"); - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - } - break; - case QAM_64: - case QAM_256: - qam_lck = r011d & 0x7; - switch(qam_lck) { - case 0x0: dprintk("Unlock\n"); - break; - case 0x4: dprintk("1st Lock in acquisition state\n"); - break; - case 0x6: dprintk("2nd Lock in acquisition state\n"); - break; - case 0x7: dprintk("Final Lock in good reception state\n"); - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - break; - } - break; - default: - printk("%s unhandled modulation\n", __func__); - } - - - return 0; -} - -static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber) -{ - dprintk("read ber\n"); - return 0; -} - -static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr) -{ - dprintk("read snr\n"); - return 0; -} - -static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) -{ - dprintk("read ucblocks\n"); - return 0; -} - -static void lgdt3304_release(struct dvb_frontend *fe) -{ - struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops demod_lgdt3304={ - .info = { - .name = "LG 3304", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .symbol_rate_min = 5056941, - .symbol_rate_max = 10762000, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .init = lgdt3304_init, - .sleep = lgdt3304_sleep, - .set_frontend = lgdt3304_set_parameters, - .read_snr = lgdt3304_read_snr, - .read_ber = lgdt3304_read_ber, - .read_status = lgdt3304_read_status, - .read_ucblocks = lgdt3304_read_ucblocks, - .release = lgdt3304_release, -}; - -struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c) -{ - - struct lgdt3304_state *state; - state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); - if (state == NULL) - return NULL; - state->addr = config->i2c_address; - state->i2c = i2c; - - memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -EXPORT_SYMBOL_GPL(lgdt3304_attach); -MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>"); -MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/lgdt3304.h b/drivers/media/dvb/frontends/lgdt3304.h deleted file mode 100644 index fc409fe..0000000 --- a/drivers/media/dvb/frontends/lgdt3304.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Driver for DVB-T lgdt3304 demodulator - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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.= - */ - -#ifndef LGDT3304_H -#define LGDT3304_H - -#include <linux/dvb/frontend.h> - -struct lgdt3304_config -{ - /* demodulator's I2C address */ - u8 i2c_address; -}; - -#if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE)) -extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_LGDT */ - -#endif /* LGDT3304_H */ diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c index 5ea28ae..0fcddc4 100644 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ b/drivers/media/dvb/frontends/lgs8gxx.c @@ -662,7 +662,7 @@ static void lgs8gxx_release(struct dvb_frontend *fe) } -static int lgs8gxx_write(struct dvb_frontend *fe, u8 *buf, int len) +static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len) { struct lgs8gxx_state *priv = fe->demodulator_priv; diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c index beba5aa..319672f 100644 --- a/drivers/media/dvb/frontends/mt352.c +++ b/drivers/media/dvb/frontends/mt352.c @@ -69,7 +69,7 @@ static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val) return 0; } -static int _mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen) +static int _mt352_write(struct dvb_frontend* fe, const u8 ibuf[], int ilen) { int err,i; for (i=0; i < ilen-1; i++) diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h index 595092f..ca2562d 100644 --- a/drivers/media/dvb/frontends/mt352.h +++ b/drivers/media/dvb/frontends/mt352.h @@ -63,7 +63,7 @@ static inline struct dvb_frontend* mt352_attach(const struct mt352_config* confi } #endif // CONFIG_DVB_MT352 -static inline int mt352_write(struct dvb_frontend *fe, u8 *buf, int len) { +static inline int mt352_write(struct dvb_frontend *fe, const u8 buf[], int len) { int r = 0; if (fe->ops.write) r = fe->ops.write(fe, buf, len); diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index 2e9fd28..e87b747 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c @@ -920,7 +920,6 @@ struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, /* create tuner i2c adapter */ strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", sizeof(state->tuner_i2c_adapter.name)); - state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo; state->tuner_i2c_adapter.algo_data = NULL; i2c_set_adapdata(&state->tuner_i2c_adapter, state); diff --git a/drivers/media/dvb/frontends/s5h1432.c b/drivers/media/dvb/frontends/s5h1432.c new file mode 100644 index 0000000..0c6dcb9 --- /dev/null +++ b/drivers/media/dvb/frontends/s5h1432.c @@ -0,0 +1,415 @@ +/* + * Samsung s5h1432 DVB-T demodulator driver + * + * Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include "dvb_frontend.h" +#include "s5h1432.h" + +struct s5h1432_state { + + struct i2c_adapter *i2c; + + /* configuration settings */ + const struct s5h1432_config *config; + + struct dvb_frontend frontend; + + fe_modulation_t current_modulation; + unsigned int first_tune:1; + + u32 current_frequency; + int if_freq; + + u8 inversion; +}; + +static int debug; + +#define dprintk(arg...) do { \ + if (debug) \ + printk(arg); \ + } while (0) + +static int s5h1432_writereg(struct s5h1432_state *state, + u8 addr, u8 reg, u8 data) +{ + int ret; + u8 buf[] = { reg, data }; + + struct i2c_msg msg = {.addr = addr, .flags = 0, .buf = buf, .len = 2 }; + + ret = i2c_transfer(state->i2c, &msg, 1); + + if (ret != 1) + printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, " + "ret == %i)\n", __func__, addr, reg, data, ret); + + return (ret != 1) ? -1 : 0; +} + +static u8 s5h1432_readreg(struct s5h1432_state *state, u8 addr, u8 reg) +{ + int ret; + u8 b0[] = { reg }; + u8 b1[] = { 0 }; + + struct i2c_msg msg[] = { + {.addr = addr, .flags = 0, .buf = b0, .len = 1}, + {.addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1} + }; + + ret = i2c_transfer(state->i2c, msg, 2); + + if (ret != 2) + printk(KERN_ERR "%s: readreg error (ret == %i)\n", + __func__, ret); + return b1[0]; +} + +static int s5h1432_sleep(struct dvb_frontend *fe) +{ + return 0; +} + +static int s5h1432_set_channel_bandwidth(struct dvb_frontend *fe, + u32 bandwidth) +{ + struct s5h1432_state *state = fe->demodulator_priv; + + u8 reg = 0; + + /* Register [0x2E] bit 3:2 : 8MHz = 0; 7MHz = 1; 6MHz = 2 */ + reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x2E); + reg &= ~(0x0C); + switch (bandwidth) { + case 6: + reg |= 0x08; + break; + case 7: + reg |= 0x04; + break; + case 8: + reg |= 0x00; + break; + default: + return 0; + } + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2E, reg); + return 1; +} + +static int s5h1432_set_IF(struct dvb_frontend *fe, u32 ifFreqHz) +{ + struct s5h1432_state *state = fe->demodulator_priv; + + switch (ifFreqHz) { + case TAIWAN_HI_IF_FREQ_44_MHZ: + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x15); + break; + case EUROPE_HI_IF_FREQ_36_MHZ: + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x40); + break; + case IF_FREQ_6_MHZ: + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xe0); + break; + case IF_FREQ_3point3_MHZ: + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE); + break; + case IF_FREQ_3point5_MHZ: + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xED); + break; + case IF_FREQ_4_MHZ: + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0xAA); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0xAA); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEA); + break; + default: + { + u32 value = 0; + value = (u32) (((48000 - (ifFreqHz / 1000)) * 512 * + (u32) 32768) / (48 * 1000)); + printk(KERN_INFO + "Default IFFreq %d :reg value = 0x%x\n", + ifFreqHz, value); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, + (u8) value & 0xFF); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, + (u8) (value >> 8) & 0xFF); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, + (u8) (value >> 16) & 0xFF); + break; + } + + } + + return 1; +} + +/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ +static int s5h1432_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + u32 dvb_bandwidth = 8; + struct s5h1432_state *state = fe->demodulator_priv; + + if (p->frequency == state->current_frequency) { + /*current_frequency = p->frequency; */ + /*state->current_frequency = p->frequency; */ + } else { + fe->ops.tuner_ops.set_params(fe, p); + msleep(300); + s5h1432_set_channel_bandwidth(fe, dvb_bandwidth); + switch (p->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + dvb_bandwidth = 6; + s5h1432_set_IF(fe, IF_FREQ_4_MHZ); + break; + case BANDWIDTH_7_MHZ: + dvb_bandwidth = 7; + s5h1432_set_IF(fe, IF_FREQ_4_MHZ); + break; + case BANDWIDTH_8_MHZ: + dvb_bandwidth = 8; + s5h1432_set_IF(fe, IF_FREQ_4_MHZ); + break; + default: + return 0; + } + /*fe->ops.tuner_ops.set_params(fe, p); */ +/*Soft Reset chip*/ + msleep(30); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); + msleep(30); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); + + s5h1432_set_channel_bandwidth(fe, dvb_bandwidth); + switch (p->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + dvb_bandwidth = 6; + s5h1432_set_IF(fe, IF_FREQ_4_MHZ); + break; + case BANDWIDTH_7_MHZ: + dvb_bandwidth = 7; + s5h1432_set_IF(fe, IF_FREQ_4_MHZ); + break; + case BANDWIDTH_8_MHZ: + dvb_bandwidth = 8; + s5h1432_set_IF(fe, IF_FREQ_4_MHZ); + break; + default: + return 0; + } + /*fe->ops.tuner_ops.set_params(fe,p); */ + /*Soft Reset chip*/ + msleep(30); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); + msleep(30); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); + + } + + state->current_frequency = p->frequency; + + return 0; +} + +static int s5h1432_init(struct dvb_frontend *fe) +{ + struct s5h1432_state *state = fe->demodulator_priv; + + u8 reg = 0; + state->current_frequency = 0; + printk(KERN_INFO " s5h1432_init().\n"); + + /*Set VSB mode as default, this also does a soft reset */ + /*Initialize registers */ + + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x04, 0xa8); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x05, 0x01); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x07, 0x70); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x19, 0x80); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1b, 0x9D); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1c, 0x30); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1d, 0x20); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x1B); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2e, 0x40); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, 0x84); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x50, 0x5a); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x5a, 0xd3); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x68, 0x50); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xb8, 0x3c); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xc4, 0x10); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xcc, 0x9c); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xDA, 0x00); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe1, 0x94); + /* s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf4, 0xa1); */ + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf9, 0x00); + + /*For NXP tuner*/ + + /*Set 3.3MHz as default IF frequency */ + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE); + /* Set reg 0x1E to get the full dynamic range */ + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x31); + + /* Mode setting in demod */ + reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x42); + reg |= 0x80; + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, reg); + /* Serial mode */ + + /* Soft Reset chip */ + + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); + msleep(30); + s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); + + + return 0; +} + +static int s5h1432_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + return 0; +} + +static int s5h1432_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + return 0; +} + +static int s5h1432_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + return 0; +} + +static int s5h1432_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + + return 0; +} + +static int s5h1432_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + return 0; +} + +static int s5h1432_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + return 0; +} + +static int s5h1432_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *tune) +{ + return 0; +} + +static void s5h1432_release(struct dvb_frontend *fe) +{ + struct s5h1432_state *state = fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops s5h1432_ops; + +struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, + struct i2c_adapter *i2c) +{ + struct s5h1432_state *state = NULL; + + printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n"); + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL); + if (state == NULL) + goto error; + + /* setup the state */ + state->config = config; + state->i2c = i2c; + state->current_modulation = QAM_16; + state->inversion = state->config->inversion; + + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &s5h1432_ops, + sizeof(struct dvb_frontend_ops)); + + state->frontend.demodulator_priv = state; + + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(s5h1432_attach); + +static struct dvb_frontend_ops s5h1432_ops = { + + .info = { + .name = "Samsung s5h1432 DVB-T Frontend", + .type = FE_OFDM, + .frequency_min = 177000000, + .frequency_max = 858000000, + .frequency_stepsize = 166666, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER}, + + .init = s5h1432_init, + .sleep = s5h1432_sleep, + .set_frontend = s5h1432_set_frontend, + .get_frontend = s5h1432_get_frontend, + .get_tune_settings = s5h1432_get_tune_settings, + .read_status = s5h1432_read_status, + .read_ber = s5h1432_read_ber, + .read_signal_strength = s5h1432_read_signal_strength, + .read_snr = s5h1432_read_snr, + .read_ucblocks = s5h1432_read_ucblocks, + .release = s5h1432_release, +}; + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Enable verbose debug messages"); + +MODULE_DESCRIPTION("Samsung s5h1432 DVB-T Demodulator driver"); +MODULE_AUTHOR("Bill Liu"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/s5h1432.h b/drivers/media/dvb/frontends/s5h1432.h new file mode 100644 index 0000000..b57438c --- /dev/null +++ b/drivers/media/dvb/frontends/s5h1432.h @@ -0,0 +1,91 @@ +/* + * Samsung s5h1432 VSB/QAM demodulator driver + * + * Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + */ + +#ifndef __S5H1432_H__ +#define __S5H1432_H__ + +#include <linux/dvb/frontend.h> + +#define S5H1432_I2C_TOP_ADDR (0x02 >> 1) + +#define TAIWAN_HI_IF_FREQ_44_MHZ 44000000 +#define EUROPE_HI_IF_FREQ_36_MHZ 36000000 +#define IF_FREQ_6_MHZ 6000000 +#define IF_FREQ_3point3_MHZ 3300000 +#define IF_FREQ_3point5_MHZ 3500000 +#define IF_FREQ_4_MHZ 4000000 + +struct s5h1432_config { + + /* serial/parallel output */ +#define S5H1432_PARALLEL_OUTPUT 0 +#define S5H1432_SERIAL_OUTPUT 1 + u8 output_mode; + + /* GPIO Setting */ +#define S5H1432_GPIO_OFF 0 +#define S5H1432_GPIO_ON 1 + u8 gpio; + + /* MPEG signal timing */ +#define S5H1432_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 +#define S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 +#define S5H1432_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 +#define S5H1432_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 + u16 mpeg_timing; + + /* IF Freq for QAM and VSB in KHz */ +#define S5H1432_IF_3250 3250 +#define S5H1432_IF_3500 3500 +#define S5H1432_IF_4000 4000 +#define S5H1432_IF_5380 5380 +#define S5H1432_IF_44000 44000 +#define S5H1432_VSB_IF_DEFAULT s5h1432_IF_44000 +#define S5H1432_QAM_IF_DEFAULT s5h1432_IF_44000 + u16 qam_if; + u16 vsb_if; + + /* Spectral Inversion */ +#define S5H1432_INVERSION_OFF 0 +#define S5H1432_INVERSION_ON 1 + u8 inversion; + + /* Return lock status based on tuner lock, or demod lock */ +#define S5H1432_TUNERLOCKING 0 +#define S5H1432_DEMODLOCKING 1 + u8 status_mode; +}; + +#if defined(CONFIG_DVB_S5H1432) || \ + (defined(CONFIG_DVB_S5H1432_MODULE) && defined(MODULE)) +extern struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *s5h1432_attach(const struct s5h1432_config + *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_s5h1432 */ + +#endif /* __s5h1432_H__ */ diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c index d21a327..4b0c99a 100644 --- a/drivers/media/dvb/frontends/si21xx.c +++ b/drivers/media/dvb/frontends/si21xx.c @@ -268,7 +268,7 @@ static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data) return (ret != 1) ? -EREMOTEIO : 0; } -static int si21_write(struct dvb_frontend *fe, u8 *buf, int len) +static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len) { struct si21xx_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c index f73c133..80a9e4c 100644 --- a/drivers/media/dvb/frontends/stb6100.c +++ b/drivers/media/dvb/frontends/stb6100.c @@ -506,7 +506,7 @@ static struct dvb_tuner_ops stb6100_ops = { }; struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, - struct stb6100_config *config, + const struct stb6100_config *config, struct i2c_adapter *i2c) { struct stb6100_state *state = NULL; diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb/frontends/stb6100.h index 395d056..2ab0966 100644 --- a/drivers/media/dvb/frontends/stb6100.h +++ b/drivers/media/dvb/frontends/stb6100.h @@ -97,13 +97,13 @@ struct stb6100_state { #if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE)) extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, - struct stb6100_config *config, + const struct stb6100_config *config, struct i2c_adapter *i2c); #else static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, - struct stb6100_config *config, + const struct stb6100_config *config, struct i2c_adapter *i2c) { printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c index 2930a5d..63db8fd 100644 --- a/drivers/media/dvb/frontends/stv0288.c +++ b/drivers/media/dvb/frontends/stv0288.c @@ -6,6 +6,8 @@ Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by> Removed stb6000 specific tuner code and revised some procedures. + 2010-09-01 Josef Pavlik <josef@pavlik.it> + Fixed diseqc_msg, diseqc_burst and set_tone problems 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 @@ -78,7 +80,7 @@ static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data) return (ret != 1) ? -EREMOTEIO : 0; } -static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len) +static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len) { struct stv0288_state *state = fe->demodulator_priv; @@ -156,14 +158,13 @@ static int stv0288_send_diseqc_msg(struct dvb_frontend *fe, stv0288_writeregI(state, 0x09, 0); msleep(30); - stv0288_writeregI(state, 0x05, 0x16); + stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */ for (i = 0; i < m->msg_len; i++) { if (stv0288_writeregI(state, 0x06, m->msg[i])) return -EREMOTEIO; - msleep(12); } - + msleep(m->msg_len*12); return 0; } @@ -174,13 +175,14 @@ static int stv0288_send_diseqc_burst(struct dvb_frontend *fe, dprintk("%s\n", __func__); - if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */ + if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */ return -EREMOTEIO; if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff)) return -EREMOTEIO; - if (stv0288_writeregI(state, 0x06, 0x12)) + msleep(15); + if (stv0288_writeregI(state, 0x05, 0x12)) return -EREMOTEIO; return 0; @@ -192,18 +194,19 @@ static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) switch (tone) { case SEC_TONE_ON: - if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */ + if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */ return -EREMOTEIO; - return stv0288_writeregI(state, 0x06, 0xff); + break; case SEC_TONE_OFF: - if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */ + if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/ return -EREMOTEIO; - return stv0288_writeregI(state, 0x06, 0x00); + break; default: return -EINVAL; } + return 0; } static u8 stv0288_inittab[] = { @@ -486,7 +489,7 @@ static int stv0288_set_frontend(struct dvb_frontend *fe, tda[2] = 0x0; /* CFRL */ for (tm = -6; tm < 7;) { /* Viterbi status */ - if (stv0288_readreg(state, 0x24) & 0x80) + if (stv0288_readreg(state, 0x24) & 0x8) break; tda[2] += 40; diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 9688744..4e3db3a 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c @@ -92,7 +92,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) return (ret != 1) ? -EREMOTEIO : 0; } -static int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len) +static int stv0299_write(struct dvb_frontend* fe, const u8 buf[], int len) { struct stv0299_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index 0fd96e2..ba219b7 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h @@ -65,7 +65,7 @@ struct stv0299_config * First of each pair is the register, second is the value. * List should be terminated with an 0xff, 0xff pair. */ - u8* inittab; + const u8* inittab; /* master clock to use */ u32 mclk; diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index f2a8abe..ea485d9 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -598,7 +598,7 @@ static int tda1004x_decode_fec(int tdafec) return -1; } -static int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) +static int tda1004x_write(struct dvb_frontend* fe, const u8 buf[], int len) { struct tda1004x_state* state = fe->demodulator_priv; diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index 8c61271..adbbf6d 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c @@ -64,7 +64,7 @@ static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) return 0; } -static int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) +static int zl10353_write(struct dvb_frontend *fe, const u8 ibuf[], int ilen) { int err, i; for (i = 0; i < ilen - 1; i++) diff --git a/drivers/media/dvb/mantis/mantis_core.c b/drivers/media/dvb/mantis/mantis_core.c index 8113b23..22524a8 100644 --- a/drivers/media/dvb/mantis/mantis_core.c +++ b/drivers/media/dvb/mantis/mantis_core.c @@ -91,10 +91,7 @@ static int get_mac_address(struct mantis_pci *mantis) return err; } dprintk(verbose, MANTIS_ERROR, 0, - " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", - mantis->mac_address[0], mantis->mac_address[1], - mantis->mac_address[2], mantis->mac_address[3], - mantis->mac_address[4], mantis->mac_address[5]); + " MAC Address=[%pM]\n", mantis->mac_address); return 0; } diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/dvb/mantis/mantis_i2c.c index 7870bcf..e779451 100644 --- a/drivers/media/dvb/mantis/mantis_i2c.c +++ b/drivers/media/dvb/mantis/mantis_i2c.c @@ -229,7 +229,6 @@ int __devinit mantis_i2c_init(struct mantis_pci *mantis) i2c_set_adapdata(i2c_adapter, mantis); i2c_adapter->owner = THIS_MODULE; - i2c_adapter->class = I2C_CLASS_TV_DIGITAL; i2c_adapter->algo = &mantis_algo; i2c_adapter->algo_data = NULL; i2c_adapter->timeout = 500; diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c index de148de..fe31cfb 100644 --- a/drivers/media/dvb/mantis/mantis_ioc.c +++ b/drivers/media/dvb/mantis/mantis_ioc.c @@ -68,14 +68,7 @@ int mantis_get_mac(struct mantis_pci *mantis) return err; } - dprintk(MANTIS_ERROR, 0, - " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", - mac_addr[0], - mac_addr[1], - mac_addr[2], - mac_addr[3], - mac_addr[4], - mac_addr[5]); + dprintk(MANTIS_ERROR, 0, " MAC Address=[%pM]\n", mac_addr); return 0; } diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c index 477fe0a..c3ae956 100644 --- a/drivers/media/dvb/ngene/ngene-i2c.c +++ b/drivers/media/dvb/ngene/ngene-i2c.c @@ -165,7 +165,6 @@ int ngene_i2c_init(struct ngene *dev, int dev_nr) struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter); i2c_set_adapdata(adap, &(dev->channel[dev_nr])); - adap->class = I2C_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG; strcpy(adap->name, "nGene"); diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 1c79821..6ca6713d 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -647,7 +647,6 @@ static int __devinit pluto2_probe(struct pci_dev *pdev, i2c_set_adapdata(&pluto->i2c_adap, pluto); strcpy(pluto->i2c_adap.name, DRIVER_NAME); pluto->i2c_adap.owner = THIS_MODULE; - pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL; pluto->i2c_adap.dev.parent = &pdev->dev; pluto->i2c_adap.algo_data = &pluto->i2c_bit; pluto->i2c_bit.data = pluto; diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c index 69ad949..0486919 100644 --- a/drivers/media/dvb/pt1/pt1.c +++ b/drivers/media/dvb/pt1/pt1.c @@ -1087,7 +1087,6 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pt1_update_power(pt1); i2c_adap = &pt1->i2c_adap; - i2c_adap->class = I2C_CLASS_TV_DIGITAL; i2c_adap->algo = &pt1_i2c_algo; i2c_adap->algo_data = NULL; i2c_adap->dev.parent = &pdev->dev; diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index ff3b0fa..135e45b 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -1504,8 +1504,7 @@ int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, u32 msgData[3]; /* keep it 3 ! */ } *pMsg; - if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) || - (PinNum > MAX_GPIO_PIN_NUMBER)) + if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER)) return -EINVAL; totalLen = sizeof(struct SmsMsgHdr_ST) + diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c index d0e4639..a27c44a 100644 --- a/drivers/media/dvb/siano/smsir.c +++ b/drivers/media/dvb/siano/smsir.c @@ -40,7 +40,7 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) const s32 *samples = (const void *)buf; for (i = 0; i < len >> 2; i++) { - struct ir_raw_event ev; + DEFINE_IR_RAW_EVENT(ev); ev.duration = abs(samples[i]) * 1000; /* Convert to ns */ ev.pulse = (samples[i] > 0) ? false : true; diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index a12b88f..fc0a60f 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -2472,7 +2472,6 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, get recognized before the main driver is fully loaded */ saa7146_write(dev, GPIO_CTRL, 0x500000); - av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL; strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ @@ -2886,7 +2885,7 @@ MODULE_DEVICE_TABLE(pci, pci_tbl); static struct saa7146_extension av7110_extension_driver = { - .name = "dvb", + .name = "av7110", .flags = SAA7146_USE_I2C_IRQ, .module = THIS_MODULE, diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 244d5d5..952b33d 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -245,8 +245,11 @@ int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) return -1; } while (1) { - if ((len = dvb_ringbuffer_avail(buf)) < 6) + len = dvb_ringbuffer_avail(buf); + if (len < 6) { + wake_up(&buf->queue); return -1; + } sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24; sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16; sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8; diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index 0546613..37666d4 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c @@ -495,8 +495,6 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, if (bi->type != BUDGET_FS_ACTIVY) saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ - budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL; - strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name)); saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 4a3f2b8..40625b2 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1694,7 +1694,6 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i i2c_set_adapdata(&ttusb->i2c_adap, ttusb); - ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; ttusb->i2c_adap.algo = &ttusb_dec_algo; ttusb->i2c_adap.algo_data = NULL; ttusb->i2c_adap.dev.parent = &udev->dev; |