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

Side by Side Diff: sound/soc/codecs/wm8978.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/wm8974.c ('k') | sound/soc/codecs/wm8985.c » ('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 * wm8978.c -- WM8978 ALSA SoC Audio Codec driver 2 * wm8978.c -- WM8978 ALSA SoC Audio Codec driver
3 * 3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> 4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2007 Carlos Munoz <carlos@kenati.com> 5 * Copyright (C) 2007 Carlos Munoz <carlos@kenati.com>
6 * Copyright 2006-2009 Wolfson Microelectronics PLC. 6 * Copyright 2006-2009 Wolfson Microelectronics PLC.
7 * Based on wm8974 and wm8990 by Liam Girdwood <lrg@slimlogic.co.uk> 7 * Based on wm8974 and wm8990 by Liam Girdwood <lrg@slimlogic.co.uk>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14 #include <linux/module.h> 14 #include <linux/module.h>
15 #include <linux/moduleparam.h> 15 #include <linux/moduleparam.h>
16 #include <linux/kernel.h> 16 #include <linux/kernel.h>
17 #include <linux/init.h> 17 #include <linux/init.h>
18 #include <linux/delay.h> 18 #include <linux/delay.h>
19 #include <linux/pm.h> 19 #include <linux/pm.h>
20 #include <linux/i2c.h> 20 #include <linux/i2c.h>
21 #include <linux/platform_device.h> 21 #include <linux/platform_device.h>
22 #include <linux/slab.h> 22 #include <linux/slab.h>
23 #include <sound/core.h> 23 #include <sound/core.h>
24 #include <sound/pcm.h> 24 #include <sound/pcm.h>
25 #include <sound/pcm_params.h> 25 #include <sound/pcm_params.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/tlv.h> 28 #include <sound/tlv.h>
30 #include <asm/div64.h> 29 #include <asm/div64.h>
31 30
32 #include "wm8978.h" 31 #include "wm8978.h"
33 32
34 /* wm8978 register cache. Note that register 0 is not included in the cache. */ 33 /* wm8978 register cache. Note that register 0 is not included in the cache. */
35 static const u16 wm8978_reg[WM8978_CACHEREGNUM] = { 34 static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
36 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */ 35 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
37 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */ 36 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */
(...skipping 15 matching lines...) Expand all
53 /* codec private data */ 52 /* codec private data */
54 struct wm8978_priv { 53 struct wm8978_priv {
55 enum snd_soc_control_type control_type; 54 enum snd_soc_control_type control_type;
56 void *control_data; 55 void *control_data;
57 unsigned int f_pllout; 56 unsigned int f_pllout;
58 unsigned int f_mclk; 57 unsigned int f_mclk;
59 unsigned int f_256fs; 58 unsigned int f_256fs;
60 unsigned int f_opclk; 59 unsigned int f_opclk;
61 int mclk_idx; 60 int mclk_idx;
62 enum wm8978_sysclk_src sysclk; 61 enum wm8978_sysclk_src sysclk;
63 u16 reg_cache[WM8978_CACHEREGNUM];
64 }; 62 };
65 63
66 static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"}; 64 static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
67 static const char *wm8978_eqmode[] = {"Capture", "Playback"}; 65 static const char *wm8978_eqmode[] = {"Capture", "Playback"};
68 static const char *wm8978_bw[] = {"Narrow", "Wide"}; 66 static const char *wm8978_bw[] = {"Narrow", "Wide"};
69 static const char *wm8978_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz"}; 67 static const char *wm8978_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz"};
70 static const char *wm8978_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz"}; 68 static const char *wm8978_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz"};
71 static const char *wm8978_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz"}; 69 static const char *wm8978_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz"};
72 static const char *wm8978_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"}; 70 static const char *wm8978_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"};
73 static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"}; 71 static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"};
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 {"Right Input Mixer", "MicN Switch", "RMICN"}, 346 {"Right Input Mixer", "MicN Switch", "RMICN"},
349 {"Right Input Mixer", "MicP Switch", "RMICP"}, 347 {"Right Input Mixer", "MicP Switch", "RMICP"},
350 348
351 {"Left Input Mixer", "L2 Switch", "L2"}, 349 {"Left Input Mixer", "L2 Switch", "L2"},
352 {"Left Input Mixer", "MicN Switch", "LMICN"}, 350 {"Left Input Mixer", "MicN Switch", "LMICN"},
353 {"Left Input Mixer", "MicP Switch", "LMICP"}, 351 {"Left Input Mixer", "MicP Switch", "LMICP"},
354 }; 352 };
355 353
356 static int wm8978_add_widgets(struct snd_soc_codec *codec) 354 static int wm8978_add_widgets(struct snd_soc_codec *codec)
357 { 355 {
358 » snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets, 356 » struct snd_soc_dapm_context *dapm = &codec->dapm;
357
358 » snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets,
359 ARRAY_SIZE(wm8978_dapm_widgets)); 359 ARRAY_SIZE(wm8978_dapm_widgets));
360
361 /* set up the WM8978 audio map */ 360 /* set up the WM8978 audio map */
362 » snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 361 » snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
363 362
364 return 0; 363 return 0;
365 } 364 }
366 365
367 /* PLL divisors */ 366 /* PLL divisors */
368 struct wm8978_pll_div { 367 struct wm8978_pll_div {
369 u32 k; 368 u32 k;
370 u8 n; 369 u8 n;
371 u8 div2; 370 u8 div2;
372 }; 371 };
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 switch (level) { 829 switch (level) {
831 case SND_SOC_BIAS_ON: 830 case SND_SOC_BIAS_ON:
832 case SND_SOC_BIAS_PREPARE: 831 case SND_SOC_BIAS_PREPARE:
833 power1 |= 1; /* VMID 75k */ 832 power1 |= 1; /* VMID 75k */
834 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1); 833 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
835 break; 834 break;
836 case SND_SOC_BIAS_STANDBY: 835 case SND_SOC_BIAS_STANDBY:
837 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */ 836 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */
838 power1 |= 0xc; 837 power1 |= 0xc;
839 838
840 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { 839 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
841 /* Initial cap charge at VMID 5k */ 840 /* Initial cap charge at VMID 5k */
842 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 841 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
843 power1 | 0x3); 842 power1 | 0x3);
844 mdelay(100); 843 mdelay(100);
845 } 844 }
846 845
847 power1 |= 0x2; /* VMID 500k */ 846 power1 |= 0x2; /* VMID 500k */
848 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1); 847 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
849 break; 848 break;
850 case SND_SOC_BIAS_OFF: 849 case SND_SOC_BIAS_OFF:
851 /* Preserve PLL - OPCLK may be used by someone */ 850 /* Preserve PLL - OPCLK may be used by someone */
852 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, ~0x20, 0); 851 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, ~0x20, 0);
853 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_2, 0); 852 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_2, 0);
854 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_3, 0); 853 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_3, 0);
855 break; 854 break;
856 } 855 }
857 856
858 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1); 857 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
859 858
860 » codec->bias_level = level; 859 » codec->dapm.bias_level = level;
861 return 0; 860 return 0;
862 } 861 }
863 862
864 #define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 863 #define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
865 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 864 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
866 865
867 static struct snd_soc_dai_ops wm8978_dai_ops = { 866 static struct snd_soc_dai_ops wm8978_dai_ops = {
868 .hw_params = wm8978_hw_params, 867 .hw_params = wm8978_hw_params,
869 .digital_mute = wm8978_mute, 868 .digital_mute = wm8978_mute,
870 .set_fmt = wm8978_set_dai_fmt, 869 .set_fmt = wm8978_set_dai_fmt,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 958 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
960 return ret; 959 return ret;
961 } 960 }
962 961
963 /* 962 /*
964 * Set the update bit in all registers, that have one. This way all 963 * Set the update bit in all registers, that have one. This way all
965 * writes to those registers will also cause the update bit to be 964 * writes to those registers will also cause the update bit to be
966 * written. 965 * written.
967 */ 966 */
968 for (i = 0; i < ARRAY_SIZE(update_reg); i++) 967 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
969 » » ((u16 *)codec->reg_cache)[update_reg[i]] |= 0x100; 968 » » snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100);
970 969
971 /* Reset the codec */ 970 /* Reset the codec */
972 ret = snd_soc_write(codec, WM8978_RESET, 0); 971 ret = snd_soc_write(codec, WM8978_RESET, 0);
973 if (ret < 0) { 972 if (ret < 0) {
974 dev_err(codec->dev, "Failed to issue reset\n"); 973 dev_err(codec->dev, "Failed to issue reset\n");
975 return ret; 974 return ret;
976 } 975 }
977 976
978 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 977 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
979 978
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 { 1064 {
1066 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1065 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1067 i2c_del_driver(&wm8978_i2c_driver); 1066 i2c_del_driver(&wm8978_i2c_driver);
1068 #endif 1067 #endif
1069 } 1068 }
1070 module_exit(wm8978_exit); 1069 module_exit(wm8978_exit);
1071 1070
1072 MODULE_DESCRIPTION("ASoC WM8978 codec driver"); 1071 MODULE_DESCRIPTION("ASoC WM8978 codec driver");
1073 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); 1072 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1074 MODULE_LICENSE("GPL"); 1073 MODULE_LICENSE("GPL");
OLDNEW
« no previous file with comments | « sound/soc/codecs/wm8974.c ('k') | sound/soc/codecs/wm8985.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698