1
linux/sound/core/isadma.c
Linus Torvalds 668c3c237f sound updates for 6.0-rc1
As diffstat shows, we've had lots of developments in a wide range
 at this time; the majority of changes are about ASoC, including
 subsystem-wide cleanups, continued SOF / Intel updates and a
 bunch of new drivers (as usual), while there have been some
 significant (but almost invisible) improvements in ALSA core
 side, too.  Below are some highlights:
 
 Core:
 - Faster lookups of control elements with Xarray; normal user
   won't notice, but on the devices with tons of control elements,
   it can be visibly faster
 - Support for input validation for controls; this will harden
   for badly written drivers in general with a slight overhead
 - Deferred async signal handling for working around the potential
   deadlocks
 - Cleanup / refactoring raw MIDI locking code
 
 ASoC:
 - Restructing of the set_fmt() callbacks for making things clearer
   in situations like CODEC to CODEC links
 - Clean up and modernizing the DAI naming scheme setups
 - Merge of more of the Intel AVS driver stack, including some
   board integrations
 - New version 4 mechanism for communication with SOF DSPs
 - Suppoort for dynamically selecting the PLL to use at runtime on
   i.MX platforms
 - Improvements for CODEC to CODEC support in the generic cards
 - Support for AMD Jadeite and various machines, AMD RPL, Intel
   MetorLake DSPs, Mediatek MT8186 DSPs and MT6366, nVidia Tegra
   MDDRC, OPE and PEQ, NXP TFA9890, Qualcomm SDM845, WCD9335 and
   WAS883x, and Texas Instruments TAS2780
 
 HD- and USB-audio:
 - Continued improvement for CS35L41 (sub)codec support
 - More quirks for various devices (HP, Lenovo, Dell, Clevo)
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmLr5bcOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE93IQ/+OleeiGv7C487QN5MrBCkdFnSAiXsXDArcMgo
 Gt6XLubH54et1tqi2ms4gRQOqr4HiBelERuqmaCLMZfEgVDc0VhJnf2jjhluYq9+
 o9+kcYKul6qTZeNZLPjEX8pBvDe7HzOl7yep++ZnKeH6DAKNQQLDjVuOcQU/BXdY
 kL8vYrLI3zfqj/pCePb5xpkBx4XdCrE3TfiCr3tAHVg9MyvSGOJyWs02mEBqQRnc
 rlLmkjQVQyln/AGK4RAPMmrrFytktAvBjmIDyFL7kAzhdxe0ouNzTvdxESeojNJv
 CVo/p3hl/+0LYjpD2x9v2pQuifOfpjwSCy6f8jsaF366sMwR1D45h051prILsxAF
 05D5AOwMCnnJdFQFxw3mIkoDva3/PRX8GFfHsXoz+efc5Ibp8ksNYVgAJ3D2TTtt
 7nAYMn0dimVDtw2LHiKantgWAs/rOqD3hDzGxFj2sR662ahsHr8pT8csnJAGoBvW
 7kgx7ZzFo/wSyZJqVqV7p4g6J79ScehRwhqoiwZau9Eo+PhuxZUKvm4RwGFh0Vvg
 GbiVRPfLV4xQd/pDin6qRX1M7cgPc62qGLkhQHAzrX6H5ipwIbQrpyDGLjwdSEp8
 XcQmzCG1zGOvb9A8BY1VBOQXxZRTqN58XujbZ6hsms7Uw8sqagxpYLA/e1bvt1E1
 RQoHQRw=
 =1n0/
 -----END PGP SIGNATURE-----

Merge tag 'sound-6.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound updates from Takashi Iwai:
 "As the diffstat shows, we've had lots of developments in a wide range
  at this time; the majority of changes are about ASoC, including
  subsystem-wide cleanups, continued SOF / Intel updates and a bunch of
  new drivers (as usual), while there have been some significant (but
  almost invisible) improvements in ALSA core side, too.

  Below are some highlights:

  Core:

   - Faster lookups of control elements with Xarray; normal user won't
     notice, but on the devices with tons of control elements, it can be
     visibly faster

   - Support for input validation for controls; this will harden for
     badly written drivers in general with a slight overhead

   - Deferred async signal handling for working around the potential
     deadlocks

   - Cleanup / refactoring raw MIDI locking code

  ASoC:

   - Restructing of the set_fmt() callbacks for making things clearer in
     situations like CODEC to CODEC links

   - Clean up and modernizing the DAI naming scheme setups

   - Merge of more of the Intel AVS driver stack, including some board
     integrations

   - New version 4 mechanism for communication with SOF DSPs

   - Suppoort for dynamically selecting the PLL to use at runtime on
     i.MX platforms

   - Improvements for CODEC to CODEC support in the generic cards

   - Support for AMD Jadeite and various machines, AMD RPL, Intel
     MetorLake DSPs, Mediatek MT8186 DSPs and MT6366, nVidia Tegra
     MDDRC, OPE and PEQ, NXP TFA9890, Qualcomm SDM845, WCD9335 and
     WAS883x, and Texas Instruments TAS2780

  HD- and USB-audio:

   - Continued improvement for CS35L41 (sub)codec support

   - More quirks for various devices (HP, Lenovo, Dell, Clevo)"

* tag 'sound-6.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (778 commits)
  ALSA: hda/realtek: Add quirk for HP Spectre x360 15-eb0xxx
  ALSA: line6: Replace sprintf() with sysfs_emit()
  ALSA: hda: Replace sprintf() with sysfs_emit()
  ALSA: pcm: Replace sprintf() with sysfs_emit()
  ALSA: core: Replace scnprintf() with sysfs_emit()
  ALSA: control-led: Replace sprintf() with sysfs_emit()
  ALSA: aoa: Replace sprintf() with sysfs_emit()
  ALSA: ac97: Replace sprintf() with sysfs_emit()
  ALSA: hda/realtek: Add quirk for Clevo NV45PZ
  ALSA: hda/realtek: Add quirk for Lenovo Yoga9 14IAP7
  ALSA: control: Use deferred fasync helper
  ALSA: pcm: Use deferred fasync helper
  ALSA: timer: Use deferred fasync helper
  ALSA: core: Add async signal helpers
  ASoC: q6asm: use kcalloc() instead of kzalloc()
  ACPI: scan: Add CLSA0101 Laptop Support
  ALSA: hda: cs35l41: Support CLSA0101
  ALSA: hda: cs35l41: Use the CS35L41 HDA internal define
  ASoC: dt-bindings: use spi-peripheral-props.yaml
  ASoC: codecs: va-macro: use fsgen as clock
  ...
2022-08-06 10:19:51 -07:00

139 lines
3.2 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* ISA DMA support functions
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*/
/*
* Defining following add some delay. Maybe this helps for some broken
* ISA DMA controllers.
*/
#undef HAVE_REALLY_SLOW_DMA_CONTROLLER
#include <linux/export.h>
#include <linux/isa-dma.h>
#include <sound/core.h>
/**
* snd_dma_program - program an ISA DMA transfer
* @dma: the dma number
* @addr: the physical address of the buffer
* @size: the DMA transfer size
* @mode: the DMA transfer mode, DMA_MODE_XXX
*
* Programs an ISA DMA transfer for the given buffer.
*/
void snd_dma_program(unsigned long dma,
unsigned long addr, unsigned int size,
unsigned short mode)
{
unsigned long flags;
flags = claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
set_dma_mode(dma, mode);
set_dma_addr(dma, addr);
set_dma_count(dma, size);
if (!(mode & DMA_MODE_NO_ENABLE))
enable_dma(dma);
release_dma_lock(flags);
}
EXPORT_SYMBOL(snd_dma_program);
/**
* snd_dma_disable - stop the ISA DMA transfer
* @dma: the dma number
*
* Stops the ISA DMA transfer.
*/
void snd_dma_disable(unsigned long dma)
{
unsigned long flags;
flags = claim_dma_lock();
clear_dma_ff(dma);
disable_dma(dma);
release_dma_lock(flags);
}
EXPORT_SYMBOL(snd_dma_disable);
/**
* snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes
* @dma: the dma number
* @size: the dma transfer size
*
* Return: The current pointer in DMA transfer buffer in bytes.
*/
unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
{
unsigned long flags;
unsigned int result, result1;
flags = claim_dma_lock();
clear_dma_ff(dma);
if (!isa_dma_bridge_buggy)
disable_dma(dma);
result = get_dma_residue(dma);
/*
* HACK - read the counter again and choose higher value in order to
* avoid reading during counter lower byte roll over if the
* isa_dma_bridge_buggy is set.
*/
result1 = get_dma_residue(dma);
if (!isa_dma_bridge_buggy)
enable_dma(dma);
release_dma_lock(flags);
if (unlikely(result < result1))
result = result1;
#ifdef CONFIG_SND_DEBUG
if (result > size)
pr_err("ALSA: pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
#endif
if (result >= size || result == 0)
return 0;
else
return size - result;
}
EXPORT_SYMBOL(snd_dma_pointer);
struct snd_dma_data {
int dma;
};
static void __snd_release_dma(struct device *dev, void *data)
{
struct snd_dma_data *p = data;
snd_dma_disable(p->dma);
free_dma(p->dma);
}
/**
* snd_devm_request_dma - the managed version of request_dma()
* @dev: the device pointer
* @dma: the dma number
* @name: the name string of the requester
*
* The requested DMA will be automatically released at unbinding via devres.
*
* Return: zero on success, or a negative error code
*/
int snd_devm_request_dma(struct device *dev, int dma, const char *name)
{
struct snd_dma_data *p;
if (request_dma(dma, name))
return -EBUSY;
p = devres_alloc(__snd_release_dma, sizeof(*p), GFP_KERNEL);
if (!p) {
free_dma(dma);
return -ENOMEM;
}
p->dma = dma;
devres_add(dev, p);
return 0;
}
EXPORT_SYMBOL_GPL(snd_devm_request_dma);