aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb/anysee.c
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2011-09-05 22:33:04 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-11-07 07:33:15 -0500
commit05cd37def5e697e158470d826cb75c5607c04bd1 (patch)
tree73e068946c2bea65be8756c80c31a698dca8865b /drivers/media/dvb/dvb-usb/anysee.c
parentbe94351e592cb71fb61aa8eeed7bf3f877dc6fff (diff)
[media] anysee: CI/CAM support
Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dvb-usb/anysee.c')
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c269
1 files changed, 236 insertions, 33 deletions
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 28c7b232c4a8..0bc1372aac18 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -130,6 +130,29 @@ static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
130 return anysee_write_reg(d, reg, val); 130 return anysee_write_reg(d, reg, val);
131} 131}
132 132
133/* read single register with mask */
134static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
135 u8 mask)
136{
137 int ret, i;
138 u8 tmp;
139
140 ret = anysee_read_reg(d, reg, &tmp);
141 if (ret)
142 return ret;
143
144 tmp &= mask;
145
146 /* find position of the first bit */
147 for (i = 0; i < 8; i++) {
148 if ((mask >> i) & 0x01)
149 break;
150 }
151 *val = tmp >> i;
152
153 return 0;
154}
155
133static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) 156static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
134{ 157{
135 u8 buf[] = {CMD_GET_HW_INFO}; 158 u8 buf[] = {CMD_GET_HW_INFO};
@@ -157,22 +180,6 @@ static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
157 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); 180 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
158} 181}
159 182
160static int anysee_init(struct dvb_usb_device *d)
161{
162 int ret;
163 /* LED light */
164 ret = anysee_led_ctrl(d, 0x01, 0x03);
165 if (ret)
166 return ret;
167
168 /* enable IR */
169 ret = anysee_ir_ctrl(d, 1);
170 if (ret)
171 return ret;
172
173 return 0;
174}
175
176/* I2C */ 183/* I2C */
177static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, 184static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
178 int num) 185 int num)
@@ -298,7 +305,7 @@ static struct tda10023_config anysee_tda10023_tda18212_config = {
298 .pll_m = 12, 305 .pll_m = 12,
299 .pll_p = 3, 306 .pll_p = 3,
300 .pll_n = 1, 307 .pll_n = 1,
301 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C, 308 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
302 .deltaf = 0xba02, 309 .deltaf = 0xba02,
303}; 310};
304 311
@@ -802,11 +809,6 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
802 /* E7 TC */ 809 /* E7 TC */
803 /* E7 PTC */ 810 /* E7 PTC */
804 811
805 /* enable transport stream on IOA[7] */
806 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
807 if (ret)
808 goto error;
809
810 if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { 812 if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
811 /* disable DVB-T demod on IOD[6] */ 813 /* disable DVB-T demod on IOD[6] */
812 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), 814 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
@@ -848,6 +850,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
848 adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = 850 adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
849 anysee_i2c_gate_ctrl; 851 anysee_i2c_gate_ctrl;
850 852
853 state->has_ci = true;
854
851 break; 855 break;
852 case ANYSEE_HW_508S2: /* 19 */ 856 case ANYSEE_HW_508S2: /* 19 */
853 case ANYSEE_HW_508PS2: /* 22 */ 857 case ANYSEE_HW_508PS2: /* 22 */
@@ -857,11 +861,6 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
857 if (state->fe_id) 861 if (state->fe_id)
858 break; 862 break;
859 863
860 /* enable transport stream on IOA[7] */
861 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
862 if (ret)
863 goto error;
864
865 /* enable DVB-S/S2 demod on IOE[5] */ 864 /* enable DVB-S/S2 demod on IOE[5] */
866 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); 865 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
867 if (ret) 866 if (ret)
@@ -871,15 +870,12 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
871 adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config, 870 adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config,
872 &adap->dev->i2c_adap, 0); 871 &adap->dev->i2c_adap, 0);
873 872
873 state->has_ci = true;
874
874 break; 875 break;
875 case ANYSEE_HW_508T2C: /* 20 */ 876 case ANYSEE_HW_508T2C: /* 20 */
876 /* E7 T2C */ 877 /* E7 T2C */
877 878
878 /* enable transport stream on IOA[7] */
879 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
880 if (ret)
881 goto error;
882
883 /* enable DVB-T/T2/C demod on IOE[5] */ 879 /* enable DVB-T/T2/C demod on IOE[5] */
884 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); 880 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
885 if (ret) 881 if (ret)
@@ -897,6 +893,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
897 &adap->dev->i2c_adap, adap->fe_adap[0].fe); 893 &adap->dev->i2c_adap, adap->fe_adap[0].fe);
898 } 894 }
899 895
896 state->has_ci = true;
897
900 break; 898 break;
901 } 899 }
902 900
@@ -1042,6 +1040,201 @@ static int anysee_rc_query(struct dvb_usb_device *d)
1042 return 0; 1040 return 0;
1043} 1041}
1044 1042
1043static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1044 int addr)
1045{
1046 struct dvb_usb_device *d = ci->data;
1047 int ret;
1048 u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
1049 u8 val;
1050
1051 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1052 if (ret)
1053 return ret;
1054
1055 return val;
1056}
1057
1058static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1059 int addr, u8 val)
1060{
1061 struct dvb_usb_device *d = ci->data;
1062 int ret;
1063 u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
1064
1065 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1066 if (ret)
1067 return ret;
1068
1069 return 0;
1070}
1071
1072static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
1073 u8 addr)
1074{
1075 struct dvb_usb_device *d = ci->data;
1076 int ret;
1077 u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
1078 u8 val;
1079
1080 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1081 if (ret)
1082 return ret;
1083
1084 return val;
1085}
1086
1087static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
1088 u8 addr, u8 val)
1089{
1090 struct dvb_usb_device *d = ci->data;
1091 int ret;
1092 u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
1093
1094 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1095 if (ret)
1096 return ret;
1097
1098 return 0;
1099}
1100
1101static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
1102{
1103 struct dvb_usb_device *d = ci->data;
1104 int ret;
1105 struct anysee_state *state = d->priv;
1106
1107 state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
1108
1109 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1110 if (ret)
1111 return ret;
1112
1113 msleep(300);
1114
1115 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1116 if (ret)
1117 return ret;
1118
1119 return 0;
1120}
1121
1122static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
1123{
1124 struct dvb_usb_device *d = ci->data;
1125 int ret;
1126
1127 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1128 if (ret)
1129 return ret;
1130
1131 msleep(30);
1132
1133 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1134 if (ret)
1135 return ret;
1136
1137 return 0;
1138}
1139
1140static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
1141{
1142 struct dvb_usb_device *d = ci->data;
1143 int ret;
1144
1145 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
1146 if (ret)
1147 return ret;
1148
1149 return 0;
1150}
1151
1152static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
1153 int open)
1154{
1155 struct dvb_usb_device *d = ci->data;
1156 struct anysee_state *state = d->priv;
1157 int ret;
1158 u8 tmp;
1159
1160 ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
1161 if (ret)
1162 return ret;
1163
1164 if (tmp == 0) {
1165 ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
1166 if (time_after(jiffies, state->ci_cam_ready))
1167 ret |= DVB_CA_EN50221_POLL_CAM_READY;
1168 }
1169
1170 return ret;
1171}
1172
1173static int anysee_ci_init(struct dvb_usb_device *d)
1174{
1175 struct anysee_state *state = d->priv;
1176 int ret;
1177
1178 state->ci.owner = THIS_MODULE;
1179 state->ci.read_attribute_mem = anysee_ci_read_attribute_mem;
1180 state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
1181 state->ci.read_cam_control = anysee_ci_read_cam_control;
1182 state->ci.write_cam_control = anysee_ci_write_cam_control;
1183 state->ci.slot_reset = anysee_ci_slot_reset;
1184 state->ci.slot_shutdown = anysee_ci_slot_shutdown;
1185 state->ci.slot_ts_enable = anysee_ci_slot_ts_enable;
1186 state->ci.poll_slot_status = anysee_ci_poll_slot_status;
1187 state->ci.data = d;
1188
1189 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1190 if (ret)
1191 return ret;
1192
1193 ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
1194 if (ret)
1195 return ret;
1196
1197 return 0;
1198}
1199
1200static void anysee_ci_release(struct dvb_usb_device *d)
1201{
1202 struct anysee_state *state = d->priv;
1203
1204 /* detach CI */
1205 if (state->has_ci)
1206 dvb_ca_en50221_release(&state->ci);
1207
1208 return;
1209}
1210
1211static int anysee_init(struct dvb_usb_device *d)
1212{
1213 struct anysee_state *state = d->priv;
1214 int ret;
1215
1216 /* LED light */
1217 ret = anysee_led_ctrl(d, 0x01, 0x03);
1218 if (ret)
1219 return ret;
1220
1221 /* enable IR */
1222 ret = anysee_ir_ctrl(d, 1);
1223 if (ret)
1224 return ret;
1225
1226 /* attach CI */
1227 if (state->has_ci) {
1228 ret = anysee_ci_init(d);
1229 if (ret) {
1230 state->has_ci = false;
1231 return ret;
1232 }
1233 }
1234
1235 return 0;
1236}
1237
1045/* DVB USB Driver stuff */ 1238/* DVB USB Driver stuff */
1046static struct dvb_usb_device_properties anysee_properties; 1239static struct dvb_usb_device_properties anysee_properties;
1047 1240
@@ -1083,6 +1276,16 @@ static int anysee_probe(struct usb_interface *intf,
1083 return anysee_init(d); 1276 return anysee_init(d);
1084} 1277}
1085 1278
1279static void anysee_disconnect(struct usb_interface *intf)
1280{
1281 struct dvb_usb_device *d = usb_get_intfdata(intf);
1282
1283 anysee_ci_release(d);
1284 dvb_usb_device_exit(intf);
1285
1286 return;
1287}
1288
1086static struct usb_device_id anysee_table[] = { 1289static struct usb_device_id anysee_table[] = {
1087 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, 1290 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
1088 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, 1291 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
@@ -1160,7 +1363,7 @@ static struct dvb_usb_device_properties anysee_properties = {
1160static struct usb_driver anysee_driver = { 1363static struct usb_driver anysee_driver = {
1161 .name = "dvb_usb_anysee", 1364 .name = "dvb_usb_anysee",
1162 .probe = anysee_probe, 1365 .probe = anysee_probe,
1163 .disconnect = dvb_usb_device_exit, 1366 .disconnect = anysee_disconnect,
1164 .id_table = anysee_table, 1367 .id_table = anysee_table,
1165}; 1368};
1166 1369