^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __SOUND_HDAUDIO_EXT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __SOUND_HDAUDIO_EXT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <sound/hdaudio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) const struct hdac_bus_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) const struct hdac_ext_bus_ops *ext_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) void snd_hdac_ext_bus_exit(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct hdac_device *hdev, int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define HDA_CODEC_REV_EXT_ENTRY(_vid, _rev, _name, drv_data) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) .api_version = HDA_DEV_ASOC, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) .driver_data = (unsigned long)(drv_data) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) void snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *chip, bool enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *chip, bool enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) bool enable, int index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) const char *codec_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) enum hdac_ext_stream_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) HDAC_EXT_STREAM_TYPE_COUPLED = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) HDAC_EXT_STREAM_TYPE_HOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) HDAC_EXT_STREAM_TYPE_LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * hdac_ext_stream: HDAC extended stream for extended HDA caps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @hstream: hdac_stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @pphc_addr: processing pipe host stream pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @pplc_addr: processing pipe link stream pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @spib_addr: software position in buffers stream pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @fifo_addr: software position Max fifos stream pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @dpibr_addr: DMA position in buffer resume pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @dpib: DMA position in buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * @lpib: Linear position in buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * @decoupled: stream host and link is decoupled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * @link_locked: link is locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @link_prepared: link is prepared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * link_substream: link substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct hdac_ext_stream {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct hdac_stream hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) void __iomem *pphc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) void __iomem *pplc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) void __iomem *spib_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) void __iomem *fifo_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) void __iomem *dpibr_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u32 dpib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u32 lpib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) bool decoupled:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bool link_locked:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) bool link_prepared;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct snd_pcm_substream *link_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define hdac_stream(s) (&(s)->hstream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define stream_to_hdac_ext_stream(s) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) container_of(s, struct hdac_ext_stream, hstream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) void snd_hdac_ext_stream_init(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct hdac_ext_stream *stream, int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int direction, int tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int num_stream, int dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) void snd_hdac_stream_free_all(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) void snd_hdac_link_free_all(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) void snd_hdac_ext_stream_release(struct hdac_ext_stream *azx_dev, int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) void snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct hdac_ext_stream *azx_dev, bool decouple);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct hdac_ext_stream *azx_dev, bool decouple);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) void snd_hdac_ext_stop_streams(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct hdac_ext_stream *stream, u32 value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct hdac_ext_stream *stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) bool enable, int index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct hdac_ext_stream *stream, u32 value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *stream, u32 value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) void snd_hdac_ext_link_stream_clear(struct hdac_ext_stream *hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int snd_hdac_ext_link_stream_setup(struct hdac_ext_stream *stream, int fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct hdac_ext_link {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct hdac_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void __iomem *ml_addr; /* link output stream reg pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u32 lcaps; /* link capablities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u16 lsdiid; /* link sdi identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* update register macro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define snd_hdac_updatel(addr, reg, mask, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) writel(((readl(addr + reg) & ~(mask)) | (val)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) addr + reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define snd_hdac_updatew(addr, reg, mask, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) writew(((readw(addr + reg) & ~(mask)) | (val)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) addr + reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct hdac_ext_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* ops common to all codec drivers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct hdac_ext_codec_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int (*build_controls)(struct hdac_ext_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int (*init)(struct hdac_ext_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) void (*free)(struct hdac_ext_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct hda_dai_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) char *dai_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) u32 maxbps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct hdac_ext_dma_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u32 format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u8 stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int snd_hda_ext_driver_register(struct hdac_driver *drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) void snd_hda_ext_driver_unregister(struct hdac_driver *drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #endif /* __SOUND_HDAUDIO_EXT_H */