aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9t031.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:43:33 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:18:35 -0400
commit979ea1ddf80ac7383acdea03471355ca62702539 (patch)
tree2ee4c73eb672c1ee8167ed7e0906bac6f3b00e69 /drivers/media/video/mt9t031.c
parent0bab829de1ab60d8c3cbf7e402192bb9446840b7 (diff)
V4L/DVB (12510): soc-camera: (partially) convert to v4l2-(sub)dev API
Convert the soc-camera framework to use the v4l2-(sub)dev API. Start using v4l2-subdev operations. Only a part of the interface between the soc_camera core, soc_camera host drivers on one side and soc_camera device drivers on the other side is replaced so far. The rest of the interface will be replaced in incremental steps, and will require extensions and, possibly, modifications to the v4l2-subdev code. 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.c173
1 files changed, 87 insertions, 86 deletions
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index d9c7c2fd698a..27a5edda902c 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -13,13 +13,13 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15 15
16#include <media/v4l2-common.h> 16#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h> 17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h> 18#include <media/soc_camera.h>
19 19
20/* mt9t031 i2c address 0x5d 20/* mt9t031 i2c address 0x5d
21 * The platform has to define i2c_board_info 21 * The platform has to define i2c_board_info and link to it from
22 * and call i2c_register_board_info() */ 22 * struct soc_camera_link */
23 23
24/* mt9t031 selected register addresses */ 24/* mt9t031 selected register addresses */
25#define MT9T031_CHIP_VERSION 0x00 25#define MT9T031_CHIP_VERSION 0x00
@@ -68,12 +68,18 @@ static const struct soc_camera_data_format mt9t031_colour_formats[] = {
68}; 68};
69 69
70struct mt9t031 { 70struct mt9t031 {
71 struct v4l2_subdev subdev;
71 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ 72 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
72 unsigned char autoexposure; 73 unsigned char autoexposure;
73 u16 xskip; 74 u16 xskip;
74 u16 yskip; 75 u16 yskip;
75}; 76};
76 77
78static struct mt9t031 *to_mt9t031(const struct i2c_client *client)
79{
80 return container_of(i2c_get_clientdata(client), struct mt9t031, subdev);
81}
82
77static int reg_read(struct i2c_client *client, const u8 reg) 83static int reg_read(struct i2c_client *client, const u8 reg)
78{ 84{
79 s32 data = i2c_smbus_read_word_data(client, reg); 85 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -134,21 +140,10 @@ static int get_shutter(struct i2c_client *client, u32 *data)
134 return ret < 0 ? ret : 0; 140 return ret < 0 ? ret : 0;
135} 141}
136 142
137static int mt9t031_init(struct soc_camera_device *icd) 143static int mt9t031_idle(struct i2c_client *client)
138{ 144{
139 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
140 struct soc_camera_link *icl = to_soc_camera_link(icd);
141 int ret; 145 int ret;
142 146
143 if (icl->power) {
144 ret = icl->power(&client->dev, 1);
145 if (ret < 0) {
146 dev_err(icd->vdev->parent,
147 "Platform failed to power-on the camera.\n");
148 return ret;
149 }
150 }
151
152 /* Disable chip output, synchronous option update */ 147 /* Disable chip output, synchronous option update */
153 ret = reg_write(client, MT9T031_RESET, 1); 148 ret = reg_write(client, MT9T031_RESET, 1);
154 if (ret >= 0) 149 if (ret >= 0)
@@ -156,43 +151,46 @@ static int mt9t031_init(struct soc_camera_device *icd)
156 if (ret >= 0) 151 if (ret >= 0)
157 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); 152 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
158 153
159 if (ret < 0 && icl->power)
160 icl->power(&client->dev, 0);
161
162 return ret >= 0 ? 0 : -EIO; 154 return ret >= 0 ? 0 : -EIO;
163} 155}
164 156
165static int mt9t031_release(struct soc_camera_device *icd) 157static int mt9t031_disable(struct i2c_client *client)
166{ 158{
167 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
168 struct soc_camera_link *icl = to_soc_camera_link(icd);
169
170 /* Disable the chip */ 159 /* Disable the chip */
171 reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); 160 reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
172 161
173 if (icl->power)
174 icl->power(&client->dev, 0);
175
176 return 0; 162 return 0;
177} 163}
178 164
179static int mt9t031_start_capture(struct soc_camera_device *icd) 165static int mt9t031_init(struct soc_camera_device *icd)
180{ 166{
181 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 167 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
182 168
183 /* Switch to master "normal" mode */ 169 return mt9t031_idle(client);
184 if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
185 return -EIO;
186 return 0;
187} 170}
188 171
189static int mt9t031_stop_capture(struct soc_camera_device *icd) 172static int mt9t031_release(struct soc_camera_device *icd)
190{ 173{
191 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 174 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
192 175
193 /* Stop sensor readout */ 176 return mt9t031_disable(client);
194 if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0) 177}
178
179static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
180{
181 struct i2c_client *client = sd->priv;
182 int ret;
183
184 if (enable)
185 /* Switch to master "normal" mode */
186 ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 2);
187 else
188 /* Stop sensor readout */
189 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
190
191 if (ret < 0)
195 return -EIO; 192 return -EIO;
193
196 return 0; 194 return 0;
197} 195}
198 196
@@ -236,7 +234,7 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
236 struct v4l2_rect *rect, u16 xskip, u16 yskip) 234 struct v4l2_rect *rect, u16 xskip, u16 yskip)
237{ 235{
238 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 236 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
239 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 237 struct mt9t031 *mt9t031 = to_mt9t031(client);
240 int ret; 238 int ret;
241 u16 xbin, ybin, width, height, left, top; 239 u16 xbin, ybin, width, height, left, top;
242 const u16 hblank = MT9T031_HORIZONTAL_BLANK, 240 const u16 hblank = MT9T031_HORIZONTAL_BLANK,
@@ -334,17 +332,17 @@ static int mt9t031_set_crop(struct soc_camera_device *icd,
334 struct v4l2_rect *rect) 332 struct v4l2_rect *rect)
335{ 333{
336 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 334 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
337 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 335 struct mt9t031 *mt9t031 = to_mt9t031(client);
338 336
339 /* CROP - no change in scaling, or in limits */ 337 /* CROP - no change in scaling, or in limits */
340 return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip); 338 return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip);
341} 339}
342 340
343static int mt9t031_set_fmt(struct soc_camera_device *icd, 341static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
344 struct v4l2_format *f)
345{ 342{
346 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 343 struct i2c_client *client = sd->priv;
347 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 344 struct mt9t031 *mt9t031 = to_mt9t031(client);
345 struct soc_camera_device *icd = client->dev.platform_data;
348 int ret; 346 int ret;
349 u16 xskip, yskip; 347 u16 xskip, yskip;
350 struct v4l2_rect rect = { 348 struct v4l2_rect rect = {
@@ -379,8 +377,7 @@ static int mt9t031_set_fmt(struct soc_camera_device *icd,
379 return ret; 377 return ret;
380} 378}
381 379
382static int mt9t031_try_fmt(struct soc_camera_device *icd, 380static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
383 struct v4l2_format *f)
384{ 381{
385 struct v4l2_pix_format *pix = &f->fmt.pix; 382 struct v4l2_pix_format *pix = &f->fmt.pix;
386 383
@@ -391,11 +388,11 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd,
391 return 0; 388 return 0;
392} 389}
393 390
394static int mt9t031_get_chip_id(struct soc_camera_device *icd, 391static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
395 struct v4l2_dbg_chip_ident *id) 392 struct v4l2_dbg_chip_ident *id)
396{ 393{
397 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 394 struct i2c_client *client = sd->priv;
398 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 395 struct mt9t031 *mt9t031 = to_mt9t031(client);
399 396
400 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 397 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
401 return -EINVAL; 398 return -EINVAL;
@@ -410,10 +407,10 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd,
410} 407}
411 408
412#ifdef CONFIG_VIDEO_ADV_DEBUG 409#ifdef CONFIG_VIDEO_ADV_DEBUG
413static int mt9t031_get_register(struct soc_camera_device *icd, 410static int mt9t031_g_register(struct v4l2_subdev *sd,
414 struct v4l2_dbg_register *reg) 411 struct v4l2_dbg_register *reg)
415{ 412{
416 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 413 struct i2c_client *client = sd->priv;
417 414
418 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 415 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
419 return -EINVAL; 416 return -EINVAL;
@@ -429,10 +426,10 @@ static int mt9t031_get_register(struct soc_camera_device *icd,
429 return 0; 426 return 0;
430} 427}
431 428
432static int mt9t031_set_register(struct soc_camera_device *icd, 429static int mt9t031_s_register(struct v4l2_subdev *sd,
433 struct v4l2_dbg_register *reg) 430 struct v4l2_dbg_register *reg)
434{ 431{
435 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 432 struct i2c_client *client = sd->priv;
436 433
437 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 434 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
438 return -EINVAL; 435 return -EINVAL;
@@ -493,35 +490,20 @@ static const struct v4l2_queryctrl mt9t031_controls[] = {
493 } 490 }
494}; 491};
495 492
496static int mt9t031_get_control(struct soc_camera_device *, struct v4l2_control *);
497static int mt9t031_set_control(struct soc_camera_device *, struct v4l2_control *);
498
499static struct soc_camera_ops mt9t031_ops = { 493static struct soc_camera_ops mt9t031_ops = {
500 .owner = THIS_MODULE,
501 .init = mt9t031_init, 494 .init = mt9t031_init,
502 .release = mt9t031_release, 495 .release = mt9t031_release,
503 .start_capture = mt9t031_start_capture,
504 .stop_capture = mt9t031_stop_capture,
505 .set_crop = mt9t031_set_crop, 496 .set_crop = mt9t031_set_crop,
506 .set_fmt = mt9t031_set_fmt,
507 .try_fmt = mt9t031_try_fmt,
508 .set_bus_param = mt9t031_set_bus_param, 497 .set_bus_param = mt9t031_set_bus_param,
509 .query_bus_param = mt9t031_query_bus_param, 498 .query_bus_param = mt9t031_query_bus_param,
510 .controls = mt9t031_controls, 499 .controls = mt9t031_controls,
511 .num_controls = ARRAY_SIZE(mt9t031_controls), 500 .num_controls = ARRAY_SIZE(mt9t031_controls),
512 .get_control = mt9t031_get_control,
513 .set_control = mt9t031_set_control,
514 .get_chip_id = mt9t031_get_chip_id,
515#ifdef CONFIG_VIDEO_ADV_DEBUG
516 .get_register = mt9t031_get_register,
517 .set_register = mt9t031_set_register,
518#endif
519}; 501};
520 502
521static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 503static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
522{ 504{
523 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 505 struct i2c_client *client = sd->priv;
524 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 506 struct mt9t031 *mt9t031 = to_mt9t031(client);
525 int data; 507 int data;
526 508
527 switch (ctrl->id) { 509 switch (ctrl->id) {
@@ -544,10 +526,11 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro
544 return 0; 526 return 0;
545} 527}
546 528
547static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 529static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
548{ 530{
549 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 531 struct i2c_client *client = sd->priv;
550 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 532 struct mt9t031 *mt9t031 = to_mt9t031(client);
533 struct soc_camera_device *icd = client->dev.platform_data;
551 const struct v4l2_queryctrl *qctrl; 534 const struct v4l2_queryctrl *qctrl;
552 int data; 535 int data;
553 536
@@ -653,12 +636,11 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
653 636
654/* Interface active, can use i2c. If it fails, it can indeed mean, that 637/* Interface active, can use i2c. If it fails, it can indeed mean, that
655 * this wasn't our capture interface, so, we wait for the right one */ 638 * this wasn't our capture interface, so, we wait for the right one */
656static int mt9t031_video_probe(struct soc_camera_device *icd, 639static int mt9t031_video_probe(struct i2c_client *client)
657 struct i2c_client *client)
658{ 640{
659 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 641 struct soc_camera_device *icd = client->dev.platform_data;
642 struct mt9t031 *mt9t031 = to_mt9t031(client);
660 s32 data; 643 s32 data;
661 int ret;
662 644
663 /* We must have a parent by now. And it cannot be a wrong one. 645 /* We must have a parent by now. And it cannot be a wrong one.
664 * So this entire test is completely redundant. */ 646 * So this entire test is completely redundant. */
@@ -666,11 +648,6 @@ static int mt9t031_video_probe(struct soc_camera_device *icd,
666 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) 648 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
667 return -ENODEV; 649 return -ENODEV;
668 650
669 /* Switch master clock on */
670 ret = soc_camera_video_start(icd, &client->dev);
671 if (ret)
672 return ret;
673
674 /* Enable the chip */ 651 /* Enable the chip */
675 data = reg_write(client, MT9T031_CHIP_ENABLE, 1); 652 data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
676 dev_dbg(&icd->dev, "write: %d\n", data); 653 dev_dbg(&icd->dev, "write: %d\n", data);
@@ -678,8 +655,6 @@ static int mt9t031_video_probe(struct soc_camera_device *icd,
678 /* Read out the chip version register */ 655 /* Read out the chip version register */
679 data = reg_read(client, MT9T031_CHIP_VERSION); 656 data = reg_read(client, MT9T031_CHIP_VERSION);
680 657
681 soc_camera_video_stop(icd);
682
683 switch (data) { 658 switch (data) {
684 case 0x1621: 659 case 0x1621:
685 mt9t031->model = V4L2_IDENT_MT9T031; 660 mt9t031->model = V4L2_IDENT_MT9T031;
@@ -697,6 +672,27 @@ static int mt9t031_video_probe(struct soc_camera_device *icd,
697 return 0; 672 return 0;
698} 673}
699 674
675static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
676 .g_ctrl = mt9t031_g_ctrl,
677 .s_ctrl = mt9t031_s_ctrl,
678 .g_chip_ident = mt9t031_g_chip_ident,
679#ifdef CONFIG_VIDEO_ADV_DEBUG
680 .g_register = mt9t031_g_register,
681 .s_register = mt9t031_s_register,
682#endif
683};
684
685static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
686 .s_stream = mt9t031_s_stream,
687 .s_fmt = mt9t031_s_fmt,
688 .try_fmt = mt9t031_try_fmt,
689};
690
691static struct v4l2_subdev_ops mt9t031_subdev_ops = {
692 .core = &mt9t031_subdev_core_ops,
693 .video = &mt9t031_subdev_video_ops,
694};
695
700static int mt9t031_probe(struct i2c_client *client, 696static int mt9t031_probe(struct i2c_client *client,
701 const struct i2c_device_id *did) 697 const struct i2c_device_id *did)
702{ 698{
@@ -727,7 +723,7 @@ static int mt9t031_probe(struct i2c_client *client,
727 if (!mt9t031) 723 if (!mt9t031)
728 return -ENOMEM; 724 return -ENOMEM;
729 725
730 i2c_set_clientdata(client, mt9t031); 726 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
731 727
732 /* Second stage probe - when a capture adapter is there */ 728 /* Second stage probe - when a capture adapter is there */
733 icd->ops = &mt9t031_ops; 729 icd->ops = &mt9t031_ops;
@@ -747,7 +743,12 @@ static int mt9t031_probe(struct i2c_client *client,
747 mt9t031->xskip = 1; 743 mt9t031->xskip = 1;
748 mt9t031->yskip = 1; 744 mt9t031->yskip = 1;
749 745
750 ret = mt9t031_video_probe(icd, client); 746 mt9t031_idle(client);
747
748 ret = mt9t031_video_probe(client);
749
750 mt9t031_disable(client);
751
751 if (ret) { 752 if (ret) {
752 icd->ops = NULL; 753 icd->ops = NULL;
753 i2c_set_clientdata(client, NULL); 754 i2c_set_clientdata(client, NULL);
@@ -759,7 +760,7 @@ static int mt9t031_probe(struct i2c_client *client,
759 760
760static int mt9t031_remove(struct i2c_client *client) 761static int mt9t031_remove(struct i2c_client *client)
761{ 762{
762 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 763 struct mt9t031 *mt9t031 = to_mt9t031(client);
763 struct soc_camera_device *icd = client->dev.platform_data; 764 struct soc_camera_device *icd = client->dev.platform_data;
764 765
765 icd->ops = NULL; 766 icd->ops = NULL;