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

V4L/DVB (9815): omap2: add OMAP2 camera driver.

Add a driver for the OMAP2 camera block. OMAP2 is used in e.g. Nokia
N800/N810 internet tablet.

This driver uses the V4L2 internal ioctl interface.

Signed-off-by: Sakari Ailus <sakari.ailus@nokia.com>
Signed-off-by: Trilok Soni <soni.trilok@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Sakari Ailus and committed by
Mauro Carvalho Chehab
39aee69a b1f1d76e

+3112
+7
drivers/media/video/Kconfig
··· 770 770 ---help--- 771 771 This is a v4l2 driver for the SuperH Mobile CEU Interface 772 772 773 + config VIDEO_OMAP2 774 + tristate "OMAP2 Camera Capture Interface driver" 775 + depends on VIDEO_DEV && ARCH_OMAP2 776 + select VIDEOBUF_DMA_SG 777 + ---help--- 778 + This is a v4l2 driver for the TI OMAP2 camera capture interface 779 + 773 780 # 774 781 # USB Multimedia device configuration 775 782 #
+3
drivers/media/video/Makefile
··· 8 8 9 9 stkwebcam-objs := stk-webcam.o stk-sensor.o 10 10 11 + omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o 12 + 11 13 videodev-objs := v4l2-dev.o v4l2-ioctl.o 12 14 13 15 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-compat-ioctl32.o v4l2-int-device.o ··· 132 130 133 131 obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o 134 132 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 133 + obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o 135 134 obj-$(CONFIG_SOC_CAMERA) += soc_camera.o 136 135 obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o 137 136 obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
+601
drivers/media/video/omap24xxcam-dma.c
··· 1 + /* 2 + * drivers/media/video/omap24xxcam-dma.c 3 + * 4 + * Copyright (C) 2004 MontaVista Software, Inc. 5 + * Copyright (C) 2004 Texas Instruments. 6 + * Copyright (C) 2007 Nokia Corporation. 7 + * 8 + * Contact: Sakari Ailus <sakari.ailus@nokia.com> 9 + * 10 + * Based on code from Andy Lowe <source@mvista.com> and 11 + * David Cohen <david.cohen@indt.org.br>. 12 + * 13 + * This program is free software; you can redistribute it and/or 14 + * modify it under the terms of the GNU General Public License 15 + * version 2 as published by the Free Software Foundation. 16 + * 17 + * This program is distributed in the hope that it will be useful, but 18 + * WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 + * General Public License for more details. 21 + * 22 + * You should have received a copy of the GNU General Public License 23 + * along with this program; if not, write to the Free Software 24 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 + * 02110-1301 USA 26 + */ 27 + 28 + #include <linux/kernel.h> 29 + #include <linux/io.h> 30 + #include <linux/scatterlist.h> 31 + 32 + #include "omap24xxcam.h" 33 + 34 + /* 35 + * 36 + * DMA hardware. 37 + * 38 + */ 39 + 40 + /* Ack all interrupt on CSR and IRQSTATUS_L0 */ 41 + static void omap24xxcam_dmahw_ack_all(unsigned long base) 42 + { 43 + u32 csr; 44 + int i; 45 + 46 + for (i = 0; i < NUM_CAMDMA_CHANNELS; ++i) { 47 + csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i)); 48 + /* ack interrupt in CSR */ 49 + omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr); 50 + } 51 + omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xf); 52 + } 53 + 54 + /* Ack dmach on CSR and IRQSTATUS_L0 */ 55 + static u32 omap24xxcam_dmahw_ack_ch(unsigned long base, int dmach) 56 + { 57 + u32 csr; 58 + 59 + csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach)); 60 + /* ack interrupt in CSR */ 61 + omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr); 62 + /* ack interrupt in IRQSTATUS */ 63 + omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach)); 64 + 65 + return csr; 66 + } 67 + 68 + static int omap24xxcam_dmahw_running(unsigned long base, int dmach) 69 + { 70 + return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) & CAMDMA_CCR_ENABLE; 71 + } 72 + 73 + static void omap24xxcam_dmahw_transfer_setup(unsigned long base, int dmach, 74 + dma_addr_t start, u32 len) 75 + { 76 + omap24xxcam_reg_out(base, CAMDMA_CCR(dmach), 77 + CAMDMA_CCR_SEL_SRC_DST_SYNC 78 + | CAMDMA_CCR_BS 79 + | CAMDMA_CCR_DST_AMODE_POST_INC 80 + | CAMDMA_CCR_SRC_AMODE_POST_INC 81 + | CAMDMA_CCR_FS 82 + | CAMDMA_CCR_WR_ACTIVE 83 + | CAMDMA_CCR_RD_ACTIVE 84 + | CAMDMA_CCR_SYNCHRO_CAMERA); 85 + omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0); 86 + omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len); 87 + omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1); 88 + omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach), 89 + CAMDMA_CSDP_WRITE_MODE_POSTED 90 + | CAMDMA_CSDP_DST_BURST_EN_32 91 + | CAMDMA_CSDP_DST_PACKED 92 + | CAMDMA_CSDP_SRC_BURST_EN_32 93 + | CAMDMA_CSDP_SRC_PACKED 94 + | CAMDMA_CSDP_DATA_TYPE_8BITS); 95 + omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0); 96 + omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start); 97 + omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0); 98 + omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD); 99 + omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0); 100 + omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0); 101 + omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), 102 + CAMDMA_CSR_MISALIGNED_ERR 103 + | CAMDMA_CSR_SECURE_ERR 104 + | CAMDMA_CSR_TRANS_ERR 105 + | CAMDMA_CSR_BLOCK 106 + | CAMDMA_CSR_DROP); 107 + omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 108 + CAMDMA_CICR_MISALIGNED_ERR_IE 109 + | CAMDMA_CICR_SECURE_ERR_IE 110 + | CAMDMA_CICR_TRANS_ERR_IE 111 + | CAMDMA_CICR_BLOCK_IE 112 + | CAMDMA_CICR_DROP_IE); 113 + } 114 + 115 + static void omap24xxcam_dmahw_transfer_start(unsigned long base, int dmach) 116 + { 117 + omap24xxcam_reg_out(base, CAMDMA_CCR(dmach), 118 + CAMDMA_CCR_SEL_SRC_DST_SYNC 119 + | CAMDMA_CCR_BS 120 + | CAMDMA_CCR_DST_AMODE_POST_INC 121 + | CAMDMA_CCR_SRC_AMODE_POST_INC 122 + | CAMDMA_CCR_ENABLE 123 + | CAMDMA_CCR_FS 124 + | CAMDMA_CCR_SYNCHRO_CAMERA); 125 + } 126 + 127 + static void omap24xxcam_dmahw_transfer_chain(unsigned long base, int dmach, 128 + int free_dmach) 129 + { 130 + int prev_dmach, ch; 131 + 132 + if (dmach == 0) 133 + prev_dmach = NUM_CAMDMA_CHANNELS - 1; 134 + else 135 + prev_dmach = dmach - 1; 136 + omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach), 137 + CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach); 138 + /* Did we chain the DMA transfer before the previous one 139 + * finished? 140 + */ 141 + ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS; 142 + while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch)) 143 + & CAMDMA_CCR_ENABLE)) { 144 + if (ch == dmach) { 145 + /* The previous transfer has ended and this one 146 + * hasn't started, so we must not have chained 147 + * to the previous one in time. We'll have to 148 + * start it now. 149 + */ 150 + omap24xxcam_dmahw_transfer_start(base, dmach); 151 + break; 152 + } else 153 + ch = (ch + 1) % NUM_CAMDMA_CHANNELS; 154 + } 155 + } 156 + 157 + /* Abort all chained DMA transfers. After all transfers have been 158 + * aborted and the DMA controller is idle, the completion routines for 159 + * any aborted transfers will be called in sequence. The DMA 160 + * controller may not be idle after this routine completes, because 161 + * the completion routines might start new transfers. 162 + */ 163 + static void omap24xxcam_dmahw_abort_ch(unsigned long base, int dmach) 164 + { 165 + /* mask all interrupts from this channel */ 166 + omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0); 167 + /* unlink this channel */ 168 + omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0, 169 + CAMDMA_CLNK_CTRL_ENABLE_LNK); 170 + /* disable this channel */ 171 + omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE); 172 + } 173 + 174 + static void omap24xxcam_dmahw_init(unsigned long base) 175 + { 176 + omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG, 177 + CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY 178 + | CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE 179 + | CAMDMA_OCP_SYSCONFIG_AUTOIDLE); 180 + 181 + omap24xxcam_reg_merge(base, CAMDMA_GCR, 0x10, 182 + CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH); 183 + 184 + omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0xf); 185 + } 186 + 187 + /* 188 + * 189 + * Individual DMA channel handling. 190 + * 191 + */ 192 + 193 + /* Start a DMA transfer from the camera to memory. 194 + * Returns zero if the transfer was successfully started, or non-zero if all 195 + * DMA channels are already in use or starting is currently inhibited. 196 + */ 197 + static int omap24xxcam_dma_start(struct omap24xxcam_dma *dma, dma_addr_t start, 198 + u32 len, dma_callback_t callback, void *arg) 199 + { 200 + unsigned long flags; 201 + int dmach; 202 + 203 + spin_lock_irqsave(&dma->lock, flags); 204 + 205 + if (!dma->free_dmach || atomic_read(&dma->dma_stop)) { 206 + spin_unlock_irqrestore(&dma->lock, flags); 207 + return -EBUSY; 208 + } 209 + 210 + dmach = dma->next_dmach; 211 + 212 + dma->ch_state[dmach].callback = callback; 213 + dma->ch_state[dmach].arg = arg; 214 + 215 + omap24xxcam_dmahw_transfer_setup(dma->base, dmach, start, len); 216 + 217 + /* We're ready to start the DMA transfer. */ 218 + 219 + if (dma->free_dmach < NUM_CAMDMA_CHANNELS) { 220 + /* A transfer is already in progress, so try to chain to it. */ 221 + omap24xxcam_dmahw_transfer_chain(dma->base, dmach, 222 + dma->free_dmach); 223 + } else { 224 + /* No transfer is in progress, so we'll just start this one 225 + * now. 226 + */ 227 + omap24xxcam_dmahw_transfer_start(dma->base, dmach); 228 + } 229 + 230 + dma->next_dmach = (dma->next_dmach + 1) % NUM_CAMDMA_CHANNELS; 231 + dma->free_dmach--; 232 + 233 + spin_unlock_irqrestore(&dma->lock, flags); 234 + 235 + return 0; 236 + } 237 + 238 + /* Abort all chained DMA transfers. After all transfers have been 239 + * aborted and the DMA controller is idle, the completion routines for 240 + * any aborted transfers will be called in sequence. The DMA 241 + * controller may not be idle after this routine completes, because 242 + * the completion routines might start new transfers. 243 + */ 244 + static void omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, u32 csr) 245 + { 246 + unsigned long flags; 247 + int dmach, i, free_dmach; 248 + dma_callback_t callback; 249 + void *arg; 250 + 251 + spin_lock_irqsave(&dma->lock, flags); 252 + 253 + /* stop any DMA transfers in progress */ 254 + dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS; 255 + for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) { 256 + omap24xxcam_dmahw_abort_ch(dma->base, dmach); 257 + dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS; 258 + } 259 + 260 + /* We have to be careful here because the callback routine 261 + * might start a new DMA transfer, and we only want to abort 262 + * transfers that were started before this routine was called. 263 + */ 264 + free_dmach = dma->free_dmach; 265 + while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) && 266 + (free_dmach < NUM_CAMDMA_CHANNELS)) { 267 + dmach = (dma->next_dmach + dma->free_dmach) 268 + % NUM_CAMDMA_CHANNELS; 269 + callback = dma->ch_state[dmach].callback; 270 + arg = dma->ch_state[dmach].arg; 271 + dma->free_dmach++; 272 + free_dmach++; 273 + if (callback) { 274 + /* leave interrupts disabled during callback */ 275 + spin_unlock(&dma->lock); 276 + (*callback) (dma, csr, arg); 277 + spin_lock(&dma->lock); 278 + } 279 + } 280 + 281 + spin_unlock_irqrestore(&dma->lock, flags); 282 + } 283 + 284 + /* Abort all chained DMA transfers. After all transfers have been 285 + * aborted and the DMA controller is idle, the completion routines for 286 + * any aborted transfers will be called in sequence. If the completion 287 + * routines attempt to start a new DMA transfer it will fail, so the 288 + * DMA controller will be idle after this routine completes. 289 + */ 290 + static void omap24xxcam_dma_stop(struct omap24xxcam_dma *dma, u32 csr) 291 + { 292 + atomic_inc(&dma->dma_stop); 293 + omap24xxcam_dma_abort(dma, csr); 294 + atomic_dec(&dma->dma_stop); 295 + } 296 + 297 + /* Camera DMA interrupt service routine. */ 298 + void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma) 299 + { 300 + int dmach; 301 + dma_callback_t callback; 302 + void *arg; 303 + u32 csr; 304 + const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR 305 + | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR 306 + | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP; 307 + 308 + spin_lock(&dma->lock); 309 + 310 + if (dma->free_dmach == NUM_CAMDMA_CHANNELS) { 311 + /* A camera DMA interrupt occurred while all channels 312 + * are idle, so we'll acknowledge the interrupt in the 313 + * IRQSTATUS register and exit. 314 + */ 315 + omap24xxcam_dmahw_ack_all(dma->base); 316 + spin_unlock(&dma->lock); 317 + return; 318 + } 319 + 320 + while (dma->free_dmach < NUM_CAMDMA_CHANNELS) { 321 + dmach = (dma->next_dmach + dma->free_dmach) 322 + % NUM_CAMDMA_CHANNELS; 323 + if (omap24xxcam_dmahw_running(dma->base, dmach)) { 324 + /* This buffer hasn't finished yet, so we're done. */ 325 + break; 326 + } 327 + csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach); 328 + if (csr & csr_error) { 329 + /* A DMA error occurred, so stop all DMA 330 + * transfers in progress. 331 + */ 332 + spin_unlock(&dma->lock); 333 + omap24xxcam_dma_stop(dma, csr); 334 + return; 335 + } else { 336 + callback = dma->ch_state[dmach].callback; 337 + arg = dma->ch_state[dmach].arg; 338 + dma->free_dmach++; 339 + if (callback) { 340 + spin_unlock(&dma->lock); 341 + (*callback) (dma, csr, arg); 342 + spin_lock(&dma->lock); 343 + } 344 + } 345 + } 346 + 347 + spin_unlock(&dma->lock); 348 + 349 + omap24xxcam_sgdma_process( 350 + container_of(dma, struct omap24xxcam_sgdma, dma)); 351 + } 352 + 353 + void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma) 354 + { 355 + unsigned long flags; 356 + 357 + spin_lock_irqsave(&dma->lock, flags); 358 + 359 + omap24xxcam_dmahw_init(dma->base); 360 + 361 + spin_unlock_irqrestore(&dma->lock, flags); 362 + } 363 + 364 + static void omap24xxcam_dma_init(struct omap24xxcam_dma *dma, 365 + unsigned long base) 366 + { 367 + int ch; 368 + 369 + /* group all channels on DMA IRQ0 and unmask irq */ 370 + spin_lock_init(&dma->lock); 371 + dma->base = base; 372 + dma->free_dmach = NUM_CAMDMA_CHANNELS; 373 + dma->next_dmach = 0; 374 + for (ch = 0; ch < NUM_CAMDMA_CHANNELS; ch++) { 375 + dma->ch_state[ch].callback = NULL; 376 + dma->ch_state[ch].arg = NULL; 377 + } 378 + } 379 + 380 + /* 381 + * 382 + * Scatter-gather DMA. 383 + * 384 + * High-level DMA construct for transferring whole picture frames to 385 + * memory that is discontinuous. 386 + * 387 + */ 388 + 389 + /* DMA completion routine for the scatter-gather DMA fragments. */ 390 + static void omap24xxcam_sgdma_callback(struct omap24xxcam_dma *dma, u32 csr, 391 + void *arg) 392 + { 393 + struct omap24xxcam_sgdma *sgdma = 394 + container_of(dma, struct omap24xxcam_sgdma, dma); 395 + int sgslot = (int)arg; 396 + struct sgdma_state *sg_state; 397 + const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR 398 + | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR 399 + | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP; 400 + 401 + spin_lock(&sgdma->lock); 402 + 403 + /* We got an interrupt, we can remove the timer */ 404 + del_timer(&sgdma->reset_timer); 405 + 406 + sg_state = sgdma->sg_state + sgslot; 407 + if (!sg_state->queued_sglist) { 408 + spin_unlock(&sgdma->lock); 409 + printk(KERN_ERR "%s: sgdma completed when none queued!\n", 410 + __func__); 411 + return; 412 + } 413 + 414 + sg_state->csr |= csr; 415 + if (!--sg_state->queued_sglist) { 416 + /* Queue for this sglist is empty, so check to see if we're 417 + * done. 418 + */ 419 + if ((sg_state->next_sglist == sg_state->sglen) 420 + || (sg_state->csr & csr_error)) { 421 + sgdma_callback_t callback = sg_state->callback; 422 + void *arg = sg_state->arg; 423 + u32 sg_csr = sg_state->csr; 424 + /* All done with this sglist */ 425 + sgdma->free_sgdma++; 426 + if (callback) { 427 + spin_unlock(&sgdma->lock); 428 + (*callback) (sgdma, sg_csr, arg); 429 + return; 430 + } 431 + } 432 + } 433 + 434 + spin_unlock(&sgdma->lock); 435 + } 436 + 437 + /* Start queued scatter-gather DMA transfers. */ 438 + void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma) 439 + { 440 + unsigned long flags; 441 + int queued_sgdma, sgslot; 442 + struct sgdma_state *sg_state; 443 + const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR 444 + | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR 445 + | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP; 446 + 447 + spin_lock_irqsave(&sgdma->lock, flags); 448 + 449 + queued_sgdma = NUM_SG_DMA - sgdma->free_sgdma; 450 + sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA; 451 + while (queued_sgdma > 0) { 452 + sg_state = sgdma->sg_state + sgslot; 453 + while ((sg_state->next_sglist < sg_state->sglen) && 454 + !(sg_state->csr & csr_error)) { 455 + const struct scatterlist *sglist; 456 + unsigned int len; 457 + 458 + sglist = sg_state->sglist + sg_state->next_sglist; 459 + /* try to start the next DMA transfer */ 460 + if (sg_state->next_sglist + 1 == sg_state->sglen) { 461 + /* 462 + * On the last sg, we handle the case where 463 + * cam->img.pix.sizeimage % PAGE_ALIGN != 0 464 + */ 465 + len = sg_state->len - sg_state->bytes_read; 466 + } else { 467 + len = sg_dma_len(sglist); 468 + } 469 + 470 + if (omap24xxcam_dma_start(&sgdma->dma, 471 + sg_dma_address(sglist), 472 + len, 473 + omap24xxcam_sgdma_callback, 474 + (void *)sgslot)) { 475 + /* DMA start failed */ 476 + spin_unlock_irqrestore(&sgdma->lock, flags); 477 + return; 478 + } else { 479 + unsigned long expires; 480 + /* DMA start was successful */ 481 + sg_state->next_sglist++; 482 + sg_state->bytes_read += len; 483 + sg_state->queued_sglist++; 484 + 485 + /* We start the reset timer */ 486 + expires = jiffies + HZ; 487 + mod_timer(&sgdma->reset_timer, expires); 488 + } 489 + } 490 + queued_sgdma--; 491 + sgslot = (sgslot + 1) % NUM_SG_DMA; 492 + } 493 + 494 + spin_unlock_irqrestore(&sgdma->lock, flags); 495 + } 496 + 497 + /* 498 + * Queue a scatter-gather DMA transfer from the camera to memory. 499 + * Returns zero if the transfer was successfully queued, or non-zero 500 + * if all of the scatter-gather slots are already in use. 501 + */ 502 + int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma, 503 + const struct scatterlist *sglist, int sglen, 504 + int len, sgdma_callback_t callback, void *arg) 505 + { 506 + unsigned long flags; 507 + struct sgdma_state *sg_state; 508 + 509 + if ((sglen < 0) || ((sglen > 0) & !sglist)) 510 + return -EINVAL; 511 + 512 + spin_lock_irqsave(&sgdma->lock, flags); 513 + 514 + if (!sgdma->free_sgdma) { 515 + spin_unlock_irqrestore(&sgdma->lock, flags); 516 + return -EBUSY; 517 + } 518 + 519 + sg_state = sgdma->sg_state + sgdma->next_sgdma; 520 + 521 + sg_state->sglist = sglist; 522 + sg_state->sglen = sglen; 523 + sg_state->next_sglist = 0; 524 + sg_state->bytes_read = 0; 525 + sg_state->len = len; 526 + sg_state->queued_sglist = 0; 527 + sg_state->csr = 0; 528 + sg_state->callback = callback; 529 + sg_state->arg = arg; 530 + 531 + sgdma->next_sgdma = (sgdma->next_sgdma + 1) % NUM_SG_DMA; 532 + sgdma->free_sgdma--; 533 + 534 + spin_unlock_irqrestore(&sgdma->lock, flags); 535 + 536 + omap24xxcam_sgdma_process(sgdma); 537 + 538 + return 0; 539 + } 540 + 541 + /* Sync scatter-gather DMA by aborting any DMA transfers currently in progress. 542 + * Any queued scatter-gather DMA transactions that have not yet been started 543 + * will remain queued. The DMA controller will be idle after this routine 544 + * completes. When the scatter-gather queue is restarted, the next 545 + * scatter-gather DMA transfer will begin at the start of a new transaction. 546 + */ 547 + void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma) 548 + { 549 + unsigned long flags; 550 + int sgslot; 551 + struct sgdma_state *sg_state; 552 + u32 csr = CAMDMA_CSR_TRANS_ERR; 553 + 554 + /* stop any DMA transfers in progress */ 555 + omap24xxcam_dma_stop(&sgdma->dma, csr); 556 + 557 + spin_lock_irqsave(&sgdma->lock, flags); 558 + 559 + if (sgdma->free_sgdma < NUM_SG_DMA) { 560 + sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA; 561 + sg_state = sgdma->sg_state + sgslot; 562 + if (sg_state->next_sglist != 0) { 563 + /* This DMA transfer was in progress, so abort it. */ 564 + sgdma_callback_t callback = sg_state->callback; 565 + void *arg = sg_state->arg; 566 + sgdma->free_sgdma++; 567 + if (callback) { 568 + /* leave interrupts masked */ 569 + spin_unlock(&sgdma->lock); 570 + (*callback) (sgdma, csr, arg); 571 + spin_lock(&sgdma->lock); 572 + } 573 + } 574 + } 575 + 576 + spin_unlock_irqrestore(&sgdma->lock, flags); 577 + } 578 + 579 + void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma, 580 + unsigned long base, 581 + void (*reset_callback)(unsigned long data), 582 + unsigned long reset_callback_data) 583 + { 584 + int sg; 585 + 586 + spin_lock_init(&sgdma->lock); 587 + sgdma->free_sgdma = NUM_SG_DMA; 588 + sgdma->next_sgdma = 0; 589 + for (sg = 0; sg < NUM_SG_DMA; sg++) { 590 + sgdma->sg_state[sg].sglen = 0; 591 + sgdma->sg_state[sg].next_sglist = 0; 592 + sgdma->sg_state[sg].bytes_read = 0; 593 + sgdma->sg_state[sg].queued_sglist = 0; 594 + sgdma->sg_state[sg].csr = 0; 595 + sgdma->sg_state[sg].callback = NULL; 596 + sgdma->sg_state[sg].arg = NULL; 597 + } 598 + 599 + omap24xxcam_dma_init(&sgdma->dma, base); 600 + setup_timer(&sgdma->reset_timer, reset_callback, reset_callback_data); 601 + }
+1908
drivers/media/video/omap24xxcam.c
··· 1 + /* 2 + * drivers/media/video/omap24xxcam.c 3 + * 4 + * OMAP 2 camera block driver. 5 + * 6 + * Copyright (C) 2004 MontaVista Software, Inc. 7 + * Copyright (C) 2004 Texas Instruments. 8 + * Copyright (C) 2007-2008 Nokia Corporation. 9 + * 10 + * Contact: Sakari Ailus <sakari.ailus@nokia.com> 11 + * 12 + * Based on code from Andy Lowe <source@mvista.com> 13 + * 14 + * This program is free software; you can redistribute it and/or 15 + * modify it under the terms of the GNU General Public License 16 + * version 2 as published by the Free Software Foundation. 17 + * 18 + * This program is distributed in the hope that it will be useful, but 19 + * WITHOUT ANY WARRANTY; without even the implied warranty of 20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 + * General Public License for more details. 22 + * 23 + * You should have received a copy of the GNU General Public License 24 + * along with this program; if not, write to the Free Software 25 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 26 + * 02110-1301 USA 27 + */ 28 + 29 + #include <linux/delay.h> 30 + #include <linux/kernel.h> 31 + #include <linux/interrupt.h> 32 + #include <linux/videodev2.h> 33 + #include <linux/pci.h> /* needed for videobufs */ 34 + #include <linux/version.h> 35 + #include <linux/platform_device.h> 36 + #include <linux/clk.h> 37 + #include <linux/io.h> 38 + 39 + #include <media/v4l2-common.h> 40 + #include <media/v4l2-ioctl.h> 41 + 42 + #include "omap24xxcam.h" 43 + 44 + #define OMAP24XXCAM_VERSION KERNEL_VERSION(0, 0, 0) 45 + 46 + #define RESET_TIMEOUT_NS 10000 47 + 48 + static void omap24xxcam_reset(struct omap24xxcam_device *cam); 49 + static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam); 50 + static void omap24xxcam_device_unregister(struct v4l2_int_device *s); 51 + static int omap24xxcam_remove(struct platform_device *pdev); 52 + 53 + /* module parameters */ 54 + static int video_nr = -1; /* video device minor (-1 ==> auto assign) */ 55 + /* 56 + * Maximum amount of memory to use for capture buffers. 57 + * Default is 4800KB, enough to double-buffer SXGA. 58 + */ 59 + static int capture_mem = 1280 * 960 * 2 * 2; 60 + 61 + static struct v4l2_int_device omap24xxcam; 62 + 63 + /* 64 + * 65 + * Clocks. 66 + * 67 + */ 68 + 69 + static void omap24xxcam_clock_put(struct omap24xxcam_device *cam) 70 + { 71 + if (cam->ick != NULL && !IS_ERR(cam->ick)) 72 + clk_put(cam->ick); 73 + if (cam->fck != NULL && !IS_ERR(cam->fck)) 74 + clk_put(cam->fck); 75 + 76 + cam->ick = cam->fck = NULL; 77 + } 78 + 79 + static int omap24xxcam_clock_get(struct omap24xxcam_device *cam) 80 + { 81 + int rval = 0; 82 + 83 + cam->fck = clk_get(cam->dev, "cam_fck"); 84 + if (IS_ERR(cam->fck)) { 85 + dev_err(cam->dev, "can't get cam_fck"); 86 + rval = PTR_ERR(cam->fck); 87 + omap24xxcam_clock_put(cam); 88 + return rval; 89 + } 90 + 91 + cam->ick = clk_get(cam->dev, "cam_ick"); 92 + if (IS_ERR(cam->ick)) { 93 + dev_err(cam->dev, "can't get cam_ick"); 94 + rval = PTR_ERR(cam->ick); 95 + omap24xxcam_clock_put(cam); 96 + } 97 + 98 + return rval; 99 + } 100 + 101 + static void omap24xxcam_clock_on(struct omap24xxcam_device *cam) 102 + { 103 + clk_enable(cam->fck); 104 + clk_enable(cam->ick); 105 + } 106 + 107 + static void omap24xxcam_clock_off(struct omap24xxcam_device *cam) 108 + { 109 + clk_disable(cam->fck); 110 + clk_disable(cam->ick); 111 + } 112 + 113 + /* 114 + * 115 + * Camera core 116 + * 117 + */ 118 + 119 + /* 120 + * Set xclk. 121 + * 122 + * To disable xclk, use value zero. 123 + */ 124 + static void omap24xxcam_core_xclk_set(const struct omap24xxcam_device *cam, 125 + u32 xclk) 126 + { 127 + if (xclk) { 128 + u32 divisor = CAM_MCLK / xclk; 129 + 130 + if (divisor == 1) 131 + omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, 132 + CC_CTRL_XCLK, 133 + CC_CTRL_XCLK_DIV_BYPASS); 134 + else 135 + omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, 136 + CC_CTRL_XCLK, divisor); 137 + } else 138 + omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, 139 + CC_CTRL_XCLK, CC_CTRL_XCLK_DIV_STABLE_LOW); 140 + } 141 + 142 + static void omap24xxcam_core_hwinit(const struct omap24xxcam_device *cam) 143 + { 144 + /* 145 + * Setting the camera core AUTOIDLE bit causes problems with frame 146 + * synchronization, so we will clear the AUTOIDLE bit instead. 147 + */ 148 + omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_SYSCONFIG, 149 + CC_SYSCONFIG_AUTOIDLE); 150 + 151 + /* program the camera interface DMA packet size */ 152 + omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL_DMA, 153 + CC_CTRL_DMA_EN | (DMA_THRESHOLD / 4 - 1)); 154 + 155 + /* enable camera core error interrupts */ 156 + omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQENABLE, 157 + CC_IRQENABLE_FW_ERR_IRQ 158 + | CC_IRQENABLE_FSC_ERR_IRQ 159 + | CC_IRQENABLE_SSC_ERR_IRQ 160 + | CC_IRQENABLE_FIFO_OF_IRQ); 161 + } 162 + 163 + /* 164 + * Enable the camera core. 165 + * 166 + * Data transfer to the camera DMA starts from next starting frame. 167 + */ 168 + static void omap24xxcam_core_enable(const struct omap24xxcam_device *cam) 169 + { 170 + 171 + omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL, 172 + cam->cc_ctrl); 173 + } 174 + 175 + /* 176 + * Disable camera core. 177 + * 178 + * The data transfer will be stopped immediately (CC_CTRL_CC_RST). The 179 + * core internal state machines will be reset. Use 180 + * CC_CTRL_CC_FRAME_TRIG instead if you want to transfer the current 181 + * frame completely. 182 + */ 183 + static void omap24xxcam_core_disable(const struct omap24xxcam_device *cam) 184 + { 185 + omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL, 186 + CC_CTRL_CC_RST); 187 + } 188 + 189 + /* Interrupt service routine for camera core interrupts. */ 190 + static void omap24xxcam_core_isr(struct omap24xxcam_device *cam) 191 + { 192 + u32 cc_irqstatus; 193 + const u32 cc_irqstatus_err = 194 + CC_IRQSTATUS_FW_ERR_IRQ 195 + | CC_IRQSTATUS_FSC_ERR_IRQ 196 + | CC_IRQSTATUS_SSC_ERR_IRQ 197 + | CC_IRQSTATUS_FIFO_UF_IRQ 198 + | CC_IRQSTATUS_FIFO_OF_IRQ; 199 + 200 + cc_irqstatus = omap24xxcam_reg_in(cam->mmio_base + CC_REG_OFFSET, 201 + CC_IRQSTATUS); 202 + omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQSTATUS, 203 + cc_irqstatus); 204 + 205 + if (cc_irqstatus & cc_irqstatus_err 206 + && !atomic_read(&cam->in_reset)) { 207 + dev_dbg(cam->dev, "resetting camera, cc_irqstatus 0x%x\n", 208 + cc_irqstatus); 209 + omap24xxcam_reset(cam); 210 + } 211 + } 212 + 213 + /* 214 + * 215 + * videobuf_buffer handling. 216 + * 217 + * Memory for mmapped videobuf_buffers is not allocated 218 + * conventionally, but by several kmalloc allocations and then 219 + * creating the scatterlist on our own. User-space buffers are handled 220 + * normally. 221 + * 222 + */ 223 + 224 + /* 225 + * Free the memory-mapped buffer memory allocated for a 226 + * videobuf_buffer and the associated scatterlist. 227 + */ 228 + static void omap24xxcam_vbq_free_mmap_buffer(struct videobuf_buffer *vb) 229 + { 230 + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); 231 + size_t alloc_size; 232 + struct page *page; 233 + int i; 234 + 235 + if (dma->sglist == NULL) 236 + return; 237 + 238 + i = dma->sglen; 239 + while (i) { 240 + i--; 241 + alloc_size = sg_dma_len(&dma->sglist[i]); 242 + page = sg_page(&dma->sglist[i]); 243 + do { 244 + ClearPageReserved(page++); 245 + } while (alloc_size -= PAGE_SIZE); 246 + __free_pages(sg_page(&dma->sglist[i]), 247 + get_order(sg_dma_len(&dma->sglist[i]))); 248 + } 249 + 250 + kfree(dma->sglist); 251 + dma->sglist = NULL; 252 + } 253 + 254 + /* Release all memory related to the videobuf_queue. */ 255 + static void omap24xxcam_vbq_free_mmap_buffers(struct videobuf_queue *vbq) 256 + { 257 + int i; 258 + 259 + mutex_lock(&vbq->vb_lock); 260 + 261 + for (i = 0; i < VIDEO_MAX_FRAME; i++) { 262 + if (NULL == vbq->bufs[i]) 263 + continue; 264 + if (V4L2_MEMORY_MMAP != vbq->bufs[i]->memory) 265 + continue; 266 + vbq->ops->buf_release(vbq, vbq->bufs[i]); 267 + omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]); 268 + kfree(vbq->bufs[i]); 269 + vbq->bufs[i] = NULL; 270 + } 271 + 272 + mutex_unlock(&vbq->vb_lock); 273 + 274 + videobuf_mmap_free(vbq); 275 + } 276 + 277 + /* 278 + * Allocate physically as contiguous as possible buffer for video 279 + * frame and allocate and build DMA scatter-gather list for it. 280 + */ 281 + static int omap24xxcam_vbq_alloc_mmap_buffer(struct videobuf_buffer *vb) 282 + { 283 + unsigned int order; 284 + size_t alloc_size, size = vb->bsize; /* vb->bsize is page aligned */ 285 + struct page *page; 286 + int max_pages, err = 0, i = 0; 287 + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); 288 + 289 + /* 290 + * allocate maximum size scatter-gather list. Note this is 291 + * overhead. We may not use as many entries as we allocate 292 + */ 293 + max_pages = vb->bsize >> PAGE_SHIFT; 294 + dma->sglist = kcalloc(max_pages, sizeof(*dma->sglist), GFP_KERNEL); 295 + if (dma->sglist == NULL) { 296 + err = -ENOMEM; 297 + goto out; 298 + } 299 + 300 + while (size) { 301 + order = get_order(size); 302 + /* 303 + * do not over-allocate even if we would get larger 304 + * contiguous chunk that way 305 + */ 306 + if ((PAGE_SIZE << order) > size) 307 + order--; 308 + 309 + /* try to allocate as many contiguous pages as possible */ 310 + page = alloc_pages(GFP_KERNEL | GFP_DMA, order); 311 + /* if allocation fails, try to allocate smaller amount */ 312 + while (page == NULL) { 313 + order--; 314 + page = alloc_pages(GFP_KERNEL | GFP_DMA, order); 315 + if (page == NULL && !order) { 316 + err = -ENOMEM; 317 + goto out; 318 + } 319 + } 320 + size -= (PAGE_SIZE << order); 321 + 322 + /* append allocated chunk of pages into scatter-gather list */ 323 + sg_set_page(&dma->sglist[i], page, PAGE_SIZE << order, 0); 324 + dma->sglen++; 325 + i++; 326 + 327 + alloc_size = (PAGE_SIZE << order); 328 + 329 + /* clear pages before giving them to user space */ 330 + memset(page_address(page), 0, alloc_size); 331 + 332 + /* mark allocated pages reserved */ 333 + do { 334 + SetPageReserved(page++); 335 + } while (alloc_size -= PAGE_SIZE); 336 + } 337 + /* 338 + * REVISIT: not fully correct to assign nr_pages == sglen but 339 + * video-buf is passing nr_pages for e.g. unmap_sg calls 340 + */ 341 + dma->nr_pages = dma->sglen; 342 + dma->direction = PCI_DMA_FROMDEVICE; 343 + 344 + return 0; 345 + 346 + out: 347 + omap24xxcam_vbq_free_mmap_buffer(vb); 348 + return err; 349 + } 350 + 351 + static int omap24xxcam_vbq_alloc_mmap_buffers(struct videobuf_queue *vbq, 352 + unsigned int count) 353 + { 354 + int i, err = 0; 355 + struct omap24xxcam_fh *fh = 356 + container_of(vbq, struct omap24xxcam_fh, vbq); 357 + 358 + mutex_lock(&vbq->vb_lock); 359 + 360 + for (i = 0; i < count; i++) { 361 + err = omap24xxcam_vbq_alloc_mmap_buffer(vbq->bufs[i]); 362 + if (err) 363 + goto out; 364 + dev_dbg(fh->cam->dev, "sglen is %d for buffer %d\n", 365 + videobuf_to_dma(vbq->bufs[i])->sglen, i); 366 + } 367 + 368 + mutex_unlock(&vbq->vb_lock); 369 + 370 + return 0; 371 + out: 372 + while (i) { 373 + i--; 374 + omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]); 375 + } 376 + 377 + mutex_unlock(&vbq->vb_lock); 378 + 379 + return err; 380 + } 381 + 382 + /* 383 + * This routine is called from interrupt context when a scatter-gather DMA 384 + * transfer of a videobuf_buffer completes. 385 + */ 386 + static void omap24xxcam_vbq_complete(struct omap24xxcam_sgdma *sgdma, 387 + u32 csr, void *arg) 388 + { 389 + struct omap24xxcam_device *cam = 390 + container_of(sgdma, struct omap24xxcam_device, sgdma); 391 + struct omap24xxcam_fh *fh = cam->streaming->private_data; 392 + struct videobuf_buffer *vb = (struct videobuf_buffer *)arg; 393 + const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR 394 + | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR 395 + | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP; 396 + unsigned long flags; 397 + 398 + spin_lock_irqsave(&cam->core_enable_disable_lock, flags); 399 + if (--cam->sgdma_in_queue == 0) 400 + omap24xxcam_core_disable(cam); 401 + spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); 402 + 403 + do_gettimeofday(&vb->ts); 404 + vb->field_count = atomic_add_return(2, &fh->field_count); 405 + if (csr & csr_error) { 406 + vb->state = VIDEOBUF_ERROR; 407 + if (!atomic_read(&fh->cam->in_reset)) { 408 + dev_dbg(cam->dev, "resetting camera, csr 0x%x\n", csr); 409 + omap24xxcam_reset(cam); 410 + } 411 + } else 412 + vb->state = VIDEOBUF_DONE; 413 + wake_up(&vb->done); 414 + } 415 + 416 + static void omap24xxcam_vbq_release(struct videobuf_queue *vbq, 417 + struct videobuf_buffer *vb) 418 + { 419 + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); 420 + 421 + /* wait for buffer, especially to get out of the sgdma queue */ 422 + videobuf_waiton(vb, 0, 0); 423 + if (vb->memory == V4L2_MEMORY_MMAP) { 424 + dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen, 425 + dma->direction); 426 + dma->direction = DMA_NONE; 427 + } else { 428 + videobuf_dma_unmap(vbq, videobuf_to_dma(vb)); 429 + videobuf_dma_free(videobuf_to_dma(vb)); 430 + } 431 + 432 + vb->state = VIDEOBUF_NEEDS_INIT; 433 + } 434 + 435 + /* 436 + * Limit the number of available kernel image capture buffers based on the 437 + * number requested, the currently selected image size, and the maximum 438 + * amount of memory permitted for kernel capture buffers. 439 + */ 440 + static int omap24xxcam_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt, 441 + unsigned int *size) 442 + { 443 + struct omap24xxcam_fh *fh = vbq->priv_data; 444 + 445 + if (*cnt <= 0) 446 + *cnt = VIDEO_MAX_FRAME; /* supply a default number of buffers */ 447 + 448 + if (*cnt > VIDEO_MAX_FRAME) 449 + *cnt = VIDEO_MAX_FRAME; 450 + 451 + *size = fh->pix.sizeimage; 452 + 453 + /* accessing fh->cam->capture_mem is ok, it's constant */ 454 + while (*size * *cnt > fh->cam->capture_mem) 455 + (*cnt)--; 456 + 457 + return 0; 458 + } 459 + 460 + static int omap24xxcam_dma_iolock(struct videobuf_queue *vbq, 461 + struct videobuf_dmabuf *dma) 462 + { 463 + int err = 0; 464 + 465 + dma->direction = PCI_DMA_FROMDEVICE; 466 + if (!dma_map_sg(vbq->dev, dma->sglist, dma->sglen, dma->direction)) { 467 + kfree(dma->sglist); 468 + dma->sglist = NULL; 469 + dma->sglen = 0; 470 + err = -EIO; 471 + } 472 + 473 + return err; 474 + } 475 + 476 + static int omap24xxcam_vbq_prepare(struct videobuf_queue *vbq, 477 + struct videobuf_buffer *vb, 478 + enum v4l2_field field) 479 + { 480 + struct omap24xxcam_fh *fh = vbq->priv_data; 481 + int err = 0; 482 + 483 + /* 484 + * Accessing pix here is okay since it's constant while 485 + * streaming is on (and we only get called then). 486 + */ 487 + if (vb->baddr) { 488 + /* This is a userspace buffer. */ 489 + if (fh->pix.sizeimage > vb->bsize) { 490 + /* The buffer isn't big enough. */ 491 + err = -EINVAL; 492 + } else 493 + vb->size = fh->pix.sizeimage; 494 + } else { 495 + if (vb->state != VIDEOBUF_NEEDS_INIT) { 496 + /* 497 + * We have a kernel bounce buffer that has 498 + * already been allocated. 499 + */ 500 + if (fh->pix.sizeimage > vb->size) { 501 + /* 502 + * The image size has been changed to 503 + * a larger size since this buffer was 504 + * allocated, so we need to free and 505 + * reallocate it. 506 + */ 507 + omap24xxcam_vbq_release(vbq, vb); 508 + vb->size = fh->pix.sizeimage; 509 + } 510 + } else { 511 + /* We need to allocate a new kernel bounce buffer. */ 512 + vb->size = fh->pix.sizeimage; 513 + } 514 + } 515 + 516 + if (err) 517 + return err; 518 + 519 + vb->width = fh->pix.width; 520 + vb->height = fh->pix.height; 521 + vb->field = field; 522 + 523 + if (vb->state == VIDEOBUF_NEEDS_INIT) { 524 + if (vb->memory == V4L2_MEMORY_MMAP) 525 + /* 526 + * we have built the scatter-gather list by ourself so 527 + * do the scatter-gather mapping as well 528 + */ 529 + err = omap24xxcam_dma_iolock(vbq, videobuf_to_dma(vb)); 530 + else 531 + err = videobuf_iolock(vbq, vb, NULL); 532 + } 533 + 534 + if (!err) 535 + vb->state = VIDEOBUF_PREPARED; 536 + else 537 + omap24xxcam_vbq_release(vbq, vb); 538 + 539 + return err; 540 + } 541 + 542 + static void omap24xxcam_vbq_queue(struct videobuf_queue *vbq, 543 + struct videobuf_buffer *vb) 544 + { 545 + struct omap24xxcam_fh *fh = vbq->priv_data; 546 + struct omap24xxcam_device *cam = fh->cam; 547 + enum videobuf_state state = vb->state; 548 + unsigned long flags; 549 + int err; 550 + 551 + /* 552 + * FIXME: We're marking the buffer active since we have no 553 + * pretty way of marking it active exactly when the 554 + * scatter-gather transfer starts. 555 + */ 556 + vb->state = VIDEOBUF_ACTIVE; 557 + 558 + err = omap24xxcam_sgdma_queue(&fh->cam->sgdma, 559 + videobuf_to_dma(vb)->sglist, 560 + videobuf_to_dma(vb)->sglen, vb->size, 561 + omap24xxcam_vbq_complete, vb); 562 + 563 + if (!err) { 564 + spin_lock_irqsave(&cam->core_enable_disable_lock, flags); 565 + if (++cam->sgdma_in_queue == 1 566 + && !atomic_read(&cam->in_reset)) 567 + omap24xxcam_core_enable(cam); 568 + spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); 569 + } else { 570 + /* 571 + * Oops. We're not supposed to get any errors here. 572 + * The only way we could get an error is if we ran out 573 + * of scatter-gather DMA slots, but we are supposed to 574 + * have at least as many scatter-gather DMA slots as 575 + * video buffers so that can't happen. 576 + */ 577 + dev_err(cam->dev, "failed to queue a video buffer for dma!\n"); 578 + dev_err(cam->dev, "likely a bug in the driver!\n"); 579 + vb->state = state; 580 + } 581 + } 582 + 583 + static struct videobuf_queue_ops omap24xxcam_vbq_ops = { 584 + .buf_setup = omap24xxcam_vbq_setup, 585 + .buf_prepare = omap24xxcam_vbq_prepare, 586 + .buf_queue = omap24xxcam_vbq_queue, 587 + .buf_release = omap24xxcam_vbq_release, 588 + }; 589 + 590 + /* 591 + * 592 + * OMAP main camera system 593 + * 594 + */ 595 + 596 + /* 597 + * Reset camera block to power-on state. 598 + */ 599 + static void omap24xxcam_poweron_reset(struct omap24xxcam_device *cam) 600 + { 601 + int max_loop = RESET_TIMEOUT_NS; 602 + 603 + /* Reset whole camera subsystem */ 604 + omap24xxcam_reg_out(cam->mmio_base, 605 + CAM_SYSCONFIG, 606 + CAM_SYSCONFIG_SOFTRESET); 607 + 608 + /* Wait till it's finished */ 609 + while (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS) 610 + & CAM_SYSSTATUS_RESETDONE) 611 + && --max_loop) { 612 + ndelay(1); 613 + } 614 + 615 + if (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS) 616 + & CAM_SYSSTATUS_RESETDONE)) 617 + dev_err(cam->dev, "camera soft reset timeout\n"); 618 + } 619 + 620 + /* 621 + * (Re)initialise the camera block. 622 + */ 623 + static void omap24xxcam_hwinit(struct omap24xxcam_device *cam) 624 + { 625 + omap24xxcam_poweron_reset(cam); 626 + 627 + /* set the camera subsystem autoidle bit */ 628 + omap24xxcam_reg_out(cam->mmio_base, CAM_SYSCONFIG, 629 + CAM_SYSCONFIG_AUTOIDLE); 630 + 631 + /* set the camera MMU autoidle bit */ 632 + omap24xxcam_reg_out(cam->mmio_base, 633 + CAMMMU_REG_OFFSET + CAMMMU_SYSCONFIG, 634 + CAMMMU_SYSCONFIG_AUTOIDLE); 635 + 636 + omap24xxcam_core_hwinit(cam); 637 + 638 + omap24xxcam_dma_hwinit(&cam->sgdma.dma); 639 + } 640 + 641 + /* 642 + * Callback for dma transfer stalling. 643 + */ 644 + static void omap24xxcam_stalled_dma_reset(unsigned long data) 645 + { 646 + struct omap24xxcam_device *cam = (struct omap24xxcam_device *)data; 647 + 648 + if (!atomic_read(&cam->in_reset)) { 649 + dev_dbg(cam->dev, "dma stalled, resetting camera\n"); 650 + omap24xxcam_reset(cam); 651 + } 652 + } 653 + 654 + /* 655 + * Stop capture. Mark we're doing a reset, stop DMA transfers and 656 + * core. (No new scatter-gather transfers will be queued whilst 657 + * in_reset is non-zero.) 658 + * 659 + * If omap24xxcam_capture_stop is called from several places at 660 + * once, only the first call will have an effect. Similarly, the last 661 + * call omap24xxcam_streaming_cont will have effect. 662 + * 663 + * Serialisation is ensured by using cam->core_enable_disable_lock. 664 + */ 665 + static void omap24xxcam_capture_stop(struct omap24xxcam_device *cam) 666 + { 667 + unsigned long flags; 668 + 669 + spin_lock_irqsave(&cam->core_enable_disable_lock, flags); 670 + 671 + if (atomic_inc_return(&cam->in_reset) != 1) { 672 + spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); 673 + return; 674 + } 675 + 676 + omap24xxcam_core_disable(cam); 677 + 678 + spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); 679 + 680 + omap24xxcam_sgdma_sync(&cam->sgdma); 681 + } 682 + 683 + /* 684 + * Reset and continue streaming. 685 + * 686 + * Note: Resetting the camera FIFO via the CC_RST bit in the CC_CTRL 687 + * register is supposed to be sufficient to recover from a camera 688 + * interface error, but it doesn't seem to be enough. If we only do 689 + * that then subsequent image captures are out of sync by either one 690 + * or two times DMA_THRESHOLD bytes. Resetting and re-initializing the 691 + * entire camera subsystem prevents the problem with frame 692 + * synchronization. 693 + */ 694 + static void omap24xxcam_capture_cont(struct omap24xxcam_device *cam) 695 + { 696 + unsigned long flags; 697 + 698 + spin_lock_irqsave(&cam->core_enable_disable_lock, flags); 699 + 700 + if (atomic_read(&cam->in_reset) != 1) 701 + goto out; 702 + 703 + omap24xxcam_hwinit(cam); 704 + 705 + omap24xxcam_sensor_if_enable(cam); 706 + 707 + omap24xxcam_sgdma_process(&cam->sgdma); 708 + 709 + if (cam->sgdma_in_queue) 710 + omap24xxcam_core_enable(cam); 711 + 712 + out: 713 + atomic_dec(&cam->in_reset); 714 + spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); 715 + } 716 + 717 + static ssize_t 718 + omap24xxcam_streaming_show(struct device *dev, struct device_attribute *attr, 719 + char *buf) 720 + { 721 + struct omap24xxcam_device *cam = dev_get_drvdata(dev); 722 + 723 + return sprintf(buf, "%s\n", cam->streaming ? "active" : "inactive"); 724 + } 725 + static DEVICE_ATTR(streaming, S_IRUGO, omap24xxcam_streaming_show, NULL); 726 + 727 + /* 728 + * Stop capture and restart it. I.e. reset the camera during use. 729 + */ 730 + static void omap24xxcam_reset(struct omap24xxcam_device *cam) 731 + { 732 + omap24xxcam_capture_stop(cam); 733 + omap24xxcam_capture_cont(cam); 734 + } 735 + 736 + /* 737 + * The main interrupt handler. 738 + */ 739 + static irqreturn_t omap24xxcam_isr(int irq, void *arg) 740 + { 741 + struct omap24xxcam_device *cam = (struct omap24xxcam_device *)arg; 742 + u32 irqstatus; 743 + unsigned int irqhandled = 0; 744 + 745 + irqstatus = omap24xxcam_reg_in(cam->mmio_base, CAM_IRQSTATUS); 746 + 747 + if (irqstatus & 748 + (CAM_IRQSTATUS_DMA_IRQ2 | CAM_IRQSTATUS_DMA_IRQ1 749 + | CAM_IRQSTATUS_DMA_IRQ0)) { 750 + omap24xxcam_dma_isr(&cam->sgdma.dma); 751 + irqhandled = 1; 752 + } 753 + if (irqstatus & CAM_IRQSTATUS_CC_IRQ) { 754 + omap24xxcam_core_isr(cam); 755 + irqhandled = 1; 756 + } 757 + if (irqstatus & CAM_IRQSTATUS_MMU_IRQ) 758 + dev_err(cam->dev, "unhandled camera MMU interrupt!\n"); 759 + 760 + return IRQ_RETVAL(irqhandled); 761 + } 762 + 763 + /* 764 + * 765 + * Sensor handling. 766 + * 767 + */ 768 + 769 + /* 770 + * Enable the external sensor interface. Try to negotiate interface 771 + * parameters with the sensor and start using the new ones. The calls 772 + * to sensor_if_enable and sensor_if_disable need not to be balanced. 773 + */ 774 + static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam) 775 + { 776 + int rval; 777 + struct v4l2_ifparm p; 778 + 779 + rval = vidioc_int_g_ifparm(cam->sdev, &p); 780 + if (rval) { 781 + dev_err(cam->dev, "vidioc_int_g_ifparm failed with %d\n", rval); 782 + return rval; 783 + } 784 + 785 + cam->if_type = p.if_type; 786 + 787 + cam->cc_ctrl = CC_CTRL_CC_EN; 788 + 789 + switch (p.if_type) { 790 + case V4L2_IF_TYPE_BT656: 791 + if (p.u.bt656.frame_start_on_rising_vs) 792 + cam->cc_ctrl |= CC_CTRL_NOBT_SYNCHRO; 793 + if (p.u.bt656.bt_sync_correct) 794 + cam->cc_ctrl |= CC_CTRL_BT_CORRECT; 795 + if (p.u.bt656.swap) 796 + cam->cc_ctrl |= CC_CTRL_PAR_ORDERCAM; 797 + if (p.u.bt656.latch_clk_inv) 798 + cam->cc_ctrl |= CC_CTRL_PAR_CLK_POL; 799 + if (p.u.bt656.nobt_hs_inv) 800 + cam->cc_ctrl |= CC_CTRL_NOBT_HS_POL; 801 + if (p.u.bt656.nobt_vs_inv) 802 + cam->cc_ctrl |= CC_CTRL_NOBT_VS_POL; 803 + 804 + switch (p.u.bt656.mode) { 805 + case V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT: 806 + cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT8; 807 + break; 808 + case V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT: 809 + cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT10; 810 + break; 811 + case V4L2_IF_TYPE_BT656_MODE_NOBT_12BIT: 812 + cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT12; 813 + break; 814 + case V4L2_IF_TYPE_BT656_MODE_BT_8BIT: 815 + cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT8; 816 + break; 817 + case V4L2_IF_TYPE_BT656_MODE_BT_10BIT: 818 + cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT10; 819 + break; 820 + default: 821 + dev_err(cam->dev, 822 + "bt656 interface mode %d not supported\n", 823 + p.u.bt656.mode); 824 + return -EINVAL; 825 + } 826 + /* 827 + * The clock rate that the sensor wants has changed. 828 + * We have to adjust the xclk from OMAP 2 side to 829 + * match the sensor's wish as closely as possible. 830 + */ 831 + if (p.u.bt656.clock_curr != cam->if_u.bt656.xclk) { 832 + u32 xclk = p.u.bt656.clock_curr; 833 + u32 divisor; 834 + 835 + if (xclk == 0) 836 + return -EINVAL; 837 + 838 + if (xclk > CAM_MCLK) 839 + xclk = CAM_MCLK; 840 + 841 + divisor = CAM_MCLK / xclk; 842 + if (divisor * xclk < CAM_MCLK) 843 + divisor++; 844 + if (CAM_MCLK / divisor < p.u.bt656.clock_min 845 + && divisor > 1) 846 + divisor--; 847 + if (divisor > 30) 848 + divisor = 30; 849 + 850 + xclk = CAM_MCLK / divisor; 851 + 852 + if (xclk < p.u.bt656.clock_min 853 + || xclk > p.u.bt656.clock_max) 854 + return -EINVAL; 855 + 856 + cam->if_u.bt656.xclk = xclk; 857 + } 858 + omap24xxcam_core_xclk_set(cam, cam->if_u.bt656.xclk); 859 + break; 860 + default: 861 + /* FIXME: how about other interfaces? */ 862 + dev_err(cam->dev, "interface type %d not supported\n", 863 + p.if_type); 864 + return -EINVAL; 865 + } 866 + 867 + return 0; 868 + } 869 + 870 + static void omap24xxcam_sensor_if_disable(const struct omap24xxcam_device *cam) 871 + { 872 + switch (cam->if_type) { 873 + case V4L2_IF_TYPE_BT656: 874 + omap24xxcam_core_xclk_set(cam, 0); 875 + break; 876 + } 877 + } 878 + 879 + /* 880 + * Initialise the sensor hardware. 881 + */ 882 + static int omap24xxcam_sensor_init(struct omap24xxcam_device *cam) 883 + { 884 + int err = 0; 885 + struct v4l2_int_device *sdev = cam->sdev; 886 + 887 + omap24xxcam_clock_on(cam); 888 + err = omap24xxcam_sensor_if_enable(cam); 889 + if (err) { 890 + dev_err(cam->dev, "sensor interface could not be enabled at " 891 + "initialisation, %d\n", err); 892 + cam->sdev = NULL; 893 + goto out; 894 + } 895 + 896 + /* power up sensor during sensor initialization */ 897 + vidioc_int_s_power(sdev, 1); 898 + 899 + err = vidioc_int_dev_init(sdev); 900 + if (err) { 901 + dev_err(cam->dev, "cannot initialize sensor, error %d\n", err); 902 + /* Sensor init failed --- it's nonexistent to us! */ 903 + cam->sdev = NULL; 904 + goto out; 905 + } 906 + 907 + dev_info(cam->dev, "sensor is %s\n", sdev->name); 908 + 909 + out: 910 + omap24xxcam_sensor_if_disable(cam); 911 + omap24xxcam_clock_off(cam); 912 + 913 + vidioc_int_s_power(sdev, 0); 914 + 915 + return err; 916 + } 917 + 918 + static void omap24xxcam_sensor_exit(struct omap24xxcam_device *cam) 919 + { 920 + if (cam->sdev) 921 + vidioc_int_dev_exit(cam->sdev); 922 + } 923 + 924 + static void omap24xxcam_sensor_disable(struct omap24xxcam_device *cam) 925 + { 926 + omap24xxcam_sensor_if_disable(cam); 927 + omap24xxcam_clock_off(cam); 928 + vidioc_int_s_power(cam->sdev, 0); 929 + } 930 + 931 + /* 932 + * Power-up and configure camera sensor. It's ready for capturing now. 933 + */ 934 + static int omap24xxcam_sensor_enable(struct omap24xxcam_device *cam) 935 + { 936 + int rval; 937 + 938 + omap24xxcam_clock_on(cam); 939 + 940 + omap24xxcam_sensor_if_enable(cam); 941 + 942 + rval = vidioc_int_s_power(cam->sdev, 1); 943 + if (rval) 944 + goto out; 945 + 946 + rval = vidioc_int_init(cam->sdev); 947 + if (rval) 948 + goto out; 949 + 950 + return 0; 951 + 952 + out: 953 + omap24xxcam_sensor_disable(cam); 954 + 955 + return rval; 956 + } 957 + 958 + static void omap24xxcam_sensor_reset_work(struct work_struct *work) 959 + { 960 + struct omap24xxcam_device *cam = 961 + container_of(work, struct omap24xxcam_device, 962 + sensor_reset_work); 963 + 964 + if (atomic_read(&cam->reset_disable)) 965 + return; 966 + 967 + omap24xxcam_capture_stop(cam); 968 + 969 + if (vidioc_int_reset(cam->sdev) == 0) { 970 + vidioc_int_init(cam->sdev); 971 + } else { 972 + /* Can't reset it by vidioc_int_reset. */ 973 + omap24xxcam_sensor_disable(cam); 974 + omap24xxcam_sensor_enable(cam); 975 + } 976 + 977 + omap24xxcam_capture_cont(cam); 978 + } 979 + 980 + /* 981 + * 982 + * IOCTL interface. 983 + * 984 + */ 985 + 986 + static int vidioc_querycap(struct file *file, void *fh, 987 + struct v4l2_capability *cap) 988 + { 989 + struct omap24xxcam_fh *ofh = fh; 990 + struct omap24xxcam_device *cam = ofh->cam; 991 + 992 + strlcpy(cap->driver, CAM_NAME, sizeof(cap->driver)); 993 + strlcpy(cap->card, cam->vfd->name, sizeof(cap->card)); 994 + cap->version = OMAP24XXCAM_VERSION; 995 + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 996 + 997 + return 0; 998 + } 999 + 1000 + static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, 1001 + struct v4l2_fmtdesc *f) 1002 + { 1003 + struct omap24xxcam_fh *ofh = fh; 1004 + struct omap24xxcam_device *cam = ofh->cam; 1005 + int rval; 1006 + 1007 + rval = vidioc_int_enum_fmt_cap(cam->sdev, f); 1008 + 1009 + return rval; 1010 + } 1011 + 1012 + static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, 1013 + struct v4l2_format *f) 1014 + { 1015 + struct omap24xxcam_fh *ofh = fh; 1016 + struct omap24xxcam_device *cam = ofh->cam; 1017 + int rval; 1018 + 1019 + mutex_lock(&cam->mutex); 1020 + rval = vidioc_int_g_fmt_cap(cam->sdev, f); 1021 + mutex_unlock(&cam->mutex); 1022 + 1023 + return rval; 1024 + } 1025 + 1026 + static int vidioc_s_fmt_vid_cap(struct file *file, void *fh, 1027 + struct v4l2_format *f) 1028 + { 1029 + struct omap24xxcam_fh *ofh = fh; 1030 + struct omap24xxcam_device *cam = ofh->cam; 1031 + int rval; 1032 + 1033 + mutex_lock(&cam->mutex); 1034 + if (cam->streaming) { 1035 + rval = -EBUSY; 1036 + goto out; 1037 + } 1038 + 1039 + rval = vidioc_int_s_fmt_cap(cam->sdev, f); 1040 + 1041 + out: 1042 + mutex_unlock(&cam->mutex); 1043 + 1044 + if (!rval) { 1045 + mutex_lock(&ofh->vbq.vb_lock); 1046 + ofh->pix = f->fmt.pix; 1047 + mutex_unlock(&ofh->vbq.vb_lock); 1048 + } 1049 + 1050 + memset(f, 0, sizeof(*f)); 1051 + vidioc_g_fmt_vid_cap(file, fh, f); 1052 + 1053 + return rval; 1054 + } 1055 + 1056 + static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, 1057 + struct v4l2_format *f) 1058 + { 1059 + struct omap24xxcam_fh *ofh = fh; 1060 + struct omap24xxcam_device *cam = ofh->cam; 1061 + int rval; 1062 + 1063 + mutex_lock(&cam->mutex); 1064 + rval = vidioc_int_try_fmt_cap(cam->sdev, f); 1065 + mutex_unlock(&cam->mutex); 1066 + 1067 + return rval; 1068 + } 1069 + 1070 + static int vidioc_reqbufs(struct file *file, void *fh, 1071 + struct v4l2_requestbuffers *b) 1072 + { 1073 + struct omap24xxcam_fh *ofh = fh; 1074 + struct omap24xxcam_device *cam = ofh->cam; 1075 + int rval; 1076 + 1077 + mutex_lock(&cam->mutex); 1078 + if (cam->streaming) { 1079 + mutex_unlock(&cam->mutex); 1080 + return -EBUSY; 1081 + } 1082 + 1083 + omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq); 1084 + mutex_unlock(&cam->mutex); 1085 + 1086 + rval = videobuf_reqbufs(&ofh->vbq, b); 1087 + 1088 + /* 1089 + * Either videobuf_reqbufs failed or the buffers are not 1090 + * memory-mapped (which would need special attention). 1091 + */ 1092 + if (rval < 0 || b->memory != V4L2_MEMORY_MMAP) 1093 + goto out; 1094 + 1095 + rval = omap24xxcam_vbq_alloc_mmap_buffers(&ofh->vbq, rval); 1096 + if (rval) 1097 + omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq); 1098 + 1099 + out: 1100 + return rval; 1101 + } 1102 + 1103 + static int vidioc_querybuf(struct file *file, void *fh, 1104 + struct v4l2_buffer *b) 1105 + { 1106 + struct omap24xxcam_fh *ofh = fh; 1107 + 1108 + return videobuf_querybuf(&ofh->vbq, b); 1109 + } 1110 + 1111 + static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) 1112 + { 1113 + struct omap24xxcam_fh *ofh = fh; 1114 + 1115 + return videobuf_qbuf(&ofh->vbq, b); 1116 + } 1117 + 1118 + static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) 1119 + { 1120 + struct omap24xxcam_fh *ofh = fh; 1121 + struct omap24xxcam_device *cam = ofh->cam; 1122 + struct videobuf_buffer *vb; 1123 + int rval; 1124 + 1125 + videobuf_dqbuf_again: 1126 + rval = videobuf_dqbuf(&ofh->vbq, b, file->f_flags & O_NONBLOCK); 1127 + if (rval) 1128 + goto out; 1129 + 1130 + vb = ofh->vbq.bufs[b->index]; 1131 + 1132 + mutex_lock(&cam->mutex); 1133 + /* _needs_reset returns -EIO if reset is required. */ 1134 + rval = vidioc_int_g_needs_reset(cam->sdev, (void *)vb->baddr); 1135 + mutex_unlock(&cam->mutex); 1136 + if (rval == -EIO) 1137 + schedule_work(&cam->sensor_reset_work); 1138 + else 1139 + rval = 0; 1140 + 1141 + out: 1142 + /* 1143 + * This is a hack. We don't want to show -EIO to the user 1144 + * space. Requeue the buffer and try again if we're not doing 1145 + * this in non-blocking mode. 1146 + */ 1147 + if (rval == -EIO) { 1148 + videobuf_qbuf(&ofh->vbq, b); 1149 + if (!(file->f_flags & O_NONBLOCK)) 1150 + goto videobuf_dqbuf_again; 1151 + /* 1152 + * We don't have a videobuf_buffer now --- maybe next 1153 + * time... 1154 + */ 1155 + rval = -EAGAIN; 1156 + } 1157 + 1158 + return rval; 1159 + } 1160 + 1161 + static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) 1162 + { 1163 + struct omap24xxcam_fh *ofh = fh; 1164 + struct omap24xxcam_device *cam = ofh->cam; 1165 + int rval; 1166 + 1167 + mutex_lock(&cam->mutex); 1168 + if (cam->streaming) { 1169 + rval = -EBUSY; 1170 + goto out; 1171 + } 1172 + 1173 + rval = omap24xxcam_sensor_if_enable(cam); 1174 + if (rval) { 1175 + dev_dbg(cam->dev, "vidioc_int_g_ifparm failed\n"); 1176 + goto out; 1177 + } 1178 + 1179 + rval = videobuf_streamon(&ofh->vbq); 1180 + if (!rval) { 1181 + cam->streaming = file; 1182 + sysfs_notify(&cam->dev->kobj, NULL, "streaming"); 1183 + } 1184 + 1185 + out: 1186 + mutex_unlock(&cam->mutex); 1187 + 1188 + return rval; 1189 + } 1190 + 1191 + static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) 1192 + { 1193 + struct omap24xxcam_fh *ofh = fh; 1194 + struct omap24xxcam_device *cam = ofh->cam; 1195 + struct videobuf_queue *q = &ofh->vbq; 1196 + int rval; 1197 + 1198 + atomic_inc(&cam->reset_disable); 1199 + 1200 + flush_scheduled_work(); 1201 + 1202 + rval = videobuf_streamoff(q); 1203 + if (!rval) { 1204 + mutex_lock(&cam->mutex); 1205 + cam->streaming = NULL; 1206 + mutex_unlock(&cam->mutex); 1207 + sysfs_notify(&cam->dev->kobj, NULL, "streaming"); 1208 + } 1209 + 1210 + atomic_dec(&cam->reset_disable); 1211 + 1212 + return rval; 1213 + } 1214 + 1215 + static int vidioc_enum_input(struct file *file, void *fh, 1216 + struct v4l2_input *inp) 1217 + { 1218 + if (inp->index > 0) 1219 + return -EINVAL; 1220 + 1221 + strlcpy(inp->name, "camera", sizeof(inp->name)); 1222 + inp->type = V4L2_INPUT_TYPE_CAMERA; 1223 + 1224 + return 0; 1225 + } 1226 + 1227 + static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) 1228 + { 1229 + *i = 0; 1230 + 1231 + return 0; 1232 + } 1233 + 1234 + static int vidioc_s_input(struct file *file, void *fh, unsigned int i) 1235 + { 1236 + if (i > 0) 1237 + return -EINVAL; 1238 + 1239 + return 0; 1240 + } 1241 + 1242 + static int vidioc_queryctrl(struct file *file, void *fh, 1243 + struct v4l2_queryctrl *a) 1244 + { 1245 + struct omap24xxcam_fh *ofh = fh; 1246 + struct omap24xxcam_device *cam = ofh->cam; 1247 + int rval; 1248 + 1249 + rval = vidioc_int_queryctrl(cam->sdev, a); 1250 + 1251 + return rval; 1252 + } 1253 + 1254 + static int vidioc_g_ctrl(struct file *file, void *fh, 1255 + struct v4l2_control *a) 1256 + { 1257 + struct omap24xxcam_fh *ofh = fh; 1258 + struct omap24xxcam_device *cam = ofh->cam; 1259 + int rval; 1260 + 1261 + mutex_lock(&cam->mutex); 1262 + rval = vidioc_int_g_ctrl(cam->sdev, a); 1263 + mutex_unlock(&cam->mutex); 1264 + 1265 + return rval; 1266 + } 1267 + 1268 + static int vidioc_s_ctrl(struct file *file, void *fh, 1269 + struct v4l2_control *a) 1270 + { 1271 + struct omap24xxcam_fh *ofh = fh; 1272 + struct omap24xxcam_device *cam = ofh->cam; 1273 + int rval; 1274 + 1275 + mutex_lock(&cam->mutex); 1276 + rval = vidioc_int_s_ctrl(cam->sdev, a); 1277 + mutex_unlock(&cam->mutex); 1278 + 1279 + return rval; 1280 + } 1281 + 1282 + static int vidioc_g_parm(struct file *file, void *fh, 1283 + struct v4l2_streamparm *a) { 1284 + struct omap24xxcam_fh *ofh = fh; 1285 + struct omap24xxcam_device *cam = ofh->cam; 1286 + int rval; 1287 + 1288 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1289 + return -EINVAL; 1290 + 1291 + mutex_lock(&cam->mutex); 1292 + rval = vidioc_int_g_parm(cam->sdev, a); 1293 + mutex_unlock(&cam->mutex); 1294 + 1295 + return rval; 1296 + } 1297 + 1298 + static int vidioc_s_parm(struct file *file, void *fh, 1299 + struct v4l2_streamparm *a) 1300 + { 1301 + struct omap24xxcam_fh *ofh = fh; 1302 + struct omap24xxcam_device *cam = ofh->cam; 1303 + struct v4l2_streamparm old_streamparm; 1304 + int rval; 1305 + 1306 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1307 + return -EINVAL; 1308 + 1309 + mutex_lock(&cam->mutex); 1310 + if (cam->streaming) { 1311 + rval = -EBUSY; 1312 + goto out; 1313 + } 1314 + 1315 + old_streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1316 + rval = vidioc_int_g_parm(cam->sdev, &old_streamparm); 1317 + if (rval) 1318 + goto out; 1319 + 1320 + rval = vidioc_int_s_parm(cam->sdev, a); 1321 + if (rval) 1322 + goto out; 1323 + 1324 + rval = omap24xxcam_sensor_if_enable(cam); 1325 + /* 1326 + * Revert to old streaming parameters if enabling sensor 1327 + * interface with the new ones failed. 1328 + */ 1329 + if (rval) 1330 + vidioc_int_s_parm(cam->sdev, &old_streamparm); 1331 + 1332 + out: 1333 + mutex_unlock(&cam->mutex); 1334 + 1335 + return rval; 1336 + } 1337 + 1338 + /* 1339 + * 1340 + * File operations. 1341 + * 1342 + */ 1343 + 1344 + static unsigned int omap24xxcam_poll(struct file *file, 1345 + struct poll_table_struct *wait) 1346 + { 1347 + struct omap24xxcam_fh *fh = file->private_data; 1348 + struct omap24xxcam_device *cam = fh->cam; 1349 + struct videobuf_buffer *vb; 1350 + 1351 + mutex_lock(&cam->mutex); 1352 + if (cam->streaming != file) { 1353 + mutex_unlock(&cam->mutex); 1354 + return POLLERR; 1355 + } 1356 + mutex_unlock(&cam->mutex); 1357 + 1358 + mutex_lock(&fh->vbq.vb_lock); 1359 + if (list_empty(&fh->vbq.stream)) { 1360 + mutex_unlock(&fh->vbq.vb_lock); 1361 + return POLLERR; 1362 + } 1363 + vb = list_entry(fh->vbq.stream.next, struct videobuf_buffer, stream); 1364 + mutex_unlock(&fh->vbq.vb_lock); 1365 + 1366 + poll_wait(file, &vb->done, wait); 1367 + 1368 + if (vb->state == VIDEOBUF_DONE || vb->state == VIDEOBUF_ERROR) 1369 + return POLLIN | POLLRDNORM; 1370 + 1371 + return 0; 1372 + } 1373 + 1374 + static int omap24xxcam_mmap_buffers(struct file *file, 1375 + struct vm_area_struct *vma) 1376 + { 1377 + struct omap24xxcam_fh *fh = file->private_data; 1378 + struct omap24xxcam_device *cam = fh->cam; 1379 + struct videobuf_queue *vbq = &fh->vbq; 1380 + unsigned int first, last, size, i, j; 1381 + int err = 0; 1382 + 1383 + mutex_lock(&cam->mutex); 1384 + if (cam->streaming) { 1385 + mutex_unlock(&cam->mutex); 1386 + return -EBUSY; 1387 + } 1388 + mutex_unlock(&cam->mutex); 1389 + mutex_lock(&vbq->vb_lock); 1390 + 1391 + /* look for first buffer to map */ 1392 + for (first = 0; first < VIDEO_MAX_FRAME; first++) { 1393 + if (NULL == vbq->bufs[first]) 1394 + continue; 1395 + if (V4L2_MEMORY_MMAP != vbq->bufs[first]->memory) 1396 + continue; 1397 + if (vbq->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT)) 1398 + break; 1399 + } 1400 + 1401 + /* look for last buffer to map */ 1402 + for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) { 1403 + if (NULL == vbq->bufs[last]) 1404 + continue; 1405 + if (V4L2_MEMORY_MMAP != vbq->bufs[last]->memory) 1406 + continue; 1407 + size += vbq->bufs[last]->bsize; 1408 + if (size == (vma->vm_end - vma->vm_start)) 1409 + break; 1410 + } 1411 + 1412 + size = 0; 1413 + for (i = first; i <= last; i++) { 1414 + struct videobuf_dmabuf *dma = videobuf_to_dma(vbq->bufs[i]); 1415 + 1416 + for (j = 0; j < dma->sglen; j++) { 1417 + err = remap_pfn_range( 1418 + vma, vma->vm_start + size, 1419 + page_to_pfn(sg_page(&dma->sglist[j])), 1420 + sg_dma_len(&dma->sglist[j]), vma->vm_page_prot); 1421 + if (err) 1422 + goto out; 1423 + size += sg_dma_len(&dma->sglist[j]); 1424 + } 1425 + } 1426 + 1427 + out: 1428 + mutex_unlock(&vbq->vb_lock); 1429 + 1430 + return err; 1431 + } 1432 + 1433 + static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma) 1434 + { 1435 + struct omap24xxcam_fh *fh = file->private_data; 1436 + int rval; 1437 + 1438 + /* let the video-buf mapper check arguments and set-up structures */ 1439 + rval = videobuf_mmap_mapper(&fh->vbq, vma); 1440 + if (rval) 1441 + return rval; 1442 + 1443 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 1444 + 1445 + /* do mapping to our allocated buffers */ 1446 + rval = omap24xxcam_mmap_buffers(file, vma); 1447 + /* 1448 + * In case of error, free vma->vm_private_data allocated by 1449 + * videobuf_mmap_mapper. 1450 + */ 1451 + if (rval) 1452 + kfree(vma->vm_private_data); 1453 + 1454 + return rval; 1455 + } 1456 + 1457 + static int omap24xxcam_open(struct inode *inode, struct file *file) 1458 + { 1459 + int minor = iminor(inode); 1460 + struct omap24xxcam_device *cam = omap24xxcam.priv; 1461 + struct omap24xxcam_fh *fh; 1462 + struct v4l2_format format; 1463 + 1464 + if (!cam || !cam->vfd || (cam->vfd->minor != minor)) 1465 + return -ENODEV; 1466 + 1467 + fh = kzalloc(sizeof(*fh), GFP_KERNEL); 1468 + if (fh == NULL) 1469 + return -ENOMEM; 1470 + 1471 + mutex_lock(&cam->mutex); 1472 + if (cam->sdev == NULL || !try_module_get(cam->sdev->module)) { 1473 + mutex_unlock(&cam->mutex); 1474 + goto out_try_module_get; 1475 + } 1476 + 1477 + if (atomic_inc_return(&cam->users) == 1) { 1478 + omap24xxcam_hwinit(cam); 1479 + if (omap24xxcam_sensor_enable(cam)) { 1480 + mutex_unlock(&cam->mutex); 1481 + goto out_omap24xxcam_sensor_enable; 1482 + } 1483 + } 1484 + mutex_unlock(&cam->mutex); 1485 + 1486 + fh->cam = cam; 1487 + mutex_lock(&cam->mutex); 1488 + vidioc_int_g_fmt_cap(cam->sdev, &format); 1489 + mutex_unlock(&cam->mutex); 1490 + /* FIXME: how about fh->pix when there are more users? */ 1491 + fh->pix = format.fmt.pix; 1492 + 1493 + file->private_data = fh; 1494 + 1495 + spin_lock_init(&fh->vbq_lock); 1496 + 1497 + videobuf_queue_sg_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL, 1498 + &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, 1499 + V4L2_FIELD_NONE, 1500 + sizeof(struct videobuf_buffer), fh); 1501 + 1502 + return 0; 1503 + 1504 + out_omap24xxcam_sensor_enable: 1505 + omap24xxcam_poweron_reset(cam); 1506 + module_put(cam->sdev->module); 1507 + 1508 + out_try_module_get: 1509 + kfree(fh); 1510 + 1511 + return -ENODEV; 1512 + } 1513 + 1514 + static int omap24xxcam_release(struct inode *inode, struct file *file) 1515 + { 1516 + struct omap24xxcam_fh *fh = file->private_data; 1517 + struct omap24xxcam_device *cam = fh->cam; 1518 + 1519 + atomic_inc(&cam->reset_disable); 1520 + 1521 + flush_scheduled_work(); 1522 + 1523 + /* stop streaming capture */ 1524 + videobuf_streamoff(&fh->vbq); 1525 + 1526 + mutex_lock(&cam->mutex); 1527 + if (cam->streaming == file) { 1528 + cam->streaming = NULL; 1529 + mutex_unlock(&cam->mutex); 1530 + sysfs_notify(&cam->dev->kobj, NULL, "streaming"); 1531 + } else { 1532 + mutex_unlock(&cam->mutex); 1533 + } 1534 + 1535 + atomic_dec(&cam->reset_disable); 1536 + 1537 + omap24xxcam_vbq_free_mmap_buffers(&fh->vbq); 1538 + 1539 + /* 1540 + * Make sure the reset work we might have scheduled is not 1541 + * pending! It may be run *only* if we have users. (And it may 1542 + * not be scheduled anymore since streaming is already 1543 + * disabled.) 1544 + */ 1545 + flush_scheduled_work(); 1546 + 1547 + mutex_lock(&cam->mutex); 1548 + if (atomic_dec_return(&cam->users) == 0) { 1549 + omap24xxcam_sensor_disable(cam); 1550 + omap24xxcam_poweron_reset(cam); 1551 + } 1552 + mutex_unlock(&cam->mutex); 1553 + 1554 + file->private_data = NULL; 1555 + 1556 + module_put(cam->sdev->module); 1557 + kfree(fh); 1558 + 1559 + return 0; 1560 + } 1561 + 1562 + static struct file_operations omap24xxcam_fops = { 1563 + .llseek = no_llseek, 1564 + .ioctl = video_ioctl2, 1565 + .poll = omap24xxcam_poll, 1566 + .mmap = omap24xxcam_mmap, 1567 + .open = omap24xxcam_open, 1568 + .release = omap24xxcam_release, 1569 + }; 1570 + 1571 + /* 1572 + * 1573 + * Power management. 1574 + * 1575 + */ 1576 + 1577 + #ifdef CONFIG_PM 1578 + static int omap24xxcam_suspend(struct platform_device *pdev, pm_message_t state) 1579 + { 1580 + struct omap24xxcam_device *cam = platform_get_drvdata(pdev); 1581 + 1582 + if (atomic_read(&cam->users) == 0) 1583 + return 0; 1584 + 1585 + if (!atomic_read(&cam->reset_disable)) 1586 + omap24xxcam_capture_stop(cam); 1587 + 1588 + omap24xxcam_sensor_disable(cam); 1589 + omap24xxcam_poweron_reset(cam); 1590 + 1591 + return 0; 1592 + } 1593 + 1594 + static int omap24xxcam_resume(struct platform_device *pdev) 1595 + { 1596 + struct omap24xxcam_device *cam = platform_get_drvdata(pdev); 1597 + 1598 + if (atomic_read(&cam->users) == 0) 1599 + return 0; 1600 + 1601 + omap24xxcam_hwinit(cam); 1602 + omap24xxcam_sensor_enable(cam); 1603 + 1604 + if (!atomic_read(&cam->reset_disable)) 1605 + omap24xxcam_capture_cont(cam); 1606 + 1607 + return 0; 1608 + } 1609 + #endif /* CONFIG_PM */ 1610 + 1611 + static const struct v4l2_ioctl_ops omap24xxcam_ioctl_fops = { 1612 + .vidioc_querycap = vidioc_querycap, 1613 + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 1614 + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 1615 + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 1616 + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 1617 + .vidioc_reqbufs = vidioc_reqbufs, 1618 + .vidioc_querybuf = vidioc_querybuf, 1619 + .vidioc_qbuf = vidioc_qbuf, 1620 + .vidioc_dqbuf = vidioc_dqbuf, 1621 + .vidioc_streamon = vidioc_streamon, 1622 + .vidioc_streamoff = vidioc_streamoff, 1623 + .vidioc_enum_input = vidioc_enum_input, 1624 + .vidioc_g_input = vidioc_g_input, 1625 + .vidioc_s_input = vidioc_s_input, 1626 + .vidioc_queryctrl = vidioc_queryctrl, 1627 + .vidioc_g_ctrl = vidioc_g_ctrl, 1628 + .vidioc_s_ctrl = vidioc_s_ctrl, 1629 + .vidioc_g_parm = vidioc_g_parm, 1630 + .vidioc_s_parm = vidioc_s_parm, 1631 + }; 1632 + 1633 + /* 1634 + * 1635 + * Camera device (i.e. /dev/video). 1636 + * 1637 + */ 1638 + 1639 + static int omap24xxcam_device_register(struct v4l2_int_device *s) 1640 + { 1641 + struct omap24xxcam_device *cam = s->u.slave->master->priv; 1642 + struct video_device *vfd; 1643 + int rval; 1644 + 1645 + /* We already have a slave. */ 1646 + if (cam->sdev) 1647 + return -EBUSY; 1648 + 1649 + cam->sdev = s; 1650 + 1651 + if (device_create_file(cam->dev, &dev_attr_streaming) != 0) { 1652 + dev_err(cam->dev, "could not register sysfs entry\n"); 1653 + rval = -EBUSY; 1654 + goto err; 1655 + } 1656 + 1657 + /* initialize the video_device struct */ 1658 + vfd = cam->vfd = video_device_alloc(); 1659 + if (!vfd) { 1660 + dev_err(cam->dev, "could not allocate video device struct\n"); 1661 + rval = -ENOMEM; 1662 + goto err; 1663 + } 1664 + vfd->release = video_device_release; 1665 + 1666 + vfd->parent = cam->dev; 1667 + 1668 + strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name)); 1669 + vfd->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_CHROMAKEY; 1670 + vfd->fops = &omap24xxcam_fops; 1671 + vfd->minor = -1; 1672 + vfd->ioctl_ops = &omap24xxcam_ioctl_fops; 1673 + 1674 + omap24xxcam_hwinit(cam); 1675 + 1676 + rval = omap24xxcam_sensor_init(cam); 1677 + if (rval) 1678 + goto err; 1679 + 1680 + if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) { 1681 + dev_err(cam->dev, "could not register V4L device\n"); 1682 + vfd->minor = -1; 1683 + rval = -EBUSY; 1684 + goto err; 1685 + } 1686 + 1687 + omap24xxcam_poweron_reset(cam); 1688 + 1689 + dev_info(cam->dev, "registered device video%d\n", vfd->minor); 1690 + 1691 + return 0; 1692 + 1693 + err: 1694 + omap24xxcam_device_unregister(s); 1695 + 1696 + return rval; 1697 + } 1698 + 1699 + static void omap24xxcam_device_unregister(struct v4l2_int_device *s) 1700 + { 1701 + struct omap24xxcam_device *cam = s->u.slave->master->priv; 1702 + 1703 + omap24xxcam_sensor_exit(cam); 1704 + 1705 + if (cam->vfd) { 1706 + if (cam->vfd->minor == -1) { 1707 + /* 1708 + * The device was never registered, so release the 1709 + * video_device struct directly. 1710 + */ 1711 + video_device_release(cam->vfd); 1712 + } else { 1713 + /* 1714 + * The unregister function will release the 1715 + * video_device struct as well as 1716 + * unregistering it. 1717 + */ 1718 + video_unregister_device(cam->vfd); 1719 + } 1720 + cam->vfd = NULL; 1721 + } 1722 + 1723 + device_remove_file(cam->dev, &dev_attr_streaming); 1724 + 1725 + cam->sdev = NULL; 1726 + } 1727 + 1728 + static struct v4l2_int_master omap24xxcam_master = { 1729 + .attach = omap24xxcam_device_register, 1730 + .detach = omap24xxcam_device_unregister, 1731 + }; 1732 + 1733 + static struct v4l2_int_device omap24xxcam = { 1734 + .module = THIS_MODULE, 1735 + .name = CAM_NAME, 1736 + .type = v4l2_int_type_master, 1737 + .u = { 1738 + .master = &omap24xxcam_master 1739 + }, 1740 + }; 1741 + 1742 + /* 1743 + * 1744 + * Driver initialisation and deinitialisation. 1745 + * 1746 + */ 1747 + 1748 + static int __init omap24xxcam_probe(struct platform_device *pdev) 1749 + { 1750 + struct omap24xxcam_device *cam; 1751 + struct resource *mem; 1752 + int irq; 1753 + 1754 + cam = kzalloc(sizeof(*cam), GFP_KERNEL); 1755 + if (!cam) { 1756 + dev_err(&pdev->dev, "could not allocate memory\n"); 1757 + goto err; 1758 + } 1759 + 1760 + platform_set_drvdata(pdev, cam); 1761 + 1762 + cam->dev = &pdev->dev; 1763 + 1764 + /* 1765 + * Impose a lower limit on the amount of memory allocated for 1766 + * capture. We require at least enough memory to double-buffer 1767 + * QVGA (300KB). 1768 + */ 1769 + if (capture_mem < 320 * 240 * 2 * 2) 1770 + capture_mem = 320 * 240 * 2 * 2; 1771 + cam->capture_mem = capture_mem; 1772 + 1773 + /* request the mem region for the camera registers */ 1774 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1775 + if (!mem) { 1776 + dev_err(cam->dev, "no mem resource?\n"); 1777 + goto err; 1778 + } 1779 + if (!request_mem_region(mem->start, (mem->end - mem->start) + 1, 1780 + pdev->name)) { 1781 + dev_err(cam->dev, 1782 + "cannot reserve camera register I/O region\n"); 1783 + goto err; 1784 + } 1785 + cam->mmio_base_phys = mem->start; 1786 + cam->mmio_size = (mem->end - mem->start) + 1; 1787 + 1788 + /* map the region */ 1789 + cam->mmio_base = (unsigned long) 1790 + ioremap_nocache(cam->mmio_base_phys, cam->mmio_size); 1791 + if (!cam->mmio_base) { 1792 + dev_err(cam->dev, "cannot map camera register I/O region\n"); 1793 + goto err; 1794 + } 1795 + 1796 + irq = platform_get_irq(pdev, 0); 1797 + if (irq <= 0) { 1798 + dev_err(cam->dev, "no irq for camera?\n"); 1799 + goto err; 1800 + } 1801 + 1802 + /* install the interrupt service routine */ 1803 + if (request_irq(irq, omap24xxcam_isr, 0, CAM_NAME, cam)) { 1804 + dev_err(cam->dev, 1805 + "could not install interrupt service routine\n"); 1806 + goto err; 1807 + } 1808 + cam->irq = irq; 1809 + 1810 + if (omap24xxcam_clock_get(cam)) 1811 + goto err; 1812 + 1813 + INIT_WORK(&cam->sensor_reset_work, omap24xxcam_sensor_reset_work); 1814 + 1815 + mutex_init(&cam->mutex); 1816 + spin_lock_init(&cam->core_enable_disable_lock); 1817 + 1818 + omap24xxcam_sgdma_init(&cam->sgdma, 1819 + cam->mmio_base + CAMDMA_REG_OFFSET, 1820 + omap24xxcam_stalled_dma_reset, 1821 + (unsigned long)cam); 1822 + 1823 + omap24xxcam.priv = cam; 1824 + 1825 + if (v4l2_int_device_register(&omap24xxcam)) 1826 + goto err; 1827 + 1828 + return 0; 1829 + 1830 + err: 1831 + omap24xxcam_remove(pdev); 1832 + return -ENODEV; 1833 + } 1834 + 1835 + static int omap24xxcam_remove(struct platform_device *pdev) 1836 + { 1837 + struct omap24xxcam_device *cam = platform_get_drvdata(pdev); 1838 + 1839 + if (!cam) 1840 + return 0; 1841 + 1842 + if (omap24xxcam.priv != NULL) 1843 + v4l2_int_device_unregister(&omap24xxcam); 1844 + omap24xxcam.priv = NULL; 1845 + 1846 + omap24xxcam_clock_put(cam); 1847 + 1848 + if (cam->irq) { 1849 + free_irq(cam->irq, cam); 1850 + cam->irq = 0; 1851 + } 1852 + 1853 + if (cam->mmio_base) { 1854 + iounmap((void *)cam->mmio_base); 1855 + cam->mmio_base = 0; 1856 + } 1857 + 1858 + if (cam->mmio_base_phys) { 1859 + release_mem_region(cam->mmio_base_phys, cam->mmio_size); 1860 + cam->mmio_base_phys = 0; 1861 + } 1862 + 1863 + kfree(cam); 1864 + 1865 + return 0; 1866 + } 1867 + 1868 + static struct platform_driver omap24xxcam_driver = { 1869 + .probe = omap24xxcam_probe, 1870 + .remove = omap24xxcam_remove, 1871 + #ifdef CONFIG_PM 1872 + .suspend = omap24xxcam_suspend, 1873 + .resume = omap24xxcam_resume, 1874 + #endif 1875 + .driver = { 1876 + .name = CAM_NAME, 1877 + .owner = THIS_MODULE, 1878 + }, 1879 + }; 1880 + 1881 + /* 1882 + * 1883 + * Module initialisation and deinitialisation 1884 + * 1885 + */ 1886 + 1887 + static int __init omap24xxcam_init(void) 1888 + { 1889 + return platform_driver_register(&omap24xxcam_driver); 1890 + } 1891 + 1892 + static void __exit omap24xxcam_cleanup(void) 1893 + { 1894 + platform_driver_unregister(&omap24xxcam_driver); 1895 + } 1896 + 1897 + MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>"); 1898 + MODULE_DESCRIPTION("OMAP24xx Video for Linux camera driver"); 1899 + MODULE_LICENSE("GPL"); 1900 + module_param(video_nr, int, 0); 1901 + MODULE_PARM_DESC(video_nr, 1902 + "Minor number for video device (-1 ==> auto assign)"); 1903 + module_param(capture_mem, int, 0); 1904 + MODULE_PARM_DESC(capture_mem, "Maximum amount of memory for capture " 1905 + "buffers (default 4800kiB)"); 1906 + 1907 + module_init(omap24xxcam_init); 1908 + module_exit(omap24xxcam_cleanup);
+593
drivers/media/video/omap24xxcam.h
··· 1 + /* 2 + * drivers/media/video/omap24xxcam.h 3 + * 4 + * Copyright (C) 2004 MontaVista Software, Inc. 5 + * Copyright (C) 2004 Texas Instruments. 6 + * Copyright (C) 2007 Nokia Corporation. 7 + * 8 + * Contact: Sakari Ailus <sakari.ailus@nokia.com> 9 + * 10 + * Based on code from Andy Lowe <source@mvista.com>. 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * version 2 as published by the Free Software Foundation. 15 + * 16 + * This program is distributed in the hope that it will be useful, but 17 + * WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 + * General Public License for more details. 20 + * 21 + * You should have received a copy of the GNU General Public License 22 + * along with this program; if not, write to the Free Software 23 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 24 + * 02110-1301 USA 25 + */ 26 + 27 + #ifndef OMAP24XXCAM_H 28 + #define OMAP24XXCAM_H 29 + 30 + #include <media/videobuf-dma-sg.h> 31 + #include <media/v4l2-int-device.h> 32 + 33 + /* 34 + * 35 + * General driver related definitions. 36 + * 37 + */ 38 + 39 + #define CAM_NAME "omap24xxcam" 40 + 41 + #define CAM_MCLK 96000000 42 + 43 + /* number of bytes transferred per DMA request */ 44 + #define DMA_THRESHOLD 32 45 + 46 + /* 47 + * NUM_CAMDMA_CHANNELS is the number of logical channels provided by 48 + * the camera DMA controller. 49 + */ 50 + #define NUM_CAMDMA_CHANNELS 4 51 + 52 + /* 53 + * NUM_SG_DMA is the number of scatter-gather DMA transfers that can 54 + * be queued. (We don't have any overlay sglists now.) 55 + */ 56 + #define NUM_SG_DMA (VIDEO_MAX_FRAME) 57 + 58 + /* 59 + * 60 + * Register definitions. 61 + * 62 + */ 63 + 64 + /* subsystem register block offsets */ 65 + #define CC_REG_OFFSET 0x00000400 66 + #define CAMDMA_REG_OFFSET 0x00000800 67 + #define CAMMMU_REG_OFFSET 0x00000C00 68 + 69 + /* define camera subsystem register offsets */ 70 + #define CAM_REVISION 0x000 71 + #define CAM_SYSCONFIG 0x010 72 + #define CAM_SYSSTATUS 0x014 73 + #define CAM_IRQSTATUS 0x018 74 + #define CAM_GPO 0x040 75 + #define CAM_GPI 0x050 76 + 77 + /* define camera core register offsets */ 78 + #define CC_REVISION 0x000 79 + #define CC_SYSCONFIG 0x010 80 + #define CC_SYSSTATUS 0x014 81 + #define CC_IRQSTATUS 0x018 82 + #define CC_IRQENABLE 0x01C 83 + #define CC_CTRL 0x040 84 + #define CC_CTRL_DMA 0x044 85 + #define CC_CTRL_XCLK 0x048 86 + #define CC_FIFODATA 0x04C 87 + #define CC_TEST 0x050 88 + #define CC_GENPAR 0x054 89 + #define CC_CCPFSCR 0x058 90 + #define CC_CCPFECR 0x05C 91 + #define CC_CCPLSCR 0x060 92 + #define CC_CCPLECR 0x064 93 + #define CC_CCPDFR 0x068 94 + 95 + /* define camera dma register offsets */ 96 + #define CAMDMA_REVISION 0x000 97 + #define CAMDMA_IRQSTATUS_L0 0x008 98 + #define CAMDMA_IRQSTATUS_L1 0x00C 99 + #define CAMDMA_IRQSTATUS_L2 0x010 100 + #define CAMDMA_IRQSTATUS_L3 0x014 101 + #define CAMDMA_IRQENABLE_L0 0x018 102 + #define CAMDMA_IRQENABLE_L1 0x01C 103 + #define CAMDMA_IRQENABLE_L2 0x020 104 + #define CAMDMA_IRQENABLE_L3 0x024 105 + #define CAMDMA_SYSSTATUS 0x028 106 + #define CAMDMA_OCP_SYSCONFIG 0x02C 107 + #define CAMDMA_CAPS_0 0x064 108 + #define CAMDMA_CAPS_2 0x06C 109 + #define CAMDMA_CAPS_3 0x070 110 + #define CAMDMA_CAPS_4 0x074 111 + #define CAMDMA_GCR 0x078 112 + #define CAMDMA_CCR(n) (0x080 + (n)*0x60) 113 + #define CAMDMA_CLNK_CTRL(n) (0x084 + (n)*0x60) 114 + #define CAMDMA_CICR(n) (0x088 + (n)*0x60) 115 + #define CAMDMA_CSR(n) (0x08C + (n)*0x60) 116 + #define CAMDMA_CSDP(n) (0x090 + (n)*0x60) 117 + #define CAMDMA_CEN(n) (0x094 + (n)*0x60) 118 + #define CAMDMA_CFN(n) (0x098 + (n)*0x60) 119 + #define CAMDMA_CSSA(n) (0x09C + (n)*0x60) 120 + #define CAMDMA_CDSA(n) (0x0A0 + (n)*0x60) 121 + #define CAMDMA_CSEI(n) (0x0A4 + (n)*0x60) 122 + #define CAMDMA_CSFI(n) (0x0A8 + (n)*0x60) 123 + #define CAMDMA_CDEI(n) (0x0AC + (n)*0x60) 124 + #define CAMDMA_CDFI(n) (0x0B0 + (n)*0x60) 125 + #define CAMDMA_CSAC(n) (0x0B4 + (n)*0x60) 126 + #define CAMDMA_CDAC(n) (0x0B8 + (n)*0x60) 127 + #define CAMDMA_CCEN(n) (0x0BC + (n)*0x60) 128 + #define CAMDMA_CCFN(n) (0x0C0 + (n)*0x60) 129 + #define CAMDMA_COLOR(n) (0x0C4 + (n)*0x60) 130 + 131 + /* define camera mmu register offsets */ 132 + #define CAMMMU_REVISION 0x000 133 + #define CAMMMU_SYSCONFIG 0x010 134 + #define CAMMMU_SYSSTATUS 0x014 135 + #define CAMMMU_IRQSTATUS 0x018 136 + #define CAMMMU_IRQENABLE 0x01C 137 + #define CAMMMU_WALKING_ST 0x040 138 + #define CAMMMU_CNTL 0x044 139 + #define CAMMMU_FAULT_AD 0x048 140 + #define CAMMMU_TTB 0x04C 141 + #define CAMMMU_LOCK 0x050 142 + #define CAMMMU_LD_TLB 0x054 143 + #define CAMMMU_CAM 0x058 144 + #define CAMMMU_RAM 0x05C 145 + #define CAMMMU_GFLUSH 0x060 146 + #define CAMMMU_FLUSH_ENTRY 0x064 147 + #define CAMMMU_READ_CAM 0x068 148 + #define CAMMMU_READ_RAM 0x06C 149 + #define CAMMMU_EMU_FAULT_AD 0x070 150 + 151 + /* Define bit fields within selected registers */ 152 + #define CAM_REVISION_MAJOR (15 << 4) 153 + #define CAM_REVISION_MAJOR_SHIFT 4 154 + #define CAM_REVISION_MINOR (15 << 0) 155 + #define CAM_REVISION_MINOR_SHIFT 0 156 + 157 + #define CAM_SYSCONFIG_SOFTRESET (1 << 1) 158 + #define CAM_SYSCONFIG_AUTOIDLE (1 << 0) 159 + 160 + #define CAM_SYSSTATUS_RESETDONE (1 << 0) 161 + 162 + #define CAM_IRQSTATUS_CC_IRQ (1 << 4) 163 + #define CAM_IRQSTATUS_MMU_IRQ (1 << 3) 164 + #define CAM_IRQSTATUS_DMA_IRQ2 (1 << 2) 165 + #define CAM_IRQSTATUS_DMA_IRQ1 (1 << 1) 166 + #define CAM_IRQSTATUS_DMA_IRQ0 (1 << 0) 167 + 168 + #define CAM_GPO_CAM_S_P_EN (1 << 1) 169 + #define CAM_GPO_CAM_CCP_MODE (1 << 0) 170 + 171 + #define CAM_GPI_CC_DMA_REQ1 (1 << 24) 172 + #define CAP_GPI_CC_DMA_REQ0 (1 << 23) 173 + #define CAP_GPI_CAM_MSTANDBY (1 << 21) 174 + #define CAP_GPI_CAM_WAIT (1 << 20) 175 + #define CAP_GPI_CAM_S_DATA (1 << 17) 176 + #define CAP_GPI_CAM_S_CLK (1 << 16) 177 + #define CAP_GPI_CAM_P_DATA (0xFFF << 3) 178 + #define CAP_GPI_CAM_P_DATA_SHIFT 3 179 + #define CAP_GPI_CAM_P_VS (1 << 2) 180 + #define CAP_GPI_CAM_P_HS (1 << 1) 181 + #define CAP_GPI_CAM_P_CLK (1 << 0) 182 + 183 + #define CC_REVISION_MAJOR (15 << 4) 184 + #define CC_REVISION_MAJOR_SHIFT 4 185 + #define CC_REVISION_MINOR (15 << 0) 186 + #define CC_REVISION_MINOR_SHIFT 0 187 + 188 + #define CC_SYSCONFIG_SIDLEMODE (3 << 3) 189 + #define CC_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3) 190 + #define CC_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3) 191 + #define CC_SYSCONFIG_SOFTRESET (1 << 1) 192 + #define CC_SYSCONFIG_AUTOIDLE (1 << 0) 193 + 194 + #define CC_SYSSTATUS_RESETDONE (1 << 0) 195 + 196 + #define CC_IRQSTATUS_FS_IRQ (1 << 19) 197 + #define CC_IRQSTATUS_LE_IRQ (1 << 18) 198 + #define CC_IRQSTATUS_LS_IRQ (1 << 17) 199 + #define CC_IRQSTATUS_FE_IRQ (1 << 16) 200 + #define CC_IRQSTATUS_FW_ERR_IRQ (1 << 10) 201 + #define CC_IRQSTATUS_FSC_ERR_IRQ (1 << 9) 202 + #define CC_IRQSTATUS_SSC_ERR_IRQ (1 << 8) 203 + #define CC_IRQSTATUS_FIFO_NOEMPTY_IRQ (1 << 4) 204 + #define CC_IRQSTATUS_FIFO_FULL_IRQ (1 << 3) 205 + #define CC_IRQSTATUS_FIFO_THR_IRQ (1 << 2) 206 + #define CC_IRQSTATUS_FIFO_OF_IRQ (1 << 1) 207 + #define CC_IRQSTATUS_FIFO_UF_IRQ (1 << 0) 208 + 209 + #define CC_IRQENABLE_FS_IRQ (1 << 19) 210 + #define CC_IRQENABLE_LE_IRQ (1 << 18) 211 + #define CC_IRQENABLE_LS_IRQ (1 << 17) 212 + #define CC_IRQENABLE_FE_IRQ (1 << 16) 213 + #define CC_IRQENABLE_FW_ERR_IRQ (1 << 10) 214 + #define CC_IRQENABLE_FSC_ERR_IRQ (1 << 9) 215 + #define CC_IRQENABLE_SSC_ERR_IRQ (1 << 8) 216 + #define CC_IRQENABLE_FIFO_NOEMPTY_IRQ (1 << 4) 217 + #define CC_IRQENABLE_FIFO_FULL_IRQ (1 << 3) 218 + #define CC_IRQENABLE_FIFO_THR_IRQ (1 << 2) 219 + #define CC_IRQENABLE_FIFO_OF_IRQ (1 << 1) 220 + #define CC_IRQENABLE_FIFO_UF_IRQ (1 << 0) 221 + 222 + #define CC_CTRL_CC_ONE_SHOT (1 << 20) 223 + #define CC_CTRL_CC_IF_SYNCHRO (1 << 19) 224 + #define CC_CTRL_CC_RST (1 << 18) 225 + #define CC_CTRL_CC_FRAME_TRIG (1 << 17) 226 + #define CC_CTRL_CC_EN (1 << 16) 227 + #define CC_CTRL_NOBT_SYNCHRO (1 << 13) 228 + #define CC_CTRL_BT_CORRECT (1 << 12) 229 + #define CC_CTRL_PAR_ORDERCAM (1 << 11) 230 + #define CC_CTRL_PAR_CLK_POL (1 << 10) 231 + #define CC_CTRL_NOBT_HS_POL (1 << 9) 232 + #define CC_CTRL_NOBT_VS_POL (1 << 8) 233 + #define CC_CTRL_PAR_MODE (7 << 1) 234 + #define CC_CTRL_PAR_MODE_SHIFT 1 235 + #define CC_CTRL_PAR_MODE_NOBT8 (0 << 1) 236 + #define CC_CTRL_PAR_MODE_NOBT10 (1 << 1) 237 + #define CC_CTRL_PAR_MODE_NOBT12 (2 << 1) 238 + #define CC_CTRL_PAR_MODE_BT8 (4 << 1) 239 + #define CC_CTRL_PAR_MODE_BT10 (5 << 1) 240 + #define CC_CTRL_PAR_MODE_FIFOTEST (7 << 1) 241 + #define CC_CTRL_CCP_MODE (1 << 0) 242 + 243 + #define CC_CTRL_DMA_EN (1 << 8) 244 + #define CC_CTRL_DMA_FIFO_THRESHOLD (0x7F << 0) 245 + #define CC_CTRL_DMA_FIFO_THRESHOLD_SHIFT 0 246 + 247 + #define CC_CTRL_XCLK_DIV (0x1F << 0) 248 + #define CC_CTRL_XCLK_DIV_SHIFT 0 249 + #define CC_CTRL_XCLK_DIV_STABLE_LOW (0 << 0) 250 + #define CC_CTRL_XCLK_DIV_STABLE_HIGH (1 << 0) 251 + #define CC_CTRL_XCLK_DIV_BYPASS (31 << 0) 252 + 253 + #define CC_TEST_FIFO_RD_POINTER (0xFF << 24) 254 + #define CC_TEST_FIFO_RD_POINTER_SHIFT 24 255 + #define CC_TEST_FIFO_WR_POINTER (0xFF << 16) 256 + #define CC_TEST_FIFO_WR_POINTER_SHIFT 16 257 + #define CC_TEST_FIFO_LEVEL (0xFF << 8) 258 + #define CC_TEST_FIFO_LEVEL_SHIFT 8 259 + #define CC_TEST_FIFO_LEVEL_PEAK (0xFF << 0) 260 + #define CC_TEST_FIFO_LEVEL_PEAK_SHIFT 0 261 + 262 + #define CC_GENPAR_FIFO_DEPTH (7 << 0) 263 + #define CC_GENPAR_FIFO_DEPTH_SHIFT 0 264 + 265 + #define CC_CCPDFR_ALPHA (0xFF << 8) 266 + #define CC_CCPDFR_ALPHA_SHIFT 8 267 + #define CC_CCPDFR_DATAFORMAT (15 << 0) 268 + #define CC_CCPDFR_DATAFORMAT_SHIFT 0 269 + #define CC_CCPDFR_DATAFORMAT_YUV422BE (0 << 0) 270 + #define CC_CCPDFR_DATAFORMAT_YUV422 (1 << 0) 271 + #define CC_CCPDFR_DATAFORMAT_YUV420 (2 << 0) 272 + #define CC_CCPDFR_DATAFORMAT_RGB444 (4 << 0) 273 + #define CC_CCPDFR_DATAFORMAT_RGB565 (5 << 0) 274 + #define CC_CCPDFR_DATAFORMAT_RGB888NDE (6 << 0) 275 + #define CC_CCPDFR_DATAFORMAT_RGB888 (7 << 0) 276 + #define CC_CCPDFR_DATAFORMAT_RAW8NDE (8 << 0) 277 + #define CC_CCPDFR_DATAFORMAT_RAW8 (9 << 0) 278 + #define CC_CCPDFR_DATAFORMAT_RAW10NDE (10 << 0) 279 + #define CC_CCPDFR_DATAFORMAT_RAW10 (11 << 0) 280 + #define CC_CCPDFR_DATAFORMAT_RAW12NDE (12 << 0) 281 + #define CC_CCPDFR_DATAFORMAT_RAW12 (13 << 0) 282 + #define CC_CCPDFR_DATAFORMAT_JPEG8 (15 << 0) 283 + 284 + #define CAMDMA_REVISION_MAJOR (15 << 4) 285 + #define CAMDMA_REVISION_MAJOR_SHIFT 4 286 + #define CAMDMA_REVISION_MINOR (15 << 0) 287 + #define CAMDMA_REVISION_MINOR_SHIFT 0 288 + 289 + #define CAMDMA_OCP_SYSCONFIG_MIDLEMODE (3 << 12) 290 + #define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY (0 << 12) 291 + #define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_NSTANDBY (1 << 12) 292 + #define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_SSTANDBY (2 << 12) 293 + #define CAMDMA_OCP_SYSCONFIG_FUNC_CLOCK (1 << 9) 294 + #define CAMDMA_OCP_SYSCONFIG_OCP_CLOCK (1 << 8) 295 + #define CAMDMA_OCP_SYSCONFIG_EMUFREE (1 << 5) 296 + #define CAMDMA_OCP_SYSCONFIG_SIDLEMODE (3 << 3) 297 + #define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3) 298 + #define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3) 299 + #define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_SIDLE (2 << 3) 300 + #define CAMDMA_OCP_SYSCONFIG_SOFTRESET (1 << 1) 301 + #define CAMDMA_OCP_SYSCONFIG_AUTOIDLE (1 << 0) 302 + 303 + #define CAMDMA_SYSSTATUS_RESETDONE (1 << 0) 304 + 305 + #define CAMDMA_GCR_ARBITRATION_RATE (0xFF << 16) 306 + #define CAMDMA_GCR_ARBITRATION_RATE_SHIFT 16 307 + #define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH (0xFF << 0) 308 + #define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH_SHIFT 0 309 + 310 + #define CAMDMA_CCR_SEL_SRC_DST_SYNC (1 << 24) 311 + #define CAMDMA_CCR_PREFETCH (1 << 23) 312 + #define CAMDMA_CCR_SUPERVISOR (1 << 22) 313 + #define CAMDMA_CCR_SECURE (1 << 21) 314 + #define CAMDMA_CCR_BS (1 << 18) 315 + #define CAMDMA_CCR_TRANSPARENT_COPY_ENABLE (1 << 17) 316 + #define CAMDMA_CCR_CONSTANT_FILL_ENABLE (1 << 16) 317 + #define CAMDMA_CCR_DST_AMODE (3 << 14) 318 + #define CAMDMA_CCR_DST_AMODE_CONST_ADDR (0 << 14) 319 + #define CAMDMA_CCR_DST_AMODE_POST_INC (1 << 14) 320 + #define CAMDMA_CCR_DST_AMODE_SGL_IDX (2 << 14) 321 + #define CAMDMA_CCR_DST_AMODE_DBL_IDX (3 << 14) 322 + #define CAMDMA_CCR_SRC_AMODE (3 << 12) 323 + #define CAMDMA_CCR_SRC_AMODE_CONST_ADDR (0 << 12) 324 + #define CAMDMA_CCR_SRC_AMODE_POST_INC (1 << 12) 325 + #define CAMDMA_CCR_SRC_AMODE_SGL_IDX (2 << 12) 326 + #define CAMDMA_CCR_SRC_AMODE_DBL_IDX (3 << 12) 327 + #define CAMDMA_CCR_WR_ACTIVE (1 << 10) 328 + #define CAMDMA_CCR_RD_ACTIVE (1 << 9) 329 + #define CAMDMA_CCR_SUSPEND_SENSITIVE (1 << 8) 330 + #define CAMDMA_CCR_ENABLE (1 << 7) 331 + #define CAMDMA_CCR_PRIO (1 << 6) 332 + #define CAMDMA_CCR_FS (1 << 5) 333 + #define CAMDMA_CCR_SYNCHRO ((3 << 19) | (31 << 0)) 334 + #define CAMDMA_CCR_SYNCHRO_CAMERA 0x01 335 + 336 + #define CAMDMA_CLNK_CTRL_ENABLE_LNK (1 << 15) 337 + #define CAMDMA_CLNK_CTRL_NEXTLCH_ID (0x1F << 0) 338 + #define CAMDMA_CLNK_CTRL_NEXTLCH_ID_SHIFT 0 339 + 340 + #define CAMDMA_CICR_MISALIGNED_ERR_IE (1 << 11) 341 + #define CAMDMA_CICR_SUPERVISOR_ERR_IE (1 << 10) 342 + #define CAMDMA_CICR_SECURE_ERR_IE (1 << 9) 343 + #define CAMDMA_CICR_TRANS_ERR_IE (1 << 8) 344 + #define CAMDMA_CICR_PACKET_IE (1 << 7) 345 + #define CAMDMA_CICR_BLOCK_IE (1 << 5) 346 + #define CAMDMA_CICR_LAST_IE (1 << 4) 347 + #define CAMDMA_CICR_FRAME_IE (1 << 3) 348 + #define CAMDMA_CICR_HALF_IE (1 << 2) 349 + #define CAMDMA_CICR_DROP_IE (1 << 1) 350 + 351 + #define CAMDMA_CSR_MISALIGNED_ERR (1 << 11) 352 + #define CAMDMA_CSR_SUPERVISOR_ERR (1 << 10) 353 + #define CAMDMA_CSR_SECURE_ERR (1 << 9) 354 + #define CAMDMA_CSR_TRANS_ERR (1 << 8) 355 + #define CAMDMA_CSR_PACKET (1 << 7) 356 + #define CAMDMA_CSR_SYNC (1 << 6) 357 + #define CAMDMA_CSR_BLOCK (1 << 5) 358 + #define CAMDMA_CSR_LAST (1 << 4) 359 + #define CAMDMA_CSR_FRAME (1 << 3) 360 + #define CAMDMA_CSR_HALF (1 << 2) 361 + #define CAMDMA_CSR_DROP (1 << 1) 362 + 363 + #define CAMDMA_CSDP_SRC_ENDIANNESS (1 << 21) 364 + #define CAMDMA_CSDP_SRC_ENDIANNESS_LOCK (1 << 20) 365 + #define CAMDMA_CSDP_DST_ENDIANNESS (1 << 19) 366 + #define CAMDMA_CSDP_DST_ENDIANNESS_LOCK (1 << 18) 367 + #define CAMDMA_CSDP_WRITE_MODE (3 << 16) 368 + #define CAMDMA_CSDP_WRITE_MODE_WRNP (0 << 16) 369 + #define CAMDMA_CSDP_WRITE_MODE_POSTED (1 << 16) 370 + #define CAMDMA_CSDP_WRITE_MODE_POSTED_LAST_WRNP (2 << 16) 371 + #define CAMDMA_CSDP_DST_BURST_EN (3 << 14) 372 + #define CAMDMA_CSDP_DST_BURST_EN_1 (0 << 14) 373 + #define CAMDMA_CSDP_DST_BURST_EN_16 (1 << 14) 374 + #define CAMDMA_CSDP_DST_BURST_EN_32 (2 << 14) 375 + #define CAMDMA_CSDP_DST_BURST_EN_64 (3 << 14) 376 + #define CAMDMA_CSDP_DST_PACKED (1 << 13) 377 + #define CAMDMA_CSDP_WR_ADD_TRSLT (15 << 9) 378 + #define CAMDMA_CSDP_WR_ADD_TRSLT_ENABLE_MREQADD (3 << 9) 379 + #define CAMDMA_CSDP_SRC_BURST_EN (3 << 7) 380 + #define CAMDMA_CSDP_SRC_BURST_EN_1 (0 << 7) 381 + #define CAMDMA_CSDP_SRC_BURST_EN_16 (1 << 7) 382 + #define CAMDMA_CSDP_SRC_BURST_EN_32 (2 << 7) 383 + #define CAMDMA_CSDP_SRC_BURST_EN_64 (3 << 7) 384 + #define CAMDMA_CSDP_SRC_PACKED (1 << 6) 385 + #define CAMDMA_CSDP_RD_ADD_TRSLT (15 << 2) 386 + #define CAMDMA_CSDP_RD_ADD_TRSLT_ENABLE_MREQADD (3 << 2) 387 + #define CAMDMA_CSDP_DATA_TYPE (3 << 0) 388 + #define CAMDMA_CSDP_DATA_TYPE_8BITS (0 << 0) 389 + #define CAMDMA_CSDP_DATA_TYPE_16BITS (1 << 0) 390 + #define CAMDMA_CSDP_DATA_TYPE_32BITS (2 << 0) 391 + 392 + #define CAMMMU_SYSCONFIG_AUTOIDLE (1 << 0) 393 + 394 + /* 395 + * 396 + * Declarations. 397 + * 398 + */ 399 + 400 + /* forward declarations */ 401 + struct omap24xxcam_sgdma; 402 + struct omap24xxcam_dma; 403 + 404 + typedef void (*sgdma_callback_t)(struct omap24xxcam_sgdma *cam, 405 + u32 status, void *arg); 406 + typedef void (*dma_callback_t)(struct omap24xxcam_dma *cam, 407 + u32 status, void *arg); 408 + 409 + struct channel_state { 410 + dma_callback_t callback; 411 + void *arg; 412 + }; 413 + 414 + /* sgdma state for each of the possible videobuf_buffers + 2 overlays */ 415 + struct sgdma_state { 416 + const struct scatterlist *sglist; 417 + int sglen; /* number of sglist entries */ 418 + int next_sglist; /* index of next sglist entry to process */ 419 + unsigned int bytes_read; /* number of bytes read */ 420 + unsigned int len; /* total length of sglist (excluding 421 + * bytes due to page alignment) */ 422 + int queued_sglist; /* number of sglist entries queued for DMA */ 423 + u32 csr; /* DMA return code */ 424 + sgdma_callback_t callback; 425 + void *arg; 426 + }; 427 + 428 + /* physical DMA channel management */ 429 + struct omap24xxcam_dma { 430 + spinlock_t lock; /* Lock for the whole structure. */ 431 + 432 + unsigned long base; /* base address for dma controller */ 433 + 434 + /* While dma_stop!=0, an attempt to start a new DMA transfer will 435 + * fail. 436 + */ 437 + atomic_t dma_stop; 438 + int free_dmach; /* number of dma channels free */ 439 + int next_dmach; /* index of next dma channel to use */ 440 + struct channel_state ch_state[NUM_CAMDMA_CHANNELS]; 441 + }; 442 + 443 + /* scatter-gather DMA (scatterlist stuff) management */ 444 + struct omap24xxcam_sgdma { 445 + struct omap24xxcam_dma dma; 446 + 447 + spinlock_t lock; /* Lock for the fields below. */ 448 + int free_sgdma; /* number of free sg dma slots */ 449 + int next_sgdma; /* index of next sg dma slot to use */ 450 + struct sgdma_state sg_state[NUM_SG_DMA]; 451 + 452 + /* Reset timer data */ 453 + struct timer_list reset_timer; 454 + }; 455 + 456 + /* per-device data structure */ 457 + struct omap24xxcam_device { 458 + /*** mutex ***/ 459 + /* 460 + * mutex serialises access to this structure. Also camera 461 + * opening and releasing is synchronised by this. 462 + */ 463 + struct mutex mutex; 464 + 465 + /*** general driver state information ***/ 466 + atomic_t users; 467 + /* 468 + * Lock to serialise core enabling and disabling and access to 469 + * sgdma_in_queue. 470 + */ 471 + spinlock_t core_enable_disable_lock; 472 + /* 473 + * Number or sgdma requests in scatter-gather queue, protected 474 + * by the lock above. 475 + */ 476 + int sgdma_in_queue; 477 + /* 478 + * Sensor interface parameters: interface type, CC_CTRL 479 + * register value and interface specific data. 480 + */ 481 + int if_type; 482 + union { 483 + struct parallel { 484 + u32 xclk; 485 + } bt656; 486 + } if_u; 487 + u32 cc_ctrl; 488 + 489 + /*** subsystem structures ***/ 490 + struct omap24xxcam_sgdma sgdma; 491 + 492 + /*** hardware resources ***/ 493 + unsigned int irq; 494 + unsigned long mmio_base; 495 + unsigned long mmio_base_phys; 496 + unsigned long mmio_size; 497 + 498 + /*** interfaces and device ***/ 499 + struct v4l2_int_device *sdev; 500 + struct device *dev; 501 + struct video_device *vfd; 502 + 503 + /*** camera and sensor reset related stuff ***/ 504 + struct work_struct sensor_reset_work; 505 + /* 506 + * We're in the middle of a reset. Don't enable core if this 507 + * is non-zero! This exists to help decisionmaking in a case 508 + * where videobuf_qbuf is called while we are in the middle of 509 + * a reset. 510 + */ 511 + atomic_t in_reset; 512 + /* 513 + * Non-zero if we don't want any resets for now. Used to 514 + * prevent reset work to run when we're about to stop 515 + * streaming. 516 + */ 517 + atomic_t reset_disable; 518 + 519 + /*** video device parameters ***/ 520 + int capture_mem; 521 + 522 + /*** camera module clocks ***/ 523 + struct clk *fck; 524 + struct clk *ick; 525 + 526 + /*** capture data ***/ 527 + /* file handle, if streaming is on */ 528 + struct file *streaming; 529 + }; 530 + 531 + /* Per-file handle data. */ 532 + struct omap24xxcam_fh { 533 + spinlock_t vbq_lock; /* spinlock for the videobuf queue */ 534 + struct videobuf_queue vbq; 535 + struct v4l2_pix_format pix; /* serialise pix by vbq->lock */ 536 + atomic_t field_count; /* field counter for videobuf_buffer */ 537 + /* accessing cam here doesn't need serialisation: it's constant */ 538 + struct omap24xxcam_device *cam; 539 + }; 540 + 541 + /* 542 + * 543 + * Register I/O functions. 544 + * 545 + */ 546 + 547 + static inline u32 omap24xxcam_reg_in(unsigned long base, u32 offset) 548 + { 549 + return readl(base + offset); 550 + } 551 + 552 + static inline u32 omap24xxcam_reg_out(unsigned long base, u32 offset, 553 + u32 val) 554 + { 555 + writel(val, base + offset); 556 + return val; 557 + } 558 + 559 + static inline u32 omap24xxcam_reg_merge(unsigned long base, u32 offset, 560 + u32 val, u32 mask) 561 + { 562 + u32 addr = base + offset; 563 + u32 new_val = (readl(addr) & ~mask) | (val & mask); 564 + 565 + writel(new_val, addr); 566 + return new_val; 567 + } 568 + 569 + /* 570 + * 571 + * Function prototypes. 572 + * 573 + */ 574 + 575 + /* dma prototypes */ 576 + 577 + void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma); 578 + void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma); 579 + 580 + /* sgdma prototypes */ 581 + 582 + void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma); 583 + int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma, 584 + const struct scatterlist *sglist, int sglen, 585 + int len, sgdma_callback_t callback, void *arg); 586 + void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma); 587 + void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma, 588 + unsigned long base, 589 + void (*reset_callback)(unsigned long data), 590 + unsigned long reset_callback_data); 591 + void omap24xxcam_sgdma_exit(struct omap24xxcam_sgdma *sgdma); 592 + 593 + #endif