aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Chant <achant@google.com>2018-03-22 17:39:55 -0400
committerTakashi Iwai <tiwai@suse.de>2018-03-23 05:25:03 -0400
commit21e9b3e931f78497b19b1f8f3d59d19412c1a28f (patch)
treeceafcd8610b694895129a9d52da56672229ac791
parent9a2fe9b801f585baccf8352d82839dcd54b300cf (diff)
ALSA: usb-audio: fix uac control query argument
This patch fixes code readability and should have no functional change. Correct uac control query functions to account for the 1-based indexing of USB Audio Class control identifiers. The function parameter, u8 control, should be the constant defined in audio-v2.h to identify the control to be checked for readability or writeability. This patch fixes all callers that had adjusted, and makes explicit the mapping between audio_feature_info[] array index and the associated control identifier. Signed-off-by: Andrew Chant <achant@google.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/linux/usb/audio-v2.h4
-rw-r--r--sound/usb/clock.c5
-rw-r--r--sound/usb/mixer.c69
3 files changed, 48 insertions, 30 deletions
diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h
index 2db83a191e78..aaafecf073ff 100644
--- a/include/linux/usb/audio-v2.h
+++ b/include/linux/usb/audio-v2.h
@@ -36,12 +36,12 @@
36 36
37static inline bool uac_v2v3_control_is_readable(u32 bmControls, u8 control) 37static inline bool uac_v2v3_control_is_readable(u32 bmControls, u8 control)
38{ 38{
39 return (bmControls >> (control * 2)) & 0x1; 39 return (bmControls >> ((control - 1) * 2)) & 0x1;
40} 40}
41 41
42static inline bool uac_v2v3_control_is_writeable(u32 bmControls, u8 control) 42static inline bool uac_v2v3_control_is_writeable(u32 bmControls, u8 control)
43{ 43{
44 return (bmControls >> (control * 2)) & 0x2; 44 return (bmControls >> ((control - 1) * 2)) & 0x2;
45} 45}
46 46
47/* 4.7.2 Class-Specific AC Interface Descriptor */ 47/* 4.7.2 Class-Specific AC Interface Descriptor */
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 25de7fe285d9..ab39ccb974c6 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -214,7 +214,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
214 214
215 /* If a clock source can't tell us whether it's valid, we assume it is */ 215 /* If a clock source can't tell us whether it's valid, we assume it is */
216 if (!uac_v2v3_control_is_readable(bmControls, 216 if (!uac_v2v3_control_is_readable(bmControls,
217 UAC2_CS_CONTROL_CLOCK_VALID - 1)) 217 UAC2_CS_CONTROL_CLOCK_VALID))
218 return 1; 218 return 1;
219 219
220 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 220 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
@@ -552,7 +552,8 @@ static int set_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
552 bmControls = cs_desc->bmControls; 552 bmControls = cs_desc->bmControls;
553 } 553 }
554 554
555 writeable = uac_v2v3_control_is_writeable(bmControls, UAC2_CS_CONTROL_SAM_FREQ - 1); 555 writeable = uac_v2v3_control_is_writeable(bmControls,
556 UAC2_CS_CONTROL_SAM_FREQ);
556 if (writeable) { 557 if (writeable) {
557 data = cpu_to_le32(rate); 558 data = cpu_to_le32(rate);
558 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, 559 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 1c02f7373eda..3075ac50a391 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -879,26 +879,27 @@ static int check_input_term(struct mixer_build *state, int id,
879 879
880/* feature unit control information */ 880/* feature unit control information */
881struct usb_feature_control_info { 881struct usb_feature_control_info {
882 int control;
882 const char *name; 883 const char *name;
883 int type; /* data type for uac1 */ 884 int type; /* data type for uac1 */
884 int type_uac2; /* data type for uac2 if different from uac1, else -1 */ 885 int type_uac2; /* data type for uac2 if different from uac1, else -1 */
885}; 886};
886 887
887static struct usb_feature_control_info audio_feature_info[] = { 888static struct usb_feature_control_info audio_feature_info[] = {
888 { "Mute", USB_MIXER_INV_BOOLEAN, -1 }, 889 { UAC_FU_MUTE, "Mute", USB_MIXER_INV_BOOLEAN, -1 },
889 { "Volume", USB_MIXER_S16, -1 }, 890 { UAC_FU_VOLUME, "Volume", USB_MIXER_S16, -1 },
890 { "Tone Control - Bass", USB_MIXER_S8, -1 }, 891 { UAC_FU_BASS, "Tone Control - Bass", USB_MIXER_S8, -1 },
891 { "Tone Control - Mid", USB_MIXER_S8, -1 }, 892 { UAC_FU_MID, "Tone Control - Mid", USB_MIXER_S8, -1 },
892 { "Tone Control - Treble", USB_MIXER_S8, -1 }, 893 { UAC_FU_TREBLE, "Tone Control - Treble", USB_MIXER_S8, -1 },
893 { "Graphic Equalizer", USB_MIXER_S8, -1 }, /* FIXME: not implemeted yet */ 894 { UAC_FU_GRAPHIC_EQUALIZER, "Graphic Equalizer", USB_MIXER_S8, -1 }, /* FIXME: not implemented yet */
894 { "Auto Gain Control", USB_MIXER_BOOLEAN, -1 }, 895 { UAC_FU_AUTOMATIC_GAIN, "Auto Gain Control", USB_MIXER_BOOLEAN, -1 },
895 { "Delay Control", USB_MIXER_U16, USB_MIXER_U32 }, 896 { UAC_FU_DELAY, "Delay Control", USB_MIXER_U16, USB_MIXER_U32 },
896 { "Bass Boost", USB_MIXER_BOOLEAN, -1 }, 897 { UAC_FU_BASS_BOOST, "Bass Boost", USB_MIXER_BOOLEAN, -1 },
897 { "Loudness", USB_MIXER_BOOLEAN, -1 }, 898 { UAC_FU_LOUDNESS, "Loudness", USB_MIXER_BOOLEAN, -1 },
898 /* UAC2 specific */ 899 /* UAC2 specific */
899 { "Input Gain Control", USB_MIXER_S16, -1 }, 900 { UAC2_FU_INPUT_GAIN, "Input Gain Control", USB_MIXER_S16, -1 },
900 { "Input Gain Pad Control", USB_MIXER_S16, -1 }, 901 { UAC2_FU_INPUT_GAIN_PAD, "Input Gain Pad Control", USB_MIXER_S16, -1 },
901 { "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 }, 902 { UAC2_FU_PHASE_INVERTER, "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 },
902}; 903};
903 904
904/* private_free callback */ 905/* private_free callback */
@@ -1293,6 +1294,17 @@ static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
1293 strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name)); 1294 strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
1294} 1295}
1295 1296
1297static struct usb_feature_control_info *get_feature_control_info(int control)
1298{
1299 int i;
1300
1301 for (i = 0; i < ARRAY_SIZE(audio_feature_info); ++i) {
1302 if (audio_feature_info[i].control == control)
1303 return &audio_feature_info[i];
1304 }
1305 return NULL;
1306}
1307
1296static void build_feature_ctl(struct mixer_build *state, void *raw_desc, 1308static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1297 unsigned int ctl_mask, int control, 1309 unsigned int ctl_mask, int control,
1298 struct usb_audio_term *iterm, int unitid, 1310 struct usb_audio_term *iterm, int unitid,
@@ -1308,8 +1320,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1308 const struct usbmix_name_map *map; 1320 const struct usbmix_name_map *map;
1309 unsigned int range; 1321 unsigned int range;
1310 1322
1311 control++; /* change from zero-based to 1-based value */
1312
1313 if (control == UAC_FU_GRAPHIC_EQUALIZER) { 1323 if (control == UAC_FU_GRAPHIC_EQUALIZER) {
1314 /* FIXME: not supported yet */ 1324 /* FIXME: not supported yet */
1315 return; 1325 return;
@@ -1325,7 +1335,10 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1325 snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); 1335 snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid);
1326 cval->control = control; 1336 cval->control = control;
1327 cval->cmask = ctl_mask; 1337 cval->cmask = ctl_mask;
1328 ctl_info = &audio_feature_info[control-1]; 1338
1339 ctl_info = get_feature_control_info(control);
1340 if (!ctl_info)
1341 return;
1329 if (state->mixer->protocol == UAC_VERSION_1) 1342 if (state->mixer->protocol == UAC_VERSION_1)
1330 cval->val_type = ctl_info->type; 1343 cval->val_type = ctl_info->type;
1331 else /* UAC_VERSION_2 */ 1344 else /* UAC_VERSION_2 */
@@ -1475,7 +1488,7 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid,
1475 * clock source validity. If that isn't readable, just bail out. 1488 * clock source validity. If that isn't readable, just bail out.
1476 */ 1489 */
1477 if (!uac_v2v3_control_is_readable(hdr->bmControls, 1490 if (!uac_v2v3_control_is_readable(hdr->bmControls,
1478 ilog2(UAC2_CS_CONTROL_CLOCK_VALID))) 1491 UAC2_CS_CONTROL_CLOCK_VALID))
1479 return 0; 1492 return 0;
1480 1493
1481 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 1494 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -1491,7 +1504,7 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid,
1491 cval->control = UAC2_CS_CONTROL_CLOCK_VALID; 1504 cval->control = UAC2_CS_CONTROL_CLOCK_VALID;
1492 1505
1493 if (uac_v2v3_control_is_writeable(hdr->bmControls, 1506 if (uac_v2v3_control_is_writeable(hdr->bmControls,
1494 ilog2(UAC2_CS_CONTROL_CLOCK_VALID))) 1507 UAC2_CS_CONTROL_CLOCK_VALID))
1495 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); 1508 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
1496 else { 1509 else {
1497 cval->master_readonly = 1; 1510 cval->master_readonly = 1;
@@ -1625,6 +1638,8 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
1625 /* check all control types */ 1638 /* check all control types */
1626 for (i = 0; i < 10; i++) { 1639 for (i = 0; i < 10; i++) {
1627 unsigned int ch_bits = 0; 1640 unsigned int ch_bits = 0;
1641 int control = audio_feature_info[i].control;
1642
1628 for (j = 0; j < channels; j++) { 1643 for (j = 0; j < channels; j++) {
1629 unsigned int mask; 1644 unsigned int mask;
1630 1645
@@ -1640,25 +1655,26 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
1640 * (for ease of programming). 1655 * (for ease of programming).
1641 */ 1656 */
1642 if (ch_bits & 1) 1657 if (ch_bits & 1)
1643 build_feature_ctl(state, _ftr, ch_bits, i, 1658 build_feature_ctl(state, _ftr, ch_bits, control,
1644 &iterm, unitid, 0); 1659 &iterm, unitid, 0);
1645 if (master_bits & (1 << i)) 1660 if (master_bits & (1 << i))
1646 build_feature_ctl(state, _ftr, 0, i, &iterm, 1661 build_feature_ctl(state, _ftr, 0, control,
1647 unitid, 0); 1662 &iterm, unitid, 0);
1648 } 1663 }
1649 } else { /* UAC_VERSION_2/3 */ 1664 } else { /* UAC_VERSION_2/3 */
1650 for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { 1665 for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
1651 unsigned int ch_bits = 0; 1666 unsigned int ch_bits = 0;
1652 unsigned int ch_read_only = 0; 1667 unsigned int ch_read_only = 0;
1668 int control = audio_feature_info[i].control;
1653 1669
1654 for (j = 0; j < channels; j++) { 1670 for (j = 0; j < channels; j++) {
1655 unsigned int mask; 1671 unsigned int mask;
1656 1672
1657 mask = snd_usb_combine_bytes(bmaControls + 1673 mask = snd_usb_combine_bytes(bmaControls +
1658 csize * (j+1), csize); 1674 csize * (j+1), csize);
1659 if (uac_v2v3_control_is_readable(mask, i)) { 1675 if (uac_v2v3_control_is_readable(mask, control)) {
1660 ch_bits |= (1 << j); 1676 ch_bits |= (1 << j);
1661 if (!uac_v2v3_control_is_writeable(mask, i)) 1677 if (!uac_v2v3_control_is_writeable(mask, control))
1662 ch_read_only |= (1 << j); 1678 ch_read_only |= (1 << j);
1663 } 1679 }
1664 } 1680 }
@@ -1677,11 +1693,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
1677 * (for ease of programming). 1693 * (for ease of programming).
1678 */ 1694 */
1679 if (ch_bits & 1) 1695 if (ch_bits & 1)
1680 build_feature_ctl(state, _ftr, ch_bits, i, 1696 build_feature_ctl(state, _ftr, ch_bits, control,
1681 &iterm, unitid, ch_read_only); 1697 &iterm, unitid, ch_read_only);
1682 if (uac_v2v3_control_is_readable(master_bits, i)) 1698 if (uac_v2v3_control_is_readable(master_bits, control))
1683 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 1699 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
1684 !uac_v2v3_control_is_writeable(master_bits, i)); 1700 !uac_v2v3_control_is_writeable(master_bits,
1701 control));
1685 } 1702 }
1686 } 1703 }
1687 1704