ASoC: wm_adsp: Update Cirrus ADSP driver

Add support for HALO DSP Core.

Change-Id: Iae25b559d2277bd40241f85d265d1fc2ac9280a6
Reviewed-on: https://gerrit.mot.com/1166692
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Yuesheng Huang <huangys@motorola.com>
Reviewed-by: Guobin Zhang <zhanggb@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Vlad Karpovich 2018-04-04 16:53:28 -05:00 • committed by Yuesheng Huang
commit 23e33a0c4d
3 changed files with 1869 additions and 376 deletions

File diff suppressed because it is too large Load diff

View file

@ -56,17 +56,41 @@ struct wm_adsp_alg_region {
struct wm_adsp_compr;
struct wm_adsp_compr_buf;
struct wm_adsp_buffer_region_def {
unsigned int mem_type;
unsigned int base_offset;
unsigned int size_offset;
};
struct wm_adsp_fw_caps {
u32 id;
struct snd_codec_desc desc;
int num_regions;
struct wm_adsp_buffer_region_def *region_defs;
};
struct wm_adsp_fw_defs {
const char *file;
const char *binfile;
bool fullname;
int compr_direction;
int num_caps;
struct wm_adsp_fw_caps *caps;
bool voice_trigger;
};
struct wm_adsp {
const char *part;
int rev;
int num;
int type;
const char *suffix;
struct device *dev;
struct regmap *regmap;
struct snd_soc_card *card;
struct snd_soc_codec *codec;
int base;
int base_sysinfo;
int sysclk_reg;
int sysclk_mask;
int sysclk_shift;
@ -75,14 +99,21 @@ struct wm_adsp {
unsigned int fw_id;
unsigned int fw_id_version;
unsigned int fw_vendor_id;
const struct wm_adsp_region *mem;
int num_mems;
int fw;
int fw_ver;
bool preloaded;
bool booted;
bool running;
int num_firmwares;
struct wm_adsp_fw_defs *firmwares;
struct list_head ctl_list;
struct work_struct boot_work;
@ -92,16 +123,24 @@ struct wm_adsp {
struct wm_adsp_compr_buf *buffer[WM_ADSP_MAX_CHANNEL_PER_DSP];
struct mutex pwr_lock;
struct mutex *fw_lock;
unsigned int lock_regions;
bool unlock_all;
unsigned int n_rx_channels;
unsigned int n_tx_channels;
struct mutex *rate_lock;
u8 *rx_rate_cache;
u8 *tx_rate_cache;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_root;
char *wmfw_file_name;
char *bin_file_name;
#endif
const char *wmfw_file;
const char *bin_file;
unsigned int lock_regions;
void (*fwevent_cb)(struct wm_adsp *dsp, int eventid);
};
struct wm_adsp_compr {
@ -122,46 +161,78 @@ struct wm_adsp_compr {
SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
#define WM_ADSP2_PRELOAD_SWITCH(wname, num) \
SOC_SINGLE_EXT(wname " Preload Switch", SND_SOC_NOPM, num, 1, 0, \
wm_adsp2_preloader_get, wm_adsp2_preloader_put)
#define WM_ADSP2(wname, num, event_fn) \
{ .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \
SND_SOC_DAPM_SPK(wname " Preload", NULL), \
{ .id = snd_soc_dapm_supply, .name = wname " Preloader", \
.reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \
.subseq = 100, /* Ensure we run after SYSCLK supply widget */ }, \
{ .id = snd_soc_dapm_out_drv, .name = wname, \
.reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
#define WM_HALO(wname, num, event_fn) \
SND_SOC_DAPM_SPK(wname " Preload", NULL), \
{ .id = snd_soc_dapm_supply, .name = wname " Preloader", \
.reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \
.subseq = 100, /* Ensure we run after SYSCLK supply widget */ }, \
{ .id = snd_soc_dapm_out_drv, .name = wname, \
.reg = SND_SOC_NOPM, .shift = num, .event = wm_halo_event, \
.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
extern const struct snd_kcontrol_new wm_adsp_fw_controls[];
int wm_adsp1_init(struct wm_adsp *dsp);
int wm_adsp2_init(struct wm_adsp *dsp, struct mutex *fw_lock);
int wm_adsp2_init(struct wm_adsp *dsp);
void wm_adsp2_remove(struct wm_adsp *dsp);
int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec);
int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec,
bool ao_dsp);
int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec);
int wm_halo_init(struct wm_adsp *dsp, struct mutex *rate_lock);
int wm_adsp1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event,
unsigned int freq);
int wm_adsp2_lock(struct wm_adsp *adsp, unsigned int regions);
irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp);
irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp);
int wm_adsp2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
extern int wm_adsp_compr_open(struct wm_adsp *dsp,
int wm_halo_early_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int wm_halo_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int wm_adsp_compr_open(struct wm_adsp *dsp,
struct snd_compr_stream *stream,
int channel);
extern int wm_adsp_compr_free(struct snd_compr_stream *stream);
extern int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
struct snd_compr_params *params);
extern int wm_adsp_compr_get_caps(struct snd_compr_stream *stream,
struct snd_compr_caps *caps);
extern int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd);
extern int wm_adsp_compr_handle_irq(struct wm_adsp *dsp, int channel);
extern int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
struct snd_compr_tstamp *tstamp);
extern int wm_adsp_compr_copy(struct snd_compr_stream *stream,
char __user *buf, size_t count);
int wm_adsp_compr_free(struct snd_compr_stream *stream);
int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
struct snd_compr_params *params);
int wm_adsp_compr_get_caps(struct snd_compr_stream *stream,
struct snd_compr_caps *caps);
int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd);
int wm_adsp_compr_handle_irq(struct wm_adsp *dsp, int channel);
int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
struct snd_compr_tstamp *tstamp);
int wm_adsp_compr_copy(struct snd_compr_stream *stream,
char __user *buf, size_t count);
extern int wm_adsp_handle_fw_event(struct wm_adsp *dsp);
#endif

View file

@ -26,6 +26,11 @@
#define WMFW_CTL_FLAG_WRITEABLE 0x0002
#define WMFW_CTL_FLAG_READABLE 0x0001
/* Non-ALSA coefficient types start at 0x1000 */
#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */
#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */
#define WMFW_CTL_TYPE_FWEVENT 0x1004 /* firmware event control */
struct wmfw_header {
char magic[4];
__le32 len;
@ -83,6 +88,23 @@ struct wmfw_adsp2_id_hdr {
__be32 n_algs;
} __packed;
struct wmfw_halo_fwid_hdr {
__be32 core_id;
__be32 block_rev;
__be32 vendor_id;
__be32 id;
__be32 ver;
} __packed;
struct wmfw_halo_id_hdr {
struct wmfw_halo_fwid_hdr fw;
__be32 xm_base;
__be32 xm_size;
__be32 ym_base;
__be32 ym_size;
__be32 n_algs;
} __packed;
struct wmfw_alg_hdr {
__be32 id;
__be32 ver;
@ -101,6 +123,14 @@ struct wmfw_adsp2_alg_hdr {
__be32 ym;
} __packed;
struct wmfw_halo_alg_hdr {
struct wmfw_alg_hdr alg;
__be32 xm_base;
__be32 xm_size;
__be32 ym_base;
__be32 ym_size;
} __packed;
struct wmfw_adsp_alg_data {
__le32 id;
u8 name[WMFW_MAX_ALG_NAME];
@ -149,6 +179,7 @@ struct wmfw_coeff_item {
#define WMFW_ADSP1 1
#define WMFW_ADSP2 2
#define WMFW_HALO 4
#define WMFW_ABSOLUTE 0xf0
#define WMFW_ALGORITHM_DATA 0xf2
@ -164,4 +195,8 @@ struct wmfw_coeff_item {
#define WMFW_ADSP2_XM 5
#define WMFW_ADSP2_YM 6
#define WMFW_HALO_PM_PACKED 0x10
#define WMFW_HALO_XM_PACKED 0x11
#define WMFW_HALO_YM_PACKED 0x12
#endif