diff options
author | Jonathan Corbet <corbet@lwn.net> | 2011-07-08 16:50:46 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:55:54 -0400 |
commit | d43dae75cc1140bf27a59aa6d8e8bc7a00f009cc (patch) | |
tree | a85f75a125f335654c5e5d5c7d07d4ad1b165f2a /drivers/media | |
parent | 983587c82189ac6c83fcd7a8914021f49098e473 (diff) |
[media] marvell-cam: core code reorganization
This code shows signs of having been mucked with over the last five years
or so; things were kind of mixed up. This patch reorders functions into a
more rational organization which, with luck, will facilitate making the
buffer modes selectable at configuration time. Code movement only: no
functional changes here.
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/marvell-ccic/mcam-core.c | 824 |
1 files changed, 420 insertions, 404 deletions
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c index af5faa6d7bc0..8a99ec208ae6 100644 --- a/drivers/media/video/marvell-ccic/mcam-core.c +++ b/drivers/media/video/marvell-ccic/mcam-core.c | |||
@@ -157,29 +157,20 @@ static struct mcam_format_struct *mcam_find_format(u32 pixelformat) | |||
157 | } | 157 | } |
158 | 158 | ||
159 | /* | 159 | /* |
160 | * Start over with DMA buffers - dev_lock needed. | 160 | * The default format we use until somebody says otherwise. |
161 | */ | 161 | */ |
162 | static void mcam_reset_buffers(struct mcam_camera *cam) | 162 | static const struct v4l2_pix_format mcam_def_pix_format = { |
163 | { | 163 | .width = VGA_WIDTH, |
164 | int i; | 164 | .height = VGA_HEIGHT, |
165 | .pixelformat = V4L2_PIX_FMT_YUYV, | ||
166 | .field = V4L2_FIELD_NONE, | ||
167 | .bytesperline = VGA_WIDTH*2, | ||
168 | .sizeimage = VGA_WIDTH*VGA_HEIGHT*2, | ||
169 | }; | ||
165 | 170 | ||
166 | cam->next_buf = -1; | 171 | static const enum v4l2_mbus_pixelcode mcam_def_mbus_code = |
167 | for (i = 0; i < cam->nbufs; i++) | 172 | V4L2_MBUS_FMT_YUYV8_2X8; |
168 | clear_bit(i, &cam->flags); | ||
169 | } | ||
170 | 173 | ||
171 | static inline int mcam_needs_config(struct mcam_camera *cam) | ||
172 | { | ||
173 | return test_bit(CF_CONFIG_NEEDED, &cam->flags); | ||
174 | } | ||
175 | |||
176 | static void mcam_set_config_needed(struct mcam_camera *cam, int needed) | ||
177 | { | ||
178 | if (needed) | ||
179 | set_bit(CF_CONFIG_NEEDED, &cam->flags); | ||
180 | else | ||
181 | clear_bit(CF_CONFIG_NEEDED, &cam->flags); | ||
182 | } | ||
183 | 174 | ||
184 | /* | 175 | /* |
185 | * The two-word DMA descriptor format used by the Armada 610 and like. There | 176 | * The two-word DMA descriptor format used by the Armada 610 and like. There |
@@ -210,6 +201,19 @@ static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb) | |||
210 | return container_of(vb, struct mcam_vb_buffer, vb_buf); | 201 | return container_of(vb, struct mcam_vb_buffer, vb_buf); |
211 | } | 202 | } |
212 | 203 | ||
204 | /* | ||
205 | * Hand a completed buffer back to user space. | ||
206 | */ | ||
207 | static void mcam_buffer_done(struct mcam_camera *cam, int frame, | ||
208 | struct vb2_buffer *vbuf) | ||
209 | { | ||
210 | vbuf->v4l2_buf.bytesused = cam->pix_format.sizeimage; | ||
211 | vbuf->v4l2_buf.sequence = cam->buf_seq[frame]; | ||
212 | vb2_set_plane_payload(vbuf, 0, cam->pix_format.sizeimage); | ||
213 | vb2_buffer_done(vbuf, VB2_BUF_STATE_DONE); | ||
214 | } | ||
215 | |||
216 | |||
213 | 217 | ||
214 | /* | 218 | /* |
215 | * Debugging and related. | 219 | * Debugging and related. |
@@ -222,13 +226,111 @@ static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb) | |||
222 | dev_dbg((cam)->dev, fmt, ##arg); | 226 | dev_dbg((cam)->dev, fmt, ##arg); |
223 | 227 | ||
224 | 228 | ||
229 | /* | ||
230 | * Flag manipulation helpers | ||
231 | */ | ||
232 | static void mcam_reset_buffers(struct mcam_camera *cam) | ||
233 | { | ||
234 | int i; | ||
235 | |||
236 | cam->next_buf = -1; | ||
237 | for (i = 0; i < cam->nbufs; i++) | ||
238 | clear_bit(i, &cam->flags); | ||
239 | } | ||
240 | |||
241 | static inline int mcam_needs_config(struct mcam_camera *cam) | ||
242 | { | ||
243 | return test_bit(CF_CONFIG_NEEDED, &cam->flags); | ||
244 | } | ||
245 | |||
246 | static void mcam_set_config_needed(struct mcam_camera *cam, int needed) | ||
247 | { | ||
248 | if (needed) | ||
249 | set_bit(CF_CONFIG_NEEDED, &cam->flags); | ||
250 | else | ||
251 | clear_bit(CF_CONFIG_NEEDED, &cam->flags); | ||
252 | } | ||
253 | |||
254 | /* ------------------------------------------------------------------- */ | ||
255 | /* | ||
256 | * Make the controller start grabbing images. Everything must | ||
257 | * be set up before doing this. | ||
258 | */ | ||
259 | static void mcam_ctlr_start(struct mcam_camera *cam) | ||
260 | { | ||
261 | /* set_bit performs a read, so no other barrier should be | ||
262 | needed here */ | ||
263 | mcam_reg_set_bit(cam, REG_CTRL0, C0_ENABLE); | ||
264 | } | ||
265 | |||
266 | static void mcam_ctlr_stop(struct mcam_camera *cam) | ||
267 | { | ||
268 | mcam_reg_clear_bit(cam, REG_CTRL0, C0_ENABLE); | ||
269 | } | ||
225 | 270 | ||
226 | /* ------------------------------------------------------------------- */ | 271 | /* ------------------------------------------------------------------- */ |
227 | /* | 272 | /* |
228 | * Deal with the controller. | 273 | * Code specific to the vmalloc buffer mode. |
229 | */ | 274 | */ |
230 | 275 | ||
231 | /* | 276 | /* |
277 | * Allocate in-kernel DMA buffers for vmalloc mode. | ||
278 | */ | ||
279 | static int mcam_alloc_dma_bufs(struct mcam_camera *cam, int loadtime) | ||
280 | { | ||
281 | int i; | ||
282 | |||
283 | mcam_set_config_needed(cam, 1); | ||
284 | if (loadtime) | ||
285 | cam->dma_buf_size = dma_buf_size; | ||
286 | else | ||
287 | cam->dma_buf_size = cam->pix_format.sizeimage; | ||
288 | if (n_dma_bufs > 3) | ||
289 | n_dma_bufs = 3; | ||
290 | |||
291 | cam->nbufs = 0; | ||
292 | for (i = 0; i < n_dma_bufs; i++) { | ||
293 | cam->dma_bufs[i] = dma_alloc_coherent(cam->dev, | ||
294 | cam->dma_buf_size, cam->dma_handles + i, | ||
295 | GFP_KERNEL); | ||
296 | if (cam->dma_bufs[i] == NULL) { | ||
297 | cam_warn(cam, "Failed to allocate DMA buffer\n"); | ||
298 | break; | ||
299 | } | ||
300 | (cam->nbufs)++; | ||
301 | } | ||
302 | |||
303 | switch (cam->nbufs) { | ||
304 | case 1: | ||
305 | dma_free_coherent(cam->dev, cam->dma_buf_size, | ||
306 | cam->dma_bufs[0], cam->dma_handles[0]); | ||
307 | cam->nbufs = 0; | ||
308 | case 0: | ||
309 | cam_err(cam, "Insufficient DMA buffers, cannot operate\n"); | ||
310 | return -ENOMEM; | ||
311 | |||
312 | case 2: | ||
313 | if (n_dma_bufs > 2) | ||
314 | cam_warn(cam, "Will limp along with only 2 buffers\n"); | ||
315 | break; | ||
316 | } | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static void mcam_free_dma_bufs(struct mcam_camera *cam) | ||
321 | { | ||
322 | int i; | ||
323 | |||
324 | for (i = 0; i < cam->nbufs; i++) { | ||
325 | dma_free_coherent(cam->dev, cam->dma_buf_size, | ||
326 | cam->dma_bufs[i], cam->dma_handles[i]); | ||
327 | cam->dma_bufs[i] = NULL; | ||
328 | } | ||
329 | cam->nbufs = 0; | ||
330 | } | ||
331 | |||
332 | |||
333 | /* | ||
232 | * Set up DMA buffers when operating in vmalloc mode | 334 | * Set up DMA buffers when operating in vmalloc mode |
233 | */ | 335 | */ |
234 | static void mcam_ctlr_dma_vmalloc(struct mcam_camera *cam) | 336 | static void mcam_ctlr_dma_vmalloc(struct mcam_camera *cam) |
@@ -251,6 +353,52 @@ static void mcam_ctlr_dma_vmalloc(struct mcam_camera *cam) | |||
251 | } | 353 | } |
252 | 354 | ||
253 | /* | 355 | /* |
356 | * Copy data out to user space in the vmalloc case | ||
357 | */ | ||
358 | static void mcam_frame_tasklet(unsigned long data) | ||
359 | { | ||
360 | struct mcam_camera *cam = (struct mcam_camera *) data; | ||
361 | int i; | ||
362 | unsigned long flags; | ||
363 | struct mcam_vb_buffer *buf; | ||
364 | |||
365 | spin_lock_irqsave(&cam->dev_lock, flags); | ||
366 | for (i = 0; i < cam->nbufs; i++) { | ||
367 | int bufno = cam->next_buf; | ||
368 | |||
369 | if (cam->state != S_STREAMING || bufno < 0) | ||
370 | break; /* I/O got stopped */ | ||
371 | if (++(cam->next_buf) >= cam->nbufs) | ||
372 | cam->next_buf = 0; | ||
373 | if (!test_bit(bufno, &cam->flags)) | ||
374 | continue; | ||
375 | if (list_empty(&cam->buffers)) { | ||
376 | singles++; | ||
377 | break; /* Leave it valid, hope for better later */ | ||
378 | } | ||
379 | delivered++; | ||
380 | clear_bit(bufno, &cam->flags); | ||
381 | buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, | ||
382 | queue); | ||
383 | list_del_init(&buf->queue); | ||
384 | /* | ||
385 | * Drop the lock during the big copy. This *should* be safe... | ||
386 | */ | ||
387 | spin_unlock_irqrestore(&cam->dev_lock, flags); | ||
388 | memcpy(vb2_plane_vaddr(&buf->vb_buf, 0), cam->dma_bufs[bufno], | ||
389 | cam->pix_format.sizeimage); | ||
390 | mcam_buffer_done(cam, bufno, &buf->vb_buf); | ||
391 | spin_lock_irqsave(&cam->dev_lock, flags); | ||
392 | } | ||
393 | spin_unlock_irqrestore(&cam->dev_lock, flags); | ||
394 | } | ||
395 | |||
396 | |||
397 | /* ---------------------------------------------------------------------- */ | ||
398 | /* | ||
399 | * DMA-contiguous code. | ||
400 | */ | ||
401 | /* | ||
254 | * Set up a contiguous buffer for the given frame. Here also is where | 402 | * Set up a contiguous buffer for the given frame. Here also is where |
255 | * the underrun strategy is set: if there is no buffer available, reuse | 403 | * the underrun strategy is set: if there is no buffer available, reuse |
256 | * the buffer from the other BAR and set the CF_SINGLE_BUFFER flag to | 404 | * the buffer from the other BAR and set the CF_SINGLE_BUFFER flag to |
@@ -295,6 +443,26 @@ static void mcam_ctlr_dma_contig(struct mcam_camera *cam) | |||
295 | mcam_set_contig_buffer(cam, 1); | 443 | mcam_set_contig_buffer(cam, 1); |
296 | } | 444 | } |
297 | 445 | ||
446 | /* | ||
447 | * Frame completion handling. | ||
448 | */ | ||
449 | static void mcam_dma_contig_done(struct mcam_camera *cam, int frame) | ||
450 | { | ||
451 | struct mcam_vb_buffer *buf = cam->vb_bufs[frame]; | ||
452 | |||
453 | if (!test_bit(CF_SINGLE_BUFFER, &cam->flags)) { | ||
454 | delivered++; | ||
455 | mcam_buffer_done(cam, frame, &buf->vb_buf); | ||
456 | } | ||
457 | mcam_set_contig_buffer(cam, frame); | ||
458 | } | ||
459 | |||
460 | |||
461 | |||
462 | /* ---------------------------------------------------------------------- */ | ||
463 | /* | ||
464 | * Scatter/gather-specific code. | ||
465 | */ | ||
298 | 466 | ||
299 | /* | 467 | /* |
300 | * Set up the next buffer for S/G I/O; caller should be sure that | 468 | * Set up the next buffer for S/G I/O; caller should be sure that |
@@ -325,8 +493,74 @@ static void mcam_ctlr_dma_sg(struct mcam_camera *cam) | |||
325 | cam->nbufs = 3; | 493 | cam->nbufs = 3; |
326 | } | 494 | } |
327 | 495 | ||
496 | |||
497 | /* | ||
498 | * Frame completion with S/G is trickier. We can't muck with | ||
499 | * a descriptor chain on the fly, since the controller buffers it | ||
500 | * internally. So we have to actually stop and restart; Marvell | ||
501 | * says this is the way to do it. | ||
502 | * | ||
503 | * Of course, stopping is easier said than done; experience shows | ||
504 | * that the controller can start a frame *after* C0_ENABLE has been | ||
505 | * cleared. So when running in S/G mode, the controller is "stopped" | ||
506 | * on receipt of the start-of-frame interrupt. That means we can | ||
507 | * safely change the DMA descriptor array here and restart things | ||
508 | * (assuming there's another buffer waiting to go). | ||
509 | */ | ||
510 | static void mcam_dma_sg_done(struct mcam_camera *cam, int frame) | ||
511 | { | ||
512 | struct mcam_vb_buffer *buf = cam->vb_bufs[0]; | ||
513 | |||
514 | /* | ||
515 | * Very Bad Not Good Things happen if you don't clear | ||
516 | * C1_DESC_ENA before making any descriptor changes. | ||
517 | */ | ||
518 | mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA); | ||
519 | /* | ||
520 | * If we have another buffer available, put it in and | ||
521 | * restart the engine. | ||
522 | */ | ||
523 | if (!list_empty(&cam->buffers)) { | ||
524 | mcam_sg_next_buffer(cam); | ||
525 | mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA); | ||
526 | mcam_ctlr_start(cam); | ||
527 | /* | ||
528 | * Otherwise set CF_SG_RESTART and the controller will | ||
529 | * be restarted once another buffer shows up. | ||
530 | */ | ||
531 | } else { | ||
532 | set_bit(CF_SG_RESTART, &cam->flags); | ||
533 | singles++; | ||
534 | } | ||
535 | /* | ||
536 | * Now we can give the completed frame back to user space. | ||
537 | */ | ||
538 | delivered++; | ||
539 | mcam_buffer_done(cam, frame, &buf->vb_buf); | ||
540 | } | ||
541 | |||
542 | |||
543 | /* | ||
544 | * Scatter/gather mode requires stopping the controller between | ||
545 | * frames so we can put in a new DMA descriptor array. If no new | ||
546 | * buffer exists at frame completion, the controller is left stopped; | ||
547 | * this function is charged with gettig things going again. | ||
548 | */ | ||
549 | static void mcam_sg_restart(struct mcam_camera *cam) | ||
550 | { | ||
551 | mcam_ctlr_dma_sg(cam); | ||
552 | mcam_ctlr_start(cam); | ||
553 | clear_bit(CF_SG_RESTART, &cam->flags); | ||
554 | } | ||
555 | |||
556 | |||
557 | /* ---------------------------------------------------------------------- */ | ||
328 | /* | 558 | /* |
329 | * Image format setup, independent of DMA scheme. | 559 | * Buffer-mode-independent controller code. |
560 | */ | ||
561 | |||
562 | /* | ||
563 | * Image format setup | ||
330 | */ | 564 | */ |
331 | static void mcam_ctlr_image(struct mcam_camera *cam) | 565 | static void mcam_ctlr_image(struct mcam_camera *cam) |
332 | { | 566 | { |
@@ -417,34 +651,7 @@ static void mcam_ctlr_irq_disable(struct mcam_camera *cam) | |||
417 | mcam_reg_clear_bit(cam, REG_IRQMASK, FRAMEIRQS); | 651 | mcam_reg_clear_bit(cam, REG_IRQMASK, FRAMEIRQS); |
418 | } | 652 | } |
419 | 653 | ||
420 | /* | ||
421 | * Make the controller start grabbing images. Everything must | ||
422 | * be set up before doing this. | ||
423 | */ | ||
424 | static void mcam_ctlr_start(struct mcam_camera *cam) | ||
425 | { | ||
426 | /* set_bit performs a read, so no other barrier should be | ||
427 | needed here */ | ||
428 | mcam_reg_set_bit(cam, REG_CTRL0, C0_ENABLE); | ||
429 | } | ||
430 | |||
431 | static void mcam_ctlr_stop(struct mcam_camera *cam) | ||
432 | { | ||
433 | mcam_reg_clear_bit(cam, REG_CTRL0, C0_ENABLE); | ||
434 | } | ||
435 | 654 | ||
436 | /* | ||
437 | * Scatter/gather mode requires stopping the controller between | ||
438 | * frames so we can put in a new DMA descriptor array. If no new | ||
439 | * buffer exists at frame completion, the controller is left stopped; | ||
440 | * this function is charged with gettig things going again. | ||
441 | */ | ||
442 | static void mcam_sg_restart(struct mcam_camera *cam) | ||
443 | { | ||
444 | mcam_ctlr_dma_sg(cam); | ||
445 | mcam_ctlr_start(cam); | ||
446 | clear_bit(CF_SG_RESTART, &cam->flags); | ||
447 | } | ||
448 | 655 | ||
449 | static void mcam_ctlr_init(struct mcam_camera *cam) | 656 | static void mcam_ctlr_init(struct mcam_camera *cam) |
450 | { | 657 | { |
@@ -603,75 +810,6 @@ static int mcam_cam_configure(struct mcam_camera *cam) | |||
603 | return ret; | 810 | return ret; |
604 | } | 811 | } |
605 | 812 | ||
606 | /* -------------------------------------------------------------------- */ | ||
607 | /* | ||
608 | * DMA buffer management. These functions need s_mutex held. | ||
609 | */ | ||
610 | |||
611 | /* | ||
612 | * Allocate in-kernel DMA buffers for vmalloc mode. | ||
613 | */ | ||
614 | static int mcam_alloc_dma_bufs(struct mcam_camera *cam, int loadtime) | ||
615 | { | ||
616 | int i; | ||
617 | |||
618 | mcam_set_config_needed(cam, 1); | ||
619 | if (loadtime) | ||
620 | cam->dma_buf_size = dma_buf_size; | ||
621 | else | ||
622 | cam->dma_buf_size = cam->pix_format.sizeimage; | ||
623 | if (n_dma_bufs > 3) | ||
624 | n_dma_bufs = 3; | ||
625 | |||
626 | cam->nbufs = 0; | ||
627 | for (i = 0; i < n_dma_bufs; i++) { | ||
628 | cam->dma_bufs[i] = dma_alloc_coherent(cam->dev, | ||
629 | cam->dma_buf_size, cam->dma_handles + i, | ||
630 | GFP_KERNEL); | ||
631 | if (cam->dma_bufs[i] == NULL) { | ||
632 | cam_warn(cam, "Failed to allocate DMA buffer\n"); | ||
633 | break; | ||
634 | } | ||
635 | (cam->nbufs)++; | ||
636 | } | ||
637 | |||
638 | switch (cam->nbufs) { | ||
639 | case 1: | ||
640 | dma_free_coherent(cam->dev, cam->dma_buf_size, | ||
641 | cam->dma_bufs[0], cam->dma_handles[0]); | ||
642 | cam->nbufs = 0; | ||
643 | case 0: | ||
644 | cam_err(cam, "Insufficient DMA buffers, cannot operate\n"); | ||
645 | return -ENOMEM; | ||
646 | |||
647 | case 2: | ||
648 | if (n_dma_bufs > 2) | ||
649 | cam_warn(cam, "Will limp along with only 2 buffers\n"); | ||
650 | break; | ||
651 | } | ||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static void mcam_free_dma_bufs(struct mcam_camera *cam) | ||
656 | { | ||
657 | int i; | ||
658 | |||
659 | for (i = 0; i < cam->nbufs; i++) { | ||
660 | dma_free_coherent(cam->dev, cam->dma_buf_size, | ||
661 | cam->dma_bufs[i], cam->dma_handles[i]); | ||
662 | cam->dma_bufs[i] = NULL; | ||
663 | } | ||
664 | cam->nbufs = 0; | ||
665 | } | ||
666 | |||
667 | |||
668 | |||
669 | /* ----------------------------------------------------------------------- */ | ||
670 | /* | ||
671 | * Here starts the V4L2 interface code. | ||
672 | */ | ||
673 | |||
674 | |||
675 | /* | 813 | /* |
676 | * Get everything ready, and start grabbing frames. | 814 | * Get everything ready, and start grabbing frames. |
677 | */ | 815 | */ |
@@ -728,44 +866,6 @@ static int mcam_vb_queue_setup(struct vb2_queue *vq, unsigned int *nbufs, | |||
728 | return 0; | 866 | return 0; |
729 | } | 867 | } |
730 | 868 | ||
731 | /* DMA_sg only */ | ||
732 | static int mcam_vb_sg_buf_init(struct vb2_buffer *vb) | ||
733 | { | ||
734 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | ||
735 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
736 | int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1; | ||
737 | |||
738 | mvb->dma_desc = dma_alloc_coherent(cam->dev, | ||
739 | ndesc * sizeof(struct mcam_dma_desc), | ||
740 | &mvb->dma_desc_pa, GFP_KERNEL); | ||
741 | if (mvb->dma_desc == NULL) { | ||
742 | cam_err(cam, "Unable to get DMA descriptor array\n"); | ||
743 | return -ENOMEM; | ||
744 | } | ||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb) | ||
749 | { | ||
750 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | ||
751 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
752 | struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); | ||
753 | struct mcam_dma_desc *desc = mvb->dma_desc; | ||
754 | struct scatterlist *sg; | ||
755 | int i; | ||
756 | |||
757 | mvb->dma_desc_nent = dma_map_sg(cam->dev, sgd->sglist, sgd->num_pages, | ||
758 | DMA_FROM_DEVICE); | ||
759 | if (mvb->dma_desc_nent <= 0) | ||
760 | return -EIO; /* Not sure what's right here */ | ||
761 | for_each_sg(sgd->sglist, sg, mvb->dma_desc_nent, i) { | ||
762 | desc->dma_addr = sg_dma_address(sg); | ||
763 | desc->segment_len = sg_dma_len(sg); | ||
764 | desc++; | ||
765 | } | ||
766 | return 0; | ||
767 | } | ||
768 | |||
769 | 869 | ||
770 | static void mcam_vb_buf_queue(struct vb2_buffer *vb) | 870 | static void mcam_vb_buf_queue(struct vb2_buffer *vb) |
771 | { | 871 | { |
@@ -785,26 +885,6 @@ static void mcam_vb_buf_queue(struct vb2_buffer *vb) | |||
785 | } | 885 | } |
786 | 886 | ||
787 | 887 | ||
788 | static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb) | ||
789 | { | ||
790 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
791 | struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); | ||
792 | |||
793 | dma_unmap_sg(cam->dev, sgd->sglist, sgd->num_pages, DMA_FROM_DEVICE); | ||
794 | return 0; | ||
795 | } | ||
796 | |||
797 | static void mcam_vb_sg_buf_cleanup(struct vb2_buffer *vb) | ||
798 | { | ||
799 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
800 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | ||
801 | int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1; | ||
802 | |||
803 | dma_free_coherent(cam->dev, ndesc * sizeof(struct mcam_dma_desc), | ||
804 | mvb->dma_desc, mvb->dma_desc_pa); | ||
805 | } | ||
806 | |||
807 | |||
808 | /* | 888 | /* |
809 | * vb2 uses these to release the mutex when waiting in dqbuf. I'm | 889 | * vb2 uses these to release the mutex when waiting in dqbuf. I'm |
810 | * not actually sure we need to do this (I'm not sure that vb2_dqbuf() needs | 890 | * not actually sure we need to do this (I'm not sure that vb2_dqbuf() needs |
@@ -882,8 +962,66 @@ static const struct vb2_ops mcam_vb2_ops = { | |||
882 | }; | 962 | }; |
883 | 963 | ||
884 | /* | 964 | /* |
885 | * Scatter/gather mode complicates things somewhat. | 965 | * Scatter/gather mode uses all of the above functions plus a |
966 | * few extras to deal with DMA mapping. | ||
886 | */ | 967 | */ |
968 | static int mcam_vb_sg_buf_init(struct vb2_buffer *vb) | ||
969 | { | ||
970 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | ||
971 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
972 | int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1; | ||
973 | |||
974 | mvb->dma_desc = dma_alloc_coherent(cam->dev, | ||
975 | ndesc * sizeof(struct mcam_dma_desc), | ||
976 | &mvb->dma_desc_pa, GFP_KERNEL); | ||
977 | if (mvb->dma_desc == NULL) { | ||
978 | cam_err(cam, "Unable to get DMA descriptor array\n"); | ||
979 | return -ENOMEM; | ||
980 | } | ||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb) | ||
985 | { | ||
986 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | ||
987 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
988 | struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); | ||
989 | struct mcam_dma_desc *desc = mvb->dma_desc; | ||
990 | struct scatterlist *sg; | ||
991 | int i; | ||
992 | |||
993 | mvb->dma_desc_nent = dma_map_sg(cam->dev, sgd->sglist, sgd->num_pages, | ||
994 | DMA_FROM_DEVICE); | ||
995 | if (mvb->dma_desc_nent <= 0) | ||
996 | return -EIO; /* Not sure what's right here */ | ||
997 | for_each_sg(sgd->sglist, sg, mvb->dma_desc_nent, i) { | ||
998 | desc->dma_addr = sg_dma_address(sg); | ||
999 | desc->segment_len = sg_dma_len(sg); | ||
1000 | desc++; | ||
1001 | } | ||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb) | ||
1006 | { | ||
1007 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
1008 | struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); | ||
1009 | |||
1010 | dma_unmap_sg(cam->dev, sgd->sglist, sgd->num_pages, DMA_FROM_DEVICE); | ||
1011 | return 0; | ||
1012 | } | ||
1013 | |||
1014 | static void mcam_vb_sg_buf_cleanup(struct vb2_buffer *vb) | ||
1015 | { | ||
1016 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
1017 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | ||
1018 | int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1; | ||
1019 | |||
1020 | dma_free_coherent(cam->dev, ndesc * sizeof(struct mcam_dma_desc), | ||
1021 | mvb->dma_desc, mvb->dma_desc_pa); | ||
1022 | } | ||
1023 | |||
1024 | |||
887 | static const struct vb2_ops mcam_vb2_sg_ops = { | 1025 | static const struct vb2_ops mcam_vb2_sg_ops = { |
888 | .queue_setup = mcam_vb_queue_setup, | 1026 | .queue_setup = mcam_vb_queue_setup, |
889 | .buf_init = mcam_vb_sg_buf_init, | 1027 | .buf_init = mcam_vb_sg_buf_init, |
@@ -934,23 +1072,10 @@ static void mcam_cleanup_vb2(struct mcam_camera *cam) | |||
934 | vb2_dma_contig_cleanup_ctx(cam->vb_alloc_ctx); | 1072 | vb2_dma_contig_cleanup_ctx(cam->vb_alloc_ctx); |
935 | } | 1073 | } |
936 | 1074 | ||
937 | static ssize_t mcam_v4l_read(struct file *filp, | ||
938 | char __user *buffer, size_t len, loff_t *pos) | ||
939 | { | ||
940 | struct mcam_camera *cam = filp->private_data; | ||
941 | int ret; | ||
942 | |||
943 | mutex_lock(&cam->s_mutex); | ||
944 | ret = vb2_read(&cam->vb_queue, buffer, len, pos, | ||
945 | filp->f_flags & O_NONBLOCK); | ||
946 | mutex_unlock(&cam->s_mutex); | ||
947 | return ret; | ||
948 | } | ||
949 | |||
950 | |||
951 | 1075 | ||
1076 | /* ---------------------------------------------------------------------- */ | ||
952 | /* | 1077 | /* |
953 | * Streaming I/O support. | 1078 | * The long list of V4L2 ioctl() operations. |
954 | */ | 1079 | */ |
955 | 1080 | ||
956 | static int mcam_vidioc_streamon(struct file *filp, void *priv, | 1081 | static int mcam_vidioc_streamon(struct file *filp, void *priv, |
@@ -1029,80 +1154,6 @@ static int mcam_vidioc_dqbuf(struct file *filp, void *priv, | |||
1029 | } | 1154 | } |
1030 | 1155 | ||
1031 | 1156 | ||
1032 | static int mcam_v4l_mmap(struct file *filp, struct vm_area_struct *vma) | ||
1033 | { | ||
1034 | struct mcam_camera *cam = filp->private_data; | ||
1035 | int ret; | ||
1036 | |||
1037 | mutex_lock(&cam->s_mutex); | ||
1038 | ret = vb2_mmap(&cam->vb_queue, vma); | ||
1039 | mutex_unlock(&cam->s_mutex); | ||
1040 | return ret; | ||
1041 | } | ||
1042 | |||
1043 | |||
1044 | |||
1045 | static int mcam_v4l_open(struct file *filp) | ||
1046 | { | ||
1047 | struct mcam_camera *cam = video_drvdata(filp); | ||
1048 | int ret = 0; | ||
1049 | |||
1050 | filp->private_data = cam; | ||
1051 | |||
1052 | frames = singles = delivered = 0; | ||
1053 | mutex_lock(&cam->s_mutex); | ||
1054 | if (cam->users == 0) { | ||
1055 | ret = mcam_setup_vb2(cam); | ||
1056 | if (ret) | ||
1057 | goto out; | ||
1058 | mcam_ctlr_power_up(cam); | ||
1059 | __mcam_cam_reset(cam); | ||
1060 | mcam_set_config_needed(cam, 1); | ||
1061 | } | ||
1062 | (cam->users)++; | ||
1063 | out: | ||
1064 | mutex_unlock(&cam->s_mutex); | ||
1065 | return ret; | ||
1066 | } | ||
1067 | |||
1068 | |||
1069 | static int mcam_v4l_release(struct file *filp) | ||
1070 | { | ||
1071 | struct mcam_camera *cam = filp->private_data; | ||
1072 | |||
1073 | cam_err(cam, "Release, %d frames, %d singles, %d delivered\n", frames, | ||
1074 | singles, delivered); | ||
1075 | mutex_lock(&cam->s_mutex); | ||
1076 | (cam->users)--; | ||
1077 | if (filp == cam->owner) { | ||
1078 | mcam_ctlr_stop_dma(cam); | ||
1079 | cam->owner = NULL; | ||
1080 | } | ||
1081 | if (cam->users == 0) { | ||
1082 | mcam_cleanup_vb2(cam); | ||
1083 | mcam_ctlr_power_down(cam); | ||
1084 | if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read) | ||
1085 | mcam_free_dma_bufs(cam); | ||
1086 | } | ||
1087 | mutex_unlock(&cam->s_mutex); | ||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | |||
1092 | |||
1093 | static unsigned int mcam_v4l_poll(struct file *filp, | ||
1094 | struct poll_table_struct *pt) | ||
1095 | { | ||
1096 | struct mcam_camera *cam = filp->private_data; | ||
1097 | int ret; | ||
1098 | |||
1099 | mutex_lock(&cam->s_mutex); | ||
1100 | ret = vb2_poll(&cam->vb_queue, filp, pt); | ||
1101 | mutex_unlock(&cam->s_mutex); | ||
1102 | return ret; | ||
1103 | } | ||
1104 | |||
1105 | |||
1106 | 1157 | ||
1107 | static int mcam_vidioc_queryctrl(struct file *filp, void *priv, | 1158 | static int mcam_vidioc_queryctrl(struct file *filp, void *priv, |
1108 | struct v4l2_queryctrl *qc) | 1159 | struct v4l2_queryctrl *qc) |
@@ -1155,21 +1206,6 @@ static int mcam_vidioc_querycap(struct file *file, void *priv, | |||
1155 | } | 1206 | } |
1156 | 1207 | ||
1157 | 1208 | ||
1158 | /* | ||
1159 | * The default format we use until somebody says otherwise. | ||
1160 | */ | ||
1161 | static const struct v4l2_pix_format mcam_def_pix_format = { | ||
1162 | .width = VGA_WIDTH, | ||
1163 | .height = VGA_HEIGHT, | ||
1164 | .pixelformat = V4L2_PIX_FMT_YUYV, | ||
1165 | .field = V4L2_FIELD_NONE, | ||
1166 | .bytesperline = VGA_WIDTH*2, | ||
1167 | .sizeimage = VGA_WIDTH*VGA_HEIGHT*2, | ||
1168 | }; | ||
1169 | |||
1170 | static const enum v4l2_mbus_pixelcode mcam_def_mbus_code = | ||
1171 | V4L2_MBUS_FMT_YUYV8_2X8; | ||
1172 | |||
1173 | static int mcam_vidioc_enum_fmt_vid_cap(struct file *filp, | 1209 | static int mcam_vidioc_enum_fmt_vid_cap(struct file *filp, |
1174 | void *priv, struct v4l2_fmtdesc *fmt) | 1210 | void *priv, struct v4l2_fmtdesc *fmt) |
1175 | { | 1211 | { |
@@ -1395,21 +1431,6 @@ static int mcam_vidioc_s_register(struct file *file, void *priv, | |||
1395 | } | 1431 | } |
1396 | #endif | 1432 | #endif |
1397 | 1433 | ||
1398 | /* | ||
1399 | * This template device holds all of those v4l2 methods; we | ||
1400 | * clone it for specific real devices. | ||
1401 | */ | ||
1402 | |||
1403 | static const struct v4l2_file_operations mcam_v4l_fops = { | ||
1404 | .owner = THIS_MODULE, | ||
1405 | .open = mcam_v4l_open, | ||
1406 | .release = mcam_v4l_release, | ||
1407 | .read = mcam_v4l_read, | ||
1408 | .poll = mcam_v4l_poll, | ||
1409 | .mmap = mcam_v4l_mmap, | ||
1410 | .unlocked_ioctl = video_ioctl2, | ||
1411 | }; | ||
1412 | |||
1413 | static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { | 1434 | static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { |
1414 | .vidioc_querycap = mcam_vidioc_querycap, | 1435 | .vidioc_querycap = mcam_vidioc_querycap, |
1415 | .vidioc_enum_fmt_vid_cap = mcam_vidioc_enum_fmt_vid_cap, | 1436 | .vidioc_enum_fmt_vid_cap = mcam_vidioc_enum_fmt_vid_cap, |
@@ -1440,133 +1461,126 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = { | |||
1440 | #endif | 1461 | #endif |
1441 | }; | 1462 | }; |
1442 | 1463 | ||
1443 | static struct video_device mcam_v4l_template = { | ||
1444 | .name = "mcam", | ||
1445 | .tvnorms = V4L2_STD_NTSC_M, | ||
1446 | .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ | ||
1447 | |||
1448 | .fops = &mcam_v4l_fops, | ||
1449 | .ioctl_ops = &mcam_v4l_ioctl_ops, | ||
1450 | .release = video_device_release_empty, | ||
1451 | }; | ||
1452 | |||
1453 | /* ---------------------------------------------------------------------- */ | 1464 | /* ---------------------------------------------------------------------- */ |
1454 | /* | 1465 | /* |
1455 | * Interrupt handler stuff | 1466 | * Our various file operations. |
1456 | */ | 1467 | */ |
1468 | static int mcam_v4l_open(struct file *filp) | ||
1469 | { | ||
1470 | struct mcam_camera *cam = video_drvdata(filp); | ||
1471 | int ret = 0; | ||
1457 | 1472 | ||
1473 | filp->private_data = cam; | ||
1458 | 1474 | ||
1459 | static void mcam_buffer_done(struct mcam_camera *cam, int frame, | 1475 | frames = singles = delivered = 0; |
1460 | struct vb2_buffer *vbuf) | 1476 | mutex_lock(&cam->s_mutex); |
1461 | { | 1477 | if (cam->users == 0) { |
1462 | vbuf->v4l2_buf.bytesused = cam->pix_format.sizeimage; | 1478 | ret = mcam_setup_vb2(cam); |
1463 | vbuf->v4l2_buf.sequence = cam->buf_seq[frame]; | 1479 | if (ret) |
1464 | vb2_set_plane_payload(vbuf, 0, cam->pix_format.sizeimage); | 1480 | goto out; |
1465 | vb2_buffer_done(vbuf, VB2_BUF_STATE_DONE); | 1481 | mcam_ctlr_power_up(cam); |
1482 | __mcam_cam_reset(cam); | ||
1483 | mcam_set_config_needed(cam, 1); | ||
1484 | } | ||
1485 | (cam->users)++; | ||
1486 | out: | ||
1487 | mutex_unlock(&cam->s_mutex); | ||
1488 | return ret; | ||
1466 | } | 1489 | } |
1467 | 1490 | ||
1468 | /* | ||
1469 | * Copy data out to user space in the vmalloc case | ||
1470 | */ | ||
1471 | static void mcam_frame_tasklet(unsigned long data) | ||
1472 | { | ||
1473 | struct mcam_camera *cam = (struct mcam_camera *) data; | ||
1474 | int i; | ||
1475 | unsigned long flags; | ||
1476 | struct mcam_vb_buffer *buf; | ||
1477 | 1491 | ||
1478 | spin_lock_irqsave(&cam->dev_lock, flags); | 1492 | static int mcam_v4l_release(struct file *filp) |
1479 | for (i = 0; i < cam->nbufs; i++) { | 1493 | { |
1480 | int bufno = cam->next_buf; | 1494 | struct mcam_camera *cam = filp->private_data; |
1481 | 1495 | ||
1482 | if (cam->state != S_STREAMING || bufno < 0) | 1496 | cam_err(cam, "Release, %d frames, %d singles, %d delivered\n", frames, |
1483 | break; /* I/O got stopped */ | 1497 | singles, delivered); |
1484 | if (++(cam->next_buf) >= cam->nbufs) | 1498 | mutex_lock(&cam->s_mutex); |
1485 | cam->next_buf = 0; | 1499 | (cam->users)--; |
1486 | if (!test_bit(bufno, &cam->flags)) | 1500 | if (filp == cam->owner) { |
1487 | continue; | 1501 | mcam_ctlr_stop_dma(cam); |
1488 | if (list_empty(&cam->buffers)) { | 1502 | cam->owner = NULL; |
1489 | singles++; | ||
1490 | break; /* Leave it valid, hope for better later */ | ||
1491 | } | ||
1492 | delivered++; | ||
1493 | clear_bit(bufno, &cam->flags); | ||
1494 | buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, | ||
1495 | queue); | ||
1496 | list_del_init(&buf->queue); | ||
1497 | /* | ||
1498 | * Drop the lock during the big copy. This *should* be safe... | ||
1499 | */ | ||
1500 | spin_unlock_irqrestore(&cam->dev_lock, flags); | ||
1501 | memcpy(vb2_plane_vaddr(&buf->vb_buf, 0), cam->dma_bufs[bufno], | ||
1502 | cam->pix_format.sizeimage); | ||
1503 | mcam_buffer_done(cam, bufno, &buf->vb_buf); | ||
1504 | spin_lock_irqsave(&cam->dev_lock, flags); | ||
1505 | } | 1503 | } |
1506 | spin_unlock_irqrestore(&cam->dev_lock, flags); | 1504 | if (cam->users == 0) { |
1505 | mcam_cleanup_vb2(cam); | ||
1506 | mcam_ctlr_power_down(cam); | ||
1507 | if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read) | ||
1508 | mcam_free_dma_bufs(cam); | ||
1509 | } | ||
1510 | mutex_unlock(&cam->s_mutex); | ||
1511 | return 0; | ||
1507 | } | 1512 | } |
1508 | 1513 | ||
1509 | /* | 1514 | static ssize_t mcam_v4l_read(struct file *filp, |
1510 | * For direct DMA, mark the buffer ready and set up another one. | 1515 | char __user *buffer, size_t len, loff_t *pos) |
1511 | */ | ||
1512 | static void mcam_dma_contig_done(struct mcam_camera *cam, int frame) | ||
1513 | { | 1516 | { |
1514 | struct mcam_vb_buffer *buf = cam->vb_bufs[frame]; | 1517 | struct mcam_camera *cam = filp->private_data; |
1518 | int ret; | ||
1515 | 1519 | ||
1516 | if (!test_bit(CF_SINGLE_BUFFER, &cam->flags)) { | 1520 | mutex_lock(&cam->s_mutex); |
1517 | delivered++; | 1521 | ret = vb2_read(&cam->vb_queue, buffer, len, pos, |
1518 | mcam_buffer_done(cam, frame, &buf->vb_buf); | 1522 | filp->f_flags & O_NONBLOCK); |
1519 | } | 1523 | mutex_unlock(&cam->s_mutex); |
1520 | mcam_set_contig_buffer(cam, frame); | 1524 | return ret; |
1521 | } | 1525 | } |
1522 | 1526 | ||
1523 | /* | 1527 | |
1524 | * Frame completion with S/G is trickier. We can't muck with | 1528 | |
1525 | * a descriptor chain on the fly, since the controller buffers it | 1529 | static unsigned int mcam_v4l_poll(struct file *filp, |
1526 | * internally. So we have to actually stop and restart; Marvell | 1530 | struct poll_table_struct *pt) |
1527 | * says this is the way to do it. | ||
1528 | * | ||
1529 | * Of course, stopping is easier said than done; experience shows | ||
1530 | * that the controller can start a frame *after* C0_ENABLE has been | ||
1531 | * cleared. So when running in S/G mode, the controller is "stopped" | ||
1532 | * on receipt of the start-of-frame interrupt. That means we can | ||
1533 | * safely change the DMA descriptor array here and restart things | ||
1534 | * (assuming there's another buffer waiting to go). | ||
1535 | */ | ||
1536 | static void mcam_dma_sg_done(struct mcam_camera *cam, int frame) | ||
1537 | { | 1531 | { |
1538 | struct mcam_vb_buffer *buf = cam->vb_bufs[0]; | 1532 | struct mcam_camera *cam = filp->private_data; |
1533 | int ret; | ||
1539 | 1534 | ||
1540 | /* | 1535 | mutex_lock(&cam->s_mutex); |
1541 | * Very Bad Not Good Things happen if you don't clear | 1536 | ret = vb2_poll(&cam->vb_queue, filp, pt); |
1542 | * C1_DESC_ENA before making any descriptor changes. | 1537 | mutex_unlock(&cam->s_mutex); |
1543 | */ | 1538 | return ret; |
1544 | mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA); | ||
1545 | /* | ||
1546 | * If we have another buffer available, put it in and | ||
1547 | * restart the engine. | ||
1548 | */ | ||
1549 | if (!list_empty(&cam->buffers)) { | ||
1550 | mcam_sg_next_buffer(cam); | ||
1551 | mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA); | ||
1552 | mcam_ctlr_start(cam); | ||
1553 | /* | ||
1554 | * Otherwise set CF_SG_RESTART and the controller will | ||
1555 | * be restarted once another buffer shows up. | ||
1556 | */ | ||
1557 | } else { | ||
1558 | set_bit(CF_SG_RESTART, &cam->flags); | ||
1559 | singles++; | ||
1560 | } | ||
1561 | /* | ||
1562 | * Now we can give the completed frame back to user space. | ||
1563 | */ | ||
1564 | delivered++; | ||
1565 | mcam_buffer_done(cam, frame, &buf->vb_buf); | ||
1566 | } | 1539 | } |
1567 | 1540 | ||
1568 | 1541 | ||
1542 | static int mcam_v4l_mmap(struct file *filp, struct vm_area_struct *vma) | ||
1543 | { | ||
1544 | struct mcam_camera *cam = filp->private_data; | ||
1545 | int ret; | ||
1546 | |||
1547 | mutex_lock(&cam->s_mutex); | ||
1548 | ret = vb2_mmap(&cam->vb_queue, vma); | ||
1549 | mutex_unlock(&cam->s_mutex); | ||
1550 | return ret; | ||
1551 | } | ||
1552 | |||
1553 | |||
1554 | |||
1555 | static const struct v4l2_file_operations mcam_v4l_fops = { | ||
1556 | .owner = THIS_MODULE, | ||
1557 | .open = mcam_v4l_open, | ||
1558 | .release = mcam_v4l_release, | ||
1559 | .read = mcam_v4l_read, | ||
1560 | .poll = mcam_v4l_poll, | ||
1561 | .mmap = mcam_v4l_mmap, | ||
1562 | .unlocked_ioctl = video_ioctl2, | ||
1563 | }; | ||
1564 | |||
1565 | |||
1566 | /* | ||
1567 | * This template device holds all of those v4l2 methods; we | ||
1568 | * clone it for specific real devices. | ||
1569 | */ | ||
1570 | static struct video_device mcam_v4l_template = { | ||
1571 | .name = "mcam", | ||
1572 | .tvnorms = V4L2_STD_NTSC_M, | ||
1573 | .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ | ||
1569 | 1574 | ||
1575 | .fops = &mcam_v4l_fops, | ||
1576 | .ioctl_ops = &mcam_v4l_ioctl_ops, | ||
1577 | .release = video_device_release_empty, | ||
1578 | }; | ||
1579 | |||
1580 | /* ---------------------------------------------------------------------- */ | ||
1581 | /* | ||
1582 | * Interrupt handler stuff | ||
1583 | */ | ||
1570 | static void mcam_frame_complete(struct mcam_camera *cam, int frame) | 1584 | static void mcam_frame_complete(struct mcam_camera *cam, int frame) |
1571 | { | 1585 | { |
1572 | /* | 1586 | /* |
@@ -1600,8 +1614,10 @@ static void mcam_frame_complete(struct mcam_camera *cam, int frame) | |||
1600 | } | 1614 | } |
1601 | 1615 | ||
1602 | 1616 | ||
1603 | 1617 | /* | |
1604 | 1618 | * The interrupt handler; this needs to be called from the | |
1619 | * platform irq handler with the lock held. | ||
1620 | */ | ||
1605 | int mccic_irq(struct mcam_camera *cam, unsigned int irqs) | 1621 | int mccic_irq(struct mcam_camera *cam, unsigned int irqs) |
1606 | { | 1622 | { |
1607 | unsigned int frame, handled = 0; | 1623 | unsigned int frame, handled = 0; |
@@ -1636,10 +1652,10 @@ int mccic_irq(struct mcam_camera *cam, unsigned int irqs) | |||
1636 | return handled; | 1652 | return handled; |
1637 | } | 1653 | } |
1638 | 1654 | ||
1655 | /* ---------------------------------------------------------------------- */ | ||
1639 | /* | 1656 | /* |
1640 | * Registration and such. | 1657 | * Registration and such. |
1641 | */ | 1658 | */ |
1642 | |||
1643 | static struct ov7670_config sensor_cfg = { | 1659 | static struct ov7670_config sensor_cfg = { |
1644 | /* | 1660 | /* |
1645 | * Exclude QCIF mode, because it only captures a tiny portion | 1661 | * Exclude QCIF mode, because it only captures a tiny portion |