PATCH: soc-camera: Support multiple camera chips per host
Hi,
soc-camera already supports more than one camera chip per host which can be used exclusively. This patch adds a hook for the board code to switch between different cameras.
Signed-off-by Sascha Hauer <[email protected]>
--- drivers/media/video/soc_camera.c | 20 ++++++++++++++++---- include/media/soc_camera.h | 7 ++++++- 2 files changed, 22 insertions(+), 5 deletions(-)
media/video/soc_camera.c renamed from media/video/soc_camera.c.orig +16 -4
@@ -218,6 +218,9 @@ static int soc_camera_open(struct inode icd->use_count++; +if (icd->link->activate) + icd->link->activate (icd->link,1 ); +/* Now we really have to activate the camera */ if (icd->use_count ==1 ) { ret = ici->ops->add (icd);
@@ -269,6 +272,8 @@ static int soc_camera_close(struct inode icd->use_count--;if (!icd->use_count) ici->ops->remove (icd); +if (icd->link->activate) + icd->link->activate (icd->link,0 ); icf->lock =NULL ;if (ici->ops->spinlock_free) ici->ops->spinlock_free (lock);
@@ -670,7 +675,7 @@ static void scan_add_host(struct soc_cammutex_lock (&list_lock);list_for_each_entry (icd, &devices, list) { -if (icd->iface == ici->nr) { +if (icd->link->bus_id == ici->nr) { icd->dev.parent = &ici->dev;device_register_link (icd); }
@@ -693,7 +698,7 @@ static int scan_add_device(struct soc_ca/* Watch out for class_for_each_device / class_find_device API by * Dave Young <[email protected]> */ list_for_each_entry (ici, &hosts, list) { -if (icd->iface == ici->nr) { +if (icd->link->bus_id == ici->nr) { ret =1 ; icd->dev.parent = &ici->dev;break ;
@@ -718,6 +723,9 @@ static int soc_camera_probe(struct devicif (!icd->ops->probe)return -ENODEV ; +if (icd->link->activate) + icd->link->activate (icd->link,1 ); +/* We only call ->add() here to activate and probe the camera. * We shall ->remove() and deactivate it immediately afterwards. */ ret = ici->ops->add (icd);
@@ -736,6 +744,9 @@ static int soc_camera_probe(struct devic } ici->ops->remove (icd); +if (icd->link->activate) + icd->link->activate (icd->link,0 ); +return ret; }
@@ -866,7 +877,8 @@ int soc_camera_device_register(struct sofor (i =0 ; i <256 && num <0 ; i++) { num = i;list_for_each_entry (ix, &devices, list) { -if (ix->iface == icd->iface && ix->devnum == i) { +if (ix->link->bus_id == icd->link->bus_id && + ix->devnum == i) { num =-1 ;break ; }
@@ -881,7 +893,7 @@ int soc_camera_device_register(struct so icd->devnum = num; icd->dev.bus = &soc_camera_bus_type;snprintf (icd->dev.bus_id,sizeof (icd->dev.bus_id), -"%u-%u" , icd->iface, icd->devnum); +"%u-%u" , icd->link->bus_id, icd->devnum); icd->dev.release = dummy_release;
media/soc_camera.h renamed from media/soc_camera.h.orig +6 -1
@@ -15,6 +15,8 @@#include <linux/videodev2.h> #include <media/videobuf-dma-sg.h> +struct soc_camera_link ; +struct soc_camera_device {struct list_head list;struct device dev;
@@ -32,7 +34,7 @@ struct soc_camera_device {unsigned short y_skip_top;/* Lines to skip at the top */ unsigned short gain;unsigned short exposure; -unsigned char iface;/* Host number */ +struct soc_camera_link *link;/* Link to this camera */ unsigned char devnum;/* Device number per host */ unsigned char buswidth;/* See comment in .c */ struct soc_camera_ops *ops;
@@ -83,6 +85,9 @@ struct soc_camera_link {int bus_id;/* GPIO number to switch between 8 and 10 bit modes */ unsigned int gpio; +/* (de-)activate this camera. Can be left empty if only one camera is +* connected to this bus. */ +void (*activate)(struct soc_camera_link *,int ); };static inline struct soc_camera_device *to_soc_camera_dev (struct device *dev)
Signature · 9 lines
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Hannoversche Str. 2, 31134 Hildesheim, Germany
Phone: +49-5121-206917-0 | Fax: +49-5121-206917-9
--
video4linux-list mailing list
Unsubscribe mailto:[email protected]?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-listExcuse me for sending -p0 patches. Here's an updated version:
soc-camera already supports more than one camera chip per host which can be used exclusively. This patch adds a hook for the board code to switch between different cameras.
Signed-off-by Sascha Hauer <[email protected]>
--- drivers/media/video/mt9m001.c | 4 ++-- drivers/media/video/mt9v022.c | 4 ++-- drivers/media/video/soc_camera.c | 20 ++++++++++++++++---- include/media/soc_camera.h | 7 ++++++- 4 files changed, 26 insertions(+), 9 deletions(-)
drivers/media/video/soc_camera.c +16 -4
@@ -218,6 +218,9 @@ static int soc_camera_open(struct inode icd->use_count++; +if (icd->link->activate) + icd->link->activate (icd->link,1 ); +/* Now we really have to activate the camera */ if (icd->use_count ==1 ) { ret = ici->ops->add (icd);
@@ -269,6 +272,8 @@ static int soc_camera_close(struct inode icd->use_count--;if (!icd->use_count) ici->ops->remove (icd); +if (icd->link->activate) + icd->link->activate (icd->link,0 ); icf->lock =NULL ;if (ici->ops->spinlock_free) ici->ops->spinlock_free (lock);
@@ -670,7 +675,7 @@ static void scan_add_host(struct soc_cammutex_lock (&list_lock);list_for_each_entry (icd, &devices, list) { -if (icd->iface == ici->nr) { +if (icd->link->bus_id == ici->nr) { icd->dev.parent = &ici->dev;device_register_link (icd); }
@@ -693,7 +698,7 @@ static int scan_add_device(struct soc_ca/* Watch out for class_for_each_device / class_find_device API by * Dave Young <[email protected]> */ list_for_each_entry (ici, &hosts, list) { -if (icd->iface == ici->nr) { +if (icd->link->bus_id == ici->nr) { ret =1 ; icd->dev.parent = &ici->dev;break ;
@@ -718,6 +723,9 @@ static int soc_camera_probe(struct devicif (!icd->ops->probe)return -ENODEV ; +if (icd->link->activate) + icd->link->activate (icd->link,1 ); +/* We only call ->add() here to activate and probe the camera. * We shall ->remove() and deactivate it immediately afterwards. */ ret = ici->ops->add (icd);
@@ -736,6 +744,9 @@ static int soc_camera_probe(struct devic } ici->ops->remove (icd); +if (icd->link->activate) + icd->link->activate (icd->link,0 ); +return ret; }
@@ -866,7 +877,8 @@ int soc_camera_device_register(struct sofor (i =0 ; i <256 && num <0 ; i++) { num = i;list_for_each_entry (ix, &devices, list) { -if (ix->iface == icd->iface && ix->devnum == i) { +if (ix->link->bus_id == icd->link->bus_id && + ix->devnum == i) { num =-1 ;break ; }
@@ -881,7 +893,7 @@ int soc_camera_device_register(struct so icd->devnum = num; icd->dev.bus = &soc_camera_bus_type;snprintf (icd->dev.bus_id,sizeof (icd->dev.bus_id), -"%u-%u" , icd->iface, icd->devnum); +"%u-%u" , icd->link->bus_id, icd->devnum); icd->dev.release = dummy_release;
include/media/soc_camera.h +6 -1
@@ -15,6 +15,8 @@#include <linux/videodev2.h> #include <media/videobuf-dma-sg.h> +struct soc_camera_link ; +struct soc_camera_device {struct list_head list;struct device dev;
@@ -32,7 +34,7 @@ struct soc_camera_device {unsigned short y_skip_top;/* Lines to skip at the top */ unsigned short gain;unsigned short exposure; -unsigned char iface;/* Host number */ +struct soc_camera_link *link;/* Link to this camera */ unsigned char devnum;/* Device number per host */ unsigned char buswidth;/* See comment in .c */ struct soc_camera_ops *ops;
@@ -83,6 +85,9 @@ struct soc_camera_link {int bus_id;/* GPIO number to switch between 8 and 10 bit modes */ unsigned int gpio; +/* (de-)activate this camera. Can be left empty if only one camera is +* connected to this bus. */ +void (*activate)(struct soc_camera_link *,int ); };static inline struct soc_camera_device *to_soc_camera_dev (struct device *dev)
drivers/media/video/mt9m001.c +2 -2
@@ -557,7 +557,7 @@ static int mt9m001_video_probe(struct so/* We must have a parent by now. And it cannot be a wrong one. * So this entire test is completely redundant. */ if (!icd->dev.parent || -to_soc_camera_host (icd->dev.parent)->nr != icd->iface) +to_soc_camera_host (icd->dev.parent)->nr != icd->link->bus_id)return -ENODEV ;/* Enable the chip */
@@ -657,7 +657,7 @@ static int mt9m001_probe(struct i2c_clie icd->height_min =32 ; icd->height_max =1024 ; icd->y_skip_top =1 ; - icd->iface = icl->bus_id; + icd->link = icl;/* Default datawidth - this is the only width this camera (normally) * supports. It is only with extra logic that it can support * other widths. Therefore it seems to be a sensible default. */
drivers/media/video/mt9v022.c +2 -2
@@ -672,7 +672,7 @@ static int mt9v022_video_probe(struct soint ret;if (!icd->dev.parent || -to_soc_camera_host (icd->dev.parent)->nr != icd->iface) +to_soc_camera_host (icd->dev.parent)->nr != icd->link->bus_id)return -ENODEV ;/* Read out the chip version register */
@@ -782,7 +782,7 @@ static int mt9v022_probe(struct i2c_clie icd->height_min =32 ; icd->height_max =480 ; icd->y_skip_top =1 ; - icd->iface = icl->bus_id; + icd->link = icl;/* Default datawidth - this is the only width this camera (normally) * supports. It is only with extra logic that it can support * other widths. Therefore it seems to be a sensible default. */
Signature · 10 lines
--
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Hannoversche Str. 2, 31134 Hildesheim, Germany
Phone: +49-5121-206917-0 | Fax: +49-5121-206917-9
--
video4linux-list mailing list
Unsubscribe mailto:[email protected]?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list