• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
41 struct 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 
set_dma_ctrl(struct fbd * fb_desc,u32 ctrl)50 static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl)
51 {
52 	fb_desc->dma_ctrl = ctrl;
53 }
54 
55 struct 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 */
62 struct frame_buffer {
63 	struct vb2_v4l2_buffer vb;
64 	struct isi_dma_desc *p_dma_desc;
65 	struct list_head list;
66 };
67 
68 struct 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 
isi_writel(struct atmel_isi * isi,u32 reg,u32 val)97 static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val)
98 {
99 	writel(val, isi->regs + reg);
100 }
isi_readl(struct atmel_isi * isi,u32 reg)101 static u32 isi_readl(struct atmel_isi *isi, u32 reg)
102 {
103 	return readl(isi->regs + reg);
104 }
105 
configure_geometry(struct atmel_isi * isi,u32 width,u32 height,u32 code)106 static 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 
is_supported(struct soc_camera_device * icd,const u32 pixformat)144 static 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 
atmel_isi_handle_streaming(struct atmel_isi * isi)161 static 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 */
isi_interrupt(int irq,void * dev_id)189 static 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
atmel_isi_wait_status(struct atmel_isi * isi,int wait_reset)220 static 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    ------------------------------------------------------------------*/
queue_setup(struct vb2_queue * vq,const void * parg,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],void * alloc_ctxs[])248 static 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 
buffer_init(struct vb2_buffer * vb)278 static 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 
buffer_prepare(struct vb2_buffer * vb)289 static 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 
buffer_cleanup(struct vb2_buffer * vb)332 static 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 
start_dma(struct atmel_isi * isi,struct frame_buffer * buffer)345 static 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 
buffer_queue(struct vb2_buffer * vb)374 static 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 
start_streaming(struct vb2_queue * vq,unsigned int count)394 static 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 */
stop_streaming(struct vb2_queue * vq)428 static 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 
468 static 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    ------------------------------------------------------------------*/
isi_camera_init_videobuf(struct vb2_queue * q,struct soc_camera_device * icd)483 static 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 
isi_camera_set_fmt(struct soc_camera_device * icd,struct v4l2_format * f)500 static 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 
isi_camera_try_fmt(struct soc_camera_device * icd,struct v4l2_format * f)551 static 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 
611 static 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 */
isi_camera_packing_supported(const struct soc_mbus_pixelfmt * fmt)623 static 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 
isi_camera_try_bus_param(struct soc_camera_device * icd,unsigned char buswidth)641 static 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 
isi_camera_get_formats(struct soc_camera_device * icd,unsigned int idx,struct soc_camera_format_xlate * xlate)671 static 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 
isi_camera_add_device(struct soc_camera_device * icd)739 static 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 
isi_camera_remove_device(struct soc_camera_device * icd)747 static 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 
isi_camera_poll(struct file * file,poll_table * pt)753 static 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 
isi_camera_querycap(struct soc_camera_host * ici,struct v4l2_capability * cap)760 static 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 
isi_camera_set_bus_param(struct soc_camera_device * icd)771 static 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 
863 static 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 /* -----------------------------------------------------------------------*/
atmel_isi_remove(struct platform_device * pdev)877 static 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 
atmel_isi_parse_dt(struct atmel_isi * isi,struct platform_device * pdev)894 static 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 
atmel_isi_probe(struct platform_device * pdev)945 static 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 
1036 err_register_soc_camera_host:
1037 	pm_runtime_disable(&pdev->dev);
1038 err_req_irq:
1039 err_ioremap:
1040 	vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
1041 err_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
atmel_isi_runtime_suspend(struct device * dev)1051 static 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 }
atmel_isi_runtime_resume(struct device * dev)1061 static 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 
1071 static 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 
1076 static const struct of_device_id atmel_isi_of_match[] = {
1077 	{ .compatible = "atmel,at91sam9g45-isi" },
1078 	{ }
1079 };
1080 MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
1081 
1082 static 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 
1091 module_platform_driver_probe(atmel_isi_driver, atmel_isi_probe);
1092 
1093 MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1094 MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1095 MODULE_LICENSE("GPL");
1096 MODULE_SUPPORTED_DEVICE("video");
1097