diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-08-25 10:43:33 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-18 23:18:35 -0400 |
commit | 979ea1ddf80ac7383acdea03471355ca62702539 (patch) | |
tree | 2ee4c73eb672c1ee8167ed7e0906bac6f3b00e69 /drivers/media/video/mt9m111.c | |
parent | 0bab829de1ab60d8c3cbf7e402192bb9446840b7 (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/mt9m111.c')
-rw-r--r-- | drivers/media/video/mt9m111.c | 309 |
1 files changed, 129 insertions, 180 deletions
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 95c2f089605f..29f976afd465 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -148,6 +148,7 @@ enum mt9m111_context { | |||
148 | }; | 148 | }; |
149 | 149 | ||
150 | struct mt9m111 { | 150 | struct mt9m111 { |
151 | struct v4l2_subdev subdev; | ||
151 | int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ | 152 | int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ |
152 | enum mt9m111_context context; | 153 | enum mt9m111_context context; |
153 | struct v4l2_rect rect; | 154 | struct v4l2_rect rect; |
@@ -164,6 +165,11 @@ struct mt9m111 { | |||
164 | unsigned int autowhitebalance:1; | 165 | unsigned int autowhitebalance:1; |
165 | }; | 166 | }; |
166 | 167 | ||
168 | static struct mt9m111 *to_mt9m111(const struct i2c_client *client) | ||
169 | { | ||
170 | return container_of(i2c_get_clientdata(client), struct mt9m111, subdev); | ||
171 | } | ||
172 | |||
167 | static int reg_page_map_set(struct i2c_client *client, const u16 reg) | 173 | static int reg_page_map_set(struct i2c_client *client, const u16 reg) |
168 | { | 174 | { |
169 | int ret; | 175 | int ret; |
@@ -227,10 +233,9 @@ static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg, | |||
227 | return mt9m111_reg_write(client, reg, ret & ~data); | 233 | return mt9m111_reg_write(client, reg, ret & ~data); |
228 | } | 234 | } |
229 | 235 | ||
230 | static int mt9m111_set_context(struct soc_camera_device *icd, | 236 | static int mt9m111_set_context(struct i2c_client *client, |
231 | enum mt9m111_context ctxt) | 237 | enum mt9m111_context ctxt) |
232 | { | 238 | { |
233 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
234 | int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B | 239 | int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B |
235 | | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B | 240 | | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B |
236 | | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B | 241 | | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B |
@@ -244,11 +249,10 @@ static int mt9m111_set_context(struct soc_camera_device *icd, | |||
244 | return reg_write(CONTEXT_CONTROL, valA); | 249 | return reg_write(CONTEXT_CONTROL, valA); |
245 | } | 250 | } |
246 | 251 | ||
247 | static int mt9m111_setup_rect(struct soc_camera_device *icd, | 252 | static int mt9m111_setup_rect(struct i2c_client *client, |
248 | struct v4l2_rect *rect) | 253 | struct v4l2_rect *rect) |
249 | { | 254 | { |
250 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 255 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
251 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
252 | int ret, is_raw_format; | 256 | int ret, is_raw_format; |
253 | int width = rect->width; | 257 | int width = rect->width; |
254 | int height = rect->height; | 258 | int height = rect->height; |
@@ -290,9 +294,8 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd, | |||
290 | return ret; | 294 | return ret; |
291 | } | 295 | } |
292 | 296 | ||
293 | static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) | 297 | static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt) |
294 | { | 298 | { |
295 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
296 | int ret; | 299 | int ret; |
297 | 300 | ||
298 | ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); | 301 | ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); |
@@ -301,20 +304,19 @@ static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) | |||
301 | return ret; | 304 | return ret; |
302 | } | 305 | } |
303 | 306 | ||
304 | static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) | 307 | static int mt9m111_setfmt_bayer8(struct i2c_client *client) |
305 | { | 308 | { |
306 | return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER); | 309 | return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER); |
307 | } | 310 | } |
308 | 311 | ||
309 | static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) | 312 | static int mt9m111_setfmt_bayer10(struct i2c_client *client) |
310 | { | 313 | { |
311 | return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); | 314 | return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_BYPASS_IFP); |
312 | } | 315 | } |
313 | 316 | ||
314 | static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) | 317 | static int mt9m111_setfmt_rgb565(struct i2c_client *client) |
315 | { | 318 | { |
316 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 319 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
317 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
318 | int val = 0; | 320 | int val = 0; |
319 | 321 | ||
320 | if (mt9m111->swap_rgb_red_blue) | 322 | if (mt9m111->swap_rgb_red_blue) |
@@ -323,13 +325,12 @@ static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) | |||
323 | val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; | 325 | val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; |
324 | val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; | 326 | val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; |
325 | 327 | ||
326 | return mt9m111_setup_pixfmt(icd, val); | 328 | return mt9m111_setup_pixfmt(client, val); |
327 | } | 329 | } |
328 | 330 | ||
329 | static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) | 331 | static int mt9m111_setfmt_rgb555(struct i2c_client *client) |
330 | { | 332 | { |
331 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 333 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
332 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
333 | int val = 0; | 334 | int val = 0; |
334 | 335 | ||
335 | if (mt9m111->swap_rgb_red_blue) | 336 | if (mt9m111->swap_rgb_red_blue) |
@@ -338,13 +339,12 @@ static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) | |||
338 | val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; | 339 | val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; |
339 | val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; | 340 | val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; |
340 | 341 | ||
341 | return mt9m111_setup_pixfmt(icd, val); | 342 | return mt9m111_setup_pixfmt(client, val); |
342 | } | 343 | } |
343 | 344 | ||
344 | static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) | 345 | static int mt9m111_setfmt_yuv(struct i2c_client *client) |
345 | { | 346 | { |
346 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 347 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
347 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
348 | int val = 0; | 348 | int val = 0; |
349 | 349 | ||
350 | if (mt9m111->swap_yuv_cb_cr) | 350 | if (mt9m111->swap_yuv_cb_cr) |
@@ -352,52 +352,22 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) | |||
352 | if (mt9m111->swap_yuv_y_chromas) | 352 | if (mt9m111->swap_yuv_y_chromas) |
353 | val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; | 353 | val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; |
354 | 354 | ||
355 | return mt9m111_setup_pixfmt(icd, val); | 355 | return mt9m111_setup_pixfmt(client, val); |
356 | } | 356 | } |
357 | 357 | ||
358 | static int mt9m111_enable(struct soc_camera_device *icd) | 358 | static int mt9m111_enable(struct i2c_client *client) |
359 | { | 359 | { |
360 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 360 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
361 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
362 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
363 | int ret; | 361 | int ret; |
364 | 362 | ||
365 | if (icl->power) { | ||
366 | ret = icl->power(&client->dev, 1); | ||
367 | if (ret < 0) { | ||
368 | dev_err(icd->vdev->parent, | ||
369 | "Platform failed to power-on the camera.\n"); | ||
370 | return ret; | ||
371 | } | ||
372 | } | ||
373 | |||
374 | ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); | 363 | ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); |
375 | if (!ret) | 364 | if (!ret) |
376 | mt9m111->powered = 1; | 365 | mt9m111->powered = 1; |
377 | return ret; | 366 | return ret; |
378 | } | 367 | } |
379 | 368 | ||
380 | static int mt9m111_disable(struct soc_camera_device *icd) | 369 | static int mt9m111_reset(struct i2c_client *client) |
381 | { | ||
382 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
383 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
384 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
385 | int ret; | ||
386 | |||
387 | ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); | ||
388 | if (!ret) | ||
389 | mt9m111->powered = 0; | ||
390 | |||
391 | if (icl->power) | ||
392 | icl->power(&client->dev, 0); | ||
393 | |||
394 | return ret; | ||
395 | } | ||
396 | |||
397 | static int mt9m111_reset(struct soc_camera_device *icd) | ||
398 | { | 370 | { |
399 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
400 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
401 | int ret; | 371 | int ret; |
402 | 372 | ||
403 | ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); | 373 | ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); |
@@ -407,22 +377,9 @@ static int mt9m111_reset(struct soc_camera_device *icd) | |||
407 | ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE | 377 | ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE |
408 | | MT9M111_RESET_RESET_SOC); | 378 | | MT9M111_RESET_RESET_SOC); |
409 | 379 | ||
410 | if (icl->reset) | ||
411 | icl->reset(&client->dev); | ||
412 | |||
413 | return ret; | 380 | return ret; |
414 | } | 381 | } |
415 | 382 | ||
416 | static int mt9m111_start_capture(struct soc_camera_device *icd) | ||
417 | { | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | static int mt9m111_stop_capture(struct soc_camera_device *icd) | ||
422 | { | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) | 383 | static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) |
427 | { | 384 | { |
428 | struct soc_camera_link *icl = to_soc_camera_link(icd); | 385 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
@@ -442,60 +399,59 @@ static int mt9m111_set_crop(struct soc_camera_device *icd, | |||
442 | struct v4l2_rect *rect) | 399 | struct v4l2_rect *rect) |
443 | { | 400 | { |
444 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 401 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
445 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 402 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
446 | int ret; | 403 | int ret; |
447 | 404 | ||
448 | dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n", | 405 | dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n", |
449 | __func__, rect->left, rect->top, rect->width, | 406 | __func__, rect->left, rect->top, rect->width, |
450 | rect->height); | 407 | rect->height); |
451 | 408 | ||
452 | ret = mt9m111_setup_rect(icd, rect); | 409 | ret = mt9m111_setup_rect(client, rect); |
453 | if (!ret) | 410 | if (!ret) |
454 | mt9m111->rect = *rect; | 411 | mt9m111->rect = *rect; |
455 | return ret; | 412 | return ret; |
456 | } | 413 | } |
457 | 414 | ||
458 | static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) | 415 | static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt) |
459 | { | 416 | { |
460 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 417 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
461 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
462 | int ret; | 418 | int ret; |
463 | 419 | ||
464 | switch (pixfmt) { | 420 | switch (pixfmt) { |
465 | case V4L2_PIX_FMT_SBGGR8: | 421 | case V4L2_PIX_FMT_SBGGR8: |
466 | ret = mt9m111_setfmt_bayer8(icd); | 422 | ret = mt9m111_setfmt_bayer8(client); |
467 | break; | 423 | break; |
468 | case V4L2_PIX_FMT_SBGGR16: | 424 | case V4L2_PIX_FMT_SBGGR16: |
469 | ret = mt9m111_setfmt_bayer10(icd); | 425 | ret = mt9m111_setfmt_bayer10(client); |
470 | break; | 426 | break; |
471 | case V4L2_PIX_FMT_RGB555: | 427 | case V4L2_PIX_FMT_RGB555: |
472 | ret = mt9m111_setfmt_rgb555(icd); | 428 | ret = mt9m111_setfmt_rgb555(client); |
473 | break; | 429 | break; |
474 | case V4L2_PIX_FMT_RGB565: | 430 | case V4L2_PIX_FMT_RGB565: |
475 | ret = mt9m111_setfmt_rgb565(icd); | 431 | ret = mt9m111_setfmt_rgb565(client); |
476 | break; | 432 | break; |
477 | case V4L2_PIX_FMT_UYVY: | 433 | case V4L2_PIX_FMT_UYVY: |
478 | mt9m111->swap_yuv_y_chromas = 0; | 434 | mt9m111->swap_yuv_y_chromas = 0; |
479 | mt9m111->swap_yuv_cb_cr = 0; | 435 | mt9m111->swap_yuv_cb_cr = 0; |
480 | ret = mt9m111_setfmt_yuv(icd); | 436 | ret = mt9m111_setfmt_yuv(client); |
481 | break; | 437 | break; |
482 | case V4L2_PIX_FMT_VYUY: | 438 | case V4L2_PIX_FMT_VYUY: |
483 | mt9m111->swap_yuv_y_chromas = 0; | 439 | mt9m111->swap_yuv_y_chromas = 0; |
484 | mt9m111->swap_yuv_cb_cr = 1; | 440 | mt9m111->swap_yuv_cb_cr = 1; |
485 | ret = mt9m111_setfmt_yuv(icd); | 441 | ret = mt9m111_setfmt_yuv(client); |
486 | break; | 442 | break; |
487 | case V4L2_PIX_FMT_YUYV: | 443 | case V4L2_PIX_FMT_YUYV: |
488 | mt9m111->swap_yuv_y_chromas = 1; | 444 | mt9m111->swap_yuv_y_chromas = 1; |
489 | mt9m111->swap_yuv_cb_cr = 0; | 445 | mt9m111->swap_yuv_cb_cr = 0; |
490 | ret = mt9m111_setfmt_yuv(icd); | 446 | ret = mt9m111_setfmt_yuv(client); |
491 | break; | 447 | break; |
492 | case V4L2_PIX_FMT_YVYU: | 448 | case V4L2_PIX_FMT_YVYU: |
493 | mt9m111->swap_yuv_y_chromas = 1; | 449 | mt9m111->swap_yuv_y_chromas = 1; |
494 | mt9m111->swap_yuv_cb_cr = 1; | 450 | mt9m111->swap_yuv_cb_cr = 1; |
495 | ret = mt9m111_setfmt_yuv(icd); | 451 | ret = mt9m111_setfmt_yuv(client); |
496 | break; | 452 | break; |
497 | default: | 453 | default: |
498 | dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt); | 454 | dev_err(&client->dev, "Pixel format not handled : %x\n", pixfmt); |
499 | ret = -EINVAL; | 455 | ret = -EINVAL; |
500 | } | 456 | } |
501 | 457 | ||
@@ -505,11 +461,10 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) | |||
505 | return ret; | 461 | return ret; |
506 | } | 462 | } |
507 | 463 | ||
508 | static int mt9m111_set_fmt(struct soc_camera_device *icd, | 464 | static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) |
509 | struct v4l2_format *f) | ||
510 | { | 465 | { |
511 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 466 | struct i2c_client *client = sd->priv; |
512 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 467 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
513 | struct v4l2_pix_format *pix = &f->fmt.pix; | 468 | struct v4l2_pix_format *pix = &f->fmt.pix; |
514 | struct v4l2_rect rect = { | 469 | struct v4l2_rect rect = { |
515 | .left = mt9m111->rect.left, | 470 | .left = mt9m111->rect.left, |
@@ -519,20 +474,19 @@ static int mt9m111_set_fmt(struct soc_camera_device *icd, | |||
519 | }; | 474 | }; |
520 | int ret; | 475 | int ret; |
521 | 476 | ||
522 | dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", | 477 | dev_dbg(&client->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", |
523 | __func__, pix->pixelformat, rect.left, rect.top, rect.width, | 478 | __func__, pix->pixelformat, rect.left, rect.top, rect.width, |
524 | rect.height); | 479 | rect.height); |
525 | 480 | ||
526 | ret = mt9m111_setup_rect(icd, &rect); | 481 | ret = mt9m111_setup_rect(client, &rect); |
527 | if (!ret) | 482 | if (!ret) |
528 | ret = mt9m111_set_pixfmt(icd, pix->pixelformat); | 483 | ret = mt9m111_set_pixfmt(client, pix->pixelformat); |
529 | if (!ret) | 484 | if (!ret) |
530 | mt9m111->rect = rect; | 485 | mt9m111->rect = rect; |
531 | return ret; | 486 | return ret; |
532 | } | 487 | } |
533 | 488 | ||
534 | static int mt9m111_try_fmt(struct soc_camera_device *icd, | 489 | static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) |
535 | struct v4l2_format *f) | ||
536 | { | 490 | { |
537 | struct v4l2_pix_format *pix = &f->fmt.pix; | 491 | struct v4l2_pix_format *pix = &f->fmt.pix; |
538 | 492 | ||
@@ -544,11 +498,11 @@ static int mt9m111_try_fmt(struct soc_camera_device *icd, | |||
544 | return 0; | 498 | return 0; |
545 | } | 499 | } |
546 | 500 | ||
547 | static int mt9m111_get_chip_id(struct soc_camera_device *icd, | 501 | static int mt9m111_g_chip_ident(struct v4l2_subdev *sd, |
548 | struct v4l2_dbg_chip_ident *id) | 502 | struct v4l2_dbg_chip_ident *id) |
549 | { | 503 | { |
550 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 504 | struct i2c_client *client = sd->priv; |
551 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 505 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
552 | 506 | ||
553 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) | 507 | if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) |
554 | return -EINVAL; | 508 | return -EINVAL; |
@@ -563,10 +517,10 @@ static int mt9m111_get_chip_id(struct soc_camera_device *icd, | |||
563 | } | 517 | } |
564 | 518 | ||
565 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 519 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
566 | static int mt9m111_get_register(struct soc_camera_device *icd, | 520 | static int mt9m111_g_register(struct v4l2_subdev *sd, |
567 | struct v4l2_dbg_register *reg) | 521 | struct v4l2_dbg_register *reg) |
568 | { | 522 | { |
569 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 523 | struct i2c_client *client = sd->priv; |
570 | int val; | 524 | int val; |
571 | 525 | ||
572 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 526 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
@@ -584,10 +538,10 @@ static int mt9m111_get_register(struct soc_camera_device *icd, | |||
584 | return 0; | 538 | return 0; |
585 | } | 539 | } |
586 | 540 | ||
587 | static int mt9m111_set_register(struct soc_camera_device *icd, | 541 | static int mt9m111_s_register(struct v4l2_subdev *sd, |
588 | struct v4l2_dbg_register *reg) | 542 | struct v4l2_dbg_register *reg) |
589 | { | 543 | { |
590 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 544 | struct i2c_client *client = sd->priv; |
591 | 545 | ||
592 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) | 546 | if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) |
593 | return -EINVAL; | 547 | return -EINVAL; |
@@ -639,41 +593,24 @@ static const struct v4l2_queryctrl mt9m111_controls[] = { | |||
639 | } | 593 | } |
640 | }; | 594 | }; |
641 | 595 | ||
642 | static int mt9m111_get_control(struct soc_camera_device *, | ||
643 | struct v4l2_control *); | ||
644 | static int mt9m111_set_control(struct soc_camera_device *, | ||
645 | struct v4l2_control *); | ||
646 | static int mt9m111_resume(struct soc_camera_device *icd); | 596 | static int mt9m111_resume(struct soc_camera_device *icd); |
647 | static int mt9m111_init(struct soc_camera_device *icd); | 597 | static int mt9m111_init(struct soc_camera_device *icd); |
648 | static int mt9m111_release(struct soc_camera_device *icd); | 598 | static int mt9m111_release(struct soc_camera_device *icd); |
649 | 599 | ||
650 | static struct soc_camera_ops mt9m111_ops = { | 600 | static struct soc_camera_ops mt9m111_ops = { |
651 | .owner = THIS_MODULE, | ||
652 | .init = mt9m111_init, | 601 | .init = mt9m111_init, |
653 | .resume = mt9m111_resume, | 602 | .resume = mt9m111_resume, |
654 | .release = mt9m111_release, | 603 | .release = mt9m111_release, |
655 | .start_capture = mt9m111_start_capture, | ||
656 | .stop_capture = mt9m111_stop_capture, | ||
657 | .set_crop = mt9m111_set_crop, | 604 | .set_crop = mt9m111_set_crop, |
658 | .set_fmt = mt9m111_set_fmt, | ||
659 | .try_fmt = mt9m111_try_fmt, | ||
660 | .query_bus_param = mt9m111_query_bus_param, | 605 | .query_bus_param = mt9m111_query_bus_param, |
661 | .set_bus_param = mt9m111_set_bus_param, | 606 | .set_bus_param = mt9m111_set_bus_param, |
662 | .controls = mt9m111_controls, | 607 | .controls = mt9m111_controls, |
663 | .num_controls = ARRAY_SIZE(mt9m111_controls), | 608 | .num_controls = ARRAY_SIZE(mt9m111_controls), |
664 | .get_control = mt9m111_get_control, | ||
665 | .set_control = mt9m111_set_control, | ||
666 | .get_chip_id = mt9m111_get_chip_id, | ||
667 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
668 | .get_register = mt9m111_get_register, | ||
669 | .set_register = mt9m111_set_register, | ||
670 | #endif | ||
671 | }; | 609 | }; |
672 | 610 | ||
673 | static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) | 611 | static int mt9m111_set_flip(struct i2c_client *client, int flip, int mask) |
674 | { | 612 | { |
675 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 613 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
676 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
677 | int ret; | 614 | int ret; |
678 | 615 | ||
679 | if (mt9m111->context == HIGHPOWER) { | 616 | if (mt9m111->context == HIGHPOWER) { |
@@ -691,9 +628,8 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) | |||
691 | return ret; | 628 | return ret; |
692 | } | 629 | } |
693 | 630 | ||
694 | static int mt9m111_get_global_gain(struct soc_camera_device *icd) | 631 | static int mt9m111_get_global_gain(struct i2c_client *client) |
695 | { | 632 | { |
696 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
697 | int data; | 633 | int data; |
698 | 634 | ||
699 | data = reg_read(GLOBAL_GAIN); | 635 | data = reg_read(GLOBAL_GAIN); |
@@ -703,9 +639,9 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd) | |||
703 | return data; | 639 | return data; |
704 | } | 640 | } |
705 | 641 | ||
706 | static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) | 642 | static int mt9m111_set_global_gain(struct i2c_client *client, int gain) |
707 | { | 643 | { |
708 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 644 | struct soc_camera_device *icd = client->dev.platform_data; |
709 | u16 val; | 645 | u16 val; |
710 | 646 | ||
711 | if (gain > 63 * 2 * 2) | 647 | if (gain > 63 * 2 * 2) |
@@ -722,10 +658,9 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) | |||
722 | return reg_write(GLOBAL_GAIN, val); | 658 | return reg_write(GLOBAL_GAIN, val); |
723 | } | 659 | } |
724 | 660 | ||
725 | static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) | 661 | static int mt9m111_set_autoexposure(struct i2c_client *client, int on) |
726 | { | 662 | { |
727 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 663 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
728 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
729 | int ret; | 664 | int ret; |
730 | 665 | ||
731 | if (on) | 666 | if (on) |
@@ -739,10 +674,9 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) | |||
739 | return ret; | 674 | return ret; |
740 | } | 675 | } |
741 | 676 | ||
742 | static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) | 677 | static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on) |
743 | { | 678 | { |
744 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 679 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
745 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | ||
746 | int ret; | 680 | int ret; |
747 | 681 | ||
748 | if (on) | 682 | if (on) |
@@ -756,11 +690,10 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) | |||
756 | return ret; | 690 | return ret; |
757 | } | 691 | } |
758 | 692 | ||
759 | static int mt9m111_get_control(struct soc_camera_device *icd, | 693 | static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
760 | struct v4l2_control *ctrl) | ||
761 | { | 694 | { |
762 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 695 | struct i2c_client *client = sd->priv; |
763 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 696 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
764 | int data; | 697 | int data; |
765 | 698 | ||
766 | switch (ctrl->id) { | 699 | switch (ctrl->id) { |
@@ -785,7 +718,7 @@ static int mt9m111_get_control(struct soc_camera_device *icd, | |||
785 | ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); | 718 | ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); |
786 | break; | 719 | break; |
787 | case V4L2_CID_GAIN: | 720 | case V4L2_CID_GAIN: |
788 | data = mt9m111_get_global_gain(icd); | 721 | data = mt9m111_get_global_gain(client); |
789 | if (data < 0) | 722 | if (data < 0) |
790 | return data; | 723 | return data; |
791 | ctrl->value = data; | 724 | ctrl->value = data; |
@@ -800,38 +733,36 @@ static int mt9m111_get_control(struct soc_camera_device *icd, | |||
800 | return 0; | 733 | return 0; |
801 | } | 734 | } |
802 | 735 | ||
803 | static int mt9m111_set_control(struct soc_camera_device *icd, | 736 | static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
804 | struct v4l2_control *ctrl) | ||
805 | { | 737 | { |
806 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 738 | struct i2c_client *client = sd->priv; |
807 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 739 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
808 | const struct v4l2_queryctrl *qctrl; | 740 | const struct v4l2_queryctrl *qctrl; |
809 | int ret; | 741 | int ret; |
810 | 742 | ||
811 | qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); | 743 | qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); |
812 | |||
813 | if (!qctrl) | 744 | if (!qctrl) |
814 | return -EINVAL; | 745 | return -EINVAL; |
815 | 746 | ||
816 | switch (ctrl->id) { | 747 | switch (ctrl->id) { |
817 | case V4L2_CID_VFLIP: | 748 | case V4L2_CID_VFLIP: |
818 | mt9m111->vflip = ctrl->value; | 749 | mt9m111->vflip = ctrl->value; |
819 | ret = mt9m111_set_flip(icd, ctrl->value, | 750 | ret = mt9m111_set_flip(client, ctrl->value, |
820 | MT9M111_RMB_MIRROR_ROWS); | 751 | MT9M111_RMB_MIRROR_ROWS); |
821 | break; | 752 | break; |
822 | case V4L2_CID_HFLIP: | 753 | case V4L2_CID_HFLIP: |
823 | mt9m111->hflip = ctrl->value; | 754 | mt9m111->hflip = ctrl->value; |
824 | ret = mt9m111_set_flip(icd, ctrl->value, | 755 | ret = mt9m111_set_flip(client, ctrl->value, |
825 | MT9M111_RMB_MIRROR_COLS); | 756 | MT9M111_RMB_MIRROR_COLS); |
826 | break; | 757 | break; |
827 | case V4L2_CID_GAIN: | 758 | case V4L2_CID_GAIN: |
828 | ret = mt9m111_set_global_gain(icd, ctrl->value); | 759 | ret = mt9m111_set_global_gain(client, ctrl->value); |
829 | break; | 760 | break; |
830 | case V4L2_CID_EXPOSURE_AUTO: | 761 | case V4L2_CID_EXPOSURE_AUTO: |
831 | ret = mt9m111_set_autoexposure(icd, ctrl->value); | 762 | ret = mt9m111_set_autoexposure(client, ctrl->value); |
832 | break; | 763 | break; |
833 | case V4L2_CID_AUTO_WHITE_BALANCE: | 764 | case V4L2_CID_AUTO_WHITE_BALANCE: |
834 | ret = mt9m111_set_autowhitebalance(icd, ctrl->value); | 765 | ret = mt9m111_set_autowhitebalance(client, ctrl->value); |
835 | break; | 766 | break; |
836 | default: | 767 | default: |
837 | ret = -EINVAL; | 768 | ret = -EINVAL; |
@@ -840,34 +771,34 @@ static int mt9m111_set_control(struct soc_camera_device *icd, | |||
840 | return ret; | 771 | return ret; |
841 | } | 772 | } |
842 | 773 | ||
843 | static int mt9m111_restore_state(struct soc_camera_device *icd) | 774 | static int mt9m111_restore_state(struct i2c_client *client) |
844 | { | 775 | { |
845 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 776 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
846 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 777 | struct soc_camera_device *icd = client->dev.platform_data; |
847 | 778 | ||
848 | mt9m111_set_context(icd, mt9m111->context); | 779 | mt9m111_set_context(client, mt9m111->context); |
849 | mt9m111_set_pixfmt(icd, mt9m111->pixfmt); | 780 | mt9m111_set_pixfmt(client, mt9m111->pixfmt); |
850 | mt9m111_setup_rect(icd, &mt9m111->rect); | 781 | mt9m111_setup_rect(client, &mt9m111->rect); |
851 | mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); | 782 | mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); |
852 | mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); | 783 | mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); |
853 | mt9m111_set_global_gain(icd, icd->gain); | 784 | mt9m111_set_global_gain(client, icd->gain); |
854 | mt9m111_set_autoexposure(icd, mt9m111->autoexposure); | 785 | mt9m111_set_autoexposure(client, mt9m111->autoexposure); |
855 | mt9m111_set_autowhitebalance(icd, mt9m111->autowhitebalance); | 786 | mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance); |
856 | return 0; | 787 | return 0; |
857 | } | 788 | } |
858 | 789 | ||
859 | static int mt9m111_resume(struct soc_camera_device *icd) | 790 | static int mt9m111_resume(struct soc_camera_device *icd) |
860 | { | 791 | { |
861 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 792 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
862 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 793 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
863 | int ret = 0; | 794 | int ret = 0; |
864 | 795 | ||
865 | if (mt9m111->powered) { | 796 | if (mt9m111->powered) { |
866 | ret = mt9m111_enable(icd); | 797 | ret = mt9m111_enable(client); |
867 | if (!ret) | 798 | if (!ret) |
868 | ret = mt9m111_reset(icd); | 799 | ret = mt9m111_reset(client); |
869 | if (!ret) | 800 | if (!ret) |
870 | ret = mt9m111_restore_state(icd); | 801 | ret = mt9m111_restore_state(client); |
871 | } | 802 | } |
872 | return ret; | 803 | return ret; |
873 | } | 804 | } |
@@ -875,17 +806,17 @@ static int mt9m111_resume(struct soc_camera_device *icd) | |||
875 | static int mt9m111_init(struct soc_camera_device *icd) | 806 | static int mt9m111_init(struct soc_camera_device *icd) |
876 | { | 807 | { |
877 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 808 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
878 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 809 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
879 | int ret; | 810 | int ret; |
880 | 811 | ||
881 | mt9m111->context = HIGHPOWER; | 812 | mt9m111->context = HIGHPOWER; |
882 | ret = mt9m111_enable(icd); | 813 | ret = mt9m111_enable(client); |
883 | if (!ret) | 814 | if (!ret) |
884 | ret = mt9m111_reset(icd); | 815 | ret = mt9m111_reset(client); |
885 | if (!ret) | 816 | if (!ret) |
886 | ret = mt9m111_set_context(icd, mt9m111->context); | 817 | ret = mt9m111_set_context(client, mt9m111->context); |
887 | if (!ret) | 818 | if (!ret) |
888 | ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); | 819 | ret = mt9m111_set_autoexposure(client, mt9m111->autoexposure); |
889 | if (ret) | 820 | if (ret) |
890 | dev_err(&icd->dev, "mt9m11x init failed: %d\n", ret); | 821 | dev_err(&icd->dev, "mt9m11x init failed: %d\n", ret); |
891 | return ret; | 822 | return ret; |
@@ -893,9 +824,14 @@ static int mt9m111_init(struct soc_camera_device *icd) | |||
893 | 824 | ||
894 | static int mt9m111_release(struct soc_camera_device *icd) | 825 | static int mt9m111_release(struct soc_camera_device *icd) |
895 | { | 826 | { |
827 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
828 | struct mt9m111 *mt9m111 = to_mt9m111(client); | ||
896 | int ret; | 829 | int ret; |
897 | 830 | ||
898 | ret = mt9m111_disable(icd); | 831 | ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); |
832 | if (!ret) | ||
833 | mt9m111->powered = 0; | ||
834 | |||
899 | if (ret < 0) | 835 | if (ret < 0) |
900 | dev_err(&icd->dev, "mt9m11x release failed: %d\n", ret); | 836 | dev_err(&icd->dev, "mt9m11x release failed: %d\n", ret); |
901 | 837 | ||
@@ -909,7 +845,7 @@ static int mt9m111_release(struct soc_camera_device *icd) | |||
909 | static int mt9m111_video_probe(struct soc_camera_device *icd, | 845 | static int mt9m111_video_probe(struct soc_camera_device *icd, |
910 | struct i2c_client *client) | 846 | struct i2c_client *client) |
911 | { | 847 | { |
912 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 848 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
913 | s32 data; | 849 | s32 data; |
914 | int ret; | 850 | int ret; |
915 | 851 | ||
@@ -921,15 +857,10 @@ static int mt9m111_video_probe(struct soc_camera_device *icd, | |||
921 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) | 857 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) |
922 | return -ENODEV; | 858 | return -ENODEV; |
923 | 859 | ||
924 | /* Switch master clock on */ | 860 | ret = mt9m111_enable(client); |
925 | ret = soc_camera_video_start(icd, &client->dev); | ||
926 | if (ret) | ||
927 | goto evstart; | ||
928 | |||
929 | ret = mt9m111_enable(icd); | ||
930 | if (ret) | 861 | if (ret) |
931 | goto ei2c; | 862 | goto ei2c; |
932 | ret = mt9m111_reset(icd); | 863 | ret = mt9m111_reset(client); |
933 | if (ret) | 864 | if (ret) |
934 | goto ei2c; | 865 | goto ei2c; |
935 | 866 | ||
@@ -961,11 +892,29 @@ static int mt9m111_video_probe(struct soc_camera_device *icd, | |||
961 | mt9m111->swap_rgb_red_blue = 1; | 892 | mt9m111->swap_rgb_red_blue = 1; |
962 | 893 | ||
963 | ei2c: | 894 | ei2c: |
964 | soc_camera_video_stop(icd); | ||
965 | evstart: | ||
966 | return ret; | 895 | return ret; |
967 | } | 896 | } |
968 | 897 | ||
898 | static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { | ||
899 | .g_ctrl = mt9m111_g_ctrl, | ||
900 | .s_ctrl = mt9m111_s_ctrl, | ||
901 | .g_chip_ident = mt9m111_g_chip_ident, | ||
902 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
903 | .g_register = mt9m111_g_register, | ||
904 | .s_register = mt9m111_s_register, | ||
905 | #endif | ||
906 | }; | ||
907 | |||
908 | static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { | ||
909 | .s_fmt = mt9m111_s_fmt, | ||
910 | .try_fmt = mt9m111_try_fmt, | ||
911 | }; | ||
912 | |||
913 | static struct v4l2_subdev_ops mt9m111_subdev_ops = { | ||
914 | .core = &mt9m111_subdev_core_ops, | ||
915 | .video = &mt9m111_subdev_video_ops, | ||
916 | }; | ||
917 | |||
969 | static int mt9m111_probe(struct i2c_client *client, | 918 | static int mt9m111_probe(struct i2c_client *client, |
970 | const struct i2c_device_id *did) | 919 | const struct i2c_device_id *did) |
971 | { | 920 | { |
@@ -996,7 +945,7 @@ static int mt9m111_probe(struct i2c_client *client, | |||
996 | if (!mt9m111) | 945 | if (!mt9m111) |
997 | return -ENOMEM; | 946 | return -ENOMEM; |
998 | 947 | ||
999 | i2c_set_clientdata(client, mt9m111); | 948 | v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops); |
1000 | 949 | ||
1001 | /* Second stage probe - when a capture adapter is there */ | 950 | /* Second stage probe - when a capture adapter is there */ |
1002 | icd->ops = &mt9m111_ops; | 951 | icd->ops = &mt9m111_ops; |
@@ -1022,7 +971,7 @@ static int mt9m111_probe(struct i2c_client *client, | |||
1022 | 971 | ||
1023 | static int mt9m111_remove(struct i2c_client *client) | 972 | static int mt9m111_remove(struct i2c_client *client) |
1024 | { | 973 | { |
1025 | struct mt9m111 *mt9m111 = i2c_get_clientdata(client); | 974 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
1026 | struct soc_camera_device *icd = client->dev.platform_data; | 975 | struct soc_camera_device *icd = client->dev.platform_data; |
1027 | 976 | ||
1028 | icd->ops = NULL; | 977 | icd->ops = NULL; |