diff options
Diffstat (limited to 'sound/pci/ac97')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 68 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 40 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.h | 1 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_pcm.c | 6 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_proc.c | 14 | ||||
-rw-r--r-- | sound/pci/ac97/ak4531_codec.c | 28 |
6 files changed, 101 insertions, 56 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 3020ca2b602b..278319bbdea1 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
31 | #include <linux/mutex.h> | ||
31 | #include <sound/core.h> | 32 | #include <sound/core.h> |
32 | #include <sound/pcm.h> | 33 | #include <sound/pcm.h> |
33 | #include <sound/ac97_codec.h> | 34 | #include <sound/ac97_codec.h> |
@@ -149,7 +150,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { | |||
149 | { 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL }, | 150 | { 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL }, |
150 | { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk | 151 | { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk |
151 | { 0x4e534331, 0xffffffff, "LM4549", NULL, NULL }, | 152 | { 0x4e534331, 0xffffffff, "LM4549", NULL, NULL }, |
152 | { 0x4e534350, 0xffffffff, "LM4550", NULL, NULL }, | 153 | { 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix |
153 | { 0x50534304, 0xffffffff, "UCB1400", NULL, NULL }, | 154 | { 0x50534304, 0xffffffff, "UCB1400", NULL, NULL }, |
154 | { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, | 155 | { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, |
155 | { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, | 156 | { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, |
@@ -191,9 +192,6 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { | |||
191 | 192 | ||
192 | static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg) | 193 | static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg) |
193 | { | 194 | { |
194 | if (ac97->limited_regs && ! test_bit(reg, ac97->reg_accessed)) | ||
195 | return 0; | ||
196 | |||
197 | /* filter some registers for buggy codecs */ | 195 | /* filter some registers for buggy codecs */ |
198 | switch (ac97->id) { | 196 | switch (ac97->id) { |
199 | case AC97_ID_AK4540: | 197 | case AC97_ID_AK4540: |
@@ -296,11 +294,11 @@ void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned sh | |||
296 | { | 294 | { |
297 | if (!snd_ac97_valid_reg(ac97, reg)) | 295 | if (!snd_ac97_valid_reg(ac97, reg)) |
298 | return; | 296 | return; |
299 | down(&ac97->reg_mutex); | 297 | mutex_lock(&ac97->reg_mutex); |
300 | ac97->regs[reg] = value; | 298 | ac97->regs[reg] = value; |
301 | ac97->bus->ops->write(ac97, reg, value); | 299 | ac97->bus->ops->write(ac97, reg, value); |
302 | set_bit(reg, ac97->reg_accessed); | 300 | set_bit(reg, ac97->reg_accessed); |
303 | up(&ac97->reg_mutex); | 301 | mutex_unlock(&ac97->reg_mutex); |
304 | } | 302 | } |
305 | 303 | ||
306 | /** | 304 | /** |
@@ -321,14 +319,14 @@ int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short va | |||
321 | 319 | ||
322 | if (!snd_ac97_valid_reg(ac97, reg)) | 320 | if (!snd_ac97_valid_reg(ac97, reg)) |
323 | return -EINVAL; | 321 | return -EINVAL; |
324 | down(&ac97->reg_mutex); | 322 | mutex_lock(&ac97->reg_mutex); |
325 | change = ac97->regs[reg] != value; | 323 | change = ac97->regs[reg] != value; |
326 | if (change) { | 324 | if (change) { |
327 | ac97->regs[reg] = value; | 325 | ac97->regs[reg] = value; |
328 | ac97->bus->ops->write(ac97, reg, value); | 326 | ac97->bus->ops->write(ac97, reg, value); |
329 | } | 327 | } |
330 | set_bit(reg, ac97->reg_accessed); | 328 | set_bit(reg, ac97->reg_accessed); |
331 | up(&ac97->reg_mutex); | 329 | mutex_unlock(&ac97->reg_mutex); |
332 | return change; | 330 | return change; |
333 | } | 331 | } |
334 | 332 | ||
@@ -351,9 +349,9 @@ int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned sho | |||
351 | 349 | ||
352 | if (!snd_ac97_valid_reg(ac97, reg)) | 350 | if (!snd_ac97_valid_reg(ac97, reg)) |
353 | return -EINVAL; | 351 | return -EINVAL; |
354 | down(&ac97->reg_mutex); | 352 | mutex_lock(&ac97->reg_mutex); |
355 | change = snd_ac97_update_bits_nolock(ac97, reg, mask, value); | 353 | change = snd_ac97_update_bits_nolock(ac97, reg, mask, value); |
356 | up(&ac97->reg_mutex); | 354 | mutex_unlock(&ac97->reg_mutex); |
357 | return change; | 355 | return change; |
358 | } | 356 | } |
359 | 357 | ||
@@ -380,12 +378,12 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns | |||
380 | int change; | 378 | int change; |
381 | unsigned short old, new, cfg; | 379 | unsigned short old, new, cfg; |
382 | 380 | ||
383 | down(&ac97->page_mutex); | 381 | mutex_lock(&ac97->page_mutex); |
384 | old = ac97->spec.ad18xx.pcmreg[codec]; | 382 | old = ac97->spec.ad18xx.pcmreg[codec]; |
385 | new = (old & ~mask) | value; | 383 | new = (old & ~mask) | value; |
386 | change = old != new; | 384 | change = old != new; |
387 | if (change) { | 385 | if (change) { |
388 | down(&ac97->reg_mutex); | 386 | mutex_lock(&ac97->reg_mutex); |
389 | cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG); | 387 | cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG); |
390 | ac97->spec.ad18xx.pcmreg[codec] = new; | 388 | ac97->spec.ad18xx.pcmreg[codec] = new; |
391 | /* select single codec */ | 389 | /* select single codec */ |
@@ -397,9 +395,9 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns | |||
397 | /* select all codecs */ | 395 | /* select all codecs */ |
398 | ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG, | 396 | ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG, |
399 | cfg | 0x7000); | 397 | cfg | 0x7000); |
400 | up(&ac97->reg_mutex); | 398 | mutex_unlock(&ac97->reg_mutex); |
401 | } | 399 | } |
402 | up(&ac97->page_mutex); | 400 | mutex_unlock(&ac97->page_mutex); |
403 | return change; | 401 | return change; |
404 | } | 402 | } |
405 | 403 | ||
@@ -467,7 +465,7 @@ static int snd_ac97_page_save(struct snd_ac97 *ac97, int reg, struct snd_kcontro | |||
467 | (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 && | 465 | (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 && |
468 | (reg >= 0x60 && reg < 0x70)) { | 466 | (reg >= 0x60 && reg < 0x70)) { |
469 | unsigned short page = (kcontrol->private_value >> 26) & 0x0f; | 467 | unsigned short page = (kcontrol->private_value >> 26) & 0x0f; |
470 | down(&ac97->page_mutex); /* lock paging */ | 468 | mutex_lock(&ac97->page_mutex); /* lock paging */ |
471 | page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; | 469 | page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; |
472 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); | 470 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); |
473 | } | 471 | } |
@@ -478,7 +476,7 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save) | |||
478 | { | 476 | { |
479 | if (page_save >= 0) { | 477 | if (page_save >= 0) { |
480 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); | 478 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); |
481 | up(&ac97->page_mutex); /* unlock paging */ | 479 | mutex_unlock(&ac97->page_mutex); /* unlock paging */ |
482 | } | 480 | } |
483 | } | 481 | } |
484 | 482 | ||
@@ -674,12 +672,12 @@ static int snd_ac97_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ | |||
674 | { | 672 | { |
675 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 673 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
676 | 674 | ||
677 | down(&ac97->reg_mutex); | 675 | mutex_lock(&ac97->reg_mutex); |
678 | ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff; | 676 | ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff; |
679 | ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff; | 677 | ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff; |
680 | ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff; | 678 | ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff; |
681 | ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff; | 679 | ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff; |
682 | up(&ac97->reg_mutex); | 680 | mutex_unlock(&ac97->reg_mutex); |
683 | return 0; | 681 | return 0; |
684 | } | 682 | } |
685 | 683 | ||
@@ -718,7 +716,7 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ | |||
718 | } | 716 | } |
719 | } | 717 | } |
720 | 718 | ||
721 | down(&ac97->reg_mutex); | 719 | mutex_lock(&ac97->reg_mutex); |
722 | change = ac97->spdif_status != new; | 720 | change = ac97->spdif_status != new; |
723 | ac97->spdif_status = new; | 721 | ac97->spdif_status = new; |
724 | 722 | ||
@@ -746,7 +744,7 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ | |||
746 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ | 744 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ |
747 | } | 745 | } |
748 | } | 746 | } |
749 | up(&ac97->reg_mutex); | 747 | mutex_unlock(&ac97->reg_mutex); |
750 | 748 | ||
751 | return change; | 749 | return change; |
752 | } | 750 | } |
@@ -763,7 +761,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
763 | 761 | ||
764 | value = (ucontrol->value.integer.value[0] & mask); | 762 | value = (ucontrol->value.integer.value[0] & mask); |
765 | 763 | ||
766 | down(&ac97->reg_mutex); | 764 | mutex_lock(&ac97->reg_mutex); |
767 | mask <<= shift; | 765 | mask <<= shift; |
768 | value <<= shift; | 766 | value <<= shift; |
769 | old = snd_ac97_read_cache(ac97, reg); | 767 | old = snd_ac97_read_cache(ac97, reg); |
@@ -777,7 +775,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
777 | if (extst & AC97_EA_SPDIF) | 775 | if (extst & AC97_EA_SPDIF) |
778 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ | 776 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ |
779 | } | 777 | } |
780 | up(&ac97->reg_mutex); | 778 | mutex_unlock(&ac97->reg_mutex); |
781 | return change; | 779 | return change; |
782 | } | 780 | } |
783 | 781 | ||
@@ -888,10 +886,10 @@ static int snd_ac97_ad18xx_pcm_get_volume(struct snd_kcontrol *kcontrol, struct | |||
888 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 886 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
889 | int codec = kcontrol->private_value & 3; | 887 | int codec = kcontrol->private_value & 3; |
890 | 888 | ||
891 | down(&ac97->page_mutex); | 889 | mutex_lock(&ac97->page_mutex); |
892 | ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31); | 890 | ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31); |
893 | ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31); | 891 | ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31); |
894 | up(&ac97->page_mutex); | 892 | mutex_unlock(&ac97->page_mutex); |
895 | return 0; | 893 | return 0; |
896 | } | 894 | } |
897 | 895 | ||
@@ -1007,9 +1005,6 @@ static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg) | |||
1007 | break; | 1005 | break; |
1008 | } | 1006 | } |
1009 | 1007 | ||
1010 | if (ac97->limited_regs && test_bit(reg, ac97->reg_accessed)) | ||
1011 | return 1; /* allow without check */ | ||
1012 | |||
1013 | val = snd_ac97_read(ac97, reg); | 1008 | val = snd_ac97_read(ac97, reg); |
1014 | if (!(val & mask)) { | 1009 | if (!(val & mask)) { |
1015 | /* nothing seems to be here - mute flag is not set */ | 1010 | /* nothing seems to be here - mute flag is not set */ |
@@ -1029,6 +1024,18 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha | |||
1029 | unsigned char max[3] = { 63, 31, 15 }; | 1024 | unsigned char max[3] = { 63, 31, 15 }; |
1030 | int i; | 1025 | int i; |
1031 | 1026 | ||
1027 | /* first look up the static resolution table */ | ||
1028 | if (ac97->res_table) { | ||
1029 | const struct snd_ac97_res_table *tbl; | ||
1030 | for (tbl = ac97->res_table; tbl->reg; tbl++) { | ||
1031 | if (tbl->reg == reg) { | ||
1032 | *lo_max = tbl->bits & 0xff; | ||
1033 | *hi_max = (tbl->bits >> 8) & 0xff; | ||
1034 | return; | ||
1035 | } | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1032 | *lo_max = *hi_max = 0; | 1039 | *lo_max = *hi_max = 0; |
1033 | for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { | 1040 | for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { |
1034 | unsigned short val; | 1041 | unsigned short val; |
@@ -1853,11 +1860,10 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, | |||
1853 | ac97->num = template->num; | 1860 | ac97->num = template->num; |
1854 | ac97->addr = template->addr; | 1861 | ac97->addr = template->addr; |
1855 | ac97->scaps = template->scaps; | 1862 | ac97->scaps = template->scaps; |
1856 | ac97->limited_regs = template->limited_regs; | 1863 | ac97->res_table = template->res_table; |
1857 | memcpy(ac97->reg_accessed, template->reg_accessed, sizeof(ac97->reg_accessed)); | ||
1858 | bus->codec[ac97->num] = ac97; | 1864 | bus->codec[ac97->num] = ac97; |
1859 | init_MUTEX(&ac97->reg_mutex); | 1865 | mutex_init(&ac97->reg_mutex); |
1860 | init_MUTEX(&ac97->page_mutex); | 1866 | mutex_init(&ac97->page_mutex); |
1861 | 1867 | ||
1862 | #ifdef CONFIG_PCI | 1868 | #ifdef CONFIG_PCI |
1863 | if (ac97->pci) { | 1869 | if (ac97->pci) { |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index a444a78c7c94..4d9cf37300f7 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/mutex.h> | ||
31 | |||
30 | #include <sound/core.h> | 32 | #include <sound/core.h> |
31 | #include <sound/pcm.h> | 33 | #include <sound/pcm.h> |
32 | #include <sound/control.h> | 34 | #include <sound/control.h> |
@@ -55,12 +57,12 @@ static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsi | |||
55 | unsigned short page_save; | 57 | unsigned short page_save; |
56 | int ret; | 58 | int ret; |
57 | 59 | ||
58 | down(&ac97->page_mutex); | 60 | mutex_lock(&ac97->page_mutex); |
59 | page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; | 61 | page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; |
60 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); | 62 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); |
61 | ret = snd_ac97_update_bits(ac97, reg, mask, value); | 63 | ret = snd_ac97_update_bits(ac97, reg, mask, value); |
62 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); | 64 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); |
63 | up(&ac97->page_mutex); /* unlock paging */ | 65 | mutex_unlock(&ac97->page_mutex); /* unlock paging */ |
64 | return ret; | 66 | return ret; |
65 | } | 67 | } |
66 | 68 | ||
@@ -897,12 +899,12 @@ static int snd_ac97_stac9708_put_bias(struct snd_kcontrol *kcontrol, struct snd_ | |||
897 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 899 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
898 | int err; | 900 | int err; |
899 | 901 | ||
900 | down(&ac97->page_mutex); | 902 | mutex_lock(&ac97->page_mutex); |
901 | snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba); | 903 | snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba); |
902 | err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010, | 904 | err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010, |
903 | (ucontrol->value.integer.value[0] & 1) << 4); | 905 | (ucontrol->value.integer.value[0] & 1) << 4); |
904 | snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0); | 906 | snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0); |
905 | up(&ac97->page_mutex); | 907 | mutex_unlock(&ac97->page_mutex); |
906 | return err; | 908 | return err; |
907 | } | 909 | } |
908 | 910 | ||
@@ -2823,3 +2825,33 @@ int mpatch_si3036(struct snd_ac97 * ac97) | |||
2823 | snd_ac97_write_cache(ac97, 0x68, 0); | 2825 | snd_ac97_write_cache(ac97, 0x68, 0); |
2824 | return 0; | 2826 | return 0; |
2825 | } | 2827 | } |
2828 | |||
2829 | /* | ||
2830 | * LM 4550 Codec | ||
2831 | * | ||
2832 | * We use a static resolution table since LM4550 codec cannot be | ||
2833 | * properly autoprobed to determine the resolution via | ||
2834 | * check_volume_resolution(). | ||
2835 | */ | ||
2836 | |||
2837 | static struct snd_ac97_res_table lm4550_restbl[] = { | ||
2838 | { AC97_MASTER, 0x1f1f }, | ||
2839 | { AC97_HEADPHONE, 0x1f1f }, | ||
2840 | { AC97_MASTER_MONO, 0x001f }, | ||
2841 | { AC97_PC_BEEP, 0x001f }, /* LSB is ignored */ | ||
2842 | { AC97_PHONE, 0x001f }, | ||
2843 | { AC97_MIC, 0x001f }, | ||
2844 | { AC97_LINE, 0x1f1f }, | ||
2845 | { AC97_CD, 0x1f1f }, | ||
2846 | { AC97_VIDEO, 0x1f1f }, | ||
2847 | { AC97_AUX, 0x1f1f }, | ||
2848 | { AC97_PCM, 0x1f1f }, | ||
2849 | { AC97_REC_GAIN, 0x0f0f }, | ||
2850 | { } /* terminator */ | ||
2851 | }; | ||
2852 | |||
2853 | int patch_lm4550(struct snd_ac97 *ac97) | ||
2854 | { | ||
2855 | ac97->res_table = lm4550_restbl; | ||
2856 | return 0; | ||
2857 | } | ||
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 5060cb6f2ec3..adcaa04586cb 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h | |||
@@ -59,3 +59,4 @@ int patch_vt1616(struct snd_ac97 * ac97); | |||
59 | int patch_vt1617a(struct snd_ac97 * ac97); | 59 | int patch_vt1617a(struct snd_ac97 * ac97); |
60 | int patch_it2646(struct snd_ac97 * ac97); | 60 | int patch_it2646(struct snd_ac97 * ac97); |
61 | int mpatch_si3036(struct snd_ac97 * ac97); | 61 | int mpatch_si3036(struct snd_ac97 * ac97); |
62 | int patch_lm4550(struct snd_ac97 * ac97); | ||
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c index c3e590bf7a02..512a3583b0ce 100644 --- a/sound/pci/ac97/ac97_pcm.c +++ b/sound/pci/ac97/ac97_pcm.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/mutex.h> | ||
31 | |||
30 | #include <sound/core.h> | 32 | #include <sound/core.h> |
31 | #include <sound/pcm.h> | 33 | #include <sound/pcm.h> |
32 | #include <sound/control.h> | 34 | #include <sound/control.h> |
@@ -206,7 +208,7 @@ static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) | |||
206 | mask = AC97_SC_SPSR_MASK; | 208 | mask = AC97_SC_SPSR_MASK; |
207 | } | 209 | } |
208 | 210 | ||
209 | down(&ac97->reg_mutex); | 211 | mutex_lock(&ac97->reg_mutex); |
210 | old = snd_ac97_read(ac97, reg) & mask; | 212 | old = snd_ac97_read(ac97, reg) & mask; |
211 | if (old != bits) { | 213 | if (old != bits) { |
212 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); | 214 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); |
@@ -231,7 +233,7 @@ static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) | |||
231 | ac97->spdif_status = sbits; | 233 | ac97->spdif_status = sbits; |
232 | } | 234 | } |
233 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); | 235 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); |
234 | up(&ac97->reg_mutex); | 236 | mutex_unlock(&ac97->reg_mutex); |
235 | return 0; | 237 | return 0; |
236 | } | 238 | } |
237 | 239 | ||
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c index 7134b3f55fb5..4d523df79cc7 100644 --- a/sound/pci/ac97/ac97_proc.c +++ b/sound/pci/ac97/ac97_proc.c | |||
@@ -24,6 +24,8 @@ | |||
24 | 24 | ||
25 | #include <sound/driver.h> | 25 | #include <sound/driver.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/mutex.h> | ||
28 | |||
27 | #include <sound/core.h> | 29 | #include <sound/core.h> |
28 | #include <sound/ac97_codec.h> | 30 | #include <sound/ac97_codec.h> |
29 | #include <sound/asoundef.h> | 31 | #include <sound/asoundef.h> |
@@ -338,7 +340,7 @@ static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buf | |||
338 | { | 340 | { |
339 | struct snd_ac97 *ac97 = entry->private_data; | 341 | struct snd_ac97 *ac97 = entry->private_data; |
340 | 342 | ||
341 | down(&ac97->page_mutex); | 343 | mutex_lock(&ac97->page_mutex); |
342 | if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 | 344 | if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 |
343 | int idx; | 345 | int idx; |
344 | for (idx = 0; idx < 3; idx++) | 346 | for (idx = 0; idx < 3; idx++) |
@@ -364,7 +366,7 @@ static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buf | |||
364 | } else { | 366 | } else { |
365 | snd_ac97_proc_read_main(ac97, buffer, 0); | 367 | snd_ac97_proc_read_main(ac97, buffer, 0); |
366 | } | 368 | } |
367 | up(&ac97->page_mutex); | 369 | mutex_unlock(&ac97->page_mutex); |
368 | } | 370 | } |
369 | 371 | ||
370 | #ifdef CONFIG_SND_DEBUG | 372 | #ifdef CONFIG_SND_DEBUG |
@@ -374,7 +376,7 @@ static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_in | |||
374 | struct snd_ac97 *ac97 = entry->private_data; | 376 | struct snd_ac97 *ac97 = entry->private_data; |
375 | char line[64]; | 377 | char line[64]; |
376 | unsigned int reg, val; | 378 | unsigned int reg, val; |
377 | down(&ac97->page_mutex); | 379 | mutex_lock(&ac97->page_mutex); |
378 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | 380 | while (!snd_info_get_line(buffer, line, sizeof(line))) { |
379 | if (sscanf(line, "%x %x", ®, &val) != 2) | 381 | if (sscanf(line, "%x %x", ®, &val) != 2) |
380 | continue; | 382 | continue; |
@@ -382,7 +384,7 @@ static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_in | |||
382 | if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff) | 384 | if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff) |
383 | snd_ac97_write_cache(ac97, reg, val); | 385 | snd_ac97_write_cache(ac97, reg, val); |
384 | } | 386 | } |
385 | up(&ac97->page_mutex); | 387 | mutex_unlock(&ac97->page_mutex); |
386 | } | 388 | } |
387 | #endif | 389 | #endif |
388 | 390 | ||
@@ -401,7 +403,7 @@ static void snd_ac97_proc_regs_read(struct snd_info_entry *entry, | |||
401 | { | 403 | { |
402 | struct snd_ac97 *ac97 = entry->private_data; | 404 | struct snd_ac97 *ac97 = entry->private_data; |
403 | 405 | ||
404 | down(&ac97->page_mutex); | 406 | mutex_lock(&ac97->page_mutex); |
405 | if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 | 407 | if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 |
406 | 408 | ||
407 | int idx; | 409 | int idx; |
@@ -417,7 +419,7 @@ static void snd_ac97_proc_regs_read(struct snd_info_entry *entry, | |||
417 | } else { | 419 | } else { |
418 | snd_ac97_proc_regs_read_main(ac97, buffer, 0); | 420 | snd_ac97_proc_regs_read_main(ac97, buffer, 0); |
419 | } | 421 | } |
420 | up(&ac97->page_mutex); | 422 | mutex_unlock(&ac97->page_mutex); |
421 | } | 423 | } |
422 | 424 | ||
423 | void snd_ac97_proc_init(struct snd_ac97 * ac97) | 425 | void snd_ac97_proc_init(struct snd_ac97 * ac97) |
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c index dcfb5036ff8b..0fb7b3407312 100644 --- a/sound/pci/ac97/ak4531_codec.c +++ b/sound/pci/ac97/ak4531_codec.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/mutex.h> | ||
27 | |||
26 | #include <sound/core.h> | 28 | #include <sound/core.h> |
27 | #include <sound/ak4531_codec.h> | 29 | #include <sound/ak4531_codec.h> |
28 | 30 | ||
@@ -82,9 +84,9 @@ static int snd_ak4531_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
82 | int invert = (kcontrol->private_value >> 22) & 1; | 84 | int invert = (kcontrol->private_value >> 22) & 1; |
83 | int val; | 85 | int val; |
84 | 86 | ||
85 | down(&ak4531->reg_mutex); | 87 | mutex_lock(&ak4531->reg_mutex); |
86 | val = (ak4531->regs[reg] >> shift) & mask; | 88 | val = (ak4531->regs[reg] >> shift) & mask; |
87 | up(&ak4531->reg_mutex); | 89 | mutex_unlock(&ak4531->reg_mutex); |
88 | if (invert) { | 90 | if (invert) { |
89 | val = mask - val; | 91 | val = mask - val; |
90 | } | 92 | } |
@@ -107,11 +109,11 @@ static int snd_ak4531_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
107 | val = mask - val; | 109 | val = mask - val; |
108 | } | 110 | } |
109 | val <<= shift; | 111 | val <<= shift; |
110 | down(&ak4531->reg_mutex); | 112 | mutex_lock(&ak4531->reg_mutex); |
111 | val = (ak4531->regs[reg] & ~(mask << shift)) | val; | 113 | val = (ak4531->regs[reg] & ~(mask << shift)) | val; |
112 | change = val != ak4531->regs[reg]; | 114 | change = val != ak4531->regs[reg]; |
113 | ak4531->write(ak4531, reg, ak4531->regs[reg] = val); | 115 | ak4531->write(ak4531, reg, ak4531->regs[reg] = val); |
114 | up(&ak4531->reg_mutex); | 116 | mutex_unlock(&ak4531->reg_mutex); |
115 | return change; | 117 | return change; |
116 | } | 118 | } |
117 | 119 | ||
@@ -143,10 +145,10 @@ static int snd_ak4531_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
143 | int invert = (kcontrol->private_value >> 22) & 1; | 145 | int invert = (kcontrol->private_value >> 22) & 1; |
144 | int left, right; | 146 | int left, right; |
145 | 147 | ||
146 | down(&ak4531->reg_mutex); | 148 | mutex_lock(&ak4531->reg_mutex); |
147 | left = (ak4531->regs[left_reg] >> left_shift) & mask; | 149 | left = (ak4531->regs[left_reg] >> left_shift) & mask; |
148 | right = (ak4531->regs[right_reg] >> right_shift) & mask; | 150 | right = (ak4531->regs[right_reg] >> right_shift) & mask; |
149 | up(&ak4531->reg_mutex); | 151 | mutex_unlock(&ak4531->reg_mutex); |
150 | if (invert) { | 152 | if (invert) { |
151 | left = mask - left; | 153 | left = mask - left; |
152 | right = mask - right; | 154 | right = mask - right; |
@@ -176,7 +178,7 @@ static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
176 | } | 178 | } |
177 | left <<= left_shift; | 179 | left <<= left_shift; |
178 | right <<= right_shift; | 180 | right <<= right_shift; |
179 | down(&ak4531->reg_mutex); | 181 | mutex_lock(&ak4531->reg_mutex); |
180 | if (left_reg == right_reg) { | 182 | if (left_reg == right_reg) { |
181 | left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right; | 183 | left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right; |
182 | change = left != ak4531->regs[left_reg]; | 184 | change = left != ak4531->regs[left_reg]; |
@@ -188,7 +190,7 @@ static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
188 | ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left); | 190 | ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left); |
189 | ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right); | 191 | ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right); |
190 | } | 192 | } |
191 | up(&ak4531->reg_mutex); | 193 | mutex_unlock(&ak4531->reg_mutex); |
192 | return change; | 194 | return change; |
193 | } | 195 | } |
194 | 196 | ||
@@ -215,12 +217,12 @@ static int snd_ak4531_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
215 | int left_shift = (kcontrol->private_value >> 16) & 0x0f; | 217 | int left_shift = (kcontrol->private_value >> 16) & 0x0f; |
216 | int right_shift = (kcontrol->private_value >> 24) & 0x0f; | 218 | int right_shift = (kcontrol->private_value >> 24) & 0x0f; |
217 | 219 | ||
218 | down(&ak4531->reg_mutex); | 220 | mutex_lock(&ak4531->reg_mutex); |
219 | ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1; | 221 | ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1; |
220 | ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1; | 222 | ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1; |
221 | ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1; | 223 | ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1; |
222 | ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1; | 224 | ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1; |
223 | up(&ak4531->reg_mutex); | 225 | mutex_unlock(&ak4531->reg_mutex); |
224 | return 0; | 226 | return 0; |
225 | } | 227 | } |
226 | 228 | ||
@@ -234,7 +236,7 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
234 | int change; | 236 | int change; |
235 | int val1, val2; | 237 | int val1, val2; |
236 | 238 | ||
237 | down(&ak4531->reg_mutex); | 239 | mutex_lock(&ak4531->reg_mutex); |
238 | val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift)); | 240 | val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift)); |
239 | val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift)); | 241 | val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift)); |
240 | val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift; | 242 | val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift; |
@@ -244,7 +246,7 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
244 | change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2]; | 246 | change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2]; |
245 | ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1); | 247 | ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1); |
246 | ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2); | 248 | ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2); |
247 | up(&ak4531->reg_mutex); | 249 | mutex_unlock(&ak4531->reg_mutex); |
248 | return change; | 250 | return change; |
249 | } | 251 | } |
250 | 252 | ||
@@ -366,7 +368,7 @@ int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531, | |||
366 | if (ak4531 == NULL) | 368 | if (ak4531 == NULL) |
367 | return -ENOMEM; | 369 | return -ENOMEM; |
368 | *ak4531 = *_ak4531; | 370 | *ak4531 = *_ak4531; |
369 | init_MUTEX(&ak4531->reg_mutex); | 371 | mutex_init(&ak4531->reg_mutex); |
370 | if ((err = snd_component_add(card, "AK4531")) < 0) { | 372 | if ((err = snd_component_add(card, "AK4531")) < 0) { |
371 | snd_ak4531_free(ak4531); | 373 | snd_ak4531_free(ak4531); |
372 | return err; | 374 | return err; |