]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/cx23885/cx23885-dvb.c
V4L/DVB (11368): v4l2-subdev: move s_standby from core to tuner.
[linux-2.6-omap-h63xx.git] / drivers / media / video / cx23885 / cx23885-dvb.c
index 1c454128a9df9c5fca5b2b6fd7253ed6111d5426..f48454ab3900897eb92fb16b492533dc622d9983 100644 (file)
@@ -30,6 +30,7 @@
 #include "cx23885.h"
 #include <media/v4l2-common.h>
 
+#include "dvb_ca_en50221.h"
 #include "s5h1409.h"
 #include "s5h1411.h"
 #include "mt2131.h"
 #include "dib7000p.h"
 #include "dibx000_common.h"
 #include "zl10353.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "lnbh24.h"
+#include "cx24116.h"
+#include "cimax2.h"
+#include "netup-eeprom.h"
+#include "netup-init.h"
 
 static unsigned int debug;
 
@@ -308,11 +316,63 @@ static struct zl10353_config dvico_fusionhdtv_xc3028 = {
        .no_tuner      = 1,
 };
 
+static struct stv0900_config netup_stv0900_config = {
+       .demod_address = 0x68,
+       .xtal = 27000000,
+       .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+       .diseqc_mode = 2,/* 2/3 PWM */
+       .path1_mode = 2,/*Serial continues clock */
+       .path2_mode = 2,/*Serial continues clock */
+       .tun1_maddress = 0,/* 0x60 */
+       .tun2_maddress = 3,/* 0x63 */
+       .tun1_adc = 1,/* 1 Vpp */
+       .tun2_adc = 1,/* 1 Vpp */
+};
+
+static struct stv6110_config netup_stv6110_tunerconfig_a = {
+       .i2c_address = 0x60,
+       .mclk = 27000000,
+       .iq_wiring = 0,
+};
+
+static struct stv6110_config netup_stv6110_tunerconfig_b = {
+       .i2c_address = 0x63,
+       .mclk = 27000000,
+       .iq_wiring = 1,
+};
+
+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,
+};
+
+static struct cx24116_config tevii_cx24116_config = {
+       .demod_address = 0x55,
+};
+
+static struct cx24116_config dvbworld_cx24116_config = {
+       .demod_address = 0x05,
+};
+
 static int dvb_register(struct cx23885_tsport *port)
 {
        struct cx23885_dev *dev = port->dev;
        struct cx23885_i2c *i2c_bus = NULL;
        struct videobuf_dvb_frontend *fe0;
+       int ret;
 
        /* Get the first frontend */
        fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
@@ -526,6 +586,78 @@ static int dvb_register(struct cx23885_tsport *port)
                                fe->ops.tuner_ops.set_config(fe, &ctl);
                }
                break;
+       case CX23885_BOARD_TBS_6920:
+               i2c_bus = &dev->i2c_bus[0];
+
+               fe0->dvb.frontend = dvb_attach(cx24116_attach,
+                       &tbs_cx24116_config,
+                       &i2c_bus->i2c_adap);
+               if (fe0->dvb.frontend != NULL)
+                       fe0->dvb.frontend->ops.set_voltage = tbs_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);
+               if (fe0->dvb.frontend != NULL)
+                       fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+               break;
+       case CX23885_BOARD_DVBWORLD_2005:
+               i2c_bus = &dev->i2c_bus[1];
+
+               fe0->dvb.frontend = dvb_attach(cx24116_attach,
+                       &dvbworld_cx24116_config,
+                       &i2c_bus->i2c_adap);
+               break;
+       case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+               i2c_bus = &dev->i2c_bus[0];
+               switch (port->nr) {
+               /* port B */
+               case 1:
+                       fe0->dvb.frontend = dvb_attach(stv0900_attach,
+                                                       &netup_stv0900_config,
+                                                       &i2c_bus->i2c_adap, 0);
+                       if (fe0->dvb.frontend != NULL) {
+                               if (dvb_attach(stv6110_attach,
+                                               fe0->dvb.frontend,
+                                               &netup_stv6110_tunerconfig_a,
+                                               &i2c_bus->i2c_adap)) {
+                                       if (!dvb_attach(lnbh24_attach,
+                                                       fe0->dvb.frontend,
+                                                       &i2c_bus->i2c_adap,
+                                                       LNBH24_PCL, 0, 0x09))
+                                               printk(KERN_ERR
+                                                       "No LNBH24 found!\n");
+
+                               }
+                       }
+                       break;
+               /* port C */
+               case 2:
+                       fe0->dvb.frontend = dvb_attach(stv0900_attach,
+                                                       &netup_stv0900_config,
+                                                       &i2c_bus->i2c_adap, 1);
+                       if (fe0->dvb.frontend != NULL) {
+                               if (dvb_attach(stv6110_attach,
+                                               fe0->dvb.frontend,
+                                               &netup_stv6110_tunerconfig_b,
+                                               &i2c_bus->i2c_adap)) {
+                                       if (!dvb_attach(lnbh24_attach,
+                                                       fe0->dvb.frontend,
+                                                       &i2c_bus->i2c_adap,
+                                                       LNBH24_PCL, 0, 0x0a))
+                                               printk(KERN_ERR
+                                                       "No LNBH24 found!\n");
+
+                               }
+                       }
+                       break;
+               }
+               break;
        default:
                printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
                        " isn't supported yet\n",
@@ -541,15 +673,39 @@ static int dvb_register(struct cx23885_tsport *port)
        fe0->dvb.frontend->callback = cx23885_tuner_callback;
 
        /* Put the analog decoder in standby to keep it quiet */
-       cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
+       call_all(dev, tuner, s_standby);
 
        if (fe0->dvb.frontend->ops.analog_ops.standby)
                fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
 
        /* register everything */
-       return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
+       ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
                &dev->pci->dev, adapter_nr, 0);
 
+       /* init CI & MAC */
+       switch (dev->board) {
+       case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: {
+               static struct netup_card_info cinfo;
+
+               netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo);
+               memcpy(port->frontends.adapter.proposed_mac,
+                               cinfo.port[port->nr - 1].mac, 6);
+               printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC="
+                       "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                       port->nr,
+                       port->frontends.adapter.proposed_mac[0],
+                       port->frontends.adapter.proposed_mac[1],
+                       port->frontends.adapter.proposed_mac[2],
+                       port->frontends.adapter.proposed_mac[3],
+                       port->frontends.adapter.proposed_mac[4],
+                       port->frontends.adapter.proposed_mac[5]);
+
+               netup_ci_init(port);
+               break;
+               }
+       }
+
+       return ret;
 }
 
 int cx23885_dvb_register(struct cx23885_tsport *port)
@@ -622,6 +778,12 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
        if (fe0->dvb.frontend)
                videobuf_dvb_unregister_bus(&port->frontends);
 
+       switch (port->dev->board) {
+       case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+               netup_ci_exit(port);
+               break;
+       }
+
        return 0;
 }