diff options
Diffstat (limited to 'drivers/media/pci/cx23885/cx23885-dvb.c')
-rw-r--r-- | drivers/media/pci/cx23885/cx23885-dvb.c | 160 |
1 files changed, 160 insertions, 0 deletions
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; |