// SPDX-License-Identifier: GPL-2.0-or-later /* * Driver for Digigram VX soundcards * * Hardware core part * * Copyright (c) 2002 by Takashi Iwai <[email protected]> */ #include <linux/delay.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/device.h> #include <linux/firmware.h> #include <linux/module.h> #include <linux/io.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/asoundef.h> #include <sound/info.h> #include <sound/vx_core.h> #include "vx_cmd.h" MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; /* * vx_check_reg_bit - wait for the specified bit is set/reset on a register * @reg: register to check * @mask: bit mask * @bit: resultant bit to be checked * @time: time-out of loop in msec * * returns zero if a bit matches, or a negative error code. */ int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int time) { … } EXPORT_SYMBOL(…); /* * vx_send_irq_dsp - set command irq bit * @num: the requested IRQ type, IRQ_XXX * * this triggers the specified IRQ request * returns 0 if successful, or a negative error code. * */ static int vx_send_irq_dsp(struct vx_core *chip, int num) { … } /* * vx_reset_chk - reset CHK bit on ISR * * returns 0 if successful, or a negative error code. */ static int vx_reset_chk(struct vx_core *chip) { … } /* * vx_transfer_end - terminate message transfer * @cmd: IRQ message to send (IRQ_MESS_XXX_END) * * returns 0 if successful, or a negative error code. * the error code can be VX-specific, retrieved via vx_get_error(). * NB: call with mutex held! */ static int vx_transfer_end(struct vx_core *chip, int cmd) { … } /* * vx_read_status - return the status rmh * @rmh: rmh record to store the status * * returns 0 if successful, or a negative error code. * the error code can be VX-specific, retrieved via vx_get_error(). * NB: call with mutex held! */ static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh) { … } #define MASK_MORE_THAN_1_WORD_COMMAND … #define MASK_1_WORD_COMMAND … /* * vx_send_msg_nolock - send a DSP message and read back the status * @rmh: the rmh record to send and receive * * returns 0 if successful, or a negative error code. * the error code can be VX-specific, retrieved via vx_get_error(). * * this function doesn't call mutex lock at all. */ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh) { … } /* * vx_send_msg - send a DSP message with mutex * @rmh: the rmh record to send and receive * * returns 0 if successful, or a negative error code. * see vx_send_msg_nolock(). */ int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh) { … } /* * vx_send_rih_nolock - send an RIH to xilinx * @cmd: the command to send * * returns 0 if successful, or a negative error code. * the error code can be VX-specific, retrieved via vx_get_error(). * * this function doesn't call mutex at all. * * unlike RMH, no command is sent to DSP. */ int vx_send_rih_nolock(struct vx_core *chip, int cmd) { … } /* * vx_send_rih - send an RIH with mutex * @cmd: the command to send * * see vx_send_rih_nolock(). */ int vx_send_rih(struct vx_core *chip, int cmd) { … } #define END_OF_RESET_WAIT_TIME … /** * snd_vx_load_boot_image - boot up the xilinx interface * @chip: VX core instance * @boot: the boot record to load */ int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot) { … } EXPORT_SYMBOL(…); /* * vx_test_irq_src - query the source of interrupts * * called from irq handler only */ static int vx_test_irq_src(struct vx_core *chip, unsigned int *ret) { … } /* * snd_vx_threaded_irq_handler - threaded irq handler */ irqreturn_t snd_vx_threaded_irq_handler(int irq, void *dev) { … } EXPORT_SYMBOL(…); /** * snd_vx_irq_handler - interrupt handler * @irq: irq number * @dev: VX core instance */ irqreturn_t snd_vx_irq_handler(int irq, void *dev) { … } EXPORT_SYMBOL(…); /* */ static void vx_reset_board(struct vx_core *chip, int cold_reset) { … } /* * proc interface */ static void vx_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { … } static void vx_proc_init(struct vx_core *chip) { … } /** * snd_vx_dsp_boot - load the DSP boot * @chip: VX core instance * @boot: firmware data */ int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot) { … } EXPORT_SYMBOL(…); /** * snd_vx_dsp_load - load the DSP image * @chip: VX core instance * @dsp: firmware data */ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp) { … } EXPORT_SYMBOL(…); #ifdef CONFIG_PM /* * suspend */ int snd_vx_suspend(struct vx_core *chip) { … } EXPORT_SYMBOL(…); /* * resume */ int snd_vx_resume(struct vx_core *chip) { … } EXPORT_SYMBOL(…); #endif static void snd_vx_release(struct device *dev, void *data) { … } /** * snd_vx_create - constructor for struct vx_core * @card: card instance * @hw: hardware specific record * @ops: VX ops pointer * @extra_size: extra byte size to allocate appending to chip * * this function allocates the instance and prepare for the hardware * initialization. * * The object is managed via devres, and will be automatically released. * * return the instance pointer if successful, NULL in error. */ struct vx_core *snd_vx_create(struct snd_card *card, const struct snd_vx_hardware *hw, const struct snd_vx_ops *ops, int extra_size) { … } EXPORT_SYMBOL(…);