aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/davinci/vpif_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/davinci/vpif_display.c')
-rw-r--r--drivers/media/video/davinci/vpif_display.c474
1 files changed, 367 insertions, 107 deletions
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index 412c65d54fe1..cdf659abdc2a 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -38,6 +38,7 @@
38#include <media/adv7343.h> 38#include <media/adv7343.h>
39#include <media/v4l2-device.h> 39#include <media/v4l2-device.h>
40#include <media/v4l2-ioctl.h> 40#include <media/v4l2-ioctl.h>
41#include <media/v4l2-chip-ident.h>
41 42
42#include <mach/dm646x.h> 43#include <mach/dm646x.h>
43 44
@@ -84,17 +85,6 @@ static struct vpif_config_params config_params = {
84static struct vpif_device vpif_obj = { {NULL} }; 85static struct vpif_device vpif_obj = { {NULL} };
85static struct device *vpif_dev; 86static struct device *vpif_dev;
86 87
87static const struct vpif_channel_config_params ch_params[] = {
88 {
89 "NTSC", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
90 286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
91 },
92 {
93 "PAL", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
94 336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
95 },
96};
97
98/* 88/*
99 * vpif_uservirt_to_phys: This function is used to convert user 89 * vpif_uservirt_to_phys: This function is used to convert user
100 * space virtual address to physical address. 90 * space virtual address to physical address.
@@ -373,30 +363,54 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
373 return IRQ_HANDLED; 363 return IRQ_HANDLED;
374} 364}
375 365
376static int vpif_get_std_info(struct channel_obj *ch) 366static int vpif_update_std_info(struct channel_obj *ch)
377{ 367{
378 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
379 struct video_obj *vid_ch = &ch->video; 368 struct video_obj *vid_ch = &ch->video;
380 struct vpif_params *vpifparams = &ch->vpifparams; 369 struct vpif_params *vpifparams = &ch->vpifparams;
381 struct vpif_channel_config_params *std_info = &vpifparams->std_info; 370 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
382 const struct vpif_channel_config_params *config; 371 const struct vpif_channel_config_params *config;
383 372
384 int index; 373 int i;
385
386 std_info->stdid = vid_ch->stdid;
387 if (!std_info->stdid)
388 return -1;
389 374
390 for (index = 0; index < ARRAY_SIZE(ch_params); index++) { 375 for (i = 0; i < vpif_ch_params_count; i++) {
391 config = &ch_params[index]; 376 config = &ch_params[i];
392 if (config->stdid & std_info->stdid) { 377 if (config->hd_sd == 0) {
393 memcpy(std_info, config, sizeof(*config)); 378 vpif_dbg(2, debug, "SD format\n");
394 break; 379 if (config->stdid & vid_ch->stdid) {
380 memcpy(std_info, config, sizeof(*config));
381 break;
382 }
383 } else {
384 vpif_dbg(2, debug, "HD format\n");
385 if (config->dv_preset == vid_ch->dv_preset) {
386 memcpy(std_info, config, sizeof(*config));
387 break;
388 }
395 } 389 }
396 } 390 }
397 391
398 if (index == ARRAY_SIZE(ch_params)) 392 if (i == vpif_ch_params_count) {
399 return -1; 393 vpif_dbg(1, debug, "Format not found\n");
394 return -EINVAL;
395 }
396
397 return 0;
398}
399
400static int vpif_update_resolution(struct channel_obj *ch)
401{
402 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
403 struct video_obj *vid_ch = &ch->video;
404 struct vpif_params *vpifparams = &ch->vpifparams;
405 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
406
407 if (!vid_ch->stdid && !vid_ch->dv_preset && !vid_ch->bt_timings.height)
408 return -EINVAL;
409
410 if (vid_ch->stdid || vid_ch->dv_preset) {
411 if (vpif_update_std_info(ch))
412 return -EINVAL;
413 }
400 414
401 common->fmt.fmt.pix.width = std_info->width; 415 common->fmt.fmt.pix.width = std_info->width;
402 common->fmt.fmt.pix.height = std_info->height; 416 common->fmt.fmt.pix.height = std_info->height;
@@ -404,8 +418,8 @@ static int vpif_get_std_info(struct channel_obj *ch)
404 common->fmt.fmt.pix.width, common->fmt.fmt.pix.height); 418 common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
405 419
406 /* Set height and width paramateres */ 420 /* Set height and width paramateres */
407 ch->common[VPIF_VIDEO_INDEX].height = std_info->height; 421 common->height = std_info->height;
408 ch->common[VPIF_VIDEO_INDEX].width = std_info->width; 422 common->width = std_info->width;
409 423
410 return 0; 424 return 0;
411} 425}
@@ -516,10 +530,8 @@ static int vpif_check_format(struct channel_obj *ch,
516 else 530 else
517 sizeimage = config_params.channel_bufsize[ch->channel_id]; 531 sizeimage = config_params.channel_bufsize[ch->channel_id];
518 532
519 if (vpif_get_std_info(ch)) { 533 if (vpif_update_resolution(ch))
520 vpif_err("Error getting the standard info\n");
521 return -EINVAL; 534 return -EINVAL;
522 }
523 535
524 hpitch = pixfmt->bytesperline; 536 hpitch = pixfmt->bytesperline;
525 vpitch = sizeimage / (hpitch * 2); 537 vpitch = sizeimage / (hpitch * 2);
@@ -568,7 +580,10 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
568static int vpif_mmap(struct file *filep, struct vm_area_struct *vma) 580static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
569{ 581{
570 struct vpif_fh *fh = filep->private_data; 582 struct vpif_fh *fh = filep->private_data;
571 struct common_obj *common = &fh->channel->common[VPIF_VIDEO_INDEX]; 583 struct channel_obj *ch = fh->channel;
584 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
585
586 vpif_dbg(2, debug, "vpif_mmap\n");
572 587
573 return videobuf_mmap_mapper(&common->buffer_queue, vma); 588 return videobuf_mmap_mapper(&common->buffer_queue, vma);
574} 589}
@@ -637,9 +652,6 @@ static int vpif_release(struct file *filep)
637 struct channel_obj *ch = fh->channel; 652 struct channel_obj *ch = fh->channel;
638 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; 653 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
639 654
640 if (mutex_lock_interruptible(&common->lock))
641 return -ERESTARTSYS;
642
643 /* if this instance is doing IO */ 655 /* if this instance is doing IO */
644 if (fh->io_allowed[VPIF_VIDEO_INDEX]) { 656 if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
645 /* Reset io_usrs member of channel object */ 657 /* Reset io_usrs member of channel object */
@@ -662,8 +674,6 @@ static int vpif_release(struct file *filep)
662 config_params.numbuffers[ch->channel_id]; 674 config_params.numbuffers[ch->channel_id];
663 } 675 }
664 676
665 mutex_unlock(&common->lock);
666
667 /* Decrement channel usrs counter */ 677 /* Decrement channel usrs counter */
668 atomic_dec(&ch->usrs); 678 atomic_dec(&ch->usrs);
669 /* If this file handle has initialize encoder device, reset it */ 679 /* If this file handle has initialize encoder device, reset it */
@@ -680,7 +690,12 @@ static int vpif_release(struct file *filep)
680} 690}
681 691
682/* functions implementing ioctls */ 692/* functions implementing ioctls */
683 693/**
694 * vpif_querycap() - QUERYCAP handler
695 * @file: file ptr
696 * @priv: file handle
697 * @cap: ptr to v4l2_capability structure
698 */
684static int vpif_querycap(struct file *file, void *priv, 699static int vpif_querycap(struct file *file, void *priv,
685 struct v4l2_capability *cap) 700 struct v4l2_capability *cap)
686{ 701{
@@ -722,17 +737,9 @@ static int vpif_g_fmt_vid_out(struct file *file, void *priv,
722 if (common->fmt.type != fmt->type) 737 if (common->fmt.type != fmt->type)
723 return -EINVAL; 738 return -EINVAL;
724 739
725 /* Fill in the information about format */ 740 if (vpif_update_resolution(ch))
726 if (mutex_lock_interruptible(&common->lock))
727 return -ERESTARTSYS;
728
729 if (vpif_get_std_info(ch)) {
730 vpif_err("Error getting the standard info\n");
731 return -EINVAL; 741 return -EINVAL;
732 }
733
734 *fmt = common->fmt; 742 *fmt = common->fmt;
735 mutex_unlock(&common->lock);
736 return 0; 743 return 0;
737} 744}
738 745
@@ -773,12 +780,7 @@ static int vpif_s_fmt_vid_out(struct file *file, void *priv,
773 /* store the pix format in the channel object */ 780 /* store the pix format in the channel object */
774 common->fmt.fmt.pix = *pixfmt; 781 common->fmt.fmt.pix = *pixfmt;
775 /* store the format in the channel object */ 782 /* store the format in the channel object */
776 if (mutex_lock_interruptible(&common->lock))
777 return -ERESTARTSYS;
778
779 common->fmt = *fmt; 783 common->fmt = *fmt;
780 mutex_unlock(&common->lock);
781
782 return 0; 784 return 0;
783} 785}
784 786
@@ -808,7 +810,6 @@ static int vpif_reqbufs(struct file *file, void *priv,
808 struct common_obj *common; 810 struct common_obj *common;
809 enum v4l2_field field; 811 enum v4l2_field field;
810 u8 index = 0; 812 u8 index = 0;
811 int ret = 0;
812 813
813 /* This file handle has not initialized the channel, 814 /* This file handle has not initialized the channel,
814 It is not allowed to do settings */ 815 It is not allowed to do settings */
@@ -826,18 +827,12 @@ static int vpif_reqbufs(struct file *file, void *priv,
826 index = VPIF_VIDEO_INDEX; 827 index = VPIF_VIDEO_INDEX;
827 828
828 common = &ch->common[index]; 829 common = &ch->common[index];
829 if (mutex_lock_interruptible(&common->lock))
830 return -ERESTARTSYS;
831 830
832 if (common->fmt.type != reqbuf->type) { 831 if (common->fmt.type != reqbuf->type)
833 ret = -EINVAL; 832 return -EINVAL;
834 goto reqbuf_exit;
835 }
836 833
837 if (0 != common->io_usrs) { 834 if (0 != common->io_usrs)
838 ret = -EBUSY; 835 return -EBUSY;
839 goto reqbuf_exit;
840 }
841 836
842 if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 837 if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
843 if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY) 838 if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
@@ -854,7 +849,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
854 &common->irqlock, 849 &common->irqlock,
855 reqbuf->type, field, 850 reqbuf->type, field,
856 sizeof(struct videobuf_buffer), fh, 851 sizeof(struct videobuf_buffer), fh,
857 NULL); 852 &common->lock);
858 853
859 /* Set io allowed member of file handle to TRUE */ 854 /* Set io allowed member of file handle to TRUE */
860 fh->io_allowed[index] = 1; 855 fh->io_allowed[index] = 1;
@@ -865,11 +860,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
865 INIT_LIST_HEAD(&common->dma_queue); 860 INIT_LIST_HEAD(&common->dma_queue);
866 861
867 /* Allocate buffers */ 862 /* Allocate buffers */
868 ret = videobuf_reqbufs(&common->buffer_queue, reqbuf); 863 return videobuf_reqbufs(&common->buffer_queue, reqbuf);
869
870reqbuf_exit:
871 mutex_unlock(&common->lock);
872 return ret;
873} 864}
874 865
875static int vpif_querybuf(struct file *file, void *priv, 866static int vpif_querybuf(struct file *file, void *priv,
@@ -990,22 +981,19 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
990 } 981 }
991 982
992 /* Call encoder subdevice function to set the standard */ 983 /* Call encoder subdevice function to set the standard */
993 if (mutex_lock_interruptible(&common->lock))
994 return -ERESTARTSYS;
995
996 ch->video.stdid = *std_id; 984 ch->video.stdid = *std_id;
985 ch->video.dv_preset = V4L2_DV_INVALID;
986 memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
987
997 /* Get the information about the standard */ 988 /* Get the information about the standard */
998 if (vpif_get_std_info(ch)) { 989 if (vpif_update_resolution(ch))
999 vpif_err("Error getting the standard info\n");
1000 return -EINVAL; 990 return -EINVAL;
1001 }
1002 991
1003 if ((ch->vpifparams.std_info.width * 992 if ((ch->vpifparams.std_info.width *
1004 ch->vpifparams.std_info.height * 2) > 993 ch->vpifparams.std_info.height * 2) >
1005 config_params.channel_bufsize[ch->channel_id]) { 994 config_params.channel_bufsize[ch->channel_id]) {
1006 vpif_err("invalid std for this size\n"); 995 vpif_err("invalid std for this size\n");
1007 ret = -EINVAL; 996 return -EINVAL;
1008 goto s_std_exit;
1009 } 997 }
1010 998
1011 common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width; 999 common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
@@ -1016,16 +1004,13 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1016 s_std_output, *std_id); 1004 s_std_output, *std_id);
1017 if (ret < 0) { 1005 if (ret < 0) {
1018 vpif_err("Failed to set output standard\n"); 1006 vpif_err("Failed to set output standard\n");
1019 goto s_std_exit; 1007 return ret;
1020 } 1008 }
1021 1009
1022 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core, 1010 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
1023 s_std, *std_id); 1011 s_std, *std_id);
1024 if (ret < 0) 1012 if (ret < 0)
1025 vpif_err("Failed to set standard for sub devices\n"); 1013 vpif_err("Failed to set standard for sub devices\n");
1026
1027s_std_exit:
1028 mutex_unlock(&common->lock);
1029 return ret; 1014 return ret;
1030} 1015}
1031 1016
@@ -1090,21 +1075,17 @@ static int vpif_streamon(struct file *file, void *priv,
1090 if (ret < 0) 1075 if (ret < 0)
1091 return ret; 1076 return ret;
1092 1077
1093 /* Call videobuf_streamon to start streaming in videobuf */ 1078 /* Call videobuf_streamon to start streaming in videobuf */
1094 ret = videobuf_streamon(&common->buffer_queue); 1079 ret = videobuf_streamon(&common->buffer_queue);
1095 if (ret < 0) { 1080 if (ret < 0) {
1096 vpif_err("videobuf_streamon\n"); 1081 vpif_err("videobuf_streamon\n");
1097 return ret; 1082 return ret;
1098 } 1083 }
1099 1084
1100 if (mutex_lock_interruptible(&common->lock))
1101 return -ERESTARTSYS;
1102
1103 /* If buffer queue is empty, return error */ 1085 /* If buffer queue is empty, return error */
1104 if (list_empty(&common->dma_queue)) { 1086 if (list_empty(&common->dma_queue)) {
1105 vpif_err("buffer queue is empty\n"); 1087 vpif_err("buffer queue is empty\n");
1106 ret = -EIO; 1088 return -EIO;
1107 goto streamon_exit;
1108 } 1089 }
1109 1090
1110 /* Get the next frame from the buffer queue */ 1091 /* Get the next frame from the buffer queue */
@@ -1130,8 +1111,7 @@ static int vpif_streamon(struct file *file, void *priv,
1130 || (!ch->vpifparams.std_info.frm_fmt 1111 || (!ch->vpifparams.std_info.frm_fmt
1131 && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) { 1112 && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
1132 vpif_err("conflict in field format and std format\n"); 1113 vpif_err("conflict in field format and std format\n");
1133 ret = -EINVAL; 1114 return -EINVAL;
1134 goto streamon_exit;
1135 } 1115 }
1136 1116
1137 /* clock settings */ 1117 /* clock settings */
@@ -1140,13 +1120,13 @@ static int vpif_streamon(struct file *file, void *priv,
1140 ch->vpifparams.std_info.hd_sd); 1120 ch->vpifparams.std_info.hd_sd);
1141 if (ret < 0) { 1121 if (ret < 0) {
1142 vpif_err("can't set clock\n"); 1122 vpif_err("can't set clock\n");
1143 goto streamon_exit; 1123 return ret;
1144 } 1124 }
1145 1125
1146 /* set the parameters and addresses */ 1126 /* set the parameters and addresses */
1147 ret = vpif_set_video_params(vpif, ch->channel_id + 2); 1127 ret = vpif_set_video_params(vpif, ch->channel_id + 2);
1148 if (ret < 0) 1128 if (ret < 0)
1149 goto streamon_exit; 1129 return ret;
1150 1130
1151 common->started = ret; 1131 common->started = ret;
1152 vpif_config_addr(ch, ret); 1132 vpif_config_addr(ch, ret);
@@ -1171,9 +1151,6 @@ static int vpif_streamon(struct file *file, void *priv,
1171 } 1151 }
1172 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1; 1152 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
1173 } 1153 }
1174
1175streamon_exit:
1176 mutex_unlock(&common->lock);
1177 return ret; 1154 return ret;
1178} 1155}
1179 1156
@@ -1199,9 +1176,6 @@ static int vpif_streamoff(struct file *file, void *priv,
1199 return -EINVAL; 1176 return -EINVAL;
1200 } 1177 }
1201 1178
1202 if (mutex_lock_interruptible(&common->lock))
1203 return -ERESTARTSYS;
1204
1205 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 1179 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1206 /* disable channel */ 1180 /* disable channel */
1207 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { 1181 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
@@ -1216,8 +1190,6 @@ static int vpif_streamoff(struct file *file, void *priv,
1216 } 1190 }
1217 1191
1218 common->started = 0; 1192 common->started = 0;
1219 mutex_unlock(&common->lock);
1220
1221 return videobuf_streamoff(&common->buffer_queue); 1193 return videobuf_streamoff(&common->buffer_queue);
1222} 1194}
1223 1195
@@ -1264,13 +1236,9 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i)
1264 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; 1236 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1265 int ret = 0; 1237 int ret = 0;
1266 1238
1267 if (mutex_lock_interruptible(&common->lock))
1268 return -ERESTARTSYS;
1269
1270 if (common->started) { 1239 if (common->started) {
1271 vpif_err("Streaming in progress\n"); 1240 vpif_err("Streaming in progress\n");
1272 ret = -EBUSY; 1241 return -EBUSY;
1273 goto s_output_exit;
1274 } 1242 }
1275 1243
1276 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video, 1244 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
@@ -1280,9 +1248,6 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i)
1280 vpif_err("Failed to set output standard\n"); 1248 vpif_err("Failed to set output standard\n");
1281 1249
1282 vid_ch->output_id = i; 1250 vid_ch->output_id = i;
1283
1284s_output_exit:
1285 mutex_unlock(&common->lock);
1286 return ret; 1251 return ret;
1287} 1252}
1288 1253
@@ -1315,6 +1280,287 @@ static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
1315 return v4l2_prio_change(&ch->prio, &fh->prio, p); 1280 return v4l2_prio_change(&ch->prio, &fh->prio, p);
1316} 1281}
1317 1282
1283/**
1284 * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
1285 * @file: file ptr
1286 * @priv: file handle
1287 * @preset: input preset
1288 */
1289static int vpif_enum_dv_presets(struct file *file, void *priv,
1290 struct v4l2_dv_enum_preset *preset)
1291{
1292 struct vpif_fh *fh = priv;
1293 struct channel_obj *ch = fh->channel;
1294 struct video_obj *vid_ch = &ch->video;
1295
1296 return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
1297 video, enum_dv_presets, preset);
1298}
1299
1300/**
1301 * vpif_s_dv_presets() - S_DV_PRESETS handler
1302 * @file: file ptr
1303 * @priv: file handle
1304 * @preset: input preset
1305 */
1306static int vpif_s_dv_preset(struct file *file, void *priv,
1307 struct v4l2_dv_preset *preset)
1308{
1309 struct vpif_fh *fh = priv;
1310 struct channel_obj *ch = fh->channel;
1311 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1312 struct video_obj *vid_ch = &ch->video;
1313 int ret = 0;
1314
1315 if (common->started) {
1316 vpif_dbg(1, debug, "streaming in progress\n");
1317 return -EBUSY;
1318 }
1319
1320 ret = v4l2_prio_check(&ch->prio, fh->prio);
1321 if (ret != 0)
1322 return ret;
1323
1324 fh->initialized = 1;
1325
1326 /* Call encoder subdevice function to set the standard */
1327 if (mutex_lock_interruptible(&common->lock))
1328 return -ERESTARTSYS;
1329
1330 ch->video.dv_preset = preset->preset;
1331 ch->video.stdid = V4L2_STD_UNKNOWN;
1332 memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
1333
1334 /* Get the information about the standard */
1335 if (vpif_update_resolution(ch)) {
1336 ret = -EINVAL;
1337 } else {
1338 /* Configure the default format information */
1339 vpif_config_format(ch);
1340
1341 ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
1342 video, s_dv_preset, preset);
1343 }
1344
1345 mutex_unlock(&common->lock);
1346
1347 return ret;
1348}
1349/**
1350 * vpif_g_dv_presets() - G_DV_PRESETS handler
1351 * @file: file ptr
1352 * @priv: file handle
1353 * @preset: input preset
1354 */
1355static int vpif_g_dv_preset(struct file *file, void *priv,
1356 struct v4l2_dv_preset *preset)
1357{
1358 struct vpif_fh *fh = priv;
1359 struct channel_obj *ch = fh->channel;
1360
1361 preset->preset = ch->video.dv_preset;
1362
1363 return 0;
1364}
1365/**
1366 * vpif_s_dv_timings() - S_DV_TIMINGS handler
1367 * @file: file ptr
1368 * @priv: file handle
1369 * @timings: digital video timings
1370 */
1371static int vpif_s_dv_timings(struct file *file, void *priv,
1372 struct v4l2_dv_timings *timings)
1373{
1374 struct vpif_fh *fh = priv;
1375 struct channel_obj *ch = fh->channel;
1376 struct vpif_params *vpifparams = &ch->vpifparams;
1377 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
1378 struct video_obj *vid_ch = &ch->video;
1379 struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
1380 int ret;
1381
1382 if (timings->type != V4L2_DV_BT_656_1120) {
1383 vpif_dbg(2, debug, "Timing type not defined\n");
1384 return -EINVAL;
1385 }
1386
1387 /* Configure subdevice timings, if any */
1388 ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
1389 video, s_dv_timings, timings);
1390 if (ret == -ENOIOCTLCMD) {
1391 vpif_dbg(2, debug, "Custom DV timings not supported by "
1392 "subdevice\n");
1393 return -EINVAL;
1394 }
1395 if (ret < 0) {
1396 vpif_dbg(2, debug, "Error setting custom DV timings\n");
1397 return ret;
1398 }
1399
1400 if (!(timings->bt.width && timings->bt.height &&
1401 (timings->bt.hbackporch ||
1402 timings->bt.hfrontporch ||
1403 timings->bt.hsync) &&
1404 timings->bt.vfrontporch &&
1405 (timings->bt.vbackporch ||
1406 timings->bt.vsync))) {
1407 vpif_dbg(2, debug, "Timings for width, height, "
1408 "horizontal back porch, horizontal sync, "
1409 "horizontal front porch, vertical back porch, "
1410 "vertical sync and vertical back porch "
1411 "must be defined\n");
1412 return -EINVAL;
1413 }
1414
1415 *bt = timings->bt;
1416
1417 /* Configure video port timings */
1418
1419 std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
1420 bt->hsync - 8;
1421 std_info->sav2eav = bt->width;
1422
1423 std_info->l1 = 1;
1424 std_info->l3 = bt->vsync + bt->vbackporch + 1;
1425
1426 if (bt->interlaced) {
1427 if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
1428 std_info->vsize = bt->height * 2 +
1429 bt->vfrontporch + bt->vsync + bt->vbackporch +
1430 bt->il_vfrontporch + bt->il_vsync +
1431 bt->il_vbackporch;
1432 std_info->l5 = std_info->vsize/2 -
1433 (bt->vfrontporch - 1);
1434 std_info->l7 = std_info->vsize/2 + 1;
1435 std_info->l9 = std_info->l7 + bt->il_vsync +
1436 bt->il_vbackporch + 1;
1437 std_info->l11 = std_info->vsize -
1438 (bt->il_vfrontporch - 1);
1439 } else {
1440 vpif_dbg(2, debug, "Required timing values for "
1441 "interlaced BT format missing\n");
1442 return -EINVAL;
1443 }
1444 } else {
1445 std_info->vsize = bt->height + bt->vfrontporch +
1446 bt->vsync + bt->vbackporch;
1447 std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
1448 }
1449 strncpy(std_info->name, "Custom timings BT656/1120",
1450 VPIF_MAX_NAME);
1451 std_info->width = bt->width;
1452 std_info->height = bt->height;
1453 std_info->frm_fmt = bt->interlaced ? 0 : 1;
1454 std_info->ycmux_mode = 0;
1455 std_info->capture_format = 0;
1456 std_info->vbi_supported = 0;
1457 std_info->hd_sd = 1;
1458 std_info->stdid = 0;
1459 std_info->dv_preset = V4L2_DV_INVALID;
1460
1461 vid_ch->stdid = 0;
1462 vid_ch->dv_preset = V4L2_DV_INVALID;
1463
1464 return 0;
1465}
1466
1467/**
1468 * vpif_g_dv_timings() - G_DV_TIMINGS handler
1469 * @file: file ptr
1470 * @priv: file handle
1471 * @timings: digital video timings
1472 */
1473static int vpif_g_dv_timings(struct file *file, void *priv,
1474 struct v4l2_dv_timings *timings)
1475{
1476 struct vpif_fh *fh = priv;
1477 struct channel_obj *ch = fh->channel;
1478 struct video_obj *vid_ch = &ch->video;
1479 struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
1480
1481 timings->bt = *bt;
1482
1483 return 0;
1484}
1485
1486/*
1487 * vpif_g_chip_ident() - Identify the chip
1488 * @file: file ptr
1489 * @priv: file handle
1490 * @chip: chip identity
1491 *
1492 * Returns zero or -EINVAL if read operations fails.
1493 */
1494static int vpif_g_chip_ident(struct file *file, void *priv,
1495 struct v4l2_dbg_chip_ident *chip)
1496{
1497 chip->ident = V4L2_IDENT_NONE;
1498 chip->revision = 0;
1499 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
1500 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
1501 vpif_dbg(2, debug, "match_type is invalid.\n");
1502 return -EINVAL;
1503 }
1504
1505 return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
1506 g_chip_ident, chip);
1507}
1508
1509#ifdef CONFIG_VIDEO_ADV_DEBUG
1510/*
1511 * vpif_dbg_g_register() - Read register
1512 * @file: file ptr
1513 * @priv: file handle
1514 * @reg: register to be read
1515 *
1516 * Debugging only
1517 * Returns zero or -EINVAL if read operations fails.
1518 */
1519static int vpif_dbg_g_register(struct file *file, void *priv,
1520 struct v4l2_dbg_register *reg){
1521 struct vpif_fh *fh = priv;
1522 struct channel_obj *ch = fh->channel;
1523 struct video_obj *vid_ch = &ch->video;
1524
1525 return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
1526 g_register, reg);
1527}
1528
1529/*
1530 * vpif_dbg_s_register() - Write to register
1531 * @file: file ptr
1532 * @priv: file handle
1533 * @reg: register to be modified
1534 *
1535 * Debugging only
1536 * Returns zero or -EINVAL if write operations fails.
1537 */
1538static int vpif_dbg_s_register(struct file *file, void *priv,
1539 struct v4l2_dbg_register *reg){
1540 struct vpif_fh *fh = priv;
1541 struct channel_obj *ch = fh->channel;
1542 struct video_obj *vid_ch = &ch->video;
1543
1544 return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
1545 s_register, reg);
1546}
1547#endif
1548
1549/*
1550 * vpif_log_status() - Status information
1551 * @file: file ptr
1552 * @priv: file handle
1553 *
1554 * Returns zero.
1555 */
1556static int vpif_log_status(struct file *filep, void *priv)
1557{
1558 /* status for sub devices */
1559 v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
1560
1561 return 0;
1562}
1563
1318/* vpif display ioctl operations */ 1564/* vpif display ioctl operations */
1319static const struct v4l2_ioctl_ops vpif_ioctl_ops = { 1565static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
1320 .vidioc_querycap = vpif_querycap, 1566 .vidioc_querycap = vpif_querycap,
@@ -1336,13 +1582,24 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
1336 .vidioc_s_output = vpif_s_output, 1582 .vidioc_s_output = vpif_s_output,
1337 .vidioc_g_output = vpif_g_output, 1583 .vidioc_g_output = vpif_g_output,
1338 .vidioc_cropcap = vpif_cropcap, 1584 .vidioc_cropcap = vpif_cropcap,
1585 .vidioc_enum_dv_presets = vpif_enum_dv_presets,
1586 .vidioc_s_dv_preset = vpif_s_dv_preset,
1587 .vidioc_g_dv_preset = vpif_g_dv_preset,
1588 .vidioc_s_dv_timings = vpif_s_dv_timings,
1589 .vidioc_g_dv_timings = vpif_g_dv_timings,
1590 .vidioc_g_chip_ident = vpif_g_chip_ident,
1591#ifdef CONFIG_VIDEO_ADV_DEBUG
1592 .vidioc_g_register = vpif_dbg_g_register,
1593 .vidioc_s_register = vpif_dbg_s_register,
1594#endif
1595 .vidioc_log_status = vpif_log_status,
1339}; 1596};
1340 1597
1341static const struct v4l2_file_operations vpif_fops = { 1598static const struct v4l2_file_operations vpif_fops = {
1342 .owner = THIS_MODULE, 1599 .owner = THIS_MODULE,
1343 .open = vpif_open, 1600 .open = vpif_open,
1344 .release = vpif_release, 1601 .release = vpif_release,
1345 .ioctl = video_ioctl2, 1602 .unlocked_ioctl = video_ioctl2,
1346 .mmap = vpif_mmap, 1603 .mmap = vpif_mmap,
1347 .poll = vpif_poll 1604 .poll = vpif_poll
1348}; 1605};
@@ -1526,6 +1783,7 @@ static __init int vpif_probe(struct platform_device *pdev)
1526 v4l2_prio_init(&ch->prio); 1783 v4l2_prio_init(&ch->prio);
1527 ch->common[VPIF_VIDEO_INDEX].fmt.type = 1784 ch->common[VPIF_VIDEO_INDEX].fmt.type =
1528 V4L2_BUF_TYPE_VIDEO_OUTPUT; 1785 V4L2_BUF_TYPE_VIDEO_OUTPUT;
1786 ch->video_dev->lock = &common->lock;
1529 1787
1530 /* register video device */ 1788 /* register video device */
1531 vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n", 1789 vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
@@ -1565,6 +1823,8 @@ static __init int vpif_probe(struct platform_device *pdev)
1565 vpif_obj.sd[i]->grp_id = 1 << i; 1823 vpif_obj.sd[i]->grp_id = 1 << i;
1566 } 1824 }
1567 1825
1826 v4l2_info(&vpif_obj.v4l2_dev,
1827 "DM646x VPIF display driver initialized\n");
1568 return 0; 1828 return 0;
1569 1829
1570probe_subdev_out: 1830probe_subdev_out: