aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2008-12-18 10:50:30 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:40:25 -0500
commit7a1a81643f80df3ff3351b1a81e54470dc47681d (patch)
treead663a1c583b8942759789ebe50ae998c7ad7d9c /drivers/media/video
parent34d359db7d683e227f27595ad3702fb2ae96108a (diff)
V4L/DVB (10088): video: sh_mobile_ceu cleanups and comments
This patch cleans up the sh_mobile_ceu driver and adds comments and constants to clarify the magic sequence in sh_mobile_ceu_capture(). Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 7d1a84426413..79eda0fed9f9 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -101,13 +101,12 @@ struct sh_mobile_ceu_dev {
101}; 101};
102 102
103static void ceu_write(struct sh_mobile_ceu_dev *priv, 103static void ceu_write(struct sh_mobile_ceu_dev *priv,
104 unsigned long reg_offs, unsigned long data) 104 unsigned long reg_offs, u32 data)
105{ 105{
106 iowrite32(data, priv->base + reg_offs); 106 iowrite32(data, priv->base + reg_offs);
107} 107}
108 108
109static unsigned long ceu_read(struct sh_mobile_ceu_dev *priv, 109static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
110 unsigned long reg_offs)
111{ 110{
112 return ioread32(priv->base + reg_offs); 111 return ioread32(priv->base + reg_offs);
113} 112}
@@ -155,18 +154,26 @@ static void free_buffer(struct videobuf_queue *vq,
155 buf->vb.state = VIDEOBUF_NEEDS_INIT; 154 buf->vb.state = VIDEOBUF_NEEDS_INIT;
156} 155}
157 156
157#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
158#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
159#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
160#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
161
162
158static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) 163static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
159{ 164{
160 struct soc_camera_device *icd = pcdev->icd; 165 struct soc_camera_device *icd = pcdev->icd;
161 unsigned long phys_addr; 166 dma_addr_t phys_addr;
162
163 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~1);
164 ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & 0x0317f313);
165 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | 1);
166 167
167 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~0x10000); 168 /* The hardware is _very_ picky about this sequence. Especially
168 169 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
169 ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10); 170 * several not-so-well documented interrupt sources in CETCR.
171 */
172 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_CPEIE);
173 ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & CEU_CETCR_MAGIC);
174 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_CPEIE);
175 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
176 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
170 177
171 if (!pcdev->active) 178 if (!pcdev->active)
172 return; 179 return;
@@ -179,7 +186,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
179 case V4L2_PIX_FMT_NV21: 186 case V4L2_PIX_FMT_NV21:
180 case V4L2_PIX_FMT_NV16: 187 case V4L2_PIX_FMT_NV16:
181 case V4L2_PIX_FMT_NV61: 188 case V4L2_PIX_FMT_NV61:
182 phys_addr += (icd->width * icd->height); 189 phys_addr += icd->width * icd->height;
183 ceu_write(pcdev, CDACR, phys_addr); 190 ceu_write(pcdev, CDACR, phys_addr);
184 } 191 }
185 192
@@ -431,13 +438,13 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
431 } 438 }
432 } 439 }
433 440
434 if ((icd->current_fmt->fourcc == V4L2_PIX_FMT_NV21) || 441 if (icd->current_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
435 (icd->current_fmt->fourcc == V4L2_PIX_FMT_NV61)) 442 icd->current_fmt->fourcc == V4L2_PIX_FMT_NV61)
436 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */ 443 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
437 444
438 value |= (common_flags & SOCAM_VSYNC_ACTIVE_LOW) ? (1 << 1) : 0; 445 value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
439 value |= (common_flags & SOCAM_HSYNC_ACTIVE_LOW) ? (1 << 0) : 0; 446 value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
440 value |= (buswidth == 16) ? (1 << 12) : 0; 447 value |= buswidth == 16 ? 1 << 12 : 0;
441 ceu_write(pcdev, CAMCR, value); 448 ceu_write(pcdev, CAMCR, value);
442 449
443 ceu_write(pcdev, CAPCR, 0x00300000); 450 ceu_write(pcdev, CAPCR, 0x00300000);
@@ -447,13 +454,13 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
447 454
448 if (yuv_mode) { 455 if (yuv_mode) {
449 width = icd->width * 2; 456 width = icd->width * 2;
450 width = (buswidth == 16) ? width / 2 : width; 457 width = buswidth == 16 ? width / 2 : width;
451 cfszr_width = cdwdr_width = icd->width; 458 cfszr_width = cdwdr_width = icd->width;
452 } else { 459 } else {
453 width = icd->width * ((icd->current_fmt->depth + 7) >> 3); 460 width = icd->width * ((icd->current_fmt->depth + 7) >> 3);
454 width = (buswidth == 16) ? width / 2 : width; 461 width = buswidth == 16 ? width / 2 : width;
455 cfszr_width = (buswidth == 8) ? width / 2 : width; 462 cfszr_width = buswidth == 8 ? width / 2 : width;
456 cdwdr_width = (buswidth == 16) ? width * 2 : width; 463 cdwdr_width = buswidth == 16 ? width * 2 : width;
457 } 464 }
458 465
459 ceu_write(pcdev, CAMOR, 0); 466 ceu_write(pcdev, CAMOR, 0);