1/*
2 * Copyright (c) 2011 Atmel Corporation
3 * Josh Wu, <josh.wu@atmel.com>
4 *
5 * Based on previous work by Lars Haring, <lars.haring@atmel.com>
6 * and Sedji Gaouaou
7 * Based on the bttv driver for Bt848 with respective copyright holders
8 *
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.
12 */
13
14#include <linux/clk.h>
15#include <linux/completion.h>
16#include <linux/delay.h>
17#include <linux/fs.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/pm_runtime.h>
24#include <linux/slab.h>
25
26#include <media/soc_camera.h>
27#include <media/soc_mediabus.h>
28#include <media/v4l2-of.h>
29#include <media/videobuf2-dma-contig.h>
30
31#include "atmel-isi.h"
32
33#define MAX_BUFFER_NUM			32
34#define MAX_SUPPORT_WIDTH		2048
35#define MAX_SUPPORT_HEIGHT		2048
36#define VID_LIMIT_BYTES			(16 * 1024 * 1024)
37#define MIN_FRAME_RATE			15
38#define FRAME_INTERVAL_MILLI_SEC	(1000 / MIN_FRAME_RATE)
39
40/* Frame buffer descriptor */
41struct fbd {
42	/* Physical address of the frame buffer */
43	u32 fb_address;
44	/* DMA Control Register(only in HISI2) */
45	u32 dma_ctrl;
46	/* Physical address of the next fbd */
47	u32 next_fbd_address;
48};
49
50static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl)
51{
52	fb_desc->dma_ctrl = ctrl;
53}
54
55struct isi_dma_desc {
56	struct list_head list;
57	struct fbd *p_fbd;
58	dma_addr_t fbd_phys;
59};
60
61/* Frame buffer data */
62struct frame_buffer {
63	struct vb2_v4l2_buffer vb;
64	struct isi_dma_desc *p_dma_desc;
65	struct list_head list;
66};
67
68struct atmel_isi {
69	/* Protects the access of variables shared with the ISR */
70	spinlock_t			lock;
71	void __iomem			*regs;
72
73	int				sequence;
74
75	struct vb2_alloc_ctx		*alloc_ctx;
76
77	/* Allocate descriptors for dma buffer use */
78	struct fbd			*p_fb_descriptors;
79	dma_addr_t			fb_descriptors_phys;
80	struct				list_head dma_desc_head;
81	struct isi_dma_desc		dma_desc[MAX_BUFFER_NUM];
82
83	struct completion		complete;
84	/* ISI peripherial clock */
85	struct clk			*pclk;
86	unsigned int			irq;
87
88	struct isi_platform_data	pdata;
89	u16				width_flags;	/* max 12 bits */
90
91	struct list_head		video_buffer_list;
92	struct frame_buffer		*active;
93
94	struct soc_camera_host		soc_host;
95};
96
97static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val)
98{
99	writel(val, isi->regs + reg);
100}
101static u32 isi_readl(struct atmel_isi *isi, u32 reg)
102{
103	return readl(isi->regs + reg);
104}
105
106static void configure_geometry(struct atmel_isi *isi, u32 width,
107			u32 height, u32 code)
108{
109	u32 cfg2;
110
111	/* According to sensor's output format to set cfg2 */
112	switch (code) {
113	default:
114	/* Grey */
115	case MEDIA_BUS_FMT_Y8_1X8:
116		cfg2 = ISI_CFG2_GRAYSCALE | ISI_CFG2_COL_SPACE_YCbCr;
117		break;
118	/* YUV */
119	case MEDIA_BUS_FMT_VYUY8_2X8:
120		cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr;
121		break;
122	case MEDIA_BUS_FMT_UYVY8_2X8:
123		cfg2 = ISI_CFG2_YCC_SWAP_MODE_2 | ISI_CFG2_COL_SPACE_YCbCr;
124		break;
125	case MEDIA_BUS_FMT_YVYU8_2X8:
126		cfg2 = ISI_CFG2_YCC_SWAP_MODE_1 | ISI_CFG2_COL_SPACE_YCbCr;
127		break;
128	case MEDIA_BUS_FMT_YUYV8_2X8:
129		cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr;
130		break;
131	/* RGB, TODO */
132	}
133
134	isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
135	/* Set width */
136	cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
137			ISI_CFG2_IM_HSIZE_MASK;
138	/* Set height */
139	cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
140			& ISI_CFG2_IM_VSIZE_MASK;
141	isi_writel(isi, ISI_CFG2, cfg2);
142}
143
144static bool is_supported(struct soc_camera_device *icd,
145		const u32 pixformat)
146{
147	switch (pixformat) {
148	/* YUV, including grey */
149	case V4L2_PIX_FMT_GREY:
150	case V4L2_PIX_FMT_YUYV:
151	case V4L2_PIX_FMT_UYVY:
152	case V4L2_PIX_FMT_YVYU:
153	case V4L2_PIX_FMT_VYUY:
154		return true;
155	/* RGB, TODO */
156	default:
157		return false;
158	}
159}
160
161static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
162{
163	if (isi->active) {
164		struct vb2_v4l2_buffer *vbuf = &isi->active->vb;
165		struct frame_buffer *buf = isi->active;
166
167		list_del_init(&buf->list);
168		v4l2_get_timestamp(&vbuf->timestamp);
169		vbuf->sequence = isi->sequence++;
170		vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
171	}
172
173	if (list_empty(&isi->video_buffer_list)) {
174		isi->active = NULL;
175	} else {
176		/* start next dma frame. */
177		isi->active = list_entry(isi->video_buffer_list.next,
178					struct frame_buffer, list);
179		isi_writel(isi, ISI_DMA_C_DSCR,
180			(u32)isi->active->p_dma_desc->fbd_phys);
181		isi_writel(isi, ISI_DMA_C_CTRL,
182			ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
183		isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
184	}
185	return IRQ_HANDLED;
186}
187
188/* ISI interrupt service routine */
189static irqreturn_t isi_interrupt(int irq, void *dev_id)
190{
191	struct atmel_isi *isi = dev_id;
192	u32 status, mask, pending;
193	irqreturn_t ret = IRQ_NONE;
194
195	spin_lock(&isi->lock);
196
197	status = isi_readl(isi, ISI_STATUS);
198	mask = isi_readl(isi, ISI_INTMASK);
199	pending = status & mask;
200
201	if (pending & ISI_CTRL_SRST) {
202		complete(&isi->complete);
203		isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
204		ret = IRQ_HANDLED;
205	} else if (pending & ISI_CTRL_DIS) {
206		complete(&isi->complete);
207		isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
208		ret = IRQ_HANDLED;
209	} else {
210		if (likely(pending & ISI_SR_CXFR_DONE))
211			ret = atmel_isi_handle_streaming(isi);
212	}
213
214	spin_unlock(&isi->lock);
215	return ret;
216}
217
218#define	WAIT_ISI_RESET		1
219#define	WAIT_ISI_DISABLE	0
220static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
221{
222	unsigned long timeout;
223	/*
224	 * The reset or disable will only succeed if we have a
225	 * pixel clock from the camera.
226	 */
227	init_completion(&isi->complete);
228
229	if (wait_reset) {
230		isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST);
231		isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST);
232	} else {
233		isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS);
234		isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
235	}
236
237	timeout = wait_for_completion_timeout(&isi->complete,
238			msecs_to_jiffies(500));
239	if (timeout == 0)
240		return -ETIMEDOUT;
241
242	return 0;
243}
244
245/* ------------------------------------------------------------------
246	Videobuf operations
247   ------------------------------------------------------------------*/
248static int queue_setup(struct vb2_queue *vq, const void *parg,
249				unsigned int *nbuffers, unsigned int *nplanes,
250				unsigned int sizes[], void *alloc_ctxs[])
251{
252	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
253	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
254	struct atmel_isi *isi = ici->priv;
255	unsigned long size;
256
257	size = icd->sizeimage;
258
259	if (!*nbuffers || *nbuffers > MAX_BUFFER_NUM)
260		*nbuffers = MAX_BUFFER_NUM;
261
262	if (size * *nbuffers > VID_LIMIT_BYTES)
263		*nbuffers = VID_LIMIT_BYTES / size;
264
265	*nplanes = 1;
266	sizes[0] = size;
267	alloc_ctxs[0] = isi->alloc_ctx;
268
269	isi->sequence = 0;
270	isi->active = NULL;
271
272	dev_dbg(icd->parent, "%s, count=%d, size=%ld\n", __func__,
273		*nbuffers, size);
274
275	return 0;
276}
277
278static int buffer_init(struct vb2_buffer *vb)
279{
280	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
281	struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
282
283	buf->p_dma_desc = NULL;
284	INIT_LIST_HEAD(&buf->list);
285
286	return 0;
287}
288
289static int buffer_prepare(struct vb2_buffer *vb)
290{
291	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
292	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
293	struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
294	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
295	struct atmel_isi *isi = ici->priv;
296	unsigned long size;
297	struct isi_dma_desc *desc;
298
299	size = icd->sizeimage;
300
301	if (vb2_plane_size(vb, 0) < size) {
302		dev_err(icd->parent, "%s data will not fit into plane (%lu < %lu)\n",
303				__func__, vb2_plane_size(vb, 0), size);
304		return -EINVAL;
305	}
306
307	vb2_set_plane_payload(vb, 0, size);
308
309	if (!buf->p_dma_desc) {
310		if (list_empty(&isi->dma_desc_head)) {
311			dev_err(icd->parent, "Not enough dma descriptors.\n");
312			return -EINVAL;
313		} else {
314			/* Get an available descriptor */
315			desc = list_entry(isi->dma_desc_head.next,
316						struct isi_dma_desc, list);
317			/* Delete the descriptor since now it is used */
318			list_del_init(&desc->list);
319
320			/* Initialize the dma descriptor */
321			desc->p_fbd->fb_address =
322					vb2_dma_contig_plane_dma_addr(vb, 0);
323			desc->p_fbd->next_fbd_address = 0;
324			set_dma_ctrl(desc->p_fbd, ISI_DMA_CTRL_WB);
325
326			buf->p_dma_desc = desc;
327		}
328	}
329	return 0;
330}
331
332static void buffer_cleanup(struct vb2_buffer *vb)
333{
334	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
335	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
336	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
337	struct atmel_isi *isi = ici->priv;
338	struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
339
340	/* This descriptor is available now and we add to head list */
341	if (buf->p_dma_desc)
342		list_add(&buf->p_dma_desc->list, &isi->dma_desc_head);
343}
344
345static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
346{
347	u32 ctrl, cfg1;
348
349	cfg1 = isi_readl(isi, ISI_CFG1);
350	/* Enable irq: cxfr for the codec path, pxfr for the preview path */
351	isi_writel(isi, ISI_INTEN,
352			ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
353
354	/* Check if already in a frame */
355	if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
356		dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
357		return;
358	}
359
360	isi_writel(isi, ISI_DMA_C_DSCR, (u32)buffer->p_dma_desc->fbd_phys);
361	isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
362	isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
363
364	cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
365	/* Enable linked list */
366	cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
367
368	/* Enable codec path and ISI */
369	ctrl = ISI_CTRL_CDC | ISI_CTRL_EN;
370	isi_writel(isi, ISI_CTRL, ctrl);
371	isi_writel(isi, ISI_CFG1, cfg1);
372}
373
374static void buffer_queue(struct vb2_buffer *vb)
375{
376	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
377	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
378	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
379	struct atmel_isi *isi = ici->priv;
380	struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
381	unsigned long flags = 0;
382
383	spin_lock_irqsave(&isi->lock, flags);
384	list_add_tail(&buf->list, &isi->video_buffer_list);
385
386	if (isi->active == NULL) {
387		isi->active = buf;
388		if (vb2_is_streaming(vb->vb2_queue))
389			start_dma(isi, buf);
390	}
391	spin_unlock_irqrestore(&isi->lock, flags);
392}
393
394static int start_streaming(struct vb2_queue *vq, unsigned int count)
395{
396	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
397	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
398	struct atmel_isi *isi = ici->priv;
399	int ret;
400
401	pm_runtime_get_sync(ici->v4l2_dev.dev);
402
403	/* Reset ISI */
404	ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
405	if (ret < 0) {
406		dev_err(icd->parent, "Reset ISI timed out\n");
407		pm_runtime_put(ici->v4l2_dev.dev);
408		return ret;
409	}
410	/* Disable all interrupts */
411	isi_writel(isi, ISI_INTDIS, (u32)~0UL);
412
413	configure_geometry(isi, icd->user_width, icd->user_height,
414				icd->current_fmt->code);
415
416	spin_lock_irq(&isi->lock);
417	/* Clear any pending interrupt */
418	isi_readl(isi, ISI_STATUS);
419
420	if (count)
421		start_dma(isi, isi->active);
422	spin_unlock_irq(&isi->lock);
423
424	return 0;
425}
426
427/* abort streaming and wait for last buffer */
428static void stop_streaming(struct vb2_queue *vq)
429{
430	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
431	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
432	struct atmel_isi *isi = ici->priv;
433	struct frame_buffer *buf, *node;
434	int ret = 0;
435	unsigned long timeout;
436
437	spin_lock_irq(&isi->lock);
438	isi->active = NULL;
439	/* Release all active buffers */
440	list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
441		list_del_init(&buf->list);
442		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
443	}
444	spin_unlock_irq(&isi->lock);
445
446	timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
447	/* Wait until the end of the current frame. */
448	while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
449			time_before(jiffies, timeout))
450		msleep(1);
451
452	if (time_after(jiffies, timeout))
453		dev_err(icd->parent,
454			"Timeout waiting for finishing codec request\n");
455
456	/* Disable interrupts */
457	isi_writel(isi, ISI_INTDIS,
458			ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
459
460	/* Disable ISI and wait for it is done */
461	ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE);
462	if (ret < 0)
463		dev_err(icd->parent, "Disable ISI timed out\n");
464
465	pm_runtime_put(ici->v4l2_dev.dev);
466}
467
468static struct vb2_ops isi_video_qops = {
469	.queue_setup		= queue_setup,
470	.buf_init		= buffer_init,
471	.buf_prepare		= buffer_prepare,
472	.buf_cleanup		= buffer_cleanup,
473	.buf_queue		= buffer_queue,
474	.start_streaming	= start_streaming,
475	.stop_streaming		= stop_streaming,
476	.wait_prepare		= vb2_ops_wait_prepare,
477	.wait_finish		= vb2_ops_wait_finish,
478};
479
480/* ------------------------------------------------------------------
481	SOC camera operations for the device
482   ------------------------------------------------------------------*/
483static int isi_camera_init_videobuf(struct vb2_queue *q,
484				     struct soc_camera_device *icd)
485{
486	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
487
488	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
489	q->io_modes = VB2_MMAP;
490	q->drv_priv = icd;
491	q->buf_struct_size = sizeof(struct frame_buffer);
492	q->ops = &isi_video_qops;
493	q->mem_ops = &vb2_dma_contig_memops;
494	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
495	q->lock = &ici->host_lock;
496
497	return vb2_queue_init(q);
498}
499
500static int isi_camera_set_fmt(struct soc_camera_device *icd,
501			      struct v4l2_format *f)
502{
503	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
504	const struct soc_camera_format_xlate *xlate;
505	struct v4l2_pix_format *pix = &f->fmt.pix;
506	struct v4l2_subdev_format format = {
507		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
508	};
509	struct v4l2_mbus_framefmt *mf = &format.format;
510	int ret;
511
512	/* check with atmel-isi support format, if not support use YUYV */
513	if (!is_supported(icd, pix->pixelformat))
514		pix->pixelformat = V4L2_PIX_FMT_YUYV;
515
516	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
517	if (!xlate) {
518		dev_warn(icd->parent, "Format %x not found\n",
519			 pix->pixelformat);
520		return -EINVAL;
521	}
522
523	dev_dbg(icd->parent, "Plan to set format %dx%d\n",
524			pix->width, pix->height);
525
526	mf->width	= pix->width;
527	mf->height	= pix->height;
528	mf->field	= pix->field;
529	mf->colorspace	= pix->colorspace;
530	mf->code	= xlate->code;
531
532	ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format);
533	if (ret < 0)
534		return ret;
535
536	if (mf->code != xlate->code)
537		return -EINVAL;
538
539	pix->width		= mf->width;
540	pix->height		= mf->height;
541	pix->field		= mf->field;
542	pix->colorspace		= mf->colorspace;
543	icd->current_fmt	= xlate;
544
545	dev_dbg(icd->parent, "Finally set format %dx%d\n",
546		pix->width, pix->height);
547
548	return ret;
549}
550
551static int isi_camera_try_fmt(struct soc_camera_device *icd,
552			      struct v4l2_format *f)
553{
554	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
555	const struct soc_camera_format_xlate *xlate;
556	struct v4l2_pix_format *pix = &f->fmt.pix;
557	struct v4l2_subdev_pad_config pad_cfg;
558	struct v4l2_subdev_format format = {
559		.which = V4L2_SUBDEV_FORMAT_TRY,
560	};
561	struct v4l2_mbus_framefmt *mf = &format.format;
562	u32 pixfmt = pix->pixelformat;
563	int ret;
564
565	/* check with atmel-isi support format, if not support use YUYV */
566	if (!is_supported(icd, pix->pixelformat))
567		pix->pixelformat = V4L2_PIX_FMT_YUYV;
568
569	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
570	if (pixfmt && !xlate) {
571		dev_warn(icd->parent, "Format %x not found\n", pixfmt);
572		return -EINVAL;
573	}
574
575	/* limit to Atmel ISI hardware capabilities */
576	if (pix->height > MAX_SUPPORT_HEIGHT)
577		pix->height = MAX_SUPPORT_HEIGHT;
578	if (pix->width > MAX_SUPPORT_WIDTH)
579		pix->width = MAX_SUPPORT_WIDTH;
580
581	/* limit to sensor capabilities */
582	mf->width	= pix->width;
583	mf->height	= pix->height;
584	mf->field	= pix->field;
585	mf->colorspace	= pix->colorspace;
586	mf->code	= xlate->code;
587
588	ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format);
589	if (ret < 0)
590		return ret;
591
592	pix->width	= mf->width;
593	pix->height	= mf->height;
594	pix->colorspace	= mf->colorspace;
595
596	switch (mf->field) {
597	case V4L2_FIELD_ANY:
598		pix->field = V4L2_FIELD_NONE;
599		break;
600	case V4L2_FIELD_NONE:
601		break;
602	default:
603		dev_err(icd->parent, "Field type %d unsupported.\n",
604			mf->field);
605		ret = -EINVAL;
606	}
607
608	return ret;
609}
610
611static const struct soc_mbus_pixelfmt isi_camera_formats[] = {
612	{
613		.fourcc			= V4L2_PIX_FMT_YUYV,
614		.name			= "Packed YUV422 16 bit",
615		.bits_per_sample	= 8,
616		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
617		.order			= SOC_MBUS_ORDER_LE,
618		.layout			= SOC_MBUS_LAYOUT_PACKED,
619	},
620};
621
622/* This will be corrected as we get more formats */
623static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
624{
625	return	fmt->packing == SOC_MBUS_PACKING_NONE ||
626		(fmt->bits_per_sample == 8 &&
627		 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
628		(fmt->bits_per_sample > 8 &&
629		 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
630}
631
632#define ISI_BUS_PARAM (V4L2_MBUS_MASTER |	\
633		V4L2_MBUS_HSYNC_ACTIVE_HIGH |	\
634		V4L2_MBUS_HSYNC_ACTIVE_LOW |	\
635		V4L2_MBUS_VSYNC_ACTIVE_HIGH |	\
636		V4L2_MBUS_VSYNC_ACTIVE_LOW |	\
637		V4L2_MBUS_PCLK_SAMPLE_RISING |	\
638		V4L2_MBUS_PCLK_SAMPLE_FALLING |	\
639		V4L2_MBUS_DATA_ACTIVE_HIGH)
640
641static int isi_camera_try_bus_param(struct soc_camera_device *icd,
642				    unsigned char buswidth)
643{
644	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
645	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
646	struct atmel_isi *isi = ici->priv;
647	struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
648	unsigned long common_flags;
649	int ret;
650
651	ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
652	if (!ret) {
653		common_flags = soc_mbus_config_compatible(&cfg,
654							  ISI_BUS_PARAM);
655		if (!common_flags) {
656			dev_warn(icd->parent,
657				 "Flags incompatible: camera 0x%x, host 0x%x\n",
658				 cfg.flags, ISI_BUS_PARAM);
659			return -EINVAL;
660		}
661	} else if (ret != -ENOIOCTLCMD) {
662		return ret;
663	}
664
665	if ((1 << (buswidth - 1)) & isi->width_flags)
666		return 0;
667	return -EINVAL;
668}
669
670
671static int isi_camera_get_formats(struct soc_camera_device *icd,
672				  unsigned int idx,
673				  struct soc_camera_format_xlate *xlate)
674{
675	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
676	int formats = 0, ret;
677	/* sensor format */
678	struct v4l2_subdev_mbus_code_enum code = {
679		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
680		.index = idx,
681	};
682	/* soc camera host format */
683	const struct soc_mbus_pixelfmt *fmt;
684
685	ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
686	if (ret < 0)
687		/* No more formats */
688		return 0;
689
690	fmt = soc_mbus_get_fmtdesc(code.code);
691	if (!fmt) {
692		dev_err(icd->parent,
693			"Invalid format code #%u: %d\n", idx, code.code);
694		return 0;
695	}
696
697	/* This also checks support for the requested bits-per-sample */
698	ret = isi_camera_try_bus_param(icd, fmt->bits_per_sample);
699	if (ret < 0) {
700		dev_err(icd->parent,
701			"Fail to try the bus parameters.\n");
702		return 0;
703	}
704
705	switch (code.code) {
706	case MEDIA_BUS_FMT_UYVY8_2X8:
707	case MEDIA_BUS_FMT_VYUY8_2X8:
708	case MEDIA_BUS_FMT_YUYV8_2X8:
709	case MEDIA_BUS_FMT_YVYU8_2X8:
710		formats++;
711		if (xlate) {
712			xlate->host_fmt	= &isi_camera_formats[0];
713			xlate->code	= code.code;
714			xlate++;
715			dev_dbg(icd->parent, "Providing format %s using code %d\n",
716				isi_camera_formats[0].name, code.code);
717		}
718		break;
719	default:
720		if (!isi_camera_packing_supported(fmt))
721			return 0;
722		if (xlate)
723			dev_dbg(icd->parent,
724				"Providing format %s in pass-through mode\n",
725				fmt->name);
726	}
727
728	/* Generic pass-through */
729	formats++;
730	if (xlate) {
731		xlate->host_fmt	= fmt;
732		xlate->code	= code.code;
733		xlate++;
734	}
735
736	return formats;
737}
738
739static int isi_camera_add_device(struct soc_camera_device *icd)
740{
741	dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
742		 icd->devnum);
743
744	return 0;
745}
746
747static void isi_camera_remove_device(struct soc_camera_device *icd)
748{
749	dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
750		 icd->devnum);
751}
752
753static unsigned int isi_camera_poll(struct file *file, poll_table *pt)
754{
755	struct soc_camera_device *icd = file->private_data;
756
757	return vb2_poll(&icd->vb2_vidq, file, pt);
758}
759
760static int isi_camera_querycap(struct soc_camera_host *ici,
761			       struct v4l2_capability *cap)
762{
763	strcpy(cap->driver, "atmel-isi");
764	strcpy(cap->card, "Atmel Image Sensor Interface");
765	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
766	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
767
768	return 0;
769}
770
771static int isi_camera_set_bus_param(struct soc_camera_device *icd)
772{
773	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
774	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
775	struct atmel_isi *isi = ici->priv;
776	struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
777	unsigned long common_flags;
778	int ret;
779	u32 cfg1 = 0;
780
781	ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
782	if (!ret) {
783		common_flags = soc_mbus_config_compatible(&cfg,
784							  ISI_BUS_PARAM);
785		if (!common_flags) {
786			dev_warn(icd->parent,
787				 "Flags incompatible: camera 0x%x, host 0x%x\n",
788				 cfg.flags, ISI_BUS_PARAM);
789			return -EINVAL;
790		}
791	} else if (ret != -ENOIOCTLCMD) {
792		return ret;
793	} else {
794		common_flags = ISI_BUS_PARAM;
795	}
796	dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n",
797		cfg.flags, ISI_BUS_PARAM, common_flags);
798
799	/* Make choises, based on platform preferences */
800	if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
801	    (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
802		if (isi->pdata.hsync_act_low)
803			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
804		else
805			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
806	}
807
808	if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
809	    (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
810		if (isi->pdata.vsync_act_low)
811			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
812		else
813			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
814	}
815
816	if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
817	    (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
818		if (isi->pdata.pclk_act_falling)
819			common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
820		else
821			common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
822	}
823
824	cfg.flags = common_flags;
825	ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
826	if (ret < 0 && ret != -ENOIOCTLCMD) {
827		dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
828			common_flags, ret);
829		return ret;
830	}
831
832	/* set bus param for ISI */
833	if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
834		cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
835	if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
836		cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
837	if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
838		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
839
840	dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix clock %s edge\n",
841		common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
842		common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
843		common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising");
844
845	if (isi->pdata.has_emb_sync)
846		cfg1 |= ISI_CFG1_EMB_SYNC;
847	if (isi->pdata.full_mode)
848		cfg1 |= ISI_CFG1_FULL_MODE;
849
850	cfg1 |= ISI_CFG1_THMASK_BEATS_16;
851
852	/* Enable PM and peripheral clock before operate isi registers */
853	pm_runtime_get_sync(ici->v4l2_dev.dev);
854
855	isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
856	isi_writel(isi, ISI_CFG1, cfg1);
857
858	pm_runtime_put(ici->v4l2_dev.dev);
859
860	return 0;
861}
862
863static struct soc_camera_host_ops isi_soc_camera_host_ops = {
864	.owner		= THIS_MODULE,
865	.add		= isi_camera_add_device,
866	.remove		= isi_camera_remove_device,
867	.set_fmt	= isi_camera_set_fmt,
868	.try_fmt	= isi_camera_try_fmt,
869	.get_formats	= isi_camera_get_formats,
870	.init_videobuf2	= isi_camera_init_videobuf,
871	.poll		= isi_camera_poll,
872	.querycap	= isi_camera_querycap,
873	.set_bus_param	= isi_camera_set_bus_param,
874};
875
876/* -----------------------------------------------------------------------*/
877static int atmel_isi_remove(struct platform_device *pdev)
878{
879	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
880	struct atmel_isi *isi = container_of(soc_host,
881					struct atmel_isi, soc_host);
882
883	soc_camera_host_unregister(soc_host);
884	vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
885	dma_free_coherent(&pdev->dev,
886			sizeof(struct fbd) * MAX_BUFFER_NUM,
887			isi->p_fb_descriptors,
888			isi->fb_descriptors_phys);
889	pm_runtime_disable(&pdev->dev);
890
891	return 0;
892}
893
894static int atmel_isi_parse_dt(struct atmel_isi *isi,
895			struct platform_device *pdev)
896{
897	struct device_node *np= pdev->dev.of_node;
898	struct v4l2_of_endpoint ep;
899	int err;
900
901	/* Default settings for ISI */
902	isi->pdata.full_mode = 1;
903	isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
904
905	np = of_graph_get_next_endpoint(np, NULL);
906	if (!np) {
907		dev_err(&pdev->dev, "Could not find the endpoint\n");
908		return -EINVAL;
909	}
910
911	err = v4l2_of_parse_endpoint(np, &ep);
912	of_node_put(np);
913	if (err) {
914		dev_err(&pdev->dev, "Could not parse the endpoint\n");
915		return err;
916	}
917
918	switch (ep.bus.parallel.bus_width) {
919	case 8:
920		isi->pdata.data_width_flags = ISI_DATAWIDTH_8;
921		break;
922	case 10:
923		isi->pdata.data_width_flags =
924				ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10;
925		break;
926	default:
927		dev_err(&pdev->dev, "Unsupported bus width: %d\n",
928				ep.bus.parallel.bus_width);
929		return -EINVAL;
930	}
931
932	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
933		isi->pdata.hsync_act_low = true;
934	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
935		isi->pdata.vsync_act_low = true;
936	if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
937		isi->pdata.pclk_act_falling = true;
938
939	if (ep.bus_type == V4L2_MBUS_BT656)
940		isi->pdata.has_emb_sync = true;
941
942	return 0;
943}
944
945static int atmel_isi_probe(struct platform_device *pdev)
946{
947	unsigned int irq;
948	struct atmel_isi *isi;
949	struct resource *regs;
950	int ret, i;
951	struct soc_camera_host *soc_host;
952
953	isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
954	if (!isi) {
955		dev_err(&pdev->dev, "Can't allocate interface!\n");
956		return -ENOMEM;
957	}
958
959	isi->pclk = devm_clk_get(&pdev->dev, "isi_clk");
960	if (IS_ERR(isi->pclk))
961		return PTR_ERR(isi->pclk);
962
963	ret = atmel_isi_parse_dt(isi, pdev);
964	if (ret)
965		return ret;
966
967	isi->active = NULL;
968	spin_lock_init(&isi->lock);
969	INIT_LIST_HEAD(&isi->video_buffer_list);
970	INIT_LIST_HEAD(&isi->dma_desc_head);
971
972	isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
973				sizeof(struct fbd) * MAX_BUFFER_NUM,
974				&isi->fb_descriptors_phys,
975				GFP_KERNEL);
976	if (!isi->p_fb_descriptors) {
977		dev_err(&pdev->dev, "Can't allocate descriptors!\n");
978		return -ENOMEM;
979	}
980
981	for (i = 0; i < MAX_BUFFER_NUM; i++) {
982		isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i;
983		isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys +
984					i * sizeof(struct fbd);
985		list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
986	}
987
988	isi->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
989	if (IS_ERR(isi->alloc_ctx)) {
990		ret = PTR_ERR(isi->alloc_ctx);
991		goto err_alloc_ctx;
992	}
993
994	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
995	isi->regs = devm_ioremap_resource(&pdev->dev, regs);
996	if (IS_ERR(isi->regs)) {
997		ret = PTR_ERR(isi->regs);
998		goto err_ioremap;
999	}
1000
1001	if (isi->pdata.data_width_flags & ISI_DATAWIDTH_8)
1002		isi->width_flags = 1 << 7;
1003	if (isi->pdata.data_width_flags & ISI_DATAWIDTH_10)
1004		isi->width_flags |= 1 << 9;
1005
1006	irq = platform_get_irq(pdev, 0);
1007	if (IS_ERR_VALUE(irq)) {
1008		ret = irq;
1009		goto err_req_irq;
1010	}
1011
1012	ret = devm_request_irq(&pdev->dev, irq, isi_interrupt, 0, "isi", isi);
1013	if (ret) {
1014		dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1015		goto err_req_irq;
1016	}
1017	isi->irq = irq;
1018
1019	soc_host		= &isi->soc_host;
1020	soc_host->drv_name	= "isi-camera";
1021	soc_host->ops		= &isi_soc_camera_host_ops;
1022	soc_host->priv		= isi;
1023	soc_host->v4l2_dev.dev	= &pdev->dev;
1024	soc_host->nr		= pdev->id;
1025
1026	pm_suspend_ignore_children(&pdev->dev, true);
1027	pm_runtime_enable(&pdev->dev);
1028
1029	ret = soc_camera_host_register(soc_host);
1030	if (ret) {
1031		dev_err(&pdev->dev, "Unable to register soc camera host\n");
1032		goto err_register_soc_camera_host;
1033	}
1034	return 0;
1035
1036err_register_soc_camera_host:
1037	pm_runtime_disable(&pdev->dev);
1038err_req_irq:
1039err_ioremap:
1040	vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
1041err_alloc_ctx:
1042	dma_free_coherent(&pdev->dev,
1043			sizeof(struct fbd) * MAX_BUFFER_NUM,
1044			isi->p_fb_descriptors,
1045			isi->fb_descriptors_phys);
1046
1047	return ret;
1048}
1049
1050#ifdef CONFIG_PM
1051static int atmel_isi_runtime_suspend(struct device *dev)
1052{
1053	struct soc_camera_host *soc_host = to_soc_camera_host(dev);
1054	struct atmel_isi *isi = container_of(soc_host,
1055					struct atmel_isi, soc_host);
1056
1057	clk_disable_unprepare(isi->pclk);
1058
1059	return 0;
1060}
1061static int atmel_isi_runtime_resume(struct device *dev)
1062{
1063	struct soc_camera_host *soc_host = to_soc_camera_host(dev);
1064	struct atmel_isi *isi = container_of(soc_host,
1065					struct atmel_isi, soc_host);
1066
1067	return clk_prepare_enable(isi->pclk);
1068}
1069#endif /* CONFIG_PM */
1070
1071static const struct dev_pm_ops atmel_isi_dev_pm_ops = {
1072	SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend,
1073				atmel_isi_runtime_resume, NULL)
1074};
1075
1076static const struct of_device_id atmel_isi_of_match[] = {
1077	{ .compatible = "atmel,at91sam9g45-isi" },
1078	{ }
1079};
1080MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
1081
1082static struct platform_driver atmel_isi_driver = {
1083	.remove		= atmel_isi_remove,
1084	.driver		= {
1085		.name = "atmel_isi",
1086		.of_match_table = of_match_ptr(atmel_isi_of_match),
1087		.pm	= &atmel_isi_dev_pm_ops,
1088	},
1089};
1090
1091module_platform_driver_probe(atmel_isi_driver, atmel_isi_probe);
1092
1093MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1094MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1095MODULE_LICENSE("GPL");
1096MODULE_SUPPORTED_DEVICE("video");
1097