Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 173935
b: refs/heads/master
c: 5cf93f1
h: refs/heads/master
i:
  173933: 7ae3b81
  173931: d924b5f
  173927: 074d404
  173919: cf97943
v: v3
  • Loading branch information
Kuninori Morimoto authored and Mauro Carvalho Chehab committed Dec 5, 2009
1 parent 4aa4e75 commit b2101fe
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b1de7aeba1d7592b97507c21ea986ec6243a4165
refs/heads/master: 5cf93f1dcaff4960bdfea22196963556778b22b3
41 changes: 33 additions & 8 deletions trunk/drivers/media/video/sh_mobile_ceu_camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,26 +236,45 @@ static void free_buffer(struct videobuf_queue *vq,
#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_CEIER_VBP (1 << 20) /* vbp error */
#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
#define CEU_CEIER_MASK (CEU_CEIER_CPEIE | CEU_CEIER_VBP)


static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
/*
* return value doesn't reflex the success/failure to queue the new buffer,
* but rather the status of the previous buffer.
*/
static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
{
struct soc_camera_device *icd = pcdev->icd;
dma_addr_t phys_addr_top, phys_addr_bottom;
u32 status;
int ret = 0;

/* 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, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
status = ceu_read(pcdev, CETCR);
ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);

/*
* When a VBP interrupt occurs, a capture end interrupt does not occur
* and the image of that frame is not captured correctly. So, soft reset
* is needed here.
*/
if (status & CEU_CEIER_VBP) {
sh_mobile_ceu_soft_reset(pcdev);
ret = -EIO;
}

if (!pcdev->active)
return;
return ret;

phys_addr_top = videobuf_to_dma_contig(pcdev->active);
ceu_write(pcdev, CDAYR, phys_addr_top);
Expand All @@ -281,6 +300,8 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)

pcdev->active->state = VIDEOBUF_ACTIVE;
ceu_write(pcdev, CAPSR, 0x1); /* start capture */

return ret;
}

static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
Expand Down Expand Up @@ -353,6 +374,11 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
list_add_tail(&vb->queue, &pcdev->capture);

if (!pcdev->active) {
/*
* Because there were no active buffer at this moment,
* we are not interested in the return value of
* sh_mobile_ceu_capture here.
*/
pcdev->active = vb;
sh_mobile_ceu_capture(pcdev);
}
Expand Down Expand Up @@ -413,9 +439,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
else
pcdev->active = NULL;

sh_mobile_ceu_capture(pcdev);

vb->state = VIDEOBUF_DONE;
vb->state = (sh_mobile_ceu_capture(pcdev) < 0) ?
VIDEOBUF_ERROR : VIDEOBUF_DONE;
do_gettimeofday(&vb->ts);
vb->field_count++;
wake_up(&vb->done);
Expand Down

0 comments on commit b2101fe

Please sign in to comment.