2 * SoC-camera host driver for Renesas R-Car VIN unit
4 * Copyright (C) 2011-2013 Renesas Solutions Corp.
5 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
7 * Based on V4L2 Driver for SuperH Mobile CEU interface "sh_mobile_ceu_camera.c"
9 * Copyright (C) 2008 Magnus Damm
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
17 #include <linux/delay.h>
18 #include <linux/interrupt.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
23 #include <linux/of_device.h>
24 #include <linux/platform_data/camera-rcar.h>
25 #include <linux/platform_device.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/slab.h>
28 #include <linux/videodev2.h>
30 #include <media/soc_camera.h>
31 #include <media/soc_mediabus.h>
32 #include <media/v4l2-common.h>
33 #include <media/v4l2-dev.h>
34 #include <media/v4l2-device.h>
35 #include <media/v4l2-mediabus.h>
36 #include <media/v4l2-of.h>
37 #include <media/v4l2-subdev.h>
38 #include <media/videobuf2-dma-contig.h>
40 #include "soc_scale_crop.h"
42 #define DRV_NAME "rcar_vin"
44 /* Register offsets for R-Car VIN */
45 #define VNMC_REG 0x00 /* Video n Main Control Register */
46 #define VNMS_REG 0x04 /* Video n Module Status Register */
47 #define VNFC_REG 0x08 /* Video n Frame Capture Register */
48 #define VNSLPRC_REG 0x0C /* Video n Start Line Pre-Clip Register */
49 #define VNELPRC_REG 0x10 /* Video n End Line Pre-Clip Register */
50 #define VNSPPRC_REG 0x14 /* Video n Start Pixel Pre-Clip Register */
51 #define VNEPPRC_REG 0x18 /* Video n End Pixel Pre-Clip Register */
52 #define VNSLPOC_REG 0x1C /* Video n Start Line Post-Clip Register */
53 #define VNELPOC_REG 0x20 /* Video n End Line Post-Clip Register */
54 #define VNSPPOC_REG 0x24 /* Video n Start Pixel Post-Clip Register */
55 #define VNEPPOC_REG 0x28 /* Video n End Pixel Post-Clip Register */
56 #define VNIS_REG 0x2C /* Video n Image Stride Register */
57 #define VNMB_REG(m) (0x30 + ((m) << 2)) /* Video n Memory Base m Register */
58 #define VNIE_REG 0x40 /* Video n Interrupt Enable Register */
59 #define VNINTS_REG 0x44 /* Video n Interrupt Status Register */
60 #define VNSI_REG 0x48 /* Video n Scanline Interrupt Register */
61 #define VNMTC_REG 0x4C /* Video n Memory Transfer Control Register */
62 #define VNYS_REG 0x50 /* Video n Y Scale Register */
63 #define VNXS_REG 0x54 /* Video n X Scale Register */
64 #define VNDMR_REG 0x58 /* Video n Data Mode Register */
65 #define VNDMR2_REG 0x5C /* Video n Data Mode Register 2 */
66 #define VNUVAOF_REG 0x60 /* Video n UV Address Offset Register */
68 /* Register bit fields for R-Car VIN */
69 /* Video n Main Control Register bits */
70 #define VNMC_FOC (1 << 21)
71 #define VNMC_YCAL (1 << 19)
72 #define VNMC_INF_YUV8_BT656 (0 << 16)
73 #define VNMC_INF_YUV8_BT601 (1 << 16)
74 #define VNMC_INF_YUV10_BT656 (2 << 16)
75 #define VNMC_INF_YUV10_BT601 (3 << 16)
76 #define VNMC_INF_YUV16 (5 << 16)
77 #define VNMC_VUP (1 << 10)
78 #define VNMC_IM_ODD (0 << 3)
79 #define VNMC_IM_ODD_EVEN (1 << 3)
80 #define VNMC_IM_EVEN (2 << 3)
81 #define VNMC_IM_FULL (3 << 3)
82 #define VNMC_BPS (1 << 1)
83 #define VNMC_ME (1 << 0)
85 /* Video n Module Status Register bits */
86 #define VNMS_FBS_MASK (3 << 3)
87 #define VNMS_FBS_SHIFT 3
88 #define VNMS_AV (1 << 1)
89 #define VNMS_CA (1 << 0)
91 /* Video n Frame Capture Register bits */
92 #define VNFC_C_FRAME (1 << 1)
93 #define VNFC_S_FRAME (1 << 0)
95 /* Video n Interrupt Enable Register bits */
96 #define VNIE_FIE (1 << 4)
97 #define VNIE_EFE (1 << 1)
99 /* Video n Data Mode Register bits */
100 #define VNDMR_EXRGB (1 << 8)
101 #define VNDMR_BPSM (1 << 4)
102 #define VNDMR_DTMD_YCSEP (1 << 1)
103 #define VNDMR_DTMD_ARGB1555 (1 << 0)
105 /* Video n Data Mode Register 2 bits */
106 #define VNDMR2_VPS (1 << 30)
107 #define VNDMR2_HPS (1 << 29)
108 #define VNDMR2_FTEV (1 << 17)
110 #define VIN_MAX_WIDTH 2048
111 #define VIN_MAX_HEIGHT 2048
120 enum rcar_vin_state
{
126 struct rcar_vin_priv
{
130 /* State of the VIN module in capturing mode */
131 enum rcar_vin_state state
;
132 struct soc_camera_host ici
;
133 struct list_head capture
;
134 #define MAX_BUFFER_NUM 3
135 struct vb2_buffer
*queue_buf
[MAX_BUFFER_NUM
];
136 struct vb2_alloc_ctx
*alloc_ctx
;
137 enum v4l2_field field
;
138 unsigned int pdata_flags
;
139 unsigned int vb_count
;
140 unsigned int nr_hw_slots
;
141 bool request_to_stop
;
142 struct completion capture_stop
;
146 #define is_continuous_transfer(priv) (priv->vb_count > MAX_BUFFER_NUM)
148 struct rcar_vin_buffer
{
149 struct vb2_buffer vb
;
150 struct list_head list
;
153 #define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
154 struct rcar_vin_buffer, \
157 struct rcar_vin_cam
{
158 /* VIN offsets within the camera output, before the VIN scaler */
159 unsigned int vin_left
;
160 unsigned int vin_top
;
161 /* Client output, as seen by the VIN */
165 * User window from S_CROP / G_CROP, produced by client cropping and
166 * scaling, VIN scaling and VIN cropping, mapped back onto the client
169 struct v4l2_rect subrect
;
170 /* Camera cropping rectangle */
171 struct v4l2_rect rect
;
172 const struct soc_mbus_pixelfmt
*extra_fmt
;
176 * .queue_setup() is called to check whether the driver can accept the requested
177 * number of buffers and to fill in plane sizes for the current frame format if
180 static int rcar_vin_videobuf_setup(struct vb2_queue
*vq
,
181 const struct v4l2_format
*fmt
,
183 unsigned int *num_planes
,
184 unsigned int sizes
[], void *alloc_ctxs
[])
186 struct soc_camera_device
*icd
= soc_camera_from_vb2q(vq
);
187 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
188 struct rcar_vin_priv
*priv
= ici
->priv
;
191 const struct soc_camera_format_xlate
*xlate
;
192 unsigned int bytes_per_line
;
195 xlate
= soc_camera_xlate_by_fourcc(icd
,
196 fmt
->fmt
.pix
.pixelformat
);
199 ret
= soc_mbus_bytes_per_line(fmt
->fmt
.pix
.width
,
204 bytes_per_line
= max_t(u32
, fmt
->fmt
.pix
.bytesperline
, ret
);
206 ret
= soc_mbus_image_size(xlate
->host_fmt
, bytes_per_line
,
207 fmt
->fmt
.pix
.height
);
211 sizes
[0] = max_t(u32
, fmt
->fmt
.pix
.sizeimage
, ret
);
213 /* Called from VIDIOC_REQBUFS or in compatibility mode */
214 sizes
[0] = icd
->sizeimage
;
217 alloc_ctxs
[0] = priv
->alloc_ctx
;
219 if (!vq
->num_buffers
)
224 priv
->vb_count
= *count
;
228 /* Number of hardware slots */
229 if (is_continuous_transfer(priv
))
230 priv
->nr_hw_slots
= MAX_BUFFER_NUM
;
232 priv
->nr_hw_slots
= 1;
234 dev_dbg(icd
->parent
, "count=%d, size=%u\n", *count
, sizes
[0]);
239 static int rcar_vin_setup(struct rcar_vin_priv
*priv
)
241 struct soc_camera_device
*icd
= priv
->ici
.icd
;
242 struct rcar_vin_cam
*cam
= icd
->host_priv
;
243 u32 vnmc
, dmr
, interrupts
;
244 bool progressive
= false, output_is_yuv
= false;
246 switch (priv
->field
) {
250 case V4L2_FIELD_BOTTOM
:
253 case V4L2_FIELD_INTERLACED
:
254 case V4L2_FIELD_INTERLACED_TB
:
257 case V4L2_FIELD_INTERLACED_BT
:
258 vnmc
= VNMC_IM_FULL
| VNMC_FOC
;
260 case V4L2_FIELD_NONE
:
261 if (is_continuous_transfer(priv
)) {
262 vnmc
= VNMC_IM_ODD_EVEN
;
273 /* input interface */
274 switch (icd
->current_fmt
->code
) {
275 case V4L2_MBUS_FMT_YUYV8_1X16
:
276 /* BT.601/BT.1358 16bit YCbCr422 */
277 vnmc
|= VNMC_INF_YUV16
;
279 case V4L2_MBUS_FMT_YUYV8_2X8
:
280 /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
281 vnmc
|= priv
->pdata_flags
& RCAR_VIN_BT656
?
282 VNMC_INF_YUV8_BT656
: VNMC_INF_YUV8_BT601
;
284 case V4L2_MBUS_FMT_YUYV10_2X10
:
285 /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
286 vnmc
|= priv
->pdata_flags
& RCAR_VIN_BT656
?
287 VNMC_INF_YUV10_BT656
: VNMC_INF_YUV10_BT601
;
294 switch (icd
->current_fmt
->host_fmt
->fourcc
) {
295 case V4L2_PIX_FMT_NV16
:
296 iowrite32(ALIGN(cam
->width
* cam
->height
, 0x80),
297 priv
->base
+ VNUVAOF_REG
);
298 dmr
= VNDMR_DTMD_YCSEP
;
299 output_is_yuv
= true;
301 case V4L2_PIX_FMT_YUYV
:
303 output_is_yuv
= true;
305 case V4L2_PIX_FMT_UYVY
:
307 output_is_yuv
= true;
309 case V4L2_PIX_FMT_RGB555X
:
310 dmr
= VNDMR_DTMD_ARGB1555
;
312 case V4L2_PIX_FMT_RGB565
:
315 case V4L2_PIX_FMT_RGB32
:
316 if (priv
->chip
== RCAR_GEN2
|| priv
->chip
== RCAR_H1
||
317 priv
->chip
== RCAR_E1
) {
322 dev_warn(icd
->parent
, "Invalid fourcc format (0x%x)\n",
323 icd
->current_fmt
->host_fmt
->fourcc
);
327 /* Always update on field change */
330 /* If input and output use the same colorspace, use bypass mode */
334 /* progressive or interlaced mode */
335 interrupts
= progressive
? VNIE_FIE
| VNIE_EFE
: VNIE_EFE
;
338 iowrite32(interrupts
, priv
->base
+ VNINTS_REG
);
339 /* enable interrupts */
340 iowrite32(interrupts
, priv
->base
+ VNIE_REG
);
341 /* start capturing */
342 iowrite32(dmr
, priv
->base
+ VNDMR_REG
);
343 iowrite32(vnmc
| VNMC_ME
, priv
->base
+ VNMC_REG
);
348 static void rcar_vin_capture(struct rcar_vin_priv
*priv
)
350 if (is_continuous_transfer(priv
))
351 /* Continuous Frame Capture Mode */
352 iowrite32(VNFC_C_FRAME
, priv
->base
+ VNFC_REG
);
354 /* Single Frame Capture Mode */
355 iowrite32(VNFC_S_FRAME
, priv
->base
+ VNFC_REG
);
358 static void rcar_vin_request_capture_stop(struct rcar_vin_priv
*priv
)
360 priv
->state
= STOPPING
;
362 /* set continuous & single transfer off */
363 iowrite32(0, priv
->base
+ VNFC_REG
);
364 /* disable capture (release DMA buffer), reset */
365 iowrite32(ioread32(priv
->base
+ VNMC_REG
) & ~VNMC_ME
,
366 priv
->base
+ VNMC_REG
);
368 /* update the status if stopped already */
369 if (!(ioread32(priv
->base
+ VNMS_REG
) & VNMS_CA
))
370 priv
->state
= STOPPED
;
373 static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv
*priv
)
377 for (slot
= 0; slot
< priv
->nr_hw_slots
; slot
++)
378 if (priv
->queue_buf
[slot
] == NULL
)
384 static int rcar_vin_hw_ready(struct rcar_vin_priv
*priv
)
386 /* Ensure all HW slots are filled */
387 return rcar_vin_get_free_hw_slot(priv
) < 0 ? 1 : 0;
390 /* Moves a buffer from the queue to the HW slots */
391 static int rcar_vin_fill_hw_slot(struct rcar_vin_priv
*priv
)
393 struct vb2_buffer
*vb
;
394 dma_addr_t phys_addr_top
;
397 if (list_empty(&priv
->capture
))
400 /* Find a free HW slot */
401 slot
= rcar_vin_get_free_hw_slot(priv
);
405 vb
= &list_entry(priv
->capture
.next
, struct rcar_vin_buffer
, list
)->vb
;
406 list_del_init(to_buf_list(vb
));
407 priv
->queue_buf
[slot
] = vb
;
408 phys_addr_top
= vb2_dma_contig_plane_dma_addr(vb
, 0);
409 iowrite32(phys_addr_top
, priv
->base
+ VNMB_REG(slot
));
414 static void rcar_vin_videobuf_queue(struct vb2_buffer
*vb
)
416 struct soc_camera_device
*icd
= soc_camera_from_vb2q(vb
->vb2_queue
);
417 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
418 struct rcar_vin_priv
*priv
= ici
->priv
;
421 size
= icd
->sizeimage
;
423 if (vb2_plane_size(vb
, 0) < size
) {
424 dev_err(icd
->parent
, "Buffer #%d too small (%lu < %lu)\n",
425 vb
->v4l2_buf
.index
, vb2_plane_size(vb
, 0), size
);
429 vb2_set_plane_payload(vb
, 0, size
);
431 dev_dbg(icd
->parent
, "%s (vb=0x%p) 0x%p %lu\n", __func__
,
432 vb
, vb2_plane_vaddr(vb
, 0), vb2_get_plane_payload(vb
, 0));
434 spin_lock_irq(&priv
->lock
);
436 list_add_tail(to_buf_list(vb
), &priv
->capture
);
437 rcar_vin_fill_hw_slot(priv
);
439 /* If we weren't running, and have enough buffers, start capturing! */
440 if (priv
->state
!= RUNNING
&& rcar_vin_hw_ready(priv
)) {
441 if (rcar_vin_setup(priv
)) {
443 list_del_init(to_buf_list(vb
));
444 spin_unlock_irq(&priv
->lock
);
447 priv
->request_to_stop
= false;
448 init_completion(&priv
->capture_stop
);
449 priv
->state
= RUNNING
;
450 rcar_vin_capture(priv
);
453 spin_unlock_irq(&priv
->lock
);
458 vb2_buffer_done(vb
, VB2_BUF_STATE_ERROR
);
461 static void rcar_vin_videobuf_release(struct vb2_buffer
*vb
)
463 struct soc_camera_device
*icd
= soc_camera_from_vb2q(vb
->vb2_queue
);
464 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
465 struct rcar_vin_priv
*priv
= ici
->priv
;
469 spin_lock_irq(&priv
->lock
);
471 /* Is the buffer in use by the VIN hardware? */
472 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++) {
473 if (priv
->queue_buf
[i
] == vb
) {
480 while (priv
->state
!= STOPPED
) {
482 /* issue stop if running */
483 if (priv
->state
== RUNNING
)
484 rcar_vin_request_capture_stop(priv
);
486 /* wait until capturing has been stopped */
487 if (priv
->state
== STOPPING
) {
488 priv
->request_to_stop
= true;
489 spin_unlock_irq(&priv
->lock
);
490 wait_for_completion(&priv
->capture_stop
);
491 spin_lock_irq(&priv
->lock
);
495 * Capturing has now stopped. The buffer we have been asked
496 * to release could be any of the current buffers in use, so
497 * release all buffers that are in use by HW
499 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++) {
500 if (priv
->queue_buf
[i
]) {
501 vb2_buffer_done(priv
->queue_buf
[i
],
502 VB2_BUF_STATE_ERROR
);
503 priv
->queue_buf
[i
] = NULL
;
507 list_del_init(to_buf_list(vb
));
510 spin_unlock_irq(&priv
->lock
);
513 static int rcar_vin_videobuf_init(struct vb2_buffer
*vb
)
515 INIT_LIST_HEAD(to_buf_list(vb
));
519 static void rcar_vin_stop_streaming(struct vb2_queue
*vq
)
521 struct soc_camera_device
*icd
= soc_camera_from_vb2q(vq
);
522 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
523 struct rcar_vin_priv
*priv
= ici
->priv
;
524 struct list_head
*buf_head
, *tmp
;
526 spin_lock_irq(&priv
->lock
);
527 list_for_each_safe(buf_head
, tmp
, &priv
->capture
)
528 list_del_init(buf_head
);
529 spin_unlock_irq(&priv
->lock
);
532 static struct vb2_ops rcar_vin_vb2_ops
= {
533 .queue_setup
= rcar_vin_videobuf_setup
,
534 .buf_init
= rcar_vin_videobuf_init
,
535 .buf_cleanup
= rcar_vin_videobuf_release
,
536 .buf_queue
= rcar_vin_videobuf_queue
,
537 .stop_streaming
= rcar_vin_stop_streaming
,
538 .wait_prepare
= soc_camera_unlock
,
539 .wait_finish
= soc_camera_lock
,
542 static irqreturn_t
rcar_vin_irq(int irq
, void *data
)
544 struct rcar_vin_priv
*priv
= data
;
546 bool can_run
= false, hw_stopped
;
548 unsigned int handled
= 0;
550 spin_lock(&priv
->lock
);
552 int_status
= ioread32(priv
->base
+ VNINTS_REG
);
556 iowrite32(int_status
, priv
->base
+ VNINTS_REG
);
559 /* nothing to do if capture status is 'STOPPED' */
560 if (priv
->state
== STOPPED
)
563 hw_stopped
= !(ioread32(priv
->base
+ VNMS_REG
) & VNMS_CA
);
565 if (!priv
->request_to_stop
) {
566 if (is_continuous_transfer(priv
))
567 slot
= (ioread32(priv
->base
+ VNMS_REG
) &
568 VNMS_FBS_MASK
) >> VNMS_FBS_SHIFT
;
572 priv
->queue_buf
[slot
]->v4l2_buf
.field
= priv
->field
;
573 priv
->queue_buf
[slot
]->v4l2_buf
.sequence
= priv
->sequence
++;
574 do_gettimeofday(&priv
->queue_buf
[slot
]->v4l2_buf
.timestamp
);
575 vb2_buffer_done(priv
->queue_buf
[slot
], VB2_BUF_STATE_DONE
);
576 priv
->queue_buf
[slot
] = NULL
;
578 if (priv
->state
!= STOPPING
)
579 can_run
= rcar_vin_fill_hw_slot(priv
);
581 if (hw_stopped
|| !can_run
) {
582 priv
->state
= STOPPED
;
583 } else if (is_continuous_transfer(priv
) &&
584 list_empty(&priv
->capture
) &&
585 priv
->state
== RUNNING
) {
587 * The continuous capturing requires an explicit stop
588 * operation when there is no buffer to be set into
589 * the VnMBm registers.
591 rcar_vin_request_capture_stop(priv
);
593 rcar_vin_capture(priv
);
596 } else if (hw_stopped
) {
597 priv
->state
= STOPPED
;
598 priv
->request_to_stop
= false;
599 complete(&priv
->capture_stop
);
603 spin_unlock(&priv
->lock
);
605 return IRQ_RETVAL(handled
);
608 static int rcar_vin_add_device(struct soc_camera_device
*icd
)
610 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
611 struct rcar_vin_priv
*priv
= ici
->priv
;
614 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++)
615 priv
->queue_buf
[i
] = NULL
;
617 pm_runtime_get_sync(ici
->v4l2_dev
.dev
);
619 dev_dbg(icd
->parent
, "R-Car VIN driver attached to camera %d\n",
625 static void rcar_vin_remove_device(struct soc_camera_device
*icd
)
627 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
628 struct rcar_vin_priv
*priv
= ici
->priv
;
629 struct vb2_buffer
*vb
;
632 /* disable capture, disable interrupts */
633 iowrite32(ioread32(priv
->base
+ VNMC_REG
) & ~VNMC_ME
,
634 priv
->base
+ VNMC_REG
);
635 iowrite32(0, priv
->base
+ VNIE_REG
);
637 priv
->state
= STOPPED
;
638 priv
->request_to_stop
= false;
640 /* make sure active buffer is cancelled */
641 spin_lock_irq(&priv
->lock
);
642 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++) {
643 vb
= priv
->queue_buf
[i
];
645 list_del_init(to_buf_list(vb
));
646 vb2_buffer_done(vb
, VB2_BUF_STATE_ERROR
);
649 spin_unlock_irq(&priv
->lock
);
651 pm_runtime_put(ici
->v4l2_dev
.dev
);
653 dev_dbg(icd
->parent
, "R-Car VIN driver detached from camera %d\n",
657 /* Called with .host_lock held */
658 static int rcar_vin_clock_start(struct soc_camera_host
*ici
)
660 /* VIN does not have "mclk" */
664 /* Called with .host_lock held */
665 static void rcar_vin_clock_stop(struct soc_camera_host
*ici
)
667 /* VIN does not have "mclk" */
670 /* rect is guaranteed to not exceed the scaled camera rectangle */
671 static int rcar_vin_set_rect(struct soc_camera_device
*icd
)
673 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
674 struct rcar_vin_cam
*cam
= icd
->host_priv
;
675 struct rcar_vin_priv
*priv
= ici
->priv
;
676 unsigned int left_offset
, top_offset
;
677 unsigned char dsize
= 0;
678 struct v4l2_rect
*cam_subrect
= &cam
->subrect
;
680 dev_dbg(icd
->parent
, "Crop %ux%u@%u:%u\n",
681 icd
->user_width
, icd
->user_height
, cam
->vin_left
, cam
->vin_top
);
683 left_offset
= cam
->vin_left
;
684 top_offset
= cam
->vin_top
;
686 if (icd
->current_fmt
->host_fmt
->fourcc
== V4L2_PIX_FMT_RGB32
&&
687 priv
->chip
== RCAR_E1
)
690 dev_dbg(icd
->parent
, "Cam %ux%u@%u:%u\n",
691 cam
->width
, cam
->height
, cam
->vin_left
, cam
->vin_top
);
692 dev_dbg(icd
->parent
, "Cam subrect %ux%u@%u:%u\n",
693 cam_subrect
->width
, cam_subrect
->height
,
694 cam_subrect
->left
, cam_subrect
->top
);
696 /* Set Start/End Pixel/Line Pre-Clip */
697 iowrite32(left_offset
<< dsize
, priv
->base
+ VNSPPRC_REG
);
698 iowrite32((left_offset
+ cam
->width
- 1) << dsize
,
699 priv
->base
+ VNEPPRC_REG
);
700 switch (priv
->field
) {
701 case V4L2_FIELD_INTERLACED
:
702 case V4L2_FIELD_INTERLACED_TB
:
703 case V4L2_FIELD_INTERLACED_BT
:
704 iowrite32(top_offset
/ 2, priv
->base
+ VNSLPRC_REG
);
705 iowrite32((top_offset
+ cam
->height
) / 2 - 1,
706 priv
->base
+ VNELPRC_REG
);
709 iowrite32(top_offset
, priv
->base
+ VNSLPRC_REG
);
710 iowrite32(top_offset
+ cam
->height
- 1,
711 priv
->base
+ VNELPRC_REG
);
715 /* Set Start/End Pixel/Line Post-Clip */
716 iowrite32(0, priv
->base
+ VNSPPOC_REG
);
717 iowrite32(0, priv
->base
+ VNSLPOC_REG
);
718 iowrite32((cam_subrect
->width
- 1) << dsize
, priv
->base
+ VNEPPOC_REG
);
719 switch (priv
->field
) {
720 case V4L2_FIELD_INTERLACED
:
721 case V4L2_FIELD_INTERLACED_TB
:
722 case V4L2_FIELD_INTERLACED_BT
:
723 iowrite32(cam_subrect
->height
/ 2 - 1,
724 priv
->base
+ VNELPOC_REG
);
727 iowrite32(cam_subrect
->height
- 1, priv
->base
+ VNELPOC_REG
);
731 iowrite32(ALIGN(cam
->width
, 0x10), priv
->base
+ VNIS_REG
);
736 static void capture_stop_preserve(struct rcar_vin_priv
*priv
, u32
*vnmc
)
738 *vnmc
= ioread32(priv
->base
+ VNMC_REG
);
740 iowrite32(*vnmc
& ~VNMC_ME
, priv
->base
+ VNMC_REG
);
743 static void capture_restore(struct rcar_vin_priv
*priv
, u32 vnmc
)
745 unsigned long timeout
= jiffies
+ 10 * HZ
;
748 * Wait until the end of the current frame. It can take a long time,
749 * but if it has been aborted by a MRST1 reset, it should exit sooner.
751 while ((ioread32(priv
->base
+ VNMS_REG
) & VNMS_AV
) &&
752 time_before(jiffies
, timeout
))
755 if (time_after(jiffies
, timeout
)) {
756 dev_err(priv
->ici
.v4l2_dev
.dev
,
757 "Timeout waiting for frame end! Interface problem?\n");
761 iowrite32(vnmc
, priv
->base
+ VNMC_REG
);
764 #define VIN_MBUS_FLAGS (V4L2_MBUS_MASTER | \
765 V4L2_MBUS_PCLK_SAMPLE_RISING | \
766 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
767 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
768 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
769 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
770 V4L2_MBUS_DATA_ACTIVE_HIGH)
772 static int rcar_vin_set_bus_param(struct soc_camera_device
*icd
)
774 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
775 struct rcar_vin_priv
*priv
= ici
->priv
;
776 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
777 struct v4l2_mbus_config cfg
;
778 unsigned long common_flags
;
783 capture_stop_preserve(priv
, &vnmc
);
785 ret
= v4l2_subdev_call(sd
, video
, g_mbus_config
, &cfg
);
787 common_flags
= soc_mbus_config_compatible(&cfg
, VIN_MBUS_FLAGS
);
789 dev_warn(icd
->parent
,
790 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
791 cfg
.flags
, VIN_MBUS_FLAGS
);
794 } else if (ret
!= -ENOIOCTLCMD
) {
797 common_flags
= VIN_MBUS_FLAGS
;
800 /* Make choises, based on platform preferences */
801 if ((common_flags
& V4L2_MBUS_HSYNC_ACTIVE_HIGH
) &&
802 (common_flags
& V4L2_MBUS_HSYNC_ACTIVE_LOW
)) {
803 if (priv
->pdata_flags
& RCAR_VIN_HSYNC_ACTIVE_LOW
)
804 common_flags
&= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH
;
806 common_flags
&= ~V4L2_MBUS_HSYNC_ACTIVE_LOW
;
809 if ((common_flags
& V4L2_MBUS_VSYNC_ACTIVE_HIGH
) &&
810 (common_flags
& V4L2_MBUS_VSYNC_ACTIVE_LOW
)) {
811 if (priv
->pdata_flags
& RCAR_VIN_VSYNC_ACTIVE_LOW
)
812 common_flags
&= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH
;
814 common_flags
&= ~V4L2_MBUS_VSYNC_ACTIVE_LOW
;
817 cfg
.flags
= common_flags
;
818 ret
= v4l2_subdev_call(sd
, video
, s_mbus_config
, &cfg
);
819 if (ret
< 0 && ret
!= -ENOIOCTLCMD
)
822 val
= priv
->field
== V4L2_FIELD_NONE
? VNDMR2_FTEV
: 0;
823 if (!(common_flags
& V4L2_MBUS_VSYNC_ACTIVE_LOW
))
825 if (!(common_flags
& V4L2_MBUS_HSYNC_ACTIVE_LOW
))
827 iowrite32(val
, priv
->base
+ VNDMR2_REG
);
829 ret
= rcar_vin_set_rect(icd
);
833 capture_restore(priv
, vnmc
);
838 static int rcar_vin_try_bus_param(struct soc_camera_device
*icd
,
839 unsigned char buswidth
)
841 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
842 struct v4l2_mbus_config cfg
;
845 ret
= v4l2_subdev_call(sd
, video
, g_mbus_config
, &cfg
);
846 if (ret
== -ENOIOCTLCMD
)
854 /* check is there common mbus flags */
855 ret
= soc_mbus_config_compatible(&cfg
, VIN_MBUS_FLAGS
);
859 dev_warn(icd
->parent
,
860 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
861 cfg
.flags
, VIN_MBUS_FLAGS
);
866 static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt
*fmt
)
868 return fmt
->packing
== SOC_MBUS_PACKING_NONE
||
869 (fmt
->bits_per_sample
> 8 &&
870 fmt
->packing
== SOC_MBUS_PACKING_EXTEND16
);
873 static const struct soc_mbus_pixelfmt rcar_vin_formats
[] = {
875 .fourcc
= V4L2_PIX_FMT_NV16
,
877 .bits_per_sample
= 8,
878 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
879 .order
= SOC_MBUS_ORDER_LE
,
880 .layout
= SOC_MBUS_LAYOUT_PLANAR_Y_C
,
883 .fourcc
= V4L2_PIX_FMT_UYVY
,
885 .bits_per_sample
= 16,
886 .packing
= SOC_MBUS_PACKING_NONE
,
887 .order
= SOC_MBUS_ORDER_LE
,
888 .layout
= SOC_MBUS_LAYOUT_PACKED
,
891 .fourcc
= V4L2_PIX_FMT_RGB565
,
893 .bits_per_sample
= 16,
894 .packing
= SOC_MBUS_PACKING_NONE
,
895 .order
= SOC_MBUS_ORDER_LE
,
896 .layout
= SOC_MBUS_LAYOUT_PACKED
,
899 .fourcc
= V4L2_PIX_FMT_RGB555X
,
901 .bits_per_sample
= 16,
902 .packing
= SOC_MBUS_PACKING_NONE
,
903 .order
= SOC_MBUS_ORDER_LE
,
904 .layout
= SOC_MBUS_LAYOUT_PACKED
,
907 .fourcc
= V4L2_PIX_FMT_RGB32
,
909 .bits_per_sample
= 32,
910 .packing
= SOC_MBUS_PACKING_NONE
,
911 .order
= SOC_MBUS_ORDER_LE
,
912 .layout
= SOC_MBUS_LAYOUT_PACKED
,
916 static int rcar_vin_get_formats(struct soc_camera_device
*icd
, unsigned int idx
,
917 struct soc_camera_format_xlate
*xlate
)
919 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
920 struct device
*dev
= icd
->parent
;
923 struct rcar_vin_cam
*cam
;
924 enum v4l2_mbus_pixelcode code
;
925 const struct soc_mbus_pixelfmt
*fmt
;
927 ret
= v4l2_subdev_call(sd
, video
, enum_mbus_fmt
, idx
, &code
);
931 fmt
= soc_mbus_get_fmtdesc(code
);
933 dev_warn(dev
, "unsupported format code #%u: %d\n", idx
, code
);
937 ret
= rcar_vin_try_bus_param(icd
, fmt
->bits_per_sample
);
941 if (!icd
->host_priv
) {
942 struct v4l2_mbus_framefmt mf
;
943 struct v4l2_rect rect
;
944 struct device
*dev
= icd
->parent
;
947 ret
= v4l2_subdev_call(sd
, video
, g_mbus_fmt
, &mf
);
951 /* Cache current client geometry */
952 ret
= soc_camera_client_g_rect(sd
, &rect
);
953 if (ret
== -ENOIOCTLCMD
) {
954 /* Sensor driver doesn't support cropping */
957 rect
.width
= mf
.width
;
958 rect
.height
= mf
.height
;
959 } else if (ret
< 0) {
964 * If sensor proposes too large format then try smaller ones:
965 * 1280x960, 640x480, 320x240
967 for (shift
= 0; shift
< 3; shift
++) {
968 if (mf
.width
<= VIN_MAX_WIDTH
&&
969 mf
.height
<= VIN_MAX_HEIGHT
)
972 mf
.width
= 1280 >> shift
;
973 mf
.height
= 960 >> shift
;
974 ret
= v4l2_device_call_until_err(sd
->v4l2_dev
,
975 soc_camera_grp_id(icd
),
984 "Failed to configure the client below %ux%u\n",
985 mf
.width
, mf
.height
);
989 dev_dbg(dev
, "camera fmt %ux%u\n", mf
.width
, mf
.height
);
991 cam
= kzalloc(sizeof(*cam
), GFP_KERNEL
);
995 * We are called with current camera crop,
996 * initialise subrect with it
1000 cam
->width
= mf
.width
;
1001 cam
->height
= mf
.height
;
1003 icd
->host_priv
= cam
;
1005 cam
= icd
->host_priv
;
1008 /* Beginning of a pass */
1010 cam
->extra_fmt
= NULL
;
1013 case V4L2_MBUS_FMT_YUYV8_1X16
:
1014 case V4L2_MBUS_FMT_YUYV8_2X8
:
1015 case V4L2_MBUS_FMT_YUYV10_2X10
:
1019 /* Add all our formats that can be generated by VIN */
1020 cam
->extra_fmt
= rcar_vin_formats
;
1022 n
= ARRAY_SIZE(rcar_vin_formats
);
1024 for (k
= 0; xlate
&& k
< n
; k
++, xlate
++) {
1025 xlate
->host_fmt
= &rcar_vin_formats
[k
];
1027 dev_dbg(dev
, "Providing format %s using code %d\n",
1028 rcar_vin_formats
[k
].name
, code
);
1032 if (!rcar_vin_packing_supported(fmt
))
1035 dev_dbg(dev
, "Providing format %s in pass-through mode\n",
1040 /* Generic pass-through */
1043 xlate
->host_fmt
= fmt
;
1051 static void rcar_vin_put_formats(struct soc_camera_device
*icd
)
1053 kfree(icd
->host_priv
);
1054 icd
->host_priv
= NULL
;
1057 static int rcar_vin_set_crop(struct soc_camera_device
*icd
,
1058 const struct v4l2_crop
*a
)
1060 struct v4l2_crop a_writable
= *a
;
1061 const struct v4l2_rect
*rect
= &a_writable
.c
;
1062 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
1063 struct rcar_vin_priv
*priv
= ici
->priv
;
1064 struct v4l2_crop cam_crop
;
1065 struct rcar_vin_cam
*cam
= icd
->host_priv
;
1066 struct v4l2_rect
*cam_rect
= &cam_crop
.c
;
1067 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
1068 struct device
*dev
= icd
->parent
;
1069 struct v4l2_mbus_framefmt mf
;
1073 dev_dbg(dev
, "S_CROP(%ux%u@%u:%u)\n", rect
->width
, rect
->height
,
1074 rect
->left
, rect
->top
);
1076 /* During camera cropping its output window can change too, stop VIN */
1077 capture_stop_preserve(priv
, &vnmc
);
1078 dev_dbg(dev
, "VNMC_REG 0x%x\n", vnmc
);
1080 /* Apply iterative camera S_CROP for new input window. */
1081 ret
= soc_camera_client_s_crop(sd
, &a_writable
, &cam_crop
,
1082 &cam
->rect
, &cam
->subrect
);
1086 dev_dbg(dev
, "camera cropped to %ux%u@%u:%u\n",
1087 cam_rect
->width
, cam_rect
->height
,
1088 cam_rect
->left
, cam_rect
->top
);
1090 /* On success cam_crop contains current camera crop */
1092 /* Retrieve camera output window */
1093 ret
= v4l2_subdev_call(sd
, video
, g_mbus_fmt
, &mf
);
1097 if (mf
.width
> VIN_MAX_WIDTH
|| mf
.height
> VIN_MAX_HEIGHT
)
1100 /* Cache camera output window */
1101 cam
->width
= mf
.width
;
1102 cam
->height
= mf
.height
;
1104 icd
->user_width
= cam
->width
;
1105 icd
->user_height
= cam
->height
;
1107 cam
->vin_left
= rect
->left
& ~1;
1108 cam
->vin_top
= rect
->top
& ~1;
1110 /* Use VIN cropping to crop to the new window. */
1111 ret
= rcar_vin_set_rect(icd
);
1115 cam
->subrect
= *rect
;
1117 dev_dbg(dev
, "VIN cropped to %ux%u@%u:%u\n",
1118 icd
->user_width
, icd
->user_height
,
1119 cam
->vin_left
, cam
->vin_top
);
1121 /* Restore capture */
1122 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++) {
1123 if (priv
->queue_buf
[i
] && priv
->state
== STOPPED
) {
1128 capture_restore(priv
, vnmc
);
1130 /* Even if only camera cropping succeeded */
1134 static int rcar_vin_get_crop(struct soc_camera_device
*icd
,
1135 struct v4l2_crop
*a
)
1137 struct rcar_vin_cam
*cam
= icd
->host_priv
;
1139 a
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1140 a
->c
= cam
->subrect
;
1145 /* Similar to set_crop multistage iterative algorithm */
1146 static int rcar_vin_set_fmt(struct soc_camera_device
*icd
,
1147 struct v4l2_format
*f
)
1149 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
1150 struct rcar_vin_priv
*priv
= ici
->priv
;
1151 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
1152 struct rcar_vin_cam
*cam
= icd
->host_priv
;
1153 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
1154 struct v4l2_mbus_framefmt mf
;
1155 struct device
*dev
= icd
->parent
;
1156 __u32 pixfmt
= pix
->pixelformat
;
1157 const struct soc_camera_format_xlate
*xlate
;
1158 unsigned int vin_sub_width
= 0, vin_sub_height
= 0;
1161 enum v4l2_field field
;
1164 dev_dbg(dev
, "S_FMT(pix=0x%x, %ux%u)\n",
1165 pixfmt
, pix
->width
, pix
->height
);
1167 switch (pix
->field
) {
1169 pix
->field
= V4L2_FIELD_NONE
;
1171 case V4L2_FIELD_NONE
:
1172 case V4L2_FIELD_TOP
:
1173 case V4L2_FIELD_BOTTOM
:
1174 case V4L2_FIELD_INTERLACED_TB
:
1175 case V4L2_FIELD_INTERLACED_BT
:
1178 case V4L2_FIELD_INTERLACED
:
1179 /* Query for standard if not explicitly mentioned _TB/_BT */
1180 ret
= v4l2_subdev_call(sd
, video
, querystd
, &std
);
1182 std
= V4L2_STD_625_50
;
1184 field
= std
& V4L2_STD_625_50
? V4L2_FIELD_INTERLACED_TB
:
1185 V4L2_FIELD_INTERLACED_BT
;
1189 xlate
= soc_camera_xlate_by_fourcc(icd
, pixfmt
);
1191 dev_warn(dev
, "Format %x not found\n", pixfmt
);
1194 /* Calculate client output geometry */
1195 soc_camera_calc_client_output(icd
, &cam
->rect
, &cam
->subrect
, pix
, &mf
,
1197 mf
.field
= pix
->field
;
1198 mf
.colorspace
= pix
->colorspace
;
1199 mf
.code
= xlate
->code
;
1202 case V4L2_PIX_FMT_RGB32
:
1203 can_scale
= priv
->chip
!= RCAR_E1
;
1205 case V4L2_PIX_FMT_UYVY
:
1206 case V4L2_PIX_FMT_YUYV
:
1207 case V4L2_PIX_FMT_RGB565
:
1208 case V4L2_PIX_FMT_RGB555X
:
1216 dev_dbg(dev
, "request camera output %ux%u\n", mf
.width
, mf
.height
);
1218 ret
= soc_camera_client_scale(icd
, &cam
->rect
, &cam
->subrect
,
1219 &mf
, &vin_sub_width
, &vin_sub_height
,
1222 /* Done with the camera. Now see if we can improve the result */
1223 dev_dbg(dev
, "Camera %d fmt %ux%u, requested %ux%u\n",
1224 ret
, mf
.width
, mf
.height
, pix
->width
, pix
->height
);
1226 if (ret
== -ENOIOCTLCMD
)
1227 dev_dbg(dev
, "Sensor doesn't support scaling\n");
1231 if (mf
.code
!= xlate
->code
)
1234 /* Prepare VIN crop */
1235 cam
->width
= mf
.width
;
1236 cam
->height
= mf
.height
;
1238 /* Use VIN scaling to scale to the requested user window. */
1240 /* We cannot scale up */
1241 if (pix
->width
> vin_sub_width
)
1242 vin_sub_width
= pix
->width
;
1244 if (pix
->height
> vin_sub_height
)
1245 vin_sub_height
= pix
->height
;
1247 pix
->colorspace
= mf
.colorspace
;
1250 pix
->width
= vin_sub_width
;
1251 pix
->height
= vin_sub_height
;
1255 * We have calculated CFLCR, the actual configuration will be performed
1256 * in rcar_vin_set_bus_param()
1259 dev_dbg(dev
, "W: %u : %u, H: %u : %u\n",
1260 vin_sub_width
, pix
->width
, vin_sub_height
, pix
->height
);
1262 icd
->current_fmt
= xlate
;
1264 priv
->field
= field
;
1269 static int rcar_vin_try_fmt(struct soc_camera_device
*icd
,
1270 struct v4l2_format
*f
)
1272 const struct soc_camera_format_xlate
*xlate
;
1273 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
1274 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
1275 struct v4l2_mbus_framefmt mf
;
1276 __u32 pixfmt
= pix
->pixelformat
;
1280 xlate
= soc_camera_xlate_by_fourcc(icd
, pixfmt
);
1282 xlate
= icd
->current_fmt
;
1283 dev_dbg(icd
->parent
, "Format %x not found, keeping %x\n",
1284 pixfmt
, xlate
->host_fmt
->fourcc
);
1285 pixfmt
= xlate
->host_fmt
->fourcc
;
1286 pix
->pixelformat
= pixfmt
;
1287 pix
->colorspace
= icd
->colorspace
;
1290 /* FIXME: calculate using depth and bus width */
1291 v4l_bound_align_image(&pix
->width
, 2, VIN_MAX_WIDTH
, 1,
1292 &pix
->height
, 4, VIN_MAX_HEIGHT
, 2, 0);
1295 height
= pix
->height
;
1297 /* let soc-camera calculate these values */
1298 pix
->bytesperline
= 0;
1301 /* limit to sensor capabilities */
1302 mf
.width
= pix
->width
;
1303 mf
.height
= pix
->height
;
1304 mf
.field
= pix
->field
;
1305 mf
.code
= xlate
->code
;
1306 mf
.colorspace
= pix
->colorspace
;
1308 ret
= v4l2_device_call_until_err(sd
->v4l2_dev
, soc_camera_grp_id(icd
),
1309 video
, try_mbus_fmt
, &mf
);
1313 pix
->width
= mf
.width
;
1314 pix
->height
= mf
.height
;
1315 pix
->field
= mf
.field
;
1316 pix
->colorspace
= mf
.colorspace
;
1318 if (pixfmt
== V4L2_PIX_FMT_NV16
) {
1319 /* FIXME: check against rect_max after converting soc-camera */
1320 /* We can scale precisely, need a bigger image from camera */
1321 if (pix
->width
< width
|| pix
->height
< height
) {
1323 * We presume, the sensor behaves sanely, i.e. if
1324 * requested a bigger rectangle, it will not return a
1327 mf
.width
= VIN_MAX_WIDTH
;
1328 mf
.height
= VIN_MAX_HEIGHT
;
1329 ret
= v4l2_device_call_until_err(sd
->v4l2_dev
,
1330 soc_camera_grp_id(icd
),
1331 video
, try_mbus_fmt
,
1334 dev_err(icd
->parent
,
1335 "client try_fmt() = %d\n", ret
);
1339 /* We will scale exactly */
1340 if (mf
.width
> width
)
1342 if (mf
.height
> height
)
1343 pix
->height
= height
;
1349 static unsigned int rcar_vin_poll(struct file
*file
, poll_table
*pt
)
1351 struct soc_camera_device
*icd
= file
->private_data
;
1353 return vb2_poll(&icd
->vb2_vidq
, file
, pt
);
1356 static int rcar_vin_querycap(struct soc_camera_host
*ici
,
1357 struct v4l2_capability
*cap
)
1359 strlcpy(cap
->card
, "R_Car_VIN", sizeof(cap
->card
));
1360 cap
->capabilities
= V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
;
1364 static int rcar_vin_init_videobuf2(struct vb2_queue
*vq
,
1365 struct soc_camera_device
*icd
)
1367 vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1368 vq
->io_modes
= VB2_MMAP
| VB2_USERPTR
;
1370 vq
->ops
= &rcar_vin_vb2_ops
;
1371 vq
->mem_ops
= &vb2_dma_contig_memops
;
1372 vq
->buf_struct_size
= sizeof(struct rcar_vin_buffer
);
1373 vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
1375 return vb2_queue_init(vq
);
1378 static struct soc_camera_host_ops rcar_vin_host_ops
= {
1379 .owner
= THIS_MODULE
,
1380 .add
= rcar_vin_add_device
,
1381 .remove
= rcar_vin_remove_device
,
1382 .clock_start
= rcar_vin_clock_start
,
1383 .clock_stop
= rcar_vin_clock_stop
,
1384 .get_formats
= rcar_vin_get_formats
,
1385 .put_formats
= rcar_vin_put_formats
,
1386 .get_crop
= rcar_vin_get_crop
,
1387 .set_crop
= rcar_vin_set_crop
,
1388 .try_fmt
= rcar_vin_try_fmt
,
1389 .set_fmt
= rcar_vin_set_fmt
,
1390 .poll
= rcar_vin_poll
,
1391 .querycap
= rcar_vin_querycap
,
1392 .set_bus_param
= rcar_vin_set_bus_param
,
1393 .init_videobuf2
= rcar_vin_init_videobuf2
,
1397 static struct of_device_id rcar_vin_of_table
[] = {
1398 { .compatible
= "renesas,vin-r8a7791", .data
= (void *)RCAR_GEN2
},
1399 { .compatible
= "renesas,vin-r8a7790", .data
= (void *)RCAR_GEN2
},
1400 { .compatible
= "renesas,vin-r8a7779", .data
= (void *)RCAR_H1
},
1401 { .compatible
= "renesas,vin-r8a7778", .data
= (void *)RCAR_M1
},
1404 MODULE_DEVICE_TABLE(of
, rcar_vin_of_table
);
1407 static struct platform_device_id rcar_vin_id_table
[] = {
1408 { "r8a7791-vin", RCAR_GEN2
},
1409 { "r8a7790-vin", RCAR_GEN2
},
1410 { "r8a7779-vin", RCAR_H1
},
1411 { "r8a7778-vin", RCAR_M1
},
1412 { "uPD35004-vin", RCAR_E1
},
1415 MODULE_DEVICE_TABLE(platform
, rcar_vin_id_table
);
1417 static int rcar_vin_probe(struct platform_device
*pdev
)
1419 const struct of_device_id
*match
= NULL
;
1420 struct rcar_vin_priv
*priv
;
1421 struct resource
*mem
;
1422 struct rcar_vin_platform_data
*pdata
;
1423 unsigned int pdata_flags
;
1426 if (pdev
->dev
.of_node
) {
1427 struct v4l2_of_endpoint ep
;
1428 struct device_node
*np
;
1430 match
= of_match_device(of_match_ptr(rcar_vin_of_table
),
1433 np
= of_graph_get_next_endpoint(pdev
->dev
.of_node
, NULL
);
1435 dev_err(&pdev
->dev
, "could not find endpoint\n");
1439 ret
= v4l2_of_parse_endpoint(np
, &ep
);
1441 dev_err(&pdev
->dev
, "could not parse endpoint\n");
1445 if (ep
.bus_type
== V4L2_MBUS_BT656
)
1446 pdata_flags
= RCAR_VIN_BT656
;
1449 if (ep
.bus
.parallel
.flags
& V4L2_MBUS_HSYNC_ACTIVE_LOW
)
1450 pdata_flags
|= RCAR_VIN_HSYNC_ACTIVE_LOW
;
1451 if (ep
.bus
.parallel
.flags
& V4L2_MBUS_VSYNC_ACTIVE_LOW
)
1452 pdata_flags
|= RCAR_VIN_VSYNC_ACTIVE_LOW
;
1457 dev_dbg(&pdev
->dev
, "pdata_flags = %08x\n", pdata_flags
);
1459 pdata
= pdev
->dev
.platform_data
;
1460 if (!pdata
|| !pdata
->flags
) {
1461 dev_err(&pdev
->dev
, "platform data not set\n");
1464 pdata_flags
= pdata
->flags
;
1467 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1471 irq
= platform_get_irq(pdev
, 0);
1475 priv
= devm_kzalloc(&pdev
->dev
, sizeof(struct rcar_vin_priv
),
1480 priv
->base
= devm_ioremap_resource(&pdev
->dev
, mem
);
1481 if (IS_ERR(priv
->base
))
1482 return PTR_ERR(priv
->base
);
1484 ret
= devm_request_irq(&pdev
->dev
, irq
, rcar_vin_irq
, IRQF_SHARED
,
1485 dev_name(&pdev
->dev
), priv
);
1489 priv
->alloc_ctx
= vb2_dma_contig_init_ctx(&pdev
->dev
);
1490 if (IS_ERR(priv
->alloc_ctx
))
1491 return PTR_ERR(priv
->alloc_ctx
);
1493 priv
->ici
.priv
= priv
;
1494 priv
->ici
.v4l2_dev
.dev
= &pdev
->dev
;
1495 priv
->ici
.drv_name
= dev_name(&pdev
->dev
);
1496 priv
->ici
.ops
= &rcar_vin_host_ops
;
1498 priv
->pdata_flags
= pdata_flags
;
1500 priv
->ici
.nr
= pdev
->id
;
1501 priv
->chip
= pdev
->id_entry
->driver_data
;
1503 priv
->ici
.nr
= of_alias_get_id(pdev
->dev
.of_node
, "vin");
1504 priv
->chip
= (enum chip_id
)match
->data
;
1507 spin_lock_init(&priv
->lock
);
1508 INIT_LIST_HEAD(&priv
->capture
);
1510 priv
->state
= STOPPED
;
1512 pm_suspend_ignore_children(&pdev
->dev
, true);
1513 pm_runtime_enable(&pdev
->dev
);
1515 ret
= soc_camera_host_register(&priv
->ici
);
1522 pm_runtime_disable(&pdev
->dev
);
1523 vb2_dma_contig_cleanup_ctx(priv
->alloc_ctx
);
1528 static int rcar_vin_remove(struct platform_device
*pdev
)
1530 struct soc_camera_host
*soc_host
= to_soc_camera_host(&pdev
->dev
);
1531 struct rcar_vin_priv
*priv
= container_of(soc_host
,
1532 struct rcar_vin_priv
, ici
);
1534 soc_camera_host_unregister(soc_host
);
1535 pm_runtime_disable(&pdev
->dev
);
1536 vb2_dma_contig_cleanup_ctx(priv
->alloc_ctx
);
1541 static struct platform_driver rcar_vin_driver
= {
1542 .probe
= rcar_vin_probe
,
1543 .remove
= rcar_vin_remove
,
1546 .owner
= THIS_MODULE
,
1547 .of_match_table
= of_match_ptr(rcar_vin_of_table
),
1549 .id_table
= rcar_vin_id_table
,
1552 module_platform_driver(rcar_vin_driver
);
1554 MODULE_LICENSE("GPL");
1555 MODULE_ALIAS("platform:rcar_vin");
1556 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");