aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/davinci
diff options
context:
space:
mode:
authorLad, Prabhakar <prabhakar.lad@ti.com>2012-09-25 07:11:49 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-10-05 21:12:27 -0400
commit2bd4e58c9d00325b7a850b2ac73fd902e9148b77 (patch)
treeef3242b551f05c3a54533e4a21ff21acd9a3b137 /drivers/media/platform/davinci
parentc389648a927bada928c854dccccf0301317784eb (diff)
[media] media: davinci: vpif: display: separate out subdev from output
vpif_display relied on a 1-1 mapping of output and subdev. This is not necessarily the case. Separate the two. So there is a list of subdevs and a list of outputs. Each output refers to a subdev and has routing information. An output does not have to have a subdev. The initial output for each channel is set to the fist output. Currently missing is support for associating multiple subdevs with an output. Signed-off-by: Lad, Prabhakar <prabhakar.lad@ti.com> Signed-off-by: Manjunath Hadli <manjunath.hadli@ti.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Sekhar Nori <nsekhar@ti.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/platform/davinci')
-rw-r--r--drivers/media/platform/davinci/vpif_display.c141
1 files changed, 111 insertions, 30 deletions
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 6229e4844bed..ae8329d79242 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -308,7 +308,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
308 channel2_intr_assert(); 308 channel2_intr_assert();
309 channel2_intr_enable(1); 309 channel2_intr_enable(1);
310 enable_channel2(1); 310 enable_channel2(1);
311 if (vpif_config_data->ch2_clip_en) 311 if (vpif_config_data->chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
312 channel2_clipping_enable(1); 312 channel2_clipping_enable(1);
313 } 313 }
314 314
@@ -317,7 +317,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
317 channel3_intr_assert(); 317 channel3_intr_assert();
318 channel3_intr_enable(1); 318 channel3_intr_enable(1);
319 enable_channel3(1); 319 enable_channel3(1);
320 if (vpif_config_data->ch3_clip_en) 320 if (vpif_config_data->chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
321 channel3_clipping_enable(1); 321 channel3_clipping_enable(1);
322 } 322 }
323 323
@@ -1174,14 +1174,16 @@ static int vpif_streamoff(struct file *file, void *priv,
1174 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 1174 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1175 /* disable channel */ 1175 /* disable channel */
1176 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { 1176 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
1177 if (vpif_config_data->ch2_clip_en) 1177 if (vpif_config_data->
1178 chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
1178 channel2_clipping_enable(0); 1179 channel2_clipping_enable(0);
1179 enable_channel2(0); 1180 enable_channel2(0);
1180 channel2_intr_enable(0); 1181 channel2_intr_enable(0);
1181 } 1182 }
1182 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) || 1183 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
1183 (2 == common->started)) { 1184 (2 == common->started)) {
1184 if (vpif_config_data->ch3_clip_en) 1185 if (vpif_config_data->
1186 chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
1185 channel3_clipping_enable(0); 1187 channel3_clipping_enable(0);
1186 enable_channel3(0); 1188 enable_channel3(0);
1187 channel3_intr_enable(0); 1189 channel3_intr_enable(0);
@@ -1214,41 +1216,118 @@ static int vpif_enum_output(struct file *file, void *fh,
1214{ 1216{
1215 1217
1216 struct vpif_display_config *config = vpif_dev->platform_data; 1218 struct vpif_display_config *config = vpif_dev->platform_data;
1219 struct vpif_display_chan_config *chan_cfg;
1220 struct vpif_fh *vpif_handler = fh;
1221 struct channel_obj *ch = vpif_handler->channel;
1217 1222
1218 if (output->index >= config->output_count) { 1223 chan_cfg = &config->chan_config[ch->channel_id];
1224 if (output->index >= chan_cfg->output_count) {
1219 vpif_dbg(1, debug, "Invalid output index\n"); 1225 vpif_dbg(1, debug, "Invalid output index\n");
1220 return -EINVAL; 1226 return -EINVAL;
1221 } 1227 }
1222 1228
1223 strcpy(output->name, config->output[output->index]); 1229 *output = chan_cfg->outputs[output->index].output;
1224 output->type = V4L2_OUTPUT_TYPE_ANALOG; 1230 return 0;
1225 output->std = VPIF_V4L2_STD; 1231}
1232
1233/**
1234 * vpif_output_to_subdev() - Maps output to sub device
1235 * @vpif_cfg - global config ptr
1236 * @chan_cfg - channel config ptr
1237 * @index - Given output index from application
1238 *
1239 * lookup the sub device information for a given output index.
1240 * we report all the output to application. output table also
1241 * has sub device name for the each output
1242 */
1243static int
1244vpif_output_to_subdev(struct vpif_display_config *vpif_cfg,
1245 struct vpif_display_chan_config *chan_cfg, int index)
1246{
1247 struct vpif_subdev_info *subdev_info;
1248 const char *subdev_name;
1249 int i;
1250
1251 vpif_dbg(2, debug, "vpif_output_to_subdev\n");
1252
1253 if (chan_cfg->outputs == NULL)
1254 return -1;
1255
1256 subdev_name = chan_cfg->outputs[index].subdev_name;
1257 if (subdev_name == NULL)
1258 return -1;
1259
1260 /* loop through the sub device list to get the sub device info */
1261 for (i = 0; i < vpif_cfg->subdev_count; i++) {
1262 subdev_info = &vpif_cfg->subdevinfo[i];
1263 if (!strcmp(subdev_info->name, subdev_name))
1264 return i;
1265 }
1266 return -1;
1267}
1268
1269/**
1270 * vpif_set_output() - Select an output
1271 * @vpif_cfg - global config ptr
1272 * @ch - channel
1273 * @index - Given output index from application
1274 *
1275 * Select the given output.
1276 */
1277static int vpif_set_output(struct vpif_display_config *vpif_cfg,
1278 struct channel_obj *ch, int index)
1279{
1280 struct vpif_display_chan_config *chan_cfg =
1281 &vpif_cfg->chan_config[ch->channel_id];
1282 struct vpif_subdev_info *subdev_info = NULL;
1283 struct v4l2_subdev *sd = NULL;
1284 u32 input = 0, output = 0;
1285 int sd_index;
1286 int ret;
1287
1288 sd_index = vpif_output_to_subdev(vpif_cfg, chan_cfg, index);
1289 if (sd_index >= 0) {
1290 sd = vpif_obj.sd[sd_index];
1291 subdev_info = &vpif_cfg->subdevinfo[sd_index];
1292 }
1226 1293
1294 if (sd) {
1295 input = chan_cfg->outputs[index].input_route;
1296 output = chan_cfg->outputs[index].output_route;
1297 ret = v4l2_subdev_call(sd, video, s_routing, input, output, 0);
1298 if (ret < 0 && ret != -ENOIOCTLCMD) {
1299 vpif_err("Failed to set output\n");
1300 return ret;
1301 }
1302
1303 }
1304 ch->output_idx = index;
1305 ch->sd = sd;
1306 if (chan_cfg->outputs != NULL)
1307 /* update tvnorms from the sub device output info */
1308 ch->video_dev->tvnorms = chan_cfg->outputs[index].output.std;
1227 return 0; 1309 return 0;
1228} 1310}
1229 1311
1230static int vpif_s_output(struct file *file, void *priv, unsigned int i) 1312static int vpif_s_output(struct file *file, void *priv, unsigned int i)
1231{ 1313{
1314 struct vpif_display_config *config = vpif_dev->platform_data;
1315 struct vpif_display_chan_config *chan_cfg;
1232 struct vpif_fh *fh = priv; 1316 struct vpif_fh *fh = priv;
1233 struct channel_obj *ch = fh->channel; 1317 struct channel_obj *ch = fh->channel;
1234 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; 1318 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1235 int ret = 0; 1319
1320 chan_cfg = &config->chan_config[ch->channel_id];
1321
1322 if (i >= chan_cfg->output_count)
1323 return -EINVAL;
1236 1324
1237 if (common->started) { 1325 if (common->started) {
1238 vpif_err("Streaming in progress\n"); 1326 vpif_err("Streaming in progress\n");
1239 return -EBUSY; 1327 return -EBUSY;
1240 } 1328 }
1241 1329
1242 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video, 1330 return vpif_set_output(config, ch, i);
1243 s_routing, 0, i, 0);
1244
1245 if (ret < 0)
1246 vpif_err("Failed to set output standard\n");
1247
1248 ch->output_idx = i;
1249 if (vpif_obj.sd[i])
1250 ch->sd = vpif_obj.sd[i];
1251 return ret;
1252} 1331}
1253 1332
1254static int vpif_g_output(struct file *file, void *priv, unsigned int *i) 1333static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
@@ -1291,9 +1370,12 @@ vpif_enum_dv_timings(struct file *file, void *priv,
1291{ 1370{
1292 struct vpif_fh *fh = priv; 1371 struct vpif_fh *fh = priv;
1293 struct channel_obj *ch = fh->channel; 1372 struct channel_obj *ch = fh->channel;
1373 int ret;
1294 1374
1295 return v4l2_subdev_call(vpif_obj.sd[ch->output_idx], 1375 ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
1296 video, enum_dv_timings, timings); 1376 if (ret == -ENOIOCTLCMD && ret == -ENODEV)
1377 return -EINVAL;
1378 return ret;
1297} 1379}
1298 1380
1299/** 1381/**
@@ -1320,12 +1402,9 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
1320 1402
1321 /* Configure subdevice timings, if any */ 1403 /* Configure subdevice timings, if any */
1322 ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings); 1404 ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
1323 if (ret == -ENOIOCTLCMD) { 1405 if (ret == -ENOIOCTLCMD || ret == -ENODEV)
1324 vpif_dbg(2, debug, "Custom DV timings not supported by " 1406 ret = 0;
1325 "subdevice\n"); 1407 if (ret < 0) {
1326 return -ENODATA;
1327 }
1328 if (ret < 0 && ret != -ENODEV) {
1329 vpif_dbg(2, debug, "Error setting custom DV timings\n"); 1408 vpif_dbg(2, debug, "Error setting custom DV timings\n");
1330 return ret; 1409 return ret;
1331 } 1410 }
@@ -1531,9 +1610,6 @@ static struct video_device vpif_video_template = {
1531 .name = "vpif", 1610 .name = "vpif",
1532 .fops = &vpif_fops, 1611 .fops = &vpif_fops,
1533 .ioctl_ops = &vpif_ioctl_ops, 1612 .ioctl_ops = &vpif_ioctl_ops,
1534 .tvnorms = VPIF_V4L2_STD,
1535 .current_norm = V4L2_STD_625_50,
1536
1537}; 1613};
1538 1614
1539/*Configure the channels, buffer sizei, request irq */ 1615/*Configure the channels, buffer sizei, request irq */
@@ -1756,6 +1832,11 @@ static __init int vpif_probe(struct platform_device *pdev)
1756 ch->video_dev->lock = &common->lock; 1832 ch->video_dev->lock = &common->lock;
1757 video_set_drvdata(ch->video_dev, ch); 1833 video_set_drvdata(ch->video_dev, ch);
1758 1834
1835 /* select output 0 */
1836 err = vpif_set_output(config, ch, 0);
1837 if (err)
1838 goto probe_out;
1839
1759 /* register video device */ 1840 /* register video device */
1760 vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n", 1841 vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
1761 (int)ch, (int)&ch->video_dev); 1842 (int)ch, (int)&ch->video_dev);