Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 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

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/platform_data/camera-rcar.h>
 23 #include <linux/platform_device.h>
 24 #include <linux/pm_runtime.h>
 25 #include <linux/slab.h>
 26 #include <linux/videodev2.h>
 27 
 28 #include <media/soc_camera.h>
 29 #include <media/soc_mediabus.h>
 30 #include <media/v4l2-common.h>
 31 #include <media/v4l2-dev.h>
 32 #include <media/v4l2-device.h>
 33 #include <media/v4l2-mediabus.h>
 34 #include <media/v4l2-subdev.h>
 35 #include <media/videobuf2-dma-contig.h>
 36 
 37 #include "soc_scale_crop.h"
 38 
 39 #define DRV_NAME "rcar_vin"
 40 
 41 /* Register offsets for R-Car VIN */
 42 #define VNMC_REG        0x00    /* Video n Main Control Register */
 43 #define VNMS_REG        0x04    /* Video n Module Status Register */
 44 #define VNFC_REG        0x08    /* Video n Frame Capture Register */
 45 #define VNSLPRC_REG     0x0C    /* Video n Start Line Pre-Clip Register */
 46 #define VNELPRC_REG     0x10    /* Video n End Line Pre-Clip Register */
 47 #define VNSPPRC_REG     0x14    /* Video n Start Pixel Pre-Clip Register */
 48 #define VNEPPRC_REG     0x18    /* Video n End Pixel Pre-Clip Register */
 49 #define VNSLPOC_REG     0x1C    /* Video n Start Line Post-Clip Register */
 50 #define VNELPOC_REG     0x20    /* Video n End Line Post-Clip Register */
 51 #define VNSPPOC_REG     0x24    /* Video n Start Pixel Post-Clip Register */
 52 #define VNEPPOC_REG     0x28    /* Video n End Pixel Post-Clip Register */
 53 #define VNIS_REG        0x2C    /* Video n Image Stride Register */
 54 #define VNMB_REG(m)     (0x30 + ((m) << 2)) /* Video n Memory Base m Register */
 55 #define VNIE_REG        0x40    /* Video n Interrupt Enable Register */
 56 #define VNINTS_REG      0x44    /* Video n Interrupt Status Register */
 57 #define VNSI_REG        0x48    /* Video n Scanline Interrupt Register */
 58 #define VNMTC_REG       0x4C    /* Video n Memory Transfer Control Register */
 59 #define VNYS_REG        0x50    /* Video n Y Scale Register */
 60 #define VNXS_REG        0x54    /* Video n X Scale Register */
 61 #define VNDMR_REG       0x58    /* Video n Data Mode Register */
 62 #define VNDMR2_REG      0x5C    /* Video n Data Mode Register 2 */
 63 #define VNUVAOF_REG     0x60    /* Video n UV Address Offset Register */
 64 
 65 /* Register bit fields for R-Car VIN */
 66 /* Video n Main Control Register bits */
 67 #define VNMC_FOC                (1 << 21)
 68 #define VNMC_YCAL               (1 << 19)
 69 #define VNMC_INF_YUV8_BT656     (0 << 16)
 70 #define VNMC_INF_YUV8_BT601     (1 << 16)
 71 #define VNMC_INF_YUV10_BT656    (2 << 16)
 72 #define VNMC_INF_YUV10_BT601    (3 << 16)
 73 #define VNMC_INF_YUV16          (5 << 16)
 74 #define VNMC_VUP                (1 << 10)
 75 #define VNMC_IM_ODD             (0 << 3)
 76 #define VNMC_IM_ODD_EVEN        (1 << 3)
 77 #define VNMC_IM_EVEN            (2 << 3)
 78 #define VNMC_IM_FULL            (3 << 3)
 79 #define VNMC_BPS                (1 << 1)
 80 #define VNMC_ME                 (1 << 0)
 81 
 82 /* Video n Module Status Register bits */
 83 #define VNMS_FBS_MASK           (3 << 3)
 84 #define VNMS_FBS_SHIFT          3
 85 #define VNMS_AV                 (1 << 1)
 86 #define VNMS_CA                 (1 << 0)
 87 
 88 /* Video n Frame Capture Register bits */
 89 #define VNFC_C_FRAME            (1 << 1)
 90 #define VNFC_S_FRAME            (1 << 0)
 91 
 92 /* Video n Interrupt Enable Register bits */
 93 #define VNIE_FIE                (1 << 4)
 94 #define VNIE_EFE                (1 << 1)
 95 
 96 /* Video n Data Mode Register bits */
 97 #define VNDMR_EXRGB             (1 << 8)
 98 #define VNDMR_BPSM              (1 << 4)
 99 #define VNDMR_DTMD_YCSEP        (1 << 1)
100 #define VNDMR_DTMD_ARGB1555     (1 << 0)
101 
102 /* Video n Data Mode Register 2 bits */
103 #define VNDMR2_VPS              (1 << 30)
104 #define VNDMR2_HPS              (1 << 29)
105 #define VNDMR2_FTEV             (1 << 17)
106 
107 #define VIN_MAX_WIDTH           2048
108 #define VIN_MAX_HEIGHT          2048
109 
110 enum chip_id {
111         RCAR_GEN2,
112         RCAR_H1,
113         RCAR_M1,
114         RCAR_E1,
115 };
116 
117 enum rcar_vin_state {
118         STOPPED = 0,
119         RUNNING,
120         STOPPING,
121 };
122 
123 struct rcar_vin_priv {
124         void __iomem                    *base;
125         spinlock_t                      lock;
126         int                             sequence;
127         /* State of the VIN module in capturing mode */
128         enum rcar_vin_state             state;
129         struct rcar_vin_platform_data   *pdata;
130         struct soc_camera_host          ici;
131         struct list_head                capture;
132 #define MAX_BUFFER_NUM                  3
133         struct vb2_buffer               *queue_buf[MAX_BUFFER_NUM];
134         struct vb2_alloc_ctx            *alloc_ctx;
135         enum v4l2_field                 field;
136         unsigned int                    vb_count;
137         unsigned int                    nr_hw_slots;
138         bool                            request_to_stop;
139         struct completion               capture_stop;
140         enum chip_id                    chip;
141 };
142 
143 #define is_continuous_transfer(priv)    (priv->vb_count > MAX_BUFFER_NUM)
144 
145 struct rcar_vin_buffer {
146         struct vb2_buffer               vb;
147         struct list_head                list;
148 };
149 
150 #define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
151                                                        struct rcar_vin_buffer, \
152                                                        vb)->list)
153 
154 struct rcar_vin_cam {
155         /* VIN offsets within the camera output, before the VIN scaler */
156         unsigned int                    vin_left;
157         unsigned int                    vin_top;
158         /* Client output, as seen by the VIN */
159         unsigned int                    width;
160         unsigned int                    height;
161         /*
162          * User window from S_CROP / G_CROP, produced by client cropping and
163          * scaling, VIN scaling and VIN cropping, mapped back onto the client
164          * input window
165          */
166         struct v4l2_rect                subrect;
167         /* Camera cropping rectangle */
168         struct v4l2_rect                rect;
169         const struct soc_mbus_pixelfmt  *extra_fmt;
170 };
171 
172 /*
173  * .queue_setup() is called to check whether the driver can accept the requested
174  * number of buffers and to fill in plane sizes for the current frame format if
175  * required
176  */
177 static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
178                                    const struct v4l2_format *fmt,
179                                    unsigned int *count,
180                                    unsigned int *num_planes,
181                                    unsigned int sizes[], void *alloc_ctxs[])
182 {
183         struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
184         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
185         struct rcar_vin_priv *priv = ici->priv;
186 
187         if (fmt) {
188                 const struct soc_camera_format_xlate *xlate;
189                 unsigned int bytes_per_line;
190                 int ret;
191 
192                 xlate = soc_camera_xlate_by_fourcc(icd,
193                                                    fmt->fmt.pix.pixelformat);
194                 if (!xlate)
195                         return -EINVAL;
196                 ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
197                                               xlate->host_fmt);
198                 if (ret < 0)
199                         return ret;
200 
201                 bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
202 
203                 ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
204                                           fmt->fmt.pix.height);
205                 if (ret < 0)
206                         return ret;
207 
208                 sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
209         } else {
210                 /* Called from VIDIOC_REQBUFS or in compatibility mode */
211                 sizes[0] = icd->sizeimage;
212         }
213 
214         alloc_ctxs[0] = priv->alloc_ctx;
215 
216         if (!vq->num_buffers)
217                 priv->sequence = 0;
218 
219         if (!*count)
220                 *count = 2;
221         priv->vb_count = *count;
222 
223         *num_planes = 1;
224 
225         /* Number of hardware slots */
226         if (is_continuous_transfer(priv))
227                 priv->nr_hw_slots = MAX_BUFFER_NUM;
228         else
229                 priv->nr_hw_slots = 1;
230 
231         dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
232 
233         return 0;
234 }
235 
236 static int rcar_vin_setup(struct rcar_vin_priv *priv)
237 {
238         struct soc_camera_device *icd = priv->ici.icd;
239         struct rcar_vin_cam *cam = icd->host_priv;
240         u32 vnmc, dmr, interrupts;
241         bool progressive = false, output_is_yuv = false;
242 
243         switch (priv->field) {
244         case V4L2_FIELD_TOP:
245                 vnmc = VNMC_IM_ODD;
246                 break;
247         case V4L2_FIELD_BOTTOM:
248                 vnmc = VNMC_IM_EVEN;
249                 break;
250         case V4L2_FIELD_INTERLACED:
251         case V4L2_FIELD_INTERLACED_TB:
252                 vnmc = VNMC_IM_FULL;
253                 break;
254         case V4L2_FIELD_INTERLACED_BT:
255                 vnmc = VNMC_IM_FULL | VNMC_FOC;
256                 break;
257         case V4L2_FIELD_NONE:
258                 if (is_continuous_transfer(priv)) {
259                         vnmc = VNMC_IM_ODD_EVEN;
260                         progressive = true;
261                 } else {
262                         vnmc = VNMC_IM_ODD;
263                 }
264                 break;
265         default:
266                 vnmc = VNMC_IM_ODD;
267                 break;
268         }
269 
270         /* input interface */
271         switch (icd->current_fmt->code) {
272         case V4L2_MBUS_FMT_YUYV8_1X16:
273                 /* BT.601/BT.1358 16bit YCbCr422 */
274                 vnmc |= VNMC_INF_YUV16;
275                 break;
276         case V4L2_MBUS_FMT_YUYV8_2X8:
277                 /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
278                 vnmc |= priv->pdata->flags & RCAR_VIN_BT656 ?
279                         VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
280                 break;
281         case V4L2_MBUS_FMT_YUYV10_2X10:
282                 /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
283                 vnmc |= priv->pdata->flags & RCAR_VIN_BT656 ?
284                         VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
285                 break;
286         default:
287                 break;
288         }
289 
290         /* output format */
291         switch (icd->current_fmt->host_fmt->fourcc) {
292         case V4L2_PIX_FMT_NV16:
293                 iowrite32(ALIGN(cam->width * cam->height, 0x80),
294                           priv->base + VNUVAOF_REG);
295                 dmr = VNDMR_DTMD_YCSEP;
296                 output_is_yuv = true;
297                 break;
298         case V4L2_PIX_FMT_YUYV:
299                 dmr = VNDMR_BPSM;
300                 output_is_yuv = true;
301                 break;
302         case V4L2_PIX_FMT_UYVY:
303                 dmr = 0;
304                 output_is_yuv = true;
305                 break;
306         case V4L2_PIX_FMT_RGB555X:
307                 dmr = VNDMR_DTMD_ARGB1555;
308                 break;
309         case V4L2_PIX_FMT_RGB565:
310                 dmr = 0;
311                 break;
312         case V4L2_PIX_FMT_RGB32:
313                 if (priv->chip == RCAR_GEN2 || priv->chip == RCAR_H1 ||
314                     priv->chip == RCAR_E1) {
315                         dmr = VNDMR_EXRGB;
316                         break;
317                 }
318         default:
319                 dev_warn(icd->parent, "Invalid fourcc format (0x%x)\n",
320                          icd->current_fmt->host_fmt->fourcc);
321                 return -EINVAL;
322         }
323 
324         /* Always update on field change */
325         vnmc |= VNMC_VUP;
326 
327         /* If input and output use the same colorspace, use bypass mode */
328         if (output_is_yuv)
329                 vnmc |= VNMC_BPS;
330 
331         /* progressive or interlaced mode */
332         interrupts = progressive ? VNIE_FIE | VNIE_EFE : VNIE_EFE;
333 
334         /* ack interrupts */
335         iowrite32(interrupts, priv->base + VNINTS_REG);
336         /* enable interrupts */
337         iowrite32(interrupts, priv->base + VNIE_REG);
338         /* start capturing */
339         iowrite32(dmr, priv->base + VNDMR_REG);
340         iowrite32(vnmc | VNMC_ME, priv->base + VNMC_REG);
341 
342         return 0;
343 }
344 
345 static void rcar_vin_capture(struct rcar_vin_priv *priv)
346 {
347         if (is_continuous_transfer(priv))
348                 /* Continuous Frame Capture Mode */
349                 iowrite32(VNFC_C_FRAME, priv->base + VNFC_REG);
350         else
351                 /* Single Frame Capture Mode */
352                 iowrite32(VNFC_S_FRAME, priv->base + VNFC_REG);
353 }
354 
355 static void rcar_vin_request_capture_stop(struct rcar_vin_priv *priv)
356 {
357         priv->state = STOPPING;
358 
359         /* set continuous & single transfer off */
360         iowrite32(0, priv->base + VNFC_REG);
361         /* disable capture (release DMA buffer), reset */
362         iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
363                   priv->base + VNMC_REG);
364 
365         /* update the status if stopped already */
366         if (!(ioread32(priv->base + VNMS_REG) & VNMS_CA))
367                 priv->state = STOPPED;
368 }
369 
370 static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv *priv)
371 {
372         int slot;
373 
374         for (slot = 0; slot < priv->nr_hw_slots; slot++)
375                 if (priv->queue_buf[slot] == NULL)
376                         return slot;
377 
378         return -1;
379 }
380 
381 static int rcar_vin_hw_ready(struct rcar_vin_priv *priv)
382 {
383         /* Ensure all HW slots are filled */
384         return rcar_vin_get_free_hw_slot(priv) < 0 ? 1 : 0;
385 }
386 
387 /* Moves a buffer from the queue to the HW slots */
388 static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
389 {
390         struct vb2_buffer *vb;
391         dma_addr_t phys_addr_top;
392         int slot;
393 
394         if (list_empty(&priv->capture))
395                 return 0;
396 
397         /* Find a free HW slot */
398         slot = rcar_vin_get_free_hw_slot(priv);
399         if (slot < 0)
400                 return 0;
401 
402         vb = &list_entry(priv->capture.next, struct rcar_vin_buffer, list)->vb;
403         list_del_init(to_buf_list(vb));
404         priv->queue_buf[slot] = vb;
405         phys_addr_top = vb2_dma_contig_plane_dma_addr(vb, 0);
406         iowrite32(phys_addr_top, priv->base + VNMB_REG(slot));
407 
408         return 1;
409 }
410 
411 static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
412 {
413         struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
414         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
415         struct rcar_vin_priv *priv = ici->priv;
416         unsigned long size;
417 
418         size = icd->sizeimage;
419 
420         if (vb2_plane_size(vb, 0) < size) {
421                 dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
422                         vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
423                 goto error;
424         }
425 
426         vb2_set_plane_payload(vb, 0, size);
427 
428         dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
429                 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
430 
431         spin_lock_irq(&priv->lock);
432 
433         list_add_tail(to_buf_list(vb), &priv->capture);
434         rcar_vin_fill_hw_slot(priv);
435 
436         /* If we weren't running, and have enough buffers, start capturing! */
437         if (priv->state != RUNNING && rcar_vin_hw_ready(priv)) {
438                 if (rcar_vin_setup(priv)) {
439                         /* Submit error */
440                         list_del_init(to_buf_list(vb));
441                         spin_unlock_irq(&priv->lock);
442                         goto error;
443                 }
444                 priv->request_to_stop = false;
445                 init_completion(&priv->capture_stop);
446                 priv->state = RUNNING;
447                 rcar_vin_capture(priv);
448         }
449 
450         spin_unlock_irq(&priv->lock);
451 
452         return;
453 
454 error:
455         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
456 }
457 
458 static void rcar_vin_videobuf_release(struct vb2_buffer *vb)
459 {
460         struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
461         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
462         struct rcar_vin_priv *priv = ici->priv;
463         unsigned int i;
464         int buf_in_use = 0;
465 
466         spin_lock_irq(&priv->lock);
467 
468         /* Is the buffer in use by the VIN hardware? */
469         for (i = 0; i < MAX_BUFFER_NUM; i++) {
470                 if (priv->queue_buf[i] == vb) {
471                         buf_in_use = 1;
472                         break;
473                 }
474         }
475 
476         if (buf_in_use) {
477                 while (priv->state != STOPPED) {
478 
479                         /* issue stop if running */
480                         if (priv->state == RUNNING)
481                                 rcar_vin_request_capture_stop(priv);
482 
483                         /* wait until capturing has been stopped */
484                         if (priv->state == STOPPING) {
485                                 priv->request_to_stop = true;
486                                 spin_unlock_irq(&priv->lock);
487                                 wait_for_completion(&priv->capture_stop);
488                                 spin_lock_irq(&priv->lock);
489                         }
490                 }
491                 /*
492                  * Capturing has now stopped. The buffer we have been asked
493                  * to release could be any of the current buffers in use, so
494                  * release all buffers that are in use by HW
495                  */
496                 for (i = 0; i < MAX_BUFFER_NUM; i++) {
497                         if (priv->queue_buf[i]) {
498                                 vb2_buffer_done(priv->queue_buf[i],
499                                         VB2_BUF_STATE_ERROR);
500                                 priv->queue_buf[i] = NULL;
501                         }
502                 }
503         } else {
504                 list_del_init(to_buf_list(vb));
505         }
506 
507         spin_unlock_irq(&priv->lock);
508 }
509 
510 static int rcar_vin_videobuf_init(struct vb2_buffer *vb)
511 {
512         INIT_LIST_HEAD(to_buf_list(vb));
513         return 0;
514 }
515 
516 static void rcar_vin_stop_streaming(struct vb2_queue *vq)
517 {
518         struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
519         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
520         struct rcar_vin_priv *priv = ici->priv;
521         struct list_head *buf_head, *tmp;
522 
523         spin_lock_irq(&priv->lock);
524         list_for_each_safe(buf_head, tmp, &priv->capture)
525                 list_del_init(buf_head);
526         spin_unlock_irq(&priv->lock);
527 }
528 
529 static struct vb2_ops rcar_vin_vb2_ops = {
530         .queue_setup    = rcar_vin_videobuf_setup,
531         .buf_init       = rcar_vin_videobuf_init,
532         .buf_cleanup    = rcar_vin_videobuf_release,
533         .buf_queue      = rcar_vin_videobuf_queue,
534         .stop_streaming = rcar_vin_stop_streaming,
535         .wait_prepare   = soc_camera_unlock,
536         .wait_finish    = soc_camera_lock,
537 };
538 
539 static irqreturn_t rcar_vin_irq(int irq, void *data)
540 {
541         struct rcar_vin_priv *priv = data;
542         u32 int_status;
543         bool can_run = false, hw_stopped;
544         int slot;
545         unsigned int handled = 0;
546 
547         spin_lock(&priv->lock);
548 
549         int_status = ioread32(priv->base + VNINTS_REG);
550         if (!int_status)
551                 goto done;
552         /* ack interrupts */
553         iowrite32(int_status, priv->base + VNINTS_REG);
554         handled = 1;
555 
556         /* nothing to do if capture status is 'STOPPED' */
557         if (priv->state == STOPPED)
558                 goto done;
559 
560         hw_stopped = !(ioread32(priv->base + VNMS_REG) & VNMS_CA);
561 
562         if (!priv->request_to_stop) {
563                 if (is_continuous_transfer(priv))
564                         slot = (ioread32(priv->base + VNMS_REG) &
565                                 VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
566                 else
567                         slot = 0;
568 
569                 priv->queue_buf[slot]->v4l2_buf.field = priv->field;
570                 priv->queue_buf[slot]->v4l2_buf.sequence = priv->sequence++;
571                 do_gettimeofday(&priv->queue_buf[slot]->v4l2_buf.timestamp);
572                 vb2_buffer_done(priv->queue_buf[slot], VB2_BUF_STATE_DONE);
573                 priv->queue_buf[slot] = NULL;
574 
575                 if (priv->state != STOPPING)
576                         can_run = rcar_vin_fill_hw_slot(priv);
577 
578                 if (hw_stopped || !can_run) {
579                         priv->state = STOPPED;
580                 } else if (is_continuous_transfer(priv) &&
581                            list_empty(&priv->capture) &&
582                            priv->state == RUNNING) {
583                         /*
584                          * The continuous capturing requires an explicit stop
585                          * operation when there is no buffer to be set into
586                          * the VnMBm registers.
587                          */
588                         rcar_vin_request_capture_stop(priv);
589                 } else {
590                         rcar_vin_capture(priv);
591                 }
592 
593         } else if (hw_stopped) {
594                 priv->state = STOPPED;
595                 priv->request_to_stop = false;
596                 complete(&priv->capture_stop);
597         }
598 
599 done:
600         spin_unlock(&priv->lock);
601 
602         return IRQ_RETVAL(handled);
603 }
604 
605 static int rcar_vin_add_device(struct soc_camera_device *icd)
606 {
607         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
608         struct rcar_vin_priv *priv = ici->priv;
609         int i;
610 
611         for (i = 0; i < MAX_BUFFER_NUM; i++)
612                 priv->queue_buf[i] = NULL;
613 
614         pm_runtime_get_sync(ici->v4l2_dev.dev);
615 
616         dev_dbg(icd->parent, "R-Car VIN driver attached to camera %d\n",
617                 icd->devnum);
618 
619         return 0;
620 }
621 
622 static void rcar_vin_remove_device(struct soc_camera_device *icd)
623 {
624         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
625         struct rcar_vin_priv *priv = ici->priv;
626         struct vb2_buffer *vb;
627         int i;
628 
629         /* disable capture, disable interrupts */
630         iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
631                   priv->base + VNMC_REG);
632         iowrite32(0, priv->base + VNIE_REG);
633 
634         priv->state = STOPPED;
635         priv->request_to_stop = false;
636 
637         /* make sure active buffer is cancelled */
638         spin_lock_irq(&priv->lock);
639         for (i = 0; i < MAX_BUFFER_NUM; i++) {
640                 vb = priv->queue_buf[i];
641                 if (vb) {
642                         list_del_init(to_buf_list(vb));
643                         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
644                 }
645         }
646         spin_unlock_irq(&priv->lock);
647 
648         pm_runtime_put(ici->v4l2_dev.dev);
649 
650         dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
651                 icd->devnum);
652 }
653 
654 /* Called with .host_lock held */
655 static int rcar_vin_clock_start(struct soc_camera_host *ici)
656 {
657         /* VIN does not have "mclk" */
658         return 0;
659 }
660 
661 /* Called with .host_lock held */
662 static void rcar_vin_clock_stop(struct soc_camera_host *ici)
663 {
664         /* VIN does not have "mclk" */
665 }
666 
667 /* rect is guaranteed to not exceed the scaled camera rectangle */
668 static int rcar_vin_set_rect(struct soc_camera_device *icd)
669 {
670         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
671         struct rcar_vin_cam *cam = icd->host_priv;
672         struct rcar_vin_priv *priv = ici->priv;
673         unsigned int left_offset, top_offset;
674         unsigned char dsize = 0;
675         struct v4l2_rect *cam_subrect = &cam->subrect;
676 
677         dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
678                 icd->user_width, icd->user_height, cam->vin_left, cam->vin_top);
679 
680         left_offset = cam->vin_left;
681         top_offset = cam->vin_top;
682 
683         if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB32 &&
684             priv->chip == RCAR_E1)
685                 dsize = 1;
686 
687         dev_dbg(icd->parent, "Cam %ux%u@%u:%u\n",
688                 cam->width, cam->height, cam->vin_left, cam->vin_top);
689         dev_dbg(icd->parent, "Cam subrect %ux%u@%u:%u\n",
690                 cam_subrect->width, cam_subrect->height,
691                 cam_subrect->left, cam_subrect->top);
692 
693         /* Set Start/End Pixel/Line Pre-Clip */
694         iowrite32(left_offset << dsize, priv->base + VNSPPRC_REG);
695         iowrite32((left_offset + cam->width - 1) << dsize,
696                   priv->base + VNEPPRC_REG);
697         switch (priv->field) {
698         case V4L2_FIELD_INTERLACED:
699         case V4L2_FIELD_INTERLACED_TB:
700         case V4L2_FIELD_INTERLACED_BT:
701                 iowrite32(top_offset / 2, priv->base + VNSLPRC_REG);
702                 iowrite32((top_offset + cam->height) / 2 - 1,
703                           priv->base + VNELPRC_REG);
704                 break;
705         default:
706                 iowrite32(top_offset, priv->base + VNSLPRC_REG);
707                 iowrite32(top_offset + cam->height - 1,
708                           priv->base + VNELPRC_REG);
709                 break;
710         }
711 
712         /* Set Start/End Pixel/Line Post-Clip */
713         iowrite32(0, priv->base + VNSPPOC_REG);
714         iowrite32(0, priv->base + VNSLPOC_REG);
715         iowrite32((cam_subrect->width - 1) << dsize, priv->base + VNEPPOC_REG);
716         switch (priv->field) {
717         case V4L2_FIELD_INTERLACED:
718         case V4L2_FIELD_INTERLACED_TB:
719         case V4L2_FIELD_INTERLACED_BT:
720                 iowrite32(cam_subrect->height / 2 - 1,
721                           priv->base + VNELPOC_REG);
722                 break;
723         default:
724                 iowrite32(cam_subrect->height - 1, priv->base + VNELPOC_REG);
725                 break;
726         }
727 
728         iowrite32(ALIGN(cam->width, 0x10), priv->base + VNIS_REG);
729 
730         return 0;
731 }
732 
733 static void capture_stop_preserve(struct rcar_vin_priv *priv, u32 *vnmc)
734 {
735         *vnmc = ioread32(priv->base + VNMC_REG);
736         /* module disable */
737         iowrite32(*vnmc & ~VNMC_ME, priv->base + VNMC_REG);
738 }
739 
740 static void capture_restore(struct rcar_vin_priv *priv, u32 vnmc)
741 {
742         unsigned long timeout = jiffies + 10 * HZ;
743 
744         /*
745          * Wait until the end of the current frame. It can take a long time,
746          * but if it has been aborted by a MRST1 reset, it should exit sooner.
747          */
748         while ((ioread32(priv->base + VNMS_REG) & VNMS_AV) &&
749                 time_before(jiffies, timeout))
750                 msleep(1);
751 
752         if (time_after(jiffies, timeout)) {
753                 dev_err(priv->ici.v4l2_dev.dev,
754                         "Timeout waiting for frame end! Interface problem?\n");
755                 return;
756         }
757 
758         iowrite32(vnmc, priv->base + VNMC_REG);
759 }
760 
761 #define VIN_MBUS_FLAGS  (V4L2_MBUS_MASTER |             \
762                          V4L2_MBUS_PCLK_SAMPLE_RISING | \
763                          V4L2_MBUS_HSYNC_ACTIVE_HIGH |  \
764                          V4L2_MBUS_HSYNC_ACTIVE_LOW |   \
765                          V4L2_MBUS_VSYNC_ACTIVE_HIGH |  \
766                          V4L2_MBUS_VSYNC_ACTIVE_LOW |   \
767                          V4L2_MBUS_DATA_ACTIVE_HIGH)
768 
769 static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
770 {
771         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
772         struct rcar_vin_priv *priv = ici->priv;
773         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
774         struct v4l2_mbus_config cfg;
775         unsigned long common_flags;
776         u32 vnmc;
777         u32 val;
778         int ret;
779 
780         capture_stop_preserve(priv, &vnmc);
781 
782         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
783         if (!ret) {
784                 common_flags = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
785                 if (!common_flags) {
786                         dev_warn(icd->parent,
787                                  "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
788                                  cfg.flags, VIN_MBUS_FLAGS);
789                         return -EINVAL;
790                 }
791         } else if (ret != -ENOIOCTLCMD) {
792                 return ret;
793         } else {
794                 common_flags = VIN_MBUS_FLAGS;
795         }
796 
797         /* Make choises, based on platform preferences */
798         if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
799             (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
800                 if (priv->pdata->flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
801                         common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
802                 else
803                         common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
804         }
805 
806         if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
807             (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
808                 if (priv->pdata->flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
809                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
810                 else
811                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
812         }
813 
814         cfg.flags = common_flags;
815         ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
816         if (ret < 0 && ret != -ENOIOCTLCMD)
817                 return ret;
818 
819         val = priv->field == V4L2_FIELD_NONE ? VNDMR2_FTEV : 0;
820         if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
821                 val |= VNDMR2_VPS;
822         if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
823                 val |= VNDMR2_HPS;
824         iowrite32(val, priv->base + VNDMR2_REG);
825 
826         ret = rcar_vin_set_rect(icd);
827         if (ret < 0)
828                 return ret;
829 
830         capture_restore(priv, vnmc);
831 
832         return 0;
833 }
834 
835 static int rcar_vin_try_bus_param(struct soc_camera_device *icd,
836                                   unsigned char buswidth)
837 {
838         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
839         struct v4l2_mbus_config cfg;
840         int ret;
841 
842         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
843         if (ret == -ENOIOCTLCMD)
844                 return 0;
845         else if (ret)
846                 return ret;
847 
848         if (buswidth > 24)
849                 return -EINVAL;
850 
851         /* check is there common mbus flags */
852         ret = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
853         if (ret)
854                 return 0;
855 
856         dev_warn(icd->parent,
857                 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
858                  cfg.flags, VIN_MBUS_FLAGS);
859 
860         return -EINVAL;
861 }
862 
863 static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
864 {
865         return  fmt->packing == SOC_MBUS_PACKING_NONE ||
866                 (fmt->bits_per_sample > 8 &&
867                  fmt->packing == SOC_MBUS_PACKING_EXTEND16);
868 }
869 
870 static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
871         {
872                 .fourcc                 = V4L2_PIX_FMT_NV16,
873                 .name                   = "NV16",
874                 .bits_per_sample        = 8,
875                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
876                 .order                  = SOC_MBUS_ORDER_LE,
877                 .layout                 = SOC_MBUS_LAYOUT_PLANAR_Y_C,
878         },
879         {
880                 .fourcc                 = V4L2_PIX_FMT_UYVY,
881                 .name                   = "UYVY",
882                 .bits_per_sample        = 16,
883                 .packing                = SOC_MBUS_PACKING_NONE,
884                 .order                  = SOC_MBUS_ORDER_LE,
885                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
886         },
887         {
888                 .fourcc                 = V4L2_PIX_FMT_RGB565,
889                 .name                   = "RGB565",
890                 .bits_per_sample        = 16,
891                 .packing                = SOC_MBUS_PACKING_NONE,
892                 .order                  = SOC_MBUS_ORDER_LE,
893                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
894         },
895         {
896                 .fourcc                 = V4L2_PIX_FMT_RGB555X,
897                 .name                   = "ARGB1555",
898                 .bits_per_sample        = 16,
899                 .packing                = SOC_MBUS_PACKING_NONE,
900                 .order                  = SOC_MBUS_ORDER_LE,
901                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
902         },
903         {
904                 .fourcc                 = V4L2_PIX_FMT_RGB32,
905                 .name                   = "RGB888",
906                 .bits_per_sample        = 32,
907                 .packing                = SOC_MBUS_PACKING_NONE,
908                 .order                  = SOC_MBUS_ORDER_LE,
909                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
910         },
911 };
912 
913 static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
914                                 struct soc_camera_format_xlate *xlate)
915 {
916         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
917         struct device *dev = icd->parent;
918         int ret, k, n;
919         int formats = 0;
920         struct rcar_vin_cam *cam;
921         enum v4l2_mbus_pixelcode code;
922         const struct soc_mbus_pixelfmt *fmt;
923 
924         ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
925         if (ret < 0)
926                 return 0;
927 
928         fmt = soc_mbus_get_fmtdesc(code);
929         if (!fmt) {
930                 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
931                 return 0;
932         }
933 
934         ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
935         if (ret < 0)
936                 return 0;
937 
938         if (!icd->host_priv) {
939                 struct v4l2_mbus_framefmt mf;
940                 struct v4l2_rect rect;
941                 struct device *dev = icd->parent;
942                 int shift;
943 
944                 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
945                 if (ret < 0)
946                         return ret;
947 
948                 /* Cache current client geometry */
949                 ret = soc_camera_client_g_rect(sd, &rect);
950                 if (ret == -ENOIOCTLCMD) {
951                         /* Sensor driver doesn't support cropping */
952                         rect.left = 0;
953                         rect.top = 0;
954                         rect.width = mf.width;
955                         rect.height = mf.height;
956                 } else if (ret < 0) {
957                         return ret;
958                 }
959 
960                 /*
961                  * If sensor proposes too large format then try smaller ones:
962                  * 1280x960, 640x480, 320x240
963                  */
964                 for (shift = 0; shift < 3; shift++) {
965                         if (mf.width <= VIN_MAX_WIDTH &&
966                             mf.height <= VIN_MAX_HEIGHT)
967                                 break;
968 
969                         mf.width = 1280 >> shift;
970                         mf.height = 960 >> shift;
971                         ret = v4l2_device_call_until_err(sd->v4l2_dev,
972                                                          soc_camera_grp_id(icd),
973                                                          video, s_mbus_fmt,
974                                                          &mf);
975                         if (ret < 0)
976                                 return ret;
977                 }
978 
979                 if (shift == 3) {
980                         dev_err(dev,
981                                 "Failed to configure the client below %ux%x\n",
982                                 mf.width, mf.height);
983                         return -EIO;
984                 }
985 
986                 dev_dbg(dev, "camera fmt %ux%u\n", mf.width, mf.height);
987 
988                 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
989                 if (!cam)
990                         return -ENOMEM;
991                 /*
992                  * We are called with current camera crop,
993                  * initialise subrect with it
994                  */
995                 cam->rect = rect;
996                 cam->subrect = rect;
997                 cam->width = mf.width;
998                 cam->height = mf.height;
999 
1000                 icd->host_priv = cam;
1001         } else {
1002                 cam = icd->host_priv;
1003         }
1004 
1005         /* Beginning of a pass */
1006         if (!idx)
1007                 cam->extra_fmt = NULL;
1008 
1009         switch (code) {
1010         case V4L2_MBUS_FMT_YUYV8_1X16:
1011         case V4L2_MBUS_FMT_YUYV8_2X8:
1012         case V4L2_MBUS_FMT_YUYV10_2X10:
1013                 if (cam->extra_fmt)
1014                         break;
1015 
1016                 /* Add all our formats that can be generated by VIN */
1017                 cam->extra_fmt = rcar_vin_formats;
1018 
1019                 n = ARRAY_SIZE(rcar_vin_formats);
1020                 formats += n;
1021                 for (k = 0; xlate && k < n; k++, xlate++) {
1022                         xlate->host_fmt = &rcar_vin_formats[k];
1023                         xlate->code = code;
1024                         dev_dbg(dev, "Providing format %s using code %d\n",
1025                                 rcar_vin_formats[k].name, code);
1026                 }
1027                 break;
1028         default:
1029                 if (!rcar_vin_packing_supported(fmt))
1030                         return 0;
1031 
1032                 dev_dbg(dev, "Providing format %s in pass-through mode\n",
1033                         fmt->name);
1034                 break;
1035         }
1036 
1037         /* Generic pass-through */
1038         formats++;
1039         if (xlate) {
1040                 xlate->host_fmt = fmt;
1041                 xlate->code = code;
1042                 xlate++;
1043         }
1044 
1045         return formats;
1046 }
1047 
1048 static void rcar_vin_put_formats(struct soc_camera_device *icd)
1049 {
1050         kfree(icd->host_priv);
1051         icd->host_priv = NULL;
1052 }
1053 
1054 static int rcar_vin_set_crop(struct soc_camera_device *icd,
1055                              const struct v4l2_crop *a)
1056 {
1057         struct v4l2_crop a_writable = *a;
1058         const struct v4l2_rect *rect = &a_writable.c;
1059         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1060         struct rcar_vin_priv *priv = ici->priv;
1061         struct v4l2_crop cam_crop;
1062         struct rcar_vin_cam *cam = icd->host_priv;
1063         struct v4l2_rect *cam_rect = &cam_crop.c;
1064         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1065         struct device *dev = icd->parent;
1066         struct v4l2_mbus_framefmt mf;
1067         u32 vnmc;
1068         int ret, i;
1069 
1070         dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1071                 rect->left, rect->top);
1072 
1073         /* During camera cropping its output window can change too, stop VIN */
1074         capture_stop_preserve(priv, &vnmc);
1075         dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
1076 
1077         /* Apply iterative camera S_CROP for new input window. */
1078         ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
1079                                        &cam->rect, &cam->subrect);
1080         if (ret < 0)
1081                 return ret;
1082 
1083         dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
1084                 cam_rect->width, cam_rect->height,
1085                 cam_rect->left, cam_rect->top);
1086 
1087         /* On success cam_crop contains current camera crop */
1088 
1089         /* Retrieve camera output window */
1090         ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1091         if (ret < 0)
1092                 return ret;
1093 
1094         if (mf.width > VIN_MAX_WIDTH || mf.height > VIN_MAX_HEIGHT)
1095                 return -EINVAL;
1096 
1097         /* Cache camera output window */
1098         cam->width = mf.width;
1099         cam->height = mf.height;
1100 
1101         icd->user_width  = cam->width;
1102         icd->user_height = cam->height;
1103 
1104         cam->vin_left = rect->left & ~1;
1105         cam->vin_top = rect->top & ~1;
1106 
1107         /* Use VIN cropping to crop to the new window. */
1108         ret = rcar_vin_set_rect(icd);
1109         if (ret < 0)
1110                 return ret;
1111 
1112         cam->subrect = *rect;
1113 
1114         dev_dbg(dev, "VIN cropped to %ux%u@%u:%u\n",
1115                 icd->user_width, icd->user_height,
1116                 cam->vin_left, cam->vin_top);
1117 
1118         /* Restore capture */
1119         for (i = 0; i < MAX_BUFFER_NUM; i++) {
1120                 if (priv->queue_buf[i] && priv->state == STOPPED) {
1121                         vnmc |= VNMC_ME;
1122                         break;
1123                 }
1124         }
1125         capture_restore(priv, vnmc);
1126 
1127         /* Even if only camera cropping succeeded */
1128         return ret;
1129 }
1130 
1131 static int rcar_vin_get_crop(struct soc_camera_device *icd,
1132                              struct v4l2_crop *a)
1133 {
1134         struct rcar_vin_cam *cam = icd->host_priv;
1135 
1136         a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1137         a->c = cam->subrect;
1138 
1139         return 0;
1140 }
1141 
1142 /* Similar to set_crop multistage iterative algorithm */
1143 static int rcar_vin_set_fmt(struct soc_camera_device *icd,
1144                             struct v4l2_format *f)
1145 {
1146         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1147         struct rcar_vin_priv *priv = ici->priv;
1148         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1149         struct rcar_vin_cam *cam = icd->host_priv;
1150         struct v4l2_pix_format *pix = &f->fmt.pix;
1151         struct v4l2_mbus_framefmt mf;
1152         struct device *dev = icd->parent;
1153         __u32 pixfmt = pix->pixelformat;
1154         const struct soc_camera_format_xlate *xlate;
1155         unsigned int vin_sub_width = 0, vin_sub_height = 0;
1156         int ret;
1157         bool can_scale;
1158         enum v4l2_field field;
1159         v4l2_std_id std;
1160 
1161         dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
1162                 pixfmt, pix->width, pix->height);
1163 
1164         switch (pix->field) {
1165         default:
1166                 pix->field = V4L2_FIELD_NONE;
1167                 /* fall-through */
1168         case V4L2_FIELD_NONE:
1169         case V4L2_FIELD_TOP:
1170         case V4L2_FIELD_BOTTOM:
1171         case V4L2_FIELD_INTERLACED_TB:
1172         case V4L2_FIELD_INTERLACED_BT:
1173                 field = pix->field;
1174                 break;
1175         case V4L2_FIELD_INTERLACED:
1176                 /* Query for standard if not explicitly mentioned _TB/_BT */
1177                 ret = v4l2_subdev_call(sd, video, querystd, &std);
1178                 if (ret < 0)
1179                         std = V4L2_STD_625_50;
1180 
1181                 field = std & V4L2_STD_625_50 ? V4L2_FIELD_INTERLACED_TB :
1182                                                 V4L2_FIELD_INTERLACED_BT;
1183                 break;
1184         }
1185 
1186         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1187         if (!xlate) {
1188                 dev_warn(dev, "Format %x not found\n", pixfmt);
1189                 return -EINVAL;
1190         }
1191         /* Calculate client output geometry */
1192         soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
1193                                       12);
1194         mf.field = pix->field;
1195         mf.colorspace = pix->colorspace;
1196         mf.code  = xlate->code;
1197 
1198         switch (pixfmt) {
1199         case V4L2_PIX_FMT_RGB32:
1200                 can_scale = priv->chip != RCAR_E1;
1201                 break;
1202         case V4L2_PIX_FMT_UYVY:
1203         case V4L2_PIX_FMT_YUYV:
1204         case V4L2_PIX_FMT_RGB565:
1205         case V4L2_PIX_FMT_RGB555X:
1206                 can_scale = true;
1207                 break;
1208         default:
1209                 can_scale = false;
1210                 break;
1211         }
1212 
1213         dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
1214 
1215         ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
1216                                       &mf, &vin_sub_width, &vin_sub_height,
1217                                       can_scale, 12);
1218 
1219         /* Done with the camera. Now see if we can improve the result */
1220         dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1221                 ret, mf.width, mf.height, pix->width, pix->height);
1222 
1223         if (ret == -ENOIOCTLCMD)
1224                 dev_dbg(dev, "Sensor doesn't support scaling\n");
1225         else if (ret < 0)
1226                 return ret;
1227 
1228         if (mf.code != xlate->code)
1229                 return -EINVAL;
1230 
1231         /* Prepare VIN crop */
1232         cam->width = mf.width;
1233         cam->height = mf.height;
1234 
1235         /* Use VIN scaling to scale to the requested user window. */
1236 
1237         /* We cannot scale up */
1238         if (pix->width > vin_sub_width)
1239                 vin_sub_width = pix->width;
1240 
1241         if (pix->height > vin_sub_height)
1242                 vin_sub_height = pix->height;
1243 
1244         pix->colorspace = mf.colorspace;
1245 
1246         if (!can_scale) {
1247                 pix->width = vin_sub_width;
1248                 pix->height = vin_sub_height;
1249         }
1250 
1251         /*
1252          * We have calculated CFLCR, the actual configuration will be performed
1253          * in rcar_vin_set_bus_param()
1254          */
1255 
1256         dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
1257                 vin_sub_width, pix->width, vin_sub_height, pix->height);
1258 
1259         icd->current_fmt = xlate;
1260 
1261         priv->field = field;
1262 
1263         return 0;
1264 }
1265 
1266 static int rcar_vin_try_fmt(struct soc_camera_device *icd,
1267                             struct v4l2_format *f)
1268 {
1269         const struct soc_camera_format_xlate *xlate;
1270         struct v4l2_pix_format *pix = &f->fmt.pix;
1271         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1272         struct v4l2_mbus_framefmt mf;
1273         __u32 pixfmt = pix->pixelformat;
1274         int width, height;
1275         int ret;
1276 
1277         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1278         if (!xlate) {
1279                 xlate = icd->current_fmt;
1280                 dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
1281                         pixfmt, xlate->host_fmt->fourcc);
1282                 pixfmt = xlate->host_fmt->fourcc;
1283                 pix->pixelformat = pixfmt;
1284                 pix->colorspace = icd->colorspace;
1285         }
1286 
1287         /* FIXME: calculate using depth and bus width */
1288         v4l_bound_align_image(&pix->width, 2, VIN_MAX_WIDTH, 1,
1289                               &pix->height, 4, VIN_MAX_HEIGHT, 2, 0);
1290 
1291         width = pix->width;
1292         height = pix->height;
1293 
1294         /* let soc-camera calculate these values */
1295         pix->bytesperline = 0;
1296         pix->sizeimage = 0;
1297 
1298         /* limit to sensor capabilities */
1299         mf.width = pix->width;
1300         mf.height = pix->height;
1301         mf.field = pix->field;
1302         mf.code = xlate->code;
1303         mf.colorspace = pix->colorspace;
1304 
1305         ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
1306                                          video, try_mbus_fmt, &mf);
1307         if (ret < 0)
1308                 return ret;
1309 
1310         pix->width = mf.width;
1311         pix->height = mf.height;
1312         pix->field = mf.field;
1313         pix->colorspace = mf.colorspace;
1314 
1315         if (pixfmt == V4L2_PIX_FMT_NV16) {
1316                 /* FIXME: check against rect_max after converting soc-camera */
1317                 /* We can scale precisely, need a bigger image from camera */
1318                 if (pix->width < width || pix->height < height) {
1319                         /*
1320                          * We presume, the sensor behaves sanely, i.e. if
1321                          * requested a bigger rectangle, it will not return a
1322                          * smaller one.
1323                          */
1324                         mf.width = VIN_MAX_WIDTH;
1325                         mf.height = VIN_MAX_HEIGHT;
1326                         ret = v4l2_device_call_until_err(sd->v4l2_dev,
1327                                                          soc_camera_grp_id(icd),
1328                                                          video, try_mbus_fmt,
1329                                                          &mf);
1330                         if (ret < 0) {
1331                                 dev_err(icd->parent,
1332                                         "client try_fmt() = %d\n", ret);
1333                                 return ret;
1334                         }
1335                 }
1336                 /* We will scale exactly */
1337                 if (mf.width > width)
1338                         pix->width = width;
1339                 if (mf.height > height)
1340                         pix->height = height;
1341         }
1342 
1343         return ret;
1344 }
1345 
1346 static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
1347 {
1348         struct soc_camera_device *icd = file->private_data;
1349 
1350         return vb2_poll(&icd->vb2_vidq, file, pt);
1351 }
1352 
1353 static int rcar_vin_querycap(struct soc_camera_host *ici,
1354                              struct v4l2_capability *cap)
1355 {
1356         strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
1357         cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1358         return 0;
1359 }
1360 
1361 static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
1362                                    struct soc_camera_device *icd)
1363 {
1364         vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1365         vq->io_modes = VB2_MMAP | VB2_USERPTR;
1366         vq->drv_priv = icd;
1367         vq->ops = &rcar_vin_vb2_ops;
1368         vq->mem_ops = &vb2_dma_contig_memops;
1369         vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
1370         vq->timestamp_flags  = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1371 
1372         return vb2_queue_init(vq);
1373 }
1374 
1375 static struct soc_camera_host_ops rcar_vin_host_ops = {
1376         .owner          = THIS_MODULE,
1377         .add            = rcar_vin_add_device,
1378         .remove         = rcar_vin_remove_device,
1379         .clock_start    = rcar_vin_clock_start,
1380         .clock_stop     = rcar_vin_clock_stop,
1381         .get_formats    = rcar_vin_get_formats,
1382         .put_formats    = rcar_vin_put_formats,
1383         .get_crop       = rcar_vin_get_crop,
1384         .set_crop       = rcar_vin_set_crop,
1385         .try_fmt        = rcar_vin_try_fmt,
1386         .set_fmt        = rcar_vin_set_fmt,
1387         .poll           = rcar_vin_poll,
1388         .querycap       = rcar_vin_querycap,
1389         .set_bus_param  = rcar_vin_set_bus_param,
1390         .init_videobuf2 = rcar_vin_init_videobuf2,
1391 };
1392 
1393 static struct platform_device_id rcar_vin_id_table[] = {
1394         { "r8a7791-vin",  RCAR_GEN2 },
1395         { "r8a7790-vin",  RCAR_GEN2 },
1396         { "r8a7779-vin",  RCAR_H1 },
1397         { "r8a7778-vin",  RCAR_M1 },
1398         { "uPD35004-vin", RCAR_E1 },
1399         {},
1400 };
1401 MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1402 
1403 static int rcar_vin_probe(struct platform_device *pdev)
1404 {
1405         struct rcar_vin_priv *priv;
1406         struct resource *mem;
1407         struct rcar_vin_platform_data *pdata;
1408         int irq, ret;
1409 
1410         pdata = pdev->dev.platform_data;
1411         if (!pdata || !pdata->flags) {
1412                 dev_err(&pdev->dev, "platform data not set\n");
1413                 return -EINVAL;
1414         }
1415 
1416         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1417         if (mem == NULL)
1418                 return -EINVAL;
1419 
1420         irq = platform_get_irq(pdev, 0);
1421         if (irq <= 0)
1422                 return -EINVAL;
1423 
1424         priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
1425                             GFP_KERNEL);
1426         if (!priv)
1427                 return -ENOMEM;
1428 
1429         priv->base = devm_ioremap_resource(&pdev->dev, mem);
1430         if (IS_ERR(priv->base))
1431                 return PTR_ERR(priv->base);
1432 
1433         ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
1434                                dev_name(&pdev->dev), priv);
1435         if (ret)
1436                 return ret;
1437 
1438         priv->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1439         if (IS_ERR(priv->alloc_ctx))
1440                 return PTR_ERR(priv->alloc_ctx);
1441 
1442         priv->ici.priv = priv;
1443         priv->ici.v4l2_dev.dev = &pdev->dev;
1444         priv->ici.nr = pdev->id;
1445         priv->ici.drv_name = dev_name(&pdev->dev);
1446         priv->ici.ops = &rcar_vin_host_ops;
1447 
1448         priv->pdata = pdata;
1449         priv->chip = pdev->id_entry->driver_data;
1450         spin_lock_init(&priv->lock);
1451         INIT_LIST_HEAD(&priv->capture);
1452 
1453         priv->state = STOPPED;
1454 
1455         pm_suspend_ignore_children(&pdev->dev, true);
1456         pm_runtime_enable(&pdev->dev);
1457 
1458         ret = soc_camera_host_register(&priv->ici);
1459         if (ret)
1460                 goto cleanup;
1461 
1462         return 0;
1463 
1464 cleanup:
1465         pm_runtime_disable(&pdev->dev);
1466         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1467 
1468         return ret;
1469 }
1470 
1471 static int rcar_vin_remove(struct platform_device *pdev)
1472 {
1473         struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1474         struct rcar_vin_priv *priv = container_of(soc_host,
1475                                                   struct rcar_vin_priv, ici);
1476 
1477         soc_camera_host_unregister(soc_host);
1478         pm_runtime_disable(&pdev->dev);
1479         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1480 
1481         return 0;
1482 }
1483 
1484 static struct platform_driver rcar_vin_driver = {
1485         .probe          = rcar_vin_probe,
1486         .remove         = rcar_vin_remove,
1487         .driver         = {
1488                 .name           = DRV_NAME,
1489                 .owner          = THIS_MODULE,
1490         },
1491         .id_table       = rcar_vin_id_table,
1492 };
1493 
1494 module_platform_driver(rcar_vin_driver);
1495 
1496 MODULE_LICENSE("GPL");
1497 MODULE_ALIAS("platform:rcar_vin");
1498 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
1499 

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