diff options
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 161 | ||||
-rw-r--r-- | drivers/media/video/msp3400.c | 159 | ||||
-rw-r--r-- | drivers/media/video/tvp5150.c | 81 |
3 files changed, 327 insertions, 74 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 8516ec12836e..446ba3b2ac36 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include "em28xx.h" | 33 | #include "em28xx.h" |
34 | #include <media/tuner.h> | 34 | #include <media/tuner.h> |
35 | #include <media/v4l2-common.h> | ||
35 | 36 | ||
36 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ | 37 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ |
37 | "Markus Rechberger <mrechberger@gmail.com>, " \ | 38 | "Markus Rechberger <mrechberger@gmail.com>, " \ |
@@ -106,8 +107,32 @@ static const unsigned char saa7114_i2c_init[] = { | |||
106 | #define TVNORMS ARRAY_SIZE(tvnorms) | 107 | #define TVNORMS ARRAY_SIZE(tvnorms) |
107 | 108 | ||
108 | /* supported controls */ | 109 | /* supported controls */ |
110 | /* Common to all boards */ | ||
109 | static struct v4l2_queryctrl em28xx_qctrl[] = { | 111 | static struct v4l2_queryctrl em28xx_qctrl[] = { |
110 | { | 112 | { |
113 | .id = V4L2_CID_AUDIO_VOLUME, | ||
114 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
115 | .name = "Volume", | ||
116 | .minimum = 0x0, | ||
117 | .maximum = 0x1f, | ||
118 | .step = 0x1, | ||
119 | .default_value = 0x1f, | ||
120 | .flags = 0, | ||
121 | },{ | ||
122 | .id = V4L2_CID_AUDIO_MUTE, | ||
123 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
124 | .name = "Mute", | ||
125 | .minimum = 0, | ||
126 | .maximum = 1, | ||
127 | .step = 1, | ||
128 | .default_value = 1, | ||
129 | .flags = 0, | ||
130 | } | ||
131 | }; | ||
132 | |||
133 | /* FIXME: These are specific to saa711x - should be moved to its code */ | ||
134 | static struct v4l2_queryctrl saa711x_qctrl[] = { | ||
135 | { | ||
111 | .id = V4L2_CID_BRIGHTNESS, | 136 | .id = V4L2_CID_BRIGHTNESS, |
112 | .type = V4L2_CTRL_TYPE_INTEGER, | 137 | .type = V4L2_CTRL_TYPE_INTEGER, |
113 | .name = "Brightness", | 138 | .name = "Brightness", |
@@ -135,24 +160,6 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { | |||
135 | .default_value = 0x10, | 160 | .default_value = 0x10, |
136 | .flags = 0, | 161 | .flags = 0, |
137 | },{ | 162 | },{ |
138 | .id = V4L2_CID_AUDIO_VOLUME, | ||
139 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
140 | .name = "Volume", | ||
141 | .minimum = 0x0, | ||
142 | .maximum = 0x1f, | ||
143 | .step = 0x1, | ||
144 | .default_value = 0x1f, | ||
145 | .flags = 0, | ||
146 | },{ | ||
147 | .id = V4L2_CID_AUDIO_MUTE, | ||
148 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
149 | .name = "Mute", | ||
150 | .minimum = 0, | ||
151 | .maximum = 1, | ||
152 | .step = 1, | ||
153 | .default_value = 1, | ||
154 | .flags = 0, | ||
155 | },{ | ||
156 | .id = V4L2_CID_RED_BALANCE, | 163 | .id = V4L2_CID_RED_BALANCE, |
157 | .type = V4L2_CTRL_TYPE_INTEGER, | 164 | .type = V4L2_CTRL_TYPE_INTEGER, |
158 | .name = "Red chroma balance", | 165 | .name = "Red chroma balance", |
@@ -179,7 +186,7 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { | |||
179 | .step = 0x1, | 186 | .step = 0x1, |
180 | .default_value = 0x20, | 187 | .default_value = 0x20, |
181 | .flags = 0, | 188 | .flags = 0, |
182 | } | 189 | } |
183 | }; | 190 | }; |
184 | 191 | ||
185 | static struct usb_driver em28xx_usb_driver; | 192 | static struct usb_driver em28xx_usb_driver; |
@@ -674,7 +681,6 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
674 | */ | 681 | */ |
675 | static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | 682 | static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) |
676 | { | 683 | { |
677 | s32 tmp; | ||
678 | switch (ctrl->id) { | 684 | switch (ctrl->id) { |
679 | case V4L2_CID_AUDIO_MUTE: | 685 | case V4L2_CID_AUDIO_MUTE: |
680 | ctrl->value = dev->mute; | 686 | ctrl->value = dev->mute; |
@@ -682,6 +688,16 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | |||
682 | case V4L2_CID_AUDIO_VOLUME: | 688 | case V4L2_CID_AUDIO_VOLUME: |
683 | ctrl->value = dev->volume; | 689 | ctrl->value = dev->volume; |
684 | return 0; | 690 | return 0; |
691 | default: | ||
692 | return -EINVAL; | ||
693 | } | ||
694 | } | ||
695 | |||
696 | /*FIXME: should be moved to saa711x */ | ||
697 | static int saa711x_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | ||
698 | { | ||
699 | s32 tmp; | ||
700 | switch (ctrl->id) { | ||
685 | case V4L2_CID_BRIGHTNESS: | 701 | case V4L2_CID_BRIGHTNESS: |
686 | if ((tmp = em28xx_brightness_get(dev)) < 0) | 702 | if ((tmp = em28xx_brightness_get(dev)) < 0) |
687 | return -EIO; | 703 | return -EIO; |
@@ -731,6 +747,15 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | |||
731 | case V4L2_CID_AUDIO_VOLUME: | 747 | case V4L2_CID_AUDIO_VOLUME: |
732 | dev->volume = ctrl->value; | 748 | dev->volume = ctrl->value; |
733 | return em28xx_audio_analog_set(dev); | 749 | return em28xx_audio_analog_set(dev); |
750 | default: | ||
751 | return -EINVAL; | ||
752 | } | ||
753 | } | ||
754 | |||
755 | /*FIXME: should be moved to saa711x */ | ||
756 | static int saa711x_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | ||
757 | { | ||
758 | switch (ctrl->id) { | ||
734 | case V4L2_CID_BRIGHTNESS: | 759 | case V4L2_CID_BRIGHTNESS: |
735 | return em28xx_brightness_set(dev, ctrl->value); | 760 | return em28xx_brightness_set(dev, ctrl->value); |
736 | case V4L2_CID_CONTRAST: | 761 | case V4L2_CID_CONTRAST: |
@@ -994,14 +1019,34 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, | |||
994 | case VIDIOC_QUERYCTRL: | 1019 | case VIDIOC_QUERYCTRL: |
995 | { | 1020 | { |
996 | struct v4l2_queryctrl *qc = arg; | 1021 | struct v4l2_queryctrl *qc = arg; |
997 | u8 i, n; | 1022 | int i, id=qc->id; |
998 | n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); | 1023 | |
999 | for (i = 0; i < n; i++) | 1024 | memset(qc,0,sizeof(*qc)); |
1000 | if (qc->id && qc->id == em28xx_qctrl[i].id) { | 1025 | qc->id=id; |
1001 | memcpy(qc, &(em28xx_qctrl[i]), | 1026 | |
1027 | if (!dev->has_msp34xx) { | ||
1028 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | ||
1029 | if (qc->id && qc->id == em28xx_qctrl[i].id) { | ||
1030 | memcpy(qc, &(em28xx_qctrl[i]), | ||
1031 | sizeof(*qc)); | ||
1032 | return 0; | ||
1033 | } | ||
1034 | } | ||
1035 | } | ||
1036 | if (dev->decoder == EM28XX_TVP5150) { | ||
1037 | em28xx_i2c_call_clients(dev,cmd,qc); | ||
1038 | if (qc->type) | ||
1039 | return 0; | ||
1040 | else | ||
1041 | return -EINVAL; | ||
1042 | } | ||
1043 | for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { | ||
1044 | if (qc->id && qc->id == saa711x_qctrl[i].id) { | ||
1045 | memcpy(qc, &(saa711x_qctrl[i]), | ||
1002 | sizeof(*qc)); | 1046 | sizeof(*qc)); |
1003 | return 0; | 1047 | return 0; |
1004 | } | 1048 | } |
1049 | } | ||
1005 | 1050 | ||
1006 | return -EINVAL; | 1051 | return -EINVAL; |
1007 | } | 1052 | } |
@@ -1009,29 +1054,66 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, | |||
1009 | case VIDIOC_G_CTRL: | 1054 | case VIDIOC_G_CTRL: |
1010 | { | 1055 | { |
1011 | struct v4l2_control *ctrl = arg; | 1056 | struct v4l2_control *ctrl = arg; |
1057 | int retval=-EINVAL; | ||
1012 | 1058 | ||
1059 | if (!dev->has_msp34xx) | ||
1060 | retval=em28xx_get_ctrl(dev, ctrl); | ||
1061 | if (retval==-EINVAL) { | ||
1062 | if (dev->decoder == EM28XX_TVP5150) { | ||
1063 | em28xx_i2c_call_clients(dev,cmd,arg); | ||
1064 | return 0; | ||
1065 | } | ||
1013 | 1066 | ||
1014 | return em28xx_get_ctrl(dev, ctrl); | 1067 | return saa711x_get_ctrl(dev, ctrl); |
1068 | } else return retval; | ||
1015 | } | 1069 | } |
1016 | 1070 | ||
1017 | case VIDIOC_S_CTRL_OLD: /* ??? */ | ||
1018 | case VIDIOC_S_CTRL: | 1071 | case VIDIOC_S_CTRL: |
1019 | { | 1072 | { |
1020 | struct v4l2_control *ctrl = arg; | 1073 | struct v4l2_control *ctrl = arg; |
1021 | u8 i, n; | 1074 | u8 i; |
1022 | 1075 | ||
1076 | if (!dev->has_msp34xx){ | ||
1077 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | ||
1078 | if (ctrl->id == em28xx_qctrl[i].id) { | ||
1079 | if (ctrl->value < | ||
1080 | em28xx_qctrl[i].minimum | ||
1081 | || ctrl->value > | ||
1082 | em28xx_qctrl[i].maximum) | ||
1083 | return -ERANGE; | ||
1084 | return em28xx_set_ctrl(dev, ctrl); | ||
1085 | } | ||
1086 | } | ||
1087 | } | ||
1023 | 1088 | ||
1024 | n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); | 1089 | if (dev->decoder == EM28XX_TVP5150) { |
1025 | for (i = 0; i < n; i++) | 1090 | em28xx_i2c_call_clients(dev,cmd,arg); |
1026 | if (ctrl->id == em28xx_qctrl[i].id) { | 1091 | return 0; |
1027 | if (ctrl->value < | 1092 | } else { |
1028 | em28xx_qctrl[i].minimum | ||
1029 | || ctrl->value > | ||
1030 | em28xx_qctrl[i].maximum) | ||
1031 | return -ERANGE; | ||
1032 | 1093 | ||
1033 | return em28xx_set_ctrl(dev, ctrl); | 1094 | if (!dev->has_msp34xx){ |
1095 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | ||
1096 | if (ctrl->id == em28xx_qctrl[i].id) { | ||
1097 | if (ctrl->value < | ||
1098 | em28xx_qctrl[i].minimum | ||
1099 | || ctrl->value > | ||
1100 | em28xx_qctrl[i].maximum) | ||
1101 | return -ERANGE; | ||
1102 | return em28xx_set_ctrl(dev, ctrl); | ||
1103 | } | ||
1104 | } | ||
1105 | for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { | ||
1106 | if (ctrl->id == saa711x_qctrl[i].id) { | ||
1107 | if (ctrl->value < | ||
1108 | saa711x_qctrl[i].minimum | ||
1109 | || ctrl->value > | ||
1110 | saa711x_qctrl[i].maximum) | ||
1111 | return -ERANGE; | ||
1112 | return saa711x_set_ctrl(dev, ctrl); | ||
1113 | } | ||
1034 | } | 1114 | } |
1115 | } | ||
1116 | |||
1035 | return -EINVAL; | 1117 | return -EINVAL; |
1036 | } | 1118 | } |
1037 | 1119 | ||
@@ -1850,9 +1932,12 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
1850 | struct em28xx *dev = usb_get_intfdata(interface); | 1932 | struct em28xx *dev = usb_get_intfdata(interface); |
1851 | usb_set_intfdata(interface, NULL); | 1933 | usb_set_intfdata(interface, NULL); |
1852 | 1934 | ||
1935 | /*FIXME: IR should be disconnected */ | ||
1936 | |||
1853 | if (!dev) | 1937 | if (!dev) |
1854 | return; | 1938 | return; |
1855 | 1939 | ||
1940 | |||
1856 | down_write(&em28xx_disconnect); | 1941 | down_write(&em28xx_disconnect); |
1857 | 1942 | ||
1858 | down(&dev->lock); | 1943 | down(&dev->lock); |
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index fc2896bc42c0..8d47d7894248 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c | |||
@@ -1642,6 +1642,45 @@ static void msp_any_detect_stereo(struct i2c_client *client) | |||
1642 | } | 1642 | } |
1643 | } | 1643 | } |
1644 | 1644 | ||
1645 | static struct v4l2_queryctrl msp34xx_qctrl[] = { | ||
1646 | { | ||
1647 | .id = V4L2_CID_AUDIO_VOLUME, | ||
1648 | .name = "Volume", | ||
1649 | .minimum = 0, | ||
1650 | .maximum = 65535, | ||
1651 | .step = 65535/100, | ||
1652 | .default_value = 58880, | ||
1653 | .flags = 0, | ||
1654 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1655 | },{ | ||
1656 | .id = V4L2_CID_AUDIO_MUTE, | ||
1657 | .name = "Mute", | ||
1658 | .minimum = 0, | ||
1659 | .maximum = 1, | ||
1660 | .step = 1, | ||
1661 | .default_value = 1, | ||
1662 | .flags = 0, | ||
1663 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1664 | },{ | ||
1665 | .id = V4L2_CID_AUDIO_BASS, | ||
1666 | .name = "Bass", | ||
1667 | .minimum = 0, | ||
1668 | .maximum = 65535, | ||
1669 | .step = 65535/100, | ||
1670 | .default_value = 32768, | ||
1671 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1672 | },{ | ||
1673 | .id = V4L2_CID_AUDIO_TREBLE, | ||
1674 | .name = "Treble", | ||
1675 | .minimum = 0, | ||
1676 | .maximum = 65535, | ||
1677 | .step = 65535/100, | ||
1678 | .default_value = 32768, | ||
1679 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1680 | }, | ||
1681 | }; | ||
1682 | |||
1683 | |||
1645 | static void msp_any_set_audmode(struct i2c_client *client, int audmode) | 1684 | static void msp_any_set_audmode(struct i2c_client *client, int audmode) |
1646 | { | 1685 | { |
1647 | struct msp3400c *msp = i2c_get_clientdata(client); | 1686 | struct msp3400c *msp = i2c_get_clientdata(client); |
@@ -1658,6 +1697,95 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode) | |||
1658 | } | 1697 | } |
1659 | } | 1698 | } |
1660 | 1699 | ||
1700 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
1701 | { | ||
1702 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1703 | |||
1704 | switch (ctrl->id) { | ||
1705 | case V4L2_CID_AUDIO_MUTE: | ||
1706 | ctrl->value = msp->muted; | ||
1707 | return 0; | ||
1708 | case V4L2_CID_AUDIO_BALANCE: | ||
1709 | { | ||
1710 | int volume = MAX(msp->left, msp->right); | ||
1711 | |||
1712 | ctrl->value = (32768 * MIN(msp->left, msp->right)) / | ||
1713 | (volume ? volume : 1); | ||
1714 | ctrl->value = (msp->left < msp->right) ? | ||
1715 | (65535 - ctrl->value) : ctrl->value; | ||
1716 | if (0 == volume) | ||
1717 | ctrl->value = 32768; | ||
1718 | return 0; | ||
1719 | } | ||
1720 | case V4L2_CID_AUDIO_BASS: | ||
1721 | ctrl->value = msp->bass; | ||
1722 | return 0; | ||
1723 | case V4L2_CID_AUDIO_TREBLE: | ||
1724 | ctrl->value = msp->treble; | ||
1725 | return 0; | ||
1726 | case V4L2_CID_AUDIO_VOLUME: | ||
1727 | ctrl->value = MAX(msp->left, msp->right); | ||
1728 | return 0; | ||
1729 | default: | ||
1730 | return -EINVAL; | ||
1731 | } | ||
1732 | } | ||
1733 | |||
1734 | static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | ||
1735 | { | ||
1736 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
1737 | int set_volume=0, balance, volume; | ||
1738 | |||
1739 | switch (ctrl->id) { | ||
1740 | case V4L2_CID_AUDIO_MUTE: | ||
1741 | if (ctrl->value>=0 && ctrl->value<2) | ||
1742 | msp->muted = ctrl->value; | ||
1743 | else | ||
1744 | return -ERANGE; | ||
1745 | |||
1746 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1747 | return 0; | ||
1748 | case V4L2_CID_AUDIO_BALANCE: | ||
1749 | balance=ctrl->value; | ||
1750 | volume = MAX(msp->left, msp->right); | ||
1751 | set_volume=1; | ||
1752 | break; | ||
1753 | case V4L2_CID_AUDIO_BASS: | ||
1754 | msp->bass=ctrl->value; | ||
1755 | msp3400c_setbass(client, msp->bass); | ||
1756 | return 0; | ||
1757 | case V4L2_CID_AUDIO_TREBLE: | ||
1758 | msp->treble=ctrl->value; | ||
1759 | msp3400c_settreble(client, msp->treble); | ||
1760 | return 0; | ||
1761 | case V4L2_CID_AUDIO_VOLUME: | ||
1762 | volume = MAX(msp->left, msp->right); | ||
1763 | |||
1764 | balance = (32768 * MIN(msp->left, msp->right)) / | ||
1765 | (volume ? volume : 1); | ||
1766 | balance = (msp->left < msp->right) ? | ||
1767 | (65535 - balance) : balance; | ||
1768 | if (0 == volume) | ||
1769 | balance = 32768; | ||
1770 | |||
1771 | volume=ctrl->value; | ||
1772 | set_volume=1; | ||
1773 | break; | ||
1774 | default: | ||
1775 | return -EINVAL; | ||
1776 | } | ||
1777 | |||
1778 | if (set_volume) { | ||
1779 | msp->left = (MIN(65536 - balance, 32768) * volume) / 32768; | ||
1780 | msp->right = (MIN(balance, 32768) * volume) / 32768; | ||
1781 | |||
1782 | msp3400_dbg("volume=%d, balance=%d, left=%d, right=%d", | ||
1783 | volume,balance,msp->left,msp->right); | ||
1784 | |||
1785 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1786 | } | ||
1787 | return 0; | ||
1788 | } | ||
1661 | 1789 | ||
1662 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | 1790 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) |
1663 | { | 1791 | { |
@@ -2027,6 +2155,37 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
2027 | 2155 | ||
2028 | break; | 2156 | break; |
2029 | } | 2157 | } |
2158 | case VIDIOC_QUERYCTRL: | ||
2159 | { | ||
2160 | struct v4l2_queryctrl *qc = arg; | ||
2161 | int i; | ||
2162 | |||
2163 | msp3400_dbg("VIDIOC_QUERYCTRL"); | ||
2164 | |||
2165 | for (i = 0; i < ARRAY_SIZE(msp34xx_qctrl); i++) | ||
2166 | if (qc->id && qc->id == msp34xx_qctrl[i].id) { | ||
2167 | memcpy(qc, &(msp34xx_qctrl[i]), | ||
2168 | sizeof(*qc)); | ||
2169 | return 0; | ||
2170 | } | ||
2171 | |||
2172 | return -EINVAL; | ||
2173 | } | ||
2174 | case VIDIOC_G_CTRL: | ||
2175 | { | ||
2176 | struct v4l2_control *ctrl = arg; | ||
2177 | msp3400_dbg("VIDIOC_G_CTRL\n"); | ||
2178 | |||
2179 | return msp_get_ctrl(client, ctrl); | ||
2180 | } | ||
2181 | case VIDIOC_S_CTRL: | ||
2182 | { | ||
2183 | struct v4l2_control *ctrl = arg; | ||
2184 | |||
2185 | msp3400_dbg("VIDIOC_S_CTRL\n"); | ||
2186 | |||
2187 | return msp_set_ctrl(client, ctrl); | ||
2188 | } | ||
2030 | 2189 | ||
2031 | default: | 2190 | default: |
2032 | /* nothing */ | 2191 | /* nothing */ |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index a60442ea4f94..d62b2302af49 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -37,24 +37,24 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
37 | /* supported controls */ | 37 | /* supported controls */ |
38 | static struct v4l2_queryctrl tvp5150_qctrl[] = { | 38 | static struct v4l2_queryctrl tvp5150_qctrl[] = { |
39 | { | 39 | { |
40 | .id = V4L2_CID_BRIGHTNESS, | 40 | .id = V4L2_CID_BRIGHTNESS, |
41 | .type = V4L2_CTRL_TYPE_INTEGER, | 41 | .type = V4L2_CTRL_TYPE_INTEGER, |
42 | .name = "Brightness", | 42 | .name = "Brightness", |
43 | .minimum = 0, | 43 | .minimum = 0, |
44 | .maximum = 255, | 44 | .maximum = 255, |
45 | .step = 1, | 45 | .step = 1, |
46 | .default_value = 0, | 46 | .default_value = 0, |
47 | .flags = 0, | 47 | .flags = 0, |
48 | }, { | 48 | }, { |
49 | .id = V4L2_CID_CONTRAST, | 49 | .id = V4L2_CID_CONTRAST, |
50 | .type = V4L2_CTRL_TYPE_INTEGER, | 50 | .type = V4L2_CTRL_TYPE_INTEGER, |
51 | .name = "Contrast", | 51 | .name = "Contrast", |
52 | .minimum = 0, | 52 | .minimum = 0, |
53 | .maximum = 255, | 53 | .maximum = 255, |
54 | .step = 0x1, | 54 | .step = 0x1, |
55 | .default_value = 0x10, | 55 | .default_value = 0x10, |
56 | .flags = 0, | 56 | .flags = 0, |
57 | }, { | 57 | }, { |
58 | .id = V4L2_CID_SATURATION, | 58 | .id = V4L2_CID_SATURATION, |
59 | .type = V4L2_CTRL_TYPE_INTEGER, | 59 | .type = V4L2_CTRL_TYPE_INTEGER, |
60 | .name = "Saturation", | 60 | .name = "Saturation", |
@@ -63,16 +63,16 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { | |||
63 | .step = 0x1, | 63 | .step = 0x1, |
64 | .default_value = 0x10, | 64 | .default_value = 0x10, |
65 | .flags = 0, | 65 | .flags = 0, |
66 | }, { | 66 | }, { |
67 | .id = V4L2_CID_HUE, | 67 | .id = V4L2_CID_HUE, |
68 | .type = V4L2_CTRL_TYPE_INTEGER, | 68 | .type = V4L2_CTRL_TYPE_INTEGER, |
69 | .name = "Hue", | 69 | .name = "Hue", |
70 | .minimum = -128, | 70 | .minimum = -128, |
71 | .maximum = 127, | 71 | .maximum = 127, |
72 | .step = 0x1, | 72 | .step = 0x1, |
73 | .default_value = 0x10, | 73 | .default_value = 0x10, |
74 | .flags = 0, | 74 | .flags = 0, |
75 | } | 75 | } |
76 | }; | 76 | }; |
77 | 77 | ||
78 | struct tvp5150 { | 78 | struct tvp5150 { |
@@ -437,11 +437,24 @@ enum tvp5150_input { | |||
437 | static inline void tvp5150_selmux(struct i2c_client *c, | 437 | static inline void tvp5150_selmux(struct i2c_client *c, |
438 | enum tvp5150_input input) | 438 | enum tvp5150_input input) |
439 | { | 439 | { |
440 | int opmode=0; | ||
441 | |||
440 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 442 | struct tvp5150 *decoder = i2c_get_clientdata(c); |
441 | 443 | ||
442 | if (!decoder->enable) | 444 | if (!decoder->enable) |
443 | input |= TVP5150_BLACK_SCREEN; | 445 | input |= TVP5150_BLACK_SCREEN; |
444 | 446 | ||
447 | switch (input) { | ||
448 | case TVP5150_ANALOG_CH0: | ||
449 | case TVP5150_ANALOG_CH1: | ||
450 | opmode=0x30; /* TV Mode */ | ||
451 | break; | ||
452 | default: | ||
453 | opmode=0; /* Auto Mode */ | ||
454 | break; | ||
455 | } | ||
456 | |||
457 | tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode); | ||
445 | tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input); | 458 | tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input); |
446 | }; | 459 | }; |
447 | 460 | ||
@@ -498,9 +511,8 @@ static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | |||
498 | case V4L2_CID_HUE: | 511 | case V4L2_CID_HUE: |
499 | ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL); | 512 | ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL); |
500 | return 0; | 513 | return 0; |
501 | default: | ||
502 | return -EINVAL; | ||
503 | } | 514 | } |
515 | return -EINVAL; | ||
504 | } | 516 | } |
505 | 517 | ||
506 | static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | 518 | static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) |
@@ -520,9 +532,8 @@ static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | |||
520 | case V4L2_CID_HUE: | 532 | case V4L2_CID_HUE: |
521 | tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value); | 533 | tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value); |
522 | return 0; | 534 | return 0; |
523 | default: | ||
524 | return -EINVAL; | ||
525 | } | 535 | } |
536 | return -EINVAL; | ||
526 | } | 537 | } |
527 | 538 | ||
528 | /**************************************************************************** | 539 | /**************************************************************************** |
@@ -627,12 +638,11 @@ static int tvp5150_command(struct i2c_client *client, | |||
627 | case VIDIOC_QUERYCTRL: | 638 | case VIDIOC_QUERYCTRL: |
628 | { | 639 | { |
629 | struct v4l2_queryctrl *qc = arg; | 640 | struct v4l2_queryctrl *qc = arg; |
630 | u8 i, n; | 641 | int i; |
631 | 642 | ||
632 | dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL"); | 643 | dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL"); |
633 | 644 | ||
634 | n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); | 645 | for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++) |
635 | for (i = 0; i < n; i++) | ||
636 | if (qc->id && qc->id == tvp5150_qctrl[i].id) { | 646 | if (qc->id && qc->id == tvp5150_qctrl[i].id) { |
637 | memcpy(qc, &(tvp5150_qctrl[i]), | 647 | memcpy(qc, &(tvp5150_qctrl[i]), |
638 | sizeof(*qc)); | 648 | sizeof(*qc)); |
@@ -648,7 +658,6 @@ static int tvp5150_command(struct i2c_client *client, | |||
648 | 658 | ||
649 | return tvp5150_get_ctrl(client, ctrl); | 659 | return tvp5150_get_ctrl(client, ctrl); |
650 | } | 660 | } |
651 | case VIDIOC_S_CTRL_OLD: /* ??? */ | ||
652 | case VIDIOC_S_CTRL: | 661 | case VIDIOC_S_CTRL: |
653 | { | 662 | { |
654 | struct v4l2_control *ctrl = arg; | 663 | struct v4l2_control *ctrl = arg; |