diff options
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 47 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.h | 2 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-mdevice.c | 1 | ||||
-rw-r--r-- | include/media/s5p_fimc.h | 9 |
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 | */ | ||
1092 | void 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 | |||
1079 | static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd, | 1126 | static 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); | |||
723 | int fimc_capture_ctrls_create(struct fimc_dev *fimc); | 723 | int fimc_capture_ctrls_create(struct fimc_dev *fimc); |
724 | int fimc_vid_cap_buf_queue(struct fimc_dev *fimc, | 724 | int fimc_vid_cap_buf_queue(struct fimc_dev *fimc, |
725 | struct fimc_vid_buffer *fimc_vb); | 725 | struct fimc_vid_buffer *fimc_vb); |
726 | void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification, | ||
727 | void *arg); | ||
726 | int fimc_capture_suspend(struct fimc_dev *fimc); | 728 | int fimc_capture_suspend(struct fimc_dev *fimc); |
727 | int fimc_capture_resume(struct fimc_dev *fimc); | 729 | int fimc_capture_resume(struct fimc_dev *fimc); |
728 | int fimc_capture_config_update(struct fimc_ctx *ctx); | 730 | int 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_ */ |