We had some problems with sensor probing and decided to use a new procdure.
Here is my second try to solve that. The first two paches are not vital but I didn't want to rebase.It currently breaks the module since I have no idea how to assign the correct formats and resolutions. I also remeber Brian had developed a new system for to make YUV422 work. Maybe we can include this right now.
Let's get this over done. GWater
From 805eb0cd70a4fb7e3fd9d624f4c5a918b9ea133a Mon Sep 17 00:00:00 2001
From: GWater <[EMAIL PROTECTED]>
Date: Sat, 15 Nov 2008 14:09:12 +0100
Subject: [PATCH] Add YUV422-output for MT9V111 sensors
Signed-off-by: GWater <[EMAIL PROTECTED]>
---
micron.c | 42 +++++++++++++++++++++++++++++++++++++++++-
1 files changed, 41 insertions(+), 1 deletions(-)
diff --git a/micron.c b/micron.c
index cc70fec..d263cbe 100644
--- a/micron.c
+++ b/micron.c
@@ -71,7 +71,13 @@ struct microdia_video_format mt9v111_fmts[] = {
.pix_fmt = V4L2_PIX_FMT_SBGGR8,
.desc = "Bayer 8bit (BGGR)",
.depth = 8,
- .set_format = sn9c20x_set_raw
+ .set_format = mt9v111_set_raw
+ },
+ {
+ .pix_fmt = V4L2_PIX_FMT_YUYV,
+ .desc = "YUV 4:2:2",
+ .depth = 16,
+ .set_format = mt9v111_set_yuv422
},
{
.pix_fmt = V4L2_PIX_FMT_JPEG,
@@ -597,6 +603,40 @@ int mt9v111_probe(struct usb_microdia *dev)
return -EINVAL;
}
+int mt9v111_set_raw(struct usb_microdia *dev)
+{
+ __u16 buf;
+
+ mt9v111_select_address_space(dev, MT9V111_ADDRESSSPACE_IFP);
+
+ sn9c20x_read_i2c_data16(dev, 1, 0x08, &buf);
+ buf = (buf & 0xef7f) + 0x1080;
+ sn9c20x_write_i2c_data16(dev, 1, 0x08, &buf);
+
+ sn9c20x_set_raw(dev);
+
+ return 0;
+}
+
+int mt9v111_set_yuv422(struct usb_microdia *dev)
+{
+ __u16 buf;
+
+ mt9v111_select_address_space(dev, MT9V111_ADDRESSSPACE_IFP);
+
+ sn9c20x_read_i2c_data16(dev, 1, 0x08, &buf);
+ buf &= 0xef7f;
+ sn9c20x_write_i2c_data16(dev, 1, 0x08, &buf);
+
+ sn9c20x_read_i2c_data16(dev, 1, 0x3a, &buf);
+ buf &= 0xffde;
+ sn9c20x_write_i2c_data16(dev, 1, 0x3a, &buf);
+
+ sn9c20x_set_raw(dev);
+
+ return 0;
+}
+
/**
* @brief Initialize mt9m111 sensors
*
--
1.5.6.5
From ebaf7d2cba2738962877eb961916a71db3577aa7 Mon Sep 17 00:00:00 2001
From: GWater <[EMAIL PROTECTED]>
Date: Fri, 14 Nov 2008 19:14:27 +0100
Subject: [PATCH] Add sensor MT9V112 used in 6270 devices
The sensor supports YUV442 and 10-bit Bayer output.
JPEG is available via sn9c20x.
However YUV422 output is disabled until we get it to work.
Signed-off-by: GWater <[EMAIL PROTECTED]>
---
microdia-dev.c | 6 ++++
microdia.h | 1 +
micron.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
micron.h | 2 +
4 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/microdia-dev.c b/microdia-dev.c
index f3cdf4d..a233ab9 100644
--- a/microdia-dev.c
+++ b/microdia-dev.c
@@ -88,6 +88,12 @@ struct sensor_info sensors[] = {
.address = 0x5d,
.probe = mt9m001_probe
},
+ {
+ .id = MT9V112_SENSOR,
+ .name = "MT9V112",
+ .address = 0x5d,
+ .probe = mt9v112_probe
+ },
};
/**
diff --git a/microdia.h b/microdia.h
index 09f3e9f..6f18e09 100644
--- a/microdia.h
+++ b/microdia.h
@@ -311,6 +311,7 @@ enum microdia_sensors {
MT9V111_SENSOR = 7,
MT9V011_SENSOR = 8,
MT9M001_SENSOR = 9,
+ MT9V112_SENSOR = 10,
};
diff --git a/micron.c b/micron.c
index d263cbe..57c113f 100644
--- a/micron.c
+++ b/micron.c
@@ -52,12 +52,12 @@ struct microdia_video_format mt9m111_fmts[] = {
.depth = 8,
.set_format = mt9m111_set_raw
},
- {
+ /*{
.pix_fmt = V4L2_PIX_FMT_YUYV,
.desc = "YUV 4:2:2",
.depth = 16,
.set_format = mt9m111_set_yuv422
- },
+ },*/
{
.pix_fmt = V4L2_PIX_FMT_JPEG,
.desc = "JPEG (YUV 4:2:2)",
@@ -425,6 +425,74 @@ static __u8 mt9m001_init[][3] = {
{0x2e, 0x00, 0x24}, {0x07, 0x00, 0x02},
};
+static __u8 mt9v112_init[][3] = {
+ {0x0d, 0x00, 0x21}, {0x0d, 0x00, 0x20}, {0xf0, 0x00, 0x00},
+ {0x34, 0xc0, 0x19}, {0x0a, 0x00, 0x11}, {0x0b, 0x00, 0x0b},
+ {0x20, 0x07, 0x03}, {0x35, 0x20, 0x22}, {0xf0, 0x00, 0x01},
+ {0x05, 0x00, 0x00}, {0x06, 0x34, 0x0c}, {0x3b, 0x04, 0x2a},
+ {0x3c, 0x04, 0x00}, {0xf0, 0x00, 0x02}, {0x2e, 0x0c, 0x58},
+ {0x5b, 0x00, 0x01}, {0xc8, 0x9f, 0x0b}, {0xf0, 0x00, 0x01},
+ {0x9b, 0x53, 0x00}, {0xf0, 0x00, 0x00}, {0x2b, 0x00, 0x20},
+ {0x2c, 0x00, 0x2a}, {0x2d, 0x00, 0x32}, {0x2e, 0x00, 0x20},
+ {0x09, 0x01, 0xdc}, {0x01, 0x00, 0x0c}, {0x02, 0x00, 0x20},
+ {0x03, 0x01, 0xe0}, {0x04, 0x02, 0x80}, {0x06, 0x00, 0x0c},
+ {0x05, 0x00, 0x98}, {0x20, 0x07, 0x03}, {0x09, 0x01, 0xf2},
+ {0x2b, 0x00, 0xa0}, {0x2c, 0x00, 0xa0}, {0x2d, 0x00, 0xa0},
+ {0x2e, 0x00, 0xa0}, {0x01, 0x00, 0x0c}, {0x02, 0x00, 0x20},
+ {0x03, 0x01, 0xe0}, {0x04, 0x02, 0x80}, {0x06, 0x00, 0x0c},
+ {0x05, 0x00, 0x98}, {0x09, 0x01, 0xc1}, {0x2b, 0x00, 0xae},
+ {0x2c, 0x00, 0xae}, {0x2d, 0x00, 0xae}, {0x2e, 0x00, 0xae},
+};
+
+/**
+ * @brief Initialize mt9v112 sensors
+ *
+ * @param dev Pointer to device structure
+ *
+ * @return 0 or negative error code
+ *
+ */
+int mt9v112_initialize(struct usb_microdia *dev)
+{
+ int i;
+ int ret = 0;
+ __u8 value[2], reg;
+ for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
+ reg = mt9v011_init[i][0];
+ value[0] = mt9v112_init[i][1];
+ value[1] = mt9v112_init[i][2];
+ ret = sn9c20x_write_i2c_data(dev, 2, reg, value);
+ if (ret < 0) {
+ UDIA_WARNING("Sensor Init Error (%d). "
+ "line %d\n", ret, i);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int mt9v112_probe(struct usb_microdia *dev)
+{
+ int ret;
+ __u8 buf[2];
+ ret = sn9c20x_read_i2c_data(dev, 2, 0x00, buf);
+ if (ret == 0) {
+ if (buf[0] != 0x12)
+ return -EINVAL;
+ if (buf[1] == 0x29) {
+ mt9v112_initialize(dev);
+ dev->camera.modes = micron_resolutions;
+ dev->camera.nmodes = ARRAY_SIZE(micron_resolutions);
+ dev->camera.fmts = mt9m111_fmts;
+ dev->camera.nfmts = ARRAY_SIZE(mt9m111_fmts);
+ return MT9V112_SENSOR;
+ }
+ }
+
+ return -EINVAL;
+}
+
/**
* @brief Initialize mt9v011 sensors
*
diff --git a/micron.h b/micron.h
index 4e2ee99..1955e5e 100644
--- a/micron.h
+++ b/micron.h
@@ -121,4 +121,6 @@ int mt9m111_set_yuv422(struct usb_microdia *dev);
int mt9m001_probe(struct usb_microdia *dev);
+int mt9v112_probe(struct usb_microdia *dev);
+
#endif
--
1.5.6.5
From 0a2f7fd94cd882d78980e388434214df8620cd0e Mon Sep 17 00:00:00 2001
From: GWater <[EMAIL PROTECTED]>
Date: Sat, 22 Nov 2008 13:39:43 +0100
Subject: [PATCH] New system regarding sensor assignment
Sensors are now assigned using the dev_microdia_assign_sensor()
function.
Initilization is seperated from that and probing has been removed.
FIXME:
- No support for 6270 and 62b0. These need probing.
- Resolutions and Formats are not geing assigned.
Therefore this patch temporarily breaks video capture.
Signed-off-by: GWater <[EMAIL PROTECTED]>
---
microdia-dev.c | 135 +++++++++++++++++++++++++++++++++++--------------------
microdia.h | 29 +++++++-----
micron.c | 54 ----------------------
micron.h | 5 +-
omnivision.c | 122 ++++++++++++++++++++------------------------------
omnivision.h | 3 +-
sn9c20x.c | 57 ++++++++++--------------
7 files changed, 178 insertions(+), 227 deletions(-)
diff --git a/microdia-dev.c b/microdia-dev.c
index a233ab9..f915272 100644
--- a/microdia-dev.c
+++ b/microdia-dev.c
@@ -38,64 +38,127 @@ struct sensor_info sensors[] = {
.id = OV9650_SENSOR,
.name = "OV9650",
.address = 0x30,
- .probe = ov_probe
+ .initialize = ov_initialize,
+ .set_hvflip = ov965x_set_hvflip,
+ .set_exposure = ov965x_set_exposure,
+ .set_auto_exposure = ov965x_set_autoexposure,
+ .flip_detect = ov965x_flip_detect,
},
{
.id = OV9655_SENSOR,
.name = "OV9655",
.address = 0x30,
- .probe = ov_probe
+ .initialize = ov_initialize,
},
{
.id = SOI968_SENSOR,
.name = "SOI968",
.address = 0x30,
- .probe = ov_probe
+ .initialize = ov_initialize,
+ .set_exposure = soi968_set_exposure,
+ .set_auto_exposure = ov965x_set_autoexposure,
},
{
.id = OV7660_SENSOR,
.name = "OV7660",
.address = 0x21,
- .probe = ov_probe
+ .initialize = ov_initialize,
+ .set_exposure = ov7660_set_exposure,
+ .set_auto_exposure = ov7660_set_autoexposure,
},
{
.id = OV7670_SENSOR,
.name = "OV7670",
.address = 0x21,
- .probe = ov_probe
- },
- {
- .id = MT9M111_SENSOR,
- .name = "MT9M111",
- .address = 0x5d,
- .probe = mt9m111_probe
+ .initialize = ov_initialize,
+ .flip_detect = ov7670_flip_detect,
},
{
.id = MT9V111_SENSOR,
.name = "MT9V111",
.address = 0x5c,
- .probe = mt9v111_probe
+ .initialize = mt9v111_initialize,
+ .set_hvflip = mt9v111_set_hvflip,
+ .set_exposure = mt9v111_set_exposure,
+ .set_auto_exposure = mt9v111_set_autoexposure,
+ },
+ {
+ .id = MT9M111_SENSOR,
+ .name = "MT9M111",
+ .address = 0x5d,
+ .initialize = mt9m111_initialize,
},
{
.id = MT9V011_SENSOR,
.name = "MT9V011",
.address = 0x5d,
- .probe = mt9v011_probe
+ .initialize = mt9v011_initialize,
+ .set_hvflip = mt9v011_set_hvflip,
+ .set_exposure = mt9v011_set_exposure,
},
{
.id = MT9M001_SENSOR,
.name = "MT9M001",
.address = 0x5d,
- .probe = mt9m001_probe
+ .initialize = mt9m001_initialize,
},
{
.id = MT9V112_SENSOR,
.name = "MT9V112",
.address = 0x5d,
- .probe = mt9v112_probe
+ .initialize = mt9v112_initialize,
},
};
+static __u16 known_cams[][2] = {
+ {0x6240, MT9M001_SENSOR},
+ {0x6242, MT9M111_SENSOR},
+ {0x6248, OV9655_SENSOR},
+ {0x624e, SOI968_SENSOR},
+ {0x624f, OV9650_SENSOR},
+ {0x6253, OV9650_SENSOR},
+ {0x6260, OV7670_SENSOR},
+ {0x627b, OV7660_SENSOR},
+ {0x627f, OV9650_SENSOR},
+ {0x6288, OV9655_SENSOR},
+ {0x628e, SOI968_SENSOR},
+ {0x62a0, OV7670_SENSOR},
+ {0x62b3, OV9655_SENSOR},
+ {0x62bb, OV7660_SENSOR},
+};
+
+int dev_microdia_assign_sensor(struct usb_microdia *dev)
+{
+ int i, j;
+ __u16 pid = le16_to_cpu(dev->udev->descriptor.idProduct);
+
+ /* FIXME: For 6270 and 62b0 perform probe */
+
+ for (i = 0; i < ARRAY_SIZE(known_cams); i++) {
+ if (pid == known_cams[i][0]) {
+ for (j = 0; j < ARRAY_SIZE(sensors); j++) {
+ if (known_cams[i][1] == sensors[j].id) {
+ dev->camera.sensor = &sensors[j];
+ return 0;
+ }
+ }
+ }
+ }
+
+ UDIA_ERROR("Could not assign sensor: "
+ "Please report to [email protected] .\n");
+
+ return -EINVAL;
+}
+
+int dev_microdia_initialize_sensor(struct usb_microdia *dev)
+{
+ int ret = -ENODEV;
+ if (dev && dev->camera.sensor->initialize)
+ ret = dev->camera.sensor->initialize(dev);
+ return ret;
+}
+
/**
* @brief Wrapper function for camera-setting functions
*
@@ -175,8 +238,8 @@ int dev_microdia_camera_set_gamma(struct usb_microdia *dev)
*/
int dev_microdia_camera_set_exposure(struct usb_microdia *dev)
{
- if (dev && dev->camera.set_exposure != NULL)
- return dev->camera.set_exposure(dev);
+ if (dev && dev->camera.sensor->set_exposure != NULL)
+ return dev->camera.sensor->set_exposure(dev);
return 0;
}
@@ -192,8 +255,8 @@ int dev_microdia_camera_set_exposure(struct usb_microdia
*dev)
int dev_microdia_camera_set_hvflip(struct usb_microdia *dev)
{
int ret = -ENODEV;
- if (dev && dev->camera.set_hvflip)
- ret = dev->camera.set_hvflip(dev);
+ if (dev && dev->camera.sensor->set_hvflip)
+ ret = dev->camera.sensor->set_hvflip(dev);
return ret;
}
@@ -243,8 +306,8 @@ int dev_microdia_camera_set_rgb_gain(struct usb_microdia
*dev)
int dev_microdia_camera_set_auto_exposure(struct usb_microdia *dev)
{
int ret = -ENODEV;
- if (dev && dev->camera.set_auto_exposure)
- ret = dev->camera.set_auto_exposure(dev);
+ if (dev && dev->camera.sensor->set_auto_exposure)
+ ret = dev->camera.sensor->set_auto_exposure(dev);
return ret;
}
@@ -260,39 +323,13 @@ int dev_microdia_camera_set_auto_exposure(struct
usb_microdia *dev)
int dev_microdia_camera_set_auto_whitebalance(struct usb_microdia *dev)
{
int ret = -ENODEV;
- if (dev && dev->camera.set_auto_whitebalance)
- ret = dev->camera.set_auto_whitebalance(dev);
+ if (dev && dev->camera.sensor->set_auto_whitebalance)
+ ret = dev->camera.sensor->set_auto_whitebalance(dev);
return ret;
}
/**
- * @brief function to probe sensor attached to bridge
- *
- * @param dev pointer to device structure
- *
- * @returns 0 or negative error value
- *
- * This function will probe the bridge for the proper sensor
- */
-int dev_microdia_probe_sensor(struct usb_microdia *dev)
-{
- int i, ret;
- dev->camera.sensor_flags = SN9C20X_I2C_2WIRE;
-
- for (i = 0; i < ARRAY_SIZE(sensors); i++) {
- dev->camera.sensor_slave_address = sensors[i].address;
- ret = sensors[i].probe(dev);
- if (ret == sensors[i].id) {
- UDIA_INFO("Detected sensor: %s\n", sensors[i].name);
- return ret;
- }
- }
-
- return UNKNOWN_SENSOR;
-}
-
-/**
* @brief Wrapper function for device-specific initialization functions
*
* @param dev Pointer to device structure
diff --git a/microdia.h b/microdia.h
index 6f18e09..bf05203 100644
--- a/microdia.h
+++ b/microdia.h
@@ -336,17 +336,20 @@ struct sensor_info {
__u8 id;
__u8 *name;
__u8 address;
- int (*probe) (struct usb_microdia *dev);
+
+/* sensor specific functions */
+ int (*initialize) (struct usb_microdia *dev);
+ int (*set_exposure) (struct usb_microdia *dev);
+ int (*set_auto_exposure) (struct usb_microdia *dev);
+ int (*set_auto_whitebalance) (struct usb_microdia *dev);
+ int (*flip_detect) (struct usb_microdia *dev);
+ int (*set_hvflip) (struct usb_microdia *dev);
};
extern struct sensor_info sensors[];
struct microdia_camera {
- __u8 sensor_slave_address;
- __u8 sensor_flags;
- __u8 sensor;
-
/* supported resolutions */
__u8 nmodes;
struct microdia_video_resolution *modes;
@@ -354,22 +357,21 @@ struct microdia_camera {
__u8 nfmts;
struct microdia_video_format *fmts;
+/* image sensor */
+ struct sensor_info *sensor;
+
+/* SCCB/I2C interface */
+ __u8 i2c_flags;
+
/* bridge functions */
- int (*initialize) (struct usb_microdia *dev);
int (*enable_video) (struct usb_microdia *dev, int enable);
/* image quality functions */
-
int (*set_contrast) (struct usb_microdia *dev);
int (*set_brightness) (struct usb_microdia *dev);
int (*set_gamma) (struct usb_microdia *dev);
- int (*set_exposure) (struct usb_microdia *dev);
- int (*flip_detect) (struct usb_microdia *dev);
- int (*set_hvflip) (struct usb_microdia *dev);
int (*set_sharpness) (struct usb_microdia *dev);
int (*set_rgb_gain) (struct usb_microdia *dev);
- int (*set_auto_exposure) (struct usb_microdia *dev);
- int (*set_auto_whitebalance) (struct usb_microdia *dev);
};
/**
@@ -425,7 +427,8 @@ void usb_microdia_delete(struct kref *);
int dev_microdia_initialize_device(struct usb_microdia *, __u32 flags);
-int dev_microdia_probe_sensor(struct usb_microdia *);
+int dev_microdia_assign_sensor(struct usb_microdia *dev);
+int dev_microdia_initialize_sensor(struct usb_microdia *dev);
int dev_microdia_enable_video(struct usb_microdia *, int);
int dev_microdia_camera_settings(struct usb_microdia *);
int dev_microdia_camera_set_contrast(struct usb_microdia *);
diff --git a/micron.c b/micron.c
index 57c113f..512bd80 100644
--- a/micron.c
+++ b/micron.c
@@ -481,7 +481,6 @@ int mt9v112_probe(struct usb_microdia *dev)
if (buf[0] != 0x12)
return -EINVAL;
if (buf[1] == 0x29) {
- mt9v112_initialize(dev);
dev->camera.modes = micron_resolutions;
dev->camera.nmodes = ARRAY_SIZE(micron_resolutions);
dev->camera.fmts = mt9m111_fmts;
@@ -565,9 +564,6 @@ int mt9v011_probe(struct usb_microdia *dev)
if (buf[0] != 0x82)
return -EINVAL;
if (buf[1] == 0x43) {
- mt9v011_initialize(dev);
- dev->camera.set_hvflip = mt9v011_set_hvflip;
- dev->camera.set_exposure = mt9v011_set_exposure;
dev->camera.modes = micron_resolutions;
dev->camera.nmodes = ARRAY_SIZE(micron_resolutions);
dev->camera.fmts = mt9x0xx_fmts;
@@ -654,10 +650,6 @@ int mt9v111_probe(struct usb_microdia *dev)
if (buf[0] != 0x82)
return -EINVAL;
if (buf[1] == 0x3a) {
- mt9v111_initialize(dev);
- dev->camera.set_hvflip = mt9v111_set_hvflip;
- dev->camera.set_exposure = mt9v111_set_exposure;
- dev->camera.set_auto_exposure =
mt9v111_set_autoexposure;
dev->camera.modes = micron_resolutions;
dev->camera.nmodes = ARRAY_SIZE(micron_resolutions);
dev->camera.fmts = mt9v111_fmts;
@@ -734,27 +726,6 @@ int mt9m001_initialize(struct usb_microdia *dev)
return ret;
}
-int mt9m001_probe(struct usb_microdia *dev)
-{
- int ret;
- __u8 buf[2];
- ret = sn9c20x_read_i2c_data(dev, 2, 0x00, buf);
- if (ret == 0) {
- if (buf[0] != 0x84)
- return -EINVAL;
- if (buf[1] == 0x31) {
- mt9m001_initialize(dev);
- dev->camera.modes = micron_resolutions;
- dev->camera.nmodes = ARRAY_SIZE(micron_resolutions);
- dev->camera.fmts = mt9x0xx_fmts;
- dev->camera.nfmts = ARRAY_SIZE(mt9x0xx_fmts);
- return MT9M001_SENSOR;
- }
- }
-
- return -EINVAL;
-}
-
/**
* @brief Initialize mt9m111 sensors
*
@@ -788,31 +759,6 @@ int mt9m111_initialize(struct usb_microdia *dev)
return ret;
}
-int mt9m111_probe(struct usb_microdia *dev)
-{
- int ret;
- __u8 buf[2] = {0x00, 0x00};
-
- /* Select address-space: Sensor */
- sn9c20x_write_i2c_data(dev, 2, 0xf0, buf);
-
- ret = sn9c20x_read_i2c_data(dev, 2, 0x00, buf);
- if (ret == 0) {
- if (buf[0] != 0x14)
- return -EINVAL;
- if (buf[1] == 0x3a) {
- mt9m111_initialize(dev);
- dev->camera.modes = mt9m111_resolutions;
- dev->camera.nmodes = ARRAY_SIZE(mt9m111_resolutions);
- dev->camera.fmts = mt9m111_fmts;
- dev->camera.nfmts = ARRAY_SIZE(mt9m111_fmts);
- return MT9M111_SENSOR;
- }
- }
-
- return -EINVAL;
-}
-
int mt9m111_set_raw(struct usb_microdia *dev)
{
__u16 buf;
diff --git a/micron.h b/micron.h
index 1955e5e..8d693f5 100644
--- a/micron.h
+++ b/micron.h
@@ -115,12 +115,13 @@ int mt9v011_set_hvflip(struct usb_microdia *dev);
int mt9v011_initialize(struct usb_microdia *dev);
int mt9v011_probe(struct usb_microdia *dev);
-int mt9m111_probe(struct usb_microdia *dev);
int mt9m111_set_raw(struct usb_microdia *dev);
int mt9m111_set_yuv422(struct usb_microdia *dev);
+int mt9m111_initialize(struct usb_microdia *dev);
-int mt9m001_probe(struct usb_microdia *dev);
+int mt9m001_initialize(struct usb_microdia *dev);
int mt9v112_probe(struct usb_microdia *dev);
+int mt9v112_initialize(struct usb_microdia *dev);
#endif
diff --git a/omnivision.c b/omnivision.c
index 36eb280..defcd5a 100644
--- a/omnivision.c
+++ b/omnivision.c
@@ -598,96 +598,70 @@ struct microdia_video_resolution ov7660_resolutions[] = {
},
};
-int ov_probe(struct usb_microdia *dev)
-{
- int ret;
- __u8 buf[2];
- ret = sn9c20x_read_i2c_data(dev, 2, 0x0a, buf);
- if (ret == 0) {
- if (buf[0] != 0x76 && buf[0] != 0x96)
- return -EINVAL;
- if (buf[1] == 0x60) {
- ov_initialize(dev, ov7660_init,
ARRAY_SIZE(ov7660_init));
- dev->camera.set_exposure = ov7660_set_exposure;
- dev->camera.set_auto_exposure = ov7660_set_autoexposure;
- dev->camera.modes = ov7660_resolutions;
- dev->camera.nmodes = ARRAY_SIZE(ov7660_resolutions);
- dev->camera.fmts = ov_fmts;
- dev->camera.nfmts = ARRAY_SIZE(ov_fmts);
- return OV7660_SENSOR;
- }
- if (buf[1] == 0x70) {
- ov_initialize(dev, ov7670_init,
ARRAY_SIZE(ov7670_init));
- dev->camera.flip_detect = ov7670_flip_detect;
- dev->camera.modes = ov7670_resolutions;
- dev->camera.nmodes = ARRAY_SIZE(ov7670_resolutions);
- dev->camera.fmts = ov_fmts;
- dev->camera.nfmts = ARRAY_SIZE(ov_fmts);
- return OV7670_SENSOR;
- }
- if (buf[1] == 0x52) {
- ov_initialize(dev, ov9650_init,
ARRAY_SIZE(ov9650_init));
- dev->camera.set_hvflip = ov965x_set_hvflip;
- dev->camera.set_exposure = ov965x_set_exposure;
- dev->camera.set_auto_exposure = ov965x_set_autoexposure;
- dev->camera.flip_detect = ov965x_flip_detect;
- dev->camera.modes = ov965x_resolutions;
- dev->camera.nmodes = ARRAY_SIZE(ov965x_resolutions);
- dev->camera.fmts = ov_fmts;
- dev->camera.nfmts = ARRAY_SIZE(ov_fmts);
- return OV9650_SENSOR;
- }
- if (buf[1] == 0x56 || buf[1] == 0x57) {
- ov_initialize(dev, ov9655_init,
ARRAY_SIZE(ov9655_init));
- dev->camera.modes = ov7670_resolutions;
- dev->camera.nmodes = ARRAY_SIZE(ov7670_resolutions);
- dev->camera.fmts = ov_fmts;
- dev->camera.nfmts = ARRAY_SIZE(ov_fmts);
- return OV9655_SENSOR;
- }
- if (buf[1] == 0x28) {
- ov_initialize(dev, soi968_init,
ARRAY_SIZE(soi968_init));
- dev->camera.set_exposure = soi968_set_exposure;
- dev->camera.set_auto_exposure = ov965x_set_autoexposure;
- dev->camera.modes = soi968_resolutions;
- dev->camera.nmodes = ARRAY_SIZE(soi968_resolutions);
- dev->camera.fmts = ov_fmts;
- dev->camera.nfmts = ARRAY_SIZE(ov_fmts);
- return SOI968_SENSOR;
- }
- }
-
- return -EINVAL;
-}
-
/**
* @brief Initialize ov sensors
*
* @param dev Pointer to device structure
- * @param ov_init Data array for initialization
- * @param array_size size of ov_init
*
* @return 0 or negative error code
*
*/
-int ov_initialize(struct usb_microdia *dev, __u8 ov_init[][2], int array_size)
+int ov_initialize(struct usb_microdia *dev)
{
int i;
int ret = 0;
- __u8 value, reg;
-
- for (i = 0; i < array_size; i++) {
- reg = ov_init[i][0];
- value = ov_init[i][1];
- ret = sn9c20x_write_i2c_data(dev, 1, reg, &value);
- if (ret < 0) {
- UDIA_INFO("Sensor Init Error (%d). line %d\n", ret, i);
- break;
- }
+
+ switch (dev->camera.sensor->id) {
+ case SOI968_SENSOR:
+ for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
+ ret = sn9c20x_write_i2c_data(dev, 1,
+ soi968_init[i][0], &soi968_init[i][1]);
+ if (ret < 0)
+ goto err;
+ }
+ break;
+ case OV9650_SENSOR:
+ for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
+ ret = sn9c20x_write_i2c_data(dev, 1,
+ ov9650_init[i][0], &ov9650_init[i][1]);
+ if (ret < 0)
+ goto err;
+ }
+ break;
+ case OV9655_SENSOR:
+ for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
+ ret = sn9c20x_write_i2c_data(dev, 1,
+ ov9655_init[i][0], &ov9655_init[i][1]);
+ if (ret < 0)
+ goto err;
+ }
+ break;
+ case OV7670_SENSOR:
+ for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
+ ret = sn9c20x_write_i2c_data(dev, 1,
+ ov7670_init[i][0], &ov7670_init[i][1]);
+ if (ret < 0)
+ goto err;
+ }
+ break;
+ case OV7660_SENSOR:
+ for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
+ ret = sn9c20x_write_i2c_data(dev, 1,
+ ov7660_init[i][0], &ov7660_init[i][1]);
+ if (ret < 0)
+ goto err;
+ }
+ break;
+
+ default:
+ return -EINVAL;
}
return ret;
+err:
+ UDIA_ERROR("Sensor Init failed (%d)! - line %d\n", ret, i);
+ return ret;
}
/**
diff --git a/omnivision.h b/omnivision.h
index e08092a..1403a18 100644
--- a/omnivision.h
+++ b/omnivision.h
@@ -547,7 +547,6 @@ int ov965x_set_exposure(struct usb_microdia *);
int ov965x_set_autoexposure(struct usb_microdia *dev);
int ov965x_flip_detect(struct usb_microdia *dev);
-int ov_probe(struct usb_microdia *dev);
-int ov_initialize(struct usb_microdia *dev, __u8 ov_init[][2], int array_size);
+int ov_initialize(struct usb_microdia *dev);
#endif
diff --git a/sn9c20x.c b/sn9c20x.c
index a26ae01..bde5b9b 100644
--- a/sn9c20x.c
+++ b/sn9c20x.c
@@ -44,7 +44,7 @@
*/
int sn9c20x_initialize(struct usb_microdia *dev)
{
- int ret, i, sensor;
+ int ret, i;
__u16 reg;
__u8 value;
@@ -99,15 +99,6 @@ int sn9c20x_initialize(struct usb_microdia *dev)
{0x11bf, 0x00},
};
- __u8 lens_gain[48] = {
- 0x10, 0x21, 0x34, 0x40, 0x47, 0x4f, 0x57, 0x5f,
- 0x64, 0x68, 0x6d, 0x73, 0x79, 0x80, 0x89, 0x97,
- 0x0d, 0x1c, 0x2a, 0x33, 0x38, 0x3d, 0x44, 0x4a,
- 0x4e, 0x52, 0x56, 0x5b, 0x61, 0x68, 0x6f, 0x7a,
- 0x0d, 0x1a, 0x2a, 0x31, 0x36, 0x3b, 0x41, 0x47,
- 0x4a, 0x4e, 0x53, 0x58, 0x5d, 0x64, 0x6b, 0x76
- };
-
__u8 qtable1[64] = {
0x0d, 0x08, 0x08, 0x0d, 0x08, 0x08, 0x0d, 0x0d,
0x0d, 0x0d, 0x11, 0x0d, 0x0d, 0x11, 0x15, 0x21,
@@ -160,21 +151,19 @@ int sn9c20x_initialize(struct usb_microdia *dev)
dev->camera.set_sharpness = sn9c20x_set_sharpness;
dev->camera.set_rgb_gain = sn9c20x_set_rgb_gain;
- sensor = dev_microdia_probe_sensor(dev);
- if (sensor == UNKNOWN_SENSOR) {
- UDIA_ERROR("Failed to detect sensor.\n");
- ret = -ENODEV;
+ ret = dev_microdia_assign_sensor(dev);
+ if (ret < 0)
goto err;
- }
- dev->camera.sensor = sensor;
-
- if (!(sensor == OV9650_SENSOR || sensor == OV9655_SENSOR))
- memset(lens_gain, 0x00, 48);
- ret = usb_microdia_control_write(dev, 0x11c0, lens_gain, 48);
+ ret = dev_microdia_initialize_sensor(dev);
if (ret < 0)
goto err;
+ /** FIXME: Assign sensor-specific reslutions and formats
+ * Brian developed a new system for that with his YUV422
+ * patch for OV sensors.
+ */
+
return 0;
err:
@@ -231,7 +220,7 @@ int sn9c20x_set_LEDs(struct usb_microdia *dev, int enable)
int ret;
__u8 led[2];
- int sensor = dev->camera.sensor;
+ int sensor = dev->camera.sensor->id;
if (enable) {
switch (sensor) {
@@ -303,8 +292,10 @@ int sn9c20x_i2c_initialize(struct usb_microdia *dev)
__u8 buf[9];
int ret;
- buf[0] = dev->camera.sensor_flags;
- buf[1] = dev->camera.sensor_slave_address;
+ dev->camera.i2c_flags = SN9C20X_I2C_2WIRE;
+
+ buf[0] = dev->camera.i2c_flags;
+ buf[1] = dev->camera.sensor->address;
buf[2] = 0x00;
buf[3] = 0x00;
buf[4] = 0x00;
@@ -383,9 +374,9 @@ int sn9c20x_read_i2c_data(struct usb_microdia *dev, __u8
nbytes,
memset(row, 0, 5);
/* now we issue the same command but with the read bit set
* and no slave register address */
- dev->camera.sensor_flags |= SN9C20X_I2C_READ;
+ dev->camera.i2c_flags |= SN9C20X_I2C_READ;
ret = sn9c20x_write_i2c_data(dev, nbytes - 1, 0, row);
- dev->camera.sensor_flags &= ~SN9C20X_I2C_READ;
+ dev->camera.i2c_flags &= ~SN9C20X_I2C_READ;
if (ret < 0)
return ret;
@@ -455,8 +446,8 @@ int sn9c20x_write_i2c_data(struct usb_microdia *dev, __u8
nbytes,
/* from the point of view of the bridge, the length
* includes the address */
- row[0] = dev->camera.sensor_flags | ((nbytes + 1) << 4);
- row[1] = dev->camera.sensor_slave_address;
+ row[0] = dev->camera.i2c_flags | ((nbytes + 1) << 4);
+ row[1] = dev->camera.sensor->address;
row[2] = address;
row[7] = 0x10; /* I think this means we want an ack */
@@ -464,19 +455,19 @@ int sn9c20x_write_i2c_data(struct usb_microdia *dev, __u8
nbytes,
row[i + 3] = i < nbytes ? data[i] : 0;
UDIA_DEBUG("I2C %s %02x: %02x %02x %02x %02x %02x %02x %02x %02x\n",
- (dev->camera.sensor_flags & SN9C20X_I2C_READ ? wasread :
waswrite), address,
+ (dev->camera.i2c_flags & SN9C20X_I2C_READ ? wasread :
waswrite), address,
row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
ret = usb_microdia_control_write(dev, 0x10c0, row, 8);
if (ret >= 0)
ret = sn9c20x_i2c_ack_wait(dev,
- dev->camera.sensor_flags & SN9C20X_I2C_400KHZ,
+ dev->camera.i2c_flags & SN9C20X_I2C_400KHZ,
&slave_error);
if (slave_error) {
UDIA_ERROR("I2C slave 0x%02x returned error during %s address
0x%02x\n",
- dev->camera.sensor_slave_address,
- (dev->camera.sensor_flags & SN9C20X_I2C_READ ? wasread
: waswrite),
+ dev->camera.sensor->address,
+ (dev->camera.i2c_flags & SN9C20X_I2C_READ ? wasread :
waswrite),
address);
return -1000;
/* there should be no interference with USB errors */
@@ -485,8 +476,8 @@ int sn9c20x_write_i2c_data(struct usb_microdia *dev, __u8
nbytes,
if (ret < 0) {
/* we got no ack */
UDIA_ERROR("No ack from I2C slave 0x%02x for %s address
0x%02x\n",
- dev->camera.sensor_slave_address,
- (dev->camera.sensor_flags & SN9C20X_I2C_READ ? wasread
: waswrite),
+ dev->camera.sensor->address,
+ (dev->camera.i2c_flags & SN9C20X_I2C_READ ? wasread :
waswrite),
address);
return ret;
}
--
1.5.6.5
signature.asc
Description: OpenPGP digital signature
