| OLD | NEW |
| 1 /* | 1 /* |
| 2 * wm8900.c -- WM8900 ALSA Soc Audio driver | 2 * wm8900.c -- WM8900 ALSA Soc Audio driver |
| 3 * | 3 * |
| 4 * Copyright 2007, 2008 Wolfson Microelectronics PLC. | 4 * Copyright 2007, 2008 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. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include <linux/delay.h> | 23 #include <linux/delay.h> |
| 24 #include <linux/pm.h> | 24 #include <linux/pm.h> |
| 25 #include <linux/i2c.h> | 25 #include <linux/i2c.h> |
| 26 #include <linux/spi/spi.h> | 26 #include <linux/spi/spi.h> |
| 27 #include <linux/platform_device.h> | 27 #include <linux/platform_device.h> |
| 28 #include <linux/slab.h> | 28 #include <linux/slab.h> |
| 29 #include <sound/core.h> | 29 #include <sound/core.h> |
| 30 #include <sound/pcm.h> | 30 #include <sound/pcm.h> |
| 31 #include <sound/pcm_params.h> | 31 #include <sound/pcm_params.h> |
| 32 #include <sound/soc.h> | 32 #include <sound/soc.h> |
| 33 #include <sound/soc-dapm.h> | |
| 34 #include <sound/initval.h> | 33 #include <sound/initval.h> |
| 35 #include <sound/tlv.h> | 34 #include <sound/tlv.h> |
| 36 | 35 |
| 37 #include "wm8900.h" | 36 #include "wm8900.h" |
| 38 | 37 |
| 39 /* WM8900 register space */ | 38 /* WM8900 register space */ |
| 40 #define WM8900_REG_RESET 0x0 | 39 #define WM8900_REG_RESET 0x0 |
| 41 #define WM8900_REG_ID 0x0 | 40 #define WM8900_REG_ID 0x0 |
| 42 #define WM8900_REG_POWER1 0x1 | 41 #define WM8900_REG_POWER1 0x1 |
| 43 #define WM8900_REG_POWER2 0x2 | 42 #define WM8900_REG_POWER2 0x2 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 #define WM8900_REG_HPCTL1_HP_OPSTAGE_ENA 0x40 | 132 #define WM8900_REG_HPCTL1_HP_OPSTAGE_ENA 0x40 |
| 134 #define WM8900_REG_HPCTL1_HP_CLAMP_IP 0x20 | 133 #define WM8900_REG_HPCTL1_HP_CLAMP_IP 0x20 |
| 135 #define WM8900_REG_HPCTL1_HP_CLAMP_OP 0x10 | 134 #define WM8900_REG_HPCTL1_HP_CLAMP_OP 0x10 |
| 136 #define WM8900_REG_HPCTL1_HP_SHORT 0x08 | 135 #define WM8900_REG_HPCTL1_HP_SHORT 0x08 |
| 137 #define WM8900_REG_HPCTL1_HP_SHORT2 0x04 | 136 #define WM8900_REG_HPCTL1_HP_SHORT2 0x04 |
| 138 | 137 |
| 139 #define WM8900_LRC_MASK 0xfc00 | 138 #define WM8900_LRC_MASK 0xfc00 |
| 140 | 139 |
| 141 struct wm8900_priv { | 140 struct wm8900_priv { |
| 142 enum snd_soc_control_type control_type; | 141 enum snd_soc_control_type control_type; |
| 143 u16 reg_cache[WM8900_MAXREG]; | |
| 144 | 142 |
| 145 u32 fll_in; /* FLL input frequency */ | 143 u32 fll_in; /* FLL input frequency */ |
| 146 u32 fll_out; /* FLL output frequency */ | 144 u32 fll_out; /* FLL output frequency */ |
| 147 }; | 145 }; |
| 148 | 146 |
| 149 /* | 147 /* |
| 150 * wm8900 register cache. We can't read the entire register space and we | 148 * wm8900 register cache. We can't read the entire register space and we |
| 151 * have slow control buses so we cache the registers. | 149 * have slow control buses so we cache the registers. |
| 152 */ | 150 */ |
| 153 static const u16 wm8900_reg_defaults[WM8900_MAXREG] = { | 151 static const u16 wm8900_reg_defaults[WM8900_MAXREG] = { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 175 0x0000, 0x0000, | 173 0x0000, 0x0000, |
| 176 0x0050, 0x0050, | 174 0x0050, 0x0050, |
| 177 0x0055, 0x0055, | 175 0x0055, 0x0055, |
| 178 0x0055, 0x0000, | 176 0x0055, 0x0000, |
| 179 0x0000, 0x0079, | 177 0x0000, 0x0079, |
| 180 0x0079, 0x0079, | 178 0x0079, 0x0079, |
| 181 0x0079, 0x0000, | 179 0x0079, 0x0000, |
| 182 /* Remaining registers all zero */ | 180 /* Remaining registers all zero */ |
| 183 }; | 181 }; |
| 184 | 182 |
| 185 static int wm8900_volatile_register(unsigned int reg) | 183 static int wm8900_volatile_register(struct snd_soc_codec *codec, unsigned int re
g) |
| 186 { | 184 { |
| 187 switch (reg) { | 185 switch (reg) { |
| 188 case WM8900_REG_ID: | 186 case WM8900_REG_ID: |
| 189 return 1; | 187 return 1; |
| 190 default: | 188 default: |
| 191 return 0; | 189 return 0; |
| 192 } | 190 } |
| 193 } | 191 } |
| 194 | 192 |
| 195 static void wm8900_reset(struct snd_soc_codec *codec) | 193 static void wm8900_reset(struct snd_soc_codec *codec) |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 * mono path. | 602 * mono path. |
| 605 */ | 603 */ |
| 606 {"Headphone Amplifier", NULL, "LINEOUT2 LP"}, | 604 {"Headphone Amplifier", NULL, "LINEOUT2 LP"}, |
| 607 {"Headphone Amplifier", NULL, "LINEOUT2 LP"}, | 605 {"Headphone Amplifier", NULL, "LINEOUT2 LP"}, |
| 608 {"HP_L", NULL, "Headphone Amplifier"}, | 606 {"HP_L", NULL, "Headphone Amplifier"}, |
| 609 {"HP_R", NULL, "Headphone Amplifier"}, | 607 {"HP_R", NULL, "Headphone Amplifier"}, |
| 610 }; | 608 }; |
| 611 | 609 |
| 612 static int wm8900_add_widgets(struct snd_soc_codec *codec) | 610 static int wm8900_add_widgets(struct snd_soc_codec *codec) |
| 613 { | 611 { |
| 614 » snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets, | 612 » struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 613 |
| 614 » snd_soc_dapm_new_controls(dapm, wm8900_dapm_widgets, |
| 615 ARRAY_SIZE(wm8900_dapm_widgets)); | 615 ARRAY_SIZE(wm8900_dapm_widgets)); |
| 616 | 616 » snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 617 » snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | |
| 618 | 617 |
| 619 return 0; | 618 return 0; |
| 620 } | 619 } |
| 621 | 620 |
| 622 static int wm8900_hw_params(struct snd_pcm_substream *substream, | 621 static int wm8900_hw_params(struct snd_pcm_substream *substream, |
| 623 struct snd_pcm_hw_params *params, | 622 struct snd_pcm_hw_params *params, |
| 624 struct snd_soc_dai *dai) | 623 struct snd_soc_dai *dai) |
| 625 { | 624 { |
| 626 struct snd_soc_pcm_runtime *rtd = substream->private_data; | 625 struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 627 struct snd_soc_codec *codec = rtd->codec; | 626 struct snd_soc_codec *codec = rtd->codec; |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1044 reg = snd_soc_read(codec, WM8900_REG_ADDCTL); | 1043 reg = snd_soc_read(codec, WM8900_REG_ADDCTL); |
| 1045 snd_soc_write(codec, WM8900_REG_ADDCTL, | 1044 snd_soc_write(codec, WM8900_REG_ADDCTL, |
| 1046 reg | WM8900_REG_ADDCTL_TEMP_SD); | 1045 reg | WM8900_REG_ADDCTL_TEMP_SD); |
| 1047 break; | 1046 break; |
| 1048 | 1047 |
| 1049 case SND_SOC_BIAS_PREPARE: | 1048 case SND_SOC_BIAS_PREPARE: |
| 1050 break; | 1049 break; |
| 1051 | 1050 |
| 1052 case SND_SOC_BIAS_STANDBY: | 1051 case SND_SOC_BIAS_STANDBY: |
| 1053 /* Charge capacitors if initial power up */ | 1052 /* Charge capacitors if initial power up */ |
| 1054 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { | 1053 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 1055 /* STARTUP_BIAS_ENA on */ | 1054 /* STARTUP_BIAS_ENA on */ |
| 1056 snd_soc_write(codec, WM8900_REG_POWER1, | 1055 snd_soc_write(codec, WM8900_REG_POWER1, |
| 1057 WM8900_REG_POWER1_STARTUP_BIAS_ENA); | 1056 WM8900_REG_POWER1_STARTUP_BIAS_ENA); |
| 1058 | 1057 |
| 1059 /* Startup bias mode */ | 1058 /* Startup bias mode */ |
| 1060 snd_soc_write(codec, WM8900_REG_ADDCTL, | 1059 snd_soc_write(codec, WM8900_REG_ADDCTL, |
| 1061 WM8900_REG_ADDCTL_BIAS_SRC | | 1060 WM8900_REG_ADDCTL_BIAS_SRC | |
| 1062 WM8900_REG_ADDCTL_VMID_SOFTST); | 1061 WM8900_REG_ADDCTL_VMID_SOFTST); |
| 1063 | 1062 |
| 1064 /* VMID 2x50k */ | 1063 /* VMID 2x50k */ |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1112 snd_soc_write(codec, WM8900_REG_POWER3, 0); | 1111 snd_soc_write(codec, WM8900_REG_POWER3, 0); |
| 1113 | 1112 |
| 1114 /* Need to let things settle before stopping the clock | 1113 /* Need to let things settle before stopping the clock |
| 1115 * to ensure that restart works, see "Stopping the | 1114 * to ensure that restart works, see "Stopping the |
| 1116 * master clock" in the datasheet. */ | 1115 * master clock" in the datasheet. */ |
| 1117 schedule_timeout_interruptible(msecs_to_jiffies(1)); | 1116 schedule_timeout_interruptible(msecs_to_jiffies(1)); |
| 1118 snd_soc_write(codec, WM8900_REG_POWER2, | 1117 snd_soc_write(codec, WM8900_REG_POWER2, |
| 1119 WM8900_REG_POWER2_SYSCLK_ENA); | 1118 WM8900_REG_POWER2_SYSCLK_ENA); |
| 1120 break; | 1119 break; |
| 1121 } | 1120 } |
| 1122 » codec->bias_level = level; | 1121 » codec->dapm.bias_level = level; |
| 1123 return 0; | 1122 return 0; |
| 1124 } | 1123 } |
| 1125 | 1124 |
| 1126 static int wm8900_suspend(struct snd_soc_codec *codec, pm_message_t state) | 1125 static int wm8900_suspend(struct snd_soc_codec *codec, pm_message_t state) |
| 1127 { | 1126 { |
| 1128 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); | 1127 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); |
| 1129 int fll_out = wm8900->fll_out; | 1128 int fll_out = wm8900->fll_out; |
| 1130 int fll_in = wm8900->fll_in; | 1129 int fll_in = wm8900->fll_in; |
| 1131 int ret; | 1130 int ret; |
| 1132 | 1131 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 #endif | 1364 #endif |
| 1366 #if defined(CONFIG_SPI_MASTER) | 1365 #if defined(CONFIG_SPI_MASTER) |
| 1367 spi_unregister_driver(&wm8900_spi_driver); | 1366 spi_unregister_driver(&wm8900_spi_driver); |
| 1368 #endif | 1367 #endif |
| 1369 } | 1368 } |
| 1370 module_exit(wm8900_exit); | 1369 module_exit(wm8900_exit); |
| 1371 | 1370 |
| 1372 MODULE_DESCRIPTION("ASoC WM8900 driver"); | 1371 MODULE_DESCRIPTION("ASoC WM8900 driver"); |
| 1373 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); | 1372 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); |
| 1374 MODULE_LICENSE("GPL"); | 1373 MODULE_LICENSE("GPL"); |
| OLD | NEW |