diff options
Diffstat (limited to 'drivers/media/video/gspca/m5602')
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_bridge.h | 119 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_core.c | 100 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_mt9m111.c | 135 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_mt9m111.h | 14 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.c | 316 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.h | 195 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_po1030.c | 166 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_po1030.h | 10 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 235 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_s5k4aa.h | 47 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_s5k83a.c | 213 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_s5k83a.h | 25 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_sensor.h | 14 |
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 */ | ||
119 | struct sd { | 112 | struct sd { |
120 | struct gspca_dev gspca_dev; | 113 | struct gspca_dev gspca_dev; |
121 | 114 | ||
@@ -140,4 +133,10 @@ int m5602_read_bridge( | |||
140 | int m5602_write_bridge( | 133 | int m5602_write_bridge( |
141 | struct sd *sd, u8 address, u8 i2c_data); | 134 | struct sd *sd, u8 address, u8 i2c_data); |
142 | 135 | ||
136 | int m5602_write_sensor(struct sd *sd, const u8 address, | ||
137 | u8 *i2c_data, const u8 len); | ||
138 | |||
139 | int 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 */ |
26 | int force_sensor; | 26 | int force_sensor; |
27 | int dump_bridge; | 27 | static int dump_bridge; |
28 | int dump_sensor; | 28 | int dump_sensor; |
29 | 29 | ||
30 | static const __devinitdata struct usb_device_id m5602_table[] = { | 30 | static 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 | ||
83 | int 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 | } | ||
126 | out: | ||
127 | return err; | ||
128 | } | ||
129 | |||
130 | int 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 */ |
85 | static void m5602_dump_bridge(struct sd *sd) | 176 | static 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 | |||
287 | static void __exit mod_m5602_exit(void) | 383 | static 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 | ||
21 | static void mt9m111_dump_registers(struct sd *sd); | ||
22 | |||
21 | int mt9m111_probe(struct sd *sd) | 23 | int 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 | ||
115 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 117 | int 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); |
135 | out: | 137 | out: |
136 | return (err < 0) ? err : 0; | 138 | return err; |
137 | } | 139 | } |
138 | 140 | ||
139 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 141 | int 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 | ||
153 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 155 | int 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); |
173 | out: | 175 | out: |
174 | return (err < 0) ? err : 0; | 176 | return err; |
175 | } | 177 | } |
176 | 178 | ||
177 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 179 | int 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 | ||
196 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 198 | int 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); |
230 | out: | 232 | out: |
231 | return (err < 0) ? err : 0; | 233 | return err; |
232 | } | ||
233 | |||
234 | int 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 | } | ||
263 | out: | ||
264 | return (err < 0) ? err : 0; | ||
265 | } | ||
266 | |||
267 | int 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 | ||
311 | void mt9m111_dump_registers(struct sd *sd) | 236 | static 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); | |||
87 | int mt9m111_init(struct sd *sd); | 87 | int mt9m111_init(struct sd *sd); |
88 | int mt9m111_power_down(struct sd *sd); | 88 | int mt9m111_power_down(struct sd *sd); |
89 | 89 | ||
90 | int mt9m111_read_sensor(struct sd *sd, const u8 address, | ||
91 | u8 *i2c_data, const u8 len); | ||
92 | |||
93 | int mt9m111_write_sensor(struct sd *sd, const u8 address, | ||
94 | u8 *i2c_data, const u8 len); | ||
95 | |||
96 | void mt9m111_dump_registers(struct sd *sd); | ||
97 | |||
98 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 90 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); |
99 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | 91 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); |
100 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | 92 | int 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 | ||
21 | int 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 | { | 23 | static |
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", | |
49 | int 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; | 71 | static void ov9650_dump_registers(struct sd *sd); |
91 | } | ||
92 | 72 | ||
93 | int ov9650_probe(struct sd *sd) | 73 | int 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 | |||
145 | int 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 | ||
166 | int ov9650_power_down(struct sd *sd) | 201 | int 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 | ||
181 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 217 | int 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); |
203 | out: | 239 | out: |
204 | return (err < 0) ? err : 0; | 240 | return err; |
205 | } | 241 | } |
206 | 242 | ||
207 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 243 | int 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 | ||
234 | out: | 270 | out: |
235 | return (err < 0) ? err : 0; | 271 | return err; |
236 | } | 272 | } |
237 | 273 | ||
238 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 274 | int 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 | ||
253 | int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 289 | int 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 | ||
274 | int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 310 | int 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 | ||
288 | int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 324 | int 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 | ||
303 | int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 339 | int 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 | ||
317 | int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 353 | int 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 | ||
332 | int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 368 | int 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 | ||
348 | int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 384 | int 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); |
367 | out: | 403 | out: |
368 | return (err < 0) ? err : 0; | 404 | return err; |
369 | } | 405 | } |
370 | 406 | ||
371 | int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 407 | int 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 | ||
387 | int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 423 | int 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); |
406 | out: | 442 | out: |
407 | return (err < 0) ? err : 0; | 443 | return err; |
408 | } | 444 | } |
409 | 445 | ||
410 | int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 446 | int 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); |
424 | out: | 460 | out: |
425 | return (err < 0) ? err : 0; | 461 | return err; |
426 | } | 462 | } |
427 | 463 | ||
428 | int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 464 | int 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 | ||
452 | out: | 488 | out: |
453 | return (err < 0) ? err : 0; | 489 | return err; |
454 | } | 490 | } |
455 | 491 | ||
456 | int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) | 492 | int 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 | ||
469 | int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) | 505 | int 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); |
482 | out: | 518 | out: |
483 | return (err < 0) ? err : 0; | 519 | return err; |
484 | } | 520 | } |
485 | 521 | ||
486 | int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) | 522 | int 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 | ||
499 | int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | 535 | int 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); |
512 | out: | 548 | out: |
513 | return (err < 0) ? err : 0; | 549 | return err; |
514 | } | 550 | } |
515 | 551 | ||
516 | void ov9650_dump_registers(struct sd *sd) | 552 | static 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 | ||
125 | int ov9650_probe(struct sd *sd); | 129 | int ov9650_probe(struct sd *sd); |
126 | int ov9650_init(struct sd *sd); | 130 | int ov9650_init(struct sd *sd); |
131 | int ov9650_start(struct sd *sd); | ||
127 | int ov9650_power_down(struct sd *sd); | 132 | int ov9650_power_down(struct sd *sd); |
128 | 133 | ||
129 | int ov9650_read_sensor(struct sd *sd, const u8 address, | ||
130 | u8 *i2c_data, const u8 len); | ||
131 | int ov9650_write_sensor(struct sd *sd, const u8 address, | ||
132 | u8 *i2c_data, const u8 len); | ||
133 | |||
134 | void ov9650_dump_registers(struct sd *sd); | ||
135 | |||
136 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 134 | int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); |
137 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | 135 | int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); |
138 | int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | 136 | int 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); | |||
155 | static struct m5602_sensor ov9650 = { | 153 | static 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 | ||
446 | static const unsigned char power_down_ov9650[][3] = | 444 | static 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 | 464 | static const unsigned char res_init_ov9650[][2] = |
467 | where the sensor is mounted upside down */ | 465 | { |
468 | static | 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") | 473 | static 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."), | 493 | static 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 | |||
513 | static 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 | ||
21 | static void po1030_dump_registers(struct sd *sd); | ||
22 | |||
21 | int po1030_probe(struct sd *sd) | 23 | int 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 | ||
67 | int 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 | |||
91 | int 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 | |||
133 | int po1030_init(struct sd *sd) | 69 | int 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 | ||
172 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 102 | int 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); |
189 | out: | 119 | out: |
190 | return (err < 0) ? err : 0; | 120 | return err; |
191 | } | 121 | } |
192 | 122 | ||
193 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 123 | int 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 | ||
216 | out: | 146 | out: |
217 | return (err < 0) ? err : 0; | 147 | return err; |
218 | } | 148 | } |
219 | 149 | ||
220 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 150 | int 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 | ||
234 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 164 | int 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 | ||
250 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 180 | int 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; | 196 | out: |
197 | return err; | ||
264 | } | 198 | } |
265 | 199 | ||
266 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 200 | int 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 | ||
282 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 216 | int 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; | 232 | out: |
233 | return err; | ||
296 | } | 234 | } |
297 | 235 | ||
298 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 236 | int 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 | ||
311 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 249 | int 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 | ||
324 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 262 | int 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 | ||
337 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 275 | int 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 | ||
351 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 289 | int 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 | ||
364 | int po1030_power_down(struct sd *sd) | 302 | int 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 | ||
369 | void po1030_dump_registers(struct sd *sd) | 307 | static 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); | |||
128 | int po1030_init(struct sd *sd); | 128 | int po1030_init(struct sd *sd); |
129 | int po1030_power_down(struct sd *sd); | 129 | int po1030_power_down(struct sd *sd); |
130 | 130 | ||
131 | void po1030_dump_registers(struct sd *sd); | ||
132 | |||
133 | int po1030_read_sensor(struct sd *sd, const u8 address, | ||
134 | u8 *i2c_data, const u8 len); | ||
135 | int po1030_write_sensor(struct sd *sd, const u8 address, | ||
136 | u8 *i2c_data, const u8 len); | ||
137 | |||
138 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | 131 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); |
139 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 132 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); |
140 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val); | 133 | int 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 | ||
21 | static | ||
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 | |||
53 | static void s5k4aa_dump_registers(struct sd *sd); | ||
54 | |||
21 | int s5k4aa_probe(struct sd *sd) | 55 | int 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 | |||
78 | sensor_found: | 113 | sensor_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 | ||
87 | int 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 | } | ||
123 | out: | ||
124 | return (err < 0) ? err : 0; | ||
125 | } | ||
126 | |||
127 | int 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 | |||
171 | int s5k4aa_init(struct sd *sd) | 122 | int 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); |
252 | out: | 203 | out: |
253 | return (err < 0) ? err : 0; | 204 | return err; |
254 | } | 205 | } |
255 | 206 | ||
256 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 207 | int 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); |
272 | out: | 223 | out: |
273 | return (err < 0) ? err : 0; | 224 | return err; |
274 | } | 225 | } |
275 | 226 | ||
276 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 227 | int 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 | ||
290 | out: | 241 | out: |
291 | return (err < 0) ? err : 0; | 242 | return err; |
292 | } | 243 | } |
293 | 244 | ||
294 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 245 | int 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 | } |
328 | out: | 279 | out: |
329 | return (err < 0) ? err : 0; | 280 | return err; |
330 | } | 281 | } |
331 | 282 | ||
332 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 283 | int 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); |
345 | out: | 296 | out: |
346 | return (err < 0) ? err : 0; | 297 | return err; |
347 | } | 298 | } |
348 | 299 | ||
349 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 300 | int 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 | } |
384 | out: | 335 | out: |
385 | return (err < 0) ? err : 0; | 336 | return err; |
386 | } | 337 | } |
387 | 338 | ||
388 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 339 | int 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 | ||
402 | out: | 353 | out: |
403 | return (err < 0) ? err : 0; | 354 | return err; |
404 | } | 355 | } |
405 | 356 | ||
406 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 357 | int 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 | ||
420 | out: | 371 | out: |
421 | return (err < 0) ? err : 0; | 372 | return err; |
422 | } | 373 | } |
423 | 374 | ||
424 | void s5k4aa_dump_registers(struct sd *sd) | 375 | static 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); | |||
68 | int s5k4aa_init(struct sd *sd); | 67 | int s5k4aa_init(struct sd *sd); |
69 | int s5k4aa_power_down(struct sd *sd); | 68 | int s5k4aa_power_down(struct sd *sd); |
70 | 69 | ||
71 | void s5k4aa_dump_registers(struct sd *sd); | ||
72 | |||
73 | int s5k4aa_read_sensor(struct sd *sd, const u8 address, | ||
74 | u8 *i2c_data, const u8 len); | ||
75 | int s5k4aa_write_sensor(struct sd *sd, const u8 address, | ||
76 | u8 *i2c_data, const u8 len); | ||
77 | |||
78 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | 70 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); |
79 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 71 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val); |
80 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | 72 | int 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 | ||
341 | static | ||
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 | ||
21 | static void s5k83a_dump_registers(struct sd *sd); | ||
22 | |||
21 | int s5k83a_probe(struct sd *sd) | 23 | int 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 | ||
71 | int 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 | |||
108 | out: | ||
109 | return (err < 0) ? err : 0; | ||
110 | } | ||
111 | |||
112 | int 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 | |||
156 | int s5k83a_init(struct sd *sd) | 73 | int 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 | ||
241 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) | 158 | int 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; | 171 | out: |
172 | return err; | ||
252 | } | 173 | } |
253 | 174 | ||
254 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) | 175 | int 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; | 199 | out: |
200 | return err; | ||
279 | } | 201 | } |
280 | 202 | ||
281 | int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) | 203 | int 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 | |
215 | out: | ||
216 | return err; | ||
291 | } | 217 | } |
292 | 218 | ||
293 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) | 219 | int 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 | ||
305 | int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 231 | int 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; | 247 | out: |
248 | return err; | ||
320 | } | 249 | } |
321 | 250 | ||
322 | int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 251 | int 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 | ||
335 | int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 263 | int 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; | 277 | out: |
278 | return err; | ||
350 | } | 279 | } |
351 | 280 | ||
352 | int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 281 | int 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; | 306 | out: |
307 | return err; | ||
378 | } | 308 | } |
379 | 309 | ||
380 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 310 | int 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; | 324 | out: |
325 | return err; | ||
395 | } | 326 | } |
396 | 327 | ||
397 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 328 | int 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 | 352 | out: | |
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); | |||
46 | int s5k83a_init(struct sd *sd); | 46 | int s5k83a_init(struct sd *sd); |
47 | int s5k83a_power_down(struct sd *sd); | 47 | int s5k83a_power_down(struct sd *sd); |
48 | 48 | ||
49 | void s5k83a_dump_registers(struct sd *sd); | ||
50 | |||
51 | int s5k83a_read_sensor(struct sd *sd, const u8 address, | ||
52 | u8 *i2c_data, const u8 len); | ||
53 | int s5k83a_write_sensor(struct sd *sd, const u8 address, | ||
54 | u8 *i2c_data, const u8 len); | ||
55 | |||
56 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); | 49 | int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val); |
57 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); | 50 | int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); |
58 | int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val); | 51 | int 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); | |||
64 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | 57 | int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); |
65 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | 58 | int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val); |
66 | 59 | ||
67 | |||
68 | static struct m5602_sensor s5k83a = { | 60 | static 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 | ||