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/config.h>
22 #include <linux/vmalloc.h>
23 #include <linux/slab.h>
24 #include <linux/proc_fs.h>
25 #include <linux/ctype.h>
26 #include <linux/delay.h>
27 #include <linux/device.h>
28 #include <linux/dma-mapping.h>
29 #include <linux/interrupt.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>
37 #include <asm/hardware/clock.h>
39 #include "omap16xxcam.h"
40 #include "camera_hw_if.h"
41 #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;
74 /* dma related stuff */
78 struct camdma_state camdma[NUM_CAMDMA_CHANNELS];
79 int dma_channel_number1;
80 int dma_channel_number2;
82 wait_queue_head_t vsync_wait;
86 static struct omap16xxcam hardware_data;
88 static int omap16xxcam_set_xclk(int, void *);
89 static void omap16xx_cam_dma_link_callback(int, unsigned short, void *);
91 /* Clears the camera data FIFO by setting RAZ_FIFO bit in MODE configuration
94 omap16xx_cam_clear_fifo(struct omap16xxcam *data)
96 data->camera_regs->mode |= RAZ_FIFO;
98 data->camera_regs->mode &= ~RAZ_FIFO;
102 omap16xx_cam_reset(struct omap16xxcam *data, int yes)
104 if (machine_is_omap_h3())
105 data->camera_regs->gpio = yes ? 0 : 1;
107 data->camera_regs->gpio = yes ? 1 : 0;
111 omap16xx_cam_init(void)
114 * FIXME - Use mux API's instead of directly writing in to MUX registers
116 omap_writel(omap_readl(FUNC_MUX_CTRL_4) & ~(0x1ff << 21), FUNC_MUX_CTRL_4);
117 omap_writel(0, FUNC_MUX_CTRL_5);
118 omap_writel(omap_readl(PULL_DWN_CTRL_0) & ~(0x1FFF << 17), PULL_DWN_CTRL_0);
119 omap_writel(omap_readl(PU_PD_SEL_0) & ~(0x1FFF << 17), PU_PD_SEL_0);
121 omap_writel(0xeaef, COMP_MODE_CTRL_0);
122 omap_writel(omap_readl(OMAP1610_RESET_CONTROL) & ~(1 << CONF_CAMERAIF_RESET_R),
123 OMAP1610_RESET_CONTROL);
124 omap_writel(omap_readl(OMAP1610_RESET_CONTROL) | (1 << CONF_CAMERAIF_RESET_R),
125 OMAP1610_RESET_CONTROL);
127 /* Enable peripheral reset */
128 omap_writew(omap_readw(ARM_RSTCT2) | (1 << EN_PER), ARM_RSTCT2);
130 /* enable peripheral clock */
131 if (machine_is_omap_h3())
132 clk_enable(clk_get(0, "tc2_ck"));
134 clk_enable(clk_get(0, "armper_ck"));
135 clk_enable(clk_get(0, "armxor_ck"));
140 omap16xx_cam_waitfor_syncedge(struct omap16xxcam *data, u32 edge_mask)
142 data->camera_regs->mode = (FIFO_TRIGGER_LVL << THRESHOLD_BIT) | edge_mask;
144 interruptible_sleep_on(&data->vsync_wait);
145 } while (signal_pending(current));
149 omap16xx_cam_configure_dma(struct omap16xxcam *data)
152 data->camera_regs->mode = (FIFO_TRIGGER_LVL << THRESHOLD_BIT)
153 | EN_DMA | EN_FIFO_FULL;
154 data->camera_regs->ctrlclock |= LCLK_EN;
157 /* acquire h/w resources DMA */
159 omap16xx_cam_link_open(struct omap16xxcam *data)
163 /* Acquire first dma channel */
164 if ((ret = omap_request_dma(OMAP_DMA_CAMERA_IF_RX,
165 "camera dma 1", omap16xx_cam_dma_link_callback,
166 (void *)data, &data->dma_channel_number1))) {
169 /* Acquire second dma channel */
170 if ((ret = omap_request_dma(OMAP_DMA_CAMERA_IF_RX,
171 "camera dma 2", omap16xx_cam_dma_link_callback,
172 (void *)data, &data->dma_channel_number2))) {
173 printk ("No DMA available for camera\n");
176 data->next_dmach = data->dma_channel_number1;
177 OMAP_DMA_CLNK_CTRL_REG(data->dma_channel_number1) =
178 data->dma_channel_number2;
179 OMAP_DMA_CLNK_CTRL_REG(data->dma_channel_number2) =
180 data->dma_channel_number1;
185 /* free h/w resources, stop i/f */
187 omap16xx_cam_link_close(struct omap16xxcam *data)
189 /* free dma channels */
190 omap_stop_dma(data->dma_channel_number1);
191 omap_stop_dma(data->dma_channel_number2);
193 omap_free_dma (data->dma_channel_number1);
194 omap_free_dma (data->dma_channel_number2);
199 /* dma callback routine. */
201 omap16xx_cam_dma_link_callback(int lch, unsigned short ch_status, void *data)
205 struct sgdma_state *sgdma = sgdma;
206 struct omap16xxcam *cam = (struct omap16xxcam *)data;
207 dma_callback_t callback;
209 spin_lock(&cam->dma_lock);
210 if (cam->free_dmach == 2)
212 printk("callback all CHANNELS WERE IDLE \n");
213 spin_unlock(&cam->dma_lock);
216 if (cam->free_dmach == 0) {
217 lch = cam->next_dmach;
219 lch = cam->next_dmach == cam->dma_channel_number1 ?
220 cam->dma_channel_number2 : cam->dma_channel_number1;
223 while (cam->free_dmach < 2)
225 if (OMAP_DMA_CCR_REG(lch) & (1 << 7))
228 count = (lch == cam->dma_channel_number2) ? 1 : 0;
230 callback = cam->camdma[count].callback;
231 arg1 = cam->camdma[count].arg1;
232 arg2 = cam->camdma[count].arg2;
235 spin_unlock(&cam->dma_lock);
236 callback(arg1, arg2);
237 spin_lock(&cam->dma_lock);
239 lch = (lch == cam->dma_channel_number2) ? cam->dma_channel_number1 :
240 cam->dma_channel_number2;
242 spin_unlock(&cam->dma_lock);
247 omap16xx_cam_isr(int irq, void *client_data, struct pt_regs *regs)
249 struct omap16xxcam *data = (struct omap16xxcam *)client_data;
250 unsigned int itstat = data->camera_regs->it_status;
252 /* VSYNC UP interrupt, start filling FIFO and enabling DMA */
254 data->camera_regs->mode &= ~EN_V_UP;
255 omap16xx_cam_clear_fifo(data);
256 omap16xx_cam_configure_dma(data);
257 omap_start_dma(data->next_dmach);
258 wake_up_interruptible(&data->vsync_wait);
261 if (itstat & V_DOWN) {
262 data->camera_regs->mode &= ~EN_V_DOWN;
263 wake_up_interruptible(&data->vsync_wait);
272 if (itstat & FIFO_FULL) {
273 omap16xx_cam_clear_fifo(data);
274 printk("FIFO_FULL\n");
277 if (itstat & DATA_XFER)
278 printk("DATA_TRANS\n");
283 /* ------------- below are interface functions ----------------- */
284 /* ------------- these functions are named omap16xxcam_<name> -- */
286 omap16xxcam_init_dma(void *priv)
289 struct omap16xxcam *data = (struct omap16xxcam *) priv;
291 data->free_dmach = 2;
292 for (ch = 0; ch < 2; ++ch) {
293 data->camdma[ch].callback = NULL;
294 data->camdma[ch].arg1 = NULL;
295 data->camdma[ch].arg2 = NULL;
301 /* start the dma of chains */
303 omap16xxcam_start_dma(struct sgdma_state *sgdma,
304 dma_callback_t callback, void *arg1, void *arg2, void *priv)
306 struct omap16xxcam *data = (struct omap16xxcam *) priv;
307 struct scatterlist *sglist;
308 unsigned long irqflags;
313 spin_lock_irqsave(&data->dma_lock, irqflags);
314 sglist = (struct scatterlist *)(sgdma->sglist + sgdma->next_sglist);
316 if (!data->free_dmach) {
317 spin_unlock_irqrestore(&data->dma_lock, irqflags);
320 dmach = data->next_dmach;
321 count = (dmach == data->dma_channel_number2) ? 1:0;
322 data->camdma[count].callback = callback;
323 data->camdma[count].arg1 = arg1;
324 data->camdma[count].arg2 = arg2;
326 if (machine_is_omap_h3())
327 omap_set_dma_src_params(dmach, OMAP_DMA_PORT_OCP_T1,
328 OMAP_DMA_AMODE_CONSTANT, CAM_CAMDATA_REG,
331 omap_set_dma_src_params(dmach, OMAP_DMA_PORT_TIPB,
332 OMAP_DMA_AMODE_CONSTANT, CAM_CAMDATA_REG,
335 omap_set_dma_dest_params(dmach, OMAP_DMA_PORT_EMIFF,
336 OMAP_DMA_AMODE_POST_INC, sg_dma_address(sglist),
339 omap_set_dma_transfer_params(dmach, OMAP_DMA_DATA_TYPE_S32,
341 sg_dma_len(sglist)/(4 * FIFO_TRIGGER_LVL),
345 OMAP_DMA_CLNK_CTRL_REG(dmach) &= ~( 1<< 15);
347 prev_dmach = (dmach == data->dma_channel_number2) ?
348 data->dma_channel_number1 : data->dma_channel_number2;
352 omap16xx_cam_waitfor_syncedge(data, EN_V_UP);
354 if (OMAP_DMA_CCR_REG(prev_dmach) & (1 << 7))
355 OMAP_DMA_CLNK_CTRL_REG(prev_dmach) |= (1 << 15);
357 /* no transfer is in progress */
358 omap_start_dma(dmach);
362 data->next_dmach = prev_dmach;
364 spin_unlock_irqrestore(&data->dma_lock, irqflags);
368 omap16xxcam_finish_dma(void *priv)
370 struct omap16xxcam *data = (struct omap16xxcam *) priv;
372 while (data->free_dmach < 2)
379 /* Enables the camera. Takes camera out of reset. Enables the clocks. */
381 omap16xxcam_enable(void *priv)
383 struct omap16xxcam *data = (struct omap16xxcam *) priv;
385 omap16xx_cam_reset(data, 1);
387 /* give clock to camera_module */
388 data->camera_regs->mode = (FIFO_TRIGGER_LVL << THRESHOLD_BIT);
389 data->camera_regs->ctrlclock = MCLK_EN | CAMEXCLK_EN;
391 omap16xx_cam_clear_fifo(data);
393 /* wait for camera to settle down */
399 /* Disables all the camera clocks. Put the camera interface in reset. */
401 omap16xxcam_disable(void *priv)
403 struct omap16xxcam *data = (struct omap16xxcam *) priv;
405 omap16xx_cam_clear_fifo(data);
407 data->camera_regs->ctrlclock = 0x00000000;
408 data->camera_regs->mode = 0x00000000;
410 omap16xx_cam_reset(data, 0);
415 /* Abort the data transfer */
417 omap16xxcam_abort(void *priv)
419 return omap16xxcam_disable(priv);
423 omap16xxcam_set_xclk(int xclk, void *priv)
425 struct omap16xxcam *data = (struct omap16xxcam *) priv;
428 divisor = data->ocp_clk/xclk;
429 if ( divisor * xclk < data->ocp_clk)
435 xclk_val = FOSCMOD_TC2_CK2;
438 xclk_val = FOSCMOD_TC2_CK3;
444 xclk_val = FOSCMOD_TC2_CK4;
448 xclk_val = FOSCMOD_TC2_CK8;
452 xclk_val = FOSCMOD_TC2_CK10;
458 xclk_val = FOSCMOD_TC2_CK12;
461 xclk_val = FOSCMOD_TC2_CK16;
464 xclk_val = FOSCMOD_TC2_CK16;
467 /* follow the protocol to change the XCLK clock */
468 data->camera_regs->ctrlclock &= ~CAMEXCLK_EN;
469 data->camera_regs->ctrlclock |= xclk_val;
470 data->camera_regs->ctrlclock |= CAMEXCLK_EN;
472 return (data->ocp_clk/divisor);
476 omap16xxcam_open(void *priv)
478 struct omap16xxcam *data = (struct omap16xxcam *) priv;
481 if ((ret = request_irq(INT_CAMERA, omap16xx_cam_isr, SA_INTERRUPT,
483 printk("FAILED to aquire irq\n");
488 omap16xxcam_enable(data);
489 omap16xxcam_init_dma(data);
491 return omap16xx_cam_link_open(data);
495 omap16xxcam_close(void *priv)
497 struct omap16xxcam *data = (struct omap16xxcam *) priv;
499 omap16xxcam_disable(priv);
501 free_irq(INT_CAMERA, data);
503 return omap16xx_cam_link_close(data);
507 omap16xxcam_cleanup(void *priv)
509 struct omap16xxcam *data = (struct omap16xxcam *) priv;
511 omap16xxcam_disable(data);
512 if (machine_is_omap_h3()) {
513 if (data->camera_regs) {
514 iounmap((void *)data->camera_regs);
515 data->camera_regs= NULL;
519 if (data->iobase_phys) {
520 release_mem_region(data->iobase_phys, CAMERA_IOSIZE);
521 data->iobase_phys = 0;
527 /* Initialise the OMAP camera interface */
529 omap16xxcam_init(void)
531 unsigned long cam_iobase;
533 if (!request_region(CAMERA_BASE, CAMERA_IOSIZE, "OAMP16xx Camera")) {
534 printk ("OMAP16XX Parallel Camera Interface is already in use\n");
538 if (machine_is_omap_h3()) {
539 cam_iobase = (unsigned long) ioremap (CAMERA_BASE, CAMERA_IOSIZE);
541 printk("CANNOT MAP CAMERA REGISTER\n");
546 cam_iobase = io_p2v(CAMERA_BASE);
548 /* Set the base address of the camera registers */
549 hardware_data.camera_regs = (camera_regs_t *)cam_iobase;
550 hardware_data.iobase_phys = (unsigned long) CAMERA_BASE;
551 /* get the input clock value to camera interface and store it */
552 if (machine_is_omap_h3())
553 hardware_data.ocp_clk = clk_get_rate(clk_get(0, "tc_ck"));
555 hardware_data.ocp_clk = clk_get_rate(clk_get(0, "mpuper_ck"));
557 /* Init the camera IF */
559 /* enable it. This is needed for sensor detection */
560 omap16xxcam_enable((void*)&hardware_data);
562 spin_lock_init(&hardware_data.dma_lock);
564 init_waitqueue_head(&hardware_data.vsync_wait);
565 return (void*)&hardware_data;
568 struct camera_hardware camera_hardware_if = {
570 name : "OMAP16xx Camera Parallel",
571 init : omap16xxcam_init,
572 cleanup : omap16xxcam_cleanup,
573 open : omap16xxcam_open,
574 close : omap16xxcam_close,
575 enable : omap16xxcam_enable,
576 disable : omap16xxcam_disable,
577 abort : omap16xxcam_abort,
578 set_xclk : omap16xxcam_set_xclk,
579 init_dma : omap16xxcam_init_dma,
580 start_dma : omap16xxcam_start_dma,
581 finish_dma : omap16xxcam_finish_dma,