brintos

brintos / linux-shallow public Read only

0
0
Text · 14.8 KiB · 09ad6e9 Raw
459 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Cirrus Logic Madera class codecs common support4 *5 * Copyright (C) 2015-2018 Cirrus Logic, Inc. and6 *                         Cirrus Logic International Semiconductor Ltd.7 */8 9#ifndef ASOC_MADERA_H10#define ASOC_MADERA_H11 12#include <linux/completion.h>13#include <sound/soc.h>14#include <sound/madera-pdata.h>15 16#include "wm_adsp.h"17 18#define MADERA_FLL1_REFCLK		119#define MADERA_FLL2_REFCLK		220#define MADERA_FLL3_REFCLK		321#define MADERA_FLLAO_REFCLK		422#define MADERA_FLL1_SYNCCLK		523#define MADERA_FLL2_SYNCCLK		624#define MADERA_FLL3_SYNCCLK		725#define MADERA_FLLAO_SYNCCLK		826 27#define MADERA_FLL_SRC_NONE		-128#define MADERA_FLL_SRC_MCLK1		029#define MADERA_FLL_SRC_MCLK2		130#define MADERA_FLL_SRC_MCLK3		231#define MADERA_FLL_SRC_SLIMCLK		332#define MADERA_FLL_SRC_FLL1		433#define MADERA_FLL_SRC_FLL2		534#define MADERA_FLL_SRC_AIF1BCLK		835#define MADERA_FLL_SRC_AIF2BCLK		936#define MADERA_FLL_SRC_AIF3BCLK		1037#define MADERA_FLL_SRC_AIF4BCLK		1138#define MADERA_FLL_SRC_AIF1LRCLK	1239#define MADERA_FLL_SRC_AIF2LRCLK	1340#define MADERA_FLL_SRC_AIF3LRCLK	1441#define MADERA_FLL_SRC_AIF4LRCLK	1542 43#define MADERA_CLK_SYSCLK_1		144#define MADERA_CLK_ASYNCCLK_1		245#define MADERA_CLK_OPCLK		346#define MADERA_CLK_ASYNC_OPCLK		447#define MADERA_CLK_SYSCLK_2		548#define MADERA_CLK_SYSCLK_3		649#define MADERA_CLK_ASYNCCLK_2		750#define MADERA_CLK_DSPCLK		851#define MADERA_CLK_OUTCLK		952 53#define MADERA_CLK_SRC_MCLK1		0x054#define MADERA_CLK_SRC_MCLK2		0x155#define MADERA_CLK_SRC_MCLK3		0x256#define MADERA_CLK_SRC_FLL1		0x457#define MADERA_CLK_SRC_FLL2		0x558#define MADERA_CLK_SRC_FLL3		0x659#define MADERA_CLK_SRC_FLLAO_HI		0x760#define MADERA_CLK_SRC_FLL1_DIV6	0x761#define MADERA_CLK_SRC_AIF1BCLK		0x862#define MADERA_CLK_SRC_AIF2BCLK		0x963#define MADERA_CLK_SRC_AIF3BCLK		0xA64#define MADERA_CLK_SRC_AIF4BCLK		0xB65#define MADERA_CLK_SRC_FLLAO		0xF66 67#define MADERA_OUTCLK_SYSCLK		068#define MADERA_OUTCLK_ASYNCCLK		169#define MADERA_OUTCLK_MCLK1		470#define MADERA_OUTCLK_MCLK2		571#define MADERA_OUTCLK_MCLK3		672 73#define MADERA_MIXER_VOL_MASK		0x00FE74#define MADERA_MIXER_VOL_SHIFT		175#define MADERA_MIXER_VOL_WIDTH		776 77#define MADERA_DOM_GRP_FX		078#define MADERA_DOM_GRP_ASRC1		179#define MADERA_DOM_GRP_ASRC2		280#define MADERA_DOM_GRP_ISRC1		381#define MADERA_DOM_GRP_ISRC2		482#define MADERA_DOM_GRP_ISRC3		583#define MADERA_DOM_GRP_ISRC4		684#define MADERA_DOM_GRP_OUT		785#define MADERA_DOM_GRP_SPD		886#define MADERA_DOM_GRP_DSP1		987#define MADERA_DOM_GRP_DSP2		1088#define MADERA_DOM_GRP_DSP3		1189#define MADERA_DOM_GRP_DSP4		1290#define MADERA_DOM_GRP_DSP5		1391#define MADERA_DOM_GRP_DSP6		1492#define MADERA_DOM_GRP_DSP7		1593#define MADERA_DOM_GRP_AIF1		1694#define MADERA_DOM_GRP_AIF2		1795#define MADERA_DOM_GRP_AIF3		1896#define MADERA_DOM_GRP_AIF4		1997#define MADERA_DOM_GRP_SLIMBUS		2098#define MADERA_DOM_GRP_PWM		2199#define MADERA_DOM_GRP_DFC		22100#define MADERA_N_DOM_GRPS		23101 102#define MADERA_MAX_DAI			11103#define MADERA_MAX_ADSP			7104 105#define MADERA_NUM_MIXER_INPUTS		148106 107struct madera;108struct wm_adsp;109 110struct madera_voice_trigger_info {111	/** Which core triggered, 1-based (1 = DSP1, ...) */112	int core_num;113};114 115struct madera_dai_priv {116	int clk;117	struct snd_pcm_hw_constraint_list constraint;118};119 120struct madera_priv {121	struct wm_adsp adsp[MADERA_MAX_ADSP];122	struct madera *madera;123	struct device *dev;124	int sysclk;125	int asyncclk;126	int dspclk;127	struct madera_dai_priv dai[MADERA_MAX_DAI];128 129	int num_inputs;130 131	unsigned int in_pending;132 133	unsigned int out_up_pending;134	unsigned int out_up_delay;135	unsigned int out_down_pending;136	unsigned int out_down_delay;137 138	unsigned int adsp_rate_cache[MADERA_MAX_ADSP];139 140	struct mutex rate_lock;141 142	int tdm_width[MADERA_MAX_AIF];143	int tdm_slots[MADERA_MAX_AIF];144 145	int domain_group_ref[MADERA_N_DOM_GRPS];146};147 148struct madera_fll_cfg {149	int n;150	unsigned int theta;151	unsigned int lambda;152	int refdiv;153	int fratio;154	int gain;155	int alt_gain;156};157 158struct madera_fll {159	struct madera *madera;160	int id;161	unsigned int base;162 163	unsigned int fout;164 165	int sync_src;166	unsigned int sync_freq;167 168	int ref_src;169	unsigned int ref_freq;170	struct madera_fll_cfg ref_cfg;171};172 173struct madera_enum {174	struct soc_enum mixer_enum;175	int val;176};177 178extern const unsigned int madera_ana_tlv[];179extern const unsigned int madera_eq_tlv[];180extern const unsigned int madera_digital_tlv[];181extern const unsigned int madera_noise_tlv[];182extern const unsigned int madera_ng_tlv[];183 184extern const unsigned int madera_mixer_tlv[];185extern const char * const madera_mixer_texts[MADERA_NUM_MIXER_INPUTS];186extern const unsigned int madera_mixer_values[MADERA_NUM_MIXER_INPUTS];187 188#define MADERA_GAINMUX_CONTROLS(name, base) \189	SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1,		\190			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\191			     madera_mixer_tlv)192 193#define MADERA_MIXER_CONTROLS(name, base) \194	SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1,		\195			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\196			     madera_mixer_tlv),			\197	SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3,		\198			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\199			     madera_mixer_tlv),			\200	SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5,		\201			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\202			     madera_mixer_tlv),			\203	SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7,		\204			     MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0,	\205			     madera_mixer_tlv)206 207#define MADERA_MUX_ENUM_DECL(name, reg) \208	SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \209		name, reg, 0, 0xff, madera_mixer_texts, madera_mixer_values)210 211#define MADERA_MUX_CTL_DECL(name) \212	const struct snd_kcontrol_new name##_mux =	\213		SOC_DAPM_ENUM("Route", name##_enum)214 215#define MADERA_MUX_ENUMS(name, base_reg) \216	static MADERA_MUX_ENUM_DECL(name##_enum, base_reg);	\217	static MADERA_MUX_CTL_DECL(name)218 219#define MADERA_MIXER_ENUMS(name, base_reg) \220	MADERA_MUX_ENUMS(name##_in1, base_reg);     \221	MADERA_MUX_ENUMS(name##_in2, base_reg + 2); \222	MADERA_MUX_ENUMS(name##_in3, base_reg + 4); \223	MADERA_MUX_ENUMS(name##_in4, base_reg + 6)224 225#define MADERA_DSP_AUX_ENUMS(name, base_reg) \226	MADERA_MUX_ENUMS(name##_aux1, base_reg);	\227	MADERA_MUX_ENUMS(name##_aux2, base_reg + 8);	\228	MADERA_MUX_ENUMS(name##_aux3, base_reg + 16);	\229	MADERA_MUX_ENUMS(name##_aux4, base_reg + 24);	\230	MADERA_MUX_ENUMS(name##_aux5, base_reg + 32);	\231	MADERA_MUX_ENUMS(name##_aux6, base_reg + 40)232 233#define MADERA_MUX(name, ctrl) \234	SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)235 236#define MADERA_MUX_WIDGETS(name, name_str) \237	MADERA_MUX(name_str " Input 1", &name##_mux)238 239#define MADERA_MIXER_WIDGETS(name, name_str)	\240	MADERA_MUX(name_str " Input 1", &name##_in1_mux), \241	MADERA_MUX(name_str " Input 2", &name##_in2_mux), \242	MADERA_MUX(name_str " Input 3", &name##_in3_mux), \243	MADERA_MUX(name_str " Input 4", &name##_in4_mux), \244	SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)245 246#define MADERA_DSP_WIDGETS(name, name_str)			\247	MADERA_MIXER_WIDGETS(name##L, name_str "L"),		\248	MADERA_MIXER_WIDGETS(name##R, name_str "R"),		\249	MADERA_MUX(name_str " Aux 1", &name##_aux1_mux),	\250	MADERA_MUX(name_str " Aux 2", &name##_aux2_mux),	\251	MADERA_MUX(name_str " Aux 3", &name##_aux3_mux),	\252	MADERA_MUX(name_str " Aux 4", &name##_aux4_mux),	\253	MADERA_MUX(name_str " Aux 5", &name##_aux5_mux),	\254	MADERA_MUX(name_str " Aux 6", &name##_aux6_mux)255 256#define MADERA_MUX_ROUTES(widget, name) \257	{ widget, NULL, name " Input 1" }, \258	MADERA_MIXER_INPUT_ROUTES(name " Input 1")259 260#define MADERA_MIXER_ROUTES(widget, name)		\261	{ widget, NULL, name " Mixer" },		\262	{ name " Mixer", NULL, name " Input 1" },	\263	{ name " Mixer", NULL, name " Input 2" },	\264	{ name " Mixer", NULL, name " Input 3" },	\265	{ name " Mixer", NULL, name " Input 4" },	\266	MADERA_MIXER_INPUT_ROUTES(name " Input 1"),	\267	MADERA_MIXER_INPUT_ROUTES(name " Input 2"),	\268	MADERA_MIXER_INPUT_ROUTES(name " Input 3"),	\269	MADERA_MIXER_INPUT_ROUTES(name " Input 4")270 271#define MADERA_DSP_ROUTES(name)				\272	{ name, NULL, name " Preloader"},		\273	{ name " Preload", NULL, name " Preloader"},	\274	{ name, NULL, "SYSCLK"},			\275	{ name, NULL, "DSPCLK"},			\276	{ name, NULL, name " Aux 1" },			\277	{ name, NULL, name " Aux 2" },			\278	{ name, NULL, name " Aux 3" },			\279	{ name, NULL, name " Aux 4" },			\280	{ name, NULL, name " Aux 5" },			\281	{ name, NULL, name " Aux 6" },			\282	MADERA_MIXER_INPUT_ROUTES(name " Aux 1"),	\283	MADERA_MIXER_INPUT_ROUTES(name " Aux 2"),	\284	MADERA_MIXER_INPUT_ROUTES(name " Aux 3"),	\285	MADERA_MIXER_INPUT_ROUTES(name " Aux 4"),	\286	MADERA_MIXER_INPUT_ROUTES(name " Aux 5"),	\287	MADERA_MIXER_INPUT_ROUTES(name " Aux 6"),	\288	MADERA_MIXER_ROUTES(name, name "L"),		\289	MADERA_MIXER_ROUTES(name, name "R")290 291#define MADERA_RATE_ENUM(xname, xenum) \292{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\293	.info = snd_soc_info_enum_double, \294	.get = snd_soc_get_enum_double, .put = madera_rate_put, \295	.private_value = (unsigned long)&xenum }296 297#define MADERA_EQ_CONTROL(xname, xbase)				\298{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\299	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get,	\300	.put = madera_eq_coeff_put, .private_value =		\301	((unsigned long)&(struct soc_bytes) { .base = xbase,	\302	 .num_regs = 20, .mask = ~MADERA_EQ1_B1_MODE }) }303 304#define MADERA_LHPF_CONTROL(xname, xbase)			\305{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\306	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get,	\307	.put = madera_lhpf_coeff_put, .private_value =		\308	((unsigned long)&(struct soc_bytes) { .base = xbase,	\309	 .num_regs = 1 }) }310 311#define MADERA_RATES SNDRV_PCM_RATE_KNOT312 313#define MADERA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \314			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)315 316#define MADERA_OSR_ENUM_SIZE		5317#define MADERA_SYNC_RATE_ENUM_SIZE	3318#define MADERA_ASYNC_RATE_ENUM_SIZE	2319#define MADERA_RATE_ENUM_SIZE \320		(MADERA_SYNC_RATE_ENUM_SIZE + MADERA_ASYNC_RATE_ENUM_SIZE)321#define MADERA_SAMPLE_RATE_ENUM_SIZE	16322#define MADERA_DFC_TYPE_ENUM_SIZE	5323#define MADERA_DFC_WIDTH_ENUM_SIZE	5324 325extern const struct snd_soc_dai_ops madera_dai_ops;326extern const struct snd_soc_dai_ops madera_simple_dai_ops;327 328extern const struct snd_kcontrol_new madera_inmux[];329extern const struct snd_kcontrol_new madera_inmode[];330 331extern const char * const madera_rate_text[MADERA_RATE_ENUM_SIZE];332extern const unsigned int madera_rate_val[MADERA_RATE_ENUM_SIZE];333 334extern const struct soc_enum madera_sample_rate[];335extern const struct soc_enum madera_isrc_fsl[];336extern const struct soc_enum madera_isrc_fsh[];337extern const struct soc_enum madera_asrc1_rate[];338extern const struct soc_enum madera_asrc1_bidir_rate[];339extern const struct soc_enum madera_asrc2_rate[];340extern const struct soc_enum madera_dfc_width[];341extern const struct soc_enum madera_dfc_type[];342 343extern const struct soc_enum madera_in_vi_ramp;344extern const struct soc_enum madera_in_vd_ramp;345 346extern const struct soc_enum madera_out_vi_ramp;347extern const struct soc_enum madera_out_vd_ramp;348 349extern const struct soc_enum madera_lhpf1_mode;350extern const struct soc_enum madera_lhpf2_mode;351extern const struct soc_enum madera_lhpf3_mode;352extern const struct soc_enum madera_lhpf4_mode;353 354extern const struct soc_enum madera_ng_hold;355extern const struct soc_enum madera_in_hpf_cut_enum;356extern const struct soc_enum madera_in_dmic_osr[];357 358extern const struct soc_enum madera_output_anc_src[];359extern const struct soc_enum madera_anc_input_src[];360extern const struct soc_enum madera_anc_ng_enum;361 362extern const struct snd_kcontrol_new madera_dsp_trigger_output_mux[];363extern const struct snd_kcontrol_new madera_drc_activity_output_mux[];364 365extern const struct snd_kcontrol_new madera_adsp_rate_controls[];366 367int madera_dfc_put(struct snd_kcontrol *kcontrol,368		   struct snd_ctl_elem_value *ucontrol);369 370int madera_lp_mode_put(struct snd_kcontrol *kcontrol,371		       struct snd_ctl_elem_value *ucontrol);372 373int madera_out1_demux_put(struct snd_kcontrol *kcontrol,374			  struct snd_ctl_elem_value *ucontrol);375int madera_out1_demux_get(struct snd_kcontrol *kcontrol,376			  struct snd_ctl_elem_value *ucontrol);377 378int madera_rate_put(struct snd_kcontrol *kcontrol,379		    struct snd_ctl_elem_value *ucontrol);380 381int madera_eq_coeff_put(struct snd_kcontrol *kcontrol,382			struct snd_ctl_elem_value *ucontrol);383int madera_lhpf_coeff_put(struct snd_kcontrol *kcontrol,384			  struct snd_ctl_elem_value *ucontrol);385 386int madera_clk_ev(struct snd_soc_dapm_widget *w,387		  struct snd_kcontrol *kcontrol, int event);388int madera_sysclk_ev(struct snd_soc_dapm_widget *w,389		     struct snd_kcontrol *kcontrol, int event);390int madera_spk_ev(struct snd_soc_dapm_widget *w,391		  struct snd_kcontrol *kcontrol, int event);392int madera_in_ev(struct snd_soc_dapm_widget *w,393		 struct snd_kcontrol *kcontrol, int event);394int madera_out_ev(struct snd_soc_dapm_widget *w,395		  struct snd_kcontrol *kcontrol, int event);396int madera_hp_ev(struct snd_soc_dapm_widget *w,397		 struct snd_kcontrol *kcontrol, int event);398int madera_anc_ev(struct snd_soc_dapm_widget *w,399		  struct snd_kcontrol *kcontrol, int event);400int madera_domain_clk_ev(struct snd_soc_dapm_widget *w,401			 struct snd_kcontrol *kcontrol,402			 int event);403 404int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num,405			unsigned int freq);406 407int madera_set_sysclk(struct snd_soc_component *component, int clk_id,408		      int source, unsigned int freq, int dir);409 410int madera_init_fll(struct madera *madera, int id, int base,411		    struct madera_fll *fll);412int madera_set_fll_refclk(struct madera_fll *fll, int source,413			  unsigned int fref, unsigned int fout);414int madera_set_fll_syncclk(struct madera_fll *fll, int source,415			   unsigned int fref, unsigned int fout);416int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,417			     unsigned int fin, unsigned int fout);418int madera_fllhj_set_refclk(struct madera_fll *fll, int source,419			    unsigned int fin, unsigned int fout);420 421int madera_core_init(struct madera_priv *priv);422int madera_core_free(struct madera_priv *priv);423int madera_init_overheat(struct madera_priv *priv);424int madera_free_overheat(struct madera_priv *priv);425int madera_init_inputs(struct snd_soc_component *component);426int madera_init_outputs(struct snd_soc_component *component,427			const struct snd_soc_dapm_route *routes,428			int n_mono_routes, int n_real);429int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,430			      irq_handler_t handler);431void madera_free_bus_error_irq(struct madera_priv *priv, int dsp_num);432 433int madera_init_dai(struct madera_priv *priv, int id);434 435int madera_set_output_mode(struct snd_soc_component *component, int output,436			   bool differential);437 438/* Following functions are for use by machine drivers */439static inline int madera_register_notifier(struct snd_soc_component *component,440					   struct notifier_block *nb)441{442	struct madera_priv *priv = snd_soc_component_get_drvdata(component);443	struct madera *madera = priv->madera;444 445	return blocking_notifier_chain_register(&madera->notifier, nb);446}447 448static inline int449madera_unregister_notifier(struct snd_soc_component *component,450			   struct notifier_block *nb)451{452	struct madera_priv *priv = snd_soc_component_get_drvdata(component);453	struct madera *madera = priv->madera;454 455	return blocking_notifier_chain_unregister(&madera->notifier, nb);456}457 458#endif459