|
|
| Line 12: |
Line 12: |
| | Manufacturer: NEWMI | | Manufacturer: NEWMI |
| | | | |
| - | There is a patch available to support this device:
| + | Uses tuner NXP TDA18218 and AF9015A. Use Kernel-2.6.37 or v4l-dvb git. |
| - | http://www.mail-archive.com/linux-media@vger.kernel.org/msg16117.html
| + | |
| | | | |
| - | However, this patch doesnt fit anymore perfectly on 2.6.35.4 due to some changes on IR and there is no official support in dvb-hg; so this patch needs to be adapted and applied.
| + | After loading dvb-usb-af9015 you should see the following: |
| - | Testing afterwards can be done as usual, for example with tzap, scan or w_scan. Needs also firmware [http://palosaari.fi/linux/v4l-dvb/firmware/af9015/4.95.0.0/dvb-usb-af9015.fw dvb-usb-af9015.fw].
| + | |
| - | | + | |
| - | Note: current Windows driver uses firmware 5.1.0.0, but the patched dvb-usb-af9015 works better with 4.95.0.0
| + | |
| - | | + | |
| - | Uses tuner NXP TDA18218, which is quite similiar to TDA18271. Preliminary support for this tuner is added with the patch above.
| + | |
| - | | + | |
| - | After applying patch and loading dvb-usb-af9015 you should see the following: | + | |
| | <pre> | | <pre> |
| | usb 3-3: new high speed USB device using ehci_hcd and address 3 | | usb 3-3: new high speed USB device using ehci_hcd and address 3 |
| Line 41: |
Line 33: |
| | input: NEWMI USB2.0 DVB-T TV Stick as /devices/pci0000:00/0000:00:1a.7/usb3/3-3/3-3:1.1/input/input8 | | input: NEWMI USB2.0 DVB-T TV Stick as /devices/pci0000:00/0000:00:1a.7/usb3/3-3/3-3:1.1/input/input8 |
| | generic-usb 0003:0CCD:0097.0002: input,hidraw0: USB HID v1.01 Keyboard [NEWMI USB2.0 DVB-T TV Stick] on usb-0000:00:1a.7-3/input1 | | generic-usb 0003:0CCD:0097.0002: input,hidraw0: USB HID v1.01 Keyboard [NEWMI USB2.0 DVB-T TV Stick] on usb-0000:00:1a.7-3/input1 |
| - | </pre>
| |
| - |
| |
| - | === [http://www.mail-archive.com/linux-media@vger.kernel.org/msg16117.html patch] with changes to linux-2.6.35.4 ===
| |
| - | <pre>
| |
| - | diff -Nru linux-2.6.35.4/drivers/media/common/tuners/Kconfig /usr/src/linux-2.6.35.4/drivers/media/common/tuners/Kconfig
| |
| - | --- linux-2.6.35.4/drivers/media/common/tuners/Kconfig 2010-08-27 01:47:12.000000000 +0200
| |
| - | +++ /usr/src/linux-2.6.35.4/drivers/media/common/tuners/Kconfig 2011-01-04 13:59:07.642000010 +0100
| |
| - | @@ -179,4 +179,11 @@
| |
| - | help
| |
| - | A driver for the silicon tuner MAX2165 from Maxim.
| |
| - |
| |
| - | +config MEDIA_TUNER_TDA18218
| |
| - | + tristate "NXP TDA18218 silicon tuner"
| |
| - | + depends on VIDEO_MEDIA && I2C
| |
| - | + default m if MEDIA_TUNER_CUSTOMISE
| |
| - | + help
| |
| - | + A driver for the silicon tuner TDA18218 from NXP.
| |
| - | +
| |
| - | endif # MEDIA_TUNER_CUSTOMISE
| |
| - | diff -Nru linux-2.6.35.4/drivers/media/common/tuners/Makefile /usr/src/linux-2.6.35.4/drivers/media/common/tuners/Makefile
| |
| - | --- linux-2.6.35.4/drivers/media/common/tuners/Makefile 2010-08-27 01:47:12.000000000 +0200
| |
| - | +++ /usr/src/linux-2.6.35.4/drivers/media/common/tuners/Makefile 2011-01-04 13:59:50.733000011 +0100
| |
| - | @@ -24,6 +24,7 @@
| |
| - | obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
| |
| - | obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
| |
| - | obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
| |
| - | +obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
| |
| - |
| |
| - | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
| |
| - | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
| |
| - | diff -Nru linux-2.6.35.4/drivers/media/common/tuners/tda18218.c /usr/src/linux-2.6.35.4/drivers/media/common/tuners/tda18218.c
| |
| - | --- linux-2.6.35.4/drivers/media/common/tuners/tda18218.c 1970-01-01 01:00:00.000000000 +0100
| |
| - | +++ /usr/src/linux-2.6.35.4/drivers/media/common/tuners/tda18218.c 2011-01-04 15:22:54.068000023 +0100
| |
| - | @@ -0,0 +1,471 @@
| |
| - | +/*
| |
| - | + * Driver for NXP TDA18218 silicon tuner
| |
| - | + *
| |
| - | + * Copyright (C) 2010 Lauris Ding <ld...@gmx.de>
| |
| - | + * 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 "tda18218.h"
| |
| - | +//#include "compat.h"
| |
| - | +#include "tda18218_priv.h"
| |
| - | +
| |
| - | +static int tda18218_write_reg(struct dvb_frontend *fe, u8 reg, u8 val)
| |
| - | +{
| |
| - | + struct tda18218_priv *priv = fe->tuner_priv;
| |
| - | + u8 buf[2] = { reg, val };
| |
| - | + struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
| |
| - | + .buf = buf, .len = 2 };
| |
| - | + int ret;
| |
| - | +
| |
| - | + if (fe->ops.i2c_gate_ctrl)
| |
| - | + fe->ops.i2c_gate_ctrl(fe, 1);
| |
| - | + /* write register */
| |
| - | + ret = i2c_transfer(priv->i2c, &msg, 1);
| |
| - | + if (fe->ops.i2c_gate_ctrl)
| |
| - | + fe->ops.i2c_gate_ctrl(fe, 0);
| |
| - | +
| |
| - | + if (ret != 1)
| |
| - | + printk(KERN_WARNING "I2C write failed ret: %d reg: %02x\n", ret, reg);
| |
| - | +
| |
| - | + return (ret == 1 ? 0 : ret);
| |
| - | +}
| |
| - | +
| |
| - | +static int tda18218_write_regs(struct dvb_frontend *fe, u8 reg,
| |
| - | + u8 *val, u8 len)
| |
| - | +{
| |
| - | + struct tda18218_priv *priv = fe->tuner_priv;
| |
| - | + u8 buf[1+len];
| |
| - | + struct i2c_msg msg = {
| |
| - | + .addr = priv->cfg->i2c_address,
| |
| - | + .flags = 0,
| |
| - | + .len = sizeof(buf),
| |
| - | + .buf = buf };
| |
| - | +
| |
| - | + int ret;
| |
| - | +
| |
| - | + buf[0] = reg;
| |
| - | + memcpy(&buf[1], val, len);
| |
| - | +
| |
| - | + if (fe->ops.i2c_gate_ctrl)
| |
| - | + fe->ops.i2c_gate_ctrl(fe, 1);
| |
| - | + ret = i2c_transfer(priv->i2c, &msg, 1);
| |
| - | + if (fe->ops.i2c_gate_ctrl)
| |
| - | + fe->ops.i2c_gate_ctrl(fe, 1);
| |
| - | +
| |
| - | + if (ret != 1)
| |
| - | + printk(KERN_WARNING "I2C write failed ret: %d reg: %02x len: %d\n", ret, reg, len);
| |
| - | +
| |
| - | + return (ret == 1 ? 0 : ret);
| |
| - | +}
| |
| - | +
| |
| - | +/*static int tda18218_read_reg(struct tda18218_priv *priv, u16 reg, u8 *val)
| |
| - | +{
| |
| - | + u8 obuf[3] = { reg >> 8, reg & 0xff, 0 };
| |
| - | + u8 ibuf[1];
| |
| - | + struct i2c_msg msg[2] = {
| |
| - | + {
| |
| - | + .addr = 0x3a,
| |
| - | + .flags = 0,
| |
| - | + .len = sizeof(obuf),
| |
| - | + .buf = obuf
| |
| - | + }, {
| |
| - | + .addr = 0x3a,
| |
| - | + .flags = I2C_M_RD,
| |
| - | + .len = sizeof(ibuf),
| |
| - | + .buf = ibuf
| |
| - | + }
| |
| - | + };
| |
| - | +
| |
| - | + if (i2c_transfer(priv->i2c, msg, 2) != 2) {
| |
| - | + printk(KERN_WARNING "I2C read failed reg:%04x\n", reg);
| |
| - | + return -EREMOTEIO;
| |
| - | + }
| |
| - | + *val = ibuf[0];
| |
| - | + return 0;
| |
| - | +}*/
| |
| - | +
| |
| - | +static int tda18218_read_regs(struct dvb_frontend *fe)
| |
| - | +{
| |
| - | + struct tda18218_priv *priv = fe->tuner_priv;
| |
| - | + u8 *regs = priv->tda18218_regs;
| |
| - | + u8 buf = 0x00;
| |
| - | + int ret;
| |
| - | + //int i;
| |
| - | + struct i2c_msg msg[] = {
| |
| - | + { .addr = 0xc0, .flags = 0,
| |
| - | + .buf = &buf, .len = 1 },
| |
| - | + { .addr = 0xc0, .flags = I2C_M_RD,
| |
| - | + .buf = regs, .len = 59 }
| |
| - | + };
| |
| - | +
| |
| - | + if (fe->ops.i2c_gate_ctrl)
| |
| - | + fe->ops.i2c_gate_ctrl(fe, 1);
| |
| - | +
| |
| - | + /* read all registers */
| |
| - | + ret = i2c_transfer(priv->i2c, msg, 2);
| |
| - | +
| |
| - | + if (fe->ops.i2c_gate_ctrl)
| |
| - | + fe->ops.i2c_gate_ctrl(fe, 0);
| |
| - | +
| |
| - | + if (ret != 2)
| |
| - | + printk(KERN_WARNING "I2C read failed ret: %d\n", ret);
| |
| - | +
| |
| - | + /*for(i = 0; i <= 58; i++)
| |
| - | + printk("Register %d: %02x\n", i, 0xff & regs[i]);*/
| |
| - | +
| |
| - | + return (ret == 2 ? 0 : ret);
| |
| - | +}
| |
| - | +
| |
| - | +static int tda18218_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
| |
| - | +{
| |
| - | + struct tda18218_priv *priv = fe->tuner_priv;
| |
| - | + u8 *regs = priv->tda18218_regs;
| |
| - | + u8 Fc, BP;
| |
| - | + int i, ret;
| |
| - | + u16 if1, bw;
| |
| - | + u32 freq;
| |
| - | +
| |
| - | + u8 paramsbuf[4][6] = {
| |
| - | + { 0x03, 0x1a },
| |
| - | + { 0x04, 0x0a },
| |
| - | + { 0x01, 0x0f },
| |
| - | + { 0x01, 0x0f },
| |
| - | + };
| |
| - | +
| |
| - | + u8 agcbuf[][2] = {
| |
| - | + { 0x1a, 0x0e },
| |
| - | + { 0x20, 0x60 },
| |
| - | + { 0x23, 0x02 },
| |
| - | + { 0x20, 0xa0 },
| |
| - | + { 0x23, 0x09 },
| |
| - | + { 0x20, 0xe0 },
| |
| - | + { 0x23, 0x0c },
| |
| - | + { 0x20, 0x40 },
| |
| - | + { 0x23, 0x01 },
| |
| - | + { 0x20, 0x80 },
| |
| - | + { 0x23, 0x08 },
| |
| - | + { 0x20, 0xc0 },
| |
| - | + { 0x23, 0x0b },
| |
| - | + { 0x24, 0x1c },
| |
| - | + { 0x24, 0x0c },
| |
| - | + };
| |
| - | +
| |
| - | + switch (params->u.ofdm.bandwidth) {
| |
| - | + case BANDWIDTH_6_MHZ:
| |
| - | + bw = 6000;
| |
| - | + Fc = 0;
| |
| - | + break;
| |
| - | + case BANDWIDTH_7_MHZ:
| |
| - | + bw = 7000;
| |
| - | + Fc = 1;
| |
| - | + break;
| |
| - | + case BANDWIDTH_8_MHZ:
| |
| - | + bw = 8000;
| |
| - | + Fc = 2;
| |
| - | + break;
| |
| - | + default:
| |
| - | + printk(KERN_WARNING "Invalid bandwidth");
| |
| - | + return -EINVAL;
| |
| - | + }
| |
| - | +
| |
| - | + if1 = bw / 2;
| |
| - | +
| |
| - | + if((params->frequency >= 174000000) && (params->frequency < 188000000)) {
| |
| - | + BP = 3;
| |
| - | + }
| |
| - | + else if((params->frequency >= 188000000) && (params->frequency < 253000000)) {
| |
| - | + BP = 4;
| |
| - | + }
| |
| - | + else if((params->frequency >= 253000000) && (params->frequency < 343000000)) {
| |
| - | + BP = 5;
| |
| - | + }
| |
| - | + else if((params->frequency >= 343000000) && (params->frequency <= 870000000)) {
| |
| - | + BP = 6;
| |
| - | + }
| |
| - | + else {
| |
| - | + printk(KERN_WARNING "Frequency out of range");
| |
| - | + return -EINVAL;
| |
| - | + }
| |
| - | +
| |
| - | + freq = params->frequency;
| |
| - | + freq /= 1000;
| |
| - | + freq +=if1;
| |
| - | + freq *= 16;
| |
| - | +
| |
| - | + tda18218_read_regs(fe);
| |
| - | +
| |
| - | + paramsbuf[0][2] = regs[0x1a] | BP;
| |
| - | + paramsbuf[0][3] = regs[0x1b] & ~3;
| |
| - | + paramsbuf[0][3] = regs[0x1b] | Fc;
| |
| - | + paramsbuf[0][4] = regs[0x1c] | 0x0a;
| |
| - | +
| |
| - | + paramsbuf[1][2] = freq >> 16;
| |
| - | + paramsbuf[1][3] = freq >> 8;
| |
| - | + paramsbuf[1][4] = (freq & 0xf0) | (regs[0x0c] & 0x0f);
| |
| - | + paramsbuf[1][5] = 0xff;
| |
| - | + paramsbuf[2][2] = regs[0x0f] | 0x40;
| |
| - | + paramsbuf[3][2] = 0x09;
| |
| - | +
| |
| - | + tda18218_write_reg(fe, 0x04, 0x03);
| |
| - | +
| |
| - | + for(i = 0; i < ARRAY_SIZE(paramsbuf); i++) {
| |
| - | +
| |
| - | + /* write registers */
| |
| - | + ret = tda18218_write_regs(fe, paramsbuf[i][1], ¶msbuf[i][2], paramsbuf[i][0]);
| |
| - | +
| |
| - | + if (ret)
| |
| - | + goto error;
| |
| - | + }
| |
| - | + for(i = 0; i < ARRAY_SIZE(agcbuf); i++) {
| |
| - | + tda18218_write_reg(fe, agcbuf[i][0], agcbuf[i][1]);
| |
| - | + }
| |
| - | +
| |
| - | + //tda18218_write_reg(fe, 0x03, 0x00);
| |
| - | + //tda18218_write_reg(fe, 0x04, 0x00);
| |
| - | + //tda18218_write_reg(fe, 0x20, 0xc7);
| |
| - | +
| |
| - | + msleep(60);
| |
| - | + i = 0;
| |
| - | + while(i < 10) {
| |
| - | + tda18218_read_regs(fe);
| |
| - | + if((regs[0x01] & 0x60) == 0x60)
| |
| - | + printk(KERN_INFO "We've got a lock!"); break;
| |
| - | + msleep(20);
| |
| - | + i++;
| |
| - | + }
| |
| - | +
| |
| - | + priv->bandwidth = params->u.ofdm.bandwidth;
| |
| - | + priv->frequency = params->frequency;
| |
| - | + return 0;
| |
| - | +error:
| |
| - | + return ret;
| |
| - | +}
| |
| - | +
| |
| - | +static int tda18218_get_frequency(struct dvb_frontend *fe, u32 *frequency)
| |
| - | +{
| |
| - | + struct tda18218_priv *priv = fe->tuner_priv;
| |
| - | + *frequency = priv->frequency;
| |
| - | + return 0;
| |
| - | +}
| |
| - | +
| |
| - | +static int tda18218_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
| |
| - | +{
| |
| - | + struct tda18218_priv *priv = fe->tuner_priv;
| |
| - | + *bandwidth = priv->bandwidth;
| |
| - | + return 0;
| |
| - | +}
| |
| - | +
| |
| - | +static int tda18218_init(struct dvb_frontend *fe)
| |
| - | +{
| |
| - | + //struct tda18218_priv *priv = fe->tuner_priv;
| |
| - | + //u8 *regs = priv->tda18218_regs;
| |
| - | + int i;
| |
| - | + int ret;
| |
| - | +
| |
| - | + u8 initbuf[][18] = {
| |
| - | + { 0x10, 0x05, 0x00, 0x00, 0xd0, 0x00, 0x40, 0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00, 0x01 },
| |
| - | + { 0x0b, 0x15, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x0e, 0x29, 0x98, 0x00, 0x00, 0x58 },
| |
| - | + { 0x10, 0x24, 0x0c, 0x48, 0x85, 0xc9, 0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00, 0x8a, 0x00 },
| |
| - | + { 0x07, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6 },
| |
| - | + };
| |
| - | +
| |
| - | + u8 initbuf2[4];
| |
| - | +
| |
| - | + for(i = 0; i < ARRAY_SIZE(initbuf); i++) {
| |
| - | +
| |
| - | + /* write registers */
| |
| - | + ret = tda18218_write_regs(fe, initbuf[i][1], &initbuf[i][2], initbuf[i][0]);
| |
| - | +
| |
| - | + if (ret != 0) {
| |
| - | + printk(KERN_ERR "init: ERROR: i2c_transfer returned: %d\n", ret);
| |
| - | + return -EREMOTEIO;
| |
| - | + }
| |
| - | + if(i == 1) {
| |
| - | + tda18218_write_reg(fe, 0x22, 0x8c);
| |
| - | + }
| |
| - | + }
| |
| - | +
| |
| - | + tda18218_write_reg(fe, 0x05, 0x80);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x20);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x27, 0xde);
| |
| - | + tda18218_write_reg(fe, 0x17, 0xf8);
| |
| - | + tda18218_write_reg(fe, 0x18, 0x0f);
| |
| - | + tda18218_write_reg(fe, 0x1c, 0x8b);
| |
| - | + tda18218_write_reg(fe, 0x29, 0x02);
| |
| - | + tda18218_write_reg(fe, 0x19, 0x1a);
| |
| - | + tda18218_write_reg(fe, 0x11, 0x13);
| |
| - | +
| |
| - | + initbuf2[0] = 0x0a;
| |
| - | + initbuf2[1] = 0x5c;
| |
| - | + initbuf2[2] = 0xc6;
| |
| - | + initbuf2[3] = 0x07;
| |
| - | + tda18218_write_regs(fe, initbuf2[0], &initbuf2[1], 3);
| |
| - | + tda18218_write_reg(fe, 0x0f, 0x49);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x40);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x20);
| |
| - | + tda18218_write_reg(fe, 0x11, 0xed);
| |
| - | + tda18218_write_reg(fe, 0x0f, 0x49);
| |
| - | + tda18218_write_reg(fe, 0x19, 0x2a);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x58);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x18);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x38);
| |
| - | + tda18218_write_reg(fe, 0x29, 0x03);
| |
| - | + tda18218_write_reg(fe, 0x19, 0x1a);
| |
| - | + tda18218_write_reg(fe, 0x11, 0x13);
| |
| - | + initbuf2[0] = 0x0a;
| |
| - | + initbuf2[1] = 0xbe;
| |
| - | + initbuf2[2] = 0x6e;
| |
| - | + initbuf2[3] = 0x07;
| |
| - | + tda18218_write_regs(fe, initbuf2[0], &initbuf2[1], 3);
| |
| - | + tda18218_write_reg(fe, 0x0f, 0x49);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x58);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x18);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x38);
| |
| - | + tda18218_write_reg(fe, 0x11, 0xed);
| |
| - | + tda18218_write_reg(fe, 0x0f, 0x49);
| |
| - | + tda18218_write_reg(fe, 0x19, 0x2a);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x58);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x18);
| |
| - | + tda18218_write_reg(fe, 0x05, 0x38);
| |
| - | + tda18218_write_reg(fe, 0x19, 0x0a);
| |
| - | + tda18218_write_reg(fe, 0x27, 0xc9);
| |
| - | + tda18218_write_reg(fe, 0x11, 0x13);
| |
| - | + initbuf2[0] = 0x17;
| |
| - | + initbuf2[1] = 0xf0;
| |
| - | + initbuf2[2] = 0x19;
| |
| - | + initbuf2[3] = 0x00;
| |
| - | + tda18218_write_regs(fe, initbuf2[0], &initbuf2[1], 2);
| |
| - | + tda18218_write_reg(fe, 0x1c, 0x98);
| |
| - | + tda18218_write_reg(fe, 0x29, 0x03);
| |
| - | + tda18218_write_reg(fe, 0x2a, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x2a, 0x01);
| |
| - | + tda18218_write_reg(fe, 0x2a, 0x02);
| |
| - | + tda18218_write_reg(fe, 0x2a, 0x03);
| |
| - | + tda18218_write_reg(fe, 0x1c, 0x98);
| |
| - | + tda18218_write_reg(fe, 0x18, 0x19);
| |
| - | + tda18218_write_reg(fe, 0x22, 0x9c);
| |
| - | + tda18218_write_reg(fe, 0x1f, 0x58);
| |
| - | + tda18218_write_reg(fe, 0x24, 0x0c);
| |
| - | + tda18218_write_reg(fe, 0x1c, 0x88);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x10);
| |
| - | + tda18218_write_reg(fe, 0x21, 0x4c);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x21, 0x48);
| |
| - | + tda18218_write_reg(fe, 0x1f, 0x5b);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x1f, 0x59);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x1f, 0x5a);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x1f, 0x5f);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x1f, 0x5d);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x1f, 0x5e);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x00);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x60);
| |
| - | + tda18218_write_reg(fe, 0x23, 0x02);
| |
| - | + tda18218_write_reg(fe, 0x20, 0xa0);
| |
| - | + tda18218_write_reg(fe, 0x23, 0x09);
| |
| - | + tda18218_write_reg(fe, 0x20, 0xe0);
| |
| - | + tda18218_write_reg(fe, 0x23, 0x0c);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x40);
| |
| - | + tda18218_write_reg(fe, 0x23, 0x01);
| |
| - | + tda18218_write_reg(fe, 0x20, 0x80);
| |
| - | + tda18218_write_reg(fe, 0x23, 0x08);
| |
| - | + tda18218_write_reg(fe, 0x20, 0xc0);
| |
| - | + tda18218_write_reg(fe, 0x23, 0x0b);
| |
| - | + tda18218_write_reg(fe, 0x1c, 0x98);
| |
| - | + tda18218_write_reg(fe, 0x22, 0x8c);
| |
| - | + initbuf2[0] = 0x17;
| |
| - | + initbuf2[1] = 0xb0;
| |
| - | + initbuf2[2] = 0x59;
| |
| - | + initbuf2[3] = 0x00;
| |
| - | + //tda18218_write_regs(fe, initbuf2[0], &initbuf2[1], 2);
| |
| - | + initbuf2[0] = 0x1a;
| |
| - | + initbuf2[1] = 0x0e;
| |
| - | + initbuf2[2] = 0x2a;
| |
| - | + initbuf2[3] = 0x98;
| |
| - | + tda18218_write_regs(fe, initbuf2[0], &initbuf2[1], 3);
| |
| - | + initbuf2[0] = 0x17;
| |
| - | + initbuf2[1] = 0xb0;
| |
| - | + initbuf2[2] = 0x59;
| |
| - | + initbuf2[3] = 0x00;
| |
| - | + tda18218_write_regs(fe, initbuf2[0], &initbuf2[1], 2);
| |
| - | + tda18218_write_reg(fe, 0x2d, 0x81);
| |
| - | + tda18218_write_reg(fe, 0x29, 0x02);
| |
| - | +
| |
| - | + return 0;
| |
| - | +}
| |
| - | +
| |
| - | +static int tda18218_release(struct dvb_frontend *fe)
| |
| - | +{
| |
| - | + kfree(fe->tuner_priv);
| |
| - | + fe->tuner_priv = NULL;
| |
| - | + return 0;
| |
| - | +}
| |
| - | +
| |
| - | +static const struct dvb_tuner_ops tda18218_tuner_ops = {
| |
| - | + .info = {
| |
| - | + .name = "NXP TDA18218",
| |
| - | + .frequency_min = TDA18218_MIN_FREQ,
| |
| - | + .frequency_max = TDA18218_MAX_FREQ,
| |
| - | + .frequency_step = TDA18218_STEP,
| |
| - | + },
| |
| - | +
| |
| - | + .release = tda18218_release,
| |
| - | + .init = tda18218_init,
| |
| - | +
| |
| - | + .set_params = tda18218_set_params,
| |
| - | + .get_frequency = tda18218_get_frequency,
| |
| - | + .get_bandwidth = tda18218_get_bandwidth,
| |
| - | +};
| |
| - | +
| |
| - | +struct dvb_frontend * tda18218_attach(struct dvb_frontend *fe,
| |
| - | + struct i2c_adapter *i2c,
| |
| - | + struct tda18218_config *cfg)
| |
| - | +{
| |
| - | + struct tda18218_priv *priv = NULL;
| |
| - | +
| |
| - | + priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
| |
| - | + if (priv == NULL)
| |
| - | + return NULL;
| |
| - | +
| |
| - | + priv->cfg = cfg;
| |
| - | + priv->i2c = i2c;
| |
| - | +
| |
| - | + fe->tuner_priv = priv;
| |
| - | +
| |
| - | + tda18218_read_regs(fe);
| |
| - | + if (priv->tda18218_regs[0x00] != 0xc0) {
| |
| - | + printk(KERN_WARNING "Device is not a TDA18218!\n");
| |
| - | + kfree(priv);
| |
| - | + return NULL;
| |
| - | + }
| |
| - | +
| |
| - | + printk(KERN_INFO "NXP TDA18218 successfully identified.\n");
| |
| - | + memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
| |
| - | + sizeof(struct dvb_tuner_ops));
| |
| - | +
| |
| - | + return fe;
| |
| - | +}
| |
| - | +EXPORT_SYMBOL(tda18218_attach);
| |
| - | +
| |
| - | +MODULE_DESCRIPTION("NXP TDA18218 silicon tuner driver");
| |
| - | +MODULE_AUTHOR("Lauris Ding <ld...@gmx.de>");
| |
| - | +MODULE_VERSION("0.1");
| |
| - | +MODULE_LICENSE("GPL");
| |
| - | diff -Nru linux-2.6.35.4/drivers/media/common/tuners/tda18218.h /usr/src/linux-2.6.35.4/drivers/media/common/tuners/tda18218.h
| |
| - | --- linux-2.6.35.4/drivers/media/common/tuners/tda18218.h 1970-01-01 01:00:00.000000000 +0100
| |
| - | +++ /usr/src/linux-2.6.35.4/drivers/media/common/tuners/tda18218.h 2011-01-04 14:03:39.306000007 +0100
| |
| - | @@ -0,0 +1,44 @@
| |
| - | +/*
| |
| - | + * Driver for NXP TDA18218 silicon tuner
| |
| - | + *
| |
| - | + * Copyright (C) 2010 Lauris Ding <ld...@gmx.de>
| |
| - | + *
| |
| - | + * 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 TDA18218_H
| |
| - | +#define TDA18218_H
| |
| - | +
| |
| - | +#include "dvb_frontend.h"
| |
| - | +
| |
| - | +struct tda18218_config {
| |
| - | + u8 i2c_address;
| |
| - | +};
| |
| - | +
| |
| - | +#if defined(CONFIG_MEDIA_TUNER_TDA18218) || (defined(CONFIG_MEDIA_TUNER_TDA18218_MODULE) && defined(MODULE))
| |
| - | +extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
| |
| - | + struct i2c_adapter *i2c,
| |
| - | + struct tda18218_config *cfg);
| |
| - | +#else
| |
| - | +static inline struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
| |
| - | + struct i2c_adapter *i2c,
| |
| - | + struct tda18218_config *cfg)
| |
| - | +{
| |
| - | + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
| |
| - | + return NULL;
| |
| - | +}
| |
| - | +#endif // CONFIG_MEDIA_TUNER_TDA18218
| |
| - | +
| |
| - | +#endif
| |
| - | diff -Nru linux-2.6.35.4/drivers/media/common/tuners/tda18218_priv.h /usr/src/linux-2.6.35.4/drivers/media/common/tuners/tda18218_priv.h
| |
| - | --- linux-2.6.35.4/drivers/media/common/tuners/tda18218_priv.h 1970-01-01 01:00:00.000000000 +0100
| |
| - | +++ /usr/src/linux-2.6.35.4/drivers/media/common/tuners/tda18218_priv.h 2011-01-04 14:04:36.744000011 +0100
| |
| - | @@ -0,0 +1,36 @@
| |
| - | +/*
| |
| - | + * Driver for NXP TDA18218 silicon tuner
| |
| - | + *
| |
| - | + * Copyright (C) 2010 Lauris Ding <ld...@gmx.de>
| |
| - | + * 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 TDA18218_PRIV_H
| |
| - | +#define TDA18218_PRIV_H
| |
| - | +
| |
| - | +#define TDA18218_STEP 1000 /* 1 kHz */
| |
| - | +#define TDA18218_MIN_FREQ 174000000 /* 174 MHz */
| |
| - | +#define TDA18218_MAX_FREQ 864000000 /* 864 MHz */
| |
| - | +
| |
| - | +struct tda18218_priv {
| |
| - | + u8 tda18218_regs[0x3b];
| |
| - | + struct tda18218_config *cfg;
| |
| - | + struct i2c_adapter *i2c;
| |
| - | +
| |
| - | + u32 frequency;
| |
| - | + u32 bandwidth;
| |
| - | +};
| |
| - | +
| |
| - | +#endif
| |
| - | diff -Nru linux-2.6.35.4/drivers/media/dvb/dvb-usb/af9015.c /usr/src/linux-2.6.35.4/drivers/media/dvb/dvb-usb/af9015.c
| |
| - | --- linux-2.6.35.4/drivers/media/dvb/dvb-usb/af9015.c 2010-08-27 01:47:12.000000000 +0200
| |
| - | +++ /usr/src/linux-2.6.35.4/drivers/media/dvb/dvb-usb/af9015.c 2011-01-05 10:21:43.993000001 +0100
| |
| - | @@ -31,6 +31,7 @@
| |
| - | #include "tda18271.h"
| |
| - | #include "mxl5005s.h"
| |
| - | #include "mc44s803.h"
| |
| - | +#include "tda18218.h"
| |
| - |
| |
| - | static int dvb_usb_af9015_debug;
| |
| - | module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
| |
| - | @@ -272,7 +273,8 @@
| |
| - |
| |
| - | while (i < num) {
| |
| - | if (msg[i].addr == af9015_af9013_config[0].demod_address ||
| |
| - | - msg[i].addr == af9015_af9013_config[1].demod_address) {
| |
| - | + msg[i].addr == af9015_af9013_config[1].demod_address ||
| |
| - | + msg[i].addr == 0x3a) {
| |
| - | addr = msg[i].buf[0] << 8;
| |
| - | addr += msg[i].buf[1];
| |
| - | mbox = msg[i].buf[2];
| |
| - | @@ -285,7 +287,8 @@
| |
| - |
| |
| - | if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
| |
| - | if (msg[i].addr ==
| |
| - | - af9015_af9013_config[0].demod_address)
| |
| - | + af9015_af9013_config[0].demod_address ||
| |
| - | + msg[i].addr == 0x3a)
| |
| - | req.cmd = READ_MEMORY;
| |
| - | else
| |
| - | req.cmd = READ_I2C;
| |
| - | @@ -300,7 +303,8 @@
| |
| - | } else if (msg[i].flags & I2C_M_RD) {
| |
| - | ret = -EINVAL;
| |
| - | if (msg[i].addr ==
| |
| - | - af9015_af9013_config[0].demod_address)
| |
| - | + af9015_af9013_config[0].demod_address ||
| |
| - | + msg[i].addr == 0x3a)
| |
| - | goto error;
| |
| - | else
| |
| - | req.cmd = READ_I2C;
| |
| - | @@ -314,7 +318,8 @@
| |
| - | i += 1;
| |
| - | } else {
| |
| - | if (msg[i].addr ==
| |
| - | - af9015_af9013_config[0].demod_address)
| |
| - | + af9015_af9013_config[0].demod_address ||
| |
| - | + msg[i].addr == 0x3a)
| |
| - | req.cmd = WRITE_MEMORY;
| |
| - | else
| |
| - | req.cmd = WRITE_I2C;
| |
| - | @@ -556,46 +561,6 @@
| |
| - | return ret;
| |
| - | }
| |
| - |
| |
| - | -/* hash (and dump) eeprom */
| |
| - | -static int af9015_eeprom_hash(struct usb_device *udev)
| |
| - | -{
| |
| - | - static const unsigned int eeprom_size = 256;
| |
| - | - unsigned int reg;
| |
| - | - int ret;
| |
| - | - u8 val, *eeprom;
| |
| - | - struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
| |
| - | -
| |
| - | - eeprom = kmalloc(eeprom_size, GFP_KERNEL);
| |
| - | - if (eeprom == NULL)
| |
| - | - return -ENOMEM;
| |
| - | -
| |
| - | - for (reg = 0; reg < eeprom_size; reg++) {
| |
| - | - req.addr = reg;
| |
| - | - ret = af9015_rw_udev(udev, &req);
| |
| - | - if (ret)
| |
| - | - goto free;
| |
| - | - eeprom[reg] = val;
| |
| - | - }
| |
| - | -
| |
| - | - if (dvb_usb_af9015_debug & 0x01)
| |
| - | - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
| |
| - | - eeprom_size);
| |
| - | -
| |
| - | - BUG_ON(eeprom_size % 4);
| |
| - | -
| |
| - | - af9015_config.eeprom_sum = 0;
| |
| - | - for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
| |
| - | - af9015_config.eeprom_sum *= GOLDEN_RATIO_PRIME_32;
| |
| - | - af9015_config.eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
| |
| - | - }
| |
| - | -
| |
| - | - deb_info("%s: eeprom sum=%.8x\n", __func__, af9015_config.eeprom_sum);
| |
| - | -
| |
| - | - ret = 0;
| |
| - | -free:
| |
| - | - kfree(eeprom);
| |
| - | - return ret;
| |
| - | -}
| |
| - |
| |
| - | static int af9015_download_ir_table(struct dvb_usb_device *d)
| |
| - | {
| |
| - | @@ -733,132 +698,12 @@
| |
| - | return ret;
| |
| - | }
| |
| - |
| |
| - | -struct af9015_setup {
| |
| - | - unsigned int id;
| |
| - | - struct dvb_usb_rc_key *rc_key_map;
| |
| - | - unsigned int rc_key_map_size;
| |
| - | - u8 *ir_table;
| |
| - | - unsigned int ir_table_size;
| |
| - | -};
| |
| - | -
| |
| - | -static const struct af9015_setup *af9015_setup_match(unsigned int id,
| |
| - | - const struct af9015_setup *table)
| |
| - | -{
| |
| - | - for (; table->rc_key_map; table++)
| |
| - | - if (table->id == id)
| |
| - | - return table;
| |
| - | - 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) },
| |
| - | - { }
| |
| - | -};
| |
| - | -
| |
| - | -/* 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_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 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);
| |
| - | - }
| |
| - | -
| |
| - | - if (table) {
| |
| - | - props->rc_key_map = table->rc_key_map;
| |
| - | - props->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;
| |
| - | - }
| |
| - | -}
| |
| - | -
| |
| - | static int af9015_read_config(struct usb_device *udev)
| |
| - | {
| |
| - | int ret;
| |
| - | u8 val, i, offset = 0;
| |
| - | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
| |
| - | + char manufacturer[10];
| |
| - |
| |
| - | /* IR remote controller */
| |
| - | req.addr = AF9015_EEPROM_IR_MODE;
| |
| - | @@ -871,17 +716,158 @@
| |
| - | if (ret)
| |
| - | goto error;
| |
| - |
| |
| - | - ret = af9015_eeprom_hash(udev);
| |
| - | - if (ret)
| |
| - | - goto error;
| |
| - | -
| |
| - | 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_key_map = NULL;
| |
| - | af9015_properties[i].rc_key_map_size = 0;
| |
| - | - } else
| |
| - | - af9015_set_remote_config(udev, &af9015_properties[i]);
| |
| - | + } else if (dvb_usb_af9015_remote) {
| |
| - | + /* load remote defined as module param */
| |
| - | + switch (dvb_usb_af9015_remote) {
| |
| - | + case AF9015_REMOTE_A_LINK_DTU_M:
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_a_link;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_a_link);
| |
| - | + af9015_config.ir_table = af9015_ir_table_a_link;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_a_link);
| |
| - | + break;
| |
| - | + case AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3:
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_msi;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_msi);
| |
| - | + af9015_config.ir_table = af9015_ir_table_msi;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_msi);
| |
| - | + break;
| |
| - | + case AF9015_REMOTE_MYGICTV_U718:
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_mygictv;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_mygictv);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_mygictv;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_mygictv);
| |
| - | + break;
| |
| - | + case AF9015_REMOTE_DIGITTRADE_DVB_T:
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_digittrade;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_digittrade);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_digittrade;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_digittrade);
| |
| - | + break;
| |
| - | + case AF9015_REMOTE_AVERMEDIA_KS:
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_avermedia;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_avermedia);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_avermedia_ks;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_avermedia_ks);
| |
| - | + break;
| |
| - | + }
| |
| - | + } else {
| |
| - | + switch (le16_to_cpu(udev->descriptor.idVendor)) {
| |
| - | + case USB_VID_LEADTEK:
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_leadtek;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_leadtek);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_leadtek;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_leadtek);
| |
| - | + break;
| |
| - | + case USB_VID_VISIONPLUS:
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_twinhan;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_twinhan);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_twinhan;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_twinhan);
| |
| - | + break;
| |
| - | + case USB_VID_KWORLD_2:
| |
| - | + /* TODO: use correct rc keys */
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_twinhan;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_twinhan);
| |
| - | + af9015_config.ir_table = af9015_ir_table_kworld;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_kworld);
| |
| - | + break;
| |
| - | + /* Check USB manufacturer and product strings and try
| |
| - | + to determine correct remote in case of chip vendor
| |
| - | + reference IDs are used. */
| |
| - | + case USB_VID_AFATECH:
| |
| - | + memset(manufacturer, 0, sizeof(manufacturer));
| |
| - | + usb_string(udev, udev->descriptor.iManufacturer,
| |
| - | + manufacturer, sizeof(manufacturer));
| |
| - | + if (!strcmp("Geniatech", manufacturer)) {
| |
| - | + /* iManufacturer 1 Geniatech
| |
| - | + iProduct 2 AF9015 */
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_mygictv;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_mygictv);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_mygictv;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_mygictv);
| |
| - | + } else if (!strcmp("MSI", manufacturer)) {
| |
| - | + /* iManufacturer 1 MSI
| |
| - | + iProduct 2 MSI K-VOX */
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_msi;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_msi);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_msi;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_msi);
| |
| - | + } else if (udev->descriptor.idProduct ==
| |
| - | + cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_trekstor;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_trekstor);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_trekstor;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_trekstor);
| |
| - | + }
| |
| - | + break;
| |
| - | + case USB_VID_AVERMEDIA:
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_avermedia;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_avermedia);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_avermedia;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_avermedia);
| |
| - | + break;
| |
| - | + case USB_VID_MSI_2:
| |
| - | + af9015_properties[i].rc_key_map =
| |
| - | + ir_codes_af9015_table_msi_digivox_iii;
| |
| - | + af9015_properties[i].rc_key_map_size =
| |
| - | + ARRAY_SIZE(ir_codes_af9015_table_msi_digivox_iii);
| |
| - | + af9015_config.ir_table =
| |
| - | + af9015_ir_table_msi_digivox_iii;
| |
| - | + af9015_config.ir_table_size =
| |
| - | + ARRAY_SIZE(af9015_ir_table_msi_digivox_iii);
| |
| - | + break;
| |
| - | + }
| |
| - | + }
| |
| - | }
| |
| - |
| |
| - | /* TS mode - one or two receivers */
| |
| - | @@ -992,6 +978,7 @@
| |
| - | 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:
| |
| - | @@ -1003,9 +990,6 @@
| |
| - | 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;
| |
| - | @@ -1208,6 +1192,10 @@
| |
| - | .dig_out = 1,
| |
| - | };
| |
| - |
| |
| - | +static struct tda18218_config af9015_tda18218_config = {
| |
| - | + .i2c_address = 0xc0,
| |
| - | +};
| |
| - | +
| |
| - | static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
| |
| - | {
| |
| - | struct af9015_state *state = adap->dev->priv;
| |
| - | @@ -1255,6 +1243,10 @@
| |
| - | ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
| |
| - | &af9015_mc44s803_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_UNKNOWN:
| |
| - | default:
| |
| - | ret = -ENODEV;
| |
| - | @@ -1299,6 +1291,7 @@
| |
| - | {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
| |
| - | /* 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_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
| |
| - | {0},
| |
| - | };
| |
| - | MODULE_DEVICE_TABLE(usb, af9015_usb_table);
| |
| - | @@ -1607,8 +1600,8 @@
| |
| - | .warm_ids = {NULL},
| |
| - | },
| |
| - | {
| |
| - | - .name = "Leadtek WinFast DTV2000DS",
| |
| - | - .cold_ids = {&af9015_usb_table[29], NULL},
| |
| - | + .name = "TerraTec Cinergy T Stick RC",
| |
| - | + .cold_ids = {&af9015_usb_table[32], NULL},
| |
| - | .warm_ids = {NULL},
| |
| - | },
| |
| - | {
| |
| - | diff -Nru linux-2.6.35.4/drivers/media/dvb/dvb-usb/dvb-usb-ids.h /usr/src/linux-2.6.35.4/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
| |
| - | --- linux-2.6.35.4/drivers/media/dvb/dvb-usb/dvb-usb-ids.h 2010-08-27 01:47:12.000000000 +0200
| |
| - | +++ /usr/src/linux-2.6.35.4/drivers/media/dvb/dvb-usb/dvb-usb-ids.h 2011-01-04 14:45:53.600000024 +0100
| |
| - | @@ -133,6 +133,7 @@
| |
| - | #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_TWINHAN_VP7041_COLD 0x3201
| |
| - | #define USB_PID_TWINHAN_VP7041_WARM 0x3202
| |
| - | #define USB_PID_TWINHAN_VP7020_COLD 0x3203
| |
| - | diff -Nru linux-2.6.35.4/drivers/media/dvb/frontends/af9013.c /usr/src/linux-2.6.35.4/drivers/media/dvb/frontends/af9013.c
| |
| - | --- linux-2.6.35.4/drivers/media/dvb/frontends/af9013.c 2010-08-27 01:47:12.000000000 +0200
| |
| - | +++ /usr/src/linux-2.6.35.4/drivers/media/dvb/frontends/af9013.c 2011-01-04 14:48:59.535000023 +0100
| |
| - | @@ -487,6 +487,20 @@
| |
| - | 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))
| |
| - | if_sample_freq = if_sample_freq - adc_freq;
| |
| - | @@ -1389,6 +1403,7 @@
| |
| - | 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;
| |
| - | diff -Nru linux-2.6.35.4/drivers/media/dvb/frontends/af9013_priv.h /usr/src/linux-2.6.35.4/drivers/media/dvb/frontends/af9013_priv.h
| |
| - | --- linux-2.6.35.4/drivers/media/dvb/frontends/af9013_priv.h 2010-08-27 01:47:12.000000000 +0200
| |
| - | +++ /usr/src/linux-2.6.35.4/drivers/media/dvb/frontends/af9013_priv.h 2011-01-04 14:52:02.621000024 +0100
| |
| - | @@ -789,8 +789,9 @@
| |
| - | { 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 },
| |
| | </pre> | | </pre> |
| | | | |
| | [[Category: DVB-T USB Devices]] | | [[Category: DVB-T USB Devices]] |
Uses tuner NXP TDA18218 and AF9015A. Use Kernel-2.6.37 or v4l-dvb git.