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_sg_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");