diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-08-25 10:28:22 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-18 23:18:27 -0400 |
commit | 40e2e0927003424c25807b575dd40da2b8685857 (patch) | |
tree | 917ca8fd5f7598194d264ec92a08b312d4932b90 /drivers/media/video/mt9t031.c | |
parent | bc1937b41d8253e2b554da385023a92189d38917 (diff) |
V4L/DVB (12506): soc-camera: convert to platform device
Convert soc-camera core and all drivers to platform device API. We already
converted platforms to register a platform device for each soc-camera client,
now we remove the compatibility code and switch completely to the new scheme.
This is a preparatory step for the v4l2-subdev conversion.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/mt9t031.c')
-rw-r--r-- | drivers/media/video/mt9t031.c | 116 |
1 files changed, 51 insertions, 65 deletions
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 4207fb342670..d9c7c2fd698a 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -68,8 +68,6 @@ static const struct soc_camera_data_format mt9t031_colour_formats[] = { | |||
68 | }; | 68 | }; |
69 | 69 | ||
70 | struct mt9t031 { | 70 | struct mt9t031 { |
71 | struct i2c_client *client; | ||
72 | struct soc_camera_device icd; | ||
73 | int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ | 71 | int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ |
74 | unsigned char autoexposure; | 72 | unsigned char autoexposure; |
75 | u16 xskip; | 73 | u16 xskip; |
@@ -138,8 +136,8 @@ static int get_shutter(struct i2c_client *client, u32 *data) | |||
138 | 136 | ||
139 | static int mt9t031_init(struct soc_camera_device *icd) | 137 | static int mt9t031_init(struct soc_camera_device *icd) |
140 | { | 138 | { |
141 | struct i2c_client *client = to_i2c_client(icd->control); | 139 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
142 | struct soc_camera_link *icl = client->dev.platform_data; | 140 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
143 | int ret; | 141 | int ret; |
144 | 142 | ||
145 | if (icl->power) { | 143 | if (icl->power) { |
@@ -166,8 +164,8 @@ static int mt9t031_init(struct soc_camera_device *icd) | |||
166 | 164 | ||
167 | static int mt9t031_release(struct soc_camera_device *icd) | 165 | static int mt9t031_release(struct soc_camera_device *icd) |
168 | { | 166 | { |
169 | struct i2c_client *client = to_i2c_client(icd->control); | 167 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
170 | struct soc_camera_link *icl = client->dev.platform_data; | 168 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
171 | 169 | ||
172 | /* Disable the chip */ | 170 | /* Disable the chip */ |
173 | reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); | 171 | reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); |
@@ -180,7 +178,7 @@ static int mt9t031_release(struct soc_camera_device *icd) | |||
180 | 178 | ||
181 | static int mt9t031_start_capture(struct soc_camera_device *icd) | 179 | static int mt9t031_start_capture(struct soc_camera_device *icd) |
182 | { | 180 | { |
183 | struct i2c_client *client = to_i2c_client(icd->control); | 181 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
184 | 182 | ||
185 | /* Switch to master "normal" mode */ | 183 | /* Switch to master "normal" mode */ |
186 | if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0) | 184 | if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0) |
@@ -190,7 +188,7 @@ static int mt9t031_start_capture(struct soc_camera_device *icd) | |||
190 | 188 | ||
191 | static int mt9t031_stop_capture(struct soc_camera_device *icd) | 189 | static int mt9t031_stop_capture(struct soc_camera_device *icd) |
192 | { | 190 | { |
193 | struct i2c_client *client = to_i2c_client(icd->control); | 191 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
194 | 192 | ||
195 | /* Stop sensor readout */ | 193 | /* Stop sensor readout */ |
196 | if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0) | 194 | if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0) |
@@ -201,7 +199,7 @@ static int mt9t031_stop_capture(struct soc_camera_device *icd) | |||
201 | static int mt9t031_set_bus_param(struct soc_camera_device *icd, | 199 | static int mt9t031_set_bus_param(struct soc_camera_device *icd, |
202 | unsigned long flags) | 200 | unsigned long flags) |
203 | { | 201 | { |
204 | struct i2c_client *client = to_i2c_client(icd->control); | 202 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
205 | 203 | ||
206 | /* The caller should have queried our parameters, check anyway */ | 204 | /* The caller should have queried our parameters, check anyway */ |
207 | if (flags & ~MT9T031_BUS_PARAM) | 205 | if (flags & ~MT9T031_BUS_PARAM) |
@@ -217,8 +215,7 @@ static int mt9t031_set_bus_param(struct soc_camera_device *icd, | |||
217 | 215 | ||
218 | static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd) | 216 | static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd) |
219 | { | 217 | { |
220 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 218 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
221 | struct soc_camera_link *icl = mt9t031->client->dev.platform_data; | ||
222 | 219 | ||
223 | return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); | 220 | return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); |
224 | } | 221 | } |
@@ -238,8 +235,8 @@ static void recalculate_limits(struct soc_camera_device *icd, | |||
238 | static int mt9t031_set_params(struct soc_camera_device *icd, | 235 | static int mt9t031_set_params(struct soc_camera_device *icd, |
239 | struct v4l2_rect *rect, u16 xskip, u16 yskip) | 236 | struct v4l2_rect *rect, u16 xskip, u16 yskip) |
240 | { | 237 | { |
241 | struct i2c_client *client = to_i2c_client(icd->control); | 238 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
242 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 239 | struct mt9t031 *mt9t031 = i2c_get_clientdata(client); |
243 | int ret; | 240 | int ret; |
244 | u16 xbin, ybin, width, height, left, top; | 241 | u16 xbin, ybin, width, height, left, top; |
245 | const u16 hblank = MT9T031_HORIZONTAL_BLANK, | 242 | const u16 hblank = MT9T031_HORIZONTAL_BLANK, |
@@ -336,7 +333,8 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
336 | static int mt9t031_set_crop(struct soc_camera_device *icd, | 333 | static int mt9t031_set_crop(struct soc_camera_device *icd, |
337 | struct v4l2_rect *rect) | 334 | struct v4l2_rect *rect) |
338 | { | 335 | { |
339 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 336 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
337 | struct mt9t031 *mt9t031 = i2c_get_clientdata(client); | ||
340 | 338 | ||
341 | /* CROP - no change in scaling, or in limits */ | 339 | /* CROP - no change in scaling, or in limits */ |
342 | return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip); | 340 | return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip); |
@@ -345,7 +343,8 @@ static int mt9t031_set_crop(struct soc_camera_device *icd, | |||
345 | static int mt9t031_set_fmt(struct soc_camera_device *icd, | 343 | static int mt9t031_set_fmt(struct soc_camera_device *icd, |
346 | struct v4l2_format *f) | 344 | struct v4l2_format *f) |
347 | { | 345 | { |
348 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 346 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
347 | struct mt9t031 *mt9t031 = i2c_get_clientdata(client); | ||
349 | int ret; | 348 | int ret; |
350 | u16 xskip, yskip; | 349 | u16 xskip, yskip; |
351 | struct v4l2_rect rect = { | 350 | struct v4l2_rect rect = { |
@@ -395,12 +394,13 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd, | |||
395 | static int mt9t031_get_chip_id(struct soc_camera_device *icd, | 394 | static int mt9t031_get_chip_id(struct soc_camera_device *icd, |
396 | struct v4l2_dbg_chip_ident *id) | 395 | struct v4l2_dbg_chip_ident *id) |
397 | { | 396 | { |
398 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 397 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
398 | struct mt9t031 *mt9t031 = i2c_get_clientdata(client); | ||
399 | 399 | ||
400 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | 400 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
401 | return -EINVAL; | 401 | return -EINVAL; |
402 | 402 | ||
403 | if (id->match.addr != mt9t031->client->addr) | 403 | if (id->match.addr != client->addr) |
404 | return -ENODEV; | 404 | return -ENODEV; |
405 | 405 | ||
406 | id->ident = mt9t031->model; | 406 | id->ident = mt9t031->model; |
@@ -413,7 +413,7 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd, | |||
413 | static int mt9t031_get_register(struct soc_camera_device *icd, | 413 | static int mt9t031_get_register(struct soc_camera_device *icd, |
414 | struct v4l2_dbg_register *reg) | 414 | struct v4l2_dbg_register *reg) |
415 | { | 415 | { |
416 | struct i2c_client *client = to_i2c_client(icd->control); | 416 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
417 | 417 | ||
418 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 418 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
419 | return -EINVAL; | 419 | return -EINVAL; |
@@ -432,7 +432,7 @@ static int mt9t031_get_register(struct soc_camera_device *icd, | |||
432 | static int mt9t031_set_register(struct soc_camera_device *icd, | 432 | static int mt9t031_set_register(struct soc_camera_device *icd, |
433 | struct v4l2_dbg_register *reg) | 433 | struct v4l2_dbg_register *reg) |
434 | { | 434 | { |
435 | struct i2c_client *client = to_i2c_client(icd->control); | 435 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
436 | 436 | ||
437 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 437 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
438 | return -EINVAL; | 438 | return -EINVAL; |
@@ -493,15 +493,11 @@ static const struct v4l2_queryctrl mt9t031_controls[] = { | |||
493 | } | 493 | } |
494 | }; | 494 | }; |
495 | 495 | ||
496 | static int mt9t031_video_probe(struct soc_camera_device *); | ||
497 | static void mt9t031_video_remove(struct soc_camera_device *); | ||
498 | static int mt9t031_get_control(struct soc_camera_device *, struct v4l2_control *); | 496 | static int mt9t031_get_control(struct soc_camera_device *, struct v4l2_control *); |
499 | static int mt9t031_set_control(struct soc_camera_device *, struct v4l2_control *); | 497 | static int mt9t031_set_control(struct soc_camera_device *, struct v4l2_control *); |
500 | 498 | ||
501 | static struct soc_camera_ops mt9t031_ops = { | 499 | static struct soc_camera_ops mt9t031_ops = { |
502 | .owner = THIS_MODULE, | 500 | .owner = THIS_MODULE, |
503 | .probe = mt9t031_video_probe, | ||
504 | .remove = mt9t031_video_remove, | ||
505 | .init = mt9t031_init, | 501 | .init = mt9t031_init, |
506 | .release = mt9t031_release, | 502 | .release = mt9t031_release, |
507 | .start_capture = mt9t031_start_capture, | 503 | .start_capture = mt9t031_start_capture, |
@@ -524,8 +520,8 @@ static struct soc_camera_ops mt9t031_ops = { | |||
524 | 520 | ||
525 | static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 521 | static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
526 | { | 522 | { |
527 | struct i2c_client *client = to_i2c_client(icd->control); | 523 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
528 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 524 | struct mt9t031 *mt9t031 = i2c_get_clientdata(client); |
529 | int data; | 525 | int data; |
530 | 526 | ||
531 | switch (ctrl->id) { | 527 | switch (ctrl->id) { |
@@ -550,8 +546,8 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro | |||
550 | 546 | ||
551 | static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 547 | static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
552 | { | 548 | { |
553 | struct i2c_client *client = to_i2c_client(icd->control); | 549 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
554 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | 550 | struct mt9t031 *mt9t031 = i2c_get_clientdata(client); |
555 | const struct v4l2_queryctrl *qctrl; | 551 | const struct v4l2_queryctrl *qctrl; |
556 | int data; | 552 | int data; |
557 | 553 | ||
@@ -657,10 +653,10 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
657 | 653 | ||
658 | /* Interface active, can use i2c. If it fails, it can indeed mean, that | 654 | /* Interface active, can use i2c. If it fails, it can indeed mean, that |
659 | * this wasn't our capture interface, so, we wait for the right one */ | 655 | * this wasn't our capture interface, so, we wait for the right one */ |
660 | static int mt9t031_video_probe(struct soc_camera_device *icd) | 656 | static int mt9t031_video_probe(struct soc_camera_device *icd, |
657 | struct i2c_client *client) | ||
661 | { | 658 | { |
662 | struct i2c_client *client = to_i2c_client(icd->control); | 659 | struct mt9t031 *mt9t031 = i2c_get_clientdata(client); |
663 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | ||
664 | s32 data; | 660 | s32 data; |
665 | int ret; | 661 | int ret; |
666 | 662 | ||
@@ -670,6 +666,11 @@ static int mt9t031_video_probe(struct soc_camera_device *icd) | |||
670 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) | 666 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) |
671 | return -ENODEV; | 667 | return -ENODEV; |
672 | 668 | ||
669 | /* Switch master clock on */ | ||
670 | ret = soc_camera_video_start(icd, &client->dev); | ||
671 | if (ret) | ||
672 | return ret; | ||
673 | |||
673 | /* Enable the chip */ | 674 | /* Enable the chip */ |
674 | data = reg_write(client, MT9T031_CHIP_ENABLE, 1); | 675 | data = reg_write(client, MT9T031_CHIP_ENABLE, 1); |
675 | dev_dbg(&icd->dev, "write: %d\n", data); | 676 | dev_dbg(&icd->dev, "write: %d\n", data); |
@@ -677,6 +678,8 @@ static int mt9t031_video_probe(struct soc_camera_device *icd) | |||
677 | /* Read out the chip version register */ | 678 | /* Read out the chip version register */ |
678 | data = reg_read(client, MT9T031_CHIP_VERSION); | 679 | data = reg_read(client, MT9T031_CHIP_VERSION); |
679 | 680 | ||
681 | soc_camera_video_stop(icd); | ||
682 | |||
680 | switch (data) { | 683 | switch (data) { |
681 | case 0x1621: | 684 | case 0x1621: |
682 | mt9t031->model = V4L2_IDENT_MT9T031; | 685 | mt9t031->model = V4L2_IDENT_MT9T031; |
@@ -684,44 +687,31 @@ static int mt9t031_video_probe(struct soc_camera_device *icd) | |||
684 | icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats); | 687 | icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats); |
685 | break; | 688 | break; |
686 | default: | 689 | default: |
687 | ret = -ENODEV; | ||
688 | dev_err(&icd->dev, | 690 | dev_err(&icd->dev, |
689 | "No MT9T031 chip detected, register read %x\n", data); | 691 | "No MT9T031 chip detected, register read %x\n", data); |
690 | goto ei2c; | 692 | return -ENODEV; |
691 | } | 693 | } |
692 | 694 | ||
693 | dev_info(&icd->dev, "Detected a MT9T031 chip ID %x\n", data); | 695 | dev_info(&icd->dev, "Detected a MT9T031 chip ID %x\n", data); |
694 | 696 | ||
695 | /* Now that we know the model, we can start video */ | ||
696 | ret = soc_camera_video_start(icd); | ||
697 | if (ret) | ||
698 | goto evstart; | ||
699 | |||
700 | return 0; | 697 | return 0; |
701 | |||
702 | evstart: | ||
703 | ei2c: | ||
704 | return ret; | ||
705 | } | ||
706 | |||
707 | static void mt9t031_video_remove(struct soc_camera_device *icd) | ||
708 | { | ||
709 | struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); | ||
710 | |||
711 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9t031->client->addr, | ||
712 | icd->dev.parent, icd->vdev); | ||
713 | soc_camera_video_stop(icd); | ||
714 | } | 698 | } |
715 | 699 | ||
716 | static int mt9t031_probe(struct i2c_client *client, | 700 | static int mt9t031_probe(struct i2c_client *client, |
717 | const struct i2c_device_id *did) | 701 | const struct i2c_device_id *did) |
718 | { | 702 | { |
719 | struct mt9t031 *mt9t031; | 703 | struct mt9t031 *mt9t031; |
720 | struct soc_camera_device *icd; | 704 | struct soc_camera_device *icd = client->dev.platform_data; |
721 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 705 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
722 | struct soc_camera_link *icl = client->dev.platform_data; | 706 | struct soc_camera_link *icl; |
723 | int ret; | 707 | int ret; |
724 | 708 | ||
709 | if (!icd) { | ||
710 | dev_err(&client->dev, "MT9T031: missing soc-camera data!\n"); | ||
711 | return -EINVAL; | ||
712 | } | ||
713 | |||
714 | icl = to_soc_camera_link(icd); | ||
725 | if (!icl) { | 715 | if (!icl) { |
726 | dev_err(&client->dev, "MT9T031 driver needs platform data\n"); | 716 | dev_err(&client->dev, "MT9T031 driver needs platform data\n"); |
727 | return -EINVAL; | 717 | return -EINVAL; |
@@ -737,13 +727,10 @@ static int mt9t031_probe(struct i2c_client *client, | |||
737 | if (!mt9t031) | 727 | if (!mt9t031) |
738 | return -ENOMEM; | 728 | return -ENOMEM; |
739 | 729 | ||
740 | mt9t031->client = client; | ||
741 | i2c_set_clientdata(client, mt9t031); | 730 | i2c_set_clientdata(client, mt9t031); |
742 | 731 | ||
743 | /* Second stage probe - when a capture adapter is there */ | 732 | /* Second stage probe - when a capture adapter is there */ |
744 | icd = &mt9t031->icd; | ||
745 | icd->ops = &mt9t031_ops; | 733 | icd->ops = &mt9t031_ops; |
746 | icd->control = &client->dev; | ||
747 | icd->x_min = MT9T031_COLUMN_SKIP; | 734 | icd->x_min = MT9T031_COLUMN_SKIP; |
748 | icd->y_min = MT9T031_ROW_SKIP; | 735 | icd->y_min = MT9T031_ROW_SKIP; |
749 | icd->x_current = icd->x_min; | 736 | icd->x_current = icd->x_min; |
@@ -753,7 +740,6 @@ static int mt9t031_probe(struct i2c_client *client, | |||
753 | icd->height_min = MT9T031_MIN_HEIGHT; | 740 | icd->height_min = MT9T031_MIN_HEIGHT; |
754 | icd->height_max = MT9T031_MAX_HEIGHT; | 741 | icd->height_max = MT9T031_MAX_HEIGHT; |
755 | icd->y_skip_top = 0; | 742 | icd->y_skip_top = 0; |
756 | icd->iface = icl->bus_id; | ||
757 | /* Simulated autoexposure. If enabled, we calculate shutter width | 743 | /* Simulated autoexposure. If enabled, we calculate shutter width |
758 | * ourselves in the driver based on vertical blanking and frame width */ | 744 | * ourselves in the driver based on vertical blanking and frame width */ |
759 | mt9t031->autoexposure = 1; | 745 | mt9t031->autoexposure = 1; |
@@ -761,24 +747,24 @@ static int mt9t031_probe(struct i2c_client *client, | |||
761 | mt9t031->xskip = 1; | 747 | mt9t031->xskip = 1; |
762 | mt9t031->yskip = 1; | 748 | mt9t031->yskip = 1; |
763 | 749 | ||
764 | ret = soc_camera_device_register(icd); | 750 | ret = mt9t031_video_probe(icd, client); |
765 | if (ret) | 751 | if (ret) { |
766 | goto eisdr; | 752 | icd->ops = NULL; |
767 | 753 | i2c_set_clientdata(client, NULL); | |
768 | return 0; | 754 | kfree(mt9t031); |
755 | } | ||
769 | 756 | ||
770 | eisdr: | ||
771 | i2c_set_clientdata(client, NULL); | ||
772 | kfree(mt9t031); | ||
773 | return ret; | 757 | return ret; |
774 | } | 758 | } |
775 | 759 | ||
776 | static int mt9t031_remove(struct i2c_client *client) | 760 | static int mt9t031_remove(struct i2c_client *client) |
777 | { | 761 | { |
778 | struct mt9t031 *mt9t031 = i2c_get_clientdata(client); | 762 | struct mt9t031 *mt9t031 = i2c_get_clientdata(client); |
763 | struct soc_camera_device *icd = client->dev.platform_data; | ||
779 | 764 | ||
780 | soc_camera_device_unregister(&mt9t031->icd); | 765 | icd->ops = NULL; |
781 | i2c_set_clientdata(client, NULL); | 766 | i2c_set_clientdata(client, NULL); |
767 | client->driver = NULL; | ||
782 | kfree(mt9t031); | 768 | kfree(mt9t031); |
783 | 769 | ||
784 | return 0; | 770 | return 0; |