aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/soc_camera/mx1_camera.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 04:49:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 04:49:05 -0400
commit0b8e74c6f44094189dbe78baf4101acc7570c6af (patch)
tree6440561d09fb71ba5928664604ec92f29940be6b /drivers/media/platform/soc_camera/mx1_camera.c
parent7f60ba388f5b9dd8b0da463b394412dace3ab814 (diff)
parentbd0d10498826ed150da5e4c45baf8b9c7088fb71 (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: "The first part of the media updates for Kernel 3.7. This series contain: - A major tree renaming patch series: now, drivers are organized internally by their used bus, instead of by V4L2 and/or DVB API, providing a cleaner driver location for hybrid drivers that implement both APIs, and allowing to cleanup the Kconfig items and make them more intuitive for the end user; - Media Kernel developers are typically very lazy with their duties of keeping the MAINTAINERS entries for their drivers updated. As now the tree is more organized, we're doing an effort to add/update those entries for the drivers that aren't currently orphan; - Several DVB USB drivers got moved to a new DVB USB v2 core; the new core fixes several bugs (as the existing one that got bitroted). Now, suspend/resume finally started to work fine (at least with some devices - we should expect more work with regards to it); - added multistream support for DVB-T2, and unified the API for DVB-S2 and ISDB-S. Backward binary support is preserved; - as usual, a few new drivers, some V4L2 core improvements and lots of drivers improvements and fixes. There are some points to notice on this series: 1) you should expect a trivial merge conflict on your tree, with the removal of Documentation/feature-removal-schedule.txt: this series would be adding two additional entries there. I opted to not rebase it due to this recent change; 2) With regards to the PCTV 520e udev-related breakage, I opted to fix it in a way that the patches can be backported to 3.5 even without your firmware fix patch. This way, Greg doesn't need to rush backporting your patch (as there are still the firmware cache and firmware path customization issues to be addressed there). I'll send later a patch (likely after the end of the merge window) reverting the rest of the DRX-K async firmware request, fully restoring its original behaviour to allow media drivers to initialize everything serialized as before for 3.7 and upper. 3) I'm planning to work on this weekend to test the DMABUF patches for V4L2. The patches are on my queue for several Kernel cycles, but, up to now, there is/was no way to test the series locally. I have some concerns about this particular changeset with regards to security issues, and with regards to the replacement of the old VIDIOC_OVERLAY ioctl's that is broken on modern systems, due to GPU drivers change. The Overlay API allows direct PCI2PCI transfers from a media capture card into the GPU framebuffer, but its API is crappy. Also, the only existing X11 driver that implements it requires a XV extension that is not available anymore on modern drivers. The DMABUF can do the same thing, but with it is promising to be a properly-designed API. If I can successfully test this series and be happy with it, I should be asking you to pull them next week." * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (717 commits) em28xx: regression fix: use DRX-K sync firmware requests on em28xx drxk: allow loading firmware synchrousnously em28xx: Make all em28xx extensions to be initialized asynchronously [media] tda18271: properly report read errors in tda18271_get_id [media] tda18271: delay IR & RF calibration until init() if delay_cal is set [media] MAINTAINERS: add Michael Krufky as tda827x maintainer [media] MAINTAINERS: add Michael Krufky as tda8290 maintainer [media] MAINTAINERS: add Michael Krufky as cxusb maintainer [media] MAINTAINERS: add Michael Krufky as lg2160 maintainer [media] MAINTAINERS: add Michael Krufky as lgdt3305 maintainer [media] MAINTAINERS: add Michael Krufky as mxl111sf maintainer [media] MAINTAINERS: add Michael Krufky as mxl5007t maintainer [media] MAINTAINERS: add Michael Krufky as tda18271 maintainer [media] s5p-tv: Report only multi-plane capabilities in vidioc_querycap [media] s5p-mfc: Fix misplaced return statement in s5p_mfc_suspend() [media] exynos-gsc: Add missing static storage class specifiers [media] exynos-gsc: Remove <linux/version.h> header file inclusion [media] s5p-fimc: Fix incorrect condition in fimc_lite_reqbufs() [media] s5p-tv: Fix potential NULL pointer dereference error [media] s5k6aa: Fix possible NULL pointer dereference ...
Diffstat (limited to 'drivers/media/platform/soc_camera/mx1_camera.c')
-rw-r--r--drivers/media/platform/soc_camera/mx1_camera.c889
1 files changed, 889 insertions, 0 deletions
diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c
new file mode 100644
index 000000000000..bbe70991d30b
--- /dev/null
+++ b/drivers/media/platform/soc_camera/mx1_camera.c
@@ -0,0 +1,889 @@
1/*
2 * V4L2 Driver for i.MXL/i.MXL camera (CSI) host
3 *
4 * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
5 * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
6 *
7 * Based on PXA SoC camera driver
8 * Copyright (C) 2006, Sascha Hauer, Pengutronix
9 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/clk.h>
17#include <linux/delay.h>
18#include <linux/device.h>
19#include <linux/dma-mapping.h>
20#include <linux/errno.h>
21#include <linux/fs.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/io.h>
25#include <linux/kernel.h>
26#include <linux/mm.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/mutex.h>
30#include <linux/platform_device.h>
31#include <linux/sched.h>
32#include <linux/slab.h>
33#include <linux/time.h>
34#include <linux/videodev2.h>
35
36#include <media/soc_camera.h>
37#include <media/v4l2-common.h>
38#include <media/v4l2-dev.h>
39#include <media/videobuf-dma-contig.h>
40#include <media/soc_mediabus.h>
41
42#include <asm/dma.h>
43#include <asm/fiq.h>
44#include <mach/dma-mx1-mx2.h>
45#include <mach/hardware.h>
46#include <mach/irqs.h>
47#include <linux/platform_data/camera-mx1.h>
48
49/*
50 * CSI registers
51 */
52#define CSICR1 0x00 /* CSI Control Register 1 */
53#define CSISR 0x08 /* CSI Status Register */
54#define CSIRXR 0x10 /* CSI RxFIFO Register */
55
56#define CSICR1_RXFF_LEVEL(x) (((x) & 0x3) << 19)
57#define CSICR1_SOF_POL (1 << 17)
58#define CSICR1_SOF_INTEN (1 << 16)
59#define CSICR1_MCLKDIV(x) (((x) & 0xf) << 12)
60#define CSICR1_MCLKEN (1 << 9)
61#define CSICR1_FCC (1 << 8)
62#define CSICR1_BIG_ENDIAN (1 << 7)
63#define CSICR1_CLR_RXFIFO (1 << 5)
64#define CSICR1_GCLK_MODE (1 << 4)
65#define CSICR1_DATA_POL (1 << 2)
66#define CSICR1_REDGE (1 << 1)
67#define CSICR1_EN (1 << 0)
68
69#define CSISR_SFF_OR_INT (1 << 25)
70#define CSISR_RFF_OR_INT (1 << 24)
71#define CSISR_STATFF_INT (1 << 21)
72#define CSISR_RXFF_INT (1 << 18)
73#define CSISR_SOF_INT (1 << 16)
74#define CSISR_DRDY (1 << 0)
75
76#define DRIVER_VERSION "0.0.2"
77#define DRIVER_NAME "mx1-camera"
78
79#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
80 CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
81
82#define CSI_BUS_FLAGS (V4L2_MBUS_MASTER | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
83 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | \
84 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
85 V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_LOW)
86
87#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */
88
89/*
90 * Structures
91 */
92
93/* buffer for one video frame */
94struct mx1_buffer {
95 /* common v4l buffer stuff -- must be first */
96 struct videobuf_buffer vb;
97 enum v4l2_mbus_pixelcode code;
98 int inwork;
99};
100
101/*
102 * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
103 * Interface. If anyone ever builds hardware to enable more than
104 * one camera, they will have to modify this driver too
105 */
106struct mx1_camera_dev {
107 struct soc_camera_host soc_host;
108 struct soc_camera_device *icd;
109 struct mx1_camera_pdata *pdata;
110 struct mx1_buffer *active;
111 struct resource *res;
112 struct clk *clk;
113 struct list_head capture;
114
115 void __iomem *base;
116 int dma_chan;
117 unsigned int irq;
118 unsigned long mclk;
119
120 spinlock_t lock;
121};
122
123/*
124 * Videobuf operations
125 */
126static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
127 unsigned int *size)
128{
129 struct soc_camera_device *icd = vq->priv_data;
130
131 *size = icd->sizeimage;
132
133 if (!*count)
134 *count = 32;
135
136 if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
137 *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size;
138
139 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size);
140
141 return 0;
142}
143
144static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
145{
146 struct soc_camera_device *icd = vq->priv_data;
147 struct videobuf_buffer *vb = &buf->vb;
148
149 BUG_ON(in_interrupt());
150
151 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
152 vb, vb->baddr, vb->bsize);
153
154 /*
155 * This waits until this buffer is out of danger, i.e., until it is no
156 * longer in STATE_QUEUED or STATE_ACTIVE
157 */
158 videobuf_waiton(vq, vb, 0, 0);
159 videobuf_dma_contig_free(vq, vb);
160
161 vb->state = VIDEOBUF_NEEDS_INIT;
162}
163
164static int mx1_videobuf_prepare(struct videobuf_queue *vq,
165 struct videobuf_buffer *vb, enum v4l2_field field)
166{
167 struct soc_camera_device *icd = vq->priv_data;
168 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
169 int ret;
170
171 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
172 vb, vb->baddr, vb->bsize);
173
174 /* Added list head initialization on alloc */
175 WARN_ON(!list_empty(&vb->queue));
176
177 BUG_ON(NULL == icd->current_fmt);
178
179 /*
180 * I think, in buf_prepare you only have to protect global data,
181 * the actual buffer is yours
182 */
183 buf->inwork = 1;
184
185 if (buf->code != icd->current_fmt->code ||
186 vb->width != icd->user_width ||
187 vb->height != icd->user_height ||
188 vb->field != field) {
189 buf->code = icd->current_fmt->code;
190 vb->width = icd->user_width;
191 vb->height = icd->user_height;
192 vb->field = field;
193 vb->state = VIDEOBUF_NEEDS_INIT;
194 }
195
196 vb->size = icd->sizeimage;
197 if (0 != vb->baddr && vb->bsize < vb->size) {
198 ret = -EINVAL;
199 goto out;
200 }
201
202 if (vb->state == VIDEOBUF_NEEDS_INIT) {
203 ret = videobuf_iolock(vq, vb, NULL);
204 if (ret)
205 goto fail;
206
207 vb->state = VIDEOBUF_PREPARED;
208 }
209
210 buf->inwork = 0;
211
212 return 0;
213
214fail:
215 free_buffer(vq, buf);
216out:
217 buf->inwork = 0;
218 return ret;
219}
220
221static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
222{
223 struct videobuf_buffer *vbuf = &pcdev->active->vb;
224 struct device *dev = pcdev->icd->parent;
225 int ret;
226
227 if (unlikely(!pcdev->active)) {
228 dev_err(dev, "DMA End IRQ with no active buffer\n");
229 return -EFAULT;
230 }
231
232 /* setup sg list for future DMA */
233 ret = imx_dma_setup_single(pcdev->dma_chan,
234 videobuf_to_dma_contig(vbuf),
235 vbuf->size, pcdev->res->start +
236 CSIRXR, DMA_MODE_READ);
237 if (unlikely(ret))
238 dev_err(dev, "Failed to setup DMA sg list\n");
239
240 return ret;
241}
242
243/* Called under spinlock_irqsave(&pcdev->lock, ...) */
244static void mx1_videobuf_queue(struct videobuf_queue *vq,
245 struct videobuf_buffer *vb)
246{
247 struct soc_camera_device *icd = vq->priv_data;
248 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
249 struct mx1_camera_dev *pcdev = ici->priv;
250 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
251
252 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
253 vb, vb->baddr, vb->bsize);
254
255 list_add_tail(&vb->queue, &pcdev->capture);
256
257 vb->state = VIDEOBUF_ACTIVE;
258
259 if (!pcdev->active) {
260 pcdev->active = buf;
261
262 /* setup sg list for future DMA */
263 if (!mx1_camera_setup_dma(pcdev)) {
264 unsigned int temp;
265 /* enable SOF irq */
266 temp = __raw_readl(pcdev->base + CSICR1) |
267 CSICR1_SOF_INTEN;
268 __raw_writel(temp, pcdev->base + CSICR1);
269 }
270 }
271}
272
273static void mx1_videobuf_release(struct videobuf_queue *vq,
274 struct videobuf_buffer *vb)
275{
276 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
277#ifdef DEBUG
278 struct soc_camera_device *icd = vq->priv_data;
279 struct device *dev = icd->parent;
280
281 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
282 vb, vb->baddr, vb->bsize);
283
284 switch (vb->state) {
285 case VIDEOBUF_ACTIVE:
286 dev_dbg(dev, "%s (active)\n", __func__);
287 break;
288 case VIDEOBUF_QUEUED:
289 dev_dbg(dev, "%s (queued)\n", __func__);
290 break;
291 case VIDEOBUF_PREPARED:
292 dev_dbg(dev, "%s (prepared)\n", __func__);
293 break;
294 default:
295 dev_dbg(dev, "%s (unknown)\n", __func__);
296 break;
297 }
298#endif
299
300 free_buffer(vq, buf);
301}
302
303static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
304 struct videobuf_buffer *vb,
305 struct mx1_buffer *buf)
306{
307 /* _init is used to debug races, see comment in mx1_camera_reqbufs() */
308 list_del_init(&vb->queue);
309 vb->state = VIDEOBUF_DONE;
310 do_gettimeofday(&vb->ts);
311 vb->field_count++;
312 wake_up(&vb->done);
313
314 if (list_empty(&pcdev->capture)) {
315 pcdev->active = NULL;
316 return;
317 }
318
319 pcdev->active = list_entry(pcdev->capture.next,
320 struct mx1_buffer, vb.queue);
321
322 /* setup sg list for future DMA */
323 if (likely(!mx1_camera_setup_dma(pcdev))) {
324 unsigned int temp;
325
326 /* enable SOF irq */
327 temp = __raw_readl(pcdev->base + CSICR1) | CSICR1_SOF_INTEN;
328 __raw_writel(temp, pcdev->base + CSICR1);
329 }
330}
331
332static void mx1_camera_dma_irq(int channel, void *data)
333{
334 struct mx1_camera_dev *pcdev = data;
335 struct device *dev = pcdev->icd->parent;
336 struct mx1_buffer *buf;
337 struct videobuf_buffer *vb;
338 unsigned long flags;
339
340 spin_lock_irqsave(&pcdev->lock, flags);
341
342 imx_dma_disable(channel);
343
344 if (unlikely(!pcdev->active)) {
345 dev_err(dev, "DMA End IRQ with no active buffer\n");
346 goto out;
347 }
348
349 vb = &pcdev->active->vb;
350 buf = container_of(vb, struct mx1_buffer, vb);
351 WARN_ON(buf->inwork || list_empty(&vb->queue));
352 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
353 vb, vb->baddr, vb->bsize);
354
355 mx1_camera_wakeup(pcdev, vb, buf);
356out:
357 spin_unlock_irqrestore(&pcdev->lock, flags);
358}
359
360static struct videobuf_queue_ops mx1_videobuf_ops = {
361 .buf_setup = mx1_videobuf_setup,
362 .buf_prepare = mx1_videobuf_prepare,
363 .buf_queue = mx1_videobuf_queue,
364 .buf_release = mx1_videobuf_release,
365};
366
367static void mx1_camera_init_videobuf(struct videobuf_queue *q,
368 struct soc_camera_device *icd)
369{
370 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
371 struct mx1_camera_dev *pcdev = ici->priv;
372
373 videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->parent,
374 &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
375 V4L2_FIELD_NONE,
376 sizeof(struct mx1_buffer), icd, &icd->video_lock);
377}
378
379static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
380{
381 unsigned int mclk = pcdev->mclk;
382 unsigned long div;
383 unsigned long lcdclk;
384
385 lcdclk = clk_get_rate(pcdev->clk);
386
387 /*
388 * We verify platform_mclk_10khz != 0, so if anyone breaks it, here
389 * they get a nice Oops
390 */
391 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
392
393 dev_dbg(pcdev->icd->parent,
394 "System clock %lukHz, target freq %dkHz, divisor %lu\n",
395 lcdclk / 1000, mclk / 1000, div);
396
397 return div;
398}
399
400static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
401{
402 unsigned int csicr1 = CSICR1_EN;
403
404 dev_dbg(pcdev->icd->parent, "Activate device\n");
405
406 clk_prepare_enable(pcdev->clk);
407
408 /* enable CSI before doing anything else */
409 __raw_writel(csicr1, pcdev->base + CSICR1);
410
411 csicr1 |= CSICR1_MCLKEN | CSICR1_FCC | CSICR1_GCLK_MODE;
412 csicr1 |= CSICR1_MCLKDIV(mclk_get_divisor(pcdev));
413 csicr1 |= CSICR1_RXFF_LEVEL(2); /* 16 words */
414
415 __raw_writel(csicr1, pcdev->base + CSICR1);
416}
417
418static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
419{
420 dev_dbg(pcdev->icd->parent, "Deactivate device\n");
421
422 /* Disable all CSI interface */
423 __raw_writel(0x00, pcdev->base + CSICR1);
424
425 clk_disable_unprepare(pcdev->clk);
426}
427
428/*
429 * The following two functions absolutely depend on the fact, that
430 * there can be only one camera on i.MX1/i.MXL camera sensor interface
431 */
432static int mx1_camera_add_device(struct soc_camera_device *icd)
433{
434 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
435 struct mx1_camera_dev *pcdev = ici->priv;
436
437 if (pcdev->icd)
438 return -EBUSY;
439
440 dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
441 icd->devnum);
442
443 mx1_camera_activate(pcdev);
444
445 pcdev->icd = icd;
446
447 return 0;
448}
449
450static void mx1_camera_remove_device(struct soc_camera_device *icd)
451{
452 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
453 struct mx1_camera_dev *pcdev = ici->priv;
454 unsigned int csicr1;
455
456 BUG_ON(icd != pcdev->icd);
457
458 /* disable interrupts */
459 csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
460 __raw_writel(csicr1, pcdev->base + CSICR1);
461
462 /* Stop DMA engine */
463 imx_dma_disable(pcdev->dma_chan);
464
465 dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
466 icd->devnum);
467
468 mx1_camera_deactivate(pcdev);
469
470 pcdev->icd = NULL;
471}
472
473static int mx1_camera_set_crop(struct soc_camera_device *icd,
474 struct v4l2_crop *a)
475{
476 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
477
478 return v4l2_subdev_call(sd, video, s_crop, a);
479}
480
481static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
482{
483 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
484 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
485 struct mx1_camera_dev *pcdev = ici->priv;
486 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
487 unsigned long common_flags;
488 unsigned int csicr1;
489 int ret;
490
491 /* MX1 supports only 8bit buswidth */
492 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
493 if (!ret) {
494 common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS);
495 if (!common_flags) {
496 dev_warn(icd->parent,
497 "Flags incompatible: camera 0x%x, host 0x%x\n",
498 cfg.flags, CSI_BUS_FLAGS);
499 return -EINVAL;
500 }
501 } else if (ret != -ENOIOCTLCMD) {
502 return ret;
503 } else {
504 common_flags = CSI_BUS_FLAGS;
505 }
506
507 /* Make choises, based on platform choice */
508 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
509 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
510 if (!pcdev->pdata ||
511 pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
512 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
513 else
514 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
515 }
516
517 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
518 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
519 if (!pcdev->pdata ||
520 pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
521 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
522 else
523 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
524 }
525
526 if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
527 (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
528 if (!pcdev->pdata ||
529 pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
530 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
531 else
532 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
533 }
534
535 cfg.flags = common_flags;
536 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
537 if (ret < 0 && ret != -ENOIOCTLCMD) {
538 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
539 common_flags, ret);
540 return ret;
541 }
542
543 csicr1 = __raw_readl(pcdev->base + CSICR1);
544
545 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
546 csicr1 |= CSICR1_REDGE;
547 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
548 csicr1 |= CSICR1_SOF_POL;
549 if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
550 csicr1 |= CSICR1_DATA_POL;
551
552 __raw_writel(csicr1, pcdev->base + CSICR1);
553
554 return 0;
555}
556
557static int mx1_camera_set_fmt(struct soc_camera_device *icd,
558 struct v4l2_format *f)
559{
560 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
561 const struct soc_camera_format_xlate *xlate;
562 struct v4l2_pix_format *pix = &f->fmt.pix;
563 struct v4l2_mbus_framefmt mf;
564 int ret, buswidth;
565
566 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
567 if (!xlate) {
568 dev_warn(icd->parent, "Format %x not found\n",
569 pix->pixelformat);
570 return -EINVAL;
571 }
572
573 buswidth = xlate->host_fmt->bits_per_sample;
574 if (buswidth > 8) {
575 dev_warn(icd->parent,
576 "bits-per-sample %d for format %x unsupported\n",
577 buswidth, pix->pixelformat);
578 return -EINVAL;
579 }
580
581 mf.width = pix->width;
582 mf.height = pix->height;
583 mf.field = pix->field;
584 mf.colorspace = pix->colorspace;
585 mf.code = xlate->code;
586
587 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
588 if (ret < 0)
589 return ret;
590
591 if (mf.code != xlate->code)
592 return -EINVAL;
593
594 pix->width = mf.width;
595 pix->height = mf.height;
596 pix->field = mf.field;
597 pix->colorspace = mf.colorspace;
598 icd->current_fmt = xlate;
599
600 return ret;
601}
602
603static int mx1_camera_try_fmt(struct soc_camera_device *icd,
604 struct v4l2_format *f)
605{
606 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
607 const struct soc_camera_format_xlate *xlate;
608 struct v4l2_pix_format *pix = &f->fmt.pix;
609 struct v4l2_mbus_framefmt mf;
610 int ret;
611 /* TODO: limit to mx1 hardware capabilities */
612
613 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
614 if (!xlate) {
615 dev_warn(icd->parent, "Format %x not found\n",
616 pix->pixelformat);
617 return -EINVAL;
618 }
619
620 mf.width = pix->width;
621 mf.height = pix->height;
622 mf.field = pix->field;
623 mf.colorspace = pix->colorspace;
624 mf.code = xlate->code;
625
626 /* limit to sensor capabilities */
627 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
628 if (ret < 0)
629 return ret;
630
631 pix->width = mf.width;
632 pix->height = mf.height;
633 pix->field = mf.field;
634 pix->colorspace = mf.colorspace;
635
636 return 0;
637}
638
639static int mx1_camera_reqbufs(struct soc_camera_device *icd,
640 struct v4l2_requestbuffers *p)
641{
642 int i;
643
644 /*
645 * This is for locking debugging only. I removed spinlocks and now I
646 * check whether .prepare is ever called on a linked buffer, or whether
647 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
648 * it hadn't triggered
649 */
650 for (i = 0; i < p->count; i++) {
651 struct mx1_buffer *buf = container_of(icd->vb_vidq.bufs[i],
652 struct mx1_buffer, vb);
653 buf->inwork = 0;
654 INIT_LIST_HEAD(&buf->vb.queue);
655 }
656
657 return 0;
658}
659
660static unsigned int mx1_camera_poll(struct file *file, poll_table *pt)
661{
662 struct soc_camera_device *icd = file->private_data;
663 struct mx1_buffer *buf;
664
665 buf = list_entry(icd->vb_vidq.stream.next, struct mx1_buffer,
666 vb.stream);
667
668 poll_wait(file, &buf->vb.done, pt);
669
670 if (buf->vb.state == VIDEOBUF_DONE ||
671 buf->vb.state == VIDEOBUF_ERROR)
672 return POLLIN | POLLRDNORM;
673
674 return 0;
675}
676
677static int mx1_camera_querycap(struct soc_camera_host *ici,
678 struct v4l2_capability *cap)
679{
680 /* cap->name is set by the friendly caller:-> */
681 strlcpy(cap->card, "i.MX1/i.MXL Camera", sizeof(cap->card));
682 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
683
684 return 0;
685}
686
687static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
688 .owner = THIS_MODULE,
689 .add = mx1_camera_add_device,
690 .remove = mx1_camera_remove_device,
691 .set_bus_param = mx1_camera_set_bus_param,
692 .set_crop = mx1_camera_set_crop,
693 .set_fmt = mx1_camera_set_fmt,
694 .try_fmt = mx1_camera_try_fmt,
695 .init_videobuf = mx1_camera_init_videobuf,
696 .reqbufs = mx1_camera_reqbufs,
697 .poll = mx1_camera_poll,
698 .querycap = mx1_camera_querycap,
699};
700
701static struct fiq_handler fh = {
702 .name = "csi_sof"
703};
704
705static int __init mx1_camera_probe(struct platform_device *pdev)
706{
707 struct mx1_camera_dev *pcdev;
708 struct resource *res;
709 struct pt_regs regs;
710 struct clk *clk;
711 void __iomem *base;
712 unsigned int irq;
713 int err = 0;
714
715 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
716 irq = platform_get_irq(pdev, 0);
717 if (!res || (int)irq <= 0) {
718 err = -ENODEV;
719 goto exit;
720 }
721
722 clk = clk_get(&pdev->dev, "csi_clk");
723 if (IS_ERR(clk)) {
724 err = PTR_ERR(clk);
725 goto exit;
726 }
727
728 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
729 if (!pcdev) {
730 dev_err(&pdev->dev, "Could not allocate pcdev\n");
731 err = -ENOMEM;
732 goto exit_put_clk;
733 }
734
735 pcdev->res = res;
736 pcdev->clk = clk;
737
738 pcdev->pdata = pdev->dev.platform_data;
739
740 if (pcdev->pdata)
741 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
742
743 if (!pcdev->mclk) {
744 dev_warn(&pdev->dev,
745 "mclk_10khz == 0! Please, fix your platform data. "
746 "Using default 20MHz\n");
747 pcdev->mclk = 20000000;
748 }
749
750 INIT_LIST_HEAD(&pcdev->capture);
751 spin_lock_init(&pcdev->lock);
752
753 /*
754 * Request the regions.
755 */
756 if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
757 err = -EBUSY;
758 goto exit_kfree;
759 }
760
761 base = ioremap(res->start, resource_size(res));
762 if (!base) {
763 err = -ENOMEM;
764 goto exit_release;
765 }
766 pcdev->irq = irq;
767 pcdev->base = base;
768
769 /* request dma */
770 pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH);
771 if (pcdev->dma_chan < 0) {
772 dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n");
773 err = -EBUSY;
774 goto exit_iounmap;
775 }
776 dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
777
778 imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL,
779 pcdev);
780
781 imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
782 IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0);
783 /* burst length : 16 words = 64 bytes */
784 imx_dma_config_burstlen(pcdev->dma_chan, 0);
785
786 /* request irq */
787 err = claim_fiq(&fh);
788 if (err) {
789 dev_err(&pdev->dev, "Camera interrupt register failed \n");
790 goto exit_free_dma;
791 }
792
793 set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end -
794 &mx1_camera_sof_fiq_start);
795
796 regs.ARM_r8 = (long)MX1_DMA_DIMR;
797 regs.ARM_r9 = (long)MX1_DMA_CCR(pcdev->dma_chan);
798 regs.ARM_r10 = (long)pcdev->base + CSICR1;
799 regs.ARM_fp = (long)pcdev->base + CSISR;
800 regs.ARM_sp = 1 << pcdev->dma_chan;
801 set_fiq_regs(&regs);
802
803 mxc_set_irq_fiq(irq, 1);
804 enable_fiq(irq);
805
806 pcdev->soc_host.drv_name = DRIVER_NAME;
807 pcdev->soc_host.ops = &mx1_soc_camera_host_ops;
808 pcdev->soc_host.priv = pcdev;
809 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
810 pcdev->soc_host.nr = pdev->id;
811 err = soc_camera_host_register(&pcdev->soc_host);
812 if (err)
813 goto exit_free_irq;
814
815 dev_info(&pdev->dev, "MX1 Camera driver loaded\n");
816
817 return 0;
818
819exit_free_irq:
820 disable_fiq(irq);
821 mxc_set_irq_fiq(irq, 0);
822 release_fiq(&fh);
823exit_free_dma:
824 imx_dma_free(pcdev->dma_chan);
825exit_iounmap:
826 iounmap(base);
827exit_release:
828 release_mem_region(res->start, resource_size(res));
829exit_kfree:
830 kfree(pcdev);
831exit_put_clk:
832 clk_put(clk);
833exit:
834 return err;
835}
836
837static int __exit mx1_camera_remove(struct platform_device *pdev)
838{
839 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
840 struct mx1_camera_dev *pcdev = container_of(soc_host,
841 struct mx1_camera_dev, soc_host);
842 struct resource *res;
843
844 imx_dma_free(pcdev->dma_chan);
845 disable_fiq(pcdev->irq);
846 mxc_set_irq_fiq(pcdev->irq, 0);
847 release_fiq(&fh);
848
849 clk_put(pcdev->clk);
850
851 soc_camera_host_unregister(soc_host);
852
853 iounmap(pcdev->base);
854
855 res = pcdev->res;
856 release_mem_region(res->start, resource_size(res));
857
858 kfree(pcdev);
859
860 dev_info(&pdev->dev, "MX1 Camera driver unloaded\n");
861
862 return 0;
863}
864
865static struct platform_driver mx1_camera_driver = {
866 .driver = {
867 .name = DRIVER_NAME,
868 },
869 .remove = __exit_p(mx1_camera_remove),
870};
871
872static int __init mx1_camera_init(void)
873{
874 return platform_driver_probe(&mx1_camera_driver, mx1_camera_probe);
875}
876
877static void __exit mx1_camera_exit(void)
878{
879 return platform_driver_unregister(&mx1_camera_driver);
880}
881
882module_init(mx1_camera_init);
883module_exit(mx1_camera_exit);
884
885MODULE_DESCRIPTION("i.MX1/i.MXL SoC Camera Host driver");
886MODULE_AUTHOR("Paulius Zaleckas <paulius.zaleckas@teltonika.lt>");
887MODULE_LICENSE("GPL v2");
888MODULE_VERSION(DRIVER_VERSION);
889MODULE_ALIAS("platform:" DRIVER_NAME);