11/*
22 * clsic-codec.c -- ALSA SoC Audio driver for CLSIC codec
33 *
4- * Copyright (C) 2015-2018 Cirrus Logic, Inc. and
4+ * Copyright (C) 2015-2019 Cirrus Logic, Inc. and
55 * Cirrus Logic International Semiconductor Ltd.
66 *
77 * This program is free software; you can redistribute it and/or modify
2929#include "tacna.h"
3030
3131#include <linux/mfd/clsic/core.h>
32- #include <linux/mfd/clsic/rassrv .h>
32+ #include <linux/mfd/clsic/clsic-tacna .h>
3333
3434#define CLSIC_N_FLL 2
3535#define CLSIC_NUM_DSP 2
3838#define CLSIC_DSP2_N_RX_CHANNELS 8
3939#define CLSIC_DSP2_N_TX_CHANNELS 8
4040
41+ /* MCD Trace Firmware can only be run on general purpose DSP */
42+ #define CLSIC_TRACE_DSP 1
43+
4144/* CLSIC codecs have four micbias switches named MICBIAS1A to MICBIAS1D */
4245#define CLSIC_MICBIAS_COUNT 4
4346#define CLSIC_MICBIAS_NAME_MAX 10
@@ -1304,6 +1307,8 @@ static const struct snd_soc_dapm_route clsic_dapm_routes[] = {
13041307 { "MICBIAS1C" , NULL , "MICVDD" },
13051308 { "MICBIAS1D" , NULL , "MICVDD" },
13061309
1310+ { "Audio Trace DSP" , NULL , "DSP2" },
1311+
13071312 { "Tone Generator 1" , NULL , "SYSCLK" },
13081313 { "Tone Generator 2" , NULL , "SYSCLK" },
13091314
@@ -1689,6 +1694,27 @@ static struct snd_soc_dai_driver clsic_dai[] = {
16891694 },
16901695 .ops = & tacna_simple_dai_ops ,
16911696 },
1697+ {
1698+ .name = "clsic-cpu-trace" ,
1699+ .capture = {
1700+ .stream_name = "Audio Trace CPU" ,
1701+ .channels_min = 1 ,
1702+ .channels_max = 6 ,
1703+ .rates = TACNA_RATES ,
1704+ .formats = TACNA_FORMATS ,
1705+ },
1706+ .compress_new = snd_soc_new_compress ,
1707+ },
1708+ {
1709+ .name = "clsic-dsp-trace" ,
1710+ .capture = {
1711+ .stream_name = "Audio Trace DSP" ,
1712+ .channels_min = 1 ,
1713+ .channels_max = 6 ,
1714+ .rates = TACNA_RATES ,
1715+ .formats = TACNA_FORMATS ,
1716+ },
1717+ },
16921718};
16931719
16941720static const struct soc_enum clsic_dsp1_rx_rate_enum [] = {
@@ -1976,6 +2002,38 @@ static void clsic_dsps_add_codec_controls(struct clsic_codec *clsic_codec)
19762002 }
19772003};
19782004
2005+ static int clsic_compr_open (struct snd_compr_stream * stream )
2006+ {
2007+ struct snd_soc_pcm_runtime * rtd = stream -> private_data ;
2008+ struct clsic_codec * clsic_codec =
2009+ snd_soc_platform_get_drvdata (rtd -> platform );
2010+ struct tacna_priv * priv = & clsic_codec -> core ;
2011+
2012+ if (strcmp (rtd -> codec_dai -> name , "clsic-dsp-trace" ) != 0 ) {
2013+ dev_err (priv -> dev ,
2014+ "No suitable compressed stream for DAI '%s'\n" ,
2015+ rtd -> codec_dai -> name );
2016+ return - EINVAL ;
2017+ }
2018+
2019+ return wm_adsp_compr_open (& priv -> dsp [CLSIC_TRACE_DSP ], stream );
2020+ }
2021+
2022+ static irqreturn_t clsic_dsp2_irq (int irq , void * data )
2023+ {
2024+ struct clsic_codec * clsic_codec = data ;
2025+ struct tacna_priv * priv = & clsic_codec -> core ;
2026+ int ret ;
2027+
2028+ ret = wm_adsp_compr_handle_irq (& priv -> dsp [CLSIC_TRACE_DSP ]);
2029+ if (ret == - ENODEV ) {
2030+ dev_err (priv -> dev , "Spurious compressed data IRQ\n" );
2031+ return IRQ_NONE ;
2032+ }
2033+
2034+ return IRQ_HANDLED ;
2035+ }
2036+
19792037static int clsic_codec_probe (struct snd_soc_codec * codec )
19802038{
19812039 struct clsic_codec * clsic_codec =
@@ -2022,7 +2080,8 @@ static int clsic_codec_probe(struct snd_soc_codec *codec)
20222080 "%s():%u Failed to add DSP2 routes: %d\n" ,
20232081 __func__ , __LINE__ , ret );
20242082
2025- wm_adsp2_codec_probe (& clsic_codec -> core .dsp [1 ], codec );
2083+ wm_adsp2_codec_probe (& clsic_codec -> core .dsp [CLSIC_TRACE_DSP ],
2084+ codec );
20262085 } else {
20272086 ret = snd_soc_dapm_new_controls (clsic_codec -> core .tacna -> dapm ,
20282087 clsic_dapm_widgets_dsp2_hidden ,
@@ -2057,7 +2116,8 @@ static int clsic_codec_remove(struct snd_soc_codec *codec)
20572116 tacna -> dapm = NULL ;
20582117
20592118 if (clsic_codec -> host_controls_dsp2 )
2060- wm_adsp2_codec_remove (& clsic_codec -> core .dsp [1 ], codec );
2119+ wm_adsp2_codec_remove (& clsic_codec -> core .dsp [CLSIC_TRACE_DSP ],
2120+ codec );
20612121
20622122 return 0 ;
20632123}
@@ -2124,6 +2184,20 @@ static const struct snd_soc_codec_driver soc_codec_dev_clsic = {
21242184 },
21252185};
21262186
2187+ static const struct snd_compr_ops clsic_compr_ops = {
2188+ .open = & clsic_compr_open ,
2189+ .free = & wm_adsp_compr_free ,
2190+ .set_params = & wm_adsp_compr_set_params ,
2191+ .get_caps = & wm_adsp_compr_get_caps ,
2192+ .trigger = & wm_adsp_compr_trigger ,
2193+ .pointer = & wm_adsp_compr_pointer ,
2194+ .copy = & wm_adsp_compr_copy ,
2195+ };
2196+
2197+ static const struct snd_soc_platform_driver clsic_compr_platform = {
2198+ .compr_ops = & clsic_compr_ops ,
2199+ };
2200+
21272201static int clsic_probe (struct platform_device * pdev )
21282202{
21292203 struct tacna * tacna = dev_get_drvdata (pdev -> dev .parent );
@@ -2164,10 +2238,17 @@ static int clsic_probe(struct platform_device *pdev)
21642238 clsic_micbias_init (clsic_codec );
21652239
21662240 /* TODO: initialise dsp2 MPU error interrupt */
2167- dsp = & clsic_codec -> core .dsp [1 ];
2241+ dsp = & clsic_codec -> core .dsp [CLSIC_TRACE_DSP ];
21682242 dsp -> num = 2 ;
21692243 dsp -> dev = clsic_codec -> core .tacna -> dev ;
21702244
2245+ ret = clsic_tacna_request_irq (tacna , CLSIC_TACNA_IRQ_DSP2_0 ,
2246+ "DSP2 IRQ0" , clsic_dsp2_irq , clsic_codec );
2247+ if (ret < 0 ) {
2248+ dev_err (& pdev -> dev , "Failed to register DSP2 IRQ: %d\n" , ret );
2249+ goto err_dsp2_irq ;
2250+ }
2251+
21712252 if (clsic_codec -> host_controls_dsp2 ) {
21722253 dsp -> part = clsic_devid_to_string (clsic -> devid );
21732254 dsp -> type = WMFW_HALO ;
@@ -2183,8 +2264,10 @@ static int clsic_probe(struct platform_device *pdev)
21832264 dsp -> n_tx_channels = CLSIC_DSP2_N_TX_CHANNELS ;
21842265
21852266 ret = wm_halo_init (dsp , & clsic_codec -> core .rate_lock );
2186- if (ret != 0 )
2267+ if (ret != 0 ) {
21872268 dev_err (& pdev -> dev , "Failed to initialise DSP2.\n" );
2269+ goto err_dsp2 ;
2270+ }
21882271
21892272 for (i = 0 ; i < CLSIC_N_FLL ; ++ i ) {
21902273 clsic_codec -> fll [i ].tacna_priv = & clsic_codec -> core ;
@@ -2208,14 +2291,32 @@ static int clsic_probe(struct platform_device *pdev)
22082291 pm_runtime_enable (& pdev -> dev );
22092292 pm_runtime_idle (& pdev -> dev );
22102293
2294+ ret = snd_soc_register_platform (& pdev -> dev , & clsic_compr_platform );
2295+ if (ret < 0 ) {
2296+ dev_err (& pdev -> dev , "Failed to register platform: %d\n" , ret );
2297+ goto err_plat ;
2298+ }
2299+
22112300 ret = snd_soc_register_codec (& pdev -> dev , & soc_codec_dev_clsic ,
22122301 clsic_dai , ARRAY_SIZE (clsic_dai ));
22132302 if (ret < 0 ) {
22142303 dev_err (& pdev -> dev , "Failed to register codec: %d\n" , ret );
2304+ goto err_codec ;
22152305 }
22162306
22172307 dev_info (& pdev -> dev , "%s() dev %p ret %d\n" , __func__ , & pdev -> dev , ret );
22182308
2309+ return ret ;
2310+
2311+ err_codec :
2312+ snd_soc_unregister_platform (& pdev -> dev );
2313+ err_plat :
2314+ wm_adsp2_remove (& clsic_codec -> core .dsp [CLSIC_TRACE_DSP ]);
2315+ err_dsp2 :
2316+ clsic_tacna_free_irq (tacna , CLSIC_TACNA_IRQ_DSP2_0 , clsic_codec );
2317+ err_dsp2_irq :
2318+ tacna_core_destroy (& clsic_codec -> core );
2319+
22192320 return ret ;
22202321}
22212322
@@ -2228,13 +2329,12 @@ static int clsic_remove(struct platform_device *pdev)
22282329 dev_dbg (& pdev -> dev , "%s() dev %p clsic %p priv %p\n" ,
22292330 __func__ , & pdev -> dev , clsic , clsic_codec );
22302331
2231- /* TODO XXX The stashed regmap is not valid from this point on */
2232-
2332+ snd_soc_unregister_platform (& pdev -> dev );
22332333 snd_soc_unregister_codec (& pdev -> dev );
2334+ clsic_tacna_free_irq (tacna , CLSIC_TACNA_IRQ_DSP2_0 , clsic_codec );
22342335 pm_runtime_disable (& pdev -> dev );
22352336
2236- if (clsic_codec -> host_controls_dsp2 )
2237- wm_adsp2_remove (& clsic_codec -> core .dsp [1 ]);
2337+ wm_adsp2_remove (& clsic_codec -> core .dsp [CLSIC_TRACE_DSP ]);
22382338
22392339 tacna_core_destroy (& clsic_codec -> core );
22402340
0 commit comments