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>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/platform_data/camera-rcar.h>
22 #include <linux/platform_device.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/slab.h>
25 #include <linux/videodev2.h>
27 #include <media/soc_camera.h>
28 #include <media/soc_mediabus.h>
29 #include <media/v4l2-common.h>
30 #include <media/v4l2-dev.h>
31 #include <media/v4l2-device.h>
32 #include <media/v4l2-mediabus.h>
33 #include <media/v4l2-subdev.h>
34 #include <media/videobuf2-dma-contig.h>
36 #include "soc_scale_crop.h"
38 #define DRV_NAME "rcar_vin"
40 /* Register offsets for R-Car VIN */
41 #define VNMC_REG 0x00 /* Video n Main Control Register */
42 #define VNMS_REG 0x04 /* Video n Module Status Register */
43 #define VNFC_REG 0x08 /* Video n Frame Capture Register */
44 #define VNSLPRC_REG 0x0C /* Video n Start Line Pre-Clip Register */
45 #define VNELPRC_REG 0x10 /* Video n End Line Pre-Clip Register */
46 #define VNSPPRC_REG 0x14 /* Video n Start Pixel Pre-Clip Register */
47 #define VNEPPRC_REG 0x18 /* Video n End Pixel Pre-Clip Register */
48 #define VNSLPOC_REG 0x1C /* Video n Start Line Post-Clip Register */
49 #define VNELPOC_REG 0x20 /* Video n End Line Post-Clip Register */
50 #define VNSPPOC_REG 0x24 /* Video n Start Pixel Post-Clip Register */
51 #define VNEPPOC_REG 0x28 /* Video n End Pixel Post-Clip Register */
52 #define VNIS_REG 0x2C /* Video n Image Stride Register */
53 #define VNMB_REG(m) (0x30 + ((m) << 2)) /* Video n Memory Base m Register */
54 #define VNIE_REG 0x40 /* Video n Interrupt Enable Register */
55 #define VNINTS_REG 0x44 /* Video n Interrupt Status Register */
56 #define VNSI_REG 0x48 /* Video n Scanline Interrupt Register */
57 #define VNMTC_REG 0x4C /* Video n Memory Transfer Control Register */
58 #define VNYS_REG 0x50 /* Video n Y Scale Register */
59 #define VNXS_REG 0x54 /* Video n X Scale Register */
60 #define VNDMR_REG 0x58 /* Video n Data Mode Register */
61 #define VNDMR2_REG 0x5C /* Video n Data Mode Register 2 */
62 #define VNUVAOF_REG 0x60 /* Video n UV Address Offset Register */
64 /* Register bit fields for R-Car VIN */
65 /* Video n Main Control Register bits */
66 #define VNMC_FOC (1 << 21)
67 #define VNMC_YCAL (1 << 19)
68 #define VNMC_INF_YUV8_BT656 (0 << 16)
69 #define VNMC_INF_YUV8_BT601 (1 << 16)
70 #define VNMC_INF_YUV16 (5 << 16)
71 #define VNMC_VUP (1 << 10)
72 #define VNMC_IM_ODD (0 << 3)
73 #define VNMC_IM_ODD_EVEN (1 << 3)
74 #define VNMC_IM_EVEN (2 << 3)
75 #define VNMC_IM_FULL (3 << 3)
76 #define VNMC_BPS (1 << 1)
77 #define VNMC_ME (1 << 0)
79 /* Video n Module Status Register bits */
80 #define VNMS_FBS_MASK (3 << 3)
81 #define VNMS_FBS_SHIFT 3
82 #define VNMS_AV (1 << 1)
83 #define VNMS_CA (1 << 0)
85 /* Video n Frame Capture Register bits */
86 #define VNFC_C_FRAME (1 << 1)
87 #define VNFC_S_FRAME (1 << 0)
89 /* Video n Interrupt Enable Register bits */
90 #define VNIE_FIE (1 << 4)
91 #define VNIE_EFE (1 << 1)
93 /* Video n Data Mode Register bits */
94 #define VNDMR_EXRGB (1 << 8)
95 #define VNDMR_BPSM (1 << 4)
96 #define VNDMR_DTMD_YCSEP (1 << 1)
97 #define VNDMR_DTMD_ARGB1555 (1 << 0)
99 /* Video n Data Mode Register 2 bits */
100 #define VNDMR2_VPS (1 << 30)
101 #define VNDMR2_HPS (1 << 29)
102 #define VNDMR2_FTEV (1 << 17)
104 #define VIN_MAX_WIDTH 2048
105 #define VIN_MAX_HEIGHT 2048
113 enum rcar_vin_state
{
119 struct rcar_vin_priv
{
123 /* State of the VIN module in capturing mode */
124 enum rcar_vin_state state
;
125 struct rcar_vin_platform_data
*pdata
;
126 struct soc_camera_host ici
;
127 struct list_head capture
;
128 #define MAX_BUFFER_NUM 3
129 struct vb2_buffer
*queue_buf
[MAX_BUFFER_NUM
];
130 struct vb2_alloc_ctx
*alloc_ctx
;
131 enum v4l2_field field
;
132 unsigned int vb_count
;
133 unsigned int nr_hw_slots
;
134 bool request_to_stop
;
135 struct completion capture_stop
;
139 #define is_continuous_transfer(priv) (priv->vb_count > MAX_BUFFER_NUM)
141 struct rcar_vin_buffer
{
142 struct vb2_buffer vb
;
143 struct list_head list
;
146 #define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
147 struct rcar_vin_buffer, \
150 struct rcar_vin_cam
{
151 /* VIN offsets within the camera output, before the VIN scaler */
152 unsigned int vin_left
;
153 unsigned int vin_top
;
154 /* Client output, as seen by the VIN */
158 * User window from S_CROP / G_CROP, produced by client cropping and
159 * scaling, VIN scaling and VIN cropping, mapped back onto the client
162 struct v4l2_rect subrect
;
163 /* Camera cropping rectangle */
164 struct v4l2_rect rect
;
165 const struct soc_mbus_pixelfmt
*extra_fmt
;
169 * .queue_setup() is called to check whether the driver can accept the requested
170 * number of buffers and to fill in plane sizes for the current frame format if
173 static int rcar_vin_videobuf_setup(struct vb2_queue
*vq
,
174 const struct v4l2_format
*fmt
,
176 unsigned int *num_planes
,
177 unsigned int sizes
[], void *alloc_ctxs
[])
179 struct soc_camera_device
*icd
= soc_camera_from_vb2q(vq
);
180 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
181 struct rcar_vin_priv
*priv
= ici
->priv
;
184 const struct soc_camera_format_xlate
*xlate
;
185 unsigned int bytes_per_line
;
188 xlate
= soc_camera_xlate_by_fourcc(icd
,
189 fmt
->fmt
.pix
.pixelformat
);
192 ret
= soc_mbus_bytes_per_line(fmt
->fmt
.pix
.width
,
197 bytes_per_line
= max_t(u32
, fmt
->fmt
.pix
.bytesperline
, ret
);
199 ret
= soc_mbus_image_size(xlate
->host_fmt
, bytes_per_line
,
200 fmt
->fmt
.pix
.height
);
204 sizes
[0] = max_t(u32
, fmt
->fmt
.pix
.sizeimage
, ret
);
206 /* Called from VIDIOC_REQBUFS or in compatibility mode */
207 sizes
[0] = icd
->sizeimage
;
210 alloc_ctxs
[0] = priv
->alloc_ctx
;
212 if (!vq
->num_buffers
)
217 priv
->vb_count
= *count
;
221 /* Number of hardware slots */
222 if (is_continuous_transfer(priv
))
223 priv
->nr_hw_slots
= MAX_BUFFER_NUM
;
225 priv
->nr_hw_slots
= 1;
227 dev_dbg(icd
->parent
, "count=%d, size=%u\n", *count
, sizes
[0]);
232 static int rcar_vin_setup(struct rcar_vin_priv
*priv
)
234 struct soc_camera_device
*icd
= priv
->ici
.icd
;
235 struct rcar_vin_cam
*cam
= icd
->host_priv
;
236 u32 vnmc
, dmr
, interrupts
;
237 bool progressive
= false, output_is_yuv
= false;
239 switch (priv
->field
) {
243 case V4L2_FIELD_BOTTOM
:
246 case V4L2_FIELD_INTERLACED
:
247 case V4L2_FIELD_INTERLACED_TB
:
250 case V4L2_FIELD_INTERLACED_BT
:
251 vnmc
= VNMC_IM_FULL
| VNMC_FOC
;
253 case V4L2_FIELD_NONE
:
254 if (is_continuous_transfer(priv
)) {
255 vnmc
= VNMC_IM_ODD_EVEN
;
266 /* input interface */
267 switch (icd
->current_fmt
->code
) {
268 case V4L2_MBUS_FMT_YUYV8_1X16
:
269 /* BT.601/BT.1358 16bit YCbCr422 */
270 vnmc
|= VNMC_INF_YUV16
;
272 case V4L2_MBUS_FMT_YUYV8_2X8
:
273 /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
274 vnmc
|= priv
->pdata
->flags
& RCAR_VIN_BT656
?
275 VNMC_INF_YUV8_BT656
: VNMC_INF_YUV8_BT601
;
281 switch (icd
->current_fmt
->host_fmt
->fourcc
) {
282 case V4L2_PIX_FMT_NV16
:
283 iowrite32(ALIGN(cam
->width
* cam
->height
, 0x80),
284 priv
->base
+ VNUVAOF_REG
);
285 dmr
= VNDMR_DTMD_YCSEP
;
286 output_is_yuv
= true;
288 case V4L2_PIX_FMT_YUYV
:
290 output_is_yuv
= true;
292 case V4L2_PIX_FMT_UYVY
:
294 output_is_yuv
= true;
296 case V4L2_PIX_FMT_RGB555X
:
297 dmr
= VNDMR_DTMD_ARGB1555
;
299 case V4L2_PIX_FMT_RGB565
:
302 case V4L2_PIX_FMT_RGB32
:
303 if (priv
->chip
== RCAR_H1
|| priv
->chip
== RCAR_E1
) {
308 dev_warn(icd
->parent
, "Invalid fourcc format (0x%x)\n",
309 icd
->current_fmt
->host_fmt
->fourcc
);
313 /* Always update on field change */
316 /* If input and output use the same colorspace, use bypass mode */
320 /* progressive or interlaced mode */
321 interrupts
= progressive
? VNIE_FIE
| VNIE_EFE
: VNIE_EFE
;
324 iowrite32(interrupts
, priv
->base
+ VNINTS_REG
);
325 /* enable interrupts */
326 iowrite32(interrupts
, priv
->base
+ VNIE_REG
);
327 /* start capturing */
328 iowrite32(dmr
, priv
->base
+ VNDMR_REG
);
329 iowrite32(vnmc
| VNMC_ME
, priv
->base
+ VNMC_REG
);
334 static void rcar_vin_capture(struct rcar_vin_priv
*priv
)
336 if (is_continuous_transfer(priv
))
337 /* Continuous Frame Capture Mode */
338 iowrite32(VNFC_C_FRAME
, priv
->base
+ VNFC_REG
);
340 /* Single Frame Capture Mode */
341 iowrite32(VNFC_S_FRAME
, priv
->base
+ VNFC_REG
);
344 static void rcar_vin_request_capture_stop(struct rcar_vin_priv
*priv
)
346 priv
->state
= STOPPING
;
348 /* set continuous & single transfer off */
349 iowrite32(0, priv
->base
+ VNFC_REG
);
350 /* disable capture (release DMA buffer), reset */
351 iowrite32(ioread32(priv
->base
+ VNMC_REG
) & ~VNMC_ME
,
352 priv
->base
+ VNMC_REG
);
354 /* update the status if stopped already */
355 if (!(ioread32(priv
->base
+ VNMS_REG
) & VNMS_CA
))
356 priv
->state
= STOPPED
;
359 static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv
*priv
)
363 for (slot
= 0; slot
< priv
->nr_hw_slots
; slot
++)
364 if (priv
->queue_buf
[slot
] == NULL
)
370 static int rcar_vin_hw_ready(struct rcar_vin_priv
*priv
)
372 /* Ensure all HW slots are filled */
373 return rcar_vin_get_free_hw_slot(priv
) < 0 ? 1 : 0;
376 /* Moves a buffer from the queue to the HW slots */
377 static int rcar_vin_fill_hw_slot(struct rcar_vin_priv
*priv
)
379 struct vb2_buffer
*vb
;
380 dma_addr_t phys_addr_top
;
383 if (list_empty(&priv
->capture
))
386 /* Find a free HW slot */
387 slot
= rcar_vin_get_free_hw_slot(priv
);
391 vb
= &list_entry(priv
->capture
.next
, struct rcar_vin_buffer
, list
)->vb
;
392 list_del_init(to_buf_list(vb
));
393 priv
->queue_buf
[slot
] = vb
;
394 phys_addr_top
= vb2_dma_contig_plane_dma_addr(vb
, 0);
395 iowrite32(phys_addr_top
, priv
->base
+ VNMB_REG(slot
));
400 static void rcar_vin_videobuf_queue(struct vb2_buffer
*vb
)
402 struct soc_camera_device
*icd
= soc_camera_from_vb2q(vb
->vb2_queue
);
403 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
404 struct rcar_vin_priv
*priv
= ici
->priv
;
407 size
= icd
->sizeimage
;
409 if (vb2_plane_size(vb
, 0) < size
) {
410 dev_err(icd
->parent
, "Buffer #%d too small (%lu < %lu)\n",
411 vb
->v4l2_buf
.index
, vb2_plane_size(vb
, 0), size
);
415 vb2_set_plane_payload(vb
, 0, size
);
417 dev_dbg(icd
->parent
, "%s (vb=0x%p) 0x%p %lu\n", __func__
,
418 vb
, vb2_plane_vaddr(vb
, 0), vb2_get_plane_payload(vb
, 0));
420 spin_lock_irq(&priv
->lock
);
422 list_add_tail(to_buf_list(vb
), &priv
->capture
);
423 rcar_vin_fill_hw_slot(priv
);
425 /* If we weren't running, and have enough buffers, start capturing! */
426 if (priv
->state
!= RUNNING
&& rcar_vin_hw_ready(priv
)) {
427 if (rcar_vin_setup(priv
)) {
429 list_del_init(to_buf_list(vb
));
430 spin_unlock_irq(&priv
->lock
);
433 priv
->request_to_stop
= false;
434 init_completion(&priv
->capture_stop
);
435 priv
->state
= RUNNING
;
436 rcar_vin_capture(priv
);
439 spin_unlock_irq(&priv
->lock
);
444 vb2_buffer_done(vb
, VB2_BUF_STATE_ERROR
);
447 static void rcar_vin_videobuf_release(struct vb2_buffer
*vb
)
449 struct soc_camera_device
*icd
= soc_camera_from_vb2q(vb
->vb2_queue
);
450 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
451 struct rcar_vin_priv
*priv
= ici
->priv
;
455 spin_lock_irq(&priv
->lock
);
457 /* Is the buffer in use by the VIN hardware? */
458 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++) {
459 if (priv
->queue_buf
[i
] == vb
) {
466 while (priv
->state
!= STOPPED
) {
468 /* issue stop if running */
469 if (priv
->state
== RUNNING
)
470 rcar_vin_request_capture_stop(priv
);
472 /* wait until capturing has been stopped */
473 if (priv
->state
== STOPPING
) {
474 priv
->request_to_stop
= true;
475 spin_unlock_irq(&priv
->lock
);
476 wait_for_completion(&priv
->capture_stop
);
477 spin_lock_irq(&priv
->lock
);
481 * Capturing has now stopped. The buffer we have been asked
482 * to release could be any of the current buffers in use, so
483 * release all buffers that are in use by HW
485 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++) {
486 if (priv
->queue_buf
[i
]) {
487 vb2_buffer_done(priv
->queue_buf
[i
],
488 VB2_BUF_STATE_ERROR
);
489 priv
->queue_buf
[i
] = NULL
;
493 list_del_init(to_buf_list(vb
));
496 spin_unlock_irq(&priv
->lock
);
499 static int rcar_vin_videobuf_init(struct vb2_buffer
*vb
)
501 INIT_LIST_HEAD(to_buf_list(vb
));
505 static int rcar_vin_stop_streaming(struct vb2_queue
*vq
)
507 struct soc_camera_device
*icd
= soc_camera_from_vb2q(vq
);
508 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
509 struct rcar_vin_priv
*priv
= ici
->priv
;
510 struct list_head
*buf_head
, *tmp
;
512 spin_lock_irq(&priv
->lock
);
513 list_for_each_safe(buf_head
, tmp
, &priv
->capture
)
514 list_del_init(buf_head
);
515 spin_unlock_irq(&priv
->lock
);
520 static struct vb2_ops rcar_vin_vb2_ops
= {
521 .queue_setup
= rcar_vin_videobuf_setup
,
522 .buf_init
= rcar_vin_videobuf_init
,
523 .buf_cleanup
= rcar_vin_videobuf_release
,
524 .buf_queue
= rcar_vin_videobuf_queue
,
525 .stop_streaming
= rcar_vin_stop_streaming
,
526 .wait_prepare
= soc_camera_unlock
,
527 .wait_finish
= soc_camera_lock
,
530 static irqreturn_t
rcar_vin_irq(int irq
, void *data
)
532 struct rcar_vin_priv
*priv
= data
;
534 bool can_run
= false, hw_stopped
;
536 unsigned int handled
= 0;
538 spin_lock(&priv
->lock
);
540 int_status
= ioread32(priv
->base
+ VNINTS_REG
);
544 iowrite32(int_status
, priv
->base
+ VNINTS_REG
);
547 /* nothing to do if capture status is 'STOPPED' */
548 if (priv
->state
== STOPPED
)
551 hw_stopped
= !(ioread32(priv
->base
+ VNMS_REG
) & VNMS_CA
);
553 if (!priv
->request_to_stop
) {
554 if (is_continuous_transfer(priv
))
555 slot
= (ioread32(priv
->base
+ VNMS_REG
) &
556 VNMS_FBS_MASK
) >> VNMS_FBS_SHIFT
;
560 priv
->queue_buf
[slot
]->v4l2_buf
.field
= priv
->field
;
561 priv
->queue_buf
[slot
]->v4l2_buf
.sequence
= priv
->sequence
++;
562 do_gettimeofday(&priv
->queue_buf
[slot
]->v4l2_buf
.timestamp
);
563 vb2_buffer_done(priv
->queue_buf
[slot
], VB2_BUF_STATE_DONE
);
564 priv
->queue_buf
[slot
] = NULL
;
566 if (priv
->state
!= STOPPING
)
567 can_run
= rcar_vin_fill_hw_slot(priv
);
569 if (hw_stopped
|| !can_run
) {
570 priv
->state
= STOPPED
;
571 } else if (is_continuous_transfer(priv
) &&
572 list_empty(&priv
->capture
) &&
573 priv
->state
== RUNNING
) {
575 * The continuous capturing requires an explicit stop
576 * operation when there is no buffer to be set into
577 * the VnMBm registers.
579 rcar_vin_request_capture_stop(priv
);
581 rcar_vin_capture(priv
);
584 } else if (hw_stopped
) {
585 priv
->state
= STOPPED
;
586 priv
->request_to_stop
= false;
587 complete(&priv
->capture_stop
);
591 spin_unlock(&priv
->lock
);
593 return IRQ_RETVAL(handled
);
596 static int rcar_vin_add_device(struct soc_camera_device
*icd
)
598 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
599 struct rcar_vin_priv
*priv
= ici
->priv
;
602 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++)
603 priv
->queue_buf
[i
] = NULL
;
605 pm_runtime_get_sync(ici
->v4l2_dev
.dev
);
607 dev_dbg(icd
->parent
, "R-Car VIN driver attached to camera %d\n",
613 static void rcar_vin_remove_device(struct soc_camera_device
*icd
)
615 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
616 struct rcar_vin_priv
*priv
= ici
->priv
;
617 struct vb2_buffer
*vb
;
620 /* disable capture, disable interrupts */
621 iowrite32(ioread32(priv
->base
+ VNMC_REG
) & ~VNMC_ME
,
622 priv
->base
+ VNMC_REG
);
623 iowrite32(0, priv
->base
+ VNIE_REG
);
625 priv
->state
= STOPPED
;
626 priv
->request_to_stop
= false;
628 /* make sure active buffer is cancelled */
629 spin_lock_irq(&priv
->lock
);
630 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++) {
631 vb
= priv
->queue_buf
[i
];
633 list_del_init(to_buf_list(vb
));
634 vb2_buffer_done(vb
, VB2_BUF_STATE_ERROR
);
637 spin_unlock_irq(&priv
->lock
);
639 pm_runtime_put(ici
->v4l2_dev
.dev
);
641 dev_dbg(icd
->parent
, "R-Car VIN driver detached from camera %d\n",
645 /* Called with .host_lock held */
646 static int rcar_vin_clock_start(struct soc_camera_host
*ici
)
648 /* VIN does not have "mclk" */
652 /* Called with .host_lock held */
653 static void rcar_vin_clock_stop(struct soc_camera_host
*ici
)
655 /* VIN does not have "mclk" */
658 /* rect is guaranteed to not exceed the scaled camera rectangle */
659 static int rcar_vin_set_rect(struct soc_camera_device
*icd
)
661 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
662 struct rcar_vin_cam
*cam
= icd
->host_priv
;
663 struct rcar_vin_priv
*priv
= ici
->priv
;
664 unsigned int left_offset
, top_offset
;
665 unsigned char dsize
= 0;
666 struct v4l2_rect
*cam_subrect
= &cam
->subrect
;
668 dev_dbg(icd
->parent
, "Crop %ux%u@%u:%u\n",
669 icd
->user_width
, icd
->user_height
, cam
->vin_left
, cam
->vin_top
);
671 left_offset
= cam
->vin_left
;
672 top_offset
= cam
->vin_top
;
674 if (icd
->current_fmt
->host_fmt
->fourcc
== V4L2_PIX_FMT_RGB32
&&
675 priv
->chip
== RCAR_E1
)
678 dev_dbg(icd
->parent
, "Cam %ux%u@%u:%u\n",
679 cam
->width
, cam
->height
, cam
->vin_left
, cam
->vin_top
);
680 dev_dbg(icd
->parent
, "Cam subrect %ux%u@%u:%u\n",
681 cam_subrect
->width
, cam_subrect
->height
,
682 cam_subrect
->left
, cam_subrect
->top
);
684 /* Set Start/End Pixel/Line Pre-Clip */
685 iowrite32(left_offset
<< dsize
, priv
->base
+ VNSPPRC_REG
);
686 iowrite32((left_offset
+ cam
->width
- 1) << dsize
,
687 priv
->base
+ VNEPPRC_REG
);
688 switch (priv
->field
) {
689 case V4L2_FIELD_INTERLACED
:
690 case V4L2_FIELD_INTERLACED_TB
:
691 case V4L2_FIELD_INTERLACED_BT
:
692 iowrite32(top_offset
/ 2, priv
->base
+ VNSLPRC_REG
);
693 iowrite32((top_offset
+ cam
->height
) / 2 - 1,
694 priv
->base
+ VNELPRC_REG
);
697 iowrite32(top_offset
, priv
->base
+ VNSLPRC_REG
);
698 iowrite32(top_offset
+ cam
->height
- 1,
699 priv
->base
+ VNELPRC_REG
);
703 /* Set Start/End Pixel/Line Post-Clip */
704 iowrite32(0, priv
->base
+ VNSPPOC_REG
);
705 iowrite32(0, priv
->base
+ VNSLPOC_REG
);
706 iowrite32((cam_subrect
->width
- 1) << dsize
, priv
->base
+ VNEPPOC_REG
);
707 switch (priv
->field
) {
708 case V4L2_FIELD_INTERLACED
:
709 case V4L2_FIELD_INTERLACED_TB
:
710 case V4L2_FIELD_INTERLACED_BT
:
711 iowrite32(cam_subrect
->height
/ 2 - 1,
712 priv
->base
+ VNELPOC_REG
);
715 iowrite32(cam_subrect
->height
- 1, priv
->base
+ VNELPOC_REG
);
719 iowrite32(ALIGN(cam
->width
, 0x10), priv
->base
+ VNIS_REG
);
724 static void capture_stop_preserve(struct rcar_vin_priv
*priv
, u32
*vnmc
)
726 *vnmc
= ioread32(priv
->base
+ VNMC_REG
);
728 iowrite32(*vnmc
& ~VNMC_ME
, priv
->base
+ VNMC_REG
);
731 static void capture_restore(struct rcar_vin_priv
*priv
, u32 vnmc
)
733 unsigned long timeout
= jiffies
+ 10 * HZ
;
736 * Wait until the end of the current frame. It can take a long time,
737 * but if it has been aborted by a MRST1 reset, it should exit sooner.
739 while ((ioread32(priv
->base
+ VNMS_REG
) & VNMS_AV
) &&
740 time_before(jiffies
, timeout
))
743 if (time_after(jiffies
, timeout
)) {
744 dev_err(priv
->ici
.v4l2_dev
.dev
,
745 "Timeout waiting for frame end! Interface problem?\n");
749 iowrite32(vnmc
, priv
->base
+ VNMC_REG
);
752 #define VIN_MBUS_FLAGS (V4L2_MBUS_MASTER | \
753 V4L2_MBUS_PCLK_SAMPLE_RISING | \
754 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
755 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
756 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
757 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
758 V4L2_MBUS_DATA_ACTIVE_HIGH)
760 static int rcar_vin_set_bus_param(struct soc_camera_device
*icd
)
762 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
763 struct rcar_vin_priv
*priv
= ici
->priv
;
764 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
765 struct v4l2_mbus_config cfg
;
766 unsigned long common_flags
;
771 capture_stop_preserve(priv
, &vnmc
);
773 ret
= v4l2_subdev_call(sd
, video
, g_mbus_config
, &cfg
);
775 common_flags
= soc_mbus_config_compatible(&cfg
, VIN_MBUS_FLAGS
);
777 dev_warn(icd
->parent
,
778 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
779 cfg
.flags
, VIN_MBUS_FLAGS
);
782 } else if (ret
!= -ENOIOCTLCMD
) {
785 common_flags
= VIN_MBUS_FLAGS
;
788 /* Make choises, based on platform preferences */
789 if ((common_flags
& V4L2_MBUS_HSYNC_ACTIVE_HIGH
) &&
790 (common_flags
& V4L2_MBUS_HSYNC_ACTIVE_LOW
)) {
791 if (priv
->pdata
->flags
& RCAR_VIN_HSYNC_ACTIVE_LOW
)
792 common_flags
&= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH
;
794 common_flags
&= ~V4L2_MBUS_HSYNC_ACTIVE_LOW
;
797 if ((common_flags
& V4L2_MBUS_VSYNC_ACTIVE_HIGH
) &&
798 (common_flags
& V4L2_MBUS_VSYNC_ACTIVE_LOW
)) {
799 if (priv
->pdata
->flags
& RCAR_VIN_VSYNC_ACTIVE_LOW
)
800 common_flags
&= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH
;
802 common_flags
&= ~V4L2_MBUS_VSYNC_ACTIVE_LOW
;
805 cfg
.flags
= common_flags
;
806 ret
= v4l2_subdev_call(sd
, video
, s_mbus_config
, &cfg
);
807 if (ret
< 0 && ret
!= -ENOIOCTLCMD
)
810 val
= priv
->field
== V4L2_FIELD_NONE
? VNDMR2_FTEV
: 0;
811 if (!(common_flags
& V4L2_MBUS_VSYNC_ACTIVE_LOW
))
813 if (!(common_flags
& V4L2_MBUS_HSYNC_ACTIVE_LOW
))
815 iowrite32(val
, priv
->base
+ VNDMR2_REG
);
817 ret
= rcar_vin_set_rect(icd
);
821 capture_restore(priv
, vnmc
);
826 static int rcar_vin_try_bus_param(struct soc_camera_device
*icd
,
827 unsigned char buswidth
)
829 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
830 struct v4l2_mbus_config cfg
;
833 ret
= v4l2_subdev_call(sd
, video
, g_mbus_config
, &cfg
);
834 if (ret
== -ENOIOCTLCMD
)
842 /* check is there common mbus flags */
843 ret
= soc_mbus_config_compatible(&cfg
, VIN_MBUS_FLAGS
);
847 dev_warn(icd
->parent
,
848 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
849 cfg
.flags
, VIN_MBUS_FLAGS
);
854 static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt
*fmt
)
856 return fmt
->packing
== SOC_MBUS_PACKING_NONE
||
857 (fmt
->bits_per_sample
> 8 &&
858 fmt
->packing
== SOC_MBUS_PACKING_EXTEND16
);
861 static const struct soc_mbus_pixelfmt rcar_vin_formats
[] = {
863 .fourcc
= V4L2_PIX_FMT_NV16
,
865 .bits_per_sample
= 8,
866 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
867 .order
= SOC_MBUS_ORDER_LE
,
868 .layout
= SOC_MBUS_LAYOUT_PLANAR_Y_C
,
871 .fourcc
= V4L2_PIX_FMT_UYVY
,
873 .bits_per_sample
= 16,
874 .packing
= SOC_MBUS_PACKING_NONE
,
875 .order
= SOC_MBUS_ORDER_LE
,
876 .layout
= SOC_MBUS_LAYOUT_PACKED
,
879 .fourcc
= V4L2_PIX_FMT_RGB565
,
881 .bits_per_sample
= 16,
882 .packing
= SOC_MBUS_PACKING_NONE
,
883 .order
= SOC_MBUS_ORDER_LE
,
884 .layout
= SOC_MBUS_LAYOUT_PACKED
,
887 .fourcc
= V4L2_PIX_FMT_RGB555X
,
889 .bits_per_sample
= 16,
890 .packing
= SOC_MBUS_PACKING_NONE
,
891 .order
= SOC_MBUS_ORDER_LE
,
892 .layout
= SOC_MBUS_LAYOUT_PACKED
,
895 .fourcc
= V4L2_PIX_FMT_RGB32
,
897 .bits_per_sample
= 32,
898 .packing
= SOC_MBUS_PACKING_NONE
,
899 .order
= SOC_MBUS_ORDER_LE
,
900 .layout
= SOC_MBUS_LAYOUT_PACKED
,
904 static int rcar_vin_get_formats(struct soc_camera_device
*icd
, unsigned int idx
,
905 struct soc_camera_format_xlate
*xlate
)
907 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
908 struct device
*dev
= icd
->parent
;
911 struct rcar_vin_cam
*cam
;
912 enum v4l2_mbus_pixelcode code
;
913 const struct soc_mbus_pixelfmt
*fmt
;
915 ret
= v4l2_subdev_call(sd
, video
, enum_mbus_fmt
, idx
, &code
);
919 fmt
= soc_mbus_get_fmtdesc(code
);
921 dev_warn(dev
, "unsupported format code #%u: %d\n", idx
, code
);
925 ret
= rcar_vin_try_bus_param(icd
, fmt
->bits_per_sample
);
929 if (!icd
->host_priv
) {
930 struct v4l2_mbus_framefmt mf
;
931 struct v4l2_rect rect
;
932 struct device
*dev
= icd
->parent
;
935 ret
= v4l2_subdev_call(sd
, video
, g_mbus_fmt
, &mf
);
939 /* Cache current client geometry */
940 ret
= soc_camera_client_g_rect(sd
, &rect
);
941 if (ret
== -ENOIOCTLCMD
) {
942 /* Sensor driver doesn't support cropping */
945 rect
.width
= mf
.width
;
946 rect
.height
= mf
.height
;
947 } else if (ret
< 0) {
952 * If sensor proposes too large format then try smaller ones:
953 * 1280x960, 640x480, 320x240
955 for (shift
= 0; shift
< 3; shift
++) {
956 if (mf
.width
<= VIN_MAX_WIDTH
&&
957 mf
.height
<= VIN_MAX_HEIGHT
)
960 mf
.width
= 1280 >> shift
;
961 mf
.height
= 960 >> shift
;
962 ret
= v4l2_device_call_until_err(sd
->v4l2_dev
,
963 soc_camera_grp_id(icd
),
972 "Failed to configure the client below %ux%x\n",
973 mf
.width
, mf
.height
);
977 dev_dbg(dev
, "camera fmt %ux%u\n", mf
.width
, mf
.height
);
979 cam
= kzalloc(sizeof(*cam
), GFP_KERNEL
);
983 * We are called with current camera crop,
984 * initialise subrect with it
988 cam
->width
= mf
.width
;
989 cam
->height
= mf
.height
;
991 icd
->host_priv
= cam
;
993 cam
= icd
->host_priv
;
996 /* Beginning of a pass */
998 cam
->extra_fmt
= NULL
;
1001 case V4L2_MBUS_FMT_YUYV8_1X16
:
1002 case V4L2_MBUS_FMT_YUYV8_2X8
:
1006 /* Add all our formats that can be generated by VIN */
1007 cam
->extra_fmt
= rcar_vin_formats
;
1009 n
= ARRAY_SIZE(rcar_vin_formats
);
1011 for (k
= 0; xlate
&& k
< n
; k
++, xlate
++) {
1012 xlate
->host_fmt
= &rcar_vin_formats
[k
];
1014 dev_dbg(dev
, "Providing format %s using code %d\n",
1015 rcar_vin_formats
[k
].name
, code
);
1019 if (!rcar_vin_packing_supported(fmt
))
1022 dev_dbg(dev
, "Providing format %s in pass-through mode\n",
1027 /* Generic pass-through */
1030 xlate
->host_fmt
= fmt
;
1038 static void rcar_vin_put_formats(struct soc_camera_device
*icd
)
1040 kfree(icd
->host_priv
);
1041 icd
->host_priv
= NULL
;
1044 static int rcar_vin_set_crop(struct soc_camera_device
*icd
,
1045 const struct v4l2_crop
*a
)
1047 struct v4l2_crop a_writable
= *a
;
1048 const struct v4l2_rect
*rect
= &a_writable
.c
;
1049 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
1050 struct rcar_vin_priv
*priv
= ici
->priv
;
1051 struct v4l2_crop cam_crop
;
1052 struct rcar_vin_cam
*cam
= icd
->host_priv
;
1053 struct v4l2_rect
*cam_rect
= &cam_crop
.c
;
1054 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
1055 struct device
*dev
= icd
->parent
;
1056 struct v4l2_mbus_framefmt mf
;
1060 dev_dbg(dev
, "S_CROP(%ux%u@%u:%u)\n", rect
->width
, rect
->height
,
1061 rect
->left
, rect
->top
);
1063 /* During camera cropping its output window can change too, stop VIN */
1064 capture_stop_preserve(priv
, &vnmc
);
1065 dev_dbg(dev
, "VNMC_REG 0x%x\n", vnmc
);
1067 /* Apply iterative camera S_CROP for new input window. */
1068 ret
= soc_camera_client_s_crop(sd
, &a_writable
, &cam_crop
,
1069 &cam
->rect
, &cam
->subrect
);
1073 dev_dbg(dev
, "camera cropped to %ux%u@%u:%u\n",
1074 cam_rect
->width
, cam_rect
->height
,
1075 cam_rect
->left
, cam_rect
->top
);
1077 /* On success cam_crop contains current camera crop */
1079 /* Retrieve camera output window */
1080 ret
= v4l2_subdev_call(sd
, video
, g_mbus_fmt
, &mf
);
1084 if (mf
.width
> VIN_MAX_WIDTH
|| mf
.height
> VIN_MAX_HEIGHT
)
1087 /* Cache camera output window */
1088 cam
->width
= mf
.width
;
1089 cam
->height
= mf
.height
;
1091 icd
->user_width
= cam
->width
;
1092 icd
->user_height
= cam
->height
;
1094 cam
->vin_left
= rect
->left
& ~1;
1095 cam
->vin_top
= rect
->top
& ~1;
1097 /* Use VIN cropping to crop to the new window. */
1098 ret
= rcar_vin_set_rect(icd
);
1102 cam
->subrect
= *rect
;
1104 dev_dbg(dev
, "VIN cropped to %ux%u@%u:%u\n",
1105 icd
->user_width
, icd
->user_height
,
1106 cam
->vin_left
, cam
->vin_top
);
1108 /* Restore capture */
1109 for (i
= 0; i
< MAX_BUFFER_NUM
; i
++) {
1110 if (priv
->queue_buf
[i
] && priv
->state
== STOPPED
) {
1115 capture_restore(priv
, vnmc
);
1117 /* Even if only camera cropping succeeded */
1121 static int rcar_vin_get_crop(struct soc_camera_device
*icd
,
1122 struct v4l2_crop
*a
)
1124 struct rcar_vin_cam
*cam
= icd
->host_priv
;
1126 a
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1127 a
->c
= cam
->subrect
;
1132 /* Similar to set_crop multistage iterative algorithm */
1133 static int rcar_vin_set_fmt(struct soc_camera_device
*icd
,
1134 struct v4l2_format
*f
)
1136 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->parent
);
1137 struct rcar_vin_priv
*priv
= ici
->priv
;
1138 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
1139 struct rcar_vin_cam
*cam
= icd
->host_priv
;
1140 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
1141 struct v4l2_mbus_framefmt mf
;
1142 struct device
*dev
= icd
->parent
;
1143 __u32 pixfmt
= pix
->pixelformat
;
1144 const struct soc_camera_format_xlate
*xlate
;
1145 unsigned int vin_sub_width
= 0, vin_sub_height
= 0;
1148 enum v4l2_field field
;
1151 dev_dbg(dev
, "S_FMT(pix=0x%x, %ux%u)\n",
1152 pixfmt
, pix
->width
, pix
->height
);
1154 switch (pix
->field
) {
1156 pix
->field
= V4L2_FIELD_NONE
;
1158 case V4L2_FIELD_NONE
:
1159 case V4L2_FIELD_TOP
:
1160 case V4L2_FIELD_BOTTOM
:
1161 case V4L2_FIELD_INTERLACED_TB
:
1162 case V4L2_FIELD_INTERLACED_BT
:
1165 case V4L2_FIELD_INTERLACED
:
1166 /* Query for standard if not explicitly mentioned _TB/_BT */
1167 ret
= v4l2_subdev_call(sd
, video
, querystd
, &std
);
1169 std
= V4L2_STD_625_50
;
1171 field
= std
& V4L2_STD_625_50
? V4L2_FIELD_INTERLACED_TB
:
1172 V4L2_FIELD_INTERLACED_BT
;
1176 xlate
= soc_camera_xlate_by_fourcc(icd
, pixfmt
);
1178 dev_warn(dev
, "Format %x not found\n", pixfmt
);
1181 /* Calculate client output geometry */
1182 soc_camera_calc_client_output(icd
, &cam
->rect
, &cam
->subrect
, pix
, &mf
,
1184 mf
.field
= pix
->field
;
1185 mf
.colorspace
= pix
->colorspace
;
1186 mf
.code
= xlate
->code
;
1189 case V4L2_PIX_FMT_RGB32
:
1190 can_scale
= priv
->chip
!= RCAR_E1
;
1192 case V4L2_PIX_FMT_UYVY
:
1193 case V4L2_PIX_FMT_YUYV
:
1194 case V4L2_PIX_FMT_RGB565
:
1195 case V4L2_PIX_FMT_RGB555X
:
1203 dev_dbg(dev
, "request camera output %ux%u\n", mf
.width
, mf
.height
);
1205 ret
= soc_camera_client_scale(icd
, &cam
->rect
, &cam
->subrect
,
1206 &mf
, &vin_sub_width
, &vin_sub_height
,
1209 /* Done with the camera. Now see if we can improve the result */
1210 dev_dbg(dev
, "Camera %d fmt %ux%u, requested %ux%u\n",
1211 ret
, mf
.width
, mf
.height
, pix
->width
, pix
->height
);
1213 if (ret
== -ENOIOCTLCMD
)
1214 dev_dbg(dev
, "Sensor doesn't support scaling\n");
1218 if (mf
.code
!= xlate
->code
)
1221 /* Prepare VIN crop */
1222 cam
->width
= mf
.width
;
1223 cam
->height
= mf
.height
;
1225 /* Use VIN scaling to scale to the requested user window. */
1227 /* We cannot scale up */
1228 if (pix
->width
> vin_sub_width
)
1229 vin_sub_width
= pix
->width
;
1231 if (pix
->height
> vin_sub_height
)
1232 vin_sub_height
= pix
->height
;
1234 pix
->colorspace
= mf
.colorspace
;
1237 pix
->width
= vin_sub_width
;
1238 pix
->height
= vin_sub_height
;
1242 * We have calculated CFLCR, the actual configuration will be performed
1243 * in rcar_vin_set_bus_param()
1246 dev_dbg(dev
, "W: %u : %u, H: %u : %u\n",
1247 vin_sub_width
, pix
->width
, vin_sub_height
, pix
->height
);
1249 icd
->current_fmt
= xlate
;
1251 priv
->field
= field
;
1256 static int rcar_vin_try_fmt(struct soc_camera_device
*icd
,
1257 struct v4l2_format
*f
)
1259 const struct soc_camera_format_xlate
*xlate
;
1260 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
1261 struct v4l2_subdev
*sd
= soc_camera_to_subdev(icd
);
1262 struct v4l2_mbus_framefmt mf
;
1263 __u32 pixfmt
= pix
->pixelformat
;
1267 xlate
= soc_camera_xlate_by_fourcc(icd
, pixfmt
);
1269 xlate
= icd
->current_fmt
;
1270 dev_dbg(icd
->parent
, "Format %x not found, keeping %x\n",
1271 pixfmt
, xlate
->host_fmt
->fourcc
);
1272 pixfmt
= xlate
->host_fmt
->fourcc
;
1273 pix
->pixelformat
= pixfmt
;
1274 pix
->colorspace
= icd
->colorspace
;
1277 /* FIXME: calculate using depth and bus width */
1278 v4l_bound_align_image(&pix
->width
, 2, VIN_MAX_WIDTH
, 1,
1279 &pix
->height
, 4, VIN_MAX_HEIGHT
, 2, 0);
1282 height
= pix
->height
;
1284 /* let soc-camera calculate these values */
1285 pix
->bytesperline
= 0;
1288 /* limit to sensor capabilities */
1289 mf
.width
= pix
->width
;
1290 mf
.height
= pix
->height
;
1291 mf
.field
= pix
->field
;
1292 mf
.code
= xlate
->code
;
1293 mf
.colorspace
= pix
->colorspace
;
1295 ret
= v4l2_device_call_until_err(sd
->v4l2_dev
, soc_camera_grp_id(icd
),
1296 video
, try_mbus_fmt
, &mf
);
1300 pix
->width
= mf
.width
;
1301 pix
->height
= mf
.height
;
1302 pix
->field
= mf
.field
;
1303 pix
->colorspace
= mf
.colorspace
;
1305 if (pixfmt
== V4L2_PIX_FMT_NV16
) {
1306 /* FIXME: check against rect_max after converting soc-camera */
1307 /* We can scale precisely, need a bigger image from camera */
1308 if (pix
->width
< width
|| pix
->height
< height
) {
1310 * We presume, the sensor behaves sanely, i.e. if
1311 * requested a bigger rectangle, it will not return a
1314 mf
.width
= VIN_MAX_WIDTH
;
1315 mf
.height
= VIN_MAX_HEIGHT
;
1316 ret
= v4l2_device_call_until_err(sd
->v4l2_dev
,
1317 soc_camera_grp_id(icd
),
1318 video
, try_mbus_fmt
,
1321 dev_err(icd
->parent
,
1322 "client try_fmt() = %d\n", ret
);
1326 /* We will scale exactly */
1327 if (mf
.width
> width
)
1329 if (mf
.height
> height
)
1330 pix
->height
= height
;
1336 static unsigned int rcar_vin_poll(struct file
*file
, poll_table
*pt
)
1338 struct soc_camera_device
*icd
= file
->private_data
;
1340 return vb2_poll(&icd
->vb2_vidq
, file
, pt
);
1343 static int rcar_vin_querycap(struct soc_camera_host
*ici
,
1344 struct v4l2_capability
*cap
)
1346 strlcpy(cap
->card
, "R_Car_VIN", sizeof(cap
->card
));
1347 cap
->capabilities
= V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
;
1351 static int rcar_vin_init_videobuf2(struct vb2_queue
*vq
,
1352 struct soc_camera_device
*icd
)
1354 vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1355 vq
->io_modes
= VB2_MMAP
| VB2_USERPTR
;
1357 vq
->ops
= &rcar_vin_vb2_ops
;
1358 vq
->mem_ops
= &vb2_dma_contig_memops
;
1359 vq
->buf_struct_size
= sizeof(struct rcar_vin_buffer
);
1360 vq
->timestamp_type
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
1362 return vb2_queue_init(vq
);
1365 static struct soc_camera_host_ops rcar_vin_host_ops
= {
1366 .owner
= THIS_MODULE
,
1367 .add
= rcar_vin_add_device
,
1368 .remove
= rcar_vin_remove_device
,
1369 .clock_start
= rcar_vin_clock_start
,
1370 .clock_stop
= rcar_vin_clock_stop
,
1371 .get_formats
= rcar_vin_get_formats
,
1372 .put_formats
= rcar_vin_put_formats
,
1373 .get_crop
= rcar_vin_get_crop
,
1374 .set_crop
= rcar_vin_set_crop
,
1375 .try_fmt
= rcar_vin_try_fmt
,
1376 .set_fmt
= rcar_vin_set_fmt
,
1377 .poll
= rcar_vin_poll
,
1378 .querycap
= rcar_vin_querycap
,
1379 .set_bus_param
= rcar_vin_set_bus_param
,
1380 .init_videobuf2
= rcar_vin_init_videobuf2
,
1383 static struct platform_device_id rcar_vin_id_table
[] = {
1384 { "r8a7779-vin", RCAR_H1
},
1385 { "r8a7778-vin", RCAR_M1
},
1386 { "uPD35004-vin", RCAR_E1
},
1389 MODULE_DEVICE_TABLE(platform
, rcar_vin_id_table
);
1391 static int rcar_vin_probe(struct platform_device
*pdev
)
1393 struct rcar_vin_priv
*priv
;
1394 struct resource
*mem
;
1395 struct rcar_vin_platform_data
*pdata
;
1398 pdata
= pdev
->dev
.platform_data
;
1399 if (!pdata
|| !pdata
->flags
) {
1400 dev_err(&pdev
->dev
, "platform data not set\n");
1404 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1408 irq
= platform_get_irq(pdev
, 0);
1412 priv
= devm_kzalloc(&pdev
->dev
, sizeof(struct rcar_vin_priv
),
1417 priv
->base
= devm_ioremap_resource(&pdev
->dev
, mem
);
1418 if (IS_ERR(priv
->base
))
1419 return PTR_ERR(priv
->base
);
1421 ret
= devm_request_irq(&pdev
->dev
, irq
, rcar_vin_irq
, IRQF_SHARED
,
1422 dev_name(&pdev
->dev
), priv
);
1426 priv
->alloc_ctx
= vb2_dma_contig_init_ctx(&pdev
->dev
);
1427 if (IS_ERR(priv
->alloc_ctx
))
1428 return PTR_ERR(priv
->alloc_ctx
);
1430 priv
->ici
.priv
= priv
;
1431 priv
->ici
.v4l2_dev
.dev
= &pdev
->dev
;
1432 priv
->ici
.nr
= pdev
->id
;
1433 priv
->ici
.drv_name
= dev_name(&pdev
->dev
);
1434 priv
->ici
.ops
= &rcar_vin_host_ops
;
1436 priv
->pdata
= pdata
;
1437 priv
->chip
= pdev
->id_entry
->driver_data
;
1438 spin_lock_init(&priv
->lock
);
1439 INIT_LIST_HEAD(&priv
->capture
);
1441 priv
->state
= STOPPED
;
1443 pm_suspend_ignore_children(&pdev
->dev
, true);
1444 pm_runtime_enable(&pdev
->dev
);
1446 ret
= soc_camera_host_register(&priv
->ici
);
1453 pm_runtime_disable(&pdev
->dev
);
1454 vb2_dma_contig_cleanup_ctx(priv
->alloc_ctx
);
1459 static int rcar_vin_remove(struct platform_device
*pdev
)
1461 struct soc_camera_host
*soc_host
= to_soc_camera_host(&pdev
->dev
);
1462 struct rcar_vin_priv
*priv
= container_of(soc_host
,
1463 struct rcar_vin_priv
, ici
);
1465 soc_camera_host_unregister(soc_host
);
1466 pm_runtime_disable(&pdev
->dev
);
1467 vb2_dma_contig_cleanup_ctx(priv
->alloc_ctx
);
1472 static struct platform_driver rcar_vin_driver
= {
1473 .probe
= rcar_vin_probe
,
1474 .remove
= rcar_vin_remove
,
1477 .owner
= THIS_MODULE
,
1479 .id_table
= rcar_vin_id_table
,
1482 module_platform_driver(rcar_vin_driver
);
1484 MODULE_LICENSE("GPL");
1485 MODULE_ALIAS("platform:rcar_vin");
1486 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");