aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c47
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h2
-rw-r--r--drivers/media/video/s5p-fimc/fimc-mdevice.c1
-rw-r--r--include/media/s5p_fimc.h9
4 files changed, 59 insertions, 0 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index adbbb63fd526..7fafd1228fbc 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1076,6 +1076,53 @@ static const struct media_entity_operations fimc_sd_media_ops = {
1076 .link_setup = fimc_link_setup, 1076 .link_setup = fimc_link_setup,
1077}; 1077};
1078 1078
1079/**
1080 * fimc_sensor_notify - v4l2_device notification from a sensor subdev
1081 * @sd: pointer to a subdev generating the notification
1082 * @notification: the notification type, must be S5P_FIMC_TX_END_NOTIFY
1083 * @arg: pointer to an u32 type integer that stores the frame payload value
1084 *
1085 * The End Of Frame notification sent by sensor subdev in its still capture
1086 * mode. If there is only a single VSYNC generated by the sensor at the
1087 * beginning of a frame transmission, FIMC does not issue the LastIrq
1088 * (end of frame) interrupt. And this notification is used to complete the
1089 * frame capture and returning a buffer to user-space. Subdev drivers should
1090 * call this notification from their last 'End of frame capture' interrupt.
1091 */
1092void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
1093 void *arg)
1094{
1095 struct fimc_sensor_info *sensor;
1096 struct fimc_vid_buffer *buf;
1097 struct fimc_md *fmd;
1098 struct fimc_dev *fimc;
1099 unsigned long flags;
1100
1101 if (sd == NULL)
1102 return;
1103
1104 sensor = v4l2_get_subdev_hostdata(sd);
1105 fmd = entity_to_fimc_mdev(&sd->entity);
1106
1107 spin_lock_irqsave(&fmd->slock, flags);
1108 fimc = sensor ? sensor->host : NULL;
1109
1110 if (fimc && arg && notification == S5P_FIMC_TX_END_NOTIFY &&
1111 test_bit(ST_CAPT_PEND, &fimc->state)) {
1112 unsigned long irq_flags;
1113 spin_lock_irqsave(&fimc->slock, irq_flags);
1114 if (!list_empty(&fimc->vid_cap.active_buf_q)) {
1115 buf = list_entry(fimc->vid_cap.active_buf_q.next,
1116 struct fimc_vid_buffer, list);
1117 vb2_set_plane_payload(&buf->vb, 0, *((u32 *)arg));
1118 }
1119 fimc_capture_irq_handler(fimc, true);
1120 fimc_deactivate_capture(fimc);
1121 spin_unlock_irqrestore(&fimc->slock, irq_flags);
1122 }
1123 spin_unlock_irqrestore(&fmd->slock, flags);
1124}
1125
1079static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd, 1126static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1080 struct v4l2_subdev_fh *fh, 1127 struct v4l2_subdev_fh *fh,
1081 struct v4l2_subdev_mbus_code_enum *code) 1128 struct v4l2_subdev_mbus_code_enum *code)
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 9b448751f44b..6ec8b37ce41e 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -723,6 +723,8 @@ void fimc_unregister_capture_device(struct fimc_dev *fimc);
723int fimc_capture_ctrls_create(struct fimc_dev *fimc); 723int fimc_capture_ctrls_create(struct fimc_dev *fimc);
724int fimc_vid_cap_buf_queue(struct fimc_dev *fimc, 724int fimc_vid_cap_buf_queue(struct fimc_dev *fimc,
725 struct fimc_vid_buffer *fimc_vb); 725 struct fimc_vid_buffer *fimc_vb);
726void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
727 void *arg);
726int fimc_capture_suspend(struct fimc_dev *fimc); 728int fimc_capture_suspend(struct fimc_dev *fimc);
727int fimc_capture_resume(struct fimc_dev *fimc); 729int fimc_capture_resume(struct fimc_dev *fimc);
728int fimc_capture_config_update(struct fimc_ctx *ctx); 730int fimc_capture_config_update(struct fimc_ctx *ctx);
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c
index db17a6fad3e0..cc337b1de913 100644
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.c
+++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c
@@ -759,6 +759,7 @@ static int __devinit fimc_md_probe(struct platform_device *pdev)
759 759
760 v4l2_dev = &fmd->v4l2_dev; 760 v4l2_dev = &fmd->v4l2_dev;
761 v4l2_dev->mdev = &fmd->media_dev; 761 v4l2_dev->mdev = &fmd->media_dev;
762 v4l2_dev->notify = fimc_sensor_notify;
762 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s", 763 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s",
763 dev_name(&pdev->dev)); 764 dev_name(&pdev->dev));
764 765
diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h
index 086a7aada9d2..2b589042588d 100644
--- a/include/media/s5p_fimc.h
+++ b/include/media/s5p_fimc.h
@@ -60,4 +60,13 @@ struct s5p_platform_fimc {
60 struct s5p_fimc_isp_info *isp_info; 60 struct s5p_fimc_isp_info *isp_info;
61 int num_clients; 61 int num_clients;
62}; 62};
63
64/*
65 * v4l2_device notification id. This is only for internal use in the kernel.
66 * Sensor subdevs should issue S5P_FIMC_TX_END_NOTIFY notification in single
67 * frame capture mode when there is only one VSYNC pulse issued by the sensor
68 * at begining of the frame transmission.
69 */
70#define S5P_FIMC_TX_END_NOTIFY _IO('e', 0)
71
63#endif /* S5P_FIMC_H_ */ 72#endif /* S5P_FIMC_H_ */