aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-09-07 04:43:59 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-01-04 21:51:05 -0500
commit081b945ed74c9bd37da2ee928f9ad281222a6477 (patch)
tree4a63554ba3669ae9ce251ce2815285ad3976f591
parent8ac7a9493a4380a8a886fbfe311ab00bc424ca0f (diff)
[media] em28xx: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c24
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c248
-rw-r--r--drivers/media/usb/em28xx/em28xx.h6
3 files changed, 53 insertions, 225 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index e17be073c0c3..1aca98f30a8d 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -2941,6 +2941,8 @@ void em28xx_release_resources(struct em28xx *dev)
2941 2941
2942 em28xx_i2c_unregister(dev); 2942 em28xx_i2c_unregister(dev);
2943 2943
2944 v4l2_ctrl_handler_free(&dev->ctrl_handler);
2945
2944 v4l2_device_unregister(&dev->v4l2_dev); 2946 v4l2_device_unregister(&dev->v4l2_dev);
2945 2947
2946 usb_put_dev(dev->udev); 2948 usb_put_dev(dev->udev);
@@ -2957,6 +2959,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
2957 struct usb_interface *interface, 2959 struct usb_interface *interface,
2958 int minor) 2960 int minor)
2959{ 2961{
2962 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
2960 int retval; 2963 int retval;
2961 static const char *default_chip_name = "em28xx"; 2964 static const char *default_chip_name = "em28xx";
2962 const char *chip_name = default_chip_name; 2965 const char *chip_name = default_chip_name;
@@ -3084,6 +3087,9 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3084 return retval; 3087 return retval;
3085 } 3088 }
3086 3089
3090 v4l2_ctrl_handler_init(hdl, 4);
3091 dev->v4l2_dev.ctrl_handler = hdl;
3092
3087 /* register i2c bus */ 3093 /* register i2c bus */
3088 retval = em28xx_i2c_register(dev); 3094 retval = em28xx_i2c_register(dev);
3089 if (retval < 0) { 3095 if (retval < 0) {
@@ -3109,6 +3115,18 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3109 __func__, retval); 3115 __func__, retval);
3110 goto fail; 3116 goto fail;
3111 } 3117 }
3118 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
3119 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
3120 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
3121 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
3122 V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
3123 } else {
3124 /* install the em28xx notify callback */
3125 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
3126 em28xx_ctrl_notify, dev);
3127 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
3128 em28xx_ctrl_notify, dev);
3129 }
3112 3130
3113 /* wake i2c devices */ 3131 /* wake i2c devices */
3114 em28xx_wake_i2c(dev); 3132 em28xx_wake_i2c(dev);
@@ -3138,6 +3156,11 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3138 msleep(3); 3156 msleep(3);
3139 } 3157 }
3140 3158
3159 v4l2_ctrl_handler_setup(&dev->ctrl_handler);
3160 retval = dev->ctrl_handler.error;
3161 if (retval)
3162 goto fail;
3163
3141 retval = em28xx_register_analog_devices(dev); 3164 retval = em28xx_register_analog_devices(dev);
3142 if (retval < 0) { 3165 if (retval < 0) {
3143 goto fail; 3166 goto fail;
@@ -3150,6 +3173,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3150 3173
3151fail: 3174fail:
3152 em28xx_i2c_unregister(dev); 3175 em28xx_i2c_unregister(dev);
3176 v4l2_ctrl_handler_free(&dev->ctrl_handler);
3153 3177
3154unregister_dev: 3178unregister_dev:
3155 v4l2_device_unregister(&dev->v4l2_dev); 3179 v4l2_device_unregister(&dev->v4l2_dev);
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 89cbfaf17bda..ebbf775fcaba 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -125,30 +125,6 @@ static struct em28xx_fmt format[] = {
125 }, 125 },
126}; 126};
127 127
128/* supported controls */
129/* Common to all boards */
130static struct v4l2_queryctrl ac97_qctrl[] = {
131 {
132 .id = V4L2_CID_AUDIO_VOLUME,
133 .type = V4L2_CTRL_TYPE_INTEGER,
134 .name = "Volume",
135 .minimum = 0x0,
136 .maximum = 0x1f,
137 .step = 0x1,
138 .default_value = 0x1f,
139 .flags = V4L2_CTRL_FLAG_SLIDER,
140 }, {
141 .id = V4L2_CID_AUDIO_MUTE,
142 .type = V4L2_CTRL_TYPE_BOOLEAN,
143 .name = "Mute",
144 .minimum = 0,
145 .maximum = 1,
146 .step = 1,
147 .default_value = 1,
148 .flags = 0,
149 }
150};
151
152/* ------------------------------------------------------------------ 128/* ------------------------------------------------------------------
153 DMA and thread functions 129 DMA and thread functions
154 ------------------------------------------------------------------*/ 130 ------------------------------------------------------------------*/
@@ -718,76 +694,48 @@ static int get_ressource(struct em28xx_fh *fh)
718 } 694 }
719} 695}
720 696
721/* 697void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv)
722 * ac97_queryctrl()
723 * return the ac97 supported controls
724 */
725static int ac97_queryctrl(struct v4l2_queryctrl *qc)
726{ 698{
727 int i; 699 struct em28xx *dev = priv;
728
729 for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
730 if (qc->id && qc->id == ac97_qctrl[i].id) {
731 memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
732 return 0;
733 }
734 }
735
736 /* Control is not ac97 related */
737 return 1;
738}
739 700
740/* 701 /*
741 * ac97_get_ctrl() 702 * In the case of non-AC97 volume controls, we still need
742 * return the current values for ac97 mute and volume 703 * to do some setups at em28xx, in order to mute/unmute
743 */ 704 * and to adjust audio volume. However, the value ranges
744static int ac97_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) 705 * should be checked by the corresponding V4L subdriver.
745{ 706 */
746 switch (ctrl->id) { 707 switch (ctrl->id) {
747 case V4L2_CID_AUDIO_MUTE: 708 case V4L2_CID_AUDIO_MUTE:
748 ctrl->value = dev->mute; 709 dev->mute = ctrl->val;
749 return 0; 710 em28xx_audio_analog_set(dev);
711 break;
750 case V4L2_CID_AUDIO_VOLUME: 712 case V4L2_CID_AUDIO_VOLUME:
751 ctrl->value = dev->volume; 713 dev->volume = ctrl->val;
752 return 0; 714 em28xx_audio_analog_set(dev);
753 default: 715 break;
754 /* Control is not ac97 related */
755 return 1;
756 } 716 }
757} 717}
758 718
759/* 719static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl)
760 * ac97_set_ctrl()
761 * set values for ac97 mute and volume
762 */
763static int ac97_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
764{ 720{
765 int i; 721 struct em28xx *dev = container_of(ctrl->handler, struct em28xx, ctrl_handler);
766
767 for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++)
768 if (ctrl->id == ac97_qctrl[i].id)
769 goto handle;
770
771 /* Announce that hasn't handle it */
772 return 1;
773
774handle:
775 if (ctrl->value < ac97_qctrl[i].minimum ||
776 ctrl->value > ac97_qctrl[i].maximum)
777 return -ERANGE;
778 722
779 switch (ctrl->id) { 723 switch (ctrl->id) {
780 case V4L2_CID_AUDIO_MUTE: 724 case V4L2_CID_AUDIO_MUTE:
781 dev->mute = ctrl->value; 725 dev->mute = ctrl->val;
782 break; 726 break;
783 case V4L2_CID_AUDIO_VOLUME: 727 case V4L2_CID_AUDIO_VOLUME:
784 dev->volume = ctrl->value; 728 dev->volume = ctrl->val;
785 break; 729 break;
786 } 730 }
787 731
788 return em28xx_audio_analog_set(dev); 732 return em28xx_audio_analog_set(dev);
789} 733}
790 734
735const struct v4l2_ctrl_ops em28xx_ctrl_ops = {
736 .s_ctrl = em28xx_s_ctrl,
737};
738
791static int check_dev(struct em28xx *dev) 739static int check_dev(struct em28xx *dev)
792{ 740{
793 if (dev->state & DEV_DISCONNECTED) { 741 if (dev->state & DEV_DISCONNECTED) {
@@ -1182,131 +1130,6 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio
1182 return 0; 1130 return 0;
1183} 1131}
1184 1132
1185static int vidioc_queryctrl(struct file *file, void *priv,
1186 struct v4l2_queryctrl *qc)
1187{
1188 struct em28xx_fh *fh = priv;
1189 struct em28xx *dev = fh->dev;
1190 int id = qc->id;
1191 int rc;
1192
1193 rc = check_dev(dev);
1194 if (rc < 0)
1195 return rc;
1196
1197 memset(qc, 0, sizeof(*qc));
1198
1199 qc->id = id;
1200
1201 /* enumerate AC97 controls */
1202 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
1203 rc = ac97_queryctrl(qc);
1204 if (!rc)
1205 return 0;
1206 }
1207
1208 /* enumerate V4L2 device controls */
1209 v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
1210
1211 if (qc->type)
1212 return 0;
1213 else
1214 return -EINVAL;
1215}
1216
1217/*
1218 * FIXME: This is an indirect way to check if a control exists at a
1219 * subdev. Instead of that hack, maybe the better would be to change all
1220 * subdevs to return -ENOIOCTLCMD, if an ioctl is not supported.
1221 */
1222static int check_subdev_ctrl(struct em28xx *dev, int id)
1223{
1224 struct v4l2_queryctrl qc;
1225
1226 memset(&qc, 0, sizeof(qc));
1227 qc.id = id;
1228
1229 /* enumerate V4L2 device controls */
1230 v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, &qc);
1231
1232 if (qc.type)
1233 return 0;
1234 else
1235 return -EINVAL;
1236}
1237
1238static int vidioc_g_ctrl(struct file *file, void *priv,
1239 struct v4l2_control *ctrl)
1240{
1241 struct em28xx_fh *fh = priv;
1242 struct em28xx *dev = fh->dev;
1243 int rc;
1244
1245 rc = check_dev(dev);
1246 if (rc < 0)
1247 return rc;
1248 rc = 0;
1249
1250 /* Set an AC97 control */
1251 if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
1252 rc = ac97_get_ctrl(dev, ctrl);
1253 else
1254 rc = 1;
1255
1256 /* It were not an AC97 control. Sends it to the v4l2 dev interface */
1257 if (rc == 1) {
1258 if (check_subdev_ctrl(dev, ctrl->id))
1259 return -EINVAL;
1260
1261 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
1262 rc = 0;
1263 }
1264
1265 return rc;
1266}
1267
1268static int vidioc_s_ctrl(struct file *file, void *priv,
1269 struct v4l2_control *ctrl)
1270{
1271 struct em28xx_fh *fh = priv;
1272 struct em28xx *dev = fh->dev;
1273 int rc;
1274
1275 rc = check_dev(dev);
1276 if (rc < 0)
1277 return rc;
1278
1279 /* Set an AC97 control */
1280 if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
1281 rc = ac97_set_ctrl(dev, ctrl);
1282 else
1283 rc = 1;
1284
1285 /* It isn't an AC97 control. Sends it to the v4l2 dev interface */
1286 if (rc == 1) {
1287 rc = check_subdev_ctrl(dev, ctrl->id);
1288 if (!rc)
1289 v4l2_device_call_all(&dev->v4l2_dev, 0,
1290 core, s_ctrl, ctrl);
1291 /*
1292 * In the case of non-AC97 volume controls, we still need
1293 * to do some setups at em28xx, in order to mute/unmute
1294 * and to adjust audio volume. However, the value ranges
1295 * should be checked by the corresponding V4L subdriver.
1296 */
1297 switch (ctrl->id) {
1298 case V4L2_CID_AUDIO_MUTE:
1299 dev->mute = ctrl->value;
1300 rc = em28xx_audio_analog_set(dev);
1301 break;
1302 case V4L2_CID_AUDIO_VOLUME:
1303 dev->volume = ctrl->value;
1304 rc = em28xx_audio_analog_set(dev);
1305 }
1306 }
1307 return (rc < 0) ? rc : 0;
1308}
1309
1310static int vidioc_g_tuner(struct file *file, void *priv, 1133static int vidioc_g_tuner(struct file *file, void *priv,
1311 struct v4l2_tuner *t) 1134 struct v4l2_tuner *t)
1312{ 1135{
@@ -1874,25 +1697,6 @@ static int radio_s_tuner(struct file *file, void *priv,
1874 return 0; 1697 return 0;
1875} 1698}
1876 1699
1877static int radio_queryctrl(struct file *file, void *priv,
1878 struct v4l2_queryctrl *qc)
1879{
1880 int i;
1881
1882 if (qc->id < V4L2_CID_BASE ||
1883 qc->id >= V4L2_CID_LASTP1)
1884 return -EINVAL;
1885
1886 for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
1887 if (qc->id && qc->id == ac97_qctrl[i].id) {
1888 memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
1889 return 0;
1890 }
1891 }
1892
1893 return -EINVAL;
1894}
1895
1896/* 1700/*
1897 * em28xx_v4l2_open() 1701 * em28xx_v4l2_open()
1898 * inits the device and starts isoc transfer 1702 * inits the device and starts isoc transfer
@@ -2218,9 +2022,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
2218 .vidioc_enum_input = vidioc_enum_input, 2022 .vidioc_enum_input = vidioc_enum_input,
2219 .vidioc_g_input = vidioc_g_input, 2023 .vidioc_g_input = vidioc_g_input,
2220 .vidioc_s_input = vidioc_s_input, 2024 .vidioc_s_input = vidioc_s_input,
2221 .vidioc_queryctrl = vidioc_queryctrl,
2222 .vidioc_g_ctrl = vidioc_g_ctrl,
2223 .vidioc_s_ctrl = vidioc_s_ctrl,
2224 .vidioc_streamon = vidioc_streamon, 2025 .vidioc_streamon = vidioc_streamon,
2225 .vidioc_streamoff = vidioc_streamoff, 2026 .vidioc_streamoff = vidioc_streamoff,
2226 .vidioc_g_tuner = vidioc_g_tuner, 2027 .vidioc_g_tuner = vidioc_g_tuner,
@@ -2254,9 +2055,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
2254 .vidioc_querycap = vidioc_querycap, 2055 .vidioc_querycap = vidioc_querycap,
2255 .vidioc_g_tuner = radio_g_tuner, 2056 .vidioc_g_tuner = radio_g_tuner,
2256 .vidioc_s_tuner = radio_s_tuner, 2057 .vidioc_s_tuner = radio_s_tuner,
2257 .vidioc_queryctrl = radio_queryctrl,
2258 .vidioc_g_ctrl = vidioc_g_ctrl,
2259 .vidioc_s_ctrl = vidioc_s_ctrl,
2260 .vidioc_g_frequency = vidioc_g_frequency, 2058 .vidioc_g_frequency = vidioc_g_frequency,
2261 .vidioc_s_frequency = vidioc_s_frequency, 2059 .vidioc_s_frequency = vidioc_s_frequency,
2262#ifdef CONFIG_VIDEO_ADV_DEBUG 2060#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -2300,7 +2098,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
2300 2098
2301int em28xx_register_analog_devices(struct em28xx *dev) 2099int em28xx_register_analog_devices(struct em28xx *dev)
2302{ 2100{
2303 u8 val; 2101 u8 val;
2304 int ret; 2102 int ret;
2305 unsigned int maxw; 2103 unsigned int maxw;
2306 2104
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index 062841e50722..707319eabe2d 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -33,6 +33,7 @@
33 33
34#include <media/videobuf-vmalloc.h> 34#include <media/videobuf-vmalloc.h>
35#include <media/v4l2-device.h> 35#include <media/v4l2-device.h>
36#include <media/v4l2-ctrls.h>
36#include <media/ir-kbd-i2c.h> 37#include <media/ir-kbd-i2c.h>
37#include <media/rc-core.h> 38#include <media/rc-core.h>
38#if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE) 39#if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE)
@@ -497,6 +498,9 @@ struct em28xx {
497 int audio_ifnum; 498 int audio_ifnum;
498 499
499 struct v4l2_device v4l2_dev; 500 struct v4l2_device v4l2_dev;
501 struct v4l2_ctrl_handler ctrl_handler;
502 /* provides ac97 mute and volume overrides */
503 struct v4l2_ctrl_handler ac97_ctrl_handler;
500 struct em28xx_board board; 504 struct em28xx_board board;
501 505
502 /* Webcam specific fields */ 506 /* Webcam specific fields */
@@ -705,6 +709,8 @@ void em28xx_close_extension(struct em28xx *dev);
705/* Provided by em28xx-video.c */ 709/* Provided by em28xx-video.c */
706int em28xx_register_analog_devices(struct em28xx *dev); 710int em28xx_register_analog_devices(struct em28xx *dev);
707void em28xx_release_analog_resources(struct em28xx *dev); 711void em28xx_release_analog_resources(struct em28xx *dev);
712void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv);
713extern const struct v4l2_ctrl_ops em28xx_ctrl_ops;
708 714
709/* Provided by em28xx-cards.c */ 715/* Provided by em28xx-cards.c */
710extern int em2800_variant_detect(struct usb_device *udev, int model); 716extern int em2800_variant_detect(struct usb_device *udev, int model);