diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-01-21 10:41:48 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-01-21 16:15:42 -0500 |
commit | 411a3450c9539043c794a5f4a6bdb03bb040670a (patch) | |
tree | ff409f1904d280c7d84d0a01b1a20f15c6eff9f1 | |
parent | 9f8cbae4163ab132cd7a56385341efdd41fcd429 (diff) |
ASoC: wm8985: Convert to direct regmap API usage
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | sound/soc/codecs/wm8985.c | 253 |
1 files changed, 177 insertions, 76 deletions
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index bbe19b2ae516..14f666398d0c 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/pm.h> | 20 | #include <linux/pm.h> |
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/regmap.h> | ||
22 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
23 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
@@ -39,73 +40,127 @@ static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = { | |||
39 | "AVDD2" | 40 | "AVDD2" |
40 | }; | 41 | }; |
41 | 42 | ||
42 | static const u16 wm8985_reg_defs[] = { | 43 | static const struct reg_default wm8985_reg_defaults[] = { |
43 | 0x0000, /* R0 - Software Reset */ | 44 | { 1, 0x0000 }, /* R1 - Power management 1 */ |
44 | 0x0000, /* R1 - Power management 1 */ | 45 | { 2, 0x0000 }, /* R2 - Power management 2 */ |
45 | 0x0000, /* R2 - Power management 2 */ | 46 | { 3, 0x0000 }, /* R3 - Power management 3 */ |
46 | 0x0000, /* R3 - Power management 3 */ | 47 | { 4, 0x0050 }, /* R4 - Audio Interface */ |
47 | 0x0050, /* R4 - Audio Interface */ | 48 | { 5, 0x0000 }, /* R5 - Companding control */ |
48 | 0x0000, /* R5 - Companding control */ | 49 | { 6, 0x0140 }, /* R6 - Clock Gen control */ |
49 | 0x0140, /* R6 - Clock Gen control */ | 50 | { 7, 0x0000 }, /* R7 - Additional control */ |
50 | 0x0000, /* R7 - Additional control */ | 51 | { 8, 0x0000 }, /* R8 - GPIO Control */ |
51 | 0x0000, /* R8 - GPIO Control */ | 52 | { 9, 0x0000 }, /* R9 - Jack Detect Control 1 */ |
52 | 0x0000, /* R9 - Jack Detect Control 1 */ | 53 | { 10, 0x0000 }, /* R10 - DAC Control */ |
53 | 0x0000, /* R10 - DAC Control */ | 54 | { 11, 0x00FF }, /* R11 - Left DAC digital Vol */ |
54 | 0x00FF, /* R11 - Left DAC digital Vol */ | 55 | { 12, 0x00FF }, /* R12 - Right DAC digital vol */ |
55 | 0x00FF, /* R12 - Right DAC digital vol */ | 56 | { 13, 0x0000 }, /* R13 - Jack Detect Control 2 */ |
56 | 0x0000, /* R13 - Jack Detect Control 2 */ | 57 | { 14, 0x0100 }, /* R14 - ADC Control */ |
57 | 0x0100, /* R14 - ADC Control */ | 58 | { 15, 0x00FF }, /* R15 - Left ADC Digital Vol */ |
58 | 0x00FF, /* R15 - Left ADC Digital Vol */ | 59 | { 16, 0x00FF }, /* R16 - Right ADC Digital Vol */ |
59 | 0x00FF, /* R16 - Right ADC Digital Vol */ | 60 | { 18, 0x012C }, /* R18 - EQ1 - low shelf */ |
60 | 0x0000, /* R17 */ | 61 | { 19, 0x002C }, /* R19 - EQ2 - peak 1 */ |
61 | 0x012C, /* R18 - EQ1 - low shelf */ | 62 | { 20, 0x002C }, /* R20 - EQ3 - peak 2 */ |
62 | 0x002C, /* R19 - EQ2 - peak 1 */ | 63 | { 21, 0x002C }, /* R21 - EQ4 - peak 3 */ |
63 | 0x002C, /* R20 - EQ3 - peak 2 */ | 64 | { 22, 0x002C }, /* R22 - EQ5 - high shelf */ |
64 | 0x002C, /* R21 - EQ4 - peak 3 */ | 65 | { 24, 0x0032 }, /* R24 - DAC Limiter 1 */ |
65 | 0x002C, /* R22 - EQ5 - high shelf */ | 66 | { 25, 0x0000 }, /* R25 - DAC Limiter 2 */ |
66 | 0x0000, /* R23 */ | 67 | { 27, 0x0000 }, /* R27 - Notch Filter 1 */ |
67 | 0x0032, /* R24 - DAC Limiter 1 */ | 68 | { 28, 0x0000 }, /* R28 - Notch Filter 2 */ |
68 | 0x0000, /* R25 - DAC Limiter 2 */ | 69 | { 29, 0x0000 }, /* R29 - Notch Filter 3 */ |
69 | 0x0000, /* R26 */ | 70 | { 30, 0x0000 }, /* R30 - Notch Filter 4 */ |
70 | 0x0000, /* R27 - Notch Filter 1 */ | 71 | { 32, 0x0038 }, /* R32 - ALC control 1 */ |
71 | 0x0000, /* R28 - Notch Filter 2 */ | 72 | { 33, 0x000B }, /* R33 - ALC control 2 */ |
72 | 0x0000, /* R29 - Notch Filter 3 */ | 73 | { 34, 0x0032 }, /* R34 - ALC control 3 */ |
73 | 0x0000, /* R30 - Notch Filter 4 */ | 74 | { 35, 0x0000 }, /* R35 - Noise Gate */ |
74 | 0x0000, /* R31 */ | 75 | { 36, 0x0008 }, /* R36 - PLL N */ |
75 | 0x0038, /* R32 - ALC control 1 */ | 76 | { 37, 0x000C }, /* R37 - PLL K 1 */ |
76 | 0x000B, /* R33 - ALC control 2 */ | 77 | { 38, 0x0093 }, /* R38 - PLL K 2 */ |
77 | 0x0032, /* R34 - ALC control 3 */ | 78 | { 39, 0x00E9 }, /* R39 - PLL K 3 */ |
78 | 0x0000, /* R35 - Noise Gate */ | 79 | { 41, 0x0000 }, /* R41 - 3D control */ |
79 | 0x0008, /* R36 - PLL N */ | 80 | { 42, 0x0000 }, /* R42 - OUT4 to ADC */ |
80 | 0x000C, /* R37 - PLL K 1 */ | 81 | { 43, 0x0000 }, /* R43 - Beep control */ |
81 | 0x0093, /* R38 - PLL K 2 */ | 82 | { 44, 0x0033 }, /* R44 - Input ctrl */ |
82 | 0x00E9, /* R39 - PLL K 3 */ | 83 | { 45, 0x0010 }, /* R45 - Left INP PGA gain ctrl */ |
83 | 0x0000, /* R40 */ | 84 | { 46, 0x0010 }, /* R46 - Right INP PGA gain ctrl */ |
84 | 0x0000, /* R41 - 3D control */ | 85 | { 47, 0x0100 }, /* R47 - Left ADC BOOST ctrl */ |
85 | 0x0000, /* R42 - OUT4 to ADC */ | 86 | { 48, 0x0100 }, /* R48 - Right ADC BOOST ctrl */ |
86 | 0x0000, /* R43 - Beep control */ | 87 | { 49, 0x0002 }, /* R49 - Output ctrl */ |
87 | 0x0033, /* R44 - Input ctrl */ | 88 | { 50, 0x0001 }, /* R50 - Left mixer ctrl */ |
88 | 0x0010, /* R45 - Left INP PGA gain ctrl */ | 89 | { 51, 0x0001 }, /* R51 - Right mixer ctrl */ |
89 | 0x0010, /* R46 - Right INP PGA gain ctrl */ | 90 | { 52, 0x0039 }, /* R52 - LOUT1 (HP) volume ctrl */ |
90 | 0x0100, /* R47 - Left ADC BOOST ctrl */ | 91 | { 53, 0x0039 }, /* R53 - ROUT1 (HP) volume ctrl */ |
91 | 0x0100, /* R48 - Right ADC BOOST ctrl */ | 92 | { 54, 0x0039 }, /* R54 - LOUT2 (SPK) volume ctrl */ |
92 | 0x0002, /* R49 - Output ctrl */ | 93 | { 55, 0x0039 }, /* R55 - ROUT2 (SPK) volume ctrl */ |
93 | 0x0001, /* R50 - Left mixer ctrl */ | 94 | { 56, 0x0001 }, /* R56 - OUT3 mixer ctrl */ |
94 | 0x0001, /* R51 - Right mixer ctrl */ | 95 | { 57, 0x0001 }, /* R57 - OUT4 (MONO) mix ctrl */ |
95 | 0x0039, /* R52 - LOUT1 (HP) volume ctrl */ | 96 | { 60, 0x0004 }, /* R60 - OUTPUT ctrl */ |
96 | 0x0039, /* R53 - ROUT1 (HP) volume ctrl */ | 97 | { 61, 0x0000 }, /* R61 - BIAS CTRL */ |
97 | 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */ | ||
98 | 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */ | ||
99 | 0x0001, /* R56 - OUT3 mixer ctrl */ | ||
100 | 0x0001, /* R57 - OUT4 (MONO) mix ctrl */ | ||
101 | 0x0001, /* R58 */ | ||
102 | 0x0000, /* R59 */ | ||
103 | 0x0004, /* R60 - OUTPUT ctrl */ | ||
104 | 0x0000, /* R61 - BIAS CTRL */ | ||
105 | 0x0180, /* R62 */ | ||
106 | 0x0000 /* R63 */ | ||
107 | }; | 98 | }; |
108 | 99 | ||
100 | static bool wm8985_writeable(struct device *dev, unsigned int reg) | ||
101 | { | ||
102 | switch (reg) { | ||
103 | case WM8985_SOFTWARE_RESET: | ||
104 | case WM8985_POWER_MANAGEMENT_1: | ||
105 | case WM8985_POWER_MANAGEMENT_2: | ||
106 | case WM8985_POWER_MANAGEMENT_3: | ||
107 | case WM8985_AUDIO_INTERFACE: | ||
108 | case WM8985_COMPANDING_CONTROL: | ||
109 | case WM8985_CLOCK_GEN_CONTROL: | ||
110 | case WM8985_ADDITIONAL_CONTROL: | ||
111 | case WM8985_GPIO_CONTROL: | ||
112 | case WM8985_JACK_DETECT_CONTROL_1: | ||
113 | case WM8985_DAC_CONTROL: | ||
114 | case WM8985_LEFT_DAC_DIGITAL_VOL: | ||
115 | case WM8985_RIGHT_DAC_DIGITAL_VOL: | ||
116 | case WM8985_JACK_DETECT_CONTROL_2: | ||
117 | case WM8985_ADC_CONTROL: | ||
118 | case WM8985_LEFT_ADC_DIGITAL_VOL: | ||
119 | case WM8985_RIGHT_ADC_DIGITAL_VOL: | ||
120 | case WM8985_EQ1_LOW_SHELF: | ||
121 | case WM8985_EQ2_PEAK_1: | ||
122 | case WM8985_EQ3_PEAK_2: | ||
123 | case WM8985_EQ4_PEAK_3: | ||
124 | case WM8985_EQ5_HIGH_SHELF: | ||
125 | case WM8985_DAC_LIMITER_1: | ||
126 | case WM8985_DAC_LIMITER_2: | ||
127 | case WM8985_NOTCH_FILTER_1: | ||
128 | case WM8985_NOTCH_FILTER_2: | ||
129 | case WM8985_NOTCH_FILTER_3: | ||
130 | case WM8985_NOTCH_FILTER_4: | ||
131 | case WM8985_ALC_CONTROL_1: | ||
132 | case WM8985_ALC_CONTROL_2: | ||
133 | case WM8985_ALC_CONTROL_3: | ||
134 | case WM8985_NOISE_GATE: | ||
135 | case WM8985_PLL_N: | ||
136 | case WM8985_PLL_K_1: | ||
137 | case WM8985_PLL_K_2: | ||
138 | case WM8985_PLL_K_3: | ||
139 | case WM8985_3D_CONTROL: | ||
140 | case WM8985_OUT4_TO_ADC: | ||
141 | case WM8985_BEEP_CONTROL: | ||
142 | case WM8985_INPUT_CTRL: | ||
143 | case WM8985_LEFT_INP_PGA_GAIN_CTRL: | ||
144 | case WM8985_RIGHT_INP_PGA_GAIN_CTRL: | ||
145 | case WM8985_LEFT_ADC_BOOST_CTRL: | ||
146 | case WM8985_RIGHT_ADC_BOOST_CTRL: | ||
147 | case WM8985_OUTPUT_CTRL0: | ||
148 | case WM8985_LEFT_MIXER_CTRL: | ||
149 | case WM8985_RIGHT_MIXER_CTRL: | ||
150 | case WM8985_LOUT1_HP_VOLUME_CTRL: | ||
151 | case WM8985_ROUT1_HP_VOLUME_CTRL: | ||
152 | case WM8985_LOUT2_SPK_VOLUME_CTRL: | ||
153 | case WM8985_ROUT2_SPK_VOLUME_CTRL: | ||
154 | case WM8985_OUT3_MIXER_CTRL: | ||
155 | case WM8985_OUT4_MONO_MIX_CTRL: | ||
156 | case WM8985_OUTPUT_CTRL1: | ||
157 | case WM8985_BIAS_CTRL: | ||
158 | return true; | ||
159 | default: | ||
160 | return false; | ||
161 | } | ||
162 | } | ||
163 | |||
109 | /* | 164 | /* |
110 | * latch bit 8 of these registers to ensure instant | 165 | * latch bit 8 of these registers to ensure instant |
111 | * volume updates | 166 | * volume updates |
@@ -124,7 +179,7 @@ static const int volume_update_regs[] = { | |||
124 | }; | 179 | }; |
125 | 180 | ||
126 | struct wm8985_priv { | 181 | struct wm8985_priv { |
127 | enum snd_soc_control_type control_type; | 182 | struct regmap *regmap; |
128 | struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES]; | 183 | struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES]; |
129 | unsigned int sysclk; | 184 | unsigned int sysclk; |
130 | unsigned int bclk; | 185 | unsigned int bclk; |
@@ -860,7 +915,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, | |||
860 | return ret; | 915 | return ret; |
861 | } | 916 | } |
862 | 917 | ||
863 | snd_soc_cache_sync(codec); | 918 | regcache_sync(wm8985->regmap); |
864 | 919 | ||
865 | /* enable anti-pop features */ | 920 | /* enable anti-pop features */ |
866 | snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC, | 921 | snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC, |
@@ -903,7 +958,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, | |||
903 | snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0); | 958 | snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0); |
904 | snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0); | 959 | snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0); |
905 | 960 | ||
906 | codec->cache_sync = 1; | 961 | regcache_mark_dirty(wm8985->regmap); |
907 | 962 | ||
908 | regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), | 963 | regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), |
909 | wm8985->supplies); | 964 | wm8985->supplies); |
@@ -948,8 +1003,9 @@ static int wm8985_probe(struct snd_soc_codec *codec) | |||
948 | int ret; | 1003 | int ret; |
949 | 1004 | ||
950 | wm8985 = snd_soc_codec_get_drvdata(codec); | 1005 | wm8985 = snd_soc_codec_get_drvdata(codec); |
1006 | codec->control_data = wm8985->regmap; | ||
951 | 1007 | ||
952 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8985->control_type); | 1008 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
953 | if (ret < 0) { | 1009 | if (ret < 0) { |
954 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); | 1010 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); |
955 | return ret; | 1011 | return ret; |
@@ -1037,14 +1093,23 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8985 = { | |||
1037 | .controls = wm8985_snd_controls, | 1093 | .controls = wm8985_snd_controls, |
1038 | .num_controls = ARRAY_SIZE(wm8985_snd_controls), | 1094 | .num_controls = ARRAY_SIZE(wm8985_snd_controls), |
1039 | .dapm_widgets = wm8985_dapm_widgets, | 1095 | .dapm_widgets = wm8985_dapm_widgets, |
1040 | .reg_cache_size = ARRAY_SIZE(wm8985_reg_defs), | ||
1041 | .reg_word_size = sizeof(u16), | ||
1042 | .reg_cache_default = wm8985_reg_defs | ||
1043 | .num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets), | 1096 | .num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets), |
1044 | .dapm_routes = wm8985_dapm_routes, | 1097 | .dapm_routes = wm8985_dapm_routes, |
1045 | .num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes), | 1098 | .num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes), |
1046 | }; | 1099 | }; |
1047 | 1100 | ||
1101 | static const struct regmap_config wm8985_regmap = { | ||
1102 | .reg_bits = 7, | ||
1103 | .val_bits = 9, | ||
1104 | |||
1105 | .max_register = WM8985_MAX_REGISTER, | ||
1106 | .writeable_reg = wm8985_writeable, | ||
1107 | |||
1108 | .cache_type = REGCACHE_RBTREE, | ||
1109 | .reg_defaults = wm8985_reg_defaults, | ||
1110 | .num_reg_defaults = ARRAY_SIZE(wm8985_reg_defaults), | ||
1111 | }; | ||
1112 | |||
1048 | #if defined(CONFIG_SPI_MASTER) | 1113 | #if defined(CONFIG_SPI_MASTER) |
1049 | static int __devinit wm8985_spi_probe(struct spi_device *spi) | 1114 | static int __devinit wm8985_spi_probe(struct spi_device *spi) |
1050 | { | 1115 | { |
@@ -1055,17 +1120,35 @@ static int __devinit wm8985_spi_probe(struct spi_device *spi) | |||
1055 | if (!wm8985) | 1120 | if (!wm8985) |
1056 | return -ENOMEM; | 1121 | return -ENOMEM; |
1057 | 1122 | ||
1058 | wm8985->control_type = SND_SOC_SPI; | ||
1059 | spi_set_drvdata(spi, wm8985); | 1123 | spi_set_drvdata(spi, wm8985); |
1060 | 1124 | ||
1125 | wm8985->regmap = regmap_init_spi(spi, &wm8985_regmap); | ||
1126 | if (IS_ERR(wm8985->regmap)) { | ||
1127 | ret = PTR_ERR(wm8985->regmap); | ||
1128 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", | ||
1129 | ret); | ||
1130 | goto err; | ||
1131 | } | ||
1132 | |||
1061 | ret = snd_soc_register_codec(&spi->dev, | 1133 | ret = snd_soc_register_codec(&spi->dev, |
1062 | &soc_codec_dev_wm8985, &wm8985_dai, 1); | 1134 | &soc_codec_dev_wm8985, &wm8985_dai, 1); |
1135 | if (ret != 0) | ||
1136 | goto err; | ||
1137 | |||
1138 | return 0; | ||
1139 | |||
1140 | err: | ||
1141 | regmap_exit(wm8985->regmap); | ||
1063 | return ret; | 1142 | return ret; |
1064 | } | 1143 | } |
1065 | 1144 | ||
1066 | static int __devexit wm8985_spi_remove(struct spi_device *spi) | 1145 | static int __devexit wm8985_spi_remove(struct spi_device *spi) |
1067 | { | 1146 | { |
1147 | struct wm8985_priv *wm8985 = spi_get_drvdata(spi); | ||
1148 | |||
1068 | snd_soc_unregister_codec(&spi->dev); | 1149 | snd_soc_unregister_codec(&spi->dev); |
1150 | regmap_exit(wm8985->regmap); | ||
1151 | |||
1069 | return 0; | 1152 | return 0; |
1070 | } | 1153 | } |
1071 | 1154 | ||
@@ -1090,17 +1173,35 @@ static __devinit int wm8985_i2c_probe(struct i2c_client *i2c, | |||
1090 | if (!wm8985) | 1173 | if (!wm8985) |
1091 | return -ENOMEM; | 1174 | return -ENOMEM; |
1092 | 1175 | ||
1093 | wm8985->control_type = SND_SOC_I2C; | ||
1094 | i2c_set_clientdata(i2c, wm8985); | 1176 | i2c_set_clientdata(i2c, wm8985); |
1095 | 1177 | ||
1178 | wm8985->regmap = regmap_init_i2c(i2c, &wm8985_regmap); | ||
1179 | if (IS_ERR(wm8985->regmap)) { | ||
1180 | ret = PTR_ERR(wm8985->regmap); | ||
1181 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
1182 | ret); | ||
1183 | goto err; | ||
1184 | } | ||
1185 | |||
1096 | ret = snd_soc_register_codec(&i2c->dev, | 1186 | ret = snd_soc_register_codec(&i2c->dev, |
1097 | &soc_codec_dev_wm8985, &wm8985_dai, 1); | 1187 | &soc_codec_dev_wm8985, &wm8985_dai, 1); |
1188 | if (ret != 0) | ||
1189 | goto err; | ||
1190 | |||
1191 | return 0; | ||
1192 | |||
1193 | err: | ||
1194 | regmap_exit(wm8985->regmap); | ||
1098 | return ret; | 1195 | return ret; |
1099 | } | 1196 | } |
1100 | 1197 | ||
1101 | static __devexit int wm8985_i2c_remove(struct i2c_client *client) | 1198 | static __devexit int wm8985_i2c_remove(struct i2c_client *i2c) |
1102 | { | 1199 | { |
1103 | snd_soc_unregister_codec(&client->dev); | 1200 | struct wm8985_priv *wm8985 = i2c_get_clientdata(i2c); |
1201 | |||
1202 | snd_soc_unregister_codec(&i2c->dev); | ||
1203 | regmap_exit(wm8985->regmap); | ||
1204 | |||
1104 | return 0; | 1205 | return 0; |
1105 | } | 1206 | } |
1106 | 1207 | ||