diff options
Diffstat (limited to 'drivers/media/video/mt9v022.c')
-rw-r--r-- | drivers/media/video/mt9v022.c | 138 |
1 files changed, 73 insertions, 65 deletions
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 4d3b4813c322..be20d312b1dc 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -91,51 +91,49 @@ struct mt9v022 { | |||
91 | u16 chip_control; | 91 | u16 chip_control; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static int reg_read(struct soc_camera_device *icd, const u8 reg) | 94 | static int reg_read(struct i2c_client *client, const u8 reg) |
95 | { | 95 | { |
96 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | ||
97 | struct i2c_client *client = mt9v022->client; | ||
98 | s32 data = i2c_smbus_read_word_data(client, reg); | 96 | s32 data = i2c_smbus_read_word_data(client, reg); |
99 | return data < 0 ? data : swab16(data); | 97 | return data < 0 ? data : swab16(data); |
100 | } | 98 | } |
101 | 99 | ||
102 | static int reg_write(struct soc_camera_device *icd, const u8 reg, | 100 | static int reg_write(struct i2c_client *client, const u8 reg, |
103 | const u16 data) | 101 | const u16 data) |
104 | { | 102 | { |
105 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 103 | return i2c_smbus_write_word_data(client, reg, swab16(data)); |
106 | return i2c_smbus_write_word_data(mt9v022->client, reg, swab16(data)); | ||
107 | } | 104 | } |
108 | 105 | ||
109 | static int reg_set(struct soc_camera_device *icd, const u8 reg, | 106 | static int reg_set(struct i2c_client *client, const u8 reg, |
110 | const u16 data) | 107 | const u16 data) |
111 | { | 108 | { |
112 | int ret; | 109 | int ret; |
113 | 110 | ||
114 | ret = reg_read(icd, reg); | 111 | ret = reg_read(client, reg); |
115 | if (ret < 0) | 112 | if (ret < 0) |
116 | return ret; | 113 | return ret; |
117 | return reg_write(icd, reg, ret | data); | 114 | return reg_write(client, reg, ret | data); |
118 | } | 115 | } |
119 | 116 | ||
120 | static int reg_clear(struct soc_camera_device *icd, const u8 reg, | 117 | static int reg_clear(struct i2c_client *client, const u8 reg, |
121 | const u16 data) | 118 | const u16 data) |
122 | { | 119 | { |
123 | int ret; | 120 | int ret; |
124 | 121 | ||
125 | ret = reg_read(icd, reg); | 122 | ret = reg_read(client, reg); |
126 | if (ret < 0) | 123 | if (ret < 0) |
127 | return ret; | 124 | return ret; |
128 | return reg_write(icd, reg, ret & ~data); | 125 | return reg_write(client, reg, ret & ~data); |
129 | } | 126 | } |
130 | 127 | ||
131 | static int mt9v022_init(struct soc_camera_device *icd) | 128 | static int mt9v022_init(struct soc_camera_device *icd) |
132 | { | 129 | { |
130 | struct i2c_client *client = to_i2c_client(icd->control); | ||
133 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 131 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
134 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | 132 | struct soc_camera_link *icl = client->dev.platform_data; |
135 | int ret; | 133 | int ret; |
136 | 134 | ||
137 | if (icl->power) { | 135 | if (icl->power) { |
138 | ret = icl->power(&mt9v022->client->dev, 1); | 136 | ret = icl->power(&client->dev, 1); |
139 | if (ret < 0) { | 137 | if (ret < 0) { |
140 | dev_err(icd->vdev->parent, | 138 | dev_err(icd->vdev->parent, |
141 | "Platform failed to power-on the camera.\n"); | 139 | "Platform failed to power-on the camera.\n"); |
@@ -148,27 +146,27 @@ static int mt9v022_init(struct soc_camera_device *icd) | |||
148 | * if available. Soft reset is done in video_probe(). | 146 | * if available. Soft reset is done in video_probe(). |
149 | */ | 147 | */ |
150 | if (icl->reset) | 148 | if (icl->reset) |
151 | icl->reset(&mt9v022->client->dev); | 149 | icl->reset(&client->dev); |
152 | 150 | ||
153 | /* Almost the default mode: master, parallel, simultaneous, and an | 151 | /* Almost the default mode: master, parallel, simultaneous, and an |
154 | * undocumented bit 0x200, which is present in table 7, but not in 8, | 152 | * undocumented bit 0x200, which is present in table 7, but not in 8, |
155 | * plus snapshot mode to disable scan for now */ | 153 | * plus snapshot mode to disable scan for now */ |
156 | mt9v022->chip_control |= 0x10; | 154 | mt9v022->chip_control |= 0x10; |
157 | ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); | 155 | ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); |
158 | if (!ret) | 156 | if (!ret) |
159 | ret = reg_write(icd, MT9V022_READ_MODE, 0x300); | 157 | ret = reg_write(client, MT9V022_READ_MODE, 0x300); |
160 | 158 | ||
161 | /* All defaults */ | 159 | /* All defaults */ |
162 | if (!ret) | 160 | if (!ret) |
163 | /* AEC, AGC on */ | 161 | /* AEC, AGC on */ |
164 | ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); | 162 | ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3); |
165 | if (!ret) | 163 | if (!ret) |
166 | ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); | 164 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); |
167 | if (!ret) | 165 | if (!ret) |
168 | /* default - auto */ | 166 | /* default - auto */ |
169 | ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); | 167 | ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); |
170 | if (!ret) | 168 | if (!ret) |
171 | ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); | 169 | ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0); |
172 | 170 | ||
173 | return ret; | 171 | return ret; |
174 | } | 172 | } |
@@ -186,10 +184,11 @@ static int mt9v022_release(struct soc_camera_device *icd) | |||
186 | 184 | ||
187 | static int mt9v022_start_capture(struct soc_camera_device *icd) | 185 | static int mt9v022_start_capture(struct soc_camera_device *icd) |
188 | { | 186 | { |
187 | struct i2c_client *client = to_i2c_client(icd->control); | ||
189 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 188 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
190 | /* Switch to master "normal" mode */ | 189 | /* Switch to master "normal" mode */ |
191 | mt9v022->chip_control &= ~0x10; | 190 | mt9v022->chip_control &= ~0x10; |
192 | if (reg_write(icd, MT9V022_CHIP_CONTROL, | 191 | if (reg_write(client, MT9V022_CHIP_CONTROL, |
193 | mt9v022->chip_control) < 0) | 192 | mt9v022->chip_control) < 0) |
194 | return -EIO; | 193 | return -EIO; |
195 | return 0; | 194 | return 0; |
@@ -197,10 +196,11 @@ static int mt9v022_start_capture(struct soc_camera_device *icd) | |||
197 | 196 | ||
198 | static int mt9v022_stop_capture(struct soc_camera_device *icd) | 197 | static int mt9v022_stop_capture(struct soc_camera_device *icd) |
199 | { | 198 | { |
199 | struct i2c_client *client = to_i2c_client(icd->control); | ||
200 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 200 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
201 | /* Switch to snapshot mode */ | 201 | /* Switch to snapshot mode */ |
202 | mt9v022->chip_control |= 0x10; | 202 | mt9v022->chip_control |= 0x10; |
203 | if (reg_write(icd, MT9V022_CHIP_CONTROL, | 203 | if (reg_write(client, MT9V022_CHIP_CONTROL, |
204 | mt9v022->chip_control) < 0) | 204 | mt9v022->chip_control) < 0) |
205 | return -EIO; | 205 | return -EIO; |
206 | return 0; | 206 | return 0; |
@@ -209,8 +209,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd) | |||
209 | static int mt9v022_set_bus_param(struct soc_camera_device *icd, | 209 | static int mt9v022_set_bus_param(struct soc_camera_device *icd, |
210 | unsigned long flags) | 210 | unsigned long flags) |
211 | { | 211 | { |
212 | struct i2c_client *client = to_i2c_client(icd->control); | ||
212 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 213 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
213 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | 214 | struct soc_camera_link *icl = client->dev.platform_data; |
214 | unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; | 215 | unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; |
215 | int ret; | 216 | int ret; |
216 | u16 pixclk = 0; | 217 | u16 pixclk = 0; |
@@ -243,14 +244,14 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd, | |||
243 | if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH)) | 244 | if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH)) |
244 | pixclk |= 0x2; | 245 | pixclk |= 0x2; |
245 | 246 | ||
246 | ret = reg_write(icd, MT9V022_PIXCLK_FV_LV, pixclk); | 247 | ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk); |
247 | if (ret < 0) | 248 | if (ret < 0) |
248 | return ret; | 249 | return ret; |
249 | 250 | ||
250 | if (!(flags & SOCAM_MASTER)) | 251 | if (!(flags & SOCAM_MASTER)) |
251 | mt9v022->chip_control &= ~0x8; | 252 | mt9v022->chip_control &= ~0x8; |
252 | 253 | ||
253 | ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); | 254 | ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); |
254 | if (ret < 0) | 255 | if (ret < 0) |
255 | return ret; | 256 | return ret; |
256 | 257 | ||
@@ -282,35 +283,36 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) | |||
282 | static int mt9v022_set_crop(struct soc_camera_device *icd, | 283 | static int mt9v022_set_crop(struct soc_camera_device *icd, |
283 | struct v4l2_rect *rect) | 284 | struct v4l2_rect *rect) |
284 | { | 285 | { |
286 | struct i2c_client *client = to_i2c_client(icd->control); | ||
285 | int ret; | 287 | int ret; |
286 | 288 | ||
287 | /* Like in example app. Contradicts the datasheet though */ | 289 | /* Like in example app. Contradicts the datasheet though */ |
288 | ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | 290 | ret = reg_read(client, MT9V022_AEC_AGC_ENABLE); |
289 | if (ret >= 0) { | 291 | if (ret >= 0) { |
290 | if (ret & 1) /* Autoexposure */ | 292 | if (ret & 1) /* Autoexposure */ |
291 | ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, | 293 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, |
292 | rect->height + icd->y_skip_top + 43); | 294 | rect->height + icd->y_skip_top + 43); |
293 | else | 295 | else |
294 | ret = reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, | 296 | ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, |
295 | rect->height + icd->y_skip_top + 43); | 297 | rect->height + icd->y_skip_top + 43); |
296 | } | 298 | } |
297 | /* Setup frame format: defaults apart from width and height */ | 299 | /* Setup frame format: defaults apart from width and height */ |
298 | if (!ret) | 300 | if (!ret) |
299 | ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); | 301 | ret = reg_write(client, MT9V022_COLUMN_START, rect->left); |
300 | if (!ret) | 302 | if (!ret) |
301 | ret = reg_write(icd, MT9V022_ROW_START, rect->top); | 303 | ret = reg_write(client, MT9V022_ROW_START, rect->top); |
302 | if (!ret) | 304 | if (!ret) |
303 | /* Default 94, Phytec driver says: | 305 | /* Default 94, Phytec driver says: |
304 | * "width + horizontal blank >= 660" */ | 306 | * "width + horizontal blank >= 660" */ |
305 | ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, | 307 | ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, |
306 | rect->width > 660 - 43 ? 43 : | 308 | rect->width > 660 - 43 ? 43 : |
307 | 660 - rect->width); | 309 | 660 - rect->width); |
308 | if (!ret) | 310 | if (!ret) |
309 | ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); | 311 | ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45); |
310 | if (!ret) | 312 | if (!ret) |
311 | ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); | 313 | ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width); |
312 | if (!ret) | 314 | if (!ret) |
313 | ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, | 315 | ret = reg_write(client, MT9V022_WINDOW_HEIGHT, |
314 | rect->height + icd->y_skip_top); | 316 | rect->height + icd->y_skip_top); |
315 | 317 | ||
316 | if (ret < 0) | 318 | if (ret < 0) |
@@ -396,16 +398,16 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd, | |||
396 | static int mt9v022_get_register(struct soc_camera_device *icd, | 398 | static int mt9v022_get_register(struct soc_camera_device *icd, |
397 | struct v4l2_dbg_register *reg) | 399 | struct v4l2_dbg_register *reg) |
398 | { | 400 | { |
399 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 401 | struct i2c_client *client = to_i2c_client(icd->control); |
400 | 402 | ||
401 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 403 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
402 | return -EINVAL; | 404 | return -EINVAL; |
403 | 405 | ||
404 | if (reg->match.addr != mt9v022->client->addr) | 406 | if (reg->match.addr != client->addr) |
405 | return -ENODEV; | 407 | return -ENODEV; |
406 | 408 | ||
407 | reg->size = 2; | 409 | reg->size = 2; |
408 | reg->val = reg_read(icd, reg->reg); | 410 | reg->val = reg_read(client, reg->reg); |
409 | 411 | ||
410 | if (reg->val > 0xffff) | 412 | if (reg->val > 0xffff) |
411 | return -EIO; | 413 | return -EIO; |
@@ -416,15 +418,15 @@ static int mt9v022_get_register(struct soc_camera_device *icd, | |||
416 | static int mt9v022_set_register(struct soc_camera_device *icd, | 418 | static int mt9v022_set_register(struct soc_camera_device *icd, |
417 | struct v4l2_dbg_register *reg) | 419 | struct v4l2_dbg_register *reg) |
418 | { | 420 | { |
419 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 421 | struct i2c_client *client = to_i2c_client(icd->control); |
420 | 422 | ||
421 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 423 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
422 | return -EINVAL; | 424 | return -EINVAL; |
423 | 425 | ||
424 | if (reg->match.addr != mt9v022->client->addr) | 426 | if (reg->match.addr != client->addr) |
425 | return -ENODEV; | 427 | return -ENODEV; |
426 | 428 | ||
427 | if (reg_write(icd, reg->reg, reg->val) < 0) | 429 | if (reg_write(client, reg->reg, reg->val) < 0) |
428 | return -EIO; | 430 | return -EIO; |
429 | 431 | ||
430 | return 0; | 432 | return 0; |
@@ -517,29 +519,30 @@ static struct soc_camera_ops mt9v022_ops = { | |||
517 | static int mt9v022_get_control(struct soc_camera_device *icd, | 519 | static int mt9v022_get_control(struct soc_camera_device *icd, |
518 | struct v4l2_control *ctrl) | 520 | struct v4l2_control *ctrl) |
519 | { | 521 | { |
522 | struct i2c_client *client = to_i2c_client(icd->control); | ||
520 | int data; | 523 | int data; |
521 | 524 | ||
522 | switch (ctrl->id) { | 525 | switch (ctrl->id) { |
523 | case V4L2_CID_VFLIP: | 526 | case V4L2_CID_VFLIP: |
524 | data = reg_read(icd, MT9V022_READ_MODE); | 527 | data = reg_read(client, MT9V022_READ_MODE); |
525 | if (data < 0) | 528 | if (data < 0) |
526 | return -EIO; | 529 | return -EIO; |
527 | ctrl->value = !!(data & 0x10); | 530 | ctrl->value = !!(data & 0x10); |
528 | break; | 531 | break; |
529 | case V4L2_CID_HFLIP: | 532 | case V4L2_CID_HFLIP: |
530 | data = reg_read(icd, MT9V022_READ_MODE); | 533 | data = reg_read(client, MT9V022_READ_MODE); |
531 | if (data < 0) | 534 | if (data < 0) |
532 | return -EIO; | 535 | return -EIO; |
533 | ctrl->value = !!(data & 0x20); | 536 | ctrl->value = !!(data & 0x20); |
534 | break; | 537 | break; |
535 | case V4L2_CID_EXPOSURE_AUTO: | 538 | case V4L2_CID_EXPOSURE_AUTO: |
536 | data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | 539 | data = reg_read(client, MT9V022_AEC_AGC_ENABLE); |
537 | if (data < 0) | 540 | if (data < 0) |
538 | return -EIO; | 541 | return -EIO; |
539 | ctrl->value = !!(data & 0x1); | 542 | ctrl->value = !!(data & 0x1); |
540 | break; | 543 | break; |
541 | case V4L2_CID_AUTOGAIN: | 544 | case V4L2_CID_AUTOGAIN: |
542 | data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); | 545 | data = reg_read(client, MT9V022_AEC_AGC_ENABLE); |
543 | if (data < 0) | 546 | if (data < 0) |
544 | return -EIO; | 547 | return -EIO; |
545 | ctrl->value = !!(data & 0x2); | 548 | ctrl->value = !!(data & 0x2); |
@@ -552,6 +555,7 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
552 | struct v4l2_control *ctrl) | 555 | struct v4l2_control *ctrl) |
553 | { | 556 | { |
554 | int data; | 557 | int data; |
558 | struct i2c_client *client = to_i2c_client(icd->control); | ||
555 | const struct v4l2_queryctrl *qctrl; | 559 | const struct v4l2_queryctrl *qctrl; |
556 | 560 | ||
557 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); | 561 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); |
@@ -562,17 +566,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
562 | switch (ctrl->id) { | 566 | switch (ctrl->id) { |
563 | case V4L2_CID_VFLIP: | 567 | case V4L2_CID_VFLIP: |
564 | if (ctrl->value) | 568 | if (ctrl->value) |
565 | data = reg_set(icd, MT9V022_READ_MODE, 0x10); | 569 | data = reg_set(client, MT9V022_READ_MODE, 0x10); |
566 | else | 570 | else |
567 | data = reg_clear(icd, MT9V022_READ_MODE, 0x10); | 571 | data = reg_clear(client, MT9V022_READ_MODE, 0x10); |
568 | if (data < 0) | 572 | if (data < 0) |
569 | return -EIO; | 573 | return -EIO; |
570 | break; | 574 | break; |
571 | case V4L2_CID_HFLIP: | 575 | case V4L2_CID_HFLIP: |
572 | if (ctrl->value) | 576 | if (ctrl->value) |
573 | data = reg_set(icd, MT9V022_READ_MODE, 0x20); | 577 | data = reg_set(client, MT9V022_READ_MODE, 0x20); |
574 | else | 578 | else |
575 | data = reg_clear(icd, MT9V022_READ_MODE, 0x20); | 579 | data = reg_clear(client, MT9V022_READ_MODE, 0x20); |
576 | if (data < 0) | 580 | if (data < 0) |
577 | return -EIO; | 581 | return -EIO; |
578 | break; | 582 | break; |
@@ -593,12 +597,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
593 | /* The user wants to set gain manually, hope, she | 597 | /* The user wants to set gain manually, hope, she |
594 | * knows, what she's doing... Switch AGC off. */ | 598 | * knows, what she's doing... Switch AGC off. */ |
595 | 599 | ||
596 | if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) | 600 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) |
597 | return -EIO; | 601 | return -EIO; |
598 | 602 | ||
599 | dev_info(&icd->dev, "Setting gain from %d to %lu\n", | 603 | dev_info(&icd->dev, "Setting gain from %d to %lu\n", |
600 | reg_read(icd, MT9V022_ANALOG_GAIN), gain); | 604 | reg_read(client, MT9V022_ANALOG_GAIN), gain); |
601 | if (reg_write(icd, MT9V022_ANALOG_GAIN, gain) < 0) | 605 | if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) |
602 | return -EIO; | 606 | return -EIO; |
603 | icd->gain = ctrl->value; | 607 | icd->gain = ctrl->value; |
604 | } | 608 | } |
@@ -614,13 +618,13 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
614 | /* The user wants to set shutter width manually, hope, | 618 | /* The user wants to set shutter width manually, hope, |
615 | * she knows, what she's doing... Switch AEC off. */ | 619 | * she knows, what she's doing... Switch AEC off. */ |
616 | 620 | ||
617 | if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) | 621 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) |
618 | return -EIO; | 622 | return -EIO; |
619 | 623 | ||
620 | dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", | 624 | dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", |
621 | reg_read(icd, MT9V022_TOTAL_SHUTTER_WIDTH), | 625 | reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), |
622 | shutter); | 626 | shutter); |
623 | if (reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, | 627 | if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, |
624 | shutter) < 0) | 628 | shutter) < 0) |
625 | return -EIO; | 629 | return -EIO; |
626 | icd->exposure = ctrl->value; | 630 | icd->exposure = ctrl->value; |
@@ -628,17 +632,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
628 | break; | 632 | break; |
629 | case V4L2_CID_AUTOGAIN: | 633 | case V4L2_CID_AUTOGAIN: |
630 | if (ctrl->value) | 634 | if (ctrl->value) |
631 | data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x2); | 635 | data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2); |
632 | else | 636 | else |
633 | data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2); | 637 | data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2); |
634 | if (data < 0) | 638 | if (data < 0) |
635 | return -EIO; | 639 | return -EIO; |
636 | break; | 640 | break; |
637 | case V4L2_CID_EXPOSURE_AUTO: | 641 | case V4L2_CID_EXPOSURE_AUTO: |
638 | if (ctrl->value) | 642 | if (ctrl->value) |
639 | data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x1); | 643 | data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1); |
640 | else | 644 | else |
641 | data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1); | 645 | data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1); |
642 | if (data < 0) | 646 | if (data < 0) |
643 | return -EIO; | 647 | return -EIO; |
644 | break; | 648 | break; |
@@ -650,8 +654,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd, | |||
650 | * this wasn't our capture interface, so, we wait for the right one */ | 654 | * this wasn't our capture interface, so, we wait for the right one */ |
651 | static int mt9v022_video_probe(struct soc_camera_device *icd) | 655 | static int mt9v022_video_probe(struct soc_camera_device *icd) |
652 | { | 656 | { |
657 | struct i2c_client *client = to_i2c_client(icd->control); | ||
653 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 658 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
654 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | 659 | struct soc_camera_link *icl = client->dev.platform_data; |
655 | s32 data; | 660 | s32 data; |
656 | int ret; | 661 | int ret; |
657 | unsigned long flags; | 662 | unsigned long flags; |
@@ -661,7 +666,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) | |||
661 | return -ENODEV; | 666 | return -ENODEV; |
662 | 667 | ||
663 | /* Read out the chip version register */ | 668 | /* Read out the chip version register */ |
664 | data = reg_read(icd, MT9V022_CHIP_VERSION); | 669 | data = reg_read(client, MT9V022_CHIP_VERSION); |
665 | 670 | ||
666 | /* must be 0x1311 or 0x1313 */ | 671 | /* must be 0x1311 or 0x1313 */ |
667 | if (data != 0x1311 && data != 0x1313) { | 672 | if (data != 0x1311 && data != 0x1313) { |
@@ -672,12 +677,12 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) | |||
672 | } | 677 | } |
673 | 678 | ||
674 | /* Soft reset */ | 679 | /* Soft reset */ |
675 | ret = reg_write(icd, MT9V022_RESET, 1); | 680 | ret = reg_write(client, MT9V022_RESET, 1); |
676 | if (ret < 0) | 681 | if (ret < 0) |
677 | goto ei2c; | 682 | goto ei2c; |
678 | /* 15 clock cycles */ | 683 | /* 15 clock cycles */ |
679 | udelay(200); | 684 | udelay(200); |
680 | if (reg_read(icd, MT9V022_RESET)) { | 685 | if (reg_read(client, MT9V022_RESET)) { |
681 | dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); | 686 | dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); |
682 | goto ei2c; | 687 | goto ei2c; |
683 | } | 688 | } |
@@ -685,11 +690,11 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) | |||
685 | /* Set monochrome or colour sensor type */ | 690 | /* Set monochrome or colour sensor type */ |
686 | if (sensor_type && (!strcmp("colour", sensor_type) || | 691 | if (sensor_type && (!strcmp("colour", sensor_type) || |
687 | !strcmp("color", sensor_type))) { | 692 | !strcmp("color", sensor_type))) { |
688 | ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); | 693 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); |
689 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; | 694 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; |
690 | icd->formats = mt9v022_colour_formats; | 695 | icd->formats = mt9v022_colour_formats; |
691 | } else { | 696 | } else { |
692 | ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11); | 697 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); |
693 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; | 698 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; |
694 | icd->formats = mt9v022_monochrome_formats; | 699 | icd->formats = mt9v022_monochrome_formats; |
695 | } | 700 | } |
@@ -735,10 +740,13 @@ ei2c: | |||
735 | static void mt9v022_video_remove(struct soc_camera_device *icd) | 740 | static void mt9v022_video_remove(struct soc_camera_device *icd) |
736 | { | 741 | { |
737 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 742 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
743 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | ||
738 | 744 | ||
739 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, | 745 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, |
740 | icd->dev.parent, icd->vdev); | 746 | icd->dev.parent, icd->vdev); |
741 | soc_camera_video_stop(icd); | 747 | soc_camera_video_stop(icd); |
748 | if (icl->free_bus) | ||
749 | icl->free_bus(icl); | ||
742 | } | 750 | } |
743 | 751 | ||
744 | static int mt9v022_probe(struct i2c_client *client, | 752 | static int mt9v022_probe(struct i2c_client *client, |