1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * wm_adsp.h -- Wolfson ADSP support 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright 2012 Wolfson Microelectronics plc 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #ifndef __WM_ADSP_H 11*4882a593Smuzhiyun #define __WM_ADSP_H 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun #include <sound/soc.h> 14*4882a593Smuzhiyun #include <sound/soc-dapm.h> 15*4882a593Smuzhiyun #include <sound/compress_driver.h> 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #include "wmfw.h" 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun /* Return values for wm_adsp_compr_handle_irq */ 20*4882a593Smuzhiyun #define WM_ADSP_COMPR_OK 0 21*4882a593Smuzhiyun #define WM_ADSP_COMPR_VOICE_TRIGGER 1 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun #define WM_ADSP2_REGION_0 BIT(0) 24*4882a593Smuzhiyun #define WM_ADSP2_REGION_1 BIT(1) 25*4882a593Smuzhiyun #define WM_ADSP2_REGION_2 BIT(2) 26*4882a593Smuzhiyun #define WM_ADSP2_REGION_3 BIT(3) 27*4882a593Smuzhiyun #define WM_ADSP2_REGION_4 BIT(4) 28*4882a593Smuzhiyun #define WM_ADSP2_REGION_5 BIT(5) 29*4882a593Smuzhiyun #define WM_ADSP2_REGION_6 BIT(6) 30*4882a593Smuzhiyun #define WM_ADSP2_REGION_7 BIT(7) 31*4882a593Smuzhiyun #define WM_ADSP2_REGION_8 BIT(8) 32*4882a593Smuzhiyun #define WM_ADSP2_REGION_9 BIT(9) 33*4882a593Smuzhiyun #define WM_ADSP2_REGION_1_9 (WM_ADSP2_REGION_1 | \ 34*4882a593Smuzhiyun WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3 | \ 35*4882a593Smuzhiyun WM_ADSP2_REGION_4 | WM_ADSP2_REGION_5 | \ 36*4882a593Smuzhiyun WM_ADSP2_REGION_6 | WM_ADSP2_REGION_7 | \ 37*4882a593Smuzhiyun WM_ADSP2_REGION_8 | WM_ADSP2_REGION_9) 38*4882a593Smuzhiyun #define WM_ADSP2_REGION_ALL (WM_ADSP2_REGION_0 | WM_ADSP2_REGION_1_9) 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun struct wm_adsp_region { 41*4882a593Smuzhiyun int type; 42*4882a593Smuzhiyun unsigned int base; 43*4882a593Smuzhiyun }; 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun struct wm_adsp_alg_region { 46*4882a593Smuzhiyun struct list_head list; 47*4882a593Smuzhiyun unsigned int alg; 48*4882a593Smuzhiyun int type; 49*4882a593Smuzhiyun unsigned int base; 50*4882a593Smuzhiyun }; 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun struct wm_adsp_compr; 53*4882a593Smuzhiyun struct wm_adsp_compr_buf; 54*4882a593Smuzhiyun struct wm_adsp_ops; 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun struct wm_adsp { 57*4882a593Smuzhiyun const char *part; 58*4882a593Smuzhiyun const char *name; 59*4882a593Smuzhiyun const char *fwf_name; 60*4882a593Smuzhiyun int rev; 61*4882a593Smuzhiyun int num; 62*4882a593Smuzhiyun int type; 63*4882a593Smuzhiyun struct device *dev; 64*4882a593Smuzhiyun struct regmap *regmap; 65*4882a593Smuzhiyun struct snd_soc_component *component; 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun struct wm_adsp_ops *ops; 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun unsigned int base; 70*4882a593Smuzhiyun unsigned int base_sysinfo; 71*4882a593Smuzhiyun unsigned int sysclk_reg; 72*4882a593Smuzhiyun unsigned int sysclk_mask; 73*4882a593Smuzhiyun unsigned int sysclk_shift; 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun struct list_head alg_regions; 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun unsigned int fw_id; 78*4882a593Smuzhiyun unsigned int fw_id_version; 79*4882a593Smuzhiyun unsigned int fw_vendor_id; 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun const struct wm_adsp_region *mem; 82*4882a593Smuzhiyun int num_mems; 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun int fw; 85*4882a593Smuzhiyun int fw_ver; 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun bool preloaded; 88*4882a593Smuzhiyun bool booted; 89*4882a593Smuzhiyun bool running; 90*4882a593Smuzhiyun bool fatal_error; 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun struct list_head ctl_list; 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun struct work_struct boot_work; 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun struct list_head compr_list; 97*4882a593Smuzhiyun struct list_head buffer_list; 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun struct mutex pwr_lock; 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun unsigned int lock_regions; 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS 104*4882a593Smuzhiyun struct dentry *debugfs_root; 105*4882a593Smuzhiyun char *wmfw_file_name; 106*4882a593Smuzhiyun char *bin_file_name; 107*4882a593Smuzhiyun #endif 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun }; 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun struct wm_adsp_ops { 112*4882a593Smuzhiyun unsigned int sys_config_size; 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun bool (*validate_version)(struct wm_adsp *dsp, unsigned int version); 115*4882a593Smuzhiyun unsigned int (*parse_sizes)(struct wm_adsp *dsp, 116*4882a593Smuzhiyun const char * const file, 117*4882a593Smuzhiyun unsigned int pos, 118*4882a593Smuzhiyun const struct firmware *firmware); 119*4882a593Smuzhiyun int (*setup_algs)(struct wm_adsp *dsp); 120*4882a593Smuzhiyun unsigned int (*region_to_reg)(struct wm_adsp_region const *mem, 121*4882a593Smuzhiyun unsigned int offset); 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun void (*show_fw_status)(struct wm_adsp *dsp); 124*4882a593Smuzhiyun void (*stop_watchdog)(struct wm_adsp *dsp); 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun int (*enable_memory)(struct wm_adsp *dsp); 127*4882a593Smuzhiyun void (*disable_memory)(struct wm_adsp *dsp); 128*4882a593Smuzhiyun int (*lock_memory)(struct wm_adsp *dsp, unsigned int lock_regions); 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun int (*enable_core)(struct wm_adsp *dsp); 131*4882a593Smuzhiyun void (*disable_core)(struct wm_adsp *dsp); 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun int (*start_core)(struct wm_adsp *dsp); 134*4882a593Smuzhiyun void (*stop_core)(struct wm_adsp *dsp); 135*4882a593Smuzhiyun }; 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun #define WM_ADSP1(wname, num) \ 138*4882a593Smuzhiyun SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ 139*4882a593Smuzhiyun wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun #define WM_ADSP2_PRELOAD_SWITCH(wname, num) \ 142*4882a593Smuzhiyun SOC_SINGLE_EXT(wname " Preload Switch", SND_SOC_NOPM, num, 1, 0, \ 143*4882a593Smuzhiyun wm_adsp2_preloader_get, wm_adsp2_preloader_put) 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun #define WM_ADSP2(wname, num, event_fn) \ 146*4882a593Smuzhiyun SND_SOC_DAPM_SPK(wname " Preload", NULL), \ 147*4882a593Smuzhiyun { .id = snd_soc_dapm_supply, .name = wname " Preloader", \ 148*4882a593Smuzhiyun .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ 149*4882a593Smuzhiyun .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \ 150*4882a593Smuzhiyun .subseq = 100, /* Ensure we run after SYSCLK supply widget */ }, \ 151*4882a593Smuzhiyun { .id = snd_soc_dapm_out_drv, .name = wname, \ 152*4882a593Smuzhiyun .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp_event, \ 153*4882a593Smuzhiyun .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun #define WM_ADSP_FW_CONTROL(dspname, num) \ 156*4882a593Smuzhiyun SOC_ENUM_EXT(dspname " Firmware", wm_adsp_fw_enum[num], \ 157*4882a593Smuzhiyun wm_adsp_fw_get, wm_adsp_fw_put) 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun extern const struct soc_enum wm_adsp_fw_enum[]; 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun int wm_adsp1_init(struct wm_adsp *dsp); 162*4882a593Smuzhiyun int wm_adsp2_init(struct wm_adsp *dsp); 163*4882a593Smuzhiyun void wm_adsp2_remove(struct wm_adsp *dsp); 164*4882a593Smuzhiyun int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component); 165*4882a593Smuzhiyun int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component); 166*4882a593Smuzhiyun int wm_halo_init(struct wm_adsp *dsp); 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun int wm_adsp1_event(struct snd_soc_dapm_widget *w, 169*4882a593Smuzhiyun struct snd_kcontrol *kcontrol, int event); 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun int wm_adsp_early_event(struct snd_soc_dapm_widget *w, 172*4882a593Smuzhiyun struct snd_kcontrol *kcontrol, int event); 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun irqreturn_t wm_adsp2_bus_error(int irq, void *data); 175*4882a593Smuzhiyun irqreturn_t wm_halo_bus_error(int irq, void *data); 176*4882a593Smuzhiyun irqreturn_t wm_halo_wdt_expire(int irq, void *data); 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun int wm_adsp_event(struct snd_soc_dapm_widget *w, 179*4882a593Smuzhiyun struct snd_kcontrol *kcontrol, int event); 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq); 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, 184*4882a593Smuzhiyun struct snd_ctl_elem_value *ucontrol); 185*4882a593Smuzhiyun int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, 186*4882a593Smuzhiyun struct snd_ctl_elem_value *ucontrol); 187*4882a593Smuzhiyun int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, 188*4882a593Smuzhiyun struct snd_ctl_elem_value *ucontrol); 189*4882a593Smuzhiyun int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, 190*4882a593Smuzhiyun struct snd_ctl_elem_value *ucontrol); 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream); 193*4882a593Smuzhiyun int wm_adsp_compr_free(struct snd_soc_component *component, 194*4882a593Smuzhiyun struct snd_compr_stream *stream); 195*4882a593Smuzhiyun int wm_adsp_compr_set_params(struct snd_soc_component *component, 196*4882a593Smuzhiyun struct snd_compr_stream *stream, 197*4882a593Smuzhiyun struct snd_compr_params *params); 198*4882a593Smuzhiyun int wm_adsp_compr_get_caps(struct snd_soc_component *component, 199*4882a593Smuzhiyun struct snd_compr_stream *stream, 200*4882a593Smuzhiyun struct snd_compr_caps *caps); 201*4882a593Smuzhiyun int wm_adsp_compr_trigger(struct snd_soc_component *component, 202*4882a593Smuzhiyun struct snd_compr_stream *stream, int cmd); 203*4882a593Smuzhiyun int wm_adsp_compr_handle_irq(struct wm_adsp *dsp); 204*4882a593Smuzhiyun int wm_adsp_compr_pointer(struct snd_soc_component *component, 205*4882a593Smuzhiyun struct snd_compr_stream *stream, 206*4882a593Smuzhiyun struct snd_compr_tstamp *tstamp); 207*4882a593Smuzhiyun int wm_adsp_compr_copy(struct snd_soc_component *component, 208*4882a593Smuzhiyun struct snd_compr_stream *stream, 209*4882a593Smuzhiyun char __user *buf, size_t count); 210*4882a593Smuzhiyun int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, 211*4882a593Smuzhiyun unsigned int alg, void *buf, size_t len); 212*4882a593Smuzhiyun int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, 213*4882a593Smuzhiyun unsigned int alg, void *buf, size_t len); 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun #endif 216