summaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/Kconfig9
-rw-r--r--sound/pci/ac97/ac97_codec.c56
-rw-r--r--sound/pci/ac97/ac97_patch.c80
-rw-r--r--sound/pci/ac97/ac97_pcm.c9
-rw-r--r--sound/pci/ad1889.c5
-rw-r--r--sound/pci/ali5451/ali5451.c92
-rw-r--r--sound/pci/als4000.c8
-rw-r--r--sound/pci/atiixp.c50
-rw-r--r--sound/pci/atiixp_modem.c37
-rw-r--r--sound/pci/au88x0/au8810.h5
-rw-r--r--sound/pci/au88x0/au8820.h5
-rw-r--r--sound/pci/au88x0/au8830.h5
-rw-r--r--sound/pci/au88x0/au88x0.c2
-rw-r--r--sound/pci/au88x0/au88x0.h8
-rw-r--r--sound/pci/au88x0/au88x0_a3d.c2
-rw-r--r--sound/pci/au88x0/au88x0_core.c10
-rw-r--r--sound/pci/au88x0/au88x0_eq.c2
-rw-r--r--sound/pci/au88x0/au88x0_synth.c8
-rw-r--r--sound/pci/azt3328.c1005
-rw-r--r--sound/pci/azt3328.h135
-rw-r--r--sound/pci/ca0106/Makefile2
-rw-r--r--sound/pci/ca0106/ca0106.h27
-rw-r--r--sound/pci/ca0106/ca0106_main.c123
-rw-r--r--sound/pci/ca0106/ca_midi.c306
-rw-r--r--sound/pci/ca0106/ca_midi.h69
-rw-r--r--sound/pci/cmipci.c126
-rw-r--r--sound/pci/cs4281.c6
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c43
-rw-r--r--sound/pci/emu10k1/emu10k1.c2
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c4
-rw-r--r--sound/pci/emu10k1/emu10k1x.c6
-rw-r--r--sound/pci/emu10k1/emufx.c59
-rw-r--r--sound/pci/emu10k1/emupcm.c3
-rw-r--r--sound/pci/emu10k1/irq.c2
-rw-r--r--sound/pci/emu10k1/memory.c6
-rw-r--r--sound/pci/emu10k1/p16v.c2
-rw-r--r--sound/pci/ens1370.c17
-rw-r--r--sound/pci/es1938.c38
-rw-r--r--sound/pci/es1968.c22
-rw-r--r--sound/pci/fm801.c25
-rw-r--r--sound/pci/hda/hda_codec.c52
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_intel.c72
-rw-r--r--sound/pci/hda/hda_local.h22
-rw-r--r--sound/pci/hda/hda_proc.c5
-rw-r--r--sound/pci/hda/patch_analog.c133
-rw-r--r--sound/pci/hda/patch_realtek.c274
-rw-r--r--sound/pci/hda/patch_si3054.c2
-rw-r--r--sound/pci/ice1712/aureon.c6
-rw-r--r--sound/pci/ice1712/delta.c2
-rw-r--r--sound/pci/ice1712/ews.c6
-rw-r--r--sound/pci/ice1712/ice1712.c10
-rw-r--r--sound/pci/ice1712/ice1724.c43
-rw-r--r--sound/pci/ice1712/pontis.c3
-rw-r--r--sound/pci/ice1712/revo.c13
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c20
-rw-r--r--sound/pci/intel8x0.c160
-rw-r--r--sound/pci/intel8x0m.c55
-rw-r--r--sound/pci/maestro3.c21
-rw-r--r--sound/pci/mixart/mixart.c3
-rw-r--r--sound/pci/nm256/nm256.c145
-rw-r--r--sound/pci/rme32.c4
-rw-r--r--sound/pci/rme96.c4
-rw-r--r--sound/pci/rme9652/hdsp.c588
-rw-r--r--sound/pci/rme9652/hdspm.c3
-rw-r--r--sound/pci/rme9652/rme9652.c6
-rw-r--r--sound/pci/sonicvibes.c24
-rw-r--r--sound/pci/trident/trident_main.c18
-rw-r--r--sound/pci/trident/trident_memory.c4
-rw-r--r--sound/pci/via82xx.c375
-rw-r--r--sound/pci/via82xx_modem.c49
-rw-r--r--sound/pci/ymfpci/ymfpci.c18
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c75
73 files changed, 2845 insertions, 1793 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index a5d593c66f9f..0fb16cf335ea 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -1,13 +1,5 @@
# ALSA PCI drivers
-config SND_AC97_CODEC
- tristate
- select SND_PCM
- select SND_AC97_BUS
-
-config SND_AC97_BUS
- tristate
-
menu "PCI devices"
depends on SND!=n && PCI
@@ -192,6 +184,7 @@ config SND_CA0106
tristate "SB Audigy LS / Live 24bit"
depends on SND
select SND_AC97_CODEC
+ select SND_RAWMIDI
help
Say Y here to include support for the Sound Blaster Audigy LS
and Live 24bit.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 41fc290149ed..9bde76c4c6a2 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -220,12 +220,6 @@ const char *snd_ac97_stereo_enhancements[] =
/* 31 */ "Reserved 31"
};
-/*
- * Shared AC97 controllers (ICH, ATIIXP...)
- */
-static DECLARE_MUTEX(shared_codec_mutex);
-static ac97_t *shared_codec[AC97_SHARED_TYPES][4];
-
/*
* I/O routines
@@ -996,14 +990,8 @@ static int snd_ac97_free(ac97_t *ac97)
{
if (ac97) {
snd_ac97_proc_done(ac97);
- if (ac97->bus) {
+ if (ac97->bus)
ac97->bus->codec[ac97->num] = NULL;
- if (ac97->bus->shared_type) {
- down(&shared_codec_mutex);
- shared_codec[ac97->bus->shared_type-1][ac97->num] = NULL;
- up(&shared_codec_mutex);
- }
- }
if (ac97->private_free)
ac97->private_free(ac97);
kfree(ac97);
@@ -1139,7 +1127,6 @@ snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97
{
snd_kcontrol_new_t template;
memcpy(&template, _template, sizeof(template));
- snd_runtime_check(!template.index, return NULL);
template.index = ac97->num;
return snd_ctl_new1(&template, ac97);
}
@@ -1758,8 +1745,7 @@ static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem)
if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
return 0;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
return -ENODEV;
}
@@ -1889,21 +1875,6 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
snd_assert(bus != NULL && template != NULL, return -EINVAL);
snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL);
- snd_assert(bus->shared_type <= AC97_SHARED_TYPES, return -EINVAL);
- if (bus->shared_type) {
- /* already shared? */
- down(&shared_codec_mutex);
- ac97 = shared_codec[bus->shared_type-1][template->num];
- if (ac97) {
- if ((ac97_is_audio(ac97) && (template->scaps & AC97_SCAP_SKIP_AUDIO)) ||
- (ac97_is_modem(ac97) && (template->scaps & AC97_SCAP_SKIP_MODEM))) {
- up(&shared_codec_mutex);
- return -EACCES; /* skip this */
- }
- }
- up(&shared_codec_mutex);
- }
-
card = bus->card;
ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
if (ac97 == NULL)
@@ -2020,8 +1991,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
do {
if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
goto __ready_ok;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num);
}
@@ -2053,8 +2023,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
do {
if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
goto __ready_ok;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
}
@@ -2077,6 +2046,8 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78);
if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78)
ac97->flags |= AC97_DOUBLE_RATE;
+ /* restore to slots 10/11 to avoid the confliction with surrounds */
+ snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, 0);
}
if (ac97->ext_id & AC97_EI_VRA) { /* VRA support */
snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]);
@@ -2153,7 +2124,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
}
}
/* make sure the proper powerdown bits are cleared */
- if (ac97->scaps) {
+ if (ac97->scaps && ac97_is_audio(ac97)) {
reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
reg &= ~AC97_EA_PRJ;
@@ -2167,13 +2138,6 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
return err;
}
*rac97 = ac97;
-
- if (bus->shared_type) {
- down(&shared_codec_mutex);
- shared_codec[bus->shared_type-1][ac97->num] = ac97;
- up(&shared_codec_mutex);
- }
-
return 0;
}
@@ -2295,8 +2259,7 @@ void snd_ac97_resume(ac97_t *ac97)
do {
if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
/* FIXME: extra delay */
ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
@@ -2308,8 +2271,7 @@ void snd_ac97_resume(ac97_t *ac97)
unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
if (val != 0xffff && (val & 1) != 0)
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
}
__reset_ready:
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 0238cc65d32a..de1c72ad2c6b 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -163,14 +163,24 @@ static int ac97_channel_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
.private_value = 1, \
}
+static inline int is_surround_on(ac97_t *ac97)
+{
+ return ac97->channel_mode >= 1;
+}
+
+static inline int is_clfe_on(ac97_t *ac97)
+{
+ return ac97->channel_mode >= 2;
+}
+
static inline int is_shared_linein(ac97_t *ac97)
{
- return ! ac97->indep_surround && ac97->channel_mode >= 1;
+ return ! ac97->indep_surround && is_surround_on(ac97);
}
static inline int is_shared_micin(ac97_t *ac97)
{
- return ! ac97->indep_surround && ac97->channel_mode >= 2;
+ return ! ac97->indep_surround && is_clfe_on(ac97);
}
@@ -1450,7 +1460,8 @@ int patch_ad1881(ac97_t * ac97)
codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));
codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));
- snd_runtime_check(codecs[0] | codecs[1] | codecs[2], goto __end);
+ if (! (codecs[0] || codecs[1] || codecs[2]))
+ goto __end;
for (idx = 0; idx < 3; idx++)
if (ac97->spec.ad18xx.unchained[idx])
@@ -1753,12 +1764,13 @@ static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
static void ad1888_update_jacks(ac97_t *ac97)
{
+ unsigned short val = 0;
+ if (! is_shared_linein(ac97))
+ val |= (1 << 12);
+ if (! is_shared_micin(ac97))
+ val |= (1 << 11);
/* shared Line-In */
- snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
- is_shared_linein(ac97) ? 0 : 1 << 12);
- /* shared Mic */
- snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
- is_shared_micin(ac97) ? 0 : 1 << 11);
+ snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
}
static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
@@ -1852,12 +1864,7 @@ static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = {
static void ad1985_update_jacks(ac97_t *ac97)
{
- /* shared Line-In */
- snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
- is_shared_linein(ac97) ? 0 : 1 << 12);
- /* shared Mic */
- snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
- is_shared_micin(ac97) ? 0 : 1 << 11);
+ ad1888_update_jacks(ac97);
snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
is_shared_micin(ac97) ? 0 : 1 << 9);
}
@@ -2442,21 +2449,37 @@ int patch_cm9739(ac97_t * ac97)
static void cm9761_update_jacks(ac97_t *ac97)
{
- unsigned short surr_vals[2][2] = {
- { 0x0008, 0x0400 }, /* off, on */
- { 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */
+ /* FIXME: check the bits for each model
+ * model 83 is confirmed to work
+ */
+ static unsigned short surr_on[3][2] = {
+ { 0x0008, 0x0000 }, /* 9761-78 & 82 */
+ { 0x0000, 0x0008 }, /* 9761-82 rev.B */
+ { 0x0000, 0x0008 }, /* 9761-83 */
+ };
+ static unsigned short clfe_on[3][2] = {
+ { 0x0000, 0x1000 }, /* 9761-78 & 82 */
+ { 0x1000, 0x0000 }, /* 9761-82 rev.B */
+ { 0x0000, 0x1000 }, /* 9761-83 */
+ };
+ static unsigned short surr_shared[3][2] = {
+ { 0x0000, 0x0400 }, /* 9761-78 & 82 */
+ { 0x0000, 0x0400 }, /* 9761-82 rev.B */
+ { 0x0000, 0x0400 }, /* 9761-83 */
};
- unsigned short clfe_vals[2][2] = {
- { 0x2000, 0x1880 }, /* off, on */
- { 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */
+ static unsigned short clfe_shared[3][2] = {
+ { 0x2000, 0x0880 }, /* 9761-78 & 82 */
+ { 0x0000, 0x2880 }, /* 9761-82 rev.B */
+ { 0x2000, 0x0800 }, /* 9761-83 */
};
+ unsigned short val = 0;
- /* shared Line-In */
- snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x0408,
- surr_vals[ac97->spec.dev_flags][is_shared_linein(ac97)]);
- /* shared Mic */
- snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3880,
- clfe_vals[ac97->spec.dev_flags][is_shared_micin(ac97)]);
+ val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
+ val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
+ val |= surr_shared[ac97->spec.dev_flags][is_shared_linein(ac97)];
+ val |= clfe_shared[ac97->spec.dev_flags][is_shared_micin(ac97)];
+
+ snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
}
static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
@@ -2551,7 +2574,7 @@ int patch_cm9761(ac97_t *ac97)
snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808);
snd_ac97_write_cache(ac97, AC97_PCM, 0x8808);
- ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */
+ ac97->spec.dev_flags = 0; /* 1 = model 82 revision B, 2 = model 83 */
if (ac97->id == AC97_ID_CM9761_82) {
unsigned short tmp;
/* check page 1, reg 0x60 */
@@ -2560,7 +2583,8 @@ int patch_cm9761(ac97_t *ac97)
tmp = snd_ac97_read(ac97, 0x60);
ac97->spec.dev_flags = tmp & 1; /* revision B? */
snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
- }
+ } else if (ac97->id == AC97_ID_CM9761_83)
+ ac97->spec.dev_flags = 2;
ac97->build_ops = &patch_cm9761_ops;
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index dd289b9512e1..ded13165d635 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -303,6 +303,15 @@ int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate)
AC97_EA_DRA, dbl ? AC97_EA_DRA : 0);
snd_ac97_update(ac97, reg, tmp & 0xffff);
snd_ac97_read(ac97, reg);
+ if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) {
+ /* Intel controllers require double rate data to be put in
+ * slots 7+8
+ */
+ snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE,
+ AC97_GP_DRSS_MASK,
+ dbl ? AC97_GP_DRSS_78 : 0);
+ snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
+ }
return 0;
}
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index d7d99a25c5e5..e72ccd1a004f 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -50,7 +50,7 @@
#include "ad1889.h"
#include "ac97/ac97_id.h"
-#define AD1889_DRVVER "$Revision: 1.3 $"
+#define AD1889_DRVVER "$Revision: 1.4 $"
MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
@@ -982,8 +982,7 @@ snd_ad1889_create(snd_card_t *card,
return 0;
free_and_ret:
- if (chip)
- kfree(chip);
+ kfree(chip);
pci_disable_device(pci);
return err;
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index f35b558c29b2..4e76c4a636d9 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -45,23 +45,25 @@ MODULE_DESCRIPTION("ALI M5451");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
-static int spdif[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static int index = SNDRV_DEFAULT_IDX1; /* Index */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int pcm_channels = 32;
+static int spdif = 0;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for ALI M5451 PCI Audio.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ALI 5451 PCI Audio.");
-module_param_array(pcm_channels, int, NULL, 0444);
+module_param(pcm_channels, int, 0444);
MODULE_PARM_DESC(pcm_channels, "PCM Channels");
-module_param_array(spdif, bool, NULL, 0444);
+module_param(spdif, bool, 0444);
MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
+
/*
* Debug part definitions
*/
@@ -396,10 +398,8 @@ static int snd_ali_codec_ready( ali_t *codec,
res = snd_ali_5451_peek(codec,port);
if (! (res & 0x8000))
return 0;
- if (sched) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (sched)
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
snd_ali_5451_poke(codec, port, res & ~0x8000);
snd_printdd("ali_codec_ready: codec is not ready.\n ");
@@ -419,12 +419,10 @@ static int snd_ali_stimer_ready(ali_t *codec, int sched)
dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
if (dwChk2 != dwChk1)
return 0;
- if (sched) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if (sched)
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
- snd_printk("ali_stimer_read: stimer is not ready.\n");
+ snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n");
return -EIO;
}
@@ -436,7 +434,7 @@ static void snd_ali_codec_poke(ali_t *codec,int secondary,
unsigned int port = 0;
if (reg >= 0x80) {
- snd_printk("ali_codec_poke: reg(%xh) invalid.\n", reg);
+ snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg);
return;
}
@@ -465,7 +463,7 @@ static unsigned short snd_ali_codec_peek( ali_t *codec,
unsigned int port = 0;
if (reg >= 0x80) {
- snd_printk("ali_codec_peek: reg(%xh) invalid.\n", reg);
+ snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg);
return ~0;
}
@@ -669,7 +667,7 @@ static int snd_ali_alloc_pcm_channel(ali_t *codec, int channel)
unsigned int idx = channel & 0x1f;
if (codec->synth.chcnt >= ALI_CHANNELS){
- snd_printk("ali_alloc_pcm_channel: no free channels.\n");
+ snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n");
return -1;
}
@@ -700,7 +698,7 @@ static int snd_ali_find_free_channel(ali_t * codec, int rec)
if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
return result;
} else {
- snd_printk("ali_find_free_channel: record channel is busy now.\n");
+ snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n");
return -1;
}
}
@@ -712,7 +710,7 @@ static int snd_ali_find_free_channel(ali_t * codec, int rec)
if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
return result;
} else {
- snd_printk("ali_find_free_channel: S/PDIF out channel is in busy now.\n");
+ snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n");
}
}
@@ -720,7 +718,7 @@ static int snd_ali_find_free_channel(ali_t * codec, int rec)
if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
return result;
}
- snd_printk("ali_find_free_channel: no free channels.\n");
+ snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n");
return -1;
}
@@ -734,7 +732,7 @@ static void snd_ali_free_channel_pcm(ali_t *codec, int channel)
return;
if (!(codec->synth.chmap & (1 << idx))) {
- snd_printk("ali_free_channel_pcm: channel %d is not in use.\n",channel);
+ snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel);
return;
} else {
codec->synth.chmap &= ~(1 << idx);
@@ -796,7 +794,7 @@ static void snd_ali_detect_spdif_rate(ali_t *codec)
}
if (count > 50000) {
- snd_printk("ali_detect_spdif_rate: timeout!\n");
+ snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
return;
}
@@ -809,7 +807,7 @@ static void snd_ali_detect_spdif_rate(ali_t *codec)
}
if (count > 50000) {
- snd_printk("ali_detect_spdif_rate: timeout!\n");
+ snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
return;
}
@@ -1077,7 +1075,7 @@ static snd_ali_voice_t *snd_ali_alloc_voice(ali_t * codec, int type, int rec, in
idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
snd_ali_find_free_channel(codec,rec);
if(idx < 0) {
- snd_printk("ali_alloc_voice: err.\n");
+ snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
spin_unlock_irqrestore(&codec->voice_alloc, flags);
return NULL;
}
@@ -1479,13 +1477,13 @@ static int snd_ali_prepare(snd_pcm_substream_t * substream)
}
rate = snd_ali_get_spdif_in_rate(codec);
if (rate == 0) {
- snd_printk("ali_capture_preapre: spdif rate detect err!\n");
+ snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n");
rate = 48000;
}
bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
if (bValue & 0x10) {
outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL));
- printk("clear SPDIF parity error flag.\n");
+ printk(KERN_WARNING "clear SPDIF parity error flag.\n");
}
if (rate != 48000)
@@ -1795,6 +1793,7 @@ struct ali_pcm_description {
unsigned int capture_num;
snd_pcm_ops_t *playback_ops;
snd_pcm_ops_t *capture_ops;
+ unsigned short class;
};
@@ -1813,12 +1812,11 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr
err = snd_pcm_new(codec->card, desc->name, device,
desc->playback_num, desc->capture_num, &pcm);
if (err < 0) {
- snd_printk("snd_ali_pcm: err called snd_pcm_new.\n");
+ snd_printk(KERN_ERR "snd_ali_pcm: err called snd_pcm_new.\n");
return err;
}
pcm->private_data = codec;
pcm->private_free = snd_ali_pcm_free;
- pcm->info_flags = 0;
if (desc->playback_ops)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
if (desc->capture_ops)
@@ -1828,6 +1826,7 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr
snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
pcm->info_flags = 0;
+ pcm->dev_class = desc->class;
pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
strcpy(pcm->name, desc->name);
codec->pcm[0] = pcm;
@@ -1836,7 +1835,7 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr
static struct ali_pcm_description ali_pcms[] = {
{ "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops },
- { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops }
+ { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM }
};
static int __devinit snd_ali_build_pcms(ali_t *codec)
@@ -1991,7 +1990,7 @@ static int __devinit snd_ali_mixer(ali_t * codec)
for ( i = 0 ; i < codec->num_of_codecs ; i++) {
ac97.num = i;
if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
- snd_printk("ali mixer %d creating error.\n", i);
+ snd_printk(KERN_ERR "ali mixer %d creating error.\n", i);
if(i == 0)
return err;
codec->num_of_codecs = 1;
@@ -2125,7 +2124,7 @@ static int snd_ali_chip_init(ali_t *codec)
snd_ali_printk("chip initializing ... \n");
if (snd_ali_reset_5451(codec)) {
- snd_printk("ali_chip_init: reset 5451 error.\n");
+ snd_printk(KERN_ERR "ali_chip_init: reset 5451 error.\n");
return -1;
}
@@ -2200,7 +2199,7 @@ static int __devinit snd_ali_resources(ali_t *codec)
codec->port = pci_resource_start(codec->pci, 0);
if (request_irq(codec->pci->irq, snd_ali_card_interrupt, SA_INTERRUPT|SA_SHIRQ, "ALI 5451", (void *)codec)) {
- snd_printk("Unable to request irq.\n");
+ snd_printk(KERN_ERR "Unable to request irq.\n");
return -EBUSY;
}
codec->irq = codec->pci->irq;
@@ -2240,7 +2239,7 @@ static int __devinit snd_ali_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 31 bits */
if (pci_set_dma_mask(pci, 0x7fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x7fffffff) < 0) {
- snd_printk("architecture does not support 31bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -2329,7 +2328,7 @@ static int __devinit snd_ali_create(snd_card_t * card,
}
if ((err = snd_ali_chip_init(codec)) < 0) {
- snd_printk("ali create: chip init error.\n");
+ snd_printk(KERN_ERR "ali create: chip init error.\n");
return err;
}
@@ -2352,25 +2351,17 @@ static int __devinit snd_ali_create(snd_card_t * card,
static int __devinit snd_ali_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
ali_t *codec;
int err;
snd_ali_printk("probe ...\n");
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
- if ((err = snd_ali_create(card, pci, pcm_channels[dev], spdif[dev], &codec)) < 0) {
+ if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) {
snd_card_free(card);
return err;
}
@@ -2401,7 +2392,6 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
}
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 196ec1c61bb4..7c61561f297f 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -594,8 +594,7 @@ static int __devinit snd_als4000_create_gameport(snd_card_als4000_t *acard, int
acard->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "als4000: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -622,8 +621,7 @@ static void snd_als4000_free_gameport(snd_card_als4000_t *acard)
acard->gameport = NULL;
snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
@@ -669,7 +667,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
- snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 241eacf1e652..f5dad9248e39 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -39,26 +39,27 @@ MODULE_DESCRIPTION("ATI IXP AC97 controller");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}");
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
-static char *ac97_quirk[SNDRV_CARDS];
-static int spdif_aclink[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
-
-module_param_array(index, int, NULL, 0444);
+static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 48000;
+static char *ac97_quirk;
+static int spdif_aclink = 1;
+
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(spdif_aclink, bool, NULL, 0444);
+module_param(spdif_aclink, bool, 0444);
MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/*
*/
@@ -329,8 +330,7 @@ static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
/* delay for one tick */
#define do_delay() do { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- schedule_timeout(1); \
+ schedule_timeout_uninterruptible(1); \
} while (0)
@@ -1372,7 +1372,6 @@ static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock, const char
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
return err;
pbus->clock = clock;
- pbus->shared_type = AC97_SHARED_TYPE_ATIIXP; /* shared with modem driver */
chip->ac97_bus = pbus;
codec_count = 0;
@@ -1579,26 +1578,18 @@ static int __devinit snd_atiixp_create(snd_card_t *card,
static int __devinit snd_atiixp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
atiixp_t *chip;
unsigned char revision;
int err;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
- strcpy(card->driver, spdif_aclink[dev] ? "ATIIXP" : "ATIIXP-SPDMA");
+ strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA");
strcpy(card->shortname, "ATI IXP");
if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
goto __error;
@@ -1606,9 +1597,9 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
if ((err = snd_atiixp_aclink_reset(chip)) < 0)
goto __error;
- chip->spdif_over_aclink = spdif_aclink[dev];
+ chip->spdif_over_aclink = spdif_aclink;
- if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev], ac97_quirk[dev])) < 0)
+ if ((err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk)) < 0)
goto __error;
if ((err = snd_atiixp_pcm_new(chip)) < 0)
@@ -1629,7 +1620,6 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
goto __error;
pci_set_drvdata(pci, card);
- dev++;
return 0;
__error:
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index c1a239a4dac6..0cf202079571 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -39,20 +39,21 @@ MODULE_DESCRIPTION("ATI IXP MC97 controller");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}");
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 48000;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/*
*/
@@ -306,8 +307,7 @@ static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
/* delay for one tick */
#define do_delay() do { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- schedule_timeout(1); \
+ schedule_timeout_uninterruptible(1); \
} while (0)
@@ -989,6 +989,7 @@ static int __devinit snd_atiixp_pcm_new(atiixp_t *chip)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
+ pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
pcm->private_data = chip;
strcpy(pcm->name, "ATI IXP MC97");
chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
@@ -1067,7 +1068,6 @@ static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock)
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
return err;
pbus->clock = clock;
- pbus->shared_type = AC97_SHARED_TYPE_ATIIXP; /* shared with audio driver */
chip->ac97_bus = pbus;
codec_count = 0;
@@ -1256,20 +1256,12 @@ static int __devinit snd_atiixp_create(snd_card_t *card,
static int __devinit snd_atiixp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
atiixp_t *chip;
unsigned char revision;
int err;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -1283,7 +1275,7 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
if ((err = snd_atiixp_aclink_reset(chip)) < 0)
goto __error;
- if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev])) < 0)
+ if ((err = snd_atiixp_mixer_new(chip, ac97_clock)) < 0)
goto __error;
if ((err = snd_atiixp_pcm_new(chip)) < 0)
@@ -1302,7 +1294,6 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
goto __error;
pci_set_drvdata(pci, card);
- dev++;
return 0;
__error:
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 3837d2ba5e67..5d69c31fe3f4 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -178,11 +178,6 @@
#define EN_SPDIF 0x000c0000
#define VORTEX_CODEC_CHN 0x29080
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
#define VORTEX_CODEC_IO 0x29188
/* SPDIF */
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index be8022e78714..abbe85e4f7a9 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -162,11 +162,6 @@
#define EN_SPORT 0x00030000
#define EN_SPDIF 0x000c0000
#define VORTEX_CODEC_CHN 0x11880
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
#define VORTEX_CODEC_IO 0x11988
#define VORTEX_SPDIF_FLAGS 0x1005c /* FIXME */
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index aa77826b5e59..04ece1b1c218 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -194,11 +194,6 @@
#define VORTEX_CODEC_CTRL 0x29184
#define VORTEX_CODEC_IO 0x29188
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
#define VORTEX_CODEC_SPORTCTRL 0x2918c
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 04b695d6fd48..6af3b13f2fd1 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -303,7 +303,7 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH,
sizeof(snd_vortex_synth_arg_t), &wave) < 0
|| wave == NULL) {
- snd_printk("Can't initialize Aureal wavetable synth\n");
+ snd_printk(KERN_ERR "Can't initialize Aureal wavetable synth\n");
} else {
snd_vortex_synth_arg_t *arg;
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index ee1ede1979f6..b1197cfab3fb 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -79,6 +79,14 @@
#define VORTEX_RESOURCE_A3D 0x00000004
#define VORTEX_RESOURCE_LAST 0x00000005
+/* codec io: VORTEX_CODEC_IO bits */
+#define VORTEX_CODEC_ID_SHIFT 24
+#define VORTEX_CODEC_WRITE 0x00800000
+#define VORTEX_CODEC_ADDSHIFT 16
+#define VORTEX_CODEC_ADDMASK 0x7f0000
+#define VORTEX_CODEC_DATSHIFT 0
+#define VORTEX_CODEC_DATMASK 0xffff
+
/* Check for SDAC bit in "Extended audio ID" AC97 register */
//#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ? 0 : ((x)->codec->ext_id&0x80))
#define VORTEX_IS_QUAD(x) ((x)->isquad)
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index 9ea2ba7bc3c8..d5755db5141f 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -488,7 +488,7 @@ static void a3dsrc_ZeroStateA3D(a3dsrc_t * a)
int i, var, var2;
if ((a->vortex) == NULL) {
- printk("vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
+ printk(KERN_ERR "vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
return;
}
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index f0eda4bbbb39..5905188d06b5 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2033,7 +2033,7 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
}
}
}
- printk("vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
+ printk(KERN_ERR "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
return -ENOMEM;
}
@@ -2165,7 +2165,7 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
memset(stream->resources, 0,
sizeof(unsigned char) *
VORTEX_RESOURCE_LAST);
- printk("vortex: out of A3D sources. Sorry\n");
+ printk(KERN_ERR "vortex: out of A3D sources. Sorry\n");
return -EBUSY;
}
/* (De)Initialize A3D hardware source. */
@@ -2532,7 +2532,8 @@ vortex_codec_write(ac97_t * codec, unsigned short addr, unsigned short data)
hwwrite(card->mmio, VORTEX_CODEC_IO,
((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
- VORTEX_CODEC_WRITE);
+ VORTEX_CODEC_WRITE |
+ (codec->num << VORTEX_CODEC_ID_SHIFT) );
/* Flush Caches. */
hwread(card->mmio, VORTEX_CODEC_IO);
@@ -2554,7 +2555,8 @@ static unsigned short vortex_codec_read(ac97_t * codec, unsigned short addr)
}
}
/* set up read address */
- read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK);
+ read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
+ (codec->num << VORTEX_CODEC_ID_SHIFT) ;
hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
/* wait for address */
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 53b47a42c7d8..9d933cc0ea0b 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -854,7 +854,7 @@ snd_vortex_peaks_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
if (count != 20) {
- printk("vortex: peak count error 20 != %d \n", count);
+ printk(KERN_ERR "vortex: peak count error 20 != %d \n", count);
return -1;
}
for (i = 0; i < 20; i++)
diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c
index 400417d34609..65f375bad43a 100644
--- a/sound/pci/au88x0/au88x0_synth.c
+++ b/sound/pci/au88x0/au88x0_synth.c
@@ -90,7 +90,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
hwwrite(vortex->mmio, WT_PARM(wt, 2), 0);
temp = hwread(vortex->mmio, WT_PARM(wt, 3));
- printk("vortex: WT PARM3: %x\n", temp);
+ printk(KERN_DEBUG "vortex: WT PARM3: %x\n", temp);
//hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0);
@@ -98,7 +98,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0);
hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0);
- printk("vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
+ printk(KERN_DEBUG "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff);
hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810);
@@ -106,7 +106,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
voice->parm0 = voice->parm1 = 0xcfb23e2f;
hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
- printk("vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
+ printk(KERN_DEBUG "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
return 0;
}
@@ -203,7 +203,7 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
}
} else {
if (wt >= NR_WT) {
- printk("vortex: WT SetReg: voice out of range\n");
+ printk(KERN_ERR "vortex: WT SetReg: voice out of range\n");
return 0;
}
}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index d5261bdec583..da99b1be2e8f 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
/*
* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- * Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
+ * Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de>
*
* Framework borrowed from Bart Hartgers's als4000.c.
* Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -46,7 +46,7 @@
* - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
* - game port (legacy address support)
* - built-in General DirectX timer having a 20 bits counter
- * with 1us resolution (FIXME: where is it?)
+ * with 1us resolution (see below!)
* - I2S serial port for external DAC
* - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
* - supports hardware volume control
@@ -55,13 +55,23 @@
* required for Microsoft's logo compliance (FIXME: where?)
* - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
*
+ * Note that this driver now is actually *better* than the Windows driver,
+ * since it additionally supports the card's 1MHz DirectX timer - just try
+ * the following snd-seq module parameters etc.:
+ * - options snd-seq seq_default_timer_class=2 seq_default_timer_sclass=0
+ * seq_default_timer_card=0 seq_client_load=1 seq_default_timer_device=0
+ * seq_default_timer_subdevice=0 seq_default_timer_resolution=1000000
+ * - "timidity -iAv -B2,8 -Os -EFreverb=0"
+ * - "pmidi -p 128:0 jazz.mid"
+ *
* Certain PCI versions of this card are susceptible to DMA traffic underruns
* in some systems (resulting in sound crackling/clicking/popping),
* probably because they don't have a DMA FIFO buffer or so.
* Overview (PCI ID/PCI subID/PCI rev.):
* - no DMA crackling on SiS735: 0x50DC/0x1801/16
* - unknown performance: 0x50DC/0x1801/10
- *
+ * (well, it's not bad on an Athlon 1800 with now very optimized IRQ handler)
+ *
* Crackling happens with VIA chipsets or, in my case, an SiS735, which is
* supposed to be very fast and supposed to get rid of crackling much
* better than a VIA, yet ironically I still get crackling, like many other
@@ -76,18 +86,13 @@
* - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
*
* BUGS
- * - when Ctrl-C'ing mpg321, the playback loops a bit
- * (premature DMA playback reset?)
- * - full-duplex sometimes breaks (IRQ management issues?).
- * Once even a spontaneous REBOOT happened!!!
+ * - full-duplex might *still* be problematic, not fully tested recently
*
* TODO
* - test MPU401 MIDI playback etc.
- * - power management (CONFIG_PM). See e.g. intel8x0 or cs4281.
+ * - power management. See e.g. intel8x0 or cs4281.
* This would be nice since the chip runs a bit hot, and it's *required*
- * anyway for proper ACPI power management. In other words: rest
- * assured that I *will* implement this very soon; as soon as Linux 2.5.x
- * has power management that's bugfree enough to work properly on my desktop.
+ * anyway for proper ACPI power management.
* - figure out what all unknown port bits are responsible for
*/
@@ -108,7 +113,7 @@
#include <sound/initval.h>
#include "azt3328.h"
-MODULE_AUTHOR("Andreas Mohr <hw7oshyuv3001@sneakemail.com>");
+MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
@@ -122,6 +127,7 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
#define DEBUG_MIXER 0
#define DEBUG_PLAY_REC 0
#define DEBUG_IO 0
+#define DEBUG_TIMER 0
#define MIXER_TESTING 0
#if DEBUG_MISC
@@ -132,8 +138,8 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
#if DEBUG_CALLS
#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
-#define snd_azf3328_dbgcallenter() printk(KERN_ERR "entering %s\n", __FUNCTION__)
-#define snd_azf3328_dbgcallleave() printk(KERN_ERR "leaving %s\n", __FUNCTION__)
+#define snd_azf3328_dbgcallenter() printk(KERN_ERR "--> %s\n", __FUNCTION__)
+#define snd_azf3328_dbgcallleave() printk(KERN_ERR "<-- %s\n", __FUNCTION__)
#else
#define snd_azf3328_dbgcalls(format, args...)
#define snd_azf3328_dbgcallenter()
@@ -152,13 +158,12 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
#define snd_azf3328_dbgplay(format, args...)
#endif
-#if DEBUG_IO
-#define snd_azf3328_dbgio(chip, where) \
- printk(KERN_ERR "%s: IDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", where, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS))
+#if DEBUG_MISC
+#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args)
#else
-#define snd_azf3328_dbgio(chip, where)
-#endif
-
+#define snd_azf3328_dbgtimer(format, args...)
+#endif
+
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
@@ -177,35 +182,40 @@ module_param_array(joystick, bool, NULL, 0444);
MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard.");
#endif
-typedef struct _snd_azf3328 azf3328_t;
-
-struct _snd_azf3328 {
- int irq;
+static int seqtimer_scaling = 128;
+module_param(seqtimer_scaling, int, 0444);
+MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
+typedef struct _snd_azf3328 {
+ /* often-used fields towards beginning, then grouped */
unsigned long codec_port;
unsigned long io2_port;
unsigned long mpu_port;
unsigned long synth_port;
unsigned long mixer_port;
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-
- struct pci_dev *pci;
- snd_card_t *card;
+ spinlock_t reg_lock;
+ snd_timer_t *timer;
+
snd_pcm_t *pcm;
- snd_rawmidi_t *rmidi;
snd_pcm_substream_t *playback_substream;
snd_pcm_substream_t *capture_substream;
unsigned int is_playing;
unsigned int is_recording;
- spinlock_t reg_lock;
-};
+ snd_card_t *card;
+ snd_rawmidi_t *rmidi;
+
+#ifdef SUPPORT_JOYSTICK
+ struct gameport *gameport;
+#endif
-static struct pci_device_id snd_azf3328_ids[] = {
+ struct pci_dev *pci;
+ int irq;
+} azf3328_t;
+
+static const struct pci_device_id snd_azf3328_ids[] = {
{ 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
{ 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
{ 0, }
@@ -213,57 +223,90 @@ static struct pci_device_id snd_azf3328_ids[] = {
MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
-static inline void snd_azf3328_io2_write(azf3328_t *chip, int reg, unsigned char value)
+static inline void
+snd_azf3328_codec_outb(const azf3328_t *chip, int reg, u8 value)
+{
+ outb(value, chip->codec_port + reg);
+}
+
+static inline u8
+snd_azf3328_codec_inb(const azf3328_t *chip, int reg)
+{
+ return inb(chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_codec_outw(const azf3328_t *chip, int reg, u16 value)
+{
+ outw(value, chip->codec_port + reg);
+}
+
+static inline u16
+snd_azf3328_codec_inw(const azf3328_t *chip, int reg)
+{
+ return inw(chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_codec_outl(const azf3328_t *chip, int reg, u32 value)
+{
+ outl(value, chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_io2_outb(const azf3328_t *chip, int reg, u8 value)
{
outb(value, chip->io2_port + reg);
}
-static inline unsigned char snd_azf3328_io2_read(azf3328_t *chip, int reg)
+static inline u8
+snd_azf3328_io2_inb(const azf3328_t *chip, int reg)
{
return inb(chip->io2_port + reg);
}
-static void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int type)
+static inline void
+snd_azf3328_mixer_outw(const azf3328_t *chip, int reg, u16 value)
{
- switch(type) {
- case WORD_VALUE:
- outw(value, chip->mixer_port + reg);
- break;
- case DWORD_VALUE:
- outl(value, chip->mixer_port + reg);
- break;
- case BYTE_VALUE:
- outb(value, chip->mixer_port + reg);
- break;
- }
+ outw(value, chip->mixer_port + reg);
+}
+
+static inline u16
+snd_azf3328_mixer_inw(const azf3328_t *chip, int reg)
+{
+ return inw(chip->mixer_port + reg);
}
-static void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
+static void
+snd_azf3328_mixer_set_mute(const azf3328_t *chip, int reg, int do_mute)
{
+ unsigned long portbase = chip->mixer_port + reg + 1;
unsigned char oldval;
/* the mute bit is on the *second* (i.e. right) register of a
* left/right channel setting */
- oldval = inb(chip->mixer_port + reg + 1);
+ oldval = inb(portbase);
if (do_mute)
oldval |= 0x80;
else
oldval &= ~0x80;
- outb(oldval, chip->mixer_port + reg + 1);
+ outb(oldval, portbase);
}
-static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
+static void
+snd_azf3328_mixer_write_volume_gradually(const azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
{
+ unsigned long portbase = chip->mixer_port + reg;
unsigned char curr_vol_left = 0, curr_vol_right = 0;
int left_done = 0, right_done = 0;
snd_azf3328_dbgcallenter();
if (chan_sel & SET_CHAN_LEFT)
- curr_vol_left = inb(chip->mixer_port + reg + 1);
+ curr_vol_left = inb(portbase + 1);
else
left_done = 1;
if (chan_sel & SET_CHAN_RIGHT)
- curr_vol_right = inb(chip->mixer_port + reg + 0);
+ curr_vol_right = inb(portbase + 0);
else
right_done = 1;
@@ -284,7 +327,7 @@ static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, u
curr_vol_left++;
else
left_done = 1;
- outb(curr_vol_left, chip->mixer_port + reg + 1);
+ outb(curr_vol_left, portbase + 1);
}
if (!right_done)
{
@@ -298,7 +341,7 @@ static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, u
/* during volume change, the right channel is crackling
* somewhat more than the left channel, unfortunately.
* This seems to be a hardware issue. */
- outb(curr_vol_right, chip->mixer_port + reg + 0);
+ outb(curr_vol_right, portbase + 0);
}
if (delay)
mdelay(delay);
@@ -320,7 +363,11 @@ typedef struct azf3328_mixer_reg {
} azf3328_mixer_reg_t;
#define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
- ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | (mask << 16) | (invert << 24) | (stereo << 25) | (enum_c << 26))
+ ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
+ (mask << 16) | \
+ (invert << 24) | \
+ (stereo << 25) | \
+ (enum_c << 26))
static void snd_azf3328_mixer_reg_decode(azf3328_mixer_reg_t *r, unsigned long val)
{
@@ -372,13 +419,15 @@ static void snd_azf3328_mixer_reg_decode(azf3328_mixer_reg_t *r, unsigned long v
.private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
}
-static int snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int
+snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
azf3328_mixer_reg_t reg;
snd_azf3328_dbgcallenter();
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->type = reg.mask == 1 ?
+ SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = reg.stereo + 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = reg.mask;
@@ -386,7 +435,8 @@ static int snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
return 0;
}
-static int snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
azf3328_t *chip = snd_kcontrol_chip(kcontrol);
azf3328_mixer_reg_t reg;
@@ -395,7 +445,7 @@ static int snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
snd_azf3328_dbgcallenter();
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- oreg = inw(chip->mixer_port + reg.reg);
+ oreg = snd_azf3328_mixer_inw(chip, reg.reg);
val = (oreg >> reg.lchan_shift) & reg.mask;
if (reg.invert)
val = reg.mask - val;
@@ -406,12 +456,17 @@ static int snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
val = reg.mask - val;
ucontrol->value.integer.value[1] = val;
}
- snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx (shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n", reg.reg, oreg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
+ snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
+ "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
+ reg.reg, oreg,
+ ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
+ reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
snd_azf3328_dbgcallleave();
return 0;
}
-static int snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
azf3328_t *chip = snd_kcontrol_chip(kcontrol);
azf3328_mixer_reg_t reg;
@@ -419,7 +474,7 @@ static int snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
snd_azf3328_dbgcallenter();
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- oreg = inw(chip->mixer_port + reg.reg);
+ oreg = snd_azf3328_mixer_inw(chip, reg.reg);
val = ucontrol->value.integer.value[0] & reg.mask;
if (reg.invert)
val = reg.mask - val;
@@ -433,24 +488,37 @@ static int snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
nreg |= (val << reg.rchan_shift);
}
if (reg.mask >= 0x07) /* it's a volume control, so better take care */
- snd_azf3328_mixer_write_volume_gradually(chip, reg.reg, nreg >> 8, nreg & 0xff, SET_CHAN_LEFT|SET_CHAN_RIGHT, 0); /* just set both channels, doesn't matter */
+ snd_azf3328_mixer_write_volume_gradually(
+ chip, reg.reg, nreg >> 8, nreg & 0xff,
+ /* just set both channels, doesn't matter */
+ SET_CHAN_LEFT|SET_CHAN_RIGHT,
+ 0);
else
- outw(nreg, chip->mixer_port + reg.reg);
+ snd_azf3328_mixer_outw(chip, reg.reg, nreg);
- snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n", reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], oreg, reg.lchan_shift, reg.rchan_shift, nreg, inw(chip->mixer_port + reg.reg));
+ snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
+ "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
+ reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
+ oreg, reg.lchan_shift, reg.rchan_shift,
+ nreg, snd_azf3328_mixer_inw(chip, reg.reg));
snd_azf3328_dbgcallleave();
return (nreg != oreg);
}
-static int snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int
+snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{
- azf3328_mixer_reg_t reg;
- static char *texts1[2] = { "ModemOut1", "ModemOut2" };
- static char *texts2[2] = { "MonoSelectSource1", "MonoSelectSource2" };
- static char *texts3[8] = {
- "Mic", "CD", "Video", "Aux", "Line",
- "Mix", "Mix Mono", "Phone"
+ static const char * const texts1[] = {
+ "ModemOut1", "ModemOut2"
+ };
+ static const char * const texts2[] = {
+ "MonoSelectSource1", "MonoSelectSource2"
+ };
+ static const char * const texts3[] = {
+ "Mic", "CD", "Video", "Aux",
+ "Line", "Mix", "Mix Mono", "Phone"
};
+ azf3328_mixer_reg_t reg;
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -471,14 +539,15 @@ static int snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_in
return 0;
}
-static int snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
- azf3328_mixer_reg_t reg;
azf3328_t *chip = snd_kcontrol_chip(kcontrol);
+ azf3328_mixer_reg_t reg;
unsigned short val;
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- val = inw(chip->mixer_port + reg.reg);
+ val = snd_azf3328_mixer_inw(chip, reg.reg);
if (reg.reg == IDX_MIXER_REC_SELECT)
{
ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
@@ -486,18 +555,22 @@ static int snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_va
}
else
ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
- snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1], reg.lchan_shift, reg.enum_c);
+
+ snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
+ reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
+ reg.lchan_shift, reg.enum_c);
return 0;
}
-static int snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
- azf3328_mixer_reg_t reg;
azf3328_t *chip = snd_kcontrol_chip(kcontrol);
+ azf3328_mixer_reg_t reg;
unsigned int oreg, nreg, val;
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
- oreg = inw(chip->mixer_port + reg.reg);
+ oreg = snd_azf3328_mixer_inw(chip, reg.reg);
val = oreg;
if (reg.reg == IDX_MIXER_REC_SELECT)
{
@@ -514,19 +587,19 @@ static int snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_va
val &= ~((reg.enum_c - 1) << reg.lchan_shift);
val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
}
- outw(val, chip->mixer_port + reg.reg);
+ snd_azf3328_mixer_outw(chip, reg.reg, val);
nreg = val;
snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
return (nreg != oreg);
}
-static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
+static const snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
AZF3328_MIXER_VOL_STEREO("Wave Playback Volume", IDX_MIXER_WAVEOUT, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Wave Playback 3D Bypass", IDX_MIXER_ADVCTL2, 7, 1),
+ AZF3328_MIXER_SWITCH("Wave 3D Bypass Playback Switch", IDX_MIXER_ADVCTL2, 7, 1),
AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
@@ -539,8 +612,8 @@ static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
- AZF3328_MIXER_SWITCH("PCBeep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
- AZF3328_MIXER_VOL_SPECIAL("PCBeep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
+ AZF3328_MIXER_SWITCH("PC Speaker Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
+ AZF3328_MIXER_VOL_SPECIAL("PC Speaker Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
@@ -553,8 +626,8 @@ static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
AZF3328_MIXER_ENUM("Mono Select Source", IDX_MIXER_ADVCTL2, 2, 9),
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
- AZF3328_MIXER_SWITCH("3D Control - Toggle", IDX_MIXER_ADVCTL2, 13, 0),
- AZF3328_MIXER_VOL_SPECIAL("3D Control - Volume", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
+ AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
+ AZF3328_MIXER_VOL_SPECIAL("3D Control - Wide", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
AZF3328_MIXER_VOL_SPECIAL("3D Control - Space", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
#if MIXER_TESTING
AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
@@ -576,9 +649,7 @@ static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
#endif
};
-#define AZF3328_INIT_VALUES (sizeof(snd_azf3328_init_values)/sizeof(unsigned int)/2)
-
-static unsigned int snd_azf3328_init_values[][2] = {
+static const u16 __devinitdata snd_azf3328_init_values[][2] = {
{ IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
{ IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
{ IDX_MIXER_BASSTREBLE, 0x0000 },
@@ -594,10 +665,11 @@ static unsigned int snd_azf3328_init_values[][2] = {
{ IDX_MIXER_REC_VOLUME, MIXER_MUTE_MASK|0x0707 },
};
-static int __devinit snd_azf3328_mixer_new(azf3328_t *chip)
+static int __devinit
+snd_azf3328_mixer_new(azf3328_t *chip)
{
snd_card_t *card;
- snd_kcontrol_new_t *sw;
+ const snd_kcontrol_new_t *sw;
unsigned int idx;
int err;
@@ -607,11 +679,13 @@ static int __devinit snd_azf3328_mixer_new(azf3328_t *chip)
card = chip->card;
/* mixer reset */
- snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
+ snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
/* mute and zero volume channels */
- for (idx = 0; idx < AZF3328_INIT_VALUES; idx++) {
- snd_azf3328_mixer_write(chip, snd_azf3328_init_values[idx][0], snd_azf3328_init_values[idx][1], WORD_VALUE);
+ for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); idx++) {
+ snd_azf3328_mixer_outw(chip,
+ snd_azf3328_init_values[idx][0],
+ snd_azf3328_init_values[idx][1]);
}
/* add mixer controls */
@@ -627,7 +701,8 @@ static int __devinit snd_azf3328_mixer_new(azf3328_t *chip)
return 0;
}
-static int snd_azf3328_hw_params(snd_pcm_substream_t * substream,
+static int
+snd_azf3328_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params)
{
int res;
@@ -637,7 +712,8 @@ static int snd_azf3328_hw_params(snd_pcm_substream_t * substream,
return res;
}
-static int snd_azf3328_hw_free(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_hw_free(snd_pcm_substream_t * substream)
{
snd_azf3328_dbgcallenter();
snd_pcm_lib_free_pages(substream);
@@ -645,43 +721,48 @@ static int snd_azf3328_hw_free(snd_pcm_substream_t * substream)
return 0;
}
-static void snd_azf3328_setfmt(azf3328_t *chip,
+static void
+snd_azf3328_setfmt(azf3328_t *chip,
unsigned int reg,
unsigned int bitrate,
unsigned int format_width,
unsigned int channels
)
{
- unsigned int val = 0xff00;
+ u16 val = 0xff00;
unsigned long flags;
snd_azf3328_dbgcallenter();
switch (bitrate) {
- case 5512: val |= 0x0d; break; /* the AZF3328 names it "5510" for some strange reason */
- case 6620: val |= 0x0b; break;
- case 8000: val |= 0x00; break;
- case 9600: val |= 0x08; break;
- case 11025: val |= 0x01; break;
- case 16000: val |= 0x02; break;
- case 22050: val |= 0x03; break;
- case 32000: val |= 0x04; break;
- case 44100: val |= 0x05; break;
- case 48000: val |= 0x06; break;
- case 64000: val |= 0x07; break;
+ case 4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
+ case 4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
+ case 5512: val |= SOUNDFORMAT_FREQ_5510; break; /* the AZF3328 names it "5510" for some strange reason */
+ case 6620: val |= SOUNDFORMAT_FREQ_6620; break;
+ case 8000: val |= SOUNDFORMAT_FREQ_8000; break;
+ case 9600: val |= SOUNDFORMAT_FREQ_9600; break;
+ case 11025: val |= SOUNDFORMAT_FREQ_11025; break;
+ case 13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
+ case 16000: val |= SOUNDFORMAT_FREQ_16000; break;
+ case 22050: val |= SOUNDFORMAT_FREQ_22050; break;
+ case 32000: val |= SOUNDFORMAT_FREQ_32000; break;
+ case 44100: val |= SOUNDFORMAT_FREQ_44100; break;
+ case 48000: val |= SOUNDFORMAT_FREQ_48000; break;
+ case 66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
default:
- snd_printk("unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
- val |= 0x05; /* 44100 */
+ snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
+ val |= SOUNDFORMAT_FREQ_44100;
break;
}
- /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) */
- /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) */
- /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) */
- /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) */
+ /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
+ /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
+ /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
+ /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
/* val = 0xff05; 5m11.556s (... -> 44100Hz) */
/* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
/* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
/* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
/* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
+
if (channels == 2)
val |= SOUNDFORMAT_FLAG_2CHANNELS;
@@ -691,7 +772,7 @@ static void snd_azf3328_setfmt(azf3328_t *chip,
spin_lock_irqsave(&chip->reg_lock, flags);
/* set bitrate/format */
- outw(val, chip->codec_port+reg);
+ snd_azf3328_codec_outw(chip, reg, val);
/* changing the bitrate/format settings switches off the
* audio output with an annoying click in case of 8/16bit format change
@@ -701,47 +782,67 @@ static void snd_azf3328_setfmt(azf3328_t *chip,
* FIXME: does this have some side effects for full-duplex
* or other dramatic side effects? */
if (reg == IDX_IO_PLAY_SOUNDFORMAT) /* only do it for playback */
- outw(inw(chip->codec_port + IDX_IO_PLAY_FLAGS)|DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) |
+ DMA_PLAY_SOMETHING1 |
+ DMA_PLAY_SOMETHING2 |
+ SOMETHING_ALMOST_ALWAYS_SET |
+ DMA_EPILOGUE_SOMETHING |
+ DMA_SOMETHING_ELSE
+ );
spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_azf3328_dbgcallleave();
}
-static void snd_azf3328_setdmaa(azf3328_t *chip,
+static void
+snd_azf3328_setdmaa(azf3328_t *chip,
long unsigned int addr,
unsigned int count,
unsigned int size,
int do_recording)
{
- long unsigned int addr1;
- long unsigned int addr2;
- unsigned int count1;
- unsigned int count2;
- unsigned long flags;
- int reg_offs = do_recording ? 0x20 : 0x00;
+ unsigned long flags, portbase;
+ unsigned int is_running;
snd_azf3328_dbgcallenter();
+ if (do_recording)
+ {
+ /* access capture registers, i.e. skip playback reg section */
+ portbase = chip->codec_port + 0x20;
+ is_running = chip->is_recording;
+ }
+ else
+ {
+ /* access the playback register section */
+ portbase = chip->codec_port + 0x00;
+ is_running = chip->is_playing;
+ }
+
/* AZF3328 uses a two buffer pointer DMA playback approach */
- if (!chip->is_playing)
+ if (!is_running)
{
- addr1 = addr;
- addr2 = addr+(size/2);
- count1 = (size/2)-1;
- count2 = (size/2)-1;
-#if DEBUG_PLAY_REC
- snd_azf3328_dbgplay("setting dma: buf1 %08lx[%d], buf2 %08lx[%d]\n", addr1, count1, addr2, count2);
-#endif
+ unsigned long addr_area2;
+ unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */
+ count_areas = size/2;
+ addr_area2 = addr+count_areas;
+ count_areas--; /* max. index */
+ snd_azf3328_dbgplay("set DMA: buf1 %08lx[%lu], buf2 %08lx[%lu]\n", addr, count_areas, addr_area2, count_areas);
+
+ /* build combined I/O buffer length word */
+ count_tmp = count_areas;
+ count_areas |= (count_tmp << 16);
spin_lock_irqsave(&chip->reg_lock, flags);
- outl(addr1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_1);
- outl(addr2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_2);
- outw(count1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_1);
- outw(count2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_2);
+ outl(addr, portbase + IDX_IO_PLAY_DMA_START_1);
+ outl(addr_area2, portbase + IDX_IO_PLAY_DMA_START_2);
+ outl(count_areas, portbase + IDX_IO_PLAY_DMA_LEN_1);
spin_unlock_irqrestore(&chip->reg_lock, flags);
}
snd_azf3328_dbgcallleave();
}
-static int snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
+static int
+snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
{
#if 0
azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -752,14 +853,18 @@ static int snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
snd_azf3328_dbgcallenter();
#if 0
- snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+ snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+ runtime->rate,
+ snd_pcm_format_width(runtime->format),
+ runtime->channels);
snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 0);
#endif
snd_azf3328_dbgcallleave();
return 0;
}
-static int snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
{
#if 0
azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -770,14 +875,18 @@ static int snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
snd_azf3328_dbgcallenter();
#if 0
- snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+ snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+ runtime->rate,
+ snd_pcm_format_width(runtime->format),
+ runtime->channels);
snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 1);
#endif
snd_azf3328_dbgcallleave();
return 0;
}
-static int snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
+static int
+snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -785,79 +894,98 @@ static int snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd
unsigned int status1;
snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
+
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
-
- snd_azf3328_dbgio(chip, "trigger1");
+ snd_azf3328_dbgplay("START PLAYBACK\n");
/* mute WaveOut */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
- snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+ snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+ runtime->rate,
+ snd_pcm_format_width(runtime->format),
+ runtime->channels);
spin_lock(&chip->reg_lock);
/* stop playback */
- status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
+ status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
status1 &= ~DMA_RESUME;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
/* FIXME: clear interrupts or what??? */
- outw(0xffff, chip->codec_port+IDX_IO_PLAY_IRQMASK);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
spin_unlock(&chip->reg_lock);
- snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 0);
+ snd_azf3328_setdmaa(chip, runtime->dma_addr,
+ snd_pcm_lib_period_bytes(substream),
+ snd_pcm_lib_buffer_bytes(substream),
+ 0);
spin_lock(&chip->reg_lock);
#ifdef WIN9X
/* FIXME: enable playback/recording??? */
status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
/* start playback again */
/* FIXME: what is this value (0x0010)??? */
status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
#else /* NT4 */
- outw(0x00, chip->codec_port+IDX_IO_PLAY_FLAGS);
- outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_PLAY_FLAGS);
- outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_PLAY_FLAGS);
- outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ 0x0000);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ DMA_PLAY_SOMETHING1);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ DMA_PLAY_SOMETHING1 |
+ DMA_PLAY_SOMETHING2);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+ DMA_RESUME |
+ SOMETHING_ALMOST_ALWAYS_SET |
+ DMA_EPILOGUE_SOMETHING |
+ DMA_SOMETHING_ELSE);
#endif
spin_unlock(&chip->reg_lock);
/* now unmute WaveOut */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
- snd_azf3328_dbgio(chip, "trigger2");
chip->is_playing = 1;
+ snd_azf3328_dbgplay("STARTED PLAYBACK\n");
break;
- case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_STOP:
+ snd_azf3328_dbgplay("STOP PLAYBACK\n");
+
/* mute WaveOut */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
spin_lock(&chip->reg_lock);
/* stop playback */
- status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
+ status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
status1 &= ~DMA_RESUME;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
+ /* hmm, is this really required? we're resetting the same bit
+ * immediately thereafter... */
status1 |= DMA_PLAY_SOMETHING1;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
status1 &= ~DMA_PLAY_SOMETHING1;
- outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
spin_unlock(&chip->reg_lock);
/* now unmute WaveOut */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
chip->is_playing = 0;
+ snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
+ snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
+ snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
break;
default:
return -EINVAL;
@@ -869,7 +997,8 @@ static int snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd
/* this is just analogous to playback; I'm not quite sure whether recording
* should actually be triggered like that */
-static int snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
+static int
+snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -877,68 +1006,86 @@ static int snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
unsigned int status1;
snd_azf3328_dbgcalls("snd_azf3328_capture_trigger cmd %d\n", cmd);
+
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- snd_azf3328_dbgio(chip, "trigger1");
+ snd_azf3328_dbgplay("START CAPTURE\n");
- snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+ snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+ runtime->rate,
+ snd_pcm_format_width(runtime->format),
+ runtime->channels);
spin_lock(&chip->reg_lock);
/* stop recording */
- status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
+ status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
status1 &= ~DMA_RESUME;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
/* FIXME: clear interrupts or what??? */
- outw(0xffff, chip->codec_port+IDX_IO_REC_IRQMASK);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
spin_unlock(&chip->reg_lock);
- snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 1);
+ snd_azf3328_setdmaa(chip, runtime->dma_addr,
+ snd_pcm_lib_period_bytes(substream),
+ snd_pcm_lib_buffer_bytes(substream),
+ 1);
spin_lock(&chip->reg_lock);
#ifdef WIN9X
/* FIXME: enable playback/recording??? */
status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
- /* start playback again */
+ /* start capture again */
/* FIXME: what is this value (0x0010)??? */
status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
#else
- outw(0x00, chip->codec_port+IDX_IO_REC_FLAGS);
- outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_REC_FLAGS);
- outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_REC_FLAGS);
- outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+ 0x0000);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+ DMA_PLAY_SOMETHING1);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+ DMA_PLAY_SOMETHING1 |
+ DMA_PLAY_SOMETHING2);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+ DMA_RESUME |
+ SOMETHING_ALMOST_ALWAYS_SET |
+ DMA_EPILOGUE_SOMETHING |
+ DMA_SOMETHING_ELSE);
#endif
spin_unlock(&chip->reg_lock);
- snd_azf3328_dbgio(chip, "trigger2");
- chip->is_playing = 1;
+ chip->is_recording = 1;
+ snd_azf3328_dbgplay("STARTED CAPTURE\n");
break;
case SNDRV_PCM_TRIGGER_STOP:
+ snd_azf3328_dbgplay("STOP CAPTURE\n");
+
spin_lock(&chip->reg_lock);
/* stop recording */
- status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
+ status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
status1 &= ~DMA_RESUME;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
status1 |= DMA_PLAY_SOMETHING1;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
status1 &= ~DMA_PLAY_SOMETHING1;
- outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+ snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
spin_unlock(&chip->reg_lock);
- chip->is_playing = 0;
+ chip->is_recording = 0;
+ snd_azf3328_dbgplay("STOPPED CAPTURE\n");
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
+ snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
+ snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
break;
default:
return -EINVAL;
@@ -948,11 +1095,11 @@ static int snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
return result;
}
-static snd_pcm_uframes_t snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t
+snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
- unsigned long bufptr, playptr;
- unsigned long result;
+ unsigned long bufptr, result;
snd_pcm_uframes_t frmres;
#ifdef QUERY_HARDWARE
@@ -960,19 +1107,20 @@ static snd_pcm_uframes_t snd_azf3328_playback_pointer(snd_pcm_substream_t * subs
#else
bufptr = substream->runtime->dma_addr;
#endif
- playptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
+ result = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
- result = playptr - bufptr;
- frmres = bytes_to_frames( substream->runtime, result );
- snd_azf3328_dbgplay("result %lx, playptr %lx (base %x), frames %ld\n", result, playptr, substream->runtime->dma_addr, frmres);
+ /* calculate offset */
+ result -= bufptr;
+ frmres = bytes_to_frames( substream->runtime, result);
+ snd_azf3328_dbgplay("PLAY @ 0x%8lx, frames %8ld\n", result, frmres);
return frmres;
}
-static snd_pcm_uframes_t snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t
+snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
- unsigned long bufptr, recptr;
- unsigned long result;
+ unsigned long bufptr, result;
snd_pcm_uframes_t frmres;
#ifdef QUERY_HARDWARE
@@ -980,96 +1128,116 @@ static snd_pcm_uframes_t snd_azf3328_capture_pointer(snd_pcm_substream_t * subst
#else
bufptr = substream->runtime->dma_addr;
#endif
- recptr = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
+ result = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
- result = recptr - bufptr;
- frmres = bytes_to_frames( substream->runtime, result );
- snd_azf3328_dbgplay("result %lx, rec ptr %lx (base %x), frames %ld\n", result, recptr, substream->runtime->dma_addr, frmres);
+ /* calculate offset */
+ result -= bufptr;
+ frmres = bytes_to_frames( substream->runtime, result);
+ snd_azf3328_dbgplay("REC @ 0x%8lx, frames %8ld\n", result, frmres);
return frmres;
}
-static irqreturn_t snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t
+snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
azf3328_t *chip = dev_id;
- unsigned int status, which;
- static unsigned long count;
+ u8 status, which;
+ static unsigned long irq_count;
- status = inw(chip->codec_port+IDX_IO_IRQSTATUS);
+ status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
/* fast path out, to ease interrupt sharing */
- if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_SOMEIRQ)))
+ if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_TIMER)))
return IRQ_NONE; /* must be interrupt for another device */
- snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", count, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS));
+ snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
+ irq_count,
+ snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
+ snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
+ status);
+ if (status & IRQ_TIMER)
+ {
+ /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */
+ if (chip->timer)
+ snd_timer_interrupt(chip->timer, chip->timer->sticks);
+ /* ACK timer */
+ spin_lock(&chip->reg_lock);
+ snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
+ spin_unlock(&chip->reg_lock);
+ snd_azf3328_dbgplay("azt3328: timer IRQ\n");
+ }
if (status & IRQ_PLAYBACK)
{
spin_lock(&chip->reg_lock);
- which = inw(chip->codec_port+IDX_IO_PLAY_IRQMASK);
- if (which & IRQ_FINISHED_PLAYBUF_1)
- /* ack IRQ */
- outw(which | IRQ_FINISHED_PLAYBUF_1, chip->codec_port+IDX_IO_PLAY_IRQMASK);
- if (which & IRQ_FINISHED_PLAYBUF_2)
- /* ack IRQ */
- outw(which | IRQ_FINISHED_PLAYBUF_2, chip->codec_port+IDX_IO_PLAY_IRQMASK);
- if (which & IRQ_PLAY_SOMETHING)
- {
- snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
- }
+ which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
+ /* ack all IRQ types immediately */
+ snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
+ spin_unlock(&chip->reg_lock);
+
if (chip->pcm && chip->playback_substream)
{
- snd_azf3328_dbgplay("which %x, playptr %lx\n", which, inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
snd_pcm_period_elapsed(chip->playback_substream);
- snd_azf3328_dbgplay("period done, playptr %lx.\n", inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
+ snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
+ which,
+ inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
}
else
snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
- spin_unlock(&chip->reg_lock);
+ if (which & IRQ_PLAY_SOMETHING)
+ snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
}
if (status & IRQ_RECORDING)
{
spin_lock(&chip->reg_lock);
- which = inw(chip->codec_port+IDX_IO_REC_IRQMASK);
- if (which & IRQ_FINISHED_RECBUF_1)
- /* ack interrupt */
- outw(which | IRQ_FINISHED_RECBUF_1, chip->codec_port+IDX_IO_REC_IRQMASK);
- if (which & IRQ_FINISHED_RECBUF_2)
- /* ack interrupt */
- outw(which | IRQ_FINISHED_RECBUF_2, chip->codec_port+IDX_IO_REC_IRQMASK);
- if (which & IRQ_REC_SOMETHING)
- {
- snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
- }
+ which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
+ /* ack all IRQ types immediately */
+ snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
+ spin_unlock(&chip->reg_lock);
+
if (chip->pcm && chip->capture_substream)
{
- snd_azf3328_dbgplay("which %x, recptr %lx\n", which, inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
- spin_unlock(&chip->reg_lock);
snd_pcm_period_elapsed(chip->capture_substream);
- spin_lock(&chip->reg_lock);
- snd_azf3328_dbgplay("period done, recptr %lx.\n", inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
+ snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
+ which,
+ inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
}
- spin_unlock(&chip->reg_lock);
+ else
+ snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
+ if (which & IRQ_REC_SOMETHING)
+ snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
}
+ /* MPU401 has less critical IRQ requirements
+ * than timer and playback/recording, right? */
if (status & IRQ_MPU401)
+ {
snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
- if (status & IRQ_SOMEIRQ)
- snd_azf3328_dbgplay("azt3328: unknown IRQ type occurred, please report!\n");
- count++;
+
+ /* hmm, do we have to ack the IRQ here somehow?
+ * If so, then I don't know how... */
+ snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
+ }
+ irq_count++;
return IRQ_HANDLED;
}
/*****************************************************************/
-static snd_pcm_hardware_t snd_azf3328_playback =
+static const snd_pcm_hardware_t snd_azf3328_playback =
{
/* FIXME!! Correct? */
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
- .rate_min = 5512,
- .rate_max = 64000,
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .formats = SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE,
+ .rates = SNDRV_PCM_RATE_5512 |
+ SNDRV_PCM_RATE_8000_48000 |
+ SNDRV_PCM_RATE_KNOT,
+ .rate_min = 4000,
+ .rate_max = 66200,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = 65536,
@@ -1083,16 +1251,21 @@ static snd_pcm_hardware_t snd_azf3328_playback =
.fifo_size = 0,
};
-static snd_pcm_hardware_t snd_azf3328_capture =
+static const snd_pcm_hardware_t snd_azf3328_capture =
{
/* FIXME */
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
- .rate_min = 5512,
- .rate_max = 64000,
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .formats = SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE,
+ .rates = SNDRV_PCM_RATE_5512 |
+ SNDRV_PCM_RATE_8000_48000 |
+ SNDRV_PCM_RATE_KNOT,
+ .rate_min = 4000,
+ .rate_max = 66200,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = 65536,
@@ -1105,8 +1278,8 @@ static snd_pcm_hardware_t snd_azf3328_capture =
static unsigned int snd_azf3328_fixed_rates[] = {
- 5512, 6620, 8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000, 64000
-};
+ 4000, 4800, 5512, 6620, 8000, 9600, 11025, 13240, 16000, 22050, 32000,
+ 44100, 48000, 66200 };
static snd_pcm_hw_constraint_list_t snd_azf3328_hw_constraints_rates = {
.count = ARRAY_SIZE(snd_azf3328_fixed_rates),
.list = snd_azf3328_fixed_rates,
@@ -1115,7 +1288,8 @@ static snd_pcm_hw_constraint_list_t snd_azf3328_hw_constraints_rates = {
/*****************************************************************/
-static int snd_azf3328_playback_open(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_playback_open(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1129,7 +1303,8 @@ static int snd_azf3328_playback_open(snd_pcm_substream_t * substream)
return 0;
}
-static int snd_azf3328_capture_open(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_open(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1143,7 +1318,8 @@ static int snd_azf3328_capture_open(snd_pcm_substream_t * substream)
return 0;
}
-static int snd_azf3328_playback_close(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_playback_close(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -1154,7 +1330,8 @@ static int snd_azf3328_playback_close(snd_pcm_substream_t * substream)
return 0;
}
-static int snd_azf3328_capture_close(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_close(snd_pcm_substream_t * substream)
{
azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -1188,14 +1365,16 @@ static snd_pcm_ops_t snd_azf3328_capture_ops = {
.pointer = snd_azf3328_capture_pointer
};
-static void snd_azf3328_pcm_free(snd_pcm_t *pcm)
+static void
+snd_azf3328_pcm_free(snd_pcm_t *pcm)
{
azf3328_t *chip = pcm->private_data;
chip->pcm = NULL;
snd_pcm_lib_preallocate_free_for_all(pcm);
}
-static int __devinit snd_azf3328_pcm(azf3328_t *chip, int device)
+static int __devinit
+snd_azf3328_pcm(azf3328_t *chip, int device)
{
snd_pcm_t *pcm;
int err;
@@ -1222,7 +1401,8 @@ static int __devinit snd_azf3328_pcm(azf3328_t *chip, int device)
/******************************************************************/
#ifdef SUPPORT_JOYSTICK
-static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev)
+static int __devinit
+snd_azf3328_config_joystick(azf3328_t *chip, int dev)
{
struct gameport *gp;
struct resource *r;
@@ -1238,8 +1418,7 @@ static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev)
chip->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -1249,15 +1428,16 @@ static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev)
gp->io = 0x200;
gameport_set_port_data(gp, r);
- snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
- snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
+ snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+ snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
gameport_register_port(chip->gameport);
return 0;
}
-static void snd_azf3328_free_joystick(azf3328_t *chip)
+static void
+snd_azf3328_free_joystick(azf3328_t *chip)
{
if (chip->gameport) {
struct resource *r = gameport_get_port_data(chip->gameport);
@@ -1265,33 +1445,36 @@ static void snd_azf3328_free_joystick(azf3328_t *chip)
gameport_unregister_port(chip->gameport);
chip->gameport = NULL;
/* disable gameport */
- snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
- snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
- release_resource(r);
- kfree_nocheck(r);
+ snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+ snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
+ release_and_free_resource(r);
}
}
#else
-static inline int snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
-static inline void snd_azf3328_free_joystick(azf3328_t *chip) { }
+static inline int
+snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
+static inline void
+snd_azf3328_free_joystick(azf3328_t *chip) { }
#endif
/******************************************************************/
-static int snd_azf3328_free(azf3328_t *chip)
+static int
+snd_azf3328_free(azf3328_t *chip)
{
if (chip->irq < 0)
goto __end_hw;
/* reset (close) mixer */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */
- snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
+ snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
- /* interrupt setup - mask everything */
- /* FIXME */
+ /* interrupt setup - mask everything (FIXME!) */
+ /* well, at least we know how to disable the timer IRQ */
+ snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00);
synchronize_irq(chip->irq);
- __end_hw:
+__end_hw:
snd_azf3328_free_joystick(chip);
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
@@ -1302,15 +1485,129 @@ static int snd_azf3328_free(azf3328_t *chip)
return 0;
}
-static int snd_azf3328_dev_free(snd_device_t *device)
+static int
+snd_azf3328_dev_free(snd_device_t *device)
{
azf3328_t *chip = device->device_data;
return snd_azf3328_free(chip);
}
+/******************************************************************/
+
+/*** NOTE: the physical timer resolution actually is 1024000 ticks per second,
+ *** but announcing those attributes to user-space would make programs
+ *** configure the timer to a 1 tick value, resulting in an absolutely fatal
+ *** timer IRQ storm.
+ *** Thus I chose to announce a down-scaled virtual timer to the outside and
+ *** calculate real timer countdown values internally.
+ *** (the scale factor can be set via module parameter "seqtimer_scaling").
+ ***/
+
+static int
+snd_azf3328_timer_start(snd_timer_t *timer)
+{
+ azf3328_t *chip;
+ unsigned long flags;
+ unsigned int delay;
+
+ snd_azf3328_dbgcallenter();
+ chip = snd_timer_chip(timer);
+ delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
+ if (delay < 49)
+ {
+ /* uhoh, that's not good, since user-space won't know about
+ * this timing tweak
+ * (we need to do it to avoid a lockup, though) */
+
+ snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
+ delay = 49; /* minimum time is 49 ticks */
+ }
+ snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
+ delay |= TIMER_ENABLE_COUNTDOWN | TIMER_ENABLE_IRQ;
+ spin_lock_irqsave(&chip->reg_lock, flags);
+ snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
+ spin_unlock_irqrestore(&chip->reg_lock, flags);
+ snd_azf3328_dbgcallleave();
+ return 0;
+}
+
+static int
+snd_azf3328_timer_stop(snd_timer_t *timer)
+{
+ azf3328_t *chip;
+ unsigned long flags;
+
+ snd_azf3328_dbgcallenter();
+ chip = snd_timer_chip(timer);
+ spin_lock_irqsave(&chip->reg_lock, flags);
+ /* disable timer countdown and interrupt */
+ /* FIXME: should we write TIMER_ACK_IRQ here? */
+ snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
+ spin_unlock_irqrestore(&chip->reg_lock, flags);
+ snd_azf3328_dbgcallleave();
+ return 0;
+}
+
+
+static int
+snd_azf3328_timer_precise_resolution(snd_timer_t *timer,
+ unsigned long *num, unsigned long *den)
+{
+ snd_azf3328_dbgcallenter();
+ *num = 1;
+ *den = 1024000 / seqtimer_scaling;
+ snd_azf3328_dbgcallleave();
+ return 0;
+}
+
+static struct _snd_timer_hardware snd_azf3328_timer_hw = {
+ .flags = SNDRV_TIMER_HW_AUTO,
+ .resolution = 977, /* 1000000/1024000 = 0.9765625us */
+ .ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
+ .start = snd_azf3328_timer_start,
+ .stop = snd_azf3328_timer_stop,
+ .precise_resolution = snd_azf3328_timer_precise_resolution,
+};
+
+static int __devinit
+snd_azf3328_timer(azf3328_t *chip, int device)
+{
+ snd_timer_t *timer = NULL;
+ snd_timer_id_t tid;
+ int err;
+
+ snd_azf3328_dbgcallenter();
+ tid.dev_class = SNDRV_TIMER_CLASS_CARD;
+ tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
+ tid.card = chip->card->number;
+ tid.device = device;
+ tid.subdevice = 0;
+
+ snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
+ snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
+ if ((err = snd_timer_new(chip->card, "AZF3328", &tid, &timer)) < 0) {
+ goto out;
+ }
+
+ strcpy(timer->name, "AZF3328 timer");
+ timer->private_data = chip;
+ timer->hw = snd_azf3328_timer_hw;
+
+ chip->timer = timer;
+
+ err = 0;
+
+out:
+ snd_azf3328_dbgcallleave();
+ return err;
+}
+
+/******************************************************************/
+
#if 0
/* check whether a bit can be modified */
-static void snd_azf3328_test_bit(unsigned int reg, int bit)
+static void
+snd_azf3328_test_bit(unsigned int reg, int bit)
{
unsigned char val, valoff, valon;
@@ -1328,7 +1625,26 @@ static void snd_azf3328_test_bit(unsigned int reg, int bit)
}
#endif
-static int __devinit snd_azf3328_create(snd_card_t * card,
+static void
+snd_azf3328_debug_show_ports(const azf3328_t *chip)
+{
+#if DEBUG_MISC
+ u16 tmp;
+
+ snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
+
+ snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_inb(chip, 0), snd_azf3328_io2_inb(chip, 1), snd_azf3328_io2_inb(chip, 2), snd_azf3328_io2_inb(chip, 3), snd_azf3328_io2_inb(chip, 4), snd_azf3328_io2_inb(chip, 5));
+
+ for (tmp=0; tmp <= 0x01; tmp += 1)
+ snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
+
+ for (tmp = 0; tmp <= 0x6E; tmp += 2)
+ snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp));
+#endif
+}
+
+static int __devinit
+snd_azf3328_create(snd_card_t * card,
struct pci_dev *pci,
unsigned long device_type,
azf3328_t ** rchip)
@@ -1347,8 +1663,8 @@ static int __devinit snd_azf3328_create(snd_card_t * card,
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto out_err;
}
spin_lock_init(&chip->reg_lock);
chip->card = card;
@@ -1358,47 +1674,39 @@ static int __devinit snd_azf3328_create(snd_card_t * card,
/* check if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
- snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
- pci_disable_device(pci);
- return -ENXIO;
+ snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
+ err = -ENXIO;
+ goto out_err;
}
if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) {
- kfree(chip);
- pci_disable_device(pci);
- return err;
+ goto out_err;
}
chip->codec_port = pci_resource_start(pci, 0);
- chip->io2_port = pci_resource_start(pci, 1);
- chip->mpu_port = pci_resource_start(pci, 2);
+ chip->io2_port = pci_resource_start(pci, 1);
+ chip->mpu_port = pci_resource_start(pci, 2);
chip->synth_port = pci_resource_start(pci, 3);
chip->mixer_port = pci_resource_start(pci, 4);
if (request_irq(pci->irq, snd_azf3328_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
- snd_azf3328_free(chip);
- return -EBUSY;
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+ err = -EBUSY;
+ goto out_err;
}
chip->irq = pci->irq;
pci_set_master(pci);
synchronize_irq(chip->irq);
- snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
-
- snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_read(chip, 0), snd_azf3328_io2_read(chip, 1), snd_azf3328_io2_read(chip, 2), snd_azf3328_io2_read(chip, 3), snd_azf3328_io2_read(chip, 4), snd_azf3328_io2_read(chip, 5));
-
- for (tmp=0; tmp <= 0x01; tmp += 1)
- snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
-
+ snd_azf3328_debug_show_ports(chip);
+
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_azf3328_free(chip);
- return err;
+ goto out_err;
}
/* create mixer interface & switches */
if ((err = snd_azf3328_mixer_new(chip)) < 0)
- return err;
+ goto out_err;
#if 0
/* set very low bitrate to reduce noise and power consumption? */
@@ -1406,22 +1714,34 @@ static int __devinit snd_azf3328_create(snd_card_t * card,
#endif
/* standard chip init stuff */
- spin_lock_irq(&chip->reg_lock);
- outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
- outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_SOMETHING_FLAGS);
- outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_REC_FLAGS);
- outb(0x0, chip->codec_port + IDX_IO_IRQ63H);
+ /* default IRQ init value */
+ tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
+ spin_lock_irq(&chip->reg_lock);
+ snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
+ snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
+ snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
+ snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); /* disable timer */
spin_unlock_irq(&chip->reg_lock);
snd_card_set_dev(card, &pci->dev);
*rchip = chip;
- return 0;
+
+ err = 0;
+ goto out;
+
+out_err:
+ if (chip)
+ snd_azf3328_free(chip);
+ pci_disable_device(pci);
+
+out:
+ return err;
}
-static int __devinit snd_azf3328_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
+static int __devinit
+snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
{
static int dev;
snd_card_t *card;
@@ -1445,63 +1765,70 @@ static int __devinit snd_azf3328_probe(struct pci_dev *pci,
strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) {
- snd_card_free(card);
- return err;
+ goto out_err;
}
if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,
chip->mpu_port, 1, pci->irq, 0,
&chip->rmidi)) < 0) {
- snd_printk("azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
- snd_card_free(card);
- return err;
+ snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
+ goto out_err;
+ }
+
+ if ((err = snd_azf3328_timer(chip, 0)) < 0) {
+ goto out_err;
}
if ((err = snd_azf3328_pcm(chip, 0)) < 0) {
- snd_card_free(card);
- return err;
+ goto out_err;
}
if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2,
OPL3_HW_AUTO, 1, &opl3) < 0) {
- snd_printk("azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
+ snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
chip->synth_port, chip->synth_port+2 );
} else {
if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
- snd_card_free(card);
- return err;
+ goto out_err;
}
}
- snd_azf3328_dbgio(chip, "create");
-
sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, chip->codec_port, chip->irq);
if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
+ goto out_err;
}
#ifdef MODULE
printk(
-"azt3328: Experimental driver for Aztech AZF3328-based soundcards such as PCI168.\n"
-"azt3328: ZERO support from Aztech: you might think hard about future purchase.\n"
-"azt3328: Feel free to contact hw7oshyuv3001@sneakemail.com for bug reports etc.!\n");
+"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n"
+"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n"
+"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
+"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
+ 1024000 / seqtimer_scaling, seqtimer_scaling);
#endif
if (snd_azf3328_config_joystick(chip, dev) < 0)
- snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
- snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
+ snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+ snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
pci_set_drvdata(pci, card);
dev++;
+ err = 0;
+ goto out;
+
+out_err:
+ snd_card_free(card);
+
+out:
snd_azf3328_dbgcallleave();
- return 0;
+ return err;
}
-static void __devexit snd_azf3328_remove(struct pci_dev *pci)
+static void __devexit
+snd_azf3328_remove(struct pci_dev *pci)
{
snd_azf3328_dbgcallenter();
snd_card_free(pci_get_drvdata(pci));
@@ -1517,7 +1844,8 @@ static struct pci_driver driver = {
.remove = __devexit_p(snd_azf3328_remove),
};
-static int __init alsa_card_azf3328_init(void)
+static int __init
+alsa_card_azf3328_init(void)
{
int err;
snd_azf3328_dbgcallenter();
@@ -1526,7 +1854,8 @@ static int __init alsa_card_azf3328_init(void)
return err;
}
-static void __exit alsa_card_azf3328_exit(void)
+static void __exit
+alsa_card_azf3328_exit(void)
{
snd_azf3328_dbgcallenter();
pci_unregister_driver(&driver);
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index 7e0e79180977..f489bdaf6d40 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -1,19 +1,17 @@
-#ifndef __SOUND_AZF3328_H
-#define __SOUND_AZF3328_H
+#ifndef __SOUND_AZT3328_H
+#define __SOUND_AZT3328_H
-/* type argument to use for the I/O functions */
-#define WORD_VALUE 0x1000
-#define DWORD_VALUE 0x2000
-#define BYTE_VALUE 0x4000
+/* "PU" == "power-up value", as tested on PCI168 PCI rev. 10 */
/*** main I/O area port indices ***/
/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
-/* the driver initialisation suggests a layout of 3 main areas:
- * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe DirectX
- * timer ???). and probably another area from 0x60 to 0x6f
- * (IRQ management, power management etc. ???). */
-/* playback area */
-#define IDX_IO_PLAY_FLAGS 0x00
+/* the driver initialisation suggests a layout of 4 main areas:
+ * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??).
+ * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
+ * power management etc.???). */
+
+/** playback area **/
+#define IDX_IO_PLAY_FLAGS 0x00 /* PU:0x0000 */
/* able to reactivate output after output muting due to 8/16bit
* output change, just like 0x0002.
* 0x0001 is the only bit that's able to start the DMA counter */
@@ -29,7 +27,7 @@
#define DMA_EPILOGUE_SOMETHING 0x0010
#define DMA_SOMETHING_ELSE 0x0020 /* ??? */
#define SOMETHING_UNMODIFIABLE 0xffc0 /* unused ? not modifiable */
-#define IDX_IO_PLAY_IRQMASK 0x02
+#define IDX_IO_PLAY_IRQTYPE 0x02 /* PU:0x0001 */
/* write back to flags in case flags are set, in order to ACK IRQ in handler
* (bit 1 of port 0x64 indicates interrupt for one of these three types)
* sometimes in this case it just writes 0xffff to globally ACK all IRQs
@@ -41,36 +39,39 @@
#define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
#define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
#define IRQMASK_UNMODIFIABLE 0xffe0 /* unused ? not modifiable */
-#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area */
-#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area */
-#define IDX_IO_PLAY_DMA_LEN_1 0x0c /* length of 1st DMA play area */
-#define IDX_IO_PLAY_DMA_LEN_2 0x0e /* length of 2nd DMA play area */
-#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position */
-#define IDX_IO_PLAY_DMA_CURROFS 0x14 /* offset within current DMA play area */
-#define IDX_IO_PLAY_SOUNDFORMAT 0x16
+#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_LEN_1 0x0c /* length of 1st DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_DMA_LEN_2 0x0e /* length of 2nd DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_CURROFS 0x14 /* offset within current DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_SOUNDFORMAT 0x16 /* PU:0x0010 */
/* all unspecified bits can't be modified */
#define SOUNDFORMAT_FREQUENCY_MASK 0x000f
+ #define SOUNDFORMAT_XTAL1 0x00
+ #define SOUNDFORMAT_XTAL2 0x01
/* all _SUSPECTED_ values are not used by Windows drivers, so we don't
* have any hard facts, only rough measurements */
- #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c
- #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a
- #define SOUNDFORMAT_FREQ_5510 0x0d
- #define SOUNDFORMAT_FREQ_6620 0x0b
- #define SOUNDFORMAT_FREQ_8000 0x00 /* also 0x0e ? */
- #define SOUNDFORMAT_FREQ_9600 0x08
- #define SOUNDFORMAT_FREQ_SUSPECTED_12000 0x09
- #define SOUNDFORMAT_FREQ_11025 0x01 /* also 0x0f ? */
- #define SOUNDFORMAT_FREQ_16000 0x02
- #define SOUNDFORMAT_FREQ_22050 0x03
- #define SOUNDFORMAT_FREQ_32000 0x04
- #define SOUNDFORMAT_FREQ_44100 0x05
- #define SOUNDFORMAT_FREQ_48000 0x06
- #define SOUNDFORMAT_FREQ_SUSPECTED_64000 0x07
+ #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2
+ #define SOUNDFORMAT_FREQ_6620 0x0a | SOUNDFORMAT_XTAL2
+ #define SOUNDFORMAT_FREQ_8000 0x00 | SOUNDFORMAT_XTAL1 /* also 0x0e | SOUNDFORMAT_XTAL1? */
+ #define SOUNDFORMAT_FREQ_9600 0x08 | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_11025 0x00 | SOUNDFORMAT_XTAL2 /* also 0x0e | SOUNDFORMAT_XTAL2? */
+ #define SOUNDFORMAT_FREQ_SUSPECTED_13240 0x08 | SOUNDFORMAT_XTAL2 /* seems to be 6620 *2 */
+ #define SOUNDFORMAT_FREQ_16000 0x02 | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_22050 0x02 | SOUNDFORMAT_XTAL2
+ #define SOUNDFORMAT_FREQ_32000 0x04 | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_44100 0x04 | SOUNDFORMAT_XTAL2
+ #define SOUNDFORMAT_FREQ_48000 0x06 | SOUNDFORMAT_XTAL1
+ #define SOUNDFORMAT_FREQ_SUSPECTED_66200 0x06 | SOUNDFORMAT_XTAL2 /* 66200 (13240 * 5); 64000 may have been nicer :-\ */
#define SOUNDFORMAT_FLAG_16BIT 0x0010
#define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
-/* recording area (see also: playback bit flag definitions) */
-#define IDX_IO_REC_FLAGS 0x20 /* ?? */
-#define IDX_IO_REC_IRQMASK 0x22 /* ?? */
+
+/** recording area (see also: playback bit flag definitions) **/
+#define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */
+#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */
#define IRQ_REC_SOMETHING 0x0001 /* something & ACK */
#define IRQ_FINISHED_RECBUF_1 0x0002 /* 1st dmabuf finished & ACK */
#define IRQ_FINISHED_RECBUF_2 0x0004 /* 2nd dmabuf finished & ACK */
@@ -78,39 +79,47 @@
* but OTOH they are most likely at port 0x22 instead */
#define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
#define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
-#define IDX_IO_REC_DMA_START_1 0x24
-#define IDX_IO_REC_DMA_START_2 0x28
-#define IDX_IO_REC_DMA_LEN_1 0x2c
-#define IDX_IO_REC_DMA_LEN_2 0x2e
-#define IDX_IO_REC_DMA_CURRPOS 0x30
-#define IDX_IO_REC_DMA_CURROFS 0x34
-#define IDX_IO_REC_SOUNDFORMAT 0x36
-/* some third area ? (after playback and recording) */
-#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init */
+#define IDX_IO_REC_DMA_START_1 0x24 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_START_2 0x28 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_LEN_1 0x2c /* PU:0x0000 */
+#define IDX_IO_REC_DMA_LEN_2 0x2e /* PU:0x0000 */
+#define IDX_IO_REC_DMA_CURRPOS 0x30 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_CURROFS 0x34 /* PU:0x00000000 */
+#define IDX_IO_REC_SOUNDFORMAT 0x36 /* PU:0x0000 */
+
+/** hmm, what is this I/O area for? MPU401?? (after playback, recording, ???, timer) **/
+#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */
/* general */
-#define IDX_IO_60H 0x60 /* writing 0xffff returns 0xffff */
-#define IDX_IO_62H 0x62 /* writing to WORD 0x0062 can hang the box ! --> responsible for IRQ management as a whole ?? */
-#define IDX_IO_IRQ63H 0x63 /* FIXME !! */
- #define IO_IRQ63H_SOMETHING 0x04 /* being set in IRQ handler in case port 0x00 had 0x0020 set upon IRQ handler */
+#define IDX_IO_42H 0x42 /* PU:0x0001 */
+
+/** DirectX timer, main interrupt area (FIXME: and something else?) **/
+#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */
+ #define TIMER_VALUE_MASK 0x000fffffUL /* timer countdown value; triggers IRQ when timer is finished */
+ #define TIMER_ENABLE_COUNTDOWN 0x01000000UL /* activate the timer countdown */
+ #define TIMER_ENABLE_IRQ 0x02000000UL /* trigger timer IRQ on zero transition */
+ #define TIMER_ACK_IRQ 0x04000000UL /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) had 0x0020 set upon IRQ handler */
#define IDX_IO_IRQSTATUS 0x64
#define IRQ_PLAYBACK 0x0001
#define IRQ_RECORDING 0x0002
#define IRQ_MPU401 0x0010
- #define IRQ_SOMEIRQ 0x0020 /* ???? */
- #define IRQ_WHO_KNOWS_UNUSED 0x00e0 /* probably unused */
+ #define IRQ_TIMER 0x0020 /* DirectX timer */
+ #define IRQ_UNKNOWN1 0x0040 /* probably unused */
+ #define IRQ_UNKNOWN2 0x0080 /* probably unused */
#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
-#define IDX_IO_SOME_VALUE 0x68 /* this is always set to 0x3ff, and writable; maybe some buffer limit, but I couldn't find out more */
-#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback !!! maybe power management ?? */
-#define IDX_IO_6CH 0x6C /* this WORD can have all its bits activated ? */
+#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
+#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback!!! maybe power management?? */
+#define IDX_IO_6CH 0x6C
#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */
/* further I/O indices not saved/restored, so probably not used */
+
/*** I/O 2 area port indices ***/
/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
#define IDX_IO2_LEGACY_ADDR 0x04
- #define LEGACY_SOMETHING 0x01 /* OPL3 ?? */
+ #define LEGACY_SOMETHING 0x01 /* OPL3?? */
#define LEGACY_JOY 0x08
+
/*** mixer I/O area port indices ***/
/* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
* generally spoken: AC97 register index = AZF3328 mixer reg index + 2
@@ -148,18 +157,18 @@
/* unlisted bits are unmodifiable */
#define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e
#define MIXER_ADVCTL1_HIFI3D_MASK 0x0300
-#define IDX_MIXER_ADVCTL2 0x20 /* resembles AC97_GENERAL_PURPOSE reg ! */
+#define IDX_MIXER_ADVCTL2 0x20 /* resembles AC97_GENERAL_PURPOSE reg! */
/* unlisted bits are unmodifiable */
- #define MIXER_ADVCTL2_BIT7 0x0080 /* WaveOut 3D Bypass ? mutes WaveOut at LineOut */
- #define MIXER_ADVCTL2_BIT8 0x0100 /* is this Modem Out Select ? */
- #define MIXER_ADVCTL2_BIT9 0x0200 /* Mono Select Source ? */
- #define MIXER_ADVCTL2_BIT13 0x2000 /* 3D enable ? */
+ #define MIXER_ADVCTL2_BIT7 0x0080 /* WaveOut 3D Bypass? mutes WaveOut at LineOut */
+ #define MIXER_ADVCTL2_BIT8 0x0100 /* is this Modem Out Select? */
+ #define MIXER_ADVCTL2_BIT9 0x0200 /* Mono Select Source? */
+ #define MIXER_ADVCTL2_BIT13 0x2000 /* 3D enable? */
#define MIXER_ADVCTL2_BIT15 0x8000 /* unknown */
-#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown ??? */
+#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown??? */
/* driver internal flags */
#define SET_CHAN_LEFT 1
#define SET_CHAN_RIGHT 2
-#endif /* __SOUND_AZF3328_H */
+#endif /* __SOUND_AZT3328_H */
diff --git a/sound/pci/ca0106/Makefile b/sound/pci/ca0106/Makefile
index 89c6ceee21f3..dcbae7b31546 100644
--- a/sound/pci/ca0106/Makefile
+++ b/sound/pci/ca0106/Makefile
@@ -1,3 +1,3 @@
-snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o
+snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o ca_midi.o
obj-$(CONFIG_SND_CA0106) += snd-ca0106.o
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index da09cab405a9..9a4b6406f7a5 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -399,10 +399,24 @@
#define PLAYBACK_VOLUME2 0x6a /* Playback Analog volume per channel. Does not effect AC3 output */
/* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
#define UNKNOWN6b 0x6b /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
-#define UART_A_DATA 0x6c /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_A_CMD 0x6d /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_B_DATA 0x6e /* Uart, Unknown. */
-#define UART_B_CMD 0x6f /* Uart, Unknown. */
+#define MIDI_UART_A_DATA 0x6c /* Midi Uart A Data */
+#define MIDI_UART_A_CMD 0x6d /* Midi Uart A Command/Status */
+#define MIDI_UART_B_DATA 0x6e /* Midi Uart B Data (currently unused) */
+#define MIDI_UART_B_CMD 0x6f /* Midi Uart B Command/Status (currently unused) */
+
+/* unique channel identifier for midi->channel */
+
+#define CA0106_MIDI_CHAN_A 0x1
+#define CA0106_MIDI_CHAN_B 0x2
+
+/* from mpu401 */
+
+#define CA0106_MIDI_INPUT_AVAIL 0x80
+#define CA0106_MIDI_OUTPUT_READY 0x40
+#define CA0106_MPU401_RESET 0xff
+#define CA0106_MPU401_ENTER_UART 0x3f
+#define CA0106_MPU401_ACK 0xfe
+
#define SAMPLE_RATE_TRACKER_STATUS 0x70 /* Readonly. Default 00108000 00108000 00500000 00500000 */
/* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 = 1.0
* Rate Locked [20]
@@ -538,6 +552,8 @@
#define CONTROL_CENTER_LFE_CHANNEL 1
#define CONTROL_UNKNOWN_CHANNEL 2
+#include "ca_midi.h"
+
typedef struct snd_ca0106_channel ca0106_channel_t;
typedef struct snd_ca0106 ca0106_t;
typedef struct snd_ca0106_pcm ca0106_pcm_t;
@@ -592,6 +608,9 @@ struct snd_ca0106 {
int capture_mic_line_in;
struct snd_dma_buffer buffer;
+
+ ca_midi_t midi;
+ ca_midi_t midi2;
};
int __devinit snd_ca0106_mixer(ca0106_t *emu);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index ba07960921d8..ee58d16002e5 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -281,7 +281,7 @@ int snd_ca0106_i2c_write(ca0106_t *emu,
int retry;
if ((reg > 0x7f) || (value > 0x1ff))
{
- snd_printk("i2c_write: invalid values.\n");
+ snd_printk(KERN_ERR "i2c_write: invalid values.\n");
return -EINVAL;
}
@@ -319,7 +319,7 @@ int snd_ca0106_i2c_write(ca0106_t *emu,
if(retry==10)
{
- snd_printk("Writing to ADC failed!\n");
+ snd_printk(KERN_ERR "Writing to ADC failed!\n");
return -EINVAL;
}
@@ -338,6 +338,18 @@ static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb)
spin_unlock_irqrestore(&emu->emu_lock, flags);
}
+static void snd_ca0106_intr_disable(ca0106_t *emu, unsigned int intrenb)
+{
+ unsigned long flags;
+ unsigned int enable;
+
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ enable = inl(emu->port + INTE) & ~intrenb;
+ outl(enable, emu->port + INTE);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+
static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime)
{
kfree(runtime->private_data);
@@ -421,7 +433,7 @@ static int snd_ca0106_pcm_open_capture_channel(snd_pcm_substream_t *substream, i
epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL) {
- snd_printk("open_capture_channel: failed epcm alloc\n");
+ snd_printk(KERN_ERR "open_capture_channel: failed epcm alloc\n");
return -ENOMEM;
}
epcm->emu = chip;
@@ -969,10 +981,8 @@ static int snd_ca0106_free(ca0106_t *chip)
#endif
// release the i/o port
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ release_and_free_resource(chip->res_port);
+
// release the irq
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
@@ -1042,6 +1052,15 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id,
snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76);
spin_lock(&chip->emu_lock);
+
+ if (chip->midi.dev_id &&
+ (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) {
+ if (chip->midi.interrupt)
+ chip->midi.interrupt(&chip->midi, status);
+ else
+ chip->midi.interrupt_disable(&chip->midi, chip->midi.tx_enable | chip->midi.rx_enable);
+ }
+
// acknowledge the interrupt if necessary
outl(status, chip->port+IPR);
@@ -1311,6 +1330,88 @@ static int __devinit snd_ca0106_create(snd_card_t *card,
return 0;
}
+
+static void ca0106_midi_interrupt_enable(ca_midi_t *midi, int intr)
+{
+ snd_ca0106_intr_enable((ca0106_t *)(midi->dev_id), intr);
+}
+
+static void ca0106_midi_interrupt_disable(ca_midi_t *midi, int intr)
+{
+ snd_ca0106_intr_disable((ca0106_t *)(midi->dev_id), intr);
+}
+
+static unsigned char ca0106_midi_read(ca_midi_t *midi, int idx)
+{
+ return (unsigned char)snd_ca0106_ptr_read((ca0106_t *)(midi->dev_id), midi->port + idx, 0);
+}
+
+static void ca0106_midi_write(ca_midi_t *midi, int data, int idx)
+{
+ snd_ca0106_ptr_write((ca0106_t *)(midi->dev_id), midi->port + idx, 0, data);
+}
+
+static snd_card_t *ca0106_dev_id_card(void *dev_id)
+{
+ return ((ca0106_t *)dev_id)->card;
+}
+
+static int ca0106_dev_id_port(void *dev_id)
+{
+ return ((ca0106_t *)dev_id)->port;
+}
+
+static int __devinit snd_ca0106_midi(ca0106_t *chip, unsigned int channel)
+{
+ ca_midi_t *midi;
+ char *name;
+ int err;
+
+ if(channel==CA0106_MIDI_CHAN_B) {
+ name = "CA0106 MPU-401 (UART) B";
+ midi = &chip->midi2;
+ midi->tx_enable = INTE_MIDI_TX_B;
+ midi->rx_enable = INTE_MIDI_RX_B;
+ midi->ipr_tx = IPR_MIDI_TX_B;
+ midi->ipr_rx = IPR_MIDI_RX_B;
+ midi->port = MIDI_UART_B_DATA;
+ } else {
+ name = "CA0106 MPU-401 (UART)";
+ midi = &chip->midi;
+ midi->tx_enable = INTE_MIDI_TX_A;
+ midi->rx_enable = INTE_MIDI_TX_B;
+ midi->ipr_tx = IPR_MIDI_TX_A;
+ midi->ipr_rx = IPR_MIDI_RX_A;
+ midi->port = MIDI_UART_A_DATA;
+ }
+
+ midi->reset = CA0106_MPU401_RESET;
+ midi->enter_uart = CA0106_MPU401_ENTER_UART;
+ midi->ack = CA0106_MPU401_ACK;
+
+ midi->input_avail = CA0106_MIDI_INPUT_AVAIL;
+ midi->output_ready = CA0106_MIDI_OUTPUT_READY;
+
+ midi->channel = channel;
+
+ midi->interrupt_enable = ca0106_midi_interrupt_enable;
+ midi->interrupt_disable = ca0106_midi_interrupt_disable;
+
+ midi->read = ca0106_midi_read;
+ midi->write = ca0106_midi_write;
+
+ midi->get_dev_id_card = ca0106_dev_id_card;
+ midi->get_dev_id_port = ca0106_dev_id_port;
+
+ midi->dev_id = chip;
+
+ if ((err = ca_midi_init(chip, midi, 0, name)) < 0)
+ return err;
+
+ return 0;
+}
+
+
static int __devinit snd_ca0106_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
@@ -1362,6 +1463,14 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
return err;
}
+ snd_printdd("ca0106: probe for MIDI channel A ...");
+ if ((err = snd_ca0106_midi(chip,CA0106_MIDI_CHAN_A)) < 0) {
+ snd_card_free(card);
+ snd_printdd(" failed, err=0x%x\n",err);
+ return err;
+ }
+ snd_printdd(" done.\n");
+
snd_ca0106_proc_init(chip);
if ((err = snd_card_register(card)) < 0) {
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
new file mode 100644
index 000000000000..2e08b27b8349
--- /dev/null
+++ b/sound/pci/ca0106/ca_midi.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
+ * Creative Audio MIDI, for the CA0106 Driver
+ * Version: 0.0.1
+ *
+ * Changelog:
+ * Implementation is based on mpu401 and emu10k1x and
+ * tested with ca0106.
+ * mpu401: Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * emu10k1x: Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ */
+
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+
+#include "ca_midi.h"
+
+#define ca_midi_write_data(midi, data) midi->write(midi, data, 0)
+#define ca_midi_write_cmd(midi, data) midi->write(midi, data, 1)
+#define ca_midi_read_data(midi) midi->read(midi, 0)
+#define ca_midi_read_stat(midi) midi->read(midi, 1)
+#define ca_midi_input_avail(midi) (!(ca_midi_read_stat(midi) & midi->input_avail))
+#define ca_midi_output_ready(midi) (!(ca_midi_read_stat(midi) & midi->output_ready))
+
+static void ca_midi_clear_rx(ca_midi_t *midi)
+{
+ int timeout = 100000;
+ for (; timeout > 0 && ca_midi_input_avail(midi); timeout--)
+ ca_midi_read_data(midi);
+#ifdef CONFIG_SND_DEBUG
+ if (timeout <= 0)
+ snd_printk(KERN_ERR "ca_midi_clear_rx: timeout (status = 0x%x)\n", ca_midi_read_stat(midi));
+#endif
+}
+
+static void ca_midi_interrupt(ca_midi_t *midi, unsigned int status) {
+ unsigned char byte;
+
+ if (midi->rmidi == NULL) {
+ midi->interrupt_disable(midi,midi->tx_enable | midi->rx_enable);
+ return;
+ }
+
+ spin_lock(&midi->input_lock);
+ if ((status & midi->ipr_rx) && ca_midi_input_avail(midi)) {
+ if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+ ca_midi_clear_rx(midi);
+ } else {
+ byte = ca_midi_read_data(midi);
+ if(midi->substream_input)
+ snd_rawmidi_receive(midi->substream_input, &byte, 1);
+
+
+ }
+ }
+ spin_unlock(&midi->input_lock);
+
+ spin_lock(&midi->output_lock);
+ if ((status & midi->ipr_tx) && ca_midi_output_ready(midi)) {
+ if (midi->substream_output &&
+ snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
+ ca_midi_write_data(midi, byte);
+ } else {
+ midi->interrupt_disable(midi,midi->tx_enable);
+ }
+ }
+ spin_unlock(&midi->output_lock);
+
+}
+
+static void ca_midi_cmd(ca_midi_t *midi, unsigned char cmd, int ack)
+{
+ unsigned long flags;
+ int timeout, ok;
+
+ spin_lock_irqsave(&midi->input_lock, flags);
+ ca_midi_write_data(midi, 0x00);
+ /* ca_midi_clear_rx(midi); */
+
+ ca_midi_write_cmd(midi, cmd);
+ if (ack) {
+ ok = 0;
+ timeout = 10000;
+ while (!ok && timeout-- > 0) {
+ if (ca_midi_input_avail(midi)) {
+ if (ca_midi_read_data(midi) == midi->ack)
+ ok = 1;
+ }
+ }
+ if (!ok && ca_midi_read_data(midi) == midi->ack)
+ ok = 1;
+ } else {
+ ok = 1;
+ }
+ spin_unlock_irqrestore(&midi->input_lock, flags);
+ if (!ok)
+ snd_printk(KERN_ERR "ca_midi_cmd: 0x%x failed at 0x%x (status = 0x%x, data = 0x%x)!!!\n",
+ cmd,
+ midi->get_dev_id_port(midi->dev_id),
+ ca_midi_read_stat(midi),
+ ca_midi_read_data(midi));
+}
+
+static int ca_midi_input_open(snd_rawmidi_substream_t * substream)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+
+ snd_assert(midi->dev_id, return -ENXIO);
+ spin_lock_irqsave(&midi->open_lock, flags);
+ midi->midi_mode |= CA_MIDI_MODE_INPUT;
+ midi->substream_input = substream;
+ if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ ca_midi_cmd(midi, midi->reset, 1);
+ ca_midi_cmd(midi, midi->enter_uart, 1);
+ } else {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ }
+ return 0;
+}
+
+static int ca_midi_output_open(snd_rawmidi_substream_t * substream)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+
+ snd_assert(midi->dev_id, return -ENXIO);
+ spin_lock_irqsave(&midi->open_lock, flags);
+ midi->midi_mode |= CA_MIDI_MODE_OUTPUT;
+ midi->substream_output = substream;
+ if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ ca_midi_cmd(midi, midi->reset, 1);
+ ca_midi_cmd(midi, midi->enter_uart, 1);
+ } else {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ }
+ return 0;
+}
+
+static int ca_midi_input_close(snd_rawmidi_substream_t * substream)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+
+ snd_assert(midi->dev_id, return -ENXIO);
+ spin_lock_irqsave(&midi->open_lock, flags);
+ midi->interrupt_disable(midi,midi->rx_enable);
+ midi->midi_mode &= ~CA_MIDI_MODE_INPUT;
+ midi->substream_input = NULL;
+ if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ ca_midi_cmd(midi, midi->reset, 0);
+ } else {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ }
+ return 0;
+}
+
+static int ca_midi_output_close(snd_rawmidi_substream_t * substream)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+ snd_assert(midi->dev_id, return -ENXIO);
+
+ spin_lock_irqsave(&midi->open_lock, flags);
+
+ midi->interrupt_disable(midi,midi->tx_enable);
+ midi->midi_mode &= ~CA_MIDI_MODE_OUTPUT;
+ midi->substream_output = NULL;
+
+ if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ ca_midi_cmd(midi, midi->reset, 0);
+ } else {
+ spin_unlock_irqrestore(&midi->open_lock, flags);
+ }
+ return 0;
+}
+
+static void ca_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ snd_assert(midi->dev_id, return);
+
+ if (up) {
+ midi->interrupt_enable(midi,midi->rx_enable);
+ } else {
+ midi->interrupt_disable(midi, midi->rx_enable);
+ }
+}
+
+static void ca_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+ ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+ unsigned long flags;
+
+ snd_assert(midi->dev_id, return);
+
+ if (up) {
+ int max = 4;
+ unsigned char byte;
+
+ spin_lock_irqsave(&midi->output_lock, flags);
+
+ /* try to send some amount of bytes here before interrupts */
+ while (max > 0) {
+ if (ca_midi_output_ready(midi)) {
+ if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT) ||
+ snd_rawmidi_transmit(substream, &byte, 1) != 1) {
+ /* no more data */
+ spin_unlock_irqrestore(&midi->output_lock, flags);
+ return;
+ }
+ ca_midi_write_data(midi, byte);
+ max--;
+ } else {
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&midi->output_lock, flags);
+ midi->interrupt_enable(midi,midi->tx_enable);
+
+ } else {
+ midi->interrupt_disable(midi,midi->tx_enable);
+ }
+}
+
+static snd_rawmidi_ops_t ca_midi_output =
+{
+ .open = ca_midi_output_open,
+ .close = ca_midi_output_close,
+ .trigger = ca_midi_output_trigger,
+};
+
+static snd_rawmidi_ops_t ca_midi_input =
+{
+ .open = ca_midi_input_open,
+ .close = ca_midi_input_close,
+ .trigger = ca_midi_input_trigger,
+};
+
+static void ca_midi_free(ca_midi_t *midi) {
+ midi->interrupt = NULL;
+ midi->interrupt_enable = NULL;
+ midi->interrupt_disable = NULL;
+ midi->read = NULL;
+ midi->write = NULL;
+ midi->get_dev_id_card = NULL;
+ midi->get_dev_id_port = NULL;
+ midi->rmidi = NULL;
+}
+
+static void ca_rmidi_free(snd_rawmidi_t *rmidi)
+{
+ ca_midi_free((ca_midi_t *)rmidi->private_data);
+}
+
+int __devinit ca_midi_init(void *dev_id, ca_midi_t *midi, int device, char *name)
+{
+ snd_rawmidi_t *rmidi;
+ int err;
+
+ if ((err = snd_rawmidi_new(midi->get_dev_id_card(midi->dev_id), name, device, 1, 1, &rmidi)) < 0)
+ return err;
+
+ midi->dev_id = dev_id;
+ midi->interrupt = ca_midi_interrupt;
+
+ spin_lock_init(&midi->open_lock);
+ spin_lock_init(&midi->input_lock);
+ spin_lock_init(&midi->output_lock);
+
+ strcpy(rmidi->name, name);
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &ca_midi_output);
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &ca_midi_input);
+ rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
+ SNDRV_RAWMIDI_INFO_INPUT |
+ SNDRV_RAWMIDI_INFO_DUPLEX;
+ rmidi->private_data = midi;
+ rmidi->private_free = ca_rmidi_free;
+
+ midi->rmidi = rmidi;
+ return 0;
+}
+
diff --git a/sound/pci/ca0106/ca_midi.h b/sound/pci/ca0106/ca_midi.h
new file mode 100644
index 000000000000..b452cec2bf57
--- /dev/null
+++ b/sound/pci/ca0106/ca_midi.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
+ * Creative Audio MIDI, for the CA0106 Driver
+ * Version: 0.0.1
+ *
+ * Changelog:
+ * See ca_midi.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include<linux/spinlock.h>
+#include<sound/rawmidi.h>
+#include<sound/mpu401.h>
+
+#define CA_MIDI_MODE_INPUT MPU401_MODE_INPUT
+#define CA_MIDI_MODE_OUTPUT MPU401_MODE_OUTPUT
+
+typedef struct ca_midi ca_midi_t;
+struct ca_midi {
+
+ snd_rawmidi_t *rmidi;
+ snd_rawmidi_substream_t *substream_input;
+ snd_rawmidi_substream_t *substream_output;
+
+ void *dev_id;
+
+ spinlock_t input_lock;
+ spinlock_t output_lock;
+ spinlock_t open_lock;
+
+ unsigned int channel;
+
+ unsigned int midi_mode;
+ int port;
+ int tx_enable, rx_enable;
+ int ipr_tx, ipr_rx;
+
+ int input_avail, output_ready;
+ int ack, reset, enter_uart;
+
+ void (*interrupt)(ca_midi_t *midi, unsigned int status);
+ void (*interrupt_enable)(ca_midi_t *midi, int intr);
+ void (*interrupt_disable)(ca_midi_t *midi, int intr);
+
+ unsigned char (*read)(ca_midi_t *midi, int idx);
+ void (*write)(ca_midi_t *midi, int data, int idx);
+
+ /* get info from dev_id */
+ snd_card_t *(*get_dev_id_card)(void *dev_id);
+ int (*get_dev_id_port)(void *dev_id);
+};
+
+int __devinit ca_midi_init(void *card, ca_midi_t *midi, int device, char *name);
+
+
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 1eb3315d136d..57e8e433d56f 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -446,9 +446,6 @@ struct snd_stru_cmipci {
snd_kcontrol_t *mixer_res_ctl[CM_SAVED_MIXERS];
int mixer_res_status[CM_SAVED_MIXERS];
- opl3_t *opl3;
- snd_hwdep_t *opl3hwdep;
-
cmipci_pcm_t channel[2]; /* ch0 - DAC, ch1 - ADC or 2nd DAC */
/* external MIDI */
@@ -2686,8 +2683,7 @@ static int __devinit snd_cmipci_create_gameport(cmipci_t *cm, int dev)
cm->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "cmipci: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
gameport_set_name(gp, "C-Media Gameport");
@@ -2712,8 +2708,7 @@ static void snd_cmipci_free_gameport(cmipci_t *cm)
cm->gameport = NULL;
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
@@ -2753,6 +2748,51 @@ static int snd_cmipci_dev_free(snd_device_t *device)
return snd_cmipci_free(cm);
}
+static int __devinit snd_cmipci_create_fm(cmipci_t *cm, long fm_port)
+{
+ long iosynth;
+ unsigned int val;
+ opl3_t *opl3;
+ int err;
+
+ /* first try FM regs in PCI port range */
+ iosynth = cm->iobase + CM_REG_FM_PCI;
+ err = snd_opl3_create(cm->card, iosynth, iosynth + 2,
+ OPL3_HW_OPL3, 1, &opl3);
+ if (err < 0) {
+ /* then try legacy ports */
+ val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
+ iosynth = fm_port;
+ switch (iosynth) {
+ case 0x3E8: val |= CM_FMSEL_3E8; break;
+ case 0x3E0: val |= CM_FMSEL_3E0; break;
+ case 0x3C8: val |= CM_FMSEL_3C8; break;
+ case 0x388: val |= CM_FMSEL_388; break;
+ default:
+ return 0;
+ }
+ snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
+ /* enable FM */
+ snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
+
+ if (snd_opl3_create(cm->card, iosynth, iosynth + 2,
+ OPL3_HW_OPL3, 0, &opl3) < 0) {
+ printk(KERN_ERR "cmipci: no OPL device at %#lx, "
+ "skipping...\n", iosynth);
+ /* disable FM */
+ snd_cmipci_write(cm, CM_REG_LEGACY_CTRL,
+ val & ~CM_FMSEL_MASK);
+ snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
+ return 0;
+ }
+ }
+ if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
+ return err;
+ }
+ return 0;
+}
+
static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
int dev, cmipci_t **rcmipci)
{
@@ -2762,8 +2802,8 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
.dev_free = snd_cmipci_dev_free,
};
unsigned int val = 0;
- long iomidi = mpu_port[dev];
- long iosynth = fm_port[dev];
+ long iomidi;
+ int integrated_midi;
int pcm_index, pcm_spdif_index;
static struct pci_device_id intel_82437vx[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
@@ -2799,7 +2839,7 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
cm->iobase = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_cmipci_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)cm)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cmipci_free(cm);
return -EBUSY;
}
@@ -2867,52 +2907,28 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
return err;
}
- /* set MPU address */
- switch (iomidi) {
- case 0x320: val = CM_VMPU_320; break;
- case 0x310: val = CM_VMPU_310; break;
- case 0x300: val = CM_VMPU_300; break;
- case 0x330: val = CM_VMPU_330; break;
- default:
- iomidi = 0; break;
- }
- if (iomidi > 0) {
- snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
- /* enable UART */
- snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
- }
-
- /* set FM address */
- val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
- switch (iosynth) {
- case 0x3E8: val |= CM_FMSEL_3E8; break;
- case 0x3E0: val |= CM_FMSEL_3E0; break;
- case 0x3C8: val |= CM_FMSEL_3C8; break;
- case 0x388: val |= CM_FMSEL_388; break;
- default:
- iosynth = 0; break;
- }
- if (iosynth > 0) {
- snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
- /* enable FM */
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
-
- if (snd_opl3_create(card, iosynth, iosynth + 2,
- OPL3_HW_OPL3, 0, &cm->opl3) < 0) {
- printk(KERN_ERR "cmipci: no OPL device at 0x%lx, skipping...\n", iosynth);
- iosynth = 0;
- } else {
- if ((err = snd_opl3_hwdep_new(cm->opl3, 0, 1, &cm->opl3hwdep)) < 0) {
- printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
- return err;
- }
+ integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff;
+ if (integrated_midi)
+ iomidi = cm->iobase + CM_REG_MPU_PCI;
+ else {
+ iomidi = mpu_port[dev];
+ switch (iomidi) {
+ case 0x320: val = CM_VMPU_320; break;
+ case 0x310: val = CM_VMPU_310; break;
+ case 0x300: val = CM_VMPU_300; break;
+ case 0x330: val = CM_VMPU_330; break;
+ default:
+ iomidi = 0; break;
+ }
+ if (iomidi > 0) {
+ snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
+ /* enable UART */
+ snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
}
}
- if (! iosynth) {
- /* disable FM */
- snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val & ~CM_FMSEL_MASK);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
- }
+
+ if ((err = snd_cmipci_create_fm(cm, fm_port[dev])) < 0)
+ return err;
/* reset mixer */
snd_cmipci_mixer_write(cm, 0, 0);
@@ -2941,7 +2957,7 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
if (iomidi > 0) {
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
- iomidi, 0,
+ iomidi, integrated_midi,
cm->irq, 0, &cm->rmidi)) < 0) {
printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
}
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index dc87e0144b5a..aea2c47712f9 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -523,8 +523,7 @@ static void snd_cs4281_delay(unsigned int delay)
delay = 1;
end_time = jiffies + delay;
do {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
} else {
udelay(delay);
@@ -533,8 +532,7 @@ static void snd_cs4281_delay(unsigned int delay)
static inline void snd_cs4281_delay_long(void)
{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
static inline void snd_cs4281_pokeBA0(cs4281_t *chip, unsigned long offset, unsigned int val)
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 6e3855b8b33d..9b8af5bcbb04 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -163,7 +163,7 @@ static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip,
goto ok1;
}
- snd_printk("AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
+ snd_printk(KERN_ERR "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
result = 0xffff;
goto end;
@@ -182,7 +182,7 @@ static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip,
udelay(10);
}
- snd_printk("AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
+ snd_printk(KERN_ERR "AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
result = 0xffff;
goto end;
@@ -281,7 +281,7 @@ static void snd_cs46xx_codec_write(cs46xx_t *chip,
goto end;
}
}
- snd_printk("AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
+ snd_printk(KERN_ERR "AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
end:
chip->active_ctrl(chip, -1);
}
@@ -510,7 +510,7 @@ static void snd_cs46xx_proc_start(cs46xx_t *chip)
}
if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)
- snd_printk("SPCR_RUNFR never reset\n");
+ snd_printk(KERN_ERR "SPCR_RUNFR never reset\n");
}
static void snd_cs46xx_proc_stop(cs46xx_t *chip)
@@ -2403,7 +2403,7 @@ static void snd_cs46xx_codec_reset (ac97_t * ac97)
msleep(10);
} while (time_after_eq(end_time, jiffies));
- snd_printk("CS46xx secondary codec dont respond!\n");
+ snd_printk(KERN_ERR "CS46xx secondary codec doesn't respond!\n");
}
#endif
@@ -2906,10 +2906,7 @@ static int snd_cs46xx_free(cs46xx_t *chip)
snd_cs46xx_region_t *region = &chip->region.idx[idx];
if (region->remap_addr)
iounmap(region->remap_addr);
- if (region->resource) {
- release_resource(region->resource);
- kfree_nocheck(region->resource);
- }
+ release_and_free_resource(region->resource);
}
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
@@ -3075,8 +3072,8 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip)
}
- snd_printk("create - never read codec ready from AC'97\n");
- snd_printk("it is not probably bug, try to use CS4236 driver\n");
+ snd_printk(KERN_ERR "create - never read codec ready from AC'97\n");
+ snd_printk(KERN_ERR "it is not probably bug, try to use CS4236 driver\n");
return -EIO;
ok1:
#ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -3124,17 +3121,17 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip)
}
#ifndef CONFIG_SND_CS46XX_NEW_DSP
- snd_printk("create - never read ISV3 & ISV4 from AC'97\n");
+ snd_printk(KERN_ERR "create - never read ISV3 & ISV4 from AC'97\n");
return -EIO;
#else
/* This may happen on a cold boot with a Terratec SiXPack 5.1.
Reloading the driver may help, if there's other soundcards
with the same problem I would like to know. (Benny) */
- snd_printk("ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
- snd_printk(" Try reloading the ALSA driver, if you find something\n");
- snd_printk(" broken or not working on your soundcard upon\n");
- snd_printk(" this message please report to alsa-devel@lists.sourceforge.net\n");
+ snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
+ snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n");
+ snd_printk(KERN_ERR " broken or not working on your soundcard upon\n");
+ snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n");
return -EIO;
#endif
@@ -3215,7 +3212,7 @@ int __devinit snd_cs46xx_start_dsp(cs46xx_t *chip)
#else
/* old image */
if (snd_cs46xx_download_image(chip) < 0) {
- snd_printk("image download error\n");
+ snd_printk(KERN_ERR "image download error\n");
return -EIO;
}
@@ -3790,7 +3787,7 @@ int __devinit snd_cs46xx_create(snd_card_t * card,
chip->ba1_addr = pci_resource_start(pci, 1);
if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
- snd_printk("wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
+ snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
snd_cs46xx_free(chip);
return -ENOMEM;
}
@@ -3839,12 +3836,12 @@ int __devinit snd_cs46xx_create(snd_card_t * card,
}
if (external_amp) {
- snd_printk("Crystal EAPD support forced on.\n");
+ snd_printk(KERN_INFO "Crystal EAPD support forced on.\n");
chip->amplifier_ctrl = amp_voyetra;
}
if (thinkpad) {
- snd_printk("Activating CLKRUN hack for Thinkpad.\n");
+ snd_printk(KERN_INFO "Activating CLKRUN hack for Thinkpad.\n");
chip->active_ctrl = clkrun_hack;
clkrun_init(chip);
}
@@ -3861,20 +3858,20 @@ int __devinit snd_cs46xx_create(snd_card_t * card,
for (idx = 0; idx < 5; idx++) {
region = &chip->region.idx[idx];
if ((region->resource = request_mem_region(region->base, region->size, region->name)) == NULL) {
- snd_printk("unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
+ snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
snd_cs46xx_free(chip);
return -EBUSY;
}
region->remap_addr = ioremap_nocache(region->base, region->size);
if (region->remap_addr == NULL) {
- snd_printk("%s ioremap problem\n", region->name);
+ snd_printk(KERN_ERR "%s ioremap problem\n", region->name);
snd_cs46xx_free(chip);
return -ENOMEM;
}
}
if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_cs46xx_free(chip);
return -EBUSY;
}
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index b0e00f0a7c2f..dd1ea9d3b81a 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -188,7 +188,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
sizeof(snd_emu10k1_synth_arg_t), &wave) < 0 ||
wave == NULL) {
- snd_printk("can't initialize Emu10k1 wavetable synth\n");
+ snd_printk(KERN_WARNING "can't initialize Emu10k1 wavetable synth\n");
} else {
snd_emu10k1_synth_arg_t *arg;
arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 7cf2f908eed9..6589bf24abcd 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -241,7 +241,7 @@ lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_onl
else if (state == SNDRV_EMUX_ST_RELEASED ||
state == SNDRV_EMUX_ST_PENDING) {
bp = best + V_RELEASED;
-#if 0
+#if 1
val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch);
if (! val)
bp = best + V_OFF;
@@ -349,7 +349,7 @@ start_voice(snd_emux_voice_t *vp)
}
/* channel to be silent and idle */
- snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0080);
+ snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0000);
snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index ad15755a63c3..cbb689474e7d 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -759,10 +759,8 @@ static int snd_emu10k1x_free(emu10k1x_t *chip)
outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
// release the i/o port
- if (chip->res_port) {
- release_resource(chip->res_port);
- kfree_nocheck(chip->res_port);
- }
+ release_and_free_resource(chip->res_port);
+
// release the irq
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 646b5d972e6f..03e8c1678952 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -364,12 +364,18 @@ static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
break;
case EMU10K1_GPR_TRANSLATION_BASS:
- snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
+ if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
+ change = -EIO;
+ goto __error;
+ }
for (j = 0; j < 5; j++)
snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
break;
case EMU10K1_GPR_TRANSLATION_TREBLE:
- snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
+ if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
+ change = -EIO;
+ goto __error;
+ }
for (j = 0; j < 5; j++)
snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
break;
@@ -412,8 +418,6 @@ int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
snd_emu10k1_fx8010_irq_t *irq;
unsigned long flags;
- snd_runtime_check(emu, return -EINVAL);
- snd_runtime_check(handler, return -EINVAL);
irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
if (irq == NULL)
return -ENOMEM;
@@ -442,7 +446,6 @@ int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
snd_emu10k1_fx8010_irq_t *tmp;
unsigned long flags;
- snd_runtime_check(irq, return -EINVAL);
spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
if ((tmp = emu->fx8010.irq_handlers) == irq) {
emu->fx8010.irq_handlers = tmp->next;
@@ -717,9 +720,15 @@ static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode
err = -EFAULT;
goto __error;
}
- snd_runtime_check(gctl->id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
- gctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
- snd_runtime_check(gctl->id.name[0] != '\0', err = -EINVAL; goto __error);
+ if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
+ gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
+ err = -EINVAL;
+ goto __error;
+ }
+ if (! gctl->id.name[0]) {
+ err = -EINVAL;
+ goto __error;
+ }
ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
memset(&knew, 0, sizeof(knew));
knew.iface = gctl->id.iface;
@@ -783,7 +792,8 @@ static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode
for (i = 0, _id = icode->gpr_del_controls;
i < icode->gpr_del_control_count; i++, _id++) {
- snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
+ if (copy_from_user(&id, _id, sizeof(id)))
+ return -EFAULT;
down_write(&card->controls_rwsem);
ctl = snd_emu10k1_look_for_ctl(emu, &id);
if (ctl)
@@ -964,8 +974,8 @@ static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
return err;
}
-#define SND_EMU10K1_GPR_CONTROLS 41
-#define SND_EMU10K1_INPUTS 10
+#define SND_EMU10K1_GPR_CONTROLS 44
+#define SND_EMU10K1_INPUTS 12
#define SND_EMU10K1_PLAYBACK_CHANNELS 8
#define SND_EMU10K1_CAPTURE_CHANNELS 4
@@ -1382,7 +1392,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
if ((z==1) && (emu->card_capabilities->spdif_bug)) {
/* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
- snd_printk("Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
+ snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
} else {
@@ -1527,7 +1537,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
ptr = 0; i = 0;
- /* we have 10 inputs */
+ /* we have 12 inputs */
playback = SND_EMU10K1_INPUTS;
/* we have 6 playback channels and tone control doubles */
capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
@@ -1551,6 +1561,8 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
+ OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
+ OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
/* Raw S/PDIF PCM */
ipcm->substream = 0;
@@ -1697,6 +1709,21 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
+ /* Front Playback Volume */
+ for (z = 0; z < 2; z++)
+ VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
+ snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
+ gpr += 2;
+
+ /* Front Capture Volume + Switch */
+ for (z = 0; z < 2; z++) {
+ SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
+ VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
+ }
+ snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
+ snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
+ gpr += 3;
+
/*
* Process inputs
*/
@@ -2058,14 +2085,16 @@ void snd_emu10k1_free_efx(emu10k1_t *emu)
#if 0 // FIXME: who use them?
int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
{
- snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
+ if (output < 0 || output >= 6)
+ return -EINVAL;
snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
return 0;
}
int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
{
- snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
+ if (output < 0 || output >= 6)
+ return -EINVAL;
snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
return 0;
}
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 66ba27afe962..bf7490dae09b 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -965,7 +965,8 @@ static void snd_emu10k1_pcm_mixer_notify1(emu10k1_t *emu, snd_kcontrol_t *kctl,
{
snd_ctl_elem_id_t id;
- snd_runtime_check(kctl != NULL, return);
+ if (! kctl)
+ return;
if (activate)
kctl->vd[idx].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
else
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
index cd8460d56752..594ea063b140 100644
--- a/sound/pci/emu10k1/irq.c
+++ b/sound/pci/emu10k1/irq.c
@@ -41,7 +41,7 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
orig_status = status;
handled = 1;
if (status & IPR_PCIERROR) {
- snd_printk("interrupt: PCI error\n");
+ snd_printk(KERN_ERR "interrupt: PCI error\n");
snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
status &= ~IPR_PCIERROR;
}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 6afeaeab3e13..d42e4aeaa73a 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -232,11 +232,11 @@ __found_pages:
static int is_valid_page(emu10k1_t *emu, dma_addr_t addr)
{
if (addr & ~emu->dma_mask) {
- snd_printk("max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
+ snd_printk(KERN_ERR "max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
return 0;
}
if (addr & (EMUPAGESIZE-1)) {
- snd_printk("page is not aligned\n");
+ snd_printk(KERN_ERR "page is not aligned\n");
return 0;
}
return 1;
@@ -501,7 +501,7 @@ static inline void *offset_ptr(emu10k1_t *emu, int page, int offset)
snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL);
ptr = emu->page_ptr_table[page];
if (! ptr) {
- printk("emu10k1: access to NULL ptr: page = %d\n", page);
+ printk(KERN_ERR "emu10k1: access to NULL ptr: page = %d\n", page);
return NULL;
}
ptr += offset & (PAGE_SIZE - 1);
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index d59c7f345ad6..e27ebb9bb74a 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -546,7 +546,7 @@ snd_p16v_pcm_pointer_capture(snd_pcm_substream_t *substream)
ptr=ptr2;
if (ptr >= runtime->buffer_size) {
ptr -= runtime->buffer_size;
- printk("buffer capture limited!\n");
+ printk(KERN_WARNING "buffer capture limited!\n");
}
//printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index bef9a59f46d7..92ff7c510f2b 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -508,7 +508,7 @@ static unsigned int snd_es1371_wait_src_ready(ensoniq_t * ensoniq)
return r;
cond_resched();
}
- snd_printk("wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
+ snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
return 0;
}
@@ -576,10 +576,9 @@ static void snd_es1370_codec_write(ak4531_t *ak4531,
outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
return;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after(end_time, jiffies));
- snd_printk("codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
+ snd_printk(KERN_ERR "codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
}
#endif /* CHIP1370 */
@@ -620,7 +619,7 @@ static void snd_es1371_codec_write(ac97_t *ac97,
}
}
up(&ensoniq->src_mutex);
- snd_printk("codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+ snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
}
static unsigned short snd_es1371_codec_read(ac97_t *ac97,
@@ -667,14 +666,14 @@ static unsigned short snd_es1371_codec_read(ac97_t *ac97,
}
up(&ensoniq->src_mutex);
if (++fail > 10) {
- snd_printk("codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
+ snd_printk(KERN_ERR "codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
return 0;
}
goto __again;
}
}
up(&ensoniq->src_mutex);
- snd_printk("es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+ snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
return 0;
}
@@ -1960,7 +1959,7 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
}
ensoniq->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ, "Ensoniq AudioPCI", (void *)ensoniq)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ensoniq_free(ensoniq);
return -EBUSY;
}
@@ -1968,7 +1967,7 @@ static int __devinit snd_ensoniq_create(snd_card_t * card,
#ifdef CHIP1370
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
16, &ensoniq->dma_bug) < 0) {
- snd_printk("unable to allocate space for phantom area - dma_bug\n");
+ snd_printk(KERN_ERR "unable to allocate space for phantom area - dma_bug\n");
snd_ensoniq_free(ensoniq);
return -EBUSY;
}
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 17fa80c23870..78f90defcab1 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -267,7 +267,7 @@ static void snd_es1938_mixer_write(es1938_t *chip, unsigned char reg, unsigned c
outb(val, SLSB_REG(chip, MIXERDATA));
spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x set to %02x\n", reg, val);
+ snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, val);
#endif
}
@@ -283,7 +283,7 @@ static int snd_es1938_mixer_read(es1938_t *chip, unsigned char reg)
data = inb(SLSB_REG(chip, MIXERDATA));
spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x now is %02x\n", reg, data);
+ snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
#endif
return data;
}
@@ -303,7 +303,8 @@ static int snd_es1938_mixer_bits(es1938_t *chip, unsigned char reg, unsigned cha
new = (old & ~mask) | (val & mask);
outb(new, SLSB_REG(chip, MIXERDATA));
#ifdef REG_DEBUG
- snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new);
+ snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
+ reg, old, new);
#endif
}
spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -323,7 +324,7 @@ static void snd_es1938_write_cmd(es1938_t *chip, unsigned char cmd)
return;
}
}
- printk("snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
+ printk(KERN_ERR "snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
}
/* -----------------------------------------------------------------
@@ -336,7 +337,7 @@ static int snd_es1938_get_byte(es1938_t *chip)
for (i = GET_LOOP_TIMEOUT; i; i--)
if ((v = inb(SLSB_REG(chip, STATUS))) & 0x80)
return inb(SLSB_REG(chip, READDATA));
- snd_printk("get_byte timeout: status 0x02%x\n", v);
+ snd_printk(KERN_ERR "get_byte timeout: status 0x02%x\n", v);
return -ENODEV;
}
@@ -351,7 +352,7 @@ static void snd_es1938_write(es1938_t *chip, unsigned char reg, unsigned char va
snd_es1938_write_cmd(chip, val);
spin_unlock_irqrestore(&chip->reg_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Reg %02x set to %02x\n", reg, val);
+ snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, val);
#endif
}
@@ -368,7 +369,7 @@ static unsigned char snd_es1938_read(es1938_t *chip, unsigned char reg)
val = snd_es1938_get_byte(chip);
spin_unlock_irqrestore(&chip->reg_lock, flags);
#ifdef REG_DEBUG
- snd_printk("Reg %02x now is %02x\n", reg, val);
+ snd_printk(KERN_DEBUG "Reg %02x now is %02x\n", reg, val);
#endif
return val;
}
@@ -390,7 +391,8 @@ static int snd_es1938_bits(es1938_t *chip, unsigned char reg, unsigned char mask
new = (old & ~mask) | (val & mask);
snd_es1938_write_cmd(chip, new);
#ifdef REG_DEBUG
- snd_printk("Reg %02x was %02x, set to %02x\n", reg, old, new);
+ snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x\n",
+ reg, old, new);
#endif
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -413,7 +415,7 @@ static void snd_es1938_reset(es1938_t *chip)
goto __next;
}
}
- snd_printk("ESS Solo-1 reset failed\n");
+ snd_printk(KERN_ERR "ESS Solo-1 reset failed\n");
__next:
snd_es1938_write_cmd(chip, ESS_CMD_ENABLEEXT);
@@ -543,10 +545,12 @@ static int snd_es1938_capture_trigger(snd_pcm_substream_t * substream,
int val;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
val = 0x0f;
chip->active |= ADC1;
break;
case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
val = 0x00;
chip->active &= ~ADC1;
break;
@@ -563,6 +567,7 @@ static int snd_es1938_playback1_trigger(snd_pcm_substream_t * substream,
es1938_t *chip = snd_pcm_substream_chip(substream);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
/* According to the documentation this should be:
0x13 but that value may randomly swap stereo channels */
snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x92);
@@ -575,6 +580,7 @@ static int snd_es1938_playback1_trigger(snd_pcm_substream_t * substream,
chip->active |= DAC2;
break;
case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
outb(0, SLIO_REG(chip, AUDIO2MODE));
snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0);
chip->active &= ~DAC2;
@@ -592,10 +598,12 @@ static int snd_es1938_playback2_trigger(snd_pcm_substream_t * substream,
int val;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
val = 5;
chip->active |= DAC1;
break;
case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
val = 0;
chip->active &= ~DAC1;
break;
@@ -1390,7 +1398,8 @@ static int es1938_suspend(snd_card_t *card, pm_message_t state)
*d = snd_es1938_reg_read(chip, *s);
outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
-
+ if (chip->irq >= 0)
+ free_irq(chip->irq, (void *)chip);
pci_disable_device(chip->pci);
return 0;
}
@@ -1401,6 +1410,9 @@ static int es1938_resume(snd_card_t *card)
unsigned char *s, *d;
pci_enable_device(chip->pci);
+ request_irq(chip->pci->irq, snd_es1938_interrupt,
+ SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip);
+ chip->irq = chip->pci->irq;
snd_es1938_chip_init(chip);
/* restore mixer-related registers */
@@ -1489,7 +1501,7 @@ static int __devinit snd_es1938_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
- snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -1514,13 +1526,13 @@ static int __devinit snd_es1938_create(snd_card_t * 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, SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_es1938_free(chip);
return -EBUSY;
}
chip->irq = pci->irq;
#ifdef ES1938_DDEBUG
- snd_printk("create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
+ snd_printk(KERN_DEBUG "create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
chip->io_port, chip->sb_port, chip->vc_port, chip->mpu_port, chip->game_port);
#endif
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ecdcada90ca2..ac8294e21cc1 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1462,13 +1462,13 @@ snd_es1968_init_dmabuf(es1968_t *chip)
snd_dma_pci_data(chip->pci),
chip->total_bufsize, &chip->dma);
if (err < 0 || ! chip->dma.area) {
- snd_printk("es1968: can't allocate dma pages for size %d\n",
+ snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n",
chip->total_bufsize);
return -ENOMEM;
}
if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
snd_dma_free_pages(&chip->dma);
- snd_printk("es1968: DMA buffer beyond 256MB.\n");
+ snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n");
return -ENOMEM;
}
}
@@ -1741,11 +1741,11 @@ static void __devinit es1968_measure_clock(es1968_t *chip)
/* search 2 APUs (although one apu is enough) */
if ((apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY)) < 0) {
- snd_printk("Hmm, cannot find empty APU pair!?\n");
+ snd_printk(KERN_ERR "Hmm, cannot find empty APU pair!?\n");
return;
}
if ((memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE)) == NULL) {
- snd_printk("cannot allocate dma buffer - using default clock %d\n", chip->clock);
+ snd_printk(KERN_ERR "cannot allocate dma buffer - using default clock %d\n", chip->clock);
snd_es1968_free_apu_pair(chip, apu);
return;
}
@@ -1806,7 +1806,7 @@ static void __devinit es1968_measure_clock(es1968_t *chip)
else
t += stop_time.tv_usec - start_time.tv_usec;
if (t == 0) {
- snd_printk("?? calculation error..\n");
+ snd_printk(KERN_ERR "?? calculation error..\n");
} else {
offset *= 1000;
offset = (offset / t) * 1000 + ((offset % t) * 1000) / t;
@@ -2090,7 +2090,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip)
outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
#if 0 /* the loop here needs to be much better if we want it.. */
- snd_printk("trying software reset\n");
+ snd_printk(KERN_INFO "trying software reset\n");
/* try and do a software reset */
outb(0x80 | 0x7c, ioaddr + 0x30);
for (w = 0;; w++) {
@@ -2461,8 +2461,7 @@ static int __devinit snd_es1968_create_gameport(es1968_t *chip, int dev)
chip->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "es1968: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -2488,8 +2487,7 @@ static void snd_es1968_free_gameport(es1968_t *chip)
gameport_unregister_port(chip->gameport);
chip->gameport = NULL;
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
@@ -2564,7 +2562,7 @@ static int __devinit snd_es1968_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 28 bits */
if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
- snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -2599,7 +2597,7 @@ static int __devinit snd_es1968_create(snd_card_t * card,
chip->io_port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_es1968_interrupt, SA_INTERRUPT|SA_SHIRQ,
"ESS Maestro", (void*)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_es1968_free(chip);
return -EBUSY;
}
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index e5cfa2a0c246..4c7c8d225c7f 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -237,7 +237,7 @@ static void snd_fm801_codec_write(ac97_t *ac97,
goto ok1;
udelay(10);
}
- snd_printk("AC'97 interface is busy (1)\n");
+ snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
return;
ok1:
@@ -252,7 +252,7 @@ static void snd_fm801_codec_write(ac97_t *ac97,
return;
udelay(10);
}
- snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
+ snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
}
static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
@@ -268,7 +268,7 @@ static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
goto ok1;
udelay(10);
}
- snd_printk("AC'97 interface is busy (1)\n");
+ snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
return 0;
ok1:
@@ -279,7 +279,7 @@ static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
goto ok2;
udelay(10);
}
- snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
+ snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
return 0;
ok2:
@@ -288,7 +288,7 @@ static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
goto ok3;
udelay(10);
}
- snd_printk("AC'97 interface #%d is not valid (2)\n", ac97->num);
+ snd_printk(KERN_ERR "AC'97 interface #%d is not valid (2)\n", ac97->num);
return 0;
ok3:
@@ -1279,7 +1279,7 @@ static int __devinit snd_fm801_create(snd_card_t * card,
}
chip->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_fm801_interrupt, SA_INTERRUPT|SA_SHIRQ, "FM801", (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", chip->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
snd_fm801_free(chip);
return -EBUSY;
}
@@ -1303,10 +1303,9 @@ static int __devinit snd_fm801_create(snd_card_t * card,
do {
if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
goto __ac97_secondary;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after(timeout, jiffies));
- snd_printk("Primary AC'97 codec not found\n");
+ snd_printk(KERN_ERR "Primary AC'97 codec not found\n");
snd_fm801_free(chip);
return -EIO;
@@ -1329,8 +1328,7 @@ static int __devinit snd_fm801_create(snd_card_t * card,
goto __ac97_ok;
}
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after(timeout, jiffies));
}
@@ -1343,10 +1341,9 @@ static int __devinit snd_fm801_create(snd_card_t * card,
do {
if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
goto __ac97_ok;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after(timeout, jiffies));
- snd_printk("Primary AC'97 codec not responding\n");
+ snd_printk(KERN_ERR "Primary AC'97 codec not responding\n");
snd_fm801_free(chip);
return -EIO;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 3815403ed095..0dbeeaf6113a 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -518,6 +518,13 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
return -ENODEV;
}
+ if (! codec->subsystem_id) {
+ hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
+ codec->subsystem_id = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_SUBSYSTEM_ID,
+ 0);
+ }
+
codec->preset = find_codec_preset(codec);
if (! *bus->card->mixername)
snd_hda_get_codec_name(codec, bus->card->mixername,
@@ -814,6 +821,51 @@ int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
}
/*
+ * bound volume controls
+ *
+ * bind multiple volumes (# indices, from 0)
+ */
+
+#define AMP_VAL_IDX_SHIFT 19
+#define AMP_VAL_IDX_MASK (0x0f<<19)
+
+int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned long pval;
+ int err;
+
+ down(&codec->spdif_mutex); /* reuse spdif_mutex */
+ pval = kcontrol->private_value;
+ kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
+ err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
+ kcontrol->private_value = pval;
+ up(&codec->spdif_mutex);
+ return err;
+}
+
+int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned long pval;
+ int i, indices, err = 0, change = 0;
+
+ down(&codec->spdif_mutex); /* reuse spdif_mutex */
+ pval = kcontrol->private_value;
+ indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
+ for (i = 0; i < indices; i++) {
+ kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
+ err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+ if (err < 0)
+ break;
+ change |= err;
+ }
+ kcontrol->private_value = pval;
+ up(&codec->spdif_mutex);
+ return err < 0 ? err : change;
+}
+
+/*
* SPDIF out controls
*/
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index bb53bcf76742..1179d6cfa82a 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -79,6 +79,8 @@ enum {
#define AC_VERB_GET_GPIO_MASK 0x0f16
#define AC_VERB_GET_GPIO_DIRECTION 0x0f17
#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
+/* f20: AFG/MFG */
+#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
/*
* SET verbs
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 6fe696e53ea6..9d1412a9f2f8 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -47,23 +47,24 @@
#include "hda_codec.h"
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static char *model[SNDRV_CARDS];
-static int position_fix[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;
+static char *id = SNDRV_DEFAULT_STR1;
+static char *model;
+static int position_fix;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
-module_param_array(model, charp, NULL, 0444);
+module_param(model, charp, 0444);
MODULE_PARM_DESC(model, "Use the given board model.");
-module_param_array(position_fix, int, NULL, 0444);
+module_param(position_fix, int, 0444);
MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
"{Intel, ICH6M},"
@@ -223,6 +224,9 @@ enum {
#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42
#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02
+/* Defines for Nvidia HDA support */
+#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
+#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
/*
* Use CORB/RIRB for communication from/to codecs.
@@ -328,6 +332,7 @@ enum {
AZX_DRIVER_VIA,
AZX_DRIVER_SIS,
AZX_DRIVER_ULI,
+ AZX_DRIVER_NVIDIA,
};
static char *driver_short_names[] __devinitdata = {
@@ -335,7 +340,8 @@ static char *driver_short_names[] __devinitdata = {
[AZX_DRIVER_ATI] = "HDA ATI SB",
[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
[AZX_DRIVER_SIS] = "HDA SIS966",
- [AZX_DRIVER_ULI] = "HDA ULI M5461"
+ [AZX_DRIVER_ULI] = "HDA ULI M5461",
+ [AZX_DRIVER_NVIDIA] = "HDA NVidia",
};
/*
@@ -710,14 +716,14 @@ static void azx_stream_stop(azx_t *chip, azx_dev_t *azx_dev)
*/
static void azx_init_chip(azx_t *chip)
{
- unsigned char tcsel_reg, ati_misc_cntl2;
+ unsigned char reg;
/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
* TCSEL == Traffic Class Select Register, which sets PCI express QOS
* Ensuring these bits are 0 clears playback static on some HD Audio codecs
*/
- pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &tcsel_reg);
- pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, tcsel_reg & 0xf8);
+ pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &reg);
+ pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8);
/* reset controller */
azx_reset(chip);
@@ -733,13 +739,21 @@ static void azx_init_chip(azx_t *chip)
azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
- /* For ATI SB450 azalia HD audio, we need to enable snoop */
- if (chip->driver_type == AZX_DRIVER_ATI) {
+ switch (chip->driver_type) {
+ case AZX_DRIVER_ATI:
+ /* For ATI SB450 azalia HD audio, we need to enable snoop */
pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
- &ati_misc_cntl2);
+ &reg);
pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
- (ati_misc_cntl2 & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
- }
+ (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
+ break;
+ case AZX_DRIVER_NVIDIA:
+ /* For NVIDIA HDA, enable snoop */
+ pci_read_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, &reg);
+ pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR,
+ (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS);
+ break;
+ }
}
@@ -1264,6 +1278,7 @@ static int __devinit azx_pcm_create(azx_t *chip)
err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
if (err < 0)
return err;
+ chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM;
pcm_dev++;
}
}
@@ -1530,32 +1545,24 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci,
static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
azx_t *chip;
int err = 0;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (! enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (NULL == card) {
snd_printk(KERN_ERR SFX "Error creating card!\n");
return -ENOMEM;
}
- if ((err = azx_create(card, pci, position_fix[dev], pci_id->driver_data,
+ if ((err = azx_create(card, pci, position_fix, pci_id->driver_data,
&chip)) < 0) {
snd_card_free(card);
return err;
}
/* create codec instances */
- if ((err = azx_codec_create(chip, model[dev])) < 0) {
+ if ((err = azx_codec_create(chip, model)) < 0) {
snd_card_free(card);
return err;
}
@@ -1581,7 +1588,6 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *
}
pci_set_drvdata(pci, card);
- dev++;
return err;
}
@@ -1601,6 +1607,8 @@ static struct pci_device_id azx_ids[] = {
{ 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
{ 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
{ 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
+ { 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */
+ { 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */
{ 0, }
};
MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 810cfd2d9bba..f51a56f813c8 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -27,28 +27,36 @@
* for mixer controls
*/
#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
+/* mono volume with index (index=0,1,...) (channel=1,2) */
#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
.info = snd_hda_mixer_amp_volume_info, \
.get = snd_hda_mixer_amp_volume_get, \
.put = snd_hda_mixer_amp_volume_put, \
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
+/* stereo volume with index */
#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
+/* mono volume */
#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction)
+/* stereo volume */
#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
+/* mono mute switch with index (index=0,1,...) (channel=1,2) */
#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
.info = snd_hda_mixer_amp_switch_info, \
.get = snd_hda_mixer_amp_switch_get, \
.put = snd_hda_mixer_amp_switch_put, \
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
+/* stereo mute switch with index */
#define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
+/* mono mute switch */
#define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
+/* stereo mute switch */
#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
@@ -59,6 +67,20 @@ int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+/* mono switch binding multiple inputs */
+#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
+ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
+ .info = snd_hda_mixer_amp_switch_info, \
+ .get = snd_hda_mixer_bind_switch_get, \
+ .put = snd_hda_mixer_bind_switch_put, \
+ .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
+
+/* stereo switch binding multiple inputs */
+#define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
+
+int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+
int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 08f6a6efc5e6..39ddf1cd9019 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -281,6 +281,11 @@ static void print_codec_info(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
print_pcm_caps(buffer, codec, nid);
}
+ if (wid_caps & AC_WCAP_POWER)
+ snd_iprintf(buffer, " Power: 0x%x\n",
+ snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_POWER_STATE, 0));
+
if (wid_caps & AC_WCAP_CONN_LIST) {
int c, curr = -1;
if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index da6874d3988c..d7d636decef8 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -28,15 +28,38 @@
#include "hda_local.h"
struct ad198x_spec {
- struct semaphore amp_mutex; /* PCM volume/mute control mutex */
- struct hda_multi_out multiout; /* playback */
- hda_nid_t adc_nid;
+ snd_kcontrol_new_t *mixers[5];
+ int num_mixers;
+
+ const struct hda_verb *init_verbs[3]; /* initialization verbs
+ * don't forget NULL termination!
+ */
+ unsigned int num_init_verbs;
+
+ /* playback */
+ struct hda_multi_out multiout; /* playback set-up
+ * max_channels, dacs must be set
+ * dig_out_nid and hp_nid are optional
+ */
+
+ /* capture */
+ unsigned int num_adc_nids;
+ hda_nid_t *adc_nids;
+ hda_nid_t dig_in_nid; /* digital-in NID; optional */
+
+ /* capture source */
const struct hda_input_mux *input_mux;
- unsigned int cur_mux; /* capture source */
+ unsigned int cur_mux[3];
+
+ /* channel model */
+ const struct alc_channel_mode *channel_mode;
+ int num_channel_mode;
+
+ /* PCM information */
+ struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */
+
+ struct semaphore amp_mutex; /* PCM volume/mute control mutex */
unsigned int spdif_route;
- snd_kcontrol_new_t *mixers;
- const struct hda_verb *init_verbs;
- struct hda_pcm pcm_rec[2]; /* PCM information */
};
/*
@@ -54,8 +77,9 @@ static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct ad198x_spec *spec = codec->spec;
+ unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- ucontrol->value.enumerated.item[0] = spec->cur_mux;
+ ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
return 0;
}
@@ -63,9 +87,10 @@ static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct ad198x_spec *spec = codec->spec;
+ unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
- spec->adc_nid, &spec->cur_mux);
+ spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
}
/*
@@ -74,22 +99,34 @@ static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u
static int ad198x_init(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;
- snd_hda_sequence_write(codec, spec->init_verbs);
+ int i;
+
+ for (i = 0; i < spec->num_init_verbs; i++)
+ snd_hda_sequence_write(codec, spec->init_verbs[i]);
return 0;
}
static int ad198x_build_controls(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;
+ unsigned int i;
int err;
- err = snd_hda_add_new_ctls(codec, spec->mixers);
- if (err < 0)
- return err;
- if (spec->multiout.dig_out_nid)
+ for (i = 0; i < spec->num_mixers; i++) {
+ err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
+ if (err < 0)
+ return err;
+ }
+ if (spec->multiout.dig_out_nid) {
err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
+ if (err < 0)
+ return err;
+ }
+ if (spec->dig_in_nid) {
+ err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
+ if (err < 0)
+ return err;
+ }
return 0;
}
@@ -152,7 +189,8 @@ static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
snd_pcm_substream_t *substream)
{
struct ad198x_spec *spec = codec->spec;
- snd_hda_codec_setup_stream(codec, spec->adc_nid, stream_tag, 0, format);
+ snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+ stream_tag, 0, format);
return 0;
}
@@ -161,7 +199,8 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
snd_pcm_substream_t *substream)
{
struct ad198x_spec *spec = codec->spec;
- snd_hda_codec_setup_stream(codec, spec->adc_nid, 0, 0, 0);
+ snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+ 0, 0, 0);
return 0;
}
@@ -171,7 +210,7 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
static struct hda_pcm_stream ad198x_pcm_analog_playback = {
.substreams = 1,
.channels_min = 2,
- .channels_max = 6,
+ .channels_max = 6, /* changed later */
.nid = 0, /* fill later */
.ops = {
.open = ad198x_playback_pcm_open,
@@ -181,7 +220,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_playback = {
};
static struct hda_pcm_stream ad198x_pcm_analog_capture = {
- .substreams = 2,
+ .substreams = 1,
.channels_min = 2,
.channels_max = 2,
.nid = 0, /* fill later */
@@ -202,6 +241,13 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = {
},
};
+static struct hda_pcm_stream ad198x_pcm_digital_capture = {
+ .substreams = 1,
+ .channels_min = 2,
+ .channels_max = 2,
+ /* NID is set in alc_build_pcms */
+};
+
static int ad198x_build_pcms(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;
@@ -215,7 +261,8 @@ static int ad198x_build_pcms(struct hda_codec *codec)
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
- info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
if (spec->multiout.dig_out_nid) {
info++;
@@ -223,6 +270,10 @@ static int ad198x_build_pcms(struct hda_codec *codec)
info->name = "AD198x Digital";
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
+ if (spec->dig_in_nid) {
+ info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
+ }
}
return 0;
@@ -237,10 +288,15 @@ static void ad198x_free(struct hda_codec *codec)
static int ad198x_resume(struct hda_codec *codec)
{
struct ad198x_spec *spec = codec->spec;
+ int i;
ad198x_init(codec);
- snd_hda_resume_ctls(codec, spec->mixers);
- snd_hda_resume_spdif_out(codec);
+ for (i = 0; i < spec->num_mixers; i++)
+ snd_hda_resume_ctls(codec, spec->mixers[i]);
+ if (spec->multiout.dig_out_nid)
+ snd_hda_resume_spdif_out(codec);
+ if (spec->dig_in_nid)
+ snd_hda_resume_spdif_in(codec);
return 0;
}
#endif
@@ -269,6 +325,7 @@ static struct hda_codec_ops ad198x_patch_ops = {
static hda_nid_t ad1986a_dac_nids[3] = {
AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
};
+static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
static struct hda_input_mux ad1986a_capture_source = {
.num_items = 7,
@@ -476,10 +533,13 @@ static int patch_ad1986a(struct hda_codec *codec)
spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
spec->multiout.dac_nids = ad1986a_dac_nids;
spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
- spec->adc_nid = AD1986A_ADC;
+ spec->num_adc_nids = 1;
+ spec->adc_nids = ad1986a_adc_nids;
spec->input_mux = &ad1986a_capture_source;
- spec->mixers = ad1986a_mixers;
- spec->init_verbs = ad1986a_init_verbs;
+ spec->num_mixers = 1;
+ spec->mixers[0] = ad1986a_mixers;
+ spec->num_init_verbs = 1;
+ spec->init_verbs[0] = ad1986a_init_verbs;
codec->patch_ops = ad198x_patch_ops;
@@ -495,6 +555,7 @@ static int patch_ad1986a(struct hda_codec *codec)
#define AD1983_ADC 0x04
static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
+static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
static struct hda_input_mux ad1983_capture_source = {
.num_items = 4,
@@ -619,6 +680,7 @@ static struct hda_verb ad1983_init_verbs[] = {
{ } /* end */
};
+
static int patch_ad1983(struct hda_codec *codec)
{
struct ad198x_spec *spec;
@@ -634,10 +696,13 @@ static int patch_ad1983(struct hda_codec *codec)
spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
spec->multiout.dac_nids = ad1983_dac_nids;
spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
- spec->adc_nid = AD1983_ADC;
+ spec->num_adc_nids = 1;
+ spec->adc_nids = ad1983_adc_nids;
spec->input_mux = &ad1983_capture_source;
- spec->mixers = ad1983_mixers;
- spec->init_verbs = ad1983_init_verbs;
+ spec->num_mixers = 1;
+ spec->mixers[0] = ad1983_mixers;
+ spec->num_init_verbs = 1;
+ spec->init_verbs[0] = ad1983_init_verbs;
spec->spdif_route = 0;
codec->patch_ops = ad198x_patch_ops;
@@ -655,6 +720,7 @@ static int patch_ad1983(struct hda_codec *codec)
#define AD1981_ADC 0x04
static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
+static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
static struct hda_input_mux ad1981_capture_source = {
@@ -775,10 +841,13 @@ static int patch_ad1981(struct hda_codec *codec)
spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
spec->multiout.dac_nids = ad1981_dac_nids;
spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
- spec->adc_nid = AD1981_ADC;
+ spec->num_adc_nids = 1;
+ spec->adc_nids = ad1981_adc_nids;
spec->input_mux = &ad1981_capture_source;
- spec->mixers = ad1981_mixers;
- spec->init_verbs = ad1981_init_verbs;
+ spec->num_mixers = 1;
+ spec->mixers[0] = ad1981_mixers;
+ spec->num_init_verbs = 1;
+ spec->init_verbs[0] = ad1981_init_verbs;
spec->spdif_route = 0;
codec->patch_ops = ad198x_patch_ops;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7327deb6df9f..cffb83fdcff7 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -57,6 +57,7 @@ enum {
enum {
ALC260_BASIC,
ALC260_HP,
+ ALC260_FUJITSU_S702x,
ALC260_MODEL_LAST /* last tag */
};
@@ -72,6 +73,7 @@ enum {
#define PIN_VREF50 0x21
#define PIN_OUT 0x40
#define PIN_HP 0xc0
+#define PIN_HP_AMP 0x80
struct alc_spec {
/* codec parameterization */
@@ -113,8 +115,6 @@ struct alc_spec {
/* PCM information */
struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */
- struct semaphore bind_mutex; /* for bound controls */
-
/* dynamic controls, init_verbs and input_mux */
struct auto_pin_cfg autocfg;
unsigned int num_kctl_alloc, num_kctl_used;
@@ -218,72 +218,53 @@ static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *uc
/*
- * bound volume controls
- *
- * bind multiple volumes (# indices, from 0)
+ * Control of pin widget settings via the mixer. Only boolean settings are
+ * supported, so VrefEn can't be controlled using these functions as they
+ * stand.
*/
-
-#define AMP_VAL_IDX_SHIFT 19
-#define AMP_VAL_IDX_MASK (0x0f<<19)
-
-static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc_pinctl_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned long pval;
-
- down(&spec->bind_mutex);
- pval = kcontrol->private_value;
- kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
- snd_hda_mixer_amp_switch_info(kcontrol, uinfo);
- kcontrol->private_value = pval;
- up(&spec->bind_mutex);
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
return 0;
}
-static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned long pval;
-
- down(&spec->bind_mutex);
- pval = kcontrol->private_value;
- kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
- snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
- kcontrol->private_value = pval;
- up(&spec->bind_mutex);
+ hda_nid_t nid = kcontrol->private_value & 0xffff;
+ long mask = (kcontrol->private_value >> 16) & 0xff;
+ long *valp = ucontrol->value.integer.value;
+
+ *valp = 0;
+ if (snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00) & mask)
+ *valp = 1;
return 0;
}
-static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct alc_spec *spec = codec->spec;
- unsigned long pval;
- int i, indices, change = 0;
-
- down(&spec->bind_mutex);
- pval = kcontrol->private_value;
- indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
- for (i = 0; i < indices; i++) {
- kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
- change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
- }
- kcontrol->private_value = pval;
- up(&spec->bind_mutex);
+ hda_nid_t nid = kcontrol->private_value & 0xffff;
+ long mask = (kcontrol->private_value >> 16) & 0xff;
+ long *valp = ucontrol->value.integer.value;
+ unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);
+ int change = ((pinctl & mask)!=0) != *valp;
+
+ if (change)
+ snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
+ *valp?(pinctl|mask):(pinctl&~mask));
return change;
}
-#define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
+#define ALC_PINCTL_SWITCH(xname, nid, mask) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
- .info = alc_bind_switch_info, \
- .get = alc_bind_switch_get, \
- .put = alc_bind_switch_put, \
- .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
-
-#define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir)
-
+ .info = alc_pinctl_switch_info, \
+ .get = alc_pinctl_switch_get, \
+ .put = alc_pinctl_switch_put, \
+ .private_value = (nid) | (mask<<16) }
/*
* ALC880 3-stack model
@@ -354,13 +335,13 @@ static struct alc_channel_mode alc880_threestack_modes[2] = {
static snd_kcontrol_new_t alc880_three_stack_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -441,7 +422,7 @@ static snd_kcontrol_new_t alc880_capture_alt_mixer[] = {
/* additional mixers to alc880_three_stack_mixer */
static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
{ } /* end */
};
@@ -498,15 +479,15 @@ static struct alc_channel_mode alc880_sixstack_modes[1] = {
static snd_kcontrol_new_t alc880_six_stack_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -566,13 +547,13 @@ static struct alc_channel_mode alc880_w810_modes[1] = {
/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
{ } /* end */
};
@@ -597,9 +578,9 @@ static struct alc_channel_mode alc880_2_jack_modes[1] = {
static snd_kcontrol_new_t alc880_z71v_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -623,9 +604,9 @@ static hda_nid_t alc880_f1734_dac_nids[1] = {
static snd_kcontrol_new_t alc880_f1734_mixer[] = {
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -648,13 +629,13 @@ static snd_kcontrol_new_t alc880_f1734_mixer[] = {
static snd_kcontrol_new_t alc880_asus_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -1383,10 +1364,10 @@ static snd_kcontrol_new_t alc880_test_mixer[] = {
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
- ALC_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
- ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
PIN_CTL_TEST("Front Pin Mode", 0x14),
PIN_CTL_TEST("Surround Pin Mode", 0x15),
PIN_CTL_TEST("CLFE Pin Mode", 0x16),
@@ -1769,7 +1750,7 @@ enum {
static snd_kcontrol_new_t alc880_control_templates[] = {
HDA_CODEC_VOLUME(NULL, 0, 0, 0),
HDA_CODEC_MUTE(NULL, 0, 0, 0),
- ALC_BIND_MUTE(NULL, 0, 0, 0),
+ HDA_BIND_MUTE(NULL, 0, 0, 0),
};
/* add dynamic controls */
@@ -2087,7 +2068,6 @@ static int patch_alc880(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- init_MUTEX(&spec->bind_mutex);
codec->spec = spec;
board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
@@ -2205,6 +2185,17 @@ static struct hda_input_mux alc260_capture_source = {
},
};
+/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack
+ * and the internal CD lines.
+ */
+static struct hda_input_mux alc260_fujitsu_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "Mic/Line", 0x0 },
+ { "CD", 0x4 },
+ },
+};
+
/*
* This is just place-holder, so there's something for alc_build_pcms to look
* at when it calculates the maximum number of channels. ALC260 has no mixer
@@ -2217,7 +2208,7 @@ static struct alc_channel_mode alc260_modes[1] = {
static snd_kcontrol_new_t alc260_base_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -2229,9 +2220,9 @@ static snd_kcontrol_new_t alc260_base_mixer[] = {
HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
{
@@ -2246,7 +2237,7 @@ static snd_kcontrol_new_t alc260_base_mixer[] = {
static snd_kcontrol_new_t alc260_hp_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -2256,9 +2247,9 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = {
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
{
@@ -2271,6 +2262,30 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = {
{ } /* end */
};
+static snd_kcontrol_new_t alc260_fujitsu_mixer[] = {
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
+ ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP),
+ HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
+ HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Source",
+ .info = alc_mux_enum_info,
+ .get = alc_mux_enum_get,
+ .put = alc_mux_enum_put,
+ },
+ { } /* end */
+};
+
static struct hda_verb alc260_init_verbs[] = {
/* Line In pin widget for input */
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -2332,6 +2347,60 @@ static struct hda_verb alc260_init_verbs[] = {
{ }
};
+/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
+ * laptops.
+ */
+static struct hda_verb alc260_fujitsu_init_verbs[] = {
+ /* Disable all GPIOs */
+ {0x01, AC_VERB_SET_GPIO_MASK, 0},
+ /* Internal speaker is connected to headphone pin */
+ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ /* Headphone/Line-out jack connects to Line1 pin; make it an output */
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ /* Ensure all other unused pins are disabled and muted.
+ * Note: trying to set widget 0x15 to anything blocks all audio
+ * output for some reason, so just leave that at the default.
+ */
+ {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+ {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ /* Disable digital (SPDIF) pins */
+ {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
+ {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
+
+ /* Start with mixer outputs muted */
+ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+
+ /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
+ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ /* Unmute Line1 pin widget amp left and right (no equiv mixer ctrl) */
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ /* Unmute pin widget used for Line-in (no equiv mixer ctrl) */
+ {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+ /* Mute capture amp left and right */
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ /* Set ADC connection select to line in (on mic1 pin) */
+ {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+ /* Mute all inputs to mixer widget (even unconnected ones) */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
+};
+
static struct hda_pcm_stream alc260_pcm_analog_playback = {
.substreams = 1,
.channels_min = 2,
@@ -2347,6 +2416,8 @@ static struct hda_pcm_stream alc260_pcm_analog_capture = {
static struct hda_board_config alc260_cfg_tbl[] = {
{ .modelname = "hp", .config = ALC260_HP },
{ .pci_subvendor = 0x103c, .config = ALC260_HP },
+ { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702x },
+ { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702x },
{}
};
@@ -2359,7 +2430,6 @@ static int patch_alc260(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- init_MUTEX(&spec->bind_mutex);
codec->spec = spec;
board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
@@ -2373,14 +2443,23 @@ static int patch_alc260(struct hda_codec *codec)
spec->mixers[spec->num_mixers] = alc260_hp_mixer;
spec->num_mixers++;
break;
+ case ALC260_FUJITSU_S702x:
+ spec->mixers[spec->num_mixers] = alc260_fujitsu_mixer;
+ spec->num_mixers++;
+ break;
default:
spec->mixers[spec->num_mixers] = alc260_base_mixer;
spec->num_mixers++;
break;
}
- spec->init_verbs[0] = alc260_init_verbs;
- spec->num_init_verbs = 1;
+ if (board_config != ALC260_FUJITSU_S702x) {
+ spec->init_verbs[0] = alc260_init_verbs;
+ spec->num_init_verbs = 1;
+ } else {
+ spec->init_verbs[0] = alc260_fujitsu_init_verbs;
+ spec->num_init_verbs = 1;
+ }
spec->channel_mode = alc260_modes;
spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
@@ -2393,7 +2472,11 @@ static int patch_alc260(struct hda_codec *codec)
spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
spec->multiout.dac_nids = alc260_dac_nids;
- spec->input_mux = &alc260_capture_source;
+ if (board_config != ALC260_FUJITSU_S702x) {
+ spec->input_mux = &alc260_capture_source;
+ } else {
+ spec->input_mux = &alc260_fujitsu_capture_source;
+ }
switch (board_config) {
case ALC260_HP:
spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids);
@@ -2483,15 +2566,15 @@ static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u
*/
static snd_kcontrol_new_t alc882_base_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
- ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+ HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -2609,7 +2692,6 @@ static int patch_alc882(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- init_MUTEX(&spec->bind_mutex);
codec->spec = spec;
spec->mixers[spec->num_mixers] = alc882_base_mixer;
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index d014b7bb70df..9c7fe0b3200a 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -3,7 +3,7 @@
*
* HD audio interface patch for Silicon Labs 3054/5 modem codec
*
- * Copyright (c) 2005 Sasha Khapyorsky <sashak@smlink.com>
+ * Copyright (c) 2005 Sasha Khapyorsky <sashak@alsa-project.org>
* Takashi Iwai <tiwai@suse.de>
*
*
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 2e0a31613ee6..db12b038286b 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -960,7 +960,7 @@ static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucont
if (change)
wm_put(ice, WM_ADC_MUX, nval);
snd_ice1712_restore_gpio_status(ice);
- return 0;
+ return change;
}
/*
@@ -1672,9 +1672,9 @@ static int __devinit aureon_add_controls(ice1712_t *ice)
snd_ice1712_save_gpio_status(ice);
id = aureon_cs8415_get(ice, CS8415_ID);
if (id != 0x41)
- snd_printk("No CS8415 chip. Skipping CS8415 controls.\n");
+ snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
else if ((id & 0x0F) != 0x01)
- snd_printk("Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
+ snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
else {
for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
snd_kcontrol_t *kctl;
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 39fbe662965d..576f69d482c9 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -546,7 +546,7 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
case ICE1712_SUBDEVICE_DELTA1010LT:
case ICE1712_SUBDEVICE_VX442:
if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
- snd_printk("unable to create I2C bus\n");
+ snd_printk(KERN_ERR "unable to create I2C bus\n");
return err;
}
ice->i2c->private_data = ice;
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index e36efa1bdac3..c8ec5cac3c17 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -438,7 +438,7 @@ static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
/* create i2c */
if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
- snd_printk("unable to create I2C bus\n");
+ snd_printk(KERN_ERR "unable to create I2C bus\n");
return err;
}
ice->i2c->private_data = ice;
@@ -448,7 +448,7 @@ static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
switch (ice->eeprom.subvendor) {
case ICE1712_SUBDEVICE_DMX6FIRE:
if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) {
- snd_printk("PCF9554 initialization failed\n");
+ snd_printk(KERN_ERR "PCF9554 initialization failed\n");
return err;
}
snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80);
@@ -791,7 +791,7 @@ static int snd_ice1712_6fire_read_pca(ice1712_t *ice, unsigned char reg)
byte = 0;
if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
snd_i2c_unlock(ice->i2c);
- printk("cannot read pca\n");
+ printk(KERN_ERR "cannot read pca\n");
return -EIO;
}
snd_i2c_unlock(ice->i2c);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index a6d98013c331..5aca37798c32 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -387,7 +387,7 @@ int __devinit snd_ice1712_init_cs8427(ice1712_t *ice, int addr)
if ((err = snd_cs8427_create(ice->i2c, addr,
(ice->cs8427_timeout * HZ) / 1000,
&ice->cs8427)) < 0) {
- snd_printk("CS8427 initialization failed\n");
+ snd_printk(KERN_ERR "CS8427 initialization failed\n");
return err;
}
ice->spdif.ops.open = open_cs8427;
@@ -2348,12 +2348,12 @@ static int __devinit snd_ice1712_read_eeprom(ice1712_t *ice, const char *modelna
if (ice->eeprom.size < 6)
ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */
else if (ice->eeprom.size > 32) {
- snd_printk("invalid EEPROM (size = %i)\n", ice->eeprom.size);
+ snd_printk(KERN_ERR "invalid EEPROM (size = %i)\n", ice->eeprom.size);
return -EIO;
}
ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
if (ice->eeprom.version != 1) {
- snd_printk("invalid EEPROM version %i\n", ice->eeprom.version);
+ snd_printk(KERN_ERR "invalid EEPROM version %i\n", ice->eeprom.version);
/* return -EIO; */
}
size = ice->eeprom.size - 6;
@@ -2524,7 +2524,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 28 bits */
if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
- snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -2573,7 +2573,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card,
ice->profi_port = pci_resource_start(pci, 3);
if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ice1712_free(ice);
return -EIO;
}
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index c3ce8f93740b..5b4293f5a652 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -675,9 +675,12 @@ static snd_pcm_hardware_t snd_vt1724_spdif =
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
.formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+ .rates = (SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|
+ SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_88200|
+ SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_176400|
+ SNDRV_PCM_RATE_192000),
.rate_min = 32000,
- .rate_max = 48000,
+ .rate_max = 192000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = (1UL << 18), /* 16bits dword */
@@ -905,6 +908,10 @@ static void update_spdif_rate(ice1712_t *ice, unsigned int rate)
case 44100: break;
case 48000: nval |= 2 << 12; break;
case 32000: nval |= 3 << 12; break;
+ case 88200: nval |= 4 << 12; break;
+ case 96000: nval |= 5 << 12; break;
+ case 192000: nval |= 6 << 12; break;
+ case 176400: nval |= 7 << 12; break;
}
if (val != nval)
update_spdif_bits(ice, nval);
@@ -1292,22 +1299,32 @@ static int snd_vt1724_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
static unsigned int encode_spdif_bits(snd_aes_iec958_t *diga)
{
- unsigned int val;
+ unsigned int val, rbits;
val = diga->status[0] & 0x03; /* professional, non-audio */
if (val & 0x01) {
/* professional */
if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
val |= 1U << 3;
- switch (diga->status[0] & IEC958_AES0_PRO_FS) {
- case IEC958_AES0_PRO_FS_44100:
- break;
- case IEC958_AES0_PRO_FS_32000:
- val |= 3U << 12;
- break;
- default:
- val |= 2U << 12;
- break;
+ rbits = (diga->status[4] >> 3) & 0x0f;
+ if (rbits) {
+ switch (rbits) {
+ case 2: val |= 5 << 12; break; /* 96k */
+ case 3: val |= 6 << 12; break; /* 192k */
+ case 10: val |= 4 << 12; break; /* 88.2k */
+ case 11: val |= 7 << 12; break; /* 176.4k */
+ }
+ } else {
+ switch (diga->status[0] & IEC958_AES0_PRO_FS) {
+ case IEC958_AES0_PRO_FS_44100:
+ break;
+ case IEC958_AES0_PRO_FS_32000:
+ val |= 3U << 12;
+ break;
+ default:
+ val |= 2U << 12;
+ break;
+ }
}
} else {
/* consumer */
@@ -2154,7 +2171,7 @@ static int __devinit snd_vt1724_create(snd_card_t * card,
ice->profi_port = pci_resource_start(pci, 1);
if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_vt1724_free(ice);
return -EIO;
}
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index a5f852b1f575..773a1ecb75ce 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -794,8 +794,7 @@ static int __devinit pontis_init(ice1712_t *ice)
/* initialize WM8776 codec */
for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
wm_put(ice, wm_inits[i], wm_inits[i+1]);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index d48d42524ac5..1fe21009ca84 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -128,17 +128,6 @@ static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
.mask_flags = 0,
};
-static unsigned int rates[] = {
- 32000, 44100, 48000, 64000, 88200, 96000,
- 176400, 192000,
-};
-
-static snd_pcm_hw_constraint_list_t revo_rates = {
- .count = ARRAY_SIZE(rates),
- .list = rates,
- .mask = 0,
-};
-
static int __devinit revo_init(ice1712_t *ice)
{
akm4xxx_t *ak;
@@ -173,8 +162,6 @@ static int __devinit revo_init(ice1712_t *ice)
break;
}
- ice->hw_rates = &revo_rates; /* AK codecs don't support lower than 32k */
-
return 0;
}
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index ab61e383024f..90c85cd95479 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -71,6 +71,22 @@ static unsigned char k8x800_eeprom[] __devinitdata = {
0x00, /* - */
};
+static unsigned char sn25p_eeprom[] __devinitdata = {
+ 0x01, /* SYSCONF: clock 256, 1ADC, 2DACs */
+ 0x02, /* ACLINK: ACLINK, packed */
+ 0x00, /* I2S: - */
+ 0x41, /* SPDIF: - */
+ 0xff, /* GPIO_DIR */
+ 0xff, /* GPIO_DIR1 */
+ 0x00, /* - */
+ 0xff, /* GPIO_MASK */
+ 0xff, /* GPIO_MASK1 */
+ 0x00, /* - */
+ 0x00, /* GPIO_STATE */
+ 0x00, /* GPIO_STATE1 */
+ 0x00, /* - */
+};
+
/* entry point */
struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
@@ -113,11 +129,11 @@ struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
{
.subvendor = VT1720_SUBDEVICE_SN25P,
.name = "Shuttle SN25P",
- /* identical with k8x800 */
+ .model = "sn25p",
.chip_init = k8x800_init,
.build_controls = k8x800_add_controls,
.eeprom_size = sizeof(k8x800_eeprom),
- .eeprom_data = k8x800_eeprom,
+ .eeprom_data = sn25p_eeprom,
},
{ } /* terminator */
};
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 1a96198a17ae..0801083f32dd 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -64,36 +64,35 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
"{AMD,AMD8111},"
"{ALI,M5455}}");
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
-static char *ac97_quirk[SNDRV_CARDS];
-static int buggy_semaphore[SNDRV_CARDS];
-static int buggy_irq[SNDRV_CARDS];
-static int xbox[SNDRV_CARDS];
-
-#ifdef SUPPORT_MIDI
-static int mpu_port[SNDRV_CARDS]; /* disabled */
-#endif
-
-module_param_array(index, int, NULL, 0444);
+static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 0;
+static char *ac97_quirk;
+static int buggy_semaphore;
+static int buggy_irq = -1; /* auto-check */
+static int xbox;
+
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel i8x0 soundcard.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(buggy_semaphore, bool, NULL, 0444);
+module_param(buggy_semaphore, bool, 0444);
MODULE_PARM_DESC(buggy_semaphore, "Enable workaround for hardwares with problematic codec semaphores.");
-module_param_array(buggy_irq, bool, NULL, 0444);
+module_param(buggy_irq, bool, 0444);
MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
-module_param_array(xbox, bool, NULL, 0444);
+module_param(xbox, bool, 0444);
MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+static int joystick;
+module_param(joystick, int, 0444);
+
/*
* Direct registers
*/
@@ -539,7 +538,7 @@ static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec)
/* access to some forbidden (non existant) ac97 registers will not
* reset the semaphore. So even if you don't get the semaphore, still
* continue the access. We don't need the semaphore anyway. */
- snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
+ snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
iagetword(chip, 0); /* clear semaphore flag */
/* I don't care about the semaphore */
@@ -554,7 +553,7 @@ static void snd_intel8x0_codec_write(ac97_t *ac97,
if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
if (! chip->in_ac97_init)
- snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
}
iaputword(chip, reg + ac97->num * 0x80, val);
}
@@ -568,7 +567,7 @@ static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
if (! chip->in_ac97_init)
- snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
res = 0xffff;
} else {
res = iagetword(chip, reg + ac97->num * 0x80);
@@ -576,7 +575,7 @@ static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
/* reset RCS and preserve other R/WC bits */
iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
if (! chip->in_ac97_init)
- snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
res = 0xffff;
}
}
@@ -607,16 +606,19 @@ static int snd_intel8x0_ali_codec_ready(intel8x0_t *chip, int mask)
if (val & mask)
return 0;
}
- snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
+ if (! chip->in_ac97_init)
+ snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
return -EBUSY;
}
static int snd_intel8x0_ali_codec_semaphore(intel8x0_t *chip)
{
int time = 100;
+ if (chip->buggy_semaphore)
+ return 0; /* just ignore ... */
while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
udelay(1);
- if (! time)
+ if (! time && ! chip->in_ac97_init)
snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY);
}
@@ -1716,6 +1718,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.type = AC97_TUNE_HP_ONLY
},
{
+ .subvendor = 0x1025,
+ .subdevice = 0x0083,
+ .name = "Acer Aspire 3003LCi",
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
.subvendor = 0x1028,
.subdevice = 0x00d8,
.name = "Dell Precision 530", /* AD1885 */
@@ -1758,6 +1766,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.type = AC97_TUNE_HP_ONLY
},
{
+ .subvendor = 0x1028,
+ .subdevice = 0x0191,
+ .name = "Dell Inspiron 8600",
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
.subvendor = 0x103c,
.subdevice = 0x006d,
.name = "HP zv5000",
@@ -2022,7 +2036,6 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock, const
if ((err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus)) < 0)
goto __err;
pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
- pbus->shared_type = AC97_SHARED_TYPE_ICH; /* shared with modem driver */
if (ac97_clock >= 8000 && ac97_clock <= 48000)
pbus->clock = ac97_clock;
/* FIXME: my test board doesn't work well with VRA... */
@@ -2131,14 +2144,13 @@ static void do_ali_reset(intel8x0_t *chip)
iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383);
iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383);
iputdword(chip, ICHREG(ALI_INTERFACECR),
- ICH_ALI_IF_MC|ICH_ALI_IF_PI|ICH_ALI_IF_PO);
+ ICH_ALI_IF_PI|ICH_ALI_IF_PO);
iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000);
iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
}
#define do_delay(chip) do {\
- set_current_state(TASK_UNINTERRUPTIBLE);\
- schedule_timeout(1);\
+ schedule_timeout_uninterruptible(1);\
} while (0)
static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing)
@@ -2166,7 +2178,7 @@ static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing)
goto __ok;
do_delay(chip);
} while (time_after_eq(end_time, jiffies));
- snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+ snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
return -EIO;
__ok:
@@ -2441,7 +2453,7 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
subs = chip->pcm[0]->streams[0].substream;
if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) {
- snd_printk("no playback buffer allocated - aborting measure ac97 clock\n");
+ snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n");
return;
}
ichdev = &chip->ichd[ICHD_PCMOUT];
@@ -2477,7 +2489,7 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
do_gettimeofday(&stop_time);
/* stop */
if (chip->device_type == DEVICE_ALI) {
- iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8));
+ iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16));
iputbyte(chip, port + ICH_REG_OFF_CR, 0);
while (igetbyte(chip, port + ICH_REG_OFF_CR))
;
@@ -2556,7 +2568,6 @@ struct ich_reg_info {
static int __devinit snd_intel8x0_create(snd_card_t * card,
struct pci_dev *pci,
unsigned long device_type,
- int buggy_sem,
intel8x0_t ** r_intel8x0)
{
intel8x0_t *chip;
@@ -2614,18 +2625,17 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
- chip->buggy_semaphore = buggy_sem;
+
+ /* module parameters */
+ chip->buggy_irq = buggy_irq;
+ chip->buggy_semaphore = buggy_semaphore;
+ if (xbox)
+ chip->xbox = 1;
if (pci->vendor == PCI_VENDOR_ID_INTEL &&
pci->device == PCI_DEVICE_ID_INTEL_440MX)
chip->fix_nocache = 1; /* enable workaround */
- /* some Nforce[2] and ICH boards have problems with IRQ handling.
- * Needs to return IRQ_HANDLED for unknown irqs.
- */
- if (device_type == DEVICE_NFORCE)
- chip->buggy_irq = 1;
-
if ((err = pci_request_regions(pci, card->shortname)) < 0) {
kfree(chip);
pci_disable_device(pci);
@@ -2644,7 +2654,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
chip->remap_addr = ioremap_nocache(chip->addr,
pci_resource_len(pci, 2));
if (chip->remap_addr == NULL) {
- snd_printk("AC'97 space ioremap problem\n");
+ snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
snd_intel8x0_free(chip);
return -EIO;
}
@@ -2657,7 +2667,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
pci_resource_len(pci, 3));
if (chip->remap_bmaddr == NULL) {
- snd_printk("Controller space ioremap problem\n");
+ snd_printk(KERN_ERR "Controller space ioremap problem\n");
snd_intel8x0_free(chip);
return -EIO;
}
@@ -2666,15 +2676,6 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
}
port_inited:
- if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
- snd_intel8x0_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- pci_set_master(pci);
- synchronize_irq(chip->irq);
-
chip->bdbars_count = bdbars[device_type];
/* initialize offsets */
@@ -2725,13 +2726,27 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
int_sta_masks = 0;
for (i = 0; i < chip->bdbars_count; i++) {
ichdev = &chip->ichd[i];
- ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
- ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
+ ichdev->bdbar = ((u32 *)chip->bdbars.area) +
+ (i * ICH_MAX_FRAGS * 2);
+ ichdev->bdbar_addr = chip->bdbars.addr +
+ (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
int_sta_masks |= ichdev->int_sta_mask;
}
- chip->int_sta_reg = device_type == DEVICE_ALI ? ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
+ chip->int_sta_reg = device_type == DEVICE_ALI ?
+ ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
chip->int_sta_mask = int_sta_masks;
+ /* request irq after initializaing int_sta_mask, etc */
+ if (request_irq(pci->irq, snd_intel8x0_interrupt,
+ SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+ snd_intel8x0_free(chip);
+ return -EBUSY;
+ }
+ chip->irq = pci->irq;
+ pci_set_master(pci);
+ synchronize_irq(chip->irq);
+
if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
snd_intel8x0_free(chip);
return err;
@@ -2782,20 +2797,12 @@ static struct shortname_table {
static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
intel8x0_t *chip;
int err;
struct shortname_table *name;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -2819,17 +2826,23 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
}
}
+ if (buggy_irq < 0) {
+ /* some Nforce[2] and ICH boards have problems with IRQ handling.
+ * Needs to return IRQ_HANDLED for unknown irqs.
+ */
+ if (pci_id->driver_data == DEVICE_NFORCE)
+ buggy_irq = 1;
+ else
+ buggy_irq = 0;
+ }
+
if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
- buggy_semaphore[dev], &chip)) < 0) {
+ &chip)) < 0) {
snd_card_free(card);
return err;
}
- if (buggy_irq[dev])
- chip->buggy_irq = 1;
- if (xbox[dev])
- chip->xbox = 1;
- if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev], ac97_quirk[dev])) < 0) {
+ if ((err = snd_intel8x0_mixer(chip, ac97_clock, ac97_quirk)) < 0) {
snd_card_free(card);
return err;
}
@@ -2844,7 +2857,7 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
"%s with %s at %#lx, irq %i", card->shortname,
snd_ac97_get_short_name(chip->ac97[0]), chip->addr, chip->irq);
- if (! ac97_clock[dev])
+ if (! ac97_clock)
intel8x0_measure_ac97_clock(chip);
if ((err = snd_card_register(card)) < 0) {
@@ -2852,7 +2865,6 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
}
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 9e2060d56c24..acfb197a833c 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
*
- * This is modified (by Sasha Khapyorsky <sashak@smlink.com>) version
+ * This is modified (by Sasha Khapyorsky <sashak@alsa-project.org>) version
* of ALSA ICH sound driver intel8x0.c .
*
*
@@ -56,20 +56,21 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
"{NVidia,NForce3 Modem},"
"{AMD,AMD768}}");
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 0;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for Intel i8x0 modemcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel i8x0 modemcard.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/*
* Direct registers
*/
@@ -362,7 +363,7 @@ static int snd_intel8x0m_codec_semaphore(intel8x0_t *chip, unsigned int codec)
/* access to some forbidden (non existant) ac97 registers will not
* reset the semaphore. So even if you don't get the semaphore, still
* continue the access. We don't need the semaphore anyway. */
- snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
+ snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
iagetword(chip, 0); /* clear semaphore flag */
/* I don't care about the semaphore */
@@ -377,7 +378,7 @@ static void snd_intel8x0_codec_write(ac97_t *ac97,
if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
if (! chip->in_ac97_init)
- snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
}
iaputword(chip, reg + ac97->num * 0x80, val);
}
@@ -391,7 +392,7 @@ static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
if (! chip->in_ac97_init)
- snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
res = 0xffff;
} else {
res = iagetword(chip, reg + ac97->num * 0x80);
@@ -399,7 +400,7 @@ static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
/* reset RCS and preserve other R/WC bits */
iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
if (! chip->in_ac97_init)
- snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
+ snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
res = 0xffff;
}
}
@@ -746,6 +747,7 @@ static int __devinit snd_intel8x0_pcm1(intel8x0_t *chip, int device, struct ich_
pcm->private_data = chip;
pcm->info_flags = 0;
+ pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
if (rec->suffix)
sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
else
@@ -854,7 +856,6 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
goto __err;
pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
- pbus->shared_type = AC97_SHARED_TYPE_ICH; /* shared with audio driver */
if (ac97_clock >= 8000 && ac97_clock <= 48000)
pbus->clock = ac97_clock;
chip->ac97_bus = pbus;
@@ -889,8 +890,7 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
*/
#define do_delay(chip) do {\
- set_current_state(TASK_UNINTERRUPTIBLE);\
- schedule_timeout(1);\
+ schedule_timeout_uninterruptible(1);\
} while (0)
static int snd_intel8x0m_ich_chip_init(intel8x0_t *chip, int probing)
@@ -916,7 +916,7 @@ static int snd_intel8x0m_ich_chip_init(intel8x0_t *chip, int probing)
goto __ok;
do_delay(chip);
} while (time_after_eq(end_time, jiffies));
- snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+ snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
return -EIO;
__ok:
@@ -1142,7 +1142,7 @@ static int __devinit snd_intel8x0m_create(snd_card_t * card,
chip->remap_addr = ioremap_nocache(chip->addr,
pci_resource_len(pci, 2));
if (chip->remap_addr == NULL) {
- snd_printk("AC'97 space ioremap problem\n");
+ snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
snd_intel8x0_free(chip);
return -EIO;
}
@@ -1155,7 +1155,7 @@ static int __devinit snd_intel8x0m_create(snd_card_t * card,
chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
pci_resource_len(pci, 3));
if (chip->remap_bmaddr == NULL) {
- snd_printk("Controller space ioremap problem\n");
+ snd_printk(KERN_ERR "Controller space ioremap problem\n");
snd_intel8x0_free(chip);
return -EIO;
}
@@ -1165,7 +1165,7 @@ static int __devinit snd_intel8x0m_create(snd_card_t * card,
port_inited:
if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_intel8x0_free(chip);
return -EBUSY;
}
@@ -1263,20 +1263,12 @@ static struct shortname_table {
static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
intel8x0_t *chip;
int err;
struct shortname_table *name;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -1295,7 +1287,7 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
return err;
}
- if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev])) < 0) {
+ if ((err = snd_intel8x0_mixer(chip, ac97_clock)) < 0) {
snd_card_free(card);
return err;
}
@@ -1314,7 +1306,6 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
}
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 2693b6f731f3..99eb76c56f81 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1492,7 +1492,7 @@ static int snd_m3_pcm_hw_params(snd_pcm_substream_t * substream,
/* set buffer address */
s->buffer_addr = substream->runtime->dma_addr;
if (s->buffer_addr & 0x3) {
- snd_printk("oh my, not aligned\n");
+ snd_printk(KERN_ERR "oh my, not aligned\n");
s->buffer_addr = s->buffer_addr & ~0x3;
}
return 0;
@@ -1942,7 +1942,7 @@ static int snd_m3_ac97_wait(m3_t *chip)
return 0;
} while (i-- > 0);
- snd_printk("ac97 serial bus busy\n");
+ snd_printk(KERN_ERR "ac97 serial bus busy\n");
return 1;
}
@@ -2046,8 +2046,7 @@ static void snd_m3_ac97_reset(m3_t *chip)
outw(0, io + GPIO_DATA);
outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((delay1 * HZ) / 1000);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(delay1));
outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
udelay(5);
@@ -2055,8 +2054,7 @@ static void snd_m3_ac97_reset(m3_t *chip)
outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
outw(~0, io + GPIO_MASK);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((delay2 * HZ) / 1000);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(delay2));
if (! snd_m3_try_read_vendor(chip))
break;
@@ -2101,8 +2099,7 @@ static int __devinit snd_m3_mixer(m3_t *chip)
/* seems ac97 PCM needs initialization.. hack hack.. */
snd_ac97_write(chip->ac97, AC97_PCM, 0x8000 | (15 << 8) | 15);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ / 10);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(100));
snd_ac97_write(chip->ac97, AC97_PCM, 0);
memset(&id, 0, sizeof(id));
@@ -2367,7 +2364,7 @@ static int __devinit snd_m3_assp_client_init(m3_t *chip, m3_dma_t *s, int index)
address = 0x1100 + ((data_bytes/2) * index);
if ((address + (data_bytes/2)) >= 0x1c00) {
- snd_printk("no memory for %d bytes at ind %d (addr 0x%x)\n",
+ snd_printk(KERN_ERR "no memory for %d bytes at ind %d (addr 0x%x)\n",
data_bytes, index, address);
return -ENOMEM;
}
@@ -2476,6 +2473,7 @@ snd_m3_chip_init(m3_t *chip)
t |= ASSP_0_WS_ENABLE;
outb(t, chip->iobase + ASSP_CONTROL_A);
+ snd_m3_assp_init(chip); /* download DSP code before starting ASSP below */
outb(RUN_ASSP, chip->iobase + ASSP_CONTROL_B);
outb(0x00, io + HARDWARE_VOL_CTRL);
@@ -2655,7 +2653,7 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci,
/* check, if we can restrict PCI DMA transfers to 28 bits */
if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
- snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -2734,14 +2732,13 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci,
snd_m3_ac97_reset(chip);
- snd_m3_assp_init(chip);
snd_m3_amp_enable(chip, 1);
tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ,
card->driver, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_m3_free(chip);
return -ENOMEM;
}
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 1a62c7f6c52b..c341c99ec783 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -451,8 +451,7 @@ static int mixart_sync_nonblock_events(mixart_mgr_t *mgr)
snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n");
return -EBUSY;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
return 0;
}
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 5c55a3b1d121..e7aa15178453 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -52,37 +52,43 @@ MODULE_SUPPORTED_DEVICE("{{NeoMagic,NM256AV},"
* some compile conditions.
*/
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int playback_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
-static int capture_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
-static int force_ac97[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled as default */
-static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not specified */
-static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
-static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
-static int reset_workaround[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
+static int index = SNDRV_DEFAULT_IDX1; /* Index */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int playback_bufsize = 16;
+static int capture_bufsize = 16;
+static int force_ac97; /* disabled as default */
+static int buffer_top; /* not specified */
+static int use_cache; /* disabled */
+static int vaio_hack; /* disabled */
+static int reset_workaround;
+static int reset_workaround_2;
+
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this soundcard.");
-module_param_array(playback_bufsize, int, NULL, 0444);
+module_param(playback_bufsize, int, 0444);
MODULE_PARM_DESC(playback_bufsize, "DAC frame size in kB for " CARD_NAME " soundcard.");
-module_param_array(capture_bufsize, int, NULL, 0444);
+module_param(capture_bufsize, int, 0444);
MODULE_PARM_DESC(capture_bufsize, "ADC frame size in kB for " CARD_NAME " soundcard.");
-module_param_array(force_ac97, bool, NULL, 0444);
+module_param(force_ac97, bool, 0444);
MODULE_PARM_DESC(force_ac97, "Force to use AC97 codec for " CARD_NAME " soundcard.");
-module_param_array(buffer_top, int, NULL, 0444);
+module_param(buffer_top, int, 0444);
MODULE_PARM_DESC(buffer_top, "Set the top address of audio buffer for " CARD_NAME " soundcard.");
-module_param_array(use_cache, bool, NULL, 0444);
+module_param(use_cache, bool, 0444);
MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access.");
-module_param_array(vaio_hack, bool, NULL, 0444);
+module_param(vaio_hack, bool, 0444);
MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks.");
-module_param_array(reset_workaround, bool, NULL, 0444);
+module_param(reset_workaround, bool, 0444);
MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops.");
+module_param(reset_workaround_2, bool, 0444);
+MODULE_PARM_DESC(reset_workaround_2, "Enable extended AC97 RESET workaround for some other laptops.");
+
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
+
/*
* hw definitions
@@ -226,6 +232,7 @@ struct snd_nm256 {
unsigned int coeffs_current: 1; /* coeff. table is loaded? */
unsigned int use_cache: 1; /* use one big coef. table */
unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */
+ unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */
int mixer_base; /* register offset of ac97 mixer */
int mixer_status_offset; /* offset of mixer status reg. */
@@ -313,9 +320,9 @@ static inline void
snd_nm256_write_buffer(nm256_t *chip, void *src, int offset, int size)
{
offset -= chip->buffer_start;
-#ifdef SNDRV_CONFIG_DEBUG
+#ifdef CONFIG_SND_DEBUG
if (offset < 0 || offset >= chip->buffer_size) {
- snd_printk("write_buffer invalid offset = %d size = %d\n", offset, size);
+ snd_printk(KERN_ERR "write_buffer invalid offset = %d size = %d\n", offset, size);
return;
}
#endif
@@ -459,7 +466,7 @@ static int snd_nm256_acquire_irq(nm256_t *chip)
if (chip->irq < 0) {
if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ,
chip->card->driver, (void*)chip)) {
- snd_printk("unable to grab IRQ %d\n", chip->pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
up(&chip->irq_mutex);
return -EBUSY;
}
@@ -1199,8 +1206,11 @@ snd_nm256_ac97_reset(ac97_t *ac97)
/* Dell latitude LS will lock up by this */
snd_nm256_writeb(chip, 0x6cc, 0x87);
}
- snd_nm256_writeb(chip, 0x6cc, 0x80);
- snd_nm256_writeb(chip, 0x6cc, 0x0);
+ if (! chip->reset_workaround_2) {
+ /* Dell latitude CSx will lock up by this */
+ snd_nm256_writeb(chip, 0x6cc, 0x80);
+ snd_nm256_writeb(chip, 0x6cc, 0x0);
+ }
}
/* create an ac97 mixer interface */
@@ -1263,7 +1273,7 @@ snd_nm256_peek_for_sig(nm256_t *chip)
temp = ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16);
if (temp == NULL) {
- snd_printk("Unable to scan for card signature in video RAM\n");
+ snd_printk(KERN_ERR "Unable to scan for card signature in video RAM\n");
return -EBUSY;
}
@@ -1277,7 +1287,7 @@ snd_nm256_peek_for_sig(nm256_t *chip)
if (pointer == 0xffffffff ||
pointer < chip->buffer_size ||
pointer > chip->buffer_end) {
- snd_printk("invalid signature found: 0x%x\n", pointer);
+ snd_printk(KERN_ERR "invalid signature found: 0x%x\n", pointer);
iounmap(temp);
return -ENODEV;
} else {
@@ -1347,14 +1357,8 @@ static int snd_nm256_free(nm256_t *chip)
iounmap(chip->cport);
if (chip->buffer)
iounmap(chip->buffer);
- if (chip->res_cport) {
- release_resource(chip->res_cport);
- kfree_nocheck(chip->res_cport);
- }
- if (chip->res_buffer) {
- release_resource(chip->res_buffer);
- kfree_nocheck(chip->res_buffer);
- }
+ release_and_free_resource(chip->res_cport);
+ release_and_free_resource(chip->res_buffer);
if (chip->irq >= 0)
free_irq(chip->irq, (void*)chip);
@@ -1420,14 +1424,14 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE,
card->driver);
if (chip->res_cport == NULL) {
- snd_printk("memory region 0x%lx (size 0x%x) busy\n",
+ snd_printk(KERN_ERR "memory region 0x%lx (size 0x%x) busy\n",
chip->cport_addr, NM_PORT2_SIZE);
err = -EBUSY;
goto __error;
}
chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE);
if (chip->cport == NULL) {
- snd_printk("unable to map control port %lx\n", chip->cport_addr);
+ snd_printk(KERN_ERR "unable to map control port %lx\n", chip->cport_addr);
err = -ENOMEM;
goto __error;
}
@@ -1485,7 +1489,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
chip->buffer_size,
card->driver);
if (chip->res_buffer == NULL) {
- snd_printk("nm256: buffer 0x%lx (size 0x%x) busy\n",
+ snd_printk(KERN_ERR "nm256: buffer 0x%lx (size 0x%x) busy\n",
chip->buffer_addr, chip->buffer_size);
err = -EBUSY;
goto __error;
@@ -1493,7 +1497,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size);
if (chip->buffer == NULL) {
err = -ENOMEM;
- snd_printk("unable to map ring buffer at %lx\n", chip->buffer_addr);
+ snd_printk(KERN_ERR "unable to map ring buffer at %lx\n", chip->buffer_addr);
goto __error;
}
@@ -1542,7 +1546,7 @@ struct nm256_quirk {
int type;
};
-enum { NM_BLACKLISTED, NM_RESET_WORKAROUND };
+enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 };
static struct nm256_quirk nm256_quirks[] __devinitdata = {
/* HP omnibook 4150 has cs4232 codec internally */
@@ -1551,6 +1555,8 @@ static struct nm256_quirk nm256_quirks[] __devinitdata = {
{ .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND },
/* Dell Latitude LS */
{ .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND },
+ /* Dell Latitude CSx */
+ { .vendor = 0x1028, .device = 0x0091, .type = NM_RESET_WORKAROUND_2 },
{ } /* terminator */
};
@@ -1558,7 +1564,6 @@ static struct nm256_quirk nm256_quirks[] __devinitdata = {
static int __devinit snd_nm256_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
nm256_t *chip;
int err;
@@ -1566,13 +1571,6 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
struct nm256_quirk *q;
u16 subsystem_vendor, subsystem_device;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
@@ -1582,14 +1580,17 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
case NM_BLACKLISTED:
printk(KERN_INFO "nm256: The device is blacklisted. Loading stopped\n");
return -ENODEV;
+ case NM_RESET_WORKAROUND_2:
+ reset_workaround_2 = 1;
+ /* Fall-through */
case NM_RESET_WORKAROUND:
- reset_workaround[dev] = 1;
+ reset_workaround = 1;
break;
}
}
}
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -1604,40 +1605,45 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
strcpy(card->driver, "NM256XL+");
break;
default:
- snd_printk("invalid device id 0x%x\n", pci->device);
+ snd_printk(KERN_ERR "invalid device id 0x%x\n", pci->device);
snd_card_free(card);
return -EINVAL;
}
- if (vaio_hack[dev])
+ if (vaio_hack)
xbuffer_top = 0x25a800; /* this avoids conflicts with XFree86 server */
else
- xbuffer_top = buffer_top[dev];
-
- if (playback_bufsize[dev] < 4)
- playback_bufsize[dev] = 4;
- if (playback_bufsize[dev] > 128)
- playback_bufsize[dev] = 128;
- if (capture_bufsize[dev] < 4)
- capture_bufsize[dev] = 4;
- if (capture_bufsize[dev] > 128)
- capture_bufsize[dev] = 128;
+ xbuffer_top = buffer_top;
+
+ if (playback_bufsize < 4)
+ playback_bufsize = 4;
+ if (playback_bufsize > 128)
+ playback_bufsize = 128;
+ if (capture_bufsize < 4)
+ capture_bufsize = 4;
+ if (capture_bufsize > 128)
+ capture_bufsize = 128;
if ((err = snd_nm256_create(card, pci,
- playback_bufsize[dev] * 1024, /* in bytes */
- capture_bufsize[dev] * 1024, /* in bytes */
- force_ac97[dev],
+ playback_bufsize * 1024, /* in bytes */
+ capture_bufsize * 1024, /* in bytes */
+ force_ac97,
xbuffer_top,
- use_cache[dev],
+ use_cache,
&chip)) < 0) {
snd_card_free(card);
return err;
}
- if (reset_workaround[dev]) {
+ if (reset_workaround) {
snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
chip->reset_workaround = 1;
}
+ if (reset_workaround_2) {
+ snd_printdd(KERN_INFO "nm256: reset_workaround_2 activated\n");
+ chip->reset_workaround_2 = 1;
+ }
+
if ((err = snd_nm256_pcm(chip, 0)) < 0 ||
(err = snd_nm256_mixer(chip)) < 0) {
snd_card_free(card);
@@ -1655,7 +1661,6 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
}
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index cd313af6ebcf..e6627b0e38e4 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1369,13 +1369,13 @@ static int __devinit snd_rme32_create(rme32_t * rme32)
rme32->port = pci_resource_start(rme32->pci, 0);
if (request_irq(pci->irq, snd_rme32_interrupt, SA_INTERRUPT | SA_SHIRQ, "RME32", (void *) rme32)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
return -EBUSY;
}
rme32->irq = pci->irq;
if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) {
- snd_printk("unable to remap memory region 0x%lx-0x%lx\n",
+ snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n",
rme32->port, rme32->port + RME32_IO_SIZE - 1);
return -ENOMEM;
}
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index c495cae78dbf..0eddeb16a10f 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1570,13 +1570,13 @@ snd_rme96_create(rme96_t *rme96)
rme96->port = pci_resource_start(rme96->pci, 0);
if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
return -EBUSY;
}
rme96->irq = pci->irq;
if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
- snd_printk("unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
+ snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
return -ENOMEM;
}
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 52525eb198c7..845158b01b02 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -671,11 +671,7 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) {
}
}
- if ((1000 / HZ) < 3000) {
- ssleep(3);
- } else {
- mdelay(3000);
- }
+ ssleep(3);
if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
@@ -692,7 +688,7 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) {
}
if (hdsp->state & HDSP_InitializationComplete) {
- snd_printk("Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
+ snd_printk(KERN_INFO "Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
spin_lock_irqsave(&hdsp->lock, flags);
snd_hdsp_set_defaults(hdsp);
spin_unlock_irqrestore(&hdsp->lock, flags);
@@ -709,9 +705,8 @@ static int hdsp_get_iobox_version (hdsp_t *hdsp)
hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
hdsp_write (hdsp, HDSP_fifoData, 0);
- if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
return -EIO;
- }
hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
hdsp_write (hdsp, HDSP_fifoData, 0);
@@ -726,22 +721,30 @@ static int hdsp_get_iobox_version (hdsp_t *hdsp)
}
} else {
/* firmware was already loaded, get iobox type */
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
+ if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
hdsp->io_type = Multiface;
- } else {
+ else
hdsp->io_type = Digiface;
- }
}
return 0;
}
-static int hdsp_check_for_firmware (hdsp_t *hdsp)
+static int hdsp_check_for_firmware (hdsp_t *hdsp, int show_err)
{
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
- snd_printk("Hammerfall-DSP: firmware not present.\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");
hdsp->state &= ~HDSP_FirmwareLoaded;
+ if (! show_err)
+ return -EIO;
+ /* try to load firmware */
+ if (hdsp->state & HDSP_FirmwareCached) {
+ if (snd_hdsp_load_firmware_from_cache(hdsp) != 0)
+ snd_printk(KERN_ERR "Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
+ } else {
+ snd_printk(KERN_ERR "Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
+ }
return -EIO;
}
return 0;
@@ -775,9 +778,9 @@ static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout)
static int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr)
{
- if (addr >= HDSP_MATRIX_MIXER_SIZE) {
+ if (addr >= HDSP_MATRIX_MIXER_SIZE)
return 0;
- }
+
return hdsp->mixer_matrix[addr];
}
@@ -802,13 +805,11 @@ static int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data)
memory."
*/
- if (hdsp->io_type == H9632 && addr >= 512) {
+ if (hdsp->io_type == H9632 && addr >= 512)
return 0;
- }
- if (hdsp->io_type == H9652 && addr >= 1352) {
+ if (hdsp->io_type == H9652 && addr >= 1352)
return 0;
- }
hdsp->mixer_matrix[addr] = data;
@@ -832,9 +833,8 @@ static int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data)
ad = (addr << 16) + data;
- if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT)) {
+ if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT))
return -1;
- }
hdsp_write (hdsp, HDSP_fifoData, ad);
hdsp->mixer_matrix[addr] = data;
@@ -851,9 +851,8 @@ static int snd_hdsp_use_is_exclusive(hdsp_t *hdsp)
spin_lock_irqsave(&hdsp->lock, flags);
if ((hdsp->playback_pid != hdsp->capture_pid) &&
- (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0)) {
+ (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0))
ret = 0;
- }
spin_unlock_irqrestore(&hdsp->lock, flags);
return ret;
}
@@ -880,9 +879,8 @@ static int hdsp_spdif_sample_rate(hdsp_t *hdsp)
unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);
unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);
- if (status & HDSP_SPDIFErrorFlag) {
+ if (status & HDSP_SPDIFErrorFlag)
return 0;
- }
switch (rate_bits) {
case HDSP_spdifFrequency32KHz: return 32000;
@@ -918,9 +916,8 @@ static snd_pcm_uframes_t hdsp_hw_pointer(hdsp_t *hdsp)
position = hdsp_read(hdsp, HDSP_statusRegister);
- if (!hdsp->precise_ptr) {
+ if (!hdsp->precise_ptr)
return (position & HDSP_BufferID) ? (hdsp->period_bytes / 4) : 0;
- }
position &= HDSP_BufferPositionMask;
position /= 4;
@@ -989,19 +986,19 @@ static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
if (!(hdsp->control_register & HDSP_ClockModeMaster)) {
if (called_internally) {
/* request from ctl or card initialization */
- snd_printk("Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
return -1;
} else {
/* hw_param request while in AutoSync mode */
int external_freq = hdsp_external_sample_rate(hdsp);
int spdif_freq = hdsp_spdif_sample_rate(hdsp);
- if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
- snd_printk("Hammerfall-DSP: Detected ADAT in double speed mode\n");
- } else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
- snd_printk("Hammerfall-DSP: Detected ADAT in quad speed mode\n");
- } else if (rate != external_freq) {
- snd_printk("Hammerfall-DSP: No AutoSync source for requested rate\n");
+ if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
+ snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in double speed mode\n");
+ else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
+ snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in quad speed mode\n");
+ else if (rate != external_freq) {
+ snd_printk(KERN_INFO "Hammerfall-DSP: No AutoSync source for requested rate\n");
return -1;
}
}
@@ -1019,63 +1016,53 @@ static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
exists for externally-driven rate changes. All we can do
is to flag rate changes in the read/write routines. */
- if (rate > 96000 && hdsp->io_type != H9632) {
+ if (rate > 96000 && hdsp->io_type != H9632)
return -EINVAL;
- }
switch (rate) {
case 32000:
- if (current_rate > 48000) {
+ if (current_rate > 48000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency32KHz;
break;
case 44100:
- if (current_rate > 48000) {
+ if (current_rate > 48000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency44_1KHz;
break;
case 48000:
- if (current_rate > 48000) {
+ if (current_rate > 48000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency48KHz;
break;
case 64000:
- if (current_rate <= 48000 || current_rate > 96000) {
+ if (current_rate <= 48000 || current_rate > 96000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency64KHz;
break;
case 88200:
- if (current_rate <= 48000 || current_rate > 96000) {
+ if (current_rate <= 48000 || current_rate > 96000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency88_2KHz;
break;
case 96000:
- if (current_rate <= 48000 || current_rate > 96000) {
+ if (current_rate <= 48000 || current_rate > 96000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency96KHz;
break;
case 128000:
- if (current_rate < 128000) {
+ if (current_rate < 128000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency128KHz;
break;
case 176400:
- if (current_rate < 128000) {
+ if (current_rate < 128000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency176_4KHz;
break;
case 192000:
- if (current_rate < 128000) {
+ if (current_rate < 128000)
reject_if_open = 1;
- }
rate_bits = HDSP_Frequency192KHz;
break;
default:
@@ -1096,11 +1083,10 @@ static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
if (rate >= 128000) {
hdsp->channel_map = channel_map_H9632_qs;
} else if (rate > 48000) {
- if (hdsp->io_type == H9632) {
+ if (hdsp->io_type == H9632)
hdsp->channel_map = channel_map_H9632_ds;
- } else {
+ else
hdsp->channel_map = channel_map_ds;
- }
} else {
switch (hdsp->io_type) {
case Multiface:
@@ -1131,54 +1117,48 @@ static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
static unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id)
{
/* the hardware already does the relevant bit-mask with 0xff */
- if (id) {
+ if (id)
return hdsp_read(hdsp, HDSP_midiDataIn1);
- } else {
+ else
return hdsp_read(hdsp, HDSP_midiDataIn0);
- }
}
static void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val)
{
/* the hardware already does the relevant bit-mask with 0xff */
- if (id) {
+ if (id)
hdsp_write(hdsp, HDSP_midiDataOut1, val);
- } else {
+ else
hdsp_write(hdsp, HDSP_midiDataOut0, val);
- }
}
static int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id)
{
- if (id) {
+ if (id)
return (hdsp_read(hdsp, HDSP_midiStatusIn1) & 0xff);
- } else {
+ else
return (hdsp_read(hdsp, HDSP_midiStatusIn0) & 0xff);
- }
}
static int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id)
{
int fifo_bytes_used;
- if (id) {
+ if (id)
fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff;
- } else {
+ else
fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff;
- }
- if (fifo_bytes_used < 128) {
+ if (fifo_bytes_used < 128)
return 128 - fifo_bytes_used;
- } else {
+ else
return 0;
- }
}
static void snd_hdsp_flush_midi_input (hdsp_t *hdsp, int id)
{
- while (snd_hdsp_midi_input_available (hdsp, id)) {
+ while (snd_hdsp_midi_input_available (hdsp, id))
snd_hdsp_midi_read_byte (hdsp, id);
- }
}
static int snd_hdsp_midi_output_write (hdsp_midi_t *hmidi)
@@ -1219,28 +1199,23 @@ static int snd_hdsp_midi_input_read (hdsp_midi_t *hmidi)
spin_lock_irqsave (&hmidi->lock, flags);
if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) {
if (hmidi->input) {
- if (n_pending > (int)sizeof (buf)) {
+ if (n_pending > (int)sizeof (buf))
n_pending = sizeof (buf);
- }
- for (i = 0; i < n_pending; ++i) {
+ for (i = 0; i < n_pending; ++i)
buf[i] = snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
- }
- if (n_pending) {
+ if (n_pending)
snd_rawmidi_receive (hmidi->input, buf, n_pending);
- }
} else {
/* flush the MIDI input FIFO */
- while (--n_pending) {
+ while (--n_pending)
snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
- }
}
}
hmidi->pending = 0;
- if (hmidi->id) {
+ if (hmidi->id)
hmidi->hdsp->control_register |= HDSP_Midi1InterruptEnable;
- } else {
+ else
hmidi->hdsp->control_register |= HDSP_Midi0InterruptEnable;
- }
hdsp_write(hmidi->hdsp, HDSP_controlRegister, hmidi->hdsp->control_register);
spin_unlock_irqrestore (&hmidi->lock, flags);
return snd_hdsp_midi_output_write (hmidi);
@@ -1310,9 +1285,8 @@ static void snd_hdsp_midi_output_trigger(snd_rawmidi_substream_t * substream, in
hmidi->istimer++;
}
} else {
- if (hmidi->istimer && --hmidi->istimer <= 0) {
+ if (hmidi->istimer && --hmidi->istimer <= 0)
del_timer (&hmidi->timer);
- }
}
spin_unlock_irqrestore (&hmidi->lock, flags);
if (up)
@@ -1400,9 +1374,8 @@ static int __devinit snd_hdsp_create_midi (snd_card_t *card, hdsp_t *hdsp, int i
spin_lock_init (&hdsp->midi[id].lock);
sprintf (buf, "%s MIDI %d", card->shortname, id+1);
- if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0) {
+ if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
return -1;
- }
sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);
hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
@@ -1588,11 +1561,10 @@ static int hdsp_spdif_out(hdsp_t *hdsp)
static int hdsp_set_spdif_output(hdsp_t *hdsp, int out)
{
- if (out) {
+ if (out)
hdsp->control_register |= HDSP_SPDIFOpticalOut;
- } else {
+ else
hdsp->control_register &= ~HDSP_SPDIFOpticalOut;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -1642,11 +1614,10 @@ static int hdsp_spdif_professional(hdsp_t *hdsp)
static int hdsp_set_spdif_professional(hdsp_t *hdsp, int val)
{
- if (val) {
+ if (val)
hdsp->control_register |= HDSP_SPDIFProfessional;
- } else {
+ else
hdsp->control_register &= ~HDSP_SPDIFProfessional;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -1687,11 +1658,10 @@ static int hdsp_spdif_emphasis(hdsp_t *hdsp)
static int hdsp_set_spdif_emphasis(hdsp_t *hdsp, int val)
{
- if (val) {
+ if (val)
hdsp->control_register |= HDSP_SPDIFEmphasis;
- } else {
+ else
hdsp->control_register &= ~HDSP_SPDIFEmphasis;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -1732,11 +1702,10 @@ static int hdsp_spdif_nonaudio(hdsp_t *hdsp)
static int hdsp_set_spdif_nonaudio(hdsp_t *hdsp, int val)
{
- if (val) {
+ if (val)
hdsp->control_register |= HDSP_SPDIFNonAudio;
- } else {
+ else
hdsp->control_register &= ~HDSP_SPDIFNonAudio;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -1921,11 +1890,10 @@ static int snd_hdsp_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_
static int hdsp_system_clock_mode(hdsp_t *hdsp)
{
- if (hdsp->control_register & HDSP_ClockModeMaster) {
+ if (hdsp->control_register & HDSP_ClockModeMaster)
return 0;
- } else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate) {
+ else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate)
return 0;
- }
return 1;
}
@@ -2074,16 +2042,17 @@ static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
val = ucontrol->value.enumerated.item[0];
if (val < 0) val = 0;
if (hdsp->io_type == H9632) {
- if (val > 9) val = 9;
+ if (val > 9)
+ val = 9;
} else {
- if (val > 6) val = 6;
+ if (val > 6)
+ val = 6;
}
spin_lock_irq(&hdsp->lock);
- if (val != hdsp_clock_source(hdsp)) {
+ if (val != hdsp_clock_source(hdsp))
change = (hdsp_set_clock_source(hdsp, val) == 0) ? 1 : 0;
- } else {
+ else
change = 0;
- }
spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2193,11 +2162,10 @@ static int snd_hdsp_put_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
if (val < 0) val = 0;
if (val > 2) val = 2;
spin_lock_irq(&hdsp->lock);
- if (val != hdsp_da_gain(hdsp)) {
+ if (val != hdsp_da_gain(hdsp))
change = (hdsp_set_da_gain(hdsp, val) == 0) ? 1 : 0;
- } else {
+ else
change = 0;
- }
spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2279,11 +2247,10 @@ static int snd_hdsp_put_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
if (val < 0) val = 0;
if (val > 2) val = 2;
spin_lock_irq(&hdsp->lock);
- if (val != hdsp_ad_gain(hdsp)) {
+ if (val != hdsp_ad_gain(hdsp))
change = (hdsp_set_ad_gain(hdsp, val) == 0) ? 1 : 0;
- } else {
+ else
change = 0;
- }
spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2365,11 +2332,10 @@ static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
if (val < 0) val = 0;
if (val > 2) val = 2;
spin_lock_irq(&hdsp->lock);
- if (val != hdsp_phone_gain(hdsp)) {
+ if (val != hdsp_phone_gain(hdsp))
change = (hdsp_set_phone_gain(hdsp, val) == 0) ? 1 : 0;
- } else {
+ else
change = 0;
- }
spin_unlock_irq(&hdsp->lock);
return change;
}
@@ -2385,19 +2351,17 @@ static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
static int hdsp_xlr_breakout_cable(hdsp_t *hdsp)
{
- if (hdsp->control_register & HDSP_XLRBreakoutCable) {
+ if (hdsp->control_register & HDSP_XLRBreakoutCable)
return 1;
- }
return 0;
}
static int hdsp_set_xlr_breakout_cable(hdsp_t *hdsp, int mode)
{
- if (mode) {
+ if (mode)
hdsp->control_register |= HDSP_XLRBreakoutCable;
- } else {
+ else
hdsp->control_register &= ~HDSP_XLRBreakoutCable;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -2450,19 +2414,17 @@ static int snd_hdsp_put_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_el
static int hdsp_aeb(hdsp_t *hdsp)
{
- if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
+ if (hdsp->control_register & HDSP_AnalogExtensionBoard)
return 1;
- }
return 0;
}
static int hdsp_set_aeb(hdsp_t *hdsp, int mode)
{
- if (mode) {
+ if (mode)
hdsp->control_register |= HDSP_AnalogExtensionBoard;
- } else {
+ else
hdsp->control_register &= ~HDSP_AnalogExtensionBoard;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -2705,11 +2667,10 @@ static int hdsp_line_out(hdsp_t *hdsp)
static int hdsp_set_line_output(hdsp_t *hdsp, int out)
{
- if (out) {
+ if (out)
hdsp->control_register |= HDSP_LineOut;
- } else {
+ else
hdsp->control_register &= ~HDSP_LineOut;
- }
hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
return 0;
}
@@ -2760,11 +2721,10 @@ static int snd_hdsp_put_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
static int hdsp_set_precise_pointer(hdsp_t *hdsp, int precise)
{
- if (precise) {
+ if (precise)
hdsp->precise_ptr = 1;
- } else {
+ else
hdsp->precise_ptr = 0;
- }
return 0;
}
@@ -2814,11 +2774,10 @@ static int snd_hdsp_put_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_
static int hdsp_set_use_midi_tasklet(hdsp_t *hdsp, int use_tasklet)
{
- if (use_tasklet) {
+ if (use_tasklet)
hdsp->use_midi_tasklet = 1;
- } else {
+ else
hdsp->use_midi_tasklet = 0;
- }
return 0;
}
@@ -2889,11 +2848,10 @@ static int snd_hdsp_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *
source = ucontrol->value.integer.value[0];
destination = ucontrol->value.integer.value[1];
- if (source >= hdsp->max_channels) {
+ if (source >= hdsp->max_channels)
addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels,destination);
- } else {
+ else
addr = hdsp_input_to_output_key(hdsp,source, destination);
- }
spin_lock_irq(&hdsp->lock);
ucontrol->value.integer.value[2] = hdsp_read_gain (hdsp, addr);
@@ -2916,11 +2874,10 @@ static int snd_hdsp_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *
source = ucontrol->value.integer.value[0];
destination = ucontrol->value.integer.value[1];
- if (source >= hdsp->max_channels) {
+ if (source >= hdsp->max_channels)
addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels, destination);
- } else {
+ else
addr = hdsp_input_to_output_key(hdsp,source, destination);
- }
gain = ucontrol->value.integer.value[2];
@@ -2957,14 +2914,12 @@ static int hdsp_wc_sync_check(hdsp_t *hdsp)
{
int status2 = hdsp_read(hdsp, HDSP_status2Register);
if (status2 & HDSP_wc_lock) {
- if (status2 & HDSP_wc_sync) {
+ if (status2 & HDSP_wc_sync)
return 2;
- } else {
+ else
return 1;
- }
- } else {
+ } else
return 0;
- }
return 0;
}
@@ -2988,14 +2943,13 @@ static int snd_hdsp_get_wc_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_va
static int hdsp_spdif_sync_check(hdsp_t *hdsp)
{
int status = hdsp_read(hdsp, HDSP_statusRegister);
- if (status & HDSP_SPDIFErrorFlag) {
+ if (status & HDSP_SPDIFErrorFlag)
return 0;
- } else {
- if (status & HDSP_SPDIFSync) {
+ else {
+ if (status & HDSP_SPDIFSync)
return 2;
- } else {
+ else
return 1;
- }
}
return 0;
}
@@ -3021,14 +2975,12 @@ static int hdsp_adatsync_sync_check(hdsp_t *hdsp)
{
int status = hdsp_read(hdsp, HDSP_statusRegister);
if (status & HDSP_TimecodeLock) {
- if (status & HDSP_TimecodeSync) {
+ if (status & HDSP_TimecodeSync)
return 2;
- } else {
+ else
return 1;
- }
- } else {
+ } else
return 0;
- }
}
static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
@@ -3051,14 +3003,12 @@ static int hdsp_adat_sync_check(hdsp_t *hdsp, int idx)
int status = hdsp_read(hdsp, HDSP_statusRegister);
if (status & (HDSP_Lock0>>idx)) {
- if (status & (HDSP_Sync0>>idx)) {
+ if (status & (HDSP_Sync0>>idx))
return 2;
- } else {
+ else
return 1;
- }
- } else {
+ } else
return 0;
- }
}
static int snd_hdsp_get_adat_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
@@ -3171,9 +3121,8 @@ static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
snd_kcontrol_t *kctl;
for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) {
+ if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
return err;
- }
if (idx == 1) /* IEC958 (S/PDIF) Stream */
hdsp->spdif_ctl = kctl;
}
@@ -3181,32 +3130,28 @@ static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
/* ADAT SyncCheck status */
snd_hdsp_adat_sync_check.name = "ADAT Lock Status";
snd_hdsp_adat_sync_check.index = 1;
- if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
+ if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
return err;
- }
if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
for (idx = 1; idx < 3; ++idx) {
snd_hdsp_adat_sync_check.index = idx+1;
- if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
+ if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
return err;
- }
}
}
/* DA, AD and Phone gain and XLR breakout cable controls for H9632 cards */
if (hdsp->io_type == H9632) {
for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_9632_controls); idx++) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0) {
+ if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0)
return err;
- }
}
}
/* AEB control for H96xx card */
if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0) {
+ if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0)
return err;
- }
}
return 0;
@@ -3228,12 +3173,11 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
char *clock_source;
int x;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n");
return;
- }
- if (hdsp_check_for_firmware(hdsp)) {
+ if (hdsp_check_for_firmware(hdsp, 0)) {
if (hdsp->state & HDSP_FirmwareCached) {
if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
snd_iprintf(buffer, "Firmware loading from cache failed, please upload manually.\n");
@@ -3314,11 +3258,10 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
}
snd_iprintf (buffer, "Sample Clock Source: %s\n", clock_source);
- if (hdsp_system_clock_mode(hdsp)) {
+ if (hdsp_system_clock_mode(hdsp))
system_clock_mode = "Slave";
- } else {
+ else
system_clock_mode = "Master";
- }
switch (hdsp_pref_sync_ref (hdsp)) {
case HDSP_SYNC_FROM_WORD:
@@ -3400,85 +3343,75 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
break;
}
- if (hdsp->control_register & HDSP_SPDIFOpticalOut) {
+ if (hdsp->control_register & HDSP_SPDIFOpticalOut)
snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
- } else {
+ else
snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
- }
- if (hdsp->control_register & HDSP_SPDIFProfessional) {
+ if (hdsp->control_register & HDSP_SPDIFProfessional)
snd_iprintf(buffer, "IEC958 quality: Professional\n");
- } else {
+ else
snd_iprintf(buffer, "IEC958 quality: Consumer\n");
- }
- if (hdsp->control_register & HDSP_SPDIFEmphasis) {
+ if (hdsp->control_register & HDSP_SPDIFEmphasis)
snd_iprintf(buffer, "IEC958 emphasis: on\n");
- } else {
+ else
snd_iprintf(buffer, "IEC958 emphasis: off\n");
- }
- if (hdsp->control_register & HDSP_SPDIFNonAudio) {
+ if (hdsp->control_register & HDSP_SPDIFNonAudio)
snd_iprintf(buffer, "IEC958 NonAudio: on\n");
- } else {
+ else
snd_iprintf(buffer, "IEC958 NonAudio: off\n");
- }
- if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) {
+ if ((x = hdsp_spdif_sample_rate (hdsp)) != 0)
snd_iprintf (buffer, "IEC958 sample rate: %d\n", x);
- } else {
+ else
snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n");
- }
snd_iprintf(buffer, "\n");
/* Sync Check */
x = status & HDSP_Sync0;
- if (status & HDSP_Lock0) {
+ if (status & HDSP_Lock0)
snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf(buffer, "ADAT1: No Lock\n");
- }
switch (hdsp->io_type) {
case Digiface:
case H9652:
x = status & HDSP_Sync1;
- if (status & HDSP_Lock1) {
+ if (status & HDSP_Lock1)
snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf(buffer, "ADAT2: No Lock\n");
- }
x = status & HDSP_Sync2;
- if (status & HDSP_Lock2) {
+ if (status & HDSP_Lock2)
snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf(buffer, "ADAT3: No Lock\n");
- }
+ break;
default:
/* relax */
break;
}
x = status & HDSP_SPDIFSync;
- if (status & HDSP_SPDIFErrorFlag) {
+ if (status & HDSP_SPDIFErrorFlag)
snd_iprintf (buffer, "SPDIF: No Lock\n");
- } else {
+ else
snd_iprintf (buffer, "SPDIF: %s\n", x ? "Sync" : "Lock");
- }
x = status2 & HDSP_wc_sync;
- if (status2 & HDSP_wc_lock) {
+ if (status2 & HDSP_wc_lock)
snd_iprintf (buffer, "Word Clock: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf (buffer, "Word Clock: No Lock\n");
- }
x = status & HDSP_TimecodeSync;
- if (status & HDSP_TimecodeLock) {
+ if (status & HDSP_TimecodeLock)
snd_iprintf(buffer, "ADAT Sync: %s\n", x ? "Sync" : "Lock");
- } else {
+ else
snd_iprintf(buffer, "ADAT Sync: No Lock\n");
- }
snd_iprintf(buffer, "\n");
@@ -3527,11 +3460,10 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no");
- if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
+ if (hdsp->control_register & HDSP_AnalogExtensionBoard)
snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n");
- } else {
+ else
snd_iprintf(buffer, "AEB : off (ADAT1 external)\n");
- }
snd_iprintf(buffer, "\n");
}
@@ -3610,25 +3542,22 @@ static int snd_hdsp_set_defaults(hdsp_t *hdsp)
#else
hdsp->control2_register = 0;
#endif
- if (hdsp->io_type == H9652) {
+ if (hdsp->io_type == H9652)
snd_hdsp_9652_enable_mixer (hdsp);
- } else {
- hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
- }
+ else
+ hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
hdsp_reset_hw_pointer(hdsp);
hdsp_compute_period_size(hdsp);
/* silence everything */
- for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i) {
+ for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i)
hdsp->mixer_matrix[i] = MINUS_INFINITY_GAIN;
- }
for (i = 0; i < ((hdsp->io_type == H9652 || hdsp->io_type == H9632) ? 1352 : HDSP_MATRIX_MIXER_SIZE); ++i) {
- if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN)) {
+ if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN))
return -EIO;
- }
}
/* H9632 specific defaults */
@@ -3649,12 +3578,10 @@ static void hdsp_midi_tasklet(unsigned long arg)
{
hdsp_t *hdsp = (hdsp_t *)arg;
- if (hdsp->midi[0].pending) {
+ if (hdsp->midi[0].pending)
snd_hdsp_midi_input_read (&hdsp->midi[0]);
- }
- if (hdsp->midi[1].pending) {
+ if (hdsp->midi[1].pending)
snd_hdsp_midi_input_read (&hdsp->midi[1]);
- }
}
static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -3674,9 +3601,8 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *reg
midi0 = status & HDSP_midi0IRQPending;
midi1 = status & HDSP_midi1IRQPending;
- if (!audio && !midi0 && !midi1) {
+ if (!audio && !midi0 && !midi1)
return IRQ_NONE;
- }
hdsp_write(hdsp, HDSP_interruptConfirmation, 0);
@@ -3684,13 +3610,11 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *reg
midi1status = hdsp_read (hdsp, HDSP_midiStatusIn1) & 0xff;
if (audio) {
- if (hdsp->capture_substream) {
+ if (hdsp->capture_substream)
snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
- }
- if (hdsp->playback_substream) {
+ if (hdsp->playback_substream)
snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
- }
}
if (midi0 && midi0status) {
@@ -3735,15 +3659,13 @@ static char *hdsp_channel_buffer_location(hdsp_t *hdsp,
snd_assert(channel >= 0 && channel < hdsp->max_channels, return NULL);
- if ((mapped_channel = hdsp->channel_map[channel]) < 0) {
+ if ((mapped_channel = hdsp->channel_map[channel]) < 0)
return NULL;
- }
- if (stream == SNDRV_PCM_STREAM_CAPTURE) {
+ if (stream == SNDRV_PCM_STREAM_CAPTURE)
return hdsp->capture_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
- } else {
+ else
return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
- }
}
static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
@@ -3824,20 +3746,11 @@ static int snd_hdsp_hw_params(snd_pcm_substream_t *substream,
pid_t this_pid;
pid_t other_pid;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock_irq(&hdsp->lock);
@@ -3908,9 +3821,8 @@ static int snd_hdsp_channel_info(snd_pcm_substream_t *substream,
snd_assert(info->channel < hdsp->max_channels, return -EINVAL);
- if ((mapped_channel = hdsp->channel_map[info->channel]) < 0) {
+ if ((mapped_channel = hdsp->channel_map[info->channel]) < 0)
return -EINVAL;
- }
info->offset = mapped_channel * HDSP_CHANNEL_BUFFER_BYTES;
info->first = 0;
@@ -3923,14 +3835,9 @@ static int snd_hdsp_ioctl(snd_pcm_substream_t *substream,
{
switch (cmd) {
case SNDRV_PCM_IOCTL1_RESET:
- {
return snd_hdsp_reset(substream);
- }
case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
- {
- snd_pcm_channel_info_t *info = arg;
- return snd_hdsp_channel_info(substream, info);
- }
+ return snd_hdsp_channel_info(substream, arg);
default:
break;
}
@@ -3944,20 +3851,11 @@ static int snd_hdsp_trigger(snd_pcm_substream_t *substream, int cmd)
snd_pcm_substream_t *other;
int running;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock(&hdsp->lock);
running = hdsp->running;
@@ -4022,20 +3920,11 @@ static int snd_hdsp_prepare(snd_pcm_substream_t *substream)
hdsp_t *hdsp = snd_pcm_substream_chip(substream);
int result = 0;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock_irq(&hdsp->lock);
if (!hdsp->running)
@@ -4285,20 +4174,11 @@ static int snd_hdsp_playback_open(snd_pcm_substream_t *substream)
hdsp_t *hdsp = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock_irq(&hdsp->lock);
@@ -4367,20 +4247,11 @@ static int snd_hdsp_capture_open(snd_pcm_substream_t *substream)
hdsp_t *hdsp = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (hdsp_check_for_firmware(hdsp)) {
- if (hdsp->state & HDSP_FirmwareCached) {
- if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
- snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
- }
- } else {
- snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
- }
+ if (hdsp_check_for_firmware(hdsp, 1))
return -EIO;
- }
spin_lock_irq(&hdsp->lock);
@@ -4589,19 +4460,17 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
int i;
if (!(hdsp->state & HDSP_FirmwareLoaded)) {
- snd_printk("Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");
return -EINVAL;
}
spin_lock_irqsave(&hdsp->lock, flags);
info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
- if (hdsp->io_type != H9632) {
+ if (hdsp->io_type != H9632)
info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
- }
info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
- for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) {
+ for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i)
info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
- }
info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp);
@@ -4621,9 +4490,8 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
}
- if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
+ if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
- }
spin_unlock_irqrestore(&hdsp->lock, flags);
if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
@@ -4645,15 +4513,13 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
if (hdsp->io_type == Undefined) {
- if ((err = hdsp_get_iobox_version(hdsp)) < 0) {
+ if ((err = hdsp_get_iobox_version(hdsp)) < 0)
return err;
- }
}
hdsp_version.io_type = hdsp->io_type;
hdsp_version.firmware_rev = hdsp->firmware_rev;
- if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version)))) {
+ if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version))))
return -EFAULT;
- }
break;
}
case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
@@ -4668,38 +4534,33 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int
if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded))
return -EBUSY;
- snd_printk("Hammerfall-DSP: initializing firmware upload\n");
+ snd_printk(KERN_INFO "Hammerfall-DSP: initializing firmware upload\n");
firmware = (hdsp_firmware_t __user *)argp;
- if (get_user(firmware_data, &firmware->firmware_data)) {
+ if (get_user(firmware_data, &firmware->firmware_data))
return -EFAULT;
- }
- if (hdsp_check_for_iobox (hdsp)) {
+ if (hdsp_check_for_iobox (hdsp))
return -EIO;
- }
- if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0) {
+ if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0)
return -EFAULT;
- }
hdsp->state |= HDSP_FirmwareCached;
- if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0) {
+ if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
return err;
- }
if (!(hdsp->state & HDSP_InitializationComplete)) {
- if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
+ if ((err = snd_hdsp_enable_io(hdsp)) < 0)
return err;
- }
snd_hdsp_initialize_channels(hdsp);
snd_hdsp_initialize_midi_flush(hdsp);
if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: error creating alsa devices\n");
- return err;
+ snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
+ return err;
}
}
break;
@@ -4790,7 +4651,7 @@ static int snd_hdsp_enable_io (hdsp_t *hdsp)
int i;
if (hdsp_fifo_wait (hdsp, 0, 100)) {
- snd_printk("Hammerfall-DSP: enable_io fifo_wait failed\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: enable_io fifo_wait failed\n");
return -EIO;
}
@@ -4856,25 +4717,25 @@ static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
int err;
if ((err = snd_hdsp_create_pcm(card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: Error creating pcm interface\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error creating pcm interface\n");
return err;
}
if ((err = snd_hdsp_create_midi(card, hdsp, 0)) < 0) {
- snd_printk("Hammerfall-DSP: Error creating first midi interface\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error creating first midi interface\n");
return err;
}
if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
if ((err = snd_hdsp_create_midi(card, hdsp, 1)) < 0) {
- snd_printk("Hammerfall-DSP: Error creating second midi interface\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error creating second midi interface\n");
return err;
}
}
if ((err = snd_hdsp_create_controls(card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: Error creating ctl interface\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error creating ctl interface\n");
return err;
}
@@ -4887,7 +4748,7 @@ static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
hdsp->playback_substream = NULL;
if ((err = snd_hdsp_set_defaults(hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: Error setting default values\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: Error setting default values\n");
return err;
}
@@ -4897,7 +4758,7 @@ static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
hdsp->port, hdsp->irq);
if ((err = snd_card_register(card)) < 0) {
- snd_printk("Hammerfall-DSP: error registering card\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: error registering card\n");
return err;
}
hdsp->state |= HDSP_InitializationComplete;
@@ -4963,18 +4824,17 @@ static int __devinit hdsp_request_fw_loader(hdsp_t *hdsp)
return err;
if (!(hdsp->state & HDSP_InitializationComplete)) {
- if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
+ if ((err = snd_hdsp_enable_io(hdsp)) < 0)
return err;
- }
if ((err = snd_hdsp_create_hwdep(hdsp->card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: error creating hwdep device\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: error creating hwdep device\n");
return err;
}
snd_hdsp_initialize_channels(hdsp);
snd_hdsp_initialize_midi_flush(hdsp);
if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
- snd_printk("Hammerfall-DSP: error creating alsa devices\n");
+ snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
return err;
}
}
@@ -5029,11 +4889,11 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
strcpy(card->driver, "H-DSP");
strcpy(card->mixername, "Xilinx FPGA");
- if (hdsp->firmware_rev < 0xa) {
+ if (hdsp->firmware_rev < 0xa)
return -ENODEV;
- } else if (hdsp->firmware_rev < 0x64) {
+ else if (hdsp->firmware_rev < 0x64)
hdsp->card_name = "RME Hammerfall DSP";
- } else if (hdsp->firmware_rev < 0x96) {
+ else if (hdsp->firmware_rev < 0x96) {
hdsp->card_name = "RME HDSP 9652";
is_9652 = 1;
} else {
@@ -5042,9 +4902,8 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
is_9632 = 1;
}
- if ((err = pci_enable_device(pci)) < 0) {
+ if ((err = pci_enable_device(pci)) < 0)
return err;
- }
pci_set_master(hdsp->pci);
@@ -5052,12 +4911,12 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
return err;
hdsp->port = pci_resource_start(pci, 0);
if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) {
- snd_printk("Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
+ snd_printk(KERN_ERR "Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
return -EBUSY;
}
if (request_irq(pci->irq, snd_hdsp_interrupt, SA_INTERRUPT|SA_SHIRQ, "hdsp", (void *)hdsp)) {
- snd_printk("Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
return -EBUSY;
}
@@ -5065,71 +4924,58 @@ static int __devinit snd_hdsp_create(snd_card_t *card,
hdsp->precise_ptr = 1;
hdsp->use_midi_tasklet = 1;
- if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) {
+ if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
return err;
- }
if (!is_9652 && !is_9632) {
/* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
- if ((1000 / HZ) < 2000) {
- ssleep(2);
- } else {
- mdelay(2000);
- }
+ ssleep(2);
if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
#ifdef HDSP_FW_LOADER
- if ((err = hdsp_request_fw_loader(hdsp)) < 0) {
+ if ((err = hdsp_request_fw_loader(hdsp)) < 0)
/* we don't fail as this can happen
if userspace is not ready for
firmware upload
*/
- snd_printk("Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
- } else {
+ snd_printk(KERN_ERR "Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
+ else
/* init is complete, we return */
return 0;
- }
#endif
/* no iobox connected, we defer initialization */
- snd_printk("Hammerfall-DSP: card initialization pending : waiting for firmware\n");
- if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
+ snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
+ if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
return err;
- }
return 0;
} else {
- snd_printk("Hammerfall-DSP: Firmware already present, initializing card.\n");
- if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
+ snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");
+ if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
hdsp->io_type = Multiface;
- } else {
+ else
hdsp->io_type = Digiface;
- }
}
}
- if ((err = snd_hdsp_enable_io(hdsp)) != 0) {
+ if ((err = snd_hdsp_enable_io(hdsp)) != 0)
return err;
- }
- if (is_9652) {
+ if (is_9652)
hdsp->io_type = H9652;
- }
- if (is_9632) {
+ if (is_9632)
hdsp->io_type = H9632;
- }
- if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
+ if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
return err;
- }
snd_hdsp_initialize_channels(hdsp);
snd_hdsp_initialize_midi_flush(hdsp);
hdsp->state |= HDSP_FirmwareLoaded;
- if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0) {
+ if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0)
return err;
- }
return 0;
}
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index fc3f3283ff37..60a1141f1327 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -3563,8 +3563,7 @@ static int snd_hdspm_free(hdspm_t * hdspm)
free_irq(hdspm->irq, (void *) hdspm);
- if (hdspm->mixer)
- kfree(hdspm->mixer);
+ kfree(hdspm->mixer);
if (hdspm->iobase)
iounmap(hdspm->iobase);
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index b600f45e1834..59fcef9b6b81 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -779,7 +779,7 @@ static inline int rme9652_spdif_sample_rate(rme9652_t *s)
break;
default:
- snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
+ snd_printk(KERN_ERR "%s: unknown S/PDIF input rate (bits = 0x%x)\n",
s->card_name, rate_bits);
return 0;
break;
@@ -2496,12 +2496,12 @@ static int __devinit snd_rme9652_create(snd_card_t *card,
rme9652->port = pci_resource_start(pci, 0);
rme9652->iobase = ioremap_nocache(rme9652->port, RME9652_IO_EXTENT);
if (rme9652->iobase == NULL) {
- snd_printk("unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
+ snd_printk(KERN_ERR "unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
return -EBUSY;
}
if (request_irq(pci->irq, snd_rme9652_interrupt, SA_INTERRUPT|SA_SHIRQ, "rme9652", (void *)rme9652)) {
- snd_printk("unable to request IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
return -EBUSY;
}
rme9652->irq = pci->irq;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 1f6c2bfd43fd..9a35474aad05 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -591,7 +591,7 @@ static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id, struct pt_reg
return IRQ_NONE;
if (status == 0xff) { /* failure */
outb(sonic->irqmask = ~0, SV_REG(sonic, IRQMASK));
- snd_printk("IRQ failure - interrupts disabled!!\n");
+ snd_printk(KERN_ERR "IRQ failure - interrupts disabled!!\n");
return IRQ_HANDLED;
}
if (sonic->pcm) {
@@ -1205,14 +1205,8 @@ static int snd_sonicvibes_free(sonicvibes_t *sonic)
pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
if (sonic->irq >= 0)
free_irq(sonic->irq, (void *)sonic);
- if (sonic->res_dmaa) {
- release_resource(sonic->res_dmaa);
- kfree_nocheck(sonic->res_dmaa);
- }
- if (sonic->res_dmac) {
- release_resource(sonic->res_dmac);
- kfree_nocheck(sonic->res_dmac);
- }
+ release_and_free_resource(sonic->res_dmaa);
+ release_and_free_resource(sonic->res_dmac);
pci_release_regions(sonic->pci);
pci_disable_device(sonic->pci);
kfree(sonic);
@@ -1245,7 +1239,7 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
- snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -1273,7 +1267,7 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
sonic->game_port = pci_resource_start(pci, 4);
if (request_irq(pci->irq, snd_sonicvibes_interrupt, SA_INTERRUPT|SA_SHIRQ, "S3 SonicVibes", (void *)sonic)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_sonicvibes_free(sonic);
return -EBUSY;
}
@@ -1287,24 +1281,24 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card,
if (!dmaa) {
dmaa = dmaio;
dmaio += 0x10;
- snd_printk("BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
+ snd_printk(KERN_INFO "BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
}
if (!dmac) {
dmac = dmaio;
dmaio += 0x10;
- snd_printk("BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
+ snd_printk(KERN_INFO "BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
}
pci_write_config_dword(pci, 0x40, dmaa);
pci_write_config_dword(pci, 0x48, dmac);
if ((sonic->res_dmaa = request_region(dmaa, 0x10, "S3 SonicVibes DDMA-A")) == NULL) {
snd_sonicvibes_free(sonic);
- snd_printk("unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
+ snd_printk(KERN_ERR "unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
return -EBUSY;
}
if ((sonic->res_dmac = request_region(dmac, 0x10, "S3 SonicVibes DDMA-C")) == NULL) {
snd_sonicvibes_free(sonic);
- snd_printk("unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
+ snd_printk(KERN_ERR "unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
return -EBUSY;
}
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 777da9a7298b..b9b93c7faafd 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -153,7 +153,7 @@ static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
}
if (count == 0 && !trident->ac97_detect) {
- snd_printk("ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
+ snd_printk(KERN_ERR "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
data = 0;
}
@@ -2893,7 +2893,8 @@ static void snd_trident_notify_pcm_change1(snd_card_t * card, snd_kcontrol_t *kc
{
snd_ctl_elem_id_t id;
- snd_runtime_check(kctl != NULL, return);
+ if (! kctl)
+ return;
if (activate)
kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
else
@@ -2989,13 +2990,13 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device
_ac97.num = 1;
err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
if (err < 0)
- snd_printk("SI7018: the secondary codec - invalid access\n");
+ snd_printk(KERN_ERR "SI7018: the secondary codec - invalid access\n");
#if 0 // only for my testing purpose --jk
{
ac97_t *mc97;
err = snd_ac97_modem(trident->card, &_ac97, &mc97);
if (err < 0)
- snd_printk("snd_ac97_modem returned error %i\n", err);
+ snd_printk(KERN_ERR "snd_ac97_modem returned error %i\n", err);
}
#endif
}
@@ -3206,8 +3207,7 @@ static inline void snd_trident_free_gameport(trident_t *chip) { }
*/
static inline void do_delay(trident_t *chip)
{
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
/*
@@ -3243,7 +3243,7 @@ static int snd_trident_sis_reset(trident_t *trident)
goto __si7018_ok;
do_delay(trident);
} while (time_after_eq(end_time, jiffies));
- snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
+ snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
if (r-- > 0) {
end_time = jiffies + HZ;
do {
@@ -3541,7 +3541,7 @@ int __devinit snd_trident_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 30 bits */
if (pci_set_dma_mask(pci, 0x3fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x3fffffff) < 0) {
- snd_printk("architecture does not support 30bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
@@ -3578,7 +3578,7 @@ int __devinit snd_trident_create(snd_card_t * card,
trident->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_trident_free(trident);
return -EBUSY;
}
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index 333d3790692a..f3e6c546af74 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -170,11 +170,11 @@ __found_pages:
static int is_valid_page(unsigned long ptr)
{
if (ptr & ~0x3fffffffUL) {
- snd_printk("max memory size is 1GB!!\n");
+ snd_printk(KERN_ERR "max memory size is 1GB!!\n");
return 0;
}
if (ptr & (SNDRV_TRIDENT_PAGE_SIZE-1)) {
- snd_printk("page is not aligned\n");
+ snd_printk(KERN_ERR "page is not aligned\n");
return 0;
}
return 1;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 3c0205b91e10..523eace250f7 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -41,6 +41,9 @@
* device for applications.
* - clean up the code, separate low-level initialization
* routines for each chipset.
+ *
+ * Sep. 26, 2005 Karsten Wiese <annabellesgarden@yahoo.de>
+ * - Optimize position calculation for the 823x chips.
*/
#include <sound/driver.h>
@@ -73,36 +76,37 @@ MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}");
#define SUPPORT_JOYSTICK 1
#endif
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static long mpu_port[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static long mpu_port;
#ifdef SUPPORT_JOYSTICK
-static int joystick[SNDRV_CARDS];
+static int joystick;
#endif
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
-static char *ac97_quirk[SNDRV_CARDS];
-static int dxs_support[SNDRV_CARDS];
+static int ac97_clock = 48000;
+static char *ac97_quirk;
+static int dxs_support;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of VIA 82xx bridge.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param(mpu_port, long, 0444);
MODULE_PARM_DESC(mpu_port, "MPU-401 port. (VT82C686x only)");
#ifdef SUPPORT_JOYSTICK
-module_param_array(joystick, bool, NULL, 0444);
+module_param(joystick, bool, 0444);
MODULE_PARM_DESC(joystick, "Enable joystick. (VT82C686x only)");
#endif
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(dxs_support, int, NULL, 0444);
+module_param(dxs_support, int, 0444);
MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/* revision numbers for via686 */
#define VIA_REV_686_A 0x10
@@ -130,6 +134,7 @@ MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2
/* common offsets */
#define VIA_REG_OFFSET_STATUS 0x00 /* byte - channel status */
#define VIA_REG_STAT_ACTIVE 0x80 /* RO */
+#define VIA8233_SHADOW_STAT_ACTIVE 0x08 /* RO */
#define VIA_REG_STAT_PAUSED 0x40 /* RO */
#define VIA_REG_STAT_TRIGGER_QUEUED 0x08 /* RO */
#define VIA_REG_STAT_STOPPED 0x04 /* RWC */
@@ -328,6 +333,9 @@ struct via_dev {
unsigned int fragsize;
unsigned int bufsize;
unsigned int bufsize2;
+ int hwptr_done; /* processed frame position in the buffer */
+ int in_interrupt;
+ int shadow_shift;
};
@@ -360,7 +368,8 @@ struct _snd_via82xx {
unsigned int mpu_port_saved;
#endif
- unsigned char playback_volume[2]; /* for VIA8233/C/8235; default = 0 */
+ unsigned char playback_volume[4][2]; /* for VIA8233/C/8235; default = 0 */
+ unsigned char playback_volume_c[2]; /* for VIA8233/C/8235; default = 0 */
unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
@@ -393,8 +402,10 @@ struct _snd_via82xx {
};
static struct pci_device_id snd_via82xx_ids[] = {
- { 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */
- { 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, }, /* VT8233 */
+ /* 0x1106, 0x3058 */
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */
+ /* 0x1106, 0x3059 */
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, }, /* VT8233 */
{ 0, }
};
@@ -548,7 +559,7 @@ static void snd_via82xx_codec_write(ac97_t *ac97,
{
via82xx_t *chip = ac97->private_data;
unsigned int xval;
-
+
xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
xval |= reg << VIA_REG_AC97_CMD_SHIFT;
@@ -596,14 +607,15 @@ static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
// outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
viadev->lastpos = 0;
+ viadev->hwptr_done = 0;
}
/*
* Interrupt handler
+ * Used for 686 and 8233A
*/
-
-static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
via82xx_t *chip = dev_id;
unsigned int status;
@@ -622,13 +634,23 @@ static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *
for (i = 0; i < chip->num_devs; i++) {
viadev_t *viadev = &chip->devs[i];
unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
- c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
- if (! c_status)
+ if (! (c_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED)))
continue;
if (viadev->substream && viadev->running) {
+ /*
+ * Update hwptr_done based on 'period elapsed'
+ * interrupts. We'll use it, when the chip returns 0
+ * for OFFSET_CURR_COUNT.
+ */
+ if (c_status & VIA_REG_STAT_EOL)
+ viadev->hwptr_done = 0;
+ else
+ viadev->hwptr_done += viadev->fragsize;
+ viadev->in_interrupt = c_status;
spin_unlock(&chip->reg_lock);
snd_pcm_period_elapsed(viadev->substream);
spin_lock(&chip->reg_lock);
+ viadev->in_interrupt = 0;
}
outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
}
@@ -637,6 +659,60 @@ static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *
}
/*
+ * Interrupt handler
+ */
+static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ via82xx_t *chip = dev_id;
+ unsigned int status;
+ unsigned int i;
+ int irqreturn = 0;
+
+ /* check status for each stream */
+ spin_lock(&chip->reg_lock);
+ status = inl(VIAREG(chip, SGD_SHADOW));
+
+ for (i = 0; i < chip->num_devs; i++) {
+ viadev_t *viadev = &chip->devs[i];
+ snd_pcm_substream_t *substream;
+ unsigned char c_status, shadow_status;
+
+ shadow_status = (status >> viadev->shadow_shift) &
+ (VIA8233_SHADOW_STAT_ACTIVE|VIA_REG_STAT_EOL|
+ VIA_REG_STAT_FLAG);
+ c_status = shadow_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG);
+ if (!c_status)
+ continue;
+
+ substream = viadev->substream;
+ if (substream && viadev->running) {
+ /*
+ * Update hwptr_done based on 'period elapsed'
+ * interrupts. We'll use it, when the chip returns 0
+ * for OFFSET_CURR_COUNT.
+ */
+ if (c_status & VIA_REG_STAT_EOL)
+ viadev->hwptr_done = 0;
+ else
+ viadev->hwptr_done += viadev->fragsize;
+ viadev->in_interrupt = c_status;
+ if (shadow_status & VIA8233_SHADOW_STAT_ACTIVE)
+ viadev->in_interrupt |= VIA_REG_STAT_ACTIVE;
+ spin_unlock(&chip->reg_lock);
+
+ snd_pcm_period_elapsed(substream);
+
+ spin_lock(&chip->reg_lock);
+ viadev->in_interrupt = 0;
+ }
+ outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
+ irqreturn = 1;
+ }
+ spin_unlock(&chip->reg_lock);
+ return IRQ_RETVAL(irqreturn);
+}
+
+/*
* PCM callbacks
*/
@@ -699,6 +775,8 @@ static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, u
size = viadev->idx_table[idx].size;
base = viadev->idx_table[idx].offset;
res = base + size - count;
+ if (res >= viadev->bufsize)
+ res -= viadev->bufsize;
/* check the validity of the calculated position */
if (size < count) {
@@ -728,9 +806,6 @@ static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, u
}
}
}
- viadev->lastpos = res; /* remember the last position */
- if (res >= viadev->bufsize)
- res -= viadev->bufsize;
return res;
}
@@ -758,6 +833,7 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
else /* CURR_PTR holds the address + 8 */
idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
res = calc_linear_pos(viadev, idx, count);
+ viadev->lastpos = res; /* remember the last position */
spin_unlock(&chip->reg_lock);
return bytes_to_frames(substream->runtime, res);
@@ -771,30 +847,44 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(snd_pcm_substream_t *substream)
via82xx_t *chip = snd_pcm_substream_chip(substream);
viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
unsigned int idx, count, res;
- int timeout = 5000;
+ int status;
snd_assert(viadev->tbl_entries, return 0);
- if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
- return 0;
+
spin_lock(&chip->reg_lock);
- do {
- count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
- /* some mobos read 0 count */
- if ((count & 0xffffff) || ! viadev->running)
- break;
- } while (--timeout);
- if (! timeout)
- snd_printd(KERN_ERR "zero position is read\n");
- idx = count >> 24;
- if (idx >= viadev->tbl_entries) {
+ count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
+ status = viadev->in_interrupt;
+ if (!status)
+ status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
+
+ if (!(status & VIA_REG_STAT_ACTIVE)) {
+ res = 0;
+ goto unlock;
+ }
+ if (count & 0xffffff) {
+ idx = count >> 24;
+ if (idx >= viadev->tbl_entries) {
#ifdef POINTER_DEBUG
- printk("fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
+ printk(KERN_DEBUG "fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
#endif
- res = viadev->lastpos;
+ res = viadev->lastpos;
+ } else {
+ count &= 0xffffff;
+ res = calc_linear_pos(viadev, idx, count);
+ }
} else {
- count &= 0xffffff;
- res = calc_linear_pos(viadev, idx, count);
- }
+ res = viadev->hwptr_done;
+ if (!viadev->in_interrupt) {
+ if (status & VIA_REG_STAT_EOL) {
+ res = 0;
+ } else
+ if (status & VIA_REG_STAT_FLAG) {
+ res += viadev->fragsize;
+ }
+ }
+ }
+unlock:
+ viadev->lastpos = res;
spin_unlock(&chip->reg_lock);
return bytes_to_frames(substream->runtime, res);
@@ -936,8 +1026,8 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream)
snd_assert((rbits & ~0xfffff) == 0, return -EINVAL);
snd_via82xx_channel_reset(chip, viadev);
snd_via82xx_set_table_ptr(chip, viadev);
- outb(chip->playback_volume[0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
- outb(chip->playback_volume[1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
+ outb(chip->playback_volume[viadev->reg_offset / 0x10][0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
+ outb(chip->playback_volume[viadev->reg_offset / 0x10][1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */
(runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */
rbits | /* rate */
@@ -1239,9 +1329,10 @@ static snd_pcm_ops_t snd_via8233_capture_ops = {
};
-static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
+static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int shadow_pos, int direction)
{
chip->devs[idx].reg_offset = reg_offset;
+ chip->devs[idx].shadow_shift = shadow_pos * 4;
chip->devs[idx].direction = direction;
chip->devs[idx].port = chip->port + reg_offset;
}
@@ -1271,9 +1362,9 @@ static int __devinit snd_via8233_pcm_new(via82xx_t *chip)
chip->pcms[0] = pcm;
/* set up playbacks */
for (i = 0; i < 4; i++)
- init_viadev(chip, i, 0x10 * i, 0);
+ init_viadev(chip, i, 0x10 * i, i, 0);
/* capture */
- init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
+ init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1289,9 +1380,9 @@ static int __devinit snd_via8233_pcm_new(via82xx_t *chip)
strcpy(pcm->name, chip->card->shortname);
chip->pcms[1] = pcm;
/* set up playback */
- init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+ init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
/* set up capture */
- init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 1);
+ init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1324,9 +1415,9 @@ static int __devinit snd_via8233a_pcm_new(via82xx_t *chip)
strcpy(pcm->name, chip->card->shortname);
chip->pcms[0] = pcm;
/* set up playback */
- init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+ init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
/* capture */
- init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
+ init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1345,7 +1436,7 @@ static int __devinit snd_via8233a_pcm_new(via82xx_t *chip)
strcpy(pcm->name, chip->card->shortname);
chip->pcms[1] = pcm;
/* set up playback */
- init_viadev(chip, chip->playback_devno, 0x30, 0);
+ init_viadev(chip, chip->playback_devno, 0x30, 3, 0);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1375,8 +1466,8 @@ static int __devinit snd_via686_pcm_new(via82xx_t *chip)
pcm->private_data = chip;
strcpy(pcm->name, chip->card->shortname);
chip->pcms[0] = pcm;
- init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0);
- init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 1);
+ init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0);
+ init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1497,14 +1588,46 @@ static int snd_via8233_dxs_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_in
static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
via82xx_t *chip = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[0];
- ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[1];
+ unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+
+ ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
+ ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1];
+ return 0;
+}
+
+static int snd_via8233_pcmdxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+ ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[0];
+ ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[1];
return 0;
}
static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+ unsigned long port = chip->port + 0x10 * idx;
+ unsigned char val;
+ int i, change = 0;
+
+ for (i = 0; i < 2; i++) {
+ val = ucontrol->value.integer.value[i];
+ if (val > VIA_DXS_MAX_VOLUME)
+ val = VIA_DXS_MAX_VOLUME;
+ val = VIA_DXS_MAX_VOLUME - val;
+ change |= val != chip->playback_volume[idx][i];
+ if (change) {
+ chip->playback_volume[idx][i] = val;
+ outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+ }
+ }
+ return change;
+}
+
+static int snd_via8233_pcmdxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ via82xx_t *chip = snd_kcontrol_chip(kcontrol);
unsigned int idx;
unsigned char val;
int i, change = 0;
@@ -1514,11 +1637,12 @@ static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
if (val > VIA_DXS_MAX_VOLUME)
val = VIA_DXS_MAX_VOLUME;
val = VIA_DXS_MAX_VOLUME - val;
- if (val != chip->playback_volume[i]) {
+ if (val != chip->playback_volume_c[i]) {
change = 1;
- chip->playback_volume[i] = val;
+ chip->playback_volume_c[i] = val;
for (idx = 0; idx < 4; idx++) {
unsigned long port = chip->port + 0x10 * idx;
+ chip->playback_volume[idx][i] = val;
outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
}
}
@@ -1526,10 +1650,19 @@ static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
return change;
}
-static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+static snd_kcontrol_new_t snd_via8233_pcmdxs_volume_control __devinitdata = {
.name = "PCM Playback Volume",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.info = snd_via8233_dxs_volume_info,
+ .get = snd_via8233_pcmdxs_volume_get,
+ .put = snd_via8233_pcmdxs_volume_put,
+};
+
+static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+ .name = "VIA DXS Playback Volume",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .count = 4,
+ .info = snd_via8233_dxs_volume_info,
.get = snd_via8233_dxs_volume_get,
.put = snd_via8233_dxs_volume_put,
};
@@ -1616,12 +1749,12 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip, const char *quirk_ov
return err;
chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
chip->ac97_bus->clock = chip->ac97_clock;
- chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
ac97.private_free = snd_via82xx_mixer_free_ac97;
ac97.pci = chip->pci;
+ ac97.scaps = AC97_SCAP_SKIP_MODEM;
if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
return err;
@@ -1637,12 +1770,12 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip, const char *quirk_ov
#ifdef SUPPORT_JOYSTICK
#define JOYSTICK_ADDR 0x200
-static int __devinit snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+static int __devinit snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
{
struct gameport *gp;
struct resource *r;
- if (!joystick[dev])
+ if (!joystick)
return -ENODEV;
r = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport");
@@ -1654,8 +1787,7 @@ static int __devinit snd_via686_create_gameport(via82xx_t *chip, int dev, unsign
chip->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "via82xx: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -1681,12 +1813,11 @@ static void snd_via686_free_gameport(via82xx_t *chip)
gameport_unregister_port(chip->gameport);
chip->gameport = NULL;
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
-static inline int snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+static inline int snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
{
return -ENOSYS;
}
@@ -1698,7 +1829,7 @@ static inline void snd_via686_free_gameport(via82xx_t *chip) { }
*
*/
-static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via8233_init_misc(via82xx_t *chip)
{
int i, err, caps;
unsigned char val;
@@ -1724,12 +1855,19 @@ static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
strcpy(sid.name, "PCM Playback Volume");
sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
if (! snd_ctl_find_id(chip->card, &sid)) {
+ snd_printd(KERN_INFO "Using DXS as PCM Playback\n");
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_pcmdxs_volume_control, chip));
+ if (err < 0)
+ return err;
+ }
+ else /* Using DXS when PCM emulation is enabled is really weird */
+ {
+ /* Standalone DXS controls */
err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
if (err < 0)
return err;
}
}
-
/* select spdif data slot 10/11 */
pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011;
@@ -1739,7 +1877,7 @@ static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
return 0;
}
-static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via686_init_misc(via82xx_t *chip)
{
unsigned char legacy, legacy_cfg;
int rev_h = 0;
@@ -1750,32 +1888,33 @@ static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
legacy &= ~VIA_FUNC_ENABLE_GAME; /* disable joystick */
if (chip->revision >= VIA_REV_686_H) {
rev_h = 1;
- if (mpu_port[dev] >= 0x200) { /* force MIDI */
- mpu_port[dev] &= 0xfffc;
- pci_write_config_dword(chip->pci, 0x18, mpu_port[dev] | 0x01);
+ if (mpu_port >= 0x200) { /* force MIDI */
+ mpu_port &= 0xfffc;
+ pci_write_config_dword(chip->pci, 0x18, mpu_port | 0x01);
#ifdef CONFIG_PM
- chip->mpu_port_saved = mpu_port[dev];
+ chip->mpu_port_saved = mpu_port;
#endif
} else {
- mpu_port[dev] = pci_resource_start(chip->pci, 2);
+ mpu_port = pci_resource_start(chip->pci, 2);
}
} else {
- switch (mpu_port[dev]) { /* force MIDI */
+ switch (mpu_port) { /* force MIDI */
case 0x300:
case 0x310:
case 0x320:
case 0x330:
legacy_cfg &= ~(3 << 2);
- legacy_cfg |= (mpu_port[dev] & 0x0030) >> 2;
+ legacy_cfg |= (mpu_port & 0x0030) >> 2;
break;
default: /* no, use BIOS settings */
if (legacy & VIA_FUNC_ENABLE_MIDI)
- mpu_port[dev] = 0x300 + ((legacy_cfg & 0x000c) << 2);
+ mpu_port = 0x300 + ((legacy_cfg & 0x000c) << 2);
break;
}
}
- if (mpu_port[dev] >= 0x200 &&
- (chip->mpu_res = request_region(mpu_port[dev], 2, "VIA82xx MPU401")) != NULL) {
+ if (mpu_port >= 0x200 &&
+ (chip->mpu_res = request_region(mpu_port, 2, "VIA82xx MPU401"))
+ != NULL) {
if (rev_h)
legacy |= VIA_FUNC_MIDI_PNP; /* enable PCI I/O 2 */
legacy |= VIA_FUNC_ENABLE_MIDI;
@@ -1783,16 +1922,17 @@ static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
if (rev_h)
legacy &= ~VIA_FUNC_MIDI_PNP; /* disable PCI I/O 2 */
legacy &= ~VIA_FUNC_ENABLE_MIDI;
- mpu_port[dev] = 0;
+ mpu_port = 0;
}
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
if (chip->mpu_res) {
if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
- mpu_port[dev], 1,
+ mpu_port, 1,
chip->irq, 0, &chip->rmidi) < 0) {
- printk(KERN_WARNING "unable to initialize MPU-401 at 0x%lx, skipping\n", mpu_port[dev]);
+ printk(KERN_WARNING "unable to initialize MPU-401"
+ " at 0x%lx, skipping\n", mpu_port);
legacy &= ~VIA_FUNC_ENABLE_MIDI;
} else {
legacy &= ~VIA_FUNC_MIDI_IRQMASK; /* enable MIDI interrupt */
@@ -1800,7 +1940,7 @@ static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
}
- snd_via686_create_gameport(chip, dev, &legacy);
+ snd_via686_create_gameport(chip, &legacy);
#ifdef CONFIG_PM
chip->legacy_saved = legacy;
@@ -1887,12 +2027,11 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
- snd_printk("AC'97 codec is not ready [0x%x]\n", val);
+ snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
#if 0 /* FIXME: we don't support the second codec yet so skip the detection now.. */
snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
@@ -1907,8 +2046,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
chip->ac97_secondary = 1;
goto __ac97_ok2;
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
} while (time_before(jiffies, end_time));
/* This is ok, the most of motherboards have only one codec */
@@ -1940,8 +2078,10 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
int i, idx;
for (idx = 0; idx < 4; idx++) {
unsigned long port = chip->port + 0x10 * idx;
- for (i = 0; i < 2; i++)
- outb(chip->playback_volume[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+ for (i = 0; i < 2; i++) {
+ chip->playback_volume[idx][i]=chip->playback_volume_c[i];
+ outb(chip->playback_volume_c[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+ }
}
}
@@ -2020,10 +2160,7 @@ static int snd_via82xx_free(via82xx_t *chip)
__end_hw:
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
- if (chip->mpu_res) {
- release_resource(chip->mpu_res);
- kfree_nocheck(chip->mpu_res);
- }
+ release_and_free_resource(chip->mpu_res);
pci_release_regions(chip->pci);
if (chip->chip_type == TYPE_VIA686) {
@@ -2084,9 +2221,12 @@ static int __devinit snd_via82xx_create(snd_card_t * card,
return err;
}
chip->port = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
+ if (request_irq(pci->irq,
+ chip_type == TYPE_VIA8233 ?
+ snd_via8233_interrupt : snd_via686_interrupt,
+ SA_INTERRUPT|SA_SHIRQ,
card->driver, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_via82xx_free(chip);
return -EBUSY;
}
@@ -2178,6 +2318,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
{ .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */
{ .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
{ .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_SRC }, /* Twinhead laptop */
+ { .subvendor = 0x1558, .subdevice = 0x4701, .action = VIA_DXS_SRC }, /* Clevo D470 */
{ .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */
{ .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */
{ .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */
@@ -2221,7 +2362,6 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
static int __devinit snd_via82xx_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
via82xx_t *chip;
unsigned char revision;
@@ -2229,14 +2369,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
unsigned int i;
int err;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -2259,12 +2392,12 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
}
}
if (chip_type != TYPE_VIA8233A) {
- if (dxs_support[dev] == VIA_DXS_AUTO)
- dxs_support[dev] = check_dxs_list(pci);
+ if (dxs_support == VIA_DXS_AUTO)
+ dxs_support = check_dxs_list(pci);
/* force to use VIA8233 or 8233A model according to
* dxs_support module option
*/
- if (dxs_support[dev] == VIA_DXS_DISABLE)
+ if (dxs_support == VIA_DXS_DISABLE)
chip_type = TYPE_VIA8233A;
else
chip_type = TYPE_VIA8233;
@@ -2282,14 +2415,15 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
goto __error;
}
- if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+ if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+ ac97_clock, &chip)) < 0)
goto __error;
- if ((err = snd_via82xx_mixer_new(chip, ac97_quirk[dev])) < 0)
+ if ((err = snd_via82xx_mixer_new(chip, ac97_quirk)) < 0)
goto __error;
if (chip_type == TYPE_VIA686) {
if ((err = snd_via686_pcm_new(chip)) < 0 ||
- (err = snd_via686_init_misc(chip, dev)) < 0)
+ (err = snd_via686_init_misc(chip)) < 0)
goto __error;
} else {
if (chip_type == TYPE_VIA8233A) {
@@ -2299,16 +2433,16 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
} else {
if ((err = snd_via8233_pcm_new(chip)) < 0)
goto __error;
- if (dxs_support[dev] == VIA_DXS_48K)
+ if (dxs_support == VIA_DXS_48K)
chip->dxs_fixed = 1;
- else if (dxs_support[dev] == VIA_DXS_NO_VRA)
+ else if (dxs_support == VIA_DXS_NO_VRA)
chip->no_vra = 1;
- else if (dxs_support[dev] == VIA_DXS_SRC) {
+ else if (dxs_support == VIA_DXS_SRC) {
chip->no_vra = 1;
chip->dxs_src = 1;
}
}
- if ((err = snd_via8233_init_misc(chip, dev)) < 0)
+ if ((err = snd_via8233_init_misc(chip)) < 0)
goto __error;
}
@@ -2329,7 +2463,6 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
__error:
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 7eac6f6ac737..011f0fb63bf9 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -26,7 +26,7 @@
/*
* Changes:
*
- * Sep. 2, 2004 Sasha Khapyorsky <sashak@smlink.com>
+ * Sep. 2, 2004 Sasha Khapyorsky <sashak@alsa-project.org>
* Modified from original audio driver 'via82xx.c' to support AC97
* modems.
*/
@@ -55,20 +55,21 @@ MODULE_DESCRIPTION("VIA VT82xx modem");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}");
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
+static int ac97_clock = 48000;
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable modem part of VIA 82xx bridge.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
/*
* Direct registers
@@ -569,7 +570,7 @@ static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, u
res = viadev->lastpos;
} else if (check_invalid_pos(viadev, res)) {
#ifdef POINTER_DEBUG
- printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+ printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
#endif
if (count && size < count) {
snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
@@ -832,6 +833,7 @@ static int __devinit snd_via686_pcm_new(via82xx_t *chip)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
+ pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
pcm->private_data = chip;
strcpy(pcm->name, chip->card->shortname);
chip->pcms[0] = pcm;
@@ -878,7 +880,6 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
return err;
chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
chip->ac97_bus->clock = chip->ac97_clock;
- chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
@@ -967,12 +968,11 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
- snd_printk("AC'97 codec is not ready [0x%x]\n", val);
+ snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
VIA_REG_AC97_SECONDARY_VALID |
@@ -986,8 +986,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip)
chip->ac97_secondary = 1;
goto __ac97_ok2;
}
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_interruptible(1);
} while (time_before(jiffies, end_time));
/* This is ok, the most of motherboards have only one codec */
@@ -1101,7 +1100,7 @@ static int __devinit snd_via82xx_create(snd_card_t * card,
chip->port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
card->driver, (void *)chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_via82xx_free(chip);
return -EBUSY;
}
@@ -1135,7 +1134,6 @@ static int __devinit snd_via82xx_create(snd_card_t * card,
static int __devinit snd_via82xx_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
- static int dev;
snd_card_t *card;
via82xx_t *chip;
unsigned char revision;
@@ -1143,14 +1141,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
unsigned int i;
int err;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- if (!enable[dev]) {
- dev++;
- return -ENOENT;
- }
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index, id, THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -1167,7 +1158,8 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
goto __error;
}
- if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+ if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+ ac97_clock, &chip)) < 0)
goto __error;
if ((err = snd_via82xx_mixer_new(chip)) < 0)
goto __error;
@@ -1191,7 +1183,6 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
return err;
}
pci_set_drvdata(pci, card);
- dev++;
return 0;
__error:
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 2e69abe51aa9..1bbba32517ff 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -130,8 +130,7 @@ static int __devinit snd_ymfpci_create_gameport(ymfpci_t *chip, int dev,
chip->gameport = gp = gameport_allocate_port();
if (!gp) {
printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n");
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
return -ENOMEM;
}
@@ -161,8 +160,7 @@ void snd_ymfpci_free_gameport(ymfpci_t *chip)
gameport_unregister_port(chip->gameport);
chip->gameport = NULL;
- release_resource(r);
- kfree_nocheck(r);
+ release_and_free_resource(r);
}
}
#else
@@ -267,14 +265,8 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
old_legacy_ctrl,
&chip)) < 0) {
snd_card_free(card);
- if (mpu_res) {
- release_resource(mpu_res);
- kfree_nocheck(mpu_res);
- }
- if (fm_res) {
- release_resource(fm_res);
- kfree_nocheck(fm_res);
- }
+ release_and_free_resource(mpu_res);
+ release_and_free_resource(fm_res);
return err;
}
chip->fm_res = fm_res;
@@ -328,7 +320,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
} else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
snd_card_free(card);
- snd_printk("cannot create opl3 hwdep\n");
+ snd_printk(KERN_ERR "cannot create opl3 hwdep\n");
return err;
}
}
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 27fa523639ae..88a43e091d77 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -92,9 +92,9 @@ static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary)
if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0)
return 0;
set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
- snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
+ snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
return -EBUSY;
}
@@ -728,8 +728,7 @@ static void snd_ymfpci_irq_wait(ymfpci_t *chip)
init_waitqueue_entry(&wait, current);
add_wait_queue(&chip->interrupt_sleep, &wait);
atomic_inc(&chip->interrupt_sleep_count);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ/20);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(50));
remove_wait_queue(&chip->interrupt_sleep, &wait);
}
}
@@ -1421,15 +1420,18 @@ static snd_kcontrol_new_t snd_ymfpci_drec_source __devinitdata = {
* Mixer controls
*/
-#define YMFPCI_SINGLE(xname, xindex, reg) \
+#define YMFPCI_SINGLE(xname, xindex, reg, shift) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
.info = snd_ymfpci_info_single, \
.get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \
- .private_value = reg }
+ .private_value = ((reg) | ((shift) << 16)) }
-static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_info_t *uinfo)
{
- switch (kcontrol->private_value) {
+ int reg = kcontrol->private_value & 0xffff;
+
+ switch (reg) {
case YDSXGR_SPDIFOUTCTRL: break;
case YDSXGR_SPDIFINCTRL: break;
default: return -EINVAL;
@@ -1441,30 +1443,35 @@ static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
return 0;
}
-static int snd_ymfpci_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_get_single(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_value_t *ucontrol)
{
ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value;
- unsigned int shift = 0, mask = 1;
+ int reg = kcontrol->private_value & 0xffff;
+ unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
+ unsigned int mask = 1;
- switch (kcontrol->private_value) {
+ switch (reg) {
case YDSXGR_SPDIFOUTCTRL: break;
case YDSXGR_SPDIFINCTRL: break;
default: return -EINVAL;
}
- ucontrol->value.integer.value[0] = (snd_ymfpci_readl(chip, reg) >> shift) & mask;
+ ucontrol->value.integer.value[0] =
+ (snd_ymfpci_readl(chip, reg) >> shift) & mask;
return 0;
}
-static int snd_ymfpci_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_put_single(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_value_t *ucontrol)
{
ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value;
- unsigned int shift = 0, mask = 1;
+ int reg = kcontrol->private_value & 0xffff;
+ unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
+ unsigned int mask = 1;
int change;
unsigned int val, oval;
- switch (kcontrol->private_value) {
+ switch (reg) {
case YDSXGR_SPDIFOUTCTRL: break;
case YDSXGR_SPDIFINCTRL: break;
default: return -EINVAL;
@@ -1583,8 +1590,9 @@ YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVO
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL),
YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "4ch Duplication",
@@ -1842,9 +1850,7 @@ static int snd_ymfpci_timer_start(snd_timer_t *timer)
unsigned int count;
chip = snd_timer_chip(timer);
- count = timer->sticks - 1;
- if (count == 0) /* minimum time is 20.8 us */
- count = 1;
+ count = (timer->sticks << 1) - 1;
spin_lock_irqsave(&chip->reg_lock, flags);
snd_ymfpci_writew(chip, YDSXGR_TIMERCOUNT, count);
snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x03);
@@ -1868,14 +1874,14 @@ static int snd_ymfpci_timer_precise_resolution(snd_timer_t *timer,
unsigned long *num, unsigned long *den)
{
*num = 1;
- *den = 96000;
+ *den = 48000;
return 0;
}
static struct _snd_timer_hardware snd_ymfpci_timer_hw = {
.flags = SNDRV_TIMER_HW_AUTO,
- .resolution = 10417, /* 1/2fs = 10.41666...us */
- .ticks = 65536,
+ .resolution = 20833, /* 1/fs = 20.8333...us */
+ .ticks = 0x8000,
.start = snd_ymfpci_timer_start,
.stop = snd_ymfpci_timer_stop,
.precise_resolution = snd_ymfpci_timer_precise_resolution,
@@ -2142,14 +2148,8 @@ static int snd_ymfpci_free(ymfpci_t *chip)
#ifdef CONFIG_PM
vfree(chip->saved_regs);
#endif
- if (chip->mpu_res) {
- release_resource(chip->mpu_res);
- kfree_nocheck(chip->mpu_res);
- }
- if (chip->fm_res) {
- release_resource(chip->fm_res);
- kfree_nocheck(chip->fm_res);
- }
+ release_and_free_resource(chip->mpu_res);
+ release_and_free_resource(chip->fm_res);
snd_ymfpci_free_gameport(chip);
if (chip->reg_area_virt)
iounmap(chip->reg_area_virt);
@@ -2158,10 +2158,7 @@ static int snd_ymfpci_free(ymfpci_t *chip)
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
- if (chip->res_reg_area) {
- release_resource(chip->res_reg_area);
- kfree_nocheck(chip->res_reg_area);
- }
+ release_and_free_resource(chip->res_reg_area);
pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
@@ -2290,12 +2287,12 @@ int __devinit snd_ymfpci_create(snd_card_t * card,
pci_set_master(pci);
if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
- snd_printk("unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
+ snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
snd_ymfpci_free(chip);
return -EBUSY;
}
if (request_irq(pci->irq, snd_ymfpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "YMFPCI", (void *) chip)) {
- snd_printk("unable to grab IRQ %d\n", pci->irq);
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_ymfpci_free(chip);
return -EBUSY;
}