// SPDX-License-Identifier: GPL-2.0-only /* * HD-audio controller helpers */ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/export.h> #include <sound/core.h> #include <sound/hdaudio.h> #include <sound/hda_register.h> #include "local.h" /* clear CORB read pointer properly */ static void azx_clear_corbrp(struct hdac_bus *bus) { … } /** * snd_hdac_bus_init_cmd_io - set up CORB/RIRB buffers * @bus: HD-audio core bus */ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus) { … } EXPORT_SYMBOL_GPL(…); /* wait for cmd dmas till they are stopped */ static void hdac_wait_for_cmd_dmas(struct hdac_bus *bus) { … } /** * snd_hdac_bus_stop_cmd_io - clean up CORB/RIRB buffers * @bus: HD-audio core bus */ void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus) { … } EXPORT_SYMBOL_GPL(…); static unsigned int azx_command_addr(u32 cmd) { … } /* receive an Immediate Response with PIO */ static int snd_hdac_bus_wait_for_pio_response(struct hdac_bus *bus, unsigned int addr) { … } /** * snd_hdac_bus_send_cmd_pio - send a command verb via Immediate Command * @bus: HD-audio core bus * @val: encoded verb value to send * * Returns zero for success or a negative error code. */ static int snd_hdac_bus_send_cmd_pio(struct hdac_bus *bus, unsigned int val) { … } /** * snd_hdac_bus_get_response_pio - receive a response via Immediate Response * @bus: HD-audio core bus * @addr: codec address * @res: pointer to store the value, NULL when not needed * * Returns zero if a value is read, or a negative error code. */ static int snd_hdac_bus_get_response_pio(struct hdac_bus *bus, unsigned int addr, unsigned int *res) { … } /** * snd_hdac_bus_send_cmd_corb - send a command verb via CORB * @bus: HD-audio core bus * @val: encoded verb value to send * * Returns zero for success or a negative error code. */ static int snd_hdac_bus_send_cmd_corb(struct hdac_bus *bus, unsigned int val) { … } #define AZX_RIRB_EX_UNSOL_EV … /** * snd_hdac_bus_update_rirb - retrieve RIRB entries * @bus: HD-audio core bus * * Usually called from interrupt handler. * The caller needs bus->reg_lock spinlock before calling this. */ void snd_hdac_bus_update_rirb(struct hdac_bus *bus) { … } EXPORT_SYMBOL_GPL(…); /** * snd_hdac_bus_get_response_rirb - receive a response via RIRB * @bus: HD-audio core bus * @addr: codec address * @res: pointer to store the value, NULL when not needed * * Returns zero if a value is read, or a negative error code. */ static int snd_hdac_bus_get_response_rirb(struct hdac_bus *bus, unsigned int addr, unsigned int *res) { … } /** * snd_hdac_bus_send_cmd - send a command verb via CORB or PIO * @bus: HD-audio core bus * @val: encoded verb value to send * * Returns zero for success or a negative error code. */ int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val) { … } EXPORT_SYMBOL_GPL(…); /** * snd_hdac_bus_get_response - receive a response via RIRB or PIO * @bus: HD-audio core bus * @addr: codec address * @res: pointer to store the value, NULL when not needed * * Returns zero if a value is read, or a negative error code. */ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, unsigned int *res) { … } EXPORT_SYMBOL_GPL(…); #define HDAC_MAX_CAPS … /** * snd_hdac_bus_parse_capabilities - parse capability structure * @bus: the pointer to bus object * * Returns 0 if successful, or a negative error code. */ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus) { … } EXPORT_SYMBOL_GPL(…); /* * Lowlevel interface */ /** * snd_hdac_bus_enter_link_reset - enter link reset * @bus: HD-audio core bus * * Enter to the link reset state. */ void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus) { … } EXPORT_SYMBOL_GPL(…); /** * snd_hdac_bus_exit_link_reset - exit link reset * @bus: HD-audio core bus * * Exit from the link reset state. */ void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus) { … } EXPORT_SYMBOL_GPL(…); /* reset codec link */ int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset) { … } EXPORT_SYMBOL_GPL(…); /* enable interrupts */ static void azx_int_enable(struct hdac_bus *bus) { … } /* disable interrupts */ static void azx_int_disable(struct hdac_bus *bus) { … } /* clear interrupts */ static void azx_int_clear(struct hdac_bus *bus) { … } /** * snd_hdac_bus_init_chip - reset and start the controller registers * @bus: HD-audio core bus * @full_reset: Do full reset */ bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset) { … } EXPORT_SYMBOL_GPL(…); /** * snd_hdac_bus_stop_chip - disable the whole IRQ and I/Os * @bus: HD-audio core bus */ void snd_hdac_bus_stop_chip(struct hdac_bus *bus) { … } EXPORT_SYMBOL_GPL(…); /** * snd_hdac_bus_handle_stream_irq - interrupt handler for streams * @bus: HD-audio core bus * @status: INTSTS register value * @ack: callback to be called for woken streams * * Returns the bits of handled streams, or zero if no stream is handled. */ int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status, void (*ack)(struct hdac_bus *, struct hdac_stream *)) { … } EXPORT_SYMBOL_GPL(…); /** * snd_hdac_bus_alloc_stream_pages - allocate BDL and other buffers * @bus: HD-audio core bus * * Call this after assigning the all streams. * Returns zero for success, or a negative error code. */ int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus) { … } EXPORT_SYMBOL_GPL(…); /** * snd_hdac_bus_free_stream_pages - release BDL and other buffers * @bus: HD-audio core bus */ void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus) { … } EXPORT_SYMBOL_GPL(…); /** * snd_hdac_bus_link_power - power up/down codec link * @codec: HD-audio device * @enable: whether to power-up the link */ void snd_hdac_bus_link_power(struct hdac_device *codec, bool enable) { … } EXPORT_SYMBOL_GPL(…);