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