| OLD | NEW |
| 1 /* | 1 /* |
| 2 * wm8990.c -- WM8990 ALSA Soc Audio driver | 2 * wm8990.c -- WM8990 ALSA Soc Audio driver |
| 3 * | 3 * |
| 4 * Copyright 2008 Wolfson Microelectronics PLC. | 4 * Copyright 2008 Wolfson Microelectronics PLC. |
| 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> | 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> |
| 6 * | 6 * |
| 7 * This program is free software; you can redistribute it and/or modify it | 7 * This program is free software; you can redistribute it and/or modify it |
| 8 * under the terms of the GNU General Public License as published by the | 8 * under the terms of the GNU General Public License as published by the |
| 9 * Free Software Foundation; either version 2 of the License, or (at your | 9 * Free Software Foundation; either version 2 of the License, or (at your |
| 10 * option) any later version. | 10 * option) any later version. |
| 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/kernel.h> | 15 #include <linux/kernel.h> |
| 16 #include <linux/init.h> | 16 #include <linux/init.h> |
| 17 #include <linux/delay.h> | 17 #include <linux/delay.h> |
| 18 #include <linux/pm.h> | 18 #include <linux/pm.h> |
| 19 #include <linux/i2c.h> | 19 #include <linux/i2c.h> |
| 20 #include <linux/platform_device.h> | 20 #include <linux/platform_device.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 <asm/div64.h> | 28 #include <asm/div64.h> |
| 30 | 29 |
| 31 #include "wm8990.h" | 30 #include "wm8990.h" |
| 32 | 31 |
| 33 /* codec private data */ | 32 /* codec private data */ |
| 34 struct wm8990_priv { | 33 struct wm8990_priv { |
| 35 enum snd_soc_control_type control_type; | 34 enum snd_soc_control_type control_type; |
| 36 unsigned int sysclk; | 35 unsigned int sysclk; |
| (...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 {"LOUT", NULL, "LOUT PGA"}, | 906 {"LOUT", NULL, "LOUT PGA"}, |
| 908 {"SPKN", NULL, "SPKMIX"}, | 907 {"SPKN", NULL, "SPKMIX"}, |
| 909 {"ROUT", NULL, "ROUT PGA"}, | 908 {"ROUT", NULL, "ROUT PGA"}, |
| 910 {"OUT4", NULL, "OUT4MIX"}, | 909 {"OUT4", NULL, "OUT4MIX"}, |
| 911 {"ROP", NULL, "ROPMIX"}, | 910 {"ROP", NULL, "ROPMIX"}, |
| 912 {"RON", NULL, "RONMIX"}, | 911 {"RON", NULL, "RONMIX"}, |
| 913 }; | 912 }; |
| 914 | 913 |
| 915 static int wm8990_add_widgets(struct snd_soc_codec *codec) | 914 static int wm8990_add_widgets(struct snd_soc_codec *codec) |
| 916 { | 915 { |
| 917 » snd_soc_dapm_new_controls(codec, wm8990_dapm_widgets, | 916 » struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 917 |
| 918 » snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets, |
| 918 ARRAY_SIZE(wm8990_dapm_widgets)); | 919 ARRAY_SIZE(wm8990_dapm_widgets)); |
| 919 | |
| 920 /* set up the WM8990 audio map */ | 920 /* set up the WM8990 audio map */ |
| 921 » snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | 921 » snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 922 | 922 |
| 923 return 0; | 923 return 0; |
| 924 } | 924 } |
| 925 | 925 |
| 926 /* PLL divisors */ | 926 /* PLL divisors */ |
| 927 struct _pll_div { | 927 struct _pll_div { |
| 928 u32 div2; | 928 u32 div2; |
| 929 u32 n; | 929 u32 n; |
| 930 u32 k; | 930 u32 k; |
| 931 }; | 931 }; |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 break; | 1163 break; |
| 1164 | 1164 |
| 1165 case SND_SOC_BIAS_PREPARE: | 1165 case SND_SOC_BIAS_PREPARE: |
| 1166 /* VMID=2*50k */ | 1166 /* VMID=2*50k */ |
| 1167 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) & | 1167 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) & |
| 1168 ~WM8990_VMID_MODE_MASK; | 1168 ~WM8990_VMID_MODE_MASK; |
| 1169 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2); | 1169 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2); |
| 1170 break; | 1170 break; |
| 1171 | 1171 |
| 1172 case SND_SOC_BIAS_STANDBY: | 1172 case SND_SOC_BIAS_STANDBY: |
| 1173 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { | 1173 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 1174 /* Enable all output discharge bits */ | 1174 /* Enable all output discharge bits */ |
| 1175 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | | 1175 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | |
| 1176 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | | 1176 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | |
| 1177 WM8990_DIS_OUT4 | WM8990_DIS_LOUT | | 1177 WM8990_DIS_OUT4 | WM8990_DIS_LOUT | |
| 1178 WM8990_DIS_ROUT); | 1178 WM8990_DIS_ROUT); |
| 1179 | 1179 |
| 1180 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */ | 1180 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */ |
| 1181 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | | 1181 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | |
| 1182 WM8990_BUFDCOPEN | WM8990_POBCTRL | | 1182 WM8990_BUFDCOPEN | WM8990_POBCTRL | |
| 1183 WM8990_VMIDTOG); | 1183 WM8990_VMIDTOG); |
| 1184 | 1184 |
| 1185 /* Delay to allow output caps to discharge */ | 1185 /* Delay to allow output caps to discharge */ |
| 1186 » » » msleep(msecs_to_jiffies(300)); | 1186 » » » msleep(300); |
| 1187 | 1187 |
| 1188 /* Disable VMIDTOG */ | 1188 /* Disable VMIDTOG */ |
| 1189 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | | 1189 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | |
| 1190 WM8990_BUFDCOPEN | WM8990_POBCTRL); | 1190 WM8990_BUFDCOPEN | WM8990_POBCTRL); |
| 1191 | 1191 |
| 1192 /* disable all output discharge bits */ | 1192 /* disable all output discharge bits */ |
| 1193 snd_soc_write(codec, WM8990_ANTIPOP1, 0); | 1193 snd_soc_write(codec, WM8990_ANTIPOP1, 0); |
| 1194 | 1194 |
| 1195 /* Enable outputs */ | 1195 /* Enable outputs */ |
| 1196 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00); | 1196 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00); |
| 1197 | 1197 |
| 1198 » » » msleep(msecs_to_jiffies(50)); | 1198 » » » msleep(50); |
| 1199 | 1199 |
| 1200 /* Enable VMID at 2x50k */ | 1200 /* Enable VMID at 2x50k */ |
| 1201 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02); | 1201 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02); |
| 1202 | 1202 |
| 1203 » » » msleep(msecs_to_jiffies(100)); | 1203 » » » msleep(100); |
| 1204 | 1204 |
| 1205 /* Enable VREF */ | 1205 /* Enable VREF */ |
| 1206 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); | 1206 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); |
| 1207 | 1207 |
| 1208 » » » msleep(msecs_to_jiffies(600)); | 1208 » » » msleep(600); |
| 1209 | 1209 |
| 1210 /* Enable BUFIOEN */ | 1210 /* Enable BUFIOEN */ |
| 1211 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | | 1211 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | |
| 1212 WM8990_BUFDCOPEN | WM8990_POBCTRL | | 1212 WM8990_BUFDCOPEN | WM8990_POBCTRL | |
| 1213 WM8990_BUFIOEN); | 1213 WM8990_BUFIOEN); |
| 1214 | 1214 |
| 1215 /* Disable outputs */ | 1215 /* Disable outputs */ |
| 1216 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3); | 1216 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3); |
| 1217 | 1217 |
| 1218 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ | 1218 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1243 /* mute DAC */ | 1243 /* mute DAC */ |
| 1244 val = snd_soc_read(codec, WM8990_DAC_CTRL); | 1244 val = snd_soc_read(codec, WM8990_DAC_CTRL); |
| 1245 snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE); | 1245 snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE); |
| 1246 | 1246 |
| 1247 /* Enable any disabled outputs */ | 1247 /* Enable any disabled outputs */ |
| 1248 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); | 1248 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); |
| 1249 | 1249 |
| 1250 /* Disable VMID */ | 1250 /* Disable VMID */ |
| 1251 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01); | 1251 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01); |
| 1252 | 1252 |
| 1253 » » msleep(msecs_to_jiffies(300)); | 1253 » » msleep(300); |
| 1254 | 1254 |
| 1255 /* Enable all output discharge bits */ | 1255 /* Enable all output discharge bits */ |
| 1256 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | | 1256 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | |
| 1257 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | | 1257 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | |
| 1258 WM8990_DIS_OUT4 | WM8990_DIS_LOUT | | 1258 WM8990_DIS_OUT4 | WM8990_DIS_LOUT | |
| 1259 WM8990_DIS_ROUT); | 1259 WM8990_DIS_ROUT); |
| 1260 | 1260 |
| 1261 /* Disable VREF */ | 1261 /* Disable VREF */ |
| 1262 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0); | 1262 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0); |
| 1263 | 1263 |
| 1264 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ | 1264 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ |
| 1265 snd_soc_write(codec, WM8990_ANTIPOP2, 0x0); | 1265 snd_soc_write(codec, WM8990_ANTIPOP2, 0x0); |
| 1266 break; | 1266 break; |
| 1267 } | 1267 } |
| 1268 | 1268 |
| 1269 » codec->bias_level = level; | 1269 » codec->dapm.bias_level = level; |
| 1270 return 0; | 1270 return 0; |
| 1271 } | 1271 } |
| 1272 | 1272 |
| 1273 #define WM8990_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ | 1273 #define WM8990_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ |
| 1274 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ | 1274 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ |
| 1275 SNDRV_PCM_RATE_48000) | 1275 SNDRV_PCM_RATE_48000) |
| 1276 | 1276 |
| 1277 #define WM8990_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 1277 #define WM8990_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
| 1278 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | 1278 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
| 1279 | 1279 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 { | 1456 { |
| 1457 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1457 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 1458 i2c_del_driver(&wm8990_i2c_driver); | 1458 i2c_del_driver(&wm8990_i2c_driver); |
| 1459 #endif | 1459 #endif |
| 1460 } | 1460 } |
| 1461 module_exit(wm8990_exit); | 1461 module_exit(wm8990_exit); |
| 1462 | 1462 |
| 1463 MODULE_DESCRIPTION("ASoC WM8990 driver"); | 1463 MODULE_DESCRIPTION("ASoC WM8990 driver"); |
| 1464 MODULE_AUTHOR("Liam Girdwood"); | 1464 MODULE_AUTHOR("Liam Girdwood"); |
| 1465 MODULE_LICENSE("GPL"); | 1465 MODULE_LICENSE("GPL"); |
| OLD | NEW |