mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-30 06:06:43 +00:00
linux: add Anysee E7 T2C support (untested)
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
aa5d4d08b8
commit
6672054200
@ -0,0 +1,852 @@
|
||||
diff -Naur linux-3.2.1/drivers/media/common/tuners/tda18212.c linux-3.2.1.patch/drivers/media/common/tuners/tda18212.c
|
||||
--- linux-3.2.1/drivers/media/common/tuners/tda18212.c 2012-01-12 20:42:45.000000000 +0100
|
||||
+++ linux-3.2.1.patch/drivers/media/common/tuners/tda18212.c 2012-01-22 14:32:12.474382952 +0100
|
||||
@@ -25,6 +25,8 @@
|
||||
struct tda18212_priv {
|
||||
struct tda18212_config *cfg;
|
||||
struct i2c_adapter *i2c;
|
||||
+
|
||||
+ u32 if_frequency;
|
||||
};
|
||||
|
||||
#define dbg(fmt, arg...) \
|
||||
@@ -136,12 +138,24 @@
|
||||
int ret, i;
|
||||
u32 if_khz;
|
||||
u8 buf[9];
|
||||
+ #define DVBT_6 0
|
||||
+ #define DVBT_7 1
|
||||
+ #define DVBT_8 2
|
||||
+ #define DVBT2_6 3
|
||||
+ #define DVBT2_7 4
|
||||
+ #define DVBT2_8 5
|
||||
+ #define DVBC_6 6
|
||||
+ #define DVBC_8 7
|
||||
static const u8 bw_params[][3] = {
|
||||
- /* 0f 13 23 */
|
||||
- { 0xb3, 0x20, 0x03 }, /* DVB-T 6 MHz */
|
||||
- { 0xb3, 0x31, 0x01 }, /* DVB-T 7 MHz */
|
||||
- { 0xb3, 0x22, 0x01 }, /* DVB-T 8 MHz */
|
||||
- { 0x92, 0x53, 0x03 }, /* DVB-C */
|
||||
+ /* reg: 0f 13 23 */
|
||||
+ [DVBT_6] = { 0xb3, 0x20, 0x03 },
|
||||
+ [DVBT_7] = { 0xb3, 0x31, 0x01 },
|
||||
+ [DVBT_8] = { 0xb3, 0x22, 0x01 },
|
||||
+ [DVBT2_6] = { 0xbc, 0x20, 0x03 },
|
||||
+ [DVBT2_7] = { 0xbc, 0x72, 0x03 },
|
||||
+ [DVBT2_8] = { 0xbc, 0x22, 0x01 },
|
||||
+ [DVBC_6] = { 0x92, 0x50, 0x03 },
|
||||
+ [DVBC_8] = { 0x92, 0x53, 0x03 },
|
||||
};
|
||||
|
||||
dbg("delsys=%d RF=%d BW=%d\n",
|
||||
@@ -155,15 +169,34 @@
|
||||
switch (c->bandwidth_hz) {
|
||||
case 6000000:
|
||||
if_khz = priv->cfg->if_dvbt_6;
|
||||
- i = 0;
|
||||
+ i = DVBT_6;
|
||||
break;
|
||||
case 7000000:
|
||||
if_khz = priv->cfg->if_dvbt_7;
|
||||
- i = 1;
|
||||
+ i = DVBT_7;
|
||||
break;
|
||||
case 8000000:
|
||||
if_khz = priv->cfg->if_dvbt_8;
|
||||
- i = 2;
|
||||
+ i = DVBT_8;
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ break;
|
||||
+ case SYS_DVBT2:
|
||||
+ switch (c->bandwidth_hz) {
|
||||
+ case 6000000:
|
||||
+ if_khz = priv->cfg->if_dvbt2_6;
|
||||
+ i = DVBT2_6;
|
||||
+ break;
|
||||
+ case 7000000:
|
||||
+ if_khz = priv->cfg->if_dvbt2_7;
|
||||
+ i = DVBT2_7;
|
||||
+ break;
|
||||
+ case 8000000:
|
||||
+ if_khz = priv->cfg->if_dvbt2_8;
|
||||
+ i = DVBT2_8;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
@@ -172,7 +205,7 @@
|
||||
break;
|
||||
case SYS_DVBC_ANNEX_AC:
|
||||
if_khz = priv->cfg->if_dvbc;
|
||||
- i = 3;
|
||||
+ i = DVBC_8;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
@@ -194,7 +227,7 @@
|
||||
buf[0] = 0x02;
|
||||
buf[1] = bw_params[i][1];
|
||||
buf[2] = 0x03; /* default value */
|
||||
- buf[3] = if_khz / 50;
|
||||
+ buf[3] = DIV_ROUND_CLOSEST(if_khz, 50);
|
||||
buf[4] = ((c->frequency / 1000) >> 16) & 0xff;
|
||||
buf[5] = ((c->frequency / 1000) >> 8) & 0xff;
|
||||
buf[6] = ((c->frequency / 1000) >> 0) & 0xff;
|
||||
@@ -204,6 +237,9 @@
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
+ /* actual IF rounded as it is on register */
|
||||
+ priv->if_frequency = buf[3] * 50 * 1000;
|
||||
+
|
||||
exit:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
@@ -215,6 +251,15 @@
|
||||
goto exit;
|
||||
}
|
||||
|
||||
+static int tda18212_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
+{
|
||||
+ struct tda18212_priv *priv = fe->tuner_priv;
|
||||
+
|
||||
+ *frequency = priv->if_frequency;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int tda18212_release(struct dvb_frontend *fe)
|
||||
{
|
||||
kfree(fe->tuner_priv);
|
||||
@@ -234,6 +279,7 @@
|
||||
.release = tda18212_release,
|
||||
|
||||
.set_params = tda18212_set_params,
|
||||
+ .get_if_frequency = tda18212_get_if_frequency,
|
||||
};
|
||||
|
||||
struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
|
||||
diff -Naur linux-3.2.1/drivers/media/common/tuners/tda18212.h linux-3.2.1.patch/drivers/media/common/tuners/tda18212.h
|
||||
--- linux-3.2.1/drivers/media/common/tuners/tda18212.h 2012-01-12 20:42:45.000000000 +0100
|
||||
+++ linux-3.2.1.patch/drivers/media/common/tuners/tda18212.h 2012-01-22 14:32:05.694265792 +0100
|
||||
@@ -29,6 +29,10 @@
|
||||
u16 if_dvbt_6;
|
||||
u16 if_dvbt_7;
|
||||
u16 if_dvbt_8;
|
||||
+ u16 if_dvbt2_5;
|
||||
+ u16 if_dvbt2_6;
|
||||
+ u16 if_dvbt2_7;
|
||||
+ u16 if_dvbt2_8;
|
||||
u16 if_dvbc;
|
||||
};
|
||||
|
||||
diff -Naur linux-3.2.1/drivers/media/dvb/dvb-usb/anysee.c linux-3.2.1.patch/drivers/media/dvb/dvb-usb/anysee.c
|
||||
--- linux-3.2.1/drivers/media/dvb/dvb-usb/anysee.c 2012-01-12 20:42:45.000000000 +0100
|
||||
+++ linux-3.2.1.patch/drivers/media/dvb/dvb-usb/anysee.c 2012-01-22 14:14:31.806583440 +0100
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "stv0900.h"
|
||||
#include "stv6110.h"
|
||||
#include "isl6423.h"
|
||||
+#include "cxd2820r.h"
|
||||
|
||||
/* debug */
|
||||
static int dvb_usb_anysee_debug;
|
||||
@@ -66,10 +67,12 @@
|
||||
if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
+ deb_xfer(">>> ");
|
||||
+ debug_dump(buf, slen, deb_xfer);
|
||||
+
|
||||
/* We need receive one message more after dvb_usb_generic_rw due
|
||||
to weird transaction flow, which is 1 x send + 2 x receive. */
|
||||
ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
|
||||
-
|
||||
if (!ret) {
|
||||
/* receive 2nd answer */
|
||||
ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
|
||||
@@ -79,7 +82,10 @@
|
||||
err("%s: recv bulk message failed: %d", __func__, ret);
|
||||
else {
|
||||
deb_xfer("<<< ");
|
||||
- debug_dump(buf, act_len, deb_xfer);
|
||||
+ debug_dump(buf, rlen, deb_xfer);
|
||||
+
|
||||
+ if (buf[63] != 0x4f)
|
||||
+ deb_info("%s: cmd failed\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +135,29 @@
|
||||
return anysee_write_reg(d, reg, val);
|
||||
}
|
||||
|
||||
+/* read single register with mask */
|
||||
+static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
|
||||
+ u8 mask)
|
||||
+{
|
||||
+ int ret, i;
|
||||
+ u8 tmp;
|
||||
+
|
||||
+ ret = anysee_read_reg(d, reg, &tmp);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ tmp &= mask;
|
||||
+
|
||||
+ /* find position of the first bit */
|
||||
+ for (i = 0; i < 8; i++) {
|
||||
+ if ((mask >> i) & 0x01)
|
||||
+ break;
|
||||
+ }
|
||||
+ *val = tmp >> i;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
|
||||
{
|
||||
u8 buf[] = {CMD_GET_HW_INFO};
|
||||
@@ -156,22 +185,6 @@
|
||||
return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
|
||||
}
|
||||
|
||||
-static int anysee_init(struct dvb_usb_device *d)
|
||||
-{
|
||||
- int ret;
|
||||
- /* LED light */
|
||||
- ret = anysee_led_ctrl(d, 0x01, 0x03);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- /* enable IR */
|
||||
- ret = anysee_ir_ctrl(d, 1);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
/* I2C */
|
||||
static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
|
||||
int num)
|
||||
@@ -297,7 +310,7 @@
|
||||
.pll_m = 12,
|
||||
.pll_p = 3,
|
||||
.pll_n = 1,
|
||||
- .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
|
||||
+ .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
|
||||
.deltaf = 0xba02,
|
||||
};
|
||||
|
||||
@@ -309,6 +322,17 @@
|
||||
.if_dvbc = 5000,
|
||||
};
|
||||
|
||||
+static struct tda18212_config anysee_tda18212_config2 = {
|
||||
+ .i2c_address = 0x60 /* (0xc0 >> 1) */,
|
||||
+ .if_dvbt_6 = 3550,
|
||||
+ .if_dvbt_7 = 3700,
|
||||
+ .if_dvbt_8 = 4150,
|
||||
+ .if_dvbt2_6 = 3250,
|
||||
+ .if_dvbt2_7 = 4000,
|
||||
+ .if_dvbt2_8 = 4000,
|
||||
+ .if_dvbc = 5000,
|
||||
+};
|
||||
+
|
||||
static struct cx24116_config anysee_cx24116_config = {
|
||||
.demod_address = (0xaa >> 1),
|
||||
.mpg_clk_pos_pol = 0x00,
|
||||
@@ -339,6 +363,18 @@
|
||||
.addr = (0x10 >> 1),
|
||||
};
|
||||
|
||||
+static struct cxd2820r_config anysee_cxd2820r_config = {
|
||||
+ .i2c_address = 0x6d, /* (0xda >> 1) */
|
||||
+ .ts_mode = 0x38,
|
||||
+ .if_dvbt_6 = 3550,
|
||||
+ .if_dvbt_7 = 3700,
|
||||
+ .if_dvbt_8 = 4150,
|
||||
+ .if_dvbt2_6 = 3250,
|
||||
+ .if_dvbt2_7 = 4000,
|
||||
+ .if_dvbt2_8 = 4000,
|
||||
+ .if_dvbc = 5000,
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* New USB device strings: Mfr=1, Product=2, SerialNumber=0
|
||||
* Manufacturer: AMT.CO.KR
|
||||
@@ -421,6 +457,14 @@
|
||||
* IOA[7] TS 1=enabled
|
||||
* IOE[5] STV0903 1=enabled
|
||||
*
|
||||
+ * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
|
||||
+ * PCB: 508T2C (rev0.3)
|
||||
+ * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
|
||||
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
|
||||
+ * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
|
||||
+ * IOA[7] TS 1=enabled
|
||||
+ * IOE[5] CXD2820R 1=enabled
|
||||
+ *
|
||||
* E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
|
||||
* PCB: 508PTC (rev0.5)
|
||||
* parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
|
||||
@@ -437,7 +481,7 @@
|
||||
* IOD[6] ZL10353 1=enabled
|
||||
* IOE[0] IF 0=enabled
|
||||
*
|
||||
- * E7 S2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
|
||||
+ * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
|
||||
* PCB: 508PS2 (rev0.4)
|
||||
* parts: DNBU10512IST(STV0903, STV6110), ISL6423
|
||||
* OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
|
||||
@@ -446,6 +490,16 @@
|
||||
* IOE[5] STV0903 1=enabled
|
||||
*/
|
||||
|
||||
+
|
||||
+/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
|
||||
+static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||
+{
|
||||
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
|
||||
+
|
||||
+ /* enable / disable tuner access on IOE[4] */
|
||||
+ return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10);
|
||||
+}
|
||||
+
|
||||
static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
|
||||
{
|
||||
struct dvb_usb_adapter *adap = fe->dvb->priv;
|
||||
@@ -577,7 +631,8 @@
|
||||
/* detect hardware only once */
|
||||
if (adap->fe_adap[0].fe == NULL) {
|
||||
/* Check which hardware we have.
|
||||
- * We must do this call two times to get reliable values (hw bug).
|
||||
+ * We must do this call two times to get reliable values
|
||||
+ * (hw/fw bug).
|
||||
*/
|
||||
ret = anysee_get_hw_info(adap->dev, hw_info);
|
||||
if (ret)
|
||||
@@ -606,14 +661,14 @@
|
||||
break;
|
||||
|
||||
/* attach demod */
|
||||
- adap->fe_adap[0].fe = dvb_attach(mt352_attach, &anysee_mt352_config,
|
||||
- &adap->dev->i2c_adap);
|
||||
+ adap->fe_adap[0].fe = dvb_attach(mt352_attach,
|
||||
+ &anysee_mt352_config, &adap->dev->i2c_adap);
|
||||
if (adap->fe_adap[0].fe)
|
||||
break;
|
||||
|
||||
/* attach demod */
|
||||
- adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
|
||||
- &adap->dev->i2c_adap);
|
||||
+ adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
|
||||
+ &anysee_zl10353_config, &adap->dev->i2c_adap);
|
||||
|
||||
break;
|
||||
case ANYSEE_HW_507CD: /* 6 */
|
||||
@@ -665,8 +720,8 @@
|
||||
goto error;
|
||||
|
||||
/* attach demod */
|
||||
- adap->fe_adap[0].fe = dvb_attach(cx24116_attach, &anysee_cx24116_config,
|
||||
- &adap->dev->i2c_adap);
|
||||
+ adap->fe_adap[0].fe = dvb_attach(cx24116_attach,
|
||||
+ &anysee_cx24116_config, &adap->dev->i2c_adap);
|
||||
|
||||
break;
|
||||
case ANYSEE_HW_507FA: /* 15 */
|
||||
@@ -747,17 +802,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
|
||||
+ if (tmp == 0xc7) {
|
||||
+ if (adap->fe_adap[state->fe_id].fe)
|
||||
+ adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
|
||||
+ anysee_i2c_gate_ctrl;
|
||||
+ }
|
||||
+
|
||||
break;
|
||||
case ANYSEE_HW_508TC: /* 18 */
|
||||
case ANYSEE_HW_508PTC: /* 21 */
|
||||
/* E7 TC */
|
||||
/* E7 PTC */
|
||||
|
||||
- /* enable transport stream on IOA[7] */
|
||||
- ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
|
||||
- if (ret)
|
||||
- goto error;
|
||||
-
|
||||
if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
|
||||
/* disable DVB-T demod on IOD[6] */
|
||||
ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
|
||||
@@ -772,7 +829,8 @@
|
||||
goto error;
|
||||
|
||||
/* attach demod */
|
||||
- adap->fe_adap[state->fe_id].fe = dvb_attach(tda10023_attach,
|
||||
+ adap->fe_adap[state->fe_id].fe =
|
||||
+ dvb_attach(tda10023_attach,
|
||||
&anysee_tda10023_tda18212_config,
|
||||
&adap->dev->i2c_adap, 0x48);
|
||||
} else {
|
||||
@@ -789,11 +847,19 @@
|
||||
goto error;
|
||||
|
||||
/* attach demod */
|
||||
- adap->fe_adap[state->fe_id].fe = dvb_attach(zl10353_attach,
|
||||
+ adap->fe_adap[state->fe_id].fe =
|
||||
+ dvb_attach(zl10353_attach,
|
||||
&anysee_zl10353_tda18212_config,
|
||||
&adap->dev->i2c_adap);
|
||||
}
|
||||
|
||||
+ /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
|
||||
+ if (adap->fe_adap[state->fe_id].fe)
|
||||
+ adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
|
||||
+ anysee_i2c_gate_ctrl;
|
||||
+
|
||||
+ state->has_ci = true;
|
||||
+
|
||||
break;
|
||||
case ANYSEE_HW_508S2: /* 19 */
|
||||
case ANYSEE_HW_508PS2: /* 22 */
|
||||
@@ -803,19 +869,41 @@
|
||||
if (state->fe_id)
|
||||
break;
|
||||
|
||||
- /* enable transport stream on IOA[7] */
|
||||
- ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
|
||||
+ /* enable DVB-S/S2 demod on IOE[5] */
|
||||
+ ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
- /* enable DVB-S/S2 demod on IOE[5] */
|
||||
+ /* attach demod */
|
||||
+ adap->fe_adap[0].fe = dvb_attach(stv0900_attach,
|
||||
+ &anysee_stv0900_config, &adap->dev->i2c_adap, 0);
|
||||
+
|
||||
+ state->has_ci = true;
|
||||
+
|
||||
+ break;
|
||||
+ case ANYSEE_HW_508T2C: /* 20 */
|
||||
+ /* E7 T2C */
|
||||
+
|
||||
+ /* enable DVB-T/T2/C demod on IOE[5] */
|
||||
ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
- /* attach demod */
|
||||
- adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config,
|
||||
- &adap->dev->i2c_adap, 0);
|
||||
+ if (state->fe_id == 0) {
|
||||
+ /* DVB-T/T2 */
|
||||
+ adap->fe_adap[state->fe_id].fe =
|
||||
+ dvb_attach(cxd2820r_attach,
|
||||
+ &anysee_cxd2820r_config,
|
||||
+ &adap->dev->i2c_adap, NULL);
|
||||
+ } else {
|
||||
+ /* DVB-C */
|
||||
+ adap->fe_adap[state->fe_id].fe =
|
||||
+ dvb_attach(cxd2820r_attach,
|
||||
+ &anysee_cxd2820r_config,
|
||||
+ &adap->dev->i2c_adap, adap->fe_adap[0].fe);
|
||||
+ }
|
||||
+
|
||||
+ state->has_ci = true;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -842,24 +930,26 @@
|
||||
/* E30 */
|
||||
|
||||
/* attach tuner */
|
||||
- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1),
|
||||
- NULL, DVB_PLL_THOMSON_DTT7579);
|
||||
+ fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
|
||||
+ (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579);
|
||||
|
||||
break;
|
||||
case ANYSEE_HW_507CD: /* 6 */
|
||||
/* E30 Plus */
|
||||
|
||||
/* attach tuner */
|
||||
- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1),
|
||||
- &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579);
|
||||
+ fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
|
||||
+ (0xc2 >> 1), &adap->dev->i2c_adap,
|
||||
+ DVB_PLL_THOMSON_DTT7579);
|
||||
|
||||
break;
|
||||
case ANYSEE_HW_507DC: /* 10 */
|
||||
/* E30 C Plus */
|
||||
|
||||
/* attach tuner */
|
||||
- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc0 >> 1),
|
||||
- &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
|
||||
+ fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
|
||||
+ (0xc0 >> 1), &adap->dev->i2c_adap,
|
||||
+ DVB_PLL_SAMSUNG_DTOS403IH102A);
|
||||
|
||||
break;
|
||||
case ANYSEE_HW_507SI: /* 11 */
|
||||
@@ -877,22 +967,12 @@
|
||||
/* Try first attach TDA18212 silicon tuner on IOE[4], if that
|
||||
* fails attach old simple PLL. */
|
||||
|
||||
- /* enable tuner on IOE[4] */
|
||||
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
|
||||
- if (ret)
|
||||
- goto error;
|
||||
-
|
||||
/* attach tuner */
|
||||
fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
|
||||
&adap->dev->i2c_adap, &anysee_tda18212_config);
|
||||
if (fe)
|
||||
break;
|
||||
|
||||
- /* disable tuner on IOE[4] */
|
||||
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
|
||||
- if (ret)
|
||||
- goto error;
|
||||
-
|
||||
/* attach tuner */
|
||||
fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe,
|
||||
(0xc0 >> 1), &adap->dev->i2c_adap,
|
||||
@@ -904,11 +984,6 @@
|
||||
/* E7 TC */
|
||||
/* E7 PTC */
|
||||
|
||||
- /* enable tuner on IOE[4] */
|
||||
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
|
||||
- if (ret)
|
||||
- goto error;
|
||||
-
|
||||
/* attach tuner */
|
||||
fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
|
||||
&adap->dev->i2c_adap, &anysee_tda18212_config);
|
||||
@@ -930,6 +1005,15 @@
|
||||
}
|
||||
|
||||
break;
|
||||
+
|
||||
+ case ANYSEE_HW_508T2C: /* 20 */
|
||||
+ /* E7 T2C */
|
||||
+
|
||||
+ /* attach tuner */
|
||||
+ fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
|
||||
+ &adap->dev->i2c_adap, &anysee_tda18212_config2);
|
||||
+
|
||||
+ break;
|
||||
default:
|
||||
fe = NULL;
|
||||
}
|
||||
@@ -939,7 +1023,6 @@
|
||||
else
|
||||
ret = -ENODEV;
|
||||
|
||||
-error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -969,6 +1052,201 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
|
||||
+ int addr)
|
||||
+{
|
||||
+ struct dvb_usb_device *d = ci->data;
|
||||
+ int ret;
|
||||
+ u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
|
||||
+ u8 val;
|
||||
+
|
||||
+ ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
|
||||
+ int addr, u8 val)
|
||||
+{
|
||||
+ struct dvb_usb_device *d = ci->data;
|
||||
+ int ret;
|
||||
+ u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
|
||||
+
|
||||
+ ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
|
||||
+ u8 addr)
|
||||
+{
|
||||
+ struct dvb_usb_device *d = ci->data;
|
||||
+ int ret;
|
||||
+ u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
|
||||
+ u8 val;
|
||||
+
|
||||
+ ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
|
||||
+ u8 addr, u8 val)
|
||||
+{
|
||||
+ struct dvb_usb_device *d = ci->data;
|
||||
+ int ret;
|
||||
+ u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
|
||||
+
|
||||
+ ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
|
||||
+{
|
||||
+ struct dvb_usb_device *d = ci->data;
|
||||
+ int ret;
|
||||
+ struct anysee_state *state = d->priv;
|
||||
+
|
||||
+ state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
|
||||
+
|
||||
+ ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ msleep(300);
|
||||
+
|
||||
+ ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
|
||||
+{
|
||||
+ struct dvb_usb_device *d = ci->data;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ msleep(30);
|
||||
+
|
||||
+ ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
|
||||
+{
|
||||
+ struct dvb_usb_device *d = ci->data;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
|
||||
+ int open)
|
||||
+{
|
||||
+ struct dvb_usb_device *d = ci->data;
|
||||
+ struct anysee_state *state = d->priv;
|
||||
+ int ret;
|
||||
+ u8 tmp;
|
||||
+
|
||||
+ ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (tmp == 0) {
|
||||
+ ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
|
||||
+ if (time_after(jiffies, state->ci_cam_ready))
|
||||
+ ret |= DVB_CA_EN50221_POLL_CAM_READY;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int anysee_ci_init(struct dvb_usb_device *d)
|
||||
+{
|
||||
+ struct anysee_state *state = d->priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ state->ci.owner = THIS_MODULE;
|
||||
+ state->ci.read_attribute_mem = anysee_ci_read_attribute_mem;
|
||||
+ state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
|
||||
+ state->ci.read_cam_control = anysee_ci_read_cam_control;
|
||||
+ state->ci.write_cam_control = anysee_ci_write_cam_control;
|
||||
+ state->ci.slot_reset = anysee_ci_slot_reset;
|
||||
+ state->ci.slot_shutdown = anysee_ci_slot_shutdown;
|
||||
+ state->ci.slot_ts_enable = anysee_ci_slot_ts_enable;
|
||||
+ state->ci.poll_slot_status = anysee_ci_poll_slot_status;
|
||||
+ state->ci.data = d;
|
||||
+
|
||||
+ ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void anysee_ci_release(struct dvb_usb_device *d)
|
||||
+{
|
||||
+ struct anysee_state *state = d->priv;
|
||||
+
|
||||
+ /* detach CI */
|
||||
+ if (state->has_ci)
|
||||
+ dvb_ca_en50221_release(&state->ci);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static int anysee_init(struct dvb_usb_device *d)
|
||||
+{
|
||||
+ struct anysee_state *state = d->priv;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* LED light */
|
||||
+ ret = anysee_led_ctrl(d, 0x01, 0x03);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* enable IR */
|
||||
+ ret = anysee_ir_ctrl(d, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* attach CI */
|
||||
+ if (state->has_ci) {
|
||||
+ ret = anysee_ci_init(d);
|
||||
+ if (ret) {
|
||||
+ state->has_ci = false;
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* DVB USB Driver stuff */
|
||||
static struct dvb_usb_device_properties anysee_properties;
|
||||
|
||||
@@ -1010,6 +1288,16 @@
|
||||
return anysee_init(d);
|
||||
}
|
||||
|
||||
+static void anysee_disconnect(struct usb_interface *intf)
|
||||
+{
|
||||
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
|
||||
+
|
||||
+ anysee_ci_release(d);
|
||||
+ dvb_usb_device_exit(intf);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
static struct usb_device_id anysee_table[] = {
|
||||
{ USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
|
||||
{ USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
|
||||
@@ -1029,7 +1317,7 @@
|
||||
{
|
||||
.num_frontends = 2,
|
||||
.frontend_ctrl = anysee_frontend_ctrl,
|
||||
- .fe = {{
|
||||
+ .fe = { {
|
||||
.streaming_ctrl = anysee_streaming_ctrl,
|
||||
.frontend_attach = anysee_frontend_attach,
|
||||
.tuner_attach = anysee_tuner_attach,
|
||||
@@ -1057,7 +1345,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
- }},
|
||||
+ } },
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1087,7 +1375,7 @@
|
||||
static struct usb_driver anysee_driver = {
|
||||
.name = "dvb_usb_anysee",
|
||||
.probe = anysee_probe,
|
||||
- .disconnect = dvb_usb_device_exit,
|
||||
+ .disconnect = anysee_disconnect,
|
||||
.id_table = anysee_table,
|
||||
};
|
||||
|
||||
diff -Naur linux-3.2.1/drivers/media/dvb/dvb-usb/anysee.h linux-3.2.1.patch/drivers/media/dvb/dvb-usb/anysee.h
|
||||
--- linux-3.2.1/drivers/media/dvb/dvb-usb/anysee.h 2012-01-12 20:42:45.000000000 +0100
|
||||
+++ linux-3.2.1.patch/drivers/media/dvb/dvb-usb/anysee.h 2012-01-22 14:14:20.107382315 +0100
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#define DVB_USB_LOG_PREFIX "anysee"
|
||||
#include "dvb-usb.h"
|
||||
+#include "dvb_ca_en50221.h"
|
||||
|
||||
#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
|
||||
#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
|
||||
@@ -54,12 +55,16 @@
|
||||
CMD_GET_IR_CODE = 0x41,
|
||||
CMD_GET_HW_INFO = 0x19,
|
||||
CMD_SMARTCARD = 0x34,
|
||||
+ CMD_CI = 0x37,
|
||||
};
|
||||
|
||||
struct anysee_state {
|
||||
u8 hw; /* PCB ID */
|
||||
u8 seq;
|
||||
u8 fe_id:1; /* frondend ID */
|
||||
+ u8 has_ci:1;
|
||||
+ struct dvb_ca_en50221 ci;
|
||||
+ unsigned long ci_cam_ready; /* jiffies */
|
||||
};
|
||||
|
||||
#define ANYSEE_HW_507T 2 /* E30 */
|
||||
@@ -69,6 +74,7 @@
|
||||
#define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */
|
||||
#define ANYSEE_HW_508TC 18 /* E7 TC */
|
||||
#define ANYSEE_HW_508S2 19 /* E7 S2 */
|
||||
+#define ANYSEE_HW_508T2C 20 /* E7 T2C */
|
||||
#define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */
|
||||
#define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */
|
||||
|
||||
diff -Naur linux-3.2.1/drivers/media/dvb/dvb-usb/Kconfig linux-3.2.1.patch/drivers/media/dvb/dvb-usb/Kconfig
|
||||
--- linux-3.2.1/drivers/media/dvb/dvb-usb/Kconfig 2012-01-12 20:42:45.000000000 +0100
|
||||
+++ linux-3.2.1.patch/drivers/media/dvb/dvb-usb/Kconfig 2012-01-22 14:14:11.662237130 +0100
|
||||
@@ -311,6 +311,7 @@
|
||||
select DVB_STV0900 if !DVB_FE_CUSTOMISE
|
||||
select DVB_STV6110 if !DVB_FE_CUSTOMISE
|
||||
select DVB_ISL6423 if !DVB_FE_CUSTOMISE
|
||||
+ select DVB_CXD2820R if !DVB_FE_CUSTOMISE
|
||||
help
|
||||
Say Y here to support the Anysee E30, Anysee E30 Plus or
|
||||
Anysee E30 C Plus DVB USB2.0 receiver.
|
Loading…
x
Reference in New Issue
Block a user