diff options
Diffstat (limited to 'sound/isa/wss')
-rw-r--r-- | sound/isa/wss/wss_lib.c | 61 |
1 files changed, 56 insertions, 5 deletions
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index a982997805c4..1688f07a14b0 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <sound/core.h> | 33 | #include <sound/core.h> |
34 | #include <sound/wss.h> | 34 | #include <sound/wss.h> |
35 | #include <sound/pcm_params.h> | 35 | #include <sound/pcm_params.h> |
36 | #include <sound/tlv.h> | ||
36 | 37 | ||
37 | #include <asm/io.h> | 38 | #include <asm/io.h> |
38 | #include <asm/dma.h> | 39 | #include <asm/dma.h> |
@@ -1957,16 +1958,58 @@ int snd_wss_put_double(struct snd_kcontrol *kcontrol, | |||
1957 | val1 <<= shift_left; | 1958 | val1 <<= shift_left; |
1958 | val2 <<= shift_right; | 1959 | val2 <<= shift_right; |
1959 | spin_lock_irqsave(&chip->reg_lock, flags); | 1960 | spin_lock_irqsave(&chip->reg_lock, flags); |
1960 | val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; | 1961 | if (left_reg != right_reg) { |
1961 | val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; | 1962 | val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; |
1962 | change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg]; | 1963 | val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; |
1963 | snd_wss_out(chip, left_reg, val1); | 1964 | change = val1 != chip->image[left_reg] || |
1964 | snd_wss_out(chip, right_reg, val2); | 1965 | val2 != chip->image[right_reg]; |
1966 | snd_wss_out(chip, left_reg, val1); | ||
1967 | snd_wss_out(chip, right_reg, val2); | ||
1968 | } else { | ||
1969 | mask = (mask << shift_left) | (mask << shift_right); | ||
1970 | val1 = (chip->image[left_reg] & ~mask) | val1 | val2; | ||
1971 | change = val1 != chip->image[left_reg]; | ||
1972 | snd_wss_out(chip, left_reg, val1); | ||
1973 | } | ||
1965 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1974 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1966 | return change; | 1975 | return change; |
1967 | } | 1976 | } |
1968 | EXPORT_SYMBOL(snd_wss_put_double); | 1977 | EXPORT_SYMBOL(snd_wss_put_double); |
1969 | 1978 | ||
1979 | static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); | ||
1980 | static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); | ||
1981 | static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); | ||
1982 | |||
1983 | static struct snd_kcontrol_new snd_ad1848_controls[] = { | ||
1984 | WSS_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, | ||
1985 | 7, 7, 1, 1), | ||
1986 | WSS_DOUBLE_TLV("PCM Playback Volume", 0, | ||
1987 | CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1, | ||
1988 | db_scale_6bit), | ||
1989 | WSS_DOUBLE("Aux Playback Switch", 0, | ||
1990 | CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), | ||
1991 | WSS_DOUBLE_TLV("Aux Playback Volume", 0, | ||
1992 | CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1, | ||
1993 | db_scale_5bit_12db_max), | ||
1994 | WSS_DOUBLE("Aux Playback Switch", 1, | ||
1995 | CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), | ||
1996 | WSS_DOUBLE_TLV("Aux Playback Volume", 1, | ||
1997 | CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1, | ||
1998 | db_scale_5bit_12db_max), | ||
1999 | WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, | ||
2000 | 0, 0, 15, 0, db_scale_rec_gain), | ||
2001 | { | ||
2002 | .name = "Capture Source", | ||
2003 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2004 | .info = snd_wss_info_mux, | ||
2005 | .get = snd_wss_get_mux, | ||
2006 | .put = snd_wss_put_mux, | ||
2007 | }, | ||
2008 | WSS_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0), | ||
2009 | WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 1, 63, 0, | ||
2010 | db_scale_6bit), | ||
2011 | }; | ||
2012 | |||
1970 | static struct snd_kcontrol_new snd_wss_controls[] = { | 2013 | static struct snd_kcontrol_new snd_wss_controls[] = { |
1971 | WSS_DOUBLE("PCM Playback Switch", 0, | 2014 | WSS_DOUBLE("PCM Playback Switch", 0, |
1972 | CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), | 2015 | CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), |
@@ -2071,6 +2114,14 @@ int snd_wss_mixer(struct snd_wss *chip) | |||
2071 | if (err < 0) | 2114 | if (err < 0) |
2072 | return err; | 2115 | return err; |
2073 | } | 2116 | } |
2117 | else if (chip->hardware & WSS_HW_AD1848_MASK) | ||
2118 | for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) { | ||
2119 | err = snd_ctl_add(card, | ||
2120 | snd_ctl_new1(&snd_ad1848_controls[idx], | ||
2121 | chip)); | ||
2122 | if (err < 0) | ||
2123 | return err; | ||
2124 | } | ||
2074 | else | 2125 | else |
2075 | for (idx = 0; idx < ARRAY_SIZE(snd_wss_controls); idx++) { | 2126 | for (idx = 0; idx < ARRAY_SIZE(snd_wss_controls); idx++) { |
2076 | err = snd_ctl_add(card, | 2127 | err = snd_ctl_add(card, |