diff options
author | Olli Salonen <olli.salonen@iki.fi> | 2014-08-11 15:58:15 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-09-23 20:33:16 -0400 |
commit | 294422662215188ace50ae14318ac025a56843d8 (patch) | |
tree | 34deeb68e4de967aa6c8dd7b4f37a5aa3381cff9 /drivers/media | |
parent | 5cd3b6b40d3a08394a9e973c597a284153eac0b5 (diff) |
[media] cx23855: add support for DVBSky T9580 DVB-C/T2/S2 tuner
DVBSky T9580 is a dual tuner card with one DVB-T2/C tuner and one DVB-S2 tuner. It contains the following components:
- PCIe bridge: Conexant CX23885
- Demod for terrestrial/cable: Silicon Labs Si2168-A30
- Tuner for terrestrial/cable: Silicon Labs Si2158-A20
- Demod for sat: Montage DS3103
- Tuner for sat: Montage TS2022
This patch depends on Max Nibble's patch for m88ds3103 (see patchwork 25312: https://patchwork.linuxtv.org/patch/25312/ ).
3 firmwares are needed:
- Si2168-A30 demod and Si2158-A20 tuner: same as TechnoTrend CT2-4400, https://www.mail-archive.com/linux-media@vger.kernel.org/msg76944.html
- Montage DS3103 demod: same as PCTV 461e, Antti has it on his LinuxTV project page: http://palosaari.fi/linux/v4l-dvb/firmware/M88DS3103/
IR receiver is not supported.
Values in cx23885_gpio_setup, cx23885_card_setup and dvbsky_t9580_set_voltage as well as the EEPROM read function are taken from the manufacturer provided semi-open source driver. The drivers in question are Linux GPL'd media tree drivers for cx23885 modified by Max Nibble (nibble.max@gmail.com) with proprietary tuner/demod drivers. Max is aware of this patch and has approved my use of the values in this patch.
Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/pci/cx23885/Kconfig | 4 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885-cards.c | 26 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885-dvb.c | 160 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885.h | 1 |
4 files changed, 191 insertions, 0 deletions
diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig index a883ea4968be..f613314b360b 100644 --- a/drivers/media/pci/cx23885/Kconfig +++ b/drivers/media/pci/cx23885/Kconfig | |||
@@ -31,12 +31,16 @@ config VIDEO_CX23885 | |||
31 | select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT | 31 | select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT |
32 | select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT | 32 | select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT |
33 | select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT | 33 | select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT |
34 | select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT | ||
35 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT | ||
34 | select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT | 36 | select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT |
35 | select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT | 37 | select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT |
36 | select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT | 38 | select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT |
37 | select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT | 39 | select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT |
38 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT | 40 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT |
39 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT | 41 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT |
42 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT | ||
43 | select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT | ||
40 | select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT | 44 | select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT |
41 | ---help--- | 45 | ---help--- |
42 | This is a video4linux driver for Conexant 23885 based | 46 | This is a video4linux driver for Conexant 23885 based |
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 21e500b0a220..88c257d1161b 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c | |||
@@ -675,6 +675,11 @@ struct cx23885_board cx23885_boards[] = { | |||
675 | .amux = CX25840_AUDIO7, | 675 | .amux = CX25840_AUDIO7, |
676 | } }, | 676 | } }, |
677 | }, | 677 | }, |
678 | [CX23885_BOARD_DVBSKY_T9580] = { | ||
679 | .name = "DVBSky T9580", | ||
680 | .portb = CX23885_MPEG_DVB, | ||
681 | .portc = CX23885_MPEG_DVB, | ||
682 | }, | ||
678 | }; | 683 | }; |
679 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 684 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); |
680 | 685 | ||
@@ -930,6 +935,10 @@ struct cx23885_subid cx23885_subids[] = { | |||
930 | .subvendor = 0x18ac, | 935 | .subvendor = 0x18ac, |
931 | .subdevice = 0xdb98, | 936 | .subdevice = 0xdb98, |
932 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2, | 937 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2, |
938 | }, { | ||
939 | .subvendor = 0x4254, | ||
940 | .subdevice = 0x9580, | ||
941 | .card = CX23885_BOARD_DVBSKY_T9580, | ||
933 | }, | 942 | }, |
934 | }; | 943 | }; |
935 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 944 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); |
@@ -1524,6 +1533,14 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
1524 | cx_set(GP0_IO, 0x00040004); | 1533 | cx_set(GP0_IO, 0x00040004); |
1525 | mdelay(60); | 1534 | mdelay(60); |
1526 | break; | 1535 | break; |
1536 | case CX23885_BOARD_DVBSKY_T9580: | ||
1537 | /* enable GPIO3-18 pins */ | ||
1538 | cx_write(MC417_CTL, 0x00000037); | ||
1539 | cx23885_gpio_enable(dev, GPIO_2 | GPIO_11, 1); | ||
1540 | cx23885_gpio_clear(dev, GPIO_2 | GPIO_11); | ||
1541 | mdelay(100); | ||
1542 | cx23885_gpio_set(dev, GPIO_2 | GPIO_11); | ||
1543 | break; | ||
1527 | } | 1544 | } |
1528 | } | 1545 | } |
1529 | 1546 | ||
@@ -1847,6 +1864,14 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1847 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 1864 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
1848 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 1865 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
1849 | break; | 1866 | break; |
1867 | case CX23885_BOARD_DVBSKY_T9580: | ||
1868 | ts1->gen_ctrl_val = 0x5; /* Parallel */ | ||
1869 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | ||
1870 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | ||
1871 | ts2->gen_ctrl_val = 0x8; /* Serial bus */ | ||
1872 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | ||
1873 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | ||
1874 | break; | ||
1850 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 1875 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
1851 | case CX23885_BOARD_HAUPPAUGE_HVR1500: | 1876 | case CX23885_BOARD_HAUPPAUGE_HVR1500: |
1852 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: | 1877 | case CX23885_BOARD_HAUPPAUGE_HVR1500Q: |
@@ -1909,6 +1934,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1909 | case CX23885_BOARD_AVERMEDIA_HC81R: | 1934 | case CX23885_BOARD_AVERMEDIA_HC81R: |
1910 | case CX23885_BOARD_TBS_6980: | 1935 | case CX23885_BOARD_TBS_6980: |
1911 | case CX23885_BOARD_TBS_6981: | 1936 | case CX23885_BOARD_TBS_6981: |
1937 | case CX23885_BOARD_DVBSKY_T9580: | ||
1912 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 1938 | dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, |
1913 | &dev->i2c_bus[2].i2c_adap, | 1939 | &dev->i2c_bus[2].i2c_adap, |
1914 | "cx25840", 0x88 >> 1, NULL); | 1940 | "cx25840", 0x88 >> 1, NULL); |
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 3e72c95a1d59..13734b8c7917 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c | |||
@@ -69,6 +69,10 @@ | |||
69 | #include "a8293.h" | 69 | #include "a8293.h" |
70 | #include "mb86a20s.h" | 70 | #include "mb86a20s.h" |
71 | #include "si2165.h" | 71 | #include "si2165.h" |
72 | #include "si2168.h" | ||
73 | #include "si2157.h" | ||
74 | #include "m88ds3103.h" | ||
75 | #include "m88ts2022.h" | ||
72 | 76 | ||
73 | static unsigned int debug; | 77 | static unsigned int debug; |
74 | 78 | ||
@@ -583,6 +587,35 @@ static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | |||
583 | return 0; | 587 | return 0; |
584 | } | 588 | } |
585 | 589 | ||
590 | static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe, | ||
591 | fe_sec_voltage_t voltage) | ||
592 | { | ||
593 | struct cx23885_tsport *port = fe->dvb->priv; | ||
594 | struct cx23885_dev *dev = port->dev; | ||
595 | |||
596 | cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1); | ||
597 | |||
598 | switch (voltage) { | ||
599 | case SEC_VOLTAGE_13: | ||
600 | cx23885_gpio_set(dev, GPIO_1); | ||
601 | cx23885_gpio_clear(dev, GPIO_0); | ||
602 | break; | ||
603 | case SEC_VOLTAGE_18: | ||
604 | cx23885_gpio_set(dev, GPIO_1); | ||
605 | cx23885_gpio_set(dev, GPIO_0); | ||
606 | break; | ||
607 | case SEC_VOLTAGE_OFF: | ||
608 | cx23885_gpio_clear(dev, GPIO_1); | ||
609 | cx23885_gpio_clear(dev, GPIO_0); | ||
610 | break; | ||
611 | } | ||
612 | |||
613 | /* call the frontend set_voltage function */ | ||
614 | port->fe_set_voltage(fe, voltage); | ||
615 | |||
616 | return 0; | ||
617 | } | ||
618 | |||
586 | static int cx23885_dvb_set_frontend(struct dvb_frontend *fe) | 619 | static int cx23885_dvb_set_frontend(struct dvb_frontend *fe) |
587 | { | 620 | { |
588 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | 621 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
@@ -747,6 +780,19 @@ static const struct si2165_config hauppauge_hvr4400_si2165_config = { | |||
747 | .ref_freq_Hz = 16000000, | 780 | .ref_freq_Hz = 16000000, |
748 | }; | 781 | }; |
749 | 782 | ||
783 | static const struct m88ds3103_config dvbsky_t9580_m88ds3103_config = { | ||
784 | .i2c_addr = 0x68, | ||
785 | .clock = 27000000, | ||
786 | .i2c_wr_max = 33, | ||
787 | .clock_out = 0, | ||
788 | .ts_mode = M88DS3103_TS_PARALLEL, | ||
789 | .ts_clk = 16000, | ||
790 | .ts_clk_pol = 1, | ||
791 | .lnb_en_pol = 1, | ||
792 | .lnb_hv_pol = 0, | ||
793 | .agc = 0x99, | ||
794 | }; | ||
795 | |||
750 | static int netup_altera_fpga_rw(void *device, int flag, int data, int read) | 796 | static int netup_altera_fpga_rw(void *device, int flag, int data, int read) |
751 | { | 797 | { |
752 | struct cx23885_dev *dev = (struct cx23885_dev *)device; | 798 | struct cx23885_dev *dev = (struct cx23885_dev *)device; |
@@ -896,6 +942,13 @@ static int dvb_register(struct cx23885_tsport *port) | |||
896 | struct cx23885_dev *dev = port->dev; | 942 | struct cx23885_dev *dev = port->dev; |
897 | struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; | 943 | struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; |
898 | struct vb2_dvb_frontend *fe0, *fe1 = NULL; | 944 | struct vb2_dvb_frontend *fe0, *fe1 = NULL; |
945 | struct si2168_config si2168_config; | ||
946 | struct si2157_config si2157_config; | ||
947 | struct m88ts2022_config m88ts2022_config; | ||
948 | struct i2c_board_info info; | ||
949 | struct i2c_adapter *adapter; | ||
950 | struct i2c_client *client_demod; | ||
951 | struct i2c_client *client_tuner; | ||
899 | int mfe_shared = 0; /* bus not shared by default */ | 952 | int mfe_shared = 0; /* bus not shared by default */ |
900 | int ret; | 953 | int ret; |
901 | 954 | ||
@@ -1533,6 +1586,97 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1533 | break; | 1586 | break; |
1534 | } | 1587 | } |
1535 | break; | 1588 | break; |
1589 | case CX23885_BOARD_DVBSKY_T9580: | ||
1590 | i2c_bus = &dev->i2c_bus[0]; | ||
1591 | i2c_bus2 = &dev->i2c_bus[1]; | ||
1592 | switch (port->nr) { | ||
1593 | /* port b - satellite */ | ||
1594 | case 1: | ||
1595 | /* attach frontend */ | ||
1596 | fe0->dvb.frontend = dvb_attach(m88ds3103_attach, | ||
1597 | &dvbsky_t9580_m88ds3103_config, | ||
1598 | &i2c_bus2->i2c_adap, &adapter); | ||
1599 | if (fe0->dvb.frontend == NULL) | ||
1600 | break; | ||
1601 | |||
1602 | /* attach tuner */ | ||
1603 | m88ts2022_config.fe = fe0->dvb.frontend; | ||
1604 | m88ts2022_config.clock = 27000000; | ||
1605 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1606 | strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); | ||
1607 | info.addr = 0x60; | ||
1608 | info.platform_data = &m88ts2022_config; | ||
1609 | request_module(info.type); | ||
1610 | client_tuner = i2c_new_device(adapter, &info); | ||
1611 | if (client_tuner == NULL || | ||
1612 | client_tuner->dev.driver == NULL) | ||
1613 | goto frontend_detach; | ||
1614 | if (!try_module_get(client_tuner->dev.driver->owner)) { | ||
1615 | i2c_unregister_device(client_tuner); | ||
1616 | goto frontend_detach; | ||
1617 | } | ||
1618 | |||
1619 | /* delegate signal strength measurement to tuner */ | ||
1620 | fe0->dvb.frontend->ops.read_signal_strength = | ||
1621 | fe0->dvb.frontend->ops.tuner_ops.get_rf_strength; | ||
1622 | |||
1623 | /* | ||
1624 | * for setting the voltage we need to set GPIOs on | ||
1625 | * the card. | ||
1626 | */ | ||
1627 | port->fe_set_voltage = | ||
1628 | fe0->dvb.frontend->ops.set_voltage; | ||
1629 | fe0->dvb.frontend->ops.set_voltage = | ||
1630 | dvbsky_t9580_set_voltage; | ||
1631 | |||
1632 | port->i2c_client_tuner = client_tuner; | ||
1633 | |||
1634 | break; | ||
1635 | /* port c - terrestrial/cable */ | ||
1636 | case 2: | ||
1637 | /* attach frontend */ | ||
1638 | si2168_config.i2c_adapter = &adapter; | ||
1639 | si2168_config.fe = &fe0->dvb.frontend; | ||
1640 | si2168_config.ts_mode = SI2168_TS_SERIAL; | ||
1641 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1642 | strlcpy(info.type, "si2168", I2C_NAME_SIZE); | ||
1643 | info.addr = 0x64; | ||
1644 | info.platform_data = &si2168_config; | ||
1645 | request_module(info.type); | ||
1646 | client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info); | ||
1647 | if (client_demod == NULL || | ||
1648 | client_demod->dev.driver == NULL) | ||
1649 | goto frontend_detach; | ||
1650 | if (!try_module_get(client_demod->dev.driver->owner)) { | ||
1651 | i2c_unregister_device(client_demod); | ||
1652 | goto frontend_detach; | ||
1653 | } | ||
1654 | port->i2c_client_demod = client_demod; | ||
1655 | |||
1656 | /* attach tuner */ | ||
1657 | si2157_config.fe = fe0->dvb.frontend; | ||
1658 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1659 | strlcpy(info.type, "si2157", I2C_NAME_SIZE); | ||
1660 | info.addr = 0x60; | ||
1661 | info.platform_data = &si2157_config; | ||
1662 | request_module(info.type); | ||
1663 | client_tuner = i2c_new_device(adapter, &info); | ||
1664 | if (client_tuner == NULL || | ||
1665 | client_tuner->dev.driver == NULL) { | ||
1666 | module_put(client_demod->dev.driver->owner); | ||
1667 | i2c_unregister_device(client_demod); | ||
1668 | goto frontend_detach; | ||
1669 | } | ||
1670 | if (!try_module_get(client_tuner->dev.driver->owner)) { | ||
1671 | i2c_unregister_device(client_tuner); | ||
1672 | module_put(client_demod->dev.driver->owner); | ||
1673 | i2c_unregister_device(client_demod); | ||
1674 | goto frontend_detach; | ||
1675 | } | ||
1676 | port->i2c_client_tuner = client_tuner; | ||
1677 | break; | ||
1678 | } | ||
1679 | break; | ||
1536 | default: | 1680 | default: |
1537 | printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " | 1681 | printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " |
1538 | " isn't supported yet\n", | 1682 | " isn't supported yet\n", |
@@ -1607,6 +1751,22 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1607 | memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); | 1751 | memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); |
1608 | break; | 1752 | break; |
1609 | } | 1753 | } |
1754 | case CX23885_BOARD_DVBSKY_T9580: { | ||
1755 | u8 eeprom[256]; /* 24C02 i2c eeprom */ | ||
1756 | |||
1757 | if (port->nr > 2) | ||
1758 | break; | ||
1759 | |||
1760 | /* Read entire EEPROM */ | ||
1761 | dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; | ||
1762 | tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, | ||
1763 | sizeof(eeprom)); | ||
1764 | printk(KERN_INFO "DVBSky T9580 port %d MAC address: %pM\n", | ||
1765 | port->nr, eeprom + 0xc0 + (port->nr-1) * 8); | ||
1766 | memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0 + | ||
1767 | (port->nr-1) * 8, 6); | ||
1768 | break; | ||
1769 | } | ||
1610 | } | 1770 | } |
1611 | 1771 | ||
1612 | return ret; | 1772 | return ret; |
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 0d5888214fb6..6c35e6115969 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h | |||
@@ -92,6 +92,7 @@ | |||
92 | #define CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200 42 | 92 | #define CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200 42 |
93 | #define CX23885_BOARD_HAUPPAUGE_IMPACTVCBE 43 | 93 | #define CX23885_BOARD_HAUPPAUGE_IMPACTVCBE 43 |
94 | #define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2 44 | 94 | #define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2 44 |
95 | #define CX23885_BOARD_DVBSKY_T9580 45 | ||
95 | 96 | ||
96 | #define GPIO_0 0x00000001 | 97 | #define GPIO_0 0x00000001 |
97 | #define GPIO_1 0x00000002 | 98 | #define GPIO_1 0x00000002 |