mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
920f2ecdf6
This development cycle resulted in a fair amount of changes in both core and driver sides. The most significant change in ALSA core is about PCM. Also the support of of-graph card and the new DAPM widget for DSP are noteworthy changes in ASoC core. And there're lots of small changes splat over the tree, as you can see in diffstat. Below are a few highlights: ALSA core: - Removal of set_fs() hackery from PCM core stuff, and the code reorganization / optimization thereafter - Improved support of PCM ack ops, and a new ABI for improved control/status mmap handling - Lots of constifications in various codes ASoC core: - The support of of-graph card, which may work as a better generic device for a replacement of simple-card - New widget types intended mainly for use with DSPs ASoC drivers: - New drivers for Allwinner V3s SoCs - Ensonic ES8316 codec support - More Intel SKL and KBL works - More device support for Intel SST Atom (mostly for cheap tablets and 2-in-1 devices) - Support for Rockchip PDM controllers - Support for STM32 I2S and S/PDIF controllers - Support for ZTE AUD96P22 codecs HD-audio: - Support of new Realtek codecs (ALC215/ALC285/ALC289), more quirks for HP and Dell machines - A few more fixes for i915 component binding Note that of-graph change may bring the conflicts with a later pull request of devicetree, as currently found in linux-next. -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEECxfAB4MH3rD5mfB6bDGAVD0pKaQFAllbtmMOHHRpd2FpQHN1 c2UuZGUACgkQbDGAVD0pKaTMkhAAnqvRvh9nYBI1E2VGtJON/AFcsF4s6xdJd0ow Bn5Kq/07rGWxAi8Cy69LM930eQrZl+xR69I7LMkC54BxVNhvhXNef7E5GXPbRi+3 l6dkBmkqvwmmHP5iiOxKtYSAnUfJitu1rmtAOVAjRh8rsWNeLuI8N8V/uilQBioi lRywdBjdylub00H1DL8cmZHbrBb4pYrL/LepTswZL3I/UZ225fMiIGFd8tXpQPwZ IKRZiuzrc3SykxSsL/aNeyxP+2qTYRtPfl/FGenKBBO2PJmGAb00yAdtQJRcD2eX Xf1alfvpNgpy/U6+C7dJgNWQvvr+lPCaFXuMukIDno/zg/xD1V1Ev/fnbVEINLve xMOnuJSGGaY6fu6eZ4Cck0VfZIj7UVA9x8zvBOKntIhq/VLfE7DDu3p9tiAZAVfH nMOLAhy+0kFyHSrv6zVWQj+cmjPwLvaW7fNWVljL5/MWuF5GJi05DUOfV/vk8BaO EnyVqe2ynzNLTsFpLHHy6XKgKtSTkPygxYSNuI7kSYAxD5qE6hXXKXTAqJ3LjDkO tGiFmxp/vHrlNvcyRjXc30th/9PPj/mRBcJ2KyjXPa63L5ZW86PiyIHKxJA4yogv y4z2ZlhIz90cZvpigFHtFqq1puVlDtKDbAaJ6AKrP8HEHUlMiPNApsSjWWBUcfzV DXzrlg0= =PUEh -----END PGP SIGNATURE----- Merge tag 'sound-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound updates from Takashi Iwai: "This development cycle resulted in a fair amount of changes in both core and driver sides. The most significant change in ALSA core is about PCM. Also the support of of-graph card and the new DAPM widget for DSP are noteworthy changes in ASoC core. And there're lots of small changes splat over the tree, as you can see in diffstat. Below are a few highlights: ALSA core: - Removal of set_fs() hackery from PCM core stuff, and the code reorganization / optimization thereafter - Improved support of PCM ack ops, and a new ABI for improved control/status mmap handling - Lots of constifications in various codes ASoC core: - The support of of-graph card, which may work as a better generic device for a replacement of simple-card - New widget types intended mainly for use with DSPs ASoC drivers: - New drivers for Allwinner V3s SoCs - Ensonic ES8316 codec support - More Intel SKL and KBL works - More device support for Intel SST Atom (mostly for cheap tablets and 2-in-1 devices) - Support for Rockchip PDM controllers - Support for STM32 I2S and S/PDIF controllers - Support for ZTE AUD96P22 codecs HD-audio: - Support of new Realtek codecs (ALC215/ALC285/ALC289), more quirks for HP and Dell machines - A few more fixes for i915 component binding" * tag 'sound-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (418 commits) ALSA: hda - Fix unbalance of i915 module refcount ASoC: Intel: Skylake: Remove driver debugfs exit ASoC: Intel: Skylake: explicitly add the headers sst-dsp.h ALSA: hda/realtek - Remove GPIO_MASK ALSA: hda/realtek - Fix typo of pincfg for Dell quirk ALSA: pcm: add a documentation for tracepoints ALSA: atmel: ac97c: fix error return code in atmel_ac97c_probe() ALSA: x86: fix error return code in hdmi_lpe_audio_probe() ASoC: Intel: Skylake: Add support to read firmware registers ASoC: Intel: Skylake: Add sram address to sst_addr structure ASoC: Intel: Skylake: Debugfs facility to dump module config ASoC: Intel: Skylake: Add debugfs support ASoC: fix semicolon.cocci warnings ASoC: rt5645: Add quirk override by module option ASoC: rsnd: make arrays path and cmd_case static const ASoC: audio-graph-card: add widgets and routing for external amplifier support ASoC: audio-graph-card: update bindings for amplifier support ASoC: rt5665: calibration should be done before jack detection ASoC: rsnd: constify dev_pm_ops structures. ASoC: nau8825: change crosstalk-bypass property to bool type ...
311 lines
7.1 KiB
C
311 lines
7.1 KiB
C
/*
|
|
* u_uac1.c -- ALSA audio utilities for Gadget stack
|
|
*
|
|
* Copyright (C) 2008 Bryan Wu <cooloney@kernel.org>
|
|
* Copyright (C) 2008 Analog Devices, Inc
|
|
*
|
|
* Enter bugs at http://blackfin.uclinux.org/
|
|
*
|
|
* Licensed under the GPL-2 or later.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/device.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/random.h>
|
|
#include <linux/syscalls.h>
|
|
|
|
#include "u_uac1_legacy.h"
|
|
|
|
/*
|
|
* This component encapsulates the ALSA devices for USB audio gadget
|
|
*/
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Some ALSA internal helper functions
|
|
*/
|
|
static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
|
|
{
|
|
struct snd_interval t;
|
|
t.empty = 0;
|
|
t.min = t.max = val;
|
|
t.openmin = t.openmax = 0;
|
|
t.integer = 1;
|
|
return snd_interval_refine(i, &t);
|
|
}
|
|
|
|
static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
|
|
snd_pcm_hw_param_t var, unsigned int val,
|
|
int dir)
|
|
{
|
|
int changed;
|
|
if (hw_is_mask(var)) {
|
|
struct snd_mask *m = hw_param_mask(params, var);
|
|
if (val == 0 && dir < 0) {
|
|
changed = -EINVAL;
|
|
snd_mask_none(m);
|
|
} else {
|
|
if (dir > 0)
|
|
val++;
|
|
else if (dir < 0)
|
|
val--;
|
|
changed = snd_mask_refine_set(
|
|
hw_param_mask(params, var), val);
|
|
}
|
|
} else if (hw_is_interval(var)) {
|
|
struct snd_interval *i = hw_param_interval(params, var);
|
|
if (val == 0 && dir < 0) {
|
|
changed = -EINVAL;
|
|
snd_interval_none(i);
|
|
} else if (dir == 0)
|
|
changed = snd_interval_refine_set(i, val);
|
|
else {
|
|
struct snd_interval t;
|
|
t.openmin = 1;
|
|
t.openmax = 1;
|
|
t.empty = 0;
|
|
t.integer = 0;
|
|
if (dir < 0) {
|
|
t.min = val - 1;
|
|
t.max = val;
|
|
} else {
|
|
t.min = val;
|
|
t.max = val+1;
|
|
}
|
|
changed = snd_interval_refine(i, &t);
|
|
}
|
|
} else
|
|
return -EINVAL;
|
|
if (changed) {
|
|
params->cmask |= 1 << var;
|
|
params->rmask |= 1 << var;
|
|
}
|
|
return changed;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Set default hardware params
|
|
*/
|
|
static int playback_default_hw_params(struct gaudio_snd_dev *snd)
|
|
{
|
|
struct snd_pcm_substream *substream = snd->substream;
|
|
struct snd_pcm_hw_params *params;
|
|
snd_pcm_sframes_t result;
|
|
|
|
/*
|
|
* SNDRV_PCM_ACCESS_RW_INTERLEAVED,
|
|
* SNDRV_PCM_FORMAT_S16_LE
|
|
* CHANNELS: 2
|
|
* RATE: 48000
|
|
*/
|
|
snd->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
|
|
snd->format = SNDRV_PCM_FORMAT_S16_LE;
|
|
snd->channels = 2;
|
|
snd->rate = 48000;
|
|
|
|
params = kzalloc(sizeof(*params), GFP_KERNEL);
|
|
if (!params)
|
|
return -ENOMEM;
|
|
|
|
_snd_pcm_hw_params_any(params);
|
|
_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS,
|
|
snd->access, 0);
|
|
_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT,
|
|
snd->format, 0);
|
|
_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS,
|
|
snd->channels, 0);
|
|
_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE,
|
|
snd->rate, 0);
|
|
|
|
snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
|
|
snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, params);
|
|
|
|
result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL);
|
|
if (result < 0) {
|
|
ERROR(snd->card,
|
|
"Preparing sound card failed: %d\n", (int)result);
|
|
kfree(params);
|
|
return result;
|
|
}
|
|
|
|
/* Store the hardware parameters */
|
|
snd->access = params_access(params);
|
|
snd->format = params_format(params);
|
|
snd->channels = params_channels(params);
|
|
snd->rate = params_rate(params);
|
|
|
|
kfree(params);
|
|
|
|
INFO(snd->card,
|
|
"Hardware params: access %x, format %x, channels %d, rate %d\n",
|
|
snd->access, snd->format, snd->channels, snd->rate);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Playback audio buffer data by ALSA PCM device
|
|
*/
|
|
size_t u_audio_playback(struct gaudio *card, void *buf, size_t count)
|
|
{
|
|
struct gaudio_snd_dev *snd = &card->playback;
|
|
struct snd_pcm_substream *substream = snd->substream;
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
ssize_t result;
|
|
snd_pcm_sframes_t frames;
|
|
|
|
try_again:
|
|
if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
|
|
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
|
|
result = snd_pcm_kernel_ioctl(substream,
|
|
SNDRV_PCM_IOCTL_PREPARE, NULL);
|
|
if (result < 0) {
|
|
ERROR(card, "Preparing sound card failed: %d\n",
|
|
(int)result);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
frames = bytes_to_frames(runtime, count);
|
|
result = snd_pcm_kernel_write(snd->substream, buf, frames);
|
|
if (result != frames) {
|
|
ERROR(card, "Playback error: %d\n", (int)result);
|
|
goto try_again;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int u_audio_get_playback_channels(struct gaudio *card)
|
|
{
|
|
return card->playback.channels;
|
|
}
|
|
|
|
int u_audio_get_playback_rate(struct gaudio *card)
|
|
{
|
|
return card->playback.rate;
|
|
}
|
|
|
|
/**
|
|
* Open ALSA PCM and control device files
|
|
* Initial the PCM or control device
|
|
*/
|
|
static int gaudio_open_snd_dev(struct gaudio *card)
|
|
{
|
|
struct snd_pcm_file *pcm_file;
|
|
struct gaudio_snd_dev *snd;
|
|
struct f_uac1_legacy_opts *opts;
|
|
char *fn_play, *fn_cap, *fn_cntl;
|
|
|
|
opts = container_of(card->func.fi, struct f_uac1_legacy_opts,
|
|
func_inst);
|
|
fn_play = opts->fn_play;
|
|
fn_cap = opts->fn_cap;
|
|
fn_cntl = opts->fn_cntl;
|
|
|
|
/* Open control device */
|
|
snd = &card->control;
|
|
snd->filp = filp_open(fn_cntl, O_RDWR, 0);
|
|
if (IS_ERR(snd->filp)) {
|
|
int ret = PTR_ERR(snd->filp);
|
|
ERROR(card, "unable to open sound control device file: %s\n",
|
|
fn_cntl);
|
|
snd->filp = NULL;
|
|
return ret;
|
|
}
|
|
snd->card = card;
|
|
|
|
/* Open PCM playback device and setup substream */
|
|
snd = &card->playback;
|
|
snd->filp = filp_open(fn_play, O_WRONLY, 0);
|
|
if (IS_ERR(snd->filp)) {
|
|
int ret = PTR_ERR(snd->filp);
|
|
|
|
ERROR(card, "No such PCM playback device: %s\n", fn_play);
|
|
snd->filp = NULL;
|
|
return ret;
|
|
}
|
|
pcm_file = snd->filp->private_data;
|
|
snd->substream = pcm_file->substream;
|
|
snd->card = card;
|
|
playback_default_hw_params(snd);
|
|
|
|
/* Open PCM capture device and setup substream */
|
|
snd = &card->capture;
|
|
snd->filp = filp_open(fn_cap, O_RDONLY, 0);
|
|
if (IS_ERR(snd->filp)) {
|
|
ERROR(card, "No such PCM capture device: %s\n", fn_cap);
|
|
snd->substream = NULL;
|
|
snd->card = NULL;
|
|
snd->filp = NULL;
|
|
} else {
|
|
pcm_file = snd->filp->private_data;
|
|
snd->substream = pcm_file->substream;
|
|
snd->card = card;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Close ALSA PCM and control device files
|
|
*/
|
|
static int gaudio_close_snd_dev(struct gaudio *gau)
|
|
{
|
|
struct gaudio_snd_dev *snd;
|
|
|
|
/* Close control device */
|
|
snd = &gau->control;
|
|
if (snd->filp)
|
|
filp_close(snd->filp, NULL);
|
|
|
|
/* Close PCM playback device and setup substream */
|
|
snd = &gau->playback;
|
|
if (snd->filp)
|
|
filp_close(snd->filp, NULL);
|
|
|
|
/* Close PCM capture device and setup substream */
|
|
snd = &gau->capture;
|
|
if (snd->filp)
|
|
filp_close(snd->filp, NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* gaudio_setup - setup ALSA interface and preparing for USB transfer
|
|
*
|
|
* This sets up PCM, mixer or MIDI ALSA devices fore USB gadget using.
|
|
*
|
|
* Returns negative errno, or zero on success
|
|
*/
|
|
int gaudio_setup(struct gaudio *card)
|
|
{
|
|
int ret;
|
|
|
|
ret = gaudio_open_snd_dev(card);
|
|
if (ret)
|
|
ERROR(card, "we need at least one control device\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
/**
|
|
* gaudio_cleanup - remove ALSA device interface
|
|
*
|
|
* This is called to free all resources allocated by @gaudio_setup().
|
|
*/
|
|
void gaudio_cleanup(struct gaudio *the_card)
|
|
{
|
|
if (the_card)
|
|
gaudio_close_snd_dev(the_card);
|
|
}
|
|
|