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	struct v4l2_rect *try_crop =
563		v4l2_subdev_state_get_crop(sd_state, 0);
564	struct v4l2_subdev_frame_size_enum fse = {
565		.code = isi_fmt->mbus_code,
566		.which = V4L2_SUBDEV_FORMAT_TRY,
567	};
568	int ret;
569
570	ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size,
571			       sd_state, &fse);
572	/*
573	 * Attempt to obtain format size from subdev. If not available,
574	 * just use the maximum ISI can receive.
575	 */
576	if (ret) {
577		try_crop->width = MAX_SUPPORT_WIDTH;
578		try_crop->height = MAX_SUPPORT_HEIGHT;
579	} else {
580		try_crop->width = fse.max_width;
581		try_crop->height = fse.max_height;
582	}
583}
584
585static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f,
586		       const struct isi_format **current_fmt)
587{
588	const struct isi_format *isi_fmt;
589	struct v4l2_pix_format *pixfmt = &f->fmt.pix;
590	struct v4l2_subdev_pad_config pad_cfg = {};
591	struct v4l2_subdev_state pad_state = {
592		.sd = isi->entity.subdev,
593		.pads = &pad_cfg,
594	};
595	struct v4l2_subdev_format format = {
596		.which = V4L2_SUBDEV_FORMAT_TRY,
597	};
598	int ret;
599
600	isi_fmt = find_format_by_fourcc(isi, pixfmt->pixelformat);
601	if (!isi_fmt) {
602		isi_fmt = isi->user_formats[isi->num_user_formats - 1];
603		pixfmt->pixelformat = isi_fmt->fourcc;
604	}
605
606	/* Limit to Atmel ISI hardware capabilities */
607	pixfmt->width = clamp(pixfmt->width, 0U, MAX_SUPPORT_WIDTH);
608	pixfmt->height = clamp(pixfmt->height, 0U, MAX_SUPPORT_HEIGHT);
609
610	v4l2_fill_mbus_format(&format.format, pixfmt, isi_fmt->mbus_code);
611
612	isi_try_fse(isi, isi_fmt, &pad_state);
613
614	ret = v4l2_subdev_call(isi->entity.subdev, pad, set_fmt,
615			       &pad_state, &format);
616	if (ret < 0)
617		return ret;
618
619	v4l2_fill_pix_format(pixfmt, &format.format);
620
621	pixfmt->field = V4L2_FIELD_NONE;
622	pixfmt->bytesperline = pixfmt->width * isi_fmt->bpp;
623	pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
624
625	if (current_fmt)
626		*current_fmt = isi_fmt;
627
628	return 0;
629}
630
631static int isi_set_fmt(struct atmel_isi *isi, struct v4l2_format *f)
632{
633	struct v4l2_subdev_format format = {
634		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
635	};
636	const struct isi_format *current_fmt;
637	int ret;
638
639	ret = isi_try_fmt(isi, f, &current_fmt);
640	if (ret)
641		return ret;
642
643	v4l2_fill_mbus_format(&format.format, &f->fmt.pix,
644			      current_fmt->mbus_code);
645	ret = v4l2_subdev_call(isi->entity.subdev, pad,
646			       set_fmt, NULL, &format);
647	if (ret < 0)
648		return ret;
649
650	isi->fmt = *f;
651	isi->current_fmt = current_fmt;
652
653	return 0;
654}
655
656static int isi_s_fmt_vid_cap(struct file *file, void *priv,
657			      struct v4l2_format *f)
658{
659	struct atmel_isi *isi = video_drvdata(file);
660
661	if (vb2_is_streaming(&isi->queue))
662		return -EBUSY;
663
664	return isi_set_fmt(isi, f);
665}
666
667static int isi_try_fmt_vid_cap(struct file *file, void *priv,
668				struct v4l2_format *f)
669{
670	struct atmel_isi *isi = video_drvdata(file);
671
672	return isi_try_fmt(isi, f, NULL);
673}
674
675static int isi_enum_fmt_vid_cap(struct file *file, void  *priv,
676				struct v4l2_fmtdesc *f)
677{
678	struct atmel_isi *isi = video_drvdata(file);
679
680	if (f->index >= isi->num_user_formats)
681		return -EINVAL;
682
683	f->pixelformat = isi->user_formats[f->index]->fourcc;
684	return 0;
685}
686
687static int isi_querycap(struct file *file, void *priv,
688			struct v4l2_capability *cap)
689{
690	strscpy(cap->driver, "atmel-isi", sizeof(cap->driver));
691	strscpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card));
692	strscpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info));
693	return 0;
694}
695
696static int isi_enum_input(struct file *file, void *priv,
697			   struct v4l2_input *i)
698{
699	if (i->index != 0)
700		return -EINVAL;
701
702	i->type = V4L2_INPUT_TYPE_CAMERA;
703	strscpy(i->name, "Camera", sizeof(i->name));
704	return 0;
705}
706
707static int isi_g_input(struct file *file, void *priv, unsigned int *i)
708{
709	*i = 0;
710	return 0;
711}
712
713static int isi_s_input(struct file *file, void *priv, unsigned int i)
714{
715	if (i > 0)
716		return -EINVAL;
717	return 0;
718}
719
720static int isi_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
721{
722	struct atmel_isi *isi = video_drvdata(file);
723
724	return v4l2_g_parm_cap(video_devdata(file), isi->entity.subdev, a);
725}
726
727static int isi_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
728{
729	struct atmel_isi *isi = video_drvdata(file);
730
731	return v4l2_s_parm_cap(video_devdata(file), isi->entity.subdev, a);
732}
733
734static int isi_enum_framesizes(struct file *file, void *fh,
735			       struct v4l2_frmsizeenum *fsize)
736{
737	struct atmel_isi *isi = video_drvdata(file);
738	const struct isi_format *isi_fmt;
739	struct v4l2_subdev_frame_size_enum fse = {
740		.index = fsize->index,
741		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
742	};
743	int ret;
744
745	isi_fmt = find_format_by_fourcc(isi, fsize->pixel_format);
746	if (!isi_fmt)
747		return -EINVAL;
748
749	fse.code = isi_fmt->mbus_code;
750
751	ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size,
752			       NULL, &fse);
753	if (ret)
754		return ret;
755
756	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
757	fsize->discrete.width = fse.max_width;
758	fsize->discrete.height = fse.max_height;
759
760	return 0;
761}
762
763static int isi_enum_frameintervals(struct file *file, void *fh,
764				    struct v4l2_frmivalenum *fival)
765{
766	struct atmel_isi *isi = video_drvdata(file);
767	const struct isi_format *isi_fmt;
768	struct v4l2_subdev_frame_interval_enum fie = {
769		.index = fival->index,
770		.width = fival->width,
771		.height = fival->height,
772		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
773	};
774	int ret;
775
776	isi_fmt = find_format_by_fourcc(isi, fival->pixel_format);
777	if (!isi_fmt)
778		return -EINVAL;
779
780	fie.code = isi_fmt->mbus_code;
781
782	ret = v4l2_subdev_call(isi->entity.subdev, pad,
783			       enum_frame_interval, NULL, &fie);
784	if (ret)
785		return ret;
786
787	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
788	fival->discrete = fie.interval;
789
790	return 0;
791}
792
793static int isi_camera_set_bus_param(struct atmel_isi *isi)
794{
795	u32 cfg1 = 0;
796	int ret;
797
798	/* set bus param for ISI */
799	if (isi->pdata.hsync_act_low)
800		cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
801	if (isi->pdata.vsync_act_low)
802		cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
803	if (isi->pdata.pclk_act_falling)
804		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
805	if (isi->pdata.has_emb_sync)
806		cfg1 |= ISI_CFG1_EMB_SYNC;
807	if (isi->pdata.full_mode)
808		cfg1 |= ISI_CFG1_FULL_MODE;
809
810	cfg1 |= ISI_CFG1_THMASK_BEATS_16;
811
812	/* Enable PM and peripheral clock before operate isi registers */
813	ret = pm_runtime_resume_and_get(isi->dev);
814	if (ret < 0)
815		return ret;
816
817	isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
818	isi_writel(isi, ISI_CFG1, cfg1);
819
820	pm_runtime_put(isi->dev);
821
822	return 0;
823}
824
825/* -----------------------------------------------------------------------*/
826static int atmel_isi_parse_dt(struct atmel_isi *isi,
827			struct platform_device *pdev)
828{
829	struct device_node *np = pdev->dev.of_node;
830	struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
831	int err;
832
833	/* Default settings for ISI */
834	isi->pdata.full_mode = 1;
835	isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
836
837	np = of_graph_get_endpoint_by_regs(np, 0, -1);
838	if (!np) {
839		dev_err(&pdev->dev, "Could not find the endpoint\n");
840		return -EINVAL;
841	}
842
843	err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
844	of_node_put(np);
845	if (err) {
846		dev_err(&pdev->dev, "Could not parse the endpoint\n");
847		return err;
848	}
849
850	switch (ep.bus.parallel.bus_width) {
851	case 8:
852		isi->pdata.data_width_flags = ISI_DATAWIDTH_8;
853		break;
854	case 10:
855		isi->pdata.data_width_flags =
856				ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10;
857		break;
858	default:
859		dev_err(&pdev->dev, "Unsupported bus width: %d\n",
860				ep.bus.parallel.bus_width);
861		return -EINVAL;
862	}
863
864	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
865		isi->pdata.hsync_act_low = true;
866	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
867		isi->pdata.vsync_act_low = true;
868	if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
869		isi->pdata.pclk_act_falling = true;
870
871	if (ep.bus_type == V4L2_MBUS_BT656)
872		isi->pdata.has_emb_sync = true;
873
874	return 0;
875}
876
877static int isi_open(struct file *file)
878{
879	struct atmel_isi *isi = video_drvdata(file);
880	struct v4l2_subdev *sd = isi->entity.subdev;
881	int ret;
882
883	if (mutex_lock_interruptible(&isi->lock))
884		return -ERESTARTSYS;
885
886	ret = v4l2_fh_open(file);
887	if (ret < 0)
888		goto unlock;
889
890	if (!v4l2_fh_is_singular_file(file))
891		goto fh_rel;
892
893	ret = v4l2_subdev_call(sd, core, s_power, 1);
894	if (ret < 0 && ret != -ENOIOCTLCMD)
895		goto fh_rel;
896
897	ret = isi_set_fmt(isi, &isi->fmt);
898	if (ret)
899		v4l2_subdev_call(sd, core, s_power, 0);
900fh_rel:
901	if (ret)
902		v4l2_fh_release(file);
903unlock:
904	mutex_unlock(&isi->lock);
905	return ret;
906}
907
908static int isi_release(struct file *file)
909{
910	struct atmel_isi *isi = video_drvdata(file);
911	struct v4l2_subdev *sd = isi->entity.subdev;
912	bool fh_singular;
913	int ret;
914
915	mutex_lock(&isi->lock);
916
917	fh_singular = v4l2_fh_is_singular_file(file);
918
919	ret = _vb2_fop_release(file, NULL);
920
921	if (fh_singular)
922		v4l2_subdev_call(sd, core, s_power, 0);
923
924	mutex_unlock(&isi->lock);
925
926	return ret;
927}
928
929static const struct v4l2_ioctl_ops isi_ioctl_ops = {
930	.vidioc_querycap		= isi_querycap,
931
932	.vidioc_try_fmt_vid_cap		= isi_try_fmt_vid_cap,
933	.vidioc_g_fmt_vid_cap		= isi_g_fmt_vid_cap,
934	.vidioc_s_fmt_vid_cap		= isi_s_fmt_vid_cap,
935	.vidioc_enum_fmt_vid_cap	= isi_enum_fmt_vid_cap,
936
937	.vidioc_enum_input		= isi_enum_input,
938	.vidioc_g_input			= isi_g_input,
939	.vidioc_s_input			= isi_s_input,
940
941	.vidioc_g_parm			= isi_g_parm,
942	.vidioc_s_parm			= isi_s_parm,
943	.vidioc_enum_framesizes		= isi_enum_framesizes,
944	.vidioc_enum_frameintervals	= isi_enum_frameintervals,
945
946	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
947	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
948	.vidioc_querybuf		= vb2_ioctl_querybuf,
949	.vidioc_qbuf			= vb2_ioctl_qbuf,
950	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
951	.vidioc_expbuf			= vb2_ioctl_expbuf,
952	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
953	.vidioc_streamon		= vb2_ioctl_streamon,
954	.vidioc_streamoff		= vb2_ioctl_streamoff,
955
956	.vidioc_log_status		= v4l2_ctrl_log_status,
957	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
958	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
959};
960
961static const struct v4l2_file_operations isi_fops = {
962	.owner		= THIS_MODULE,
963	.unlocked_ioctl	= video_ioctl2,
964	.open		= isi_open,
965	.release	= isi_release,
966	.poll		= vb2_fop_poll,
967	.mmap		= vb2_fop_mmap,
968	.read		= vb2_fop_read,
969};
970
971static int isi_set_default_fmt(struct atmel_isi *isi)
972{
973	struct v4l2_format f = {
974		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
975		.fmt.pix = {
976			.width		= VGA_WIDTH,
977			.height		= VGA_HEIGHT,
978			.field		= V4L2_FIELD_NONE,
979			.pixelformat	= isi->user_formats[0]->fourcc,
980		},
981	};
982	int ret;
983
984	ret = isi_try_fmt(isi, &f, NULL);
985	if (ret)
986		return ret;
987	isi->current_fmt = isi->user_formats[0];
988	isi->fmt = f;
989	return 0;
990}
991
992static const struct isi_format isi_formats[] = {
993	{
994		.fourcc = V4L2_PIX_FMT_YUYV,
995		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
996		.bpp = 2,
997		.swap = ISI_CFG2_YCC_SWAP_DEFAULT,
998	}, {
999		.fourcc = V4L2_PIX_FMT_YUYV,
1000		.mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
1001		.bpp = 2,
1002		.swap = ISI_CFG2_YCC_SWAP_MODE_1,
1003	}, {
1004		.fourcc = V4L2_PIX_FMT_YUYV,
1005		.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
1006		.bpp = 2,
1007		.swap = ISI_CFG2_YCC_SWAP_MODE_2,
1008	}, {
1009		.fourcc = V4L2_PIX_FMT_YUYV,
1010		.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
1011		.bpp = 2,
1012		.swap = ISI_CFG2_YCC_SWAP_MODE_3,
1013	}, {
1014		.fourcc = V4L2_PIX_FMT_RGB565,
1015		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
1016		.bpp = 2,
1017		.swap = ISI_CFG2_YCC_SWAP_MODE_2,
1018	}, {
1019		.fourcc = V4L2_PIX_FMT_RGB565,
1020		.mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
1021		.bpp = 2,
1022		.swap = ISI_CFG2_YCC_SWAP_MODE_3,
1023	}, {
1024		.fourcc = V4L2_PIX_FMT_RGB565,
1025		.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
1026		.bpp = 2,
1027		.swap = ISI_CFG2_YCC_SWAP_DEFAULT,
1028	}, {
1029		.fourcc = V4L2_PIX_FMT_RGB565,
1030		.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
1031		.bpp = 2,
1032		.swap = ISI_CFG2_YCC_SWAP_MODE_1,
1033	}, {
1034		.fourcc = V4L2_PIX_FMT_GREY,
1035		.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
1036		.bpp = 1,
1037		.swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
1038	}, {
1039		.fourcc = V4L2_PIX_FMT_Y16,
1040		.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
1041		.bpp = 2,
1042		.swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
1043	},
1044};
1045
1046static int isi_formats_init(struct atmel_isi *isi)
1047{
1048	const struct isi_format *isi_fmts[ARRAY_SIZE(isi_formats)];
1049	unsigned int num_fmts = 0, i, j;
1050	struct v4l2_subdev *subdev = isi->entity.subdev;
1051	struct v4l2_subdev_mbus_code_enum mbus_code = {
1052		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
1053	};
1054
1055	while (!v4l2_subdev_call(subdev, pad, enum_mbus_code,
1056				 NULL, &mbus_code)) {
1057		for (i = 0; i < ARRAY_SIZE(isi_formats); i++) {
1058			if (isi_formats[i].mbus_code != mbus_code.code)
1059				continue;
1060
1061			/* Code supported, have we got this fourcc yet? */
1062			for (j = 0; j < num_fmts; j++)
1063				if (isi_fmts[j]->fourcc == isi_formats[i].fourcc)
1064					/* Already available */
1065					break;
1066			if (j == num_fmts)
1067				/* new */
1068				isi_fmts[num_fmts++] = isi_formats + i;
1069		}
1070		mbus_code.index++;
1071	}
1072
1073	if (!num_fmts)
1074		return -ENXIO;
1075
1076	isi->num_user_formats = num_fmts;
1077	isi->user_formats = devm_kcalloc(isi->dev,
1078					 num_fmts, sizeof(struct isi_format *),
1079					 GFP_KERNEL);
1080	if (!isi->user_formats)
1081		return -ENOMEM;
1082
1083	memcpy(isi->user_formats, isi_fmts,
1084	       num_fmts * sizeof(struct isi_format *));
1085	isi->current_fmt = isi->user_formats[0];
1086
1087	return 0;
1088}
1089
1090static int isi_graph_notify_complete(struct v4l2_async_notifier *notifier)
1091{
1092	struct atmel_isi *isi = notifier_to_isi(notifier);
1093	int ret;
1094
1095	isi->vdev->ctrl_handler = isi->entity.subdev->ctrl_handler;
1096	ret = isi_formats_init(isi);
1097	if (ret) {
1098		dev_err(isi->dev, "No supported mediabus format found\n");
1099		return ret;
1100	}
1101	ret = isi_camera_set_bus_param(isi);
1102	if (ret) {
1103		dev_err(isi->dev, "Can't wake up device\n");
1104		return ret;
1105	}
1106
1107	ret = isi_set_default_fmt(isi);
1108	if (ret) {
1109		dev_err(isi->dev, "Could not set default format\n");
1110		return ret;
1111	}
1112
1113	ret = video_register_device(isi->vdev, VFL_TYPE_VIDEO, -1);
1114	if (ret) {
1115		dev_err(isi->dev, "Failed to register video device\n");
1116		return ret;
1117	}
1118
1119	dev_dbg(isi->dev, "Device registered as %s\n",
1120		video_device_node_name(isi->vdev));
1121	return 0;
1122}
1123
1124static void isi_graph_notify_unbind(struct v4l2_async_notifier *notifier,
1125				     struct v4l2_subdev *sd,
1126				     struct v4l2_async_connection *asd)
1127{
1128	struct atmel_isi *isi = notifier_to_isi(notifier);
1129
1130	dev_dbg(isi->dev, "Removing %s\n", video_device_node_name(isi->vdev));
1131
1132	/* Checks internally if vdev have been init or not */
1133	video_unregister_device(isi->vdev);
1134}
1135
1136static int isi_graph_notify_bound(struct v4l2_async_notifier *notifier,
1137				   struct v4l2_subdev *subdev,
1138				   struct v4l2_async_connection *asd)
1139{
1140	struct atmel_isi *isi = notifier_to_isi(notifier);
1141
1142	dev_dbg(isi->dev, "subdev %s bound\n", subdev->name);
1143
1144	isi->entity.subdev = subdev;
1145
1146	return 0;
1147}
1148
1149static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
1150	.bound = isi_graph_notify_bound,
1151	.unbind = isi_graph_notify_unbind,
1152	.complete = isi_graph_notify_complete,
1153};
1154
1155static int isi_graph_init(struct atmel_isi *isi)
1156{
1157	struct v4l2_async_connection *asd;
1158	struct device_node *ep;
1159	int ret;
1160
1161	ep = of_graph_get_endpoint_by_regs(isi->dev->of_node, 0, -1);
1162	if (!ep)
1163		return -EINVAL;
1164
1165	v4l2_async_nf_init(&isi->notifier, &isi->v4l2_dev);
1166
1167	asd = v4l2_async_nf_add_fwnode_remote(&isi->notifier,
1168					      of_fwnode_handle(ep),
1169					      struct v4l2_async_connection);
1170	of_node_put(ep);
1171
1172	if (IS_ERR(asd))
1173		return PTR_ERR(asd);
1174
1175	isi->notifier.ops = &isi_graph_notify_ops;
1176
1177	ret = v4l2_async_nf_register(&isi->notifier);
1178	if (ret < 0) {
1179		dev_err(isi->dev, "Notifier registration failed\n");
1180		v4l2_async_nf_cleanup(&isi->notifier);
1181		return ret;
1182	}
1183
1184	return 0;
1185}
1186
1187
1188static int atmel_isi_probe(struct platform_device *pdev)
1189{
1190	int irq;
1191	struct atmel_isi *isi;
1192	struct vb2_queue *q;
1193	int ret, i;
1194
1195	isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
1196	if (!isi)
1197		return -ENOMEM;
1198
1199	isi->pclk = devm_clk_get(&pdev->dev, "isi_clk");
1200	if (IS_ERR(isi->pclk))
1201		return PTR_ERR(isi->pclk);
1202
1203	ret = atmel_isi_parse_dt(isi, pdev);
1204	if (ret)
1205		return ret;
1206
1207	isi->active = NULL;
1208	isi->dev = &pdev->dev;
1209	mutex_init(&isi->lock);
1210	spin_lock_init(&isi->irqlock);
1211	INIT_LIST_HEAD(&isi->video_buffer_list);
1212	INIT_LIST_HEAD(&isi->dma_desc_head);
1213
1214	q = &isi->queue;
1215
1216	/* Initialize the top-level structure */
1217	ret = v4l2_device_register(&pdev->dev, &isi->v4l2_dev);
1218	if (ret)
1219		return ret;
1220
1221	isi->vdev = video_device_alloc();
1222	if (!isi->vdev) {
1223		ret = -ENOMEM;
1224		goto err_vdev_alloc;
1225	}
1226
1227	/* video node */
1228	isi->vdev->fops = &isi_fops;
1229	isi->vdev->v4l2_dev = &isi->v4l2_dev;
1230	isi->vdev->queue = &isi->queue;
1231	strscpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name));
1232	isi->vdev->release = video_device_release;
1233	isi->vdev->ioctl_ops = &isi_ioctl_ops;
1234	isi->vdev->lock = &isi->lock;
1235	isi->vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1236		V4L2_CAP_READWRITE;
1237	video_set_drvdata(isi->vdev, isi);
1238
1239	/* buffer queue */
1240	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1241	q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
1242	q->lock = &isi->lock;
1243	q->drv_priv = isi;
1244	q->buf_struct_size = sizeof(struct frame_buffer);
1245	q->ops = &isi_video_qops;
1246	q->mem_ops = &vb2_dma_contig_memops;
1247	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1248	q->min_queued_buffers = 2;
1249	q->dev = &pdev->dev;
1250
1251	ret = vb2_queue_init(q);
1252	if (ret < 0) {
1253		dev_err(&pdev->dev, "failed to initialize VB2 queue\n");
1254		goto err_vb2_queue;
1255	}
1256	isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
1257				sizeof(struct fbd) * VIDEO_MAX_FRAME,
1258				&isi->fb_descriptors_phys,
1259				GFP_KERNEL);
1260	if (!isi->p_fb_descriptors) {
1261		dev_err(&pdev->dev, "Can't allocate descriptors!\n");
1262		ret = -ENOMEM;
1263		goto err_dma_alloc;
1264	}
1265
1266	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1267		isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i;
1268		isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys +
1269					i * sizeof(struct fbd);
1270		list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
1271	}
1272
1273	isi->regs = devm_platform_ioremap_resource(pdev, 0);
1274	if (IS_ERR(isi->regs)) {
1275		ret = PTR_ERR(isi->regs);
1276		goto err_ioremap;
1277	}
1278
1279	if (isi->pdata.data_width_flags & ISI_DATAWIDTH_8)
1280		isi->width_flags = 1 << 7;
1281	if (isi->pdata.data_width_flags & ISI_DATAWIDTH_10)
1282		isi->width_flags |= 1 << 9;
1283
1284	irq = platform_get_irq(pdev, 0);
1285	if (irq < 0) {
1286		ret = irq;
1287		goto err_req_irq;
1288	}
1289
1290	ret = devm_request_irq(&pdev->dev, irq, isi_interrupt, 0, "isi", isi);
1291	if (ret) {
1292		dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1293		goto err_req_irq;
1294	}
1295	isi->irq = irq;
1296
1297	ret = isi_graph_init(isi);
1298	if (ret < 0)
1299		goto err_req_irq;
1300
1301	pm_suspend_ignore_children(&pdev->dev, true);
1302	pm_runtime_enable(&pdev->dev);
1303	platform_set_drvdata(pdev, isi);
1304	return 0;
1305
1306err_req_irq:
1307err_ioremap:
1308	dma_free_coherent(&pdev->dev,
1309			sizeof(struct fbd) * VIDEO_MAX_FRAME,
1310			isi->p_fb_descriptors,
1311			isi->fb_descriptors_phys);
1312err_dma_alloc:
1313err_vb2_queue:
1314	video_device_release(isi->vdev);
1315err_vdev_alloc:
1316	v4l2_device_unregister(&isi->v4l2_dev);
1317
1318	return ret;
1319}
1320
1321static void atmel_isi_remove(struct platform_device *pdev)
1322{
1323	struct atmel_isi *isi = platform_get_drvdata(pdev);
1324
1325	dma_free_coherent(&pdev->dev,
1326			sizeof(struct fbd) * VIDEO_MAX_FRAME,
1327			isi->p_fb_descriptors,
1328			isi->fb_descriptors_phys);
1329	pm_runtime_disable(&pdev->dev);
1330	v4l2_async_nf_unregister(&isi->notifier);
1331	v4l2_async_nf_cleanup(&isi->notifier);
1332	v4l2_device_unregister(&isi->v4l2_dev);
1333}
1334
1335#ifdef CONFIG_PM
1336static int atmel_isi_runtime_suspend(struct device *dev)
1337{
1338	struct atmel_isi *isi = dev_get_drvdata(dev);
1339
1340	clk_disable_unprepare(isi->pclk);
1341
1342	return 0;
1343}
1344static int atmel_isi_runtime_resume(struct device *dev)
1345{
1346	struct atmel_isi *isi = dev_get_drvdata(dev);
1347
1348	return clk_prepare_enable(isi->pclk);
1349}
1350#endif /* CONFIG_PM */
1351
1352static const struct dev_pm_ops atmel_isi_dev_pm_ops = {
1353	SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend,
1354				atmel_isi_runtime_resume, NULL)
1355};
1356
1357static const struct of_device_id atmel_isi_of_match[] = {
1358	{ .compatible = "atmel,at91sam9g45-isi" },
1359	{ }
1360};
1361MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
1362
1363static struct platform_driver atmel_isi_driver = {
1364	.driver		= {
1365		.name = "atmel_isi",
1366		.of_match_table = of_match_ptr(atmel_isi_of_match),
1367		.pm	= &atmel_isi_dev_pm_ops,
1368	},
1369	.probe		= atmel_isi_probe,
1370	.remove_new	= atmel_isi_remove,
1371};
1372
1373module_platform_driver(atmel_isi_driver);
1374
1375MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1376MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1377MODULE_LICENSE("GPL");
1378