diff options
author | Igor M. Liplianin <liplianin@me.by> | 2011-02-25 16:41:22 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:32:25 -0400 |
commit | d2ffc447cabb3a497d7f413403abd8793b348329 (patch) | |
tree | 7999af844cecb0ff688ff9b180eb1c9ff5907f93 | |
parent | 195288da53e03c35f97df8fa08f48f5b625bfb4e (diff) |
[media] dw2102: add support for Geniatech SU3000 USB DVB-S2 card
The card uses ds3000 demod from Montage.
Signed-off-by: Igor M. Liplianin <liplianin@me.by>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/dvb/dvb-usb/dw2102.c | 287 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/ds3000.c | 40 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/ds3000.h | 1 |
3 files changed, 325 insertions, 3 deletions
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index f9affdd12d91..461c96a816d7 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* DVB USB framework compliant Linux driver for the | 1 | /* DVB USB framework compliant Linux driver for the |
2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, | 2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, |
3 | * TeVii S600, S630, S650, | 3 | * TeVii S600, S630, S650, |
4 | * Prof 1100, 7500 Cards | 4 | * Prof 1100, 7500, |
5 | * Geniatech SU3000 Cards | ||
5 | * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) | 6 | * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) |
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
@@ -67,6 +68,7 @@ | |||
67 | #define REG_21_SYMBOLRATE_BYTE2 0x21 | 68 | #define REG_21_SYMBOLRATE_BYTE2 0x21 |
68 | /* on my own*/ | 69 | /* on my own*/ |
69 | #define DW2102_VOLTAGE_CTRL (0x1800) | 70 | #define DW2102_VOLTAGE_CTRL (0x1800) |
71 | #define SU3000_STREAM_CTRL (0x1900) | ||
70 | #define DW2102_RC_QUERY (0x1a00) | 72 | #define DW2102_RC_QUERY (0x1a00) |
71 | 73 | ||
72 | #define err_str "did not find the firmware file. (%s) " \ | 74 | #define err_str "did not find the firmware file. (%s) " \ |
@@ -78,6 +80,10 @@ struct rc_map_dvb_usb_table_table { | |||
78 | int rc_keys_size; | 80 | int rc_keys_size; |
79 | }; | 81 | }; |
80 | 82 | ||
83 | struct su3000_state { | ||
84 | u8 initialized; | ||
85 | }; | ||
86 | |||
81 | /* debug */ | 87 | /* debug */ |
82 | static int dvb_usb_dw2102_debug; | 88 | static int dvb_usb_dw2102_debug; |
83 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); | 89 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); |
@@ -570,6 +576,70 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
570 | return num; | 576 | return num; |
571 | } | 577 | } |
572 | 578 | ||
579 | static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||
580 | int num) | ||
581 | { | ||
582 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
583 | u8 obuf[0x40], ibuf[0x40]; | ||
584 | |||
585 | if (!d) | ||
586 | return -ENODEV; | ||
587 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
588 | return -EAGAIN; | ||
589 | |||
590 | switch (num) { | ||
591 | case 1: | ||
592 | switch (msg[0].addr) { | ||
593 | case SU3000_STREAM_CTRL: | ||
594 | obuf[0] = msg[0].buf[0] + 0x36; | ||
595 | obuf[1] = 3; | ||
596 | obuf[2] = 0; | ||
597 | if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0) | ||
598 | err("i2c transfer failed."); | ||
599 | break; | ||
600 | case DW2102_RC_QUERY: | ||
601 | obuf[0] = 0x10; | ||
602 | if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0) | ||
603 | err("i2c transfer failed."); | ||
604 | msg[0].buf[1] = ibuf[0]; | ||
605 | msg[0].buf[0] = ibuf[1]; | ||
606 | break; | ||
607 | default: | ||
608 | /* always i2c write*/ | ||
609 | obuf[0] = 0x08; | ||
610 | obuf[1] = msg[0].addr; | ||
611 | obuf[2] = msg[0].len; | ||
612 | |||
613 | memcpy(&obuf[3], msg[0].buf, msg[0].len); | ||
614 | |||
615 | if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3, | ||
616 | ibuf, 1, 0) < 0) | ||
617 | err("i2c transfer failed."); | ||
618 | |||
619 | } | ||
620 | break; | ||
621 | case 2: | ||
622 | /* always i2c read */ | ||
623 | obuf[0] = 0x09; | ||
624 | obuf[1] = msg[0].len; | ||
625 | obuf[2] = msg[1].len; | ||
626 | obuf[3] = msg[0].addr; | ||
627 | memcpy(&obuf[4], msg[0].buf, msg[0].len); | ||
628 | |||
629 | if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4, | ||
630 | ibuf, msg[1].len + 1, 0) < 0) | ||
631 | err("i2c transfer failed."); | ||
632 | |||
633 | memcpy(msg[1].buf, &ibuf[1], msg[1].len); | ||
634 | break; | ||
635 | default: | ||
636 | warn("more than 2 i2c messages at a time is not handled yet."); | ||
637 | break; | ||
638 | } | ||
639 | mutex_unlock(&d->i2c_mutex); | ||
640 | return num; | ||
641 | } | ||
642 | |||
573 | static u32 dw210x_i2c_func(struct i2c_adapter *adapter) | 643 | static u32 dw210x_i2c_func(struct i2c_adapter *adapter) |
574 | { | 644 | { |
575 | return I2C_FUNC_I2C; | 645 | return I2C_FUNC_I2C; |
@@ -605,6 +675,11 @@ static struct i2c_algorithm s6x0_i2c_algo = { | |||
605 | .functionality = dw210x_i2c_func, | 675 | .functionality = dw210x_i2c_func, |
606 | }; | 676 | }; |
607 | 677 | ||
678 | static struct i2c_algorithm su3000_i2c_algo = { | ||
679 | .master_xfer = su3000_i2c_transfer, | ||
680 | .functionality = dw210x_i2c_func, | ||
681 | }; | ||
682 | |||
608 | static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | 683 | static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) |
609 | { | 684 | { |
610 | int i; | 685 | int i; |
@@ -669,6 +744,82 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | |||
669 | return 0; | 744 | return 0; |
670 | }; | 745 | }; |
671 | 746 | ||
747 | static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||
748 | { | ||
749 | static u8 command_start[] = {0x00}; | ||
750 | static u8 command_stop[] = {0x01}; | ||
751 | struct i2c_msg msg = { | ||
752 | .addr = SU3000_STREAM_CTRL, | ||
753 | .flags = 0, | ||
754 | .buf = onoff ? command_start : command_stop, | ||
755 | .len = 1 | ||
756 | }; | ||
757 | |||
758 | i2c_transfer(&adap->dev->i2c_adap, &msg, 1); | ||
759 | |||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | static int su3000_power_ctrl(struct dvb_usb_device *d, int i) | ||
764 | { | ||
765 | struct su3000_state *state = (struct su3000_state *)d->priv; | ||
766 | u8 obuf[] = {0xde, 0}; | ||
767 | |||
768 | info("%s: %d, initialized %d\n", __func__, i, state->initialized); | ||
769 | |||
770 | if (i && !state->initialized) { | ||
771 | state->initialized = 1; | ||
772 | /* reset board */ | ||
773 | dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0); | ||
774 | } | ||
775 | |||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | ||
780 | { | ||
781 | int i; | ||
782 | u8 obuf[] = { 0x1f, 0xf0 }; | ||
783 | u8 ibuf[] = { 0 }; | ||
784 | struct i2c_msg msg[] = { | ||
785 | { | ||
786 | .addr = 0x51, | ||
787 | .flags = 0, | ||
788 | .buf = obuf, | ||
789 | .len = 2, | ||
790 | }, { | ||
791 | .addr = 0x51, | ||
792 | .flags = I2C_M_RD, | ||
793 | .buf = ibuf, | ||
794 | .len = 1, | ||
795 | |||
796 | } | ||
797 | }; | ||
798 | |||
799 | for (i = 0; i < 6; i++) { | ||
800 | obuf[1] = 0xf0 + i; | ||
801 | if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) | ||
802 | break; | ||
803 | else | ||
804 | mac[i] = ibuf[0]; | ||
805 | |||
806 | debug_dump(mac, 6, printk); | ||
807 | } | ||
808 | |||
809 | return 0; | ||
810 | } | ||
811 | |||
812 | static int su3000_identify_state(struct usb_device *udev, | ||
813 | struct dvb_usb_device_properties *props, | ||
814 | struct dvb_usb_device_description **desc, | ||
815 | int *cold) | ||
816 | { | ||
817 | info("%s\n", __func__); | ||
818 | |||
819 | *cold = 0; | ||
820 | return 0; | ||
821 | } | ||
822 | |||
672 | static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 823 | static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
673 | { | 824 | { |
674 | static u8 command_13v[] = {0x00, 0x01}; | 825 | static u8 command_13v[] = {0x00, 0x01}; |
@@ -774,6 +925,11 @@ static struct stv0900_config prof_7500_stv0900_config = { | |||
774 | .tun1_type = 3, | 925 | .tun1_type = 3, |
775 | }; | 926 | }; |
776 | 927 | ||
928 | static struct ds3000_config su3000_ds3000_config = { | ||
929 | .demod_address = 0x68, | ||
930 | .ci_mode = 1, | ||
931 | }; | ||
932 | |||
777 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | 933 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) |
778 | { | 934 | { |
779 | struct dvb_tuner_ops *tuner_ops = NULL; | 935 | struct dvb_tuner_ops *tuner_ops = NULL; |
@@ -944,6 +1100,43 @@ static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) | |||
944 | return 0; | 1100 | return 0; |
945 | } | 1101 | } |
946 | 1102 | ||
1103 | static int su3000_frontend_attach(struct dvb_usb_adapter *d) | ||
1104 | { | ||
1105 | u8 obuf[3] = { 0xe, 0x80, 0 }; | ||
1106 | u8 ibuf[] = { 0 }; | ||
1107 | |||
1108 | if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | ||
1109 | err("command 0x0e transfer failed."); | ||
1110 | |||
1111 | obuf[0] = 0xe; | ||
1112 | obuf[1] = 0x83; | ||
1113 | obuf[2] = 0; | ||
1114 | |||
1115 | if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | ||
1116 | err("command 0x0e transfer failed."); | ||
1117 | |||
1118 | obuf[0] = 0xe; | ||
1119 | obuf[1] = 0x83; | ||
1120 | obuf[2] = 1; | ||
1121 | |||
1122 | if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | ||
1123 | err("command 0x0e transfer failed."); | ||
1124 | |||
1125 | obuf[0] = 0x51; | ||
1126 | |||
1127 | if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) | ||
1128 | err("command 0x51 transfer failed."); | ||
1129 | |||
1130 | d->fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, | ||
1131 | &d->dev->i2c_adap); | ||
1132 | if (d->fe == NULL) | ||
1133 | return -EIO; | ||
1134 | |||
1135 | info("Attached DS3000!\n"); | ||
1136 | |||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
947 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | 1140 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) |
948 | { | 1141 | { |
949 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, | 1142 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, |
@@ -1078,10 +1271,49 @@ static struct rc_map_table rc_map_tbs_table[] = { | |||
1078 | { 0xf89b, KEY_MODE } | 1271 | { 0xf89b, KEY_MODE } |
1079 | }; | 1272 | }; |
1080 | 1273 | ||
1274 | static struct rc_map_table rc_map_su3000_table[] = { | ||
1275 | { 0x25, KEY_POWER }, /* right-bottom Red */ | ||
1276 | { 0x0a, KEY_MUTE }, /* -/-- */ | ||
1277 | { 0x01, KEY_1 }, | ||
1278 | { 0x02, KEY_2 }, | ||
1279 | { 0x03, KEY_3 }, | ||
1280 | { 0x04, KEY_4 }, | ||
1281 | { 0x05, KEY_5 }, | ||
1282 | { 0x06, KEY_6 }, | ||
1283 | { 0x07, KEY_7 }, | ||
1284 | { 0x08, KEY_8 }, | ||
1285 | { 0x09, KEY_9 }, | ||
1286 | { 0x00, KEY_0 }, | ||
1287 | { 0x20, KEY_UP }, /* CH+ */ | ||
1288 | { 0x21, KEY_DOWN }, /* CH+ */ | ||
1289 | { 0x12, KEY_VOLUMEUP }, /* Brightness Up */ | ||
1290 | { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */ | ||
1291 | { 0x1f, KEY_RECORD }, | ||
1292 | { 0x17, KEY_PLAY }, | ||
1293 | { 0x16, KEY_PAUSE }, | ||
1294 | { 0x0b, KEY_STOP }, | ||
1295 | { 0x27, KEY_FASTFORWARD },/* >> */ | ||
1296 | { 0x26, KEY_REWIND }, /* << */ | ||
1297 | { 0x0d, KEY_OK }, /* Mute */ | ||
1298 | { 0x11, KEY_LEFT }, /* VOL- */ | ||
1299 | { 0x10, KEY_RIGHT }, /* VOL+ */ | ||
1300 | { 0x29, KEY_BACK }, /* button under 9 */ | ||
1301 | { 0x2c, KEY_MENU }, /* TTX */ | ||
1302 | { 0x2b, KEY_EPG }, /* EPG */ | ||
1303 | { 0x1e, KEY_RED }, /* OSD */ | ||
1304 | { 0x0e, KEY_GREEN }, /* Window */ | ||
1305 | { 0x2d, KEY_YELLOW }, /* button under << */ | ||
1306 | { 0x0f, KEY_BLUE }, /* bottom yellow button */ | ||
1307 | { 0x14, KEY_AUDIO }, /* Snapshot */ | ||
1308 | { 0x38, KEY_TV }, /* TV/Radio */ | ||
1309 | { 0x0c, KEY_ESC } /* upper Red buttton */ | ||
1310 | }; | ||
1311 | |||
1081 | static struct rc_map_dvb_usb_table_table keys_tables[] = { | 1312 | static struct rc_map_dvb_usb_table_table keys_tables[] = { |
1082 | { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) }, | 1313 | { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) }, |
1083 | { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) }, | 1314 | { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) }, |
1084 | { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) }, | 1315 | { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) }, |
1316 | { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) }, | ||
1085 | }; | 1317 | }; |
1086 | 1318 | ||
1087 | static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 1319 | static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) |
@@ -1137,6 +1369,7 @@ static struct usb_device_id dw2102_table[] = { | |||
1137 | {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, | 1369 | {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, |
1138 | {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, | 1370 | {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, |
1139 | {USB_DEVICE(0x3034, 0x7500)}, | 1371 | {USB_DEVICE(0x3034, 0x7500)}, |
1372 | {USB_DEVICE(0x1f4d, 0x3000)}, | ||
1140 | { } | 1373 | { } |
1141 | }; | 1374 | }; |
1142 | 1375 | ||
@@ -1473,6 +1706,51 @@ static struct dvb_usb_device_description d7500 = { | |||
1473 | {NULL}, | 1706 | {NULL}, |
1474 | }; | 1707 | }; |
1475 | 1708 | ||
1709 | static struct dvb_usb_device_properties su3000_properties = { | ||
1710 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
1711 | .usb_ctrl = DEVICE_SPECIFIC, | ||
1712 | .size_of_priv = sizeof(struct su3000_state), | ||
1713 | .power_ctrl = su3000_power_ctrl, | ||
1714 | .num_adapters = 1, | ||
1715 | .identify_state = su3000_identify_state, | ||
1716 | .i2c_algo = &su3000_i2c_algo, | ||
1717 | |||
1718 | .rc.legacy = { | ||
1719 | .rc_map_table = rc_map_su3000_table, | ||
1720 | .rc_map_size = ARRAY_SIZE(rc_map_su3000_table), | ||
1721 | .rc_interval = 150, | ||
1722 | .rc_query = dw2102_rc_query, | ||
1723 | }, | ||
1724 | |||
1725 | .read_mac_address = su3000_read_mac_address, | ||
1726 | |||
1727 | .generic_bulk_ctrl_endpoint = 0x01, | ||
1728 | |||
1729 | .adapter = { | ||
1730 | { | ||
1731 | .streaming_ctrl = su3000_streaming_ctrl, | ||
1732 | .frontend_attach = su3000_frontend_attach, | ||
1733 | .stream = { | ||
1734 | .type = USB_BULK, | ||
1735 | .count = 8, | ||
1736 | .endpoint = 0x82, | ||
1737 | .u = { | ||
1738 | .bulk = { | ||
1739 | .buffersize = 4096, | ||
1740 | } | ||
1741 | } | ||
1742 | } | ||
1743 | } | ||
1744 | }, | ||
1745 | .num_device_descs = 1, | ||
1746 | .devices = { | ||
1747 | { "SU3000HD DVB-S USB2.0", | ||
1748 | { &dw2102_table[10], NULL }, | ||
1749 | { NULL }, | ||
1750 | }, | ||
1751 | } | ||
1752 | }; | ||
1753 | |||
1476 | static int dw2102_probe(struct usb_interface *intf, | 1754 | static int dw2102_probe(struct usb_interface *intf, |
1477 | const struct usb_device_id *id) | 1755 | const struct usb_device_id *id) |
1478 | { | 1756 | { |
@@ -1527,7 +1805,9 @@ static int dw2102_probe(struct usb_interface *intf, | |||
1527 | 0 == dvb_usb_device_init(intf, s660, | 1805 | 0 == dvb_usb_device_init(intf, s660, |
1528 | THIS_MODULE, NULL, adapter_nr) || | 1806 | THIS_MODULE, NULL, adapter_nr) || |
1529 | 0 == dvb_usb_device_init(intf, p7500, | 1807 | 0 == dvb_usb_device_init(intf, p7500, |
1530 | THIS_MODULE, NULL, adapter_nr)) | 1808 | THIS_MODULE, NULL, adapter_nr) || |
1809 | 0 == dvb_usb_device_init(intf, &su3000_properties, | ||
1810 | THIS_MODULE, NULL, adapter_nr)) | ||
1531 | return 0; | 1811 | return 0; |
1532 | 1812 | ||
1533 | return -ENODEV; | 1813 | return -ENODEV; |
@@ -1561,6 +1841,7 @@ MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | |||
1561 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," | 1841 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," |
1562 | " DVB-C 3101 USB2.0," | 1842 | " DVB-C 3101 USB2.0," |
1563 | " TeVii S600, S630, S650, S660 USB2.0," | 1843 | " TeVii S600, S630, S650, S660 USB2.0," |
1564 | " Prof 1100, 7500 USB2.0 devices"); | 1844 | " Prof 1100, 7500 USB2.0," |
1845 | " Geniatech SU3000 devices"); | ||
1565 | MODULE_VERSION("0.1"); | 1846 | MODULE_VERSION("0.1"); |
1566 | MODULE_LICENSE("GPL"); | 1847 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c index 993357383fd4..3373890c092e 100644 --- a/drivers/media/dvb/frontends/ds3000.c +++ b/drivers/media/dvb/frontends/ds3000.c | |||
@@ -509,6 +509,33 @@ static int ds3000_load_firmware(struct dvb_frontend *fe, | |||
509 | return 0; | 509 | return 0; |
510 | } | 510 | } |
511 | 511 | ||
512 | static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
513 | { | ||
514 | struct ds3000_state *state = fe->demodulator_priv; | ||
515 | u8 data; | ||
516 | |||
517 | dprintk("%s(%d)\n", __func__, voltage); | ||
518 | |||
519 | data = ds3000_readreg(state, 0xa2); | ||
520 | data |= 0x03; /* bit0 V/H, bit1 off/on */ | ||
521 | |||
522 | switch (voltage) { | ||
523 | case SEC_VOLTAGE_18: | ||
524 | data &= ~0x03; | ||
525 | break; | ||
526 | case SEC_VOLTAGE_13: | ||
527 | data &= ~0x03; | ||
528 | data |= 0x01; | ||
529 | break; | ||
530 | case SEC_VOLTAGE_OFF: | ||
531 | break; | ||
532 | } | ||
533 | |||
534 | ds3000_writereg(state, 0xa2, data); | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
512 | static void ds3000_dump_registers(struct dvb_frontend *fe) | 539 | static void ds3000_dump_registers(struct dvb_frontend *fe) |
513 | { | 540 | { |
514 | struct ds3000_state *state = fe->demodulator_priv; | 541 | struct ds3000_state *state = fe->demodulator_priv; |
@@ -1255,6 +1282,18 @@ static int ds3000_tune(struct dvb_frontend *fe, | |||
1255 | ds3000_writereg(state, 0xfd, 0x42); | 1282 | ds3000_writereg(state, 0xfd, 0x42); |
1256 | ds3000_writereg(state, 0x08, 0x07);*/ | 1283 | ds3000_writereg(state, 0x08, 0x07);*/ |
1257 | 1284 | ||
1285 | if (state->config->ci_mode) { | ||
1286 | switch (c->delivery_system) { | ||
1287 | case SYS_DVBS: | ||
1288 | default: | ||
1289 | ds3000_writereg(state, 0xfd, 0x80); | ||
1290 | break; | ||
1291 | case SYS_DVBS2: | ||
1292 | ds3000_writereg(state, 0xfd, 0x01); | ||
1293 | break; | ||
1294 | } | ||
1295 | } | ||
1296 | |||
1258 | /* ds3000 out of software reset */ | 1297 | /* ds3000 out of software reset */ |
1259 | ds3000_writereg(state, 0x00, 0x00); | 1298 | ds3000_writereg(state, 0x00, 0x00); |
1260 | /* start ds3000 build-in uC */ | 1299 | /* start ds3000 build-in uC */ |
@@ -1351,6 +1390,7 @@ static struct dvb_frontend_ops ds3000_ops = { | |||
1351 | .read_signal_strength = ds3000_read_signal_strength, | 1390 | .read_signal_strength = ds3000_read_signal_strength, |
1352 | .read_snr = ds3000_read_snr, | 1391 | .read_snr = ds3000_read_snr, |
1353 | .read_ucblocks = ds3000_read_ucblocks, | 1392 | .read_ucblocks = ds3000_read_ucblocks, |
1393 | .set_voltage = ds3000_set_voltage, | ||
1354 | .set_tone = ds3000_set_tone, | 1394 | .set_tone = ds3000_set_tone, |
1355 | .diseqc_send_master_cmd = ds3000_send_diseqc_msg, | 1395 | .diseqc_send_master_cmd = ds3000_send_diseqc_msg, |
1356 | .diseqc_send_burst = ds3000_diseqc_send_burst, | 1396 | .diseqc_send_burst = ds3000_diseqc_send_burst, |
diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h index 67f67038740a..00e4e95590e9 100644 --- a/drivers/media/dvb/frontends/ds3000.h +++ b/drivers/media/dvb/frontends/ds3000.h | |||
@@ -27,6 +27,7 @@ | |||
27 | struct ds3000_config { | 27 | struct ds3000_config { |
28 | /* the demodulator's i2c address */ | 28 | /* the demodulator's i2c address */ |
29 | u8 demod_address; | 29 | u8 demod_address; |
30 | u8 ci_mode; | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | #if defined(CONFIG_DVB_DS3000) || \ | 33 | #if defined(CONFIG_DVB_DS3000) || \ |