diff options
Diffstat (limited to 'sound/pci/ctxfi/ctmixer.c')
| -rw-r--r-- | sound/pci/ctxfi/ctmixer.c | 111 |
1 files changed, 88 insertions, 23 deletions
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index 48fe0e39c2be..fc9fde284fb3 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -1,10 +1,7 @@ -/** +// SPDX-License-Identifier: GPL-2.0-only +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * - * This source file is released under GPL v2 license (no other versions). - * See the COPYING file included in the main directory of this source - * distribution for the license terms and conditions. - * * @File ctmixer.c * * @Brief @@ -12,7 +9,6 @@ * * @Author Liu Chun * @Date May 28 2008 - * */ @@ -551,8 +547,14 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state) atc->mic_unmute(atc, state); else if (MIXER_SPDIFI_C_S == type) atc->spdif_in_unmute(atc, state); - else if (MIXER_WAVEF_P_S == type) - atc->line_front_unmute(atc, state); + else if (MIXER_WAVEF_P_S == type) { + if (cap.dedicated_rca) { + atc->rca_unmute(atc, atc->rca_state ? 0 : state); + atc->line_front_unmute(atc, atc->rca_state ? state : 0); + } else { + atc->line_front_unmute(atc, state); + } + } else if (MIXER_WAVES_P_S == type) atc->line_surround_unmute(atc, state); else if (MIXER_WAVEC_P_S == type) @@ -616,6 +618,57 @@ static struct snd_kcontrol_new swh_ctl = { .put = ct_alsa_mix_switch_put }; +static int dedicated_rca_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *info) +{ + static const char *const names[2] = { + "RCA", "Front" + }; + + return snd_ctl_enum_info(info, 1, 2, names); +} + +static int dedicated_rca_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct ct_atc *atc = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = atc->rca_state; + return 0; +} + +static int dedicated_rca_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct ct_atc *atc = snd_kcontrol_chip(kcontrol); + unsigned int rca_state = ucontrol->value.enumerated.item[0]; + unsigned char state; + + if (rca_state > 1) + return -EINVAL; + + if (rca_state == atc->rca_state) + return 0; + + state = get_switch_state(atc->mixer, MIXER_WAVEF_P_S); + do_switch(atc, MIXER_WAVEF_P_S, 0); + + atc->rca_state = rca_state; + atc->dedicated_rca_select(atc); + + do_switch(atc, MIXER_WAVEF_P_S, state); + + return 1; +} + +static struct snd_kcontrol_new rca_ctl = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Analog Playback Route", + .info = dedicated_rca_info, + .get = dedicated_rca_get, + .put = dedicated_rca_put, +}; + static int ct_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -788,7 +841,17 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer) if (err) return err; } - atc->line_front_unmute(atc, 1); + + if (cap.dedicated_rca) { + err = ct_mixer_kcontrol_new(mixer, &rca_ctl); + if (err) + return err; + + atc->line_front_unmute(atc, 0); + atc->rca_unmute(atc, 1); + } else { + atc->line_front_unmute(atc, 1); + } set_switch_state(mixer, MIXER_WAVEF_P_S, 1); atc->line_surround_unmute(atc, 0); set_switch_state(mixer, MIXER_WAVES_P_S, 0); @@ -854,8 +917,8 @@ static int ct_mixer_get_resources(struct ct_mixer *mixer) for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) { err = sum_mgr->get_sum(sum_mgr, &sum_desc, &sum); if (err) { - printk(KERN_ERR "ctxfi:Failed to get sum resources for " - "front output!\n"); + dev_err(mixer->atc->card->dev, + "Failed to get sum resources for front output!\n"); break; } mixer->sums[i] = sum; @@ -869,8 +932,8 @@ static int ct_mixer_get_resources(struct ct_mixer *mixer) for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) { err = amixer_mgr->get_amixer(amixer_mgr, &am_desc, &amixer); if (err) { - printk(KERN_ERR "ctxfi:Failed to get amixer resources " - "for mixer obj!\n"); + dev_err(mixer->atc->card->dev, + "Failed to get amixer resources for mixer obj!\n"); break; } mixer->amixers[i] = amixer; @@ -910,13 +973,14 @@ static int ct_mixer_get_mem(struct ct_mixer **rmixer) if (!mixer) return -ENOMEM; - mixer->amixers = kzalloc(sizeof(void *)*(NUM_CT_AMIXERS*CHN_NUM), + mixer->amixers = kcalloc(NUM_CT_AMIXERS * CHN_NUM, sizeof(void *), GFP_KERNEL); if (!mixer->amixers) { err = -ENOMEM; goto error1; } - mixer->sums = kzalloc(sizeof(void *)*(NUM_CT_SUMS*CHN_NUM), GFP_KERNEL); + mixer->sums = kcalloc(NUM_CT_SUMS * CHN_NUM, sizeof(void *), + GFP_KERNEL); if (!mixer->sums) { err = -ENOMEM; goto error2; @@ -937,17 +1001,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); } @@ -971,12 +1036,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); } @@ -1221,7 +1286,7 @@ int ct_alsa_mix_create(struct ct_atc *atc, if (err) return err; - strcpy(atc->card->mixername, device_name); + strscpy(atc->card->mixername, device_name); return 0; } |
