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