ALSA: ctxfi: Refactor resource alloc for sparse mappings

Refactor atc_get_resources(), atc_connect_resources(), and
atc_release_resources() to allocate resources based on maximum type
definitions.

This allows specific resources to be conditionally skipped based on
capabilities. This is necessary for hardware variants where resource
allocations do not follow a sequential order.

Signed-off-by: Harin Lee <me@harin.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20251124180501.2760421-5-me@harin.net
This commit is contained in:
Harin Lee 2025-11-25 03:04:59 +09:00 committed by Takashi Iwai
parent 9bb003a1f9
commit a2dbaeb5c6
2 changed files with 35 additions and 29 deletions

View File

@ -25,6 +25,9 @@
#include <sound/control.h>
#include <sound/asoundef.h>
#define NUM_ATC_SRCS 6
#define NUM_ATC_PCM (2 * 4)
#define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */
#define MAX_MULTI_CHN 8
@ -1161,8 +1164,10 @@ static int atc_release_resources(struct ct_atc *atc)
if (atc->daios) {
daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
for (i = 0; i < atc->n_daio; i++) {
for (i = 0; i < NUM_DAIOTYP; i++) {
daio = atc->daios[i];
if (!daio)
continue;
if (daio->output) {
dao = container_of(daio, struct dao, daio);
dao->ops->clear_left_input(dao);
@ -1176,8 +1181,9 @@ static int atc_release_resources(struct ct_atc *atc)
if (atc->pcm) {
sum_mgr = atc->rsc_mgrs[SUM];
for (i = 0; i < atc->n_pcm; i++)
sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
for (i = 0; i < NUM_ATC_PCM; i++)
if (atc->pcm[i])
sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
kfree(atc->pcm);
atc->pcm = NULL;
@ -1185,8 +1191,9 @@ static int atc_release_resources(struct ct_atc *atc)
if (atc->srcs) {
src_mgr = atc->rsc_mgrs[SRC];
for (i = 0; i < atc->n_src; i++)
src_mgr->put_src(src_mgr, atc->srcs[i]);
for (i = 0; i < NUM_ATC_SRCS; i++)
if (atc->srcs[i])
src_mgr->put_src(src_mgr, atc->srcs[i]);
kfree(atc->srcs);
atc->srcs = NULL;
@ -1194,7 +1201,9 @@ static int atc_release_resources(struct ct_atc *atc)
if (atc->srcimps) {
srcimp_mgr = atc->rsc_mgrs[SRCIMP];
for (i = 0; i < atc->n_srcimp; i++) {
for (i = 0; i < NUM_ATC_SRCS; i++) {
if (!atc->srcimps[i])
continue;
srcimp = atc->srcimps[i];
srcimp->ops->unmap(srcimp);
srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]);
@ -1367,30 +1376,32 @@ static int atc_get_resources(struct ct_atc *atc)
struct srcimp_mgr *srcimp_mgr;
struct sum_desc sum_dsc = {0};
struct sum_mgr *sum_mgr;
int err, i, num_srcs, num_daios;
struct capabilities cap;
int err, i;
num_daios = ((atc->model == CTSB1270) ? 8 : 7);
num_srcs = ((atc->model == CTSB1270) ? 6 : 4);
cap = atc->capabilities(atc);
atc->daios = kcalloc(num_daios, sizeof(void *), GFP_KERNEL);
atc->daios = kcalloc(NUM_DAIOTYP, sizeof(void *), GFP_KERNEL);
if (!atc->daios)
return -ENOMEM;
atc->srcs = kcalloc(num_srcs, sizeof(void *), GFP_KERNEL);
atc->srcs = kcalloc(NUM_ATC_SRCS, sizeof(void *), GFP_KERNEL);
if (!atc->srcs)
return -ENOMEM;
atc->srcimps = kcalloc(num_srcs, sizeof(void *), GFP_KERNEL);
atc->srcimps = kcalloc(NUM_ATC_SRCS, sizeof(void *), GFP_KERNEL);
if (!atc->srcimps)
return -ENOMEM;
atc->pcm = kcalloc(2 * 4, sizeof(void *), GFP_KERNEL);
atc->pcm = kcalloc(NUM_ATC_PCM, sizeof(void *), GFP_KERNEL);
if (!atc->pcm)
return -ENOMEM;
daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
da_desc.msr = atc->msr;
for (i = 0, atc->n_daio = 0; i < num_daios; i++) {
for (i = 0; i < NUM_DAIOTYP; i++) {
if ((i == MIC) && !cap.dedicated_mic)
continue;
da_desc.type = (atc->model != CTSB073X) ? i :
((i == SPDIFIO) ? SPDIFI1 : i);
da_desc.output = i < LINEIM;
@ -1402,42 +1413,39 @@ static int atc_get_resources(struct ct_atc *atc)
i);
return err;
}
atc->n_daio++;
}
src_mgr = atc->rsc_mgrs[SRC];
src_dsc.multi = 1;
src_dsc.msr = atc->msr;
src_dsc.mode = ARCRW;
for (i = 0, atc->n_src = 0; i < num_srcs; i++) {
for (i = 0; i < NUM_ATC_SRCS; i++) {
if (((i > 3) && !cap.dedicated_mic))
continue;
err = src_mgr->get_src(src_mgr, &src_dsc,
(struct src **)&atc->srcs[i]);
if (err)
return err;
atc->n_src++;
}
srcimp_mgr = atc->rsc_mgrs[SRCIMP];
srcimp_dsc.msr = 8;
for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) {
for (i = 0; i < NUM_ATC_SRCS; i++) {
if (((i > 3) && !cap.dedicated_mic))
continue;
err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
(struct srcimp **)&atc->srcimps[i]);
if (err)
return err;
atc->n_srcimp++;
}
sum_mgr = atc->rsc_mgrs[SUM];
sum_dsc.msr = atc->msr;
for (i = 0, atc->n_pcm = 0; i < (2*4); i++) {
for (i = 0; i < NUM_ATC_PCM; i++) {
err = sum_mgr->get_sum(sum_mgr, &sum_dsc,
(struct sum **)&atc->pcm[i]);
if (err)
return err;
atc->n_pcm++;
}
return 0;
@ -1490,9 +1498,11 @@ static void atc_connect_resources(struct ct_atc *atc)
struct sum *sum;
struct ct_mixer *mixer;
struct rsc *rscs[2] = {NULL};
struct capabilities cap;
int i, j;
mixer = atc->mixer;
cap = atc->capabilities(atc);
for (i = MIX_WAVE_FRONT, j = LINEO1; i <= MIX_SPDIF_OUT; i++, j++) {
mixer->get_output_ports(mixer, i, &rscs[0], &rscs[1]);
@ -1510,7 +1520,7 @@ static void atc_connect_resources(struct ct_atc *atc)
src = atc->srcs[3];
mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
if (atc->model == CTSB1270) {
if (cap.dedicated_mic) {
/* Titanium HD has a dedicated ADC for the Mic. */
dai = container_of(atc->daios[MIC], struct dai, daio);
atc_connect_dai(atc->rsc_mgrs[SRC], dai,

View File

@ -132,10 +132,6 @@ struct ct_atc {
void **pcm; /* SUMs for collecting all pcm stream */
void **srcs; /* Sample Rate Converters for input signal */
void **srcimps; /* input mappers for SRCs */
unsigned char n_daio;
unsigned char n_src;
unsigned char n_srcimp;
unsigned char n_pcm;
struct ct_timer *timer;