diff options
Diffstat (limited to 'sound/i2c')
-rw-r--r-- | sound/i2c/l3/uda1341.c | 170 |
1 files changed, 135 insertions, 35 deletions
diff --git a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c index 103a7dcd0dde..bc7eb23e615f 100644 --- a/sound/i2c/l3/uda1341.c +++ b/sound/i2c/l3/uda1341.c | |||
@@ -17,7 +17,7 @@ | |||
17 | * 2002-05-12 Tomas Kasparek another code cleanup | 17 | * 2002-05-12 Tomas Kasparek another code cleanup |
18 | */ | 18 | */ |
19 | 19 | ||
20 | /* $Id: uda1341.c,v 1.16 2005/09/09 13:22:34 tiwai Exp $ */ | 20 | /* $Id: uda1341.c,v 1.17 2005/11/17 10:25:22 tiwai Exp $ */ |
21 | 21 | ||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
@@ -56,6 +56,33 @@ | |||
56 | 56 | ||
57 | /* }}} */ | 57 | /* }}} */ |
58 | 58 | ||
59 | |||
60 | static const char *peak_names[] = { | ||
61 | "before", | ||
62 | "after", | ||
63 | }; | ||
64 | |||
65 | static const char *filter_names[] = { | ||
66 | "flat", | ||
67 | "min", | ||
68 | "min", | ||
69 | "max", | ||
70 | }; | ||
71 | |||
72 | static const char *mixer_names[] = { | ||
73 | "double differential", | ||
74 | "input channel 1 (line in)", | ||
75 | "input channel 2 (microphone)", | ||
76 | "digital mixer", | ||
77 | }; | ||
78 | |||
79 | static const char *deemp_names[] = { | ||
80 | "none", | ||
81 | "32 kHz", | ||
82 | "44.1 kHz", | ||
83 | "48 kHz", | ||
84 | }; | ||
85 | |||
59 | enum uda1341_regs_names { | 86 | enum uda1341_regs_names { |
60 | stat0, | 87 | stat0, |
61 | stat1, | 88 | stat1, |
@@ -73,7 +100,7 @@ enum uda1341_regs_names { | |||
73 | uda1341_reg_last, | 100 | uda1341_reg_last, |
74 | }; | 101 | }; |
75 | 102 | ||
76 | const char *uda1341_reg_names[] = { | 103 | static const char *uda1341_reg_names[] = { |
77 | "stat 0 ", | 104 | "stat 0 ", |
78 | "stat 1 ", | 105 | "stat 1 ", |
79 | "data 00", | 106 | "data 00", |
@@ -89,7 +116,7 @@ const char *uda1341_reg_names[] = { | |||
89 | "ext 6", | 116 | "ext 6", |
90 | }; | 117 | }; |
91 | 118 | ||
92 | const int uda1341_enum_items[] = { | 119 | static const int uda1341_enum_items[] = { |
93 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 120 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
94 | 2, //peak - before/after | 121 | 2, //peak - before/after |
95 | 4, //deemp - none/32/44.1/48 | 122 | 4, //deemp - none/32/44.1/48 |
@@ -100,7 +127,7 @@ const int uda1341_enum_items[] = { | |||
100 | 0, 0, 0, 0, 0, | 127 | 0, 0, 0, 0, 0, |
101 | }; | 128 | }; |
102 | 129 | ||
103 | const char ** uda1341_enum_names[] = { | 130 | static const char ** uda1341_enum_names[] = { |
104 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 131 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
105 | peak_names, //peak - before/after | 132 | peak_names, //peak - before/after |
106 | deemp_names, //deemp - none/32/44.1/48 | 133 | deemp_names, //deemp - none/32/44.1/48 |
@@ -129,11 +156,9 @@ struct uda1341 { | |||
129 | #endif | 156 | #endif |
130 | }; | 157 | }; |
131 | 158 | ||
132 | //hack for ALSA magic casting | ||
133 | typedef struct l3_client l3_client_t; | ||
134 | |||
135 | /* transfer 8bit integer into string with binary representation */ | 159 | /* transfer 8bit integer into string with binary representation */ |
136 | void int2str_bin8(uint8_t val, char *buf){ | 160 | static void int2str_bin8(uint8_t val, char *buf) |
161 | { | ||
137 | const int size = sizeof(val) * 8; | 162 | const int size = sizeof(val) * 8; |
138 | int i; | 163 | int i; |
139 | 164 | ||
@@ -146,7 +171,7 @@ void int2str_bin8(uint8_t val, char *buf){ | |||
146 | 171 | ||
147 | /* {{{ HW manipulation routines */ | 172 | /* {{{ HW manipulation routines */ |
148 | 173 | ||
149 | int snd_uda1341_codec_write(struct l3_client *clnt, unsigned short reg, unsigned short val) | 174 | static int snd_uda1341_codec_write(struct l3_client *clnt, unsigned short reg, unsigned short val) |
150 | { | 175 | { |
151 | struct uda1341 *uda = clnt->driver_data; | 176 | struct uda1341 *uda = clnt->driver_data; |
152 | unsigned char buf[2] = { 0xc0, 0xe0 }; // for EXT addressing | 177 | unsigned char buf[2] = { 0xc0, 0xe0 }; // for EXT addressing |
@@ -171,7 +196,7 @@ int snd_uda1341_codec_write(struct l3_client *clnt, unsigned short reg, unsigned | |||
171 | return err; | 196 | return err; |
172 | } | 197 | } |
173 | 198 | ||
174 | int snd_uda1341_codec_read(struct l3_client *clnt, unsigned short reg) | 199 | static int snd_uda1341_codec_read(struct l3_client *clnt, unsigned short reg) |
175 | { | 200 | { |
176 | unsigned char val; | 201 | unsigned char val; |
177 | int err; | 202 | int err; |
@@ -188,8 +213,9 @@ static inline int snd_uda1341_valid_reg(struct l3_client *clnt, unsigned short r | |||
188 | return reg < uda1341_reg_last; | 213 | return reg < uda1341_reg_last; |
189 | } | 214 | } |
190 | 215 | ||
191 | int snd_uda1341_update_bits(struct l3_client *clnt, unsigned short reg, unsigned short mask, | 216 | static int snd_uda1341_update_bits(struct l3_client *clnt, unsigned short reg, |
192 | unsigned short shift, unsigned short value, int flush) | 217 | unsigned short mask, unsigned short shift, |
218 | unsigned short value, int flush) | ||
193 | { | 219 | { |
194 | int change; | 220 | int change; |
195 | unsigned short old, new; | 221 | unsigned short old, new; |
@@ -214,8 +240,8 @@ int snd_uda1341_update_bits(struct l3_client *clnt, unsigned short reg, unsigned | |||
214 | return change; | 240 | return change; |
215 | } | 241 | } |
216 | 242 | ||
217 | int snd_uda1341_cfg_write(struct l3_client *clnt, unsigned short what, | 243 | static int snd_uda1341_cfg_write(struct l3_client *clnt, unsigned short what, |
218 | unsigned short value, int flush) | 244 | unsigned short value, int flush) |
219 | { | 245 | { |
220 | struct uda1341 *uda = clnt->driver_data; | 246 | struct uda1341 *uda = clnt->driver_data; |
221 | int ret = 0; | 247 | int ret = 0; |
@@ -327,6 +353,81 @@ int snd_uda1341_cfg_write(struct l3_client *clnt, unsigned short what, | |||
327 | /* }}} */ | 353 | /* }}} */ |
328 | 354 | ||
329 | /* {{{ Proc interface */ | 355 | /* {{{ Proc interface */ |
356 | #ifdef CONFIG_PROC_FS | ||
357 | |||
358 | static const char *format_names[] = { | ||
359 | "I2S-bus", | ||
360 | "LSB 16bits", | ||
361 | "LSB 18bits", | ||
362 | "LSB 20bits", | ||
363 | "MSB", | ||
364 | "in LSB 16bits/out MSB", | ||
365 | "in LSB 18bits/out MSB", | ||
366 | "in LSB 20bits/out MSB", | ||
367 | }; | ||
368 | |||
369 | static const char *fs_names[] = { | ||
370 | "512*fs", | ||
371 | "384*fs", | ||
372 | "256*fs", | ||
373 | "Unused - bad value!", | ||
374 | }; | ||
375 | |||
376 | static const char* bass_values[][16] = { | ||
377 | {"0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", | ||
378 | "0 dB", "0 dB", "0 dB", "0 dB", "undefined", }, //flat | ||
379 | {"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB", | ||
380 | "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min | ||
381 | {"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB", | ||
382 | "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min | ||
383 | {"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "20 dB", | ||
384 | "22 dB", "24 dB", "24 dB", "24 dB", "undefined",}, // max | ||
385 | }; | ||
386 | |||
387 | static const char *mic_sens_value[] = { | ||
388 | "-3 dB", "0 dB", "3 dB", "9 dB", "15 dB", "21 dB", "27 dB", "not used", | ||
389 | }; | ||
390 | |||
391 | static const unsigned short AGC_atime[] = { | ||
392 | 11, 16, 11, 16, 21, 11, 16, 21, | ||
393 | }; | ||
394 | |||
395 | static const unsigned short AGC_dtime[] = { | ||
396 | 100, 100, 200, 200, 200, 400, 400, 400, | ||
397 | }; | ||
398 | |||
399 | static const char *AGC_level[] = { | ||
400 | "-9.0", "-11.5", "-15.0", "-17.5", | ||
401 | }; | ||
402 | |||
403 | static const char *ig_small_value[] = { | ||
404 | "-3.0", "-2.5", "-2.0", "-1.5", "-1.0", "-0.5", | ||
405 | }; | ||
406 | |||
407 | /* | ||
408 | * this was computed as peak_value[i] = pow((63-i)*1.42,1.013) | ||
409 | * | ||
410 | * UDA1341 datasheet on page 21: Peak value (dB) = (Peak level - 63.5)*5*log2 | ||
411 | * There is an table with these values [level]=value: [3]=-90.31, [7]=-84.29 | ||
412 | * [61]=-2.78, [62] = -1.48, [63] = 0.0 | ||
413 | * I tried to compute it, but using but even using logarithm with base either 10 or 2 | ||
414 | * i was'n able to get values in the table from the formula. So I constructed another | ||
415 | * formula (see above) to interpolate the values as good as possible. If there is some | ||
416 | * mistake, please contact me on tomas.kasparek@seznam.cz. Thanks. | ||
417 | * UDA1341TS datasheet is available at: | ||
418 | * http://www-us9.semiconductors.com/acrobat/datasheets/UDA1341TS_3.pdf | ||
419 | */ | ||
420 | static const char *peak_value[] = { | ||
421 | "-INF dB", "N.A.", "N.A", "90.31 dB", "N.A.", "N.A.", "N.A.", "-84.29 dB", | ||
422 | "-82.65 dB", "-81.13 dB", "-79.61 dB", "-78.09 dB", "-76.57 dB", "-75.05 dB", "-73.53 dB", | ||
423 | "-72.01 dB", "-70.49 dB", "-68.97 dB", "-67.45 dB", "-65.93 dB", "-64.41 dB", "-62.90 dB", | ||
424 | "-61.38 dB", "-59.86 dB", "-58.35 dB", "-56.83 dB", "-55.32 dB", "-53.80 dB", "-52.29 dB", | ||
425 | "-50.78 dB", "-49.26 dB", "-47.75 dB", "-46.24 dB", "-44.73 dB", "-43.22 dB", "-41.71 dB", | ||
426 | "-40.20 dB", "-38.69 dB", "-37.19 dB", "-35.68 dB", "-34.17 dB", "-32.67 dB", "-31.17 dB", | ||
427 | "-29.66 dB", "-28.16 dB", "-26.66 dB", "-25.16 dB", "-23.66 dB", "-22.16 dB", "-20.67 dB", | ||
428 | "-19.17 dB", "-17.68 dB", "-16.19 dB", "-14.70 dB", "-13.21 dB", "-11.72 dB", "-10.24 dB", | ||
429 | "-8.76 dB", "-7.28 dB", "-5.81 dB", "-4.34 dB", "-2.88 dB", "-1.43 dB", "0.00 dB", | ||
430 | }; | ||
330 | 431 | ||
331 | static void snd_uda1341_proc_read(snd_info_entry_t *entry, | 432 | static void snd_uda1341_proc_read(snd_info_entry_t *entry, |
332 | snd_info_buffer_t * buffer) | 433 | snd_info_buffer_t * buffer) |
@@ -401,7 +502,6 @@ static void snd_uda1341_proc_regs_read(snd_info_entry_t *entry, | |||
401 | int reg; | 502 | int reg; |
402 | char buf[12]; | 503 | char buf[12]; |
403 | 504 | ||
404 | spin_lock(&uda->reg_lock); | ||
405 | for (reg = 0; reg < uda1341_reg_last; reg ++) { | 505 | for (reg = 0; reg < uda1341_reg_last; reg ++) { |
406 | if (reg == empty) | 506 | if (reg == empty) |
407 | continue; | 507 | continue; |
@@ -411,9 +511,8 @@ static void snd_uda1341_proc_regs_read(snd_info_entry_t *entry, | |||
411 | 511 | ||
412 | int2str_bin8(snd_uda1341_codec_read(clnt, UDA1341_DATA1), buf); | 512 | int2str_bin8(snd_uda1341_codec_read(clnt, UDA1341_DATA1), buf); |
413 | snd_iprintf(buffer, "DATA1 = %s\n", buf); | 513 | snd_iprintf(buffer, "DATA1 = %s\n", buf); |
414 | |||
415 | spin_unlock(&uda->reg_lock); | ||
416 | } | 514 | } |
515 | #endif /* CONFIG_PROC_FS */ | ||
417 | 516 | ||
418 | static void __devinit snd_uda1341_proc_init(snd_card_t *card, struct l3_client *clnt) | 517 | static void __devinit snd_uda1341_proc_init(snd_card_t *card, struct l3_client *clnt) |
419 | { | 518 | { |
@@ -647,10 +746,10 @@ static snd_kcontrol_new_t snd_uda1341_controls[] = { | |||
647 | UDA1341_2REGS("Gain Input Amplifier Gain (channel 2)", CMD_IG, ext4, ext5, 0, 0, 3, 31, 0), | 746 | UDA1341_2REGS("Gain Input Amplifier Gain (channel 2)", CMD_IG, ext4, ext5, 0, 0, 3, 31, 0), |
648 | }; | 747 | }; |
649 | 748 | ||
650 | static void uda1341_free(struct l3_client *uda1341) | 749 | static void uda1341_free(struct l3_client *clnt) |
651 | { | 750 | { |
652 | l3_detach_client(uda1341); // calls kfree for driver_data (uda1341_t) | 751 | l3_detach_client(clnt); // calls kfree for driver_data (uda1341_t) |
653 | kfree(uda1341); | 752 | kfree(clnt); |
654 | } | 753 | } |
655 | 754 | ||
656 | static int uda1341_dev_free(snd_device_t *device) | 755 | static int uda1341_dev_free(snd_device_t *device) |
@@ -660,41 +759,42 @@ static int uda1341_dev_free(snd_device_t *device) | |||
660 | return 0; | 759 | return 0; |
661 | } | 760 | } |
662 | 761 | ||
663 | int __init snd_chip_uda1341_mixer_new(snd_card_t *card, struct l3_client **clnt) | 762 | int __init snd_chip_uda1341_mixer_new(snd_card_t *card, struct l3_client **clntp) |
664 | { | 763 | { |
665 | static snd_device_ops_t ops = { | 764 | static snd_device_ops_t ops = { |
666 | .dev_free = uda1341_dev_free, | 765 | .dev_free = uda1341_dev_free, |
667 | }; | 766 | }; |
668 | struct l3_client *uda1341; | 767 | struct l3_client *clnt; |
669 | int idx, err; | 768 | int idx, err; |
670 | 769 | ||
671 | snd_assert(card != NULL, return -EINVAL); | 770 | snd_assert(card != NULL, return -EINVAL); |
672 | 771 | ||
673 | uda1341 = kzalloc(sizeof(*uda1341), GFP_KERNEL); | 772 | clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); |
674 | if (uda1341 == NULL) | 773 | if (clnt == NULL) |
675 | return -ENOMEM; | 774 | return -ENOMEM; |
676 | 775 | ||
677 | if ((err = l3_attach_client(uda1341, "l3-bit-sa1100-gpio", "snd-uda1341"))) { | 776 | if ((err = l3_attach_client(clnt, "l3-bit-sa1100-gpio", UDA1341_ALSA_NAME))) { |
678 | kfree(uda1341); | 777 | kfree(clnt); |
679 | return err; | ||
680 | } | ||
681 | |||
682 | if ((err = snd_device_new(card, SNDRV_DEV_CODEC, uda1341, &ops)) < 0) { | ||
683 | l3_detach_client(uda1341); | ||
684 | kfree(uda1341); | ||
685 | return err; | 778 | return err; |
686 | } | 779 | } |
687 | 780 | ||
688 | for (idx = 0; idx < ARRAY_SIZE(snd_uda1341_controls); idx++) { | 781 | for (idx = 0; idx < ARRAY_SIZE(snd_uda1341_controls); idx++) { |
689 | if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_uda1341_controls[idx], uda1341))) < 0) | 782 | if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_uda1341_controls[idx], clnt))) < 0) { |
783 | uda1341_free(clnt); | ||
690 | return err; | 784 | return err; |
785 | } | ||
786 | } | ||
787 | |||
788 | if ((err = snd_device_new(card, SNDRV_DEV_CODEC, clnt, &ops)) < 0) { | ||
789 | uda1341_free(clnt); | ||
790 | return err; | ||
691 | } | 791 | } |
692 | 792 | ||
693 | *clnt = uda1341; | 793 | *clntp = clnt; |
694 | strcpy(card->mixername, "UDA1341TS Mixer"); | 794 | strcpy(card->mixername, "UDA1341TS Mixer"); |
695 | ((uda1341_t *)uda1341->driver_data)->card = card; | 795 | ((uda1341_t *)uda1341->driver_data)->card = card; |
696 | 796 | ||
697 | snd_uda1341_proc_init(card, uda1341); | 797 | snd_uda1341_proc_init(card, clnt); |
698 | 798 | ||
699 | return 0; | 799 | return 0; |
700 | } | 800 | } |