Commit 36633237be60c0ec88b11e00d5fa22a305563d03
Committed by
Mark Brown
1 parent
42aee9b43e
Exists in
master
and in
7 other branches
ASoC: sn95031: Add support for reading mic bias
This patch adds support to read the mic bias voltage when a jack is inserted. It uses ADC to measure. Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Harsha Priya <priya.harsha@intel.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Showing 2 changed files with 147 additions and 4 deletions Inline Diff
sound/soc/codecs/sn95031.c
1 | /* | 1 | /* |
2 | * sn95031.c - TI sn95031 Codec driver | 2 | * sn95031.c - TI sn95031 Codec driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Intel Corp | 4 | * Copyright (C) 2010 Intel Corp |
5 | * Author: Vinod Koul <vinod.koul@intel.com> | 5 | * Author: Vinod Koul <vinod.koul@intel.com> |
6 | * Author: Harsha Priya <priya.harsha@intel.com> | 6 | * Author: Harsha Priya <priya.harsha@intel.com> |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
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 as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; version 2 of the License. | 11 | * the Free Software Foundation; version 2 of the License. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, but | 13 | * This program is distributed in the hope that it will be useful, but |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | * General Public License for more details. | 16 | * General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License along | 18 | * You should have received a copy of the GNU General Public License along |
19 | * with this program; if not, write to the Free Software Foundation, Inc., | 19 | * with this program; if not, write to the Free Software Foundation, Inc., |
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | 20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
21 | * | 21 | * |
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
23 | * | 23 | * |
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
27 | 27 | ||
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <asm/intel_scu_ipc.h> | 30 | #include <asm/intel_scu_ipc.h> |
31 | #include <sound/pcm.h> | 31 | #include <sound/pcm.h> |
32 | #include <sound/pcm_params.h> | 32 | #include <sound/pcm_params.h> |
33 | #include <sound/soc.h> | 33 | #include <sound/soc.h> |
34 | #include <sound/soc-dapm.h> | 34 | #include <sound/soc-dapm.h> |
35 | #include <sound/initval.h> | 35 | #include <sound/initval.h> |
36 | #include <sound/tlv.h> | 36 | #include <sound/tlv.h> |
37 | #include <sound/jack.h> | 37 | #include <sound/jack.h> |
38 | #include "sn95031.h" | 38 | #include "sn95031.h" |
39 | 39 | ||
40 | #define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100) | 40 | #define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100) |
41 | #define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) | 41 | #define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) |
42 | 42 | ||
43 | /* adc helper functions */ | ||
44 | |||
45 | /* enables mic bias voltage */ | ||
46 | static void sn95031_enable_mic_bias(struct snd_soc_codec *codec) | ||
47 | { | ||
48 | snd_soc_write(codec, SN95031_VAUD, BIT(2)|BIT(1)|BIT(0)); | ||
49 | snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(2), BIT(2)); | ||
50 | } | ||
51 | |||
52 | /* Enable/Disable the ADC depending on the argument */ | ||
53 | static void configure_adc(struct snd_soc_codec *sn95031_codec, int val) | ||
54 | { | ||
55 | int value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1); | ||
56 | |||
57 | if (val) { | ||
58 | /* Enable and start the ADC */ | ||
59 | value |= (SN95031_ADC_ENBL | SN95031_ADC_START); | ||
60 | value &= (~SN95031_ADC_NO_LOOP); | ||
61 | } else { | ||
62 | /* Just stop the ADC */ | ||
63 | value &= (~SN95031_ADC_START); | ||
64 | } | ||
65 | snd_soc_write(sn95031_codec, SN95031_ADC1CNTL1, value); | ||
66 | } | ||
67 | |||
43 | /* | 68 | /* |
44 | * todo: | 69 | * finds an empty channel for conversion |
45 | * capture paths | 70 | * If the ADC is not enabled then start using 0th channel |
46 | * jack detection | 71 | * itself. Otherwise find an empty channel by looking for a |
47 | * PM functions | 72 | * channel in which the stopbit is set to 1. returns the index |
73 | * of the first free channel if succeeds or an error code. | ||
74 | * | ||
75 | * Context: can sleep | ||
76 | * | ||
48 | */ | 77 | */ |
78 | static int find_free_channel(struct snd_soc_codec *sn95031_codec) | ||
79 | { | ||
80 | int ret = 0, i, value; | ||
49 | 81 | ||
82 | /* check whether ADC is enabled */ | ||
83 | value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1); | ||
84 | |||
85 | if ((value & SN95031_ADC_ENBL) == 0) | ||
86 | return 0; | ||
87 | |||
88 | /* ADC is already enabled; Looking for an empty channel */ | ||
89 | for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) { | ||
90 | value = snd_soc_read(sn95031_codec, | ||
91 | SN95031_ADC_CHNL_START_ADDR + i); | ||
92 | if (value & SN95031_STOPBIT_MASK) { | ||
93 | ret = i; | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | return (ret > SN95031_ADC_LOOP_MAX) ? (-EINVAL) : ret; | ||
98 | } | ||
99 | |||
100 | /* Initialize the ADC for reading micbias values. Can sleep. */ | ||
101 | static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec) | ||
102 | { | ||
103 | int base_addr, chnl_addr; | ||
104 | int value; | ||
105 | static int channel_index; | ||
106 | |||
107 | /* Index of the first channel in which the stop bit is set */ | ||
108 | channel_index = find_free_channel(sn95031_codec); | ||
109 | if (channel_index < 0) { | ||
110 | pr_err("No free ADC channels"); | ||
111 | return channel_index; | ||
112 | } | ||
113 | |||
114 | base_addr = SN95031_ADC_CHNL_START_ADDR + channel_index; | ||
115 | |||
116 | if (!(channel_index == 0 || channel_index == SN95031_ADC_LOOP_MAX)) { | ||
117 | /* Reset stop bit for channels other than 0 and 12 */ | ||
118 | value = snd_soc_read(sn95031_codec, base_addr); | ||
119 | /* Set the stop bit to zero */ | ||
120 | snd_soc_write(sn95031_codec, base_addr, value & 0xEF); | ||
121 | /* Index of the first free channel */ | ||
122 | base_addr++; | ||
123 | channel_index++; | ||
124 | } | ||
125 | |||
126 | /* Since this is the last channel, set the stop bit | ||
127 | to 1 by ORing the DIE_SENSOR_CODE with 0x10 */ | ||
128 | snd_soc_write(sn95031_codec, base_addr, | ||
129 | SN95031_AUDIO_DETECT_CODE | 0x10); | ||
130 | |||
131 | chnl_addr = SN95031_ADC_DATA_START_ADDR + 2 * channel_index; | ||
132 | pr_debug("mid_initialize : %x", chnl_addr); | ||
133 | configure_adc(sn95031_codec, 1); | ||
134 | return chnl_addr; | ||
135 | } | ||
136 | |||
137 | |||
138 | /* reads the ADC registers and gets the mic bias value in mV. */ | ||
139 | static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec) | ||
140 | { | ||
141 | u16 adc_adr = sn95031_initialize_adc(codec); | ||
142 | u16 adc_val1, adc_val2; | ||
143 | unsigned int mic_bias; | ||
144 | |||
145 | sn95031_enable_mic_bias(codec); | ||
146 | |||
147 | /* Enable the sound card for conversion before reading */ | ||
148 | snd_soc_write(codec, SN95031_ADC1CNTL3, 0x05); | ||
149 | /* Re-toggle the RRDATARD bit */ | ||
150 | snd_soc_write(codec, SN95031_ADC1CNTL3, 0x04); | ||
151 | |||
152 | /* Read the higher bits of data */ | ||
153 | msleep(1000); | ||
154 | adc_val1 = snd_soc_read(codec, adc_adr); | ||
155 | adc_adr++; | ||
156 | adc_val2 = snd_soc_read(codec, adc_adr); | ||
157 | |||
158 | /* Adding lower two bits to the higher bits */ | ||
159 | mic_bias = (adc_val1 << 2) + (adc_val2 & 3); | ||
160 | mic_bias = (mic_bias * SN95031_ADC_ONE_LSB_MULTIPLIER) / 1000; | ||
161 | pr_debug("mic bias = %dmV\n", mic_bias); | ||
162 | return mic_bias; | ||
163 | } | ||
164 | EXPORT_SYMBOL_GPL(sn95031_get_mic_bias); | ||
165 | /*end - adc helper functions */ | ||
166 | |||
50 | static inline unsigned int sn95031_read(struct snd_soc_codec *codec, | 167 | static inline unsigned int sn95031_read(struct snd_soc_codec *codec, |
51 | unsigned int reg) | 168 | unsigned int reg) |
52 | { | 169 | { |
53 | u8 value = 0; | 170 | u8 value = 0; |
54 | int ret; | 171 | int ret; |
55 | 172 | ||
56 | ret = intel_scu_ipc_ioread8(reg, &value); | 173 | ret = intel_scu_ipc_ioread8(reg, &value); |
57 | if (ret) | 174 | if (ret) |
58 | pr_err("read of %x failed, err %d\n", reg, ret); | 175 | pr_err("read of %x failed, err %d\n", reg, ret); |
59 | return value; | 176 | return value; |
60 | 177 | ||
61 | } | 178 | } |
62 | 179 | ||
63 | static inline int sn95031_write(struct snd_soc_codec *codec, | 180 | static inline int sn95031_write(struct snd_soc_codec *codec, |
64 | unsigned int reg, unsigned int value) | 181 | unsigned int reg, unsigned int value) |
65 | { | 182 | { |
66 | int ret; | 183 | int ret; |
67 | 184 | ||
68 | ret = intel_scu_ipc_iowrite8(reg, value); | 185 | ret = intel_scu_ipc_iowrite8(reg, value); |
69 | if (ret) | 186 | if (ret) |
70 | pr_err("write of %x failed, err %d\n", reg, ret); | 187 | pr_err("write of %x failed, err %d\n", reg, ret); |
71 | return ret; | 188 | return ret; |
72 | } | 189 | } |
73 | 190 | ||
74 | static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, | 191 | static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, |
75 | enum snd_soc_bias_level level) | 192 | enum snd_soc_bias_level level) |
76 | { | 193 | { |
77 | switch (level) { | 194 | switch (level) { |
78 | case SND_SOC_BIAS_ON: | 195 | case SND_SOC_BIAS_ON: |
79 | break; | 196 | break; |
80 | 197 | ||
81 | case SND_SOC_BIAS_PREPARE: | 198 | case SND_SOC_BIAS_PREPARE: |
82 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { | 199 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { |
83 | pr_debug("vaud_bias powering up pll\n"); | 200 | pr_debug("vaud_bias powering up pll\n"); |
84 | /* power up the pll */ | 201 | /* power up the pll */ |
85 | snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5)); | 202 | snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5)); |
86 | /* enable pcm 2 */ | 203 | /* enable pcm 2 */ |
87 | snd_soc_update_bits(codec, SN95031_PCM2C2, | 204 | snd_soc_update_bits(codec, SN95031_PCM2C2, |
88 | BIT(0), BIT(0)); | 205 | BIT(0), BIT(0)); |
89 | } | 206 | } |
90 | break; | 207 | break; |
91 | 208 | ||
92 | case SND_SOC_BIAS_STANDBY: | 209 | case SND_SOC_BIAS_STANDBY: |
93 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 210 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
94 | pr_debug("vaud_bias power up rail\n"); | 211 | pr_debug("vaud_bias power up rail\n"); |
95 | /* power up the rail */ | 212 | /* power up the rail */ |
96 | snd_soc_write(codec, SN95031_VAUD, | 213 | snd_soc_write(codec, SN95031_VAUD, |
97 | BIT(2)|BIT(1)|BIT(0)); | 214 | BIT(2)|BIT(1)|BIT(0)); |
98 | msleep(1); | 215 | msleep(1); |
99 | } else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) { | 216 | } else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) { |
100 | /* turn off pcm */ | 217 | /* turn off pcm */ |
101 | pr_debug("vaud_bias power dn pcm\n"); | 218 | pr_debug("vaud_bias power dn pcm\n"); |
102 | snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0); | 219 | snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0); |
103 | snd_soc_write(codec, SN95031_AUDPLLCTRL, 0); | 220 | snd_soc_write(codec, SN95031_AUDPLLCTRL, 0); |
104 | } | 221 | } |
105 | break; | 222 | break; |
106 | 223 | ||
107 | 224 | ||
108 | case SND_SOC_BIAS_OFF: | 225 | case SND_SOC_BIAS_OFF: |
109 | pr_debug("vaud_bias _OFF doing rail shutdown\n"); | 226 | pr_debug("vaud_bias _OFF doing rail shutdown\n"); |
110 | snd_soc_write(codec, SN95031_VAUD, BIT(3)); | 227 | snd_soc_write(codec, SN95031_VAUD, BIT(3)); |
111 | break; | 228 | break; |
112 | } | 229 | } |
113 | 230 | ||
114 | codec->dapm.bias_level = level; | 231 | codec->dapm.bias_level = level; |
115 | return 0; | 232 | return 0; |
116 | } | 233 | } |
117 | 234 | ||
118 | static int sn95031_vhs_event(struct snd_soc_dapm_widget *w, | 235 | static int sn95031_vhs_event(struct snd_soc_dapm_widget *w, |
119 | struct snd_kcontrol *kcontrol, int event) | 236 | struct snd_kcontrol *kcontrol, int event) |
120 | { | 237 | { |
121 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 238 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
122 | pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); | 239 | pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); |
123 | /* power up the rail */ | 240 | /* power up the rail */ |
124 | snd_soc_write(w->codec, SN95031_VHSP, 0x3D); | 241 | snd_soc_write(w->codec, SN95031_VHSP, 0x3D); |
125 | snd_soc_write(w->codec, SN95031_VHSN, 0x3F); | 242 | snd_soc_write(w->codec, SN95031_VHSN, 0x3F); |
126 | msleep(1); | 243 | msleep(1); |
127 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { | 244 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { |
128 | pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); | 245 | pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); |
129 | snd_soc_write(w->codec, SN95031_VHSP, 0xC4); | 246 | snd_soc_write(w->codec, SN95031_VHSP, 0xC4); |
130 | snd_soc_write(w->codec, SN95031_VHSN, 0x04); | 247 | snd_soc_write(w->codec, SN95031_VHSN, 0x04); |
131 | } | 248 | } |
132 | return 0; | 249 | return 0; |
133 | } | 250 | } |
134 | 251 | ||
135 | static int sn95031_vihf_event(struct snd_soc_dapm_widget *w, | 252 | static int sn95031_vihf_event(struct snd_soc_dapm_widget *w, |
136 | struct snd_kcontrol *kcontrol, int event) | 253 | struct snd_kcontrol *kcontrol, int event) |
137 | { | 254 | { |
138 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 255 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
139 | pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); | 256 | pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); |
140 | /* power up the rail */ | 257 | /* power up the rail */ |
141 | snd_soc_write(w->codec, SN95031_VIHF, 0x27); | 258 | snd_soc_write(w->codec, SN95031_VIHF, 0x27); |
142 | msleep(1); | 259 | msleep(1); |
143 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { | 260 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { |
144 | pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); | 261 | pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); |
145 | snd_soc_write(w->codec, SN95031_VIHF, 0x24); | 262 | snd_soc_write(w->codec, SN95031_VIHF, 0x24); |
146 | } | 263 | } |
147 | return 0; | 264 | return 0; |
148 | } | 265 | } |
149 | 266 | ||
150 | static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w, | 267 | static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w, |
151 | struct snd_kcontrol *k, int event) | 268 | struct snd_kcontrol *k, int event) |
152 | { | 269 | { |
153 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; | 270 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; |
154 | 271 | ||
155 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 272 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
156 | ldo = BIT(5)|BIT(4); | 273 | ldo = BIT(5)|BIT(4); |
157 | clk_dir = BIT(0); | 274 | clk_dir = BIT(0); |
158 | data_dir = BIT(7); | 275 | data_dir = BIT(7); |
159 | } | 276 | } |
160 | /* program DMIC LDO, clock and set clock */ | 277 | /* program DMIC LDO, clock and set clock */ |
161 | snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); | 278 | snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); |
162 | snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir); | 279 | snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir); |
163 | snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir); | 280 | snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir); |
164 | return 0; | 281 | return 0; |
165 | } | 282 | } |
166 | 283 | ||
167 | static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w, | 284 | static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w, |
168 | struct snd_kcontrol *k, int event) | 285 | struct snd_kcontrol *k, int event) |
169 | { | 286 | { |
170 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; | 287 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; |
171 | 288 | ||
172 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 289 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
173 | ldo = BIT(5)|BIT(4); | 290 | ldo = BIT(5)|BIT(4); |
174 | clk_dir = BIT(2); | 291 | clk_dir = BIT(2); |
175 | data_dir = BIT(1); | 292 | data_dir = BIT(1); |
176 | } | 293 | } |
177 | /* program DMIC LDO, clock and set clock */ | 294 | /* program DMIC LDO, clock and set clock */ |
178 | snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); | 295 | snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); |
179 | snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir); | 296 | snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir); |
180 | snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir); | 297 | snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir); |
181 | return 0; | 298 | return 0; |
182 | } | 299 | } |
183 | 300 | ||
184 | static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w, | 301 | static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w, |
185 | struct snd_kcontrol *k, int event) | 302 | struct snd_kcontrol *k, int event) |
186 | { | 303 | { |
187 | unsigned int ldo = 0; | 304 | unsigned int ldo = 0; |
188 | 305 | ||
189 | if (SND_SOC_DAPM_EVENT_ON(event)) | 306 | if (SND_SOC_DAPM_EVENT_ON(event)) |
190 | ldo = BIT(7)|BIT(6); | 307 | ldo = BIT(7)|BIT(6); |
191 | 308 | ||
192 | /* program DMIC LDO */ | 309 | /* program DMIC LDO */ |
193 | snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo); | 310 | snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo); |
194 | return 0; | 311 | return 0; |
195 | } | 312 | } |
196 | 313 | ||
197 | /* mux controls */ | 314 | /* mux controls */ |
198 | static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" }; | 315 | static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" }; |
199 | 316 | ||
200 | static const struct soc_enum sn95031_micl_enum = | 317 | static const struct soc_enum sn95031_micl_enum = |
201 | SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 1, 2, sn95031_mic_texts); | 318 | SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 1, 2, sn95031_mic_texts); |
202 | 319 | ||
203 | static const struct snd_kcontrol_new sn95031_micl_mux_control = | 320 | static const struct snd_kcontrol_new sn95031_micl_mux_control = |
204 | SOC_DAPM_ENUM("Route", sn95031_micl_enum); | 321 | SOC_DAPM_ENUM("Route", sn95031_micl_enum); |
205 | 322 | ||
206 | static const struct soc_enum sn95031_micr_enum = | 323 | static const struct soc_enum sn95031_micr_enum = |
207 | SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 3, 2, sn95031_mic_texts); | 324 | SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 3, 2, sn95031_mic_texts); |
208 | 325 | ||
209 | static const struct snd_kcontrol_new sn95031_micr_mux_control = | 326 | static const struct snd_kcontrol_new sn95031_micr_mux_control = |
210 | SOC_DAPM_ENUM("Route", sn95031_micr_enum); | 327 | SOC_DAPM_ENUM("Route", sn95031_micr_enum); |
211 | 328 | ||
212 | static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3", | 329 | static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3", |
213 | "DMIC4", "DMIC5", "DMIC6", | 330 | "DMIC4", "DMIC5", "DMIC6", |
214 | "ADC Left", "ADC Right" }; | 331 | "ADC Left", "ADC Right" }; |
215 | 332 | ||
216 | static const struct soc_enum sn95031_input1_enum = | 333 | static const struct soc_enum sn95031_input1_enum = |
217 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 0, 8, sn95031_input_texts); | 334 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 0, 8, sn95031_input_texts); |
218 | 335 | ||
219 | static const struct snd_kcontrol_new sn95031_input1_mux_control = | 336 | static const struct snd_kcontrol_new sn95031_input1_mux_control = |
220 | SOC_DAPM_ENUM("Route", sn95031_input1_enum); | 337 | SOC_DAPM_ENUM("Route", sn95031_input1_enum); |
221 | 338 | ||
222 | static const struct soc_enum sn95031_input2_enum = | 339 | static const struct soc_enum sn95031_input2_enum = |
223 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 4, 8, sn95031_input_texts); | 340 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 4, 8, sn95031_input_texts); |
224 | 341 | ||
225 | static const struct snd_kcontrol_new sn95031_input2_mux_control = | 342 | static const struct snd_kcontrol_new sn95031_input2_mux_control = |
226 | SOC_DAPM_ENUM("Route", sn95031_input2_enum); | 343 | SOC_DAPM_ENUM("Route", sn95031_input2_enum); |
227 | 344 | ||
228 | static const struct soc_enum sn95031_input3_enum = | 345 | static const struct soc_enum sn95031_input3_enum = |
229 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 0, 8, sn95031_input_texts); | 346 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 0, 8, sn95031_input_texts); |
230 | 347 | ||
231 | static const struct snd_kcontrol_new sn95031_input3_mux_control = | 348 | static const struct snd_kcontrol_new sn95031_input3_mux_control = |
232 | SOC_DAPM_ENUM("Route", sn95031_input3_enum); | 349 | SOC_DAPM_ENUM("Route", sn95031_input3_enum); |
233 | 350 | ||
234 | static const struct soc_enum sn95031_input4_enum = | 351 | static const struct soc_enum sn95031_input4_enum = |
235 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 4, 8, sn95031_input_texts); | 352 | SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 4, 8, sn95031_input_texts); |
236 | 353 | ||
237 | static const struct snd_kcontrol_new sn95031_input4_mux_control = | 354 | static const struct snd_kcontrol_new sn95031_input4_mux_control = |
238 | SOC_DAPM_ENUM("Route", sn95031_input4_enum); | 355 | SOC_DAPM_ENUM("Route", sn95031_input4_enum); |
239 | 356 | ||
240 | /* capture path controls */ | 357 | /* capture path controls */ |
241 | 358 | ||
242 | static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"}; | 359 | static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"}; |
243 | 360 | ||
244 | /* 0dB to 30dB in 10dB steps */ | 361 | /* 0dB to 30dB in 10dB steps */ |
245 | static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 30); | 362 | static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 30); |
246 | 363 | ||
247 | static const struct soc_enum sn95031_micmode1_enum = | 364 | static const struct soc_enum sn95031_micmode1_enum = |
248 | SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text); | 365 | SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text); |
249 | static const struct soc_enum sn95031_micmode2_enum = | 366 | static const struct soc_enum sn95031_micmode2_enum = |
250 | SOC_ENUM_SINGLE(SN95031_MICAMP2, 1, 2, sn95031_micmode_text); | 367 | SOC_ENUM_SINGLE(SN95031_MICAMP2, 1, 2, sn95031_micmode_text); |
251 | 368 | ||
252 | static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"}; | 369 | static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"}; |
253 | 370 | ||
254 | static const struct soc_enum sn95031_dmic12_cfg_enum = | 371 | static const struct soc_enum sn95031_dmic12_cfg_enum = |
255 | SOC_ENUM_SINGLE(SN95031_DMICMUX, 0, 2, sn95031_dmic_cfg_text); | 372 | SOC_ENUM_SINGLE(SN95031_DMICMUX, 0, 2, sn95031_dmic_cfg_text); |
256 | static const struct soc_enum sn95031_dmic34_cfg_enum = | 373 | static const struct soc_enum sn95031_dmic34_cfg_enum = |
257 | SOC_ENUM_SINGLE(SN95031_DMICMUX, 1, 2, sn95031_dmic_cfg_text); | 374 | SOC_ENUM_SINGLE(SN95031_DMICMUX, 1, 2, sn95031_dmic_cfg_text); |
258 | static const struct soc_enum sn95031_dmic56_cfg_enum = | 375 | static const struct soc_enum sn95031_dmic56_cfg_enum = |
259 | SOC_ENUM_SINGLE(SN95031_DMICMUX, 2, 2, sn95031_dmic_cfg_text); | 376 | SOC_ENUM_SINGLE(SN95031_DMICMUX, 2, 2, sn95031_dmic_cfg_text); |
260 | 377 | ||
261 | static const struct snd_kcontrol_new sn95031_snd_controls[] = { | 378 | static const struct snd_kcontrol_new sn95031_snd_controls[] = { |
262 | SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum), | 379 | SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum), |
263 | SOC_ENUM("Mic2Mode Capture Route", sn95031_micmode2_enum), | 380 | SOC_ENUM("Mic2Mode Capture Route", sn95031_micmode2_enum), |
264 | SOC_ENUM("DMIC12 Capture Route", sn95031_dmic12_cfg_enum), | 381 | SOC_ENUM("DMIC12 Capture Route", sn95031_dmic12_cfg_enum), |
265 | SOC_ENUM("DMIC34 Capture Route", sn95031_dmic34_cfg_enum), | 382 | SOC_ENUM("DMIC34 Capture Route", sn95031_dmic34_cfg_enum), |
266 | SOC_ENUM("DMIC56 Capture Route", sn95031_dmic56_cfg_enum), | 383 | SOC_ENUM("DMIC56 Capture Route", sn95031_dmic56_cfg_enum), |
267 | SOC_SINGLE_TLV("Mic1 Capture Volume", SN95031_MICAMP1, | 384 | SOC_SINGLE_TLV("Mic1 Capture Volume", SN95031_MICAMP1, |
268 | 2, 4, 0, mic_tlv), | 385 | 2, 4, 0, mic_tlv), |
269 | SOC_SINGLE_TLV("Mic2 Capture Volume", SN95031_MICAMP2, | 386 | SOC_SINGLE_TLV("Mic2 Capture Volume", SN95031_MICAMP2, |
270 | 2, 4, 0, mic_tlv), | 387 | 2, 4, 0, mic_tlv), |
271 | }; | 388 | }; |
272 | 389 | ||
273 | /* DAPM widgets */ | 390 | /* DAPM widgets */ |
274 | static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = { | 391 | static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = { |
275 | 392 | ||
276 | /* all end points mic, hs etc */ | 393 | /* all end points mic, hs etc */ |
277 | SND_SOC_DAPM_OUTPUT("HPOUTL"), | 394 | SND_SOC_DAPM_OUTPUT("HPOUTL"), |
278 | SND_SOC_DAPM_OUTPUT("HPOUTR"), | 395 | SND_SOC_DAPM_OUTPUT("HPOUTR"), |
279 | SND_SOC_DAPM_OUTPUT("EPOUT"), | 396 | SND_SOC_DAPM_OUTPUT("EPOUT"), |
280 | SND_SOC_DAPM_OUTPUT("IHFOUTL"), | 397 | SND_SOC_DAPM_OUTPUT("IHFOUTL"), |
281 | SND_SOC_DAPM_OUTPUT("IHFOUTR"), | 398 | SND_SOC_DAPM_OUTPUT("IHFOUTR"), |
282 | SND_SOC_DAPM_OUTPUT("LINEOUTL"), | 399 | SND_SOC_DAPM_OUTPUT("LINEOUTL"), |
283 | SND_SOC_DAPM_OUTPUT("LINEOUTR"), | 400 | SND_SOC_DAPM_OUTPUT("LINEOUTR"), |
284 | SND_SOC_DAPM_OUTPUT("VIB1OUT"), | 401 | SND_SOC_DAPM_OUTPUT("VIB1OUT"), |
285 | SND_SOC_DAPM_OUTPUT("VIB2OUT"), | 402 | SND_SOC_DAPM_OUTPUT("VIB2OUT"), |
286 | 403 | ||
287 | SND_SOC_DAPM_INPUT("AMIC1"), /* headset mic */ | 404 | SND_SOC_DAPM_INPUT("AMIC1"), /* headset mic */ |
288 | SND_SOC_DAPM_INPUT("AMIC2"), | 405 | SND_SOC_DAPM_INPUT("AMIC2"), |
289 | SND_SOC_DAPM_INPUT("DMIC1"), | 406 | SND_SOC_DAPM_INPUT("DMIC1"), |
290 | SND_SOC_DAPM_INPUT("DMIC2"), | 407 | SND_SOC_DAPM_INPUT("DMIC2"), |
291 | SND_SOC_DAPM_INPUT("DMIC3"), | 408 | SND_SOC_DAPM_INPUT("DMIC3"), |
292 | SND_SOC_DAPM_INPUT("DMIC4"), | 409 | SND_SOC_DAPM_INPUT("DMIC4"), |
293 | SND_SOC_DAPM_INPUT("DMIC5"), | 410 | SND_SOC_DAPM_INPUT("DMIC5"), |
294 | SND_SOC_DAPM_INPUT("DMIC6"), | 411 | SND_SOC_DAPM_INPUT("DMIC6"), |
295 | SND_SOC_DAPM_INPUT("LINEINL"), | 412 | SND_SOC_DAPM_INPUT("LINEINL"), |
296 | SND_SOC_DAPM_INPUT("LINEINR"), | 413 | SND_SOC_DAPM_INPUT("LINEINR"), |
297 | 414 | ||
298 | SND_SOC_DAPM_MICBIAS("AMIC1Bias", SN95031_MICBIAS, 2, 0), | 415 | SND_SOC_DAPM_MICBIAS("AMIC1Bias", SN95031_MICBIAS, 2, 0), |
299 | SND_SOC_DAPM_MICBIAS("AMIC2Bias", SN95031_MICBIAS, 3, 0), | 416 | SND_SOC_DAPM_MICBIAS("AMIC2Bias", SN95031_MICBIAS, 3, 0), |
300 | SND_SOC_DAPM_MICBIAS("DMIC12Bias", SN95031_DMICMUX, 3, 0), | 417 | SND_SOC_DAPM_MICBIAS("DMIC12Bias", SN95031_DMICMUX, 3, 0), |
301 | SND_SOC_DAPM_MICBIAS("DMIC34Bias", SN95031_DMICMUX, 4, 0), | 418 | SND_SOC_DAPM_MICBIAS("DMIC34Bias", SN95031_DMICMUX, 4, 0), |
302 | SND_SOC_DAPM_MICBIAS("DMIC56Bias", SN95031_DMICMUX, 5, 0), | 419 | SND_SOC_DAPM_MICBIAS("DMIC56Bias", SN95031_DMICMUX, 5, 0), |
303 | 420 | ||
304 | SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0, | 421 | SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0, |
305 | sn95031_dmic12_event, | 422 | sn95031_dmic12_event, |
306 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 423 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
307 | SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0, | 424 | SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0, |
308 | sn95031_dmic34_event, | 425 | sn95031_dmic34_event, |
309 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 426 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
310 | SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0, | 427 | SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0, |
311 | sn95031_dmic56_event, | 428 | sn95031_dmic56_event, |
312 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 429 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
313 | 430 | ||
314 | SND_SOC_DAPM_AIF_OUT("PCM_Out", "Capture", 0, | 431 | SND_SOC_DAPM_AIF_OUT("PCM_Out", "Capture", 0, |
315 | SND_SOC_NOPM, 0, 0), | 432 | SND_SOC_NOPM, 0, 0), |
316 | 433 | ||
317 | SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0, | 434 | SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0, |
318 | sn95031_vhs_event, | 435 | sn95031_vhs_event, |
319 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 436 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
320 | SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0, | 437 | SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0, |
321 | sn95031_vihf_event, | 438 | sn95031_vihf_event, |
322 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 439 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
323 | 440 | ||
324 | /* playback path driver enables */ | 441 | /* playback path driver enables */ |
325 | SND_SOC_DAPM_PGA("Headset Left Playback", | 442 | SND_SOC_DAPM_PGA("Headset Left Playback", |
326 | SN95031_DRIVEREN, 0, 0, NULL, 0), | 443 | SN95031_DRIVEREN, 0, 0, NULL, 0), |
327 | SND_SOC_DAPM_PGA("Headset Right Playback", | 444 | SND_SOC_DAPM_PGA("Headset Right Playback", |
328 | SN95031_DRIVEREN, 1, 0, NULL, 0), | 445 | SN95031_DRIVEREN, 1, 0, NULL, 0), |
329 | SND_SOC_DAPM_PGA("Speaker Left Playback", | 446 | SND_SOC_DAPM_PGA("Speaker Left Playback", |
330 | SN95031_DRIVEREN, 2, 0, NULL, 0), | 447 | SN95031_DRIVEREN, 2, 0, NULL, 0), |
331 | SND_SOC_DAPM_PGA("Speaker Right Playback", | 448 | SND_SOC_DAPM_PGA("Speaker Right Playback", |
332 | SN95031_DRIVEREN, 3, 0, NULL, 0), | 449 | SN95031_DRIVEREN, 3, 0, NULL, 0), |
333 | SND_SOC_DAPM_PGA("Vibra1 Playback", | 450 | SND_SOC_DAPM_PGA("Vibra1 Playback", |
334 | SN95031_DRIVEREN, 4, 0, NULL, 0), | 451 | SN95031_DRIVEREN, 4, 0, NULL, 0), |
335 | SND_SOC_DAPM_PGA("Vibra2 Playback", | 452 | SND_SOC_DAPM_PGA("Vibra2 Playback", |
336 | SN95031_DRIVEREN, 5, 0, NULL, 0), | 453 | SN95031_DRIVEREN, 5, 0, NULL, 0), |
337 | SND_SOC_DAPM_PGA("Earpiece Playback", | 454 | SND_SOC_DAPM_PGA("Earpiece Playback", |
338 | SN95031_DRIVEREN, 6, 0, NULL, 0), | 455 | SN95031_DRIVEREN, 6, 0, NULL, 0), |
339 | SND_SOC_DAPM_PGA("Lineout Left Playback", | 456 | SND_SOC_DAPM_PGA("Lineout Left Playback", |
340 | SN95031_LOCTL, 0, 0, NULL, 0), | 457 | SN95031_LOCTL, 0, 0, NULL, 0), |
341 | SND_SOC_DAPM_PGA("Lineout Right Playback", | 458 | SND_SOC_DAPM_PGA("Lineout Right Playback", |
342 | SN95031_LOCTL, 4, 0, NULL, 0), | 459 | SN95031_LOCTL, 4, 0, NULL, 0), |
343 | 460 | ||
344 | /* playback path filter enable */ | 461 | /* playback path filter enable */ |
345 | SND_SOC_DAPM_PGA("Headset Left Filter", | 462 | SND_SOC_DAPM_PGA("Headset Left Filter", |
346 | SN95031_HSEPRXCTRL, 4, 0, NULL, 0), | 463 | SN95031_HSEPRXCTRL, 4, 0, NULL, 0), |
347 | SND_SOC_DAPM_PGA("Headset Right Filter", | 464 | SND_SOC_DAPM_PGA("Headset Right Filter", |
348 | SN95031_HSEPRXCTRL, 5, 0, NULL, 0), | 465 | SN95031_HSEPRXCTRL, 5, 0, NULL, 0), |
349 | SND_SOC_DAPM_PGA("Speaker Left Filter", | 466 | SND_SOC_DAPM_PGA("Speaker Left Filter", |
350 | SN95031_IHFRXCTRL, 0, 0, NULL, 0), | 467 | SN95031_IHFRXCTRL, 0, 0, NULL, 0), |
351 | SND_SOC_DAPM_PGA("Speaker Right Filter", | 468 | SND_SOC_DAPM_PGA("Speaker Right Filter", |
352 | SN95031_IHFRXCTRL, 1, 0, NULL, 0), | 469 | SN95031_IHFRXCTRL, 1, 0, NULL, 0), |
353 | 470 | ||
354 | /* DACs */ | 471 | /* DACs */ |
355 | SND_SOC_DAPM_DAC("HSDAC Left", "Headset", | 472 | SND_SOC_DAPM_DAC("HSDAC Left", "Headset", |
356 | SN95031_DACCONFIG, 0, 0), | 473 | SN95031_DACCONFIG, 0, 0), |
357 | SND_SOC_DAPM_DAC("HSDAC Right", "Headset", | 474 | SND_SOC_DAPM_DAC("HSDAC Right", "Headset", |
358 | SN95031_DACCONFIG, 1, 0), | 475 | SN95031_DACCONFIG, 1, 0), |
359 | SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker", | 476 | SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker", |
360 | SN95031_DACCONFIG, 2, 0), | 477 | SN95031_DACCONFIG, 2, 0), |
361 | SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker", | 478 | SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker", |
362 | SN95031_DACCONFIG, 3, 0), | 479 | SN95031_DACCONFIG, 3, 0), |
363 | SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1", | 480 | SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1", |
364 | SN95031_VIB1C5, 1, 0), | 481 | SN95031_VIB1C5, 1, 0), |
365 | SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2", | 482 | SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2", |
366 | SN95031_VIB2C5, 1, 0), | 483 | SN95031_VIB2C5, 1, 0), |
367 | 484 | ||
368 | /* capture widgets */ | 485 | /* capture widgets */ |
369 | SND_SOC_DAPM_PGA("LineIn Enable Left", SN95031_MICAMP1, | 486 | SND_SOC_DAPM_PGA("LineIn Enable Left", SN95031_MICAMP1, |
370 | 7, 0, NULL, 0), | 487 | 7, 0, NULL, 0), |
371 | SND_SOC_DAPM_PGA("LineIn Enable Right", SN95031_MICAMP2, | 488 | SND_SOC_DAPM_PGA("LineIn Enable Right", SN95031_MICAMP2, |
372 | 7, 0, NULL, 0), | 489 | 7, 0, NULL, 0), |
373 | 490 | ||
374 | SND_SOC_DAPM_PGA("MIC1 Enable", SN95031_MICAMP1, 0, 0, NULL, 0), | 491 | SND_SOC_DAPM_PGA("MIC1 Enable", SN95031_MICAMP1, 0, 0, NULL, 0), |
375 | SND_SOC_DAPM_PGA("MIC2 Enable", SN95031_MICAMP2, 0, 0, NULL, 0), | 492 | SND_SOC_DAPM_PGA("MIC2 Enable", SN95031_MICAMP2, 0, 0, NULL, 0), |
376 | SND_SOC_DAPM_PGA("TX1 Enable", SN95031_AUDIOTXEN, 2, 0, NULL, 0), | 493 | SND_SOC_DAPM_PGA("TX1 Enable", SN95031_AUDIOTXEN, 2, 0, NULL, 0), |
377 | SND_SOC_DAPM_PGA("TX2 Enable", SN95031_AUDIOTXEN, 3, 0, NULL, 0), | 494 | SND_SOC_DAPM_PGA("TX2 Enable", SN95031_AUDIOTXEN, 3, 0, NULL, 0), |
378 | SND_SOC_DAPM_PGA("TX3 Enable", SN95031_AUDIOTXEN, 4, 0, NULL, 0), | 495 | SND_SOC_DAPM_PGA("TX3 Enable", SN95031_AUDIOTXEN, 4, 0, NULL, 0), |
379 | SND_SOC_DAPM_PGA("TX4 Enable", SN95031_AUDIOTXEN, 5, 0, NULL, 0), | 496 | SND_SOC_DAPM_PGA("TX4 Enable", SN95031_AUDIOTXEN, 5, 0, NULL, 0), |
380 | 497 | ||
381 | /* ADC have null stream as they will be turned ON by TX path */ | 498 | /* ADC have null stream as they will be turned ON by TX path */ |
382 | SND_SOC_DAPM_ADC("ADC Left", NULL, | 499 | SND_SOC_DAPM_ADC("ADC Left", NULL, |
383 | SN95031_ADCCONFIG, 0, 0), | 500 | SN95031_ADCCONFIG, 0, 0), |
384 | SND_SOC_DAPM_ADC("ADC Right", NULL, | 501 | SND_SOC_DAPM_ADC("ADC Right", NULL, |
385 | SN95031_ADCCONFIG, 2, 0), | 502 | SN95031_ADCCONFIG, 2, 0), |
386 | 503 | ||
387 | SND_SOC_DAPM_MUX("Mic_InputL Capture Route", | 504 | SND_SOC_DAPM_MUX("Mic_InputL Capture Route", |
388 | SND_SOC_NOPM, 0, 0, &sn95031_micl_mux_control), | 505 | SND_SOC_NOPM, 0, 0, &sn95031_micl_mux_control), |
389 | SND_SOC_DAPM_MUX("Mic_InputR Capture Route", | 506 | SND_SOC_DAPM_MUX("Mic_InputR Capture Route", |
390 | SND_SOC_NOPM, 0, 0, &sn95031_micr_mux_control), | 507 | SND_SOC_NOPM, 0, 0, &sn95031_micr_mux_control), |
391 | 508 | ||
392 | SND_SOC_DAPM_MUX("Txpath1 Capture Route", | 509 | SND_SOC_DAPM_MUX("Txpath1 Capture Route", |
393 | SND_SOC_NOPM, 0, 0, &sn95031_input1_mux_control), | 510 | SND_SOC_NOPM, 0, 0, &sn95031_input1_mux_control), |
394 | SND_SOC_DAPM_MUX("Txpath2 Capture Route", | 511 | SND_SOC_DAPM_MUX("Txpath2 Capture Route", |
395 | SND_SOC_NOPM, 0, 0, &sn95031_input2_mux_control), | 512 | SND_SOC_NOPM, 0, 0, &sn95031_input2_mux_control), |
396 | SND_SOC_DAPM_MUX("Txpath3 Capture Route", | 513 | SND_SOC_DAPM_MUX("Txpath3 Capture Route", |
397 | SND_SOC_NOPM, 0, 0, &sn95031_input3_mux_control), | 514 | SND_SOC_NOPM, 0, 0, &sn95031_input3_mux_control), |
398 | SND_SOC_DAPM_MUX("Txpath4 Capture Route", | 515 | SND_SOC_DAPM_MUX("Txpath4 Capture Route", |
399 | SND_SOC_NOPM, 0, 0, &sn95031_input4_mux_control), | 516 | SND_SOC_NOPM, 0, 0, &sn95031_input4_mux_control), |
400 | 517 | ||
401 | }; | 518 | }; |
402 | 519 | ||
403 | static const struct snd_soc_dapm_route sn95031_audio_map[] = { | 520 | static const struct snd_soc_dapm_route sn95031_audio_map[] = { |
404 | /* headset and earpiece map */ | 521 | /* headset and earpiece map */ |
405 | { "HPOUTL", NULL, "Headset Left Playback" }, | 522 | { "HPOUTL", NULL, "Headset Left Playback" }, |
406 | { "HPOUTR", NULL, "Headset Right Playback" }, | 523 | { "HPOUTR", NULL, "Headset Right Playback" }, |
407 | { "EPOUT", NULL, "Earpiece Playback" }, | 524 | { "EPOUT", NULL, "Earpiece Playback" }, |
408 | { "Headset Left Playback", NULL, "Headset Left Filter"}, | 525 | { "Headset Left Playback", NULL, "Headset Left Filter"}, |
409 | { "Headset Right Playback", NULL, "Headset Right Filter"}, | 526 | { "Headset Right Playback", NULL, "Headset Right Filter"}, |
410 | { "Earpiece Playback", NULL, "Headset Left Filter"}, | 527 | { "Earpiece Playback", NULL, "Headset Left Filter"}, |
411 | { "Headset Left Filter", NULL, "HSDAC Left"}, | 528 | { "Headset Left Filter", NULL, "HSDAC Left"}, |
412 | { "Headset Right Filter", NULL, "HSDAC Right"}, | 529 | { "Headset Right Filter", NULL, "HSDAC Right"}, |
413 | { "HSDAC Left", NULL, "Headset Rail"}, | 530 | { "HSDAC Left", NULL, "Headset Rail"}, |
414 | { "HSDAC Right", NULL, "Headset Rail"}, | 531 | { "HSDAC Right", NULL, "Headset Rail"}, |
415 | 532 | ||
416 | /* speaker map */ | 533 | /* speaker map */ |
417 | { "IHFOUTL", "NULL", "Speaker Left Playback"}, | 534 | { "IHFOUTL", "NULL", "Speaker Left Playback"}, |
418 | { "IHFOUTR", "NULL", "Speaker Right Playback"}, | 535 | { "IHFOUTR", "NULL", "Speaker Right Playback"}, |
419 | { "Speaker Left Playback", NULL, "Speaker Left Filter"}, | 536 | { "Speaker Left Playback", NULL, "Speaker Left Filter"}, |
420 | { "Speaker Right Playback", NULL, "Speaker Right Filter"}, | 537 | { "Speaker Right Playback", NULL, "Speaker Right Filter"}, |
421 | { "Speaker Left Filter", NULL, "IHFDAC Left"}, | 538 | { "Speaker Left Filter", NULL, "IHFDAC Left"}, |
422 | { "Speaker Right Filter", NULL, "IHFDAC Right"}, | 539 | { "Speaker Right Filter", NULL, "IHFDAC Right"}, |
423 | { "IHFDAC Left", NULL, "Speaker Rail"}, | 540 | { "IHFDAC Left", NULL, "Speaker Rail"}, |
424 | { "IHFDAC Right", NULL, "Speaker Rail"}, | 541 | { "IHFDAC Right", NULL, "Speaker Rail"}, |
425 | 542 | ||
426 | /* vibra map */ | 543 | /* vibra map */ |
427 | { "VIB1OUT", NULL, "Vibra1 Playback"}, | 544 | { "VIB1OUT", NULL, "Vibra1 Playback"}, |
428 | { "Vibra1 Playback", NULL, "Vibra1 DAC"}, | 545 | { "Vibra1 Playback", NULL, "Vibra1 DAC"}, |
429 | 546 | ||
430 | { "VIB2OUT", NULL, "Vibra2 Playback"}, | 547 | { "VIB2OUT", NULL, "Vibra2 Playback"}, |
431 | { "Vibra2 Playback", NULL, "Vibra2 DAC"}, | 548 | { "Vibra2 Playback", NULL, "Vibra2 DAC"}, |
432 | 549 | ||
433 | /* lineout */ | 550 | /* lineout */ |
434 | { "LINEOUTL", NULL, "Lineout Left Playback"}, | 551 | { "LINEOUTL", NULL, "Lineout Left Playback"}, |
435 | { "LINEOUTR", NULL, "Lineout Right Playback"}, | 552 | { "LINEOUTR", NULL, "Lineout Right Playback"}, |
436 | { "Lineout Left Playback", NULL, "Headset Left Filter"}, | 553 | { "Lineout Left Playback", NULL, "Headset Left Filter"}, |
437 | { "Lineout Left Playback", NULL, "Speaker Left Filter"}, | 554 | { "Lineout Left Playback", NULL, "Speaker Left Filter"}, |
438 | { "Lineout Left Playback", NULL, "Vibra1 DAC"}, | 555 | { "Lineout Left Playback", NULL, "Vibra1 DAC"}, |
439 | { "Lineout Right Playback", NULL, "Headset Right Filter"}, | 556 | { "Lineout Right Playback", NULL, "Headset Right Filter"}, |
440 | { "Lineout Right Playback", NULL, "Speaker Right Filter"}, | 557 | { "Lineout Right Playback", NULL, "Speaker Right Filter"}, |
441 | { "Lineout Right Playback", NULL, "Vibra2 DAC"}, | 558 | { "Lineout Right Playback", NULL, "Vibra2 DAC"}, |
442 | 559 | ||
443 | /* Headset (AMIC1) mic */ | 560 | /* Headset (AMIC1) mic */ |
444 | { "AMIC1Bias", NULL, "AMIC1"}, | 561 | { "AMIC1Bias", NULL, "AMIC1"}, |
445 | { "MIC1 Enable", NULL, "AMIC1Bias"}, | 562 | { "MIC1 Enable", NULL, "AMIC1Bias"}, |
446 | { "Mic_InputL Capture Route", "AMIC", "MIC1 Enable"}, | 563 | { "Mic_InputL Capture Route", "AMIC", "MIC1 Enable"}, |
447 | 564 | ||
448 | /* AMIC2 */ | 565 | /* AMIC2 */ |
449 | { "AMIC2Bias", NULL, "AMIC2"}, | 566 | { "AMIC2Bias", NULL, "AMIC2"}, |
450 | { "MIC2 Enable", NULL, "AMIC2Bias"}, | 567 | { "MIC2 Enable", NULL, "AMIC2Bias"}, |
451 | { "Mic_InputR Capture Route", "AMIC", "MIC2 Enable"}, | 568 | { "Mic_InputR Capture Route", "AMIC", "MIC2 Enable"}, |
452 | 569 | ||
453 | 570 | ||
454 | /* Linein */ | 571 | /* Linein */ |
455 | { "LineIn Enable Left", NULL, "LINEINL"}, | 572 | { "LineIn Enable Left", NULL, "LINEINL"}, |
456 | { "LineIn Enable Right", NULL, "LINEINR"}, | 573 | { "LineIn Enable Right", NULL, "LINEINR"}, |
457 | { "Mic_InputL Capture Route", "LineIn", "LineIn Enable Left"}, | 574 | { "Mic_InputL Capture Route", "LineIn", "LineIn Enable Left"}, |
458 | { "Mic_InputR Capture Route", "LineIn", "LineIn Enable Right"}, | 575 | { "Mic_InputR Capture Route", "LineIn", "LineIn Enable Right"}, |
459 | 576 | ||
460 | /* ADC connection */ | 577 | /* ADC connection */ |
461 | { "ADC Left", NULL, "Mic_InputL Capture Route"}, | 578 | { "ADC Left", NULL, "Mic_InputL Capture Route"}, |
462 | { "ADC Right", NULL, "Mic_InputR Capture Route"}, | 579 | { "ADC Right", NULL, "Mic_InputR Capture Route"}, |
463 | 580 | ||
464 | /*DMIC connections */ | 581 | /*DMIC connections */ |
465 | { "DMIC1", NULL, "DMIC12supply"}, | 582 | { "DMIC1", NULL, "DMIC12supply"}, |
466 | { "DMIC2", NULL, "DMIC12supply"}, | 583 | { "DMIC2", NULL, "DMIC12supply"}, |
467 | { "DMIC3", NULL, "DMIC34supply"}, | 584 | { "DMIC3", NULL, "DMIC34supply"}, |
468 | { "DMIC4", NULL, "DMIC34supply"}, | 585 | { "DMIC4", NULL, "DMIC34supply"}, |
469 | { "DMIC5", NULL, "DMIC56supply"}, | 586 | { "DMIC5", NULL, "DMIC56supply"}, |
470 | { "DMIC6", NULL, "DMIC56supply"}, | 587 | { "DMIC6", NULL, "DMIC56supply"}, |
471 | 588 | ||
472 | { "DMIC12Bias", NULL, "DMIC1"}, | 589 | { "DMIC12Bias", NULL, "DMIC1"}, |
473 | { "DMIC12Bias", NULL, "DMIC2"}, | 590 | { "DMIC12Bias", NULL, "DMIC2"}, |
474 | { "DMIC34Bias", NULL, "DMIC3"}, | 591 | { "DMIC34Bias", NULL, "DMIC3"}, |
475 | { "DMIC34Bias", NULL, "DMIC4"}, | 592 | { "DMIC34Bias", NULL, "DMIC4"}, |
476 | { "DMIC56Bias", NULL, "DMIC5"}, | 593 | { "DMIC56Bias", NULL, "DMIC5"}, |
477 | { "DMIC56Bias", NULL, "DMIC6"}, | 594 | { "DMIC56Bias", NULL, "DMIC6"}, |
478 | 595 | ||
479 | /*TX path inputs*/ | 596 | /*TX path inputs*/ |
480 | { "Txpath1 Capture Route", "ADC Left", "ADC Left"}, | 597 | { "Txpath1 Capture Route", "ADC Left", "ADC Left"}, |
481 | { "Txpath2 Capture Route", "ADC Left", "ADC Left"}, | 598 | { "Txpath2 Capture Route", "ADC Left", "ADC Left"}, |
482 | { "Txpath3 Capture Route", "ADC Left", "ADC Left"}, | 599 | { "Txpath3 Capture Route", "ADC Left", "ADC Left"}, |
483 | { "Txpath4 Capture Route", "ADC Left", "ADC Left"}, | 600 | { "Txpath4 Capture Route", "ADC Left", "ADC Left"}, |
484 | { "Txpath1 Capture Route", "ADC Right", "ADC Right"}, | 601 | { "Txpath1 Capture Route", "ADC Right", "ADC Right"}, |
485 | { "Txpath2 Capture Route", "ADC Right", "ADC Right"}, | 602 | { "Txpath2 Capture Route", "ADC Right", "ADC Right"}, |
486 | { "Txpath3 Capture Route", "ADC Right", "ADC Right"}, | 603 | { "Txpath3 Capture Route", "ADC Right", "ADC Right"}, |
487 | { "Txpath4 Capture Route", "ADC Right", "ADC Right"}, | 604 | { "Txpath4 Capture Route", "ADC Right", "ADC Right"}, |
488 | { "Txpath1 Capture Route", NULL, "DMIC1"}, | 605 | { "Txpath1 Capture Route", NULL, "DMIC1"}, |
489 | { "Txpath2 Capture Route", NULL, "DMIC1"}, | 606 | { "Txpath2 Capture Route", NULL, "DMIC1"}, |
490 | { "Txpath3 Capture Route", NULL, "DMIC1"}, | 607 | { "Txpath3 Capture Route", NULL, "DMIC1"}, |
491 | { "Txpath4 Capture Route", NULL, "DMIC1"}, | 608 | { "Txpath4 Capture Route", NULL, "DMIC1"}, |
492 | { "Txpath1 Capture Route", NULL, "DMIC2"}, | 609 | { "Txpath1 Capture Route", NULL, "DMIC2"}, |
493 | { "Txpath2 Capture Route", NULL, "DMIC2"}, | 610 | { "Txpath2 Capture Route", NULL, "DMIC2"}, |
494 | { "Txpath3 Capture Route", NULL, "DMIC2"}, | 611 | { "Txpath3 Capture Route", NULL, "DMIC2"}, |
495 | { "Txpath4 Capture Route", NULL, "DMIC2"}, | 612 | { "Txpath4 Capture Route", NULL, "DMIC2"}, |
496 | { "Txpath1 Capture Route", NULL, "DMIC3"}, | 613 | { "Txpath1 Capture Route", NULL, "DMIC3"}, |
497 | { "Txpath2 Capture Route", NULL, "DMIC3"}, | 614 | { "Txpath2 Capture Route", NULL, "DMIC3"}, |
498 | { "Txpath3 Capture Route", NULL, "DMIC3"}, | 615 | { "Txpath3 Capture Route", NULL, "DMIC3"}, |
499 | { "Txpath4 Capture Route", NULL, "DMIC3"}, | 616 | { "Txpath4 Capture Route", NULL, "DMIC3"}, |
500 | { "Txpath1 Capture Route", NULL, "DMIC4"}, | 617 | { "Txpath1 Capture Route", NULL, "DMIC4"}, |
501 | { "Txpath2 Capture Route", NULL, "DMIC4"}, | 618 | { "Txpath2 Capture Route", NULL, "DMIC4"}, |
502 | { "Txpath3 Capture Route", NULL, "DMIC4"}, | 619 | { "Txpath3 Capture Route", NULL, "DMIC4"}, |
503 | { "Txpath4 Capture Route", NULL, "DMIC4"}, | 620 | { "Txpath4 Capture Route", NULL, "DMIC4"}, |
504 | { "Txpath1 Capture Route", NULL, "DMIC5"}, | 621 | { "Txpath1 Capture Route", NULL, "DMIC5"}, |
505 | { "Txpath2 Capture Route", NULL, "DMIC5"}, | 622 | { "Txpath2 Capture Route", NULL, "DMIC5"}, |
506 | { "Txpath3 Capture Route", NULL, "DMIC5"}, | 623 | { "Txpath3 Capture Route", NULL, "DMIC5"}, |
507 | { "Txpath4 Capture Route", NULL, "DMIC5"}, | 624 | { "Txpath4 Capture Route", NULL, "DMIC5"}, |
508 | { "Txpath1 Capture Route", NULL, "DMIC6"}, | 625 | { "Txpath1 Capture Route", NULL, "DMIC6"}, |
509 | { "Txpath2 Capture Route", NULL, "DMIC6"}, | 626 | { "Txpath2 Capture Route", NULL, "DMIC6"}, |
510 | { "Txpath3 Capture Route", NULL, "DMIC6"}, | 627 | { "Txpath3 Capture Route", NULL, "DMIC6"}, |
511 | { "Txpath4 Capture Route", NULL, "DMIC6"}, | 628 | { "Txpath4 Capture Route", NULL, "DMIC6"}, |
512 | 629 | ||
513 | /* tx path */ | 630 | /* tx path */ |
514 | { "TX1 Enable", NULL, "Txpath1 Capture Route"}, | 631 | { "TX1 Enable", NULL, "Txpath1 Capture Route"}, |
515 | { "TX2 Enable", NULL, "Txpath2 Capture Route"}, | 632 | { "TX2 Enable", NULL, "Txpath2 Capture Route"}, |
516 | { "TX3 Enable", NULL, "Txpath3 Capture Route"}, | 633 | { "TX3 Enable", NULL, "Txpath3 Capture Route"}, |
517 | { "TX4 Enable", NULL, "Txpath4 Capture Route"}, | 634 | { "TX4 Enable", NULL, "Txpath4 Capture Route"}, |
518 | { "PCM_Out", NULL, "TX1 Enable"}, | 635 | { "PCM_Out", NULL, "TX1 Enable"}, |
519 | { "PCM_Out", NULL, "TX2 Enable"}, | 636 | { "PCM_Out", NULL, "TX2 Enable"}, |
520 | { "PCM_Out", NULL, "TX3 Enable"}, | 637 | { "PCM_Out", NULL, "TX3 Enable"}, |
521 | { "PCM_Out", NULL, "TX4 Enable"}, | 638 | { "PCM_Out", NULL, "TX4 Enable"}, |
522 | 639 | ||
523 | }; | 640 | }; |
524 | 641 | ||
525 | /* speaker and headset mutes, for audio pops and clicks */ | 642 | /* speaker and headset mutes, for audio pops and clicks */ |
526 | static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute) | 643 | static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute) |
527 | { | 644 | { |
528 | snd_soc_update_bits(dai->codec, | 645 | snd_soc_update_bits(dai->codec, |
529 | SN95031_HSLVOLCTRL, BIT(7), (!mute << 7)); | 646 | SN95031_HSLVOLCTRL, BIT(7), (!mute << 7)); |
530 | snd_soc_update_bits(dai->codec, | 647 | snd_soc_update_bits(dai->codec, |
531 | SN95031_HSRVOLCTRL, BIT(7), (!mute << 7)); | 648 | SN95031_HSRVOLCTRL, BIT(7), (!mute << 7)); |
532 | return 0; | 649 | return 0; |
533 | } | 650 | } |
534 | 651 | ||
535 | static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute) | 652 | static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute) |
536 | { | 653 | { |
537 | snd_soc_update_bits(dai->codec, | 654 | snd_soc_update_bits(dai->codec, |
538 | SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7)); | 655 | SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7)); |
539 | snd_soc_update_bits(dai->codec, | 656 | snd_soc_update_bits(dai->codec, |
540 | SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7)); | 657 | SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7)); |
541 | return 0; | 658 | return 0; |
542 | } | 659 | } |
543 | 660 | ||
544 | int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, | 661 | int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, |
545 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 662 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
546 | { | 663 | { |
547 | unsigned int format, rate; | 664 | unsigned int format, rate; |
548 | 665 | ||
549 | switch (params_format(params)) { | 666 | switch (params_format(params)) { |
550 | case SNDRV_PCM_FORMAT_S16_LE: | 667 | case SNDRV_PCM_FORMAT_S16_LE: |
551 | format = BIT(4)|BIT(5); | 668 | format = BIT(4)|BIT(5); |
552 | break; | 669 | break; |
553 | 670 | ||
554 | case SNDRV_PCM_FORMAT_S24_LE: | 671 | case SNDRV_PCM_FORMAT_S24_LE: |
555 | format = 0; | 672 | format = 0; |
556 | break; | 673 | break; |
557 | default: | 674 | default: |
558 | return -EINVAL; | 675 | return -EINVAL; |
559 | } | 676 | } |
560 | snd_soc_update_bits(dai->codec, SN95031_PCM2C2, | 677 | snd_soc_update_bits(dai->codec, SN95031_PCM2C2, |
561 | BIT(4)|BIT(5), format); | 678 | BIT(4)|BIT(5), format); |
562 | 679 | ||
563 | switch (params_rate(params)) { | 680 | switch (params_rate(params)) { |
564 | case 48000: | 681 | case 48000: |
565 | pr_debug("RATE_48000\n"); | 682 | pr_debug("RATE_48000\n"); |
566 | rate = 0; | 683 | rate = 0; |
567 | break; | 684 | break; |
568 | 685 | ||
569 | case 44100: | 686 | case 44100: |
570 | pr_debug("RATE_44100\n"); | 687 | pr_debug("RATE_44100\n"); |
571 | rate = BIT(7); | 688 | rate = BIT(7); |
572 | break; | 689 | break; |
573 | 690 | ||
574 | default: | 691 | default: |
575 | pr_err("ERR rate %d\n", params_rate(params)); | 692 | pr_err("ERR rate %d\n", params_rate(params)); |
576 | return -EINVAL; | 693 | return -EINVAL; |
577 | } | 694 | } |
578 | snd_soc_update_bits(dai->codec, SN95031_PCM1C1, BIT(7), rate); | 695 | snd_soc_update_bits(dai->codec, SN95031_PCM1C1, BIT(7), rate); |
579 | 696 | ||
580 | return 0; | 697 | return 0; |
581 | } | 698 | } |
582 | 699 | ||
583 | /* Codec DAI section */ | 700 | /* Codec DAI section */ |
584 | static struct snd_soc_dai_ops sn95031_headset_dai_ops = { | 701 | static struct snd_soc_dai_ops sn95031_headset_dai_ops = { |
585 | .digital_mute = sn95031_pcm_hs_mute, | 702 | .digital_mute = sn95031_pcm_hs_mute, |
586 | .hw_params = sn95031_pcm_hw_params, | 703 | .hw_params = sn95031_pcm_hw_params, |
587 | }; | 704 | }; |
588 | 705 | ||
589 | static struct snd_soc_dai_ops sn95031_speaker_dai_ops = { | 706 | static struct snd_soc_dai_ops sn95031_speaker_dai_ops = { |
590 | .digital_mute = sn95031_pcm_spkr_mute, | 707 | .digital_mute = sn95031_pcm_spkr_mute, |
591 | .hw_params = sn95031_pcm_hw_params, | 708 | .hw_params = sn95031_pcm_hw_params, |
592 | }; | 709 | }; |
593 | 710 | ||
594 | static struct snd_soc_dai_ops sn95031_vib1_dai_ops = { | 711 | static struct snd_soc_dai_ops sn95031_vib1_dai_ops = { |
595 | .hw_params = sn95031_pcm_hw_params, | 712 | .hw_params = sn95031_pcm_hw_params, |
596 | }; | 713 | }; |
597 | 714 | ||
598 | static struct snd_soc_dai_ops sn95031_vib2_dai_ops = { | 715 | static struct snd_soc_dai_ops sn95031_vib2_dai_ops = { |
599 | .hw_params = sn95031_pcm_hw_params, | 716 | .hw_params = sn95031_pcm_hw_params, |
600 | }; | 717 | }; |
601 | 718 | ||
602 | struct snd_soc_dai_driver sn95031_dais[] = { | 719 | struct snd_soc_dai_driver sn95031_dais[] = { |
603 | { | 720 | { |
604 | .name = "SN95031 Headset", | 721 | .name = "SN95031 Headset", |
605 | .playback = { | 722 | .playback = { |
606 | .stream_name = "Headset", | 723 | .stream_name = "Headset", |
607 | .channels_min = 2, | 724 | .channels_min = 2, |
608 | .channels_max = 2, | 725 | .channels_max = 2, |
609 | .rates = SN95031_RATES, | 726 | .rates = SN95031_RATES, |
610 | .formats = SN95031_FORMATS, | 727 | .formats = SN95031_FORMATS, |
611 | }, | 728 | }, |
612 | .capture = { | 729 | .capture = { |
613 | .stream_name = "Capture", | 730 | .stream_name = "Capture", |
614 | .channels_min = 1, | 731 | .channels_min = 1, |
615 | .channels_max = 5, | 732 | .channels_max = 5, |
616 | .rates = SN95031_RATES, | 733 | .rates = SN95031_RATES, |
617 | .formats = SN95031_FORMATS, | 734 | .formats = SN95031_FORMATS, |
618 | }, | 735 | }, |
619 | .ops = &sn95031_headset_dai_ops, | 736 | .ops = &sn95031_headset_dai_ops, |
620 | }, | 737 | }, |
621 | { .name = "SN95031 Speaker", | 738 | { .name = "SN95031 Speaker", |
622 | .playback = { | 739 | .playback = { |
623 | .stream_name = "Speaker", | 740 | .stream_name = "Speaker", |
624 | .channels_min = 2, | 741 | .channels_min = 2, |
625 | .channels_max = 2, | 742 | .channels_max = 2, |
626 | .rates = SN95031_RATES, | 743 | .rates = SN95031_RATES, |
627 | .formats = SN95031_FORMATS, | 744 | .formats = SN95031_FORMATS, |
628 | }, | 745 | }, |
629 | .ops = &sn95031_speaker_dai_ops, | 746 | .ops = &sn95031_speaker_dai_ops, |
630 | }, | 747 | }, |
631 | { .name = "SN95031 Vibra1", | 748 | { .name = "SN95031 Vibra1", |
632 | .playback = { | 749 | .playback = { |
633 | .stream_name = "Vibra1", | 750 | .stream_name = "Vibra1", |
634 | .channels_min = 1, | 751 | .channels_min = 1, |
635 | .channels_max = 1, | 752 | .channels_max = 1, |
636 | .rates = SN95031_RATES, | 753 | .rates = SN95031_RATES, |
637 | .formats = SN95031_FORMATS, | 754 | .formats = SN95031_FORMATS, |
638 | }, | 755 | }, |
639 | .ops = &sn95031_vib1_dai_ops, | 756 | .ops = &sn95031_vib1_dai_ops, |
640 | }, | 757 | }, |
641 | { .name = "SN95031 Vibra2", | 758 | { .name = "SN95031 Vibra2", |
642 | .playback = { | 759 | .playback = { |
643 | .stream_name = "Vibra2", | 760 | .stream_name = "Vibra2", |
644 | .channels_min = 1, | 761 | .channels_min = 1, |
645 | .channels_max = 1, | 762 | .channels_max = 1, |
646 | .rates = SN95031_RATES, | 763 | .rates = SN95031_RATES, |
647 | .formats = SN95031_FORMATS, | 764 | .formats = SN95031_FORMATS, |
648 | }, | 765 | }, |
649 | .ops = &sn95031_vib2_dai_ops, | 766 | .ops = &sn95031_vib2_dai_ops, |
650 | }, | 767 | }, |
651 | }; | 768 | }; |
652 | 769 | ||
653 | static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec) | 770 | static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec) |
654 | { | 771 | { |
655 | snd_soc_write(codec, SN95031_BTNCTRL2, 0x00); | 772 | snd_soc_write(codec, SN95031_BTNCTRL2, 0x00); |
656 | } | 773 | } |
657 | 774 | ||
658 | static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec) | 775 | static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec) |
659 | { | 776 | { |
660 | snd_soc_write(codec, SN95031_BTNCTRL1, 0x77); | 777 | snd_soc_write(codec, SN95031_BTNCTRL1, 0x77); |
661 | snd_soc_write(codec, SN95031_BTNCTRL2, 0x01); | 778 | snd_soc_write(codec, SN95031_BTNCTRL2, 0x01); |
662 | } | 779 | } |
663 | 780 | ||
664 | static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack) | 781 | static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack) |
665 | { | 782 | { |
783 | int micbias = sn95031_get_mic_bias(mfld_jack->codec); | ||
784 | |||
666 | /* Defaulting to HEADSET for now. | 785 | /* Defaulting to HEADSET for now. |
667 | * will change after adding soc-jack detection apis */ | 786 | * will change after adding soc-jack detection apis */ |
668 | int jack_type = SND_JACK_HEADSET; | 787 | int jack_type = SND_JACK_HEADSET; |
669 | 788 | ||
670 | pr_debug("jack type detected = %d\n", jack_type); | 789 | pr_debug("jack type detected = %d\n", jack_type); |
671 | if (jack_type == SND_JACK_HEADSET) | 790 | if (jack_type == SND_JACK_HEADSET) |
672 | sn95031_enable_jack_btn(mfld_jack->codec); | 791 | sn95031_enable_jack_btn(mfld_jack->codec); |
673 | return jack_type; | 792 | return jack_type; |
674 | } | 793 | } |
675 | 794 | ||
676 | void sn95031_jack_detection(struct mfld_jack_data *jack_data) | 795 | void sn95031_jack_detection(struct mfld_jack_data *jack_data) |
677 | { | 796 | { |
678 | unsigned int status; | 797 | unsigned int status; |
679 | unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET; | 798 | unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET; |
680 | 799 | ||
681 | pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id); | 800 | pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id); |
682 | if (jack_data->intr_id & 0x1) { | 801 | if (jack_data->intr_id & 0x1) { |
683 | pr_debug("short_push detected\n"); | 802 | pr_debug("short_push detected\n"); |
684 | status = SND_JACK_HEADSET | SND_JACK_BTN_0; | 803 | status = SND_JACK_HEADSET | SND_JACK_BTN_0; |
685 | } else if (jack_data->intr_id & 0x2) { | 804 | } else if (jack_data->intr_id & 0x2) { |
686 | pr_debug("long_push detected\n"); | 805 | pr_debug("long_push detected\n"); |
687 | status = SND_JACK_HEADSET | SND_JACK_BTN_1; | 806 | status = SND_JACK_HEADSET | SND_JACK_BTN_1; |
688 | } else if (jack_data->intr_id & 0x4) { | 807 | } else if (jack_data->intr_id & 0x4) { |
689 | pr_debug("headset or headphones inserted\n"); | 808 | pr_debug("headset or headphones inserted\n"); |
690 | status = sn95031_get_headset_state(jack_data->mfld_jack); | 809 | status = sn95031_get_headset_state(jack_data->mfld_jack); |
691 | } else if (jack_data->intr_id & 0x8) { | 810 | } else if (jack_data->intr_id & 0x8) { |
692 | pr_debug("headset or headphones removed\n"); | 811 | pr_debug("headset or headphones removed\n"); |
693 | status = 0; | 812 | status = 0; |
694 | sn95031_disable_jack_btn(jack_data->mfld_jack->codec); | 813 | sn95031_disable_jack_btn(jack_data->mfld_jack->codec); |
695 | } else { | 814 | } else { |
696 | pr_err("unidentified interrupt\n"); | 815 | pr_err("unidentified interrupt\n"); |
697 | return; | 816 | return; |
698 | } | 817 | } |
699 | 818 | ||
700 | snd_soc_jack_report(jack_data->mfld_jack, status, mask); | 819 | snd_soc_jack_report(jack_data->mfld_jack, status, mask); |
701 | /*button pressed and released so we send explicit button release */ | 820 | /*button pressed and released so we send explicit button release */ |
702 | if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1)) | 821 | if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1)) |
703 | snd_soc_jack_report(jack_data->mfld_jack, | 822 | snd_soc_jack_report(jack_data->mfld_jack, |
704 | SND_JACK_HEADSET, mask); | 823 | SND_JACK_HEADSET, mask); |
705 | } | 824 | } |
706 | EXPORT_SYMBOL_GPL(sn95031_jack_detection); | 825 | EXPORT_SYMBOL_GPL(sn95031_jack_detection); |
707 | 826 | ||
708 | /* codec registration */ | 827 | /* codec registration */ |
709 | static int sn95031_codec_probe(struct snd_soc_codec *codec) | 828 | static int sn95031_codec_probe(struct snd_soc_codec *codec) |
710 | { | 829 | { |
711 | int ret; | 830 | int ret; |
712 | 831 | ||
713 | pr_debug("codec_probe called\n"); | 832 | pr_debug("codec_probe called\n"); |
714 | 833 | ||
715 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; | 834 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; |
716 | codec->dapm.idle_bias_off = 1; | 835 | codec->dapm.idle_bias_off = 1; |
717 | 836 | ||
718 | /* PCM interface config | 837 | /* PCM interface config |
719 | * This sets the pcm rx slot conguration to max 6 slots | 838 | * This sets the pcm rx slot conguration to max 6 slots |
720 | * for max 4 dais (2 stereo and 2 mono) | 839 | * for max 4 dais (2 stereo and 2 mono) |
721 | */ | 840 | */ |
722 | snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10); | 841 | snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10); |
723 | snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32); | 842 | snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32); |
724 | snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54); | 843 | snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54); |
725 | snd_soc_write(codec, SN95031_PCM2TXSLOT01, 0x10); | 844 | snd_soc_write(codec, SN95031_PCM2TXSLOT01, 0x10); |
726 | snd_soc_write(codec, SN95031_PCM2TXSLOT23, 0x32); | 845 | snd_soc_write(codec, SN95031_PCM2TXSLOT23, 0x32); |
727 | /* pcm port setting | 846 | /* pcm port setting |
728 | * This sets the pcm port to slave and clock at 19.2Mhz which | 847 | * This sets the pcm port to slave and clock at 19.2Mhz which |
729 | * can support 6slots, sampling rate set per stream in hw-params | 848 | * can support 6slots, sampling rate set per stream in hw-params |
730 | */ | 849 | */ |
731 | snd_soc_write(codec, SN95031_PCM1C1, 0x00); | 850 | snd_soc_write(codec, SN95031_PCM1C1, 0x00); |
732 | snd_soc_write(codec, SN95031_PCM2C1, 0x01); | 851 | snd_soc_write(codec, SN95031_PCM2C1, 0x01); |
733 | snd_soc_write(codec, SN95031_PCM2C2, 0x0A); | 852 | snd_soc_write(codec, SN95031_PCM2C2, 0x0A); |
734 | snd_soc_write(codec, SN95031_HSMIXER, BIT(0)|BIT(4)); | 853 | snd_soc_write(codec, SN95031_HSMIXER, BIT(0)|BIT(4)); |
735 | /* vendor vibra workround, the vibras are muted by | 854 | /* vendor vibra workround, the vibras are muted by |
736 | * custom register so unmute them | 855 | * custom register so unmute them |
737 | */ | 856 | */ |
738 | snd_soc_write(codec, SN95031_SSR5, 0x80); | 857 | snd_soc_write(codec, SN95031_SSR5, 0x80); |
739 | snd_soc_write(codec, SN95031_SSR6, 0x80); | 858 | snd_soc_write(codec, SN95031_SSR6, 0x80); |
740 | snd_soc_write(codec, SN95031_VIB1C5, 0x00); | 859 | snd_soc_write(codec, SN95031_VIB1C5, 0x00); |
741 | snd_soc_write(codec, SN95031_VIB2C5, 0x00); | 860 | snd_soc_write(codec, SN95031_VIB2C5, 0x00); |
742 | /* configure vibras for pcm port */ | 861 | /* configure vibras for pcm port */ |
743 | snd_soc_write(codec, SN95031_VIB1C3, 0x00); | 862 | snd_soc_write(codec, SN95031_VIB1C3, 0x00); |
744 | snd_soc_write(codec, SN95031_VIB2C3, 0x00); | 863 | snd_soc_write(codec, SN95031_VIB2C3, 0x00); |
745 | 864 | ||
746 | /* soft mute ramp time */ | 865 | /* soft mute ramp time */ |
747 | snd_soc_write(codec, SN95031_SOFTMUTE, 0x3); | 866 | snd_soc_write(codec, SN95031_SOFTMUTE, 0x3); |
748 | /* fix the initial volume at 1dB, | 867 | /* fix the initial volume at 1dB, |
749 | * default in +9dB, | 868 | * default in +9dB, |
750 | * 1dB give optimal swing on DAC, amps | 869 | * 1dB give optimal swing on DAC, amps |
751 | */ | 870 | */ |
752 | snd_soc_write(codec, SN95031_HSLVOLCTRL, 0x08); | 871 | snd_soc_write(codec, SN95031_HSLVOLCTRL, 0x08); |
753 | snd_soc_write(codec, SN95031_HSRVOLCTRL, 0x08); | 872 | snd_soc_write(codec, SN95031_HSRVOLCTRL, 0x08); |
754 | snd_soc_write(codec, SN95031_IHFLVOLCTRL, 0x08); | 873 | snd_soc_write(codec, SN95031_IHFLVOLCTRL, 0x08); |
755 | snd_soc_write(codec, SN95031_IHFRVOLCTRL, 0x08); | 874 | snd_soc_write(codec, SN95031_IHFRVOLCTRL, 0x08); |
756 | /* dac mode and lineout workaround */ | 875 | /* dac mode and lineout workaround */ |
757 | snd_soc_write(codec, SN95031_SSR2, 0x10); | 876 | snd_soc_write(codec, SN95031_SSR2, 0x10); |
758 | snd_soc_write(codec, SN95031_SSR3, 0x40); | 877 | snd_soc_write(codec, SN95031_SSR3, 0x40); |
759 | 878 | ||
760 | snd_soc_add_controls(codec, sn95031_snd_controls, | 879 | snd_soc_add_controls(codec, sn95031_snd_controls, |
761 | ARRAY_SIZE(sn95031_snd_controls)); | 880 | ARRAY_SIZE(sn95031_snd_controls)); |
762 | 881 | ||
763 | ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets, | 882 | ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets, |
764 | ARRAY_SIZE(sn95031_dapm_widgets)); | 883 | ARRAY_SIZE(sn95031_dapm_widgets)); |
765 | if (ret) | 884 | if (ret) |
766 | pr_err("soc_dapm_new_control failed %d", ret); | 885 | pr_err("soc_dapm_new_control failed %d", ret); |
767 | ret = snd_soc_dapm_add_routes(&codec->dapm, sn95031_audio_map, | 886 | ret = snd_soc_dapm_add_routes(&codec->dapm, sn95031_audio_map, |
768 | ARRAY_SIZE(sn95031_audio_map)); | 887 | ARRAY_SIZE(sn95031_audio_map)); |
769 | if (ret) | 888 | if (ret) |
770 | pr_err("soc_dapm_add_routes failed %d", ret); | 889 | pr_err("soc_dapm_add_routes failed %d", ret); |
771 | 890 | ||
772 | return ret; | 891 | return ret; |
773 | } | 892 | } |
774 | 893 | ||
775 | static int sn95031_codec_remove(struct snd_soc_codec *codec) | 894 | static int sn95031_codec_remove(struct snd_soc_codec *codec) |
776 | { | 895 | { |
777 | pr_debug("codec_remove called\n"); | 896 | pr_debug("codec_remove called\n"); |
778 | sn95031_set_vaud_bias(codec, SND_SOC_BIAS_OFF); | 897 | sn95031_set_vaud_bias(codec, SND_SOC_BIAS_OFF); |
779 | 898 | ||
780 | return 0; | 899 | return 0; |
781 | } | 900 | } |
782 | 901 | ||
783 | struct snd_soc_codec_driver sn95031_codec = { | 902 | struct snd_soc_codec_driver sn95031_codec = { |
784 | .probe = sn95031_codec_probe, | 903 | .probe = sn95031_codec_probe, |
785 | .remove = sn95031_codec_remove, | 904 | .remove = sn95031_codec_remove, |
786 | .read = sn95031_read, | 905 | .read = sn95031_read, |
787 | .write = sn95031_write, | 906 | .write = sn95031_write, |
788 | .set_bias_level = sn95031_set_vaud_bias, | 907 | .set_bias_level = sn95031_set_vaud_bias, |
789 | }; | 908 | }; |
790 | 909 | ||
791 | static int __devinit sn95031_device_probe(struct platform_device *pdev) | 910 | static int __devinit sn95031_device_probe(struct platform_device *pdev) |
792 | { | 911 | { |
793 | pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev)); | 912 | pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev)); |
794 | return snd_soc_register_codec(&pdev->dev, &sn95031_codec, | 913 | return snd_soc_register_codec(&pdev->dev, &sn95031_codec, |
795 | sn95031_dais, ARRAY_SIZE(sn95031_dais)); | 914 | sn95031_dais, ARRAY_SIZE(sn95031_dais)); |
796 | } | 915 | } |
797 | 916 | ||
798 | static int __devexit sn95031_device_remove(struct platform_device *pdev) | 917 | static int __devexit sn95031_device_remove(struct platform_device *pdev) |
799 | { | 918 | { |
800 | pr_debug("codec device remove called\n"); | 919 | pr_debug("codec device remove called\n"); |
801 | snd_soc_unregister_codec(&pdev->dev); | 920 | snd_soc_unregister_codec(&pdev->dev); |
802 | return 0; | 921 | return 0; |
803 | } | 922 | } |
804 | 923 | ||
805 | static struct platform_driver sn95031_codec_driver = { | 924 | static struct platform_driver sn95031_codec_driver = { |
806 | .driver = { | 925 | .driver = { |
807 | .name = "sn95031", | 926 | .name = "sn95031", |
808 | .owner = THIS_MODULE, | 927 | .owner = THIS_MODULE, |
809 | }, | 928 | }, |
810 | .probe = sn95031_device_probe, | 929 | .probe = sn95031_device_probe, |
811 | .remove = sn95031_device_remove, | 930 | .remove = sn95031_device_remove, |
812 | }; | 931 | }; |
813 | 932 | ||
814 | static int __init sn95031_init(void) | 933 | static int __init sn95031_init(void) |
815 | { | 934 | { |
816 | pr_debug("driver init called\n"); | 935 | pr_debug("driver init called\n"); |
817 | return platform_driver_register(&sn95031_codec_driver); | 936 | return platform_driver_register(&sn95031_codec_driver); |
818 | } | 937 | } |
819 | module_init(sn95031_init); | 938 | module_init(sn95031_init); |
820 | 939 | ||
821 | static void __exit sn95031_exit(void) | 940 | static void __exit sn95031_exit(void) |
822 | { | 941 | { |
823 | pr_debug("driver exit called\n"); | 942 | pr_debug("driver exit called\n"); |
824 | platform_driver_unregister(&sn95031_codec_driver); | 943 | platform_driver_unregister(&sn95031_codec_driver); |
825 | } | 944 | } |
826 | module_exit(sn95031_exit); | 945 | module_exit(sn95031_exit); |
827 | 946 | ||
828 | MODULE_DESCRIPTION("ASoC TI SN95031 codec driver"); | 947 | MODULE_DESCRIPTION("ASoC TI SN95031 codec driver"); |
829 | MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); | 948 | MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); |
830 | MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>"); | 949 | MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>"); |
831 | MODULE_LICENSE("GPL v2"); | 950 | MODULE_LICENSE("GPL v2"); |
832 | MODULE_ALIAS("platform:sn95031"); | 951 | MODULE_ALIAS("platform:sn95031"); |
833 | 952 |
sound/soc/codecs/sn95031.h
1 | /* | 1 | /* |
2 | * sn95031.h - TI sn95031 Codec driver | 2 | * sn95031.h - TI sn95031 Codec driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Intel Corp | 4 | * Copyright (C) 2010 Intel Corp |
5 | * Author: Vinod Koul <vinod.koul@intel.com> | 5 | * Author: Vinod Koul <vinod.koul@intel.com> |
6 | * Author: Harsha Priya <priya.harsha@intel.com> | 6 | * Author: Harsha Priya <priya.harsha@intel.com> |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
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 as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; version 2 of the License. | 11 | * the Free Software Foundation; version 2 of the License. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, but | 13 | * This program is distributed in the hope that it will be useful, but |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | * General Public License for more details. | 16 | * General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License along | 18 | * You should have received a copy of the GNU General Public License along |
19 | * with this program; if not, write to the Free Software Foundation, Inc., | 19 | * with this program; if not, write to the Free Software Foundation, Inc., |
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | 20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
21 | * | 21 | * |
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
23 | * | 23 | * |
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | #ifndef _SN95031_H | 26 | #ifndef _SN95031_H |
27 | #define _SN95031_H | 27 | #define _SN95031_H |
28 | 28 | ||
29 | /*register map*/ | 29 | /*register map*/ |
30 | #define SN95031_VAUD 0xDB | 30 | #define SN95031_VAUD 0xDB |
31 | #define SN95031_VHSP 0xDC | 31 | #define SN95031_VHSP 0xDC |
32 | #define SN95031_VHSN 0xDD | 32 | #define SN95031_VHSN 0xDD |
33 | #define SN95031_VIHF 0xC9 | 33 | #define SN95031_VIHF 0xC9 |
34 | 34 | ||
35 | #define SN95031_AUDPLLCTRL 0x240 | 35 | #define SN95031_AUDPLLCTRL 0x240 |
36 | #define SN95031_DMICBUF0123 0x241 | 36 | #define SN95031_DMICBUF0123 0x241 |
37 | #define SN95031_DMICBUF45 0x242 | 37 | #define SN95031_DMICBUF45 0x242 |
38 | #define SN95031_DMICGPO 0x244 | 38 | #define SN95031_DMICGPO 0x244 |
39 | #define SN95031_DMICMUX 0x245 | 39 | #define SN95031_DMICMUX 0x245 |
40 | #define SN95031_DMICLK 0x246 | 40 | #define SN95031_DMICLK 0x246 |
41 | #define SN95031_MICBIAS 0x247 | 41 | #define SN95031_MICBIAS 0x247 |
42 | #define SN95031_ADCCONFIG 0x248 | 42 | #define SN95031_ADCCONFIG 0x248 |
43 | #define SN95031_MICAMP1 0x249 | 43 | #define SN95031_MICAMP1 0x249 |
44 | #define SN95031_MICAMP2 0x24A | 44 | #define SN95031_MICAMP2 0x24A |
45 | #define SN95031_NOISEMUX 0x24B | 45 | #define SN95031_NOISEMUX 0x24B |
46 | #define SN95031_AUDIOMUX12 0x24C | 46 | #define SN95031_AUDIOMUX12 0x24C |
47 | #define SN95031_AUDIOMUX34 0x24D | 47 | #define SN95031_AUDIOMUX34 0x24D |
48 | #define SN95031_AUDIOSINC 0x24E | 48 | #define SN95031_AUDIOSINC 0x24E |
49 | #define SN95031_AUDIOTXEN 0x24F | 49 | #define SN95031_AUDIOTXEN 0x24F |
50 | #define SN95031_HSEPRXCTRL 0x250 | 50 | #define SN95031_HSEPRXCTRL 0x250 |
51 | #define SN95031_IHFRXCTRL 0x251 | 51 | #define SN95031_IHFRXCTRL 0x251 |
52 | #define SN95031_HSMIXER 0x256 | 52 | #define SN95031_HSMIXER 0x256 |
53 | #define SN95031_DACCONFIG 0x257 | 53 | #define SN95031_DACCONFIG 0x257 |
54 | #define SN95031_SOFTMUTE 0x258 | 54 | #define SN95031_SOFTMUTE 0x258 |
55 | #define SN95031_HSLVOLCTRL 0x259 | 55 | #define SN95031_HSLVOLCTRL 0x259 |
56 | #define SN95031_HSRVOLCTRL 0x25A | 56 | #define SN95031_HSRVOLCTRL 0x25A |
57 | #define SN95031_IHFLVOLCTRL 0x25B | 57 | #define SN95031_IHFLVOLCTRL 0x25B |
58 | #define SN95031_IHFRVOLCTRL 0x25C | 58 | #define SN95031_IHFRVOLCTRL 0x25C |
59 | #define SN95031_DRIVEREN 0x25D | 59 | #define SN95031_DRIVEREN 0x25D |
60 | #define SN95031_LOCTL 0x25E | 60 | #define SN95031_LOCTL 0x25E |
61 | #define SN95031_VIB1C1 0x25F | 61 | #define SN95031_VIB1C1 0x25F |
62 | #define SN95031_VIB1C2 0x260 | 62 | #define SN95031_VIB1C2 0x260 |
63 | #define SN95031_VIB1C3 0x261 | 63 | #define SN95031_VIB1C3 0x261 |
64 | #define SN95031_VIB1SPIPCM1 0x262 | 64 | #define SN95031_VIB1SPIPCM1 0x262 |
65 | #define SN95031_VIB1SPIPCM2 0x263 | 65 | #define SN95031_VIB1SPIPCM2 0x263 |
66 | #define SN95031_VIB1C5 0x264 | 66 | #define SN95031_VIB1C5 0x264 |
67 | #define SN95031_VIB2C1 0x265 | 67 | #define SN95031_VIB2C1 0x265 |
68 | #define SN95031_VIB2C2 0x266 | 68 | #define SN95031_VIB2C2 0x266 |
69 | #define SN95031_VIB2C3 0x267 | 69 | #define SN95031_VIB2C3 0x267 |
70 | #define SN95031_VIB2SPIPCM1 0x268 | 70 | #define SN95031_VIB2SPIPCM1 0x268 |
71 | #define SN95031_VIB2SPIPCM2 0x269 | 71 | #define SN95031_VIB2SPIPCM2 0x269 |
72 | #define SN95031_VIB2C5 0x26A | 72 | #define SN95031_VIB2C5 0x26A |
73 | #define SN95031_BTNCTRL1 0x26B | 73 | #define SN95031_BTNCTRL1 0x26B |
74 | #define SN95031_BTNCTRL2 0x26C | 74 | #define SN95031_BTNCTRL2 0x26C |
75 | #define SN95031_PCM1TXSLOT01 0x26D | 75 | #define SN95031_PCM1TXSLOT01 0x26D |
76 | #define SN95031_PCM1TXSLOT23 0x26E | 76 | #define SN95031_PCM1TXSLOT23 0x26E |
77 | #define SN95031_PCM1TXSLOT45 0x26F | 77 | #define SN95031_PCM1TXSLOT45 0x26F |
78 | #define SN95031_PCM1RXSLOT0_3 0x270 | 78 | #define SN95031_PCM1RXSLOT0_3 0x270 |
79 | #define SN95031_PCM1RXSLOT45 0x271 | 79 | #define SN95031_PCM1RXSLOT45 0x271 |
80 | #define SN95031_PCM2TXSLOT01 0x272 | 80 | #define SN95031_PCM2TXSLOT01 0x272 |
81 | #define SN95031_PCM2TXSLOT23 0x273 | 81 | #define SN95031_PCM2TXSLOT23 0x273 |
82 | #define SN95031_PCM2TXSLOT45 0x274 | 82 | #define SN95031_PCM2TXSLOT45 0x274 |
83 | #define SN95031_PCM2RXSLOT01 0x275 | 83 | #define SN95031_PCM2RXSLOT01 0x275 |
84 | #define SN95031_PCM2RXSLOT23 0x276 | 84 | #define SN95031_PCM2RXSLOT23 0x276 |
85 | #define SN95031_PCM2RXSLOT45 0x277 | 85 | #define SN95031_PCM2RXSLOT45 0x277 |
86 | #define SN95031_PCM1C1 0x278 | 86 | #define SN95031_PCM1C1 0x278 |
87 | #define SN95031_PCM1C2 0x279 | 87 | #define SN95031_PCM1C2 0x279 |
88 | #define SN95031_PCM1C3 0x27A | 88 | #define SN95031_PCM1C3 0x27A |
89 | #define SN95031_PCM2C1 0x27B | 89 | #define SN95031_PCM2C1 0x27B |
90 | #define SN95031_PCM2C2 0x27C | 90 | #define SN95031_PCM2C2 0x27C |
91 | /*end codec register defn*/ | 91 | /*end codec register defn*/ |
92 | 92 | ||
93 | /*vendor defn these are not part of avp*/ | 93 | /*vendor defn these are not part of avp*/ |
94 | #define SN95031_SSR2 0x381 | 94 | #define SN95031_SSR2 0x381 |
95 | #define SN95031_SSR3 0x382 | 95 | #define SN95031_SSR3 0x382 |
96 | #define SN95031_SSR5 0x384 | 96 | #define SN95031_SSR5 0x384 |
97 | #define SN95031_SSR6 0x385 | 97 | #define SN95031_SSR6 0x385 |
98 | 98 | ||
99 | /* ADC registers */ | ||
100 | |||
101 | #define SN95031_ADC1CNTL1 0x1C0 | ||
102 | #define SN95031_ADC_ENBL 0x10 | ||
103 | #define SN95031_ADC_START 0x08 | ||
104 | #define SN95031_ADC1CNTL3 0x1C2 | ||
105 | #define SN95031_ADCTHERM_ENBL 0x04 | ||
106 | #define SN95031_ADCRRDATA_ENBL 0x05 | ||
107 | #define SN95031_STOPBIT_MASK 16 | ||
108 | #define SN95031_ADCTHERM_MASK 4 | ||
109 | #define SN95031_ADC_CHANLS_MAX 15 /* Number of ADC channels */ | ||
110 | #define SN95031_ADC_LOOP_MAX (SN95031_ADC_CHANLS_MAX - 1) | ||
111 | #define SN95031_ADC_NO_LOOP 0x07 | ||
99 | #define SN95031_AUDIO_GPIO_CTRL 0x070 | 112 | #define SN95031_AUDIO_GPIO_CTRL 0x070 |
113 | |||
114 | /* ADC channel code values */ | ||
115 | #define SN95031_AUDIO_DETECT_CODE 0x06 | ||
116 | |||
117 | /* ADC base addresses */ | ||
118 | #define SN95031_ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */ | ||
119 | #define SN95031_ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */ | ||
120 | /* multipier to convert to mV */ | ||
121 | #define SN95031_ADC_ONE_LSB_MULTIPLIER 2346 | ||
122 | |||
123 | |||
100 | struct mfld_jack_data { | 124 | struct mfld_jack_data { |
101 | int intr_id; | 125 | int intr_id; |
102 | int micbias_vol; | 126 | int micbias_vol; |
103 | struct snd_soc_jack *mfld_jack; | 127 | struct snd_soc_jack *mfld_jack; |
104 | }; | 128 | }; |
105 | 129 | ||
106 | extern void sn95031_jack_detection(struct mfld_jack_data *jack_data); | 130 | extern void sn95031_jack_detection(struct mfld_jack_data *jack_data); |
107 | 131 | ||
108 | #endif | 132 | #endif |
109 | 133 |