[GIT PULL] V4L2: clock and async probing APIs, soc-camera example implementation
Hi Mauro With acks from Hans and Laurent I'd like to ask you to pull my V4L2 clock and asynchronous probing APIs together with respective soc-camera changes. I included an ack from Laurent, even though he requested me to include the documentation update into this pull request, which I haven't done yet. But we agreed privately, that it's also ok, if I submit a v2 of the patch first to the list next Monday and then send an additional pull request for it some time next week. The last patch from the patch series, as I posted it to the list last time is also omitted, because (1) it's for arch/arm, (2) the board, which I used as an example to develop and test these patches will be removed from the kernel, so, I'll need to pick up a different platform for testing, also a different camera host driver, perhaps. The following changes since commit 4ef72e347112a834fbd6944565b1f63d4af19c8a: [media] V4L2: soc-camera: remove unneeded include path (2013-06-21 13:11:59 -0300) are available in the git repository at: git://linuxtv.org/gliakhovetski/v4l-dvb.git for-3.11-2 Guennadi Liakhovetski (20): soc-camera: move common code to soc_camera.c soc-camera: add host clock callbacks to start and stop the master clock pxa-camera: move interface activation and deactivation to clock callbacks omap1-camera: move interface activation and deactivation to clock callbacks atmel-isi: move interface activation and deactivation to clock callbacks mx3-camera: move interface activation and deactivation to clock callbacks mx2-camera: move interface activation and deactivation to clock callbacks mx1-camera: move interface activation and deactivation to clock callbacks sh-mobile-ceu-camera: move interface activation and deactivation to clock callbacks soc-camera: make .clock_{start,stop} compulsory, .add / .remove optional soc-camera: don't attach the client to the host during probing sh-mobile-ceu-camera: add primitive OF support sh-mobile-ceu-driver: support max width and height in DT V4L2: add temporary clock helpers V4L2: add a device pointer to struct v4l2_subdev V4L2: support asynchronous subdevice registration soc-camera: switch I2C subdevice drivers to use v4l2-clk soc-camera: add V4L2-async support sh_mobile_ceu_camera: add asynchronous subdevice probing support imx074: support asynchronous probing .../devicetree/bindings/media/sh_mobile_ceu.txt| 18 + drivers/media/i2c/soc_camera/imx074.c | 32 +- drivers/media/i2c/soc_camera/mt9m001.c | 17 +- drivers/media/i2c/soc_camera/mt9m111.c | 20 +- drivers/media/i2c/soc_camera/mt9t031.c | 19 +- drivers/media/i2c/soc_camera/mt9t112.c | 25 +- drivers/media/i2c/soc_camera/mt9v022.c | 17 +- drivers/media/i2c/soc_camera/ov2640.c | 19 +- drivers/media/i2c/soc_camera/ov5642.c | 20 +- drivers/media/i2c/soc_camera/ov6650.c | 17 +- drivers/media/i2c/soc_camera/ov772x.c | 15 +- drivers/media/i2c/soc_camera/ov9640.c | 17 +- drivers/media/i2c/soc_camera/ov9640.h |1 + drivers/media/i2c/soc_camera/ov9740.c | 18 +- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 17 +- drivers/media/i2c/soc_camera/tw9910.c | 24 +- drivers/media/platform/soc_camera/atmel-isi.c | 38 +- drivers/media/platform/soc_camera/mx1_camera.c | 48 +- drivers/media/platform/soc_camera/mx2_camera.c | 41 +- drivers/media/platform/soc_camera/mx3_camera.c | 44 +- drivers/media/platform/soc_camera/omap1_camera.c | 41 +- drivers/media/platform/soc_camera/pxa_camera.c | 46 +- .../platform/soc_camera/sh_mobile_ceu_camera.c | 243 +-- drivers/media/platform/soc_camera/sh_mobile_csi2.c | 153 +++-- drivers/media/platform/soc_camera/soc_camera.c | 707 +--- .../platform/soc_camera/soc_camera_platform.c |2 +- drivers/media/v4l2-core/Makefile |3 +- drivers/media/v4l2-core/v4l2-async.c | 280 drivers/media/v4l2-core/v4l2-clk.c | 242 +++ drivers/media/v4l2-core/v4l2-common.c |2 + include/media/sh_mobile_ceu.h |2 + include/media/sh_mobile_csi2.h |2 +- include/media/soc_camera.h | 39 +- include/media/v4l2-async.h | 105 +++ include/media/v4l2-clk.h | 54 ++ include/media/v4l2-subdev.h| 10 + 36 files changed, 1973 insertions(+), 425 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/sh_mobile_ceu.txt create mode 100644 drivers/media/v4l2-core/v4l2-async.c create mode 100644 drivers/media/v4l2-core/v4l2-clk.c create mode 100644 include/media
Re: [REVIEWv2 PATCH 02/12] soc_camera: replace vdev-parent by vdev-v4l2_dev.
Hi Hans Thanks for the patch. On Wed, 12 Jun 2013, Hans Verkuil wrote: From: Hans Verkuil hans.verk...@cisco.com The parent field will eventually disappear to be replaced by v4l2_dev. soc_camera does provide a v4l2_device struct but did not point to it in struct video_device. This is now fixed. Now the video nodes can be found under the correct platform bus, and the advanced debug ioctls work correctly as well (the core implementation of those ioctls requires that v4l2_dev is set correctly). Signed-off-by: Hans Verkuil hans.verk...@cisco.com I'm not quite sure about this patch, because where before only one dev_drvdata pointer was used to store a pointed to the icd context, now two pointers are used and your vdev_set_drvdata() is now called much later than platform_set_drvdata() in soc_camera_pdrv_probe(). So, I had to verify no calls to vdev_get_drvdata() are made between those two moments. I think it should be ok, specifically, an uncertain place is soc_camera_vdev_to_subdev(), used by the mt9t031 driver from its runtime PM. But I don't have access to that sensor, so, it hasn't been tested in ages. In fact, I think, I should remove its runtime PM and just call the resume from s_power(1). If anything breaks and onyone notices it - they will complain. Anyway, for now here's my Acked-by: Guennadi Liakhovetski g.liakhovet...@gmx.de Thanks Guennadi --- drivers/media/platform/soc_camera/soc_camera.c |5 +++-- include/media/soc_camera.h |4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 0252fbb..9a43560 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -524,7 +524,7 @@ static int soc_camera_open(struct file *file) return -ENODEV; } - icd = dev_get_drvdata(vdev-parent); + icd = video_get_drvdata(vdev); ici = to_soc_camera_host(icd-parent); ret = try_module_get(ici-ops-owner) ? 0 : -ENODEV; @@ -1477,7 +1477,7 @@ static int video_dev_create(struct soc_camera_device *icd) strlcpy(vdev-name, ici-drv_name, sizeof(vdev-name)); - vdev-parent= icd-pdev; + vdev-v4l2_dev = ici-v4l2_dev; vdev-fops = soc_camera_fops; vdev-ioctl_ops = soc_camera_ioctl_ops; vdev-release = video_device_release; @@ -1500,6 +1500,7 @@ static int soc_camera_video_start(struct soc_camera_device *icd) if (!icd-parent) return -ENODEV; + video_set_drvdata(icd-vdev, icd); ret = video_register_device(icd-vdev, VFL_TYPE_GRABBER, -1); if (ret 0) { dev_err(icd-pdev, video_register_device failed: %d\n, ret); diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index ff77d08..31a4bfe 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -346,9 +346,9 @@ static inline struct soc_camera_subdev_desc *soc_camera_i2c_to_desc(const struct return client-dev.platform_data; } -static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(const struct video_device *vdev) +static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(struct video_device *vdev) { - struct soc_camera_device *icd = dev_get_drvdata(vdev-parent); + struct soc_camera_device *icd = video_get_drvdata(vdev); return soc_camera_to_subdev(icd); } -- 1.7.10.4 --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] V4L2: add documentation for V4L2 clock helpers and asynchronous probing
Add documentation for the V4L2 clock and V4L2 asynchronous probing APIs to v4l2-framework.txt. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- Hopefully we can commit the actual patches now, while we refine the documentation. Documentation/video4linux/v4l2-framework.txt | 62 +- 1 files changed, 60 insertions(+), 2 deletions(-) diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index a300b28..159a83a 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -326,8 +326,27 @@ that width, height and the media bus pixel code are equal on both source and sink of the link. Subdev drivers are also free to use this function to perform the checks mentioned above in addition to their own checks. -A device (bridge) driver needs to register the v4l2_subdev with the -v4l2_device: +There are currently two ways to register subdevices with the V4L2 core. The +first (traditional) possibility is to have subdevices registered by bridge +drivers. This can be done, when the bridge driver has the complete information +about subdevices, connected to it and knows exactly when to register them. This +is typically the case for internal subdevices, like video data processing units +within SoCs or complex pluggable boards, camera sensors in USB cameras or +connected to SoCs, which pass information about them to bridge drivers, usually +in their platform data. + +There are however also situations, where subdevices have to be registered +asynchronously to bridge devices. An example of such a configuration is Device +Tree based systems, on which information about subdevices is made available to +the system indpendently from the bridge devices, e.g. when subdevices are +defined in DT as I2C device nodes. The API, used in this second case is +described further below. + +Using one or the other registration method only affects the probing process, the +run-time bridge-subdevice interaction is in both cases the same. + +In the synchronous case a device (bridge) driver needs to register the +v4l2_subdev with the v4l2_device: int err = v4l2_device_register_subdev(v4l2_dev, sd); @@ -394,6 +413,25 @@ controlled through GPIO pins. This distinction is only relevant when setting up the device, but once the subdev is registered it is completely transparent. +In the asynchronous case subdevices register themselves using the +v4l2_async_register_subdev() function. Unregistration is performed, using the +v4l2_async_unregister_subdev() call. Subdevices registered this way are stored +on a global list of subdevices, ready to be picked up by bridge drivers. + +Bridge drivers in turn have to register a notifier object with an array of +subdevice descriptors, that the bridge device needs for its operation. This is +performed using the v4l2_async_notifier_register() call. To unregister the +notifier the driver has to call v4l2_async_notifier_unregister(). The former of +the two functions takes two arguments: a pointer to struct v4l2_device and a +pointer to struct v4l2_async_notifier. The latter contains a pointer to an array +of pointers to subdevice descriptors of type struct v4l2_async_subdev type. The +V4L2 core will then use these descriptors to match asynchronously registered +subdevices to them. If a match is detected the .bound() notifier callback is +called. After all subdevices have been located the .complete() callback is +called. When a subdevice is removed from the system the .unbind() method is +called. All three callbacks are optional. + + V4L2 sub-device userspace API - @@ -1061,3 +1099,23 @@ available event type is 'class base + 1'. An example on how the V4L2 events may be used can be found in the OMAP 3 ISP driver (drivers/media/platform/omap3isp). + + +V4L2 clocks +--- + +Many subdevices, like camera sensors, TV decoders and encoders, need a clock +signal to be supplied by the system. Often this clock is supplied by the +respective bridge device. The Linux kernel provides a Common Clock Framework for +this purpose, however, it is not (yet) available on all architectures. Besides, +the nature of the multi-functional (clock, data + synchronisation, I2C control) +connection of subdevices to the system might impose special requirements on the +clock API usage. For these reasons a V4L2 clock helper API has been developed +and is provided to bridge and subdevice drivers. + +The API consists of two parts: two functions to register and unregister a V4L2 +clock source: v4l2_clk_register() and v4l2_clk_unregister() and calls to control +a clock object, similar to respective generic clock API calls: v4l2_clk_get(), +v4l2_clk_put(), v4l2_clk_enable(), v4l2_clk_disable(), v4l2_clk_get_rate(), and +v4l2_clk_set_rate(). Clock suppliers have to provide clock operations, that will +be called when clock users invoke respective API
Re: [PATCH 14/15] ARM: shmobile: Remove AP4EVB board support
On Mon, 17 Jun 2013, Magnus Damm wrote: [snip] So Guennadi, if you want to keep this board then you have to step up and fix things. If not then there is no point in keeping it. Ok, after a private discussion we agreed to remove the board, which will also make the drivers for the Renesas sh-/r-mobile CSI2 interface and for the Sony IMX074 sensor untestable and susceptible to removal. Also multi-subdevice support in soc-camera now will lose its only use and can become broken. I will also drop CSI2 and AP4EVB patches from my V4L2 clock / async probing series. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v10 16/21] V4L2: support asynchronous subdevice registration
Hi Hans On Fri, 14 Jun 2013, Hans Verkuil wrote: On Fri 14 June 2013 09:14:48 Guennadi Liakhovetski wrote: Hi Sylwester On Thu, 13 Jun 2013, Sylwester Nawrocki wrote: Hi Guennadi, Overall it looks quite neat at this v10. :) Thanks :) On 06/11/2013 10:23 AM, Guennadi Liakhovetski wrote: Currently bridge device drivers register devices for all subdevices synchronously, tupically, during their probing. E.g. if an I2C CMOS sensor s/tupically/typically is attached to a video bridge device, the bridge driver will create an I2C +/** + * v4l2_async_subdev_list - provided by subdevices + * @list: links struct v4l2_async_subdev_list objects to a global list + * before probing, and onto notifier-done after probing + * @asd: pointer to respective struct v4l2_async_subdev + * @notifier: pointer to managing notifier + */ +struct v4l2_async_subdev_list { + struct list_head list; + struct v4l2_async_subdev *asd; + struct v4l2_async_notifier *notifier; +}; I have a patch for this patch, which embeds members of this struct directly into struct v4l2_subdev. My felling is that the code is simpler and easier to follow this way, I might be missing some important details though. Thanks, saw it. In principle I have nothing against it. I think, it's just principle approach to this work, which seems to differ slightly from how others see it. I tried to as little intrusive as possible, touching current APIs only if absolutely necessary, keeping the async stuff largely separated from the rest. If however the common feeling is, that we should inject it directly in V4L2 core, I have nothing against it either. Still, I would prefer to keep the .c and .h files separate for now at least to reduce merge conflicts etc. I think it makes sense to move this to the core, but keep the .c and .h files separate. Ok, we can apply Sylwester's patch on top of my series, sure. A general note: my experience is that if being being intrusive to existing APIs/data structures will simplify your code, then that's probable a good idea. Core APIs and data structures are not 'holy' and it is quite OK to change them. They will need careful code review, but other than that it is perfectly fine. +/** + * v4l2_async_notifier - v4l2_device notifier data + * @subdev_num:number of subdevices + * @subdev:array of pointers to subdevices How about changing this to: @subdevs: array of pointers to the subdevice descriptors I'm sure every single line of comments and code in these (and all other) patches can be improved :) I think it would be more immediately clear this is the actual subdevs array pointer, and perhaps we could have subdev_num renamed to num_subdevs ? Sure, why not :) + * @v4l2_dev: pointer to struct v4l2_device + * @waiting: list of struct v4l2_async_subdev, waiting for their drivers + * @done: list of struct v4l2_async_subdev_list, already probed + * @list: member in a global list of notifiers + * @bound: a subdevice driver has successfully probed one of subdevices + * @complete: all subdevices have been probed successfully + * @unbind:a subdevice is leaving + */ +struct v4l2_async_notifier { + unsigned int subdev_num; + struct v4l2_async_subdev **subdev; + struct v4l2_device *v4l2_dev; + struct list_head waiting; + struct list_head done; + struct list_head list; + int (*bound)(struct v4l2_async_notifier *notifier, +struct v4l2_subdev *subdev, +struct v4l2_async_subdev *asd); + int (*complete)(struct v4l2_async_notifier *notifier); + void (*unbind)(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd); +}; + +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, +struct v4l2_async_notifier *notifier); +void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); +int v4l2_async_register_subdev(struct v4l2_subdev *sd); +void v4l2_async_unregister_subdev(struct v4l2_subdev *sd); I still think async_ in this public API is unnecessary, since we register/ unregister a subdev with the core and notifiers are intrinsically asynchronous. But your preference seems be otherwise, what could I do... :) At most it just means one less happy user of this interface. I think v4l2_register_subdev looks awfully similar to v4l2_device_register_subdev. It becomes very confusing naming it like that. I prefer v4l2_async where 'async' refers to the v4l2-async
Re: [PATCH v10 16/21] V4L2: support asynchronous subdevice registration
On Fri, 14 Jun 2013, Sylwester Nawrocki wrote: Hi, On 06/14/2013 11:14 AM, Guennadi Liakhovetski wrote: On Fri, 14 Jun 2013, Hans Verkuil wrote: On Fri 14 June 2013 09:14:48 Guennadi Liakhovetski wrote: On Thu, 13 Jun 2013, Sylwester Nawrocki wrote: On 06/11/2013 10:23 AM, Guennadi Liakhovetski wrote: [...] + * @v4l2_dev: pointer to struct v4l2_device + * @waiting: list of struct v4l2_async_subdev, waiting for their drivers + * @done: list of struct v4l2_async_subdev_list, already probed + * @list: member in a global list of notifiers + * @bound: a subdevice driver has successfully probed one of subdevices + * @complete: all subdevices have been probed successfully + * @unbind:a subdevice is leaving + */ +struct v4l2_async_notifier { + unsigned int subdev_num; + struct v4l2_async_subdev **subdev; + struct v4l2_device *v4l2_dev; + struct list_head waiting; + struct list_head done; + struct list_head list; + int (*bound)(struct v4l2_async_notifier *notifier, +struct v4l2_subdev *subdev, +struct v4l2_async_subdev *asd); + int (*complete)(struct v4l2_async_notifier *notifier); + void (*unbind)(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd); +}; + +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, +struct v4l2_async_notifier *notifier); +void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); +int v4l2_async_register_subdev(struct v4l2_subdev *sd); +void v4l2_async_unregister_subdev(struct v4l2_subdev *sd); I still think async_ in this public API is unnecessary, since we register/ unregister a subdev with the core and notifiers are intrinsically asynchronous. But your preference seems be otherwise, what could I do... :) At most it just means one less happy user of this interface. I think v4l2_register_subdev looks awfully similar to v4l2_device_register_subdev. It becomes very confusing naming it like that. I prefer v4l2_async where 'async' refers to the v4l2-async module. Ok, let's leave v4l2_async then. And v4l2(_async)_notifier_(un)register()? I guess it would be better to have all or none of the functions with that prefix. So either: Exactly. Thanks Guennadi v4l2_async_notifier_register v4l2_async_notifier_unregister v4l2_async_register_subdev v4l2_async_unregister_subdev or v4l2_subdev_notifier_register v4l2_subdev_notifier_unregister v4l2_subdev_register v4l2_subdev_unregister Thanks, Sylwester --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 07/21] mx2-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the mx2-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/mx2_camera.c | 28 +++ 1 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index 772e071..45a0276 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -412,13 +412,26 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) writel(0, pcdev-base_emma + PRP_CNTL); } +static int mx2_camera_add_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void mx2_camera_remove_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, Camera driver detached from camera %d\n, +icd-devnum); +} + /* * The following two functions absolutely depend on the fact, that * there can be only one camera on mx2 camera sensor interface */ -static int mx2_camera_add_device(struct soc_camera_device *icd) +static int mx2_camera_clock_start(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx2_camera_dev *pcdev = ici-priv; int ret; u32 csicr1; @@ -439,9 +452,6 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) pcdev-frame_count = 0; - dev_info(icd-parent, Camera driver attached to camera %d\n, -icd-devnum); - return 0; exit_csi_ahb: @@ -450,14 +460,10 @@ exit_csi_ahb: return ret; } -static void mx2_camera_remove_device(struct soc_camera_device *icd) +static void mx2_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx2_camera_dev *pcdev = ici-priv; - dev_info(icd-parent, Camera driver detached from camera %d\n, -icd-devnum); - mx2_camera_deactivate(pcdev); } @@ -1271,6 +1277,8 @@ static struct soc_camera_host_ops mx2_soc_camera_host_ops = { .owner = THIS_MODULE, .add= mx2_camera_add_device, .remove = mx2_camera_remove_device, + .clock_start= mx2_camera_clock_start, + .clock_stop = mx2_camera_clock_stop, .set_fmt= mx2_camera_set_fmt, .set_crop = mx2_camera_set_crop, .get_formats= mx2_camera_get_formats, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 02/21] soc-camera: add host clock callbacks to start and stop the master clock
Currently soc-camera uses a single camera host callback to activate the interface master clock and to configure the interface for a specific client. However, during probing we might not have the information about a client, we just need to activate the clock. Add new camera host driver callbacks to only start and stop the clock without and client-specific configuration. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/soc_camera.c | 19 +-- include/media/soc_camera.h |2 ++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 832f059..df90565 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -513,10 +513,23 @@ static int soc_camera_add_device(struct soc_camera_device *icd) if (ici-icd) return -EBUSY; + if (ici-ops-clock_start) { + ret = ici-ops-clock_start(ici); + if (ret 0) + return ret; + } + ret = ici-ops-add(icd); - if (!ret) - ici-icd = icd; + if (ret 0) + goto eadd; + + ici-icd = icd; + return 0; + +eadd: + if (ici-ops-clock_stop) + ici-ops-clock_stop(ici); return ret; } @@ -528,6 +541,8 @@ static void soc_camera_remove_device(struct soc_camera_device *icd) return; ici-ops-remove(icd); + if (ici-ops-clock_stop) + ici-ops-clock_stop(ici); ici-icd = NULL; } diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 5a46ce2..64415ee 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -74,6 +74,8 @@ struct soc_camera_host_ops { struct module *owner; int (*add)(struct soc_camera_device *); void (*remove)(struct soc_camera_device *); + int (*clock_start)(struct soc_camera_host *); + void (*clock_stop)(struct soc_camera_host *); /* * .get_formats() is called for each client device format, but * .put_formats() is only called once. Further, if any of the calls to -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 08/21] mx1-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the mx1-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/mx1_camera.c | 32 +++- 1 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c index 5f9ec8e..fea3e61 100644 --- a/drivers/media/platform/soc_camera/mx1_camera.c +++ b/drivers/media/platform/soc_camera/mx1_camera.c @@ -399,7 +399,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) { unsigned int csicr1 = CSICR1_EN; - dev_dbg(pcdev-soc_host.icd-parent, Activate device\n); + dev_dbg(pcdev-soc_host.v4l2_dev.dev, Activate device\n); clk_prepare_enable(pcdev-clk); @@ -415,7 +415,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) { - dev_dbg(pcdev-soc_host.icd-parent, Deactivate device\n); + dev_dbg(pcdev-soc_host.v4l2_dev.dev, Deactivate device\n); /* Disable all CSI interface */ __raw_writel(0x00, pcdev-base + CSICR1); @@ -423,26 +423,35 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) clk_disable_unprepare(pcdev-clk); } +static int mx1_camera_add_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, MX1 Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void mx1_camera_remove_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, MX1 Camera driver detached from camera %d\n, +icd-devnum); +} + /* * The following two functions absolutely depend on the fact, that * there can be only one camera on i.MX1/i.MXL camera sensor interface */ -static int mx1_camera_add_device(struct soc_camera_device *icd) +static int mx1_camera_clock_start(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx1_camera_dev *pcdev = ici-priv; - dev_info(icd-parent, MX1 Camera driver attached to camera %d\n, -icd-devnum); - mx1_camera_activate(pcdev); return 0; } -static void mx1_camera_remove_device(struct soc_camera_device *icd) +static void mx1_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx1_camera_dev *pcdev = ici-priv; unsigned int csicr1; @@ -453,9 +462,6 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd) /* Stop DMA engine */ imx_dma_disable(pcdev-dma_chan); - dev_info(icd-parent, MX1 Camera driver detached from camera %d\n, -icd-devnum); - mx1_camera_deactivate(pcdev); } @@ -669,6 +675,8 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = { .owner = THIS_MODULE, .add= mx1_camera_add_device, .remove = mx1_camera_remove_device, + .clock_start= mx1_camera_clock_start, + .clock_stop = mx1_camera_clock_stop, .set_bus_param = mx1_camera_set_bus_param, .set_fmt= mx1_camera_set_fmt, .try_fmt= mx1_camera_try_fmt, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 11/21] soc-camera: don't attach the client to the host during probing
During client probing we only have to turn on the host's clock, no need to actually attach the client to the host. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/soc_camera.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index e503f03..ac98bcb 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1207,7 +1207,7 @@ static int soc_camera_probe(struct soc_camera_device *icd) ssdd-reset(icd-pdev); mutex_lock(ici-host_lock); - ret = soc_camera_add_device(icd); + ret = ici-ops-clock_start(ici); mutex_unlock(ici-host_lock); if (ret 0) goto eadd; @@ -1280,7 +1280,7 @@ static int soc_camera_probe(struct soc_camera_device *icd) icd-field = mf.field; } - soc_camera_remove_device(icd); + ici-ops-clock_stop(ici); mutex_unlock(ici-host_lock); @@ -1303,7 +1303,7 @@ eadddev: icd-vdev = NULL; evdc: mutex_lock(ici-host_lock); - soc_camera_remove_device(icd); + ici-ops-clock_stop(ici); mutex_unlock(ici-host_lock); eadd: v4l2_ctrl_handler_free(icd-ctrl_handler); -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 04/21] omap1-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the omap1-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/omap1_camera.c | 27 ++--- 1 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index c42c23e..6769193 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -893,13 +893,26 @@ static void sensor_reset(struct omap1_cam_dev *pcdev, bool reset) CAM_WRITE(pcdev, GPIO, !reset); } +static int omap1_cam_add_device(struct soc_camera_device *icd) +{ + dev_dbg(icd-parent, OMAP1 Camera driver attached to camera %d\n, + icd-devnum); + + return 0; +} + +static void omap1_cam_remove_device(struct soc_camera_device *icd) +{ + dev_dbg(icd-parent, + OMAP1 Camera driver detached from camera %d\n, icd-devnum); +} + /* * The following two functions absolutely depend on the fact, that * there can be only one camera on OMAP1 camera sensor interface */ -static int omap1_cam_add_device(struct soc_camera_device *icd) +static int omap1_cam_clock_start(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct omap1_cam_dev *pcdev = ici-priv; u32 ctrlclock; @@ -937,14 +950,11 @@ static int omap1_cam_add_device(struct soc_camera_device *icd) sensor_reset(pcdev, false); - dev_dbg(icd-parent, OMAP1 Camera driver attached to camera %d\n, - icd-devnum); return 0; } -static void omap1_cam_remove_device(struct soc_camera_device *icd) +static void omap1_cam_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct omap1_cam_dev *pcdev = ici-priv; u32 ctrlclock; @@ -965,9 +975,6 @@ static void omap1_cam_remove_device(struct soc_camera_device *icd) CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock ~MCLK_EN); clk_disable(pcdev-clk); - - dev_dbg(icd-parent, - OMAP1 Camera driver detached from camera %d\n, icd-devnum); } /* Duplicate standard formats based on host capability of byte swapping */ @@ -1525,6 +1532,8 @@ static struct soc_camera_host_ops omap1_host_ops = { .owner = THIS_MODULE, .add= omap1_cam_add_device, .remove = omap1_cam_remove_device, + .clock_start= omap1_cam_clock_start, + .clock_stop = omap1_cam_clock_stop, .get_formats= omap1_cam_get_formats, .set_crop = omap1_cam_set_crop, .set_fmt= omap1_cam_set_fmt, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 10/21] soc-camera: make .clock_{start,stop} compulsory, .add / .remove optional
All existing soc-camera host drivers use .clock_start() and .clock_stop() callbacks to activate and deactivate their camera interfaces, whereas .add() and .remove() callbacks are usually dummy. Make the former two compulsory and the latter two optional. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/soc_camera.c | 27 +++ 1 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index df90565..e503f03 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -513,23 +513,22 @@ static int soc_camera_add_device(struct soc_camera_device *icd) if (ici-icd) return -EBUSY; - if (ici-ops-clock_start) { - ret = ici-ops-clock_start(ici); + ret = ici-ops-clock_start(ici); + if (ret 0) + return ret; + + if (ici-ops-add) { + ret = ici-ops-add(icd); if (ret 0) - return ret; + goto eadd; } - ret = ici-ops-add(icd); - if (ret 0) - goto eadd; - ici-icd = icd; return 0; eadd: - if (ici-ops-clock_stop) - ici-ops-clock_stop(ici); + ici-ops-clock_stop(ici); return ret; } @@ -540,9 +539,9 @@ static void soc_camera_remove_device(struct soc_camera_device *icd) if (WARN_ON(icd != ici-icd)) return; - ici-ops-remove(icd); - if (ici-ops-clock_stop) - ici-ops-clock_stop(ici); + if (ici-ops-remove) + ici-ops-remove(icd); + ici-ops-clock_stop(ici); ici-icd = NULL; } @@ -1413,8 +1412,8 @@ int soc_camera_host_register(struct soc_camera_host *ici) ((!ici-ops-init_videobuf || !ici-ops-reqbufs) !ici-ops-init_videobuf2) || - !ici-ops-add || - !ici-ops-remove || + !ici-ops-clock_start || + !ici-ops-clock_stop || !ici-ops-poll || !ici-v4l2_dev.dev) return -EINVAL; -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 09/21] sh-mobile-ceu-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the sh-mobile-ceu-camera driver activates and, respectively, deactivates its camera interface and, if necessary, the CSI2 controller. Only handling of the CSI2 interface is client-specific and is only needed, when a data-exchange with the client is taking place. Move the rest to .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- .../platform/soc_camera/sh_mobile_ceu_camera.c | 58 1 files changed, 35 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 5b7d8e1..9037472 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -162,7 +162,6 @@ static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs) static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev) { int i, success = 0; - struct soc_camera_device *icd = pcdev-ici.icd; ceu_write(pcdev, CAPSR, 1 16); /* reset */ @@ -186,7 +185,7 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev) if (2 != success) { - dev_warn(icd-pdev, soft reset time out\n); + dev_warn(pcdev-ici.v4l2_dev.dev, soft reset time out\n); return -EIO; } @@ -543,35 +542,21 @@ static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev) return NULL; } -/* Called with .host_lock held */ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct sh_mobile_ceu_dev *pcdev = ici-priv; - struct v4l2_subdev *csi2_sd; + struct v4l2_subdev *csi2_sd = find_csi2(pcdev); int ret; - dev_info(icd-parent, -SuperH Mobile CEU driver attached to camera %d\n, -icd-devnum); - - pm_runtime_get_sync(ici-v4l2_dev.dev); - - pcdev-buf_total = 0; - - ret = sh_mobile_ceu_soft_reset(pcdev); - - csi2_sd = find_csi2(pcdev); if (csi2_sd) { csi2_sd-grp_id = soc_camera_grp_id(icd); v4l2_set_subdev_hostdata(csi2_sd, icd); } ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); - if (ret 0 ret != -ENOIOCTLCMD ret != -ENODEV) { - pm_runtime_put(ici-v4l2_dev.dev); + if (ret 0 ret != -ENOIOCTLCMD ret != -ENODEV) return ret; - } /* * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver @@ -580,19 +565,48 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) if (ret == -ENODEV csi2_sd) csi2_sd-grp_id = 0; + dev_info(icd-parent, +SuperH Mobile CEU driver attached to camera %d\n, +icd-devnum); + return 0; } -/* Called with .host_lock held */ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct sh_mobile_ceu_dev *pcdev = ici-priv; struct v4l2_subdev *csi2_sd = find_csi2(pcdev); + dev_info(icd-parent, +SuperH Mobile CEU driver detached from camera %d\n, +icd-devnum); + v4l2_subdev_call(csi2_sd, core, s_power, 0); if (csi2_sd) csi2_sd-grp_id = 0; +} + +/* Called with .host_lock held */ +static int sh_mobile_ceu_clock_start(struct soc_camera_host *ici) +{ + struct sh_mobile_ceu_dev *pcdev = ici-priv; + int ret; + + pm_runtime_get_sync(ici-v4l2_dev.dev); + + pcdev-buf_total = 0; + + ret = sh_mobile_ceu_soft_reset(pcdev); + + return 0; +} + +/* Called with .host_lock held */ +static void sh_mobile_ceu_clock_stop(struct soc_camera_host *ici) +{ + struct sh_mobile_ceu_dev *pcdev = ici-priv; + /* disable capture, disable interrupts */ ceu_write(pcdev, CEIER, 0); sh_mobile_ceu_soft_reset(pcdev); @@ -607,10 +621,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) spin_unlock_irq(pcdev-lock); pm_runtime_put(ici-v4l2_dev.dev); - - dev_info(icd-parent, -SuperH Mobile CEU driver detached from camera %d\n, -icd-devnum); } /* @@ -2027,6 +2037,8 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { .owner = THIS_MODULE, .add= sh_mobile_ceu_add_device, .remove = sh_mobile_ceu_remove_device, + .clock_start= sh_mobile_ceu_clock_start, + .clock_stop = sh_mobile_ceu_clock_stop, .get_formats= sh_mobile_ceu_get_formats, .put_formats= sh_mobile_ceu_put_formats, .get_crop = sh_mobile_ceu_get_crop, -- 1.7.2.5 -- To unsubscribe
[PATCH v11 01/21] soc-camera: move common code to soc_camera.c
All soc-camera host drivers include a pointer to an soc-camera device in their host private struct to check, that only one client is connected. Move this common code to soc_camera.c. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/atmel-isi.c | 10 +- drivers/media/platform/soc_camera/mx1_camera.c | 20 +++ drivers/media/platform/soc_camera/mx2_camera.c | 13 +-- drivers/media/platform/soc_camera/mx3_camera.c |9 - drivers/media/platform/soc_camera/omap1_camera.c | 14 +-- drivers/media/platform/soc_camera/pxa_camera.c | 18 ++--- .../platform/soc_camera/sh_mobile_ceu_camera.c | 13 +-- drivers/media/platform/soc_camera/soc_camera.c | 38 --- include/media/soc_camera.h |1 + 9 files changed, 49 insertions(+), 87 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 1abbb36..c9e080a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -102,7 +102,6 @@ struct atmel_isi { struct list_headvideo_buffer_list; struct frame_buffer *active; - struct soc_camera_device*icd; struct soc_camera_host soc_host; }; @@ -367,7 +366,7 @@ static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer) /* Check if already in a frame */ if (isi_readl(isi, ISI_STATUS) ISI_CTRL_CDC) { - dev_err(isi-icd-parent, Already in frame handling.\n); + dev_err(isi-soc_host.icd-parent, Already in frame handling.\n); return; } @@ -753,9 +752,6 @@ static int isi_camera_add_device(struct soc_camera_device *icd) struct atmel_isi *isi = ici-priv; int ret; - if (isi-icd) - return -EBUSY; - ret = clk_enable(isi-pclk); if (ret) return ret; @@ -766,7 +762,6 @@ static int isi_camera_add_device(struct soc_camera_device *icd) return ret; } - isi-icd = icd; dev_dbg(icd-parent, Atmel ISI Camera driver attached to camera %d\n, icd-devnum); return 0; @@ -777,11 +772,8 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct atmel_isi *isi = ici-priv; - BUG_ON(icd != isi-icd); - clk_disable(isi-mck); clk_disable(isi-pclk); - isi-icd = NULL; dev_dbg(icd-parent, Atmel ISI Camera driver detached from camera %d\n, icd-devnum); diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c index a3fd8d6..5f9ec8e 100644 --- a/drivers/media/platform/soc_camera/mx1_camera.c +++ b/drivers/media/platform/soc_camera/mx1_camera.c @@ -104,7 +104,6 @@ struct mx1_buffer { */ struct mx1_camera_dev { struct soc_camera_host soc_host; - struct soc_camera_device*icd; struct mx1_camera_pdata *pdata; struct mx1_buffer *active; struct resource *res; @@ -220,7 +219,7 @@ out: static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev) { struct videobuf_buffer *vbuf = pcdev-active-vb; - struct device *dev = pcdev-icd-parent; + struct device *dev = pcdev-soc_host.icd-parent; int ret; if (unlikely(!pcdev-active)) { @@ -331,7 +330,7 @@ static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev, static void mx1_camera_dma_irq(int channel, void *data) { struct mx1_camera_dev *pcdev = data; - struct device *dev = pcdev-icd-parent; + struct device *dev = pcdev-soc_host.icd-parent; struct mx1_buffer *buf; struct videobuf_buffer *vb; unsigned long flags; @@ -389,7 +388,7 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev) */ div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; - dev_dbg(pcdev-icd-parent, + dev_dbg(pcdev-soc_host.icd-parent, System clock %lukHz, target freq %dkHz, divisor %lu\n, lcdclk / 1000, mclk / 1000, div); @@ -400,7 +399,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) { unsigned int csicr1 = CSICR1_EN; - dev_dbg(pcdev-icd-parent, Activate device\n); + dev_dbg(pcdev-soc_host.icd-parent, Activate device\n); clk_prepare_enable(pcdev-clk); @@ -416,7 +415,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) { - dev_dbg(pcdev-icd-parent, Deactivate device\n); + dev_dbg(pcdev-soc_host.icd-parent, Deactivate device\n); /* Disable all CSI interface */ __raw_writel
[PATCH v11 06/21] mx3-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the mx3-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/mx3_camera.c | 35 ++- 1 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 71b9b19..1047e3e 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -460,8 +460,7 @@ static int mx3_camera_init_videobuf(struct vb2_queue *q, } /* First part of ipu_csi_init_interface() */ -static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam, - struct soc_camera_device *icd) +static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam) { u32 conf; long rate; @@ -505,31 +504,40 @@ static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam, clk_prepare_enable(mx3_cam-clk); rate = clk_round_rate(mx3_cam-clk, mx3_cam-mclk); - dev_dbg(icd-parent, Set SENS_CONF to %x, rate %ld\n, conf, rate); + dev_dbg(mx3_cam-soc_host.v4l2_dev.dev, Set SENS_CONF to %x, rate %ld\n, conf, rate); if (rate) clk_set_rate(mx3_cam-clk, rate); } -/* Called with .host_lock held */ static int mx3_camera_add_device(struct soc_camera_device *icd) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); + dev_info(icd-parent, MX3 Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void mx3_camera_remove_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, MX3 Camera driver detached from camera %d\n, +icd-devnum); +} + +/* Called with .host_lock held */ +static int mx3_camera_clock_start(struct soc_camera_host *ici) +{ struct mx3_camera_dev *mx3_cam = ici-priv; - mx3_camera_activate(mx3_cam, icd); + mx3_camera_activate(mx3_cam); mx3_cam-buf_total = 0; - dev_info(icd-parent, MX3 Camera driver attached to camera %d\n, -icd-devnum); - return 0; } /* Called with .host_lock held */ -static void mx3_camera_remove_device(struct soc_camera_device *icd) +static void mx3_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx3_camera_dev *mx3_cam = ici-priv; struct idmac_channel **ichan = mx3_cam-idmac_channel[0]; @@ -539,9 +547,6 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd) } clk_disable_unprepare(mx3_cam-clk); - - dev_info(icd-parent, MX3 Camera driver detached from camera %d\n, -icd-devnum); } static int test_platform_param(struct mx3_camera_dev *mx3_cam, @@ -1124,6 +1129,8 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = { .owner = THIS_MODULE, .add= mx3_camera_add_device, .remove = mx3_camera_remove_device, + .clock_start= mx3_camera_clock_start, + .clock_stop = mx3_camera_clock_stop, .set_crop = mx3_camera_set_crop, .set_fmt= mx3_camera_set_fmt, .try_fmt= mx3_camera_try_fmt, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 05/21] atmel-isi: move interface activation and deactivation to clock callbacks
When adding and removing a client, the atmel-isi camera host driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/atmel-isi.c | 28 + 1 files changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c9e080a..1044856 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -745,10 +745,23 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, return formats; } -/* Called with .host_lock held */ static int isi_camera_add_device(struct soc_camera_device *icd) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); + dev_dbg(icd-parent, Atmel ISI Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void isi_camera_remove_device(struct soc_camera_device *icd) +{ + dev_dbg(icd-parent, Atmel ISI Camera driver detached from camera %d\n, +icd-devnum); +} + +/* Called with .host_lock held */ +static int isi_camera_clock_start(struct soc_camera_host *ici) +{ struct atmel_isi *isi = ici-priv; int ret; @@ -762,21 +775,16 @@ static int isi_camera_add_device(struct soc_camera_device *icd) return ret; } - dev_dbg(icd-parent, Atmel ISI Camera driver attached to camera %d\n, -icd-devnum); return 0; } + /* Called with .host_lock held */ -static void isi_camera_remove_device(struct soc_camera_device *icd) +static void isi_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct atmel_isi *isi = ici-priv; clk_disable(isi-mck); clk_disable(isi-pclk); - - dev_dbg(icd-parent, Atmel ISI Camera driver detached from camera %d\n, -icd-devnum); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -880,6 +888,8 @@ static struct soc_camera_host_ops isi_soc_camera_host_ops = { .owner = THIS_MODULE, .add= isi_camera_add_device, .remove = isi_camera_remove_device, + .clock_start= isi_camera_clock_start, + .clock_stop = isi_camera_clock_stop, .set_fmt= isi_camera_set_fmt, .try_fmt= isi_camera_try_fmt, .get_formats= isi_camera_get_formats, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 03/21] pxa-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the pxa-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/pxa_camera.c | 28 +++ 1 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 686edf7..d4df305 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -955,33 +955,39 @@ static irqreturn_t pxa_camera_irq(int irq, void *data) return IRQ_HANDLED; } +static int pxa_camera_add_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, PXA Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void pxa_camera_remove_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, PXA Camera driver detached from camera %d\n, +icd-devnum); +} + /* * The following two functions absolutely depend on the fact, that * there can be only one camera on PXA quick capture interface * Called with .host_lock held */ -static int pxa_camera_add_device(struct soc_camera_device *icd) +static int pxa_camera_clock_start(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct pxa_camera_dev *pcdev = ici-priv; pxa_camera_activate(pcdev); - dev_info(icd-parent, PXA Camera driver attached to camera %d\n, -icd-devnum); - return 0; } /* Called with .host_lock held */ -static void pxa_camera_remove_device(struct soc_camera_device *icd) +static void pxa_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct pxa_camera_dev *pcdev = ici-priv; - dev_info(icd-parent, PXA Camera driver detached from camera %d\n, -icd-devnum); - /* disable capture, disable interrupts */ __raw_writel(0x3ff, pcdev-base + CICR0); @@ -1630,6 +1636,8 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { .owner = THIS_MODULE, .add= pxa_camera_add_device, .remove = pxa_camera_remove_device, + .clock_start= pxa_camera_clock_start, + .clock_stop = pxa_camera_clock_stop, .set_crop = pxa_camera_set_crop, .get_formats= pxa_camera_get_formats, .put_formats= pxa_camera_put_formats, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 13/21] sh-mobile-ceu-driver: support max width and height in DT
Some CEU implementations have non-standard (larger) maximum supported width and height values. Add two OF properties to specify them. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- .../devicetree/bindings/media/sh_mobile_ceu.txt| 18 +++ .../platform/soc_camera/sh_mobile_ceu_camera.c | 23 ++- 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/sh_mobile_ceu.txt diff --git a/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt b/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt new file mode 100644 index 000..1ce4e46 --- /dev/null +++ b/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt @@ -0,0 +1,18 @@ +Bindings, specific for the sh_mobile_ceu_camera.c driver: + - compatible: Should be renesas,sh-mobile-ceu + - reg: register base and size + - interrupts: the interrupt number + - interrupt-parent: the interrupt controller + - renesas,max-width: maximum image width, supported on this SoC + - renesas,max-height: maximum image height, supported on this SoC + +Example: + +ceu0: ceu@0xfe91 { + compatible = renesas,sh-mobile-ceu; + reg = 0xfe91 0xa0; + interrupt-parent = intcs; + interrupts = 0x880; + renesas,max-width = 8188; + renesas,max-height = 8188; +}; diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index fcc13d8..b0f0995 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -2116,11 +2116,30 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) /* TODO: implement per-device bus flags */ if (pcdev-pdata) { - pcdev-max_width = pcdev-pdata-max_width ? : 2560; - pcdev-max_height = pcdev-pdata-max_height ? : 1920; + pcdev-max_width = pcdev-pdata-max_width; + pcdev-max_height = pcdev-pdata-max_height; pcdev-flags = pcdev-pdata-flags; } + if (!pcdev-max_width) { + unsigned int v; + err = of_property_read_u32(pdev-dev.of_node, renesas,max-width, v); + if (!err) + pcdev-max_width = v; + + if (!pcdev-max_width) + pcdev-max_width = 2560; + } + if (!pcdev-max_height) { + unsigned int v; + err = of_property_read_u32(pdev-dev.of_node, renesas,max-height, v); + if (!err) + pcdev-max_height = v; + + if (!pcdev-max_height) + pcdev-max_height = 1920; + } + base = devm_ioremap_resource(pdev-dev, res); if (IS_ERR(base)) return PTR_ERR(base); -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 17/21] soc-camera: switch I2C subdevice drivers to use v4l2-clk
Instead of centrally enabling and disabling subdevice master clocks in soc-camera core, let subdevice drivers do that themselves, using the V4L2 clock API and soc-camera convenience wrappers. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/i2c/soc_camera/imx074.c | 18 ++- drivers/media/i2c/soc_camera/mt9m001.c | 17 ++- drivers/media/i2c/soc_camera/mt9m111.c | 20 ++- drivers/media/i2c/soc_camera/mt9t031.c | 19 ++- drivers/media/i2c/soc_camera/mt9t112.c | 25 +++- drivers/media/i2c/soc_camera/mt9v022.c | 17 ++- drivers/media/i2c/soc_camera/ov2640.c | 19 ++- drivers/media/i2c/soc_camera/ov5642.c | 20 ++- drivers/media/i2c/soc_camera/ov6650.c | 17 ++- drivers/media/i2c/soc_camera/ov772x.c | 15 ++- drivers/media/i2c/soc_camera/ov9640.c | 17 ++- drivers/media/i2c/soc_camera/ov9640.h |1 + drivers/media/i2c/soc_camera/ov9740.c | 18 ++- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 17 ++- drivers/media/i2c/soc_camera/tw9910.c | 24 +++- drivers/media/platform/soc_camera/soc_camera.c | 162 +++- .../platform/soc_camera/soc_camera_platform.c |2 +- include/media/soc_camera.h | 13 +- 18 files changed, 362 insertions(+), 79 deletions(-) diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index a2a5cbb..a6a5060 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -18,6 +18,7 @@ #include linux/module.h #include media/soc_camera.h +#include media/v4l2-clk.h #include media/v4l2-subdev.h #include media/v4l2-chip-ident.h @@ -77,6 +78,7 @@ struct imx074_datafmt { struct imx074 { struct v4l2_subdev subdev; const struct imx074_datafmt *fmt; + struct v4l2_clk *clk; }; static const struct imx074_datafmt imx074_colour_fmts[] = { @@ -272,8 +274,9 @@ static int imx074_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct imx074 *priv = to_imx074(client); - return soc_camera_set_power(client-dev, ssdd, on); + return soc_camera_set_power(client-dev, ssdd, priv-clk, on); } static int imx074_g_mbus_config(struct v4l2_subdev *sd, @@ -431,6 +434,7 @@ static int imx074_probe(struct i2c_client *client, struct imx074 *priv; struct i2c_adapter *adapter = to_i2c_adapter(client-dev.parent); struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + int ret; if (!ssdd) { dev_err(client-dev, IMX074: missing platform data!\n); @@ -451,13 +455,23 @@ static int imx074_probe(struct i2c_client *client, priv-fmt = imx074_colour_fmts[0]; - return imx074_video_probe(client); + priv-clk = v4l2_clk_get(client-dev, mclk); + if (IS_ERR(priv-clk)) + return PTR_ERR(priv-clk); + + ret = imx074_video_probe(client); + if (ret 0) + v4l2_clk_put(priv-clk); + + return ret; } static int imx074_remove(struct i2c_client *client) { struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct imx074 *priv = to_imx074(client); + v4l2_clk_put(priv-clk); if (ssdd-free_bus) ssdd-free_bus(ssdd); diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c index dd90898..620f9df 100644 --- a/drivers/media/i2c/soc_camera/mt9m001.c +++ b/drivers/media/i2c/soc_camera/mt9m001.c @@ -16,6 +16,7 @@ #include media/soc_camera.h #include media/soc_mediabus.h +#include media/v4l2-clk.h #include media/v4l2-subdev.h #include media/v4l2-chip-ident.h #include media/v4l2-ctrls.h @@ -94,6 +95,7 @@ struct mt9m001 { struct v4l2_ctrl *exposure; }; struct v4l2_rect rect; /* Sensor window */ + struct v4l2_clk *clk; const struct mt9m001_datafmt *fmt; const struct mt9m001_datafmt *fmts; int num_fmts; @@ -381,8 +383,9 @@ static int mt9m001_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct mt9m001 *mt9m001 = to_mt9m001(client); - return soc_camera_set_power(client-dev, ssdd, on); + return soc_camera_set_power(client-dev, ssdd, mt9m001-clk, on); } static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl) @@ -710,9 +713,18 @@ static int mt9m001_probe(struct i2c_client *client, mt9m001-rect.width = MT9M001_MAX_WIDTH; mt9m001-rect.height= MT9M001_MAX_HEIGHT; + mt9m001-clk
[PATCH v11 16/21] V4L2: support asynchronous subdevice registration
Currently bridge device drivers register devices for all subdevices synchronously, typically, during their probing. E.g. if an I2C CMOS sensor is attached to a video bridge device, the bridge driver will create an I2C device and wait for the respective I2C driver to probe. This makes linking of devices straight forward, but this approach cannot be used with intrinsically asynchronous and unordered device registration systems like the Flattened Device Tree. To support such systems this patch adds an asynchronous subdevice registration framework to V4L2. To use it respective (e.g. I2C) subdevice drivers must register themselves with the framework. A bridge driver on the other hand must register notification callbacks, that will be called upon various related events. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- v11: extended comments, renamed one field drivers/media/v4l2-core/Makefile |3 +- drivers/media/v4l2-core/v4l2-async.c | 280 ++ include/media/v4l2-async.h | 105 + include/media/v4l2-subdev.h |8 + 4 files changed, 395 insertions(+), 1 deletions(-) create mode 100644 drivers/media/v4l2-core/v4l2-async.c create mode 100644 include/media/v4l2-async.h diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index 628c630..4c33b8d6 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -5,7 +5,8 @@ tuner-objs := tuner-core.o videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ - v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o + v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o \ + v4l2-async.o ifeq ($(CONFIG_COMPAT),y) videodev-objs += v4l2-compat-ioctl32.o endif diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c new file mode 100644 index 000..c80ffb4 --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -0,0 +1,280 @@ +/* + * V4L2 asynchronous subdevice registration API + * + * Copyright (C) 2012-2013, Guennadi Liakhovetski g.liakhovet...@gmx.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/device.h +#include linux/err.h +#include linux/i2c.h +#include linux/list.h +#include linux/module.h +#include linux/mutex.h +#include linux/platform_device.h +#include linux/slab.h +#include linux/types.h + +#include media/v4l2-async.h +#include media/v4l2-device.h +#include media/v4l2-subdev.h + +static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd) +{ + struct i2c_client *client = i2c_verify_client(dev); + return client + asd-bus_type == V4L2_ASYNC_BUS_I2C + asd-match.i2c.adapter_id == client-adapter-nr + asd-match.i2c.address == client-addr; +} + +static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd) +{ + return asd-bus_type == V4L2_ASYNC_BUS_PLATFORM + !strcmp(asd-match.platform.name, dev_name(dev)); +} + +static LIST_HEAD(subdev_list); +static LIST_HEAD(notifier_list); +static DEFINE_MUTEX(list_lock); + +static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier, + struct v4l2_async_subdev_list *asdl) +{ + struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl); + struct v4l2_async_subdev *asd; + bool (*match)(struct device *, + struct v4l2_async_subdev *); + + list_for_each_entry(asd, notifier-waiting, list) { + /* bus_type has been verified valid before */ + switch (asd-bus_type) { + case V4L2_ASYNC_BUS_CUSTOM: + match = asd-match.custom.match; + if (!match) + /* Match always */ + return asd; + break; + case V4L2_ASYNC_BUS_PLATFORM: + match = match_platform; + break; + case V4L2_ASYNC_BUS_I2C: + match = match_i2c; + break; + default: + /* Cannot happen, unless someone breaks us */ + WARN_ON(true); + return NULL; + } + + /* match cannot be NULL here */ + if (match(sd-dev, asd)) + return asd; + } + + return NULL; +} + +static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, + struct v4l2_async_subdev_list *asdl, + struct v4l2_async_subdev *asd) +{ + struct v4l2_subdev *sd
[PATCH v11 19/21] sh_mobile_ceu_camera: add asynchronous subdevice probing support
Use the v4l2-async API to support asynchronous subdevice probing, including the CSI2 subdevice. Synchronous probing is still supported too. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- .../platform/soc_camera/sh_mobile_ceu_camera.c | 134 +- drivers/media/platform/soc_camera/sh_mobile_csi2.c | 153 include/media/sh_mobile_ceu.h |2 + include/media/sh_mobile_csi2.h |2 +- 4 files changed, 190 insertions(+), 101 deletions(-) diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index b0f0995..d1b410b 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -36,6 +36,7 @@ #include linux/pm_runtime.h #include linux/sched.h +#include media/v4l2-async.h #include media/v4l2-common.h #include media/v4l2-dev.h #include media/soc_camera.h @@ -96,6 +97,10 @@ struct sh_mobile_ceu_buffer { struct sh_mobile_ceu_dev { struct soc_camera_host ici; + /* Asynchronous CSI2 linking */ + struct v4l2_async_subdev *csi2_asd; + struct v4l2_subdev *csi2_sd; + /* Synchronous probing compatibility */ struct platform_device *csi2_pdev; unsigned int irq; @@ -185,7 +190,6 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev) udelay(1); } - if (2 != success) { dev_warn(pcdev-ici.v4l2_dev.dev, soft reset time out\n); return -EIO; @@ -534,16 +538,29 @@ static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev) { struct v4l2_subdev *sd; - if (!pcdev-csi2_pdev) - return NULL; + if (pcdev-csi2_sd) + return pcdev-csi2_sd; - v4l2_device_for_each_subdev(sd, pcdev-ici.v4l2_dev) - if (pcdev-csi2_pdev-dev == v4l2_get_subdevdata(sd)) - return sd; + if (pcdev-csi2_asd) { + char name[] = sh-mobile-csi2; + v4l2_device_for_each_subdev(sd, pcdev-ici.v4l2_dev) + if (!strncmp(name, sd-name, sizeof(name) - 1)) { + pcdev-csi2_sd = sd; + return sd; + } + } return NULL; } +static struct v4l2_subdev *csi2_subdev(struct sh_mobile_ceu_dev *pcdev, + struct soc_camera_device *icd) +{ + struct v4l2_subdev *sd = pcdev-csi2_sd; + + return sd sd-grp_id == soc_camera_grp_id(icd) ? sd : NULL; +} + static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd-parent); @@ -564,12 +581,12 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver * has not found this soc-camera device among its clients */ - if (ret == -ENODEV csi2_sd) + if (csi2_sd ret == -ENODEV) csi2_sd-grp_id = 0; dev_info(icd-parent, -SuperH Mobile CEU driver attached to camera %d\n, -icd-devnum); +SuperH Mobile CEU%s driver attached to camera %d\n, +csi2_sd csi2_sd-grp_id ? /CSI-2 : , icd-devnum); return 0; } @@ -585,8 +602,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) icd-devnum); v4l2_subdev_call(csi2_sd, core, s_power, 0); - if (csi2_sd) - csi2_sd-grp_id = 0; } /* Called with .host_lock held */ @@ -708,7 +723,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) } /* CSI2 special configuration */ - if (pcdev-csi2_pdev) { + if (csi2_subdev(pcdev, icd)) { in_width = ((in_width - 2) * 2); left_offset *= 2; } @@ -765,13 +780,7 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr) static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev, struct soc_camera_device *icd) { - if (pcdev-csi2_pdev) { - struct v4l2_subdev *csi2_sd = find_csi2(pcdev); - if (csi2_sd csi2_sd-grp_id == soc_camera_grp_id(icd)) - return csi2_sd; - } - - return soc_camera_to_subdev(icd); + return csi2_subdev(pcdev, icd) ? : soc_camera_to_subdev(icd); } #define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \ @@ -875,7 +884,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) value |= common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 1 : 0; value |= common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 0 : 0; - if (pcdev-csi2_pdev) /* CSI2 mode */ + if (csi2_subdev(pcdev, icd
[PATCH v11 21/21] ARM: shmobile: convert ap4evb to asynchronously register camera subdevices
Register the imx074 camera I2C and the CSI-2 platform devices directly in board platform data instead of letting the sh_mobile_ceu_camera driver and the soc-camera framework register them at their run-time. This uses the V4L2 asynchronous subdevice probing capability. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- arch/arm/mach-shmobile/board-ap4evb.c | 103 +++- arch/arm/mach-shmobile/clock-sh7372.c |1 + 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 45f78ca..f0beec0 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -51,6 +51,7 @@ #include media/sh_mobile_ceu.h #include media/sh_mobile_csi2.h #include media/soc_camera.h +#include media/v4l2-async.h #include sound/sh_fsi.h #include sound/simple_card.h @@ -872,22 +873,32 @@ static struct platform_device leds_device = { }, }; -static struct i2c_board_info imx074_info = { - I2C_BOARD_INFO(imx074, 0x1a), +/* I2C */ +static struct soc_camera_subdev_desc imx074_desc; +static struct i2c_board_info i2c0_devices[] = { + { + I2C_BOARD_INFO(ak4643, 0x13), + }, { + I2C_BOARD_INFO(imx074, 0x1a), + .platform_data = imx074_desc, + }, }; -static struct soc_camera_link imx074_link = { - .bus_id = 0, - .board_info = imx074_info, - .i2c_adapter_id = 0, - .module_name= imx074, +static struct i2c_board_info i2c1_devices[] = { + { + I2C_BOARD_INFO(r2025sd, 0x32), + }, }; -static struct platform_device ap4evb_camera = { - .name = soc-camera-pdrv, - .id = 0, - .dev= { - .platform_data = imx074_link, +static struct resource csi2_resources[] = { + { + .name = CSI2, + .start = 0xffc9, + .end= 0xffc90fff, + .flags = IORESOURCE_MEM, + }, { + .start = intcs_evt2irq(0x17a0), + .flags = IORESOURCE_IRQ, }, }; @@ -896,7 +907,7 @@ static struct sh_csi2_client_config csi2_clients[] = { .phy= SH_CSI2_PHY_MAIN, .lanes = 0,/* default: 2 lanes */ .channel= 0, - .pdev = ap4evb_camera, + .name = imx074, }, }; @@ -907,31 +918,50 @@ static struct sh_csi2_pdata csi2_info = { .flags = SH_CSI2_ECC | SH_CSI2_CRC, }; -static struct resource csi2_resources[] = { - [0] = { - .name = CSI2, - .start = 0xffc9, - .end= 0xffc90fff, - .flags = IORESOURCE_MEM, +static struct platform_device csi2_device = { + .name = sh-mobile-csi2, + .id = 0, + .num_resources = ARRAY_SIZE(csi2_resources), + .resource = csi2_resources, + .dev= { + .platform_data = csi2_info, }, - [1] = { - .start = intcs_evt2irq(0x17a0), - .flags = IORESOURCE_IRQ, +}; + +static struct soc_camera_async_subdev csi2_sd = { + .asd = { + .bus_type = V4L2_ASYNC_BUS_PLATFORM, + .match.platform.name = sh-mobile-csi2.0, }, + .role = SOCAM_SUBDEV_DATA_PROCESSOR, }; -static struct sh_mobile_ceu_companion csi2 = { - .id = 0, - .num_resources = ARRAY_SIZE(csi2_resources), - .resource = csi2_resources, - .platform_data = csi2_info, +static struct soc_camera_async_subdev imx074_sd = { + .asd = { + .bus_type = V4L2_ASYNC_BUS_I2C, + .match.i2c = { + .adapter_id = 0, + .address = 0x1a, + }, + }, + .role = SOCAM_SUBDEV_DATA_SOURCE, }; +static struct v4l2_async_subdev *ceu_subdevs[] = { + /* Single 2-element group */ + csi2_sd.asd, + imx074_sd.asd, +}; + +/* 0-terminated array of group-sizes */ +static int ceu_subdev_sizes[] = {ARRAY_SIZE(ceu_subdevs), 0}; + static struct sh_mobile_ceu_info sh_mobile_ceu_info = { .flags = SH_CEU_FLAG_USE_8BIT_BUS, .max_width = 8188, .max_height = 8188, - .csi2 = csi2, + .asd = ceu_subdevs, + .asd_sizes = ceu_subdev_sizes, }; static struct resource ceu_resources[] = { @@ -976,7 +1006,7 @@ static struct platform_device *ap4evb_devices[] __initdata = { lcdc_device, lcdc1_device, ceu_device, - ap4evb_camera, + csi2_device, meram_device, }; @@ -1071,19 +1101,6 @@ static struct i2c_board_info tsc_device = { /*.irq is selected on ap4evb_init */ }; -/* I2C */ -static struct i2c_board_info i2c0_devices
[PATCH v11 12/21] sh-mobile-ceu-camera: add primitive OF support
Add an OF hook to sh_mobile_ceu_camera.c, no properties so far. Booting with DT also requires platform data to be optional. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- .../platform/soc_camera/sh_mobile_ceu_camera.c | 33 ++-- 1 files changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 9037472..fcc13d8 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -27,6 +27,7 @@ #include linux/kernel.h #include linux/mm.h #include linux/moduleparam.h +#include linux/of.h #include linux/time.h #include linux/slab.h #include linux/device.h @@ -118,6 +119,7 @@ struct sh_mobile_ceu_dev { enum v4l2_field field; int sequence; + unsigned long flags; unsigned int image_mode:1; unsigned int is_16bit:1; @@ -706,7 +708,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) } /* CSI2 special configuration */ - if (pcdev-pdata-csi2) { + if (pcdev-csi2_pdev) { in_width = ((in_width - 2) * 2); left_offset *= 2; } @@ -810,7 +812,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) /* Make choises, based on platform preferences */ if ((common_flags V4L2_MBUS_HSYNC_ACTIVE_HIGH) (common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW)) { - if (pcdev-pdata-flags SH_CEU_FLAG_HSYNC_LOW) + if (pcdev-flags SH_CEU_FLAG_HSYNC_LOW) common_flags = ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; else common_flags = ~V4L2_MBUS_HSYNC_ACTIVE_LOW; @@ -818,7 +820,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) if ((common_flags V4L2_MBUS_VSYNC_ACTIVE_HIGH) (common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW)) { - if (pcdev-pdata-flags SH_CEU_FLAG_VSYNC_LOW) + if (pcdev-flags SH_CEU_FLAG_VSYNC_LOW) common_flags = ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; else common_flags = ~V4L2_MBUS_VSYNC_ACTIVE_LOW; @@ -873,11 +875,11 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) value |= common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 1 : 0; value |= common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 0 : 0; - if (pcdev-pdata-csi2) /* CSI2 mode */ + if (pcdev-csi2_pdev) /* CSI2 mode */ value |= 3 12; else if (pcdev-is_16bit) value |= 1 12; - else if (pcdev-pdata-flags SH_CEU_FLAG_LOWER_8BIT) + else if (pcdev-flags SH_CEU_FLAG_LOWER_8BIT) value |= 2 12; ceu_write(pcdev, CAMCR, value); @@ -1052,7 +1054,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int return 0; } - if (!pcdev-pdata-csi2) { + if (!pcdev-pdata || !pcdev-pdata-csi2) { /* Are there any restrictions in the CSI-2 case? */ ret = sh_mobile_ceu_try_bus_param(icd, fmt-bits_per_sample); if (ret 0) @@ -2107,13 +2109,17 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) init_completion(pcdev-complete); pcdev-pdata = pdev-dev.platform_data; - if (!pcdev-pdata) { + if (!pcdev-pdata !pdev-dev.of_node) { dev_err(pdev-dev, CEU platform data not set.\n); return -EINVAL; } - pcdev-max_width = pcdev-pdata-max_width ? : 2560; - pcdev-max_height = pcdev-pdata-max_height ? : 1920; + /* TODO: implement per-device bus flags */ + if (pcdev-pdata) { + pcdev-max_width = pcdev-pdata-max_width ? : 2560; + pcdev-max_height = pcdev-pdata-max_height ? : 1920; + pcdev-flags = pcdev-pdata-flags; + } base = devm_ioremap_resource(pdev-dev, res); if (IS_ERR(base)) @@ -2168,7 +2174,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) goto exit_free_ctx; /* CSI2 interfacing */ - csi2 = pcdev-pdata-csi2; + csi2 = pcdev-pdata ? pcdev-pdata-csi2 : NULL; if (csi2) { struct platform_device *csi2_pdev = platform_device_alloc(sh-mobile-csi2, csi2-id); @@ -2290,10 +2296,17 @@ static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = { .runtime_resume = sh_mobile_ceu_runtime_nop, }; +static const struct of_device_id sh_mobile_ceu_of_match[] = { + { .compatible = renesas,sh-mobile-ceu }, + { } +}; +MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match); + static struct platform_driver sh_mobile_ceu_driver = { .driver = { .name = sh_mobile_ceu
[PATCH v11 15/21] V4L2: add a device pointer to struct v4l2_subdev
It is often useful to have simple means to get from a subdevice to the underlying physical device. This patch adds such a pointer to struct v4l2_subdev and sets it accordingly in the I2C and SPI cases. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- v11: extended a comment drivers/media/v4l2-core/v4l2-common.c |2 ++ include/media/v4l2-subdev.h |2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index 3fed63f..accfec6 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -291,6 +291,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, sd-flags |= V4L2_SUBDEV_FL_IS_I2C; /* the owner is the same as the i2c_client's driver owner */ sd-owner = client-driver-driver.owner; + sd-dev = client-dev; /* i2c_client and v4l2_subdev point to one another */ v4l2_set_subdevdata(sd, client); i2c_set_clientdata(client, sd); @@ -426,6 +427,7 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi, sd-flags |= V4L2_SUBDEV_FL_IS_SPI; /* the owner is the same as the spi_device's driver owner */ sd-owner = spi-dev.driver-owner; + sd-dev = spi-dev; /* spi_device and v4l2_subdev point to one another */ v4l2_set_subdevdata(sd, spi); spi_set_drvdata(spi, sd); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 5298d67..39a37f5 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -585,6 +585,8 @@ struct v4l2_subdev { void *host_priv; /* subdev device node */ struct video_device *devnode; + /* pointer to the physical device, if any */ + struct device *dev; }; #define media_entity_to_v4l2_subdev(ent) \ -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 14/21] V4L2: add temporary clock helpers
Typical video devices like camera sensors require an external clock source. Many such devices cannot even access their hardware registers without a running clock. These clock sources should be controlled by their consumers. This should be performed, using the generic clock framework. Unfortunately so far only very few systems have been ported to that framework. This patch adds a set of temporary helpers, mimicking the generic clock API, to V4L2. Platforms, adopting the clock API, should switch to using it. Eventually this temporary API should be removed. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/v4l2-core/Makefile |2 +- drivers/media/v4l2-core/v4l2-clk.c | 242 include/media/v4l2-clk.h | 54 3 files changed, 297 insertions(+), 1 deletions(-) create mode 100644 drivers/media/v4l2-core/v4l2-clk.c create mode 100644 include/media/v4l2-clk.h diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index aa50c46..628c630 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -5,7 +5,7 @@ tuner-objs := tuner-core.o videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ - v4l2-event.o v4l2-ctrls.o v4l2-subdev.o + v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o ifeq ($(CONFIG_COMPAT),y) videodev-objs += v4l2-compat-ioctl32.o endif diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c new file mode 100644 index 000..b67de86 --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-clk.c @@ -0,0 +1,242 @@ +/* + * V4L2 clock service + * + * Copyright (C) 2012-2013, Guennadi Liakhovetski g.liakhovet...@gmx.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/atomic.h +#include linux/device.h +#include linux/errno.h +#include linux/list.h +#include linux/module.h +#include linux/mutex.h +#include linux/slab.h +#include linux/string.h + +#include media/v4l2-clk.h +#include media/v4l2-subdev.h + +static DEFINE_MUTEX(clk_lock); +static LIST_HEAD(clk_list); + +static struct v4l2_clk *v4l2_clk_find(const char *dev_id, const char *id) +{ + struct v4l2_clk *clk; + + list_for_each_entry(clk, clk_list, list) { + if (strcmp(dev_id, clk-dev_id)) + continue; + + if (!id || !clk-id || !strcmp(clk-id, id)) + return clk; + } + + return ERR_PTR(-ENODEV); +} + +struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) +{ + struct v4l2_clk *clk; + + mutex_lock(clk_lock); + clk = v4l2_clk_find(dev_name(dev), id); + + if (!IS_ERR(clk)) + atomic_inc(clk-use_count); + mutex_unlock(clk_lock); + + return clk; +} +EXPORT_SYMBOL(v4l2_clk_get); + +void v4l2_clk_put(struct v4l2_clk *clk) +{ + struct v4l2_clk *tmp; + + if (IS_ERR(clk)) + return; + + mutex_lock(clk_lock); + + list_for_each_entry(tmp, clk_list, list) + if (tmp == clk) + atomic_dec(clk-use_count); + + mutex_unlock(clk_lock); +} +EXPORT_SYMBOL(v4l2_clk_put); + +static int v4l2_clk_lock_driver(struct v4l2_clk *clk) +{ + struct v4l2_clk *tmp; + int ret = -ENODEV; + + mutex_lock(clk_lock); + + list_for_each_entry(tmp, clk_list, list) + if (tmp == clk) { + ret = !try_module_get(clk-ops-owner); + if (ret) + ret = -EFAULT; + break; + } + + mutex_unlock(clk_lock); + + return ret; +} + +static void v4l2_clk_unlock_driver(struct v4l2_clk *clk) +{ + module_put(clk-ops-owner); +} + +int v4l2_clk_enable(struct v4l2_clk *clk) +{ + int ret = v4l2_clk_lock_driver(clk); + + if (ret 0) + return ret; + + mutex_lock(clk-lock); + + if (++clk-enable == 1 clk-ops-enable) { + ret = clk-ops-enable(clk); + if (ret 0) + clk-enable--; + } + + mutex_unlock(clk-lock); + + return ret; +} +EXPORT_SYMBOL(v4l2_clk_enable); + +/* + * You might Oops if you try to disabled a disabled clock, because then the + * driver isn't locked and could have been unloaded by now, so, don't do that + */ +void v4l2_clk_disable(struct v4l2_clk *clk) +{ + int enable; + + mutex_lock(clk-lock); + + enable = --clk-enable; + if (WARN(enable 0, Unbalanced %s() on %s:%s!\n, __func__, +clk-dev_id, clk-id)) + clk-enable++; + else if (!enable clk-ops-disable) + clk-ops-disable(clk); + + mutex_unlock(clk-lock
[PATCH v11 00/21] V4L2 clock and asynchronous probing
v11 of the V4L2 clock helper and asynchronous probing patch set. Functionally identical to v10, only differences are a couple of comment lines and one renamed struct field - as requested by respectable reviewers :) Only patches #15, 16 and 18 changed. Guennadi Liakhovetski (21): soc-camera: move common code to soc_camera.c soc-camera: add host clock callbacks to start and stop the master clock pxa-camera: move interface activation and deactivation to clock callbacks omap1-camera: move interface activation and deactivation to clock callbacks atmel-isi: move interface activation and deactivation to clock callbacks mx3-camera: move interface activation and deactivation to clock callbacks mx2-camera: move interface activation and deactivation to clock callbacks mx1-camera: move interface activation and deactivation to clock callbacks sh-mobile-ceu-camera: move interface activation and deactivation to clock callbacks soc-camera: make .clock_{start,stop} compulsory, .add / .remove optional soc-camera: don't attach the client to the host during probing sh-mobile-ceu-camera: add primitive OF support sh-mobile-ceu-driver: support max width and height in DT V4L2: add temporary clock helpers V4L2: add a device pointer to struct v4l2_subdev V4L2: support asynchronous subdevice registration soc-camera: switch I2C subdevice drivers to use v4l2-clk soc-camera: add V4L2-async support sh_mobile_ceu_camera: add asynchronous subdevice probing support imx074: support asynchronous probing ARM: shmobile: convert ap4evb to asynchronously register camera subdevices .../devicetree/bindings/media/sh_mobile_ceu.txt| 18 + arch/arm/mach-shmobile/board-ap4evb.c | 103 ++-- arch/arm/mach-shmobile/clock-sh7372.c |1 + drivers/media/i2c/soc_camera/imx074.c | 32 +- drivers/media/i2c/soc_camera/mt9m001.c | 17 +- drivers/media/i2c/soc_camera/mt9m111.c | 20 +- drivers/media/i2c/soc_camera/mt9t031.c | 19 +- drivers/media/i2c/soc_camera/mt9t112.c | 25 +- drivers/media/i2c/soc_camera/mt9v022.c | 17 +- drivers/media/i2c/soc_camera/ov2640.c | 19 +- drivers/media/i2c/soc_camera/ov5642.c | 20 +- drivers/media/i2c/soc_camera/ov6650.c | 17 +- drivers/media/i2c/soc_camera/ov772x.c | 15 +- drivers/media/i2c/soc_camera/ov9640.c | 17 +- drivers/media/i2c/soc_camera/ov9640.h |1 + drivers/media/i2c/soc_camera/ov9740.c | 18 +- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 17 +- drivers/media/i2c/soc_camera/tw9910.c | 24 +- drivers/media/platform/soc_camera/atmel-isi.c | 38 +- drivers/media/platform/soc_camera/mx1_camera.c | 48 +- drivers/media/platform/soc_camera/mx2_camera.c | 41 +- drivers/media/platform/soc_camera/mx3_camera.c | 44 +- drivers/media/platform/soc_camera/omap1_camera.c | 41 +- drivers/media/platform/soc_camera/pxa_camera.c | 46 +- .../platform/soc_camera/sh_mobile_ceu_camera.c | 243 +-- drivers/media/platform/soc_camera/sh_mobile_csi2.c | 153 +++-- drivers/media/platform/soc_camera/soc_camera.c | 707 +--- .../platform/soc_camera/soc_camera_platform.c |2 +- drivers/media/v4l2-core/Makefile |3 +- drivers/media/v4l2-core/v4l2-async.c | 280 drivers/media/v4l2-core/v4l2-clk.c | 242 +++ drivers/media/v4l2-core/v4l2-common.c |2 + include/media/sh_mobile_ceu.h |2 + include/media/sh_mobile_csi2.h |2 +- include/media/soc_camera.h | 39 +- include/media/v4l2-async.h | 105 +++ include/media/v4l2-clk.h | 54 ++ include/media/v4l2-subdev.h| 10 + 38 files changed, 2035 insertions(+), 467 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/sh_mobile_ceu.txt create mode 100644 drivers/media/v4l2-core/v4l2-async.c create mode 100644 drivers/media/v4l2-core/v4l2-clk.c create mode 100644 include/media/v4l2-async.h create mode 100644 include/media/v4l2-clk.h -- 1.7.2.5 Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 20/21] imx074: support asynchronous probing
Both synchronous and asynchronous imx074 subdevice probing is supported by this patch. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/i2c/soc_camera/imx074.c | 20 +--- 1 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index a6a5060..84245e1 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -18,6 +18,7 @@ #include linux/module.h #include media/soc_camera.h +#include media/v4l2-async.h #include media/v4l2-clk.h #include media/v4l2-subdev.h #include media/v4l2-chip-ident.h @@ -456,13 +457,24 @@ static int imx074_probe(struct i2c_client *client, priv-fmt = imx074_colour_fmts[0]; priv-clk = v4l2_clk_get(client-dev, mclk); - if (IS_ERR(priv-clk)) - return PTR_ERR(priv-clk); + if (IS_ERR(priv-clk)) { + dev_info(client-dev, Error %ld getting clock\n, PTR_ERR(priv-clk)); + return -EPROBE_DEFER; + } + + ret = soc_camera_power_init(client-dev, ssdd); + if (ret 0) + goto epwrinit; ret = imx074_video_probe(client); if (ret 0) - v4l2_clk_put(priv-clk); + goto eprobe; + return v4l2_async_register_subdev(priv-subdev); + +epwrinit: +eprobe: + v4l2_clk_put(priv-clk); return ret; } @@ -471,7 +483,9 @@ static int imx074_remove(struct i2c_client *client) struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct imx074 *priv = to_imx074(client); + v4l2_async_unregister_subdev(priv-subdev); v4l2_clk_put(priv-clk); + if (ssdd-free_bus) ssdd-free_bus(ssdd); -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 18/21] soc-camera: add V4L2-async support
Add support for asynchronous subdevice probing, using the v4l2-async API. The legacy synchronous mode is still supported too, which allows to gradually update drivers and platforms. The selected approach adds a notifier for each struct soc_camera_device instance, i.e. for each video device node, even when there are multiple such instances registered with a single soc-camera host simultaneously. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- v11: adapted to the changed field name from patch #16 drivers/media/platform/soc_camera/soc_camera.c | 527 include/media/soc_camera.h | 23 +- 2 files changed, 464 insertions(+), 86 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 5845916..524d0e9 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -21,22 +21,23 @@ #include linux/i2c.h #include linux/init.h #include linux/list.h -#include linux/mutex.h #include linux/module.h +#include linux/mutex.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/regulator/consumer.h #include linux/slab.h -#include linux/pm_runtime.h #include linux/vmalloc.h #include media/soc_camera.h +#include media/soc_mediabus.h +#include media/v4l2-async.h #include media/v4l2-clk.h #include media/v4l2-common.h #include media/v4l2-ioctl.h #include media/v4l2-dev.h #include media/videobuf-core.h #include media/videobuf2-core.h -#include media/soc_mediabus.h /* Default to VGA resolution */ #define DEFAULT_WIDTH 640 @@ -47,23 +48,39 @@ (icd)-vb_vidq.streaming : \ vb2_is_streaming((icd)-vb2_vidq)) +#define MAP_MAX_NUM 32 +static DECLARE_BITMAP(device_map, MAP_MAX_NUM); static LIST_HEAD(hosts); static LIST_HEAD(devices); -static DEFINE_MUTEX(list_lock);/* Protects the list of hosts */ +/* + * Protects lists and bitmaps of hosts and devices. + * Lock nesting: Ok to take -host_lock under list_lock. + */ +static DEFINE_MUTEX(list_lock); + +struct soc_camera_async_client { + struct v4l2_async_subdev *sensor; + struct v4l2_async_notifier notifier; + struct platform_device *pdev; + struct list_head list; /* needed for clean up */ +}; + +static int soc_camera_video_start(struct soc_camera_device *icd); +static int video_dev_create(struct soc_camera_device *icd); int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd, struct v4l2_clk *clk) { int ret = clk ? v4l2_clk_enable(clk) : 0; if (ret 0) { - dev_err(dev, Cannot enable clock\n); + dev_err(dev, Cannot enable clock: %d\n, ret); return ret; } ret = regulator_bulk_enable(ssdd-num_regulators, ssdd-regulators); if (ret 0) { dev_err(dev, Cannot enable regulators\n); - goto eregenable;; + goto eregenable; } if (ssdd-power) { @@ -117,6 +134,14 @@ int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd } EXPORT_SYMBOL(soc_camera_power_off); +int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd) +{ + + return devm_regulator_bulk_get(dev, ssdd-num_regulators, + ssdd-regulators); +} +EXPORT_SYMBOL(soc_camera_power_init); + static int __soc_camera_power_on(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); @@ -533,7 +558,9 @@ static int soc_camera_add_device(struct soc_camera_device *icd) return -EBUSY; if (!icd-clk) { + mutex_lock(ici-clk_lock); ret = ici-ops-clock_start(ici); + mutex_unlock(ici-clk_lock); if (ret 0) return ret; } @@ -549,8 +576,11 @@ static int soc_camera_add_device(struct soc_camera_device *icd) return 0; eadd: - if (!icd-clk) + if (!icd-clk) { + mutex_lock(ici-clk_lock); ici-ops-clock_stop(ici); + mutex_unlock(ici-clk_lock); + } return ret; } @@ -563,8 +593,11 @@ static void soc_camera_remove_device(struct soc_camera_device *icd) if (ici-ops-remove) ici-ops-remove(icd); - if (!icd-clk) + if (!icd-clk) { + mutex_lock(ici-clk_lock); ici-ops-clock_stop(ici); + mutex_unlock(ici-clk_lock); + } ici-icd = NULL; } @@ -673,8 +706,8 @@ static int soc_camera_open(struct file *file) return 0; /* -* First four errors are entered with the .host_lock held -* and use_count == 1 +* All errors are entered with the .host_lock held, first four also
Re: [PATCH v11 00/21] V4L2 clock and asynchronous probing
Hi Laurent On Fri, 14 Jun 2013, Laurent Pinchart wrote: Hi Guennadi, Thank you for the patches. On Friday 14 June 2013 21:08:10 Guennadi Liakhovetski wrote: v11 of the V4L2 clock helper and asynchronous probing patch set. Functionally identical to v10, only differences are a couple of comment lines and one renamed struct field - as requested by respectable reviewers :) Only patches #15, 16 and 18 changed. [snip] .../devicetree/bindings/media/sh_mobile_ceu.txt| 18 + Documentation/video4linux/v4l2-framework.txt is missing :-) I know. I will add it as soon as these patches are in. Thanks Guennadi arch/arm/mach-shmobile/board-ap4evb.c | 103 ++-- arch/arm/mach-shmobile/clock-sh7372.c |1 + drivers/media/i2c/soc_camera/imx074.c | 32 +- drivers/media/i2c/soc_camera/mt9m001.c | 17 +- drivers/media/i2c/soc_camera/mt9m111.c | 20 +- drivers/media/i2c/soc_camera/mt9t031.c | 19 +- drivers/media/i2c/soc_camera/mt9t112.c | 25 +- drivers/media/i2c/soc_camera/mt9v022.c | 17 +- drivers/media/i2c/soc_camera/ov2640.c | 19 +- drivers/media/i2c/soc_camera/ov5642.c | 20 +- drivers/media/i2c/soc_camera/ov6650.c | 17 +- drivers/media/i2c/soc_camera/ov772x.c | 15 +- drivers/media/i2c/soc_camera/ov9640.c | 17 +- drivers/media/i2c/soc_camera/ov9640.h |1 + drivers/media/i2c/soc_camera/ov9740.c | 18 +- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 17 +- drivers/media/i2c/soc_camera/tw9910.c | 24 +- drivers/media/platform/soc_camera/atmel-isi.c | 38 +- drivers/media/platform/soc_camera/mx1_camera.c | 48 +- drivers/media/platform/soc_camera/mx2_camera.c | 41 +- drivers/media/platform/soc_camera/mx3_camera.c | 44 +- drivers/media/platform/soc_camera/omap1_camera.c | 41 +- drivers/media/platform/soc_camera/pxa_camera.c | 46 +- .../platform/soc_camera/sh_mobile_ceu_camera.c | 243 +-- drivers/media/platform/soc_camera/sh_mobile_csi2.c | 153 +++-- drivers/media/platform/soc_camera/soc_camera.c | 707 ++--- .../platform/soc_camera/soc_camera_platform.c |2 +- drivers/media/v4l2-core/Makefile |3 +- drivers/media/v4l2-core/v4l2-async.c | 280 drivers/media/v4l2-core/v4l2-clk.c | 242 +++ drivers/media/v4l2-core/v4l2-common.c |2 + include/media/sh_mobile_ceu.h |2 + include/media/sh_mobile_csi2.h |2 +- include/media/soc_camera.h | 39 +- include/media/v4l2-async.h | 105 +++ include/media/v4l2-clk.h | 54 ++ include/media/v4l2-subdev.h| 10 + 38 files changed, 2035 insertions(+), 467 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/sh_mobile_ceu.txt create mode 100644 drivers/media/v4l2-core/v4l2-async.c create mode 100644 drivers/media/v4l2-core/v4l2-clk.c create mode 100644 include/media/v4l2-async.h create mode 100644 include/media/v4l2-clk.h -- Regards, Laurent Pinchart --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6] V4L2: soc_camera: Renesas R-Car VIN driver
V4L2_MBUS_FMT_YUYV8_1X16: + case V4L2_MBUS_FMT_YUYV8_2X8: + if (cam-extra_fmt) + break; + + /* Add all our formats that can be generated by VIN */ + cam-extra_fmt = rcar_vin_formats; + + n = ARRAY_SIZE(rcar_vin_formats); + formats += n; + for (k = 0; xlate k n; k++, xlate++) { + xlate-host_fmt = rcar_vin_formats[k]; + xlate-code = code; + dev_dbg(dev, Providing format %s using code %d\n, + rcar_vin_formats[k].name, code); + } + break; + default: + if (!rcar_vin_packing_supported(fmt)) + return 0; + + dev_dbg(dev, Providing format %s in pass-through mode\n, + fmt-name); + break; Ok, you added pass-through... + } + + /* Generic pass-through */ + formats++; + if (xlate) { + xlate-host_fmt = fmt; + xlate-code = code; + xlate++; + } + + return formats; +} [snip] +/* Similar to set_crop multistage iterative algorithm */ +static int rcar_vin_set_fmt(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd-parent); + struct rcar_vin_priv *priv = ici-priv; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct rcar_vin_cam *cam = icd-host_priv; + struct v4l2_pix_format *pix = f-fmt.pix; + struct v4l2_mbus_framefmt mf; + struct device *dev = icd-parent; + __u32 pixfmt = pix-pixelformat; + const struct soc_camera_format_xlate *xlate; + unsigned int vin_sub_width = 0, vin_sub_height = 0; + int ret; + bool can_scale; + enum v4l2_field field; + v4l2_std_id std; + + dev_dbg(dev, S_FMT(pix=0x%x, %ux%u)\n, + pixfmt, pix-width, pix-height); + + switch (pix-field) { + default: + pix-field = V4L2_FIELD_NONE; + /* fall-through */ + case V4L2_FIELD_NONE: + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_INTERLACED_TB: + case V4L2_FIELD_INTERLACED_BT: + field = pix-field; + break; + case V4L2_FIELD_INTERLACED: + /* Query for standard if not explicitly mentioned _TB/_BT */ + ret = v4l2_subdev_call(sd, video, querystd, std); + if (ret 0) + std = V4L2_STD_625_50; + + field = std V4L2_STD_625_50 ? V4L2_FIELD_INTERLACED_TB : + V4L2_FIELD_INTERLACED_BT; + break; + } + + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_warn(dev, Format %x not found\n, pixfmt); + return -EINVAL; + } + /* Calculate client output geometry */ + soc_camera_calc_client_output(icd, cam-rect, cam-subrect, pix, mf, 12); + mf.field = pix-field; + mf.colorspace = pix-colorspace; + mf.code = xlate-code; + + switch (pixfmt) { + case V4L2_PIX_FMT_NV16: + can_scale = false; + break; + case V4L2_PIX_FMT_RGB32: + can_scale = priv-chip != RCAR_E1; + break; + default: + can_scale = true; You also get here in the pass-through mode, right? I don't think you can scale then. + break; + } + + dev_dbg(dev, request camera output %ux%u\n, mf.width, mf.height); + + ret = soc_camera_client_scale(icd, cam-rect, cam-subrect, + mf, vin_sub_width, vin_sub_height, + can_scale, 12); + + /* Done with the camera. Now see if we can improve the result */ + dev_dbg(dev, Camera %d fmt %ux%u, requested %ux%u\n, + ret, mf.width, mf.height, pix-width, pix-height); + + if (ret 0) + dev_dbg(dev, Sensor doesn't support cropping\n); Are you sure this print is correct? Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 10/21] soc-camera: make .clock_{start,stop} compulsory, .add / .remove optional
All existing soc-camera host drivers use .clock_start() and .clock_stop() callbacks to activate and deactivate their camera interfaces, whereas .add() and .remove() callbacks are usually dummy. Make the former two compulsory and the latter two optional. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/soc_camera.c | 27 +++ 1 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index df90565..e503f03 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -513,23 +513,22 @@ static int soc_camera_add_device(struct soc_camera_device *icd) if (ici-icd) return -EBUSY; - if (ici-ops-clock_start) { - ret = ici-ops-clock_start(ici); + ret = ici-ops-clock_start(ici); + if (ret 0) + return ret; + + if (ici-ops-add) { + ret = ici-ops-add(icd); if (ret 0) - return ret; + goto eadd; } - ret = ici-ops-add(icd); - if (ret 0) - goto eadd; - ici-icd = icd; return 0; eadd: - if (ici-ops-clock_stop) - ici-ops-clock_stop(ici); + ici-ops-clock_stop(ici); return ret; } @@ -540,9 +539,9 @@ static void soc_camera_remove_device(struct soc_camera_device *icd) if (WARN_ON(icd != ici-icd)) return; - ici-ops-remove(icd); - if (ici-ops-clock_stop) - ici-ops-clock_stop(ici); + if (ici-ops-remove) + ici-ops-remove(icd); + ici-ops-clock_stop(ici); ici-icd = NULL; } @@ -1413,8 +1412,8 @@ int soc_camera_host_register(struct soc_camera_host *ici) ((!ici-ops-init_videobuf || !ici-ops-reqbufs) !ici-ops-init_videobuf2) || - !ici-ops-add || - !ici-ops-remove || + !ici-ops-clock_start || + !ici-ops-clock_stop || !ici-ops-poll || !ici-v4l2_dev.dev) return -EINVAL; -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 08/21] mx1-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the mx1-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/mx1_camera.c | 32 +++- 1 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c index 5f9ec8e..fea3e61 100644 --- a/drivers/media/platform/soc_camera/mx1_camera.c +++ b/drivers/media/platform/soc_camera/mx1_camera.c @@ -399,7 +399,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) { unsigned int csicr1 = CSICR1_EN; - dev_dbg(pcdev-soc_host.icd-parent, Activate device\n); + dev_dbg(pcdev-soc_host.v4l2_dev.dev, Activate device\n); clk_prepare_enable(pcdev-clk); @@ -415,7 +415,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) { - dev_dbg(pcdev-soc_host.icd-parent, Deactivate device\n); + dev_dbg(pcdev-soc_host.v4l2_dev.dev, Deactivate device\n); /* Disable all CSI interface */ __raw_writel(0x00, pcdev-base + CSICR1); @@ -423,26 +423,35 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) clk_disable_unprepare(pcdev-clk); } +static int mx1_camera_add_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, MX1 Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void mx1_camera_remove_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, MX1 Camera driver detached from camera %d\n, +icd-devnum); +} + /* * The following two functions absolutely depend on the fact, that * there can be only one camera on i.MX1/i.MXL camera sensor interface */ -static int mx1_camera_add_device(struct soc_camera_device *icd) +static int mx1_camera_clock_start(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx1_camera_dev *pcdev = ici-priv; - dev_info(icd-parent, MX1 Camera driver attached to camera %d\n, -icd-devnum); - mx1_camera_activate(pcdev); return 0; } -static void mx1_camera_remove_device(struct soc_camera_device *icd) +static void mx1_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx1_camera_dev *pcdev = ici-priv; unsigned int csicr1; @@ -453,9 +462,6 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd) /* Stop DMA engine */ imx_dma_disable(pcdev-dma_chan); - dev_info(icd-parent, MX1 Camera driver detached from camera %d\n, -icd-devnum); - mx1_camera_deactivate(pcdev); } @@ -669,6 +675,8 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = { .owner = THIS_MODULE, .add= mx1_camera_add_device, .remove = mx1_camera_remove_device, + .clock_start= mx1_camera_clock_start, + .clock_stop = mx1_camera_clock_stop, .set_bus_param = mx1_camera_set_bus_param, .set_fmt= mx1_camera_set_fmt, .try_fmt= mx1_camera_try_fmt, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 07/21] mx2-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the mx2-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/mx2_camera.c | 28 +++ 1 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index 772e071..45a0276 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -412,13 +412,26 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) writel(0, pcdev-base_emma + PRP_CNTL); } +static int mx2_camera_add_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void mx2_camera_remove_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, Camera driver detached from camera %d\n, +icd-devnum); +} + /* * The following two functions absolutely depend on the fact, that * there can be only one camera on mx2 camera sensor interface */ -static int mx2_camera_add_device(struct soc_camera_device *icd) +static int mx2_camera_clock_start(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx2_camera_dev *pcdev = ici-priv; int ret; u32 csicr1; @@ -439,9 +452,6 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) pcdev-frame_count = 0; - dev_info(icd-parent, Camera driver attached to camera %d\n, -icd-devnum); - return 0; exit_csi_ahb: @@ -450,14 +460,10 @@ exit_csi_ahb: return ret; } -static void mx2_camera_remove_device(struct soc_camera_device *icd) +static void mx2_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx2_camera_dev *pcdev = ici-priv; - dev_info(icd-parent, Camera driver detached from camera %d\n, -icd-devnum); - mx2_camera_deactivate(pcdev); } @@ -1271,6 +1277,8 @@ static struct soc_camera_host_ops mx2_soc_camera_host_ops = { .owner = THIS_MODULE, .add= mx2_camera_add_device, .remove = mx2_camera_remove_device, + .clock_start= mx2_camera_clock_start, + .clock_stop = mx2_camera_clock_stop, .set_fmt= mx2_camera_set_fmt, .set_crop = mx2_camera_set_crop, .get_formats= mx2_camera_get_formats, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 17/21] soc-camera: switch I2C subdevice drivers to use v4l2-clk
Instead of centrally enabling and disabling subdevice master clocks in soc-camera core, let subdevice drivers do that themselves, using the V4L2 clock API and soc-camera convenience wrappers. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/i2c/soc_camera/imx074.c | 18 ++- drivers/media/i2c/soc_camera/mt9m001.c | 17 ++- drivers/media/i2c/soc_camera/mt9m111.c | 20 ++- drivers/media/i2c/soc_camera/mt9t031.c | 19 ++- drivers/media/i2c/soc_camera/mt9t112.c | 25 +++- drivers/media/i2c/soc_camera/mt9v022.c | 17 ++- drivers/media/i2c/soc_camera/ov2640.c | 19 ++- drivers/media/i2c/soc_camera/ov5642.c | 20 ++- drivers/media/i2c/soc_camera/ov6650.c | 17 ++- drivers/media/i2c/soc_camera/ov772x.c | 15 ++- drivers/media/i2c/soc_camera/ov9640.c | 17 ++- drivers/media/i2c/soc_camera/ov9640.h |1 + drivers/media/i2c/soc_camera/ov9740.c | 18 ++- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 17 ++- drivers/media/i2c/soc_camera/tw9910.c | 24 +++- drivers/media/platform/soc_camera/soc_camera.c | 162 +++- .../platform/soc_camera/soc_camera_platform.c |2 +- include/media/soc_camera.h | 13 +- 18 files changed, 362 insertions(+), 79 deletions(-) diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index a2a5cbb..a6a5060 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -18,6 +18,7 @@ #include linux/module.h #include media/soc_camera.h +#include media/v4l2-clk.h #include media/v4l2-subdev.h #include media/v4l2-chip-ident.h @@ -77,6 +78,7 @@ struct imx074_datafmt { struct imx074 { struct v4l2_subdev subdev; const struct imx074_datafmt *fmt; + struct v4l2_clk *clk; }; static const struct imx074_datafmt imx074_colour_fmts[] = { @@ -272,8 +274,9 @@ static int imx074_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct imx074 *priv = to_imx074(client); - return soc_camera_set_power(client-dev, ssdd, on); + return soc_camera_set_power(client-dev, ssdd, priv-clk, on); } static int imx074_g_mbus_config(struct v4l2_subdev *sd, @@ -431,6 +434,7 @@ static int imx074_probe(struct i2c_client *client, struct imx074 *priv; struct i2c_adapter *adapter = to_i2c_adapter(client-dev.parent); struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + int ret; if (!ssdd) { dev_err(client-dev, IMX074: missing platform data!\n); @@ -451,13 +455,23 @@ static int imx074_probe(struct i2c_client *client, priv-fmt = imx074_colour_fmts[0]; - return imx074_video_probe(client); + priv-clk = v4l2_clk_get(client-dev, mclk); + if (IS_ERR(priv-clk)) + return PTR_ERR(priv-clk); + + ret = imx074_video_probe(client); + if (ret 0) + v4l2_clk_put(priv-clk); + + return ret; } static int imx074_remove(struct i2c_client *client) { struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct imx074 *priv = to_imx074(client); + v4l2_clk_put(priv-clk); if (ssdd-free_bus) ssdd-free_bus(ssdd); diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c index dd90898..620f9df 100644 --- a/drivers/media/i2c/soc_camera/mt9m001.c +++ b/drivers/media/i2c/soc_camera/mt9m001.c @@ -16,6 +16,7 @@ #include media/soc_camera.h #include media/soc_mediabus.h +#include media/v4l2-clk.h #include media/v4l2-subdev.h #include media/v4l2-chip-ident.h #include media/v4l2-ctrls.h @@ -94,6 +95,7 @@ struct mt9m001 { struct v4l2_ctrl *exposure; }; struct v4l2_rect rect; /* Sensor window */ + struct v4l2_clk *clk; const struct mt9m001_datafmt *fmt; const struct mt9m001_datafmt *fmts; int num_fmts; @@ -381,8 +383,9 @@ static int mt9m001_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct mt9m001 *mt9m001 = to_mt9m001(client); - return soc_camera_set_power(client-dev, ssdd, on); + return soc_camera_set_power(client-dev, ssdd, mt9m001-clk, on); } static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl) @@ -710,9 +713,18 @@ static int mt9m001_probe(struct i2c_client *client, mt9m001-rect.width = MT9M001_MAX_WIDTH; mt9m001-rect.height= MT9M001_MAX_HEIGHT; + mt9m001-clk
[PATCH v10 00/21] V4L2 clock and asynchronous probing
3.11 is approaching... Here comes v10 of the V4L2 clock helper and asynchronous probing patch set. In this series I included 3 groups of patches, that actually aren't that strongly related. 1. patches 1-11 split soc-camera subdevice linking procedure into two steps: (a) turning on the master clock and (b) actually linking a (client) subdevice to a host. This is necessary to keep the V4L2 clock API free from any device context. 2. patches 12-13 are adding device tree support to the sh_mobile_ceu_camera soc-camera host driver. They aren't really related, but following V4L2 async support for this driver has been developed on top of this code, so, I would prefer to keep the order. 3. patches 14-21 are the actual clock and async probing code. They contain core support and an example conversion of the soc-camera framework and one its platform (an AP4EVB board) to the new APIs. Thanks for all the reviews and suggestions. Guennadi Liakhovetski (21): soc-camera: move common code to soc_camera.c soc-camera: add host clock callbacks to start and stop the master clock pxa-camera: move interface activation and deactivation to clock callbacks omap1-camera: move interface activation and deactivation to clock callbacks atmel-isi: move interface activation and deactivation to clock callbacks mx3-camera: move interface activation and deactivation to clock callbacks mx2-camera: move interface activation and deactivation to clock callbacks mx1-camera: move interface activation and deactivation to clock callbacks sh-mobile-ceu-camera: move interface activation and deactivation to clock callbacks soc-camera: make .clock_{start,stop} compulsory, .add / .remove optional soc-camera: don't attach the client to the host during probing sh-mobile-ceu-camera: add primitive OF support sh-mobile-ceu-driver: support max width and height in DT V4L2: add temporary clock helpers V4L2: add a device pointer to struct v4l2_subdev V4L2: support asynchronous subdevice registration soc-camera: switch I2C subdevice drivers to use v4l2-clk soc-camera: add V4L2-async support sh_mobile_ceu_camera: add asynchronous subdevice probing support imx074: support asynchronous probing ARM: shmobile: convert ap4evb to asynchronously register camera subdevices .../devicetree/bindings/media/sh_mobile_ceu.txt| 18 + arch/arm/mach-shmobile/board-ap4evb.c | 103 ++-- arch/arm/mach-shmobile/clock-sh7372.c |1 + drivers/media/i2c/soc_camera/imx074.c | 32 +- drivers/media/i2c/soc_camera/mt9m001.c | 17 +- drivers/media/i2c/soc_camera/mt9m111.c | 20 +- drivers/media/i2c/soc_camera/mt9t031.c | 19 +- drivers/media/i2c/soc_camera/mt9t112.c | 25 +- drivers/media/i2c/soc_camera/mt9v022.c | 17 +- drivers/media/i2c/soc_camera/ov2640.c | 19 +- drivers/media/i2c/soc_camera/ov5642.c | 20 +- drivers/media/i2c/soc_camera/ov6650.c | 17 +- drivers/media/i2c/soc_camera/ov772x.c | 15 +- drivers/media/i2c/soc_camera/ov9640.c | 17 +- drivers/media/i2c/soc_camera/ov9640.h |1 + drivers/media/i2c/soc_camera/ov9740.c | 18 +- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 17 +- drivers/media/i2c/soc_camera/tw9910.c | 24 +- drivers/media/platform/soc_camera/atmel-isi.c | 38 +- drivers/media/platform/soc_camera/mx1_camera.c | 48 +- drivers/media/platform/soc_camera/mx2_camera.c | 41 +- drivers/media/platform/soc_camera/mx3_camera.c | 44 +- drivers/media/platform/soc_camera/omap1_camera.c | 41 +- drivers/media/platform/soc_camera/pxa_camera.c | 46 +- .../platform/soc_camera/sh_mobile_ceu_camera.c | 243 +-- drivers/media/platform/soc_camera/sh_mobile_csi2.c | 153 +++-- drivers/media/platform/soc_camera/soc_camera.c | 707 +--- .../platform/soc_camera/soc_camera_platform.c |2 +- drivers/media/v4l2-core/Makefile |3 +- drivers/media/v4l2-core/v4l2-async.c | 280 drivers/media/v4l2-core/v4l2-clk.c | 242 +++ drivers/media/v4l2-core/v4l2-common.c |2 + include/media/sh_mobile_ceu.h |2 + include/media/sh_mobile_csi2.h |2 +- include/media/soc_camera.h | 39 +- include/media/v4l2-async.h | 105 +++ include/media/v4l2-clk.h | 54 ++ include/media/v4l2-subdev.h| 10 + 38 files changed, 2035 insertions(+), 467 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/sh_mobile_ceu.txt create mode 100644 drivers/media/v4l2-core/v4l2-async.c create mode 100644 drivers/media/v4l2-core/v4l2-clk.c create mode 100644
[PATCH v10 02/21] soc-camera: add host clock callbacks to start and stop the master clock
Currently soc-camera uses a single camera host callback to activate the interface master clock and to configure the interface for a specific client. However, during probing we might not have the information about a client, we just need to activate the clock. Add new camera host driver callbacks to only start and stop the clock without and client-specific configuration. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/soc_camera.c | 19 +-- include/media/soc_camera.h |2 ++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 832f059..df90565 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -513,10 +513,23 @@ static int soc_camera_add_device(struct soc_camera_device *icd) if (ici-icd) return -EBUSY; + if (ici-ops-clock_start) { + ret = ici-ops-clock_start(ici); + if (ret 0) + return ret; + } + ret = ici-ops-add(icd); - if (!ret) - ici-icd = icd; + if (ret 0) + goto eadd; + + ici-icd = icd; + return 0; + +eadd: + if (ici-ops-clock_stop) + ici-ops-clock_stop(ici); return ret; } @@ -528,6 +541,8 @@ static void soc_camera_remove_device(struct soc_camera_device *icd) return; ici-ops-remove(icd); + if (ici-ops-clock_stop) + ici-ops-clock_stop(ici); ici-icd = NULL; } diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 5a46ce2..64415ee 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -74,6 +74,8 @@ struct soc_camera_host_ops { struct module *owner; int (*add)(struct soc_camera_device *); void (*remove)(struct soc_camera_device *); + int (*clock_start)(struct soc_camera_host *); + void (*clock_stop)(struct soc_camera_host *); /* * .get_formats() is called for each client device format, but * .put_formats() is only called once. Further, if any of the calls to -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 18/21] soc-camera: add V4L2-async support
Add support for asynchronous subdevice probing, using the v4l2-async API. The legacy synchronous mode is still supported too, which allows to gradually update drivers and platforms. The selected approach adds a notifier for each struct soc_camera_device instance, i.e. for each video device node, even when there are multiple such instances registered with a single soc-camera host simultaneously. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/soc_camera.c | 527 include/media/soc_camera.h | 23 +- 2 files changed, 464 insertions(+), 86 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 5845916..725e49d 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -21,22 +21,23 @@ #include linux/i2c.h #include linux/init.h #include linux/list.h -#include linux/mutex.h #include linux/module.h +#include linux/mutex.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/regulator/consumer.h #include linux/slab.h -#include linux/pm_runtime.h #include linux/vmalloc.h #include media/soc_camera.h +#include media/soc_mediabus.h +#include media/v4l2-async.h #include media/v4l2-clk.h #include media/v4l2-common.h #include media/v4l2-ioctl.h #include media/v4l2-dev.h #include media/videobuf-core.h #include media/videobuf2-core.h -#include media/soc_mediabus.h /* Default to VGA resolution */ #define DEFAULT_WIDTH 640 @@ -47,23 +48,39 @@ (icd)-vb_vidq.streaming : \ vb2_is_streaming((icd)-vb2_vidq)) +#define MAP_MAX_NUM 32 +static DECLARE_BITMAP(device_map, MAP_MAX_NUM); static LIST_HEAD(hosts); static LIST_HEAD(devices); -static DEFINE_MUTEX(list_lock);/* Protects the list of hosts */ +/* + * Protects lists and bitmaps of hosts and devices. + * Lock nesting: Ok to take -host_lock under list_lock. + */ +static DEFINE_MUTEX(list_lock); + +struct soc_camera_async_client { + struct v4l2_async_subdev *sensor; + struct v4l2_async_notifier notifier; + struct platform_device *pdev; + struct list_head list; /* needed for clean up */ +}; + +static int soc_camera_video_start(struct soc_camera_device *icd); +static int video_dev_create(struct soc_camera_device *icd); int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd, struct v4l2_clk *clk) { int ret = clk ? v4l2_clk_enable(clk) : 0; if (ret 0) { - dev_err(dev, Cannot enable clock\n); + dev_err(dev, Cannot enable clock: %d\n, ret); return ret; } ret = regulator_bulk_enable(ssdd-num_regulators, ssdd-regulators); if (ret 0) { dev_err(dev, Cannot enable regulators\n); - goto eregenable;; + goto eregenable; } if (ssdd-power) { @@ -117,6 +134,14 @@ int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd } EXPORT_SYMBOL(soc_camera_power_off); +int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd) +{ + + return devm_regulator_bulk_get(dev, ssdd-num_regulators, + ssdd-regulators); +} +EXPORT_SYMBOL(soc_camera_power_init); + static int __soc_camera_power_on(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); @@ -533,7 +558,9 @@ static int soc_camera_add_device(struct soc_camera_device *icd) return -EBUSY; if (!icd-clk) { + mutex_lock(ici-clk_lock); ret = ici-ops-clock_start(ici); + mutex_unlock(ici-clk_lock); if (ret 0) return ret; } @@ -549,8 +576,11 @@ static int soc_camera_add_device(struct soc_camera_device *icd) return 0; eadd: - if (!icd-clk) + if (!icd-clk) { + mutex_lock(ici-clk_lock); ici-ops-clock_stop(ici); + mutex_unlock(ici-clk_lock); + } return ret; } @@ -563,8 +593,11 @@ static void soc_camera_remove_device(struct soc_camera_device *icd) if (ici-ops-remove) ici-ops-remove(icd); - if (!icd-clk) + if (!icd-clk) { + mutex_lock(ici-clk_lock); ici-ops-clock_stop(ici); + mutex_unlock(ici-clk_lock); + } ici-icd = NULL; } @@ -673,8 +706,8 @@ static int soc_camera_open(struct file *file) return 0; /* -* First four errors are entered with the .host_lock held -* and use_count == 1 +* All errors are entered with the .host_lock held, first four also +* with use_count == 1 */ einitvb
[PATCH v10 11/21] soc-camera: don't attach the client to the host during probing
During client probing we only have to turn on the host's clock, no need to actually attach the client to the host. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/soc_camera.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index e503f03..ac98bcb 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1207,7 +1207,7 @@ static int soc_camera_probe(struct soc_camera_device *icd) ssdd-reset(icd-pdev); mutex_lock(ici-host_lock); - ret = soc_camera_add_device(icd); + ret = ici-ops-clock_start(ici); mutex_unlock(ici-host_lock); if (ret 0) goto eadd; @@ -1280,7 +1280,7 @@ static int soc_camera_probe(struct soc_camera_device *icd) icd-field = mf.field; } - soc_camera_remove_device(icd); + ici-ops-clock_stop(ici); mutex_unlock(ici-host_lock); @@ -1303,7 +1303,7 @@ eadddev: icd-vdev = NULL; evdc: mutex_lock(ici-host_lock); - soc_camera_remove_device(icd); + ici-ops-clock_stop(ici); mutex_unlock(ici-host_lock); eadd: v4l2_ctrl_handler_free(icd-ctrl_handler); -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 04/21] omap1-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the omap1-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/omap1_camera.c | 27 ++--- 1 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index c42c23e..6769193 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -893,13 +893,26 @@ static void sensor_reset(struct omap1_cam_dev *pcdev, bool reset) CAM_WRITE(pcdev, GPIO, !reset); } +static int omap1_cam_add_device(struct soc_camera_device *icd) +{ + dev_dbg(icd-parent, OMAP1 Camera driver attached to camera %d\n, + icd-devnum); + + return 0; +} + +static void omap1_cam_remove_device(struct soc_camera_device *icd) +{ + dev_dbg(icd-parent, + OMAP1 Camera driver detached from camera %d\n, icd-devnum); +} + /* * The following two functions absolutely depend on the fact, that * there can be only one camera on OMAP1 camera sensor interface */ -static int omap1_cam_add_device(struct soc_camera_device *icd) +static int omap1_cam_clock_start(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct omap1_cam_dev *pcdev = ici-priv; u32 ctrlclock; @@ -937,14 +950,11 @@ static int omap1_cam_add_device(struct soc_camera_device *icd) sensor_reset(pcdev, false); - dev_dbg(icd-parent, OMAP1 Camera driver attached to camera %d\n, - icd-devnum); return 0; } -static void omap1_cam_remove_device(struct soc_camera_device *icd) +static void omap1_cam_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct omap1_cam_dev *pcdev = ici-priv; u32 ctrlclock; @@ -965,9 +975,6 @@ static void omap1_cam_remove_device(struct soc_camera_device *icd) CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock ~MCLK_EN); clk_disable(pcdev-clk); - - dev_dbg(icd-parent, - OMAP1 Camera driver detached from camera %d\n, icd-devnum); } /* Duplicate standard formats based on host capability of byte swapping */ @@ -1525,6 +1532,8 @@ static struct soc_camera_host_ops omap1_host_ops = { .owner = THIS_MODULE, .add= omap1_cam_add_device, .remove = omap1_cam_remove_device, + .clock_start= omap1_cam_clock_start, + .clock_stop = omap1_cam_clock_stop, .get_formats= omap1_cam_get_formats, .set_crop = omap1_cam_set_crop, .set_fmt= omap1_cam_set_fmt, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 20/21] imx074: support asynchronous probing
Both synchronous and asynchronous imx074 subdevice probing is supported by this patch. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/i2c/soc_camera/imx074.c | 20 +--- 1 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index a6a5060..84245e1 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -18,6 +18,7 @@ #include linux/module.h #include media/soc_camera.h +#include media/v4l2-async.h #include media/v4l2-clk.h #include media/v4l2-subdev.h #include media/v4l2-chip-ident.h @@ -456,13 +457,24 @@ static int imx074_probe(struct i2c_client *client, priv-fmt = imx074_colour_fmts[0]; priv-clk = v4l2_clk_get(client-dev, mclk); - if (IS_ERR(priv-clk)) - return PTR_ERR(priv-clk); + if (IS_ERR(priv-clk)) { + dev_info(client-dev, Error %ld getting clock\n, PTR_ERR(priv-clk)); + return -EPROBE_DEFER; + } + + ret = soc_camera_power_init(client-dev, ssdd); + if (ret 0) + goto epwrinit; ret = imx074_video_probe(client); if (ret 0) - v4l2_clk_put(priv-clk); + goto eprobe; + return v4l2_async_register_subdev(priv-subdev); + +epwrinit: +eprobe: + v4l2_clk_put(priv-clk); return ret; } @@ -471,7 +483,9 @@ static int imx074_remove(struct i2c_client *client) struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct imx074 *priv = to_imx074(client); + v4l2_async_unregister_subdev(priv-subdev); v4l2_clk_put(priv-clk); + if (ssdd-free_bus) ssdd-free_bus(ssdd); -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 12/21] sh-mobile-ceu-camera: add primitive OF support
Add an OF hook to sh_mobile_ceu_camera.c, no properties so far. Booting with DT also requires platform data to be optional. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- .../platform/soc_camera/sh_mobile_ceu_camera.c | 33 ++-- 1 files changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 9037472..fcc13d8 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -27,6 +27,7 @@ #include linux/kernel.h #include linux/mm.h #include linux/moduleparam.h +#include linux/of.h #include linux/time.h #include linux/slab.h #include linux/device.h @@ -118,6 +119,7 @@ struct sh_mobile_ceu_dev { enum v4l2_field field; int sequence; + unsigned long flags; unsigned int image_mode:1; unsigned int is_16bit:1; @@ -706,7 +708,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) } /* CSI2 special configuration */ - if (pcdev-pdata-csi2) { + if (pcdev-csi2_pdev) { in_width = ((in_width - 2) * 2); left_offset *= 2; } @@ -810,7 +812,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) /* Make choises, based on platform preferences */ if ((common_flags V4L2_MBUS_HSYNC_ACTIVE_HIGH) (common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW)) { - if (pcdev-pdata-flags SH_CEU_FLAG_HSYNC_LOW) + if (pcdev-flags SH_CEU_FLAG_HSYNC_LOW) common_flags = ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; else common_flags = ~V4L2_MBUS_HSYNC_ACTIVE_LOW; @@ -818,7 +820,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) if ((common_flags V4L2_MBUS_VSYNC_ACTIVE_HIGH) (common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW)) { - if (pcdev-pdata-flags SH_CEU_FLAG_VSYNC_LOW) + if (pcdev-flags SH_CEU_FLAG_VSYNC_LOW) common_flags = ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; else common_flags = ~V4L2_MBUS_VSYNC_ACTIVE_LOW; @@ -873,11 +875,11 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) value |= common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 1 : 0; value |= common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 0 : 0; - if (pcdev-pdata-csi2) /* CSI2 mode */ + if (pcdev-csi2_pdev) /* CSI2 mode */ value |= 3 12; else if (pcdev-is_16bit) value |= 1 12; - else if (pcdev-pdata-flags SH_CEU_FLAG_LOWER_8BIT) + else if (pcdev-flags SH_CEU_FLAG_LOWER_8BIT) value |= 2 12; ceu_write(pcdev, CAMCR, value); @@ -1052,7 +1054,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int return 0; } - if (!pcdev-pdata-csi2) { + if (!pcdev-pdata || !pcdev-pdata-csi2) { /* Are there any restrictions in the CSI-2 case? */ ret = sh_mobile_ceu_try_bus_param(icd, fmt-bits_per_sample); if (ret 0) @@ -2107,13 +2109,17 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) init_completion(pcdev-complete); pcdev-pdata = pdev-dev.platform_data; - if (!pcdev-pdata) { + if (!pcdev-pdata !pdev-dev.of_node) { dev_err(pdev-dev, CEU platform data not set.\n); return -EINVAL; } - pcdev-max_width = pcdev-pdata-max_width ? : 2560; - pcdev-max_height = pcdev-pdata-max_height ? : 1920; + /* TODO: implement per-device bus flags */ + if (pcdev-pdata) { + pcdev-max_width = pcdev-pdata-max_width ? : 2560; + pcdev-max_height = pcdev-pdata-max_height ? : 1920; + pcdev-flags = pcdev-pdata-flags; + } base = devm_ioremap_resource(pdev-dev, res); if (IS_ERR(base)) @@ -2168,7 +2174,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) goto exit_free_ctx; /* CSI2 interfacing */ - csi2 = pcdev-pdata-csi2; + csi2 = pcdev-pdata ? pcdev-pdata-csi2 : NULL; if (csi2) { struct platform_device *csi2_pdev = platform_device_alloc(sh-mobile-csi2, csi2-id); @@ -2290,10 +2296,17 @@ static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = { .runtime_resume = sh_mobile_ceu_runtime_nop, }; +static const struct of_device_id sh_mobile_ceu_of_match[] = { + { .compatible = renesas,sh-mobile-ceu }, + { } +}; +MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match); + static struct platform_driver sh_mobile_ceu_driver = { .driver = { .name = sh_mobile_ceu
[PATCH v10 21/21] ARM: shmobile: convert ap4evb to asynchronously register camera subdevices
Register the imx074 camera I2C and the CSI-2 platform devices directly in board platform data instead of letting the sh_mobile_ceu_camera driver and the soc-camera framework register them at their run-time. This uses the V4L2 asynchronous subdevice probing capability. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- arch/arm/mach-shmobile/board-ap4evb.c | 103 +++- arch/arm/mach-shmobile/clock-sh7372.c |1 + 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 45f78ca..f0beec0 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -51,6 +51,7 @@ #include media/sh_mobile_ceu.h #include media/sh_mobile_csi2.h #include media/soc_camera.h +#include media/v4l2-async.h #include sound/sh_fsi.h #include sound/simple_card.h @@ -872,22 +873,32 @@ static struct platform_device leds_device = { }, }; -static struct i2c_board_info imx074_info = { - I2C_BOARD_INFO(imx074, 0x1a), +/* I2C */ +static struct soc_camera_subdev_desc imx074_desc; +static struct i2c_board_info i2c0_devices[] = { + { + I2C_BOARD_INFO(ak4643, 0x13), + }, { + I2C_BOARD_INFO(imx074, 0x1a), + .platform_data = imx074_desc, + }, }; -static struct soc_camera_link imx074_link = { - .bus_id = 0, - .board_info = imx074_info, - .i2c_adapter_id = 0, - .module_name= imx074, +static struct i2c_board_info i2c1_devices[] = { + { + I2C_BOARD_INFO(r2025sd, 0x32), + }, }; -static struct platform_device ap4evb_camera = { - .name = soc-camera-pdrv, - .id = 0, - .dev= { - .platform_data = imx074_link, +static struct resource csi2_resources[] = { + { + .name = CSI2, + .start = 0xffc9, + .end= 0xffc90fff, + .flags = IORESOURCE_MEM, + }, { + .start = intcs_evt2irq(0x17a0), + .flags = IORESOURCE_IRQ, }, }; @@ -896,7 +907,7 @@ static struct sh_csi2_client_config csi2_clients[] = { .phy= SH_CSI2_PHY_MAIN, .lanes = 0,/* default: 2 lanes */ .channel= 0, - .pdev = ap4evb_camera, + .name = imx074, }, }; @@ -907,31 +918,50 @@ static struct sh_csi2_pdata csi2_info = { .flags = SH_CSI2_ECC | SH_CSI2_CRC, }; -static struct resource csi2_resources[] = { - [0] = { - .name = CSI2, - .start = 0xffc9, - .end= 0xffc90fff, - .flags = IORESOURCE_MEM, +static struct platform_device csi2_device = { + .name = sh-mobile-csi2, + .id = 0, + .num_resources = ARRAY_SIZE(csi2_resources), + .resource = csi2_resources, + .dev= { + .platform_data = csi2_info, }, - [1] = { - .start = intcs_evt2irq(0x17a0), - .flags = IORESOURCE_IRQ, +}; + +static struct soc_camera_async_subdev csi2_sd = { + .asd = { + .bus_type = V4L2_ASYNC_BUS_PLATFORM, + .match.platform.name = sh-mobile-csi2.0, }, + .role = SOCAM_SUBDEV_DATA_PROCESSOR, }; -static struct sh_mobile_ceu_companion csi2 = { - .id = 0, - .num_resources = ARRAY_SIZE(csi2_resources), - .resource = csi2_resources, - .platform_data = csi2_info, +static struct soc_camera_async_subdev imx074_sd = { + .asd = { + .bus_type = V4L2_ASYNC_BUS_I2C, + .match.i2c = { + .adapter_id = 0, + .address = 0x1a, + }, + }, + .role = SOCAM_SUBDEV_DATA_SOURCE, }; +static struct v4l2_async_subdev *ceu_subdevs[] = { + /* Single 2-element group */ + csi2_sd.asd, + imx074_sd.asd, +}; + +/* 0-terminated array of group-sizes */ +static int ceu_subdev_sizes[] = {ARRAY_SIZE(ceu_subdevs), 0}; + static struct sh_mobile_ceu_info sh_mobile_ceu_info = { .flags = SH_CEU_FLAG_USE_8BIT_BUS, .max_width = 8188, .max_height = 8188, - .csi2 = csi2, + .asd = ceu_subdevs, + .asd_sizes = ceu_subdev_sizes, }; static struct resource ceu_resources[] = { @@ -976,7 +1006,7 @@ static struct platform_device *ap4evb_devices[] __initdata = { lcdc_device, lcdc1_device, ceu_device, - ap4evb_camera, + csi2_device, meram_device, }; @@ -1071,19 +1101,6 @@ static struct i2c_board_info tsc_device = { /*.irq is selected on ap4evb_init */ }; -/* I2C */ -static struct i2c_board_info i2c0_devices
[PATCH v10 01/21] soc-camera: move common code to soc_camera.c
All soc-camera host drivers include a pointer to an soc-camera device in their host private struct to check, that only one client is connected. Move this common code to soc_camera.c. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/atmel-isi.c | 10 +- drivers/media/platform/soc_camera/mx1_camera.c | 20 +++ drivers/media/platform/soc_camera/mx2_camera.c | 13 +-- drivers/media/platform/soc_camera/mx3_camera.c |9 - drivers/media/platform/soc_camera/omap1_camera.c | 14 +-- drivers/media/platform/soc_camera/pxa_camera.c | 18 ++--- .../platform/soc_camera/sh_mobile_ceu_camera.c | 13 +-- drivers/media/platform/soc_camera/soc_camera.c | 38 --- include/media/soc_camera.h |1 + 9 files changed, 49 insertions(+), 87 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 1abbb36..c9e080a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -102,7 +102,6 @@ struct atmel_isi { struct list_headvideo_buffer_list; struct frame_buffer *active; - struct soc_camera_device*icd; struct soc_camera_host soc_host; }; @@ -367,7 +366,7 @@ static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer) /* Check if already in a frame */ if (isi_readl(isi, ISI_STATUS) ISI_CTRL_CDC) { - dev_err(isi-icd-parent, Already in frame handling.\n); + dev_err(isi-soc_host.icd-parent, Already in frame handling.\n); return; } @@ -753,9 +752,6 @@ static int isi_camera_add_device(struct soc_camera_device *icd) struct atmel_isi *isi = ici-priv; int ret; - if (isi-icd) - return -EBUSY; - ret = clk_enable(isi-pclk); if (ret) return ret; @@ -766,7 +762,6 @@ static int isi_camera_add_device(struct soc_camera_device *icd) return ret; } - isi-icd = icd; dev_dbg(icd-parent, Atmel ISI Camera driver attached to camera %d\n, icd-devnum); return 0; @@ -777,11 +772,8 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct atmel_isi *isi = ici-priv; - BUG_ON(icd != isi-icd); - clk_disable(isi-mck); clk_disable(isi-pclk); - isi-icd = NULL; dev_dbg(icd-parent, Atmel ISI Camera driver detached from camera %d\n, icd-devnum); diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c index a3fd8d6..5f9ec8e 100644 --- a/drivers/media/platform/soc_camera/mx1_camera.c +++ b/drivers/media/platform/soc_camera/mx1_camera.c @@ -104,7 +104,6 @@ struct mx1_buffer { */ struct mx1_camera_dev { struct soc_camera_host soc_host; - struct soc_camera_device*icd; struct mx1_camera_pdata *pdata; struct mx1_buffer *active; struct resource *res; @@ -220,7 +219,7 @@ out: static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev) { struct videobuf_buffer *vbuf = pcdev-active-vb; - struct device *dev = pcdev-icd-parent; + struct device *dev = pcdev-soc_host.icd-parent; int ret; if (unlikely(!pcdev-active)) { @@ -331,7 +330,7 @@ static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev, static void mx1_camera_dma_irq(int channel, void *data) { struct mx1_camera_dev *pcdev = data; - struct device *dev = pcdev-icd-parent; + struct device *dev = pcdev-soc_host.icd-parent; struct mx1_buffer *buf; struct videobuf_buffer *vb; unsigned long flags; @@ -389,7 +388,7 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev) */ div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; - dev_dbg(pcdev-icd-parent, + dev_dbg(pcdev-soc_host.icd-parent, System clock %lukHz, target freq %dkHz, divisor %lu\n, lcdclk / 1000, mclk / 1000, div); @@ -400,7 +399,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) { unsigned int csicr1 = CSICR1_EN; - dev_dbg(pcdev-icd-parent, Activate device\n); + dev_dbg(pcdev-soc_host.icd-parent, Activate device\n); clk_prepare_enable(pcdev-clk); @@ -416,7 +415,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) { - dev_dbg(pcdev-icd-parent, Deactivate device\n); + dev_dbg(pcdev-soc_host.icd-parent, Deactivate device\n); /* Disable all CSI interface */ __raw_writel
[PATCH v10 03/21] pxa-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the pxa-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/pxa_camera.c | 28 +++ 1 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 686edf7..d4df305 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -955,33 +955,39 @@ static irqreturn_t pxa_camera_irq(int irq, void *data) return IRQ_HANDLED; } +static int pxa_camera_add_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, PXA Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void pxa_camera_remove_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, PXA Camera driver detached from camera %d\n, +icd-devnum); +} + /* * The following two functions absolutely depend on the fact, that * there can be only one camera on PXA quick capture interface * Called with .host_lock held */ -static int pxa_camera_add_device(struct soc_camera_device *icd) +static int pxa_camera_clock_start(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct pxa_camera_dev *pcdev = ici-priv; pxa_camera_activate(pcdev); - dev_info(icd-parent, PXA Camera driver attached to camera %d\n, -icd-devnum); - return 0; } /* Called with .host_lock held */ -static void pxa_camera_remove_device(struct soc_camera_device *icd) +static void pxa_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct pxa_camera_dev *pcdev = ici-priv; - dev_info(icd-parent, PXA Camera driver detached from camera %d\n, -icd-devnum); - /* disable capture, disable interrupts */ __raw_writel(0x3ff, pcdev-base + CICR0); @@ -1630,6 +1636,8 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { .owner = THIS_MODULE, .add= pxa_camera_add_device, .remove = pxa_camera_remove_device, + .clock_start= pxa_camera_clock_start, + .clock_stop = pxa_camera_clock_stop, .set_crop = pxa_camera_set_crop, .get_formats= pxa_camera_get_formats, .put_formats= pxa_camera_put_formats, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 15/21] V4L2: add a device pointer to struct v4l2_subdev
It is often useful to have simple means to get from a subdevice to the underlying physical device. This patch adds such a pointer to struct v4l2_subdev and sets it accordingly in the I2C and SPI cases. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/v4l2-core/v4l2-common.c |2 ++ include/media/v4l2-subdev.h |2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index 3fed63f..accfec6 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -291,6 +291,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, sd-flags |= V4L2_SUBDEV_FL_IS_I2C; /* the owner is the same as the i2c_client's driver owner */ sd-owner = client-driver-driver.owner; + sd-dev = client-dev; /* i2c_client and v4l2_subdev point to one another */ v4l2_set_subdevdata(sd, client); i2c_set_clientdata(client, sd); @@ -426,6 +427,7 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi, sd-flags |= V4L2_SUBDEV_FL_IS_SPI; /* the owner is the same as the spi_device's driver owner */ sd-owner = spi-dev.driver-owner; + sd-dev = spi-dev; /* spi_device and v4l2_subdev point to one another */ v4l2_set_subdevdata(sd, spi); spi_set_drvdata(spi, sd); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 5298d67..d8756fa 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -585,6 +585,8 @@ struct v4l2_subdev { void *host_priv; /* subdev device node */ struct video_device *devnode; + /* pointer to the physical device */ + struct device *dev; }; #define media_entity_to_v4l2_subdev(ent) \ -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 19/21] sh_mobile_ceu_camera: add asynchronous subdevice probing support
Use the v4l2-async API to support asynchronous subdevice probing, including the CSI2 subdevice. Synchronous probing is still supported too. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- .../platform/soc_camera/sh_mobile_ceu_camera.c | 134 +- drivers/media/platform/soc_camera/sh_mobile_csi2.c | 153 include/media/sh_mobile_ceu.h |2 + include/media/sh_mobile_csi2.h |2 +- 4 files changed, 190 insertions(+), 101 deletions(-) diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index b0f0995..d1b410b 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -36,6 +36,7 @@ #include linux/pm_runtime.h #include linux/sched.h +#include media/v4l2-async.h #include media/v4l2-common.h #include media/v4l2-dev.h #include media/soc_camera.h @@ -96,6 +97,10 @@ struct sh_mobile_ceu_buffer { struct sh_mobile_ceu_dev { struct soc_camera_host ici; + /* Asynchronous CSI2 linking */ + struct v4l2_async_subdev *csi2_asd; + struct v4l2_subdev *csi2_sd; + /* Synchronous probing compatibility */ struct platform_device *csi2_pdev; unsigned int irq; @@ -185,7 +190,6 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev) udelay(1); } - if (2 != success) { dev_warn(pcdev-ici.v4l2_dev.dev, soft reset time out\n); return -EIO; @@ -534,16 +538,29 @@ static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev) { struct v4l2_subdev *sd; - if (!pcdev-csi2_pdev) - return NULL; + if (pcdev-csi2_sd) + return pcdev-csi2_sd; - v4l2_device_for_each_subdev(sd, pcdev-ici.v4l2_dev) - if (pcdev-csi2_pdev-dev == v4l2_get_subdevdata(sd)) - return sd; + if (pcdev-csi2_asd) { + char name[] = sh-mobile-csi2; + v4l2_device_for_each_subdev(sd, pcdev-ici.v4l2_dev) + if (!strncmp(name, sd-name, sizeof(name) - 1)) { + pcdev-csi2_sd = sd; + return sd; + } + } return NULL; } +static struct v4l2_subdev *csi2_subdev(struct sh_mobile_ceu_dev *pcdev, + struct soc_camera_device *icd) +{ + struct v4l2_subdev *sd = pcdev-csi2_sd; + + return sd sd-grp_id == soc_camera_grp_id(icd) ? sd : NULL; +} + static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd-parent); @@ -564,12 +581,12 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver * has not found this soc-camera device among its clients */ - if (ret == -ENODEV csi2_sd) + if (csi2_sd ret == -ENODEV) csi2_sd-grp_id = 0; dev_info(icd-parent, -SuperH Mobile CEU driver attached to camera %d\n, -icd-devnum); +SuperH Mobile CEU%s driver attached to camera %d\n, +csi2_sd csi2_sd-grp_id ? /CSI-2 : , icd-devnum); return 0; } @@ -585,8 +602,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) icd-devnum); v4l2_subdev_call(csi2_sd, core, s_power, 0); - if (csi2_sd) - csi2_sd-grp_id = 0; } /* Called with .host_lock held */ @@ -708,7 +723,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) } /* CSI2 special configuration */ - if (pcdev-csi2_pdev) { + if (csi2_subdev(pcdev, icd)) { in_width = ((in_width - 2) * 2); left_offset *= 2; } @@ -765,13 +780,7 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr) static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev, struct soc_camera_device *icd) { - if (pcdev-csi2_pdev) { - struct v4l2_subdev *csi2_sd = find_csi2(pcdev); - if (csi2_sd csi2_sd-grp_id == soc_camera_grp_id(icd)) - return csi2_sd; - } - - return soc_camera_to_subdev(icd); + return csi2_subdev(pcdev, icd) ? : soc_camera_to_subdev(icd); } #define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \ @@ -875,7 +884,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) value |= common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 1 : 0; value |= common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 0 : 0; - if (pcdev-csi2_pdev) /* CSI2 mode */ + if (csi2_subdev(pcdev, icd
[PATCH v10 14/21] V4L2: add temporary clock helpers
Typical video devices like camera sensors require an external clock source. Many such devices cannot even access their hardware registers without a running clock. These clock sources should be controlled by their consumers. This should be performed, using the generic clock framework. Unfortunately so far only very few systems have been ported to that framework. This patch adds a set of temporary helpers, mimicking the generic clock API, to V4L2. Platforms, adopting the clock API, should switch to using it. Eventually this temporary API should be removed. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- v10: lock the driver only between enable / disable to avoid a circular dependency and allow driver unloading. drivers/media/v4l2-core/Makefile |2 +- drivers/media/v4l2-core/v4l2-clk.c | 242 include/media/v4l2-clk.h | 54 3 files changed, 297 insertions(+), 1 deletions(-) create mode 100644 drivers/media/v4l2-core/v4l2-clk.c create mode 100644 include/media/v4l2-clk.h diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index aa50c46..628c630 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -5,7 +5,7 @@ tuner-objs := tuner-core.o videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ - v4l2-event.o v4l2-ctrls.o v4l2-subdev.o + v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o ifeq ($(CONFIG_COMPAT),y) videodev-objs += v4l2-compat-ioctl32.o endif diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c new file mode 100644 index 000..b67de86 --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-clk.c @@ -0,0 +1,242 @@ +/* + * V4L2 clock service + * + * Copyright (C) 2012-2013, Guennadi Liakhovetski g.liakhovet...@gmx.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/atomic.h +#include linux/device.h +#include linux/errno.h +#include linux/list.h +#include linux/module.h +#include linux/mutex.h +#include linux/slab.h +#include linux/string.h + +#include media/v4l2-clk.h +#include media/v4l2-subdev.h + +static DEFINE_MUTEX(clk_lock); +static LIST_HEAD(clk_list); + +static struct v4l2_clk *v4l2_clk_find(const char *dev_id, const char *id) +{ + struct v4l2_clk *clk; + + list_for_each_entry(clk, clk_list, list) { + if (strcmp(dev_id, clk-dev_id)) + continue; + + if (!id || !clk-id || !strcmp(clk-id, id)) + return clk; + } + + return ERR_PTR(-ENODEV); +} + +struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) +{ + struct v4l2_clk *clk; + + mutex_lock(clk_lock); + clk = v4l2_clk_find(dev_name(dev), id); + + if (!IS_ERR(clk)) + atomic_inc(clk-use_count); + mutex_unlock(clk_lock); + + return clk; +} +EXPORT_SYMBOL(v4l2_clk_get); + +void v4l2_clk_put(struct v4l2_clk *clk) +{ + struct v4l2_clk *tmp; + + if (IS_ERR(clk)) + return; + + mutex_lock(clk_lock); + + list_for_each_entry(tmp, clk_list, list) + if (tmp == clk) + atomic_dec(clk-use_count); + + mutex_unlock(clk_lock); +} +EXPORT_SYMBOL(v4l2_clk_put); + +static int v4l2_clk_lock_driver(struct v4l2_clk *clk) +{ + struct v4l2_clk *tmp; + int ret = -ENODEV; + + mutex_lock(clk_lock); + + list_for_each_entry(tmp, clk_list, list) + if (tmp == clk) { + ret = !try_module_get(clk-ops-owner); + if (ret) + ret = -EFAULT; + break; + } + + mutex_unlock(clk_lock); + + return ret; +} + +static void v4l2_clk_unlock_driver(struct v4l2_clk *clk) +{ + module_put(clk-ops-owner); +} + +int v4l2_clk_enable(struct v4l2_clk *clk) +{ + int ret = v4l2_clk_lock_driver(clk); + + if (ret 0) + return ret; + + mutex_lock(clk-lock); + + if (++clk-enable == 1 clk-ops-enable) { + ret = clk-ops-enable(clk); + if (ret 0) + clk-enable--; + } + + mutex_unlock(clk-lock); + + return ret; +} +EXPORT_SYMBOL(v4l2_clk_enable); + +/* + * You might Oops if you try to disabled a disabled clock, because then the + * driver isn't locked and could have been unloaded by now, so, don't do that + */ +void v4l2_clk_disable(struct v4l2_clk *clk) +{ + int enable; + + mutex_lock(clk-lock); + + enable = --clk-enable; + if (WARN(enable 0, Unbalanced %s() on %s:%s!\n, __func__, +clk-dev_id, clk-id)) + clk-enable++; + else if (!enable
[PATCH v10 06/21] mx3-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the mx3-camera driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/mx3_camera.c | 35 ++- 1 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 71b9b19..1047e3e 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -460,8 +460,7 @@ static int mx3_camera_init_videobuf(struct vb2_queue *q, } /* First part of ipu_csi_init_interface() */ -static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam, - struct soc_camera_device *icd) +static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam) { u32 conf; long rate; @@ -505,31 +504,40 @@ static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam, clk_prepare_enable(mx3_cam-clk); rate = clk_round_rate(mx3_cam-clk, mx3_cam-mclk); - dev_dbg(icd-parent, Set SENS_CONF to %x, rate %ld\n, conf, rate); + dev_dbg(mx3_cam-soc_host.v4l2_dev.dev, Set SENS_CONF to %x, rate %ld\n, conf, rate); if (rate) clk_set_rate(mx3_cam-clk, rate); } -/* Called with .host_lock held */ static int mx3_camera_add_device(struct soc_camera_device *icd) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); + dev_info(icd-parent, MX3 Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void mx3_camera_remove_device(struct soc_camera_device *icd) +{ + dev_info(icd-parent, MX3 Camera driver detached from camera %d\n, +icd-devnum); +} + +/* Called with .host_lock held */ +static int mx3_camera_clock_start(struct soc_camera_host *ici) +{ struct mx3_camera_dev *mx3_cam = ici-priv; - mx3_camera_activate(mx3_cam, icd); + mx3_camera_activate(mx3_cam); mx3_cam-buf_total = 0; - dev_info(icd-parent, MX3 Camera driver attached to camera %d\n, -icd-devnum); - return 0; } /* Called with .host_lock held */ -static void mx3_camera_remove_device(struct soc_camera_device *icd) +static void mx3_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct mx3_camera_dev *mx3_cam = ici-priv; struct idmac_channel **ichan = mx3_cam-idmac_channel[0]; @@ -539,9 +547,6 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd) } clk_disable_unprepare(mx3_cam-clk); - - dev_info(icd-parent, MX3 Camera driver detached from camera %d\n, -icd-devnum); } static int test_platform_param(struct mx3_camera_dev *mx3_cam, @@ -1124,6 +1129,8 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = { .owner = THIS_MODULE, .add= mx3_camera_add_device, .remove = mx3_camera_remove_device, + .clock_start= mx3_camera_clock_start, + .clock_stop = mx3_camera_clock_stop, .set_crop = mx3_camera_set_crop, .set_fmt= mx3_camera_set_fmt, .try_fmt= mx3_camera_try_fmt, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 09/21] sh-mobile-ceu-camera: move interface activation and deactivation to clock callbacks
When adding and removing a client, the sh-mobile-ceu-camera driver activates and, respectively, deactivates its camera interface and, if necessary, the CSI2 controller. Only handling of the CSI2 interface is client-specific and is only needed, when a data-exchange with the client is taking place. Move the rest to .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- .../platform/soc_camera/sh_mobile_ceu_camera.c | 58 1 files changed, 35 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 5b7d8e1..9037472 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -162,7 +162,6 @@ static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs) static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev) { int i, success = 0; - struct soc_camera_device *icd = pcdev-ici.icd; ceu_write(pcdev, CAPSR, 1 16); /* reset */ @@ -186,7 +185,7 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev) if (2 != success) { - dev_warn(icd-pdev, soft reset time out\n); + dev_warn(pcdev-ici.v4l2_dev.dev, soft reset time out\n); return -EIO; } @@ -543,35 +542,21 @@ static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev) return NULL; } -/* Called with .host_lock held */ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct sh_mobile_ceu_dev *pcdev = ici-priv; - struct v4l2_subdev *csi2_sd; + struct v4l2_subdev *csi2_sd = find_csi2(pcdev); int ret; - dev_info(icd-parent, -SuperH Mobile CEU driver attached to camera %d\n, -icd-devnum); - - pm_runtime_get_sync(ici-v4l2_dev.dev); - - pcdev-buf_total = 0; - - ret = sh_mobile_ceu_soft_reset(pcdev); - - csi2_sd = find_csi2(pcdev); if (csi2_sd) { csi2_sd-grp_id = soc_camera_grp_id(icd); v4l2_set_subdev_hostdata(csi2_sd, icd); } ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); - if (ret 0 ret != -ENOIOCTLCMD ret != -ENODEV) { - pm_runtime_put(ici-v4l2_dev.dev); + if (ret 0 ret != -ENOIOCTLCMD ret != -ENODEV) return ret; - } /* * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver @@ -580,19 +565,48 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) if (ret == -ENODEV csi2_sd) csi2_sd-grp_id = 0; + dev_info(icd-parent, +SuperH Mobile CEU driver attached to camera %d\n, +icd-devnum); + return 0; } -/* Called with .host_lock held */ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct sh_mobile_ceu_dev *pcdev = ici-priv; struct v4l2_subdev *csi2_sd = find_csi2(pcdev); + dev_info(icd-parent, +SuperH Mobile CEU driver detached from camera %d\n, +icd-devnum); + v4l2_subdev_call(csi2_sd, core, s_power, 0); if (csi2_sd) csi2_sd-grp_id = 0; +} + +/* Called with .host_lock held */ +static int sh_mobile_ceu_clock_start(struct soc_camera_host *ici) +{ + struct sh_mobile_ceu_dev *pcdev = ici-priv; + int ret; + + pm_runtime_get_sync(ici-v4l2_dev.dev); + + pcdev-buf_total = 0; + + ret = sh_mobile_ceu_soft_reset(pcdev); + + return 0; +} + +/* Called with .host_lock held */ +static void sh_mobile_ceu_clock_stop(struct soc_camera_host *ici) +{ + struct sh_mobile_ceu_dev *pcdev = ici-priv; + /* disable capture, disable interrupts */ ceu_write(pcdev, CEIER, 0); sh_mobile_ceu_soft_reset(pcdev); @@ -607,10 +621,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) spin_unlock_irq(pcdev-lock); pm_runtime_put(ici-v4l2_dev.dev); - - dev_info(icd-parent, -SuperH Mobile CEU driver detached from camera %d\n, -icd-devnum); } /* @@ -2027,6 +2037,8 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { .owner = THIS_MODULE, .add= sh_mobile_ceu_add_device, .remove = sh_mobile_ceu_remove_device, + .clock_start= sh_mobile_ceu_clock_start, + .clock_stop = sh_mobile_ceu_clock_stop, .get_formats= sh_mobile_ceu_get_formats, .put_formats= sh_mobile_ceu_put_formats, .get_crop = sh_mobile_ceu_get_crop, -- 1.7.2.5 -- To unsubscribe
[PATCH v10 05/21] atmel-isi: move interface activation and deactivation to clock callbacks
When adding and removing a client, the atmel-isi camera host driver only activates and deactivates its camera interface respectively, which doesn't include any client-specific actions. Move this functionality into .clock_start() and .clock_stop() callbacks. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/atmel-isi.c | 28 + 1 files changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c9e080a..1044856 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -745,10 +745,23 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, return formats; } -/* Called with .host_lock held */ static int isi_camera_add_device(struct soc_camera_device *icd) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); + dev_dbg(icd-parent, Atmel ISI Camera driver attached to camera %d\n, +icd-devnum); + + return 0; +} + +static void isi_camera_remove_device(struct soc_camera_device *icd) +{ + dev_dbg(icd-parent, Atmel ISI Camera driver detached from camera %d\n, +icd-devnum); +} + +/* Called with .host_lock held */ +static int isi_camera_clock_start(struct soc_camera_host *ici) +{ struct atmel_isi *isi = ici-priv; int ret; @@ -762,21 +775,16 @@ static int isi_camera_add_device(struct soc_camera_device *icd) return ret; } - dev_dbg(icd-parent, Atmel ISI Camera driver attached to camera %d\n, -icd-devnum); return 0; } + /* Called with .host_lock held */ -static void isi_camera_remove_device(struct soc_camera_device *icd) +static void isi_camera_clock_stop(struct soc_camera_host *ici) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); struct atmel_isi *isi = ici-priv; clk_disable(isi-mck); clk_disable(isi-pclk); - - dev_dbg(icd-parent, Atmel ISI Camera driver detached from camera %d\n, -icd-devnum); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -880,6 +888,8 @@ static struct soc_camera_host_ops isi_soc_camera_host_ops = { .owner = THIS_MODULE, .add= isi_camera_add_device, .remove = isi_camera_remove_device, + .clock_start= isi_camera_clock_start, + .clock_stop = isi_camera_clock_stop, .set_fmt= isi_camera_set_fmt, .try_fmt= isi_camera_try_fmt, .get_formats= isi_camera_get_formats, -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 13/21] sh-mobile-ceu-driver: support max width and height in DT
Some CEU implementations have non-standard (larger) maximum supported width and height values. Add two OF properties to specify them. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- .../devicetree/bindings/media/sh_mobile_ceu.txt| 18 +++ .../platform/soc_camera/sh_mobile_ceu_camera.c | 23 ++- 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/sh_mobile_ceu.txt diff --git a/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt b/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt new file mode 100644 index 000..1ce4e46 --- /dev/null +++ b/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt @@ -0,0 +1,18 @@ +Bindings, specific for the sh_mobile_ceu_camera.c driver: + - compatible: Should be renesas,sh-mobile-ceu + - reg: register base and size + - interrupts: the interrupt number + - interrupt-parent: the interrupt controller + - renesas,max-width: maximum image width, supported on this SoC + - renesas,max-height: maximum image height, supported on this SoC + +Example: + +ceu0: ceu@0xfe91 { + compatible = renesas,sh-mobile-ceu; + reg = 0xfe91 0xa0; + interrupt-parent = intcs; + interrupts = 0x880; + renesas,max-width = 8188; + renesas,max-height = 8188; +}; diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index fcc13d8..b0f0995 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -2116,11 +2116,30 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) /* TODO: implement per-device bus flags */ if (pcdev-pdata) { - pcdev-max_width = pcdev-pdata-max_width ? : 2560; - pcdev-max_height = pcdev-pdata-max_height ? : 1920; + pcdev-max_width = pcdev-pdata-max_width; + pcdev-max_height = pcdev-pdata-max_height; pcdev-flags = pcdev-pdata-flags; } + if (!pcdev-max_width) { + unsigned int v; + err = of_property_read_u32(pdev-dev.of_node, renesas,max-width, v); + if (!err) + pcdev-max_width = v; + + if (!pcdev-max_width) + pcdev-max_width = 2560; + } + if (!pcdev-max_height) { + unsigned int v; + err = of_property_read_u32(pdev-dev.of_node, renesas,max-height, v); + if (!err) + pcdev-max_height = v; + + if (!pcdev-max_height) + pcdev-max_height = 1920; + } + base = devm_ioremap_resource(pdev-dev, res); if (IS_ERR(base)) return PTR_ERR(base); -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 16/21] V4L2: support asynchronous subdevice registration
Currently bridge device drivers register devices for all subdevices synchronously, tupically, during their probing. E.g. if an I2C CMOS sensor is attached to a video bridge device, the bridge driver will create an I2C device and wait for the respective I2C driver to probe. This makes linking of devices straight forward, but this approach cannot be used with intrinsically asynchronous and unordered device registration systems like the Flattened Device Tree. To support such systems this patch adds an asynchronous subdevice registration framework to V4L2. To use it respective (e.g. I2C) subdevice drivers must register themselves with the framework. A bridge driver on the other hand must register notification callbacks, that will be called upon various related events. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- v10: (a) remove dynamic dev[] allocation (b) merge struct v4l2_async_hw_info into struct v4l2_async_subdev (c) change .bound(), .unbind() prototypes - thanks to Laurent for a patch (d) improve struct comment (e) remove an unused variable in v4l2_async_unregister_subdev() (f) lock the device, when dereferencing dev-driver (g) fix a false success in v4l2_async_belongs() drivers/media/v4l2-core/Makefile |3 +- drivers/media/v4l2-core/v4l2-async.c | 280 ++ include/media/v4l2-async.h | 105 + include/media/v4l2-subdev.h |8 + 4 files changed, 395 insertions(+), 1 deletions(-) create mode 100644 drivers/media/v4l2-core/v4l2-async.c create mode 100644 include/media/v4l2-async.h diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index 628c630..4c33b8d6 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -5,7 +5,8 @@ tuner-objs := tuner-core.o videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ - v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o + v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o \ + v4l2-async.o ifeq ($(CONFIG_COMPAT),y) videodev-objs += v4l2-compat-ioctl32.o endif diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c new file mode 100644 index 000..3590ccc --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -0,0 +1,280 @@ +/* + * V4L2 asynchronous subdevice registration API + * + * Copyright (C) 2012-2013, Guennadi Liakhovetski g.liakhovet...@gmx.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/device.h +#include linux/err.h +#include linux/i2c.h +#include linux/list.h +#include linux/module.h +#include linux/mutex.h +#include linux/platform_device.h +#include linux/slab.h +#include linux/types.h + +#include media/v4l2-async.h +#include media/v4l2-device.h +#include media/v4l2-subdev.h + +static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd) +{ + struct i2c_client *client = i2c_verify_client(dev); + return client + asd-bus_type == V4L2_ASYNC_BUS_I2C + asd-match.i2c.adapter_id == client-adapter-nr + asd-match.i2c.address == client-addr; +} + +static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd) +{ + return asd-bus_type == V4L2_ASYNC_BUS_PLATFORM + !strcmp(asd-match.platform.name, dev_name(dev)); +} + +static LIST_HEAD(subdev_list); +static LIST_HEAD(notifier_list); +static DEFINE_MUTEX(list_lock); + +static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier, + struct v4l2_async_subdev_list *asdl) +{ + struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl); + struct v4l2_async_subdev *asd; + bool (*match)(struct device *, + struct v4l2_async_subdev *); + + list_for_each_entry(asd, notifier-waiting, list) { + /* bus_type has been verified valid before */ + switch (asd-bus_type) { + case V4L2_ASYNC_BUS_CUSTOM: + match = asd-match.custom.match; + if (!match) + /* Match always */ + return asd; + break; + case V4L2_ASYNC_BUS_PLATFORM: + match = match_platform; + break; + case V4L2_ASYNC_BUS_I2C: + match = match_i2c; + break; + default: + /* Cannot happen, unless someone breaks us */ + WARN_ON(true); + return NULL; + } + + /* match cannot be NULL here
Re: [PATCH] v4l2: remove g_chip_ident where it is easy to do so.
) Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 05/13] soc_camera: replace vdev-parent by vdev-v4l2_dev.
On Mon, 3 Jun 2013, Hans Verkuil wrote: From: Hans Verkuil hans.verk...@cisco.com The parent field will eventually disappear to be replaced by v4l2_dev. soc_camera does provide a v4l2_device struct but did not point to it in struct video_device. This is now fixed. Signed-off-by: Hans Verkuil hans.verk...@cisco.com Cc: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/soc_camera.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 96645e9..ea951ec 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -524,7 +524,7 @@ static int soc_camera_open(struct file *file) return -ENODEV; } - icd = dev_get_drvdata(vdev-parent); + icd = dev_get_drvdata(vdev-v4l2_dev-dev); ici = to_soc_camera_host(icd-parent); ret = try_module_get(ici-ops-owner) ? 0 : -ENODEV; @@ -1511,7 +1511,7 @@ static int video_dev_create(struct soc_camera_device *icd) strlcpy(vdev-name, ici-drv_name, sizeof(vdev-name)); - vdev-parent= icd-pdev; + vdev-v4l2_dev = ici-v4l2_dev; vdev-fops = soc_camera_fops; vdev-ioctl_ops = soc_camera_ioctl_ops; vdev-release = video_device_release; Doesn't it break soc-camera?... I think those are 2 absolutely different devices, so, you're not getting icd from dev_get_drvdata(vdev-v4l2_dev-dev). Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 03/13] sh_vou: remove current_norm
Hi Hans On Mon, 3 Jun 2013, Hans Verkuil wrote: From: Hans Verkuil hans.verk...@cisco.com The current_norm field is deprecated and is replaced by g_std. This driver already implements g_std, so just remove current_norm. Signed-off-by: Hans Verkuil hans.verk...@cisco.com Cc: Guennadi Liakhovetski g.liakhovet...@gmx.de Would you like to pull this via your tree? In that case Acked-by: Guennadi Liakhovetski g.liakhovet...@gmx.de Otherwise I can easily take it via mine. Thanks Guennadi --- drivers/media/platform/sh_vou.c |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index 7d02350..84625fa 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -1313,7 +1313,6 @@ static const struct video_device sh_vou_video_template = { .fops = sh_vou_fops, .ioctl_ops = sh_vou_ioctl_ops, .tvnorms= V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */ - .current_norm = V4L2_STD_NTSC_M, .vfl_dir= VFL_DIR_TX, }; @@ -1352,7 +1351,7 @@ static int sh_vou_probe(struct platform_device *pdev) pix = vou_dev-pix; /* Fill in defaults */ - vou_dev-std= sh_vou_video_template.current_norm; + vou_dev-std= V4L2_STD_NTSC_M; rect-left = 0; rect-top = 0; rect-width = VOU_MAX_IMAGE_WIDTH; -- 1.7.10.4 --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 04/13] soc_camera: remove use of current_norm.
Hi Hans On Mon, 3 Jun 2013, Hans Verkuil wrote: From: Hans Verkuil hans.verk...@cisco.com The current_norm field is deprecated, so don't set it. Since it is set to V4L2_STD_UNKNOWN which is 0 it didn't do anything anyway. Also remove a few other unnecessary uses of V4L2_STD_UNKNOWN. Signed-off-by: Hans Verkuil hans.verk...@cisco.com Cc: Guennadi Liakhovetski g.liakhovet...@gmx.de I'd rather take this via my tree to avoid any conflicts, is this ok with you? Thanks Guennadi --- drivers/media/platform/soc_camera/soc_camera.c |3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index eea832c..96645e9 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -235,7 +235,6 @@ static int soc_camera_enum_input(struct file *file, void *priv, /* default is camera */ inp-type = V4L2_INPUT_TYPE_CAMERA; - inp-std = V4L2_STD_UNKNOWN; strcpy(inp-name, Camera); return 0; @@ -1513,11 +1512,9 @@ static int video_dev_create(struct soc_camera_device *icd) strlcpy(vdev-name, ici-drv_name, sizeof(vdev-name)); vdev-parent= icd-pdev; - vdev-current_norm = V4L2_STD_UNKNOWN; vdev-fops = soc_camera_fops; vdev-ioctl_ops = soc_camera_ioctl_ops; vdev-release = video_device_release; - vdev-tvnorms = V4L2_STD_UNKNOWN; vdev-ctrl_handler = icd-ctrl_handler; vdev-lock = ici-host_lock; -- 1.7.10.4 --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 04/13] soc_camera: remove use of current_norm.
On Fri, 7 Jun 2013, Hans Verkuil wrote: On Fri June 7 2013 11:36:57 Guennadi Liakhovetski wrote: Hi Hans On Mon, 3 Jun 2013, Hans Verkuil wrote: From: Hans Verkuil hans.verk...@cisco.com The current_norm field is deprecated, so don't set it. Since it is set to V4L2_STD_UNKNOWN which is 0 it didn't do anything anyway. Also remove a few other unnecessary uses of V4L2_STD_UNKNOWN. Signed-off-by: Hans Verkuil hans.verk...@cisco.com Cc: Guennadi Liakhovetski g.liakhovet...@gmx.de I'd rather take this via my tree to avoid any conflicts, is this ok with you? Ideally I would like to take this in myself since the last patch of the series removes current_norm support entirely. If you take it, then I have to leave off the last patch until both our trees are merged. If you still prefer to take it yourself, then let me know and I'll leave this patch and the last patch out when I merge it. Ok, take it via your tree, we'll resolve any conflicts afterwards. Acked-by: Guennadi Liakhovetski g.liakhovet...@gmx.de Thanks Guennadi Regards, Hans Thanks Guennadi --- drivers/media/platform/soc_camera/soc_camera.c |3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index eea832c..96645e9 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -235,7 +235,6 @@ static int soc_camera_enum_input(struct file *file, void *priv, /* default is camera */ inp-type = V4L2_INPUT_TYPE_CAMERA; - inp-std = V4L2_STD_UNKNOWN; strcpy(inp-name, Camera); return 0; @@ -1513,11 +1512,9 @@ static int video_dev_create(struct soc_camera_device *icd) strlcpy(vdev-name, ici-drv_name, sizeof(vdev-name)); vdev-parent= icd-pdev; - vdev-current_norm = V4L2_STD_UNKNOWN; vdev-fops = soc_camera_fops; vdev-ioctl_ops = soc_camera_ioctl_ops; vdev-release = video_device_release; - vdev-tvnorms = V4L2_STD_UNKNOWN; vdev-ctrl_handler = icd-ctrl_handler; vdev-lock = ici-host_lock; --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 05/13] soc_camera: replace vdev-parent by vdev-v4l2_dev.
On Fri, 7 Jun 2013, Hans Verkuil wrote: Stupid question perhaps, but why is soc_camera_device a platform_device? Partially that's historic. It's weird. The camera host device is definitely a platform_device, and the video nodes are childs of that platform_device, but soc_camera_device doesn't map to any hardware. Using platform devices for camera sensors etc. is a way to inform the soc-camera core about them. Soc-camera core registers a platform driver, which probes those devices, and then, once soc-camera hosts register with the soc-camera core, they are matched against those platform devices. Yes, this could also be done differently - hosts could just pass lists of respective camera sensor descriptors, but soc-camera is currently using a different approach. This anyway is going to disappear once we convert to asynchronous probing... Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[GIT PULL] soc-camera: 3.10 fixes
Hi Mauro Please push these to 3.10. The following changes since commit 1612e111e4e565422242727efb59499cce8738e4: Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (2013-06-06 18:09:05 -0700) are available in the git repository at: git://linuxtv.org/gliakhovetski/v4l-dvb.git 3.10-rc4-fixes Katsuya Matsubara (3): sh_veu: invoke v4l2_m2m_job_finish() even if a job has been aborted sh_veu: keep power supply until the m2m context is released sh_veu: fix the buffer size calculation Wenbing Wang (1): soc_camera: error dev remove and v4l2 call drivers/media/platform/sh_veu.c| 15 ++- drivers/media/platform/soc_camera/soc_camera.c |4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[GIT PULL] soc-camera: 3.11 minor updates
Hi Mauro These are just a couple of minor updates for 3.11: The following changes since commit 7eac97d7e714429f7ef1ba5d35f94c07f4c34f8e: [media] media: pci: remove duplicate checks for EPERM (2013-05-27 09:34:56 -0300) are available in the git repository at: git://linuxtv.org/gliakhovetski/v4l-dvb.git for-3.11-1 Guennadi Liakhovetski (1): V4L2: soc-camera: remove unneeded include path Paul Bolle (1): soc-camera: remove two unused configs Sachin Kamat (6): soc_camera: Constify dev_pm_ops in mt9t031.c soc_camera: Fix checkpatch warning in ov9640.c soc_camera/sh_mobile_csi2: Remove redundant platform_set_drvdata() soc_camera_platform: Remove redundant platform_set_drvdata() soc_camera: mt9t112: Remove empty function soc_camera: tw9910: Remove empty function Thomas Meyer (1): media: Cocci spatch ptr_ret.spatch drivers/media/i2c/soc_camera/mt9t031.c |2 +- drivers/media/i2c/soc_camera/mt9t112.c |6 -- drivers/media/i2c/soc_camera/ov9640.c |2 +- drivers/media/i2c/soc_camera/tw9910.c |6 -- drivers/media/platform/sh_veu.c|5 + drivers/media/platform/soc_camera/Kconfig |8 drivers/media/platform/soc_camera/Makefile |2 -- drivers/media/platform/soc_camera/sh_mobile_csi2.c |8 +--- .../platform/soc_camera/soc_camera_platform.c | 11 +-- 9 files changed, 5 insertions(+), 45 deletions(-) Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] ov10635: Add OmniVision ov10635 SoC camera driver
On Thu, 6 Jun 2013, jean-philippe francois wrote: 2013/6/5 Guennadi Liakhovetski g.liakhovet...@gmx.de: Hi Phil Thanks for the patch. I'll look at it in more detail hopefully soon enough... One remark so far to Jean-Philippe's comment: On Tue, 4 Jun 2013, jean-philippe francois wrote: 2013/6/3 Phil Edworthy phil.edwor...@renesas.com: Signed-off-by: Phil Edworthy phil.edwor...@renesas.com --- v2: - Simplified flow in ov10635_s_ctrl. - Removed chip ident code - build tested only drivers/media/i2c/soc_camera/Kconfig |6 + drivers/media/i2c/soc_camera/Makefile |1 + drivers/media/i2c/soc_camera/ov10635.c | 1141 3 files changed, 1148 insertions(+) create mode 100644 drivers/media/i2c/soc_camera/ov10635.c [snip] diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c new file mode 100644 index 000..bf08aae --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov10635.c @@ -0,0 +1,1141 @@ [snip] +/* default register setup */ +static const struct ov10635_reg ov10635_regs_default[] = { + { 0x0103, 0x01 }, { 0x301b, 0xff }, { 0x301c, 0xff }, { 0x301a, 0xff }, + { 0x3011, 0x02 }, /* drive strength reduced to x1 */ + { 0x6900, 0x0c }, { 0x6901, 0x11 }, { 0x3503, 0x10 }, { 0x3025, 0x03 }, + { 0x3005, 0x20 }, { 0x3006, 0x91 }, { 0x3600, 0x74 }, { 0x3601, 0x2b }, + { 0x3612, 0x00 }, { 0x3611, 0x67 }, { 0x3633, 0xca }, { 0x3602, 0x2f }, + { 0x3603, 0x00 }, { 0x3630, 0x28 }, { 0x3631, 0x16 }, { 0x3714, 0x10 }, + { 0x371d, 0x01 }, { 0x4300, 0x38 }, { 0x3007, 0x01 }, { 0x3024, 0x01 }, + { 0x3020, 0x0b }, { 0x3702, 0x0d }, { 0x3703, 0x20 }, { 0x3704, 0x15 }, + { 0x3709, 0xa8 }, { 0x370c, 0xc7 }, { 0x370d, 0x80 }, { 0x3712, 0x00 }, + { 0x3713, 0x20 }, { 0x3715, 0x04 }, { 0x381d, 0x40 }, { 0x381c, 0x00 }, + { 0x3822, 0x50 }, { 0x3824, 0x10 }, { 0x3815, 0x8c }, { 0x3804, 0x05 }, + { 0x3805, 0x1f }, { 0x3800, 0x00 }, { 0x3801, 0x00 }, { 0x3806, 0x02 }, + { 0x3807, 0xfd }, { 0x3802, 0x00 }, { 0x3803, 0x2c }, { 0x3808, 0x05 }, + { 0x3809, 0x00 }, { 0x380a, 0x02 }, { 0x380b, 0xd0 }, { 0x380c, 0x06 }, + { 0x380d, 0xf6 }, { 0x380e, 0x02 }, { 0x380f, 0xec }, { 0x3813, 0x02 }, + { 0x3811, 0x08 }, { 0x381f, 0x0c }, { 0x3819, 0x04 }, { 0x3804, 0x01 }, + { 0x3805, 0x00 }, { 0x3828, 0x03 }, { 0x3829, 0x10 }, { 0x382a, 0x10 }, + { 0x3621, 0x63 }, { 0x5005, 0x08 }, { 0x56d5, 0x00 }, { 0x56d6, 0x80 }, + { 0x56d7, 0x00 }, { 0x56d8, 0x00 }, { 0x56d9, 0x00 }, { 0x56da, 0x80 }, + { 0x56db, 0x00 }, { 0x56dc, 0x00 }, { 0x56e8, 0x00 }, { 0x56e9, 0x7f }, + { 0x56ea, 0x00 }, { 0x56eb, 0x7f }, { 0x5100, 0x00 }, { 0x5101, 0x80 }, + { 0x5102, 0x00 }, { 0x5103, 0x80 }, { 0x5104, 0x00 }, { 0x5105, 0x80 }, + { 0x5106, 0x00 }, { 0x5107, 0x80 }, { 0x5108, 0x00 }, { 0x5109, 0x00 }, + { 0x510a, 0x00 }, { 0x510b, 0x00 }, { 0x510c, 0x00 }, { 0x510d, 0x00 }, + { 0x510e, 0x00 }, { 0x510f, 0x00 }, { 0x5110, 0x00 }, { 0x5111, 0x80 }, + { 0x5112, 0x00 }, { 0x5113, 0x80 }, { 0x5114, 0x00 }, { 0x5115, 0x80 }, + { 0x5116, 0x00 }, { 0x5117, 0x80 }, { 0x5118, 0x00 }, { 0x5119, 0x00 }, + { 0x511a, 0x00 }, { 0x511b, 0x00 }, { 0x511c, 0x00 }, { 0x511d, 0x00 }, + { 0x511e, 0x00 }, { 0x511f, 0x00 }, { 0x56d0, 0x00 }, { 0x5006, 0x24 }, + { 0x5608, 0x0b }, { 0x52d7, 0x06 }, { 0x528d, 0x08 }, { 0x5293, 0x12 }, + { 0x52d3, 0x12 }, { 0x5288, 0x06 }, { 0x5289, 0x20 }, { 0x52c8, 0x06 }, + { 0x52c9, 0x20 }, { 0x52cd, 0x04 }, { 0x5381, 0x00 }, { 0x5382, 0xff }, + { 0x5589, 0x76 }, { 0x558a, 0x47 }, { 0x558b, 0xef }, { 0x558c, 0xc9 }, + { 0x558d, 0x49 }, { 0x558e, 0x30 }, { 0x558f, 0x67 }, { 0x5590, 0x3f }, + { 0x5591, 0xf0 }, { 0x5592, 0x10 }, { 0x55a2, 0x6d }, { 0x55a3, 0x55 }, + { 0x55a4, 0xc3 }, { 0x55a5, 0xb5 }, { 0x55a6, 0x43 }, { 0x55a7, 0x38 }, + { 0x55a8, 0x5f }, { 0x55a9, 0x4b }, { 0x55aa, 0xf0 }, { 0x55ab, 0x10 }, + { 0x5581, 0x52 }, { 0x5300, 0x01 }, { 0x5301, 0x00 }, { 0x5302, 0x00 }, + { 0x5303, 0x0e }, { 0x5304, 0x00 }, { 0x5305, 0x0e }, { 0x5306, 0x00 }, + { 0x5307, 0x36 }, { 0x5308, 0x00 }, { 0x5309, 0xd9 }, { 0x530a, 0x00 }, + { 0x530b, 0x0f }, { 0x530c, 0x00 }, { 0x530d, 0x2c }, { 0x530e, 0x00 }, + { 0x530f, 0x59 }, { 0x5310, 0x00 }, { 0x5311, 0x7b }, { 0x5312, 0x00 }, + { 0x5313, 0x22 }, { 0x5314, 0x00 }, { 0x5315, 0xd5 }, { 0x5316, 0x00 }, + { 0x5317, 0x13 }, { 0x5318, 0x00 }, { 0x5319, 0x18 }, { 0x531a, 0x00 }, + { 0x531b
Re: [PATCH v2] ov10635: Add OmniVision ov10635 SoC camera driver
}, + { 0x4305, 0x02 }, { 0x4306, 0x03 }, { 0x4307, 0xfe }, { 0x4308, 0x00 }, + { 0x4309, 0x02 }, +}; + +static const struct ov10635_reg ov10635_regs_vert_sub_sample[] = { + { 0x381f, 0x06 }, { 0x4001, 0x02 }, { 0x4004, 0x02 }, { 0x4050, 0x10 }, + { 0x4051, 0x11 }, { 0x6e47, 0x06 }, { 0x4610, 0x03 }, { 0x4613, 0x0a }, +}; + +static const struct ov10635_reg ov10635_regs_enable[] = { + { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, + { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x301b, 0xf0 }, { 0x301c, 0xf0 }, + { 0x301a, 0xf0 }, +}; Register 0x3042 is only touched by the enable part, not by the change mode part I think you could move the {0x3042, 0xf0} sequence in the standard_regs array, and keep only the 0x301b, 0x301c, 0x301a registers. By the way, did you test with a single write ? There is the same sequence in ov5642 init, so I believe it is copy pasted in every omnivision init. Is it actually useful ? If this is indeed the case and all OV sensor camera drivers use the same initialisation sequence, maybe it's time to consider making one firmware file for them all and loading it in user-space? Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] [media] soc_camera: error dev remove and v4l2 call
Hi On Wed, 5 Jun 2013, Wenbing Wang wrote: From: Wenbing Wang wan...@marvell.com in soc_camera_close(), if ici-ops-remove() removes device firstly, and then call __soc_camera_power_off(), it has logic error. Since if remove device, it should disable subdev clk. but in __soc_camera_ power_off(), it will callback v4l2 s_power function which will read/write subdev registers to control power by i2c. and then i2c read/write will fail because of clk disable. So suggest to re-sequence two functions call. Thanks for the patch. I agree, that the clock should be switched off after powering off the client. And this is also how it's done in the latest version of my v4l2-clk / v4l2-async patches: there in soc_camera_power_off() first power-off is performed and only then v4l2_clk_disable() is called to detach the client from the host and stop the master clock. So, if you need this fix for 3.10, we could push it upstream. Otherwise hopefully we'll manage to get v4l2-clk and -async in 3.11 and thus have this fixed there. Then this patch won't be needed. Thanks Guennadi Change-Id: Iee7a6d4fc7c7c1addb5d342621eb8dcd00fa2745 Signed-off-by: Wenbing Wang wan...@marvell.com --- drivers/media/platform/soc_camera/soc_camera.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index eea832c..3a4efbd 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -643,9 +643,9 @@ static int soc_camera_close(struct file *file) if (ici-ops-init_videobuf2) vb2_queue_release(icd-vb2_vidq); - ici-ops-remove(icd); - __soc_camera_power_off(icd); + + ici-ops-remove(icd); } if (icd-streamer == file) -- 1.7.5.4 --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] [media] soc_camera: mt9t112: Remove empty function
Hi Sachin On Tue, 4 Jun 2013, Sachin Kamat wrote: On 24 May 2013 16:55, Sachin Kamat sachin.ka...@linaro.org wrote: After the switch to devm_* functions, the 'remove' function does not do anything. Delete it. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org Cc: Kuninori Morimoto morimoto.kunin...@renesas.com --- drivers/media/i2c/soc_camera/mt9t112.c |6 -- 1 file changed, 6 deletions(-) [snip] Gentle ping on this series :) Both these patches are in my queue for 3.11. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] [media] soc_camera/sh_mobile_csi2: Remove redundant platform_set_drvdata()
On Mon, 20 May 2013, Sachin Kamat wrote: On 13 May 2013 14:49, Sachin Kamat sachin.ka...@linaro.org wrote: Commit 0998d06310 (device-core: Ensure drvdata = NULL when no driver is bound) removes the need to set driver data field to NULL. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org Thanks, both queued for 3.11. Guennadi --- drivers/media/platform/soc_camera/sh_mobile_csi2.c |8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c index 09cb4fc..13a1f8f 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c +++ b/drivers/media/platform/soc_camera/sh_mobile_csi2.c @@ -340,18 +340,13 @@ static int sh_csi2_probe(struct platform_device *pdev) ret = v4l2_device_register_subdev(pdata-v4l2_dev, priv-subdev); dev_dbg(pdev-dev, %s(%p): ret(register_subdev) = %d\n, __func__, priv, ret); if (ret 0) - goto esdreg; + return ret; pm_runtime_enable(pdev-dev); dev_dbg(pdev-dev, CSI2 probed.\n); return 0; - -esdreg: - platform_set_drvdata(pdev, NULL); - - return ret; } static int sh_csi2_remove(struct platform_device *pdev) @@ -360,7 +355,6 @@ static int sh_csi2_remove(struct platform_device *pdev) v4l2_device_unregister_subdev(priv-subdev); pm_runtime_disable(pdev-dev); - platform_set_drvdata(pdev, NULL); return 0; } -- 1.7.9.5 Ping... -- With warm regards, Sachin --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4] V4L2: soc_camera: Renesas R-Car VIN driver
On Sat, 18 May 2013, Sergei Shtylyov wrote: Hello. On 05/15/2013 09:44 AM, Guennadi Liakhovetski wrote: From: Vladimir Barinov vladimir.bari...@cogentembedded.com Add Renesas R-Car VIN (Video In) V4L2 driver. Based on the patch by Phil Edworthy phil.edwor...@renesas.com. Signed-off-by: Vladimir Barinov vladimir.bari...@cogentembedded.com [Sergei: removed deprecated IRQF_DISABLED flag, reordered/renamed 'enum chip_id' values, reordered rcar_vin_id_table[] entries, removed senseless parens from to_buf_list() macro, used ALIGN() macro in rcar_vin_setup(), added {} to the *if* statement and used 'bool' values instead of 0/1 where necessary, done some reformatting and clarified some comments.] Signed-off-by: Sergei Shtylyov sergei.shtyl...@cogentembedded.com --- This patch is against the 'media_tree.git' repo. Changes since version 3: Why aren't you using this: http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/63820 ? Thanks Guennadi We have now incorporated the needed changes and I will post the updated patch. I must note that you haven't managed to get rid of all CEU references in the shared soc_scale_crop.c module, both in the variable names and in the comments. Ok, I'll try to remember this and prepare an improved v2. Otherwise you're welcome to suggest an improvement. As long as those ceu occurrences aren't exposed in the API, it shouldn't affect users though. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: mt9p031 shows purple coloured capture
On Thu, 16 May 2013, Andrei Andreyanau wrote: Hi, Laurent, I have an issue with the mt9p031 camera. The kernel version I use uses soc camera framework as well as camera does. And I have the following thing which appears randomly while capturing the image using gstreamer. When I start the capture for the first time, it shows the correct image (live stream). When I stop and start it again it may show the image in purple (it can appear on the third or fourth time). Or it can show the correct image every time I start the capture. Do you have any idea why it appears so? Wrong clock or *sync polarity selection? Which leads to random start-of-frame misplacement? Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4] V4L2: soc_camera: Renesas R-Car VIN driver
Hi Sergei, Vladimir On Wed, 15 May 2013, Sergei Shtylyov wrote: From: Vladimir Barinov vladimir.bari...@cogentembedded.com Add Renesas R-Car VIN (Video In) V4L2 driver. Based on the patch by Phil Edworthy phil.edwor...@renesas.com. Signed-off-by: Vladimir Barinov vladimir.bari...@cogentembedded.com [Sergei: removed deprecated IRQF_DISABLED flag, reordered/renamed 'enum chip_id' values, reordered rcar_vin_id_table[] entries, removed senseless parens from to_buf_list() macro, used ALIGN() macro in rcar_vin_setup(), added {} to the *if* statement and used 'bool' values instead of 0/1 where necessary, done some reformatting and clarified some comments.] Signed-off-by: Sergei Shtylyov sergei.shtyl...@cogentembedded.com --- This patch is against the 'media_tree.git' repo. Changes since version 3: Why aren't you using this: http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/63820 ? Thanks Guennadi - removed the driver's dependency on R-Car M1A/H1 SoCs from Kconfig; - made the driver aware of the differences between R-Car E1/M1/H1 SoCs by having different platform device IDs for different SoCs, introcduced 'enum chips_id' to be used as the 'driver_data' field of 'struct platform_device_id' and then copied to the 'chip' field of 'struct rcar_vin_priv'; - sorted #include's alphabetically, added a number of #includes media/v4l2-*; - removed the 'data_through' field of the 'struct rcar_vin_priv' and the pass- through logic from set_fmt() method; - simplified is_continuous_transfer(), used it where applicable; - removed senseless parens from to_buf_list() macro; - removed the 'code' field from the 'struct rcar_vin_cam'; - largely rewrote the queue_setup() method; - removed 'input_is_yuv' variable from rcar_vin_setup(), made 'progressive' and 'output_is_yuv' variables 'bool', and made setting VnDMR.EXRGB bit only happen on R-Car E1/H1 there; - made use of ALIGN() macro in rcar_vin_setup() and rcar_vin_set_rect(); - fixed missing {} on one branch of the *if* statement in several places, added {} to the *if* statement where necessary; - stopped saving/restoring flags when grabbing/dropping a spinlock in the buf_queue() and buf_cleanup() methods; - made 'dsize' variable calculation depend on R-Car E1 in rcar_vin_set_rect() - fix the continuous capturing to stop when there is no buffer to be set into the VnMBm registers in rcar_vin_irq(); - replaced BUG_ON() with WARN_ON() and *return* in the remove() method, also replaced pm_runtime_put_sync() with pm_runtime_put() there; - removed size_dst() and calc_scale() as the calls to calc_scale() were also removed from the set_fmt() method; - removed the VnMC register value check from capture_restore(); - removed 'cfg' variable initializers from set_bus_param() method and rcar_vin_try_bus_param(); - added bus width check to rcar_vin_try_bus_param(); - removed V4L2_PIX_FMT_YUYV format from rcar_vin_formats[], initialize 'layout' field of every element in this table; - changed dev_err() call and *return* -EINVAL to dev_warn() and *return* 0 in the get_formats() method, - added rcar_vin_packing_supported() and started handling pass-through mode in the get_formats() method; - constified the parameters of is_smaller() and is_inside(); - redid the scaling logic so that it can't scale RGB32 data on R-Car E1 in the set_fmt() method, also stopped assigning to 'cam-code' there; - started selecting the current format if soc_camera_xlate_by_fourcc() call failed in the try_fmt() method, also started letting 'soc-camera' calculate bytes-per-line and image size there; - removed pm_runtime_resume() call from the driver's probe() method - added setting of the 'timestamp_type' field to the init_videobuf2() method. Changes since version 2: - replaced Cyrillic characters in comments with the proper Latinic ones. Changes since the original posting: - added IRQF_SHARED flag in devm_request_irq() call (since on R8A7778 VIN0/1 share the same IRQ) and removed deprecated IRQF_DISABLED flag. drivers/media/platform/soc_camera/Kconfig|7 drivers/media/platform/soc_camera/Makefile |1 drivers/media/platform/soc_camera/rcar_vin.c | 1814 +++ include/linux/platform_data/camera-rcar.h| 25 4 files changed, 1847 insertions(+) --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/1] mt9t031: Fix panic on probe
Hi Philippe On Wed, 8 May 2013, Philippe Rétornaz wrote: The video device is not yet valid when probe() is called. Call directly soc_camera_power_on/off() instead of calling mt9t031_s_power(). Signed-off-by: Philippe Rétornaz philippe.retor...@epfl.ch There is already a patch for this: https://patchwork.kernel.org/patch/2462501/ Thanks Guennadi --- drivers/media/i2c/soc_camera/mt9t031.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c index d80d044..71c0b16 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/media/i2c/soc_camera/mt9t031.c @@ -632,10 +632,11 @@ static int mt9t031_s_power(struct v4l2_subdev *sd, int on) static int mt9t031_video_probe(struct i2c_client *client) { struct mt9t031 *mt9t031 = to_mt9t031(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); s32 data; int ret; - ret = mt9t031_s_power(mt9t031-subdev, 1); + ret = soc_camera_power_on(client-dev, ssdd); if (ret 0) return ret; @@ -664,7 +665,7 @@ static int mt9t031_video_probe(struct i2c_client *client) ret = v4l2_ctrl_handler_setup(mt9t031-hdl); done: - mt9t031_s_power(mt9t031-subdev, 0); + soc_camera_power_off(client-dev, ssdd); return ret; } -- 1.7.9.5 --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/7] soc_camera/mx1_camera: Fix warnings related to spacing
On Wed, 3 Apr 2013, Sachin Kamat wrote: Fixes the following checkpatch warnings: WARNING: unnecessary whitespace before a quoted newline WARNING: please, no space before tabs Signed-off-by: Sachin Kamat sachin.ka...@linaro.org Thanks, all 7 queued for 3.11 Guennadi --- drivers/media/platform/soc_camera/mx1_camera.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c index 4389f43..a3fd8d6 100644 --- a/drivers/media/platform/soc_camera/mx1_camera.c +++ b/drivers/media/platform/soc_camera/mx1_camera.c @@ -776,7 +776,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev) /* request irq */ err = claim_fiq(fh); if (err) { - dev_err(pdev-dev, Camera interrupt register failed \n); + dev_err(pdev-dev, Camera interrupt register failed\n); goto exit_free_dma; } @@ -853,7 +853,7 @@ static int __exit mx1_camera_remove(struct platform_device *pdev) } static struct platform_driver mx1_camera_driver = { - .driver = { + .driver = { .name = DRIVER_NAME, }, .remove = __exit_p(mx1_camera_remove), -- 1.7.9.5 --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] [media] soc_camera: Constify dev_pm_ops in mt9t031.c
On Tue, 30 Apr 2013, Sachin Kamat wrote: Silences the following warning: WARNING: struct dev_pm_ops should normally be const Signed-off-by: Sachin Kamat sachin.ka...@linaro.org Thanks, both queued for 3.11 Guennadi --- drivers/media/i2c/soc_camera/mt9t031.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c index 26a15b8..191e3f1 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/media/i2c/soc_camera/mt9t031.c @@ -595,7 +595,7 @@ static int mt9t031_runtime_resume(struct device *dev) return 0; } -static struct dev_pm_ops mt9t031_dev_pm_ops = { +static const struct dev_pm_ops mt9t031_dev_pm_ops = { .runtime_suspend= mt9t031_runtime_suspend, .runtime_resume = mt9t031_runtime_resume, }; -- 1.7.9.5 --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] soc_camera: Add V4L2_MBUS_FMT_YUYV10_2X10 format
On Wed, 1 May 2013, phil.edwor...@renesas.com wrote: Hi Guennadi, From: Guennadi Liakhovetski g.liakhovet...@gmx.de To: phil.edwor...@renesas.com, Cc: linux-media@vger.kernel.org, Mauro Carvalho Chehab mche...@redhat.com Date: 26/04/2013 22:00 Subject: Re: [PATCH] soc_camera: Add V4L2_MBUS_FMT_YUYV10_2X10 format Hi Phil On Fri, 26 Apr 2013, phil.edwor...@renesas.com wrote: Hi Guennadi, snip Wow, what kind of host can pack two 10-bit samples into 3 bytes and write 3-byte pixels to memory? I think I might have misunderstood how this is used. From my understanding, the MBUS formats are used to describe the hardware interfaces to cameras, i.e. 2 samples of 10 bits. I guess that the fourcc field also determines what v4l2 format is required to capture this. No, not quite. This table describes default pass-through capture of video data on a media bus to memory. E.g. the first entry in the table means, that if you get the V4L2_MBUS_FMT_YUYV8_2X8 format on the bus, you sample 8 bits at a time, and store the samples 1-to-1 into RAM, you get the V4L2_PIX_FMT_YUYV format in your buffer. It can also describe some standard operations with the sampled data, like swapping the order, filling missing high bits (e.g. if you sample 10 bits but store 16 bits per sample with high 6 bits nullified). The table also specifies which bits are used for padding in the original data, e.g. V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE has SOC_MBUS_PACKING_2X8_PADLO, whereas V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE has SOC_MBUS_PACKING_2X8_PADHI, which means, that out of 16 bits of data, that you get when you sample an 8-bit bus twice, either low or high 6 bits are invalid and should be discarded. Ok, I see. However, is it necessary to provide a default pass-through v4l2 format? No, it's not. If no (soc-camera) host camera driver is willing to use this pass-through conversion, then it's not required. Ok, I'll look at that when I get a moment! I can't see a suitable v4l2 format! For the hardware I have been working on, there is always the option of converting the data to another format, so this is not really needed. I doubt that it makes sense to add yet another v4l2 format for userspace, when typical uses would involve the host hardware converting the format to something else, e.g. V4L2_PIX_FMT_RGB32. Up to you, really. If you don't need this default conversion, don't add it. Ok, it seems like it would be a bad idea to provide a default conversion that my not be supported by other hosts. Right, that table collects natural conversions, mostly just straightforward bus-to-buffer. In your case of 2 10-bit samples such a natural transfer would produce one 16-bit word per sample, of which only 10 bits are useful information. So, your 20 bits of pixel data would be located in bits 25:16 and 9:0 of each 32-bit (long)word. I don't think there is a fourcc code, describing such a buffer layout... It probably would be useless without a special conversion software. So, if there is not a natural conversion I do not populate the fourcc field, doesn't the other information in the soc_mbus_lookup struct becomes moot? Nothing can allocate a buffer for it, so nothing should be using the bits_per_sample, packing or order fields. Similarly, nothing should call soc_mbus_samples_per_pixel() with this format. By extension, there is no need to add SOC_MBUS_PACKING_2X10_PADHI to soc_mbus_bytes_per_line(). Maybe there is no _natural_ conversion, but your hardware can be able to handle this in a _special_ way. Then you allocate a specific instance of struct soc_mbus_pixelfmt in your driver for that conversion, similar to how, e.g. sh_mobile_ceu_camera.c uses its sh_mobile_ceu_formats[] array. Then you still can use soc_mbus_bytes_per_line() and soc_mbus_image_size() with that your special format descriptor. But for those you do need to define SOC_MBUS_PACKING_2X10_PADHI and teach them to use it. And please document this new packing well, because it's not a trivial one. Thanks Guennadi Since V4L2_MBUS_FMT_YUYV10_2X10 already exists without the above additional info, I guess there is no need for this patch at all. Thanks Phil --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 02/20] V4L2: support asynchronous subdevice registration
Hi Sascha On Tue, 30 Apr 2013, Sascha Hauer wrote: Hi Guennadi, On Fri, Apr 12, 2013 at 05:40:22PM +0200, Guennadi Liakhovetski wrote: Currently bridge device drivers register devices for all subdevices synchronously, tupically, during their probing. E.g. if an I2C CMOS sensor is attached to a video bridge device, the bridge driver will create an I2C device and wait for the respective I2C driver to probe. This makes linking of devices straight forward, but this approach cannot be used with intrinsically asynchronous and unordered device registration systems like the Flattened Device Tree. To support such systems this patch adds an asynchronous subdevice registration framework to V4L2. To use it respective (e.g. I2C) subdevice drivers must register themselves with the framework. A bridge driver on the other hand must register notification callbacks, that will be called upon various related events. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- + +static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier, + struct v4l2_async_subdev_list *asdl) +{ + struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl); + struct v4l2_async_subdev *asd = NULL; + bool (*match)(struct device *, + struct v4l2_async_hw_info *); + + list_for_each_entry (asd, notifier-waiting, list) { + struct v4l2_async_hw_info *hw = asd-hw; + + /* bus_type has been verified valid before */ + switch (hw-bus_type) { + case V4L2_ASYNC_BUS_CUSTOM: + match = hw-match.custom.match; + if (!match) + /* Match always */ + return asd; + break; + case V4L2_ASYNC_BUS_PLATFORM: + match = match_platform; + break; + case V4L2_ASYNC_BUS_I2C: + match = match_i2c; + break; + default: + /* Cannot happen, unless someone breaks us */ + WARN_ON(true); + return NULL; + } + + if (match match(sd-dev, hw)) + break; + } + + return asd; 'asd' can never be NULL here. You have to explicitly return NULL when leaving the loop without match. I've already proposed a fix for this and Laurent has proposed a simplified version. Thanks Guennadi Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/4] V4L2: soc_camera: Renesas R-Car VIN driver
On Tue, 30 Apr 2013, Vladimir Barinov wrote: [snip] +static int rcar_vin_init_videobuf2(struct vb2_queue *vq, + struct soc_camera_device *icd) +{ +vq-type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +vq-io_modes = VB2_MMAP | VB2_USERPTR; +vq-drv_priv = icd; +vq-ops = rcar_vin_vb2_ops; +vq-mem_ops = vb2_dma_contig_memops; +vq-buf_struct_size = sizeof(struct rcar_vin_buffer); Please, add vq-timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; There is not such field in struct vb2_queue. Please, look at the current kernel, e.g. the next tree, within days this will be in Linus' tree too. Mainline submissions should always be developed against the newest kernel version. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/4] V4L2: soc_camera: Renesas R-Car VIN driver
On Sun, 28 Apr 2013, Sergei Shtylyov wrote: send these patches patchwork.linuxtv.org -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 23/24] V4L2: mt9p031: add struct v4l2_subdev_platform_data to platform data
Hi Sascha On Fri, 26 Apr 2013, Sascha Hauer wrote: Hi Guennadi, On Mon, Apr 22, 2013 at 02:39:57PM +0200, Guennadi Liakhovetski wrote: On Mon, 22 Apr 2013, Laurent Pinchart wrote: Hi Guennadi, On Thursday 18 April 2013 23:47:26 Guennadi Liakhovetski wrote: On Thu, 18 Apr 2013, Guennadi Liakhovetski wrote: Adding struct v4l2_subdev_platform_data to mt9p031's platform data allows the driver to use generic functions to manage sensor power supplies. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de A small addition to this one too: to be absolutely honest, I also had to replace 12-bit formats with their 8-bit counterparts, because only 8 data lanes are connected to my camera host. We'll need to somehow properly solve this too. That information should be conveyed by platform/DT data for the host, and be used to convert the 12-bit media bus code into a 8-bit media bus code in the host (a core helper function would probably be helpful). Yes, and we discussed this before too, I think. I proposed based then to implement some compatibility table of trivial transformations, like a 12-bit Bayer, right-shifted by 4 bits, produces a respective 8-bit Bayer etc. Such transformations would fit nicely in soc_mediabus.c ;-) This just needs to be implemented... These trivial transformations may turn out not to be so trivial. In the devicetree we would then need kind of 'shift-4-bit-left' properties. We already have a data-shift property exactly for this purpose. How about instead describing the sensor node with: mbus-formats = 0x3010, 0x2013; and the corresponding host interface with: mbus-formats = 0x3013, 0x2001; How would this describe _how_ the transformation should be performed? And why does the host driver need mbus formats? The translation is from mbus formats to fourcc formats (in memory). If you use those as bridge DT node properties, that would only tell the bridge driver which mbus format to request from the subdevice when requested fourcc format X. This decision soc-camera currently performs automatically, if this is ever needed as a configuration parameter, we'll think then where and how to put it. Thanks Guennadi This would allow to describe arbitrary transformations without having to limit to the 'trivial' ones. The result would be easier to understand also I think. --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Kernel Patch:do not wait for interrupt when releasing buffers
On Fri, 26 Apr 2013, vishwanath chandapur wrote: Hi Guennadi, Thank you for reply Sorry that was typo mistake . Kernel Version :3.0.8 So, it is 3.0? Sorry, please update and re-test. Thanks Guennadi Br Vishwa On Fri, Apr 26, 2013 at 3:13 PM, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: Hi On Fri, 26 Apr 2013, vishwanath chandapur wrote: Hi, Sorry my english is poor. This is vishawanath , I have a bug in camera module,When ever vb is NULL in sh_mobile_ceu_irq. device will reboot. It seems there is a race condition ,Since we are not clearing the interrupt,the same interrupt occurs continuously and rate of interrupt is also high (30 per Micros seconds ),this not allowing to schedule other tasks ,Finally device reboots with WATCH DOG NMI interrupt. Help on this will be greatly appreciated,As we are struggling to solve this bug from last 2 months. Kernel Version :3.0.8 Sorry, do you _really_ mean kernel 3.0(.8)? Not 3.8(.0)? If so, I'm afraid, I have to ask you to re-test with a recent kernel - best with current Linus' mainline 3.9-rcX, at least with 3.8. If it was a typo and you did mean 3.8, please, try to re-send in such a way, that your patch doesn't get corrupt as in this your mail. Also, please, add Linux Media Mailing List linux-media@vger.kernel.org to CC. Thanks Guennadi Please let me for more info on this issue. if (!vb) /* Stale interrupt from a released buffer */ Reboot goto out; diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.cindex d890f8d..67c7dcd 100644--- a/drivers/media/video/sh_mobile_ceu_camera.c+++ b/drivers/media/video/sh_mobile_ceu_camera.c@@ -296,8 +306,8 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, dev_dbg(icd-dev, %s (vb=0x%p) 0x%08lx %zd\n, __func__, vb, vb-baddr, vb-bsize); -vb-state = VIDEOBUF_QUEUED; spin_lock_irqsave(pcdev-lock, flags);+vb-state = VIDEOBUF_QUEUED; list_add_tail(vb-queue, pcdev-capture); if (!pcdev-active) {@@ -311,6 +321,27 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) {+ struct soc_camera_device *icd = vq-priv_data;+ struct soc_camera_host *ici = to_soc_camera_host(icd-dev.parent);+ struct sh_mobile_ceu_dev *pcdev = ici-priv;+unsigned long flags;++ spin_lock_irqsave(pcdev-lock, flags);++ if (pcdev-active == vb) {+ /* disable capture (release DMA buffer), reset */+ ceu_write(pcdev, CAPSR, 1 16);+ pcdev-active = NULL;+ }++ if ((vb-state == VIDEOBUF_ACTIVE || vb-state == VIDEOBUF_QUEUED) + !list_empty(vb-queue)) {+ vb-state = VIDEOBUF_ERROR;+ list_del_init(vb-queue);+ }++ spin_unlock_irqrestore(pcdev-lock, flags);+ free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb)); } @@ -330,6 +361,10 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) spin_lock_irqsave(pcdev-lock, flags); vb = pcdev-active;+if (!vb)+ /* Stale interrupt from a released buffer */+goto out;+ list_del_init(vb-queue); if (!list_empty(pcdev-capture))@@ -344,6 +379,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) do_gettimeofday(vb-ts); vb-field_count++; wake_up(vb-done);++out: spin_unlock_irqrestore(pcdev-lock, flags); return IRQ_HANDLED; --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Kernel Patch:do not wait for interrupt when releasing buffers
On Fri, 26 Apr 2013, vishwanath chandapur wrote: Yes it is 3.0 please update and re-test. Please let me know which version i need to update, Please, see my first reply to you. Thanks Guennadi Thanks Vishwa On Fri, Apr 26, 2013 at 3:23 PM, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: On Fri, 26 Apr 2013, vishwanath chandapur wrote: Hi Guennadi, Thank you for reply Sorry that was typo mistake . Kernel Version :3.0.8 So, it is 3.0? Sorry, please update and re-test. Thanks Guennadi Br Vishwa On Fri, Apr 26, 2013 at 3:13 PM, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: Hi On Fri, 26 Apr 2013, vishwanath chandapur wrote: Hi, Sorry my english is poor. This is vishawanath , I have a bug in camera module,When ever vb is NULL in sh_mobile_ceu_irq. device will reboot. It seems there is a race condition ,Since we are not clearing the interrupt,the same interrupt occurs continuously and rate of interrupt is also high (30 per Micros seconds ),this not allowing to schedule other tasks ,Finally device reboots with WATCH DOG NMI interrupt. Help on this will be greatly appreciated,As we are struggling to solve this bug from last 2 months. Kernel Version :3.0.8 Sorry, do you _really_ mean kernel 3.0(.8)? Not 3.8(.0)? If so, I'm afraid, I have to ask you to re-test with a recent kernel - best with current Linus' mainline 3.9-rcX, at least with 3.8. If it was a typo and you did mean 3.8, please, try to re-send in such a way, that your patch doesn't get corrupt as in this your mail. Also, please, add Linux Media Mailing List linux-media@vger.kernel.org to CC. Thanks Guennadi Please let me for more info on this issue. if (!vb) /* Stale interrupt from a released buffer */ Reboot goto out; diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.cindex d890f8d..67c7dcd 100644--- a/drivers/media/video/sh_mobile_ceu_camera.c+++ b/drivers/media/video/sh_mobile_ceu_camera.c@@ -296,8 +306,8 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, dev_dbg(icd-dev, %s (vb=0x%p) 0x%08lx %zd\n, __func__, vb, vb-baddr, vb-bsize); -vb-state = VIDEOBUF_QUEUED; spin_lock_irqsave(pcdev-lock, flags);+vb-state = VIDEOBUF_QUEUED; list_add_tail(vb-queue, pcdev-capture); if (!pcdev-active) {@@ -311,6 +321,27 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) {+ struct soc_camera_device *icd = vq-priv_data;+ struct soc_camera_host *ici = to_soc_camera_host(icd-dev.parent);+ struct sh_mobile_ceu_dev *pcdev = ici-priv;+unsigned long flags;++ spin_lock_irqsave(pcdev-lock, flags);++ if (pcdev-active == vb) {+ /* disable capture (release DMA buffer), reset */+ ceu_write(pcdev, CAPSR, 1 16);+ pcdev-active = NULL;+ }++ if ((vb-state == VIDEOBUF_ACTIVE || vb-state == VIDEOBUF_QUEUED) + !list_empty(vb-queue)) {+ vb-state = VIDEOBUF_ERROR;+ list_del_init(vb-queue);+ }++ spin_unlock_irqrestore(pcdev-lock, flags);+ free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb)); } @@ -330,6 +361,10 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) spin_lock_irqsave(pcdev-lock, flags); vb = pcdev-active;+if (!vb)+ /* Stale interrupt from a released buffer */+goto out;+ list_del_init(vb-queue); if (!list_empty(pcdev-capture))@@ -344,6 +379,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) do_gettimeofday(vb-ts); vb-field_count++; wake_up(vb-done);++out: spin_unlock_irqrestore(pcdev-lock, flags); return IRQ_HANDLED; --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Kernel Patch:do not wait for interrupt when releasing buffers
On Fri, 26 Apr 2013, vishwanath chandapur wrote: Hi Thanks for support.One more last question Is this bug was known issue with old kernel(3.0). Don't remember hearing about or seeing such a problem, no. Thanks Guennadi Best Regards Vishwa On Fri, Apr 26, 2013 at 3:34 PM, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: On Fri, 26 Apr 2013, vishwanath chandapur wrote: Yes it is 3.0 please update and re-test. Please let me know which version i need to update, Please, see my first reply to you. Thanks Guennadi Thanks Vishwa On Fri, Apr 26, 2013 at 3:23 PM, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: On Fri, 26 Apr 2013, vishwanath chandapur wrote: Hi Guennadi, Thank you for reply Sorry that was typo mistake . Kernel Version :3.0.8 So, it is 3.0? Sorry, please update and re-test. Thanks Guennadi Br Vishwa On Fri, Apr 26, 2013 at 3:13 PM, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: Hi On Fri, 26 Apr 2013, vishwanath chandapur wrote: Hi, Sorry my english is poor. This is vishawanath , I have a bug in camera module,When ever vb is NULL in sh_mobile_ceu_irq. device will reboot. It seems there is a race condition ,Since we are not clearing the interrupt,the same interrupt occurs continuously and rate of interrupt is also high (30 per Micros seconds ),this not allowing to schedule other tasks ,Finally device reboots with WATCH DOG NMI interrupt. Help on this will be greatly appreciated,As we are struggling to solve this bug from last 2 months. Kernel Version :3.0.8 Sorry, do you _really_ mean kernel 3.0(.8)? Not 3.8(.0)? If so, I'm afraid, I have to ask you to re-test with a recent kernel - best with current Linus' mainline 3.9-rcX, at least with 3.8. If it was a typo and you did mean 3.8, please, try to re-send in such a way, that your patch doesn't get corrupt as in this your mail. Also, please, add Linux Media Mailing List linux-media@vger.kernel.org to CC. Thanks Guennadi Please let me for more info on this issue. if (!vb) /* Stale interrupt from a released buffer */ Reboot goto out; diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.cindex d890f8d..67c7dcd 100644--- a/drivers/media/video/sh_mobile_ceu_camera.c+++ b/drivers/media/video/sh_mobile_ceu_camera.c@@ -296,8 +306,8 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, dev_dbg(icd-dev, %s (vb=0x%p) 0x%08lx %zd\n, __func__, vb, vb-baddr, vb-bsize); -vb-state = VIDEOBUF_QUEUED; spin_lock_irqsave(pcdev-lock, flags);+vb-state = VIDEOBUF_QUEUED; list_add_tail(vb-queue, pcdev-capture); if (!pcdev-active) {@@ -311,6 +321,27 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) {+ struct soc_camera_device *icd = vq-priv_data;+ struct soc_camera_host *ici = to_soc_camera_host(icd-dev.parent);+ struct sh_mobile_ceu_dev *pcdev = ici-priv;+unsigned long flags;++ spin_lock_irqsave(pcdev-lock, flags);++ if (pcdev-active == vb) {+ /* disable capture (release DMA buffer), reset */+ ceu_write(pcdev, CAPSR, 1 16);+ pcdev-active = NULL;+ }++ if ((vb-state == VIDEOBUF_ACTIVE || vb-state == VIDEOBUF_QUEUED) + !list_empty(vb-queue)) {+ vb-state = VIDEOBUF_ERROR;+ list_del_init(vb-queue);+ }++ spin_unlock_irqrestore(pcdev-lock, flags);+ free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb)); } @@ -330,6 +361,10 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) spin_lock_irqsave(pcdev-lock, flags); vb = pcdev-active;+if (!vb)+ /* Stale interrupt from a released buffer */+goto out;+ list_del_init(vb-queue); if (!list_empty(pcdev-capture))@@ -344,6 +379,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) do_gettimeofday(vb-ts); vb-field_count++; wake_up(vb-done);++out: spin_unlock_irqrestore(pcdev-lock, flags); return
Re: [PATCH] soc_camera: Add V4L2_MBUS_FMT_YUYV10_2X10 format
Hi Phil On Fri, 26 Apr 2013, phil.edwor...@renesas.com wrote: Hi Guennadi, snip Wow, what kind of host can pack two 10-bit samples into 3 bytes and write 3-byte pixels to memory? I think I might have misunderstood how this is used. From my understanding, the MBUS formats are used to describe the hardware interfaces to cameras, i.e. 2 samples of 10 bits. I guess that the fourcc field also determines what v4l2 format is required to capture this. No, not quite. This table describes default pass-through capture of video data on a media bus to memory. E.g. the first entry in the table means, that if you get the V4L2_MBUS_FMT_YUYV8_2X8 format on the bus, you sample 8 bits at a time, and store the samples 1-to-1 into RAM, you get the V4L2_PIX_FMT_YUYV format in your buffer. It can also describe some standard operations with the sampled data, like swapping the order, filling missing high bits (e.g. if you sample 10 bits but store 16 bits per sample with high 6 bits nullified). The table also specifies which bits are used for padding in the original data, e.g. V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE has SOC_MBUS_PACKING_2X8_PADLO, whereas V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE has SOC_MBUS_PACKING_2X8_PADHI, which means, that out of 16 bits of data, that you get when you sample an 8-bit bus twice, either low or high 6 bits are invalid and should be discarded. Ok, I see. However, is it necessary to provide a default pass-through v4l2 format? No, it's not. If no (soc-camera) host camera driver is willing to use this pass-through conversion, then it's not required. Ok, I'll look at that when I get a moment! I can't see a suitable v4l2 format! For the hardware I have been working on, there is always the option of converting the data to another format, so this is not really needed. I doubt that it makes sense to add yet another v4l2 format for userspace, when typical uses would involve the host hardware converting the format to something else, e.g. V4L2_PIX_FMT_RGB32. Up to you, really. If you don't need this default conversion, don't add it. Ok, it seems like it would be a bad idea to provide a default conversion that my not be supported by other hosts. Right, that table collects natural conversions, mostly just straightforward bus-to-buffer. In your case of 2 10-bit samples such a natural transfer would produce one 16-bit word per sample, of which only 10 bits are useful information. So, your 20 bits of pixel data would be located in bits 25:16 and 9:0 of each 32-bit (long)word. I don't think there is a fourcc code, describing such a buffer layout... It probably would be useless without a special conversion software. Thanks Guennadi However, I am not sure how the two relate to each other. How does the above code imply 3 bytes? Not the above code, but your entry in the soc_mbus_bytes_per_line() function below, where you multiply width * 3. It looks like hosts use soc_mbus_bytes_per_line() to report the size of video buffers needed. Shouldn't the hosts report the buffer metrics for the v4l2 format, since that is what will be output? What has this to do with the MBUS specifics? struct soc_mbus_pixelfmt describes a conversion from an MBUS code to a pixel format in memory. Camera host drivers call that function with a _suitable_ conversion descriptor (either a standard or a special one) and the function calculates the number of bytes. Right, I think I understand! Thanks Phil --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 02/20] V4L2: support asynchronous subdevice registration
Hi Sascha On Fri, 26 Apr 2013, Sascha Hauer wrote: Hi Guennadi, On Fri, Apr 12, 2013 at 05:40:22PM +0200, Guennadi Liakhovetski wrote: + +static bool match_i2c(struct device *dev, struct v4l2_async_hw_info *hw_dev) +{ + struct i2c_client *client = i2c_verify_client(dev); + return client + hw_dev-bus_type == V4L2_ASYNC_BUS_I2C + hw_dev-match.i2c.adapter_id == client-adapter-nr + hw_dev-match.i2c.address == client-addr; +} + +static bool match_platform(struct device *dev, struct v4l2_async_hw_info *hw_dev) +{ + return hw_dev-bus_type == V4L2_ASYNC_BUS_PLATFORM + !strcmp(hw_dev-match.platform.name, dev_name(dev)); +} I recently solved the same problem without being aware of your series. How about registering the asynchronous subdevices with a 'void *key' instead of a bus specific matching function? Personally I don't think adding dummy data is a good idea. You can of course use pointers to real data, even just to the device object itself. But I really was trying to unbind host and subdevice devices, similar how clocks or pinmux entries or regulators are matched to their users. In the DT case we already use phandles to bind entities / pads / in whatever terms you prefer to think;-) Thanks Guennadi With platform based devices the key could simply be a pointer to some dummy value which is used by both the subdevice and the device in its platform_data. for the shmobile patch you have later in this series this would become: static int csi2_r2025sd_key; static struct r2025sd_platform_data r2025sd_pdata { .key = csi2_r2025sd_key, }; static struct i2c_board_info i2c1_devices[] = { { I2C_BOARD_INFO(r2025sd, 0x32), .platform_data = r2025sd_pdata, }, }; static struct sh_csi2_pdata csi2_info = { .flags = SH_CSI2_ECC | SH_CSI2_CRC, .key = csi2_r2025sd_key, }; For devicetree based devices the pointer to the subdevices devicenode could be used as key. I think this would make your matching code easier and also bus type agnostic. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] soc_camera: Add V4L2_MBUS_FMT_YUYV10_2X10 format
--- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] soc_camera: Add V4L2_MBUS_FMT_YUYV10_2X10 format
SOC_MBUS_PACKING_EXTEND16: return width * 2; + case SOC_MBUS_PACKING_2X10_PADHI: + return width * 3; case SOC_MBUS_PACKING_1_5X8: return width * 3 / 2; case SOC_MBUS_PACKING_VARIABLE: diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h index d33f6d0..b131a47 100644 --- a/include/media/soc_mediabus.h +++ b/include/media/soc_mediabus.h @@ -21,6 +21,8 @@ * @SOC_MBUS_PACKING_2X8_PADHI: 16 bits transferred in 2 8-bit samples, in the *possibly incomplete byte high bits are padding * @SOC_MBUS_PACKING_2X8_PADLO: as above, but low bits are padding + * @SOC_MBUS_PACKING_2X10_PADHI:20 bits transferred in 2 10-bit samples. The A TAB is missing after :? Ok. I just came to make this changes, however the text for SOC_MBUS_PACKING_2X10_PADHI is in line with the surrounding text. Would you like all of the other comments to be indented with another tab? Ah right, sorry, no, then please don't. Thanks Guennadi + *high bits are padding * @SOC_MBUS_PACKING_EXTEND16: sample width (e.g., 10 bits) has to be extended *to 16 bits * @SOC_MBUS_PACKING_VARIABLE: compressed formats with variable packing @@ -33,6 +35,7 @@ enum soc_mbus_packing { SOC_MBUS_PACKING_NONE, SOC_MBUS_PACKING_2X8_PADHI, SOC_MBUS_PACKING_2X8_PADLO, + SOC_MBUS_PACKING_2X10_PADHI, SOC_MBUS_PACKING_EXTEND16, SOC_MBUS_PACKING_VARIABLE, SOC_MBUS_PACKING_1_5X8, -- 1.7.5.4 Thanks Phil --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] V4L2: soc-camera: remove unneeded include path
soc-camera isn't sufficiently broken to include any files from the drivers/media/i2c/soc_camera directory in its core or host driver files:-) Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/Makefile |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile index 136b7f8..bedb042 100644 --- a/drivers/media/platform/soc_camera/Makefile +++ b/drivers/media/platform/soc_camera/Makefile @@ -10,5 +10,3 @@ obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o - -ccflags-y += -I$(srctree)/drivers/media/i2c/soc_camera -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] soc-camera: common cropping and scaling helpers
Hi Recently a VIN soc-camera host driver has been submitted, that was based on the sh_mobile_ceu_camera driver and as such it copied some of its functions with no or very little change. This patch set extracts those functions to make them available for other soc-camera drivers too. Those functions deal with optimal cropping and scaling configuration of the host and the client. It isn't easy to get this right, so, it is better to have these routines centrally to get a better test coverage and not to have to fix or extend each driver separately. The way these patches are organised is to make it simple to follow changes and avoid any breakage. The first one modifies the functions in-place, preparing them for extraction. The second one really just moves them out into a separate file without any further changes. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] V4L2: sh_mobile_ceu_camera: remove CEU specific data from generic functions
Several functions in the sh_mobile_ceu_camera driver implement generic algorithms and can be re-used by other V4L2 camera host drivers too. These functions attempt to optimise scaling and cropping functions of the subdevice, e.g. a camera sensor. This patch makes those functions generic for future re-use by other camera host drivers. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- .../platform/soc_camera/sh_mobile_ceu_camera.c | 130 +++- 1 files changed, 71 insertions(+), 59 deletions(-) diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 99d9029..4de3e7f 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1005,7 +1005,7 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt) fmt-packing == SOC_MBUS_PACKING_EXTEND16); } -static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); +static int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl) { @@ -1084,7 +1084,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int /* FIXME: subwindow is lost between close / open */ /* Cache current client geometry */ - ret = client_g_rect(sd, rect); + ret = soc_camera_client_g_rect(sd, rect); if (ret 0) return ret; @@ -1208,18 +1208,23 @@ static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2) r1-top + r1-height r2-top + r2-height; } -static unsigned int scale_down(unsigned int size, unsigned int scale) +static unsigned int soc_camera_shift_scale(unsigned int size, unsigned int shift, + unsigned int scale) { - return (size * 4096 + scale / 2) / scale; + return ((size shift) + scale / 2) / scale; } -static unsigned int calc_generic_scale(unsigned int input, unsigned int output) +static unsigned int soc_camera_calc_scale(unsigned int input, unsigned int shift, + unsigned int output) { - return (input * 4096 + output / 2) / output; + return soc_camera_shift_scale(input, shift, output); } +#define scale_down(size, scale) soc_camera_shift_scale(size, 12, scale) +#define calc_generic_scale(in, out) soc_camera_shift_scale(in, 12, out) + /* Get and store current client crop */ -static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect) +static int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect) { struct v4l2_crop crop; struct v4l2_cropcap cap; @@ -1244,10 +1249,8 @@ static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect) } /* Client crop has changed, update our sub-rectangle to remain within the area */ -static void update_subrect(struct sh_mobile_ceu_cam *cam) +static void update_subrect(struct v4l2_rect *rect, struct v4l2_rect *subrect) { - struct v4l2_rect *rect = cam-rect, *subrect = cam-subrect; - if (rect-width subrect-width) subrect-width = rect-width; @@ -1275,19 +1278,18 @@ static void update_subrect(struct sh_mobile_ceu_cam *cam) * 2. if (1) failed, try to double the client image until we get one big enough * 3. if (2) failed, try to request the maximum image */ -static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop, -struct v4l2_crop *cam_crop) +static int soc_camera_client_s_crop(struct v4l2_subdev *sd, + struct v4l2_crop *crop, struct v4l2_crop *cam_crop, + struct v4l2_rect *target_rect, struct v4l2_rect *subrect) { - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct v4l2_rect *rect = crop-c, *cam_rect = cam_crop-c; struct device *dev = sd-v4l2_dev-dev; - struct sh_mobile_ceu_cam *cam = icd-host_priv; struct v4l2_cropcap cap; int ret; unsigned int width, height; v4l2_subdev_call(sd, video, s_crop, crop); - ret = client_g_rect(sd, cam_rect); + ret = soc_camera_client_g_rect(sd, cam_rect); if (ret 0) return ret; @@ -1299,7 +1301,7 @@ static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop, /* Even if camera S_CROP failed, but camera rectangle matches */ dev_dbg(dev, Camera S_CROP successful for %dx%d@%d:%d\n, rect-width, rect-height, rect-left, rect-top); - cam-rect = *cam_rect; + *target_rect = *cam_rect; return 0; } @@ -1365,7 +1367,7 @@ static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop
[PATCH 2/2] V4L2: soc-camera: move generic functions into a separate file
The sh_mobile_ceu_camera driver implements a generic algorithm for setting up an optimal client and host scaling and cropping configuration. This patch makes those functions available for all drivers. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/platform/soc_camera/Kconfig |4 + drivers/media/platform/soc_camera/Makefile |4 + .../platform/soc_camera/sh_mobile_ceu_camera.c | 391 +--- drivers/media/platform/soc_camera/soc_scale_crop.c | 401 drivers/media/platform/soc_camera/soc_scale_crop.h | 47 +++ 5 files changed, 459 insertions(+), 388 deletions(-) create mode 100644 drivers/media/platform/soc_camera/soc_scale_crop.c create mode 100644 drivers/media/platform/soc_camera/soc_scale_crop.h diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig index b139b52..99f1952 100644 --- a/drivers/media/platform/soc_camera/Kconfig +++ b/drivers/media/platform/soc_camera/Kconfig @@ -8,6 +8,9 @@ config SOC_CAMERA over a bus like PCI or USB. For example some i2c camera connected directly to the data bus of an SoC. +config SOC_CAMERA_SCALE_CROP + tristate + config SOC_CAMERA_PLATFORM tristate platform camera support depends on SOC_CAMERA @@ -55,6 +58,7 @@ config VIDEO_SH_MOBILE_CEU tristate SuperH Mobile CEU Interface driver depends on VIDEO_DEV SOC_CAMERA HAS_DMA HAVE_CLK select VIDEOBUF2_DMA_CONTIG + select SOC_CAMERA_SCALE_CROP ---help--- This is a v4l2 driver for the SuperH Mobile CEU Interface diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile index bedb042..3918622 100644 --- a/drivers/media/platform/soc_camera/Makefile +++ b/drivers/media/platform/soc_camera/Makefile @@ -1,4 +1,8 @@ obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o +obj-$(CONFIG_SOC_CAMERA_SCALE_CROP)+= soc_scale_crop.o + +# a platform subdevice driver stub, allowing to support cameras by adding a +# couple of callback functions to the board code obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o # soc-camera host drivers have to be linked after camera drivers diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 4de3e7f..ebd73f9 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -46,6 +46,8 @@ #include media/v4l2-mediabus.h #include media/soc_mediabus.h +#include soc_scale_crop.h + /* register offsets for sh7722 / sh7723 */ #define CAPSR 0x00 /* Capture start register */ @@ -1005,8 +1007,6 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt) fmt-packing == SOC_MBUS_PACKING_EXTEND16); } -static int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); - static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl) { return container_of(ctrl-handler, struct soc_camera_device, @@ -1194,344 +1194,8 @@ static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd) icd-host_priv = NULL; } -/* Check if any dimension of r1 is smaller than respective one of r2 */ -static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2) -{ - return r1-width r2-width || r1-height r2-height; -} - -/* Check if r1 fails to cover r2 */ -static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2) -{ - return r1-left r2-left || r1-top r2-top || - r1-left + r1-width r2-left + r2-width || - r1-top + r1-height r2-top + r2-height; -} - -static unsigned int soc_camera_shift_scale(unsigned int size, unsigned int shift, - unsigned int scale) -{ - return ((size shift) + scale / 2) / scale; -} - -static unsigned int soc_camera_calc_scale(unsigned int input, unsigned int shift, - unsigned int output) -{ - return soc_camera_shift_scale(input, shift, output); -} - #define scale_down(size, scale) soc_camera_shift_scale(size, 12, scale) -#define calc_generic_scale(in, out) soc_camera_shift_scale(in, 12, out) - -/* Get and store current client crop */ -static int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect) -{ - struct v4l2_crop crop; - struct v4l2_cropcap cap; - int ret; - - crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = v4l2_subdev_call(sd, video, g_crop, crop); - if (!ret) { - *rect = crop.c; - return ret; - } - - /* Camera driver doesn't support .g_crop(), assume default rectangle */ - cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = v4l2_subdev_call(sd, video, cropcap, cap
Re: [PATCH] soc_camera: Add V4L2_MBUS_FMT_YUYV10_2X10 format
Hi Phil Thanks for the patch. On Wed, 17 Apr 2013, Phil Edworthy wrote: The V4L2_MBUS_FMT_YUYV10_2X10 format has already been added to mediabus, so this patch just adds SoC camera support. Signed-off-by: Phil Edworthy phil.edwor...@renesas.com --- drivers/media/platform/soc_camera/soc_mediabus.c | 15 +++ include/media/soc_mediabus.h |3 +++ 2 files changed, 18 insertions(+), 0 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c index 7569e77..be47d41 100644 --- a/drivers/media/platform/soc_camera/soc_mediabus.c +++ b/drivers/media/platform/soc_camera/soc_mediabus.c @@ -57,6 +57,15 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { + .code = V4L2_MBUS_FMT_YUYV10_2X10, + .fmt = { + .fourcc = V4L2_PIX_FMT_YUYV, + .name = YUYV, + .bits_per_sample= 10, + .packing= SOC_MBUS_PACKING_2X10_PADHI, Wow, what kind of host can pack two 10-bit samples into 3 bytes and write 3-byte pixels to memory? + .order = SOC_MBUS_ORDER_LE, + }, +}, { .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555, @@ -403,6 +412,10 @@ int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf, *numerator = 2; *denominator = 1; return 0; + case SOC_MBUS_PACKING_2X10_PADHI: + *numerator = 3; + *denominator = 1; Why 3? it's 2 samples per pixel, right? Should be *numerator = 2 above? + return 0; case SOC_MBUS_PACKING_1_5X8: *numerator = 3; *denominator = 2; @@ -428,6 +441,8 @@ s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) case SOC_MBUS_PACKING_2X8_PADLO: case SOC_MBUS_PACKING_EXTEND16: return width * 2; + case SOC_MBUS_PACKING_2X10_PADHI: + return width * 3; case SOC_MBUS_PACKING_1_5X8: return width * 3 / 2; case SOC_MBUS_PACKING_VARIABLE: diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h index d33f6d0..b131a47 100644 --- a/include/media/soc_mediabus.h +++ b/include/media/soc_mediabus.h @@ -21,6 +21,8 @@ * @SOC_MBUS_PACKING_2X8_PADHI: 16 bits transferred in 2 8-bit samples, in the * possibly incomplete byte high bits are padding * @SOC_MBUS_PACKING_2X8_PADLO: as above, but low bits are padding + * @SOC_MBUS_PACKING_2X10_PADHI:20 bits transferred in 2 10-bit samples. The A TAB is missing after :? + * high bits are padding * @SOC_MBUS_PACKING_EXTEND16: sample width (e.g., 10 bits) has to be extended * to 16 bits * @SOC_MBUS_PACKING_VARIABLE: compressed formats with variable packing @@ -33,6 +35,7 @@ enum soc_mbus_packing { SOC_MBUS_PACKING_NONE, SOC_MBUS_PACKING_2X8_PADHI, SOC_MBUS_PACKING_2X8_PADLO, + SOC_MBUS_PACKING_2X10_PADHI, SOC_MBUS_PACKING_EXTEND16, SOC_MBUS_PACKING_VARIABLE, SOC_MBUS_PACKING_1_5X8, -- 1.7.5.4 Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/3] Fix some bugs in the sh_veu driver
Hi Matsubara-san On Tue, 23 Apr 2013, Katsuya Matsubara wrote: Hi Guennadi, This patch set fixes some small bugs in the sh_veu driver. They have been tested on the Mackerel board. Thanks, Katsuya Matsubara (3): [media] sh_veu: invoke v4l2_m2m_job_finish() even if a job has been aborted [media] sh_veu: keep power supply until the m2m context is released [media] sh_veu: fix the buffer size calculation Thanks for your patches. I don't think we should push them to 3.9, I'll get them queued to 3.10 as fixes, after 3.9 is released we can also send them to stable, do you think they are important enough? Thanks Guennadi drivers/media/platform/sh_veu.c | 15 ++- 1 files changed, 6 insertions(+), 9 deletions(-) --- Katsuya Matsubara / IGEL Co., Ltd --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 02/20] V4L2: support asynchronous subdevice registration
Hi Laurent On Mon, 22 Apr 2013, Laurent Pinchart wrote: Hi Guennadi and Sylwester, On Monday 15 April 2013 13:57:17 Sylwester Nawrocki wrote: On 04/12/2013 05:40 PM, Guennadi Liakhovetski wrote: [snip] + + if (notifier-unbind) + notifier-unbind(notifier, asdl); + } + + mutex_unlock(list_lock); + + if (dev) { + while (i--) { + if (dev[i] device_attach(dev[i]) 0) This is my last major pain point. To avoid race conditions we need circular references (see http://www.mail-archive.com/linux-media@vger.kernel.org/msg61092.html). We will thus need a way to break the circle by explictly requesting the subdev to release its resources. I'm afraid I have no well-designed solution for that at the moment. I think we really can design the framework to allow a _safe_ unloading of the bridge driver. An rmmod run is not an immediate death - we have time to clean up and release all resources properly. As an example, I just had a network interface running, but rmmod-ing of one of hardware drivers just safely destroyed the interface. In our case, rmmod bridge should just signal the subdevice to release the clock reference. Whether we have the required - is a separate question. Currently a call to v4l2_clk_get() increments the clock owner use-count. This isn't a problem for soc-camera, since there the soc-camera core owns the clock. For other bridge drivers they would probably own the clock themselves, so, incrementing their use-count would block their modules in memory. To avoid that we have to remove that use-count incrementing. The crash, described in the referenced mail can happen if the subdevice driver calls (typically) v4l2_clk_enable() on a clock, that's already been freed. Wouldn't a locked look-up in the global clock list in v4l2-clk.c prevent such a crash? E.g. int v4l2_clk_enable(struct v4l2_clk *clk) { struct v4l2_clk *tmp; int ret = -ENODEV; mutex_lock(clk_lock); list_for_each_entry(tmp, clk_list, list) if (tmp == clk) { ret = !try_module_get(clk-ops-owner); if (ret) ret = -EFAULT; break; } mutex_unlock(clk_lock); if (ret 0) return ret; ... } We'd have to do a similar locked look-up in v4l2_clk_put(). Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: AT91SAM9M10: Problem porting driver for MT9P031 sensor
Hi Marcio On Tue, 23 Apr 2013, Marcio Campos de Lima wrote: Hi Guennadi What is the Linux version that has all of your patches already applied? Where can I download it? You can pull the tmp-mt9p031-dontuse branch of git://linuxtv.org/gliakhovetski/v4l-dvb.git I'd be grateful if you let me know, when you've pulled it. I'd like to remove it again ASAP, because this is only a temporary branch created only for you to play with. Nobody else should use it, most commits in it will not go into the mainline. If you don't tell me anything I'll remove it anyway within the next couple of days. Thanks Guennadi Thanks Marcio On 19/04/13 10:42, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: On Thu, 18 Apr 2013, Marcio Campos de Lima wrote: Hi Guennadi Thanks a lot for your attention. I think I cannot apply the patches. My Linux sources, downloaded from www.at91.com, does not have the V4l2-async.h header and, I suppose, many others headers. The MT9P031 sources have been modified and it is in a different tree. Can you tell me where I can download an already patched Kernel 3.6.9 which I can add theses functionality to the driver I am using? Hm, no, sorry, today isn't your lucky day. I don't think I can help you with a 3.6 kernel. Thanks Guennadi By the way, our MT9P031 sensor board has 10-bit format. I have fixed already. Regards MArcio On 18/04/13 19:44, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: Hi Marcio On Thu, 18 Apr 2013, Marcio Campos de Lima wrote: Hi I am porting the MT9P031 sensor device driver for a custom designed board based at the AT91SAM9M45-EK development board and Linux 3.6.9. The driver detects the sensor but does not create /dev/video1. Can anybody help me? Congratulations, today is your lucky day :-) I've just posted a patch-series http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/6 35 04 to do exactly what you need. Well, 99% of what you need :) With at91 you're using the atmel-isi soc-camera camera host driver. Shich isn't extended by this patch series to support the asynchronous subdevice registration, but it's rather easy to add, please, have a look at patch #15 for an example, based on the mx3_camera driver. Then there's a slight problem of mt9p031 only exporting 12-bit formats. You can fix it internally by substituting 8-bit formats (you are using 8 bits, right?) instead. We'll need a proper solution at some point. The last patch in the series shows how to add support for the mt9p031 sensor to a board. Anyway, give it a try, feel free to ask. Thanks Guennadi Thanks Marcio This is the probe code fo the driver if this can help: /* --- -- -- -- * Driver initialization and probing */ static int mt9p031_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct mt9p031_platform_data *pdata = client-dev.platform_data; struct i2c_adapter *adapter = to_i2c_adapter(client-dev.parent); struct mt9p031 *mt9p031; unsigned int i; int ret; if (pdata == NULL) { dev_err(client-dev, No platform data\n); return -EINVAL; } if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_warn(client-dev, I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n); return -EIO; } mt9p031 = kzalloc(sizeof(*mt9p031), GFP_KERNEL); if (mt9p031 == NULL) return -ENOMEM; mt9p031-pdata = pdata; mt9p031-output_control = MT9P031_OUTPUT_CONTROL_DEF; mt9p031-mode2 = MT9P031_READ_MODE_2_ROW_BLC; v4l2_ctrl_handler_init(mt9p031-ctrls, ARRAY_SIZE(mt9p031_ctrls) + 4); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN, MT9P031_SHUTTER_WIDTH_MAX, 1, MT9P031_SHUTTER_WIDTH_DEF); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_GAIN, MT9P031_GLOBAL_GAIN_MIN, MT9P031_GLOBAL_GAIN_MAX, 1, MT9P031_GLOBAL_GAIN_DEF); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); for (i = 0; i ARRAY_SIZE(mt9p031_ctrls); ++i) v4l2_ctrl_new_custom(mt9p031-ctrls, mt9p031_ctrls[i], NULL); mt9p031-subdev.ctrl_handler
Re: [PATCH RFC v2 1/4] media: i2c: adv7343: add support for asynchronous probing
Hi Prabhakar On Mon, 22 Apr 2013, Prabhakar Lad wrote: From: Lad, Prabhakar prabhakar.cse...@gmail.com Both synchronous and asynchronous adv7343 subdevice probing is supported by this patch. Signed-off-by: Lad, Prabhakar prabhakar.cse...@gmail.com Cc: Guennadi Liakhovetski g.liakhovet...@gmx.de Cc: Laurent Pinchart laurent.pinch...@ideasonboard.com Cc: Hans Verkuil hverk...@xs4all.nl Cc: Sakari Ailus sakari.ai...@iki.fi Cc: Mauro Carvalho Chehab mche...@redhat.com --- drivers/media/i2c/adv7343.c | 17 + 1 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c index 9fc2b98..5b1417b 100644 --- a/drivers/media/i2c/adv7343.c +++ b/drivers/media/i2c/adv7343.c @@ -27,6 +27,7 @@ #include linux/uaccess.h #include media/adv7343.h +#include media/v4l2-async.h #include media/v4l2-device.h #include media/v4l2-chip-ident.h #include media/v4l2-ctrls.h @@ -44,6 +45,7 @@ struct adv7343_state { struct v4l2_subdev sd; struct v4l2_ctrl_handler hdl; const struct adv7343_platform_data *pdata; + struct v4l2_async_subdev_list asdl; Do you still need this? Don't think it's needed any more with the latest V4L2-async version. Thanks Guennadi u8 reg00; u8 reg01; u8 reg02; @@ -455,16 +457,22 @@ static int adv7343_probe(struct i2c_client *client, ADV7343_GAIN_DEF); state-sd.ctrl_handler = state-hdl; if (state-hdl.error) { - int err = state-hdl.error; - - v4l2_ctrl_handler_free(state-hdl); - return err; + err = state-hdl.error; + goto done; } v4l2_ctrl_handler_setup(state-hdl); err = adv7343_initialize(state-sd); if (err) + goto done; + + state-sd.dev = client-dev; + err = v4l2_async_register_subdev(state-sd); + +done: + if (err 0) v4l2_ctrl_handler_free(state-hdl); + return err; } @@ -473,6 +481,7 @@ static int adv7343_remove(struct i2c_client *client) struct v4l2_subdev *sd = i2c_get_clientdata(client); struct adv7343_state *state = to_state(sd); + v4l2_async_unregister_subdev(state-sd); v4l2_device_unregister_subdev(sd); v4l2_ctrl_handler_free(state-hdl); -- 1.7.4.1 --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] V4L2: fix subdevice matching in asynchronous probing
On Mon, 22 Apr 2013, Laurent Pinchart wrote: Hi Guennadi, On Friday 19 April 2013 16:41:02 Guennadi Liakhovetski wrote: A wrapped list iterating loop hasn't been correctly recognised in v4l2_async_belongs(), which led to false positives. Fix the bug by verifying the loop termination condition. Reported-by: Prabhakar Lad prabhakar.cse...@gmail.com Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- Prabhakar, please, check, whether this fixes your problem. drivers/media/v4l2-core/v4l2-async.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 5d6b428..5631944 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -76,6 +76,10 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier * break; } + if (asd-list == notifier-waiting) + /* Wrapped - no match found */ + return NULL; + return asd; } What about just if (match match(sd-dev, hw)) return asd; } return NULL; } That's a bit simpler. Well, if it were simpler, it would've occurred to me instead of the other more complex solution, tight? ;-) No, sure, looks better, thanks! As soon as the actual patches are approved in principle, I'll merge this into them. Regards Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 18/24] V4L2: mt9p031: power down the sensor if no supported device has been detected
Hi Laurent On Mon, 22 Apr 2013, Laurent Pinchart wrote: Hi Guennadi, Thanks for the patch. On Thursday 18 April 2013 23:35:39 Guennadi Liakhovetski wrote: The mt9p031 driver first accesses the I2C device in its .registered() method. While doing that it furst powers the device up, but if probing s/furst/first/ fails, it doesn't power the chip back down. This patch fixes that bug. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- drivers/media/i2c/mt9p031.c | 10 ++ 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index eb2de22..70f4525 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -844,7 +844,7 @@ static int mt9p031_registered(struct v4l2_subdev *subdev) ret = mt9p031_power_on(mt9p031); if (ret 0) { dev_err(client-dev, MT9P031 power up failed\n); - return ret; + goto done; Not here. If power on fails, there's no need to power off. Oops, right. } /* Read out the chip version register */ @@ -852,13 +852,15 @@ static int mt9p031_registered(struct v4l2_subdev *subdev) if (data != MT9P031_CHIP_VERSION_VALUE) { dev_err(client-dev, MT9P031 not detected, wrong version 0x%04x\n, data); - return -ENODEV; + ret = -ENODEV; } +done: mt9p031_power_off(mt9p031); - dev_info(client-dev, MT9P031 detected at address 0x%02x\n, -client-addr); + if (!ret) + dev_info(client-dev, MT9P031 detected at address 0x%02x\n, +client-addr); return ret; } It would be easier to just move the power off line right after the mt9p031_read() call and leave the rest unchanged. Sure, please, do. Thanks Guennadi diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index 28cf95b..8de84c0 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -849,18 +849,18 @@ static int mt9p031_registered(struct v4l2_subdev *subdev) /* Read out the chip version register */ data = mt9p031_read(client, MT9P031_CHIP_VERSION); + mt9p031_power_off(mt9p031); + if (data != MT9P031_CHIP_VERSION_VALUE) { dev_err(client-dev, MT9P031 not detected, wrong version 0x%04x\n, data); return -ENODEV; } - mt9p031_power_off(mt9p031); - dev_info(client-dev, MT9P031 detected at address 0x%02x\n, client-addr); - return ret; + return 0; } static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) If you're happy with that there's no need to resubmit, I'll apply the patch to my tree for v3.11. -- Regards, Laurent Pinchart --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 23/24] V4L2: mt9p031: add struct v4l2_subdev_platform_data to platform data
On Mon, 22 Apr 2013, Laurent Pinchart wrote: Hi Guennadi, On Thursday 18 April 2013 23:47:26 Guennadi Liakhovetski wrote: On Thu, 18 Apr 2013, Guennadi Liakhovetski wrote: Adding struct v4l2_subdev_platform_data to mt9p031's platform data allows the driver to use generic functions to manage sensor power supplies. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de A small addition to this one too: to be absolutely honest, I also had to replace 12-bit formats with their 8-bit counterparts, because only 8 data lanes are connected to my camera host. We'll need to somehow properly solve this too. That information should be conveyed by platform/DT data for the host, and be used to convert the 12-bit media bus code into a 8-bit media bus code in the host (a core helper function would probably be helpful). Yes, and we discussed this before too, I think. I proposed based then to implement some compatibility table of trivial transformations, like a 12-bit Bayer, right-shifted by 4 bits, produces a respective 8-bit Bayer etc. Such transformations would fit nicely in soc_mediabus.c ;-) This just needs to be implemented... Sure, I'd be happy to move soc_mediabus.c to drivers/media/v4l2-core/v4l2-mediabus.c. Thanks Guennadi --- drivers/media/i2c/mt9p031.c |1 + include/media/mt9p031.h |3 +++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index 70f4525..ca2cc6e 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -1048,6 +1048,7 @@ static int mt9p031_probe(struct i2c_client *client, goto done; mt9p031-subdev.dev = client-dev; + mt9p031-subdev.pdata = pdata-sd_pdata; ret = v4l2_async_register_subdev(mt9p031-subdev); done: diff --git a/include/media/mt9p031.h b/include/media/mt9p031.h index 0c97b19..7bf7b53 100644 --- a/include/media/mt9p031.h +++ b/include/media/mt9p031.h @@ -1,6 +1,8 @@ #ifndef MT9P031_H #define MT9P031_H +#include media/v4l2-subdev.h + struct v4l2_subdev; /* @@ -15,6 +17,7 @@ struct mt9p031_platform_data { int reset; int ext_freq; int target_freq; + struct v4l2_subdev_platform_data sd_pdata; }; #endif -- Regards, Laurent Pinchart --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 06/24] V4L2: add a common V4L2 subdevice platform data type
Hi Hans Thanks for reviewing. On Fri, 19 Apr 2013, Hans Verkuil wrote: On Thu April 18 2013 23:35:27 Guennadi Liakhovetski wrote: This struct shall be used by subdevice drivers to pass per-subdevice data, e.g. power supplies, to generic V4L2 methods, at the same time allowing optional host-specific extensions via the host_priv pointer. To avoid having to pass two pointers to those methods, add a pointer to this new struct to struct v4l2_subdev. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- include/media/v4l2-subdev.h | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index eb91366..b15c6e0 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -561,6 +561,17 @@ struct v4l2_subdev_internal_ops { /* Set this flag if this subdev generates events. */ #define V4L2_SUBDEV_FL_HAS_EVENTS (1U 3) +struct regulator_bulk_data; + +struct v4l2_subdev_platform_data { + /* Optional regulators uset to power on/off the subdevice */ + struct regulator_bulk_data *regulators; + int num_regulators; + + /* Per-subdevice data, specific for a certain video host device */ + void *host_priv; +}; + /* Each instance of a subdev driver should create this struct, either stand-alone or embedded in a larger struct. */ @@ -589,6 +600,8 @@ struct v4l2_subdev { /* pointer to the physical device */ struct device *dev; struct v4l2_async_subdev_list asdl; + /* common part of subdevice platform data */ + struct v4l2_subdev_platform_data *pdata; }; static inline struct v4l2_subdev *v4l2_async_to_subdev( Sorry, this is the wrong approach. This is data that is of no use to the subdev driver itself. It really is v4l2_subdev_host_platform_data, and as such must be maintained by the bridge driver. I don't think so. It has been discussed and agreed upon, that only subdevice drivers know when to switch power on and off, because only they know when they need to access the hardware. So, they have to manage regulators. In fact, those regulators supply power to respective subdevices, e.g. a camera sensor. Why should the bridge driver manage them? The V4L2 core can (and probably should) provide helper functions for that, like soc-camera currently does, but in any case it's the subdevice driver, that has to call them. Thanks Guennadi It can use v4l2_get/set_subdev_hostdata() to associate this struct with a subdev, though. Regards, Hans --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 21/24] V4L2: add a subdevice-driver pad-operation wrapper
On Fri, 19 Apr 2013, Hans Verkuil wrote: On Thu April 18 2013 23:35:42 Guennadi Liakhovetski wrote: Some subdevice drivers implement only the pad-level API, making them unusable with V4L2 camera host drivers, using the plain subdevice video API. This patch implements a wrapper to allow those two types of drivers to be used together. So far only a subset of operations is supported, the rest shall be added as needed. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de Nacked-by: Hans Verkuil hans.verk...@cisco.com I wish you'd discussed this with me before spending time on this. This is really not the right approach to this problem. I don't see this as such a strict requirement. I think, many systems work sufficiently well with subdevice video ops and don't need pad operations. Those systems simply don't have all the complexity, that really led to the pad-level API / MC. Think about simple camera interfaces, that can only capture data from a camera and DMA it to RAM with no or very little processing. No fancy scalers, converters, compressors etc. Do you really want to spend time converting such host drivers to the pad-level API and either use fake file-handles or really export everything to the user-space and make users configure both the camera source and the host sink pads manually independently... Isn't it an overkill? With my approach you just add I want to stay with subdev ops and use a wrapper with pad-enabled sensor drivers to the _host_ driver, because it's really the host driver, that has to be punished for being lazy. And you're done. No need to modify subdevice drivers first to add wrappers and then to remove them again... Thanks Guennadi The problem is that all the non-pad ops should be converted to the pad ops. There is no point in having two different implementations of the same thing. IMHO the best approach is to convert the users of the old ops to the pad ops and add helper functions to v4l2-subdev.c that subdev drivers can use to still support the old ops by calling the new pad op instead. The next step is to convert all bridge driver uses of the old ops to the new ops and once that's done we can drop the old ops. This second step can be done at leisure. So in v4l2-subdev.c you would have a helper like this: int v4l2_subdev_video_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { struct v4l2_subdev_mbus_code_enum mbus_code; int err; memset(mbus_code, 0, sizeof(mbus_code)); mbus_code.index = index; err = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, mbus_code); if (err = 0) *code = mbus_code.code; return err; } This helper would then be used in a subdev driver as the video enum_mbus_fmt op. I now also understand your earlier patch allowing dummy v4l2_fh structs. That's definitely not the right approach, instead the v4l2_subdev_get_try_##fun_name macro (which IMHO should be dropped: just write out the functions in full) should be modified to handle a NULL v4l2_fh: #define __V4L2_SUBDEV_MK_GET_TRY(rtype, fun_name, field_name) \ static inline struct rtype *\ v4l2_subdev_get_try_##fun_name(struct v4l2_subdev_fh *fh, \ unsigned int pad)\ { \ if (fh == NULL) \ return NULL;\ BUG_ON(unlikely(pad = vdev_to_v4l2_subdev( \ fh-vfh.vdev)-entity.num_pads)); \ return fh-pad[pad].field_name;\ } Is there any point to the try variants if you don't have file handles? If there is (and I don't see it), then v4l2_subdev could get a pointer to a struct v4l2_subdev_try_buf and the macro could use that if fh == NULL. Regards, Hans --- drivers/media/v4l2-core/Makefile|3 + drivers/media/v4l2-core/v4l2-pad-wrap.c | 329 +++ include/media/v4l2-pad-wrap.h | 23 +++ include/media/v4l2-subdev.h |2 + 4 files changed, 357 insertions(+), 0 deletions(-) create mode 100644 drivers/media/v4l2-core/v4l2-pad-wrap.c create mode 100644 include/media/v4l2-pad-wrap.h diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index 4c33b8d6..85dda29 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -13,6 +13,9 @@ endif ifeq ($(CONFIG_OF),y) videodev-objs += v4l2-of.o endif +ifeq ($(CONFIG_VIDEO_V4L2_SUBDEV_API),y) + videodev-objs += v4l2-pad-wrap.o +endif obj-$(CONFIG_VIDEO_V4L2
Re: AT91SAM9M10: Problem porting driver for MT9P031 sensor
On Thu, 18 Apr 2013, Marcio Campos de Lima wrote: Hi Guennadi Thanks a lot for your attention. I think I cannot apply the patches. My Linux sources, downloaded from www.at91.com, does not have the V4l2-async.h header and, I suppose, many others headers. The MT9P031 sources have been modified and it is in a different tree. Can you tell me where I can download an already patched Kernel 3.6.9 which I can add theses functionality to the driver I am using? Hm, no, sorry, today isn't your lucky day. I don't think I can help you with a 3.6 kernel. Thanks Guennadi By the way, our MT9P031 sensor board has 10-bit format. I have fixed already. Regards MArcio On 18/04/13 19:44, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: Hi Marcio On Thu, 18 Apr 2013, Marcio Campos de Lima wrote: Hi I am porting the MT9P031 sensor device driver for a custom designed board based at the AT91SAM9M45-EK development board and Linux 3.6.9. The driver detects the sensor but does not create /dev/video1. Can anybody help me? Congratulations, today is your lucky day :-) I've just posted a patch-series http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/635 04 to do exactly what you need. Well, 99% of what you need :) With at91 you're using the atmel-isi soc-camera camera host driver. Shich isn't extended by this patch series to support the asynchronous subdevice registration, but it's rather easy to add, please, have a look at patch #15 for an example, based on the mx3_camera driver. Then there's a slight problem of mt9p031 only exporting 12-bit formats. You can fix it internally by substituting 8-bit formats (you are using 8 bits, right?) instead. We'll need a proper solution at some point. The last patch in the series shows how to add support for the mt9p031 sensor to a board. Anyway, give it a try, feel free to ask. Thanks Guennadi Thanks Marcio This is the probe code fo the driver if this can help: /* - -- -- * Driver initialization and probing */ static int mt9p031_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct mt9p031_platform_data *pdata = client-dev.platform_data; struct i2c_adapter *adapter = to_i2c_adapter(client-dev.parent); struct mt9p031 *mt9p031; unsigned int i; int ret; if (pdata == NULL) { dev_err(client-dev, No platform data\n); return -EINVAL; } if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_warn(client-dev, I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n); return -EIO; } mt9p031 = kzalloc(sizeof(*mt9p031), GFP_KERNEL); if (mt9p031 == NULL) return -ENOMEM; mt9p031-pdata = pdata; mt9p031-output_control = MT9P031_OUTPUT_CONTROL_DEF; mt9p031-mode2 = MT9P031_READ_MODE_2_ROW_BLC; v4l2_ctrl_handler_init(mt9p031-ctrls, ARRAY_SIZE(mt9p031_ctrls) + 4); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN, MT9P031_SHUTTER_WIDTH_MAX, 1, MT9P031_SHUTTER_WIDTH_DEF); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_GAIN, MT9P031_GLOBAL_GAIN_MIN, MT9P031_GLOBAL_GAIN_MAX, 1, MT9P031_GLOBAL_GAIN_DEF); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); for (i = 0; i ARRAY_SIZE(mt9p031_ctrls); ++i) v4l2_ctrl_new_custom(mt9p031-ctrls, mt9p031_ctrls[i], NULL); mt9p031-subdev.ctrl_handler = mt9p031-ctrls; if (mt9p031-ctrls.error) printk(KERN_INFO %s: control initialization error %d\n, __func__, mt9p031-ctrls.error); mutex_init(mt9p031-power_lock); v4l2_i2c_subdev_init(mt9p031-subdev, client, mt9p031_subdev_ops); mt9p031-subdev.internal_ops = mt9p031_subdev_internal_ops; mt9p031-pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(mt9p031-subdev.entity, 1, mt9p031-pad, 0); if (ret 0) goto done; mt9p031-subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; mt9p031-crop.width = MT9P031_WINDOW_WIDTH_DEF; mt9p031-crop.height = MT9P031_WINDOW_HEIGHT_DEF; mt9p031-crop.left = MT9P031_COLUMN_START_DEF; mt9p031-crop.top = MT9P031_ROW_START_DEF; if (mt9p031-pdata-version == MT9P031_MONOCHROME_VERSION) mt9p031-format.code = V4L2_MBUS_FMT_Y12_1X12; else mt9p031-format.code = V4L2_MBUS_FMT_SGRBG12_1X12; mt9p031-format.width = MT9P031_WINDOW_WIDTH_DEF; mt9p031
Re: AT91SAM9M10: Problem porting driver for MT9P031 sensor
On Fri, 19 Apr 2013, Marcio Lima wrote: Hi Which version can you help me? You can apply the patch series, that I pointed you out at yesterday on top of the v4l2-async branch of git://linuxtv.org/gliakhovetski/v4l-dvb.git which is based on some 3.9-rcX. Thanks Guennadi Enviado via iPhone Em 19/04/2013, às 09:42, Guennadi Liakhovetski g.liakhovet...@gmx.de escreveu: On Thu, 18 Apr 2013, Marcio Campos de Lima wrote: Hi Guennadi Thanks a lot for your attention. I think I cannot apply the patches. My Linux sources, downloaded from www.at91.com, does not have the V4l2-async.h header and, I suppose, many others headers. The MT9P031 sources have been modified and it is in a different tree. Can you tell me where I can download an already patched Kernel 3.6.9 which I can add theses functionality to the driver I am using? Hm, no, sorry, today isn't your lucky day. I don't think I can help you with a 3.6 kernel. Thanks Guennadi By the way, our MT9P031 sensor board has 10-bit format. I have fixed already. Regards MArcio On 18/04/13 19:44, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: Hi Marcio On Thu, 18 Apr 2013, Marcio Campos de Lima wrote: Hi I am porting the MT9P031 sensor device driver for a custom designed board based at the AT91SAM9M45-EK development board and Linux 3.6.9. The driver detects the sensor but does not create /dev/video1. Can anybody help me? Congratulations, today is your lucky day :-) I've just posted a patch-series http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/635 04 to do exactly what you need. Well, 99% of what you need :) With at91 you're using the atmel-isi soc-camera camera host driver. Shich isn't extended by this patch series to support the asynchronous subdevice registration, but it's rather easy to add, please, have a look at patch #15 for an example, based on the mx3_camera driver. Then there's a slight problem of mt9p031 only exporting 12-bit formats. You can fix it internally by substituting 8-bit formats (you are using 8 bits, right?) instead. We'll need a proper solution at some point. The last patch in the series shows how to add support for the mt9p031 sensor to a board. Anyway, give it a try, feel free to ask. Thanks Guennadi Thanks Marcio This is the probe code fo the driver if this can help: /* - -- -- * Driver initialization and probing */ static int mt9p031_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct mt9p031_platform_data *pdata = client-dev.platform_data; struct i2c_adapter *adapter = to_i2c_adapter(client-dev.parent); struct mt9p031 *mt9p031; unsigned int i; int ret; if (pdata == NULL) { dev_err(client-dev, No platform data\n); return -EINVAL; } if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_warn(client-dev, I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n); return -EIO; } mt9p031 = kzalloc(sizeof(*mt9p031), GFP_KERNEL); if (mt9p031 == NULL) return -ENOMEM; mt9p031-pdata = pdata; mt9p031-output_control= MT9P031_OUTPUT_CONTROL_DEF; mt9p031-mode2 = MT9P031_READ_MODE_2_ROW_BLC; v4l2_ctrl_handler_init(mt9p031-ctrls, ARRAY_SIZE(mt9p031_ctrls) + 4); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN, MT9P031_SHUTTER_WIDTH_MAX, 1, MT9P031_SHUTTER_WIDTH_DEF); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_GAIN, MT9P031_GLOBAL_GAIN_MIN, MT9P031_GLOBAL_GAIN_MAX, 1, MT9P031_GLOBAL_GAIN_DEF); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(mt9p031-ctrls, mt9p031_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); for (i = 0; i ARRAY_SIZE(mt9p031_ctrls); ++i) v4l2_ctrl_new_custom(mt9p031-ctrls, mt9p031_ctrls[i], NULL); mt9p031-subdev.ctrl_handler = mt9p031-ctrls; if (mt9p031-ctrls.error) printk(KERN_INFO %s: control initialization error %d\n, __func__, mt9p031-ctrls.error); mutex_init(mt9p031-power_lock); v4l2_i2c_subdev_init(mt9p031-subdev, client, mt9p031_subdev_ops); mt9p031-subdev.internal_ops = mt9p031_subdev_internal_ops; mt9p031-pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(mt9p031-subdev.entity, 1, mt9p031-pad, 0); if (ret 0) goto done; mt9p031-subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; mt9p031-crop.width = MT9P031_WINDOW_WIDTH_DEF; mt9p031-crop.height = MT9P031_WINDOW_HEIGHT_DEF; mt9p031-crop.left
[PATCH] V4L2: fix subdevice matching in asynchronous probing
A wrapped list iterating loop hasn't been correctly recognised in v4l2_async_belongs(), which led to false positives. Fix the bug by verifying the loop termination condition. Reported-by: Prabhakar Lad prabhakar.cse...@gmail.com Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- Prabhakar, please, check, whether this fixes your problem. drivers/media/v4l2-core/v4l2-async.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 5d6b428..5631944 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -76,6 +76,10 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier * break; } + if (asd-list == notifier-waiting) + /* Wrapped - no match found */ + return NULL; + return asd; } -- 1.7.2.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html