You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-next' into for-linus
This commit is contained in:
@@ -655,17 +655,6 @@ development branches in general while the development for the current
|
||||
and next kernels are found in for-linus and for-next branches,
|
||||
respectively.
|
||||
|
||||
If you are using the latest Linus tree, it'd be better to pull the
|
||||
above GIT tree onto it. If you are using the older kernels, an easy
|
||||
way to try the latest ALSA code is to build from the snapshot
|
||||
tarball. There are daily tarballs and the latest snapshot tarball.
|
||||
All can be built just like normal alsa-driver release packages, that
|
||||
is, installed via the usual spells: configure, make and make
|
||||
install(-modules). See INSTALL in the package. The snapshot tarballs
|
||||
are found at:
|
||||
|
||||
- ftp://ftp.suse.com/pub/people/tiwai/snapshot/
|
||||
|
||||
|
||||
Sending a Bug Report
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -699,7 +688,12 @@ problems.
|
||||
alsa-info
|
||||
~~~~~~~~~
|
||||
The script `alsa-info.sh` is a very useful tool to gather the audio
|
||||
device information. You can fetch the latest version from:
|
||||
device information. It's included in alsa-utils package. The latest
|
||||
version can be found on git repository:
|
||||
|
||||
- git://git.alsa-project.org/alsa-utils.git
|
||||
|
||||
The script can be fetched directly from the following URL, too:
|
||||
|
||||
- http://www.alsa-project.org/alsa-info.sh
|
||||
|
||||
@@ -836,15 +830,11 @@ can get a proc-file dump at the current state, get a list of control
|
||||
(mixer) elements, set/get the control element value, simulate the PCM
|
||||
operation, the jack plugging simulation, etc.
|
||||
|
||||
The package is found in:
|
||||
|
||||
- ftp://ftp.suse.com/pub/people/tiwai/misc/
|
||||
|
||||
A git repository is available:
|
||||
The program is found in the git repository below:
|
||||
|
||||
- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/hda-emu.git
|
||||
|
||||
See README file in the tarball for more details about hda-emu
|
||||
See README file in the repository for more details about hda-emu
|
||||
program.
|
||||
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ Gapless Playback
|
||||
================
|
||||
When playing thru an album, the decoders have the ability to skip the encoder
|
||||
delay and padding and directly move from one track content to another. The end
|
||||
user can perceive this as gapless playback as we dont have silence while
|
||||
user can perceive this as gapless playback as we don't have silence while
|
||||
switching from one track to another
|
||||
|
||||
Also, there might be low-intensity noises due to encoding. Perfect gapless is
|
||||
@@ -184,7 +184,7 @@ Sequence flow for gapless would be:
|
||||
- Fill data of the first track
|
||||
- Trigger start
|
||||
- User-space finished sending all,
|
||||
- Indicaite next track data by sending set_next_track
|
||||
- Indicate next track data by sending set_next_track
|
||||
- Set metadata of the next track
|
||||
- then call partial_drain to flush most of buffer in DSP
|
||||
- Fill data of the next track
|
||||
|
||||
@@ -132,7 +132,7 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
|
||||
SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
|
||||
ARRAY_SIZE(wm8731_output_mixer_controls)),
|
||||
|
||||
If you dont want the mixer elements prefixed with the name of the mixer widget,
|
||||
If you don't want the mixer elements prefixed with the name of the mixer widget,
|
||||
you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same
|
||||
as for SND_SOC_DAPM_MIXER.
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ multiple re-usable component drivers :-
|
||||
and any audio DSP drivers for that platform.
|
||||
|
||||
* Machine class driver: The machine driver class acts as the glue that
|
||||
decribes and binds the other component drivers together to form an ALSA
|
||||
describes and binds the other component drivers together to form an ALSA
|
||||
"sound card device". It handles any machine specific controls and
|
||||
machine level audio events (e.g. turning on an amp at start of playback).
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ will be required to issue multiple queries and perform an
|
||||
interpolation of the results
|
||||
|
||||
In some hardware-specific configuration, the system timestamp is
|
||||
latched by a low-level audio subsytem, and the information provided
|
||||
latched by a low-level audio subsystem, and the information provided
|
||||
back to the driver. Due to potential delays in the communication with
|
||||
the hardware, there is a risk of misalignment with the avail and delay
|
||||
information. To make sure applications are not confused, a
|
||||
|
||||
@@ -36,6 +36,8 @@ struct hdac_chmap_ops {
|
||||
int (*chmap_validate)(struct hdac_chmap *hchmap, int ca,
|
||||
int channels, unsigned char *chmap);
|
||||
|
||||
int (*get_spk_alloc)(struct hdac_device *hdac, int pcm_idx);
|
||||
|
||||
void (*get_chmap)(struct hdac_device *hdac, int pcm_idx,
|
||||
unsigned char *chmap);
|
||||
void (*set_chmap)(struct hdac_device *hdac, int pcm_idx,
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
|
||||
int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
|
||||
void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
|
||||
int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate);
|
||||
int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid,
|
||||
int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
|
||||
int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
|
||||
bool *audio_enabled, char *buffer, int max_bytes);
|
||||
int snd_hdac_i915_init(struct hdac_bus *bus);
|
||||
int snd_hdac_i915_exit(struct hdac_bus *bus);
|
||||
@@ -28,12 +28,12 @@ static inline int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
|
||||
static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
|
||||
{
|
||||
}
|
||||
static inline int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid,
|
||||
int rate)
|
||||
static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
|
||||
hda_nid_t nid, int rate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid,
|
||||
static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
|
||||
bool *audio_enabled, char *buffer,
|
||||
int max_bytes)
|
||||
{
|
||||
|
||||
@@ -672,7 +672,7 @@ enum {
|
||||
|
||||
/* global timers (device member) */
|
||||
#define SNDRV_TIMER_GLOBAL_SYSTEM 0
|
||||
#define SNDRV_TIMER_GLOBAL_RTC 1
|
||||
#define SNDRV_TIMER_GLOBAL_RTC 1 /* unused */
|
||||
#define SNDRV_TIMER_GLOBAL_HPET 2
|
||||
#define SNDRV_TIMER_GLOBAL_HRTIMER 3
|
||||
|
||||
|
||||
@@ -141,35 +141,6 @@ config SND_SEQ_HRTIMER_DEFAULT
|
||||
Say Y here to use the HR-timer backend as the default sequencer
|
||||
timer.
|
||||
|
||||
config SND_RTCTIMER
|
||||
tristate "RTC Timer support"
|
||||
depends on RTC
|
||||
select SND_TIMER
|
||||
help
|
||||
Say Y here to enable RTC timer support for ALSA. ALSA uses
|
||||
the RTC timer as a precise timing source and maps the RTC
|
||||
timer to ALSA's timer interface. The ALSA sequencer code also
|
||||
can use this timing source.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-rtctimer.
|
||||
|
||||
Note that this option is exclusive with the new RTC drivers
|
||||
(CONFIG_RTC_CLASS) since this requires the old API.
|
||||
|
||||
config SND_SEQ_RTCTIMER_DEFAULT
|
||||
bool "Use RTC as default sequencer timer"
|
||||
depends on SND_RTCTIMER && SND_SEQUENCER
|
||||
depends on !SND_SEQ_HRTIMER_DEFAULT
|
||||
default y
|
||||
help
|
||||
Say Y here to use the RTC timer as the default sequencer
|
||||
timer. This is strongly recommended because it ensures
|
||||
precise MIDI timing even when the system timer runs at less
|
||||
than 1000 Hz.
|
||||
|
||||
If in doubt, say Y.
|
||||
|
||||
config SND_DYNAMIC_MINORS
|
||||
bool "Dynamic device file minor numbers"
|
||||
help
|
||||
|
||||
@@ -37,7 +37,6 @@ obj-$(CONFIG_SND) += snd.o
|
||||
obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
|
||||
obj-$(CONFIG_SND_TIMER) += snd-timer.o
|
||||
obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o
|
||||
obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o
|
||||
obj-$(CONFIG_SND_PCM) += snd-pcm.o
|
||||
obj-$(CONFIG_SND_DMAENGINE_PCM) += snd-pcm-dmaengine.o
|
||||
obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
|
||||
|
||||
@@ -288,9 +288,12 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf,
|
||||
stream = &data->stream;
|
||||
mutex_lock(&stream->device->lock);
|
||||
/* write is allowed when stream is running or has been steup */
|
||||
if (stream->runtime->state != SNDRV_PCM_STATE_SETUP &&
|
||||
stream->runtime->state != SNDRV_PCM_STATE_PREPARED &&
|
||||
stream->runtime->state != SNDRV_PCM_STATE_RUNNING) {
|
||||
switch (stream->runtime->state) {
|
||||
case SNDRV_PCM_STATE_SETUP:
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
case SNDRV_PCM_STATE_RUNNING:
|
||||
break;
|
||||
default:
|
||||
mutex_unlock(&stream->device->lock);
|
||||
return -EBADFD;
|
||||
}
|
||||
@@ -391,14 +394,13 @@ static unsigned int snd_compr_poll(struct file *f, poll_table *wait)
|
||||
int retval = 0;
|
||||
|
||||
if (snd_BUG_ON(!data))
|
||||
return -EFAULT;
|
||||
return POLLERR;
|
||||
|
||||
stream = &data->stream;
|
||||
if (snd_BUG_ON(!stream))
|
||||
return -EFAULT;
|
||||
|
||||
mutex_lock(&stream->device->lock);
|
||||
if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
|
||||
retval = -EBADFD;
|
||||
retval = snd_compr_get_poll(stream) | POLLERR;
|
||||
goto out;
|
||||
}
|
||||
poll_wait(f, &stream->runtime->sleep, wait);
|
||||
@@ -421,10 +423,7 @@ static unsigned int snd_compr_poll(struct file *f, poll_table *wait)
|
||||
retval = snd_compr_get_poll(stream);
|
||||
break;
|
||||
default:
|
||||
if (stream->direction == SND_COMPRESS_PLAYBACK)
|
||||
retval = POLLOUT | POLLWRNORM | POLLERR;
|
||||
else
|
||||
retval = POLLIN | POLLRDNORM | POLLERR;
|
||||
retval = snd_compr_get_poll(stream) | POLLERR;
|
||||
break;
|
||||
}
|
||||
out:
|
||||
@@ -802,9 +801,9 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
||||
|
||||
if (snd_BUG_ON(!data))
|
||||
return -EFAULT;
|
||||
|
||||
stream = &data->stream;
|
||||
if (snd_BUG_ON(!stream))
|
||||
return -EFAULT;
|
||||
|
||||
mutex_lock(&stream->device->lock);
|
||||
switch (_IOC_NR(cmd)) {
|
||||
case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
|
||||
|
||||
+37
-15
@@ -38,37 +38,53 @@ static unsigned int resolution;
|
||||
struct snd_hrtimer {
|
||||
struct snd_timer *timer;
|
||||
struct hrtimer hrt;
|
||||
atomic_t running;
|
||||
bool in_callback;
|
||||
};
|
||||
|
||||
static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
|
||||
{
|
||||
struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
|
||||
struct snd_timer *t = stime->timer;
|
||||
unsigned long oruns;
|
||||
ktime_t delta;
|
||||
unsigned long ticks;
|
||||
enum hrtimer_restart ret = HRTIMER_NORESTART;
|
||||
|
||||
if (!atomic_read(&stime->running))
|
||||
return HRTIMER_NORESTART;
|
||||
spin_lock(&t->lock);
|
||||
if (!t->running)
|
||||
goto out; /* fast path */
|
||||
stime->in_callback = true;
|
||||
ticks = t->sticks;
|
||||
spin_unlock(&t->lock);
|
||||
|
||||
oruns = hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
|
||||
snd_timer_interrupt(stime->timer, t->sticks * oruns);
|
||||
/* calculate the drift */
|
||||
delta = ktime_sub(hrt->base->get_time(), hrtimer_get_expires(hrt));
|
||||
if (delta.tv64 > 0)
|
||||
ticks += ktime_divns(delta, ticks * resolution);
|
||||
|
||||
if (!atomic_read(&stime->running))
|
||||
return HRTIMER_NORESTART;
|
||||
return HRTIMER_RESTART;
|
||||
snd_timer_interrupt(stime->timer, ticks);
|
||||
|
||||
spin_lock(&t->lock);
|
||||
if (t->running) {
|
||||
hrtimer_add_expires_ns(hrt, t->sticks * resolution);
|
||||
ret = HRTIMER_RESTART;
|
||||
}
|
||||
|
||||
stime->in_callback = false;
|
||||
out:
|
||||
spin_unlock(&t->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int snd_hrtimer_open(struct snd_timer *t)
|
||||
{
|
||||
struct snd_hrtimer *stime;
|
||||
|
||||
stime = kmalloc(sizeof(*stime), GFP_KERNEL);
|
||||
stime = kzalloc(sizeof(*stime), GFP_KERNEL);
|
||||
if (!stime)
|
||||
return -ENOMEM;
|
||||
hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
stime->timer = t;
|
||||
stime->hrt.function = snd_hrtimer_callback;
|
||||
atomic_set(&stime->running, 0);
|
||||
t->private_data = stime;
|
||||
return 0;
|
||||
}
|
||||
@@ -78,6 +94,11 @@ static int snd_hrtimer_close(struct snd_timer *t)
|
||||
struct snd_hrtimer *stime = t->private_data;
|
||||
|
||||
if (stime) {
|
||||
spin_lock_irq(&t->lock);
|
||||
t->running = 0; /* just to be sure */
|
||||
stime->in_callback = 1; /* skip start/stop */
|
||||
spin_unlock_irq(&t->lock);
|
||||
|
||||
hrtimer_cancel(&stime->hrt);
|
||||
kfree(stime);
|
||||
t->private_data = NULL;
|
||||
@@ -89,18 +110,19 @@ static int snd_hrtimer_start(struct snd_timer *t)
|
||||
{
|
||||
struct snd_hrtimer *stime = t->private_data;
|
||||
|
||||
atomic_set(&stime->running, 0);
|
||||
hrtimer_try_to_cancel(&stime->hrt);
|
||||
if (stime->in_callback)
|
||||
return 0;
|
||||
hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
|
||||
HRTIMER_MODE_REL);
|
||||
atomic_set(&stime->running, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_hrtimer_stop(struct snd_timer *t)
|
||||
{
|
||||
struct snd_hrtimer *stime = t->private_data;
|
||||
atomic_set(&stime->running, 0);
|
||||
|
||||
if (stime->in_callback)
|
||||
return 0;
|
||||
hrtimer_try_to_cancel(&stime->hrt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1886,8 +1886,8 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
|
||||
snd_timer_interrupt(substream->timer, 1);
|
||||
#endif
|
||||
_end:
|
||||
snd_pcm_stream_unlock_irqrestore(substream, flags);
|
||||
kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
|
||||
snd_pcm_stream_unlock_irqrestore(substream, flags);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_pcm_period_elapsed);
|
||||
@@ -2595,6 +2595,8 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
|
||||
};
|
||||
int err;
|
||||
|
||||
if (WARN_ON(pcm->streams[stream].chmap_kctl))
|
||||
return -EBUSY;
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -3161,7 +3161,7 @@ static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
|
||||
|
||||
substream = pcm_file->substream;
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
return POLLOUT | POLLWRNORM | POLLERR;
|
||||
runtime = substream->runtime;
|
||||
|
||||
poll_wait(file, &runtime->sleep, wait);
|
||||
@@ -3200,7 +3200,7 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
|
||||
|
||||
substream = pcm_file->substream;
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
return POLLIN | POLLRDNORM | POLLERR;
|
||||
runtime = substream->runtime;
|
||||
|
||||
poll_wait(file, &runtime->sleep, wait);
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* RTC based high-frequency timer
|
||||
*
|
||||
* Copyright (C) 2000 Takashi Iwai
|
||||
* based on rtctimer.c by Steve Ratcliffe
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/log2.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/timer.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_RTC)
|
||||
|
||||
#include <linux/mc146818rtc.h>
|
||||
|
||||
#define RTC_FREQ 1024 /* default frequency */
|
||||
#define NANO_SEC 1000000000L /* 10^9 in sec */
|
||||
|
||||
/*
|
||||
* prototypes
|
||||
*/
|
||||
static int rtctimer_open(struct snd_timer *t);
|
||||
static int rtctimer_close(struct snd_timer *t);
|
||||
static int rtctimer_start(struct snd_timer *t);
|
||||
static int rtctimer_stop(struct snd_timer *t);
|
||||
|
||||
|
||||
/*
|
||||
* The hardware dependent description for this timer.
|
||||
*/
|
||||
static struct snd_timer_hardware rtc_hw = {
|
||||
.flags = SNDRV_TIMER_HW_AUTO |
|
||||
SNDRV_TIMER_HW_FIRST |
|
||||
SNDRV_TIMER_HW_TASKLET,
|
||||
.ticks = 100000000L, /* FIXME: XXX */
|
||||
.open = rtctimer_open,
|
||||
.close = rtctimer_close,
|
||||
.start = rtctimer_start,
|
||||
.stop = rtctimer_stop,
|
||||
};
|
||||
|
||||
static int rtctimer_freq = RTC_FREQ; /* frequency */
|
||||
static struct snd_timer *rtctimer;
|
||||
static struct tasklet_struct rtc_tasklet;
|
||||
static rtc_task_t rtc_task;
|
||||
|
||||
|
||||
static int
|
||||
rtctimer_open(struct snd_timer *t)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = rtc_register(&rtc_task);
|
||||
if (err < 0)
|
||||
return err;
|
||||
t->private_data = &rtc_task;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rtctimer_close(struct snd_timer *t)
|
||||
{
|
||||
rtc_task_t *rtc = t->private_data;
|
||||
if (rtc) {
|
||||
rtc_unregister(rtc);
|
||||
tasklet_kill(&rtc_tasklet);
|
||||
t->private_data = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rtctimer_start(struct snd_timer *timer)
|
||||
{
|
||||
rtc_task_t *rtc = timer->private_data;
|
||||
if (snd_BUG_ON(!rtc))
|
||||
return -EINVAL;
|
||||
rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
|
||||
rtc_control(rtc, RTC_PIE_ON, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rtctimer_stop(struct snd_timer *timer)
|
||||
{
|
||||
rtc_task_t *rtc = timer->private_data;
|
||||
if (snd_BUG_ON(!rtc))
|
||||
return -EINVAL;
|
||||
rtc_control(rtc, RTC_PIE_OFF, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtctimer_tasklet(unsigned long data)
|
||||
{
|
||||
snd_timer_interrupt((struct snd_timer *)data, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* interrupt
|
||||
*/
|
||||
static void rtctimer_interrupt(void *private_data)
|
||||
{
|
||||
tasklet_schedule(private_data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ENTRY functions
|
||||
*/
|
||||
static int __init rtctimer_init(void)
|
||||
{
|
||||
int err;
|
||||
struct snd_timer *timer;
|
||||
|
||||
if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
|
||||
!is_power_of_2(rtctimer_freq)) {
|
||||
pr_err("ALSA: rtctimer: invalid frequency %d\n", rtctimer_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Create a new timer and set up the fields */
|
||||
err = snd_timer_global_new("rtc", SNDRV_TIMER_GLOBAL_RTC, &timer);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
timer->module = THIS_MODULE;
|
||||
strcpy(timer->name, "RTC timer");
|
||||
timer->hw = rtc_hw;
|
||||
timer->hw.resolution = NANO_SEC / rtctimer_freq;
|
||||
|
||||
tasklet_init(&rtc_tasklet, rtctimer_tasklet, (unsigned long)timer);
|
||||
|
||||
/* set up RTC callback */
|
||||
rtc_task.func = rtctimer_interrupt;
|
||||
rtc_task.private_data = &rtc_tasklet;
|
||||
|
||||
err = snd_timer_global_register(timer);
|
||||
if (err < 0) {
|
||||
snd_timer_global_free(timer);
|
||||
return err;
|
||||
}
|
||||
rtctimer = timer; /* remember this */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rtctimer_exit(void)
|
||||
{
|
||||
if (rtctimer) {
|
||||
snd_timer_global_free(rtctimer);
|
||||
rtctimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* exported stuff
|
||||
*/
|
||||
module_init(rtctimer_init)
|
||||
module_exit(rtctimer_exit)
|
||||
|
||||
module_param(rtctimer_freq, int, 0444);
|
||||
MODULE_PARM_DESC(rtctimer_freq, "timer frequency in Hz");
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
MODULE_ALIAS("snd-timer-" __stringify(SNDRV_TIMER_GLOBAL_RTC));
|
||||
|
||||
#endif /* IS_ENABLED(CONFIG_RTC) */
|
||||
@@ -47,8 +47,6 @@ int seq_default_timer_card = -1;
|
||||
int seq_default_timer_device =
|
||||
#ifdef CONFIG_SND_SEQ_HRTIMER_DEFAULT
|
||||
SNDRV_TIMER_GLOBAL_HRTIMER
|
||||
#elif defined(CONFIG_SND_SEQ_RTCTIMER_DEFAULT)
|
||||
SNDRV_TIMER_GLOBAL_RTC
|
||||
#else
|
||||
SNDRV_TIMER_GLOBAL_SYSTEM
|
||||
#endif
|
||||
|
||||
+3
-2
@@ -37,8 +37,6 @@
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_HRTIMER)
|
||||
#define DEFAULT_TIMER_LIMIT 4
|
||||
#elif IS_ENABLED(CONFIG_SND_RTCTIMER)
|
||||
#define DEFAULT_TIMER_LIMIT 2
|
||||
#else
|
||||
#define DEFAULT_TIMER_LIMIT 1
|
||||
#endif
|
||||
@@ -1225,6 +1223,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
|
||||
tu->tstamp = *tstamp;
|
||||
if ((tu->filter & (1 << event)) == 0 || !tu->tread)
|
||||
return;
|
||||
memset(&r1, 0, sizeof(r1));
|
||||
r1.event = event;
|
||||
r1.tstamp = *tstamp;
|
||||
r1.val = resolution;
|
||||
@@ -1267,6 +1266,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
|
||||
}
|
||||
if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
|
||||
tu->last_resolution != resolution) {
|
||||
memset(&r1, 0, sizeof(r1));
|
||||
r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
|
||||
r1.tstamp = tstamp;
|
||||
r1.val = resolution;
|
||||
@@ -1739,6 +1739,7 @@ static int snd_timer_user_params(struct file *file,
|
||||
if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
|
||||
if (tu->tread) {
|
||||
struct snd_timer_tread tread;
|
||||
memset(&tread, 0, sizeof(tread));
|
||||
tread.event = SNDRV_TIMER_EVENT_EARLY;
|
||||
tread.tstamp.tv_sec = 0;
|
||||
tread.tstamp.tv_nsec = 0;
|
||||
|
||||
@@ -134,6 +134,7 @@ config SND_FIREWIRE_TASCAM
|
||||
Say Y here to include support for TASCAM.
|
||||
* FW-1884
|
||||
* FW-1082
|
||||
* FW-1804
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-firewire-tascam.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# To find a header included by define_trace.h.
|
||||
CFLAGS_amdtp-stream.o := -I$(src)
|
||||
|
||||
snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
|
||||
fcp.o cmp.o amdtp-stream.o amdtp-am824.o
|
||||
snd-isight-objs := isight.o
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* amdtp-stream-trace.h - tracepoint definitions to dump a part of packet data
|
||||
*
|
||||
* Copyright (c) 2016 Takashi Sakamoto
|
||||
* Licensed under the terms of the GNU General Public License, version 2.
|
||||
*/
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM snd_firewire_lib
|
||||
|
||||
#if !defined(_AMDTP_STREAM_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _AMDTP_STREAM_TRACE_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
TRACE_EVENT(in_packet,
|
||||
TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 cip_header[2], unsigned int payload_quadlets, unsigned int index),
|
||||
TP_ARGS(s, cycles, cip_header, payload_quadlets, index),
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, second)
|
||||
__field(unsigned int, cycle)
|
||||
__field(int, channel)
|
||||
__field(int, src)
|
||||
__field(int, dest)
|
||||
__field(u32, cip_header0)
|
||||
__field(u32, cip_header1)
|
||||
__field(unsigned int, payload_quadlets)
|
||||
__field(unsigned int, packet_index)
|
||||
__field(bool, irq)
|
||||
__field(unsigned int, index)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->second = cycles / CYCLES_PER_SECOND;
|
||||
__entry->cycle = cycles % CYCLES_PER_SECOND;
|
||||
__entry->channel = s->context->channel;
|
||||
__entry->src = fw_parent_device(s->unit)->node_id;
|
||||
__entry->dest = fw_parent_device(s->unit)->card->node_id;
|
||||
__entry->cip_header0 = cip_header[0];
|
||||
__entry->cip_header1 = cip_header[1];
|
||||
__entry->payload_quadlets = payload_quadlets;
|
||||
__entry->packet_index = s->packet_index;
|
||||
__entry->irq = in_interrupt();
|
||||
__entry->index = index;
|
||||
),
|
||||
TP_printk(
|
||||
"%02u %04u %04x %04x %02d %08x %08x %03u %02u %01u %02u",
|
||||
__entry->second,
|
||||
__entry->cycle,
|
||||
__entry->src,
|
||||
__entry->dest,
|
||||
__entry->channel,
|
||||
__entry->cip_header0,
|
||||
__entry->cip_header1,
|
||||
__entry->payload_quadlets,
|
||||
__entry->packet_index,
|
||||
__entry->irq,
|
||||
__entry->index)
|
||||
);
|
||||
|
||||
TRACE_EVENT(out_packet,
|
||||
TP_PROTO(const struct amdtp_stream *s, u32 cycles, __be32 *cip_header, unsigned int payload_length, unsigned int index),
|
||||
TP_ARGS(s, cycles, cip_header, payload_length, index),
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, second)
|
||||
__field(unsigned int, cycle)
|
||||
__field(int, channel)
|
||||
__field(int, src)
|
||||
__field(int, dest)
|
||||
__field(u32, cip_header0)
|
||||
__field(u32, cip_header1)
|
||||
__field(unsigned int, payload_quadlets)
|
||||
__field(unsigned int, packet_index)
|
||||
__field(bool, irq)
|
||||
__field(unsigned int, index)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->second = cycles / CYCLES_PER_SECOND;
|
||||
__entry->cycle = cycles % CYCLES_PER_SECOND;
|
||||
__entry->channel = s->context->channel;
|
||||
__entry->src = fw_parent_device(s->unit)->card->node_id;
|
||||
__entry->dest = fw_parent_device(s->unit)->node_id;
|
||||
__entry->cip_header0 = be32_to_cpu(cip_header[0]);
|
||||
__entry->cip_header1 = be32_to_cpu(cip_header[1]);
|
||||
__entry->payload_quadlets = payload_length / 4;
|
||||
__entry->packet_index = s->packet_index;
|
||||
__entry->irq = in_interrupt();
|
||||
__entry->index = index;
|
||||
),
|
||||
TP_printk(
|
||||
"%02u %04u %04x %04x %02d %08x %08x %03u %02u %01u %02u",
|
||||
__entry->second,
|
||||
__entry->cycle,
|
||||
__entry->src,
|
||||
__entry->dest,
|
||||
__entry->channel,
|
||||
__entry->cip_header0,
|
||||
__entry->cip_header1,
|
||||
__entry->payload_quadlets,
|
||||
__entry->packet_index,
|
||||
__entry->irq,
|
||||
__entry->index)
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE amdtp-stream-trace
|
||||
#include <trace/define_trace.h>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user