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