aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/soc_camera.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:28:22 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:18:27 -0400
commit40e2e0927003424c25807b575dd40da2b8685857 (patch)
tree917ca8fd5f7598194d264ec92a08b312d4932b90 /drivers/media/video/soc_camera.c
parentbc1937b41d8253e2b554da385023a92189d38917 (diff)
V4L/DVB (12506): soc-camera: convert to platform device
Convert soc-camera core and all drivers to platform device API. We already converted platforms to register a platform device for each soc-camera client, now we remove the compatibility code and switch completely to the new scheme. This is a preparatory step for the v4l2-subdev conversion. 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.c431
1 files changed, 212 insertions, 219 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 0340754e5406..20ef5c773fae 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -21,15 +21,15 @@
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/module.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
28 28
29#include <media/soc_camera.h> 29#include <media/soc_camera.h>
30#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31#include <media/v4l2-dev.h>
32#include <media/v4l2-ioctl.h> 31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-dev.h>
33#include <media/videobuf-core.h> 33#include <media/videobuf-core.h>
34 34
35/* Default to VGA resolution */ 35/* Default to VGA resolution */
@@ -38,7 +38,7 @@
38 38
39static LIST_HEAD(hosts); 39static LIST_HEAD(hosts);
40static LIST_HEAD(devices); 40static LIST_HEAD(devices);
41static DEFINE_MUTEX(list_lock); 41static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
42 42
43const struct soc_camera_data_format *soc_camera_format_by_fourcc( 43const struct soc_camera_data_format *soc_camera_format_by_fourcc(
44 struct soc_camera_device *icd, unsigned int fourcc) 44 struct soc_camera_device *icd, unsigned int fourcc)
@@ -209,6 +209,7 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
209 return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK); 209 return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK);
210} 210}
211 211
212/* Always entered with .video_lock held */
212static int soc_camera_init_user_formats(struct soc_camera_device *icd) 213static int soc_camera_init_user_formats(struct soc_camera_device *icd)
213{ 214{
214 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 215 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -257,9 +258,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
257 return 0; 258 return 0;
258} 259}
259 260
261/* Always entered with .video_lock held */
260static void soc_camera_free_user_formats(struct soc_camera_device *icd) 262static void soc_camera_free_user_formats(struct soc_camera_device *icd)
261{ 263{
264 icd->current_fmt = NULL;
262 vfree(icd->user_formats); 265 vfree(icd->user_formats);
266 icd->user_formats = NULL;
263} 267}
264 268
265/* Called with .vb_lock held */ 269/* Called with .vb_lock held */
@@ -310,10 +314,6 @@ static int soc_camera_open(struct file *file)
310 struct soc_camera_file *icf; 314 struct soc_camera_file *icf;
311 int ret; 315 int ret;
312 316
313 icf = vmalloc(sizeof(*icf));
314 if (!icf)
315 return -ENOMEM;
316
317 /* 317 /*
318 * It is safe to dereference these pointers now as long as a user has 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. 319 * the video device open - we are protected by the held cdev reference.
@@ -321,8 +321,17 @@ static int soc_camera_open(struct file *file)
321 321
322 vdev = video_devdata(file); 322 vdev = video_devdata(file);
323 icd = container_of(vdev->parent, struct soc_camera_device, dev); 323 icd = container_of(vdev->parent, struct soc_camera_device, dev);
324
325 if (!icd->ops)
326 /* No device driver attached */
327 return -ENODEV;
328
324 ici = to_soc_camera_host(icd->dev.parent); 329 ici = to_soc_camera_host(icd->dev.parent);
325 330
331 icf = vmalloc(sizeof(*icf));
332 if (!icf)
333 return -ENOMEM;
334
326 if (!try_module_get(icd->ops->owner)) { 335 if (!try_module_get(icd->ops->owner)) {
327 dev_err(&icd->dev, "Couldn't lock sensor driver.\n"); 336 dev_err(&icd->dev, "Couldn't lock sensor driver.\n");
328 ret = -EINVAL; 337 ret = -EINVAL;
@@ -335,7 +344,7 @@ static int soc_camera_open(struct file *file)
335 goto emgi; 344 goto emgi;
336 } 345 }
337 346
338 /* Protect against icd->remove() until we module_get() both drivers. */ 347 /* Protect against icd->ops->remove() until we module_get() both drivers. */
339 mutex_lock(&icd->video_lock); 348 mutex_lock(&icd->video_lock);
340 349
341 icf->icd = icd; 350 icf->icd = icd;
@@ -350,11 +359,18 @@ static int soc_camera_open(struct file *file)
350 .width = icd->width, 359 .width = icd->width,
351 .height = icd->height, 360 .height = icd->height,
352 .field = icd->field, 361 .field = icd->field,
353 .pixelformat = icd->current_fmt->fourcc,
354 .colorspace = icd->current_fmt->colorspace,
355 }, 362 },
356 }; 363 };
357 364
365 ret = soc_camera_init_user_formats(icd);
366 if (ret < 0)
367 goto eiufmt;
368
369 dev_dbg(&icd->dev, "Using fmt %x\n", icd->current_fmt->fourcc);
370
371 f.fmt.pix.pixelformat = icd->current_fmt->fourcc;
372 f.fmt.pix.colorspace = icd->current_fmt->colorspace;
373
358 ret = ici->ops->add(icd); 374 ret = ici->ops->add(icd);
359 if (ret < 0) { 375 if (ret < 0) {
360 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); 376 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
@@ -383,6 +399,8 @@ static int soc_camera_open(struct file *file)
383esfmt: 399esfmt:
384 ici->ops->remove(icd); 400 ici->ops->remove(icd);
385eiciadd: 401eiciadd:
402 soc_camera_free_user_formats(icd);
403eiufmt:
386 icd->use_count--; 404 icd->use_count--;
387 mutex_unlock(&icd->video_lock); 405 mutex_unlock(&icd->video_lock);
388 module_put(ici->ops->owner); 406 module_put(ici->ops->owner);
@@ -402,8 +420,10 @@ static int soc_camera_close(struct file *file)
402 420
403 mutex_lock(&icd->video_lock); 421 mutex_lock(&icd->video_lock);
404 icd->use_count--; 422 icd->use_count--;
405 if (!icd->use_count) 423 if (!icd->use_count) {
406 ici->ops->remove(icd); 424 ici->ops->remove(icd);
425 soc_camera_free_user_formats(icd);
426 }
407 427
408 mutex_unlock(&icd->video_lock); 428 mutex_unlock(&icd->video_lock);
409 429
@@ -764,29 +784,6 @@ static int soc_camera_s_register(struct file *file, void *fh,
764} 784}
765#endif 785#endif
766 786
767static int device_register_link(struct soc_camera_device *icd)
768{
769 int ret = dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
770
771 if (!ret)
772 ret = device_register(&icd->dev);
773
774 if (ret < 0) {
775 /* Prevent calling device_unregister() */
776 icd->dev.parent = NULL;
777 dev_err(&icd->dev, "Cannot register device: %d\n", ret);
778 /* Even if probe() was unsuccessful for all registered drivers,
779 * device_register() returns 0, and we add the link, just to
780 * document this camera's control device */
781 } else if (icd->control)
782 /* Have to sysfs_remove_link() before device_unregister()? */
783 if (sysfs_create_link(&icd->dev.kobj, &icd->control->kobj,
784 "control"))
785 dev_warn(&icd->dev,
786 "Failed creating the control symlink\n");
787 return ret;
788}
789
790/* So far this function cannot fail */ 787/* So far this function cannot fail */
791static void scan_add_host(struct soc_camera_host *ici) 788static void scan_add_host(struct soc_camera_host *ici)
792{ 789{
@@ -796,106 +793,124 @@ static void scan_add_host(struct soc_camera_host *ici)
796 793
797 list_for_each_entry(icd, &devices, list) { 794 list_for_each_entry(icd, &devices, list) {
798 if (icd->iface == ici->nr) { 795 if (icd->iface == ici->nr) {
796 int ret;
799 icd->dev.parent = ici->dev; 797 icd->dev.parent = ici->dev;
800 device_register_link(icd); 798 dev_set_name(&icd->dev, "%u-%u", icd->iface,
799 icd->devnum);
800 ret = device_register(&icd->dev);
801 if (ret < 0) {
802 icd->dev.parent = NULL;
803 dev_err(&icd->dev,
804 "Cannot register device: %d\n", ret);
805 }
801 } 806 }
802 } 807 }
803 808
804 mutex_unlock(&list_lock); 809 mutex_unlock(&list_lock);
805} 810}
806 811
807/* return: 0 if no match found or a match found and 812#ifdef CONFIG_I2C_BOARDINFO
808 * device_register() successful, error code otherwise */ 813static int soc_camera_init_i2c(struct soc_camera_device *icd,
809static int scan_add_device(struct soc_camera_device *icd) 814 struct soc_camera_link *icl)
810{ 815{
811 struct soc_camera_host *ici; 816 struct i2c_client *client;
812 int ret = 0; 817 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
818 int ret;
813 819
814 mutex_lock(&list_lock); 820 if (!adap) {
821 ret = -ENODEV;
822 dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n",
823 icl->i2c_adapter_id);
824 goto ei2cga;
825 }
815 826
816 list_add_tail(&icd->list, &devices); 827 icl->board_info->platform_data = icd;
817 828
818 /* Watch out for class_for_each_device / class_find_device API by 829 client = i2c_new_device(adap, icl->board_info);
819 * Dave Young <hidave.darkstar@gmail.com> */ 830 if (!client) {
820 list_for_each_entry(ici, &hosts, list) { 831 ret = -ENOMEM;
821 if (icd->iface == ici->nr) { 832 goto ei2cnd;
822 ret = 1;
823 icd->dev.parent = ici->dev;
824 break;
825 }
826 } 833 }
827 834
828 mutex_unlock(&list_lock); 835 /*
829 836 * We set icd drvdata at two locations - here and in
830 if (ret) 837 * soc_camera_video_start(). Depending on the module loading /
831 ret = device_register_link(icd); 838 * initialisation order one of these locations will be entered first
839 */
840 /* Use to_i2c_client(dev) to recover the i2c client */
841 dev_set_drvdata(&icd->dev, &client->dev);
832 842
843 return 0;
844ei2cnd:
845 i2c_put_adapter(adap);
846ei2cga:
833 return ret; 847 return ret;
834} 848}
835 849
850static void soc_camera_free_i2c(struct soc_camera_device *icd)
851{
852 struct i2c_client *client =
853 to_i2c_client(to_soc_camera_control(icd));
854 dev_set_drvdata(&icd->dev, NULL);
855 i2c_unregister_device(client);
856 i2c_put_adapter(client->adapter);
857}
858#else
859#define soc_camera_init_i2c(icd, icl) (-ENODEV)
860#define soc_camera_free_i2c(icd) do {} while (0)
861#endif
862
863static int video_dev_create(struct soc_camera_device *icd);
864/* Called during host-driver probe */
836static int soc_camera_probe(struct device *dev) 865static int soc_camera_probe(struct device *dev)
837{ 866{
838 struct soc_camera_device *icd = to_soc_camera_dev(dev); 867 struct soc_camera_device *icd = to_soc_camera_dev(dev);
839 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 868 struct soc_camera_link *icl = to_soc_camera_link(icd);
840 int ret; 869 int ret;
841 870
842 /* 871 dev_info(dev, "Probing %s\n", dev_name(dev));
843 * Possible race scenario:
844 * modprobe <camera-host-driver> triggers __func__
845 * at this moment respective <camera-sensor-driver> gets rmmod'ed
846 * to protect take module references.
847 */
848 872
849 if (!try_module_get(icd->ops->owner)) { 873 ret = video_dev_create(icd);
850 dev_err(&icd->dev, "Couldn't lock sensor driver.\n"); 874 if (ret < 0)
851 ret = -EINVAL; 875 goto evdc;
852 goto emgd;
853 }
854 876
855 if (!try_module_get(ici->ops->owner)) { 877 /* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
856 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); 878 if (icl->board_info) {
879 ret = soc_camera_init_i2c(icd, icl);
880 if (ret < 0)
881 goto eadddev;
882 } else if (!icl->add_device || !icl->del_device) {
857 ret = -EINVAL; 883 ret = -EINVAL;
858 goto emgi; 884 goto eadddev;
885 } else {
886 ret = icl->add_device(icl, &icd->dev);
887 if (ret < 0)
888 goto eadddev;
859 } 889 }
860 890
861 mutex_lock(&icd->video_lock); 891 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, icd->vdev->minor);
862 892 if (ret < 0) {
863 /* We only call ->add() here to activate and probe the camera. 893 dev_err(&icd->dev, "video_register_device failed: %d\n", ret);
864 * We shall ->remove() and deactivate it immediately afterwards. */ 894 goto evidregd;
865 ret = ici->ops->add(icd); 895 }
866 if (ret < 0)
867 goto eiadd;
868
869 ret = icd->ops->probe(icd);
870 if (ret >= 0) {
871 const struct v4l2_queryctrl *qctrl;
872 896
873 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN); 897 /* Do we have to sysfs_remove_link() before device_unregister()? */
874 icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0; 898 if (to_soc_camera_control(icd) &&
875 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 899 sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj,
876 icd->exposure = qctrl ? qctrl->default_value : 900 "control"))
877 (unsigned short)~0; 901 dev_warn(&icd->dev, "Failed creating the control symlink\n");
878 902
879 ret = soc_camera_init_user_formats(icd);
880 if (ret < 0) {
881 if (icd->ops->remove)
882 icd->ops->remove(icd);
883 goto eiufmt;
884 }
885 903
886 icd->height = DEFAULT_HEIGHT; 904 return 0;
887 icd->width = DEFAULT_WIDTH;
888 icd->field = V4L2_FIELD_ANY;
889 }
890 905
891eiufmt: 906evidregd:
892 ici->ops->remove(icd); 907 if (icl->board_info)
893eiadd: 908 soc_camera_free_i2c(icd);
894 mutex_unlock(&icd->video_lock); 909 else
895 module_put(ici->ops->owner); 910 icl->del_device(icl);
896emgi: 911eadddev:
897 module_put(icd->ops->owner); 912 video_device_release(icd->vdev);
898emgd: 913evdc:
899 return ret; 914 return ret;
900} 915}
901 916
@@ -904,13 +919,22 @@ emgd:
904static int soc_camera_remove(struct device *dev) 919static int soc_camera_remove(struct device *dev)
905{ 920{
906 struct soc_camera_device *icd = to_soc_camera_dev(dev); 921 struct soc_camera_device *icd = to_soc_camera_dev(dev);
922 struct soc_camera_link *icl = to_soc_camera_link(icd);
923 struct video_device *vdev = icd->vdev;
907 924
908 mutex_lock(&icd->video_lock); 925 BUG_ON(!dev->parent);
909 if (icd->ops->remove)
910 icd->ops->remove(icd);
911 mutex_unlock(&icd->video_lock);
912 926
913 soc_camera_free_user_formats(icd); 927 if (vdev) {
928 mutex_lock(&icd->video_lock);
929 video_unregister_device(vdev);
930 icd->vdev = NULL;
931 mutex_unlock(&icd->video_lock);
932 }
933
934 if (icl->board_info)
935 soc_camera_free_i2c(icd);
936 else
937 icl->del_device(icl);
914 938
915 return 0; 939 return 0;
916} 940}
@@ -1005,10 +1029,14 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1005 1029
1006 list_for_each_entry(icd, &devices, list) { 1030 list_for_each_entry(icd, &devices, list) {
1007 if (icd->dev.parent == ici->dev) { 1031 if (icd->dev.parent == ici->dev) {
1032 /* The bus->remove will be called */
1008 device_unregister(&icd->dev); 1033 device_unregister(&icd->dev);
1009 /* Not before device_unregister(), .remove 1034 /* Not before device_unregister(), .remove
1010 * needs parent to call ici->ops->remove() */ 1035 * needs parent to call ici->ops->remove() */
1011 icd->dev.parent = NULL; 1036 icd->dev.parent = NULL;
1037
1038 /* If the host module is loaded again, device_register()
1039 * would complain "already initialised" */
1012 memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj)); 1040 memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj));
1013 } 1041 }
1014 } 1042 }
@@ -1020,26 +1048,14 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1020EXPORT_SYMBOL(soc_camera_host_unregister); 1048EXPORT_SYMBOL(soc_camera_host_unregister);
1021 1049
1022/* Image capture device */ 1050/* Image capture device */
1023int soc_camera_device_register(struct soc_camera_device *icd) 1051static int soc_camera_device_register(struct soc_camera_device *icd)
1024{ 1052{
1025 struct soc_camera_device *ix; 1053 struct soc_camera_device *ix;
1026 int num = -1, i; 1054 int num = -1, i;
1027 1055
1028 if (!icd || !icd->ops ||
1029 !icd->ops->probe ||
1030 !icd->ops->init ||
1031 !icd->ops->release ||
1032 !icd->ops->start_capture ||
1033 !icd->ops->stop_capture ||
1034 !icd->ops->set_crop ||
1035 !icd->ops->set_fmt ||
1036 !icd->ops->try_fmt ||
1037 !icd->ops->query_bus_param ||
1038 !icd->ops->set_bus_param)
1039 return -EINVAL;
1040
1041 for (i = 0; i < 256 && num < 0; i++) { 1056 for (i = 0; i < 256 && num < 0; i++) {
1042 num = i; 1057 num = i;
1058 /* Check if this index is available on this interface */
1043 list_for_each_entry(ix, &devices, list) { 1059 list_for_each_entry(ix, &devices, list) {
1044 if (ix->iface == icd->iface && ix->devnum == i) { 1060 if (ix->iface == icd->iface && ix->devnum == i) {
1045 num = -1; 1061 num = -1;
@@ -1061,21 +1077,15 @@ int soc_camera_device_register(struct soc_camera_device *icd)
1061 icd->host_priv = NULL; 1077 icd->host_priv = NULL;
1062 mutex_init(&icd->video_lock); 1078 mutex_init(&icd->video_lock);
1063 1079
1064 return scan_add_device(icd); 1080 list_add_tail(&icd->list, &devices);
1081
1082 return 0;
1065} 1083}
1066EXPORT_SYMBOL(soc_camera_device_register);
1067 1084
1068void soc_camera_device_unregister(struct soc_camera_device *icd) 1085static void soc_camera_device_unregister(struct soc_camera_device *icd)
1069{ 1086{
1070 mutex_lock(&list_lock);
1071 list_del(&icd->list); 1087 list_del(&icd->list);
1072
1073 /* The bus->remove will be eventually called */
1074 if (icd->dev.parent)
1075 device_unregister(&icd->dev);
1076 mutex_unlock(&list_lock);
1077} 1088}
1078EXPORT_SYMBOL(soc_camera_device_unregister);
1079 1089
1080static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { 1090static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1081 .vidioc_querycap = soc_camera_querycap, 1091 .vidioc_querycap = soc_camera_querycap,
@@ -1106,22 +1116,13 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1106#endif 1116#endif
1107}; 1117};
1108 1118
1109/* 1119static int video_dev_create(struct soc_camera_device *icd)
1110 * Usually called from the struct soc_camera_ops .probe() method, i.e., from
1111 * soc_camera_probe() above with .video_lock held
1112 */
1113int soc_camera_video_start(struct soc_camera_device *icd)
1114{ 1120{
1115 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1121 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1116 int err = -ENOMEM; 1122 struct video_device *vdev = video_device_alloc();
1117 struct video_device *vdev;
1118 1123
1119 if (!icd->dev.parent)
1120 return -ENODEV;
1121
1122 vdev = video_device_alloc();
1123 if (!vdev) 1124 if (!vdev)
1124 goto evidallocd; 1125 return -ENOMEM;
1125 dev_dbg(ici->dev, "Allocated video_device %p\n", vdev); 1126 dev_dbg(ici->dev, "Allocated video_device %p\n", vdev);
1126 1127
1127 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); 1128 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
@@ -1132,118 +1133,110 @@ int soc_camera_video_start(struct soc_camera_device *icd)
1132 vdev->ioctl_ops = &soc_camera_ioctl_ops; 1133 vdev->ioctl_ops = &soc_camera_ioctl_ops;
1133 vdev->release = video_device_release; 1134 vdev->release = video_device_release;
1134 vdev->minor = -1; 1135 vdev->minor = -1;
1135 vdev->tvnorms = V4L2_STD_UNKNOWN, 1136 vdev->tvnorms = V4L2_STD_UNKNOWN;
1136 1137
1137 err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor);
1138 if (err < 0) {
1139 dev_err(vdev->parent, "video_register_device failed\n");
1140 goto evidregd;
1141 }
1142 icd->vdev = vdev; 1138 icd->vdev = vdev;
1143 1139
1144 return 0; 1140 return 0;
1141}
1145 1142
1146evidregd: 1143/*
1147 video_device_release(vdev); 1144 * Usually called from the struct soc_camera_ops .probe() method, i.e., from
1148evidallocd: 1145 * soc_camera_probe() above with .video_lock held
1149 return err; 1146 */
1147int soc_camera_video_start(struct soc_camera_device *icd, struct device *dev)
1148{
1149 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1150 const struct v4l2_queryctrl *qctrl;
1151
1152 if (!icd->dev.parent)
1153 return -ENODEV;
1154
1155 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 ||
1163 !icd->ops->set_bus_param)
1164 return -EINVAL;
1165
1166 /* See comment in soc_camera_probe() */
1167 dev_set_drvdata(&icd->dev, dev);
1168
1169 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN);
1170 icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0;
1171 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
1172 icd->exposure = qctrl ? qctrl->default_value : (unsigned short)~0;
1173
1174 return ici->ops->add(icd);
1150} 1175}
1151EXPORT_SYMBOL(soc_camera_video_start); 1176EXPORT_SYMBOL(soc_camera_video_start);
1152 1177
1153/* Called from client .remove() methods with .video_lock held */ 1178/* Called from client .remove() methods with .video_lock held */
1154void soc_camera_video_stop(struct soc_camera_device *icd) 1179void soc_camera_video_stop(struct soc_camera_device *icd)
1155{ 1180{
1156 struct video_device *vdev = icd->vdev; 1181 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1157 1182
1158 dev_dbg(&icd->dev, "%s\n", __func__); 1183 dev_dbg(&icd->dev, "%s\n", __func__);
1159 1184
1160 if (!icd->dev.parent || !vdev) 1185 ici->ops->remove(icd);
1161 return;
1162
1163 video_unregister_device(vdev);
1164 icd->vdev = NULL;
1165} 1186}
1166EXPORT_SYMBOL(soc_camera_video_stop); 1187EXPORT_SYMBOL(soc_camera_video_stop);
1167 1188
1168#ifdef CONFIG_I2C_BOARDINFO 1189static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1169static int soc_camera_init_i2c(struct platform_device *pdev,
1170 struct soc_camera_link *icl)
1171{ 1190{
1172 struct i2c_client *client; 1191 struct soc_camera_link *icl = pdev->dev.platform_data;
1173 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id); 1192 struct soc_camera_device *icd;
1174 int ret; 1193 int ret;
1175 1194
1176 if (!adap) { 1195 if (!icl)
1177 ret = -ENODEV; 1196 return -EINVAL;
1178 dev_err(&pdev->dev, "Cannot get adapter #%d. No driver?\n",
1179 icl->i2c_adapter_id);
1180 goto ei2cga;
1181 }
1182 1197
1183 icl->board_info->platform_data = icl; 1198 icd = kzalloc(sizeof(*icd), GFP_KERNEL);
1184 client = i2c_new_device(adap, icl->board_info); 1199 if (!icd)
1185 if (!client) { 1200 return -ENOMEM;
1186 ret = -ENOMEM;
1187 goto ei2cnd;
1188 }
1189 1201
1190 platform_set_drvdata(pdev, client); 1202 icd->iface = icl->bus_id;
1203 platform_set_drvdata(pdev, icd);
1204 icd->dev.platform_data = icl;
1191 1205
1192 return 0; 1206 ret = soc_camera_device_register(icd);
1193ei2cnd: 1207 if (ret < 0)
1194 i2c_put_adapter(adap); 1208 goto escdevreg;
1195ei2cga:
1196 return ret;
1197}
1198 1209
1199static void soc_camera_free_i2c(struct platform_device *pdev) 1210 return 0;
1200{
1201 struct i2c_client *client = platform_get_drvdata(pdev);
1202 1211
1203 if (!client) 1212escdevreg:
1204 return; 1213 kfree(icd);
1205 1214
1206 i2c_unregister_device(client); 1215 return ret;
1207 i2c_put_adapter(client->adapter);
1208} 1216}
1209#else
1210#define soc_camera_init_i2c(d, icl) (-ENODEV)
1211#define soc_camera_free_i2c(d) do {} while (0)
1212#endif
1213 1217
1214static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) 1218/* Only called on rmmod for each platform device, since they are not
1219 * hot-pluggable. Now we know, that all our users - hosts and devices have
1220 * been unloaded already */
1221static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
1215{ 1222{
1216 struct soc_camera_link *icl = pdev->dev.platform_data; 1223 struct soc_camera_device *icd = platform_get_drvdata(pdev);
1217 1224
1218 if (!icl) 1225 if (!icd)
1219 return -EINVAL; 1226 return -EINVAL;
1220 1227
1221 if (icl->board_info) 1228 soc_camera_device_unregister(icd);
1222 return soc_camera_init_i2c(pdev, icl);
1223 else if (!icl->add_device || !icl->del_device)
1224 return -EINVAL;
1225 1229
1226 /* &pdev->dev will become &icd->dev */ 1230 kfree(icd);
1227 return icl->add_device(icl, &pdev->dev);
1228}
1229 1231
1230static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
1231{
1232 struct soc_camera_link *icl = pdev->dev.platform_data;
1233
1234 if (icl->board_info)
1235 soc_camera_free_i2c(pdev);
1236 else
1237 icl->del_device(icl);
1238 return 0; 1232 return 0;
1239} 1233}
1240 1234
1241static struct platform_driver __refdata soc_camera_pdrv = { 1235static struct platform_driver __refdata soc_camera_pdrv = {
1242 .probe = soc_camera_pdrv_probe, 1236 .remove = __devexit_p(soc_camera_pdrv_remove),
1243 .remove = __devexit_p(soc_camera_pdrv_remove), 1237 .driver = {
1244 .driver = { 1238 .name = "soc-camera-pdrv",
1245 .name = "soc-camera-pdrv", 1239 .owner = THIS_MODULE,
1246 .owner = THIS_MODULE,
1247 }, 1240 },
1248}; 1241};
1249 1242
@@ -1256,7 +1249,7 @@ static int __init soc_camera_init(void)
1256 if (ret) 1249 if (ret)
1257 goto edrvr; 1250 goto edrvr;
1258 1251
1259 ret = platform_driver_register(&soc_camera_pdrv); 1252 ret = platform_driver_probe(&soc_camera_pdrv, soc_camera_pdrv_probe);
1260 if (ret) 1253 if (ret)
1261 goto epdr; 1254 goto epdr;
1262 1255