diff options
-rw-r--r-- | sound/firewire/motu/motu-protocol-v2.c | 64 | ||||
-rw-r--r-- | sound/firewire/motu/motu-protocol-v3.c | 19 | ||||
-rw-r--r-- | sound/firewire/motu/motu.c | 19 | ||||
-rw-r--r-- | sound/firewire/motu/motu.h | 5 | ||||
-rw-r--r-- | sound/pci/ctxfi/ctmixer.c | 15 | ||||
-rw-r--r-- | sound/pci/hda/dell_wmi_helper.c | 116 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 136 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.h | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 62 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 13 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 66 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 31 | ||||
-rw-r--r-- | sound/pci/hda/thinkpad_helper.c | 27 | ||||
-rw-r--r-- | sound/pci/ice1712/prodigy_hifi.c | 21 | ||||
-rw-r--r-- | sound/usb/line6/toneport.c | 5 |
15 files changed, 326 insertions, 289 deletions
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 525b746330be..453fc29fade7 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -13,6 +13,8 @@ #define V2_CLOCK_RATE_SHIFT 3 #define V2_CLOCK_SRC_MASK 0x00000007 #define V2_CLOCK_SRC_SHIFT 0 +#define V2_CLOCK_TRAVELER_FETCH_DISABLE 0x04000000 +#define V2_CLOCK_TRAVELER_FETCH_ENABLE 0x03000000 #define V2_IN_OUT_CONF_OFFSET 0x0c04 #define V2_OPT_OUT_IFACE_MASK 0x00000c00 @@ -66,6 +68,11 @@ static int v2_set_clock_rate(struct snd_motu *motu, unsigned int rate) data &= ~V2_CLOCK_RATE_MASK; data |= i << V2_CLOCK_RATE_SHIFT; + if (motu->spec == &snd_motu_spec_traveler) { + data &= ~V2_CLOCK_TRAVELER_FETCH_ENABLE; + data |= V2_CLOCK_TRAVELER_FETCH_DISABLE; + } + reg = cpu_to_be32(data); return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, ®, sizeof(reg)); @@ -121,8 +128,31 @@ static int v2_get_clock_source(struct snd_motu *motu, static int v2_switch_fetching_mode(struct snd_motu *motu, bool enable) { - /* V2 protocol doesn't have this feature. */ - return 0; + __be32 reg; + u32 data; + int err = 0; + + if (motu->spec == &snd_motu_spec_traveler) { + err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, + ®, sizeof(reg)); + if (err < 0) + return err; + data = be32_to_cpu(reg); + + data &= ~(V2_CLOCK_TRAVELER_FETCH_DISABLE | + V2_CLOCK_TRAVELER_FETCH_ENABLE); + + if (enable) + data |= V2_CLOCK_TRAVELER_FETCH_ENABLE; + else + data |= V2_CLOCK_TRAVELER_FETCH_DISABLE; + + reg = cpu_to_be32(data); + err = snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, + ®, sizeof(reg)); + } + + return err; } static void calculate_fixed_part(struct snd_motu_packet_format *formats, @@ -149,11 +179,20 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[1] += 2; } } else { - /* - * Packets to v2 units transfer main-out-1/2 and phone-out-1/2. - */ - pcm_chunks[0] += 4; - pcm_chunks[1] += 4; + if (flags & SND_MOTU_SPEC_RX_SEPARETED_MAIN) { + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; + } + + // Packets to v2 units include 2 chunks for phone 1/2, except + // for 176.4/192.0 kHz. + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; + } + + if (flags & SND_MOTU_SPEC_HAS_AESEBU_IFACE) { + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; } /* @@ -164,19 +203,16 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[0] += 2; pcm_chunks[1] += 2; - /* This part should be multiples of 4. */ - formats->fixed_part_pcm_chunks[0] = round_up(2 + pcm_chunks[0], 4) - 2; - formats->fixed_part_pcm_chunks[1] = round_up(2 + pcm_chunks[1], 4) - 2; - if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) - formats->fixed_part_pcm_chunks[2] = - round_up(2 + pcm_chunks[2], 4) - 2; + formats->fixed_part_pcm_chunks[0] = pcm_chunks[0]; + formats->fixed_part_pcm_chunks[1] = pcm_chunks[1]; + formats->fixed_part_pcm_chunks[2] = pcm_chunks[2]; } static void calculate_differed_part(struct snd_motu_packet_format *formats, enum snd_motu_spec_flags flags, u32 data, u32 mask, u32 shift) { - unsigned char pcm_chunks[3] = {0, 0}; + unsigned char pcm_chunks[2] = {0, 0}; /* * When optical interfaces are configured for S/PDIF (TOSLINK), diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c index c7cd9864dc4d..7cc80a05e91f 100644 --- a/sound/firewire/motu/motu-protocol-v3.c +++ b/sound/firewire/motu/motu-protocol-v3.c @@ -188,11 +188,20 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[1] += 2; } } else { - /* - * Packets to v2 units transfer main-out-1/2 and phone-out-1/2. - */ - pcm_chunks[0] += 4; - pcm_chunks[1] += 4; + if (flags & SND_MOTU_SPEC_RX_SEPARETED_MAIN) { + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; + } + + // Packets to v3 units include 2 chunks for phone 1/2, except + // for 176.4/192.0 kHz. + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; + } + + if (flags & SND_MOTU_SPEC_HAS_AESEBU_IFACE) { + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; } /* diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c index 0d6b526105ab..300d31b6f191 100644 --- a/sound/firewire/motu/motu.c +++ b/sound/firewire/motu/motu.c @@ -200,6 +200,22 @@ static const struct snd_motu_spec motu_828mk2 = { .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | SND_MOTU_SPEC_TX_MICINST_CHUNK | SND_MOTU_SPEC_TX_RETURN_CHUNK | + SND_MOTU_SPEC_RX_SEPARETED_MAIN | + SND_MOTU_SPEC_HAS_OPT_IFACE_A | + SND_MOTU_SPEC_RX_MIDI_2ND_Q | + SND_MOTU_SPEC_TX_MIDI_2ND_Q, + + .analog_in_ports = 8, + .analog_out_ports = 8, +}; + +const struct snd_motu_spec snd_motu_spec_traveler = { + .name = "Traveler", + .protocol = &snd_motu_protocol_v2, + .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | + SND_MOTU_SPEC_SUPPORT_CLOCK_X4 | + SND_MOTU_SPEC_TX_RETURN_CHUNK | + SND_MOTU_SPEC_HAS_AESEBU_IFACE | SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_RX_MIDI_2ND_Q | SND_MOTU_SPEC_TX_MIDI_2ND_Q, @@ -216,6 +232,7 @@ static const struct snd_motu_spec motu_828mk3 = { SND_MOTU_SPEC_TX_MICINST_CHUNK | SND_MOTU_SPEC_TX_RETURN_CHUNK | SND_MOTU_SPEC_TX_REVERB_CHUNK | + SND_MOTU_SPEC_RX_SEPARETED_MAIN | SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_HAS_OPT_IFACE_B | SND_MOTU_SPEC_RX_MIDI_3RD_Q | @@ -231,6 +248,7 @@ static const struct snd_motu_spec motu_audio_express = { .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | SND_MOTU_SPEC_TX_MICINST_CHUNK | SND_MOTU_SPEC_TX_RETURN_CHUNK | + SND_MOTU_SPEC_RX_SEPARETED_MAIN | SND_MOTU_SPEC_RX_MIDI_2ND_Q | SND_MOTU_SPEC_TX_MIDI_3RD_Q, .analog_in_ports = 2, @@ -250,6 +268,7 @@ static const struct snd_motu_spec motu_audio_express = { static const struct ieee1394_device_id motu_id_table[] = { SND_MOTU_DEV_ENTRY(0x101800, &motu_828mk2), + SND_MOTU_DEV_ENTRY(0x107800, &snd_motu_spec_traveler), SND_MOTU_DEV_ENTRY(0x106800, &motu_828mk3), /* FireWire only. */ SND_MOTU_DEV_ENTRY(0x100800, &motu_828mk3), /* Hybrid. */ SND_MOTU_DEV_ENTRY(0x104800, &motu_audio_express), diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index 4b23cf337c4b..fd5327d30ab1 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -79,13 +79,14 @@ enum snd_motu_spec_flags { SND_MOTU_SPEC_TX_MICINST_CHUNK = 0x0004, SND_MOTU_SPEC_TX_RETURN_CHUNK = 0x0008, SND_MOTU_SPEC_TX_REVERB_CHUNK = 0x0010, - SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020, + SND_MOTU_SPEC_HAS_AESEBU_IFACE = 0x0020, SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040, SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080, SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0100, SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0200, SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0400, SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0800, + SND_MOTU_SPEC_RX_SEPARETED_MAIN = 0x1000, }; #define SND_MOTU_CLOCK_RATE_COUNT 6 @@ -128,6 +129,8 @@ struct snd_motu_spec { extern const struct snd_motu_protocol snd_motu_protocol_v2; extern const struct snd_motu_protocol snd_motu_protocol_v3; +extern const struct snd_motu_spec snd_motu_spec_traveler; + int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit, enum amdtp_stream_direction dir, const struct snd_motu_protocol *const protocol); diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index db710d0a609f..4777d50fbbf8 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -938,17 +938,18 @@ static int ct_mixer_topology_build(struct ct_mixer *mixer) struct sum *sum; struct amixer *amix_d, *amix_s; enum CT_AMIXER_CTL i, j; + enum CT_SUM_CTL k; /* Build topology from destination to source */ /* Set up Master mixer */ - for (i = AMIXER_MASTER_F, j = SUM_IN_F; - i <= AMIXER_MASTER_S; i++, j++) { + for (i = AMIXER_MASTER_F, k = SUM_IN_F; + i <= AMIXER_MASTER_S; i++, k++) { amix_d = mixer->amixers[i*CHN_NUM]; - sum = mixer->sums[j*CHN_NUM]; + sum = mixer->sums[k*CHN_NUM]; amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL); amix_d = mixer->amixers[i*CHN_NUM+1]; - sum = mixer->sums[j*CHN_NUM+1]; + sum = mixer->sums[k*CHN_NUM+1]; amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL); } @@ -972,12 +973,12 @@ static int ct_mixer_topology_build(struct ct_mixer *mixer) amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL); /* Set up PCM-in mixer */ - for (i = AMIXER_PCM_F, j = SUM_IN_F; i <= AMIXER_PCM_S; i++, j++) { + for (i = AMIXER_PCM_F, k = SUM_IN_F; i <= AMIXER_PCM_S; i++, k++) { amix_d = mixer->amixers[i*CHN_NUM]; - sum = mixer->sums[j*CHN_NUM]; + sum = mixer->sums[k*CHN_NUM]; amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); amix_d = mixer->amixers[i*CHN_NUM+1]; - sum = mixer->sums[j*CHN_NUM+1]; + sum = mixer->sums[k*CHN_NUM+1]; amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); } diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c index 1b48a8c19d28..8a7dbd1a7fbf 100644 --- a/sound/pci/hda/dell_wmi_helper.c +++ b/sound/pci/hda/dell_wmi_helper.c @@ -6,111 +6,18 @@ #if IS_ENABLED(CONFIG_DELL_LAPTOP) #include <linux/dell-led.h> -enum { - MICMUTE_LED_ON, - MICMUTE_LED_OFF, - MICMUTE_LED_FOLLOW_CAPTURE, - MICMUTE_LED_FOLLOW_MUTE, -}; - -static int dell_led_mode = MICMUTE_LED_FOLLOW_MUTE; -static int dell_capture; -static int dell_led_value; static int (*dell_micmute_led_set_func)(int); -static void (*dell_old_cap_hook)(struct hda_codec *, - struct snd_kcontrol *, - struct snd_ctl_elem_value *); - -static void call_micmute_led_update(void) -{ - int val; - - switch (dell_led_mode) { - case MICMUTE_LED_ON: - val = 1; - break; - case MICMUTE_LED_OFF: - val = 0; - break; - case MICMUTE_LED_FOLLOW_CAPTURE: - val = dell_capture; - break; - case MICMUTE_LED_FOLLOW_MUTE: - default: - val = !dell_capture; - break; - } - - if (val == dell_led_value) - return; - dell_led_value = val; - dell_micmute_led_set_func(dell_led_value); -} - -static void update_dell_wmi_micmute_led(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (dell_old_cap_hook) - dell_old_cap_hook(codec, kcontrol, ucontrol); - - if (!ucontrol || !dell_micmute_led_set_func) - return; - if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { - /* TODO: How do I verify if it's a mono or stereo here? */ - dell_capture = (ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]); - call_micmute_led_update(); - } -} -static int dell_mic_mute_led_mode_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) +static void dell_micmute_update(struct hda_codec *codec) { - static const char * const texts[] = { - "On", "Off", "Follow Capture", "Follow Mute", - }; - - return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); -} + struct hda_gen_spec *spec = codec->spec; -static int dell_mic_mute_led_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = dell_led_mode; - return 0; + dell_micmute_led_set_func(spec->micmute_led.led_value); } -static int dell_mic_mute_led_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - unsigned int mode; - - mode = ucontrol->value.enumerated.item[0]; - if (mode > MICMUTE_LED_FOLLOW_MUTE) - mode = MICMUTE_LED_FOLLOW_MUTE; - if (mode == dell_led_mode) - return 0; - dell_led_mode = mode; - call_micmute_led_update(); - return 1; -} - -static const struct snd_kcontrol_new dell_mic_mute_mode_ctls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Mute-LED Mode", - .info = dell_mic_mute_led_mode_info, - .get = dell_mic_mute_led_mode_get, - .put = dell_mic_mute_led_mode_put, - }, - {} -}; - static void alc_fixup_dell_wmi(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - struct alc_spec *spec = codec->spec; bool removefunc = false; if (action == HDA_FIXUP_ACT_PROBE) { @@ -121,25 +28,14 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec, return; } - removefunc = true; - if (dell_micmute_led_set_func(false) >= 0) { - dell_led_value = 0; - if (spec->gen.num_adc_nids > 1 && !spec->gen.dyn_adc_switch) - codec_dbg(codec, "Skipping micmute LED control due to several ADCs"); - else { - dell_old_cap_hook = spec->gen.cap_sync_hook; - spec->gen.cap_sync_hook = update_dell_wmi_micmute_led; - removefunc = false; - add_mixer(spec, dell_mic_mute_mode_ctls); - } - } - + removefunc = (dell_micmute_led_set_func(false) < 0) || + (snd_hda_gen_add_micmute_led(codec, + dell_micmute_update) <= 0); } if (dell_micmute_led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) { symbol_put(dell_micmute_led_set); dell_micmute_led_set_func = NULL; - dell_old_cap_hook = NULL; } } diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index db773e219aaa..942f96e184b6 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -3900,6 +3900,142 @@ static int parse_mic_boost(struct hda_codec *codec) } /* + * mic mute LED hook helpers + */ +enum { + MICMUTE_LED_ON, + MICMUTE_LED_OFF, + MICMUTE_LED_FOLLOW_CAPTURE, + MICMUTE_LED_FOLLOW_MUTE, +}; + +static void call_micmute_led_update(struct hda_codec *codec) +{ + struct hda_gen_spec *spec = codec->spec; + unsigned int val; + + switch (spec->micmute_led.led_mode) { + case MICMUTE_LED_ON: + val = 1; + break; + case MICMUTE_LED_OFF: + val = 0; + break; + case MICMUTE_LED_FOLLOW_CAPTURE: + val = !!spec->micmute_led.capture; + break; + case MICMUTE_LED_FOLLOW_MUTE: + default: + val = !spec->micmute_led.capture; + break; + } + + if (val == spec->micmute_led.led_value) + return; + spec->micmute_led.led_value = val; + if (spec->micmute_led.update) + spec->micmute_led.update(codec); +} + +static void update_micmute_led(struct hda_codec *codec, + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_gen_spec *spec = codec->spec; + unsigned int mask; + + if (spec->micmute_led.old_hook) + spec->micmute_led.old_hook(codec, kcontrol, ucontrol); + + if (!ucontrol) + return; + mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + if (!strcmp("Capture Switch", ucontrol->id.name)) { + /* TODO: How do I verify if it's a mono or stereo here? */ + if (ucontrol->value.integer.value[0] || + ucontrol->value.integer.value[1]) + spec->micmute_led.capture |= mask; + else + spec->micmute_led.capture &= ~mask; + call_micmute_led_update(codec); + } +} + +static int micmute_led_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static const char * const texts[] = { + "On", "Off", "Follow Capture", "Follow Mute", + }; + + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); +} + +static int micmute_led_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct hda_gen_spec *spec = codec->spec; + + ucontrol->value.enumerated.item[0] = spec->micmute_led.led_mode; + return 0; +} + +static int micmute_led_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct hda_gen_spec *spec = codec->spec; + unsigned int mode; + + mode = ucontrol->value.enumerated.item[0]; + if (mode > MICMUTE_LED_FOLLOW_MUTE) + mode = MICMUTE_LED_FOLLOW_MUTE; + if (mode == spec->micmute_led.led_mode) + return 0; + spec->micmute_led.led_mode = mode; + call_micmute_led_update(codec); + return 1; +} + +static const struct snd_kcontrol_new micmute_led_mode_ctl = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Mute-LED Mode", + .info = micmute_led_mode_info, + .get = micmute_led_mode_get, + .put = micmute_led_mode_put, +}; + +/** + * snd_hda_gen_add_micmute_led - helper for setting up mic mute LED hook + * @codec: the HDA codec + * @hook: the callback for updating LED + * + * Called from the codec drivers for offering the mic mute LED controls. + * When established, it sets up cap_sync_hook and triggers the callback at + * each time when the capture mixer switch changes. The callback is supposed + * to update the LED accordingly. + * + * Returns 0 if the hook is established or a negative error code. + */ +int snd_hda_gen_add_micmute_led(struct hda_codec *codec, + void (*hook)(struct hda_codec *)) +{ + struct hda_gen_spec *spec = codec->spec; + + spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE; + spec->micmute_led.capture = 0; + spec->micmute_led.led_value = 0; + spec->micmute_led.old_hook = spec->cap_sync_hook; + spec->micmute_led.update = hook; + spec->cap_sync_hook = update_micmute_led; + if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl)) + return -ENOMEM; + return 0; +} +EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led); + +/* * parse digital I/Os and set up NIDs in BIOS auto-parse mode */ static void parse_digital(struct hda_codec *codec) diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 61772317de46..10123664fa61 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -86,6 +86,16 @@ struct badness_table { extern const struct badness_table hda_main_out_badness; extern const struct badness_table hda_extra_out_badness; +struct hda_micmute_hook { + unsigned int led_mode; + unsigned int capture; + unsigned int led_value; + void (*update)(struct hda_codec *codec); + void (*old_hook)(struct hda_codec *codec, + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +}; + struct hda_gen_spec { char stream_name_analog[32]; /* analog PCM stream */ const struct hda_pcm_stream *stream_analog_playback; @@ -276,6 +286,9 @@ struct hda_gen_spec { struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); + /* mic mute LED hook; called via cap_sync_hook */ + struct hda_micmute_hook micmute_led; + /* PCM hooks */ void (*pcm_playback_hook)(struct hda_pcm_stream *hinfo, struct hda_codec *codec, @@ -342,4 +355,7 @@ unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on); int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin); +int snd_hda_gen_add_micmute_led(struct hda_codec *codec, + void (*hook)(struct hda_codec *)); + #endif /* __SOUND_HDA_GENERIC_H */ diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 04e949aa01ad..d62c56feaf7d 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -991,6 +991,7 @@ struct ca0132_spec { enum { QUIRK_NONE, QUIRK_ALIENWARE, + QUIRK_ALIENWARE_M17XR4, QUIRK_SBZ, QUIRK_R3DI, }; @@ -1040,6 +1041,7 @@ static const struct hda_pintbl r3di_pincfgs[] = { }; static const struct snd_pci_quirk ca0132_quirks[] = { + SND_PCI_QUIRK(0x1028, 0x057b, "Alienware M17x R4", QUIRK_ALIENWARE_M17XR4), SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE), SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE), SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE), @@ -5966,7 +5968,7 @@ static int ca0132_build_pcms(struct hda_codec *codec) info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; /* With the DSP enabled, desktops don't use this ADC. */ - if (spec->use_alt_functions) { + if (!spec->use_alt_functions) { info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2"); if (!info) return -ENOMEM; @@ -6130,7 +6132,10 @@ static void ca0132_init_dmic(struct hda_codec *codec) * Bit 6: set to select Data2, clear for Data1 * Bit 7: set to enable DMic, clear for AMic */ - val = 0x23; + if (spec->quirk == QUIRK_ALIENWARE_M17XR4) + val = 0x33; + else + val = 0x23; /* keep a copy of dmic ctl val for enable/disable dmic purpuse */ spec->dmic_ctl = val; snd_hda_codec_write(codec, spec->input_pins[0], 0, @@ -7223,7 +7228,7 @@ static int ca0132_init(struct hda_codec *codec) snd_hda_sequence_write(codec, spec->base_init_verbs); - if (spec->quirk != QUIRK_NONE) + if (spec->use_alt_functions) ca0132_alt_init(codec); ca0132_download_dsp(codec); @@ -7237,8 +7242,9 @@ static int ca0132_init(struct hda_codec *codec) case QUIRK_R3DI: r3di_setup_defaults(codec); break; - case QUIRK_NONE: - case QUIRK_ALIENWARE: + case QUIRK_SBZ: + break; + default: ca0132_setup_defaults(codec); ca0132_init_analog_mic2(codec); ca0132_init_dmic(codec); @@ -7343,7 +7349,6 @@ static const struct hda_codec_ops ca0132_patch_ops = { static void ca0132_config(struct hda_codec *codec) { struct ca0132_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; spec->dacs[0] = 0x2; spec->dacs[1] = 0x3; @@ -7405,12 +7410,7 @@ static void ca0132_config(struct hda_codec *codec) /* SPDIF I/O */ spec->dig_out = 0x05; spec->multiout.dig_out_nid = spec->dig_out; - cfg->dig_out_pins[0] = 0x0c; - cfg->dig_outs = 1; - cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF; spec->dig_in = 0x09; - cfg->dig_in_pin = 0x0e; - cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; break; case QUIRK_R3DI: codec_dbg(codec, "%s: QUIRK_R3DI applied.\n", __func__); @@ -7438,9 +7438,6 @@ static void ca0132_config(struct hda_codec *codec) /* SPDIF I/O */ spec->dig_out = 0x05; spec->multiout.dig_out_nid = spec->dig_out; - cfg->dig_out_pins[0] = 0x0c; - cfg->dig_outs = 1; - cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF; break; default: spec->num_outputs = 2; @@ -7463,12 +7460,7 @@ static void ca0132_config(struct hda_codec *codec) /* SPDIF I/O */ spec->dig_out = 0x05; spec->multiout.dig_out_nid = spec->dig_out; - cfg->dig_out_pins[0] = 0x0c; - cfg->dig_outs = 1; - cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF; spec->dig_in = 0x09; - cfg->dig_in_pin = 0x0e; - cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; break; } } @@ -7476,7 +7468,7 @@ static void ca0132_config(struct hda_codec *codec) static int ca0132_prepare_verbs(struct hda_codec *codec) { /* Verbs + terminator (an empty element) */ -#define NUM_SPEC_VERBS 4 +#define NUM_SPEC_VERBS 2 struct ca0132_spec *spec = codec->spec; spec->chip_init_verbs = ca0132_init_verbs0; @@ -7488,34 +7480,24 @@ static int ca0132_prepare_verbs(struct hda_codec *codec) if (!spec->spec_init_verbs) return -ENOMEM; - /* HP jack autodetection */ - spec->spec_init_verbs[0].nid = spec->unsol_tag_hp; - spec->spec_init_verbs[0].param = AC_VERB_SET_UNSOLICITED_ENABLE; - spec->spec_init_verbs[0].verb = AC_USRSP_EN | spec->unsol_tag_hp; - - /* MIC1 jack autodetection */ - spec->spec_init_verbs[1].nid = spec->unsol_tag_amic1; - spec->spec_init_verbs[1].param = AC_VERB_SET_UNSOLICITED_ENABLE; - spec->spec_init_verbs[1].verb = AC_USRSP_EN | spec->unsol_tag_amic1; - /* config EAPD */ - spec->spec_init_verbs[2].nid = 0x0b; - spec->spec_init_verbs[2].param = 0x78D; - spec->spec_init_verbs[2].verb = 0x00; + spec->spec_init_verbs[0].nid = 0x0b; + spec->spec_init_verbs[0].param = 0x78D; + spec->spec_init_verbs[0].verb = 0x00; /* Previously commented configuration */ /* - spec->spec_init_verbs[3].nid = 0x0b; - spec->spec_init_verbs[3].param = AC_VERB_SET_EAPD_BTLENABLE; + spec->spec_init_verbs[2].nid = 0x0b; + spec->spec_init_verbs[2].param = AC_VERB_SET_EAPD_BTLENABLE; + spec->spec_init_verbs[2].verb = 0x02; + + spec->spec_init_verbs[3].nid = 0x10; + spec->spec_init_verbs[3].param = 0x78D; spec->spec_init_verbs[3].verb = 0x02; spec->spec_init_verbs[4].nid = 0x10; - spec->spec_init_verbs[4].param = 0x78D; + spec->spec_init_verbs[4].param = AC_VERB_SET_EAPD_BTLENABLE; spec->spec_init_verbs[4].verb = 0x02; - - spec->spec_init_verbs[5].nid = 0x10; - spec->spec_init_verbs[5].param = AC_VERB_SET_EAPD_BTLENABLE; - spec->spec_init_verbs[5].verb = 0x02; */ /* Terminator: spec->spec_init_verbs[NUM_SPEC_VERBS-1] */ diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e7fcfc3b8885..b7339cb5c45b 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -343,6 +343,7 @@ static void cxt_fixup_headphone_mic(struct hda_codec *codec, snd_hdac_regmap_add_vendor_verb(&codec->core, 0x410); break; case HDA_FIXUP_ACT_PROBE: + WARN_ON(spec->gen.cap_sync_hook); spec->gen.cap_sync_hook = cxt_update_headset_mode_hook; spec->gen.automute_hook = cxt_update_headset_mode; break; @@ -695,16 +696,12 @@ static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled) } /* turn on/off mic-mute LED via GPIO per capture hook */ -static void cxt_fixup_gpio_mic_mute_hook(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void cxt_gpio_micmute_update(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; - if (ucontrol) - cxt_update_gpio_led(codec, spec->gpio_mic_led_mask, - ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]); + cxt_update_gpio_led(codec, spec->gpio_mic_led_mask, + spec->gen.micmute_led.led_value); } @@ -721,11 +718,11 @@ static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = cxt_fixup_gpio_mic_mute_hook; spec->gpio_led = 0; spec->mute_led_polarity = 0; spec->gpio_mute_led_mask = 0x01; spec->gpio_mic_led_mask = 0x02; + snd_hda_gen_add_micmute_led(codec, cxt_gpio_micmute_update); } snd_hda_add_verbs(codec, gpio_init); if (spec->gpio_led) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e9bd33ea538f..7934c5df4d80 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3718,16 +3718,12 @@ static void alc_fixup_gpio_mute_hook(void *private_data, int enabled) } /* turn on/off mic-mute LED via GPIO per capture hook */ -static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void alc_gpio_micmute_update(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - if (ucontrol) - alc_update_gpio_led(codec, spec->gpio_mic_led_mask, - ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]); + alc_update_gpio_led(codec, spec->gpio_mic_led_mask, + spec->gen.micmute_led.led_value); } static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, @@ -3742,12 +3738,12 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; spec->gpio_led = 0; spec->mute_led_polarity = 0; spec->gpio_mute_led_mask = 0x08; spec->gpio_mic_led_mask = 0x10; snd_hda_add_verbs(codec, gpio_init); + snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update); } } @@ -3763,39 +3759,30 @@ static void alc286_fixup_hp_gpio_led(struct hda_codec *codec, if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; spec->gpio_led = 0; spec->mute_led_polarity = 0; spec->gpio_mute_led_mask = 0x02; spec->gpio_mic_led_mask = 0x20; snd_hda_add_verbs(codec, gpio_init); + snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update); } } /* turn on/off mic-mute LED per capture hook */ -static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void alc_cap_micmute_update(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int pinval, enable, disable; + unsigned int pinval; + if (!spec->cap_mute_led_nid) + return; pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid); pinval &= ~AC_PINCTL_VREFEN; - enable = pinval | AC_PINCTL_VREF_80; - disable = pinval | AC_PINCTL_VREF_HIZ; - - if (!ucontrol) - return; - - if (ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]) - pinval = disable; + if (spec->gen.micmute_led.led_value) + pinval |= AC_PINCTL_VREF_80; else - pinval = enable; - - if (spec->cap_mute_led_nid) - snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval); + pinval |= AC_PINCTL_VREF_HIZ; + snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval); } static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, @@ -3810,12 +3797,12 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; spec->gpio_led = 0; spec->mute_led_polarity = 0; spec->gpio_mute_led_mask = 0x08; spec->cap_mute_led_nid = 0x18; snd_hda_add_verbs(codec, gpio_init); + snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update); codec->power_filter = led_power_filter; } } @@ -3833,12 +3820,12 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; spec->gpio_led = 0; spec->mute_led_polarity = 0; spec->gpio_mute_led_mask = 0x08; spec->cap_mute_led_nid = 0x18; snd_hda_add_verbs(codec, gpio_init); + snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update); codec->power_filter = led_power_filter; } } @@ -3915,11 +3902,11 @@ static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec, gpio2_mic_hotkey_event); spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; spec->gpio_led = 0; spec->mute_led_polarity = 0; spec->gpio_mute_led_mask = 0x08; spec->gpio_mic_led_mask = 0x10; + snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update); return; } @@ -3957,10 +3944,10 @@ static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec, snd_hda_jack_detect_enable_callback(codec, 0x1b, gpio2_mic_hotkey_event); - spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; spec->gpio_led = 0; spec->mute_led_polarity = 0; spec->gpio_mic_led_mask = 0x04; + snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update); return; } @@ -3986,14 +3973,10 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, { struct alc_spec *spec = codec->spec; + alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a); if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; - spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; - spec->mute_led_polarity = 0; - spec->mute_led_nid = 0x1a; spec->cap_mute_led_nid = 0x18; - spec->gen.vmaster_mute_enum = 1; - codec->power_filter = led_power_filter; + snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update); } } @@ -4841,6 +4824,7 @@ static void alc_probe_headset_mode(struct hda_codec *codec) spec->headphone_mic_pin = cfg->inputs[i].pin; } + WARN_ON(spec->gen.cap_sync_hook); spec->gen.cap_sync_hook = alc_update_headset_mode_hook; spec->gen.automute_hook = alc_update_headset_mode; spec->gen.hp_automute_hook = alc_update_headset_jack_cb; @@ -4995,7 +4979,6 @@ static void alc_fixup_tpt440_dock(struct hda_codec *codec, struct alc_spec *spec = codec->spec; if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->shutup = alc_no_shutup; /* reduce click noise */ spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */ spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; codec->power_save_node = 0; /* avoid click noises */ @@ -5394,6 +5377,13 @@ static void alc274_fixup_bind_dacs(struct hda_codec *codec, /* for hda_fixup_thinkpad_acpi() */ #include "thinkpad_helper.c" +static void alc_fixup_thinkpad_acpi(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */ + hda_fixup_thinkpad_acpi(codec, fix, action); +} + /* for dell wmi mic mute led */ #include "dell_wmi_helper.c" @@ -5946,7 +5936,7 @@ static const struct hda_fixup alc269_fixups[] = { }, [ALC269_FIXUP_THINKPAD_ACPI] = { .type = HDA_FIXUP_FUNC, - .v.func = hda_fixup_thinkpad_acpi, + .v.func = alc_fixup_thinkpad_acpi, .chained = true, .chain_id = ALC269_FIXUP_SKU_IGNORE, }, diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 63d15b545b33..046705b4691a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -332,33 +332,15 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, } /* hook for controlling mic-mute LED GPIO */ -static void stac_capture_led_hook(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void stac_capture_led_update(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; - unsigned int mask; - bool cur_mute, prev_mute; - if (!kcontrol || !ucontrol) - return; - - mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - prev_mute = !spec->mic_enabled; - if (ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]) - spec->mic_enabled |= mask; + if (spec->gen.micmute_led.led_value) + spec->gpio_data |= spec->mic_mute_led_gpio; else - spec->mic_enabled &= ~mask; - cur_mute = !spec->mic_enabled; - if (cur_mute != prev_mute) { - if (cur_mute) - spec->gpio_data |= spec->mic_mute_led_gpio; - else - spec->gpio_data &= ~spec->mic_mute_led_gpio; - stac_gpio_set(codec, spec->gpio_mask, - spec->gpio_dir, spec->gpio_data); - } + spec->gpio_data &= ~spec->mic_mute_led_gpio; + stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); } static int stac_vrefout_set(struct hda_codec *codec, @@ -4656,8 +4638,7 @@ static void stac_setup_gpio(struct hda_codec *codec) spec->gpio_dir |= spec->mic_mute_led_gpio; spec->mic_enabled = 0; spec->gpio_data |= spec->mic_mute_led_gpio; - - spec->gen.cap_sync_hook = stac_capture_led_hook; + snd_hda_gen_add_micmute_led(codec, stac_capture_led_update); } } diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c index 65bb3ac6af4c..97f49b751e6e 100644 --- a/sound/pci/hda/thinkpad_helper.c +++ b/sound/pci/hda/thinkpad_helper.c @@ -27,17 +27,11 @@ static void update_tpacpi_mute_led(void *private_data, int enabled) led_set_func(TPACPI_LED_MUTE, !enabled); } -static void update_tpacpi_micmute_led(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void update_tpacpi_micmute(struct hda_codec *codec) { - if (!ucontrol || !led_set_func) - return; - if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { - /* TODO: How do I verify if it's a mono or stereo here? */ - bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]; - led_set_func(TPACPI_LED_MICMUTE, !val); - } + struct hda_gen_spec *spec = codec->spec; + + led_set_func(TPACPI_LED_MICMUTE, spec->micmute_led.led_value); } static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, @@ -63,15 +57,10 @@ static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, spec->vmaster_mute.hook = update_tpacpi_mute_led; removefunc = false; } - if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { - if (spec->num_adc_nids > 1 && !spec->dyn_adc_switch) - codec_dbg(codec, - "Skipping micmute LED control due to several ADCs"); - else { - spec->cap_sync_hook = update_tpacpi_micmute_led; - removefunc = false; - } - } + if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0 && + snd_hda_gen_add_micmute_led(codec, + update_tpacpi_micmute) > 0) + removefunc = false; } if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) { diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index d7366ade5a25..c97b5528e4b8 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c @@ -314,26 +314,7 @@ static struct snd_kcontrol_new prodigy_hd2_controls[] = { /* --------------- */ -/* - * Logarithmic volume values for WM87*6 - * Computed as 20 * Log10(255 / x) - */ -static const unsigned char wm_vol[256] = { - 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, - 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, - 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, - 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -#define WM_VOL_MAX (sizeof(wm_vol) - 1) +#define WM_VOL_MAX 255 #define WM_VOL_MUTE 0x8000 diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 750467fb95db..f47ba94e6f4a 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -367,12 +367,13 @@ static bool toneport_has_source_select(struct usb_line6_toneport *toneport) */ static void toneport_setup(struct usb_line6_toneport *toneport) { - int ticks; + u32 ticks; struct usb_line6 *line6 = &toneport->line6; struct usb_device *usbdev = line6->usbdev; /* sync time on device with host: */ - ticks = (int)get_seconds(); + /* note: 32-bit timestamps overflow in year 2106 */ + ticks = (u32)ktime_get_real_seconds(); line6_write_data(line6, 0x80c6, &ticks, 4); /* enable device: */ |