1919static DEFINE_MUTEX (gb_codec_list_lock );
2020static LIST_HEAD (gb_codec_list );
2121
22- static int gbcodec_event_spk (struct snd_soc_dapm_widget * w ,
23- struct snd_kcontrol * k , int event )
24- {
25- /* Ensure GB speaker is connected */
26-
27- return 0 ;
28- }
29-
30- static int gbcodec_event_hp (struct snd_soc_dapm_widget * w ,
31- struct snd_kcontrol * k , int event )
32- {
33- /* Ensure GB module supports jack slot */
34-
35- return 0 ;
36- }
37-
38- static int gbcodec_event_int_mic (struct snd_soc_dapm_widget * w ,
39- struct snd_kcontrol * k , int event )
40- {
41- /* Ensure GB module supports jack slot */
42-
43- return 0 ;
44- }
45-
46- static const struct snd_kcontrol_new gbcodec_snd_controls [] = {
47- SOC_DOUBLE ("Playback Mute" , GBCODEC_MUTE_REG , 0 , 1 , 1 , 1 ),
48- SOC_DOUBLE ("Capture Mute" , GBCODEC_MUTE_REG , 4 , 5 , 1 , 1 ),
49- SOC_DOUBLE_R ("Playback Volume" , GBCODEC_PB_LVOL_REG ,
50- GBCODEC_PB_RVOL_REG , 0 , 127 , 0 ),
51- SOC_DOUBLE_R ("Capture Volume" , GBCODEC_CAP_LVOL_REG ,
52- GBCODEC_CAP_RVOL_REG , 0 , 127 , 0 ),
53- };
54-
55- static const struct snd_kcontrol_new spk_amp_ctl =
56- SOC_DAPM_SINGLE ("Switch" , GBCODEC_CTL_REG , 0 , 1 , 0 );
57-
58- static const struct snd_kcontrol_new hp_amp_ctl =
59- SOC_DAPM_SINGLE ("Switch" , GBCODEC_CTL_REG , 1 , 1 , 0 );
60-
61- static const struct snd_kcontrol_new mic_adc_ctl =
62- SOC_DAPM_SINGLE ("Switch" , GBCODEC_CTL_REG , 4 , 1 , 0 );
63-
64- /* APB1-GBSPK source */
65- static const char * const gbcodec_apb1_src [] = {"Stereo" , "Left" , "Right" };
66-
67- static const SOC_ENUM_SINGLE_DECL (
68- gbcodec_apb1_rx_enum , GBCODEC_APB1_MUX_REG , 0 , gbcodec_apb1_src ) ;
69-
70- static const struct snd_kcontrol_new gbcodec_apb1_rx_mux =
71- SOC_DAPM_ENUM ("APB1 source" , gbcodec_apb1_rx_enum );
72-
73- static const SOC_ENUM_SINGLE_DECL (
74- gbcodec_mic_enum , GBCODEC_APB1_MUX_REG , 4 , gbcodec_apb1_src ) ;
75-
76- static const struct snd_kcontrol_new gbcodec_mic_mux =
77- SOC_DAPM_ENUM ("MIC source" , gbcodec_mic_enum );
78-
79- static const struct snd_soc_dapm_widget gbcodec_dapm_widgets [] = {
80- SND_SOC_DAPM_SPK ("Spk" , gbcodec_event_spk ),
81- SND_SOC_DAPM_SPK ("HP" , gbcodec_event_hp ),
82- SND_SOC_DAPM_MIC ("Int Mic" , gbcodec_event_int_mic ),
83-
84- SND_SOC_DAPM_OUTPUT ("SPKOUT" ),
85- SND_SOC_DAPM_OUTPUT ("HPOUT" ),
86-
87- SND_SOC_DAPM_INPUT ("MIC" ),
88- SND_SOC_DAPM_INPUT ("HSMIC" ),
89-
90- SND_SOC_DAPM_SWITCH ("SPK Amp" , SND_SOC_NOPM , 0 , 0 , & spk_amp_ctl ),
91- SND_SOC_DAPM_SWITCH ("HP Amp" , SND_SOC_NOPM , 0 , 0 , & hp_amp_ctl ),
92- SND_SOC_DAPM_SWITCH ("MIC ADC" , SND_SOC_NOPM , 0 , 0 , & mic_adc_ctl ),
93-
94- SND_SOC_DAPM_PGA ("SPK DAC" , SND_SOC_NOPM , 0 , 0 , NULL , 0 ),
95- SND_SOC_DAPM_PGA ("HP DAC" , SND_SOC_NOPM , 0 , 0 , NULL , 0 ),
96-
97- SND_SOC_DAPM_MIXER ("SPK Mixer" , SND_SOC_NOPM , 0 , 0 , NULL , 0 ),
98- SND_SOC_DAPM_MIXER ("HP Mixer" , SND_SOC_NOPM , 0 , 0 , NULL , 0 ),
99- SND_SOC_DAPM_MIXER ("APB1_TX Mixer" , SND_SOC_NOPM , 0 , 0 , NULL , 0 ),
100-
101- SND_SOC_DAPM_MUX ("APB1_RX Mux" , SND_SOC_NOPM , 0 , 0 ,
102- & gbcodec_apb1_rx_mux ),
103- SND_SOC_DAPM_MUX ("MIC Mux" , SND_SOC_NOPM , 0 , 0 , & gbcodec_mic_mux ),
104-
105- SND_SOC_DAPM_AIF_IN ("APB1RX" , "APBridgeA1 Playback" , 0 , SND_SOC_NOPM , 0 ,
106- 0 ),
107- SND_SOC_DAPM_AIF_OUT ("APB1TX" , "APBridgeA1 Capture" , 0 , SND_SOC_NOPM , 0 ,
108- 0 ),
109- };
110-
111- static const struct snd_soc_dapm_route gbcodec_dapm_routes [] = {
112- /* Playback path */
113- {"Spk" , NULL , "SPKOUT" },
114- {"SPKOUT" , NULL , "SPK Amp" },
115- {"SPK Amp" , "Switch" , "SPK DAC" },
116- {"SPK DAC" , NULL , "SPK Mixer" },
117-
118- {"HP" , NULL , "HPOUT" },
119- {"HPOUT" , NULL , "HP Amp" },
120- {"HP Amp" , "Switch" , "HP DAC" },
121- {"HP DAC" , NULL , "HP Mixer" },
122-
123- {"SPK Mixer" , NULL , "APB1_RX Mux" },
124- {"HP Mixer" , NULL , "APB1_RX Mux" },
125-
126- {"APB1_RX Mux" , "Left" , "APB1RX" },
127- {"APB1_RX Mux" , "Right" , "APB1RX" },
128- {"APB1_RX Mux" , "Stereo" , "APB1RX" },
129-
130- /* Capture path */
131- {"MIC" , NULL , "Int Mic" },
132- {"MIC" , NULL , "MIC Mux" },
133- {"MIC Mux" , "Left" , "MIC ADC" },
134- {"MIC Mux" , "Right" , "MIC ADC" },
135- {"MIC Mux" , "Stereo" , "MIC ADC" },
136- {"MIC ADC" , "Switch" , "APB1_TX Mixer" },
137- {"APB1_TX Mixer" , NULL , "APB1TX" }
138- };
139-
14022static int gbcodec_startup (struct snd_pcm_substream * substream ,
14123 struct snd_soc_dai * dai )
14224{
@@ -180,24 +62,9 @@ static struct snd_soc_dai_ops gbcodec_dai_ops = {
18062 .digital_mute = gbcodec_digital_mute ,
18163};
18264
183- static struct snd_soc_dai_driver gbcodec_dai = {
184- .playback = {
185- .stream_name = "APBridgeA1 Playback" ,
186- .channels_min = 1 ,
187- .channels_max = 2 ,
188- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100 ,
189- .formats = SNDRV_PCM_FMTBIT_S16_LE ,
190- },
191- .capture = {
192- .stream_name = "APBridgeA1 Capture" ,
193- .channels_min = 2 ,
194- .channels_max = 2 ,
195- .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100 ,
196- .formats = SNDRV_PCM_FMTBIT_S16_LE ,
197- },
198- .ops = & gbcodec_dai_ops ,
199- };
200-
65+ /*
66+ * codec driver ops
67+ */
20168static int gbcodec_probe (struct snd_soc_codec * codec )
20269{
20370 /* Empty function for now */
@@ -261,13 +128,6 @@ static struct snd_soc_codec_driver soc_codec_dev_gbcodec = {
261128 .reg_word_size = 1 ,
262129
263130 .idle_bias_off = true,
264-
265- .controls = gbcodec_snd_controls ,
266- .num_controls = ARRAY_SIZE (gbcodec_snd_controls ),
267- .dapm_widgets = gbcodec_dapm_widgets ,
268- .num_dapm_widgets = ARRAY_SIZE (gbcodec_dapm_widgets ),
269- .dapm_routes = gbcodec_dapm_routes ,
270- .num_dapm_routes = ARRAY_SIZE (gbcodec_dapm_routes ),
271131};
272132
273133/*
@@ -369,6 +229,9 @@ static struct gbaudio_codec_info *gbaudio_get_codec(struct device *dev,
369229
370230 mutex_init (& gbcodec -> lock );
371231 INIT_LIST_HEAD (& gbcodec -> dai_list );
232+ INIT_LIST_HEAD (& gbcodec -> widget_list );
233+ INIT_LIST_HEAD (& gbcodec -> codec_ctl_list );
234+ INIT_LIST_HEAD (& gbcodec -> widget_ctl_list );
372235 gbcodec -> dev_id = dev_id ;
373236 dev_set_drvdata (dev , gbcodec );
374237 gbcodec -> dev = dev ;
@@ -412,8 +275,9 @@ struct device_driver gb_codec_driver = {
412275
413276static int gbaudio_codec_probe (struct gb_connection * connection )
414277{
415- int ret ;
278+ int ret , i ;
416279 struct gbaudio_codec_info * gbcodec ;
280+ struct gb_audio_topology * topology ;
417281 struct device * dev = & connection -> bundle -> dev ;
418282 int dev_id = connection -> bundle -> id ;
419283
@@ -425,8 +289,35 @@ static int gbaudio_codec_probe(struct gb_connection *connection)
425289
426290 gbcodec -> mgmt_connection = connection ;
427291
292+ /* fetch topology data */
293+ ret = gb_audio_gb_get_topology (connection , & topology );
294+ if (ret ) {
295+ dev_err (gbcodec -> dev ,
296+ "%d:Error while fetching topology\n" , ret );
297+ goto base_error ;
298+ }
299+
300+ /* process topology data */
301+ ret = gbaudio_tplg_parse_data (gbcodec , topology );
302+ if (ret ) {
303+ dev_err (dev , "%d:Error while parsing topology data\n" ,
304+ ret );
305+ goto topology_error ;
306+ }
307+ gbcodec -> topology = topology ;
308+
309+ /* update codec info */
310+ soc_codec_dev_gbcodec .controls = gbcodec -> kctls ;
311+ soc_codec_dev_gbcodec .num_controls = gbcodec -> num_kcontrols ;
312+ soc_codec_dev_gbcodec .dapm_widgets = gbcodec -> widgets ;
313+ soc_codec_dev_gbcodec .num_dapm_widgets = gbcodec -> num_dapm_widgets ;
314+ soc_codec_dev_gbcodec .dapm_routes = gbcodec -> routes ;
315+ soc_codec_dev_gbcodec .num_dapm_routes = gbcodec -> num_dapm_routes ;
316+
428317 /* update DAI info */
429- gbcodec -> dais = & gbcodec_dai ;
318+ for (i = 0 ; i < gbcodec -> num_dais ; i ++ )
319+ gbcodec -> dais [i ].ops = & gbcodec_dai_ops ;
320+
430321 /* FIXME */
431322 dev -> driver = & gb_codec_driver ;
432323
@@ -435,7 +326,7 @@ static int gbaudio_codec_probe(struct gb_connection *connection)
435326 gbcodec -> dais , 1 );
436327 if (ret ) {
437328 dev_err (dev , "%d:Failed to register codec\n" , ret );
438- goto base_error ;
329+ goto parse_error ;
439330 }
440331
441332 /* update DAI links in response to this codec */
@@ -455,8 +346,13 @@ static int gbaudio_codec_probe(struct gb_connection *connection)
455346
456347codec_reg_error :
457348 snd_soc_unregister_codec (dev );
458- base_error :
459349 dev -> driver = NULL ;
350+ parse_error :
351+ gbaudio_tplg_release (gbcodec );
352+ gbcodec -> topology = NULL ;
353+ topology_error :
354+ kfree (topology );
355+ base_error :
460356 gbcodec -> mgmt_connection = NULL ;
461357 return ret ;
462358}
@@ -480,6 +376,8 @@ static void gbaudio_codec_remove(struct gb_connection *connection)
480376
481377 snd_soc_unregister_codec (dev );
482378 dev -> driver = NULL ;
379+ gbaudio_tplg_release (gbcodec );
380+ kfree (gbcodec -> topology );
483381 gbcodec -> mgmt_connection = NULL ;
484382 mutex_lock (& gbcodec -> lock );
485383 gbcodec -> codec_registered = 0 ;
@@ -509,68 +407,6 @@ static struct gb_protocol gb_audio_mgmt_protocol = {
509407 .request_recv = gbaudio_codec_report_event_recv ,
510408};
511409
512- static struct gbaudio_dai * gbaudio_allocate_dai (struct gbaudio_codec_info * gb ,
513- int data_cport ,
514- struct gb_connection * connection ,
515- const char * name )
516- {
517- struct gbaudio_dai * dai ;
518-
519- mutex_lock (& gb -> lock );
520- dai = devm_kzalloc (gb -> dev , sizeof (* dai ), GFP_KERNEL );
521- if (!dai ) {
522- dev_err (gb -> dev , "%s:DAI Malloc failure\n" , name );
523- mutex_unlock (& gb -> lock );
524- return NULL ;
525- }
526-
527- dai -> data_cport = data_cport ;
528- dai -> connection = connection ;
529-
530- /* update name */
531- if (name )
532- strlcpy (dai -> name , name , NAME_SIZE );
533- list_add (& dai -> list , & gb -> dai_list );
534- dev_dbg (gb -> dev , "%d:%s: DAI added\n" , data_cport , dai -> name );
535- mutex_unlock (& gb -> lock );
536-
537- return dai ;
538- }
539-
540- struct gbaudio_dai * gbaudio_add_dai (struct gbaudio_codec_info * gbcodec ,
541- int data_cport ,
542- struct gb_connection * connection ,
543- const char * name )
544- {
545- struct gbaudio_dai * dai , * _dai ;
546-
547- /* FIXME need to take care for multiple DAIs */
548- mutex_lock (& gbcodec -> lock );
549- if (list_empty (& gbcodec -> dai_list )) {
550- mutex_unlock (& gbcodec -> lock );
551- return gbaudio_allocate_dai (gbcodec , data_cport , connection ,
552- name );
553- }
554-
555- list_for_each_entry_safe (dai , _dai , & gbcodec -> dai_list , list ) {
556- if (dai -> data_cport == data_cport ) {
557- if (connection )
558- dai -> connection = connection ;
559-
560- if (name )
561- strlcpy (dai -> name , name , NAME_SIZE );
562- dev_dbg (gbcodec -> dev , "%d:%s: DAI updated\n" ,
563- data_cport , dai -> name );
564- mutex_unlock (& gbcodec -> lock );
565- return dai ;
566- }
567- }
568-
569- dev_err (gbcodec -> dev , "%s:DAI not found\n" , name );
570- mutex_unlock (& gbcodec -> lock );
571- return NULL ;
572- }
573-
574410static int gbaudio_dai_probe (struct gb_connection * connection )
575411{
576412 struct gbaudio_dai * dai ;
0 commit comments