diff options
Diffstat (limited to 'drivers/media/usb/cx231xx/cx231xx-cards.c')
-rw-r--r-- | drivers/media/usb/cx231xx/cx231xx-cards.c | 220 |
1 files changed, 114 insertions, 106 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index cd74310887af..75b24b711531 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c | |||
@@ -1115,6 +1115,117 @@ static void flush_request_modules(struct cx231xx *dev) | |||
1115 | #define flush_request_modules(dev) | 1115 | #define flush_request_modules(dev) |
1116 | #endif /* CONFIG_MODULES */ | 1116 | #endif /* CONFIG_MODULES */ |
1117 | 1117 | ||
1118 | static int cx231xx_init_v4l2(struct cx231xx *dev, | ||
1119 | struct usb_device *udev, | ||
1120 | struct usb_interface *interface, | ||
1121 | int isoc_pipe) | ||
1122 | { | ||
1123 | struct usb_interface *uif; | ||
1124 | int i, idx; | ||
1125 | |||
1126 | /* Video Init */ | ||
1127 | |||
1128 | /* compute alternate max packet sizes for video */ | ||
1129 | idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1; | ||
1130 | if (idx >= dev->max_iad_interface_count) { | ||
1131 | cx231xx_errdev("Video PCB interface #%d doesn't exist\n", idx); | ||
1132 | return -ENODEV; | ||
1133 | } | ||
1134 | |||
1135 | uif = udev->actconfig->interface[idx]; | ||
1136 | |||
1137 | dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; | ||
1138 | dev->video_mode.num_alt = uif->num_altsetting; | ||
1139 | |||
1140 | cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", | ||
1141 | dev->video_mode.end_point_addr, | ||
1142 | dev->video_mode.num_alt); | ||
1143 | |||
1144 | dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL); | ||
1145 | if (dev->video_mode.alt_max_pkt_size == NULL) { | ||
1146 | cx231xx_errdev("out of memory!\n"); | ||
1147 | return -ENOMEM; | ||
1148 | } | ||
1149 | |||
1150 | for (i = 0; i < dev->video_mode.num_alt; i++) { | ||
1151 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); | ||
1152 | dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
1153 | cx231xx_info("Alternate setting %i, max size= %i\n", i, | ||
1154 | dev->video_mode.alt_max_pkt_size[i]); | ||
1155 | } | ||
1156 | |||
1157 | /* VBI Init */ | ||
1158 | |||
1159 | idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1; | ||
1160 | if (idx >= dev->max_iad_interface_count) { | ||
1161 | cx231xx_errdev("VBI PCB interface #%d doesn't exist\n", idx); | ||
1162 | return -ENODEV; | ||
1163 | } | ||
1164 | uif = udev->actconfig->interface[idx]; | ||
1165 | |||
1166 | dev->vbi_mode.end_point_addr = | ||
1167 | uif->altsetting[0].endpoint[isoc_pipe].desc. | ||
1168 | bEndpointAddress; | ||
1169 | |||
1170 | dev->vbi_mode.num_alt = uif->num_altsetting; | ||
1171 | cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", | ||
1172 | dev->vbi_mode.end_point_addr, | ||
1173 | dev->vbi_mode.num_alt); | ||
1174 | |||
1175 | /* compute alternate max packet sizes for vbi */ | ||
1176 | dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL); | ||
1177 | if (dev->vbi_mode.alt_max_pkt_size == NULL) { | ||
1178 | cx231xx_errdev("out of memory!\n"); | ||
1179 | return -ENOMEM; | ||
1180 | } | ||
1181 | |||
1182 | for (i = 0; i < dev->vbi_mode.num_alt; i++) { | ||
1183 | u16 tmp = | ||
1184 | le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | ||
1185 | desc.wMaxPacketSize); | ||
1186 | dev->vbi_mode.alt_max_pkt_size[i] = | ||
1187 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
1188 | cx231xx_info("Alternate setting %i, max size= %i\n", i, | ||
1189 | dev->vbi_mode.alt_max_pkt_size[i]); | ||
1190 | } | ||
1191 | |||
1192 | /* Sliced CC VBI init */ | ||
1193 | |||
1194 | /* compute alternate max packet sizes for sliced CC */ | ||
1195 | idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1; | ||
1196 | if (idx >= dev->max_iad_interface_count) { | ||
1197 | cx231xx_errdev("Sliced CC PCB interface #%d doesn't exist\n", idx); | ||
1198 | return -ENODEV; | ||
1199 | } | ||
1200 | uif = udev->actconfig->interface[idx]; | ||
1201 | |||
1202 | dev->sliced_cc_mode.end_point_addr = | ||
1203 | uif->altsetting[0].endpoint[isoc_pipe].desc. | ||
1204 | bEndpointAddress; | ||
1205 | |||
1206 | dev->sliced_cc_mode.num_alt = uif->num_altsetting; | ||
1207 | cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", | ||
1208 | dev->sliced_cc_mode.end_point_addr, | ||
1209 | dev->sliced_cc_mode.num_alt); | ||
1210 | dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL); | ||
1211 | |||
1212 | if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) { | ||
1213 | cx231xx_errdev("out of memory!\n"); | ||
1214 | return -ENOMEM; | ||
1215 | } | ||
1216 | |||
1217 | for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { | ||
1218 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | ||
1219 | desc.wMaxPacketSize); | ||
1220 | dev->sliced_cc_mode.alt_max_pkt_size[i] = | ||
1221 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
1222 | cx231xx_info("Alternate setting %i, max size= %i\n", i, | ||
1223 | dev->sliced_cc_mode.alt_max_pkt_size[i]); | ||
1224 | } | ||
1225 | |||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1118 | /* | 1229 | /* |
1119 | * cx231xx_usb_probe() | 1230 | * cx231xx_usb_probe() |
1120 | * checks for supported devices | 1231 | * checks for supported devices |
@@ -1232,124 +1343,21 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1232 | /* save our data pointer in this interface device */ | 1343 | /* save our data pointer in this interface device */ |
1233 | usb_set_intfdata(interface, dev); | 1344 | usb_set_intfdata(interface, dev); |
1234 | 1345 | ||
1235 | /* | ||
1236 | * AV device initialization - only done at the last interface | ||
1237 | */ | ||
1238 | |||
1239 | /* Create v4l2 device */ | 1346 | /* Create v4l2 device */ |
1240 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); | 1347 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); |
1241 | if (retval) { | 1348 | if (retval) { |
1242 | cx231xx_errdev("v4l2_device_register failed\n"); | 1349 | cx231xx_errdev("v4l2_device_register failed\n"); |
1243 | retval = -EIO; | ||
1244 | goto err_v4l2; | 1350 | goto err_v4l2; |
1245 | } | 1351 | } |
1352 | |||
1246 | /* allocate device struct */ | 1353 | /* allocate device struct */ |
1247 | retval = cx231xx_init_dev(dev, udev, nr); | 1354 | retval = cx231xx_init_dev(dev, udev, nr); |
1248 | if (retval) | 1355 | if (retval) |
1249 | goto err_init; | 1356 | goto err_init; |
1250 | 1357 | ||
1251 | /* compute alternate max packet sizes for video */ | 1358 | retval = cx231xx_init_v4l2(dev, udev, interface, isoc_pipe); |
1252 | idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1; | 1359 | if (retval) |
1253 | if (idx >= dev->max_iad_interface_count) { | ||
1254 | cx231xx_errdev("Video PCB interface #%d doesn't exist\n", idx); | ||
1255 | retval = -ENODEV; | ||
1256 | goto err_init; | 1360 | goto err_init; |
1257 | } | ||
1258 | uif = udev->actconfig->interface[idx]; | ||
1259 | |||
1260 | dev->video_mode.end_point_addr = uif->altsetting[0]. | ||
1261 | endpoint[isoc_pipe].desc.bEndpointAddress; | ||
1262 | |||
1263 | dev->video_mode.num_alt = uif->num_altsetting; | ||
1264 | cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", | ||
1265 | dev->video_mode.end_point_addr, | ||
1266 | dev->video_mode.num_alt); | ||
1267 | |||
1268 | dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL); | ||
1269 | if (dev->video_mode.alt_max_pkt_size == NULL) { | ||
1270 | cx231xx_errdev("out of memory!\n"); | ||
1271 | retval = -ENOMEM; | ||
1272 | goto err_video_alt; | ||
1273 | } | ||
1274 | |||
1275 | for (i = 0; i < dev->video_mode.num_alt; i++) { | ||
1276 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | ||
1277 | desc.wMaxPacketSize); | ||
1278 | dev->video_mode.alt_max_pkt_size[i] = | ||
1279 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
1280 | cx231xx_info("Alternate setting %i, max size= %i\n", i, | ||
1281 | dev->video_mode.alt_max_pkt_size[i]); | ||
1282 | } | ||
1283 | |||
1284 | /* compute alternate max packet sizes for vbi */ | ||
1285 | |||
1286 | idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1; | ||
1287 | if (idx >= dev->max_iad_interface_count) { | ||
1288 | cx231xx_errdev("VBI PCB interface #%d doesn't exist\n", idx); | ||
1289 | retval = -ENODEV; | ||
1290 | goto err_video_alt; | ||
1291 | } | ||
1292 | uif = udev->actconfig->interface[idx]; | ||
1293 | |||
1294 | dev->vbi_mode.end_point_addr = | ||
1295 | uif->altsetting[0].endpoint[isoc_pipe].desc. | ||
1296 | bEndpointAddress; | ||
1297 | |||
1298 | dev->vbi_mode.num_alt = uif->num_altsetting; | ||
1299 | cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", | ||
1300 | dev->vbi_mode.end_point_addr, | ||
1301 | dev->vbi_mode.num_alt); | ||
1302 | |||
1303 | dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL); | ||
1304 | if (dev->vbi_mode.alt_max_pkt_size == NULL) { | ||
1305 | cx231xx_errdev("out of memory!\n"); | ||
1306 | retval = -ENOMEM; | ||
1307 | goto err_video_alt; | ||
1308 | } | ||
1309 | |||
1310 | for (i = 0; i < dev->vbi_mode.num_alt; i++) { | ||
1311 | u16 tmp = | ||
1312 | le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | ||
1313 | desc.wMaxPacketSize); | ||
1314 | dev->vbi_mode.alt_max_pkt_size[i] = | ||
1315 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
1316 | cx231xx_info("Alternate setting %i, max size= %i\n", i, | ||
1317 | dev->vbi_mode.alt_max_pkt_size[i]); | ||
1318 | } | ||
1319 | |||
1320 | /* compute alternate max packet sizes for sliced CC */ | ||
1321 | idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1; | ||
1322 | if (idx >= dev->max_iad_interface_count) { | ||
1323 | cx231xx_errdev("Sliced CC PCB interface #%d doesn't exist\n", idx); | ||
1324 | retval = -ENODEV; | ||
1325 | goto err_video_alt; | ||
1326 | } | ||
1327 | uif = udev->actconfig->interface[idx]; | ||
1328 | |||
1329 | dev->sliced_cc_mode.end_point_addr = | ||
1330 | uif->altsetting[0].endpoint[isoc_pipe].desc. | ||
1331 | bEndpointAddress; | ||
1332 | |||
1333 | dev->sliced_cc_mode.num_alt = uif->num_altsetting; | ||
1334 | cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", | ||
1335 | dev->sliced_cc_mode.end_point_addr, | ||
1336 | dev->sliced_cc_mode.num_alt); | ||
1337 | dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL); | ||
1338 | |||
1339 | if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) { | ||
1340 | cx231xx_errdev("out of memory!\n"); | ||
1341 | retval = -ENOMEM; | ||
1342 | goto err_video_alt; | ||
1343 | } | ||
1344 | |||
1345 | for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { | ||
1346 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | ||
1347 | desc.wMaxPacketSize); | ||
1348 | dev->sliced_cc_mode.alt_max_pkt_size[i] = | ||
1349 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
1350 | cx231xx_info("Alternate setting %i, max size= %i\n", i, | ||
1351 | dev->sliced_cc_mode.alt_max_pkt_size[i]); | ||
1352 | } | ||
1353 | 1361 | ||
1354 | if (dev->current_pcb_config.ts1_source != 0xff) { | 1362 | if (dev->current_pcb_config.ts1_source != 0xff) { |
1355 | /* compute alternate max packet sizes for TS1 */ | 1363 | /* compute alternate max packet sizes for TS1 */ |