Re: [PATCH 1/2] mt9p031: Add mt9p031 sensor driver.

2011-05-18 Thread Laurent Pinchart
Hi Javier,

On Wednesday 18 May 2011 11:10:03 javier Martin wrote:
> Hi Laurent,
> I've already fixed almost every issue you pointed out.
> However, I still have got some doubts that I hope you can clarify.
> 
> On 17 May 2011 13:33, Laurent Pinchart wrote:
> > On Tuesday 17 May 2011 11:28:47 Javier Martin wrote:
> >> It has been tested in beagleboard xM, using LI-5M03 module.
> >> 
> >> Signed-off-by: Javier Martin 
> >> 
> >> +
> >> +static int mt9p031_power_on(struct mt9p031 *mt9p031)
> >> +{
> >> + int ret;
> >> +
> >> + if (mt9p031->pdata->set_xclk)
> >> + mt9p031->pdata->set_xclk(&mt9p031->subdev, 5400);
> >> + /* turn on VDD_IO */
> >> + ret = regulator_enable(mt9p031->reg_2v8);
> >> + if (ret) {
> >> + pr_err("Failed to enable 2.8v regulator: %d\n", ret);
> >> + return -1;
> >> + }
> >
> >I would enable the regulator first. As a general rule, chips should be
> >powered up before their I/Os are actively driven.
> >
> >You need to restore registers here, otherwise all controls set by the user
> >will not be applied to the device.
> 
> It's my mistake. This driver uses two regulators: 1,8 and 2,8 V
> respectively. 2,8V regulator powers analog part and I/O whereas 1,8V
> one powers the core. What I failed to do was keeping 1,8V regulator
> always powered on, so that register configuration was not lost, and
> power 2,8V regulator on and off as needed since it does not affect
> register values. However, I messed it all up.
> 
> Ideally I would have to power 1,8V regulator on and off too. However,
> as you wisely pointed out, registers should be restored in that case.
> How am I supposed to keep track of register values? Are there any
> helper functions I can use for that purpose or must I create a custom
> register cache? Do you know any driver that uses this technique?

You can either keep track of register contents manually, or use the control 
framework to restore the value of all controls by calling 
v4l2_ctrl_handler_setup(). That's what the mt9v032 driver does in its power on 
handler. You might have to restore a couple of registers manually if they're 
not handled through controls.

> > [snip]
> > 
> >> +static int mt9p031_set_params(struct i2c_client *client,
> >> +   struct v4l2_rect *rect, u16 xskip, u16
> >> yskip)
> > 
> > set_params should apply the parameters, not change them. They should have
> > already been validated by the callers.
> 
> "mt9p031_set_params()" function is used by "mt9p031_set_crop()" and
> "mt9p031_set_format()", as you have correctly stated, these functions
> shouldn' apply parameters but only change them.
> I've checked mt9v032 driver and it is as you said. The question is,
> where should these parameters get applied then?

The mt9v032 driver applies those parameters at stream on time. The downside is 
that it doesn't support resolution or crop changes at runtime. While changing 
resolution at runtime might not make much sense in most cases, changing the 
crop rectangle (providing its size stays the same) is a useful feature.

You can handle resolution changes at runtime, or you can choose to only set 
the resolution at stream on time. In both cases, the mt9p031_set_params() 
function should only apply parameters to the device, not change their value on 
the driver side. That was the purpose of my original comment.

> >> +static int mt9p031_registered(struct v4l2_subdev *sd)
> >> +{
> >> + struct mt9p031 *mt9p031;
> >> + mt9p031 = container_of(sd, struct mt9p031, subdev);
> >> +
> >> + mt9p031_power_off(mt9p031);
> > 
> > What's that for ?
> > 
> >> + return 0;
> >> +}
> 
> Since "mt9p031_power_off()" and "mt9p031_power_on()" functions
> disable/enable the 2,8V regulator which powers I/O, it must be powered
> on during probe and after registering, it can be safely powered off.

Can't you just power it off at the end of your probe function, instead of 
doing it here ?

> > You have a set_xclk callback to board code, so I assume the chip can be
> > driven by one of the OMAP3 ISP XCLK signals. To call back to the OMAP3
> > ISP from board code, you need to get hold of the OMAP3 ISP device
> > pointer. Your next patch exports omap3isp_device, but I'm not sure
> > that's the way to go. One option is
> > 
> > struct isp_device *isp = v4l2_dev_to_isp_device(subdev->v4l2_dev);
> > 
> > but that requires the subdev to be registered before the function can be
> > called. In that case you would need to move the probe code to the
> > registered subdev internal function.
> 
> Yes, I tried using that function but it didn't work because subdev
> hadn't been registeret yet.
> 
> > A clean solution is needed in the long run, preferably not involving
> > board code at all. It would be nice if the OMAP3 ISP driver could export
> > XCLKA/XCLKB as generic clock objects.
> 
> So, what should I do in order to submit the driver to mainline?
> Do you want me to move the probe code to register

Re: [PATCH 1/2] mt9p031: Add mt9p031 sensor driver.

2011-05-18 Thread javier Martin
Hi Ivan,

On 17 May 2011 19:14, Ivan Nazarenko  wrote:
> Javier,
>
> I have been using the aptina patch (https://github.com/Aptina/BeagleBoard-xM) 
> on beagleboard while waiting linux-media solve this mt9p031 issue. Now that 
> you have something working, I would like to try it - but I would like to know 
> what is the clock rate you actually drove the sensor.
>
> Reviewing your path, I suppose it is 54MHz, so you would be achieving some 10 
> full 5MPix frames/s from the sensor. Is that correct? (the aptina patch 
> delivers less than 4 fps).
>

Yes, you are right. Whereas clock rate is set to 54MHz, with my
oscilloscope I have measured 57 MHz.


-- 
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com
--
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] mt9p031: Add mt9p031 sensor driver.

2011-05-18 Thread javier Martin
Hi Laurent,
I've already fixed almost every issue you pointed out.
However, I still have got some doubts that I hope you can clarify.

On 17 May 2011 13:33, Laurent Pinchart
 wrote:
> Hi Javier,
>
> Thanks for the patch.
>
> On Tuesday 17 May 2011 11:28:47 Javier Martin wrote:
>> It has been tested in beagleboard xM, using LI-5M03 module.
>>
>> Signed-off-by: Javier Martin 
>>
>> +
>> +static int mt9p031_power_on(struct mt9p031 *mt9p031)
>> +{
>> + int ret;
>> +
>> + if (mt9p031->pdata->set_xclk)
>> + mt9p031->pdata->set_xclk(&mt9p031->subdev, 5400);
>> + /* turn on VDD_IO */
>> + ret = regulator_enable(mt9p031->reg_2v8);
>> + if (ret) {
>> + pr_err("Failed to enable 2.8v regulator: %d\n", ret);
>> + return -1;
>> + }
>
>I would enable the regulator first. As a general rule, chips should be powered
>up before their I/Os are actively driven.
>
>You need to restore registers here, otherwise all controls set by the user
>will not be applied to the device.

It's my mistake. This driver uses two regulators: 1,8 and 2,8 V
respectively. 2,8V regulator powers analog part and I/O whereas 1,8V
one powers the core. What I failed to do was keeping 1,8V regulator
always powered on, so that register configuration was not lost, and
power 2,8V regulator on and off as needed since it does not affect
register values. However, I messed it all up.

Ideally I would have to power 1,8V regulator on and off too. However,
as you wisely pointed out, registers should be restored in that case.
How am I supposed to keep track of register values? Are there any
helper functions I can use for that purpose or must I create a custom
register cache? Do you know any driver that uses this technique?

> [snip]
>> +static int mt9p031_set_params(struct i2c_client *client,
>> +                           struct v4l2_rect *rect, u16 xskip, u16 yskip)
>
> set_params should apply the parameters, not change them. They should have
> already been validated by the callers.

"mt9p031_set_params()" function is used by "mt9p031_set_crop()" and
"mt9p031_set_format()", as you have correctly stated, these functions
shouldn' apply parameters but only change them.
I've checked mt9v032 driver and it is as you said. The question is,
where should these parameters get applied then?

>> +static int mt9p031_registered(struct v4l2_subdev *sd)
>> +{
>> +     struct mt9p031 *mt9p031;
>> +     mt9p031 = container_of(sd, struct mt9p031, subdev);
>> +
>> +     mt9p031_power_off(mt9p031);
>
> What's that for ?
>
>> +     return 0;
>> +}

Since "mt9p031_power_off()" and "mt9p031_power_on()" functions
disable/enable the 2,8V regulator which powers I/O, it must be powered
on during probe and after registering, it can be safely powered off.

>
> You have a set_xclk callback to board code, so I assume the chip can be driven
> by one of the OMAP3 ISP XCLK signals. To call back to the OMAP3 ISP from board
> code, you need to get hold of the OMAP3 ISP device pointer. Your next patch
> exports omap3isp_device, but I'm not sure that's the way to go. One option is
>
> struct isp_device *isp = v4l2_dev_to_isp_device(subdev->v4l2_dev);
>
> but that requires the subdev to be registered before the function can be
> called. In that case you would need to move the probe code to the registered
> subdev internal function.
>

Yes, I tried using that function but it didn't work because subdev
hadn't been registeret yet.

> A clean solution is needed in the long run, preferably not involving board
> code at all. It would be nice if the OMAP3 ISP driver could export XCLKA/XCLKB
> as generic clock objects.

So, what should I do in order to submit the driver to mainline?
 Do you want me to move the probe code to registered callback?

Thank you.

-- 
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com
--
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] mt9p031: Add mt9p031 sensor driver.

2011-05-18 Thread Laurent Pinchart
Hi Chris,

On Wednesday 18 May 2011 07:09:44 Chris Rodley wrote:
> 
> Trying out the new patch.. I get this error:
> 
> root@beagle:~# modprobe iommu2
> [   24.691375] omap-iommu omap-iommu.0: isp registered
> root@beagle:~# modprobe omap3_isp
> [   26.923065] Linux video capture interface: v2.00
> [   27.027679] omap3isp omap3isp: Revision 2.0 found
> [   27.032684] omap-iommu omap-iommu.0: isp: version 1.1
> [   27.333648] mt9p031 2-0048: Detected a MT9P031 chip ID 1801
> [   27.427459] kernel BUG at drivers/media/video/omap3isp/isp.c:1494!

What kernel and OMAP3 ISP driver are you using ? The BUG_ON statement is at 
line 1492 in mainline. Bugs in error paths were present in older versions, 
make sure you use the latest one.

> [   27.434082] Unable to handle kernel NULL pointer dereference at virtual
> address  [   27.442657] pgd = c7724000
> [   27.445526] [] *pgd=87700831, *pte=, *ppte=
> [   27.452178] Internal error: Oops: 817 [#1]
> [   27.456512] last sysfs file:
> /sys/devices/platform/omap3isp/video4linux/v4l-subdev7/dev [   27.464965]
> Modules linked in: mt9p031 omap3_isp(+) v4l2_common videodev iovmm iommu2
> iommu [   27.473815] CPU: 0Not tainted  (2.6.39 #17)
> [   27.481536] PC is at __bug+0x1c/0x28
> [   27.485321] LR is at __bug+0x18/0x28
> [   27.489105] pc : []lr : []psr: 2013
> [   27.489105] sp : c76c1e08  ip :   fp : c050ff48
> [   27.501220] r10: c051bd40  r9 : c050ff48  r8 : c7788000
> [   27.506744] r7 :   r6 : c7788348  r5 :   r4 : c7788000
> [   27.513610] r3 :   r2 : c76c1dfc  r1 : c0473627  r0 : 004c
> [   27.520507] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment
> user [   27.528045] Control: 10c5387d  Table: 87724019  DAC: 0015
> [   27.534118] Process modprobe (pid: 269, stack limit = 0xc76c02f0)
> [   27.540557] Stack: (0xc76c1e08 to 0xc76c2000)
> [   27.545166] 1e00:    bf0404d4 c7788000 
> c773f800 bf040dd4 [   27.553802] 1e20:  c7788000 c740c598 
> c778e1a8 c778ef18 c050ff7c c050ff48 [   27.562438] 1e40: c050ff7c bf053a28
> bf053a28  0025 001c  c02336fc [   27.571075] 1e60:
> c02336e8 c0232608  c050ff48 c050ff7c bf053a28  c0232724
> [   27.579711] 1e80: bf053a28 c76c1e90 c02326c4 c0231888 c740c578 c747d230
> bf053a28 bf053a28 [   27.588348] 1ea0: c763f980 c0540880  c0231f24
> bf051331 bf051336 0033 bf053a28 [   27.596984] 1ec0:  0001
> bf05b000  001c c0232c4c  bf053c68 [   27.605621] 1ee0:
>  0001 bf05b000  001c c0036510 bf05b000 
> [   27.614257] 1f00: 0001  bf053c68  0001 c7703ec0
> 0001 c0094028 [   27.622924] 1f20: bf053c74  c00919c8 c03a4998
> bf053dbc 00b71148 c765ae00 c88b7000 [   27.631561] 1f40: 00021d91 c88ce794
> c88ce627 c88d62cc c7665000 00014ddc 00017a1c  [   27.640197] 1f60:
>  0023 0024 0018 001c 000f  c04cab04
> [   27.648834] 1f80:  00b71008 00b71148  0080 c003b124
> c76c  [   27.657470] 1fa0: bec2dc84 c003afa0 00b71008 00b71148
> 4009d000 00021d91 00b71148 0001a6d8 [   27.666107] 1fc0: 00b71008 00b71148
>  0080 00b71040 bec2dc84  bec2dc84 [   27.674743] 1fe0:
> 00b712a8 bec2d984 b4ec 40208084 6010 4009d000 0a5c 
> [   27.683502] [] (__bug+0x1c/0x28) from []
> (omap3isp_put+0x30/0x90 [omap3_isp]) [   27.692962] []
> (omap3isp_put+0x30/0x90 [omap3_isp]) from []
> (isp_probe+0x7dc/0x958 [omap3_isp]) [   27.704040] []
> (isp_probe+0x7dc/0x958 [omap3_isp]) from []
> (platform_drv_probe+0x14/0x18) [   27.714538] []
> (platform_drv_probe+0x14/0x18) from []
> (driver_probe_device+0xc8/0x184) [   27.724731] []
> (driver_probe_device+0xc8/0x184) from []
> (__driver_attach+0x60/0x84) [   27.734649] []
> (__driver_attach+0x60/0x84) from [] (bus_for_each_dev+0x4c/0x78)
> [   27.744201] [] (bus_for_each_dev+0x4c/0x78) from []
> (bus_add_driver+0xac/0x224) [   27.753784] []
> (bus_add_driver+0xac/0x224) from [] (driver_register+0xa8/0x12c)
> [   27.763336] [] (driver_register+0xa8/0x12c) from []
> (do_one_initcall+0x90/0x160) [   27.773010] []
> (do_one_initcall+0x90/0x160) from []
> (sys_init_module+0x16e0/0x1854) [   27.782928] []
> (sys_init_module+0x16e0/0x1854) from []
> (ret_fast_syscall+0x0/0x30) [   27.792755] Code: e59f0010 e1a01003
> eb0d66a1 e3a03000 (e5833000) [   27.799285] ---[ end trace
> e4f3fc044db258d3 ]---

-- 
Regards,

Laurent Pinchart
--
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] mt9p031: Add mt9p031 sensor driver.

2011-05-17 Thread Russell King - ARM Linux
On Tue, May 17, 2011 at 01:33:52PM +0200, Laurent Pinchart wrote:
> Hi Javier,
> 
> Thanks for the patch.

Sorry, but this laziness is getting beyond a joke...  And the fact that
apparantly no one is picking up on it other than me is also a joke.

> > +static int mt9p031_power_on(struct mt9p031 *mt9p031)
> > +{
> > +   int ret;
> > +
> > +   if (mt9p031->pdata->set_xclk)
> > +   mt9p031->pdata->set_xclk(&mt9p031->subdev, 5400);
> > +   /* turn on VDD_IO */
> > +   ret = regulator_enable(mt9p031->reg_2v8);
> > +   if (ret) {
> > +   pr_err("Failed to enable 2.8v regulator: %d\n", ret);
> > +   return -1;

And why all these 'return -1's?  My guess is that this is plain laziness
on the authors part.

> > +static int mt9p031_set_params(struct i2c_client *client,
> > + struct v4l2_rect *rect, u16 xskip, u16 yskip)
> 
> set_params should apply the parameters, not change them. They should have 
> already been validated by the callers.
> 
> > +{
...
> > +err:
> > +   return -1;

And again...

> > +}
> > +
> > +static int mt9p031_set_crop(struct v4l2_subdev *sd,
> > +   struct v4l2_subdev_fh *fh,
> > +   struct v4l2_subdev_crop *crop)
> > +{
...

> > +   if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
> > +   ret = mt9p031_set_params(client, &rect, xskip, yskip);
> > +   if (ret < 0)
> > +   return ret;

So this propagates the lazy 'return -1' all the way back to userspace.
This is utter crap - really it is, and I'm getting sick and tired of
telling people that they should not use 'return -1'.  It's down right
lazy and sloppy programming.

I wish people would stop doing it.  I wish people would review their own
stuff for this _before_ posting it onto a mailing list, so I don't have
to keep complaining about it.  And I wish people reviewing drivers would
also look for this as well and complain about it.

'return -1' is generally a big fat warning sign that the author is doing
something wrong, and should _always_ be investigated and complained about.
--
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] mt9p031: Add mt9p031 sensor driver.

2011-05-17 Thread Ivan Nazarenko
Javier,

I have been using the aptina patch (https://github.com/Aptina/BeagleBoard-xM) 
on beagleboard while waiting linux-media solve this mt9p031 issue. Now that you 
have something working, I would like to try it - but I would like to know what 
is the clock rate you actually drove the sensor.

Reviewing your path, I suppose it is 54MHz, so you would be achieving some 10 
full 5MPix frames/s from the sensor. Is that correct? (the aptina patch 
delivers less than 4 fps).

Regards,

Ivan

On Tuesday, May 17, 2011 08:59:04 javier Martin wrote:
> On 17 May 2011 13:47, Guennadi Liakhovetski  wrote:
> > Hi Laurent
> >
> > Thanks for your review! Javier, if you like, you can wait a couple of days
> > until I find some time to review the driver, or you can submit a version,
> > addressing Laurent's points, but be prepared to have to do another one;)
> >
> > Thanks
> > Guennadi
> > ---
> > Guennadi Liakhovetski, Ph.D.
> > Freelance Open-Source Software Developer
> > http://www.open-technology.de/
> >
> 
> OK, I think I'll wait to have Guennadi's review too.
> Thank you both.
> 
> 
--
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] mt9p031: Add mt9p031 sensor driver.

2011-05-17 Thread javier Martin
On 17 May 2011 13:47, Guennadi Liakhovetski  wrote:
> Hi Laurent
>
> Thanks for your review! Javier, if you like, you can wait a couple of days
> until I find some time to review the driver, or you can submit a version,
> addressing Laurent's points, but be prepared to have to do another one;)
>
> Thanks
> Guennadi
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
>

OK, I think I'll wait to have Guennadi's review too.
Thank you both.

-- 
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com
--
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] mt9p031: Add mt9p031 sensor driver.

2011-05-17 Thread Guennadi Liakhovetski
Hi Laurent

Thanks for your review! Javier, if you like, you can wait a couple of days 
until I find some time to review the driver, or you can submit a version, 
addressing Laurent's points, but be prepared to have to do another one;)

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] mt9p031: Add mt9p031 sensor driver.

2011-05-17 Thread Laurent Pinchart
Hi Javier,

Thanks for the patch.

On Tuesday 17 May 2011 11:28:47 Javier Martin wrote:
> It has been tested in beagleboard xM, using LI-5M03 module.
> 
> Signed-off-by: Javier Martin 

[snip]

> diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
> new file mode 100644
> index 000..850cfec
> --- /dev/null
> +++ b/drivers/media/video/mt9p031.c
> @@ -0,0 +1,773 @@
> +/*
> + * Driver for MT9P031 CMOS Image Sensor from Aptina
> + *
> + * Copyright (C) 2011, Javier Martin 
> + *
> + * Copyright (C) 2011, Guennadi Liakhovetski 
> + *
> + * Based on the MT9V032 driver and Bastian Hecht's code.
> + *
> + * 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 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/* mt9p031 selected register addresses */
> +#define MT9P031_CHIP_VERSION 0x00
> +#define  MT9P031_CHIP_VERSION_VALUE  0x1801
> +#define MT9P031_ROW_START0x01
> +#define  MT9P031_ROW_START_SKIP  54
> +#define MT9P031_COLUMN_START 0x02
> +#define  MT9P031_COLUMN_START_SKIP   16
> +#define MT9P031_WINDOW_HEIGHT0x03
> +#define MT9P031_WINDOW_WIDTH 0x04
> +#define MT9P031_H_BLANKING   0x05
> +#define  MT9P031_H_BLANKING_VALUE0
> +#define MT9P031_V_BLANKING   0x06
> +#define  MT9P031_V_BLANKING_VALUE25
> +#define MT9P031_OUTPUT_CONTROL   0x07
> +#define  MT9P031_OUTPUT_CONTROL_CEN  2
> +#define  MT9P031_OUTPUT_CONTROL_SYN  1
> +#define MT9P031_SHUTTER_WIDTH_UPPER  0x08
> +#define MT9P031_SHUTTER_WIDTH0x09
> +#define MT9P031_PIXEL_CLOCK_CONTROL  0x0a
> +#define MT9P031_FRAME_RESTART0x0b
> +#define MT9P031_SHUTTER_DELAY0x0c
> +#define MT9P031_RESET0x0d
> +#define  MT9P031_RESET_ENABLE1
> +#define  MT9P031_RESET_DISABLE   0
> +#define MT9P031_READ_MODE_1  0x1e
> +#define MT9P031_READ_MODE_2  0x20
> +#define  MT9P031_READ_MODE_2_ROW_MIR 0x8000
> +#define  MT9P031_READ_MODE_2_COL_MIR 0x4000
> +#define MT9P031_ROW_ADDRESS_MODE 0x22
> +#define MT9P031_COLUMN_ADDRESS_MODE  0x23
> +#define MT9P031_GLOBAL_GAIN  0x35
> +
> +#define MT9P031_MAX_HEIGHT   1944
> +#define MT9P031_MAX_WIDTH2592
> +#define MT9P031_MIN_HEIGHT   2
> +#define MT9P031_MIN_WIDTH18
> +
> +struct mt9p031 {
> + struct v4l2_subdev subdev;
> + struct media_pad pad;
> + struct v4l2_rect rect;  /* Sensor window */
> + struct v4l2_mbus_framefmt format;
> + struct mt9p031_platform_data *pdata;
> + int model;  /* V4L2_IDENT_MT9P031* codes from v4l2-chip-ident.h */

model is assigned by never read, you can remove it.

> + u16 xskip;
> + u16 yskip;
> + struct regulator *reg_1v8, *reg_2v8;

Please split this on two lines.

You never enable the 1.8V regulator, is that intentional ?

> +};

[snip]

> +static int reg_set(struct i2c_client *client, const u8 reg,
> +const u16 data)
> +{
> + int ret;
> +
> + ret = reg_read(client, reg);
> + if (ret < 0)
> + return ret;
> + return reg_write(client, reg, ret | data);
> +}
> +
> +static int reg_clear(struct i2c_client *client, const u8 reg,
> +  const u16 data)
> +{
> + int ret;
> +
> + ret = reg_read(client, reg);
> + if (ret < 0)
> + return ret;
> + return reg_write(client, reg, ret & ~data);
> +}

I still think you should use a shadow copy of the register in the mt9p031 
structure instead of reading the value back from the hardware. As these two 
functions are only used to handle the output control register, you could 
create an mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear, u16 
set) function instead.

> +static int mt9p031_idle(struct i2c_client *client)

This function resets the chip, what about calling it mt9p031_reset() instead ?

> +{
> + int ret;
> +
> + /* Disable chip output, synchronous option update */
> + ret = reg_write(client, MT9P031_RESET, MT9P031_RESET_ENABLE);
> + if (ret < 0)
> + goto err;

You can return -EIO directly.

> + ret = reg_write(client, MT9P031_RESET, MT9P031_RESET_DISABLE);
> + if (ret < 0)
> + goto err;

Here too.

> + ret = reg_clear(client, MT9P031_OUTPUT_CONTROL,
> + MT9P031_OUTPUT_C

[PATCH 1/2] mt9p031: Add mt9p031 sensor driver.

2011-05-17 Thread Javier Martin
It has been tested in beagleboard xM, using LI-5M03 module.

Signed-off-by: Javier Martin 
---
 drivers/media/video/Kconfig |8 +
 drivers/media/video/Makefile|1 +
 drivers/media/video/mt9p031.c   |  773 +++
 include/media/mt9p031.h |   11 +
 include/media/v4l2-chip-ident.h |1 +
 5 files changed, 794 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/mt9p031.c
 create mode 100644 include/media/mt9p031.h

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 00f51dd..32df8bd 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -329,6 +329,14 @@ config VIDEO_OV7670
  OV7670 VGA camera.  It currently only works with the M88ALP01
  controller.
 
+config VIDEO_MT9P031
+   tristate "Micron MT9P031 support"
+   depends on I2C && VIDEO_V4L2
+   ---help---
+ This driver supports MT9P031 cameras from Micron
+ This is a Video4Linux2 sensor-level driver for the Micron
+ mt0p031 5 Mpixel camera.
+
 config VIDEO_MT9V011
tristate "Micron mt9v011 sensor support"
depends on I2C && VIDEO_V4L2
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index ace5d8b..912b29b 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
 obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
 obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
 obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
+obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
 obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
 obj-$(CONFIG_VIDEO_SR030PC30)  += sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)+= noon010pc30.o
diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
new file mode 100644
index 000..850cfec
--- /dev/null
+++ b/drivers/media/video/mt9p031.c
@@ -0,0 +1,773 @@
+/*
+ * Driver for MT9P031 CMOS Image Sensor from Aptina
+ *
+ * Copyright (C) 2011, Javier Martin 
+ *
+ * Copyright (C) 2011, Guennadi Liakhovetski 
+ *
+ * Based on the MT9V032 driver and Bastian Hecht's code.
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* mt9p031 selected register addresses */
+#define MT9P031_CHIP_VERSION   0x00
+#defineMT9P031_CHIP_VERSION_VALUE  0x1801
+#define MT9P031_ROW_START  0x01
+#defineMT9P031_ROW_START_SKIP  54
+#define MT9P031_COLUMN_START   0x02
+#defineMT9P031_COLUMN_START_SKIP   16
+#define MT9P031_WINDOW_HEIGHT  0x03
+#define MT9P031_WINDOW_WIDTH   0x04
+#define MT9P031_H_BLANKING 0x05
+#defineMT9P031_H_BLANKING_VALUE0
+#define MT9P031_V_BLANKING 0x06
+#defineMT9P031_V_BLANKING_VALUE25
+#define MT9P031_OUTPUT_CONTROL 0x07
+#defineMT9P031_OUTPUT_CONTROL_CEN  2
+#defineMT9P031_OUTPUT_CONTROL_SYN  1
+#define MT9P031_SHUTTER_WIDTH_UPPER0x08
+#define MT9P031_SHUTTER_WIDTH  0x09
+#define MT9P031_PIXEL_CLOCK_CONTROL0x0a
+#define MT9P031_FRAME_RESTART  0x0b
+#define MT9P031_SHUTTER_DELAY  0x0c
+#define MT9P031_RESET  0x0d
+#defineMT9P031_RESET_ENABLE1
+#defineMT9P031_RESET_DISABLE   0
+#define MT9P031_READ_MODE_10x1e
+#define MT9P031_READ_MODE_20x20
+#defineMT9P031_READ_MODE_2_ROW_MIR 0x8000
+#defineMT9P031_READ_MODE_2_COL_MIR 0x4000
+#define MT9P031_ROW_ADDRESS_MODE   0x22
+#define MT9P031_COLUMN_ADDRESS_MODE0x23
+#define MT9P031_GLOBAL_GAIN0x35
+
+#define MT9P031_MAX_HEIGHT 1944
+#define MT9P031_MAX_WIDTH  2592
+#define MT9P031_MIN_HEIGHT 2
+#define MT9P031_MIN_WIDTH  18
+
+struct mt9p031 {
+   struct v4l2_subdev subdev;
+   struct media_pad pad;
+   struct v4l2_rect rect;  /* Sensor window */
+   struct v4l2_mbus_framefmt format;
+   struct mt9p031_platform_data *pdata;
+   int model;  /* V4L2_IDENT_MT9P031* codes from v4l2-chip-ident.h */
+   u16 xskip;
+   u16 yskip;
+   struct regulator *reg_1v8, *reg_2v8;
+};
+
+static struct mt9p031 *to_mt9p031(const struct i2c_client *client)
+{
+   return container_of(i2c_get_clientdata(client), struct mt9p031, subdev);
+}
+
+static int reg_read(struct i2c_client *client,