root/drivers/media/platform/atmel/atmel-isi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_dma_ctrl
  2. isi_writel
  3. isi_readl
  4. configure_geometry
  5. atmel_isi_handle_streaming
  6. isi_interrupt
  7. atmel_isi_wait_status
  8. queue_setup
  9. buffer_init
  10. buffer_prepare
  11. buffer_cleanup
  12. start_dma
  13. buffer_queue
  14. start_streaming
  15. stop_streaming
  16. isi_g_fmt_vid_cap
  17. find_format_by_fourcc
  18. isi_try_fmt
  19. isi_set_fmt
  20. isi_s_fmt_vid_cap
  21. isi_try_fmt_vid_cap
  22. isi_enum_fmt_vid_cap
  23. isi_querycap
  24. isi_enum_input
  25. isi_g_input
  26. isi_s_input
  27. isi_g_parm
  28. isi_s_parm
  29. isi_enum_framesizes
  30. isi_enum_frameintervals
  31. isi_camera_set_bus_param
  32. atmel_isi_parse_dt
  33. isi_open
  34. isi_release
  35. isi_set_default_fmt
  36. isi_formats_init
  37. isi_graph_notify_complete
  38. isi_graph_notify_unbind
  39. isi_graph_notify_bound
  40. isi_graph_parse
  41. isi_graph_init
  42. atmel_isi_probe
  43. atmel_isi_remove
  44. atmel_isi_runtime_suspend
  45. atmel_isi_runtime_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2011 Atmel Corporation
   4  * Josh Wu, <josh.wu@atmel.com>
   5  *
   6  * Based on previous work by Lars Haring, <lars.haring@atmel.com>
   7  * and Sedji Gaouaou
   8  * Based on the bttv driver for Bt848 with respective copyright holders
   9  */
  10 
  11 #include <linux/clk.h>
  12 #include <linux/completion.h>
  13 #include <linux/delay.h>
  14 #include <linux/fs.h>
  15 #include <linux/init.h>
  16 #include <linux/interrupt.h>
  17 #include <linux/kernel.h>
  18 #include <linux/module.h>
  19 #include <linux/of_graph.h>
  20 #include <linux/platform_device.h>
  21 #include <linux/pm_runtime.h>
  22 #include <linux/slab.h>
  23 #include <linux/of.h>
  24 
  25 #include <linux/videodev2.h>
  26 #include <media/v4l2-ctrls.h>
  27 #include <media/v4l2-device.h>
  28 #include <media/v4l2-dev.h>
  29 #include <media/v4l2-ioctl.h>
  30 #include <media/v4l2-event.h>
  31 #include <media/v4l2-fwnode.h>
  32 #include <media/videobuf2-dma-contig.h>
  33 #include <media/v4l2-image-sizes.h>
  34 
  35 #include "atmel-isi.h"
  36 
  37 #define MAX_SUPPORT_WIDTH               2048U
  38 #define MAX_SUPPORT_HEIGHT              2048U
  39 #define MIN_FRAME_RATE                  15
  40 #define FRAME_INTERVAL_MILLI_SEC        (1000 / MIN_FRAME_RATE)
  41 
  42 /* Frame buffer descriptor */
  43 struct fbd {
  44         /* Physical address of the frame buffer */
  45         u32 fb_address;
  46         /* DMA Control Register(only in HISI2) */
  47         u32 dma_ctrl;
  48         /* Physical address of the next fbd */
  49         u32 next_fbd_address;
  50 };
  51 
  52 static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl)
  53 {
  54         fb_desc->dma_ctrl = ctrl;
  55 }
  56 
  57 struct isi_dma_desc {
  58         struct list_head list;
  59         struct fbd *p_fbd;
  60         dma_addr_t fbd_phys;
  61 };
  62 
  63 /* Frame buffer data */
  64 struct frame_buffer {
  65         struct vb2_v4l2_buffer vb;
  66         struct isi_dma_desc *p_dma_desc;
  67         struct list_head list;
  68 };
  69 
  70 struct isi_graph_entity {
  71         struct device_node *node;
  72 
  73         struct v4l2_async_subdev asd;
  74         struct v4l2_subdev *subdev;
  75 };
  76 
  77 /*
  78  * struct isi_format - ISI media bus format information
  79  * @fourcc:             Fourcc code for this format
  80  * @mbus_code:          V4L2 media bus format code.
  81  * @bpp:                Bytes per pixel (when stored in memory)
  82  * @swap:               Byte swap configuration value
  83  * @support:            Indicates format supported by subdev
  84  * @skip:               Skip duplicate format supported by subdev
  85  */
  86 struct isi_format {
  87         u32     fourcc;
  88         u32     mbus_code;
  89         u8      bpp;
  90         u32     swap;
  91 };
  92 
  93 
  94 struct atmel_isi {
  95         /* Protects the access of variables shared with the ISR */
  96         spinlock_t                      irqlock;
  97         struct device                   *dev;
  98         void __iomem                    *regs;
  99 
 100         int                             sequence;
 101 
 102         /* Allocate descriptors for dma buffer use */
 103         struct fbd                      *p_fb_descriptors;
 104         dma_addr_t                      fb_descriptors_phys;
 105         struct                          list_head dma_desc_head;
 106         struct isi_dma_desc             dma_desc[VIDEO_MAX_FRAME];
 107         bool                            enable_preview_path;
 108 
 109         struct completion               complete;
 110         /* ISI peripheral clock */
 111         struct clk                      *pclk;
 112         unsigned int                    irq;
 113 
 114         struct isi_platform_data        pdata;
 115         u16                             width_flags;    /* max 12 bits */
 116 
 117         struct list_head                video_buffer_list;
 118         struct frame_buffer             *active;
 119 
 120         struct v4l2_device              v4l2_dev;
 121         struct video_device             *vdev;
 122         struct v4l2_async_notifier      notifier;
 123         struct isi_graph_entity         entity;
 124         struct v4l2_format              fmt;
 125 
 126         const struct isi_format         **user_formats;
 127         unsigned int                    num_user_formats;
 128         const struct isi_format         *current_fmt;
 129 
 130         struct mutex                    lock;
 131         struct vb2_queue                queue;
 132 };
 133 
 134 #define notifier_to_isi(n) container_of(n, struct atmel_isi, notifier)
 135 
 136 static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val)
 137 {
 138         writel(val, isi->regs + reg);
 139 }
 140 static u32 isi_readl(struct atmel_isi *isi, u32 reg)
 141 {
 142         return readl(isi->regs + reg);
 143 }
 144 
 145 static void configure_geometry(struct atmel_isi *isi)
 146 {
 147         u32 cfg2, psize;
 148         u32 fourcc = isi->current_fmt->fourcc;
 149 
 150         isi->enable_preview_path = fourcc == V4L2_PIX_FMT_RGB565 ||
 151                                    fourcc == V4L2_PIX_FMT_RGB32;
 152 
 153         /* According to sensor's output format to set cfg2 */
 154         cfg2 = isi->current_fmt->swap;
 155 
 156         isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
 157         /* Set width */
 158         cfg2 |= ((isi->fmt.fmt.pix.width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
 159                         ISI_CFG2_IM_HSIZE_MASK;
 160         /* Set height */
 161         cfg2 |= ((isi->fmt.fmt.pix.height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
 162                         & ISI_CFG2_IM_VSIZE_MASK;
 163         isi_writel(isi, ISI_CFG2, cfg2);
 164 
 165         /* No down sampling, preview size equal to sensor output size */
 166         psize = ((isi->fmt.fmt.pix.width - 1) << ISI_PSIZE_PREV_HSIZE_OFFSET) &
 167                 ISI_PSIZE_PREV_HSIZE_MASK;
 168         psize |= ((isi->fmt.fmt.pix.height - 1) << ISI_PSIZE_PREV_VSIZE_OFFSET) &
 169                 ISI_PSIZE_PREV_VSIZE_MASK;
 170         isi_writel(isi, ISI_PSIZE, psize);
 171         isi_writel(isi, ISI_PDECF, ISI_PDECF_NO_SAMPLING);
 172 }
 173 
 174 static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
 175 {
 176         if (isi->active) {
 177                 struct vb2_v4l2_buffer *vbuf = &isi->active->vb;
 178                 struct frame_buffer *buf = isi->active;
 179 
 180                 list_del_init(&buf->list);
 181                 vbuf->vb2_buf.timestamp = ktime_get_ns();
 182                 vbuf->sequence = isi->sequence++;
 183                 vbuf->field = V4L2_FIELD_NONE;
 184                 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
 185         }
 186 
 187         if (list_empty(&isi->video_buffer_list)) {
 188                 isi->active = NULL;
 189         } else {
 190                 /* start next dma frame. */
 191                 isi->active = list_entry(isi->video_buffer_list.next,
 192                                         struct frame_buffer, list);
 193                 if (!isi->enable_preview_path) {
 194                         isi_writel(isi, ISI_DMA_C_DSCR,
 195                                 (u32)isi->active->p_dma_desc->fbd_phys);
 196                         isi_writel(isi, ISI_DMA_C_CTRL,
 197                                 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
 198                         isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
 199                 } else {
 200                         isi_writel(isi, ISI_DMA_P_DSCR,
 201                                 (u32)isi->active->p_dma_desc->fbd_phys);
 202                         isi_writel(isi, ISI_DMA_P_CTRL,
 203                                 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
 204                         isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
 205                 }
 206         }
 207         return IRQ_HANDLED;
 208 }
 209 
 210 /* ISI interrupt service routine */
 211 static irqreturn_t isi_interrupt(int irq, void *dev_id)
 212 {
 213         struct atmel_isi *isi = dev_id;
 214         u32 status, mask, pending;
 215         irqreturn_t ret = IRQ_NONE;
 216 
 217         spin_lock(&isi->irqlock);
 218 
 219         status = isi_readl(isi, ISI_STATUS);
 220         mask = isi_readl(isi, ISI_INTMASK);
 221         pending = status & mask;
 222 
 223         if (pending & ISI_CTRL_SRST) {
 224                 complete(&isi->complete);
 225                 isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
 226                 ret = IRQ_HANDLED;
 227         } else if (pending & ISI_CTRL_DIS) {
 228                 complete(&isi->complete);
 229                 isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
 230                 ret = IRQ_HANDLED;
 231         } else {
 232                 if (likely(pending & ISI_SR_CXFR_DONE) ||
 233                                 likely(pending & ISI_SR_PXFR_DONE))
 234                         ret = atmel_isi_handle_streaming(isi);
 235         }
 236 
 237         spin_unlock(&isi->irqlock);
 238         return ret;
 239 }
 240 
 241 #define WAIT_ISI_RESET          1
 242 #define WAIT_ISI_DISABLE        0
 243 static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
 244 {
 245         unsigned long timeout;
 246         /*
 247          * The reset or disable will only succeed if we have a
 248          * pixel clock from the camera.
 249          */
 250         init_completion(&isi->complete);
 251 
 252         if (wait_reset) {
 253                 isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST);
 254                 isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST);
 255         } else {
 256                 isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS);
 257                 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
 258         }
 259 
 260         timeout = wait_for_completion_timeout(&isi->complete,
 261                         msecs_to_jiffies(500));
 262         if (timeout == 0)
 263                 return -ETIMEDOUT;
 264 
 265         return 0;
 266 }
 267 
 268 /* ------------------------------------------------------------------
 269         Videobuf operations
 270    ------------------------------------------------------------------*/
 271 static int queue_setup(struct vb2_queue *vq,
 272                                 unsigned int *nbuffers, unsigned int *nplanes,
 273                                 unsigned int sizes[], struct device *alloc_devs[])
 274 {
 275         struct atmel_isi *isi = vb2_get_drv_priv(vq);
 276         unsigned long size;
 277 
 278         size = isi->fmt.fmt.pix.sizeimage;
 279 
 280         /* Make sure the image size is large enough. */
 281         if (*nplanes)
 282                 return sizes[0] < size ? -EINVAL : 0;
 283 
 284         *nplanes = 1;
 285         sizes[0] = size;
 286 
 287         isi->active = NULL;
 288 
 289         dev_dbg(isi->dev, "%s, count=%d, size=%ld\n", __func__,
 290                 *nbuffers, size);
 291 
 292         return 0;
 293 }
 294 
 295 static int buffer_init(struct vb2_buffer *vb)
 296 {
 297         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 298         struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
 299 
 300         buf->p_dma_desc = NULL;
 301         INIT_LIST_HEAD(&buf->list);
 302 
 303         return 0;
 304 }
 305 
 306 static int buffer_prepare(struct vb2_buffer *vb)
 307 {
 308         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 309         struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
 310         struct atmel_isi *isi = vb2_get_drv_priv(vb->vb2_queue);
 311         unsigned long size;
 312         struct isi_dma_desc *desc;
 313 
 314         size = isi->fmt.fmt.pix.sizeimage;
 315 
 316         if (vb2_plane_size(vb, 0) < size) {
 317                 dev_err(isi->dev, "%s data will not fit into plane (%lu < %lu)\n",
 318                                 __func__, vb2_plane_size(vb, 0), size);
 319                 return -EINVAL;
 320         }
 321 
 322         vb2_set_plane_payload(vb, 0, size);
 323 
 324         if (!buf->p_dma_desc) {
 325                 if (list_empty(&isi->dma_desc_head)) {
 326                         dev_err(isi->dev, "Not enough dma descriptors.\n");
 327                         return -EINVAL;
 328                 } else {
 329                         /* Get an available descriptor */
 330                         desc = list_entry(isi->dma_desc_head.next,
 331                                                 struct isi_dma_desc, list);
 332                         /* Delete the descriptor since now it is used */
 333                         list_del_init(&desc->list);
 334 
 335                         /* Initialize the dma descriptor */
 336                         desc->p_fbd->fb_address =
 337                                         vb2_dma_contig_plane_dma_addr(vb, 0);
 338                         desc->p_fbd->next_fbd_address = 0;
 339                         set_dma_ctrl(desc->p_fbd, ISI_DMA_CTRL_WB);
 340 
 341                         buf->p_dma_desc = desc;
 342                 }
 343         }
 344         return 0;
 345 }
 346 
 347 static void buffer_cleanup(struct vb2_buffer *vb)
 348 {
 349         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 350         struct atmel_isi *isi = vb2_get_drv_priv(vb->vb2_queue);
 351         struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
 352 
 353         /* This descriptor is available now and we add to head list */
 354         if (buf->p_dma_desc)
 355                 list_add(&buf->p_dma_desc->list, &isi->dma_desc_head);
 356 }
 357 
 358 static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
 359 {
 360         u32 ctrl, cfg1;
 361 
 362         cfg1 = isi_readl(isi, ISI_CFG1);
 363         /* Enable irq: cxfr for the codec path, pxfr for the preview path */
 364         isi_writel(isi, ISI_INTEN,
 365                         ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
 366 
 367         /* Check if already in a frame */
 368         if (!isi->enable_preview_path) {
 369                 if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
 370                         dev_err(isi->dev, "Already in frame handling.\n");
 371                         return;
 372                 }
 373 
 374                 isi_writel(isi, ISI_DMA_C_DSCR,
 375                                 (u32)buffer->p_dma_desc->fbd_phys);
 376                 isi_writel(isi, ISI_DMA_C_CTRL,
 377                                 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
 378                 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
 379         } else {
 380                 isi_writel(isi, ISI_DMA_P_DSCR,
 381                                 (u32)buffer->p_dma_desc->fbd_phys);
 382                 isi_writel(isi, ISI_DMA_P_CTRL,
 383                                 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
 384                 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
 385         }
 386 
 387         cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
 388         /* Enable linked list */
 389         cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
 390 
 391         /* Enable ISI */
 392         ctrl = ISI_CTRL_EN;
 393 
 394         if (!isi->enable_preview_path)
 395                 ctrl |= ISI_CTRL_CDC;
 396 
 397         isi_writel(isi, ISI_CTRL, ctrl);
 398         isi_writel(isi, ISI_CFG1, cfg1);
 399 }
 400 
 401 static void buffer_queue(struct vb2_buffer *vb)
 402 {
 403         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 404         struct atmel_isi *isi = vb2_get_drv_priv(vb->vb2_queue);
 405         struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
 406         unsigned long flags = 0;
 407 
 408         spin_lock_irqsave(&isi->irqlock, flags);
 409         list_add_tail(&buf->list, &isi->video_buffer_list);
 410 
 411         if (!isi->active) {
 412                 isi->active = buf;
 413                 if (vb2_is_streaming(vb->vb2_queue))
 414                         start_dma(isi, buf);
 415         }
 416         spin_unlock_irqrestore(&isi->irqlock, flags);
 417 }
 418 
 419 static int start_streaming(struct vb2_queue *vq, unsigned int count)
 420 {
 421         struct atmel_isi *isi = vb2_get_drv_priv(vq);
 422         struct frame_buffer *buf, *node;
 423         int ret;
 424 
 425         pm_runtime_get_sync(isi->dev);
 426 
 427         /* Enable stream on the sub device */
 428         ret = v4l2_subdev_call(isi->entity.subdev, video, s_stream, 1);
 429         if (ret && ret != -ENOIOCTLCMD) {
 430                 dev_err(isi->dev, "stream on failed in subdev\n");
 431                 goto err_start_stream;
 432         }
 433 
 434         /* Reset ISI */
 435         ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
 436         if (ret < 0) {
 437                 dev_err(isi->dev, "Reset ISI timed out\n");
 438                 goto err_reset;
 439         }
 440         /* Disable all interrupts */
 441         isi_writel(isi, ISI_INTDIS, (u32)~0UL);
 442 
 443         isi->sequence = 0;
 444         configure_geometry(isi);
 445 
 446         spin_lock_irq(&isi->irqlock);
 447         /* Clear any pending interrupt */
 448         isi_readl(isi, ISI_STATUS);
 449 
 450         start_dma(isi, isi->active);
 451         spin_unlock_irq(&isi->irqlock);
 452 
 453         return 0;
 454 
 455 err_reset:
 456         v4l2_subdev_call(isi->entity.subdev, video, s_stream, 0);
 457 
 458 err_start_stream:
 459         pm_runtime_put(isi->dev);
 460 
 461         spin_lock_irq(&isi->irqlock);
 462         isi->active = NULL;
 463         /* Release all active buffers */
 464         list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
 465                 list_del_init(&buf->list);
 466                 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
 467         }
 468         spin_unlock_irq(&isi->irqlock);
 469 
 470         return ret;
 471 }
 472 
 473 /* abort streaming and wait for last buffer */
 474 static void stop_streaming(struct vb2_queue *vq)
 475 {
 476         struct atmel_isi *isi = vb2_get_drv_priv(vq);
 477         struct frame_buffer *buf, *node;
 478         int ret = 0;
 479         unsigned long timeout;
 480 
 481         /* Disable stream on the sub device */
 482         ret = v4l2_subdev_call(isi->entity.subdev, video, s_stream, 0);
 483         if (ret && ret != -ENOIOCTLCMD)
 484                 dev_err(isi->dev, "stream off failed in subdev\n");
 485 
 486         spin_lock_irq(&isi->irqlock);
 487         isi->active = NULL;
 488         /* Release all active buffers */
 489         list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
 490                 list_del_init(&buf->list);
 491                 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 492         }
 493         spin_unlock_irq(&isi->irqlock);
 494 
 495         if (!isi->enable_preview_path) {
 496                 timeout = jiffies + (FRAME_INTERVAL_MILLI_SEC * HZ) / 1000;
 497                 /* Wait until the end of the current frame. */
 498                 while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
 499                                 time_before(jiffies, timeout))
 500                         msleep(1);
 501 
 502                 if (time_after(jiffies, timeout))
 503                         dev_err(isi->dev,
 504                                 "Timeout waiting for finishing codec request\n");
 505         }
 506 
 507         /* Disable interrupts */
 508         isi_writel(isi, ISI_INTDIS,
 509                         ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
 510 
 511         /* Disable ISI and wait for it is done */
 512         ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE);
 513         if (ret < 0)
 514                 dev_err(isi->dev, "Disable ISI timed out\n");
 515 
 516         pm_runtime_put(isi->dev);
 517 }
 518 
 519 static const struct vb2_ops isi_video_qops = {
 520         .queue_setup            = queue_setup,
 521         .buf_init               = buffer_init,
 522         .buf_prepare            = buffer_prepare,
 523         .buf_cleanup            = buffer_cleanup,
 524         .buf_queue              = buffer_queue,
 525         .start_streaming        = start_streaming,
 526         .stop_streaming         = stop_streaming,
 527         .wait_prepare           = vb2_ops_wait_prepare,
 528         .wait_finish            = vb2_ops_wait_finish,
 529 };
 530 
 531 static int isi_g_fmt_vid_cap(struct file *file, void *priv,
 532                               struct v4l2_format *fmt)
 533 {
 534         struct atmel_isi *isi = video_drvdata(file);
 535 
 536         *fmt = isi->fmt;
 537 
 538         return 0;
 539 }
 540 
 541 static const struct isi_format *find_format_by_fourcc(struct atmel_isi *isi,
 542                                                       unsigned int fourcc)
 543 {
 544         unsigned int num_formats = isi->num_user_formats;
 545         const struct isi_format *fmt;
 546         unsigned int i;
 547 
 548         for (i = 0; i < num_formats; i++) {
 549                 fmt = isi->user_formats[i];
 550                 if (fmt->fourcc == fourcc)
 551                         return fmt;
 552         }
 553 
 554         return NULL;
 555 }
 556 
 557 static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f,
 558                        const struct isi_format **current_fmt)
 559 {
 560         const struct isi_format *isi_fmt;
 561         struct v4l2_pix_format *pixfmt = &f->fmt.pix;
 562         struct v4l2_subdev_pad_config pad_cfg;
 563         struct v4l2_subdev_format format = {
 564                 .which = V4L2_SUBDEV_FORMAT_TRY,
 565         };
 566         int ret;
 567 
 568         isi_fmt = find_format_by_fourcc(isi, pixfmt->pixelformat);
 569         if (!isi_fmt) {
 570                 isi_fmt = isi->user_formats[isi->num_user_formats - 1];
 571                 pixfmt->pixelformat = isi_fmt->fourcc;
 572         }
 573 
 574         /* Limit to Atmel ISI hardware capabilities */
 575         pixfmt->width = clamp(pixfmt->width, 0U, MAX_SUPPORT_WIDTH);
 576         pixfmt->height = clamp(pixfmt->height, 0U, MAX_SUPPORT_HEIGHT);
 577 
 578         v4l2_fill_mbus_format(&format.format, pixfmt, isi_fmt->mbus_code);
 579         ret = v4l2_subdev_call(isi->entity.subdev, pad, set_fmt,
 580                                &pad_cfg, &format);
 581         if (ret < 0)
 582                 return ret;
 583 
 584         v4l2_fill_pix_format(pixfmt, &format.format);
 585 
 586         pixfmt->field = V4L2_FIELD_NONE;
 587         pixfmt->bytesperline = pixfmt->width * isi_fmt->bpp;
 588         pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
 589 
 590         if (current_fmt)
 591                 *current_fmt = isi_fmt;
 592 
 593         return 0;
 594 }
 595 
 596 static int isi_set_fmt(struct atmel_isi *isi, struct v4l2_format *f)
 597 {
 598         struct v4l2_subdev_format format = {
 599                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
 600         };
 601         const struct isi_format *current_fmt;
 602         int ret;
 603 
 604         ret = isi_try_fmt(isi, f, &current_fmt);
 605         if (ret)
 606                 return ret;
 607 
 608         v4l2_fill_mbus_format(&format.format, &f->fmt.pix,
 609                               current_fmt->mbus_code);
 610         ret = v4l2_subdev_call(isi->entity.subdev, pad,
 611                                set_fmt, NULL, &format);
 612         if (ret < 0)
 613                 return ret;
 614 
 615         isi->fmt = *f;
 616         isi->current_fmt = current_fmt;
 617 
 618         return 0;
 619 }
 620 
 621 static int isi_s_fmt_vid_cap(struct file *file, void *priv,
 622                               struct v4l2_format *f)
 623 {
 624         struct atmel_isi *isi = video_drvdata(file);
 625 
 626         if (vb2_is_streaming(&isi->queue))
 627                 return -EBUSY;
 628 
 629         return isi_set_fmt(isi, f);
 630 }
 631 
 632 static int isi_try_fmt_vid_cap(struct file *file, void *priv,
 633                                 struct v4l2_format *f)
 634 {
 635         struct atmel_isi *isi = video_drvdata(file);
 636 
 637         return isi_try_fmt(isi, f, NULL);
 638 }
 639 
 640 static int isi_enum_fmt_vid_cap(struct file *file, void  *priv,
 641                                 struct v4l2_fmtdesc *f)
 642 {
 643         struct atmel_isi *isi = video_drvdata(file);
 644 
 645         if (f->index >= isi->num_user_formats)
 646                 return -EINVAL;
 647 
 648         f->pixelformat = isi->user_formats[f->index]->fourcc;
 649         return 0;
 650 }
 651 
 652 static int isi_querycap(struct file *file, void *priv,
 653                         struct v4l2_capability *cap)
 654 {
 655         strscpy(cap->driver, "atmel-isi", sizeof(cap->driver));
 656         strscpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card));
 657         strscpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info));
 658         return 0;
 659 }
 660 
 661 static int isi_enum_input(struct file *file, void *priv,
 662                            struct v4l2_input *i)
 663 {
 664         if (i->index != 0)
 665                 return -EINVAL;
 666 
 667         i->type = V4L2_INPUT_TYPE_CAMERA;
 668         strscpy(i->name, "Camera", sizeof(i->name));
 669         return 0;
 670 }
 671 
 672 static int isi_g_input(struct file *file, void *priv, unsigned int *i)
 673 {
 674         *i = 0;
 675         return 0;
 676 }
 677 
 678 static int isi_s_input(struct file *file, void *priv, unsigned int i)
 679 {
 680         if (i > 0)
 681                 return -EINVAL;
 682         return 0;
 683 }
 684 
 685 static int isi_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
 686 {
 687         struct atmel_isi *isi = video_drvdata(file);
 688 
 689         return v4l2_g_parm_cap(video_devdata(file), isi->entity.subdev, a);
 690 }
 691 
 692 static int isi_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
 693 {
 694         struct atmel_isi *isi = video_drvdata(file);
 695 
 696         return v4l2_s_parm_cap(video_devdata(file), isi->entity.subdev, a);
 697 }
 698 
 699 static int isi_enum_framesizes(struct file *file, void *fh,
 700                                struct v4l2_frmsizeenum *fsize)
 701 {
 702         struct atmel_isi *isi = video_drvdata(file);
 703         const struct isi_format *isi_fmt;
 704         struct v4l2_subdev_frame_size_enum fse = {
 705                 .index = fsize->index,
 706                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
 707         };
 708         int ret;
 709 
 710         isi_fmt = find_format_by_fourcc(isi, fsize->pixel_format);
 711         if (!isi_fmt)
 712                 return -EINVAL;
 713 
 714         fse.code = isi_fmt->mbus_code;
 715 
 716         ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size,
 717                                NULL, &fse);
 718         if (ret)
 719                 return ret;
 720 
 721         fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
 722         fsize->discrete.width = fse.max_width;
 723         fsize->discrete.height = fse.max_height;
 724 
 725         return 0;
 726 }
 727 
 728 static int isi_enum_frameintervals(struct file *file, void *fh,
 729                                     struct v4l2_frmivalenum *fival)
 730 {
 731         struct atmel_isi *isi = video_drvdata(file);
 732         const struct isi_format *isi_fmt;
 733         struct v4l2_subdev_frame_interval_enum fie = {
 734                 .index = fival->index,
 735                 .width = fival->width,
 736                 .height = fival->height,
 737                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
 738         };
 739         int ret;
 740 
 741         isi_fmt = find_format_by_fourcc(isi, fival->pixel_format);
 742         if (!isi_fmt)
 743                 return -EINVAL;
 744 
 745         fie.code = isi_fmt->mbus_code;
 746 
 747         ret = v4l2_subdev_call(isi->entity.subdev, pad,
 748                                enum_frame_interval, NULL, &fie);
 749         if (ret)
 750                 return ret;
 751 
 752         fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
 753         fival->discrete = fie.interval;
 754 
 755         return 0;
 756 }
 757 
 758 static void isi_camera_set_bus_param(struct atmel_isi *isi)
 759 {
 760         u32 cfg1 = 0;
 761 
 762         /* set bus param for ISI */
 763         if (isi->pdata.hsync_act_low)
 764                 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
 765         if (isi->pdata.vsync_act_low)
 766                 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
 767         if (isi->pdata.pclk_act_falling)
 768                 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
 769         if (isi->pdata.has_emb_sync)
 770                 cfg1 |= ISI_CFG1_EMB_SYNC;
 771         if (isi->pdata.full_mode)
 772                 cfg1 |= ISI_CFG1_FULL_MODE;
 773 
 774         cfg1 |= ISI_CFG1_THMASK_BEATS_16;
 775 
 776         /* Enable PM and peripheral clock before operate isi registers */
 777         pm_runtime_get_sync(isi->dev);
 778 
 779         isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
 780         isi_writel(isi, ISI_CFG1, cfg1);
 781 
 782         pm_runtime_put(isi->dev);
 783 }
 784 
 785 /* -----------------------------------------------------------------------*/
 786 static int atmel_isi_parse_dt(struct atmel_isi *isi,
 787                         struct platform_device *pdev)
 788 {
 789         struct device_node *np = pdev->dev.of_node;
 790         struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
 791         int err;
 792 
 793         /* Default settings for ISI */
 794         isi->pdata.full_mode = 1;
 795         isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
 796 
 797         np = of_graph_get_next_endpoint(np, NULL);
 798         if (!np) {
 799                 dev_err(&pdev->dev, "Could not find the endpoint\n");
 800                 return -EINVAL;
 801         }
 802 
 803         err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
 804         of_node_put(np);
 805         if (err) {
 806                 dev_err(&pdev->dev, "Could not parse the endpoint\n");
 807                 return err;
 808         }
 809 
 810         switch (ep.bus.parallel.bus_width) {
 811         case 8:
 812                 isi->pdata.data_width_flags = ISI_DATAWIDTH_8;
 813                 break;
 814         case 10:
 815                 isi->pdata.data_width_flags =
 816                                 ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10;
 817                 break;
 818         default:
 819                 dev_err(&pdev->dev, "Unsupported bus width: %d\n",
 820                                 ep.bus.parallel.bus_width);
 821                 return -EINVAL;
 822         }
 823 
 824         if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
 825                 isi->pdata.hsync_act_low = true;
 826         if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
 827                 isi->pdata.vsync_act_low = true;
 828         if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
 829                 isi->pdata.pclk_act_falling = true;
 830 
 831         if (ep.bus_type == V4L2_MBUS_BT656)
 832                 isi->pdata.has_emb_sync = true;
 833 
 834         return 0;
 835 }
 836 
 837 static int isi_open(struct file *file)
 838 {
 839         struct atmel_isi *isi = video_drvdata(file);
 840         struct v4l2_subdev *sd = isi->entity.subdev;
 841         int ret;
 842 
 843         if (mutex_lock_interruptible(&isi->lock))
 844                 return -ERESTARTSYS;
 845 
 846         ret = v4l2_fh_open(file);
 847         if (ret < 0)
 848                 goto unlock;
 849 
 850         if (!v4l2_fh_is_singular_file(file))
 851                 goto fh_rel;
 852 
 853         ret = v4l2_subdev_call(sd, core, s_power, 1);
 854         if (ret < 0 && ret != -ENOIOCTLCMD)
 855                 goto fh_rel;
 856 
 857         ret = isi_set_fmt(isi, &isi->fmt);
 858         if (ret)
 859                 v4l2_subdev_call(sd, core, s_power, 0);
 860 fh_rel:
 861         if (ret)
 862                 v4l2_fh_release(file);
 863 unlock:
 864         mutex_unlock(&isi->lock);
 865         return ret;
 866 }
 867 
 868 static int isi_release(struct file *file)
 869 {
 870         struct atmel_isi *isi = video_drvdata(file);
 871         struct v4l2_subdev *sd = isi->entity.subdev;
 872         bool fh_singular;
 873         int ret;
 874 
 875         mutex_lock(&isi->lock);
 876 
 877         fh_singular = v4l2_fh_is_singular_file(file);
 878 
 879         ret = _vb2_fop_release(file, NULL);
 880 
 881         if (fh_singular)
 882                 v4l2_subdev_call(sd, core, s_power, 0);
 883 
 884         mutex_unlock(&isi->lock);
 885 
 886         return ret;
 887 }
 888 
 889 static const struct v4l2_ioctl_ops isi_ioctl_ops = {
 890         .vidioc_querycap                = isi_querycap,
 891 
 892         .vidioc_try_fmt_vid_cap         = isi_try_fmt_vid_cap,
 893         .vidioc_g_fmt_vid_cap           = isi_g_fmt_vid_cap,
 894         .vidioc_s_fmt_vid_cap           = isi_s_fmt_vid_cap,
 895         .vidioc_enum_fmt_vid_cap        = isi_enum_fmt_vid_cap,
 896 
 897         .vidioc_enum_input              = isi_enum_input,
 898         .vidioc_g_input                 = isi_g_input,
 899         .vidioc_s_input                 = isi_s_input,
 900 
 901         .vidioc_g_parm                  = isi_g_parm,
 902         .vidioc_s_parm                  = isi_s_parm,
 903         .vidioc_enum_framesizes         = isi_enum_framesizes,
 904         .vidioc_enum_frameintervals     = isi_enum_frameintervals,
 905 
 906         .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
 907         .vidioc_create_bufs             = vb2_ioctl_create_bufs,
 908         .vidioc_querybuf                = vb2_ioctl_querybuf,
 909         .vidioc_qbuf                    = vb2_ioctl_qbuf,
 910         .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
 911         .vidioc_expbuf                  = vb2_ioctl_expbuf,
 912         .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
 913         .vidioc_streamon                = vb2_ioctl_streamon,
 914         .vidioc_streamoff               = vb2_ioctl_streamoff,
 915 
 916         .vidioc_log_status              = v4l2_ctrl_log_status,
 917         .vidioc_subscribe_event         = v4l2_ctrl_subscribe_event,
 918         .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
 919 };
 920 
 921 static const struct v4l2_file_operations isi_fops = {
 922         .owner          = THIS_MODULE,
 923         .unlocked_ioctl = video_ioctl2,
 924         .open           = isi_open,
 925         .release        = isi_release,
 926         .poll           = vb2_fop_poll,
 927         .mmap           = vb2_fop_mmap,
 928         .read           = vb2_fop_read,
 929 };
 930 
 931 static int isi_set_default_fmt(struct atmel_isi *isi)
 932 {
 933         struct v4l2_format f = {
 934                 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
 935                 .fmt.pix = {
 936                         .width          = VGA_WIDTH,
 937                         .height         = VGA_HEIGHT,
 938                         .field          = V4L2_FIELD_NONE,
 939                         .pixelformat    = isi->user_formats[0]->fourcc,
 940                 },
 941         };
 942         int ret;
 943 
 944         ret = isi_try_fmt(isi, &f, NULL);
 945         if (ret)
 946                 return ret;
 947         isi->current_fmt = isi->user_formats[0];
 948         isi->fmt = f;
 949         return 0;
 950 }
 951 
 952 static const struct isi_format isi_formats[] = {
 953         {
 954                 .fourcc = V4L2_PIX_FMT_YUYV,
 955                 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
 956                 .bpp = 2,
 957                 .swap = ISI_CFG2_YCC_SWAP_DEFAULT,
 958         }, {
 959                 .fourcc = V4L2_PIX_FMT_YUYV,
 960                 .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
 961                 .bpp = 2,
 962                 .swap = ISI_CFG2_YCC_SWAP_MODE_1,
 963         }, {
 964                 .fourcc = V4L2_PIX_FMT_YUYV,
 965                 .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
 966                 .bpp = 2,
 967                 .swap = ISI_CFG2_YCC_SWAP_MODE_2,
 968         }, {
 969                 .fourcc = V4L2_PIX_FMT_YUYV,
 970                 .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
 971                 .bpp = 2,
 972                 .swap = ISI_CFG2_YCC_SWAP_MODE_3,
 973         }, {
 974                 .fourcc = V4L2_PIX_FMT_RGB565,
 975                 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
 976                 .bpp = 2,
 977                 .swap = ISI_CFG2_YCC_SWAP_MODE_2,
 978         }, {
 979                 .fourcc = V4L2_PIX_FMT_RGB565,
 980                 .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
 981                 .bpp = 2,
 982                 .swap = ISI_CFG2_YCC_SWAP_MODE_3,
 983         }, {
 984                 .fourcc = V4L2_PIX_FMT_RGB565,
 985                 .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
 986                 .bpp = 2,
 987                 .swap = ISI_CFG2_YCC_SWAP_DEFAULT,
 988         }, {
 989                 .fourcc = V4L2_PIX_FMT_RGB565,
 990                 .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
 991                 .bpp = 2,
 992                 .swap = ISI_CFG2_YCC_SWAP_MODE_1,
 993         },
 994 };
 995 
 996 static int isi_formats_init(struct atmel_isi *isi)
 997 {
 998         const struct isi_format *isi_fmts[ARRAY_SIZE(isi_formats)];
 999         unsigned int num_fmts = 0, i, j;
1000         struct v4l2_subdev *subdev = isi->entity.subdev;
1001         struct v4l2_subdev_mbus_code_enum mbus_code = {
1002                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1003         };
1004 
1005         while (!v4l2_subdev_call(subdev, pad, enum_mbus_code,
1006                                  NULL, &mbus_code)) {
1007                 for (i = 0; i < ARRAY_SIZE(isi_formats); i++) {
1008                         if (isi_formats[i].mbus_code != mbus_code.code)
1009                                 continue;
1010 
1011                         /* Code supported, have we got this fourcc yet? */
1012                         for (j = 0; j < num_fmts; j++)
1013                                 if (isi_fmts[j]->fourcc == isi_formats[i].fourcc)
1014                                         /* Already available */
1015                                         break;
1016                         if (j == num_fmts)
1017                                 /* new */
1018                                 isi_fmts[num_fmts++] = isi_formats + i;
1019                 }
1020                 mbus_code.index++;
1021         }
1022 
1023         if (!num_fmts)
1024                 return -ENXIO;
1025 
1026         isi->num_user_formats = num_fmts;
1027         isi->user_formats = devm_kcalloc(isi->dev,
1028                                          num_fmts, sizeof(struct isi_format *),
1029                                          GFP_KERNEL);
1030         if (!isi->user_formats)
1031                 return -ENOMEM;
1032 
1033         memcpy(isi->user_formats, isi_fmts,
1034                num_fmts * sizeof(struct isi_format *));
1035         isi->current_fmt = isi->user_formats[0];
1036 
1037         return 0;
1038 }
1039 
1040 static int isi_graph_notify_complete(struct v4l2_async_notifier *notifier)
1041 {
1042         struct atmel_isi *isi = notifier_to_isi(notifier);
1043         int ret;
1044 
1045         isi->vdev->ctrl_handler = isi->entity.subdev->ctrl_handler;
1046         ret = isi_formats_init(isi);
1047         if (ret) {
1048                 dev_err(isi->dev, "No supported mediabus format found\n");
1049                 return ret;
1050         }
1051         isi_camera_set_bus_param(isi);
1052 
1053         ret = isi_set_default_fmt(isi);
1054         if (ret) {
1055                 dev_err(isi->dev, "Could not set default format\n");
1056                 return ret;
1057         }
1058 
1059         ret = video_register_device(isi->vdev, VFL_TYPE_GRABBER, -1);
1060         if (ret) {
1061                 dev_err(isi->dev, "Failed to register video device\n");
1062                 return ret;
1063         }
1064 
1065         dev_dbg(isi->dev, "Device registered as %s\n",
1066                 video_device_node_name(isi->vdev));
1067         return 0;
1068 }
1069 
1070 static void isi_graph_notify_unbind(struct v4l2_async_notifier *notifier,
1071                                      struct v4l2_subdev *sd,
1072                                      struct v4l2_async_subdev *asd)
1073 {
1074         struct atmel_isi *isi = notifier_to_isi(notifier);
1075 
1076         dev_dbg(isi->dev, "Removing %s\n", video_device_node_name(isi->vdev));
1077 
1078         /* Checks internally if vdev have been init or not */
1079         video_unregister_device(isi->vdev);
1080 }
1081 
1082 static int isi_graph_notify_bound(struct v4l2_async_notifier *notifier,
1083                                    struct v4l2_subdev *subdev,
1084                                    struct v4l2_async_subdev *asd)
1085 {
1086         struct atmel_isi *isi = notifier_to_isi(notifier);
1087 
1088         dev_dbg(isi->dev, "subdev %s bound\n", subdev->name);
1089 
1090         isi->entity.subdev = subdev;
1091 
1092         return 0;
1093 }
1094 
1095 static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
1096         .bound = isi_graph_notify_bound,
1097         .unbind = isi_graph_notify_unbind,
1098         .complete = isi_graph_notify_complete,
1099 };
1100 
1101 static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
1102 {
1103         struct device_node *ep = NULL;
1104         struct device_node *remote;
1105 
1106         ep = of_graph_get_next_endpoint(node, ep);
1107         if (!ep)
1108                 return -EINVAL;
1109 
1110         remote = of_graph_get_remote_port_parent(ep);
1111         of_node_put(ep);
1112         if (!remote)
1113                 return -EINVAL;
1114 
1115         /* Remote node to connect */
1116         isi->entity.node = remote;
1117         isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
1118         isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
1119         return 0;
1120 }
1121 
1122 static int isi_graph_init(struct atmel_isi *isi)
1123 {
1124         int ret;
1125 
1126         /* Parse the graph to extract a list of subdevice DT nodes. */
1127         ret = isi_graph_parse(isi, isi->dev->of_node);
1128         if (ret < 0) {
1129                 dev_err(isi->dev, "Graph parsing failed\n");
1130                 return ret;
1131         }
1132 
1133         v4l2_async_notifier_init(&isi->notifier);
1134 
1135         ret = v4l2_async_notifier_add_subdev(&isi->notifier, &isi->entity.asd);
1136         if (ret) {
1137                 of_node_put(isi->entity.node);
1138                 return ret;
1139         }
1140 
1141         isi->notifier.ops = &isi_graph_notify_ops;
1142 
1143         ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier);
1144         if (ret < 0) {
1145                 dev_err(isi->dev, "Notifier registration failed\n");
1146                 v4l2_async_notifier_cleanup(&isi->notifier);
1147                 return ret;
1148         }
1149 
1150         return 0;
1151 }
1152 
1153 
1154 static int atmel_isi_probe(struct platform_device *pdev)
1155 {
1156         int irq;
1157         struct atmel_isi *isi;
1158         struct vb2_queue *q;
1159         struct resource *regs;
1160         int ret, i;
1161 
1162         isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
1163         if (!isi)
1164                 return -ENOMEM;
1165 
1166         isi->pclk = devm_clk_get(&pdev->dev, "isi_clk");
1167         if (IS_ERR(isi->pclk))
1168                 return PTR_ERR(isi->pclk);
1169 
1170         ret = atmel_isi_parse_dt(isi, pdev);
1171         if (ret)
1172                 return ret;
1173 
1174         isi->active = NULL;
1175         isi->dev = &pdev->dev;
1176         mutex_init(&isi->lock);
1177         spin_lock_init(&isi->irqlock);
1178         INIT_LIST_HEAD(&isi->video_buffer_list);
1179         INIT_LIST_HEAD(&isi->dma_desc_head);
1180 
1181         q = &isi->queue;
1182 
1183         /* Initialize the top-level structure */
1184         ret = v4l2_device_register(&pdev->dev, &isi->v4l2_dev);
1185         if (ret)
1186                 return ret;
1187 
1188         isi->vdev = video_device_alloc();
1189         if (!isi->vdev) {
1190                 ret = -ENOMEM;
1191                 goto err_vdev_alloc;
1192         }
1193 
1194         /* video node */
1195         isi->vdev->fops = &isi_fops;
1196         isi->vdev->v4l2_dev = &isi->v4l2_dev;
1197         isi->vdev->queue = &isi->queue;
1198         strscpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name));
1199         isi->vdev->release = video_device_release;
1200         isi->vdev->ioctl_ops = &isi_ioctl_ops;
1201         isi->vdev->lock = &isi->lock;
1202         isi->vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1203                 V4L2_CAP_READWRITE;
1204         video_set_drvdata(isi->vdev, isi);
1205 
1206         /* buffer queue */
1207         q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1208         q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
1209         q->lock = &isi->lock;
1210         q->drv_priv = isi;
1211         q->buf_struct_size = sizeof(struct frame_buffer);
1212         q->ops = &isi_video_qops;
1213         q->mem_ops = &vb2_dma_contig_memops;
1214         q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1215         q->min_buffers_needed = 2;
1216         q->dev = &pdev->dev;
1217 
1218         ret = vb2_queue_init(q);
1219         if (ret < 0) {
1220                 dev_err(&pdev->dev, "failed to initialize VB2 queue\n");
1221                 goto err_vb2_queue;
1222         }
1223         isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
1224                                 sizeof(struct fbd) * VIDEO_MAX_FRAME,
1225                                 &isi->fb_descriptors_phys,
1226                                 GFP_KERNEL);
1227         if (!isi->p_fb_descriptors) {
1228                 dev_err(&pdev->dev, "Can't allocate descriptors!\n");
1229                 ret = -ENOMEM;
1230                 goto err_dma_alloc;
1231         }
1232 
1233         for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1234                 isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i;
1235                 isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys +
1236                                         i * sizeof(struct fbd);
1237                 list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
1238         }
1239 
1240         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1241         isi->regs = devm_ioremap_resource(&pdev->dev, regs);
1242         if (IS_ERR(isi->regs)) {
1243                 ret = PTR_ERR(isi->regs);
1244                 goto err_ioremap;
1245         }
1246 
1247         if (isi->pdata.data_width_flags & ISI_DATAWIDTH_8)
1248                 isi->width_flags = 1 << 7;
1249         if (isi->pdata.data_width_flags & ISI_DATAWIDTH_10)
1250                 isi->width_flags |= 1 << 9;
1251 
1252         irq = platform_get_irq(pdev, 0);
1253         if (irq < 0) {
1254                 ret = irq;
1255                 goto err_req_irq;
1256         }
1257 
1258         ret = devm_request_irq(&pdev->dev, irq, isi_interrupt, 0, "isi", isi);
1259         if (ret) {
1260                 dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1261                 goto err_req_irq;
1262         }
1263         isi->irq = irq;
1264 
1265         ret = isi_graph_init(isi);
1266         if (ret < 0)
1267                 goto err_req_irq;
1268 
1269         pm_suspend_ignore_children(&pdev->dev, true);
1270         pm_runtime_enable(&pdev->dev);
1271         platform_set_drvdata(pdev, isi);
1272         return 0;
1273 
1274 err_req_irq:
1275 err_ioremap:
1276         dma_free_coherent(&pdev->dev,
1277                         sizeof(struct fbd) * VIDEO_MAX_FRAME,
1278                         isi->p_fb_descriptors,
1279                         isi->fb_descriptors_phys);
1280 err_dma_alloc:
1281 err_vb2_queue:
1282         video_device_release(isi->vdev);
1283 err_vdev_alloc:
1284         v4l2_device_unregister(&isi->v4l2_dev);
1285 
1286         return ret;
1287 }
1288 
1289 static int atmel_isi_remove(struct platform_device *pdev)
1290 {
1291         struct atmel_isi *isi = platform_get_drvdata(pdev);
1292 
1293         dma_free_coherent(&pdev->dev,
1294                         sizeof(struct fbd) * VIDEO_MAX_FRAME,
1295                         isi->p_fb_descriptors,
1296                         isi->fb_descriptors_phys);
1297         pm_runtime_disable(&pdev->dev);
1298         v4l2_async_notifier_unregister(&isi->notifier);
1299         v4l2_async_notifier_cleanup(&isi->notifier);
1300         v4l2_device_unregister(&isi->v4l2_dev);
1301 
1302         return 0;
1303 }
1304 
1305 #ifdef CONFIG_PM
1306 static int atmel_isi_runtime_suspend(struct device *dev)
1307 {
1308         struct atmel_isi *isi = dev_get_drvdata(dev);
1309 
1310         clk_disable_unprepare(isi->pclk);
1311 
1312         return 0;
1313 }
1314 static int atmel_isi_runtime_resume(struct device *dev)
1315 {
1316         struct atmel_isi *isi = dev_get_drvdata(dev);
1317 
1318         return clk_prepare_enable(isi->pclk);
1319 }
1320 #endif /* CONFIG_PM */
1321 
1322 static const struct dev_pm_ops atmel_isi_dev_pm_ops = {
1323         SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend,
1324                                 atmel_isi_runtime_resume, NULL)
1325 };
1326 
1327 static const struct of_device_id atmel_isi_of_match[] = {
1328         { .compatible = "atmel,at91sam9g45-isi" },
1329         { }
1330 };
1331 MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
1332 
1333 static struct platform_driver atmel_isi_driver = {
1334         .driver         = {
1335                 .name = "atmel_isi",
1336                 .of_match_table = of_match_ptr(atmel_isi_of_match),
1337                 .pm     = &atmel_isi_dev_pm_ops,
1338         },
1339         .probe          = atmel_isi_probe,
1340         .remove         = atmel_isi_remove,
1341 };
1342 
1343 module_platform_driver(atmel_isi_driver);
1344 
1345 MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1346 MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1347 MODULE_LICENSE("GPL");
1348 MODULE_SUPPORTED_DEVICE("video");

/* [<][>][^][v][top][bottom][index][help] */