2 * camera image capture (abstract) bus driver
4 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
6 * This driver provides an interface between platform-specific camera
7 * busses and camera devices. It should be used if the camera is
8 * connected not over a "proper" bus like PCI or USB, but over a
9 * special bus, like, for example, the Quick Capture interface on PXA270
10 * SoCs. Later it should also be used for i.MX31 SoCs from Freescale.
11 * It can handle multiple cameras and / or multiple busses, which can
12 * be used, e.g., in stereo-vision applications.
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/device.h>
22 #include <linux/list.h>
23 #include <linux/err.h>
24 #include <linux/mutex.h>
25 #include <linux/vmalloc.h>
27 #include <media/v4l2-common.h>
28 #include <media/v4l2-dev.h>
29 #include <media/soc_camera.h>
31 static LIST_HEAD(hosts
);
32 static LIST_HEAD(devices
);
33 static DEFINE_MUTEX(list_lock
);
34 static DEFINE_MUTEX(video_lock
);
36 const static struct soc_camera_data_format
*
37 format_by_fourcc(struct soc_camera_device
*icd
, unsigned int fourcc
)
41 for (i
= 0; i
< icd
->ops
->num_formats
; i
++)
42 if (icd
->ops
->formats
[i
].fourcc
== fourcc
)
43 return icd
->ops
->formats
+ i
;
47 static int soc_camera_try_fmt_cap(struct file
*file
, void *priv
,
48 struct v4l2_format
*f
)
50 struct soc_camera_file
*icf
= file
->private_data
;
51 struct soc_camera_device
*icd
= icf
->icd
;
52 struct soc_camera_host
*ici
=
53 to_soc_camera_host(icd
->dev
.parent
);
54 enum v4l2_field field
;
55 const struct soc_camera_data_format
*fmt
;
58 WARN_ON(priv
!= file
->private_data
);
60 fmt
= format_by_fourcc(icd
, f
->fmt
.pix
.pixelformat
);
62 dev_dbg(&icd
->dev
, "invalid format 0x%08x\n",
63 f
->fmt
.pix
.pixelformat
);
67 dev_dbg(&icd
->dev
, "fmt: 0x%08x\n", fmt
->fourcc
);
69 field
= f
->fmt
.pix
.field
;
71 if (field
== V4L2_FIELD_ANY
) {
72 field
= V4L2_FIELD_NONE
;
73 } else if (V4L2_FIELD_NONE
!= field
) {
74 dev_err(&icd
->dev
, "Field type invalid.\n");
78 /* limit to host capabilities */
79 ret
= ici
->try_fmt_cap(ici
, f
);
81 /* limit to sensor capabilities */
83 ret
= icd
->ops
->try_fmt_cap(icd
, f
);
85 /* calculate missing fields */
86 f
->fmt
.pix
.field
= field
;
87 f
->fmt
.pix
.bytesperline
=
88 (f
->fmt
.pix
.width
* fmt
->depth
) >> 3;
89 f
->fmt
.pix
.sizeimage
=
90 f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
95 static int soc_camera_enum_input(struct file
*file
, void *priv
,
96 struct v4l2_input
*inp
)
101 inp
->type
= V4L2_INPUT_TYPE_CAMERA
;
102 inp
->std
= V4L2_STD_UNKNOWN
;
103 strcpy(inp
->name
, "Camera");
108 static int soc_camera_g_input(struct file
*file
, void *priv
, unsigned int *i
)
115 static int soc_camera_s_input(struct file
*file
, void *priv
, unsigned int i
)
123 static int soc_camera_s_std(struct file
*file
, void *priv
, v4l2_std_id
*a
)
128 static int soc_camera_reqbufs(struct file
*file
, void *priv
,
129 struct v4l2_requestbuffers
*p
)
132 struct soc_camera_file
*icf
= file
->private_data
;
133 struct soc_camera_device
*icd
= icf
->icd
;
134 struct soc_camera_host
*ici
=
135 to_soc_camera_host(icd
->dev
.parent
);
137 WARN_ON(priv
!= file
->private_data
);
139 dev_dbg(&icd
->dev
, "%s: %d\n", __FUNCTION__
, p
->memory
);
141 ret
= videobuf_reqbufs(&icf
->vb_vidq
, p
);
145 return ici
->reqbufs(icf
, p
);
150 static int soc_camera_querybuf(struct file
*file
, void *priv
,
151 struct v4l2_buffer
*p
)
153 struct soc_camera_file
*icf
= file
->private_data
;
155 WARN_ON(priv
!= file
->private_data
);
157 return videobuf_querybuf(&icf
->vb_vidq
, p
);
160 static int soc_camera_qbuf(struct file
*file
, void *priv
,
161 struct v4l2_buffer
*p
)
163 struct soc_camera_file
*icf
= file
->private_data
;
165 WARN_ON(priv
!= file
->private_data
);
167 return videobuf_qbuf(&icf
->vb_vidq
, p
);
170 static int soc_camera_dqbuf(struct file
*file
, void *priv
,
171 struct v4l2_buffer
*p
)
173 struct soc_camera_file
*icf
= file
->private_data
;
175 WARN_ON(priv
!= file
->private_data
);
177 return videobuf_dqbuf(&icf
->vb_vidq
, p
, file
->f_flags
& O_NONBLOCK
);
180 static int soc_camera_open(struct inode
*inode
, struct file
*file
)
182 struct video_device
*vdev
= video_devdata(file
);
183 struct soc_camera_device
*icd
= container_of(vdev
->dev
,
184 struct soc_camera_device
, dev
);
185 struct soc_camera_host
*ici
=
186 to_soc_camera_host(icd
->dev
.parent
);
187 struct soc_camera_file
*icf
;
190 icf
= vmalloc(sizeof(*icf
));
196 if (!try_module_get(icd
->ops
->owner
)) {
197 dev_err(&icd
->dev
, "Couldn't lock sensor driver.\n");
202 if (!try_module_get(ici
->owner
)) {
203 dev_err(&icd
->dev
, "Couldn't lock capture bus driver.\n");
208 file
->private_data
= icf
;
209 dev_dbg(&icd
->dev
, "camera device open\n");
211 /* We must pass NULL as dev pointer, then all pci_* dma operations
212 * transform to normal dma_* ones. Do we need an irqlock? */
213 videobuf_queue_pci_init(&icf
->vb_vidq
, ici
->vbq_ops
, NULL
, NULL
,
214 V4L2_BUF_TYPE_VIDEO_CAPTURE
, V4L2_FIELD_NONE
,
220 module_put(icd
->ops
->owner
);
226 static int soc_camera_close(struct inode
*inode
, struct file
*file
)
228 struct soc_camera_file
*icf
= file
->private_data
;
229 struct soc_camera_device
*icd
= icf
->icd
;
230 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->dev
.parent
);
231 struct video_device
*vdev
= icd
->vdev
;
233 module_put(icd
->ops
->owner
);
234 module_put(ici
->owner
);
235 vfree(file
->private_data
);
237 dev_dbg(vdev
->dev
, "camera device close\n");
242 static int soc_camera_read(struct file
*file
, char __user
*buf
,
243 size_t count
, loff_t
*ppos
)
245 struct soc_camera_file
*icf
= file
->private_data
;
246 struct soc_camera_device
*icd
= icf
->icd
;
247 struct video_device
*vdev
= icd
->vdev
;
250 dev_err(vdev
->dev
, "camera device read not implemented\n");
255 static int soc_camera_mmap(struct file
*file
, struct vm_area_struct
*vma
)
257 struct soc_camera_file
*icf
= file
->private_data
;
258 struct soc_camera_device
*icd
= icf
->icd
;
261 dev_dbg(&icd
->dev
, "mmap called, vma=0x%08lx\n", (unsigned long)vma
);
263 err
= videobuf_mmap_mapper(&icf
->vb_vidq
, vma
);
265 dev_dbg(&icd
->dev
, "vma start=0x%08lx, size=%ld, ret=%d\n",
266 (unsigned long)vma
->vm_start
,
267 (unsigned long)vma
->vm_end
- (unsigned long)vma
->vm_start
,
273 static unsigned int soc_camera_poll(struct file
*file
, poll_table
*pt
)
275 struct soc_camera_file
*icf
= file
->private_data
;
276 struct soc_camera_device
*icd
= icf
->icd
;
277 struct soc_camera_host
*ici
=
278 to_soc_camera_host(icd
->dev
.parent
);
280 if (list_empty(&icf
->vb_vidq
.stream
)) {
281 dev_err(&icd
->dev
, "Trying to poll with no queued buffers!\n");
285 return ici
->poll(file
, pt
);
289 static struct file_operations soc_camera_fops
= {
290 .owner
= THIS_MODULE
,
291 .open
= soc_camera_open
,
292 .release
= soc_camera_close
,
293 .ioctl
= video_ioctl2
,
294 .read
= soc_camera_read
,
295 .mmap
= soc_camera_mmap
,
296 .poll
= soc_camera_poll
,
301 static int soc_camera_s_fmt_cap(struct file
*file
, void *priv
,
302 struct v4l2_format
*f
)
304 struct soc_camera_file
*icf
= file
->private_data
;
305 struct soc_camera_device
*icd
= icf
->icd
;
306 struct soc_camera_host
*ici
=
307 to_soc_camera_host(icd
->dev
.parent
);
309 struct v4l2_rect rect
;
310 const static struct soc_camera_data_format
*data_fmt
;
312 WARN_ON(priv
!= file
->private_data
);
314 data_fmt
= format_by_fourcc(icd
, f
->fmt
.pix
.pixelformat
);
318 /* cached_datawidth may be further adjusted by the ici */
319 icd
->cached_datawidth
= data_fmt
->depth
;
321 ret
= soc_camera_try_fmt_cap(file
, icf
, f
);
325 rect
.left
= icd
->x_current
;
326 rect
.top
= icd
->y_current
;
327 rect
.width
= f
->fmt
.pix
.width
;
328 rect
.height
= f
->fmt
.pix
.height
;
329 ret
= ici
->set_capture_format(icd
, f
->fmt
.pix
.pixelformat
, &rect
);
332 icd
->current_fmt
= data_fmt
;
333 icd
->width
= rect
.width
;
334 icd
->height
= rect
.height
;
335 icf
->vb_vidq
.field
= f
->fmt
.pix
.field
;
336 if (V4L2_BUF_TYPE_VIDEO_CAPTURE
!= f
->type
)
337 dev_warn(&icd
->dev
, "Attention! Wrong buf-type %d\n",
340 dev_dbg(&icd
->dev
, "set width: %d height: %d\n",
341 icd
->width
, icd
->height
);
347 static int soc_camera_enum_fmt_cap(struct file
*file
, void *priv
,
348 struct v4l2_fmtdesc
*f
)
350 struct soc_camera_file
*icf
= file
->private_data
;
351 struct soc_camera_device
*icd
= icf
->icd
;
352 const struct soc_camera_data_format
*format
;
354 WARN_ON(priv
!= file
->private_data
);
356 if (f
->index
>= icd
->ops
->num_formats
)
359 format
= &icd
->ops
->formats
[f
->index
];
361 strlcpy(f
->description
, format
->name
, sizeof(f
->description
));
362 f
->pixelformat
= format
->fourcc
;
366 static int soc_camera_g_fmt_cap(struct file
*file
, void *priv
,
367 struct v4l2_format
*f
)
369 struct soc_camera_file
*icf
= file
->private_data
;
370 struct soc_camera_device
*icd
= icf
->icd
;
372 WARN_ON(priv
!= file
->private_data
);
374 f
->fmt
.pix
.width
= icd
->width
;
375 f
->fmt
.pix
.height
= icd
->height
;
376 f
->fmt
.pix
.field
= icf
->vb_vidq
.field
;
377 f
->fmt
.pix
.pixelformat
= icd
->current_fmt
->fourcc
;
378 f
->fmt
.pix
.bytesperline
=
379 (f
->fmt
.pix
.width
* icd
->current_fmt
->depth
) >> 3;
380 f
->fmt
.pix
.sizeimage
=
381 f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
382 dev_dbg(&icd
->dev
, "current_fmt->fourcc: 0x%08x\n",
383 icd
->current_fmt
->fourcc
);
387 static int soc_camera_querycap(struct file
*file
, void *priv
,
388 struct v4l2_capability
*cap
)
390 struct soc_camera_file
*icf
= file
->private_data
;
391 struct soc_camera_device
*icd
= icf
->icd
;
392 struct soc_camera_host
*ici
=
393 to_soc_camera_host(icd
->dev
.parent
);
395 WARN_ON(priv
!= file
->private_data
);
397 strlcpy(cap
->driver
, ici
->drv_name
, sizeof(cap
->driver
));
398 return ici
->querycap(ici
, cap
);
401 static int soc_camera_streamon(struct file
*file
, void *priv
,
402 enum v4l2_buf_type i
)
404 struct soc_camera_file
*icf
= file
->private_data
;
405 struct soc_camera_device
*icd
= icf
->icd
;
407 WARN_ON(priv
!= file
->private_data
);
409 dev_dbg(&icd
->dev
, "%s\n", __FUNCTION__
);
411 if (i
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
414 icd
->ops
->start_capture(icd
);
416 /* This calls buf_queue from host driver's videobuf_queue_ops */
417 return videobuf_streamon(&icf
->vb_vidq
);
420 static int soc_camera_streamoff(struct file
*file
, void *priv
,
421 enum v4l2_buf_type i
)
423 struct soc_camera_file
*icf
= file
->private_data
;
424 struct soc_camera_device
*icd
= icf
->icd
;
426 WARN_ON(priv
!= file
->private_data
);
428 dev_dbg(&icd
->dev
, "%s\n", __FUNCTION__
);
430 if (i
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
433 /* This calls buf_release from host driver's videobuf_queue_ops for all
434 * remaining buffers. When the last buffer is freed, stop capture */
435 videobuf_streamoff(&icf
->vb_vidq
);
437 icd
->ops
->stop_capture(icd
);
442 static int soc_camera_queryctrl(struct file
*file
, void *priv
,
443 struct v4l2_queryctrl
*qc
)
445 struct soc_camera_file
*icf
= file
->private_data
;
446 struct soc_camera_device
*icd
= icf
->icd
;
449 WARN_ON(priv
!= file
->private_data
);
454 for (i
= 0; i
< icd
->ops
->num_controls
; i
++)
455 if (qc
->id
== icd
->ops
->controls
[i
].id
) {
456 memcpy(qc
, &(icd
->ops
->controls
[i
]),
464 static int soc_camera_g_ctrl(struct file
*file
, void *priv
,
465 struct v4l2_control
*ctrl
)
467 struct soc_camera_file
*icf
= file
->private_data
;
468 struct soc_camera_device
*icd
= icf
->icd
;
470 WARN_ON(priv
!= file
->private_data
);
474 if (icd
->gain
== (unsigned short)~0)
476 ctrl
->value
= icd
->gain
;
478 case V4L2_CID_EXPOSURE
:
479 if (icd
->exposure
== (unsigned short)~0)
481 ctrl
->value
= icd
->exposure
;
485 if (icd
->ops
->get_control
)
486 return icd
->ops
->get_control(icd
, ctrl
);
490 static int soc_camera_s_ctrl(struct file
*file
, void *priv
,
491 struct v4l2_control
*ctrl
)
493 struct soc_camera_file
*icf
= file
->private_data
;
494 struct soc_camera_device
*icd
= icf
->icd
;
496 WARN_ON(priv
!= file
->private_data
);
498 if (icd
->ops
->set_control
)
499 return icd
->ops
->set_control(icd
, ctrl
);
503 static int soc_camera_cropcap(struct file
*file
, void *fh
,
504 struct v4l2_cropcap
*a
)
506 struct soc_camera_file
*icf
= file
->private_data
;
507 struct soc_camera_device
*icd
= icf
->icd
;
509 a
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
510 a
->bounds
.left
= icd
->x_min
;
511 a
->bounds
.top
= icd
->y_min
;
512 a
->bounds
.width
= icd
->width_max
;
513 a
->bounds
.height
= icd
->height_max
;
514 a
->defrect
.left
= icd
->x_min
;
515 a
->defrect
.top
= icd
->y_min
;
516 a
->defrect
.width
= 640;
517 a
->defrect
.height
= 480;
518 a
->pixelaspect
.numerator
= 1;
519 a
->pixelaspect
.denominator
= 1;
524 static int soc_camera_g_crop(struct file
*file
, void *fh
,
527 struct soc_camera_file
*icf
= file
->private_data
;
528 struct soc_camera_device
*icd
= icf
->icd
;
530 a
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
531 a
->c
.left
= icd
->x_current
;
532 a
->c
.top
= icd
->y_current
;
533 a
->c
.width
= icd
->width
;
534 a
->c
.height
= icd
->height
;
539 static int soc_camera_s_crop(struct file
*file
, void *fh
,
542 struct soc_camera_file
*icf
= file
->private_data
;
543 struct soc_camera_device
*icd
= icf
->icd
;
544 struct soc_camera_host
*ici
=
545 to_soc_camera_host(icd
->dev
.parent
);
548 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
551 ret
= ici
->set_capture_format(icd
, 0, &a
->c
);
553 icd
->width
= a
->c
.width
;
554 icd
->height
= a
->c
.height
;
555 icd
->x_current
= a
->c
.left
;
556 icd
->y_current
= a
->c
.top
;
562 static int soc_camera_g_chip_ident(struct file
*file
, void *fh
,
563 struct v4l2_chip_ident
*id
)
565 struct soc_camera_file
*icf
= file
->private_data
;
566 struct soc_camera_device
*icd
= icf
->icd
;
568 if (!icd
->ops
->get_chip_id
)
571 return icd
->ops
->get_chip_id(icd
, id
);
574 #ifdef CONFIG_VIDEO_ADV_DEBUG
575 static int soc_camera_g_register(struct file
*file
, void *fh
,
576 struct v4l2_register
*reg
)
578 struct soc_camera_file
*icf
= file
->private_data
;
579 struct soc_camera_device
*icd
= icf
->icd
;
581 if (!icd
->ops
->get_register
)
584 return icd
->ops
->get_register(icd
, reg
);
587 static int soc_camera_s_register(struct file
*file
, void *fh
,
588 struct v4l2_register
*reg
)
590 struct soc_camera_file
*icf
= file
->private_data
;
591 struct soc_camera_device
*icd
= icf
->icd
;
593 if (!icd
->ops
->set_register
)
596 return icd
->ops
->set_register(icd
, reg
);
600 static int device_register_link(struct soc_camera_device
*icd
)
602 int ret
= device_register(&icd
->dev
);
605 /* Prevent calling device_unregister() */
606 icd
->dev
.parent
= NULL
;
607 dev_err(&icd
->dev
, "Cannot register device: %d\n", ret
);
608 /* Even if probe() was unsuccessful for all registered drivers,
609 * device_register() returns 0, and we add the link, just to
610 * document this camera's control device */
611 } else if (icd
->control
)
612 /* Have to sysfs_remove_link() before device_unregister()? */
613 if (sysfs_create_link(&icd
->dev
.kobj
, &icd
->control
->kobj
,
616 "Failed creating the control symlink\n");
620 /* So far this function cannot fail */
621 static void scan_add_host(struct soc_camera_host
*ici
)
623 struct soc_camera_device
*icd
;
625 mutex_lock(&list_lock
);
627 list_for_each_entry(icd
, &devices
, list
) {
628 if (icd
->iface
== ici
->nr
) {
629 icd
->dev
.parent
= &ici
->dev
;
630 device_register_link(icd
);
634 mutex_unlock(&list_lock
);
637 /* return: 0 if no match found or a match found and
638 * device_register() successful, error code otherwise */
639 static int scan_add_device(struct soc_camera_device
*icd
)
641 struct soc_camera_host
*ici
;
644 mutex_lock(&list_lock
);
646 list_add_tail(&icd
->list
, &devices
);
648 /* Watch out for class_for_each_device / class_find_device API by
649 * Dave Young <hidave.darkstar@gmail.com> */
650 list_for_each_entry(ici
, &hosts
, list
) {
651 if (icd
->iface
== ici
->nr
) {
653 icd
->dev
.parent
= &ici
->dev
;
658 mutex_unlock(&list_lock
);
661 ret
= device_register_link(icd
);
666 static int soc_camera_probe(struct device
*dev
)
668 struct soc_camera_device
*icd
= to_soc_camera_dev(dev
);
669 struct soc_camera_host
*ici
=
670 to_soc_camera_host(icd
->dev
.parent
);
680 ret
= icd
->probe(icd
);
684 const struct v4l2_queryctrl
*qctrl
;
686 qctrl
= soc_camera_find_qctrl(icd
->ops
, V4L2_CID_GAIN
);
687 icd
->gain
= qctrl
? qctrl
->default_value
: (unsigned short)~0;
688 qctrl
= soc_camera_find_qctrl(icd
->ops
, V4L2_CID_EXPOSURE
);
689 icd
->exposure
= qctrl
? qctrl
->default_value
:
696 /* This is called on device_unregister, which only means we have to disconnect
697 * from the host, but not remove ourselves from the device list */
698 static int soc_camera_remove(struct device
*dev
)
700 struct soc_camera_device
*icd
= to_soc_camera_dev(dev
);
701 struct soc_camera_host
*ici
=
702 to_soc_camera_host(icd
->dev
.parent
);
712 static struct bus_type soc_camera_bus_type
= {
713 .name
= "soc-camera",
714 .probe
= soc_camera_probe
,
715 .remove
= soc_camera_remove
,
718 static struct device_driver ic_drv
= {
720 .bus
= &soc_camera_bus_type
,
721 .owner
= THIS_MODULE
,
725 * Image capture host - this is a host device, not a bus device, so,
726 * no bus reference, no probing.
728 static struct class soc_camera_host_class
= {
729 .owner
= THIS_MODULE
,
730 .name
= "camera_host",
733 static void dummy_release(struct device
*dev
)
737 int soc_camera_host_register(struct soc_camera_host
*ici
, struct module
*owner
)
740 struct soc_camera_host
*ix
;
742 if (!ici
->vbq_ops
|| !ici
->add
|| !ici
->remove
|| !owner
)
745 /* Number might be equal to the platform device ID */
746 sprintf(ici
->dev
.bus_id
, "camera_host%d", ici
->nr
);
747 ici
->dev
.class = &soc_camera_host_class
;
749 mutex_lock(&list_lock
);
750 list_for_each_entry(ix
, &hosts
, list
) {
751 if (ix
->nr
== ici
->nr
) {
752 mutex_unlock(&list_lock
);
757 list_add_tail(&ici
->list
, &hosts
);
758 mutex_unlock(&list_lock
);
761 ici
->dev
.release
= dummy_release
;
763 ret
= device_register(&ici
->dev
);
773 mutex_lock(&list_lock
);
774 list_del(&ici
->list
);
775 mutex_unlock(&list_lock
);
779 EXPORT_SYMBOL(soc_camera_host_register
);
781 /* Unregister all clients! */
782 void soc_camera_host_unregister(struct soc_camera_host
*ici
)
784 struct soc_camera_device
*icd
;
786 mutex_lock(&list_lock
);
788 list_del(&ici
->list
);
790 list_for_each_entry(icd
, &devices
, list
) {
791 if (icd
->dev
.parent
== &ici
->dev
) {
792 device_unregister(&icd
->dev
);
793 /* Not before device_unregister(), .remove
794 * needs parent to call ici->remove() */
795 icd
->dev
.parent
= NULL
;
796 memset(&icd
->dev
.kobj
, 0, sizeof(icd
->dev
.kobj
));
800 mutex_unlock(&list_lock
);
802 device_unregister(&ici
->dev
);
804 EXPORT_SYMBOL(soc_camera_host_unregister
);
806 /* Image capture device */
807 int soc_camera_device_register(struct soc_camera_device
*icd
)
809 struct soc_camera_device
*ix
;
815 for (i
= 0; i
< 256 && num
< 0; i
++) {
817 list_for_each_entry(ix
, &devices
, list
) {
818 if (ix
->iface
== icd
->iface
&& ix
->devnum
== i
) {
826 /* ok, we have 256 cameras on this host...
827 * man, stay reasonable... */
831 icd
->dev
.bus
= &soc_camera_bus_type
;
832 snprintf(icd
->dev
.bus_id
, sizeof(icd
->dev
.bus_id
),
833 "%u-%u", icd
->iface
, icd
->devnum
);
835 icd
->dev
.release
= dummy_release
;
837 if (icd
->ops
->get_datawidth
)
838 icd
->cached_datawidth
= icd
->ops
->get_datawidth(icd
);
840 return scan_add_device(icd
);
842 EXPORT_SYMBOL(soc_camera_device_register
);
844 void soc_camera_device_unregister(struct soc_camera_device
*icd
)
846 mutex_lock(&list_lock
);
847 list_del(&icd
->list
);
849 /* The bus->remove will be eventually called */
851 device_unregister(&icd
->dev
);
852 mutex_unlock(&list_lock
);
854 EXPORT_SYMBOL(soc_camera_device_unregister
);
856 int soc_camera_video_start(struct soc_camera_device
*icd
)
858 struct soc_camera_host
*ici
= to_soc_camera_host(icd
->dev
.parent
);
860 struct video_device
*vdev
;
862 if (!icd
->dev
.parent
)
865 vdev
= video_device_alloc();
868 dev_dbg(&ici
->dev
, "Allocated video_device %p\n", vdev
);
870 strlcpy(vdev
->name
, ici
->drv_name
, sizeof(vdev
->name
));
871 /* Maybe better &ici->dev */
872 vdev
->dev
= &icd
->dev
;
873 vdev
->type
= VID_TYPE_CAPTURE
;
874 vdev
->current_norm
= V4L2_STD_UNKNOWN
;
875 vdev
->fops
= &soc_camera_fops
;
876 vdev
->release
= video_device_release
;
878 vdev
->tvnorms
= V4L2_STD_UNKNOWN
,
879 vdev
->vidioc_querycap
= soc_camera_querycap
;
880 vdev
->vidioc_g_fmt_cap
= soc_camera_g_fmt_cap
;
881 vdev
->vidioc_enum_fmt_cap
= soc_camera_enum_fmt_cap
;
882 vdev
->vidioc_s_fmt_cap
= soc_camera_s_fmt_cap
;
883 vdev
->vidioc_enum_input
= soc_camera_enum_input
;
884 vdev
->vidioc_g_input
= soc_camera_g_input
;
885 vdev
->vidioc_s_input
= soc_camera_s_input
;
886 vdev
->vidioc_s_std
= soc_camera_s_std
;
887 vdev
->vidioc_reqbufs
= soc_camera_reqbufs
;
888 vdev
->vidioc_try_fmt_cap
= soc_camera_try_fmt_cap
;
889 vdev
->vidioc_querybuf
= soc_camera_querybuf
;
890 vdev
->vidioc_qbuf
= soc_camera_qbuf
;
891 vdev
->vidioc_dqbuf
= soc_camera_dqbuf
;
892 vdev
->vidioc_streamon
= soc_camera_streamon
;
893 vdev
->vidioc_streamoff
= soc_camera_streamoff
;
894 vdev
->vidioc_queryctrl
= soc_camera_queryctrl
;
895 vdev
->vidioc_g_ctrl
= soc_camera_g_ctrl
;
896 vdev
->vidioc_s_ctrl
= soc_camera_s_ctrl
;
897 vdev
->vidioc_cropcap
= soc_camera_cropcap
;
898 vdev
->vidioc_g_crop
= soc_camera_g_crop
;
899 vdev
->vidioc_s_crop
= soc_camera_s_crop
;
900 vdev
->vidioc_g_chip_ident
= soc_camera_g_chip_ident
;
901 #ifdef CONFIG_VIDEO_ADV_DEBUG
902 vdev
->vidioc_g_register
= soc_camera_g_register
;
903 vdev
->vidioc_s_register
= soc_camera_s_register
;
906 icd
->current_fmt
= &icd
->ops
->formats
[0];
908 err
= video_register_device(vdev
, VFL_TYPE_GRABBER
, vdev
->minor
);
910 dev_err(vdev
->dev
, "video_register_device failed\n");
918 video_device_release(vdev
);
922 EXPORT_SYMBOL(soc_camera_video_start
);
924 void soc_camera_video_stop(struct soc_camera_device
*icd
)
926 struct video_device
*vdev
= icd
->vdev
;
928 dev_dbg(&icd
->dev
, "%s\n", __FUNCTION__
);
930 if (!icd
->dev
.parent
|| !vdev
)
933 mutex_lock(&video_lock
);
934 video_unregister_device(vdev
);
936 mutex_unlock(&video_lock
);
938 EXPORT_SYMBOL(soc_camera_video_stop
);
940 static int __init
soc_camera_init(void)
942 int ret
= bus_register(&soc_camera_bus_type
);
945 ret
= driver_register(&ic_drv
);
948 ret
= class_register(&soc_camera_host_class
);
955 driver_unregister(&ic_drv
);
957 bus_unregister(&soc_camera_bus_type
);
961 static void __exit
soc_camera_exit(void)
963 class_unregister(&soc_camera_host_class
);
964 driver_unregister(&ic_drv
);
965 bus_unregister(&soc_camera_bus_type
);
968 module_init(soc_camera_init
);
969 module_exit(soc_camera_exit
);
971 MODULE_DESCRIPTION("Image capture bus driver");
972 MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
973 MODULE_LICENSE("GPL");