2 * drivers/media/video/omap/omap16xxcam.c
4 * Copyright (C) 2004 Texas Instruments, Inc.
6 * Video-for-Linux (Version 2) camera capture driver for
7 * the OMAP H2 and H3 camera controller.
9 * leverage some code from CEE distribution
10 * Copyright (C) 2003-2004 MontaVista Software, Inc.
12 * This package is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
16 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 #include <linux/vmalloc.h>
22 #include <linux/slab.h>
23 #include <linux/proc_fs.h>
24 #include <linux/ctype.h>
25 #include <linux/delay.h>
26 #include <linux/device.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/interrupt.h>
29 #include <linux/clk.h>
31 #include <asm/arch/irqs.h>
32 #include <asm/arch/dma.h>
33 #include <asm/arch/hardware.h>
35 #include <asm/scatterlist.h>
36 #include <asm/mach-types.h>
38 #include "omap16xxcam.h"
39 #include "camera_hw_if.h"
40 #include "camera_core.h"
43 #define CONF_CAMERAIF_RESET_R 5
46 /* NUM_CAMDMA_CHANNELS is the number of logical channels used for
49 #define NUM_CAMDMA_CHANNELS 2
52 unsigned int ctrlclock; /* 00 */
53 unsigned int it_status; /* 04 */
54 unsigned int mode; /* 08 */
55 unsigned int status; /* 0C */
56 unsigned int camdata; /* 10 */
57 unsigned int gpio; /* 14 */
58 unsigned int peak_counter; /* 18 */
62 dma_callback_t callback;
68 camera_regs_t *camera_regs;
69 unsigned long iobase_phys;
71 /* frequncy (in Hz) of camera interface functional clock (ocp_clk) */
72 unsigned long ocp_clk;
76 /* dma related stuff */
80 struct camdma_state camdma[NUM_CAMDMA_CHANNELS];
81 int dma_channel_number1;
82 int dma_channel_number2;
84 wait_queue_head_t vsync_wait;
88 static struct omap16xxcam hardware_data;
90 static int omap16xxcam_set_xclk(int, void *);
91 static void omap16xx_cam_dma_link_callback(int, unsigned short, void *);
93 /* Clears the camera data FIFO by setting RAZ_FIFO bit in MODE configuration
96 omap16xx_cam_clear_fifo(struct omap16xxcam *data)
98 data->camera_regs->mode |= RAZ_FIFO;
100 data->camera_regs->mode &= ~RAZ_FIFO;
104 omap16xx_cam_reset(struct omap16xxcam *data, int yes)
106 if (machine_is_omap_h3())
107 data->camera_regs->gpio = yes ? 0 : 1;
109 data->camera_regs->gpio = yes ? 1 : 0;
113 omap16xx_cam_init(void)
116 * FIXME - Use mux API's instead of directly writing in to MUX registers
118 omap_writel(omap_readl(FUNC_MUX_CTRL_4) & ~(0x1ff << 21), FUNC_MUX_CTRL_4);
119 omap_writel(0, FUNC_MUX_CTRL_5);
120 omap_writel(omap_readl(PULL_DWN_CTRL_0) & ~(0x1FFF << 17), PULL_DWN_CTRL_0);
121 omap_writel(omap_readl(PU_PD_SEL_0) & ~(0x1FFF << 17), PU_PD_SEL_0);
123 omap_writel(0xeaef, COMP_MODE_CTRL_0);
124 omap_writel(omap_readl(OMAP1610_RESET_CONTROL) & ~(1 << CONF_CAMERAIF_RESET_R),
125 OMAP1610_RESET_CONTROL);
126 omap_writel(omap_readl(OMAP1610_RESET_CONTROL) | (1 << CONF_CAMERAIF_RESET_R),
127 OMAP1610_RESET_CONTROL);
129 /* Enable peripheral reset */
130 omap_writew(omap_readw(ARM_RSTCT2) | (1 << EN_PER), ARM_RSTCT2);
132 /* enable peripheral clock */
133 clk_enable(hardware_data.func_clk);
137 omap16xx_cam_waitfor_syncedge(struct omap16xxcam *data, u32 edge_mask)
139 data->camera_regs->mode = (FIFO_TRIGGER_LVL << THRESHOLD_BIT) | edge_mask;
141 interruptible_sleep_on(&data->vsync_wait);
142 } while (signal_pending(current));
146 omap16xx_cam_configure_dma(struct omap16xxcam *data)
149 data->camera_regs->mode = (FIFO_TRIGGER_LVL << THRESHOLD_BIT)
150 | EN_DMA | EN_FIFO_FULL;
151 data->camera_regs->ctrlclock |= LCLK_EN;
154 /* acquire h/w resources DMA */
156 omap16xx_cam_link_open(struct omap16xxcam *data)
160 /* Acquire first dma channel */
161 if ((ret = omap_request_dma(OMAP_DMA_CAMERA_IF_RX,
162 "camera dma 1", omap16xx_cam_dma_link_callback,
163 (void *)data, &data->dma_channel_number1))) {
166 /* Acquire second dma channel */
167 if ((ret = omap_request_dma(OMAP_DMA_CAMERA_IF_RX,
168 "camera dma 2", omap16xx_cam_dma_link_callback,
169 (void *)data, &data->dma_channel_number2))) {
170 printk ("No DMA available for camera\n");
173 data->next_dmach = data->dma_channel_number1;
174 OMAP_DMA_CLNK_CTRL_REG(data->dma_channel_number1) =
175 data->dma_channel_number2;
176 OMAP_DMA_CLNK_CTRL_REG(data->dma_channel_number2) =
177 data->dma_channel_number1;
182 /* free h/w resources, stop i/f */
184 omap16xx_cam_link_close(struct omap16xxcam *data)
186 /* free dma channels */
187 omap_stop_dma(data->dma_channel_number1);
188 omap_stop_dma(data->dma_channel_number2);
190 omap_free_dma (data->dma_channel_number1);
191 omap_free_dma (data->dma_channel_number2);
196 /* dma callback routine. */
198 omap16xx_cam_dma_link_callback(int lch, unsigned short ch_status, void *data)
202 struct sgdma_state *sgdma = sgdma;
203 struct omap16xxcam *cam = (struct omap16xxcam *)data;
204 dma_callback_t callback;
206 spin_lock(&cam->dma_lock);
207 if (cam->free_dmach == 2)
209 printk("callback all CHANNELS WERE IDLE \n");
210 spin_unlock(&cam->dma_lock);
213 if (cam->free_dmach == 0) {
214 lch = cam->next_dmach;
216 lch = cam->next_dmach == cam->dma_channel_number1 ?
217 cam->dma_channel_number2 : cam->dma_channel_number1;
220 while (cam->free_dmach < 2)
222 if (OMAP_DMA_CCR_REG(lch) & (1 << 7))
225 count = (lch == cam->dma_channel_number2) ? 1 : 0;
227 callback = cam->camdma[count].callback;
228 arg1 = cam->camdma[count].arg1;
229 arg2 = cam->camdma[count].arg2;
232 spin_unlock(&cam->dma_lock);
233 callback(arg1, arg2);
234 spin_lock(&cam->dma_lock);
236 lch = (lch == cam->dma_channel_number2) ? cam->dma_channel_number1 :
237 cam->dma_channel_number2;
239 spin_unlock(&cam->dma_lock);
244 omap16xx_cam_isr(int irq, void *client_data)
246 struct omap16xxcam *data = (struct omap16xxcam *)client_data;
247 unsigned int itstat = data->camera_regs->it_status;
249 /* VSYNC UP interrupt, start filling FIFO and enabling DMA */
251 data->camera_regs->mode &= ~EN_V_UP;
252 omap16xx_cam_clear_fifo(data);
253 omap16xx_cam_configure_dma(data);
254 omap_start_dma(data->next_dmach);
255 wake_up_interruptible(&data->vsync_wait);
258 if (itstat & V_DOWN) {
259 data->camera_regs->mode &= ~EN_V_DOWN;
260 wake_up_interruptible(&data->vsync_wait);
269 if (itstat & FIFO_FULL) {
270 omap16xx_cam_clear_fifo(data);
271 printk("FIFO_FULL\n");
274 if (itstat & DATA_XFER)
275 printk("DATA_TRANS\n");
280 /* ------------- below are interface functions ----------------- */
281 /* ------------- these functions are named omap16xxcam_<name> -- */
283 omap16xxcam_init_dma(void *priv)
286 struct omap16xxcam *data = (struct omap16xxcam *) priv;
288 data->free_dmach = 2;
289 for (ch = 0; ch < 2; ++ch) {
290 data->camdma[ch].callback = NULL;
291 data->camdma[ch].arg1 = NULL;
292 data->camdma[ch].arg2 = NULL;
298 /* start the dma of chains */
300 omap16xxcam_start_dma(struct sgdma_state *sgdma,
301 dma_callback_t callback, void *arg1, void *arg2, void *priv)
303 struct omap16xxcam *data = (struct omap16xxcam *) priv;
304 struct scatterlist *sglist;
305 unsigned long irqflags;
310 spin_lock_irqsave(&data->dma_lock, irqflags);
311 sglist = (struct scatterlist *)(sgdma->sglist + sgdma->next_sglist);
313 if (!data->free_dmach) {
314 spin_unlock_irqrestore(&data->dma_lock, irqflags);
317 dmach = data->next_dmach;
318 count = (dmach == data->dma_channel_number2) ? 1:0;
319 data->camdma[count].callback = callback;
320 data->camdma[count].arg1 = arg1;
321 data->camdma[count].arg2 = arg2;
323 if (cpu_is_omap1710())
324 omap_set_dma_src_params(dmach, OMAP_DMA_PORT_OCP_T1,
325 OMAP_DMA_AMODE_CONSTANT, CAM_CAMDATA_REG,
328 omap_set_dma_src_params(dmach, OMAP_DMA_PORT_TIPB,
329 OMAP_DMA_AMODE_CONSTANT, CAM_CAMDATA_REG,
332 omap_set_dma_dest_params(dmach, OMAP_DMA_PORT_EMIFF,
333 OMAP_DMA_AMODE_POST_INC, sg_dma_address(sglist),
336 omap_set_dma_transfer_params(dmach, OMAP_DMA_DATA_TYPE_S32,
338 sg_dma_len(sglist)/(4 * FIFO_TRIGGER_LVL),
342 OMAP_DMA_CLNK_CTRL_REG(dmach) &= ~( 1<< 15);
344 prev_dmach = (dmach == data->dma_channel_number2) ?
345 data->dma_channel_number1 : data->dma_channel_number2;
349 omap16xx_cam_waitfor_syncedge(data, EN_V_UP);
351 if (OMAP_DMA_CCR_REG(prev_dmach) & (1 << 7))
352 OMAP_DMA_CLNK_CTRL_REG(prev_dmach) |= (1 << 15);
354 /* no transfer is in progress */
355 omap_start_dma(dmach);
359 data->next_dmach = prev_dmach;
361 spin_unlock_irqrestore(&data->dma_lock, irqflags);
365 omap16xxcam_finish_dma(void *priv)
367 struct omap16xxcam *data = (struct omap16xxcam *) priv;
369 while (data->free_dmach < 2)
376 /* Enables the camera. Takes camera out of reset. Enables the clocks. */
378 omap16xxcam_enable(void *priv)
380 struct omap16xxcam *data = (struct omap16xxcam *) priv;
382 omap16xx_cam_reset(data, 1);
384 /* give clock to camera_module */
385 data->camera_regs->mode = (FIFO_TRIGGER_LVL << THRESHOLD_BIT);
386 data->camera_regs->ctrlclock = MCLK_EN | CAMEXCLK_EN;
388 omap16xx_cam_clear_fifo(data);
390 /* wait for camera to settle down */
396 /* Disables all the camera clocks. Put the camera interface in reset. */
398 omap16xxcam_disable(void *priv)
400 struct omap16xxcam *data = (struct omap16xxcam *) priv;
402 omap16xx_cam_clear_fifo(data);
404 data->camera_regs->ctrlclock = 0x00000000;
405 data->camera_regs->mode = 0x00000000;
407 omap16xx_cam_reset(data, 0);
412 /* Abort the data transfer */
414 omap16xxcam_abort(void *priv)
416 return omap16xxcam_disable(priv);
420 omap16xxcam_set_xclk(int xclk, void *priv)
422 struct omap16xxcam *data = (struct omap16xxcam *) priv;
425 divisor = data->ocp_clk/xclk;
426 if ( divisor * xclk < data->ocp_clk)
432 xclk_val = FOSCMOD_TC2_CK2;
435 xclk_val = FOSCMOD_TC2_CK3;
441 xclk_val = FOSCMOD_TC2_CK4;
445 xclk_val = FOSCMOD_TC2_CK8;
449 xclk_val = FOSCMOD_TC2_CK10;
455 xclk_val = FOSCMOD_TC2_CK12;
458 xclk_val = FOSCMOD_TC2_CK16;
461 xclk_val = FOSCMOD_TC2_CK16;
464 /* follow the protocol to change the XCLK clock */
465 data->camera_regs->ctrlclock &= ~CAMEXCLK_EN;
466 data->camera_regs->ctrlclock |= xclk_val;
467 data->camera_regs->ctrlclock |= CAMEXCLK_EN;
469 return (data->ocp_clk/divisor);
473 omap16xxcam_open(void *priv)
475 struct omap16xxcam *data = (struct omap16xxcam *) priv;
478 if ((ret = request_irq(INT_CAMERA, omap16xx_cam_isr, SA_INTERRUPT,
480 printk("FAILED to aquire irq\n");
485 omap16xxcam_enable(data);
486 omap16xxcam_init_dma(data);
488 return omap16xx_cam_link_open(data);
492 omap16xxcam_close(void *priv)
494 struct omap16xxcam *data = (struct omap16xxcam *) priv;
496 omap16xxcam_disable(priv);
498 free_irq(INT_CAMERA, data);
500 return omap16xx_cam_link_close(data);
504 omap16xxcam_cleanup(void *priv)
506 struct omap16xxcam *data = (struct omap16xxcam *) priv;
508 if (!data->camera_regs)
511 omap16xxcam_disable(data);
512 if (cpu_is_omap1710())
513 iounmap((void *)data->camera_regs);
514 data->camera_regs= NULL;
516 if (data->iobase_phys) {
517 release_mem_region(data->iobase_phys, CAMERA_IOSIZE);
518 data->iobase_phys = 0;
521 if (hardware_data.func_clk) {
522 clk_disable(hardware_data.func_clk);
523 clk_put(hardware_data.func_clk);
524 hardware_data.func_clk = NULL;
530 /* Initialise the OMAP camera interface */
532 omap16xxcam_init(void)
534 unsigned long cam_iobase;
536 if (!request_mem_region(CAMERA_BASE, CAMERA_IOSIZE,
537 camera_hardware_if.name)) {
538 pr_debug("%s is already in use\n", camera_hardware_if.name);
542 if (cpu_is_omap1710()) {
543 cam_iobase = (unsigned long) ioremap (CAMERA_BASE,
546 printk("CANNOT MAP CAMERA REGISTER\n");
551 cam_iobase = io_p2v(CAMERA_BASE);
553 /* Set the base address of the camera registers */
554 hardware_data.camera_regs = (camera_regs_t *)cam_iobase;
555 hardware_data.iobase_phys = (unsigned long) CAMERA_BASE;
557 /* get the input clock value to camera interface and store it */
558 if (cpu_is_omap1710())
559 hardware_data.func_clk = clk_get(0, "tc2_ck");
561 hardware_data.func_clk = clk_get(0, "armper_ck");
562 hardware_data.ocp_clk = clk_get_rate(hardware_data.func_clk);
564 /* Init the camera IF */
566 /* enable it. This is needed for sensor detection */
567 omap16xxcam_enable((void*)&hardware_data);
569 spin_lock_init(&hardware_data.dma_lock);
571 init_waitqueue_head(&hardware_data.vsync_wait);
572 return (void*)&hardware_data;
575 struct camera_hardware camera_hardware_if = {
577 .name = "OMAP16xx Parallel Camera",
578 .init = omap16xxcam_init,
579 .cleanup = omap16xxcam_cleanup,
580 .open = omap16xxcam_open,
581 .close = omap16xxcam_close,
582 .enable = omap16xxcam_enable,
583 .disable = omap16xxcam_disable,
584 .abort = omap16xxcam_abort,
585 .set_xclk = omap16xxcam_set_xclk,
586 .init_dma = omap16xxcam_init_dma,
587 .start_dma = omap16xxcam_start_dma,
588 .finish_dma = omap16xxcam_finish_dma,