提交 5823b3a6 编写于 作者: H Hartmut Hackmann 提交者: Mauro Carvalho Chehab

V4L/DVB (7392): saa7134: support 2nd DVB-S section of the MD8800

There are some restrictions:
- The 2nd DVB-S section will only work if the 1st is configured for DVB-S too.
  so "options saa7134-dvb use_frontend=0,1" won't work.
- Currently it is not possible to set the higher LNB supply voltages, so
  14V instead of 13V in the 2nd section.
- It is not possibe to turn off the 2nd LNB supply independently.
This comes from the problem that the 2nd section can't access the i2c interface
of the LNB supply chip.
Signed-off-by: NHartmut Hackmann <hartmut.hackmann@t-online.de>
Signed-off-by: NMauro Carvalho Chehab <mchehab@infradead.org>
上级 637afdb5
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "saa7134.h" #include "saa7134.h"
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include "dvb-pll.h" #include "dvb-pll.h"
#include <dvb_frontend.h>
#include "mt352.h" #include "mt352.h"
#include "mt352_priv.h" /* FIXME */ #include "mt352_priv.h" /* FIXME */
...@@ -94,7 +95,7 @@ static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on) ...@@ -94,7 +95,7 @@ static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28)); saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
udelay(10); udelay(10);
ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27); ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27);
dprintk("%s %s\n", __FUNCTION__, ok ? "on" : "off"); dprintk("%s %s\n", __func__, ok ? "on" : "off");
if (!ok) if (!ok)
saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26)); saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
...@@ -114,7 +115,7 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe) ...@@ -114,7 +115,7 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe)
static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 }; static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 };
struct saa7134_dev *dev= fe->dvb->priv; struct saa7134_dev *dev= fe->dvb->priv;
dprintk("%s called\n", __FUNCTION__); dprintk("%s called\n", __func__);
mt352_write(fe, clock_config, sizeof(clock_config)); mt352_write(fe, clock_config, sizeof(clock_config));
udelay(200); udelay(200);
...@@ -882,6 +883,33 @@ static int md8800_set_high_voltage(struct dvb_frontend *fe, long arg) ...@@ -882,6 +883,33 @@ static int md8800_set_high_voltage(struct dvb_frontend *fe, long arg)
return res; return res;
}; };
static int md8800_set_voltage2(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
{
struct saa7134_dev *dev = fe->dvb->priv;
u8 wbuf[2] = { 0x1f, 00 };
u8 rbuf;
struct i2c_msg msg[] = { { .addr = 0x08, .flags = 0, .buf = wbuf, .len = 1 },
{ .addr = 0x08, .flags = I2C_M_RD, .buf = &rbuf, .len = 1 } };
if (i2c_transfer(&dev->i2c_adap, msg, 2) != 2)
return -EIO;
/* NOTE: this assumes that gpo1 is used, it might be bit 5 (gpo2) */
if (voltage == SEC_VOLTAGE_18)
wbuf[1] = rbuf | 0x10;
else
wbuf[1] = rbuf & 0xef;
msg[0].len = 2;
i2c_transfer(&dev->i2c_adap, msg, 1);
return 0;
}
static int md8800_set_high_voltage2(struct dvb_frontend *fe, long arg)
{
struct saa7134_dev *dev = fe->dvb->priv;
wprintk("%s: sorry can't set high LNB supply voltage from here\n", __func__);
return -EIO;
}
/* ================================================================== /* ==================================================================
* nxt200x based ATSC cards, helper functions * nxt200x based ATSC cards, helper functions
*/ */
...@@ -1003,11 +1031,11 @@ static int dvb_init(struct saa7134_dev *dev) ...@@ -1003,11 +1031,11 @@ static int dvb_init(struct saa7134_dev *dev)
if (dev->dvb.frontend) { if (dev->dvb.frontend) {
if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
&dev->i2c_adap, 0) == NULL) { &dev->i2c_adap, 0) == NULL) {
wprintk("%s: Lifeview Trio, No tda826x found!\n", __FUNCTION__); wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
} }
if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
0x08, 0, 0) == NULL) { 0x08, 0, 0) == NULL) {
wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __FUNCTION__); wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
} }
} }
} }
...@@ -1036,27 +1064,35 @@ static int dvb_init(struct saa7134_dev *dev) ...@@ -1036,27 +1064,35 @@ static int dvb_init(struct saa7134_dev *dev)
dev->dvb.frontend = dvb_attach(tda10086_attach, dev->dvb.frontend = dvb_attach(tda10086_attach,
&flydvbs, &dev->i2c_adap); &flydvbs, &dev->i2c_adap);
if (dev->dvb.frontend) { if (dev->dvb.frontend) {
struct dvb_frontend *fe; struct dvb_frontend *fe = dev->dvb.frontend;
u8 dev_id = dev->eedata[2];
u8 data = 0xc4;
struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
if (dvb_attach(tda826x_attach, dev->dvb.frontend, if (dvb_attach(tda826x_attach, dev->dvb.frontend,
0x60, &dev->i2c_adap, 0) == NULL) 0x60, &dev->i2c_adap, 0) == NULL)
wprintk("%s: Medion Quadro, no tda826x " wprintk("%s: Medion Quadro, no tda826x "
"found !\n", __FUNCTION__); "found !\n", __func__);
/* Note 10.2. Hac if (dev_id != 0x08) {
* up to here. configuration for ctx948 and and one branch /* we need to open the i2c gate (we know it exists) */
* of md8800 should be identical fe->ops.i2c_gate_ctrl(fe, 1);
*/ if (dvb_attach(isl6405_attach, fe,
/* we need to open the i2c gate (we know it exists) */ &dev->i2c_adap, 0x08, 0, 0) == NULL)
fe = dev->dvb.frontend; wprintk("%s: Medion Quadro, no ISL6405 "
fe->ops.i2c_gate_ctrl(fe, 1); "found !\n", __func__);
if (dvb_attach(isl6405_attach, fe, /* fire up the 2nd section of the LNB supply since we can't do
&dev->i2c_adap, 0x08, 0, 0) == NULL) this from the other section */
wprintk("%s: Medion Quadro, no ISL6405 " msg.buf = &data;
"found !\n", __FUNCTION__); i2c_transfer(&dev->i2c_adap, &msg, 1);
fe->ops.i2c_gate_ctrl(fe, 0); fe->ops.i2c_gate_ctrl(fe, 0);
dev->original_set_voltage = fe->ops.set_voltage; dev->original_set_voltage = fe->ops.set_voltage;
fe->ops.set_voltage = md8800_set_voltage; fe->ops.set_voltage = md8800_set_voltage;
dev->original_set_high_voltage = fe->ops.enable_high_lnb_voltage; dev->original_set_high_voltage = fe->ops.enable_high_lnb_voltage;
fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage; fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage;
} else {
fe->ops.set_voltage = md8800_set_voltage2;
fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage2;
}
} }
} }
break; break;
...@@ -1082,11 +1118,11 @@ static int dvb_init(struct saa7134_dev *dev) ...@@ -1082,11 +1118,11 @@ static int dvb_init(struct saa7134_dev *dev)
if (dev->dvb.frontend) { if (dev->dvb.frontend) {
if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
&dev->i2c_adap, 0) == NULL) { &dev->i2c_adap, 0) == NULL) {
wprintk("%s: No tda826x found!\n", __FUNCTION__); wprintk("%s: No tda826x found!\n", __func__);
} }
if (dvb_attach(isl6421_attach, dev->dvb.frontend, if (dvb_attach(isl6421_attach, dev->dvb.frontend,
&dev->i2c_adap, 0x08, 0, 0) == NULL) { &dev->i2c_adap, 0x08, 0, 0) == NULL) {
wprintk("%s: No ISL6421 found!\n", __FUNCTION__); wprintk("%s: No ISL6421 found!\n", __func__);
} }
} }
break; break;
...@@ -1138,10 +1174,10 @@ static int dvb_init(struct saa7134_dev *dev) ...@@ -1138,10 +1174,10 @@ static int dvb_init(struct saa7134_dev *dev)
if (dev->dvb.frontend) { if (dev->dvb.frontend) {
if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
&dev->i2c_adap, 0) == NULL) &dev->i2c_adap, 0) == NULL)
wprintk("%s: No tda826x found!\n", __FUNCTION__); wprintk("%s: No tda826x found!\n", __func__);
if (dvb_attach(lnbp21_attach, dev->dvb.frontend, if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
&dev->i2c_adap, 0, 0) == NULL) &dev->i2c_adap, 0, 0) == NULL)
wprintk("%s: No lnbp21 found!\n", __FUNCTION__); wprintk("%s: No lnbp21 found!\n", __func__);
} }
break; break;
case SAA7134_BOARD_CREATIX_CTX953: case SAA7134_BOARD_CREATIX_CTX953:
...@@ -1164,14 +1200,14 @@ static int dvb_init(struct saa7134_dev *dev) ...@@ -1164,14 +1200,14 @@ static int dvb_init(struct saa7134_dev *dev)
if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
&dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL)
wprintk("%s: MD7134 DVB-S, no SD1878 " wprintk("%s: MD7134 DVB-S, no SD1878 "
"found !\n", __FUNCTION__); "found !\n", __func__);
/* we need to open the i2c gate (we know it exists) */ /* we need to open the i2c gate (we know it exists) */
fe = dev->dvb.frontend; fe = dev->dvb.frontend;
fe->ops.i2c_gate_ctrl(fe, 1); fe->ops.i2c_gate_ctrl(fe, 1);
if (dvb_attach(isl6405_attach, fe, if (dvb_attach(isl6405_attach, fe,
&dev->i2c_adap, 0x08, 0, 0) == NULL) &dev->i2c_adap, 0x08, 0, 0) == NULL)
wprintk("%s: MD7134 DVB-S, no ISL6405 " wprintk("%s: MD7134 DVB-S, no ISL6405 "
"found !\n", __FUNCTION__); "found !\n", __func__);
fe->ops.i2c_gate_ctrl(fe, 0); fe->ops.i2c_gate_ctrl(fe, 0);
dev->original_set_voltage = fe->ops.set_voltage; dev->original_set_voltage = fe->ops.set_voltage;
fe->ops.set_voltage = md8800_set_voltage; fe->ops.set_voltage = md8800_set_voltage;
...@@ -1239,8 +1275,20 @@ static int dvb_fini(struct saa7134_dev *dev) ...@@ -1239,8 +1275,20 @@ static int dvb_fini(struct saa7134_dev *dev)
/* otherwise we don't detect the tuner on next insmod */ /* otherwise we don't detect the tuner on next insmod */
saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg); saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg);
} else if (dev->board == SAA7134_BOARD_MEDION_MD8800_QUADRO) {
if ((dev->eedata[2] != 0x08) && use_frontend) {
/* turn off the 2nd lnb supply */
u8 data = 0x80;
struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1};
struct dvb_frontend *fe;
fe = dev->dvb.frontend;
if (fe->ops.i2c_gate_ctrl) {
fe->ops.i2c_gate_ctrl(fe, 1);
i2c_transfer(&dev->i2c_adap, &msg, 1);
fe->ops.i2c_gate_ctrl(fe, 0);
}
}
} }
videobuf_dvb_unregister(&dev->dvb); videobuf_dvb_unregister(&dev->dvb);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册