linux/drivers/media/platform/soc_camera/mx3_camera.c
<<
>>
Prefs
   1/*
   2 * V4L2 Driver for i.MX3x camera host
   3 *
   4 * Copyright (C) 2008
   5 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/module.h>
  14#include <linux/videodev2.h>
  15#include <linux/platform_device.h>
  16#include <linux/clk.h>
  17#include <linux/vmalloc.h>
  18#include <linux/interrupt.h>
  19#include <linux/sched.h>
  20#include <linux/dma/ipu-dma.h>
  21
  22#include <media/v4l2-common.h>
  23#include <media/v4l2-dev.h>
  24#include <media/videobuf2-dma-contig.h>
  25#include <media/soc_camera.h>
  26#include <media/soc_mediabus.h>
  27
  28#include <linux/platform_data/camera-mx3.h>
  29#include <linux/platform_data/dma-imx.h>
  30
  31#define MX3_CAM_DRV_NAME "mx3-camera"
  32
  33/* CMOS Sensor Interface Registers */
  34#define CSI_REG_START           0x60
  35
  36#define CSI_SENS_CONF           (0x60 - CSI_REG_START)
  37#define CSI_SENS_FRM_SIZE       (0x64 - CSI_REG_START)
  38#define CSI_ACT_FRM_SIZE        (0x68 - CSI_REG_START)
  39#define CSI_OUT_FRM_CTRL        (0x6C - CSI_REG_START)
  40#define CSI_TST_CTRL            (0x70 - CSI_REG_START)
  41#define CSI_CCIR_CODE_1         (0x74 - CSI_REG_START)
  42#define CSI_CCIR_CODE_2         (0x78 - CSI_REG_START)
  43#define CSI_CCIR_CODE_3         (0x7C - CSI_REG_START)
  44#define CSI_FLASH_STROBE_1      (0x80 - CSI_REG_START)
  45#define CSI_FLASH_STROBE_2      (0x84 - CSI_REG_START)
  46
  47#define CSI_SENS_CONF_VSYNC_POL_SHIFT           0
  48#define CSI_SENS_CONF_HSYNC_POL_SHIFT           1
  49#define CSI_SENS_CONF_DATA_POL_SHIFT            2
  50#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT         3
  51#define CSI_SENS_CONF_SENS_PRTCL_SHIFT          4
  52#define CSI_SENS_CONF_SENS_CLKSRC_SHIFT         7
  53#define CSI_SENS_CONF_DATA_FMT_SHIFT            8
  54#define CSI_SENS_CONF_DATA_WIDTH_SHIFT          10
  55#define CSI_SENS_CONF_EXT_VSYNC_SHIFT           15
  56#define CSI_SENS_CONF_DIVRATIO_SHIFT            16
  57
  58#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444       (0UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
  59#define CSI_SENS_CONF_DATA_FMT_YUV422           (2UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
  60#define CSI_SENS_CONF_DATA_FMT_BAYER            (3UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
  61
  62#define MAX_VIDEO_MEM 16
  63
  64struct mx3_camera_buffer {
  65        /* common v4l buffer stuff -- must be first */
  66        struct vb2_buffer                       vb;
  67        struct list_head                        queue;
  68
  69        /* One descriptot per scatterlist (per frame) */
  70        struct dma_async_tx_descriptor          *txd;
  71
  72        /* We have to "build" a scatterlist ourselves - one element per frame */
  73        struct scatterlist                      sg;
  74};
  75
  76/**
  77 * struct mx3_camera_dev - i.MX3x camera (CSI) object
  78 * @dev:                camera device, to which the coherent buffer is attached
  79 * @icd:                currently attached camera sensor
  80 * @clk:                pointer to clock
  81 * @base:               remapped register base address
  82 * @pdata:              platform data
  83 * @platform_flags:     platform flags
  84 * @mclk:               master clock frequency in Hz
  85 * @capture:            list of capture videobuffers
  86 * @lock:               protects video buffer lists
  87 * @active:             active video buffer
  88 * @idmac_channel:      array of pointers to IPU DMAC DMA channels
  89 * @soc_host:           embedded soc_host object
  90 */
  91struct mx3_camera_dev {
  92        /*
  93         * i.MX3x is only supposed to handle one camera on its Camera Sensor
  94         * Interface. If anyone ever builds hardware to enable more than one
  95         * camera _simultaneously_, they will have to modify this driver too
  96         */
  97        struct soc_camera_device *icd;
  98        struct clk              *clk;
  99
 100        void __iomem            *base;
 101
 102        struct mx3_camera_pdata *pdata;
 103
 104        unsigned long           platform_flags;
 105        unsigned long           mclk;
 106        u16                     width_flags;    /* max 15 bits */
 107
 108        struct list_head        capture;
 109        spinlock_t              lock;           /* Protects video buffer lists */
 110        struct mx3_camera_buffer *active;
 111        size_t                  buf_total;
 112        struct vb2_alloc_ctx    *alloc_ctx;
 113        enum v4l2_field         field;
 114        int                     sequence;
 115
 116        /* IDMAC / dmaengine interface */
 117        struct idmac_channel    *idmac_channel[1];      /* We need one channel */
 118
 119        struct soc_camera_host  soc_host;
 120};
 121
 122struct dma_chan_request {
 123        struct mx3_camera_dev   *mx3_cam;
 124        enum ipu_channel        id;
 125};
 126
 127static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg)
 128{
 129        return __raw_readl(mx3->base + reg);
 130}
 131
 132static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
 133{
 134        __raw_writel(value, mx3->base + reg);
 135}
 136
 137static struct mx3_camera_buffer *to_mx3_vb(struct vb2_buffer *vb)
 138{
 139        return container_of(vb, struct mx3_camera_buffer, vb);
 140}
 141
 142/* Called from the IPU IDMAC ISR */
 143static void mx3_cam_dma_done(void *arg)
 144{
 145        struct idmac_tx_desc *desc = to_tx_desc(arg);
 146        struct dma_chan *chan = desc->txd.chan;
 147        struct idmac_channel *ichannel = to_idmac_chan(chan);
 148        struct mx3_camera_dev *mx3_cam = ichannel->client;
 149
 150        dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
 151                desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
 152
 153        spin_lock(&mx3_cam->lock);
 154        if (mx3_cam->active) {
 155                struct vb2_buffer *vb = &mx3_cam->active->vb;
 156                struct mx3_camera_buffer *buf = to_mx3_vb(vb);
 157
 158                list_del_init(&buf->queue);
 159                v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
 160                vb->v4l2_buf.field = mx3_cam->field;
 161                vb->v4l2_buf.sequence = mx3_cam->sequence++;
 162                vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
 163        }
 164
 165        if (list_empty(&mx3_cam->capture)) {
 166                mx3_cam->active = NULL;
 167                spin_unlock(&mx3_cam->lock);
 168
 169                /*
 170                 * stop capture - without further buffers IPU_CHA_BUF0_RDY will
 171                 * not get updated
 172                 */
 173                return;
 174        }
 175
 176        mx3_cam->active = list_entry(mx3_cam->capture.next,
 177                                     struct mx3_camera_buffer, queue);
 178        spin_unlock(&mx3_cam->lock);
 179}
 180
 181/*
 182 * Videobuf operations
 183 */
 184
 185/*
 186 * Calculate the __buffer__ (not data) size and number of buffers.
 187 */
 188static int mx3_videobuf_setup(struct vb2_queue *vq,
 189                        const struct v4l2_format *fmt,
 190                        unsigned int *count, unsigned int *num_planes,
 191                        unsigned int sizes[], void *alloc_ctxs[])
 192{
 193        struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
 194        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 195        struct mx3_camera_dev *mx3_cam = ici->priv;
 196
 197        if (!mx3_cam->idmac_channel[0])
 198                return -EINVAL;
 199
 200        if (fmt) {
 201                const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
 202                                                                fmt->fmt.pix.pixelformat);
 203                unsigned int bytes_per_line;
 204                int ret;
 205
 206                if (!xlate)
 207                        return -EINVAL;
 208
 209                ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
 210                                              xlate->host_fmt);
 211                if (ret < 0)
 212                        return ret;
 213
 214                bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
 215
 216                ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
 217                                          fmt->fmt.pix.height);
 218                if (ret < 0)
 219                        return ret;
 220
 221                sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
 222        } else {
 223                /* Called from VIDIOC_REQBUFS or in compatibility mode */
 224                sizes[0] = icd->sizeimage;
 225        }
 226
 227        alloc_ctxs[0] = mx3_cam->alloc_ctx;
 228
 229        if (!vq->num_buffers)
 230                mx3_cam->sequence = 0;
 231
 232        if (!*count)
 233                *count = 2;
 234
 235        /* If *num_planes != 0, we have already verified *count. */
 236        if (!*num_planes &&
 237            sizes[0] * *count + mx3_cam->buf_total > MAX_VIDEO_MEM * 1024 * 1024)
 238                *count = (MAX_VIDEO_MEM * 1024 * 1024 - mx3_cam->buf_total) /
 239                        sizes[0];
 240
 241        *num_planes = 1;
 242
 243        return 0;
 244}
 245
 246static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
 247{
 248        /* Add more formats as need arises and test possibilities appear... */
 249        switch (fourcc) {
 250        case V4L2_PIX_FMT_RGB24:
 251                return IPU_PIX_FMT_RGB24;
 252        case V4L2_PIX_FMT_UYVY:
 253        case V4L2_PIX_FMT_RGB565:
 254        default:
 255                return IPU_PIX_FMT_GENERIC;
 256        }
 257}
 258
 259static void mx3_videobuf_queue(struct vb2_buffer *vb)
 260{
 261        struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
 262        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 263        struct mx3_camera_dev *mx3_cam = ici->priv;
 264        struct mx3_camera_buffer *buf = to_mx3_vb(vb);
 265        struct scatterlist *sg = &buf->sg;
 266        struct dma_async_tx_descriptor *txd;
 267        struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
 268        struct idmac_video_param *video = &ichan->params.video;
 269        const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt;
 270        unsigned long flags;
 271        dma_cookie_t cookie;
 272        size_t new_size;
 273
 274        new_size = icd->sizeimage;
 275
 276        if (vb2_plane_size(vb, 0) < new_size) {
 277                dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
 278                        vb->v4l2_buf.index, vb2_plane_size(vb, 0), new_size);
 279                goto error;
 280        }
 281
 282        if (!buf->txd) {
 283                sg_dma_address(sg)      = vb2_dma_contig_plane_dma_addr(vb, 0);
 284                sg_dma_len(sg)          = new_size;
 285
 286                txd = dmaengine_prep_slave_sg(
 287                        &ichan->dma_chan, sg, 1, DMA_DEV_TO_MEM,
 288                        DMA_PREP_INTERRUPT);
 289                if (!txd)
 290                        goto error;
 291
 292                txd->callback_param     = txd;
 293                txd->callback           = mx3_cam_dma_done;
 294
 295                buf->txd                = txd;
 296        } else {
 297                txd = buf->txd;
 298        }
 299
 300        vb2_set_plane_payload(vb, 0, new_size);
 301
 302        /* This is the configuration of one sg-element */
 303        video->out_pixel_fmt = fourcc_to_ipu_pix(host_fmt->fourcc);
 304
 305        if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
 306                /*
 307                 * If the IPU DMA channel is configured to transfer generic
 308                 * 8-bit data, we have to set up the geometry parameters
 309                 * correctly, according to the current pixel format. The DMA
 310                 * horizontal parameters in this case are expressed in bytes,
 311                 * not in pixels.
 312                 */
 313                video->out_width        = icd->bytesperline;
 314                video->out_height       = icd->user_height;
 315                video->out_stride       = icd->bytesperline;
 316        } else {
 317                /*
 318                 * For IPU known formats the pixel unit will be managed
 319                 * successfully by the IPU code
 320                 */
 321                video->out_width        = icd->user_width;
 322                video->out_height       = icd->user_height;
 323                video->out_stride       = icd->user_width;
 324        }
 325
 326#ifdef DEBUG
 327        /* helps to see what DMA actually has written */
 328        if (vb2_plane_vaddr(vb, 0))
 329                memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
 330#endif
 331
 332        spin_lock_irqsave(&mx3_cam->lock, flags);
 333        list_add_tail(&buf->queue, &mx3_cam->capture);
 334
 335        if (!mx3_cam->active)
 336                mx3_cam->active = buf;
 337
 338        spin_unlock_irq(&mx3_cam->lock);
 339
 340        cookie = txd->tx_submit(txd);
 341        dev_dbg(icd->parent, "Submitted cookie %d DMA 0x%08x\n",
 342                cookie, sg_dma_address(&buf->sg));
 343
 344        if (cookie >= 0)
 345                return;
 346
 347        spin_lock_irq(&mx3_cam->lock);
 348
 349        /* Submit error */
 350        list_del_init(&buf->queue);
 351
 352        if (mx3_cam->active == buf)
 353                mx3_cam->active = NULL;
 354
 355        spin_unlock_irqrestore(&mx3_cam->lock, flags);
 356error:
 357        vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
 358}
 359
 360static void mx3_videobuf_release(struct vb2_buffer *vb)
 361{
 362        struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
 363        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 364        struct mx3_camera_dev *mx3_cam = ici->priv;
 365        struct mx3_camera_buffer *buf = to_mx3_vb(vb);
 366        struct dma_async_tx_descriptor *txd = buf->txd;
 367        unsigned long flags;
 368
 369        dev_dbg(icd->parent,
 370                "Release%s DMA 0x%08x, queue %sempty\n",
 371                mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
 372                list_empty(&buf->queue) ? "" : "not ");
 373
 374        spin_lock_irqsave(&mx3_cam->lock, flags);
 375
 376        if (mx3_cam->active == buf)
 377                mx3_cam->active = NULL;
 378
 379        /* Doesn't hurt also if the list is empty */
 380        list_del_init(&buf->queue);
 381
 382        if (txd) {
 383                buf->txd = NULL;
 384                if (mx3_cam->idmac_channel[0])
 385                        async_tx_ack(txd);
 386        }
 387
 388        spin_unlock_irqrestore(&mx3_cam->lock, flags);
 389
 390        mx3_cam->buf_total -= vb2_plane_size(vb, 0);
 391}
 392
 393static int mx3_videobuf_init(struct vb2_buffer *vb)
 394{
 395        struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
 396        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 397        struct mx3_camera_dev *mx3_cam = ici->priv;
 398        struct mx3_camera_buffer *buf = to_mx3_vb(vb);
 399
 400        if (!buf->txd) {
 401                /* This is for locking debugging only */
 402                INIT_LIST_HEAD(&buf->queue);
 403                sg_init_table(&buf->sg, 1);
 404
 405                mx3_cam->buf_total += vb2_plane_size(vb, 0);
 406        }
 407
 408        return 0;
 409}
 410
 411static int mx3_stop_streaming(struct vb2_queue *q)
 412{
 413        struct soc_camera_device *icd = soc_camera_from_vb2q(q);
 414        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 415        struct mx3_camera_dev *mx3_cam = ici->priv;
 416        struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
 417        struct mx3_camera_buffer *buf, *tmp;
 418        unsigned long flags;
 419
 420        if (ichan) {
 421                struct dma_chan *chan = &ichan->dma_chan;
 422                chan->device->device_control(chan, DMA_PAUSE, 0);
 423        }
 424
 425        spin_lock_irqsave(&mx3_cam->lock, flags);
 426
 427        mx3_cam->active = NULL;
 428
 429        list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
 430                list_del_init(&buf->queue);
 431                vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
 432        }
 433
 434        spin_unlock_irqrestore(&mx3_cam->lock, flags);
 435
 436        return 0;
 437}
 438
 439static struct vb2_ops mx3_videobuf_ops = {
 440        .queue_setup    = mx3_videobuf_setup,
 441        .buf_queue      = mx3_videobuf_queue,
 442        .buf_cleanup    = mx3_videobuf_release,
 443        .buf_init       = mx3_videobuf_init,
 444        .wait_prepare   = soc_camera_unlock,
 445        .wait_finish    = soc_camera_lock,
 446        .stop_streaming = mx3_stop_streaming,
 447};
 448
 449static int mx3_camera_init_videobuf(struct vb2_queue *q,
 450                                     struct soc_camera_device *icd)
 451{
 452        q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 453        q->io_modes = VB2_MMAP | VB2_USERPTR;
 454        q->drv_priv = icd;
 455        q->ops = &mx3_videobuf_ops;
 456        q->mem_ops = &vb2_dma_contig_memops;
 457        q->buf_struct_size = sizeof(struct mx3_camera_buffer);
 458
 459        return vb2_queue_init(q);
 460}
 461
 462/* First part of ipu_csi_init_interface() */
 463static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
 464                                struct soc_camera_device *icd)
 465{
 466        u32 conf;
 467        long rate;
 468
 469        /* Set default size: ipu_csi_set_window_size() */
 470        csi_reg_write(mx3_cam, (640 - 1) | ((480 - 1) << 16), CSI_ACT_FRM_SIZE);
 471        /* ...and position to 0:0: ipu_csi_set_window_pos() */
 472        conf = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
 473        csi_reg_write(mx3_cam, conf, CSI_OUT_FRM_CTRL);
 474
 475        /* We use only gated clock synchronisation mode so far */
 476        conf = 0 << CSI_SENS_CONF_SENS_PRTCL_SHIFT;
 477
 478        /* Set generic data, platform-biggest bus-width */
 479        conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
 480
 481        if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
 482                conf |= 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
 483        else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
 484                conf |= 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
 485        else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
 486                conf |= 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
 487        else/* if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)*/
 488                conf |= 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
 489
 490        if (mx3_cam->platform_flags & MX3_CAMERA_CLK_SRC)
 491                conf |= 1 << CSI_SENS_CONF_SENS_CLKSRC_SHIFT;
 492        if (mx3_cam->platform_flags & MX3_CAMERA_EXT_VSYNC)
 493                conf |= 1 << CSI_SENS_CONF_EXT_VSYNC_SHIFT;
 494        if (mx3_cam->platform_flags & MX3_CAMERA_DP)
 495                conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
 496        if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
 497                conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
 498        if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
 499                conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
 500        if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
 501                conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
 502
 503        /* ipu_csi_init_interface() */
 504        csi_reg_write(mx3_cam, conf, CSI_SENS_CONF);
 505
 506        clk_prepare_enable(mx3_cam->clk);
 507        rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
 508        dev_dbg(icd->parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
 509        if (rate)
 510                clk_set_rate(mx3_cam->clk, rate);
 511}
 512
 513/* Called with .host_lock held */
 514static int mx3_camera_add_device(struct soc_camera_device *icd)
 515{
 516        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 517        struct mx3_camera_dev *mx3_cam = ici->priv;
 518
 519        if (mx3_cam->icd)
 520                return -EBUSY;
 521
 522        mx3_camera_activate(mx3_cam, icd);
 523
 524        mx3_cam->buf_total = 0;
 525        mx3_cam->icd = icd;
 526
 527        dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
 528                 icd->devnum);
 529
 530        return 0;
 531}
 532
 533/* Called with .host_lock held */
 534static void mx3_camera_remove_device(struct soc_camera_device *icd)
 535{
 536        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 537        struct mx3_camera_dev *mx3_cam = ici->priv;
 538        struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
 539
 540        BUG_ON(icd != mx3_cam->icd);
 541
 542        if (*ichan) {
 543                dma_release_channel(&(*ichan)->dma_chan);
 544                *ichan = NULL;
 545        }
 546
 547        clk_disable_unprepare(mx3_cam->clk);
 548
 549        mx3_cam->icd = NULL;
 550
 551        dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
 552                 icd->devnum);
 553}
 554
 555static int test_platform_param(struct mx3_camera_dev *mx3_cam,
 556                               unsigned char buswidth, unsigned long *flags)
 557{
 558        /*
 559         * If requested data width is supported by the platform, use it or any
 560         * possible lower value - i.MX31 is smart enough to shift bits
 561         */
 562        if (buswidth > fls(mx3_cam->width_flags))
 563                return -EINVAL;
 564
 565        /*
 566         * Platform specified synchronization and pixel clock polarities are
 567         * only a recommendation and are only used during probing. MX3x
 568         * camera interface only works in master mode, i.e., uses HSYNC and
 569         * VSYNC signals from the sensor
 570         */
 571        *flags = V4L2_MBUS_MASTER |
 572                V4L2_MBUS_HSYNC_ACTIVE_HIGH |
 573                V4L2_MBUS_HSYNC_ACTIVE_LOW |
 574                V4L2_MBUS_VSYNC_ACTIVE_HIGH |
 575                V4L2_MBUS_VSYNC_ACTIVE_LOW |
 576                V4L2_MBUS_PCLK_SAMPLE_RISING |
 577                V4L2_MBUS_PCLK_SAMPLE_FALLING |
 578                V4L2_MBUS_DATA_ACTIVE_HIGH |
 579                V4L2_MBUS_DATA_ACTIVE_LOW;
 580
 581        return 0;
 582}
 583
 584static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
 585                                    const unsigned int depth)
 586{
 587        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 588        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 589        struct mx3_camera_dev *mx3_cam = ici->priv;
 590        struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
 591        unsigned long bus_flags, common_flags;
 592        int ret = test_platform_param(mx3_cam, depth, &bus_flags);
 593
 594        dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret);
 595
 596        if (ret < 0)
 597                return ret;
 598
 599        ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
 600        if (!ret) {
 601                common_flags = soc_mbus_config_compatible(&cfg,
 602                                                          bus_flags);
 603                if (!common_flags) {
 604                        dev_warn(icd->parent,
 605                                 "Flags incompatible: camera 0x%x, host 0x%lx\n",
 606                                 cfg.flags, bus_flags);
 607                        return -EINVAL;
 608                }
 609        } else if (ret != -ENOIOCTLCMD) {
 610                return ret;
 611        }
 612
 613        return 0;
 614}
 615
 616static bool chan_filter(struct dma_chan *chan, void *arg)
 617{
 618        struct dma_chan_request *rq = arg;
 619        struct mx3_camera_pdata *pdata;
 620
 621        if (!imx_dma_is_ipu(chan))
 622                return false;
 623
 624        if (!rq)
 625                return false;
 626
 627        pdata = rq->mx3_cam->soc_host.v4l2_dev.dev->platform_data;
 628
 629        return rq->id == chan->chan_id &&
 630                pdata->dma_dev == chan->device->dev;
 631}
 632
 633static const struct soc_mbus_pixelfmt mx3_camera_formats[] = {
 634        {
 635                .fourcc                 = V4L2_PIX_FMT_SBGGR8,
 636                .name                   = "Bayer BGGR (sRGB) 8 bit",
 637                .bits_per_sample        = 8,
 638                .packing                = SOC_MBUS_PACKING_NONE,
 639                .order                  = SOC_MBUS_ORDER_LE,
 640                .layout                 = SOC_MBUS_LAYOUT_PACKED,
 641        }, {
 642                .fourcc                 = V4L2_PIX_FMT_GREY,
 643                .name                   = "Monochrome 8 bit",
 644                .bits_per_sample        = 8,
 645                .packing                = SOC_MBUS_PACKING_NONE,
 646                .order                  = SOC_MBUS_ORDER_LE,
 647                .layout                 = SOC_MBUS_LAYOUT_PACKED,
 648        },
 649};
 650
 651/* This will be corrected as we get more formats */
 652static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
 653{
 654        return  fmt->packing == SOC_MBUS_PACKING_NONE ||
 655                (fmt->bits_per_sample == 8 &&
 656                 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
 657                (fmt->bits_per_sample > 8 &&
 658                 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
 659}
 660
 661static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
 662                                  struct soc_camera_format_xlate *xlate)
 663{
 664        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 665        struct device *dev = icd->parent;
 666        int formats = 0, ret;
 667        enum v4l2_mbus_pixelcode code;
 668        const struct soc_mbus_pixelfmt *fmt;
 669
 670        ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
 671        if (ret < 0)
 672                /* No more formats */
 673                return 0;
 674
 675        fmt = soc_mbus_get_fmtdesc(code);
 676        if (!fmt) {
 677                dev_warn(icd->parent,
 678                         "Unsupported format code #%u: %d\n", idx, code);
 679                return 0;
 680        }
 681
 682        /* This also checks support for the requested bits-per-sample */
 683        ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample);
 684        if (ret < 0)
 685                return 0;
 686
 687        switch (code) {
 688        case V4L2_MBUS_FMT_SBGGR10_1X10:
 689                formats++;
 690                if (xlate) {
 691                        xlate->host_fmt = &mx3_camera_formats[0];
 692                        xlate->code     = code;
 693                        xlate++;
 694                        dev_dbg(dev, "Providing format %s using code %d\n",
 695                                mx3_camera_formats[0].name, code);
 696                }
 697                break;
 698        case V4L2_MBUS_FMT_Y10_1X10:
 699                formats++;
 700                if (xlate) {
 701                        xlate->host_fmt = &mx3_camera_formats[1];
 702                        xlate->code     = code;
 703                        xlate++;
 704                        dev_dbg(dev, "Providing format %s using code %d\n",
 705                                mx3_camera_formats[1].name, code);
 706                }
 707                break;
 708        default:
 709                if (!mx3_camera_packing_supported(fmt))
 710                        return 0;
 711        }
 712
 713        /* Generic pass-through */
 714        formats++;
 715        if (xlate) {
 716                xlate->host_fmt = fmt;
 717                xlate->code     = code;
 718                dev_dbg(dev, "Providing format %c%c%c%c in pass-through mode\n",
 719                        (fmt->fourcc >> (0*8)) & 0xFF,
 720                        (fmt->fourcc >> (1*8)) & 0xFF,
 721                        (fmt->fourcc >> (2*8)) & 0xFF,
 722                        (fmt->fourcc >> (3*8)) & 0xFF);
 723                xlate++;
 724        }
 725
 726        return formats;
 727}
 728
 729static void configure_geometry(struct mx3_camera_dev *mx3_cam,
 730                               unsigned int width, unsigned int height,
 731                               const struct soc_mbus_pixelfmt *fmt)
 732{
 733        u32 ctrl, width_field, height_field;
 734
 735        if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
 736                /*
 737                 * As the CSI will be configured to output BAYER, here
 738                 * the width parameter count the number of samples to
 739                 * capture to complete the whole image width.
 740                 */
 741                unsigned int num, den;
 742                int ret = soc_mbus_samples_per_pixel(fmt, &num, &den);
 743                BUG_ON(ret < 0);
 744                width = width * num / den;
 745        }
 746
 747        /* Setup frame size - this cannot be changed on-the-fly... */
 748        width_field = width - 1;
 749        height_field = height - 1;
 750        csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
 751
 752        csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
 753        csi_reg_write(mx3_cam, (height_field << 16) | 0x22, CSI_FLASH_STROBE_2);
 754
 755        csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_ACT_FRM_SIZE);
 756
 757        /* ...and position */
 758        ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
 759        /* Sensor does the cropping */
 760        csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
 761}
 762
 763static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
 764{
 765        dma_cap_mask_t mask;
 766        struct dma_chan *chan;
 767        struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
 768        /* We have to use IDMAC_IC_7 for Bayer / generic data */
 769        struct dma_chan_request rq = {.mx3_cam = mx3_cam,
 770                                      .id = IDMAC_IC_7};
 771
 772        dma_cap_zero(mask);
 773        dma_cap_set(DMA_SLAVE, mask);
 774        dma_cap_set(DMA_PRIVATE, mask);
 775        chan = dma_request_channel(mask, chan_filter, &rq);
 776        if (!chan)
 777                return -EBUSY;
 778
 779        *ichan = to_idmac_chan(chan);
 780        (*ichan)->client = mx3_cam;
 781
 782        return 0;
 783}
 784
 785/*
 786 * FIXME: learn to use stride != width, then we can keep stride properly aligned
 787 * and support arbitrary (even) widths.
 788 */
 789static inline void stride_align(__u32 *width)
 790{
 791        if (ALIGN(*width, 8) < 4096)
 792                *width = ALIGN(*width, 8);
 793        else
 794                *width = *width &  ~7;
 795}
 796
 797/*
 798 * As long as we don't implement host-side cropping and scaling, we can use
 799 * default g_crop and cropcap from soc_camera.c
 800 */
 801static int mx3_camera_set_crop(struct soc_camera_device *icd,
 802                               const struct v4l2_crop *a)
 803{
 804        struct v4l2_crop a_writable = *a;
 805        struct v4l2_rect *rect = &a_writable.c;
 806        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 807        struct mx3_camera_dev *mx3_cam = ici->priv;
 808        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 809        struct v4l2_mbus_framefmt mf;
 810        int ret;
 811
 812        soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
 813        soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
 814
 815        ret = v4l2_subdev_call(sd, video, s_crop, a);
 816        if (ret < 0)
 817                return ret;
 818
 819        /* The capture device might have changed its output sizes */
 820        ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
 821        if (ret < 0)
 822                return ret;
 823
 824        if (mf.code != icd->current_fmt->code)
 825                return -EINVAL;
 826
 827        if (mf.width & 7) {
 828                /* Ouch! We can only handle 8-byte aligned width... */
 829                stride_align(&mf.width);
 830                ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
 831                if (ret < 0)
 832                        return ret;
 833        }
 834
 835        if (mf.width != icd->user_width || mf.height != icd->user_height)
 836                configure_geometry(mx3_cam, mf.width, mf.height,
 837                                   icd->current_fmt->host_fmt);
 838
 839        dev_dbg(icd->parent, "Sensor cropped %dx%d\n",
 840                mf.width, mf.height);
 841
 842        icd->user_width         = mf.width;
 843        icd->user_height        = mf.height;
 844
 845        return ret;
 846}
 847
 848static int mx3_camera_set_fmt(struct soc_camera_device *icd,
 849                              struct v4l2_format *f)
 850{
 851        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 852        struct mx3_camera_dev *mx3_cam = ici->priv;
 853        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 854        const struct soc_camera_format_xlate *xlate;
 855        struct v4l2_pix_format *pix = &f->fmt.pix;
 856        struct v4l2_mbus_framefmt mf;
 857        int ret;
 858
 859        xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
 860        if (!xlate) {
 861                dev_warn(icd->parent, "Format %x not found\n",
 862                         pix->pixelformat);
 863                return -EINVAL;
 864        }
 865
 866        stride_align(&pix->width);
 867        dev_dbg(icd->parent, "Set format %dx%d\n", pix->width, pix->height);
 868
 869        /*
 870         * Might have to perform a complete interface initialisation like in
 871         * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
 872         * mxc_v4l2_s_fmt()
 873         */
 874
 875        configure_geometry(mx3_cam, pix->width, pix->height, xlate->host_fmt);
 876
 877        mf.width        = pix->width;
 878        mf.height       = pix->height;
 879        mf.field        = pix->field;
 880        mf.colorspace   = pix->colorspace;
 881        mf.code         = xlate->code;
 882
 883        ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
 884        if (ret < 0)
 885                return ret;
 886
 887        if (mf.code != xlate->code)
 888                return -EINVAL;
 889
 890        if (!mx3_cam->idmac_channel[0]) {
 891                ret = acquire_dma_channel(mx3_cam);
 892                if (ret < 0)
 893                        return ret;
 894        }
 895
 896        pix->width              = mf.width;
 897        pix->height             = mf.height;
 898        pix->field              = mf.field;
 899        mx3_cam->field          = mf.field;
 900        pix->colorspace         = mf.colorspace;
 901        icd->current_fmt        = xlate;
 902
 903        dev_dbg(icd->parent, "Sensor set %dx%d\n", pix->width, pix->height);
 904
 905        return ret;
 906}
 907
 908static int mx3_camera_try_fmt(struct soc_camera_device *icd,
 909                              struct v4l2_format *f)
 910{
 911        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 912        const struct soc_camera_format_xlate *xlate;
 913        struct v4l2_pix_format *pix = &f->fmt.pix;
 914        struct v4l2_mbus_framefmt mf;
 915        __u32 pixfmt = pix->pixelformat;
 916        int ret;
 917
 918        xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 919        if (pixfmt && !xlate) {
 920                dev_warn(icd->parent, "Format %x not found\n", pixfmt);
 921                return -EINVAL;
 922        }
 923
 924        /* limit to MX3 hardware capabilities */
 925        if (pix->height > 4096)
 926                pix->height = 4096;
 927        if (pix->width > 4096)
 928                pix->width = 4096;
 929
 930        /* limit to sensor capabilities */
 931        mf.width        = pix->width;
 932        mf.height       = pix->height;
 933        mf.field        = pix->field;
 934        mf.colorspace   = pix->colorspace;
 935        mf.code         = xlate->code;
 936
 937        ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
 938        if (ret < 0)
 939                return ret;
 940
 941        pix->width      = mf.width;
 942        pix->height     = mf.height;
 943        pix->colorspace = mf.colorspace;
 944
 945        switch (mf.field) {
 946        case V4L2_FIELD_ANY:
 947                pix->field = V4L2_FIELD_NONE;
 948                break;
 949        case V4L2_FIELD_NONE:
 950                break;
 951        default:
 952                dev_err(icd->parent, "Field type %d unsupported.\n",
 953                        mf.field);
 954                ret = -EINVAL;
 955        }
 956
 957        return ret;
 958}
 959
 960static int mx3_camera_reqbufs(struct soc_camera_device *icd,
 961                              struct v4l2_requestbuffers *p)
 962{
 963        return 0;
 964}
 965
 966static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
 967{
 968        struct soc_camera_device *icd = file->private_data;
 969
 970        return vb2_poll(&icd->vb2_vidq, file, pt);
 971}
 972
 973static int mx3_camera_querycap(struct soc_camera_host *ici,
 974                               struct v4l2_capability *cap)
 975{
 976        /* cap->name is set by the firendly caller:-> */
 977        strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card));
 978        cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 979
 980        return 0;
 981}
 982
 983static int mx3_camera_set_bus_param(struct soc_camera_device *icd)
 984{
 985        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 986        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 987        struct mx3_camera_dev *mx3_cam = ici->priv;
 988        struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
 989        u32 pixfmt = icd->current_fmt->host_fmt->fourcc;
 990        unsigned long bus_flags, common_flags;
 991        u32 dw, sens_conf;
 992        const struct soc_mbus_pixelfmt *fmt;
 993        int buswidth;
 994        int ret;
 995        const struct soc_camera_format_xlate *xlate;
 996        struct device *dev = icd->parent;
 997
 998        fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
 999        if (!fmt)
1000                return -EINVAL;
1001
1002        xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1003        if (!xlate) {
1004                dev_warn(dev, "Format %x not found\n", pixfmt);
1005                return -EINVAL;
1006        }
1007
1008        buswidth = fmt->bits_per_sample;
1009        ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
1010
1011        dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
1012
1013        if (ret < 0)
1014                return ret;
1015
1016        ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1017        if (!ret) {
1018                common_flags = soc_mbus_config_compatible(&cfg,
1019                                                          bus_flags);
1020                if (!common_flags) {
1021                        dev_warn(icd->parent,
1022                                 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1023                                 cfg.flags, bus_flags);
1024                        return -EINVAL;
1025                }
1026        } else if (ret != -ENOIOCTLCMD) {
1027                return ret;
1028        } else {
1029                common_flags = bus_flags;
1030        }
1031
1032        dev_dbg(dev, "Flags cam: 0x%x host: 0x%lx common: 0x%lx\n",
1033                cfg.flags, bus_flags, common_flags);
1034
1035        /* Make choices, based on platform preferences */
1036        if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1037            (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1038                if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
1039                        common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1040                else
1041                        common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1042        }
1043
1044        if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1045            (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1046                if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
1047                        common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1048                else
1049                        common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1050        }
1051
1052        if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
1053            (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
1054                if (mx3_cam->platform_flags & MX3_CAMERA_DP)
1055                        common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
1056                else
1057                        common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
1058        }
1059
1060        if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1061            (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1062                if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
1063                        common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1064                else
1065                        common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1066        }
1067
1068        cfg.flags = common_flags;
1069        ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1070        if (ret < 0 && ret != -ENOIOCTLCMD) {
1071                dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
1072                        common_flags, ret);
1073                return ret;
1074        }
1075
1076        /*
1077         * So far only gated clock mode is supported. Add a line
1078         *      (3 << CSI_SENS_CONF_SENS_PRTCL_SHIFT) |
1079         * below and select the required mode when supporting other
1080         * synchronisation protocols.
1081         */
1082        sens_conf = csi_reg_read(mx3_cam, CSI_SENS_CONF) &
1083                ~((1 << CSI_SENS_CONF_VSYNC_POL_SHIFT) |
1084                  (1 << CSI_SENS_CONF_HSYNC_POL_SHIFT) |
1085                  (1 << CSI_SENS_CONF_DATA_POL_SHIFT) |
1086                  (1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT) |
1087                  (3 << CSI_SENS_CONF_DATA_FMT_SHIFT) |
1088                  (3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT));
1089
1090        /* TODO: Support RGB and YUV formats */
1091
1092        /* This has been set in mx3_camera_activate(), but we clear it above */
1093        sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
1094
1095        if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1096                sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
1097        if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1098                sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
1099        if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1100                sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
1101        if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
1102                sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
1103
1104        /* Just do what we're asked to do */
1105        switch (xlate->host_fmt->bits_per_sample) {
1106        case 4:
1107                dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1108                break;
1109        case 8:
1110                dw = 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1111                break;
1112        case 10:
1113                dw = 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1114                break;
1115        default:
1116                /*
1117                 * Actually it can only be 15 now, default is just to silence
1118                 * compiler warnings
1119                 */
1120        case 15:
1121                dw = 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1122        }
1123
1124        csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
1125
1126        dev_dbg(dev, "Set SENS_CONF to %x\n", sens_conf | dw);
1127
1128        return 0;
1129}
1130
1131static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
1132        .owner          = THIS_MODULE,
1133        .add            = mx3_camera_add_device,
1134        .remove         = mx3_camera_remove_device,
1135        .set_crop       = mx3_camera_set_crop,
1136        .set_fmt        = mx3_camera_set_fmt,
1137        .try_fmt        = mx3_camera_try_fmt,
1138        .get_formats    = mx3_camera_get_formats,
1139        .init_videobuf2 = mx3_camera_init_videobuf,
1140        .reqbufs        = mx3_camera_reqbufs,
1141        .poll           = mx3_camera_poll,
1142        .querycap       = mx3_camera_querycap,
1143        .set_bus_param  = mx3_camera_set_bus_param,
1144};
1145
1146static int mx3_camera_probe(struct platform_device *pdev)
1147{
1148        struct mx3_camera_dev *mx3_cam;
1149        struct resource *res;
1150        void __iomem *base;
1151        int err = 0;
1152        struct soc_camera_host *soc_host;
1153
1154        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1155        if (!res) {
1156                err = -ENODEV;
1157                goto egetres;
1158        }
1159
1160        mx3_cam = vzalloc(sizeof(*mx3_cam));
1161        if (!mx3_cam) {
1162                dev_err(&pdev->dev, "Could not allocate mx3 camera object\n");
1163                err = -ENOMEM;
1164                goto ealloc;
1165        }
1166
1167        mx3_cam->clk = clk_get(&pdev->dev, NULL);
1168        if (IS_ERR(mx3_cam->clk)) {
1169                err = PTR_ERR(mx3_cam->clk);
1170                goto eclkget;
1171        }
1172
1173        mx3_cam->pdata = pdev->dev.platform_data;
1174        mx3_cam->platform_flags = mx3_cam->pdata->flags;
1175        if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_MASK)) {
1176                /*
1177                 * Platform hasn't set available data widths. This is bad.
1178                 * Warn and use a default.
1179                 */
1180                dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
1181                         "data widths, using default 8 bit\n");
1182                mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
1183        }
1184        if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
1185                mx3_cam->width_flags = 1 << 3;
1186        if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
1187                mx3_cam->width_flags |= 1 << 7;
1188        if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
1189                mx3_cam->width_flags |= 1 << 9;
1190        if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
1191                mx3_cam->width_flags |= 1 << 14;
1192
1193        mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000;
1194        if (!mx3_cam->mclk) {
1195                dev_warn(&pdev->dev,
1196                         "mclk_10khz == 0! Please, fix your platform data. "
1197                         "Using default 20MHz\n");
1198                mx3_cam->mclk = 20000000;
1199        }
1200
1201        /* list of video-buffers */
1202        INIT_LIST_HEAD(&mx3_cam->capture);
1203        spin_lock_init(&mx3_cam->lock);
1204
1205        base = ioremap(res->start, resource_size(res));
1206        if (!base) {
1207                pr_err("Couldn't map %x@%x\n", resource_size(res), res->start);
1208                err = -ENOMEM;
1209                goto eioremap;
1210        }
1211
1212        mx3_cam->base   = base;
1213
1214        soc_host                = &mx3_cam->soc_host;
1215        soc_host->drv_name      = MX3_CAM_DRV_NAME;
1216        soc_host->ops           = &mx3_soc_camera_host_ops;
1217        soc_host->priv          = mx3_cam;
1218        soc_host->v4l2_dev.dev  = &pdev->dev;
1219        soc_host->nr            = pdev->id;
1220
1221        mx3_cam->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1222        if (IS_ERR(mx3_cam->alloc_ctx)) {
1223                err = PTR_ERR(mx3_cam->alloc_ctx);
1224                goto eallocctx;
1225        }
1226
1227        err = soc_camera_host_register(soc_host);
1228        if (err)
1229                goto ecamhostreg;
1230
1231        /* IDMAC interface */
1232        dmaengine_get();
1233
1234        return 0;
1235
1236ecamhostreg:
1237        vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1238eallocctx:
1239        iounmap(base);
1240eioremap:
1241        clk_put(mx3_cam->clk);
1242eclkget:
1243        vfree(mx3_cam);
1244ealloc:
1245egetres:
1246        return err;
1247}
1248
1249static int mx3_camera_remove(struct platform_device *pdev)
1250{
1251        struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1252        struct mx3_camera_dev *mx3_cam = container_of(soc_host,
1253                                        struct mx3_camera_dev, soc_host);
1254
1255        clk_put(mx3_cam->clk);
1256
1257        soc_camera_host_unregister(soc_host);
1258
1259        iounmap(mx3_cam->base);
1260
1261        /*
1262         * The channel has either not been allocated,
1263         * or should have been released
1264         */
1265        if (WARN_ON(mx3_cam->idmac_channel[0]))
1266                dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan);
1267
1268        vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1269
1270        vfree(mx3_cam);
1271
1272        dmaengine_put();
1273
1274        return 0;
1275}
1276
1277static struct platform_driver mx3_camera_driver = {
1278        .driver         = {
1279                .name   = MX3_CAM_DRV_NAME,
1280        },
1281        .probe          = mx3_camera_probe,
1282        .remove         = mx3_camera_remove,
1283};
1284
1285module_platform_driver(mx3_camera_driver);
1286
1287MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
1288MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
1289MODULE_LICENSE("GPL v2");
1290MODULE_VERSION("0.2.3");
1291MODULE_ALIAS("platform:" MX3_CAM_DRV_NAME);
1292