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/mt9m001.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/mt9m001.c')
-rw-r--r-- | drivers/media/video/mt9m001.c | 114 |
1 files changed, 54 insertions, 60 deletions
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 4d794b42d6cd..1e4f269fc08b 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
@@ -69,8 +69,6 @@ static const struct soc_camera_data_format mt9m001_monochrome_formats[] = { | |||
69 | }; | 69 | }; |
70 | 70 | ||
71 | struct mt9m001 { | 71 | struct mt9m001 { |
72 | struct i2c_client *client; | ||
73 | struct soc_camera_device icd; | ||
74 | int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ | 72 | int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ |
75 | unsigned char autoexposure; | 73 | unsigned char autoexposure; |
76 | }; | 74 | }; |
@@ -111,11 +109,11 @@ static int reg_clear(struct i2c_client *client, const u8 reg, | |||
111 | 109 | ||
112 | static int mt9m001_init(struct soc_camera_device *icd) | 110 | static int mt9m001_init(struct soc_camera_device *icd) |
113 | { | 111 | { |
114 | struct i2c_client *client = to_i2c_client(icd->control); | 112 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
115 | struct soc_camera_link *icl = client->dev.platform_data; | 113 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
116 | int ret; | 114 | int ret; |
117 | 115 | ||
118 | dev_dbg(icd->vdev->parent, "%s\n", __func__); | 116 | dev_dbg(&icd->dev, "%s\n", __func__); |
119 | 117 | ||
120 | if (icl->power) { | 118 | if (icl->power) { |
121 | ret = icl->power(&client->dev, 1); | 119 | ret = icl->power(&client->dev, 1); |
@@ -147,8 +145,8 @@ static int mt9m001_init(struct soc_camera_device *icd) | |||
147 | 145 | ||
148 | static int mt9m001_release(struct soc_camera_device *icd) | 146 | static int mt9m001_release(struct soc_camera_device *icd) |
149 | { | 147 | { |
150 | struct i2c_client *client = to_i2c_client(icd->control); | 148 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
151 | struct soc_camera_link *icl = client->dev.platform_data; | 149 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
152 | 150 | ||
153 | /* Disable the chip */ | 151 | /* Disable the chip */ |
154 | reg_write(client, MT9M001_OUTPUT_CONTROL, 0); | 152 | reg_write(client, MT9M001_OUTPUT_CONTROL, 0); |
@@ -161,7 +159,7 @@ static int mt9m001_release(struct soc_camera_device *icd) | |||
161 | 159 | ||
162 | static int mt9m001_start_capture(struct soc_camera_device *icd) | 160 | static int mt9m001_start_capture(struct soc_camera_device *icd) |
163 | { | 161 | { |
164 | struct i2c_client *client = to_i2c_client(icd->control); | 162 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
165 | 163 | ||
166 | /* Switch to master "normal" mode */ | 164 | /* Switch to master "normal" mode */ |
167 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0) | 165 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0) |
@@ -171,7 +169,7 @@ static int mt9m001_start_capture(struct soc_camera_device *icd) | |||
171 | 169 | ||
172 | static int mt9m001_stop_capture(struct soc_camera_device *icd) | 170 | static int mt9m001_stop_capture(struct soc_camera_device *icd) |
173 | { | 171 | { |
174 | struct i2c_client *client = to_i2c_client(icd->control); | 172 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
175 | 173 | ||
176 | /* Stop sensor readout */ | 174 | /* Stop sensor readout */ |
177 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0) | 175 | if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0) |
@@ -182,8 +180,7 @@ static int mt9m001_stop_capture(struct soc_camera_device *icd) | |||
182 | static int mt9m001_set_bus_param(struct soc_camera_device *icd, | 180 | static int mt9m001_set_bus_param(struct soc_camera_device *icd, |
183 | unsigned long flags) | 181 | unsigned long flags) |
184 | { | 182 | { |
185 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 183 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
186 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | ||
187 | unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK; | 184 | unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK; |
188 | 185 | ||
189 | /* Only one width bit may be set */ | 186 | /* Only one width bit may be set */ |
@@ -205,8 +202,7 @@ static int mt9m001_set_bus_param(struct soc_camera_device *icd, | |||
205 | 202 | ||
206 | static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) | 203 | static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) |
207 | { | 204 | { |
208 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 205 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
209 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | ||
210 | /* MT9M001 has all capture_format parameters fixed */ | 206 | /* MT9M001 has all capture_format parameters fixed */ |
211 | unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING | | 207 | unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING | |
212 | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | | 208 | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | |
@@ -223,8 +219,8 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) | |||
223 | static int mt9m001_set_crop(struct soc_camera_device *icd, | 219 | static int mt9m001_set_crop(struct soc_camera_device *icd, |
224 | struct v4l2_rect *rect) | 220 | struct v4l2_rect *rect) |
225 | { | 221 | { |
226 | struct i2c_client *client = to_i2c_client(icd->control); | 222 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
227 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 223 | struct mt9m001 *mt9m001 = i2c_get_clientdata(client); |
228 | int ret; | 224 | int ret; |
229 | const u16 hblank = 9, vblank = 25; | 225 | const u16 hblank = 9, vblank = 25; |
230 | 226 | ||
@@ -290,12 +286,13 @@ static int mt9m001_try_fmt(struct soc_camera_device *icd, | |||
290 | static int mt9m001_get_chip_id(struct soc_camera_device *icd, | 286 | static int mt9m001_get_chip_id(struct soc_camera_device *icd, |
291 | struct v4l2_dbg_chip_ident *id) | 287 | struct v4l2_dbg_chip_ident *id) |
292 | { | 288 | { |
293 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 289 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
290 | struct mt9m001 *mt9m001 = i2c_get_clientdata(client); | ||
294 | 291 | ||
295 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | 292 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
296 | return -EINVAL; | 293 | return -EINVAL; |
297 | 294 | ||
298 | if (id->match.addr != mt9m001->client->addr) | 295 | if (id->match.addr != client->addr) |
299 | return -ENODEV; | 296 | return -ENODEV; |
300 | 297 | ||
301 | id->ident = mt9m001->model; | 298 | id->ident = mt9m001->model; |
@@ -308,7 +305,7 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd, | |||
308 | static int mt9m001_get_register(struct soc_camera_device *icd, | 305 | static int mt9m001_get_register(struct soc_camera_device *icd, |
309 | struct v4l2_dbg_register *reg) | 306 | struct v4l2_dbg_register *reg) |
310 | { | 307 | { |
311 | struct i2c_client *client = to_i2c_client(icd->control); | 308 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
312 | 309 | ||
313 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 310 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
314 | return -EINVAL; | 311 | return -EINVAL; |
@@ -328,7 +325,7 @@ static int mt9m001_get_register(struct soc_camera_device *icd, | |||
328 | static int mt9m001_set_register(struct soc_camera_device *icd, | 325 | static int mt9m001_set_register(struct soc_camera_device *icd, |
329 | struct v4l2_dbg_register *reg) | 326 | struct v4l2_dbg_register *reg) |
330 | { | 327 | { |
331 | struct i2c_client *client = to_i2c_client(icd->control); | 328 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
332 | 329 | ||
333 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) | 330 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) |
334 | return -EINVAL; | 331 | return -EINVAL; |
@@ -381,15 +378,11 @@ static const struct v4l2_queryctrl mt9m001_controls[] = { | |||
381 | } | 378 | } |
382 | }; | 379 | }; |
383 | 380 | ||
384 | static int mt9m001_video_probe(struct soc_camera_device *); | ||
385 | static void mt9m001_video_remove(struct soc_camera_device *); | ||
386 | static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *); | 381 | static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *); |
387 | static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *); | 382 | static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *); |
388 | 383 | ||
389 | static struct soc_camera_ops mt9m001_ops = { | 384 | static struct soc_camera_ops mt9m001_ops = { |
390 | .owner = THIS_MODULE, | 385 | .owner = THIS_MODULE, |
391 | .probe = mt9m001_video_probe, | ||
392 | .remove = mt9m001_video_remove, | ||
393 | .init = mt9m001_init, | 386 | .init = mt9m001_init, |
394 | .release = mt9m001_release, | 387 | .release = mt9m001_release, |
395 | .start_capture = mt9m001_start_capture, | 388 | .start_capture = mt9m001_start_capture, |
@@ -412,8 +405,8 @@ static struct soc_camera_ops mt9m001_ops = { | |||
412 | 405 | ||
413 | static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 406 | static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
414 | { | 407 | { |
415 | struct i2c_client *client = to_i2c_client(icd->control); | 408 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
416 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 409 | struct mt9m001 *mt9m001 = i2c_get_clientdata(client); |
417 | int data; | 410 | int data; |
418 | 411 | ||
419 | switch (ctrl->id) { | 412 | switch (ctrl->id) { |
@@ -432,8 +425,8 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro | |||
432 | 425 | ||
433 | static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) | 426 | static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) |
434 | { | 427 | { |
435 | struct i2c_client *client = to_i2c_client(icd->control); | 428 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
436 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 429 | struct mt9m001 *mt9m001 = i2c_get_clientdata(client); |
437 | const struct v4l2_queryctrl *qctrl; | 430 | const struct v4l2_queryctrl *qctrl; |
438 | int data; | 431 | int data; |
439 | 432 | ||
@@ -525,11 +518,11 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro | |||
525 | 518 | ||
526 | /* Interface active, can use i2c. If it fails, it can indeed mean, that | 519 | /* Interface active, can use i2c. If it fails, it can indeed mean, that |
527 | * this wasn't our capture interface, so, we wait for the right one */ | 520 | * this wasn't our capture interface, so, we wait for the right one */ |
528 | static int mt9m001_video_probe(struct soc_camera_device *icd) | 521 | static int mt9m001_video_probe(struct soc_camera_device *icd, |
522 | struct i2c_client *client) | ||
529 | { | 523 | { |
530 | struct i2c_client *client = to_i2c_client(icd->control); | 524 | struct mt9m001 *mt9m001 = i2c_get_clientdata(client); |
531 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 525 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
532 | struct soc_camera_link *icl = client->dev.platform_data; | ||
533 | s32 data; | 526 | s32 data; |
534 | int ret; | 527 | int ret; |
535 | unsigned long flags; | 528 | unsigned long flags; |
@@ -540,6 +533,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd) | |||
540 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) | 533 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) |
541 | return -ENODEV; | 534 | return -ENODEV; |
542 | 535 | ||
536 | /* Switch master clock on */ | ||
537 | ret = soc_camera_video_start(icd, &client->dev); | ||
538 | if (ret) | ||
539 | return ret; | ||
540 | |||
543 | /* Enable the chip */ | 541 | /* Enable the chip */ |
544 | data = reg_write(client, MT9M001_CHIP_ENABLE, 1); | 542 | data = reg_write(client, MT9M001_CHIP_ENABLE, 1); |
545 | dev_dbg(&icd->dev, "write: %d\n", data); | 543 | dev_dbg(&icd->dev, "write: %d\n", data); |
@@ -547,6 +545,8 @@ static int mt9m001_video_probe(struct soc_camera_device *icd) | |||
547 | /* Read out the chip version register */ | 545 | /* Read out the chip version register */ |
548 | data = reg_read(client, MT9M001_CHIP_VERSION); | 546 | data = reg_read(client, MT9M001_CHIP_VERSION); |
549 | 547 | ||
548 | soc_camera_video_stop(icd); | ||
549 | |||
550 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ | 550 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ |
551 | switch (data) { | 551 | switch (data) { |
552 | case 0x8411: | 552 | case 0x8411: |
@@ -559,10 +559,9 @@ static int mt9m001_video_probe(struct soc_camera_device *icd) | |||
559 | icd->formats = mt9m001_monochrome_formats; | 559 | icd->formats = mt9m001_monochrome_formats; |
560 | break; | 560 | break; |
561 | default: | 561 | default: |
562 | ret = -ENODEV; | ||
563 | dev_err(&icd->dev, | 562 | dev_err(&icd->dev, |
564 | "No MT9M001 chip detected, register read %x\n", data); | 563 | "No MT9M001 chip detected, register read %x\n", data); |
565 | goto ei2c; | 564 | return -ENODEV; |
566 | } | 565 | } |
567 | 566 | ||
568 | icd->num_formats = 0; | 567 | icd->num_formats = 0; |
@@ -588,26 +587,16 @@ static int mt9m001_video_probe(struct soc_camera_device *icd) | |||
588 | dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, | 587 | dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, |
589 | data == 0x8431 ? "C12STM" : "C12ST"); | 588 | data == 0x8431 ? "C12STM" : "C12ST"); |
590 | 589 | ||
591 | /* Now that we know the model, we can start video */ | ||
592 | ret = soc_camera_video_start(icd); | ||
593 | if (ret) | ||
594 | goto eisis; | ||
595 | |||
596 | return 0; | 590 | return 0; |
597 | |||
598 | eisis: | ||
599 | ei2c: | ||
600 | return ret; | ||
601 | } | 591 | } |
602 | 592 | ||
603 | static void mt9m001_video_remove(struct soc_camera_device *icd) | 593 | static void mt9m001_video_remove(struct soc_camera_device *icd) |
604 | { | 594 | { |
605 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 595 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
606 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | 596 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
607 | 597 | ||
608 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, | 598 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", client->addr, |
609 | icd->dev.parent, icd->vdev); | 599 | icd->dev.parent, icd->vdev); |
610 | soc_camera_video_stop(icd); | ||
611 | if (icl->free_bus) | 600 | if (icl->free_bus) |
612 | icl->free_bus(icl); | 601 | icl->free_bus(icl); |
613 | } | 602 | } |
@@ -616,11 +605,17 @@ static int mt9m001_probe(struct i2c_client *client, | |||
616 | const struct i2c_device_id *did) | 605 | const struct i2c_device_id *did) |
617 | { | 606 | { |
618 | struct mt9m001 *mt9m001; | 607 | struct mt9m001 *mt9m001; |
619 | struct soc_camera_device *icd; | 608 | struct soc_camera_device *icd = client->dev.platform_data; |
620 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 609 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
621 | struct soc_camera_link *icl = client->dev.platform_data; | 610 | struct soc_camera_link *icl; |
622 | int ret; | 611 | int ret; |
623 | 612 | ||
613 | if (!icd) { | ||
614 | dev_err(&client->dev, "MT9M001: missing soc-camera data!\n"); | ||
615 | return -EINVAL; | ||
616 | } | ||
617 | |||
618 | icl = to_soc_camera_link(icd); | ||
624 | if (!icl) { | 619 | if (!icl) { |
625 | dev_err(&client->dev, "MT9M001 driver needs platform data\n"); | 620 | dev_err(&client->dev, "MT9M001 driver needs platform data\n"); |
626 | return -EINVAL; | 621 | return -EINVAL; |
@@ -636,13 +631,10 @@ static int mt9m001_probe(struct i2c_client *client, | |||
636 | if (!mt9m001) | 631 | if (!mt9m001) |
637 | return -ENOMEM; | 632 | return -ENOMEM; |
638 | 633 | ||
639 | mt9m001->client = client; | ||
640 | i2c_set_clientdata(client, mt9m001); | 634 | i2c_set_clientdata(client, mt9m001); |
641 | 635 | ||
642 | /* Second stage probe - when a capture adapter is there */ | 636 | /* Second stage probe - when a capture adapter is there */ |
643 | icd = &mt9m001->icd; | ||
644 | icd->ops = &mt9m001_ops; | 637 | icd->ops = &mt9m001_ops; |
645 | icd->control = &client->dev; | ||
646 | icd->x_min = 20; | 638 | icd->x_min = 20; |
647 | icd->y_min = 12; | 639 | icd->y_min = 12; |
648 | icd->x_current = 20; | 640 | icd->x_current = 20; |
@@ -652,27 +644,29 @@ static int mt9m001_probe(struct i2c_client *client, | |||
652 | icd->height_min = 32; | 644 | icd->height_min = 32; |
653 | icd->height_max = 1024; | 645 | icd->height_max = 1024; |
654 | icd->y_skip_top = 1; | 646 | icd->y_skip_top = 1; |
655 | icd->iface = icl->bus_id; | ||
656 | /* Simulated autoexposure. If enabled, we calculate shutter width | 647 | /* Simulated autoexposure. If enabled, we calculate shutter width |
657 | * ourselves in the driver based on vertical blanking and frame width */ | 648 | * ourselves in the driver based on vertical blanking and frame width */ |
658 | mt9m001->autoexposure = 1; | 649 | mt9m001->autoexposure = 1; |
659 | 650 | ||
660 | ret = soc_camera_device_register(icd); | 651 | ret = mt9m001_video_probe(icd, client); |
661 | if (ret) | 652 | if (ret) { |
662 | goto eisdr; | 653 | icd->ops = NULL; |
663 | 654 | i2c_set_clientdata(client, NULL); | |
664 | return 0; | 655 | kfree(mt9m001); |
656 | } | ||
665 | 657 | ||
666 | eisdr: | ||
667 | kfree(mt9m001); | ||
668 | return ret; | 658 | return ret; |
669 | } | 659 | } |
670 | 660 | ||
671 | static int mt9m001_remove(struct i2c_client *client) | 661 | static int mt9m001_remove(struct i2c_client *client) |
672 | { | 662 | { |
673 | struct mt9m001 *mt9m001 = i2c_get_clientdata(client); | 663 | struct mt9m001 *mt9m001 = i2c_get_clientdata(client); |
664 | struct soc_camera_device *icd = client->dev.platform_data; | ||
674 | 665 | ||
675 | soc_camera_device_unregister(&mt9m001->icd); | 666 | icd->ops = NULL; |
667 | mt9m001_video_remove(icd); | ||
668 | i2c_set_clientdata(client, NULL); | ||
669 | client->driver = NULL; | ||
676 | kfree(mt9m001); | 670 | kfree(mt9m001); |
677 | 671 | ||
678 | return 0; | 672 | return 0; |