aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Rapoport <mike@compulab.co.il>2008-04-22 09:36:32 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:45 -0400
commita5462e5be3c1cec7e00e6af9985ff31bf4ef8aa0 (patch)
tree70f73b03fe40b47e6dea2a3ab2494f42cbb676ee /drivers
parent587df9fca6496f4236c526b2c83f068a63cfd769 (diff)
V4L/DVB (7669): pxa_camera: Add support for YUV modes
This patch adds support for YUV packed and planar capture for pxa_camera. Signed-off-by: Mike Rapoport <mike@compulab.co.il> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/pxa_camera.c416
1 files changed, 304 insertions, 112 deletions
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 936db67a5b0f..b999bda23c48 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -49,6 +49,9 @@
49 49
50#define CICR1_DW_VAL(x) ((x) & CICR1_DW) /* Data bus width */ 50#define CICR1_DW_VAL(x) ((x) & CICR1_DW) /* Data bus width */
51#define CICR1_PPL_VAL(x) (((x) << 15) & CICR1_PPL) /* Pixels per line */ 51#define CICR1_PPL_VAL(x) (((x) << 15) & CICR1_PPL) /* Pixels per line */
52#define CICR1_COLOR_SP_VAL(x) (((x) << 3) & CICR1_COLOR_SP) /* color space */
53#define CICR1_RGB_BPP_VAL(x) (((x) << 7) & CICR1_RGB_BPP) /* bpp for rgb */
54#define CICR1_RGBT_CONV_VAL(x) (((x) << 29) & CICR1_RGBT_CONV) /* rgbt conv */
52 55
53#define CICR2_BLW_VAL(x) (((x) << 24) & CICR2_BLW) /* Beginning-of-line pixel clock wait count */ 56#define CICR2_BLW_VAL(x) (((x) << 24) & CICR2_BLW) /* Beginning-of-line pixel clock wait count */
54#define CICR2_ELW_VAL(x) (((x) << 16) & CICR2_ELW) /* End-of-line pixel clock wait count */ 57#define CICR2_ELW_VAL(x) (((x) << 16) & CICR2_ELW) /* End-of-line pixel clock wait count */
@@ -70,6 +73,19 @@ static DEFINE_MUTEX(camera_lock);
70/* 73/*
71 * Structures 74 * Structures
72 */ 75 */
76enum pxa_camera_active_dma {
77 DMA_Y = 0x1,
78 DMA_U = 0x2,
79 DMA_V = 0x4,
80};
81
82/* descriptor needed for the PXA DMA engine */
83struct pxa_cam_dma {
84 dma_addr_t sg_dma;
85 struct pxa_dma_desc *sg_cpu;
86 size_t sg_size;
87 int sglen;
88};
73 89
74/* buffer for one video frame */ 90/* buffer for one video frame */
75struct pxa_buffer { 91struct pxa_buffer {
@@ -78,11 +94,12 @@ struct pxa_buffer {
78 94
79 const struct soc_camera_data_format *fmt; 95 const struct soc_camera_data_format *fmt;
80 96
81 /* our descriptor list needed for the PXA DMA engine */ 97 /* our descriptor lists for Y, U and V channels */
82 dma_addr_t sg_dma; 98 struct pxa_cam_dma dmas[3];
83 struct pxa_dma_desc *sg_cpu; 99
84 size_t sg_size;
85 int inwork; 100 int inwork;
101
102 enum pxa_camera_active_dma active_dma;
86}; 103};
87 104
88struct pxa_framebuffer_queue { 105struct pxa_framebuffer_queue {
@@ -100,7 +117,8 @@ struct pxa_camera_dev {
100 117
101 unsigned int irq; 118 unsigned int irq;
102 void __iomem *base; 119 void __iomem *base;
103 unsigned int dma_chan_y; 120
121 unsigned int dma_chans[3];
104 122
105 struct pxacamera_platform_data *pdata; 123 struct pxacamera_platform_data *pdata;
106 struct resource *res; 124 struct resource *res;
@@ -128,7 +146,15 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
128 146
129 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 147 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
130 148
131 *size = icd->width * icd->height * ((icd->current_fmt->depth + 7) >> 3); 149 /* planar capture requires Y, U and V buffers to be page aligned */
150 if (icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
151 *size = PAGE_ALIGN(icd->width * icd->height); /* Y pages */
152 *size += PAGE_ALIGN(icd->width * icd->height / 2); /* U pages */
153 *size += PAGE_ALIGN(icd->width * icd->height / 2); /* V pages */
154 } else {
155 *size = icd->width * icd->height *
156 ((icd->current_fmt->depth + 7) >> 3);
157 }
132 158
133 if (0 == *count) 159 if (0 == *count)
134 *count = 32; 160 *count = 32;
@@ -145,6 +171,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
145 to_soc_camera_host(icd->dev.parent); 171 to_soc_camera_host(icd->dev.parent);
146 struct pxa_camera_dev *pcdev = ici->priv; 172 struct pxa_camera_dev *pcdev = ici->priv;
147 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); 173 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
174 int i;
148 175
149 BUG_ON(in_interrupt()); 176 BUG_ON(in_interrupt());
150 177
@@ -157,14 +184,62 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
157 videobuf_dma_unmap(vq, dma); 184 videobuf_dma_unmap(vq, dma);
158 videobuf_dma_free(dma); 185 videobuf_dma_free(dma);
159 186
160 if (buf->sg_cpu) 187 for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
161 dma_free_coherent(pcdev->dev, buf->sg_size, buf->sg_cpu, 188 if (buf->dmas[i].sg_cpu)
162 buf->sg_dma); 189 dma_free_coherent(pcdev->dev, buf->dmas[i].sg_size,
163 buf->sg_cpu = NULL; 190 buf->dmas[i].sg_cpu,
191 buf->dmas[i].sg_dma);
192 buf->dmas[i].sg_cpu = NULL;
193 }
164 194
165 buf->vb.state = VIDEOBUF_NEEDS_INIT; 195 buf->vb.state = VIDEOBUF_NEEDS_INIT;
166} 196}
167 197
198static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
199 struct pxa_buffer *buf,
200 struct videobuf_dmabuf *dma, int channel,
201 int sglen, int sg_start, int cibr,
202 unsigned int size)
203{
204 struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
205 int i;
206
207 if (pxa_dma->sg_cpu)
208 dma_free_coherent(pcdev->dev, pxa_dma->sg_size,
209 pxa_dma->sg_cpu, pxa_dma->sg_dma);
210
211 pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
212 pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size,
213 &pxa_dma->sg_dma, GFP_KERNEL);
214 if (!pxa_dma->sg_cpu)
215 return -ENOMEM;
216
217 pxa_dma->sglen = sglen;
218
219 for (i = 0; i < sglen; i++) {
220 int sg_i = sg_start + i;
221 struct scatterlist *sg = dma->sglist;
222 unsigned int dma_len = sg_dma_len(&sg[sg_i]), xfer_len;
223
224 pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
225 pxa_dma->sg_cpu[i].dtadr = sg_dma_address(&sg[sg_i]);
226
227 /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
228 xfer_len = (min(dma_len, size) + 7) & ~7;
229
230 pxa_dma->sg_cpu[i].dcmd =
231 DCMD_FLOWSRC | DCMD_BURST8 | DCMD_INCTRGADDR | xfer_len;
232 size -= dma_len;
233 pxa_dma->sg_cpu[i].ddadr =
234 pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
235 }
236
237 pxa_dma->sg_cpu[sglen - 1].ddadr = DDADR_STOP;
238 pxa_dma->sg_cpu[sglen - 1].dcmd |= DCMD_ENDIRQEN;
239
240 return 0;
241}
242
168static int pxa_videobuf_prepare(struct videobuf_queue *vq, 243static int pxa_videobuf_prepare(struct videobuf_queue *vq,
169 struct videobuf_buffer *vb, enum v4l2_field field) 244 struct videobuf_buffer *vb, enum v4l2_field field)
170{ 245{
@@ -173,7 +248,9 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
173 to_soc_camera_host(icd->dev.parent); 248 to_soc_camera_host(icd->dev.parent);
174 struct pxa_camera_dev *pcdev = ici->priv; 249 struct pxa_camera_dev *pcdev = ici->priv;
175 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 250 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
176 int i, ret; 251 int ret;
252 int sglen_y, sglen_yu = 0, sglen_u = 0, sglen_v = 0;
253 int size_y, size_u = 0, size_v = 0;
177 254
178 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 255 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
179 vb, vb->baddr, vb->bsize); 256 vb, vb->baddr, vb->bsize);
@@ -218,49 +295,64 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
218 if (ret) 295 if (ret)
219 goto fail; 296 goto fail;
220 297
221 if (buf->sg_cpu) 298 if (buf->fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
222 dma_free_coherent(pcdev->dev, buf->sg_size, buf->sg_cpu, 299 /* FIXME the calculations should be more precise */
223 buf->sg_dma); 300 sglen_y = dma->sglen / 2;
301 sglen_u = sglen_v = dma->sglen / 4 + 1;
302 sglen_yu = sglen_y + sglen_u;
303 size_y = size / 2;
304 size_u = size_v = size / 4;
305 } else {
306 sglen_y = dma->sglen;
307 size_y = size;
308 }
309
310 /* init DMA for Y channel */
311 ret = pxa_init_dma_channel(pcdev, buf, dma, 0, sglen_y,
312 0, 0x28, size_y);
224 313
225 buf->sg_size = (dma->sglen + 1) * sizeof(struct pxa_dma_desc); 314 if (ret) {
226 buf->sg_cpu = dma_alloc_coherent(pcdev->dev, buf->sg_size, 315 dev_err(pcdev->dev,
227 &buf->sg_dma, GFP_KERNEL); 316 "DMA initialization for Y/RGB failed\n");
228 if (!buf->sg_cpu) {
229 ret = -ENOMEM;
230 goto fail; 317 goto fail;
231 } 318 }
232 319
233 dev_dbg(&icd->dev, "nents=%d size: %d sg=0x%p\n", 320 if (buf->fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
234 dma->sglen, size, dma->sglist); 321 /* init DMA for U channel */
235 for (i = 0; i < dma->sglen; i++) { 322 ret = pxa_init_dma_channel(pcdev, buf, dma, 1, sglen_u,
236 struct scatterlist *sg = dma->sglist; 323 sglen_y, 0x30, size_u);
237 unsigned int dma_len = sg_dma_len(&sg[i]), xfer_len; 324 if (ret) {
238 325 dev_err(pcdev->dev,
239 /* CIBR0 */ 326 "DMA initialization for U failed\n");
240 buf->sg_cpu[i].dsadr = pcdev->res->start + 0x28; 327 goto fail_u;
241 buf->sg_cpu[i].dtadr = sg_dma_address(&sg[i]); 328 }
242 /* PXA270 Developer's Manual 27.4.4.1: 329
243 * round up to 8 bytes */ 330 /* init DMA for V channel */
244 xfer_len = (min(dma_len, size) + 7) & ~7; 331 ret = pxa_init_dma_channel(pcdev, buf, dma, 2, sglen_v,
245 if (xfer_len & 7) 332 sglen_yu, 0x38, size_v);
246 dev_err(&icd->dev, "Unaligned buffer: " 333 if (ret) {
247 "dma_len %u, size %u\n", dma_len, size); 334 dev_err(pcdev->dev,
248 buf->sg_cpu[i].dcmd = DCMD_FLOWSRC | DCMD_BURST8 | 335 "DMA initialization for V failed\n");
249 DCMD_INCTRGADDR | xfer_len; 336 goto fail_v;
250 size -= dma_len; 337 }
251 buf->sg_cpu[i].ddadr = buf->sg_dma + (i + 1) *
252 sizeof(struct pxa_dma_desc);
253 } 338 }
254 buf->sg_cpu[dma->sglen - 1].ddadr = DDADR_STOP;
255 buf->sg_cpu[dma->sglen - 1].dcmd |= DCMD_ENDIRQEN;
256 339
257 vb->state = VIDEOBUF_PREPARED; 340 vb->state = VIDEOBUF_PREPARED;
258 } 341 }
259 342
260 buf->inwork = 0; 343 buf->inwork = 0;
344 buf->active_dma = DMA_Y;
345 if (buf->fmt->fourcc == V4L2_PIX_FMT_YUV422P)
346 buf->active_dma |= DMA_U | DMA_V;
261 347
262 return 0; 348 return 0;
263 349
350fail_v:
351 dma_free_coherent(pcdev->dev, buf->dmas[1].sg_size,
352 buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
353fail_u:
354 dma_free_coherent(pcdev->dev, buf->dmas[0].sg_size,
355 buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
264fail: 356fail:
265 free_buffer(vq, buf); 357 free_buffer(vq, buf);
266out: 358out:
@@ -277,8 +369,6 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
277 struct pxa_camera_dev *pcdev = ici->priv; 369 struct pxa_camera_dev *pcdev = ici->priv;
278 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 370 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
279 struct pxa_buffer *active; 371 struct pxa_buffer *active;
280 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
281 int nents = dma->sglen;
282 unsigned long flags; 372 unsigned long flags;
283 373
284 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 374 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
@@ -292,59 +382,86 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
292 382
293 if (!active) { 383 if (!active) {
294 CIFR |= CIFR_RESET_F; 384 CIFR |= CIFR_RESET_F;
295 DDADR(pcdev->dma_chan_y) = buf->sg_dma; 385 DDADR(pcdev->dma_chans[0]) = buf->dmas[0].sg_dma;
296 DCSR(pcdev->dma_chan_y) = DCSR_RUN; 386 DCSR(pcdev->dma_chans[0]) = DCSR_RUN;
387
388 if (buf->fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
389 DDADR(pcdev->dma_chans[1]) = buf->dmas[1].sg_dma;
390 DCSR(pcdev->dma_chans[1]) = DCSR_RUN;
391
392 DDADR(pcdev->dma_chans[2]) = buf->dmas[2].sg_dma;
393 DCSR(pcdev->dma_chans[2]) = DCSR_RUN;
394 }
395
297 pcdev->active = buf; 396 pcdev->active = buf;
298 CICR0 |= CICR0_ENB; 397 CICR0 |= CICR0_ENB;
299 } else { 398 } else {
300 struct videobuf_dmabuf *active_dma = 399 struct pxa_cam_dma *buf_dma;
301 videobuf_to_dma(&active->vb); 400 struct pxa_cam_dma *act_dma;
302 /* Stop DMA engine */ 401 int channels = 1;
303 DCSR(pcdev->dma_chan_y) = 0; 402 int nents;
304 403 int i;
305 /* Add the descriptors we just initialized to the currently 404
306 * running chain 405 if (buf->fmt->fourcc == V4L2_PIX_FMT_YUV422P)
307 */ 406 channels = 3;
308 active->sg_cpu[active_dma->sglen - 1].ddadr = buf->sg_dma; 407
309 408 for (i = 0; i < channels; i++) {
310 /* Setup a dummy descriptor with the DMA engines current 409 buf_dma = &buf->dmas[i];
311 * state 410 act_dma = &active->dmas[i];
312 */ 411 nents = buf_dma->sglen;
313 /* CIBR0 */ 412
314 buf->sg_cpu[nents].dsadr = pcdev->res->start + 0x28; 413 /* Stop DMA engine */
315 buf->sg_cpu[nents].dtadr = DTADR(pcdev->dma_chan_y); 414 DCSR(pcdev->dma_chans[i]) = 0;
316 buf->sg_cpu[nents].dcmd = DCMD(pcdev->dma_chan_y); 415
317 416 /* Add the descriptors we just initialized to
318 if (DDADR(pcdev->dma_chan_y) == DDADR_STOP) { 417 the currently running chain */
319 /* The DMA engine is on the last descriptor, set the 418 act_dma->sg_cpu[act_dma->sglen - 1].ddadr =
320 * next descriptors address to the descriptors 419 buf_dma->sg_dma;
321 * we just initialized 420
421 /* Setup a dummy descriptor with the DMA engines current
422 * state
322 */ 423 */
323 buf->sg_cpu[nents].ddadr = buf->sg_dma; 424 buf_dma->sg_cpu[nents].dsadr =
324 } else { 425 pcdev->res->start + 0x28 + i*8; /* CIBRx */
325 buf->sg_cpu[nents].ddadr = DDADR(pcdev->dma_chan_y); 426 buf_dma->sg_cpu[nents].dtadr =
427 DTADR(pcdev->dma_chans[i]);
428 buf_dma->sg_cpu[nents].dcmd =
429 DCMD(pcdev->dma_chans[i]);
430
431 if (DDADR(pcdev->dma_chans[i]) == DDADR_STOP) {
432 /* The DMA engine is on the last
433 descriptor, set the next descriptors
434 address to the descriptors we just
435 initialized */
436 buf_dma->sg_cpu[nents].ddadr = buf_dma->sg_dma;
437 } else {
438 buf_dma->sg_cpu[nents].ddadr =
439 DDADR(pcdev->dma_chans[i]);
440 }
441
442 /* The next descriptor is the dummy descriptor */
443 DDADR(pcdev->dma_chans[i]) = buf_dma->sg_dma + nents *
444 sizeof(struct pxa_dma_desc);
445
446 DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
326 } 447 }
327
328 /* The next descriptor is the dummy descriptor */
329 DDADR(pcdev->dma_chan_y) = buf->sg_dma + nents *
330 sizeof(struct pxa_dma_desc);
331
332#ifdef DEBUG 448#ifdef DEBUG
333 if (CISR & CISR_IFO_0) { 449 if (CISR & (CISR_IFO_0 | CISR_IFO_1 | CISR_IFO_2)) {
334 dev_warn(pcdev->dev, "FIFO overrun\n"); 450 dev_warn(pcdev->dev, "FIFO overrun\n");
335 DDADR(pcdev->dma_chan_y) = pcdev->active->sg_dma; 451 for (i = 0; i < channels; i++)
452 DDADR(pcdev->dma_chans[i]) =
453 pcdev->active->dmas[i].sg_dma;
336 454
337 CICR0 &= ~CICR0_ENB; 455 CICR0 &= ~CICR0_ENB;
338 CIFR |= CIFR_RESET_F; 456 CIFR |= CIFR_RESET_F;
339 DCSR(pcdev->dma_chan_y) = DCSR_RUN; 457 for (i = 0; i < channels; i++)
458 DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
340 CICR0 |= CICR0_ENB; 459 CICR0 |= CICR0_ENB;
341 } else 460 }
342#endif 461#endif
343 DCSR(pcdev->dma_chan_y) = DCSR_RUN;
344 } 462 }
345 463
346 spin_unlock_irqrestore(&pcdev->lock, flags); 464 spin_unlock_irqrestore(&pcdev->lock, flags);
347
348} 465}
349 466
350static void pxa_videobuf_release(struct videobuf_queue *vq, 467static void pxa_videobuf_release(struct videobuf_queue *vq,
@@ -376,9 +493,33 @@ static void pxa_videobuf_release(struct videobuf_queue *vq,
376 free_buffer(vq, buf); 493 free_buffer(vq, buf);
377} 494}
378 495
379static void pxa_camera_dma_irq_y(int channel, void *data) 496static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
497 struct videobuf_buffer *vb,
498 struct pxa_buffer *buf)
499{
500 /* _init is used to debug races, see comment in pxa_camera_reqbufs() */
501 list_del_init(&vb->queue);
502 vb->state = VIDEOBUF_DONE;
503 do_gettimeofday(&vb->ts);
504 vb->field_count++;
505 wake_up(&vb->done);
506
507 if (list_empty(&pcdev->capture)) {
508 pcdev->active = NULL;
509 DCSR(pcdev->dma_chans[0]) = 0;
510 DCSR(pcdev->dma_chans[1]) = 0;
511 DCSR(pcdev->dma_chans[2]) = 0;
512 CICR0 &= ~CICR0_ENB;
513 return;
514 }
515
516 pcdev->active = list_entry(pcdev->capture.next,
517 struct pxa_buffer, vb.queue);
518}
519
520static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
521 enum pxa_camera_active_dma act_dma)
380{ 522{
381 struct pxa_camera_dev *pcdev = data;
382 struct pxa_buffer *buf; 523 struct pxa_buffer *buf;
383 unsigned long flags; 524 unsigned long flags;
384 unsigned int status; 525 unsigned int status;
@@ -386,8 +527,8 @@ static void pxa_camera_dma_irq_y(int channel, void *data)
386 527
387 spin_lock_irqsave(&pcdev->lock, flags); 528 spin_lock_irqsave(&pcdev->lock, flags);
388 529
389 status = DCSR(pcdev->dma_chan_y); 530 status = DCSR(channel);
390 DCSR(pcdev->dma_chan_y) = status; 531 DCSR(channel) = status | DCSR_ENDINTR;
391 532
392 if (status & DCSR_BUSERR) { 533 if (status & DCSR_BUSERR) {
393 dev_err(pcdev->dev, "DMA Bus Error IRQ!\n"); 534 dev_err(pcdev->dev, "DMA Bus Error IRQ!\n");
@@ -411,27 +552,32 @@ static void pxa_camera_dma_irq_y(int channel, void *data)
411 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 552 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
412 vb, vb->baddr, vb->bsize); 553 vb, vb->baddr, vb->bsize);
413 554
414 /* _init is used to debug races, see comment in pxa_camera_reqbufs() */ 555 buf->active_dma &= ~act_dma;
415 list_del_init(&vb->queue); 556 if (!buf->active_dma)
416 vb->state = VIDEOBUF_DONE; 557 pxa_camera_wakeup(pcdev, vb, buf);
417 do_gettimeofday(&vb->ts);
418 vb->field_count++;
419 wake_up(&vb->done);
420
421 if (list_empty(&pcdev->capture)) {
422 pcdev->active = NULL;
423 DCSR(pcdev->dma_chan_y) = 0;
424 CICR0 &= ~CICR0_ENB;
425 goto out;
426 }
427
428 pcdev->active = list_entry(pcdev->capture.next, struct pxa_buffer,
429 vb.queue);
430 558
431out: 559out:
432 spin_unlock_irqrestore(&pcdev->lock, flags); 560 spin_unlock_irqrestore(&pcdev->lock, flags);
433} 561}
434 562
563static void pxa_camera_dma_irq_y(int channel, void *data)
564{
565 struct pxa_camera_dev *pcdev = data;
566 pxa_camera_dma_irq(channel, pcdev, DMA_Y);
567}
568
569static void pxa_camera_dma_irq_u(int channel, void *data)
570{
571 struct pxa_camera_dev *pcdev = data;
572 pxa_camera_dma_irq(channel, pcdev, DMA_U);
573}
574
575static void pxa_camera_dma_irq_v(int channel, void *data)
576{
577 struct pxa_camera_dev *pcdev = data;
578 pxa_camera_dma_irq(channel, pcdev, DMA_V);
579}
580
435static struct videobuf_queue_ops pxa_videobuf_ops = { 581static struct videobuf_queue_ops pxa_videobuf_ops = {
436 .buf_setup = pxa_videobuf_setup, 582 .buf_setup = pxa_videobuf_setup,
437 .buf_prepare = pxa_videobuf_prepare, 583 .buf_prepare = pxa_videobuf_prepare,
@@ -525,7 +671,6 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
525 dev_dbg(pcdev->dev, "Camera interrupt status 0x%x\n", status); 671 dev_dbg(pcdev->dev, "Camera interrupt status 0x%x\n", status);
526 672
527 CISR = status; 673 CISR = status;
528
529 return IRQ_HANDLED; 674 return IRQ_HANDLED;
530} 675}
531 676
@@ -571,8 +716,11 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
571 716
572 /* disable capture, disable interrupts */ 717 /* disable capture, disable interrupts */
573 CICR0 = 0x3ff; 718 CICR0 = 0x3ff;
719
574 /* Stop DMA engine */ 720 /* Stop DMA engine */
575 DCSR(pcdev->dma_chan_y) = 0; 721 DCSR(pcdev->dma_chans[0]) = 0;
722 DCSR(pcdev->dma_chans[1]) = 0;
723 DCSR(pcdev->dma_chans[2]) = 0;
576 724
577 icd->ops->release(icd); 725 icd->ops->release(icd);
578 726
@@ -625,7 +773,7 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
625 to_soc_camera_host(icd->dev.parent); 773 to_soc_camera_host(icd->dev.parent);
626 struct pxa_camera_dev *pcdev = ici->priv; 774 struct pxa_camera_dev *pcdev = ici->priv;
627 unsigned long dw, bpp, bus_flags, camera_flags, common_flags; 775 unsigned long dw, bpp, bus_flags, camera_flags, common_flags;
628 u32 cicr0, cicr4 = 0; 776 u32 cicr0, cicr1, cicr4 = 0;
629 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags); 777 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
630 778
631 if (ret < 0) 779 if (ret < 0)
@@ -702,7 +850,25 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
702 cicr0 = CICR0; 850 cicr0 = CICR0;
703 if (cicr0 & CICR0_ENB) 851 if (cicr0 & CICR0_ENB)
704 CICR0 = cicr0 & ~CICR0_ENB; 852 CICR0 = cicr0 & ~CICR0_ENB;
705 CICR1 = CICR1_PPL_VAL(icd->width - 1) | bpp | dw; 853
854 cicr1 = CICR1_PPL_VAL(icd->width - 1) | bpp | dw;
855
856 switch (pixfmt) {
857 case V4L2_PIX_FMT_YUV422P:
858 cicr1 |= CICR1_YCBCR_F;
859 case V4L2_PIX_FMT_YUYV:
860 cicr1 |= CICR1_COLOR_SP_VAL(2);
861 break;
862 case V4L2_PIX_FMT_RGB555:
863 cicr1 |= CICR1_RGB_BPP_VAL(1) | CICR1_RGBT_CONV_VAL(2) |
864 CICR1_TBIT | CICR1_COLOR_SP_VAL(1);
865 break;
866 case V4L2_PIX_FMT_RGB565:
867 cicr1 |= CICR1_COLOR_SP_VAL(1) | CICR1_RGB_BPP_VAL(2);
868 break;
869 }
870
871 CICR1 = cicr1;
706 CICR2 = 0; 872 CICR2 = 0;
707 CICR3 = CICR3_LPF_VAL(icd->height - 1) | 873 CICR3 = CICR3_LPF_VAL(icd->height - 1) |
708 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); 874 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top));
@@ -905,16 +1071,36 @@ static int pxa_camera_probe(struct platform_device *pdev)
905 pcdev->dev = &pdev->dev; 1071 pcdev->dev = &pdev->dev;
906 1072
907 /* request dma */ 1073 /* request dma */
908 pcdev->dma_chan_y = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, 1074 pcdev->dma_chans[0] = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
909 pxa_camera_dma_irq_y, pcdev); 1075 pxa_camera_dma_irq_y, pcdev);
910 if (pcdev->dma_chan_y < 0) { 1076 if (pcdev->dma_chans[0] < 0) {
911 dev_err(pcdev->dev, "Can't request DMA for Y\n"); 1077 dev_err(pcdev->dev, "Can't request DMA for Y\n");
912 err = -ENOMEM; 1078 err = -ENOMEM;
913 goto exit_iounmap; 1079 goto exit_iounmap;
914 } 1080 }
915 dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chan_y); 1081 dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
1082
1083 pcdev->dma_chans[1] = pxa_request_dma("CI_U", DMA_PRIO_HIGH,
1084 pxa_camera_dma_irq_u, pcdev);
1085 if (pcdev->dma_chans[1] < 0) {
1086 dev_err(pcdev->dev, "Can't request DMA for U\n");
1087 err = -ENOMEM;
1088 goto exit_free_dma_y;
1089 }
1090 dev_dbg(pcdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
1091
1092 pcdev->dma_chans[2] = pxa_request_dma("CI_V", DMA_PRIO_HIGH,
1093 pxa_camera_dma_irq_v, pcdev);
1094 if (pcdev->dma_chans[0] < 0) {
1095 dev_err(pcdev->dev, "Can't request DMA for V\n");
1096 err = -ENOMEM;
1097 goto exit_free_dma_u;
1098 }
1099 dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
916 1100
917 DRCMR68 = pcdev->dma_chan_y | DRCMR_MAPVLD; 1101 DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD;
1102 DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD;
1103 DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD;
918 1104
919 /* request irq */ 1105 /* request irq */
920 err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME, 1106 err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME,
@@ -936,7 +1122,11 @@ static int pxa_camera_probe(struct platform_device *pdev)
936exit_free_irq: 1122exit_free_irq:
937 free_irq(pcdev->irq, pcdev); 1123 free_irq(pcdev->irq, pcdev);
938exit_free_dma: 1124exit_free_dma:
939 pxa_free_dma(pcdev->dma_chan_y); 1125 pxa_free_dma(pcdev->dma_chans[2]);
1126exit_free_dma_u:
1127 pxa_free_dma(pcdev->dma_chans[1]);
1128exit_free_dma_y:
1129 pxa_free_dma(pcdev->dma_chans[0]);
940exit_iounmap: 1130exit_iounmap:
941 iounmap(base); 1131 iounmap(base);
942exit_release: 1132exit_release:
@@ -956,7 +1146,9 @@ static int __devexit pxa_camera_remove(struct platform_device *pdev)
956 1146
957 clk_put(pcdev->clk); 1147 clk_put(pcdev->clk);
958 1148
959 pxa_free_dma(pcdev->dma_chan_y); 1149 pxa_free_dma(pcdev->dma_chans[0]);
1150 pxa_free_dma(pcdev->dma_chans[1]);
1151 pxa_free_dma(pcdev->dma_chans[2]);
960 free_irq(pcdev->irq, pcdev); 1152 free_irq(pcdev->irq, pcdev);
961 1153
962 soc_camera_host_unregister(&pxa_soc_camera_host); 1154 soc_camera_host_unregister(&pxa_soc_camera_host);