xref: /linux/include/sound/hdaudio_ext.h (revision 76f56fae)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2dfe66a18SJeeja KP #ifndef __SOUND_HDAUDIO_EXT_H
3dfe66a18SJeeja KP #define __SOUND_HDAUDIO_EXT_H
4dfe66a18SJeeja KP 
5dfe66a18SJeeja KP #include <sound/hdaudio.h>
6dfe66a18SJeeja KP 
7*76f56faeSRakesh Ughreja int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
8dfe66a18SJeeja KP 		      const struct hdac_bus_ops *ops,
9dfe66a18SJeeja KP 		      const struct hdac_io_ops *io_ops);
10dfe66a18SJeeja KP 
11*76f56faeSRakesh Ughreja void snd_hdac_ext_bus_exit(struct hdac_bus *bus);
12*76f56faeSRakesh Ughreja int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr);
13dfe66a18SJeeja KP void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev);
14*76f56faeSRakesh Ughreja void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus);
15dfe66a18SJeeja KP 
16b6e84c99SSubhransu S. Prusty #define HDA_CODEC_REV_EXT_ENTRY(_vid, _rev, _name, drv_data) \
17b6e84c99SSubhransu S. Prusty 	{ .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
18b6e84c99SSubhransu S. Prusty 	  .api_version = HDA_DEV_ASOC, \
19b6e84c99SSubhransu S. Prusty 	  .driver_data = (unsigned long)(drv_data) }
20b6e84c99SSubhransu S. Prusty #define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
21b6e84c99SSubhransu S. Prusty 	HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
22b6e84c99SSubhransu S. Prusty 
23*76f56faeSRakesh Ughreja void snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *chip, bool enable);
24*76f56faeSRakesh Ughreja void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *chip, bool enable);
25dfe66a18SJeeja KP 
26*76f56faeSRakesh Ughreja void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *chip,
270b00a561SJeeja KP 				 bool enable, int index);
280b00a561SJeeja KP 
29*76f56faeSRakesh Ughreja int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus);
30*76f56faeSRakesh Ughreja struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus,
310b00a561SJeeja KP 						const char *codec_name);
320b00a561SJeeja KP 
330b00a561SJeeja KP enum hdac_ext_stream_type {
340b00a561SJeeja KP 	HDAC_EXT_STREAM_TYPE_COUPLED = 0,
350b00a561SJeeja KP 	HDAC_EXT_STREAM_TYPE_HOST,
360b00a561SJeeja KP 	HDAC_EXT_STREAM_TYPE_LINK
370b00a561SJeeja KP };
380b00a561SJeeja KP 
39df203a4eSJeeja KP /**
40df203a4eSJeeja KP  * hdac_ext_stream: HDAC extended stream for extended HDA caps
41df203a4eSJeeja KP  *
42df203a4eSJeeja KP  * @hstream: hdac_stream
43df203a4eSJeeja KP  * @pphc_addr: processing pipe host stream pointer
44df203a4eSJeeja KP  * @pplc_addr: processing pipe link stream pointer
45ee8bc4dfSJeeja KP  * @spib_addr: software position in buffers stream pointer
46ee8bc4dfSJeeja KP  * @fifo_addr: software position Max fifos stream pointer
47a9c48f7fSJeeja KP  * @dpibr_addr: DMA position in buffer resume pointer
48a9c48f7fSJeeja KP  * @dpib: DMA position in buffer
49a9c48f7fSJeeja KP  * @lpib: Linear position in buffer
50df203a4eSJeeja KP  * @decoupled: stream host and link is decoupled
51df203a4eSJeeja KP  * @link_locked: link is locked
52df203a4eSJeeja KP  * @link_prepared: link is prepared
53df203a4eSJeeja KP  * link_substream: link substream
54df203a4eSJeeja KP  */
55df203a4eSJeeja KP struct hdac_ext_stream {
56df203a4eSJeeja KP 	struct hdac_stream hstream;
57df203a4eSJeeja KP 
58df203a4eSJeeja KP 	void __iomem *pphc_addr;
59df203a4eSJeeja KP 	void __iomem *pplc_addr;
60df203a4eSJeeja KP 
61ee8bc4dfSJeeja KP 	void __iomem *spib_addr;
62ee8bc4dfSJeeja KP 	void __iomem *fifo_addr;
63ee8bc4dfSJeeja KP 
64a9c48f7fSJeeja KP 	void __iomem *dpibr_addr;
65a9c48f7fSJeeja KP 
66a9c48f7fSJeeja KP 	u32 dpib;
67a9c48f7fSJeeja KP 	u32 lpib;
68df203a4eSJeeja KP 	bool decoupled:1;
69df203a4eSJeeja KP 	bool link_locked:1;
70df203a4eSJeeja KP 	bool link_prepared;
71df203a4eSJeeja KP 
72df203a4eSJeeja KP 	struct snd_pcm_substream *link_substream;
73df203a4eSJeeja KP };
74df203a4eSJeeja KP 
75df203a4eSJeeja KP #define hdac_stream(s)		(&(s)->hstream)
76df203a4eSJeeja KP #define stream_to_hdac_ext_stream(s) \
77df203a4eSJeeja KP 	container_of(s, struct hdac_ext_stream, hstream)
78df203a4eSJeeja KP 
79*76f56faeSRakesh Ughreja void snd_hdac_ext_stream_init(struct hdac_bus *bus,
80df203a4eSJeeja KP 				struct hdac_ext_stream *stream, int idx,
81df203a4eSJeeja KP 				int direction, int tag);
82*76f56faeSRakesh Ughreja int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
83e7a3484dSVinod Koul 		int num_stream, int dir);
84*76f56faeSRakesh Ughreja void snd_hdac_stream_free_all(struct hdac_bus *bus);
85*76f56faeSRakesh Ughreja void snd_hdac_link_free_all(struct hdac_bus *bus);
86*76f56faeSRakesh Ughreja struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus,
87df203a4eSJeeja KP 					   struct snd_pcm_substream *substream,
88df203a4eSJeeja KP 					   int type);
89df203a4eSJeeja KP void snd_hdac_ext_stream_release(struct hdac_ext_stream *azx_dev, int type);
90*76f56faeSRakesh Ughreja void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
91df203a4eSJeeja KP 				struct hdac_ext_stream *azx_dev, bool decouple);
92*76f56faeSRakesh Ughreja void snd_hdac_ext_stop_streams(struct hdac_bus *bus);
93df203a4eSJeeja KP 
94*76f56faeSRakesh Ughreja int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus,
95ee8bc4dfSJeeja KP 				 struct hdac_ext_stream *stream, u32 value);
96*76f56faeSRakesh Ughreja int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus,
97ee8bc4dfSJeeja KP 				 struct hdac_ext_stream *stream);
98*76f56faeSRakesh Ughreja void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,
99a9c48f7fSJeeja KP 				bool enable, int index);
100*76f56faeSRakesh Ughreja int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus,
101a9c48f7fSJeeja KP 				struct hdac_ext_stream *stream, u32 value);
102a9c48f7fSJeeja KP int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *stream, u32 value);
103ee8bc4dfSJeeja KP 
104df203a4eSJeeja KP void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *hstream);
105df203a4eSJeeja KP void snd_hdac_ext_link_stream_clear(struct hdac_ext_stream *hstream);
106df203a4eSJeeja KP void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hstream);
107df203a4eSJeeja KP int snd_hdac_ext_link_stream_setup(struct hdac_ext_stream *stream, int fmt);
108df203a4eSJeeja KP 
1090b00a561SJeeja KP struct hdac_ext_link {
1100b00a561SJeeja KP 	struct hdac_bus *bus;
1110b00a561SJeeja KP 	int index;
1120b00a561SJeeja KP 	void __iomem *ml_addr; /* link output stream reg pointer */
1130b00a561SJeeja KP 	u32 lcaps;   /* link capablities */
1140b00a561SJeeja KP 	u16 lsdiid;  /* link sdi identifier */
1154446085dSVinod Koul 
1164446085dSVinod Koul 	int ref_count;
1174446085dSVinod Koul 
1180b00a561SJeeja KP 	struct list_head list;
1190b00a561SJeeja KP };
1200b00a561SJeeja KP 
1210b00a561SJeeja KP int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *link);
1220b00a561SJeeja KP int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link);
123*76f56faeSRakesh Ughreja int snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus);
124*76f56faeSRakesh Ughreja int snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus);
1250b00a561SJeeja KP void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link,
1260b00a561SJeeja KP 				 int stream);
1270b00a561SJeeja KP void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
1280b00a561SJeeja KP 				 int stream);
1290b00a561SJeeja KP 
130*76f56faeSRakesh Ughreja int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link);
131*76f56faeSRakesh Ughreja int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link);
1324446085dSVinod Koul 
1330b00a561SJeeja KP /* update register macro */
1340b00a561SJeeja KP #define snd_hdac_updatel(addr, reg, mask, val)		\
1350b00a561SJeeja KP 	writel(((readl(addr + reg) & ~(mask)) | (val)), \
1360b00a561SJeeja KP 		addr + reg)
1370b00a561SJeeja KP 
138df203a4eSJeeja KP #define snd_hdac_updatew(addr, reg, mask, val)		\
139df203a4eSJeeja KP 	writew(((readw(addr + reg) & ~(mask)) | (val)), \
140df203a4eSJeeja KP 		addr + reg)
141df203a4eSJeeja KP 
142a512f561SVinod Koul 
143a512f561SVinod Koul struct hdac_ext_device;
144a512f561SVinod Koul 
145a512f561SVinod Koul /* ops common to all codec drivers */
146a512f561SVinod Koul struct hdac_ext_codec_ops {
147a512f561SVinod Koul 	int (*build_controls)(struct hdac_ext_device *dev);
148a512f561SVinod Koul 	int (*init)(struct hdac_ext_device *dev);
149a512f561SVinod Koul 	void (*free)(struct hdac_ext_device *dev);
150a512f561SVinod Koul };
151a512f561SVinod Koul 
152a512f561SVinod Koul struct hda_dai_map {
153a512f561SVinod Koul 	char *dai_name;
154a512f561SVinod Koul 	hda_nid_t nid;
155a512f561SVinod Koul 	u32	maxbps;
156a512f561SVinod Koul };
157a512f561SVinod Koul 
1581e83b047SSubhransu S. Prusty struct hdac_ext_dma_params {
1591e83b047SSubhransu S. Prusty 	u32 format;
1601e83b047SSubhransu S. Prusty 	u8 stream_tag;
1611e83b047SSubhransu S. Prusty };
1623787a398SRakesh Ughreja 
163d51783c1SVinod Koul /*
164d51783c1SVinod Koul  * HD-audio codec base driver
165d51783c1SVinod Koul  */
166d51783c1SVinod Koul struct hdac_ext_driver {
167d51783c1SVinod Koul 	struct hdac_driver hdac;
168d51783c1SVinod Koul 
1693787a398SRakesh Ughreja 	int	(*probe)(struct hdac_device *dev);
1703787a398SRakesh Ughreja 	int	(*remove)(struct hdac_device *dev);
1713787a398SRakesh Ughreja 	void	(*shutdown)(struct hdac_device *dev);
172d51783c1SVinod Koul };
173d51783c1SVinod Koul 
174d51783c1SVinod Koul int snd_hda_ext_driver_register(struct hdac_ext_driver *drv);
175d51783c1SVinod Koul void snd_hda_ext_driver_unregister(struct hdac_ext_driver *drv);
176d51783c1SVinod Koul 
177d51783c1SVinod Koul #define to_ehdac_driver(_drv) container_of(_drv, struct hdac_ext_driver, hdac)
178a512f561SVinod Koul 
179dfe66a18SJeeja KP #endif /* __SOUND_HDAUDIO_EXT_H */
180