18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __SOUND_HDAUDIO_EXT_H
38c2ecf20Sopenharmony_ci#define __SOUND_HDAUDIO_EXT_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <sound/hdaudio.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciint snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
88c2ecf20Sopenharmony_ci		      const struct hdac_bus_ops *ops,
98c2ecf20Sopenharmony_ci		      const struct hdac_ext_bus_ops *ext_ops);
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_civoid snd_hdac_ext_bus_exit(struct hdac_bus *bus);
128c2ecf20Sopenharmony_ciint snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr,
138c2ecf20Sopenharmony_ci				struct hdac_device *hdev, int type);
148c2ecf20Sopenharmony_civoid snd_hdac_ext_bus_device_exit(struct hdac_device *hdev);
158c2ecf20Sopenharmony_civoid snd_hdac_ext_bus_device_remove(struct hdac_bus *bus);
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define HDA_CODEC_REV_EXT_ENTRY(_vid, _rev, _name, drv_data) \
188c2ecf20Sopenharmony_ci	{ .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
198c2ecf20Sopenharmony_ci	  .api_version = HDA_DEV_ASOC, \
208c2ecf20Sopenharmony_ci	  .driver_data = (unsigned long)(drv_data) }
218c2ecf20Sopenharmony_ci#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
228c2ecf20Sopenharmony_ci	HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_civoid snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *chip, bool enable);
258c2ecf20Sopenharmony_civoid snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *chip, bool enable);
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_civoid snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *chip,
288c2ecf20Sopenharmony_ci				 bool enable, int index);
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ciint snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus);
318c2ecf20Sopenharmony_cistruct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus,
328c2ecf20Sopenharmony_ci						const char *codec_name);
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_cienum hdac_ext_stream_type {
358c2ecf20Sopenharmony_ci	HDAC_EXT_STREAM_TYPE_COUPLED = 0,
368c2ecf20Sopenharmony_ci	HDAC_EXT_STREAM_TYPE_HOST,
378c2ecf20Sopenharmony_ci	HDAC_EXT_STREAM_TYPE_LINK
388c2ecf20Sopenharmony_ci};
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/**
418c2ecf20Sopenharmony_ci * hdac_ext_stream: HDAC extended stream for extended HDA caps
428c2ecf20Sopenharmony_ci *
438c2ecf20Sopenharmony_ci * @hstream: hdac_stream
448c2ecf20Sopenharmony_ci * @pphc_addr: processing pipe host stream pointer
458c2ecf20Sopenharmony_ci * @pplc_addr: processing pipe link stream pointer
468c2ecf20Sopenharmony_ci * @spib_addr: software position in buffers stream pointer
478c2ecf20Sopenharmony_ci * @fifo_addr: software position Max fifos stream pointer
488c2ecf20Sopenharmony_ci * @dpibr_addr: DMA position in buffer resume pointer
498c2ecf20Sopenharmony_ci * @dpib: DMA position in buffer
508c2ecf20Sopenharmony_ci * @lpib: Linear position in buffer
518c2ecf20Sopenharmony_ci * @decoupled: stream host and link is decoupled
528c2ecf20Sopenharmony_ci * @link_locked: link is locked
538c2ecf20Sopenharmony_ci * @link_prepared: link is prepared
548c2ecf20Sopenharmony_ci * link_substream: link substream
558c2ecf20Sopenharmony_ci */
568c2ecf20Sopenharmony_cistruct hdac_ext_stream {
578c2ecf20Sopenharmony_ci	struct hdac_stream hstream;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	void __iomem *pphc_addr;
608c2ecf20Sopenharmony_ci	void __iomem *pplc_addr;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	void __iomem *spib_addr;
638c2ecf20Sopenharmony_ci	void __iomem *fifo_addr;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	void __iomem *dpibr_addr;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	u32 dpib;
688c2ecf20Sopenharmony_ci	u32 lpib;
698c2ecf20Sopenharmony_ci	bool decoupled:1;
708c2ecf20Sopenharmony_ci	bool link_locked:1;
718c2ecf20Sopenharmony_ci	bool link_prepared;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	struct snd_pcm_substream *link_substream;
748c2ecf20Sopenharmony_ci};
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci#define hdac_stream(s)		(&(s)->hstream)
778c2ecf20Sopenharmony_ci#define stream_to_hdac_ext_stream(s) \
788c2ecf20Sopenharmony_ci	container_of(s, struct hdac_ext_stream, hstream)
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_civoid snd_hdac_ext_stream_init(struct hdac_bus *bus,
818c2ecf20Sopenharmony_ci				struct hdac_ext_stream *stream, int idx,
828c2ecf20Sopenharmony_ci				int direction, int tag);
838c2ecf20Sopenharmony_ciint snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
848c2ecf20Sopenharmony_ci		int num_stream, int dir);
858c2ecf20Sopenharmony_civoid snd_hdac_stream_free_all(struct hdac_bus *bus);
868c2ecf20Sopenharmony_civoid snd_hdac_link_free_all(struct hdac_bus *bus);
878c2ecf20Sopenharmony_cistruct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus,
888c2ecf20Sopenharmony_ci					   struct snd_pcm_substream *substream,
898c2ecf20Sopenharmony_ci					   int type);
908c2ecf20Sopenharmony_civoid snd_hdac_ext_stream_release(struct hdac_ext_stream *azx_dev, int type);
918c2ecf20Sopenharmony_civoid snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus,
928c2ecf20Sopenharmony_ci				  struct hdac_ext_stream *azx_dev, bool decouple);
938c2ecf20Sopenharmony_civoid snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
948c2ecf20Sopenharmony_ci				struct hdac_ext_stream *azx_dev, bool decouple);
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ciint snd_hdac_ext_stream_set_spib(struct hdac_bus *bus,
978c2ecf20Sopenharmony_ci				 struct hdac_ext_stream *stream, u32 value);
988c2ecf20Sopenharmony_ciint snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus,
998c2ecf20Sopenharmony_ci				 struct hdac_ext_stream *stream);
1008c2ecf20Sopenharmony_civoid snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,
1018c2ecf20Sopenharmony_ci				bool enable, int index);
1028c2ecf20Sopenharmony_ciint snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus,
1038c2ecf20Sopenharmony_ci				struct hdac_ext_stream *stream, u32 value);
1048c2ecf20Sopenharmony_ciint snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *stream, u32 value);
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_civoid snd_hdac_ext_link_stream_start(struct hdac_ext_stream *hstream);
1078c2ecf20Sopenharmony_civoid snd_hdac_ext_link_stream_clear(struct hdac_ext_stream *hstream);
1088c2ecf20Sopenharmony_civoid snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hstream);
1098c2ecf20Sopenharmony_ciint snd_hdac_ext_link_stream_setup(struct hdac_ext_stream *stream, int fmt);
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cistruct hdac_ext_link {
1128c2ecf20Sopenharmony_ci	struct hdac_bus *bus;
1138c2ecf20Sopenharmony_ci	int index;
1148c2ecf20Sopenharmony_ci	void __iomem *ml_addr; /* link output stream reg pointer */
1158c2ecf20Sopenharmony_ci	u32 lcaps;   /* link capablities */
1168c2ecf20Sopenharmony_ci	u16 lsdiid;  /* link sdi identifier */
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	int ref_count;
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	struct list_head list;
1218c2ecf20Sopenharmony_ci};
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ciint snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *link);
1248c2ecf20Sopenharmony_ciint snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link);
1258c2ecf20Sopenharmony_ciint snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus);
1268c2ecf20Sopenharmony_ciint snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus);
1278c2ecf20Sopenharmony_civoid snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link,
1288c2ecf20Sopenharmony_ci				 int stream);
1298c2ecf20Sopenharmony_civoid snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
1308c2ecf20Sopenharmony_ci				 int stream);
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ciint snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link);
1338c2ecf20Sopenharmony_ciint snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link);
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci/* update register macro */
1368c2ecf20Sopenharmony_ci#define snd_hdac_updatel(addr, reg, mask, val)		\
1378c2ecf20Sopenharmony_ci	writel(((readl(addr + reg) & ~(mask)) | (val)), \
1388c2ecf20Sopenharmony_ci		addr + reg)
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci#define snd_hdac_updatew(addr, reg, mask, val)		\
1418c2ecf20Sopenharmony_ci	writew(((readw(addr + reg) & ~(mask)) | (val)), \
1428c2ecf20Sopenharmony_ci		addr + reg)
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistruct hdac_ext_device;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci/* ops common to all codec drivers */
1488c2ecf20Sopenharmony_cistruct hdac_ext_codec_ops {
1498c2ecf20Sopenharmony_ci	int (*build_controls)(struct hdac_ext_device *dev);
1508c2ecf20Sopenharmony_ci	int (*init)(struct hdac_ext_device *dev);
1518c2ecf20Sopenharmony_ci	void (*free)(struct hdac_ext_device *dev);
1528c2ecf20Sopenharmony_ci};
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_cistruct hda_dai_map {
1558c2ecf20Sopenharmony_ci	char *dai_name;
1568c2ecf20Sopenharmony_ci	hda_nid_t nid;
1578c2ecf20Sopenharmony_ci	u32	maxbps;
1588c2ecf20Sopenharmony_ci};
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_cistruct hdac_ext_dma_params {
1618c2ecf20Sopenharmony_ci	u32 format;
1628c2ecf20Sopenharmony_ci	u8 stream_tag;
1638c2ecf20Sopenharmony_ci};
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ciint snd_hda_ext_driver_register(struct hdac_driver *drv);
1668c2ecf20Sopenharmony_civoid snd_hda_ext_driver_unregister(struct hdac_driver *drv);
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci#endif /* __SOUND_HDAUDIO_EXT_H */
169