diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-08-22 07:16:25 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-09-23 04:43:28 -0400 |
commit | eac06a10d2b814dfacc36a8fff35ef07bf4eec8e (patch) | |
tree | b58b442323d539ae6edaebede6643f49213e4978 | |
parent | 0e7febf15851fb438b9518654340d1f704d202e5 (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.h | 22 | ||||
-rw-r--r-- | sound/isa/ad1848/ad1848_lib.c | 49 |
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 | ||
182 | int 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 */ |
185 | struct ad1848_mix_elem { | 183 | struct 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 | ||
204 | static 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 | |||
217 | int 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 | ||
122 | EXPORT_SYMBOL(snd_ad1848_out); | ||
123 | |||
121 | static void snd_ad1848_dout(struct snd_ad1848 *chip, | 124 | static 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 | ||
947 | EXPORT_SYMBOL(snd_ad1848_create); | ||
948 | |||
944 | static struct snd_pcm_ops snd_ad1848_playback_ops = { | 949 | static 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 | ||
996 | EXPORT_SYMBOL(snd_ad1848_pcm); | ||
997 | |||
991 | const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction) | 998 | const 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 | ||
1004 | EXPORT_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 | */ |
1174 | int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int type, unsigned long value) | 1183 | int 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 | ||
1224 | EXPORT_SYMBOL(snd_ad1848_add_ctl_elem); | ||
1225 | |||
1226 | static DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); | ||
1227 | static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); | ||
1228 | static DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); | ||
1210 | 1229 | ||
1211 | static struct ad1848_mix_elem snd_ad1848_controls[] = { | 1230 | static struct ad1848_mix_elem snd_ad1848_controls[] = { |
1212 | AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), | 1231 | AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), |
1213 | AD1848_DOUBLE("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1), | 1232 | AD1848_DOUBLE_TLV("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1, |
1233 | db_scale_6bit), | ||
1214 | AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1), | 1234 | AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1), |
1215 | AD1848_DOUBLE("Aux Playback Volume", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1), | 1235 | AD1848_DOUBLE_TLV("Aux Playback Volume", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1, |
1236 | db_scale_5bit_12db_max), | ||
1216 | AD1848_DOUBLE("Aux Playback Switch", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1), | 1237 | AD1848_DOUBLE("Aux Playback Switch", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1), |
1217 | AD1848_DOUBLE("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1), | 1238 | AD1848_DOUBLE_TLV("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1, |
1218 | AD1848_DOUBLE("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0), | 1239 | db_scale_5bit_12db_max), |
1240 | AD1848_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 | }, |
1223 | AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0), | 1246 | AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0), |
1224 | AD1848_SINGLE("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0) | 1247 | AD1848_SINGLE_TLV("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0, |
1248 | db_scale_6bit), | ||
1225 | }; | 1249 | }; |
1226 | 1250 | ||
1227 | int snd_ad1848_mixer(struct snd_ad1848 *chip) | 1251 | int 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 | ||
1248 | EXPORT_SYMBOL(snd_ad1848_out); | ||
1249 | EXPORT_SYMBOL(snd_ad1848_create); | ||
1250 | EXPORT_SYMBOL(snd_ad1848_pcm); | ||
1251 | EXPORT_SYMBOL(snd_ad1848_get_pcm_ops); | ||
1252 | EXPORT_SYMBOL(snd_ad1848_mixer); | 1272 | EXPORT_SYMBOL(snd_ad1848_mixer); |
1253 | EXPORT_SYMBOL(snd_ad1848_add_ctl); | ||
1254 | 1273 | ||
1255 | /* | 1274 | /* |
1256 | * INIT part | 1275 | * INIT part |