Version:  2.0.40 2.2.26 2.4.37 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4

Linux/drivers/media/platform/soc_camera/atmel-isi.c

  1 /*
  2  * Copyright (c) 2011 Atmel Corporation
  3  * Josh Wu, <josh.wu@atmel.com>
  4  *
  5  * Based on previous work by Lars Haring, <lars.haring@atmel.com>
  6  * and Sedji Gaouaou
  7  * Based on the bttv driver for Bt848 with respective copyright holders
  8  *
  9  * This program is free software; you can redistribute it and/or modify
 10  * it under the terms of the GNU General Public License version 2 as
 11  * published by the Free Software Foundation.
 12  */
 13 
 14 #include <linux/clk.h>
 15 #include <linux/completion.h>
 16 #include <linux/delay.h>
 17 #include <linux/fs.h>
 18 #include <linux/init.h>
 19 #include <linux/interrupt.h>
 20 #include <linux/kernel.h>
 21 #include <linux/module.h>
 22 #include <linux/platform_device.h>
 23 #include <linux/pm_runtime.h>
 24 #include <linux/slab.h>
 25 
 26 #include <media/soc_camera.h>
 27 #include <media/soc_mediabus.h>
 28 #include <media/v4l2-of.h>
 29 #include <media/videobuf2-dma-contig.h>
 30 
 31 #include "atmel-isi.h"
 32 
 33 #define MAX_BUFFER_NUM                  32
 34 #define MAX_SUPPORT_WIDTH               2048
 35 #define MAX_SUPPORT_HEIGHT              2048
 36 #define VID_LIMIT_BYTES                 (16 * 1024 * 1024)
 37 #define MIN_FRAME_RATE                  15
 38 #define FRAME_INTERVAL_MILLI_SEC        (1000 / MIN_FRAME_RATE)
 39 
 40 /* Frame buffer descriptor */
 41 struct fbd {
 42         /* Physical address of the frame buffer */
 43         u32 fb_address;
 44         /* DMA Control Register(only in HISI2) */
 45         u32 dma_ctrl;
 46         /* Physical address of the next fbd */
 47         u32 next_fbd_address;
 48 };
 49 
 50 static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl)
 51 {
 52         fb_desc->dma_ctrl = ctrl;
 53 }
 54 
 55 struct isi_dma_desc {
 56         struct list_head list;
 57         struct fbd *p_fbd;
 58         dma_addr_t fbd_phys;
 59 };
 60 
 61 /* Frame buffer data */
 62 struct frame_buffer {
 63         struct vb2_v4l2_buffer vb;
 64         struct isi_dma_desc *p_dma_desc;
 65         struct list_head list;
 66 };
 67 
 68 struct atmel_isi {
 69         /* Protects the access of variables shared with the ISR */
 70         spinlock_t                      lock;
 71         void __iomem                    *regs;
 72 
 73         int                             sequence;
 74 
 75         struct vb2_alloc_ctx            *alloc_ctx;
 76 
 77         /* Allocate descriptors for dma buffer use */
 78         struct fbd                      *p_fb_descriptors;
 79         dma_addr_t                      fb_descriptors_phys;
 80         struct                          list_head dma_desc_head;
 81         struct isi_dma_desc             dma_desc[MAX_BUFFER_NUM];
 82 
 83         struct completion               complete;
 84         /* ISI peripherial clock */
 85         struct clk                      *pclk;
 86         unsigned int                    irq;
 87 
 88         struct isi_platform_data        pdata;
 89         u16                             width_flags;    /* max 12 bits */
 90 
 91         struct list_head                video_buffer_list;
 92         struct frame_buffer             *active;
 93 
 94         struct soc_camera_host          soc_host;
 95 };
 96 
 97 static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val)
 98 {
 99         writel(val, isi->regs + reg);
100 }
101 static u32 isi_readl(struct atmel_isi *isi, u32 reg)
102 {
103         return readl(isi->regs + reg);
104 }
105 
106 static void configure_geometry(struct atmel_isi *isi, u32 width,
107                         u32 height, u32 code)
108 {
109         u32 cfg2;
110 
111         /* According to sensor's output format to set cfg2 */
112         switch (code) {
113         default:
114         /* Grey */
115         case MEDIA_BUS_FMT_Y8_1X8:
116                 cfg2 = ISI_CFG2_GRAYSCALE | ISI_CFG2_COL_SPACE_YCbCr;
117                 break;
118         /* YUV */
119         case MEDIA_BUS_FMT_VYUY8_2X8:
120                 cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr;
121                 break;
122         case MEDIA_BUS_FMT_UYVY8_2X8:
123                 cfg2 = ISI_CFG2_YCC_SWAP_MODE_2 | ISI_CFG2_COL_SPACE_YCbCr;
124                 break;
125         case MEDIA_BUS_FMT_YVYU8_2X8:
126                 cfg2 = ISI_CFG2_YCC_SWAP_MODE_1 | ISI_CFG2_COL_SPACE_YCbCr;
127                 break;
128         case MEDIA_BUS_FMT_YUYV8_2X8:
129                 cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr;
130                 break;
131         /* RGB, TODO */
132         }
133 
134         isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
135         /* Set width */
136         cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
137                         ISI_CFG2_IM_HSIZE_MASK;
138         /* Set height */
139         cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
140                         & ISI_CFG2_IM_VSIZE_MASK;
141         isi_writel(isi, ISI_CFG2, cfg2);
142 }
143 
144 static bool is_supported(struct soc_camera_device *icd,
145                 const u32 pixformat)
146 {
147         switch (pixformat) {
148         /* YUV, including grey */
149         case V4L2_PIX_FMT_GREY:
150         case V4L2_PIX_FMT_YUYV:
151         case V4L2_PIX_FMT_UYVY:
152         case V4L2_PIX_FMT_YVYU:
153         case V4L2_PIX_FMT_VYUY:
154                 return true;
155         /* RGB, TODO */
156         default:
157                 return false;
158         }
159 }
160 
161 static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
162 {
163         if (isi->active) {
164                 struct vb2_v4l2_buffer *vbuf = &isi->active->vb;
165                 struct frame_buffer *buf = isi->active;
166 
167                 list_del_init(&buf->list);
168                 v4l2_get_timestamp(&vbuf->timestamp);
169                 vbuf->sequence = isi->sequence++;
170                 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
171         }
172 
173         if (list_empty(&isi->video_buffer_list)) {
174                 isi->active = NULL;
175         } else {
176                 /* start next dma frame. */
177                 isi->active = list_entry(isi->video_buffer_list.next,
178                                         struct frame_buffer, list);
179                 isi_writel(isi, ISI_DMA_C_DSCR,
180                         (u32)isi->active->p_dma_desc->fbd_phys);
181                 isi_writel(isi, ISI_DMA_C_CTRL,
182                         ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
183                 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
184         }
185         return IRQ_HANDLED;
186 }
187 
188 /* ISI interrupt service routine */
189 static irqreturn_t isi_interrupt(int irq, void *dev_id)
190 {
191         struct atmel_isi *isi = dev_id;
192         u32 status, mask, pending;
193         irqreturn_t ret = IRQ_NONE;
194 
195         spin_lock(&isi->lock);
196 
197         status = isi_readl(isi, ISI_STATUS);
198         mask = isi_readl(isi, ISI_INTMASK);
199         pending = status & mask;
200 
201         if (pending & ISI_CTRL_SRST) {
202                 complete(&isi->complete);
203                 isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
204                 ret = IRQ_HANDLED;
205         } else if (pending & ISI_CTRL_DIS) {
206                 complete(&isi->complete);
207                 isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
208                 ret = IRQ_HANDLED;
209         } else {
210                 if (likely(pending & ISI_SR_CXFR_DONE))
211                         ret = atmel_isi_handle_streaming(isi);
212         }
213 
214         spin_unlock(&isi->lock);
215         return ret;
216 }
217 
218 #define WAIT_ISI_RESET          1
219 #define WAIT_ISI_DISABLE        0
220 static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
221 {
222         unsigned long timeout;
223         /*
224          * The reset or disable will only succeed if we have a
225          * pixel clock from the camera.
226          */
227         init_completion(&isi->complete);
228 
229         if (wait_reset) {
230                 isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST);
231                 isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST);
232         } else {
233                 isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS);
234                 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
235         }
236 
237         timeout = wait_for_completion_timeout(&isi->complete,
238                         msecs_to_jiffies(500));
239         if (timeout == 0)
240                 return -ETIMEDOUT;
241 
242         return 0;
243 }
244 
245 /* ------------------------------------------------------------------
246         Videobuf operations
247    ------------------------------------------------------------------*/
248 static int queue_setup(struct vb2_queue *vq, const void *parg,
249                                 unsigned int *nbuffers, unsigned int *nplanes,
250                                 unsigned int sizes[], void *alloc_ctxs[])
251 {
252         struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
253         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
254         struct atmel_isi *isi = ici->priv;
255         unsigned long size;
256 
257         size = icd->sizeimage;
258 
259         if (!*nbuffers || *nbuffers > MAX_BUFFER_NUM)
260                 *nbuffers = MAX_BUFFER_NUM;
261 
262         if (size * *nbuffers > VID_LIMIT_BYTES)
263                 *nbuffers = VID_LIMIT_BYTES / size;
264 
265         *nplanes = 1;
266         sizes[0] = size;
267         alloc_ctxs[0] = isi->alloc_ctx;
268 
269         isi->sequence = 0;
270         isi->active = NULL;
271 
272         dev_dbg(icd->parent, "%s, count=%d, size=%ld\n", __func__,
273                 *nbuffers, size);
274 
275         return 0;
276 }
277 
278 static int buffer_init(struct vb2_buffer *vb)
279 {
280         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
281         struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
282 
283         buf->p_dma_desc = NULL;
284         INIT_LIST_HEAD(&buf->list);
285 
286         return 0;
287 }
288 
289 static int buffer_prepare(struct vb2_buffer *vb)
290 {
291         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
292         struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
293         struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
294         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
295         struct atmel_isi *isi = ici->priv;
296         unsigned long size;
297         struct isi_dma_desc *desc;
298 
299         size = icd->sizeimage;
300 
301         if (vb2_plane_size(vb, 0) < size) {
302                 dev_err(icd->parent, "%s data will not fit into plane (%lu < %lu)\n",
303                                 __func__, vb2_plane_size(vb, 0), size);
304                 return -EINVAL;
305         }
306 
307         vb2_set_plane_payload(vb, 0, size);
308 
309         if (!buf->p_dma_desc) {
310                 if (list_empty(&isi->dma_desc_head)) {
311                         dev_err(icd->parent, "Not enough dma descriptors.\n");
312                         return -EINVAL;
313                 } else {
314                         /* Get an available descriptor */
315                         desc = list_entry(isi->dma_desc_head.next,
316                                                 struct isi_dma_desc, list);
317                         /* Delete the descriptor since now it is used */
318                         list_del_init(&desc->list);
319 
320                         /* Initialize the dma descriptor */
321                         desc->p_fbd->fb_address =
322                                         vb2_dma_contig_plane_dma_addr(vb, 0);
323                         desc->p_fbd->next_fbd_address = 0;
324                         set_dma_ctrl(desc->p_fbd, ISI_DMA_CTRL_WB);
325 
326                         buf->p_dma_desc = desc;
327                 }
328         }
329         return 0;
330 }
331 
332 static void buffer_cleanup(struct vb2_buffer *vb)
333 {
334         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
335         struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
336         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
337         struct atmel_isi *isi = ici->priv;
338         struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
339 
340         /* This descriptor is available now and we add to head list */
341         if (buf->p_dma_desc)
342                 list_add(&buf->p_dma_desc->list, &isi->dma_desc_head);
343 }
344 
345 static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
346 {
347         u32 ctrl, cfg1;
348 
349         cfg1 = isi_readl(isi, ISI_CFG1);
350         /* Enable irq: cxfr for the codec path, pxfr for the preview path */
351         isi_writel(isi, ISI_INTEN,
352                         ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
353 
354         /* Check if already in a frame */
355         if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
356                 dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
357                 return;
358         }
359 
360         isi_writel(isi, ISI_DMA_C_DSCR, (u32)buffer->p_dma_desc->fbd_phys);
361         isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
362         isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
363 
364         cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
365         /* Enable linked list */
366         cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
367 
368         /* Enable codec path and ISI */
369         ctrl = ISI_CTRL_CDC | ISI_CTRL_EN;
370         isi_writel(isi, ISI_CTRL, ctrl);
371         isi_writel(isi, ISI_CFG1, cfg1);
372 }
373 
374 static void buffer_queue(struct vb2_buffer *vb)
375 {
376         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
377         struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
378         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
379         struct atmel_isi *isi = ici->priv;
380         struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
381         unsigned long flags = 0;
382 
383         spin_lock_irqsave(&isi->lock, flags);
384         list_add_tail(&buf->list, &isi->video_buffer_list);
385 
386         if (isi->active == NULL) {
387                 isi->active = buf;
388                 if (vb2_is_streaming(vb->vb2_queue))
389                         start_dma(isi, buf);
390         }
391         spin_unlock_irqrestore(&isi->lock, flags);
392 }
393 
394 static int start_streaming(struct vb2_queue *vq, unsigned int count)
395 {
396         struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
397         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
398         struct atmel_isi *isi = ici->priv;
399         int ret;
400 
401         pm_runtime_get_sync(ici->v4l2_dev.dev);
402 
403         /* Reset ISI */
404         ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
405         if (ret < 0) {
406                 dev_err(icd->parent, "Reset ISI timed out\n");
407                 pm_runtime_put(ici->v4l2_dev.dev);
408                 return ret;
409         }
410         /* Disable all interrupts */
411         isi_writel(isi, ISI_INTDIS, (u32)~0UL);
412 
413         configure_geometry(isi, icd->user_width, icd->user_height,
414                                 icd->current_fmt->code);
415 
416         spin_lock_irq(&isi->lock);
417         /* Clear any pending interrupt */
418         isi_readl(isi, ISI_STATUS);
419 
420         if (count)
421                 start_dma(isi, isi->active);
422         spin_unlock_irq(&isi->lock);
423 
424         return 0;
425 }
426 
427 /* abort streaming and wait for last buffer */
428 static void stop_streaming(struct vb2_queue *vq)
429 {
430         struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
431         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
432         struct atmel_isi *isi = ici->priv;
433         struct frame_buffer *buf, *node;
434         int ret = 0;
435         unsigned long timeout;
436 
437         spin_lock_irq(&isi->lock);
438         isi->active = NULL;
439         /* Release all active buffers */
440         list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
441                 list_del_init(&buf->list);
442                 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
443         }
444         spin_unlock_irq(&isi->lock);
445 
446         timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
447         /* Wait until the end of the current frame. */
448         while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
449                         time_before(jiffies, timeout))
450                 msleep(1);
451 
452         if (time_after(jiffies, timeout))
453                 dev_err(icd->parent,
454                         "Timeout waiting for finishing codec request\n");
455 
456         /* Disable interrupts */
457         isi_writel(isi, ISI_INTDIS,
458                         ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
459 
460         /* Disable ISI and wait for it is done */
461         ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE);
462         if (ret < 0)
463                 dev_err(icd->parent, "Disable ISI timed out\n");
464 
465         pm_runtime_put(ici->v4l2_dev.dev);
466 }
467 
468 static struct vb2_ops isi_video_qops = {
469         .queue_setup            = queue_setup,
470         .buf_init               = buffer_init,
471         .buf_prepare            = buffer_prepare,
472         .buf_cleanup            = buffer_cleanup,
473         .buf_queue              = buffer_queue,
474         .start_streaming        = start_streaming,
475         .stop_streaming         = stop_streaming,
476         .wait_prepare           = vb2_ops_wait_prepare,
477         .wait_finish            = vb2_ops_wait_finish,
478 };
479 
480 /* ------------------------------------------------------------------
481         SOC camera operations for the device
482    ------------------------------------------------------------------*/
483 static int isi_camera_init_videobuf(struct vb2_queue *q,
484                                      struct soc_camera_device *icd)
485 {
486         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
487 
488         q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
489         q->io_modes = VB2_MMAP;
490         q->drv_priv = icd;
491         q->buf_struct_size = sizeof(struct frame_buffer);
492         q->ops = &isi_video_qops;
493         q->mem_ops = &vb2_dma_contig_memops;
494         q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
495         q->lock = &ici->host_lock;
496 
497         return vb2_queue_init(q);
498 }
499 
500 static int isi_camera_set_fmt(struct soc_camera_device *icd,
501                               struct v4l2_format *f)
502 {
503         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
504         const struct soc_camera_format_xlate *xlate;
505         struct v4l2_pix_format *pix = &f->fmt.pix;
506         struct v4l2_subdev_format format = {
507                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
508         };
509         struct v4l2_mbus_framefmt *mf = &format.format;
510         int ret;
511 
512         /* check with atmel-isi support format, if not support use YUYV */
513         if (!is_supported(icd, pix->pixelformat))
514                 pix->pixelformat = V4L2_PIX_FMT_YUYV;
515 
516         xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
517         if (!xlate) {
518                 dev_warn(icd->parent, "Format %x not found\n",
519                          pix->pixelformat);
520                 return -EINVAL;
521         }
522 
523         dev_dbg(icd->parent, "Plan to set format %dx%d\n",
524                         pix->width, pix->height);
525 
526         mf->width       = pix->width;
527         mf->height      = pix->height;
528         mf->field       = pix->field;
529         mf->colorspace  = pix->colorspace;
530         mf->code        = xlate->code;
531 
532         ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format);
533         if (ret < 0)
534                 return ret;
535 
536         if (mf->code != xlate->code)
537                 return -EINVAL;
538 
539         pix->width              = mf->width;
540         pix->height             = mf->height;
541         pix->field              = mf->field;
542         pix->colorspace         = mf->colorspace;
543         icd->current_fmt        = xlate;
544 
545         dev_dbg(icd->parent, "Finally set format %dx%d\n",
546                 pix->width, pix->height);
547 
548         return ret;
549 }
550 
551 static int isi_camera_try_fmt(struct soc_camera_device *icd,
552                               struct v4l2_format *f)
553 {
554         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
555         const struct soc_camera_format_xlate *xlate;
556         struct v4l2_pix_format *pix = &f->fmt.pix;
557         struct v4l2_subdev_pad_config pad_cfg;
558         struct v4l2_subdev_format format = {
559                 .which = V4L2_SUBDEV_FORMAT_TRY,
560         };
561         struct v4l2_mbus_framefmt *mf = &format.format;
562         u32 pixfmt = pix->pixelformat;
563         int ret;
564 
565         /* check with atmel-isi support format, if not support use YUYV */
566         if (!is_supported(icd, pix->pixelformat))
567                 pix->pixelformat = V4L2_PIX_FMT_YUYV;
568 
569         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
570         if (pixfmt && !xlate) {
571                 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
572                 return -EINVAL;
573         }
574 
575         /* limit to Atmel ISI hardware capabilities */
576         if (pix->height > MAX_SUPPORT_HEIGHT)
577                 pix->height = MAX_SUPPORT_HEIGHT;
578         if (pix->width > MAX_SUPPORT_WIDTH)
579                 pix->width = MAX_SUPPORT_WIDTH;
580 
581         /* limit to sensor capabilities */
582         mf->width       = pix->width;
583         mf->height      = pix->height;
584         mf->field       = pix->field;
585         mf->colorspace  = pix->colorspace;
586         mf->code        = xlate->code;
587 
588         ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format);
589         if (ret < 0)
590                 return ret;
591 
592         pix->width      = mf->width;
593         pix->height     = mf->height;
594         pix->colorspace = mf->colorspace;
595 
596         switch (mf->field) {
597         case V4L2_FIELD_ANY:
598                 pix->field = V4L2_FIELD_NONE;
599                 break;
600         case V4L2_FIELD_NONE:
601                 break;
602         default:
603                 dev_err(icd->parent, "Field type %d unsupported.\n",
604                         mf->field);
605                 ret = -EINVAL;
606         }
607 
608         return ret;
609 }
610 
611 static const struct soc_mbus_pixelfmt isi_camera_formats[] = {
612         {
613                 .fourcc                 = V4L2_PIX_FMT_YUYV,
614                 .name                   = "Packed YUV422 16 bit",
615                 .bits_per_sample        = 8,
616                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
617                 .order                  = SOC_MBUS_ORDER_LE,
618                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
619         },
620 };
621 
622 /* This will be corrected as we get more formats */
623 static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
624 {
625         return  fmt->packing == SOC_MBUS_PACKING_NONE ||
626                 (fmt->bits_per_sample == 8 &&
627                  fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
628                 (fmt->bits_per_sample > 8 &&
629                  fmt->packing == SOC_MBUS_PACKING_EXTEND16);
630 }
631 
632 #define ISI_BUS_PARAM (V4L2_MBUS_MASTER |       \
633                 V4L2_MBUS_HSYNC_ACTIVE_HIGH |   \
634                 V4L2_MBUS_HSYNC_ACTIVE_LOW |    \
635                 V4L2_MBUS_VSYNC_ACTIVE_HIGH |   \
636                 V4L2_MBUS_VSYNC_ACTIVE_LOW |    \
637                 V4L2_MBUS_PCLK_SAMPLE_RISING |  \
638                 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
639                 V4L2_MBUS_DATA_ACTIVE_HIGH)
640 
641 static int isi_camera_try_bus_param(struct soc_camera_device *icd,
642                                     unsigned char buswidth)
643 {
644         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
645         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
646         struct atmel_isi *isi = ici->priv;
647         struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
648         unsigned long common_flags;
649         int ret;
650 
651         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
652         if (!ret) {
653                 common_flags = soc_mbus_config_compatible(&cfg,
654                                                           ISI_BUS_PARAM);
655                 if (!common_flags) {
656                         dev_warn(icd->parent,
657                                  "Flags incompatible: camera 0x%x, host 0x%x\n",
658                                  cfg.flags, ISI_BUS_PARAM);
659                         return -EINVAL;
660                 }
661         } else if (ret != -ENOIOCTLCMD) {
662                 return ret;
663         }
664 
665         if ((1 << (buswidth - 1)) & isi->width_flags)
666                 return 0;
667         return -EINVAL;
668 }
669 
670 
671 static int isi_camera_get_formats(struct soc_camera_device *icd,
672                                   unsigned int idx,
673                                   struct soc_camera_format_xlate *xlate)
674 {
675         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
676         int formats = 0, ret;
677         /* sensor format */
678         struct v4l2_subdev_mbus_code_enum code = {
679                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
680                 .index = idx,
681         };
682         /* soc camera host format */
683         const struct soc_mbus_pixelfmt *fmt;
684 
685         ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
686         if (ret < 0)
687                 /* No more formats */
688                 return 0;
689 
690         fmt = soc_mbus_get_fmtdesc(code.code);
691         if (!fmt) {
692                 dev_err(icd->parent,
693                         "Invalid format code #%u: %d\n", idx, code.code);
694                 return 0;
695         }
696 
697         /* This also checks support for the requested bits-per-sample */
698         ret = isi_camera_try_bus_param(icd, fmt->bits_per_sample);
699         if (ret < 0) {
700                 dev_err(icd->parent,
701                         "Fail to try the bus parameters.\n");
702                 return 0;
703         }
704 
705         switch (code.code) {
706         case MEDIA_BUS_FMT_UYVY8_2X8:
707         case MEDIA_BUS_FMT_VYUY8_2X8:
708         case MEDIA_BUS_FMT_YUYV8_2X8:
709         case MEDIA_BUS_FMT_YVYU8_2X8:
710                 formats++;
711                 if (xlate) {
712                         xlate->host_fmt = &isi_camera_formats[0];
713                         xlate->code     = code.code;
714                         xlate++;
715                         dev_dbg(icd->parent, "Providing format %s using code %d\n",
716                                 isi_camera_formats[0].name, code.code);
717                 }
718                 break;
719         default:
720                 if (!isi_camera_packing_supported(fmt))
721                         return 0;
722                 if (xlate)
723                         dev_dbg(icd->parent,
724                                 "Providing format %s in pass-through mode\n",
725                                 fmt->name);
726         }
727 
728         /* Generic pass-through */
729         formats++;
730         if (xlate) {
731                 xlate->host_fmt = fmt;
732                 xlate->code     = code.code;
733                 xlate++;
734         }
735 
736         return formats;
737 }
738 
739 static int isi_camera_add_device(struct soc_camera_device *icd)
740 {
741         dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
742                  icd->devnum);
743 
744         return 0;
745 }
746 
747 static void isi_camera_remove_device(struct soc_camera_device *icd)
748 {
749         dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
750                  icd->devnum);
751 }
752 
753 static unsigned int isi_camera_poll(struct file *file, poll_table *pt)
754 {
755         struct soc_camera_device *icd = file->private_data;
756 
757         return vb2_poll(&icd->vb2_vidq, file, pt);
758 }
759 
760 static int isi_camera_querycap(struct soc_camera_host *ici,
761                                struct v4l2_capability *cap)
762 {
763         strcpy(cap->driver, "atmel-isi");
764         strcpy(cap->card, "Atmel Image Sensor Interface");
765         cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
766         cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
767 
768         return 0;
769 }
770 
771 static int isi_camera_set_bus_param(struct soc_camera_device *icd)
772 {
773         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
774         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
775         struct atmel_isi *isi = ici->priv;
776         struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
777         unsigned long common_flags;
778         int ret;
779         u32 cfg1 = 0;
780 
781         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
782         if (!ret) {
783                 common_flags = soc_mbus_config_compatible(&cfg,
784                                                           ISI_BUS_PARAM);
785                 if (!common_flags) {
786                         dev_warn(icd->parent,
787                                  "Flags incompatible: camera 0x%x, host 0x%x\n",
788                                  cfg.flags, ISI_BUS_PARAM);
789                         return -EINVAL;
790                 }
791         } else if (ret != -ENOIOCTLCMD) {
792                 return ret;
793         } else {
794                 common_flags = ISI_BUS_PARAM;
795         }
796         dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n",
797                 cfg.flags, ISI_BUS_PARAM, common_flags);
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 (isi->pdata.hsync_act_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 (isi->pdata.vsync_act_low)
811                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
812                 else
813                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
814         }
815 
816         if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
817             (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
818                 if (isi->pdata.pclk_act_falling)
819                         common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
820                 else
821                         common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
822         }
823 
824         cfg.flags = common_flags;
825         ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
826         if (ret < 0 && ret != -ENOIOCTLCMD) {
827                 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
828                         common_flags, ret);
829                 return ret;
830         }
831 
832         /* set bus param for ISI */
833         if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
834                 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
835         if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
836                 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
837         if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
838                 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
839 
840         dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix clock %s edge\n",
841                 common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
842                 common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
843                 common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising");
844 
845         if (isi->pdata.has_emb_sync)
846                 cfg1 |= ISI_CFG1_EMB_SYNC;
847         if (isi->pdata.full_mode)
848                 cfg1 |= ISI_CFG1_FULL_MODE;
849 
850         cfg1 |= ISI_CFG1_THMASK_BEATS_16;
851 
852         /* Enable PM and peripheral clock before operate isi registers */
853         pm_runtime_get_sync(ici->v4l2_dev.dev);
854 
855         isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
856         isi_writel(isi, ISI_CFG1, cfg1);
857 
858         pm_runtime_put(ici->v4l2_dev.dev);
859 
860         return 0;
861 }
862 
863 static struct soc_camera_host_ops isi_soc_camera_host_ops = {
864         .owner          = THIS_MODULE,
865         .add            = isi_camera_add_device,
866         .remove         = isi_camera_remove_device,
867         .set_fmt        = isi_camera_set_fmt,
868         .try_fmt        = isi_camera_try_fmt,
869         .get_formats    = isi_camera_get_formats,
870         .init_videobuf2 = isi_camera_init_videobuf,
871         .poll           = isi_camera_poll,
872         .querycap       = isi_camera_querycap,
873         .set_bus_param  = isi_camera_set_bus_param,
874 };
875 
876 /* -----------------------------------------------------------------------*/
877 static int atmel_isi_remove(struct platform_device *pdev)
878 {
879         struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
880         struct atmel_isi *isi = container_of(soc_host,
881                                         struct atmel_isi, soc_host);
882 
883         soc_camera_host_unregister(soc_host);
884         vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
885         dma_free_coherent(&pdev->dev,
886                         sizeof(struct fbd) * MAX_BUFFER_NUM,
887                         isi->p_fb_descriptors,
888                         isi->fb_descriptors_phys);
889         pm_runtime_disable(&pdev->dev);
890 
891         return 0;
892 }
893 
894 static int atmel_isi_parse_dt(struct atmel_isi *isi,
895                         struct platform_device *pdev)
896 {
897         struct device_node *np= pdev->dev.of_node;
898         struct v4l2_of_endpoint ep;
899         int err;
900 
901         /* Default settings for ISI */
902         isi->pdata.full_mode = 1;
903         isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
904 
905         np = of_graph_get_next_endpoint(np, NULL);
906         if (!np) {
907                 dev_err(&pdev->dev, "Could not find the endpoint\n");
908                 return -EINVAL;
909         }
910 
911         err = v4l2_of_parse_endpoint(np, &ep);
912         of_node_put(np);
913         if (err) {
914                 dev_err(&pdev->dev, "Could not parse the endpoint\n");
915                 return err;
916         }
917 
918         switch (ep.bus.parallel.bus_width) {
919         case 8:
920                 isi->pdata.data_width_flags = ISI_DATAWIDTH_8;
921                 break;
922         case 10:
923                 isi->pdata.data_width_flags =
924                                 ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10;
925                 break;
926         default:
927                 dev_err(&pdev->dev, "Unsupported bus width: %d\n",
928                                 ep.bus.parallel.bus_width);
929                 return -EINVAL;
930         }
931 
932         if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
933                 isi->pdata.hsync_act_low = true;
934         if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
935                 isi->pdata.vsync_act_low = true;
936         if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
937                 isi->pdata.pclk_act_falling = true;
938 
939         if (ep.bus_type == V4L2_MBUS_BT656)
940                 isi->pdata.has_emb_sync = true;
941 
942         return 0;
943 }
944 
945 static int atmel_isi_probe(struct platform_device *pdev)
946 {
947         unsigned int irq;
948         struct atmel_isi *isi;
949         struct resource *regs;
950         int ret, i;
951         struct soc_camera_host *soc_host;
952 
953         isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
954         if (!isi) {
955                 dev_err(&pdev->dev, "Can't allocate interface!\n");
956                 return -ENOMEM;
957         }
958 
959         isi->pclk = devm_clk_get(&pdev->dev, "isi_clk");
960         if (IS_ERR(isi->pclk))
961                 return PTR_ERR(isi->pclk);
962 
963         ret = atmel_isi_parse_dt(isi, pdev);
964         if (ret)
965                 return ret;
966 
967         isi->active = NULL;
968         spin_lock_init(&isi->lock);
969         INIT_LIST_HEAD(&isi->video_buffer_list);
970         INIT_LIST_HEAD(&isi->dma_desc_head);
971 
972         isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
973                                 sizeof(struct fbd) * MAX_BUFFER_NUM,
974                                 &isi->fb_descriptors_phys,
975                                 GFP_KERNEL);
976         if (!isi->p_fb_descriptors) {
977                 dev_err(&pdev->dev, "Can't allocate descriptors!\n");
978                 return -ENOMEM;
979         }
980 
981         for (i = 0; i < MAX_BUFFER_NUM; i++) {
982                 isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i;
983                 isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys +
984                                         i * sizeof(struct fbd);
985                 list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
986         }
987 
988         isi->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
989         if (IS_ERR(isi->alloc_ctx)) {
990                 ret = PTR_ERR(isi->alloc_ctx);
991                 goto err_alloc_ctx;
992         }
993 
994         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
995         isi->regs = devm_ioremap_resource(&pdev->dev, regs);
996         if (IS_ERR(isi->regs)) {
997                 ret = PTR_ERR(isi->regs);
998                 goto err_ioremap;
999         }
1000 
1001         if (isi->pdata.data_width_flags & ISI_DATAWIDTH_8)
1002                 isi->width_flags = 1 << 7;
1003         if (isi->pdata.data_width_flags & ISI_DATAWIDTH_10)
1004                 isi->width_flags |= 1 << 9;
1005 
1006         irq = platform_get_irq(pdev, 0);
1007         if (IS_ERR_VALUE(irq)) {
1008                 ret = irq;
1009                 goto err_req_irq;
1010         }
1011 
1012         ret = devm_request_irq(&pdev->dev, irq, isi_interrupt, 0, "isi", isi);
1013         if (ret) {
1014                 dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1015                 goto err_req_irq;
1016         }
1017         isi->irq = irq;
1018 
1019         soc_host                = &isi->soc_host;
1020         soc_host->drv_name      = "isi-camera";
1021         soc_host->ops           = &isi_soc_camera_host_ops;
1022         soc_host->priv          = isi;
1023         soc_host->v4l2_dev.dev  = &pdev->dev;
1024         soc_host->nr            = pdev->id;
1025 
1026         pm_suspend_ignore_children(&pdev->dev, true);
1027         pm_runtime_enable(&pdev->dev);
1028 
1029         ret = soc_camera_host_register(soc_host);
1030         if (ret) {
1031                 dev_err(&pdev->dev, "Unable to register soc camera host\n");
1032                 goto err_register_soc_camera_host;
1033         }
1034         return 0;
1035 
1036 err_register_soc_camera_host:
1037         pm_runtime_disable(&pdev->dev);
1038 err_req_irq:
1039 err_ioremap:
1040         vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
1041 err_alloc_ctx:
1042         dma_free_coherent(&pdev->dev,
1043                         sizeof(struct fbd) * MAX_BUFFER_NUM,
1044                         isi->p_fb_descriptors,
1045                         isi->fb_descriptors_phys);
1046 
1047         return ret;
1048 }
1049 
1050 #ifdef CONFIG_PM
1051 static int atmel_isi_runtime_suspend(struct device *dev)
1052 {
1053         struct soc_camera_host *soc_host = to_soc_camera_host(dev);
1054         struct atmel_isi *isi = container_of(soc_host,
1055                                         struct atmel_isi, soc_host);
1056 
1057         clk_disable_unprepare(isi->pclk);
1058 
1059         return 0;
1060 }
1061 static int atmel_isi_runtime_resume(struct device *dev)
1062 {
1063         struct soc_camera_host *soc_host = to_soc_camera_host(dev);
1064         struct atmel_isi *isi = container_of(soc_host,
1065                                         struct atmel_isi, soc_host);
1066 
1067         return clk_prepare_enable(isi->pclk);
1068 }
1069 #endif /* CONFIG_PM */
1070 
1071 static const struct dev_pm_ops atmel_isi_dev_pm_ops = {
1072         SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend,
1073                                 atmel_isi_runtime_resume, NULL)
1074 };
1075 
1076 static const struct of_device_id atmel_isi_of_match[] = {
1077         { .compatible = "atmel,at91sam9g45-isi" },
1078         { }
1079 };
1080 MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
1081 
1082 static struct platform_driver atmel_isi_driver = {
1083         .remove         = atmel_isi_remove,
1084         .driver         = {
1085                 .name = "atmel_isi",
1086                 .of_match_table = of_match_ptr(atmel_isi_of_match),
1087                 .pm     = &atmel_isi_dev_pm_ops,
1088         },
1089 };
1090 
1091 module_platform_driver_probe(atmel_isi_driver, atmel_isi_probe);
1092 
1093 MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1094 MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1095 MODULE_LICENSE("GPL");
1096 MODULE_SUPPORTED_DEVICE("video");
1097 

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