Skip to content

Commit f2b4592

Browse files
committed
Add support for cs42l45 into the Intel machine driver
Merge series from Charles Keepax <ckeepax@opensource.cirrus.com>: Now that the full class driver is in place we can add support to the Intel machine driver for Cirrus's new SDCA audio CODEC the cs42l45. This makes some minor tweaks to the machine driver itself to support SDCA devices, and then adds the necessary tables etc. to define the device. Note, this series shouldn't have any dependencies on the other series of improvements to the class driver that is already on the list. So either can be merged first.
2 parents 86dc090 + 1e645bc commit f2b4592

10 files changed

Lines changed: 275 additions & 81 deletions

File tree

include/sound/sdca_function.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ enum sdca_entity0_controls {
611611
#define SDCA_CTL_NDAI_PACKETTYPE_NAME "NDAI Packet Type"
612612
#define SDCA_CTL_MIXER_NAME "Mixer"
613613
#define SDCA_CTL_SELECTOR_NAME "Selector"
614-
#define SDCA_CTL_MUTE_NAME "Mute"
614+
#define SDCA_CTL_MUTE_NAME "Channel"
615615
#define SDCA_CTL_CHANNEL_VOLUME_NAME "Channel Volume"
616616
#define SDCA_CTL_AGC_NAME "AGC"
617617
#define SDCA_CTL_BASS_BOOST_NAME "Bass Boost"
@@ -1456,6 +1456,8 @@ int sdca_parse_function(struct device *dev, struct sdw_slave *sdw,
14561456
struct sdca_function_desc *desc,
14571457
struct sdca_function_data *function);
14581458

1459+
const char *sdca_find_terminal_name(enum sdca_terminal_type type);
1460+
14591461
struct sdca_control *sdca_selector_find_control(struct device *dev,
14601462
struct sdca_entity *entity,
14611463
const int sel);

include/sound/soc_sdw_utils.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <sound/soc-acpi.h>
1414

1515
#define SOC_SDW_MAX_DAI_NUM 8
16+
#define SOC_SDW_MAX_AUX_NUM 2
1617
#define SOC_SDW_MAX_NO_PROPS 2
1718
#define SOC_SDW_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
1819

@@ -45,6 +46,7 @@ struct asoc_sdw_codec_info;
4546

4647
struct asoc_sdw_dai_info {
4748
const bool direction[2]; /* playback & capture support */
49+
const char *codec_name;
4850
const char *dai_name;
4951
const char *component_name;
5052
const int dai_type;
@@ -64,17 +66,22 @@ struct asoc_sdw_dai_info {
6466
bool quirk_exclude;
6567
};
6668

69+
struct asoc_sdw_aux_info {
70+
const char *codec_name;
71+
};
72+
6773
struct asoc_sdw_codec_info {
6874
const int part_id;
6975
const int version_id;
70-
const char *codec_name;
7176
const char *name_prefix;
7277
int amp_num;
7378
const u8 acpi_id[ACPI_ID_LEN];
7479
const bool ignore_internal_dmic;
7580
const struct snd_soc_ops *ops;
7681
struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM];
7782
const int dai_num;
83+
struct asoc_sdw_aux_info auxs[SOC_SDW_MAX_AUX_NUM];
84+
const int aux_num;
7885

7986
int (*codec_card_late_probe)(struct snd_soc_card *card);
8087

@@ -131,7 +138,7 @@ int asoc_sdw_hw_free(struct snd_pcm_substream *substream);
131138
void asoc_sdw_shutdown(struct snd_pcm_substream *substream);
132139

133140
const char *asoc_sdw_get_codec_name(struct device *dev,
134-
const struct asoc_sdw_codec_info *codec_info,
141+
const struct asoc_sdw_dai_info *dai_info,
135142
const struct snd_soc_acpi_link_adr *adr_link,
136143
int adr_index);
137144

@@ -165,13 +172,15 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d
165172
int no_pcm, int (*init)(struct snd_soc_pcm_runtime *rtd),
166173
const struct snd_soc_ops *ops);
167174

168-
int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends);
175+
int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
176+
int *num_devs, int *num_ends, int *num_aux);
169177

170178
struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
171179
const struct snd_soc_acpi_endpoint *new);
172180
int asoc_sdw_get_dai_type(u32 type);
173181

174182
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
183+
struct snd_soc_aux_dev *soc_aux,
175184
struct asoc_sdw_dailink *soc_dais,
176185
struct asoc_sdw_endpoint *soc_ends,
177186
int *num_devs);
@@ -248,6 +257,8 @@ int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da
248257
int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
249258
int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
250259
int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
260+
int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
261+
int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
251262
int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
252263
int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
253264
/* TI */

sound/soc/amd/acp/acp-sdw-legacy-mach.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,20 +360,25 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
360360
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
361361
struct asoc_sdw_endpoint *soc_ends __free(kfree) = NULL;
362362
struct asoc_sdw_dailink *soc_dais __free(kfree) = NULL;
363+
struct snd_soc_aux_dev *soc_aux;
363364
struct snd_soc_codec_conf *codec_conf;
364365
struct snd_soc_dai_link *dai_links;
365366
int num_devs = 0;
366367
int num_ends = 0;
368+
int num_aux = 0;
369+
int num_confs;
367370
int num_links;
368371
int be_id = 0;
369372
int ret;
370373

371-
ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends);
374+
ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends, &num_aux);
372375
if (ret < 0) {
373376
dev_err(dev, "failed to count devices/endpoints: %d\n", ret);
374377
return ret;
375378
}
376379

380+
num_confs = num_ends;
381+
377382
/* One per DAI link, worst case is a DAI link for every endpoint */
378383
soc_dais = kcalloc(num_ends, sizeof(*soc_dais), GFP_KERNEL);
379384
if (!soc_dais)
@@ -384,7 +389,11 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
384389
if (!soc_ends)
385390
return -ENOMEM;
386391

387-
ret = asoc_sdw_parse_sdw_endpoints(card, soc_dais, soc_ends, &num_devs);
392+
soc_aux = devm_kcalloc(dev, num_aux, sizeof(*soc_aux), GFP_KERNEL);
393+
if (!soc_aux)
394+
return -ENOMEM;
395+
396+
ret = asoc_sdw_parse_sdw_endpoints(card, soc_aux, soc_dais, soc_ends, &num_confs);
388397
if (ret < 0)
389398
return ret;
390399

@@ -396,7 +405,7 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
396405

397406
dev_dbg(dev, "sdw %d, dmic %d", sdw_be_num, dmic_num);
398407

399-
codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
408+
codec_conf = devm_kcalloc(dev, num_confs, sizeof(*codec_conf), GFP_KERNEL);
400409
if (!codec_conf)
401410
return -ENOMEM;
402411

@@ -407,9 +416,11 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
407416
return -ENOMEM;
408417

409418
card->codec_conf = codec_conf;
410-
card->num_configs = num_devs;
419+
card->num_configs = num_confs;
411420
card->dai_link = dai_links;
412421
card->num_links = num_links;
422+
card->aux_dev = soc_aux;
423+
card->num_aux_devs = num_aux;
413424

414425
/* SDW */
415426
if (sdw_be_num) {

sound/soc/amd/acp/acp-sdw-sof-mach.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,15 +272,17 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
272272
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
273273
struct asoc_sdw_endpoint *sof_ends __free(kfree) = NULL;
274274
struct asoc_sdw_dailink *sof_dais __free(kfree) = NULL;
275+
struct snd_soc_aux_dev *sof_aux;
275276
struct snd_soc_codec_conf *codec_conf;
276277
struct snd_soc_dai_link *dai_links;
277278
int num_devs = 0;
278279
int num_ends = 0;
280+
int num_aux = 0;
279281
int num_links;
280282
int be_id = 0;
281283
int ret;
282284

283-
ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends);
285+
ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends, &num_aux);
284286
if (ret < 0) {
285287
dev_err(dev, "failed to count devices/endpoints: %d\n", ret);
286288
return ret;
@@ -296,7 +298,11 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
296298
if (!sof_ends)
297299
return -ENOMEM;
298300

299-
ret = asoc_sdw_parse_sdw_endpoints(card, sof_dais, sof_ends, &num_devs);
301+
sof_aux = devm_kcalloc(dev, num_aux, sizeof(*sof_aux), GFP_KERNEL);
302+
if (!sof_aux)
303+
return -ENOMEM;
304+
305+
ret = asoc_sdw_parse_sdw_endpoints(card, sof_aux, sof_dais, sof_ends, &num_devs);
300306
if (ret < 0)
301307
return ret;
302308

@@ -322,6 +328,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
322328
card->num_configs = num_devs;
323329
card->dai_link = dai_links;
324330
card->num_links = num_links;
331+
card->aux_dev = sof_aux;
332+
card->num_aux_devs = num_aux;
325333

326334
/* SDW */
327335
if (sdw_be_num) {

sound/soc/intel/boards/sof_sdw.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,21 +1189,26 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
11891189
struct asoc_sdw_codec_info *ssp_info;
11901190
struct asoc_sdw_endpoint *sof_ends;
11911191
struct asoc_sdw_dailink *sof_dais;
1192+
struct snd_soc_aux_dev *sof_aux;
11921193
int num_devs = 0;
11931194
int num_ends = 0;
1195+
int num_aux = 0;
1196+
int num_confs;
11941197
struct snd_soc_dai_link *dai_links;
11951198
int num_links;
11961199
int be_id = 0;
11971200
int hdmi_num;
11981201
unsigned long ssp_mask;
11991202
int ret;
12001203

1201-
ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends);
1204+
ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends, &num_aux);
12021205
if (ret < 0) {
12031206
dev_err(dev, "failed to count devices/endpoints: %d\n", ret);
12041207
return ret;
12051208
}
12061209

1210+
num_confs = num_ends;
1211+
12071212
/*
12081213
* One per DAI link, worst case is a DAI link for every endpoint, also
12091214
* add one additional to act as a terminator such that code can iterate
@@ -1220,7 +1225,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
12201225
goto err_dai;
12211226
}
12221227

1223-
ret = asoc_sdw_parse_sdw_endpoints(card, sof_dais, sof_ends, &num_devs);
1228+
sof_aux = devm_kcalloc(dev, num_aux, sizeof(*sof_aux), GFP_KERNEL);
1229+
if (!sof_aux) {
1230+
ret = -ENOMEM;
1231+
goto err_dai;
1232+
}
1233+
1234+
ret = asoc_sdw_parse_sdw_endpoints(card, sof_aux, sof_dais, sof_ends, &num_confs);
12241235
if (ret < 0)
12251236
goto err_end;
12261237

@@ -1268,7 +1279,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
12681279
sdw_be_num, ssp_num, dmic_num,
12691280
intel_ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num);
12701281

1271-
codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
1282+
codec_conf = devm_kcalloc(dev, num_confs, sizeof(*codec_conf), GFP_KERNEL);
12721283
if (!codec_conf) {
12731284
ret = -ENOMEM;
12741285
goto err_end;
@@ -1283,9 +1294,11 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
12831294
}
12841295

12851296
card->codec_conf = codec_conf;
1286-
card->num_configs = num_devs;
1297+
card->num_configs = num_confs;
12871298
card->dai_link = dai_links;
12881299
card->num_links = num_links;
1300+
card->aux_dev = sof_aux;
1301+
card->num_aux_devs = num_aux;
12891302

12901303
/* SDW */
12911304
if (sdw_be_num) {

sound/soc/sdca/sdca_asoc.c

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -115,50 +115,6 @@ int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *fun
115115
}
116116
EXPORT_SYMBOL_NS(sdca_asoc_count_component, "SND_SOC_SDCA");
117117

118-
static const char *get_terminal_name(enum sdca_terminal_type type)
119-
{
120-
switch (type) {
121-
case SDCA_TERM_TYPE_LINEIN_STEREO:
122-
return SDCA_TERM_TYPE_LINEIN_STEREO_NAME;
123-
case SDCA_TERM_TYPE_LINEIN_FRONT_LR:
124-
return SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME;
125-
case SDCA_TERM_TYPE_LINEIN_CENTER_LFE:
126-
return SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME;
127-
case SDCA_TERM_TYPE_LINEIN_SURROUND_LR:
128-
return SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME;
129-
case SDCA_TERM_TYPE_LINEIN_REAR_LR:
130-
return SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME;
131-
case SDCA_TERM_TYPE_LINEOUT_STEREO:
132-
return SDCA_TERM_TYPE_LINEOUT_STEREO_NAME;
133-
case SDCA_TERM_TYPE_LINEOUT_FRONT_LR:
134-
return SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME;
135-
case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE:
136-
return SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME;
137-
case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR:
138-
return SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME;
139-
case SDCA_TERM_TYPE_LINEOUT_REAR_LR:
140-
return SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME;
141-
case SDCA_TERM_TYPE_MIC_JACK:
142-
return SDCA_TERM_TYPE_MIC_JACK_NAME;
143-
case SDCA_TERM_TYPE_STEREO_JACK:
144-
return SDCA_TERM_TYPE_STEREO_JACK_NAME;
145-
case SDCA_TERM_TYPE_FRONT_LR_JACK:
146-
return SDCA_TERM_TYPE_FRONT_LR_JACK_NAME;
147-
case SDCA_TERM_TYPE_CENTER_LFE_JACK:
148-
return SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME;
149-
case SDCA_TERM_TYPE_SURROUND_LR_JACK:
150-
return SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME;
151-
case SDCA_TERM_TYPE_REAR_LR_JACK:
152-
return SDCA_TERM_TYPE_REAR_LR_JACK_NAME;
153-
case SDCA_TERM_TYPE_HEADPHONE_JACK:
154-
return SDCA_TERM_TYPE_HEADPHONE_JACK_NAME;
155-
case SDCA_TERM_TYPE_HEADSET_JACK:
156-
return SDCA_TERM_TYPE_HEADSET_JACK_NAME;
157-
default:
158-
return NULL;
159-
}
160-
}
161-
162118
static int entity_early_parse_ge(struct device *dev,
163119
struct sdca_function_data *function,
164120
struct sdca_entity *entity)
@@ -217,7 +173,7 @@ static int entity_early_parse_ge(struct device *dev,
217173
type = sdca_range(range, SDCA_SELECTED_MODE_TERM_TYPE, i);
218174

219175
values[i + 3] = sdca_range(range, SDCA_SELECTED_MODE_INDEX, i);
220-
texts[i + 3] = get_terminal_name(type);
176+
texts[i + 3] = sdca_find_terminal_name(type);
221177
if (!texts[i + 3]) {
222178
dev_err(dev, "%s: unrecognised terminal type: %#x\n",
223179
entity->label, type);
@@ -499,7 +455,7 @@ static int entity_parse_su_device(struct device *dev,
499455
return -EINVAL;
500456
}
501457

502-
add_route(route, entity->label, get_terminal_name(term),
458+
add_route(route, entity->label, sdca_find_terminal_name(term),
503459
entity->sources[affected->val - 1]->label);
504460
}
505461
}
@@ -886,6 +842,9 @@ static int populate_control(struct device *dev,
886842
mc->min = 0;
887843
mc->max = clamp((0x1ull << control->nbits) - 1, 0, type_max(mc->max));
888844

845+
if (SDCA_CTL_TYPE(entity->type, control->sel) == SDCA_CTL_TYPE_S(FU, MUTE))
846+
mc->invert = true;
847+
889848
(*kctl)->name = control_name;
890849
(*kctl)->private_value = (unsigned long)mc;
891850
(*kctl)->iface = SNDRV_CTL_ELEM_IFACE_MIXER;

0 commit comments

Comments
 (0)