summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/gspca/m5602
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/gspca/m5602')
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_bridge.h12
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_core.c37
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c2
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_ov9650.h6
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h6
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c92
-rw-r--r--linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h58
7 files changed, 172 insertions, 41 deletions
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_bridge.h b/linux/drivers/media/video/gspca/m5602/m5602_bridge.h
index 6b2441e84..60c588dff 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -167,16 +167,4 @@ int m5602_read_bridge(
int m5602_write_bridge(
struct sd *sd, u8 address, u8 i2c_data);
-int m5602_configure(struct gspca_dev *gspca_dev,
- const struct usb_device_id *id);
-
-int m5602_init(struct gspca_dev *gspca_dev);
-
-void m5602_start_transfer(struct gspca_dev *gspca_dev);
-
-void m5602_stop_transfer(struct gspca_dev *gspca_dev);
-
-void m5602_urb_complete(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
- __u8 *data, int len);
-
#endif
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_core.c b/linux/drivers/media/video/gspca/m5602/m5602_core.c
index 30efe7d4b..1d1658294 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_core.c
@@ -35,16 +35,6 @@ static const __devinitdata struct usb_device_id m5602_table[] = {
MODULE_DEVICE_TABLE(usb, m5602_table);
-/* sub-driver description, the ctrl and nctrl is filled at probe time */
-static struct sd_desc sd_desc = {
- .name = MODULE_NAME,
- .config = m5602_configure,
- .init = m5602_init,
- .start = m5602_start_transfer,
- .stopN = m5602_stop_transfer,
- .pkt_scan = m5602_urb_complete
-};
-
/* Reads a byte from the m5602 */
int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
{
@@ -104,7 +94,7 @@ static void m5602_dump_bridge(struct sd *sd)
info("Warning: The camera probably won't work until it's power cycled");
}
-int m5602_probe_sensor(struct sd *sd)
+static int m5602_probe_sensor(struct sd *sd)
{
/* Try the po1030 */
sd->sensor = &po1030;
@@ -137,7 +127,10 @@ int m5602_probe_sensor(struct sd *sd)
return -ENODEV;
}
-int m5602_init(struct gspca_dev *gspca_dev)
+static int m5602_configure(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id);
+
+static int m5602_init(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int err;
@@ -149,7 +142,7 @@ int m5602_init(struct gspca_dev *gspca_dev)
return err;
}
-void m5602_start_transfer(struct gspca_dev *gspca_dev)
+static int m5602_start_transfer(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
__u8 *buf = sd->gspca_dev.usb_buf;
@@ -162,9 +155,11 @@ void m5602_start_transfer(struct gspca_dev *gspca_dev)
4, M5602_URB_MSG_TIMEOUT);
PDEBUG(DBG_V4L2, "Transfer started");
+ return 0;
}
-void m5602_urb_complete(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
+static void m5602_urb_complete(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame,
__u8 *data, int len)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -216,13 +211,23 @@ void m5602_urb_complete(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
}
}
-void m5602_stop_transfer(struct gspca_dev *gspca_dev)
+static void m5602_stop_transfer(struct gspca_dev *gspca_dev)
{
/* Is there are a command to stop a data transfer? */
}
+/* sub-driver description, the ctrl and nctrl is filled at probe time */
+static struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .config = m5602_configure,
+ .init = m5602_init,
+ .start = m5602_start_transfer,
+ .stopN = m5602_stop_transfer,
+ .pkt_scan = m5602_urb_complete
+};
+
/* this function is called at probe time */
-int m5602_configure(struct gspca_dev *gspca_dev,
+static int m5602_configure(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
struct sd *sd = (struct sd *) gspca_dev;
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index ea2250217..566d4925a 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -69,7 +69,7 @@ sensor_found:
int mt9m111_init(struct sd *sd)
{
- int i, err;
+ int i, err = 0;
/* Init the sensor */
for (i = 0; i < ARRAY_SIZE(init_mt9m111); i++) {
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_ov9650.h b/linux/drivers/media/video/gspca/m5602/m5602_ov9650.h
index 70429b411..f5830a0f7 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -466,7 +466,11 @@ static const unsigned char power_down_ov9650[][3] =
/* Vertically and horizontally flips the image if matched, needed for machines
where the sensor is mounted upside down */
-static const struct dmi_system_id ov9650_flip_dmi_table[] = {
+static
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+ const
+#endif
+ struct dmi_system_id ov9650_flip_dmi_table[] = {
{
.ident = "ASUS A6VC",
.matches = {
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index 5d808a750..a39183252 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -339,7 +339,11 @@ static const unsigned char init_s5k4aa[][4] =
{SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
};
-static const struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
+static
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+ const
+#endif
+ struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
{
.ident = "Fujitsu-Siemens Amilo Xa 2528",
.matches = {
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index c1ff967b1..b4b33c2d0 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -321,7 +321,7 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
{
- int err = 0;
+ int err;
u8 data[2];
struct sd *sd = (struct sd *) gspca_dev;
@@ -331,3 +331,93 @@ int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
return (err < 0) ? err : 0;
}
+
+int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ int err;
+ u8 data[1];
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ data[0] = 0x05;
+ err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
+ if (err < 0)
+ return err;
+
+ err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1);
+ *val = (data[0] | 0x40) ? 1 : 0;
+
+ return (err < 0) ? err : 0;
+}
+
+int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+ int err;
+ u8 data[1];
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ data[0] = 0x05;
+ err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
+ if (err < 0)
+ return err;
+
+ err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1);
+ if (err < 0)
+ return err;
+
+ /* set or zero six bit, seven is hflip */
+ data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
+ : (data[0] & 0x80) | S5K83A_FLIP_MASK;
+ err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1);
+ if (err < 0)
+ return err;
+
+ data[0] = (val) ? 0x0b : 0x0a;
+ err = s5k83a_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
+
+ return (err < 0) ? err : 0;
+}
+
+int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ int err;
+ u8 data[1];
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ data[0] = 0x05;
+ err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
+ if (err < 0)
+ return err;
+
+ err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1);
+ *val = (data[0] | 0x80) ? 1 : 0;
+
+ return (err < 0) ? err : 0;
+}
+
+int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+ int err;
+ u8 data[1];
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ data[0] = 0x05;
+ err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
+ if (err < 0)
+ return err;
+
+ err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1);
+ if (err < 0)
+ return err;
+
+ /* set or zero seven bit, six is vflip */
+ data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
+ : (data[0] & 0x40) | S5K83A_FLIP_MASK;
+ err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1);
+ if (err < 0)
+ return err;
+
+ data[0] = (val) ? 0x0a : 0x0b;
+ err = s5k83a_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
+
+ return (err < 0) ? err : 0;
+}
diff --git a/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 67432b5a5..8e9fb61a0 100644
--- a/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/linux/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -21,15 +21,20 @@
#include "m5602_sensor.h"
-#define S5K83A_PAGE_MAP 0xec
-#define S5K83A_GAIN 0x18
+#define S5K83A_FLIP 0x01
+#define S5K83A_HFLIP_TUNE 0x03
+#define S5K83A_VFLIP_TUNE 0x05
#define S5K83A_WHITENESS 0x0a
-#define S5K83A_BRIGHTNESS 0x1b
+#define S5K83A_GAIN 0x18
+#define S5K83A_BRIGHTNESS 0x1b
+#define S5K83A_PAGE_MAP 0xec
#define S5K83A_DEFAULT_BRIGHTNESS 0x71
#define S5K83A_DEFAULT_WHITENESS 0x7e
-#define S5K83A_DEFAULT_GAIN 0x00
-#define S5K83A_MAXIMUM_GAIN 0x3c
+#define S5K83A_DEFAULT_GAIN 0x00
+#define S5K83A_MAXIMUM_GAIN 0x3c
+#define S5K83A_FLIP_MASK 0x10
+
/*****************************************************************************/
@@ -56,6 +61,11 @@ int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val);
int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
+int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
+int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+
static struct m5602_sensor s5k83a = {
.name = "S5K83A",
@@ -65,7 +75,7 @@ static struct m5602_sensor s5k83a = {
.read_sensor = s5k83a_read_sensor,
.write_sensor = s5k83a_write_sensor,
.i2c_slave_id = 0x5a,
- .nctrls = 3,
+ .nctrls = 5,
.ctrls = {
{
{
@@ -107,7 +117,31 @@ static struct m5602_sensor s5k83a = {
},
.set = s5k83a_set_gain,
.get = s5k83a_get_gain
- }
+ }, {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = s5k83a_set_hflip,
+ .get = s5k83a_get_hflip
+ }, {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = s5k83a_set_vflip,
+ .get = s5k83a_get_vflip
+ }
},
.nmodes = 1,
.modes = {
@@ -121,7 +155,6 @@ static struct m5602_sensor s5k83a = {
.bytesperline = M5602_DEFAULT_FRAME_WIDTH,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1
-
}
}
};
@@ -438,7 +471,14 @@ static const unsigned char init_s5k83a[][4] =
{SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00},
/* set default gain */
- {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN}
+ {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN},
+
+ /* set default flip */
+ {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
+ {SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00},
+ {SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00},
+ {SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00}
+
};
#endif