Merge branch 'topic/beep-rename' into topic/core-change

This commit is contained in:
Takashi Iwai 2009-12-01 15:58:10 +01:00
commit 75639e7ee1
47 changed files with 1171 additions and 2163 deletions

View file

@ -1454,6 +1454,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for internal PC-Speaker. Module for internal PC-Speaker.
nopcm - Disable PC-Speaker PCM sound. Only beeps remain.
nforce_wa - enable NForce chipset workaround. Expect bad sound. nforce_wa - enable NForce chipset workaround. Expect bad sound.
This module supports system beeps, some kind of PCM playback and This module supports system beeps, some kind of PCM playback and
@ -1631,7 +1632,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module snd-sscape Module snd-sscape
----------------- -----------------
Module for ENSONIQ SoundScape PnP cards. Module for ENSONIQ SoundScape cards.
port - Port # (PnP setup) port - Port # (PnP setup)
wss_port - WSS Port # (PnP setup) wss_port - WSS Port # (PnP setup)
@ -1639,10 +1640,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - MPU-401 IRQ # (PnP setup) mpu_irq - MPU-401 IRQ # (PnP setup)
dma - DMA # (PnP setup) dma - DMA # (PnP setup)
dma2 - 2nd DMA # (PnP setup, -1 to disable) dma2 - 2nd DMA # (PnP setup, -1 to disable)
joystick - Enable gameport - 0 = disable (default), 1 = enable
This module supports multiple cards. ISA PnP must be enabled. This module supports multiple cards.
You need sscape_ctl tool in alsa-tools package for loading
the microcode. The driver requires the firmware loader support on kernel.
Module snd-sun-amd7930 (on sparc only) Module snd-sun-amd7930 (on sparc only)
-------------------------------------- --------------------------------------

View file

@ -18,8 +18,9 @@ SOURCE:
Master Master
Master Mono Master Mono
Hardware Master Hardware Master
Speaker (internal speaker)
Headphone Headphone
PC Speaker Beep (beep generator)
Phone Phone
Phone Input Phone Input
Phone Output Phone Output

View file

@ -13,6 +13,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <sound/sh_dac_audio.h>
#include <asm/hd64461.h> #include <asm/hd64461.h>
#include <asm/io.h> #include <asm/io.h>
#include <mach/hp6xx.h> #include <mach/hp6xx.h>
@ -51,9 +52,63 @@ static struct platform_device jornadakbd_device = {
.id = -1, .id = -1,
}; };
static void dac_audio_start(struct dac_audio_pdata *pdata)
{
u16 v;
u8 v8;
/* HP Jornada 680/690 speaker on */
v = inw(HD64461_GPADR);
v &= ~HD64461_GPADR_SPEAKER;
outw(v, HD64461_GPADR);
/* HP Palmtop 620lx/660lx speaker on */
v8 = inb(PKDR);
v8 &= ~PKDR_SPEAKER;
outb(v8, PKDR);
sh_dac_enable(pdata->channel);
}
static void dac_audio_stop(struct dac_audio_pdata *pdata)
{
u16 v;
u8 v8;
/* HP Jornada 680/690 speaker off */
v = inw(HD64461_GPADR);
v |= HD64461_GPADR_SPEAKER;
outw(v, HD64461_GPADR);
/* HP Palmtop 620lx/660lx speaker off */
v8 = inb(PKDR);
v8 |= PKDR_SPEAKER;
outb(v8, PKDR);
sh_dac_output(0, pdata->channel);
sh_dac_disable(pdata->channel);
}
static struct dac_audio_pdata dac_audio_platform_data = {
.buffer_size = 64000,
.channel = 1,
.start = dac_audio_start,
.stop = dac_audio_stop,
};
static struct platform_device dac_audio_device = {
.name = "dac_audio",
.id = -1,
.dev = {
.platform_data = &dac_audio_platform_data,
}
};
static struct platform_device *hp6xx_devices[] __initdata = { static struct platform_device *hp6xx_devices[] __initdata = {
&cf_ide_device, &cf_ide_device,
&jornadakbd_device, &jornadakbd_device,
&dac_audio_device,
}; };
static void __init hp6xx_init_irq(void) static void __init hp6xx_init_irq(void)

View file

@ -29,6 +29,9 @@
#define PKDR_LED_GREEN 0x10 #define PKDR_LED_GREEN 0x10
/* HP Palmtop 620lx/660lx speaker on/off */
#define PKDR_SPEAKER 0x20
#define SCPDR_TS_SCAN_ENABLE 0x20 #define SCPDR_TS_SCAN_ENABLE 0x20
#define SCPDR_TS_SCAN_Y 0x02 #define SCPDR_TS_SCAN_Y 0x02
#define SCPDR_TS_SCAN_X 0x01 #define SCPDR_TS_SCAN_X 0x01
@ -42,6 +45,7 @@
#define ADC_CHANNEL_BACKUP 4 #define ADC_CHANNEL_BACKUP 4
#define ADC_CHANNEL_CHARGE 5 #define ADC_CHANNEL_CHARGE 5
/* HP Jornada 680/690 speaker on/off */
#define HD64461_GPADR_SPEAKER 0x01 #define HD64461_GPADR_SPEAKER 0x01
#define HD64461_GPADR_PCMCIA0 (0x02|0x08) #define HD64461_GPADR_PCMCIA0 (0x02|0x08)

View file

@ -2,7 +2,6 @@ header-y += asound_fm.h
header-y += hdsp.h header-y += hdsp.h
header-y += hdspm.h header-y += hdspm.h
header-y += sfnt_info.h header-y += sfnt_info.h
header-y += sscape_ioctl.h
unifdef-y += asequencer.h unifdef-y += asequencer.h
unifdef-y += asound.h unifdef-y += asound.h

View file

@ -0,0 +1,21 @@
/*
* SH_DAC specific configuration, for the dac_audio platform_device
*
* Copyright (C) 2009 Rafael Ignacio Zurita <rizurita@yahoo.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#ifndef __INCLUDE_SH_DAC_AUDIO_H
#define __INCLUDE_SH_DAC_AUDIO_H
struct dac_audio_pdata {
int buffer_size;
int channel;
void (*start)(struct dac_audio_pdata *pd);
void (*stop)(struct dac_audio_pdata *pd);
};
#endif /* __INCLUDE_SH_DAC_AUDIO_H */

View file

@ -1,21 +0,0 @@
#ifndef SSCAPE_IOCTL_H
#define SSCAPE_IOCTL_H
struct sscape_bootblock
{
unsigned char code[256];
unsigned version;
};
#define SSCAPE_MICROCODE_SIZE 65536
struct sscape_microcode
{
unsigned char __user *code;
};
#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock)
#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode)
#endif

View file

@ -85,16 +85,24 @@ EXPORT_SYMBOL(snd_dma_disable);
unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
{ {
unsigned long flags; unsigned long flags;
unsigned int result; unsigned int result, result1;
flags = claim_dma_lock(); flags = claim_dma_lock();
clear_dma_ff(dma); clear_dma_ff(dma);
if (!isa_dma_bridge_buggy) if (!isa_dma_bridge_buggy)
disable_dma(dma); disable_dma(dma);
result = get_dma_residue(dma); result = get_dma_residue(dma);
/*
* HACK - read the counter again and choose higher value in order to
* avoid reading during counter lower byte roll over if the
* isa_dma_bridge_buggy is set.
*/
result1 = get_dma_residue(dma);
if (!isa_dma_bridge_buggy) if (!isa_dma_bridge_buggy)
enable_dma(dma); enable_dma(dma);
release_dma_lock(flags); release_dma_lock(flags);
if (unlikely(result < result1))
result = result1;
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (result > size) if (result > size)
snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size); snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);

View file

@ -1251,7 +1251,9 @@ static void snd_mixer_oss_build(struct snd_mixer_oss *mixer)
{ SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */ { SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */
{ SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */ { SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */
{ SOUND_MIXER_PCM, "PCM", 0 }, { SOUND_MIXER_PCM, "PCM", 0 },
{ SOUND_MIXER_SPEAKER, "PC Speaker", 0 }, { SOUND_MIXER_SPEAKER, "Beep", 0 },
{ SOUND_MIXER_SPEAKER, "PC Speaker", 0 }, /* fallback */
{ SOUND_MIXER_SPEAKER, "Speaker", 0 }, /* fallback */
{ SOUND_MIXER_LINE, "Line", 0 }, { SOUND_MIXER_LINE, "Line", 0 },
{ SOUND_MIXER_MIC, "Mic", 0 }, { SOUND_MIXER_MIC, "Mic", 0 },
{ SOUND_MIXER_CD, "CD", 0 }, { SOUND_MIXER_CD, "CD", 0 },

View file

@ -26,6 +26,7 @@ MODULE_ALIAS("platform:pcspkr");
static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
static int nopcm; /* Disable PCM capability of the driver */
module_param(index, int, 0444); module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for pcsp soundcard."); MODULE_PARM_DESC(index, "Index value for pcsp soundcard.");
@ -33,6 +34,8 @@ module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for pcsp soundcard."); MODULE_PARM_DESC(id, "ID string for pcsp soundcard.");
module_param(enable, bool, 0444); module_param(enable, bool, 0444);
MODULE_PARM_DESC(enable, "Enable PC-Speaker sound."); MODULE_PARM_DESC(enable, "Enable PC-Speaker sound.");
module_param(nopcm, bool, 0444);
MODULE_PARM_DESC(nopcm, "Disable PC-Speaker PCM sound. Only beeps remain.");
struct snd_pcsp pcsp_chip; struct snd_pcsp pcsp_chip;
@ -43,13 +46,16 @@ static int __devinit snd_pcsp_create(struct snd_card *card)
int err; int err;
int div, min_div, order; int div, min_div, order;
hrtimer_get_res(CLOCK_MONOTONIC, &tp); if (!nopcm) {
if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) { hrtimer_get_res(CLOCK_MONOTONIC, &tp);
printk(KERN_ERR "PCSP: Timer resolution is not sufficient " if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) {
"(%linS)\n", tp.tv_nsec); printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI " "(%linS)\n", tp.tv_nsec);
"enabled.\n"); printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
return -EIO; "enabled.\n");
printk(KERN_ERR "PCSP: Turned into nopcm mode.\n");
nopcm = 1;
}
} }
if (loops_per_jiffy >= PCSP_MIN_LPJ && tp.tv_nsec <= PCSP_MIN_PERIOD_NS) if (loops_per_jiffy >= PCSP_MIN_LPJ && tp.tv_nsec <= PCSP_MIN_PERIOD_NS)
@ -107,12 +113,14 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
err = snd_pcsp_new_pcm(&pcsp_chip); if (!nopcm) {
if (err < 0) { err = snd_pcsp_new_pcm(&pcsp_chip);
snd_card_free(card); if (err < 0) {
return err; snd_card_free(card);
return err;
}
} }
err = snd_pcsp_new_mixer(&pcsp_chip); err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
if (err < 0) { if (err < 0) {
snd_card_free(card); snd_card_free(card);
return err; return err;

View file

@ -83,6 +83,6 @@ extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
extern void pcsp_sync_stop(struct snd_pcsp *chip); extern void pcsp_sync_stop(struct snd_pcsp *chip);
extern int snd_pcsp_new_pcm(struct snd_pcsp *chip); extern int snd_pcsp_new_pcm(struct snd_pcsp *chip);
extern int snd_pcsp_new_mixer(struct snd_pcsp *chip); extern int snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm);
#endif #endif

View file

@ -119,24 +119,43 @@ static int pcsp_pcspkr_put(struct snd_kcontrol *kcontrol,
.put = pcsp_##ctl_type##_put, \ .put = pcsp_##ctl_type##_put, \
} }
static struct snd_kcontrol_new __devinitdata snd_pcsp_controls[] = { static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_pcm[] = {
PCSP_MIXER_CONTROL(enable, "Master Playback Switch"), PCSP_MIXER_CONTROL(enable, "Master Playback Switch"),
PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"), PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"),
PCSP_MIXER_CONTROL(pcspkr, "PC Speaker Playback Switch"),
}; };
int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip) static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_spkr[] = {
{ PCSP_MIXER_CONTROL(pcspkr, "Beep Playback Switch"),
struct snd_card *card = chip->card; };
int i, err;
for (i = 0; i < ARRAY_SIZE(snd_pcsp_controls); i++) { static int __devinit snd_pcsp_ctls_add(struct snd_pcsp *chip,
err = snd_ctl_add(card, struct snd_kcontrol_new *ctls, int num)
snd_ctl_new1(snd_pcsp_controls + i, {
chip)); int i, err;
struct snd_card *card = chip->card;
for (i = 0; i < num; i++) {
err = snd_ctl_add(card, snd_ctl_new1(ctls + i, chip));
if (err < 0) if (err < 0)
return err; return err;
} }
return 0;
}
int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm)
{
int err;
struct snd_card *card = chip->card;
if (!nopcm) {
err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_pcm,
ARRAY_SIZE(snd_pcsp_controls_pcm));
if (err < 0)
return err;
}
err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_spkr,
ARRAY_SIZE(snd_pcsp_controls_spkr));
if (err < 0)
return err;
strcpy(card->mixername, "PC-Speaker"); strcpy(card->mixername, "PC-Speaker");

View file

@ -372,15 +372,21 @@ config SND_SGALAXY
config SND_SSCAPE config SND_SSCAPE
tristate "Ensoniq SoundScape driver" tristate "Ensoniq SoundScape driver"
select SND_HWDEP
select SND_MPU401_UART select SND_MPU401_UART
select SND_WSS_LIB select SND_WSS_LIB
select FW_LOADER
help help
Say Y here to include support for Ensoniq SoundScape Say Y here to include support for Ensoniq SoundScape
soundcards. and Ensoniq OEM soundcards.
The PCM audio is supported on SoundScape Classic, Elite, PnP The PCM audio is supported on SoundScape Classic, Elite, PnP
and VIVO cards. The MIDI support is very experimental. and VIVO cards. The supported OEM cards are SPEA Media FX and
Reveal SC-600.
The MIDI support is very experimental and requires binary
firmware files called "scope.cod" and "sndscape.co?" where the
? is digit 0, 1, 2, 3 or 4. The firmware files can be found
in DOS or Windows driver packages. One has to put the firmware
files into the /lib/firmware directory.
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called snd-sscape. will be called snd-sscape.

View file

@ -237,7 +237,7 @@ WSS_DOUBLE("Wavetable Capture Volume", 0,
CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0), CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0),
WSS_SINGLE("3D Control - Switch", 0, WSS_SINGLE("3D Control - Switch", 0,
CMI8330_RMUX3D, 5, 1, 1), CMI8330_RMUX3D, 5, 1, 1),
WSS_SINGLE("PC Speaker Playback Volume", 0, WSS_SINGLE("Beep Playback Volume", 0,
CMI8330_OUTPUTVOL, 3, 3, 0), CMI8330_OUTPUTVOL, 3, 3, 0),
WSS_DOUBLE("FM Playback Switch", 0, WSS_DOUBLE("FM Playback Switch", 0,
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
@ -262,7 +262,7 @@ SB_DOUBLE("SB Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3,
SB_DOUBLE("SB Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31), SB_DOUBLE("SB Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
SB_SINGLE("SB Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1), SB_SINGLE("SB Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
SB_SINGLE("SB Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31), SB_SINGLE("SB Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
SB_SINGLE("SB PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3), SB_SINGLE("SB Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
SB_DOUBLE("SB Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3), SB_DOUBLE("SB Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3), SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1), SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),

View file

@ -982,7 +982,7 @@ ES1688_DOUBLE("CD Playback Volume", 0, ES1688_CD_DEV, ES1688_CD_DEV, 4, 0, 15, 0
ES1688_DOUBLE("FM Playback Volume", 0, ES1688_FM_DEV, ES1688_FM_DEV, 4, 0, 15, 0), ES1688_DOUBLE("FM Playback Volume", 0, ES1688_FM_DEV, ES1688_FM_DEV, 4, 0, 15, 0),
ES1688_DOUBLE("Mic Playback Volume", 0, ES1688_MIC_DEV, ES1688_MIC_DEV, 4, 0, 15, 0), ES1688_DOUBLE("Mic Playback Volume", 0, ES1688_MIC_DEV, ES1688_MIC_DEV, 4, 0, 15, 0),
ES1688_DOUBLE("Aux Playback Volume", 0, ES1688_AUX_DEV, ES1688_AUX_DEV, 4, 0, 15, 0), ES1688_DOUBLE("Aux Playback Volume", 0, ES1688_AUX_DEV, ES1688_AUX_DEV, 4, 0, 15, 0),
ES1688_SINGLE("PC Speaker Playback Volume", 0, ES1688_SPEAKER_DEV, 0, 7, 0), ES1688_SINGLE("Beep Playback Volume", 0, ES1688_SPEAKER_DEV, 0, 7, 0),
ES1688_DOUBLE("Capture Volume", 0, ES1688_RECLEV_DEV, ES1688_RECLEV_DEV, 4, 0, 15, 0), ES1688_DOUBLE("Capture Volume", 0, ES1688_RECLEV_DEV, ES1688_RECLEV_DEV, 4, 0, 15, 0),
ES1688_SINGLE("Capture Switch", 0, ES1688_REC_DEV, 4, 1, 1), ES1688_SINGLE("Capture Switch", 0, ES1688_REC_DEV, 4, 1, 1),
{ {

View file

@ -121,7 +121,6 @@ struct snd_es18xx {
unsigned int dma1_shift; unsigned int dma1_shift;
unsigned int dma2_shift; unsigned int dma2_shift;
struct snd_card *card;
struct snd_pcm *pcm; struct snd_pcm *pcm;
struct snd_pcm_substream *playback_a_substream; struct snd_pcm_substream *playback_a_substream;
struct snd_pcm_substream *capture_a_substream; struct snd_pcm_substream *capture_a_substream;
@ -140,10 +139,6 @@ struct snd_es18xx {
#ifdef CONFIG_PM #ifdef CONFIG_PM
unsigned char pm_reg; unsigned char pm_reg;
#endif #endif
};
struct snd_audiodrive {
struct snd_es18xx *chip;
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
struct pnp_dev *dev; struct pnp_dev *dev;
struct pnp_dev *devc; struct pnp_dev *devc;
@ -755,7 +750,8 @@ static int snd_es18xx_playback_trigger(struct snd_pcm_substream *substream,
static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id) static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
{ {
struct snd_es18xx *chip = dev_id; struct snd_card *card = dev_id;
struct snd_es18xx *chip = card->private_data;
unsigned char status; unsigned char status;
if (chip->caps & ES18XX_CONTROL) { if (chip->caps & ES18XX_CONTROL) {
@ -805,12 +801,16 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
int split = 0; int split = 0;
if (chip->caps & ES18XX_HWV) { if (chip->caps & ES18XX_HWV) {
split = snd_es18xx_mixer_read(chip, 0x64) & 0x80; split = snd_es18xx_mixer_read(chip, 0x64) & 0x80;
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id); &chip->hw_switch->id);
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->hw_volume->id);
} }
if (!split) { if (!split) {
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id); &chip->master_switch->id);
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->master_volume->id);
} }
/* ack interrupt */ /* ack interrupt */
snd_es18xx_mixer_write(chip, 0x66, 0x00); snd_es18xx_mixer_write(chip, 0x66, 0x00);
@ -1313,7 +1313,7 @@ ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0)
* The chipset specific mixer controls * The chipset specific mixer controls
*/ */
static struct snd_kcontrol_new snd_es18xx_opt_speaker = static struct snd_kcontrol_new snd_es18xx_opt_speaker =
ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0); ES18XX_SINGLE("Beep Playback Volume", 0, 0x3c, 0, 7, 0);
static struct snd_kcontrol_new snd_es18xx_opt_1869[] = { static struct snd_kcontrol_new snd_es18xx_opt_1869[] = {
ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
@ -1691,8 +1691,10 @@ static struct snd_pcm_ops snd_es18xx_capture_ops = {
.pointer = snd_es18xx_capture_pointer, .pointer = snd_es18xx_capture_pointer,
}; };
static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct snd_pcm ** rpcm) static int __devinit snd_es18xx_pcm(struct snd_card *card, int device,
struct snd_pcm **rpcm)
{ {
struct snd_es18xx *chip = card->private_data;
struct snd_pcm *pcm; struct snd_pcm *pcm;
char str[16]; char str[16];
int err; int err;
@ -1701,9 +1703,9 @@ static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct
*rpcm = NULL; *rpcm = NULL;
sprintf(str, "ES%x", chip->version); sprintf(str, "ES%x", chip->version);
if (chip->caps & ES18XX_PCM2) if (chip->caps & ES18XX_PCM2)
err = snd_pcm_new(chip->card, str, device, 2, 1, &pcm); err = snd_pcm_new(card, str, device, 2, 1, &pcm);
else else
err = snd_pcm_new(chip->card, str, device, 1, 1, &pcm); err = snd_pcm_new(card, str, device, 1, 1, &pcm);
if (err < 0) if (err < 0)
return err; return err;
@ -1734,10 +1736,9 @@ static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state) static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state)
{ {
struct snd_audiodrive *acard = card->private_data; struct snd_es18xx *chip = card->private_data;
struct snd_es18xx *chip = acard->chip;
snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(chip->pcm); snd_pcm_suspend_all(chip->pcm);
@ -1752,24 +1753,25 @@ static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state)
static int snd_es18xx_resume(struct snd_card *card) static int snd_es18xx_resume(struct snd_card *card)
{ {
struct snd_audiodrive *acard = card->private_data; struct snd_es18xx *chip = card->private_data;
struct snd_es18xx *chip = acard->chip;
/* restore PM register, we won't wake till (not 0x07) i/o activity though */ /* restore PM register, we won't wake till (not 0x07) i/o activity though */
snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM); snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM);
snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0); snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0; return 0;
} }
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
static int snd_es18xx_free(struct snd_es18xx *chip) static int snd_es18xx_free(struct snd_card *card)
{ {
struct snd_es18xx *chip = card->private_data;
release_and_free_resource(chip->res_port); release_and_free_resource(chip->res_port);
release_and_free_resource(chip->res_ctrl_port); release_and_free_resource(chip->res_ctrl_port);
release_and_free_resource(chip->res_mpu_port); release_and_free_resource(chip->res_mpu_port);
if (chip->irq >= 0) if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip); free_irq(chip->irq, (void *) card);
if (chip->dma1 >= 0) { if (chip->dma1 >= 0) {
disable_dma(chip->dma1); disable_dma(chip->dma1);
free_dma(chip->dma1); free_dma(chip->dma1);
@ -1778,37 +1780,29 @@ static int snd_es18xx_free(struct snd_es18xx *chip)
disable_dma(chip->dma2); disable_dma(chip->dma2);
free_dma(chip->dma2); free_dma(chip->dma2);
} }
kfree(chip);
return 0; return 0;
} }
static int snd_es18xx_dev_free(struct snd_device *device) static int snd_es18xx_dev_free(struct snd_device *device)
{ {
struct snd_es18xx *chip = device->device_data; return snd_es18xx_free(device->card);
return snd_es18xx_free(chip);
} }
static int __devinit snd_es18xx_new_device(struct snd_card *card, static int __devinit snd_es18xx_new_device(struct snd_card *card,
unsigned long port, unsigned long port,
unsigned long mpu_port, unsigned long mpu_port,
unsigned long fm_port, unsigned long fm_port,
int irq, int dma1, int dma2, int irq, int dma1, int dma2)
struct snd_es18xx ** rchip)
{ {
struct snd_es18xx *chip; struct snd_es18xx *chip = card->private_data;
static struct snd_device_ops ops = { static struct snd_device_ops ops = {
.dev_free = snd_es18xx_dev_free, .dev_free = snd_es18xx_dev_free,
}; };
int err; int err;
*rchip = NULL;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
spin_lock_init(&chip->reg_lock); spin_lock_init(&chip->reg_lock);
spin_lock_init(&chip->mixer_lock); spin_lock_init(&chip->mixer_lock);
spin_lock_init(&chip->ctrl_lock); spin_lock_init(&chip->ctrl_lock);
chip->card = card;
chip->port = port; chip->port = port;
chip->mpu_port = mpu_port; chip->mpu_port = mpu_port;
chip->fm_port = fm_port; chip->fm_port = fm_port;
@ -1818,53 +1812,53 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card,
chip->audio2_vol = 0x00; chip->audio2_vol = 0x00;
chip->active = 0; chip->active = 0;
if ((chip->res_port = request_region(port, 16, "ES18xx")) == NULL) { chip->res_port = request_region(port, 16, "ES18xx");
snd_es18xx_free(chip); if (chip->res_port == NULL) {
snd_es18xx_free(card);
snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1); snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1);
return -EBUSY; return -EBUSY;
} }
if (request_irq(irq, snd_es18xx_interrupt, IRQF_DISABLED, "ES18xx", (void *) chip)) { if (request_irq(irq, snd_es18xx_interrupt, IRQF_DISABLED, "ES18xx",
snd_es18xx_free(chip); (void *) card)) {
snd_es18xx_free(card);
snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq); snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq);
return -EBUSY; return -EBUSY;
} }
chip->irq = irq; chip->irq = irq;
if (request_dma(dma1, "ES18xx DMA 1")) { if (request_dma(dma1, "ES18xx DMA 1")) {
snd_es18xx_free(chip); snd_es18xx_free(card);
snd_printk(KERN_ERR PFX "unable to grap DMA1 %d\n", dma1); snd_printk(KERN_ERR PFX "unable to grap DMA1 %d\n", dma1);
return -EBUSY; return -EBUSY;
} }
chip->dma1 = dma1; chip->dma1 = dma1;
if (dma2 != dma1 && request_dma(dma2, "ES18xx DMA 2")) { if (dma2 != dma1 && request_dma(dma2, "ES18xx DMA 2")) {
snd_es18xx_free(chip); snd_es18xx_free(card);
snd_printk(KERN_ERR PFX "unable to grap DMA2 %d\n", dma2); snd_printk(KERN_ERR PFX "unable to grap DMA2 %d\n", dma2);
return -EBUSY; return -EBUSY;
} }
chip->dma2 = dma2; chip->dma2 = dma2;
if (snd_es18xx_probe(chip) < 0) { if (snd_es18xx_probe(chip) < 0) {
snd_es18xx_free(chip); snd_es18xx_free(card);
return -ENODEV; return -ENODEV;
} }
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, NULL, &ops);
snd_es18xx_free(chip); if (err < 0) {
snd_es18xx_free(card);
return err; return err;
} }
*rchip = chip;
return 0; return 0;
} }
static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip) static int __devinit snd_es18xx_mixer(struct snd_card *card)
{ {
struct snd_card *card; struct snd_es18xx *chip = card->private_data;
int err; int err;
unsigned int idx; unsigned int idx;
card = chip->card;
strcpy(card->mixername, chip->pcm->name); strcpy(card->mixername, chip->pcm->name);
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_base_controls); idx++) { for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_base_controls); idx++) {
@ -2063,11 +2057,11 @@ static int __devinit snd_audiodrive_pnp_init_main(int dev, struct pnp_dev *pdev)
return 0; return 0;
} }
static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard, static int __devinit snd_audiodrive_pnp(int dev, struct snd_es18xx *chip,
struct pnp_dev *pdev) struct pnp_dev *pdev)
{ {
acard->dev = pdev; chip->dev = pdev;
if (snd_audiodrive_pnp_init_main(dev, acard->dev) < 0) if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
return -EBUSY; return -EBUSY;
return 0; return 0;
} }
@ -2093,26 +2087,26 @@ static struct pnp_card_device_id snd_audiodrive_pnpids[] = {
MODULE_DEVICE_TABLE(pnp_card, snd_audiodrive_pnpids); MODULE_DEVICE_TABLE(pnp_card, snd_audiodrive_pnpids);
static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard, static int __devinit snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip,
struct pnp_card_link *card, struct pnp_card_link *card,
const struct pnp_card_device_id *id) const struct pnp_card_device_id *id)
{ {
acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
if (acard->dev == NULL) if (chip->dev == NULL)
return -EBUSY; return -EBUSY;
acard->devc = pnp_request_card_device(card, id->devs[1].id, NULL); chip->devc = pnp_request_card_device(card, id->devs[1].id, NULL);
if (acard->devc == NULL) if (chip->devc == NULL)
return -EBUSY; return -EBUSY;
/* Control port initialization */ /* Control port initialization */
if (pnp_activate_dev(acard->devc) < 0) { if (pnp_activate_dev(chip->devc) < 0) {
snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n"); snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
return -EAGAIN; return -EAGAIN;
} }
snd_printdd("pnp: port=0x%llx\n", snd_printdd("pnp: port=0x%llx\n",
(unsigned long long)pnp_port_start(acard->devc, 0)); (unsigned long long)pnp_port_start(chip->devc, 0));
if (snd_audiodrive_pnp_init_main(dev, acard->dev) < 0) if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
return -EBUSY; return -EBUSY;
return 0; return 0;
@ -2128,24 +2122,20 @@ static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard,
static int snd_es18xx_card_new(int dev, struct snd_card **cardp) static int snd_es18xx_card_new(int dev, struct snd_card **cardp)
{ {
return snd_card_create(index[dev], id[dev], THIS_MODULE, return snd_card_create(index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_audiodrive), cardp); sizeof(struct snd_es18xx), cardp);
} }
static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
{ {
struct snd_audiodrive *acard = card->private_data; struct snd_es18xx *chip = card->private_data;
struct snd_es18xx *chip;
struct snd_opl3 *opl3; struct snd_opl3 *opl3;
int err; int err;
if ((err = snd_es18xx_new_device(card, err = snd_es18xx_new_device(card,
port[dev], port[dev], mpu_port[dev], fm_port[dev],
mpu_port[dev], irq[dev], dma1[dev], dma2[dev]);
fm_port[dev], if (err < 0)
irq[dev], dma1[dev], dma2[dev],
&chip)) < 0)
return err; return err;
acard->chip = chip;
sprintf(card->driver, "ES%x", chip->version); sprintf(card->driver, "ES%x", chip->version);
@ -2161,10 +2151,12 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
chip->port, chip->port,
irq[dev], dma1[dev]); irq[dev], dma1[dev]);
if ((err = snd_es18xx_pcm(chip, 0, NULL)) < 0) err = snd_es18xx_pcm(card, 0, NULL);
if (err < 0)
return err; return err;
if ((err = snd_es18xx_mixer(chip)) < 0) err = snd_es18xx_mixer(card);
if (err < 0)
return err; return err;
if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {

View file

@ -631,7 +631,7 @@ static struct sbmix_elem snd_sb16_ctl_mic_play_switch =
static struct sbmix_elem snd_sb16_ctl_mic_play_vol = static struct sbmix_elem snd_sb16_ctl_mic_play_vol =
SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31); SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31);
static struct sbmix_elem snd_sb16_ctl_pc_speaker_vol = static struct sbmix_elem snd_sb16_ctl_pc_speaker_vol =
SB_SINGLE("PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3); SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3);
static struct sbmix_elem snd_sb16_ctl_capture_vol = static struct sbmix_elem snd_sb16_ctl_capture_vol =
SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3); SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3);
static struct sbmix_elem snd_sb16_ctl_play_vol = static struct sbmix_elem snd_sb16_ctl_play_vol =
@ -689,7 +689,7 @@ static struct sbmix_elem snd_dt019x_ctl_cd_play_vol =
static struct sbmix_elem snd_dt019x_ctl_mic_play_vol = static struct sbmix_elem snd_dt019x_ctl_mic_play_vol =
SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7); SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7);
static struct sbmix_elem snd_dt019x_ctl_pc_speaker_vol = static struct sbmix_elem snd_dt019x_ctl_pc_speaker_vol =
SB_SINGLE("PC Speaker Volume", SB_DT019X_SPKR_DEV, 0, 7); SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7);
static struct sbmix_elem snd_dt019x_ctl_line_play_vol = static struct sbmix_elem snd_dt019x_ctl_line_play_vol =
SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15); SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15);
static struct sbmix_elem snd_dt019x_ctl_pcm_play_switch = static struct sbmix_elem snd_dt019x_ctl_pcm_play_switch =

File diff suppressed because it is too large Load diff

View file

@ -2198,64 +2198,26 @@ EXPORT_SYMBOL(snd_wss_put_double);
static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
static struct snd_kcontrol_new snd_ad1848_controls[] = {
WSS_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT,
7, 7, 1, 1),
WSS_DOUBLE_TLV("PCM Playback Volume", 0,
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
db_scale_6bit),
WSS_DOUBLE("Aux Playback Switch", 0,
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE_TLV("Aux Playback Volume", 0,
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
db_scale_5bit_12db_max),
WSS_DOUBLE("Aux Playback Switch", 1,
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE_TLV("Aux Playback Volume", 1,
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
db_scale_5bit_12db_max),
WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
0, 0, 15, 0, db_scale_rec_gain),
{
.name = "Capture Source",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.info = snd_wss_info_mux,
.get = snd_wss_get_mux,
.put = snd_wss_put_mux,
},
WSS_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 1, 63, 0,
db_scale_6bit),
};
static struct snd_kcontrol_new snd_wss_controls[] = { static struct snd_kcontrol_new snd_wss_controls[] = {
WSS_DOUBLE("PCM Playback Switch", 0, WSS_DOUBLE("PCM Playback Switch", 0,
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
WSS_DOUBLE("PCM Playback Volume", 0, WSS_DOUBLE_TLV("PCM Playback Volume", 0,
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
WSS_DOUBLE("Line Playback Switch", 0, db_scale_6bit),
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
WSS_DOUBLE("Line Playback Volume", 0,
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
WSS_DOUBLE("Aux Playback Switch", 0, WSS_DOUBLE("Aux Playback Switch", 0,
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE("Aux Playback Volume", 0, WSS_DOUBLE_TLV("Aux Playback Volume", 0,
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
db_scale_5bit_12db_max),
WSS_DOUBLE("Aux Playback Switch", 1, WSS_DOUBLE("Aux Playback Switch", 1,
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE("Aux Playback Volume", 1, WSS_DOUBLE_TLV("Aux Playback Volume", 1,
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
WSS_SINGLE("Mono Playback Switch", 0, db_scale_5bit_12db_max),
CS4231_MONO_CTRL, 7, 1, 1), WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
WSS_SINGLE("Mono Playback Volume", 0, 0, 0, 15, 0, db_scale_rec_gain),
CS4231_MONO_CTRL, 0, 15, 1),
WSS_SINGLE("Mono Output Playback Switch", 0,
CS4231_MONO_CTRL, 6, 1, 1),
WSS_SINGLE("Mono Output Playback Bypass", 0,
CS4231_MONO_CTRL, 5, 1, 0),
WSS_DOUBLE("Capture Volume", 0,
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
{ {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Capture Source", .name = "Capture Source",
@ -2267,15 +2229,30 @@ WSS_DOUBLE("Mic Boost", 0,
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
WSS_SINGLE("Loopback Capture Switch", 0, WSS_SINGLE("Loopback Capture Switch", 0,
CS4231_LOOPBACK, 0, 1, 0), CS4231_LOOPBACK, 0, 1, 0),
WSS_SINGLE("Loopback Capture Volume", 0, WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1,
CS4231_LOOPBACK, 2, 63, 1) db_scale_6bit),
WSS_DOUBLE("Line Playback Switch", 0,
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
WSS_DOUBLE_TLV("Line Playback Volume", 0,
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
db_scale_5bit_12db_max),
WSS_SINGLE("Mono Playback Switch", 0,
CS4231_MONO_CTRL, 7, 1, 1),
WSS_SINGLE_TLV("Mono Playback Volume", 0,
CS4231_MONO_CTRL, 0, 15, 1,
db_scale_4bit),
WSS_SINGLE("Mono Output Playback Switch", 0,
CS4231_MONO_CTRL, 6, 1, 1),
WSS_SINGLE("Mono Output Playback Bypass", 0,
CS4231_MONO_CTRL, 5, 1, 0),
}; };
static struct snd_kcontrol_new snd_opti93x_controls[] = { static struct snd_kcontrol_new snd_opti93x_controls[] = {
WSS_DOUBLE("Master Playback Switch", 0, WSS_DOUBLE("Master Playback Switch", 0,
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
WSS_DOUBLE("Master Playback Volume", 0, WSS_DOUBLE_TLV("Master Playback Volume", 0,
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
db_scale_6bit),
WSS_DOUBLE("PCM Playback Switch", 0, WSS_DOUBLE("PCM Playback Switch", 0,
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
WSS_DOUBLE("PCM Playback Volume", 0, WSS_DOUBLE("PCM Playback Volume", 0,
@ -2334,22 +2311,21 @@ int snd_wss_mixer(struct snd_wss *chip)
if (err < 0) if (err < 0)
return err; return err;
} }
else if (chip->hardware & WSS_HW_AD1848_MASK) else {
for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) { int count = ARRAY_SIZE(snd_wss_controls);
err = snd_ctl_add(card,
snd_ctl_new1(&snd_ad1848_controls[idx], /* Use only the first 11 entries on AD1848 */
chip)); if (chip->hardware & WSS_HW_AD1848_MASK)
if (err < 0) count = 11;
return err;
} for (idx = 0; idx < count; idx++) {
else
for (idx = 0; idx < ARRAY_SIZE(snd_wss_controls); idx++) {
err = snd_ctl_add(card, err = snd_ctl_add(card,
snd_ctl_new1(&snd_wss_controls[idx], snd_ctl_new1(&snd_wss_controls[idx],
chip)); chip));
if (err < 0) if (err < 0)
return err; return err;
} }
}
return 0; return 0;
} }
EXPORT_SYMBOL(snd_wss_mixer); EXPORT_SYMBOL(snd_wss_mixer);

View file

@ -287,18 +287,6 @@ config SOUND_DMAP
Say Y unless you have 16MB or more RAM or a PCI sound card. Say Y unless you have 16MB or more RAM or a PCI sound card.
config SOUND_SSCAPE
tristate "Ensoniq SoundScape support"
help
Answer Y if you have a sound card based on the Ensoniq SoundScape
chipset. Such cards are being manufactured at least by Ensoniq, Spea
and Reveal (Reveal makes also other cards).
If you compile the driver into the kernel, you have to add
"sscape=<io>,<irq>,<dma>,<mpuio>,<mpuirq>" to the kernel command
line.
config SOUND_VMIDI config SOUND_VMIDI
tristate "Loopback MIDI device support" tristate "Loopback MIDI device support"
help help

View file

@ -13,7 +13,6 @@ obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o
obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o
obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o
obj-$(CONFIG_SOUND_MSS) += ad1848.o obj-$(CONFIG_SOUND_MSS) += ad1848.o
obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o
obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o

View file

@ -164,9 +164,6 @@ static ssize_t dac_audio_write(struct file *file, const char *buf, size_t count,
int free; int free;
int nbytes; int nbytes;
if (count < 0)
return -EINVAL;
if (!count) { if (!count) {
dac_audio_sync(); dac_audio_sync();
return 0; return 0;

File diff suppressed because it is too large Load diff

View file

@ -603,8 +603,8 @@ AC97_SINGLE("Tone Control - Treble", AC97_MASTER_TONE, 0, 15, 1)
}; };
static const struct snd_kcontrol_new snd_ac97_controls_pc_beep[2] = { static const struct snd_kcontrol_new snd_ac97_controls_pc_beep[2] = {
AC97_SINGLE("PC Speaker Playback Switch", AC97_PC_BEEP, 15, 1, 1), AC97_SINGLE("Beep Playback Switch", AC97_PC_BEEP, 15, 1, 1),
AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1) AC97_SINGLE("Beep Playback Volume", AC97_PC_BEEP, 1, 15, 1)
}; };
static const struct snd_kcontrol_new snd_ac97_controls_mic_boost = static const struct snd_kcontrol_new snd_ac97_controls_mic_boost =
@ -1393,7 +1393,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
} }
} }
/* build PC Speaker controls */ /* build Beep controls */
if (!(ac97->flags & AC97_HAS_NO_PC_BEEP) && if (!(ac97->flags & AC97_HAS_NO_PC_BEEP) &&
((ac97->flags & AC97_HAS_PC_BEEP) || ((ac97->flags & AC97_HAS_PC_BEEP) ||
snd_ac97_try_volume_mix(ac97, AC97_PC_BEEP))) { snd_ac97_try_volume_mix(ac97, AC97_PC_BEEP))) {

View file

@ -800,12 +800,12 @@ AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1),
AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0), AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1), AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1),
AC97_SINGLE("PC Beep to Headphone Switch", AC97_AUX, 15, 1, 1), AC97_SINGLE("Beep to Headphone Switch", AC97_AUX, 15, 1, 1),
AC97_SINGLE("PC Beep to Headphone Volume", AC97_AUX, 12, 7, 1), AC97_SINGLE("Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
AC97_SINGLE("PC Beep to Master Switch", AC97_AUX, 11, 1, 1), AC97_SINGLE("Beep to Master Switch", AC97_AUX, 11, 1, 1),
AC97_SINGLE("PC Beep to Master Volume", AC97_AUX, 8, 7, 1), AC97_SINGLE("Beep to Master Volume", AC97_AUX, 8, 7, 1),
AC97_SINGLE("PC Beep to Mono Switch", AC97_AUX, 7, 1, 1), AC97_SINGLE("Beep to Mono Switch", AC97_AUX, 7, 1, 1),
AC97_SINGLE("PC Beep to Mono Volume", AC97_AUX, 4, 7, 1), AC97_SINGLE("Beep to Mono Volume", AC97_AUX, 4, 7, 1),
AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1), AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1),
AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1), AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1),

View file

@ -830,8 +830,8 @@ static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0), AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1), AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1), AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
AZF3328_MIXER_SWITCH("PC Speaker Playback Switch", IDX_MIXER_PCBEEP, 15, 1), AZF3328_MIXER_SWITCH("Beep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
AZF3328_MIXER_VOL_SPECIAL("PC Speaker Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1), AZF3328_MIXER_VOL_SPECIAL("Beep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1), AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1), AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1), AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),

View file

@ -792,8 +792,8 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
"Phone Playback Volume", "Phone Playback Volume",
"Video Playback Switch", "Video Playback Switch",
"Video Playback Volume", "Video Playback Volume",
"PC Speaker Playback Switch", "Beep Playback Switch",
"PC Speaker Playback Volume", "Beep Playback Volume",
"Mono Output Select", "Mono Output Select",
"Capture Source", "Capture Source",
"Capture Switch", "Capture Switch",

View file

@ -304,7 +304,7 @@ static void snd_ca0106_proc_reg_write32(struct snd_info_entry *entry,
while (!snd_info_get_line(buffer, line, sizeof(line))) { while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x", &reg, &val) != 2) if (sscanf(line, "%x %x", &reg, &val) != 2)
continue; continue;
if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) { if (reg < 0x40 && val <= 0xffffffff) {
spin_lock_irqsave(&emu->emu_lock, flags); spin_lock_irqsave(&emu->emu_lock, flags);
outl(val, emu->port + (reg & 0xfffffffc)); outl(val, emu->port + (reg & 0xfffffffc));
spin_unlock_irqrestore(&emu->emu_lock, flags); spin_unlock_irqrestore(&emu->emu_lock, flags);
@ -405,7 +405,7 @@ static void snd_ca0106_proc_reg_write(struct snd_info_entry *entry,
while (!snd_info_get_line(buffer, line, sizeof(line))) { while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3) if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
continue; continue;
if ((reg < 0x80) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) ) if (reg < 0x80 && val <= 0xffffffff && channel_id <= 3)
snd_ca0106_ptr_write(emu, reg, channel_id, val); snd_ca0106_ptr_write(emu, reg, channel_id, val);
} }
} }

View file

@ -2302,7 +2302,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
CMIPCI_SB_VOL_MONO("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31), CMIPCI_SB_VOL_MONO("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
CMIPCI_SB_SW_MONO("Mic Playback Switch", 0), CMIPCI_SB_SW_MONO("Mic Playback Switch", 0),
CMIPCI_DOUBLE("Mic Capture Switch", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0, 1, 0, 0), CMIPCI_DOUBLE("Mic Capture Switch", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0, 1, 0, 0),
CMIPCI_SB_VOL_MONO("PC Speaker Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3), CMIPCI_SB_VOL_MONO("Beep Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15), CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15),
CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0), CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0),
CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0), CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0),
@ -2310,7 +2310,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7), CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7),
CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7), CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7),
CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0), CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0),
CMIPCI_DOUBLE("PC Speaker Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0), CMIPCI_DOUBLE("Beep Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0),
CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0), CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0),
}; };

View file

@ -240,7 +240,7 @@ static int select_rom(unsigned int pitch)
} else if (pitch == 0x02000000) { } else if (pitch == 0x02000000) {
/* pitch == 2 */ /* pitch == 2 */
return 3; return 3;
} else if (pitch >= 0x0 && pitch <= 0x08000000) { } else if (pitch <= 0x08000000) {
/* 0 <= pitch <= 8 */ /* 0 <= pitch <= 8 */
return 0; return 0;
} else { } else {

View file

@ -1040,8 +1040,7 @@ static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry,
if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3) if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
continue; continue;
if ((reg < 0x49) && (reg >= 0) && (val <= 0xffffffff) if (reg < 0x49 && val <= 0xffffffff && channel_id <= 2)
&& (channel_id >= 0) && (channel_id <= 2) )
snd_emu10k1x_ptr_write(emu, reg, channel_id, val); snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
} }
} }

View file

@ -1818,8 +1818,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
"Master Playback Switch", "Master Capture Switch", "Master Playback Switch", "Master Capture Switch",
"Master Playback Volume", "Master Capture Volume", "Master Playback Volume", "Master Capture Volume",
"Wave Master Playback Volume", "Master Playback Volume", "Wave Master Playback Volume", "Master Playback Volume",
"PC Speaker Playback Switch", "PC Speaker Capture Switch", "Beep Playback Switch", "Beep Capture Switch",
"PC Speaker Playback Volume", "PC Speaker Capture Volume", "Beep Playback Volume", "Beep Capture Volume",
"Phone Playback Switch", "Phone Capture Switch", "Phone Playback Switch", "Phone Capture Switch",
"Phone Playback Volume", "Phone Capture Volume", "Phone Playback Volume", "Phone Capture Volume",
"Mic Playback Switch", "Mic Capture Switch", "Mic Playback Switch", "Mic Capture Switch",

View file

@ -451,7 +451,7 @@ static void snd_emu_proc_io_reg_write(struct snd_info_entry *entry,
while (!snd_info_get_line(buffer, line, sizeof(line))) { while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x", &reg, &val) != 2) if (sscanf(line, "%x %x", &reg, &val) != 2)
continue; continue;
if ((reg < 0x40) && (reg >= 0) && (val <= 0xffffffff) ) { if (reg < 0x40 && val <= 0xffffffff) {
spin_lock_irqsave(&emu->emu_lock, flags); spin_lock_irqsave(&emu->emu_lock, flags);
outl(val, emu->port + (reg & 0xfffffffc)); outl(val, emu->port + (reg & 0xfffffffc));
spin_unlock_irqrestore(&emu->emu_lock, flags); spin_unlock_irqrestore(&emu->emu_lock, flags);
@ -527,7 +527,7 @@ static void snd_emu_proc_ptr_reg_write(struct snd_info_entry *entry,
while (!snd_info_get_line(buffer, line, sizeof(line))) { while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3) if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
continue; continue;
if ((reg < 0xa0) && (reg >= 0) && (val <= 0xffffffff) && (channel_id >= 0) && (channel_id <= 3) ) if (reg < 0xa0 && val <= 0xffffffff && channel_id <= 3)
snd_ptr_write(emu, iobase, reg, channel_id, val); snd_ptr_write(emu, iobase, reg, channel_id, val);
} }
} }

View file

@ -256,7 +256,7 @@ int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value)
if (reg > 0x3f) if (reg > 0x3f)
return 1; return 1;
reg += 0x40; /* 0x40 upwards are registers. */ reg += 0x40; /* 0x40 upwards are registers. */
if (value < 0 || value > 0x3f) /* 0 to 0x3f are values */ if (value > 0x3f) /* 0 to 0x3f are values */
return 1; return 1;
spin_lock_irqsave(&emu->emu_lock, flags); spin_lock_irqsave(&emu->emu_lock, flags);
outl(reg, emu->port + A_IOCFG); outl(reg, emu->port + A_IOCFG);

View file

@ -1387,7 +1387,7 @@ ES1938_DOUBLE_TLV("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0,
db_scale_line), db_scale_line),
ES1938_DOUBLE_TLV("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0, ES1938_DOUBLE_TLV("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0,
db_scale_capture), db_scale_capture),
ES1938_SINGLE("PC Speaker Volume", 0, 0x3c, 0, 7, 0), ES1938_SINGLE("Beep Volume", 0, 0x3c, 0, 7, 0),
ES1938_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0), ES1938_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
ES1938_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), ES1938_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
{ {

View file

@ -197,8 +197,8 @@ static struct snd_kcontrol_new cmi9880_basic_mixer[] = {
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT),
HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x23, 0, HDA_OUTPUT), HDA_CODEC_VOLUME("Beep Playback Volume", 0x23, 0, HDA_OUTPUT),
HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x23, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Beep Playback Switch", 0x23, 0, HDA_OUTPUT),
{ } /* end */ { } /* end */
}; };

View file

@ -7336,8 +7336,8 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = {
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
/* FIXME: this looks suspicious... /* FIXME: this looks suspicious...
HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
*/ */
{ } /* end */ { } /* end */
}; };

View file

@ -3224,7 +3224,7 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
/* check for mute support for the the amp */ /* check for mute support for the the amp */
if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) { if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
"PC Beep Playback Switch", "Beep Playback Switch",
HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
if (err < 0) if (err < 0)
return err; return err;
@ -3233,7 +3233,7 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
/* check to see if there is volume support for the amp */ /* check to see if there is volume support for the amp */
if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
"PC Beep Playback Volume", "Beep Playback Volume",
HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
if (err < 0) if (err < 0)
return err; return err;
@ -3274,7 +3274,7 @@ static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
static int stac92xx_beep_switch_ctl(struct hda_codec *codec) static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
{ {
return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl, return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
0, "PC Beep Playback Switch", 0); 0, "Beep Playback Switch", 0);
} }
#endif #endif

View file

@ -479,7 +479,7 @@ static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol,
static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] __devinitdata = { static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] __devinitdata = {
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PC Speaker Playback Volume", .name = "Speaker Playback Volume",
.info = snd_pmac_awacs_info_volume_amp, .info = snd_pmac_awacs_info_volume_amp,
.get = snd_pmac_awacs_get_volume_amp, .get = snd_pmac_awacs_get_volume_amp,
.put = snd_pmac_awacs_put_volume_amp, .put = snd_pmac_awacs_put_volume_amp,
@ -525,7 +525,7 @@ static struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw __devinitdata = {
static struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw __devinitdata = { static struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PC Speaker Playback Switch", .name = "Speaker Playback Switch",
.info = snd_pmac_boolean_stereo_info, .info = snd_pmac_boolean_stereo_info,
.get = snd_pmac_awacs_get_switch_amp, .get = snd_pmac_awacs_get_switch_amp,
.put = snd_pmac_awacs_put_switch_amp, .put = snd_pmac_awacs_put_switch_amp,
@ -696,17 +696,17 @@ static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_imac[] __devinitdata
}; };
static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __devinitdata = { static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __devinitdata = {
AWACS_VOLUME("PC Speaker Playback Volume", 4, 6, 1), AWACS_VOLUME("Speaker Playback Volume", 4, 6, 1),
}; };
static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __devinitdata = static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __devinitdata =
AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1); AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __devinitdata = static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __devinitdata =
AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 1); AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __devinitdata = static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __devinitdata =
AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0); AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
/* /*

View file

@ -505,7 +505,7 @@ static struct snd_kcontrol_new snd_pmac_burgundy_mixers_imac[] __devinitdata = {
MASK_ADDR_BURGUNDY_GAINLINE, 1, 0), MASK_ADDR_BURGUNDY_GAINLINE, 1, 0),
BURGUNDY_VOLUME_B("Mic Gain Capture Volume", 0, BURGUNDY_VOLUME_B("Mic Gain Capture Volume", 0,
MASK_ADDR_BURGUNDY_GAINMIC, 1, 0), MASK_ADDR_BURGUNDY_GAINMIC, 1, 0),
BURGUNDY_VOLUME_B("PC Speaker Playback Volume", 0, BURGUNDY_VOLUME_B("Speaker Playback Volume", 0,
MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1), MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1),
BURGUNDY_VOLUME_B("Line out Playback Volume", 0, BURGUNDY_VOLUME_B("Line out Playback Volume", 0,
MASK_ADDR_BURGUNDY_ATTENLINEOUT, 1, 1), MASK_ADDR_BURGUNDY_ATTENLINEOUT, 1, 1),
@ -527,7 +527,7 @@ static struct snd_kcontrol_new snd_pmac_burgundy_mixers_pmac[] __devinitdata = {
MASK_ADDR_BURGUNDY_VOLMIC, 16), MASK_ADDR_BURGUNDY_VOLMIC, 16),
BURGUNDY_VOLUME_B("Line in Gain Capture Volume", 0, BURGUNDY_VOLUME_B("Line in Gain Capture Volume", 0,
MASK_ADDR_BURGUNDY_GAINMIC, 1, 0), MASK_ADDR_BURGUNDY_GAINMIC, 1, 0),
BURGUNDY_VOLUME_B("PC Speaker Playback Volume", 0, BURGUNDY_VOLUME_B("Speaker Playback Volume", 0,
MASK_ADDR_BURGUNDY_ATTENMONO, 0, 1), MASK_ADDR_BURGUNDY_ATTENMONO, 0, 1),
BURGUNDY_VOLUME_B("Line out Playback Volume", 0, BURGUNDY_VOLUME_B("Line out Playback Volume", 0,
MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1), MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1),
@ -549,11 +549,11 @@ BURGUNDY_SWITCH_B("Master Playback Switch", 0,
BURGUNDY_OUTPUT_INTERN BURGUNDY_OUTPUT_INTERN
| BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1); | BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_imac __devinitdata = static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_imac __devinitdata =
BURGUNDY_SWITCH_B("PC Speaker Playback Switch", 0, BURGUNDY_SWITCH_B("Speaker Playback Switch", 0,
MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1); BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_pmac __devinitdata = static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_pmac __devinitdata =
BURGUNDY_SWITCH_B("PC Speaker Playback Switch", 0, BURGUNDY_SWITCH_B("Speaker Playback Switch", 0,
MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
BURGUNDY_OUTPUT_INTERN, 0, 0); BURGUNDY_OUTPUT_INTERN, 0, 0);
static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_imac __devinitdata = static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_imac __devinitdata =

View file

@ -905,7 +905,7 @@ static struct snd_kcontrol_new tumbler_hp_sw __devinitdata = {
}; };
static struct snd_kcontrol_new tumbler_speaker_sw __devinitdata = { static struct snd_kcontrol_new tumbler_speaker_sw __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PC Speaker Playback Switch", .name = "Speaker Playback Switch",
.info = snd_pmac_boolean_mono_info, .info = snd_pmac_boolean_mono_info,
.get = tumbler_get_mute_switch, .get = tumbler_get_mute_switch,
.put = tumbler_put_mute_switch, .put = tumbler_put_mute_switch,

View file

@ -19,5 +19,13 @@ config SND_AICA
help help
ALSA Sound driver for the SEGA Dreamcast console. ALSA Sound driver for the SEGA Dreamcast console.
config SND_SH_DAC_AUDIO
tristate "SuperH DAC audio support"
depends on SND
depends on CPU_SH3 && HIGH_RES_TIMERS
select SND_PCM
help
Say Y here to include support for the on-chip DAC.
endif # SND_SUPERH endif # SND_SUPERH

View file

@ -3,6 +3,8 @@
# #
snd-aica-objs := aica.o snd-aica-objs := aica.o
snd-sh_dac_audio-objs := sh_dac_audio.o
# Toplevel Module Dependency # Toplevel Module Dependency
obj-$(CONFIG_SND_AICA) += snd-aica.o obj-$(CONFIG_SND_AICA) += snd-aica.o
obj-$(CONFIG_SND_SH_DAC_AUDIO) += snd-sh_dac_audio.o

453
sound/sh/sh_dac_audio.c Normal file
View file

@ -0,0 +1,453 @@
/*
* sh_dac_audio.c - SuperH DAC audio driver for ALSA
*
* Copyright (c) 2009 by Rafael Ignacio Zurita <rizurita@yahoo.com>
*
*
* Based on sh_dac_audio.c (Copyright (C) 2004, 2005 by Andriy Skulysh)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/sh_dac_audio.h>
#include <asm/clock.h>
#include <asm/hd64461.h>
#include <mach/hp6xx.h>
#include <cpu/dac.h>
MODULE_AUTHOR("Rafael Ignacio Zurita <rizurita@yahoo.com>");
MODULE_DESCRIPTION("SuperH DAC audio driver");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{SuperH DAC audio support}}");
/* Module Parameters */
static int index = SNDRV_DEFAULT_IDX1;
static char *id = SNDRV_DEFAULT_STR1;
module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for SuperH DAC audio.");
module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for SuperH DAC audio.");
/* main struct */
struct snd_sh_dac {
struct snd_card *card;
struct snd_pcm_substream *substream;
struct hrtimer hrtimer;
ktime_t wakeups_per_second;
int rate;
int empty;
char *data_buffer, *buffer_begin, *buffer_end;
int processed; /* bytes proccesed, to compare with period_size */
int buffer_size;
struct dac_audio_pdata *pdata;
};
static void dac_audio_start_timer(struct snd_sh_dac *chip)
{
hrtimer_start(&chip->hrtimer, chip->wakeups_per_second,
HRTIMER_MODE_REL);
}
static void dac_audio_stop_timer(struct snd_sh_dac *chip)
{
hrtimer_cancel(&chip->hrtimer);
}
static void dac_audio_reset(struct snd_sh_dac *chip)
{
dac_audio_stop_timer(chip);
chip->buffer_begin = chip->buffer_end = chip->data_buffer;
chip->processed = 0;
chip->empty = 1;
}
static void dac_audio_set_rate(struct snd_sh_dac *chip)
{
chip->wakeups_per_second = ktime_set(0, 1000000000 / chip->rate);
}
/* PCM INTERFACE */
static struct snd_pcm_hardware snd_sh_dac_pcm_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_HALF_DUPLEX),
.formats = SNDRV_PCM_FMTBIT_U8,
.rates = SNDRV_PCM_RATE_8000,
.rate_min = 8000,
.rate_max = 8000,
.channels_min = 1,
.channels_max = 1,
.buffer_bytes_max = (48*1024),
.period_bytes_min = 1,
.period_bytes_max = (48*1024),
.periods_min = 1,
.periods_max = 1024,
};
static int snd_sh_dac_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
runtime->hw = snd_sh_dac_pcm_hw;
chip->substream = substream;
chip->buffer_begin = chip->buffer_end = chip->data_buffer;
chip->processed = 0;
chip->empty = 1;
chip->pdata->start(chip->pdata);
return 0;
}
static int snd_sh_dac_pcm_close(struct snd_pcm_substream *substream)
{
struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
chip->substream = NULL;
dac_audio_stop_timer(chip);
chip->pdata->stop(chip->pdata);
return 0;
}
static int snd_sh_dac_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
return snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(hw_params));
}
static int snd_sh_dac_pcm_hw_free(struct snd_pcm_substream *substream)
{
return snd_pcm_lib_free_pages(substream);
}
static int snd_sh_dac_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = chip->substream->runtime;
chip->buffer_size = runtime->buffer_size;
memset(chip->data_buffer, 0, chip->pdata->buffer_size);
return 0;
}
static int snd_sh_dac_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
dac_audio_start_timer(chip);
break;
case SNDRV_PCM_TRIGGER_STOP:
chip->buffer_begin = chip->buffer_end = chip->data_buffer;
chip->processed = 0;
chip->empty = 1;
dac_audio_stop_timer(chip);
break;
default:
return -EINVAL;
}
return 0;
}
static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, int channel,
snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
{
/* channel is not used (interleaved data) */
struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
ssize_t b_count = frames_to_bytes(runtime , count);
ssize_t b_pos = frames_to_bytes(runtime , pos);
if (count < 0)
return -EINVAL;
if (!count)
return 0;
memcpy_toio(chip->data_buffer + b_pos, src, b_count);
chip->buffer_end = chip->data_buffer + b_pos + b_count;
if (chip->empty) {
chip->empty = 0;
dac_audio_start_timer(chip);
}
return 0;
}
static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream,
int channel, snd_pcm_uframes_t pos,
snd_pcm_uframes_t count)
{
/* channel is not used (interleaved data) */
struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
ssize_t b_count = frames_to_bytes(runtime , count);
ssize_t b_pos = frames_to_bytes(runtime , pos);
if (count < 0)
return -EINVAL;
if (!count)
return 0;
memset_io(chip->data_buffer + b_pos, 0, b_count);
chip->buffer_end = chip->data_buffer + b_pos + b_count;
if (chip->empty) {
chip->empty = 0;
dac_audio_start_timer(chip);
}
return 0;
}
static
snd_pcm_uframes_t snd_sh_dac_pcm_pointer(struct snd_pcm_substream *substream)
{
struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
int pointer = chip->buffer_begin - chip->data_buffer;
return pointer;
}
/* pcm ops */
static struct snd_pcm_ops snd_sh_dac_pcm_ops = {
.open = snd_sh_dac_pcm_open,
.close = snd_sh_dac_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_sh_dac_pcm_hw_params,
.hw_free = snd_sh_dac_pcm_hw_free,
.prepare = snd_sh_dac_pcm_prepare,
.trigger = snd_sh_dac_pcm_trigger,
.pointer = snd_sh_dac_pcm_pointer,
.copy = snd_sh_dac_pcm_copy,
.silence = snd_sh_dac_pcm_silence,
.mmap = snd_pcm_lib_mmap_iomem,
};
static int __devinit snd_sh_dac_pcm(struct snd_sh_dac *chip, int device)
{
int err;
struct snd_pcm *pcm;
/* device should be always 0 for us */
err = snd_pcm_new(chip->card, "SH_DAC PCM", device, 1, 0, &pcm);
if (err < 0)
return err;
pcm->private_data = chip;
strcpy(pcm->name, "SH_DAC PCM");
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sh_dac_pcm_ops);
/* buffer size=48K */
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL),
48 * 1024,
48 * 1024);
return 0;
}
/* END OF PCM INTERFACE */
/* driver .remove -- destructor */
static int snd_sh_dac_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
platform_set_drvdata(devptr, NULL);
return 0;
}
/* free -- it has been defined by create */
static int snd_sh_dac_free(struct snd_sh_dac *chip)
{
/* release the data */
kfree(chip->data_buffer);
kfree(chip);
return 0;
}
static int snd_sh_dac_dev_free(struct snd_device *device)
{
struct snd_sh_dac *chip = device->device_data;
return snd_sh_dac_free(chip);
}
static enum hrtimer_restart sh_dac_audio_timer(struct hrtimer *handle)
{
struct snd_sh_dac *chip = container_of(handle, struct snd_sh_dac,
hrtimer);
struct snd_pcm_runtime *runtime = chip->substream->runtime;
ssize_t b_ps = frames_to_bytes(runtime, runtime->period_size);
if (!chip->empty) {
sh_dac_output(*chip->buffer_begin, chip->pdata->channel);
chip->buffer_begin++;
chip->processed++;
if (chip->processed >= b_ps) {
chip->processed -= b_ps;
snd_pcm_period_elapsed(chip->substream);
}
if (chip->buffer_begin == (chip->data_buffer +
chip->buffer_size - 1))
chip->buffer_begin = chip->data_buffer;
if (chip->buffer_begin == chip->buffer_end)
chip->empty = 1;
}
if (!chip->empty)
hrtimer_start(&chip->hrtimer, chip->wakeups_per_second,
HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
/* create -- chip-specific constructor for the cards components */
static int __devinit snd_sh_dac_create(struct snd_card *card,
struct platform_device *devptr,
struct snd_sh_dac **rchip)
{
struct snd_sh_dac *chip;
int err;
static struct snd_device_ops ops = {
.dev_free = snd_sh_dac_dev_free,
};
*rchip = NULL;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
chip->card = card;
hrtimer_init(&chip->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
chip->hrtimer.function = sh_dac_audio_timer;
dac_audio_reset(chip);
chip->rate = 8000;
dac_audio_set_rate(chip);
chip->pdata = devptr->dev.platform_data;
chip->data_buffer = kmalloc(chip->pdata->buffer_size, GFP_KERNEL);
if (chip->data_buffer == NULL) {
kfree(chip);
return -ENOMEM;
}
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_sh_dac_free(chip);
return err;
}
*rchip = chip;
return 0;
}
/* driver .probe -- constructor */
static int __devinit snd_sh_dac_probe(struct platform_device *devptr)
{
struct snd_sh_dac *chip;
struct snd_card *card;
int err;
err = snd_card_create(index, id, THIS_MODULE, 0, &card);
if (err < 0) {
snd_printk(KERN_ERR "cannot allocate the card\n");
return err;
}
err = snd_sh_dac_create(card, devptr, &chip);
if (err < 0)
goto probe_error;
err = snd_sh_dac_pcm(chip, 0);
if (err < 0)
goto probe_error;
strcpy(card->driver, "snd_sh_dac");
strcpy(card->shortname, "SuperH DAC audio driver");
printk(KERN_INFO "%s %s", card->longname, card->shortname);
err = snd_card_register(card);
if (err < 0)
goto probe_error;
snd_printk("ALSA driver for SuperH DAC audio");
platform_set_drvdata(devptr, card);
return 0;
probe_error:
snd_card_free(card);
return err;
}
/*
* "driver" definition
*/
static struct platform_driver driver = {
.probe = snd_sh_dac_probe,
.remove = snd_sh_dac_remove,
.driver = {
.name = "dac_audio",
},
};
static int __init sh_dac_init(void)
{
return platform_driver_register(&driver);
}
static void __exit sh_dac_exit(void)
{
platform_driver_unregister(&driver);
}
module_init(sh_dac_init);
module_exit(sh_dac_exit);

View file

@ -85,7 +85,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
* of data into val * of data into val
*/ */
if ((reg < 0 || reg > 9) && (reg != 15)) { if (reg > 9 && reg != 15) {
printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg); printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
return -1; return -1;
} }

View file

@ -165,9 +165,9 @@ SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1),
SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0), SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
SOC_SINGLE("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1), SOC_SINGLE("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1),
SOC_SINGLE("PC Beep Playback Headphone Volume", AC97_AUX, 12, 7, 1), SOC_SINGLE("Beep Playback Headphone Volume", AC97_AUX, 12, 7, 1),
SOC_SINGLE("PC Beep Playback Speaker Volume", AC97_AUX, 8, 7, 1), SOC_SINGLE("Beep Playback Speaker Volume", AC97_AUX, 8, 7, 1),
SOC_SINGLE("PC Beep Playback Mono Volume", AC97_AUX, 4, 7, 1), SOC_SINGLE("Beep Playback Mono Volume", AC97_AUX, 4, 7, 1),
SOC_SINGLE("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1), SOC_SINGLE("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1),
SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1), SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1),
@ -266,7 +266,7 @@ static int mixer_event(struct snd_soc_dapm_widget *w,
/* Left Headphone Mixers */ /* Left Headphone Mixers */
static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = { static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = {
SOC_DAPM_SINGLE("PC Beep Playback Switch", HPL_MIXER, 5, 1, 0), SOC_DAPM_SINGLE("Beep Playback Switch", HPL_MIXER, 5, 1, 0),
SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0), SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0),
SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0), SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0),
SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0), SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0),
@ -276,7 +276,7 @@ SOC_DAPM_SINGLE("Bypass Playback Switch", HPL_MIXER, 0, 1, 0),
/* Right Headphone Mixers */ /* Right Headphone Mixers */
static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = { static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = {
SOC_DAPM_SINGLE("PC Beep Playback Switch", HPR_MIXER, 5, 1, 0), SOC_DAPM_SINGLE("Beep Playback Switch", HPR_MIXER, 5, 1, 0),
SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0), SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0),
SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0), SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0),
SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0), SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0),
@ -294,7 +294,7 @@ SOC_DAPM_ENUM("Route", wm9713_enum[0]);
/* Speaker Mixer */ /* Speaker Mixer */
static const struct snd_kcontrol_new wm9713_speaker_mixer_controls[] = { static const struct snd_kcontrol_new wm9713_speaker_mixer_controls[] = {
SOC_DAPM_SINGLE("PC Beep Playback Switch", AC97_AUX, 11, 1, 1), SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 11, 1, 1),
SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 11, 1, 1), SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 11, 1, 1),
SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 11, 1, 1), SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 11, 1, 1),
SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 14, 1, 1), SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 14, 1, 1),
@ -304,7 +304,7 @@ SOC_DAPM_SINGLE("Bypass Playback Switch", AC97_PC_BEEP, 14, 1, 1),
/* Mono Mixer */ /* Mono Mixer */
static const struct snd_kcontrol_new wm9713_mono_mixer_controls[] = { static const struct snd_kcontrol_new wm9713_mono_mixer_controls[] = {
SOC_DAPM_SINGLE("PC Beep Playback Switch", AC97_AUX, 7, 1, 1), SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 7, 1, 1),
SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 7, 1, 1), SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 7, 1, 1),
SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 7, 1, 1), SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 7, 1, 1),
SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 13, 1, 1), SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 13, 1, 1),
@ -463,7 +463,7 @@ SND_SOC_DAPM_VMID("VMID"),
static const struct snd_soc_dapm_route audio_map[] = { static const struct snd_soc_dapm_route audio_map[] = {
/* left HP mixer */ /* left HP mixer */
{"Left HP Mixer", "PC Beep Playback Switch", "PCBEEP"}, {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
{"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
{"Left HP Mixer", "Aux Playback Switch", "Aux DAC"}, {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"},
{"Left HP Mixer", "Bypass Playback Switch", "Left Line In"}, {"Left HP Mixer", "Bypass Playback Switch", "Left Line In"},
@ -472,7 +472,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"Left HP Mixer", NULL, "Capture Headphone Mux"}, {"Left HP Mixer", NULL, "Capture Headphone Mux"},
/* right HP mixer */ /* right HP mixer */
{"Right HP Mixer", "PC Beep Playback Switch", "PCBEEP"}, {"Right HP Mixer", "Beep Playback Switch", "PCBEEP"},
{"Right HP Mixer", "Voice Playback Switch", "Voice DAC"}, {"Right HP Mixer", "Voice Playback Switch", "Voice DAC"},
{"Right HP Mixer", "Aux Playback Switch", "Aux DAC"}, {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"},
{"Right HP Mixer", "Bypass Playback Switch", "Right Line In"}, {"Right HP Mixer", "Bypass Playback Switch", "Right Line In"},
@ -491,7 +491,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"Capture Mixer", NULL, "Right Capture Source"}, {"Capture Mixer", NULL, "Right Capture Source"},
/* speaker mixer */ /* speaker mixer */
{"Speaker Mixer", "PC Beep Playback Switch", "PCBEEP"}, {"Speaker Mixer", "Beep Playback Switch", "PCBEEP"},
{"Speaker Mixer", "Voice Playback Switch", "Voice DAC"}, {"Speaker Mixer", "Voice Playback Switch", "Voice DAC"},
{"Speaker Mixer", "Aux Playback Switch", "Aux DAC"}, {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"},
{"Speaker Mixer", "Bypass Playback Switch", "Line Mixer"}, {"Speaker Mixer", "Bypass Playback Switch", "Line Mixer"},
@ -499,7 +499,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"Speaker Mixer", "MonoIn Playback Switch", "Mono In"}, {"Speaker Mixer", "MonoIn Playback Switch", "Mono In"},
/* mono mixer */ /* mono mixer */
{"Mono Mixer", "PC Beep Playback Switch", "PCBEEP"}, {"Mono Mixer", "Beep Playback Switch", "PCBEEP"},
{"Mono Mixer", "Voice Playback Switch", "Voice DAC"}, {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
{"Mono Mixer", "Aux Playback Switch", "Aux DAC"}, {"Mono Mixer", "Aux Playback Switch", "Aux DAC"},
{"Mono Mixer", "Bypass Playback Switch", "Line Mixer"}, {"Mono Mixer", "Bypass Playback Switch", "Line Mixer"},

View file

@ -66,6 +66,28 @@ static int us122l_create_usbmidi(struct snd_card *card)
iface, &quirk); iface, &quirk);
} }
static int us144_create_usbmidi(struct snd_card *card)
{
static struct snd_usb_midi_endpoint_info quirk_data = {
.out_ep = 4,
.in_ep = 3,
.out_cables = 0x001,
.in_cables = 0x001
};
static struct snd_usb_audio_quirk quirk = {
.vendor_name = "US144",
.product_name = NAME_ALLCAPS,
.ifnum = 0,
.type = QUIRK_MIDI_US122L,
.data = &quirk_data
};
struct usb_device *dev = US122L(card)->chip.dev;
struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
return snd_usb_create_midi_interface(&US122L(card)->chip,
iface, &quirk);
}
/* /*
* Wrapper for usb_control_msg(). * Wrapper for usb_control_msg().
* Allocates a temp buffer to prevent dmaing from/to the stack. * Allocates a temp buffer to prevent dmaing from/to the stack.
@ -171,6 +193,11 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
if (!us122l->first) if (!us122l->first)
us122l->first = file; us122l->first = file;
if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
iface = usb_ifnum_to_if(us122l->chip.dev, 0);
usb_autopm_get_interface(iface);
}
iface = usb_ifnum_to_if(us122l->chip.dev, 1); iface = usb_ifnum_to_if(us122l->chip.dev, 1);
usb_autopm_get_interface(iface); usb_autopm_get_interface(iface);
return 0; return 0;
@ -179,8 +206,14 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file) static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
{ {
struct us122l *us122l = hw->private_data; struct us122l *us122l = hw->private_data;
struct usb_interface *iface = usb_ifnum_to_if(us122l->chip.dev, 1); struct usb_interface *iface;
snd_printdd(KERN_DEBUG "%p %p\n", hw, file); snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
iface = usb_ifnum_to_if(us122l->chip.dev, 0);
usb_autopm_put_interface(iface);
}
iface = usb_ifnum_to_if(us122l->chip.dev, 1);
usb_autopm_put_interface(iface); usb_autopm_put_interface(iface);
if (us122l->first == file) if (us122l->first == file)
us122l->first = NULL; us122l->first = NULL;
@ -443,6 +476,13 @@ static bool us122l_create_card(struct snd_card *card)
int err; int err;
struct us122l *us122l = US122L(card); struct us122l *us122l = US122L(card);
if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
err = usb_set_interface(us122l->chip.dev, 0, 1);
if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n");
return false;
}
}
err = usb_set_interface(us122l->chip.dev, 1, 1); err = usb_set_interface(us122l->chip.dev, 1, 1);
if (err) { if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n"); snd_printk(KERN_ERR "usb_set_interface error \n");
@ -455,7 +495,10 @@ static bool us122l_create_card(struct snd_card *card)
if (!us122l_start(us122l, 44100, 256)) if (!us122l_start(us122l, 44100, 256))
return false; return false;
err = us122l_create_usbmidi(card); if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144)
err = us144_create_usbmidi(card);
else
err = us122l_create_usbmidi(card);
if (err < 0) { if (err < 0) {
snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err); snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
us122l_stop(us122l); us122l_stop(us122l);
@ -542,6 +585,7 @@ static int us122l_usb_probe(struct usb_interface *intf,
return err; return err;
} }
usb_get_intf(usb_ifnum_to_if(device, 0));
usb_get_dev(device); usb_get_dev(device);
*cardp = card; *cardp = card;
return 0; return 0;
@ -550,9 +594,16 @@ static int us122l_usb_probe(struct usb_interface *intf,
static int snd_us122l_probe(struct usb_interface *intf, static int snd_us122l_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct usb_device *device = interface_to_usbdev(intf);
struct snd_card *card; struct snd_card *card;
int err; int err;
if (device->descriptor.idProduct == USB_ID_US144
&& device->speed == USB_SPEED_HIGH) {
snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
return -ENODEV;
}
snd_printdd(KERN_DEBUG"%p:%i\n", snd_printdd(KERN_DEBUG"%p:%i\n",
intf, intf->cur_altsetting->desc.bInterfaceNumber); intf, intf->cur_altsetting->desc.bInterfaceNumber);
if (intf->cur_altsetting->desc.bInterfaceNumber != 1) if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
@ -591,7 +642,8 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
snd_usbmidi_disconnect(p); snd_usbmidi_disconnect(p);
} }
usb_put_intf(intf); usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 0));
usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 1));
usb_put_dev(us122l->chip.dev); usb_put_dev(us122l->chip.dev);
while (atomic_read(&us122l->mmap_count)) while (atomic_read(&us122l->mmap_count))
@ -642,6 +694,13 @@ static int snd_us122l_resume(struct usb_interface *intf)
mutex_lock(&us122l->mutex); mutex_lock(&us122l->mutex);
/* needed, doesn't restart without: */ /* needed, doesn't restart without: */
if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) {
err = usb_set_interface(us122l->chip.dev, 0, 1);
if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n");
goto unlock;
}
}
err = usb_set_interface(us122l->chip.dev, 1, 1); err = usb_set_interface(us122l->chip.dev, 1, 1);
if (err) { if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n"); snd_printk(KERN_ERR "usb_set_interface error \n");
@ -675,11 +734,11 @@ static struct usb_device_id snd_us122l_usb_id_table[] = {
.idVendor = 0x0644, .idVendor = 0x0644,
.idProduct = USB_ID_US122L .idProduct = USB_ID_US122L
}, },
/* { */ /* US-144 maybe works when @USB1.1. Untested. */ { /* US-144 only works at USB1.1! Disable module ehci-hcd. */
/* .match_flags = USB_DEVICE_ID_MATCH_DEVICE, */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
/* .idVendor = 0x0644, */ .idVendor = 0x0644,
/* .idProduct = USB_ID_US144 */ .idProduct = USB_ID_US144
/* }, */ },
{ /* terminator */ } { /* terminator */ }
}; };