aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-03-03 08:50:34 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-24 11:44:26 -0400
commitd3b2ccd9e307eae80b4b4eeb0ede46cb02212df2 (patch)
treee7b2657e690b1ca8054476b65de4d345526f62ee /drivers/staging
parent9b8451d5af25ca79f63066e1312526ffee606a76 (diff)
[media] s2250: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/go7007/s2250-board.c149
1 files changed, 46 insertions, 103 deletions
diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c
index 2266e1b197cd..589951340826 100644
--- a/drivers/staging/media/go7007/s2250-board.c
+++ b/drivers/staging/media/go7007/s2250-board.c
@@ -116,6 +116,7 @@ static u16 vid_regs_fp_pal[] = {
116 116
117struct s2250 { 117struct s2250 {
118 struct v4l2_subdev sd; 118 struct v4l2_subdev sd;
119 struct v4l2_ctrl_handler hdl;
119 v4l2_std_id std; 120 v4l2_std_id std;
120 int input; 121 int input;
121 int brightness; 122 int brightness;
@@ -370,110 +371,36 @@ static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
370 return 0; 371 return 0;
371} 372}
372 373
373static int s2250_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *query) 374static int s2250_s_ctrl(struct v4l2_ctrl *ctrl)
374{ 375{
375 switch (query->id) { 376 struct s2250 *state = container_of(ctrl->handler, struct s2250, hdl);
376 case V4L2_CID_BRIGHTNESS: 377 struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
377 return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
378 case V4L2_CID_CONTRAST:
379 return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
380 case V4L2_CID_SATURATION:
381 return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
382 case V4L2_CID_HUE:
383 return v4l2_ctrl_query_fill(query, -50, 50, 1, 0);
384 default:
385 return -EINVAL;
386 }
387 return 0;
388}
389
390static int s2250_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
391{
392 struct s2250 *state = to_state(sd);
393 struct i2c_client *client = v4l2_get_subdevdata(sd);
394 int value1;
395 u16 oldvalue; 378 u16 oldvalue;
396 379
397 switch (ctrl->id) { 380 switch (ctrl->id) {
398 case V4L2_CID_BRIGHTNESS: 381 case V4L2_CID_BRIGHTNESS:
399 if (ctrl->value > 100)
400 state->brightness = 100;
401 else if (ctrl->value < 0)
402 state->brightness = 0;
403 else
404 state->brightness = ctrl->value;
405 value1 = (state->brightness - 50) * 255 / 100;
406 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue); 382 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
407 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, 383 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
408 value1 | (oldvalue & ~0xff)); 384 ctrl->val | (oldvalue & ~0xff));
409 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue); 385 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
410 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, 386 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
411 value1 | (oldvalue & ~0xff)); 387 ctrl->val | (oldvalue & ~0xff));
412 write_reg_fp(client, 0x140, 0x60); 388 write_reg_fp(client, 0x140, 0x60);
413 break; 389 break;
414 case V4L2_CID_CONTRAST: 390 case V4L2_CID_CONTRAST:
415 if (ctrl->value > 100)
416 state->contrast = 100;
417 else if (ctrl->value < 0)
418 state->contrast = 0;
419 else
420 state->contrast = ctrl->value;
421 value1 = state->contrast * 0x40 / 100;
422 if (value1 > 0x3f)
423 value1 = 0x3f; /* max */
424 read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue); 391 read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
425 write_reg_fp(client, VPX322_ADDR_CONTRAST0, 392 write_reg_fp(client, VPX322_ADDR_CONTRAST0,
426 value1 | (oldvalue & ~0x3f)); 393 ctrl->val | (oldvalue & ~0x3f));
427 read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue); 394 read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
428 write_reg_fp(client, VPX322_ADDR_CONTRAST1, 395 write_reg_fp(client, VPX322_ADDR_CONTRAST1,
429 value1 | (oldvalue & ~0x3f)); 396 ctrl->val | (oldvalue & ~0x3f));
430 write_reg_fp(client, 0x140, 0x60); 397 write_reg_fp(client, 0x140, 0x60);
431 break; 398 break;
432 case V4L2_CID_SATURATION: 399 case V4L2_CID_SATURATION:
433 if (ctrl->value > 100) 400 write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
434 state->saturation = 100;
435 else if (ctrl->value < 0)
436 state->saturation = 0;
437 else
438 state->saturation = ctrl->value;
439 value1 = state->saturation * 4140 / 100;
440 if (value1 > 4094)
441 value1 = 4094;
442 write_reg_fp(client, VPX322_ADDR_SAT, value1);
443 break;
444 case V4L2_CID_HUE:
445 if (ctrl->value > 50)
446 state->hue = 50;
447 else if (ctrl->value < -50)
448 state->hue = -50;
449 else
450 state->hue = ctrl->value;
451 /* clamp the hue range */
452 value1 = state->hue * 280 / 50;
453 write_reg_fp(client, VPX322_ADDR_HUE, value1);
454 break;
455 default:
456 return -EINVAL;
457 }
458 return 0;
459}
460
461static int s2250_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
462{
463 struct s2250 *state = to_state(sd);
464
465 switch (ctrl->id) {
466 case V4L2_CID_BRIGHTNESS:
467 ctrl->value = state->brightness;
468 break;
469 case V4L2_CID_CONTRAST:
470 ctrl->value = state->contrast;
471 break;
472 case V4L2_CID_SATURATION:
473 ctrl->value = state->saturation;
474 break; 401 break;
475 case V4L2_CID_HUE: 402 case V4L2_CID_HUE:
476 ctrl->value = state->hue; 403 write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
477 break; 404 break;
478 default: 405 default:
479 return -EINVAL; 406 return -EINVAL;
@@ -531,24 +458,21 @@ static int s2250_log_status(struct v4l2_subdev *sd)
531 v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" : 458 v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
532 state->input == 1 ? "S-video" : 459 state->input == 1 ? "S-video" :
533 "error"); 460 "error");
534 v4l2_info(sd, "Brightness: %d\n", state->brightness);
535 v4l2_info(sd, "Contrast: %d\n", state->contrast);
536 v4l2_info(sd, "Saturation: %d\n", state->saturation);
537 v4l2_info(sd, "Hue: %d\n", state->hue);
538 v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" : 461 v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" :
539 state->audio_input == 1 ? "Mic" : 462 state->audio_input == 1 ? "Mic" :
540 state->audio_input == 2 ? "Mic Boost" : 463 state->audio_input == 2 ? "Mic Boost" :
541 "error"); 464 "error");
542 return 0; 465 return v4l2_ctrl_subdev_log_status(sd);
543} 466}
544 467
545/* --------------------------------------------------------------------------*/ 468/* --------------------------------------------------------------------------*/
546 469
470static const struct v4l2_ctrl_ops s2250_ctrl_ops = {
471 .s_ctrl = s2250_s_ctrl,
472};
473
547static const struct v4l2_subdev_core_ops s2250_core_ops = { 474static const struct v4l2_subdev_core_ops s2250_core_ops = {
548 .log_status = s2250_log_status, 475 .log_status = s2250_log_status,
549 .g_ctrl = s2250_g_ctrl,
550 .s_ctrl = s2250_s_ctrl,
551 .queryctrl = s2250_queryctrl,
552 .s_std = s2250_s_std, 476 .s_std = s2250_s_std,
553}; 477};
554 478
@@ -596,6 +520,24 @@ static int s2250_probe(struct i2c_client *client,
596 v4l2_info(sd, "initializing %s at address 0x%x on %s\n", 520 v4l2_info(sd, "initializing %s at address 0x%x on %s\n",
597 "Sensoray 2250/2251", client->addr, client->adapter->name); 521 "Sensoray 2250/2251", client->addr, client->adapter->name);
598 522
523 v4l2_ctrl_handler_init(&state->hdl, 4);
524 v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
525 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
526 v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
527 V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x32);
528 v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
529 V4L2_CID_SATURATION, 0, 4094, 1, 2070);
530 v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
531 V4L2_CID_HUE, -512, 511, 1, 0);
532 sd->ctrl_handler = &state->hdl;
533 if (state->hdl.error) {
534 int err = state->hdl.error;
535
536 v4l2_ctrl_handler_free(&state->hdl);
537 kfree(state);
538 return err;
539 }
540
599 state->std = V4L2_STD_NTSC; 541 state->std = V4L2_STD_NTSC;
600 state->brightness = 50; 542 state->brightness = 50;
601 state->contrast = 50; 543 state->contrast = 50;
@@ -606,22 +548,16 @@ static int s2250_probe(struct i2c_client *client,
606 /* initialize the audio */ 548 /* initialize the audio */
607 if (write_regs(audio, aud_regs) < 0) { 549 if (write_regs(audio, aud_regs) < 0) {
608 dev_err(&client->dev, "error initializing audio\n"); 550 dev_err(&client->dev, "error initializing audio\n");
609 i2c_unregister_device(audio); 551 goto fail;
610 kfree(state);
611 return 0;
612 } 552 }
613 553
614 if (write_regs(client, vid_regs) < 0) { 554 if (write_regs(client, vid_regs) < 0) {
615 dev_err(&client->dev, "error initializing decoder\n"); 555 dev_err(&client->dev, "error initializing decoder\n");
616 i2c_unregister_device(audio); 556 goto fail;
617 kfree(state);
618 return 0;
619 } 557 }
620 if (write_regs_fp(client, vid_regs_fp) < 0) { 558 if (write_regs_fp(client, vid_regs_fp) < 0) {
621 dev_err(&client->dev, "error initializing decoder\n"); 559 dev_err(&client->dev, "error initializing decoder\n");
622 i2c_unregister_device(audio); 560 goto fail;
623 kfree(state);
624 return 0;
625 } 561 }
626 /* set default channel */ 562 /* set default channel */
627 /* composite */ 563 /* composite */
@@ -657,14 +593,21 @@ static int s2250_probe(struct i2c_client *client,
657 593
658 v4l2_info(sd, "initialized successfully\n"); 594 v4l2_info(sd, "initialized successfully\n");
659 return 0; 595 return 0;
596
597fail:
598 i2c_unregister_device(audio);
599 v4l2_ctrl_handler_free(&state->hdl);
600 kfree(state);
601 return -EIO;
660} 602}
661 603
662static int s2250_remove(struct i2c_client *client) 604static int s2250_remove(struct i2c_client *client)
663{ 605{
664 struct v4l2_subdev *sd = i2c_get_clientdata(client); 606 struct s2250 *state = to_state(i2c_get_clientdata(client));
665 607
666 v4l2_device_unregister_subdev(sd); 608 v4l2_device_unregister_subdev(&state->sd);
667 kfree(to_state(sd)); 609 v4l2_ctrl_handler_free(&state->hdl);
610 kfree(state);
668 return 0; 611 return 0;
669} 612}
670 613