projects
/
powerpc.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
[ALSA] hda-codec - Control SPDIF as slave
[powerpc.git]
/
sound
/
sh
/
aica.c
diff --git
a/sound/sh/aica.c
b/sound/sh/aica.c
index
7397865
..
d49417b
100644
(file)
--- a/
sound/sh/aica.c
+++ b/
sound/sh/aica.c
@@
-35,7
+35,6
@@
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
-#include <sound/driver.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
@@
-106,11
+105,14
@@
static void spu_write_wait(void)
static void spu_memset(u32 toi, u32 what, int length)
{
int i;
static void spu_memset(u32 toi, u32 what, int length)
{
int i;
+ unsigned long flags;
snd_assert(length % 4 == 0, return);
for (i = 0; i < length; i++) {
if (!(i % 8))
spu_write_wait();
snd_assert(length % 4 == 0, return);
for (i = 0; i < length; i++) {
if (!(i % 8))
spu_write_wait();
+ local_irq_save(flags);
writel(what, toi + SPU_MEMORY_BASE);
writel(what, toi + SPU_MEMORY_BASE);
+ local_irq_restore(flags);
toi++;
}
}
toi++;
}
}
@@
-118,6
+120,7
@@
static void spu_memset(u32 toi, u32 what, int length)
/* spu_memload - write to SPU address space */
static void spu_memload(u32 toi, void *from, int length)
{
/* spu_memload - write to SPU address space */
static void spu_memload(u32 toi, void *from, int length)
{
+ unsigned long flags;
u32 *froml = from;
u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi);
int i;
u32 *froml = from;
u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi);
int i;
@@
-128,7
+131,9
@@
static void spu_memload(u32 toi, void *from, int length)
if (!(i % 8))
spu_write_wait();
val = *froml;
if (!(i % 8))
spu_write_wait();
val = *froml;
+ local_irq_save(flags);
writel(val, to);
writel(val, to);
+ local_irq_restore(flags);
froml++;
to++;
}
froml++;
to++;
}
@@
-138,28
+143,36
@@
static void spu_memload(u32 toi, void *from, int length)
static void spu_disable(void)
{
int i;
static void spu_disable(void)
{
int i;
+ unsigned long flags;
u32 regval;
spu_write_wait();
regval = readl(ARM_RESET_REGISTER);
regval |= 1;
spu_write_wait();
u32 regval;
spu_write_wait();
regval = readl(ARM_RESET_REGISTER);
regval |= 1;
spu_write_wait();
+ local_irq_save(flags);
writel(regval, ARM_RESET_REGISTER);
writel(regval, ARM_RESET_REGISTER);
+ local_irq_restore(flags);
for (i = 0; i < 64; i++) {
spu_write_wait();
regval = readl(SPU_REGISTER_BASE + (i * 0x80));
regval = (regval & ~0x4000) | 0x8000;
spu_write_wait();
for (i = 0; i < 64; i++) {
spu_write_wait();
regval = readl(SPU_REGISTER_BASE + (i * 0x80));
regval = (regval & ~0x4000) | 0x8000;
spu_write_wait();
+ local_irq_save(flags);
writel(regval, SPU_REGISTER_BASE + (i * 0x80));
writel(regval, SPU_REGISTER_BASE + (i * 0x80));
+ local_irq_restore(flags);
}
}
/* spu_enable - set spu registers to enable sound output */
static void spu_enable(void)
{
}
}
/* spu_enable - set spu registers to enable sound output */
static void spu_enable(void)
{
+ unsigned long flags;
u32 regval = readl(ARM_RESET_REGISTER);
regval &= ~1;
spu_write_wait();
u32 regval = readl(ARM_RESET_REGISTER);
regval &= ~1;
spu_write_wait();
+ local_irq_save(flags);
writel(regval, ARM_RESET_REGISTER);
writel(regval, ARM_RESET_REGISTER);
+ local_irq_restore(flags);
}
/*
}
/*
@@
-168,25
+181,34
@@
static void spu_enable(void)
*/
static void spu_reset(void)
{
*/
static void spu_reset(void)
{
+ unsigned long flags;
spu_disable();
spu_memset(0, 0, 0x200000 / 4);
/* Put ARM7 in endless loop */
spu_disable();
spu_memset(0, 0, 0x200000 / 4);
/* Put ARM7 in endless loop */
+ local_irq_save(flags);
ctrl_outl(0xea000002, SPU_MEMORY_BASE);
ctrl_outl(0xea000002, SPU_MEMORY_BASE);
+ local_irq_restore(flags);
spu_enable();
}
/* aica_chn_start - write to spu to start playback */
static void aica_chn_start(void)
{
spu_enable();
}
/* aica_chn_start - write to spu to start playback */
static void aica_chn_start(void)
{
+ unsigned long flags;
spu_write_wait();
spu_write_wait();
+ local_irq_save(flags);
writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT);
writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT);
+ local_irq_restore(flags);
}
/* aica_chn_halt - write to spu to halt playback */
static void aica_chn_halt(void)
{
}
/* aica_chn_halt - write to spu to halt playback */
static void aica_chn_halt(void)
{
+ unsigned long flags;
spu_write_wait();
spu_write_wait();
+ local_irq_save(flags);
writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT);
writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT);
+ local_irq_restore(flags);
}
/* ALSA code below */
}
/* ALSA code below */
@@
-213,12
+235,14
@@
static int aica_dma_transfer(int channels, int buffer_size,
int q, err, period_offset;
struct snd_card_aica *dreamcastcard;
struct snd_pcm_runtime *runtime;
int q, err, period_offset;
struct snd_card_aica *dreamcastcard;
struct snd_pcm_runtime *runtime;
+ unsigned long flags;
err = 0;
dreamcastcard = substream->pcm->private_data;
period_offset = dreamcastcard->clicks;
period_offset %= (AICA_PERIOD_NUMBER / channels);
runtime = substream->runtime;
for (q = 0; q < channels; q++) {
err = 0;
dreamcastcard = substream->pcm->private_data;
period_offset = dreamcastcard->clicks;
period_offset %= (AICA_PERIOD_NUMBER / channels);
runtime = substream->runtime;
for (q = 0; q < channels; q++) {
+ local_irq_save(flags);
err = dma_xfer(AICA_DMA_CHANNEL,
(unsigned long) (runtime->dma_area +
(AICA_BUFFER_SIZE * q) /
err = dma_xfer(AICA_DMA_CHANNEL,
(unsigned long) (runtime->dma_area +
(AICA_BUFFER_SIZE * q) /
@@
-228,9
+252,12
@@
static int aica_dma_transfer(int channels, int buffer_size,
AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET +
AICA_PERIOD_SIZE * period_offset,
buffer_size / channels, AICA_DMA_MODE);
AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET +
AICA_PERIOD_SIZE * period_offset,
buffer_size / channels, AICA_DMA_MODE);
- if (unlikely(err < 0))
+ if (unlikely(err < 0)) {
+ local_irq_restore(flags);
break;
break;
+ }
dma_wait_for_completion(AICA_DMA_CHANNEL);
dma_wait_for_completion(AICA_DMA_CHANNEL);
+ local_irq_restore(flags);
}
return err;
}
}
return err;
}
@@
-451,15
+478,7
@@
static int __init snd_aicapcmchip(struct snd_card_aica
}
/* Mixer controls */
}
/* Mixer controls */
-static int aica_pcmswitch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define aica_pcmswitch_info snd_ctl_boolean_mono_info
static int aica_pcmswitch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
static int aica_pcmswitch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@
-503,11
+522,14
@@
static int aica_pcmvolume_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_card_aica *dreamcastcard;
struct snd_ctl_elem_value *ucontrol)
{
struct snd_card_aica *dreamcastcard;
+ unsigned int vol;
dreamcastcard = kcontrol->private_data;
if (unlikely(!dreamcastcard->channel))
return -ETXTBSY;
dreamcastcard = kcontrol->private_data;
if (unlikely(!dreamcastcard->channel))
return -ETXTBSY;
- if (unlikely(dreamcastcard->channel->vol ==
- ucontrol->value.integer.value[0]))
+ vol = ucontrol->value.integer.value[0];
+ if (vol > 0xff)
+ return -EINVAL;
+ if (unlikely(dreamcastcard->channel->vol == vol))
return 0;
dreamcastcard->channel->vol = ucontrol->value.integer.value[0];
dreamcastcard->master_volume = ucontrol->value.integer.value[0];
return 0;
dreamcastcard->channel->vol = ucontrol->value.integer.value[0];
dreamcastcard->master_volume = ucontrol->value.integer.value[0];