aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9m001.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/mt9m001.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/mt9m001.c')
-rw-r--r--drivers/media/video/mt9m001.c157
1 files changed, 68 insertions, 89 deletions
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 1e4f269fc08b..2a73dac11d37 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.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/* mt9m001 i2c address 0x5d 20/* mt9m001 i2c address 0x5d
21 * The platform has to define i2c_board_info 21 * The platform has to define ctruct i2c_board_info objects and link to them
22 * and call i2c_register_board_info() */ 22 * from struct soc_camera_link */
23 23
24/* mt9m001 selected register addresses */ 24/* mt9m001 selected register addresses */
25#define MT9M001_CHIP_VERSION 0x00 25#define MT9M001_CHIP_VERSION 0x00
@@ -69,10 +69,16 @@ static const struct soc_camera_data_format mt9m001_monochrome_formats[] = {
69}; 69};
70 70
71struct mt9m001 { 71struct mt9m001 {
72 struct v4l2_subdev subdev;
72 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ 73 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
73 unsigned char autoexposure; 74 unsigned char autoexposure;
74}; 75};
75 76
77static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
78{
79 return container_of(i2c_get_clientdata(client), struct mt9m001, subdev);
80}
81
76static int reg_read(struct i2c_client *client, const u8 reg) 82static int reg_read(struct i2c_client *client, const u8 reg)
77{ 83{
78 s32 data = i2c_smbus_read_word_data(client, reg); 84 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -110,32 +116,18 @@ static int reg_clear(struct i2c_client *client, const u8 reg,
110static int mt9m001_init(struct soc_camera_device *icd) 116static int mt9m001_init(struct soc_camera_device *icd)
111{ 117{
112 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 118 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
113 struct soc_camera_link *icl = to_soc_camera_link(icd);
114 int ret; 119 int ret;
115 120
116 dev_dbg(&icd->dev, "%s\n", __func__); 121 dev_dbg(&icd->dev, "%s\n", __func__);
117 122
118 if (icl->power) { 123 /*
119 ret = icl->power(&client->dev, 1); 124 * We don't know, whether platform provides reset,
120 if (ret < 0) { 125 * issue a soft reset too
121 dev_err(icd->vdev->parent, 126 */
122 "Platform failed to power-on the camera.\n"); 127 ret = reg_write(client, MT9M001_RESET, 1);
123 return ret; 128 if (!ret)
124 } 129 ret = reg_write(client, MT9M001_RESET, 0);
125 }
126
127 /* The camera could have been already on, we reset it additionally */
128 if (icl->reset)
129 ret = icl->reset(&client->dev);
130 else
131 ret = -ENODEV;
132 130
133 if (ret < 0) {
134 /* Either no platform reset, or platform reset failed */
135 ret = reg_write(client, MT9M001_RESET, 1);
136 if (!ret)
137 ret = reg_write(client, MT9M001_RESET, 0);
138 }
139 /* Disable chip, synchronous option update */ 131 /* Disable chip, synchronous option update */
140 if (!ret) 132 if (!ret)
141 ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0); 133 ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
@@ -146,33 +138,19 @@ static int mt9m001_init(struct soc_camera_device *icd)
146static int mt9m001_release(struct soc_camera_device *icd) 138static int mt9m001_release(struct soc_camera_device *icd)
147{ 139{
148 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 140 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
149 struct soc_camera_link *icl = to_soc_camera_link(icd);
150 141
151 /* Disable the chip */ 142 /* Disable the chip */
152 reg_write(client, MT9M001_OUTPUT_CONTROL, 0); 143 reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
153 144
154 if (icl->power)
155 icl->power(&client->dev, 0);
156
157 return 0; 145 return 0;
158} 146}
159 147
160static int mt9m001_start_capture(struct soc_camera_device *icd) 148static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
161{ 149{
162 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 150 struct i2c_client *client = sd->priv;
163 151
164 /* Switch to master "normal" mode */ 152 /* Switch to master "normal" mode or stop sensor readout */
165 if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0) 153 if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0)
166 return -EIO;
167 return 0;
168}
169
170static int mt9m001_stop_capture(struct soc_camera_device *icd)
171{
172 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
173
174 /* Stop sensor readout */
175 if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0)
176 return -EIO; 154 return -EIO;
177 return 0; 155 return 0;
178} 156}
@@ -220,7 +198,7 @@ static int mt9m001_set_crop(struct soc_camera_device *icd,
220 struct v4l2_rect *rect) 198 struct v4l2_rect *rect)
221{ 199{
222 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 200 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
223 struct mt9m001 *mt9m001 = i2c_get_clientdata(client); 201 struct mt9m001 *mt9m001 = to_mt9m001(client);
224 int ret; 202 int ret;
225 const u16 hblank = 9, vblank = 25; 203 const u16 hblank = 9, vblank = 25;
226 204
@@ -257,9 +235,10 @@ static int mt9m001_set_crop(struct soc_camera_device *icd,
257 return ret; 235 return ret;
258} 236}
259 237
260static int mt9m001_set_fmt(struct soc_camera_device *icd, 238static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
261 struct v4l2_format *f)
262{ 239{
240 struct i2c_client *client = sd->priv;
241 struct soc_camera_device *icd = client->dev.platform_data;
263 struct v4l2_rect rect = { 242 struct v4l2_rect rect = {
264 .left = icd->x_current, 243 .left = icd->x_current,
265 .top = icd->y_current, 244 .top = icd->y_current,
@@ -271,9 +250,10 @@ static int mt9m001_set_fmt(struct soc_camera_device *icd,
271 return mt9m001_set_crop(icd, &rect); 250 return mt9m001_set_crop(icd, &rect);
272} 251}
273 252
274static int mt9m001_try_fmt(struct soc_camera_device *icd, 253static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
275 struct v4l2_format *f)
276{ 254{
255 struct i2c_client *client = sd->priv;
256 struct soc_camera_device *icd = client->dev.platform_data;
277 struct v4l2_pix_format *pix = &f->fmt.pix; 257 struct v4l2_pix_format *pix = &f->fmt.pix;
278 258
279 v4l_bound_align_image(&pix->width, 48, 1280, 1, 259 v4l_bound_align_image(&pix->width, 48, 1280, 1,
@@ -283,11 +263,11 @@ static int mt9m001_try_fmt(struct soc_camera_device *icd,
283 return 0; 263 return 0;
284} 264}
285 265
286static int mt9m001_get_chip_id(struct soc_camera_device *icd, 266static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
287 struct v4l2_dbg_chip_ident *id) 267 struct v4l2_dbg_chip_ident *id)
288{ 268{
289 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 269 struct i2c_client *client = sd->priv;
290 struct mt9m001 *mt9m001 = i2c_get_clientdata(client); 270 struct mt9m001 *mt9m001 = to_mt9m001(client);
291 271
292 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 272 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
293 return -EINVAL; 273 return -EINVAL;
@@ -302,10 +282,10 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd,
302} 282}
303 283
304#ifdef CONFIG_VIDEO_ADV_DEBUG 284#ifdef CONFIG_VIDEO_ADV_DEBUG
305static int mt9m001_get_register(struct soc_camera_device *icd, 285static int mt9m001_g_register(struct v4l2_subdev *sd,
306 struct v4l2_dbg_register *reg) 286 struct v4l2_dbg_register *reg)
307{ 287{
308 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 288 struct i2c_client *client = sd->priv;
309 289
310 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 290 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
311 return -EINVAL; 291 return -EINVAL;
@@ -322,10 +302,10 @@ static int mt9m001_get_register(struct soc_camera_device *icd,
322 return 0; 302 return 0;
323} 303}
324 304
325static int mt9m001_set_register(struct soc_camera_device *icd, 305static int mt9m001_s_register(struct v4l2_subdev *sd,
326 struct v4l2_dbg_register *reg) 306 struct v4l2_dbg_register *reg)
327{ 307{
328 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 308 struct i2c_client *client = sd->priv;
329 309
330 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)
331 return -EINVAL; 311 return -EINVAL;
@@ -378,35 +358,20 @@ static const struct v4l2_queryctrl mt9m001_controls[] = {
378 } 358 }
379}; 359};
380 360
381static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *);
382static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *);
383
384static struct soc_camera_ops mt9m001_ops = { 361static struct soc_camera_ops mt9m001_ops = {
385 .owner = THIS_MODULE,
386 .init = mt9m001_init, 362 .init = mt9m001_init,
387 .release = mt9m001_release, 363 .release = mt9m001_release,
388 .start_capture = mt9m001_start_capture,
389 .stop_capture = mt9m001_stop_capture,
390 .set_crop = mt9m001_set_crop, 364 .set_crop = mt9m001_set_crop,
391 .set_fmt = mt9m001_set_fmt,
392 .try_fmt = mt9m001_try_fmt,
393 .set_bus_param = mt9m001_set_bus_param, 365 .set_bus_param = mt9m001_set_bus_param,
394 .query_bus_param = mt9m001_query_bus_param, 366 .query_bus_param = mt9m001_query_bus_param,
395 .controls = mt9m001_controls, 367 .controls = mt9m001_controls,
396 .num_controls = ARRAY_SIZE(mt9m001_controls), 368 .num_controls = ARRAY_SIZE(mt9m001_controls),
397 .get_control = mt9m001_get_control,
398 .set_control = mt9m001_set_control,
399 .get_chip_id = mt9m001_get_chip_id,
400#ifdef CONFIG_VIDEO_ADV_DEBUG
401 .get_register = mt9m001_get_register,
402 .set_register = mt9m001_set_register,
403#endif
404}; 369};
405 370
406static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 371static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
407{ 372{
408 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 373 struct i2c_client *client = sd->priv;
409 struct mt9m001 *mt9m001 = i2c_get_clientdata(client); 374 struct mt9m001 *mt9m001 = to_mt9m001(client);
410 int data; 375 int data;
411 376
412 switch (ctrl->id) { 377 switch (ctrl->id) {
@@ -423,10 +388,11 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro
423 return 0; 388 return 0;
424} 389}
425 390
426static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 391static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
427{ 392{
428 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 393 struct i2c_client *client = sd->priv;
429 struct mt9m001 *mt9m001 = i2c_get_clientdata(client); 394 struct mt9m001 *mt9m001 = to_mt9m001(client);
395 struct soc_camera_device *icd = client->dev.platform_data;
430 const struct v4l2_queryctrl *qctrl; 396 const struct v4l2_queryctrl *qctrl;
431 int data; 397 int data;
432 398
@@ -521,10 +487,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
521static int mt9m001_video_probe(struct soc_camera_device *icd, 487static int mt9m001_video_probe(struct soc_camera_device *icd,
522 struct i2c_client *client) 488 struct i2c_client *client)
523{ 489{
524 struct mt9m001 *mt9m001 = i2c_get_clientdata(client); 490 struct mt9m001 *mt9m001 = to_mt9m001(client);
525 struct soc_camera_link *icl = to_soc_camera_link(icd); 491 struct soc_camera_link *icl = to_soc_camera_link(icd);
526 s32 data; 492 s32 data;
527 int ret;
528 unsigned long flags; 493 unsigned long flags;
529 494
530 /* We must have a parent by now. And it cannot be a wrong one. 495 /* We must have a parent by now. And it cannot be a wrong one.
@@ -533,11 +498,6 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
533 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) 498 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
534 return -ENODEV; 499 return -ENODEV;
535 500
536 /* Switch master clock on */
537 ret = soc_camera_video_start(icd, &client->dev);
538 if (ret)
539 return ret;
540
541 /* Enable the chip */ 501 /* Enable the chip */
542 data = reg_write(client, MT9M001_CHIP_ENABLE, 1); 502 data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
543 dev_dbg(&icd->dev, "write: %d\n", data); 503 dev_dbg(&icd->dev, "write: %d\n", data);
@@ -545,8 +505,6 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
545 /* Read out the chip version register */ 505 /* Read out the chip version register */
546 data = reg_read(client, MT9M001_CHIP_VERSION); 506 data = reg_read(client, MT9M001_CHIP_VERSION);
547 507
548 soc_camera_video_stop(icd);
549
550 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ 508 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
551 switch (data) { 509 switch (data) {
552 case 0x8411: 510 case 0x8411:
@@ -601,6 +559,27 @@ static void mt9m001_video_remove(struct soc_camera_device *icd)
601 icl->free_bus(icl); 559 icl->free_bus(icl);
602} 560}
603 561
562static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
563 .g_ctrl = mt9m001_g_ctrl,
564 .s_ctrl = mt9m001_s_ctrl,
565 .g_chip_ident = mt9m001_g_chip_ident,
566#ifdef CONFIG_VIDEO_ADV_DEBUG
567 .g_register = mt9m001_g_register,
568 .s_register = mt9m001_s_register,
569#endif
570};
571
572static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
573 .s_stream = mt9m001_s_stream,
574 .s_fmt = mt9m001_s_fmt,
575 .try_fmt = mt9m001_try_fmt,
576};
577
578static struct v4l2_subdev_ops mt9m001_subdev_ops = {
579 .core = &mt9m001_subdev_core_ops,
580 .video = &mt9m001_subdev_video_ops,
581};
582
604static int mt9m001_probe(struct i2c_client *client, 583static int mt9m001_probe(struct i2c_client *client,
605 const struct i2c_device_id *did) 584 const struct i2c_device_id *did)
606{ 585{
@@ -631,7 +610,7 @@ static int mt9m001_probe(struct i2c_client *client,
631 if (!mt9m001) 610 if (!mt9m001)
632 return -ENOMEM; 611 return -ENOMEM;
633 612
634 i2c_set_clientdata(client, mt9m001); 613 v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
635 614
636 /* Second stage probe - when a capture adapter is there */ 615 /* Second stage probe - when a capture adapter is there */
637 icd->ops = &mt9m001_ops; 616 icd->ops = &mt9m001_ops;
@@ -660,7 +639,7 @@ static int mt9m001_probe(struct i2c_client *client,
660 639
661static int mt9m001_remove(struct i2c_client *client) 640static int mt9m001_remove(struct i2c_client *client)
662{ 641{
663 struct mt9m001 *mt9m001 = i2c_get_clientdata(client); 642 struct mt9m001 *mt9m001 = to_mt9m001(client);
664 struct soc_camera_device *icd = client->dev.platform_data; 643 struct soc_camera_device *icd = client->dev.platform_data;
665 644
666 icd->ops = NULL; 645 icd->ops = NULL;