Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB: saa7115: convert to the new control framework

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
e3560543 11bbc1ca

+83 -100
+83 -100
drivers/media/video/saa7115.c
··· 45 45 #include <linux/i2c.h> 46 46 #include <linux/videodev2.h> 47 47 #include <media/v4l2-device.h> 48 + #include <media/v4l2-ctrls.h> 48 49 #include <media/v4l2-chip-ident.h> 49 50 #include <media/v4l2-i2c-drv.h> 50 51 #include <media/saa7115.h> ··· 66 65 67 66 struct saa711x_state { 68 67 struct v4l2_subdev sd; 68 + struct v4l2_ctrl_handler hdl; 69 + 70 + struct { 71 + /* chroma gain control cluster */ 72 + struct v4l2_ctrl *agc; 73 + struct v4l2_ctrl *gain; 74 + }; 75 + 69 76 v4l2_std_id std; 70 77 int input; 71 78 int output; 72 79 int enable; 73 80 int radio; 74 - int bright; 75 - int contrast; 76 - int hue; 77 - int sat; 78 - int chroma_agc; 79 81 int width; 80 82 int height; 81 83 u32 ident; ··· 92 88 static inline struct saa711x_state *to_state(struct v4l2_subdev *sd) 93 89 { 94 90 return container_of(sd, struct saa711x_state, sd); 91 + } 92 + 93 + static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) 94 + { 95 + return &container_of(ctrl->handler, struct saa711x_state, hdl)->sd; 95 96 } 96 97 97 98 /* ----------------------------------------------------------------------- */ ··· 750 741 return 0; 751 742 } 752 743 753 - static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 744 + static int saa711x_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 754 745 { 746 + struct v4l2_subdev *sd = to_sd(ctrl); 755 747 struct saa711x_state *state = to_state(sd); 756 - u8 val; 757 748 758 749 switch (ctrl->id) { 759 - case V4L2_CID_BRIGHTNESS: 760 - if (ctrl->value < 0 || ctrl->value > 255) { 761 - v4l2_err(sd, "invalid brightness setting %d\n", ctrl->value); 762 - return -ERANGE; 763 - } 764 - 765 - state->bright = ctrl->value; 766 - saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, state->bright); 767 - break; 768 - 769 - case V4L2_CID_CONTRAST: 770 - if (ctrl->value < 0 || ctrl->value > 127) { 771 - v4l2_err(sd, "invalid contrast setting %d\n", ctrl->value); 772 - return -ERANGE; 773 - } 774 - 775 - state->contrast = ctrl->value; 776 - saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, state->contrast); 777 - break; 778 - 779 - case V4L2_CID_SATURATION: 780 - if (ctrl->value < 0 || ctrl->value > 127) { 781 - v4l2_err(sd, "invalid saturation setting %d\n", ctrl->value); 782 - return -ERANGE; 783 - } 784 - 785 - state->sat = ctrl->value; 786 - saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, state->sat); 787 - break; 788 - 789 - case V4L2_CID_HUE: 790 - if (ctrl->value < -128 || ctrl->value > 127) { 791 - v4l2_err(sd, "invalid hue setting %d\n", ctrl->value); 792 - return -ERANGE; 793 - } 794 - 795 - state->hue = ctrl->value; 796 - saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, state->hue); 797 - break; 798 750 case V4L2_CID_CHROMA_AGC: 799 - val = saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL); 800 - state->chroma_agc = ctrl->value; 801 - if (ctrl->value) 802 - val &= 0x7f; 803 - else 804 - val |= 0x80; 805 - saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, val); 751 + /* chroma gain cluster */ 752 + if (state->agc->cur.val) 753 + state->gain->cur.val = 754 + saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f; 806 755 break; 807 - case V4L2_CID_CHROMA_GAIN: 808 - /* Chroma gain cannot be set when AGC is enabled */ 809 - if (state->chroma_agc == 1) 810 - return -EINVAL; 811 - saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, ctrl->value | 0x80); 812 - break; 813 - default: 814 - return -EINVAL; 815 756 } 816 - 817 757 return 0; 818 758 } 819 759 820 - static int saa711x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 760 + static int saa711x_s_ctrl(struct v4l2_ctrl *ctrl) 821 761 { 762 + struct v4l2_subdev *sd = to_sd(ctrl); 822 763 struct saa711x_state *state = to_state(sd); 823 764 824 765 switch (ctrl->id) { 825 766 case V4L2_CID_BRIGHTNESS: 826 - ctrl->value = state->bright; 767 + saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, ctrl->val); 827 768 break; 769 + 828 770 case V4L2_CID_CONTRAST: 829 - ctrl->value = state->contrast; 771 + saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, ctrl->val); 830 772 break; 773 + 831 774 case V4L2_CID_SATURATION: 832 - ctrl->value = state->sat; 775 + saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, ctrl->val); 833 776 break; 777 + 834 778 case V4L2_CID_HUE: 835 - ctrl->value = state->hue; 779 + saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, ctrl->val); 836 780 break; 781 + 837 782 case V4L2_CID_CHROMA_AGC: 838 - ctrl->value = state->chroma_agc; 783 + /* chroma gain cluster */ 784 + if (state->agc->val) 785 + saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val); 786 + else 787 + saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val | 0x80); 788 + v4l2_ctrl_activate(state->gain, !state->agc->val); 839 789 break; 840 - case V4L2_CID_CHROMA_GAIN: 841 - ctrl->value = saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f; 842 - break; 790 + 843 791 default: 844 792 return -EINVAL; 845 793 } ··· 1189 1223 return 0; 1190 1224 } 1191 1225 1192 - static int saa711x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 1193 - { 1194 - switch (qc->id) { 1195 - case V4L2_CID_BRIGHTNESS: 1196 - return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); 1197 - case V4L2_CID_CONTRAST: 1198 - case V4L2_CID_SATURATION: 1199 - return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64); 1200 - case V4L2_CID_HUE: 1201 - return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); 1202 - case V4L2_CID_CHROMA_AGC: 1203 - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 1204 - case V4L2_CID_CHROMA_GAIN: 1205 - return v4l2_ctrl_query_fill(qc, 0, 127, 1, 48); 1206 - default: 1207 - return -EINVAL; 1208 - } 1209 - } 1210 - 1211 1226 static int saa711x_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 1212 1227 { 1213 1228 struct saa711x_state *state = to_state(sd); ··· 1465 1518 break; 1466 1519 } 1467 1520 v4l2_info(sd, "Width, Height: %d, %d\n", state->width, state->height); 1521 + v4l2_ctrl_handler_log_status(&state->hdl, sd->name); 1468 1522 return 0; 1469 1523 } 1470 1524 1471 1525 /* ----------------------------------------------------------------------- */ 1472 1526 1527 + static const struct v4l2_ctrl_ops saa711x_ctrl_ops = { 1528 + .s_ctrl = saa711x_s_ctrl, 1529 + .g_volatile_ctrl = saa711x_g_volatile_ctrl, 1530 + }; 1531 + 1473 1532 static const struct v4l2_subdev_core_ops saa711x_core_ops = { 1474 1533 .log_status = saa711x_log_status, 1475 1534 .g_chip_ident = saa711x_g_chip_ident, 1476 - .g_ctrl = saa711x_g_ctrl, 1477 - .s_ctrl = saa711x_s_ctrl, 1478 - .queryctrl = saa711x_queryctrl, 1535 + .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, 1536 + .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, 1537 + .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, 1538 + .g_ctrl = v4l2_subdev_g_ctrl, 1539 + .s_ctrl = v4l2_subdev_s_ctrl, 1540 + .queryctrl = v4l2_subdev_queryctrl, 1541 + .querymenu = v4l2_subdev_querymenu, 1479 1542 .s_std = saa711x_s_std, 1480 1543 .reset = saa711x_reset, 1481 1544 .s_gpio = saa711x_s_gpio, ··· 1536 1579 { 1537 1580 struct saa711x_state *state; 1538 1581 struct v4l2_subdev *sd; 1539 - int i; 1540 - char name[17]; 1582 + struct v4l2_ctrl_handler *hdl; 1583 + int i; 1584 + char name[17]; 1541 1585 char chip_id; 1542 1586 int autodetect = !id || id->driver_data == 1; 1543 1587 ··· 1577 1619 return -ENOMEM; 1578 1620 sd = &state->sd; 1579 1621 v4l2_i2c_subdev_init(sd, client, &saa711x_ops); 1622 + 1623 + hdl = &state->hdl; 1624 + v4l2_ctrl_handler_init(hdl, 6); 1625 + /* add in ascending ID order */ 1626 + v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops, 1627 + V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); 1628 + v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops, 1629 + V4L2_CID_CONTRAST, 0, 127, 1, 64); 1630 + v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops, 1631 + V4L2_CID_SATURATION, 0, 127, 1, 64); 1632 + v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops, 1633 + V4L2_CID_HUE, -128, 127, 1, 0); 1634 + state->agc = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops, 1635 + V4L2_CID_CHROMA_AGC, 0, 1, 1, 1); 1636 + state->gain = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops, 1637 + V4L2_CID_CHROMA_GAIN, 0, 127, 1, 40); 1638 + state->gain->is_volatile = 1; 1639 + sd->ctrl_handler = hdl; 1640 + if (hdl->error) { 1641 + int err = hdl->error; 1642 + 1643 + v4l2_ctrl_handler_free(hdl); 1644 + kfree(state); 1645 + return err; 1646 + } 1647 + state->agc->flags |= V4L2_CTRL_FLAG_UPDATE; 1648 + v4l2_ctrl_cluster(2, &state->agc); 1649 + 1580 1650 state->input = -1; 1581 1651 state->output = SAA7115_IPORT_ON; 1582 1652 state->enable = 1; 1583 1653 state->radio = 0; 1584 - state->bright = 128; 1585 - state->contrast = 64; 1586 - state->hue = 0; 1587 - state->sat = 64; 1588 - state->chroma_agc = 1; 1589 1654 switch (chip_id) { 1590 1655 case '1': 1591 1656 state->ident = V4L2_IDENT_SAA7111; ··· 1656 1675 if (state->ident > V4L2_IDENT_SAA7111A) 1657 1676 saa711x_writeregs(sd, saa7115_init_misc); 1658 1677 saa711x_set_v4lstd(sd, V4L2_STD_NTSC); 1678 + v4l2_ctrl_handler_setup(hdl); 1659 1679 1660 1680 v4l2_dbg(1, debug, sd, "status: (1E) 0x%02x, (1F) 0x%02x\n", 1661 1681 saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC), ··· 1671 1689 struct v4l2_subdev *sd = i2c_get_clientdata(client); 1672 1690 1673 1691 v4l2_device_unregister_subdev(sd); 1692 + v4l2_ctrl_handler_free(sd->ctrl_handler); 1674 1693 kfree(to_state(sd)); 1675 1694 return 0; 1676 1695 }