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