^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * HD-audio core stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #ifndef __SOUND_HDAUDIO_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define __SOUND_HDAUDIO_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/timecounter.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sound/memalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sound/hda_verbs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <drm/i915_component.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* codec node id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) typedef u16 hda_nid_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct hdac_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct hdac_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct hdac_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct hdac_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct hdac_widget_tree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct hda_device_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * exported bus type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) extern struct bus_type snd_hda_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * generic arrays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct snd_array {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned int used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) unsigned int alloced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned int elem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned int alloc_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * HD-audio codec base device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct hdac_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct device dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct hdac_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned int addr; /* codec address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct list_head list; /* list point for bus codec_list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) hda_nid_t afg; /* AFG node id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) hda_nid_t mfg; /* MFG node id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* ids */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int vendor_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned int subsystem_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned int revision_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned int afg_function_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned int mfg_function_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned int afg_unsol:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned int mfg_unsol:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned int power_caps; /* FG power caps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) const char *vendor_name; /* codec vendor name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) const char *chip_name; /* codec chip name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* verb exec op override */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int (*exec_verb)(struct hdac_device *dev, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) unsigned int flags, unsigned int *res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* widgets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned int num_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) hda_nid_t start_nid, end_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* misc flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) atomic_t in_pm; /* suspend/resume being performed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* sysfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct mutex widget_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct hdac_widget_tree *widgets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* regmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct mutex regmap_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct snd_array vendor_verbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) bool lazy_cache:1; /* don't wake up for writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) bool caps_overwriting:1; /* caps overwrite being in process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) bool cache_coef:1; /* cache COEF read/write too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* device/driver type used for matching */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) HDA_DEV_CORE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) HDA_DEV_LEGACY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) HDA_DEV_ASOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) SND_SKL_PCI_BIND_AUTO, /* automatic selection based on pci class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) SND_SKL_PCI_BIND_LEGACY,/* bind only with legacy driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) SND_SKL_PCI_BIND_ASOC /* bind only with ASoC driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) HDA_INPUT, HDA_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define dev_to_hdac_dev(_dev) container_of(_dev, struct hdac_device, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) const char *name, unsigned int addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) void snd_hdac_device_exit(struct hdac_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int snd_hdac_device_register(struct hdac_device *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) void snd_hdac_device_unregister(struct hdac_device *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int snd_hdac_codec_modalias(struct hdac_device *hdac, char *buf, size_t size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int snd_hdac_refresh_widgets(struct hdac_device *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int verb, unsigned int parm, unsigned int *res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int _snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned int *res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int parm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int snd_hdac_override_parm(struct hdac_device *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned int parm, unsigned int val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) hda_nid_t *conn_list, int max_conns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) hda_nid_t *start_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned int snd_hdac_calc_stream_format(unsigned int rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned int channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) snd_pcm_format_t format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned int maxbps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) unsigned short spdif_ctls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned int format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int snd_hdac_codec_read(struct hdac_device *hdac, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int flags, unsigned int verb, unsigned int parm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int flags, unsigned int verb, unsigned int parm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) bool snd_hdac_check_power_state(struct hdac_device *hdac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) hda_nid_t nid, unsigned int target_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned int snd_hdac_sync_power_state(struct hdac_device *hdac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) hda_nid_t nid, unsigned int target_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * snd_hdac_read_parm - read a codec parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * @codec: the codec object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * @nid: NID to read a parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * @parm: parameter to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Returns -1 for error. If you need to distinguish the error more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * strictly, use _snd_hdac_read_parm() directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static inline int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int parm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return _snd_hdac_read_parm(codec, nid, parm, &val) < 0 ? -1 : val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int snd_hdac_power_up(struct hdac_device *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int snd_hdac_power_down(struct hdac_device *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int snd_hdac_power_up_pm(struct hdac_device *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int snd_hdac_power_down_pm(struct hdac_device *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int snd_hdac_keep_power_up(struct hdac_device *codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* call this at entering into suspend/resume callbacks in codec driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static inline void snd_hdac_enter_pm(struct hdac_device *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) atomic_inc(&codec->in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* call this at leaving from suspend/resume callbacks in codec driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static inline void snd_hdac_leave_pm(struct hdac_device *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) atomic_dec(&codec->in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static inline bool snd_hdac_is_in_pm(struct hdac_device *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return atomic_read(&codec->in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static inline bool snd_hdac_is_power_on(struct hdac_device *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return !pm_runtime_suspended(&codec->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static inline int snd_hdac_keep_power_up(struct hdac_device *codec) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static inline void snd_hdac_enter_pm(struct hdac_device *codec) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static inline void snd_hdac_leave_pm(struct hdac_device *codec) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static inline bool snd_hdac_is_in_pm(struct hdac_device *codec) { return false; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static inline bool snd_hdac_is_power_on(struct hdac_device *codec) { return true; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * HD-audio codec base driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct hdac_driver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct device_driver driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) const struct hda_device_id *id_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) void (*unsol_event)(struct hdac_device *dev, unsigned int event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* fields used by ext bus APIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int (*probe)(struct hdac_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int (*remove)(struct hdac_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) void (*shutdown)(struct hdac_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) const struct hda_device_id *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) hdac_get_device_id(struct hdac_device *hdev, struct hdac_driver *drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Bus verb operators
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct hdac_bus_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* send a single command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int (*command)(struct hdac_bus *bus, unsigned int cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* get a response from the last command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int (*get_response)(struct hdac_bus *bus, unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) unsigned int *res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * ops used for ASoC HDA codec drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct hdac_ext_bus_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int (*hdev_attach)(struct hdac_device *hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int (*hdev_detach)(struct hdac_device *hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define HDA_UNSOL_QUEUE_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #define HDA_MAX_CODECS 8 /* limit by controller side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * CORB/RIRB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * Each CORB entry is 4byte, RIRB is 8byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct hdac_rb {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) __le32 *buf; /* virtual address of CORB/RIRB buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dma_addr_t addr; /* physical address of CORB/RIRB buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned short rp, wp; /* RIRB read/write pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int cmds[HDA_MAX_CODECS]; /* number of pending requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u32 res[HDA_MAX_CODECS]; /* last read value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * HD-audio bus base driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * @ppcap: pp capabilities pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * @spbcap: SPIB capabilities pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * @mlcap: MultiLink capabilities pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * @gtscap: gts capabilities pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * @drsmcap: dma resume capabilities pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * @num_streams: streams supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * @idx: HDA link index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * @hlink_list: link list of HDA links
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * @lock: lock for link and display power mgmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * @cmd_dma_state: state of cmd DMAs: CORB and RIRB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct hdac_bus {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) const struct hdac_bus_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) const struct hdac_ext_bus_ops *ext_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* h/w resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) void __iomem *remap_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) void __iomem *ppcap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) void __iomem *spbcap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) void __iomem *mlcap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) void __iomem *gtscap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) void __iomem *drsmcap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* codec linked list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct list_head codec_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) unsigned int num_codecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* link caddr -> codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct hdac_device *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* unsolicited event queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) u32 unsol_queue[HDA_UNSOL_QUEUE_SIZE * 2]; /* ring buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) unsigned int unsol_rp, unsol_wp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct work_struct unsol_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* bit flags of detected codecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) unsigned long codec_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* bit flags of powered codecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned long codec_powered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* CORB/RIRB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct hdac_rb corb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct hdac_rb rirb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unsigned int last_cmd[HDA_MAX_CODECS]; /* last sent command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) wait_queue_head_t rirb_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* CORB/RIRB and position buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct snd_dma_buffer rb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct snd_dma_buffer posbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int dma_type; /* SNDRV_DMA_TYPE_XXX for CORB/RIRB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* hdac_stream linked list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct list_head stream_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* operation state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) bool chip_init:1; /* h/w initialized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* behavior flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) bool aligned_mmio:1; /* aligned MMIO access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) bool sync_write:1; /* sync after verb write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) bool use_posbuf:1; /* use position buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) bool snoop:1; /* enable snooping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) bool align_bdle_4k:1; /* BDLE align 4K boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) bool reverse_assign:1; /* assign devices in reverse order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) bool corbrp_self_clear:1; /* CORBRP clears itself after reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) bool polling_mode:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) bool needs_damn_long_delay:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int poll_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int bdl_pos_adj; /* BDL position adjustment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* delay time in us for dma stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned int dma_stop_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* locks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) spinlock_t reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct mutex cmd_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* DRM component interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct drm_audio_component *audio_component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) long display_power_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) unsigned long display_power_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* parameters required for enhanced capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) int num_streams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* link management */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct list_head hlink_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) bool cmd_dma_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* factor used to derive STRIPE control value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned int sdo_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) const struct hdac_bus_ops *ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) void snd_hdac_bus_exit(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) unsigned int cmd, unsigned int *res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) set_bit(codec->addr, &codec->bus->codec_powered);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) clear_bit(codec->addr, &codec->bus->codec_powered);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) unsigned int *res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) void snd_hdac_bus_stop_chip(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) void snd_hdac_bus_update_rirb(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) void (*ack)(struct hdac_bus *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct hdac_stream *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #ifdef CONFIG_SND_HDA_ALIGNED_MMIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) unsigned int snd_hdac_aligned_read(void __iomem *addr, unsigned int mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) void snd_hdac_aligned_write(unsigned int val, void __iomem *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) unsigned int mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #define snd_hdac_aligned_mmio(bus) (bus)->aligned_mmio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #define snd_hdac_aligned_mmio(bus) false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) #define snd_hdac_aligned_read(addr, mask) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) #define snd_hdac_aligned_write(val, addr, mask) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static inline void snd_hdac_reg_writeb(struct hdac_bus *bus, void __iomem *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (snd_hdac_aligned_mmio(bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) snd_hdac_aligned_write(val, addr, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) writeb(val, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static inline void snd_hdac_reg_writew(struct hdac_bus *bus, void __iomem *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (snd_hdac_aligned_mmio(bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) snd_hdac_aligned_write(val, addr, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) writew(val, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static inline u8 snd_hdac_reg_readb(struct hdac_bus *bus, void __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return snd_hdac_aligned_mmio(bus) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) snd_hdac_aligned_read(addr, 0xff) : readb(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static inline u16 snd_hdac_reg_readw(struct hdac_bus *bus, void __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return snd_hdac_aligned_mmio(bus) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) snd_hdac_aligned_read(addr, 0xffff) : readw(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) #define snd_hdac_reg_writel(bus, addr, val) writel(val, addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) #define snd_hdac_reg_readl(bus, addr) readl(addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * macros for easy use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) #define _snd_hdac_chip_writeb(chip, reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) snd_hdac_reg_writeb(chip, (chip)->remap_addr + (reg), value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #define _snd_hdac_chip_readb(chip, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) snd_hdac_reg_readb(chip, (chip)->remap_addr + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) #define _snd_hdac_chip_writew(chip, reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) snd_hdac_reg_writew(chip, (chip)->remap_addr + (reg), value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) #define _snd_hdac_chip_readw(chip, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) snd_hdac_reg_readw(chip, (chip)->remap_addr + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) #define _snd_hdac_chip_writel(chip, reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) snd_hdac_reg_writel(chip, (chip)->remap_addr + (reg), value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) #define _snd_hdac_chip_readl(chip, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) snd_hdac_reg_readl(chip, (chip)->remap_addr + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* read/write a register, pass without AZX_REG_ prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) #define snd_hdac_chip_writel(chip, reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) _snd_hdac_chip_writel(chip, AZX_REG_ ## reg, value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) #define snd_hdac_chip_writew(chip, reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) _snd_hdac_chip_writew(chip, AZX_REG_ ## reg, value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #define snd_hdac_chip_writeb(chip, reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) _snd_hdac_chip_writeb(chip, AZX_REG_ ## reg, value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) #define snd_hdac_chip_readl(chip, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) _snd_hdac_chip_readl(chip, AZX_REG_ ## reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) #define snd_hdac_chip_readw(chip, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) _snd_hdac_chip_readw(chip, AZX_REG_ ## reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #define snd_hdac_chip_readb(chip, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) _snd_hdac_chip_readb(chip, AZX_REG_ ## reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* update a register, pass without AZX_REG_ prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #define snd_hdac_chip_updatel(chip, reg, mask, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) snd_hdac_chip_writel(chip, reg, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) (snd_hdac_chip_readl(chip, reg) & ~(mask)) | (val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) #define snd_hdac_chip_updatew(chip, reg, mask, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) snd_hdac_chip_writew(chip, reg, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) (snd_hdac_chip_readw(chip, reg) & ~(mask)) | (val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) #define snd_hdac_chip_updateb(chip, reg, mask, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) snd_hdac_chip_writeb(chip, reg, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) (snd_hdac_chip_readb(chip, reg) & ~(mask)) | (val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * HD-audio stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct hdac_stream {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct hdac_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct snd_dma_buffer bdl; /* BDL buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) __le32 *posbuf; /* position buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int direction; /* playback / capture (SNDRV_PCM_STREAM_*) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) unsigned int bufsize; /* size of the play buffer in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned int period_bytes; /* size of the period in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) unsigned int frags; /* number for period in the play buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) unsigned int fifo_size; /* FIFO size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) void __iomem *sd_addr; /* stream descriptor pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) u32 sd_int_sta_mask; /* stream int status mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* pcm support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct snd_pcm_substream *substream; /* assigned substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * set in PCM open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct snd_compr_stream *cstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) unsigned int format_val; /* format value to be set in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * controller and the codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) unsigned char stream_tag; /* assigned stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) unsigned char index; /* stream index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int assigned_key; /* last device# key assigned to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) bool opened:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) bool running:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) bool prepared:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) bool no_period_wakeup:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) bool locked:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) bool stripe:1; /* apply stripe control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) u64 curr_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* timestamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) unsigned long start_wallclk; /* start + minimum wallclk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) unsigned long period_wallclk; /* wallclk for period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct timecounter tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct cyclecounter cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) int delay_negative_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) #ifdef CONFIG_SND_HDA_DSP_LOADER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* DSP access mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct mutex dsp_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) void snd_hdac_stream_init(struct hdac_bus *bus, struct hdac_stream *azx_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int idx, int direction, int tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct snd_pcm_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) void snd_hdac_stream_release(struct hdac_stream *azx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct hdac_stream *snd_hdac_get_stream(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) int dir, int stream_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int snd_hdac_stream_setup(struct hdac_stream *azx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) void snd_hdac_stream_cleanup(struct hdac_stream *azx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) unsigned int format_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) void snd_hdac_stream_clear(struct hdac_stream *azx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) void snd_hdac_stream_stop(struct hdac_stream *azx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) void snd_hdac_stream_reset(struct hdac_stream *azx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) unsigned int streams, unsigned int reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) unsigned int streams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) unsigned int streams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct snd_pcm_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * macros for easy use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /* read/write a register, pass without AZX_REG_ prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) #define snd_hdac_stream_writel(dev, reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) snd_hdac_reg_writel((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) #define snd_hdac_stream_writew(dev, reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) snd_hdac_reg_writew((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) #define snd_hdac_stream_writeb(dev, reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) snd_hdac_reg_writeb((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) #define snd_hdac_stream_readl(dev, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) snd_hdac_reg_readl((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) #define snd_hdac_stream_readw(dev, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) snd_hdac_reg_readw((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #define snd_hdac_stream_readb(dev, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) snd_hdac_reg_readb((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* update a register, pass without AZX_REG_ prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) #define snd_hdac_stream_updatel(dev, reg, mask, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) snd_hdac_stream_writel(dev, reg, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) (snd_hdac_stream_readl(dev, reg) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ~(mask)) | (val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) #define snd_hdac_stream_updatew(dev, reg, mask, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) snd_hdac_stream_writew(dev, reg, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) (snd_hdac_stream_readw(dev, reg) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ~(mask)) | (val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) #define snd_hdac_stream_updateb(dev, reg, mask, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) snd_hdac_stream_writeb(dev, reg, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) (snd_hdac_stream_readb(dev, reg) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ~(mask)) | (val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #ifdef CONFIG_SND_HDA_DSP_LOADER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* DSP lock helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #define snd_hdac_dsp_lock_init(dev) mutex_init(&(dev)->dsp_mutex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) #define snd_hdac_dsp_lock(dev) mutex_lock(&(dev)->dsp_mutex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) #define snd_hdac_dsp_unlock(dev) mutex_unlock(&(dev)->dsp_mutex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #define snd_hdac_stream_is_locked(dev) ((dev)->locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* DSP loader helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) unsigned int byte_size, struct snd_dma_buffer *bufp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct snd_dma_buffer *dmab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) #else /* CONFIG_SND_HDA_DSP_LOADER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) #define snd_hdac_dsp_lock_init(dev) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #define snd_hdac_dsp_lock(dev) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) #define snd_hdac_dsp_unlock(dev) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) #define snd_hdac_stream_is_locked(dev) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) unsigned int byte_size, struct snd_dma_buffer *bufp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static inline void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static inline void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct snd_dma_buffer *dmab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #endif /* CONFIG_SND_HDA_DSP_LOADER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * generic array helpers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) void *snd_array_new(struct snd_array *array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) void snd_array_free(struct snd_array *array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static inline void snd_array_init(struct snd_array *array, unsigned int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) unsigned int align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) array->elem_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) array->alloc_align = align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static inline void *snd_array_elem(struct snd_array *array, unsigned int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return array->list + idx * array->elem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return (unsigned long)(ptr - array->list) / array->elem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* a helper macro to iterate for each snd_array element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) #define snd_array_for_each(array, idx, ptr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) for ((idx) = 0, (ptr) = (array)->list; (idx) < (array)->used; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) (ptr) = snd_array_elem(array, ++(idx)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #endif /* __SOUND_HDAUDIO_H */