summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-07-22 10:43:24 +0400
committerTakashi Iwai <tiwai@suse.de>2011-07-22 10:43:24 +0400
commit7d339ae99758bc21033d4a19bcd4f7b55f96e24e (patch)
treea5bb46e47f7c4ae193cdf1a73c361144d6099df8 /sound
parent13b137ef0367237909bb2dc38babfb8305154676 (diff)
parent000477a0fe1af14355a52622a77ccce8bfd7230d (diff)
downloadlinux-7d339ae99758bc21033d4a19bcd4f7b55f96e24e.tar.xz
Merge branch 'topic/misc' into for-linus
Diffstat (limited to 'sound')
-rw-r--r--sound/core/rawmidi.c45
-rw-r--r--sound/firewire/speakers.c2
-rw-r--r--sound/pci/ad1889.c4
-rw-r--r--sound/pci/ali5451/ali5451.c4
-rw-r--r--sound/pci/als300.c4
-rw-r--r--sound/pci/als4000.c2
-rw-r--r--sound/pci/asihpi/asihpi.c81
-rw-r--r--sound/pci/asihpi/hpi.h24
-rw-r--r--sound/pci/asihpi/hpi6000.c11
-rw-r--r--sound/pci/asihpi/hpi6205.c52
-rw-r--r--sound/pci/asihpi/hpi6205.h25
-rw-r--r--sound/pci/asihpi/hpi_internal.h155
-rw-r--r--sound/pci/asihpi/hpicmn.c17
-rw-r--r--sound/pci/asihpi/hpidspcd.c136
-rw-r--r--sound/pci/asihpi/hpidspcd.h72
-rw-r--r--sound/pci/asihpi/hpifunc.c86
-rw-r--r--sound/pci/asihpi/hpimsginit.c4
-rw-r--r--sound/pci/asihpi/hpimsgx.c6
-rw-r--r--sound/pci/asihpi/hpioctl.c10
-rw-r--r--sound/pci/asihpi/hpios.c8
-rw-r--r--sound/pci/asihpi/hpios.h1
-rw-r--r--sound/pci/atiixp.c4
-rw-r--r--sound/pci/atiixp_modem.c4
-rw-r--r--sound/pci/au88x0/au88x0.c4
-rw-r--r--sound/pci/aw2/aw2-alsa.c4
-rw-r--r--sound/pci/azt3328.c4
-rw-r--r--sound/pci/bt87x.c4
-rw-r--r--sound/pci/ca0106/ca0106_main.c4
-rw-r--r--sound/pci/cmipci.c4
-rw-r--r--sound/pci/cs4281.c4
-rw-r--r--sound/pci/cs46xx/cs46xx.c2
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c2
-rw-r--r--sound/pci/cs5530.c2
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c4
-rw-r--r--sound/pci/ctxfi/ct20k2reg.h1
-rw-r--r--sound/pci/ctxfi/ctatc.c107
-rw-r--r--sound/pci/ctxfi/ctatc.h8
-rw-r--r--sound/pci/ctxfi/ctdaio.c23
-rw-r--r--sound/pci/ctxfi/ctdaio.h1
-rw-r--r--sound/pci/ctxfi/cthardware.h14
-rw-r--r--sound/pci/ctxfi/cthw20k1.c15
-rw-r--r--sound/pci/ctxfi/cthw20k2.c337
-rw-r--r--sound/pci/ctxfi/ctmixer.c145
-rw-r--r--sound/pci/ctxfi/xfi.c6
-rw-r--r--sound/pci/echoaudio/echoaudio.c6
-rw-r--r--sound/pci/emu10k1/emu10k1.c2
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c2
-rw-r--r--sound/pci/emu10k1/emu10k1x.c4
-rw-r--r--sound/pci/ens1370.c4
-rw-r--r--sound/pci/es1938.c6
-rw-r--r--sound/pci/es1968.c68
-rw-r--r--sound/pci/fm801.c4
-rw-r--r--sound/pci/hda/hda_codec.c10
-rw-r--r--sound/pci/hda/hda_intel.c4
-rw-r--r--sound/pci/ice1712/ice1712.c4
-rw-r--r--sound/pci/ice1712/ice1724.c4
-rw-r--r--sound/pci/intel8x0.c12
-rw-r--r--sound/pci/intel8x0m.c6
-rw-r--r--sound/pci/korg1212/korg1212.c4
-rw-r--r--sound/pci/lola/lola.c4
-rw-r--r--sound/pci/lola/lola.h2
-rw-r--r--sound/pci/lola/lola_mixer.c130
-rw-r--r--sound/pci/lx6464es/lx6464es.c25
-rw-r--r--sound/pci/lx6464es/lx6464es.h2
-rw-r--r--sound/pci/lx6464es/lx_core.c14
-rw-r--r--sound/pci/lx6464es/lx_core.h2
-rw-r--r--sound/pci/maestro3.c75
-rw-r--r--sound/pci/mixart/mixart.c4
-rw-r--r--sound/pci/nm256/nm256.c4
-rw-r--r--sound/pci/oxygen/oxygen.c2
-rw-r--r--sound/pci/oxygen/oxygen_lib.c2
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c6
-rw-r--r--sound/pci/oxygen/virtuoso.c2
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c5
-rw-r--r--sound/pci/pcxhr/pcxhr.c4
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/pci/rme32.c4
-rw-r--r--sound/pci/rme96.c4
-rw-r--r--sound/pci/rme9652/hdsp.c4
-rw-r--r--sound/pci/rme9652/hdspm.c4
-rw-r--r--sound/pci/rme9652/rme9652.c4
-rw-r--r--sound/pci/sis7019.c6
-rw-r--r--sound/pci/sonicvibes.c4
-rw-r--r--sound/pci/trident/trident.c2
-rw-r--r--sound/pci/trident/trident_main.c2
-rw-r--r--sound/pci/via82xx.c4
-rw-r--r--sound/pci/via82xx_modem.c4
-rw-r--r--sound/pci/vx222/vx222.c4
-rw-r--r--sound/pci/ymfpci/ymfpci.c2
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c2
-rw-r--r--sound/pcmcia/vx/vxpocket.c2
-rw-r--r--sound/usb/card.c16
-rw-r--r--sound/usb/endpoint.c2
-rw-r--r--sound/usb/misc/ua101.c2
-rw-r--r--sound/usb/quirks-table.h30
-rw-r--r--sound/usb/quirks.c159
97 files changed, 1227 insertions, 917 deletions
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index cbbed0db9e56..849a0ed95054 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -92,16 +92,12 @@ static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substre
(!substream->append || runtime->avail >= count);
}
-static void snd_rawmidi_input_event_tasklet(unsigned long data)
+static void snd_rawmidi_input_event_work(struct work_struct *work)
{
- struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
- substream->runtime->event(substream);
-}
-
-static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
-{
- struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
- substream->ops->trigger(substream, 1);
+ struct snd_rawmidi_runtime *runtime =
+ container_of(work, struct snd_rawmidi_runtime, event_work);
+ if (runtime->event)
+ runtime->event(runtime->substream);
}
static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
@@ -110,16 +106,10 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
return -ENOMEM;
+ runtime->substream = substream;
spin_lock_init(&runtime->lock);
init_waitqueue_head(&runtime->sleep);
- if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
- tasklet_init(&runtime->tasklet,
- snd_rawmidi_input_event_tasklet,
- (unsigned long)substream);
- else
- tasklet_init(&runtime->tasklet,
- snd_rawmidi_output_trigger_tasklet,
- (unsigned long)substream);
+ INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
runtime->event = NULL;
runtime->buffer_size = PAGE_SIZE;
runtime->avail_min = 1;
@@ -150,12 +140,7 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
{
if (!substream->opened)
return;
- if (up) {
- tasklet_schedule(&substream->runtime->tasklet);
- } else {
- tasklet_kill(&substream->runtime->tasklet);
- substream->ops->trigger(substream, 0);
- }
+ substream->ops->trigger(substream, up);
}
static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -163,8 +148,8 @@ static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, i
if (!substream->opened)
return;
substream->ops->trigger(substream, up);
- if (!up && substream->runtime->event)
- tasklet_kill(&substream->runtime->tasklet);
+ if (!up)
+ cancel_work_sync(&substream->runtime->event_work);
}
int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
@@ -641,10 +626,10 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
return -EINVAL;
}
if (params->buffer_size != runtime->buffer_size) {
- newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
+ newbuf = krealloc(runtime->buffer, params->buffer_size,
+ GFP_KERNEL);
if (!newbuf)
return -ENOMEM;
- kfree(runtime->buffer);
runtime->buffer = newbuf;
runtime->buffer_size = params->buffer_size;
runtime->avail = runtime->buffer_size;
@@ -668,10 +653,10 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
return -EINVAL;
}
if (params->buffer_size != runtime->buffer_size) {
- newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
+ newbuf = krealloc(runtime->buffer, params->buffer_size,
+ GFP_KERNEL);
if (!newbuf)
return -ENOMEM;
- kfree(runtime->buffer);
runtime->buffer = newbuf;
runtime->buffer_size = params->buffer_size;
}
@@ -926,7 +911,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
}
if (result > 0) {
if (runtime->event)
- tasklet_schedule(&runtime->tasklet);
+ schedule_work(&runtime->event_work);
else if (snd_rawmidi_ready(substream))
wake_up(&runtime->sleep);
}
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index 5466de8527bd..3fc257da180c 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -171,7 +171,7 @@ static int fwspk_open(struct snd_pcm_substream *substream)
err = snd_pcm_hw_constraint_minmax(runtime,
SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- 5000, 8192000);
+ 5000, UINT_MAX);
if (err < 0)
return err;
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index d8f6fd65ebbb..201503673f25 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -944,7 +944,7 @@ snd_ad1889_create(struct snd_card *card,
spin_lock_init(&chip->lock); /* only now can we call ad1889_free */
if (request_irq(pci->irq, snd_ad1889_interrupt,
- IRQF_SHARED, card->driver, chip)) {
+ IRQF_SHARED, KBUILD_MODNAME, chip)) {
printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
snd_ad1889_free(chip);
return -EBUSY;
@@ -1055,7 +1055,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
static struct pci_driver ad1889_pci_driver = {
- .name = "AD1889 Audio",
+ .name = KBUILD_MODNAME,
.id_table = snd_ad1889_ids,
.probe = snd_ad1889_probe,
.remove = __devexit_p(snd_ad1889_remove),
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 5c6e322a48f0..b444b74d9dcf 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -2090,7 +2090,7 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
codec->port = pci_resource_start(codec->pci, 0);
if (request_irq(codec->pci->irq, snd_ali_card_interrupt,
- IRQF_SHARED, "ALI 5451", codec)) {
+ IRQF_SHARED, KBUILD_MODNAME, codec)) {
snd_printk(KERN_ERR "Unable to request irq.\n");
return -EBUSY;
}
@@ -2295,7 +2295,7 @@ static void __devexit snd_ali_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "ALI 5451",
+ .name = KBUILD_MODNAME,
.id_table = snd_ali_ids,
.probe = snd_ali_probe,
.remove = __devexit_p(snd_ali_remove),
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index d7653cb7ac60..736c8e93db1f 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -722,7 +722,7 @@ static int __devinit snd_als300_create(struct snd_card *card,
irq_handler = snd_als300_interrupt;
if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
- card->shortname, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_als300_free(chip);
return -EBUSY;
@@ -846,7 +846,7 @@ static int __devinit snd_als300_probe(struct pci_dev *pci,
}
static struct pci_driver driver = {
- .name = "ALS300",
+ .name = KBUILD_MODNAME,
.id_table = snd_als300_ids,
.probe = snd_als300_probe,
.remove = __devexit_p(snd_als300_remove),
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 0e247cb90ecc..a9c1af33f276 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -1036,7 +1036,7 @@ static int snd_als4000_resume(struct pci_dev *pci)
static struct pci_driver driver = {
- .name = "ALS4000",
+ .name = KBUILD_MODNAME,
.id_table = snd_als4000_ids,
.probe = snd_card_als4000_probe,
.remove = __devexit_p(snd_card_als4000_remove),
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index e3569bdd3b64..b941d2541dda 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -49,19 +49,21 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
#if defined CONFIG_SND_DEBUG
/* copied from pcm_lib.c, hope later patch will make that version public
and this copy can be removed */
-static void pcm_debug_name(struct snd_pcm_substream *substream,
- char *name, size_t len)
+static inline void
+snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
{
- snprintf(name, len, "pcmC%dD%d%c:%d",
+ snprintf(buf, size, "pcmC%dD%d%c:%d",
substream->pcm->card->number,
substream->pcm->device,
substream->stream ? 'c' : 'p',
substream->number);
}
-#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
#else
-#define pcm_debug_name(s, n, l) do { } while (0)
-#define DEBUG_NAME(name, substream) do { } while (0)
+static inline void
+snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
+{
+ *buf = 0;
+}
#endif
#if defined CONFIG_SND_DEBUG_VERBOSE
@@ -304,7 +306,8 @@ static u16 handle_error(u16 err, int line, char *filename)
static void print_hwparams(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *p)
{
- DEBUG_NAME(substream, name);
+ char name[16];
+ snd_pcm_debug_name(substream, name, sizeof(name));
snd_printd("%s HWPARAMS\n", name);
snd_printd(" samplerate %d Hz\n", params_rate(p));
snd_printd(" channels %d\n", params_channels(p));
@@ -576,8 +579,9 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
struct snd_pcm_substream *s;
u16 e;
- DEBUG_NAME(substream, name);
+ char name[16];
+ snd_pcm_debug_name(substream, name, sizeof(name));
snd_printdd("%s trigger\n", name);
switch (cmd) {
@@ -741,7 +745,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
int loops = 0;
u16 state;
u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
- DEBUG_NAME(substream, name);
+ char name[16];
+
+ snd_pcm_debug_name(substream, name, sizeof(name));
snd_printdd("%s snd_card_asihpi_timer_function\n", name);
@@ -1323,10 +1329,12 @@ static const char * const asihpi_src_names[] = {
"RF",
"Clock",
"Bitstream",
- "Microphone",
- "Cobranet",
+ "Mic",
+ "Net",
"Analog",
"Adapter",
+ "RTP",
+ "GPI",
};
compile_time_assert(
@@ -1341,8 +1349,10 @@ static const char * const asihpi_dst_names[] = {
"Digital",
"RF",
"Speaker",
- "Cobranet Out",
- "Analog"
+ "Net",
+ "Analog",
+ "RTP",
+ "GPO",
};
compile_time_assert(
@@ -1476,11 +1486,40 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
+#define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info
+
+static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u32 h_control = kcontrol->private_value;
+ u32 mute;
+
+ hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
+ ucontrol->value.integer.value[0] = mute ? 0 : 1;
+
+ return 0;
+}
+
+static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u32 h_control = kcontrol->private_value;
+ int change = 1;
+ /* HPI currently only supports all or none muting of multichannel volume
+ ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
+ */
+ int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
+ hpi_handle_error(hpi_volume_set_mute(h_control, mute));
+ return change;
+}
+
static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
struct hpi_control *hpi_ctl)
{
struct snd_card *card = asihpi->card;
struct snd_kcontrol_new snd_control;
+ int err;
+ u32 mute;
asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1490,7 +1529,19 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
snd_control.put = snd_asihpi_volume_put;
snd_control.tlv.p = db_scale_100;
- return ctl_add(card, &snd_control, asihpi);
+ err = ctl_add(card, &snd_control, asihpi);
+ if (err)
+ return err;
+
+ if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
+ asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
+ snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+ snd_control.info = snd_asihpi_volume_mute_info;
+ snd_control.get = snd_asihpi_volume_mute_get;
+ snd_control.put = snd_asihpi_volume_mute_put;
+ err = ctl_add(card, &snd_control, asihpi);
+ }
+ return err;
}
/*------------------------------------------------------------
@@ -2923,7 +2974,7 @@ static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
static struct pci_driver driver = {
- .name = "asihpi",
+ .name = KBUILD_MODNAME,
.id_table = asihpi_pci_tbl,
.probe = snd_asihpi_probe,
.remove = __devexit_p(snd_asihpi_remove),
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
index 255429c32c1c..f20727288994 100644
--- a/sound/pci/asihpi/hpi.h
+++ b/sound/pci/asihpi/hpi.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -42,12 +42,11 @@ i.e 3.05.02 is a development version
#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
-/* Use single digits for versions less that 10 to avoid octal. */
-#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 6, 0)
-#define HPI_VER_STRING "4.06.00"
+#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 8, 0)
+#define HPI_VER_STRING "4.08.00"
/* Library version as documented in hpi-api-versions.txt */
-#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0)
+#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 0, 0)
#include <linux/types.h>
#define HPI_BUILD_EXCLUDE_DEPRECATED
@@ -211,8 +210,12 @@ enum HPI_SOURCENODES {
HPI_SOURCENODE_COBRANET = 109,
HPI_SOURCENODE_ANALOG = 110, /**< analog input node. */
HPI_SOURCENODE_ADAPTER = 111, /**< adapter node. */
+ /** RTP stream input node - This node is a destination for
+ packets of RTP audio samples from other devices. */
+ HPI_SOURCENODE_RTP_DESTINATION = 112,
+ HPI_SOURCENODE_GP_IN = 113, /**< general purpose input. */
/* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
- HPI_SOURCENODE_LAST_INDEX = 111 /**< largest ID */
+ HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */
/* AX6 max sourcenode types = 15 */
};
@@ -228,7 +231,7 @@ enum HPI_DESTNODES {
HPI_DESTNODE_NONE = 200,
/** In Stream (Record) node. */
HPI_DESTNODE_ISTREAM = 201,
- HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
+ HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
HPI_DESTNODE_AESEBU_OUT = 203, /**< AES/EBU output node. */
HPI_DESTNODE_RF = 204, /**< RF output node. */
HPI_DESTNODE_SPEAKER = 205, /**< speaker output node. */
@@ -236,9 +239,12 @@ enum HPI_DESTNODES {
Audio samples from the device are sent out on the Cobranet network.*/
HPI_DESTNODE_COBRANET = 206,
HPI_DESTNODE_ANALOG = 207, /**< analog output node. */
-
+ /** RTP stream output node - This node is a source for
+ packets of RTP audio samples that are sent to other devices. */
+ HPI_DESTNODE_RTP_SOURCE = 208,
+ HPI_DESTNODE_GP_OUT = 209, /**< general purpose output node. */
/* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
- HPI_DESTNODE_LAST_INDEX = 207 /**< largest ID */
+ HPI_DESTNODE_LAST_INDEX = 209 /**< largest ID */
/* AX6 max destnode types = 15 */
};
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index df4aed5295dd..3cc6f11c20aa 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -359,7 +359,7 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
HPI_ERROR_PROCESSING_MESSAGE);
switch (phm->type) {
- case HPI_TYPE_MESSAGE:
+ case HPI_TYPE_REQUEST:
switch (phm->object) {
case HPI_OBJ_SUBSYSTEM:
subsys_message(phm, phr);
@@ -538,7 +538,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
memset(&hm, 0, sizeof(hm));
- hm.type = HPI_TYPE_MESSAGE;
+ hm.type = HPI_TYPE_REQUEST;
hm.size = sizeof(struct hpi_message);
hm.object = HPI_OBJ_ADAPTER;
hm.function = HPI_ADAPTER_GET_INFO;
@@ -946,11 +946,8 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
}
/* write the DSP code down into the DSPs memory */
- /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
- dsp_code.ps_dev = pao->pci.pci_dev;
-
- error = hpi_dsp_code_open(boot_load_family, &dsp_code,
- pos_error_code);
+ error = hpi_dsp_code_open(boot_load_family, pao->pci.pci_dev,
+ &dsp_code, pos_error_code);
if (error)
return error;
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index 9d5df54a6b46..e041a6ae1c5a 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -373,6 +373,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
/** Entry point to this HPI backend
* All calls to the HPI start here
*/
+static
void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
struct hpi_response *phr)
{
@@ -392,7 +393,7 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
switch (phm->type) {
- case HPI_TYPE_MESSAGE:
+ case HPI_TYPE_REQUEST:
switch (phm->object) {
case HPI_OBJ_SUBSYSTEM:
subsys_message(pao, phm, phr);
@@ -402,7 +403,6 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
adapter_message(pao, phm, phr);
break;
- case HPI_OBJ_CONTROLEX:
case HPI_OBJ_CONTROL:
control_message(pao, phm, phr);
break;
@@ -634,11 +634,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
memset(&hm, 0, sizeof(hm));
- hm.type = HPI_TYPE_MESSAGE;
+ /* wAdapterIndex == version == 0 */
+ hm.type = HPI_TYPE_REQUEST;
hm.size = sizeof(hm);
hm.object = HPI_OBJ_ADAPTER;
hm.function = HPI_ADAPTER_GET_INFO;
- hm.adapter_index = 0;
+
memset(&hr, 0, sizeof(hr));
hr.size = sizeof(hr);
@@ -658,9 +659,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
hr.u.ax.info.num_outstreams +
hr.u.ax.info.num_instreams;
- hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
- 65536, pao->pci.pci_dev);
-
HPI_DEBUG_LOG(VERBOSE,
"got adapter info type %x index %d serial %d\n",
hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
@@ -709,9 +707,6 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao)
[i]);
phw->outstream_host_buffer_size[i] = 0;
}
-
- hpios_locked_mem_unprepare(pao->pci.pci_dev);
-
kfree(phw);
}
@@ -1371,9 +1366,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
return err;
/* write the DSP code down into the DSPs memory */
- dsp_code.ps_dev = pao->pci.pci_dev;
- err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
- pos_error_code);
+ err = hpi_dsp_code_open(boot_code_id[dsp], pao->pci.pci_dev,
+ &dsp_code, pos_error_code);
if (err)
return err;
@@ -2084,13 +2078,13 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
u16 err = 0;
message_count++;
- if (phm->size > sizeof(interface->u)) {
+ if (phm->size > sizeof(interface->u.message_buffer)) {
phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
- phr->specific_error = sizeof(interface->u);
+ phr->specific_error = sizeof(interface->u.message_buffer);
phr->size = sizeof(struct hpi_response_header);
HPI_DEBUG_LOG(ERROR,
"message len %d too big for buffer %zd \n", phm->size,
- sizeof(interface->u));
+ sizeof(interface->u.message_buffer));
return 0;
}
@@ -2122,18 +2116,19 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
/* read the result */
if (time_out) {
- if (interface->u.response_buffer.size <= phr->size)
+ if (interface->u.response_buffer.response.size <= phr->size)
memcpy(phr, &interface->u.response_buffer,
- interface->u.response_buffer.size);
+ interface->u.response_buffer.response.size);
else {
HPI_DEBUG_LOG(ERROR,
"response len %d too big for buffer %d\n",
- interface->u.response_buffer.size, phr->size);
+ interface->u.response_buffer.response.size,
+ phr->size);
memcpy(phr, &interface->u.response_buffer,
sizeof(struct hpi_response_header));
phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
phr->specific_error =
- interface->u.response_buffer.size;
+ interface->u.response_buffer.response.size;
phr->size = sizeof(struct hpi_response_header);
}
}
@@ -2202,23 +2197,6 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
break;
- case HPI_CONTROL_SET_STATE:
- if (phm->object == HPI_OBJ_CONTROLEX
- && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
- err = hpi6205_transfer_data(pao,
- phm->u.cx.u.cobranet_bigdata.pb_data,
- phm->u.cx.u.cobranet_bigdata.byte_count,
- H620_HIF_SEND_DATA);
- break;
-
- case HPI_CONTROL_GET_STATE:
- if (phm->object == HPI_OBJ_CONTROLEX
- && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
- err = hpi6205_transfer_data(pao,
- phm->u.cx.u.cobranet_bigdata.pb_data,
- phr->u.cx.u.cobranet_data.byte_count,
- H620_HIF_GET_DATA);
- break;
}
phr->error = err;
diff --git a/sound/pci/asihpi/hpi6205.h b/sound/pci/asihpi/hpi6205.h
index df2f02c0c7b4..ec0827b633a6 100644
--- a/sound/pci/asihpi/hpi6205.h
+++ b/sound/pci/asihpi/hpi6205.h
@@ -1,7 +1,7 @@
/*****************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -70,15 +70,28 @@ The Host located memory buffer that the 6205 will bus master
in and out of.
************************************************************/
#define HPI6205_SIZEOF_DATA (16*1024)
+
+struct message_buffer_6205 {
+ struct hpi_message message;
+ char data[256];
+};
+
+struct response_buffer_6205 {
+ struct hpi_response response;
+ char data[256];
+};
+
+union buffer_6205 {
+ struct message_buffer_6205 message_buffer;
+ struct response_buffer_6205 response_buffer;
+ u8 b_data[HPI6205_SIZEOF_DATA];
+};
+
struct bus_master_interface {
u32 host_cmd;
u32 dsp_ack;
u32 transfer_size_in_bytes;
- union {
- struct hpi_message_header message_buffer;
- struct hpi_response_header response_buffer;
- u8 b_data[HPI6205_SIZEOF_DATA];
- } u;
+ union buffer_6205 u;
struct controlcache_6205 control_cache;
struct async_event_buffer_6205 async_buffer;
struct hpi_hostbuffer_status
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index bf5eced76bac..d497030c160f 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -1,7 +1,7 @@
/******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -32,12 +32,6 @@ HPI internal definitions
#include "hpios.h"
/* physical memory allocation */
-void hpios_locked_mem_init(void
- );
-void hpios_locked_mem_free_all(void
- );
-#define hpios_locked_mem_prepare(a, b, c, d);
-#define hpios_locked_mem_unprepare(a)
/** Allocate and map an area of locked memory for bus master DMA operations.
@@ -226,8 +220,8 @@ enum HPI_CONTROL_ATTRIBUTES {
HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
- HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3),
- HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4),
+ /*HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3), */
+ /*HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4), */
HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
@@ -364,10 +358,12 @@ Used in DLL to indicate device not present
#define HPI_ADAPTER_ASI(f) (f)
enum HPI_MESSAGE_TYPES {
- HPI_TYPE_MESSAGE = 1,
+ HPI_TYPE_REQUEST = 1,
HPI_TYPE_RESPONSE = 2,
HPI_TYPE_DATA = 3,
- HPI_TYPE_SSX2BYPASS_MESSAGE = 4
+ HPI_TYPE_SSX2BYPASS_MESSAGE = 4,
+ HPI_TYPE_COMMAND = 5,
+ HPI_TYPE_NOTIFICATION = 6
};
enum HPI_OBJECT_TYPES {
@@ -383,7 +379,7 @@ enum HPI_OBJECT_TYPES {
HPI_OBJ_WATCHDOG = 10,
HPI_OBJ_CLOCK = 11,
HPI_OBJ_PROFILE = 12,
- HPI_OBJ_CONTROLEX = 13,
+ /* HPI_ OBJ_ CONTROLEX = 13, */
HPI_OBJ_ASYNCEVENT = 14
#define HPI_OBJ_MAXINDEX 14
};
@@ -608,7 +604,7 @@ struct hpi_data_compat32 {
#endif
struct hpi_buffer {
- /** placehoder for backward compatibility (see dwBufferSize) */
+ /** placeholder for backward compatibility (see dwBufferSize) */
struct hpi_msg_format reserved;
u32 command; /**< HPI_BUFFER_CMD_xxx*/
u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
@@ -912,95 +908,13 @@ union hpi_control_union_res {
u32 remaining_chars;
} chars8;
char c_data12[12];
-};
-
-/* HPI_CONTROLX_STRUCTURES */
-
-/* Message */
-
-/** Used for all HMI variables where max length <= 8 bytes
-*/
-struct hpi_controlx_msg_cobranet_data {
- u32 hmi_address;
- u32 byte_count;
- u32 data[2];
-};
-
-/** Used for string data, and for packet bridge
-*/
-struct hpi_controlx_msg_cobranet_bigdata {
- u32 hmi_address;
- u32 byte_count;
- u8 *pb_data;
-#ifndef HPI64BIT
- u32 padding;
-#endif
-};
-
-/** Used for PADS control reading of string fields.
-*/
-struct hpi_controlx_msg_pad_data {
- u32 field;
- u32 byte_count;
- u8 *pb_data;
-#ifndef HPI64BIT
- u32 padding;
-#endif
-};
-
-/** Used for generic data
-*/
-
-struct hpi_controlx_msg_generic {
- u32 param1;
- u32 param2;
-};
-
-struct hpi_controlx_msg {
- u16 attribute; /* control attribute or property */
- u16 saved_index;
- union {
- struct hpi_controlx_msg_cobranet_data cobranet_data;
- struct hpi_controlx_msg_cobranet_bigdata cobranet_bigdata;
- struct hpi_controlx_msg_generic generic;
- struct hpi_controlx_msg_pad_data pad_data;
- /*struct param_value universal_value; */
- /* nothing extra to send for status read */
- } u;
-};
-
-/* Response */
-/**
-*/
-struct hpi_controlx_res_cobranet_data {
- u32 byte_count;
- u32 data[2];
-};
-
-struct hpi_controlx_res_cobranet_bigdata {
- u32 byte_count;
-};
-
-struct hpi_controlx_res_cobranet_status {
- u32 status;
- u32 readable_size;
- u32 writeable_size;
-};
-
-struct hpi_controlx_res_generic {
- u32 param1;
- u32 param2;
-};
-
-struct hpi_controlx_res {
union {
- struct hpi_controlx_res_cobranet_bigdata cobranet_bigdata;
- struct hpi_controlx_res_cobranet_data cobranet_data;
- struct hpi_controlx_res_cobranet_status cobranet_status;
- struct hpi_controlx_res_generic generic;
- /*struct param_info universal_info; */
- /*struct param_value universal_value; */
- } u;
+ struct {
+ u32 status;
+ u32 readable_size;
+ u32 writeable_size;
+ } status;
+ } cobranet;
};
struct hpi_nvmemory_msg {
@@ -1126,7 +1040,6 @@ struct hpi_message {
/* identical to struct hpi_control_msg,
but field naming is improved */
struct hpi_control_union_msg cu;
- struct hpi_controlx_msg cx; /* extended mixer control; */
struct hpi_nvmemory_msg n;
struct hpi_gpio_msg l; /* digital i/o */
struct hpi_watchdog_msg w;
@@ -1151,7 +1064,7 @@ struct hpi_message {
sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\
sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\
sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\
- sizeof(struct hpi_message_header) + sizeof(struct hpi_controlx_msg),\
+ sizeof(struct hpi_message_header), /* controlx obj removed */ \
sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
}
@@ -1188,7 +1101,6 @@ struct hpi_response {
struct hpi_control_res c; /* mixer control; */
/* identical to hpi_control_res, but field naming is improved */
union hpi_control_union_res cu;
- struct hpi_controlx_res cx; /* extended mixer control; */
struct hpi_nvmemory_res n;
struct hpi_gpio_res l; /* digital i/o */
struct hpi_watchdog_res w;
@@ -1213,7 +1125,7 @@ struct hpi_response {
sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\
sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\
sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\
- sizeof(struct hpi_response_header) + sizeof(struct hpi_controlx_res),\
+ sizeof(struct hpi_response_header), /* controlx obj removed */ \
sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
}
@@ -1308,6 +1220,30 @@ struct hpi_res_adapter_debug_read {
u8 bytes[256];
};
+struct hpi_msg_cobranet_hmi {
+ u16 attribute;
+ u16 padding;
+ u32 hmi_address;
+ u32 byte_count;
+};
+
+struct hpi_msg_cobranet_hmiwrite {
+ struct hpi_message_header h;
+ struct hpi_msg_cobranet_hmi p;
+ u8 bytes[256];
+};
+
+struct hpi_msg_cobranet_hmiread {
+ struct hpi_message_header h;
+ struct hpi_msg_cobranet_hmi p;
+};
+
+struct hpi_res_cobranet_hmiread {
+ struct hpi_response_header h;
+ u32 byte_count;
+ u8 bytes[256];
+};
+
#if 1
#define hpi_message_header_v1 hpi_message_header
#define hpi_response_header_v1 hpi_response_header
@@ -1338,7 +1274,6 @@ struct hpi_msg_payload_v0 {
union hpi_mixerx_msg mx;
struct hpi_control_msg c;
struct hpi_control_union_msg cu;
- struct hpi_controlx_msg cx;
struct hpi_nvmemory_msg n;
struct hpi_gpio_msg l;
struct hpi_watchdog_msg w;
@@ -1358,7 +1293,6 @@ struct hpi_res_payload_v0 {
union hpi_mixerx_res mx;
struct hpi_control_res c;
union hpi_control_union_res cu;
- struct hpi_controlx_res cx;
struct hpi_nvmemory_res n;
struct hpi_gpio_res l;
struct hpi_watchdog_res w;
@@ -1493,12 +1427,6 @@ struct hpi_control_cache_microphone {
char temp_padding[6];
};
-struct hpi_control_cache_generic {
- struct hpi_control_cache_info i;
- u32 dw1;
- u32 dw2;
-};
-
struct hpi_control_cache_single {
union {
struct hpi_control_cache_info i;
@@ -1514,7 +1442,6 @@ struct hpi_control_cache_single {
struct hpi_control_cache_silencedetector silence;
struct hpi_control_cache_sampleclock clk;
struct hpi_control_cache_microphone microphone;
- struct hpi_control_cache_generic generic;
} u;
};
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index b15a02e91f82..65b7ca13115b 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -57,7 +57,7 @@ u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
}
if (phr->function != phm->function) {
- HPI_DEBUG_LOG(ERROR, "header type %d invalid\n",
+ HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
phr->function);
return HPI_ERROR_INVALID_RESPONSE;
}
@@ -315,8 +315,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
short found = 1;
struct hpi_control_cache_info *pI;
struct hpi_control_cache_single *pC;
- struct hpi_control_cache_pad *p_pad;
-
+ size_t response_size;
if (!find_control(phm->obj_index, p_cache, &pI)) {
HPI_DEBUG_LOG(VERBOSE,
"HPICMN find_control() failed for adap %d\n",
@@ -326,11 +325,15 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
phr->error = 0;
+ /* set the default response size */
+ response_size =
+ sizeof(struct hpi_response_header) +
+ sizeof(struct hpi_control_res);
+
/* pC is the default cached control strucure. May be cast to
something else in the following switch statement.
*/
pC = (struct hpi_control_cache_single *)pI;
- p_pad = (struct hpi_control_cache_pad *)pI;
switch (pI->control_type) {
@@ -529,9 +532,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
pI->control_index, pI->control_type, phm->u.c.attribute);
if (found)
- phr->size =
- sizeof(struct hpi_response_header) +
- sizeof(struct hpi_control_res);
+ phr->size = (u16)response_size;
return found;
}
@@ -682,7 +683,7 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
{
switch (phm->type) {
- case HPI_TYPE_MESSAGE:
+ case HPI_TYPE_REQUEST:
switch (phm->object) {
case HPI_OBJ_SUBSYSTEM:
subsys_message(phm, phr);
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
index 5c6ea113d219..3a7afa31c1d8 100644
--- a/sound/pci/asihpi/hpidspcd.c
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -1,8 +1,8 @@
/***********************************************************************/
-/*!
+/**
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -18,90 +18,59 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\file
-Functions for reading DSP code to load into DSP
-
-(Linux only:) If DSPCODE_FIRMWARE_LOADER is defined, code is read using
+Functions for reading DSP code using
hotplug firmware loader from individual dsp code files
-
-If neither of the above is defined, code is read from linked arrays.
-DSPCODE_ARRAY is defined.
-
-HPI_INCLUDE_**** must be defined
-and the appropriate hzz?????.c or hex?????.c linked in
-
- */
+*/
/***********************************************************************/
#define SOURCEFILE_NAME "hpidspcd.c"
#include "hpidspcd.h"
#include "hpidebug.h"
-/**
- Header structure for binary dsp code file (see asidsp.doc)
- This structure must match that used in s2bin.c for generation of asidsp.bin
- */
-
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(push, 1)
-#endif
-
-struct code_header {
- u32 size;
- char type[4];
- u32 adapter;
- u32 version;
- u32 crc;
+struct dsp_code_private {
+ /** Firmware descriptor */
+ const struct firmware *firmware;
+ struct pci_dev *dev;
};
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(pop)
-#endif
-
#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
-/***********************************************************************/
-#include <linux/pci.h>
/*-------------------------------------------------------------------*/
-short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
- u32 *pos_error_code)
+short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
+ u32 *os_error_code)
{
- const struct firmware *ps_firmware = ps_dsp_code->ps_firmware;
+ const struct firmware *firmware;
+ struct pci_dev *dev = os_data;
struct code_header header;
char fw_name[20];
int err;
sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
- err = request_firmware(&ps_firmware, fw_name,
- &ps_dsp_code->ps_dev->dev);
+ err = request_firmware(&firmware, fw_name, &dev->dev);
- if (err != 0) {
- dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
+ if (err || !firmware) {
+ dev_printk(KERN_ERR, &dev->dev,
"%d, request_firmware failed for %s\n", err,
fw_name);
goto error1;
}
- if (ps_firmware->size < sizeof(header)) {
- dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
- "Header size too small %s\n", fw_name);
- goto error2;
- }
- memcpy(&header, ps_firmware->data, sizeof(header));
- if (header.adapter != adapter) {
- dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
- "Adapter type incorrect %4x != %4x\n", header.adapter,
- adapter);
+ if (firmware->size < sizeof(header)) {
+ dev_printk(KERN_ERR, &dev->dev, "Header size too small %s\n",
+ fw_name);
goto error2;
}
- if (header.size != ps_firmware->size) {
- dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
- "Code size wrong %d != %ld\n", header.size,
- (unsigned long)ps_firmware->size);
+ memcpy(&header, firmware->data, sizeof(header));
+
+ if ((header.type != 0x45444F43) || /* "CODE" */
+ (header.adapter != adapter)
+ || (header.size != firmware->size)) {
+ dev_printk(KERN_ERR, &dev->dev, "Invalid firmware file\n");
goto error2;
}
- if (header.version / 100 != HPI_VER_DECIMAL / 100) {
- dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
+ if ((header.version / 100 & ~1) != (HPI_VER_DECIMAL / 100 & ~1)) {
+ dev_printk(KERN_ERR, &dev->dev,
"Incompatible firmware version "
"DSP image %d != Driver %d\n", header.version,
HPI_VER_DECIMAL);
@@ -109,67 +78,70 @@ short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
}
if (header.version != HPI_VER_DECIMAL) {
- dev_printk(KERN_WARNING, &ps_dsp_code->ps_dev->dev,
+ dev_printk(KERN_WARNING, &dev->dev,
"Firmware: release version mismatch DSP image %d != Driver %d\n",
header.version, HPI_VER_DECIMAL);
}
HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
- ps_dsp_code->ps_firmware = ps_firmware;
- ps_dsp_code->block_length = header.size / sizeof(u32);
- ps_dsp_code->word_count = sizeof(header) / sizeof(u32);
- ps_dsp_code->version = header.version;
- ps_dsp_code->crc = header.crc;
+ dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL);
+ if (!dsp_code->pvt)
+ return HPI_ERROR_MEMORY_ALLOC;
+
+ dsp_code->pvt->dev = dev;
+ dsp_code->pvt->firmware = firmware;
+ dsp_code->header = header;
+ dsp_code->block_length = header.size / sizeof(u32);
+ dsp_code->word_count = sizeof(header) / sizeof(u32);
return 0;
error2:
- release_firmware(ps_firmware);
+ release_firmware(firmware);
error1:
- ps_dsp_code->ps_firmware = NULL;
- ps_dsp_code->block_length = 0;
+ dsp_code->block_length = 0;
return HPI_ERROR_DSP_FILE_NOT_FOUND;
}
/*-------------------------------------------------------------------*/
-void hpi_dsp_code_close(struct dsp_code *ps_dsp_code)
+void hpi_dsp_code_close(struct dsp_code *dsp_code)
{
- if (ps_dsp_code->ps_firmware != NULL) {
+ if (dsp_code->pvt->firmware) {
HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
- release_firmware(ps_dsp_code->ps_firmware);
- ps_dsp_code->ps_firmware = NULL;
+ release_firmware(dsp_code->pvt->firmware);
+ dsp_code->pvt->firmware = NULL;
}
+ kfree(dsp_code->pvt);
}
/*-------------------------------------------------------------------*/
-void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code)
+void hpi_dsp_code_rewind(struct dsp_code *dsp_code)
{
/* Go back to start of data, after header */
- ps_dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
+ dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
}
/*-------------------------------------------------------------------*/
-short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword)
+short hpi_dsp_code_read_word(struct dsp_code *dsp_code, u32 *pword)
{
- if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length)
+ if (dsp_code->word_count + 1 > dsp_code->block_length)
return HPI_ERROR_DSP_FILE_FORMAT;
- *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code->
+ *pword = ((u32 *)(dsp_code->pvt->firmware->data))[dsp_code->
word_count];
- ps_dsp_code->word_count++;
+ dsp_code->word_count++;
return 0;
}
/*-------------------------------------------------------------------*/
short hpi_dsp_code_read_block(size_t words_requested,
- struct dsp_code *ps_dsp_code, u32 **ppblock)
+ struct dsp_code *dsp_code, u32 **ppblock)
{
- if (ps_dsp_code->word_count + words_requested >
- ps_dsp_code->block_length)
+ if (dsp_code->word_count + words_requested > dsp_code->block_length)
return HPI_ERROR_DSP_FILE_FORMAT;
*ppblock =
- ((u32 *)(ps_dsp_code->ps_firmware->data)) +
- ps_dsp_code->word_count;
- ps_dsp_code->word_count += words_requested;
+ ((u32 *)(dsp_code->pvt->firmware->data)) +
+ dsp_code->word_count;
+ dsp_code->word_count += words_requested;
return 0;
}
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
index 65f0ca732704..b22881122f19 100644
--- a/sound/pci/asihpi/hpidspcd.h
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -2,7 +2,7 @@
/**
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -20,19 +20,6 @@
\file
Functions for reading DSP code to load into DSP
- hpi_dspcode_defines HPI DSP code loading method
-Define exactly one of these to select how the DSP code is supplied to
-the adapter.
-
-End users writing applications that use the HPI interface do not have to
-use any of the below defines; they are only necessary for building drivers
-
-HPI_DSPCODE_FILE:
-DSP code is supplied as a file that is opened and read from by the driver.
-
-HPI_DSPCODE_FIRMWARE:
-DSP code is read using the hotplug firmware loader module.
- Only valid when compiling the HPI kernel driver under Linux.
*/
/***********************************************************************/
#ifndef _HPIDSPCD_H_
@@ -40,37 +27,56 @@ DSP code is read using the hotplug firmware loader module.
#include "hpi_internal.h"
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(push, 1)
-#endif
+/** Code header version is decimal encoded e.g. 4.06.10 is 40601 */
+#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
+HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
+
+/** Header structure for dsp firmware file
+ This structure must match that used in s2bin.c for generation of asidsp.bin
+ */
+/*#ifndef DISABLE_PRAGMA_PACK1 */
+/*#pragma pack(push, 1) */
+/*#endif */
+struct code_header {
+ /** Size in bytes including header */
+ u32 size;
+ /** File type tag "CODE" == 0x45444F43 */
+ u32 type;
+ /** Adapter model number */
+ u32 adapter;
+ /** Firmware version*/
+ u32 version;
+ /** Data checksum */
+ u32 checksum;
+};
+/*#ifndef DISABLE_PRAGMA_PACK1 */
+/*#pragma pack(pop) */
+/*#endif */
+
+/*? Don't need the pragmas? */
+compile_time_assert((sizeof(struct code_header) == 20), code_header_size);
/** Descriptor for dspcode from firmware loader */
struct dsp_code {
- /** Firmware descriptor */
- const struct firmware *ps_firmware;
- struct pci_dev *ps_dev;
+ /** copy of file header */
+ struct code_header header;
/** Expected number of words in the whole dsp code,INCL header */
- long int block_length;
+ u32 block_length;
/** Number of words read so far */
- long int word_count;
- /** Version read from dsp code file */
- u32 version;
- /** CRC read from dsp code file */
- u32 crc;
-};
+ u32 word_count;
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(pop)
-#endif
+ /** internal state of DSP code reader */
+ struct dsp_code_private *pvt;
+};
-/** Prepare *psDspCode to refer to the requuested adapter.
- Searches the file, or selects the appropriate linked array
+/** Prepare *psDspCode to refer to the requested adapter's firmware.
+Code file name is obtained from HpiOs_GetDspCodePath
\return 0 for success, or error code if requested code is not available
*/
short hpi_dsp_code_open(
/** Code identifier, usually adapter family */
- u32 adapter,
+ u32 adapter, void *pci_dev,
/** Pointer to DSP code control structure */
struct dsp_code *ps_dsp_code,
/** Pointer to dword to receive OS specific error code */
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index 7397b169b89f..ebb568d695f1 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -1663,68 +1663,64 @@ u16 hpi_channel_mode_get(u32 h_control, u16 *mode)
u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
u8 *pb_data)
{
- struct hpi_message hm;
- struct hpi_response hr;
+ struct hpi_msg_cobranet_hmiwrite hm;
+ struct hpi_response_header hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
- HPI_CONTROL_SET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
- return HPI_ERROR_INVALID_HANDLE;
+ hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr, sizeof(hr),
+ HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
- hm.u.cx.u.cobranet_data.byte_count = byte_count;
- hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
+ if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
+ &hm.h.obj_index))
+ return HPI_ERROR_INVALID_HANDLE;
- if (byte_count <= 8) {
- memcpy(hm.u.cx.u.cobranet_data.data, pb_data, byte_count);
- hm.u.cx.attribute = HPI_COBRANET_SET;
- } else {
- hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
- hm.u.cx.attribute = HPI_COBRANET_SET_DATA;
- }
+ if (byte_count > sizeof(hm.bytes))
+ return HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
- hpi_send_recv(&hm, &hr);
+ hm.p.attribute = HPI_COBRANET_SET;
+ hm.p.byte_count = byte_count;
+ hm.p.hmi_address = hmi_address;
+ memcpy(hm.bytes, pb_data, byte_count);
+ hm.h.size = (u16)(sizeof(hm.h) + sizeof(hm.p) + byte_count);
+ hpi_send_recvV1(&hm.h, &hr);
return hr.error;
}
u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
u32 *pbyte_count, u8 *pb_data)
{
- struct hpi_message hm;
- struct hpi_response hr;
+ struct hpi_msg_cobranet_hmiread hm;
+ struct hpi_res_cobranet_hmiread hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
- HPI_CONTROL_GET_STATE);
- if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
+ hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr.h, sizeof(hr),
+ HPI_OBJ_CONTROL, HPI_CONTROL_GET_STATE);
+
+ if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
+ &hm.h.obj_index))
return HPI_ERROR_INVALID_HANDLE;
- hm.u.cx.u.cobranet_data.byte_count = max_byte_count;
- hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
+ if (max_byte_count > sizeof(hr.bytes))
+ return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
- if (max_byte_count <= 8) {
- hm.u.cx.attribute = HPI_COBRANET_GET;
- } else {
- hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
- hm.u.cx.attribute = HPI_COBRANET_GET_DATA;
- }
+ hm.p.attribute = HPI_COBRANET_GET;
+ hm.p.byte_count = max_byte_count;
+ hm.p.hmi_address = hmi_address;
- hpi_send_recv(&hm, &hr);
- if (!hr.error && pb_data) {
+ hpi_send_recvV1(&hm.h, &hr.h);
- *pbyte_count = hr.u.cx.u.cobranet_data.byte_count;
+ if (!hr.h.error && pb_data) {
+ if (hr.byte_count > sizeof(hr.bytes))
- if (*pbyte_count < max_byte_count)
- max_byte_count = *pbyte_count;
+ return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
- if (hm.u.cx.attribute == HPI_COBRANET_GET) {
- memcpy(pb_data, hr.u.cx.u.cobranet_data.data,
- max_byte_count);
- } else {
+ *pbyte_count = hr.byte_count;
- }
+ if (hr.byte_count < max_byte_count)
+ max_byte_count = *pbyte_count;
+ memcpy(pb_data, hr.bytes, max_byte_count);
}
- return hr.error;
+ return hr.h.error;
}
u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
@@ -1733,23 +1729,23 @@ u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
struct hpi_message hm;
struct hpi_response hr;
- hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
+ hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
return HPI_ERROR_INVALID_HANDLE;
- hm.u.cx.attribute = HPI_COBRANET_GET_STATUS;
+ hm.u.c.attribute = HPI_COBRANET_GET_STATUS;
hpi_send_recv(&hm, &hr);
if (!hr.error) {
if (pstatus)
- *pstatus = hr.u.cx.u.cobranet_status.status;
+ *pstatus = hr.u.cu.cobranet.status.status;
if (preadable_size)
*preadable_size =
- hr.u.cx.u.cobranet_status.readable_size;
+ hr.u.cu.cobranet.status.readable_size;
if (pwriteable_size)
*pwriteable_size =
- hr.u.cx.u.cobranet_status.writeable_size;
+ hr.u.cu.cobranet.status.writeable_size;
}
return hr.error;
}
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
index 628376ce4a49..52400a6b5f15 100644
--- a/sound/pci/asihpi/hpimsginit.c
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -46,7 +46,7 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
if (gwSSX2_bypass)
phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
else
- phm->type = HPI_TYPE_MESSAGE;
+ phm->type = HPI_TYPE_REQUEST;
phm->object = object;
phm->function = function;
phm->version = 0;
@@ -89,7 +89,7 @@ static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
memset(phm, 0, sizeof(*phm));
if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
phm->size = size;
- phm->type = HPI_TYPE_MESSAGE;
+ phm->type = HPI_TYPE_REQUEST;
phm->object = object;
phm->function = function;
phm->version = 1;
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index 7352a5f7b4f7..2e779421a618 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-Extended Message Function With Response Cacheing
+Extended Message Function With Response Caching
(C) Copyright AudioScience Inc. 2002
*****************************************************************************/
@@ -186,7 +186,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
/* Initialize this module's internal state */
hpios_msgxlock_init(&msgx_lock);
memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
- hpios_locked_mem_init();
/* Init subsys_findadapters response to no-adapters */
HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
@@ -197,7 +196,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
case HPI_SUBSYS_DRIVER_UNLOAD:
HPI_COMMON(phm, phr);
HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
- hpios_locked_mem_free_all();
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_DRIVER_UNLOAD, 0);
return;
@@ -315,7 +313,7 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
{
HPI_DEBUG_MESSAGE(DEBUG, phm);
- if (phm->type != HPI_TYPE_MESSAGE) {
+ if (phm->type != HPI_TYPE_REQUEST) {
hpi_init_response(phr, phm->object, phm->function,
HPI_ERROR_INVALID_TYPE);
return;
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index d8e7047512f8..65fcf4770731 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -1,7 +1,7 @@
/*******************************************************************************
AudioScience HPI driver
- Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
+ Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
@@ -157,11 +157,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
goto out;
}
- if (hm->h.adapter_index >= HPI_MAX_ADAPTERS) {
- err = -EINVAL;
- goto out;
- }
-
switch (hm->h.function) {
case HPI_SUBSYS_CREATE_ADAPTER:
case HPI_ADAPTER_DELETE:
@@ -187,7 +182,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
/* -1=no data 0=read from user mem, 1=write to user mem */
int wrflag = -1;
u32 adapter = hm->h.adapter_index;
- pa = &adapters[adapter];
if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
@@ -203,6 +197,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
goto out;
}
+ pa = &adapters[adapter];
+
if (mutex_lock_interruptible(&adapters[adapter].mutex)) {
err = -EINTR;
goto out;
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c
index 742ee12a9e17..ff2a19b544fa 100644
--- a/sound/pci/asihpi/hpios.c
+++ b/sound/pci/asihpi/hpios.c
@@ -39,10 +39,6 @@ void hpios_delay_micro_seconds(u32 num_micro_sec)
}
-void hpios_locked_mem_init(void)
-{
-}
-
/** Allocated an area of locked memory for bus master DMA operations.
On error, return -ENOMEM, and *pMemArea.size = 0
@@ -85,7 +81,3 @@ u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
return 1;
}
}
-
-void hpios_locked_mem_free_all(void)
-{
-}
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
index 03273e729f99..2f605e34bad0 100644
--- a/sound/pci/asihpi/hpios.h
+++ b/sound/pci/asihpi/hpios.h
@@ -38,6 +38,7 @@ HPI Operating System Specific macros for Linux Kernel driver
#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
+#include <linux/mutex.h>
#define HPI_NO_OS_FILE_OPS
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 3119cd97a217..537e0a2cc68a 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1624,7 +1624,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
}
if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
- card->shortname, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_atiixp_free(chip);
return -EBUSY;
@@ -1701,7 +1701,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "ATI IXP AC97 controller",
+ .name = KBUILD_MODNAME,
.id_table = snd_atiixp_ids,
.probe = snd_atiixp_probe,
.remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 2f74c2fdf1ea..45df275c8248 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1260,7 +1260,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
}
if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
- card->shortname, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_atiixp_free(chip);
return -EBUSY;
@@ -1332,7 +1332,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "ATI IXP MC97 controller",
+ .name = KBUILD_MODNAME,
.id_table = snd_atiixp_ids,
.probe = snd_atiixp_probe,
.remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 7b72c88e449d..a38469986885 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -196,7 +196,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
}
if ((err = request_irq(pci->irq, vortex_interrupt,
- IRQF_SHARED, CARD_NAME_SHORT,
+ IRQF_SHARED, KBUILD_MODNAME,
chip)) != 0) {
printk(KERN_ERR "cannot grab irq\n");
goto irq_out;
@@ -375,7 +375,7 @@ static void __devexit snd_vortex_remove(struct pci_dev *pci)
// pci_driver definition
static struct pci_driver driver = {
- .name = CARD_NAME_SHORT,
+ .name = KBUILD_MODNAME,
.id_table = snd_vortex_ids,
.probe = snd_vortex_probe,
.remove = __devexit_p(snd_vortex_remove),
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index c15002242d98..f8569b11331b 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -171,7 +171,7 @@ MODULE_DEVICE_TABLE(pci, snd_aw2_ids);
/* pci_driver definition */
static struct pci_driver driver = {
- .name = "Emagic Audiowerk 2",
+ .name = KBUILD_MODNAME,
.id_table = snd_aw2_ids,
.probe = snd_aw2_probe,
.remove = __devexit_p(snd_aw2_remove),
@@ -317,7 +317,7 @@ static int __devinit snd_aw2_create(struct snd_card *card,
snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
- IRQF_SHARED, "Audiowerk2", chip)) {
+ IRQF_SHARED, KBUILD_MODNAME, chip)) {
printk(KERN_ERR "aw2: Cannot grab irq %d\n", pci->irq);
iounmap(chip->iobase_virt);
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 9b7a6346037a..e4d76a270c9f 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2559,7 +2559,7 @@ snd_azf3328_create(struct snd_card *card,
codec_setup->name = "I2S_OUT";
if (request_irq(pci->irq, snd_azf3328_interrupt,
- IRQF_SHARED, card->shortname, chip)) {
+ IRQF_SHARED, KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
err = -EBUSY;
goto out_err;
@@ -2860,7 +2860,7 @@ snd_azf3328_resume(struct pci_dev *pci)
static struct pci_driver driver = {
- .name = "AZF3328",
+ .name = KBUILD_MODNAME,
.id_table = snd_azf3328_ids,
.probe = snd_azf3328_probe,
.remove = __devexit_p(snd_azf3328_remove),
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 2958a05b5293..39180335c237 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -760,7 +760,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
- "Bt87x audio", chip);
+ KBUILD_MODNAME, chip);
if (err < 0) {
snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
goto fail;
@@ -965,7 +965,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = {
};
static struct pci_driver driver = {
- .name = "Bt87x",
+ .name = KBUILD_MODNAME,
.id_table = snd_bt87x_ids,
.probe = snd_bt87x_probe,
.remove = __devexit_p(snd_bt87x_remove),
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 437759239694..061b7e654586 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1666,7 +1666,7 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
}
if (request_irq(pci->irq, snd_ca0106_interrupt,
- IRQF_SHARED, "snd_ca0106", chip)) {
+ IRQF_SHARED, KBUILD_MODNAME, chip)) {
snd_ca0106_free(chip);
printk(KERN_ERR "cannot grab irq\n");
return -EBUSY;
@@ -1933,7 +1933,7 @@ MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
// pci_driver definition
static struct pci_driver driver = {
- .name = "CA0106",
+ .name = KBUILD_MODNAME,
.id_table = snd_ca0106_ids,
.probe = snd_ca0106_probe,
.remove = __devexit_p(snd_ca0106_remove),
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index f4e573555da3..9cf99fb7eb9c 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3053,7 +3053,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
cm->iobase = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_cmipci_interrupt,
- IRQF_SHARED, card->driver, cm)) {
+ IRQF_SHARED, KBUILD_MODNAME, cm)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cmipci_free(cm);
return -EBUSY;
@@ -3398,7 +3398,7 @@ static int snd_cmipci_resume(struct pci_dev *pci)
#endif /* CONFIG_PM */
static struct pci_driver driver = {
- .name = "C-Media PCI",
+ .name = KBUILD_MODNAME,
.id_table = snd_cmipci_ids,
.probe = snd_cmipci_probe,
.remove = __devexit_p(snd_cmipci_remove),
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 6772070ed492..07f04e390aa1 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1382,7 +1382,7 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
}
if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED,
- "CS4281", chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cs4281_free(chip);
return -ENOMEM;
@@ -2085,7 +2085,7 @@ static int cs4281_resume(struct pci_dev *pci)
#endif /* CONFIG_PM */
static struct pci_driver driver = {
- .name = "CS4281",
+ .name = KBUILD_MODNAME,
.id_table = snd_cs4281_ids,
.probe = snd_cs4281_probe,
.remove = __devexit_p(snd_cs4281_remove),
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 767fa7f06cd0..1af95559aaaa 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -162,7 +162,7 @@ static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "Sound Fusion CS46xx",
+ .name = KBUILD_MODNAME,
.id_table = snd_cs46xx_ids,
.probe = snd_card_cs46xx_probe,
.remove = __devexit_p(snd_card_cs46xx_remove),
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index aad37082cb6e..9546bf07f0d1 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -3835,7 +3835,7 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
}
if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
- "CS46XX", chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cs46xx_free(chip);
return -EBUSY;
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index bc07e275d4d4..a4669346d146 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -285,7 +285,7 @@ static int __devinit snd_cs5530_probe(struct pci_dev *pci,
}
static struct pci_driver driver = {
- .name = "CS5530_Audio",
+ .name = KBUILD_MODNAME,
.id_table = snd_cs5530_ids,
.probe = snd_cs5530_probe,
.remove = __devexit_p(snd_cs5530_remove),
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index afb803708416..10d22ed5fece 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -311,7 +311,7 @@ static int __devinit snd_cs5535audio_create(struct snd_card *card,
cs5535au->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_cs5535audio_interrupt,
- IRQF_SHARED, "CS5535 Audio", cs5535au)) {
+ IRQF_SHARED, KBUILD_MODNAME, cs5535au)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
err = -EBUSY;
goto sndfail;
@@ -395,7 +395,7 @@ static void __devexit snd_cs5535audio_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = DRIVER_NAME,
+ .name = KBUILD_MODNAME,
.id_table = snd_cs5535audio_ids,
.probe = snd_cs5535audio_probe,
.remove = __devexit_p(snd_cs5535audio_remove),
diff --git a/sound/pci/ctxfi/ct20k2reg.h b/sound/pci/ctxfi/ct20k2reg.h
index e0394e3996e8..ca501ba03d64 100644
--- a/sound/pci/ctxfi/ct20k2reg.h
+++ b/sound/pci/ctxfi/ct20k2reg.h
@@ -55,6 +55,7 @@
/* GPIO Registers */
#define GPIO_DATA 0x1B7020
#define GPIO_CTRL 0x1B7024
+#define GPIO_EXT_DATA 0x1B70A0
/* Virtual memory registers */
#define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 13f33c0719d3..d8a4423539ce 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -18,7 +18,6 @@
#include "ctatc.h"
#include "ctpcm.h"
#include "ctmixer.h"
-#include "cthardware.h"
#include "ctsrc.h"
#include "ctamixer.h"
#include "ctdaio.h"
@@ -30,7 +29,6 @@
#include <sound/asoundef.h>
#define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */
-#define DAIONUM 7
#define MAX_MULTI_CHN 8
#define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \
@@ -53,6 +51,8 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
"SB0760", CTSB0760),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB1270,
+ "SB1270", CTSB1270),
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801,
"SB0880", CTSB0880),
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802,
@@ -75,6 +75,7 @@ static const char *ct_subsys_name[NUM_CTCARDS] = {
[CTSB0760] = "SB076x",
[CTHENDRIX] = "Hendrix",
[CTSB0880] = "SB0880",
+ [CTSB1270] = "SB1270",
[CT20K2_UNKNOWN] = "Unknown",
};
@@ -459,12 +460,12 @@ static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm,
apcm->substream->runtime->rate);
*n_srcc = 0;
- if (1 == atc->msr) {
+ if (1 == atc->msr) { /* FIXME: do we really need SRC here if pitch==1 */
*n_srcc = apcm->substream->runtime->channels;
conf[0].pitch = pitch;
conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1;
conf[0].vo = 1;
- } else if (2 == atc->msr) {
+ } else if (2 <= atc->msr) {
if (0x8000000 < pitch) {
/* Need two-stage SRCs, SRCIMPs and
* AMIXERs for converting format */
@@ -970,11 +971,39 @@ static int atc_select_mic_in(struct ct_atc *atc)
return 0;
}
-static int atc_have_digit_io_switch(struct ct_atc *atc)
+static struct capabilities atc_capabilities(struct ct_atc *atc)
{
struct hw *hw = atc->hw;
- return hw->have_digit_io_switch(hw);
+ return hw->capabilities(hw);
+}
+
+static int atc_output_switch_get(struct ct_atc *atc)
+{
+ struct hw *hw = atc->hw;
+
+ return hw->output_switch_get(hw);
+}
+
+static int atc_output_switch_put(struct ct_atc *atc, int position)
+{
+ struct hw *hw = atc->hw;
+
+ return hw->output_switch_put(hw, position);
+}
+
+static int atc_mic_source_switch_get(struct ct_atc *atc)
+{
+ struct hw *hw = atc->hw;
+
+ return hw->mic_source_switch_get(hw);
+}
+
+static int atc_mic_source_switch_put(struct ct_atc *atc, int position)
+{
+ struct hw *hw = atc->hw;
+
+ return hw->mic_source_switch_put(hw, position);
}
static int atc_select_digit_io(struct ct_atc *atc)
@@ -1045,6 +1074,11 @@ static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
return atc_daio_unmute(atc, state, LINEIM);
}
+static int atc_mic_unmute(struct ct_atc *atc, unsigned char state)
+{
+ return atc_daio_unmute(atc, state, MIC);
+}
+
static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state)
{
return atc_daio_unmute(atc, state, SPDIFOO);
@@ -1331,17 +1365,20 @@ static int atc_get_resources(struct ct_atc *atc)
struct srcimp_mgr *srcimp_mgr;
struct sum_desc sum_dsc = {0};
struct sum_mgr *sum_mgr;
- int err, i;
+ int err, i, num_srcs, num_daios;
- atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL);
+ num_daios = ((atc->model == CTSB1270) ? 8 : 7);
+ num_srcs = ((atc->model == CTSB1270) ? 6 : 4);
+
+ atc->daios = kzalloc(sizeof(void *)*num_daios, GFP_KERNEL);
if (!atc->daios)
return -ENOMEM;
- atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
+ atc->srcs = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
if (!atc->srcs)
return -ENOMEM;
- atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
+ atc->srcimps = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
if (!atc->srcimps)
return -ENOMEM;
@@ -1351,8 +1388,9 @@ static int atc_get_resources(struct ct_atc *atc)
daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
da_desc.msr = atc->msr;
- for (i = 0, atc->n_daio = 0; i < DAIONUM-1; i++) {
- da_desc.type = i;
+ for (i = 0, atc->n_daio = 0; i < num_daios; i++) {
+ da_desc.type = (atc->model != CTSB073X) ? i :
+ ((i == SPDIFIO) ? SPDIFI1 : i);
err = daio_mgr->get_daio(daio_mgr, &da_desc,
(struct daio **)&atc->daios[i]);
if (err) {
@@ -1362,23 +1400,12 @@ static int atc_get_resources(struct ct_atc *atc)
}
atc->n_daio++;
}
- if (atc->model == CTSB073X)
- da_desc.type = SPDIFI1;
- else
- da_desc.type = SPDIFIO;
- err = daio_mgr->get_daio(daio_mgr, &da_desc,
- (struct daio **)&atc->daios[i]);
- if (err) {
- printk(KERN_ERR "ctxfi: Failed to get S/PDIF-in resource!!!\n");
- return err;
- }
- atc->n_daio++;
src_mgr = atc->rsc_mgrs[SRC];
src_dsc.multi = 1;
src_dsc.msr = atc->msr;
src_dsc.mode = ARCRW;
- for (i = 0, atc->n_src = 0; i < (2*2); i++) {
+ for (i = 0, atc->n_src = 0; i < num_srcs; i++) {
err = src_mgr->get_src(src_mgr, &src_dsc,
(struct src **)&atc->srcs[i]);
if (err)
@@ -1388,8 +1415,8 @@ static int atc_get_resources(struct ct_atc *atc)
}
srcimp_mgr = atc->rsc_mgrs[SRCIMP];
- srcimp_dsc.msr = 8; /* SRCIMPs for S/PDIFIn SRT */
- for (i = 0, atc->n_srcimp = 0; i < (2*1); i++) {
+ srcimp_dsc.msr = 8;
+ for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) {
err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
(struct srcimp **)&atc->srcimps[i]);
if (err)
@@ -1397,15 +1424,6 @@ static int atc_get_resources(struct ct_atc *atc)
atc->n_srcimp++;
}
- srcimp_dsc.msr = 8; /* SRCIMPs for LINE/MICIn SRT */
- for (i = 0; i < (2*1); i++) {
- err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
- (struct srcimp **)&atc->srcimps[2*1+i]);
- if (err)
- return err;
-
- atc->n_srcimp++;
- }
sum_mgr = atc->rsc_mgrs[SUM];
sum_dsc.msr = atc->msr;
@@ -1488,6 +1506,18 @@ static void atc_connect_resources(struct ct_atc *atc)
src = atc->srcs[3];
mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
+ if (atc->model == CTSB1270) {
+ /* Titanium HD has a dedicated ADC for the Mic. */
+ dai = container_of(atc->daios[MIC], struct dai, daio);
+ atc_connect_dai(atc->rsc_mgrs[SRC], dai,
+ (struct src **)&atc->srcs[4],
+ (struct srcimp **)&atc->srcimps[4]);
+ src = atc->srcs[4];
+ mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc);
+ src = atc->srcs[5];
+ mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc);
+ }
+
dai = container_of(atc->daios[SPDIFIO], struct dai, daio);
atc_connect_dai(atc->rsc_mgrs[SRC], dai,
(struct src **)&atc->srcs[0],
@@ -1606,12 +1636,17 @@ static struct ct_atc atc_preset __devinitdata = {
.line_clfe_unmute = atc_line_clfe_unmute,
.line_rear_unmute = atc_line_rear_unmute,
.line_in_unmute = atc_line_in_unmute,
+ .mic_unmute = atc_mic_unmute,
.spdif_out_unmute = atc_spdif_out_unmute,
.spdif_in_unmute = atc_spdif_in_unmute,
.spdif_out_get_status = atc_spdif_out_get_status,
.spdif_out_set_status = atc_spdif_out_set_status,
.spdif_out_passthru = atc_spdif_out_passthru,
- .have_digit_io_switch = atc_have_digit_io_switch,
+ .capabilities = atc_capabilities,
+ .output_switch_get = atc_output_switch_get,
+ .output_switch_put = atc_output_switch_put,
+ .mic_source_switch_get = atc_mic_source_switch_get,
+ .mic_source_switch_put = atc_mic_source_switch_put,
#ifdef CONFIG_PM
.suspend = atc_suspend,
.resume = atc_resume,
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 7167c0185d52..3a0def656af0 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -25,6 +25,7 @@
#include <sound/core.h>
#include "ctvmem.h"
+#include "cthardware.h"
#include "ctresource.h"
enum CTALSADEVS { /* Types of alsa devices */
@@ -115,12 +116,17 @@ struct ct_atc {
int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state);
int (*line_in_unmute)(struct ct_atc *atc, unsigned char state);
+ int (*mic_unmute)(struct ct_atc *atc, unsigned char state);
int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state);
int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state);
int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
- int (*have_digit_io_switch)(struct ct_atc *atc);
+ struct capabilities (*capabilities)(struct ct_atc *atc);
+ int (*output_switch_get)(struct ct_atc *atc);
+ int (*output_switch_put)(struct ct_atc *atc, int position);
+ int (*mic_source_switch_get)(struct ct_atc *atc);
+ int (*mic_source_switch_put)(struct ct_atc *atc, int position);
/* Don't touch! Used for internal object. */
void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c
index 47d9ea97de02..0c00eb4088ef 100644
--- a/sound/pci/ctxfi/ctdaio.c
+++ b/sound/pci/ctxfi/ctdaio.c
@@ -22,20 +22,9 @@
#include <linux/slab.h>
#include <linux/kernel.h>
-#define DAIO_RESOURCE_NUM NUM_DAIOTYP
#define DAIO_OUT_MAX SPDIFOO
-union daio_usage {
- struct {
- unsigned short lineo1:1;
- unsigned short lineo2:1;
- unsigned short lineo3:1;
- unsigned short lineo4:1;
- unsigned short spdifoo:1;
- unsigned short lineim:1;
- unsigned short spdifio:1;
- unsigned short spdifi1:1;
- } bf;
+struct daio_usage {
unsigned short data;
};
@@ -61,6 +50,7 @@ struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
[LINEO3] = {.left = 0x50, .right = 0x51},
[LINEO4] = {.left = 0x70, .right = 0x71},
[LINEIM] = {.left = 0x45, .right = 0xc5},
+ [MIC] = {.left = 0x55, .right = 0xd5},
[SPDIFOO] = {.left = 0x00, .right = 0x01},
[SPDIFIO] = {.left = 0x05, .right = 0x85},
};
@@ -138,6 +128,7 @@ static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
case LINEO3: return 5;
case LINEO4: return 6;
case LINEIM: return 4;
+ case MIC: return 5;
default: return -EINVAL;
}
default:
@@ -519,17 +510,17 @@ static int dai_rsc_uninit(struct dai *dai)
static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
{
- if (((union daio_usage *)mgr->rscs)->data & (0x1 << type))
+ if (((struct daio_usage *)mgr->rscs)->data & (0x1 << type))
return -ENOENT;
- ((union daio_usage *)mgr->rscs)->data |= (0x1 << type);
+ ((struct daio_usage *)mgr->rscs)->data |= (0x1 << type);
return 0;
}
static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
{
- ((union daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
+ ((struct daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
return 0;
}
@@ -712,7 +703,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
if (!daio_mgr)
return -ENOMEM;
- err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw);
+ err = rsc_mgr_init(&daio_mgr->mgr, DAIO, NUM_DAIOTYP, hw);
if (err)
goto error1;
diff --git a/sound/pci/ctxfi/ctdaio.h b/sound/pci/ctxfi/ctdaio.h
index 0f52ce571ee8..85ccb6ee1ab4 100644
--- a/sound/pci/ctxfi/ctdaio.h
+++ b/sound/pci/ctxfi/ctdaio.h
@@ -33,6 +33,7 @@ enum DAIOTYP {
SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */
LINEIM,
SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */
+ MIC, /* Dedicated mic on Titanium HD */
SPDIFI1, /* S/PDIF In on internal Drive Bay */
NUM_DAIOTYP
};
diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h
index af55405f5dec..908315bec3b4 100644
--- a/sound/pci/ctxfi/cthardware.h
+++ b/sound/pci/ctxfi/cthardware.h
@@ -39,6 +39,7 @@ enum CTCARDS {
CT20K2_MODEL_FIRST = CTSB0760,
CTHENDRIX,
CTSB0880,
+ CTSB1270,
CT20K2_UNKNOWN,
NUM_CTCARDS /* This should always be the last */
};
@@ -60,6 +61,13 @@ struct card_conf {
unsigned int msr; /* master sample rate in rsrs */
};
+struct capabilities {
+ unsigned int digit_io_switch:1;
+ unsigned int dedicated_mic:1;
+ unsigned int output_switch:1;
+ unsigned int mic_source_switch:1;
+};
+
struct hw {
int (*card_init)(struct hw *hw, struct card_conf *info);
int (*card_stop)(struct hw *hw);
@@ -70,7 +78,11 @@ struct hw {
#endif
int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
- int (*have_digit_io_switch)(struct hw *hw);
+ struct capabilities (*capabilities)(struct hw *hw);
+ int (*output_switch_get)(struct hw *hw);
+ int (*output_switch_put)(struct hw *hw, int position);
+ int (*mic_source_switch_get)(struct hw *hw);
+ int (*mic_source_switch_put)(struct hw *hw, int position);
/* SRC operations */
int (*src_rsc_get_ctrl_blk)(void **rblk);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index a5c957db5cea..a7df19791f5a 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -1777,10 +1777,17 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
return adc_init_SBx(hw, info->input, info->mic20db);
}
-static int hw_have_digit_io_switch(struct hw *hw)
+static struct capabilities hw_capabilities(struct hw *hw)
{
+ struct capabilities cap;
+
/* SB073x and Vista compatible cards have no digit IO switch */
- return !(hw->model == CTSB073X || hw->model == CTUAA);
+ cap.digit_io_switch = !(hw->model == CTSB073X || hw->model == CTUAA);
+ cap.dedicated_mic = 0;
+ cap.output_switch = 0;
+ cap.mic_source_switch = 0;
+
+ return cap;
}
#define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
@@ -1933,7 +1940,7 @@ static int hw_card_start(struct hw *hw)
if (hw->irq < 0) {
err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
- "ctxfi", hw);
+ KBUILD_MODNAME, hw);
if (err < 0) {
printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
goto error2;
@@ -2172,7 +2179,7 @@ static struct hw ct20k1_preset __devinitdata = {
.pll_init = hw_pll_init,
.is_adc_source_selected = hw_is_adc_input_selected,
.select_adc_source = hw_adc_input_select,
- .have_digit_io_switch = hw_have_digit_io_switch,
+ .capabilities = hw_capabilities,
#ifdef CONFIG_PM
.suspend = hw_suspend,
.resume = hw_resume,
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index 5364164674e4..d6c54b524bfa 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -8,7 +8,7 @@
* @File cthw20k2.c
*
* @Brief
- * This file contains the implementation of hardware access methord for 20k2.
+ * This file contains the implementation of hardware access method for 20k2.
*
* @Author Liu Chun
* @Date May 14 2008
@@ -38,6 +38,8 @@ struct hw20k2 {
unsigned char dev_id;
unsigned char addr_size;
unsigned char data_size;
+
+ int mic_source;
};
static u32 hw_read_20kx(struct hw *hw, u32 reg);
@@ -1163,7 +1165,12 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101);
hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
} else if (2 == info->msr) {
- hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
+ if (hw->model != CTSB1270) {
+ hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
+ } else {
+ /* PCM4220 on Titanium HD is different. */
+ hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11011111);
+ }
/* Specify all playing 96khz
* EA [0] - Enabled
* RTA [4:5] - 96kHz
@@ -1175,6 +1182,10 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
* RTD [28:29] - 96kHz */
hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111);
hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
+ } else if ((4 == info->msr) && (hw->model == CTSB1270)) {
+ hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21011111);
+ hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121);
+ hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
} else {
printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n");
return -EINVAL;
@@ -1182,6 +1193,8 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
for (i = 0; i < 8; i++) {
if (i <= 3) {
+ /* This comment looks wrong since loop is over 4 */
+ /* channels and emu20k2 supports 4 spdif IOs. */
/* 1st 3 channels are SPDIFs (SB0960) */
if (i == 3)
data = 0x1001001;
@@ -1206,12 +1219,16 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B);
} else {
+ /* Again, loop is over 4 channels not 5. */
/* Next 5 channels are I2S (SB0960) */
data = 0x11;
hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data);
if (2 == info->msr) {
/* Four channels per sample period */
data |= 0x1000;
+ } else if (4 == info->msr) {
+ /* FIXME: check this against the chip spec */
+ data |= 0x2000;
}
hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data);
}
@@ -1299,21 +1316,18 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
pllenb = 0xB;
hw_write_20kx(hw, PLL_ENB, pllenb);
- pllctl = 0x20D00000;
- set_field(&pllctl, PLLCTL_FD, 16 - 4);
+ pllctl = 0x20C00000;
+ set_field(&pllctl, PLLCTL_B, 0);
+ set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4);
+ set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1);
hw_write_20kx(hw, PLL_CTL, pllctl);
mdelay(40);
+
pllctl = hw_read_20kx(hw, PLL_CTL);
- set_field(&pllctl, PLLCTL_B, 0);
- if (48000 == rsr) {
- set_field(&pllctl, PLLCTL_FD, 16 - 2);
- set_field(&pllctl, PLLCTL_RD, 1 - 1); /* 3000*16/1 = 48000 */
- } else { /* 44100 */
- set_field(&pllctl, PLLCTL_FD, 147 - 2);
- set_field(&pllctl, PLLCTL_RD, 10 - 1); /* 3000*147/10 = 44100 */
- }
+ set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2);
hw_write_20kx(hw, PLL_CTL, pllctl);
mdelay(40);
+
for (i = 0; i < 1000; i++) {
pllstat = hw_read_20kx(hw, PLL_STAT);
if (get_field(pllstat, PLLSTAT_PD))
@@ -1557,7 +1571,7 @@ static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
hw20k2_i2c_wait_data_ready(hw);
- /* Dummy write to trigger the write oprtation */
+ /* Dummy write to trigger the write operation */
hw_write_20kx(hw, I2C_IF_WDATA, 0);
hw20k2_i2c_wait_data_ready(hw);
@@ -1568,6 +1582,30 @@ static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
return 0;
}
+static void hw_dac_stop(struct hw *hw)
+{
+ u32 data;
+ data = hw_read_20kx(hw, GPIO_DATA);
+ data &= 0xFFFFFFFD;
+ hw_write_20kx(hw, GPIO_DATA, data);
+ mdelay(10);
+}
+
+static void hw_dac_start(struct hw *hw)
+{
+ u32 data;
+ data = hw_read_20kx(hw, GPIO_DATA);
+ data |= 0x2;
+ hw_write_20kx(hw, GPIO_DATA, data);
+ mdelay(50);
+}
+
+static void hw_dac_reset(struct hw *hw)
+{
+ hw_dac_stop(hw);
+ hw_dac_start(hw);
+}
+
static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
{
int err;
@@ -1594,6 +1632,21 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
0x00000000 /* Vol Control B4 */
};
+ if (hw->model == CTSB1270) {
+ hw_dac_stop(hw);
+ data = hw_read_20kx(hw, GPIO_DATA);
+ data &= ~0x0600;
+ if (1 == info->msr)
+ data |= 0x0000; /* Single Speed Mode 0-50kHz */
+ else if (2 == info->msr)
+ data |= 0x0200; /* Double Speed Mode 50-100kHz */
+ else
+ data |= 0x0600; /* Quad Speed Mode 100-200kHz */
+ hw_write_20kx(hw, GPIO_DATA, data);
+ hw_dac_start(hw);
+ return 0;
+ }
+
/* Set DAC reset bit as output */
data = hw_read_20kx(hw, GPIO_CTRL);
data |= 0x02;
@@ -1606,22 +1659,8 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
for (i = 0; i < 2; i++) {
/* Reset DAC twice just in-case the chip
* didn't initialized properly */
- data = hw_read_20kx(hw, GPIO_DATA);
- /* GPIO data bit 1 */
- data &= 0xFFFFFFFD;
- hw_write_20kx(hw, GPIO_DATA, data);
- mdelay(10);
- data |= 0x2;
- hw_write_20kx(hw, GPIO_DATA, data);
- mdelay(50);
-
- /* Reset the 2nd time */
- data &= 0xFFFFFFFD;
- hw_write_20kx(hw, GPIO_DATA, data);
- mdelay(10);
- data |= 0x2;
- hw_write_20kx(hw, GPIO_DATA, data);
- mdelay(50);
+ hw_dac_reset(hw);
+ hw_dac_reset(hw);
if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1))
continue;
@@ -1725,7 +1764,11 @@ End:
static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
{
u32 data;
-
+ if (hw->model == CTSB1270) {
+ /* Titanium HD has two ADC chips, one for line in and one */
+ /* for MIC. We don't need to switch the ADC input. */
+ return 1;
+ }
data = hw_read_20kx(hw, GPIO_DATA);
switch (type) {
case ADC_MICIN:
@@ -1742,35 +1785,47 @@ static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
#define MIC_BOOST_0DB 0xCF
#define MIC_BOOST_STEPS_PER_DB 2
-#define MIC_BOOST_20DB (MIC_BOOST_0DB + 20 * MIC_BOOST_STEPS_PER_DB)
+
+static void hw_wm8775_input_select(struct hw *hw, u8 input, s8 gain_in_db)
+{
+ u32 adcmc, gain;
+
+ if (input > 3)
+ input = 3;
+
+ adcmc = ((u32)1 << input) | 0x100; /* Link L+R gain... */
+
+ hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, adcmc),
+ MAKE_WM8775_DATA(adcmc));
+
+ if (gain_in_db < -103)
+ gain_in_db = -103;
+ if (gain_in_db > 24)
+ gain_in_db = 24;
+
+ gain = gain_in_db * MIC_BOOST_STEPS_PER_DB + MIC_BOOST_0DB;
+
+ hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, gain),
+ MAKE_WM8775_DATA(gain));
+ /* ...so there should be no need for the following. */
+ hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, gain),
+ MAKE_WM8775_DATA(gain));
+}
static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
{
u32 data;
-
data = hw_read_20kx(hw, GPIO_DATA);
switch (type) {
case ADC_MICIN:
data |= (0x1 << 14);
hw_write_20kx(hw, GPIO_DATA, data);
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
- MAKE_WM8775_DATA(0x101)); /* Mic-in */
- hw20k2_i2c_write(hw,
- MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
- MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
- hw20k2_i2c_write(hw,
- MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
- MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
+ hw_wm8775_input_select(hw, 0, 20); /* Mic, 20dB */
break;
case ADC_LINEIN:
data &= ~(0x1 << 14);
hw_write_20kx(hw, GPIO_DATA, data);
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
- MAKE_WM8775_DATA(0x102)); /* Line-in */
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
- MAKE_WM8775_DATA(0xCF)); /* No boost */
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
- MAKE_WM8775_DATA(0xCF)); /* No boost */
+ hw_wm8775_input_select(hw, 1, 0); /* Line-in, 0dB */
break;
default:
break;
@@ -1782,7 +1837,7 @@ static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
{
int err;
- u32 mux = 2, data, ctl;
+ u32 data, ctl;
/* Set ADC reset bit as output */
data = hw_read_20kx(hw, GPIO_CTRL);
@@ -1796,19 +1851,42 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
goto error;
}
- /* Make ADC in normal operation */
+ /* Reset the ADC (reset is active low). */
data = hw_read_20kx(hw, GPIO_DATA);
data &= ~(0x1 << 15);
+ hw_write_20kx(hw, GPIO_DATA, data);
+
+ if (hw->model == CTSB1270) {
+ /* Set up the PCM4220 ADC on Titanium HD */
+ data &= ~0x0C;
+ if (1 == info->msr)
+ data |= 0x00; /* Single Speed Mode 32-50kHz */
+ else if (2 == info->msr)
+ data |= 0x08; /* Double Speed Mode 50-108kHz */
+ else
+ data |= 0x04; /* Quad Speed Mode 108kHz-216kHz */
+ hw_write_20kx(hw, GPIO_DATA, data);
+ }
+
mdelay(10);
+ /* Return the ADC to normal operation. */
data |= (0x1 << 15);
hw_write_20kx(hw, GPIO_DATA, data);
mdelay(50);
+ /* I2C write to register offset 0x0B to set ADC LRCLK polarity */
+ /* invert bit, interface format to I2S, word length to 24-bit, */
+ /* enable ADC high pass filter. Fixes bug 5323? */
+ hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_IC, 0x26),
+ MAKE_WM8775_DATA(0x26));
+
/* Set the master mode (256fs) */
if (1 == info->msr) {
+ /* slave mode, 128x oversampling 256fs */
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02),
MAKE_WM8775_DATA(0x02));
- } else if (2 == info->msr) {
+ } else if ((2 == info->msr) || (4 == info->msr)) {
+ /* slave mode, 64x oversampling, 256fs */
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A),
MAKE_WM8775_DATA(0x0A));
} else {
@@ -1818,55 +1896,113 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
goto error;
}
- /* Configure GPIO bit 14 change to line-in/mic-in */
- ctl = hw_read_20kx(hw, GPIO_CTRL);
- ctl |= 0x1 << 14;
- hw_write_20kx(hw, GPIO_CTRL, ctl);
-
- /* Check using Mic-in or Line-in */
- data = hw_read_20kx(hw, GPIO_DATA);
-
- if (mux == 1) {
- /* Configures GPIO data to select Mic-in */
- data |= 0x1 << 14;
- hw_write_20kx(hw, GPIO_DATA, data);
-
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
- MAKE_WM8775_DATA(0x101)); /* Mic-in */
- hw20k2_i2c_write(hw,
- MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
- MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
- hw20k2_i2c_write(hw,
- MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
- MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
- } else if (mux == 2) {
- /* Configures GPIO data to select Line-in */
- data &= ~(0x1 << 14);
- hw_write_20kx(hw, GPIO_DATA, data);
-
- /* Setup ADC */
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
- MAKE_WM8775_DATA(0x102)); /* Line-in */
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
- MAKE_WM8775_DATA(0xCF)); /* No boost */
- hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
- MAKE_WM8775_DATA(0xCF)); /* No boost */
+ if (hw->model != CTSB1270) {
+ /* Configure GPIO bit 14 change to line-in/mic-in */
+ ctl = hw_read_20kx(hw, GPIO_CTRL);
+ ctl |= 0x1 << 14;
+ hw_write_20kx(hw, GPIO_CTRL, ctl);
+ hw_adc_input_select(hw, ADC_LINEIN);
} else {
- printk(KERN_ALERT "ctxfi: ERROR!!! Invalid input mux!!!\n");
- err = -EINVAL;
- goto error;
+ hw_wm8775_input_select(hw, 0, 0);
}
return 0;
-
error:
hw20k2_i2c_uninit(hw);
return err;
}
-static int hw_have_digit_io_switch(struct hw *hw)
+static struct capabilities hw_capabilities(struct hw *hw)
{
- return 0;
+ struct capabilities cap;
+
+ cap.digit_io_switch = 0;
+ cap.dedicated_mic = hw->model == CTSB1270;
+ cap.output_switch = hw->model == CTSB1270;
+ cap.mic_source_switch = hw->model == CTSB1270;
+
+ return cap;
+}
+
+static int hw_output_switch_get(struct hw *hw)
+{
+ u32 data = hw_read_20kx(hw, GPIO_EXT_DATA);
+
+ switch (data & 0x30) {
+ case 0x00:
+ return 0;
+ case 0x10:
+ return 1;
+ case 0x20:
+ return 2;
+ default:
+ return 3;
+ }
+}
+
+static int hw_output_switch_put(struct hw *hw, int position)
+{
+ u32 data;
+
+ if (position == hw_output_switch_get(hw))
+ return 0;
+
+ /* Mute line and headphones (intended for anti-pop). */
+ data = hw_read_20kx(hw, GPIO_DATA);
+ data |= (0x03 << 11);
+ hw_write_20kx(hw, GPIO_DATA, data);
+
+ data = hw_read_20kx(hw, GPIO_EXT_DATA) & ~0x30;
+ switch (position) {
+ case 0:
+ break;
+ case 1:
+ data |= 0x10;
+ break;
+ default:
+ data |= 0x20;
+ }
+ hw_write_20kx(hw, GPIO_EXT_DATA, data);
+
+ /* Unmute line and headphones. */
+ data = hw_read_20kx(hw, GPIO_DATA);
+ data &= ~(0x03 << 11);
+ hw_write_20kx(hw, GPIO_DATA, data);
+
+ return 1;
+}
+
+static int hw_mic_source_switch_get(struct hw *hw)
+{
+ struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
+
+ return hw20k2->mic_source;
+}
+
+static int hw_mic_source_switch_put(struct hw *hw, int position)
+{
+ struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
+
+ if (position == hw20k2->mic_source)
+ return 0;
+
+ switch (position) {
+ case 0:
+ hw_wm8775_input_select(hw, 0, 0); /* Mic, 0dB */
+ break;
+ case 1:
+ hw_wm8775_input_select(hw, 1, 0); /* FP Mic, 0dB */
+ break;
+ case 2:
+ hw_wm8775_input_select(hw, 3, 0); /* Aux Ext, 0dB */
+ break;
+ default:
+ return 0;
+ }
+
+ hw20k2->mic_source = position;
+
+ return 1;
}
static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
@@ -1925,7 +2061,7 @@ static int hw_card_start(struct hw *hw)
if (hw->irq < 0) {
err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
- "ctxfi", hw);
+ KBUILD_MODNAME, hw);
if (err < 0) {
printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
goto error2;
@@ -2023,13 +2159,16 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
/* Reset all SRC pending interrupts */
hw_write_20kx(hw, SRC_IP, 0);
- /* TODO: detect the card ID and configure GPIO accordingly. */
- /* Configures GPIO (0xD802 0x98028) */
- /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/
- /* Configures GPIO (SB0880) */
- /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/
- hw_write_20kx(hw, GPIO_CTRL, 0xD802);
-
+ if (hw->model != CTSB1270) {
+ /* TODO: detect the card ID and configure GPIO accordingly. */
+ /* Configures GPIO (0xD802 0x98028) */
+ /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/
+ /* Configures GPIO (SB0880) */
+ /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/
+ hw_write_20kx(hw, GPIO_CTRL, 0xD802);
+ } else {
+ hw_write_20kx(hw, GPIO_CTRL, 0x9E5F);
+ }
/* Enable audio ring */
hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01);
@@ -2106,7 +2245,11 @@ static struct hw ct20k2_preset __devinitdata = {
.pll_init = hw_pll_init,
.is_adc_source_selected = hw_is_adc_input_selected,
.select_adc_source = hw_adc_input_select,
- .have_digit_io_switch = hw_have_digit_io_switch,
+ .capabilities = hw_capabilities,
+ .output_switch_get = hw_output_switch_get,
+ .output_switch_put = hw_output_switch_put,
+ .mic_source_switch_get = hw_mic_source_switch_get,
+ .mic_source_switch_put = hw_mic_source_switch_put,
#ifdef CONFIG_PM
.suspend = hw_suspend,
.resume = hw_resume,
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
index c3519ff42fbb..0cc13eeef8da 100644
--- a/sound/pci/ctxfi/ctmixer.c
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -86,9 +86,7 @@ enum CTALSA_MIXER_CTL {
MIXER_LINEIN_C_S,
MIXER_MIC_C_S,
MIXER_SPDIFI_C_S,
- MIXER_LINEIN_P_S,
MIXER_SPDIFO_P_S,
- MIXER_SPDIFI_P_S,
MIXER_WAVEF_P_S,
MIXER_WAVER_P_S,
MIXER_WAVEC_P_S,
@@ -137,11 +135,11 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[MIXER_LINEIN_P] = {
.ctl = 1,
- .name = "Line-in Playback Volume",
+ .name = "Line Playback Volume",
},
[MIXER_LINEIN_C] = {
.ctl = 1,
- .name = "Line-in Capture Volume",
+ .name = "Line Capture Volume",
},
[MIXER_MIC_P] = {
.ctl = 1,
@@ -153,15 +151,15 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[MIXER_SPDIFI_P] = {
.ctl = 1,
- .name = "S/PDIF-in Playback Volume",
+ .name = "IEC958 Playback Volume",
},
[MIXER_SPDIFI_C] = {
.ctl = 1,
- .name = "S/PDIF-in Capture Volume",
+ .name = "IEC958 Capture Volume",
},
[MIXER_SPDIFO_P] = {
.ctl = 1,
- .name = "S/PDIF-out Playback Volume",
+ .name = "Digital Playback Volume",
},
[MIXER_WAVEF_P] = {
.ctl = 1,
@@ -179,14 +177,13 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
.ctl = 1,
.name = "Surround Playback Volume",
},
-
[MIXER_PCM_C_S] = {
.ctl = 1,
.name = "PCM Capture Switch",
},
[MIXER_LINEIN_C_S] = {
.ctl = 1,
- .name = "Line-in Capture Switch",
+ .name = "Line Capture Switch",
},
[MIXER_MIC_C_S] = {
.ctl = 1,
@@ -194,19 +191,11 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[MIXER_SPDIFI_C_S] = {
.ctl = 1,
- .name = "S/PDIF-in Capture Switch",
- },
- [MIXER_LINEIN_P_S] = {
- .ctl = 1,
- .name = "Line-in Playback Switch",
+ .name = "IEC958 Capture Switch",
},
[MIXER_SPDIFO_P_S] = {
.ctl = 1,
- .name = "S/PDIF-out Playback Switch",
- },
- [MIXER_SPDIFI_P_S] = {
- .ctl = 1,
- .name = "S/PDIF-in Playback Switch",
+ .name = "Digital Playback Switch",
},
[MIXER_WAVEF_P_S] = {
.ctl = 1,
@@ -236,6 +225,8 @@ ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
static void
ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
+/* FIXME: this static looks like it would fail if more than one card was */
+/* installed. */
static struct snd_kcontrol *kctls[2] = {NULL};
static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index)
@@ -420,6 +411,77 @@ static struct snd_kcontrol_new vol_ctl = {
.tlv = { .p = ct_vol_db_scale },
};
+static int output_switch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *info)
+{
+ static const char *const names[3] = {
+ "FP Headphones", "Headphones", "Speakers"
+ };
+
+ return snd_ctl_enum_info(info, 1, 3, names);
+}
+
+static int output_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
+ ucontrol->value.enumerated.item[0] = atc->output_switch_get(atc);
+ return 0;
+}
+
+static int output_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
+ if (ucontrol->value.enumerated.item[0] > 2)
+ return -EINVAL;
+ return atc->output_switch_put(atc, ucontrol->value.enumerated.item[0]);
+}
+
+static struct snd_kcontrol_new output_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Analog Output Playback Enum",
+ .info = output_switch_info,
+ .get = output_switch_get,
+ .put = output_switch_put,
+};
+
+static int mic_source_switch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *info)
+{
+ static const char *const names[3] = {
+ "Mic", "FP Mic", "Aux"
+ };
+
+ return snd_ctl_enum_info(info, 1, 3, names);
+}
+
+static int mic_source_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
+ ucontrol->value.enumerated.item[0] = atc->mic_source_switch_get(atc);
+ return 0;
+}
+
+static int mic_source_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
+ if (ucontrol->value.enumerated.item[0] > 2)
+ return -EINVAL;
+ return atc->mic_source_switch_put(atc,
+ ucontrol->value.enumerated.item[0]);
+}
+
+static struct snd_kcontrol_new mic_source_ctl = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mic Source Capture Enum",
+ .info = mic_source_switch_info,
+ .get = mic_source_switch_get,
+ .put = mic_source_switch_put,
+};
+
static void
do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type)
{
@@ -465,6 +527,7 @@ do_digit_io_switch(struct ct_atc *atc, int state)
static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
{
struct ct_mixer *mixer = atc->mixer;
+ struct capabilities cap = atc->capabilities(atc);
/* Do changes in mixer. */
if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
@@ -477,8 +540,17 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
}
}
/* Do changes out of mixer. */
- if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type))
- do_line_mic_switch(atc, type);
+ if (!cap.dedicated_mic &&
+ (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) {
+ if (state)
+ do_line_mic_switch(atc, type);
+ atc->line_in_unmute(atc, state);
+ } else if (cap.dedicated_mic && (MIXER_LINEIN_C_S == type))
+ atc->line_in_unmute(atc, state);
+ else if (cap.dedicated_mic && (MIXER_MIC_C_S == type))
+ atc->mic_unmute(atc, state);
+ else if (MIXER_SPDIFI_C_S == type)
+ atc->spdif_in_unmute(atc, state);
else if (MIXER_WAVEF_P_S == type)
atc->line_front_unmute(atc, state);
else if (MIXER_WAVES_P_S == type)
@@ -487,12 +559,8 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
atc->line_clfe_unmute(atc, state);
else if (MIXER_WAVER_P_S == type)
atc->line_rear_unmute(atc, state);
- else if (MIXER_LINEIN_P_S == type)
- atc->line_in_unmute(atc, state);
else if (MIXER_SPDIFO_P_S == type)
atc->spdif_out_unmute(atc, state);
- else if (MIXER_SPDIFI_P_S == type)
- atc->spdif_in_unmute(atc, state);
else if (MIXER_DIGITAL_IO_S == type)
do_digit_io_switch(atc, state);
@@ -671,6 +739,7 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
{
enum CTALSA_MIXER_CTL type;
struct ct_atc *atc = mixer->atc;
+ struct capabilities cap = atc->capabilities(atc);
int err;
/* Create snd kcontrol instances on demand */
@@ -684,8 +753,8 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
}
}
- ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl =
- atc->have_digit_io_switch(atc);
+ ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl = cap.digit_io_switch;
+
for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) {
if (ct_kcontrol_init_table[type].ctl) {
swh_ctl.name = ct_kcontrol_init_table[type].name;
@@ -708,6 +777,17 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
if (err)
return err;
+ if (cap.output_switch) {
+ err = ct_mixer_kcontrol_new(mixer, &output_ctl);
+ if (err)
+ return err;
+ }
+
+ if (cap.mic_source_switch) {
+ err = ct_mixer_kcontrol_new(mixer, &mic_source_ctl);
+ if (err)
+ return err;
+ }
atc->line_front_unmute(atc, 1);
set_switch_state(mixer, MIXER_WAVEF_P_S, 1);
atc->line_surround_unmute(atc, 0);
@@ -719,13 +799,12 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
atc->spdif_out_unmute(atc, 0);
set_switch_state(mixer, MIXER_SPDIFO_P_S, 0);
atc->line_in_unmute(atc, 0);
- set_switch_state(mixer, MIXER_LINEIN_P_S, 0);
+ if (cap.dedicated_mic)
+ atc->mic_unmute(atc, 0);
atc->spdif_in_unmute(atc, 0);
- set_switch_state(mixer, MIXER_SPDIFI_P_S, 0);
-
- set_switch_state(mixer, MIXER_PCM_C_S, 1);
- set_switch_state(mixer, MIXER_LINEIN_C_S, 1);
- set_switch_state(mixer, MIXER_SPDIFI_C_S, 1);
+ set_switch_state(mixer, MIXER_PCM_C_S, 0);
+ set_switch_state(mixer, MIXER_LINEIN_C_S, 0);
+ set_switch_state(mixer, MIXER_SPDIFI_C_S, 0);
return 0;
}
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index f42e7e1a1074..b259aa03a3a9 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -80,11 +80,11 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
"are 48000 and 44100, Value 48000 is assumed.\n");
reference_rate = 48000;
}
- if ((multiple != 1) && (multiple != 2)) {
+ if ((multiple != 1) && (multiple != 2) && (multiple != 4)) {
printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n",
multiple);
printk(KERN_ERR "ctxfi: The valid values for multiple are "
- "1 and 2, Value 2 is assumed.\n");
+ "1, 2 and 4, Value 2 is assumed.\n");
multiple = 2;
}
err = ct_atc_create(card, pci, reference_rate, multiple,
@@ -143,7 +143,7 @@ static int ct_card_resume(struct pci_dev *pci)
#endif
static struct pci_driver ct_driver = {
- .name = "SB-XFi",
+ .name = KBUILD_MODNAME,
.id_table = ct_pci_dev_ids,
.probe = ct_card_probe,
.remove = __devexit_p(ct_card_remove),
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 20763dd03fa0..d7306980d0f1 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -1995,7 +1995,7 @@ static __devinit int snd_echo_create(struct snd_card *card,
ioremap_nocache(chip->dsp_registers_phys, sz);
if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
- ECHOCARD_NAME, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_echo_free(chip);
snd_printk(KERN_ERR "cannot grab irq\n");
return -EBUSY;
@@ -2286,7 +2286,7 @@ static int snd_echo_resume(struct pci_dev *pci)
kfree(commpage_bak);
if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
- ECHOCARD_NAME, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_echo_free(chip);
snd_printk(KERN_ERR "cannot grab irq\n");
return -EBUSY;
@@ -2327,7 +2327,7 @@ static void __devexit snd_echo_remove(struct pci_dev *pci)
/* pci_driver definition */
static struct pci_driver driver = {
- .name = "Echoaudio " ECHOCARD_NAME,
+ .name = KBUILD_MODNAME,
.id_table = snd_echo_ids,
.probe = snd_echo_probe,
.remove = __devexit_p(snd_echo_remove),
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index aff8387c45cf..a9c45d2cdb13 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -264,7 +264,7 @@ static int snd_emu10k1_resume(struct pci_dev *pci)
#endif
static struct pci_driver driver = {
- .name = "EMU10K1_Audigy",
+ .name = KBUILD_MODNAME,
.id_table = snd_emu10k1_ids,
.probe = snd_card_emu10k1_probe,
.remove = __devexit_p(snd_card_emu10k1_remove),
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 15f0161ce4a2..fcd4935766b2 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1912,7 +1912,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
/* irq handler must be registered after I/O ports are activated */
if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED,
- "EMU10K1", emu)) {
+ KBUILD_MODNAME, emu)) {
err = -EBUSY;
goto error;
}
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 0c701e4ec8a5..d4fde1b4b093 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -925,7 +925,7 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card,
}
if (request_irq(pci->irq, snd_emu10k1x_interrupt,
- IRQF_SHARED, "EMU10K1X", chip)) {
+ IRQF_SHARED, KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
snd_emu10k1x_free(chip);
return -EBUSY;
@@ -1613,7 +1613,7 @@ MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
// pci_driver definition
static struct pci_driver driver = {
- .name = "EMU10K1X",
+ .name = KBUILD_MODNAME,
.id_table = snd_emu10k1x_ids,
.probe = snd_emu10k1x_probe,
.remove = __devexit_p(snd_emu10k1x_remove),
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 863eafea691f..f02e2f8d7122 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -2120,7 +2120,7 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
}
ensoniq->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED,
- "Ensoniq AudioPCI", ensoniq)) {
+ KBUILD_MODNAME, ensoniq)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ensoniq_free(ensoniq);
return -EBUSY;
@@ -2489,7 +2489,7 @@ static void __devexit snd_audiopci_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = DRIVER_NAME,
+ .name = KBUILD_MODNAME,
.id_table = snd_audiopci_ids,
.probe = snd_audiopci_probe,
.remove = __devexit_p(snd_audiopci_remove),
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 553b75217259..26a5a2f25d4b 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1514,7 +1514,7 @@ static int es1938_resume(struct pci_dev *pci)
}
if (request_irq(pci->irq, snd_es1938_interrupt,
- IRQF_SHARED, "ES1938", chip)) {
+ IRQF_SHARED, KBUILD_MODNAME, chip)) {
printk(KERN_ERR "es1938: unable to grab IRQ %d, "
"disabling device\n", pci->irq);
snd_card_disconnect(card);
@@ -1636,7 +1636,7 @@ static int __devinit snd_es1938_create(struct snd_card *card,
chip->mpu_port = pci_resource_start(pci, 3);
chip->game_port = pci_resource_start(pci, 4);
if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,
- "ES1938", chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_es1938_free(chip);
return -EBUSY;
@@ -1882,7 +1882,7 @@ static void __devexit snd_es1938_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "ESS ES1938 (Solo-1)",
+ .name = KBUILD_MODNAME,
.id_table = snd_es1938_ids,
.probe = snd_es1938_probe,
.remove = __devexit_p(snd_es1938_remove),
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ab0a6156a704..99ea9320c6b5 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -554,9 +554,8 @@ struct es1968 {
#else
struct snd_kcontrol *master_switch; /* for h/w volume control */
struct snd_kcontrol *master_volume;
- spinlock_t ac97_lock;
- struct tasklet_struct hwvol_tq;
#endif
+ struct work_struct hwvol_work;
#ifdef CONFIG_SND_ES1968_RADIO
struct snd_tea575x tea;
@@ -646,38 +645,23 @@ static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
{
struct es1968 *chip = ac97->private_data;
-#ifndef CONFIG_SND_ES1968_INPUT
- unsigned long flags;
-#endif
snd_es1968_ac97_wait(chip);
/* Write the bus */
-#ifndef CONFIG_SND_ES1968_INPUT
- spin_lock_irqsave(&chip->ac97_lock, flags);
-#endif
outw(val, chip->io_port + ESM_AC97_DATA);
/*msleep(1);*/
outb(reg, chip->io_port + ESM_AC97_INDEX);
/*msleep(1);*/
-#ifndef CONFIG_SND_ES1968_INPUT
- spin_unlock_irqrestore(&chip->ac97_lock, flags);
-#endif
}
static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{
u16 data = 0;
struct es1968 *chip = ac97->private_data;
-#ifndef CONFIG_SND_ES1968_INPUT
- unsigned long flags;
-#endif
snd_es1968_ac97_wait(chip);
-#ifndef CONFIG_SND_ES1968_INPUT
- spin_lock_irqsave(&chip->ac97_lock, flags);
-#endif
outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
/*msleep(1);*/
@@ -685,9 +669,6 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
data = inw(chip->io_port + ESM_AC97_DATA);
/*msleep(1);*/
}
-#ifndef CONFIG_SND_ES1968_INPUT
- spin_unlock_irqrestore(&chip->ac97_lock, flags);
-#endif
return data;
}
@@ -1904,13 +1885,10 @@ static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
(without wrap around) in response to volume button presses and then
generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
of a byte wide register. The meaning of bits 0 and 4 is unknown. */
-static void es1968_update_hw_volume(unsigned long private_data)
+static void es1968_update_hw_volume(struct work_struct *work)
{
- struct es1968 *chip = (struct es1968 *) private_data;
+ struct es1968 *chip = container_of(work, struct es1968, hwvol_work);
int x, val;
-#ifndef CONFIG_SND_ES1968_INPUT
- unsigned long flags;
-#endif
/* Figure out which volume control button was pushed,
based on differences from the default register
@@ -1929,18 +1907,11 @@ static void es1968_update_hw_volume(unsigned long private_data)
if (! chip->master_switch || ! chip->master_volume)
return;
- /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
- spin_lock_irqsave(&chip->ac97_lock, flags);
- val = chip->ac97->regs[AC97_MASTER];
+ val = snd_ac97_read(chip->ac97, AC97_MASTER);
switch (x) {
case 0x88:
/* mute */
val ^= 0x8000;
- chip->ac97->regs[AC97_MASTER] = val;
- outw(val, chip->io_port + ESM_AC97_DATA);
- outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_switch->id);
break;
case 0xaa:
/* volume up */
@@ -1948,11 +1919,6 @@ static void es1968_update_hw_volume(unsigned long private_data)
val--;
if ((val & 0x7f00) > 0)
val -= 0x0100;
- chip->ac97->regs[AC97_MASTER] = val;
- outw(val, chip->io_port + ESM_AC97_DATA);
- outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_volume->id);
break;
case 0x66:
/* volume down */
@@ -1960,14 +1926,11 @@ static void es1968_update_hw_volume(unsigned long private_data)
val++;
if ((val & 0x7f00) < 0x1f00)
val += 0x0100;
- chip->ac97->regs[AC97_MASTER] = val;
- outw(val, chip->io_port + ESM_AC97_DATA);
- outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_volume->id);
break;
}
- spin_unlock_irqrestore(&chip->ac97_lock, flags);
+ if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &chip->master_volume->id);
#else
if (!chip->input_dev)
return;
@@ -2013,11 +1976,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
if (event & ESM_HWVOL_IRQ)
-#ifdef CONFIG_SND_ES1968_INPUT
- es1968_update_hw_volume((unsigned long)chip);
-#else
- tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
-#endif
+ schedule_work(&chip->hwvol_work);
/* else ack 'em all, i imagine */
outb(0xFF, chip->io_port + 0x1A);
@@ -2426,6 +2385,7 @@ static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
return 0;
chip->in_suspend = 1;
+ cancel_work_sync(&chip->hwvol_work);
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(chip->pcm);
snd_ac97_suspend(chip->ac97);
@@ -2638,6 +2598,7 @@ static struct snd_tea575x_ops snd_es1968_tea_ops = {
static int snd_es1968_free(struct es1968 *chip)
{
+ cancel_work_sync(&chip->hwvol_work);
#ifdef CONFIG_SND_ES1968_INPUT
if (chip->input_dev)
input_unregister_device(chip->input_dev);
@@ -2728,10 +2689,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
INIT_LIST_HEAD(&chip->buf_list);
INIT_LIST_HEAD(&chip->substream_list);
mutex_init(&chip->memory_mutex);
-#ifndef CONFIG_SND_ES1968_INPUT
- spin_lock_init(&chip->ac97_lock);
- tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
-#endif
+ INIT_WORK(&chip->hwvol_work, es1968_update_hw_volume);
chip->card = card;
chip->pci = pci;
chip->irq = -1;
@@ -2746,7 +2704,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
}
chip->io_port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
- "ESS Maestro", chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_es1968_free(chip);
return -EBUSY;
@@ -2925,7 +2883,7 @@ static void __devexit snd_es1968_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "ES1968 (ESS Maestro)",
+ .name = KBUILD_MODNAME,
.id_table = snd_es1968_ids,
.probe = snd_es1968_probe,
.remove = __devexit_p(snd_es1968_remove),
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index a7ec7030cf87..f9123f09e83e 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1199,7 +1199,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
chip->port = pci_resource_start(pci, 0);
if ((tea575x_tuner & TUNER_ONLY) == 0) {
if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
- "FM801", chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
snd_fm801_free(chip);
return -EBUSY;
@@ -1394,7 +1394,7 @@ static int snd_fm801_resume(struct pci_dev *pci)
#endif
static struct pci_driver driver = {
- .name = "FM801",
+ .name = KBUILD_MODNAME,
.id_table = snd_fm801_ids,
.probe = snd_card_fm801_probe,
.remove = __devexit_p(snd_card_fm801_remove),
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 45b4a8d70e08..f26e487eca1c 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4957,17 +4957,15 @@ void *snd_array_new(struct snd_array *array)
{
if (array->used >= array->alloced) {
int num = array->alloced + array->alloc_align;
+ int size = (num + 1) * array->elem_size;
+ int oldsize = array->alloced * array->elem_size;
void *nlist;
if (snd_BUG_ON(num >= 4096))
return NULL;
- nlist = kcalloc(num + 1, array->elem_size, GFP_KERNEL);
+ nlist = krealloc(array->list, size, GFP_KERNEL);
if (!nlist)
return NULL;
- if (array->list) {
- memcpy(nlist, array->list,
- array->elem_size * array->alloced);
- kfree(array->list);
- }
+ memset(nlist + oldsize, 0, size - oldsize);
array->list = nlist;
array->alloced = num;
}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 486f6deb3eee..5cc3d07f715f 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2149,7 +2149,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
{
if (request_irq(chip->pci->irq, azx_interrupt,
chip->msi ? 0 : IRQF_SHARED,
- "hda_intel", chip)) {
+ KBUILD_MODNAME, chip)) {
printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
"disabling device\n", chip->pci->irq);
if (do_disconnect)
@@ -2908,7 +2908,7 @@ MODULE_DEVICE_TABLE(pci, azx_ids);
/* pci_driver definition */
static struct pci_driver driver = {
- .name = "HDA Intel",
+ .name = KBUILD_MODNAME,
.id_table = azx_ids,
.probe = azx_probe,
.remove = __devexit_p(azx_remove),
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index f4594d76b6ea..be06fb3e45a1 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2607,7 +2607,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
ice->profi_port = pci_resource_start(pci, 3);
if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED,
- "ICE1712", ice)) {
+ KBUILD_MODNAME, ice)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ice1712_free(ice);
return -EIO;
@@ -2802,7 +2802,7 @@ static void __devexit snd_ice1712_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "ICE1712",
+ .name = KBUILD_MODNAME,
.id_table = snd_ice1712_ids,
.probe = snd_ice1712_probe,
.remove = __devexit_p(snd_ice1712_remove),
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index c1498fa5545f..c2b7f8bc41e4 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2509,7 +2509,7 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
ice->profi_port = pci_resource_start(pci, 1);
if (request_irq(pci->irq, snd_vt1724_interrupt,
- IRQF_SHARED, "ICE1724", ice)) {
+ IRQF_SHARED, KBUILD_MODNAME, ice)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_vt1724_free(ice);
return -EIO;
@@ -2802,7 +2802,7 @@ static int snd_vt1724_resume(struct pci_dev *pci)
#endif
static struct pci_driver driver = {
- .name = "ICE1724",
+ .name = KBUILD_MODNAME,
.id_table = snd_vt1724_ids,
.probe = snd_vt1724_probe,
.remove = __devexit_p(snd_vt1724_remove),
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 6c896dbfd796..6a5b387b97fd 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1884,6 +1884,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
},
{
.subvendor = 0x1028,
+ .subdevice = 0x0189,
+ .name = "Dell Inspiron 9300",
+ .type = AC97_TUNE_HP_MUTE_LED
+ },
+ {
+ .subvendor = 0x1028,
.subdevice = 0x0191,
.name = "Dell Inspiron 8600",
.type = AC97_TUNE_HP_ONLY
@@ -2647,7 +2653,7 @@ static int intel8x0_resume(struct pci_dev *pci)
pci_set_master(pci);
snd_intel8x0_chip_init(chip, 0);
if (request_irq(pci->irq, snd_intel8x0_interrupt,
- IRQF_SHARED, card->shortname, chip)) {
+ IRQF_SHARED, KBUILD_MODNAME, chip)) {
printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
"disabling device\n", pci->irq);
snd_card_disconnect(card);
@@ -3106,7 +3112,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
/* request irq after initializaing int_sta_mask, etc */
if (request_irq(pci->irq, snd_intel8x0_interrupt,
- IRQF_SHARED, card->shortname, chip)) {
+ IRQF_SHARED, KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_intel8x0_free(chip);
return -EBUSY;
@@ -3266,7 +3272,7 @@ static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "Intel ICH",
+ .name = KBUILD_MODNAME,
.id_table = snd_intel8x0_ids,
.probe = snd_intel8x0_probe,
.remove = __devexit_p(snd_intel8x0_remove),
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index f3353b49c785..7c161645d865 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1047,7 +1047,7 @@ static int intel8x0m_resume(struct pci_dev *pci)
}
pci_set_master(pci);
if (request_irq(pci->irq, snd_intel8x0m_interrupt,
- IRQF_SHARED, card->shortname, chip)) {
+ IRQF_SHARED, KBUILD_MODNAME, chip)) {
printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
"disabling device\n", pci->irq);
snd_card_disconnect(card);
@@ -1174,7 +1174,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
port_inited:
if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
- card->shortname, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_intel8x0m_free(chip);
return -EBUSY;
@@ -1325,7 +1325,7 @@ static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "Intel ICH Modem",
+ .name = KBUILD_MODNAME,
.id_table = snd_intel8x0m_ids,
.probe = snd_intel8x0m_probe,
.remove = __devexit_p(snd_intel8x0m_remove),
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 6d795700be79..fc1d573cf306 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2241,7 +2241,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
err = request_irq(pci->irq, snd_korg1212_interrupt,
IRQF_SHARED,
- "korg1212", korg1212);
+ KBUILD_MODNAME, korg1212);
if (err) {
snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
@@ -2477,7 +2477,7 @@ static void __devexit snd_korg1212_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "korg1212",
+ .name = KBUILD_MODNAME,
.id_table = snd_korg1212_ids,
.probe = snd_korg1212_probe,
.remove = __devexit_p(snd_korg1212_remove),
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
index 2692e5ae5f2d..3e92e5b5ec3d 100644
--- a/sound/pci/lola/lola.c
+++ b/sound/pci/lola/lola.c
@@ -648,7 +648,7 @@ static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
goto errout;
if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
- DRVNAME, chip)) {
+ KBUILD_MODNAME, chip)) {
printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
err = -EBUSY;
goto errout;
@@ -771,7 +771,7 @@ MODULE_DEVICE_TABLE(pci, lola_ids);
/* pci_driver definition */
static struct pci_driver driver = {
- .name = DRVNAME,
+ .name = KBUILD_MODNAME,
.id_table = lola_ids,
.probe = lola_probe,
.remove = __devexit_p(lola_remove),
diff --git a/sound/pci/lola/lola.h b/sound/pci/lola/lola.h
index d5708e29b16d..f0b100059efd 100644
--- a/sound/pci/lola/lola.h
+++ b/sound/pci/lola/lola.h
@@ -480,7 +480,7 @@ struct lola {
/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f)
-#define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res) ((res >> 7) & 0x1f)
+#define LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(res) ((res >> 7) & 0x1f)
int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
unsigned int data, unsigned int extdata);
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c
index 5d518f1a712c..6b8d64812951 100644
--- a/sound/pci/lola/lola_mixer.c
+++ b/sound/pci/lola/lola_mixer.c
@@ -144,40 +144,61 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
- /* mixer matrix can have unused areas between PhysIn and
+ /* mixer matrix may have unused areas between PhysIn and
* Play or Record and PhysOut zones
*/
chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
- LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val);
-
- /* example : MixerMatrix of LoLa881
- * 0-------8------16-------8------16
- * | | | | |
- * | INPUT | | INPUT | |
- * | -> |unused | -> |unused |
- * | RECORD| | OUTPUT| |
- * | | | | |
- * 8--------------------------------
- * | | | | |
- * | | | | |
- * |unused |unused |unused |unused |
- * | | | | |
- * | | | | |
- * 16-------------------------------
- * | | | | |
- * | PLAY | | PLAY | |
- * | -> |unused | -> |unused |
- * | RECORD| | OUTPUT| |
- * | | | | |
- * 8--------------------------------
- * | | | | |
- * | | | | |
- * |unused |unused |unused |unused |
- * | | | | |
- * | | | | |
- * 16-------------------------------
+ LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
+
+ /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
+ * +-+ 0-------8------16-------8------16
+ * | | | | | | |
+ * |s| | INPUT | | INPUT | |
+ * | |->| -> |unused | -> |unused |
+ * |r| |CAPTURE| | OUTPUT| |
+ * | | | MIX | | MIX | |
+ * |c| 8--------------------------------
+ * | | | | | | |
+ * | | | | | | |
+ * |g| |unused |unused |unused |unused |
+ * | | | | | | |
+ * |a| | | | | |
+ * | | 16-------------------------------
+ * |i| | | | | |
+ * | | | PLAYBK| | PLAYBK| |
+ * |n|->| -> |unused | -> |unused |
+ * | | |CAPTURE| | OUTPUT| |
+ * | | | MIX | | MIX | |
+ * |a| 8--------------------------------
+ * |r| | | | | |
+ * |r| | | | | |
+ * |a| |unused |unused |unused |unused |
+ * |y| | | | | |
+ * | | | | | | |
+ * +++ 16--|---------------|------------
+ * +---V---------------V-----------+
+ * | dest_mix_gain_enable array |
+ * +-------------------------------+
+ */
+ /* example : MixerMatrix of LoLa280
+ * +-+ 0-------8-2
+ * | | | | |
+ * |s| | INPUT | | INPUT
+ * |r|->| -> | | ->
+ * |c| |CAPTURE| | <- OUTPUT
+ * | | | MIX | | MIX
+ * |g| 8----------
+ * |a| | | |
+ * |i| | PLAYBK| | PLAYBACK
+ * |n|->| -> | | ->
+ * | | |CAPTURE| | <- OUTPUT
+ * |a| | MIX | | MIX
+ * |r| 8---|----|-
+ * |r| +---V----V-------------------+
+ * |a| | dest_mix_gain_enable array |
+ * |y| +----------------------------+
*/
if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
@@ -192,6 +213,9 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
(((1U << chip->mixer.dest_phys_outs) - 1)
<< chip->mixer.dest_phys_out_ofs);
+ snd_printdd("Mixer src_mask=%x, dest_mask=%x\n",
+ chip->mixer.src_mask, chip->mixer.dest_mask);
+
return 0;
}
@@ -202,12 +226,19 @@ static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
if (!(chip->mixer.src_mask & (1 << id)))
return -EINVAL;
- writew(gain, &chip->mixer.array->src_gain[id]);
oldval = val = readl(&chip->mixer.array->src_gain_enable);
if (on)
val |= (1 << id);
else
val &= ~(1 << id);
+ /* test if values unchanged */
+ if ((val == oldval) &&
+ (gain == readw(&chip->mixer.array->src_gain[id])))
+ return 0;
+
+ snd_printdd("lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
+ id, gain, val);
+ writew(gain, &chip->mixer.array->src_gain[id]);
writel(val, &chip->mixer.array->src_gain_enable);
lola_codec_flush(chip);
/* inform micro-controller about the new source gain */
@@ -269,6 +300,7 @@ static int lola_mixer_set_mapping_gain(struct lola *chip,
src, dest);
}
+#if 0 /* not used */
static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
unsigned int mask, unsigned short *gains)
{
@@ -289,6 +321,7 @@ static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
return lola_codec_write(chip, chip->mixer.nid,
LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
}
+#endif /* not used */
/*
*/
@@ -376,6 +409,8 @@ static int set_analog_volume(struct lola *chip, int dir,
return 0;
if (external_call)
lola_codec_flush(chip);
+ snd_printdd("set_analog_volume (dir=%d idx=%d, volume=%d)\n",
+ dir, idx, val);
err = lola_codec_write(chip, pin->nid,
LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
if (err < 0)
@@ -427,23 +462,40 @@ static int init_mixer_values(struct lola *chip)
{
int i;
- /* all src on */
+ /* all sample rate converters on */
lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
- /* clear all matrix */
+ /* clear all mixer matrix settings */
memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
- /* set src gain to 0dB */
+ /* inform firmware about all updated matrix columns - capture part */
+ for (i = 0; i < chip->mixer.dest_stream_ins; i++)
+ lola_codec_write(chip, chip->mixer.nid,
+ LOLA_VERB_SET_DESTINATION_GAIN,
+ i, 0);
+ /* inform firmware about all updated matrix columns - output part */
+ for (i = 0; i < chip->mixer.dest_phys_outs; i++)
+ lola_codec_write(chip, chip->mixer.nid,
+ LOLA_VERB_SET_DESTINATION_GAIN,
+ chip->mixer.dest_phys_out_ofs + i, 0);
+
+ /* set all digital input source (master) gains to 0dB */
for (i = 0; i < chip->mixer.src_phys_ins; i++)
lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
+
+ /* set all digital playback source (master) gains to 0dB */
for (i = 0; i < chip->mixer.src_stream_outs; i++)
lola_mixer_set_src_gain(chip,
i + chip->mixer.src_stream_out_ofs,
336, true); /* 0dB */
- /* set 1:1 dest gain */
+ /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
int src = i % chip->mixer.src_phys_ins;
lola_mixer_set_mapping_gain(chip, src, i, 336, true);
}
+ /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
+ * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
+ * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
+ */
for (i = 0; i < chip->mixer.src_stream_outs; i++) {
int src = chip->mixer.src_stream_out_ofs + i;
int dst = chip->mixer.dest_phys_out_ofs +
@@ -693,6 +745,7 @@ static int __devinit create_src_gain_mixer(struct lola *chip,
snd_ctl_new1(&lola_src_gain_mixer, chip));
}
+#if 0 /* not used */
/*
* destination gain (matrix-like) mixer
*/
@@ -781,6 +834,7 @@ static int __devinit create_dest_gain_mixer(struct lola *chip,
return snd_ctl_add(chip->card,
snd_ctl_new1(&lola_dest_gain_mixer, chip));
}
+#endif /* not used */
/*
*/
@@ -798,14 +852,16 @@ int __devinit lola_create_mixer(struct lola *chip)
if (err < 0)
return err;
err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
- "Line Source Gain Volume");
+ "Digital Capture Volume");
if (err < 0)
return err;
err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
chip->mixer.src_stream_out_ofs,
- "Stream Source Gain Volume");
+ "Digital Playback Volume");
if (err < 0)
return err;
+#if 0
+/* FIXME: buggy mixer matrix handling */
err = create_dest_gain_mixer(chip,
chip->mixer.src_phys_ins, 0,
chip->mixer.dest_stream_ins, 0,
@@ -834,6 +890,6 @@ int __devinit lola_create_mixer(struct lola *chip)
"Stream Playback Volume");
if (err < 0)
return err;
-
+#endif /* FIXME */
return init_mixer_values(chip);
}
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 1bd7a540fd49..04ae84b2a107 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -762,7 +762,6 @@ static int lx_set_granularity(struct lx6464es *chip, u32 gran)
static int __devinit lx_init_dsp(struct lx6464es *chip)
{
int err;
- u8 mac_address[6];
int i;
snd_printdd("->lx_init_dsp\n");
@@ -787,11 +786,11 @@ static int __devinit lx_init_dsp(struct lx6464es *chip)
/** \todo the mac address should be ready by not, but it isn't,
* so we wait for it */
for (i = 0; i != 1000; ++i) {
- err = lx_dsp_get_mac(chip, mac_address);
+ err = lx_dsp_get_mac(chip);
if (err)
return err;
- if (mac_address[0] || mac_address[1] || mac_address[2] ||
- mac_address[3] || mac_address[4] || mac_address[5])
+ if (chip->mac_address[0] || chip->mac_address[1] || chip->mac_address[2] ||
+ chip->mac_address[3] || chip->mac_address[4] || chip->mac_address[5])
goto mac_ready;
msleep(1);
}
@@ -800,8 +799,8 @@ static int __devinit lx_init_dsp(struct lx6464es *chip)
mac_ready:
snd_printd(LXP "mac address ready read after: %dms\n", i);
snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n",
- mac_address[0], mac_address[1], mac_address[2],
- mac_address[3], mac_address[4], mac_address[5]);
+ chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
+ chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
err = lx_init_get_version_features(chip);
if (err)
@@ -1031,7 +1030,7 @@ static int __devinit snd_lx6464es_create(struct snd_card *card,
chip->port_dsp_bar = pci_ioremap_bar(pci, 2);
err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED,
- card_name, chip);
+ KBUILD_MODNAME, chip);
if (err) {
snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq);
goto request_irq_failed;
@@ -1108,8 +1107,14 @@ static int __devinit snd_lx6464es_probe(struct pci_dev *pci,
goto out_free;
}
- strcpy(card->driver, "lx6464es");
- strcpy(card->shortname, "Digigram LX6464ES");
+ strcpy(card->driver, "LX6464ES");
+ sprintf(card->id, "LX6464ES_%02X%02X%02X",
+ chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
+
+ sprintf(card->shortname, "LX6464ES %02X.%02X.%02X.%02X.%02X.%02X",
+ chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
+ chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
+
sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i",
card->shortname, chip->port_plx,
chip->port_dsp_bar, chip->irq);
@@ -1137,7 +1142,7 @@ static void __devexit snd_lx6464es_remove(struct pci_dev *pci)
static struct pci_driver driver = {
- .name = "Digigram LX6464ES",
+ .name = KBUILD_MODNAME,
.id_table = snd_lx6464es_ids,
.probe = snd_lx6464es_probe,
.remove = __devexit_p(snd_lx6464es_remove),
diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h
index aea621eafbb5..e2a124ae27e8 100644
--- a/sound/pci/lx6464es/lx6464es.h
+++ b/sound/pci/lx6464es/lx6464es.h
@@ -69,6 +69,8 @@ struct lx6464es {
struct pci_dev *pci;
int irq;
+ u8 mac_address[6];
+
spinlock_t lock; /* interrupt spinlock */
struct mutex setup_mutex; /* mutex used in hw_params, open
* and close */
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
index 617f98b0cbae..5c8717e29eeb 100644
--- a/sound/pci/lx6464es/lx_core.c
+++ b/sound/pci/lx6464es/lx_core.c
@@ -424,7 +424,7 @@ int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
return ret;
}
-int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address)
+int lx_dsp_get_mac(struct lx6464es *chip)
{
u32 macmsb, maclsb;
@@ -432,12 +432,12 @@ int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address)
maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF;
/* todo: endianess handling */
- mac_address[5] = ((u8 *)(&maclsb))[0];
- mac_address[4] = ((u8 *)(&maclsb))[1];
- mac_address[3] = ((u8 *)(&maclsb))[2];
- mac_address[2] = ((u8 *)(&macmsb))[0];
- mac_address[1] = ((u8 *)(&macmsb))[1];
- mac_address[0] = ((u8 *)(&macmsb))[2];
+ chip->mac_address[5] = ((u8 *)(&maclsb))[0];
+ chip->mac_address[4] = ((u8 *)(&maclsb))[1];
+ chip->mac_address[3] = ((u8 *)(&maclsb))[2];
+ chip->mac_address[2] = ((u8 *)(&macmsb))[0];
+ chip->mac_address[1] = ((u8 *)(&macmsb))[1];
+ chip->mac_address[0] = ((u8 *)(&macmsb))[2];
return 0;
}
diff --git a/sound/pci/lx6464es/lx_core.h b/sound/pci/lx6464es/lx_core.h
index 6bd9cbbbc68d..1dd562980b6c 100644
--- a/sound/pci/lx6464es/lx_core.h
+++ b/sound/pci/lx6464es/lx_core.h
@@ -116,7 +116,7 @@ int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version);
int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq);
int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran);
int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data);
-int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address);
+int lx_dsp_get_mac(struct lx6464es *chip);
/* low-level pipe handling */
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 3c40d726b46e..0378126e6272 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -850,11 +850,10 @@ struct snd_m3 {
struct input_dev *input_dev;
char phys[64]; /* physical device path */
#else
- spinlock_t ac97_lock;
struct snd_kcontrol *master_switch;
struct snd_kcontrol *master_volume;
- struct tasklet_struct hwvol_tq;
#endif
+ struct work_struct hwvol_work;
unsigned int in_suspend;
@@ -1609,13 +1608,10 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
(without wrap around) in response to volume button presses and then
generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
of a byte wide register. The meaning of bits 0 and 4 is unknown. */
-static void snd_m3_update_hw_volume(unsigned long private_data)
+static void snd_m3_update_hw_volume(struct work_struct *work)
{
- struct snd_m3 *chip = (struct snd_m3 *) private_data;
+ struct snd_m3 *chip = container_of(work, struct snd_m3, hwvol_work);
int x, val;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- unsigned long flags;
-#endif
/* Figure out which volume control button was pushed,
based on differences from the default register
@@ -1645,21 +1641,13 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
if (!chip->master_switch || !chip->master_volume)
return;
- /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
- spin_lock_irqsave(&chip->ac97_lock, flags);
-
- val = chip->ac97->regs[AC97_MASTER_VOL];
+ val = snd_ac97_read(chip->ac97, AC97_MASTER);
switch (x) {
case 0x88:
/* The counters have not changed, yet we've received a HV
interrupt. According to tests run by various people this
happens when pressing the mute button. */
val ^= 0x8000;
- chip->ac97->regs[AC97_MASTER_VOL] = val;
- outw(val, chip->iobase + CODEC_DATA);
- outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_switch->id);
break;
case 0xaa:
/* counters increased by 1 -> volume up */
@@ -1667,11 +1655,6 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
val--;
if ((val & 0x7f00) > 0)
val -= 0x0100;
- chip->ac97->regs[AC97_MASTER_VOL] = val;
- outw(val, chip->iobase + CODEC_DATA);
- outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_volume->id);
break;
case 0x66:
/* counters decreased by 1 -> volume down */
@@ -1679,14 +1662,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
val++;
if ((val & 0x7f00) < 0x1f00)
val += 0x0100;
- chip->ac97->regs[AC97_MASTER_VOL] = val;
- outw(val, chip->iobase + CODEC_DATA);
- outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &chip->master_volume->id);
break;
}
- spin_unlock_irqrestore(&chip->ac97_lock, flags);
+ if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &chip->master_switch->id);
#else
if (!chip->input_dev)
return;
@@ -1730,11 +1710,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
return IRQ_NONE;
if (status & HV_INT_PENDING)
-#ifdef CONFIG_SND_MAESTRO3_INPUT
- snd_m3_update_hw_volume((unsigned long)chip);
-#else
- tasklet_schedule(&chip->hwvol_tq);
-#endif
+ schedule_work(&chip->hwvol_work);
/*
* ack an assp int if its running
@@ -2000,24 +1976,14 @@ static unsigned short
snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{
struct snd_m3 *chip = ac97->private_data;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- unsigned long flags;
-#endif
unsigned short data = 0xffff;
if (snd_m3_ac97_wait(chip))
goto fail;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- spin_lock_irqsave(&chip->ac97_lock, flags);
-#endif
snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
if (snd_m3_ac97_wait(chip))
- goto fail_unlock;
+ goto fail;
data = snd_m3_inw(chip, CODEC_DATA);
-fail_unlock:
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- spin_unlock_irqrestore(&chip->ac97_lock, flags);
-#endif
fail:
return data;
}
@@ -2026,20 +1992,11 @@ static void
snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
{
struct snd_m3 *chip = ac97->private_data;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- unsigned long flags;
-#endif
if (snd_m3_ac97_wait(chip))
return;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- spin_lock_irqsave(&chip->ac97_lock, flags);
-#endif
snd_m3_outw(chip, val, CODEC_DATA);
snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- spin_unlock_irqrestore(&chip->ac97_lock, flags);
-#endif
}
@@ -2458,6 +2415,7 @@ static int snd_m3_free(struct snd_m3 *chip)
struct m3_dma *s;
int i;
+ cancel_work_sync(&chip->hwvol_work);
#ifdef CONFIG_SND_MAESTRO3_INPUT
if (chip->input_dev)
input_unregister_device(chip->input_dev);
@@ -2511,6 +2469,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
return 0;
chip->in_suspend = 1;
+ cancel_work_sync(&chip->hwvol_work);
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(chip->pcm);
snd_ac97_suspend(chip->ac97);
@@ -2667,9 +2626,6 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
}
spin_lock_init(&chip->reg_lock);
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- spin_lock_init(&chip->ac97_lock);
-#endif
switch (pci->device) {
case PCI_DEVICE_ID_ESS_ALLEGRO:
@@ -2683,6 +2639,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
+ INIT_WORK(&chip->hwvol_work, snd_m3_update_hw_volume);
chip->external_amp = enable_amp;
if (amp_gpio >= 0 && amp_gpio <= 0x0f)
@@ -2752,12 +2709,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
snd_m3_hv_init(chip);
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
-#endif
-
if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
- card->driver, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_m3_free(chip);
return -ENOMEM;
@@ -2885,7 +2838,7 @@ static void __devexit snd_m3_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "Maestro3",
+ .name = KBUILD_MODNAME,
.id_table = snd_m3_ids,
.probe = snd_m3_probe,
.remove = __devexit_p(snd_m3_remove),
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 6c3fd4d1c49d..dbee59906ae1 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1268,7 +1268,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
}
if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED,
- CARD_NAME, mgr)) {
+ KBUILD_MODNAME, mgr)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_mixart_free(mgr);
return -EBUSY;
@@ -1381,7 +1381,7 @@ static void __devexit snd_mixart_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "Digigram miXart",
+ .name = KBUILD_MODNAME,
.id_table = snd_mixart_ids,
.probe = snd_mixart_probe,
.remove = __devexit_p(snd_mixart_remove),
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 5a60492ac7b3..83ea7a7d3eec 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -465,7 +465,7 @@ static int snd_nm256_acquire_irq(struct nm256 *chip)
mutex_lock(&chip->irq_mutex);
if (chip->irq < 0) {
if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED,
- chip->card->driver, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
mutex_unlock(&chip->irq_mutex);
return -EBUSY;
@@ -1743,7 +1743,7 @@ static void __devexit snd_nm256_remove(struct pci_dev *pci)
static struct pci_driver driver = {
- .name = "NeoMagic 256",
+ .name = KBUILD_MODNAME,
.id_table = snd_nm256_ids,
.probe = snd_nm256_probe,
.remove = __devexit_p(snd_nm256_remove),
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index d7e8ddd9a67b..218d9854e5cb 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -859,7 +859,7 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
}
static struct pci_driver oxygen_driver = {
- .name = "CMI8788",
+ .name = KBUILD_MODNAME,
.id_table = oxygen_ids,
.probe = generic_oxygen_probe,
.remove = __devexit_p(oxygen_pci_remove),
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 70b739816fcc..82311fcb86f6 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -655,7 +655,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
chip->model.init(chip);
err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
- DRIVER, chip);
+ KBUILD_MODNAME, chip);
if (err < 0) {
snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
goto err_card;
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index d5533e34ece9..cc0bcd9f3350 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -168,12 +168,6 @@ static int oxygen_open(struct snd_pcm_substream *substream,
if (err < 0)
return err;
}
- if (channel == PCM_MULTICH) {
- err = snd_pcm_hw_constraint_minmax
- (runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 0, 8192000);
- if (err < 0)
- return err;
- }
snd_pcm_set_sync(substream);
chip->streams[channel] = substream;
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 469010a8b849..773db794b43f 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -88,7 +88,7 @@ static int __devinit xonar_probe(struct pci_dev *pci,
}
static struct pci_driver xonar_driver = {
- .name = "AV200",
+ .name = KBUILD_MODNAME,
.id_table = xonar_ids,
.probe = xonar_probe,
.remove = __devexit_p(oxygen_pci_remove),
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index 54cad38ec30a..32d096c98f5b 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -327,8 +327,10 @@ static void pcm1796_init(struct oxygen *chip)
{
struct xonar_pcm179x *data = chip->model_data;
- data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE |
+ data->pcm1796_regs[0][18 - PCM1796_REG_BASE] =
PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
+ if (!data->broken_i2c)
+ data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE;
data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
PCM1796_FLT_SHARP | PCM1796_ATS_1;
data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
@@ -1123,6 +1125,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
chip->model.control_filter = xonar_st_h6_control_filter;
chip->model.dac_channels_pcm = 8;
chip->model.dac_channels_mixer = 8;
+ chip->model.dac_volume_min = 255;
chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
break;
}
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 95cfde27d25c..046578d26f98 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1501,7 +1501,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci,
mgr->irq = -1;
if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED,
- card_name, mgr)) {
+ KBUILD_MODNAME, mgr)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
pcxhr_free(mgr);
return -EBUSY;
@@ -1608,7 +1608,7 @@ static void __devexit pcxhr_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "Digigram pcxhr",
+ .name = KBUILD_MODNAME,
.id_table = pcxhr_ids,
.probe = pcxhr_probe,
.remove = __devexit_p(pcxhr_remove),
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index ad5202efd7a9..e34ae14908b3 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1890,7 +1890,7 @@ snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
UNSET_AIE(hwport);
if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED,
- "RIPTIDE", chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
pci->irq);
snd_riptide_free(chip);
@@ -2176,7 +2176,7 @@ static void __devexit snd_card_riptide_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "RIPTIDE",
+ .name = KBUILD_MODNAME,
.id_table = snd_riptide_ids,
.probe = snd_card_riptide_probe,
.remove = __devexit_p(snd_card_riptide_remove),
@@ -2188,7 +2188,7 @@ static struct pci_driver driver = {
#ifdef SUPPORT_JOYSTICK
static struct pci_driver joystick_driver = {
- .name = "Riptide Joystick",
+ .name = KBUILD_MODNAME "-joystick",
.id_table = snd_riptide_joystick_ids,
.probe = snd_riptide_joystick_probe,
.remove = __devexit_p(snd_riptide_joystick_remove),
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 3c04524de37c..6be77a264d47 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1355,7 +1355,7 @@ static int __devinit snd_rme32_create(struct rme32 * rme32)
}
if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_SHARED,
- "RME32", rme32)) {
+ KBUILD_MODNAME, rme32)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
return -EBUSY;
}
@@ -1985,7 +1985,7 @@ static void __devexit snd_rme32_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "RME Digi32",
+ .name = KBUILD_MODNAME,
.id_table = snd_rme32_ids,
.probe = snd_rme32_probe,
.remove = __devexit_p(snd_rme32_remove),
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 9ff247fc8871..409e5b89519d 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1561,7 +1561,7 @@ snd_rme96_create(struct rme96 *rme96)
}
if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED,
- "RME96", rme96)) {
+ KBUILD_MODNAME, rme96)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
return -EBUSY;
}
@@ -2396,7 +2396,7 @@ static void __devexit snd_rme96_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "RME Digi96",
+ .name = KBUILD_MODNAME,
.id_table = snd_rme96_ids,
.probe = snd_rme96_probe,
.remove = __devexit_p(snd_rme96_remove),
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 2d8332416c83..1c6d1e1c27c1 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -5482,7 +5482,7 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
}
if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED,
- "hdsp", hdsp)) {
+ KBUILD_MODNAME, hdsp)) {
snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
return -EBUSY;
}
@@ -5637,7 +5637,7 @@ static void __devexit snd_hdsp_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "RME Hammerfall DSP",
+ .name = KBUILD_MODNAME,
.id_table = snd_hdsp_ids,
.probe = snd_hdsp_probe,
.remove = __devexit_p(snd_hdsp_remove),
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index c8e402fc3782..af130ee0c45d 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -6441,7 +6441,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
hdspm->port + io_extent - 1);
if (request_irq(pci->irq, snd_hdspm_interrupt,
- IRQF_SHARED, "hdspm", hdspm)) {
+ IRQF_SHARED, KBUILD_MODNAME, hdspm)) {
snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
return -EBUSY;
}
@@ -6779,7 +6779,7 @@ static void __devexit snd_hdspm_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "RME Hammerfall DSP MADI",
+ .name = KBUILD_MODNAME,
.id_table = snd_hdspm_ids,
.probe = snd_hdspm_probe,
.remove = __devexit_p(snd_hdspm_remove),
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index c492af5b25f3..1c7bc1ef8186 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -2479,7 +2479,7 @@ static int __devinit snd_rme9652_create(struct snd_card *card,
}
if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED,
- "rme9652", rme9652)) {
+ KBUILD_MODNAME, rme9652)) {
snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
return -EBUSY;
}
@@ -2632,7 +2632,7 @@ static void __devexit snd_rme9652_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "RME Digi9652 (Hammerfall)",
+ .name = KBUILD_MODNAME,
.id_table = snd_rme9652_ids,
.probe = snd_rme9652_probe,
.remove = __devexit_p(snd_rme9652_remove),
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 2b5c7a95ae1f..bcf61524a13f 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -1235,7 +1235,7 @@ static int sis_resume(struct pci_dev *pci)
}
if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
- card->shortname, sis)) {
+ KBUILD_MODNAME, sis)) {
printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq);
goto error;
}
@@ -1341,7 +1341,7 @@ static int __devinit sis_chip_create(struct snd_card *card,
goto error_out_cleanup;
if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
- card->shortname, sis)) {
+ KBUILD_MODNAME, sis)) {
printk(KERN_ERR "unable to allocate irq %d\n", sis->irq);
goto error_out_cleanup;
}
@@ -1436,7 +1436,7 @@ static void __devexit snd_sis7019_remove(struct pci_dev *pci)
}
static struct pci_driver sis7019_driver = {
- .name = "SiS7019",
+ .name = KBUILD_MODNAME,
.id_table = snd_sis7019_ids,
.probe = snd_sis7019_probe,
.remove = __devexit_p(snd_sis7019_remove),
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 337b9facadfd..2571a67b389a 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1294,7 +1294,7 @@ static int __devinit snd_sonicvibes_create(struct snd_card *card,
sonic->game_port = pci_resource_start(pci, 4);
if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED,
- "S3 SonicVibes", sonic)) {
+ KBUILD_MODNAME, sonic)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_sonicvibes_free(sonic);
return -EBUSY;
@@ -1530,7 +1530,7 @@ static void __devexit snd_sonic_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "S3 SonicVibes",
+ .name = KBUILD_MODNAME,
.id_table = snd_sonic_ids,
.probe = snd_sonic_probe,
.remove = __devexit_p(snd_sonic_remove),
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 6d0581841d7a..d8a128f6fc02 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -172,7 +172,7 @@ static void __devexit snd_trident_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "Trident4DWaveAudio",
+ .name = KBUILD_MODNAME,
.id_table = snd_trident_ids,
.probe = snd_trident_probe,
.remove = __devexit_p(snd_trident_remove),
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 2870a4fdc130..5bd57a7c52d2 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -3598,7 +3598,7 @@ int __devinit snd_trident_create(struct snd_card *card,
trident->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
- "Trident Audio", trident)) {
+ KBUILD_MODNAME, trident)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_trident_free(trident);
return -EBUSY;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 8c5f8b5a59f0..f03fd620a2a0 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2377,7 +2377,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
chip_type == TYPE_VIA8233 ?
snd_via8233_interrupt : snd_via686_interrupt,
IRQF_SHARED,
- card->driver, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_via82xx_free(chip);
return -EBUSY;
@@ -2611,7 +2611,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "VIA 82xx Audio",
+ .name = KBUILD_MODNAME,
.id_table = snd_via82xx_ids,
.probe = snd_via82xx_probe,
.remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index f7e8bbbe3953..a386dd9f6732 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1129,7 +1129,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
}
chip->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED,
- card->driver, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_via82xx_free(chip);
return -EBUSY;
@@ -1224,7 +1224,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "VIA 82xx Modem",
+ .name = KBUILD_MODNAME,
.id_table = snd_via82xx_modem_ids,
.probe = snd_via82xx_probe,
.remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index 99a9a814be0b..5342d5e1366a 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -169,7 +169,7 @@ static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci
vx->port[i] = pci_resource_start(pci, i + 1);
if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
- CARD_NAME, chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_vx222_free(chip);
return -EBUSY;
@@ -290,7 +290,7 @@ static int snd_vx222_resume(struct pci_dev *pci)
#endif
static struct pci_driver driver = {
- .name = "Digigram VX222",
+ .name = KBUILD_MODNAME,
.id_table = snd_vx222_ids,
.probe = snd_vx222_probe,
.remove = __devexit_p(snd_vx222_remove),
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 80c682113381..511d57653124 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -345,7 +345,7 @@ static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
}
static struct pci_driver driver = {
- .name = "Yamaha DS-1 PCI",
+ .name = KBUILD_MODNAME,
.id_table = snd_ymfpci_ids,
.probe = snd_card_ymfpci_probe,
.remove = __devexit_p(snd_card_ymfpci_remove),
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index c94c051ad0c8..f3260e658b8a 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2380,7 +2380,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
return -EBUSY;
}
if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED,
- "YMFPCI", chip)) {
+ KBUILD_MODNAME, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ymfpci_free(chip);
return -EBUSY;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index ce33be0e4e98..66488a7a5706 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -223,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link)
if (ret)
goto failed;
- ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt);
+ ret = pcmcia_request_irq(link, pdacf_interrupt);
if (ret)
goto failed;
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index d9ef21d8fa73..31777d1ea49f 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -229,7 +229,7 @@ static int vxpocket_config(struct pcmcia_device *link)
if (ret)
goto failed;
- ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler);
+ ret = pcmcia_request_irq(link, snd_vx_irq_handler);
if (ret)
goto failed;
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 220c6167dd86..781d9e61adfb 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -433,9 +433,10 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
* only at the first time. the successive calls of this function will
* append the pcm interface to the corresponding card.
*/
-static void *snd_usb_audio_probe(struct usb_device *dev,
- struct usb_interface *intf,
- const struct usb_device_id *usb_id)
+static struct snd_usb_audio *
+snd_usb_audio_probe(struct usb_device *dev,
+ struct usb_interface *intf,
+ const struct usb_device_id *usb_id)
{
const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
int i, err;
@@ -540,16 +541,15 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
* we need to take care of counter, since disconnection can be called also
* many times as well as usb_audio_probe().
*/
-static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
+static void snd_usb_audio_disconnect(struct usb_device *dev,
+ struct snd_usb_audio *chip)
{
- struct snd_usb_audio *chip;
struct snd_card *card;
struct list_head *p;
- if (ptr == (void *)-1L)
+ if (chip == (void *)-1L)
return;
- chip = ptr;
card = chip->card;
mutex_lock(&register_mutex);
mutex_lock(&chip->shutdown_mutex);
@@ -585,7 +585,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
static int usb_audio_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- void *chip;
+ struct snd_usb_audio *chip;
chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
if (chip) {
usb_set_intfdata(intf, chip);
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index b0ef9f501896..7c0d21ecd821 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -408,6 +408,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
/* doesn't set the sample rate attribute, but supports it */
fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
break;
+ case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */
+ case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
an older model 77d:223) */
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index fb5d68fa7ff4..67bec7612442 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -645,7 +645,7 @@ static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
err = snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1500000 / ua->packets_per_second,
- 8192000);
+ UINT_MAX);
if (err < 0)
return err;
err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 0b2ae8e1c02d..dba0b7f11c54 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -1677,6 +1677,36 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
+{
+ USB_DEVICE(0x0582, 0x011e),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ /* .vendor_name = "BOSS", */
+ /* .product_name = "BR-800", */
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = (const struct snd_usb_audio_quirk[]) {
+ {
+ .ifnum = 0,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 1,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 2,
+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
+ .data = & (const struct snd_usb_midi_endpoint_info) {
+ .out_cables = 0x0001,
+ .in_cables = 0x0001
+ }
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
/* Guillemot devices */
{
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 090e1930dfdc..77762c99afbe 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -369,6 +369,30 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
return 0;
}
+static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)
+{
+ int err;
+
+ if (dev->actconfig->desc.bConfigurationValue == 1) {
+ snd_printk(KERN_INFO "usb-audio: "
+ "Fast Track Pro switching to config #2\n");
+ /* This function has to be available by the usb core module.
+ * if it is not avialable the boot quirk has to be left out
+ * and the configuration has to be set by udev or hotplug
+ * rules
+ */
+ err = usb_driver_set_configuration(dev, 2);
+ if (err < 0) {
+ snd_printdd("error usb_driver_set_configuration: %d\n",
+ err);
+ return -ENODEV;
+ }
+ } else
+ snd_printk(KERN_INFO "usb-audio: Fast Track Pro config OK\n");
+
+ return 0;
+}
+
/*
* C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
* documented in the device's data sheet.
@@ -471,16 +495,49 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
/*
* Setup quirks
*/
-#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
-#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
-#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
-#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
-#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
-#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
-#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
-#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
-#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
-#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
+#define MAUDIO_SET 0x01 /* parse device_setup */
+#define MAUDIO_SET_COMPATIBLE 0x80 /* use only "win-compatible" interfaces */
+#define MAUDIO_SET_DTS 0x02 /* enable DTS Digital Output */
+#define MAUDIO_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
+#define MAUDIO_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
+#define MAUDIO_SET_DI 0x10 /* enable Digital Input */
+#define MAUDIO_SET_MASK 0x1f /* bit mask for setup value */
+#define MAUDIO_SET_24B_48K_DI 0x19 /* 24bits+48KHz+Digital Input */
+#define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48KHz+No Digital Input */
+#define MAUDIO_SET_16B_48K_DI 0x11 /* 16bits+48KHz+Digital Input */
+#define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48KHz+No Digital Input */
+
+static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
+ int iface, int altno)
+{
+ /* Reset ALL ifaces to 0 altsetting.
+ * Call it for every possible altsetting of every interface.
+ */
+ usb_set_interface(chip->dev, iface, 0);
+ if (chip->setup & MAUDIO_SET) {
+ if (chip->setup & MAUDIO_SET_COMPATIBLE) {
+ if (iface != 1 && iface != 2)
+ return 1; /* skip all interfaces but 1 and 2 */
+ } else {
+ unsigned int mask;
+ if (iface == 1 || iface == 2)
+ return 1; /* skip interfaces 1 and 2 */
+ if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
+ return 1; /* skip this altsetting */
+ mask = chip->setup & MAUDIO_SET_MASK;
+ if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
+ return 1; /* skip this altsetting */
+ if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
+ return 1; /* skip this altsetting */
+ if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 4)
+ return 1; /* skip this altsetting */
+ }
+ }
+ snd_printdd(KERN_INFO
+ "using altsetting %d for interface %d config %d\n",
+ altno, iface, chip->setup);
+ return 0; /* keep this altsetting */
+}
static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
int iface,
@@ -491,30 +548,65 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
*/
usb_set_interface(chip->dev, iface, 0);
- if (chip->setup & AUDIOPHILE_SET) {
- if ((chip->setup & AUDIOPHILE_SET_DTS)
- && altno != 6)
+ if (chip->setup & MAUDIO_SET) {
+ unsigned int mask;
+ if ((chip->setup & MAUDIO_SET_DTS) && altno != 6)
return 1; /* skip this altsetting */
- if ((chip->setup & AUDIOPHILE_SET_96K)
- && altno != 1)
+ if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
return 1; /* skip this altsetting */
- if ((chip->setup & AUDIOPHILE_SET_MASK) ==
- AUDIOPHILE_SET_24B_48K_DI && altno != 2)
+ mask = chip->setup & MAUDIO_SET_MASK;
+ if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
return 1; /* skip this altsetting */
- if ((chip->setup & AUDIOPHILE_SET_MASK) ==
- AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
+ if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
return 1; /* skip this altsetting */
- if ((chip->setup & AUDIOPHILE_SET_MASK) ==
- AUDIOPHILE_SET_16B_48K_DI && altno != 4)
+ if (mask == MAUDIO_SET_16B_48K_DI && altno != 4)
return 1; /* skip this altsetting */
- if ((chip->setup & AUDIOPHILE_SET_MASK) ==
- AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
+ if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5)
return 1; /* skip this altsetting */
}
return 0; /* keep this altsetting */
}
+
+static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
+ int iface, int altno)
+{
+ /* Reset ALL ifaces to 0 altsetting.
+ * Call it for every possible altsetting of every interface.
+ */
+ usb_set_interface(chip->dev, iface, 0);
+
+ /* possible configuration where both inputs and only one output is
+ *used is not supported by the current setup
+ */
+ if (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) {
+ if (chip->setup & MAUDIO_SET_96K) {
+ if (altno != 3 && altno != 6)
+ return 1;
+ } else if (chip->setup & MAUDIO_SET_DI) {
+ if (iface == 4)
+ return 1; /* no analog input */
+ if (altno != 2 && altno != 5)
+ return 1; /* enable only altsets 2 and 5 */
+ } else {
+ if (iface == 5)
+ return 1; /* disable digialt input */
+ if (altno != 2 && altno != 5)
+ return 1; /* enalbe only altsets 2 and 5 */
+ }
+ } else {
+ /* keep only 16-Bit mode */
+ if (altno != 1)
+ return 1;
+ }
+
+ snd_printdd(KERN_INFO
+ "using altsetting %d for interface %d config %d\n",
+ altno, iface, chip->setup);
+ return 0; /* keep this altsetting */
+}
+
int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
int iface,
int altno)
@@ -522,6 +614,12 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
/* audiophile usb: skip altsets incompatible with device_setup */
if (chip->usb_id == USB_ID(0x0763, 0x2003))
return audiophile_skip_setting_quirk(chip, iface, altno);
+ /* quattro usb: skip altsets incompatible with device_setup */
+ if (chip->usb_id == USB_ID(0x0763, 0x2001))
+ return quattro_skip_setting_quirk(chip, iface, altno);
+ /* fasttrackpro usb: skip altsets incompatible with device_setup */
+ if (chip->usb_id == USB_ID(0x0763, 0x2012))
+ return fasttrackpro_skip_setting_quirk(chip, iface, altno);
return 0;
}
@@ -560,6 +658,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
return snd_usb_nativeinstruments_boot_quirk(dev);
+ case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
+ return snd_usb_fasttrackpro_boot_quirk(dev);
}
return 0;
@@ -570,15 +670,24 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
*/
int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
{
+ /* it depends on altsetting wether the device is big-endian or not */
switch (chip->usb_id) {
case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
- if (fp->endpoint & USB_DIR_IN)
+ if (fp->altsetting == 2 || fp->altsetting == 3 ||
+ fp->altsetting == 5 || fp->altsetting == 6)
return 1;
break;
case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
if (chip->setup == 0x00 ||
- fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
+ fp->altsetting == 1 || fp->altsetting == 2 ||
+ fp->altsetting == 3)
+ return 1;
+ break;
+ case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */
+ if (fp->altsetting == 2 || fp->altsetting == 3 ||
+ fp->altsetting == 5 || fp->altsetting == 6)
return 1;
+ break;
}
return 0;
}