Re: [PATCH] uvcvideo: Add quirk for Quanta NL3 laptop camera

2015-04-09 Thread Daniel Drake
Hi Laurent,

On Sat, Apr 4, 2015 at 3:44 PM, Laurent Pinchart
laurent.pinch...@ideasonboard.com wrote:
 I'm not sure that adding a device-specific quirk is the bast way to handle
 this problem, as it wouldn't really scale if other devices expose buggy
 descriptors. A more generic way to patch or override descriptors might be
 better, with a single quirk and a pointer to a patch function. This would
 require refactoring the quirks system to store a structure pointer instead of
 a bitfield in the driver_info field.

I agree, but I don't currently have time to work on a more advanced approach.

I think that's OK for everyone, as I can work with this patch for the
time being, and if nobody else has broken descriptors, there's no
particular rush.

Thanks,
Daniel
--
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] uvcvideo: Add quirk for Quanta NL3 laptop camera

2015-03-12 Thread Daniel Drake
The Quanta NL3 laptop has a UVC camera which the descriptor says
comes from Realtek: https://gist.github.com/dsd/9a6567baa53c747fd306

Probe fails, because the output terminal (ID 3) references a
non-existent source with ID 6. Fixing it to add itself onto the
end of the chain makes the camera work.

Signed-off-by: Daniel Drake dr...@endlessm.com
---
 drivers/media/usb/uvc/uvc_driver.c | 36 
 drivers/media/usb/uvc/uvcvideo.h   |  1 +
 2 files changed, 37 insertions(+)

diff --git a/drivers/media/usb/uvc/uvc_driver.c 
b/drivers/media/usb/uvc/uvc_driver.c
index cf27006..3cb4be3 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1575,6 +1575,30 @@ static const char *uvc_print_chain(struct 
uvc_video_chain *chain)
 }
 
 /*
+ * This Realtek camera has a broken descriptor. The output terminal
+ * references a non-existent source. The rest of the simple chain is
+ * fine. Fix the OT to chain on to the end.
+ */
+static void uvc_handle_rtl57a7(struct uvc_device *dev)
+{
+   struct uvc_entity *term;
+
+   term = uvc_entity_by_id(dev, 3);
+   if (!term) {
+   uvc_printk(KERN_INFO, RTL57A7: no entity with id 3\n);
+   return;
+   }
+
+   if (!UVC_ENTITY_IS_OTERM(term)) {
+   uvc_printk(KERN_INFO, RTL57A7: entity 3 is not OT\n);
+   return;
+   }
+
+   term-baSourceID[0] = 4;
+   uvc_printk(KERN_INFO, Applied RTL57A7 chain quirk.\n);
+}
+
+/*
  * Scan the device for video chains and register video devices.
  *
  * Chains are scanned starting at their output terminals and walked backwards.
@@ -1584,6 +1608,9 @@ static int uvc_scan_device(struct uvc_device *dev)
struct uvc_video_chain *chain;
struct uvc_entity *term;
 
+   if (dev-quirks  UVC_QUIRK_RTL57A7)
+   uvc_handle_rtl57a7(dev);
+
list_for_each_entry(term, dev-entities, list) {
if (!UVC_ENTITY_IS_OTERM(term))
continue;
@@ -2351,6 +2378,15 @@ static struct usb_device_id uvc_ids[] = {
  .bInterfaceSubClass   = 1,
  .bInterfaceProtocol   = 0,
  .driver_info  = UVC_QUIRK_PROBE_MINMAX },
+   /* Realtek camera in Quanta NL3 laptop */
+   { .match_flags  = USB_DEVICE_ID_MATCH_DEVICE
+   | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0bda,
+ .idProduct= 0x57a7,
+ .bInterfaceClass  = USB_CLASS_VIDEO,
+ .bInterfaceSubClass   = 1,
+ .bInterfaceProtocol   = 0,
+ .driver_info  = UVC_QUIRK_RTL57A7 },
/* MT6227 */
{ .match_flags  = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index c63e5b5..710e480 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -152,6 +152,7 @@
 #define UVC_QUIRK_RESTRICT_FRAME_RATE  0x0200
 #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT0x0400
 #define UVC_QUIRK_FORCE_Y8 0x0800
+#define UVC_QUIRK_RTL57A7  0x1000
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED0x0001
-- 
2.1.0

--
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 resend] via-camera: pass correct format settings to sensor

2012-07-15 Thread Daniel Drake
The code attempts to maintain a user format and a sensor format,
but in this case it looks like a typo is passing the user format down
to the sensor.

This was preventing display of video at anything other than 640x480.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/via-camera.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 308e150..eb404c2 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -963,7 +963,7 @@ static int viacam_do_try_fmt(struct via_camera *cam,
 
upix-pixelformat = f-pixelformat;
viacam_fmt_pre(upix, spix);
-   v4l2_fill_mbus_format(mbus_fmt, upix, f-mbus_code);
+   v4l2_fill_mbus_format(mbus_fmt, spix, f-mbus_code);
ret = sensor_call(cam, video, try_mbus_fmt, mbus_fmt);
v4l2_fill_pix_format(spix, mbus_fmt);
viacam_fmt_post(upix, spix);
-- 
1.7.10.4

--
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] via-camera: pass correct format settings to sensor

2012-05-23 Thread Daniel Drake
The code attempts to maintain a user format and a sensor format,
but in this case it looks like a typo is passing the user format down
to the sensor.

This was preventing display of video at anything other than 640x480.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/via-camera.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 308e150..eb404c2 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -963,7 +963,7 @@ static int viacam_do_try_fmt(struct via_camera *cam,
 
upix-pixelformat = f-pixelformat;
viacam_fmt_pre(upix, spix);
-   v4l2_fill_mbus_format(mbus_fmt, upix, f-mbus_code);
+   v4l2_fill_mbus_format(mbus_fmt, spix, f-mbus_code);
ret = sensor_call(cam, video, try_mbus_fmt, mbus_fmt);
v4l2_fill_pix_format(spix, mbus_fmt);
viacam_fmt_post(upix, spix);
-- 
1.7.10.1

--
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] mmp-camera: specify XO-1.75 clock speed

2012-05-16 Thread Daniel Drake
On Wed, May 16, 2012 at 3:12 PM, Jonathan Corbet cor...@lwn.net wrote:
 On Tue, 15 May 2012 20:43:31 +0100 (BST)
 Daniel Drake d...@laptop.org wrote:

 Jon, is it OK to assume that XO-1.75 is the only mmp-camera user?

 It's the only one I know of at the moment, certainly.

 Even so, I think it would be a lot better to put this parameter into the
 mmp_camera_platform_data structure instead of wiring it into the driver
 source; it could then be set in olpc-xo-1-75.c with the other relevant
 parameters.  I won't oppose the inclusion of this patch, but...any chance
 it could be done that way?

I'll look into it. Please put this patch on pause for now.

Thanks
Daniel
--
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] mmp-camera: specify XO-1.75 clock speed

2012-05-15 Thread Daniel Drake
For the ov7670 camera to return images at the requested frame rate,
it needs to make calculations based on the clock speed, which is
a completely external factor (depends on the wiring of the system).

On the XO-1.75, which is the only known mmp-camera user, the camera
is clocked at 48MHz.

Pass this information to the ov7670 driver, to fix an issue where
a framerate faster than the requested amount was being provided.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/marvell-ccic/mmp-driver.c |7 +++
 1 file changed, 7 insertions(+)

Jon, is it OK to assume that XO-1.75 is the only mmp-camera user?

diff --git a/drivers/media/video/marvell-ccic/mmp-driver.c 
b/drivers/media/video/marvell-ccic/mmp-driver.c
index c4c17fe..0ba49c7 100644
--- a/drivers/media/video/marvell-ccic/mmp-driver.c
+++ b/drivers/media/video/marvell-ccic/mmp-driver.c
@@ -188,6 +188,13 @@ static int mmpcam_probe(struct platform_device *pdev)
mcam-chip_id = V4L2_IDENT_ARMADA610;
mcam-buffer_mode = B_DMA_sg;
spin_lock_init(mcam-dev_lock);
+
+   /*
+* Set the clock speed for the XO-1.75; I don't believe this
+* driver has ever run anywhere else.
+*/
+   mcam-clock_speed = 48;
+
/*
 * Get our I/O memory.
 */
-- 
1.7.10.1

--
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] via-camera: specify XO-1.5 camera clock speed

2012-04-30 Thread Daniel Drake
For the ov7670 camera to return images at the requested frame rate,
it needs to make calculations based on the clock speed, which is
a completely external factor (depends on the wiring of the system).

On the XO-1.5, which is the only known via-camera user, the camera
is clocked at 90MHz.

Pass this information to the ov7670 driver, to fix an issue where
a framerate of 3x the requested amount was being provided.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/via-camera.c |   15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 20f7237..308e150 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -18,6 +18,7 @@
 #include media/v4l2-device.h
 #include media/v4l2-ioctl.h
 #include media/v4l2-chip-ident.h
+#include media/ov7670.h
 #include media/videobuf-dma-sg.h
 #include linux/delay.h
 #include linux/dma-mapping.h
@@ -1347,11 +1348,21 @@ static __devinit bool viacam_serial_is_enabled(void)
return false;
 }
 
+static struct ov7670_config sensor_cfg = {
+   /* The XO-1.5 (only known user) clocks the camera at 90MHz. */
+   .clock_speed = 90,
+};
+
 static __devinit int viacam_probe(struct platform_device *pdev)
 {
int ret;
struct i2c_adapter *sensor_adapter;
struct viafb_dev *viadev = pdev-dev.platform_data;
+   struct i2c_board_info ov7670_info = {
+   .type = ov7670,
+   .addr = 0x42  1,
+   .platform_data = sensor_cfg,
+   };
 
/*
 * Note that there are actually two capture channels on
@@ -1433,8 +1444,8 @@ static __devinit int viacam_probe(struct platform_device 
*pdev)
 * is OLPC-specific.  0x42 assumption is ov7670-specific.
 */
sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31);
-   cam-sensor = v4l2_i2c_new_subdev(cam-v4l2_dev, sensor_adapter,
-   ov7670, 0x42  1, NULL);
+   cam-sensor = v4l2_i2c_new_subdev_board(cam-v4l2_dev, sensor_adapter,
+   ov7670_info, NULL);
if (cam-sensor == NULL) {
dev_err(pdev-dev, Unable to find the sensor!\n);
ret = -ENODEV;
-- 
1.7.10

--
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] via-camera: specify XO-1.5 camera clock speed

2012-04-30 Thread Daniel Drake
On Mon, Apr 30, 2012 at 5:27 PM, Jonathan Corbet cor...@lwn.net wrote:
 On Mon, 30 Apr 2012 23:06:27 +0100 (BST)
 Daniel Drake d...@laptop.org wrote:

 For the ov7670 camera to return images at the requested frame rate,
 it needs to make calculations based on the clock speed, which is
 a completely external factor (depends on the wiring of the system).

 On the XO-1.5, which is the only known via-camera user, the camera
 is clocked at 90MHz.

 Pass this information to the ov7670 driver, to fix an issue where
 a framerate of 3x the requested amount was being provided.

 This is big-time weird...this problem has been solved before.  The reason
 ov7670 *has* a clock speed parameter is because the XO 1.5 - the second
 user - clocked it so fast.  I'm going to have to go digging through some
 history to try to figure out where this fix went...

 Meanwhile, this looks fine.

We solved it with ugly #ifdef things in the OLPC kernel.
http://dev.laptop.org/ticket/10137

Then we found and discussed the upstreamable solution, put the
ov7670_config thing in place, and solved it for XO-1 (cafe).

But for whatever reason it looks like I forgot to fix via-camera --
maybe via-camera was still in flux and non-upstream at that time.

Daniel
--
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] via-camera: disable RGB mode

2011-10-26 Thread Daniel Drake
The RGB mode does not work correctly. It captures fine at 640x480
but whenever the scaling engine is used to produce another resolution,
color corruption occurs (lots of erroneous pink and green).

It is not clear how the scaling engine is supposed to work and how
it knows which pixel format it is dealing with. Work around this
problem by disabling RGB support. YUYV scaling works just fine.

Test case:

gst-launch v4l2src ! video/x-raw-rgb,bpp=16,width=320,height=240 ! \
ffmpegcolorspace ! xvimagesink

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/via-camera.c |   10 +++---
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index bb7f17f..e64b571 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -156,14 +156,10 @@ static struct via_format {
.mbus_code  = V4L2_MBUS_FMT_YUYV8_2X8,
.bpp= 2,
},
-   {
-   .desc   = RGB 565,
-   .pixelformat= V4L2_PIX_FMT_RGB565,
-   .mbus_code  = V4L2_MBUS_FMT_RGB565_2X8_LE,
-   .bpp= 2,
-   },
/* RGB444 and Bayer should be doable, but have never been
-  tested with this driver. */
+  tested with this driver. RGB565 seems to work at the default
+  resolution, but results in color corruption when being scaled by
+  viacam_set_scaled(), and is disabled as a result. */
 };
 #define N_VIA_FMTS ARRAY_SIZE(via_formats)
 
-- 
1.7.6.4

--
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


via-camera: scaling and RGB modes

2011-10-14 Thread Daniel Drake
Hi Jon,

We're dealing with a via-camera issue from the Scratch application.
The latest version of scratch uses libv4l2 and requests RGB24 images
as that is what it uses internally.

via-camera/ov7670 doesn't support RGB24 but libv4l2 kicks in with its
format conversion and chooses RGB565, which we do support.

The catch is that Scratch requests 320x240 video. You probably recall
that you made via-camera only ever request 640x480 from ov7670, but
you also made via-camera offer discontinuous sizes and you used the
via-camera hardware to scale the image to the appropriate size
(viacam_set_scale).

This scaling seems to work fine with YUYV, but fails with RGBA. Test case:
gst-launch v4l2src ! video/x-raw-rgb,bpp=16,width=320,height=240 !
ffmpegcolorspace ! xvimagesink

The colours in the resultant image wrong (lots of green). Change to
640x480, everything fine.

The only documentation I can find on this is the Chrome9 HCM Graphics
Processor Programming Manual which really doesn't explain much about
the camera hardware apart from a bare set of register descriptions.
What algorithm does that scaling functionality use, how does it know
which format the image is in? Is there further documentation or are we
stuck with this?

If we're stuck with it, we have the options of solving this either by
disabling everything other than YUYV (which scales fine), or just by
disabling the scaling and locking to 640x480. Thoughts/other ideas?

Unless I'm missing something, there doesn't seem a way to express in
the V4L2 API that RGB is only available at 640x480 while YUYV is
available at a range of sizes.

Thanks,
Daniel
--
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] [media] via-camera: add MODULE_ALIAS

2011-04-29 Thread Daniel Drake
This fixes autoloading of the module.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/via-camera.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 8c780c2..85d3048 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -29,6 +29,7 @@
 
 #include via-camera.h
 
+MODULE_ALIAS(platform:viafb-camera);
 MODULE_AUTHOR(Jonathan Corbet cor...@lwn.net);
 MODULE_DESCRIPTION(VIA framebuffer-based camera controller driver);
 MODULE_LICENSE(GPL);
-- 
1.7.4.4

--
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] via-camera: Fix OLPC serial check

2011-03-03 Thread Daniel Drake
The code that checks the OLPC serial port is never built at the moment,
because CONFIG_OLPC_XO_1_5 doesn't exist and probably won't be added.

Fix it so that it gets compiled in, only executes on OLPC laptops, and
move the check into the probe routine.

The compiler is smart enough to eliminate this code when CONFIG_OLPC=n
(due to machine_is_olpc() always returning false).

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/via-camera.c |   83 +-
 1 files changed, 37 insertions(+), 46 deletions(-)

diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 2f973cd..4f19edc 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -25,6 +25,7 @@
 #include linux/via-core.h
 #include linux/via-gpio.h
 #include linux/via_i2c.h
+#include asm/olpc.h
 
 #include via-camera.h
 
@@ -38,14 +39,12 @@ MODULE_PARM_DESC(flip_image,
If set, the sensor will be instructed to flip the image 
vertically.);
 
-#ifdef CONFIG_OLPC_XO_1_5
 static int override_serial;
 module_param(override_serial, bool, 0444);
 MODULE_PARM_DESC(override_serial,
The camera driver will normally refuse to load if 
the XO 1.5 serial port is enabled.  Set this option 
-   to force the issue.);
-#endif
+   to force-enable the camera.);
 
 /*
  * Basic window sizes.
@@ -1261,6 +1260,37 @@ static struct video_device viacam_v4l_template = {
.release= video_device_release_empty, /* Check this */
 };
 
+/*
+ * The OLPC folks put the serial port on the same pin as
+ * the camera. They also get grumpy if we break the
+ * serial port and keep them from using it.  So we have
+ * to check the serial enable bit and not step on it.
+ */
+#define VIACAM_SERIAL_DEVFN 0x88
+#define VIACAM_SERIAL_CREG 0x46
+#define VIACAM_SERIAL_BIT 0x40
+
+static __devinit bool viacam_serial_is_enabled(void)
+{
+   struct pci_bus *pbus = pci_find_bus(0, 0);
+   u8 cbyte;
+
+   pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
+   VIACAM_SERIAL_CREG, cbyte);
+   if ((cbyte  VIACAM_SERIAL_BIT) == 0)
+   return false; /* Not enabled */
+   if (override_serial == 0) {
+   printk(KERN_NOTICE Via camera: serial port is enabled,  \
+   refusing to load.\n);
+   printk(KERN_NOTICE Specify override_serial=1 to force  \
+   module loading.\n);
+   return true;
+   }
+   printk(KERN_NOTICE Via camera: overriding serial port\n);
+   pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
+   VIACAM_SERIAL_CREG, cbyte  ~VIACAM_SERIAL_BIT);
+   return false;
+}
 
 static __devinit int viacam_probe(struct platform_device *pdev)
 {
@@ -1292,6 +1322,10 @@ static __devinit int viacam_probe(struct platform_device 
*pdev)
printk(KERN_ERR viacam: No I/O memory, so no pictures\n);
return -ENOMEM;
}
+
+   if (machine_is_olpc()  viacam_serial_is_enabled())
+   return -EBUSY;
+
/*
 * Basic structure initialization.
 */
@@ -1395,7 +1429,6 @@ static __devexit int viacam_remove(struct platform_device 
*pdev)
return 0;
 }
 
-
 static struct platform_driver viacam_driver = {
.driver = {
.name = viafb-camera,
@@ -1404,50 +1437,8 @@ static struct platform_driver viacam_driver = {
.remove = viacam_remove,
 };
 
-
-#ifdef CONFIG_OLPC_XO_1_5
-/*
- * The OLPC folks put the serial port on the same pin as
- * the camera. They also get grumpy if we break the
- * serial port and keep them from using it.  So we have
- * to check the serial enable bit and not step on it.
- */
-#define VIACAM_SERIAL_DEVFN 0x88
-#define VIACAM_SERIAL_CREG 0x46
-#define VIACAM_SERIAL_BIT 0x40
-
-static __devinit int viacam_check_serial_port(void)
-{
-   struct pci_bus *pbus = pci_find_bus(0, 0);
-   u8 cbyte;
-
-   pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
-   VIACAM_SERIAL_CREG, cbyte);
-   if ((cbyte  VIACAM_SERIAL_BIT) == 0)
-   return 0; /* Not enabled */
-   if (override_serial == 0) {
-   printk(KERN_NOTICE Via camera: serial port is enabled,  \
-   refusing to load.\n);
-   printk(KERN_NOTICE Specify override_serial=1 to force  \
-   module loading.\n);
-   return -EBUSY;
-   }
-   printk(KERN_NOTICE Via camera: overriding serial port\n);
-   pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
-   VIACAM_SERIAL_CREG, cbyte  ~VIACAM_SERIAL_BIT);
-   return 0;
-}
-#endif
-
-
-
-
 static int viacam_init(void)
 {
-#ifdef CONFIG_OLPC_XO_1_5
-   if (viacam_check_serial_port())
-   return -EBUSY;
-#endif
return

Re: [PATCH] via-camera: fix OLPC serial port check

2010-10-28 Thread Daniel Drake
On 28 October 2010 20:08, Jonathan Corbet cor...@lwn.net wrote:
 This makes every user carry a bit of OLPC-specific code.  But there are
 no non-OLPC users currently, the code is small, and we get rid of some
 #ifdefs, which is always a good thing.  Seems good to me.

I think the compiler might be smart enough to optimize it out.
When CONFIG_OLPC=n, machine_is_olpc() compiles down to a simple no.
Hopefully that then makes all of that code candidate for dead code
elimination by the compiler.

Daniel
--
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] cafe_ccic: fix subdev configuration

2010-10-27 Thread Daniel Drake
For some reason, commit 1aafeb30104a is missing one change that was
included in the email submission.

The sensor configuration must be passed down to the ov7670 subdev.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/cafe_ccic.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 8a07906..21f6f06 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -2065,8 +2065,9 @@ static int cafe_pci_probe(struct pci_dev *pdev,
sensor_cfg.clock_speed = 45;
 
cam-sensor_addr = 0x42;
-   cam-sensor = v4l2_i2c_new_subdev(cam-v4l2_dev, cam-i2c_adapter,
-   NULL, ov7670, cam-sensor_addr, NULL);
+   cam-sensor = v4l2_i2c_new_subdev_cfg(cam-v4l2_dev, cam-i2c_adapter,
+   ov7670, ov7670, 0, sensor_cfg, cam-sensor_addr,
+   NULL);
if (cam-sensor == NULL) {
ret = -ENODEV;
goto out_smbus;
-- 
1.7.2.3

--
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] cafe_ccic: fix colorspace corruption on resume

2010-10-27 Thread Daniel Drake
If you suspend and resume during video capture, the video colours
are corrupted on resume. This is because the sensor is being unconditionally
powered off during the resume path.

Only power down during resume if the camera is not in use, and correctly
reconfigure the sensor during resume.
Fixes http://dev.laptop.org/ticket/10190

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/cafe_ccic.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 7bc3667..d147525 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -859,8 +859,6 @@ static int cafe_cam_configure(struct cafe_camera *cam)
struct v4l2_mbus_framefmt mbus_fmt;
int ret;
 
-   if (cam-state != S_IDLE)
-   return -EINVAL;
v4l2_fill_mbus_format(mbus_fmt, cam-pix_format, cam-mbus_code);
ret = sensor_call(cam, core, init, 0);
if (ret == 0)
@@ -2197,12 +2195,13 @@ static int cafe_pci_resume(struct pci_dev *pdev)
return ret;
}
cafe_ctlr_init(cam);
-   cafe_ctlr_power_down(cam);
 
mutex_lock(cam-s_mutex);
if (cam-users  0) {
cafe_ctlr_power_up(cam);
__cafe_cam_reset(cam);
+   } else {
+   cafe_ctlr_power_down(cam);
}
mutex_unlock(cam-s_mutex);
 
-- 
1.7.2.3

--
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] via-camera: fix OLPC serial port check

2010-10-27 Thread Daniel Drake
CONFIG_OLPC_XO_1_5 does not exist in mainline, and it's not certain that
we'll find a reason to add it later.

We should also be detecting this at runtime, and if we do it at probe
time we can be sure not to mess around with the PCI config space on XO-1.

viafb already depends on X86 so there won't be any problems including
the olpc.h header directly.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/via-camera.c |   82 ++
 1 files changed, 39 insertions(+), 43 deletions(-)

diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 02a21bc..118c26b 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -28,6 +28,8 @@
 #include linux/via-gpio.h
 #include linux/via_i2c.h
 
+#include asm/olpc.h
+
 #include via-camera.h
 
 MODULE_AUTHOR(Jonathan Corbet cor...@lwn.net);
@@ -40,14 +42,12 @@ MODULE_PARM_DESC(flip_image,
If set, the sensor will be instructed to flip the image 
vertically.);
 
-#ifdef CONFIG_OLPC_XO_1_5
 static int override_serial;
 module_param(override_serial, bool, 0444);
 MODULE_PARM_DESC(override_serial,
The camera driver will normally refuse to load if 
the XO 1.5 serial port is enabled.  Set this option 
to force the issue.);
-#endif
 
 /*
  * Basic window sizes.
@@ -1276,6 +1276,40 @@ static struct video_device viacam_v4l_template = {
.release= video_device_release_empty, /* Check this */
 };
 
+/*
+ * The OLPC folks put the serial port on the same pin as
+ * the camera. They also get grumpy if we break the
+ * serial port and keep them from using it.  So we have
+ * to check the serial enable bit and not step on it.
+ */
+#define VIACAM_SERIAL_DEVFN 0x88
+#define VIACAM_SERIAL_CREG 0x46
+#define VIACAM_SERIAL_BIT 0x40
+
+static __devinit int viacam_check_serial_port(void)
+{
+   struct pci_bus *pbus = pci_find_bus(0, 0);
+   u8 cbyte;
+
+   if (!machine_is_olpc())
+   return 0;
+
+   pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
+   VIACAM_SERIAL_CREG, cbyte);
+   if ((cbyte  VIACAM_SERIAL_BIT) == 0)
+   return 0; /* Not enabled */
+   if (override_serial == 0) {
+   printk(KERN_NOTICE Via camera: serial port is enabled,  \
+   refusing to load.\n);
+   printk(KERN_NOTICE Specify override_serial=1 to force  \
+   module loading.\n);
+   return -EBUSY;
+   }
+   printk(KERN_NOTICE Via camera: overriding serial port\n);
+   pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
+   VIACAM_SERIAL_CREG, cbyte  ~VIACAM_SERIAL_BIT);
+   return 0;
+}
 
 static __devinit int viacam_probe(struct platform_device *pdev)
 {
@@ -1291,6 +1325,9 @@ static __devinit int viacam_probe(struct platform_device 
*pdev)
 */
struct via_camera *cam;
 
+   if (viacam_check_serial_port())
+   return -EBUSY;
+
/*
 * Ensure that frame buffer memory has been set aside for
 * this purpose.  As an arbitrary limit, refuse to work
@@ -1420,49 +1457,8 @@ static struct platform_driver viacam_driver = {
 };
 
 
-#ifdef CONFIG_OLPC_XO_1_5
-/*
- * The OLPC folks put the serial port on the same pin as
- * the camera. They also get grumpy if we break the
- * serial port and keep them from using it.  So we have
- * to check the serial enable bit and not step on it.
- */
-#define VIACAM_SERIAL_DEVFN 0x88
-#define VIACAM_SERIAL_CREG 0x46
-#define VIACAM_SERIAL_BIT 0x40
-
-static __devinit int viacam_check_serial_port(void)
-{
-   struct pci_bus *pbus = pci_find_bus(0, 0);
-   u8 cbyte;
-
-   pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
-   VIACAM_SERIAL_CREG, cbyte);
-   if ((cbyte  VIACAM_SERIAL_BIT) == 0)
-   return 0; /* Not enabled */
-   if (override_serial == 0) {
-   printk(KERN_NOTICE Via camera: serial port is enabled,  \
-   refusing to load.\n);
-   printk(KERN_NOTICE Specify override_serial=1 to force  \
-   module loading.\n);
-   return -EBUSY;
-   }
-   printk(KERN_NOTICE Via camera: overriding serial port\n);
-   pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
-   VIACAM_SERIAL_CREG, cbyte  ~VIACAM_SERIAL_BIT);
-   return 0;
-}
-#endif
-
-
-
-
 static int viacam_init(void)
 {
-#ifdef CONFIG_OLPC_XO_1_5
-   if (viacam_check_serial_port())
-   return -EBUSY;
-#endif
return platform_driver_register(viacam_driver);
 }
 module_init(viacam_init);
-- 
1.7.2.3

--
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] ov7670: allow configuration of image size, clock speed, and I/O method

2010-10-19 Thread Daniel Drake
These parameters need to be configurable based on the host system.
They can now be communicated through the s_config call.

The old CONFIG_OLPC_XO_1 selector was not correct; this kind of
arrangement wouldn't allow for a universal kernel that would work on both
laptops.

Certain parts of the probe routine had to be moved later (into s_config),
because we can't do any I/O until we know which I/O method has been
selected through this mechanism.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/ov7670.c |  133 ++
 drivers/media/video/ov7670.h |   20 ++
 2 files changed, 115 insertions(+), 38 deletions(-)
 create mode 100644 drivers/media/video/ov7670.h

diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 0b78f33..c881a64 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -20,6 +20,7 @@
 #include media/v4l2-chip-ident.h
 #include media/v4l2-mediabus.h
 
+#include ov7670.h
 
 MODULE_AUTHOR(Jonathan Corbet cor...@lwn.net);
 MODULE_DESCRIPTION(A low-level driver for OmniVision ov7670 sensors);
@@ -43,11 +44,6 @@ MODULE_PARM_DESC(debug, Debug level (0-1));
 #defineQCIF_HEIGHT 144
 
 /*
- * Our nominal (default) frame rate.
- */
-#define OV7670_FRAME_RATE 30
-
-/*
  * The 7670 sits on i2c with ID 0x42
  */
 #define OV7670_I2C_ADDR 0x42
@@ -198,7 +194,11 @@ struct ov7670_info {
struct ov7670_format_struct *fmt;  /* Current format */
unsigned char sat;  /* Saturation value */
int hue;/* Hue value */
+   int min_width;  /* Filter out smaller sizes */
+   int min_height; /* Filter out smaller sizes */
+   int clock_speed;/* External clock speed (MHz) */
u8 clkrc;   /* Clock divider value */
+   bool use_smbus; /* Use smbus I/O instead of I2C */
 };
 
 static inline struct ov7670_info *to_state(struct v4l2_subdev *sd)
@@ -415,8 +415,7 @@ static struct regval_list ov7670_fmt_raw[] = {
  * ov7670 is not really an SMBUS device, though, so the communication
  * is not always entirely reliable.
  */
-#ifdef CONFIG_OLPC_XO_1
-static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
+static int ov7670_read_smbus(struct v4l2_subdev *sd, unsigned char reg,
unsigned char *value)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -431,7 +430,7 @@ static int ov7670_read(struct v4l2_subdev *sd, unsigned 
char reg,
 }
 
 
-static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
+static int ov7670_write_smbus(struct v4l2_subdev *sd, unsigned char reg,
unsigned char value)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -442,11 +441,10 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned 
char reg,
return ret;
 }
 
-#else /* ! CONFIG_OLPC_XO_1 */
 /*
  * On most platforms, we'd rather do straight i2c I/O.
  */
-static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
+static int ov7670_read_i2c(struct v4l2_subdev *sd, unsigned char reg,
unsigned char *value)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -479,7 +477,7 @@ static int ov7670_read(struct v4l2_subdev *sd, unsigned 
char reg,
 }
 
 
-static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
+static int ov7670_write_i2c(struct v4l2_subdev *sd, unsigned char reg,
unsigned char value)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -498,8 +496,26 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned 
char reg,
msleep(5);  /* Wait for reset to run */
return ret;
 }
-#endif /* CONFIG_OLPC_XO_1 */
 
+static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
+   unsigned char *value)
+{
+   struct ov7670_info *info = to_state(sd);
+   if (info-use_smbus)
+   return ov7670_read_smbus(sd, reg, value);
+   else
+   return ov7670_read_i2c(sd, reg, value);
+}
+
+static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
+   unsigned char value)
+{
+   struct ov7670_info *info = to_state(sd);
+   if (info-use_smbus)
+   return ov7670_write_smbus(sd, reg, value);
+   else
+   return ov7670_write_i2c(sd, reg, value);
+}
 
 /*
  * Write a list of register settings; ff/ff stops the process.
@@ -854,7 +870,7 @@ static int ov7670_g_parm(struct v4l2_subdev *sd, struct 
v4l2_streamparm *parms)
memset(cp, 0, sizeof(struct v4l2_captureparm));
cp-capability = V4L2_CAP_TIMEPERFRAME;
cp-timeperframe.numerator = 1;
-   cp-timeperframe.denominator = OV7670_FRAME_RATE;
+   cp-timeperframe.denominator = info-clock_speed;
if ((info-clkrc  CLK_EXT) == 0  (info-clkrc  CLK_SCALE)  1)
cp-timeperframe.denominator /= (info-clkrc

[PATCH 2/2] cafe_ccic: Configure ov7670 correctly

2010-10-19 Thread Daniel Drake
Force smbus communication, disable QCIF mode, and set the correct
clock speed on the OLPC XO-1.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/cafe_ccic.c |   33 +++--
 1 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index b4f5b3b..4378597 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -25,6 +25,7 @@
 #include linux/module.h
 #include linux/init.h
 #include linux/fs.h
+#include linux/dmi.h
 #include linux/mm.h
 #include linux/pci.h
 #include linux/i2c.h
@@ -46,6 +47,7 @@
 #include asm/uaccess.h
 #include asm/io.h
 
+#include ov7670.h
 #include cafe_ccic-regs.h
 
 #define CAFE_VERSION 0x02
@@ -1974,11 +1976,33 @@ static irqreturn_t cafe_irq(int irq, void *data)
  * PCI interface stuff.
  */
 
+static const struct dmi_system_id olpc_xo1_dmi[] = {
+   {
+   .matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, OLPC),
+   DMI_MATCH(DMI_PRODUCT_NAME, XO),
+   DMI_MATCH(DMI_PRODUCT_VERSION, 1),
+   },
+   },
+   { }
+};
+
 static int cafe_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
 {
int ret;
struct cafe_camera *cam;
+   struct ov7670_config sensor_cfg = {
+   /* This controller only does SMBUS */
+   .use_smbus = true,
+
+   /*
+* Exclude QCIF mode, because it only captures a tiny portion
+* of the sensor FOV
+*/
+   .min_width = 320,
+   .min_height = 240,
+   };
 
/*
 * Start putting together one of our big camera structures.
@@ -2036,13 +2060,18 @@ static int cafe_pci_probe(struct pci_dev *pdev,
if (ret)
goto out_freeirq;
 
+   /* Apply XO-1 clock speed */
+   if (dmi_check_system(olpc_xo1_dmi))
+   sensor_cfg.clock_speed = 45;
+
cam-sensor_addr = 0x42;
-   cam-sensor = v4l2_i2c_new_subdev(cam-v4l2_dev, cam-i2c_adapter,
-   ov7670, ov7670, cam-sensor_addr, NULL);
+   cam-sensor = v4l2_i2c_new_subdev_cfg(cam-v4l2_dev, cam-i2c_adapter,
+   ov7670, ov7670, 0, sensor_cfg, cam-sensor_addr, NULL);
if (cam-sensor == NULL) {
ret = -ENODEV;
goto out_smbus;
}
+
ret = cafe_cam_init(cam);
if (ret)
goto out_smbus;
-- 
1.7.2.3

--
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] ov7670: fix QVGA visible area

2010-10-18 Thread Daniel Drake
The QVGA mode has a green horizontal line on the left hand side, and a red
(or sometimes blue) vertical line at the bottom. Tweak the visible area
to remove them.

Thanks to Mauro for explaining how to fix this.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/ov7670.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index a18dcd0..0b78f33 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -675,10 +675,10 @@ static struct ov7670_win_size {
.width  = QVGA_WIDTH,
.height = QVGA_HEIGHT,
.com7_bit   = COM7_FMT_QVGA,
-   .hstart = 164,  /* Empirically determined */
-   .hstop  =  20,
-   .vstart =  14,
-   .vstop  = 494,
+   .hstart = 168,  /* Empirically determined */
+   .hstop  =  24,
+   .vstart =  12,
+   .vstop  = 492,
.regs   = NULL,
},
/* QCIF */
-- 
1.7.2.3

--
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/3] ov7670: remove QCIF mode

2010-10-08 Thread Daniel Drake
This super-low-resolution mode only captures from a small portion of
the sensor FOV, making it a bit useless.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/ov7670.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index a18dcd0..7017e5c 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -618,6 +618,7 @@ static struct ov7670_format_struct {
  * which is allegedly provided by the sensor.  So here's the weird register
  * settings.
  */
+#if 0
 static struct regval_list ov7670_qcif_regs[] = {
{ REG_COM3, COM3_SCALEEN|COM3_DCWEN },
{ REG_COM3, COM3_DCWEN },
@@ -636,6 +637,7 @@ static struct regval_list ov7670_qcif_regs[] = {
{ REG_COM13, 0xc0 },
{ 0xff, 0xff },
 };
+#endif
 
 static struct ov7670_win_size {
int width;
@@ -681,7 +683,8 @@ static struct ov7670_win_size {
.vstop  = 494,
.regs   = NULL,
},
-   /* QCIF */
+#if 0
+   /* QCIF - disabled because it only shows a small portion of sensor FOV 
*/
{
.width  = QCIF_WIDTH,
.height = QCIF_HEIGHT,
@@ -692,6 +695,7 @@ static struct ov7670_win_size {
.vstop  = 494,
.regs   = ov7670_qcif_regs,
},
+#endif
 };
 
 #define N_WIN_SIZES (ARRAY_SIZE(ov7670_win_sizes))
-- 
1.7.2.3

--
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 2/3] ov7670: disable QVGA mode

2010-10-08 Thread Daniel Drake
Capturing at this resolution results in an ugly green horizontal line
at the left side of the image. Disable until fixed.

http://dev.laptop.org/ticket/10231

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/ov7670.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 7017e5c..9fffcdd 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -672,7 +672,9 @@ static struct ov7670_win_size {
.vstop  = 494,
.regs   = NULL,
},
-   /* QVGA */
+#if 0
+   /* QVGA - disabled due to ugly green line.
+* http://dev.laptop.org/ticket/10231 */
{
.width  = QVGA_WIDTH,
.height = QVGA_HEIGHT,
@@ -683,6 +685,7 @@ static struct ov7670_win_size {
.vstop  = 494,
.regs   = NULL,
},
+#endif
 #if 0
/* QCIF - disabled because it only shows a small portion of sensor FOV 
*/
{
-- 
1.7.2.3

--
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 3/3] ov7670: Support customization of clock speed

2010-10-08 Thread Daniel Drake
For accurate frame rate limiting, we need to know the speed of the external
clock wired into the ov7670 chip.

Add a module parameter so that the user can specify this information.
And add DMI detection for appropriate clock speeds on the OLPC XO-1 and
XO-1.5 laptops. If specified, the module parameter wins over whatever we
might have set through the DMI table.

Based on earlier work by Jonathan Corbet.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/ov7670.c |   71 -
 1 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 9fffcdd..c4d9ed0 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -16,6 +16,7 @@
 #include linux/i2c.h
 #include linux/delay.h
 #include linux/videodev2.h
+#include linux/dmi.h
 #include media/v4l2-device.h
 #include media/v4l2-chip-ident.h
 #include media/v4l2-mediabus.h
@@ -30,6 +31,19 @@ module_param(debug, bool, 0644);
 MODULE_PARM_DESC(debug, Debug level (0-1));
 
 /*
+ * What is our fastest frame rate?  It's a function of how the chip
+ * is clocked, and this is an external clock, so we don't know. If we have
+ * a DMI entry describing the platform, use it. If not, assume 30. In both
+ * cases, accept override from a module parameter.
+ */
+static int clock_speed = 30;
+static bool clock_speed_from_param = false;
+static int set_clock_speed_from_param(const char *val, struct kernel_param 
*kp);
+module_param_call(clock_speed, set_clock_speed_from_param, param_get_int,
+ clock_speed, 0440);
+MODULE_PARM_DESC(clock_speed, External clock speed (Hz));
+
+/*
  * Basic window sizes.  These probably belong somewhere more globally
  * useful.
  */
@@ -43,11 +57,6 @@ MODULE_PARM_DESC(debug, Debug level (0-1));
 #defineQCIF_HEIGHT 144
 
 /*
- * Our nominal (default) frame rate.
- */
-#define OV7670_FRAME_RATE 30
-
-/*
  * The 7670 sits on i2c with ID 0x42
  */
 #define OV7670_I2C_ADDR 0x42
@@ -188,6 +197,44 @@ MODULE_PARM_DESC(debug, Debug level (0-1));
 #define REG_HAECC7 0xaa/* Hist AEC/AGC control 7 */
 #define REG_BD60MAX0xab/* 60hz banding step limit */
 
+static int set_clock_speed_from_param(const char *val, struct kernel_param *kp)
+{
+   int ret = param_set_int(val, kp);
+   if (ret == 0)
+   clock_speed_from_param = true;
+   return ret;
+}
+
+static int __init set_clock_speed_from_dmi(const struct dmi_system_id *dmi)
+{
+   if (clock_speed_from_param)
+   return 0; /* module param beats DMI */
+
+   clock_speed = (int) dmi-driver_data;
+   return 0;
+}
+
+static const struct dmi_system_id __initconst dmi_clock_speeds[] = {
+   {
+   .callback = set_clock_speed_from_dmi,
+   .driver_data = (void *) 45,
+   .matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, OLPC),
+   DMI_MATCH(DMI_PRODUCT_NAME, XO),
+   DMI_MATCH(DMI_PRODUCT_VERSION, 1),
+   },
+   },
+   {
+   .callback = set_clock_speed_from_dmi,
+   .driver_data = (void *) 90,
+   .matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, OLPC),
+   DMI_MATCH(DMI_PRODUCT_NAME, XO),
+   DMI_MATCH(DMI_PRODUCT_VERSION, 1.5),
+   },
+   },
+   { }
+};
 
 /*
  * Information we maintain about a known sensor.
@@ -861,7 +908,7 @@ static int ov7670_g_parm(struct v4l2_subdev *sd, struct 
v4l2_streamparm *parms)
memset(cp, 0, sizeof(struct v4l2_captureparm));
cp-capability = V4L2_CAP_TIMEPERFRAME;
cp-timeperframe.numerator = 1;
-   cp-timeperframe.denominator = OV7670_FRAME_RATE;
+   cp-timeperframe.denominator = clock_speed;
if ((info-clkrc  CLK_EXT) == 0  (info-clkrc  CLK_SCALE)  1)
cp-timeperframe.denominator /= (info-clkrc  CLK_SCALE);
return 0;
@@ -882,14 +929,14 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct 
v4l2_streamparm *parms)
if (tpf-numerator == 0 || tpf-denominator == 0)
div = 1;  /* Reset to full rate */
else
-   div = (tpf-numerator*OV7670_FRAME_RATE)/tpf-denominator;
+   div = (tpf-numerator*clock_speed)/tpf-denominator;
if (div == 0)
div = 1;
else if (div  CLK_SCALE)
div = CLK_SCALE;
info-clkrc = (info-clkrc  0x80) | div;
tpf-numerator = 1;
-   tpf-denominator = OV7670_FRAME_RATE/div;
+   tpf-denominator = clock_speed/div;
return ov7670_write(sd, REG_CLKRC, info-clkrc);
 }
 
@@ -1510,10 +1557,15 @@ static int ov7670_probe(struct i2c_client *client,
}
v4l_info(client, chip found @ 0x%02x (%s)\n,
client-addr  1, client-adapter-name);
+   /*
+* Make sure the clock speed is rational

Passing info from main dev to subdev

2010-10-08 Thread Daniel Drake
Hi,

The cafe_ccic + ov7670 combination is currently broken in mainstream
on the OLPC XO-1 laptop because of it's move to i2c (2bf7de4), in
order to work on the new XO-1.5 laptop. The smbus IO code was brought
back in 467142093 but this code is never triggered - CONFIG_OLPC_XO_1
doesn't exist.

I would like to do this at runtime, since we should aim to have a
kernel that can run on both XO-1 and XO-1.5.
So, I would like ov7670 to support both methods (i2c and smbus) and
for the parent device (cafe_ccic on XO-1, via-camera on XO-1.5) to
declare which one to use.

So my question: how can I communicate such info from parent to subdev?
Just the value of 1 variable would be enough.

Thanks,
Daniel
--
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/3] ov7670: remove QCIF mode

2010-10-08 Thread Daniel Drake
On 8 October 2010 22:11, Jonathan Corbet cor...@lwn.net wrote:
 I'm certainly not attached to this mode, but...does it harm anybody if
 it's there?

Yes. Applications like gstreamer will pick this resolution if its the
closest resolution to the target file resolution. On XO-1 we always
pick a low res so gstreamer picks this one. And we end up with a video
that only records a miniscule portion of the FOV.

All the other settings of the camera scale the image so that the whole
FOV is covered. But this one records at normal resolution, only
sending a small center portion of the FOV. The same pixels can be read
by recording at full res and then just cutting out the center bit.

Daniel
--
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 2/3] ov7670: disable QVGA mode

2010-10-08 Thread Daniel Drake
On 8 October 2010 22:13, Jonathan Corbet cor...@lwn.net wrote:
 A problem like that will be at the controller level, not the sensor
 level.  Given that this is an XO-1 report, I'd assume something
 requires tweaking in the cafe_ccic driver.  I wasn't aware of this; I
 know it worked once upon a time.

I reported it 3 months ago
http://dev.laptop.org/ticket/10231

Are you interested in working on this?
I'd have no idea where to start.

I'm not so convinced that it's a controller problem rather than a
sensor one, given that it says the sensor register values were
determined empirically rather than from docs.

Thanks,
Daniel
--
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


pending ov7670/cafe_ccic patches

2010-10-02 Thread Daniel Drake
Hi Mauro,

Just a quick reminder about 4 pending cafe_ccic/ov7670 patches, all
acked by Jon Corbet:

http://www.spinics.net/lists/linux-media/msg23371.html
http://www.spinics.net/lists/linux-media/msg23373.html
http://www.spinics.net/lists/linux-media/msg23372.html
http://www.spinics.net/lists/linux-media/msg23369.html

The patches were made against linus master so don't account for
changes that have happened since then (such as the mbus stuff).
However the patches are all still valid without modification and git's
default merge algo applies them just fine. Let me know if you'd like
me to resend them anyway based on your latest tree.

cheers
Daniel
--
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 4/4] cafe_ccic: Implement VIDIOC_ENUM_FRAMEINTERVALS and ENUM_FRAMESIZES

2010-09-24 Thread Daniel Drake
This allows GStreamer to pick appropriate framerates and resolutions
based on desired capture parameters.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/cafe_ccic.c |   26 ++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 8ddd2b6..09ec476 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1650,6 +1650,30 @@ static int cafe_vidioc_g_chip_ident(struct file *file, 
void *priv,
return sensor_call(cam, core, g_chip_ident, chip);
 }
 
+static int cafe_vidioc_enum_framesizes(struct file *filp, void *priv,
+   struct v4l2_frmsizeenum *sizes)
+{
+   struct cafe_camera *cam = priv;
+   int ret;
+
+   mutex_lock(cam-s_mutex);
+   ret = sensor_call(cam, video, enum_framesizes, sizes);
+   mutex_unlock(cam-s_mutex);
+   return ret;
+}
+
+static int cafe_vidioc_enum_frameintervals(struct file *filp, void *priv,
+   struct v4l2_frmivalenum *interval)
+{
+   struct cafe_camera *cam = priv;
+   int ret;
+
+   mutex_lock(cam-s_mutex);
+   ret = sensor_call(cam, video, enum_frameintervals, interval);
+   mutex_unlock(cam-s_mutex);
+   return ret;
+}
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cafe_vidioc_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg)
@@ -1713,6 +1737,8 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
.vidioc_s_ctrl  = cafe_vidioc_s_ctrl,
.vidioc_g_parm  = cafe_vidioc_g_parm,
.vidioc_s_parm  = cafe_vidioc_s_parm,
+   .vidioc_enum_framesizes = cafe_vidioc_enum_framesizes,
+   .vidioc_enum_frameintervals = cafe_vidioc_enum_frameintervals,
.vidioc_g_chip_ident= cafe_vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register  = cafe_vidioc_g_register,
-- 
1.7.2.2

--
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/4] cafe_ccic: Fix hang in command write processing

2010-09-24 Thread Daniel Drake
This patch, which basically reverts 6d77444ac, fixes an occasional
on-boot or on-capture hang on the XO-1 laptop.

It seems like the cafe hardware is flakier than we thought and that in
some cases, the commands get executed but are never reported as completed
(even if we substantially increase the delays before reading registers).

Reintroduce the 1-second CAFE_SMBUS_TIMEOUT to catch and avoid this
strange hardware bug.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/cafe_ccic.c |   36 +---
 1 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index be35e69..8ddd2b6 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -319,7 +319,6 @@ static int cafe_smbus_write_data(struct cafe_camera *cam,
 {
unsigned int rval;
unsigned long flags;
-   DEFINE_WAIT(the_wait);
 
spin_lock_irqsave(cam-dev_lock, flags);
rval = TWSIC0_EN | ((addr  TWSIC0_SID_SHIFT)  TWSIC0_SID);
@@ -334,28 +333,27 @@ static int cafe_smbus_write_data(struct cafe_camera *cam,
cafe_reg_write(cam, REG_TWSIC1, rval);
spin_unlock_irqrestore(cam-dev_lock, flags);
 
+   /* Unfortunately, reading TWSIC1 too soon after sending a command
+* causes the device to die.
+* Use a busy-wait because we often send a large quantity of small
+* commands at-once; using msleep() would cause a lot of context
+* switches which take longer than 2ms, resulting in a noticable
+* boot-time and capture-start delays.
+*/
+   mdelay(2);
+
/*
-* Time to wait for the write to complete.  THIS IS A RACY
-* WAY TO DO IT, but the sad fact is that reading the TWSIC1
-* register too quickly after starting the operation sends
-* the device into a place that may be kinder and better, but
-* which is absolutely useless for controlling the sensor.  In
-* practice we have plenty of time to get into our sleep state
-* before the interrupt hits, and the worst case is that we
-* time out and then see that things completed, so this seems
-* the best way for now.
+* Another sad fact is that sometimes, commands silently complete but
+* cafe_smbus_write_done() never becomes aware of this.
+* This happens at random and appears to possible occur with any
+* command.
+* We don't understand why this is. We work around this issue
+* with the timeout in the wait below, assuming that all commands
+* complete within the timeout.
 */
-   do {
-   prepare_to_wait(cam-smbus_wait, the_wait,
-   TASK_UNINTERRUPTIBLE);
-   schedule_timeout(1); /* even 1 jiffy is too long */
-   finish_wait(cam-smbus_wait, the_wait);
-   } while (!cafe_smbus_write_done(cam));
-
-#ifdef IF_THE_CAFE_HARDWARE_WORKED_RIGHT
wait_event_timeout(cam-smbus_wait, cafe_smbus_write_done(cam),
CAFE_SMBUS_TIMEOUT);
-#endif
+
spin_lock_irqsave(cam-dev_lock, flags);
rval = cafe_reg_read(cam, REG_TWSIC1);
spin_unlock_irqrestore(cam-dev_lock, flags);
-- 
1.7.2.2

--
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 2/4] ov7670: implement VIDIOC_ENUM_FRAMEINTERVALS

2010-09-24 Thread Daniel Drake
From: Jonathan Corbet cor...@lwn.net

Inquiring minds (and gstreamer) want to know.

Signed-off-by: Jonathan Corbet cor...@lwn.net
Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/ov7670.c |   21 ++---
 1 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 91c886a..f551f63 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -896,14 +896,28 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct 
v4l2_streamparm *parms)
 }
 
 
-
 /*
- * Code for dealing with controls.
+ * Frame intervals.  Since frame rates are controlled with the clock
+ * divider, we can only do 30/n for integer n values.  So no continuous
+ * or stepwise options.  Here we just pick a handful of logical values.
  */
 
+static int ov7670_frame_rates[] = { 30, 15, 10, 5, 1 };
 
+static int ov7670_enum_frameintervals(struct v4l2_subdev *sd,
+   struct v4l2_frmivalenum *interval)
+{
+   if (interval-index = ARRAY_SIZE(ov7670_frame_rates))
+   return -EINVAL;
+   interval-type = V4L2_FRMIVAL_TYPE_DISCRETE;
+   interval-discrete.numerator = 1;
+   interval-discrete.denominator = ov7670_frame_rates[interval-index];
+   return 0;
+}
 
-
+/*
+ * Code for dealing with controls.
+ */
 
 static int ov7670_store_cmatrix(struct v4l2_subdev *sd,
int matrix[CMATRIX_LEN])
@@ -1447,6 +1461,7 @@ static const struct v4l2_subdev_video_ops 
ov7670_video_ops = {
.s_fmt = ov7670_s_fmt,
.s_parm = ov7670_s_parm,
.g_parm = ov7670_g_parm,
+   .enum_frameintervals = ov7670_enum_frameintervals,
 };
 
 static const struct v4l2_subdev_ops ov7670_ops = {
-- 
1.7.2.2

--
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 3/4] ov7670: implement VIDIOC_ENUM_FRAMESIZES

2010-09-24 Thread Daniel Drake
GStreamer uses this.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/ov7670.c |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index f551f63..214cebf 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -916,6 +916,22 @@ static int ov7670_enum_frameintervals(struct v4l2_subdev 
*sd,
 }
 
 /*
+ * Frame size enumeration
+ */
+static int ov7670_enum_framesizes(struct v4l2_subdev *sd,
+   struct v4l2_frmsizeenum *fsize)
+{
+   __u32 index = fsize-index;
+   if (index = N_WIN_SIZES)
+   return -EINVAL;
+
+   fsize-type = V4L2_FRMSIZE_TYPE_DISCRETE;
+   fsize-discrete.width = ov7670_win_sizes[index].width;
+   fsize-discrete.height = ov7670_win_sizes[index].height;
+   return 0;
+}
+
+/*
  * Code for dealing with controls.
  */
 
@@ -1462,6 +1478,7 @@ static const struct v4l2_subdev_video_ops 
ov7670_video_ops = {
.s_parm = ov7670_s_parm,
.g_parm = ov7670_g_parm,
.enum_frameintervals = ov7670_enum_frameintervals,
+   .enum_framesizes = ov7670_enum_framesizes,
 };
 
 static const struct v4l2_subdev_ops ov7670_ops = {
-- 
1.7.2.2

--
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