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

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 int 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         return 0;
529 }
530 
531 static struct vb2_ops rcar_vin_vb2_ops = {
532         .queue_setup    = rcar_vin_videobuf_setup,
533         .buf_init       = rcar_vin_videobuf_init,
534         .buf_cleanup    = rcar_vin_videobuf_release,
535         .buf_queue      = rcar_vin_videobuf_queue,
536         .stop_streaming = rcar_vin_stop_streaming,
537         .wait_prepare   = soc_camera_unlock,
538         .wait_finish    = soc_camera_lock,
539 };
540 
541 static irqreturn_t rcar_vin_irq(int irq, void *data)
542 {
543         struct rcar_vin_priv *priv = data;
544         u32 int_status;
545         bool can_run = false, hw_stopped;
546         int slot;
547         unsigned int handled = 0;
548 
549         spin_lock(&priv->lock);
550 
551         int_status = ioread32(priv->base + VNINTS_REG);
552         if (!int_status)
553                 goto done;
554         /* ack interrupts */
555         iowrite32(int_status, priv->base + VNINTS_REG);
556         handled = 1;
557 
558         /* nothing to do if capture status is 'STOPPED' */
559         if (priv->state == STOPPED)
560                 goto done;
561 
562         hw_stopped = !(ioread32(priv->base + VNMS_REG) & VNMS_CA);
563 
564         if (!priv->request_to_stop) {
565                 if (is_continuous_transfer(priv))
566                         slot = (ioread32(priv->base + VNMS_REG) &
567                                 VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
568                 else
569                         slot = 0;
570 
571                 priv->queue_buf[slot]->v4l2_buf.field = priv->field;
572                 priv->queue_buf[slot]->v4l2_buf.sequence = priv->sequence++;
573                 do_gettimeofday(&priv->queue_buf[slot]->v4l2_buf.timestamp);
574                 vb2_buffer_done(priv->queue_buf[slot], VB2_BUF_STATE_DONE);
575                 priv->queue_buf[slot] = NULL;
576 
577                 if (priv->state != STOPPING)
578                         can_run = rcar_vin_fill_hw_slot(priv);
579 
580                 if (hw_stopped || !can_run) {
581                         priv->state = STOPPED;
582                 } else if (is_continuous_transfer(priv) &&
583                            list_empty(&priv->capture) &&
584                            priv->state == RUNNING) {
585                         /*
586                          * The continuous capturing requires an explicit stop
587                          * operation when there is no buffer to be set into
588                          * the VnMBm registers.
589                          */
590                         rcar_vin_request_capture_stop(priv);
591                 } else {
592                         rcar_vin_capture(priv);
593                 }
594 
595         } else if (hw_stopped) {
596                 priv->state = STOPPED;
597                 priv->request_to_stop = false;
598                 complete(&priv->capture_stop);
599         }
600 
601 done:
602         spin_unlock(&priv->lock);
603 
604         return IRQ_RETVAL(handled);
605 }
606 
607 static int rcar_vin_add_device(struct soc_camera_device *icd)
608 {
609         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
610         struct rcar_vin_priv *priv = ici->priv;
611         int i;
612 
613         for (i = 0; i < MAX_BUFFER_NUM; i++)
614                 priv->queue_buf[i] = NULL;
615 
616         pm_runtime_get_sync(ici->v4l2_dev.dev);
617 
618         dev_dbg(icd->parent, "R-Car VIN driver attached to camera %d\n",
619                 icd->devnum);
620 
621         return 0;
622 }
623 
624 static void rcar_vin_remove_device(struct soc_camera_device *icd)
625 {
626         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
627         struct rcar_vin_priv *priv = ici->priv;
628         struct vb2_buffer *vb;
629         int i;
630 
631         /* disable capture, disable interrupts */
632         iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
633                   priv->base + VNMC_REG);
634         iowrite32(0, priv->base + VNIE_REG);
635 
636         priv->state = STOPPED;
637         priv->request_to_stop = false;
638 
639         /* make sure active buffer is cancelled */
640         spin_lock_irq(&priv->lock);
641         for (i = 0; i < MAX_BUFFER_NUM; i++) {
642                 vb = priv->queue_buf[i];
643                 if (vb) {
644                         list_del_init(to_buf_list(vb));
645                         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
646                 }
647         }
648         spin_unlock_irq(&priv->lock);
649 
650         pm_runtime_put(ici->v4l2_dev.dev);
651 
652         dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
653                 icd->devnum);
654 }
655 
656 /* Called with .host_lock held */
657 static int rcar_vin_clock_start(struct soc_camera_host *ici)
658 {
659         /* VIN does not have "mclk" */
660         return 0;
661 }
662 
663 /* Called with .host_lock held */
664 static void rcar_vin_clock_stop(struct soc_camera_host *ici)
665 {
666         /* VIN does not have "mclk" */
667 }
668 
669 /* rect is guaranteed to not exceed the scaled camera rectangle */
670 static int rcar_vin_set_rect(struct soc_camera_device *icd)
671 {
672         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
673         struct rcar_vin_cam *cam = icd->host_priv;
674         struct rcar_vin_priv *priv = ici->priv;
675         unsigned int left_offset, top_offset;
676         unsigned char dsize = 0;
677         struct v4l2_rect *cam_subrect = &cam->subrect;
678 
679         dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
680                 icd->user_width, icd->user_height, cam->vin_left, cam->vin_top);
681 
682         left_offset = cam->vin_left;
683         top_offset = cam->vin_top;
684 
685         if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB32 &&
686             priv->chip == RCAR_E1)
687                 dsize = 1;
688 
689         dev_dbg(icd->parent, "Cam %ux%u@%u:%u\n",
690                 cam->width, cam->height, cam->vin_left, cam->vin_top);
691         dev_dbg(icd->parent, "Cam subrect %ux%u@%u:%u\n",
692                 cam_subrect->width, cam_subrect->height,
693                 cam_subrect->left, cam_subrect->top);
694 
695         /* Set Start/End Pixel/Line Pre-Clip */
696         iowrite32(left_offset << dsize, priv->base + VNSPPRC_REG);
697         iowrite32((left_offset + cam->width - 1) << dsize,
698                   priv->base + VNEPPRC_REG);
699         switch (priv->field) {
700         case V4L2_FIELD_INTERLACED:
701         case V4L2_FIELD_INTERLACED_TB:
702         case V4L2_FIELD_INTERLACED_BT:
703                 iowrite32(top_offset / 2, priv->base + VNSLPRC_REG);
704                 iowrite32((top_offset + cam->height) / 2 - 1,
705                           priv->base + VNELPRC_REG);
706                 break;
707         default:
708                 iowrite32(top_offset, priv->base + VNSLPRC_REG);
709                 iowrite32(top_offset + cam->height - 1,
710                           priv->base + VNELPRC_REG);
711                 break;
712         }
713 
714         /* Set Start/End Pixel/Line Post-Clip */
715         iowrite32(0, priv->base + VNSPPOC_REG);
716         iowrite32(0, priv->base + VNSLPOC_REG);
717         iowrite32((cam_subrect->width - 1) << dsize, priv->base + VNEPPOC_REG);
718         switch (priv->field) {
719         case V4L2_FIELD_INTERLACED:
720         case V4L2_FIELD_INTERLACED_TB:
721         case V4L2_FIELD_INTERLACED_BT:
722                 iowrite32(cam_subrect->height / 2 - 1,
723                           priv->base + VNELPOC_REG);
724                 break;
725         default:
726                 iowrite32(cam_subrect->height - 1, priv->base + VNELPOC_REG);
727                 break;
728         }
729 
730         iowrite32(ALIGN(cam->width, 0x10), priv->base + VNIS_REG);
731 
732         return 0;
733 }
734 
735 static void capture_stop_preserve(struct rcar_vin_priv *priv, u32 *vnmc)
736 {
737         *vnmc = ioread32(priv->base + VNMC_REG);
738         /* module disable */
739         iowrite32(*vnmc & ~VNMC_ME, priv->base + VNMC_REG);
740 }
741 
742 static void capture_restore(struct rcar_vin_priv *priv, u32 vnmc)
743 {
744         unsigned long timeout = jiffies + 10 * HZ;
745 
746         /*
747          * Wait until the end of the current frame. It can take a long time,
748          * but if it has been aborted by a MRST1 reset, it should exit sooner.
749          */
750         while ((ioread32(priv->base + VNMS_REG) & VNMS_AV) &&
751                 time_before(jiffies, timeout))
752                 msleep(1);
753 
754         if (time_after(jiffies, timeout)) {
755                 dev_err(priv->ici.v4l2_dev.dev,
756                         "Timeout waiting for frame end! Interface problem?\n");
757                 return;
758         }
759 
760         iowrite32(vnmc, priv->base + VNMC_REG);
761 }
762 
763 #define VIN_MBUS_FLAGS  (V4L2_MBUS_MASTER |             \
764                          V4L2_MBUS_PCLK_SAMPLE_RISING | \
765                          V4L2_MBUS_HSYNC_ACTIVE_HIGH |  \
766                          V4L2_MBUS_HSYNC_ACTIVE_LOW |   \
767                          V4L2_MBUS_VSYNC_ACTIVE_HIGH |  \
768                          V4L2_MBUS_VSYNC_ACTIVE_LOW |   \
769                          V4L2_MBUS_DATA_ACTIVE_HIGH)
770 
771 static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
772 {
773         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
774         struct rcar_vin_priv *priv = ici->priv;
775         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
776         struct v4l2_mbus_config cfg;
777         unsigned long common_flags;
778         u32 vnmc;
779         u32 val;
780         int ret;
781 
782         capture_stop_preserve(priv, &vnmc);
783 
784         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
785         if (!ret) {
786                 common_flags = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
787                 if (!common_flags) {
788                         dev_warn(icd->parent,
789                                  "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
790                                  cfg.flags, VIN_MBUS_FLAGS);
791                         return -EINVAL;
792                 }
793         } else if (ret != -ENOIOCTLCMD) {
794                 return ret;
795         } else {
796                 common_flags = VIN_MBUS_FLAGS;
797         }
798 
799         /* Make choises, based on platform preferences */
800         if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
801             (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
802                 if (priv->pdata->flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
803                         common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
804                 else
805                         common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
806         }
807 
808         if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
809             (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
810                 if (priv->pdata->flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
811                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
812                 else
813                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
814         }
815 
816         cfg.flags = common_flags;
817         ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
818         if (ret < 0 && ret != -ENOIOCTLCMD)
819                 return ret;
820 
821         val = priv->field == V4L2_FIELD_NONE ? VNDMR2_FTEV : 0;
822         if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
823                 val |= VNDMR2_VPS;
824         if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
825                 val |= VNDMR2_HPS;
826         iowrite32(val, priv->base + VNDMR2_REG);
827 
828         ret = rcar_vin_set_rect(icd);
829         if (ret < 0)
830                 return ret;
831 
832         capture_restore(priv, vnmc);
833 
834         return 0;
835 }
836 
837 static int rcar_vin_try_bus_param(struct soc_camera_device *icd,
838                                   unsigned char buswidth)
839 {
840         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
841         struct v4l2_mbus_config cfg;
842         int ret;
843 
844         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
845         if (ret == -ENOIOCTLCMD)
846                 return 0;
847         else if (ret)
848                 return ret;
849 
850         if (buswidth > 24)
851                 return -EINVAL;
852 
853         /* check is there common mbus flags */
854         ret = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
855         if (ret)
856                 return 0;
857 
858         dev_warn(icd->parent,
859                 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
860                  cfg.flags, VIN_MBUS_FLAGS);
861 
862         return -EINVAL;
863 }
864 
865 static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
866 {
867         return  fmt->packing == SOC_MBUS_PACKING_NONE ||
868                 (fmt->bits_per_sample > 8 &&
869                  fmt->packing == SOC_MBUS_PACKING_EXTEND16);
870 }
871 
872 static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
873         {
874                 .fourcc                 = V4L2_PIX_FMT_NV16,
875                 .name                   = "NV16",
876                 .bits_per_sample        = 8,
877                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
878                 .order                  = SOC_MBUS_ORDER_LE,
879                 .layout                 = SOC_MBUS_LAYOUT_PLANAR_Y_C,
880         },
881         {
882                 .fourcc                 = V4L2_PIX_FMT_UYVY,
883                 .name                   = "UYVY",
884                 .bits_per_sample        = 16,
885                 .packing                = SOC_MBUS_PACKING_NONE,
886                 .order                  = SOC_MBUS_ORDER_LE,
887                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
888         },
889         {
890                 .fourcc                 = V4L2_PIX_FMT_RGB565,
891                 .name                   = "RGB565",
892                 .bits_per_sample        = 16,
893                 .packing                = SOC_MBUS_PACKING_NONE,
894                 .order                  = SOC_MBUS_ORDER_LE,
895                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
896         },
897         {
898                 .fourcc                 = V4L2_PIX_FMT_RGB555X,
899                 .name                   = "ARGB1555",
900                 .bits_per_sample        = 16,
901                 .packing                = SOC_MBUS_PACKING_NONE,
902                 .order                  = SOC_MBUS_ORDER_LE,
903                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
904         },
905         {
906                 .fourcc                 = V4L2_PIX_FMT_RGB32,
907                 .name                   = "RGB888",
908                 .bits_per_sample        = 32,
909                 .packing                = SOC_MBUS_PACKING_NONE,
910                 .order                  = SOC_MBUS_ORDER_LE,
911                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
912         },
913 };
914 
915 static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
916                                 struct soc_camera_format_xlate *xlate)
917 {
918         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
919         struct device *dev = icd->parent;
920         int ret, k, n;
921         int formats = 0;
922         struct rcar_vin_cam *cam;
923         enum v4l2_mbus_pixelcode code;
924         const struct soc_mbus_pixelfmt *fmt;
925 
926         ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
927         if (ret < 0)
928                 return 0;
929 
930         fmt = soc_mbus_get_fmtdesc(code);
931         if (!fmt) {
932                 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
933                 return 0;
934         }
935 
936         ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
937         if (ret < 0)
938                 return 0;
939 
940         if (!icd->host_priv) {
941                 struct v4l2_mbus_framefmt mf;
942                 struct v4l2_rect rect;
943                 struct device *dev = icd->parent;
944                 int shift;
945 
946                 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
947                 if (ret < 0)
948                         return ret;
949 
950                 /* Cache current client geometry */
951                 ret = soc_camera_client_g_rect(sd, &rect);
952                 if (ret == -ENOIOCTLCMD) {
953                         /* Sensor driver doesn't support cropping */
954                         rect.left = 0;
955                         rect.top = 0;
956                         rect.width = mf.width;
957                         rect.height = mf.height;
958                 } else if (ret < 0) {
959                         return ret;
960                 }
961 
962                 /*
963                  * If sensor proposes too large format then try smaller ones:
964                  * 1280x960, 640x480, 320x240
965                  */
966                 for (shift = 0; shift < 3; shift++) {
967                         if (mf.width <= VIN_MAX_WIDTH &&
968                             mf.height <= VIN_MAX_HEIGHT)
969                                 break;
970 
971                         mf.width = 1280 >> shift;
972                         mf.height = 960 >> shift;
973                         ret = v4l2_device_call_until_err(sd->v4l2_dev,
974                                                          soc_camera_grp_id(icd),
975                                                          video, s_mbus_fmt,
976                                                          &mf);
977                         if (ret < 0)
978                                 return ret;
979                 }
980 
981                 if (shift == 3) {
982                         dev_err(dev,
983                                 "Failed to configure the client below %ux%x\n",
984                                 mf.width, mf.height);
985                         return -EIO;
986                 }
987 
988                 dev_dbg(dev, "camera fmt %ux%u\n", mf.width, mf.height);
989 
990                 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
991                 if (!cam)
992                         return -ENOMEM;
993                 /*
994                  * We are called with current camera crop,
995                  * initialise subrect with it
996                  */
997                 cam->rect = rect;
998                 cam->subrect = rect;
999                 cam->width = mf.width;
1000                 cam->height = mf.height;
1001 
1002                 icd->host_priv = cam;
1003         } else {
1004                 cam = icd->host_priv;
1005         }
1006 
1007         /* Beginning of a pass */
1008         if (!idx)
1009                 cam->extra_fmt = NULL;
1010 
1011         switch (code) {
1012         case V4L2_MBUS_FMT_YUYV8_1X16:
1013         case V4L2_MBUS_FMT_YUYV8_2X8:
1014         case V4L2_MBUS_FMT_YUYV10_2X10:
1015                 if (cam->extra_fmt)
1016                         break;
1017 
1018                 /* Add all our formats that can be generated by VIN */
1019                 cam->extra_fmt = rcar_vin_formats;
1020 
1021                 n = ARRAY_SIZE(rcar_vin_formats);
1022                 formats += n;
1023                 for (k = 0; xlate && k < n; k++, xlate++) {
1024                         xlate->host_fmt = &rcar_vin_formats[k];
1025                         xlate->code = code;
1026                         dev_dbg(dev, "Providing format %s using code %d\n",
1027                                 rcar_vin_formats[k].name, code);
1028                 }
1029                 break;
1030         default:
1031                 if (!rcar_vin_packing_supported(fmt))
1032                         return 0;
1033 
1034                 dev_dbg(dev, "Providing format %s in pass-through mode\n",
1035                         fmt->name);
1036                 break;
1037         }
1038 
1039         /* Generic pass-through */
1040         formats++;
1041         if (xlate) {
1042                 xlate->host_fmt = fmt;
1043                 xlate->code = code;
1044                 xlate++;
1045         }
1046 
1047         return formats;
1048 }
1049 
1050 static void rcar_vin_put_formats(struct soc_camera_device *icd)
1051 {
1052         kfree(icd->host_priv);
1053         icd->host_priv = NULL;
1054 }
1055 
1056 static int rcar_vin_set_crop(struct soc_camera_device *icd,
1057                              const struct v4l2_crop *a)
1058 {
1059         struct v4l2_crop a_writable = *a;
1060         const struct v4l2_rect *rect = &a_writable.c;
1061         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1062         struct rcar_vin_priv *priv = ici->priv;
1063         struct v4l2_crop cam_crop;
1064         struct rcar_vin_cam *cam = icd->host_priv;
1065         struct v4l2_rect *cam_rect = &cam_crop.c;
1066         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1067         struct device *dev = icd->parent;
1068         struct v4l2_mbus_framefmt mf;
1069         u32 vnmc;
1070         int ret, i;
1071 
1072         dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1073                 rect->left, rect->top);
1074 
1075         /* During camera cropping its output window can change too, stop VIN */
1076         capture_stop_preserve(priv, &vnmc);
1077         dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
1078 
1079         /* Apply iterative camera S_CROP for new input window. */
1080         ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
1081                                        &cam->rect, &cam->subrect);
1082         if (ret < 0)
1083                 return ret;
1084 
1085         dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
1086                 cam_rect->width, cam_rect->height,
1087                 cam_rect->left, cam_rect->top);
1088 
1089         /* On success cam_crop contains current camera crop */
1090 
1091         /* Retrieve camera output window */
1092         ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1093         if (ret < 0)
1094                 return ret;
1095 
1096         if (mf.width > VIN_MAX_WIDTH || mf.height > VIN_MAX_HEIGHT)
1097                 return -EINVAL;
1098 
1099         /* Cache camera output window */
1100         cam->width = mf.width;
1101         cam->height = mf.height;
1102 
1103         icd->user_width  = cam->width;
1104         icd->user_height = cam->height;
1105 
1106         cam->vin_left = rect->left & ~1;
1107         cam->vin_top = rect->top & ~1;
1108 
1109         /* Use VIN cropping to crop to the new window. */
1110         ret = rcar_vin_set_rect(icd);
1111         if (ret < 0)
1112                 return ret;
1113 
1114         cam->subrect = *rect;
1115 
1116         dev_dbg(dev, "VIN cropped to %ux%u@%u:%u\n",
1117                 icd->user_width, icd->user_height,
1118                 cam->vin_left, cam->vin_top);
1119 
1120         /* Restore capture */
1121         for (i = 0; i < MAX_BUFFER_NUM; i++) {
1122                 if (priv->queue_buf[i] && priv->state == STOPPED) {
1123                         vnmc |= VNMC_ME;
1124                         break;
1125                 }
1126         }
1127         capture_restore(priv, vnmc);
1128 
1129         /* Even if only camera cropping succeeded */
1130         return ret;
1131 }
1132 
1133 static int rcar_vin_get_crop(struct soc_camera_device *icd,
1134                              struct v4l2_crop *a)
1135 {
1136         struct rcar_vin_cam *cam = icd->host_priv;
1137 
1138         a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1139         a->c = cam->subrect;
1140 
1141         return 0;
1142 }
1143 
1144 /* Similar to set_crop multistage iterative algorithm */
1145 static int rcar_vin_set_fmt(struct soc_camera_device *icd,
1146                             struct v4l2_format *f)
1147 {
1148         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1149         struct rcar_vin_priv *priv = ici->priv;
1150         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1151         struct rcar_vin_cam *cam = icd->host_priv;
1152         struct v4l2_pix_format *pix = &f->fmt.pix;
1153         struct v4l2_mbus_framefmt mf;
1154         struct device *dev = icd->parent;
1155         __u32 pixfmt = pix->pixelformat;
1156         const struct soc_camera_format_xlate *xlate;
1157         unsigned int vin_sub_width = 0, vin_sub_height = 0;
1158         int ret;
1159         bool can_scale;
1160         enum v4l2_field field;
1161         v4l2_std_id std;
1162 
1163         dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
1164                 pixfmt, pix->width, pix->height);
1165 
1166         switch (pix->field) {
1167         default:
1168                 pix->field = V4L2_FIELD_NONE;
1169                 /* fall-through */
1170         case V4L2_FIELD_NONE:
1171         case V4L2_FIELD_TOP:
1172         case V4L2_FIELD_BOTTOM:
1173         case V4L2_FIELD_INTERLACED_TB:
1174         case V4L2_FIELD_INTERLACED_BT:
1175                 field = pix->field;
1176                 break;
1177         case V4L2_FIELD_INTERLACED:
1178                 /* Query for standard if not explicitly mentioned _TB/_BT */
1179                 ret = v4l2_subdev_call(sd, video, querystd, &std);
1180                 if (ret < 0)
1181                         std = V4L2_STD_625_50;
1182 
1183                 field = std & V4L2_STD_625_50 ? V4L2_FIELD_INTERLACED_TB :
1184                                                 V4L2_FIELD_INTERLACED_BT;
1185                 break;
1186         }
1187 
1188         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1189         if (!xlate) {
1190                 dev_warn(dev, "Format %x not found\n", pixfmt);
1191                 return -EINVAL;
1192         }
1193         /* Calculate client output geometry */
1194         soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
1195                                       12);
1196         mf.field = pix->field;
1197         mf.colorspace = pix->colorspace;
1198         mf.code  = xlate->code;
1199 
1200         switch (pixfmt) {
1201         case V4L2_PIX_FMT_RGB32:
1202                 can_scale = priv->chip != RCAR_E1;
1203                 break;
1204         case V4L2_PIX_FMT_UYVY:
1205         case V4L2_PIX_FMT_YUYV:
1206         case V4L2_PIX_FMT_RGB565:
1207         case V4L2_PIX_FMT_RGB555X:
1208                 can_scale = true;
1209                 break;
1210         default:
1211                 can_scale = false;
1212                 break;
1213         }
1214 
1215         dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
1216 
1217         ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
1218                                       &mf, &vin_sub_width, &vin_sub_height,
1219                                       can_scale, 12);
1220 
1221         /* Done with the camera. Now see if we can improve the result */
1222         dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1223                 ret, mf.width, mf.height, pix->width, pix->height);
1224 
1225         if (ret == -ENOIOCTLCMD)
1226                 dev_dbg(dev, "Sensor doesn't support scaling\n");
1227         else if (ret < 0)
1228                 return ret;
1229 
1230         if (mf.code != xlate->code)
1231                 return -EINVAL;
1232 
1233         /* Prepare VIN crop */
1234         cam->width = mf.width;
1235         cam->height = mf.height;
1236 
1237         /* Use VIN scaling to scale to the requested user window. */
1238 
1239         /* We cannot scale up */
1240         if (pix->width > vin_sub_width)
1241                 vin_sub_width = pix->width;
1242 
1243         if (pix->height > vin_sub_height)
1244                 vin_sub_height = pix->height;
1245 
1246         pix->colorspace = mf.colorspace;
1247 
1248         if (!can_scale) {
1249                 pix->width = vin_sub_width;
1250                 pix->height = vin_sub_height;
1251         }
1252 
1253         /*
1254          * We have calculated CFLCR, the actual configuration will be performed
1255          * in rcar_vin_set_bus_param()
1256          */
1257 
1258         dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
1259                 vin_sub_width, pix->width, vin_sub_height, pix->height);
1260 
1261         icd->current_fmt = xlate;
1262 
1263         priv->field = field;
1264 
1265         return 0;
1266 }
1267 
1268 static int rcar_vin_try_fmt(struct soc_camera_device *icd,
1269                             struct v4l2_format *f)
1270 {
1271         const struct soc_camera_format_xlate *xlate;
1272         struct v4l2_pix_format *pix = &f->fmt.pix;
1273         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1274         struct v4l2_mbus_framefmt mf;
1275         __u32 pixfmt = pix->pixelformat;
1276         int width, height;
1277         int ret;
1278 
1279         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1280         if (!xlate) {
1281                 xlate = icd->current_fmt;
1282                 dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
1283                         pixfmt, xlate->host_fmt->fourcc);
1284                 pixfmt = xlate->host_fmt->fourcc;
1285                 pix->pixelformat = pixfmt;
1286                 pix->colorspace = icd->colorspace;
1287         }
1288 
1289         /* FIXME: calculate using depth and bus width */
1290         v4l_bound_align_image(&pix->width, 2, VIN_MAX_WIDTH, 1,
1291                               &pix->height, 4, VIN_MAX_HEIGHT, 2, 0);
1292 
1293         width = pix->width;
1294         height = pix->height;
1295 
1296         /* let soc-camera calculate these values */
1297         pix->bytesperline = 0;
1298         pix->sizeimage = 0;
1299 
1300         /* limit to sensor capabilities */
1301         mf.width = pix->width;
1302         mf.height = pix->height;
1303         mf.field = pix->field;
1304         mf.code = xlate->code;
1305         mf.colorspace = pix->colorspace;
1306 
1307         ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
1308                                          video, try_mbus_fmt, &mf);
1309         if (ret < 0)
1310                 return ret;
1311 
1312         pix->width = mf.width;
1313         pix->height = mf.height;
1314         pix->field = mf.field;
1315         pix->colorspace = mf.colorspace;
1316 
1317         if (pixfmt == V4L2_PIX_FMT_NV16) {
1318                 /* FIXME: check against rect_max after converting soc-camera */
1319                 /* We can scale precisely, need a bigger image from camera */
1320                 if (pix->width < width || pix->height < height) {
1321                         /*
1322                          * We presume, the sensor behaves sanely, i.e. if
1323                          * requested a bigger rectangle, it will not return a
1324                          * smaller one.
1325                          */
1326                         mf.width = VIN_MAX_WIDTH;
1327                         mf.height = VIN_MAX_HEIGHT;
1328                         ret = v4l2_device_call_until_err(sd->v4l2_dev,
1329                                                          soc_camera_grp_id(icd),
1330                                                          video, try_mbus_fmt,
1331                                                          &mf);
1332                         if (ret < 0) {
1333                                 dev_err(icd->parent,
1334                                         "client try_fmt() = %d\n", ret);
1335                                 return ret;
1336                         }
1337                 }
1338                 /* We will scale exactly */
1339                 if (mf.width > width)
1340                         pix->width = width;
1341                 if (mf.height > height)
1342                         pix->height = height;
1343         }
1344 
1345         return ret;
1346 }
1347 
1348 static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
1349 {
1350         struct soc_camera_device *icd = file->private_data;
1351 
1352         return vb2_poll(&icd->vb2_vidq, file, pt);
1353 }
1354 
1355 static int rcar_vin_querycap(struct soc_camera_host *ici,
1356                              struct v4l2_capability *cap)
1357 {
1358         strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
1359         cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1360         return 0;
1361 }
1362 
1363 static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
1364                                    struct soc_camera_device *icd)
1365 {
1366         vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1367         vq->io_modes = VB2_MMAP | VB2_USERPTR;
1368         vq->drv_priv = icd;
1369         vq->ops = &rcar_vin_vb2_ops;
1370         vq->mem_ops = &vb2_dma_contig_memops;
1371         vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
1372         vq->timestamp_flags  = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1373 
1374         return vb2_queue_init(vq);
1375 }
1376 
1377 static struct soc_camera_host_ops rcar_vin_host_ops = {
1378         .owner          = THIS_MODULE,
1379         .add            = rcar_vin_add_device,
1380         .remove         = rcar_vin_remove_device,
1381         .clock_start    = rcar_vin_clock_start,
1382         .clock_stop     = rcar_vin_clock_stop,
1383         .get_formats    = rcar_vin_get_formats,
1384         .put_formats    = rcar_vin_put_formats,
1385         .get_crop       = rcar_vin_get_crop,
1386         .set_crop       = rcar_vin_set_crop,
1387         .try_fmt        = rcar_vin_try_fmt,
1388         .set_fmt        = rcar_vin_set_fmt,
1389         .poll           = rcar_vin_poll,
1390         .querycap       = rcar_vin_querycap,
1391         .set_bus_param  = rcar_vin_set_bus_param,
1392         .init_videobuf2 = rcar_vin_init_videobuf2,
1393 };
1394 
1395 static struct platform_device_id rcar_vin_id_table[] = {
1396         { "r8a7791-vin",  RCAR_GEN2 },
1397         { "r8a7790-vin",  RCAR_GEN2 },
1398         { "r8a7779-vin",  RCAR_H1 },
1399         { "r8a7778-vin",  RCAR_M1 },
1400         { "uPD35004-vin", RCAR_E1 },
1401         {},
1402 };
1403 MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1404 
1405 static int rcar_vin_probe(struct platform_device *pdev)
1406 {
1407         struct rcar_vin_priv *priv;
1408         struct resource *mem;
1409         struct rcar_vin_platform_data *pdata;
1410         int irq, ret;
1411 
1412         pdata = pdev->dev.platform_data;
1413         if (!pdata || !pdata->flags) {
1414                 dev_err(&pdev->dev, "platform data not set\n");
1415                 return -EINVAL;
1416         }
1417 
1418         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1419         if (mem == NULL)
1420                 return -EINVAL;
1421 
1422         irq = platform_get_irq(pdev, 0);
1423         if (irq <= 0)
1424                 return -EINVAL;
1425 
1426         priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
1427                             GFP_KERNEL);
1428         if (!priv)
1429                 return -ENOMEM;
1430 
1431         priv->base = devm_ioremap_resource(&pdev->dev, mem);
1432         if (IS_ERR(priv->base))
1433                 return PTR_ERR(priv->base);
1434 
1435         ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
1436                                dev_name(&pdev->dev), priv);
1437         if (ret)
1438                 return ret;
1439 
1440         priv->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1441         if (IS_ERR(priv->alloc_ctx))
1442                 return PTR_ERR(priv->alloc_ctx);
1443 
1444         priv->ici.priv = priv;
1445         priv->ici.v4l2_dev.dev = &pdev->dev;
1446         priv->ici.nr = pdev->id;
1447         priv->ici.drv_name = dev_name(&pdev->dev);
1448         priv->ici.ops = &rcar_vin_host_ops;
1449 
1450         priv->pdata = pdata;
1451         priv->chip = pdev->id_entry->driver_data;
1452         spin_lock_init(&priv->lock);
1453         INIT_LIST_HEAD(&priv->capture);
1454 
1455         priv->state = STOPPED;
1456 
1457         pm_suspend_ignore_children(&pdev->dev, true);
1458         pm_runtime_enable(&pdev->dev);
1459 
1460         ret = soc_camera_host_register(&priv->ici);
1461         if (ret)
1462                 goto cleanup;
1463 
1464         return 0;
1465 
1466 cleanup:
1467         pm_runtime_disable(&pdev->dev);
1468         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1469 
1470         return ret;
1471 }
1472 
1473 static int rcar_vin_remove(struct platform_device *pdev)
1474 {
1475         struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1476         struct rcar_vin_priv *priv = container_of(soc_host,
1477                                                   struct rcar_vin_priv, ici);
1478 
1479         soc_camera_host_unregister(soc_host);
1480         pm_runtime_disable(&pdev->dev);
1481         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1482 
1483         return 0;
1484 }
1485 
1486 static struct platform_driver rcar_vin_driver = {
1487         .probe          = rcar_vin_probe,
1488         .remove         = rcar_vin_remove,
1489         .driver         = {
1490                 .name           = DRV_NAME,
1491                 .owner          = THIS_MODULE,
1492         },
1493         .id_table       = rcar_vin_id_table,
1494 };
1495 
1496 module_platform_driver(rcar_vin_driver);
1497 
1498 MODULE_LICENSE("GPL");
1499 MODULE_ALIAS("platform:rcar_vin");
1500 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
1501 

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