Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/drivers/media/platform/soc_camera/rcar_vin.c

  1 /*
  2  * SoC-camera host driver for Renesas R-Car VIN unit
  3  *
  4  * Copyright (C) 2011-2013 Renesas Solutions Corp.
  5  * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
  6  *
  7  * Based on V4L2 Driver for SuperH Mobile CEU interface "sh_mobile_ceu_camera.c"
  8  *
  9  * Copyright (C) 2008 Magnus Damm
 10  *
 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.
 15  */
 16 
 17 #include <linux/delay.h>
 18 #include <linux/interrupt.h>
 19 #include <linux/io.h>
 20 #include <linux/kernel.h>
 21 #include <linux/module.h>
 22 #include <linux/of.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>
 29 
 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>
 39 
 40 #include "soc_scale_crop.h"
 41 
 42 #define DRV_NAME "rcar_vin"
 43 
 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 */
 67 
 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)
 84 
 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)
 90 
 91 /* Video n Frame Capture Register bits */
 92 #define VNFC_C_FRAME            (1 << 1)
 93 #define VNFC_S_FRAME            (1 << 0)
 94 
 95 /* Video n Interrupt Enable Register bits */
 96 #define VNIE_FIE                (1 << 4)
 97 #define VNIE_EFE                (1 << 1)
 98 
 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)
104 
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)
109 
110 #define VIN_MAX_WIDTH           2048
111 #define VIN_MAX_HEIGHT          2048
112 
113 enum chip_id {
114         RCAR_GEN2,
115         RCAR_H1,
116         RCAR_M1,
117         RCAR_E1,
118 };
119 
120 enum rcar_vin_state {
121         STOPPED = 0,
122         RUNNING,
123         STOPPING,
124 };
125 
126 struct rcar_vin_priv {
127         void __iomem                    *base;
128         spinlock_t                      lock;
129         int                             sequence;
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;
143         enum chip_id                    chip;
144 };
145 
146 #define is_continuous_transfer(priv)    (priv->vb_count > MAX_BUFFER_NUM)
147 
148 struct rcar_vin_buffer {
149         struct vb2_buffer               vb;
150         struct list_head                list;
151 };
152 
153 #define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
154                                                        struct rcar_vin_buffer, \
155                                                        vb)->list)
156 
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 */
162         unsigned int                    width;
163         unsigned int                    height;
164         /*
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
167          * input window
168          */
169         struct v4l2_rect                subrect;
170         /* Camera cropping rectangle */
171         struct v4l2_rect                rect;
172         const struct soc_mbus_pixelfmt  *extra_fmt;
173 };
174 
175 /*
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
178  * required
179  */
180 static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
181                                    const struct v4l2_format *fmt,
182                                    unsigned int *count,
183                                    unsigned int *num_planes,
184                                    unsigned int sizes[], void *alloc_ctxs[])
185 {
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;
189 
190         if (fmt) {
191                 const struct soc_camera_format_xlate *xlate;
192                 unsigned int bytes_per_line;
193                 int ret;
194 
195                 xlate = soc_camera_xlate_by_fourcc(icd,
196                                                    fmt->fmt.pix.pixelformat);
197                 if (!xlate)
198                         return -EINVAL;
199                 ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
200                                               xlate->host_fmt);
201                 if (ret < 0)
202                         return ret;
203 
204                 bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
205 
206                 ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
207                                           fmt->fmt.pix.height);
208                 if (ret < 0)
209                         return ret;
210 
211                 sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
212         } else {
213                 /* Called from VIDIOC_REQBUFS or in compatibility mode */
214                 sizes[0] = icd->sizeimage;
215         }
216 
217         alloc_ctxs[0] = priv->alloc_ctx;
218 
219         if (!vq->num_buffers)
220                 priv->sequence = 0;
221 
222         if (!*count)
223                 *count = 2;
224         priv->vb_count = *count;
225 
226         *num_planes = 1;
227 
228         /* Number of hardware slots */
229         if (is_continuous_transfer(priv))
230                 priv->nr_hw_slots = MAX_BUFFER_NUM;
231         else
232                 priv->nr_hw_slots = 1;
233 
234         dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
235 
236         return 0;
237 }
238 
239 static int rcar_vin_setup(struct rcar_vin_priv *priv)
240 {
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;
245 
246         switch (priv->field) {
247         case V4L2_FIELD_TOP:
248                 vnmc = VNMC_IM_ODD;
249                 break;
250         case V4L2_FIELD_BOTTOM:
251                 vnmc = VNMC_IM_EVEN;
252                 break;
253         case V4L2_FIELD_INTERLACED:
254         case V4L2_FIELD_INTERLACED_TB:
255                 vnmc = VNMC_IM_FULL;
256                 break;
257         case V4L2_FIELD_INTERLACED_BT:
258                 vnmc = VNMC_IM_FULL | VNMC_FOC;
259                 break;
260         case V4L2_FIELD_NONE:
261                 if (is_continuous_transfer(priv)) {
262                         vnmc = VNMC_IM_ODD_EVEN;
263                         progressive = true;
264                 } else {
265                         vnmc = VNMC_IM_ODD;
266                 }
267                 break;
268         default:
269                 vnmc = VNMC_IM_ODD;
270                 break;
271         }
272 
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;
278                 break;
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;
283                 break;
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;
288                 break;
289         default:
290                 break;
291         }
292 
293         /* output format */
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;
300                 break;
301         case V4L2_PIX_FMT_YUYV:
302                 dmr = VNDMR_BPSM;
303                 output_is_yuv = true;
304                 break;
305         case V4L2_PIX_FMT_UYVY:
306                 dmr = 0;
307                 output_is_yuv = true;
308                 break;
309         case V4L2_PIX_FMT_RGB555X:
310                 dmr = VNDMR_DTMD_ARGB1555;
311                 break;
312         case V4L2_PIX_FMT_RGB565:
313                 dmr = 0;
314                 break;
315         case V4L2_PIX_FMT_RGB32:
316                 if (priv->chip == RCAR_GEN2 || priv->chip == RCAR_H1 ||
317                     priv->chip == RCAR_E1) {
318                         dmr = VNDMR_EXRGB;
319                         break;
320                 }
321         default:
322                 dev_warn(icd->parent, "Invalid fourcc format (0x%x)\n",
323                          icd->current_fmt->host_fmt->fourcc);
324                 return -EINVAL;
325         }
326 
327         /* Always update on field change */
328         vnmc |= VNMC_VUP;
329 
330         /* If input and output use the same colorspace, use bypass mode */
331         if (output_is_yuv)
332                 vnmc |= VNMC_BPS;
333 
334         /* progressive or interlaced mode */
335         interrupts = progressive ? VNIE_FIE | VNIE_EFE : VNIE_EFE;
336 
337         /* ack interrupts */
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);
344 
345         return 0;
346 }
347 
348 static void rcar_vin_capture(struct rcar_vin_priv *priv)
349 {
350         if (is_continuous_transfer(priv))
351                 /* Continuous Frame Capture Mode */
352                 iowrite32(VNFC_C_FRAME, priv->base + VNFC_REG);
353         else
354                 /* Single Frame Capture Mode */
355                 iowrite32(VNFC_S_FRAME, priv->base + VNFC_REG);
356 }
357 
358 static void rcar_vin_request_capture_stop(struct rcar_vin_priv *priv)
359 {
360         priv->state = STOPPING;
361 
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);
367 
368         /* update the status if stopped already */
369         if (!(ioread32(priv->base + VNMS_REG) & VNMS_CA))
370                 priv->state = STOPPED;
371 }
372 
373 static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv *priv)
374 {
375         int slot;
376 
377         for (slot = 0; slot < priv->nr_hw_slots; slot++)
378                 if (priv->queue_buf[slot] == NULL)
379                         return slot;
380 
381         return -1;
382 }
383 
384 static int rcar_vin_hw_ready(struct rcar_vin_priv *priv)
385 {
386         /* Ensure all HW slots are filled */
387         return rcar_vin_get_free_hw_slot(priv) < 0 ? 1 : 0;
388 }
389 
390 /* Moves a buffer from the queue to the HW slots */
391 static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
392 {
393         struct vb2_buffer *vb;
394         dma_addr_t phys_addr_top;
395         int slot;
396 
397         if (list_empty(&priv->capture))
398                 return 0;
399 
400         /* Find a free HW slot */
401         slot = rcar_vin_get_free_hw_slot(priv);
402         if (slot < 0)
403                 return 0;
404 
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));
410 
411         return 1;
412 }
413 
414 static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
415 {
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;
419         unsigned long size;
420 
421         size = icd->sizeimage;
422 
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);
426                 goto error;
427         }
428 
429         vb2_set_plane_payload(vb, 0, size);
430 
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));
433 
434         spin_lock_irq(&priv->lock);
435 
436         list_add_tail(to_buf_list(vb), &priv->capture);
437         rcar_vin_fill_hw_slot(priv);
438 
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)) {
442                         /* Submit error */
443                         list_del_init(to_buf_list(vb));
444                         spin_unlock_irq(&priv->lock);
445                         goto error;
446                 }
447                 priv->request_to_stop = false;
448                 init_completion(&priv->capture_stop);
449                 priv->state = RUNNING;
450                 rcar_vin_capture(priv);
451         }
452 
453         spin_unlock_irq(&priv->lock);
454 
455         return;
456 
457 error:
458         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
459 }
460 
461 static void rcar_vin_videobuf_release(struct vb2_buffer *vb)
462 {
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;
466         unsigned int i;
467         int buf_in_use = 0;
468 
469         spin_lock_irq(&priv->lock);
470 
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) {
474                         buf_in_use = 1;
475                         break;
476                 }
477         }
478 
479         if (buf_in_use) {
480                 while (priv->state != STOPPED) {
481 
482                         /* issue stop if running */
483                         if (priv->state == RUNNING)
484                                 rcar_vin_request_capture_stop(priv);
485 
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);
492                         }
493                 }
494                 /*
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
498                  */
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;
504                         }
505                 }
506         } else {
507                 list_del_init(to_buf_list(vb));
508         }
509 
510         spin_unlock_irq(&priv->lock);
511 }
512 
513 static int rcar_vin_videobuf_init(struct vb2_buffer *vb)
514 {
515         INIT_LIST_HEAD(to_buf_list(vb));
516         return 0;
517 }
518 
519 static void rcar_vin_stop_streaming(struct vb2_queue *vq)
520 {
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;
525 
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);
530 }
531 
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,
540 };
541 
542 static irqreturn_t rcar_vin_irq(int irq, void *data)
543 {
544         struct rcar_vin_priv *priv = data;
545         u32 int_status;
546         bool can_run = false, hw_stopped;
547         int slot;
548         unsigned int handled = 0;
549 
550         spin_lock(&priv->lock);
551 
552         int_status = ioread32(priv->base + VNINTS_REG);
553         if (!int_status)
554                 goto done;
555         /* ack interrupts */
556         iowrite32(int_status, priv->base + VNINTS_REG);
557         handled = 1;
558 
559         /* nothing to do if capture status is 'STOPPED' */
560         if (priv->state == STOPPED)
561                 goto done;
562 
563         hw_stopped = !(ioread32(priv->base + VNMS_REG) & VNMS_CA);
564 
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;
569                 else
570                         slot = 0;
571 
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;
577 
578                 if (priv->state != STOPPING)
579                         can_run = rcar_vin_fill_hw_slot(priv);
580 
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) {
586                         /*
587                          * The continuous capturing requires an explicit stop
588                          * operation when there is no buffer to be set into
589                          * the VnMBm registers.
590                          */
591                         rcar_vin_request_capture_stop(priv);
592                 } else {
593                         rcar_vin_capture(priv);
594                 }
595 
596         } else if (hw_stopped) {
597                 priv->state = STOPPED;
598                 priv->request_to_stop = false;
599                 complete(&priv->capture_stop);
600         }
601 
602 done:
603         spin_unlock(&priv->lock);
604 
605         return IRQ_RETVAL(handled);
606 }
607 
608 static int rcar_vin_add_device(struct soc_camera_device *icd)
609 {
610         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
611         struct rcar_vin_priv *priv = ici->priv;
612         int i;
613 
614         for (i = 0; i < MAX_BUFFER_NUM; i++)
615                 priv->queue_buf[i] = NULL;
616 
617         pm_runtime_get_sync(ici->v4l2_dev.dev);
618 
619         dev_dbg(icd->parent, "R-Car VIN driver attached to camera %d\n",
620                 icd->devnum);
621 
622         return 0;
623 }
624 
625 static void rcar_vin_remove_device(struct soc_camera_device *icd)
626 {
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;
630         int i;
631 
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);
636 
637         priv->state = STOPPED;
638         priv->request_to_stop = false;
639 
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];
644                 if (vb) {
645                         list_del_init(to_buf_list(vb));
646                         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
647                 }
648         }
649         spin_unlock_irq(&priv->lock);
650 
651         pm_runtime_put(ici->v4l2_dev.dev);
652 
653         dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
654                 icd->devnum);
655 }
656 
657 /* Called with .host_lock held */
658 static int rcar_vin_clock_start(struct soc_camera_host *ici)
659 {
660         /* VIN does not have "mclk" */
661         return 0;
662 }
663 
664 /* Called with .host_lock held */
665 static void rcar_vin_clock_stop(struct soc_camera_host *ici)
666 {
667         /* VIN does not have "mclk" */
668 }
669 
670 /* rect is guaranteed to not exceed the scaled camera rectangle */
671 static int rcar_vin_set_rect(struct soc_camera_device *icd)
672 {
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;
679 
680         dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
681                 icd->user_width, icd->user_height, cam->vin_left, cam->vin_top);
682 
683         left_offset = cam->vin_left;
684         top_offset = cam->vin_top;
685 
686         if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB32 &&
687             priv->chip == RCAR_E1)
688                 dsize = 1;
689 
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);
695 
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);
707                 break;
708         default:
709                 iowrite32(top_offset, priv->base + VNSLPRC_REG);
710                 iowrite32(top_offset + cam->height - 1,
711                           priv->base + VNELPRC_REG);
712                 break;
713         }
714 
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);
725                 break;
726         default:
727                 iowrite32(cam_subrect->height - 1, priv->base + VNELPOC_REG);
728                 break;
729         }
730 
731         iowrite32(ALIGN(cam->width, 0x10), priv->base + VNIS_REG);
732 
733         return 0;
734 }
735 
736 static void capture_stop_preserve(struct rcar_vin_priv *priv, u32 *vnmc)
737 {
738         *vnmc = ioread32(priv->base + VNMC_REG);
739         /* module disable */
740         iowrite32(*vnmc & ~VNMC_ME, priv->base + VNMC_REG);
741 }
742 
743 static void capture_restore(struct rcar_vin_priv *priv, u32 vnmc)
744 {
745         unsigned long timeout = jiffies + 10 * HZ;
746 
747         /*
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.
750          */
751         while ((ioread32(priv->base + VNMS_REG) & VNMS_AV) &&
752                 time_before(jiffies, timeout))
753                 msleep(1);
754 
755         if (time_after(jiffies, timeout)) {
756                 dev_err(priv->ici.v4l2_dev.dev,
757                         "Timeout waiting for frame end! Interface problem?\n");
758                 return;
759         }
760 
761         iowrite32(vnmc, priv->base + VNMC_REG);
762 }
763 
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)
771 
772 static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
773 {
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;
779         u32 vnmc;
780         u32 val;
781         int ret;
782 
783         capture_stop_preserve(priv, &vnmc);
784 
785         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
786         if (!ret) {
787                 common_flags = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
788                 if (!common_flags) {
789                         dev_warn(icd->parent,
790                                  "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
791                                  cfg.flags, VIN_MBUS_FLAGS);
792                         return -EINVAL;
793                 }
794         } else if (ret != -ENOIOCTLCMD) {
795                 return ret;
796         } else {
797                 common_flags = VIN_MBUS_FLAGS;
798         }
799 
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;
805                 else
806                         common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
807         }
808 
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;
813                 else
814                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
815         }
816 
817         cfg.flags = common_flags;
818         ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
819         if (ret < 0 && ret != -ENOIOCTLCMD)
820                 return ret;
821 
822         val = priv->field == V4L2_FIELD_NONE ? VNDMR2_FTEV : 0;
823         if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
824                 val |= VNDMR2_VPS;
825         if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
826                 val |= VNDMR2_HPS;
827         iowrite32(val, priv->base + VNDMR2_REG);
828 
829         ret = rcar_vin_set_rect(icd);
830         if (ret < 0)
831                 return ret;
832 
833         capture_restore(priv, vnmc);
834 
835         return 0;
836 }
837 
838 static int rcar_vin_try_bus_param(struct soc_camera_device *icd,
839                                   unsigned char buswidth)
840 {
841         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
842         struct v4l2_mbus_config cfg;
843         int ret;
844 
845         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
846         if (ret == -ENOIOCTLCMD)
847                 return 0;
848         else if (ret)
849                 return ret;
850 
851         if (buswidth > 24)
852                 return -EINVAL;
853 
854         /* check is there common mbus flags */
855         ret = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
856         if (ret)
857                 return 0;
858 
859         dev_warn(icd->parent,
860                 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
861                  cfg.flags, VIN_MBUS_FLAGS);
862 
863         return -EINVAL;
864 }
865 
866 static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
867 {
868         return  fmt->packing == SOC_MBUS_PACKING_NONE ||
869                 (fmt->bits_per_sample > 8 &&
870                  fmt->packing == SOC_MBUS_PACKING_EXTEND16);
871 }
872 
873 static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
874         {
875                 .fourcc                 = V4L2_PIX_FMT_NV16,
876                 .name                   = "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,
881         },
882         {
883                 .fourcc                 = V4L2_PIX_FMT_UYVY,
884                 .name                   = "UYVY",
885                 .bits_per_sample        = 16,
886                 .packing                = SOC_MBUS_PACKING_NONE,
887                 .order                  = SOC_MBUS_ORDER_LE,
888                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
889         },
890         {
891                 .fourcc                 = V4L2_PIX_FMT_RGB565,
892                 .name                   = "RGB565",
893                 .bits_per_sample        = 16,
894                 .packing                = SOC_MBUS_PACKING_NONE,
895                 .order                  = SOC_MBUS_ORDER_LE,
896                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
897         },
898         {
899                 .fourcc                 = V4L2_PIX_FMT_RGB555X,
900                 .name                   = "ARGB1555",
901                 .bits_per_sample        = 16,
902                 .packing                = SOC_MBUS_PACKING_NONE,
903                 .order                  = SOC_MBUS_ORDER_LE,
904                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
905         },
906         {
907                 .fourcc                 = V4L2_PIX_FMT_RGB32,
908                 .name                   = "RGB888",
909                 .bits_per_sample        = 32,
910                 .packing                = SOC_MBUS_PACKING_NONE,
911                 .order                  = SOC_MBUS_ORDER_LE,
912                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
913         },
914 };
915 
916 static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
917                                 struct soc_camera_format_xlate *xlate)
918 {
919         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
920         struct device *dev = icd->parent;
921         int ret, k, n;
922         int formats = 0;
923         struct rcar_vin_cam *cam;
924         enum v4l2_mbus_pixelcode code;
925         const struct soc_mbus_pixelfmt *fmt;
926 
927         ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
928         if (ret < 0)
929                 return 0;
930 
931         fmt = soc_mbus_get_fmtdesc(code);
932         if (!fmt) {
933                 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
934                 return 0;
935         }
936 
937         ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
938         if (ret < 0)
939                 return 0;
940 
941         if (!icd->host_priv) {
942                 struct v4l2_mbus_framefmt mf;
943                 struct v4l2_rect rect;
944                 struct device *dev = icd->parent;
945                 int shift;
946 
947                 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
948                 if (ret < 0)
949                         return ret;
950 
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 */
955                         rect.left = 0;
956                         rect.top = 0;
957                         rect.width = mf.width;
958                         rect.height = mf.height;
959                 } else if (ret < 0) {
960                         return ret;
961                 }
962 
963                 /*
964                  * If sensor proposes too large format then try smaller ones:
965                  * 1280x960, 640x480, 320x240
966                  */
967                 for (shift = 0; shift < 3; shift++) {
968                         if (mf.width <= VIN_MAX_WIDTH &&
969                             mf.height <= VIN_MAX_HEIGHT)
970                                 break;
971 
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),
976                                                          video, s_mbus_fmt,
977                                                          &mf);
978                         if (ret < 0)
979                                 return ret;
980                 }
981 
982                 if (shift == 3) {
983                         dev_err(dev,
984                                 "Failed to configure the client below %ux%u\n",
985                                 mf.width, mf.height);
986                         return -EIO;
987                 }
988 
989                 dev_dbg(dev, "camera fmt %ux%u\n", mf.width, mf.height);
990 
991                 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
992                 if (!cam)
993                         return -ENOMEM;
994                 /*
995                  * We are called with current camera crop,
996                  * initialise subrect with it
997                  */
998                 cam->rect = rect;
999                 cam->subrect = rect;
1000                 cam->width = mf.width;
1001                 cam->height = mf.height;
1002 
1003                 icd->host_priv = cam;
1004         } else {
1005                 cam = icd->host_priv;
1006         }
1007 
1008         /* Beginning of a pass */
1009         if (!idx)
1010                 cam->extra_fmt = NULL;
1011 
1012         switch (code) {
1013         case V4L2_MBUS_FMT_YUYV8_1X16:
1014         case V4L2_MBUS_FMT_YUYV8_2X8:
1015         case V4L2_MBUS_FMT_YUYV10_2X10:
1016                 if (cam->extra_fmt)
1017                         break;
1018 
1019                 /* Add all our formats that can be generated by VIN */
1020                 cam->extra_fmt = rcar_vin_formats;
1021 
1022                 n = ARRAY_SIZE(rcar_vin_formats);
1023                 formats += n;
1024                 for (k = 0; xlate && k < n; k++, xlate++) {
1025                         xlate->host_fmt = &rcar_vin_formats[k];
1026                         xlate->code = code;
1027                         dev_dbg(dev, "Providing format %s using code %d\n",
1028                                 rcar_vin_formats[k].name, code);
1029                 }
1030                 break;
1031         default:
1032                 if (!rcar_vin_packing_supported(fmt))
1033                         return 0;
1034 
1035                 dev_dbg(dev, "Providing format %s in pass-through mode\n",
1036                         fmt->name);
1037                 break;
1038         }
1039 
1040         /* Generic pass-through */
1041         formats++;
1042         if (xlate) {
1043                 xlate->host_fmt = fmt;
1044                 xlate->code = code;
1045                 xlate++;
1046         }
1047 
1048         return formats;
1049 }
1050 
1051 static void rcar_vin_put_formats(struct soc_camera_device *icd)
1052 {
1053         kfree(icd->host_priv);
1054         icd->host_priv = NULL;
1055 }
1056 
1057 static int rcar_vin_set_crop(struct soc_camera_device *icd,
1058                              const struct v4l2_crop *a)
1059 {
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;
1070         u32 vnmc;
1071         int ret, i;
1072 
1073         dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1074                 rect->left, rect->top);
1075 
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);
1079 
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);
1083         if (ret < 0)
1084                 return ret;
1085 
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);
1089 
1090         /* On success cam_crop contains current camera crop */
1091 
1092         /* Retrieve camera output window */
1093         ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1094         if (ret < 0)
1095                 return ret;
1096 
1097         if (mf.width > VIN_MAX_WIDTH || mf.height > VIN_MAX_HEIGHT)
1098                 return -EINVAL;
1099 
1100         /* Cache camera output window */
1101         cam->width = mf.width;
1102         cam->height = mf.height;
1103 
1104         icd->user_width  = cam->width;
1105         icd->user_height = cam->height;
1106 
1107         cam->vin_left = rect->left & ~1;
1108         cam->vin_top = rect->top & ~1;
1109 
1110         /* Use VIN cropping to crop to the new window. */
1111         ret = rcar_vin_set_rect(icd);
1112         if (ret < 0)
1113                 return ret;
1114 
1115         cam->subrect = *rect;
1116 
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);
1120 
1121         /* Restore capture */
1122         for (i = 0; i < MAX_BUFFER_NUM; i++) {
1123                 if (priv->queue_buf[i] && priv->state == STOPPED) {
1124                         vnmc |= VNMC_ME;
1125                         break;
1126                 }
1127         }
1128         capture_restore(priv, vnmc);
1129 
1130         /* Even if only camera cropping succeeded */
1131         return ret;
1132 }
1133 
1134 static int rcar_vin_get_crop(struct soc_camera_device *icd,
1135                              struct v4l2_crop *a)
1136 {
1137         struct rcar_vin_cam *cam = icd->host_priv;
1138 
1139         a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1140         a->c = cam->subrect;
1141 
1142         return 0;
1143 }
1144 
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)
1148 {
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;
1159         int ret;
1160         bool can_scale;
1161         enum v4l2_field field;
1162         v4l2_std_id std;
1163 
1164         dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
1165                 pixfmt, pix->width, pix->height);
1166 
1167         switch (pix->field) {
1168         default:
1169                 pix->field = V4L2_FIELD_NONE;
1170                 /* fall-through */
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:
1176                 field = pix->field;
1177                 break;
1178         case V4L2_FIELD_INTERLACED:
1179                 /* Query for standard if not explicitly mentioned _TB/_BT */
1180                 ret = v4l2_subdev_call(sd, video, querystd, &std);
1181                 if (ret < 0)
1182                         std = V4L2_STD_625_50;
1183 
1184                 field = std & V4L2_STD_625_50 ? V4L2_FIELD_INTERLACED_TB :
1185                                                 V4L2_FIELD_INTERLACED_BT;
1186                 break;
1187         }
1188 
1189         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1190         if (!xlate) {
1191                 dev_warn(dev, "Format %x not found\n", pixfmt);
1192                 return -EINVAL;
1193         }
1194         /* Calculate client output geometry */
1195         soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
1196                                       12);
1197         mf.field = pix->field;
1198         mf.colorspace = pix->colorspace;
1199         mf.code  = xlate->code;
1200 
1201         switch (pixfmt) {
1202         case V4L2_PIX_FMT_RGB32:
1203                 can_scale = priv->chip != RCAR_E1;
1204                 break;
1205         case V4L2_PIX_FMT_UYVY:
1206         case V4L2_PIX_FMT_YUYV:
1207         case V4L2_PIX_FMT_RGB565:
1208         case V4L2_PIX_FMT_RGB555X:
1209                 can_scale = true;
1210                 break;
1211         default:
1212                 can_scale = false;
1213                 break;
1214         }
1215 
1216         dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
1217 
1218         ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
1219                                       &mf, &vin_sub_width, &vin_sub_height,
1220                                       can_scale, 12);
1221 
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);
1225 
1226         if (ret == -ENOIOCTLCMD)
1227                 dev_dbg(dev, "Sensor doesn't support scaling\n");
1228         else if (ret < 0)
1229                 return ret;
1230 
1231         if (mf.code != xlate->code)
1232                 return -EINVAL;
1233 
1234         /* Prepare VIN crop */
1235         cam->width = mf.width;
1236         cam->height = mf.height;
1237 
1238         /* Use VIN scaling to scale to the requested user window. */
1239 
1240         /* We cannot scale up */
1241         if (pix->width > vin_sub_width)
1242                 vin_sub_width = pix->width;
1243 
1244         if (pix->height > vin_sub_height)
1245                 vin_sub_height = pix->height;
1246 
1247         pix->colorspace = mf.colorspace;
1248 
1249         if (!can_scale) {
1250                 pix->width = vin_sub_width;
1251                 pix->height = vin_sub_height;
1252         }
1253 
1254         /*
1255          * We have calculated CFLCR, the actual configuration will be performed
1256          * in rcar_vin_set_bus_param()
1257          */
1258 
1259         dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
1260                 vin_sub_width, pix->width, vin_sub_height, pix->height);
1261 
1262         icd->current_fmt = xlate;
1263 
1264         priv->field = field;
1265 
1266         return 0;
1267 }
1268 
1269 static int rcar_vin_try_fmt(struct soc_camera_device *icd,
1270                             struct v4l2_format *f)
1271 {
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;
1277         int width, height;
1278         int ret;
1279 
1280         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1281         if (!xlate) {
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;
1288         }
1289 
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);
1293 
1294         width = pix->width;
1295         height = pix->height;
1296 
1297         /* let soc-camera calculate these values */
1298         pix->bytesperline = 0;
1299         pix->sizeimage = 0;
1300 
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;
1307 
1308         ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
1309                                          video, try_mbus_fmt, &mf);
1310         if (ret < 0)
1311                 return ret;
1312 
1313         pix->width = mf.width;
1314         pix->height = mf.height;
1315         pix->field = mf.field;
1316         pix->colorspace = mf.colorspace;
1317 
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) {
1322                         /*
1323                          * We presume, the sensor behaves sanely, i.e. if
1324                          * requested a bigger rectangle, it will not return a
1325                          * smaller one.
1326                          */
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,
1332                                                          &mf);
1333                         if (ret < 0) {
1334                                 dev_err(icd->parent,
1335                                         "client try_fmt() = %d\n", ret);
1336                                 return ret;
1337                         }
1338                 }
1339                 /* We will scale exactly */
1340                 if (mf.width > width)
1341                         pix->width = width;
1342                 if (mf.height > height)
1343                         pix->height = height;
1344         }
1345 
1346         return ret;
1347 }
1348 
1349 static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
1350 {
1351         struct soc_camera_device *icd = file->private_data;
1352 
1353         return vb2_poll(&icd->vb2_vidq, file, pt);
1354 }
1355 
1356 static int rcar_vin_querycap(struct soc_camera_host *ici,
1357                              struct v4l2_capability *cap)
1358 {
1359         strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
1360         cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1361         return 0;
1362 }
1363 
1364 static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
1365                                    struct soc_camera_device *icd)
1366 {
1367         vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1368         vq->io_modes = VB2_MMAP | VB2_USERPTR;
1369         vq->drv_priv = icd;
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;
1374 
1375         return vb2_queue_init(vq);
1376 }
1377 
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,
1394 };
1395 
1396 #ifdef CONFIG_OF
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 },
1402         { },
1403 };
1404 MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
1405 #endif
1406 
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 },
1413         {},
1414 };
1415 MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1416 
1417 static int rcar_vin_probe(struct platform_device *pdev)
1418 {
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;
1424         int irq, ret;
1425 
1426         if (pdev->dev.of_node) {
1427                 struct v4l2_of_endpoint ep;
1428                 struct device_node *np;
1429 
1430                 match = of_match_device(of_match_ptr(rcar_vin_of_table),
1431                                         &pdev->dev);
1432 
1433                 np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
1434                 if (!np) {
1435                         dev_err(&pdev->dev, "could not find endpoint\n");
1436                         return -EINVAL;
1437                 }
1438 
1439                 ret = v4l2_of_parse_endpoint(np, &ep);
1440                 if (ret) {
1441                         dev_err(&pdev->dev, "could not parse endpoint\n");
1442                         return ret;
1443                 }
1444 
1445                 if (ep.bus_type == V4L2_MBUS_BT656)
1446                         pdata_flags = RCAR_VIN_BT656;
1447                 else {
1448                         pdata_flags = 0;
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;
1453                 }
1454 
1455                 of_node_put(np);
1456 
1457                 dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
1458         } else {
1459                 pdata = pdev->dev.platform_data;
1460                 if (!pdata || !pdata->flags) {
1461                         dev_err(&pdev->dev, "platform data not set\n");
1462                         return -EINVAL;
1463                 }
1464                 pdata_flags = pdata->flags;
1465         }
1466 
1467         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1468         if (mem == NULL)
1469                 return -EINVAL;
1470 
1471         irq = platform_get_irq(pdev, 0);
1472         if (irq <= 0)
1473                 return -EINVAL;
1474 
1475         priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
1476                             GFP_KERNEL);
1477         if (!priv)
1478                 return -ENOMEM;
1479 
1480         priv->base = devm_ioremap_resource(&pdev->dev, mem);
1481         if (IS_ERR(priv->base))
1482                 return PTR_ERR(priv->base);
1483 
1484         ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
1485                                dev_name(&pdev->dev), priv);
1486         if (ret)
1487                 return ret;
1488 
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);
1492 
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;
1497 
1498         priv->pdata_flags = pdata_flags;
1499         if (!match) {
1500                 priv->ici.nr = pdev->id;
1501                 priv->chip = pdev->id_entry->driver_data;
1502         } else {
1503                 priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
1504                 priv->chip = (enum chip_id)match->data;
1505         }
1506 
1507         spin_lock_init(&priv->lock);
1508         INIT_LIST_HEAD(&priv->capture);
1509 
1510         priv->state = STOPPED;
1511 
1512         pm_suspend_ignore_children(&pdev->dev, true);
1513         pm_runtime_enable(&pdev->dev);
1514 
1515         ret = soc_camera_host_register(&priv->ici);
1516         if (ret)
1517                 goto cleanup;
1518 
1519         return 0;
1520 
1521 cleanup:
1522         pm_runtime_disable(&pdev->dev);
1523         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1524 
1525         return ret;
1526 }
1527 
1528 static int rcar_vin_remove(struct platform_device *pdev)
1529 {
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);
1533 
1534         soc_camera_host_unregister(soc_host);
1535         pm_runtime_disable(&pdev->dev);
1536         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1537 
1538         return 0;
1539 }
1540 
1541 static struct platform_driver rcar_vin_driver = {
1542         .probe          = rcar_vin_probe,
1543         .remove         = rcar_vin_remove,
1544         .driver         = {
1545                 .name           = DRV_NAME,
1546                 .owner          = THIS_MODULE,
1547                 .of_match_table = of_match_ptr(rcar_vin_of_table),
1548         },
1549         .id_table       = rcar_vin_id_table,
1550 };
1551 
1552 module_platform_driver(rcar_vin_driver);
1553 
1554 MODULE_LICENSE("GPL");
1555 MODULE_ALIAS("platform:rcar_vin");
1556 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
1557 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us