399 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * arizona.h - Wolfson Arizona class device shared support4 *5 * Copyright 2012 Wolfson Microelectronics plc6 *7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>8 */9 10#ifndef _ASOC_ARIZONA_H11#define _ASOC_ARIZONA_H12 13#include <linux/completion.h>14#include <linux/notifier.h>15#include <linux/mfd/arizona/core.h>16 17#include <sound/soc.h>18 19#include "wm_adsp.h"20 21#define ARIZONA_CLK_SYSCLK 122#define ARIZONA_CLK_ASYNCCLK 223#define ARIZONA_CLK_OPCLK 324#define ARIZONA_CLK_ASYNC_OPCLK 425 26#define ARIZONA_CLK_SRC_MCLK1 0x027#define ARIZONA_CLK_SRC_MCLK2 0x128#define ARIZONA_CLK_SRC_FLL1 0x429#define ARIZONA_CLK_SRC_FLL2 0x530#define ARIZONA_CLK_SRC_AIF1BCLK 0x831#define ARIZONA_CLK_SRC_AIF2BCLK 0x932#define ARIZONA_CLK_SRC_AIF3BCLK 0xa33 34#define ARIZONA_FLL_SRC_NONE -135#define ARIZONA_FLL_SRC_MCLK1 036#define ARIZONA_FLL_SRC_MCLK2 137#define ARIZONA_FLL_SRC_SLIMCLK 338#define ARIZONA_FLL_SRC_FLL1 439#define ARIZONA_FLL_SRC_FLL2 540#define ARIZONA_FLL_SRC_AIF1BCLK 841#define ARIZONA_FLL_SRC_AIF2BCLK 942#define ARIZONA_FLL_SRC_AIF3BCLK 1043#define ARIZONA_FLL_SRC_AIF1LRCLK 1244#define ARIZONA_FLL_SRC_AIF2LRCLK 1345#define ARIZONA_FLL_SRC_AIF3LRCLK 1446 47#define ARIZONA_MIXER_VOL_MASK 0x00FE48#define ARIZONA_MIXER_VOL_SHIFT 149#define ARIZONA_MIXER_VOL_WIDTH 750 51#define ARIZONA_CLK_6MHZ 052#define ARIZONA_CLK_12MHZ 153#define ARIZONA_CLK_24MHZ 254#define ARIZONA_CLK_49MHZ 355#define ARIZONA_CLK_73MHZ 456#define ARIZONA_CLK_98MHZ 557#define ARIZONA_CLK_147MHZ 658 59#define ARIZONA_MAX_DAI 1060#define ARIZONA_MAX_ADSP 461 62#define ARIZONA_DVFS_SR1_RQ 0x00163#define ARIZONA_DVFS_ADSP1_RQ 0x10064 65/* Notifier events */66#define ARIZONA_NOTIFY_VOICE_TRIGGER 0x167 68struct wm_adsp;69 70struct arizona_dai_priv {71 int clk;72 73 struct snd_pcm_hw_constraint_list constraint;74};75 76struct arizona_priv {77 struct wm_adsp adsp[ARIZONA_MAX_ADSP];78 struct arizona *arizona;79 int sysclk;80 int asyncclk;81 struct arizona_dai_priv dai[ARIZONA_MAX_DAI];82 83 int num_inputs;84 unsigned int in_pending;85 86 unsigned int out_up_pending;87 unsigned int out_up_delay;88 unsigned int out_down_pending;89 unsigned int out_down_delay;90 91 unsigned int dvfs_reqs;92 struct mutex dvfs_lock;93 bool dvfs_cached;94 95 /* Variables used by arizona-jack.c code */96 struct mutex lock;97 struct delayed_work hpdet_work;98 struct delayed_work micd_detect_work;99 struct delayed_work micd_timeout_work;100 struct snd_soc_jack *jack;101 struct regulator *micvdd;102 struct gpio_desc *micd_pol_gpio;103 104 u16 last_jackdet;105 106 int micd_mode;107 const struct arizona_micd_config *micd_modes;108 int micd_num_modes;109 110 int micd_button_mask;111 const struct arizona_micd_range *micd_ranges;112 int num_micd_ranges;113 114 bool micd_reva;115 bool micd_clamp;116 117 bool hpdet_active;118 bool hpdet_done;119 bool hpdet_retried;120 121 bool mic;122 bool detecting;123 124 int num_hpdet_res;125 unsigned int hpdet_res[3];126 127 int jack_flips;128 int hpdet_ip_version;129};130 131struct arizona_voice_trigger_info {132 int core;133};134 135#define ARIZONA_NUM_MIXER_INPUTS 104136 137extern const unsigned int arizona_mixer_tlv[];138extern const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];139extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];140 141#define ARIZONA_GAINMUX_CONTROLS(name, base) \142 SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \143 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \144 arizona_mixer_tlv)145 146#define ARIZONA_MIXER_CONTROLS(name, base) \147 SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \148 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \149 arizona_mixer_tlv), \150 SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3, \151 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \152 arizona_mixer_tlv), \153 SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5, \154 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \155 arizona_mixer_tlv), \156 SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7, \157 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \158 arizona_mixer_tlv)159 160#define ARIZONA_MUX_ENUM_DECL(name, reg) \161 SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \162 name, reg, 0, 0xff, arizona_mixer_texts, arizona_mixer_values)163 164#define ARIZONA_MUX_CTL_DECL(name) \165 const struct snd_kcontrol_new name##_mux = \166 SOC_DAPM_ENUM("Route", name##_enum)167 168#define ARIZONA_MUX_ENUMS(name, base_reg) \169 static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \170 static ARIZONA_MUX_CTL_DECL(name)171 172#define ARIZONA_MIXER_ENUMS(name, base_reg) \173 ARIZONA_MUX_ENUMS(name##_in1, base_reg); \174 ARIZONA_MUX_ENUMS(name##_in2, base_reg + 2); \175 ARIZONA_MUX_ENUMS(name##_in3, base_reg + 4); \176 ARIZONA_MUX_ENUMS(name##_in4, base_reg + 6)177 178#define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \179 ARIZONA_MUX_ENUMS(name##_aux1, base_reg); \180 ARIZONA_MUX_ENUMS(name##_aux2, base_reg + 8); \181 ARIZONA_MUX_ENUMS(name##_aux3, base_reg + 16); \182 ARIZONA_MUX_ENUMS(name##_aux4, base_reg + 24); \183 ARIZONA_MUX_ENUMS(name##_aux5, base_reg + 32); \184 ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40)185 186#define ARIZONA_MUX(name, ctrl) \187 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)188 189#define ARIZONA_MUX_WIDGETS(name, name_str) \190 ARIZONA_MUX(name_str " Input", &name##_mux)191 192#define ARIZONA_MIXER_WIDGETS(name, name_str) \193 ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \194 ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \195 ARIZONA_MUX(name_str " Input 3", &name##_in3_mux), \196 ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \197 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)198 199#define ARIZONA_DSP_WIDGETS(name, name_str) \200 ARIZONA_MIXER_WIDGETS(name##L, name_str "L"), \201 ARIZONA_MIXER_WIDGETS(name##R, name_str "R"), \202 ARIZONA_MUX(name_str " Aux 1", &name##_aux1_mux), \203 ARIZONA_MUX(name_str " Aux 2", &name##_aux2_mux), \204 ARIZONA_MUX(name_str " Aux 3", &name##_aux3_mux), \205 ARIZONA_MUX(name_str " Aux 4", &name##_aux4_mux), \206 ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \207 ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux)208 209#define ARIZONA_MUX_ROUTES(widget, name) \210 { widget, NULL, name " Input" }, \211 ARIZONA_MIXER_INPUT_ROUTES(name " Input")212 213#define ARIZONA_MIXER_ROUTES(widget, name) \214 { widget, NULL, name " Mixer" }, \215 { name " Mixer", NULL, name " Input 1" }, \216 { name " Mixer", NULL, name " Input 2" }, \217 { name " Mixer", NULL, name " Input 3" }, \218 { name " Mixer", NULL, name " Input 4" }, \219 ARIZONA_MIXER_INPUT_ROUTES(name " Input 1"), \220 ARIZONA_MIXER_INPUT_ROUTES(name " Input 2"), \221 ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \222 ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")223 224#define ARIZONA_DSP_ROUTES(name) \225 { name, NULL, name " Preloader"}, \226 { name " Preloader", NULL, "SYSCLK" }, \227 { name " Preload", NULL, name " Preloader"}, \228 { name, NULL, name " Aux 1" }, \229 { name, NULL, name " Aux 2" }, \230 { name, NULL, name " Aux 3" }, \231 { name, NULL, name " Aux 4" }, \232 { name, NULL, name " Aux 5" }, \233 { name, NULL, name " Aux 6" }, \234 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \235 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \236 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \237 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \238 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \239 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \240 ARIZONA_MIXER_ROUTES(name, name "L"), \241 ARIZONA_MIXER_ROUTES(name, name "R")242 243#define ARIZONA_EQ_CONTROL(xname, xbase) \244{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \245 .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \246 .put = arizona_eq_coeff_put, .private_value = \247 ((unsigned long)&(struct soc_bytes) { .base = xbase, \248 .num_regs = 20, .mask = ~ARIZONA_EQ1_B1_MODE }) }249 250#define ARIZONA_LHPF_CONTROL(xname, xbase) \251{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \252 .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \253 .put = arizona_lhpf_coeff_put, .private_value = \254 ((unsigned long)&(struct soc_bytes) { .base = xbase, \255 .num_regs = 1 }) }256 257#define ARIZONA_RATE_ENUM_SIZE 4258#define ARIZONA_SAMPLE_RATE_ENUM_SIZE 14259 260/* SND_JACK_* mask for supported cable/switch types */261#define ARIZONA_JACK_MASK (SND_JACK_HEADSET | SND_JACK_LINEOUT | SND_JACK_MECHANICAL)262 263extern const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];264extern const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];265extern const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE];266extern const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE];267 268extern const struct soc_enum arizona_isrc_fsl[];269extern const struct soc_enum arizona_isrc_fsh[];270extern const struct soc_enum arizona_asrc_rate1;271 272extern const struct soc_enum arizona_in_vi_ramp;273extern const struct soc_enum arizona_in_vd_ramp;274 275extern const struct soc_enum arizona_out_vi_ramp;276extern const struct soc_enum arizona_out_vd_ramp;277 278extern const struct soc_enum arizona_lhpf1_mode;279extern const struct soc_enum arizona_lhpf2_mode;280extern const struct soc_enum arizona_lhpf3_mode;281extern const struct soc_enum arizona_lhpf4_mode;282 283extern const struct soc_enum arizona_ng_hold;284extern const struct soc_enum arizona_in_hpf_cut_enum;285extern const struct soc_enum arizona_in_dmic_osr[];286 287extern const struct snd_kcontrol_new arizona_adsp2_rate_controls[];288 289extern const struct soc_enum arizona_anc_input_src[];290extern const struct soc_enum arizona_anc_ng_enum;291extern const struct soc_enum arizona_output_anc_src[];292 293extern const struct snd_kcontrol_new arizona_voice_trigger_switch[];294 295int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,296 int event);297int arizona_out_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,298 int event);299int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,300 int event);301int arizona_anc_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,302 int event);303 304int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,305 struct snd_ctl_elem_value *ucontrol);306int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,307 struct snd_ctl_elem_value *ucontrol);308 309int arizona_clk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,310 int event);311int arizona_set_sysclk(struct snd_soc_component *component, int clk_id, int source,312 unsigned int freq, int dir);313 314extern const struct snd_soc_dai_ops arizona_dai_ops;315extern const struct snd_soc_dai_ops arizona_simple_dai_ops;316 317#define ARIZONA_FLL_NAME_LEN 20318 319struct arizona_fll {320 struct arizona *arizona;321 int id;322 unsigned int base;323 unsigned int vco_mult;324 325 unsigned int fout;326 int sync_src;327 unsigned int sync_freq;328 int ref_src;329 unsigned int ref_freq;330 331 char lock_name[ARIZONA_FLL_NAME_LEN];332 char clock_ok_name[ARIZONA_FLL_NAME_LEN];333};334 335int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags);336int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags);337int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,338 struct snd_kcontrol *kcontrol, int event);339void arizona_init_dvfs(struct arizona_priv *priv);340 341int arizona_init_fll(struct arizona *arizona, int id, int base,342 int lock_irq, int ok_irq, struct arizona_fll *fll);343int arizona_set_fll_refclk(struct arizona_fll *fll, int source,344 unsigned int Fref, unsigned int Fout);345int arizona_set_fll(struct arizona_fll *fll, int source,346 unsigned int Fref, unsigned int Fout);347 348int arizona_init_spk(struct snd_soc_component *component);349int arizona_init_gpio(struct snd_soc_component *component);350int arizona_init_mono(struct snd_soc_component *component);351 352int arizona_init_common(struct arizona *arizona);353int arizona_init_vol_limit(struct arizona *arizona);354 355int arizona_init_spk_irqs(struct arizona *arizona);356int arizona_free_spk_irqs(struct arizona *arizona);357 358int arizona_init_dai(struct arizona_priv *priv, int id);359 360int arizona_set_output_mode(struct snd_soc_component *component, int output,361 bool diff);362 363bool arizona_input_analog(struct snd_soc_component *component, int shift);364 365const char *arizona_sample_rate_val_to_name(unsigned int rate_val);366 367static inline int arizona_register_notifier(struct snd_soc_component *component,368 struct notifier_block *nb,369 int (*notify)370 (struct notifier_block *nb,371 unsigned long action, void *data))372{373 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);374 struct arizona *arizona = priv->arizona;375 376 nb->notifier_call = notify;377 378 return blocking_notifier_chain_register(&arizona->notifier, nb);379}380 381static inline int arizona_unregister_notifier(struct snd_soc_component *component,382 struct notifier_block *nb)383{384 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);385 struct arizona *arizona = priv->arizona;386 387 return blocking_notifier_chain_unregister(&arizona->notifier, nb);388}389 390int arizona_of_get_audio_pdata(struct arizona *arizona);391 392int arizona_jack_codec_dev_probe(struct arizona_priv *info, struct device *dev);393int arizona_jack_codec_dev_remove(struct arizona_priv *info);394 395int arizona_jack_set_jack(struct snd_soc_component *component,396 struct snd_soc_jack *jack, void *data);397 398#endif399