mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Merge branch 'topic/misc' into for-linus
This commit is contained in:
commit
57648cd52b
36 changed files with 1463 additions and 702 deletions
|
|
@ -394,21 +394,15 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
err = snd_wss_create(card, port[dev], cport[dev],
|
||||
err = snd_cs4236_create(card, port[dev], cport[dev],
|
||||
irq[dev],
|
||||
dma1[dev], dma2[dev],
|
||||
WSS_HW_DETECT3, 0, &chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
acard->chip = chip;
|
||||
if (chip->hardware & WSS_HW_CS4236B_MASK) {
|
||||
snd_wss_free(chip);
|
||||
err = snd_cs4236_create(card,
|
||||
port[dev], cport[dev],
|
||||
irq[dev], dma1[dev], dma2[dev],
|
||||
WSS_HW_DETECT, 0, &chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
acard->chip = chip;
|
||||
|
||||
err = snd_cs4236_pcm(chip, 0, &pcm);
|
||||
if (err < 0)
|
||||
|
|
@ -418,7 +412,6 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
|
|||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
acard->chip = chip;
|
||||
err = snd_wss_pcm(chip, 0, &pcm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@
|
|||
#include <sound/core.h>
|
||||
#include <sound/wss.h>
|
||||
#include <sound/asoundef.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
/*
|
||||
*
|
||||
|
|
@ -264,7 +266,10 @@ static void snd_cs4236_resume(struct snd_wss *chip)
|
|||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
/*
|
||||
* This function does no fail if the chip is not CS4236B or compatible.
|
||||
* It just an equivalent to the snd_wss_create() then.
|
||||
*/
|
||||
int snd_cs4236_create(struct snd_card *card,
|
||||
unsigned long port,
|
||||
unsigned long cport,
|
||||
|
|
@ -281,21 +286,17 @@ int snd_cs4236_create(struct snd_card *card,
|
|||
*rchip = NULL;
|
||||
if (hardware == WSS_HW_DETECT)
|
||||
hardware = WSS_HW_DETECT3;
|
||||
if (cport < 0x100) {
|
||||
snd_printk(KERN_ERR "please, specify control port "
|
||||
"for CS4236+ chips\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = snd_wss_create(card, port, cport,
|
||||
irq, dma1, dma2, hardware, hwshare, &chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (!(chip->hardware & WSS_HW_CS4236B_MASK)) {
|
||||
snd_printk(KERN_ERR "CS4236+: MODE3 and extended registers "
|
||||
"not available, hardware=0x%x\n", chip->hardware);
|
||||
snd_device_free(card, chip);
|
||||
return -ENODEV;
|
||||
if ((chip->hardware & WSS_HW_CS4236B_MASK) == 0) {
|
||||
snd_printd("chip is not CS4236+, hardware=0x%x\n",
|
||||
chip->hardware);
|
||||
*rchip = chip;
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
|
|
@ -308,9 +309,16 @@ int snd_cs4236_create(struct snd_card *card,
|
|||
idx, snd_cs4236_ctrl_in(chip, idx));
|
||||
}
|
||||
#endif
|
||||
if (cport < 0x100 || cport == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR "please, specify control port "
|
||||
"for CS4236+ chips\n");
|
||||
snd_device_free(card, chip);
|
||||
return -ENODEV;
|
||||
}
|
||||
ver1 = snd_cs4236_ctrl_in(chip, 1);
|
||||
ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
|
||||
snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2);
|
||||
snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n",
|
||||
cport, ver1, ver2);
|
||||
if (ver1 != ver2) {
|
||||
snd_printk(KERN_ERR "CS4236+ chip detected, but "
|
||||
"control port 0x%lx is not valid\n", cport);
|
||||
|
|
@ -321,13 +329,17 @@ int snd_cs4236_create(struct snd_card *card,
|
|||
snd_cs4236_ctrl_out(chip, 2, 0xff);
|
||||
snd_cs4236_ctrl_out(chip, 3, 0x00);
|
||||
snd_cs4236_ctrl_out(chip, 4, 0x80);
|
||||
snd_cs4236_ctrl_out(chip, 5, ((IEC958_AES1_CON_PCM_CODER & 3) << 6) | IEC958_AES0_CON_EMPHASIS_NONE);
|
||||
reg = ((IEC958_AES1_CON_PCM_CODER & 3) << 6) |
|
||||
IEC958_AES0_CON_EMPHASIS_NONE;
|
||||
snd_cs4236_ctrl_out(chip, 5, reg);
|
||||
snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
|
||||
snd_cs4236_ctrl_out(chip, 7, 0x00);
|
||||
/* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958 output */
|
||||
/* is working with this setup, other hardware should have */
|
||||
/* different signal paths and this value should be selectable */
|
||||
/* in the future */
|
||||
/*
|
||||
* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958
|
||||
* output is working with this setup, other hardware should
|
||||
* have different signal paths and this value should be
|
||||
* selectable in the future
|
||||
*/
|
||||
snd_cs4236_ctrl_out(chip, 8, 0x8c);
|
||||
chip->rate_constraint = snd_cs4236_xrate;
|
||||
chip->set_playback_format = snd_cs4236_playback_format;
|
||||
|
|
@ -339,9 +351,10 @@ int snd_cs4236_create(struct snd_card *card,
|
|||
|
||||
/* initialize extended registers */
|
||||
for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++)
|
||||
snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), snd_cs4236_ext_map[reg]);
|
||||
snd_cs4236_ext_out(chip, CS4236_I23VAL(reg),
|
||||
snd_cs4236_ext_map[reg]);
|
||||
|
||||
/* initialize compatible but more featured registers */
|
||||
/* initialize compatible but more featured registers */
|
||||
snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40);
|
||||
snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40);
|
||||
snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
|
||||
|
|
@ -387,6 +400,14 @@ int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
|
|||
.get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
|
||||
.private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
|
||||
|
||||
#define CS4236_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_single, \
|
||||
.get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
|
||||
.private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
int mask = (kcontrol->private_value >> 16) & 0xff;
|
||||
|
|
@ -490,6 +511,16 @@ static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
|||
.get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
|
||||
|
||||
#define CS4236_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, \
|
||||
shift_right, mask, invert, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
|
||||
(shift_right << 19) | (mask << 24) | (invert << 22), \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
int mask = (kcontrol->private_value >> 24) & 0xff;
|
||||
|
|
@ -560,12 +591,23 @@ static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
|
|||
return change;
|
||||
}
|
||||
|
||||
#define CS4236_DOUBLE1(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
|
||||
#define CS4236_DOUBLE1(xname, xindex, left_reg, right_reg, shift_left, \
|
||||
shift_right, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
|
||||
|
||||
#define CS4236_DOUBLE1_TLV(xname, xindex, left_reg, right_reg, shift_left, \
|
||||
shift_right, mask, invert, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
|
||||
(shift_right << 19) | (mask << 24) | (invert << 22), \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
|
||||
|
|
@ -619,16 +661,18 @@ static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
|||
return change;
|
||||
}
|
||||
|
||||
#define CS4236_MASTER_DIGITAL(xname, xindex) \
|
||||
#define CS4236_MASTER_DIGITAL(xname, xindex, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4236_get_master_digital, .put = snd_cs4236_put_master_digital, \
|
||||
.private_value = 71 << 24 }
|
||||
.private_value = 71 << 24, \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol)
|
||||
{
|
||||
return (vol < 64) ? 63 - vol : 64 + (71 - vol);
|
||||
}
|
||||
}
|
||||
|
||||
static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
|
@ -661,11 +705,13 @@ static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct s
|
|||
return change;
|
||||
}
|
||||
|
||||
#define CS4235_OUTPUT_ACCU(xname, xindex) \
|
||||
#define CS4235_OUTPUT_ACCU(xname, xindex, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4235_get_output_accu, .put = snd_cs4235_put_output_accu, \
|
||||
.private_value = 3 << 24 }
|
||||
.private_value = 3 << 24, \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static inline int snd_cs4235_mixer_output_accu_get_volume(int vol)
|
||||
{
|
||||
|
|
@ -720,41 +766,56 @@ static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_
|
|||
return change;
|
||||
}
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -9450, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_6bit_12db_max, -8250, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_22db_max, -2400, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_2bit, -1800, 600, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
|
||||
|
||||
static struct snd_kcontrol_new snd_cs4236_controls[] = {
|
||||
|
||||
CS4236_DOUBLE("Master Digital Playback Switch", 0,
|
||||
CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Master Digital Capture Switch", 0,
|
||||
CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
|
||||
CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
|
||||
CS4236_MASTER_DIGITAL("Master Digital Volume", 0, db_scale_7bit),
|
||||
|
||||
CS4236_DOUBLE("Capture Boost Volume", 0,
|
||||
CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1),
|
||||
CS4236_DOUBLE_TLV("Capture Boost Volume", 0,
|
||||
CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
|
||||
db_scale_2bit),
|
||||
|
||||
WSS_DOUBLE("PCM Playback Switch", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("PCM Playback Volume", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
|
||||
WSS_DOUBLE_TLV("PCM Playback Volume", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
|
||||
CS4236_DOUBLE("DSP Playback Switch", 0,
|
||||
CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("DSP Playback Volume", 0,
|
||||
CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1),
|
||||
CS4236_DOUBLE_TLV("DSP Playback Volume", 0,
|
||||
CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
|
||||
CS4236_DOUBLE("FM Playback Switch", 0,
|
||||
CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("FM Playback Volume", 0,
|
||||
CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1),
|
||||
CS4236_DOUBLE_TLV("FM Playback Volume", 0,
|
||||
CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
|
||||
CS4236_DOUBLE("Wavetable Playback Switch", 0,
|
||||
CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Wavetable Playback Volume", 0,
|
||||
CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1),
|
||||
CS4236_DOUBLE_TLV("Wavetable Playback Volume", 0,
|
||||
CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1,
|
||||
db_scale_6bit_12db_max),
|
||||
|
||||
WSS_DOUBLE("Synth Playback Switch", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Synth Volume", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Synth Volume", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
WSS_DOUBLE("Synth Capture Switch", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Synth Capture Bypass", 0,
|
||||
|
|
@ -764,14 +825,16 @@ CS4236_DOUBLE("Mic Playback Switch", 0,
|
|||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
|
||||
CS4236_DOUBLE("Mic Capture Switch", 0,
|
||||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 0, 0, 31, 1),
|
||||
CS4236_DOUBLE("Mic Playback Boost", 0,
|
||||
CS4236_DOUBLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC,
|
||||
0, 0, 31, 1, db_scale_5bit_22db_max),
|
||||
CS4236_DOUBLE("Mic Playback Boost (+20dB)", 0,
|
||||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0),
|
||||
|
||||
WSS_DOUBLE("Line Playback Switch", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Line Volume", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Line Volume", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
WSS_DOUBLE("Line Capture Switch", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Line Capture Bypass", 0,
|
||||
|
|
@ -779,57 +842,63 @@ WSS_DOUBLE("Line Capture Bypass", 0,
|
|||
|
||||
WSS_DOUBLE("CD Playback Switch", 0,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("CD Volume", 0,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("CD Volume", 0,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
WSS_DOUBLE("CD Capture Switch", 0,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
|
||||
|
||||
CS4236_DOUBLE1("Mono Output Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
|
||||
CS4236_DOUBLE1("Mono Playback Switch", 0,
|
||||
CS4236_DOUBLE1("Beep Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
|
||||
WSS_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
|
||||
WSS_SINGLE("Mono Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0),
|
||||
WSS_SINGLE_TLV("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1,
|
||||
db_scale_4bit),
|
||||
WSS_SINGLE("Beep Bypass Playback Switch", 0, CS4231_MONO_CTRL, 5, 1, 0),
|
||||
|
||||
WSS_DOUBLE("Capture Volume", 0,
|
||||
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
|
||||
WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
|
||||
0, 0, 15, 0, db_scale_rec_gain),
|
||||
WSS_DOUBLE("Analog Loopback Capture Switch", 0,
|
||||
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
|
||||
|
||||
WSS_SINGLE("Digital Loopback Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
|
||||
CS4236_DOUBLE1("Digital Loopback Playback Volume", 0,
|
||||
CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1)
|
||||
WSS_SINGLE("Loopback Digital Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
|
||||
CS4236_DOUBLE1_TLV("Loopback Digital Playback Volume", 0,
|
||||
CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
};
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_6db_max, -5600, 200, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_2bit_16db_max, -2400, 800, 0);
|
||||
|
||||
static struct snd_kcontrol_new snd_cs4235_controls[] = {
|
||||
|
||||
WSS_DOUBLE("Master Switch", 0,
|
||||
WSS_DOUBLE("Master Playback Switch", 0,
|
||||
CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Master Volume", 0,
|
||||
CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Master Playback Volume", 0,
|
||||
CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1,
|
||||
db_scale_5bit_6db_max),
|
||||
|
||||
CS4235_OUTPUT_ACCU("Playback Volume", 0),
|
||||
CS4235_OUTPUT_ACCU("Playback Volume", 0, db_scale_2bit_16db_max),
|
||||
|
||||
CS4236_DOUBLE("Master Digital Playback Switch", 0,
|
||||
CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Master Digital Capture Switch", 0,
|
||||
CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
|
||||
CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
|
||||
|
||||
WSS_DOUBLE("Master Digital Playback Switch", 1,
|
||||
WSS_DOUBLE("Synth Playback Switch", 1,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Master Digital Capture Switch", 1,
|
||||
WSS_DOUBLE("Synth Capture Switch", 1,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Master Digital Volume", 1,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Synth Volume", 1,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
|
||||
CS4236_DOUBLE("Capture Volume", 0,
|
||||
CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1),
|
||||
CS4236_DOUBLE_TLV("Capture Volume", 0,
|
||||
CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
|
||||
db_scale_2bit),
|
||||
|
||||
WSS_DOUBLE("PCM Switch", 0,
|
||||
WSS_DOUBLE("PCM Playback Switch", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("PCM Volume", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
|
||||
WSS_DOUBLE("PCM Capture Switch", 0,
|
||||
CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
|
||||
WSS_DOUBLE_TLV("PCM Volume", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
|
||||
CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
|
||||
|
||||
|
|
@ -842,29 +911,29 @@ CS4236_DOUBLE("Mic Capture Switch", 0,
|
|||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Mic Playback Switch", 0,
|
||||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
|
||||
CS4236_SINGLE("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1),
|
||||
CS4236_SINGLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, 5, 1, 0),
|
||||
CS4236_SINGLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1,
|
||||
db_scale_5bit_22db_max),
|
||||
CS4236_SINGLE("Mic Boost (+20dB)", 0, CS4236_LEFT_MIC, 5, 1, 0),
|
||||
|
||||
WSS_DOUBLE("Aux Playback Switch", 0,
|
||||
WSS_DOUBLE("Line Playback Switch", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Aux Capture Switch", 0,
|
||||
WSS_DOUBLE("Line Capture Switch", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Aux Volume", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Line Volume", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
|
||||
WSS_DOUBLE("Aux Playback Switch", 1,
|
||||
WSS_DOUBLE("CD Playback Switch", 1,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Aux Capture Switch", 1,
|
||||
WSS_DOUBLE("CD Capture Switch", 1,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Aux Volume", 1,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("CD Volume", 1,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
|
||||
CS4236_DOUBLE1("Master Mono Switch", 0,
|
||||
CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
|
||||
|
||||
CS4236_DOUBLE1("Mono Switch", 0,
|
||||
CS4236_DOUBLE1("Beep Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
|
||||
WSS_SINGLE("Mono Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
|
||||
WSS_SINGLE("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
|
||||
|
||||
WSS_DOUBLE("Analog Loopback Switch", 0,
|
||||
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
|
||||
|
|
|
|||
|
|
@ -102,8 +102,6 @@
|
|||
|
||||
struct snd_es18xx {
|
||||
unsigned long port; /* port of ESS chip */
|
||||
unsigned long mpu_port; /* MPU-401 port of ESS chip */
|
||||
unsigned long fm_port; /* FM port */
|
||||
unsigned long ctrl_port; /* Control port of ESS chip */
|
||||
struct resource *res_port;
|
||||
struct resource *res_mpu_port;
|
||||
|
|
@ -116,8 +114,6 @@ struct snd_es18xx {
|
|||
unsigned short audio2_vol; /* volume level of audio2 */
|
||||
|
||||
unsigned short active; /* active channel mask */
|
||||
unsigned int dma1_size;
|
||||
unsigned int dma2_size;
|
||||
unsigned int dma1_shift;
|
||||
unsigned int dma2_shift;
|
||||
|
||||
|
|
@ -135,7 +131,6 @@ struct snd_es18xx {
|
|||
|
||||
spinlock_t reg_lock;
|
||||
spinlock_t mixer_lock;
|
||||
spinlock_t ctrl_lock;
|
||||
#ifdef CONFIG_PM
|
||||
unsigned char pm_reg;
|
||||
#endif
|
||||
|
|
@ -354,7 +349,7 @@ static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned ch
|
|||
}
|
||||
|
||||
|
||||
static int snd_es18xx_reset(struct snd_es18xx *chip)
|
||||
static int __devinit snd_es18xx_reset(struct snd_es18xx *chip)
|
||||
{
|
||||
int i;
|
||||
outb(0x03, chip->port + 0x06);
|
||||
|
|
@ -490,8 +485,6 @@ static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip,
|
|||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
unsigned int count = snd_pcm_lib_period_bytes(substream);
|
||||
|
||||
chip->dma2_size = size;
|
||||
|
||||
snd_es18xx_rate_set(chip, substream, DAC2);
|
||||
|
||||
/* Transfer Count Reload */
|
||||
|
|
@ -591,8 +584,6 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
|
|||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
unsigned int count = snd_pcm_lib_period_bytes(substream);
|
||||
|
||||
chip->dma1_size = size;
|
||||
|
||||
snd_es18xx_reset_fifo(chip);
|
||||
|
||||
/* Set stereo/mono */
|
||||
|
|
@ -659,8 +650,6 @@ static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip,
|
|||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
unsigned int count = snd_pcm_lib_period_bytes(substream);
|
||||
|
||||
chip->dma1_size = size;
|
||||
|
||||
snd_es18xx_reset_fifo(chip);
|
||||
|
||||
/* Set stereo/mono */
|
||||
|
|
@ -821,17 +810,18 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
|
|||
static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
|
||||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
int pos;
|
||||
|
||||
if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
|
||||
if (!(chip->active & DAC2))
|
||||
return 0;
|
||||
pos = snd_dma_pointer(chip->dma2, chip->dma2_size);
|
||||
pos = snd_dma_pointer(chip->dma2, size);
|
||||
return pos >> chip->dma2_shift;
|
||||
} else {
|
||||
if (!(chip->active & DAC1))
|
||||
return 0;
|
||||
pos = snd_dma_pointer(chip->dma1, chip->dma1_size);
|
||||
pos = snd_dma_pointer(chip->dma1, size);
|
||||
return pos >> chip->dma1_shift;
|
||||
}
|
||||
}
|
||||
|
|
@ -839,11 +829,12 @@ static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *s
|
|||
static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
|
||||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
int pos;
|
||||
|
||||
if (!(chip->active & ADC1))
|
||||
return 0;
|
||||
pos = snd_dma_pointer(chip->dma1, chip->dma1_size);
|
||||
pos = snd_dma_pointer(chip->dma1, size);
|
||||
return pos >> chip->dma1_shift;
|
||||
}
|
||||
|
||||
|
|
@ -974,9 +965,6 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
|
|||
|
||||
static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
static char *texts4Source[4] = {
|
||||
"Mic", "CD", "Line", "Master"
|
||||
};
|
||||
static char *texts5Source[5] = {
|
||||
"Mic", "CD", "Line", "Master", "Mix"
|
||||
};
|
||||
|
|
@ -994,7 +982,8 @@ static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
|
|||
uinfo->value.enumerated.items = 4;
|
||||
if (uinfo->value.enumerated.item > 3)
|
||||
uinfo->value.enumerated.item = 3;
|
||||
strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]);
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
texts5Source[uinfo->value.enumerated.item]);
|
||||
break;
|
||||
case 0x1887:
|
||||
case 0x1888:
|
||||
|
|
@ -1378,11 +1367,9 @@ ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
|
|||
static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
|
||||
{
|
||||
int data;
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&chip->ctrl_lock, flags);
|
||||
|
||||
outb(reg, chip->ctrl_port);
|
||||
data = inb(chip->ctrl_port + 1);
|
||||
spin_unlock_irqrestore(&chip->ctrl_lock, flags);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
@ -1398,7 +1385,9 @@ static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip,
|
|||
#endif
|
||||
}
|
||||
|
||||
static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
|
||||
static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip,
|
||||
unsigned long mpu_port,
|
||||
unsigned long fm_port)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
|
|
@ -1412,15 +1401,15 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
|
|||
if (chip->caps & ES18XX_CONTROL) {
|
||||
/* Hardware volume IRQ */
|
||||
snd_es18xx_config_write(chip, 0x27, chip->irq);
|
||||
if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) {
|
||||
if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
|
||||
/* FM I/O */
|
||||
snd_es18xx_config_write(chip, 0x62, chip->fm_port >> 8);
|
||||
snd_es18xx_config_write(chip, 0x63, chip->fm_port & 0xff);
|
||||
snd_es18xx_config_write(chip, 0x62, fm_port >> 8);
|
||||
snd_es18xx_config_write(chip, 0x63, fm_port & 0xff);
|
||||
}
|
||||
if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
|
||||
if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
|
||||
/* MPU-401 I/O */
|
||||
snd_es18xx_config_write(chip, 0x64, chip->mpu_port >> 8);
|
||||
snd_es18xx_config_write(chip, 0x65, chip->mpu_port & 0xff);
|
||||
snd_es18xx_config_write(chip, 0x64, mpu_port >> 8);
|
||||
snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff);
|
||||
/* MPU-401 IRQ */
|
||||
snd_es18xx_config_write(chip, 0x28, chip->irq);
|
||||
}
|
||||
|
|
@ -1507,11 +1496,12 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
|
|||
snd_es18xx_mixer_write(chip, 0x7A, 0x68);
|
||||
/* Enable and set hardware volume interrupt */
|
||||
snd_es18xx_mixer_write(chip, 0x64, 0x06);
|
||||
if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
|
||||
if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
|
||||
/* MPU401 share irq with audio
|
||||
Joystick enabled
|
||||
FM enabled */
|
||||
snd_es18xx_mixer_write(chip, 0x40, 0x43 | (chip->mpu_port & 0xf0) >> 1);
|
||||
snd_es18xx_mixer_write(chip, 0x40,
|
||||
0x43 | (mpu_port & 0xf0) >> 1);
|
||||
}
|
||||
snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01);
|
||||
}
|
||||
|
|
@ -1629,7 +1619,9 @@ static int __devinit snd_es18xx_identify(struct snd_es18xx *chip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
|
||||
static int __devinit snd_es18xx_probe(struct snd_es18xx *chip,
|
||||
unsigned long mpu_port,
|
||||
unsigned long fm_port)
|
||||
{
|
||||
if (snd_es18xx_identify(chip) < 0) {
|
||||
snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port);
|
||||
|
|
@ -1650,8 +1642,6 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
|
|||
chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
|
||||
break;
|
||||
case 0x1887:
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
|
||||
break;
|
||||
case 0x1888:
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
|
||||
break;
|
||||
|
|
@ -1666,7 +1656,7 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
|
|||
if (chip->dma1 == chip->dma2)
|
||||
chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME);
|
||||
|
||||
return snd_es18xx_initialize(chip);
|
||||
return snd_es18xx_initialize(chip, mpu_port, fm_port);
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops snd_es18xx_playback_ops = {
|
||||
|
|
@ -1802,10 +1792,7 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card,
|
|||
|
||||
spin_lock_init(&chip->reg_lock);
|
||||
spin_lock_init(&chip->mixer_lock);
|
||||
spin_lock_init(&chip->ctrl_lock);
|
||||
chip->port = port;
|
||||
chip->mpu_port = mpu_port;
|
||||
chip->fm_port = fm_port;
|
||||
chip->irq = -1;
|
||||
chip->dma1 = -1;
|
||||
chip->dma2 = -1;
|
||||
|
|
@ -1841,11 +1828,11 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card,
|
|||
}
|
||||
chip->dma2 = dma2;
|
||||
|
||||
if (snd_es18xx_probe(chip) < 0) {
|
||||
if (snd_es18xx_probe(chip, mpu_port, fm_port) < 0) {
|
||||
snd_es18xx_free(card);
|
||||
return -ENODEV;
|
||||
}
|
||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, NULL, &ops);
|
||||
return -ENODEV;
|
||||
}
|
||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
|
||||
if (err < 0) {
|
||||
snd_es18xx_free(card);
|
||||
return err;
|
||||
|
|
@ -1980,7 +1967,7 @@ 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_ISAPNP; /* Enable this card */
|
||||
#ifdef CONFIG_PNP
|
||||
static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
|
||||
static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
|
||||
#endif
|
||||
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
|
||||
#ifndef CONFIG_PNP
|
||||
|
|
@ -2160,19 +2147,23 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
|
|||
return err;
|
||||
|
||||
if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
|
||||
if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) {
|
||||
snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port);
|
||||
if (snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
|
||||
OPL3_HW_OPL3, 0, &opl3) < 0) {
|
||||
snd_printk(KERN_WARNING PFX
|
||||
"opl3 not detected at 0x%lx\n",
|
||||
fm_port[dev]);
|
||||
} else {
|
||||
if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
|
||||
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
|
||||
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
|
||||
chip->mpu_port, 0,
|
||||
irq[dev], 0,
|
||||
&chip->rmidi)) < 0)
|
||||
err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
|
||||
mpu_port[dev], 0,
|
||||
irq[dev], 0, &chip->rmidi);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,73 +0,0 @@
|
|||
#ifndef _MIRO_H_
|
||||
#define _MIRO_H_
|
||||
|
||||
#define ACI_REG_COMMAND 0 /* write register offset */
|
||||
#define ACI_REG_STATUS 1 /* read register offset */
|
||||
#define ACI_REG_BUSY 2 /* busy register offset */
|
||||
#define ACI_REG_RDS 2 /* PCM20: RDS register offset */
|
||||
#define ACI_MINTIME 500 /* ACI time out limit */
|
||||
|
||||
#define ACI_SET_MUTE 0x0d
|
||||
#define ACI_SET_POWERAMP 0x0f
|
||||
#define ACI_SET_TUNERMUTE 0xa3
|
||||
#define ACI_SET_TUNERMONO 0xa4
|
||||
#define ACI_SET_IDE 0xd0
|
||||
#define ACI_SET_WSS 0xd1
|
||||
#define ACI_SET_SOLOMODE 0xd2
|
||||
#define ACI_SET_PREAMP 0x03
|
||||
#define ACI_GET_PREAMP 0x21
|
||||
#define ACI_WRITE_TUNE 0xa7
|
||||
#define ACI_READ_TUNERSTEREO 0xa8
|
||||
#define ACI_READ_TUNERSTATION 0xa9
|
||||
#define ACI_READ_VERSION 0xf1
|
||||
#define ACI_READ_IDCODE 0xf2
|
||||
#define ACI_INIT 0xff
|
||||
#define ACI_STATUS 0xf0
|
||||
#define ACI_S_GENERAL 0x00
|
||||
#define ACI_ERROR_OP 0xdf
|
||||
|
||||
/* ACI Mixer */
|
||||
|
||||
/* These are the values for the right channel GET registers.
|
||||
Add an offset of 0x01 for the left channel register.
|
||||
(left=right+0x01) */
|
||||
|
||||
#define ACI_GET_MASTER 0x03
|
||||
#define ACI_GET_MIC 0x05
|
||||
#define ACI_GET_LINE 0x07
|
||||
#define ACI_GET_CD 0x09
|
||||
#define ACI_GET_SYNTH 0x0b
|
||||
#define ACI_GET_PCM 0x0d
|
||||
#define ACI_GET_LINE1 0x10 /* Radio on PCM20 */
|
||||
#define ACI_GET_LINE2 0x12
|
||||
|
||||
#define ACI_GET_EQ1 0x22 /* from Bass ... */
|
||||
#define ACI_GET_EQ2 0x24
|
||||
#define ACI_GET_EQ3 0x26
|
||||
#define ACI_GET_EQ4 0x28
|
||||
#define ACI_GET_EQ5 0x2a
|
||||
#define ACI_GET_EQ6 0x2c
|
||||
#define ACI_GET_EQ7 0x2e /* ... to Treble */
|
||||
|
||||
/* And these are the values for the right channel SET registers.
|
||||
For left channel access you have to add an offset of 0x08.
|
||||
MASTER is an exception, which needs an offset of 0x01 */
|
||||
|
||||
#define ACI_SET_MASTER 0x00
|
||||
#define ACI_SET_MIC 0x30
|
||||
#define ACI_SET_LINE 0x31
|
||||
#define ACI_SET_CD 0x34
|
||||
#define ACI_SET_SYNTH 0x33
|
||||
#define ACI_SET_PCM 0x32
|
||||
#define ACI_SET_LINE1 0x35 /* Radio on PCM20 */
|
||||
#define ACI_SET_LINE2 0x36
|
||||
|
||||
#define ACI_SET_EQ1 0x40 /* from Bass ... */
|
||||
#define ACI_SET_EQ2 0x41
|
||||
#define ACI_SET_EQ3 0x42
|
||||
#define ACI_SET_EQ4 0x43
|
||||
#define ACI_SET_EQ5 0x44
|
||||
#define ACI_SET_EQ6 0x45
|
||||
#define ACI_SET_EQ7 0x46 /* ... to Treble */
|
||||
|
||||
#endif /* _MIRO_H_ */
|
||||
|
|
@ -141,15 +141,7 @@ struct snd_opti9xx {
|
|||
|
||||
spinlock_t lock;
|
||||
|
||||
long wss_base;
|
||||
int irq;
|
||||
int dma1;
|
||||
int dma2;
|
||||
|
||||
long fm_port;
|
||||
|
||||
long mpu_port;
|
||||
int mpu_irq;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
struct pnp_dev *dev;
|
||||
|
|
@ -216,13 +208,7 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
|
|||
|
||||
spin_lock_init(&chip->lock);
|
||||
|
||||
chip->wss_base = -1;
|
||||
chip->irq = -1;
|
||||
chip->dma1 = -1;
|
||||
chip->dma2 = -1;
|
||||
chip->fm_port = -1;
|
||||
chip->mpu_port = -1;
|
||||
chip->mpu_irq = -1;
|
||||
|
||||
switch (hardware) {
|
||||
#ifndef OPTi93X
|
||||
|
|
@ -348,7 +334,10 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
|
|||
(snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
|
||||
|
||||
|
||||
static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
|
||||
static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
|
||||
long wss_base,
|
||||
int irq, int dma1, int dma2,
|
||||
long mpu_port, int mpu_irq)
|
||||
{
|
||||
unsigned char wss_base_bits;
|
||||
unsigned char irq_bits;
|
||||
|
|
@ -416,7 +405,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (chip->wss_base) {
|
||||
switch (wss_base) {
|
||||
case 0x530:
|
||||
wss_base_bits = 0x00;
|
||||
break;
|
||||
|
|
@ -430,14 +419,13 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
|
|||
wss_base_bits = 0x02;
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n",
|
||||
chip->wss_base);
|
||||
snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base);
|
||||
goto __skip_base;
|
||||
}
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
|
||||
|
||||
__skip_base:
|
||||
switch (chip->irq) {
|
||||
switch (irq) {
|
||||
//#ifdef OPTi93X
|
||||
case 5:
|
||||
irq_bits = 0x05;
|
||||
|
|
@ -456,11 +444,11 @@ __skip_base:
|
|||
irq_bits = 0x04;
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "WSS irq # %d not valid\n", chip->irq);
|
||||
snd_printk(KERN_WARNING "WSS irq # %d not valid\n", irq);
|
||||
goto __skip_resources;
|
||||
}
|
||||
|
||||
switch (chip->dma1) {
|
||||
switch (dma1) {
|
||||
case 0:
|
||||
dma_bits = 0x01;
|
||||
break;
|
||||
|
|
@ -471,38 +459,36 @@ __skip_base:
|
|||
dma_bits = 0x03;
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n",
|
||||
chip->dma1);
|
||||
snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", dma1);
|
||||
goto __skip_resources;
|
||||
}
|
||||
|
||||
#if defined(CS4231) || defined(OPTi93X)
|
||||
if (chip->dma1 == chip->dma2) {
|
||||
if (dma1 == dma2) {
|
||||
snd_printk(KERN_ERR "don't want to share dmas\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
switch (chip->dma2) {
|
||||
switch (dma2) {
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n",
|
||||
chip->dma2);
|
||||
snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", dma2);
|
||||
goto __skip_resources;
|
||||
}
|
||||
dma_bits |= 0x04;
|
||||
#endif /* CS4231 || OPTi93X */
|
||||
|
||||
#ifndef OPTi93X
|
||||
outb(irq_bits << 3 | dma_bits, chip->wss_base);
|
||||
outb(irq_bits << 3 | dma_bits, wss_base);
|
||||
#else /* OPTi93X */
|
||||
snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
|
||||
#endif /* OPTi93X */
|
||||
|
||||
__skip_resources:
|
||||
if (chip->hardware > OPTi9XX_HW_82C928) {
|
||||
switch (chip->mpu_port) {
|
||||
switch (mpu_port) {
|
||||
case 0:
|
||||
case -1:
|
||||
break;
|
||||
|
|
@ -520,12 +506,11 @@ __skip_resources:
|
|||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING
|
||||
"MPU-401 port 0x%lx not valid\n",
|
||||
chip->mpu_port);
|
||||
"MPU-401 port 0x%lx not valid\n", mpu_port);
|
||||
goto __skip_mpu;
|
||||
}
|
||||
|
||||
switch (chip->mpu_irq) {
|
||||
switch (mpu_irq) {
|
||||
case 5:
|
||||
mpu_irq_bits = 0x02;
|
||||
break;
|
||||
|
|
@ -540,12 +525,12 @@ __skip_resources:
|
|||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n",
|
||||
chip->mpu_irq);
|
||||
mpu_irq);
|
||||
goto __skip_mpu;
|
||||
}
|
||||
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6),
|
||||
(chip->mpu_port <= 0) ? 0x00 :
|
||||
(mpu_port <= 0) ? 0x00 :
|
||||
0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
|
||||
0xf8);
|
||||
}
|
||||
|
|
@ -701,6 +686,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
|||
{
|
||||
static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
|
||||
int error;
|
||||
int xdma2;
|
||||
struct snd_opti9xx *chip = card->private_data;
|
||||
struct snd_wss *codec;
|
||||
#ifdef CS4231
|
||||
|
|
@ -715,31 +701,25 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
|||
"OPTi9xx MC")) == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->wss_base = port;
|
||||
chip->fm_port = fm_port;
|
||||
chip->mpu_port = mpu_port;
|
||||
chip->irq = irq;
|
||||
chip->mpu_irq = mpu_irq;
|
||||
chip->dma1 = dma1;
|
||||
#if defined(CS4231) || defined(OPTi93X)
|
||||
chip->dma2 = dma2;
|
||||
xdma2 = dma2;
|
||||
#else
|
||||
chip->dma2 = -1;
|
||||
xdma2 = -1;
|
||||
#endif
|
||||
|
||||
if (chip->wss_base == SNDRV_AUTO_PORT) {
|
||||
chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4);
|
||||
if (chip->wss_base < 0) {
|
||||
if (port == SNDRV_AUTO_PORT) {
|
||||
port = snd_legacy_find_free_ioport(possible_ports, 4);
|
||||
if (port < 0) {
|
||||
snd_printk(KERN_ERR "unable to find a free WSS port\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
error = snd_opti9xx_configure(chip);
|
||||
error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
|
||||
mpu_port, mpu_irq);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = snd_wss_create(card, chip->wss_base + 4, -1,
|
||||
chip->irq, chip->dma1, chip->dma2,
|
||||
error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2,
|
||||
#ifdef OPTi93X
|
||||
WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
|
||||
#else
|
||||
|
|
@ -763,35 +743,35 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
|||
return error;
|
||||
#endif
|
||||
#ifdef OPTi93X
|
||||
error = request_irq(chip->irq, snd_opti93x_interrupt,
|
||||
error = request_irq(irq, snd_opti93x_interrupt,
|
||||
IRQF_DISABLED, DEV_NAME" - WSS", codec);
|
||||
if (error < 0) {
|
||||
snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
chip->irq = irq;
|
||||
strcpy(card->driver, chip->name);
|
||||
sprintf(card->shortname, "OPTi %s", card->driver);
|
||||
#if defined(CS4231) || defined(OPTi93X)
|
||||
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
|
||||
card->shortname, pcm->name, chip->wss_base + 4,
|
||||
chip->irq, chip->dma1, chip->dma2);
|
||||
card->shortname, pcm->name, port + 4, irq, dma1, xdma2);
|
||||
#else
|
||||
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
|
||||
card->shortname, pcm->name, chip->wss_base + 4,
|
||||
chip->irq, chip->dma1);
|
||||
card->shortname, pcm->name, port + 4, irq, dma1);
|
||||
#endif /* CS4231 || OPTi93X */
|
||||
|
||||
if (chip->mpu_port <= 0 || chip->mpu_port == SNDRV_AUTO_PORT)
|
||||
if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
|
||||
rmidi = NULL;
|
||||
else
|
||||
if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
|
||||
chip->mpu_port, 0, chip->mpu_irq, IRQF_DISABLED,
|
||||
&rmidi)))
|
||||
else {
|
||||
error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
|
||||
mpu_port, 0, mpu_irq, IRQF_DISABLED, &rmidi);
|
||||
if (error)
|
||||
snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
|
||||
chip->mpu_port);
|
||||
mpu_port);
|
||||
}
|
||||
|
||||
if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) {
|
||||
if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
|
||||
struct snd_opl3 *opl3 = NULL;
|
||||
#ifndef OPTi93X
|
||||
if (chip->hardware == OPTi9XX_HW_82C928 ||
|
||||
|
|
@ -801,9 +781,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
|||
/* assume we have an OPL4 */
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
|
||||
0x20, 0x20);
|
||||
if (snd_opl4_create(card,
|
||||
chip->fm_port,
|
||||
chip->fm_port - 8,
|
||||
if (snd_opl4_create(card, fm_port, fm_port - 8,
|
||||
2, &opl3, &opl4) < 0) {
|
||||
/* no luck, use OPL3 instead */
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
|
||||
|
|
@ -811,12 +789,10 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
|||
}
|
||||
}
|
||||
#endif /* !OPTi93X */
|
||||
if (!opl3 && snd_opl3_create(card,
|
||||
chip->fm_port,
|
||||
chip->fm_port + 2,
|
||||
if (!opl3 && snd_opl3_create(card, fm_port, fm_port + 2,
|
||||
OPL3_HW_AUTO, 0, &opl3) < 0) {
|
||||
snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
|
||||
chip->fm_port, chip->fm_port + 4 - 1);
|
||||
fm_port, fm_port + 4 - 1);
|
||||
}
|
||||
if (opl3) {
|
||||
error = snd_opl3_hwdep_new(opl3, 0, 1, &synth);
|
||||
|
|
|
|||
|
|
@ -1682,7 +1682,7 @@ static void snd_wss_resume(struct snd_wss *chip)
|
|||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
int snd_wss_free(struct snd_wss *chip)
|
||||
static int snd_wss_free(struct snd_wss *chip)
|
||||
{
|
||||
release_and_free_resource(chip->res_port);
|
||||
release_and_free_resource(chip->res_cport);
|
||||
|
|
@ -1705,7 +1705,6 @@ int snd_wss_free(struct snd_wss *chip)
|
|||
kfree(chip);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_wss_free);
|
||||
|
||||
static int snd_wss_dev_free(struct snd_device *device)
|
||||
{
|
||||
|
|
@ -2225,7 +2224,7 @@ WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
|
|||
.get = snd_wss_get_mux,
|
||||
.put = snd_wss_put_mux,
|
||||
},
|
||||
WSS_DOUBLE("Mic Boost", 0,
|
||||
WSS_DOUBLE("Mic Boost (+20dB)", 0,
|
||||
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
|
||||
WSS_SINGLE("Loopback Capture Switch", 0,
|
||||
CS4231_LOOPBACK, 0, 1, 0),
|
||||
|
|
@ -2236,14 +2235,14 @@ WSS_DOUBLE("Line Playback Switch", 0,
|
|||
WSS_DOUBLE_TLV("Line Playback Volume", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
WSS_SINGLE("Mono Playback Switch", 0,
|
||||
WSS_SINGLE("Beep Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, 7, 1, 1),
|
||||
WSS_SINGLE_TLV("Mono Playback Volume", 0,
|
||||
WSS_SINGLE_TLV("Beep Playback Volume", 0,
|
||||
CS4231_MONO_CTRL, 0, 15, 1,
|
||||
db_scale_4bit),
|
||||
WSS_SINGLE("Mono Output Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, 6, 1, 1),
|
||||
WSS_SINGLE("Mono Output Playback Bypass", 0,
|
||||
WSS_SINGLE("Beep Bypass Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, 5, 1, 0),
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue