Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(787)

Side by Side Diff: sound/soc/codecs/wm8993.c

Issue 6577007: CHROMIUM: ASoC: Import entire upstream ASoC tree (Closed)
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sound/soc/codecs/wm8991.c ('k') | sound/soc/codecs/wm8994.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * wm8993.c -- WM8993 ALSA SoC audio driver 2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 * 3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics plc 4 * Copyright 2009, 2010 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/regulator/consumer.h> 19 #include <linux/regulator/consumer.h>
20 #include <linux/spi/spi.h> 20 #include <linux/spi/spi.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/tlv.h> 25 #include <sound/tlv.h>
26 #include <sound/soc.h> 26 #include <sound/soc.h>
27 #include <sound/soc-dapm.h>
28 #include <sound/initval.h> 27 #include <sound/initval.h>
29 #include <sound/wm8993.h> 28 #include <sound/wm8993.h>
30 29
31 #include "wm8993.h" 30 #include "wm8993.h"
32 #include "wm_hubs.h" 31 #include "wm_hubs.h"
33 32
34 #define WM8993_NUM_SUPPLIES 6 33 #define WM8993_NUM_SUPPLIES 6
35 static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = { 34 static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = {
36 "DCVDD", 35 "DCVDD",
37 "DBVDD", 36 "DBVDD",
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 { 160, 10 }, 218 { 160, 10 },
220 { 220, 11 }, 219 { 220, 11 },
221 { 240, 12 }, 220 { 240, 12 },
222 { 320, 13 }, 221 { 320, 13 },
223 { 440, 14 }, 222 { 440, 14 },
224 { 480, 15 }, 223 { 480, 15 },
225 }; 224 };
226 225
227 struct wm8993_priv { 226 struct wm8993_priv {
228 struct wm_hubs_data hubs_data; 227 struct wm_hubs_data hubs_data;
229 u16 reg_cache[WM8993_REGISTER_COUNT];
230 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; 228 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
231 struct wm8993_platform_data pdata; 229 struct wm8993_platform_data pdata;
232 enum snd_soc_control_type control_type; 230 enum snd_soc_control_type control_type;
233 int master; 231 int master;
234 int sysclk_source; 232 int sysclk_source;
235 int tdm_slots; 233 int tdm_slots;
236 int tdm_width; 234 int tdm_width;
237 unsigned int mclk_rate; 235 unsigned int mclk_rate;
238 unsigned int sysclk_rate; 236 unsigned int sysclk_rate;
239 unsigned int fs; 237 unsigned int fs;
240 unsigned int bclk; 238 unsigned int bclk;
241 int class_w_users; 239 int class_w_users;
242 unsigned int fll_fref; 240 unsigned int fll_fref;
243 unsigned int fll_fout; 241 unsigned int fll_fout;
244 int fll_src; 242 int fll_src;
245 }; 243 };
246 244
247 static int wm8993_volatile(unsigned int reg) 245 static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg)
248 { 246 {
249 switch (reg) { 247 switch (reg) {
250 case WM8993_SOFTWARE_RESET: 248 case WM8993_SOFTWARE_RESET:
251 case WM8993_DC_SERVO_0: 249 case WM8993_DC_SERVO_0:
252 case WM8993_DC_SERVO_READBACK_0: 250 case WM8993_DC_SERVO_READBACK_0:
253 case WM8993_DC_SERVO_READBACK_1: 251 case WM8993_DC_SERVO_READBACK_1:
254 case WM8993_DC_SERVO_READBACK_2: 252 case WM8993_DC_SERVO_READBACK_2:
255 return 1; 253 return 1;
256 default: 254 default:
257 return 0; 255 return 0;
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 /* Turn it off if we're using the main output mixer */ 726 /* Turn it off if we're using the main output mixer */
729 if (ucontrol->value.integer.value[0] == 0) { 727 if (ucontrol->value.integer.value[0] == 0) {
730 if (wm8993->class_w_users == 0) { 728 if (wm8993->class_w_users == 0) {
731 dev_dbg(codec->dev, "Disabling Class W\n"); 729 dev_dbg(codec->dev, "Disabling Class W\n");
732 snd_soc_update_bits(codec, WM8993_CLASS_W_0, 730 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
733 WM8993_CP_DYN_FREQ | 731 WM8993_CP_DYN_FREQ |
734 WM8993_CP_DYN_V, 732 WM8993_CP_DYN_V,
735 0); 733 0);
736 } 734 }
737 wm8993->class_w_users++; 735 wm8993->class_w_users++;
736 wm8993->hubs_data.class_w = true;
738 } 737 }
739 738
740 /* Implement the change */ 739 /* Implement the change */
741 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 740 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
742 741
743 /* Enable it if we're using the direct DAC path */ 742 /* Enable it if we're using the direct DAC path */
744 if (ucontrol->value.integer.value[0] == 1) { 743 if (ucontrol->value.integer.value[0] == 1) {
745 if (wm8993->class_w_users == 1) { 744 if (wm8993->class_w_users == 1) {
746 dev_dbg(codec->dev, "Enabling Class W\n"); 745 dev_dbg(codec->dev, "Enabling Class W\n");
747 snd_soc_update_bits(codec, WM8993_CLASS_W_0, 746 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
748 WM8993_CP_DYN_FREQ | 747 WM8993_CP_DYN_FREQ |
749 WM8993_CP_DYN_V, 748 WM8993_CP_DYN_V,
750 WM8993_CP_DYN_FREQ | 749 WM8993_CP_DYN_FREQ |
751 WM8993_CP_DYN_V); 750 WM8993_CP_DYN_V);
752 } 751 }
753 wm8993->class_w_users--; 752 wm8993->class_w_users--;
753 wm8993->hubs_data.class_w = false;
754 } 754 }
755 755
756 dev_dbg(codec->dev, "Indirect DAC use count now %d\n", 756 dev_dbg(codec->dev, "Indirect DAC use count now %d\n",
757 wm8993->class_w_users); 757 wm8993->class_w_users);
758 758
759 return ret; 759 return ret;
760 } 760 }
761 761
762 #define SOC_DAPM_ENUM_W(xname, xenum) \ 762 #define SOC_DAPM_ENUM_W(xname, xenum) \
763 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 763 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 case SND_SOC_BIAS_ON: 961 case SND_SOC_BIAS_ON:
962 case SND_SOC_BIAS_PREPARE: 962 case SND_SOC_BIAS_PREPARE:
963 /* VMID=2*40k */ 963 /* VMID=2*40k */
964 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 964 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
965 WM8993_VMID_SEL_MASK, 0x2); 965 WM8993_VMID_SEL_MASK, 0x2);
966 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2, 966 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
967 WM8993_TSHUT_ENA, WM8993_TSHUT_ENA); 967 WM8993_TSHUT_ENA, WM8993_TSHUT_ENA);
968 break; 968 break;
969 969
970 case SND_SOC_BIAS_STANDBY: 970 case SND_SOC_BIAS_STANDBY:
971 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { 971 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
972 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies) , 972 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies) ,
973 wm8993->supplies); 973 wm8993->supplies);
974 if (ret != 0) 974 if (ret != 0)
975 return ret; 975 return ret;
976 976
977 wm8993_cache_restore(codec); 977 wm8993_cache_restore(codec);
978 978
979 /* Tune DC servo configuration */ 979 /* Tune DC servo configuration */
980 snd_soc_write(codec, 0x44, 3); 980 snd_soc_write(codec, 0x44, 3);
981 snd_soc_write(codec, 0x56, 3); 981 snd_soc_write(codec, 0x56, 3);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 break; 1022 break;
1023 1023
1024 case SND_SOC_BIAS_OFF: 1024 case SND_SOC_BIAS_OFF:
1025 snd_soc_update_bits(codec, WM8993_ANTIPOP1, 1025 snd_soc_update_bits(codec, WM8993_ANTIPOP1,
1026 WM8993_LINEOUT_VMID_BUF_ENA, 0); 1026 WM8993_LINEOUT_VMID_BUF_ENA, 0);
1027 1027
1028 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 1028 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
1029 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 1029 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
1030 0); 1030 0);
1031 1031
1032 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1033 WM8993_STARTUP_BIAS_ENA |
1034 WM8993_VMID_BUF_ENA |
1035 WM8993_VMID_RAMP_MASK |
1036 WM8993_BIAS_SRC, 0);
1037
1032 #ifdef CONFIG_REGULATOR 1038 #ifdef CONFIG_REGULATOR
1033 /* Post 2.6.34 we will be able to get a callback when 1039 /* Post 2.6.34 we will be able to get a callback when
1034 * the regulators are disabled which we can use but 1040 * the regulators are disabled which we can use but
1035 * for now just assume that the power will be cut if 1041 * for now just assume that the power will be cut if
1036 * the regulator API is in use. 1042 * the regulator API is in use.
1037 */ 1043 */
1038 codec->cache_sync = 1; 1044 codec->cache_sync = 1;
1039 #endif 1045 #endif
1040 1046
1041 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), 1047 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
1042 wm8993->supplies); 1048 wm8993->supplies);
1043 break; 1049 break;
1044 } 1050 }
1045 1051
1046 » codec->bias_level = level; 1052 » codec->dapm.bias_level = level;
1047 1053
1048 return 0; 1054 return 0;
1049 } 1055 }
1050 1056
1051 static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai, 1057 static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
1052 int clk_id, unsigned int freq, int dir) 1058 int clk_id, unsigned int freq, int dir)
1053 { 1059 {
1054 struct snd_soc_codec *codec = codec_dai->codec; 1060 struct snd_soc_codec *codec = codec_dai->codec;
1055 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1061 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1056 1062
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 ret = configure_clock(codec); 1224 ret = configure_clock(codec);
1219 if (ret != 0) 1225 if (ret != 0)
1220 return ret; 1226 return ret;
1221 1227
1222 /* Select nearest CLK_SYS_RATE */ 1228 /* Select nearest CLK_SYS_RATE */
1223 best = 0; 1229 best = 0;
1224 best_val = abs((wm8993->sysclk_rate / clk_sys_rates[0].ratio) 1230 best_val = abs((wm8993->sysclk_rate / clk_sys_rates[0].ratio)
1225 - wm8993->fs); 1231 - wm8993->fs);
1226 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { 1232 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1227 cur_val = abs((wm8993->sysclk_rate / 1233 cur_val = abs((wm8993->sysclk_rate /
1228 » » » clk_sys_rates[i].ratio) - wm8993->fs);; 1234 » » » clk_sys_rates[i].ratio) - wm8993->fs);
1229 if (cur_val < best_val) { 1235 if (cur_val < best_val) {
1230 best = i; 1236 best = i;
1231 best_val = cur_val; 1237 best_val = cur_val;
1232 } 1238 }
1233 } 1239 }
1234 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n", 1240 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
1235 clk_sys_rates[best].ratio); 1241 clk_sys_rates[best].ratio);
1236 clocking3 |= (clk_sys_rates[best].clk_sys_rate 1242 clocking3 |= (clk_sys_rates[best].clk_sys_rate
1237 << WM8993_CLK_SYS_RATE_SHIFT); 1243 << WM8993_CLK_SYS_RATE_SHIFT);
1238 1244
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 .rates = WM8993_RATES, 1421 .rates = WM8993_RATES,
1416 .formats = WM8993_FORMATS, 1422 .formats = WM8993_FORMATS,
1417 }, 1423 },
1418 .ops = &wm8993_ops, 1424 .ops = &wm8993_ops,
1419 .symmetric_rates = 1, 1425 .symmetric_rates = 1,
1420 }; 1426 };
1421 1427
1422 static int wm8993_probe(struct snd_soc_codec *codec) 1428 static int wm8993_probe(struct snd_soc_codec *codec)
1423 { 1429 {
1424 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1430 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1431 struct snd_soc_dapm_context *dapm = &codec->dapm;
1425 int ret, i, val; 1432 int ret, i, val;
1426 1433
1427 wm8993->hubs_data.hp_startup_mode = 1; 1434 wm8993->hubs_data.hp_startup_mode = 1;
1428 wm8993->hubs_data.dcs_codes = -2; 1435 wm8993->hubs_data.dcs_codes = -2;
1429 1436
1430 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1437 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1431 if (ret != 0) { 1438 if (ret != 0) {
1432 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1439 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1433 return ret; 1440 return ret;
1434 } 1441 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 snd_soc_add_controls(codec, wm8993_snd_controls, 1503 snd_soc_add_controls(codec, wm8993_snd_controls,
1497 ARRAY_SIZE(wm8993_snd_controls)); 1504 ARRAY_SIZE(wm8993_snd_controls));
1498 if (wm8993->pdata.num_retune_configs != 0) { 1505 if (wm8993->pdata.num_retune_configs != 0) {
1499 dev_dbg(codec->dev, "Using ReTune Mobile\n"); 1506 dev_dbg(codec->dev, "Using ReTune Mobile\n");
1500 } else { 1507 } else {
1501 dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n"); 1508 dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n");
1502 snd_soc_add_controls(codec, wm8993_eq_controls, 1509 snd_soc_add_controls(codec, wm8993_eq_controls,
1503 ARRAY_SIZE(wm8993_eq_controls)); 1510 ARRAY_SIZE(wm8993_eq_controls));
1504 } 1511 }
1505 1512
1506 » snd_soc_dapm_new_controls(codec, wm8993_dapm_widgets, 1513 » snd_soc_dapm_new_controls(dapm, wm8993_dapm_widgets,
1507 ARRAY_SIZE(wm8993_dapm_widgets)); 1514 ARRAY_SIZE(wm8993_dapm_widgets));
1508 wm_hubs_add_analogue_controls(codec); 1515 wm_hubs_add_analogue_controls(codec);
1509 1516
1510 » snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 1517 » snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1511 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1518 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1512 wm8993->pdata.lineout2_diff); 1519 wm8993->pdata.lineout2_diff);
1513 1520
1514 return 0; 1521 return 0;
1515 1522
1516 err_enable: 1523 err_enable:
1517 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); 1524 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1518 err_get: 1525 err_get:
1519 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); 1526 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1520 return ret; 1527 return ret;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1662 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1656 i2c_del_driver(&wm8993_i2c_driver); 1663 i2c_del_driver(&wm8993_i2c_driver);
1657 #endif 1664 #endif
1658 } 1665 }
1659 module_exit(wm8993_exit); 1666 module_exit(wm8993_exit);
1660 1667
1661 1668
1662 MODULE_DESCRIPTION("ASoC WM8993 driver"); 1669 MODULE_DESCRIPTION("ASoC WM8993 driver");
1663 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1670 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1664 MODULE_LICENSE("GPL"); 1671 MODULE_LICENSE("GPL");
OLDNEW
« no previous file with comments | « sound/soc/codecs/wm8991.c ('k') | sound/soc/codecs/wm8994.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698