diff options
Diffstat (limited to 'drivers/media/video/mx1_camera.c')
-rw-r--r-- | drivers/media/video/mx1_camera.c | 126 |
1 files changed, 97 insertions, 29 deletions
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 72802291e81..2ba14fb5b03 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
38 | #include <media/v4l2-dev.h> | 38 | #include <media/v4l2-dev.h> |
39 | #include <media/videobuf-dma-contig.h> | 39 | #include <media/videobuf-dma-contig.h> |
40 | #include <media/soc_mediabus.h> | ||
40 | 41 | ||
41 | #include <asm/dma.h> | 42 | #include <asm/dma.h> |
42 | #include <asm/fiq.h> | 43 | #include <asm/fiq.h> |
@@ -94,14 +95,16 @@ | |||
94 | /* buffer for one video frame */ | 95 | /* buffer for one video frame */ |
95 | struct mx1_buffer { | 96 | struct mx1_buffer { |
96 | /* common v4l buffer stuff -- must be first */ | 97 | /* common v4l buffer stuff -- must be first */ |
97 | struct videobuf_buffer vb; | 98 | struct videobuf_buffer vb; |
98 | const struct soc_camera_data_format *fmt; | 99 | enum v4l2_mbus_pixelcode code; |
99 | int inwork; | 100 | int inwork; |
100 | }; | 101 | }; |
101 | 102 | ||
102 | /* i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor | 103 | /* |
104 | * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor | ||
103 | * Interface. If anyone ever builds hardware to enable more than | 105 | * Interface. If anyone ever builds hardware to enable more than |
104 | * one camera, they will have to modify this driver too */ | 106 | * one camera, they will have to modify this driver too |
107 | */ | ||
105 | struct mx1_camera_dev { | 108 | struct mx1_camera_dev { |
106 | struct soc_camera_host soc_host; | 109 | struct soc_camera_host soc_host; |
107 | struct soc_camera_device *icd; | 110 | struct soc_camera_device *icd; |
@@ -126,9 +129,13 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, | |||
126 | unsigned int *size) | 129 | unsigned int *size) |
127 | { | 130 | { |
128 | struct soc_camera_device *icd = vq->priv_data; | 131 | struct soc_camera_device *icd = vq->priv_data; |
132 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
133 | icd->current_fmt->host_fmt); | ||
134 | |||
135 | if (bytes_per_line < 0) | ||
136 | return bytes_per_line; | ||
129 | 137 | ||
130 | *size = icd->user_width * icd->user_height * | 138 | *size = bytes_per_line * icd->user_height; |
131 | ((icd->current_fmt->depth + 7) >> 3); | ||
132 | 139 | ||
133 | if (!*count) | 140 | if (!*count) |
134 | *count = 32; | 141 | *count = 32; |
@@ -151,8 +158,10 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf) | |||
151 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 158 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, |
152 | vb, vb->baddr, vb->bsize); | 159 | vb, vb->baddr, vb->bsize); |
153 | 160 | ||
154 | /* This waits until this buffer is out of danger, i.e., until it is no | 161 | /* |
155 | * longer in STATE_QUEUED or STATE_ACTIVE */ | 162 | * This waits until this buffer is out of danger, i.e., until it is no |
163 | * longer in STATE_QUEUED or STATE_ACTIVE | ||
164 | */ | ||
156 | videobuf_waiton(vb, 0, 0); | 165 | videobuf_waiton(vb, 0, 0); |
157 | videobuf_dma_contig_free(vq, vb); | 166 | videobuf_dma_contig_free(vq, vb); |
158 | 167 | ||
@@ -165,6 +174,11 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq, | |||
165 | struct soc_camera_device *icd = vq->priv_data; | 174 | struct soc_camera_device *icd = vq->priv_data; |
166 | struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); | 175 | struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); |
167 | int ret; | 176 | int ret; |
177 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
178 | icd->current_fmt->host_fmt); | ||
179 | |||
180 | if (bytes_per_line < 0) | ||
181 | return bytes_per_line; | ||
168 | 182 | ||
169 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 183 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, |
170 | vb, vb->baddr, vb->bsize); | 184 | vb, vb->baddr, vb->bsize); |
@@ -174,22 +188,24 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq, | |||
174 | 188 | ||
175 | BUG_ON(NULL == icd->current_fmt); | 189 | BUG_ON(NULL == icd->current_fmt); |
176 | 190 | ||
177 | /* I think, in buf_prepare you only have to protect global data, | 191 | /* |
178 | * the actual buffer is yours */ | 192 | * I think, in buf_prepare you only have to protect global data, |
193 | * the actual buffer is yours | ||
194 | */ | ||
179 | buf->inwork = 1; | 195 | buf->inwork = 1; |
180 | 196 | ||
181 | if (buf->fmt != icd->current_fmt || | 197 | if (buf->code != icd->current_fmt->code || |
182 | vb->width != icd->user_width || | 198 | vb->width != icd->user_width || |
183 | vb->height != icd->user_height || | 199 | vb->height != icd->user_height || |
184 | vb->field != field) { | 200 | vb->field != field) { |
185 | buf->fmt = icd->current_fmt; | 201 | buf->code = icd->current_fmt->code; |
186 | vb->width = icd->user_width; | 202 | vb->width = icd->user_width; |
187 | vb->height = icd->user_height; | 203 | vb->height = icd->user_height; |
188 | vb->field = field; | 204 | vb->field = field; |
189 | vb->state = VIDEOBUF_NEEDS_INIT; | 205 | vb->state = VIDEOBUF_NEEDS_INIT; |
190 | } | 206 | } |
191 | 207 | ||
192 | vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); | 208 | vb->size = bytes_per_line * vb->height; |
193 | if (0 != vb->baddr && vb->bsize < vb->size) { | 209 | if (0 != vb->baddr && vb->bsize < vb->size) { |
194 | ret = -EINVAL; | 210 | ret = -EINVAL; |
195 | goto out; | 211 | goto out; |
@@ -381,8 +397,10 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev) | |||
381 | 397 | ||
382 | lcdclk = clk_get_rate(pcdev->clk); | 398 | lcdclk = clk_get_rate(pcdev->clk); |
383 | 399 | ||
384 | /* We verify platform_mclk_10khz != 0, so if anyone breaks it, here | 400 | /* |
385 | * they get a nice Oops */ | 401 | * We verify platform_mclk_10khz != 0, so if anyone breaks it, here |
402 | * they get a nice Oops | ||
403 | */ | ||
386 | div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; | 404 | div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; |
387 | 405 | ||
388 | dev_dbg(pcdev->icd->dev.parent, | 406 | dev_dbg(pcdev->icd->dev.parent, |
@@ -420,8 +438,10 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) | |||
420 | clk_disable(pcdev->clk); | 438 | clk_disable(pcdev->clk); |
421 | } | 439 | } |
422 | 440 | ||
423 | /* The following two functions absolutely depend on the fact, that | 441 | /* |
424 | * there can be only one camera on i.MX1/i.MXL camera sensor interface */ | 442 | * The following two functions absolutely depend on the fact, that |
443 | * there can be only one camera on i.MX1/i.MXL camera sensor interface | ||
444 | */ | ||
425 | static int mx1_camera_add_device(struct soc_camera_device *icd) | 445 | static int mx1_camera_add_device(struct soc_camera_device *icd) |
426 | { | 446 | { |
427 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 447 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
@@ -487,12 +507,10 @@ static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
487 | 507 | ||
488 | /* MX1 supports only 8bit buswidth */ | 508 | /* MX1 supports only 8bit buswidth */ |
489 | common_flags = soc_camera_bus_param_compatible(camera_flags, | 509 | common_flags = soc_camera_bus_param_compatible(camera_flags, |
490 | CSI_BUS_FLAGS); | 510 | CSI_BUS_FLAGS); |
491 | if (!common_flags) | 511 | if (!common_flags) |
492 | return -EINVAL; | 512 | return -EINVAL; |
493 | 513 | ||
494 | icd->buswidth = 8; | ||
495 | |||
496 | /* Make choises, based on platform choice */ | 514 | /* Make choises, based on platform choice */ |
497 | if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && | 515 | if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && |
498 | (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { | 516 | (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { |
@@ -545,7 +563,8 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd, | |||
545 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 563 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
546 | const struct soc_camera_format_xlate *xlate; | 564 | const struct soc_camera_format_xlate *xlate; |
547 | struct v4l2_pix_format *pix = &f->fmt.pix; | 565 | struct v4l2_pix_format *pix = &f->fmt.pix; |
548 | int ret; | 566 | struct v4l2_mbus_framefmt mf; |
567 | int ret, buswidth; | ||
549 | 568 | ||
550 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 569 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
551 | if (!xlate) { | 570 | if (!xlate) { |
@@ -554,12 +573,33 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd, | |||
554 | return -EINVAL; | 573 | return -EINVAL; |
555 | } | 574 | } |
556 | 575 | ||
557 | ret = v4l2_subdev_call(sd, video, s_fmt, f); | 576 | buswidth = xlate->host_fmt->bits_per_sample; |
558 | if (!ret) { | 577 | if (buswidth > 8) { |
559 | icd->buswidth = xlate->buswidth; | 578 | dev_warn(icd->dev.parent, |
560 | icd->current_fmt = xlate->host_fmt; | 579 | "bits-per-sample %d for format %x unsupported\n", |
580 | buswidth, pix->pixelformat); | ||
581 | return -EINVAL; | ||
561 | } | 582 | } |
562 | 583 | ||
584 | mf.width = pix->width; | ||
585 | mf.height = pix->height; | ||
586 | mf.field = pix->field; | ||
587 | mf.colorspace = pix->colorspace; | ||
588 | mf.code = xlate->code; | ||
589 | |||
590 | ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); | ||
591 | if (ret < 0) | ||
592 | return ret; | ||
593 | |||
594 | if (mf.code != xlate->code) | ||
595 | return -EINVAL; | ||
596 | |||
597 | pix->width = mf.width; | ||
598 | pix->height = mf.height; | ||
599 | pix->field = mf.field; | ||
600 | pix->colorspace = mf.colorspace; | ||
601 | icd->current_fmt = xlate; | ||
602 | |||
563 | return ret; | 603 | return ret; |
564 | } | 604 | } |
565 | 605 | ||
@@ -567,10 +607,36 @@ static int mx1_camera_try_fmt(struct soc_camera_device *icd, | |||
567 | struct v4l2_format *f) | 607 | struct v4l2_format *f) |
568 | { | 608 | { |
569 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 609 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
610 | const struct soc_camera_format_xlate *xlate; | ||
611 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
612 | struct v4l2_mbus_framefmt mf; | ||
613 | int ret; | ||
570 | /* TODO: limit to mx1 hardware capabilities */ | 614 | /* TODO: limit to mx1 hardware capabilities */ |
571 | 615 | ||
616 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | ||
617 | if (!xlate) { | ||
618 | dev_warn(icd->dev.parent, "Format %x not found\n", | ||
619 | pix->pixelformat); | ||
620 | return -EINVAL; | ||
621 | } | ||
622 | |||
623 | mf.width = pix->width; | ||
624 | mf.height = pix->height; | ||
625 | mf.field = pix->field; | ||
626 | mf.colorspace = pix->colorspace; | ||
627 | mf.code = xlate->code; | ||
628 | |||
572 | /* limit to sensor capabilities */ | 629 | /* limit to sensor capabilities */ |
573 | return v4l2_subdev_call(sd, video, try_fmt, f); | 630 | ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); |
631 | if (ret < 0) | ||
632 | return ret; | ||
633 | |||
634 | pix->width = mf.width; | ||
635 | pix->height = mf.height; | ||
636 | pix->field = mf.field; | ||
637 | pix->colorspace = mf.colorspace; | ||
638 | |||
639 | return 0; | ||
574 | } | 640 | } |
575 | 641 | ||
576 | static int mx1_camera_reqbufs(struct soc_camera_file *icf, | 642 | static int mx1_camera_reqbufs(struct soc_camera_file *icf, |
@@ -578,10 +644,12 @@ static int mx1_camera_reqbufs(struct soc_camera_file *icf, | |||
578 | { | 644 | { |
579 | int i; | 645 | int i; |
580 | 646 | ||
581 | /* This is for locking debugging only. I removed spinlocks and now I | 647 | /* |
648 | * This is for locking debugging only. I removed spinlocks and now I | ||
582 | * check whether .prepare is ever called on a linked buffer, or whether | 649 | * check whether .prepare is ever called on a linked buffer, or whether |
583 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now | 650 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now |
584 | * it hadn't triggered */ | 651 | * it hadn't triggered |
652 | */ | ||
585 | for (i = 0; i < p->count; i++) { | 653 | for (i = 0; i < p->count; i++) { |
586 | struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i], | 654 | struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i], |
587 | struct mx1_buffer, vb); | 655 | struct mx1_buffer, vb); |