162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __SOUND_HDAUDIO_EXT_H 362306a36Sopenharmony_ci#define __SOUND_HDAUDIO_EXT_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/io-64-nonatomic-lo-hi.h> 662306a36Sopenharmony_ci#include <linux/iopoll.h> 762306a36Sopenharmony_ci#include <sound/hdaudio.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciint snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, 1062306a36Sopenharmony_ci const struct hdac_bus_ops *ops, 1162306a36Sopenharmony_ci const struct hdac_ext_bus_ops *ext_ops); 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_civoid snd_hdac_ext_bus_exit(struct hdac_bus *bus); 1462306a36Sopenharmony_civoid snd_hdac_ext_bus_device_remove(struct hdac_bus *bus); 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define HDA_CODEC_REV_EXT_ENTRY(_vid, _rev, _name, drv_data) \ 1762306a36Sopenharmony_ci { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \ 1862306a36Sopenharmony_ci .api_version = HDA_DEV_ASOC, \ 1962306a36Sopenharmony_ci .driver_data = (unsigned long)(drv_data) } 2062306a36Sopenharmony_ci#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \ 2162306a36Sopenharmony_ci HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data) 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_civoid snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *chip, bool enable); 2462306a36Sopenharmony_civoid snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *chip, bool enable); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ciint snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus); 2762306a36Sopenharmony_cistruct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_addr(struct hdac_bus *bus, int addr); 2862306a36Sopenharmony_cistruct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_name(struct hdac_bus *bus, 2962306a36Sopenharmony_ci const char *codec_name); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cienum hdac_ext_stream_type { 3262306a36Sopenharmony_ci HDAC_EXT_STREAM_TYPE_COUPLED = 0, 3362306a36Sopenharmony_ci HDAC_EXT_STREAM_TYPE_HOST, 3462306a36Sopenharmony_ci HDAC_EXT_STREAM_TYPE_LINK 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/** 3862306a36Sopenharmony_ci * hdac_ext_stream: HDAC extended stream for extended HDA caps 3962306a36Sopenharmony_ci * 4062306a36Sopenharmony_ci * @hstream: hdac_stream 4162306a36Sopenharmony_ci * @pphc_addr: processing pipe host stream pointer 4262306a36Sopenharmony_ci * @pplc_addr: processing pipe link stream pointer 4362306a36Sopenharmony_ci * @decoupled: stream host and link is decoupled 4462306a36Sopenharmony_ci * @link_locked: link is locked 4562306a36Sopenharmony_ci * @link_prepared: link is prepared 4662306a36Sopenharmony_ci * @link_substream: link substream 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_cistruct hdac_ext_stream { 4962306a36Sopenharmony_ci struct hdac_stream hstream; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci void __iomem *pphc_addr; 5262306a36Sopenharmony_ci void __iomem *pplc_addr; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci u32 pphcllpl; 5562306a36Sopenharmony_ci u32 pphcllpu; 5662306a36Sopenharmony_ci u32 pphcldpl; 5762306a36Sopenharmony_ci u32 pphcldpu; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci bool decoupled:1; 6062306a36Sopenharmony_ci bool link_locked:1; 6162306a36Sopenharmony_ci bool link_prepared; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci struct snd_pcm_substream *link_substream; 6462306a36Sopenharmony_ci}; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#define hdac_stream(s) (&(s)->hstream) 6762306a36Sopenharmony_ci#define stream_to_hdac_ext_stream(s) \ 6862306a36Sopenharmony_ci container_of(s, struct hdac_ext_stream, hstream) 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ciint snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx, 7162306a36Sopenharmony_ci int num_stream, int dir); 7262306a36Sopenharmony_civoid snd_hdac_ext_stream_free_all(struct hdac_bus *bus); 7362306a36Sopenharmony_civoid snd_hdac_ext_link_free_all(struct hdac_bus *bus); 7462306a36Sopenharmony_cistruct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus, 7562306a36Sopenharmony_ci struct snd_pcm_substream *substream, 7662306a36Sopenharmony_ci int type); 7762306a36Sopenharmony_civoid snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type); 7862306a36Sopenharmony_cistruct hdac_ext_stream *snd_hdac_ext_cstream_assign(struct hdac_bus *bus, 7962306a36Sopenharmony_ci struct snd_compr_stream *cstream); 8062306a36Sopenharmony_civoid snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus, 8162306a36Sopenharmony_ci struct hdac_ext_stream *hext_stream, bool decouple); 8262306a36Sopenharmony_civoid snd_hdac_ext_stream_decouple(struct hdac_bus *bus, 8362306a36Sopenharmony_ci struct hdac_ext_stream *azx_dev, bool decouple); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_civoid snd_hdac_ext_stream_start(struct hdac_ext_stream *hext_stream); 8662306a36Sopenharmony_civoid snd_hdac_ext_stream_clear(struct hdac_ext_stream *hext_stream); 8762306a36Sopenharmony_civoid snd_hdac_ext_stream_reset(struct hdac_ext_stream *hext_stream); 8862306a36Sopenharmony_ciint snd_hdac_ext_stream_setup(struct hdac_ext_stream *hext_stream, int fmt); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistruct hdac_ext_link { 9162306a36Sopenharmony_ci struct hdac_bus *bus; 9262306a36Sopenharmony_ci int index; 9362306a36Sopenharmony_ci void __iomem *ml_addr; /* link output stream reg pointer */ 9462306a36Sopenharmony_ci u32 lcaps; /* link capablities */ 9562306a36Sopenharmony_ci u16 lsdiid; /* link sdi identifier */ 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci int ref_count; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci struct list_head list; 10062306a36Sopenharmony_ci}; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ciint snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *hlink); 10362306a36Sopenharmony_ciint snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *hlink); 10462306a36Sopenharmony_ciint snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus); 10562306a36Sopenharmony_ciint snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus); 10662306a36Sopenharmony_civoid snd_hdac_ext_bus_link_set_stream_id(struct hdac_ext_link *hlink, 10762306a36Sopenharmony_ci int stream); 10862306a36Sopenharmony_civoid snd_hdac_ext_bus_link_clear_stream_id(struct hdac_ext_link *hlink, 10962306a36Sopenharmony_ci int stream); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciint snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *hlink); 11262306a36Sopenharmony_ciint snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *hlink); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_civoid snd_hdac_ext_bus_link_power(struct hdac_device *codec, bool enable); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci#define snd_hdac_adsp_writeb(chip, reg, value) \ 11762306a36Sopenharmony_ci snd_hdac_reg_writeb(chip, (chip)->dsp_ba + (reg), value) 11862306a36Sopenharmony_ci#define snd_hdac_adsp_readb(chip, reg) \ 11962306a36Sopenharmony_ci snd_hdac_reg_readb(chip, (chip)->dsp_ba + (reg)) 12062306a36Sopenharmony_ci#define snd_hdac_adsp_writew(chip, reg, value) \ 12162306a36Sopenharmony_ci snd_hdac_reg_writew(chip, (chip)->dsp_ba + (reg), value) 12262306a36Sopenharmony_ci#define snd_hdac_adsp_readw(chip, reg) \ 12362306a36Sopenharmony_ci snd_hdac_reg_readw(chip, (chip)->dsp_ba + (reg)) 12462306a36Sopenharmony_ci#define snd_hdac_adsp_writel(chip, reg, value) \ 12562306a36Sopenharmony_ci snd_hdac_reg_writel(chip, (chip)->dsp_ba + (reg), value) 12662306a36Sopenharmony_ci#define snd_hdac_adsp_readl(chip, reg) \ 12762306a36Sopenharmony_ci snd_hdac_reg_readl(chip, (chip)->dsp_ba + (reg)) 12862306a36Sopenharmony_ci#define snd_hdac_adsp_writeq(chip, reg, value) \ 12962306a36Sopenharmony_ci snd_hdac_reg_writeq(chip, (chip)->dsp_ba + (reg), value) 13062306a36Sopenharmony_ci#define snd_hdac_adsp_readq(chip, reg) \ 13162306a36Sopenharmony_ci snd_hdac_reg_readq(chip, (chip)->dsp_ba + (reg)) 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci#define snd_hdac_adsp_updateb(chip, reg, mask, val) \ 13462306a36Sopenharmony_ci snd_hdac_adsp_writeb(chip, reg, \ 13562306a36Sopenharmony_ci (snd_hdac_adsp_readb(chip, reg) & ~(mask)) | (val)) 13662306a36Sopenharmony_ci#define snd_hdac_adsp_updatew(chip, reg, mask, val) \ 13762306a36Sopenharmony_ci snd_hdac_adsp_writew(chip, reg, \ 13862306a36Sopenharmony_ci (snd_hdac_adsp_readw(chip, reg) & ~(mask)) | (val)) 13962306a36Sopenharmony_ci#define snd_hdac_adsp_updatel(chip, reg, mask, val) \ 14062306a36Sopenharmony_ci snd_hdac_adsp_writel(chip, reg, \ 14162306a36Sopenharmony_ci (snd_hdac_adsp_readl(chip, reg) & ~(mask)) | (val)) 14262306a36Sopenharmony_ci#define snd_hdac_adsp_updateq(chip, reg, mask, val) \ 14362306a36Sopenharmony_ci snd_hdac_adsp_writeq(chip, reg, \ 14462306a36Sopenharmony_ci (snd_hdac_adsp_readq(chip, reg) & ~(mask)) | (val)) 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci#define snd_hdac_adsp_readb_poll(chip, reg, val, cond, delay_us, timeout_us) \ 14762306a36Sopenharmony_ci readb_poll_timeout((chip)->dsp_ba + (reg), val, cond, \ 14862306a36Sopenharmony_ci delay_us, timeout_us) 14962306a36Sopenharmony_ci#define snd_hdac_adsp_readw_poll(chip, reg, val, cond, delay_us, timeout_us) \ 15062306a36Sopenharmony_ci readw_poll_timeout((chip)->dsp_ba + (reg), val, cond, \ 15162306a36Sopenharmony_ci delay_us, timeout_us) 15262306a36Sopenharmony_ci#define snd_hdac_adsp_readl_poll(chip, reg, val, cond, delay_us, timeout_us) \ 15362306a36Sopenharmony_ci readl_poll_timeout((chip)->dsp_ba + (reg), val, cond, \ 15462306a36Sopenharmony_ci delay_us, timeout_us) 15562306a36Sopenharmony_ci#define snd_hdac_adsp_readq_poll(chip, reg, val, cond, delay_us, timeout_us) \ 15662306a36Sopenharmony_ci readq_poll_timeout((chip)->dsp_ba + (reg), val, cond, \ 15762306a36Sopenharmony_ci delay_us, timeout_us) 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cistruct hdac_ext_device; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* ops common to all codec drivers */ 16262306a36Sopenharmony_cistruct hdac_ext_codec_ops { 16362306a36Sopenharmony_ci int (*build_controls)(struct hdac_ext_device *dev); 16462306a36Sopenharmony_ci int (*init)(struct hdac_ext_device *dev); 16562306a36Sopenharmony_ci void (*free)(struct hdac_ext_device *dev); 16662306a36Sopenharmony_ci}; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cistruct hda_dai_map { 16962306a36Sopenharmony_ci char *dai_name; 17062306a36Sopenharmony_ci hda_nid_t nid; 17162306a36Sopenharmony_ci u32 maxbps; 17262306a36Sopenharmony_ci}; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistruct hdac_ext_dma_params { 17562306a36Sopenharmony_ci u32 format; 17662306a36Sopenharmony_ci u8 stream_tag; 17762306a36Sopenharmony_ci}; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ciint snd_hda_ext_driver_register(struct hdac_driver *drv); 18062306a36Sopenharmony_civoid snd_hda_ext_driver_unregister(struct hdac_driver *drv); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci#endif /* __SOUND_HDAUDIO_EXT_H */ 183