struct snd_rawmidi_substream, list);
}
+static void enable_midi_irq(struct snd_ice1712 *ice, u8 flag, int enable);
+
static void vt1724_midi_write(struct snd_ice1712 *ice)
{
struct snd_rawmidi_substream *s;
for (i = 0; i < count; ++i)
outb(buffer[i], ICEREG1724(ice, MPU_DATA));
}
+ /* mask irq when all bytes have been transmitted.
+ * enabled again in output_trigger when the new data comes in.
+ */
+ enable_midi_irq(ice, VT1724_IRQ_MPU_TX,
+ !snd_rawmidi_transmit_empty(s));
}
static void vt1724_midi_read(struct snd_ice1712 *ice)
}
}
-static void vt1724_enable_midi_irq(struct snd_rawmidi_substream *substream,
- u8 flag, int enable)
+/* call with ice->reg_lock */
+static void enable_midi_irq(struct snd_ice1712 *ice, u8 flag, int enable)
{
- struct snd_ice1712 *ice = substream->rmidi->private_data;
- u8 mask;
-
- spin_lock_irq(&ice->reg_lock);
- mask = inb(ICEREG1724(ice, IRQMASK));
+ u8 mask = inb(ICEREG1724(ice, IRQMASK));
if (enable)
mask &= ~flag;
else
mask |= flag;
outb(mask, ICEREG1724(ice, IRQMASK));
+}
+
+static void vt1724_enable_midi_irq(struct snd_rawmidi_substream *substream,
+ u8 flag, int enable)
+{
+ struct snd_ice1712 *ice = substream->rmidi->private_data;
+
+ spin_lock_irq(&ice->reg_lock);
+ enable_midi_irq(ice, flag, enable);
spin_unlock_irq(&ice->reg_lock);
}
static int vt1724_midi_output_open(struct snd_rawmidi_substream *s)
{
- vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 1);
return 0;
}
static int vt1724_midi_output_close(struct snd_rawmidi_substream *s)
{
- vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 0);
return 0;
}
vt1724_midi_write(ice);
} else {
ice->midi_output = 0;
+ enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
}
spin_unlock_irqrestore(&ice->reg_lock, flags);
}
struct snd_ice1712 *ice = s->rmidi->private_data;
unsigned long timeout;
+ vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 0);
/* 32 bytes should be transmitted in less than about 12 ms */
timeout = jiffies + msecs_to_jiffies(15);
do {
status &= status_mask;
if (status == 0)
break;
+ spin_lock(&ice->reg_lock);
if (++timeout > 10) {
status = inb(ICEREG1724(ice, IRQSTAT));
printk(KERN_ERR "ice1724: Too long irq loop, "
"status = 0x%x\n", status);
if (status & VT1724_IRQ_MPU_TX) {
printk(KERN_ERR "ice1724: Disabling MPU_TX\n");
- outb(inb(ICEREG1724(ice, IRQMASK)) |
- VT1724_IRQ_MPU_TX,
- ICEREG1724(ice, IRQMASK));
+ enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
}
+ spin_unlock(&ice->reg_lock);
break;
}
handled = 1;
if (status & VT1724_IRQ_MPU_TX) {
- spin_lock(&ice->reg_lock);
if (ice->midi_output)
vt1724_midi_write(ice);
- spin_unlock(&ice->reg_lock);
+ else
+ enable_midi_irq(ice, VT1724_IRQ_MPU_TX, 0);
/* Due to mysterical reasons, MPU_TX is always
* generated (and can't be cleared) when a PCM
* playback is going. So let's ignore at the
status_mask &= ~VT1724_IRQ_MPU_TX;
}
if (status & VT1724_IRQ_MPU_RX) {
- spin_lock(&ice->reg_lock);
if (ice->midi_input)
vt1724_midi_read(ice);
else
vt1724_midi_clear_rx(ice);
- spin_unlock(&ice->reg_lock);
}
/* ack MPU irq */
outb(status, ICEREG1724(ice, IRQSTAT));
+ spin_unlock(&ice->reg_lock);
if (status & VT1724_IRQ_MTPCM) {
/*
* Multi-track PCM
spin_unlock_irq(&ice->reg_lock);
- /* printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream)); */
+ /*
+ printk(KERN_DEBUG "pro prepare: ch = %d, addr = 0x%x, "
+ "buffer = 0x%x, period = 0x%x\n",
+ substream->runtime->channels,
+ (unsigned int)substream->runtime->dma_addr,
+ snd_pcm_lib_buffer_bytes(substream),
+ snd_pcm_lib_period_bytes(substream));
+ */
return 0;
}
wait_i2c_busy(ice);
val = inb(ICEREG1724(ice, I2C_DATA));
mutex_unlock(&ice->i2c_mutex);
- /* printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); */
+ /*
+ printk(KERN_DEBUG "i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val);
+ */
return val;
}
{
mutex_lock(&ice->i2c_mutex);
wait_i2c_busy(ice);
- /* printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); */
+ /*
+ printk(KERN_DEBUG "i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data);
+ */
outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
outb(data, ICEREG1724(ice, I2C_DATA));
outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
/* due to possible conflicts with stac9460_set_rate_val, mutexing */
mutex_lock(&spec->mute_mutex);
- /*printk("Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
- ucontrol->value.integer.value[0]);*/
+ /*
+ printk(KERN_DEBUG "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
+ ucontrol->value.integer.value[0]);
+ */
change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]);
mutex_unlock(&spec->mute_mutex);
return change;
change = (ovol != nvol);
if (change) {
ovol = (0x7f - nvol) | (tmp & 0x80);
- /*printk("DAC Volume: reg 0x%02x: 0x%02x\n", idx, ovol);*/
+ /*
+ printk(KERN_DEBUG "DAC Volume: reg 0x%02x: 0x%02x\n",
+ idx, ovol);
+ */
stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
}
return change;
for (idx = 0; idx < 7 ; ++idx)
changed[idx] = stac9460_dac_mute(ice,
STAC946X_MASTER_VOLUME + idx, 0);
- /*printk("Rate change: %d, new MC: 0x%02x\n", rate, new);*/
+ /*printk(KERN_DEBUG "Rate change: %d, new MC: 0x%02x\n", rate, new);*/
stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);
udelay(10);
/* unmuting - only originally unmuted dacs -