Merge branch 'for-next' into for-linus
Preparation for 4.19 merge material. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <linux/idr.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -68,6 +69,27 @@ ac97_codec_find(struct ac97_controller *ac97_ctrl, unsigned int codec_num)
|
||||
return ac97_ctrl->codecs[codec_num];
|
||||
}
|
||||
|
||||
static struct device_node *
|
||||
ac97_of_get_child_device(struct ac97_controller *ac97_ctrl, int idx,
|
||||
unsigned int vendor_id)
|
||||
{
|
||||
struct device_node *node;
|
||||
u32 reg;
|
||||
char compat[] = "ac97,0000,0000";
|
||||
|
||||
snprintf(compat, sizeof(compat), "ac97,%04x,%04x",
|
||||
vendor_id >> 16, vendor_id & 0xffff);
|
||||
|
||||
for_each_child_of_node(ac97_ctrl->parent->of_node, node) {
|
||||
if ((idx != of_property_read_u32(node, "reg", ®)) ||
|
||||
!of_device_is_compatible(node, compat))
|
||||
continue;
|
||||
return of_node_get(node);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ac97_codec_release(struct device *dev)
|
||||
{
|
||||
struct ac97_codec_device *adev;
|
||||
@@ -76,6 +98,7 @@ static void ac97_codec_release(struct device *dev)
|
||||
adev = to_ac97_device(dev);
|
||||
ac97_ctrl = adev->ac97_ctrl;
|
||||
ac97_ctrl->codecs[adev->num] = NULL;
|
||||
of_node_put(dev->of_node);
|
||||
kfree(adev);
|
||||
}
|
||||
|
||||
@@ -98,6 +121,8 @@ static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
|
||||
|
||||
device_initialize(&codec->dev);
|
||||
dev_set_name(&codec->dev, "%s:%u", dev_name(ac97_ctrl->parent), idx);
|
||||
codec->dev.of_node = ac97_of_get_child_device(ac97_ctrl, idx,
|
||||
vendor_id);
|
||||
|
||||
ret = device_add(&codec->dev);
|
||||
if (ret)
|
||||
@@ -105,6 +130,7 @@ static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
|
||||
|
||||
return 0;
|
||||
err_free_codec:
|
||||
of_node_put(codec->dev.of_node);
|
||||
put_device(&codec->dev);
|
||||
kfree(codec);
|
||||
ac97_ctrl->codecs[idx] = NULL;
|
||||
|
@@ -88,8 +88,10 @@ static struct device_node *get_gpio(char *name,
|
||||
}
|
||||
|
||||
reg = of_get_property(np, "reg", NULL);
|
||||
if (!reg)
|
||||
if (!reg) {
|
||||
of_node_put(np);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*gpioptr = *reg;
|
||||
|
||||
|
@@ -1160,18 +1160,6 @@ int snd_compress_deregister(struct snd_compr *device)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_compress_deregister);
|
||||
|
||||
static int __init snd_compress_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit snd_compress_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(snd_compress_init);
|
||||
module_exit(snd_compress_exit);
|
||||
|
||||
MODULE_DESCRIPTION("ALSA Compressed offload framework");
|
||||
MODULE_AUTHOR("Vinod Koul <vinod.koul@linux.intel.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -1851,7 +1851,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
|
||||
format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
|
||||
for (fmt = 0; fmt < 32; ++fmt) {
|
||||
if (snd_mask_test(format_mask, fmt)) {
|
||||
int f = snd_pcm_oss_format_to(fmt);
|
||||
int f = snd_pcm_oss_format_to((__force snd_pcm_format_t)fmt);
|
||||
if (f >= 0)
|
||||
formats |= f;
|
||||
}
|
||||
|
@@ -281,10 +281,10 @@ static int snd_pcm_plug_formats(const struct snd_mask *mask,
|
||||
SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE);
|
||||
snd_mask_set(&formats, (__force int)SNDRV_PCM_FORMAT_MU_LAW);
|
||||
|
||||
if (formats.bits[0] & (u32)linfmts)
|
||||
formats.bits[0] |= (u32)linfmts;
|
||||
if (formats.bits[1] & (u32)(linfmts >> 32))
|
||||
formats.bits[1] |= (u32)(linfmts >> 32);
|
||||
if (formats.bits[0] & lower_32_bits(linfmts))
|
||||
formats.bits[0] |= lower_32_bits(linfmts);
|
||||
if (formats.bits[1] & upper_32_bits(linfmts))
|
||||
formats.bits[1] |= upper_32_bits(linfmts);
|
||||
return snd_mask_test(&formats, (__force int)format);
|
||||
}
|
||||
|
||||
@@ -353,6 +353,7 @@ snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format,
|
||||
if (snd_mask_test(format_mask, (__force int)format1))
|
||||
return format1;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
return (__force snd_pcm_format_t)-EINVAL;
|
||||
}
|
||||
|
@@ -492,13 +492,8 @@ static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
{
|
||||
struct snd_pcm_substream *substream = entry->private_data;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
runtime = substream->runtime;
|
||||
if (runtime && runtime->status->state == SNDRV_PCM_STATE_RUNNING)
|
||||
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
snd_pcm_stop_xrun(substream);
|
||||
}
|
||||
|
||||
static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
|
||||
|
@@ -153,7 +153,8 @@ EXPORT_SYMBOL(snd_pcm_debug_name);
|
||||
dump_stack(); \
|
||||
} while (0)
|
||||
|
||||
static void xrun(struct snd_pcm_substream *substream)
|
||||
/* call with stream lock held */
|
||||
void __snd_pcm_xrun(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
|
||||
@@ -201,7 +202,7 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
|
||||
}
|
||||
} else {
|
||||
if (avail >= runtime->stop_threshold) {
|
||||
xrun(substream);
|
||||
__snd_pcm_xrun(substream);
|
||||
return -EPIPE;
|
||||
}
|
||||
}
|
||||
@@ -297,7 +298,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
|
||||
}
|
||||
|
||||
if (pos == SNDRV_PCM_POS_XRUN) {
|
||||
xrun(substream);
|
||||
__snd_pcm_xrun(substream);
|
||||
return -EPIPE;
|
||||
}
|
||||
if (pos >= runtime->buffer_size) {
|
||||
@@ -626,27 +627,33 @@ EXPORT_SYMBOL(snd_interval_refine);
|
||||
|
||||
static int snd_interval_refine_first(struct snd_interval *i)
|
||||
{
|
||||
const unsigned int last_max = i->max;
|
||||
|
||||
if (snd_BUG_ON(snd_interval_empty(i)))
|
||||
return -EINVAL;
|
||||
if (snd_interval_single(i))
|
||||
return 0;
|
||||
i->max = i->min;
|
||||
i->openmax = i->openmin;
|
||||
if (i->openmax)
|
||||
if (i->openmin)
|
||||
i->max++;
|
||||
/* only exclude max value if also excluded before refine */
|
||||
i->openmax = (i->openmax && i->max >= last_max);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int snd_interval_refine_last(struct snd_interval *i)
|
||||
{
|
||||
const unsigned int last_min = i->min;
|
||||
|
||||
if (snd_BUG_ON(snd_interval_empty(i)))
|
||||
return -EINVAL;
|
||||
if (snd_interval_single(i))
|
||||
return 0;
|
||||
i->min = i->max;
|
||||
i->openmin = i->openmax;
|
||||
if (i->openmin)
|
||||
if (i->openmax)
|
||||
i->min--;
|
||||
/* only exclude min value if also excluded before refine */
|
||||
i->openmin = (i->openmin && i->min <= last_min);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1832,12 +1839,19 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
|
||||
if (runtime->no_period_wakeup)
|
||||
wait_time = MAX_SCHEDULE_TIMEOUT;
|
||||
else {
|
||||
wait_time = 10;
|
||||
if (runtime->rate) {
|
||||
long t = runtime->period_size * 2 / runtime->rate;
|
||||
wait_time = max(t, wait_time);
|
||||
/* use wait time from substream if available */
|
||||
if (substream->wait_time) {
|
||||
wait_time = substream->wait_time;
|
||||
} else {
|
||||
wait_time = 10;
|
||||
|
||||
if (runtime->rate) {
|
||||
long t = runtime->period_size * 2 /
|
||||
runtime->rate;
|
||||
wait_time = max(t, wait_time);
|
||||
}
|
||||
wait_time = msecs_to_jiffies(wait_time * 1000);
|
||||
}
|
||||
wait_time = msecs_to_jiffies(wait_time * 1000);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
|
@@ -65,4 +65,6 @@ static inline void snd_pcm_timer_init(struct snd_pcm_substream *substream) {}
|
||||
static inline void snd_pcm_timer_done(struct snd_pcm_substream *substream) {}
|
||||
#endif
|
||||
|
||||
void __snd_pcm_xrun(struct snd_pcm_substream *substream);
|
||||
|
||||
#endif /* __SOUND_CORE_PCM_LOCAL_H */
|
||||
|
@@ -1337,13 +1337,12 @@ int snd_pcm_drain_done(struct snd_pcm_substream *substream)
|
||||
int snd_pcm_stop_xrun(struct snd_pcm_substream *substream)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
snd_pcm_stream_lock_irqsave(substream, flags);
|
||||
if (snd_pcm_running(substream))
|
||||
ret = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
|
||||
if (substream->runtime && snd_pcm_running(substream))
|
||||
__snd_pcm_xrun(substream);
|
||||
snd_pcm_stream_unlock_irqrestore(substream, flags);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun);
|
||||
|
||||
@@ -1591,7 +1590,8 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream)
|
||||
result = 0; /* already there */
|
||||
break;
|
||||
case SNDRV_PCM_STATE_RUNNING:
|
||||
result = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
|
||||
__snd_pcm_xrun(substream);
|
||||
result = 0;
|
||||
break;
|
||||
default:
|
||||
result = -EBADFD;
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mm.h>
|
||||
#include <sound/rawmidi.h>
|
||||
#include <sound/info.h>
|
||||
#include <sound/control.h>
|
||||
@@ -88,6 +89,7 @@ static inline unsigned short snd_rawmidi_file_flags(struct file *file)
|
||||
static inline int snd_rawmidi_ready(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
return runtime->avail >= runtime->avail_min;
|
||||
}
|
||||
|
||||
@@ -95,6 +97,7 @@ static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substre
|
||||
size_t count)
|
||||
{
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
return runtime->avail >= runtime->avail_min &&
|
||||
(!substream->append || runtime->avail >= count);
|
||||
}
|
||||
@@ -103,6 +106,7 @@ static void snd_rawmidi_input_event_work(struct work_struct *work)
|
||||
{
|
||||
struct snd_rawmidi_runtime *runtime =
|
||||
container_of(work, struct snd_rawmidi_runtime, event_work);
|
||||
|
||||
if (runtime->event)
|
||||
runtime->event(runtime->substream);
|
||||
}
|
||||
@@ -111,7 +115,8 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct snd_rawmidi_runtime *runtime;
|
||||
|
||||
if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
|
||||
runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
|
||||
if (!runtime)
|
||||
return -ENOMEM;
|
||||
runtime->substream = substream;
|
||||
spin_lock_init(&runtime->lock);
|
||||
@@ -124,7 +129,8 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
|
||||
runtime->avail = 0;
|
||||
else
|
||||
runtime->avail = runtime->buffer_size;
|
||||
if ((runtime->buffer = kmalloc(runtime->buffer_size, GFP_KERNEL)) == NULL) {
|
||||
runtime->buffer = kvmalloc(runtime->buffer_size, GFP_KERNEL);
|
||||
if (!runtime->buffer) {
|
||||
kfree(runtime);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -137,13 +143,13 @@ static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
kfree(runtime->buffer);
|
||||
kvfree(runtime->buffer);
|
||||
kfree(runtime);
|
||||
substream->runtime = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,int up)
|
||||
static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
|
||||
{
|
||||
if (!substream->opened)
|
||||
return;
|
||||
@@ -159,17 +165,28 @@ static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, i
|
||||
cancel_work_sync(&substream->runtime->event_work);
|
||||
}
|
||||
|
||||
int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
|
||||
static void __reset_runtime_ptrs(struct snd_rawmidi_runtime *runtime,
|
||||
bool is_input)
|
||||
{
|
||||
runtime->drain = 0;
|
||||
runtime->appl_ptr = runtime->hw_ptr = 0;
|
||||
runtime->avail = is_input ? 0 : runtime->buffer_size;
|
||||
}
|
||||
|
||||
static void reset_runtime_ptrs(struct snd_rawmidi_runtime *runtime,
|
||||
bool is_input)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
snd_rawmidi_output_trigger(substream, 0);
|
||||
runtime->drain = 0;
|
||||
spin_lock_irqsave(&runtime->lock, flags);
|
||||
runtime->appl_ptr = runtime->hw_ptr = 0;
|
||||
runtime->avail = runtime->buffer_size;
|
||||
__reset_runtime_ptrs(runtime, is_input);
|
||||
spin_unlock_irqrestore(&runtime->lock, flags);
|
||||
}
|
||||
|
||||
int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
snd_rawmidi_output_trigger(substream, 0);
|
||||
reset_runtime_ptrs(substream->runtime, false);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_rawmidi_drop_output);
|
||||
@@ -208,15 +225,8 @@ EXPORT_SYMBOL(snd_rawmidi_drain_output);
|
||||
|
||||
int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
snd_rawmidi_input_trigger(substream, 0);
|
||||
runtime->drain = 0;
|
||||
spin_lock_irqsave(&runtime->lock, flags);
|
||||
runtime->appl_ptr = runtime->hw_ptr = 0;
|
||||
runtime->avail = 0;
|
||||
spin_unlock_irqrestore(&runtime->lock, flags);
|
||||
reset_runtime_ptrs(substream->runtime, true);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_rawmidi_drain_input);
|
||||
@@ -330,25 +340,23 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
|
||||
|
||||
/* called from sound/core/seq/seq_midi.c */
|
||||
int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
|
||||
int mode, struct snd_rawmidi_file * rfile)
|
||||
int mode, struct snd_rawmidi_file *rfile)
|
||||
{
|
||||
struct snd_rawmidi *rmidi;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
if (snd_BUG_ON(!rfile))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(®ister_mutex);
|
||||
rmidi = snd_rawmidi_search(card, device);
|
||||
if (rmidi == NULL) {
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!try_module_get(rmidi->card->module)) {
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENXIO;
|
||||
}
|
||||
if (!rmidi)
|
||||
err = -ENODEV;
|
||||
else if (!try_module_get(rmidi->card->module))
|
||||
err = -ENXIO;
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
mutex_lock(&rmidi->open_mutex);
|
||||
err = rawmidi_open_priv(rmidi, subdevice, mode, rfile);
|
||||
@@ -370,7 +378,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
|
||||
struct snd_rawmidi_file *rawmidi_file = NULL;
|
||||
wait_queue_entry_t wait;
|
||||
|
||||
if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
|
||||
if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
|
||||
return -EINVAL; /* invalid combination */
|
||||
|
||||
err = nonseekable_open(inode, file);
|
||||
@@ -520,7 +528,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile)
|
||||
|
||||
if (snd_BUG_ON(!rfile))
|
||||
return -ENXIO;
|
||||
|
||||
|
||||
rmidi = rfile->rmidi;
|
||||
rawmidi_release_priv(rfile);
|
||||
module_put(rmidi->card->module);
|
||||
@@ -548,7 +556,7 @@ static int snd_rawmidi_info(struct snd_rawmidi_substream *substream,
|
||||
struct snd_rawmidi_info *info)
|
||||
{
|
||||
struct snd_rawmidi *rmidi;
|
||||
|
||||
|
||||
if (substream == NULL)
|
||||
return -ENODEV;
|
||||
rmidi = substream->rmidi;
|
||||
@@ -568,11 +576,13 @@ static int snd_rawmidi_info(struct snd_rawmidi_substream *substream,
|
||||
}
|
||||
|
||||
static int snd_rawmidi_info_user(struct snd_rawmidi_substream *substream,
|
||||
struct snd_rawmidi_info __user * _info)
|
||||
struct snd_rawmidi_info __user *_info)
|
||||
{
|
||||
struct snd_rawmidi_info info;
|
||||
int err;
|
||||
if ((err = snd_rawmidi_info(substream, &info)) < 0)
|
||||
|
||||
err = snd_rawmidi_info(substream, &info);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
|
||||
return -EFAULT;
|
||||
@@ -619,85 +629,68 @@ static int snd_rawmidi_info_select_user(struct snd_card *card,
|
||||
{
|
||||
int err;
|
||||
struct snd_rawmidi_info info;
|
||||
|
||||
if (get_user(info.device, &_info->device))
|
||||
return -EFAULT;
|
||||
if (get_user(info.stream, &_info->stream))
|
||||
return -EFAULT;
|
||||
if (get_user(info.subdevice, &_info->subdevice))
|
||||
return -EFAULT;
|
||||
if ((err = snd_rawmidi_info_select(card, &info)) < 0)
|
||||
err = snd_rawmidi_info_select(card, &info);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
|
||||
struct snd_rawmidi_params * params)
|
||||
static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime,
|
||||
struct snd_rawmidi_params *params,
|
||||
bool is_input)
|
||||
{
|
||||
char *newbuf, *oldbuf;
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
if (substream->append && substream->use_count > 1)
|
||||
return -EBUSY;
|
||||
snd_rawmidi_drain_output(substream);
|
||||
if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
|
||||
|
||||
if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L)
|
||||
return -EINVAL;
|
||||
}
|
||||
if (params->avail_min < 1 || params->avail_min > params->buffer_size) {
|
||||
if (params->avail_min < 1 || params->avail_min > params->buffer_size)
|
||||
return -EINVAL;
|
||||
}
|
||||
if (params->buffer_size != runtime->buffer_size) {
|
||||
newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
|
||||
newbuf = kvmalloc(params->buffer_size, GFP_KERNEL);
|
||||
if (!newbuf)
|
||||
return -ENOMEM;
|
||||
spin_lock_irq(&runtime->lock);
|
||||
oldbuf = runtime->buffer;
|
||||
runtime->buffer = newbuf;
|
||||
runtime->buffer_size = params->buffer_size;
|
||||
runtime->avail = runtime->buffer_size;
|
||||
runtime->appl_ptr = runtime->hw_ptr = 0;
|
||||
__reset_runtime_ptrs(runtime, is_input);
|
||||
spin_unlock_irq(&runtime->lock);
|
||||
kfree(oldbuf);
|
||||
kvfree(oldbuf);
|
||||
}
|
||||
runtime->avail_min = params->avail_min;
|
||||
substream->active_sensing = !params->no_active_sensing;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
|
||||
struct snd_rawmidi_params *params)
|
||||
{
|
||||
if (substream->append && substream->use_count > 1)
|
||||
return -EBUSY;
|
||||
snd_rawmidi_drain_output(substream);
|
||||
substream->active_sensing = !params->no_active_sensing;
|
||||
return resize_runtime_buffer(substream->runtime, params, false);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_rawmidi_output_params);
|
||||
|
||||
int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
|
||||
struct snd_rawmidi_params * params)
|
||||
struct snd_rawmidi_params *params)
|
||||
{
|
||||
char *newbuf, *oldbuf;
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
snd_rawmidi_drain_input(substream);
|
||||
if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (params->avail_min < 1 || params->avail_min > params->buffer_size) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (params->buffer_size != runtime->buffer_size) {
|
||||
newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
|
||||
if (!newbuf)
|
||||
return -ENOMEM;
|
||||
spin_lock_irq(&runtime->lock);
|
||||
oldbuf = runtime->buffer;
|
||||
runtime->buffer = newbuf;
|
||||
runtime->buffer_size = params->buffer_size;
|
||||
runtime->appl_ptr = runtime->hw_ptr = 0;
|
||||
spin_unlock_irq(&runtime->lock);
|
||||
kfree(oldbuf);
|
||||
}
|
||||
runtime->avail_min = params->avail_min;
|
||||
return 0;
|
||||
return resize_runtime_buffer(substream->runtime, params, true);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_rawmidi_input_params);
|
||||
|
||||
static int snd_rawmidi_output_status(struct snd_rawmidi_substream *substream,
|
||||
struct snd_rawmidi_status * status)
|
||||
struct snd_rawmidi_status *status)
|
||||
{
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
@@ -710,7 +703,7 @@ static int snd_rawmidi_output_status(struct snd_rawmidi_substream *substream,
|
||||
}
|
||||
|
||||
static int snd_rawmidi_input_status(struct snd_rawmidi_substream *substream,
|
||||
struct snd_rawmidi_status * status)
|
||||
struct snd_rawmidi_status *status)
|
||||
{
|
||||
struct snd_rawmidi_runtime *runtime = substream->runtime;
|
||||
|
||||
@@ -739,6 +732,7 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long
|
||||
{
|
||||
int stream;
|
||||
struct snd_rawmidi_info __user *info = argp;
|
||||
|
||||
if (get_user(stream, &info->stream))
|
||||
return -EFAULT;
|
||||
switch (stream) {
|
||||
@@ -753,6 +747,7 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long
|
||||
case SNDRV_RAWMIDI_IOCTL_PARAMS:
|
||||
{
|
||||
struct snd_rawmidi_params params;
|
||||
|
||||
if (copy_from_user(¶ms, argp, sizeof(struct snd_rawmidi_params)))
|
||||
return -EFAULT;
|
||||
switch (params.stream) {
|
||||
@@ -772,6 +767,7 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long
|
||||
{
|
||||
int err = 0;
|
||||
struct snd_rawmidi_status status;
|
||||
|
||||
if (copy_from_user(&status, argp, sizeof(struct snd_rawmidi_status)))
|
||||
return -EFAULT;
|
||||
switch (status.stream) {
|
||||
@@ -797,6 +793,7 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long
|
||||
case SNDRV_RAWMIDI_IOCTL_DROP:
|
||||
{
|
||||
int val;
|
||||
|
||||
if (get_user(val, (int __user *) argp))
|
||||
return -EFAULT;
|
||||
switch (val) {
|
||||
@@ -811,6 +808,7 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long
|
||||
case SNDRV_RAWMIDI_IOCTL_DRAIN:
|
||||
{
|
||||
int val;
|
||||
|
||||
if (get_user(val, (int __user *) argp))
|
||||
return -EFAULT;
|
||||
switch (val) {
|
||||
@@ -844,7 +842,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
|
||||
case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE:
|
||||
{
|
||||
int device;
|
||||
|
||||
|
||||
if (get_user(device, (int __user *)argp))
|
||||
return -EFAULT;
|
||||
if (device >= SNDRV_RAWMIDI_DEVICES) /* next device is -1 */
|
||||
@@ -866,7 +864,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
|
||||
case SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE:
|
||||
{
|
||||
int val;
|
||||
|
||||
|
||||
if (get_user(val, (int __user *)argp))
|
||||
return -EFAULT;
|
||||
control->preferred_subdevice[SND_CTL_SUBDEV_RAWMIDI] = val;
|
||||
@@ -1020,6 +1018,7 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
|
||||
spin_lock_irq(&runtime->lock);
|
||||
while (!snd_rawmidi_ready(substream)) {
|
||||
wait_queue_entry_t wait;
|
||||
|
||||
if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
|
||||
spin_unlock_irq(&runtime->lock);
|
||||
return result > 0 ? result : -EAGAIN;
|
||||
@@ -1072,7 +1071,7 @@ int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream)
|
||||
spin_lock_irqsave(&runtime->lock, flags);
|
||||
result = runtime->avail >= runtime->buffer_size;
|
||||
spin_unlock_irqrestore(&runtime->lock, flags);
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_rawmidi_transmit_empty);
|
||||
|
||||
@@ -1210,7 +1209,7 @@ EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
|
||||
* @substream: the rawmidi substream
|
||||
* @buffer: the buffer pointer
|
||||
* @count: the data size to transfer
|
||||
*
|
||||
*
|
||||
* Copies data from the buffer to the device and advances the pointer.
|
||||
*
|
||||
* Return: The copied size if successful, or a negative error code on failure.
|
||||
@@ -1324,6 +1323,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
|
||||
spin_lock_irq(&runtime->lock);
|
||||
while (!snd_rawmidi_ready_append(substream, count)) {
|
||||
wait_queue_entry_t wait;
|
||||
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
spin_unlock_irq(&runtime->lock);
|
||||
return result > 0 ? result : -EAGAIN;
|
||||
@@ -1357,6 +1357,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
|
||||
while (runtime->avail != runtime->buffer_size) {
|
||||
wait_queue_entry_t wait;
|
||||
unsigned int last_avail = runtime->avail;
|
||||
|
||||
init_waitqueue_entry(&wait, current);
|
||||
add_wait_queue(&runtime->sleep, &wait);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
@@ -1374,7 +1375,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
|
||||
return result;
|
||||
}
|
||||
|
||||
static __poll_t snd_rawmidi_poll(struct file *file, poll_table * wait)
|
||||
static __poll_t snd_rawmidi_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct snd_rawmidi_file *rfile;
|
||||
struct snd_rawmidi_runtime *runtime;
|
||||
@@ -1411,7 +1412,6 @@ static __poll_t snd_rawmidi_poll(struct file *file, poll_table * wait)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
|
||||
@@ -1479,8 +1479,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
|
||||
* Register functions
|
||||
*/
|
||||
|
||||
static const struct file_operations snd_rawmidi_f_ops =
|
||||
{
|
||||
static const struct file_operations snd_rawmidi_f_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = snd_rawmidi_read,
|
||||
.write = snd_rawmidi_write,
|
||||
@@ -1535,7 +1534,7 @@ static void release_rawmidi_device(struct device *dev)
|
||||
*/
|
||||
int snd_rawmidi_new(struct snd_card *card, char *id, int device,
|
||||
int output_count, int input_count,
|
||||
struct snd_rawmidi ** rrawmidi)
|
||||
struct snd_rawmidi **rrawmidi)
|
||||
{
|
||||
struct snd_rawmidi *rmidi;
|
||||
int err;
|
||||
@@ -1566,27 +1565,29 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
|
||||
rmidi->dev.release = release_rawmidi_device;
|
||||
dev_set_name(&rmidi->dev, "midiC%iD%i", card->number, device);
|
||||
|
||||
if ((err = snd_rawmidi_alloc_substreams(rmidi,
|
||||
&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],
|
||||
SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
input_count)) < 0) {
|
||||
snd_rawmidi_free(rmidi);
|
||||
return err;
|
||||
}
|
||||
if ((err = snd_rawmidi_alloc_substreams(rmidi,
|
||||
&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT],
|
||||
SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
output_count)) < 0) {
|
||||
snd_rawmidi_free(rmidi);
|
||||
return err;
|
||||
}
|
||||
if ((err = snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops)) < 0) {
|
||||
snd_rawmidi_free(rmidi);
|
||||
return err;
|
||||
}
|
||||
err = snd_rawmidi_alloc_substreams(rmidi,
|
||||
&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],
|
||||
SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
input_count);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = snd_rawmidi_alloc_substreams(rmidi,
|
||||
&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT],
|
||||
SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
output_count);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
if (rrawmidi)
|
||||
*rrawmidi = rmidi;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_rawmidi_free(rmidi);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_rawmidi_new);
|
||||
|
||||
@@ -1624,6 +1625,7 @@ static int snd_rawmidi_free(struct snd_rawmidi *rmidi)
|
||||
static int snd_rawmidi_dev_free(struct snd_device *device)
|
||||
{
|
||||
struct snd_rawmidi *rmidi = device->device_data;
|
||||
|
||||
return snd_rawmidi_free(rmidi);
|
||||
}
|
||||
|
||||
@@ -1631,6 +1633,7 @@ static int snd_rawmidi_dev_free(struct snd_device *device)
|
||||
static void snd_rawmidi_dev_seq_free(struct snd_seq_device *device)
|
||||
{
|
||||
struct snd_rawmidi *rmidi = device->private_data;
|
||||
|
||||
rmidi->seq_dev = NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -1644,30 +1647,27 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
|
||||
|
||||
if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
|
||||
return -ENOMEM;
|
||||
err = 0;
|
||||
mutex_lock(®ister_mutex);
|
||||
if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
list_add_tail(&rmidi->list, &snd_rawmidi_devices);
|
||||
if (snd_rawmidi_search(rmidi->card, rmidi->device))
|
||||
err = -EBUSY;
|
||||
else
|
||||
list_add_tail(&rmidi->list, &snd_rawmidi_devices);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
|
||||
rmidi->card, rmidi->device,
|
||||
&snd_rawmidi_f_ops, rmidi, &rmidi->dev);
|
||||
if (err < 0) {
|
||||
rmidi_err(rmidi, "unable to register\n");
|
||||
mutex_lock(®ister_mutex);
|
||||
list_del(&rmidi->list);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
goto error;
|
||||
}
|
||||
if (rmidi->ops && rmidi->ops->dev_register &&
|
||||
(err = rmidi->ops->dev_register(rmidi)) < 0) {
|
||||
snd_unregister_device(&rmidi->dev);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_del(&rmidi->list);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
if (rmidi->ops && rmidi->ops->dev_register) {
|
||||
err = rmidi->ops->dev_register(rmidi);
|
||||
if (err < 0)
|
||||
goto error_unregister;
|
||||
}
|
||||
#ifdef CONFIG_SND_OSSEMUL
|
||||
rmidi->ossreg = 0;
|
||||
@@ -1719,6 +1719,14 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
error_unregister:
|
||||
snd_unregister_device(&rmidi->dev);
|
||||
error:
|
||||
mutex_lock(®ister_mutex);
|
||||
list_del(&rmidi->list);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int snd_rawmidi_dev_disconnect(struct snd_device *device)
|
||||
@@ -1732,6 +1740,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
|
||||
list_del_init(&rmidi->list);
|
||||
for (dir = 0; dir < 2; dir++) {
|
||||
struct snd_rawmidi_substream *s;
|
||||
|
||||
list_for_each_entry(s, &rmidi->streams[dir].substreams, list) {
|
||||
if (s->runtime)
|
||||
wake_up(&s->runtime->sleep);
|
||||
@@ -1769,7 +1778,7 @@ void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
|
||||
const struct snd_rawmidi_ops *ops)
|
||||
{
|
||||
struct snd_rawmidi_substream *substream;
|
||||
|
||||
|
||||
list_for_each_entry(substream, &rmidi->streams[stream].substreams, list)
|
||||
substream->ops = ops;
|
||||
}
|
||||
|
@@ -637,7 +637,7 @@ snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, stru
|
||||
|
||||
if ((mdev = get_mididev(dp, dev)) == NULL)
|
||||
return -ENODEV;
|
||||
if (snd_midi_event_encode_byte(mdev->coder, c, ev) > 0) {
|
||||
if (snd_midi_event_encode_byte(mdev->coder, c, ev)) {
|
||||
snd_seq_oss_fill_addr(dp, ev, mdev->client, mdev->port);
|
||||
snd_use_lock_free(&mdev->use_lock);
|
||||
return 0;
|
||||
|
@@ -92,7 +92,7 @@ snd_seq_oss_process_timer_event(struct seq_oss_timer *rec, union evrec *ev)
|
||||
case TMR_WAIT_REL:
|
||||
parm += rec->cur_tick;
|
||||
rec->realtime = 0;
|
||||
/* continue to next */
|
||||
/* fall through and continue to next */
|
||||
case TMR_WAIT_ABS:
|
||||
if (parm == 0) {
|
||||
rec->realtime = 1;
|
||||
|
@@ -84,30 +84,32 @@ static int __init alsa_seq_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = client_init_data()) < 0)
|
||||
goto error;
|
||||
|
||||
/* init memory, room for selected events */
|
||||
if ((err = snd_sequencer_memory_init()) < 0)
|
||||
goto error;
|
||||
|
||||
/* init event queues */
|
||||
if ((err = snd_seq_queues_init()) < 0)
|
||||
err = client_init_data();
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* register sequencer device */
|
||||
if ((err = snd_sequencer_device_init()) < 0)
|
||||
err = snd_sequencer_device_init();
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* register proc interface */
|
||||
if ((err = snd_seq_info_init()) < 0)
|
||||
goto error;
|
||||
err = snd_seq_info_init();
|
||||
if (err < 0)
|
||||
goto error_device;
|
||||
|
||||
/* register our internal client */
|
||||
if ((err = snd_seq_system_client_init()) < 0)
|
||||
goto error;
|
||||
err = snd_seq_system_client_init();
|
||||
if (err < 0)
|
||||
goto error_info;
|
||||
|
||||
snd_seq_autoload_init();
|
||||
return 0;
|
||||
|
||||
error_info:
|
||||
snd_seq_info_done();
|
||||
error_device:
|
||||
snd_sequencer_device_done();
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
@@ -126,9 +128,6 @@ static void __exit alsa_seq_exit(void)
|
||||
/* unregister sequencer device */
|
||||
snd_sequencer_device_done();
|
||||
|
||||
/* release event memory */
|
||||
snd_sequencer_memory_done();
|
||||
|
||||
snd_seq_autoload_exit();
|
||||
}
|
||||
|
||||
|
@@ -311,10 +311,9 @@ static int snd_seq_open(struct inode *inode, struct file *file)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (mutex_lock_interruptible(®ister_mutex))
|
||||
return -ERESTARTSYS;
|
||||
mutex_lock(®ister_mutex);
|
||||
client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
|
||||
if (client == NULL) {
|
||||
if (!client) {
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENOMEM; /* failure code */
|
||||
}
|
||||
@@ -1704,10 +1703,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
|
||||
if (queue == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(&queue->timer_mutex)) {
|
||||
queuefree(queue);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
mutex_lock(&queue->timer_mutex);
|
||||
tmr = queue->timer;
|
||||
memset(timer, 0, sizeof(*timer));
|
||||
timer->queue = queue->queue;
|
||||
@@ -1741,10 +1737,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
|
||||
q = queueptr(timer->queue);
|
||||
if (q == NULL)
|
||||
return -ENXIO;
|
||||
if (mutex_lock_interruptible(&q->timer_mutex)) {
|
||||
queuefree(q);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
mutex_lock(&q->timer_mutex);
|
||||
tmr = q->timer;
|
||||
snd_seq_queue_timer_close(timer->queue);
|
||||
tmr->type = timer->type;
|
||||
@@ -2180,8 +2173,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
|
||||
if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS)
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(®ister_mutex))
|
||||
return -ERESTARTSYS;
|
||||
mutex_lock(®ister_mutex);
|
||||
|
||||
if (card) {
|
||||
client_index += SNDRV_SEQ_GLOBAL_CLIENTS
|
||||
@@ -2522,19 +2514,15 @@ int __init snd_sequencer_device_init(void)
|
||||
snd_device_initialize(&seq_dev, NULL);
|
||||
dev_set_name(&seq_dev, "seq");
|
||||
|
||||
if (mutex_lock_interruptible(®ister_mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
mutex_lock(®ister_mutex);
|
||||
err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
|
||||
&snd_seq_f_ops, NULL, &seq_dev);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (err < 0) {
|
||||
mutex_unlock(®ister_mutex);
|
||||
put_device(&seq_dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
mutex_unlock(®ister_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2543,7 +2531,7 @@ int __init snd_sequencer_device_init(void)
|
||||
/*
|
||||
* unregister sequencer device
|
||||
*/
|
||||
void __exit snd_sequencer_device_done(void)
|
||||
void snd_sequencer_device_done(void)
|
||||
{
|
||||
snd_unregister_device(&seq_dev);
|
||||
put_device(&seq_dev);
|
||||
|
@@ -50,7 +50,7 @@ create_info_entry(char *name, void (*read)(struct snd_info_entry *,
|
||||
return entry;
|
||||
}
|
||||
|
||||
static void free_info_entries(void)
|
||||
void snd_seq_info_done(void)
|
||||
{
|
||||
snd_info_free_entry(queues_entry);
|
||||
snd_info_free_entry(clients_entry);
|
||||
@@ -70,12 +70,6 @@ int __init snd_seq_info_init(void)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free_info_entries();
|
||||
snd_seq_info_done();
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int __exit snd_seq_info_done(void)
|
||||
{
|
||||
free_info_entries();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -30,11 +30,11 @@ void snd_seq_info_queues_read(struct snd_info_entry *entry, struct snd_info_buff
|
||||
|
||||
|
||||
#ifdef CONFIG_SND_PROC_FS
|
||||
int snd_seq_info_init( void );
|
||||
int snd_seq_info_done( void );
|
||||
int snd_seq_info_init(void);
|
||||
void snd_seq_info_done(void);
|
||||
#else
|
||||
static inline int snd_seq_info_init(void) { return 0; }
|
||||
static inline int snd_seq_info_done(void) { return 0; }
|
||||
static inline void snd_seq_info_done(void) {}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -504,18 +504,6 @@ int snd_seq_pool_delete(struct snd_seq_pool **ppool)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialize sequencer memory */
|
||||
int __init snd_sequencer_memory_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* release sequencer memory */
|
||||
void __exit snd_sequencer_memory_done(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* exported to seq_clientmgr.c */
|
||||
void snd_seq_info_pool(struct snd_info_buffer *buffer,
|
||||
struct snd_seq_pool *pool, char *space)
|
||||
|
@@ -94,12 +94,6 @@ struct snd_seq_pool *snd_seq_pool_new(int poolsize);
|
||||
/* remove pool */
|
||||
int snd_seq_pool_delete(struct snd_seq_pool **pool);
|
||||
|
||||
/* init memory */
|
||||
int snd_sequencer_memory_init(void);
|
||||
|
||||
/* release event memory */
|
||||
void snd_sequencer_memory_done(void);
|
||||
|
||||
/* polling */
|
||||
int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file, poll_table *wait);
|
||||
|
||||
|
@@ -78,7 +78,7 @@ static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
|
||||
struct seq_midisynth *msynth;
|
||||
struct snd_seq_event ev;
|
||||
char buf[16], *pbuf;
|
||||
long res, count;
|
||||
long res;
|
||||
|
||||
if (substream == NULL)
|
||||
return;
|
||||
@@ -94,19 +94,15 @@ static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
|
||||
if (msynth->parser == NULL)
|
||||
continue;
|
||||
pbuf = buf;
|
||||
while (res > 0) {
|
||||
count = snd_midi_event_encode(msynth->parser, pbuf, res, &ev);
|
||||
if (count < 0)
|
||||
break;
|
||||
pbuf += count;
|
||||
res -= count;
|
||||
if (ev.type != SNDRV_SEQ_EVENT_NONE) {
|
||||
ev.source.port = msynth->seq_port;
|
||||
ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
|
||||
snd_seq_kernel_client_dispatch(msynth->seq_client, &ev, 1, 0);
|
||||
/* clear event and reset header */
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
}
|
||||
while (res-- > 0) {
|
||||
if (!snd_midi_event_encode_byte(msynth->parser,
|
||||
*pbuf++, &ev))
|
||||
continue;
|
||||
ev.source.port = msynth->seq_port;
|
||||
ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
|
||||
snd_seq_kernel_client_dispatch(msynth->seq_client, &ev, 1, 0);
|
||||
/* clear event and reset header */
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -318,7 +318,7 @@ do_control(struct snd_midi_op *ops, void *drv, struct snd_midi_channel_set *chse
|
||||
break;
|
||||
case MIDI_CTL_MSB_DATA_ENTRY:
|
||||
chan->control[MIDI_CTL_LSB_DATA_ENTRY] = 0;
|
||||
/* go through here */
|
||||
/* fall through */
|
||||
case MIDI_CTL_LSB_DATA_ENTRY:
|
||||
if (chan->param_type == SNDRV_MIDI_PARAM_TYPE_REGISTERED)
|
||||
rpn(ops, drv, chan, chset);
|
||||
@@ -728,15 +728,3 @@ void snd_midi_channel_free_set(struct snd_midi_channel_set *chset)
|
||||
kfree(chset);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_midi_channel_free_set);
|
||||
|
||||
static int __init alsa_seq_midi_emul_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_seq_midi_emul_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_seq_midi_emul_init)
|
||||
module_exit(alsa_seq_midi_emul_exit)
|
||||
|
@@ -175,84 +175,23 @@ void snd_midi_event_reset_decode(struct snd_midi_event *dev)
|
||||
}
|
||||
EXPORT_SYMBOL(snd_midi_event_reset_decode);
|
||||
|
||||
#if 0
|
||||
void snd_midi_event_init(struct snd_midi_event *dev)
|
||||
{
|
||||
snd_midi_event_reset_encode(dev);
|
||||
snd_midi_event_reset_decode(dev);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
void snd_midi_event_no_status(struct snd_midi_event *dev, int on)
|
||||
{
|
||||
dev->nostat = on ? 1 : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_midi_event_no_status);
|
||||
|
||||
/*
|
||||
* resize buffer
|
||||
*/
|
||||
#if 0
|
||||
int snd_midi_event_resize_buffer(struct snd_midi_event *dev, int bufsize)
|
||||
{
|
||||
unsigned char *new_buf, *old_buf;
|
||||
unsigned long flags;
|
||||
|
||||
if (bufsize == dev->bufsize)
|
||||
return 0;
|
||||
new_buf = kmalloc(bufsize, GFP_KERNEL);
|
||||
if (new_buf == NULL)
|
||||
return -ENOMEM;
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
old_buf = dev->buf;
|
||||
dev->buf = new_buf;
|
||||
dev->bufsize = bufsize;
|
||||
reset_encode(dev);
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
kfree(old_buf);
|
||||
return 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/*
|
||||
* read bytes and encode to sequencer event if finished
|
||||
* return the size of encoded bytes
|
||||
*/
|
||||
long snd_midi_event_encode(struct snd_midi_event *dev, unsigned char *buf, long count,
|
||||
struct snd_seq_event *ev)
|
||||
{
|
||||
long result = 0;
|
||||
int rc;
|
||||
|
||||
ev->type = SNDRV_SEQ_EVENT_NONE;
|
||||
|
||||
while (count-- > 0) {
|
||||
rc = snd_midi_event_encode_byte(dev, *buf++, ev);
|
||||
result++;
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
else if (rc > 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_midi_event_encode);
|
||||
|
||||
/*
|
||||
* read one byte and encode to sequencer event:
|
||||
* return 1 if MIDI bytes are encoded to an event
|
||||
* 0 data is not finished
|
||||
* negative for error
|
||||
* return true if MIDI bytes are encoded to an event
|
||||
* false data is not finished
|
||||
*/
|
||||
int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
|
||||
struct snd_seq_event *ev)
|
||||
bool snd_midi_event_encode_byte(struct snd_midi_event *dev, unsigned char c,
|
||||
struct snd_seq_event *ev)
|
||||
{
|
||||
int rc = 0;
|
||||
bool rc = false;
|
||||
unsigned long flags;
|
||||
|
||||
c &= 0xff;
|
||||
|
||||
if (c >= MIDI_CMD_COMMON_CLOCK) {
|
||||
/* real-time event */
|
||||
ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
|
||||
@@ -293,7 +232,7 @@ int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
|
||||
status_event[dev->type].encode(dev, ev);
|
||||
if (dev->type >= ST_SPECIAL)
|
||||
dev->type = ST_INVALID;
|
||||
rc = 1;
|
||||
rc = true;
|
||||
} else if (dev->type == ST_SYSEX) {
|
||||
if (c == MIDI_CMD_COMMON_SYSEX_END ||
|
||||
dev->read >= dev->bufsize) {
|
||||
@@ -306,7 +245,7 @@ int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
|
||||
dev->read = 0; /* continue to parse */
|
||||
else
|
||||
reset_encode(dev); /* all parsed */
|
||||
rc = 1;
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,15 +470,3 @@ static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf,
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int __init alsa_seq_midi_event_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_seq_midi_event_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_seq_midi_event_init)
|
||||
module_exit(alsa_seq_midi_event_exit)
|
||||
|
@@ -159,18 +159,8 @@ static void queue_delete(struct snd_seq_queue *q)
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* setup queues */
|
||||
int __init snd_seq_queues_init(void)
|
||||
{
|
||||
/*
|
||||
memset(queue_list, 0, sizeof(queue_list));
|
||||
num_queues = 0;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* delete all existing queues */
|
||||
void __exit snd_seq_queues_delete(void)
|
||||
void snd_seq_queues_delete(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@@ -63,9 +63,6 @@ struct snd_seq_queue {
|
||||
/* get the number of current queues */
|
||||
int snd_seq_queue_get_cur_queues(void);
|
||||
|
||||
/* init queues structure */
|
||||
int snd_seq_queues_init(void);
|
||||
|
||||
/* delete queues */
|
||||
void snd_seq_queues_delete(void);
|
||||
|
||||
@@ -112,28 +109,4 @@ int snd_seq_queue_is_used(int queueid, int client);
|
||||
|
||||
int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop);
|
||||
|
||||
/*
|
||||
* 64bit division - for sync stuff..
|
||||
*/
|
||||
#if defined(i386) || defined(i486)
|
||||
|
||||
#define udiv_qrnnd(q, r, n1, n0, d) \
|
||||
__asm__ ("divl %4" \
|
||||
: "=a" ((u32)(q)), \
|
||||
"=d" ((u32)(r)) \
|
||||
: "0" ((u32)(n0)), \
|
||||
"1" ((u32)(n1)), \
|
||||
"rm" ((u32)(d)))
|
||||
|
||||
#define u64_div(x,y,q) do {u32 __tmp; udiv_qrnnd(q, __tmp, (x)>>32, x, y);} while (0)
|
||||
#define u64_mod(x,y,r) do {u32 __tmp; udiv_qrnnd(__tmp, q, (x)>>32, x, y);} while (0)
|
||||
#define u64_divmod(x,y,q,r) udiv_qrnnd(q, r, (x)>>32, x, y)
|
||||
|
||||
#else
|
||||
#define u64_div(x,y,q) ((q) = (u32)((u64)(x) / (u64)(y)))
|
||||
#define u64_mod(x,y,r) ((r) = (u32)((u64)(x) % (u64)(y)))
|
||||
#define u64_divmod(x,y,q,r) (u64_div(x,y,q), u64_mod(x,y,r))
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -89,7 +89,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
|
||||
else
|
||||
down_read(&rdev->filelist_sem);
|
||||
list_for_each_entry(vmidi, &rdev->filelist, list) {
|
||||
if (!vmidi->trigger)
|
||||
if (!READ_ONCE(vmidi->trigger))
|
||||
continue;
|
||||
if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
|
||||
if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
|
||||
@@ -109,23 +109,6 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* receive an event from the remote virmidi port
|
||||
*
|
||||
* for rawmidi inputs, you can call this function from the event
|
||||
* handler of a remote port which is attached to the virmidi via
|
||||
* SNDRV_VIRMIDI_SEQ_ATTACH.
|
||||
*/
|
||||
#if 0
|
||||
int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct snd_seq_event *ev)
|
||||
{
|
||||
struct snd_virmidi_dev *rdev;
|
||||
|
||||
rdev = rmidi->private_data;
|
||||
return snd_virmidi_dev_receive_event(rdev, ev, true);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/*
|
||||
* event handler of virmidi port
|
||||
*/
|
||||
@@ -147,10 +130,46 @@ static void snd_virmidi_input_trigger(struct snd_rawmidi_substream *substream, i
|
||||
{
|
||||
struct snd_virmidi *vmidi = substream->runtime->private_data;
|
||||
|
||||
if (up) {
|
||||
vmidi->trigger = 1;
|
||||
} else {
|
||||
vmidi->trigger = 0;
|
||||
WRITE_ONCE(vmidi->trigger, !!up);
|
||||
}
|
||||
|
||||
/* process rawmidi bytes and send events;
|
||||
* we need no lock here for vmidi->event since it's handled only in this work
|
||||
*/
|
||||
static void snd_vmidi_output_work(struct work_struct *work)
|
||||
{
|
||||
struct snd_virmidi *vmidi;
|
||||
struct snd_rawmidi_substream *substream;
|
||||
unsigned char input;
|
||||
int ret;
|
||||
|
||||
vmidi = container_of(work, struct snd_virmidi, output_work);
|
||||
substream = vmidi->substream;
|
||||
|
||||
/* discard the outputs in dispatch mode unless subscribed */
|
||||
if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH &&
|
||||
!(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) {
|
||||
while (!snd_rawmidi_transmit_empty(substream))
|
||||
snd_rawmidi_transmit_ack(substream, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
while (READ_ONCE(vmidi->trigger)) {
|
||||
if (snd_rawmidi_transmit(substream, &input, 1) != 1)
|
||||
break;
|
||||
if (!snd_midi_event_encode_byte(vmidi->parser, input,
|
||||
&vmidi->event))
|
||||
continue;
|
||||
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
|
||||
ret = snd_seq_kernel_client_dispatch(vmidi->client,
|
||||
&vmidi->event,
|
||||
false, 0);
|
||||
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
/* rawmidi input might be huge, allow to have a break */
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,62 +179,10 @@ static void snd_virmidi_input_trigger(struct snd_rawmidi_substream *substream, i
|
||||
static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
|
||||
{
|
||||
struct snd_virmidi *vmidi = substream->runtime->private_data;
|
||||
int count, res;
|
||||
unsigned char buf[32], *pbuf;
|
||||
unsigned long flags;
|
||||
bool check_resched = !in_atomic();
|
||||
|
||||
if (up) {
|
||||
vmidi->trigger = 1;
|
||||
if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH &&
|
||||
!(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) {
|
||||
while (snd_rawmidi_transmit(substream, buf,
|
||||
sizeof(buf)) > 0) {
|
||||
/* ignored */
|
||||
}
|
||||
return;
|
||||
}
|
||||
spin_lock_irqsave(&substream->runtime->lock, flags);
|
||||
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
|
||||
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
|
||||
goto out;
|
||||
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
|
||||
}
|
||||
while (1) {
|
||||
count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
|
||||
if (count <= 0)
|
||||
break;
|
||||
pbuf = buf;
|
||||
while (count > 0) {
|
||||
res = snd_midi_event_encode(vmidi->parser, pbuf, count, &vmidi->event);
|
||||
if (res < 0) {
|
||||
snd_midi_event_reset_encode(vmidi->parser);
|
||||
continue;
|
||||
}
|
||||
__snd_rawmidi_transmit_ack(substream, res);
|
||||
pbuf += res;
|
||||
count -= res;
|
||||
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
|
||||
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
|
||||
goto out;
|
||||
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
|
||||
}
|
||||
}
|
||||
if (!check_resched)
|
||||
continue;
|
||||
/* do temporary unlock & cond_resched() for avoiding
|
||||
* CPU soft lockup, which may happen via a write from
|
||||
* a huge rawmidi buffer
|
||||
*/
|
||||
spin_unlock_irqrestore(&substream->runtime->lock, flags);
|
||||
cond_resched();
|
||||
spin_lock_irqsave(&substream->runtime->lock, flags);
|
||||
}
|
||||
out:
|
||||
spin_unlock_irqrestore(&substream->runtime->lock, flags);
|
||||
} else {
|
||||
vmidi->trigger = 0;
|
||||
}
|
||||
WRITE_ONCE(vmidi->trigger, !!up);
|
||||
if (up)
|
||||
queue_work(system_highpri_wq, &vmidi->output_work);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -270,6 +237,7 @@ static int snd_virmidi_output_open(struct snd_rawmidi_substream *substream)
|
||||
vmidi->port = rdev->port;
|
||||
snd_virmidi_init_event(vmidi, &vmidi->event);
|
||||
vmidi->rdev = rdev;
|
||||
INIT_WORK(&vmidi->output_work, snd_vmidi_output_work);
|
||||
runtime->private_data = vmidi;
|
||||
return 0;
|
||||
}
|
||||
@@ -299,6 +267,9 @@ static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream)
|
||||
static int snd_virmidi_output_close(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct snd_virmidi *vmidi = substream->runtime->private_data;
|
||||
|
||||
WRITE_ONCE(vmidi->trigger, false); /* to be sure */
|
||||
cancel_work_sync(&vmidi->output_work);
|
||||
snd_midi_event_free(vmidi->parser);
|
||||
substream->runtime->private_data = NULL;
|
||||
kfree(vmidi);
|
||||
@@ -556,19 +527,3 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_virmidi_new);
|
||||
|
||||
/*
|
||||
* ENTRY functions
|
||||
*/
|
||||
|
||||
static int __init alsa_virmidi_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_virmidi_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_virmidi_init)
|
||||
module_exit(alsa_virmidi_exit)
|
||||
|
@@ -883,6 +883,11 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
|
||||
|
||||
if (snd_BUG_ON(!tid))
|
||||
return -EINVAL;
|
||||
if (tid->dev_class == SNDRV_TIMER_CLASS_CARD ||
|
||||
tid->dev_class == SNDRV_TIMER_CLASS_PCM) {
|
||||
if (WARN_ON(!card))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (rtimer)
|
||||
*rtimer = NULL;
|
||||
timer = kzalloc(sizeof(*timer), GFP_KERNEL);
|
||||
|
@@ -778,7 +778,6 @@ static const struct snd_pcm_ops loopback_pcm_ops = {
|
||||
.trigger = loopback_trigger,
|
||||
.pointer = loopback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
static int loopback_pcm_new(struct loopback *loopback,
|
||||
|
@@ -617,19 +617,3 @@ free_device:
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_mpu401_uart_new);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_mpu401_uart_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_mpu401_uart_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_mpu401_uart_init)
|
||||
module_exit(alsa_mpu401_uart_exit)
|
||||
|
@@ -21,8 +21,6 @@
|
||||
|
||||
#include "opl3_voice.h"
|
||||
|
||||
extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
|
||||
|
||||
static char snd_opl3_drum_table[47] =
|
||||
{
|
||||
OPL3_BASSDRUM_ON, OPL3_BASSDRUM_ON, OPL3_HIHAT_ON, /* 35 - 37 */
|
||||
|
@@ -31,13 +31,12 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <sound/minors.h>
|
||||
#include "opl3_voice.h"
|
||||
|
||||
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Hannu Savolainen 1993-1996, Rob Hooft");
|
||||
MODULE_DESCRIPTION("Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
|
||||
|
||||
static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -539,19 +538,3 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_opl3_hwdep_new);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_opl3_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_opl3_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_opl3_init)
|
||||
module_exit(alsa_opl3_exit)
|
||||
|
@@ -25,10 +25,6 @@
|
||||
#include "opl3_voice.h"
|
||||
#include <sound/asoundef.h>
|
||||
|
||||
extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
|
||||
|
||||
extern bool use_internal_drums;
|
||||
|
||||
static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
|
||||
struct snd_midi_channel *chan);
|
||||
/*
|
||||
@@ -372,6 +368,7 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
|
||||
instr_4op = 1;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
spin_unlock_irqrestore(&opl3->voice_lock, flags);
|
||||
return;
|
||||
@@ -721,9 +718,6 @@ void snd_opl3_note_off(void *p, int note, int vel,
|
||||
*/
|
||||
void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
|
||||
{
|
||||
struct snd_opl3 *opl3;
|
||||
|
||||
opl3 = p;
|
||||
#ifdef DEBUG_MIDI
|
||||
snd_printk(KERN_DEBUG "Key pressure, ch#: %i, inst#: %i\n",
|
||||
chan->number, chan->midi_program);
|
||||
@@ -735,9 +729,6 @@ void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *cha
|
||||
*/
|
||||
void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan)
|
||||
{
|
||||
struct snd_opl3 *opl3;
|
||||
|
||||
opl3 = p;
|
||||
#ifdef DEBUG_MIDI
|
||||
snd_printk(KERN_DEBUG "Terminate note, ch#: %i, inst#: %i\n",
|
||||
chan->number, chan->midi_program);
|
||||
@@ -861,9 +852,6 @@ void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
|
||||
void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan,
|
||||
struct snd_midi_channel_set *chset)
|
||||
{
|
||||
struct snd_opl3 *opl3;
|
||||
|
||||
opl3 = p;
|
||||
#ifdef DEBUG_MIDI
|
||||
snd_printk(KERN_DEBUG "NRPN, ch#: %i, inst#: %i\n",
|
||||
chan->number, chan->midi_program);
|
||||
@@ -876,9 +864,6 @@ void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan,
|
||||
void snd_opl3_sysex(void *p, unsigned char *buf, int len,
|
||||
int parsed, struct snd_midi_channel_set *chset)
|
||||
{
|
||||
struct snd_opl3 *opl3;
|
||||
|
||||
opl3 = p;
|
||||
#ifdef DEBUG_MIDI
|
||||
snd_printk(KERN_DEBUG "SYSEX\n");
|
||||
#endif
|
||||
|
@@ -29,8 +29,6 @@ static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg);
|
||||
|
||||
/* operators */
|
||||
|
||||
extern struct snd_midi_op opl3_ops;
|
||||
|
||||
static struct snd_seq_oss_callback oss_callback = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = snd_opl3_open_seq_oss,
|
||||
@@ -233,11 +231,8 @@ static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
|
||||
static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
|
||||
unsigned long ioarg)
|
||||
{
|
||||
struct snd_opl3 *opl3;
|
||||
|
||||
if (snd_BUG_ON(!arg))
|
||||
return -ENXIO;
|
||||
opl3 = arg->private_data;
|
||||
switch (cmd) {
|
||||
case SNDCTL_FM_LOAD_INSTR:
|
||||
snd_printk(KERN_ERR "OPL3: "
|
||||
@@ -261,11 +256,8 @@ static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
|
||||
/* reset device */
|
||||
static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg)
|
||||
{
|
||||
struct snd_opl3 *opl3;
|
||||
|
||||
if (snd_BUG_ON(!arg))
|
||||
return -ENXIO;
|
||||
opl3 = arg->private_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <linux/nospec.h>
|
||||
#include <sound/opl3.h>
|
||||
#include <sound/asound_fm.h>
|
||||
#include "opl3_voice.h"
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SEQUENCER)
|
||||
#define OPL3_SUPPORT_SYNTH
|
||||
|
@@ -52,4 +52,8 @@ void snd_opl3_free_seq_oss(struct snd_opl3 *opl3);
|
||||
#define snd_opl3_free_seq_oss(opl3) /* NOP */
|
||||
#endif
|
||||
|
||||
extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
|
||||
extern bool use_internal_drums;
|
||||
extern struct snd_midi_op opl3_ops;
|
||||
|
||||
#endif
|
||||
|
@@ -263,15 +263,3 @@ int snd_opl4_create(struct snd_card *card,
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_opl4_create);
|
||||
|
||||
static int __init alsa_opl4_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_opl4_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_opl4_init)
|
||||
module_exit(alsa_opl4_exit)
|
||||
|
@@ -815,18 +815,3 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_vx_create);
|
||||
|
||||
/*
|
||||
* module entries
|
||||
*/
|
||||
static int __init alsa_vx_core_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_vx_core_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_vx_core_init)
|
||||
module_exit(alsa_vx_core_exit)
|
||||
|
@@ -883,7 +883,6 @@ static const struct snd_pcm_ops vx_pcm_playback_ops = {
|
||||
.trigger = vx_pcm_trigger,
|
||||
.pointer = vx_pcm_playback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
|
||||
@@ -1105,7 +1104,6 @@ static const struct snd_pcm_ops vx_pcm_capture_ops = {
|
||||
.trigger = vx_pcm_trigger,
|
||||
.pointer = vx_pcm_capture_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
|
||||
|
@@ -373,7 +373,6 @@ int snd_bebob_create_pcm_devices(struct snd_bebob *bebob)
|
||||
.pointer = pcm_playback_pointer,
|
||||
.ack = pcm_playback_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
@@ -412,7 +412,6 @@ int snd_dice_create_pcm(struct snd_dice *dice)
|
||||
.pointer = capture_pointer,
|
||||
.ack = capture_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
static const struct snd_pcm_ops playback_ops = {
|
||||
.open = pcm_open,
|
||||
@@ -425,7 +424,6 @@ int snd_dice_create_pcm(struct snd_dice *dice)
|
||||
.pointer = playback_pointer,
|
||||
.ack = playback_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
unsigned int capture, playback;
|
||||
|
@@ -352,7 +352,6 @@ int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x)
|
||||
.pointer = pcm_playback_pointer,
|
||||
.ack = pcm_playback_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
@@ -383,7 +383,6 @@ int snd_ff_create_pcm_devices(struct snd_ff *ff)
|
||||
.pointer = pcm_playback_pointer,
|
||||
.ack = pcm_playback_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
@@ -397,7 +397,6 @@ int snd_efw_create_pcm_devices(struct snd_efw *efw)
|
||||
.pointer = pcm_playback_pointer,
|
||||
.ack = pcm_playback_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
@@ -454,7 +454,6 @@ static int isight_create_pcm(struct isight *isight)
|
||||
.trigger = isight_trigger,
|
||||
.pointer = isight_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
@@ -363,7 +363,6 @@ int snd_motu_create_pcm_devices(struct snd_motu *motu)
|
||||
.pointer = capture_pointer,
|
||||
.ack = capture_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
static const struct snd_pcm_ops playback_ops = {
|
||||
.open = pcm_open,
|
||||
@@ -376,7 +375,6 @@ int snd_motu_create_pcm_devices(struct snd_motu *motu)
|
||||
.pointer = playback_pointer,
|
||||
.ack = playback_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
@@ -13,6 +13,8 @@
|
||||
#define V2_CLOCK_RATE_SHIFT 3
|
||||
#define V2_CLOCK_SRC_MASK 0x00000007
|
||||
#define V2_CLOCK_SRC_SHIFT 0
|
||||
#define V2_CLOCK_TRAVELER_FETCH_DISABLE 0x04000000
|
||||
#define V2_CLOCK_TRAVELER_FETCH_ENABLE 0x03000000
|
||||
|
||||
#define V2_IN_OUT_CONF_OFFSET 0x0c04
|
||||
#define V2_OPT_OUT_IFACE_MASK 0x00000c00
|
||||
@@ -66,6 +68,11 @@ static int v2_set_clock_rate(struct snd_motu *motu, unsigned int rate)
|
||||
data &= ~V2_CLOCK_RATE_MASK;
|
||||
data |= i << V2_CLOCK_RATE_SHIFT;
|
||||
|
||||
if (motu->spec == &snd_motu_spec_traveler) {
|
||||
data &= ~V2_CLOCK_TRAVELER_FETCH_ENABLE;
|
||||
data |= V2_CLOCK_TRAVELER_FETCH_DISABLE;
|
||||
}
|
||||
|
||||
reg = cpu_to_be32(data);
|
||||
return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, ®,
|
||||
sizeof(reg));
|
||||
@@ -121,8 +128,31 @@ static int v2_get_clock_source(struct snd_motu *motu,
|
||||
|
||||
static int v2_switch_fetching_mode(struct snd_motu *motu, bool enable)
|
||||
{
|
||||
/* V2 protocol doesn't have this feature. */
|
||||
return 0;
|
||||
__be32 reg;
|
||||
u32 data;
|
||||
int err = 0;
|
||||
|
||||
if (motu->spec == &snd_motu_spec_traveler) {
|
||||
err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET,
|
||||
®, sizeof(reg));
|
||||
if (err < 0)
|
||||
return err;
|
||||
data = be32_to_cpu(reg);
|
||||
|
||||
data &= ~(V2_CLOCK_TRAVELER_FETCH_DISABLE |
|
||||
V2_CLOCK_TRAVELER_FETCH_ENABLE);
|
||||
|
||||
if (enable)
|
||||
data |= V2_CLOCK_TRAVELER_FETCH_ENABLE;
|
||||
else
|
||||
data |= V2_CLOCK_TRAVELER_FETCH_DISABLE;
|
||||
|
||||
reg = cpu_to_be32(data);
|
||||
err = snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET,
|
||||
®, sizeof(reg));
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void calculate_fixed_part(struct snd_motu_packet_format *formats,
|
||||
@@ -149,11 +179,20 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats,
|
||||
pcm_chunks[1] += 2;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Packets to v2 units transfer main-out-1/2 and phone-out-1/2.
|
||||
*/
|
||||
pcm_chunks[0] += 4;
|
||||
pcm_chunks[1] += 4;
|
||||
if (flags & SND_MOTU_SPEC_RX_SEPARETED_MAIN) {
|
||||
pcm_chunks[0] += 2;
|
||||
pcm_chunks[1] += 2;
|
||||
}
|
||||
|
||||
// Packets to v2 units include 2 chunks for phone 1/2, except
|
||||
// for 176.4/192.0 kHz.
|
||||
pcm_chunks[0] += 2;
|
||||
pcm_chunks[1] += 2;
|
||||
}
|
||||
|
||||
if (flags & SND_MOTU_SPEC_HAS_AESEBU_IFACE) {
|
||||
pcm_chunks[0] += 2;
|
||||
pcm_chunks[1] += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -164,19 +203,16 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats,
|
||||
pcm_chunks[0] += 2;
|
||||
pcm_chunks[1] += 2;
|
||||
|
||||
/* This part should be multiples of 4. */
|
||||
formats->fixed_part_pcm_chunks[0] = round_up(2 + pcm_chunks[0], 4) - 2;
|
||||
formats->fixed_part_pcm_chunks[1] = round_up(2 + pcm_chunks[1], 4) - 2;
|
||||
if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4)
|
||||
formats->fixed_part_pcm_chunks[2] =
|
||||
round_up(2 + pcm_chunks[2], 4) - 2;
|
||||
formats->fixed_part_pcm_chunks[0] = pcm_chunks[0];
|
||||
formats->fixed_part_pcm_chunks[1] = pcm_chunks[1];
|
||||
formats->fixed_part_pcm_chunks[2] = pcm_chunks[2];
|
||||
}
|
||||
|
||||
static void calculate_differed_part(struct snd_motu_packet_format *formats,
|
||||
enum snd_motu_spec_flags flags,
|
||||
u32 data, u32 mask, u32 shift)
|
||||
{
|
||||
unsigned char pcm_chunks[3] = {0, 0};
|
||||
unsigned char pcm_chunks[2] = {0, 0};
|
||||
|
||||
/*
|
||||
* When optical interfaces are configured for S/PDIF (TOSLINK),
|
||||
|
@@ -188,11 +188,20 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats,
|
||||
pcm_chunks[1] += 2;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Packets to v2 units transfer main-out-1/2 and phone-out-1/2.
|
||||
*/
|
||||
pcm_chunks[0] += 4;
|
||||
pcm_chunks[1] += 4;
|
||||
if (flags & SND_MOTU_SPEC_RX_SEPARETED_MAIN) {
|
||||
pcm_chunks[0] += 2;
|
||||
pcm_chunks[1] += 2;
|
||||
}
|
||||
|
||||
// Packets to v3 units include 2 chunks for phone 1/2, except
|
||||
// for 176.4/192.0 kHz.
|
||||
pcm_chunks[0] += 2;
|
||||
pcm_chunks[1] += 2;
|
||||
}
|
||||
|
||||
if (flags & SND_MOTU_SPEC_HAS_AESEBU_IFACE) {
|
||||
pcm_chunks[0] += 2;
|
||||
pcm_chunks[1] += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -200,6 +200,22 @@ static const struct snd_motu_spec motu_828mk2 = {
|
||||
.flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
|
||||
SND_MOTU_SPEC_TX_MICINST_CHUNK |
|
||||
SND_MOTU_SPEC_TX_RETURN_CHUNK |
|
||||
SND_MOTU_SPEC_RX_SEPARETED_MAIN |
|
||||
SND_MOTU_SPEC_HAS_OPT_IFACE_A |
|
||||
SND_MOTU_SPEC_RX_MIDI_2ND_Q |
|
||||
SND_MOTU_SPEC_TX_MIDI_2ND_Q,
|
||||
|
||||
.analog_in_ports = 8,
|
||||
.analog_out_ports = 8,
|
||||
};
|
||||
|
||||
const struct snd_motu_spec snd_motu_spec_traveler = {
|
||||
.name = "Traveler",
|
||||
.protocol = &snd_motu_protocol_v2,
|
||||
.flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
|
||||
SND_MOTU_SPEC_SUPPORT_CLOCK_X4 |
|
||||
SND_MOTU_SPEC_TX_RETURN_CHUNK |
|
||||
SND_MOTU_SPEC_HAS_AESEBU_IFACE |
|
||||
SND_MOTU_SPEC_HAS_OPT_IFACE_A |
|
||||
SND_MOTU_SPEC_RX_MIDI_2ND_Q |
|
||||
SND_MOTU_SPEC_TX_MIDI_2ND_Q,
|
||||
@@ -216,6 +232,7 @@ static const struct snd_motu_spec motu_828mk3 = {
|
||||
SND_MOTU_SPEC_TX_MICINST_CHUNK |
|
||||
SND_MOTU_SPEC_TX_RETURN_CHUNK |
|
||||
SND_MOTU_SPEC_TX_REVERB_CHUNK |
|
||||
SND_MOTU_SPEC_RX_SEPARETED_MAIN |
|
||||
SND_MOTU_SPEC_HAS_OPT_IFACE_A |
|
||||
SND_MOTU_SPEC_HAS_OPT_IFACE_B |
|
||||
SND_MOTU_SPEC_RX_MIDI_3RD_Q |
|
||||
@@ -231,6 +248,7 @@ static const struct snd_motu_spec motu_audio_express = {
|
||||
.flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
|
||||
SND_MOTU_SPEC_TX_MICINST_CHUNK |
|
||||
SND_MOTU_SPEC_TX_RETURN_CHUNK |
|
||||
SND_MOTU_SPEC_RX_SEPARETED_MAIN |
|
||||
SND_MOTU_SPEC_RX_MIDI_2ND_Q |
|
||||
SND_MOTU_SPEC_TX_MIDI_3RD_Q,
|
||||
.analog_in_ports = 2,
|
||||
@@ -250,6 +268,7 @@ static const struct snd_motu_spec motu_audio_express = {
|
||||
|
||||
static const struct ieee1394_device_id motu_id_table[] = {
|
||||
SND_MOTU_DEV_ENTRY(0x101800, &motu_828mk2),
|
||||
SND_MOTU_DEV_ENTRY(0x107800, &snd_motu_spec_traveler),
|
||||
SND_MOTU_DEV_ENTRY(0x106800, &motu_828mk3), /* FireWire only. */
|
||||
SND_MOTU_DEV_ENTRY(0x100800, &motu_828mk3), /* Hybrid. */
|
||||
SND_MOTU_DEV_ENTRY(0x104800, &motu_audio_express),
|
||||
|
@@ -79,13 +79,14 @@ enum snd_motu_spec_flags {
|
||||
SND_MOTU_SPEC_TX_MICINST_CHUNK = 0x0004,
|
||||
SND_MOTU_SPEC_TX_RETURN_CHUNK = 0x0008,
|
||||
SND_MOTU_SPEC_TX_REVERB_CHUNK = 0x0010,
|
||||
SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020,
|
||||
SND_MOTU_SPEC_HAS_AESEBU_IFACE = 0x0020,
|
||||
SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040,
|
||||
SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080,
|
||||
SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0100,
|
||||
SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0200,
|
||||
SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0400,
|
||||
SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0800,
|
||||
SND_MOTU_SPEC_RX_SEPARETED_MAIN = 0x1000,
|
||||
};
|
||||
|
||||
#define SND_MOTU_CLOCK_RATE_COUNT 6
|
||||
@@ -128,6 +129,8 @@ struct snd_motu_spec {
|
||||
extern const struct snd_motu_protocol snd_motu_protocol_v2;
|
||||
extern const struct snd_motu_protocol snd_motu_protocol_v3;
|
||||
|
||||
extern const struct snd_motu_spec snd_motu_spec_traveler;
|
||||
|
||||
int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
|
||||
enum amdtp_stream_direction dir,
|
||||
const struct snd_motu_protocol *const protocol);
|
||||
|
@@ -389,7 +389,6 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
|
||||
.pointer = pcm_capture_pointer,
|
||||
.ack = pcm_capture_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
static const struct snd_pcm_ops playback_ops = {
|
||||
.open = pcm_open,
|
||||
@@ -402,7 +401,6 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
|
||||
.pointer = pcm_playback_pointer,
|
||||
.ack = pcm_playback_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
unsigned int cap = 0;
|
||||
|
@@ -279,7 +279,6 @@ int snd_tscm_create_pcm_devices(struct snd_tscm *tscm)
|
||||
.pointer = pcm_playback_pointer,
|
||||
.ack = pcm_playback_ack,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
@@ -5,11 +5,12 @@ config SND_HDA_CORE
|
||||
config SND_HDA_DSP_LOADER
|
||||
bool
|
||||
|
||||
config SND_HDA_COMPONENT
|
||||
bool
|
||||
|
||||
config SND_HDA_I915
|
||||
bool
|
||||
default y
|
||||
depends on DRM_I915
|
||||
depends on SND_HDA_CORE
|
||||
select SND_HDA_COMPONENT
|
||||
|
||||
config SND_HDA_EXT_CORE
|
||||
tristate
|
||||
|
@@ -6,6 +6,7 @@ snd-hda-core-objs += trace.o
|
||||
CFLAGS_trace.o := -I$(src)
|
||||
|
||||
# for sync with i915 gfx driver
|
||||
snd-hda-core-$(CONFIG_SND_HDA_COMPONENT) += hdac_component.o
|
||||
snd-hda-core-$(CONFIG_SND_HDA_I915) += hdac_i915.o
|
||||
|
||||
obj-$(CONFIG_SND_HDA_CORE) += snd-hda-core.o
|
||||
|
@@ -87,9 +87,10 @@ static const struct hdac_io_ops hdac_ext_default_io = {
|
||||
*
|
||||
* Returns 0 if successful, or a negative error code.
|
||||
*/
|
||||
int snd_hdac_ext_bus_init(struct hdac_ext_bus *ebus, struct device *dev,
|
||||
int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
|
||||
const struct hdac_bus_ops *ops,
|
||||
const struct hdac_io_ops *io_ops)
|
||||
const struct hdac_io_ops *io_ops,
|
||||
const struct hdac_ext_bus_ops *ext_ops)
|
||||
{
|
||||
int ret;
|
||||
static int idx;
|
||||
@@ -98,15 +99,16 @@ int snd_hdac_ext_bus_init(struct hdac_ext_bus *ebus, struct device *dev,
|
||||
if (io_ops == NULL)
|
||||
io_ops = &hdac_ext_default_io;
|
||||
|
||||
ret = snd_hdac_bus_init(&ebus->bus, dev, ops, io_ops);
|
||||
ret = snd_hdac_bus_init(bus, dev, ops, io_ops);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
INIT_LIST_HEAD(&ebus->hlink_list);
|
||||
ebus->idx = idx++;
|
||||
bus->ext_ops = ext_ops;
|
||||
INIT_LIST_HEAD(&bus->hlink_list);
|
||||
bus->idx = idx++;
|
||||
|
||||
mutex_init(&ebus->lock);
|
||||
ebus->cmd_dma_state = true;
|
||||
mutex_init(&bus->lock);
|
||||
bus->cmd_dma_state = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -116,10 +118,10 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_init);
|
||||
* snd_hdac_ext_bus_exit - clean up a HD-audio extended bus
|
||||
* @ebus: the pointer to extended bus object
|
||||
*/
|
||||
void snd_hdac_ext_bus_exit(struct hdac_ext_bus *ebus)
|
||||
void snd_hdac_ext_bus_exit(struct hdac_bus *bus)
|
||||
{
|
||||
snd_hdac_bus_exit(&ebus->bus);
|
||||
WARN_ON(!list_empty(&ebus->hlink_list));
|
||||
snd_hdac_bus_exit(bus);
|
||||
WARN_ON(!list_empty(&bus->hlink_list));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_exit);
|
||||
|
||||
@@ -135,21 +137,15 @@ static void default_release(struct device *dev)
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *ebus, int addr)
|
||||
int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr,
|
||||
struct hdac_device *hdev)
|
||||
{
|
||||
struct hdac_ext_device *edev;
|
||||
struct hdac_device *hdev = NULL;
|
||||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||||
char name[15];
|
||||
int ret;
|
||||
|
||||
edev = kzalloc(sizeof(*edev), GFP_KERNEL);
|
||||
if (!edev)
|
||||
return -ENOMEM;
|
||||
hdev = &edev->hdev;
|
||||
edev->ebus = ebus;
|
||||
hdev->bus = bus;
|
||||
|
||||
snprintf(name, sizeof(name), "ehdaudio%dD%d", ebus->idx, addr);
|
||||
snprintf(name, sizeof(name), "ehdaudio%dD%d", bus->idx, addr);
|
||||
|
||||
ret = snd_hdac_device_init(hdev, bus, name, addr);
|
||||
if (ret < 0) {
|
||||
@@ -176,10 +172,8 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_init);
|
||||
*/
|
||||
void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev)
|
||||
{
|
||||
struct hdac_ext_device *edev = to_ehdac_device(hdev);
|
||||
|
||||
snd_hdac_device_exit(hdev);
|
||||
kfree(edev);
|
||||
kfree(hdev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_exit);
|
||||
|
||||
@@ -188,14 +182,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_exit);
|
||||
*
|
||||
* @ebus: HD-audio extended bus
|
||||
*/
|
||||
void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus)
|
||||
void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus)
|
||||
{
|
||||
struct hdac_device *codec, *__codec;
|
||||
/*
|
||||
* we need to remove all the codec devices objects created in the
|
||||
* snd_hdac_ext_bus_device_init
|
||||
*/
|
||||
list_for_each_entry_safe(codec, __codec, &ebus->bus.codec_list, list) {
|
||||
list_for_each_entry_safe(codec, __codec, &bus->codec_list, list) {
|
||||
snd_hdac_device_unregister(codec);
|
||||
put_device(&codec->dev);
|
||||
}
|
||||
@@ -204,35 +198,31 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_remove);
|
||||
#define dev_to_hdac(dev) (container_of((dev), \
|
||||
struct hdac_device, dev))
|
||||
|
||||
static inline struct hdac_ext_driver *get_edrv(struct device *dev)
|
||||
static inline struct hdac_driver *get_hdrv(struct device *dev)
|
||||
{
|
||||
struct hdac_driver *hdrv = drv_to_hdac_driver(dev->driver);
|
||||
struct hdac_ext_driver *edrv = to_ehdac_driver(hdrv);
|
||||
|
||||
return edrv;
|
||||
return hdrv;
|
||||
}
|
||||
|
||||
static inline struct hdac_ext_device *get_edev(struct device *dev)
|
||||
static inline struct hdac_device *get_hdev(struct device *dev)
|
||||
{
|
||||
struct hdac_device *hdev = dev_to_hdac_dev(dev);
|
||||
struct hdac_ext_device *edev = to_ehdac_device(hdev);
|
||||
|
||||
return edev;
|
||||
return hdev;
|
||||
}
|
||||
|
||||
static int hda_ext_drv_probe(struct device *dev)
|
||||
{
|
||||
return (get_edrv(dev))->probe(get_edev(dev));
|
||||
return (get_hdrv(dev))->probe(get_hdev(dev));
|
||||
}
|
||||
|
||||
static int hdac_ext_drv_remove(struct device *dev)
|
||||
{
|
||||
return (get_edrv(dev))->remove(get_edev(dev));
|
||||
return (get_hdrv(dev))->remove(get_hdev(dev));
|
||||
}
|
||||
|
||||
static void hdac_ext_drv_shutdown(struct device *dev)
|
||||
{
|
||||
return (get_edrv(dev))->shutdown(get_edev(dev));
|
||||
return (get_hdrv(dev))->shutdown(get_hdev(dev));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,20 +230,20 @@ static void hdac_ext_drv_shutdown(struct device *dev)
|
||||
*
|
||||
* @drv: ext hda driver structure
|
||||
*/
|
||||
int snd_hda_ext_driver_register(struct hdac_ext_driver *drv)
|
||||
int snd_hda_ext_driver_register(struct hdac_driver *drv)
|
||||
{
|
||||
drv->hdac.type = HDA_DEV_ASOC;
|
||||
drv->hdac.driver.bus = &snd_hda_bus_type;
|
||||
drv->type = HDA_DEV_ASOC;
|
||||
drv->driver.bus = &snd_hda_bus_type;
|
||||
/* we use default match */
|
||||
|
||||
if (drv->probe)
|
||||
drv->hdac.driver.probe = hda_ext_drv_probe;
|
||||
drv->driver.probe = hda_ext_drv_probe;
|
||||
if (drv->remove)
|
||||
drv->hdac.driver.remove = hdac_ext_drv_remove;
|
||||
drv->driver.remove = hdac_ext_drv_remove;
|
||||
if (drv->shutdown)
|
||||
drv->hdac.driver.shutdown = hdac_ext_drv_shutdown;
|
||||
drv->driver.shutdown = hdac_ext_drv_shutdown;
|
||||
|
||||
return driver_register(&drv->hdac.driver);
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_ext_driver_register);
|
||||
|
||||
@@ -262,8 +252,8 @@ EXPORT_SYMBOL_GPL(snd_hda_ext_driver_register);
|
||||
*
|
||||
* @drv: ext hda driver structure
|
||||
*/
|
||||
void snd_hda_ext_driver_unregister(struct hdac_ext_driver *drv)
|
||||
void snd_hda_ext_driver_unregister(struct hdac_driver *drv)
|
||||
{
|
||||
driver_unregister(&drv->hdac.driver);
|
||||
driver_unregister(&drv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_ext_driver_unregister);
|
||||
|
@@ -39,9 +39,8 @@
|
||||
* @ebus: HD-audio extended core bus
|
||||
* @enable: flag to turn on/off the capability
|
||||
*/
|
||||
void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *ebus, bool enable)
|
||||
void snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *bus, bool enable)
|
||||
{
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
|
||||
if (!bus->ppcap) {
|
||||
dev_err(bus->dev, "Address of PP capability is NULL");
|
||||
@@ -60,9 +59,8 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_enable);
|
||||
* @ebus: HD-audio extended core bus
|
||||
* @enable: flag to enable/disable interrupt
|
||||
*/
|
||||
void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *ebus, bool enable)
|
||||
void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *bus, bool enable)
|
||||
{
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
|
||||
if (!bus->ppcap) {
|
||||
dev_err(bus->dev, "Address of PP capability is NULL\n");
|
||||
@@ -89,12 +87,11 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_int_enable);
|
||||
* in hlink_list of extended hdac bus
|
||||
* Note: this will be freed on bus exit by driver
|
||||
*/
|
||||
int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus)
|
||||
int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus)
|
||||
{
|
||||
int idx;
|
||||
u32 link_count;
|
||||
struct hdac_ext_link *hlink;
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
|
||||
link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
|
||||
|
||||
@@ -114,7 +111,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus)
|
||||
/* since link in On, update the ref */
|
||||
hlink->ref_count = 1;
|
||||
|
||||
list_add_tail(&hlink->list, &ebus->hlink_list);
|
||||
list_add_tail(&hlink->list, &bus->hlink_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -127,12 +124,12 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_ml_capabilities);
|
||||
* @ebus: HD-audio ext core bus
|
||||
*/
|
||||
|
||||
void snd_hdac_link_free_all(struct hdac_ext_bus *ebus)
|
||||
void snd_hdac_link_free_all(struct hdac_bus *bus)
|
||||
{
|
||||
struct hdac_ext_link *l;
|
||||
|
||||
while (!list_empty(&ebus->hlink_list)) {
|
||||
l = list_first_entry(&ebus->hlink_list, struct hdac_ext_link, list);
|
||||
while (!list_empty(&bus->hlink_list)) {
|
||||
l = list_first_entry(&bus->hlink_list, struct hdac_ext_link, list);
|
||||
list_del(&l->list);
|
||||
kfree(l);
|
||||
}
|
||||
@@ -144,7 +141,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_link_free_all);
|
||||
* @ebus: HD-audio extended core bus
|
||||
* @codec_name: codec name
|
||||
*/
|
||||
struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_ext_bus *ebus,
|
||||
struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus,
|
||||
const char *codec_name)
|
||||
{
|
||||
int i;
|
||||
@@ -153,10 +150,10 @@ struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_ext_bus *ebus,
|
||||
|
||||
if (sscanf(codec_name, "ehdaudio%dD%d", &bus_idx, &addr) != 2)
|
||||
return NULL;
|
||||
if (ebus->idx != bus_idx)
|
||||
if (bus->idx != bus_idx)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(hlink, &ebus->hlink_list, list) {
|
||||
list_for_each_entry(hlink, &bus->hlink_list, list) {
|
||||
for (i = 0; i < HDA_MAX_CODECS; i++) {
|
||||
if (hlink->lsdiid & (0x1 << addr))
|
||||
return hlink;
|
||||
@@ -219,12 +216,12 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down);
|
||||
* snd_hdac_ext_bus_link_power_up_all -power up all hda link
|
||||
* @ebus: HD-audio extended bus
|
||||
*/
|
||||
int snd_hdac_ext_bus_link_power_up_all(struct hdac_ext_bus *ebus)
|
||||
int snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus)
|
||||
{
|
||||
struct hdac_ext_link *hlink = NULL;
|
||||
int ret;
|
||||
|
||||
list_for_each_entry(hlink, &ebus->hlink_list, list) {
|
||||
list_for_each_entry(hlink, &bus->hlink_list, list) {
|
||||
snd_hdac_updatel(hlink->ml_addr,
|
||||
AZX_REG_ML_LCTL, 0, AZX_MLCTL_SPA);
|
||||
ret = check_hdac_link_power_active(hlink, true);
|
||||
@@ -240,12 +237,12 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_up_all);
|
||||
* snd_hdac_ext_bus_link_power_down_all -power down all hda link
|
||||
* @ebus: HD-audio extended bus
|
||||
*/
|
||||
int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus)
|
||||
int snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus)
|
||||
{
|
||||
struct hdac_ext_link *hlink = NULL;
|
||||
int ret;
|
||||
|
||||
list_for_each_entry(hlink, &ebus->hlink_list, list) {
|
||||
list_for_each_entry(hlink, &bus->hlink_list, list) {
|
||||
snd_hdac_updatel(hlink->ml_addr, AZX_REG_ML_LCTL, AZX_MLCTL_SPA, 0);
|
||||
ret = check_hdac_link_power_active(hlink, false);
|
||||
if (ret < 0)
|
||||
@@ -256,39 +253,48 @@ int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all);
|
||||
|
||||
int snd_hdac_ext_bus_link_get(struct hdac_ext_bus *ebus,
|
||||
int snd_hdac_ext_bus_link_get(struct hdac_bus *bus,
|
||||
struct hdac_ext_link *link)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&ebus->lock);
|
||||
mutex_lock(&bus->lock);
|
||||
|
||||
/*
|
||||
* if we move from 0 to 1, count will be 1 so power up this link
|
||||
* as well, also check the dma status and trigger that
|
||||
*/
|
||||
if (++link->ref_count == 1) {
|
||||
if (!ebus->cmd_dma_state) {
|
||||
snd_hdac_bus_init_cmd_io(&ebus->bus);
|
||||
ebus->cmd_dma_state = true;
|
||||
if (!bus->cmd_dma_state) {
|
||||
snd_hdac_bus_init_cmd_io(bus);
|
||||
bus->cmd_dma_state = true;
|
||||
}
|
||||
|
||||
ret = snd_hdac_ext_bus_link_power_up(link);
|
||||
|
||||
/*
|
||||
* wait for 521usec for codec to report status
|
||||
* HDA spec section 4.3 - Codec Discovery
|
||||
*/
|
||||
udelay(521);
|
||||
bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
|
||||
dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask);
|
||||
snd_hdac_chip_writew(bus, STATESTS, bus->codec_mask);
|
||||
}
|
||||
|
||||
mutex_unlock(&ebus->lock);
|
||||
mutex_unlock(&bus->lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_get);
|
||||
|
||||
int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus,
|
||||
int snd_hdac_ext_bus_link_put(struct hdac_bus *bus,
|
||||
struct hdac_ext_link *link)
|
||||
{
|
||||
int ret = 0;
|
||||
struct hdac_ext_link *hlink;
|
||||
bool link_up = false;
|
||||
|
||||
mutex_lock(&ebus->lock);
|
||||
mutex_lock(&bus->lock);
|
||||
|
||||
/*
|
||||
* if we move from 1 to 0, count will be 0
|
||||
@@ -301,7 +307,7 @@ int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus,
|
||||
* now check if all links are off, if so turn off
|
||||
* cmd dma as well
|
||||
*/
|
||||
list_for_each_entry(hlink, &ebus->hlink_list, list) {
|
||||
list_for_each_entry(hlink, &bus->hlink_list, list) {
|
||||
if (hlink->ref_count) {
|
||||
link_up = true;
|
||||
break;
|
||||
@@ -309,12 +315,12 @@ int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus,
|
||||
}
|
||||
|
||||
if (!link_up) {
|
||||
snd_hdac_bus_stop_cmd_io(&ebus->bus);
|
||||
ebus->cmd_dma_state = false;
|
||||
snd_hdac_bus_stop_cmd_io(bus);
|
||||
bus->cmd_dma_state = false;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&ebus->lock);
|
||||
mutex_unlock(&bus->lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_put);
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stream_init - initialize each stream (aka device)
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @stream: HD-audio ext core stream object to initialize
|
||||
* @idx: stream index number
|
||||
* @direction: stream direction (SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE)
|
||||
@@ -34,18 +34,16 @@
|
||||
* initialize the stream, if ppcap is enabled then init those and then
|
||||
* invoke hdac stream initialization routine
|
||||
*/
|
||||
void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus,
|
||||
void snd_hdac_ext_stream_init(struct hdac_bus *bus,
|
||||
struct hdac_ext_stream *stream,
|
||||
int idx, int direction, int tag)
|
||||
{
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
|
||||
if (bus->ppcap) {
|
||||
stream->pphc_addr = bus->ppcap + AZX_PPHC_BASE +
|
||||
AZX_PPHC_INTERVAL * idx;
|
||||
|
||||
stream->pplc_addr = bus->ppcap + AZX_PPLC_BASE +
|
||||
AZX_PPLC_MULTI * ebus->num_streams +
|
||||
AZX_PPLC_MULTI * bus->num_streams +
|
||||
AZX_PPLC_INTERVAL * idx;
|
||||
}
|
||||
|
||||
@@ -71,12 +69,12 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init);
|
||||
/**
|
||||
* snd_hdac_ext_stream_init_all - create and initialize the stream objects
|
||||
* for an extended hda bus
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @start_idx: start index for streams
|
||||
* @num_stream: number of streams to initialize
|
||||
* @dir: direction of streams
|
||||
*/
|
||||
int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx,
|
||||
int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
|
||||
int num_stream, int dir)
|
||||
{
|
||||
int stream_tag = 0;
|
||||
@@ -88,7 +86,7 @@ int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx,
|
||||
if (!stream)
|
||||
return -ENOMEM;
|
||||
tag = ++stream_tag;
|
||||
snd_hdac_ext_stream_init(ebus, stream, idx, dir, tag);
|
||||
snd_hdac_ext_stream_init(bus, stream, idx, dir, tag);
|
||||
idx++;
|
||||
}
|
||||
|
||||
@@ -100,17 +98,16 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init_all);
|
||||
/**
|
||||
* snd_hdac_stream_free_all - free hdac extended stream objects
|
||||
*
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
*/
|
||||
void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus)
|
||||
void snd_hdac_stream_free_all(struct hdac_bus *bus)
|
||||
{
|
||||
struct hdac_stream *s, *_s;
|
||||
struct hdac_ext_stream *stream;
|
||||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||||
|
||||
list_for_each_entry_safe(s, _s, &bus->stream_list, list) {
|
||||
stream = stream_to_hdac_ext_stream(s);
|
||||
snd_hdac_ext_stream_decouple(ebus, stream, false);
|
||||
snd_hdac_ext_stream_decouple(bus, stream, false);
|
||||
list_del(&s->list);
|
||||
kfree(stream);
|
||||
}
|
||||
@@ -119,15 +116,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_free_all);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stream_decouple - decouple the hdac stream
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @stream: HD-audio ext core stream object to initialize
|
||||
* @decouple: flag to decouple
|
||||
*/
|
||||
void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus,
|
||||
void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
|
||||
struct hdac_ext_stream *stream, bool decouple)
|
||||
{
|
||||
struct hdac_stream *hstream = &stream->hstream;
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
u32 val;
|
||||
int mask = AZX_PPCTL_PROCEN(hstream->index);
|
||||
|
||||
@@ -251,19 +247,18 @@ void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_ext_link_clear_stream_id);
|
||||
|
||||
static struct hdac_ext_stream *
|
||||
hdac_ext_link_stream_assign(struct hdac_ext_bus *ebus,
|
||||
hdac_ext_link_stream_assign(struct hdac_bus *bus,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct hdac_ext_stream *res = NULL;
|
||||
struct hdac_stream *stream = NULL;
|
||||
struct hdac_bus *hbus = &ebus->bus;
|
||||
|
||||
if (!hbus->ppcap) {
|
||||
dev_err(hbus->dev, "stream type not supported\n");
|
||||
if (!bus->ppcap) {
|
||||
dev_err(bus->dev, "stream type not supported\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_for_each_entry(stream, &hbus->stream_list, list) {
|
||||
list_for_each_entry(stream, &bus->stream_list, list) {
|
||||
struct hdac_ext_stream *hstream = container_of(stream,
|
||||
struct hdac_ext_stream,
|
||||
hstream);
|
||||
@@ -277,34 +272,33 @@ hdac_ext_link_stream_assign(struct hdac_ext_bus *ebus,
|
||||
}
|
||||
|
||||
if (!hstream->link_locked) {
|
||||
snd_hdac_ext_stream_decouple(ebus, hstream, true);
|
||||
snd_hdac_ext_stream_decouple(bus, hstream, true);
|
||||
res = hstream;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (res) {
|
||||
spin_lock_irq(&hbus->reg_lock);
|
||||
spin_lock_irq(&bus->reg_lock);
|
||||
res->link_locked = 1;
|
||||
res->link_substream = substream;
|
||||
spin_unlock_irq(&hbus->reg_lock);
|
||||
spin_unlock_irq(&bus->reg_lock);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct hdac_ext_stream *
|
||||
hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,
|
||||
hdac_ext_host_stream_assign(struct hdac_bus *bus,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct hdac_ext_stream *res = NULL;
|
||||
struct hdac_stream *stream = NULL;
|
||||
struct hdac_bus *hbus = &ebus->bus;
|
||||
|
||||
if (!hbus->ppcap) {
|
||||
dev_err(hbus->dev, "stream type not supported\n");
|
||||
if (!bus->ppcap) {
|
||||
dev_err(bus->dev, "stream type not supported\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_for_each_entry(stream, &hbus->stream_list, list) {
|
||||
list_for_each_entry(stream, &bus->stream_list, list) {
|
||||
struct hdac_ext_stream *hstream = container_of(stream,
|
||||
struct hdac_ext_stream,
|
||||
hstream);
|
||||
@@ -313,17 +307,17 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,
|
||||
|
||||
if (!stream->opened) {
|
||||
if (!hstream->decoupled)
|
||||
snd_hdac_ext_stream_decouple(ebus, hstream, true);
|
||||
snd_hdac_ext_stream_decouple(bus, hstream, true);
|
||||
res = hstream;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (res) {
|
||||
spin_lock_irq(&hbus->reg_lock);
|
||||
spin_lock_irq(&bus->reg_lock);
|
||||
res->hstream.opened = 1;
|
||||
res->hstream.running = 0;
|
||||
res->hstream.substream = substream;
|
||||
spin_unlock_irq(&hbus->reg_lock);
|
||||
spin_unlock_irq(&bus->reg_lock);
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -331,7 +325,7 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stream_assign - assign a stream for the PCM
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @substream: PCM substream to assign
|
||||
* @type: type of stream (coupled, host or link stream)
|
||||
*
|
||||
@@ -346,27 +340,26 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,
|
||||
* the same stream object when it's used beforehand. when a stream is
|
||||
* decoupled, it becomes a host stream and link stream.
|
||||
*/
|
||||
struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_ext_bus *ebus,
|
||||
struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus,
|
||||
struct snd_pcm_substream *substream,
|
||||
int type)
|
||||
{
|
||||
struct hdac_ext_stream *hstream = NULL;
|
||||
struct hdac_stream *stream = NULL;
|
||||
struct hdac_bus *hbus = &ebus->bus;
|
||||
|
||||
switch (type) {
|
||||
case HDAC_EXT_STREAM_TYPE_COUPLED:
|
||||
stream = snd_hdac_stream_assign(hbus, substream);
|
||||
stream = snd_hdac_stream_assign(bus, substream);
|
||||
if (stream)
|
||||
hstream = container_of(stream,
|
||||
struct hdac_ext_stream, hstream);
|
||||
return hstream;
|
||||
|
||||
case HDAC_EXT_STREAM_TYPE_HOST:
|
||||
return hdac_ext_host_stream_assign(ebus, substream);
|
||||
return hdac_ext_host_stream_assign(bus, substream);
|
||||
|
||||
case HDAC_EXT_STREAM_TYPE_LINK:
|
||||
return hdac_ext_link_stream_assign(ebus, substream);
|
||||
return hdac_ext_link_stream_assign(bus, substream);
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
@@ -384,7 +377,6 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_assign);
|
||||
void snd_hdac_ext_stream_release(struct hdac_ext_stream *stream, int type)
|
||||
{
|
||||
struct hdac_bus *bus = stream->hstream.bus;
|
||||
struct hdac_ext_bus *ebus = hbus_to_ebus(bus);
|
||||
|
||||
switch (type) {
|
||||
case HDAC_EXT_STREAM_TYPE_COUPLED:
|
||||
@@ -393,13 +385,13 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *stream, int type)
|
||||
|
||||
case HDAC_EXT_STREAM_TYPE_HOST:
|
||||
if (stream->decoupled && !stream->link_locked)
|
||||
snd_hdac_ext_stream_decouple(ebus, stream, false);
|
||||
snd_hdac_ext_stream_decouple(bus, stream, false);
|
||||
snd_hdac_stream_release(&stream->hstream);
|
||||
break;
|
||||
|
||||
case HDAC_EXT_STREAM_TYPE_LINK:
|
||||
if (stream->decoupled && !stream->hstream.opened)
|
||||
snd_hdac_ext_stream_decouple(ebus, stream, false);
|
||||
snd_hdac_ext_stream_decouple(bus, stream, false);
|
||||
spin_lock_irq(&bus->reg_lock);
|
||||
stream->link_locked = 0;
|
||||
stream->link_substream = NULL;
|
||||
@@ -415,16 +407,15 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_release);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stream_spbcap_enable - enable SPIB for a stream
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @enable: flag to enable/disable SPIB
|
||||
* @index: stream index for which SPIB need to be enabled
|
||||
*/
|
||||
void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *ebus,
|
||||
void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *bus,
|
||||
bool enable, int index)
|
||||
{
|
||||
u32 mask = 0;
|
||||
u32 register_mask = 0;
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
|
||||
if (!bus->spbcap) {
|
||||
dev_err(bus->dev, "Address of SPB capability is NULL\n");
|
||||
@@ -446,14 +437,13 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stream_set_spib - sets the spib value of a stream
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @stream: hdac_ext_stream
|
||||
* @value: spib value to set
|
||||
*/
|
||||
int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus,
|
||||
int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus,
|
||||
struct hdac_ext_stream *stream, u32 value)
|
||||
{
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
|
||||
if (!bus->spbcap) {
|
||||
dev_err(bus->dev, "Address of SPB capability is NULL\n");
|
||||
@@ -468,15 +458,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_spib);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stream_get_spbmaxfifo - gets the spib value of a stream
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @stream: hdac_ext_stream
|
||||
*
|
||||
* Return maxfifo for the stream
|
||||
*/
|
||||
int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus,
|
||||
int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus,
|
||||
struct hdac_ext_stream *stream)
|
||||
{
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
|
||||
if (!bus->spbcap) {
|
||||
dev_err(bus->dev, "Address of SPB capability is NULL\n");
|
||||
@@ -490,11 +479,10 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_get_spbmaxfifo);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stop_streams - stop all stream if running
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
*/
|
||||
void snd_hdac_ext_stop_streams(struct hdac_ext_bus *ebus)
|
||||
void snd_hdac_ext_stop_streams(struct hdac_bus *bus)
|
||||
{
|
||||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||||
struct hdac_stream *stream;
|
||||
|
||||
if (bus->chip_init) {
|
||||
@@ -507,16 +495,15 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stop_streams);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stream_drsm_enable - enable DMA resume for a stream
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @enable: flag to enable/disable DRSM
|
||||
* @index: stream index for which DRSM need to be enabled
|
||||
*/
|
||||
void snd_hdac_ext_stream_drsm_enable(struct hdac_ext_bus *ebus,
|
||||
void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,
|
||||
bool enable, int index)
|
||||
{
|
||||
u32 mask = 0;
|
||||
u32 register_mask = 0;
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
|
||||
if (!bus->drsmcap) {
|
||||
dev_err(bus->dev, "Address of DRSM capability is NULL\n");
|
||||
@@ -538,14 +525,13 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stream_set_dpibr - sets the dpibr value of a stream
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @stream: hdac_ext_stream
|
||||
* @value: dpib value to set
|
||||
*/
|
||||
int snd_hdac_ext_stream_set_dpibr(struct hdac_ext_bus *ebus,
|
||||
int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus,
|
||||
struct hdac_ext_stream *stream, u32 value)
|
||||
{
|
||||
struct hdac_bus *bus = &ebus->bus;
|
||||
|
||||
if (!bus->drsmcap) {
|
||||
dev_err(bus->dev, "Address of DRSM capability is NULL\n");
|
||||
@@ -560,7 +546,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_dpibr);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_stream_set_lpib - sets the lpib value of a stream
|
||||
* @ebus: HD-audio ext core bus
|
||||
* @bus: HD-audio core bus
|
||||
* @stream: hdac_ext_stream
|
||||
* @value: lpib value to set
|
||||
*/
|
||||
|
335
sound/hda/hdac_component.c
Normal file
335
sound/hda/hdac_component.c
Normal file
@@ -0,0 +1,335 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// hdac_component.c - routines for sync between HD-A core and DRM driver
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/component.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/hdaudio.h>
|
||||
#include <sound/hda_component.h>
|
||||
#include <sound/hda_register.h>
|
||||
|
||||
static void hdac_acomp_release(struct device *dev, void *res)
|
||||
{
|
||||
}
|
||||
|
||||
static struct drm_audio_component *hdac_get_acomp(struct device *dev)
|
||||
{
|
||||
return devres_find(dev, hdac_acomp_release, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup
|
||||
* @bus: HDA core bus
|
||||
* @enable: enable or disable the wakeup
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with graphics driver.
|
||||
*
|
||||
* This function should be called during the chip reset, also called at
|
||||
* resume for updating STATESTS register read.
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable)
|
||||
{
|
||||
struct drm_audio_component *acomp = bus->audio_component;
|
||||
|
||||
if (!acomp || !acomp->ops)
|
||||
return -ENODEV;
|
||||
|
||||
if (!acomp->ops->codec_wake_override)
|
||||
return 0;
|
||||
|
||||
dev_dbg(bus->dev, "%s codec wakeup\n",
|
||||
enable ? "enable" : "disable");
|
||||
|
||||
acomp->ops->codec_wake_override(acomp->dev, enable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_set_codec_wakeup);
|
||||
|
||||
/**
|
||||
* snd_hdac_display_power - Power up / down the power refcount
|
||||
* @bus: HDA core bus
|
||||
* @enable: power up or down
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with graphics driver.
|
||||
*
|
||||
* This function manages a refcount and calls the get_power() and
|
||||
* put_power() ops accordingly, toggling the codec wakeup, too.
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
|
||||
{
|
||||
struct drm_audio_component *acomp = bus->audio_component;
|
||||
|
||||
if (!acomp || !acomp->ops)
|
||||
return -ENODEV;
|
||||
|
||||
dev_dbg(bus->dev, "display power %s\n",
|
||||
enable ? "enable" : "disable");
|
||||
|
||||
if (enable) {
|
||||
if (!bus->drm_power_refcount++) {
|
||||
if (acomp->ops->get_power)
|
||||
acomp->ops->get_power(acomp->dev);
|
||||
snd_hdac_set_codec_wakeup(bus, true);
|
||||
snd_hdac_set_codec_wakeup(bus, false);
|
||||
}
|
||||
} else {
|
||||
WARN_ON(!bus->drm_power_refcount);
|
||||
if (!--bus->drm_power_refcount)
|
||||
if (acomp->ops->put_power)
|
||||
acomp->ops->put_power(acomp->dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_display_power);
|
||||
|
||||
/**
|
||||
* snd_hdac_sync_audio_rate - Set N/CTS based on the sample rate
|
||||
* @codec: HDA codec
|
||||
* @nid: the pin widget NID
|
||||
* @dev_id: device identifier
|
||||
* @rate: the sample rate to set
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with graphics driver.
|
||||
*
|
||||
* This function sets N/CTS value based on the given sample rate.
|
||||
* Returns zero for success, or a negative error code.
|
||||
*/
|
||||
int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
|
||||
int dev_id, int rate)
|
||||
{
|
||||
struct hdac_bus *bus = codec->bus;
|
||||
struct drm_audio_component *acomp = bus->audio_component;
|
||||
int port, pipe;
|
||||
|
||||
if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate)
|
||||
return -ENODEV;
|
||||
port = nid;
|
||||
if (acomp->audio_ops && acomp->audio_ops->pin2port) {
|
||||
port = acomp->audio_ops->pin2port(codec, nid);
|
||||
if (port < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
pipe = dev_id;
|
||||
return acomp->ops->sync_audio_rate(acomp->dev, port, pipe, rate);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
|
||||
|
||||
/**
|
||||
* snd_hdac_acomp_get_eld - Get the audio state and ELD via component
|
||||
* @codec: HDA codec
|
||||
* @nid: the pin widget NID
|
||||
* @dev_id: device identifier
|
||||
* @audio_enabled: the pointer to store the current audio state
|
||||
* @buffer: the buffer pointer to store ELD bytes
|
||||
* @max_bytes: the max bytes to be stored on @buffer
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with graphics driver.
|
||||
*
|
||||
* This function queries the current state of the audio on the given
|
||||
* digital port and fetches the ELD bytes onto the given buffer.
|
||||
* It returns the number of bytes for the total ELD data, zero for
|
||||
* invalid ELD, or a negative error code.
|
||||
*
|
||||
* The return size is the total bytes required for the whole ELD bytes,
|
||||
* thus it may be over @max_bytes. If it's over @max_bytes, it implies
|
||||
* that only a part of ELD bytes have been fetched.
|
||||
*/
|
||||
int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
|
||||
bool *audio_enabled, char *buffer, int max_bytes)
|
||||
{
|
||||
struct hdac_bus *bus = codec->bus;
|
||||
struct drm_audio_component *acomp = bus->audio_component;
|
||||
int port, pipe;
|
||||
|
||||
if (!acomp || !acomp->ops || !acomp->ops->get_eld)
|
||||
return -ENODEV;
|
||||
|
||||
port = nid;
|
||||
if (acomp->audio_ops && acomp->audio_ops->pin2port) {
|
||||
port = acomp->audio_ops->pin2port(codec, nid);
|
||||
if (port < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
pipe = dev_id;
|
||||
return acomp->ops->get_eld(acomp->dev, port, pipe, audio_enabled,
|
||||
buffer, max_bytes);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
|
||||
|
||||
static int hdac_component_master_bind(struct device *dev)
|
||||
{
|
||||
struct drm_audio_component *acomp = hdac_get_acomp(dev);
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(!acomp))
|
||||
return -EINVAL;
|
||||
|
||||
ret = component_bind_all(dev, acomp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (WARN_ON(!(acomp->dev && acomp->ops))) {
|
||||
ret = -EINVAL;
|
||||
goto out_unbind;
|
||||
}
|
||||
|
||||
/* pin the module to avoid dynamic unbinding, but only if given */
|
||||
if (!try_module_get(acomp->ops->owner)) {
|
||||
ret = -ENODEV;
|
||||
goto out_unbind;
|
||||
}
|
||||
|
||||
if (acomp->audio_ops && acomp->audio_ops->master_bind) {
|
||||
ret = acomp->audio_ops->master_bind(dev, acomp);
|
||||
if (ret < 0)
|
||||
goto module_put;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
module_put:
|
||||
module_put(acomp->ops->owner);
|
||||
out_unbind:
|
||||
component_unbind_all(dev, acomp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hdac_component_master_unbind(struct device *dev)
|
||||
{
|
||||
struct drm_audio_component *acomp = hdac_get_acomp(dev);
|
||||
|
||||
if (acomp->audio_ops && acomp->audio_ops->master_unbind)
|
||||
acomp->audio_ops->master_unbind(dev, acomp);
|
||||
module_put(acomp->ops->owner);
|
||||
component_unbind_all(dev, acomp);
|
||||
WARN_ON(acomp->ops || acomp->dev);
|
||||
}
|
||||
|
||||
static const struct component_master_ops hdac_component_master_ops = {
|
||||
.bind = hdac_component_master_bind,
|
||||
.unbind = hdac_component_master_unbind,
|
||||
};
|
||||
|
||||
/**
|
||||
* snd_hdac_acomp_register_notifier - Register audio component ops
|
||||
* @bus: HDA core bus
|
||||
* @aops: audio component ops
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with graphics driver.
|
||||
*
|
||||
* This function sets the given ops to be called by the graphics driver.
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_acomp_register_notifier(struct hdac_bus *bus,
|
||||
const struct drm_audio_component_audio_ops *aops)
|
||||
{
|
||||
if (!bus->audio_component)
|
||||
return -ENODEV;
|
||||
|
||||
bus->audio_component->audio_ops = aops;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_acomp_register_notifier);
|
||||
|
||||
/**
|
||||
* snd_hdac_acomp_init - Initialize audio component
|
||||
* @bus: HDA core bus
|
||||
* @match_master: match function for finding components
|
||||
* @extra_size: Extra bytes to allocate
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with graphics driver.
|
||||
*
|
||||
* This function initializes and sets up the audio component to communicate
|
||||
* with graphics driver.
|
||||
*
|
||||
* Unlike snd_hdac_i915_init(), this function doesn't synchronize with the
|
||||
* binding with the DRM component. Each caller needs to sync via master_bind
|
||||
* audio_ops.
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_acomp_init(struct hdac_bus *bus,
|
||||
const struct drm_audio_component_audio_ops *aops,
|
||||
int (*match_master)(struct device *, void *),
|
||||
size_t extra_size)
|
||||
{
|
||||
struct component_match *match = NULL;
|
||||
struct device *dev = bus->dev;
|
||||
struct drm_audio_component *acomp;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(hdac_get_acomp(dev)))
|
||||
return -EBUSY;
|
||||
|
||||
acomp = devres_alloc(hdac_acomp_release, sizeof(*acomp) + extra_size,
|
||||
GFP_KERNEL);
|
||||
if (!acomp)
|
||||
return -ENOMEM;
|
||||
acomp->audio_ops = aops;
|
||||
bus->audio_component = acomp;
|
||||
devres_add(dev, acomp);
|
||||
|
||||
component_match_add(dev, &match, match_master, bus);
|
||||
ret = component_master_add_with_match(dev, &hdac_component_master_ops,
|
||||
match);
|
||||
if (ret < 0)
|
||||
goto out_err;
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
bus->audio_component = NULL;
|
||||
devres_destroy(dev, hdac_acomp_release, NULL, NULL);
|
||||
dev_info(dev, "failed to add audio component master (%d)\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_acomp_init);
|
||||
|
||||
/**
|
||||
* snd_hdac_acomp_exit - Finalize audio component
|
||||
* @bus: HDA core bus
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with graphics driver.
|
||||
*
|
||||
* This function releases the audio component that has been used.
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_acomp_exit(struct hdac_bus *bus)
|
||||
{
|
||||
struct device *dev = bus->dev;
|
||||
struct drm_audio_component *acomp = bus->audio_component;
|
||||
|
||||
if (!acomp)
|
||||
return 0;
|
||||
|
||||
WARN_ON(bus->drm_power_refcount);
|
||||
if (bus->drm_power_refcount > 0 && acomp->ops)
|
||||
acomp->ops->put_power(acomp->dev);
|
||||
|
||||
component_master_del(dev, &hdac_component_master_ops);
|
||||
|
||||
bus->audio_component = NULL;
|
||||
devres_destroy(dev, hdac_acomp_release, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_acomp_exit);
|
@@ -738,7 +738,7 @@ static struct hda_rate_tbl rate_bits[] = {
|
||||
*/
|
||||
unsigned int snd_hdac_calc_stream_format(unsigned int rate,
|
||||
unsigned int channels,
|
||||
unsigned int format,
|
||||
snd_pcm_format_t format,
|
||||
unsigned int maxbps,
|
||||
unsigned short spdif_ctls)
|
||||
{
|
||||
|
@@ -15,88 +15,12 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/component.h>
|
||||
#include <drm/i915_component.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/hdaudio.h>
|
||||
#include <sound/hda_i915.h>
|
||||
#include <sound/hda_register.h>
|
||||
|
||||
static struct i915_audio_component *hdac_acomp;
|
||||
|
||||
/**
|
||||
* snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup
|
||||
* @bus: HDA core bus
|
||||
* @enable: enable or disable the wakeup
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with i915 graphics.
|
||||
*
|
||||
* This function should be called during the chip reset, also called at
|
||||
* resume for updating STATESTS register read.
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable)
|
||||
{
|
||||
struct i915_audio_component *acomp = bus->audio_component;
|
||||
|
||||
if (!acomp || !acomp->ops)
|
||||
return -ENODEV;
|
||||
|
||||
if (!acomp->ops->codec_wake_override) {
|
||||
dev_warn(bus->dev,
|
||||
"Invalid codec wake callback\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_dbg(bus->dev, "%s codec wakeup\n",
|
||||
enable ? "enable" : "disable");
|
||||
|
||||
acomp->ops->codec_wake_override(acomp->dev, enable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_set_codec_wakeup);
|
||||
|
||||
/**
|
||||
* snd_hdac_display_power - Power up / down the power refcount
|
||||
* @bus: HDA core bus
|
||||
* @enable: power up or down
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with i915 graphics.
|
||||
*
|
||||
* This function manages a refcount and calls the i915 get_power() and
|
||||
* put_power() ops accordingly, toggling the codec wakeup, too.
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
|
||||
{
|
||||
struct i915_audio_component *acomp = bus->audio_component;
|
||||
|
||||
if (!acomp || !acomp->ops)
|
||||
return -ENODEV;
|
||||
|
||||
dev_dbg(bus->dev, "display power %s\n",
|
||||
enable ? "enable" : "disable");
|
||||
|
||||
if (enable) {
|
||||
if (!bus->i915_power_refcount++) {
|
||||
acomp->ops->get_power(acomp->dev);
|
||||
snd_hdac_set_codec_wakeup(bus, true);
|
||||
snd_hdac_set_codec_wakeup(bus, false);
|
||||
}
|
||||
} else {
|
||||
WARN_ON(!bus->i915_power_refcount);
|
||||
if (!--bus->i915_power_refcount)
|
||||
acomp->ops->put_power(acomp->dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_display_power);
|
||||
static struct completion bind_complete;
|
||||
|
||||
#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
|
||||
((pci)->device == 0x0c0c) || \
|
||||
@@ -119,7 +43,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_display_power);
|
||||
*/
|
||||
void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
|
||||
{
|
||||
struct i915_audio_component *acomp = bus->audio_component;
|
||||
struct drm_audio_component *acomp = bus->audio_component;
|
||||
struct pci_dev *pci = to_pci_dev(bus->dev);
|
||||
int cdclk_freq;
|
||||
unsigned int bclk_m, bclk_n;
|
||||
@@ -158,181 +82,11 @@ void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk);
|
||||
|
||||
/* There is a fixed mapping between audio pin node and display port.
|
||||
* on SNB, IVY, HSW, BSW, SKL, BXT, KBL:
|
||||
* Pin Widget 5 - PORT B (port = 1 in i915 driver)
|
||||
* Pin Widget 6 - PORT C (port = 2 in i915 driver)
|
||||
* Pin Widget 7 - PORT D (port = 3 in i915 driver)
|
||||
*
|
||||
* on VLV, ILK:
|
||||
* Pin Widget 4 - PORT B (port = 1 in i915 driver)
|
||||
* Pin Widget 5 - PORT C (port = 2 in i915 driver)
|
||||
* Pin Widget 6 - PORT D (port = 3 in i915 driver)
|
||||
*/
|
||||
static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
|
||||
static int i915_component_master_match(struct device *dev, void *data)
|
||||
{
|
||||
int base_nid;
|
||||
|
||||
switch (codec->vendor_id) {
|
||||
case 0x80860054: /* ILK */
|
||||
case 0x80862804: /* ILK */
|
||||
case 0x80862882: /* VLV */
|
||||
base_nid = 3;
|
||||
break;
|
||||
default:
|
||||
base_nid = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (WARN_ON(pin_nid <= base_nid || pin_nid > base_nid + 3))
|
||||
return -1;
|
||||
return pin_nid - base_nid;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hdac_sync_audio_rate - Set N/CTS based on the sample rate
|
||||
* @codec: HDA codec
|
||||
* @nid: the pin widget NID
|
||||
* @dev_id: device identifier
|
||||
* @rate: the sample rate to set
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with i915 graphics.
|
||||
*
|
||||
* This function sets N/CTS value based on the given sample rate.
|
||||
* Returns zero for success, or a negative error code.
|
||||
*/
|
||||
int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
|
||||
int dev_id, int rate)
|
||||
{
|
||||
struct hdac_bus *bus = codec->bus;
|
||||
struct i915_audio_component *acomp = bus->audio_component;
|
||||
int port, pipe;
|
||||
|
||||
if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate)
|
||||
return -ENODEV;
|
||||
port = pin2port(codec, nid);
|
||||
if (port < 0)
|
||||
return -EINVAL;
|
||||
pipe = dev_id;
|
||||
return acomp->ops->sync_audio_rate(acomp->dev, port, pipe, rate);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
|
||||
|
||||
/**
|
||||
* snd_hdac_acomp_get_eld - Get the audio state and ELD via component
|
||||
* @codec: HDA codec
|
||||
* @nid: the pin widget NID
|
||||
* @dev_id: device identifier
|
||||
* @audio_enabled: the pointer to store the current audio state
|
||||
* @buffer: the buffer pointer to store ELD bytes
|
||||
* @max_bytes: the max bytes to be stored on @buffer
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with i915 graphics.
|
||||
*
|
||||
* This function queries the current state of the audio on the given
|
||||
* digital port and fetches the ELD bytes onto the given buffer.
|
||||
* It returns the number of bytes for the total ELD data, zero for
|
||||
* invalid ELD, or a negative error code.
|
||||
*
|
||||
* The return size is the total bytes required for the whole ELD bytes,
|
||||
* thus it may be over @max_bytes. If it's over @max_bytes, it implies
|
||||
* that only a part of ELD bytes have been fetched.
|
||||
*/
|
||||
int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
|
||||
bool *audio_enabled, char *buffer, int max_bytes)
|
||||
{
|
||||
struct hdac_bus *bus = codec->bus;
|
||||
struct i915_audio_component *acomp = bus->audio_component;
|
||||
int port, pipe;
|
||||
|
||||
if (!acomp || !acomp->ops || !acomp->ops->get_eld)
|
||||
return -ENODEV;
|
||||
|
||||
port = pin2port(codec, nid);
|
||||
if (port < 0)
|
||||
return -EINVAL;
|
||||
|
||||
pipe = dev_id;
|
||||
return acomp->ops->get_eld(acomp->dev, port, pipe, audio_enabled,
|
||||
buffer, max_bytes);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
|
||||
|
||||
static int hdac_component_master_bind(struct device *dev)
|
||||
{
|
||||
struct i915_audio_component *acomp = hdac_acomp;
|
||||
int ret;
|
||||
|
||||
ret = component_bind_all(dev, acomp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (WARN_ON(!(acomp->dev && acomp->ops && acomp->ops->get_power &&
|
||||
acomp->ops->put_power && acomp->ops->get_cdclk_freq))) {
|
||||
ret = -EINVAL;
|
||||
goto out_unbind;
|
||||
}
|
||||
|
||||
/*
|
||||
* Atm, we don't support dynamic unbinding initiated by the child
|
||||
* component, so pin its containing module until we unbind.
|
||||
*/
|
||||
if (!try_module_get(acomp->ops->owner)) {
|
||||
ret = -ENODEV;
|
||||
goto out_unbind;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_unbind:
|
||||
component_unbind_all(dev, acomp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hdac_component_master_unbind(struct device *dev)
|
||||
{
|
||||
struct i915_audio_component *acomp = hdac_acomp;
|
||||
|
||||
module_put(acomp->ops->owner);
|
||||
component_unbind_all(dev, acomp);
|
||||
WARN_ON(acomp->ops || acomp->dev);
|
||||
}
|
||||
|
||||
static const struct component_master_ops hdac_component_master_ops = {
|
||||
.bind = hdac_component_master_bind,
|
||||
.unbind = hdac_component_master_unbind,
|
||||
};
|
||||
|
||||
static int hdac_component_master_match(struct device *dev, void *data)
|
||||
{
|
||||
/* i915 is the only supported component */
|
||||
return !strcmp(dev->driver->name, "i915");
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hdac_i915_register_notifier - Register i915 audio component ops
|
||||
* @aops: i915 audio component ops
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with i915 graphics.
|
||||
*
|
||||
* This function sets the given ops to be called by the i915 graphics driver.
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *aops)
|
||||
{
|
||||
if (!hdac_acomp)
|
||||
return -ENODEV;
|
||||
|
||||
hdac_acomp->audio_ops = aops;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier);
|
||||
|
||||
/* check whether intel graphics is present */
|
||||
static bool i915_gfx_present(void)
|
||||
{
|
||||
@@ -345,6 +99,19 @@ static bool i915_gfx_present(void)
|
||||
return pci_dev_present(ids);
|
||||
}
|
||||
|
||||
static int i915_master_bind(struct device *dev,
|
||||
struct drm_audio_component *acomp)
|
||||
{
|
||||
complete_all(&bind_complete);
|
||||
/* clear audio_ops here as it was needed only for completion call */
|
||||
acomp->audio_ops = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_audio_component_audio_ops i915_init_ops = {
|
||||
.master_bind = i915_master_bind
|
||||
};
|
||||
|
||||
/**
|
||||
* snd_hdac_i915_init - Initialize i915 audio component
|
||||
* @bus: HDA core bus
|
||||
@@ -359,83 +126,31 @@ static bool i915_gfx_present(void)
|
||||
*/
|
||||
int snd_hdac_i915_init(struct hdac_bus *bus)
|
||||
{
|
||||
struct component_match *match = NULL;
|
||||
struct device *dev = bus->dev;
|
||||
struct i915_audio_component *acomp;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(hdac_acomp))
|
||||
return -EBUSY;
|
||||
struct drm_audio_component *acomp;
|
||||
int err;
|
||||
|
||||
if (!i915_gfx_present())
|
||||
return -ENODEV;
|
||||
|
||||
acomp = kzalloc(sizeof(*acomp), GFP_KERNEL);
|
||||
init_completion(&bind_complete);
|
||||
|
||||
err = snd_hdac_acomp_init(bus, &i915_init_ops,
|
||||
i915_component_master_match,
|
||||
sizeof(struct i915_audio_component) - sizeof(*acomp));
|
||||
if (err < 0)
|
||||
return err;
|
||||
acomp = bus->audio_component;
|
||||
if (!acomp)
|
||||
return -ENOMEM;
|
||||
bus->audio_component = acomp;
|
||||
hdac_acomp = acomp;
|
||||
|
||||
component_match_add(dev, &match, hdac_component_master_match, bus);
|
||||
ret = component_master_add_with_match(dev, &hdac_component_master_ops,
|
||||
match);
|
||||
if (ret < 0)
|
||||
goto out_err;
|
||||
|
||||
/*
|
||||
* Atm, we don't support deferring the component binding, so make sure
|
||||
* i915 is loaded and that the binding successfully completes.
|
||||
*/
|
||||
request_module("i915");
|
||||
|
||||
return -ENODEV;
|
||||
if (!acomp->ops) {
|
||||
ret = -ENODEV;
|
||||
goto out_master_del;
|
||||
request_module("i915");
|
||||
/* 10s timeout */
|
||||
wait_for_completion_timeout(&bind_complete, 10 * 1000);
|
||||
}
|
||||
if (!acomp->ops) {
|
||||
snd_hdac_acomp_exit(bus);
|
||||
return -ENODEV;
|
||||
}
|
||||
dev_dbg(dev, "bound to i915 component master\n");
|
||||
|
||||
return 0;
|
||||
out_master_del:
|
||||
component_master_del(dev, &hdac_component_master_ops);
|
||||
out_err:
|
||||
kfree(acomp);
|
||||
bus->audio_component = NULL;
|
||||
hdac_acomp = NULL;
|
||||
dev_info(dev, "failed to add i915 component master (%d)\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_i915_init);
|
||||
|
||||
/**
|
||||
* snd_hdac_i915_exit - Finalize i915 audio component
|
||||
* @bus: HDA core bus
|
||||
*
|
||||
* This function is supposed to be used only by a HD-audio controller
|
||||
* driver that needs the interaction with i915 graphics.
|
||||
*
|
||||
* This function releases the i915 audio component that has been used.
|
||||
*
|
||||
* Returns zero for success or a negative error code.
|
||||
*/
|
||||
int snd_hdac_i915_exit(struct hdac_bus *bus)
|
||||
{
|
||||
struct device *dev = bus->dev;
|
||||
struct i915_audio_component *acomp = bus->audio_component;
|
||||
|
||||
if (!acomp)
|
||||
return 0;
|
||||
|
||||
WARN_ON(bus->i915_power_refcount);
|
||||
if (bus->i915_power_refcount > 0 && acomp->ops)
|
||||
acomp->ops->put_power(acomp->dev);
|
||||
|
||||
component_master_del(dev, &hdac_component_master_ops);
|
||||
|
||||
kfree(acomp);
|
||||
bus->audio_component = NULL;
|
||||
hdac_acomp = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_i915_exit);
|
||||
|
@@ -621,7 +621,7 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
|
||||
unsigned int byte_size, struct snd_dma_buffer *bufp)
|
||||
{
|
||||
struct hdac_bus *bus = azx_dev->bus;
|
||||
u32 *bdl;
|
||||
__le32 *bdl;
|
||||
int err;
|
||||
|
||||
snd_hdac_dsp_lock(azx_dev);
|
||||
@@ -651,7 +651,7 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
|
||||
snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0);
|
||||
|
||||
azx_dev->frags = 0;
|
||||
bdl = (u32 *)azx_dev->bdl.area;
|
||||
bdl = (__le32 *)azx_dev->bdl.area;
|
||||
err = setup_bdle(bus, bufp, azx_dev, &bdl, 0, byte_size, 0);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
@@ -621,15 +621,3 @@ int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_cs8427_iec958_pcm);
|
||||
|
||||
static int __init alsa_cs8427_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_cs8427_module_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_cs8427_module_init)
|
||||
module_exit(alsa_cs8427_module_exit)
|
||||
|
@@ -338,16 +338,3 @@ static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
|
||||
snd_i2c_bit_stop(bus);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int __init alsa_i2c_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_i2c_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_i2c_init)
|
||||
module_exit(alsa_i2c_exit)
|
||||
|
@@ -911,15 +911,3 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_akm4xxx_build_controls);
|
||||
|
||||
static int __init alsa_akm4xxx_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_akm4xxx_module_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_akm4xxx_module_init)
|
||||
module_exit(alsa_akm4xxx_module_exit)
|
||||
|
@@ -368,19 +368,3 @@ int snd_tea6330t_update_mixer(struct snd_card *card,
|
||||
|
||||
EXPORT_SYMBOL(snd_tea6330t_detect);
|
||||
EXPORT_SYMBOL(snd_tea6330t_update_mixer);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_tea6330t_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_tea6330t_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_tea6330t_init)
|
||||
module_exit(alsa_tea6330t_exit)
|
||||
|
@@ -459,7 +459,7 @@ config SND_MSND_CLASSIC
|
||||
Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or
|
||||
Monterey (not for the Pinnacle or Fiji).
|
||||
|
||||
See <file:Documentation/sound/oss/MultiSound> for important information
|
||||
See <file:Documentation/sound/cards/multisound.sh> for important information
|
||||
about this driver. Note that it has been discontinued, but the
|
||||
Voyetra Turtle Beach knowledge base entry for it is still available
|
||||
at <http://www.turtlebeach.com/site/kb_ftp/790.asp>.
|
||||
|
@@ -85,7 +85,8 @@ static void snd_ad1816a_write_mask(struct snd_ad1816a *chip, unsigned char reg,
|
||||
|
||||
|
||||
static unsigned char snd_ad1816a_get_format(struct snd_ad1816a *chip,
|
||||
unsigned int format, int channels)
|
||||
snd_pcm_format_t format,
|
||||
int channels)
|
||||
{
|
||||
unsigned char retval = AD1816A_FMT_LINEAR_8;
|
||||
|
||||
|
@@ -260,7 +260,6 @@ static int snd_es968_pnp_detect(struct pnp_card_link *pcard,
|
||||
struct snd_card *card;
|
||||
static unsigned int dev;
|
||||
int error;
|
||||
struct snd_es1688 *chip;
|
||||
|
||||
if (snd_es968_pnp_is_probed)
|
||||
return -EBUSY;
|
||||
@@ -276,7 +275,6 @@ static int snd_es968_pnp_detect(struct pnp_card_link *pcard,
|
||||
sizeof(struct snd_es1688), &card);
|
||||
if (error < 0)
|
||||
return error;
|
||||
chip = card->private_data;
|
||||
|
||||
error = snd_card_es968_pnp(card, dev, pcard, pid);
|
||||
if (error < 0) {
|
||||
|
@@ -1029,19 +1029,3 @@ EXPORT_SYMBOL(snd_es1688_mixer_write);
|
||||
EXPORT_SYMBOL(snd_es1688_create);
|
||||
EXPORT_SYMBOL(snd_es1688_pcm);
|
||||
EXPORT_SYMBOL(snd_es1688_mixer);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_es1688_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_es1688_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_es1688_init)
|
||||
module_exit(alsa_es1688_exit)
|
||||
|
@@ -1024,6 +1024,7 @@ static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
|
||||
val = 3;
|
||||
} else
|
||||
retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00;
|
||||
/* fall through */
|
||||
/* 4 source chips */
|
||||
case 0x1868:
|
||||
case 0x1878:
|
||||
|
@@ -260,6 +260,7 @@ static int snd_galaxy_match(struct device *dev, unsigned int n)
|
||||
break;
|
||||
case 2:
|
||||
irq[n] = 9;
|
||||
/* Fall through */
|
||||
case 9:
|
||||
wss_config[n] |= WSS_CONFIG_IRQ_9;
|
||||
break;
|
||||
@@ -304,6 +305,7 @@ static int snd_galaxy_match(struct device *dev, unsigned int n)
|
||||
case 1:
|
||||
if (dma1[n] == 0)
|
||||
break;
|
||||
/* Fall through */
|
||||
default:
|
||||
dev_err(dev, "invalid capture DMA %d\n", dma2[n]);
|
||||
return 0;
|
||||
@@ -333,6 +335,7 @@ mpu:
|
||||
break;
|
||||
case 2:
|
||||
mpu_irq[n] = 9;
|
||||
/* Fall through */
|
||||
case 9:
|
||||
config[n] |= GALAXY_CONFIG_MPUIRQ_2;
|
||||
break;
|
||||
|
@@ -461,7 +461,7 @@ void snd_gf1_print_voice_registers(struct snd_gus_card * gus)
|
||||
printk(KERN_INFO " -%i- GFA1 effect address = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
|
||||
printk(KERN_INFO " -%i- GFA1 effect volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
|
||||
printk(KERN_INFO " -%i- GFA1 effect volume final = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
|
||||
printk(KERN_INFO " -%i- GFA1 effect acumulator = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
|
||||
printk(KERN_INFO " -%i- GFA1 effect accumulator = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
|
||||
}
|
||||
if (mode & 0x20) {
|
||||
printk(KERN_INFO " -%i- GFA1 left offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
|
||||
|
@@ -465,19 +465,3 @@ EXPORT_SYMBOL(snd_gf1_mem_alloc);
|
||||
EXPORT_SYMBOL(snd_gf1_mem_xfree);
|
||||
EXPORT_SYMBOL(snd_gf1_mem_free);
|
||||
EXPORT_SYMBOL(snd_gf1_mem_lock);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_gus_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_gus_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_gus_init)
|
||||
module_exit(alsa_gus_exit)
|
||||
|
@@ -292,7 +292,6 @@ void snd_gf1_free_voice(struct snd_gus_card * gus, struct snd_gus_voice *voice)
|
||||
{
|
||||
unsigned long flags;
|
||||
void (*private_free)(struct snd_gus_voice *voice);
|
||||
void *private_data;
|
||||
|
||||
if (voice == NULL || !voice->use)
|
||||
return;
|
||||
@@ -300,7 +299,6 @@ void snd_gf1_free_voice(struct snd_gus_card * gus, struct snd_gus_voice *voice)
|
||||
snd_gf1_clear_voices(gus, voice->number, voice->number);
|
||||
spin_lock_irqsave(&gus->voice_alloc, flags);
|
||||
private_free = voice->private_free;
|
||||
private_data = voice->private_data;
|
||||
voice->private_free = NULL;
|
||||
voice->private_data = NULL;
|
||||
if (voice->pcm)
|
||||
|
@@ -54,7 +54,7 @@
|
||||
#define LOGNAME "msnd"
|
||||
|
||||
|
||||
void snd_msnd_init_queue(void *base, int start, int size)
|
||||
void snd_msnd_init_queue(void __iomem *base, int start, int size)
|
||||
{
|
||||
writew(PCTODSP_BASED(start), base + JQS_wStart);
|
||||
writew(PCTODSP_OFFSET(size) - 1, base + JQS_wSize);
|
||||
@@ -270,7 +270,7 @@ int snd_msnd_DARQ(struct snd_msnd *chip, int bank)
|
||||
udelay(1);
|
||||
|
||||
if (chip->capturePeriods == 2) {
|
||||
void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF +
|
||||
void __iomem *pDAQ = chip->mappedbase + DARQ_DATA_BUFF +
|
||||
bank * DAQDS__size + DAQDS_wStart;
|
||||
unsigned short offset = 0x3000 + chip->capturePeriodBytes;
|
||||
|
||||
@@ -309,7 +309,7 @@ int snd_msnd_DAPQ(struct snd_msnd *chip, int start)
|
||||
{
|
||||
u16 DAPQ_tail;
|
||||
int protect = start, nbanks = 0;
|
||||
void *DAQD;
|
||||
void __iomem *DAQD;
|
||||
static int play_banks_submitted;
|
||||
/* unsigned long flags;
|
||||
spin_lock_irqsave(&chip->lock, flags); not necessary */
|
||||
@@ -370,7 +370,7 @@ static void snd_msnd_play_reset_queue(struct snd_msnd *chip,
|
||||
unsigned int pcm_count)
|
||||
{
|
||||
int n;
|
||||
void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF;
|
||||
void __iomem *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF;
|
||||
|
||||
chip->last_playbank = -1;
|
||||
chip->playLimit = pcm_count * (pcm_periods - 1);
|
||||
@@ -398,7 +398,7 @@ static void snd_msnd_capture_reset_queue(struct snd_msnd *chip,
|
||||
unsigned int pcm_count)
|
||||
{
|
||||
int n;
|
||||
void *pDAQ;
|
||||
void __iomem *pDAQ;
|
||||
/* unsigned long flags; */
|
||||
|
||||
/* snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); */
|
||||
@@ -485,7 +485,7 @@ static int snd_msnd_playback_open(struct snd_pcm_substream *substream)
|
||||
clear_bit(F_WRITING, &chip->flags);
|
||||
snd_msnd_enable_irq(chip);
|
||||
|
||||
runtime->dma_area = chip->mappedbase;
|
||||
runtime->dma_area = (__force void *)chip->mappedbase;
|
||||
runtime->dma_bytes = 0x3000;
|
||||
|
||||
chip->playback_substream = substream;
|
||||
@@ -508,7 +508,7 @@ static int snd_msnd_playback_hw_params(struct snd_pcm_substream *substream,
|
||||
{
|
||||
int i;
|
||||
struct snd_msnd *chip = snd_pcm_substream_chip(substream);
|
||||
void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF;
|
||||
void __iomem *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF;
|
||||
|
||||
chip->play_sample_size = snd_pcm_format_width(params_format(params));
|
||||
chip->play_channels = params_channels(params);
|
||||
@@ -589,7 +589,7 @@ static int snd_msnd_capture_open(struct snd_pcm_substream *substream)
|
||||
|
||||
set_bit(F_AUDIO_READ_INUSE, &chip->flags);
|
||||
snd_msnd_enable_irq(chip);
|
||||
runtime->dma_area = chip->mappedbase + 0x3000;
|
||||
runtime->dma_area = (__force void *)chip->mappedbase + 0x3000;
|
||||
runtime->dma_bytes = 0x3000;
|
||||
memset(runtime->dma_area, 0, runtime->dma_bytes);
|
||||
chip->capture_substream = substream;
|
||||
@@ -654,7 +654,7 @@ static int snd_msnd_capture_hw_params(struct snd_pcm_substream *substream,
|
||||
{
|
||||
int i;
|
||||
struct snd_msnd *chip = snd_pcm_substream_chip(substream);
|
||||
void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF;
|
||||
void __iomem *pDAQ = chip->mappedbase + DARQ_DATA_BUFF;
|
||||
|
||||
chip->capture_sample_size = snd_pcm_format_width(params_format(params));
|
||||
chip->capture_channels = params_channels(params);
|
||||
|
@@ -283,7 +283,7 @@ struct snd_msnd {
|
||||
|
||||
};
|
||||
|
||||
void snd_msnd_init_queue(void *base, int start, int size);
|
||||
void snd_msnd_init_queue(void __iomem *base, int start, int size);
|
||||
|
||||
int snd_msnd_send_dsp_cmd(struct snd_msnd *chip, u8 cmd);
|
||||
int snd_msnd_send_word(struct snd_msnd *chip,
|
||||
|
@@ -119,7 +119,7 @@ void snd_msndmidi_input_read(void *mpuv)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct snd_msndmidi *mpu = mpuv;
|
||||
void *pwMIDQData = mpu->dev->mappedbase + MIDQ_DATA_BUFF;
|
||||
void __iomem *pwMIDQData = mpu->dev->mappedbase + MIDQ_DATA_BUFF;
|
||||
u16 head, tail, size;
|
||||
|
||||
spin_lock_irqsave(&mpu->input_lock, flags);
|
||||
|
@@ -82,10 +82,10 @@
|
||||
|
||||
static void set_default_audio_parameters(struct snd_msnd *chip)
|
||||
{
|
||||
chip->play_sample_size = DEFSAMPLESIZE;
|
||||
chip->play_sample_size = snd_pcm_format_width(DEFSAMPLESIZE);
|
||||
chip->play_sample_rate = DEFSAMPLERATE;
|
||||
chip->play_channels = DEFCHANNELS;
|
||||
chip->capture_sample_size = DEFSAMPLESIZE;
|
||||
chip->capture_sample_size = snd_pcm_format_width(DEFSAMPLESIZE);
|
||||
chip->capture_sample_rate = DEFSAMPLERATE;
|
||||
chip->capture_channels = DEFCHANNELS;
|
||||
}
|
||||
@@ -169,7 +169,7 @@ static void snd_msnd_eval_dsp_msg(struct snd_msnd *chip, u16 wMessage)
|
||||
static irqreturn_t snd_msnd_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct snd_msnd *chip = dev_id;
|
||||
void *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF;
|
||||
void __iomem *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF;
|
||||
u16 head, tail, size;
|
||||
|
||||
/* Send ack to DSP */
|
||||
@@ -810,7 +810,7 @@ module_param(calibrate_signal, int, 0444);
|
||||
#ifndef MSND_CLASSIC
|
||||
module_param_array(digital, int, NULL, 0444);
|
||||
module_param_hw_array(cfg, long, ioport, NULL, 0444);
|
||||
module_param_array(reset, int, 0, 0444);
|
||||
module_param_array(reset, int, NULL, 0444);
|
||||
module_param_hw_array(mpu_io, long, ioport, NULL, 0444);
|
||||
module_param_hw_array(mpu_irq, int, irq, NULL, 0444);
|
||||
module_param_hw_array(ide_io0, long, ioport, NULL, 0444);
|
||||
|
@@ -176,10 +176,13 @@ static int aci_busy_wait(struct snd_miro_aci *aci)
|
||||
switch (timeout-ACI_MINTIME) {
|
||||
case 0 ... 9:
|
||||
out /= 10;
|
||||
/* fall through */
|
||||
case 10 ... 19:
|
||||
out /= 10;
|
||||
/* fall through */
|
||||
case 20 ... 30:
|
||||
out /= 10;
|
||||
/* fall through */
|
||||
default:
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(out);
|
||||
@@ -834,6 +837,7 @@ static unsigned char snd_miro_read(struct snd_miro *chip,
|
||||
retval = inb(chip->mc_base + 9);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
|
||||
case OPTi9XX_HW_82C929:
|
||||
retval = inb(chip->mc_base + reg);
|
||||
@@ -863,6 +867,7 @@ static void snd_miro_write(struct snd_miro *chip, unsigned char reg,
|
||||
outb(value, chip->mc_base + 9);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
|
||||
case OPTi9XX_HW_82C929:
|
||||
outb(value, chip->mc_base + reg);
|
||||
|
@@ -261,6 +261,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
|
||||
retval = inb(chip->mc_base + 9);
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
case OPTi9XX_HW_82C928:
|
||||
case OPTi9XX_HW_82C929:
|
||||
@@ -303,6 +304,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
|
||||
outb(value, chip->mc_base + 9);
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
case OPTi9XX_HW_82C928:
|
||||
case OPTi9XX_HW_82C929:
|
||||
@@ -350,6 +352,7 @@ static int snd_opti9xx_configure(struct snd_opti9xx *chip,
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
|
||||
/* enable wave audio */
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
|
||||
/* Fall through */
|
||||
|
||||
case OPTi9XX_HW_82C925:
|
||||
/* enable WSS mode */
|
||||
|
@@ -165,11 +165,8 @@ snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
|
||||
return 0;
|
||||
|
||||
/* be sure loop points start < end */
|
||||
if (sp->v.loopstart > sp->v.loopend) {
|
||||
int tmp = sp->v.loopstart;
|
||||
sp->v.loopstart = sp->v.loopend;
|
||||
sp->v.loopend = tmp;
|
||||
}
|
||||
if (sp->v.loopstart > sp->v.loopend)
|
||||
swap(sp->v.loopstart, sp->v.loopend);
|
||||
|
||||
/* compute true data size to be loaded */
|
||||
truesize = sp->v.size;
|
||||
|
@@ -470,7 +470,7 @@ static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
|
||||
/* convert to word unit */
|
||||
pos = (pos << 1) + rec->loop_start[voice];
|
||||
count <<= 1;
|
||||
LOOP_WRITE(rec, pos, src, count, COPY_UESR);
|
||||
LOOP_WRITE(rec, pos, src, count, COPY_USER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -60,18 +60,18 @@ MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp");
|
||||
* RIFF data format
|
||||
*/
|
||||
struct riff_header {
|
||||
__u32 name;
|
||||
__u32 len;
|
||||
__le32 name;
|
||||
__le32 len;
|
||||
};
|
||||
|
||||
struct desc_header {
|
||||
struct riff_header info;
|
||||
__u16 func_nr;
|
||||
__u16 VOC_type;
|
||||
__u16 flags_play_rec;
|
||||
__u16 flags_16bit_8bit;
|
||||
__u16 flags_stereo_mono;
|
||||
__u16 flags_rates;
|
||||
__le16 func_nr;
|
||||
__le16 VOC_type;
|
||||
__le16 flags_play_rec;
|
||||
__le16 flags_16bit_8bit;
|
||||
__le16 flags_stereo_mono;
|
||||
__le16 flags_rates;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -93,7 +93,7 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
|
||||
struct snd_sb_csp_microcode __user * code);
|
||||
static int snd_sb_csp_unload(struct snd_sb_csp * p);
|
||||
static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags);
|
||||
static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode);
|
||||
static int snd_sb_csp_autoload(struct snd_sb_csp * p, snd_pcm_format_t pcm_sfmt, int play_rec_mode);
|
||||
static int snd_sb_csp_check_version(struct snd_sb_csp * p);
|
||||
|
||||
static int snd_sb_csp_use(struct snd_sb_csp * p);
|
||||
@@ -314,7 +314,7 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
|
||||
unsigned short func_nr = 0;
|
||||
|
||||
struct riff_header file_h, item_h, code_h;
|
||||
__u32 item_type;
|
||||
__le32 item_type;
|
||||
struct desc_header funcdesc_h;
|
||||
|
||||
unsigned long flags;
|
||||
@@ -326,7 +326,7 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
|
||||
|
||||
if (copy_from_user(&file_h, data_ptr, sizeof(file_h)))
|
||||
return -EFAULT;
|
||||
if ((file_h.name != RIFF_HEADER) ||
|
||||
if ((le32_to_cpu(file_h.name) != RIFF_HEADER) ||
|
||||
(le32_to_cpu(file_h.len) >= SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE - sizeof(file_h))) {
|
||||
snd_printd("%s: Invalid RIFF header\n", __func__);
|
||||
return -EINVAL;
|
||||
@@ -336,7 +336,7 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
|
||||
|
||||
if (copy_from_user(&item_type, data_ptr, sizeof(item_type)))
|
||||
return -EFAULT;
|
||||
if (item_type != CSP__HEADER) {
|
||||
if (le32_to_cpu(item_type) != CSP__HEADER) {
|
||||
snd_printd("%s: Invalid RIFF file type\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -346,12 +346,12 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
|
||||
if (copy_from_user(&item_h, data_ptr, sizeof(item_h)))
|
||||
return -EFAULT;
|
||||
data_ptr += sizeof(item_h);
|
||||
if (item_h.name != LIST_HEADER)
|
||||
if (le32_to_cpu(item_h.name) != LIST_HEADER)
|
||||
continue;
|
||||
|
||||
if (copy_from_user(&item_type, data_ptr, sizeof(item_type)))
|
||||
return -EFAULT;
|
||||
switch (item_type) {
|
||||
switch (le32_to_cpu(item_type)) {
|
||||
case FUNC_HEADER:
|
||||
if (copy_from_user(&funcdesc_h, data_ptr + sizeof(item_type), sizeof(funcdesc_h)))
|
||||
return -EFAULT;
|
||||
@@ -378,7 +378,7 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
|
||||
return -EFAULT;
|
||||
|
||||
/* init microcode blocks */
|
||||
if (code_h.name != INIT_HEADER)
|
||||
if (le32_to_cpu(code_h.name) != INIT_HEADER)
|
||||
break;
|
||||
data_ptr += sizeof(code_h);
|
||||
err = snd_sb_csp_load_user(p, data_ptr, le32_to_cpu(code_h.len),
|
||||
@@ -391,7 +391,7 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
|
||||
if (copy_from_user(&code_h, data_ptr, sizeof(code_h)))
|
||||
return -EFAULT;
|
||||
|
||||
if (code_h.name != MAIN_HEADER) {
|
||||
if (le32_to_cpu(code_h.name) != MAIN_HEADER) {
|
||||
snd_printd("%s: Missing 'main' microcode\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -726,7 +726,7 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags)
|
||||
* autoload hardware codec if necessary
|
||||
* return 0 if CSP is loaded and ready to run (p->running != 0)
|
||||
*/
|
||||
static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode)
|
||||
static int snd_sb_csp_autoload(struct snd_sb_csp * p, snd_pcm_format_t pcm_sfmt, int play_rec_mode)
|
||||
{
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
@@ -736,7 +736,7 @@ static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec
|
||||
return -EBUSY;
|
||||
|
||||
/* autoload microcode only if requested hardware codec is not already loaded */
|
||||
if (((1 << pcm_sfmt) & p->acc_format) && (play_rec_mode & p->mode)) {
|
||||
if (((1U << (__force int)pcm_sfmt) & p->acc_format) && (play_rec_mode & p->mode)) {
|
||||
p->running = SNDRV_SB_CSP_ST_AUTO;
|
||||
} else {
|
||||
switch (pcm_sfmt) {
|
||||
@@ -1185,19 +1185,3 @@ static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buff
|
||||
/* */
|
||||
|
||||
EXPORT_SYMBOL(snd_sb_csp_new);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_sb_csp_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_sb_csp_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_sb_csp_init)
|
||||
module_exit(alsa_sb_csp_exit)
|
||||
|
@@ -49,6 +49,9 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
|
||||
MODULE_DESCRIPTION("Routines for control of 16-bit SoundBlaster cards and clones");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define runtime_format_bits(runtime) \
|
||||
((unsigned int)pcm_format_to_bits((runtime)->format))
|
||||
|
||||
#ifdef CONFIG_SND_SB16_CSP
|
||||
static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
@@ -58,7 +61,7 @@ static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_ru
|
||||
if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
|
||||
/* manually loaded codec */
|
||||
if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) &&
|
||||
((1U << runtime->format) == csp->acc_format)) {
|
||||
(runtime_format_bits(runtime) == csp->acc_format)) {
|
||||
/* Supported runtime PCM format for playback */
|
||||
if (csp->ops.csp_use(csp) == 0) {
|
||||
/* If CSP was successfully acquired */
|
||||
@@ -66,7 +69,7 @@ static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_ru
|
||||
}
|
||||
} else if ((csp->mode & SNDRV_SB_CSP_MODE_QSOUND) && (csp->q_enabled)) {
|
||||
/* QSound decoder is loaded and enabled */
|
||||
if ((1 << runtime->format) & (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
|
||||
if (runtime_format_bits(runtime) & (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE)) {
|
||||
/* Only for simple PCM formats */
|
||||
if (csp->ops.csp_use(csp) == 0) {
|
||||
@@ -106,7 +109,7 @@ static void snd_sb16_csp_capture_prepare(struct snd_sb *chip, struct snd_pcm_run
|
||||
if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
|
||||
/* manually loaded codec */
|
||||
if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) &&
|
||||
((1U << runtime->format) == csp->acc_format)) {
|
||||
(runtime_format_bits(runtime) == csp->acc_format)) {
|
||||
/* Supported runtime PCM format for capture */
|
||||
if (csp->ops.csp_use(csp) == 0) {
|
||||
/* If CSP was successfully acquired */
|
||||
@@ -897,19 +900,3 @@ EXPORT_SYMBOL(snd_sb16dsp_pcm);
|
||||
EXPORT_SYMBOL(snd_sb16dsp_get_pcm_ops);
|
||||
EXPORT_SYMBOL(snd_sb16dsp_configure);
|
||||
EXPORT_SYMBOL(snd_sb16dsp_interrupt);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_sb16_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_sb16_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_sb16_init)
|
||||
module_exit(alsa_sb16_exit)
|
||||
|
@@ -381,7 +381,6 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
|
||||
irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip)
|
||||
{
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
|
||||
snd_sb_ack_8bit(chip);
|
||||
switch (chip->mode) {
|
||||
@@ -391,7 +390,6 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip)
|
||||
/* fallthru */
|
||||
case SB_MODE_PLAYBACK_8:
|
||||
substream = chip->playback_substream;
|
||||
runtime = substream->runtime;
|
||||
if (chip->playback_format == SB_DSP_OUTPUT)
|
||||
snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START);
|
||||
snd_pcm_period_elapsed(substream);
|
||||
@@ -402,7 +400,6 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip)
|
||||
/* fallthru */
|
||||
case SB_MODE_CAPTURE_8:
|
||||
substream = chip->capture_substream;
|
||||
runtime = substream->runtime;
|
||||
if (chip->capture_format == SB_DSP_INPUT)
|
||||
snd_sb8_capture_trigger(substream, SNDRV_PCM_TRIGGER_START);
|
||||
snd_pcm_period_elapsed(substream);
|
||||
@@ -624,19 +621,3 @@ EXPORT_SYMBOL(snd_sb8dsp_interrupt);
|
||||
/* sb8_midi.c */
|
||||
EXPORT_SYMBOL(snd_sb8dsp_midi_interrupt);
|
||||
EXPORT_SYMBOL(snd_sb8dsp_midi);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_sb8_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_sb8_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_sb8_init)
|
||||
module_exit(alsa_sb8_exit)
|
||||
|
@@ -305,19 +305,3 @@ EXPORT_SYMBOL(snd_sbmixer_add_ctl);
|
||||
EXPORT_SYMBOL(snd_sbmixer_suspend);
|
||||
EXPORT_SYMBOL(snd_sbmixer_resume);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_sb_common_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_sb_common_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_sb_common_init)
|
||||
module_exit(alsa_sb_common_exit)
|
||||
|
@@ -541,7 +541,7 @@ static unsigned char snd_wss_get_rate(unsigned int rate)
|
||||
}
|
||||
|
||||
static unsigned char snd_wss_get_format(struct snd_wss *chip,
|
||||
int format,
|
||||
snd_pcm_format_t format,
|
||||
int channels)
|
||||
{
|
||||
unsigned char rformat;
|
||||
@@ -2279,19 +2279,3 @@ const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction)
|
||||
&snd_wss_playback_ops : &snd_wss_capture_ops;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_wss_get_pcm_ops);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_wss_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_wss_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_wss_init);
|
||||
module_exit(alsa_wss_exit);
|
||||
|
@@ -685,7 +685,6 @@ static const struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
|
||||
.trigger = snd_sgio2audio_pcm_trigger,
|
||||
.pointer = snd_sgio2audio_pcm_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
static const struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
|
||||
@@ -698,7 +697,6 @@ static const struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
|
||||
.trigger = snd_sgio2audio_pcm_trigger,
|
||||
.pointer = snd_sgio2audio_pcm_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
static const struct snd_pcm_ops snd_sgio2audio_capture_ops = {
|
||||
@@ -711,7 +709,6 @@ static const struct snd_pcm_ops snd_sgio2audio_capture_ops = {
|
||||
.trigger = snd_sgio2audio_pcm_trigger,
|
||||
.pointer = snd_sgio2audio_pcm_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -2941,19 +2941,3 @@ int snd_ac97_tune_hardware(struct snd_ac97 *ac97,
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_ac97_tune_hardware);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_ac97_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_ac97_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_ac97_init)
|
||||
module_exit(alsa_ac97_exit)
|
||||
|
@@ -1484,12 +1484,9 @@ static struct snd_pcm_hardware snd_ali_capture =
|
||||
static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
struct snd_ali_voice *pvoice = runtime->private_data;
|
||||
struct snd_ali *codec;
|
||||
|
||||
if (pvoice) {
|
||||
codec = pvoice->codec;
|
||||
if (pvoice)
|
||||
snd_ali_free_voice(pvoice->codec, pvoice);
|
||||
}
|
||||
}
|
||||
|
||||
static int snd_ali_open(struct snd_pcm_substream *substream, int rec,
|
||||
|
@@ -311,27 +311,29 @@ static void print_hwparams(struct snd_pcm_substream *substream,
|
||||
snd_pcm_format_width(params_format(p)) / 8);
|
||||
}
|
||||
|
||||
#define INVALID_FORMAT (__force snd_pcm_format_t)(-1)
|
||||
|
||||
static snd_pcm_format_t hpi_to_alsa_formats[] = {
|
||||
-1, /* INVALID */
|
||||
INVALID_FORMAT, /* INVALID */
|
||||
SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
|
||||
SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
|
||||
-1, /* HPI_FORMAT_MPEG_L1 3 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_MPEG_L1 3 */
|
||||
SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
|
||||
SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
|
||||
-1, /* HPI_FORMAT_DOLBY_AC2 6 */
|
||||
-1, /* HPI_FORMAT_DOLBY_AC3 7 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_DOLBY_AC2 6 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_DOLBY_AC3 7 */
|
||||
SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
|
||||
-1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
|
||||
-1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
|
||||
SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
|
||||
-1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
|
||||
-1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_RAW_BITSTREAM 12 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
|
||||
SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
|
||||
#if 1
|
||||
/* ALSA can't handle 3 byte sample size together with power-of-2
|
||||
* constraint on buffer_bytes, so disable this format
|
||||
*/
|
||||
-1
|
||||
INVALID_FORMAT
|
||||
#else
|
||||
/* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
|
||||
#endif
|
||||
@@ -1023,7 +1025,7 @@ static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
|
||||
format, sample_rate, 128000, 0);
|
||||
if (!err)
|
||||
err = hpi_outstream_query_format(h_stream, &hpi_format);
|
||||
if (!err && (hpi_to_alsa_formats[format] != -1))
|
||||
if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT))
|
||||
formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]);
|
||||
}
|
||||
return formats;
|
||||
@@ -1205,7 +1207,7 @@ static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
|
||||
format, sample_rate, 128000, 0);
|
||||
if (!err)
|
||||
err = hpi_instream_query_format(h_stream, &hpi_format);
|
||||
if (!err && (hpi_to_alsa_formats[format] != -1))
|
||||
if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT))
|
||||
formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]);
|
||||
}
|
||||
return formats;
|
||||
|
@@ -635,7 +635,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
|
||||
{
|
||||
struct hpi_message hm;
|
||||
struct hpi_response hr;
|
||||
u32 max_streams;
|
||||
|
||||
HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
|
||||
memset(&hm, 0, sizeof(hm));
|
||||
@@ -660,10 +659,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
|
||||
pao->type = hr.u.ax.info.adapter_type;
|
||||
pao->index = hr.u.ax.info.adapter_index;
|
||||
|
||||
max_streams =
|
||||
hr.u.ax.info.num_outstreams +
|
||||
hr.u.ax.info.num_instreams;
|
||||
|
||||
HPI_DEBUG_LOG(VERBOSE,
|
||||
"got adapter info type %x index %d serial %d\n",
|
||||
hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
|
||||
|
@@ -207,10 +207,10 @@ struct atiixp;
|
||||
*/
|
||||
|
||||
struct atiixp_dma_desc {
|
||||
u32 addr; /* DMA buffer address */
|
||||
__le32 addr; /* DMA buffer address */
|
||||
u16 status; /* status bits */
|
||||
u16 size; /* size of the packet in dwords */
|
||||
u32 next; /* address of the next packet descriptor */
|
||||
__le32 next; /* address of the next packet descriptor */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -183,10 +183,10 @@ struct atiixp_modem;
|
||||
*/
|
||||
|
||||
struct atiixp_dma_desc {
|
||||
u32 addr; /* DMA buffer address */
|
||||
__le32 addr; /* DMA buffer address */
|
||||
u16 status; /* status bits */
|
||||
u16 size; /* size of the packet in dwords */
|
||||
u32 next; /* address of the next packet descriptor */
|
||||
__le32 next; /* address of the next packet descriptor */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -241,7 +241,7 @@ static int vortex_core_init(vortex_t * card);
|
||||
static int vortex_core_shutdown(vortex_t * card);
|
||||
static void vortex_enable_int(vortex_t * card);
|
||||
static irqreturn_t vortex_interrupt(int irq, void *dev_id);
|
||||
static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v);
|
||||
static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v);
|
||||
|
||||
/* Connection stuff. */
|
||||
static void vortex_connect_default(vortex_t * vortex, int en);
|
||||
|
@@ -2770,7 +2770,7 @@ static int vortex_core_shutdown(vortex_t * vortex)
|
||||
|
||||
/* Alsa support. */
|
||||
|
||||
static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v)
|
||||
static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v)
|
||||
{
|
||||
int fmt;
|
||||
|
||||
|
@@ -228,14 +228,14 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea
|
||||
unsigned int periods, unsigned int period_bytes)
|
||||
{
|
||||
unsigned int i, offset;
|
||||
u32 *risc;
|
||||
__le32 *risc;
|
||||
|
||||
if (chip->dma_risc.area == NULL) {
|
||||
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
|
||||
PAGE_ALIGN(MAX_RISC_SIZE), &chip->dma_risc) < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
risc = (u32 *)chip->dma_risc.area;
|
||||
risc = (__le32 *)chip->dma_risc.area;
|
||||
offset = 0;
|
||||
*risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_FM1);
|
||||
*risc++ = cpu_to_le32(0);
|
||||
|
@@ -73,13 +73,10 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
|
||||
{
|
||||
struct proc_scb_info * scb_info = entry->private_data;
|
||||
struct dsp_scb_descriptor * scb = scb_info->scb_desc;
|
||||
struct dsp_spos_instance * ins;
|
||||
struct snd_cs46xx *chip = scb_info->chip;
|
||||
int j,col;
|
||||
void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
|
||||
|
||||
ins = chip->dsp_spos_instance;
|
||||
|
||||
mutex_lock(&chip->spos_mutex);
|
||||
snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name);
|
||||
|
||||
|
@@ -192,8 +192,6 @@ static void process_bm0_irq(struct cs5535audio *cs5535au)
|
||||
bm_stat = cs_readb(cs5535au, ACC_BM0_STATUS);
|
||||
spin_unlock(&cs5535au->reg_lock);
|
||||
if (bm_stat & EOP) {
|
||||
struct cs5535audio_dma *dma;
|
||||
dma = cs5535au->playback_substream->runtime->private_data;
|
||||
snd_pcm_period_elapsed(cs5535au->playback_substream);
|
||||
} else {
|
||||
dev_err(cs5535au->card->dev,
|
||||
@@ -208,11 +206,8 @@ static void process_bm1_irq(struct cs5535audio *cs5535au)
|
||||
spin_lock(&cs5535au->reg_lock);
|
||||
bm_stat = cs_readb(cs5535au, ACC_BM1_STATUS);
|
||||
spin_unlock(&cs5535au->reg_lock);
|
||||
if (bm_stat & EOP) {
|
||||
struct cs5535audio_dma *dma;
|
||||
dma = cs5535au->capture_substream->runtime->private_data;
|
||||
if (bm_stat & EOP)
|
||||
snd_pcm_period_elapsed(cs5535au->capture_substream);
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
|
||||
|
@@ -1319,7 +1319,7 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
|
||||
break;
|
||||
|
||||
hw_write_20kx(hw, PLLCTL, pllctl);
|
||||
mdelay(40);
|
||||
msleep(40);
|
||||
}
|
||||
if (i >= 3) {
|
||||
dev_alert(hw->card->dev, "PLL initialization failed!!!\n");
|
||||
@@ -1407,7 +1407,7 @@ static int hw_reset_dac(struct hw *hw)
|
||||
/* To be effective, need to reset the DAC twice. */
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* set gpio */
|
||||
mdelay(100);
|
||||
msleep(100);
|
||||
gpioorg = (u16)hw_read_20kx(hw, GPIO);
|
||||
gpioorg &= 0xfffd;
|
||||
hw_write_20kx(hw, GPIO, gpioorg);
|
||||
@@ -2030,7 +2030,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
|
||||
hw_write_20kx(hw, GIE, 0);
|
||||
/* Reset all SRC pending interrupts */
|
||||
hw_write_20kx(hw, SRCIP, 0);
|
||||
mdelay(30);
|
||||
msleep(30);
|
||||
|
||||
/* Detect the card ID and configure GPIO accordingly. */
|
||||
switch (hw->model) {
|
||||
|
@@ -1316,12 +1316,12 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
|
||||
set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4);
|
||||
set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1);
|
||||
hw_write_20kx(hw, PLL_CTL, pllctl);
|
||||
mdelay(40);
|
||||
msleep(40);
|
||||
|
||||
pllctl = hw_read_20kx(hw, PLL_CTL);
|
||||
set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2);
|
||||
hw_write_20kx(hw, PLL_CTL, pllctl);
|
||||
mdelay(40);
|
||||
msleep(40);
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
pllstat = hw_read_20kx(hw, PLL_STAT);
|
||||
@@ -1584,7 +1584,7 @@ static void hw_dac_stop(struct hw *hw)
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data &= 0xFFFFFFFD;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(10);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
|
||||
static void hw_dac_start(struct hw *hw)
|
||||
@@ -1593,7 +1593,7 @@ static void hw_dac_start(struct hw *hw)
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data |= 0x2;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(50);
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
static void hw_dac_reset(struct hw *hw)
|
||||
@@ -1864,11 +1864,11 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
}
|
||||
|
||||
mdelay(10);
|
||||
usleep_range(10000, 11000);
|
||||
/* Return the ADC to normal operation. */
|
||||
data |= (0x1 << 15);
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(50);
|
||||
msleep(50);
|
||||
|
||||
/* I2C write to register offset 0x0B to set ADC LRCLK polarity */
|
||||
/* invert bit, interface format to I2S, word length to 24-bit, */
|
||||
|
@@ -938,17 +938,18 @@ static int ct_mixer_topology_build(struct ct_mixer *mixer)
|
||||
struct sum *sum;
|
||||
struct amixer *amix_d, *amix_s;
|
||||
enum CT_AMIXER_CTL i, j;
|
||||
enum CT_SUM_CTL k;
|
||||
|
||||
/* Build topology from destination to source */
|
||||
|
||||
/* Set up Master mixer */
|
||||
for (i = AMIXER_MASTER_F, j = SUM_IN_F;
|
||||
i <= AMIXER_MASTER_S; i++, j++) {
|
||||
for (i = AMIXER_MASTER_F, k = SUM_IN_F;
|
||||
i <= AMIXER_MASTER_S; i++, k++) {
|
||||
amix_d = mixer->amixers[i*CHN_NUM];
|
||||
sum = mixer->sums[j*CHN_NUM];
|
||||
sum = mixer->sums[k*CHN_NUM];
|
||||
amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
|
||||
amix_d = mixer->amixers[i*CHN_NUM+1];
|
||||
sum = mixer->sums[j*CHN_NUM+1];
|
||||
sum = mixer->sums[k*CHN_NUM+1];
|
||||
amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
|
||||
}
|
||||
|
||||
@@ -972,12 +973,12 @@ static int ct_mixer_topology_build(struct ct_mixer *mixer)
|
||||
amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
|
||||
|
||||
/* Set up PCM-in mixer */
|
||||
for (i = AMIXER_PCM_F, j = SUM_IN_F; i <= AMIXER_PCM_S; i++, j++) {
|
||||
for (i = AMIXER_PCM_F, k = SUM_IN_F; i <= AMIXER_PCM_S; i++, k++) {
|
||||
amix_d = mixer->amixers[i*CHN_NUM];
|
||||
sum = mixer->sums[j*CHN_NUM];
|
||||
sum = mixer->sums[k*CHN_NUM];
|
||||
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
|
||||
amix_d = mixer->amixers[i*CHN_NUM+1];
|
||||
sum = mixer->sums[j*CHN_NUM+1];
|
||||
sum = mixer->sums[k*CHN_NUM+1];
|
||||
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
|
||||
}
|
||||
|
||||
|
@@ -713,6 +713,7 @@ static int pcm_prepare(struct snd_pcm_substream *substream)
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S32_BE:
|
||||
format.data_are_bigendian = 1;
|
||||
/* fall through */
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
format.bits_per_sample = 32;
|
||||
break;
|
||||
@@ -764,6 +765,7 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
pipe->last_counter = 0;
|
||||
pipe->position = 0;
|
||||
*pipe->dma_counter = 0;
|
||||
/* fall through */
|
||||
case PIPE_STATE_PAUSED:
|
||||
pipe->state = PIPE_STATE_STARTED;
|
||||
break;
|
||||
|
برخی از فایل ها نشان داده نشدند زیرا تعداد زیادی فایل در این تفاوت تغییر کرده اند نمایش بیشتر
مرجع در شماره جدید
Block a user