From e163609ef77f065dbf3936dcb8f5ffcf6d19b35c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 30 Jun 2012 09:03:21 -0300 Subject: [media] gspca_konica: Fix init sequence The konica needs a freaking large time (circa 6.5 seconds) to "boot", and does not want to be bothered while doing so, so sleep for 6 seconds, and then query its status register at 100ms intervals until it becomes ready. This removes the "reg_w err: -32" messages shown in dmesg whenever a konica cam gets initialized, and also fixes the camera not working when an app tries to use it directly after it has been plugged in and after a suspend/resume cycle. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/konica.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c index 46e1ae402767..bbf91e07e38b 100644 --- a/drivers/media/video/gspca/konica.c +++ b/drivers/media/video/gspca/konica.c @@ -103,7 +103,8 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index) 0, 1000); if (ret < 0) { - pr_err("reg_w err %d\n", ret); + pr_err("reg_w err writing %02x to %02x: %d\n", + value, index, ret); gspca_dev->usb_err = ret; } } @@ -124,7 +125,7 @@ static void reg_r(struct gspca_dev *gspca_dev, u16 value, u16 index) 2, 1000); if (ret < 0) { - pr_err("reg_w err %d\n", ret); + pr_err("reg_r err %d\n", ret); gspca_dev->usb_err = ret; } } @@ -153,16 +154,23 @@ static int sd_config(struct gspca_dev *gspca_dev, /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - /* HDG not sure if these 2 reads are needed */ - reg_r(gspca_dev, 0, 0x10); - PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x", - gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); - reg_r(gspca_dev, 0, 0x10); - PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x", - gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); + int i; + + /* + * The konica needs a freaking large time to "boot" (approx 6.5 sec.), + * and does not want to be bothered while doing so :| + * Register 0x10 counts from 1 - 3, with 3 being "ready" + */ + msleep(6000); + for (i = 0; i < 20; i++) { + reg_r(gspca_dev, 0, 0x10); + if (gspca_dev->usb_buf[0] == 3) + break; + msleep(100); + } reg_w(gspca_dev, 0, 0x0d); - return 0; + return gspca_dev->usb_err; } static int sd_start(struct gspca_dev *gspca_dev) -- cgit v1.2.3