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