diff options
author | Magnus Damm <damm@igel.co.jp> | 2008-12-18 10:50:30 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:40:25 -0500 |
commit | 7a1a81643f80df3ff3351b1a81e54470dc47681d (patch) | |
tree | ad663a1c583b8942759789ebe50ae998c7ad7d9c /drivers/media/video | |
parent | 34d359db7d683e227f27595ad3702fb2ae96108a (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.c | 49 |
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 | ||
103 | static void ceu_write(struct sh_mobile_ceu_dev *priv, | 103 | static 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 | ||
109 | static unsigned long ceu_read(struct sh_mobile_ceu_dev *priv, | 109 | static 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 | |||
158 | static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) | 163 | static 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); |