mirror of
https://github.com/adulau/aha.git
synced 2024-12-26 18:56:14 +00:00
Merge branch 'topic/beep-rename' into topic/core-change
This commit is contained in:
commit
75639e7ee1
47 changed files with 1171 additions and 2163 deletions
|
@ -1454,6 +1454,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
|
||||
Module for internal PC-Speaker.
|
||||
|
||||
nopcm - Disable PC-Speaker PCM sound. Only beeps remain.
|
||||
nforce_wa - enable NForce chipset workaround. Expect bad sound.
|
||||
|
||||
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 for ENSONIQ SoundScape PnP cards.
|
||||
Module for ENSONIQ SoundScape cards.
|
||||
|
||||
port - 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)
|
||||
dma - DMA # (PnP setup)
|
||||
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.
|
||||
You need sscape_ctl tool in alsa-tools package for loading
|
||||
the microcode.
|
||||
This module supports multiple cards.
|
||||
|
||||
The driver requires the firmware loader support on kernel.
|
||||
|
||||
Module snd-sun-amd7930 (on sparc only)
|
||||
--------------------------------------
|
||||
|
|
|
@ -18,8 +18,9 @@ SOURCE:
|
|||
Master
|
||||
Master Mono
|
||||
Hardware Master
|
||||
Speaker (internal speaker)
|
||||
Headphone
|
||||
PC Speaker
|
||||
Beep (beep generator)
|
||||
Phone
|
||||
Phone Input
|
||||
Phone Output
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/irq.h>
|
||||
#include <sound/sh_dac_audio.h>
|
||||
#include <asm/hd64461.h>
|
||||
#include <asm/io.h>
|
||||
#include <mach/hp6xx.h>
|
||||
|
@ -51,9 +52,63 @@ static struct platform_device jornadakbd_device = {
|
|||
.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 = {
|
||||
&cf_ide_device,
|
||||
&jornadakbd_device,
|
||||
&dac_audio_device,
|
||||
};
|
||||
|
||||
static void __init hp6xx_init_irq(void)
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#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_Y 0x02
|
||||
#define SCPDR_TS_SCAN_X 0x01
|
||||
|
@ -42,6 +45,7 @@
|
|||
#define ADC_CHANNEL_BACKUP 4
|
||||
#define ADC_CHANNEL_CHARGE 5
|
||||
|
||||
/* HP Jornada 680/690 speaker on/off */
|
||||
#define HD64461_GPADR_SPEAKER 0x01
|
||||
#define HD64461_GPADR_PCMCIA0 (0x02|0x08)
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ header-y += asound_fm.h
|
|||
header-y += hdsp.h
|
||||
header-y += hdspm.h
|
||||
header-y += sfnt_info.h
|
||||
header-y += sscape_ioctl.h
|
||||
|
||||
unifdef-y += asequencer.h
|
||||
unifdef-y += asound.h
|
||||
|
|
21
include/sound/sh_dac_audio.h
Normal file
21
include/sound/sh_dac_audio.h
Normal 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 */
|
|
@ -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
|
|
@ -85,16 +85,24 @@ EXPORT_SYMBOL(snd_dma_disable);
|
|||
unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int result;
|
||||
unsigned int result, result1;
|
||||
|
||||
flags = claim_dma_lock();
|
||||
clear_dma_ff(dma);
|
||||
if (!isa_dma_bridge_buggy)
|
||||
disable_dma(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)
|
||||
enable_dma(dma);
|
||||
release_dma_lock(flags);
|
||||
if (unlikely(result < result1))
|
||||
result = result1;
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
if (result > size)
|
||||
snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
|
||||
|
|
|
@ -1251,7 +1251,9 @@ static void snd_mixer_oss_build(struct snd_mixer_oss *mixer)
|
|||
{ SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */
|
||||
{ SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */
|
||||
{ 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_MIC, "Mic", 0 },
|
||||
{ SOUND_MIXER_CD, "CD", 0 },
|
||||
|
|
|
@ -26,6 +26,7 @@ MODULE_ALIAS("platform:pcspkr");
|
|||
static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
|
||||
static char *id = SNDRV_DEFAULT_STR1; /* ID for 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_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_param(enable, bool, 0444);
|
||||
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;
|
||||
|
||||
|
@ -43,13 +46,16 @@ static int __devinit snd_pcsp_create(struct snd_card *card)
|
|||
int err;
|
||||
int div, min_div, order;
|
||||
|
||||
hrtimer_get_res(CLOCK_MONOTONIC, &tp);
|
||||
if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) {
|
||||
printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
|
||||
"(%linS)\n", tp.tv_nsec);
|
||||
printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
|
||||
"enabled.\n");
|
||||
return -EIO;
|
||||
if (!nopcm) {
|
||||
hrtimer_get_res(CLOCK_MONOTONIC, &tp);
|
||||
if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) {
|
||||
printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
|
||||
"(%linS)\n", tp.tv_nsec);
|
||||
printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
|
||||
"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)
|
||||
|
@ -107,12 +113,14 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
|
|||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
err = snd_pcsp_new_pcm(&pcsp_chip);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
if (!nopcm) {
|
||||
err = snd_pcsp_new_pcm(&pcsp_chip);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
err = snd_pcsp_new_mixer(&pcsp_chip);
|
||||
err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
|
||||
if (err < 0) {
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
|
|
|
@ -83,6 +83,6 @@ extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
|
|||
extern void pcsp_sync_stop(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
|
||||
|
|
|
@ -119,24 +119,43 @@ static int pcsp_pcspkr_put(struct snd_kcontrol *kcontrol,
|
|||
.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(treble, "BaseFRQ Playback Volume"),
|
||||
PCSP_MIXER_CONTROL(pcspkr, "PC Speaker Playback Switch"),
|
||||
};
|
||||
|
||||
int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip)
|
||||
{
|
||||
struct snd_card *card = chip->card;
|
||||
int i, err;
|
||||
static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_spkr[] = {
|
||||
PCSP_MIXER_CONTROL(pcspkr, "Beep Playback Switch"),
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(snd_pcsp_controls); i++) {
|
||||
err = snd_ctl_add(card,
|
||||
snd_ctl_new1(snd_pcsp_controls + i,
|
||||
chip));
|
||||
static int __devinit snd_pcsp_ctls_add(struct snd_pcsp *chip,
|
||||
struct snd_kcontrol_new *ctls, int num)
|
||||
{
|
||||
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)
|
||||
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");
|
||||
|
||||
|
|
|
@ -372,15 +372,21 @@ config SND_SGALAXY
|
|||
|
||||
config SND_SSCAPE
|
||||
tristate "Ensoniq SoundScape driver"
|
||||
select SND_HWDEP
|
||||
select SND_MPU401_UART
|
||||
select SND_WSS_LIB
|
||||
select FW_LOADER
|
||||
help
|
||||
Say Y here to include support for Ensoniq SoundScape
|
||||
soundcards.
|
||||
and Ensoniq OEM soundcards.
|
||||
|
||||
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
|
||||
will be called snd-sscape.
|
||||
|
|
|
@ -237,7 +237,7 @@ WSS_DOUBLE("Wavetable Capture Volume", 0,
|
|||
CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0),
|
||||
WSS_SINGLE("3D Control - Switch", 0,
|
||||
CMI8330_RMUX3D, 5, 1, 1),
|
||||
WSS_SINGLE("PC Speaker Playback Volume", 0,
|
||||
WSS_SINGLE("Beep Playback Volume", 0,
|
||||
CMI8330_OUTPUTVOL, 3, 3, 0),
|
||||
WSS_DOUBLE("FM Playback Switch", 0,
|
||||
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_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 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 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),
|
||||
|
|
|
@ -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("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_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_SINGLE("Capture Switch", 0, ES1688_REC_DEV, 4, 1, 1),
|
||||
{
|
||||
|
|
|
@ -121,7 +121,6 @@ struct snd_es18xx {
|
|||
unsigned int dma1_shift;
|
||||
unsigned int dma2_shift;
|
||||
|
||||
struct snd_card *card;
|
||||
struct snd_pcm *pcm;
|
||||
struct snd_pcm_substream *playback_a_substream;
|
||||
struct snd_pcm_substream *capture_a_substream;
|
||||
|
@ -140,10 +139,6 @@ struct snd_es18xx {
|
|||
#ifdef CONFIG_PM
|
||||
unsigned char pm_reg;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct snd_audiodrive {
|
||||
struct snd_es18xx *chip;
|
||||
#ifdef CONFIG_PNP
|
||||
struct pnp_dev *dev;
|
||||
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)
|
||||
{
|
||||
struct snd_es18xx *chip = dev_id;
|
||||
struct snd_card *card = dev_id;
|
||||
struct snd_es18xx *chip = card->private_data;
|
||||
unsigned char status;
|
||||
|
||||
if (chip->caps & ES18XX_CONTROL) {
|
||||
|
@ -805,12 +801,16 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
|
|||
int split = 0;
|
||||
if (chip->caps & ES18XX_HWV) {
|
||||
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(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->hw_switch->id);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->hw_volume->id);
|
||||
}
|
||||
if (!split) {
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_switch->id);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_volume->id);
|
||||
}
|
||||
/* ack interrupt */
|
||||
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
|
||||
*/
|
||||
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[] = {
|
||||
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,
|
||||
};
|
||||
|
||||
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;
|
||||
char str[16];
|
||||
int err;
|
||||
|
@ -1701,9 +1703,9 @@ static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct
|
|||
*rpcm = NULL;
|
||||
sprintf(str, "ES%x", chip->version);
|
||||
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
|
||||
err = snd_pcm_new(chip->card, str, device, 1, 1, &pcm);
|
||||
err = snd_pcm_new(card, str, device, 1, 1, &pcm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1734,10 +1736,9 @@ static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct
|
|||
#ifdef CONFIG_PM
|
||||
static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state)
|
||||
{
|
||||
struct snd_audiodrive *acard = card->private_data;
|
||||
struct snd_es18xx *chip = acard->chip;
|
||||
struct snd_es18xx *chip = card->private_data;
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
struct snd_audiodrive *acard = card->private_data;
|
||||
struct snd_es18xx *chip = acard->chip;
|
||||
struct snd_es18xx *chip = card->private_data;
|
||||
|
||||
/* 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_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
#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_ctrl_port);
|
||||
release_and_free_resource(chip->res_mpu_port);
|
||||
if (chip->irq >= 0)
|
||||
free_irq(chip->irq, (void *) chip);
|
||||
free_irq(chip->irq, (void *) card);
|
||||
if (chip->dma1 >= 0) {
|
||||
disable_dma(chip->dma1);
|
||||
free_dma(chip->dma1);
|
||||
|
@ -1778,37 +1780,29 @@ static int snd_es18xx_free(struct snd_es18xx *chip)
|
|||
disable_dma(chip->dma2);
|
||||
free_dma(chip->dma2);
|
||||
}
|
||||
kfree(chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_es18xx_dev_free(struct snd_device *device)
|
||||
{
|
||||
struct snd_es18xx *chip = device->device_data;
|
||||
return snd_es18xx_free(chip);
|
||||
return snd_es18xx_free(device->card);
|
||||
}
|
||||
|
||||
static int __devinit snd_es18xx_new_device(struct snd_card *card,
|
||||
unsigned long port,
|
||||
unsigned long mpu_port,
|
||||
unsigned long fm_port,
|
||||
int irq, int dma1, int dma2,
|
||||
struct snd_es18xx ** rchip)
|
||||
int irq, int dma1, int dma2)
|
||||
{
|
||||
struct snd_es18xx *chip;
|
||||
struct snd_es18xx *chip = card->private_data;
|
||||
static struct snd_device_ops ops = {
|
||||
.dev_free = snd_es18xx_dev_free,
|
||||
};
|
||||
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->mixer_lock);
|
||||
spin_lock_init(&chip->ctrl_lock);
|
||||
chip->card = card;
|
||||
chip->port = port;
|
||||
chip->mpu_port = mpu_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->active = 0;
|
||||
|
||||
if ((chip->res_port = request_region(port, 16, "ES18xx")) == NULL) {
|
||||
snd_es18xx_free(chip);
|
||||
chip->res_port = request_region(port, 16, "ES18xx");
|
||||
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);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (request_irq(irq, snd_es18xx_interrupt, IRQF_DISABLED, "ES18xx", (void *) chip)) {
|
||||
snd_es18xx_free(chip);
|
||||
if (request_irq(irq, snd_es18xx_interrupt, IRQF_DISABLED, "ES18xx",
|
||||
(void *) card)) {
|
||||
snd_es18xx_free(card);
|
||||
snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
chip->irq = irq;
|
||||
|
||||
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);
|
||||
return -EBUSY;
|
||||
}
|
||||
chip->dma1 = dma1;
|
||||
|
||||
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);
|
||||
return -EBUSY;
|
||||
}
|
||||
chip->dma2 = dma2;
|
||||
|
||||
if (snd_es18xx_probe(chip) < 0) {
|
||||
snd_es18xx_free(chip);
|
||||
snd_es18xx_free(card);
|
||||
return -ENODEV;
|
||||
}
|
||||
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
|
||||
snd_es18xx_free(chip);
|
||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, NULL, &ops);
|
||||
if (err < 0) {
|
||||
snd_es18xx_free(card);
|
||||
return err;
|
||||
}
|
||||
*rchip = chip;
|
||||
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;
|
||||
unsigned int idx;
|
||||
|
||||
card = chip->card;
|
||||
|
||||
strcpy(card->mixername, chip->pcm->name);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
acard->dev = pdev;
|
||||
if (snd_audiodrive_pnp_init_main(dev, acard->dev) < 0)
|
||||
chip->dev = pdev;
|
||||
if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
|
||||
return -EBUSY;
|
||||
return 0;
|
||||
}
|
||||
|
@ -2093,26 +2087,26 @@ static struct pnp_card_device_id 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,
|
||||
const struct pnp_card_device_id *id)
|
||||
{
|
||||
acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
|
||||
if (acard->dev == NULL)
|
||||
chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
|
||||
if (chip->dev == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
acard->devc = pnp_request_card_device(card, id->devs[1].id, NULL);
|
||||
if (acard->devc == NULL)
|
||||
chip->devc = pnp_request_card_device(card, id->devs[1].id, NULL);
|
||||
if (chip->devc == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
/* 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");
|
||||
return -EAGAIN;
|
||||
}
|
||||
snd_printdd("pnp: port=0x%llx\n",
|
||||
(unsigned long long)pnp_port_start(acard->devc, 0));
|
||||
if (snd_audiodrive_pnp_init_main(dev, acard->dev) < 0)
|
||||
(unsigned long long)pnp_port_start(chip->devc, 0));
|
||||
if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
|
||||
return -EBUSY;
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
struct snd_audiodrive *acard = card->private_data;
|
||||
struct snd_es18xx *chip;
|
||||
struct snd_es18xx *chip = card->private_data;
|
||||
struct snd_opl3 *opl3;
|
||||
int err;
|
||||
|
||||
if ((err = snd_es18xx_new_device(card,
|
||||
port[dev],
|
||||
mpu_port[dev],
|
||||
fm_port[dev],
|
||||
irq[dev], dma1[dev], dma2[dev],
|
||||
&chip)) < 0)
|
||||
err = snd_es18xx_new_device(card,
|
||||
port[dev], mpu_port[dev], fm_port[dev],
|
||||
irq[dev], dma1[dev], dma2[dev]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
acard->chip = chip;
|
||||
|
||||
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,
|
||||
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;
|
||||
|
||||
if ((err = snd_es18xx_mixer(chip)) < 0)
|
||||
err = snd_es18xx_mixer(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
|
||||
|
|
|
@ -631,7 +631,7 @@ static struct sbmix_elem snd_sb16_ctl_mic_play_switch =
|
|||
static struct sbmix_elem snd_sb16_ctl_mic_play_vol =
|
||||
SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31);
|
||||
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 =
|
||||
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 =
|
||||
|
@ -689,7 +689,7 @@ static struct sbmix_elem snd_dt019x_ctl_cd_play_vol =
|
|||
static struct sbmix_elem snd_dt019x_ctl_mic_play_vol =
|
||||
SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7);
|
||||
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 =
|
||||
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 =
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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_5bit_12db_max, -3450, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 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 const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
|
||||
|
||||
static struct snd_kcontrol_new snd_wss_controls[] = {
|
||||
WSS_DOUBLE("PCM Playback Switch", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("PCM Playback Volume", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
|
||||
WSS_DOUBLE("Line Playback Switch", 0,
|
||||
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_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("Aux Playback Volume", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 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("Aux Playback Volume", 1,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
|
||||
WSS_SINGLE("Mono Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, 7, 1, 1),
|
||||
WSS_SINGLE("Mono Playback Volume", 0,
|
||||
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),
|
||||
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),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Capture Source",
|
||||
|
@ -2267,15 +2229,30 @@ WSS_DOUBLE("Mic Boost", 0,
|
|||
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
|
||||
WSS_SINGLE("Loopback Capture Switch", 0,
|
||||
CS4231_LOOPBACK, 0, 1, 0),
|
||||
WSS_SINGLE("Loopback Capture Volume", 0,
|
||||
CS4231_LOOPBACK, 2, 63, 1)
|
||||
WSS_SINGLE_TLV("Loopback Capture Volume", 0, 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[] = {
|
||||
WSS_DOUBLE("Master Playback Switch", 0,
|
||||
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Master Playback Volume", 0,
|
||||
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
|
||||
WSS_DOUBLE_TLV("Master Playback Volume", 0,
|
||||
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
|
||||
db_scale_6bit),
|
||||
WSS_DOUBLE("PCM Playback Switch", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("PCM Playback Volume", 0,
|
||||
|
@ -2334,22 +2311,21 @@ int snd_wss_mixer(struct snd_wss *chip)
|
|||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
else if (chip->hardware & WSS_HW_AD1848_MASK)
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) {
|
||||
err = snd_ctl_add(card,
|
||||
snd_ctl_new1(&snd_ad1848_controls[idx],
|
||||
chip));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
else
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_wss_controls); idx++) {
|
||||
else {
|
||||
int count = ARRAY_SIZE(snd_wss_controls);
|
||||
|
||||
/* Use only the first 11 entries on AD1848 */
|
||||
if (chip->hardware & WSS_HW_AD1848_MASK)
|
||||
count = 11;
|
||||
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
err = snd_ctl_add(card,
|
||||
snd_ctl_new1(&snd_wss_controls[idx],
|
||||
chip));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_wss_mixer);
|
||||
|
|
|
@ -287,18 +287,6 @@ config SOUND_DMAP
|
|||
|
||||
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
|
||||
tristate "Loopback MIDI device support"
|
||||
help
|
||||
|
|
|
@ -13,7 +13,6 @@ obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o
|
|||
obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.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_SSCAPE) += sscape.o ad1848.o mpu401.o
|
||||
obj-$(CONFIG_SOUND_MSS) += ad1848.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
|
||||
|
|
|
@ -164,9 +164,6 @@ static ssize_t dac_audio_write(struct file *file, const char *buf, size_t count,
|
|||
int free;
|
||||
int nbytes;
|
||||
|
||||
if (count < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!count) {
|
||||
dac_audio_sync();
|
||||
return 0;
|
||||
|
|
1480
sound/oss/sscape.c
1480
sound/oss/sscape.c
File diff suppressed because it is too large
Load diff
|
@ -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] = {
|
||||
AC97_SINGLE("PC Speaker Playback Switch", AC97_PC_BEEP, 15, 1, 1),
|
||||
AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1)
|
||||
AC97_SINGLE("Beep Playback Switch", AC97_PC_BEEP, 15, 1, 1),
|
||||
AC97_SINGLE("Beep Playback Volume", AC97_PC_BEEP, 1, 15, 1)
|
||||
};
|
||||
|
||||
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) &&
|
||||
((ac97->flags & AC97_HAS_PC_BEEP) ||
|
||||
snd_ac97_try_volume_mix(ac97, AC97_PC_BEEP))) {
|
||||
|
|
|
@ -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 Volume", AC97_MASTER_TONE, 0, 31, 1),
|
||||
|
||||
AC97_SINGLE("PC Beep to Headphone Switch", AC97_AUX, 15, 1, 1),
|
||||
AC97_SINGLE("PC Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
|
||||
AC97_SINGLE("PC Beep to Master Switch", AC97_AUX, 11, 1, 1),
|
||||
AC97_SINGLE("PC Beep to Master Volume", AC97_AUX, 8, 7, 1),
|
||||
AC97_SINGLE("PC 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 Headphone Switch", AC97_AUX, 15, 1, 1),
|
||||
AC97_SINGLE("Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
|
||||
AC97_SINGLE("Beep to Master Switch", AC97_AUX, 11, 1, 1),
|
||||
AC97_SINGLE("Beep to Master Volume", AC97_AUX, 8, 7, 1),
|
||||
AC97_SINGLE("Beep to Mono Switch", AC97_AUX, 7, 1, 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 Volume", AC97_PCM, 12, 7, 1),
|
||||
|
|
|
@ -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("Line Playback Switch", IDX_MIXER_LINEIN, 15, 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_VOL_SPECIAL("PC Speaker Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
|
||||
AZF3328_MIXER_SWITCH("Beep Playback Switch", IDX_MIXER_PCBEEP, 15, 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_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
|
||||
AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
|
||||
|
|
|
@ -792,8 +792,8 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
|
|||
"Phone Playback Volume",
|
||||
"Video Playback Switch",
|
||||
"Video Playback Volume",
|
||||
"PC Speaker Playback Switch",
|
||||
"PC Speaker Playback Volume",
|
||||
"Beep Playback Switch",
|
||||
"Beep Playback Volume",
|
||||
"Mono Output Select",
|
||||
"Capture Source",
|
||||
"Capture Switch",
|
||||
|
|
|
@ -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))) {
|
||||
if (sscanf(line, "%x %x", ®, &val) != 2)
|
||||
continue;
|
||||
if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) {
|
||||
if (reg < 0x40 && val <= 0xffffffff) {
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
outl(val, emu->port + (reg & 0xfffffffc));
|
||||
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))) {
|
||||
if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_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_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_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),
|
||||
|
@ -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_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("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),
|
||||
};
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ static int select_rom(unsigned int pitch)
|
|||
} else if (pitch == 0x02000000) {
|
||||
/* pitch == 2 */
|
||||
return 3;
|
||||
} else if (pitch >= 0x0 && pitch <= 0x08000000) {
|
||||
} else if (pitch <= 0x08000000) {
|
||||
/* 0 <= pitch <= 8 */
|
||||
return 0;
|
||||
} else {
|
||||
|
|
|
@ -1040,8 +1040,7 @@ static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry,
|
|||
if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3)
|
||||
continue;
|
||||
|
||||
if ((reg < 0x49) && (reg >= 0) && (val <= 0xffffffff)
|
||||
&& (channel_id >= 0) && (channel_id <= 2) )
|
||||
if (reg < 0x49 && val <= 0xffffffff && channel_id <= 2)
|
||||
snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1818,8 +1818,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
|
|||
"Master Playback Switch", "Master Capture Switch",
|
||||
"Master Playback Volume", "Master Capture Volume",
|
||||
"Wave Master Playback Volume", "Master Playback Volume",
|
||||
"PC Speaker Playback Switch", "PC Speaker Capture Switch",
|
||||
"PC Speaker Playback Volume", "PC Speaker Capture Volume",
|
||||
"Beep Playback Switch", "Beep Capture Switch",
|
||||
"Beep Playback Volume", "Beep Capture Volume",
|
||||
"Phone Playback Switch", "Phone Capture Switch",
|
||||
"Phone Playback Volume", "Phone Capture Volume",
|
||||
"Mic Playback Switch", "Mic Capture Switch",
|
||||
|
|
|
@ -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))) {
|
||||
if (sscanf(line, "%x %x", ®, &val) != 2)
|
||||
continue;
|
||||
if ((reg < 0x40) && (reg >= 0) && (val <= 0xffffffff) ) {
|
||||
if (reg < 0x40 && val <= 0xffffffff) {
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
outl(val, emu->port + (reg & 0xfffffffc));
|
||||
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))) {
|
||||
if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value)
|
|||
if (reg > 0x3f)
|
||||
return 1;
|
||||
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;
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
outl(reg, emu->port + A_IOCFG);
|
||||
|
|
|
@ -1387,7 +1387,7 @@ ES1938_DOUBLE_TLV("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0,
|
|||
db_scale_line),
|
||||
ES1938_DOUBLE_TLV("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0,
|
||||
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("Capture Switch", 0, 0x1c, 4, 1, 1),
|
||||
{
|
||||
|
|
|
@ -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_MUTE("Capture Switch", 0x08, 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_MUTE("PC Speaker Playback Switch", 0x23, 0, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("Beep Playback Volume", 0x23, 0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE("Beep Playback Switch", 0x23, 0, HDA_OUTPUT),
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
|
|
|
@ -7336,8 +7336,8 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = {
|
|||
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
|
||||
/* FIXME: this looks suspicious...
|
||||
HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
|
||||
HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
|
||||
*/
|
||||
{ } /* end */
|
||||
};
|
||||
|
|
|
@ -3224,7 +3224,7 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
|
|||
/* check for mute support for the the amp */
|
||||
if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
|
||||
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));
|
||||
if (err < 0)
|
||||
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 */
|
||||
if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
|
||||
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));
|
||||
if (err < 0)
|
||||
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)
|
||||
{
|
||||
return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
|
||||
0, "PC Beep Playback Switch", 0);
|
||||
0, "Beep Playback Switch", 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "PC Speaker Playback Volume",
|
||||
.name = "Speaker Playback Volume",
|
||||
.info = snd_pmac_awacs_info_volume_amp,
|
||||
.get = snd_pmac_awacs_get_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 = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "PC Speaker Playback Switch",
|
||||
.name = "Speaker Playback Switch",
|
||||
.info = snd_pmac_boolean_stereo_info,
|
||||
.get = snd_pmac_awacs_get_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 = {
|
||||
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 =
|
||||
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 =
|
||||
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 =
|
||||
AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
|
||||
AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -505,7 +505,7 @@ static struct snd_kcontrol_new snd_pmac_burgundy_mixers_imac[] __devinitdata = {
|
|||
MASK_ADDR_BURGUNDY_GAINLINE, 1, 0),
|
||||
BURGUNDY_VOLUME_B("Mic Gain Capture Volume", 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),
|
||||
BURGUNDY_VOLUME_B("Line out Playback Volume", 0,
|
||||
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),
|
||||
BURGUNDY_VOLUME_B("Line in Gain Capture Volume", 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),
|
||||
BURGUNDY_VOLUME_B("Line out Playback Volume", 0,
|
||||
MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1),
|
||||
|
@ -549,11 +549,11 @@ BURGUNDY_SWITCH_B("Master Playback Switch", 0,
|
|||
BURGUNDY_OUTPUT_INTERN
|
||||
| BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
|
||||
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,
|
||||
BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
|
||||
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,
|
||||
BURGUNDY_OUTPUT_INTERN, 0, 0);
|
||||
static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_imac __devinitdata =
|
||||
|
|
|
@ -905,7 +905,7 @@ static struct snd_kcontrol_new tumbler_hp_sw __devinitdata = {
|
|||
};
|
||||
static struct snd_kcontrol_new tumbler_speaker_sw __devinitdata = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "PC Speaker Playback Switch",
|
||||
.name = "Speaker Playback Switch",
|
||||
.info = snd_pmac_boolean_mono_info,
|
||||
.get = tumbler_get_mute_switch,
|
||||
.put = tumbler_put_mute_switch,
|
||||
|
|
|
@ -19,5 +19,13 @@ config SND_AICA
|
|||
help
|
||||
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
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#
|
||||
|
||||
snd-aica-objs := aica.o
|
||||
snd-sh_dac_audio-objs := sh_dac_audio.o
|
||||
|
||||
# Toplevel Module Dependency
|
||||
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
453
sound/sh/sh_dac_audio.c
Normal 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);
|
|
@ -85,7 +85,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
|
|||
* 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);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -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 Volume", AC97_MASTER_TONE, 0, 31, 1),
|
||||
|
||||
SOC_SINGLE("PC Beep Playback Headphone Volume", AC97_AUX, 12, 7, 1),
|
||||
SOC_SINGLE("PC 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 Headphone Volume", AC97_AUX, 12, 7, 1),
|
||||
SOC_SINGLE("Beep Playback Speaker Volume", AC97_AUX, 8, 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 Master Volume", AC97_PCM, 8, 7, 1),
|
||||
|
@ -266,7 +266,7 @@ static int mixer_event(struct snd_soc_dapm_widget *w,
|
|||
|
||||
/* Left Headphone Mixers */
|
||||
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("Aux Playback Switch", HPL_MIXER, 3, 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 */
|
||||
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("Aux Playback Switch", HPR_MIXER, 3, 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 */
|
||||
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("Aux Playback Switch", AC97_REC_SEL, 11, 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 */
|
||||
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("Aux Playback Switch", AC97_REC_SEL, 7, 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[] = {
|
||||
/* 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", "Aux Playback Switch", "Aux DAC"},
|
||||
{"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"},
|
||||
|
||||
/* 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", "Aux Playback Switch", "Aux DAC"},
|
||||
{"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"},
|
||||
|
||||
/* speaker mixer */
|
||||
{"Speaker Mixer", "PC Beep Playback Switch", "PCBEEP"},
|
||||
{"Speaker Mixer", "Beep Playback Switch", "PCBEEP"},
|
||||
{"Speaker Mixer", "Voice Playback Switch", "Voice DAC"},
|
||||
{"Speaker Mixer", "Aux Playback Switch", "Aux DAC"},
|
||||
{"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"},
|
||||
|
||||
/* mono mixer */
|
||||
{"Mono Mixer", "PC Beep Playback Switch", "PCBEEP"},
|
||||
{"Mono Mixer", "Beep Playback Switch", "PCBEEP"},
|
||||
{"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
|
||||
{"Mono Mixer", "Aux Playback Switch", "Aux DAC"},
|
||||
{"Mono Mixer", "Bypass Playback Switch", "Line Mixer"},
|
||||
|
|
|
@ -66,6 +66,28 @@ static int us122l_create_usbmidi(struct snd_card *card)
|
|||
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().
|
||||
* 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)
|
||||
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);
|
||||
usb_autopm_get_interface(iface);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
if (us122l->first == file)
|
||||
us122l->first = NULL;
|
||||
|
@ -443,6 +476,13 @@ static bool us122l_create_card(struct snd_card *card)
|
|||
int err;
|
||||
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);
|
||||
if (err) {
|
||||
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))
|
||||
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) {
|
||||
snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
|
||||
us122l_stop(us122l);
|
||||
|
@ -542,6 +585,7 @@ static int us122l_usb_probe(struct usb_interface *intf,
|
|||
return err;
|
||||
}
|
||||
|
||||
usb_get_intf(usb_ifnum_to_if(device, 0));
|
||||
usb_get_dev(device);
|
||||
*cardp = card;
|
||||
return 0;
|
||||
|
@ -550,9 +594,16 @@ static int us122l_usb_probe(struct usb_interface *intf,
|
|||
static int snd_us122l_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *device = interface_to_usbdev(intf);
|
||||
struct snd_card *card;
|
||||
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",
|
||||
intf, intf->cur_altsetting->desc.bInterfaceNumber);
|
||||
if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
|
||||
|
@ -591,7 +642,8 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
|
|||
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);
|
||||
|
||||
while (atomic_read(&us122l->mmap_count))
|
||||
|
@ -642,6 +694,13 @@ static int snd_us122l_resume(struct usb_interface *intf)
|
|||
|
||||
mutex_lock(&us122l->mutex);
|
||||
/* 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);
|
||||
if (err) {
|
||||
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,
|
||||
.idProduct = USB_ID_US122L
|
||||
},
|
||||
/* { */ /* US-144 maybe works when @USB1.1. Untested. */
|
||||
/* .match_flags = USB_DEVICE_ID_MATCH_DEVICE, */
|
||||
/* .idVendor = 0x0644, */
|
||||
/* .idProduct = USB_ID_US144 */
|
||||
/* }, */
|
||||
{ /* US-144 only works at USB1.1! Disable module ehci-hcd. */
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x0644,
|
||||
.idProduct = USB_ID_US144
|
||||
},
|
||||
{ /* terminator */ }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue