Skip to contentSkip to conversation

video: sh_mobile_ceu cleanups and comments

PATCH New Magnus Damm 1 participant 1 message Dec 15, 2008 Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 video: sh_mobile_ceu cleanups and comments

From: Magnus Damm <[email protected]>

This patch cleans up the sh_mobile_ceu driver and adds comments and constants to clarify the magic sequence in sh_mobile_ceu_capture().

---

Applies on top of the NV16 patch. The interlace patch is excluded.

 drivers/media/video/sh_mobile_ceu_camera.c |   40 ++++++++++++++++------------
 1 file changed, 23 insertions(+), 17 deletions(-)
drivers/media/video/sh_mobile_ceu_camera.c +23 -17
@@ -103,14 +103,12 @@ struct sh_mobile_ceu_dev {
 	const struct soc_camera_data_format *camera_fmt;
 };
 
-static void ceu_write(struct sh_mobile_ceu_dev *priv,
-		      unsigned long reg_offs, unsigned long data)
+static void ceu_write(struct sh_mobile_ceu_dev *priv, u32 reg_offs, u32 data)
 {
 	iowrite32(data, priv->base + reg_offs);
 }
 
-static unsigned long ceu_read(struct sh_mobile_ceu_dev *priv,
-			      unsigned long reg_offs)
+static u32 ceu_read(struct sh_mobile_ceu_dev *priv, u32 reg_offs)
 {
 	return ioread32(priv->base + reg_offs);
 }
@@ -158,18 +156,26 @@ static void free_buffer(struct videobuf_
 	buf->vb.state = VIDEOBUF_NEEDS_INIT;
 }
 
+#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
+#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
+#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
+#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
+
+
 static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 {
 	struct soc_camera_device *icd = pcdev->icd;
-	unsigned long phys_addr;
-
-	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~1);
-	ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & 0x0317f313);
-	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | 1);
+	dma_addr_t phys_addr;
 
-	ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~0x10000);
-
-	ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10);
+	/* The hardware is _very_ picky about this sequence. Especially
+	 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
+	 * several not-so-well documented interrupt sources in CETCR.
+	 */
+	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_CPEIE);
+	ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & CEU_CETCR_MAGIC);
+	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_CPEIE);
+	ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
+	ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
 
 	if (!pcdev->active)
 		return;
@@ -182,7 +188,7 @@ static void sh_mobile_ceu_capture(struct
 	case V4L2_PIX_FMT_NV21:
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
-		phys_addr += (icd->width * icd->height);
+		phys_addr += icd->width * icd->height;
 		ceu_write(pcdev, CDACR, phys_addr);
 	}
 
@@ -452,13 +458,13 @@ static int sh_mobile_ceu_set_bus_param(s
 
 	if (yuv_mode) {
 		width = icd->width * 2;
-		width = (buswidth == 16) ? width / 2 : width;
+		width = buswidth == 16 ? width / 2 : width;
 		cfszr_width = cdwdr_width = icd->width;
 	} else {
 		width = icd->width * ((icd->current_fmt->depth + 7) >> 3);
-		width = (buswidth == 16) ? width / 2 : width;
-		cfszr_width = (buswidth == 8) ? width / 2 : width;
-		cdwdr_width = (buswidth == 16) ? width * 2 : width;
+		width = buswidth == 16 ? width / 2 : width;
+		cfszr_width = buswidth == 8 ? width / 2 : width;
+		cdwdr_width = buswidth == 16 ? width * 2 : width;
 	}
 
 	ceu_write(pcdev, CAMOR, 0);

--
video4linux-list mailing list
Unsubscribe mailto:[email protected]?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list