aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9v022.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/mt9v022.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/mt9v022.c')
-rw-r--r--drivers/media/video/mt9v022.c167
1 files changed, 68 insertions, 99 deletions
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 959cc299f1ae..3cb9f0f1e256 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -14,13 +14,13 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/log2.h> 15#include <linux/log2.h>
16 16
17#include <media/v4l2-common.h> 17#include <media/v4l2-subdev.h>
18#include <media/v4l2-chip-ident.h> 18#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20 20
21/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c 21/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
22 * The platform has to define i2c_board_info 22 * The platform has to define ctruct i2c_board_info objects and link to them
23 * and call i2c_register_board_info() */ 23 * from struct soc_camera_link */
24 24
25static char *sensor_type; 25static char *sensor_type;
26module_param(sensor_type, charp, S_IRUGO); 26module_param(sensor_type, charp, S_IRUGO);
@@ -85,10 +85,16 @@ static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
85}; 85};
86 86
87struct mt9v022 { 87struct mt9v022 {
88 struct v4l2_subdev subdev;
88 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ 89 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
89 u16 chip_control; 90 u16 chip_control;
90}; 91};
91 92
93static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
94{
95 return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
96}
97
92static int reg_read(struct i2c_client *client, const u8 reg) 98static int reg_read(struct i2c_client *client, const u8 reg)
93{ 99{
94 s32 data = i2c_smbus_read_word_data(client, reg); 100 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -126,26 +132,9 @@ static int reg_clear(struct i2c_client *client, const u8 reg,
126static int mt9v022_init(struct soc_camera_device *icd) 132static int mt9v022_init(struct soc_camera_device *icd)
127{ 133{
128 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 134 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
129 struct soc_camera_link *icl = to_soc_camera_link(icd); 135 struct mt9v022 *mt9v022 = to_mt9v022(client);
130 struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
131 int ret; 136 int ret;
132 137
133 if (icl->power) {
134 ret = icl->power(&client->dev, 1);
135 if (ret < 0) {
136 dev_err(icd->vdev->parent,
137 "Platform failed to power-on the camera.\n");
138 return ret;
139 }
140 }
141
142 /*
143 * The camera could have been already on, we hard-reset it additionally,
144 * if available. Soft reset is done in video_probe().
145 */
146 if (icl->reset)
147 icl->reset(&client->dev);
148
149 /* Almost the default mode: master, parallel, simultaneous, and an 138 /* Almost the default mode: master, parallel, simultaneous, and an
150 * undocumented bit 0x200, which is present in table 7, but not in 8, 139 * undocumented bit 0x200, which is present in table 7, but not in 8,
151 * plus snapshot mode to disable scan for now */ 140 * plus snapshot mode to disable scan for now */
@@ -169,37 +158,19 @@ static int mt9v022_init(struct soc_camera_device *icd)
169 return ret; 158 return ret;
170} 159}
171 160
172static int mt9v022_release(struct soc_camera_device *icd) 161static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
173{ 162{
174 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 163 struct i2c_client *client = sd->priv;
175 struct soc_camera_link *icl = to_soc_camera_link(icd); 164 struct mt9v022 *mt9v022 = to_mt9v022(client);
176 165
177 if (icl->power) 166 if (enable)
178 icl->power(&client->dev, 0); 167 /* Switch to master "normal" mode */
179 168 mt9v022->chip_control &= ~0x10;
180 return 0; 169 else
181} 170 /* Switch to snapshot mode */
182 171 mt9v022->chip_control |= 0x10;
183static int mt9v022_start_capture(struct soc_camera_device *icd)
184{
185 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
186 struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
187 /* Switch to master "normal" mode */
188 mt9v022->chip_control &= ~0x10;
189 if (reg_write(client, MT9V022_CHIP_CONTROL,
190 mt9v022->chip_control) < 0)
191 return -EIO;
192 return 0;
193}
194 172
195static int mt9v022_stop_capture(struct soc_camera_device *icd) 173 if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
196{
197 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
198 struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
199 /* Switch to snapshot mode */
200 mt9v022->chip_control |= 0x10;
201 if (reg_write(client, MT9V022_CHIP_CONTROL,
202 mt9v022->chip_control) < 0)
203 return -EIO; 174 return -EIO;
204 return 0; 175 return 0;
205} 176}
@@ -208,7 +179,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
208 unsigned long flags) 179 unsigned long flags)
209{ 180{
210 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 181 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
211 struct mt9v022 *mt9v022 = i2c_get_clientdata(client); 182 struct mt9v022 *mt9v022 = to_mt9v022(client);
212 struct soc_camera_link *icl = to_soc_camera_link(icd); 183 struct soc_camera_link *icl = to_soc_camera_link(icd);
213 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; 184 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
214 int ret; 185 int ret;
@@ -320,11 +291,11 @@ static int mt9v022_set_crop(struct soc_camera_device *icd,
320 return 0; 291 return 0;
321} 292}
322 293
323static int mt9v022_set_fmt(struct soc_camera_device *icd, 294static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
324 struct v4l2_format *f)
325{ 295{
326 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 296 struct i2c_client *client = sd->priv;
327 struct mt9v022 *mt9v022 = i2c_get_clientdata(client); 297 struct mt9v022 *mt9v022 = to_mt9v022(client);
298 struct soc_camera_device *icd = client->dev.platform_data;
328 struct v4l2_pix_format *pix = &f->fmt.pix; 299 struct v4l2_pix_format *pix = &f->fmt.pix;
329 struct v4l2_rect rect = { 300 struct v4l2_rect rect = {
330 .left = icd->x_current, 301 .left = icd->x_current,
@@ -357,9 +328,10 @@ static int mt9v022_set_fmt(struct soc_camera_device *icd,
357 return mt9v022_set_crop(icd, &rect); 328 return mt9v022_set_crop(icd, &rect);
358} 329}
359 330
360static int mt9v022_try_fmt(struct soc_camera_device *icd, 331static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
361 struct v4l2_format *f)
362{ 332{
333 struct i2c_client *client = sd->priv;
334 struct soc_camera_device *icd = client->dev.platform_data;
363 struct v4l2_pix_format *pix = &f->fmt.pix; 335 struct v4l2_pix_format *pix = &f->fmt.pix;
364 336
365 v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */, 337 v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */,
@@ -369,11 +341,11 @@ static int mt9v022_try_fmt(struct soc_camera_device *icd,
369 return 0; 341 return 0;
370} 342}
371 343
372static int mt9v022_get_chip_id(struct soc_camera_device *icd, 344static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
373 struct v4l2_dbg_chip_ident *id) 345 struct v4l2_dbg_chip_ident *id)
374{ 346{
375 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 347 struct i2c_client *client = sd->priv;
376 struct mt9v022 *mt9v022 = i2c_get_clientdata(client); 348 struct mt9v022 *mt9v022 = to_mt9v022(client);
377 349
378 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 350 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
379 return -EINVAL; 351 return -EINVAL;
@@ -388,10 +360,10 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd,
388} 360}
389 361
390#ifdef CONFIG_VIDEO_ADV_DEBUG 362#ifdef CONFIG_VIDEO_ADV_DEBUG
391static int mt9v022_get_register(struct soc_camera_device *icd, 363static int mt9v022_g_register(struct v4l2_subdev *sd,
392 struct v4l2_dbg_register *reg) 364 struct v4l2_dbg_register *reg)
393{ 365{
394 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 366 struct i2c_client *client = sd->priv;
395 367
396 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 368 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
397 return -EINVAL; 369 return -EINVAL;
@@ -408,10 +380,10 @@ static int mt9v022_get_register(struct soc_camera_device *icd,
408 return 0; 380 return 0;
409} 381}
410 382
411static int mt9v022_set_register(struct soc_camera_device *icd, 383static int mt9v022_s_register(struct v4l2_subdev *sd,
412 struct v4l2_dbg_register *reg) 384 struct v4l2_dbg_register *reg)
413{ 385{
414 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 386 struct i2c_client *client = sd->priv;
415 387
416 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 388 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
417 return -EINVAL; 389 return -EINVAL;
@@ -480,35 +452,18 @@ static const struct v4l2_queryctrl mt9v022_controls[] = {
480 } 452 }
481}; 453};
482 454
483static int mt9v022_get_control(struct soc_camera_device *, struct v4l2_control *);
484static int mt9v022_set_control(struct soc_camera_device *, struct v4l2_control *);
485
486static struct soc_camera_ops mt9v022_ops = { 455static struct soc_camera_ops mt9v022_ops = {
487 .owner = THIS_MODULE,
488 .init = mt9v022_init, 456 .init = mt9v022_init,
489 .release = mt9v022_release,
490 .start_capture = mt9v022_start_capture,
491 .stop_capture = mt9v022_stop_capture,
492 .set_crop = mt9v022_set_crop, 457 .set_crop = mt9v022_set_crop,
493 .set_fmt = mt9v022_set_fmt,
494 .try_fmt = mt9v022_try_fmt,
495 .set_bus_param = mt9v022_set_bus_param, 458 .set_bus_param = mt9v022_set_bus_param,
496 .query_bus_param = mt9v022_query_bus_param, 459 .query_bus_param = mt9v022_query_bus_param,
497 .controls = mt9v022_controls, 460 .controls = mt9v022_controls,
498 .num_controls = ARRAY_SIZE(mt9v022_controls), 461 .num_controls = ARRAY_SIZE(mt9v022_controls),
499 .get_control = mt9v022_get_control,
500 .set_control = mt9v022_set_control,
501 .get_chip_id = mt9v022_get_chip_id,
502#ifdef CONFIG_VIDEO_ADV_DEBUG
503 .get_register = mt9v022_get_register,
504 .set_register = mt9v022_set_register,
505#endif
506}; 462};
507 463
508static int mt9v022_get_control(struct soc_camera_device *icd, 464static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
509 struct v4l2_control *ctrl)
510{ 465{
511 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 466 struct i2c_client *client = sd->priv;
512 int data; 467 int data;
513 468
514 switch (ctrl->id) { 469 switch (ctrl->id) {
@@ -540,15 +495,14 @@ static int mt9v022_get_control(struct soc_camera_device *icd,
540 return 0; 495 return 0;
541} 496}
542 497
543static int mt9v022_set_control(struct soc_camera_device *icd, 498static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
544 struct v4l2_control *ctrl)
545{ 499{
546 int data; 500 int data;
547 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 501 struct i2c_client *client = sd->priv;
502 struct soc_camera_device *icd = client->dev.platform_data;
548 const struct v4l2_queryctrl *qctrl; 503 const struct v4l2_queryctrl *qctrl;
549 504
550 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); 505 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
551
552 if (!qctrl) 506 if (!qctrl)
553 return -EINVAL; 507 return -EINVAL;
554 508
@@ -644,7 +598,7 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
644static int mt9v022_video_probe(struct soc_camera_device *icd, 598static int mt9v022_video_probe(struct soc_camera_device *icd,
645 struct i2c_client *client) 599 struct i2c_client *client)
646{ 600{
647 struct mt9v022 *mt9v022 = i2c_get_clientdata(client); 601 struct mt9v022 *mt9v022 = to_mt9v022(client);
648 struct soc_camera_link *icl = to_soc_camera_link(icd); 602 struct soc_camera_link *icl = to_soc_camera_link(icd);
649 s32 data; 603 s32 data;
650 int ret; 604 int ret;
@@ -654,11 +608,6 @@ static int mt9v022_video_probe(struct soc_camera_device *icd,
654 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) 608 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
655 return -ENODEV; 609 return -ENODEV;
656 610
657 /* Switch master clock on */
658 ret = soc_camera_video_start(icd, &client->dev);
659 if (ret)
660 return ret;
661
662 /* Read out the chip version register */ 611 /* Read out the chip version register */
663 data = reg_read(client, MT9V022_CHIP_VERSION); 612 data = reg_read(client, MT9V022_CHIP_VERSION);
664 613
@@ -723,8 +672,6 @@ static int mt9v022_video_probe(struct soc_camera_device *icd,
723 "monochrome" : "colour"); 672 "monochrome" : "colour");
724 673
725ei2c: 674ei2c:
726 soc_camera_video_stop(icd);
727
728 return ret; 675 return ret;
729} 676}
730 677
@@ -739,6 +686,27 @@ static void mt9v022_video_remove(struct soc_camera_device *icd)
739 icl->free_bus(icl); 686 icl->free_bus(icl);
740} 687}
741 688
689static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
690 .g_ctrl = mt9v022_g_ctrl,
691 .s_ctrl = mt9v022_s_ctrl,
692 .g_chip_ident = mt9v022_g_chip_ident,
693#ifdef CONFIG_VIDEO_ADV_DEBUG
694 .g_register = mt9v022_g_register,
695 .s_register = mt9v022_s_register,
696#endif
697};
698
699static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
700 .s_stream = mt9v022_s_stream,
701 .s_fmt = mt9v022_s_fmt,
702 .try_fmt = mt9v022_try_fmt,
703};
704
705static struct v4l2_subdev_ops mt9v022_subdev_ops = {
706 .core = &mt9v022_subdev_core_ops,
707 .video = &mt9v022_subdev_video_ops,
708};
709
742static int mt9v022_probe(struct i2c_client *client, 710static int mt9v022_probe(struct i2c_client *client,
743 const struct i2c_device_id *did) 711 const struct i2c_device_id *did)
744{ 712{
@@ -769,8 +737,9 @@ static int mt9v022_probe(struct i2c_client *client,
769 if (!mt9v022) 737 if (!mt9v022)
770 return -ENOMEM; 738 return -ENOMEM;
771 739
740 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
741
772 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; 742 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
773 i2c_set_clientdata(client, mt9v022);
774 743
775 icd->ops = &mt9v022_ops; 744 icd->ops = &mt9v022_ops;
776 icd->x_min = 1; 745 icd->x_min = 1;
@@ -795,7 +764,7 @@ static int mt9v022_probe(struct i2c_client *client,
795 764
796static int mt9v022_remove(struct i2c_client *client) 765static int mt9v022_remove(struct i2c_client *client)
797{ 766{
798 struct mt9v022 *mt9v022 = i2c_get_clientdata(client); 767 struct mt9v022 *mt9v022 = to_mt9v022(client);
799 struct soc_camera_device *icd = client->dev.platform_data; 768 struct soc_camera_device *icd = client->dev.platform_data;
800 769
801 icd->ops = NULL; 770 icd->ops = NULL;