0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef ASOC_MADERA_H
0010 #define ASOC_MADERA_H
0011
0012 #include <linux/completion.h>
0013 #include <sound/soc.h>
0014 #include <sound/madera-pdata.h>
0015
0016 #include "wm_adsp.h"
0017
0018 #define MADERA_FLL1_REFCLK 1
0019 #define MADERA_FLL2_REFCLK 2
0020 #define MADERA_FLL3_REFCLK 3
0021 #define MADERA_FLLAO_REFCLK 4
0022 #define MADERA_FLL1_SYNCCLK 5
0023 #define MADERA_FLL2_SYNCCLK 6
0024 #define MADERA_FLL3_SYNCCLK 7
0025 #define MADERA_FLLAO_SYNCCLK 8
0026
0027 #define MADERA_FLL_SRC_NONE -1
0028 #define MADERA_FLL_SRC_MCLK1 0
0029 #define MADERA_FLL_SRC_MCLK2 1
0030 #define MADERA_FLL_SRC_MCLK3 2
0031 #define MADERA_FLL_SRC_SLIMCLK 3
0032 #define MADERA_FLL_SRC_FLL1 4
0033 #define MADERA_FLL_SRC_FLL2 5
0034 #define MADERA_FLL_SRC_AIF1BCLK 8
0035 #define MADERA_FLL_SRC_AIF2BCLK 9
0036 #define MADERA_FLL_SRC_AIF3BCLK 10
0037 #define MADERA_FLL_SRC_AIF4BCLK 11
0038 #define MADERA_FLL_SRC_AIF1LRCLK 12
0039 #define MADERA_FLL_SRC_AIF2LRCLK 13
0040 #define MADERA_FLL_SRC_AIF3LRCLK 14
0041 #define MADERA_FLL_SRC_AIF4LRCLK 15
0042
0043 #define MADERA_CLK_SYSCLK_1 1
0044 #define MADERA_CLK_ASYNCCLK_1 2
0045 #define MADERA_CLK_OPCLK 3
0046 #define MADERA_CLK_ASYNC_OPCLK 4
0047 #define MADERA_CLK_SYSCLK_2 5
0048 #define MADERA_CLK_SYSCLK_3 6
0049 #define MADERA_CLK_ASYNCCLK_2 7
0050 #define MADERA_CLK_DSPCLK 8
0051 #define MADERA_CLK_OUTCLK 9
0052
0053 #define MADERA_CLK_SRC_MCLK1 0x0
0054 #define MADERA_CLK_SRC_MCLK2 0x1
0055 #define MADERA_CLK_SRC_MCLK3 0x2
0056 #define MADERA_CLK_SRC_FLL1 0x4
0057 #define MADERA_CLK_SRC_FLL2 0x5
0058 #define MADERA_CLK_SRC_FLL3 0x6
0059 #define MADERA_CLK_SRC_FLLAO_HI 0x7
0060 #define MADERA_CLK_SRC_FLL1_DIV6 0x7
0061 #define MADERA_CLK_SRC_AIF1BCLK 0x8
0062 #define MADERA_CLK_SRC_AIF2BCLK 0x9
0063 #define MADERA_CLK_SRC_AIF3BCLK 0xA
0064 #define MADERA_CLK_SRC_AIF4BCLK 0xB
0065 #define MADERA_CLK_SRC_FLLAO 0xF
0066
0067 #define MADERA_OUTCLK_SYSCLK 0
0068 #define MADERA_OUTCLK_ASYNCCLK 1
0069 #define MADERA_OUTCLK_MCLK1 4
0070 #define MADERA_OUTCLK_MCLK2 5
0071 #define MADERA_OUTCLK_MCLK3 6
0072
0073 #define MADERA_MIXER_VOL_MASK 0x00FE
0074 #define MADERA_MIXER_VOL_SHIFT 1
0075 #define MADERA_MIXER_VOL_WIDTH 7
0076
0077 #define MADERA_DOM_GRP_FX 0
0078 #define MADERA_DOM_GRP_ASRC1 1
0079 #define MADERA_DOM_GRP_ASRC2 2
0080 #define MADERA_DOM_GRP_ISRC1 3
0081 #define MADERA_DOM_GRP_ISRC2 4
0082 #define MADERA_DOM_GRP_ISRC3 5
0083 #define MADERA_DOM_GRP_ISRC4 6
0084 #define MADERA_DOM_GRP_OUT 7
0085 #define MADERA_DOM_GRP_SPD 8
0086 #define MADERA_DOM_GRP_DSP1 9
0087 #define MADERA_DOM_GRP_DSP2 10
0088 #define MADERA_DOM_GRP_DSP3 11
0089 #define MADERA_DOM_GRP_DSP4 12
0090 #define MADERA_DOM_GRP_DSP5 13
0091 #define MADERA_DOM_GRP_DSP6 14
0092 #define MADERA_DOM_GRP_DSP7 15
0093 #define MADERA_DOM_GRP_AIF1 16
0094 #define MADERA_DOM_GRP_AIF2 17
0095 #define MADERA_DOM_GRP_AIF3 18
0096 #define MADERA_DOM_GRP_AIF4 19
0097 #define MADERA_DOM_GRP_SLIMBUS 20
0098 #define MADERA_DOM_GRP_PWM 21
0099 #define MADERA_DOM_GRP_DFC 22
0100 #define MADERA_N_DOM_GRPS 23
0101
0102 #define MADERA_MAX_DAI 11
0103 #define MADERA_MAX_ADSP 7
0104
0105 #define MADERA_NUM_MIXER_INPUTS 148
0106
0107 struct madera;
0108 struct wm_adsp;
0109
0110 struct madera_voice_trigger_info {
0111
0112 int core_num;
0113 };
0114
0115 struct madera_dai_priv {
0116 int clk;
0117 struct snd_pcm_hw_constraint_list constraint;
0118 };
0119
0120 struct madera_priv {
0121 struct wm_adsp adsp[MADERA_MAX_ADSP];
0122 struct madera *madera;
0123 struct device *dev;
0124 int sysclk;
0125 int asyncclk;
0126 int dspclk;
0127 struct madera_dai_priv dai[MADERA_MAX_DAI];
0128
0129 int num_inputs;
0130
0131 unsigned int in_pending;
0132
0133 unsigned int out_up_pending;
0134 unsigned int out_up_delay;
0135 unsigned int out_down_pending;
0136 unsigned int out_down_delay;
0137
0138 unsigned int adsp_rate_cache[MADERA_MAX_ADSP];
0139
0140 struct mutex rate_lock;
0141
0142 int tdm_width[MADERA_MAX_AIF];
0143 int tdm_slots[MADERA_MAX_AIF];
0144
0145 int domain_group_ref[MADERA_N_DOM_GRPS];
0146 };
0147
0148 struct madera_fll_cfg {
0149 int n;
0150 unsigned int theta;
0151 unsigned int lambda;
0152 int refdiv;
0153 int fratio;
0154 int gain;
0155 int alt_gain;
0156 };
0157
0158 struct madera_fll {
0159 struct madera *madera;
0160 int id;
0161 unsigned int base;
0162
0163 unsigned int fout;
0164
0165 int sync_src;
0166 unsigned int sync_freq;
0167
0168 int ref_src;
0169 unsigned int ref_freq;
0170 struct madera_fll_cfg ref_cfg;
0171 };
0172
0173 struct madera_enum {
0174 struct soc_enum mixer_enum;
0175 int val;
0176 };
0177
0178 extern const unsigned int madera_ana_tlv[];
0179 extern const unsigned int madera_eq_tlv[];
0180 extern const unsigned int madera_digital_tlv[];
0181 extern const unsigned int madera_noise_tlv[];
0182 extern const unsigned int madera_ng_tlv[];
0183
0184 extern const unsigned int madera_mixer_tlv[];
0185 extern const char * const madera_mixer_texts[MADERA_NUM_MIXER_INPUTS];
0186 extern const unsigned int madera_mixer_values[MADERA_NUM_MIXER_INPUTS];
0187
0188 #define MADERA_GAINMUX_CONTROLS(name, base) \
0189 SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \
0190 MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0191 madera_mixer_tlv)
0192
0193 #define MADERA_MIXER_CONTROLS(name, base) \
0194 SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \
0195 MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0196 madera_mixer_tlv), \
0197 SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3, \
0198 MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0199 madera_mixer_tlv), \
0200 SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5, \
0201 MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0202 madera_mixer_tlv), \
0203 SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7, \
0204 MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0205 madera_mixer_tlv)
0206
0207 #define MADERA_MUX_ENUM_DECL(name, reg) \
0208 SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \
0209 name, reg, 0, 0xff, madera_mixer_texts, madera_mixer_values)
0210
0211 #define MADERA_MUX_CTL_DECL(name) \
0212 const struct snd_kcontrol_new name##_mux = \
0213 SOC_DAPM_ENUM("Route", name##_enum)
0214
0215 #define MADERA_MUX_ENUMS(name, base_reg) \
0216 static MADERA_MUX_ENUM_DECL(name##_enum, base_reg); \
0217 static MADERA_MUX_CTL_DECL(name)
0218
0219 #define MADERA_MIXER_ENUMS(name, base_reg) \
0220 MADERA_MUX_ENUMS(name##_in1, base_reg); \
0221 MADERA_MUX_ENUMS(name##_in2, base_reg + 2); \
0222 MADERA_MUX_ENUMS(name##_in3, base_reg + 4); \
0223 MADERA_MUX_ENUMS(name##_in4, base_reg + 6)
0224
0225 #define MADERA_DSP_AUX_ENUMS(name, base_reg) \
0226 MADERA_MUX_ENUMS(name##_aux1, base_reg); \
0227 MADERA_MUX_ENUMS(name##_aux2, base_reg + 8); \
0228 MADERA_MUX_ENUMS(name##_aux3, base_reg + 16); \
0229 MADERA_MUX_ENUMS(name##_aux4, base_reg + 24); \
0230 MADERA_MUX_ENUMS(name##_aux5, base_reg + 32); \
0231 MADERA_MUX_ENUMS(name##_aux6, base_reg + 40)
0232
0233 #define MADERA_MUX(name, ctrl) \
0234 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
0235
0236 #define MADERA_MUX_WIDGETS(name, name_str) \
0237 MADERA_MUX(name_str " Input 1", &name##_mux)
0238
0239 #define MADERA_MIXER_WIDGETS(name, name_str) \
0240 MADERA_MUX(name_str " Input 1", &name##_in1_mux), \
0241 MADERA_MUX(name_str " Input 2", &name##_in2_mux), \
0242 MADERA_MUX(name_str " Input 3", &name##_in3_mux), \
0243 MADERA_MUX(name_str " Input 4", &name##_in4_mux), \
0244 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
0245
0246 #define MADERA_DSP_WIDGETS(name, name_str) \
0247 MADERA_MIXER_WIDGETS(name##L, name_str "L"), \
0248 MADERA_MIXER_WIDGETS(name##R, name_str "R"), \
0249 MADERA_MUX(name_str " Aux 1", &name##_aux1_mux), \
0250 MADERA_MUX(name_str " Aux 2", &name##_aux2_mux), \
0251 MADERA_MUX(name_str " Aux 3", &name##_aux3_mux), \
0252 MADERA_MUX(name_str " Aux 4", &name##_aux4_mux), \
0253 MADERA_MUX(name_str " Aux 5", &name##_aux5_mux), \
0254 MADERA_MUX(name_str " Aux 6", &name##_aux6_mux)
0255
0256 #define MADERA_MUX_ROUTES(widget, name) \
0257 { widget, NULL, name " Input 1" }, \
0258 MADERA_MIXER_INPUT_ROUTES(name " Input 1")
0259
0260 #define MADERA_MIXER_ROUTES(widget, name) \
0261 { widget, NULL, name " Mixer" }, \
0262 { name " Mixer", NULL, name " Input 1" }, \
0263 { name " Mixer", NULL, name " Input 2" }, \
0264 { name " Mixer", NULL, name " Input 3" }, \
0265 { name " Mixer", NULL, name " Input 4" }, \
0266 MADERA_MIXER_INPUT_ROUTES(name " Input 1"), \
0267 MADERA_MIXER_INPUT_ROUTES(name " Input 2"), \
0268 MADERA_MIXER_INPUT_ROUTES(name " Input 3"), \
0269 MADERA_MIXER_INPUT_ROUTES(name " Input 4")
0270
0271 #define MADERA_DSP_ROUTES(name) \
0272 { name, NULL, name " Preloader"}, \
0273 { name " Preload", NULL, name " Preloader"}, \
0274 { name, NULL, "SYSCLK"}, \
0275 { name, NULL, "DSPCLK"}, \
0276 { name, NULL, name " Aux 1" }, \
0277 { name, NULL, name " Aux 2" }, \
0278 { name, NULL, name " Aux 3" }, \
0279 { name, NULL, name " Aux 4" }, \
0280 { name, NULL, name " Aux 5" }, \
0281 { name, NULL, name " Aux 6" }, \
0282 MADERA_MIXER_INPUT_ROUTES(name " Aux 1"), \
0283 MADERA_MIXER_INPUT_ROUTES(name " Aux 2"), \
0284 MADERA_MIXER_INPUT_ROUTES(name " Aux 3"), \
0285 MADERA_MIXER_INPUT_ROUTES(name " Aux 4"), \
0286 MADERA_MIXER_INPUT_ROUTES(name " Aux 5"), \
0287 MADERA_MIXER_INPUT_ROUTES(name " Aux 6"), \
0288 MADERA_MIXER_ROUTES(name, name "L"), \
0289 MADERA_MIXER_ROUTES(name, name "R")
0290
0291 #define MADERA_RATE_ENUM(xname, xenum) \
0292 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
0293 .info = snd_soc_info_enum_double, \
0294 .get = snd_soc_get_enum_double, .put = madera_rate_put, \
0295 .private_value = (unsigned long)&xenum }
0296
0297 #define MADERA_EQ_CONTROL(xname, xbase) \
0298 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
0299 .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
0300 .put = madera_eq_coeff_put, .private_value = \
0301 ((unsigned long)&(struct soc_bytes) { .base = xbase, \
0302 .num_regs = 20, .mask = ~MADERA_EQ1_B1_MODE }) }
0303
0304 #define MADERA_LHPF_CONTROL(xname, xbase) \
0305 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
0306 .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
0307 .put = madera_lhpf_coeff_put, .private_value = \
0308 ((unsigned long)&(struct soc_bytes) { .base = xbase, \
0309 .num_regs = 1 }) }
0310
0311 #define MADERA_RATES SNDRV_PCM_RATE_KNOT
0312
0313 #define MADERA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
0314 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
0315
0316 #define MADERA_OSR_ENUM_SIZE 5
0317 #define MADERA_SYNC_RATE_ENUM_SIZE 3
0318 #define MADERA_ASYNC_RATE_ENUM_SIZE 2
0319 #define MADERA_RATE_ENUM_SIZE \
0320 (MADERA_SYNC_RATE_ENUM_SIZE + MADERA_ASYNC_RATE_ENUM_SIZE)
0321 #define MADERA_SAMPLE_RATE_ENUM_SIZE 16
0322 #define MADERA_DFC_TYPE_ENUM_SIZE 5
0323 #define MADERA_DFC_WIDTH_ENUM_SIZE 5
0324
0325 extern const struct snd_soc_dai_ops madera_dai_ops;
0326 extern const struct snd_soc_dai_ops madera_simple_dai_ops;
0327
0328 extern const struct snd_kcontrol_new madera_inmux[];
0329 extern const struct snd_kcontrol_new madera_inmode[];
0330
0331 extern const char * const madera_rate_text[MADERA_RATE_ENUM_SIZE];
0332 extern const unsigned int madera_rate_val[MADERA_RATE_ENUM_SIZE];
0333
0334 extern const struct soc_enum madera_sample_rate[];
0335 extern const struct soc_enum madera_isrc_fsl[];
0336 extern const struct soc_enum madera_isrc_fsh[];
0337 extern const struct soc_enum madera_asrc1_rate[];
0338 extern const struct soc_enum madera_asrc1_bidir_rate[];
0339 extern const struct soc_enum madera_asrc2_rate[];
0340 extern const struct soc_enum madera_dfc_width[];
0341 extern const struct soc_enum madera_dfc_type[];
0342
0343 extern const struct soc_enum madera_in_vi_ramp;
0344 extern const struct soc_enum madera_in_vd_ramp;
0345
0346 extern const struct soc_enum madera_out_vi_ramp;
0347 extern const struct soc_enum madera_out_vd_ramp;
0348
0349 extern const struct soc_enum madera_lhpf1_mode;
0350 extern const struct soc_enum madera_lhpf2_mode;
0351 extern const struct soc_enum madera_lhpf3_mode;
0352 extern const struct soc_enum madera_lhpf4_mode;
0353
0354 extern const struct soc_enum madera_ng_hold;
0355 extern const struct soc_enum madera_in_hpf_cut_enum;
0356 extern const struct soc_enum madera_in_dmic_osr[];
0357
0358 extern const struct soc_enum madera_output_anc_src[];
0359 extern const struct soc_enum madera_anc_input_src[];
0360 extern const struct soc_enum madera_anc_ng_enum;
0361
0362 extern const struct snd_kcontrol_new madera_dsp_trigger_output_mux[];
0363 extern const struct snd_kcontrol_new madera_drc_activity_output_mux[];
0364
0365 extern const struct snd_kcontrol_new madera_adsp_rate_controls[];
0366
0367 int madera_dfc_put(struct snd_kcontrol *kcontrol,
0368 struct snd_ctl_elem_value *ucontrol);
0369
0370 int madera_lp_mode_put(struct snd_kcontrol *kcontrol,
0371 struct snd_ctl_elem_value *ucontrol);
0372
0373 int madera_out1_demux_put(struct snd_kcontrol *kcontrol,
0374 struct snd_ctl_elem_value *ucontrol);
0375 int madera_out1_demux_get(struct snd_kcontrol *kcontrol,
0376 struct snd_ctl_elem_value *ucontrol);
0377
0378 int madera_rate_put(struct snd_kcontrol *kcontrol,
0379 struct snd_ctl_elem_value *ucontrol);
0380
0381 int madera_eq_coeff_put(struct snd_kcontrol *kcontrol,
0382 struct snd_ctl_elem_value *ucontrol);
0383 int madera_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
0384 struct snd_ctl_elem_value *ucontrol);
0385
0386 int madera_clk_ev(struct snd_soc_dapm_widget *w,
0387 struct snd_kcontrol *kcontrol, int event);
0388 int madera_sysclk_ev(struct snd_soc_dapm_widget *w,
0389 struct snd_kcontrol *kcontrol, int event);
0390 int madera_spk_ev(struct snd_soc_dapm_widget *w,
0391 struct snd_kcontrol *kcontrol, int event);
0392 int madera_in_ev(struct snd_soc_dapm_widget *w,
0393 struct snd_kcontrol *kcontrol, int event);
0394 int madera_out_ev(struct snd_soc_dapm_widget *w,
0395 struct snd_kcontrol *kcontrol, int event);
0396 int madera_hp_ev(struct snd_soc_dapm_widget *w,
0397 struct snd_kcontrol *kcontrol, int event);
0398 int madera_anc_ev(struct snd_soc_dapm_widget *w,
0399 struct snd_kcontrol *kcontrol, int event);
0400 int madera_domain_clk_ev(struct snd_soc_dapm_widget *w,
0401 struct snd_kcontrol *kcontrol,
0402 int event);
0403
0404 int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num,
0405 unsigned int freq);
0406
0407 int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
0408 int source, unsigned int freq, int dir);
0409
0410 int madera_init_fll(struct madera *madera, int id, int base,
0411 struct madera_fll *fll);
0412 int madera_set_fll_refclk(struct madera_fll *fll, int source,
0413 unsigned int fref, unsigned int fout);
0414 int madera_set_fll_syncclk(struct madera_fll *fll, int source,
0415 unsigned int fref, unsigned int fout);
0416 int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
0417 unsigned int fin, unsigned int fout);
0418 int madera_fllhj_set_refclk(struct madera_fll *fll, int source,
0419 unsigned int fin, unsigned int fout);
0420
0421 int madera_core_init(struct madera_priv *priv);
0422 int madera_core_free(struct madera_priv *priv);
0423 int madera_init_overheat(struct madera_priv *priv);
0424 int madera_free_overheat(struct madera_priv *priv);
0425 int madera_init_inputs(struct snd_soc_component *component);
0426 int madera_init_outputs(struct snd_soc_component *component,
0427 const struct snd_soc_dapm_route *routes,
0428 int n_mono_routes, int n_real);
0429 int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,
0430 irq_handler_t handler);
0431 void madera_free_bus_error_irq(struct madera_priv *priv, int dsp_num);
0432
0433 int madera_init_dai(struct madera_priv *priv, int id);
0434
0435 int madera_set_output_mode(struct snd_soc_component *component, int output,
0436 bool differential);
0437
0438
0439 static inline int madera_register_notifier(struct snd_soc_component *component,
0440 struct notifier_block *nb)
0441 {
0442 struct madera_priv *priv = snd_soc_component_get_drvdata(component);
0443 struct madera *madera = priv->madera;
0444
0445 return blocking_notifier_chain_register(&madera->notifier, nb);
0446 }
0447
0448 static inline int
0449 madera_unregister_notifier(struct snd_soc_component *component,
0450 struct notifier_block *nb)
0451 {
0452 struct madera_priv *priv = snd_soc_component_get_drvdata(component);
0453 struct madera *madera = priv->madera;
0454
0455 return blocking_notifier_chain_unregister(&madera->notifier, nb);
0456 }
0457
0458 #endif