diff options
author | Erik Andr?n <erik.andren@gmail.com> | 2009-01-04 14:52:48 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 17:20:23 -0400 |
commit | 04f15655f6cd99ba7d7c9ef8f969a71061a1fbac (patch) | |
tree | 9b9729f9910119ddb9c738cc8401bae1859ce8fb /drivers/media/video/gspca | |
parent | 881cd41882fa5762e3f831dd997368fef5257274 (diff) |
V4L/DVB (11450): gspca - m5602-mt9m111: Convert the mt9m111 to use a v4l2 ctrl cache
Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_mt9m111.c | 65 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_mt9m111.h | 4 |
2 files changed, 43 insertions, 26 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 7d3f9e348ef4..43791a6b8d2a 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c | |||
@@ -32,6 +32,7 @@ static struct v4l2_pix_format mt9m111_modes[] = { | |||
32 | }; | 32 | }; |
33 | 33 | ||
34 | const static struct ctrl mt9m111_ctrls[] = { | 34 | const static struct ctrl mt9m111_ctrls[] = { |
35 | #define VFLIP_IDX 0 | ||
35 | { | 36 | { |
36 | { | 37 | { |
37 | .id = V4L2_CID_VFLIP, | 38 | .id = V4L2_CID_VFLIP, |
@@ -44,7 +45,9 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
44 | }, | 45 | }, |
45 | .set = mt9m111_set_vflip, | 46 | .set = mt9m111_set_vflip, |
46 | .get = mt9m111_get_vflip | 47 | .get = mt9m111_get_vflip |
47 | }, { | 48 | }, |
49 | #define HFLIP_IDX 1 | ||
50 | { | ||
48 | { | 51 | { |
49 | .id = V4L2_CID_HFLIP, | 52 | .id = V4L2_CID_HFLIP, |
50 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 53 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -56,7 +59,9 @@ const static struct ctrl mt9m111_ctrls[] = { | |||
56 | }, | 59 | }, |
57 | .set = mt9m111_set_hflip, | 60 | .set = mt9m111_set_hflip, |
58 | .get = mt9m111_get_hflip | 61 | .get = mt9m111_get_hflip |
59 | }, { | 62 | }, |
63 | #define GAIN_IDX 2 | ||
64 | { | ||
60 | { | 65 | { |
61 | .id = V4L2_CID_GAIN, | 66 | .id = V4L2_CID_GAIN, |
62 | .type = V4L2_CTRL_TYPE_INTEGER, | 67 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -79,6 +84,7 @@ int mt9m111_probe(struct sd *sd) | |||
79 | { | 84 | { |
80 | u8 data[2] = {0x00, 0x00}; | 85 | u8 data[2] = {0x00, 0x00}; |
81 | int i; | 86 | int i; |
87 | s32 *sensor_settings; | ||
82 | 88 | ||
83 | if (force_sensor) { | 89 | if (force_sensor) { |
84 | if (force_sensor == MT9M111_SENSOR) { | 90 | if (force_sensor == MT9M111_SENSOR) { |
@@ -117,10 +123,19 @@ int mt9m111_probe(struct sd *sd) | |||
117 | return -ENODEV; | 123 | return -ENODEV; |
118 | 124 | ||
119 | sensor_found: | 125 | sensor_found: |
126 | sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), GFP_KERNEL); | ||
127 | if (!sensor_settings) | ||
128 | return -ENOMEM; | ||
129 | |||
120 | sd->gspca_dev.cam.cam_mode = mt9m111_modes; | 130 | sd->gspca_dev.cam.cam_mode = mt9m111_modes; |
121 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); | 131 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); |
122 | sd->desc->ctrls = mt9m111_ctrls; | 132 | sd->desc->ctrls = mt9m111_ctrls; |
123 | sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); | 133 | sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); |
134 | |||
135 | for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++) | ||
136 | sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value; | ||
137 | sd->sensor_priv = sensor_settings; | ||
138 | |||
124 | return 0; | 139 | return 0; |
125 | } | 140 | } |
126 | 141 | ||
@@ -155,18 +170,21 @@ int mt9m111_power_down(struct sd *sd) | |||
155 | return 0; | 170 | return 0; |
156 | } | 171 | } |
157 | 172 | ||
173 | void mt9m111_disconnect(struct sd *sd) | ||
174 | { | ||
175 | sd->sensor = NULL; | ||
176 | kfree(sd->sensor_priv); | ||
177 | } | ||
178 | |||
158 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 179 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
159 | { | 180 | { |
160 | int err; | ||
161 | u8 data[2] = {0x00, 0x00}; | ||
162 | struct sd *sd = (struct sd *) gspca_dev; | 181 | struct sd *sd = (struct sd *) gspca_dev; |
182 | s32 *sensor_settings = sd->sensor_priv; | ||
163 | 183 | ||
164 | err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 184 | *val = sensor_settings[VFLIP_IDX]; |
165 | data, 2); | ||
166 | *val = data[0] & MT9M111_RMB_MIRROR_ROWS; | ||
167 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 185 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
168 | 186 | ||
169 | return err; | 187 | return 0; |
170 | } | 188 | } |
171 | 189 | ||
172 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 190 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
@@ -174,9 +192,12 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
174 | int err; | 192 | int err; |
175 | u8 data[2] = {0x00, 0x00}; | 193 | u8 data[2] = {0x00, 0x00}; |
176 | struct sd *sd = (struct sd *) gspca_dev; | 194 | struct sd *sd = (struct sd *) gspca_dev; |
195 | s32 *sensor_settings = sd->sensor_priv; | ||
177 | 196 | ||
178 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 197 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
179 | 198 | ||
199 | sensor_settings[VFLIP_IDX] = val; | ||
200 | |||
180 | /* Set the correct page map */ | 201 | /* Set the correct page map */ |
181 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 202 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
182 | if (err < 0) | 203 | if (err < 0) |
@@ -194,16 +215,13 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
194 | 215 | ||
195 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 216 | int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
196 | { | 217 | { |
197 | int err; | ||
198 | u8 data[2] = {0x00, 0x00}; | ||
199 | struct sd *sd = (struct sd *) gspca_dev; | 218 | struct sd *sd = (struct sd *) gspca_dev; |
219 | s32 *sensor_settings = sd->sensor_priv; | ||
200 | 220 | ||
201 | err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, | 221 | *val = sensor_settings[HFLIP_IDX]; |
202 | data, 2); | ||
203 | *val = data[0] & MT9M111_RMB_MIRROR_COLS; | ||
204 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 222 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
205 | 223 | ||
206 | return err; | 224 | return 0; |
207 | } | 225 | } |
208 | 226 | ||
209 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 227 | int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
@@ -211,9 +229,11 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
211 | int err; | 229 | int err; |
212 | u8 data[2] = {0x00, 0x00}; | 230 | u8 data[2] = {0x00, 0x00}; |
213 | struct sd *sd = (struct sd *) gspca_dev; | 231 | struct sd *sd = (struct sd *) gspca_dev; |
232 | s32 *sensor_settings = sd->sensor_priv; | ||
214 | 233 | ||
215 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | 234 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); |
216 | 235 | ||
236 | sensor_settings[HFLIP_IDX] = val; | ||
217 | /* Set the correct page map */ | 237 | /* Set the correct page map */ |
218 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 238 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
219 | if (err < 0) | 239 | if (err < 0) |
@@ -231,21 +251,13 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
231 | 251 | ||
232 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 252 | int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
233 | { | 253 | { |
234 | int err, tmp; | ||
235 | u8 data[2] = {0x00, 0x00}; | ||
236 | struct sd *sd = (struct sd *) gspca_dev; | 254 | struct sd *sd = (struct sd *) gspca_dev; |
255 | s32 *sensor_settings = sd->sensor_priv; | ||
237 | 256 | ||
238 | err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); | 257 | *val = sensor_settings[GAIN_IDX]; |
239 | tmp = ((data[1] << 8) | data[0]); | ||
240 | |||
241 | *val = ((tmp & (1 << 10)) * 2) | | ||
242 | ((tmp & (1 << 9)) * 2) | | ||
243 | ((tmp & (1 << 8)) * 2) | | ||
244 | (tmp & 0x7f); | ||
245 | |||
246 | PDEBUG(D_V4L2, "Read gain %d", *val); | 258 | PDEBUG(D_V4L2, "Read gain %d", *val); |
247 | 259 | ||
248 | return err; | 260 | return 0; |
249 | } | 261 | } |
250 | 262 | ||
251 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 263 | int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
@@ -253,6 +265,9 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
253 | int err, tmp; | 265 | int err, tmp; |
254 | u8 data[2] = {0x00, 0x00}; | 266 | u8 data[2] = {0x00, 0x00}; |
255 | struct sd *sd = (struct sd *) gspca_dev; | 267 | struct sd *sd = (struct sd *) gspca_dev; |
268 | s32 *sensor_settings = sd->sensor_priv; | ||
269 | |||
270 | sensor_settings[GAIN_IDX] = val; | ||
256 | 271 | ||
257 | /* Set the correct page map */ | 272 | /* Set the correct page map */ |
258 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); | 273 | err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); |
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h index 00c6db02bdb7..03769fc04427 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h | |||
@@ -86,6 +86,7 @@ extern int dump_sensor; | |||
86 | int mt9m111_probe(struct sd *sd); | 86 | 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 | void mt9m111_disconnect(struct sd *sd); | ||
89 | 90 | ||
90 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 91 | int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); |
91 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | 92 | int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); |
@@ -102,7 +103,8 @@ const static struct m5602_sensor mt9m111 = { | |||
102 | 103 | ||
103 | .probe = mt9m111_probe, | 104 | .probe = mt9m111_probe, |
104 | .init = mt9m111_init, | 105 | .init = mt9m111_init, |
105 | .power_down = mt9m111_power_down | 106 | .power_down = mt9m111_power_down, |
107 | .disconnect = mt9m111_disconnect, | ||
106 | }; | 108 | }; |
107 | 109 | ||
108 | static const unsigned char preinit_mt9m111[][4] = | 110 | static const unsigned char preinit_mt9m111[][4] = |