Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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