aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/soc_camera.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:43:33 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:18:35 -0400
commit979ea1ddf80ac7383acdea03471355ca62702539 (patch)
tree2ee4c73eb672c1ee8167ed7e0906bac6f3b00e69 /drivers/media/video/soc_camera.c
parent0bab829de1ab60d8c3cbf7e402192bb9446840b7 (diff)
V4L/DVB (12510): soc-camera: (partially) convert to v4l2-(sub)dev API
Convert the soc-camera framework to use the v4l2-(sub)dev API. Start using v4l2-subdev operations. Only a part of the interface between the soc_camera core, soc_camera host drivers on one side and soc_camera device drivers on the other side is replaced so far. The rest of the interface will be replaced in incremental steps, and will require extensions and, possibly, modifications to the v4l2-subdev code. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/soc_camera.c')
-rw-r--r--drivers/media/video/soc_camera.c250
1 files changed, 148 insertions, 102 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 20ef5c773fae..0a1cb40bfbf6 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -170,8 +170,6 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
170 170
171 WARN_ON(priv != file->private_data); 171 WARN_ON(priv != file->private_data);
172 172
173 dev_dbg(&icd->dev, "%s: %d\n", __func__, p->memory);
174
175 ret = videobuf_reqbufs(&icf->vb_vidq, p); 173 ret = videobuf_reqbufs(&icf->vb_vidq, p);
176 if (ret < 0) 174 if (ret < 0)
177 return ret; 175 return ret;
@@ -285,7 +283,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
285 return ret; 283 return ret;
286 } else if (!icd->current_fmt || 284 } else if (!icd->current_fmt ||
287 icd->current_fmt->fourcc != pix->pixelformat) { 285 icd->current_fmt->fourcc != pix->pixelformat) {
288 dev_err(ici->dev, 286 dev_err(ici->v4l2_dev.dev,
289 "Host driver hasn't set up current format correctly!\n"); 287 "Host driver hasn't set up current format correctly!\n");
290 return -EINVAL; 288 return -EINVAL;
291 } 289 }
@@ -308,20 +306,13 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
308 306
309static int soc_camera_open(struct file *file) 307static int soc_camera_open(struct file *file)
310{ 308{
311 struct video_device *vdev; 309 struct video_device *vdev = video_devdata(file);
312 struct soc_camera_device *icd; 310 struct soc_camera_device *icd = container_of(vdev->parent, struct soc_camera_device, dev);
311 struct soc_camera_link *icl = to_soc_camera_link(icd);
313 struct soc_camera_host *ici; 312 struct soc_camera_host *ici;
314 struct soc_camera_file *icf; 313 struct soc_camera_file *icf;
315 int ret; 314 int ret;
316 315
317 /*
318 * It is safe to dereference these pointers now as long as a user has
319 * the video device open - we are protected by the held cdev reference.
320 */
321
322 vdev = video_devdata(file);
323 icd = container_of(vdev->parent, struct soc_camera_device, dev);
324
325 if (!icd->ops) 316 if (!icd->ops)
326 /* No device driver attached */ 317 /* No device driver attached */
327 return -ENODEV; 318 return -ENODEV;
@@ -332,12 +323,6 @@ static int soc_camera_open(struct file *file)
332 if (!icf) 323 if (!icf)
333 return -ENOMEM; 324 return -ENOMEM;
334 325
335 if (!try_module_get(icd->ops->owner)) {
336 dev_err(&icd->dev, "Couldn't lock sensor driver.\n");
337 ret = -EINVAL;
338 goto emgd;
339 }
340
341 if (!try_module_get(ici->ops->owner)) { 326 if (!try_module_get(ici->ops->owner)) {
342 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); 327 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
343 ret = -EINVAL; 328 ret = -EINVAL;
@@ -366,47 +351,65 @@ static int soc_camera_open(struct file *file)
366 if (ret < 0) 351 if (ret < 0)
367 goto eiufmt; 352 goto eiufmt;
368 353
369 dev_dbg(&icd->dev, "Using fmt %x\n", icd->current_fmt->fourcc);
370
371 f.fmt.pix.pixelformat = icd->current_fmt->fourcc; 354 f.fmt.pix.pixelformat = icd->current_fmt->fourcc;
372 f.fmt.pix.colorspace = icd->current_fmt->colorspace; 355 f.fmt.pix.colorspace = icd->current_fmt->colorspace;
373 356
357 if (icl->power) {
358 ret = icl->power(icd->pdev, 1);
359 if (ret < 0)
360 goto epower;
361 }
362
363 /* The camera could have been already on, try to reset */
364 if (icl->reset)
365 icl->reset(icd->pdev);
366
374 ret = ici->ops->add(icd); 367 ret = ici->ops->add(icd);
375 if (ret < 0) { 368 if (ret < 0) {
376 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); 369 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
377 goto eiciadd; 370 goto eiciadd;
378 } 371 }
379 372
373 if (icd->ops->init) {
374 ret = icd->ops->init(icd);
375 if (ret < 0)
376 goto einit;
377 }
378
380 /* Try to configure with default parameters */ 379 /* Try to configure with default parameters */
381 ret = soc_camera_set_fmt(icf, &f); 380 ret = soc_camera_set_fmt(icf, &f);
382 if (ret < 0) 381 if (ret < 0)
383 goto esfmt; 382 goto esfmt;
384 } 383 }
385 384
386 mutex_unlock(&icd->video_lock);
387
388 file->private_data = icf; 385 file->private_data = icf;
389 dev_dbg(&icd->dev, "camera device open\n"); 386 dev_dbg(&icd->dev, "camera device open\n");
390 387
391 ici->ops->init_videobuf(&icf->vb_vidq, icd); 388 ici->ops->init_videobuf(&icf->vb_vidq, icd);
392 389
390 mutex_unlock(&icd->video_lock);
391
393 return 0; 392 return 0;
394 393
395 /* 394 /*
396 * First three errors are entered with the .video_lock held 395 * First five errors are entered with the .video_lock held
397 * and use_count == 1 396 * and use_count == 1
398 */ 397 */
399esfmt: 398esfmt:
399 if (icd->ops->release)
400 icd->ops->release(icd);
401einit:
400 ici->ops->remove(icd); 402 ici->ops->remove(icd);
401eiciadd: 403eiciadd:
404 if (icl->power)
405 icl->power(icd->pdev, 0);
406epower:
402 soc_camera_free_user_formats(icd); 407 soc_camera_free_user_formats(icd);
403eiufmt: 408eiufmt:
404 icd->use_count--; 409 icd->use_count--;
405 mutex_unlock(&icd->video_lock); 410 mutex_unlock(&icd->video_lock);
406 module_put(ici->ops->owner); 411 module_put(ici->ops->owner);
407emgi: 412emgi:
408 module_put(icd->ops->owner);
409emgd:
410 vfree(icf); 413 vfree(icf);
411 return ret; 414 return ret;
412} 415}
@@ -421,13 +424,18 @@ static int soc_camera_close(struct file *file)
421 mutex_lock(&icd->video_lock); 424 mutex_lock(&icd->video_lock);
422 icd->use_count--; 425 icd->use_count--;
423 if (!icd->use_count) { 426 if (!icd->use_count) {
427 struct soc_camera_link *icl = to_soc_camera_link(icd);
428
429 if (icd->ops->release)
430 icd->ops->release(icd);
424 ici->ops->remove(icd); 431 ici->ops->remove(icd);
432 if (icl->power)
433 icl->power(icd->pdev, 0);
425 soc_camera_free_user_formats(icd); 434 soc_camera_free_user_formats(icd);
426 } 435 }
427 436
428 mutex_unlock(&icd->video_lock); 437 mutex_unlock(&icd->video_lock);
429 438
430 module_put(icd->ops->owner);
431 module_put(ici->ops->owner); 439 module_put(ici->ops->owner);
432 440
433 vfree(icf); 441 vfree(icf);
@@ -575,18 +583,17 @@ static int soc_camera_streamon(struct file *file, void *priv,
575{ 583{
576 struct soc_camera_file *icf = file->private_data; 584 struct soc_camera_file *icf = file->private_data;
577 struct soc_camera_device *icd = icf->icd; 585 struct soc_camera_device *icd = icf->icd;
586 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
578 int ret; 587 int ret;
579 588
580 WARN_ON(priv != file->private_data); 589 WARN_ON(priv != file->private_data);
581 590
582 dev_dbg(&icd->dev, "%s\n", __func__);
583
584 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 591 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
585 return -EINVAL; 592 return -EINVAL;
586 593
587 mutex_lock(&icd->video_lock); 594 mutex_lock(&icd->video_lock);
588 595
589 icd->ops->start_capture(icd); 596 v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, s_stream, 1);
590 597
591 /* This calls buf_queue from host driver's videobuf_queue_ops */ 598 /* This calls buf_queue from host driver's videobuf_queue_ops */
592 ret = videobuf_streamon(&icf->vb_vidq); 599 ret = videobuf_streamon(&icf->vb_vidq);
@@ -601,11 +608,10 @@ static int soc_camera_streamoff(struct file *file, void *priv,
601{ 608{
602 struct soc_camera_file *icf = file->private_data; 609 struct soc_camera_file *icf = file->private_data;
603 struct soc_camera_device *icd = icf->icd; 610 struct soc_camera_device *icd = icf->icd;
611 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
604 612
605 WARN_ON(priv != file->private_data); 613 WARN_ON(priv != file->private_data);
606 614
607 dev_dbg(&icd->dev, "%s\n", __func__);
608
609 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 615 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
610 return -EINVAL; 616 return -EINVAL;
611 617
@@ -615,7 +621,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
615 * remaining buffers. When the last buffer is freed, stop capture */ 621 * remaining buffers. When the last buffer is freed, stop capture */
616 videobuf_streamoff(&icf->vb_vidq); 622 videobuf_streamoff(&icf->vb_vidq);
617 623
618 icd->ops->stop_capture(icd); 624 v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, s_stream, 0);
619 625
620 mutex_unlock(&icd->video_lock); 626 mutex_unlock(&icd->video_lock);
621 627
@@ -649,6 +655,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
649{ 655{
650 struct soc_camera_file *icf = file->private_data; 656 struct soc_camera_file *icf = file->private_data;
651 struct soc_camera_device *icd = icf->icd; 657 struct soc_camera_device *icd = icf->icd;
658 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
652 659
653 WARN_ON(priv != file->private_data); 660 WARN_ON(priv != file->private_data);
654 661
@@ -665,9 +672,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
665 return 0; 672 return 0;
666 } 673 }
667 674
668 if (icd->ops->get_control) 675 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_ctrl, ctrl);
669 return icd->ops->get_control(icd, ctrl);
670 return -EINVAL;
671} 676}
672 677
673static int soc_camera_s_ctrl(struct file *file, void *priv, 678static int soc_camera_s_ctrl(struct file *file, void *priv,
@@ -675,12 +680,11 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
675{ 680{
676 struct soc_camera_file *icf = file->private_data; 681 struct soc_camera_file *icf = file->private_data;
677 struct soc_camera_device *icd = icf->icd; 682 struct soc_camera_device *icd = icf->icd;
683 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
678 684
679 WARN_ON(priv != file->private_data); 685 WARN_ON(priv != file->private_data);
680 686
681 if (icd->ops->set_control) 687 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_ctrl, ctrl);
682 return icd->ops->set_control(icd, ctrl);
683 return -EINVAL;
684} 688}
685 689
686static int soc_camera_cropcap(struct file *file, void *fh, 690static int soc_camera_cropcap(struct file *file, void *fh,
@@ -751,11 +755,9 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh,
751{ 755{
752 struct soc_camera_file *icf = file->private_data; 756 struct soc_camera_file *icf = file->private_data;
753 struct soc_camera_device *icd = icf->icd; 757 struct soc_camera_device *icd = icf->icd;
758 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
754 759
755 if (!icd->ops->get_chip_id) 760 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_chip_ident, id);
756 return -EINVAL;
757
758 return icd->ops->get_chip_id(icd, id);
759} 761}
760 762
761#ifdef CONFIG_VIDEO_ADV_DEBUG 763#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -764,11 +766,9 @@ static int soc_camera_g_register(struct file *file, void *fh,
764{ 766{
765 struct soc_camera_file *icf = file->private_data; 767 struct soc_camera_file *icf = file->private_data;
766 struct soc_camera_device *icd = icf->icd; 768 struct soc_camera_device *icd = icf->icd;
769 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
767 770
768 if (!icd->ops->get_register) 771 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_register, reg);
769 return -EINVAL;
770
771 return icd->ops->get_register(icd, reg);
772} 772}
773 773
774static int soc_camera_s_register(struct file *file, void *fh, 774static int soc_camera_s_register(struct file *file, void *fh,
@@ -776,11 +776,9 @@ static int soc_camera_s_register(struct file *file, void *fh,
776{ 776{
777 struct soc_camera_file *icf = file->private_data; 777 struct soc_camera_file *icf = file->private_data;
778 struct soc_camera_device *icd = icf->icd; 778 struct soc_camera_device *icd = icf->icd;
779 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
779 780
780 if (!icd->ops->set_register) 781 return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_register, reg);
781 return -EINVAL;
782
783 return icd->ops->set_register(icd, reg);
784} 782}
785#endif 783#endif
786 784
@@ -794,7 +792,7 @@ static void scan_add_host(struct soc_camera_host *ici)
794 list_for_each_entry(icd, &devices, list) { 792 list_for_each_entry(icd, &devices, list) {
795 if (icd->iface == ici->nr) { 793 if (icd->iface == ici->nr) {
796 int ret; 794 int ret;
797 icd->dev.parent = ici->dev; 795 icd->dev.parent = ici->v4l2_dev.dev;
798 dev_set_name(&icd->dev, "%u-%u", icd->iface, 796 dev_set_name(&icd->dev, "%u-%u", icd->iface,
799 icd->devnum); 797 icd->devnum);
800 ret = device_register(&icd->dev); 798 ret = device_register(&icd->dev);
@@ -814,7 +812,9 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
814 struct soc_camera_link *icl) 812 struct soc_camera_link *icl)
815{ 813{
816 struct i2c_client *client; 814 struct i2c_client *client;
815 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
817 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id); 816 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
817 struct v4l2_subdev *subdev;
818 int ret; 818 int ret;
819 819
820 if (!adap) { 820 if (!adap) {
@@ -826,17 +826,16 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
826 826
827 icl->board_info->platform_data = icd; 827 icl->board_info->platform_data = icd;
828 828
829 client = i2c_new_device(adap, icl->board_info); 829 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
830 if (!client) { 830 icl->module_name, icl->board_info, NULL);
831 if (!subdev) {
831 ret = -ENOMEM; 832 ret = -ENOMEM;
832 goto ei2cnd; 833 goto ei2cnd;
833 } 834 }
834 835
835 /* 836 subdev->grp_id = (__u32)icd;
836 * We set icd drvdata at two locations - here and in 837 client = subdev->priv;
837 * soc_camera_video_start(). Depending on the module loading / 838
838 * initialisation order one of these locations will be entered first
839 */
840 /* Use to_i2c_client(dev) to recover the i2c client */ 839 /* Use to_i2c_client(dev) to recover the i2c client */
841 dev_set_drvdata(&icd->dev, &client->dev); 840 dev_set_drvdata(&icd->dev, &client->dev);
842 841
@@ -852,6 +851,7 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd)
852 struct i2c_client *client = 851 struct i2c_client *client =
853 to_i2c_client(to_soc_camera_control(icd)); 852 to_i2c_client(to_soc_camera_control(icd));
854 dev_set_drvdata(&icd->dev, NULL); 853 dev_set_drvdata(&icd->dev, NULL);
854 v4l2_device_unregister_subdev(i2c_get_clientdata(client));
855 i2c_unregister_device(client); 855 i2c_unregister_device(client);
856 i2c_put_adapter(client->adapter); 856 i2c_put_adapter(client->adapter);
857} 857}
@@ -860,16 +860,37 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd)
860#define soc_camera_free_i2c(icd) do {} while (0) 860#define soc_camera_free_i2c(icd) do {} while (0)
861#endif 861#endif
862 862
863static int soc_camera_video_start(struct soc_camera_device *icd);
863static int video_dev_create(struct soc_camera_device *icd); 864static int video_dev_create(struct soc_camera_device *icd);
864/* Called during host-driver probe */ 865/* Called during host-driver probe */
865static int soc_camera_probe(struct device *dev) 866static int soc_camera_probe(struct device *dev)
866{ 867{
867 struct soc_camera_device *icd = to_soc_camera_dev(dev); 868 struct soc_camera_device *icd = to_soc_camera_dev(dev);
869 struct soc_camera_host *ici = to_soc_camera_host(dev->parent);
868 struct soc_camera_link *icl = to_soc_camera_link(icd); 870 struct soc_camera_link *icl = to_soc_camera_link(icd);
871 struct device *control = NULL;
869 int ret; 872 int ret;
870 873
871 dev_info(dev, "Probing %s\n", dev_name(dev)); 874 dev_info(dev, "Probing %s\n", dev_name(dev));
872 875
876 if (icl->power) {
877 ret = icl->power(icd->pdev, 1);
878 if (ret < 0) {
879 dev_err(dev,
880 "Platform failed to power-on the camera.\n");
881 goto epower;
882 }
883 }
884
885 /* The camera could have been already on, try to reset */
886 if (icl->reset)
887 icl->reset(icd->pdev);
888
889 ret = ici->ops->add(icd);
890 if (ret < 0)
891 goto eadd;
892
893 /* Must have icd->vdev before registering the device */
873 ret = video_dev_create(icd); 894 ret = video_dev_create(icd);
874 if (ret < 0) 895 if (ret < 0)
875 goto evdc; 896 goto evdc;
@@ -883,34 +904,61 @@ static int soc_camera_probe(struct device *dev)
883 ret = -EINVAL; 904 ret = -EINVAL;
884 goto eadddev; 905 goto eadddev;
885 } else { 906 } else {
907 if (icl->module_name)
908 ret = request_module(icl->module_name);
909
886 ret = icl->add_device(icl, &icd->dev); 910 ret = icl->add_device(icl, &icd->dev);
887 if (ret < 0) 911 if (ret < 0)
888 goto eadddev; 912 goto eadddev;
889 }
890 913
891 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, icd->vdev->minor); 914 /* FIXME: this is racy, have to use driver-binding notification */
892 if (ret < 0) { 915 control = to_soc_camera_control(icd);
893 dev_err(&icd->dev, "video_register_device failed: %d\n", ret); 916 if (!control || !control->driver ||
894 goto evidregd; 917 !try_module_get(control->driver->owner)) {
918 icl->del_device(icl);
919 goto enodrv;
920 }
895 } 921 }
896 922
923 /* ..._video_start() will create a device node, so we have to protect */
924 mutex_lock(&icd->video_lock);
925
926 ret = soc_camera_video_start(icd);
927 if (ret < 0)
928 goto evidstart;
929
897 /* Do we have to sysfs_remove_link() before device_unregister()? */ 930 /* Do we have to sysfs_remove_link() before device_unregister()? */
898 if (to_soc_camera_control(icd) && 931 if (to_soc_camera_control(icd) &&
899 sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj, 932 sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj,
900 "control")) 933 "control"))
901 dev_warn(&icd->dev, "Failed creating the control symlink\n"); 934 dev_warn(&icd->dev, "Failed creating the control symlink\n");
902 935
936 ici->ops->remove(icd);
937
938 if (icl->power)
939 icl->power(icd->pdev, 0);
940
941 mutex_unlock(&icd->video_lock);
903 942
904 return 0; 943 return 0;
905 944
906evidregd: 945evidstart:
907 if (icl->board_info) 946 mutex_unlock(&icd->video_lock);
947 if (icl->board_info) {
908 soc_camera_free_i2c(icd); 948 soc_camera_free_i2c(icd);
909 else 949 } else {
910 icl->del_device(icl); 950 icl->del_device(icl);
951 module_put(control->driver->owner);
952 }
953enodrv:
911eadddev: 954eadddev:
912 video_device_release(icd->vdev); 955 video_device_release(icd->vdev);
913evdc: 956evdc:
957 ici->ops->remove(icd);
958eadd:
959 if (icl->power)
960 icl->power(icd->pdev, 0);
961epower:
914 return ret; 962 return ret;
915} 963}
916 964
@@ -931,10 +979,16 @@ static int soc_camera_remove(struct device *dev)
931 mutex_unlock(&icd->video_lock); 979 mutex_unlock(&icd->video_lock);
932 } 980 }
933 981
934 if (icl->board_info) 982 if (icl->board_info) {
935 soc_camera_free_i2c(icd); 983 soc_camera_free_i2c(icd);
936 else 984 } else {
937 icl->del_device(icl); 985 struct device_driver *drv = to_soc_camera_control(icd) ?
986 to_soc_camera_control(icd)->driver : NULL;
987 if (drv) {
988 icl->del_device(icl);
989 module_put(drv->owner);
990 }
991 }
938 992
939 return 0; 993 return 0;
940} 994}
@@ -984,6 +1038,7 @@ static void dummy_release(struct device *dev)
984int soc_camera_host_register(struct soc_camera_host *ici) 1038int soc_camera_host_register(struct soc_camera_host *ici)
985{ 1039{
986 struct soc_camera_host *ix; 1040 struct soc_camera_host *ix;
1041 int ret;
987 1042
988 if (!ici || !ici->ops || 1043 if (!ici || !ici->ops ||
989 !ici->ops->try_fmt || 1044 !ici->ops->try_fmt ||
@@ -996,18 +1051,20 @@ int soc_camera_host_register(struct soc_camera_host *ici)
996 !ici->ops->add || 1051 !ici->ops->add ||
997 !ici->ops->remove || 1052 !ici->ops->remove ||
998 !ici->ops->poll || 1053 !ici->ops->poll ||
999 !ici->dev) 1054 !ici->v4l2_dev.dev)
1000 return -EINVAL; 1055 return -EINVAL;
1001 1056
1002 mutex_lock(&list_lock); 1057 mutex_lock(&list_lock);
1003 list_for_each_entry(ix, &hosts, list) { 1058 list_for_each_entry(ix, &hosts, list) {
1004 if (ix->nr == ici->nr) { 1059 if (ix->nr == ici->nr) {
1005 mutex_unlock(&list_lock); 1060 ret = -EBUSY;
1006 return -EBUSY; 1061 goto edevreg;
1007 } 1062 }
1008 } 1063 }
1009 1064
1010 dev_set_drvdata(ici->dev, ici); 1065 ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
1066 if (ret < 0)
1067 goto edevreg;
1011 1068
1012 list_add_tail(&ici->list, &hosts); 1069 list_add_tail(&ici->list, &hosts);
1013 mutex_unlock(&list_lock); 1070 mutex_unlock(&list_lock);
@@ -1015,6 +1072,10 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1015 scan_add_host(ici); 1072 scan_add_host(ici);
1016 1073
1017 return 0; 1074 return 0;
1075
1076edevreg:
1077 mutex_unlock(&list_lock);
1078 return ret;
1018} 1079}
1019EXPORT_SYMBOL(soc_camera_host_register); 1080EXPORT_SYMBOL(soc_camera_host_register);
1020 1081
@@ -1028,7 +1089,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1028 list_del(&ici->list); 1089 list_del(&ici->list);
1029 1090
1030 list_for_each_entry(icd, &devices, list) { 1091 list_for_each_entry(icd, &devices, list) {
1031 if (icd->dev.parent == ici->dev) { 1092 if (icd->iface == ici->nr) {
1032 /* The bus->remove will be called */ 1093 /* The bus->remove will be called */
1033 device_unregister(&icd->dev); 1094 device_unregister(&icd->dev);
1034 /* Not before device_unregister(), .remove 1095 /* Not before device_unregister(), .remove
@@ -1043,7 +1104,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1043 1104
1044 mutex_unlock(&list_lock); 1105 mutex_unlock(&list_lock);
1045 1106
1046 dev_set_drvdata(ici->dev, NULL); 1107 v4l2_device_unregister(&ici->v4l2_dev);
1047} 1108}
1048EXPORT_SYMBOL(soc_camera_host_unregister); 1109EXPORT_SYMBOL(soc_camera_host_unregister);
1049 1110
@@ -1123,7 +1184,6 @@ static int video_dev_create(struct soc_camera_device *icd)
1123 1184
1124 if (!vdev) 1185 if (!vdev)
1125 return -ENOMEM; 1186 return -ENOMEM;
1126 dev_dbg(ici->dev, "Allocated video_device %p\n", vdev);
1127 1187
1128 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); 1188 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
1129 1189
@@ -1141,50 +1201,35 @@ static int video_dev_create(struct soc_camera_device *icd)
1141} 1201}
1142 1202
1143/* 1203/*
1144 * Usually called from the struct soc_camera_ops .probe() method, i.e., from 1204 * Called from soc_camera_probe() above (with .video_lock held???)
1145 * soc_camera_probe() above with .video_lock held
1146 */ 1205 */
1147int soc_camera_video_start(struct soc_camera_device *icd, struct device *dev) 1206static int soc_camera_video_start(struct soc_camera_device *icd)
1148{ 1207{
1149 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1150 const struct v4l2_queryctrl *qctrl; 1208 const struct v4l2_queryctrl *qctrl;
1209 int ret;
1151 1210
1152 if (!icd->dev.parent) 1211 if (!icd->dev.parent)
1153 return -ENODEV; 1212 return -ENODEV;
1154 1213
1155 if (!icd->ops || 1214 if (!icd->ops ||
1156 !icd->ops->init ||
1157 !icd->ops->release ||
1158 !icd->ops->start_capture ||
1159 !icd->ops->stop_capture ||
1160 !icd->ops->set_fmt ||
1161 !icd->ops->try_fmt ||
1162 !icd->ops->query_bus_param || 1215 !icd->ops->query_bus_param ||
1163 !icd->ops->set_bus_param) 1216 !icd->ops->set_bus_param)
1164 return -EINVAL; 1217 return -EINVAL;
1165 1218
1166 /* See comment in soc_camera_probe() */ 1219 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER,
1167 dev_set_drvdata(&icd->dev, dev); 1220 icd->vdev->minor);
1221 if (ret < 0) {
1222 dev_err(&icd->dev, "video_register_device failed: %d\n", ret);
1223 return ret;
1224 }
1168 1225
1169 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN); 1226 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN);
1170 icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0; 1227 icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0;
1171 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 1228 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
1172 icd->exposure = qctrl ? qctrl->default_value : (unsigned short)~0; 1229 icd->exposure = qctrl ? qctrl->default_value : (unsigned short)~0;
1173 1230
1174 return ici->ops->add(icd); 1231 return 0;
1175}
1176EXPORT_SYMBOL(soc_camera_video_start);
1177
1178/* Called from client .remove() methods with .video_lock held */
1179void soc_camera_video_stop(struct soc_camera_device *icd)
1180{
1181 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1182
1183 dev_dbg(&icd->dev, "%s\n", __func__);
1184
1185 ici->ops->remove(icd);
1186} 1232}
1187EXPORT_SYMBOL(soc_camera_video_stop);
1188 1233
1189static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) 1234static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1190{ 1235{
@@ -1200,6 +1245,7 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1200 return -ENOMEM; 1245 return -ENOMEM;
1201 1246
1202 icd->iface = icl->bus_id; 1247 icd->iface = icl->bus_id;
1248 icd->pdev = &pdev->dev;
1203 platform_set_drvdata(pdev, icd); 1249 platform_set_drvdata(pdev, icd);
1204 icd->dev.platform_data = icl; 1250 icd->dev.platform_data = icl;
1205 1251