aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-08-22 07:16:25 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:43:28 -0400
commiteac06a10d2b814dfacc36a8fff35ef07bf4eec8e (patch)
treeb58b442323d539ae6edaebede6643f49213e4978
parent0e7febf15851fb438b9518654340d1f704d202e5 (diff)
[ALSA] Add dB scale information to ad1848 driver
Added the dB scale information to ad1848 driver. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r--include/sound/ad1848.h22
-rw-r--r--sound/isa/ad1848/ad1848_lib.c49
2 files changed, 50 insertions, 21 deletions
diff --git a/include/sound/ad1848.h b/include/sound/ad1848.h
index 57af1fe7b309..c8de6f83338f 100644
--- a/include/sound/ad1848.h
+++ b/include/sound/ad1848.h
@@ -179,14 +179,13 @@ enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE };
179#define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \ 179#define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \
180 ((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22)) 180 ((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22))
181 181
182int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int type, unsigned long value);
183
184/* for ease of use */ 182/* for ease of use */
185struct ad1848_mix_elem { 183struct ad1848_mix_elem {
186 const char *name; 184 const char *name;
187 int index; 185 int index;
188 int type; 186 int type;
189 unsigned long private_value; 187 unsigned long private_value;
188 unsigned int *tlv;
190}; 189};
191 190
192#define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \ 191#define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \
@@ -195,15 +194,26 @@ struct ad1848_mix_elem {
195 .type = AD1848_MIX_SINGLE, \ 194 .type = AD1848_MIX_SINGLE, \
196 .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) } 195 .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) }
197 196
197#define AD1848_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
198{ .name = xname, \
199 .index = xindex, \
200 .type = AD1848_MIX_SINGLE, \
201 .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert), \
202 .tlv = xtlv }
203
198#define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ 204#define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
199{ .name = xname, \ 205{ .name = xname, \
200 .index = xindex, \ 206 .index = xindex, \
201 .type = AD1848_MIX_DOUBLE, \ 207 .type = AD1848_MIX_DOUBLE, \
202 .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) } 208 .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) }
203 209
204static inline int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip, const struct ad1848_mix_elem *c) 210#define AD1848_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \
205{ 211{ .name = xname, \
206 return snd_ad1848_add_ctl(chip, c->name, c->index, c->type, c->private_value); 212 .index = xindex, \
207} 213 .type = AD1848_MIX_DOUBLE, \
214 .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert), \
215 .tlv = xtlv }
216
217int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip, const struct ad1848_mix_elem *c);
208 218
209#endif /* __SOUND_AD1848_H */ 219#endif /* __SOUND_AD1848_H */
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