2 * Copyright (c) 2011 Atmel Corporation
3 * Josh Wu, <josh.wu@atmel.com>
5 * Based on previous work by Lars Haring, <lars.haring@atmel.com>
7 * Based on the bttv driver for Bt848 with respective copyright holders
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
14 #include <linux/clk.h>
15 #include <linux/completion.h>
16 #include <linux/delay.h>
18 #include <linux/init.h>
19 #include <linux/interrupt.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/of_graph.h>
23 #include <linux/platform_device.h>
24 #include <linux/pm_runtime.h>
25 #include <linux/slab.h>
28 #include <linux/videodev2.h>
29 #include <media/v4l2-ctrls.h>
30 #include <media/v4l2-device.h>
31 #include <media/v4l2-dev.h>
32 #include <media/v4l2-ioctl.h>
33 #include <media/v4l2-event.h>
34 #include <media/v4l2-fwnode.h>
35 #include <media/videobuf2-dma-contig.h>
36 #include <media/v4l2-image-sizes.h>
38 #include "atmel-isi.h"
40 #define MAX_SUPPORT_WIDTH 2048U
41 #define MAX_SUPPORT_HEIGHT 2048U
42 #define MIN_FRAME_RATE 15
43 #define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE)
45 /* Frame buffer descriptor */
47 /* Physical address of the frame buffer */
49 /* DMA Control Register(only in HISI2) */
51 /* Physical address of the next fbd */
55 static void set_dma_ctrl(struct fbd
*fb_desc
, u32 ctrl
)
57 fb_desc
->dma_ctrl
= ctrl
;
61 struct list_head list
;
66 /* Frame buffer data */
68 struct vb2_v4l2_buffer vb
;
69 struct isi_dma_desc
*p_dma_desc
;
70 struct list_head list
;
73 struct isi_graph_entity
{
74 struct device_node
*node
;
76 struct v4l2_async_subdev asd
;
77 struct v4l2_subdev
*subdev
;
81 * struct isi_format - ISI media bus format information
82 * @fourcc: Fourcc code for this format
83 * @mbus_code: V4L2 media bus format code.
84 * @bpp: Bytes per pixel (when stored in memory)
85 * @swap: Byte swap configuration value
86 * @support: Indicates format supported by subdev
87 * @skip: Skip duplicate format supported by subdev
98 /* Protects the access of variables shared with the ISR */
105 /* Allocate descriptors for dma buffer use */
106 struct fbd
*p_fb_descriptors
;
107 dma_addr_t fb_descriptors_phys
;
108 struct list_head dma_desc_head
;
109 struct isi_dma_desc dma_desc
[VIDEO_MAX_FRAME
];
110 bool enable_preview_path
;
112 struct completion complete
;
113 /* ISI peripherial clock */
117 struct isi_platform_data pdata
;
118 u16 width_flags
; /* max 12 bits */
120 struct list_head video_buffer_list
;
121 struct frame_buffer
*active
;
123 struct v4l2_device v4l2_dev
;
124 struct video_device
*vdev
;
125 struct v4l2_async_notifier notifier
;
126 struct isi_graph_entity entity
;
127 struct v4l2_format fmt
;
129 const struct isi_format
**user_formats
;
130 unsigned int num_user_formats
;
131 const struct isi_format
*current_fmt
;
134 struct vb2_queue queue
;
137 #define notifier_to_isi(n) container_of(n, struct atmel_isi, notifier)
139 static void isi_writel(struct atmel_isi
*isi
, u32 reg
, u32 val
)
141 writel(val
, isi
->regs
+ reg
);
143 static u32
isi_readl(struct atmel_isi
*isi
, u32 reg
)
145 return readl(isi
->regs
+ reg
);
148 static void configure_geometry(struct atmel_isi
*isi
)
151 u32 fourcc
= isi
->current_fmt
->fourcc
;
153 isi
->enable_preview_path
= fourcc
== V4L2_PIX_FMT_RGB565
||
154 fourcc
== V4L2_PIX_FMT_RGB32
;
156 /* According to sensor's output format to set cfg2 */
157 cfg2
= isi
->current_fmt
->swap
;
159 isi_writel(isi
, ISI_CTRL
, ISI_CTRL_DIS
);
161 cfg2
|= ((isi
->fmt
.fmt
.pix
.width
- 1) << ISI_CFG2_IM_HSIZE_OFFSET
) &
162 ISI_CFG2_IM_HSIZE_MASK
;
164 cfg2
|= ((isi
->fmt
.fmt
.pix
.height
- 1) << ISI_CFG2_IM_VSIZE_OFFSET
)
165 & ISI_CFG2_IM_VSIZE_MASK
;
166 isi_writel(isi
, ISI_CFG2
, cfg2
);
168 /* No down sampling, preview size equal to sensor output size */
169 psize
= ((isi
->fmt
.fmt
.pix
.width
- 1) << ISI_PSIZE_PREV_HSIZE_OFFSET
) &
170 ISI_PSIZE_PREV_HSIZE_MASK
;
171 psize
|= ((isi
->fmt
.fmt
.pix
.height
- 1) << ISI_PSIZE_PREV_VSIZE_OFFSET
) &
172 ISI_PSIZE_PREV_VSIZE_MASK
;
173 isi_writel(isi
, ISI_PSIZE
, psize
);
174 isi_writel(isi
, ISI_PDECF
, ISI_PDECF_NO_SAMPLING
);
177 static irqreturn_t
atmel_isi_handle_streaming(struct atmel_isi
*isi
)
180 struct vb2_v4l2_buffer
*vbuf
= &isi
->active
->vb
;
181 struct frame_buffer
*buf
= isi
->active
;
183 list_del_init(&buf
->list
);
184 vbuf
->vb2_buf
.timestamp
= ktime_get_ns();
185 vbuf
->sequence
= isi
->sequence
++;
186 vbuf
->field
= V4L2_FIELD_NONE
;
187 vb2_buffer_done(&vbuf
->vb2_buf
, VB2_BUF_STATE_DONE
);
190 if (list_empty(&isi
->video_buffer_list
)) {
193 /* start next dma frame. */
194 isi
->active
= list_entry(isi
->video_buffer_list
.next
,
195 struct frame_buffer
, list
);
196 if (!isi
->enable_preview_path
) {
197 isi_writel(isi
, ISI_DMA_C_DSCR
,
198 (u32
)isi
->active
->p_dma_desc
->fbd_phys
);
199 isi_writel(isi
, ISI_DMA_C_CTRL
,
200 ISI_DMA_CTRL_FETCH
| ISI_DMA_CTRL_DONE
);
201 isi_writel(isi
, ISI_DMA_CHER
, ISI_DMA_CHSR_C_CH
);
203 isi_writel(isi
, ISI_DMA_P_DSCR
,
204 (u32
)isi
->active
->p_dma_desc
->fbd_phys
);
205 isi_writel(isi
, ISI_DMA_P_CTRL
,
206 ISI_DMA_CTRL_FETCH
| ISI_DMA_CTRL_DONE
);
207 isi_writel(isi
, ISI_DMA_CHER
, ISI_DMA_CHSR_P_CH
);
213 /* ISI interrupt service routine */
214 static irqreturn_t
isi_interrupt(int irq
, void *dev_id
)
216 struct atmel_isi
*isi
= dev_id
;
217 u32 status
, mask
, pending
;
218 irqreturn_t ret
= IRQ_NONE
;
220 spin_lock(&isi
->irqlock
);
222 status
= isi_readl(isi
, ISI_STATUS
);
223 mask
= isi_readl(isi
, ISI_INTMASK
);
224 pending
= status
& mask
;
226 if (pending
& ISI_CTRL_SRST
) {
227 complete(&isi
->complete
);
228 isi_writel(isi
, ISI_INTDIS
, ISI_CTRL_SRST
);
230 } else if (pending
& ISI_CTRL_DIS
) {
231 complete(&isi
->complete
);
232 isi_writel(isi
, ISI_INTDIS
, ISI_CTRL_DIS
);
235 if (likely(pending
& ISI_SR_CXFR_DONE
) ||
236 likely(pending
& ISI_SR_PXFR_DONE
))
237 ret
= atmel_isi_handle_streaming(isi
);
240 spin_unlock(&isi
->irqlock
);
244 #define WAIT_ISI_RESET 1
245 #define WAIT_ISI_DISABLE 0
246 static int atmel_isi_wait_status(struct atmel_isi
*isi
, int wait_reset
)
248 unsigned long timeout
;
250 * The reset or disable will only succeed if we have a
251 * pixel clock from the camera.
253 init_completion(&isi
->complete
);
256 isi_writel(isi
, ISI_INTEN
, ISI_CTRL_SRST
);
257 isi_writel(isi
, ISI_CTRL
, ISI_CTRL_SRST
);
259 isi_writel(isi
, ISI_INTEN
, ISI_CTRL_DIS
);
260 isi_writel(isi
, ISI_CTRL
, ISI_CTRL_DIS
);
263 timeout
= wait_for_completion_timeout(&isi
->complete
,
264 msecs_to_jiffies(500));
271 /* ------------------------------------------------------------------
273 ------------------------------------------------------------------*/
274 static int queue_setup(struct vb2_queue
*vq
,
275 unsigned int *nbuffers
, unsigned int *nplanes
,
276 unsigned int sizes
[], struct device
*alloc_devs
[])
278 struct atmel_isi
*isi
= vb2_get_drv_priv(vq
);
281 size
= isi
->fmt
.fmt
.pix
.sizeimage
;
283 /* Make sure the image size is large enough. */
285 return sizes
[0] < size
? -EINVAL
: 0;
292 dev_dbg(isi
->dev
, "%s, count=%d, size=%ld\n", __func__
,
298 static int buffer_init(struct vb2_buffer
*vb
)
300 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
301 struct frame_buffer
*buf
= container_of(vbuf
, struct frame_buffer
, vb
);
303 buf
->p_dma_desc
= NULL
;
304 INIT_LIST_HEAD(&buf
->list
);
309 static int buffer_prepare(struct vb2_buffer
*vb
)
311 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
312 struct frame_buffer
*buf
= container_of(vbuf
, struct frame_buffer
, vb
);
313 struct atmel_isi
*isi
= vb2_get_drv_priv(vb
->vb2_queue
);
315 struct isi_dma_desc
*desc
;
317 size
= isi
->fmt
.fmt
.pix
.sizeimage
;
319 if (vb2_plane_size(vb
, 0) < size
) {
320 dev_err(isi
->dev
, "%s data will not fit into plane (%lu < %lu)\n",
321 __func__
, vb2_plane_size(vb
, 0), size
);
325 vb2_set_plane_payload(vb
, 0, size
);
327 if (!buf
->p_dma_desc
) {
328 if (list_empty(&isi
->dma_desc_head
)) {
329 dev_err(isi
->dev
, "Not enough dma descriptors.\n");
332 /* Get an available descriptor */
333 desc
= list_entry(isi
->dma_desc_head
.next
,
334 struct isi_dma_desc
, list
);
335 /* Delete the descriptor since now it is used */
336 list_del_init(&desc
->list
);
338 /* Initialize the dma descriptor */
339 desc
->p_fbd
->fb_address
=
340 vb2_dma_contig_plane_dma_addr(vb
, 0);
341 desc
->p_fbd
->next_fbd_address
= 0;
342 set_dma_ctrl(desc
->p_fbd
, ISI_DMA_CTRL_WB
);
344 buf
->p_dma_desc
= desc
;
350 static void buffer_cleanup(struct vb2_buffer
*vb
)
352 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
353 struct atmel_isi
*isi
= vb2_get_drv_priv(vb
->vb2_queue
);
354 struct frame_buffer
*buf
= container_of(vbuf
, struct frame_buffer
, vb
);
356 /* This descriptor is available now and we add to head list */
358 list_add(&buf
->p_dma_desc
->list
, &isi
->dma_desc_head
);
361 static void start_dma(struct atmel_isi
*isi
, struct frame_buffer
*buffer
)
365 cfg1
= isi_readl(isi
, ISI_CFG1
);
366 /* Enable irq: cxfr for the codec path, pxfr for the preview path */
367 isi_writel(isi
, ISI_INTEN
,
368 ISI_SR_CXFR_DONE
| ISI_SR_PXFR_DONE
);
370 /* Check if already in a frame */
371 if (!isi
->enable_preview_path
) {
372 if (isi_readl(isi
, ISI_STATUS
) & ISI_CTRL_CDC
) {
373 dev_err(isi
->dev
, "Already in frame handling.\n");
377 isi_writel(isi
, ISI_DMA_C_DSCR
,
378 (u32
)buffer
->p_dma_desc
->fbd_phys
);
379 isi_writel(isi
, ISI_DMA_C_CTRL
,
380 ISI_DMA_CTRL_FETCH
| ISI_DMA_CTRL_DONE
);
381 isi_writel(isi
, ISI_DMA_CHER
, ISI_DMA_CHSR_C_CH
);
383 isi_writel(isi
, ISI_DMA_P_DSCR
,
384 (u32
)buffer
->p_dma_desc
->fbd_phys
);
385 isi_writel(isi
, ISI_DMA_P_CTRL
,
386 ISI_DMA_CTRL_FETCH
| ISI_DMA_CTRL_DONE
);
387 isi_writel(isi
, ISI_DMA_CHER
, ISI_DMA_CHSR_P_CH
);
390 cfg1
&= ~ISI_CFG1_FRATE_DIV_MASK
;
391 /* Enable linked list */
392 cfg1
|= isi
->pdata
.frate
| ISI_CFG1_DISCR
;
397 if (!isi
->enable_preview_path
)
398 ctrl
|= ISI_CTRL_CDC
;
400 isi_writel(isi
, ISI_CTRL
, ctrl
);
401 isi_writel(isi
, ISI_CFG1
, cfg1
);
404 static void buffer_queue(struct vb2_buffer
*vb
)
406 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
407 struct atmel_isi
*isi
= vb2_get_drv_priv(vb
->vb2_queue
);
408 struct frame_buffer
*buf
= container_of(vbuf
, struct frame_buffer
, vb
);
409 unsigned long flags
= 0;
411 spin_lock_irqsave(&isi
->irqlock
, flags
);
412 list_add_tail(&buf
->list
, &isi
->video_buffer_list
);
416 if (vb2_is_streaming(vb
->vb2_queue
))
419 spin_unlock_irqrestore(&isi
->irqlock
, flags
);
422 static int start_streaming(struct vb2_queue
*vq
, unsigned int count
)
424 struct atmel_isi
*isi
= vb2_get_drv_priv(vq
);
425 struct frame_buffer
*buf
, *node
;
428 pm_runtime_get_sync(isi
->dev
);
430 /* Enable stream on the sub device */
431 ret
= v4l2_subdev_call(isi
->entity
.subdev
, video
, s_stream
, 1);
432 if (ret
&& ret
!= -ENOIOCTLCMD
) {
433 dev_err(isi
->dev
, "stream on failed in subdev\n");
434 goto err_start_stream
;
438 ret
= atmel_isi_wait_status(isi
, WAIT_ISI_RESET
);
440 dev_err(isi
->dev
, "Reset ISI timed out\n");
443 /* Disable all interrupts */
444 isi_writel(isi
, ISI_INTDIS
, (u32
)~0UL);
447 configure_geometry(isi
);
449 spin_lock_irq(&isi
->irqlock
);
450 /* Clear any pending interrupt */
451 isi_readl(isi
, ISI_STATUS
);
453 start_dma(isi
, isi
->active
);
454 spin_unlock_irq(&isi
->irqlock
);
459 v4l2_subdev_call(isi
->entity
.subdev
, video
, s_stream
, 0);
462 pm_runtime_put(isi
->dev
);
464 spin_lock_irq(&isi
->irqlock
);
466 /* Release all active buffers */
467 list_for_each_entry_safe(buf
, node
, &isi
->video_buffer_list
, list
) {
468 list_del_init(&buf
->list
);
469 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_QUEUED
);
471 spin_unlock_irq(&isi
->irqlock
);
476 /* abort streaming and wait for last buffer */
477 static void stop_streaming(struct vb2_queue
*vq
)
479 struct atmel_isi
*isi
= vb2_get_drv_priv(vq
);
480 struct frame_buffer
*buf
, *node
;
482 unsigned long timeout
;
484 /* Disable stream on the sub device */
485 ret
= v4l2_subdev_call(isi
->entity
.subdev
, video
, s_stream
, 0);
486 if (ret
&& ret
!= -ENOIOCTLCMD
)
487 dev_err(isi
->dev
, "stream off failed in subdev\n");
489 spin_lock_irq(&isi
->irqlock
);
491 /* Release all active buffers */
492 list_for_each_entry_safe(buf
, node
, &isi
->video_buffer_list
, list
) {
493 list_del_init(&buf
->list
);
494 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
496 spin_unlock_irq(&isi
->irqlock
);
498 if (!isi
->enable_preview_path
) {
499 timeout
= jiffies
+ FRAME_INTERVAL_MILLI_SEC
* HZ
;
500 /* Wait until the end of the current frame. */
501 while ((isi_readl(isi
, ISI_STATUS
) & ISI_CTRL_CDC
) &&
502 time_before(jiffies
, timeout
))
505 if (time_after(jiffies
, timeout
))
507 "Timeout waiting for finishing codec request\n");
510 /* Disable interrupts */
511 isi_writel(isi
, ISI_INTDIS
,
512 ISI_SR_CXFR_DONE
| ISI_SR_PXFR_DONE
);
514 /* Disable ISI and wait for it is done */
515 ret
= atmel_isi_wait_status(isi
, WAIT_ISI_DISABLE
);
517 dev_err(isi
->dev
, "Disable ISI timed out\n");
519 pm_runtime_put(isi
->dev
);
522 static const struct vb2_ops isi_video_qops
= {
523 .queue_setup
= queue_setup
,
524 .buf_init
= buffer_init
,
525 .buf_prepare
= buffer_prepare
,
526 .buf_cleanup
= buffer_cleanup
,
527 .buf_queue
= buffer_queue
,
528 .start_streaming
= start_streaming
,
529 .stop_streaming
= stop_streaming
,
530 .wait_prepare
= vb2_ops_wait_prepare
,
531 .wait_finish
= vb2_ops_wait_finish
,
534 static int isi_g_fmt_vid_cap(struct file
*file
, void *priv
,
535 struct v4l2_format
*fmt
)
537 struct atmel_isi
*isi
= video_drvdata(file
);
544 static const struct isi_format
*find_format_by_fourcc(struct atmel_isi
*isi
,
547 unsigned int num_formats
= isi
->num_user_formats
;
548 const struct isi_format
*fmt
;
551 for (i
= 0; i
< num_formats
; i
++) {
552 fmt
= isi
->user_formats
[i
];
553 if (fmt
->fourcc
== fourcc
)
560 static int isi_try_fmt(struct atmel_isi
*isi
, struct v4l2_format
*f
,
561 const struct isi_format
**current_fmt
)
563 const struct isi_format
*isi_fmt
;
564 struct v4l2_pix_format
*pixfmt
= &f
->fmt
.pix
;
565 struct v4l2_subdev_pad_config pad_cfg
;
566 struct v4l2_subdev_format format
= {
567 .which
= V4L2_SUBDEV_FORMAT_TRY
,
571 isi_fmt
= find_format_by_fourcc(isi
, pixfmt
->pixelformat
);
573 isi_fmt
= isi
->user_formats
[isi
->num_user_formats
- 1];
574 pixfmt
->pixelformat
= isi_fmt
->fourcc
;
577 /* Limit to Atmel ISI hardware capabilities */
578 pixfmt
->width
= clamp(pixfmt
->width
, 0U, MAX_SUPPORT_WIDTH
);
579 pixfmt
->height
= clamp(pixfmt
->height
, 0U, MAX_SUPPORT_HEIGHT
);
581 v4l2_fill_mbus_format(&format
.format
, pixfmt
, isi_fmt
->mbus_code
);
582 ret
= v4l2_subdev_call(isi
->entity
.subdev
, pad
, set_fmt
,
587 v4l2_fill_pix_format(pixfmt
, &format
.format
);
589 pixfmt
->field
= V4L2_FIELD_NONE
;
590 pixfmt
->bytesperline
= pixfmt
->width
* isi_fmt
->bpp
;
591 pixfmt
->sizeimage
= pixfmt
->bytesperline
* pixfmt
->height
;
594 *current_fmt
= isi_fmt
;
599 static int isi_set_fmt(struct atmel_isi
*isi
, struct v4l2_format
*f
)
601 struct v4l2_subdev_format format
= {
602 .which
= V4L2_SUBDEV_FORMAT_ACTIVE
,
604 const struct isi_format
*current_fmt
;
607 ret
= isi_try_fmt(isi
, f
, ¤t_fmt
);
611 v4l2_fill_mbus_format(&format
.format
, &f
->fmt
.pix
,
612 current_fmt
->mbus_code
);
613 ret
= v4l2_subdev_call(isi
->entity
.subdev
, pad
,
614 set_fmt
, NULL
, &format
);
619 isi
->current_fmt
= current_fmt
;
624 static int isi_s_fmt_vid_cap(struct file
*file
, void *priv
,
625 struct v4l2_format
*f
)
627 struct atmel_isi
*isi
= video_drvdata(file
);
629 if (vb2_is_streaming(&isi
->queue
))
632 return isi_set_fmt(isi
, f
);
635 static int isi_try_fmt_vid_cap(struct file
*file
, void *priv
,
636 struct v4l2_format
*f
)
638 struct atmel_isi
*isi
= video_drvdata(file
);
640 return isi_try_fmt(isi
, f
, NULL
);
643 static int isi_enum_fmt_vid_cap(struct file
*file
, void *priv
,
644 struct v4l2_fmtdesc
*f
)
646 struct atmel_isi
*isi
= video_drvdata(file
);
648 if (f
->index
>= isi
->num_user_formats
)
651 f
->pixelformat
= isi
->user_formats
[f
->index
]->fourcc
;
655 static int isi_querycap(struct file
*file
, void *priv
,
656 struct v4l2_capability
*cap
)
658 strlcpy(cap
->driver
, "atmel-isi", sizeof(cap
->driver
));
659 strlcpy(cap
->card
, "Atmel Image Sensor Interface", sizeof(cap
->card
));
660 strlcpy(cap
->bus_info
, "platform:isi", sizeof(cap
->bus_info
));
664 static int isi_enum_input(struct file
*file
, void *priv
,
665 struct v4l2_input
*i
)
670 i
->type
= V4L2_INPUT_TYPE_CAMERA
;
671 strlcpy(i
->name
, "Camera", sizeof(i
->name
));
675 static int isi_g_input(struct file
*file
, void *priv
, unsigned int *i
)
681 static int isi_s_input(struct file
*file
, void *priv
, unsigned int i
)
688 static int isi_g_parm(struct file
*file
, void *fh
, struct v4l2_streamparm
*a
)
690 struct atmel_isi
*isi
= video_drvdata(file
);
692 return v4l2_g_parm_cap(video_devdata(file
), isi
->entity
.subdev
, a
);
695 static int isi_s_parm(struct file
*file
, void *fh
, struct v4l2_streamparm
*a
)
697 struct atmel_isi
*isi
= video_drvdata(file
);
699 return v4l2_s_parm_cap(video_devdata(file
), isi
->entity
.subdev
, a
);
702 static int isi_enum_framesizes(struct file
*file
, void *fh
,
703 struct v4l2_frmsizeenum
*fsize
)
705 struct atmel_isi
*isi
= video_drvdata(file
);
706 const struct isi_format
*isi_fmt
;
707 struct v4l2_subdev_frame_size_enum fse
= {
708 .index
= fsize
->index
,
709 .which
= V4L2_SUBDEV_FORMAT_ACTIVE
,
713 isi_fmt
= find_format_by_fourcc(isi
, fsize
->pixel_format
);
717 fse
.code
= isi_fmt
->mbus_code
;
719 ret
= v4l2_subdev_call(isi
->entity
.subdev
, pad
, enum_frame_size
,
724 fsize
->type
= V4L2_FRMSIZE_TYPE_DISCRETE
;
725 fsize
->discrete
.width
= fse
.max_width
;
726 fsize
->discrete
.height
= fse
.max_height
;
731 static int isi_enum_frameintervals(struct file
*file
, void *fh
,
732 struct v4l2_frmivalenum
*fival
)
734 struct atmel_isi
*isi
= video_drvdata(file
);
735 const struct isi_format
*isi_fmt
;
736 struct v4l2_subdev_frame_interval_enum fie
= {
737 .index
= fival
->index
,
738 .width
= fival
->width
,
739 .height
= fival
->height
,
740 .which
= V4L2_SUBDEV_FORMAT_ACTIVE
,
744 isi_fmt
= find_format_by_fourcc(isi
, fival
->pixel_format
);
748 fie
.code
= isi_fmt
->mbus_code
;
750 ret
= v4l2_subdev_call(isi
->entity
.subdev
, pad
,
751 enum_frame_interval
, NULL
, &fie
);
755 fival
->type
= V4L2_FRMIVAL_TYPE_DISCRETE
;
756 fival
->discrete
= fie
.interval
;
761 static void isi_camera_set_bus_param(struct atmel_isi
*isi
)
765 /* set bus param for ISI */
766 if (isi
->pdata
.hsync_act_low
)
767 cfg1
|= ISI_CFG1_HSYNC_POL_ACTIVE_LOW
;
768 if (isi
->pdata
.vsync_act_low
)
769 cfg1
|= ISI_CFG1_VSYNC_POL_ACTIVE_LOW
;
770 if (isi
->pdata
.pclk_act_falling
)
771 cfg1
|= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING
;
772 if (isi
->pdata
.has_emb_sync
)
773 cfg1
|= ISI_CFG1_EMB_SYNC
;
774 if (isi
->pdata
.full_mode
)
775 cfg1
|= ISI_CFG1_FULL_MODE
;
777 cfg1
|= ISI_CFG1_THMASK_BEATS_16
;
779 /* Enable PM and peripheral clock before operate isi registers */
780 pm_runtime_get_sync(isi
->dev
);
782 isi_writel(isi
, ISI_CTRL
, ISI_CTRL_DIS
);
783 isi_writel(isi
, ISI_CFG1
, cfg1
);
785 pm_runtime_put(isi
->dev
);
788 /* -----------------------------------------------------------------------*/
789 static int atmel_isi_parse_dt(struct atmel_isi
*isi
,
790 struct platform_device
*pdev
)
792 struct device_node
*np
= pdev
->dev
.of_node
;
793 struct v4l2_fwnode_endpoint ep
;
796 /* Default settings for ISI */
797 isi
->pdata
.full_mode
= 1;
798 isi
->pdata
.frate
= ISI_CFG1_FRATE_CAPTURE_ALL
;
800 np
= of_graph_get_next_endpoint(np
, NULL
);
802 dev_err(&pdev
->dev
, "Could not find the endpoint\n");
806 err
= v4l2_fwnode_endpoint_parse(of_fwnode_handle(np
), &ep
);
809 dev_err(&pdev
->dev
, "Could not parse the endpoint\n");
813 switch (ep
.bus
.parallel
.bus_width
) {
815 isi
->pdata
.data_width_flags
= ISI_DATAWIDTH_8
;
818 isi
->pdata
.data_width_flags
=
819 ISI_DATAWIDTH_8
| ISI_DATAWIDTH_10
;
822 dev_err(&pdev
->dev
, "Unsupported bus width: %d\n",
823 ep
.bus
.parallel
.bus_width
);
827 if (ep
.bus
.parallel
.flags
& V4L2_MBUS_HSYNC_ACTIVE_LOW
)
828 isi
->pdata
.hsync_act_low
= true;
829 if (ep
.bus
.parallel
.flags
& V4L2_MBUS_VSYNC_ACTIVE_LOW
)
830 isi
->pdata
.vsync_act_low
= true;
831 if (ep
.bus
.parallel
.flags
& V4L2_MBUS_PCLK_SAMPLE_FALLING
)
832 isi
->pdata
.pclk_act_falling
= true;
834 if (ep
.bus_type
== V4L2_MBUS_BT656
)
835 isi
->pdata
.has_emb_sync
= true;
840 static int isi_open(struct file
*file
)
842 struct atmel_isi
*isi
= video_drvdata(file
);
843 struct v4l2_subdev
*sd
= isi
->entity
.subdev
;
846 if (mutex_lock_interruptible(&isi
->lock
))
849 ret
= v4l2_fh_open(file
);
853 if (!v4l2_fh_is_singular_file(file
))
856 ret
= v4l2_subdev_call(sd
, core
, s_power
, 1);
857 if (ret
< 0 && ret
!= -ENOIOCTLCMD
)
860 ret
= isi_set_fmt(isi
, &isi
->fmt
);
862 v4l2_subdev_call(sd
, core
, s_power
, 0);
865 v4l2_fh_release(file
);
867 mutex_unlock(&isi
->lock
);
871 static int isi_release(struct file
*file
)
873 struct atmel_isi
*isi
= video_drvdata(file
);
874 struct v4l2_subdev
*sd
= isi
->entity
.subdev
;
878 mutex_lock(&isi
->lock
);
880 fh_singular
= v4l2_fh_is_singular_file(file
);
882 ret
= _vb2_fop_release(file
, NULL
);
885 v4l2_subdev_call(sd
, core
, s_power
, 0);
887 mutex_unlock(&isi
->lock
);
892 static const struct v4l2_ioctl_ops isi_ioctl_ops
= {
893 .vidioc_querycap
= isi_querycap
,
895 .vidioc_try_fmt_vid_cap
= isi_try_fmt_vid_cap
,
896 .vidioc_g_fmt_vid_cap
= isi_g_fmt_vid_cap
,
897 .vidioc_s_fmt_vid_cap
= isi_s_fmt_vid_cap
,
898 .vidioc_enum_fmt_vid_cap
= isi_enum_fmt_vid_cap
,
900 .vidioc_enum_input
= isi_enum_input
,
901 .vidioc_g_input
= isi_g_input
,
902 .vidioc_s_input
= isi_s_input
,
904 .vidioc_g_parm
= isi_g_parm
,
905 .vidioc_s_parm
= isi_s_parm
,
906 .vidioc_enum_framesizes
= isi_enum_framesizes
,
907 .vidioc_enum_frameintervals
= isi_enum_frameintervals
,
909 .vidioc_reqbufs
= vb2_ioctl_reqbufs
,
910 .vidioc_create_bufs
= vb2_ioctl_create_bufs
,
911 .vidioc_querybuf
= vb2_ioctl_querybuf
,
912 .vidioc_qbuf
= vb2_ioctl_qbuf
,
913 .vidioc_dqbuf
= vb2_ioctl_dqbuf
,
914 .vidioc_expbuf
= vb2_ioctl_expbuf
,
915 .vidioc_prepare_buf
= vb2_ioctl_prepare_buf
,
916 .vidioc_streamon
= vb2_ioctl_streamon
,
917 .vidioc_streamoff
= vb2_ioctl_streamoff
,
919 .vidioc_log_status
= v4l2_ctrl_log_status
,
920 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
921 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
924 static const struct v4l2_file_operations isi_fops
= {
925 .owner
= THIS_MODULE
,
926 .unlocked_ioctl
= video_ioctl2
,
928 .release
= isi_release
,
929 .poll
= vb2_fop_poll
,
930 .mmap
= vb2_fop_mmap
,
931 .read
= vb2_fop_read
,
934 static int isi_set_default_fmt(struct atmel_isi
*isi
)
936 struct v4l2_format f
= {
937 .type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
,
940 .height
= VGA_HEIGHT
,
941 .field
= V4L2_FIELD_NONE
,
942 .pixelformat
= isi
->user_formats
[0]->fourcc
,
947 ret
= isi_try_fmt(isi
, &f
, NULL
);
950 isi
->current_fmt
= isi
->user_formats
[0];
955 static const struct isi_format isi_formats
[] = {
957 .fourcc
= V4L2_PIX_FMT_YUYV
,
958 .mbus_code
= MEDIA_BUS_FMT_YUYV8_2X8
,
960 .swap
= ISI_CFG2_YCC_SWAP_DEFAULT
,
962 .fourcc
= V4L2_PIX_FMT_YUYV
,
963 .mbus_code
= MEDIA_BUS_FMT_YVYU8_2X8
,
965 .swap
= ISI_CFG2_YCC_SWAP_MODE_1
,
967 .fourcc
= V4L2_PIX_FMT_YUYV
,
968 .mbus_code
= MEDIA_BUS_FMT_UYVY8_2X8
,
970 .swap
= ISI_CFG2_YCC_SWAP_MODE_2
,
972 .fourcc
= V4L2_PIX_FMT_YUYV
,
973 .mbus_code
= MEDIA_BUS_FMT_VYUY8_2X8
,
975 .swap
= ISI_CFG2_YCC_SWAP_MODE_3
,
977 .fourcc
= V4L2_PIX_FMT_RGB565
,
978 .mbus_code
= MEDIA_BUS_FMT_YUYV8_2X8
,
980 .swap
= ISI_CFG2_YCC_SWAP_MODE_2
,
982 .fourcc
= V4L2_PIX_FMT_RGB565
,
983 .mbus_code
= MEDIA_BUS_FMT_YVYU8_2X8
,
985 .swap
= ISI_CFG2_YCC_SWAP_MODE_3
,
987 .fourcc
= V4L2_PIX_FMT_RGB565
,
988 .mbus_code
= MEDIA_BUS_FMT_UYVY8_2X8
,
990 .swap
= ISI_CFG2_YCC_SWAP_DEFAULT
,
992 .fourcc
= V4L2_PIX_FMT_RGB565
,
993 .mbus_code
= MEDIA_BUS_FMT_VYUY8_2X8
,
995 .swap
= ISI_CFG2_YCC_SWAP_MODE_1
,
999 static int isi_formats_init(struct atmel_isi
*isi
)
1001 const struct isi_format
*isi_fmts
[ARRAY_SIZE(isi_formats
)];
1002 unsigned int num_fmts
= 0, i
, j
;
1003 struct v4l2_subdev
*subdev
= isi
->entity
.subdev
;
1004 struct v4l2_subdev_mbus_code_enum mbus_code
= {
1005 .which
= V4L2_SUBDEV_FORMAT_ACTIVE
,
1008 while (!v4l2_subdev_call(subdev
, pad
, enum_mbus_code
,
1009 NULL
, &mbus_code
)) {
1010 for (i
= 0; i
< ARRAY_SIZE(isi_formats
); i
++) {
1011 if (isi_formats
[i
].mbus_code
!= mbus_code
.code
)
1014 /* Code supported, have we got this fourcc yet? */
1015 for (j
= 0; j
< num_fmts
; j
++)
1016 if (isi_fmts
[j
]->fourcc
== isi_formats
[i
].fourcc
)
1017 /* Already available */
1021 isi_fmts
[num_fmts
++] = isi_formats
+ i
;
1029 isi
->num_user_formats
= num_fmts
;
1030 isi
->user_formats
= devm_kcalloc(isi
->dev
,
1031 num_fmts
, sizeof(struct isi_format
*),
1033 if (!isi
->user_formats
)
1036 memcpy(isi
->user_formats
, isi_fmts
,
1037 num_fmts
* sizeof(struct isi_format
*));
1038 isi
->current_fmt
= isi
->user_formats
[0];
1043 static int isi_graph_notify_complete(struct v4l2_async_notifier
*notifier
)
1045 struct atmel_isi
*isi
= notifier_to_isi(notifier
);
1048 isi
->vdev
->ctrl_handler
= isi
->entity
.subdev
->ctrl_handler
;
1049 ret
= isi_formats_init(isi
);
1051 dev_err(isi
->dev
, "No supported mediabus format found\n");
1054 isi_camera_set_bus_param(isi
);
1056 ret
= isi_set_default_fmt(isi
);
1058 dev_err(isi
->dev
, "Could not set default format\n");
1062 ret
= video_register_device(isi
->vdev
, VFL_TYPE_GRABBER
, -1);
1064 dev_err(isi
->dev
, "Failed to register video device\n");
1068 dev_dbg(isi
->dev
, "Device registered as %s\n",
1069 video_device_node_name(isi
->vdev
));
1073 static void isi_graph_notify_unbind(struct v4l2_async_notifier
*notifier
,
1074 struct v4l2_subdev
*sd
,
1075 struct v4l2_async_subdev
*asd
)
1077 struct atmel_isi
*isi
= notifier_to_isi(notifier
);
1079 dev_dbg(isi
->dev
, "Removing %s\n", video_device_node_name(isi
->vdev
));
1081 /* Checks internaly if vdev have been init or not */
1082 video_unregister_device(isi
->vdev
);
1085 static int isi_graph_notify_bound(struct v4l2_async_notifier
*notifier
,
1086 struct v4l2_subdev
*subdev
,
1087 struct v4l2_async_subdev
*asd
)
1089 struct atmel_isi
*isi
= notifier_to_isi(notifier
);
1091 dev_dbg(isi
->dev
, "subdev %s bound\n", subdev
->name
);
1093 isi
->entity
.subdev
= subdev
;
1098 static const struct v4l2_async_notifier_operations isi_graph_notify_ops
= {
1099 .bound
= isi_graph_notify_bound
,
1100 .unbind
= isi_graph_notify_unbind
,
1101 .complete
= isi_graph_notify_complete
,
1104 static int isi_graph_parse(struct atmel_isi
*isi
, struct device_node
*node
)
1106 struct device_node
*ep
= NULL
;
1107 struct device_node
*remote
;
1109 ep
= of_graph_get_next_endpoint(node
, ep
);
1113 remote
= of_graph_get_remote_port_parent(ep
);
1118 /* Remote node to connect */
1119 isi
->entity
.node
= remote
;
1120 isi
->entity
.asd
.match_type
= V4L2_ASYNC_MATCH_FWNODE
;
1121 isi
->entity
.asd
.match
.fwnode
= of_fwnode_handle(remote
);
1125 static int isi_graph_init(struct atmel_isi
*isi
)
1127 struct v4l2_async_subdev
**subdevs
= NULL
;
1130 /* Parse the graph to extract a list of subdevice DT nodes. */
1131 ret
= isi_graph_parse(isi
, isi
->dev
->of_node
);
1133 dev_err(isi
->dev
, "Graph parsing failed\n");
1137 /* Register the subdevices notifier. */
1138 subdevs
= devm_kzalloc(isi
->dev
, sizeof(*subdevs
), GFP_KERNEL
);
1140 of_node_put(isi
->entity
.node
);
1144 subdevs
[0] = &isi
->entity
.asd
;
1146 isi
->notifier
.subdevs
= subdevs
;
1147 isi
->notifier
.num_subdevs
= 1;
1148 isi
->notifier
.ops
= &isi_graph_notify_ops
;
1150 ret
= v4l2_async_notifier_register(&isi
->v4l2_dev
, &isi
->notifier
);
1152 dev_err(isi
->dev
, "Notifier registration failed\n");
1153 of_node_put(isi
->entity
.node
);
1161 static int atmel_isi_probe(struct platform_device
*pdev
)
1164 struct atmel_isi
*isi
;
1165 struct vb2_queue
*q
;
1166 struct resource
*regs
;
1169 isi
= devm_kzalloc(&pdev
->dev
, sizeof(struct atmel_isi
), GFP_KERNEL
);
1173 isi
->pclk
= devm_clk_get(&pdev
->dev
, "isi_clk");
1174 if (IS_ERR(isi
->pclk
))
1175 return PTR_ERR(isi
->pclk
);
1177 ret
= atmel_isi_parse_dt(isi
, pdev
);
1182 isi
->dev
= &pdev
->dev
;
1183 mutex_init(&isi
->lock
);
1184 spin_lock_init(&isi
->irqlock
);
1185 INIT_LIST_HEAD(&isi
->video_buffer_list
);
1186 INIT_LIST_HEAD(&isi
->dma_desc_head
);
1190 /* Initialize the top-level structure */
1191 ret
= v4l2_device_register(&pdev
->dev
, &isi
->v4l2_dev
);
1195 isi
->vdev
= video_device_alloc();
1198 goto err_vdev_alloc
;
1202 isi
->vdev
->fops
= &isi_fops
;
1203 isi
->vdev
->v4l2_dev
= &isi
->v4l2_dev
;
1204 isi
->vdev
->queue
= &isi
->queue
;
1205 strlcpy(isi
->vdev
->name
, KBUILD_MODNAME
, sizeof(isi
->vdev
->name
));
1206 isi
->vdev
->release
= video_device_release
;
1207 isi
->vdev
->ioctl_ops
= &isi_ioctl_ops
;
1208 isi
->vdev
->lock
= &isi
->lock
;
1209 isi
->vdev
->device_caps
= V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
|
1211 video_set_drvdata(isi
->vdev
, isi
);
1214 q
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1215 q
->io_modes
= VB2_MMAP
| VB2_READ
| VB2_DMABUF
;
1216 q
->lock
= &isi
->lock
;
1218 q
->buf_struct_size
= sizeof(struct frame_buffer
);
1219 q
->ops
= &isi_video_qops
;
1220 q
->mem_ops
= &vb2_dma_contig_memops
;
1221 q
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
1222 q
->min_buffers_needed
= 2;
1223 q
->dev
= &pdev
->dev
;
1225 ret
= vb2_queue_init(q
);
1227 dev_err(&pdev
->dev
, "failed to initialize VB2 queue\n");
1230 isi
->p_fb_descriptors
= dma_alloc_coherent(&pdev
->dev
,
1231 sizeof(struct fbd
) * VIDEO_MAX_FRAME
,
1232 &isi
->fb_descriptors_phys
,
1234 if (!isi
->p_fb_descriptors
) {
1235 dev_err(&pdev
->dev
, "Can't allocate descriptors!\n");
1240 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++) {
1241 isi
->dma_desc
[i
].p_fbd
= isi
->p_fb_descriptors
+ i
;
1242 isi
->dma_desc
[i
].fbd_phys
= isi
->fb_descriptors_phys
+
1243 i
* sizeof(struct fbd
);
1244 list_add(&isi
->dma_desc
[i
].list
, &isi
->dma_desc_head
);
1247 regs
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1248 isi
->regs
= devm_ioremap_resource(&pdev
->dev
, regs
);
1249 if (IS_ERR(isi
->regs
)) {
1250 ret
= PTR_ERR(isi
->regs
);
1254 if (isi
->pdata
.data_width_flags
& ISI_DATAWIDTH_8
)
1255 isi
->width_flags
= 1 << 7;
1256 if (isi
->pdata
.data_width_flags
& ISI_DATAWIDTH_10
)
1257 isi
->width_flags
|= 1 << 9;
1259 irq
= platform_get_irq(pdev
, 0);
1265 ret
= devm_request_irq(&pdev
->dev
, irq
, isi_interrupt
, 0, "isi", isi
);
1267 dev_err(&pdev
->dev
, "Unable to request irq %d\n", irq
);
1272 ret
= isi_graph_init(isi
);
1276 pm_suspend_ignore_children(&pdev
->dev
, true);
1277 pm_runtime_enable(&pdev
->dev
);
1278 platform_set_drvdata(pdev
, isi
);
1283 dma_free_coherent(&pdev
->dev
,
1284 sizeof(struct fbd
) * VIDEO_MAX_FRAME
,
1285 isi
->p_fb_descriptors
,
1286 isi
->fb_descriptors_phys
);
1289 video_device_release(isi
->vdev
);
1291 v4l2_device_unregister(&isi
->v4l2_dev
);
1296 static int atmel_isi_remove(struct platform_device
*pdev
)
1298 struct atmel_isi
*isi
= platform_get_drvdata(pdev
);
1300 dma_free_coherent(&pdev
->dev
,
1301 sizeof(struct fbd
) * VIDEO_MAX_FRAME
,
1302 isi
->p_fb_descriptors
,
1303 isi
->fb_descriptors_phys
);
1304 pm_runtime_disable(&pdev
->dev
);
1305 v4l2_async_notifier_unregister(&isi
->notifier
);
1306 v4l2_device_unregister(&isi
->v4l2_dev
);
1312 static int atmel_isi_runtime_suspend(struct device
*dev
)
1314 struct atmel_isi
*isi
= dev_get_drvdata(dev
);
1316 clk_disable_unprepare(isi
->pclk
);
1320 static int atmel_isi_runtime_resume(struct device
*dev
)
1322 struct atmel_isi
*isi
= dev_get_drvdata(dev
);
1324 return clk_prepare_enable(isi
->pclk
);
1326 #endif /* CONFIG_PM */
1328 static const struct dev_pm_ops atmel_isi_dev_pm_ops
= {
1329 SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend
,
1330 atmel_isi_runtime_resume
, NULL
)
1333 static const struct of_device_id atmel_isi_of_match
[] = {
1334 { .compatible
= "atmel,at91sam9g45-isi" },
1337 MODULE_DEVICE_TABLE(of
, atmel_isi_of_match
);
1339 static struct platform_driver atmel_isi_driver
= {
1341 .name
= "atmel_isi",
1342 .of_match_table
= of_match_ptr(atmel_isi_of_match
),
1343 .pm
= &atmel_isi_dev_pm_ops
,
1345 .probe
= atmel_isi_probe
,
1346 .remove
= atmel_isi_remove
,
1349 module_platform_driver(atmel_isi_driver
);
1351 MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1352 MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1353 MODULE_LICENSE("GPL");
1354 MODULE_SUPPORTED_DEVICE("video");