| OLD | NEW |
| 1 /* | 1 /* |
| 2 * wm8955.c -- WM8955 ALSA SoC Audio driver | 2 * wm8955.c -- WM8955 ALSA SoC Audio driver |
| 3 * | 3 * |
| 4 * Copyright 2009 Wolfson Microelectronics plc | 4 * Copyright 2009 Wolfson Microelectronics plc |
| 5 * | 5 * |
| 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| 7 * | 7 * |
| 8 * This program is free software; you can redistribute it and/or modify | 8 * This program is free software; you can redistribute it and/or modify |
| 9 * it under the terms of the GNU General Public License version 2 as | 9 * it under the terms of the GNU General Public License version 2 as |
| 10 * published by the Free Software Foundation. | 10 * published by the Free Software Foundation. |
| 11 */ | 11 */ |
| 12 | 12 |
| 13 #include <linux/module.h> | 13 #include <linux/module.h> |
| 14 #include <linux/moduleparam.h> | 14 #include <linux/moduleparam.h> |
| 15 #include <linux/init.h> | 15 #include <linux/init.h> |
| 16 #include <linux/delay.h> | 16 #include <linux/delay.h> |
| 17 #include <linux/pm.h> | 17 #include <linux/pm.h> |
| 18 #include <linux/i2c.h> | 18 #include <linux/i2c.h> |
| 19 #include <linux/platform_device.h> | 19 #include <linux/platform_device.h> |
| 20 #include <linux/regulator/consumer.h> | 20 #include <linux/regulator/consumer.h> |
| 21 #include <linux/slab.h> | 21 #include <linux/slab.h> |
| 22 #include <sound/core.h> | 22 #include <sound/core.h> |
| 23 #include <sound/pcm.h> | 23 #include <sound/pcm.h> |
| 24 #include <sound/pcm_params.h> | 24 #include <sound/pcm_params.h> |
| 25 #include <sound/soc.h> | 25 #include <sound/soc.h> |
| 26 #include <sound/soc-dapm.h> | |
| 27 #include <sound/initval.h> | 26 #include <sound/initval.h> |
| 28 #include <sound/tlv.h> | 27 #include <sound/tlv.h> |
| 29 #include <sound/wm8955.h> | 28 #include <sound/wm8955.h> |
| 30 | 29 |
| 31 #include "wm8955.h" | 30 #include "wm8955.h" |
| 32 | 31 |
| 33 #define WM8955_NUM_SUPPLIES 4 | 32 #define WM8955_NUM_SUPPLIES 4 |
| 34 static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { | 33 static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { |
| 35 "DCVDD", | 34 "DCVDD", |
| 36 "DBVDD", | 35 "DBVDD", |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 | 568 |
| 570 { "MOUT PGA", NULL, "Mono" }, | 569 { "MOUT PGA", NULL, "Mono" }, |
| 571 { "MONOOUT", NULL, "MOUT PGA" }, | 570 { "MONOOUT", NULL, "MOUT PGA" }, |
| 572 | 571 |
| 573 /* OUT3 not currently implemented */ | 572 /* OUT3 not currently implemented */ |
| 574 { "OUT3", NULL, "OUT3 PGA" }, | 573 { "OUT3", NULL, "OUT3 PGA" }, |
| 575 }; | 574 }; |
| 576 | 575 |
| 577 static int wm8955_add_widgets(struct snd_soc_codec *codec) | 576 static int wm8955_add_widgets(struct snd_soc_codec *codec) |
| 578 { | 577 { |
| 578 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 579 |
| 579 snd_soc_add_controls(codec, wm8955_snd_controls, | 580 snd_soc_add_controls(codec, wm8955_snd_controls, |
| 580 ARRAY_SIZE(wm8955_snd_controls)); | 581 ARRAY_SIZE(wm8955_snd_controls)); |
| 581 | 582 |
| 582 » snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets, | 583 » snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets, |
| 583 ARRAY_SIZE(wm8955_dapm_widgets)); | 584 ARRAY_SIZE(wm8955_dapm_widgets)); |
| 584 | 585 » snd_soc_dapm_add_routes(dapm, wm8955_intercon, |
| 585 » snd_soc_dapm_add_routes(codec, wm8955_intercon, | |
| 586 ARRAY_SIZE(wm8955_intercon)); | 586 ARRAY_SIZE(wm8955_intercon)); |
| 587 | 587 |
| 588 return 0; | 588 return 0; |
| 589 } | 589 } |
| 590 | 590 |
| 591 static int wm8955_hw_params(struct snd_pcm_substream *substream, | 591 static int wm8955_hw_params(struct snd_pcm_substream *substream, |
| 592 struct snd_pcm_hw_params *params, | 592 struct snd_pcm_hw_params *params, |
| 593 struct snd_soc_dai *dai) | 593 struct snd_soc_dai *dai) |
| 594 { | 594 { |
| 595 struct snd_soc_codec *codec = dai->codec; | 595 struct snd_soc_codec *codec = dai->codec; |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 WM8955_VMIDSEL_MASK, | 779 WM8955_VMIDSEL_MASK, |
| 780 0x1 << WM8955_VMIDSEL_SHIFT); | 780 0x1 << WM8955_VMIDSEL_SHIFT); |
| 781 | 781 |
| 782 /* Default bias current */ | 782 /* Default bias current */ |
| 783 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1, | 783 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1, |
| 784 WM8955_VSEL_MASK, | 784 WM8955_VSEL_MASK, |
| 785 0x2 << WM8955_VSEL_SHIFT); | 785 0x2 << WM8955_VSEL_SHIFT); |
| 786 break; | 786 break; |
| 787 | 787 |
| 788 case SND_SOC_BIAS_STANDBY: | 788 case SND_SOC_BIAS_STANDBY: |
| 789 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { | 789 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 790 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies)
, | 790 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies)
, |
| 791 wm8955->supplies); | 791 wm8955->supplies); |
| 792 if (ret != 0) { | 792 if (ret != 0) { |
| 793 dev_err(codec->dev, | 793 dev_err(codec->dev, |
| 794 "Failed to enable supplies: %d\n", | 794 "Failed to enable supplies: %d\n", |
| 795 ret); | 795 ret); |
| 796 return ret; | 796 return ret; |
| 797 } | 797 } |
| 798 | 798 |
| 799 /* Sync back cached values if they're | 799 /* Sync back cached values if they're |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 | 843 |
| 844 /* Turn off VMID and VREF */ | 844 /* Turn off VMID and VREF */ |
| 845 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, | 845 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, |
| 846 WM8955_VREF | | 846 WM8955_VREF | |
| 847 WM8955_VMIDSEL_MASK, 0); | 847 WM8955_VMIDSEL_MASK, 0); |
| 848 | 848 |
| 849 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), | 849 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), |
| 850 wm8955->supplies); | 850 wm8955->supplies); |
| 851 break; | 851 break; |
| 852 } | 852 } |
| 853 » codec->bias_level = level; | 853 » codec->dapm.bias_level = level; |
| 854 return 0; | 854 return 0; |
| 855 } | 855 } |
| 856 | 856 |
| 857 #define WM8955_RATES SNDRV_PCM_RATE_8000_96000 | 857 #define WM8955_RATES SNDRV_PCM_RATE_8000_96000 |
| 858 | 858 |
| 859 #define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 859 #define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
| 860 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | 860 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
| 861 | 861 |
| 862 static struct snd_soc_dai_ops wm8955_dai_ops = { | 862 static struct snd_soc_dai_ops wm8955_dai_ops = { |
| 863 .set_sysclk = wm8955_set_sysclk, | 863 .set_sysclk = wm8955_set_sysclk, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 goto err_get; | 927 goto err_get; |
| 928 } | 928 } |
| 929 | 929 |
| 930 ret = wm8955_reset(codec); | 930 ret = wm8955_reset(codec); |
| 931 if (ret < 0) { | 931 if (ret < 0) { |
| 932 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); | 932 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); |
| 933 goto err_enable; | 933 goto err_enable; |
| 934 } | 934 } |
| 935 | 935 |
| 936 /* Change some default settings - latch VU and enable ZC */ | 936 /* Change some default settings - latch VU and enable ZC */ |
| 937 » reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; | 937 » snd_soc_update_bits(codec, WM8955_LEFT_DAC_VOLUME, |
| 938 » reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; | 938 » » » WM8955_LDVU, WM8955_LDVU); |
| 939 » reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; | 939 » snd_soc_update_bits(codec, WM8955_RIGHT_DAC_VOLUME, |
| 940 » reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; | 940 » » » WM8955_RDVU, WM8955_RDVU); |
| 941 » reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; | 941 » snd_soc_update_bits(codec, WM8955_LOUT1_VOLUME, |
| 942 » reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; | 942 » » » WM8955_LO1VU | WM8955_LO1ZC, |
| 943 » reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; | 943 » » » WM8955_LO1VU | WM8955_LO1ZC); |
| 944 » snd_soc_update_bits(codec, WM8955_ROUT1_VOLUME, |
| 945 » » » WM8955_RO1VU | WM8955_RO1ZC, |
| 946 » » » WM8955_RO1VU | WM8955_RO1ZC); |
| 947 » snd_soc_update_bits(codec, WM8955_LOUT2_VOLUME, |
| 948 » » » WM8955_LO2VU | WM8955_LO2ZC, |
| 949 » » » WM8955_LO2VU | WM8955_LO2ZC); |
| 950 » snd_soc_update_bits(codec, WM8955_ROUT2_VOLUME, |
| 951 » » » WM8955_RO2VU | WM8955_RO2ZC, |
| 952 » » » WM8955_RO2VU | WM8955_RO2ZC); |
| 953 » snd_soc_update_bits(codec, WM8955_MONOOUT_VOLUME, |
| 954 » » » WM8955_MOZC, WM8955_MOZC); |
| 944 | 955 |
| 945 /* Also enable adaptive bass boost by default */ | 956 /* Also enable adaptive bass boost by default */ |
| 946 » reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; | 957 » snd_soc_update_bits(codec, WM8955_BASS_CONTROL, WM8955_BB, WM8955_BB); |
| 947 | 958 |
| 948 /* Set platform data values */ | 959 /* Set platform data values */ |
| 949 if (pdata) { | 960 if (pdata) { |
| 950 if (pdata->out2_speaker) | 961 if (pdata->out2_speaker) |
| 951 reg_cache[WM8955_ADDITIONAL_CONTROL_2] | 962 reg_cache[WM8955_ADDITIONAL_CONTROL_2] |
| 952 |= WM8955_ROUT2INV; | 963 |= WM8955_ROUT2INV; |
| 953 | 964 |
| 954 if (pdata->monoin_diff) | 965 if (pdata->monoin_diff) |
| 955 reg_cache[WM8955_MONO_OUT_MIX_1] | 966 reg_cache[WM8955_MONO_OUT_MIX_1] |
| 956 |= WM8955_DMEN; | 967 |= WM8955_DMEN; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 { | 1065 { |
| 1055 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1066 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 1056 i2c_del_driver(&wm8955_i2c_driver); | 1067 i2c_del_driver(&wm8955_i2c_driver); |
| 1057 #endif | 1068 #endif |
| 1058 } | 1069 } |
| 1059 module_exit(wm8955_exit); | 1070 module_exit(wm8955_exit); |
| 1060 | 1071 |
| 1061 MODULE_DESCRIPTION("ASoC WM8955 driver"); | 1072 MODULE_DESCRIPTION("ASoC WM8955 driver"); |
| 1062 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1073 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
| 1063 MODULE_LICENSE("GPL"); | 1074 MODULE_LICENSE("GPL"); |
| OLD | NEW |