1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2011 Atmel Corporation
4 * Josh Wu, <josh.wu@atmel.com>
5 *
6 * Based on previous work by Lars Haring, <lars.haring@atmel.com>
7 * and Sedji Gaouaou
8 * Based on the bttv driver for Bt848 with respective copyright holders
9 */
10
11#include <linux/clk.h>
12#include <linux/completion.h>
13#include <linux/delay.h>
14#include <linux/fs.h>
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/of_graph.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/slab.h>
23#include <linux/of.h>
24
25#include <linux/videodev2.h>
26#include <media/v4l2-ctrls.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-dev.h>
29#include <media/v4l2-ioctl.h>
30#include <media/v4l2-event.h>
31#include <media/v4l2-fwnode.h>
32#include <media/videobuf2-dma-contig.h>
33#include <media/v4l2-image-sizes.h>
34
35#include "atmel-isi.h"
36
37#define MAX_SUPPORT_WIDTH		2048U
38#define MAX_SUPPORT_HEIGHT		2048U
39#define MIN_FRAME_RATE			15
40#define FRAME_INTERVAL_MILLI_SEC	(1000 / MIN_FRAME_RATE)
41
42/* Frame buffer descriptor */
43struct fbd {
44	/* Physical address of the frame buffer */
45	u32 fb_address;
46	/* DMA Control Register(only in HISI2) */
47	u32 dma_ctrl;
48	/* Physical address of the next fbd */
49	u32 next_fbd_address;
50};
51
52static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl)
53{
54	fb_desc->dma_ctrl = ctrl;
55}
56
57struct isi_dma_desc {
58	struct list_head list;
59	struct fbd *p_fbd;
60	dma_addr_t fbd_phys;
61};
62
63/* Frame buffer data */
64struct frame_buffer {
65	struct vb2_v4l2_buffer vb;
66	struct isi_dma_desc *p_dma_desc;
67	struct list_head list;
68};
69
70struct isi_graph_entity {
71	struct device_node *node;
72
73	struct v4l2_subdev *subdev;
74};
75
76/*
77 * struct isi_format - ISI media bus format information
78 * @fourcc:		Fourcc code for this format
79 * @mbus_code:		V4L2 media bus format code.
80 * @bpp:		Bytes per pixel (when stored in memory)
81 * @swap:		Byte swap configuration value
82 * @support:		Indicates format supported by subdev
83 * @skip:		Skip duplicate format supported by subdev
84 */
85struct isi_format {
86	u32	fourcc;
87	u32	mbus_code;
88	u8	bpp;
89	u32	swap;
90};
91
92
93struct atmel_isi {
94	/* Protects the access of variables shared with the ISR */
95	spinlock_t			irqlock;
96	struct device			*dev;
97	void __iomem			*regs;
98
99	int				sequence;
100
101	/* Allocate descriptors for dma buffer use */
102	struct fbd			*p_fb_descriptors;
103	dma_addr_t			fb_descriptors_phys;
104	struct				list_head dma_desc_head;
105	struct isi_dma_desc		dma_desc[VIDEO_MAX_FRAME];
106	bool				enable_preview_path;
107
108	struct completion		complete;
109	/* ISI peripheral clock */
110	struct clk			*pclk;
111	unsigned int			irq;
112
113	struct isi_platform_data	pdata;
114	u16				width_flags;	/* max 12 bits */
115
116	struct list_head		video_buffer_list;
117	struct frame_buffer		*active;
118
119	struct v4l2_device		v4l2_dev;
120	struct video_device		*vdev;
121	struct v4l2_async_notifier	notifier;
122	struct isi_graph_entity		entity;
123	struct v4l2_format		fmt;
124
125	const struct isi_format		**user_formats;
126	unsigned int			num_user_formats;
127	const struct isi_format		*current_fmt;
128
129	struct mutex			lock;
130	struct vb2_queue		queue;
131};
132
133#define notifier_to_isi(n) container_of(n, struct atmel_isi, notifier)
134
135static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val)
136{
137	writel(val, isi->regs + reg);
138}
139static u32 isi_readl(struct atmel_isi *isi, u32 reg)
140{
141	return readl(isi->regs + reg);
142}
143
144static void configure_geometry(struct atmel_isi *isi)
145{
146	u32 cfg2, psize;
147	u32 fourcc = isi->current_fmt->fourcc;
148
149	isi->enable_preview_path = fourcc == V4L2_PIX_FMT_RGB565 ||
150				   fourcc == V4L2_PIX_FMT_RGB32 ||
151				   fourcc == V4L2_PIX_FMT_Y16;
152
153	/* According to sensor's output format to set cfg2 */
154	cfg2 = isi->current_fmt->swap;
155
156	isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
157	/* Set width */
158	cfg2 |= ((isi->fmt.fmt.pix.width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
159			ISI_CFG2_IM_HSIZE_MASK;
160	/* Set height */
161	cfg2 |= ((isi->fmt.fmt.pix.height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
162			& ISI_CFG2_IM_VSIZE_MASK;
163	isi_writel(isi, ISI_CFG2, cfg2);
164
165	/* No down sampling, preview size equal to sensor output size */
166	psize = ((isi->fmt.fmt.pix.width - 1) << ISI_PSIZE_PREV_HSIZE_OFFSET) &
167		ISI_PSIZE_PREV_HSIZE_MASK;
168	psize |= ((isi->fmt.fmt.pix.height - 1) << ISI_PSIZE_PREV_VSIZE_OFFSET) &
169		ISI_PSIZE_PREV_VSIZE_MASK;
170	isi_writel(isi, ISI_PSIZE, psize);
171	isi_writel(isi, ISI_PDECF, ISI_PDECF_NO_SAMPLING);
172}
173
174static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
175{
176	if (isi->active) {
177		struct vb2_v4l2_buffer *vbuf = &isi->active->vb;
178		struct frame_buffer *buf = isi->active;
179
180		list_del_init(&buf->list);
181		vbuf->vb2_buf.timestamp = ktime_get_ns();
182		vbuf->sequence = isi->sequence++;
183		vbuf->field = V4L2_FIELD_NONE;
184		vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
185	}
186
187	if (list_empty(&isi->video_buffer_list)) {
188		isi->active = NULL;
189	} else {
190		/* start next dma frame. */
191		isi->active = list_entry(isi->video_buffer_list.next,
192					struct frame_buffer, list);
193		if (!isi->enable_preview_path) {
194			isi_writel(isi, ISI_DMA_C_DSCR,
195				(u32)isi->active->p_dma_desc->fbd_phys);
196			isi_writel(isi, ISI_DMA_C_CTRL,
197				ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
198			isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
199		} else {
200			isi_writel(isi, ISI_DMA_P_DSCR,
201				(u32)isi->active->p_dma_desc->fbd_phys);
202			isi_writel(isi, ISI_DMA_P_CTRL,
203				ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
204			isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
205		}
206	}
207	return IRQ_HANDLED;
208}
209
210/* ISI interrupt service routine */
211static irqreturn_t isi_interrupt(int irq, void *dev_id)
212{
213	struct atmel_isi *isi = dev_id;
214	u32 status, mask, pending;
215	irqreturn_t ret = IRQ_NONE;
216
217	spin_lock(&isi->irqlock);
218
219	status = isi_readl(isi, ISI_STATUS);
220	mask = isi_readl(isi, ISI_INTMASK);
221	pending = status & mask;
222
223	if (pending & ISI_CTRL_SRST) {
224		complete(&isi->complete);
225		isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
226		ret = IRQ_HANDLED;
227	} else if (pending & ISI_CTRL_DIS) {
228		complete(&isi->complete);
229		isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
230		ret = IRQ_HANDLED;
231	} else {
232		if (likely(pending & ISI_SR_CXFR_DONE) ||
233				likely(pending & ISI_SR_PXFR_DONE))
234			ret = atmel_isi_handle_streaming(isi);
235	}
236
237	spin_unlock(&isi->irqlock);
238	return ret;
239}
240
241#define	WAIT_ISI_RESET		1
242#define	WAIT_ISI_DISABLE	0
243static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
244{
245	unsigned long timeout;
246	/*
247	 * The reset or disable will only succeed if we have a
248	 * pixel clock from the camera.
249	 */
250	init_completion(&isi->complete);
251
252	if (wait_reset) {
253		isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST);
254		isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST);
255	} else {
256		isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS);
257		isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
258	}
259
260	timeout = wait_for_completion_timeout(&isi->complete,
261			msecs_to_jiffies(500));
262	if (timeout == 0)
263		return -ETIMEDOUT;
264
265	return 0;
266}
267
268/* ------------------------------------------------------------------
269	Videobuf operations
270   ------------------------------------------------------------------*/
271static int queue_setup(struct vb2_queue *vq,
272				unsigned int *nbuffers, unsigned int *nplanes,
273				unsigned int sizes[], struct device *alloc_devs[])
274{
275	struct atmel_isi *isi = vb2_get_drv_priv(vq);
276	unsigned long size;
277
278	size = isi->fmt.fmt.pix.sizeimage;
279
280	/* Make sure the image size is large enough. */
281	if (*nplanes)
282		return sizes[0] < size ? -EINVAL : 0;
283
284	*nplanes = 1;
285	sizes[0] = size;
286
287	isi->active = NULL;
288
289	dev_dbg(isi->dev, "%s, count=%d, size=%ld\n", __func__,
290		*nbuffers, size);
291
292	return 0;
293}
294
295static int buffer_init(struct vb2_buffer *vb)
296{
297	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
298	struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
299
300	buf->p_dma_desc = NULL;
301	INIT_LIST_HEAD(&buf->list);
302
303	return 0;
304}
305
306static int buffer_prepare(struct vb2_buffer *vb)
307{
308	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
309	struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
310	struct atmel_isi *isi = vb2_get_drv_priv(vb->vb2_queue);
311	unsigned long size;
312	struct isi_dma_desc *desc;
313
314	size = isi->fmt.fmt.pix.sizeimage;
315
316	if (vb2_plane_size(vb, 0) < size) {
317		dev_err(isi->dev, "%s data will not fit into plane (%lu < %lu)\n",
318				__func__, vb2_plane_size(vb, 0), size);
319		return -EINVAL;
320	}
321
322	vb2_set_plane_payload(vb, 0, size);
323
324	if (!buf->p_dma_desc) {
325		if (list_empty(&isi->dma_desc_head)) {
326			dev_err(isi->dev, "Not enough dma descriptors.\n");
327			return -EINVAL;
328		} else {
329			/* Get an available descriptor */
330			desc = list_entry(isi->dma_desc_head.next,
331						struct isi_dma_desc, list);
332			/* Delete the descriptor since now it is used */
333			list_del_init(&desc->list);
334
335			/* Initialize the dma descriptor */
336			desc->p_fbd->fb_address =
337					vb2_dma_contig_plane_dma_addr(vb, 0);
338			desc->p_fbd->next_fbd_address = 0;
339			set_dma_ctrl(desc->p_fbd, ISI_DMA_CTRL_WB);
340
341			buf->p_dma_desc = desc;
342		}
343	}
344	return 0;
345}
346
347static void buffer_cleanup(struct vb2_buffer *vb)
348{
349	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
350	struct atmel_isi *isi = vb2_get_drv_priv(vb->vb2_queue);
351	struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
352
353	/* This descriptor is available now and we add to head list */
354	if (buf->p_dma_desc)
355		list_add(&buf->p_dma_desc->list, &isi->dma_desc_head);
356}
357
358static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
359{
360	u32 ctrl, cfg1;
361
362	cfg1 = isi_readl(isi, ISI_CFG1);
363	/* Enable irq: cxfr for the codec path, pxfr for the preview path */
364	isi_writel(isi, ISI_INTEN,
365			ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
366
367	/* Check if already in a frame */
368	if (!isi->enable_preview_path) {
369		if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
370			dev_err(isi->dev, "Already in frame handling.\n");
371			return;
372		}
373
374		isi_writel(isi, ISI_DMA_C_DSCR,
375				(u32)buffer->p_dma_desc->fbd_phys);
376		isi_writel(isi, ISI_DMA_C_CTRL,
377				ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
378		isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
379	} else {
380		isi_writel(isi, ISI_DMA_P_DSCR,
381				(u32)buffer->p_dma_desc->fbd_phys);
382		isi_writel(isi, ISI_DMA_P_CTRL,
383				ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
384		isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
385	}
386
387	cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
388	/* Enable linked list */
389	cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
390
391	/* Enable ISI */
392	ctrl = ISI_CTRL_EN;
393
394	if (!isi->enable_preview_path)
395		ctrl |= ISI_CTRL_CDC;
396
397	isi_writel(isi, ISI_CTRL, ctrl);
398	isi_writel(isi, ISI_CFG1, cfg1);
399}
400
401static void buffer_queue(struct vb2_buffer *vb)
402{
403	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
404	struct atmel_isi *isi = vb2_get_drv_priv(vb->vb2_queue);
405	struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
406	unsigned long flags = 0;
407
408	spin_lock_irqsave(&isi->irqlock, flags);
409	list_add_tail(&buf->list, &isi->video_buffer_list);
410
411	if (!isi->active) {
412		isi->active = buf;
413		if (vb2_is_streaming(vb->vb2_queue))
414			start_dma(isi, buf);
415	}
416	spin_unlock_irqrestore(&isi->irqlock, flags);
417}
418
419static int start_streaming(struct vb2_queue *vq, unsigned int count)
420{
421	struct atmel_isi *isi = vb2_get_drv_priv(vq);
422	struct frame_buffer *buf, *node;
423	int ret;
424
425	ret = pm_runtime_resume_and_get(isi->dev);
426	if (ret < 0)
427		return ret;
428
429	/* Enable stream on the sub device */
430	ret = v4l2_subdev_call(isi->entity.subdev, video, s_stream, 1);
431	if (ret && ret != -ENOIOCTLCMD) {
432		dev_err(isi->dev, "stream on failed in subdev\n");
433		goto err_start_stream;
434	}
435
436	/* Reset ISI */
437	ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
438	if (ret < 0) {
439		dev_err(isi->dev, "Reset ISI timed out\n");
440		goto err_reset;
441	}
442	/* Disable all interrupts */
443	isi_writel(isi, ISI_INTDIS, (u32)~0UL);
444
445	isi->sequence = 0;
446	configure_geometry(isi);
447
448	spin_lock_irq(&isi->irqlock);
449	/* Clear any pending interrupt */
450	isi_readl(isi, ISI_STATUS);
451
452	start_dma(isi, isi->active);
453	spin_unlock_irq(&isi->irqlock);
454
455	return 0;
456
457err_reset:
458	v4l2_subdev_call(isi->entity.subdev, video, s_stream, 0);
459
460err_start_stream:
461	pm_runtime_put(isi->dev);
462
463	spin_lock_irq(&isi->irqlock);
464	isi->active = NULL;
465	/* Release all active buffers */
466	list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
467		list_del_init(&buf->list);
468		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
469	}
470	spin_unlock_irq(&isi->irqlock);
471
472	return ret;
473}
474
475/* abort streaming and wait for last buffer */
476static void stop_streaming(struct vb2_queue *vq)
477{
478	struct atmel_isi *isi = vb2_get_drv_priv(vq);
479	struct frame_buffer *buf, *node;
480	int ret = 0;
481	unsigned long timeout;
482
483	/* Disable stream on the sub device */
484	ret = v4l2_subdev_call(isi->entity.subdev, video, s_stream, 0);
485	if (ret && ret != -ENOIOCTLCMD)
486		dev_err(isi->dev, "stream off failed in subdev\n");
487
488	spin_lock_irq(&isi->irqlock);
489	isi->active = NULL;
490	/* Release all active buffers */
491	list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
492		list_del_init(&buf->list);
493		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
494	}
495	spin_unlock_irq(&isi->irqlock);
496
497	if (!isi->enable_preview_path) {
498		timeout = jiffies + (FRAME_INTERVAL_MILLI_SEC * HZ) / 1000;
499		/* Wait until the end of the current frame. */
500		while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
501				time_before(jiffies, timeout))
502			msleep(1);
503
504		if (time_after(jiffies, timeout))
505			dev_err(isi->dev,
506				"Timeout waiting for finishing codec request\n");
507	}
508
509	/* Disable interrupts */
510	isi_writel(isi, ISI_INTDIS,
511			ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
512
513	/* Disable ISI and wait for it is done */
514	ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE);
515	if (ret < 0)
516		dev_err(isi->dev, "Disable ISI timed out\n");
517
518	pm_runtime_put(isi->dev);
519}
520
521static const struct vb2_ops isi_video_qops = {
522	.queue_setup		= queue_setup,
523	.buf_init		= buffer_init,
524	.buf_prepare		= buffer_prepare,
525	.buf_cleanup		= buffer_cleanup,
526	.buf_queue		= buffer_queue,
527	.start_streaming	= start_streaming,
528	.stop_streaming		= stop_streaming,
529	.wait_prepare		= vb2_ops_wait_prepare,
530	.wait_finish		= vb2_ops_wait_finish,
531};
532
533static int isi_g_fmt_vid_cap(struct file *file, void *priv,
534			      struct v4l2_format *fmt)
535{
536	struct atmel_isi *isi = video_drvdata(file);
537
538	*fmt = isi->fmt;
539
540	return 0;
541}
542
543static const struct isi_format *find_format_by_fourcc(struct atmel_isi *isi,
544						      unsigned int fourcc)
545{
546	unsigned int num_formats = isi->num_user_formats;
547	const struct isi_format *fmt;
548	unsigned int i;
549
550	for (i = 0; i < num_formats; i++) {
551		fmt = isi->user_formats[i];
552		if (fmt->fourcc == fourcc)
553			return fmt;
554	}
555
556	return NULL;
557}
558
559static void isi_try_fse(struct atmel_isi *isi, const struct isi_format *isi_fmt,
560			struct v4l2_subdev_state *sd_state)
561{
562	int ret;
563	struct v4l2_subdev_frame_size_enum fse = {
564		.code = isi_fmt->mbus_code,
565		.which = V4L2_SUBDEV_FORMAT_TRY,
566	};
567
568	ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size,
569			       sd_state, &fse);
570	/*
571	 * Attempt to obtain format size from subdev. If not available,
572	 * just use the maximum ISI can receive.
573	 */
574	if (ret) {
575		sd_state->pads->try_crop.width = MAX_SUPPORT_WIDTH;
576		sd_state->pads->try_crop.height = MAX_SUPPORT_HEIGHT;
577	} else {
578		sd_state->pads->try_crop.width = fse.max_width;
579		sd_state->pads->try_crop.height = fse.max_height;
580	}
581}
582
583static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f,
584		       const struct isi_format **current_fmt)
585{
586	const struct isi_format *isi_fmt;
587	struct v4l2_pix_format *pixfmt = &f->fmt.pix;
588	struct v4l2_subdev_pad_config pad_cfg = {};
589	struct v4l2_subdev_state pad_state = {
590		.pads = &pad_cfg,
591	};
592	struct v4l2_subdev_format format = {
593		.which = V4L2_SUBDEV_FORMAT_TRY,
594	};
595	int ret;
596
597	isi_fmt = find_format_by_fourcc(isi, pixfmt->pixelformat);
598	if (!isi_fmt) {
599		isi_fmt = isi->user_formats[isi->num_user_formats - 1];
600		pixfmt->pixelformat = isi_fmt->fourcc;
601	}
602
603	/* Limit to Atmel ISI hardware capabilities */
604	pixfmt->width = clamp(pixfmt->width, 0U, MAX_SUPPORT_WIDTH);
605	pixfmt->height = clamp(pixfmt->height, 0U, MAX_SUPPORT_HEIGHT);
606
607	v4l2_fill_mbus_format(&format.format, pixfmt, isi_fmt->mbus_code);
608
609	isi_try_fse(isi, isi_fmt, &pad_state);
610
611	ret = v4l2_subdev_call(isi->entity.subdev, pad, set_fmt,
612			       &pad_state, &format);
613	if (ret < 0)
614		return ret;
615
616	v4l2_fill_pix_format(pixfmt, &format.format);
617
618	pixfmt->field = V4L2_FIELD_NONE;
619	pixfmt->bytesperline = pixfmt->width * isi_fmt->bpp;
620	pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
621
622	if (current_fmt)
623		*current_fmt = isi_fmt;
624
625	return 0;
626}
627
628static int isi_set_fmt(struct atmel_isi *isi, struct v4l2_format *f)
629{
630	struct v4l2_subdev_format format = {
631		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
632	};
633	const struct isi_format *current_fmt;
634	int ret;
635
636	ret = isi_try_fmt(isi, f, &current_fmt);
637	if (ret)
638		return ret;
639
640	v4l2_fill_mbus_format(&format.format, &f->fmt.pix,
641			      current_fmt->mbus_code);
642	ret = v4l2_subdev_call(isi->entity.subdev, pad,
643			       set_fmt, NULL, &format);
644	if (ret < 0)
645		return ret;
646
647	isi->fmt = *f;
648	isi->current_fmt = current_fmt;
649
650	return 0;
651}
652
653static int isi_s_fmt_vid_cap(struct file *file, void *priv,
654			      struct v4l2_format *f)
655{
656	struct atmel_isi *isi = video_drvdata(file);
657
658	if (vb2_is_streaming(&isi->queue))
659		return -EBUSY;
660
661	return isi_set_fmt(isi, f);
662}
663
664static int isi_try_fmt_vid_cap(struct file *file, void *priv,
665				struct v4l2_format *f)
666{
667	struct atmel_isi *isi = video_drvdata(file);
668
669	return isi_try_fmt(isi, f, NULL);
670}
671
672static int isi_enum_fmt_vid_cap(struct file *file, void  *priv,
673				struct v4l2_fmtdesc *f)
674{
675	struct atmel_isi *isi = video_drvdata(file);
676
677	if (f->index >= isi->num_user_formats)
678		return -EINVAL;
679
680	f->pixelformat = isi->user_formats[f->index]->fourcc;
681	return 0;
682}
683
684static int isi_querycap(struct file *file, void *priv,
685			struct v4l2_capability *cap)
686{
687	strscpy(cap->driver, "atmel-isi", sizeof(cap->driver));
688	strscpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card));
689	strscpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info));
690	return 0;
691}
692
693static int isi_enum_input(struct file *file, void *priv,
694			   struct v4l2_input *i)
695{
696	if (i->index != 0)
697		return -EINVAL;
698
699	i->type = V4L2_INPUT_TYPE_CAMERA;
700	strscpy(i->name, "Camera", sizeof(i->name));
701	return 0;
702}
703
704static int isi_g_input(struct file *file, void *priv, unsigned int *i)
705{
706	*i = 0;
707	return 0;
708}
709
710static int isi_s_input(struct file *file, void *priv, unsigned int i)
711{
712	if (i > 0)
713		return -EINVAL;
714	return 0;
715}
716
717static int isi_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
718{
719	struct atmel_isi *isi = video_drvdata(file);
720
721	return v4l2_g_parm_cap(video_devdata(file), isi->entity.subdev, a);
722}
723
724static int isi_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
725{
726	struct atmel_isi *isi = video_drvdata(file);
727
728	return v4l2_s_parm_cap(video_devdata(file), isi->entity.subdev, a);
729}
730
731static int isi_enum_framesizes(struct file *file, void *fh,
732			       struct v4l2_frmsizeenum *fsize)
733{
734	struct atmel_isi *isi = video_drvdata(file);
735	const struct isi_format *isi_fmt;
736	struct v4l2_subdev_frame_size_enum fse = {
737		.index = fsize->index,
738		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
739	};
740	int ret;
741
742	isi_fmt = find_format_by_fourcc(isi, fsize->pixel_format);
743	if (!isi_fmt)
744		return -EINVAL;
745
746	fse.code = isi_fmt->mbus_code;
747
748	ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size,
749			       NULL, &fse);
750	if (ret)
751		return ret;
752
753	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
754	fsize->discrete.width = fse.max_width;
755	fsize->discrete.height = fse.max_height;
756
757	return 0;
758}
759
760static int isi_enum_frameintervals(struct file *file, void *fh,
761				    struct v4l2_frmivalenum *fival)
762{
763	struct atmel_isi *isi = video_drvdata(file);
764	const struct isi_format *isi_fmt;
765	struct v4l2_subdev_frame_interval_enum fie = {
766		.index = fival->index,
767		.width = fival->width,
768		.height = fival->height,
769		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
770	};
771	int ret;
772
773	isi_fmt = find_format_by_fourcc(isi, fival->pixel_format);
774	if (!isi_fmt)
775		return -EINVAL;
776
777	fie.code = isi_fmt->mbus_code;
778
779	ret = v4l2_subdev_call(isi->entity.subdev, pad,
780			       enum_frame_interval, NULL, &fie);
781	if (ret)
782		return ret;
783
784	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
785	fival->discrete = fie.interval;
786
787	return 0;
788}
789
790static int isi_camera_set_bus_param(struct atmel_isi *isi)
791{
792	u32 cfg1 = 0;
793	int ret;
794
795	/* set bus param for ISI */
796	if (isi->pdata.hsync_act_low)
797		cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
798	if (isi->pdata.vsync_act_low)
799		cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
800	if (isi->pdata.pclk_act_falling)
801		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
802	if (isi->pdata.has_emb_sync)
803		cfg1 |= ISI_CFG1_EMB_SYNC;
804	if (isi->pdata.full_mode)
805		cfg1 |= ISI_CFG1_FULL_MODE;
806
807	cfg1 |= ISI_CFG1_THMASK_BEATS_16;
808
809	/* Enable PM and peripheral clock before operate isi registers */
810	ret = pm_runtime_resume_and_get(isi->dev);
811	if (ret < 0)
812		return ret;
813
814	isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
815	isi_writel(isi, ISI_CFG1, cfg1);
816
817	pm_runtime_put(isi->dev);
818
819	return 0;
820}
821
822/* -----------------------------------------------------------------------*/
823static int atmel_isi_parse_dt(struct atmel_isi *isi,
824			struct platform_device *pdev)
825{
826	struct device_node *np = pdev->dev.of_node;
827	struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
828	int err;
829
830	/* Default settings for ISI */
831	isi->pdata.full_mode = 1;
832	isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
833
834	np = of_graph_get_next_endpoint(np, NULL);
835	if (!np) {
836		dev_err(&pdev->dev, "Could not find the endpoint\n");
837		return -EINVAL;
838	}
839
840	err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
841	of_node_put(np);
842	if (err) {
843		dev_err(&pdev->dev, "Could not parse the endpoint\n");
844		return err;
845	}
846
847	switch (ep.bus.parallel.bus_width) {
848	case 8:
849		isi->pdata.data_width_flags = ISI_DATAWIDTH_8;
850		break;
851	case 10:
852		isi->pdata.data_width_flags =
853				ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10;
854		break;
855	default:
856		dev_err(&pdev->dev, "Unsupported bus width: %d\n",
857				ep.bus.parallel.bus_width);
858		return -EINVAL;
859	}
860
861	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
862		isi->pdata.hsync_act_low = true;
863	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
864		isi->pdata.vsync_act_low = true;
865	if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
866		isi->pdata.pclk_act_falling = true;
867
868	if (ep.bus_type == V4L2_MBUS_BT656)
869		isi->pdata.has_emb_sync = true;
870
871	return 0;
872}
873
874static int isi_open(struct file *file)
875{
876	struct atmel_isi *isi = video_drvdata(file);
877	struct v4l2_subdev *sd = isi->entity.subdev;
878	int ret;
879
880	if (mutex_lock_interruptible(&isi->lock))
881		return -ERESTARTSYS;
882
883	ret = v4l2_fh_open(file);
884	if (ret < 0)
885		goto unlock;
886
887	if (!v4l2_fh_is_singular_file(file))
888		goto fh_rel;
889
890	ret = v4l2_subdev_call(sd, core, s_power, 1);
891	if (ret < 0 && ret != -ENOIOCTLCMD)
892		goto fh_rel;
893
894	ret = isi_set_fmt(isi, &isi->fmt);
895	if (ret)
896		v4l2_subdev_call(sd, core, s_power, 0);
897fh_rel:
898	if (ret)
899		v4l2_fh_release(file);
900unlock:
901	mutex_unlock(&isi->lock);
902	return ret;
903}
904
905static int isi_release(struct file *file)
906{
907	struct atmel_isi *isi = video_drvdata(file);
908	struct v4l2_subdev *sd = isi->entity.subdev;
909	bool fh_singular;
910	int ret;
911
912	mutex_lock(&isi->lock);
913
914	fh_singular = v4l2_fh_is_singular_file(file);
915
916	ret = _vb2_fop_release(file, NULL);
917
918	if (fh_singular)
919		v4l2_subdev_call(sd, core, s_power, 0);
920
921	mutex_unlock(&isi->lock);
922
923	return ret;
924}
925
926static const struct v4l2_ioctl_ops isi_ioctl_ops = {
927	.vidioc_querycap		= isi_querycap,
928
929	.vidioc_try_fmt_vid_cap		= isi_try_fmt_vid_cap,
930	.vidioc_g_fmt_vid_cap		= isi_g_fmt_vid_cap,
931	.vidioc_s_fmt_vid_cap		= isi_s_fmt_vid_cap,
932	.vidioc_enum_fmt_vid_cap	= isi_enum_fmt_vid_cap,
933
934	.vidioc_enum_input		= isi_enum_input,
935	.vidioc_g_input			= isi_g_input,
936	.vidioc_s_input			= isi_s_input,
937
938	.vidioc_g_parm			= isi_g_parm,
939	.vidioc_s_parm			= isi_s_parm,
940	.vidioc_enum_framesizes		= isi_enum_framesizes,
941	.vidioc_enum_frameintervals	= isi_enum_frameintervals,
942
943	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
944	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
945	.vidioc_querybuf		= vb2_ioctl_querybuf,
946	.vidioc_qbuf			= vb2_ioctl_qbuf,
947	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
948	.vidioc_expbuf			= vb2_ioctl_expbuf,
949	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
950	.vidioc_streamon		= vb2_ioctl_streamon,
951	.vidioc_streamoff		= vb2_ioctl_streamoff,
952
953	.vidioc_log_status		= v4l2_ctrl_log_status,
954	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
955	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
956};
957
958static const struct v4l2_file_operations isi_fops = {
959	.owner		= THIS_MODULE,
960	.unlocked_ioctl	= video_ioctl2,
961	.open		= isi_open,
962	.release	= isi_release,
963	.poll		= vb2_fop_poll,
964	.mmap		= vb2_fop_mmap,
965	.read		= vb2_fop_read,
966};
967
968static int isi_set_default_fmt(struct atmel_isi *isi)
969{
970	struct v4l2_format f = {
971		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
972		.fmt.pix = {
973			.width		= VGA_WIDTH,
974			.height		= VGA_HEIGHT,
975			.field		= V4L2_FIELD_NONE,
976			.pixelformat	= isi->user_formats[0]->fourcc,
977		},
978	};
979	int ret;
980
981	ret = isi_try_fmt(isi, &f, NULL);
982	if (ret)
983		return ret;
984	isi->current_fmt = isi->user_formats[0];
985	isi->fmt = f;
986	return 0;
987}
988
989static const struct isi_format isi_formats[] = {
990	{
991		.fourcc = V4L2_PIX_FMT_YUYV,
992		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
993		.bpp = 2,
994		.swap = ISI_CFG2_YCC_SWAP_DEFAULT,
995	}, {
996		.fourcc = V4L2_PIX_FMT_YUYV,
997		.mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
998		.bpp = 2,
999		.swap = ISI_CFG2_YCC_SWAP_MODE_1,
1000	}, {
1001		.fourcc = V4L2_PIX_FMT_YUYV,
1002		.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
1003		.bpp = 2,
1004		.swap = ISI_CFG2_YCC_SWAP_MODE_2,
1005	}, {
1006		.fourcc = V4L2_PIX_FMT_YUYV,
1007		.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
1008		.bpp = 2,
1009		.swap = ISI_CFG2_YCC_SWAP_MODE_3,
1010	}, {
1011		.fourcc = V4L2_PIX_FMT_RGB565,
1012		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
1013		.bpp = 2,
1014		.swap = ISI_CFG2_YCC_SWAP_MODE_2,
1015	}, {
1016		.fourcc = V4L2_PIX_FMT_RGB565,
1017		.mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
1018		.bpp = 2,
1019		.swap = ISI_CFG2_YCC_SWAP_MODE_3,
1020	}, {
1021		.fourcc = V4L2_PIX_FMT_RGB565,
1022		.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
1023		.bpp = 2,
1024		.swap = ISI_CFG2_YCC_SWAP_DEFAULT,
1025	}, {
1026		.fourcc = V4L2_PIX_FMT_RGB565,
1027		.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
1028		.bpp = 2,
1029		.swap = ISI_CFG2_YCC_SWAP_MODE_1,
1030	}, {
1031		.fourcc = V4L2_PIX_FMT_GREY,
1032		.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
1033		.bpp = 1,
1034		.swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
1035	}, {
1036		.fourcc = V4L2_PIX_FMT_Y16,
1037		.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
1038		.bpp = 2,
1039		.swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
1040	},
1041};
1042
1043static int isi_formats_init(struct atmel_isi *isi)
1044{
1045	const struct isi_format *isi_fmts[ARRAY_SIZE(isi_formats)];
1046	unsigned int num_fmts = 0, i, j;
1047	struct v4l2_subdev *subdev = isi->entity.subdev;
1048	struct v4l2_subdev_mbus_code_enum mbus_code = {
1049		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
1050	};
1051
1052	while (!v4l2_subdev_call(subdev, pad, enum_mbus_code,
1053				 NULL, &mbus_code)) {
1054		for (i = 0; i < ARRAY_SIZE(isi_formats); i++) {
1055			if (isi_formats[i].mbus_code != mbus_code.code)
1056				continue;
1057
1058			/* Code supported, have we got this fourcc yet? */
1059			for (j = 0; j < num_fmts; j++)
1060				if (isi_fmts[j]->fourcc == isi_formats[i].fourcc)
1061					/* Already available */
1062					break;
1063			if (j == num_fmts)
1064				/* new */
1065				isi_fmts[num_fmts++] = isi_formats + i;
1066		}
1067		mbus_code.index++;
1068	}
1069
1070	if (!num_fmts)
1071		return -ENXIO;
1072
1073	isi->num_user_formats = num_fmts;
1074	isi->user_formats = devm_kcalloc(isi->dev,
1075					 num_fmts, sizeof(struct isi_format *),
1076					 GFP_KERNEL);
1077	if (!isi->user_formats)
1078		return -ENOMEM;
1079
1080	memcpy(isi->user_formats, isi_fmts,
1081	       num_fmts * sizeof(struct isi_format *));
1082	isi->current_fmt = isi->user_formats[0];
1083
1084	return 0;
1085}
1086
1087static int isi_graph_notify_complete(struct v4l2_async_notifier *notifier)
1088{
1089	struct atmel_isi *isi = notifier_to_isi(notifier);
1090	int ret;
1091
1092	isi->vdev->ctrl_handler = isi->entity.subdev->ctrl_handler;
1093	ret = isi_formats_init(isi);
1094	if (ret) {
1095		dev_err(isi->dev, "No supported mediabus format found\n");
1096		return ret;
1097	}
1098	ret = isi_camera_set_bus_param(isi);
1099	if (ret) {
1100		dev_err(isi->dev, "Can't wake up device\n");
1101		return ret;
1102	}
1103
1104	ret = isi_set_default_fmt(isi);
1105	if (ret) {
1106		dev_err(isi->dev, "Could not set default format\n");
1107		return ret;
1108	}
1109
1110	ret = video_register_device(isi->vdev, VFL_TYPE_VIDEO, -1);
1111	if (ret) {
1112		dev_err(isi->dev, "Failed to register video device\n");
1113		return ret;
1114	}
1115
1116	dev_dbg(isi->dev, "Device registered as %s\n",
1117		video_device_node_name(isi->vdev));
1118	return 0;
1119}
1120
1121static void isi_graph_notify_unbind(struct v4l2_async_notifier *notifier,
1122				     struct v4l2_subdev *sd,
1123				     struct v4l2_async_connection *asd)
1124{
1125	struct atmel_isi *isi = notifier_to_isi(notifier);
1126
1127	dev_dbg(isi->dev, "Removing %s\n", video_device_node_name(isi->vdev));
1128
1129	/* Checks internally if vdev have been init or not */
1130	video_unregister_device(isi->vdev);
1131}
1132
1133static int isi_graph_notify_bound(struct v4l2_async_notifier *notifier,
1134				   struct v4l2_subdev *subdev,
1135				   struct v4l2_async_connection *asd)
1136{
1137	struct atmel_isi *isi = notifier_to_isi(notifier);
1138
1139	dev_dbg(isi->dev, "subdev %s bound\n", subdev->name);
1140
1141	isi->entity.subdev = subdev;
1142
1143	return 0;
1144}
1145
1146static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
1147	.bound = isi_graph_notify_bound,
1148	.unbind = isi_graph_notify_unbind,
1149	.complete = isi_graph_notify_complete,
1150};
1151
1152static int isi_graph_init(struct atmel_isi *isi)
1153{
1154	struct v4l2_async_connection *asd;
1155	struct device_node *ep;
1156	int ret;
1157
1158	ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
1159	if (!ep)
1160		return -EINVAL;
1161
1162	v4l2_async_nf_init(&isi->notifier, &isi->v4l2_dev);
1163
1164	asd = v4l2_async_nf_add_fwnode_remote(&isi->notifier,
1165					      of_fwnode_handle(ep),
1166					      struct v4l2_async_connection);
1167	of_node_put(ep);
1168
1169	if (IS_ERR(asd))
1170		return PTR_ERR(asd);
1171
1172	isi->notifier.ops = &isi_graph_notify_ops;
1173
1174	ret = v4l2_async_nf_register(&isi->notifier);
1175	if (ret < 0) {
1176		dev_err(isi->dev, "Notifier registration failed\n");
1177		v4l2_async_nf_cleanup(&isi->notifier);
1178		return ret;
1179	}
1180
1181	return 0;
1182}
1183
1184
1185static int atmel_isi_probe(struct platform_device *pdev)
1186{
1187	int irq;
1188	struct atmel_isi *isi;
1189	struct vb2_queue *q;
1190	int ret, i;
1191
1192	isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
1193	if (!isi)
1194		return -ENOMEM;
1195
1196	isi->pclk = devm_clk_get(&pdev->dev, "isi_clk");
1197	if (IS_ERR(isi->pclk))
1198		return PTR_ERR(isi->pclk);
1199
1200	ret = atmel_isi_parse_dt(isi, pdev);
1201	if (ret)
1202		return ret;
1203
1204	isi->active = NULL;
1205	isi->dev = &pdev->dev;
1206	mutex_init(&isi->lock);
1207	spin_lock_init(&isi->irqlock);
1208	INIT_LIST_HEAD(&isi->video_buffer_list);
1209	INIT_LIST_HEAD(&isi->dma_desc_head);
1210
1211	q = &isi->queue;
1212
1213	/* Initialize the top-level structure */
1214	ret = v4l2_device_register(&pdev->dev, &isi->v4l2_dev);
1215	if (ret)
1216		return ret;
1217
1218	isi->vdev = video_device_alloc();
1219	if (!isi->vdev) {
1220		ret = -ENOMEM;
1221		goto err_vdev_alloc;
1222	}
1223
1224	/* video node */
1225	isi->vdev->fops = &isi_fops;
1226	isi->vdev->v4l2_dev = &isi->v4l2_dev;
1227	isi->vdev->queue = &isi->queue;
1228	strscpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name));
1229	isi->vdev->release = video_device_release;
1230	isi->vdev->ioctl_ops = &isi_ioctl_ops;
1231	isi->vdev->lock = &isi->lock;
1232	isi->vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1233		V4L2_CAP_READWRITE;
1234	video_set_drvdata(isi->vdev, isi);
1235
1236	/* buffer queue */
1237	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1238	q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
1239	q->lock = &isi->lock;
1240	q->drv_priv = isi;
1241	q->buf_struct_size = sizeof(struct frame_buffer);
1242	q->ops = &isi_video_qops;
1243	q->mem_ops = &vb2_dma_contig_memops;
1244	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1245	q->min_buffers_needed = 2;
1246	q->dev = &pdev->dev;
1247
1248	ret = vb2_queue_init(q);
1249	if (ret < 0) {
1250		dev_err(&pdev->dev, "failed to initialize VB2 queue\n");
1251		goto err_vb2_queue;
1252	}
1253	isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
1254				sizeof(struct fbd) * VIDEO_MAX_FRAME,
1255				&isi->fb_descriptors_phys,
1256				GFP_KERNEL);
1257	if (!isi->p_fb_descriptors) {
1258		dev_err(&pdev->dev, "Can't allocate descriptors!\n");
1259		ret = -ENOMEM;
1260		goto err_dma_alloc;
1261	}
1262
1263	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1264		isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i;
1265		isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys +
1266					i * sizeof(struct fbd);
1267		list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
1268	}
1269
1270	isi->regs = devm_platform_ioremap_resource(pdev, 0);
1271	if (IS_ERR(isi->regs)) {
1272		ret = PTR_ERR(isi->regs);
1273		goto err_ioremap;
1274	}
1275
1276	if (isi->pdata.data_width_flags & ISI_DATAWIDTH_8)
1277		isi->width_flags = 1 << 7;
1278	if (isi->pdata.data_width_flags & ISI_DATAWIDTH_10)
1279		isi->width_flags |= 1 << 9;
1280
1281	irq = platform_get_irq(pdev, 0);
1282	if (irq < 0) {
1283		ret = irq;
1284		goto err_req_irq;
1285	}
1286
1287	ret = devm_request_irq(&pdev->dev, irq, isi_interrupt, 0, "isi", isi);
1288	if (ret) {
1289		dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1290		goto err_req_irq;
1291	}
1292	isi->irq = irq;
1293
1294	ret = isi_graph_init(isi);
1295	if (ret < 0)
1296		goto err_req_irq;
1297
1298	pm_suspend_ignore_children(&pdev->dev, true);
1299	pm_runtime_enable(&pdev->dev);
1300	platform_set_drvdata(pdev, isi);
1301	return 0;
1302
1303err_req_irq:
1304err_ioremap:
1305	dma_free_coherent(&pdev->dev,
1306			sizeof(struct fbd) * VIDEO_MAX_FRAME,
1307			isi->p_fb_descriptors,
1308			isi->fb_descriptors_phys);
1309err_dma_alloc:
1310err_vb2_queue:
1311	video_device_release(isi->vdev);
1312err_vdev_alloc:
1313	v4l2_device_unregister(&isi->v4l2_dev);
1314
1315	return ret;
1316}
1317
1318static void atmel_isi_remove(struct platform_device *pdev)
1319{
1320	struct atmel_isi *isi = platform_get_drvdata(pdev);
1321
1322	dma_free_coherent(&pdev->dev,
1323			sizeof(struct fbd) * VIDEO_MAX_FRAME,
1324			isi->p_fb_descriptors,
1325			isi->fb_descriptors_phys);
1326	pm_runtime_disable(&pdev->dev);
1327	v4l2_async_nf_unregister(&isi->notifier);
1328	v4l2_async_nf_cleanup(&isi->notifier);
1329	v4l2_device_unregister(&isi->v4l2_dev);
1330}
1331
1332#ifdef CONFIG_PM
1333static int atmel_isi_runtime_suspend(struct device *dev)
1334{
1335	struct atmel_isi *isi = dev_get_drvdata(dev);
1336
1337	clk_disable_unprepare(isi->pclk);
1338
1339	return 0;
1340}
1341static int atmel_isi_runtime_resume(struct device *dev)
1342{
1343	struct atmel_isi *isi = dev_get_drvdata(dev);
1344
1345	return clk_prepare_enable(isi->pclk);
1346}
1347#endif /* CONFIG_PM */
1348
1349static const struct dev_pm_ops atmel_isi_dev_pm_ops = {
1350	SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend,
1351				atmel_isi_runtime_resume, NULL)
1352};
1353
1354static const struct of_device_id atmel_isi_of_match[] = {
1355	{ .compatible = "atmel,at91sam9g45-isi" },
1356	{ }
1357};
1358MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
1359
1360static struct platform_driver atmel_isi_driver = {
1361	.driver		= {
1362		.name = "atmel_isi",
1363		.of_match_table = of_match_ptr(atmel_isi_of_match),
1364		.pm	= &atmel_isi_dev_pm_ops,
1365	},
1366	.probe		= atmel_isi_probe,
1367	.remove_new	= atmel_isi_remove,
1368};
1369
1370module_platform_driver(atmel_isi_driver);
1371
1372MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1373MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1374MODULE_LICENSE("GPL");
1375