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"
42 #define CONF_CAMERAIF_RESET_R 5
45 /* NUM_CAMDMA_CHANNELS is the number of logical channels used for
48 #define NUM_CAMDMA_CHANNELS 2
51 unsigned int ctrlclock; /* 00 */
52 unsigned int it_status; /* 04 */
53 unsigned int mode; /* 08 */
54 unsigned int status; /* 0C */
55 unsigned int camdata; /* 10 */
56 unsigned int gpio; /* 14 */
57 unsigned int peak_counter; /* 18 */
61 dma_callback_t callback;
67 camera_regs_t *camera_regs;
68 unsigned long iobase_phys;
70 /* Frequency (in Hz) of camera interface functional clock (ocp_clk) */
71 unsigned long ocp_clk;
75 /* DMA related stuff */
79 struct camdma_state camdma[NUM_CAMDMA_CHANNELS];
80 int dma_channel_number1;
81 int dma_channel_number2;
83 wait_queue_head_t vsync_wait;
87 static struct omap16xxcam hardware_data;
89 static int omap16xxcam_set_xclk(int, void *);
90 static void omap16xx_cam_dma_link_callback(int, unsigned short, void *);
92 /* Clears the camera data FIFO by setting RAZ_FIFO bit in MODE configuration
95 static void omap16xx_cam_clear_fifo(struct omap16xxcam *data)
97 data->camera_regs->mode |= RAZ_FIFO;
99 data->camera_regs->mode &= ~RAZ_FIFO;
102 static void 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;
110 static void omap16xx_cam_init(void)
113 * FIXME - Use mux API's instead of directly writing in to MUX registers
115 omap_writel(omap_readl(FUNC_MUX_CTRL_4) & ~(0x1ff << 21),
117 omap_writel(0, FUNC_MUX_CTRL_5);
118 omap_writel(omap_readl(PULL_DWN_CTRL_0) & ~(0x1FFF << 17),
120 omap_writel(omap_readl(PU_PD_SEL_0) & ~(0x1FFF << 17), PU_PD_SEL_0);
122 omap_writel(0xeaef, COMP_MODE_CTRL_0);
123 omap_writel(omap_readl(OMAP1610_RESET_CONTROL) &
124 ~(1 << CONF_CAMERAIF_RESET_R), OMAP1610_RESET_CONTROL);
125 omap_writel(omap_readl(OMAP1610_RESET_CONTROL) |
126 (1 << CONF_CAMERAIF_RESET_R), OMAP1610_RESET_CONTROL);
128 /* Enable peripheral reset */
129 omap_writew(omap_readw(ARM_RSTCT2) | (1 << EN_PER), ARM_RSTCT2);
131 /* Enable peripheral clock */
132 clk_enable(hardware_data.func_clk);
135 static void omap16xx_cam_waitfor_syncedge(struct omap16xxcam *data,
138 data->camera_regs->mode =
139 (FIFO_TRIGGER_LVL << THRESHOLD_BIT) | edge_mask;
141 interruptible_sleep_on(&data->vsync_wait);
142 } while (signal_pending(current));
145 static void omap16xx_cam_configure_dma(struct omap16xxcam *data)
148 data->camera_regs->mode = (FIFO_TRIGGER_LVL << THRESHOLD_BIT)
149 | EN_DMA | EN_FIFO_FULL;
150 data->camera_regs->ctrlclock |= LCLK_EN;
153 /* Acquire h/w resources DMA */
154 static int omap16xx_cam_link_open(struct omap16xxcam *data)
158 /* Acquire first DMA channel */
159 ret = omap_request_dma(OMAP_DMA_CAMERA_IF_RX,
161 omap16xx_cam_dma_link_callback,
162 (void *)data, &data->dma_channel_number1);
166 /* Acquire second DMA channel */
167 ret = omap_request_dma(OMAP_DMA_CAMERA_IF_RX,
169 omap16xx_cam_dma_link_callback,
170 (void *)data, &data->dma_channel_number2);
172 printk(KERN_ERR "No DMA available for camera\n");
175 data->next_dmach = data->dma_channel_number1;
176 OMAP_DMA_CLNK_CTRL_REG(data->dma_channel_number1) =
177 data->dma_channel_number2;
178 OMAP_DMA_CLNK_CTRL_REG(data->dma_channel_number2) =
179 data->dma_channel_number1;
184 /* Free h/w resources, stop i/f */
185 static int omap16xx_cam_link_close(struct omap16xxcam *data)
187 /* Free DMA channels */
188 omap_stop_dma(data->dma_channel_number1);
189 omap_stop_dma(data->dma_channel_number2);
191 omap_free_dma(data->dma_channel_number1);
192 omap_free_dma(data->dma_channel_number2);
197 /* DMA callback routine. */
198 static void omap16xx_cam_dma_link_callback(int lch, unsigned short ch_status,
203 struct sgdma_state *sgdma = sgdma;
204 struct omap16xxcam *cam = (struct omap16xxcam *)data;
205 dma_callback_t callback;
207 spin_lock(&cam->dma_lock);
208 if (cam->free_dmach == 2) {
209 printk(KERN_ERR "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) {
221 if (OMAP_DMA_CCR_REG(lch) & (1 << 7))
224 count = (lch == cam->dma_channel_number2) ? 1 : 0;
226 callback = cam->camdma[count].callback;
227 arg1 = cam->camdma[count].arg1;
228 arg2 = cam->camdma[count].arg2;
231 spin_unlock(&cam->dma_lock);
232 callback(arg1, arg2);
233 spin_lock(&cam->dma_lock);
237 cam->dma_channel_number2) ? cam->
238 dma_channel_number1 : cam->dma_channel_number2;
240 spin_unlock(&cam->dma_lock);
244 static irqreturn_t 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);
264 printk(KERN_INFO "H_UP\n");
267 printk(KERN_INFO "H_DOWN\n");
269 if (itstat & FIFO_FULL) {
270 omap16xx_cam_clear_fifo(data);
271 printk(KERN_INFO "FIFO_FULL\n");
274 if (itstat & DATA_XFER)
275 printk(KERN_INFO "DATA_TRANS\n");
280 /* ------------- Below are interface functions -----------------
281 * ------------- These functions are named omap16xxcam_<name> --
283 static int 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 */
299 static int omap16xxcam_start_dma(struct sgdma_state *sgdma,
300 dma_callback_t callback, void *arg1,
301 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,
326 CAM_CAMDATA_REG, 0, 0);
328 omap_set_dma_src_params(dmach, OMAP_DMA_PORT_TIPB,
329 OMAP_DMA_AMODE_CONSTANT,
330 CAM_CAMDATA_REG, 0, 0);
332 omap_set_dma_dest_params(dmach, OMAP_DMA_PORT_EMIFF,
333 OMAP_DMA_AMODE_POST_INC,
334 sg_dma_address(sglist), 0, 0);
336 omap_set_dma_transfer_params(dmach, OMAP_DMA_DATA_TYPE_S32,
338 sg_dma_len(sglist) / (4 *
340 OMAP_DMA_SYNC_FRAME, 0, 0);
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 int static omap16xxcam_finish_dma(void *priv)
367 struct omap16xxcam *data = (struct omap16xxcam *)priv;
369 while (data->free_dmach < 2)
375 /* Enables the camera. Takes camera out of reset. Enables the clocks. */
376 static int omap16xxcam_enable(void *priv)
378 struct omap16xxcam *data = (struct omap16xxcam *)priv;
380 omap16xx_cam_reset(data, 1);
382 /* Give clock to camera_module */
383 data->camera_regs->mode = (FIFO_TRIGGER_LVL << THRESHOLD_BIT);
384 data->camera_regs->ctrlclock = MCLK_EN | CAMEXCLK_EN;
386 omap16xx_cam_clear_fifo(data);
388 /* Wait for camera to settle down */
394 /* Disables all the camera clocks. Put the camera interface in reset. */
395 static int omap16xxcam_disable(void *priv)
397 struct omap16xxcam *data = (struct omap16xxcam *)priv;
399 omap16xx_cam_clear_fifo(data);
401 data->camera_regs->ctrlclock = 0x00000000;
402 data->camera_regs->mode = 0x00000000;
404 omap16xx_cam_reset(data, 0);
409 /* Abort the data transfer */
410 static int omap16xxcam_abort(void *priv)
412 return omap16xxcam_disable(priv);
415 static int omap16xxcam_set_xclk(int xclk, void *priv)
417 struct omap16xxcam *data = (struct omap16xxcam *)priv;
420 divisor = data->ocp_clk / xclk;
421 if (divisor * xclk < data->ocp_clk)
427 xclk_val = FOSCMOD_TC2_CK2;
430 xclk_val = FOSCMOD_TC2_CK3;
436 xclk_val = FOSCMOD_TC2_CK4;
440 xclk_val = FOSCMOD_TC2_CK8;
444 xclk_val = FOSCMOD_TC2_CK10;
450 xclk_val = FOSCMOD_TC2_CK12;
453 xclk_val = FOSCMOD_TC2_CK16;
456 xclk_val = FOSCMOD_TC2_CK16;
459 /* Follow the protocol to change the XCLK clock */
460 data->camera_regs->ctrlclock &= ~CAMEXCLK_EN;
461 data->camera_regs->ctrlclock |= xclk_val;
462 data->camera_regs->ctrlclock |= CAMEXCLK_EN;
464 return (data->ocp_clk / divisor);
467 static int omap16xxcam_open(void *priv)
469 struct omap16xxcam *data = (struct omap16xxcam *)priv;
472 ret = request_irq(INT_CAMERA, omap16xx_cam_isr, IRQF_DISABLED,
475 printk(KERN_ERR "FAILED to acquire IRQ\n");
480 omap16xxcam_enable(data);
481 omap16xxcam_init_dma(data);
483 return omap16xx_cam_link_open(data);
486 static int omap16xxcam_close(void *priv)
488 struct omap16xxcam *data = (struct omap16xxcam *)priv;
490 omap16xxcam_disable(priv);
492 free_irq(INT_CAMERA, data);
494 return omap16xx_cam_link_close(data);
497 static int omap16xxcam_cleanup(void *priv)
499 struct omap16xxcam *data = (struct omap16xxcam *)priv;
501 if (!data->camera_regs)
504 omap16xxcam_disable(data);
505 if (cpu_is_omap1710())
506 iounmap((void *)data->camera_regs);
507 data->camera_regs = NULL;
509 if (data->iobase_phys) {
510 release_mem_region(data->iobase_phys, CAMERA_IOSIZE);
511 data->iobase_phys = 0;
514 if (hardware_data.func_clk) {
515 clk_disable(hardware_data.func_clk);
516 clk_put(hardware_data.func_clk);
517 hardware_data.func_clk = NULL;
523 /* Initialize the OMAP camera interface */
524 static void *omap16xxcam_init(void)
526 unsigned long cam_iobase;
528 if (!request_mem_region(CAMERA_BASE, CAMERA_IOSIZE,
529 camera_hardware_if.name)) {
530 pr_debug("%s is already in use\n", camera_hardware_if.name);
534 if (cpu_is_omap1710()) {
535 cam_iobase = (unsigned long)ioremap(CAMERA_BASE, CAMERA_IOSIZE);
537 printk(KERN_ERR "CANNOT MAP CAMERA REGISTER\n");
541 cam_iobase = io_p2v(CAMERA_BASE);
543 /* Set the base address of the camera registers */
544 hardware_data.camera_regs = (camera_regs_t *) cam_iobase;
545 hardware_data.iobase_phys = (unsigned long)CAMERA_BASE;
547 /* Get the input clock value to camera interface and store it */
548 if (cpu_is_omap1710())
549 hardware_data.func_clk = clk_get(0, "tc2_ck");
551 hardware_data.func_clk = clk_get(0, "armper_ck");
552 hardware_data.ocp_clk = clk_get_rate(hardware_data.func_clk);
554 /* Initialize the camera IF */
556 /* Enable it. This is needed for sensor detection */
557 omap16xxcam_enable((void *)&hardware_data);
558 /* Initialize DMA data */
559 spin_lock_init(&hardware_data.dma_lock);
561 init_waitqueue_head(&hardware_data.vsync_wait);
562 return (void *)&hardware_data;
565 struct camera_hardware camera_hardware_if = {
567 .name = "OMAP16xx Parallel Camera",
568 .init = omap16xxcam_init,
569 .cleanup = omap16xxcam_cleanup,
570 .open = omap16xxcam_open,
571 .close = omap16xxcam_close,
572 .enable = omap16xxcam_enable,
573 .disable = omap16xxcam_disable,
574 .abort = omap16xxcam_abort,
575 .set_xclk = omap16xxcam_set_xclk,
576 .init_dma = omap16xxcam_init_dma,
577 .start_dma = omap16xxcam_start_dma,
578 .finish_dma = omap16xxcam_finish_dma,