aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa')
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c55
-rw-r--r--sound/isa/ad1848/ad1848_lib.c49
-rw-r--r--sound/isa/es18xx.c219
-rw-r--r--sound/isa/gus/gus_mem_proc.c6
-rw-r--r--sound/isa/opl3sa2.c26
5 files changed, 262 insertions, 93 deletions
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 8fcf2c151823..fd9b61eda0f3 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/tlv.h>
27#include <sound/ad1816a.h> 28#include <sound/ad1816a.h>
28 29
29#include <asm/io.h> 30#include <asm/io.h>
@@ -765,6 +766,13 @@ static int snd_ad1816a_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
765 return change; 766 return change;
766} 767}
767 768
769#define AD1816A_SINGLE_TLV(xname, reg, shift, mask, invert, xtlv) \
770{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
771 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
772 .name = xname, .info = snd_ad1816a_info_single, \
773 .get = snd_ad1816a_get_single, .put = snd_ad1816a_put_single, \
774 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
775 .tlv = { .p = (xtlv) } }
768#define AD1816A_SINGLE(xname, reg, shift, mask, invert) \ 776#define AD1816A_SINGLE(xname, reg, shift, mask, invert) \
769{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ad1816a_info_single, \ 777{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ad1816a_info_single, \
770 .get = snd_ad1816a_get_single, .put = snd_ad1816a_put_single, \ 778 .get = snd_ad1816a_get_single, .put = snd_ad1816a_put_single, \
@@ -822,6 +830,14 @@ static int snd_ad1816a_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
822 return change; 830 return change;
823} 831}
824 832
833#define AD1816A_DOUBLE_TLV(xname, reg, shift_left, shift_right, mask, invert, xtlv) \
834{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
835 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
836 .name = xname, .info = snd_ad1816a_info_double, \
837 .get = snd_ad1816a_get_double, .put = snd_ad1816a_put_double, \
838 .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24), \
839 .tlv = { .p = (xtlv) } }
840
825#define AD1816A_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ 841#define AD1816A_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
826{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ad1816a_info_double, \ 842{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ad1816a_info_double, \
827 .get = snd_ad1816a_get_double, .put = snd_ad1816a_put_double, \ 843 .get = snd_ad1816a_get_double, .put = snd_ad1816a_put_double, \
@@ -890,28 +906,44 @@ static int snd_ad1816a_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
890 return change; 906 return change;
891} 907}
892 908
909static DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
910static DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
911static DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
912static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
913static DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
914
893static struct snd_kcontrol_new snd_ad1816a_controls[] __devinitdata = { 915static struct snd_kcontrol_new snd_ad1816a_controls[] __devinitdata = {
894AD1816A_DOUBLE("Master Playback Switch", AD1816A_MASTER_ATT, 15, 7, 1, 1), 916AD1816A_DOUBLE("Master Playback Switch", AD1816A_MASTER_ATT, 15, 7, 1, 1),
895AD1816A_DOUBLE("Master Playback Volume", AD1816A_MASTER_ATT, 8, 0, 31, 1), 917AD1816A_DOUBLE_TLV("Master Playback Volume", AD1816A_MASTER_ATT, 8, 0, 31, 1,
918 db_scale_5bit),
896AD1816A_DOUBLE("PCM Playback Switch", AD1816A_VOICE_ATT, 15, 7, 1, 1), 919AD1816A_DOUBLE("PCM Playback Switch", AD1816A_VOICE_ATT, 15, 7, 1, 1),
897AD1816A_DOUBLE("PCM Playback Volume", AD1816A_VOICE_ATT, 8, 0, 63, 1), 920AD1816A_DOUBLE_TLV("PCM Playback Volume", AD1816A_VOICE_ATT, 8, 0, 63, 1,
921 db_scale_6bit),
898AD1816A_DOUBLE("Line Playback Switch", AD1816A_LINE_GAIN_ATT, 15, 7, 1, 1), 922AD1816A_DOUBLE("Line Playback Switch", AD1816A_LINE_GAIN_ATT, 15, 7, 1, 1),
899AD1816A_DOUBLE("Line Playback Volume", AD1816A_LINE_GAIN_ATT, 8, 0, 31, 1), 923AD1816A_DOUBLE_TLV("Line Playback Volume", AD1816A_LINE_GAIN_ATT, 8, 0, 31, 1,
924 db_scale_5bit_12db_max),
900AD1816A_DOUBLE("CD Playback Switch", AD1816A_CD_GAIN_ATT, 15, 7, 1, 1), 925AD1816A_DOUBLE("CD Playback Switch", AD1816A_CD_GAIN_ATT, 15, 7, 1, 1),
901AD1816A_DOUBLE("CD Playback Volume", AD1816A_CD_GAIN_ATT, 8, 0, 31, 1), 926AD1816A_DOUBLE_TLV("CD Playback Volume", AD1816A_CD_GAIN_ATT, 8, 0, 31, 1,
927 db_scale_5bit_12db_max),
902AD1816A_DOUBLE("Synth Playback Switch", AD1816A_SYNTH_GAIN_ATT, 15, 7, 1, 1), 928AD1816A_DOUBLE("Synth Playback Switch", AD1816A_SYNTH_GAIN_ATT, 15, 7, 1, 1),
903AD1816A_DOUBLE("Synth Playback Volume", AD1816A_SYNTH_GAIN_ATT, 8, 0, 31, 1), 929AD1816A_DOUBLE_TLV("Synth Playback Volume", AD1816A_SYNTH_GAIN_ATT, 8, 0, 31, 1,
930 db_scale_5bit_12db_max),
904AD1816A_DOUBLE("FM Playback Switch", AD1816A_FM_ATT, 15, 7, 1, 1), 931AD1816A_DOUBLE("FM Playback Switch", AD1816A_FM_ATT, 15, 7, 1, 1),
905AD1816A_DOUBLE("FM Playback Volume", AD1816A_FM_ATT, 8, 0, 63, 1), 932AD1816A_DOUBLE_TLV("FM Playback Volume", AD1816A_FM_ATT, 8, 0, 63, 1,
933 db_scale_6bit),
906AD1816A_SINGLE("Mic Playback Switch", AD1816A_MIC_GAIN_ATT, 15, 1, 1), 934AD1816A_SINGLE("Mic Playback Switch", AD1816A_MIC_GAIN_ATT, 15, 1, 1),
907AD1816A_SINGLE("Mic Playback Volume", AD1816A_MIC_GAIN_ATT, 8, 31, 1), 935AD1816A_SINGLE_TLV("Mic Playback Volume", AD1816A_MIC_GAIN_ATT, 8, 31, 1,
936 db_scale_5bit_12db_max),
908AD1816A_SINGLE("Mic Boost", AD1816A_MIC_GAIN_ATT, 14, 1, 0), 937AD1816A_SINGLE("Mic Boost", AD1816A_MIC_GAIN_ATT, 14, 1, 0),
909AD1816A_DOUBLE("Video Playback Switch", AD1816A_VID_GAIN_ATT, 15, 7, 1, 1), 938AD1816A_DOUBLE("Video Playback Switch", AD1816A_VID_GAIN_ATT, 15, 7, 1, 1),
910AD1816A_DOUBLE("Video Playback Volume", AD1816A_VID_GAIN_ATT, 8, 0, 31, 1), 939AD1816A_DOUBLE_TLV("Video Playback Volume", AD1816A_VID_GAIN_ATT, 8, 0, 31, 1,
940 db_scale_5bit_12db_max),
911AD1816A_SINGLE("Phone Capture Switch", AD1816A_PHONE_IN_GAIN_ATT, 15, 1, 1), 941AD1816A_SINGLE("Phone Capture Switch", AD1816A_PHONE_IN_GAIN_ATT, 15, 1, 1),
912AD1816A_SINGLE("Phone Capture Volume", AD1816A_PHONE_IN_GAIN_ATT, 0, 15, 1), 942AD1816A_SINGLE_TLV("Phone Capture Volume", AD1816A_PHONE_IN_GAIN_ATT, 0, 15, 1,
943 db_scale_4bit),
913AD1816A_SINGLE("Phone Playback Switch", AD1816A_PHONE_OUT_ATT, 7, 1, 1), 944AD1816A_SINGLE("Phone Playback Switch", AD1816A_PHONE_OUT_ATT, 7, 1, 1),
914AD1816A_SINGLE("Phone Playback Volume", AD1816A_PHONE_OUT_ATT, 0, 31, 1), 945AD1816A_SINGLE_TLV("Phone Playback Volume", AD1816A_PHONE_OUT_ATT, 0, 31, 1,
946 db_scale_5bit),
915{ 947{
916 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 948 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
917 .name = "Capture Source", 949 .name = "Capture Source",
@@ -920,7 +952,8 @@ AD1816A_SINGLE("Phone Playback Volume", AD1816A_PHONE_OUT_ATT, 0, 31, 1),
920 .put = snd_ad1816a_put_mux, 952 .put = snd_ad1816a_put_mux,
921}, 953},
922AD1816A_DOUBLE("Capture Switch", AD1816A_ADC_PGA, 15, 7, 1, 1), 954AD1816A_DOUBLE("Capture Switch", AD1816A_ADC_PGA, 15, 7, 1, 1),
923AD1816A_DOUBLE("Capture Volume", AD1816A_ADC_PGA, 8, 0, 15, 0), 955AD1816A_DOUBLE_TLV("Capture Volume", AD1816A_ADC_PGA, 8, 0, 15, 0,
956 db_scale_rec_gain),
924AD1816A_SINGLE("3D Control - Switch", AD1816A_3D_PHAT_CTRL, 15, 1, 1), 957AD1816A_SINGLE("3D Control - Switch", AD1816A_3D_PHAT_CTRL, 15, 1, 1),
925AD1816A_SINGLE("3D Control - Level", AD1816A_3D_PHAT_CTRL, 0, 15, 0), 958AD1816A_SINGLE("3D Control - Level", AD1816A_3D_PHAT_CTRL, 0, 15, 0),
926}; 959};
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index e711f87d5fd1..a6fbd5d1d62f 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -29,6 +29,7 @@
29#include <sound/core.h> 29#include <sound/core.h>
30#include <sound/ad1848.h> 30#include <sound/ad1848.h>
31#include <sound/control.h> 31#include <sound/control.h>
32#include <sound/tlv.h>
32#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
33 34
34#include <asm/io.h> 35#include <asm/io.h>
@@ -118,6 +119,8 @@ void snd_ad1848_out(struct snd_ad1848 *chip,
118#endif 119#endif
119} 120}
120 121
122EXPORT_SYMBOL(snd_ad1848_out);
123
121static void snd_ad1848_dout(struct snd_ad1848 *chip, 124static void snd_ad1848_dout(struct snd_ad1848 *chip,
122 unsigned char reg, unsigned char value) 125 unsigned char reg, unsigned char value)
123{ 126{
@@ -941,6 +944,8 @@ int snd_ad1848_create(struct snd_card *card,
941 return 0; 944 return 0;
942} 945}
943 946
947EXPORT_SYMBOL(snd_ad1848_create);
948
944static struct snd_pcm_ops snd_ad1848_playback_ops = { 949static struct snd_pcm_ops snd_ad1848_playback_ops = {
945 .open = snd_ad1848_playback_open, 950 .open = snd_ad1848_playback_open,
946 .close = snd_ad1848_playback_close, 951 .close = snd_ad1848_playback_close,
@@ -988,12 +993,16 @@ int snd_ad1848_pcm(struct snd_ad1848 *chip, int device, struct snd_pcm **rpcm)
988 return 0; 993 return 0;
989} 994}
990 995
996EXPORT_SYMBOL(snd_ad1848_pcm);
997
991const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction) 998const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction)
992{ 999{
993 return direction == SNDRV_PCM_STREAM_PLAYBACK ? 1000 return direction == SNDRV_PCM_STREAM_PLAYBACK ?
994 &snd_ad1848_playback_ops : &snd_ad1848_capture_ops; 1001 &snd_ad1848_playback_ops : &snd_ad1848_capture_ops;
995} 1002}
996 1003
1004EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
1005
997/* 1006/*
998 * MIXER part 1007 * MIXER part
999 */ 1008 */
@@ -1171,7 +1180,8 @@ static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1171 1180
1172/* 1181/*
1173 */ 1182 */
1174int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int type, unsigned long value) 1183int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip,
1184 const struct ad1848_mix_elem *c)
1175{ 1185{
1176 static struct snd_kcontrol_new newctls[] = { 1186 static struct snd_kcontrol_new newctls[] = {
1177 [AD1848_MIX_SINGLE] = { 1187 [AD1848_MIX_SINGLE] = {
@@ -1196,32 +1206,46 @@ int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int
1196 struct snd_kcontrol *ctl; 1206 struct snd_kcontrol *ctl;
1197 int err; 1207 int err;
1198 1208
1199 ctl = snd_ctl_new1(&newctls[type], chip); 1209 ctl = snd_ctl_new1(&newctls[c->type], chip);
1200 if (! ctl) 1210 if (! ctl)
1201 return -ENOMEM; 1211 return -ENOMEM;
1202 strlcpy(ctl->id.name, name, sizeof(ctl->id.name)); 1212 strlcpy(ctl->id.name, c->name, sizeof(ctl->id.name));
1203 ctl->id.index = index; 1213 ctl->id.index = c->index;
1204 ctl->private_value = value; 1214 ctl->private_value = c->private_value;
1215 if (c->tlv) {
1216 ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1217 ctl->tlv.p = c->tlv;
1218 }
1205 if ((err = snd_ctl_add(chip->card, ctl)) < 0) 1219 if ((err = snd_ctl_add(chip->card, ctl)) < 0)
1206 return err; 1220 return err;
1207 return 0; 1221 return 0;
1208} 1222}
1209 1223
1224EXPORT_SYMBOL(snd_ad1848_add_ctl_elem);
1225
1226static DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
1227static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
1228static DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
1210 1229
1211static struct ad1848_mix_elem snd_ad1848_controls[] = { 1230static struct ad1848_mix_elem snd_ad1848_controls[] = {
1212AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), 1231AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1),
1213AD1848_DOUBLE("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1), 1232AD1848_DOUBLE_TLV("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1,
1233 db_scale_6bit),
1214AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 1234AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1215AD1848_DOUBLE("Aux Playback Volume", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1), 1235AD1848_DOUBLE_TLV("Aux Playback Volume", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
1236 db_scale_5bit_12db_max),
1216AD1848_DOUBLE("Aux Playback Switch", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 1237AD1848_DOUBLE("Aux Playback Switch", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1217AD1848_DOUBLE("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1), 1238AD1848_DOUBLE_TLV("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
1218AD1848_DOUBLE("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0), 1239 db_scale_5bit_12db_max),
1240AD1848_DOUBLE_TLV("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0,
1241 db_scale_rec_gain),
1219{ 1242{
1220 .name = "Capture Source", 1243 .name = "Capture Source",
1221 .type = AD1848_MIX_CAPTURE, 1244 .type = AD1848_MIX_CAPTURE,
1222}, 1245},
1223AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0), 1246AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0),
1224AD1848_SINGLE("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0) 1247AD1848_SINGLE_TLV("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0,
1248 db_scale_6bit),
1225}; 1249};
1226 1250
1227int snd_ad1848_mixer(struct snd_ad1848 *chip) 1251int snd_ad1848_mixer(struct snd_ad1848 *chip)
@@ -1245,12 +1269,7 @@ int snd_ad1848_mixer(struct snd_ad1848 *chip)
1245 return 0; 1269 return 0;
1246} 1270}
1247 1271
1248EXPORT_SYMBOL(snd_ad1848_out);
1249EXPORT_SYMBOL(snd_ad1848_create);
1250EXPORT_SYMBOL(snd_ad1848_pcm);
1251EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
1252EXPORT_SYMBOL(snd_ad1848_mixer); 1272EXPORT_SYMBOL(snd_ad1848_mixer);
1253EXPORT_SYMBOL(snd_ad1848_add_ctl);
1254 1273
1255/* 1274/*
1256 * INIT part 1275 * INIT part
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 34998de9968c..85818200333f 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -2038,7 +2038,80 @@ MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
2038static struct platform_device *platform_devices[SNDRV_CARDS]; 2038static struct platform_device *platform_devices[SNDRV_CARDS];
2039 2039
2040#ifdef CONFIG_PNP 2040#ifdef CONFIG_PNP
2041static int pnp_registered; 2041static int pnp_registered, pnpc_registered;
2042
2043static struct pnp_device_id snd_audiodrive_pnpbiosids[] = {
2044 { .id = "ESS1869" },
2045 { .id = "" } /* end */
2046};
2047
2048MODULE_DEVICE_TABLE(pnp, snd_audiodrive_pnpbiosids);
2049
2050/* PnP main device initialization */
2051static int __devinit snd_audiodrive_pnp_init_main(int dev, struct pnp_dev *pdev,
2052 struct pnp_resource_table *cfg)
2053{
2054 int err;
2055
2056 pnp_init_resource_table(cfg);
2057 if (port[dev] != SNDRV_AUTO_PORT)
2058 pnp_resource_change(&cfg->port_resource[0], port[dev], 16);
2059 if (fm_port[dev] != SNDRV_AUTO_PORT)
2060 pnp_resource_change(&cfg->port_resource[1], fm_port[dev], 4);
2061 if (mpu_port[dev] != SNDRV_AUTO_PORT)
2062 pnp_resource_change(&cfg->port_resource[2], mpu_port[dev], 2);
2063 if (dma1[dev] != SNDRV_AUTO_DMA)
2064 pnp_resource_change(&cfg->dma_resource[0], dma1[dev], 1);
2065 if (dma2[dev] != SNDRV_AUTO_DMA)
2066 pnp_resource_change(&cfg->dma_resource[1], dma2[dev], 1);
2067 if (irq[dev] != SNDRV_AUTO_IRQ)
2068 pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1);
2069 if (pnp_device_is_isapnp(pdev)) {
2070 err = pnp_manual_config_dev(pdev, cfg, 0);
2071 if (err < 0)
2072 snd_printk(KERN_ERR PFX "PnP manual resources are invalid, using auto config\n");
2073 }
2074 err = pnp_activate_dev(pdev);
2075 if (err < 0) {
2076 snd_printk(KERN_ERR PFX "PnP configure failure (out of resources?)\n");
2077 return -EBUSY;
2078 }
2079 /* ok. hack using Vendor-Defined Card-Level registers */
2080 /* skip csn and logdev initialization - already done in isapnp_configure */
2081 if (pnp_device_is_isapnp(pdev)) {
2082 isapnp_cfg_begin(isapnp_card_number(pdev), isapnp_csn_number(pdev));
2083 isapnp_write_byte(0x27, pnp_irq(pdev, 0)); /* Hardware Volume IRQ Number */
2084 if (mpu_port[dev] != SNDRV_AUTO_PORT)
2085 isapnp_write_byte(0x28, pnp_irq(pdev, 0)); /* MPU-401 IRQ Number */
2086 isapnp_write_byte(0x72, pnp_irq(pdev, 0)); /* second IRQ */
2087 isapnp_cfg_end();
2088 }
2089 port[dev] = pnp_port_start(pdev, 0);
2090 fm_port[dev] = pnp_port_start(pdev, 1);
2091 mpu_port[dev] = pnp_port_start(pdev, 2);
2092 dma1[dev] = pnp_dma(pdev, 0);
2093 dma2[dev] = pnp_dma(pdev, 1);
2094 irq[dev] = pnp_irq(pdev, 0);
2095 snd_printdd("PnP ES18xx: port=0x%lx, fm port=0x%lx, mpu port=0x%lx\n", port[dev], fm_port[dev], mpu_port[dev]);
2096 snd_printdd("PnP ES18xx: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]);
2097 return 0;
2098}
2099
2100static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard,
2101 struct pnp_dev *pdev)
2102{
2103 struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
2104
2105 if (!cfg)
2106 return -ENOMEM;
2107 acard->dev = pdev;
2108 if (snd_audiodrive_pnp_init_main(dev, acard->dev, cfg) < 0) {
2109 kfree(cfg);
2110 return -EBUSY;
2111 }
2112 kfree(cfg);
2113 return 0;
2114}
2042 2115
2043static struct pnp_card_device_id snd_audiodrive_pnpids[] = { 2116static struct pnp_card_device_id snd_audiodrive_pnpids[] = {
2044 /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */ 2117 /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */
@@ -2061,13 +2134,11 @@ static struct pnp_card_device_id snd_audiodrive_pnpids[] = {
2061 2134
2062MODULE_DEVICE_TABLE(pnp_card, snd_audiodrive_pnpids); 2135MODULE_DEVICE_TABLE(pnp_card, snd_audiodrive_pnpids);
2063 2136
2064static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard, 2137static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard,
2065 struct pnp_card_link *card, 2138 struct pnp_card_link *card,
2066 const struct pnp_card_device_id *id) 2139 const struct pnp_card_device_id *id)
2067{ 2140{
2068 struct pnp_dev *pdev;
2069 struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); 2141 struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
2070 int err;
2071 2142
2072 if (!cfg) 2143 if (!cfg)
2073 return -ENOMEM; 2144 return -ENOMEM;
@@ -2082,58 +2153,16 @@ static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard,
2082 return -EBUSY; 2153 return -EBUSY;
2083 } 2154 }
2084 /* Control port initialization */ 2155 /* Control port initialization */
2085 err = pnp_activate_dev(acard->devc); 2156 if (pnp_activate_dev(acard->devc) < 0) {
2086 if (err < 0) {
2087 snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n"); 2157 snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
2088 kfree(cfg);
2089 return -EAGAIN; 2158 return -EAGAIN;
2090 } 2159 }
2091 snd_printdd("pnp: port=0x%llx\n", 2160 snd_printdd("pnp: port=0x%llx\n",
2092 (unsigned long long)pnp_port_start(acard->devc, 0)); 2161 (unsigned long long)pnp_port_start(acard->devc, 0));
2093 /* PnP initialization */ 2162 if (snd_audiodrive_pnp_init_main(dev, acard->dev, cfg) < 0) {
2094 pdev = acard->dev;
2095 pnp_init_resource_table(cfg);
2096 if (port[dev] != SNDRV_AUTO_PORT)
2097 pnp_resource_change(&cfg->port_resource[0], port[dev], 16);
2098 if (fm_port[dev] != SNDRV_AUTO_PORT)
2099 pnp_resource_change(&cfg->port_resource[1], fm_port[dev], 4);
2100 if (mpu_port[dev] != SNDRV_AUTO_PORT)
2101 pnp_resource_change(&cfg->port_resource[2], mpu_port[dev], 2);
2102 if (dma1[dev] != SNDRV_AUTO_DMA)
2103 pnp_resource_change(&cfg->dma_resource[0], dma1[dev], 1);
2104 if (dma2[dev] != SNDRV_AUTO_DMA)
2105 pnp_resource_change(&cfg->dma_resource[1], dma2[dev], 1);
2106 if (irq[dev] != SNDRV_AUTO_IRQ)
2107 pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1);
2108 err = pnp_manual_config_dev(pdev, cfg, 0);
2109 if (err < 0)
2110 snd_printk(KERN_ERR PFX "PnP manual resources are invalid, using auto config\n");
2111 err = pnp_activate_dev(pdev);
2112 if (err < 0) {
2113 snd_printk(KERN_ERR PFX "PnP configure failure (out of resources?)\n");
2114 kfree(cfg); 2163 kfree(cfg);
2115 return -EBUSY; 2164 return -EBUSY;
2116 } 2165 }
2117 /* ok. hack using Vendor-Defined Card-Level registers */
2118 /* skip csn and logdev initialization - already done in isapnp_configure */
2119 if (pnp_device_is_isapnp(pdev)) {
2120 isapnp_cfg_begin(isapnp_card_number(pdev), isapnp_csn_number(pdev));
2121 isapnp_write_byte(0x27, pnp_irq(pdev, 0)); /* Hardware Volume IRQ Number */
2122 if (mpu_port[dev] != SNDRV_AUTO_PORT)
2123 isapnp_write_byte(0x28, pnp_irq(pdev, 0)); /* MPU-401 IRQ Number */
2124 isapnp_write_byte(0x72, pnp_irq(pdev, 0)); /* second IRQ */
2125 isapnp_cfg_end();
2126 } else {
2127 snd_printk(KERN_ERR PFX "unable to install ISA PnP hack, expect malfunction\n");
2128 }
2129 port[dev] = pnp_port_start(pdev, 0);
2130 fm_port[dev] = pnp_port_start(pdev, 1);
2131 mpu_port[dev] = pnp_port_start(pdev, 2);
2132 dma1[dev] = pnp_dma(pdev, 0);
2133 dma2[dev] = pnp_dma(pdev, 1);
2134 irq[dev] = pnp_irq(pdev, 0);
2135 snd_printdd("PnP ES18xx: port=0x%lx, fm port=0x%lx, mpu port=0x%lx\n", port[dev], fm_port[dev], mpu_port[dev]);
2136 snd_printdd("PnP ES18xx: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]);
2137 kfree(cfg); 2166 kfree(cfg);
2138 return 0; 2167 return 0;
2139} 2168}
@@ -2302,7 +2331,69 @@ static struct platform_driver snd_es18xx_nonpnp_driver = {
2302#ifdef CONFIG_PNP 2331#ifdef CONFIG_PNP
2303static unsigned int __devinitdata es18xx_pnp_devices; 2332static unsigned int __devinitdata es18xx_pnp_devices;
2304 2333
2305static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard, 2334static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
2335 const struct pnp_device_id *id)
2336{
2337 static int dev;
2338 int err;
2339 struct snd_card *card;
2340
2341 if (pnp_device_is_isapnp(pdev))
2342 return -ENOENT; /* we have another procedure - card */
2343 for (; dev < SNDRV_CARDS; dev++) {
2344 if (enable[dev] && isapnp[dev])
2345 break;
2346 }
2347 if (dev >= SNDRV_CARDS)
2348 return -ENODEV;
2349
2350 card = snd_es18xx_card_new(dev);
2351 if (! card)
2352 return -ENOMEM;
2353 if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) {
2354 snd_card_free(card);
2355 return err;
2356 }
2357 snd_card_set_dev(card, &pdev->dev);
2358 if ((err = snd_audiodrive_probe(card, dev)) < 0) {
2359 snd_card_free(card);
2360 return err;
2361 }
2362 pnp_set_drvdata(pdev, card);
2363 dev++;
2364 es18xx_pnp_devices++;
2365 return 0;
2366}
2367
2368static void __devexit snd_audiodrive_pnp_remove(struct pnp_dev * pdev)
2369{
2370 snd_card_free(pnp_get_drvdata(pdev));
2371 pnp_set_drvdata(pdev, NULL);
2372}
2373
2374#ifdef CONFIG_PM
2375static int snd_audiodrive_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
2376{
2377 return snd_es18xx_suspend(pnp_get_drvdata(pdev), state);
2378}
2379static int snd_audiodrive_pnp_resume(struct pnp_dev *pdev)
2380{
2381 return snd_es18xx_resume(pnp_get_drvdata(pdev));
2382}
2383#endif
2384
2385static struct pnp_driver es18xx_pnp_driver = {
2386 .name = "es18xx-pnpbios",
2387 .id_table = snd_audiodrive_pnpbiosids,
2388 .probe = snd_audiodrive_pnp_detect,
2389 .remove = __devexit_p(snd_audiodrive_pnp_remove),
2390#ifdef CONFIG_PM
2391 .suspend = snd_audiodrive_pnp_suspend,
2392 .resume = snd_audiodrive_pnp_resume,
2393#endif
2394};
2395
2396static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
2306 const struct pnp_card_device_id *pid) 2397 const struct pnp_card_device_id *pid)
2307{ 2398{
2308 static int dev; 2399 static int dev;
@@ -2320,7 +2411,7 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard,
2320 if (! card) 2411 if (! card)
2321 return -ENOMEM; 2412 return -ENOMEM;
2322 2413
2323 if ((res = snd_audiodrive_pnp(dev, card->private_data, pcard, pid)) < 0) { 2414 if ((res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid)) < 0) {
2324 snd_card_free(card); 2415 snd_card_free(card);
2325 return res; 2416 return res;
2326 } 2417 }
@@ -2336,19 +2427,19 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard,
2336 return 0; 2427 return 0;
2337} 2428}
2338 2429
2339static void __devexit snd_audiodrive_pnp_remove(struct pnp_card_link * pcard) 2430static void __devexit snd_audiodrive_pnpc_remove(struct pnp_card_link * pcard)
2340{ 2431{
2341 snd_card_free(pnp_get_card_drvdata(pcard)); 2432 snd_card_free(pnp_get_card_drvdata(pcard));
2342 pnp_set_card_drvdata(pcard, NULL); 2433 pnp_set_card_drvdata(pcard, NULL);
2343} 2434}
2344 2435
2345#ifdef CONFIG_PM 2436#ifdef CONFIG_PM
2346static int snd_audiodrive_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state) 2437static int snd_audiodrive_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state)
2347{ 2438{
2348 return snd_es18xx_suspend(pnp_get_card_drvdata(pcard), state); 2439 return snd_es18xx_suspend(pnp_get_card_drvdata(pcard), state);
2349} 2440}
2350 2441
2351static int snd_audiodrive_pnp_resume(struct pnp_card_link *pcard) 2442static int snd_audiodrive_pnpc_resume(struct pnp_card_link *pcard)
2352{ 2443{
2353 return snd_es18xx_resume(pnp_get_card_drvdata(pcard)); 2444 return snd_es18xx_resume(pnp_get_card_drvdata(pcard));
2354} 2445}
@@ -2359,11 +2450,11 @@ static struct pnp_card_driver es18xx_pnpc_driver = {
2359 .flags = PNP_DRIVER_RES_DISABLE, 2450 .flags = PNP_DRIVER_RES_DISABLE,
2360 .name = "es18xx", 2451 .name = "es18xx",
2361 .id_table = snd_audiodrive_pnpids, 2452 .id_table = snd_audiodrive_pnpids,
2362 .probe = snd_audiodrive_pnp_detect, 2453 .probe = snd_audiodrive_pnpc_detect,
2363 .remove = __devexit_p(snd_audiodrive_pnp_remove), 2454 .remove = __devexit_p(snd_audiodrive_pnpc_remove),
2364#ifdef CONFIG_PM 2455#ifdef CONFIG_PM
2365 .suspend = snd_audiodrive_pnp_suspend, 2456 .suspend = snd_audiodrive_pnpc_suspend,
2366 .resume = snd_audiodrive_pnp_resume, 2457 .resume = snd_audiodrive_pnpc_resume,
2367#endif 2458#endif
2368}; 2459};
2369#endif /* CONFIG_PNP */ 2460#endif /* CONFIG_PNP */
@@ -2373,8 +2464,10 @@ static void __init_or_module snd_es18xx_unregister_all(void)
2373 int i; 2464 int i;
2374 2465
2375#ifdef CONFIG_PNP 2466#ifdef CONFIG_PNP
2376 if (pnp_registered) 2467 if (pnpc_registered)
2377 pnp_unregister_card_driver(&es18xx_pnpc_driver); 2468 pnp_unregister_card_driver(&es18xx_pnpc_driver);
2469 if (pnp_registered)
2470 pnp_unregister_driver(&es18xx_pnp_driver);
2378#endif 2471#endif
2379 for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) 2472 for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
2380 platform_device_unregister(platform_devices[i]); 2473 platform_device_unregister(platform_devices[i]);
@@ -2405,11 +2498,13 @@ static int __init alsa_card_es18xx_init(void)
2405 } 2498 }
2406 2499
2407#ifdef CONFIG_PNP 2500#ifdef CONFIG_PNP
2408 err = pnp_register_card_driver(&es18xx_pnpc_driver); 2501 err = pnp_register_driver(&es18xx_pnp_driver);
2409 if (!err) { 2502 if (!err)
2410 pnp_registered = 1; 2503 pnp_registered = 1;
2411 cards += es18xx_pnp_devices; 2504 err = pnp_register_card_driver(&es18xx_pnpc_driver);
2412 } 2505 if (!err)
2506 pnpc_registered = 1;
2507 cards += es18xx_pnp_devices;
2413#endif 2508#endif
2414 2509
2415 if(!cards) { 2510 if(!cards) {
diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
index 4080255007d5..80f0a83818b2 100644
--- a/sound/isa/gus/gus_mem_proc.c
+++ b/sound/isa/gus/gus_mem_proc.c
@@ -61,13 +61,13 @@ static long long snd_gf1_mem_proc_llseek(struct snd_info_entry *entry,
61 struct gus_proc_private *priv = entry->private_data; 61 struct gus_proc_private *priv = entry->private_data;
62 62
63 switch (orig) { 63 switch (orig) {
64 case 0: /* SEEK_SET */ 64 case SEEK_SET:
65 file->f_pos = offset; 65 file->f_pos = offset;
66 break; 66 break;
67 case 1: /* SEEK_CUR */ 67 case SEEK_CUR:
68 file->f_pos += offset; 68 file->f_pos += offset;
69 break; 69 break;
70 case 2: /* SEEK_END, offset is negative */ 70 case SEEK_END: /* offset is negative */
71 file->f_pos = priv->size + offset; 71 file->f_pos = priv->size + offset;
72 break; 72 break;
73 default: 73 default:
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 4031b61b797f..da92bf6c392b 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -33,6 +33,7 @@
33#include <sound/mpu401.h> 33#include <sound/mpu401.h>
34#include <sound/opl3.h> 34#include <sound/opl3.h>
35#include <sound/initval.h> 35#include <sound/initval.h>
36#include <sound/tlv.h>
36 37
37#include <asm/io.h> 38#include <asm/io.h>
38 39
@@ -337,6 +338,14 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id, struct pt_regs *
337 .info = snd_opl3sa2_info_single, \ 338 .info = snd_opl3sa2_info_single, \
338 .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \ 339 .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \
339 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } 340 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
341#define OPL3SA2_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
342{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
343 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
344 .name = xname, .index = xindex, \
345 .info = snd_opl3sa2_info_single, \
346 .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \
347 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
348 .tlv = { .p = (xtlv) } }
340 349
341static int snd_opl3sa2_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 350static int snd_opl3sa2_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
342{ 351{
@@ -395,6 +404,14 @@ static int snd_opl3sa2_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_
395 .info = snd_opl3sa2_info_double, \ 404 .info = snd_opl3sa2_info_double, \
396 .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \ 405 .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
397 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } 406 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
407#define OPL3SA2_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \
408{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
409 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
410 .name = xname, .index = xindex, \
411 .info = snd_opl3sa2_info_double, \
412 .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
413 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22), \
414 .tlv = { .p = (xtlv) } }
398 415
399static int snd_opl3sa2_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 416static int snd_opl3sa2_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
400{ 417{
@@ -469,11 +486,16 @@ static int snd_opl3sa2_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
469 return change; 486 return change;
470} 487}
471 488
489static DECLARE_TLV_DB_SCALE(db_scale_master, -3000, 200, 0);
490static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
491
472static struct snd_kcontrol_new snd_opl3sa2_controls[] = { 492static struct snd_kcontrol_new snd_opl3sa2_controls[] = {
473OPL3SA2_DOUBLE("Master Playback Switch", 0, 0x07, 0x08, 7, 7, 1, 1), 493OPL3SA2_DOUBLE("Master Playback Switch", 0, 0x07, 0x08, 7, 7, 1, 1),
474OPL3SA2_DOUBLE("Master Playback Volume", 0, 0x07, 0x08, 0, 0, 15, 1), 494OPL3SA2_DOUBLE_TLV("Master Playback Volume", 0, 0x07, 0x08, 0, 0, 15, 1,
495 db_scale_master),
475OPL3SA2_SINGLE("Mic Playback Switch", 0, 0x09, 7, 1, 1), 496OPL3SA2_SINGLE("Mic Playback Switch", 0, 0x09, 7, 1, 1),
476OPL3SA2_SINGLE("Mic Playback Volume", 0, 0x09, 0, 31, 1) 497OPL3SA2_SINGLE_TLV("Mic Playback Volume", 0, 0x09, 0, 31, 1,
498 db_scale_5bit_12db_max),
477}; 499};
478 500
479static struct snd_kcontrol_new snd_opl3sa2_tone_controls[] = { 501static struct snd_kcontrol_new snd_opl3sa2_tone_controls[] = {