aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-video.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c161
1 files changed, 102 insertions, 59 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index ab079d9256c4..a6bdbc21410e 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -124,7 +124,7 @@ static struct em28xx_fmt format[] = {
124 124
125/* supported controls */ 125/* supported controls */
126/* Common to all boards */ 126/* Common to all boards */
127static struct v4l2_queryctrl em28xx_qctrl[] = { 127static struct v4l2_queryctrl ac97_qctrl[] = {
128 { 128 {
129 .id = V4L2_CID_AUDIO_VOLUME, 129 .id = V4L2_CID_AUDIO_VOLUME,
130 .type = V4L2_CTRL_TYPE_INTEGER, 130 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -133,7 +133,7 @@ static struct v4l2_queryctrl em28xx_qctrl[] = {
133 .maximum = 0x1f, 133 .maximum = 0x1f,
134 .step = 0x1, 134 .step = 0x1,
135 .default_value = 0x1f, 135 .default_value = 0x1f,
136 .flags = 0, 136 .flags = V4L2_CTRL_FLAG_SLIDER,
137 }, { 137 }, {
138 .id = V4L2_CID_AUDIO_MUTE, 138 .id = V4L2_CID_AUDIO_MUTE,
139 .type = V4L2_CTRL_TYPE_BOOLEAN, 139 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -609,10 +609,29 @@ static void res_free(struct em28xx_fh *fh)
609} 609}
610 610
611/* 611/*
612 * em28xx_get_ctrl() 612 * ac97_queryctrl()
613 * return the current saturation, brightness or contrast, mute state 613 * return the ac97 supported controls
614 */ 614 */
615static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) 615static int ac97_queryctrl(struct v4l2_queryctrl *qc)
616{
617 int i;
618
619 for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
620 if (qc->id && qc->id == ac97_qctrl[i].id) {
621 memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
622 return 0;
623 }
624 }
625
626 /* Control is not ac97 related */
627 return 1;
628}
629
630/*
631 * ac97_get_ctrl()
632 * return the current values for ac97 mute and volume
633 */
634static int ac97_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
616{ 635{
617 switch (ctrl->id) { 636 switch (ctrl->id) {
618 case V4L2_CID_AUDIO_MUTE: 637 case V4L2_CID_AUDIO_MUTE:
@@ -622,29 +641,41 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
622 ctrl->value = dev->volume; 641 ctrl->value = dev->volume;
623 return 0; 642 return 0;
624 default: 643 default:
625 return -EINVAL; 644 /* Control is not ac97 related */
645 return 1;
626 } 646 }
627} 647}
628 648
629/* 649/*
630 * em28xx_set_ctrl() 650 * ac97_set_ctrl()
631 * mute or set new saturation, brightness or contrast 651 * set values for ac97 mute and volume
632 */ 652 */
633static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) 653static int ac97_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
634{ 654{
655 int i;
656
657 for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++)
658 if (ctrl->id == ac97_qctrl[i].id)
659 goto handle;
660
661 /* Announce that hasn't handle it */
662 return 1;
663
664handle:
665 if (ctrl->value < ac97_qctrl[i].minimum ||
666 ctrl->value > ac97_qctrl[i].maximum)
667 return -ERANGE;
668
635 switch (ctrl->id) { 669 switch (ctrl->id) {
636 case V4L2_CID_AUDIO_MUTE: 670 case V4L2_CID_AUDIO_MUTE:
637 if (ctrl->value != dev->mute) { 671 dev->mute = ctrl->value;
638 dev->mute = ctrl->value; 672 break;
639 return em28xx_audio_analog_set(dev);
640 }
641 return 0;
642 case V4L2_CID_AUDIO_VOLUME: 673 case V4L2_CID_AUDIO_VOLUME:
643 dev->volume = ctrl->value; 674 dev->volume = ctrl->value;
644 return em28xx_audio_analog_set(dev); 675 break;
645 default:
646 return -EINVAL;
647 } 676 }
677
678 return em28xx_audio_analog_set(dev);
648} 679}
649 680
650static int check_dev(struct em28xx *dev) 681static int check_dev(struct em28xx *dev)
@@ -974,6 +1005,9 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
974 struct em28xx_fh *fh = priv; 1005 struct em28xx_fh *fh = priv;
975 struct em28xx *dev = fh->dev; 1006 struct em28xx *dev = fh->dev;
976 1007
1008 if (!dev->audio_mode.has_audio)
1009 return -EINVAL;
1010
977 switch (a->index) { 1011 switch (a->index) {
978 case EM28XX_AMUX_VIDEO: 1012 case EM28XX_AMUX_VIDEO:
979 strcpy(a->name, "Television"); 1013 strcpy(a->name, "Television");
@@ -1015,6 +1049,9 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
1015 struct em28xx *dev = fh->dev; 1049 struct em28xx *dev = fh->dev;
1016 1050
1017 1051
1052 if (!dev->audio_mode.has_audio)
1053 return -EINVAL;
1054
1018 if (a->index >= MAX_EM28XX_INPUT) 1055 if (a->index >= MAX_EM28XX_INPUT)
1019 return -EINVAL; 1056 return -EINVAL;
1020 if (0 == INPUT(a->index)->type) 1057 if (0 == INPUT(a->index)->type)
@@ -1038,7 +1075,6 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1038 struct em28xx_fh *fh = priv; 1075 struct em28xx_fh *fh = priv;
1039 struct em28xx *dev = fh->dev; 1076 struct em28xx *dev = fh->dev;
1040 int id = qc->id; 1077 int id = qc->id;
1041 int i;
1042 int rc; 1078 int rc;
1043 1079
1044 rc = check_dev(dev); 1080 rc = check_dev(dev);
@@ -1049,15 +1085,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1049 1085
1050 qc->id = id; 1086 qc->id = id;
1051 1087
1052 if (!dev->board.has_msp34xx) { 1088 /* enumberate AC97 controls */
1053 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { 1089 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
1054 if (qc->id && qc->id == em28xx_qctrl[i].id) { 1090 rc = ac97_queryctrl(qc);
1055 memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); 1091 if (!rc)
1056 return 0; 1092 return 0;
1057 }
1058 }
1059 } 1093 }
1060 1094
1095 /* enumberate V4L2 device controls */
1061 mutex_lock(&dev->lock); 1096 mutex_lock(&dev->lock);
1062 v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc); 1097 v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
1063 mutex_unlock(&dev->lock); 1098 mutex_unlock(&dev->lock);
@@ -1082,14 +1117,16 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1082 1117
1083 mutex_lock(&dev->lock); 1118 mutex_lock(&dev->lock);
1084 1119
1085 if (dev->board.has_msp34xx) 1120 /* Set an AC97 control */
1121 if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
1122 rc = ac97_get_ctrl(dev, ctrl);
1123 else
1124 rc = 1;
1125
1126 /* It were not an AC97 control. Sends it to the v4l2 dev interface */
1127 if (rc == 1) {
1086 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl); 1128 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
1087 else { 1129 rc = 0;
1088 rc = em28xx_get_ctrl(dev, ctrl);
1089 if (rc < 0) {
1090 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
1091 rc = 0;
1092 }
1093 } 1130 }
1094 1131
1095 mutex_unlock(&dev->lock); 1132 mutex_unlock(&dev->lock);
@@ -1101,7 +1138,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1101{ 1138{
1102 struct em28xx_fh *fh = priv; 1139 struct em28xx_fh *fh = priv;
1103 struct em28xx *dev = fh->dev; 1140 struct em28xx *dev = fh->dev;
1104 u8 i;
1105 int rc; 1141 int rc;
1106 1142
1107 rc = check_dev(dev); 1143 rc = check_dev(dev);
@@ -1110,28 +1146,31 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1110 1146
1111 mutex_lock(&dev->lock); 1147 mutex_lock(&dev->lock);
1112 1148
1113 if (dev->board.has_msp34xx) 1149 /* Set an AC97 control */
1114 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); 1150 if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
1115 else { 1151 rc = ac97_set_ctrl(dev, ctrl);
1152 else
1116 rc = 1; 1153 rc = 1;
1117 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
1118 if (ctrl->id == em28xx_qctrl[i].id) {
1119 if (ctrl->value < em28xx_qctrl[i].minimum ||
1120 ctrl->value > em28xx_qctrl[i].maximum) {
1121 rc = -ERANGE;
1122 break;
1123 }
1124
1125 rc = em28xx_set_ctrl(dev, ctrl);
1126 break;
1127 }
1128 }
1129 }
1130 1154
1131 /* Control not found - try to send it to the attached devices */ 1155 /* It isn't an AC97 control. Sends it to the v4l2 dev interface */
1132 if (rc == 1) { 1156 if (rc == 1) {
1133 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); 1157 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
1134 rc = 0; 1158
1159 /*
1160 * In the case of non-AC97 volume controls, we still need
1161 * to do some setups at em28xx, in order to mute/unmute
1162 * and to adjust audio volume. However, the value ranges
1163 * should be checked by the corresponding V4L subdriver.
1164 */
1165 switch (ctrl->id) {
1166 case V4L2_CID_AUDIO_MUTE:
1167 dev->mute = ctrl->value;
1168 rc = em28xx_audio_analog_set(dev);
1169 break;
1170 case V4L2_CID_AUDIO_VOLUME:
1171 dev->volume = ctrl->value;
1172 rc = em28xx_audio_analog_set(dev);
1173 }
1135 } 1174 }
1136 1175
1137 mutex_unlock(&dev->lock); 1176 mutex_unlock(&dev->lock);
@@ -1275,8 +1314,9 @@ static int vidioc_g_register(struct file *file, void *priv,
1275 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg); 1314 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
1276 return 0; 1315 return 0;
1277 case V4L2_CHIP_MATCH_I2C_ADDR: 1316 case V4L2_CHIP_MATCH_I2C_ADDR:
1278 /* Not supported yet */ 1317 /* TODO: is this correct? */
1279 return -EINVAL; 1318 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
1319 return 0;
1280 default: 1320 default:
1281 if (!v4l2_chip_match_host(&reg->match)) 1321 if (!v4l2_chip_match_host(&reg->match))
1282 return -EINVAL; 1322 return -EINVAL;
@@ -1327,8 +1367,9 @@ static int vidioc_s_register(struct file *file, void *priv,
1327 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg); 1367 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
1328 return 0; 1368 return 0;
1329 case V4L2_CHIP_MATCH_I2C_ADDR: 1369 case V4L2_CHIP_MATCH_I2C_ADDR:
1330 /* Not supported yet */ 1370 /* TODO: is this correct? */
1331 return -EINVAL; 1371 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
1372 return 0;
1332 default: 1373 default:
1333 if (!v4l2_chip_match_host(&reg->match)) 1374 if (!v4l2_chip_match_host(&reg->match))
1334 return -EINVAL; 1375 return -EINVAL;
@@ -1431,9 +1472,11 @@ static int vidioc_querycap(struct file *file, void *priv,
1431 cap->capabilities = 1472 cap->capabilities =
1432 V4L2_CAP_SLICED_VBI_CAPTURE | 1473 V4L2_CAP_SLICED_VBI_CAPTURE |
1433 V4L2_CAP_VIDEO_CAPTURE | 1474 V4L2_CAP_VIDEO_CAPTURE |
1434 V4L2_CAP_AUDIO |
1435 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; 1475 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1436 1476
1477 if (dev->audio_mode.has_audio)
1478 cap->capabilities |= V4L2_CAP_AUDIO;
1479
1437 if (dev->tuner_type != TUNER_ABSENT) 1480 if (dev->tuner_type != TUNER_ABSENT)
1438 cap->capabilities |= V4L2_CAP_TUNER; 1481 cap->capabilities |= V4L2_CAP_TUNER;
1439 1482
@@ -1654,9 +1697,9 @@ static int radio_queryctrl(struct file *file, void *priv,
1654 qc->id >= V4L2_CID_LASTP1) 1697 qc->id >= V4L2_CID_LASTP1)
1655 return -EINVAL; 1698 return -EINVAL;
1656 1699
1657 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { 1700 for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
1658 if (qc->id && qc->id == em28xx_qctrl[i].id) { 1701 if (qc->id && qc->id == ac97_qctrl[i].id) {
1659 memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); 1702 memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
1660 return 0; 1703 return 0;
1661 } 1704 }
1662 } 1705 }