/* FIXME: this static looks like it would fail if more than one card was */ /* installed. */ staticstruct snd_kcontrol *kctls[2] = {NULL};
staticenum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index)
{ switch (alsa_index) { case MIXER_MASTER_P: return AMIXER_MASTER_F; case MIXER_MASTER_C: return AMIXER_MASTER_F_C; case MIXER_PCM_P: return AMIXER_PCM_F; case MIXER_PCM_C: case MIXER_PCM_C_S: return AMIXER_PCM_F_C; case MIXER_LINEIN_P: return AMIXER_LINEIN; case MIXER_LINEIN_C: case MIXER_LINEIN_C_S: return AMIXER_LINEIN_C; case MIXER_MIC_P: return AMIXER_MIC; case MIXER_MIC_C: case MIXER_MIC_C_S: return AMIXER_MIC_C; case MIXER_SPDIFI_P: return AMIXER_SPDIFI; case MIXER_SPDIFI_C: case MIXER_SPDIFI_C_S: return AMIXER_SPDIFI_C; case MIXER_SPDIFO_P: return AMIXER_SPDIFO; case MIXER_WAVEF_P: return AMIXER_WAVE_F; case MIXER_WAVES_P: return AMIXER_WAVE_S; case MIXER_WAVEC_P: return AMIXER_WAVE_C; case MIXER_WAVER_P: return AMIXER_WAVE_R; default: return NUM_CT_AMIXERS;
}
}
staticenum CT_AMIXER_CTL get_recording_amixer(enum CT_AMIXER_CTL index)
{ switch (index) { case AMIXER_MASTER_F: return AMIXER_MASTER_F_C; case AMIXER_PCM_F: return AMIXER_PCM_F_C; case AMIXER_SPDIFI: return AMIXER_SPDIFI_C; case AMIXER_LINEIN: return AMIXER_LINEIN_C; case AMIXER_MIC: return AMIXER_MIC_C; default: return NUM_CT_AMIXERS;
}
}
#if 0 /* not used */ /* Map integer value ranging from 0 to 65535 to 14-bit float value ranging
* from 2^-6 to (1+1023/1024) */ staticunsignedint uint16_to_float14(unsignedint x)
{ unsignedint i;
if (x < 17) return 0;
x *= 2031;
x /= 65535;
x += 16;
/* i <= 6 */ for (i = 0; !(x & 0x400); i++)
x <<= 1;
/* Allocate sum resources for mixer obj */
sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM];
sum_desc.msr = mixer->atc->msr; for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) {
err = sum_mgr->get_sum(sum_mgr, &sum_desc, &sum); if (err) {
dev_err(mixer->atc->card->dev, "Failed to get sum resources for front output!\n"); break;
}
mixer->sums[i] = sum;
} if (err) goto error1;
/* Allocate amixer resources for mixer obj */
amixer_mgr = (struct amixer_mgr *)mixer->atc->rsc_mgrs[AMIXER];
am_desc.msr = mixer->atc->msr; for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) {
err = amixer_mgr->get_amixer(amixer_mgr, &am_desc, &amixer); if (err) {
dev_err(mixer->atc->card->dev, "Failed to get amixer resources for mixer obj!\n"); break;
}
mixer->amixers[i] = amixer;
} if (err) goto error2;
return 0;
error2: for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) { if (NULL != mixer->amixers[i]) {
amixer = mixer->amixers[i];
amixer_mgr->put_amixer(amixer_mgr, amixer);
mixer->amixers[i] = NULL;
}
}
error1: for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) { if (NULL != mixer->sums[i]) {
sum_mgr->put_sum(sum_mgr, (struct sum *)mixer->sums[i]);
mixer->sums[i] = NULL;
}
}
return err;
}
staticint ct_mixer_get_mem(struct ct_mixer **rmixer)
{ struct ct_mixer *mixer; int err;
*rmixer = NULL; /* Allocate mem for mixer obj */
mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); if (!mixer) return -ENOMEM;
staticint 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, k = SUM_IN_F;
i <= AMIXER_MASTER_S; i++, k++) {
amix_d = mixer->amixers[i*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[k*CHN_NUM+1];
amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
}
/* Set up Wave-out mixer */ for (i = AMIXER_WAVE_F, j = AMIXER_MASTER_F;
i <= AMIXER_WAVE_S; i++, j++) {
amix_d = mixer->amixers[i*CHN_NUM];
amix_s = mixer->amixers[j*CHN_NUM];
amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
amix_d = mixer->amixers[i*CHN_NUM+1];
amix_s = mixer->amixers[j*CHN_NUM+1];
amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
}
/* Set up PCM-in mixer */ 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[k*CHN_NUM];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
amix_d = mixer->amixers[i*CHN_NUM+1];
sum = mixer->sums[k*CHN_NUM+1];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
}
/* Set up Line-in mixer */
amix_d = mixer->amixers[AMIXER_LINEIN*CHN_NUM];
sum = mixer->sums[SUM_IN_F*CHN_NUM];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
amix_d = mixer->amixers[AMIXER_LINEIN*CHN_NUM+1];
sum = mixer->sums[SUM_IN_F*CHN_NUM+1];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
/* Set up Mic-in mixer */
amix_d = mixer->amixers[AMIXER_MIC*CHN_NUM];
sum = mixer->sums[SUM_IN_F*CHN_NUM];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
amix_d = mixer->amixers[AMIXER_MIC*CHN_NUM+1];
sum = mixer->sums[SUM_IN_F*CHN_NUM+1];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
/* Set up S/PDIF-in mixer */
amix_d = mixer->amixers[AMIXER_SPDIFI*CHN_NUM];
sum = mixer->sums[SUM_IN_F*CHN_NUM];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
amix_d = mixer->amixers[AMIXER_SPDIFI*CHN_NUM+1];
sum = mixer->sums[SUM_IN_F*CHN_NUM+1];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
/* Set up Master recording mixer */
amix_d = mixer->amixers[AMIXER_MASTER_F_C*CHN_NUM];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
amix_d = mixer->amixers[AMIXER_MASTER_F_C*CHN_NUM+1];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
/* Set up PCM-in recording mixer */
amix_d = mixer->amixers[AMIXER_PCM_F_C*CHN_NUM];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
amix_d = mixer->amixers[AMIXER_PCM_F_C*CHN_NUM+1];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
/* Set up Line-in recording mixer */
amix_d = mixer->amixers[AMIXER_LINEIN_C*CHN_NUM];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
amix_d = mixer->amixers[AMIXER_LINEIN_C*CHN_NUM+1];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
/* Set up Mic-in recording mixer */
amix_d = mixer->amixers[AMIXER_MIC_C*CHN_NUM];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
amix_d = mixer->amixers[AMIXER_MIC_C*CHN_NUM+1];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
/* Set up S/PDIF-in recording mixer */
amix_d = mixer->amixers[AMIXER_SPDIFI_C*CHN_NUM];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
amix_d = mixer->amixers[AMIXER_SPDIFI_C*CHN_NUM+1];
sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
#ifdef CONFIG_PM_SLEEP staticint mixer_resume(struct ct_mixer *mixer)
{ int i, state; struct amixer *amixer;
/* resume topology and volume gain. */ for (i = 0; i < NUM_CT_AMIXERS*CHN_NUM; i++) {
amixer = mixer->amixers[i];
amixer->ops->commit_write(amixer);
}
/* resume switch state. */ for (i = SWH_MIXER_START; i <= SWH_MIXER_END; i++) {
state = get_switch_state(mixer, i);
do_switch(mixer->atc, i, state);
}
return 0;
} #endif
int ct_mixer_destroy(struct ct_mixer *mixer)
{ struct sum_mgr *sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM]; struct amixer_mgr *amixer_mgr =
(struct amixer_mgr *)mixer->atc->rsc_mgrs[AMIXER]; struct amixer *amixer; int i = 0;
/* Release amixer resources */ for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) { if (NULL != mixer->amixers[i]) {
amixer = mixer->amixers[i];
amixer_mgr->put_amixer(amixer_mgr, amixer);
}
}
/* Release sum resources */ for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) { if (NULL != mixer->sums[i])
sum_mgr->put_sum(sum_mgr, (struct sum *)mixer->sums[i]);
}
/* Release mem assigned to mixer object */
kfree(mixer->sums);
kfree(mixer->amixers);
kfree(mixer);
return 0;
}
int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer)
{ struct ct_mixer *mixer; int err;
*rmixer = NULL;
/* Allocate mem for mixer obj */
err = ct_mixer_get_mem(&mixer); if (err) return err;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.