aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9m001.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:28:22 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:18:27 -0400
commit40e2e0927003424c25807b575dd40da2b8685857 (patch)
tree917ca8fd5f7598194d264ec92a08b312d4932b90 /drivers/media/video/mt9m001.c
parentbc1937b41d8253e2b554da385023a92189d38917 (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.c114
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
71struct mt9m001 { 71struct 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
112static int mt9m001_init(struct soc_camera_device *icd) 110static 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
148static int mt9m001_release(struct soc_camera_device *icd) 146static 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
162static int mt9m001_start_capture(struct soc_camera_device *icd) 160static 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
172static int mt9m001_stop_capture(struct soc_camera_device *icd) 170static 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)
182static int mt9m001_set_bus_param(struct soc_camera_device *icd, 180static 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
206static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) 203static 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)
223static int mt9m001_set_crop(struct soc_camera_device *icd, 219static 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,
290static int mt9m001_get_chip_id(struct soc_camera_device *icd, 286static 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,
308static int mt9m001_get_register(struct soc_camera_device *icd, 305static 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,
328static int mt9m001_set_register(struct soc_camera_device *icd, 325static 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
384static int mt9m001_video_probe(struct soc_camera_device *);
385static void mt9m001_video_remove(struct soc_camera_device *);
386static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *); 381static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *);
387static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *); 382static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *);
388 383
389static struct soc_camera_ops mt9m001_ops = { 384static 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
413static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 406static 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
433static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 426static 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 */
528static int mt9m001_video_probe(struct soc_camera_device *icd) 521static 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
598eisis:
599ei2c:
600 return ret;
601} 591}
602 592
603static void mt9m001_video_remove(struct soc_camera_device *icd) 593static 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
666eisdr:
667 kfree(mt9m001);
668 return ret; 658 return ret;
669} 659}
670 660
671static int mt9m001_remove(struct i2c_client *client) 661static 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;