aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vimc/vimc-sensor.c
diff options
context:
space:
mode:
authorLucas A. M. Magalhães <lucmaga@gmail.com>2019-01-21 20:05:01 -0500
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-02-07 12:23:09 -0500
commitadc589d2a20808fb99d46a78175cd023f2040338 (patch)
treed31919d178d5b9a82a3be8fb9aea4a2e74742e66 /drivers/media/platform/vimc/vimc-sensor.c
parent276c1f066bdaaed6fe82ed231e1eff2f41c34882 (diff)
media: vimc: Add vimc-streamer for stream control
Add a linear pipeline logic for the stream control. It's created by walking backwards on the entity graph. When the stream starts it will simply loop through the pipeline calling the respective process_frame function of each entity. Fixes: f2fe89061d797 ("vimc: Virtual Media Controller core, capture and sensor") Cc: stable@vger.kernel.org # for v4.20 Signed-off-by: Lucas A. M. Magalhães <lucmaga@gmail.com> Acked-by: Helen Koike <helen.koike@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> [hverkuil-cisco@xs4all.nl: fixed small space-after-tab issue in the patch] Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/platform/vimc/vimc-sensor.c')
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c56
1 files changed, 13 insertions, 43 deletions
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index 32ca9c6172b1..93961a1e694f 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -16,8 +16,6 @@
16 */ 16 */
17 17
18#include <linux/component.h> 18#include <linux/component.h>
19#include <linux/freezer.h>
20#include <linux/kthread.h>
21#include <linux/module.h> 19#include <linux/module.h>
22#include <linux/mod_devicetable.h> 20#include <linux/mod_devicetable.h>
23#include <linux/platform_device.h> 21#include <linux/platform_device.h>
@@ -201,38 +199,27 @@ static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
201 .set_fmt = vimc_sen_set_fmt, 199 .set_fmt = vimc_sen_set_fmt,
202}; 200};
203 201
204static int vimc_sen_tpg_thread(void *data) 202static void *vimc_sen_process_frame(struct vimc_ent_device *ved,
203 const void *sink_frame)
205{ 204{
206 struct vimc_sen_device *vsen = data; 205 struct vimc_sen_device *vsen = container_of(ved, struct vimc_sen_device,
207 unsigned int i; 206 ved);
208 207 const struct vimc_pix_map *vpix;
209 set_freezable(); 208 unsigned int frame_size;
210 set_current_state(TASK_UNINTERRUPTIBLE);
211
212 for (;;) {
213 try_to_freeze();
214 if (kthread_should_stop())
215 break;
216
217 tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
218 209
219 /* Send the frame to all source pads */ 210 /* Calculate the frame size */
220 for (i = 0; i < vsen->sd.entity.num_pads; i++) 211 vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
221 vimc_propagate_frame(&vsen->sd.entity.pads[i], 212 frame_size = vsen->mbus_format.width * vpix->bpp *
222 vsen->frame); 213 vsen->mbus_format.height;
223 214
224 /* 60 frames per second */ 215 tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
225 schedule_timeout(HZ/60); 216 return vsen->frame;
226 }
227
228 return 0;
229} 217}
230 218
231static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) 219static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
232{ 220{
233 struct vimc_sen_device *vsen = 221 struct vimc_sen_device *vsen =
234 container_of(sd, struct vimc_sen_device, sd); 222 container_of(sd, struct vimc_sen_device, sd);
235 int ret;
236 223
237 if (enable) { 224 if (enable) {
238 const struct vimc_pix_map *vpix; 225 const struct vimc_pix_map *vpix;
@@ -258,26 +245,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
258 /* configure the test pattern generator */ 245 /* configure the test pattern generator */
259 vimc_sen_tpg_s_format(vsen); 246 vimc_sen_tpg_s_format(vsen);
260 247
261 /* Initialize the image generator thread */
262 vsen->kthread_sen = kthread_run(vimc_sen_tpg_thread, vsen,
263 "%s-sen", vsen->sd.v4l2_dev->name);
264 if (IS_ERR(vsen->kthread_sen)) {
265 dev_err(vsen->dev, "%s: kernel_thread() failed\n",
266 vsen->sd.name);
267 vfree(vsen->frame);
268 vsen->frame = NULL;
269 return PTR_ERR(vsen->kthread_sen);
270 }
271 } else { 248 } else {
272 if (!vsen->kthread_sen)
273 return 0;
274
275 /* Stop image generator */
276 ret = kthread_stop(vsen->kthread_sen);
277 if (ret)
278 return ret;
279 249
280 vsen->kthread_sen = NULL;
281 vfree(vsen->frame); 250 vfree(vsen->frame);
282 vsen->frame = NULL; 251 vsen->frame = NULL;
283 return 0; 252 return 0;
@@ -413,6 +382,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
413 if (ret) 382 if (ret)
414 goto err_free_hdl; 383 goto err_free_hdl;
415 384
385 vsen->ved.process_frame = vimc_sen_process_frame;
416 dev_set_drvdata(comp, &vsen->ved); 386 dev_set_drvdata(comp, &vsen->ved);
417 vsen->dev = comp; 387 vsen->dev = comp;
418 388