summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx23885
diff options
context:
space:
mode:
authorIgor M. Liplianin <liplianin@me.by>2009-11-24 20:16:04 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 18:42:08 -0200
commit09ea33e5c696958e8b1ae6d5ab184476b16592f1 (patch)
tree2543aefab407abd23e1070e626c6f7a1333f83b5 /drivers/media/video/cx23885
parent6afd2aa856eba0706176cecea1f989b1081c96dc (diff)
V4L/DVB (13493): TeVii S470 and TBS 6920 fixes
The new hardware design applied for this cards. Silicon Labs C8051F300 microcontroller is used for LNB power control. It connected to cx23885 GPIO pins: GPIO0 - P0.3 data GPIO1 - P0.2 reset GPIO2 - P0.1 clk GPIO3 - P0.0 busy Tevii S470 based on Montage Technology M88TS2020 digital satellite tuner and M88DS3000 advanced DVB-S/S2 demodulator. Signed-off-by: Igor M. Liplianin <liplianin@me.by> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx23885')
-rw-r--r--drivers/media/video/cx23885/Kconfig2
-rw-r--r--drivers/media/video/cx23885/Makefile2
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c14
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c20
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c38
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.c177
-rw-r--r--drivers/media/video/cx23885/cx23885-f300.h2
-rw-r--r--drivers/media/video/cx23885/cx23885.h1
8 files changed, 227 insertions, 29 deletions
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index fd3fc3e3198..bcdda9a9aa9 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -18,7 +18,9 @@ config VIDEO_CX23885
select DVB_TDA10048 if !DVB_FE_CUSTOMISE
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
select DVB_STV6110 if !DVB_FE_CUSTOMISE
+ select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_STV0900 if !DVB_FE_CUSTOMISE
+ select DVB_DS3000 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index bb462589b53..5787ae24363 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -1,7 +1,7 @@
cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
cx23885-ioctl.o cx23885-ir.o cx23885-input.o cx23888-ir.o \
- netup-init.o cimax2.o netup-eeprom.o
+ netup-init.o cimax2.o netup-eeprom.o cx23885-f300.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 23302ddf418..1ec48169277 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -782,10 +782,14 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
cx_set(GP0_IO, 0x00040004);
break;
case CX23885_BOARD_TBS_6920:
- case CX23885_BOARD_TEVII_S470:
cx_write(MC417_CTL, 0x00000036);
cx_write(MC417_OEN, 0x00001000);
- cx_write(MC417_RWD, 0x00001800);
+ cx_set(MC417_RWD, 0x00000002);
+ mdelay(200);
+ cx_clear(MC417_RWD, 0x00000800);
+ mdelay(200);
+ cx_set(MC417_RWD, 0x00000800);
+ mdelay(200);
break;
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
/* GPIO-0 INTA from CiMax1
@@ -1002,8 +1006,12 @@ void cx23885_card_setup(struct cx23885_dev *dev)
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
break;
- case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_TBS_6920:
+ ts1->gen_ctrl_val = 0x4; /* Parallel */
+ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ break;
+ case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_DVBWORLD_2005:
ts1->gen_ctrl_val = 0x5; /* Parallel */
ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index e8eb4ec0c30..04b12d27bc1 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1871,6 +1871,26 @@ void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask)
printk(KERN_INFO "%s: Unsupported\n", dev->name);
}
+u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask)
+{
+ if (mask & 0x00000007)
+ return (cx_read(GP0_IO) >> 8) & mask & 0x7;
+
+ if (mask & 0x0007fff8) {
+ if (encoder_on_portb(dev) || encoder_on_portc(dev))
+ printk(KERN_ERR
+ "%s: Reading GPIO moving on encoder ports\n",
+ dev->name);
+ return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3;
+ }
+
+ /* TODO: 23-19 */
+ if (mask & 0x00f80000)
+ printk(KERN_INFO "%s: Unsupported\n", dev->name);
+
+ return 0;
+}
+
void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
{
if ((mask & 0x00000007) && asoutput)
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index bf24e86293c..2607de134fa 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -56,6 +56,8 @@
#include "netup-init.h"
#include "lgdt3305.h"
#include "atbm8830.h"
+#include "ds3000.h"
+#include "cx23885-f300.h"
static unsigned int debug;
@@ -427,26 +429,12 @@ static struct stv6110_config netup_stv6110_tunerconfig_b = {
.gain = 8, /* +16 dB - maximum gain */
};
-static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
- struct cx23885_tsport *port = fe->dvb->priv;
- struct cx23885_dev *dev = port->dev;
-
- if (voltage == SEC_VOLTAGE_18)
- cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
- else if (voltage == SEC_VOLTAGE_13)
- cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
- else
- cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
- return 0;
-}
-
static struct cx24116_config tbs_cx24116_config = {
- .demod_address = 0x05,
+ .demod_address = 0x55,
};
-static struct cx24116_config tevii_cx24116_config = {
- .demod_address = 0x55,
+static struct ds3000_config tevii_ds3000_config = {
+ .demod_address = 0x68,
};
static struct cx24116_config dvbworld_cx24116_config = {
@@ -832,23 +820,23 @@ static int dvb_register(struct cx23885_tsport *port)
}
break;
case CX23885_BOARD_TBS_6920:
- i2c_bus = &dev->i2c_bus[0];
+ i2c_bus = &dev->i2c_bus[1];
fe0->dvb.frontend = dvb_attach(cx24116_attach,
- &tbs_cx24116_config,
- &i2c_bus->i2c_adap);
+ &tbs_cx24116_config,
+ &i2c_bus->i2c_adap);
if (fe0->dvb.frontend != NULL)
- fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
break;
case CX23885_BOARD_TEVII_S470:
i2c_bus = &dev->i2c_bus[1];
- fe0->dvb.frontend = dvb_attach(cx24116_attach,
- &tevii_cx24116_config,
- &i2c_bus->i2c_adap);
+ fe0->dvb.frontend = dvb_attach(ds3000_attach,
+ &tevii_ds3000_config,
+ &i2c_bus->i2c_adap);
if (fe0->dvb.frontend != NULL)
- fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
break;
case CX23885_BOARD_DVBWORLD_2005:
diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/video/cx23885/cx23885-f300.c
new file mode 100644
index 00000000000..93998f22098
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.c
@@ -0,0 +1,177 @@
+/*
+ * Driver for Silicon Labs C8051F300 microcontroller.
+ *
+ * It is used for LNB power control in TeVii S470,
+ * TBS 6920 PCIe DVB-S2 cards.
+ *
+ * Microcontroller connected to cx23885 GPIO pins:
+ * GPIO0 - data - P0.3 F300
+ * GPIO1 - reset - P0.2 F300
+ * GPIO2 - clk - P0.1 F300
+ * GPIO3 - busy - P0.0 F300
+ *
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by>
+ *
+ * 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 "cx23885.h"
+
+#define F300_DATA GPIO_0
+#define F300_RESET GPIO_1
+#define F300_CLK GPIO_2
+#define F300_BUSY GPIO_3
+
+static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
+{
+ cx23885_gpio_enable(dev, line, 1);
+ if (lvl == 1)
+ cx23885_gpio_set(dev, line);
+ else
+ cx23885_gpio_clear(dev, line);
+}
+
+static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
+{
+ cx23885_gpio_enable(dev, line, 0);
+
+ return cx23885_gpio_get(dev, line);
+}
+
+static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
+{
+ u8 i;
+
+ for (i = 0; i < 8; i++) {
+ f300_set_line(dev, F300_CLK, 0);
+ udelay(30);
+ f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
+ udelay(30);
+ dta <<= 1;
+ f300_set_line(dev, F300_CLK, 1);
+ udelay(30);
+ }
+}
+
+static u8 f300_get_byte(struct cx23885_dev *dev)
+{
+ u8 i, dta = 0;
+
+ for (i = 0; i < 8; i++) {
+ f300_set_line(dev, F300_CLK, 0);
+ udelay(30);
+ dta <<= 1;
+ f300_set_line(dev, F300_CLK, 1);
+ udelay(30);
+ dta |= f300_get_line(dev, F300_DATA);/* msb first */
+
+ }
+
+ return dta;
+}
+
+static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
+{
+ struct cx23885_tsport *port = fe->dvb->priv;
+ struct cx23885_dev *dev = port->dev;
+ u8 i, temp, ret = 0;
+
+ temp = buf[0];
+ for (i = 0; i < buf[0]; i++)
+ temp += buf[i + 1];
+ temp = (~temp + 1);/* get check sum */
+ buf[1 + buf[0]] = temp;
+
+ f300_set_line(dev, F300_RESET, 1);
+ f300_set_line(dev, F300_CLK, 1);
+ udelay(30);
+ f300_set_line(dev, F300_DATA, 1);
+ msleep(1);
+
+ /* question: */
+ f300_set_line(dev, F300_RESET, 0);/* begin to send data */
+ msleep(1);
+
+ f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
+ msleep(1);
+
+ temp = buf[0];
+ temp += 2;
+ for (i = 0; i < temp; i++)
+ f300_send_byte(dev, buf[i]);
+
+ f300_set_line(dev, F300_RESET, 1);/* sent data over */
+ f300_set_line(dev, F300_DATA, 1);
+
+ /* answer: */
+ temp = 0;
+ for (i = 0; ((i < 8) & (temp == 0)); i++) {
+ msleep(1);
+ if (f300_get_line(dev, F300_BUSY) == 0)
+ temp = 1;
+ }
+
+ if (i > 7) {
+ printk(KERN_ERR "%s: timeout, the slave no response\n",
+ __func__);
+ ret = 1; /* timeout, the slave no response */
+ } else { /* the slave not busy, prepare for getting data */
+ f300_set_line(dev, F300_RESET, 0);/*ready...*/
+ msleep(1);
+ f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
+ msleep(1);
+ temp = f300_get_byte(dev);/*get the data length */
+ if (temp > 14)
+ temp = 14;
+
+ for (i = 0; i < (temp + 1); i++)
+ f300_get_byte(dev);/* get data to empty buffer */
+
+ f300_set_line(dev, F300_RESET, 1);/* received data over */
+ f300_set_line(dev, F300_DATA, 1);
+ }
+
+ return ret;
+}
+
+int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ u8 buf[16];
+
+ buf[0] = 0x05;
+ buf[1] = 0x38;/* write port */
+ buf[2] = 0x01;/* A port, lnb power */
+
+ switch (voltage) {
+ case SEC_VOLTAGE_13:
+ buf[3] = 0x01;/* power on */
+ buf[4] = 0x02;/* B port, H/V */
+ buf[5] = 0x00;/*13V v*/
+ break;
+ case SEC_VOLTAGE_18:
+ buf[3] = 0x01;
+ buf[4] = 0x02;
+ buf[5] = 0x01;/* 18V h*/
+ break;
+ case SEC_VOLTAGE_OFF:
+ buf[3] = 0x00;/* power off */
+ buf[4] = 0x00;
+ buf[5] = 0x00;
+ break;
+ }
+
+ return f300_xfer(fe, buf);
+}
diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/video/cx23885/cx23885-f300.h
new file mode 100644
index 00000000000..e73344c9496
--- /dev/null
+++ b/drivers/media/video/cx23885/cx23885-f300.h
@@ -0,0 +1,2 @@
+extern int f300_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage);
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 33832002552..fa744764dc8 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -471,6 +471,7 @@ extern void cx23885_wakeup(struct cx23885_tsport *port,
extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
+extern u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask);
extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
int asoutput);