aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/m5602
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/m5602')
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h119
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c100
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c135
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h14
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c316
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h195
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c166
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h10
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c235
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h47
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c213
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h25
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h14
13 files changed, 716 insertions, 873 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index 1a37ae4bc82d..a3f3b7a0c7e7 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -25,59 +25,59 @@
25 25
26/*****************************************************************************/ 26/*****************************************************************************/
27 27
28#define M5602_XB_SENSOR_TYPE 0x00 28#define M5602_XB_SENSOR_TYPE 0x00
29#define M5602_XB_SENSOR_CTRL 0x01 29#define M5602_XB_SENSOR_CTRL 0x01
30#define M5602_XB_LINE_OF_FRAME_H 0x02 30#define M5602_XB_LINE_OF_FRAME_H 0x02
31#define M5602_XB_LINE_OF_FRAME_L 0x03 31#define M5602_XB_LINE_OF_FRAME_L 0x03
32#define M5602_XB_PIX_OF_LINE_H 0x04 32#define M5602_XB_PIX_OF_LINE_H 0x04
33#define M5602_XB_PIX_OF_LINE_L 0x05 33#define M5602_XB_PIX_OF_LINE_L 0x05
34#define M5602_XB_VSYNC_PARA 0x06 34#define M5602_XB_VSYNC_PARA 0x06
35#define M5602_XB_HSYNC_PARA 0x07 35#define M5602_XB_HSYNC_PARA 0x07
36#define M5602_XB_TEST_MODE_1 0x08 36#define M5602_XB_TEST_MODE_1 0x08
37#define M5602_XB_TEST_MODE_2 0x09 37#define M5602_XB_TEST_MODE_2 0x09
38#define M5602_XB_SIG_INI 0x0a 38#define M5602_XB_SIG_INI 0x0a
39#define M5602_XB_DS_PARA 0x0e 39#define M5602_XB_DS_PARA 0x0e
40#define M5602_XB_TRIG_PARA 0x0f 40#define M5602_XB_TRIG_PARA 0x0f
41#define M5602_XB_CLK_PD 0x10 41#define M5602_XB_CLK_PD 0x10
42#define M5602_XB_MCU_CLK_CTRL 0x12 42#define M5602_XB_MCU_CLK_CTRL 0x12
43#define M5602_XB_MCU_CLK_DIV 0x13 43#define M5602_XB_MCU_CLK_DIV 0x13
44#define M5602_XB_SEN_CLK_CTRL 0x14 44#define M5602_XB_SEN_CLK_CTRL 0x14
45#define M5602_XB_SEN_CLK_DIV 0x15 45#define M5602_XB_SEN_CLK_DIV 0x15
46#define M5602_XB_AUD_CLK_CTRL 0x16 46#define M5602_XB_AUD_CLK_CTRL 0x16
47#define M5602_XB_AUD_CLK_DIV 0x17 47#define M5602_XB_AUD_CLK_DIV 0x17
48#define M5602_XB_DEVCTR1 0x41 48#define M5602_XB_DEVCTR1 0x41
49#define M5602_XB_EPSETR0 0x42 49#define M5602_XB_EPSETR0 0x42
50#define M5602_XB_EPAFCTR 0x47 50#define M5602_XB_EPAFCTR 0x47
51#define M5602_XB_EPBFCTR 0x49 51#define M5602_XB_EPBFCTR 0x49
52#define M5602_XB_EPEFCTR 0x4f 52#define M5602_XB_EPEFCTR 0x4f
53#define M5602_XB_TEST_REG 0x53 53#define M5602_XB_TEST_REG 0x53
54#define M5602_XB_ALT2SIZE 0x54 54#define M5602_XB_ALT2SIZE 0x54
55#define M5602_XB_ALT3SIZE 0x55 55#define M5602_XB_ALT3SIZE 0x55
56#define M5602_XB_OBSFRAME 0x56 56#define M5602_XB_OBSFRAME 0x56
57#define M5602_XB_PWR_CTL 0x59 57#define M5602_XB_PWR_CTL 0x59
58#define M5602_XB_ADC_CTRL 0x60 58#define M5602_XB_ADC_CTRL 0x60
59#define M5602_XB_ADC_DATA 0x61 59#define M5602_XB_ADC_DATA 0x61
60#define M5602_XB_MISC_CTRL 0x62 60#define M5602_XB_MISC_CTRL 0x62
61#define M5602_XB_SNAPSHOT 0x63 61#define M5602_XB_SNAPSHOT 0x63
62#define M5602_XB_SCRATCH_1 0x64 62#define M5602_XB_SCRATCH_1 0x64
63#define M5602_XB_SCRATCH_2 0x65 63#define M5602_XB_SCRATCH_2 0x65
64#define M5602_XB_SCRATCH_3 0x66 64#define M5602_XB_SCRATCH_3 0x66
65#define M5602_XB_SCRATCH_4 0x67 65#define M5602_XB_SCRATCH_4 0x67
66#define M5602_XB_I2C_CTRL 0x68 66#define M5602_XB_I2C_CTRL 0x68
67#define M5602_XB_I2C_CLK_DIV 0x69 67#define M5602_XB_I2C_CLK_DIV 0x69
68#define M5602_XB_I2C_DEV_ADDR 0x6a 68#define M5602_XB_I2C_DEV_ADDR 0x6a
69#define M5602_XB_I2C_REG_ADDR 0x6b 69#define M5602_XB_I2C_REG_ADDR 0x6b
70#define M5602_XB_I2C_DATA 0x6c 70#define M5602_XB_I2C_DATA 0x6c
71#define M5602_XB_I2C_STATUS 0x6d 71#define M5602_XB_I2C_STATUS 0x6d
72#define M5602_XB_GPIO_DAT_H 0x70 72#define M5602_XB_GPIO_DAT_H 0x70
73#define M5602_XB_GPIO_DAT_L 0x71 73#define M5602_XB_GPIO_DAT_L 0x71
74#define M5602_XB_GPIO_DIR_H 0x72 74#define M5602_XB_GPIO_DIR_H 0x72
75#define M5602_XB_GPIO_DIR_L 0x73 75#define M5602_XB_GPIO_DIR_L 0x73
76#define M5602_XB_GPIO_EN_H 0x74 76#define M5602_XB_GPIO_EN_H 0x74
77#define M5602_XB_GPIO_EN_L 0x75 77#define M5602_XB_GPIO_EN_L 0x75
78#define M5602_XB_GPIO_DAT 0x76 78#define M5602_XB_GPIO_DAT 0x76
79#define M5602_XB_GPIO_DIR 0x77 79#define M5602_XB_GPIO_DIR 0x77
80#define M5602_XB_MISC_CTL 0x70 80#define M5602_XB_MISC_CTL 0x70
81 81
82#define I2C_BUSY 0x80 82#define I2C_BUSY 0x80
83 83
@@ -90,13 +90,7 @@
90#define M5602_ISOC_ENDPOINT_ADDR 0x81 90#define M5602_ISOC_ENDPOINT_ADDR 0x81
91#define M5602_INTR_ENDPOINT_ADDR 0x82 91#define M5602_INTR_ENDPOINT_ADDR 0x82
92 92
93#define M5602_MAX_FRAMES 32
94#define M5602_URBS 2
95#define M5602_ISOC_PACKETS 14
96
97#define M5602_URB_TIMEOUT msecs_to_jiffies(2 * M5602_ISOC_PACKETS)
98#define M5602_URB_MSG_TIMEOUT 5000 93#define M5602_URB_MSG_TIMEOUT 5000
99#define M5602_FRAME_TIMEOUT 2
100 94
101/*****************************************************************************/ 95/*****************************************************************************/
102 96
@@ -115,7 +109,6 @@ static const unsigned char sensor_urb_skeleton[] = {
115 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11 109 0x13, M5602_XB_I2C_CTRL, 0x81, 0x11
116}; 110};
117 111
118/* m5602 device descriptor, currently it just wraps the m5602_camera struct */
119struct sd { 112struct sd {
120 struct gspca_dev gspca_dev; 113 struct gspca_dev gspca_dev;
121 114
@@ -140,4 +133,10 @@ int m5602_read_bridge(
140int m5602_write_bridge( 133int m5602_write_bridge(
141 struct sd *sd, u8 address, u8 i2c_data); 134 struct sd *sd, u8 address, u8 i2c_data);
142 135
136int m5602_write_sensor(struct sd *sd, const u8 address,
137 u8 *i2c_data, const u8 len);
138
139int m5602_read_sensor(struct sd *sd, const u8 address,
140 u8 *i2c_data, const u8 len);
141
143#endif 142#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index fd6ce384b487..ed906fe31287 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -24,7 +24,7 @@
24 24
25/* Kernel module parameters */ 25/* Kernel module parameters */
26int force_sensor; 26int force_sensor;
27int dump_bridge; 27static int dump_bridge;
28int dump_sensor; 28int dump_sensor;
29 29
30static const __devinitdata struct usb_device_id m5602_table[] = { 30static const __devinitdata struct usb_device_id m5602_table[] = {
@@ -80,6 +80,97 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
80 return (err < 0) ? err : 0; 80 return (err < 0) ? err : 0;
81} 81}
82 82
83int m5602_read_sensor(struct sd *sd, const u8 address,
84 u8 *i2c_data, const u8 len)
85{
86 int err, i;
87
88 if (!len || len > sd->sensor->i2c_regW)
89 return -EINVAL;
90
91 do {
92 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
93 } while ((*i2c_data & I2C_BUSY) && !err);
94 if (err < 0)
95 goto out;
96
97 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
98 sd->sensor->i2c_slave_id);
99 if (err < 0)
100 goto out;
101
102 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
103 if (err < 0)
104 goto out;
105
106 if (sd->sensor->i2c_regW == 1) {
107 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len);
108 if (err < 0)
109 goto out;
110
111 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
112 if (err < 0)
113 goto out;
114 } else {
115 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
116 if (err < 0)
117 goto out;
118 }
119
120 for (i = 0; (i < len) && !err; i++) {
121 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
122
123 PDEBUG(D_CONF, "Reading sensor register "
124 "0x%x containing 0x%x ", address, *i2c_data);
125 }
126out:
127 return err;
128}
129
130int m5602_write_sensor(struct sd *sd, const u8 address,
131 u8 *i2c_data, const u8 len)
132{
133 int err, i;
134 u8 *p;
135 struct usb_device *udev = sd->gspca_dev.dev;
136 __u8 *buf = sd->gspca_dev.usb_buf;
137
138 /* No sensor with a data width larger than 16 bits has yet been seen */
139 if (len > sd->sensor->i2c_regW || !len)
140 return -EINVAL;
141
142 memcpy(buf, sensor_urb_skeleton,
143 sizeof(sensor_urb_skeleton));
144
145 buf[11] = sd->sensor->i2c_slave_id;
146 buf[15] = address;
147
148 /* Special case larger sensor writes */
149 p = buf + 16;
150
151 /* Copy a four byte write sequence for each byte to be written to */
152 for (i = 0; i < len; i++) {
153 memcpy(p, sensor_urb_skeleton + 16, 4);
154 p[3] = i2c_data[i];
155 p += 4;
156 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
157 address, i2c_data[i]);
158 }
159
160 /* Copy the tailer */
161 memcpy(p, sensor_urb_skeleton + 20, 4);
162
163 /* Set the total length */
164 p[3] = 0x10 + len;
165
166 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
167 0x04, 0x40, 0x19,
168 0x0000, buf,
169 20 + len * 4, M5602_URB_MSG_TIMEOUT);
170
171 return (err < 0) ? err : 0;
172}
173
83/* Dump all the registers of the m5602 bridge, 174/* Dump all the registers of the m5602 bridge,
84 unfortunately this breaks the camera until it's power cycled */ 175 unfortunately this breaks the camera until it's power cycled */
85static void m5602_dump_bridge(struct sd *sd) 176static void m5602_dump_bridge(struct sd *sd)
@@ -150,11 +241,15 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
150 241
151 /* Send start command to the camera */ 242 /* Send start command to the camera */
152 const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01}; 243 const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01};
244
245 if (sd->sensor->start)
246 sd->sensor->start(sd);
247
153 memcpy(buf, buffer, sizeof(buffer)); 248 memcpy(buf, buffer, sizeof(buffer));
154 err = usb_control_msg(gspca_dev->dev, 249 err = usb_control_msg(gspca_dev->dev,
155 usb_sndctrlpipe(gspca_dev->dev, 0), 250 usb_sndctrlpipe(gspca_dev->dev, 0),
156 0x04, 0x40, 0x19, 0x0000, buf, 251 0x04, 0x40, 0x19, 0x0000, buf,
157 4, M5602_URB_MSG_TIMEOUT); 252 sizeof(buffer), M5602_URB_MSG_TIMEOUT);
158 253
159 PDEBUG(D_STREAM, "Transfer started"); 254 PDEBUG(D_STREAM, "Transfer started");
160 return (err < 0) ? err : 0; 255 return (err < 0) ? err : 0;
@@ -284,6 +379,7 @@ static int __init mod_m5602_init(void)
284 PDEBUG(D_PROBE, "registered"); 379 PDEBUG(D_PROBE, "registered");
285 return 0; 380 return 0;
286} 381}
382
287static void __exit mod_m5602_exit(void) 383static void __exit mod_m5602_exit(void)
288{ 384{
289 usb_deregister(&sd_driver); 385 usb_deregister(&sd_driver);
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index fb700c2d055a..c0e71c331454 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -18,6 +18,8 @@
18 18
19#include "m5602_mt9m111.h" 19#include "m5602_mt9m111.h"
20 20
21static void mt9m111_dump_registers(struct sd *sd);
22
21int mt9m111_probe(struct sd *sd) 23int mt9m111_probe(struct sd *sd)
22{ 24{
23 u8 data[2] = {0x00, 0x00}; 25 u8 data[2] = {0x00, 0x00};
@@ -44,12 +46,12 @@ int mt9m111_probe(struct sd *sd)
44 } else { 46 } else {
45 data[0] = preinit_mt9m111[i][2]; 47 data[0] = preinit_mt9m111[i][2];
46 data[1] = preinit_mt9m111[i][3]; 48 data[1] = preinit_mt9m111[i][3];
47 mt9m111_write_sensor(sd, 49 m5602_write_sensor(sd,
48 preinit_mt9m111[i][1], data, 2); 50 preinit_mt9m111[i][1], data, 2);
49 } 51 }
50 } 52 }
51 53
52 if (mt9m111_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2)) 54 if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2))
53 return -ENODEV; 55 return -ENODEV;
54 56
55 if ((data[0] == 0x14) && (data[1] == 0x3a)) { 57 if ((data[0] == 0x14) && (data[1] == 0x3a)) {
@@ -72,7 +74,7 @@ int mt9m111_init(struct sd *sd)
72 int i, err = 0; 74 int i, err = 0;
73 75
74 /* Init the sensor */ 76 /* Init the sensor */
75 for (i = 0; i < ARRAY_SIZE(init_mt9m111); i++) { 77 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
76 u8 data[2]; 78 u8 data[2];
77 79
78 if (init_mt9m111[i][0] == BRIDGE) { 80 if (init_mt9m111[i][0] == BRIDGE) {
@@ -82,7 +84,7 @@ int mt9m111_init(struct sd *sd)
82 } else { 84 } else {
83 data[0] = init_mt9m111[i][2]; 85 data[0] = init_mt9m111[i][2];
84 data[1] = init_mt9m111[i][3]; 86 data[1] = init_mt9m111[i][3];
85 err = mt9m111_write_sensor(sd, 87 err = m5602_write_sensor(sd,
86 init_mt9m111[i][1], data, 2); 88 init_mt9m111[i][1], data, 2);
87 } 89 }
88 } 90 }
@@ -104,12 +106,12 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
104 u8 data[2] = {0x00, 0x00}; 106 u8 data[2] = {0x00, 0x00};
105 struct sd *sd = (struct sd *) gspca_dev; 107 struct sd *sd = (struct sd *) gspca_dev;
106 108
107 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 109 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
108 data, 2); 110 data, 2);
109 *val = data[0] & MT9M111_RMB_MIRROR_ROWS; 111 *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
110 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 112 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
111 113
112 return (err < 0) ? err : 0; 114 return err;
113} 115}
114 116
115int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 117int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -121,19 +123,19 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
121 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 123 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
122 124
123 /* Set the correct page map */ 125 /* Set the correct page map */
124 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 126 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
125 if (err < 0) 127 if (err < 0)
126 goto out; 128 goto out;
127 129
128 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); 130 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
129 if (err < 0) 131 if (err < 0)
130 goto out; 132 goto out;
131 133
132 data[0] = (data[0] & 0xfe) | val; 134 data[0] = (data[0] & 0xfe) | val;
133 err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 135 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
134 data, 2); 136 data, 2);
135out: 137out:
136 return (err < 0) ? err : 0; 138 return err;
137} 139}
138 140
139int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 141int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -142,12 +144,12 @@ int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
142 u8 data[2] = {0x00, 0x00}; 144 u8 data[2] = {0x00, 0x00};
143 struct sd *sd = (struct sd *) gspca_dev; 145 struct sd *sd = (struct sd *) gspca_dev;
144 146
145 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 147 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
146 data, 2); 148 data, 2);
147 *val = data[0] & MT9M111_RMB_MIRROR_COLS; 149 *val = data[0] & MT9M111_RMB_MIRROR_COLS;
148 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 150 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
149 151
150 return (err < 0) ? err : 0; 152 return err;
151} 153}
152 154
153int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 155int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -159,19 +161,19 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
159 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 161 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
160 162
161 /* Set the correct page map */ 163 /* Set the correct page map */
162 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 164 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
163 if (err < 0) 165 if (err < 0)
164 goto out; 166 goto out;
165 167
166 err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2); 168 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
167 if (err < 0) 169 if (err < 0)
168 goto out; 170 goto out;
169 171
170 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); 172 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
171 err = mt9m111_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 173 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
172 data, 2); 174 data, 2);
173out: 175out:
174 return (err < 0) ? err : 0; 176 return err;
175} 177}
176 178
177int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 179int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -180,7 +182,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
180 u8 data[2] = {0x00, 0x00}; 182 u8 data[2] = {0x00, 0x00};
181 struct sd *sd = (struct sd *) gspca_dev; 183 struct sd *sd = (struct sd *) gspca_dev;
182 184
183 err = mt9m111_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); 185 err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2);
184 tmp = ((data[1] << 8) | data[0]); 186 tmp = ((data[1] << 8) | data[0]);
185 187
186 *val = ((tmp & (1 << 10)) * 2) | 188 *val = ((tmp & (1 << 10)) * 2) |
@@ -190,7 +192,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
190 192
191 PDEBUG(D_V4L2, "Read gain %d", *val); 193 PDEBUG(D_V4L2, "Read gain %d", *val);
192 194
193 return (err < 0) ? err : 0; 195 return err;
194} 196}
195 197
196int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) 198int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -200,7 +202,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
200 struct sd *sd = (struct sd *) gspca_dev; 202 struct sd *sd = (struct sd *) gspca_dev;
201 203
202 /* Set the correct page map */ 204 /* Set the correct page map */
203 err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 205 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
204 if (err < 0) 206 if (err < 0)
205 goto out; 207 goto out;
206 208
@@ -225,90 +227,13 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
225 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, 227 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
226 data[1], data[0]); 228 data[1], data[0]);
227 229
228 err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN, 230 err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
229 data, 2); 231 data, 2);
230out: 232out:
231 return (err < 0) ? err : 0; 233 return err;
232}
233
234int mt9m111_read_sensor(struct sd *sd, const u8 address,
235 u8 *i2c_data, const u8 len) {
236 int err, i;
237
238 do {
239 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
240 } while ((*i2c_data & I2C_BUSY) && !err);
241 if (err < 0)
242 goto out;
243
244 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
245 sd->sensor->i2c_slave_id);
246 if (err < 0)
247 goto out;
248
249 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
250 if (err < 0)
251 goto out;
252
253 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x1a);
254 if (err < 0)
255 goto out;
256
257 for (i = 0; i < len && !err; i++) {
258 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
259
260 PDEBUG(D_CONF, "Reading sensor register "
261 "0x%x contains 0x%x ", address, *i2c_data);
262 }
263out:
264 return (err < 0) ? err : 0;
265}
266
267int mt9m111_write_sensor(struct sd *sd, const u8 address,
268 u8 *i2c_data, const u8 len)
269{
270 int err, i;
271 u8 *p;
272 struct usb_device *udev = sd->gspca_dev.dev;
273 __u8 *buf = sd->gspca_dev.usb_buf;
274
275 /* No sensor with a data width larger
276 than 16 bits has yet been seen, nor with 0 :p*/
277 if (len > 2 || !len)
278 return -EINVAL;
279
280 memcpy(buf, sensor_urb_skeleton,
281 sizeof(sensor_urb_skeleton));
282
283 buf[11] = sd->sensor->i2c_slave_id;
284 buf[15] = address;
285
286 p = buf + 16;
287
288 /* Copy a four byte write sequence for each byte to be written to */
289 for (i = 0; i < len; i++) {
290 memcpy(p, sensor_urb_skeleton + 16, 4);
291 p[3] = i2c_data[i];
292 p += 4;
293 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
294 address, i2c_data[i]);
295 }
296
297 /* Copy the tailer */
298 memcpy(p, sensor_urb_skeleton + 20, 4);
299
300 /* Set the total length */
301 p[3] = 0x10 + len;
302
303 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
304 0x04, 0x40, 0x19,
305 0x0000, buf,
306 20 + len * 4, M5602_URB_MSG_TIMEOUT);
307
308 return (err < 0) ? err : 0;
309} 234}
310 235
311void mt9m111_dump_registers(struct sd *sd) 236static void mt9m111_dump_registers(struct sd *sd)
312{ 237{
313 u8 address, value[2] = {0x00, 0x00}; 238 u8 address, value[2] = {0x00, 0x00};
314 239
@@ -316,27 +241,27 @@ void mt9m111_dump_registers(struct sd *sd)
316 241
317 info("Dumping the mt9m111 sensor core registers"); 242 info("Dumping the mt9m111 sensor core registers");
318 value[1] = MT9M111_SENSOR_CORE; 243 value[1] = MT9M111_SENSOR_CORE;
319 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); 244 m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
320 for (address = 0; address < 0xff; address++) { 245 for (address = 0; address < 0xff; address++) {
321 mt9m111_read_sensor(sd, address, value, 2); 246 m5602_read_sensor(sd, address, value, 2);
322 info("register 0x%x contains 0x%x%x", 247 info("register 0x%x contains 0x%x%x",
323 address, value[0], value[1]); 248 address, value[0], value[1]);
324 } 249 }
325 250
326 info("Dumping the mt9m111 color pipeline registers"); 251 info("Dumping the mt9m111 color pipeline registers");
327 value[1] = MT9M111_COLORPIPE; 252 value[1] = MT9M111_COLORPIPE;
328 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); 253 m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
329 for (address = 0; address < 0xff; address++) { 254 for (address = 0; address < 0xff; address++) {
330 mt9m111_read_sensor(sd, address, value, 2); 255 m5602_read_sensor(sd, address, value, 2);
331 info("register 0x%x contains 0x%x%x", 256 info("register 0x%x contains 0x%x%x",
332 address, value[0], value[1]); 257 address, value[0], value[1]);
333 } 258 }
334 259
335 info("Dumping the mt9m111 camera control registers"); 260 info("Dumping the mt9m111 camera control registers");
336 value[1] = MT9M111_CAMERA_CONTROL; 261 value[1] = MT9M111_CAMERA_CONTROL;
337 mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, value, 2); 262 m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
338 for (address = 0; address < 0xff; address++) { 263 for (address = 0; address < 0xff; address++) {
339 mt9m111_read_sensor(sd, address, value, 2); 264 m5602_read_sensor(sd, address, value, 2);
340 info("register 0x%x contains 0x%x%x", 265 info("register 0x%x contains 0x%x%x",
341 address, value[0], value[1]); 266 address, value[0], value[1]);
342 } 267 }
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 315209d5aeef..e795ab7a36c9 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -87,14 +87,6 @@ int mt9m111_probe(struct sd *sd);
87int mt9m111_init(struct sd *sd); 87int mt9m111_init(struct sd *sd);
88int mt9m111_power_down(struct sd *sd); 88int mt9m111_power_down(struct sd *sd);
89 89
90int mt9m111_read_sensor(struct sd *sd, const u8 address,
91 u8 *i2c_data, const u8 len);
92
93int mt9m111_write_sensor(struct sd *sd, const u8 address,
94 u8 *i2c_data, const u8 len);
95
96void mt9m111_dump_registers(struct sd *sd);
97
98int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 90int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
99int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 91int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
100int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 92int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -106,14 +98,12 @@ static struct m5602_sensor mt9m111 = {
106 .name = "MT9M111", 98 .name = "MT9M111",
107 99
108 .i2c_slave_id = 0xba, 100 .i2c_slave_id = 0xba,
101 .i2c_regW = 2,
109 102
110 .probe = mt9m111_probe, 103 .probe = mt9m111_probe,
111 .init = mt9m111_init, 104 .init = mt9m111_init,
112 .power_down = mt9m111_power_down, 105 .power_down = mt9m111_power_down,
113 106
114 .read_sensor = mt9m111_read_sensor,
115 .write_sensor = mt9m111_write_sensor,
116
117 .nctrls = 3, 107 .nctrls = 3,
118 .ctrls = { 108 .ctrls = {
119 { 109 {
@@ -1003,7 +993,7 @@ static const unsigned char init_mt9m111[][4] =
1003 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, 993 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
1004 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 994 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
1005 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 995 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
1006 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, 996 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/
1007 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, 997 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
1008 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 998 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
1009 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 999 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 837c7e47661c..c908a8d6970a 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -18,77 +18,57 @@
18 18
19#include "m5602_ov9650.h" 19#include "m5602_ov9650.h"
20 20
21int ov9650_read_sensor(struct sd *sd, const u8 address, 21/* Vertically and horizontally flips the image if matched, needed for machines
22 u8 *i2c_data, const u8 len) 22 where the sensor is mounted upside down */
23{ 23static
24 int err, i; 24 const
25 25 struct dmi_system_id ov9650_flip_dmi_table[] = {
26 /* The ov9650 registers have a max depth of one byte */ 26 {
27 if (len > 1 || !len) 27 .ident = "ASUS A6VC",
28 return -EINVAL; 28 .matches = {
29 29 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
30 do { 30 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
31 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); 31 }
32 } while ((*i2c_data & I2C_BUSY) && !err); 32 },
33 33 {
34 m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, 34 .ident = "ASUS A6VM",
35 ov9650.i2c_slave_id); 35 .matches = {
36 m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); 36 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
37 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len); 37 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
38 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); 38 }
39 39 },
40 for (i = 0; i < len; i++) { 40 {
41 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); 41 .ident = "ASUS A6JC",
42 42 .matches = {
43 PDEBUG(D_CONF, "Reading sensor register " 43 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
44 "0x%x containing 0x%x ", address, *i2c_data); 44 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
45 } 45 }
46 return (err < 0) ? err : 0; 46 },
47} 47 {
48 48 .ident = "ASUS A6Ja",
49int ov9650_write_sensor(struct sd *sd, const u8 address, 49 .matches = {
50 u8 *i2c_data, const u8 len) 50 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
51{ 51 DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
52 int err, i; 52 }
53 u8 *p; 53 },
54 struct usb_device *udev = sd->gspca_dev.dev; 54 {
55 __u8 *buf = sd->gspca_dev.usb_buf; 55 .ident = "ASUS A6Kt",
56 56 .matches = {
57 /* The ov9650 only supports one byte writes */ 57 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
58 if (len > 1 || !len) 58 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
59 return -EINVAL; 59 }
60 60 },
61 memcpy(buf, sensor_urb_skeleton, 61 {
62 sizeof(sensor_urb_skeleton)); 62 .ident = "Alienware Aurora m9700",
63 63 .matches = {
64 buf[11] = sd->sensor->i2c_slave_id; 64 DMI_MATCH(DMI_SYS_VENDOR, "alienware"),
65 buf[15] = address; 65 DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
66 66 }
67 /* Special case larger sensor writes */ 67 },
68 p = buf + 16; 68 { }
69 69};
70 /* Copy a four byte write sequence for each byte to be written to */
71 for (i = 0; i < len; i++) {
72 memcpy(p, sensor_urb_skeleton + 16, 4);
73 p[3] = i2c_data[i];
74 p += 4;
75 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
76 address, i2c_data[i]);
77 }
78
79 /* Copy the tailer */
80 memcpy(p, sensor_urb_skeleton + 20, 4);
81
82 /* Set the total length */
83 p[3] = 0x10 + len;
84
85 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
86 0x04, 0x40, 0x19,
87 0x0000, buf,
88 20 + len * 4, M5602_URB_MSG_TIMEOUT);
89 70
90 return (err < 0) ? err : 0; 71static void ov9650_dump_registers(struct sd *sd);
91}
92 72
93int ov9650_probe(struct sd *sd) 73int ov9650_probe(struct sd *sd)
94{ 74{
@@ -110,16 +90,16 @@ int ov9650_probe(struct sd *sd)
110 for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) { 90 for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) {
111 u8 data = preinit_ov9650[i][2]; 91 u8 data = preinit_ov9650[i][2];
112 if (preinit_ov9650[i][0] == SENSOR) 92 if (preinit_ov9650[i][0] == SENSOR)
113 ov9650_write_sensor(sd, 93 m5602_write_sensor(sd,
114 preinit_ov9650[i][1], &data, 1); 94 preinit_ov9650[i][1], &data, 1);
115 else 95 else
116 m5602_write_bridge(sd, preinit_ov9650[i][1], data); 96 m5602_write_bridge(sd, preinit_ov9650[i][1], data);
117 } 97 }
118 98
119 if (ov9650_read_sensor(sd, OV9650_PID, &prod_id, 1)) 99 if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
120 return -ENODEV; 100 return -ENODEV;
121 101
122 if (ov9650_read_sensor(sd, OV9650_VER, &ver_id, 1)) 102 if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1))
123 return -ENODEV; 103 return -ENODEV;
124 104
125 if ((prod_id == 0x96) && (ver_id == 0x52)) { 105 if ((prod_id == 0x96) && (ver_id == 0x52)) {
@@ -148,34 +128,90 @@ int ov9650_init(struct sd *sd)
148 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) { 128 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) {
149 data = init_ov9650[i][2]; 129 data = init_ov9650[i][2];
150 if (init_ov9650[i][0] == SENSOR) 130 if (init_ov9650[i][0] == SENSOR)
151 err = ov9650_write_sensor(sd, init_ov9650[i][1], 131 err = m5602_write_sensor(sd, init_ov9650[i][1],
152 &data, 1); 132 &data, 1);
153 else 133 else
154 err = m5602_write_bridge(sd, init_ov9650[i][1], data); 134 err = m5602_write_bridge(sd, init_ov9650[i][1], data);
155 } 135 }
156 136
157 if (!err && dmi_check_system(ov9650_flip_dmi_table)) { 137 if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
158 info("vflip quirk active"); 138 info("vflip quirk active");
159 data = 0x30; 139 data = 0x30;
160 err = ov9650_write_sensor(sd, OV9650_MVFP, &data, 1); 140 err = m5602_write_sensor(sd, OV9650_MVFP, &data, 1);
161 } 141 }
142 return err;
143}
144
145int ov9650_start(struct sd *sd)
146{
147 int i, err = 0;
148 struct cam *cam = &sd->gspca_dev.cam;
162 149
163 return (err < 0) ? err : 0; 150 for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
151 u8 data = res_init_ov9650[i][1];
152 err = m5602_write_bridge(sd, res_init_ov9650[i][0], data);
153 }
154 if (err < 0)
155 return err;
156
157 switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
158 {
159 case 640:
160 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
161
162 for (i = 0; i < ARRAY_SIZE(VGA_ov9650) && !err; i++) {
163 u8 data = VGA_ov9650[i][2];
164 if (VGA_ov9650[i][0] == SENSOR)
165 err = m5602_write_sensor(sd,
166 VGA_ov9650[i][1], &data, 1);
167 else
168 err = m5602_write_bridge(sd, VGA_ov9650[i][1], data);
169 }
170 break;
171
172 case 352:
173 PDEBUG(D_V4L2, "Configuring camera for CIF mode");
174
175 for (i = 0; i < ARRAY_SIZE(CIF_ov9650) && !err; i++) {
176 u8 data = CIF_ov9650[i][2];
177 if (CIF_ov9650[i][0] == SENSOR)
178 err = m5602_write_sensor(sd,
179 CIF_ov9650[i][1], &data, 1);
180 else
181 err = m5602_write_bridge(sd, CIF_ov9650[i][1], data);
182 }
183 break;
184
185 case 320:
186 PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
187
188 for (i = 0; i < ARRAY_SIZE(QVGA_ov9650) && !err; i++) {
189 u8 data = QVGA_ov9650[i][2];
190 if (QVGA_ov9650[i][0] == SENSOR)
191 err = m5602_write_sensor(sd,
192 QVGA_ov9650[i][1], &data, 1);
193 else
194 err = m5602_write_bridge(sd, QVGA_ov9650[i][1], data);
195 }
196 break;
197 }
198 return err;
164} 199}
165 200
166int ov9650_power_down(struct sd *sd) 201int ov9650_power_down(struct sd *sd)
167{ 202{
168 int i; 203 int i, err = 0;
169 for (i = 0; i < ARRAY_SIZE(power_down_ov9650); i++) { 204 for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) {
170 u8 data = power_down_ov9650[i][2]; 205 u8 data = power_down_ov9650[i][2];
171 if (power_down_ov9650[i][0] == SENSOR) 206 if (power_down_ov9650[i][0] == SENSOR)
172 ov9650_write_sensor(sd, 207 err = m5602_write_sensor(sd,
173 power_down_ov9650[i][1], &data, 1); 208 power_down_ov9650[i][1], &data, 1);
174 else 209 else
175 m5602_write_bridge(sd, power_down_ov9650[i][1], data); 210 err = m5602_write_bridge(sd, power_down_ov9650[i][1],
211 data);
176 } 212 }
177 213
178 return 0; 214 return err;
179} 215}
180 216
181int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 217int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -184,24 +220,24 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
184 u8 i2c_data; 220 u8 i2c_data;
185 int err; 221 int err;
186 222
187 err = ov9650_read_sensor(sd, OV9650_COM1, &i2c_data, 1); 223 err = m5602_read_sensor(sd, OV9650_COM1, &i2c_data, 1);
188 if (err < 0) 224 if (err < 0)
189 goto out; 225 goto out;
190 *val = i2c_data & 0x03; 226 *val = i2c_data & 0x03;
191 227
192 err = ov9650_read_sensor(sd, OV9650_AECH, &i2c_data, 1); 228 err = m5602_read_sensor(sd, OV9650_AECH, &i2c_data, 1);
193 if (err < 0) 229 if (err < 0)
194 goto out; 230 goto out;
195 *val |= (i2c_data << 2); 231 *val |= (i2c_data << 2);
196 232
197 err = ov9650_read_sensor(sd, OV9650_AECHM, &i2c_data, 1); 233 err = m5602_read_sensor(sd, OV9650_AECHM, &i2c_data, 1);
198 if (err < 0) 234 if (err < 0)
199 goto out; 235 goto out;
200 *val |= (i2c_data & 0x3f) << 10; 236 *val |= (i2c_data & 0x3f) << 10;
201 237
202 PDEBUG(D_V4L2, "Read exposure %d", *val); 238 PDEBUG(D_V4L2, "Read exposure %d", *val);
203out: 239out:
204 return (err < 0) ? err : 0; 240 return err;
205} 241}
206 242
207int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 243int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
@@ -215,24 +251,24 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
215 251
216 /* The 6 MSBs */ 252 /* The 6 MSBs */
217 i2c_data = (val >> 10) & 0x3f; 253 i2c_data = (val >> 10) & 0x3f;
218 err = ov9650_write_sensor(sd, OV9650_AECHM, 254 err = m5602_write_sensor(sd, OV9650_AECHM,
219 &i2c_data, 1); 255 &i2c_data, 1);
220 if (err < 0) 256 if (err < 0)
221 goto out; 257 goto out;
222 258
223 /* The 8 middle bits */ 259 /* The 8 middle bits */
224 i2c_data = (val >> 2) & 0xff; 260 i2c_data = (val >> 2) & 0xff;
225 err = ov9650_write_sensor(sd, OV9650_AECH, 261 err = m5602_write_sensor(sd, OV9650_AECH,
226 &i2c_data, 1); 262 &i2c_data, 1);
227 if (err < 0) 263 if (err < 0)
228 goto out; 264 goto out;
229 265
230 /* The 2 LSBs */ 266 /* The 2 LSBs */
231 i2c_data = val & 0x03; 267 i2c_data = val & 0x03;
232 err = ov9650_write_sensor(sd, OV9650_COM1, &i2c_data, 1); 268 err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
233 269
234out: 270out:
235 return (err < 0) ? err : 0; 271 return err;
236} 272}
237 273
238int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 274int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -241,13 +277,13 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
241 u8 i2c_data; 277 u8 i2c_data;
242 struct sd *sd = (struct sd *) gspca_dev; 278 struct sd *sd = (struct sd *) gspca_dev;
243 279
244 ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 280 m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
245 *val = (i2c_data & 0x03) << 8; 281 *val = (i2c_data & 0x03) << 8;
246 282
247 err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); 283 err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
248 *val |= i2c_data; 284 *val |= i2c_data;
249 PDEBUG(D_V4L2, "Read gain %d", *val); 285 PDEBUG(D_V4L2, "Read gain %d", *val);
250 return (err < 0) ? err : 0; 286 return err;
251} 287}
252 288
253int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) 289int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -259,16 +295,16 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
259 /* The 2 MSB */ 295 /* The 2 MSB */
260 /* Read the OV9650_VREF register first to avoid 296 /* Read the OV9650_VREF register first to avoid
261 corrupting the VREF high and low bits */ 297 corrupting the VREF high and low bits */
262 ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 298 m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
263 /* Mask away all uninteresting bits */ 299 /* Mask away all uninteresting bits */
264 i2c_data = ((val & 0x0300) >> 2) | 300 i2c_data = ((val & 0x0300) >> 2) |
265 (i2c_data & 0x3F); 301 (i2c_data & 0x3F);
266 err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1); 302 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
267 303
268 /* The 8 LSBs */ 304 /* The 8 LSBs */
269 i2c_data = val & 0xff; 305 i2c_data = val & 0xff;
270 err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); 306 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
271 return (err < 0) ? err : 0; 307 return err;
272} 308}
273 309
274int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 310int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -277,12 +313,12 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
277 u8 i2c_data; 313 u8 i2c_data;
278 struct sd *sd = (struct sd *) gspca_dev; 314 struct sd *sd = (struct sd *) gspca_dev;
279 315
280 err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1); 316 err = m5602_read_sensor(sd, OV9650_RED, &i2c_data, 1);
281 *val = i2c_data; 317 *val = i2c_data;
282 318
283 PDEBUG(D_V4L2, "Read red gain %d", *val); 319 PDEBUG(D_V4L2, "Read red gain %d", *val);
284 320
285 return (err < 0) ? err : 0; 321 return err;
286} 322}
287 323
288int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 324int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -295,9 +331,9 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
295 val & 0xff); 331 val & 0xff);
296 332
297 i2c_data = val & 0xff; 333 i2c_data = val & 0xff;
298 err = ov9650_write_sensor(sd, OV9650_RED, &i2c_data, 1); 334 err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
299 335
300 return (err < 0) ? err : 0; 336 return err;
301} 337}
302 338
303int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 339int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -306,12 +342,12 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
306 u8 i2c_data; 342 u8 i2c_data;
307 struct sd *sd = (struct sd *) gspca_dev; 343 struct sd *sd = (struct sd *) gspca_dev;
308 344
309 err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1); 345 err = m5602_read_sensor(sd, OV9650_BLUE, &i2c_data, 1);
310 *val = i2c_data; 346 *val = i2c_data;
311 347
312 PDEBUG(D_V4L2, "Read blue gain %d", *val); 348 PDEBUG(D_V4L2, "Read blue gain %d", *val);
313 349
314 return (err < 0) ? err : 0; 350 return err;
315} 351}
316 352
317int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 353int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -324,9 +360,9 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
324 val & 0xff); 360 val & 0xff);
325 361
326 i2c_data = val & 0xff; 362 i2c_data = val & 0xff;
327 err = ov9650_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); 363 err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
328 364
329 return (err < 0) ? err : 0; 365 return err;
330} 366}
331 367
332int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 368int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -335,14 +371,14 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
335 u8 i2c_data; 371 u8 i2c_data;
336 struct sd *sd = (struct sd *) gspca_dev; 372 struct sd *sd = (struct sd *) gspca_dev;
337 373
338 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 374 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
339 if (dmi_check_system(ov9650_flip_dmi_table)) 375 if (dmi_check_system(ov9650_flip_dmi_table))
340 *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1; 376 *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1;
341 else 377 else
342 *val = (i2c_data & OV9650_HFLIP) >> 5; 378 *val = (i2c_data & OV9650_HFLIP) >> 5;
343 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 379 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
344 380
345 return (err < 0) ? err : 0; 381 return err;
346} 382}
347 383
348int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 384int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -352,20 +388,20 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
352 struct sd *sd = (struct sd *) gspca_dev; 388 struct sd *sd = (struct sd *) gspca_dev;
353 389
354 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 390 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
355 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 391 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
356 if (err < 0) 392 if (err < 0)
357 goto out; 393 goto out;
358 394
359 if (dmi_check_system(ov9650_flip_dmi_table)) 395 if (dmi_check_system(ov9650_flip_dmi_table))
360 i2c_data = ((i2c_data & 0xdf) | 396 i2c_data = ((i2c_data & 0xdf) |
361 (((val ? 0 : 1) & 0x01) << 5)); 397 (((val ? 0 : 1) & 0x01) << 5));
362 else 398 else
363 i2c_data = ((i2c_data & 0xdf) | 399 i2c_data = ((i2c_data & 0xdf) |
364 ((val & 0x01) << 5)); 400 ((val & 0x01) << 5));
365 401
366 err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 402 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
367out: 403out:
368 return (err < 0) ? err : 0; 404 return err;
369} 405}
370 406
371int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 407int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -374,14 +410,14 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
374 u8 i2c_data; 410 u8 i2c_data;
375 struct sd *sd = (struct sd *) gspca_dev; 411 struct sd *sd = (struct sd *) gspca_dev;
376 412
377 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 413 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
378 if (dmi_check_system(ov9650_flip_dmi_table)) 414 if (dmi_check_system(ov9650_flip_dmi_table))
379 *val = ((i2c_data & 0x10) >> 4) ? 0 : 1; 415 *val = ((i2c_data & 0x10) >> 4) ? 0 : 1;
380 else 416 else
381 *val = (i2c_data & 0x10) >> 4; 417 *val = (i2c_data & 0x10) >> 4;
382 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 418 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
383 419
384 return (err < 0) ? err : 0; 420 return err;
385} 421}
386 422
387int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 423int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -391,7 +427,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
391 struct sd *sd = (struct sd *) gspca_dev; 427 struct sd *sd = (struct sd *) gspca_dev;
392 428
393 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 429 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
394 err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1); 430 err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
395 if (err < 0) 431 if (err < 0)
396 goto out; 432 goto out;
397 433
@@ -402,9 +438,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
402 i2c_data = ((i2c_data & 0xef) | 438 i2c_data = ((i2c_data & 0xef) |
403 ((val & 0x01) << 4)); 439 ((val & 0x01) << 4));
404 440
405 err = ov9650_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 441 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
406out: 442out:
407 return (err < 0) ? err : 0; 443 return err;
408} 444}
409 445
410int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 446int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -413,16 +449,16 @@ int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
413 u8 i2c_data; 449 u8 i2c_data;
414 struct sd *sd = (struct sd *) gspca_dev; 450 struct sd *sd = (struct sd *) gspca_dev;
415 451
416 err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 452 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
417 if (err < 0) 453 if (err < 0)
418 goto out; 454 goto out;
419 *val = (i2c_data & 0x03) << 8; 455 *val = (i2c_data & 0x03) << 8;
420 456
421 err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1); 457 err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
422 *val |= i2c_data; 458 *val |= i2c_data;
423 PDEBUG(D_V4L2, "Read gain %d", *val); 459 PDEBUG(D_V4L2, "Read gain %d", *val);
424out: 460out:
425 return (err < 0) ? err : 0; 461 return err;
426} 462}
427 463
428int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 464int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -435,22 +471,22 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
435 471
436 /* Read the OV9650_VREF register first to avoid 472 /* Read the OV9650_VREF register first to avoid
437 corrupting the VREF high and low bits */ 473 corrupting the VREF high and low bits */
438 err = ov9650_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 474 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
439 if (err < 0) 475 if (err < 0)
440 goto out; 476 goto out;
441 477
442 /* Mask away all uninteresting bits */ 478 /* Mask away all uninteresting bits */
443 i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F); 479 i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
444 err = ov9650_write_sensor(sd, OV9650_VREF, &i2c_data, 1); 480 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
445 if (err < 0) 481 if (err < 0)
446 goto out; 482 goto out;
447 483
448 /* The 8 LSBs */ 484 /* The 8 LSBs */
449 i2c_data = val & 0xff; 485 i2c_data = val & 0xff;
450 err = ov9650_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); 486 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
451 487
452out: 488out:
453 return (err < 0) ? err : 0; 489 return err;
454} 490}
455 491
456int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) 492int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -459,11 +495,11 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
459 u8 i2c_data; 495 u8 i2c_data;
460 struct sd *sd = (struct sd *) gspca_dev; 496 struct sd *sd = (struct sd *) gspca_dev;
461 497
462 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 498 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
463 *val = (i2c_data & OV9650_AWB_EN) >> 1; 499 *val = (i2c_data & OV9650_AWB_EN) >> 1;
464 PDEBUG(D_V4L2, "Read auto white balance %d", *val); 500 PDEBUG(D_V4L2, "Read auto white balance %d", *val);
465 501
466 return (err < 0) ? err : 0; 502 return err;
467} 503}
468 504
469int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) 505int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -473,14 +509,14 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
473 struct sd *sd = (struct sd *) gspca_dev; 509 struct sd *sd = (struct sd *) gspca_dev;
474 510
475 PDEBUG(D_V4L2, "Set auto white balance to %d", val); 511 PDEBUG(D_V4L2, "Set auto white balance to %d", val);
476 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 512 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
477 if (err < 0) 513 if (err < 0)
478 goto out; 514 goto out;
479 515
480 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); 516 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
481 err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 517 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
482out: 518out:
483 return (err < 0) ? err : 0; 519 return err;
484} 520}
485 521
486int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) 522int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -489,11 +525,11 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
489 u8 i2c_data; 525 u8 i2c_data;
490 struct sd *sd = (struct sd *) gspca_dev; 526 struct sd *sd = (struct sd *) gspca_dev;
491 527
492 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 528 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
493 *val = (i2c_data & OV9650_AGC_EN) >> 2; 529 *val = (i2c_data & OV9650_AGC_EN) >> 2;
494 PDEBUG(D_V4L2, "Read auto gain control %d", *val); 530 PDEBUG(D_V4L2, "Read auto gain control %d", *val);
495 531
496 return (err < 0) ? err : 0; 532 return err;
497} 533}
498 534
499int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 535int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -503,23 +539,23 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
503 struct sd *sd = (struct sd *) gspca_dev; 539 struct sd *sd = (struct sd *) gspca_dev;
504 540
505 PDEBUG(D_V4L2, "Set auto gain control to %d", val); 541 PDEBUG(D_V4L2, "Set auto gain control to %d", val);
506 err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 542 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
507 if (err < 0) 543 if (err < 0)
508 goto out; 544 goto out;
509 545
510 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 546 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
511 err = ov9650_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 547 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
512out: 548out:
513 return (err < 0) ? err : 0; 549 return err;
514} 550}
515 551
516void ov9650_dump_registers(struct sd *sd) 552static void ov9650_dump_registers(struct sd *sd)
517{ 553{
518 int address; 554 int address;
519 info("Dumping the ov9650 register state"); 555 info("Dumping the ov9650 register state");
520 for (address = 0; address < 0xa9; address++) { 556 for (address = 0; address < 0xa9; address++) {
521 u8 value; 557 u8 value;
522 ov9650_read_sensor(sd, address, &value, 1); 558 m5602_read_sensor(sd, address, &value, 1);
523 info("register 0x%x contains 0x%x", 559 info("register 0x%x contains 0x%x",
524 address, value); 560 address, value);
525 } 561 }
@@ -531,9 +567,9 @@ void ov9650_dump_registers(struct sd *sd)
531 u8 old_value, ctrl_value; 567 u8 old_value, ctrl_value;
532 u8 test_value[2] = {0xff, 0xff}; 568 u8 test_value[2] = {0xff, 0xff};
533 569
534 ov9650_read_sensor(sd, address, &old_value, 1); 570 m5602_read_sensor(sd, address, &old_value, 1);
535 ov9650_write_sensor(sd, address, test_value, 1); 571 m5602_write_sensor(sd, address, test_value, 1);
536 ov9650_read_sensor(sd, address, &ctrl_value, 1); 572 m5602_read_sensor(sd, address, &ctrl_value, 1);
537 573
538 if (ctrl_value == test_value[0]) 574 if (ctrl_value == test_value[0])
539 info("register 0x%x is writeable", address); 575 info("register 0x%x is writeable", address);
@@ -541,6 +577,6 @@ void ov9650_dump_registers(struct sd *sd)
541 info("register 0x%x is read only", address); 577 info("register 0x%x is read only", address);
542 578
543 /* Restore original value */ 579 /* Restore original value */
544 ov9650_write_sensor(sd, address, &old_value, 1); 580 m5602_write_sensor(sd, address, &old_value, 1);
545 } 581 }
546} 582}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index 065632f0378e..f4b33b8e8dae 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -20,7 +20,6 @@
20#define M5602_OV9650_H_ 20#define M5602_OV9650_H_
21 21
22#include <linux/dmi.h> 22#include <linux/dmi.h>
23
24#include "m5602_sensor.h" 23#include "m5602_sensor.h"
25 24
26/*****************************************************************************/ 25/*****************************************************************************/
@@ -36,6 +35,7 @@
36#define OV9650_PID 0x0a 35#define OV9650_PID 0x0a
37#define OV9650_VER 0x0b 36#define OV9650_VER 0x0b
38#define OV9650_COM3 0x0c 37#define OV9650_COM3 0x0c
38#define OV9650_COM4 0x0d
39#define OV9650_COM5 0x0e 39#define OV9650_COM5 0x0e
40#define OV9650_COM6 0x0f 40#define OV9650_COM6 0x0f
41#define OV9650_AECH 0x10 41#define OV9650_AECH 0x10
@@ -94,6 +94,8 @@
94 94
95#define OV9650_REGISTER_RESET (1 << 7) 95#define OV9650_REGISTER_RESET (1 << 7)
96#define OV9650_VGA_SELECT (1 << 6) 96#define OV9650_VGA_SELECT (1 << 6)
97#define OV9650_CIF_SELECT (1 << 5)
98#define OV9650_QVGA_SELECT (1 << 4)
97#define OV9650_RGB_SELECT (1 << 2) 99#define OV9650_RGB_SELECT (1 << 2)
98#define OV9650_RAW_RGB_SELECT (1 << 0) 100#define OV9650_RAW_RGB_SELECT (1 << 0)
99 101
@@ -108,6 +110,8 @@
108#define OV9650_SYSTEM_CLK_SEL (1 << 7) 110#define OV9650_SYSTEM_CLK_SEL (1 << 7)
109#define OV9650_SLAM_MODE (1 << 4) 111#define OV9650_SLAM_MODE (1 << 4)
110 112
113#define OV9650_QVGA_VARIOPIXEL (1 << 7)
114
111#define OV9650_VFLIP (1 << 4) 115#define OV9650_VFLIP (1 << 4)
112#define OV9650_HFLIP (1 << 5) 116#define OV9650_HFLIP (1 << 5)
113 117
@@ -124,15 +128,9 @@ extern int dump_sensor;
124 128
125int ov9650_probe(struct sd *sd); 129int ov9650_probe(struct sd *sd);
126int ov9650_init(struct sd *sd); 130int ov9650_init(struct sd *sd);
131int ov9650_start(struct sd *sd);
127int ov9650_power_down(struct sd *sd); 132int ov9650_power_down(struct sd *sd);
128 133
129int ov9650_read_sensor(struct sd *sd, const u8 address,
130 u8 *i2c_data, const u8 len);
131int ov9650_write_sensor(struct sd *sd, const u8 address,
132 u8 *i2c_data, const u8 len);
133
134void ov9650_dump_registers(struct sd *sd);
135
136int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 134int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
137int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 135int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
138int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 136int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -155,11 +153,11 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
155static struct m5602_sensor ov9650 = { 153static struct m5602_sensor ov9650 = {
156 .name = "OV9650", 154 .name = "OV9650",
157 .i2c_slave_id = 0x60, 155 .i2c_slave_id = 0x60,
156 .i2c_regW = 1,
158 .probe = ov9650_probe, 157 .probe = ov9650_probe,
159 .init = ov9650_init, 158 .init = ov9650_init,
159 .start = ov9650_start,
160 .power_down = ov9650_power_down, 160 .power_down = ov9650_power_down,
161 .read_sensor = ov9650_read_sensor,
162 .write_sensor = ov9650_write_sensor,
163 161
164 .nctrls = 8, 162 .nctrls = 8,
165 .ctrls = { 163 .ctrls = {
@@ -264,18 +262,38 @@ static struct m5602_sensor ov9650 = {
264 } 262 }
265 }, 263 },
266 264
267 .nmodes = 1, 265 .nmodes = 3,
268 .modes = { 266 .modes = {
269 { 267 {
270 M5602_DEFAULT_FRAME_WIDTH, 268 320,
271 M5602_DEFAULT_FRAME_HEIGHT, 269 240,
270 V4L2_PIX_FMT_SBGGR8,
271 V4L2_FIELD_NONE,
272 .sizeimage =
273 320 * 240,
274 .bytesperline = 320,
275 .colorspace = V4L2_COLORSPACE_SRGB,
276 .priv = 0
277 }, {
278 352,
279 288,
280 V4L2_PIX_FMT_SBGGR8,
281 V4L2_FIELD_NONE,
282 .sizeimage =
283 352 * 288,
284 .bytesperline = 352,
285 .colorspace = V4L2_COLORSPACE_SRGB,
286 .priv = 0
287 }, {
288 640,
289 480,
272 V4L2_PIX_FMT_SBGGR8, 290 V4L2_PIX_FMT_SBGGR8,
273 V4L2_FIELD_NONE, 291 V4L2_FIELD_NONE,
274 .sizeimage = 292 .sizeimage =
275 M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT, 293 640 * 480,
276 .bytesperline = M5602_DEFAULT_FRAME_WIDTH, 294 .bytesperline = 640,
277 .colorspace = V4L2_COLORSPACE_SRGB, 295 .colorspace = V4L2_COLORSPACE_SRGB,
278 .priv = 1 296 .priv = 0
279 } 297 }
280 } 298 }
281}; 299};
@@ -324,6 +342,7 @@ static const unsigned char init_ov9650[][3] =
324 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, 342 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
325 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 343 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
326 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a}, 344 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
345
327 /* Reset chip */ 346 /* Reset chip */
328 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 347 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
329 /* Enable double clock */ 348 /* Enable double clock */
@@ -331,8 +350,6 @@ static const unsigned char init_ov9650[][3] =
331 /* Do something out of spec with the power */ 350 /* Do something out of spec with the power */
332 {SENSOR, OV9650_OFON, 0x40}, 351 {SENSOR, OV9650_OFON, 0x40},
333 352
334 /* Set QQVGA */
335 {SENSOR, OV9650_COM1, 0x20},
336 /* Set fast AGC/AEC algorithm with unlimited step size */ 353 /* Set fast AGC/AEC algorithm with unlimited step size */
337 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | 354 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
338 OV9650_AEC_UNLIM_STEP_SIZE | 355 OV9650_AEC_UNLIM_STEP_SIZE |
@@ -343,7 +360,7 @@ static const unsigned char init_ov9650[][3] =
343 {SENSOR, OV9650_ACOM38, 0x81}, 360 {SENSOR, OV9650_ACOM38, 0x81},
344 /* Turn off color matrix coefficient double option */ 361 /* Turn off color matrix coefficient double option */
345 {SENSOR, OV9650_COM16, 0x00}, 362 {SENSOR, OV9650_COM16, 0x00},
346 /* Enable color matrix for RGB/YUV, Delay Y channel, 363 /* Enable color matrix for RGB/YUV, Delay Y channel,
347 set output Y/UV delay to 1 */ 364 set output Y/UV delay to 1 */
348 {SENSOR, OV9650_COM13, 0x19}, 365 {SENSOR, OV9650_COM13, 0x19},
349 /* Enable digital BLC, Set output mode to U Y V Y */ 366 /* Enable digital BLC, Set output mode to U Y V Y */
@@ -352,7 +369,7 @@ static const unsigned char init_ov9650[][3] =
352 {SENSOR, OV9650_COM24, 0x00}, 369 {SENSOR, OV9650_COM24, 0x00},
353 /* Enable HREF and some out of spec things */ 370 /* Enable HREF and some out of spec things */
354 {SENSOR, OV9650_COM12, 0x73}, 371 {SENSOR, OV9650_COM12, 0x73},
355 /* Set all DBLC offset signs to positive and 372 /* Set all DBLC offset signs to positive and
356 do some out of spec stuff */ 373 do some out of spec stuff */
357 {SENSOR, OV9650_DBLC1, 0xdf}, 374 {SENSOR, OV9650_DBLC1, 0xdf},
358 {SENSOR, OV9650_COM21, 0x06}, 375 {SENSOR, OV9650_COM21, 0x06},
@@ -364,7 +381,7 @@ static const unsigned char init_ov9650[][3] =
364 {SENSOR, OV9650_RSVD96, 0x04}, 381 {SENSOR, OV9650_RSVD96, 0x04},
365 /* Enable full range output */ 382 /* Enable full range output */
366 {SENSOR, OV9650_COM15, 0x0}, 383 {SENSOR, OV9650_COM15, 0x0},
367 /* Enable HREF at optical black, enable ADBLC bias, 384 /* Enable HREF at optical black, enable ADBLC bias,
368 enable ADBLC, reset timings at format change */ 385 enable ADBLC, reset timings at format change */
369 {SENSOR, OV9650_COM6, 0x4b}, 386 {SENSOR, OV9650_COM6, 0x4b},
370 /* Subtract 32 from the B channel bias */ 387 /* Subtract 32 from the B channel bias */
@@ -385,7 +402,7 @@ static const unsigned char init_ov9650[][3] =
385 {SENSOR, OV9650_AEB, 0x5c}, 402 {SENSOR, OV9650_AEB, 0x5c},
386 /* Set the high and low limit nibbles to 3 */ 403 /* Set the high and low limit nibbles to 3 */
387 {SENSOR, OV9650_VPT, 0xc3}, 404 {SENSOR, OV9650_VPT, 0xc3},
388 /* Set the Automatic Gain Ceiling (AGC) to 128x, 405 /* Set the Automatic Gain Ceiling (AGC) to 128x,
389 drop VSYNC at frame drop, 406 drop VSYNC at frame drop,
390 limit exposure timing, 407 limit exposure timing,
391 drop frame when the AEC step is larger than the exposure gap */ 408 drop frame when the AEC step is larger than the exposure gap */
@@ -394,9 +411,9 @@ static const unsigned char init_ov9650[][3] =
394 and set PWDN to SLVS (slave mode vertical sync) */ 411 and set PWDN to SLVS (slave mode vertical sync) */
395 {SENSOR, OV9650_COM10, 0x42}, 412 {SENSOR, OV9650_COM10, 0x42},
396 /* Set horizontal column start high to default value */ 413 /* Set horizontal column start high to default value */
397 {SENSOR, OV9650_HSTART, 0x1a}, 414 {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
398 /* Set horizontal column end */ 415 /* Set horizontal column end */
399 {SENSOR, OV9650_HSTOP, 0xbf}, 416 {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
400 /* Complementing register to the two writes above */ 417 /* Complementing register to the two writes above */
401 {SENSOR, OV9650_HREF, 0xb2}, 418 {SENSOR, OV9650_HREF, 0xb2},
402 /* Set vertical row start high bits */ 419 /* Set vertical row start high bits */
@@ -405,10 +422,6 @@ static const unsigned char init_ov9650[][3] =
405 {SENSOR, OV9650_VSTOP, 0x7e}, 422 {SENSOR, OV9650_VSTOP, 0x7e},
406 /* Set complementing vertical frame control */ 423 /* Set complementing vertical frame control */
407 {SENSOR, OV9650_VREF, 0x10}, 424 {SENSOR, OV9650_VREF, 0x10},
408 /* Set raw RGB output format with VGA resolution */
409 {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
410 OV9650_RGB_SELECT |
411 OV9650_RAW_RGB_SELECT},
412 {SENSOR, OV9650_ADC, 0x04}, 425 {SENSOR, OV9650_ADC, 0x04},
413 {SENSOR, OV9650_HV, 0x40}, 426 {SENSOR, OV9650_HV, 0x40},
414 /* Enable denoise, and white-pixel erase */ 427 /* Enable denoise, and white-pixel erase */
@@ -417,30 +430,15 @@ static const unsigned char init_ov9650[][3] =
417 /* Set the high bits of the exposure value */ 430 /* Set the high bits of the exposure value */
418 {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)}, 431 {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)},
419 432
433 /* Enable VARIOPIXEL */
434 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
435 {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
436
420 /* Set the low bits of the exposure value */ 437 /* Set the low bits of the exposure value */
421 {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)}, 438 {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)},
422 {SENSOR, OV9650_GAIN, GAIN_DEFAULT}, 439 {SENSOR, OV9650_GAIN, GAIN_DEFAULT},
423 {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT}, 440 {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT},
424 {SENSOR, OV9650_RED, RED_GAIN_DEFAULT}, 441 {SENSOR, OV9650_RED, RED_GAIN_DEFAULT},
425
426 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
427 {SENSOR, OV9650_COM5, OV9650_SYSTEM_CLK_SEL},
428
429 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
430 {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
431 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
432 {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
433 {BRIDGE, M5602_XB_SIG_INI, 0x01},
434 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
435 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
436 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
437 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
438 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0},
439 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
440 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
441 {BRIDGE, M5602_XB_HSYNC_PARA, 0x5e},
442 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
443 {BRIDGE, M5602_XB_HSYNC_PARA, 0xde}
444}; 442};
445 443
446static const unsigned char power_down_ov9650[][3] = 444static const unsigned char power_down_ov9650[][3] =
@@ -460,43 +458,76 @@ static const unsigned char power_down_ov9650[][3] =
460 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06}, 458 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
461 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, 459 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
462 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, 460 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
463 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0} 461 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
464}; 462};
465 463
466/* Vertically and horizontally flips the image if matched, needed for machines 464static const unsigned char res_init_ov9650[][2] =
467 where the sensor is mounted upside down */ 465{
468static 466 {M5602_XB_LINE_OF_FRAME_H, 0x82},
469 const 467 {M5602_XB_LINE_OF_FRAME_L, 0x00},
470 struct dmi_system_id ov9650_flip_dmi_table[] = { 468 {M5602_XB_PIX_OF_LINE_H, 0x82},
471 { 469 {M5602_XB_PIX_OF_LINE_L, 0x00},
472 .ident = "ASUS A6VC", 470 {M5602_XB_SIG_INI, 0x01}
473 .matches = { 471};
474 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 472
475 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") 473static const unsigned char VGA_ov9650[][3] =
476 } 474{
477 }, 475 /* Moves the view window in a vertical orientation */
478 { 476 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
479 .ident = "ASUS A6VM", 477 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
480 .matches = { 478 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
481 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 479 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
482 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") 480 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
483 } 481 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
484 }, 482 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
485 { 483 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
486 .ident = "ASUS A6JC", 484 {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
487 .matches = { 485 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, /* 640 + 98 */
488 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 486 {BRIDGE, M5602_XB_HSYNC_PARA, 0xe2},
489 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") 487
490 } 488 {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
491 }, 489 OV9650_RGB_SELECT |
492 { 490 OV9650_RAW_RGB_SELECT},
493 .ident = "ASUS A6Kt", 491};
494 .matches = { 492
495 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 493static const unsigned char CIF_ov9650[][3] =
496 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") 494{
497 } 495 /* Moves the view window in a vertical orientation */
498 }, 496 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
499 { } 497 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
498 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
499 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
500 {BRIDGE, M5602_XB_VSYNC_PARA, 0x20}, /* 288 */
501 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
502 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
503 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
504 {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
505 {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 352 + 98 */
506 {BRIDGE, M5602_XB_HSYNC_PARA, 0xc2},
507
508 {SENSOR, OV9650_COM7, OV9650_CIF_SELECT |
509 OV9650_RGB_SELECT |
510 OV9650_RAW_RGB_SELECT},
511};
512
513static const unsigned char QVGA_ov9650[][3] =
514{
515 /* Moves the view window in a vertical orientation */
516 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
517 {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
518 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
519 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
520 {BRIDGE, M5602_XB_VSYNC_PARA, 0xf0}, /* 240 */
521 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
522 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
523 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
524 {BRIDGE, M5602_XB_HSYNC_PARA, 0x31}, /* 50 */
525 {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 320 + 50 */
526 {BRIDGE, M5602_XB_HSYNC_PARA, 0x71},
527
528 {SENSOR, OV9650_COM7, OV9650_QVGA_SELECT |
529 OV9650_RGB_SELECT |
530 OV9650_RAW_RGB_SELECT},
500}; 531};
501 532
502#endif 533#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index d17ac52566e6..2e7fb91673cf 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -18,6 +18,8 @@
18 18
19#include "m5602_po1030.h" 19#include "m5602_po1030.h"
20 20
21static void po1030_dump_registers(struct sd *sd);
22
21int po1030_probe(struct sd *sd) 23int po1030_probe(struct sd *sd)
22{ 24{
23 u8 prod_id = 0, ver_id = 0, i; 25 u8 prod_id = 0, ver_id = 0, i;
@@ -38,16 +40,16 @@ int po1030_probe(struct sd *sd)
38 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { 40 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
39 u8 data = preinit_po1030[i][2]; 41 u8 data = preinit_po1030[i][2];
40 if (preinit_po1030[i][0] == SENSOR) 42 if (preinit_po1030[i][0] == SENSOR)
41 po1030_write_sensor(sd, 43 m5602_write_sensor(sd,
42 preinit_po1030[i][1], &data, 1); 44 preinit_po1030[i][1], &data, 1);
43 else 45 else
44 m5602_write_bridge(sd, preinit_po1030[i][1], data); 46 m5602_write_bridge(sd, preinit_po1030[i][1], data);
45 } 47 }
46 48
47 if (po1030_read_sensor(sd, 0x3, &prod_id, 1)) 49 if (m5602_read_sensor(sd, 0x3, &prod_id, 1))
48 return -ENODEV; 50 return -ENODEV;
49 51
50 if (po1030_read_sensor(sd, 0x4, &ver_id, 1)) 52 if (m5602_read_sensor(sd, 0x4, &ver_id, 1))
51 return -ENODEV; 53 return -ENODEV;
52 54
53 if ((prod_id == 0x02) && (ver_id == 0xef)) { 55 if ((prod_id == 0x02) && (ver_id == 0xef)) {
@@ -64,78 +66,12 @@ sensor_found:
64 return 0; 66 return 0;
65} 67}
66 68
67int po1030_read_sensor(struct sd *sd, const u8 address,
68 u8 *i2c_data, const u8 len)
69{
70 int err, i;
71
72 do {
73 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
74 } while ((*i2c_data & I2C_BUSY) && !err);
75
76 m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
77 sd->sensor->i2c_slave_id);
78 m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
79 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len);
80 m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
81
82 for (i = 0; i < len; i++) {
83 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
84
85 PDEBUG(D_CONF, "Reading sensor register "
86 "0x%x containing 0x%x ", address, *i2c_data);
87 }
88 return (err < 0) ? err : 0;
89}
90
91int po1030_write_sensor(struct sd *sd, const u8 address,
92 u8 *i2c_data, const u8 len)
93{
94 int err, i;
95 u8 *p;
96 struct usb_device *udev = sd->gspca_dev.dev;
97 __u8 *buf = sd->gspca_dev.usb_buf;
98
99 /* The po1030 only supports one byte writes */
100 if (len > 1 || !len)
101 return -EINVAL;
102
103 memcpy(buf, sensor_urb_skeleton, sizeof(sensor_urb_skeleton));
104
105 buf[11] = sd->sensor->i2c_slave_id;
106 buf[15] = address;
107
108 p = buf + 16;
109
110 /* Copy a four byte write sequence for each byte to be written to */
111 for (i = 0; i < len; i++) {
112 memcpy(p, sensor_urb_skeleton + 16, 4);
113 p[3] = i2c_data[i];
114 p += 4;
115 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
116 address, i2c_data[i]);
117 }
118
119 /* Copy the footer */
120 memcpy(p, sensor_urb_skeleton + 20, 4);
121
122 /* Set the total length */
123 p[3] = 0x10 + len;
124
125 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
126 0x04, 0x40, 0x19,
127 0x0000, buf,
128 20 + len * 4, M5602_URB_MSG_TIMEOUT);
129
130 return (err < 0) ? err : 0;
131}
132
133int po1030_init(struct sd *sd) 69int po1030_init(struct sd *sd)
134{ 70{
135 int i, err = 0; 71 int i, err = 0;
136 72
137 /* Init the sensor */ 73 /* Init the sensor */
138 for (i = 0; i < ARRAY_SIZE(init_po1030); i++) { 74 for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
139 u8 data[2] = {0x00, 0x00}; 75 u8 data[2] = {0x00, 0x00};
140 76
141 switch (init_po1030[i][0]) { 77 switch (init_po1030[i][0]) {
@@ -147,16 +83,10 @@ int po1030_init(struct sd *sd)
147 83
148 case SENSOR: 84 case SENSOR:
149 data[0] = init_po1030[i][2]; 85 data[0] = init_po1030[i][2];
150 err = po1030_write_sensor(sd, 86 err = m5602_write_sensor(sd,
151 init_po1030[i][1], data, 1); 87 init_po1030[i][1], data, 1);
152 break; 88 break;
153 89
154 case SENSOR_LONG:
155 data[0] = init_po1030[i][2];
156 data[1] = init_po1030[i][3];
157 err = po1030_write_sensor(sd,
158 init_po1030[i][1], data, 2);
159 break;
160 default: 90 default:
161 info("Invalid stream command, exiting init"); 91 info("Invalid stream command, exiting init");
162 return -EINVAL; 92 return -EINVAL;
@@ -166,7 +96,7 @@ int po1030_init(struct sd *sd)
166 if (dump_sensor) 96 if (dump_sensor)
167 po1030_dump_registers(sd); 97 po1030_dump_registers(sd);
168 98
169 return (err < 0) ? err : 0; 99 return err;
170} 100}
171 101
172int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 102int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -175,19 +105,19 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
175 u8 i2c_data; 105 u8 i2c_data;
176 int err; 106 int err;
177 107
178 err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_H, 108 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H,
179 &i2c_data, 1); 109 &i2c_data, 1);
180 if (err < 0) 110 if (err < 0)
181 goto out; 111 goto out;
182 *val = (i2c_data << 8); 112 *val = (i2c_data << 8);
183 113
184 err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_M, 114 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M,
185 &i2c_data, 1); 115 &i2c_data, 1);
186 *val |= i2c_data; 116 *val |= i2c_data;
187 117
188 PDEBUG(D_V4L2, "Exposure read as %d", *val); 118 PDEBUG(D_V4L2, "Exposure read as %d", *val);
189out: 119out:
190 return (err < 0) ? err : 0; 120 return err;
191} 121}
192 122
193int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 123int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
@@ -202,7 +132,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
202 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", 132 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
203 i2c_data); 133 i2c_data);
204 134
205 err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H, 135 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
206 &i2c_data, 1); 136 &i2c_data, 1);
207 if (err < 0) 137 if (err < 0)
208 goto out; 138 goto out;
@@ -210,11 +140,11 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
210 i2c_data = (val & 0xff); 140 i2c_data = (val & 0xff);
211 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", 141 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
212 i2c_data); 142 i2c_data);
213 err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M, 143 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
214 &i2c_data, 1); 144 &i2c_data, 1);
215 145
216out: 146out:
217 return (err < 0) ? err : 0; 147 return err;
218} 148}
219 149
220int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 150int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -223,12 +153,12 @@ int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
223 u8 i2c_data; 153 u8 i2c_data;
224 int err; 154 int err;
225 155
226 err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, 156 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
227 &i2c_data, 1); 157 &i2c_data, 1);
228 *val = i2c_data; 158 *val = i2c_data;
229 PDEBUG(D_V4L2, "Read global gain %d", *val); 159 PDEBUG(D_V4L2, "Read global gain %d", *val);
230 160
231 return (err < 0) ? err : 0; 161 return err;
232} 162}
233 163
234int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 164int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -237,14 +167,14 @@ int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
237 u8 i2c_data; 167 u8 i2c_data;
238 int err; 168 int err;
239 169
240 err = po1030_read_sensor(sd, PO1030_REG_CONTROL2, 170 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2,
241 &i2c_data, 1); 171 &i2c_data, 1);
242 172
243 *val = (i2c_data >> 7) & 0x01 ; 173 *val = (i2c_data >> 7) & 0x01 ;
244 174
245 PDEBUG(D_V4L2, "Read hflip %d", *val); 175 PDEBUG(D_V4L2, "Read hflip %d", *val);
246 176
247 return (err < 0) ? err : 0; 177 return err;
248} 178}
249 179
250int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 180int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -254,13 +184,17 @@ int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
254 int err; 184 int err;
255 185
256 PDEBUG(D_V4L2, "Set hflip %d", val); 186 PDEBUG(D_V4L2, "Set hflip %d", val);
187 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
188 if (err < 0)
189 goto out;
257 190
258 i2c_data = (val & 0x01) << 7; 191 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
259 192
260 err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, 193 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
261 &i2c_data, 1); 194 &i2c_data, 1);
262 195
263 return (err < 0) ? err : 0; 196out:
197 return err;
264} 198}
265 199
266int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 200int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -269,14 +203,14 @@ int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
269 u8 i2c_data; 203 u8 i2c_data;
270 int err; 204 int err;
271 205
272 err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN, 206 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
273 &i2c_data, 1); 207 &i2c_data, 1);
274 208
275 *val = (i2c_data >> 6) & 0x01; 209 *val = (i2c_data >> 6) & 0x01;
276 210
277 PDEBUG(D_V4L2, "Read vflip %d", *val); 211 PDEBUG(D_V4L2, "Read vflip %d", *val);
278 212
279 return (err < 0) ? err : 0; 213 return err;
280} 214}
281 215
282int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 216int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -286,13 +220,17 @@ int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
286 int err; 220 int err;
287 221
288 PDEBUG(D_V4L2, "Set vflip %d", val); 222 PDEBUG(D_V4L2, "Set vflip %d", val);
223 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
224 if (err < 0)
225 goto out;
289 226
290 i2c_data = (val & 0x01) << 6; 227 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
291 228
292 err = po1030_write_sensor(sd, PO1030_REG_CONTROL2, 229 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
293 &i2c_data, 1); 230 &i2c_data, 1);
294 231
295 return (err < 0) ? err : 0; 232out:
233 return err;
296} 234}
297 235
298int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) 236int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -303,9 +241,9 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
303 241
304 i2c_data = val & 0xff; 242 i2c_data = val & 0xff;
305 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); 243 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
306 err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN, 244 err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
307 &i2c_data, 1); 245 &i2c_data, 1);
308 return (err < 0) ? err : 0; 246 return err;
309} 247}
310 248
311int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 249int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -314,11 +252,11 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
314 u8 i2c_data; 252 u8 i2c_data;
315 int err; 253 int err;
316 254
317 err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN, 255 err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN,
318 &i2c_data, 1); 256 &i2c_data, 1);
319 *val = i2c_data; 257 *val = i2c_data;
320 PDEBUG(D_V4L2, "Read red gain %d", *val); 258 PDEBUG(D_V4L2, "Read red gain %d", *val);
321 return (err < 0) ? err : 0; 259 return err;
322} 260}
323 261
324int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 262int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -329,9 +267,9 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
329 267
330 i2c_data = val & 0xff; 268 i2c_data = val & 0xff;
331 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); 269 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
332 err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN, 270 err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
333 &i2c_data, 1); 271 &i2c_data, 1);
334 return (err < 0) ? err : 0; 272 return err;
335} 273}
336 274
337int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 275int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -340,12 +278,12 @@ int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
340 u8 i2c_data; 278 u8 i2c_data;
341 int err; 279 int err;
342 280
343 err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN, 281 err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN,
344 &i2c_data, 1); 282 &i2c_data, 1);
345 *val = i2c_data; 283 *val = i2c_data;
346 PDEBUG(D_V4L2, "Read blue gain %d", *val); 284 PDEBUG(D_V4L2, "Read blue gain %d", *val);
347 285
348 return (err < 0) ? err : 0; 286 return err;
349} 287}
350 288
351int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 289int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -355,10 +293,10 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
355 int err; 293 int err;
356 i2c_data = val & 0xff; 294 i2c_data = val & 0xff;
357 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); 295 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
358 err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN, 296 err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
359 &i2c_data, 1); 297 &i2c_data, 1);
360 298
361 return (err < 0) ? err : 0; 299 return err;
362} 300}
363 301
364int po1030_power_down(struct sd *sd) 302int po1030_power_down(struct sd *sd)
@@ -366,14 +304,14 @@ int po1030_power_down(struct sd *sd)
366 return 0; 304 return 0;
367} 305}
368 306
369void po1030_dump_registers(struct sd *sd) 307static void po1030_dump_registers(struct sd *sd)
370{ 308{
371 int address; 309 int address;
372 u8 value = 0; 310 u8 value = 0;
373 311
374 info("Dumping the po1030 sensor core registers"); 312 info("Dumping the po1030 sensor core registers");
375 for (address = 0; address < 0x7f; address++) { 313 for (address = 0; address < 0x7f; address++) {
376 po1030_read_sensor(sd, address, &value, 1); 314 m5602_read_sensor(sd, address, &value, 1);
377 info("register 0x%x contains 0x%x", 315 info("register 0x%x contains 0x%x",
378 address, value); 316 address, value);
379 } 317 }
@@ -385,9 +323,9 @@ void po1030_dump_registers(struct sd *sd)
385 u8 old_value, ctrl_value; 323 u8 old_value, ctrl_value;
386 u8 test_value[2] = {0xff, 0xff}; 324 u8 test_value[2] = {0xff, 0xff};
387 325
388 po1030_read_sensor(sd, address, &old_value, 1); 326 m5602_read_sensor(sd, address, &old_value, 1);
389 po1030_write_sensor(sd, address, test_value, 1); 327 m5602_write_sensor(sd, address, test_value, 1);
390 po1030_read_sensor(sd, address, &ctrl_value, 1); 328 m5602_read_sensor(sd, address, &ctrl_value, 1);
391 329
392 if (ctrl_value == test_value[0]) 330 if (ctrl_value == test_value[0])
393 info("register 0x%x is writeable", address); 331 info("register 0x%x is writeable", address);
@@ -395,6 +333,6 @@ void po1030_dump_registers(struct sd *sd)
395 info("register 0x%x is read only", address); 333 info("register 0x%x is read only", address);
396 334
397 /* Restore original value */ 335 /* Restore original value */
398 po1030_write_sensor(sd, address, &old_value, 1); 336 m5602_write_sensor(sd, address, &old_value, 1);
399 } 337 }
400} 338}
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index a0b75ff61d79..def39d5bcec6 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -10,7 +10,7 @@
10 * v4l2 interface modeled after the V4L2 driver 10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers 11 * for SN9C10x PC Camera Controllers
12 * 12 *
13 * Register defines taken from Pascal Stangs Proxycon Armlib 13 * Register defines taken from Pascal Stangs Procyon Armlib
14 * 14 *
15 * This program is free software; you can redistribute it and/or 15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as 16 * modify it under the terms of the GNU General Public License as
@@ -128,13 +128,6 @@ int po1030_probe(struct sd *sd);
128int po1030_init(struct sd *sd); 128int po1030_init(struct sd *sd);
129int po1030_power_down(struct sd *sd); 129int po1030_power_down(struct sd *sd);
130 130
131void po1030_dump_registers(struct sd *sd);
132
133int po1030_read_sensor(struct sd *sd, const u8 address,
134 u8 *i2c_data, const u8 len);
135int po1030_write_sensor(struct sd *sd, const u8 address,
136 u8 *i2c_data, const u8 len);
137
138int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 131int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
139int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 132int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
140int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 133int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -152,6 +145,7 @@ static struct m5602_sensor po1030 = {
152 .name = "PO1030", 145 .name = "PO1030",
153 146
154 .i2c_slave_id = 0xdc, 147 .i2c_slave_id = 0xdc,
148 .i2c_regW = 1,
155 149
156 .probe = po1030_probe, 150 .probe = po1030_probe,
157 .init = po1030_init, 151 .init = po1030_init,
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 14b1eac5b812..e564a61a72d7 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -18,6 +18,40 @@
18 18
19#include "m5602_s5k4aa.h" 19#include "m5602_s5k4aa.h"
20 20
21static
22 const
23 struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
24 {
25 .ident = "Fujitsu-Siemens Amilo Xa 2528",
26 .matches = {
27 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
28 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
29 }
30 }, {
31 .ident = "Fujitsu-Siemens Amilo Xi 2550",
32 .matches = {
33 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
34 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
35 }
36 }, {
37 .ident = "MSI GX700",
38 .matches = {
39 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
40 DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
41 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
42 }
43 }, {
44 .ident = "MSI GX700/GX705/EX700",
45 .matches = {
46 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
47 DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700")
48 }
49 },
50 { }
51};
52
53static void s5k4aa_dump_registers(struct sd *sd);
54
21int s5k4aa_probe(struct sd *sd) 55int s5k4aa_probe(struct sd *sd)
22{ 56{
23 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 57 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -49,7 +83,7 @@ int s5k4aa_probe(struct sd *sd)
49 83
50 case SENSOR: 84 case SENSOR:
51 data[0] = preinit_s5k4aa[i][2]; 85 data[0] = preinit_s5k4aa[i][2];
52 err = s5k4aa_write_sensor(sd, 86 err = m5602_write_sensor(sd,
53 preinit_s5k4aa[i][1], 87 preinit_s5k4aa[i][1],
54 data, 1); 88 data, 1);
55 break; 89 break;
@@ -57,7 +91,7 @@ int s5k4aa_probe(struct sd *sd)
57 case SENSOR_LONG: 91 case SENSOR_LONG:
58 data[0] = preinit_s5k4aa[i][2]; 92 data[0] = preinit_s5k4aa[i][2];
59 data[1] = preinit_s5k4aa[i][3]; 93 data[1] = preinit_s5k4aa[i][3];
60 err = s5k4aa_write_sensor(sd, 94 err = m5602_write_sensor(sd,
61 preinit_s5k4aa[i][1], 95 preinit_s5k4aa[i][1],
62 data, 2); 96 data, 2);
63 break; 97 break;
@@ -68,13 +102,14 @@ int s5k4aa_probe(struct sd *sd)
68 } 102 }
69 103
70 /* Test some registers, but we don't know their exact meaning yet */ 104 /* Test some registers, but we don't know their exact meaning yet */
71 if (s5k4aa_read_sensor(sd, 0x00, prod_id, sizeof(prod_id))) 105 if (m5602_read_sensor(sd, 0x00, prod_id, sizeof(prod_id)))
72 return -ENODEV; 106 return -ENODEV;
73 107
74 if (memcmp(prod_id, expected_prod_id, sizeof(prod_id))) 108 if (memcmp(prod_id, expected_prod_id, sizeof(prod_id)))
75 return -ENODEV; 109 return -ENODEV;
76 else 110 else
77 info("Detected a s5k4aa sensor"); 111 info("Detected a s5k4aa sensor");
112
78sensor_found: 113sensor_found:
79 sd->gspca_dev.cam.cam_mode = s5k4aa.modes; 114 sd->gspca_dev.cam.cam_mode = s5k4aa.modes;
80 sd->gspca_dev.cam.nmodes = s5k4aa.nmodes; 115 sd->gspca_dev.cam.nmodes = s5k4aa.nmodes;
@@ -84,90 +119,6 @@ sensor_found:
84 return 0; 119 return 0;
85} 120}
86 121
87int s5k4aa_read_sensor(struct sd *sd, const u8 address,
88 u8 *i2c_data, const u8 len)
89{
90 int err, i;
91
92 do {
93 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
94 } while ((*i2c_data & I2C_BUSY) && !err);
95 if (err < 0)
96 goto out;
97
98 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
99 sd->sensor->i2c_slave_id);
100 if (err < 0)
101 goto out;
102
103 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
104 if (err < 0)
105 goto out;
106
107 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
108 if (err < 0)
109 goto out;
110
111 do {
112 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
113 } while ((*i2c_data & I2C_BUSY) && !err);
114 if (err < 0)
115 goto out;
116
117 for (i = 0; (i < len) & !err; i++) {
118 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
119
120 PDEBUG(D_CONF, "Reading sensor register "
121 "0x%x containing 0x%x ", address, *i2c_data);
122 }
123out:
124 return (err < 0) ? err : 0;
125}
126
127int s5k4aa_write_sensor(struct sd *sd, const u8 address,
128 u8 *i2c_data, const u8 len)
129{
130 int err, i;
131 u8 *p;
132 struct usb_device *udev = sd->gspca_dev.dev;
133 __u8 *buf = sd->gspca_dev.usb_buf;
134
135 /* No sensor with a data width larger than 16 bits has yet been seen */
136 if (len > 2 || !len)
137 return -EINVAL;
138
139 memcpy(buf, sensor_urb_skeleton,
140 sizeof(sensor_urb_skeleton));
141
142 buf[11] = sd->sensor->i2c_slave_id;
143 buf[15] = address;
144
145 /* Special case larger sensor writes */
146 p = buf + 16;
147
148 /* Copy a four byte write sequence for each byte to be written to */
149 for (i = 0; i < len; i++) {
150 memcpy(p, sensor_urb_skeleton + 16, 4);
151 p[3] = i2c_data[i];
152 p += 4;
153 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
154 address, i2c_data[i]);
155 }
156
157 /* Copy the tailer */
158 memcpy(p, sensor_urb_skeleton + 20, 4);
159
160 /* Set the total length */
161 p[3] = 0x10 + len;
162
163 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
164 0x04, 0x40, 0x19,
165 0x0000, buf,
166 20 + len * 4, M5602_URB_MSG_TIMEOUT);
167
168 return (err < 0) ? err : 0;
169}
170
171int s5k4aa_init(struct sd *sd) 122int s5k4aa_init(struct sd *sd)
172{ 123{
173 int i, err = 0; 124 int i, err = 0;
@@ -184,14 +135,14 @@ int s5k4aa_init(struct sd *sd)
184 135
185 case SENSOR: 136 case SENSOR:
186 data[0] = init_s5k4aa[i][2]; 137 data[0] = init_s5k4aa[i][2];
187 err = s5k4aa_write_sensor(sd, 138 err = m5602_write_sensor(sd,
188 init_s5k4aa[i][1], data, 1); 139 init_s5k4aa[i][1], data, 1);
189 break; 140 break;
190 141
191 case SENSOR_LONG: 142 case SENSOR_LONG:
192 data[0] = init_s5k4aa[i][2]; 143 data[0] = init_s5k4aa[i][2];
193 data[1] = init_s5k4aa[i][3]; 144 data[1] = init_s5k4aa[i][3];
194 err = s5k4aa_write_sensor(sd, 145 err = m5602_write_sensor(sd,
195 init_s5k4aa[i][1], data, 2); 146 init_s5k4aa[i][1], data, 2);
196 break; 147 break;
197 default: 148 default:
@@ -206,21 +157,21 @@ int s5k4aa_init(struct sd *sd)
206 if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) { 157 if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) {
207 u8 data = 0x02; 158 u8 data = 0x02;
208 info("vertical flip quirk active"); 159 info("vertical flip quirk active");
209 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 160 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
210 s5k4aa_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); 161 m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
211 data |= S5K4AA_RM_V_FLIP; 162 data |= S5K4AA_RM_V_FLIP;
212 data &= ~S5K4AA_RM_H_FLIP; 163 data &= ~S5K4AA_RM_H_FLIP;
213 s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 164 m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
214 165
215 /* Decrement COLSTART to preserve color order (BGGR) */ 166 /* Decrement COLSTART to preserve color order (BGGR) */
216 s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 167 m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
217 data--; 168 data--;
218 s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 169 m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
219 170
220 /* Increment ROWSTART to preserve color order (BGGR) */ 171 /* Increment ROWSTART to preserve color order (BGGR) */
221 s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 172 m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
222 data++; 173 data++;
223 s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 174 m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
224 } 175 }
225 176
226 return (err < 0) ? err : 0; 177 return (err < 0) ? err : 0;
@@ -237,20 +188,20 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
237 u8 data = S5K4AA_PAGE_MAP_2; 188 u8 data = S5K4AA_PAGE_MAP_2;
238 int err; 189 int err;
239 190
240 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 191 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
241 if (err < 0) 192 if (err < 0)
242 goto out; 193 goto out;
243 194
244 err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); 195 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
245 if (err < 0) 196 if (err < 0)
246 goto out; 197 goto out;
247 198
248 *val = data << 8; 199 *val = data << 8;
249 err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); 200 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
250 *val |= data; 201 *val |= data;
251 PDEBUG(D_V4L2, "Read exposure %d", *val); 202 PDEBUG(D_V4L2, "Read exposure %d", *val);
252out: 203out:
253 return (err < 0) ? err : 0; 204 return err;
254} 205}
255 206
256int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 207int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
@@ -260,17 +211,17 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
260 int err; 211 int err;
261 212
262 PDEBUG(D_V4L2, "Set exposure to %d", val); 213 PDEBUG(D_V4L2, "Set exposure to %d", val);
263 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 214 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
264 if (err < 0) 215 if (err < 0)
265 goto out; 216 goto out;
266 data = (val >> 8) & 0xff; 217 data = (val >> 8) & 0xff;
267 err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); 218 err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
268 if (err < 0) 219 if (err < 0)
269 goto out; 220 goto out;
270 data = val & 0xff; 221 data = val & 0xff;
271 err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); 222 err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
272out: 223out:
273 return (err < 0) ? err : 0; 224 return err;
274} 225}
275 226
276int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 227int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -279,16 +230,16 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
279 u8 data = S5K4AA_PAGE_MAP_2; 230 u8 data = S5K4AA_PAGE_MAP_2;
280 int err; 231 int err;
281 232
282 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 233 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
283 if (err < 0) 234 if (err < 0)
284 goto out; 235 goto out;
285 236
286 err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 237 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
287 *val = (data & S5K4AA_RM_V_FLIP) >> 7; 238 *val = (data & S5K4AA_RM_V_FLIP) >> 7;
288 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 239 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
289 240
290out: 241out:
291 return (err < 0) ? err : 0; 242 return err;
292} 243}
293 244
294int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 245int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -298,35 +249,35 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
298 int err; 249 int err;
299 250
300 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 251 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
301 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 252 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
302 if (err < 0) 253 if (err < 0)
303 goto out; 254 goto out;
304 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 255 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
305 if (err < 0) 256 if (err < 0)
306 goto out; 257 goto out;
307 data = ((data & ~S5K4AA_RM_V_FLIP) 258 data = ((data & ~S5K4AA_RM_V_FLIP)
308 | ((val & 0x01) << 7)); 259 | ((val & 0x01) << 7));
309 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 260 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
310 if (err < 0) 261 if (err < 0)
311 goto out; 262 goto out;
312 263
313 if (val) { 264 if (val) {
314 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 265 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
315 if (err < 0) 266 if (err < 0)
316 goto out; 267 goto out;
317 268
318 data++; 269 data++;
319 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 270 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
320 } else { 271 } else {
321 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 272 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
322 if (err < 0) 273 if (err < 0)
323 goto out; 274 goto out;
324 275
325 data--; 276 data--;
326 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 277 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
327 } 278 }
328out: 279out:
329 return (err < 0) ? err : 0; 280 return err;
330} 281}
331 282
332int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 283int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -335,15 +286,15 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
335 u8 data = S5K4AA_PAGE_MAP_2; 286 u8 data = S5K4AA_PAGE_MAP_2;
336 int err; 287 int err;
337 288
338 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 289 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
339 if (err < 0) 290 if (err < 0)
340 goto out; 291 goto out;
341 292
342 err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 293 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
343 *val = (data & S5K4AA_RM_H_FLIP) >> 6; 294 *val = (data & S5K4AA_RM_H_FLIP) >> 6;
344 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 295 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
345out: 296out:
346 return (err < 0) ? err : 0; 297 return err;
347} 298}
348 299
349int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 300int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -354,35 +305,35 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
354 305
355 PDEBUG(D_V4L2, "Set horizontal flip to %d", 306 PDEBUG(D_V4L2, "Set horizontal flip to %d",
356 val); 307 val);
357 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 308 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
358 if (err < 0) 309 if (err < 0)
359 goto out; 310 goto out;
360 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 311 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
361 if (err < 0) 312 if (err < 0)
362 goto out; 313 goto out;
363 314
364 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); 315 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
365 err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 316 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
366 if (err < 0) 317 if (err < 0)
367 goto out; 318 goto out;
368 319
369 if (val) { 320 if (val) {
370 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 321 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
371 if (err < 0) 322 if (err < 0)
372 goto out; 323 goto out;
373 data++; 324 data++;
374 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 325 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
375 if (err < 0) 326 if (err < 0)
376 goto out; 327 goto out;
377 } else { 328 } else {
378 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 329 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
379 if (err < 0) 330 if (err < 0)
380 goto out; 331 goto out;
381 data--; 332 data--;
382 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 333 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
383 } 334 }
384out: 335out:
385 return (err < 0) ? err : 0; 336 return err;
386} 337}
387 338
388int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 339int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -391,16 +342,16 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
391 u8 data = S5K4AA_PAGE_MAP_2; 342 u8 data = S5K4AA_PAGE_MAP_2;
392 int err; 343 int err;
393 344
394 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 345 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
395 if (err < 0) 346 if (err < 0)
396 goto out; 347 goto out;
397 348
398 err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); 349 err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
399 *val = data; 350 *val = data;
400 PDEBUG(D_V4L2, "Read gain %d", *val); 351 PDEBUG(D_V4L2, "Read gain %d", *val);
401 352
402out: 353out:
403 return (err < 0) ? err : 0; 354 return err;
404} 355}
405 356
406int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) 357int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -410,28 +361,28 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
410 int err; 361 int err;
411 362
412 PDEBUG(D_V4L2, "Set gain to %d", val); 363 PDEBUG(D_V4L2, "Set gain to %d", val);
413 err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 364 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
414 if (err < 0) 365 if (err < 0)
415 goto out; 366 goto out;
416 367
417 data = val & 0xff; 368 data = val & 0xff;
418 err = s5k4aa_write_sensor(sd, S5K4AA_GAIN_2, &data, 1); 369 err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1);
419 370
420out: 371out:
421 return (err < 0) ? err : 0; 372 return err;
422} 373}
423 374
424void s5k4aa_dump_registers(struct sd *sd) 375static void s5k4aa_dump_registers(struct sd *sd)
425{ 376{
426 int address; 377 int address;
427 u8 page, old_page; 378 u8 page, old_page;
428 s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); 379 m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
429 for (page = 0; page < 16; page++) { 380 for (page = 0; page < 16; page++) {
430 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); 381 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
431 info("Dumping the s5k4aa register state for page 0x%x", page); 382 info("Dumping the s5k4aa register state for page 0x%x", page);
432 for (address = 0; address <= 0xff; address++) { 383 for (address = 0; address <= 0xff; address++) {
433 u8 value = 0; 384 u8 value = 0;
434 s5k4aa_read_sensor(sd, address, &value, 1); 385 m5602_read_sensor(sd, address, &value, 1);
435 info("register 0x%x contains 0x%x", 386 info("register 0x%x contains 0x%x",
436 address, value); 387 address, value);
437 } 388 }
@@ -439,15 +390,15 @@ void s5k4aa_dump_registers(struct sd *sd)
439 info("s5k4aa register state dump complete"); 390 info("s5k4aa register state dump complete");
440 391
441 for (page = 0; page < 16; page++) { 392 for (page = 0; page < 16; page++) {
442 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1); 393 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
443 info("Probing for which registers that are " 394 info("Probing for which registers that are "
444 "read/write for page 0x%x", page); 395 "read/write for page 0x%x", page);
445 for (address = 0; address <= 0xff; address++) { 396 for (address = 0; address <= 0xff; address++) {
446 u8 old_value, ctrl_value, test_value = 0xff; 397 u8 old_value, ctrl_value, test_value = 0xff;
447 398
448 s5k4aa_read_sensor(sd, address, &old_value, 1); 399 m5602_read_sensor(sd, address, &old_value, 1);
449 s5k4aa_write_sensor(sd, address, &test_value, 1); 400 m5602_write_sensor(sd, address, &test_value, 1);
450 s5k4aa_read_sensor(sd, address, &ctrl_value, 1); 401 m5602_read_sensor(sd, address, &ctrl_value, 1);
451 402
452 if (ctrl_value == test_value) 403 if (ctrl_value == test_value)
453 info("register 0x%x is writeable", address); 404 info("register 0x%x is writeable", address);
@@ -455,9 +406,9 @@ void s5k4aa_dump_registers(struct sd *sd)
455 info("register 0x%x is read only", address); 406 info("register 0x%x is read only", address);
456 407
457 /* Restore original value */ 408 /* Restore original value */
458 s5k4aa_write_sensor(sd, address, &old_value, 1); 409 m5602_write_sensor(sd, address, &old_value, 1);
459 } 410 }
460 } 411 }
461 info("Read/write register probing complete"); 412 info("Read/write register probing complete");
462 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1); 413 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
463} 414}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index eaef67655afa..1f88b0d040c4 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -41,11 +41,10 @@
41#define S5K4AA_WINDOW_HEIGHT_LO 0x09 41#define S5K4AA_WINDOW_HEIGHT_LO 0x09
42#define S5K4AA_WINDOW_WIDTH_HI 0x0a 42#define S5K4AA_WINDOW_WIDTH_HI 0x0a
43#define S5K4AA_WINDOW_WIDTH_LO 0x0b 43#define S5K4AA_WINDOW_WIDTH_LO 0x0b
44#define S5K4AA_GLOBAL_GAIN__ 0x0f /* Only a guess ATM !!! */ 44#define S5K4AA_GLOBAL_GAIN__ 0x0f
45#define S5K4AA_H_BLANK_HI__ 0x1d /* Only a guess ATM !!! sync lost 45/* sync lost, if too low, reduces frame rate if too high */
46 if too low, reduces frame rate 46#define S5K4AA_H_BLANK_HI__ 0x1d
47 if too high */ 47#define S5K4AA_H_BLANK_LO__ 0x1e
48#define S5K4AA_H_BLANK_LO__ 0x1e /* Only a guess ATM !!! */
49#define S5K4AA_EXPOSURE_HI 0x17 48#define S5K4AA_EXPOSURE_HI 0x17
50#define S5K4AA_EXPOSURE_LO 0x18 49#define S5K4AA_EXPOSURE_LO 0x18
51#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ 50#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */
@@ -68,13 +67,6 @@ int s5k4aa_probe(struct sd *sd);
68int s5k4aa_init(struct sd *sd); 67int s5k4aa_init(struct sd *sd);
69int s5k4aa_power_down(struct sd *sd); 68int s5k4aa_power_down(struct sd *sd);
70 69
71void s5k4aa_dump_registers(struct sd *sd);
72
73int s5k4aa_read_sensor(struct sd *sd, const u8 address,
74 u8 *i2c_data, const u8 len);
75int s5k4aa_write_sensor(struct sd *sd, const u8 address,
76 u8 *i2c_data, const u8 len);
77
78int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 70int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
79int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 71int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
80int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 72int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -89,9 +81,8 @@ static struct m5602_sensor s5k4aa = {
89 .probe = s5k4aa_probe, 81 .probe = s5k4aa_probe,
90 .init = s5k4aa_init, 82 .init = s5k4aa_init,
91 .power_down = s5k4aa_power_down, 83 .power_down = s5k4aa_power_down,
92 .read_sensor = s5k4aa_read_sensor,
93 .write_sensor = s5k4aa_write_sensor,
94 .i2c_slave_id = 0x5a, 84 .i2c_slave_id = 0x5a,
85 .i2c_regW = 2,
95 .nctrls = 4, 86 .nctrls = 4,
96 .ctrls = { 87 .ctrls = {
97 { 88 {
@@ -338,32 +329,4 @@ static const unsigned char init_s5k4aa[][4] =
338 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00} 329 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
339}; 330};
340 331
341static
342 const
343 struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
344 {
345 .ident = "Fujitsu-Siemens Amilo Xa 2528",
346 .matches = {
347 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
348 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
349 }
350 },
351 {
352 .ident = "Fujitsu-Siemens Amilo Xi 2550",
353 .matches = {
354 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
355 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
356 }
357 },
358 {
359 .ident = "MSI GX700",
360 .matches = {
361 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
362 DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
363 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
364 }
365 },
366 { }
367};
368
369#endif 332#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 8988a728e0b4..af3f2dc2c702 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -18,6 +18,8 @@
18 18
19#include "m5602_s5k83a.h" 19#include "m5602_s5k83a.h"
20 20
21static void s5k83a_dump_registers(struct sd *sd);
22
21int s5k83a_probe(struct sd *sd) 23int s5k83a_probe(struct sd *sd)
22{ 24{
23 u8 prod_id = 0, ver_id = 0; 25 u8 prod_id = 0, ver_id = 0;
@@ -39,7 +41,7 @@ int s5k83a_probe(struct sd *sd)
39 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) { 41 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
40 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]}; 42 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
41 if (preinit_s5k83a[i][0] == SENSOR) 43 if (preinit_s5k83a[i][0] == SENSOR)
42 err = s5k83a_write_sensor(sd, preinit_s5k83a[i][1], 44 err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
43 data, 2); 45 data, 2);
44 else 46 else
45 err = m5602_write_bridge(sd, preinit_s5k83a[i][1], 47 err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
@@ -49,10 +51,10 @@ int s5k83a_probe(struct sd *sd)
49 /* We don't know what register (if any) that contain the product id 51 /* We don't know what register (if any) that contain the product id
50 * Just pick the first addresses that seem to produce the same results 52 * Just pick the first addresses that seem to produce the same results
51 * on multiple machines */ 53 * on multiple machines */
52 if (s5k83a_read_sensor(sd, 0x00, &prod_id, 1)) 54 if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
53 return -ENODEV; 55 return -ENODEV;
54 56
55 if (s5k83a_read_sensor(sd, 0x01, &ver_id, 1)) 57 if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
56 return -ENODEV; 58 return -ENODEV;
57 59
58 if ((prod_id == 0xff) || (ver_id == 0xff)) 60 if ((prod_id == 0xff) || (ver_id == 0xff))
@@ -68,91 +70,6 @@ sensor_found:
68 return 0; 70 return 0;
69} 71}
70 72
71int s5k83a_read_sensor(struct sd *sd, const u8 address,
72 u8 *i2c_data, const u8 len)
73{
74 int err, i;
75
76 do {
77 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
78 } while ((*i2c_data & I2C_BUSY) && !err);
79 if (err < 0)
80 goto out;
81
82 err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
83 sd->sensor->i2c_slave_id);
84 if (err < 0)
85 goto out;
86
87 err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
88 if (err < 0)
89 goto out;
90
91 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
92 if (err < 0)
93 goto out;
94
95 do {
96 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
97 } while ((*i2c_data & I2C_BUSY) && !err);
98
99 if (err < 0)
100 goto out;
101 for (i = 0; i < len && !len; i++) {
102 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
103
104 PDEBUG(D_CONF, "Reading sensor register "
105 "0x%x containing 0x%x ", address, *i2c_data);
106 }
107
108out:
109 return (err < 0) ? err : 0;
110}
111
112int s5k83a_write_sensor(struct sd *sd, const u8 address,
113 u8 *i2c_data, const u8 len)
114{
115 int err, i;
116 u8 *p;
117 struct usb_device *udev = sd->gspca_dev.dev;
118 __u8 *buf = sd->gspca_dev.usb_buf;
119
120 /* No sensor with a data width larger than 16 bits has yet been seen */
121 if (len > 2 || !len)
122 return -EINVAL;
123
124 memcpy(buf, sensor_urb_skeleton,
125 sizeof(sensor_urb_skeleton));
126
127 buf[11] = sd->sensor->i2c_slave_id;
128 buf[15] = address;
129
130 /* Special case larger sensor writes */
131 p = buf + 16;
132
133 /* Copy a four byte write sequence for each byte to be written to */
134 for (i = 0; i < len; i++) {
135 memcpy(p, sensor_urb_skeleton + 16, 4);
136 p[3] = i2c_data[i];
137 p += 4;
138 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
139 address, i2c_data[i]);
140 }
141
142 /* Copy the tailer */
143 memcpy(p, sensor_urb_skeleton + 20, 4);
144
145 /* Set the total length */
146 p[3] = 0x10 + len;
147
148 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
149 0x04, 0x40, 0x19,
150 0x0000, buf,
151 20 + len * 4, M5602_URB_MSG_TIMEOUT);
152
153 return (err < 0) ? err : 0;
154}
155
156int s5k83a_init(struct sd *sd) 73int s5k83a_init(struct sd *sd)
157{ 74{
158 int i, err = 0; 75 int i, err = 0;
@@ -169,14 +86,14 @@ int s5k83a_init(struct sd *sd)
169 86
170 case SENSOR: 87 case SENSOR:
171 data[0] = init_s5k83a[i][2]; 88 data[0] = init_s5k83a[i][2];
172 err = s5k83a_write_sensor(sd, 89 err = m5602_write_sensor(sd,
173 init_s5k83a[i][1], data, 1); 90 init_s5k83a[i][1], data, 1);
174 break; 91 break;
175 92
176 case SENSOR_LONG: 93 case SENSOR_LONG:
177 data[0] = init_s5k83a[i][2]; 94 data[0] = init_s5k83a[i][2];
178 data[1] = init_s5k83a[i][3]; 95 data[1] = init_s5k83a[i][3];
179 err = s5k83a_write_sensor(sd, 96 err = m5602_write_sensor(sd,
180 init_s5k83a[i][1], data, 2); 97 init_s5k83a[i][1], data, 2);
181 break; 98 break;
182 default: 99 default:
@@ -200,14 +117,14 @@ void s5k83a_dump_registers(struct sd *sd)
200{ 117{
201 int address; 118 int address;
202 u8 page, old_page; 119 u8 page, old_page;
203 s5k83a_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); 120 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
204 121
205 for (page = 0; page < 16; page++) { 122 for (page = 0; page < 16; page++) {
206 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 123 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
207 info("Dumping the s5k83a register state for page 0x%x", page); 124 info("Dumping the s5k83a register state for page 0x%x", page);
208 for (address = 0; address <= 0xff; address++) { 125 for (address = 0; address <= 0xff; address++) {
209 u8 val = 0; 126 u8 val = 0;
210 s5k83a_read_sensor(sd, address, &val, 1); 127 m5602_read_sensor(sd, address, &val, 1);
211 info("register 0x%x contains 0x%x", 128 info("register 0x%x contains 0x%x",
212 address, val); 129 address, val);
213 } 130 }
@@ -215,15 +132,15 @@ void s5k83a_dump_registers(struct sd *sd)
215 info("s5k83a register state dump complete"); 132 info("s5k83a register state dump complete");
216 133
217 for (page = 0; page < 16; page++) { 134 for (page = 0; page < 16; page++) {
218 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 135 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
219 info("Probing for which registers that are read/write " 136 info("Probing for which registers that are read/write "
220 "for page 0x%x", page); 137 "for page 0x%x", page);
221 for (address = 0; address <= 0xff; address++) { 138 for (address = 0; address <= 0xff; address++) {
222 u8 old_val, ctrl_val, test_val = 0xff; 139 u8 old_val, ctrl_val, test_val = 0xff;
223 140
224 s5k83a_read_sensor(sd, address, &old_val, 1); 141 m5602_read_sensor(sd, address, &old_val, 1);
225 s5k83a_write_sensor(sd, address, &test_val, 1); 142 m5602_write_sensor(sd, address, &test_val, 1);
226 s5k83a_read_sensor(sd, address, &ctrl_val, 1); 143 m5602_read_sensor(sd, address, &ctrl_val, 1);
227 144
228 if (ctrl_val == test_val) 145 if (ctrl_val == test_val)
229 info("register 0x%x is writeable", address); 146 info("register 0x%x is writeable", address);
@@ -231,11 +148,11 @@ void s5k83a_dump_registers(struct sd *sd)
231 info("register 0x%x is read only", address); 148 info("register 0x%x is read only", address);
232 149
233 /* Restore original val */ 150 /* Restore original val */
234 s5k83a_write_sensor(sd, address, &old_val, 1); 151 m5602_write_sensor(sd, address, &old_val, 1);
235 } 152 }
236 } 153 }
237 info("Read/write register probing complete"); 154 info("Read/write register probing complete");
238 s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1); 155 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
239} 156}
240 157
241int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 158int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -244,11 +161,15 @@ int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
244 u8 data[2]; 161 u8 data[2];
245 struct sd *sd = (struct sd *) gspca_dev; 162 struct sd *sd = (struct sd *) gspca_dev;
246 163
247 err = s5k83a_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 164 err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
165 if (err < 0)
166 goto out;
167
248 data[1] = data[1] << 1; 168 data[1] = data[1] << 1;
249 *val = data[1]; 169 *val = data[1];
250 170
251 return (err < 0) ? err : 0; 171out:
172 return err;
252} 173}
253 174
254int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 175int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -259,23 +180,24 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
259 180
260 data[0] = 0x00; 181 data[0] = 0x00;
261 data[1] = 0x20; 182 data[1] = 0x20;
262 err = s5k83a_write_sensor(sd, 0x14, data, 2); 183 err = m5602_write_sensor(sd, 0x14, data, 2);
263 if (err < 0) 184 if (err < 0)
264 return err; 185 goto out;
265 186
266 data[0] = 0x01; 187 data[0] = 0x01;
267 data[1] = 0x00; 188 data[1] = 0x00;
268 err = s5k83a_write_sensor(sd, 0x0d, data, 2); 189 err = m5602_write_sensor(sd, 0x0d, data, 2);
269 if (err < 0) 190 if (err < 0)
270 return err; 191 goto out;
271 192
272 /* FIXME: This is not sane, we need to figure out the composition 193 /* FIXME: This is not sane, we need to figure out the composition
273 of these registers */ 194 of these registers */
274 data[0] = val >> 3; /* brightness, high 5 bits */ 195 data[0] = val >> 3; /* brightness, high 5 bits */
275 data[1] = val >> 1; /* brightness, high 7 bits */ 196 data[1] = val >> 1; /* brightness, high 7 bits */
276 err = s5k83a_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 197 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
277 198
278 return (err < 0) ? err : 0; 199out:
200 return err;
279} 201}
280 202
281int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) 203int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -284,10 +206,14 @@ int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
284 u8 data; 206 u8 data;
285 struct sd *sd = (struct sd *) gspca_dev; 207 struct sd *sd = (struct sd *) gspca_dev;
286 208
287 err = s5k83a_read_sensor(sd, S5K83A_WHITENESS, &data, 1); 209 err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1);
210 if (err < 0)
211 goto out;
288 212
289 *val = data; 213 *val = data;
290 return (err < 0) ? err : 0; 214
215out:
216 return err;
291} 217}
292 218
293int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) 219int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
@@ -297,9 +223,9 @@ int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val)
297 struct sd *sd = (struct sd *) gspca_dev; 223 struct sd *sd = (struct sd *) gspca_dev;
298 224
299 data[0] = val; 225 data[0] = val;
300 err = s5k83a_write_sensor(sd, S5K83A_WHITENESS, data, 1); 226 err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1);
301 227
302 return (err < 0) ? err : 0; 228 return err;
303} 229}
304 230
305int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 231int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -308,7 +234,9 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
308 u8 data[2]; 234 u8 data[2];
309 struct sd *sd = (struct sd *) gspca_dev; 235 struct sd *sd = (struct sd *) gspca_dev;
310 236
311 err = s5k83a_read_sensor(sd, S5K83A_GAIN, data, 2); 237 err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2);
238 if (err < 0)
239 goto out;
312 240
313 data[1] = data[1] & 0x3f; 241 data[1] = data[1] & 0x3f;
314 if (data[1] > S5K83A_MAXIMUM_GAIN) 242 if (data[1] > S5K83A_MAXIMUM_GAIN)
@@ -316,7 +244,8 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
316 244
317 *val = data[1]; 245 *val = data[1];
318 246
319 return (err < 0) ? err : 0; 247out:
248 return err;
320} 249}
321 250
322int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) 251int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -327,9 +256,8 @@ int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
327 256
328 data[0] = 0; 257 data[0] = 0;
329 data[1] = val; 258 data[1] = val;
330 err = s5k83a_write_sensor(sd, S5K83A_GAIN, data, 2); 259 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
331 260 return err;
332 return (err < 0) ? err : 0;
333} 261}
334 262
335int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 263int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -339,14 +267,15 @@ int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
339 struct sd *sd = (struct sd *) gspca_dev; 267 struct sd *sd = (struct sd *) gspca_dev;
340 268
341 data[0] = 0x05; 269 data[0] = 0x05;
342 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 270 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
343 if (err < 0) 271 if (err < 0)
344 return err; 272 goto out;
345 273
346 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 274 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
347 *val = (data[0] | 0x40) ? 1 : 0; 275 *val = (data[0] | 0x40) ? 1 : 0;
348 276
349 return (err < 0) ? err : 0; 277out:
278 return err;
350} 279}
351 280
352int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 281int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -356,25 +285,26 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
356 struct sd *sd = (struct sd *) gspca_dev; 285 struct sd *sd = (struct sd *) gspca_dev;
357 286
358 data[0] = 0x05; 287 data[0] = 0x05;
359 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 288 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
360 if (err < 0) 289 if (err < 0)
361 return err; 290 goto out;
362 291
363 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 292 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
364 if (err < 0) 293 if (err < 0)
365 return err; 294 goto out;
366 295
367 /* set or zero six bit, seven is hflip */ 296 /* set or zero six bit, seven is hflip */
368 data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK 297 data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
369 : (data[0] & 0x80) | S5K83A_FLIP_MASK; 298 : (data[0] & 0x80) | S5K83A_FLIP_MASK;
370 err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1); 299 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
371 if (err < 0) 300 if (err < 0)
372 return err; 301 goto out;
373 302
374 data[0] = (val) ? 0x0b : 0x0a; 303 data[0] = (val) ? 0x0b : 0x0a;
375 err = s5k83a_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); 304 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
376 305
377 return (err < 0) ? err : 0; 306out:
307 return err;
378} 308}
379 309
380int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 310int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -384,14 +314,15 @@ int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
384 struct sd *sd = (struct sd *) gspca_dev; 314 struct sd *sd = (struct sd *) gspca_dev;
385 315
386 data[0] = 0x05; 316 data[0] = 0x05;
387 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 317 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
388 if (err < 0) 318 if (err < 0)
389 return err; 319 goto out;
390 320
391 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 321 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
392 *val = (data[0] | 0x80) ? 1 : 0; 322 *val = (data[0] | 0x80) ? 1 : 0;
393 323
394 return (err < 0) ? err : 0; 324out:
325 return err;
395} 326}
396 327
397int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 328int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -401,23 +332,23 @@ int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
401 struct sd *sd = (struct sd *) gspca_dev; 332 struct sd *sd = (struct sd *) gspca_dev;
402 333
403 data[0] = 0x05; 334 data[0] = 0x05;
404 err = s5k83a_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 335 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
405 if (err < 0) 336 if (err < 0)
406 return err; 337 goto out;
407 338
408 err = s5k83a_read_sensor(sd, S5K83A_FLIP, data, 1); 339 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
409 if (err < 0) 340 if (err < 0)
410 return err; 341 goto out;
411 342
412 /* set or zero seven bit, six is vflip */ 343 /* set or zero seven bit, six is vflip */
413 data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK 344 data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
414 : (data[0] & 0x40) | S5K83A_FLIP_MASK; 345 : (data[0] & 0x40) | S5K83A_FLIP_MASK;
415 err = s5k83a_write_sensor(sd, S5K83A_FLIP, data, 1); 346 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
416 if (err < 0) 347 if (err < 0)
417 return err; 348 goto out;
418 349
419 data[0] = (val) ? 0x0a : 0x0b; 350 data[0] = (val) ? 0x0a : 0x0b;
420 err = s5k83a_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1); 351 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
421 352out:
422 return (err < 0) ? err : 0; 353 return err;
423} 354}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index ee3ee9cfca1d..05ccb5b57a88 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -22,15 +22,15 @@
22#include "m5602_sensor.h" 22#include "m5602_sensor.h"
23 23
24#define S5K83A_FLIP 0x01 24#define S5K83A_FLIP 0x01
25#define S5K83A_HFLIP_TUNE 0x03 25#define S5K83A_HFLIP_TUNE 0x03
26#define S5K83A_VFLIP_TUNE 0x05 26#define S5K83A_VFLIP_TUNE 0x05
27#define S5K83A_WHITENESS 0x0a 27#define S5K83A_WHITENESS 0x0a
28#define S5K83A_GAIN 0x18 28#define S5K83A_GAIN 0x18
29#define S5K83A_BRIGHTNESS 0x1b 29#define S5K83A_BRIGHTNESS 0x1b
30#define S5K83A_PAGE_MAP 0xec 30#define S5K83A_PAGE_MAP 0xec
31 31
32#define S5K83A_DEFAULT_BRIGHTNESS 0x71 32#define S5K83A_DEFAULT_BRIGHTNESS 0x71
33#define S5K83A_DEFAULT_WHITENESS 0x7e 33#define S5K83A_DEFAULT_WHITENESS 0x7e
34#define S5K83A_DEFAULT_GAIN 0x00 34#define S5K83A_DEFAULT_GAIN 0x00
35#define S5K83A_MAXIMUM_GAIN 0x3c 35#define S5K83A_MAXIMUM_GAIN 0x3c
36#define S5K83A_FLIP_MASK 0x10 36#define S5K83A_FLIP_MASK 0x10
@@ -46,13 +46,6 @@ int s5k83a_probe(struct sd *sd);
46int s5k83a_init(struct sd *sd); 46int s5k83a_init(struct sd *sd);
47int s5k83a_power_down(struct sd *sd); 47int s5k83a_power_down(struct sd *sd);
48 48
49void s5k83a_dump_registers(struct sd *sd);
50
51int s5k83a_read_sensor(struct sd *sd, const u8 address,
52 u8 *i2c_data, const u8 len);
53int s5k83a_write_sensor(struct sd *sd, const u8 address,
54 u8 *i2c_data, const u8 len);
55
56int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); 49int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
57int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); 50int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
58int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val); 51int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
@@ -64,15 +57,13 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
64int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 57int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
65int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); 58int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
66 59
67
68static struct m5602_sensor s5k83a = { 60static struct m5602_sensor s5k83a = {
69 .name = "S5K83A", 61 .name = "S5K83A",
70 .probe = s5k83a_probe, 62 .probe = s5k83a_probe,
71 .init = s5k83a_init, 63 .init = s5k83a_init,
72 .power_down = s5k83a_power_down, 64 .power_down = s5k83a_power_down,
73 .read_sensor = s5k83a_read_sensor,
74 .write_sensor = s5k83a_write_sensor,
75 .i2c_slave_id = 0x5a, 65 .i2c_slave_id = 0x5a,
66 .i2c_regW = 2,
76 .nctrls = 5, 67 .nctrls = 5,
77 .ctrls = { 68 .ctrls = {
78 { 69 {
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 60c9a48e0c02..261623f0da48 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -49,23 +49,21 @@ struct m5602_sensor {
49 /* What i2c address the sensor is connected to */ 49 /* What i2c address the sensor is connected to */
50 u8 i2c_slave_id; 50 u8 i2c_slave_id;
51 51
52 /* Width of each i2c register (in bytes) */
53 u8 i2c_regW;
54
52 /* Probes if the sensor is connected */ 55 /* Probes if the sensor is connected */
53 int (*probe)(struct sd *sd); 56 int (*probe)(struct sd *sd);
54 57
55 /* Performs a initialization sequence */ 58 /* Performs a initialization sequence */
56 int (*init)(struct sd *sd); 59 int (*init)(struct sd *sd);
57 60
61 /* Executed when the camera starts to send data */
62 int (*start)(struct sd *sd);
63
58 /* Performs a power down sequence */ 64 /* Performs a power down sequence */
59 int (*power_down)(struct sd *sd); 65 int (*power_down)(struct sd *sd);
60 66
61 /* Reads a sensor register */
62 int (*read_sensor)(struct sd *sd, const u8 address,
63 u8 *i2c_data, const u8 len);
64
65 /* Writes to a sensor register */
66 int (*write_sensor)(struct sd *sd, const u8 address,
67 u8 *i2c_data, const u8 len);
68
69 int nctrls; 67 int nctrls;
70 struct ctrl ctrls[M5602_MAX_CTRLS]; 68 struct ctrl ctrls[M5602_MAX_CTRLS];
71 69