Skip to contentSkip to conversation

OMAP2 camera and TCM825x sensor drivers

PATCH In review Sakari Ailus 6 participants 22 messages Feb 28, 2007 – Mar 14, 2007 2 messages not in the archive Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 OMAP2 camera and TCM825x sensor drivers

Hi,

I'm about to send a patch set of OMAP 2 camera and a TCM825x sensor drivers. Compared to those from maemo.org, there are clean-ups and the overlay support has been removed, among other things.

This is all still very much work in progress but I'd be glad to hear comments about it.

Both drivers should compile, and also function with 2.6.18 from maemo.org. (Except that there's a bug in VIDIOC_DQBUF in 2.6.18.) Some N800-specific code is missing for the moment. Also locking is in sore state. The interface changes (temporarily) break existing OMAP 1 camera driver and the ov9640 sensor driver.

These patches are against Tony's tree.

I recommend not to apply these for the time being. :)

Regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#1 lore raw

PATCH 1/1 ARM: OMAP2: Camera: Add OMAP2 24xx camera driver.

This is a modified version of the camera driver originally from Montavista.

---
 drivers/media/video/omap/Makefile             |    1 +
 drivers/media/video/omap/omap24xxcam-core.c   |  202 ++++
 drivers/media/video/omap/omap24xxcam-dma.c    |  320 +++++++
 drivers/media/video/omap/omap24xxcam-dma.h    |   65 ++
 drivers/media/video/omap/omap24xxcam-dmahw.c  |  224 +++++
 drivers/media/video/omap/omap24xxcam-sensor.c |  226 +++++
 drivers/media/video/omap/omap24xxcam-sgdma.c  |  298 ++++++
 drivers/media/video/omap/omap24xxcam-vbq.c    |  370 ++++++++
 drivers/media/video/omap/omap24xxcam.c        | 1216 +++++++++++++++++++++++++
 drivers/media/video/omap/omap24xxcam.h        |  659 +++++++++++++
 10 files changed, 3581 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/omap/omap24xxcam-core.c
 create mode 100644 drivers/media/video/omap/omap24xxcam-dma.c
 create mode 100644 drivers/media/video/omap/omap24xxcam-dma.h
 create mode 100644 drivers/media/video/omap/omap24xxcam-dmahw.c
 create mode 100644 drivers/media/video/omap/omap24xxcam-sensor.c
 create mode 100644 drivers/media/video/omap/omap24xxcam-sgdma.c
 create mode 100644 drivers/media/video/omap/omap24xxcam-vbq.c
 create mode 100644 drivers/media/video/omap/omap24xxcam.c
 create mode 100644 drivers/media/video/omap/omap24xxcam.h
drivers/media/video/omap/Makefile +1 -0
index 36ae615..4ca1d1d 100644
@@ -4,6 +4,7 @@ obj-$(CONFIG_VIDEO_OMAP_CAMERA) += omapcamera.o
 obj-$(CONFIG_VIDEO_CAMERA_SENSOR_OV9640) += sensor_ov9640.o
 
 objs-y$(CONFIG_ARCH_OMAP16XX) += omap16xxcam.o camera_core.o
+objs-y$(CONFIG_ARCH_OMAP24XX) += omap24xxcam.o omap24xxcam-sgdma.o omap24xxcam-dma.o omap24xxcam-dmahw.o omap24xxcam-core.o omap24xxcam-sensor.o omap24xxcam-vbq.o
 objs-y$(CONFIG_MACH_OMAP_H3) += h3_sensor_power.o
 objs-y$(CONFIG_MACH_OMAP_H4) += h4_sensor_power.o
 
drivers/media/video/omap/omap24xxcam-core.c new file +202 -0

202 lines not on this page · raw message

drivers/media/video/omap/omap24xxcam-dma.c new file +320 -0

320 lines not on this page · raw message

drivers/media/video/omap/omap24xxcam-dma.h new file +65 -0

65 lines not on this page · raw message

drivers/media/video/omap/omap24xxcam-dmahw.c new file +224 -0

224 lines not on this page · raw message

drivers/media/video/omap/omap24xxcam-sensor.c new file +226 -0

226 lines not on this page · raw message

drivers/media/video/omap/omap24xxcam-sgdma.c new file +298 -0

298 lines not on this page · raw message

drivers/media/video/omap/omap24xxcam-vbq.c new file +370 -0

370 lines not on this page · raw message

drivers/media/video/omap/omap24xxcam.c new file +1216 -0

1,216 lines not on this page · raw message

drivers/media/video/omap/omap24xxcam.h new file +659 -0

72 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.5.0.1

Part of the diff is not shown here. View the raw message.

#2 lore raw

PATCH 1/1 ARM: OMAP2: Camera: Add a driver for TCM825x sensor.

This driver has been originally written by David Cohen <[email protected]>.

---
 drivers/media/video/omap/Kconfig          |    4 +
 drivers/media/video/omap/Makefile         |    1 +
 drivers/media/video/omap/sensor_tcm825x.c | 1102 +++++++++++++++++++++++++++++
 drivers/media/video/omap/tcm825x.h        |  179 +++++
 4 files changed, 1286 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/omap/sensor_tcm825x.c
 create mode 100644 drivers/media/video/omap/tcm825x.h
drivers/media/video/omap/Kconfig +4 -0
index 809193b..8515c4c 100644
@@ -10,3 +10,7 @@ config VIDEO_CAMERA_SENSOR_OV9640
 	depends on VIDEO_OMAP_CAMERA
 	help
 	  OmniVision 9640 camera sensor support
+
+config VIDEO_CAMERA_SENSOR_TCM825X
+	tristate "TCM825x sensor support"
+	depends on VIDEO_OMAP_CAMERA
drivers/media/video/omap/Makefile +1 -0
index 4ca1d1d..3814d75 100644
@@ -2,6 +2,7 @@
 
 obj-$(CONFIG_VIDEO_OMAP_CAMERA) += omapcamera.o
 obj-$(CONFIG_VIDEO_CAMERA_SENSOR_OV9640) += sensor_ov9640.o
+obj-$(CONFIG_VIDEO_CAMERA_SENSOR_TCM825X) += sensor_tcm825x.o
 
 objs-y$(CONFIG_ARCH_OMAP16XX) += omap16xxcam.o camera_core.o
 objs-y$(CONFIG_ARCH_OMAP24XX) += omap24xxcam.o omap24xxcam-sgdma.o omap24xxcam-dma.o omap24xxcam-dmahw.o omap24xxcam-core.o omap24xxcam-sensor.o omap24xxcam-vbq.o
drivers/media/video/omap/sensor_tcm825x.c new file +1102 -0

1,102 lines not on this page · raw message

drivers/media/video/omap/tcm825x.h new file +179 -0

179 lines not on this page · raw message

Signature · 1 line
1.5.0.1
#3 lore raw

PATCH 1/1 ARM: OMAP2: Camera: Modify sensor interface.

Clean up sensor interface.

---
 drivers/media/video/omap/sensor_if.h |   59 +++++++++++++++++++++++++--------
 1 files changed, 44 insertions(+), 15 deletions(-)
drivers/media/video/omap/sensor_if.h +44 -15
index 47bb716..cda2686 100644
@@ -20,31 +20,60 @@
 
 #define OMAP_SENSOR_NAME_LEN		31
 
+struct omap_camera_sensor;
+
+struct omap_camera {
+	void *priv;
+	/*
+	 * Tell camera to reset the sensor, i.e. power down and up
+	 * again.
+	 */
+	int (*sensor_register)(struct omap_camera *oc,
+			       struct omap_camera_sensor *os);
+	void (*sensor_unregister)(struct omap_camera *oc,
+				  struct omap_camera_sensor *os);
+	void (*sensor_reset)(struct omap_camera *oc,
+			     struct omap_camera_sensor *os);
+};
+
 struct omap_camera_sensor {
 	unsigned int version;
 	char name[OMAP_SENSOR_NAME_LEN + 1];
 
-	void *(*init)(struct v4l2_pix_format *);
-	int (*cleanup)(void *);
+	struct module *module;
+	void *priv; /* sensor's private data */
 
-	int (*power_on)(void *);
-	int (*power_off)(void *);
+	int (*init)(struct omap_camera_sensor *os, struct v4l2_pix_format *pix,
+		    struct omap_camera *oc);
+	int (*cleanup)(struct omap_camera_sensor *os);
 
-	int (*enum_pixformat)(struct v4l2_fmtdesc *, void *);
-	int (*try_format)(struct v4l2_pix_format *, void *);
+	int (*power_on)(struct omap_camera_sensor *os);
+	int (*power_off)(struct omap_camera_sensor *os);
 
-	unsigned long (*calc_xclk)(struct v4l2_pix_format *,
-				   struct v4l2_fract *, void *);
+	int (*frame_check)(struct omap_camera_sensor *os,
+			   struct v4l2_pix_format *pix, void *buf);
 
-	int (*configure)(struct v4l2_pix_format *, unsigned long,
-			 struct v4l2_fract *, void *);
+	int (*enum_pixformat)(struct omap_camera_sensor *os,
+			      struct v4l2_fmtdesc *fmtdesc);
+	int (*try_format)(struct omap_camera_sensor *os,
+			  struct v4l2_pix_format *fmt);
 
-	int (*query_control) (struct v4l2_queryctrl *, void *);
-	int (*get_control)(struct v4l2_control *, void *);
-	int (*set_control)(struct v4l2_control *, void *);
+	unsigned long (*calc_xclk)(struct omap_camera_sensor *os,
+				   struct v4l2_pix_format *fmt,
+				   struct v4l2_fract *fract);
 
-};
+	int (*configure)(struct omap_camera_sensor *os,
+			 struct v4l2_pix_format *fmt, unsigned long,
+			 struct v4l2_fract *fract);
 
-extern struct omap_camera_sensor camera_sensor_if;
+	int (*query_control) (struct omap_camera_sensor *os,
+			      struct v4l2_queryctrl *ctrl);
+	int (*get_control)(struct omap_camera_sensor *os,
+			   struct v4l2_control *ctrl);
+	int (*set_control)(struct omap_camera_sensor *os,
+			   struct v4l2_control *ctrl);
+};
+	
+extern struct omap_camera omap24xxcam_camera;
 
 #endif
Signature · 1 line
1.5.0.1
#4 lore raw

PATCH 1/1 ARM: OMAP2: Camera: Adapt to 2.6.20.

---
 drivers/media/video/omap/omap24xxcam-sensor.c |    6 ++++--
 drivers/media/video/omap/omap24xxcam.c        |   12 +++++++-----
 drivers/media/video/omap/omap24xxcam.h        |    2 +-
 3 files changed, 12 insertions(+), 8 deletions(-)
drivers/media/video/omap/omap24xxcam-sensor.c +4 -2
index bde7429..3f1ab05 100644
@@ -132,9 +132,11 @@ void omap24xxcam_sensor_disable(struct omap24xxcam_device *cam)
 		cam->sensor->power_off(cam->sensor);
 }
 
-void omap24xxcam_sensor_reset_work(void * data)
+void omap24xxcam_sensor_reset_work(struct work_struct *work)
 {
-	struct omap24xxcam_device *cam = (struct omap24xxcam_device *)data;
+	struct omap24xxcam_device *cam =
+		container_of(work, struct omap24xxcam_device,
+			     sensor_reset_work);
 	
 	omap24xxcam_sensor_disable(cam);
 
drivers/media/video/omap/omap24xxcam.c +7 -5
index 4f954ed..c8f1b74 100644
@@ -148,9 +148,11 @@ static void omap24xxcam_reset_timer(unsigned long data)
 	omap24xxcam_camera_reset_schedule(cam);
 }
 
-void omap24xxcam_camera_reset_work(void * data)
+void omap24xxcam_camera_reset_work(struct work_struct *work)
 {
-	struct omap24xxcam_device *cam = (struct omap24xxcam_device *)data;
+	struct omap24xxcam_device *cam =
+		container_of(work, struct omap24xxcam_device,
+			     sensor_reset_work);
 
 	/* Disable and reset the camera interface. */
 	omap24xxcam_core_disable(&cam->core);
@@ -190,7 +192,7 @@ void omap24xxcam_camera_reset_schedule(struct omap24xxcam_device *cam)
 	schedule_work(&cam->camera_reset_work);
 }
 
-static irqreturn_t omap24xxcam_isr(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t omap24xxcam_isr(int irq, void *arg)
 {
 	struct omap24xxcam_device *cam = (struct omap24xxcam_device *)arg;
 	unsigned long irqstatus;
@@ -1061,9 +1063,9 @@ static int omap24xxcam_probe(struct platform_device *pdev)
 	cam->sgdma.reset_timer.function = omap24xxcam_reset_timer;
 	cam->sgdma.reset_timer.data = (unsigned long)cam;
 	INIT_WORK(&cam->camera_reset_work,
-		  omap24xxcam_camera_reset_work, cam);
+		  omap24xxcam_camera_reset_work);
 	INIT_WORK(&cam->sensor_reset_work,
-		  omap24xxcam_sensor_reset_work, cam);
+		  omap24xxcam_sensor_reset_work);
 
 	/* initialize the spinlock used to serialize access to the image 
 	 * parameters
drivers/media/video/omap/omap24xxcam.h +1 -1
index eba5ea6..9defee3 100644
@@ -615,7 +615,7 @@ int omap24xxcam_sensor_init(struct omap24xxcam_device *cam);
 void omap24xxcam_sensor_exit(struct omap24xxcam_device *cam);
 int omap24xxcam_sensor_enable(struct omap24xxcam_device *cam);
 void omap24xxcam_sensor_disable(struct omap24xxcam_device *cam);
-void omap24xxcam_sensor_reset_work(void * data);
+void omap24xxcam_sensor_reset_work(struct work_struct *work);
 void omap24xxcam_sensor_reset_schedule(struct omap_camera *oc,
 				       struct omap_camera_sensor *os);
 unsigned long omap24xxcam_sensor_calc_xclk(struct omap24xxcam_device *cam,
Signature · 1 line
1.5.0.1
#5 lore raw

Re: [PATCH] ARM: OMAP2: Camera: Adapt to 2.6.20.

Quoted 7 lines · Sakari Ailus
---
 drivers/media/video/omap/omap24xxcam-sensor.c |    6 ++++--
 drivers/media/video/omap/omap24xxcam.c        |   12 +++++++-----
 drivers/media/video/omap/omap24xxcam.h        |    2 +-
 3 files changed, 12 insertions(+), 8 deletions(-)

I think you have not looked at patches posted by me about OMAP2420 camera. Part of the changes are taken from N800 kernel tree and TI's tree. Those sensor interface changes are also changed to adapt TI Micron sensor. I believe you should have worked on those changes and modified sensor interface for N800. Why re-work?

http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009062.html
http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009063.html
http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009069.html
http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009064.html
http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009065.html

Please help me to review above patches instead, then we will have less re-work and come to conclusion, whose patches should be integrated instead. BTW, I have N800 so I can test this sensor now.

Signature · 1 line
--Trilok Soni
#6 lore raw

Re: [PATCH] ARM: OMAP2: Camera: Adapt to 2.6.20.

Quoted 5 lines · ext Trilok Soni

I think you have not looked at patches posted by me about OMAP2420 camera. Part of the changes are taken from N800 kernel tree and TI's tree. Those sensor interface changes are also changed to adapt TI Micron sensor. I believe you should have worked on those changes and modified sensor interface for N800. Why re-work?

I was actually thinking of that sensor interface change due to Micron sensor (in your patches) a bit. Anyway, as I said, this is a work in progress, and I've been just trying to keep the driver somehow functional.

I don't like the original sensor interface very much. It passes void pointers with no name to interface functions, these pointers obviously point to some sensor private data. Then the init function returns the pointer to the sensor. Hmm.

I'd like that the sensor didn't know about the camera. This is accomplished by adding a generic camera interface with register, reset (so far specific to N800) and unregister. The sensor could then register itself to the camera, whose pointer it gets from its configuration (machine specific).

module field has been added so that the camera can try_module_get() the sensor when the device is opened. Beyond that it's just what I see fit. :) This is all naturally open for changes.

Quoted 6 lines

http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009062.html

http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009063.html

http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009069.html

Quoted 8 lines

http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009064.html

http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009065.html

Please help me to review above patches instead, then we will have less re-work and come to conclusion, whose patches should be integrated instead. BTW, I have N800 so I can test this sensor now.

I'll have a look.

Signature · 2 lines
Sakari Ailus
[email protected]
#7 lore raw

Re: [PATCH] ARM: OMAP2: Camera: Add OMAP2 24xx camera driver.

In reply to Sakari Ailus
Quoted 12 lines · Sakari Ailus

This is a modified version of the camera driver originally from Montavista.

---
 drivers/media/video/omap/Makefile             |    1 +
 drivers/media/video/omap/omap24xxcam-core.c   |  202 ++++
 drivers/media/video/omap/omap24xxcam-dma.c    |  320 +++++++
 drivers/media/video/omap/omap24xxcam-dma.h    |   65 ++
 drivers/media/video/omap/omap24xxcam-dmahw.c  |  224 +++++
 drivers/media/video/omap/omap24xxcam-sensor.c |  226 +++++
 drivers/media/video/omap/omap24xxcam-sgdma.c  |  298 ++++++
 drivers/media/video/omap/omap24xxcam-vbq.c    |  370 ++++++++
Quoted 1 line

drivers/media/video/omap/omap24xxcam.c | 1216 > +

First review comments...

Quoted 11 lines
drivers/media/video/omap/omap24xxcam-core.c new file +11 -0
+#include "omap24xxcam.h"
+
+/* Program the camera interface xclk for the frequency cam->img.xclk based on
+ * the functional clock frequency cam->img.mclk.  If the specifed cam->img.xclk
+ * frequency is not possible based on the value of cam->img.mclk, then the
+ * closest xclk frequency lower than the specified xclk will be selected.
+ * The actual xclk frequency is returned in cam->img.xclk.  If cam->img.xclk is zero,
+ * then xclk is turned off (stable low value).
+ */
+
+void omap24xxcam_core_init(struct omap24xxcam_core *core,

drivers/media/video/omap/omap24xxcam-core.c line 70

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-core.c new file +10 -0
+                          unsigned long base)
+{
+       DBG;
+
+       core->base = base;
+
+       /* Setting the camera core AUTOIDLE bit causes problems with frame
+        * synchronization, so we will clear the AUTOIDLE bit instead.
+        */
+       //omap24xxcam_reg_out(cam, CC_SYSCONFIG, 0);

DBG should be removed from everywhere.

drivers/media/video/omap/omap24xxcam-core.c line 78

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-core.c new file +8 -0
+       omap24xxcam_reg_out(core->base, CC_SYSCONFIG, CC_SYSCONFIG_AUTOIDLE);
+
+       core->xclk_enabled = 0;
+}
+
+void omap24xxcam_core_exit(const struct omap24xxcam_core *core)
+{
+}

Nothing in core_exit ? If yes, then should be removed.

drivers/media/video/omap/omap24xxcam-core.c line 118

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-core.c new file +10 -0
+
+void omap24xxcam_core_enable_callback(struct omap24xxcam_device *cam)
+{
+       omap24xxcam_core_enable(&cam->core);
+}
+/* reset core fifo and dma */
+/* void omap24xxcam_core_reset(struct omap24xxcam_device *cam) */
+/* { */
+/*     omap24xxcam_reg_out(cam, CC_CTRL, CC_CTRL_CC_RST); */
+/* } */

Remove this commented code if not used.

Quoted 17 lines
drivers/media/video/omap/omap24xxcam-core.c new file +17 -0
+
+/* Interrupt service routine for camera core interrupts. */
+void omap24xxcam_core_isr(struct omap24xxcam_core *core)
+{
+       unsigned long cc_irqstatus;
+       const unsigned long cc_irqstatus_err =
+               CC_IRQSTATUS_FW_ERR_IRQ
+               | CC_IRQSTATUS_FSC_ERR_IRQ
+               | CC_IRQSTATUS_SSC_ERR_IRQ
+               | CC_IRQSTATUS_FIFO_UF_IRQ
+               | CC_IRQSTATUS_FIFO_OF_IRQ;
+
+       DBG;
+
+       cc_irqstatus = omap24xxcam_reg_in(core->base, CC_IRQSTATUS);
+       omap24xxcam_reg_out(core->base, CC_IRQSTATUS, cc_irqstatus);
+

drivers/media/video/omap/omap24xxcam-core.c line 145

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-core.c new file +10 -0
+       if (cc_irqstatus & cc_irqstatus_err) {
+               printk("%s: scheduling camera reset, cc_irqstatus 0x%lx\n",
+                      __FUNCTION__, cc_irqstatus);
+               omap24xxcam_camera_reset_schedule(
+                       container_of(core, struct omap24xxcam_device, core));
+       } else {
+               if (cc_irqstatus & 0xffff)
+                       printk("%s: cc_irqstatus 0x%lx\n",
+                              __FUNCTION__, cc_irqstatus);
+       }

Add proper KERN_INFO/KERN_WARN/KERN_ERR etc. as needed.

Quoted 6 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +0 -0
new file mode 100644
index 0000000..d10f1c8
@@ -0,0 +1,320 @@

...

drivers/media/video/omap/omap24xxcam-dma.c line 49

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +8 -0
+#include <asm/semaphore.h>
+
+#include "omap24xxcam.h"
+#include "omap24xxcam-dma.h"
+
+/* configuration macros */
+#define CAM_NAME       "omap24xxcam"
+#define CONFIG_H4

CONFIG_H4 is not used anywhere.

...

drivers/media/video/omap/omap24xxcam-dmahw.c line 2

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +2 -0
new file mode 100644
index 0000000..21d23db
@@ -0,0 +1,224 @@
+/*
+ * drivers/media/video/omap/omap24xxcam-dma.c

Doesn't match with file name.

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +8 -0
+ *
+ * Video-for-Linux (Version 2) camera capture driver for
+ * the OMAP24xx camera controller.
+ *
+ * Author: David Cohen <[email protected]>
+ * Based on: omap24xxcam.c by Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.

drivers/media/video/omap/omap24xxcam-dmahw.c line 20

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +10 -0
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ * History:
+ * 2005/nov - David Cohen <[email protected]>
+ *            Updated the driver for the Linux Device Model and new version of V4L2.
+ */

Why same History is carried too? For History I would suggest GIT commit comments. This keeps file header clean :)

Quoted 12 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +12 -0
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/videodev.h>
+#include <linux/pci.h>         /* needed for videobufs */

drivers/media/video/omap/omap24xxcam-dmahw.c line 42

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +10 -0
+#include <media/video-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/input.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/scatterlist.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>

Do you need all the header files here too? OR just copied from omap24xxcam.c ?

drivers/media/video/omap/omap24xxcam-dmahw.c line 49

Quoted 7 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +7 -0
+
+#include "omap24xxcam.h"
+#include "omap24xxcam-dma.h"
+
+/* configuration macros */
+#define CAM_NAME       "omap24xxcam"
+#define CONFIG_H4

CONFIG_H4 again.

drivers/media/video/omap/omap24xxcam-dmahw.c line 57

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +8 -0
+
+/* Ack all interrupt on CSR and IRQSTATUS_L0 */
+void omap24xxcam_dmahw_ack_all(unsigned long base)
+{
+       unsigned long csr;
+       int i;
+
+       for (i = 0; i< 4; ++i) {

Use NUM_CAM_DMACHANNELS?

Quoted 21 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +21 -0
+               csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i));
+               /* ack interrupt in CSR */
+               omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr);
+       }
+       omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xffffffff);
+}
+
+/* Ack dmach on CSR and IRQSTATUS_L0 */
+unsigned long omap24xxcam_dmahw_ack_ch(unsigned long base, int dmach)
+{
+       unsigned long csr;
+
+       csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach));
+       /* ack interrupt in CSR */
+       omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr);
+       /* ack interrupt in IRQSTATUS */
+       omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach));
+
+       return csr;
+}
+

...

drivers/media/video/omap/omap24xxcam-sensor.c line 2

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +2 -0
new file mode 100644
index 0000000..bde7429
@@ -0,0 +1,226 @@
+/*
+ * drivers/media/video/omap/omap24xxcam-dma.c

Again mismatch against filenames. It is better that we avoid putting filepath in file header.

Quoted 19 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +19 -0
+ *
+ * Video-for-Linux (Version 2) camera capture driver for
+ * the OMAP24xx camera controller.
+ *
+ * Author: David Cohen <[email protected]>
+ * Based on: omap24xxcam.c by Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ * History:
+ * 2005/nov - David Cohen <[email protected]>
+ *            Updated the driver for the Linux Device Model and new version of V4L2.
+ */
+

...

drivers/media/video/omap/omap24xxcam-sensor.c line 137

Quoted 4 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +4 -0
+
+void omap24xxcam_sensor_reset_work(void * data)
+{
+       struct omap24xxcam_device *cam = (struct omap24xxcam_device *)data;

Do we really need such castings?

Quoted 5 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +5 -0
+
+       omap24xxcam_sensor_disable(cam);
+
+       omap24xxcam_sensor_enable(cam);
+}

...

...

Quoted 15 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +15 -0
+
+/* This should be called by the sensor code whenever it's ready */
+int omap24xxcam_sensor_register(struct omap_camera *oc,
+                               struct omap_camera_sensor *os)
+{
+       struct omap24xxcam_device *cam = oc->priv;
+       int rval;
+
+       /* the device has not been initialised yet */
+       if (cam == NULL)
+               return -ENODEV;
+       if (os == NULL)
+               return -EINVAL;
+       if (cam->sensor != NULL)
+               return -EBUSY;

drivers/media/video/omap/omap24xxcam-sensor.c line 213

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +10 -0
+
+       cam->sensor = os;
+       rval = omap24xxcam_device_enable(cam);
+
+       if (rval)
+               cam->sensor = NULL;
+       return rval;
+}
+
+EXPORT_SYMBOL(omap24xxcam_sensor_register);

What registration functionality is done above? I can see only checking against the sensor initialization and enabling it if not. Please use proper name.

Quoted 20 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +13 -0
+
+void omap24xxcam_sensor_unregister(struct omap_camera *oc,
+                                  struct omap_camera_sensor *os)
+{
+       struct omap24xxcam_device *cam = oc->priv;
+
+       BUG_ON(cam->users != 0);
+       BUG_ON(cam->sensor == NULL);
+
+       cam->sensor = NULL;
+}
+
+EXPORT_SYMBOL(omap24xxcam_sensor_unregister);
drivers/media/video/omap/omap24xxcam-sgdma.c new file +1 -0
new file mode 100644
index 0000000..0243a59
@@ -0,0 +1,298 @@
+/*

...

Quoted 32 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +32 -0
+/* Sync scatter-gather DMA by aborting any DMA transfers currently in progress.
+ * Any queued scatter-gather DMA transactions that have not yet been started
+ * will remain queued.  The DMA controller will be idle after this routine
+ * completes.  When the scatter-gather queue is restarted, the next
+ * scatter-gather DMA transfer will begin at the start of a new transaction.
+ */
+void
+omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma, unsigned long csr)
+{
+       unsigned long irqflags;
+       int sgslot;
+       struct sgdma_state *sg_state;
+
+       DBG;
+
+       /* stop any DMA transfers in progress */
+       omap24xxcam_dma_stop(&sgdma->dma, csr);
+
+       spin_lock_irqsave(&sgdma->lock, irqflags);
+
+       if (sgdma->free_sgdma < NUM_SG_DMA) {
+               sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
+               sg_state = sgdma->sg_state + sgslot;
+               if (sg_state->next_sglist != 0) {
+                       /* This DMA transfer was in progress, so abort it. */
+                       sgdma_callback_t callback = sg_state->callback;
+                       void *arg = sg_state->arg;
+                       sgdma->free_sgdma++;
+                       if (callback) {
+                               /* leave interrupts masked */
+                               spin_unlock(&sgdma->lock);
+                               (*callback) (sgdma, csr, arg);

drivers/media/video/omap/omap24xxcam-sgdma.c line 260

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +10 -0
+                               spin_lock(&sgdma->lock);
+                       }
+               }
+       }
+
+       spin_unlock_irqrestore(&sgdma->lock, irqflags);
+}
+
+
+void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma, unsigned long base)

I think this lines exceeds 80 column rule.
...

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +4 -0
new file mode 100644
index 0000000..f6d8803
@@ -0,0 +1,370 @@
+/*
+ * OMAP 24xx camera high-level DMA (not hardware) and scatter-gather
+ * DMA handling
+ *

...

Quoted 51 lines
drivers/media/video/omap/omap24xxcam.c new file +45 -0
new file mode 100644
index 0000000..4f954ed
@@ -0,0 +1,1216 @@
+/*
+ * drivers/media/video/omap/omap24xxcam.c
+ *
+ * Video-for-Linux (Version 2) camera capture driver for
+ * the OMAP24xx camera controller.
+ *
+ * Author: Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ * History:
+ * 2005/nov - David Cohen <[email protected]>
+ *            Updated the driver for the Linux Device Model and new version of V4L2.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/pci.h>         /* needed for videobufs */
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>

drivers/media/video/omap/omap24xxcam.c line 55

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+
+#include <media/video-buf.h>
+#include <media/v4l2-common.h>
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/scatterlist.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>
+#include <asm/processor.h>

Do we need all above header files? like processor.h ? Please check.

drivers/media/video/omap/omap24xxcam.c line 57

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.c new file +2 -0
+
+#include <asm/arch/clock.h>

#include <linux/clk.h> ?

Quoted 8 lines
drivers/media/video/omap/omap24xxcam.c new file +8 -0
+
+#include "omap24xxcam.h"
+#include "omap24xxcam-dma.h"
+
+#include "sensor_if.h"
+
+/* configuration macros */
+

drivers/media/video/omap/omap24xxcam.c line 75

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+//#define DEBUG_CAM
+#ifdef DEBUG_CAM
+#define DBG            printk(KERN_INFO CAM_NAME ": %s\n", __FUNCTION__)
+#define DBG_END        printk(KERN_INFO CAM_NAME ": %s END!\n", __FUNCTION__)
+#define DBG_MID(x)     printk(KERN_INFO CAM_NAME ": %s - %d\n", __FUNCTION__, x)
+#else
+#define DBG
+#define DBG_END
+#define DBG_MID(x)
+#endif

Remove above DBG stuff, something like pr_debug?

drivers/media/video/omap/omap24xxcam.c line 195

Quoted 9 lines
drivers/media/video/omap/omap24xxcam.c new file +9 -0
+
+void omap24xxcam_camera_reset_schedule(struct omap24xxcam_device *cam)
+{
+       schedule_work(&cam->camera_reset_work);
+}
+
+static irqreturn_t omap24xxcam_isr(int irq, void *arg, struct pt_regs *regs)
+{
+       struct omap24xxcam_device *cam = (struct omap24xxcam_device *)arg;

unnecessary casting.

Ah...How it is ported to 2.6.20? struct pt_regs is still there.

Quoted 17 lines
drivers/media/video/omap/omap24xxcam.c new file +17 -0
+
+static int
+omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       struct omap24xxcam_fh *fh = file->private_data;
+       int err;
+
+       /* let the video-buf mapper check arguments and set-up structures */
+       err = videobuf_mmap_mapper(&fh->vbq, vma);
+       if (err)
+               goto err1;
+
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+       /* do mapping to our allocated buffers */
+       err = omap24xxcam_mmap_buffers(file, vma);
+       if (err)

drivers/media/video/omap/omap24xxcam.c line 688

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+               goto err2;
+
+       return 0;
+
+err2:
+       if (vma->vm_private_data)
+               kfree(vma->vm_private_data);
+err1:
+
+       return err;

It is better not to use err1, err2 kind of goto labels. Instead err_videobuf_mmap and err_omap_mmap. You know the benefits.

drivers/media/video/omap/omap24xxcam.c line 712

Quoted 5 lines
drivers/media/video/omap/omap24xxcam.c new file +5 -0
+
+static void omap24xxcam_clock_put(struct omap24xxcam_device *cam)
+{
+       if (cam->img.ick == NULL)
+               return;

What about img.fck check ?

Quoted 4 lines
drivers/media/video/omap/omap24xxcam.c new file +4 -0
+
+       clk_put(cam->img.ick);
+       clk_put(cam->img.fck);
+}

...

drivers/media/video/omap/omap24xxcam.c line 974

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+
+        */
+       /* choose an arbitrary xclk frequency */
+       omap24xxcam_core_xclk_set(&cam->core, 12000000);
+
+       omap24xxcam_camera.priv = cam;
+
+       if ((rval = omap24xxcam_sensor_init(cam))) {
+               goto err;
+       }

No need of { }. Also please use proper goto labels as suggested earlier.

Quoted 45 lines
drivers/media/video/omap/omap24xxcam.c new file +45 -0
+
+       if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) {
+               printk(KERN_ERR CAM_NAME
+                      ": could not register Video for Linux device\n");
+               vfd->minor = -1;
+               rval = -EBUSY;
+               goto err;
+       }
+
+       printk(KERN_INFO CAM_NAME
+              ": registered device video%d [v4l2]\n", vfd->minor);
+
+       return 0;
+
+err:
+       omap24xxcam_device_disable(cam);
+
+       return rval;
+}
+
+void omap24xxcam_device_disable(struct omap24xxcam_device *cam)
+{
+       omap24xxcam_sensor_exit(cam);
+
+       if (cam->vfd) {
+               if (cam->vfd->minor == -1) {
+                       /* The device was never registered, so release the
+                        * video_device struct directly.
+                        */
+                       video_device_release(cam->vfd);
+               } else {
+                       /* The unregister function will release the video_device
+                        * struct as well as unregistering it.
+                        */
+                       video_unregister_device(cam->vfd);
+               }
+               cam->vfd = NULL;
+       }
+}
+
+static int omap24xxcam_probe(struct platform_device *pdev)
+{
+       struct omap24xxcam_device *cam;
+       DBG;
+

...

drivers/media/video/omap/omap24xxcam.c line 1096

Quoted 9 lines
drivers/media/video/omap/omap24xxcam.c new file +9 -0
+
+       /* install the interrupt service routine */
+       if (request_irq(INT_24XX_CAM_IRQ, omap24xxcam_isr, IRQF_DISABLED,
+                       CAM_NAME, cam)) {
+               printk(KERN_ERR CAM_NAME
+                      ": could not install interrupt service routine\n");
+               goto err;
+       }
+       cam->irq = INT_24XX_CAM_IRQ;

Please make proper use of platform_data and resources. irq should have come from device.c registration of platform resource. Please check my patches.

http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009064.html

Quoted 11 lines
drivers/media/video/omap/omap24xxcam.c new file +11 -0
+
+       /* set driver specific data to use in power management functions */
+       platform_set_drvdata(pdev, cam);
+
+       mutex_init(&cam->mutex);
+       cam->users = 0;
+
+       cam->camera_block_alive = 1;
+
+       omap24xxcam_device_enable(cam);
+

drivers/media/video/omap/omap24xxcam.c line 1117

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+       return 0;
+
+err:
+       omap24xxcam_remove(&omap24xxcam_dev);
+       return -ENODEV;
+}
+
+static int omap24xxcam_remove(struct platform_device *pdev)
+{
+       struct omap24xxcam_device *cam = camera_module;

Why not platform_get_drvdata() ?

Quoted 34 lines
drivers/media/video/omap/omap24xxcam.c new file +34 -0
+
+       if (!cam)
+               return 0;
+
+       omap24xxcam_device_disable(cam);
+
+       if (cam->irq) {
+               free_irq(cam->irq, cam);
+               cam->irq = 0;
+       }
+
+       omap24xxcam_sgdma_exit(&cam->sgdma);
+       omap24xxcam_core_exit(&cam->core);
+
+       omap24xxcam_clock_off(cam);
+       omap24xxcam_clock_put(cam);
+
+       if (cam->mmio_base) {
+               iounmap((void *)cam->mmio_base);
+               cam->mmio_base = 0;
+       }
+
+       if (cam->mmio_base_phys) {
+               release_mem_region(cam->mmio_base_phys,
+                                  cam->mmio_size);
+               cam->mmio_base_phys = 0;
+       }
+
+       kfree(cam);
+       camera_module = NULL;
+
+       return 0;
+}
+

...

drivers/media/video/omap/omap24xxcam.h line 2

Quoted 8 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0
new file mode 100644
index 0000000..eba5ea6
@@ -0,0 +1,659 @@
+/*
+ * drivers/media/video/omap24xxcam.h

Incorrect filepath.

Quoted 22 lines
drivers/media/video/omap/omap24xxcam.h new file +22 -0
+ *
+ * Video-for-Linux (Version 2) camera capture driver for
+ * the OMAP24xx camera controller.
+ *
+ * Author: Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef OMAP24XXCAM_H
+#define OMAP24XXCAM_H
+
+#include "sensor_if.h"
+
+//#define DEBUG_CAM
+
+#define CAM_NAME       "omap24xxcam"

drivers/media/video/omap/omap24xxcam.h line 34

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.h new file +10 -0
+
+#ifdef DEBUG_CAM
+#define DBG            printk(KERN_INFO CAM_NAME ": %s\n", __FUNCTION__)
+#define DBG_END        printk(KERN_INFO CAM_NAME ": %s END!\n", __FUNCTION__)
+#define DBG_MID(x)     printk(KERN_INFO CAM_NAME ": %s - %d\n", __FUNCTION__, x)
+#else
+#define DBG
+#define DBG_END
+#define DBG_MID(x)
+#endif

Remove above DBGs.

Signature · 1 line
--Trilok Soni
#8 lore raw

Re: [PATCH] ARM: OMAP2: Camera: Add OMAP2 24xx camera driver.

Hi,

Thanks for your comments. They indeed were useful and I'm planning to do roughly everything I'm not commenting.

Quoted 22 lines · ext Trilok Soni
Quoted 21 lines · Sakari Ailus
drivers/media/video/omap/omap24xxcam-sensor.c new file +21 -0
+
+/* This should be called by the sensor code whenever it's ready */
+int omap24xxcam_sensor_register(struct omap_camera *oc,
+                               struct omap_camera_sensor *os)
+{
+       struct omap24xxcam_device *cam = oc->priv;
+       int rval;
+
+       /* the device has not been initialised yet */
+       if (cam == NULL)
+               return -ENODEV;
+       if (os == NULL)
+               return -EINVAL;
+       if (cam->sensor != NULL)
+               return -EBUSY;
+
+       cam->sensor = os;
+       rval = omap24xxcam_device_enable(cam);
+
+       if (rval)
+               cam->sensor = NULL;
Quoted 8 lines

drivers/media/video/omap/omap24xxcam-sensor.c line 213

Quoted 4 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +4 -0
+       return rval;
+}
+
+EXPORT_SYMBOL(omap24xxcam_sensor_register);

What registration functionality is done above? I can see only checking against the sensor initialization and enabling it if not. Please use proper name.

"cam->sensor = os;".

This gives the sensor to the camera. So I think the name is justified.

Quoted 5 lines
Quoted 5 lines
drivers/media/video/omap/omap24xxcam.c new file +0 -0
new file mode 100644
index 0000000..4f954ed

...

Quoted 7 lines

drivers/media/video/omap/omap24xxcam.c line 712

Quoted 5 lines
drivers/media/video/omap/omap24xxcam.c new file +5 -0
+
+static void omap24xxcam_clock_put(struct omap24xxcam_device *cam)
+{
+       if (cam->img.ick == NULL)
+               return;

What about img.fck check ?

omap24xxcam_clock_get always get()s both or neither. Thus there's no need to check both.

Quoted 4 lines
Quoted 4 lines
drivers/media/video/omap/omap24xxcam.c new file +4 -0
+
+        */
+       /* choose an arbitrary xclk frequency */
+       omap24xxcam_core_xclk_set(&cam->core, 12000000);
Quoted 8 lines

drivers/media/video/omap/omap24xxcam.c line 974

Quoted 6 lines
drivers/media/video/omap/omap24xxcam.c new file +6 -0
+
+       omap24xxcam_camera.priv = cam;
+
+       if ((rval = omap24xxcam_sensor_init(cam))) {
+               goto err;
+       }

No need of { }. Also please use proper goto labels as suggested earlier.

There's only one label in that function. omap24xxcam_device_disable will do whatever was left behind by failed omap24xxcam_device_enable. (Or at least that's the idea.)

Quoted 11 lines

drivers/media/video/omap/omap24xxcam.c line 1096

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +6 -0
+
+       /* install the interrupt service routine */
+       if (request_irq(INT_24XX_CAM_IRQ, omap24xxcam_isr, IRQF_DISABLED,
+                       CAM_NAME, cam)) {
+               printk(KERN_ERR CAM_NAME
+                      ": could not install interrupt service 

routine\n");

drivers/media/video/omap/omap24xxcam.c new file +3 -0
+               goto err;
+       }
+       cam->irq = INT_24XX_CAM_IRQ;
Quoted 5 lines

Please make proper use of platform_data and resources. irq should have come from device.c registration of platform resource. Please check my patches.

http://linux.omap.com/pipermail/linux-omap-open-source/2007-February/009064.html

I fully agree with that.

Regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#9 lore raw

RE: [PATCH] ARM: OMAP2: Camera: Add OMAP2 24xx camera driver.

In reply to Sakari Ailus

Sakari,

I am yet to review this patch completely. One immediate topic that I want to bring up is about DMA files. In Jian's code to David and Komal he had DMA driver integrated into camera driver and David moved the DMA part to new file. Which according to me was an OK one, but in your patch set I see around 3 DMA related files. I really don't see a necessity for this split.

If you really want to clean up the DMA part of it then its better to upgrade the dma.c file for OMAP2, the CAM_DMA and system_DMA are same. Why not add this functionality there? Or use the existing DMA functionality instead of duplicating the code.

Also, looking at the future Camera work for 3430 I feel this DMA framework is definitely going totally different (FYI there is no integrated CAM DMA in ISP). We have to use MMU here and we are looking at adopting Trilok's and DOYU-san's MMU framework.

Can you please give some insight into this DMA split?

Thanks & Regards,
Khasim

Quoted 3 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]]

On

Quoted 6 lines

Behalf Of Sakari Ailus
Sent: Wednesday, February 28, 2007 9:59 AM
To: [email protected]
Subject: [PATCH] ARM: OMAP2: Camera: Add OMAP2 24xx camera driver.

This is a modified version of the camera driver originally from

Montavista.

Quoted 89 lines

---

drivers/media/video/omap/Makefile             |    1 +
drivers/media/video/omap/omap24xxcam-core.c   |  202 ++++
drivers/media/video/omap/omap24xxcam-dma.c    |  320 +++++++
drivers/media/video/omap/omap24xxcam-dma.h    |   65 ++
drivers/media/video/omap/omap24xxcam-dmahw.c  |  224 +++++
drivers/media/video/omap/omap24xxcam-sensor.c |  226 +++++
drivers/media/video/omap/omap24xxcam-sgdma.c  |  298 ++++++
drivers/media/video/omap/omap24xxcam-vbq.c    |  370 ++++++++
drivers/media/video/omap/omap24xxcam.c        | 1216
+++++++++++++++++++++++++
drivers/media/video/omap/omap24xxcam.h        |  659 +++++++++++++
10 files changed, 3581 insertions(+), 0 deletions(-)

create mode 100644 drivers/media/video/omap/omap24xxcam-core.c create mode 100644 drivers/media/video/omap/omap24xxcam-dma.c create mode 100644 drivers/media/video/omap/omap24xxcam-dma.h create mode 100644 drivers/media/video/omap/omap24xxcam-dmahw.c create mode 100644 drivers/media/video/omap/omap24xxcam-sensor.c create mode 100644 drivers/media/video/omap/omap24xxcam-sgdma.c create mode 100644 drivers/media/video/omap/omap24xxcam-vbq.c create mode 100644 drivers/media/video/omap/omap24xxcam.c create mode 100644 drivers/media/video/omap/omap24xxcam.h

drivers/media/video/omap/Makefile +0 -0
index 36ae615..4ca1d1d 100644
@@ -4,6 +4,7 @@ obj-$(CONFIG_VIDEO_OMAP_CAMERA) += omapcamera.o

obj-$(CONFIG_VIDEO_CAMERA_SENSOR_OV9640) += sensor_ov9640.o

objs-y$(CONFIG_ARCH_OMAP16XX) += omap16xxcam.o camera_core.o +objs-y$(CONFIG_ARCH_OMAP24XX) += omap24xxcam.o omap24xxcam-sgdma.o omap24xxcam-dma.o omap24xxcam-dmahw.o omap24xxcam-core.o omap24xxcam- sensor.o omap24xxcam-vbq.o
objs-y$(CONFIG_MACH_OMAP_H3) += h3_sensor_power.o objs-y$(CONFIG_MACH_OMAP_H4) += h4_sensor_power.o

drivers/media/video/omap/omap24xxcam-core.c new file +42 -0
new file mode 100644
index 0000000..1e30768
@@ -0,0 +1,202 @@
+/*
+ * OMAP 24xx camera high-level DMA (not hardware) and scatter-gather
+ * DMA handling
+ *
+ * Author: Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/videodev.h>
+#include <linux/pci.h>		/* needed for videobufs */
+#include <media/video-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/input.h>
+#include <linux/version.h>

drivers/media/video/omap/omap24xxcam-core.c line 52

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-core.c new file +10 -0
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/scatterlist.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>
+
+#include "omap24xxcam.h"
+
+/* Program the camera interface xclk for the frequency cam->img.xclk

based

Quoted 4 lines

on
+ * the functional clock frequency cam->img.mclk. If the specifed cam-

Quoted 1 line

img.xclk

+ * frequency is not possible based on the value of cam->img.mclk, then

the

Quoted 1 line

+ * closest xclk frequency lower than the specified xclk will be

selected.

drivers/media/video/omap/omap24xxcam-core.c

Quoted 13 lines

+ * The actual xclk frequency is returned in cam->img.xclk. If cam-

Quoted 1 line

img.xclk is zero,

+ * then xclk is turned off (stable low value).
+ */

drivers/media/video/omap/omap24xxcam-core.c new file +9 -0
+
+void omap24xxcam_core_init(struct omap24xxcam_core *core,
+			   unsigned long base)
+{
+	DBG;
+
+	core->base = base;
+
+	/* Setting the camera core AUTOIDLE bit causes problems with

frame

drivers/media/video/omap/omap24xxcam-core.c

Quoted 4 lines
drivers/media/video/omap/omap24xxcam-core.c new file +4 -0
+	 * synchronization, so we will clear the AUTOIDLE bit instead.
+	 */
+	//omap24xxcam_reg_out(cam, CC_SYSCONFIG, 0);
+	omap24xxcam_reg_out(core->base, CC_SYSCONFIG,

CC_SYSCONFIG_AUTOIDLE);

Quoted 11 lines
drivers/media/video/omap/omap24xxcam-core.c new file +11 -0
+
+	core->xclk_enabled = 0;
+}
+
+void omap24xxcam_core_exit(const struct omap24xxcam_core *core)
+{
+}
+
+/* Enable the camera core interface. */
+void omap24xxcam_core_enable(struct omap24xxcam_core *core)
+{

drivers/media/video/omap/omap24xxcam-core.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-core.c new file +10 -0
+	DBG;
+
+	/* program the camera interface DMA packet size */
+	omap24xxcam_reg_out(core->base, CC_CTRL_DMA,
+		   CC_CTRL_DMA_EN | (DMA_THRESHOLD / 4 - 1));
+
+	/* enable camera core error interrupts */
+	omap24xxcam_reg_out(core->base, CC_IRQENABLE,
+		   CC_IRQENABLE_FW_ERR_IRQ | CC_IRQENABLE_FSC_ERR_IRQ
+		   | CC_IRQENABLE_SSC_ERR_IRQ |

CC_IRQENABLE_FIFO_OF_IRQ);

Quoted 35 lines
drivers/media/video/omap/omap24xxcam-core.c new file +35 -0
+
+	/* enable the camera interface */
+	omap24xxcam_reg_out(core->base, CC_CTRL,
+		   CC_CTRL_NOBT_SYNCHRO
+		   | CC_CTRL_PAR_MODE_NOBT8
+		   | CC_CTRL_CC_EN);
+
+	if (core->xclk_enabled)
+		omap24xxcam_core_xclk_enable(core);
+}
+
+void omap24xxcam_core_disable(struct omap24xxcam_core *core)
+{
+	omap24xxcam_reg_out(core->base, CC_CTRL, 0);
+	omap24xxcam_reg_out(core->base, CC_CTRL, CC_CTRL_CC_RST);
+}
+
+void omap24xxcam_core_enable_callback(struct omap24xxcam_device *cam)
+{
+	omap24xxcam_core_enable(&cam->core);
+}
+/* reset core fifo and dma */
+/* void omap24xxcam_core_reset(struct omap24xxcam_device *cam) */
+/* { */
+/* 	omap24xxcam_reg_out(cam, CC_CTRL, CC_CTRL_CC_RST); */
+/* } */
+
+/* Interrupt service routine for camera core interrupts. */
+void omap24xxcam_core_isr(struct omap24xxcam_core *core)
+{
+	unsigned long cc_irqstatus;
+	const unsigned long cc_irqstatus_err =
+		CC_IRQSTATUS_FW_ERR_IRQ
+		| CC_IRQSTATUS_FSC_ERR_IRQ
+		| CC_IRQSTATUS_SSC_ERR_IRQ

drivers/media/video/omap/omap24xxcam-core.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-core.c new file +10 -0
+		| CC_IRQSTATUS_FIFO_UF_IRQ
+		| CC_IRQSTATUS_FIFO_OF_IRQ;
+
+	DBG;
+
+	cc_irqstatus = omap24xxcam_reg_in(core->base, CC_IRQSTATUS);
+	omap24xxcam_reg_out(core->base, CC_IRQSTATUS, cc_irqstatus);
+
+	if (cc_irqstatus & cc_irqstatus_err) {
+		printk("%s: scheduling camera reset, cc_irqstatus

0x%lx\n",

drivers/media/video/omap/omap24xxcam-core.c

Quoted 3 lines
drivers/media/video/omap/omap24xxcam-core.c new file +3 -0
+		       __FUNCTION__, cc_irqstatus);
+		omap24xxcam_camera_reset_schedule(
+			container_of(core, struct omap24xxcam_device,

core));

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-core.c new file +8 -0
+	} else {
+		if (cc_irqstatus & 0xffff)
+			printk("%s: cc_irqstatus 0x%lx\n",
+			       __FUNCTION__, cc_irqstatus);
+	}
+
+}
+

drivers/media/video/omap/omap24xxcam-core.c line 160

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-core.c new file +10 -0
+static void xclk_set(struct omap24xxcam_core *core)
+{
+	unsigned long divisor = core->mclk / core->xclk;
+
+	if (core->xclk_enabled) {
+		if (divisor == 1)
+			omap24xxcam_reg_out(core->base, CC_CTRL_XCLK,
+				   CC_CTRL_XCLK_DIV_BYPASS);
+		else
+			omap24xxcam_reg_out(core->base, CC_CTRL_XCLK,

divisor);

Quoted 54 lines
drivers/media/video/omap/omap24xxcam-core.c new file +44 -0
+	} else
+		omap24xxcam_reg_out(core->base, CC_CTRL_XCLK,
+			   CC_CTRL_XCLK_DIV_STABLE_LOW);
+
+}
+
+void omap24xxcam_core_xclk_enable(struct omap24xxcam_core *core)
+{
+	core->xclk_enabled = 1;
+	xclk_set(core);
+}
+
+void omap24xxcam_core_xclk_disable(struct omap24xxcam_core *core)
+{
+
+	core->xclk_enabled = 0;
+	xclk_set(core);
+}
+
+void omap24xxcam_core_xclk_set(struct omap24xxcam_core *core,
+			       unsigned long xclk)
+{
+	unsigned long divisor;
+
+	DBG;
+
+	if (xclk > core->mclk)
+		xclk = core->mclk;
+
+	divisor = core->mclk / xclk;
+	if (xclk * divisor < core->mclk)
+		divisor += 1;
+	if (divisor > 30)
+		divisor = 30;
+	core->xclk = core->mclk / divisor;
+
+	xclk_set(core);
+}
+
+void omap24xxcam_core_mclk_set(struct omap24xxcam_core *core,
+			       unsigned long mclk)
+{
+	core->mclk = mclk;
+}
drivers/media/video/omap/omap24xxcam-dma.c new file +3 -0
new file mode 100644
index 0000000..d10f1c8
@@ -0,0 +1,320 @@
+/*
+ * drivers/media/video/omap/omap24xxcam-dma.c
+ *

drivers/media/video/omap/omap24xxcam-dma.c line 13

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +10 -0
+ * Video-for-Linux (Version 2) camera capture driver for
+ * the OMAP24xx camera controller.
+ *
+ * Author: David Cohen <[email protected]>
+ * Based on: omap24xxcam.c by Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public

License

drivers/media/video/omap/omap24xxcam-dma.c line 14

Quoted 1 line
drivers/media/video/omap/omap24xxcam-dma.c new file +1 -0
+ * version 2. This program is licensed "as is" without any warranty of

any

Quoted 29 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +5 -0
+ * kind, whether express or implied.
+ *
+ * History:
+ * 2005/nov - David Cohen <[email protected]>
+ *            Updated the driver for the Linux Device Model and new

version of V4L2.
+ */

drivers/media/video/omap/omap24xxcam-dma.c new file +22 -0
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/videodev.h>
+#include <linux/pci.h>		/* needed for videobufs */
+#include <media/video-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/input.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/scatterlist.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +10 -0
+
+#include "omap24xxcam.h"
+#include "omap24xxcam-dma.h"
+
+/* configuration macros */
+#define CAM_NAME 	"omap24xxcam"
+#define CONFIG_H4
+
+/* Start a DMA transfer from the camera to memory.
+ * Returns zero if the transfer was successfully started, or non-zero

if

Quoted 22 lines

all
+ * DMA channels are already in use or starting is currently inhibited.
+ */

drivers/media/video/omap/omap24xxcam-dma.c new file +19 -0
+int
+omap24xxcam_dma_start(struct omap24xxcam_dma *dma, dma_addr_t start,
+	unsigned long len, dma_callback_t callback, void *arg)
+{
+	unsigned long irqflags;
+	int dmach;
+	void (*dma_notify)(struct omap24xxcam_device *cam);
+
+	DBG;
+
+	spin_lock_irqsave(&dma->lock, irqflags);
+
+	if (!dma->free_dmach || dma->dma_stop) {
+		spin_unlock_irqrestore(&dma->lock, irqflags);
+		DBG_MID(3);
+		return -EBUSY;
+	}
+
+	dmach = dma->next_dmach;

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +10 -0
+
+	dma->ch_state[dmach].callback = callback;
+	dma->ch_state[dmach].arg = arg;
+
+	omap24xxcam_dmahw_transfer_setup(dma->base, dmach, start, len);
+
+	/* We're ready to start the DMA transfer. */
+
+	if (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
+		/* A transfer is already in progress, so try to chain to

it. */

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 5 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +1 -0
+		omap24xxcam_dmahw_transfer_chain(dma->base, dmach, dma-
Quoted 1 line

free_dmach);

drivers/media/video/omap/omap24xxcam-dma.c new file +3 -0
+	}
+	else {
+		/* No transfer is in progress, so we'll just start this

one

Quoted 16 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +15 -0
+		 * now.
+		 */
+		omap24xxcam_dmahw_transfer_start(dma->base, dmach);
+	}
+
+	dma->next_dmach = (dma->next_dmach + 1) % NUM_CAMDMA_CHANNELS;
+	dma->free_dmach--;
+
+	dma_notify = dma->dma_notify;
+	dma->dma_notify = NULL;
+
+	spin_unlock_irqrestore(&dma->lock, irqflags);
+
+	if (dma_notify)
+		(*dma_notify)(container_of(container_of(dma, struct

omap24xxcam_sgdma, dma), struct omap24xxcam_device, sgdma));

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 7 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +7 -0
+
+	DBG_END;
+
+	return 0;
+}
+
+/* Abort all chained DMA transfers.  After all transfers have been

aborted

Quoted 4 lines

and
+ * the DMA controller is idle, the completion routines for any aborted transfers
+ * will be called in sequence. The DMA controller may not be idle

after

Quoted 8 lines

this
+ * routine completes, because the completion routines might start new transfers.
+ */

drivers/media/video/omap/omap24xxcam-dma.c new file +4 -0
+void
+omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, unsigned long csr)
+{
+	unsigned long irqflags;

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +10 -0
+	int dmach, i, free_dmach;
+	dma_callback_t callback;
+	void *arg;
+
+	DBG;
+
+	spin_lock_irqsave(&dma->lock, irqflags);
+
+	/* stop any DMA transfers in progress */
+	dmach = (dma->next_dmach + dma->free_dmach) %

NUM_CAMDMA_CHANNELS;

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +6 -0
+	for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) {
+		omap24xxcam_dmahw_abort_ch(dma->base, dmach);
+		dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS;
+	}
+
+	/* We have to be careful here because the callback routine might

start

drivers/media/video/omap/omap24xxcam-dma.c new file +1 -0
+	 * a new DMA transfer, and we only want to abort transfers that

were

Quoted 13 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +13 -0
+	 * started before this routine was called.
+	 */
+	free_dmach = dma->free_dmach;
+	while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) &&
+	       (free_dmach < NUM_CAMDMA_CHANNELS)) {
+		dmach = (dma->next_dmach + dma->free_dmach)
+		    % NUM_CAMDMA_CHANNELS;
+		callback = dma->ch_state[dmach].callback;
+		arg = dma->ch_state[dmach].arg;
+		dma->free_dmach++;
+		free_dmach++;
+		if (callback) {
+			/* leave interrupts disabled during callback */

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +10 -0
+			spin_unlock(&dma->lock);
+			(*callback) (dma, csr, arg);
+			spin_lock(&dma->lock);
+		}
+	}
+
+	spin_unlock_irqrestore(&dma->lock, irqflags);
+}
+
+/* Abort all chained DMA transfers.  After all transfers have been

aborted

Quoted 6 lines

and
+ * the DMA controller is idle, the completion routines for any aborted transfers
+ * will be called in sequence. If the completion routines attempt to start a
+ * new DMA transfer it will fail, so the DMA controller will be idle

after

Quoted 10 lines

this
+ * routine completes.
+ */

drivers/media/video/omap/omap24xxcam-dma.c new file +7 -0
+void
+omap24xxcam_dma_stop(struct omap24xxcam_dma *dma, unsigned long csr)
+{
+	unsigned long irqflags;
+
+	DBG;
+

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +10 -0
+	spin_lock_irqsave(&dma->lock, irqflags);
+	dma->dma_stop++;
+	spin_unlock_irqrestore(&dma->lock, irqflags);
+	omap24xxcam_dma_abort(dma, csr);
+	spin_lock_irqsave(&dma->lock, irqflags);
+	dma->dma_stop--;
+	spin_unlock_irqrestore(&dma->lock, irqflags);
+}
+
+/* Register a routine to be called once immediately after a DMA

transfer

Quoted 2 lines

is
+ * started. The purpose of this is to allow the camera interface to

be

Quoted 1 line

+ * started only after a DMA transaction has been queued in order to

avoid

Quoted 1 line

+ * DMA overruns. The registered callback routine will only be called

one

Quoted 1 line

+ * time and then discarded. Only one callback routine may be

registered

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 9 lines

at a
+ * time.
+ * Returns zero if successful, or a non-zero error code if a different callback
+ * routine has already been registered.
+ */

drivers/media/video/omap/omap24xxcam-dma.c new file +3 -0
+int
+omap24xxcam_dma_notify(struct omap24xxcam_dma *dma,
+		       void (*callback) (struct omap24xxcam_device *

cam))

Quoted 26 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +26 -0
+{
+	unsigned long irqflags;
+
+	DBG;
+
+	spin_lock_irqsave(&dma->lock, irqflags);
+
+	if (dma->dma_notify && (dma->dma_notify != callback)) {
+		spin_unlock_irqrestore(&dma->lock, irqflags);
+		return -EBUSY;
+	}
+
+	dma->dma_notify = callback;
+
+	spin_unlock_irqrestore(&dma->lock, irqflags);
+
+	return 0;
+}
+
+/* Camera DMA interrupt service routine. */
+void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma)
+{
+	int dmach;
+	dma_callback_t callback;
+	void *arg;
+	unsigned long csr;

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +10 -0
+	const unsigned long csr_error = CAMDMA_CSR_MISALIGNED_ERR
+	    | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
+	    | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
+
+	DBG;
+
+	spin_lock(&dma->lock);
+
+	if (dma->free_dmach == NUM_CAMDMA_CHANNELS) {
+		/* A camera DMA interrupt occurred while all channels

are idle,

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam-dma.c new file +1 -0
+		 * so we'll acknowledge the interrupt in the IRQSTATUS

register

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 12 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +12 -0
+		 * and exit.
+		 */
+		omap24xxcam_dmahw_ack_all(dma->base);
+		spin_unlock(&dma->lock);
+		return;
+	}
+
+	while (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
+		dmach = (dma->next_dmach + dma->free_dmach)
+		    % NUM_CAMDMA_CHANNELS;
+		if (omap24xxcam_dmahw_running(dma->base, dmach)) {
+			/* This buffer hasn't finished yet, so we're

done. */

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 5 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +5 -0
+			break;
+		}
+		csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach);
+		if (csr & csr_error) {
+			/* A DMA error occurred, so stop all DMA

transfers in

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +10 -0
+			 * progress.
+			 */
+			spin_unlock(&dma->lock);
+			omap24xxcam_dma_stop(dma, csr);
+			return;
+		} else {
+			callback = dma->ch_state[dmach].callback;
+			arg = dma->ch_state[dmach].arg;
+			dma->free_dmach++;
+			if (callback) {

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +10 -0
+				spin_unlock(&dma->lock);
+				(*callback) (dma, csr, arg);
+				spin_lock(&dma->lock);
+			}
+		}
+	}
+
+	spin_unlock(&dma->lock);
+
+	omap24xxcam_sgdma_process(container_of(dma, struct

omap24xxcam_sgdma,

drivers/media/video/omap/omap24xxcam-dma.c

Quoted 4 lines

dma));

drivers/media/video/omap/omap24xxcam-dma.c new file +3 -0
+}
+
+void omap24xxcam_dma_init(struct omap24xxcam_dma *dma, unsigned long

base)

Quoted 60 lines
drivers/media/video/omap/omap24xxcam-dma.c new file +53 -0
+{
+	int ch;
+
+	DBG;
+
+	/* group all channels on DMA IRQ0 and unmask irq */
+	spin_lock_init(&dma->lock);
+	dma->base = base;
+	dma->free_dmach = NUM_CAMDMA_CHANNELS;
+	dma->next_dmach = 0;
+	for (ch = 0; ch < NUM_CAMDMA_CHANNELS; ch++) {
+		dma->ch_state[ch].callback = NULL;
+		dma->ch_state[ch].arg = NULL;
+	}
+}
+
+/* Shutdown the camera DMA driver and controller. */
+void
+omap24xxcam_dma_exit(struct omap24xxcam_dma *dma)
+{
+	DBG;
+
+	omap24xxcam_dma_disable(dma);
+}
+
+void omap24xxcam_dma_enable(struct omap24xxcam_dma *dma)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma->lock, flags);
+
+	omap24xxcam_dmahw_init(dma->base);
+	omap24xxcam_dmahw_unmask_irq0(dma->base);
+
+	spin_unlock_irqrestore(&dma->lock, flags);
+}
+
+void omap24xxcam_dma_disable(struct omap24xxcam_dma *dma)
+{
+	int ch;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma->lock, flags);
+
+	/* Mask all DMA interrupts */
+	omap24xxcam_dmahw_mask_all(dma->base);
+
+	/* disable all DMA channels */
+	for (ch = 0; ch < NUM_CAMDMA_CHANNELS; ch++)
+		omap24xxcam_dmahw_disable_ch(dma->base, ch);
+
+	spin_unlock_irqrestore(&dma->lock, flags);
+}
drivers/media/video/omap/omap24xxcam-dma.h new file +0 -0
new file mode 100644
index 0000000..5898fd9

drivers/media/video/omap/omap24xxcam-dma.h line 8

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-dma.h new file +8 -0
@@ -0,0 +1,65 @@
+/*
+ * drivers/media/video/omap/omap24xxcam-dma.h
+ *
+ * Copyright (C) 2006 Instituto Nokia de Tecnolodia
+ *
+ * Author: David Cohen <[email protected]>
+ *
+ * This file is licensed under the terms of the GNU General Public

License

drivers/media/video/omap/omap24xxcam-dma.h line 9

Quoted 1 line
drivers/media/video/omap/omap24xxcam-dma.h new file +1 -0
+ * version 2. This program is licensed "as is" without any warranty of

any

drivers/media/video/omap/omap24xxcam-dma.h

Quoted 9 lines
drivers/media/video/omap/omap24xxcam-dma.h new file +9 -0
+ * kind, whether express or implied.
+ */
+
+/* sg_dma prototypes */
+
+void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma);
+int
+omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
+			const struct scatterlist *sglist, int sglen, int

len,

Quoted 5 lines
drivers/media/video/omap/omap24xxcam-dma.h new file +3 -0
+			 sgdma_callback_t callback, void *arg);
+void
+omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma, unsigned long

csr);
+void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma, unsigned

long

drivers/media/video/omap/omap24xxcam-dma.h

Quoted 10 lines

base);

drivers/media/video/omap/omap24xxcam-dma.h new file +9 -0
+void omap24xxcam_sgdma_exit(struct omap24xxcam_sgdma *sgdma);
+void omap24xxcam_sgdma_enable(struct omap24xxcam_sgdma *sgdma);
+void omap24xxcam_sgdma_disable(struct omap24xxcam_sgdma *sgdma);
+
+/* dma prototypes */
+
+int
+omap24xxcam_dma_start(struct omap24xxcam_dma *dma, dma_addr_t start,
+		      unsigned long len, dma_callback_t callback, void

*arg);

drivers/media/video/omap/omap24xxcam-dma.h

Quoted 7 lines
drivers/media/video/omap/omap24xxcam-dma.h new file +7 -0
+void
+omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, unsigned long csr);
+void
+omap24xxcam_dma_stop(struct omap24xxcam_dma *dma, unsigned long csr);
+int
+omap24xxcam_dma_notify(struct omap24xxcam_dma *dma,
+		       void (*callback) (struct omap24xxcam_device *

cam));

Quoted 7 lines
drivers/media/video/omap/omap24xxcam-dma.h new file +7 -0
+void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma);
+void
+omap24xxcam_dma_init(struct omap24xxcam_dma *dma, unsigned long base);
+void
+omap24xxcam_dma_exit(struct omap24xxcam_dma *dma);
+void
+omap24xxcam_dma_enable(struct omap24xxcam_dma *dma);

drivers/media/video/omap/omap24xxcam-dma.h

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dma.h new file +10 -0
+void
+omap24xxcam_dma_disable(struct omap24xxcam_dma *dma);
+
+/* dmahw prototypes */
+
+void omap24xxcam_dmahw_ack_all(unsigned long base);
+unsigned long omap24xxcam_dmahw_ack_ch(unsigned long base, int dmach);
+int omap24xxcam_dmahw_running(unsigned long base, int dmach);
+void omap24xxcam_dmahw_transfer_setup(unsigned long base, int dmach,
+				      dma_addr_t start, unsigned long

len);

Quoted 20 lines
drivers/media/video/omap/omap24xxcam-dma.h new file +10 -0
+void omap24xxcam_dmahw_transfer_chain(unsigned long base, int dmach,
+				      int free_dmach);
+void omap24xxcam_dmahw_transfer_start(unsigned long base, int dmach);
+void
+omap24xxcam_dmahw_abort_ch(unsigned long base, int dmach);
+void omap24xxcam_dmahw_mask_all(unsigned long base);
+void omap24xxcam_dmahw_unmask_irq0(unsigned long base);
+void omap24xxcam_dmahw_disable_ch(unsigned long base, int ch);
+void omap24xxcam_dmahw_init(unsigned long base);
+
drivers/media/video/omap/omap24xxcam-dmahw.c new file +3 -0
new file mode 100644
index 0000000..21d23db
@@ -0,0 +1,224 @@
+/*
+ * drivers/media/video/omap/omap24xxcam-dma.c
+ *

drivers/media/video/omap/omap24xxcam-dmahw.c line 13

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +10 -0
+ * Video-for-Linux (Version 2) camera capture driver for
+ * the OMAP24xx camera controller.
+ *
+ * Author: David Cohen <[email protected]>
+ * Based on: omap24xxcam.c by Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public

License

drivers/media/video/omap/omap24xxcam-dmahw.c line 14

Quoted 1 line
drivers/media/video/omap/omap24xxcam-dmahw.c new file +1 -0
+ * version 2. This program is licensed "as is" without any warranty of

any

Quoted 151 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +5 -0
+ * kind, whether express or implied.
+ *
+ * History:
+ * 2005/nov - David Cohen <[email protected]>
+ *            Updated the driver for the Linux Device Model and new

version of V4L2.
+ */

drivers/media/video/omap/omap24xxcam-dmahw.c new file +61 -0
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/videodev.h>
+#include <linux/pci.h>		/* needed for videobufs */
+#include <media/video-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/input.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/scatterlist.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>
+
+#include "omap24xxcam.h"
+#include "omap24xxcam-dma.h"
+
+/* configuration macros */
+#define CAM_NAME 	"omap24xxcam"
+#define CONFIG_H4
+
+/* Ack all interrupt on CSR and IRQSTATUS_L0 */
+void omap24xxcam_dmahw_ack_all(unsigned long base)
+{
+	unsigned long csr;
+	int i;
+
+	for (i = 0; i< 4; ++i) {
+		csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i));
+		/* ack interrupt in CSR */
+		omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr);
+	}
+	omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xffffffff);
+}
+
+/* Ack dmach on CSR and IRQSTATUS_L0 */
+unsigned long omap24xxcam_dmahw_ack_ch(unsigned long base, int dmach)
+{
+	unsigned long csr;
+
+	csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach));
+	/* ack interrupt in CSR */
+	omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr);
+	/* ack interrupt in IRQSTATUS */
+	omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach));
+
+	return csr;
+}
+
+int omap24xxcam_dmahw_running(unsigned long base, int dmach)
+{
+	return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) &

CAMDMA_CCR_ENABLE;

drivers/media/video/omap/omap24xxcam-dmahw.c new file +82 -0
+}
+
+void omap24xxcam_dmahw_transfer_setup(unsigned long base, int dmach,
+			     dma_addr_t start, unsigned long len)
+{
+	omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
+		       CAMDMA_CCR_SEL_SRC_DST_SYNC
+		       | CAMDMA_CCR_BS
+		       | CAMDMA_CCR_DST_AMODE_POST_INC
+		       | CAMDMA_CCR_SRC_AMODE_POST_INC
+		       | CAMDMA_CCR_FS
+		       | CAMDMA_CCR_WR_ACTIVE
+		       | CAMDMA_CCR_RD_ACTIVE
+		       | CAMDMA_CCR_SYNCHRO_CAMERA);
+	omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0);
+	omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len);
+	omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1);
+	omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach),
+		       CAMDMA_CSDP_WRITE_MODE_POSTED
+		       | CAMDMA_CSDP_DST_BURST_EN_32
+		       | CAMDMA_CSDP_DST_PACKED
+		       | CAMDMA_CSDP_SRC_BURST_EN_32
+		       | CAMDMA_CSDP_SRC_PACKED
+		       | CAMDMA_CSDP_DATA_TYPE_8BITS);
+	omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0);
+	omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start);
+	omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0);
+	omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD);
+	omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0);
+	omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0);
+	omap24xxcam_reg_out(base, CAMDMA_CSR(dmach),
+		       CAMDMA_CSR_MISALIGNED_ERR
+		       | CAMDMA_CSR_SUPERVISOR_ERR
+		       | CAMDMA_CSR_SECURE_ERR
+		       | CAMDMA_CSR_TRANS_ERR
+		       | CAMDMA_CSR_BLOCK
+		       | CAMDMA_CSR_DROP);
+	omap24xxcam_reg_out(base, CAMDMA_CICR(dmach),
+		       CAMDMA_CICR_MISALIGNED_ERR_IE
+		       | CAMDMA_CICR_SUPERVISOR_ERR_IE
+		       | CAMDMA_CICR_SECURE_ERR_IE
+		       | CAMDMA_CICR_TRANS_ERR_IE
+		       | CAMDMA_CICR_BLOCK_IE
+		       | CAMDMA_CICR_DROP_IE);
+}
+
+void omap24xxcam_dmahw_transfer_chain(unsigned long base, int dmach,
+				      int free_dmach)
+{
+	int prev_dmach, ch;
+
+	if (dmach == 0)
+		prev_dmach = NUM_CAMDMA_CHANNELS - 1;
+	else
+		prev_dmach = dmach - 1;
+	omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach),
+		       CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach);
+	/* Did we chain the DMA transfer before the previous one
+	 * finished?
+	 */
+	ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS;
+	DBG_MID(1);
+	while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch))
+		 & CAMDMA_CCR_ENABLE))
+	{
+		if (ch == dmach) {
+			/* The previous transfer has ended and this one
+			 * hasn't started, so we must not have chained
+			 * to the previous one in time.  We'll have to
+			 * start it now.
+			 */
+			omap24xxcam_dmahw_transfer_start(base, dmach);
+			break;
+		} else
+			ch = (ch + 1) % NUM_CAMDMA_CHANNELS;
+	}
+	DBG_MID(2);
+}
+
+void omap24xxcam_dmahw_transfer_start(unsigned long base, int dmach)
+{
+	omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),

drivers/media/video/omap/omap24xxcam-dmahw.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +10 -0
+		       CAMDMA_CCR_SEL_SRC_DST_SYNC
+		       | CAMDMA_CCR_BS
+		       | CAMDMA_CCR_DST_AMODE_POST_INC
+		       | CAMDMA_CCR_SRC_AMODE_POST_INC
+		       | CAMDMA_CCR_ENABLE
+		       | CAMDMA_CCR_FS
+		       | CAMDMA_CCR_SYNCHRO_CAMERA);
+}
+
+/* Abort all chained DMA transfers.  After all transfers have been

aborted

Quoted 4 lines

and
+ * the DMA controller is idle, the completion routines for any aborted transfers
+ * will be called in sequence. The DMA controller may not be idle

after

Quoted 4 lines

this
+ * routine completes, because the completion routines might start new transfers.
+ */

drivers/media/video/omap/omap24xxcam-dmahw.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +10 -0
+void
+omap24xxcam_dmahw_abort_ch(unsigned long base, int dmach)
+{
+	/* mask all interrupts from this channel */
+	omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0);
+	/* unlink this channel */
+	omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0,
+			CAMDMA_CLNK_CTRL_ENABLE_LNK);
+	/* disable this channel */
+	omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0,

CAMDMA_CCR_ENABLE);

Quoted 47 lines
drivers/media/video/omap/omap24xxcam-dmahw.c new file +37 -0
+}
+
+/* Mask all DMA interrupts */
+void omap24xxcam_dmahw_mask_all(unsigned long base)
+{
+	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0);
+	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L1, 0);
+	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L2, 0);
+	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L3, 0);
+}
+
+/* group all channels on DMA IRQ0 and unmask irq */
+void omap24xxcam_dmahw_unmask_irq0(unsigned long base)
+{
+	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0xffffffff);
+	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L1, 0);
+	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L2, 0);
+	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L3, 0);
+}
+
+void omap24xxcam_dmahw_disable_ch(unsigned long base, int ch)
+{
+	omap24xxcam_reg_out(base, CAMDMA_CCR(ch), 0);
+}
+
+void omap24xxcam_dmahw_init(unsigned long base)
+{
+	DBG;
+	omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG,
+		CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY
+	      | CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE
+	      | CAMDMA_OCP_SYSCONFIG_AUTOIDLE);
+
+	omap24xxcam_reg_merge(base, CAMDMA_GCR, 0x10,
+		CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH);
+}
+
drivers/media/video/omap/omap24xxcam-sensor.c new file +3 -0
new file mode 100644
index 0000000..bde7429
@@ -0,0 +1,226 @@
+/*
+ * drivers/media/video/omap/omap24xxcam-dma.c
+ *

drivers/media/video/omap/omap24xxcam-sensor.c line 13

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +10 -0
+ * Video-for-Linux (Version 2) camera capture driver for
+ * the OMAP24xx camera controller.
+ *
+ * Author: David Cohen <[email protected]>
+ * Based on: omap24xxcam.c by Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public

License

drivers/media/video/omap/omap24xxcam-sensor.c line 14

Quoted 1 line
drivers/media/video/omap/omap24xxcam-sensor.c new file +1 -0
+ * version 2. This program is licensed "as is" without any warranty of

any

Quoted 43 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +5 -0
+ * kind, whether express or implied.
+ *
+ * History:
+ * 2005/nov - David Cohen <[email protected]>
+ *            Updated the driver for the Linux Device Model and new

version of V4L2.
+ */

drivers/media/video/omap/omap24xxcam-sensor.c new file +36 -0
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/videodev.h>
+#include <linux/pci.h>		/* needed for videobufs */
+#include <media/video-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/input.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/scatterlist.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>
+
+#include "omap24xxcam.h"
+#include "sensor_if.h"
+#include "omap24xxcam-dma.h"
+
+/* camera driver: initialise sensor */
+int omap24xxcam_sensor_init(struct omap24xxcam_device *cam)
+{
+	int err = 0;
+
+	if (cam->sensor == NULL)
+		return -ENODEV;
+
+	if (cam->sensor_alive)

drivers/media/video/omap/omap24xxcam-sensor.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +10 -0
+		return 0;
+
+	omap24xxcam_clock_on(cam);
+	omap24xxcam_core_xclk_enable(&cam->core);
+
+	/* power up sensor during sensor initialization */
+	if (cam->sensor->power_on)
+		cam->sensor->power_on(cam->sensor);
+
+	/* initialize the sensor and define a default capture format

cam-

Quoted 31 lines
Quoted 1 line

img.pix */

drivers/media/video/omap/omap24xxcam-sensor.c new file +30 -0
+	err = cam->sensor->init(cam->sensor,
+				&cam->img.pix,
+				&omap24xxcam_camera);
+	if (err) {
+		printk(KERN_ERR CAM_NAME
+		       ": cannot initialize sensor, error %d\n", err);
+		goto out;
+	}
+	printk(KERN_INFO "Sensor is %s\n", cam->sensor->name);
+
+out:
+	omap24xxcam_core_xclk_disable(&cam->core);
+	omap24xxcam_clock_off(cam);
+
+	if (cam->sensor->power_off)
+		cam->sensor->power_off(cam->sensor);
+
+	cam->sensor_alive = 1;
+
+	return err;
+}
+
+void omap24xxcam_sensor_exit(struct omap24xxcam_device *cam)
+{
+	if (cam->sensor == NULL)
+		return;
+	if (!cam->sensor_alive)
+		return;
+
+	omap24xxcam_sensor_disable(cam);

drivers/media/video/omap/omap24xxcam-sensor.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +10 -0
+	cam->sensor->cleanup(cam->sensor);
+	cam->sensor_alive = 0;
+}
+
+/* Power-up and configure camera sensor */
+int omap24xxcam_sensor_enable(struct omap24xxcam_device *cam)
+{
+	omap24xxcam_clock_on(cam);
+
+	/* calculate xclk based on the default capture format and

default

Quoted 6 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +6 -0
+	 * frame rate
+	 */
+	omap24xxcam_core_xclk_set(
+		&cam->core,
+		cam->sensor->calc_xclk(
+			cam->sensor,

drivers/media/video/omap/omap24xxcam-sensor.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +10 -0
+			&cam->img.pix,
+			&cam->img.cparm.timeperframe));
+	omap24xxcam_core_xclk_enable(&cam->core);
+
+ 	if (cam->sensor->power_on)
+		cam->sensor->power_on(cam->sensor);
+
+	/* program the sensor for the default capture format and rate */
+	cam->sensor->configure(cam->sensor, &cam->img.pix,
+			       cam->core.xclk,

&cam->img.cparm.timeperframe);

Quoted 5 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +5 -0
+
+	return 0;
+}
+
+void omap24xxcam_sensor_disable(struct omap24xxcam_device *cam)

drivers/media/video/omap/omap24xxcam-sensor.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +10 -0
+{
+	omap24xxcam_core_xclk_disable(&cam->core);
+	omap24xxcam_clock_off(cam);
+	if (cam->sensor->power_off)
+		cam->sensor->power_off(cam->sensor);
+}
+
+void omap24xxcam_sensor_reset_work(void * data)
+{
+	struct omap24xxcam_device *cam = (struct omap24xxcam_device

*)data;

Quoted 7 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +7 -0
+
+	omap24xxcam_sensor_disable(cam);
+
+	omap24xxcam_sensor_enable(cam);
+}
+
+void omap24xxcam_sensor_reset_schedule(struct omap_camera *oc,

drivers/media/video/omap/omap24xxcam-sensor.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +10 -0
+				       struct omap_camera_sensor *os)
+{
+	struct omap24xxcam_device *cam = oc->priv;
+
+	schedule_work(&cam->sensor_reset_work);
+}
+
+EXPORT_SYMBOL(omap24xxcam_sensor_reset_schedule);
+
+unsigned long omap24xxcam_sensor_calc_xclk(struct omap24xxcam_device

*cam,

drivers/media/video/omap/omap24xxcam-sensor.c

Quoted 2 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +2 -0
+					   struct v4l2_pix_format *pix,
+					   struct v4l2_fract

*timeperframe)

Quoted 19 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +19 -0
+{
+	return cam->sensor->calc_xclk(cam->sensor,
+				      pix,
+				      timeperframe);
+}
+
+int omap24xxcam_sensor_try_format(struct omap24xxcam_device *cam,
+				  struct v4l2_pix_format *pix)
+{
+	return cam->sensor->try_format(cam->sensor,
+				       pix);
+}
+
+int omap24xxcam_sensor_set_format(struct omap24xxcam_device *cam,
+				  struct v4l2_pix_format *pix,
+				  struct v4l2_fract *timeperframe,
+				  unsigned long *xclk)
+{
+	int err;

drivers/media/video/omap/omap24xxcam-sensor.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +10 -0
+
+	if (timeperframe->numerator == 0
+	    || timeperframe->denominator == 0)
+		return -EINVAL;
+
+	*xclk = cam->sensor->calc_xclk(cam->sensor, pix, timeperframe);
+
+	omap24xxcam_core_xclk_set(&cam->core, *xclk);
+
+	err = cam->sensor->configure(cam->sensor, pix, *xclk,

timeperframe);

Quoted 100 lines
drivers/media/video/omap/omap24xxcam-sensor.c new file +41 -0
+
+	return err;
+}
+
+/* This should be called by the sensor code whenever it's ready */
+int omap24xxcam_sensor_register(struct omap_camera *oc,
+				struct omap_camera_sensor *os)
+{
+	struct omap24xxcam_device *cam = oc->priv;
+	int rval;
+
+	/* the device has not been initialised yet */
+	if (cam == NULL)
+		return -ENODEV;
+	if (os == NULL)
+		return -EINVAL;
+	if (cam->sensor != NULL)
+		return -EBUSY;
+
+	cam->sensor = os;
+	rval = omap24xxcam_device_enable(cam);
+
+	if (rval)
+		cam->sensor = NULL;
+	return rval;
+}
+
+EXPORT_SYMBOL(omap24xxcam_sensor_register);
+
+void omap24xxcam_sensor_unregister(struct omap_camera *oc,
+				   struct omap_camera_sensor *os)
+{
+	struct omap24xxcam_device *cam = oc->priv;
+
+	BUG_ON(cam->users != 0);
+	BUG_ON(cam->sensor == NULL);
+
+	cam->sensor = NULL;
+}
+
+EXPORT_SYMBOL(omap24xxcam_sensor_unregister);
drivers/media/video/omap/omap24xxcam-sgdma.c new file +52 -0
new file mode 100644
index 0000000..0243a59
@@ -0,0 +1,298 @@
+/*
+ * OMAP 24xx camera high-level DMA (not hardware) and scatter-gather
+ * DMA handling
+ *
+ * Author: Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/videodev.h>
+#include <linux/pci.h>		/* needed for videobufs */
+#include <media/video-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/input.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/scatterlist.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>
+
+#include "omap24xxcam.h"
+#include "omap24xxcam-dma.h"
+

drivers/media/video/omap/omap24xxcam-sgdma.c line 62

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +10 -0
+/*
+ * Scatter-gather DMA
+ *
+ * High-level DMA construct for transferring whole picture frames to
+ * memory that is discontinuous.
+ */
+
+/* DMA completion routine for the scatter-gather DMA fragments. */
+static void
+omap24xxcam_sgdma_callback(struct omap24xxcam_dma *dma, unsigned long

csr,

Quoted 18 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +18 -0
+			    void *arg)
+{
+	struct omap24xxcam_sgdma *sgdma =
+		container_of(dma, struct omap24xxcam_sgdma, dma);
+	int sgslot = (int)arg;
+	struct sgdma_state *sg_state;
+	const unsigned long csr_error = CAMDMA_CSR_MISALIGNED_ERR
+	    | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
+	    | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
+
+	DBG;
+
+	spin_lock(&sgdma->lock);
+
+	/* We got an interrupt, we can remove the timer */
+	del_timer(&sgdma->reset_timer);
+
+	sg_state = sgdma->sg_state + sgslot;

drivers/media/video/omap/omap24xxcam-sgdma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +10 -0
+	if (!sg_state->queued_sglist) {
+		spin_unlock(&sgdma->lock);
+		printk(KERN_DEBUG CAM_NAME
+		       ": sgdma completed when none queued!\n");
+		return;
+	}
+
+	sg_state->csr |= csr;
+	if (!--sg_state->queued_sglist) {
+		/* Queue for this sglist is empty, so check to see if

we're

Quoted 11 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +11 -0
+		 * done.
+		 */
+		if ((sg_state->next_sglist == sg_state->sglen)
+		    || (sg_state->csr & csr_error)) {
+			sgdma_callback_t callback = sg_state->callback;
+			void *arg = sg_state->arg;
+			unsigned long sg_csr = sg_state->csr;
+			/* All done with this sglist */
+			sgdma->free_sgdma++;
+			if (callback) {
+				spin_unlock(&sgdma->lock);

drivers/media/video/omap/omap24xxcam-sgdma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +10 -0
+				(*callback) (sgdma, sg_csr, arg);
+				return;
+			}
+		}
+	}
+
+	spin_unlock(&sgdma->lock);
+}
+
+/* Process the scatter-gather DMA queue by starting queued transfers.

*/

Quoted 13 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +13 -0
+void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma)
+{
+	unsigned long irqflags;
+	int queued_sgdma, sgslot;
+	struct sgdma_state *sg_state;
+	const unsigned long csr_error = CAMDMA_CSR_MISALIGNED_ERR
+	    | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
+	    | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
+
+	DBG;
+
+	spin_lock_irqsave(&sgdma->lock, irqflags);
+

drivers/media/video/omap/omap24xxcam-sgdma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +10 -0
+	queued_sgdma = NUM_SG_DMA - sgdma->free_sgdma;
+	sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
+	while (queued_sgdma > 0) {
+		sg_state = sgdma->sg_state + sgslot;
+		while ((sg_state->next_sglist < sg_state->sglen) &&
+		       !(sg_state->csr & csr_error)) {
+			const struct scatterlist *sglist;
+			unsigned int len;
+
+			sglist = sg_state->sglist +

sg_state->next_sglist;

drivers/media/video/omap/omap24xxcam-sgdma.c line 136

Quoted 2 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +2 -0
+			/* try to start the next DMA transfer */
+			if ( sg_state->next_sglist + 1 ==

sg_state->sglen ) {

drivers/media/video/omap/omap24xxcam-sgdma.c line 138

Quoted 2 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +2 -0
+				/*
+				 *  On the last sg, we handle the case

where

drivers/media/video/omap/omap24xxcam-sgdma.c line 139

Quoted 1 line
drivers/media/video/omap/omap24xxcam-sgdma.c new file +1 -0
+				 *  cam->img.pix.sizeimage % PAGE_ALIGN

!= 0

drivers/media/video/omap/omap24xxcam-sgdma.c line 141

Quoted 2 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +2 -0
+				 */
+				len = sg_state->len -

sg_state->bytes_read;

drivers/media/video/omap/omap24xxcam-sgdma.c line 159

Quoted 8 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +5 -0
+			} else {
+				len = sg_dma_len(sglist);
+			}
+
+			if (omap24xxcam_dma_start(&sgdma->dma,

sg_dma_address(sglist),

drivers/media/video/omap/omap24xxcam-sgdma.c new file +2 -0
+						  len,
+

omap24xxcam_sgdma_callback,

drivers/media/video/omap/omap24xxcam-sgdma.c

Quoted 3 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +3 -0
+						  (void *)sgslot)) {
+				/* DMA start failed */
+				spin_unlock_irqrestore(&sgdma->lock,

irqflags);

Quoted 18 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +18 -0
+				return;
+			} else {
+				unsigned long expires;
+				/* DMA start was successful */
+				sg_state->next_sglist++;
+				sg_state->bytes_read += len;
+				sg_state->queued_sglist++;
+
+				/* We start the reset timer */
+				expires = jiffies + HZ;
+				mod_timer(&sgdma->reset_timer, expires);
+			}
+		}
+		queued_sgdma--;
+		sgslot = (sgslot + 1) % NUM_SG_DMA;
+	}
+
+	spin_unlock_irqrestore(&sgdma->lock, irqflags);

drivers/media/video/omap/omap24xxcam-sgdma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +10 -0
+	DBG_END;
+}
+
+/* Queue a scatter-gather DMA transfer from the camera to memory.
+ * Returns zero if the transfer was successfully queued, or
+ * non-zero if all of the scatter-gather slots are already in use.
+ */
+int
+omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
+			const struct scatterlist *sglist, int sglen, int

len,

Quoted 40 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +40 -0
+			 sgdma_callback_t callback, void *arg)
+{
+	unsigned long irqflags;
+	struct sgdma_state *sg_state;
+
+	DBG;
+
+	if ((sglen < 0) || ((sglen > 0) & !sglist))
+		return -EINVAL;
+
+	spin_lock_irqsave(&sgdma->lock, irqflags);
+
+	if (!sgdma->free_sgdma) {
+		spin_unlock_irqrestore(&sgdma->lock, irqflags);
+		return -EBUSY;
+	}
+
+	sg_state = sgdma->sg_state + sgdma->next_sgdma;
+
+	sg_state->sglist = sglist;
+	sg_state->sglen = sglen;
+	sg_state->next_sglist = 0;
+	sg_state->bytes_read = 0;
+	sg_state->len = len;
+	sg_state->queued_sglist = 0;
+	sg_state->csr = 0;
+	sg_state->callback = callback;
+	sg_state->arg = arg;
+
+	sgdma->next_sgdma = (sgdma->next_sgdma + 1) % NUM_SG_DMA;
+	sgdma->free_sgdma--;
+
+	spin_unlock_irqrestore(&sgdma->lock, irqflags);
+
+	omap24xxcam_sgdma_process(sgdma);
+
+	return 0;
+}
+
+/* Sync scatter-gather DMA by aborting any DMA transfers currently in
Quoted 4 lines

progress.
+ * Any queued scatter-gather DMA transactions that have not yet been started
+ * will remain queued. The DMA controller will be idle after this

routine

drivers/media/video/omap/omap24xxcam-sgdma.c

Quoted 6 lines

+ * completes. When the scatter-gather queue is restarted, the next
+ * scatter-gather DMA transfer will begin at the start of a new transaction.
+ */

drivers/media/video/omap/omap24xxcam-sgdma.c new file +2 -0
+void
+omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma, unsigned long

csr)

Quoted 4 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +4 -0
+{
+	unsigned long irqflags;
+	int sgslot;
+	struct sgdma_state *sg_state;

drivers/media/video/omap/omap24xxcam-sgdma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +10 -0
+
+	DBG;
+
+	/* stop any DMA transfers in progress */
+	omap24xxcam_dma_stop(&sgdma->dma, csr);
+
+	spin_lock_irqsave(&sgdma->lock, irqflags);
+
+	if (sgdma->free_sgdma < NUM_SG_DMA) {
+		sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) %

NUM_SG_DMA;

drivers/media/video/omap/omap24xxcam-sgdma.c

Quoted 3 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +3 -0
+		sg_state = sgdma->sg_state + sgslot;
+		if (sg_state->next_sglist != 0) {
+			/* This DMA transfer was in progress, so abort

it. */

Quoted 7 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +7 -0
+			sgdma_callback_t callback = sg_state->callback;
+			void *arg = sg_state->arg;
+			sgdma->free_sgdma++;
+			if (callback) {
+				/* leave interrupts masked */
+				spin_unlock(&sgdma->lock);
+				(*callback) (sgdma, csr, arg);

drivers/media/video/omap/omap24xxcam-sgdma.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-sgdma.c new file +10 -0
+				spin_lock(&sgdma->lock);
+			}
+		}
+	}
+
+	spin_unlock_irqrestore(&sgdma->lock, irqflags);
+}
+
+
+void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma, unsigned

long

Quoted 115 lines

base)

drivers/media/video/omap/omap24xxcam-sgdma.c new file +38 -0
+{
+	int sg;
+
+	DBG;
+
+	spin_lock_init(&sgdma->lock);
+	sgdma->free_sgdma = NUM_SG_DMA;
+	sgdma->next_sgdma = 0;
+	for (sg = 0; sg < NUM_SG_DMA; sg++) {
+		sgdma->sg_state[sg].sglen = 0;
+		sgdma->sg_state[sg].next_sglist = 0;
+		sgdma->sg_state[sg].bytes_read = 0;
+		sgdma->sg_state[sg].queued_sglist = 0;
+		sgdma->sg_state[sg].csr = 0;
+		sgdma->sg_state[sg].callback = NULL;
+		sgdma->sg_state[sg].arg = NULL;
+	}
+
+	omap24xxcam_dma_init(&sgdma->dma, base);
+}
+
+void omap24xxcam_sgdma_exit(struct omap24xxcam_sgdma *sgdma)
+{
+	omap24xxcam_sgdma_sync(sgdma, CAMDMA_CSR_TRANS_ERR);
+	omap24xxcam_dma_exit(&sgdma->dma);
+}
+
+void omap24xxcam_sgdma_enable(struct omap24xxcam_sgdma *sgdma)
+{
+	omap24xxcam_dma_enable(&sgdma->dma);
+	omap24xxcam_sgdma_process(sgdma);
+}
+
+void omap24xxcam_sgdma_disable(struct omap24xxcam_sgdma *sgdma)
+{
+	omap24xxcam_sgdma_sync(sgdma, CAMDMA_CSR_TRANS_ERR);
+	omap24xxcam_dma_disable(&sgdma->dma);
+}
drivers/media/video/omap/omap24xxcam-vbq.c new file +69 -0
new file mode 100644
index 0000000..f6d8803
@@ -0,0 +1,370 @@
+/*
+ * OMAP 24xx camera high-level DMA (not hardware) and scatter-gather
+ * DMA handling
+ *
+ * Author: Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/videodev.h>
+#include <linux/pci.h>		/* needed for videobufs */
+#include <media/video-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/input.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/scatterlist.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>
+
+#include "omap24xxcam.h"
+#include "omap24xxcam-dma.h"
+
+static void
+omap24xxcam_vbq_free_mmap_buffer(struct videobuf_buffer *vb)
+{
+	int i;
+	size_t alloc_size;
+	struct page *page;
+
+	if (vb->dma.sglist == NULL)
+		return;
+
+	i = vb->dma.sglen;
+	while (i) {
+		i--;
+		alloc_size = vb->dma.sglist[i].length;
+		page = vb->dma.sglist[i].page;
+		do {
+			ClearPageReserved(page++);

drivers/media/video/omap/omap24xxcam-vbq.c line 79

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+		} while (alloc_size -= PAGE_SIZE);
+		__free_pages(vb->dma.sglist[i].page,
+			     get_order(vb->dma.sglist[i].length));
+	}
+
+	kfree(vb->dma.sglist);
+	vb->dma.sglist = NULL;
+}
+
+/* Allocate physically as contiguous as possible buffer for video

frame

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 8 lines

and
+ * build DMA scatter-gather list for it
+ */

drivers/media/video/omap/omap24xxcam-vbq.c new file +5 -0
+static int
+omap24xxcam_vbq_alloc_mmap_buffer(struct videobuf_buffer *vb)
+{
+	unsigned long order;
+	size_t alloc_size, size = vb->bsize; /* vb->bsize is page

aligned */

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 4 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +4 -0
+	struct page *page;
+	int max_pages, err = 0, i = 0;
+
+	/* allocate maximum size scatter-gather list. Note this is

overhead.

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 13 lines

We

drivers/media/video/omap/omap24xxcam-vbq.c new file +3 -0
+	 * may not use as many entries as we allocate */
+	max_pages = vb->bsize >> PAGE_SHIFT;
+	vb->dma.sglist = kcalloc(max_pages, sizeof(*vb->dma.sglist),

GFP_KERNEL);

drivers/media/video/omap/omap24xxcam-vbq.c new file +8 -0
+	if (vb->dma.sglist == NULL) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	while (size) {
+		order = get_order(size);
+		/* do not over-allocate even if we would get larger

contiguous

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 5 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +5 -0
+		 * chunk that way */
+		if ((PAGE_SIZE << order) > size)
+			order--;
+
+		/* try to allocate as many contiguous pages as possible

*/

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 2 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +2 -0
+		page = alloc_pages(GFP_KERNEL | GFP_DMA, order);
+		/* if allocation fails, try to allocate smaller amount

*/

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 11 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +11 -0
+		while (page == NULL) {
+			order--;
+			page = alloc_pages(GFP_KERNEL | GFP_DMA, order);
+			if (page == NULL && !order) {
+				err = -ENOMEM;
+				goto out;
+			}
+		}
+		size -= (PAGE_SIZE << order);
+
+		/* append allocated chunk of pages into scatter-gather

list */

Quoted 6 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +6 -0
+		vb->dma.sglist[i].page = page;
+		vb->dma.sglist[i].length = (PAGE_SIZE << order);
+		vb->dma.sglen++;
+		i++;
+
+		alloc_size = (PAGE_SIZE << order);

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+
+		/* clear pages before giving them to user space */
+		memset(page_address(page), 0, alloc_size);
+
+		/* mark allocated pages reserved */
+		do {
+			SetPageReserved(page++);
+		} while (alloc_size -= PAGE_SIZE);
+	}
+	/* REVISIT: not fully correct to assign nr_pages == sglen but

video-

Quoted 30 lines

buf

drivers/media/video/omap/omap24xxcam-vbq.c new file +29 -0
+	 * is passing nr_pages for e.g. unmap_sg calls */
+	vb->dma.nr_pages = vb->dma.sglen;
+	vb->dma.direction = PCI_DMA_FROMDEVICE;
+
+	return 0;
+
+out:
+	omap24xxcam_vbq_free_mmap_buffer(vb);
+	return err;
+}
+
+int
+omap24xxcam_vbq_alloc_mmap_buffers(struct videobuf_queue *vbq,
+				   unsigned int count)
+{
+	int i, err = 0;
+
+	mutex_lock(&vbq->lock);
+	for (i = 0; i < count; i++) {
+		err = omap24xxcam_vbq_alloc_mmap_buffer(vbq->bufs[i]);
+		if (err)
+			goto out;
+		printk("%s: sglen is %d for buffer %d\n",
+		       __FUNCTION__, vbq->bufs[i]->dma.sglen, i);
+	}
+	mutex_unlock(&vbq->lock);
+
+	return 0;
+out:

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+	while (i) {
+		i--;
+		omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]);
+	}
+	mutex_unlock(&vbq->lock);
+
+	return err;
+}
+
+/* This routine is called from interrupt context when a scatter-gather

DMA

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 4 lines

+ * transfer of a videobuf_buffer completes.
+ */

drivers/media/video/omap/omap24xxcam-vbq.c new file +2 -0
+void
+omap24xxcam_vbq_complete(struct omap24xxcam_sgdma *sgdma, unsigned

long

Quoted 11 lines

csr,

drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+			 void *arg)
+{
+	struct omap24xxcam_device *cam =
+		container_of(sgdma, struct omap24xxcam_device, sgdma);
+	struct omap24xxcam_capture *capture = &cam->capture;
+	struct videobuf_buffer *vb = (struct videobuf_buffer *)arg;
+	const unsigned long csr_error = CAMDMA_CSR_MISALIGNED_ERR
+	    | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
+	    | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
+

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+	DBG;
+
+	spin_lock(&capture->lock);
+
+	do_gettimeofday(&vb->ts);
+	vb->field_count = capture->field_count;
+	capture->field_count += 2;
+	if (csr & csr_error) {
+		vb->state = STATE_ERROR;
+		printk(KERN_INFO "%s: scheduling camera reset, csr

0x%lx\n",

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+		       __FUNCTION__, csr);
+		omap24xxcam_camera_reset_schedule(cam);
+	} else
+		vb->state = STATE_DONE;
+	wake_up(&vb->done);
+	spin_unlock(&capture->lock);
+}
+
+void
+omap24xxcam_vbq_release(struct videobuf_queue *vbq, struct

videobuf_buffer

Quoted 10 lines

*vb)

drivers/media/video/omap/omap24xxcam-vbq.c new file +9 -0
+{
+	struct videobuf_dmabuf *dma = &vb->dma;
+	DBG;
+
+	videobuf_waiton(vb, 0, 0);
+	if (vb->memory == V4L2_MEMORY_MMAP) {
+		dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen,
+			     dma->direction);
+		dma->direction = PCI_DMA_NONE;

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+		omap24xxcam_vbq_free_mmap_buffer(vb);
+	} else {
+		videobuf_dma_unmap(vbq, &vb->dma);
+		videobuf_dma_free(&vb->dma);
+	}
+
+	vb->state = STATE_NEEDS_INIT;
+}
+
+/* Limit the number of available kernel image capture buffers based on

the

Quoted 1 line

+ * number requested, the currently selected image size, and the

maximum

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 12 lines

+ * amount of memory permitted for kernel capture buffers.
+ */

drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+static int
+omap24xxcam_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt,
+		      unsigned int *size)
+{
+	struct omap24xxcam_device *cam = vbq->priv_data;
+
+	DBG;
+
+	if (*cnt <= 0)
+		*cnt = VIDEO_MAX_FRAME;	/* supply a default number of

buffers

Quoted 9 lines

*/

drivers/media/video/omap/omap24xxcam-vbq.c new file +8 -0
+
+	if (*cnt > VIDEO_MAX_FRAME)
+		*cnt = VIDEO_MAX_FRAME;
+
+	spin_lock(&cam->img.img_lock);
+
+	*size = cam->img.pix.sizeimage;
+

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+	spin_unlock(&cam->img.img_lock);
+
+	while (*size * *cnt > cam->capture_mem)
+		(*cnt)--;
+
+	return 0;
+}
+
+static int
+omap24xxcam_dma_iolock(struct videobuf_queue* vbq, struct

videobuf_dmabuf

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 6 lines

*dma)

drivers/media/video/omap/omap24xxcam-vbq.c new file +5 -0
+{
+	int err = 0;
+
+	dma->direction = PCI_DMA_FROMDEVICE;
+	if (!dma_map_sg(vbq->dev, dma->sglist, dma->sglen,

dma->direction)) {

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 11 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +11 -0
+		kfree(dma->sglist);
+		dma->sglist = NULL;
+		dma->sglen = 0;
+		err = -EIO;
+	}
+
+	return err;
+}
+
+static int
+omap24xxcam_vbq_prepare(struct videobuf_queue *vbq, struct

videobuf_buffer

Quoted 10 lines

*vb,

drivers/media/video/omap/omap24xxcam-vbq.c new file +9 -0
+			enum v4l2_field field)
+{
+	struct omap24xxcam_device *cam = vbq->priv_data;
+	int err = 0;
+
+	DBG;
+
+	spin_lock(&cam->img.img_lock);
+

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+	if (vb->baddr) {
+		/* This is a userspace buffer. */
+		if (cam->img.pix.sizeimage > vb->bsize) {
+			/* The buffer isn't big enough. */
+			err = -EINVAL;
+		} else
+			vb->size = cam->img.pix.sizeimage;
+	} else if (!vb->baddr) {
+		if (vb->state != STATE_NEEDS_INIT) {
+			/* We have a kernel bounce buffer that has

already been

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 4 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +4 -0
+			 * allocated.
+			 */
+			if (cam->img.pix.sizeimage > vb->size) {
+				/* The image size has been changed to a

larger

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam-vbq.c new file +1 -0
+				 * size since this buffer was allocated,

so we

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 9 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +9 -0
+				 * need to free and reallocate it.
+				 */
+				spin_unlock(&cam->img.img_lock);
+				omap24xxcam_vbq_release(vbq, vb);
+				spin_lock(&cam->img.img_lock);
+				vb->size = cam->img.pix.sizeimage;
+			}
+		} else {
+			/* We need to allocate a new kernel bounce

buffer. */

Quoted 6 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +6 -0
+			vb->size = cam->img.pix.sizeimage;
+		}
+	}
+
+	vb->width = cam->img.pix.width;
+	vb->height = cam->img.pix.height;

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+	vb->field = field;
+
+	spin_unlock(&cam->img.img_lock);
+
+	if (err)
+		return err;
+
+	if (vb->state == STATE_NEEDS_INIT) {
+		if (vb->memory == V4L2_MEMORY_MMAP)
+			/* we have built the scatter-gather list by

ourself so

Quoted 6 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +6 -0
+			 * do the scatter-gather mapping as well */
+			err = omap24xxcam_dma_iolock(vbq, &vb->dma);
+		else
+			err = videobuf_iolock(vbq, vb, NULL);
+	}
+

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +10 -0
+	if (!err)
+		vb->state = STATE_PREPARED;
+	else
+		omap24xxcam_vbq_release(vbq, vb);
+
+	return err;
+}
+
+static void
+omap24xxcam_vbq_queue(struct videobuf_queue *vbq, struct

videobuf_buffer

Quoted 11 lines

*vb)

drivers/media/video/omap/omap24xxcam-vbq.c new file +9 -0
+{
+	struct omap24xxcam_device *cam = vbq->priv_data;
+	enum videobuf_state state = vb->state;
+	int err;
+
+	DBG;
+
+	vb->state = STATE_QUEUED;
+	err = omap24xxcam_sgdma_queue(&cam->sgdma, vb->dma.sglist, vb-
Quoted 1 line

dma.sglen,

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 4 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +4 -0
+				      cam->img.pix.sizeimage,
+				       omap24xxcam_vbq_complete, vb);
+	if (err) {
+		/* Oops.  We're not supposed to get any errors here.

The only

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam-vbq.c new file +1 -0
+		 * way we could get an error is if we ran out of

scatter-gather

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam-vbq.c new file +1 -0
+		 * DMA slots, but we are supposed to have at least as

many

drivers/media/video/omap/omap24xxcam-vbq.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam-vbq.c new file +1 -0
+		 * scatter-gather DMA slots as video buffers so that

can't

Quoted 24 lines
drivers/media/video/omap/omap24xxcam-vbq.c new file +15 -0
+		 * happen.
+		 */
+		printk(KERN_DEBUG CAM_NAME
+		       ": Failed to queue a video buffer for DMA!\n");
+		vb->state = state;
+	}
+}
+
+struct videobuf_queue_ops omap24xxcam_vbq_ops = {
+ 	.buf_setup = omap24xxcam_vbq_setup,
+	.buf_prepare = omap24xxcam_vbq_prepare,
+	.buf_queue = omap24xxcam_vbq_queue,
+	.buf_release = omap24xxcam_vbq_release,
+};
+
drivers/media/video/omap/omap24xxcam.c new file +2 -0
new file mode 100644
index 0000000..4f954ed
@@ -0,0 +1,1216 @@
+/*
+ * drivers/media/video/omap/omap24xxcam.c

drivers/media/video/omap/omap24xxcam.c line 12

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+ *
+ * Video-for-Linux (Version 2) camera capture driver for
+ * the OMAP24xx camera controller.
+ *
+ * Author: Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public

License

drivers/media/video/omap/omap24xxcam.c line 13

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+ * version 2. This program is licensed "as is" without any warranty of

any

Quoted 46 lines
drivers/media/video/omap/omap24xxcam.c new file +5 -0
+ * kind, whether express or implied.
+ *
+ * History:
+ * 2005/nov - David Cohen <[email protected]>
+ *            Updated the driver for the Linux Device Model and new

version of V4L2.
+ */

drivers/media/video/omap/omap24xxcam.c new file +39 -0
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/pci.h>		/* needed for videobufs */
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <media/video-buf.h>
+#include <media/v4l2-common.h>
+
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/scatterlist.h>
+#include <asm/irq.h>
+#include <asm/semaphore.h>
+#include <asm/processor.h>
+
+#include <asm/arch/clock.h>
+

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+#include "omap24xxcam.h"
+#include "omap24xxcam-dma.h"
+
+#include "sensor_if.h"
+
+/* configuration macros */
+
+//#define DEBUG_CAM
+#ifdef DEBUG_CAM
+#define DBG		printk(KERN_INFO CAM_NAME ": %s\n",

__FUNCTION__)

Quoted 1 line

+#define DBG_END printk(KERN_INFO CAM_NAME ": %s END!\n",

__FUNCTION__)

Quoted 14 lines

+#define DBG_MID(x) printk(KERN_INFO CAM_NAME ": %s - %d\n",
__FUNCTION__, x)

drivers/media/video/omap/omap24xxcam.c new file +12 -0
+#else
+#define DBG
+#define DBG_END
+#define DBG_MID(x)
+#endif
+
+#define RESET_TIMEOUT (HZ / 5)
+
+struct omap_camera omap24xxcam_camera = {
+	.sensor_register = &omap24xxcam_sensor_register,
+	.sensor_unregister = &omap24xxcam_sensor_unregister,
+	.sensor_reset = &omap24xxcam_sensor_reset_schedule,

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+};
+
+struct omap24xxcam_device *camera_module;
+
+static struct platform_device omap24xxcam_dev;
+
+static int omap24xxcam_remove(struct platform_device *pdev);
+
+/* module parameters */
+static int video_nr = -1;	/* video device minor (-1 ==> auto

assign) */

drivers/media/video/omap/omap24xxcam.c line 144

Quoted 6 lines
drivers/media/video/omap/omap24xxcam.c new file +6 -0
+/* Maximum amount of memory to use for capture buffers.
+ * Default is 4800KB, enough to double-buffer SXGA.
+ */
+static int capture_mem = 1280 * 960 * 2 * 2;
+
+/*

-----------------------------------------------------------------------

drivers/media/video/omap/omap24xxcam.c

Quoted 3 lines

--- */

drivers/media/video/omap/omap24xxcam.c new file +2 -0
+
+/* Initialize the camera subsystem (camera core, camera DMA, and

camera

Quoted 14 lines

MMU) */

drivers/media/video/omap/omap24xxcam.c new file +13 -0
+static void omap24xxcam_reset(const struct omap24xxcam_device *cam)
+{
+	unsigned long timeout;
+
+	DBG;
+
+	omap24xxcam_reg_out(cam->mmio_base,
+			    CAM_SYSCONFIG,
+			    CAM_SYSCONFIG_SOFTRESET);
+
+	/* wait for reset to complete */
+	timeout = jiffies + RESET_TIMEOUT;
+

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+	while (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
+		 & CAM_SYSSTATUS_RESETDONE)
+	       && time_before(jiffies, timeout)) {
+		msleep(1);
+	}
+
+	if (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
+	      & CAM_SYSSTATUS_RESETDONE)) {
+		printk(KERN_WARNING CAM_NAME
+		       ": timeout waiting for camera subsystem

reset\n");

Quoted 7 lines
drivers/media/video/omap/omap24xxcam.c new file +7 -0
+	}
+
+	/* set the camera subsystem autoidle bit */
+	omap24xxcam_reg_out(cam->mmio_base, CAM_SYSCONFIG,
+			    CAM_SYSCONFIG_AUTOIDLE);
+
+	/* initialize the camera MMU */

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+	/* set the camera MMU autoidle bit */
+	omap24xxcam_reg_out(cam->mmio_base,
+			    CAMMMU_REG_OFFSET + CAMMMU_SYSCONFIG,
+			    CAMMMU_SYSCONFIG_AUTOIDLE);
+}
+
+/* This gets called whenever a DMA transfer is stalled */
+static void omap24xxcam_reset_timer(unsigned long data)
+{
+	struct omap24xxcam_device *cam = (struct omap24xxcam_device

*)data;

drivers/media/video/omap/omap24xxcam.c

Quoted 13 lines
drivers/media/video/omap/omap24xxcam.c new file +13 -0
+
+	printk("%s()\n", __FUNCTION__);
+
+	/*
+	 * Sensor reset must not be called from
+	 * interrupt context as it may sleep
+	 */
+	omap24xxcam_camera_reset_schedule(cam);
+}
+
+void omap24xxcam_camera_reset_work(void * data)
+{
+	struct omap24xxcam_device *cam = (struct omap24xxcam_device

*)data;

drivers/media/video/omap/omap24xxcam.c

Quoted 12 lines
drivers/media/video/omap/omap24xxcam.c new file +12 -0
+
+	/* Disable and reset the camera interface. */
+	omap24xxcam_core_disable(&cam->core);
+
+ 	/* Stop the DMA controller and frame sync scatter-gather DMA. */
+	omap24xxcam_sgdma_disable(&cam->sgdma);
+
+	/* Reset and re-initialize the entire camera subsystem.
+	 * Resetting the camera FIFO via the CC_RST bit in the CC_CTRL
+	 * register is supposed to be sufficient to recover from a
+	 * camera interface error, but it doesn't seem to be enough.  If
+	 * we only do that then subsequent image captures are out of

sync

drivers/media/video/omap/omap24xxcam.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	 * by either one or two times DMA_THRESHOLD bytes.  Resetting

and

drivers/media/video/omap/omap24xxcam.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	 * re-initializing the entire camera subsystem prevents the

problem

drivers/media/video/omap/omap24xxcam.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	 * with frame synchronization.  Calling cam_init() from an ISR

is

drivers/media/video/omap/omap24xxcam.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	 * undesirable since it waits an indeterminate amount of time

for the

drivers/media/video/omap/omap24xxcam.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	 * camera subsystem reset to complete.  If we ever figure out

exactly

drivers/media/video/omap/omap24xxcam.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	 * what needs to be reset to recover from a camera interface

error,

drivers/media/video/omap/omap24xxcam.c

Quoted 8 lines
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	 * maybe we can replace this global reset with something less

drastic.

drivers/media/video/omap/omap24xxcam.c new file +6 -0
+	 */
+	omap24xxcam_reset(cam);
+	omap24xxcam_core_enable(&cam->core);
+
+	if (cam->capture.streaming) {
+		/* Preview or capture is in progress, so we need to

register

drivers/media/video/omap/omap24xxcam.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+		 * our routine to restart the camera interface the next

time a

Quoted 16 lines
drivers/media/video/omap/omap24xxcam.c new file +3 -0
+		 * DMA transfer is queued.
+		 */
+		omap24xxcam_dma_notify(&cam->sgdma.dma,

omap24xxcam_core_enable_callback);

drivers/media/video/omap/omap24xxcam.c new file +11 -0
+	}
+
+	omap24xxcam_sgdma_enable(&cam->sgdma);
+}
+
+void omap24xxcam_camera_reset_schedule(struct omap24xxcam_device *cam)
+{
+	schedule_work(&cam->camera_reset_work);
+}
+
+static irqreturn_t omap24xxcam_isr(int irq, void *arg, struct pt_regs

*regs)

drivers/media/video/omap/omap24xxcam.c

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.c new file +2 -0
+{
+	struct omap24xxcam_device *cam = (struct omap24xxcam_device

*)arg;

Quoted 20 lines
drivers/media/video/omap/omap24xxcam.c new file +19 -0
+	unsigned long irqstatus;
+	unsigned int irqhandled = 0;
+
+	DBG;
+
+	irqstatus = omap24xxcam_reg_in(cam->mmio_base, CAM_IRQSTATUS);
+
+	if (irqstatus &
+	    (CAM_IRQSTATUS_DMA_IRQ2 | CAM_IRQSTATUS_DMA_IRQ1
+	     | CAM_IRQSTATUS_DMA_IRQ0)) {
+		omap24xxcam_dma_isr(&cam->sgdma.dma);
+		irqhandled = 1;
+	}
+	if (irqstatus & CAM_IRQSTATUS_CC_IRQ) {
+		omap24xxcam_core_isr(&cam->core);
+		irqhandled = 1;
+	}
+	if (irqstatus & CAM_IRQSTATUS_MMU_IRQ)
+		printk(KERN_ERR CAM_NAME ": Unhandled camera MMU

interrupt!\n");

drivers/media/video/omap/omap24xxcam.c

Quoted 5 lines
drivers/media/video/omap/omap24xxcam.c new file +5 -0
+
+	return IRQ_RETVAL(irqhandled);
+}
+
+/*

-----------------------------------------------------------------------

Quoted 30 lines

--- */

drivers/media/video/omap/omap24xxcam.c new file +29 -0
+
+static int vidioc_querycap(struct file *file, void *fh,
+			   struct v4l2_capability *cap)
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+
+	memset(cap, 0, sizeof(*cap));
+	strlcpy(cap->driver, CAM_NAME, sizeof(cap->driver));
+	strlcpy(cap->card, cam->vfd->name, sizeof(cap->card));
+	cap->bus_info[0] = '\0';
+	cap->version = KERNEL_VERSION(0, 0, 0);
+	cap->capabilities =
+		V4L2_CAP_VIDEO_CAPTURE
+		| V4L2_CAP_READWRITE
+		| V4L2_CAP_STREAMING;
+
+	return 0;
+}
+
+static int vidioc_enum_input(struct file *file, void *fh,
+			     struct v4l2_input *inp)
+{
+	/* default handler assumes 1 video input (the camera) */
+	int index = inp->index;
+
+	memset(inp, 0, sizeof(*inp));
+	inp->index = index;
+

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+	if (index > 0)
+		return -EINVAL;
+
+	strlcpy(inp->name, "camera", sizeof(inp->name));
+	inp->type = V4L2_INPUT_TYPE_CAMERA;
+
+	return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int

*i)

Quoted 50 lines
drivers/media/video/omap/omap24xxcam.c new file +50 -0
+{
+	*i = 0;
+
+	return 0;
+
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
+{
+	if (i > 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int vidioc_g_fmt_cap(struct file *file, void *fh,
+			    struct v4l2_format *f)
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	memset(pix, 0, sizeof(*pix));
+	spin_lock(&cam->img.img_lock);
+	*pix = cam->img.pix;
+	spin_unlock(&cam->img.img_lock);
+	return 0;
+}
+
+static int vidioc_try_fmt_cap(struct file *file, void *fh,
+			      struct v4l2_format *f)
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+
+	return omap24xxcam_sensor_try_format(cam, &f->fmt.pix);
+}
+
+static int vidioc_s_fmt_cap(struct file *file, void *fh,
+			    struct v4l2_format *f)
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+	struct omap24xxcam_capture *capture = &cam->capture;
+	int err;
+
+	spin_lock(&capture->lock);
+	if (capture->streaming) {
+		spin_unlock(&capture->lock);
+		return -EBUSY;

drivers/media/video/omap/omap24xxcam.c line 323

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+	}
+	spin_unlock(&capture->lock);
+	spin_lock(&cam->img.img_lock);
+	omap24xxcam_sensor_try_format(cam, &f->fmt.pix);
+	/* set the new capture format */
+	cam->img.pix = f->fmt.pix;
+	/* adjust the capture frame rate */
+	err = omap24xxcam_sensor_set_format(cam,
+					    &cam->img.pix,
+

&cam->img.cparm.timeperframe,

Quoted 73 lines
drivers/media/video/omap/omap24xxcam.c new file +73 -0
+					    &cam->core.xclk);
+	spin_unlock(&cam->img.img_lock);
+	return err;
+}
+
+static int vidioc_g_parm(struct file *file, void *fh,
+			 struct v4l2_streamparm *a) {
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+
+	enum v4l2_buf_type type = a->type;
+
+	memset(a, 0, sizeof(*a));
+	a->type = type;
+	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	spin_lock(&cam->img.img_lock);
+	a->parm.capture = cam->img.cparm;
+	spin_unlock(&cam->img.img_lock);
+	return 0;
+}
+
+static int vidioc_s_parm(struct file *file, void *fh,
+			 struct v4l2_streamparm *a)
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+	struct omap24xxcam_capture *capture = &cam->capture;
+	int err;
+	struct v4l2_captureparm *cparm = &a->parm.capture;
+
+	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	spin_lock(&capture->lock);
+	if (capture->streaming) {
+		spin_unlock(&capture->lock);
+		return -EBUSY;
+	}
+	spin_unlock(&capture->lock);
+	spin_lock(&cam->img.img_lock);
+	err = omap24xxcam_sensor_set_format(
+		cam,
+		&cam->img.pix,
+		&cparm->timeperframe,
+		&cam->core.xclk);
+	if (!err) {
+		cam->img.cparm.capturemode = cparm->capturemode;
+		cam->img.cparm.timeperframe =
+			cparm->timeperframe;
+		spin_unlock(&cam->img.img_lock);
+	} else {
+		spin_unlock(&cam->img.img_lock);
+	}
+	return 0;
+}
+
+static int vidioc_reqbufs(struct file *file, void *fh,
+			  struct v4l2_requestbuffers *b)
+{
+	struct omap24xxcam_fh *ofh = fh;
+
+	int err = videobuf_reqbufs(&ofh->vbq, b);
+	if (b->memory == V4L2_MEMORY_MMAP && !err) {
+		err = omap24xxcam_vbq_alloc_mmap_buffers(&ofh->vbq,
+							 b->count);
+		if (err) {
+			/* REVISIT: is this proper reverse for
+			 * videobuf_reqbufs? */
+			videobuf_mmap_free(&ofh->vbq);
+		}
+	}
+	return err;
+}

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+
+static int vidioc_querybuf(struct file *file, void *fh,
+			   struct v4l2_buffer *b)
+{
+	struct omap24xxcam_fh *ofh = fh;
+
+	return videobuf_querybuf(&ofh->vbq, b);
+}
+
+static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer

*b)

drivers/media/video/omap/omap24xxcam.c

Quoted 7 lines
drivers/media/video/omap/omap24xxcam.c new file +7 -0
+{
+	struct omap24xxcam_fh *ofh = fh;
+
+	return videobuf_qbuf(&ofh->vbq, b);
+}
+
+static int vidioc_dqbuf(struct file *file, void *fh, struct

v4l2_buffer

Quoted 15 lines

*b)

drivers/media/video/omap/omap24xxcam.c new file +14 -0
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+	struct videobuf_buffer *vb;
+	int rval;
+
+	rval = videobuf_dqbuf(&ofh->vbq, b,
+			      file->f_flags & O_NONBLOCK);
+
+	if (rval < 0)
+		return rval;
+	vb = ofh->vbq.bufs[b->index];
+
+	if (cam->sensor->frame_check)

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+		rval = cam->sensor->frame_check(
+			cam->sensor,
+			&cam->img.pix,
+			(void *)vb->baddr);
+
+	return rval;
+
+}
+
+static int vidioc_streamon(struct file *file, void *fh, enum

v4l2_buf_type

Quoted 77 lines

i)

drivers/media/video/omap/omap24xxcam.c new file +14 -0
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+	struct omap24xxcam_capture *capture = &cam->capture;
+
+	spin_lock(&capture->lock);
+	if (capture->streaming) {
+		spin_unlock(&capture->lock);
+		return -EBUSY;
+	} else
+		capture->streaming = file;
+	spin_unlock(&capture->lock);
+
+	omap24xxcam_dma_notify(&cam->sgdma.dma,

omap24xxcam_core_enable_callback);

drivers/media/video/omap/omap24xxcam.c new file +4 -0
+	return videobuf_streamon(&ofh->vbq);
+}
+
+static int vidioc_streamoff(struct file *file, void *fh, enum

v4l2_buf_type i)

drivers/media/video/omap/omap24xxcam.c new file +56 -0
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+	struct omap24xxcam_capture *capture = &cam->capture;
+	struct videobuf_queue *q = &ofh->vbq;
+	int j;
+	int err;
+
+	/* video-buf lib has trouble to turn off streaming while
+	   any buffer is still in QUEUED state. Let's wait until
+	   all queued buffers are filled.
+	*/
+	for (j = 0; j < VIDEO_MAX_FRAME; j++) {
+		if (NULL == q->bufs[j])
+			continue;
+		videobuf_waiton(q->bufs[j], 0, 0);
+	}
+
+	err = videobuf_streamoff(q);
+
+	if (err < 0)
+		return err;
+
+	spin_lock(&capture->lock);
+	if (capture->streaming == file)
+		capture->streaming = NULL;
+	spin_unlock(&capture->lock);
+	return 0;
+}
+static int vidioc_g_ctrl(struct file *file, void *fh,
+			 struct v4l2_control *a)
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+
+	return cam->sensor->get_control(cam->sensor, a);
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh,
+			 struct v4l2_control *a)
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+
+	return cam->sensor->set_control(cam->sensor, a);
+}
+
+static int vidioc_queryctrl(struct file *file, void *fh,
+			    struct v4l2_queryctrl *a) {
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+
+	return cam->sensor->query_control(cam->sensor, a);
+}
+
+static int vidioc_enum_fmt_cap(struct file *file, void *fh,

drivers/media/video/omap/omap24xxcam.c line 518

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+			       struct v4l2_fmtdesc *f)
+{
+	struct omap24xxcam_fh *ofh = fh;
+	struct omap24xxcam_device *cam = ofh->cam;
+
+	return cam->sensor->enum_pixformat(cam->sensor,
+					   f);
+}
+
+/*

-----------------------------------------------------------------------

drivers/media/video/omap/omap24xxcam.c

Quoted 8 lines

--- */

drivers/media/video/omap/omap24xxcam.c new file +7 -0
+
+	/*
+	 *  file operations
+	 */
+
+static unsigned
+int omap24xxcam_poll(struct file *file, struct poll_table_struct

*wait)

Quoted 7 lines
drivers/media/video/omap/omap24xxcam.c new file +7 -0
+{
+	struct omap24xxcam_fh *fh = file->private_data;
+	struct omap24xxcam_device *cam = fh->cam;
+	struct omap24xxcam_capture *capture = &cam->capture;
+	struct videobuf_buffer *vb;
+	enum v4l2_field field;
+

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+	DBG;
+
+	spin_lock(&capture->lock);
+
+	if (capture->streaming == file) {
+		spin_unlock(&capture->lock);
+		/* streaming capture */
+		if (list_empty(&fh->vbq.stream))
+			return POLLERR;
+		vb = list_entry(fh->vbq.stream.next, struct

videobuf_buffer,

drivers/media/video/omap/omap24xxcam.c

Quoted 3 lines
drivers/media/video/omap/omap24xxcam.c new file +3 -0
+				stream);
+	} else if (capture->streaming) {
+		/* streaming I/O is in progress on another file

descriptor */

Quoted 64 lines
drivers/media/video/omap/omap24xxcam.c new file +24 -0
+		spin_unlock(&capture->lock);
+		return POLLERR;
+	} else {
+		/* read() capture */
+		spin_unlock(&capture->lock);
+		mutex_lock(&fh->vbq.lock);
+		if (fh->vbq.read_buf == NULL) {
+			/* need to capture a new image */
+			fh->vbq.read_buf =
+				videobuf_alloc(fh->vbq.msize);
+			if (fh->vbq.read_buf == NULL) {
+				mutex_unlock(&fh->vbq.lock);
+				return POLLERR;
+			}
+			fh->vbq.read_buf->memory = V4L2_MEMORY_USERPTR;
+			field = videobuf_next_field(&fh->vbq);
+			if (fh->vbq.ops->buf_prepare(&fh->vbq,
+						     fh->vbq.read_buf,
+						     field) != 0) {
+				mutex_unlock(&fh->vbq.lock);
+				return POLLERR;
+			}
+
+			omap24xxcam_dma_notify(&cam->sgdma.dma,

omap24xxcam_core_enable_callback);

drivers/media/video/omap/omap24xxcam.c new file +9 -0
+			fh->vbq.ops->buf_queue(&fh->vbq,
+					       fh->vbq.read_buf);
+			fh->vbq.read_off = 0;
+		}
+		mutex_unlock(&fh->vbq.lock);
+		vb = (struct videobuf_buffer *)fh->vbq.read_buf;
+	}
+
+	omap24xxcam_dma_notify(&cam->sgdma.dma,

omap24xxcam_core_enable_callback);

drivers/media/video/omap/omap24xxcam.c new file +9 -0
+	poll_wait(file, &vb->done, wait);
+	if (vb->state == STATE_DONE || vb->state == STATE_ERROR)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+static ssize_t
+omap24xxcam_read(struct file *file, char *data, size_t count, loff_t *

ppos)

drivers/media/video/omap/omap24xxcam.c new file +16 -0
+{
+	struct omap24xxcam_fh *fh = file->private_data;
+	struct omap24xxcam_device *cam = fh->cam;
+	struct omap24xxcam_capture *capture = &cam->capture;
+	int err;
+
+	DBG;
+
+	spin_lock(&capture->lock);
+	if (capture->streaming) {
+		spin_unlock(&capture->lock);
+		return -EBUSY;
+	}
+	spin_unlock(&capture->lock);
+
+	omap24xxcam_dma_notify(&cam->sgdma.dma,

omap24xxcam_core_enable_callback);

drivers/media/video/omap/omap24xxcam.c new file +2 -0
+
+	err =

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+		videobuf_read_one(&fh->vbq, data, count, ppos,
+				  file->f_flags & O_NONBLOCK);
+
+	DBG_END;
+
+	return err;
+}
+
+static int
+omap24xxcam_mmap_buffers(struct file *file, struct vm_area_struct

*vma)

Quoted 6 lines
drivers/media/video/omap/omap24xxcam.c new file +6 -0
+{
+	struct omap24xxcam_fh *fh = file->private_data;
+	struct videobuf_queue *vbq = &fh->vbq;
+	struct videobuf_buffer *vb;
+	unsigned int first, last, size, i, j;
+	int err = 0;

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+
+	mutex_lock(&vbq->lock);
+
+	/* look for first buffer to map */
+	for (first = 0; first < VIDEO_MAX_FRAME; first++) {
+		if (NULL == vbq->bufs[first])
+			continue;
+		if (V4L2_MEMORY_MMAP != vbq->bufs[first]->memory)
+			continue;
+		if (vbq->bufs[first]->boff == (vma->vm_pgoff <<

PAGE_SHIFT))

Quoted 11 lines
drivers/media/video/omap/omap24xxcam.c new file +11 -0
+			break;
+	}
+
+	/* look for last buffer to map */
+	for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) {
+		if (NULL == vbq->bufs[last])
+			continue;
+		if (V4L2_MEMORY_MMAP != vbq->bufs[last]->memory)
+			continue;
+		size += vbq->bufs[last]->bsize;
+		if (size == (vma->vm_end - vma->vm_start))

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+			break;
+	}
+
+	size = 0;
+	for (i = first; i <= last; i++) {
+		vb = vbq->bufs[i];
+		for (j = 0; j < vb->dma.sglen; j++) {
+			err = remap_pfn_range(vma, vma->vm_start + size,
+				page_to_pfn(vb->dma.sglist[j].page),
+				vb->dma.sglist[j].length,

vma->vm_page_prot);

Quoted 9 lines
drivers/media/video/omap/omap24xxcam.c new file +9 -0
+			if (err)
+				goto out;
+			size += vb->dma.sglist[j].length;
+		}
+	}
+
+out:
+	mutex_unlock(&vbq->lock);
+

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+	return err;
+}
+
+static int
+omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct omap24xxcam_fh *fh = file->private_data;
+	int err;
+
+	/* let the video-buf mapper check arguments and set-up

structures */

Quoted 69 lines
drivers/media/video/omap/omap24xxcam.c new file +69 -0
+	err = videobuf_mmap_mapper(&fh->vbq, vma);
+	if (err)
+		goto err1;
+
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	/* do mapping to our allocated buffers */
+	err = omap24xxcam_mmap_buffers(file, vma);
+	if (err)
+		goto err2;
+
+	return 0;
+
+err2:
+	if (vma->vm_private_data)
+		kfree(vma->vm_private_data);
+err1:
+
+	return err;
+}
+
+static int omap24xxcam_clock_get(struct omap24xxcam_device *cam)
+{
+	cam->img.fck = clk_get(0, "cam_fck");
+	if (IS_ERR((cam->img.fck))) {
+		dev_err(cam->dev, "can't get cam_fck");
+		return PTR_ERR(cam->img.fck);
+	}
+
+	cam->img.ick = clk_get(0, "cam_ick");
+	if (IS_ERR((cam->img.ick))) {
+		dev_err(cam->dev, "can't get cam_ick");
+		clk_put(cam->img.fck);
+		return PTR_ERR(cam->img.ick);
+	}
+
+	return 0;
+}
+
+static void omap24xxcam_clock_put(struct omap24xxcam_device *cam)
+{
+	if (cam->img.ick == NULL)
+		return;
+
+	clk_put(cam->img.ick);
+	clk_put(cam->img.fck);
+}
+
+/*
+ * Do some sanity check, set clock rate, starts it and
+ *  turn codec audio on
+ */
+int omap24xxcam_clock_on(struct omap24xxcam_device *cam)
+{
+
+	clk_enable(cam->img.fck);
+	clk_enable(cam->img.ick);
+
+	printk(KERN_DEBUG
+	       "FCLK = %d [%d], usecount = %d\n",
+	       (uint) clk_get_rate(cam->img.fck), CAM_CLOCK,
+	       clk_get_usecount(cam->img.fck));
+
+	return 0;
+}
+
+/*
+ * Do some sanity check, turn clock off and then turn
+ *  codec audio off

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+ */
+int omap24xxcam_clock_off(struct omap24xxcam_device *cam)
+{
+	if (cam->img.ick == NULL)
+		return 0;
+
+	if (clk_get_usecount(cam->img.fck) > 0) {
+		if (clk_get_rate(cam->img.fck) != CAM_CLOCK) {
+			printk(KERN_WARNING
+			       "FCLK for camera should be %d Hz. But is

%d Hz\n",

drivers/media/video/omap/omap24xxcam.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+			       (uint) clk_get_rate(cam->img.fck),

CAM_CLOCK);

Quoted 93 lines
drivers/media/video/omap/omap24xxcam.c new file +93 -0
+		}
+
+		clk_disable(cam->img.fck);
+		clk_disable(cam->img.ick);
+	}
+
+	return 0;
+}
+
+static int omap24xxcam_release(struct inode *inode, struct file *file)
+{
+	struct omap24xxcam_fh *fh = file->private_data;
+	struct omap24xxcam_device *cam = fh->cam;
+	struct omap24xxcam_capture *capture = &cam->capture;
+
+	DBG;
+
+	spin_lock(&capture->lock);
+
+	/* stop streaming capture */
+	if (capture->streaming == file) {
+		capture->streaming = NULL;
+		spin_unlock(&capture->lock);
+		videobuf_streamoff(&fh->vbq);
+		spin_lock(&capture->lock);
+	}
+
+	/* release read_buf videobuf_buffer struct */
+	if (fh->vbq.read_buf) {
+		omap24xxcam_vbq_release(&fh->vbq, fh->vbq.read_buf);
+		kfree(fh->vbq.read_buf);
+	}
+	spin_unlock(&capture->lock);
+
+	mutex_lock(&cam->mutex);
+	if (--cam->users == 0) {
+		/* power down the sensor */
+		omap24xxcam_core_disable(&cam->core);
+		omap24xxcam_sgdma_disable(&cam->sgdma);
+		omap24xxcam_sensor_disable(cam);
+	}
+	mutex_unlock(&cam->mutex);
+
+	file->private_data = NULL;
+
+	module_put(cam->sensor->module);
+	kfree(fh);
+
+	return 0;
+}
+
+static int omap24xxcam_open(struct inode *inode, struct file *file)
+{
+	int minor = iminor(inode);
+	struct omap24xxcam_device *cam = camera_module;
+	struct omap24xxcam_capture *capture = &cam->capture;
+	struct omap24xxcam_fh *fh;
+
+	DBG;
+
+	if (!cam || !cam->vfd || (cam->vfd->minor != minor))
+		return -ENODEV;
+
+	if (!try_module_get(cam->sensor->module))
+		return -ENODEV;
+
+	fh = kzalloc(sizeof(struct omap24xxcam_fh), GFP_KERNEL);
+
+	if (fh == NULL)
+		return -ENOMEM;
+
+	fh->cam = cam;
+	file->private_data = fh;
+
+	videobuf_queue_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL,
+			    &capture->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			    V4L2_FIELD_NONE,
+			    sizeof(struct videobuf_buffer), cam);
+
+	mutex_lock(&cam->mutex);
+	if (cam->users == 0) {
+		omap24xxcam_sgdma_enable(&cam->sgdma);
+		omap24xxcam_sensor_enable(cam);
+
+	}
+	cam->users++;
+	mutex_unlock(&cam->mutex);
+
+	return 0;
+}
+
+static struct file_operations omap24xxcam_fops = {
+	.owner = THIS_MODULE,

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+	.llseek = no_llseek,
+	.read = omap24xxcam_read,
+	.poll = omap24xxcam_poll,
+	.ioctl = video_ioctl2,
+	.mmap = omap24xxcam_mmap,
+	.open = omap24xxcam_open,
+	.release = omap24xxcam_release,
+};
+
+/*

-----------------------------------------------------------------------

drivers/media/video/omap/omap24xxcam.c

Quoted 3 lines

--- */

drivers/media/video/omap/omap24xxcam.c new file +2 -0
+#ifdef CONFIG_PM
+static int omap24xxcam_suspend(struct platform_device *pdev,

pm_message_t

Quoted 33 lines

state)

drivers/media/video/omap/omap24xxcam.c new file +32 -0
+{
+	struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
+
+	DBG;
+
+	mutex_lock(&cam->mutex);
+	if (cam->users == 0) {
+		mutex_unlock(&cam->mutex);
+		return 0;
+	}
+	mutex_unlock(&cam->mutex);
+
+	/* Disable the camera interface. */
+	omap24xxcam_core_disable(&cam->core);
+
+	/* Stop the DMA controller and frame sync scatter-gather DMA. */
+	omap24xxcam_sgdma_disable(&cam->sgdma);
+
+	/* power down the sensor */
+	omap24xxcam_sensor_disable(cam);
+
+	return 0;
+}
+static int omap24xxcam_resume(struct platform_device *pdev)
+{
+	struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
+
+	DBG;
+
+	mutex_lock(&cam->mutex);
+	if (cam->users == 0) {
+		mutex_unlock(&cam->mutex);

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+		return 0;
+	}
+	mutex_unlock(&cam->mutex);
+
+	/* FIXME: what clocks need to be enabled now? None? */
+	omap24xxcam_core_enable(&cam->core);
+
+	if (cam->capture.streaming) {
+		/* capture was in progress, so we need to register
+		 * our routine to restart the camera interface the next

time a

Quoted 58 lines
drivers/media/video/omap/omap24xxcam.c new file +3 -0
+		 * DMA transfer is queued.
+		 */
+		omap24xxcam_dma_notify(&cam->sgdma.dma,

omap24xxcam_core_enable_callback);

drivers/media/video/omap/omap24xxcam.c new file +54 -0
+	}
+
+	/* Restart the scatter-gather DMA queue. */
+	omap24xxcam_sgdma_enable(&cam->sgdma);
+
+	/* power-up and re-configure the sensor */
+	omap24xxcam_sensor_enable(cam);
+
+	/* camera interface will be enabled through dma_notify function
+	 ** automatically when new dma starts
+	 */
+
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+int omap24xxcam_device_enable(struct omap24xxcam_device *cam)
+{
+	struct video_device *vfd;
+	int rval;
+
+	if (cam == NULL || !cam->camera_block_alive || cam->vfd != NULL)
+		return -EBUSY;
+
+	/* initialize the video_device struct */
+	vfd = cam->vfd = video_device_alloc();
+	if (!vfd) {
+		printk(KERN_ERR CAM_NAME
+		       ": could not allocate video device struct\n");
+		rval = -ENOMEM;
+		goto err;
+	}
+	vfd->release = video_device_release;
+
+	strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
+	vfd->type = VID_TYPE_CAPTURE | VID_TYPE_CHROMAKEY;
+	/* need to register for a VID_HARDWARE_* ID in videodev.h */
+	vfd->hardware = 0;
+	vfd->fops = &omap24xxcam_fops;
+	/* FIXME: need to use the full v4l2 API */
+	vfd->priv = camera_module;
+	vfd->minor = -1;
+
+	vfd->vidioc_querycap = &vidioc_querycap;
+	vfd->vidioc_enum_input = &vidioc_enum_input;
+	vfd->vidioc_g_input = &vidioc_g_input;
+	vfd->vidioc_s_input = &vidioc_s_input;
+	vfd->vidioc_g_fmt_cap = &vidioc_g_fmt_cap;
+	vfd->vidioc_try_fmt_cap = &vidioc_try_fmt_cap;
+	vfd->vidioc_s_fmt_cap = &vidioc_s_fmt_cap;
+	vfd->vidioc_g_parm = &vidioc_g_parm;
+	vfd->vidioc_s_parm = &vidioc_s_parm;
+	vfd->vidioc_reqbufs = &vidioc_reqbufs;
+	vfd->vidioc_querybuf = &vidioc_querybuf;

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+	vfd->vidioc_qbuf = &vidioc_qbuf;
+	vfd->vidioc_dqbuf = &vidioc_dqbuf;
+	vfd->vidioc_streamon = &vidioc_streamon;
+	vfd->vidioc_streamoff = &vidioc_streamoff;
+	vfd->vidioc_g_ctrl = &vidioc_g_ctrl;
+	vfd->vidioc_s_ctrl = &vidioc_s_ctrl;
+	vfd->vidioc_queryctrl = &vidioc_queryctrl;
+	vfd->vidioc_enum_fmt_cap = &vidioc_enum_fmt_cap;
+
+	/* Enable the xclk output.  The sensor may (and does, in the

case of

drivers/media/video/omap/omap24xxcam.c

Quoted 1 line
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	 * the OV9640) require an xclk input in order for its

initialization

drivers/media/video/omap/omap24xxcam.c

Quoted 12 lines
drivers/media/video/omap/omap24xxcam.c new file +12 -0
+	 * routine to work.
+	 */
+	/* choose an arbitrary xclk frequency */
+	omap24xxcam_core_xclk_set(&cam->core, 12000000);
+
+	omap24xxcam_camera.priv = cam;
+
+	if ((rval = omap24xxcam_sensor_init(cam))) {
+		goto err;
+	}
+
+	if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0)

{

Quoted 15 lines
drivers/media/video/omap/omap24xxcam.c new file +15 -0
+		printk(KERN_ERR CAM_NAME
+		       ": could not register Video for Linux device\n");
+		vfd->minor = -1;
+		rval = -EBUSY;
+		goto err;
+	}
+
+	printk(KERN_INFO CAM_NAME
+	       ": registered device video%d [v4l2]\n", vfd->minor);
+
+	return 0;
+
+err:
+	omap24xxcam_device_disable(cam);
+

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+	return rval;
+}
+
+void omap24xxcam_device_disable(struct omap24xxcam_device *cam)
+{
+	omap24xxcam_sensor_exit(cam);
+
+	if (cam->vfd) {
+		if (cam->vfd->minor == -1) {
+			/* The device was never registered, so release

the

drivers/media/video/omap/omap24xxcam.c

Quoted 5 lines
drivers/media/video/omap/omap24xxcam.c new file +5 -0
+			 * video_device struct directly.
+			 */
+			video_device_release(cam->vfd);
+		} else {
+			/* The unregister function will release the

video_device

Quoted 7 lines
drivers/media/video/omap/omap24xxcam.c new file +7 -0
+			 * struct as well as unregistering it.
+			 */
+			video_unregister_device(cam->vfd);
+		}
+		cam->vfd = NULL;
+	}
+}

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+
+static int omap24xxcam_probe(struct platform_device *pdev)
+{
+	struct omap24xxcam_device *cam;
+	DBG;
+
+	cam = camera_module = kzalloc(sizeof(struct omap24xxcam_device),
+				      GFP_KERNEL);
+	if (!cam) {
+		printk(KERN_ERR CAM_NAME ": could not allocate

memory\n");

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +8 -0
+		goto err;
+	}
+	cam->dev = &pdev->dev;
+
+	/* initialize the videobuf queue ops */
+	spin_lock_init(&cam->capture.lock);
+
+	/* Impose a lower limit on the amount of memory allocated for

capture.

drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	 * We require at least enough memory to double-buffer QVGA

(300KB).

Quoted 44 lines
drivers/media/video/omap/omap24xxcam.c new file +44 -0
+	 */
+	if (capture_mem < 320 * 240 * 2 * 2)
+		capture_mem = 320 * 240 * 2 * 2;
+	cam->capture_mem = capture_mem;
+
+	/* request the mem region for the camera registers */
+	if (!request_mem_region(CAM_REG_BASE, CAM_REG_SIZE, CAM_NAME)) {
+		printk(KERN_ERR CAM_NAME
+		       ": cannot reserve camera register I/O region\n");
+		goto err;
+	}
+	cam->mmio_base_phys = CAM_REG_BASE;
+	cam->mmio_size = CAM_REG_SIZE;
+
+	/* map the region */
+	cam->mmio_base = (unsigned long)
+		ioremap_nocache(cam->mmio_base_phys,
+				cam->mmio_size);
+	if (!cam->mmio_base) {
+		printk(KERN_ERR CAM_NAME
+		       ": cannot map camera register I/O region\n");
+		goto err;
+	}
+
+	/* initialize the camera interface */
+	omap24xxcam_reset(cam);
+
+	init_timer(&cam->sgdma.reset_timer);
+	cam->sgdma.reset_timer.function = omap24xxcam_reset_timer;
+	cam->sgdma.reset_timer.data = (unsigned long)cam;
+	INIT_WORK(&cam->camera_reset_work,
+		  omap24xxcam_camera_reset_work, cam);
+	INIT_WORK(&cam->sensor_reset_work,
+		  omap24xxcam_sensor_reset_work, cam);
+
+	/* initialize the spinlock used to serialize access to the image
+	 * parameters
+	 */
+	spin_lock_init(&cam->img.img_lock);
+
+	/* initialize the camera interface functional clock frequency */
+	omap24xxcam_core_mclk_set(&cam->core, 96000000); /* 96MHz */
+	if (omap24xxcam_clock_get(cam) < 0)
+		goto err;

drivers/media/video/omap/omap24xxcam.c

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+
+	/* initialize the streaming capture parameters */
+	cam->img.cparm.readbuffers = 1;
+	cam->img.cparm.capability = V4L2_CAP_TIMEPERFRAME;
+
+	/* select an arbitrary default capture frame rate of 5fps */
+	cam->img.cparm.timeperframe.numerator = 1;
+	cam->img.cparm.timeperframe.denominator = 15;
+
+	omap24xxcam_core_init(&cam->core, cam->mmio_base +

CC_REG_OFFSET);

drivers/media/video/omap/omap24xxcam.c

Quoted 5 lines
drivers/media/video/omap/omap24xxcam.c new file +1 -0
+	omap24xxcam_sgdma_init(&cam->sgdma, cam->mmio_base +

CAMDMA_REG_OFFSET);

drivers/media/video/omap/omap24xxcam.c new file +3 -0
+
+	/* install the interrupt service routine */
+	if (request_irq(INT_24XX_CAM_IRQ, omap24xxcam_isr,

IRQF_DISABLED,

drivers/media/video/omap/omap24xxcam.c

Quoted 3 lines
drivers/media/video/omap/omap24xxcam.c new file +3 -0
+			CAM_NAME, cam)) {
+		printk(KERN_ERR CAM_NAME
+		       ": could not install interrupt service

routine\n");

drivers/media/video/omap/omap24xxcam.c

Quoted 5 lines
drivers/media/video/omap/omap24xxcam.c new file +5 -0
+		goto err;
+	}
+	cam->irq = INT_24XX_CAM_IRQ;
+
+	/* set driver specific data to use in power management functions

*/

Quoted 128 lines
drivers/media/video/omap/omap24xxcam.c new file +115 -0
+	platform_set_drvdata(pdev, cam);
+
+	mutex_init(&cam->mutex);
+	cam->users = 0;
+
+	cam->camera_block_alive = 1;
+
+	omap24xxcam_device_enable(cam);
+
+	return 0;
+
+err:
+	omap24xxcam_remove(&omap24xxcam_dev);
+	return -ENODEV;
+}
+
+static int omap24xxcam_remove(struct platform_device *pdev)
+{
+	struct omap24xxcam_device *cam = camera_module;
+
+	if (!cam)
+		return 0;
+
+	omap24xxcam_device_disable(cam);
+
+	if (cam->irq) {
+		free_irq(cam->irq, cam);
+		cam->irq = 0;
+	}
+
+	omap24xxcam_sgdma_exit(&cam->sgdma);
+	omap24xxcam_core_exit(&cam->core);
+
+	omap24xxcam_clock_off(cam);
+	omap24xxcam_clock_put(cam);
+
+	if (cam->mmio_base) {
+		iounmap((void *)cam->mmio_base);
+		cam->mmio_base = 0;
+	}
+
+	if (cam->mmio_base_phys) {
+		release_mem_region(cam->mmio_base_phys,
+				   cam->mmio_size);
+		cam->mmio_base_phys = 0;
+	}
+
+	kfree(cam);
+	camera_module = NULL;
+
+	return 0;
+}
+
+static struct platform_driver omap24xxcam_driver = {
+	.probe = omap24xxcam_probe,
+	.remove = omap24xxcam_remove,
+#ifdef CONFIG_PM
+	.suspend = omap24xxcam_suspend,
+	.resume = omap24xxcam_resume,
+#else
+	.suspend = NULL,
+	.resume = NULL,
+#endif
+	.shutdown = NULL,
+	.driver = {
+		.name = CAM_NAME,
+	},
+};
+
+static struct platform_device omap24xxcam_dev = {
+	.name = CAM_NAME,
+	.dev = {
+		.release = NULL,
+		},
+	.id = 0,
+};
+
+int __init omap24xxcam_init(void)
+{
+	int ret;
+
+	DBG;
+
+	ret = platform_driver_register(&omap24xxcam_driver);
+	if (ret != 0)
+		return ret;
+
+	ret = platform_device_register(&omap24xxcam_dev);
+	if (ret != 0) {
+		platform_driver_unregister(&omap24xxcam_driver);
+		return ret;
+	}
+
+	return 0;
+}
+
+void __exit omap24xxcam_cleanup(void)
+{
+	DBG;
+
+	platform_device_unregister(&omap24xxcam_dev);
+	platform_driver_unregister(&omap24xxcam_driver);
+
+	omap24xxcam_remove(&omap24xxcam_dev);
+}
+
+MODULE_AUTHOR("MontaVista Software, Inc.");
+MODULE_DESCRIPTION("OMAP24xx Video for Linux camera driver");
+MODULE_LICENSE("GPL");
+module_param(video_nr, int, 0);
+MODULE_PARM_DESC(video_nr,
+		 "Minor number for video device (-1 ==> auto assign)");
+module_param(capture_mem, int, 0);
+MODULE_PARM_DESC(capture_mem,
+		 "Maximum amount of memory for capture buffers (default

4800KB)");

drivers/media/video/omap/omap24xxcam.c new file +3 -0
+
+module_init(omap24xxcam_init);
+module_exit(omap24xxcam_cleanup);
drivers/media/video/omap/omap24xxcam.h new file +2 -0
new file mode 100644
index 0000000..eba5ea6
@@ -0,0 +1,659 @@
+/*
+ * drivers/media/video/omap24xxcam.h

drivers/media/video/omap/omap24xxcam.h line 12

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.h new file +10 -0
+ *
+ * Video-for-Linux (Version 2) camera capture driver for
+ * the OMAP24xx camera controller.
+ *
+ * Author: Andy Lowe ([email protected])
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public

License

drivers/media/video/omap/omap24xxcam.h line 13

Quoted 1 line
drivers/media/video/omap/omap24xxcam.h new file +1 -0
+ * version 2. This program is licensed "as is" without any warranty of

any

Quoted 4 lines
drivers/media/video/omap/omap24xxcam.h new file +4 -0
+ * kind, whether express or implied.
+ */
+
+#ifndef OMAP24XXCAM_H

drivers/media/video/omap/omap24xxcam.h

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.h new file +10 -0
+#define OMAP24XXCAM_H
+
+#include "sensor_if.h"
+
+//#define DEBUG_CAM
+
+#define CAM_NAME 	"omap24xxcam"
+
+#ifdef DEBUG_CAM
+#define DBG		printk(KERN_INFO CAM_NAME ": %s\n",

__FUNCTION__)

drivers/media/video/omap/omap24xxcam.h line 28

Quoted 1 line
drivers/media/video/omap/omap24xxcam.h new file +1 -0
+#define DBG_END 	printk(KERN_INFO CAM_NAME ": %s END!\n",

__FUNCTION__)

Quoted 100 lines
drivers/media/video/omap/omap24xxcam.h new file +1 -0
+#define DBG_MID(x)	printk(KERN_INFO CAM_NAME ": %s - %d\n",

__FUNCTION__, x)

drivers/media/video/omap/omap24xxcam.h new file +98 -0
+#else
+#define DBG
+#define DBG_END
+#define DBG_MID(x)
+#endif
+
+#define CAM_CLOCK		96000000
+
+/* physical memory map definitions */
+	/* camera subsystem */
+#define CAM_REG_BASE		0x48052000
+#define CAM_REG_SIZE		0x00001000
+	/* camera core */
+#define CC_REG_OFFSET		0x00000400
+	/* camera DMA */
+#define CAMDMA_REG_OFFSET	0x00000800
+	/* camera MMU */
+#define CAMMMU_REG_OFFSET	0x00000C00
+
+/* define camera subsystem register offsets */
+#define CAM_REVISION			0x000
+#define CAM_SYSCONFIG			0x010
+#define CAM_SYSSTATUS			0x014
+#define CAM_IRQSTATUS			0x018
+#define CAM_GPO				0x040
+#define CAM_GPI				0x050
+
+/* define camera core register offsets */
+#define CC_REVISION			0x000
+#define CC_SYSCONFIG			0x010
+#define CC_SYSSTATUS			0x014
+#define CC_IRQSTATUS			0x018
+#define CC_IRQENABLE			0x01C
+#define CC_CTRL				0x040
+#define CC_CTRL_DMA			0x044
+#define CC_CTRL_XCLK			0x048
+#define CC_FIFODATA			0x04C
+#define CC_TEST				0x050
+#define CC_GENPAR			0x054
+#define CC_CCPFSCR			0x058
+#define CC_CCPFECR			0x05C
+#define CC_CCPLSCR			0x060
+#define CC_CCPLECR			0x064
+#define CC_CCPDFR			0x068
+
+/* define camera dma register offsets */
+#define CAMDMA_REVISION			0x000
+#define CAMDMA_IRQSTATUS_L0		0x008
+#define CAMDMA_IRQSTATUS_L1		0x00C
+#define CAMDMA_IRQSTATUS_L2		0x010
+#define CAMDMA_IRQSTATUS_L3		0x014
+#define CAMDMA_IRQENABLE_L0		0x018
+#define CAMDMA_IRQENABLE_L1		0x01C
+#define CAMDMA_IRQENABLE_L2		0x020
+#define CAMDMA_IRQENABLE_L3		0x024
+#define CAMDMA_SYSSTATUS		0x028
+#define CAMDMA_OCP_SYSCONFIG		0x02C
+#define CAMDMA_CAPS_0			0x064
+#define CAMDMA_CAPS_2			0x06C
+#define CAMDMA_CAPS_3			0x070
+#define CAMDMA_CAPS_4			0x074
+#define CAMDMA_GCR			0x078
+#define CAMDMA_CCR(n)			(0x080 + (n)*0x60)
+#define CAMDMA_CLNK_CTRL(n)		(0x084 + (n)*0x60)
+#define CAMDMA_CICR(n)			(0x088 + (n)*0x60)
+#define CAMDMA_CSR(n)			(0x08C + (n)*0x60)
+#define CAMDMA_CSDP(n)			(0x090 + (n)*0x60)
+#define CAMDMA_CEN(n)			(0x094 + (n)*0x60)
+#define CAMDMA_CFN(n)			(0x098 + (n)*0x60)
+#define CAMDMA_CSSA(n)			(0x09C + (n)*0x60)
+#define CAMDMA_CDSA(n)			(0x0A0 + (n)*0x60)
+#define CAMDMA_CSEI(n)			(0x0A4 + (n)*0x60)
+#define CAMDMA_CSFI(n)			(0x0A8 + (n)*0x60)
+#define CAMDMA_CDEI(n)			(0x0AC + (n)*0x60)
+#define CAMDMA_CDFI(n)			(0x0B0 + (n)*0x60)
+#define CAMDMA_CSAC(n)			(0x0B4 + (n)*0x60)
+#define CAMDMA_CDAC(n)			(0x0B8 + (n)*0x60)
+#define CAMDMA_CCEN(n)			(0x0BC + (n)*0x60)
+#define CAMDMA_CCFN(n)			(0x0C0 + (n)*0x60)
+#define CAMDMA_COLOR(n)			(0x0C4 + (n)*0x60)
+
+/* define camera mmu register offsets */
+#define CAMMMU_REVISION			0x000
+#define CAMMMU_SYSCONFIG		0x010
+#define CAMMMU_SYSSTATUS		0x014
+#define CAMMMU_IRQSTATUS		0x018
+#define CAMMMU_IRQENABLE		0x01C
+#define CAMMMU_WALKING_ST		0x040
[… more lines in the raw message]

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drivers/media/video/omap/omap24xxcam.h line 127

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.h new file +10 -0
+#define CAMMMU_CNTL			0x044
+#define CAMMMU_FAULT_AD			0x048
+#define CAMMMU_TTB			0x04C
+#define CAMMMU_LOCK			0x050
+#define CAMMMU_LD_TLB			0x054
+#define CAMMMU_CAM			0x058
+#define CAMMMU_RAM			0x05C
+#define CAMMMU_GFLUSH			0x060
+#define CAMMMU_FLUSH_ENTRY		0x064
+#define CAMMMU_READ_CAM			0x068
[… more lines in the raw message]

1)

Quoted 1 line

+#define CAM_SYSCONFIG_AUTOIDLE (1 <<

0)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

0)

drivers/media/video/omap/omap24xxcam.h

Quoted 4 lines
drivers/media/video/omap/omap24xxcam.h new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

2)

Quoted 1 line

+#define CAM_IRQSTATUS_DMA_IRQ1 (1 <<

1)

Quoted 1 line

+#define CAM_IRQSTATUS_DMA_IRQ0 (1 <<

0)

drivers/media/video/omap/omap24xxcam.h

Quoted 22 lines
drivers/media/video/omap/omap24xxcam.h new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

3)

drivers/media/video/omap/omap24xxcam.h

Quoted 3 lines
drivers/media/video/omap/omap24xxcam.h new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

1)

drivers/media/video/omap/omap24xxcam.h

Quoted 3 lines
drivers/media/video/omap/omap24xxcam.h new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

0)

drivers/media/video/omap/omap24xxcam.h

Quoted 6 lines
drivers/media/video/omap/omap24xxcam.h new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

10)

drivers/media/video/omap/omap24xxcam.h

Quoted 13 lines
drivers/media/video/omap/omap24xxcam.h new file +13 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

10)

drivers/media/video/omap/omap24xxcam.h

Quoted 11 lines
drivers/media/video/omap/omap24xxcam.h new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

18)

drivers/media/video/omap/omap24xxcam.h

Quoted 11 lines
drivers/media/video/omap/omap24xxcam.h new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

1)

Quoted 1 line

+#define CC_CTRL_PAR_MODE_NOBT10 (1 <<

1)

Quoted 1 line

+#define CC_CTRL_PAR_MODE_NOBT12 (2 <<

1)

drivers/media/video/omap/omap24xxcam.h

Quoted 6 lines
drivers/media/video/omap/omap24xxcam.h new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

8)

drivers/media/video/omap/omap24xxcam.h

Quoted 8 lines
drivers/media/video/omap/omap24xxcam.h new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

0)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

24)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

16)

drivers/media/video/omap/omap24xxcam.h

Quoted 4 lines
drivers/media/video/omap/omap24xxcam.h new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

0)

drivers/media/video/omap/omap24xxcam.h

Quoted 6 lines
drivers/media/video/omap/omap24xxcam.h new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

8)

drivers/media/video/omap/omap24xxcam.h

Quoted 9 lines
drivers/media/video/omap/omap24xxcam.h new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

0)

drivers/media/video/omap/omap24xxcam.h

Quoted 15 lines
drivers/media/video/omap/omap24xxcam.h new file +15 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

12)

Quoted 1 line

+#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY (0 <<

12)

Quoted 1 line

+#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_NSTANDBY (1 <<

12)

Quoted 1 line

+#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_SSTANDBY (2 <<

12)

Quoted 1 line

+#define CAMDMA_OCP_SYSCONFIG_FUNC_CLOCK (1 <<

9)

Quoted 1 line

+#define CAMDMA_OCP_SYSCONFIG_OCP_CLOCK (1 <<

8)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

3)

drivers/media/video/omap/omap24xxcam.h

Quoted 4 lines
drivers/media/video/omap/omap24xxcam.h new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

1)

drivers/media/video/omap/omap24xxcam.h

Quoted 16 lines
drivers/media/video/omap/omap24xxcam.h new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

16)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

14)

drivers/media/video/omap/omap24xxcam.h

Quoted 5 lines
drivers/media/video/omap/omap24xxcam.h new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

12)

drivers/media/video/omap/omap24xxcam.h

Quoted 8 lines
drivers/media/video/omap/omap24xxcam.h new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

6)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

<< 0))

drivers/media/video/omap/omap24xxcam.h

Quoted 23 lines
drivers/media/video/omap/omap24xxcam.h new file +23 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

6)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

4)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

2)

Quoted 1 line

+#define CAMDMA_CSR_DROP (1 <<

1)

drivers/media/video/omap/omap24xxcam.h

Quoted 3 lines
drivers/media/video/omap/omap24xxcam.h new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

20)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

18)

Quoted 1 line

+#define CAMDMA_CSDP_WRITE_MODE (3 <<

16)

drivers/media/video/omap/omap24xxcam.h

Quoted 3 lines
drivers/media/video/omap/omap24xxcam.h new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

16)

drivers/media/video/omap/omap24xxcam.h

Quoted 6 lines
drivers/media/video/omap/omap24xxcam.h new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

13)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

9)

drivers/media/video/omap/omap24xxcam.h

Quoted 6 lines
drivers/media/video/omap/omap24xxcam.h new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

6)

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

2)

drivers/media/video/omap/omap24xxcam.h

Quoted 30 lines
drivers/media/video/omap/omap24xxcam.h new file +30 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/media/video/omap/omap24xxcam.h

Quoted 1 line
drivers/media/video/omap/omap24xxcam.h new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/media/video/omap/omap24xxcam.h

Quoted 15 lines
drivers/media/video/omap/omap24xxcam.h new file +15 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

per DMA

Quoted 2 lines

request */
+/* NUM_CAMDMA_CHANNELS is the number of logical channels provided by

the

drivers/media/video/omap/omap24xxcam.h

Quoted 5 lines

camera
+ * DMA controller.
+ */

drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

be

Quoted 2 lines

queued.
+ * We need it to be 2 greater than the maximum number of video frames

so

Quoted 2 lines

that
+ * we can use 2 slots for overlay while still having VIDEO_MAX_FRAME

slots

drivers/media/video/omap/omap24xxcam.h

Quoted 16 lines

left
+ * for streaming.
+ */

drivers/media/video/omap/omap24xxcam.h new file +13 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/media/video/omap/omap24xxcam.h

Quoted 4 lines
drivers/media/video/omap/omap24xxcam.h new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

process */

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

bytes

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines

due to page alignment) */

drivers/media/video/omap/omap24xxcam.h new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DMA

drivers/media/video/omap/omap24xxcam.h

Quoted 13 lines

*/

drivers/media/video/omap/omap24xxcam.h new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

will

drivers/media/video/omap/omap24xxcam.h

Quoted 7 lines
drivers/media/video/omap/omap24xxcam.h new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

notification

drivers/media/video/omap/omap24xxcam.h

Quoted 26 lines

when

drivers/media/video/omap/omap24xxcam.h new file +25 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

videobuf_buffer */

drivers/media/video/omap/omap24xxcam.h

Quoted 6 lines
drivers/media/video/omap/omap24xxcam.h new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

parameters

drivers/media/video/omap/omap24xxcam.h

Quoted 11 lines

for

drivers/media/video/omap/omap24xxcam.h new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

by the

drivers/media/video/omap/omap24xxcam.h

Quoted 23 lines
drivers/media/video/omap/omap24xxcam.h new file +23 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/media/video/omap/omap24xxcam.h

Quoted 50 lines
drivers/media/video/omap/omap24xxcam.h new file +50 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

offset)

drivers/media/video/omap/omap24xxcam.h

Quoted 5 lines
drivers/media/video/omap/omap24xxcam.h new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

offset,

drivers/media/video/omap/omap24xxcam.h

Quoted 44 lines
drivers/media/video/omap/omap24xxcam.h new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

offset,

drivers/media/video/omap/omap24xxcam.h new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

long xclk);

drivers/media/video/omap/omap24xxcam.h new file +13 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*cam,

drivers/media/video/omap/omap24xxcam.h

Quoted 2 lines
drivers/media/video/omap/omap24xxcam.h new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*timeperframe);

drivers/media/video/omap/omap24xxcam.h

Quoted 18 lines
drivers/media/video/omap/omap24xxcam.h new file +18 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

long

drivers/media/video/omap/omap24xxcam.h

Quoted 4 lines

csr,

drivers/media/video/omap/omap24xxcam.h new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

videobuf_buffer

drivers/media/video/omap/omap24xxcam.h

Quoted 5 lines

*vb);

drivers/media/video/omap/omap24xxcam.h new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*cam);

Quoted 18 lines
drivers/media/video/omap/omap24xxcam.h new file +11 -1

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

1.5.0.1

_______________________________________________
Linux-omap-open-source mailing list
[email protected]
http://linux.omap.com/mailman/listinfo/linux-omap-open-source

Part of the diff is not shown here. View the raw message.

#10 lore raw

Re: [PATCH] ARM: OMAP2: Camera: Add OMAP2 24xx camera driver.

Quoted 12 lines · Khasim

I am yet to review this patch completely. One immediate topic that I want to bring up is about DMA files. In Jian's code to David and Komal he had DMA driver integrated into camera driver and David moved the DMA part to new file. Which according to me was an OK one, but in your patch set I see around 3 DMA related files. I really don't see a necessity for this split.

If you really want to clean up the DMA part of it then its better to upgrade the dma.c file for OMAP2, the CAM_DMA and system_DMA are same. Why not add this functionality there? Or use the existing DMA functionality instead of duplicating the code.

Quoted 4 lines

Also, looking at the future Camera work for 3430 I feel this DMA framework is definitely going totally different (FYI there is no integrated CAM DMA in ISP). We have to use MMU here and we are looking at adopting Trilok's and DOYU-san's MMU framework.

I haven't looked at the 3430 spec yet, but the MMU should be used on 2420 as well. Is it different on 3430? The current allocation of memory-mapped buffers is a hack...

Quoted 1 line

Can you please give some insight into this DMA split?

I did the DMA split to reduce the mess. I also think the new interface offered by the DMA code is better. DMA is split to scatter-gather DMA, individual DMA channels and DMA hardware handling. Accesses to different logical parts are fairly clearly visible (e.g. container_of stuff). And it's out of the main driver. The splitting into files could be of course different, but I have to say like some things in Java. ;)

But indeed if there's a general DMA framework that could be used, then I suppose that's the way to go eventually.

Signature · 2 lines
Sakari Ailus
[email protected]
#11 lore raw

Re: [PATCH] ARM: OMAP2: Camera: Add OMAP2 24xx camera driver.

Quoted 9 lines · Sakari Ailus
Quoted 2 lines

Can you please give some insight into this DMA split?

I did the DMA split to reduce the mess. I also think the new interface offered by the DMA code is better. DMA is split to scatter-gather DMA, individual DMA channels and DMA hardware handling. Accesses to different logical parts are fairly clearly visible (e.g. container_of stuff). And it's out of the main driver. The splitting into files could be of course different, but I have to say like some things in Java. ;)

I think there is no problem in getting 3k plus lines of code as single driver file into upstream. smc91x.c alone is 2300+ lines of code.

Quoted 4 lines

But indeed if there's a general DMA framework that could be used, then I suppose that's the way to go eventually.

MMU/MBox (IVA/DSP/Cam) framework like approach can be used. Something like "SysDMA" and "CamDMA" as two separate instances of similar or may be slightly different hardware blocks.

Signature · 1 line
--Trilok Soni
#12 lore raw

RE: [PATCH] ARM: OMAP2: Camera: Add OMAP2 24xx camera driver.

In reply to Sakari Ailus

Hi Sakari,

My comments below, looks like most of the code from Trilok's and your patch is same, but you have spit the functionality in many files, which doesn't add any features or advantages to the actual camera driver architecture as such.

1. Why do we need a separate omap24xxcam-core.c? I don't see any added advantage from this split. Can you please briefly explain your thoughts?

2. Headers in every file is different from the file name. Its bit difficult to get the intent of code :). I agree this is an evolving code, you can reject this comment.

3. Lot of code is already available and well organized in David's and Trilok's patch like for example: omap24xxcam_core_enable is same as omap24xxcam_cc_enable, the functionality in omap24xxcam-dmahw.c omap24xx-vbq.c is same as code in their patches. I felt like this functionality is better achieved with previous patches, is this split really required?

4. I see few comments are same as in David's code but functionality or code is different example:

+/* Program the camera interface xclk for the frequency cam->img.xclk based on
+ * the functional clock frequency cam->img.mclk. If the specifed cam->img.xclk
+ * frequency is not possible based on the value of cam->img.mclk, then the
+ * closest xclk frequency lower than the specified xclk will be selected.
+ * The actual xclk frequency is returned in cam->img.xclk. If cam->img.xclk is zero,
+ * then xclk is turned off (stable low value).
+ */
+
+void omap24xxcam_core_init(struct omap24xxcam_core *core,
+ unsigned long base)
+{
+ DBG;
+
+ core->base = base;
+
+ /* Setting the camera core AUTOIDLE bit causes problems with
frame
+ * synchronization, so we will clear the AUTOIDLE bit instead.
+ */
+ //omap24xxcam_reg_out(cam, CC_SYSCONFIG, 0);
+ omap24xxcam_reg_out(core->base, CC_SYSCONFIG,
CC_SYSCONFIG_AUTOIDLE);
+
+ core->xclk_enabled = 0;
+}
+
+void omap24xxcam_core_exit(const struct omap24xxcam_core *core) +{
+}
+

5. Your drivers/media/video/omap/omap24xxcam-sgdma.c is same as what is available in drivers/media/video/omap/omap24xxcam-dma.c (from David).

6. Same with vbq.c.

7. Ioctl mapping is ok, but it might be an issue if were to add a special case that is not part of V4L2 for now (atleast for testing sake).

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): [email protected]

#15 lore raw

Re: Fwd: [PATCH] ARM: OMAP2: Camera: Add OMAP2 24xx camera driver.

Quoted 1 line · André Goddard Rosa

Hi, Sakari!

Hello,

And thanks for the comments!

...

Quoted 22 lines
Quoted 7 lines
drivers/media/video/omap/omap24xxcam.c new file +7 -0
+static int
+omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       struct omap24xxcam_fh *fh = file->private_data;
+       int err;
+
+       /* let the video-buf mapper check arguments and set-up structures */

drivers/media/video/omap/omap24xxcam.c line 679

Quoted 10 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+       err = videobuf_mmap_mapper(&fh->vbq, vma);
+       if (err)
+               goto err1;
+
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+       /* do mapping to our allocated buffers */
+       err = omap24xxcam_mmap_buffers(file, vma);
+       if (err)
+               goto err2;

Same comments of Trilok here, but also please find that videobuf_mmap_mapper() allocates memory. Where is it being released in this case?

Quoted 1 line

Should we call videobuf_mmap_free() in this error case?

It's that kfree. If you look at the other drivers, no special attention is paid on this one. It's because the vidobuf_mmap_mapper is the last function called, i.e. there is no case where videobuf_mmap_mapper would succeed but the driver's mmap call would fail.

...

Quoted 15 lines
Quoted 11 lines
drivers/media/video/omap/omap24xxcam.c new file +10 -0
+       omap24xxcam_sensor_exit(cam);
+
+       if (cam->vfd) {
+               if (cam->vfd->minor == -1) {
+                       /* The device was never registered, so release the
+                        * video_device struct directly.
+                        */
+                       video_device_release(cam->vfd);
+               } else {
+                       /* The unregister function will release the

video_device

drivers/media/video/omap/omap24xxcam.c line 1009

Quoted 3 lines
drivers/media/video/omap/omap24xxcam.c new file +3 -0
+                        * struct as well as unregistering it.
+                        */
+                       video_unregister_device(cam->vfd);
Quoted 2 lines

Are you sure that video_unregister_device() calls video_device_release(cam->vfd) or does kfree(cam->vfd) in its regular path?

video_unregister_device doesn't do that directly. I have to check further what's happening here.

It indeed looks like a potential memory leak.

Regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#16 lore raw
In reply to Sakari Ailus

If some patches are for review please mark them as "RFC". "Patch" is when it has to go into tree - Some one can correct me if I am wrong.

Sakari,

Thanks for the code, do you have any kind of design doc or ppt that gives a brief overview of what the code is and the interface considered etc. Its bit hard to go directly to code :(

The second issue is merging TI's camera code with this. I can post our design considerations for camera. We can see how to integrate TIs sensor and additional functionality provided by TI's camera code (like rotation, scatter gather dma, multiple sensors handling etc).

Please do comment if you find any issues with the same.

Regards,
Khasim

Quoted 35 lines

-----Original Message-----
From: [email protected] [mailto:linux-omap- [email protected]] On Behalf Of Sakari Ailus
Sent: Wednesday, February 28, 2007 9:49 AM
To: [email protected]
Subject: [PATCH] OMAP2 camera and TCM825x sensor drivers

Hi,

I'm about to send a patch set of OMAP 2 camera and a TCM825x sensor drivers. Compared to those from maemo.org, there are clean-ups and the overlay support has been removed, among other things.

This is all still very much work in progress but I'd be glad to hear comments about it.

Both drivers should compile, and also function with 2.6.18 from maemo.org. (Except that there's a bug in VIDIOC_DQBUF in 2.6.18.) Some N800-specific code is missing for the moment. Also locking is in sore state. The interface changes (temporarily) break existing OMAP 1 camera driver and the ov9640 sensor driver.

These patches are against Tony's tree.

I recommend not to apply these for the time being. :)

Regards,

--
Sakari Ailus
[email protected]
_______________________________________________
Linux-omap-open-source mailing list
[email protected]
http://linux.omap.com/mailman/listinfo/linux-omap-open-source

#17 lore raw

Syed,

Quoted 8 lines · Khasim

If some patches are for review please mark them as "RFC". "Patch" is when it has to go into tree - Some one can correct me if I am wrong.

Sakari,

Thanks for the code, do you have any kind of design doc or ppt that gives a brief overview of what the code is and the interface considered etc. Its bit hard to go directly to code :(

I don't think that you will need this. What interface you would like to understand? Please phrase the questions based on the code and may Sakari can help you to understand :) I believe some of the changes in N800 camera driver was also done to reduce the interrupt latencies and bugs in video-buf.

Quoted 5 lines

The second issue is merging TI's camera code with this. I can post our design considerations for camera. We can see how to integrate TIs sensor and additional functionality provided by TI's camera code (like rotation, scatter gather dma, multiple sensors handling etc).

Do you mean "rotation" of the preview window ? See, preview in camera driver is just a add-on functionality _but_ not must. I would not use this auto preview functionality, instead captured stream will go to /dev/fb1 and then shown on the LCD/TV out and rotated based on the N800 sensor or app commands.

Signature · 1 line
--Trilok Soni
#18 lore raw
Quoted 12 lines · Trilok Soni

Syed,

Quoted 8 lines · Khasim

If some patches are for review please mark them as "RFC". "Patch" is when it has to go into tree - Some one can correct me if I am wrong.

Sakari,

Thanks for the code, do you have any kind of design doc or ppt that gives a brief overview of what the code is and the interface considered etc. Its bit hard to go directly to code :(

Quoted 5 lines

I don't think that you will need this. What interface you would like to understand? Please phrase the questions based on the code and may Sakari can help you to understand :) I believe some of the changes in N800 camera driver was also done to reduce the interrupt latencies and bugs in video-buf.

I agree with Trilok. The idea is to do incremental changes based on patches.

Quoted 10 lines
Quoted 4 lines

The second issue is merging TI's camera code with this. I can post our design considerations for camera. We can see how to integrate TIs sensor and additional functionality provided by TI's camera code (like rotation, scatter gather dma, multiple sensors handling etc).

Do you mean "rotation" of the preview window ? See, preview in camera driver is just a add-on functionality _but_ not must. I would not use this auto preview functionality, instead captured stream will go to /dev/fb1 and then shown on the LCD/TV out and rotated based on the N800 sensor or app commands.

Yyp, additional features are easy to add later once we have basics in place.

Regards,

Tony

#19 lore raw
Quoted 2 lines
Quoted 2 lines

do you have any kind of design doc or ppt that gives a brief overview of what the code is and the interface

considered

Sakari, taking this back :) Sorry was kind of used to these for a while.

Quoted 5 lines
Quoted 5 lines

Do you mean "rotation" of the preview window ? See, preview in camera driver is just a add-on functionality _but_ not must. I would not use this auto preview functionality, instead captured stream will go to /dev/fb1 and then shown on the LCD/TV out and rotated based on the N800 sensor or app commands.

Trilok, this may be your use case but not true for all OMAP users :) Few take preview seriously; I have seen demands for a preview with rotation/mirroring/cropping/scaling :) Again it's as per demands. Why to send a data to app that is not getting stored?

No issues, as Tony suggested we can go ahead and add more functionality later (if required).

Trilok, will you be pushing the Micron sensor library too?

Regards,
Khasim

Quoted 7 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]]
Sent: Thursday, March 01, 2007 2:07 AM
To: Trilok Soni
Cc: Syed Mohammed, Khasim; [email protected]
Subject: Re: [PATCH] OMAP2 camera and TCM825x sensor drivers

Quoted 11 lines
Quoted 10 lines · Trilok Soni

Syed,

Quoted 7 lines · Khasim

If some patches are for review please mark them as "RFC". "Patch" is when it has to go into tree - Some one can correct me if I am wrong.

Sakari,

Thanks for the code, do you have any kind of design doc or ppt that gives a brief overview of what the code is and the interface

considered

Quoted 6 lines
Quoted 6 lines
Quoted 1 line

etc. Its bit hard to go directly to code :(

I don't think that you will need this. What interface you would like to understand? Please phrase the questions based on the code and may Sakari can help you to understand :) I believe some of the changes in N800 camera driver was also done to reduce the interrupt latencies

and

Quoted 6 lines
Quoted 1 line

bugs in video-buf.

I agree with Trilok. The idea is to do incremental changes based on patches.

Quoted 1 line
Quoted 1 line

The second issue is merging TI's camera code with this. I can post

our

Quoted 1 line
Quoted 1 line
Quoted 1 line

design considerations for camera. We can see how to integrate TIs

sensor

Quoted 15 lines
Quoted 8 lines
Quoted 2 lines

and additional functionality provided by TI's camera code (like rotation, scatter gather dma, multiple sensors handling etc).

Do you mean "rotation" of the preview window ? See, preview in camera driver is just a add-on functionality _but_ not must. I would not use this auto preview functionality, instead captured stream will go to /dev/fb1 and then shown on the LCD/TV out and rotated based on the N800 sensor or app commands.

Yyp, additional features are easy to add later once we have basics in place.

Regards,

Tony

#20 lore raw

Hi All

Can some one tell me when I use the camera on N800 then which part of the code gets executed?
I mean is there some application, which starts running and opens camera driver or there is no application program on the top of camera driver, it is just the camera driver which gets started when I start using the camera and takes care of capturing pics?

If it is some application on top of camera driver then how does it interact with the camera driver? does it interacts in a linux std way, I mean first it opens /dev/video0 then it sends ioctl commands etc.?
Please enlighten these points, I am confused.

Thanks in advance.
Sahlot

Quoted 84 lines · Khasim
Quoted 3 lines
Quoted 3 lines

do you have any kind of design doc or ppt that gives a brief overview of what the code is and the interface

considered

Sakari, taking this back :) Sorry was kind of used to these for a while.

Quoted 5 lines
Quoted 5 lines

Do you mean "rotation" of the preview window ? See, preview in camera driver is just a add-on functionality _but_ not must. I would not use this auto preview functionality, instead captured stream will go to /dev/fb1 and then shown on the LCD/TV out and rotated based on the N800 sensor or app commands.

Trilok, this may be your use case but not true for all OMAP users :) Few take preview seriously; I have seen demands for a preview with rotation/mirroring/cropping/scaling :) Again it's as per demands. Why to send a data to app that is not getting stored?

No issues, as Tony suggested we can go ahead and add more functionality later (if required).

Trilok, will you be pushing the Micron sensor library too?

Regards,
Khasim

Quoted 7 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]]
Sent: Thursday, March 01, 2007 2:07 AM
To: Trilok Soni
Cc: Syed Mohammed, Khasim; [email protected]
Subject: Re: [PATCH] OMAP2 camera and TCM825x sensor drivers

Quoted 11 lines
Quoted 10 lines · Trilok Soni

Syed,

Quoted 7 lines · Khasim

If some patches are for review please mark them as "RFC". "Patch" is when it has to go into tree - Some one can correct me if I am wrong.

Sakari,

Thanks for the code, do you have any kind of design doc or ppt that gives a brief overview of what the code is and the interface

considered

Quoted 6 lines
Quoted 6 lines
Quoted 1 line

etc. Its bit hard to go directly to code :(

I don't think that you will need this. What interface you would like to understand? Please phrase the questions based on the code and may Sakari can help you to understand :) I believe some of the changes in N800 camera driver was also done to reduce the interrupt latencies

and

Quoted 6 lines
Quoted 1 line

bugs in video-buf.

I agree with Trilok. The idea is to do incremental changes based on patches.

Quoted 1 line
Quoted 1 line

The second issue is merging TI's camera code with this. I can post

our

Quoted 1 line
Quoted 1 line
Quoted 1 line

design considerations for camera. We can see how to integrate TIs

sensor

Quoted 9 lines
Quoted 8 lines
Quoted 2 lines

and additional functionality provided by TI's camera code (like rotation, scatter gather dma, multiple sensors handling etc).

Do you mean "rotation" of the preview window ? See, preview in camera driver is just a add-on functionality _but_ not must. I would not use this auto preview functionality, instead captured stream will go to /dev/fb1 and then shown on the LCD/TV out and rotated based on the N800 sensor or app commands.

Quoted 6 lines

Yyp, additional features are easy to add later once we have basics in place.

Regards,

Tony

_______________________________________________
Linux-omap-open-source mailing list
[email protected]
http://linux.omap.com/mailman/listinfo/linux-omap-open-source

#21 lore raw

Hi, Sahlot Arvind!

Quoted 9 lines · ext sahlot arvind

Hi All

Can some one tell me when I use the camera on N800 then which part of the code gets executed?
I mean is there some application, which starts running and opens camera driver or there is no application program on the top of camera driver, it is just the camera driver which gets started when I start using the camera and takes care of capturing pics?

Quoted 5 lines

If it is some application on top of camera driver then how does it interact with the camera driver? does it interacts in a linux std way, I mean first it opens /dev/video0 then it sends ioctl commands etc.?
Please enlighten these points, I am confused.

Please take a look at this link: http://maemo.org/platform/docs/howtos/howto_camera_api_bora.html

Best regards,
André Goddard

#22 lore raw
In reply to Syed Mohammed, Khasim
Quoted 5 lines · Khasim
Quoted 2 lines
Quoted 2 lines

do you have any kind of design doc or ppt that gives a brief overview of what the code is and the interface

considered

Sakari, taking this back :) Sorry was kind of used to these for a while.

Good, as I didn't have any. ;)

Quoted 10 lines
Quoted 5 lines
Quoted 5 lines

Do you mean "rotation" of the preview window ? See, preview in camera driver is just a add-on functionality _but_ not must. I would not use this auto preview functionality, instead captured stream will go to /dev/fb1 and then shown on the LCD/TV out and rotated based on the N800 sensor or app commands.

Trilok, this may be your use case but not true for all OMAP users :) Few take preview seriously; I have seen demands for a preview with rotation/mirroring/cropping/scaling :) Again it's as per demands. Why to send a data to app that is not getting stored?

Is there a real life use case where even preview is really useful? Or necessary? (I'm asking because I can't figure anything immediately. Except maybe something like xawtv, but for a camera. :))

Signature · 2 lines
Sakari Ailus
[email protected]
#23 lore raw
In reply to Syed Mohammed, Khasim
Quoted 2 lines · Khasim

If some patches are for review please mark them as "RFC". "Patch" is when it has to go into tree - Some one can correct me if I am wrong.

Alright, I'll do that next time.

Quoted 3 lines

Thanks for the code, do you have any kind of design doc or ppt that gives a brief overview of what the code is and the interface considered etc. Its bit hard to go directly to code :(

I'm afraid I don't have any.

The primary goal for me at the moment regarding these drivers is to clean them up and integrated them to Tony's git tree. I think supporting all the features at this point is somewhat secondary unless they are really needed.

Quoted 4 lines

The second issue is merging TI's camera code with this. I can post our design considerations for camera. We can see how to integrate TIs sensor and additional functionality provided by TI's camera code (like rotation, scatter gather dma, multiple sensors handling etc).

Add-on features will probably have to wait till I get the driver into better shape.

Signature · 2 lines
Sakari Ailus
[email protected]