aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9v022.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/mt9v022.c')
-rw-r--r--drivers/media/video/mt9v022.c138
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
94static int reg_read(struct soc_camera_device *icd, const u8 reg) 94static 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
102static int reg_write(struct soc_camera_device *icd, const u8 reg, 100static 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
109static int reg_set(struct soc_camera_device *icd, const u8 reg, 106static 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
120static int reg_clear(struct soc_camera_device *icd, const u8 reg, 117static 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
131static int mt9v022_init(struct soc_camera_device *icd) 128static 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
187static int mt9v022_start_capture(struct soc_camera_device *icd) 185static 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
198static int mt9v022_stop_capture(struct soc_camera_device *icd) 197static 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)
209static int mt9v022_set_bus_param(struct soc_camera_device *icd, 209static 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)
282static int mt9v022_set_crop(struct soc_camera_device *icd, 283static 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,
396static int mt9v022_get_register(struct soc_camera_device *icd, 398static 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,
416static int mt9v022_set_register(struct soc_camera_device *icd, 418static 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 = {
517static int mt9v022_get_control(struct soc_camera_device *icd, 519static 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 */
651static int mt9v022_video_probe(struct soc_camera_device *icd) 655static 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:
735static void mt9v022_video_remove(struct soc_camera_device *icd) 740static 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
744static int mt9v022_probe(struct i2c_client *client, 752static int mt9v022_probe(struct i2c_client *client,