linux/include/sound/hdaudio_ext.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __SOUND_HDAUDIO_EXT_H
   3#define __SOUND_HDAUDIO_EXT_H
   4
   5#include <linux/io-64-nonatomic-lo-hi.h>
   6#include <linux/iopoll.h>
   7#include <sound/hdaudio.h>
   8
   9int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
  10                      const struct hdac_bus_ops *ops,
  11                      const struct hdac_ext_bus_ops *ext_ops);
  12
  13void snd_hdac_ext_bus_exit(struct hdac_bus *bus);
  14int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr,
  15                                struct hdac_device *hdev, int type);
  16void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev);
  17void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus);
  18
  19#define HDA_CODEC_REV_EXT_ENTRY(_vid, _rev, _name, drv_data) \
  20        { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
  21          .api_version = HDA_DEV_ASOC, \
  22          .driver_data = (unsigned long)(drv_data) }
  23#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
  24        HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
  25
  26void snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *chip, bool enable);
  27void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *chip, bool enable);
  28
  29void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *chip,
  30                                 bool enable, int index);
  31
  32int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus);
  33struct hdac_ext_link *snd_hdac_ext_bus_link_at(struct hdac_bus *bus, int addr);
  34struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus,
  35                                                const char *codec_name);
  36
  37enum hdac_ext_stream_type {
  38        HDAC_EXT_STREAM_TYPE_COUPLED = 0,
  39        HDAC_EXT_STREAM_TYPE_HOST,
  40        HDAC_EXT_STREAM_TYPE_LINK
  41};
  42
  43/**
  44 * hdac_ext_stream: HDAC extended stream for extended HDA caps
  45 *
  46 * @hstream: hdac_stream
  47 * @pphc_addr: processing pipe host stream pointer
  48 * @pplc_addr: processing pipe link stream pointer
  49 * @spib_addr: software position in buffers stream pointer
  50 * @fifo_addr: software position Max fifos stream pointer
  51 * @dpibr_addr: DMA position in buffer resume pointer
  52 * @dpib: DMA position in buffer
  53 * @lpib: Linear position in buffer
  54 * @decoupled: stream host and link is decoupled
  55 * @link_locked: link is locked
  56 * @link_prepared: link is prepared
  57 * @link_substream: link substream
  58 */
  59struct hdac_ext_stream {
  60        struct hdac_stream hstream;
  61
  62        void __iomem *pphc_addr;
  63        void __iomem *pplc_addr;
  64
  65        void __iomem *spib_addr;
  66        void __iomem *fifo_addr;
  67
  68        void __iomem *dpibr_addr;
  69
  70        u32 dpib;
  71        u32 lpib;
  72        bool decoupled:1;
  73        bool link_locked:1;
  74        bool link_prepared;
  75
  76        struct snd_pcm_substream *link_substream;
  77};
  78
  79#define hdac_stream(s)          (&(s)->hstream)
  80#define stream_to_hdac_ext_stream(s) \
  81        container_of(s, struct hdac_ext_stream, hstream)
  82
  83void snd_hdac_ext_stream_init(struct hdac_bus *bus,
  84                              struct hdac_ext_stream *hext_stream, int idx,
  85                              int direction, int tag);
  86int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
  87                                 int num_stream, int dir);
  88void snd_hdac_stream_free_all(struct hdac_bus *bus);
  89void snd_hdac_link_free_all(struct hdac_bus *bus);
  90struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus,
  91                                           struct snd_pcm_substream *substream,
  92                                           int type);
  93void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type);
  94void snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus,
  95                                         struct hdac_ext_stream *hext_stream, bool decouple);
  96void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
  97                                struct hdac_ext_stream *azx_dev, bool decouple);
  98
  99int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus,
 100                                 struct hdac_ext_stream *hext_stream, u32 value);
 101int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus,
 102                                       struct hdac_ext_stream *hext_stream);
 103void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,
 104                                bool enable, int index);
 105int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus,
 106                                struct hdac_ext_stream *hext_stream, u32 value);
 107int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *hext_stream, u32 value);
 108
 109void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *hext_stream);
 110void snd_hdac_ext_link_stream_clear(struct hdac_ext_stream *hext_stream);
 111void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hext_stream);
 112int snd_hdac_ext_link_stream_setup(struct hdac_ext_stream *hext_stream, int fmt);
 113
 114struct hdac_ext_link {
 115        struct hdac_bus *bus;
 116        int index;
 117        void __iomem *ml_addr; /* link output stream reg pointer */
 118        u32 lcaps;   /* link capablities */
 119        u16 lsdiid;  /* link sdi identifier */
 120
 121        int ref_count;
 122
 123        struct list_head list;
 124};
 125
 126int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *link);
 127int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link);
 128int snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus);
 129int snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus);
 130void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link,
 131                                 int stream);
 132void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
 133                                 int stream);
 134
 135int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link);
 136int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link);
 137
 138void snd_hdac_ext_bus_link_power(struct hdac_device *codec, bool enable);
 139
 140/* update register macro */
 141#define snd_hdac_updatel(addr, reg, mask, val)          \
 142        writel(((readl(addr + reg) & ~(mask)) | (val)), \
 143                addr + reg)
 144
 145#define snd_hdac_updatew(addr, reg, mask, val)          \
 146        writew(((readw(addr + reg) & ~(mask)) | (val)), \
 147                addr + reg)
 148
 149#define snd_hdac_adsp_writeb(chip, reg, value) \
 150        snd_hdac_reg_writeb(chip, (chip)->dsp_ba + (reg), value)
 151#define snd_hdac_adsp_readb(chip, reg) \
 152        snd_hdac_reg_readb(chip, (chip)->dsp_ba + (reg))
 153#define snd_hdac_adsp_writew(chip, reg, value) \
 154        snd_hdac_reg_writew(chip, (chip)->dsp_ba + (reg), value)
 155#define snd_hdac_adsp_readw(chip, reg) \
 156        snd_hdac_reg_readw(chip, (chip)->dsp_ba + (reg))
 157#define snd_hdac_adsp_writel(chip, reg, value) \
 158        snd_hdac_reg_writel(chip, (chip)->dsp_ba + (reg), value)
 159#define snd_hdac_adsp_readl(chip, reg) \
 160        snd_hdac_reg_readl(chip, (chip)->dsp_ba + (reg))
 161#define snd_hdac_adsp_writeq(chip, reg, value) \
 162        snd_hdac_reg_writeq(chip, (chip)->dsp_ba + (reg), value)
 163#define snd_hdac_adsp_readq(chip, reg) \
 164        snd_hdac_reg_readq(chip, (chip)->dsp_ba + (reg))
 165
 166#define snd_hdac_adsp_updateb(chip, reg, mask, val) \
 167        snd_hdac_adsp_writeb(chip, reg, \
 168                        (snd_hdac_adsp_readb(chip, reg) & ~(mask)) | (val))
 169#define snd_hdac_adsp_updatew(chip, reg, mask, val) \
 170        snd_hdac_adsp_writew(chip, reg, \
 171                        (snd_hdac_adsp_readw(chip, reg) & ~(mask)) | (val))
 172#define snd_hdac_adsp_updatel(chip, reg, mask, val) \
 173        snd_hdac_adsp_writel(chip, reg, \
 174                        (snd_hdac_adsp_readl(chip, reg) & ~(mask)) | (val))
 175#define snd_hdac_adsp_updateq(chip, reg, mask, val) \
 176        snd_hdac_adsp_writeq(chip, reg, \
 177                        (snd_hdac_adsp_readq(chip, reg) & ~(mask)) | (val))
 178
 179#define snd_hdac_adsp_readb_poll(chip, reg, val, cond, delay_us, timeout_us) \
 180        readb_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
 181                           delay_us, timeout_us)
 182#define snd_hdac_adsp_readw_poll(chip, reg, val, cond, delay_us, timeout_us) \
 183        readw_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
 184                           delay_us, timeout_us)
 185#define snd_hdac_adsp_readl_poll(chip, reg, val, cond, delay_us, timeout_us) \
 186        readl_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
 187                           delay_us, timeout_us)
 188#define snd_hdac_adsp_readq_poll(chip, reg, val, cond, delay_us, timeout_us) \
 189        readq_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
 190                           delay_us, timeout_us)
 191#define snd_hdac_stream_readb_poll(strm, reg, val, cond, delay_us, timeout_us) \
 192        readb_poll_timeout((strm)->sd_addr + AZX_REG_ ## reg, val, cond, \
 193                           delay_us, timeout_us)
 194#define snd_hdac_stream_readl_poll(strm, reg, val, cond, delay_us, timeout_us) \
 195        readl_poll_timeout((strm)->sd_addr + AZX_REG_ ## reg, val, cond, \
 196                           delay_us, timeout_us)
 197
 198struct hdac_ext_device;
 199
 200/* ops common to all codec drivers */
 201struct hdac_ext_codec_ops {
 202        int (*build_controls)(struct hdac_ext_device *dev);
 203        int (*init)(struct hdac_ext_device *dev);
 204        void (*free)(struct hdac_ext_device *dev);
 205};
 206
 207struct hda_dai_map {
 208        char *dai_name;
 209        hda_nid_t nid;
 210        u32     maxbps;
 211};
 212
 213struct hdac_ext_dma_params {
 214        u32 format;
 215        u8 stream_tag;
 216};
 217
 218int snd_hda_ext_driver_register(struct hdac_driver *drv);
 219void snd_hda_ext_driver_unregister(struct hdac_driver *drv);
 220
 221#endif /* __SOUND_HDAUDIO_EXT_H */
 222