Drivers: media: remove __dev* attributes.
[deliverable/linux.git] / drivers / media / platform / s5p-fimc / fimc-lite.c
1 /*
2 * Samsung EXYNOS FIMC-LITE (camera host interface) driver
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11 #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
12
13 #include <linux/bug.h>
14 #include <linux/device.h>
15 #include <linux/errno.h>
16 #include <linux/interrupt.h>
17 #include <linux/kernel.h>
18 #include <linux/list.h>
19 #include <linux/module.h>
20 #include <linux/types.h>
21 #include <linux/platform_device.h>
22 #include <linux/pm_runtime.h>
23 #include <linux/slab.h>
24 #include <linux/videodev2.h>
25
26 #include <media/v4l2-device.h>
27 #include <media/v4l2-ioctl.h>
28 #include <media/v4l2-mem2mem.h>
29 #include <media/videobuf2-core.h>
30 #include <media/videobuf2-dma-contig.h>
31 #include <media/s5p_fimc.h>
32
33 #include "fimc-mdevice.h"
34 #include "fimc-core.h"
35 #include "fimc-lite.h"
36 #include "fimc-lite-reg.h"
37
38 static int debug;
39 module_param(debug, int, 0644);
40
41 static const struct fimc_fmt fimc_lite_formats[] = {
42 {
43 .name = "YUV 4:2:2 packed, YCbYCr",
44 .fourcc = V4L2_PIX_FMT_YUYV,
45 .depth = { 16 },
46 .color = FIMC_FMT_YCBYCR422,
47 .memplanes = 1,
48 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
49 }, {
50 .name = "YUV 4:2:2 packed, CbYCrY",
51 .fourcc = V4L2_PIX_FMT_UYVY,
52 .depth = { 16 },
53 .color = FIMC_FMT_CBYCRY422,
54 .memplanes = 1,
55 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
56 }, {
57 .name = "YUV 4:2:2 packed, CrYCbY",
58 .fourcc = V4L2_PIX_FMT_VYUY,
59 .depth = { 16 },
60 .color = FIMC_FMT_CRYCBY422,
61 .memplanes = 1,
62 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
63 }, {
64 .name = "YUV 4:2:2 packed, YCrYCb",
65 .fourcc = V4L2_PIX_FMT_YVYU,
66 .depth = { 16 },
67 .color = FIMC_FMT_YCRYCB422,
68 .memplanes = 1,
69 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
70 }, {
71 .name = "RAW8 (GRBG)",
72 .fourcc = V4L2_PIX_FMT_SGRBG8,
73 .depth = { 8 },
74 .color = FIMC_FMT_RAW8,
75 .memplanes = 1,
76 .mbus_code = V4L2_MBUS_FMT_SGRBG8_1X8,
77 }, {
78 .name = "RAW10 (GRBG)",
79 .fourcc = V4L2_PIX_FMT_SGRBG10,
80 .depth = { 10 },
81 .color = FIMC_FMT_RAW10,
82 .memplanes = 1,
83 .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10,
84 }, {
85 .name = "RAW12 (GRBG)",
86 .fourcc = V4L2_PIX_FMT_SGRBG12,
87 .depth = { 12 },
88 .color = FIMC_FMT_RAW12,
89 .memplanes = 1,
90 .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12,
91 },
92 };
93
94 /**
95 * fimc_lite_find_format - lookup fimc color format by fourcc or media bus code
96 * @pixelformat: fourcc to match, ignored if null
97 * @mbus_code: media bus code to match, ignored if null
98 * @index: index to the fimc_lite_formats array, ignored if negative
99 */
100 static const struct fimc_fmt *fimc_lite_find_format(const u32 *pixelformat,
101 const u32 *mbus_code, int index)
102 {
103 const struct fimc_fmt *fmt, *def_fmt = NULL;
104 unsigned int i;
105 int id = 0;
106
107 if (index >= (int)ARRAY_SIZE(fimc_lite_formats))
108 return NULL;
109
110 for (i = 0; i < ARRAY_SIZE(fimc_lite_formats); ++i) {
111 fmt = &fimc_lite_formats[i];
112 if (pixelformat && fmt->fourcc == *pixelformat)
113 return fmt;
114 if (mbus_code && fmt->mbus_code == *mbus_code)
115 return fmt;
116 if (index == id)
117 def_fmt = fmt;
118 id++;
119 }
120 return def_fmt;
121 }
122
123 static int fimc_lite_hw_init(struct fimc_lite *fimc)
124 {
125 struct fimc_pipeline *pipeline = &fimc->pipeline;
126 struct fimc_sensor_info *sensor;
127 unsigned long flags;
128
129 if (pipeline->subdevs[IDX_SENSOR] == NULL)
130 return -ENXIO;
131
132 if (fimc->fmt == NULL)
133 return -EINVAL;
134
135 sensor = v4l2_get_subdev_hostdata(pipeline->subdevs[IDX_SENSOR]);
136 spin_lock_irqsave(&fimc->slock, flags);
137
138 flite_hw_set_camera_bus(fimc, &sensor->pdata);
139 flite_hw_set_source_format(fimc, &fimc->inp_frame);
140 flite_hw_set_window_offset(fimc, &fimc->inp_frame);
141 flite_hw_set_output_dma(fimc, &fimc->out_frame, true);
142 flite_hw_set_interrupt_mask(fimc);
143 flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
144
145 if (debug > 0)
146 flite_hw_dump_regs(fimc, __func__);
147
148 spin_unlock_irqrestore(&fimc->slock, flags);
149 return 0;
150 }
151
152 /*
153 * Reinitialize the driver so it is ready to start the streaming again.
154 * Set fimc->state to indicate stream off and the hardware shut down state.
155 * If not suspending (@suspend is false), return any buffers to videobuf2.
156 * Otherwise put any owned buffers onto the pending buffers queue, so they
157 * can be re-spun when the device is being resumed. Also perform FIMC
158 * software reset and disable streaming on the whole pipeline if required.
159 */
160 static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
161 {
162 struct flite_buffer *buf;
163 unsigned long flags;
164 bool streaming;
165
166 spin_lock_irqsave(&fimc->slock, flags);
167 streaming = fimc->state & (1 << ST_SENSOR_STREAM);
168
169 fimc->state &= ~(1 << ST_FLITE_RUN | 1 << ST_FLITE_OFF |
170 1 << ST_FLITE_STREAM | 1 << ST_SENSOR_STREAM);
171 if (suspend)
172 fimc->state |= (1 << ST_FLITE_SUSPENDED);
173 else
174 fimc->state &= ~(1 << ST_FLITE_PENDING |
175 1 << ST_FLITE_SUSPENDED);
176
177 /* Release unused buffers */
178 while (!suspend && !list_empty(&fimc->pending_buf_q)) {
179 buf = fimc_lite_pending_queue_pop(fimc);
180 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
181 }
182 /* If suspending put unused buffers onto pending queue */
183 while (!list_empty(&fimc->active_buf_q)) {
184 buf = fimc_lite_active_queue_pop(fimc);
185 if (suspend)
186 fimc_lite_pending_queue_add(fimc, buf);
187 else
188 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
189 }
190
191 spin_unlock_irqrestore(&fimc->slock, flags);
192
193 flite_hw_reset(fimc);
194
195 if (!streaming)
196 return 0;
197
198 return fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 0);
199 }
200
201 static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
202 {
203 unsigned long flags;
204
205 if (!fimc_lite_active(fimc))
206 return 0;
207
208 spin_lock_irqsave(&fimc->slock, flags);
209 set_bit(ST_FLITE_OFF, &fimc->state);
210 flite_hw_capture_stop(fimc);
211 spin_unlock_irqrestore(&fimc->slock, flags);
212
213 wait_event_timeout(fimc->irq_queue,
214 !test_bit(ST_FLITE_OFF, &fimc->state),
215 (2*HZ/10)); /* 200 ms */
216
217 return fimc_lite_reinit(fimc, suspend);
218 }
219
220 /* Must be called with fimc.slock spinlock held. */
221 static void fimc_lite_config_update(struct fimc_lite *fimc)
222 {
223 flite_hw_set_window_offset(fimc, &fimc->inp_frame);
224 flite_hw_set_dma_window(fimc, &fimc->out_frame);
225 flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
226 clear_bit(ST_FLITE_CONFIG, &fimc->state);
227 }
228
229 static irqreturn_t flite_irq_handler(int irq, void *priv)
230 {
231 struct fimc_lite *fimc = priv;
232 struct flite_buffer *vbuf;
233 unsigned long flags;
234 struct timeval *tv;
235 struct timespec ts;
236 u32 intsrc;
237
238 spin_lock_irqsave(&fimc->slock, flags);
239
240 intsrc = flite_hw_get_interrupt_source(fimc);
241 flite_hw_clear_pending_irq(fimc);
242
243 if (test_and_clear_bit(ST_FLITE_OFF, &fimc->state)) {
244 wake_up(&fimc->irq_queue);
245 goto done;
246 }
247
248 if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW) {
249 clear_bit(ST_FLITE_RUN, &fimc->state);
250 fimc->events.data_overflow++;
251 }
252
253 if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND) {
254 flite_hw_clear_last_capture_end(fimc);
255 clear_bit(ST_FLITE_STREAM, &fimc->state);
256 wake_up(&fimc->irq_queue);
257 }
258
259 if (fimc->out_path != FIMC_IO_DMA)
260 goto done;
261
262 if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
263 test_bit(ST_FLITE_RUN, &fimc->state) &&
264 !list_empty(&fimc->active_buf_q) &&
265 !list_empty(&fimc->pending_buf_q)) {
266 vbuf = fimc_lite_active_queue_pop(fimc);
267 ktime_get_ts(&ts);
268 tv = &vbuf->vb.v4l2_buf.timestamp;
269 tv->tv_sec = ts.tv_sec;
270 tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
271 vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
272 vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
273
274 vbuf = fimc_lite_pending_queue_pop(fimc);
275 flite_hw_set_output_addr(fimc, vbuf->paddr);
276 fimc_lite_active_queue_add(fimc, vbuf);
277 }
278
279 if (test_bit(ST_FLITE_CONFIG, &fimc->state))
280 fimc_lite_config_update(fimc);
281
282 if (list_empty(&fimc->pending_buf_q)) {
283 flite_hw_capture_stop(fimc);
284 clear_bit(ST_FLITE_STREAM, &fimc->state);
285 }
286 done:
287 set_bit(ST_FLITE_RUN, &fimc->state);
288 spin_unlock_irqrestore(&fimc->slock, flags);
289 return IRQ_HANDLED;
290 }
291
292 static int start_streaming(struct vb2_queue *q, unsigned int count)
293 {
294 struct fimc_lite *fimc = q->drv_priv;
295 int ret;
296
297 fimc->frame_count = 0;
298
299 ret = fimc_lite_hw_init(fimc);
300 if (ret) {
301 fimc_lite_reinit(fimc, false);
302 return ret;
303 }
304
305 set_bit(ST_FLITE_PENDING, &fimc->state);
306
307 if (!list_empty(&fimc->active_buf_q) &&
308 !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
309 flite_hw_capture_start(fimc);
310
311 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
312 fimc_pipeline_call(fimc, set_stream,
313 &fimc->pipeline, 1);
314 }
315 if (debug > 0)
316 flite_hw_dump_regs(fimc, __func__);
317
318 return 0;
319 }
320
321 static int stop_streaming(struct vb2_queue *q)
322 {
323 struct fimc_lite *fimc = q->drv_priv;
324
325 if (!fimc_lite_active(fimc))
326 return -EINVAL;
327
328 return fimc_lite_stop_capture(fimc, false);
329 }
330
331 static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
332 unsigned int *num_buffers, unsigned int *num_planes,
333 unsigned int sizes[], void *allocators[])
334 {
335 const struct v4l2_pix_format_mplane *pixm = NULL;
336 struct fimc_lite *fimc = vq->drv_priv;
337 struct flite_frame *frame = &fimc->out_frame;
338 const struct fimc_fmt *fmt = fimc->fmt;
339 unsigned long wh;
340 int i;
341
342 if (pfmt) {
343 pixm = &pfmt->fmt.pix_mp;
344 fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, -1);
345 wh = pixm->width * pixm->height;
346 } else {
347 wh = frame->f_width * frame->f_height;
348 }
349
350 if (fmt == NULL)
351 return -EINVAL;
352
353 *num_planes = fmt->memplanes;
354
355 for (i = 0; i < fmt->memplanes; i++) {
356 unsigned int size = (wh * fmt->depth[i]) / 8;
357 if (pixm)
358 sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
359 else
360 sizes[i] = size;
361 allocators[i] = fimc->alloc_ctx;
362 }
363
364 return 0;
365 }
366
367 static int buffer_prepare(struct vb2_buffer *vb)
368 {
369 struct vb2_queue *vq = vb->vb2_queue;
370 struct fimc_lite *fimc = vq->drv_priv;
371 int i;
372
373 if (fimc->fmt == NULL)
374 return -EINVAL;
375
376 for (i = 0; i < fimc->fmt->memplanes; i++) {
377 unsigned long size = fimc->payload[i];
378
379 if (vb2_plane_size(vb, i) < size) {
380 v4l2_err(&fimc->vfd,
381 "User buffer too small (%ld < %ld)\n",
382 vb2_plane_size(vb, i), size);
383 return -EINVAL;
384 }
385 vb2_set_plane_payload(vb, i, size);
386 }
387
388 return 0;
389 }
390
391 static void buffer_queue(struct vb2_buffer *vb)
392 {
393 struct flite_buffer *buf
394 = container_of(vb, struct flite_buffer, vb);
395 struct fimc_lite *fimc = vb2_get_drv_priv(vb->vb2_queue);
396 unsigned long flags;
397
398 spin_lock_irqsave(&fimc->slock, flags);
399 buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
400
401 if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
402 !test_bit(ST_FLITE_STREAM, &fimc->state) &&
403 list_empty(&fimc->active_buf_q)) {
404 flite_hw_set_output_addr(fimc, buf->paddr);
405 fimc_lite_active_queue_add(fimc, buf);
406 } else {
407 fimc_lite_pending_queue_add(fimc, buf);
408 }
409
410 if (vb2_is_streaming(&fimc->vb_queue) &&
411 !list_empty(&fimc->pending_buf_q) &&
412 !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
413 flite_hw_capture_start(fimc);
414 spin_unlock_irqrestore(&fimc->slock, flags);
415
416 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
417 fimc_pipeline_call(fimc, set_stream,
418 &fimc->pipeline, 1);
419 return;
420 }
421 spin_unlock_irqrestore(&fimc->slock, flags);
422 }
423
424 static void fimc_lock(struct vb2_queue *vq)
425 {
426 struct fimc_lite *fimc = vb2_get_drv_priv(vq);
427 mutex_lock(&fimc->lock);
428 }
429
430 static void fimc_unlock(struct vb2_queue *vq)
431 {
432 struct fimc_lite *fimc = vb2_get_drv_priv(vq);
433 mutex_unlock(&fimc->lock);
434 }
435
436 static const struct vb2_ops fimc_lite_qops = {
437 .queue_setup = queue_setup,
438 .buf_prepare = buffer_prepare,
439 .buf_queue = buffer_queue,
440 .wait_prepare = fimc_unlock,
441 .wait_finish = fimc_lock,
442 .start_streaming = start_streaming,
443 .stop_streaming = stop_streaming,
444 };
445
446 static void fimc_lite_clear_event_counters(struct fimc_lite *fimc)
447 {
448 unsigned long flags;
449
450 spin_lock_irqsave(&fimc->slock, flags);
451 memset(&fimc->events, 0, sizeof(fimc->events));
452 spin_unlock_irqrestore(&fimc->slock, flags);
453 }
454
455 static int fimc_lite_open(struct file *file)
456 {
457 struct fimc_lite *fimc = video_drvdata(file);
458 int ret;
459
460 if (mutex_lock_interruptible(&fimc->lock))
461 return -ERESTARTSYS;
462
463 set_bit(ST_FLITE_IN_USE, &fimc->state);
464 ret = pm_runtime_get_sync(&fimc->pdev->dev);
465 if (ret < 0)
466 goto done;
467
468 ret = v4l2_fh_open(file);
469 if (ret < 0)
470 goto done;
471
472 if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) {
473 ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
474 &fimc->vfd.entity, true);
475 if (ret < 0) {
476 pm_runtime_put_sync(&fimc->pdev->dev);
477 fimc->ref_count--;
478 v4l2_fh_release(file);
479 clear_bit(ST_FLITE_IN_USE, &fimc->state);
480 }
481
482 fimc_lite_clear_event_counters(fimc);
483 }
484 done:
485 mutex_unlock(&fimc->lock);
486 return ret;
487 }
488
489 static int fimc_lite_close(struct file *file)
490 {
491 struct fimc_lite *fimc = video_drvdata(file);
492 int ret;
493
494 mutex_lock(&fimc->lock);
495
496 if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
497 clear_bit(ST_FLITE_IN_USE, &fimc->state);
498 fimc_lite_stop_capture(fimc, false);
499 fimc_pipeline_call(fimc, close, &fimc->pipeline);
500 clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
501 }
502
503 pm_runtime_put(&fimc->pdev->dev);
504
505 if (fimc->ref_count == 0)
506 vb2_queue_release(&fimc->vb_queue);
507
508 ret = v4l2_fh_release(file);
509
510 mutex_unlock(&fimc->lock);
511 return ret;
512 }
513
514 static unsigned int fimc_lite_poll(struct file *file,
515 struct poll_table_struct *wait)
516 {
517 struct fimc_lite *fimc = video_drvdata(file);
518 int ret;
519
520 if (mutex_lock_interruptible(&fimc->lock))
521 return POLL_ERR;
522
523 ret = vb2_poll(&fimc->vb_queue, file, wait);
524 mutex_unlock(&fimc->lock);
525
526 return ret;
527 }
528
529 static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma)
530 {
531 struct fimc_lite *fimc = video_drvdata(file);
532 int ret;
533
534 if (mutex_lock_interruptible(&fimc->lock))
535 return -ERESTARTSYS;
536
537 ret = vb2_mmap(&fimc->vb_queue, vma);
538 mutex_unlock(&fimc->lock);
539
540 return ret;
541 }
542
543 static const struct v4l2_file_operations fimc_lite_fops = {
544 .owner = THIS_MODULE,
545 .open = fimc_lite_open,
546 .release = fimc_lite_close,
547 .poll = fimc_lite_poll,
548 .unlocked_ioctl = video_ioctl2,
549 .mmap = fimc_lite_mmap,
550 };
551
552 /*
553 * Format and crop negotiation helpers
554 */
555
556 static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
557 u32 *width, u32 *height,
558 u32 *code, u32 *fourcc, int pad)
559 {
560 struct flite_variant *variant = fimc->variant;
561 const struct fimc_fmt *fmt;
562
563 fmt = fimc_lite_find_format(fourcc, code, 0);
564 if (WARN_ON(!fmt))
565 return NULL;
566
567 if (code)
568 *code = fmt->mbus_code;
569 if (fourcc)
570 *fourcc = fmt->fourcc;
571
572 if (pad == FLITE_SD_PAD_SINK) {
573 v4l_bound_align_image(width, 8, variant->max_width,
574 ffs(variant->out_width_align) - 1,
575 height, 0, variant->max_height, 0, 0);
576 } else {
577 v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
578 ffs(variant->out_width_align) - 1,
579 height, 0, fimc->inp_frame.rect.height,
580 0, 0);
581 }
582
583 v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
584 code ? *code : 0, *width, *height);
585
586 return fmt;
587 }
588
589 static void fimc_lite_try_crop(struct fimc_lite *fimc, struct v4l2_rect *r)
590 {
591 struct flite_frame *frame = &fimc->inp_frame;
592
593 v4l_bound_align_image(&r->width, 0, frame->f_width, 0,
594 &r->height, 0, frame->f_height, 0, 0);
595
596 /* Adjust left/top if cropping rectangle got out of bounds */
597 r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
598 r->left = round_down(r->left, fimc->variant->win_hor_offs_align);
599 r->top = clamp_t(u32, r->top, 0, frame->f_height - r->height);
600
601 v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, sink fmt: %dx%d",
602 r->left, r->top, r->width, r->height,
603 frame->f_width, frame->f_height);
604 }
605
606 static void fimc_lite_try_compose(struct fimc_lite *fimc, struct v4l2_rect *r)
607 {
608 struct flite_frame *frame = &fimc->out_frame;
609 struct v4l2_rect *crop_rect = &fimc->inp_frame.rect;
610
611 /* Scaling is not supported so we enforce compose rectangle size
612 same as size of the sink crop rectangle. */
613 r->width = crop_rect->width;
614 r->height = crop_rect->height;
615
616 /* Adjust left/top if the composing rectangle got out of bounds */
617 r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
618 r->left = round_down(r->left, fimc->variant->out_hor_offs_align);
619 r->top = clamp_t(u32, r->top, 0, fimc->out_frame.f_height - r->height);
620
621 v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, source fmt: %dx%d",
622 r->left, r->top, r->width, r->height,
623 frame->f_width, frame->f_height);
624 }
625
626 /*
627 * Video node ioctl operations
628 */
629 static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
630 struct v4l2_capability *cap)
631 {
632 strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
633 cap->bus_info[0] = 0;
634 cap->card[0] = 0;
635 cap->capabilities = V4L2_CAP_STREAMING;
636 return 0;
637 }
638
639 static int fimc_lite_enum_fmt_mplane(struct file *file, void *priv,
640 struct v4l2_fmtdesc *f)
641 {
642 const struct fimc_fmt *fmt;
643
644 if (f->index >= ARRAY_SIZE(fimc_lite_formats))
645 return -EINVAL;
646
647 fmt = &fimc_lite_formats[f->index];
648 strlcpy(f->description, fmt->name, sizeof(f->description));
649 f->pixelformat = fmt->fourcc;
650
651 return 0;
652 }
653
654 static int fimc_lite_g_fmt_mplane(struct file *file, void *fh,
655 struct v4l2_format *f)
656 {
657 struct fimc_lite *fimc = video_drvdata(file);
658 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
659 struct v4l2_plane_pix_format *plane_fmt = &pixm->plane_fmt[0];
660 struct flite_frame *frame = &fimc->out_frame;
661 const struct fimc_fmt *fmt = fimc->fmt;
662
663 plane_fmt->bytesperline = (frame->f_width * fmt->depth[0]) / 8;
664 plane_fmt->sizeimage = plane_fmt->bytesperline * frame->f_height;
665
666 pixm->num_planes = fmt->memplanes;
667 pixm->pixelformat = fmt->fourcc;
668 pixm->width = frame->f_width;
669 pixm->height = frame->f_height;
670 pixm->field = V4L2_FIELD_NONE;
671 pixm->colorspace = V4L2_COLORSPACE_JPEG;
672 return 0;
673 }
674
675 static int fimc_lite_try_fmt(struct fimc_lite *fimc,
676 struct v4l2_pix_format_mplane *pixm,
677 const struct fimc_fmt **ffmt)
678 {
679 struct flite_variant *variant = fimc->variant;
680 u32 bpl = pixm->plane_fmt[0].bytesperline;
681 const struct fimc_fmt *fmt;
682
683 fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, 0);
684 if (WARN_ON(fmt == NULL))
685 return -EINVAL;
686 if (ffmt)
687 *ffmt = fmt;
688 v4l_bound_align_image(&pixm->width, 8, variant->max_width,
689 ffs(variant->out_width_align) - 1,
690 &pixm->height, 0, variant->max_height, 0, 0);
691
692 if ((bpl == 0 || ((bpl * 8) / fmt->depth[0]) < pixm->width))
693 pixm->plane_fmt[0].bytesperline = (pixm->width *
694 fmt->depth[0]) / 8;
695
696 if (pixm->plane_fmt[0].sizeimage == 0)
697 pixm->plane_fmt[0].sizeimage = (pixm->width * pixm->height *
698 fmt->depth[0]) / 8;
699 pixm->num_planes = fmt->memplanes;
700 pixm->pixelformat = fmt->fourcc;
701 pixm->colorspace = V4L2_COLORSPACE_JPEG;
702 pixm->field = V4L2_FIELD_NONE;
703 return 0;
704 }
705
706 static int fimc_lite_try_fmt_mplane(struct file *file, void *fh,
707 struct v4l2_format *f)
708 {
709 struct fimc_lite *fimc = video_drvdata(file);
710
711 return fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, NULL);
712 }
713
714 static int fimc_lite_s_fmt_mplane(struct file *file, void *priv,
715 struct v4l2_format *f)
716 {
717 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
718 struct fimc_lite *fimc = video_drvdata(file);
719 struct flite_frame *frame = &fimc->out_frame;
720 const struct fimc_fmt *fmt = NULL;
721 int ret;
722
723 if (vb2_is_busy(&fimc->vb_queue))
724 return -EBUSY;
725
726 ret = fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, &fmt);
727 if (ret < 0)
728 return ret;
729
730 fimc->fmt = fmt;
731 fimc->payload[0] = max((pixm->width * pixm->height * fmt->depth[0]) / 8,
732 pixm->plane_fmt[0].sizeimage);
733 frame->f_width = pixm->width;
734 frame->f_height = pixm->height;
735
736 return 0;
737 }
738
739 static int fimc_pipeline_validate(struct fimc_lite *fimc)
740 {
741 struct v4l2_subdev *sd = &fimc->subdev;
742 struct v4l2_subdev_format sink_fmt, src_fmt;
743 struct media_pad *pad;
744 int ret;
745
746 while (1) {
747 /* Retrieve format at the sink pad */
748 pad = &sd->entity.pads[0];
749 if (!(pad->flags & MEDIA_PAD_FL_SINK))
750 break;
751 /* Don't call FIMC subdev operation to avoid nested locking */
752 if (sd == &fimc->subdev) {
753 struct flite_frame *ff = &fimc->out_frame;
754 sink_fmt.format.width = ff->f_width;
755 sink_fmt.format.height = ff->f_height;
756 sink_fmt.format.code = fimc->fmt->mbus_code;
757 } else {
758 sink_fmt.pad = pad->index;
759 sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
760 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
761 &sink_fmt);
762 if (ret < 0 && ret != -ENOIOCTLCMD)
763 return -EPIPE;
764 }
765 /* Retrieve format at the source pad */
766 pad = media_entity_remote_source(pad);
767 if (pad == NULL ||
768 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
769 break;
770
771 sd = media_entity_to_v4l2_subdev(pad->entity);
772 src_fmt.pad = pad->index;
773 src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
774 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
775 if (ret < 0 && ret != -ENOIOCTLCMD)
776 return -EPIPE;
777
778 if (src_fmt.format.width != sink_fmt.format.width ||
779 src_fmt.format.height != sink_fmt.format.height ||
780 src_fmt.format.code != sink_fmt.format.code)
781 return -EPIPE;
782 }
783 return 0;
784 }
785
786 static int fimc_lite_streamon(struct file *file, void *priv,
787 enum v4l2_buf_type type)
788 {
789 struct fimc_lite *fimc = video_drvdata(file);
790 struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
791 struct fimc_pipeline *p = &fimc->pipeline;
792 int ret;
793
794 if (fimc_lite_active(fimc))
795 return -EBUSY;
796
797 ret = media_entity_pipeline_start(&sensor->entity, p->m_pipeline);
798 if (ret < 0)
799 return ret;
800
801 ret = fimc_pipeline_validate(fimc);
802 if (ret) {
803 media_entity_pipeline_stop(&sensor->entity);
804 return ret;
805 }
806
807 return vb2_streamon(&fimc->vb_queue, type);
808 }
809
810 static int fimc_lite_streamoff(struct file *file, void *priv,
811 enum v4l2_buf_type type)
812 {
813 struct fimc_lite *fimc = video_drvdata(file);
814 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
815 int ret;
816
817 ret = vb2_streamoff(&fimc->vb_queue, type);
818 if (ret == 0)
819 media_entity_pipeline_stop(&sd->entity);
820 return ret;
821 }
822
823 static int fimc_lite_reqbufs(struct file *file, void *priv,
824 struct v4l2_requestbuffers *reqbufs)
825 {
826 struct fimc_lite *fimc = video_drvdata(file);
827 int ret;
828
829 reqbufs->count = max_t(u32, FLITE_REQ_BUFS_MIN, reqbufs->count);
830 ret = vb2_reqbufs(&fimc->vb_queue, reqbufs);
831 if (!ret)
832 fimc->reqbufs_count = reqbufs->count;
833
834 return ret;
835 }
836
837 static int fimc_lite_querybuf(struct file *file, void *priv,
838 struct v4l2_buffer *buf)
839 {
840 struct fimc_lite *fimc = video_drvdata(file);
841
842 return vb2_querybuf(&fimc->vb_queue, buf);
843 }
844
845 static int fimc_lite_qbuf(struct file *file, void *priv,
846 struct v4l2_buffer *buf)
847 {
848 struct fimc_lite *fimc = video_drvdata(file);
849
850 return vb2_qbuf(&fimc->vb_queue, buf);
851 }
852
853 static int fimc_lite_dqbuf(struct file *file, void *priv,
854 struct v4l2_buffer *buf)
855 {
856 struct fimc_lite *fimc = video_drvdata(file);
857
858 return vb2_dqbuf(&fimc->vb_queue, buf, file->f_flags & O_NONBLOCK);
859 }
860
861 static int fimc_lite_create_bufs(struct file *file, void *priv,
862 struct v4l2_create_buffers *create)
863 {
864 struct fimc_lite *fimc = video_drvdata(file);
865
866 return vb2_create_bufs(&fimc->vb_queue, create);
867 }
868
869 static int fimc_lite_prepare_buf(struct file *file, void *priv,
870 struct v4l2_buffer *b)
871 {
872 struct fimc_lite *fimc = video_drvdata(file);
873
874 return vb2_prepare_buf(&fimc->vb_queue, b);
875 }
876
877 /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
878 static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
879 {
880 if (a->left < b->left || a->top < b->top)
881 return 0;
882 if (a->left + a->width > b->left + b->width)
883 return 0;
884 if (a->top + a->height > b->top + b->height)
885 return 0;
886
887 return 1;
888 }
889
890 static int fimc_lite_g_selection(struct file *file, void *fh,
891 struct v4l2_selection *sel)
892 {
893 struct fimc_lite *fimc = video_drvdata(file);
894 struct flite_frame *f = &fimc->out_frame;
895
896 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
897 return -EINVAL;
898
899 switch (sel->target) {
900 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
901 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
902 sel->r.left = 0;
903 sel->r.top = 0;
904 sel->r.width = f->f_width;
905 sel->r.height = f->f_height;
906 return 0;
907
908 case V4L2_SEL_TGT_COMPOSE:
909 sel->r = f->rect;
910 return 0;
911 }
912
913 return -EINVAL;
914 }
915
916 static int fimc_lite_s_selection(struct file *file, void *fh,
917 struct v4l2_selection *sel)
918 {
919 struct fimc_lite *fimc = video_drvdata(file);
920 struct flite_frame *f = &fimc->out_frame;
921 struct v4l2_rect rect = sel->r;
922 unsigned long flags;
923
924 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
925 sel->target != V4L2_SEL_TGT_COMPOSE)
926 return -EINVAL;
927
928 fimc_lite_try_compose(fimc, &rect);
929
930 if ((sel->flags & V4L2_SEL_FLAG_LE) &&
931 !enclosed_rectangle(&rect, &sel->r))
932 return -ERANGE;
933
934 if ((sel->flags & V4L2_SEL_FLAG_GE) &&
935 !enclosed_rectangle(&sel->r, &rect))
936 return -ERANGE;
937
938 sel->r = rect;
939 spin_lock_irqsave(&fimc->slock, flags);
940 f->rect = rect;
941 set_bit(ST_FLITE_CONFIG, &fimc->state);
942 spin_unlock_irqrestore(&fimc->slock, flags);
943
944 return 0;
945 }
946
947 static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
948 .vidioc_querycap = fimc_vidioc_querycap_capture,
949 .vidioc_enum_fmt_vid_cap_mplane = fimc_lite_enum_fmt_mplane,
950 .vidioc_try_fmt_vid_cap_mplane = fimc_lite_try_fmt_mplane,
951 .vidioc_s_fmt_vid_cap_mplane = fimc_lite_s_fmt_mplane,
952 .vidioc_g_fmt_vid_cap_mplane = fimc_lite_g_fmt_mplane,
953 .vidioc_g_selection = fimc_lite_g_selection,
954 .vidioc_s_selection = fimc_lite_s_selection,
955 .vidioc_reqbufs = fimc_lite_reqbufs,
956 .vidioc_querybuf = fimc_lite_querybuf,
957 .vidioc_prepare_buf = fimc_lite_prepare_buf,
958 .vidioc_create_bufs = fimc_lite_create_bufs,
959 .vidioc_qbuf = fimc_lite_qbuf,
960 .vidioc_dqbuf = fimc_lite_dqbuf,
961 .vidioc_streamon = fimc_lite_streamon,
962 .vidioc_streamoff = fimc_lite_streamoff,
963 };
964
965 /* Capture subdev media entity operations */
966 static int fimc_lite_link_setup(struct media_entity *entity,
967 const struct media_pad *local,
968 const struct media_pad *remote, u32 flags)
969 {
970 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
971 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
972 unsigned int remote_ent_type = media_entity_type(remote->entity);
973
974 if (WARN_ON(fimc == NULL))
975 return 0;
976
977 v4l2_dbg(1, debug, sd, "%s: %s --> %s, flags: 0x%x. source_id: 0x%x",
978 __func__, local->entity->name, remote->entity->name,
979 flags, fimc->source_subdev_grp_id);
980
981 switch (local->index) {
982 case FIMC_SD_PAD_SINK:
983 if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV)
984 return -EINVAL;
985
986 if (flags & MEDIA_LNK_FL_ENABLED) {
987 if (fimc->source_subdev_grp_id != 0)
988 return -EBUSY;
989 fimc->source_subdev_grp_id = sd->grp_id;
990 return 0;
991 }
992
993 fimc->source_subdev_grp_id = 0;
994 break;
995
996 case FIMC_SD_PAD_SOURCE:
997 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
998 fimc->out_path = FIMC_IO_NONE;
999 return 0;
1000 }
1001 if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
1002 fimc->out_path = FIMC_IO_ISP;
1003 else
1004 fimc->out_path = FIMC_IO_DMA;
1005 break;
1006
1007 default:
1008 v4l2_err(sd, "Invalid pad index\n");
1009 return -EINVAL;
1010 }
1011
1012 return 0;
1013 }
1014
1015 static const struct media_entity_operations fimc_lite_subdev_media_ops = {
1016 .link_setup = fimc_lite_link_setup,
1017 };
1018
1019 static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1020 struct v4l2_subdev_fh *fh,
1021 struct v4l2_subdev_mbus_code_enum *code)
1022 {
1023 const struct fimc_fmt *fmt;
1024
1025 fmt = fimc_lite_find_format(NULL, NULL, code->index);
1026 if (!fmt)
1027 return -EINVAL;
1028 code->code = fmt->mbus_code;
1029 return 0;
1030 }
1031
1032 static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
1033 struct v4l2_subdev_fh *fh,
1034 struct v4l2_subdev_format *fmt)
1035 {
1036 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1037 struct v4l2_mbus_framefmt *mf = &fmt->format;
1038 struct flite_frame *f = &fimc->out_frame;
1039
1040 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1041 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1042 fmt->format = *mf;
1043 return 0;
1044 }
1045 mf->colorspace = V4L2_COLORSPACE_JPEG;
1046
1047 mutex_lock(&fimc->lock);
1048 mf->code = fimc->fmt->mbus_code;
1049
1050 if (fmt->pad == FLITE_SD_PAD_SINK) {
1051 /* full camera input frame size */
1052 mf->width = f->f_width;
1053 mf->height = f->f_height;
1054 } else {
1055 /* crop size */
1056 mf->width = f->rect.width;
1057 mf->height = f->rect.height;
1058 }
1059 mutex_unlock(&fimc->lock);
1060 return 0;
1061 }
1062
1063 static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
1064 struct v4l2_subdev_fh *fh,
1065 struct v4l2_subdev_format *fmt)
1066 {
1067 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1068 struct v4l2_mbus_framefmt *mf = &fmt->format;
1069 struct flite_frame *sink = &fimc->inp_frame;
1070 struct flite_frame *source = &fimc->out_frame;
1071 const struct fimc_fmt *ffmt;
1072
1073 v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d",
1074 fmt->pad, mf->code, mf->width, mf->height);
1075
1076 mf->colorspace = V4L2_COLORSPACE_JPEG;
1077 mutex_lock(&fimc->lock);
1078
1079 if ((fimc->out_path == FIMC_IO_ISP && sd->entity.stream_count > 0) ||
1080 (fimc->out_path == FIMC_IO_DMA && vb2_is_busy(&fimc->vb_queue))) {
1081 mutex_unlock(&fimc->lock);
1082 return -EBUSY;
1083 }
1084
1085 ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
1086 &mf->code, NULL, fmt->pad);
1087
1088 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1089 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1090 *mf = fmt->format;
1091 mutex_unlock(&fimc->lock);
1092 return 0;
1093 }
1094
1095 if (fmt->pad == FLITE_SD_PAD_SINK) {
1096 sink->f_width = mf->width;
1097 sink->f_height = mf->height;
1098 fimc->fmt = ffmt;
1099 /* Set sink crop rectangle */
1100 sink->rect.width = mf->width;
1101 sink->rect.height = mf->height;
1102 sink->rect.left = 0;
1103 sink->rect.top = 0;
1104 /* Reset source format and crop rectangle */
1105 source->rect = sink->rect;
1106 source->f_width = mf->width;
1107 source->f_height = mf->height;
1108 } else {
1109 /* Allow changing format only on sink pad */
1110 mf->code = fimc->fmt->mbus_code;
1111 mf->width = sink->rect.width;
1112 mf->height = sink->rect.height;
1113 }
1114
1115 mutex_unlock(&fimc->lock);
1116 return 0;
1117 }
1118
1119 static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
1120 struct v4l2_subdev_fh *fh,
1121 struct v4l2_subdev_selection *sel)
1122 {
1123 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1124 struct flite_frame *f = &fimc->inp_frame;
1125
1126 if ((sel->target != V4L2_SEL_TGT_CROP &&
1127 sel->target != V4L2_SEL_TGT_CROP_BOUNDS) ||
1128 sel->pad != FLITE_SD_PAD_SINK)
1129 return -EINVAL;
1130
1131 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1132 sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
1133 return 0;
1134 }
1135
1136 mutex_lock(&fimc->lock);
1137 if (sel->target == V4L2_SEL_TGT_CROP) {
1138 sel->r = f->rect;
1139 } else {
1140 sel->r.left = 0;
1141 sel->r.top = 0;
1142 sel->r.width = f->f_width;
1143 sel->r.height = f->f_height;
1144 }
1145 mutex_unlock(&fimc->lock);
1146
1147 v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
1148 __func__, f->rect.left, f->rect.top, f->rect.width,
1149 f->rect.height, f->f_width, f->f_height);
1150
1151 return 0;
1152 }
1153
1154 static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
1155 struct v4l2_subdev_fh *fh,
1156 struct v4l2_subdev_selection *sel)
1157 {
1158 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1159 struct flite_frame *f = &fimc->inp_frame;
1160 int ret = 0;
1161
1162 if (sel->target != V4L2_SEL_TGT_CROP || sel->pad != FLITE_SD_PAD_SINK)
1163 return -EINVAL;
1164
1165 mutex_lock(&fimc->lock);
1166 fimc_lite_try_crop(fimc, &sel->r);
1167
1168 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1169 *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r;
1170 } else {
1171 unsigned long flags;
1172 spin_lock_irqsave(&fimc->slock, flags);
1173 f->rect = sel->r;
1174 /* Same crop rectangle on the source pad */
1175 fimc->out_frame.rect = sel->r;
1176 set_bit(ST_FLITE_CONFIG, &fimc->state);
1177 spin_unlock_irqrestore(&fimc->slock, flags);
1178 }
1179 mutex_unlock(&fimc->lock);
1180
1181 v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
1182 __func__, f->rect.left, f->rect.top, f->rect.width,
1183 f->rect.height, f->f_width, f->f_height);
1184
1185 return ret;
1186 }
1187
1188 static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
1189 {
1190 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1191
1192 if (fimc->out_path == FIMC_IO_DMA)
1193 return -ENOIOCTLCMD;
1194
1195 /* TODO: */
1196
1197 return 0;
1198 }
1199
1200 static int fimc_lite_subdev_s_power(struct v4l2_subdev *sd, int on)
1201 {
1202 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1203
1204 if (fimc->out_path == FIMC_IO_DMA)
1205 return -ENOIOCTLCMD;
1206
1207 /* TODO: */
1208
1209 return 0;
1210 }
1211
1212 static int fimc_lite_log_status(struct v4l2_subdev *sd)
1213 {
1214 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1215
1216 flite_hw_dump_regs(fimc, __func__);
1217 return 0;
1218 }
1219
1220 static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
1221 {
1222 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1223 struct vb2_queue *q = &fimc->vb_queue;
1224 struct video_device *vfd = &fimc->vfd;
1225 int ret;
1226
1227 memset(vfd, 0, sizeof(*vfd));
1228
1229 fimc->fmt = &fimc_lite_formats[0];
1230 fimc->out_path = FIMC_IO_DMA;
1231
1232 snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
1233 fimc->index);
1234
1235 vfd->fops = &fimc_lite_fops;
1236 vfd->ioctl_ops = &fimc_lite_ioctl_ops;
1237 vfd->v4l2_dev = sd->v4l2_dev;
1238 vfd->minor = -1;
1239 vfd->release = video_device_release_empty;
1240 vfd->lock = &fimc->lock;
1241 fimc->ref_count = 0;
1242 fimc->reqbufs_count = 0;
1243
1244 INIT_LIST_HEAD(&fimc->pending_buf_q);
1245 INIT_LIST_HEAD(&fimc->active_buf_q);
1246
1247 memset(q, 0, sizeof(*q));
1248 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1249 q->io_modes = VB2_MMAP | VB2_USERPTR;
1250 q->ops = &fimc_lite_qops;
1251 q->mem_ops = &vb2_dma_contig_memops;
1252 q->buf_struct_size = sizeof(struct flite_buffer);
1253 q->drv_priv = fimc;
1254
1255 ret = vb2_queue_init(q);
1256 if (ret < 0)
1257 return ret;
1258
1259 fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
1260 ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
1261 if (ret < 0)
1262 return ret;
1263
1264 video_set_drvdata(vfd, fimc);
1265 fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
1266
1267 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
1268 if (ret < 0) {
1269 media_entity_cleanup(&vfd->entity);
1270 fimc->pipeline_ops = NULL;
1271 return ret;
1272 }
1273
1274 v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n",
1275 vfd->name, video_device_node_name(vfd));
1276 return 0;
1277 }
1278
1279 static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
1280 {
1281 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1282
1283 if (fimc == NULL)
1284 return;
1285
1286 if (video_is_registered(&fimc->vfd)) {
1287 video_unregister_device(&fimc->vfd);
1288 media_entity_cleanup(&fimc->vfd.entity);
1289 fimc->pipeline_ops = NULL;
1290 }
1291 }
1292
1293 static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
1294 .registered = fimc_lite_subdev_registered,
1295 .unregistered = fimc_lite_subdev_unregistered,
1296 };
1297
1298 static const struct v4l2_subdev_pad_ops fimc_lite_subdev_pad_ops = {
1299 .enum_mbus_code = fimc_lite_subdev_enum_mbus_code,
1300 .get_selection = fimc_lite_subdev_get_selection,
1301 .set_selection = fimc_lite_subdev_set_selection,
1302 .get_fmt = fimc_lite_subdev_get_fmt,
1303 .set_fmt = fimc_lite_subdev_set_fmt,
1304 };
1305
1306 static const struct v4l2_subdev_video_ops fimc_lite_subdev_video_ops = {
1307 .s_stream = fimc_lite_subdev_s_stream,
1308 };
1309
1310 static const struct v4l2_subdev_core_ops fimc_lite_core_ops = {
1311 .s_power = fimc_lite_subdev_s_power,
1312 .log_status = fimc_lite_log_status,
1313 };
1314
1315 static struct v4l2_subdev_ops fimc_lite_subdev_ops = {
1316 .core = &fimc_lite_core_ops,
1317 .video = &fimc_lite_subdev_video_ops,
1318 .pad = &fimc_lite_subdev_pad_ops,
1319 };
1320
1321 static int fimc_lite_s_ctrl(struct v4l2_ctrl *ctrl)
1322 {
1323 struct fimc_lite *fimc = container_of(ctrl->handler, struct fimc_lite,
1324 ctrl_handler);
1325 set_bit(ST_FLITE_CONFIG, &fimc->state);
1326 return 0;
1327 }
1328
1329 static const struct v4l2_ctrl_ops fimc_lite_ctrl_ops = {
1330 .s_ctrl = fimc_lite_s_ctrl,
1331 };
1332
1333 static const struct v4l2_ctrl_config fimc_lite_ctrl = {
1334 .ops = &fimc_lite_ctrl_ops,
1335 .id = V4L2_CTRL_CLASS_USER | 0x1001,
1336 .type = V4L2_CTRL_TYPE_BOOLEAN,
1337 .name = "Test Pattern 640x480",
1338 };
1339
1340 static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
1341 {
1342 struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
1343 struct v4l2_subdev *sd = &fimc->subdev;
1344 int ret;
1345
1346 v4l2_subdev_init(sd, &fimc_lite_subdev_ops);
1347 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1348 snprintf(sd->name, sizeof(sd->name), "FIMC-LITE.%d", fimc->index);
1349
1350 fimc->subdev_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1351 fimc->subdev_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1352 ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
1353 fimc->subdev_pads, 0);
1354 if (ret)
1355 return ret;
1356
1357 v4l2_ctrl_handler_init(handler, 1);
1358 fimc->test_pattern = v4l2_ctrl_new_custom(handler, &fimc_lite_ctrl,
1359 NULL);
1360 if (handler->error) {
1361 media_entity_cleanup(&sd->entity);
1362 return handler->error;
1363 }
1364
1365 sd->ctrl_handler = handler;
1366 sd->internal_ops = &fimc_lite_subdev_internal_ops;
1367 sd->entity.ops = &fimc_lite_subdev_media_ops;
1368 v4l2_set_subdevdata(sd, fimc);
1369
1370 return 0;
1371 }
1372
1373 static void fimc_lite_unregister_capture_subdev(struct fimc_lite *fimc)
1374 {
1375 struct v4l2_subdev *sd = &fimc->subdev;
1376
1377 v4l2_device_unregister_subdev(sd);
1378 media_entity_cleanup(&sd->entity);
1379 v4l2_ctrl_handler_free(&fimc->ctrl_handler);
1380 v4l2_set_subdevdata(sd, NULL);
1381 }
1382
1383 static void fimc_lite_clk_put(struct fimc_lite *fimc)
1384 {
1385 if (IS_ERR_OR_NULL(fimc->clock))
1386 return;
1387
1388 clk_unprepare(fimc->clock);
1389 clk_put(fimc->clock);
1390 fimc->clock = NULL;
1391 }
1392
1393 static int fimc_lite_clk_get(struct fimc_lite *fimc)
1394 {
1395 int ret;
1396
1397 fimc->clock = clk_get(&fimc->pdev->dev, FLITE_CLK_NAME);
1398 if (IS_ERR(fimc->clock))
1399 return PTR_ERR(fimc->clock);
1400
1401 ret = clk_prepare(fimc->clock);
1402 if (ret < 0) {
1403 clk_put(fimc->clock);
1404 fimc->clock = NULL;
1405 }
1406 return ret;
1407 }
1408
1409 static int fimc_lite_probe(struct platform_device *pdev)
1410 {
1411 struct flite_drvdata *drv_data = fimc_lite_get_drvdata(pdev);
1412 struct fimc_lite *fimc;
1413 struct resource *res;
1414 int ret;
1415
1416 fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL);
1417 if (!fimc)
1418 return -ENOMEM;
1419
1420 fimc->index = pdev->id;
1421 fimc->variant = drv_data->variant[fimc->index];
1422 fimc->pdev = pdev;
1423
1424 init_waitqueue_head(&fimc->irq_queue);
1425 spin_lock_init(&fimc->slock);
1426 mutex_init(&fimc->lock);
1427
1428 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1429 fimc->regs = devm_request_and_ioremap(&pdev->dev, res);
1430 if (fimc->regs == NULL) {
1431 dev_err(&pdev->dev, "Failed to obtain io memory\n");
1432 return -ENOENT;
1433 }
1434
1435 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1436 if (res == NULL) {
1437 dev_err(&pdev->dev, "Failed to get IRQ resource\n");
1438 return -ENXIO;
1439 }
1440
1441 ret = fimc_lite_clk_get(fimc);
1442 if (ret)
1443 return ret;
1444
1445 ret = devm_request_irq(&pdev->dev, res->start, flite_irq_handler,
1446 0, dev_name(&pdev->dev), fimc);
1447 if (ret) {
1448 dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
1449 goto err_clk;
1450 }
1451
1452 /* The video node will be created within the subdev's registered() op */
1453 ret = fimc_lite_create_capture_subdev(fimc);
1454 if (ret)
1455 goto err_clk;
1456
1457 platform_set_drvdata(pdev, fimc);
1458 pm_runtime_enable(&pdev->dev);
1459 ret = pm_runtime_get_sync(&pdev->dev);
1460 if (ret < 0)
1461 goto err_sd;
1462
1463 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1464 if (IS_ERR(fimc->alloc_ctx)) {
1465 ret = PTR_ERR(fimc->alloc_ctx);
1466 goto err_pm;
1467 }
1468 pm_runtime_put(&pdev->dev);
1469
1470 dev_dbg(&pdev->dev, "FIMC-LITE.%d registered successfully\n",
1471 fimc->index);
1472 return 0;
1473 err_pm:
1474 pm_runtime_put(&pdev->dev);
1475 err_sd:
1476 fimc_lite_unregister_capture_subdev(fimc);
1477 err_clk:
1478 fimc_lite_clk_put(fimc);
1479 return ret;
1480 }
1481
1482 static int fimc_lite_runtime_resume(struct device *dev)
1483 {
1484 struct fimc_lite *fimc = dev_get_drvdata(dev);
1485
1486 clk_enable(fimc->clock);
1487 return 0;
1488 }
1489
1490 static int fimc_lite_runtime_suspend(struct device *dev)
1491 {
1492 struct fimc_lite *fimc = dev_get_drvdata(dev);
1493
1494 clk_disable(fimc->clock);
1495 return 0;
1496 }
1497
1498 #ifdef CONFIG_PM_SLEEP
1499 static int fimc_lite_resume(struct device *dev)
1500 {
1501 struct fimc_lite *fimc = dev_get_drvdata(dev);
1502 struct flite_buffer *buf;
1503 unsigned long flags;
1504 int i;
1505
1506 spin_lock_irqsave(&fimc->slock, flags);
1507 if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
1508 !test_bit(ST_FLITE_IN_USE, &fimc->state)) {
1509 spin_unlock_irqrestore(&fimc->slock, flags);
1510 return 0;
1511 }
1512 flite_hw_reset(fimc);
1513 spin_unlock_irqrestore(&fimc->slock, flags);
1514
1515 if (!test_and_clear_bit(ST_FLITE_SUSPENDED, &fimc->state))
1516 return 0;
1517
1518 INIT_LIST_HEAD(&fimc->active_buf_q);
1519 fimc_pipeline_call(fimc, open, &fimc->pipeline,
1520 &fimc->vfd.entity, false);
1521 fimc_lite_hw_init(fimc);
1522 clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
1523
1524 for (i = 0; i < fimc->reqbufs_count; i++) {
1525 if (list_empty(&fimc->pending_buf_q))
1526 break;
1527 buf = fimc_lite_pending_queue_pop(fimc);
1528 buffer_queue(&buf->vb);
1529 }
1530 return 0;
1531 }
1532
1533 static int fimc_lite_suspend(struct device *dev)
1534 {
1535 struct fimc_lite *fimc = dev_get_drvdata(dev);
1536 bool suspend = test_bit(ST_FLITE_IN_USE, &fimc->state);
1537 int ret;
1538
1539 if (test_and_set_bit(ST_LPM, &fimc->state))
1540 return 0;
1541
1542 ret = fimc_lite_stop_capture(fimc, suspend);
1543 if (ret < 0 || !fimc_lite_active(fimc))
1544 return ret;
1545
1546 return fimc_pipeline_call(fimc, close, &fimc->pipeline);
1547 }
1548 #endif /* CONFIG_PM_SLEEP */
1549
1550 static int fimc_lite_remove(struct platform_device *pdev)
1551 {
1552 struct fimc_lite *fimc = platform_get_drvdata(pdev);
1553 struct device *dev = &pdev->dev;
1554
1555 pm_runtime_disable(dev);
1556 pm_runtime_set_suspended(dev);
1557 fimc_lite_unregister_capture_subdev(fimc);
1558 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1559 fimc_lite_clk_put(fimc);
1560
1561 dev_info(dev, "Driver unloaded\n");
1562 return 0;
1563 }
1564
1565 static struct flite_variant fimc_lite0_variant_exynos4 = {
1566 .max_width = 8192,
1567 .max_height = 8192,
1568 .out_width_align = 8,
1569 .win_hor_offs_align = 2,
1570 .out_hor_offs_align = 8,
1571 };
1572
1573 /* EXYNOS4212, EXYNOS4412 */
1574 static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
1575 .variant = {
1576 [0] = &fimc_lite0_variant_exynos4,
1577 [1] = &fimc_lite0_variant_exynos4,
1578 },
1579 };
1580
1581 static struct platform_device_id fimc_lite_driver_ids[] = {
1582 {
1583 .name = "exynos-fimc-lite",
1584 .driver_data = (unsigned long)&fimc_lite_drvdata_exynos4,
1585 },
1586 { /* sentinel */ },
1587 };
1588 MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids);
1589
1590 static const struct dev_pm_ops fimc_lite_pm_ops = {
1591 SET_SYSTEM_SLEEP_PM_OPS(fimc_lite_suspend, fimc_lite_resume)
1592 SET_RUNTIME_PM_OPS(fimc_lite_runtime_suspend, fimc_lite_runtime_resume,
1593 NULL)
1594 };
1595
1596 static struct platform_driver fimc_lite_driver = {
1597 .probe = fimc_lite_probe,
1598 .remove = fimc_lite_remove,
1599 .id_table = fimc_lite_driver_ids,
1600 .driver = {
1601 .name = FIMC_LITE_DRV_NAME,
1602 .owner = THIS_MODULE,
1603 .pm = &fimc_lite_pm_ops,
1604 }
1605 };
1606 module_platform_driver(fimc_lite_driver);
1607 MODULE_LICENSE("GPL");
1608 MODULE_ALIAS("platform:" FIMC_LITE_DRV_NAME);
This page took 0.071533 seconds and 5 git commands to generate.