blob: e5b0cd1ade19c2ac71eed6bebc76553f63d4a06b [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Jeeja KPdfe66a12015-06-11 14:11:47 +05302#ifndef __SOUND_HDAUDIO_EXT_H
3#define __SOUND_HDAUDIO_EXT_H
4
5#include <sound/hdaudio.h>
6
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -05007int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
Jeeja KPdfe66a12015-06-11 14:11:47 +05308 const struct hdac_bus_ops *ops,
9 const struct hdac_io_ops *io_ops);
10
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050011void snd_hdac_ext_bus_exit(struct hdac_bus *bus);
12int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr);
Jeeja KPdfe66a12015-06-11 14:11:47 +053013void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev);
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050014void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus);
Jeeja KPdfe66a12015-06-11 14:11:47 +053015
Subhransu S. Prustyb6e84c92015-10-19 16:58:46 +053016#define HDA_CODEC_REV_EXT_ENTRY(_vid, _rev, _name, drv_data) \
17 { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
18 .api_version = HDA_DEV_ASOC, \
19 .driver_data = (unsigned long)(drv_data) }
20#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
21 HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
22
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050023void snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *chip, bool enable);
24void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *chip, bool enable);
Jeeja KPdfe66a12015-06-11 14:11:47 +053025
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050026void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *chip,
Jeeja KP0b00a562015-06-11 14:11:48 +053027 bool enable, int index);
28
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050029int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus);
30struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus,
Jeeja KP0b00a562015-06-11 14:11:48 +053031 const char *codec_name);
32
33enum hdac_ext_stream_type {
34 HDAC_EXT_STREAM_TYPE_COUPLED = 0,
35 HDAC_EXT_STREAM_TYPE_HOST,
36 HDAC_EXT_STREAM_TYPE_LINK
37};
38
Jeeja KPdf203a42015-06-11 14:11:49 +053039/**
40 * hdac_ext_stream: HDAC extended stream for extended HDA caps
41 *
42 * @hstream: hdac_stream
43 * @pphc_addr: processing pipe host stream pointer
44 * @pplc_addr: processing pipe link stream pointer
Jeeja KPee8bc4d2015-08-21 21:36:20 +053045 * @spib_addr: software position in buffers stream pointer
46 * @fifo_addr: software position Max fifos stream pointer
Jeeja KPa9c48f72015-12-18 15:11:59 +053047 * @dpibr_addr: DMA position in buffer resume pointer
48 * @dpib: DMA position in buffer
49 * @lpib: Linear position in buffer
Jeeja KPdf203a42015-06-11 14:11:49 +053050 * @decoupled: stream host and link is decoupled
51 * @link_locked: link is locked
52 * @link_prepared: link is prepared
53 * link_substream: link substream
54 */
55struct hdac_ext_stream {
56 struct hdac_stream hstream;
57
58 void __iomem *pphc_addr;
59 void __iomem *pplc_addr;
60
Jeeja KPee8bc4d2015-08-21 21:36:20 +053061 void __iomem *spib_addr;
62 void __iomem *fifo_addr;
63
Jeeja KPa9c48f72015-12-18 15:11:59 +053064 void __iomem *dpibr_addr;
65
66 u32 dpib;
67 u32 lpib;
Jeeja KPdf203a42015-06-11 14:11:49 +053068 bool decoupled:1;
69 bool link_locked:1;
70 bool link_prepared;
71
72 struct snd_pcm_substream *link_substream;
73};
74
75#define hdac_stream(s) (&(s)->hstream)
76#define stream_to_hdac_ext_stream(s) \
77 container_of(s, struct hdac_ext_stream, hstream)
78
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050079void snd_hdac_ext_stream_init(struct hdac_bus *bus,
Jeeja KPdf203a42015-06-11 14:11:49 +053080 struct hdac_ext_stream *stream, int idx,
81 int direction, int tag);
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050082int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
Vinod Koule7a34842015-06-17 11:20:16 +053083 int num_stream, int dir);
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050084void snd_hdac_stream_free_all(struct hdac_bus *bus);
85void snd_hdac_link_free_all(struct hdac_bus *bus);
86struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus,
Jeeja KPdf203a42015-06-11 14:11:49 +053087 struct snd_pcm_substream *substream,
88 int type);
89void snd_hdac_ext_stream_release(struct hdac_ext_stream *azx_dev, int type);
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050090void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
Jeeja KPdf203a42015-06-11 14:11:49 +053091 struct hdac_ext_stream *azx_dev, bool decouple);
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050092void snd_hdac_ext_stop_streams(struct hdac_bus *bus);
Jeeja KPdf203a42015-06-11 14:11:49 +053093
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050094int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus,
Jeeja KPee8bc4d2015-08-21 21:36:20 +053095 struct hdac_ext_stream *stream, u32 value);
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050096int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus,
Jeeja KPee8bc4d2015-08-21 21:36:20 +053097 struct hdac_ext_stream *stream);
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -050098void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,
Jeeja KPa9c48f72015-12-18 15:11:59 +053099 bool enable, int index);
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -0500100int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus,
Jeeja KPa9c48f72015-12-18 15:11:59 +0530101 struct hdac_ext_stream *stream, u32 value);
102int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *stream, u32 value);
Jeeja KPee8bc4d2015-08-21 21:36:20 +0530103
Jeeja KPdf203a42015-06-11 14:11:49 +0530104void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *hstream);
105void snd_hdac_ext_link_stream_clear(struct hdac_ext_stream *hstream);
106void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hstream);
107int snd_hdac_ext_link_stream_setup(struct hdac_ext_stream *stream, int fmt);
108
Jeeja KP0b00a562015-06-11 14:11:48 +0530109struct hdac_ext_link {
110 struct hdac_bus *bus;
111 int index;
112 void __iomem *ml_addr; /* link output stream reg pointer */
113 u32 lcaps; /* link capablities */
114 u16 lsdiid; /* link sdi identifier */
Vinod Koul4446085d2016-05-12 08:58:53 +0530115
116 int ref_count;
117
Jeeja KP0b00a562015-06-11 14:11:48 +0530118 struct list_head list;
119};
120
121int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *link);
122int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link);
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -0500123int snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus);
124int snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus);
Jeeja KP0b00a562015-06-11 14:11:48 +0530125void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link,
126 int stream);
127void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
128 int stream);
129
Rakesh Ughreja76f56fa2018-06-01 22:53:50 -0500130int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link);
131int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link);
Vinod Koul4446085d2016-05-12 08:58:53 +0530132
Jeeja KP0b00a562015-06-11 14:11:48 +0530133/* update register macro */
134#define snd_hdac_updatel(addr, reg, mask, val) \
135 writel(((readl(addr + reg) & ~(mask)) | (val)), \
136 addr + reg)
137
Jeeja KPdf203a42015-06-11 14:11:49 +0530138#define snd_hdac_updatew(addr, reg, mask, val) \
139 writew(((readw(addr + reg) & ~(mask)) | (val)), \
140 addr + reg)
141
Vinod Koula512f562015-08-21 15:47:41 +0530142
143struct hdac_ext_device;
144
145/* ops common to all codec drivers */
146struct hdac_ext_codec_ops {
147 int (*build_controls)(struct hdac_ext_device *dev);
148 int (*init)(struct hdac_ext_device *dev);
149 void (*free)(struct hdac_ext_device *dev);
150};
151
152struct hda_dai_map {
153 char *dai_name;
154 hda_nid_t nid;
155 u32 maxbps;
156};
157
Subhransu S. Prusty1e83b042015-11-10 18:42:05 +0530158struct hdac_ext_dma_params {
159 u32 format;
160 u8 stream_tag;
161};
Rakesh Ughreja3787a392018-06-01 22:53:49 -0500162
Vinod Kould51783c2015-08-21 15:47:42 +0530163/*
164 * HD-audio codec base driver
165 */
166struct hdac_ext_driver {
167 struct hdac_driver hdac;
168
Rakesh Ughreja3787a392018-06-01 22:53:49 -0500169 int (*probe)(struct hdac_device *dev);
170 int (*remove)(struct hdac_device *dev);
171 void (*shutdown)(struct hdac_device *dev);
Vinod Kould51783c2015-08-21 15:47:42 +0530172};
173
174int snd_hda_ext_driver_register(struct hdac_ext_driver *drv);
175void snd_hda_ext_driver_unregister(struct hdac_ext_driver *drv);
176
177#define to_ehdac_driver(_drv) container_of(_drv, struct hdac_ext_driver, hdac)
Vinod Koula512f562015-08-21 15:47:41 +0530178
Jeeja KPdfe66a12015-06-11 14:11:47 +0530179#endif /* __SOUND_HDAUDIO_EXT_H */