blob: a0295eae385a43ddb1969df1dc28ad3fce223f50 [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05302 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/gpio.h>
Asish Bhattacharyac71827a2012-03-05 10:11:45 -080016#include <linux/mfd/pm8xxx/spk.h>
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053017#include <linux/platform_device.h>
18#include <linux/gpio.h>
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053019#include <linux/slab.h>
20#include <sound/core.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053023#include <sound/pcm.h>
24#include <sound/jack.h>
25#include <asm/mach-types.h>
26#include <mach/socinfo.h>
27#include "msm-pcm-routing.h"
28#include "../codecs/wcd9304.h"
29
30/* 8930 machine driver */
31
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053032#define MSM8930_SPK_ON 1
33#define MSM8930_SPK_OFF 0
34
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053035#define BTSCO_RATE_8KHZ 8000
36#define BTSCO_RATE_16KHZ 16000
37
Asish Bhattacharyac71827a2012-03-05 10:11:45 -080038#define SPK_AMP_POS 0x1
39#define SPK_AMP_NEG 0x2
Bhalchandra Gajare98a28cd2012-05-16 12:00:20 -070040#define SPKR_BOOST_GPIO 15
Bhalchandra Gajareb28275f2012-08-13 12:32:12 -070041#define LEFT_SPKR_AMPL_GPIO 15
Bhalchandra Gajare97676792012-05-22 17:41:45 -070042#define DEFAULT_PMIC_SPK_GAIN 0x0D
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053043#define SITAR_EXT_CLK_RATE 12288000
44
Bhalchandra Gajare7708ee32012-05-24 17:37:37 -070045#define SITAR_MBHC_DEF_BUTTONS 8
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053046#define SITAR_MBHC_DEF_RLOADS 5
47
Bhalchandra Gajare2e0893e2012-05-24 00:39:47 -070048#define GPIO_AUX_PCM_DOUT 63
49#define GPIO_AUX_PCM_DIN 64
50#define GPIO_AUX_PCM_SYNC 65
51#define GPIO_AUX_PCM_CLK 66
52
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053053static int msm8930_spk_control;
54static int msm8930_slim_0_rx_ch = 1;
55static int msm8930_slim_0_tx_ch = 1;
Bhalchandra Gajare97676792012-05-22 17:41:45 -070056static int msm8930_pmic_spk_gain = DEFAULT_PMIC_SPK_GAIN;
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053057
Asish Bhattacharyac71827a2012-03-05 10:11:45 -080058static int msm8930_ext_spk_pamp;
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053059static int msm8930_btsco_rate = BTSCO_RATE_8KHZ;
60static int msm8930_btsco_ch = 1;
Vicky Sehrawat53f5c2e2012-11-05 17:54:13 -080061static int hdmi_rate_variable;
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053062static struct clk *codec_clk;
63static int clk_users;
64
65static int msm8930_headset_gpios_configured;
66
67static struct snd_soc_jack hs_jack;
68static struct snd_soc_jack button_jack;
Kuirong Wang892c9ad2012-09-20 11:43:17 -070069static atomic_t auxpcm_rsc_ref;
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -070070
71static int msm8930_enable_codec_ext_clk(
72 struct snd_soc_codec *codec, int enable,
73 bool dapm);
74
75static struct sitar_mbhc_config mbhc_cfg = {
76 .headset_jack = &hs_jack,
77 .button_jack = &button_jack,
78 .read_fw_bin = false,
79 .calibration = NULL,
80 .micbias = SITAR_MICBIAS2,
81 .mclk_cb_fn = msm8930_enable_codec_ext_clk,
82 .mclk_rate = SITAR_EXT_CLK_RATE,
83 .gpio = 0,
84 .gpio_irq = 0,
85 .gpio_level_insert = 1,
86};
87
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053088
89static void msm8930_ext_control(struct snd_soc_codec *codec)
90{
91 struct snd_soc_dapm_context *dapm = &codec->dapm;
92
93 pr_debug("%s: msm8930_spk_control = %d", __func__, msm8930_spk_control);
94 if (msm8930_spk_control == MSM8930_SPK_ON) {
95 snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Pos");
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -080096 snd_soc_dapm_enable_pin(dapm, "Ext Spk left Neg");
Asish Bhattacharyab86c3472012-02-15 08:31:52 +053097 } else {
98 snd_soc_dapm_disable_pin(dapm, "Ext Spk Left Pos");
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -080099 snd_soc_dapm_disable_pin(dapm, "Ext Spk Left Neg");
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530100 }
101
102 snd_soc_dapm_sync(dapm);
103}
104
105static int msm8930_get_spk(struct snd_kcontrol *kcontrol,
106 struct snd_ctl_elem_value *ucontrol)
107{
108 pr_debug("%s: msm8930_spk_control = %d", __func__, msm8930_spk_control);
109 ucontrol->value.integer.value[0] = msm8930_spk_control;
110 return 0;
111}
112static int msm8930_set_spk(struct snd_kcontrol *kcontrol,
113 struct snd_ctl_elem_value *ucontrol)
114{
115 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
116
117 pr_debug("%s()\n", __func__);
118 if (msm8930_spk_control == ucontrol->value.integer.value[0])
119 return 0;
120
121 msm8930_spk_control = ucontrol->value.integer.value[0];
122 msm8930_ext_control(codec);
123 return 1;
124}
125
Bhalchandra Gajareb28275f2012-08-13 12:32:12 -0700126static int msm8930_cfg_spkr_gpio(int gpio,
127 int enable, const char *gpio_label)
128{
129 int ret = 0;
130
131 pr_debug("%s: Configure %s GPIO %u",
132 __func__, gpio_label, gpio);
133 ret = gpio_request(gpio, gpio_label);
134 if (ret)
135 return ret;
136
137 pr_debug("%s: Enable %s gpio %u\n",
138 __func__, gpio_label, gpio);
139 gpio_direction_output(gpio, enable);
140
141 return ret;
142}
143
Asish Bhattacharyac71827a2012-03-05 10:11:45 -0800144static void msm8960_ext_spk_power_amp_on(u32 spk)
145{
Bhalchandra Gajare98a28cd2012-05-16 12:00:20 -0700146 int ret = 0;
147
Asish Bhattacharyac71827a2012-03-05 10:11:45 -0800148 if (spk & (SPK_AMP_POS | SPK_AMP_NEG)) {
149 if ((msm8930_ext_spk_pamp & SPK_AMP_POS) &&
150 (msm8930_ext_spk_pamp & SPK_AMP_NEG)) {
151
152 pr_debug("%s() External Bottom Speaker Ampl already "
153 "turned on. spk = 0x%08x\n", __func__, spk);
154 return;
155 }
156
157 msm8930_ext_spk_pamp |= spk;
158
159 if ((msm8930_ext_spk_pamp & SPK_AMP_POS) &&
160 (msm8930_ext_spk_pamp & SPK_AMP_NEG)) {
161
Bhalchandra Gajareb28275f2012-08-13 12:32:12 -0700162 if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
163 ret = msm8930_cfg_spkr_gpio(
164 LEFT_SPKR_AMPL_GPIO,
165 1, "LEFT_SPKR_AMPL");
Bhalchandra Gajare98a28cd2012-05-16 12:00:20 -0700166 if (ret) {
Bhalchandra Gajareb28275f2012-08-13 12:32:12 -0700167 pr_err("%s: Failed to config ampl gpio %u\n",
168 __func__, LEFT_SPKR_AMPL_GPIO);
Bhalchandra Gajare98a28cd2012-05-16 12:00:20 -0700169 return;
170 }
Bhalchandra Gajareb28275f2012-08-13 12:32:12 -0700171 } else {
Bhalchandra Gajare98a28cd2012-05-16 12:00:20 -0700172
Bhalchandra Gajareb28275f2012-08-13 12:32:12 -0700173 if (machine_is_msm8930_mtp()
174 || machine_is_msm8930_fluid()) {
175 ret = msm8930_cfg_spkr_gpio(
176 SPKR_BOOST_GPIO, 1, "SPKR_BOOST");
177 if (ret) {
178 pr_err("%s: Failure: spkr boost gpio %u\n",
179 __func__, SPKR_BOOST_GPIO);
180 return;
181 }
182 }
183 pm8xxx_spk_enable(MSM8930_SPK_ON);
Bhalchandra Gajare98a28cd2012-05-16 12:00:20 -0700184 }
185
Asish Bhattacharyac71827a2012-03-05 10:11:45 -0800186 pr_debug("%s: slepping 4 ms after turning on external "
187 " Left Speaker Ampl\n", __func__);
188 usleep_range(4000, 4000);
189 }
190
191 } else {
192
193 pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
194 __func__, spk);
195 return;
196 }
197}
198
199static void msm8960_ext_spk_power_amp_off(u32 spk)
200{
201 if (spk & (SPK_AMP_POS | SPK_AMP_NEG)) {
202 if (!msm8930_ext_spk_pamp)
203 return;
Bhalchandra Gajareb28275f2012-08-13 12:32:12 -0700204
205 if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
206 gpio_free(LEFT_SPKR_AMPL_GPIO);
207 msm8930_ext_spk_pamp = 0;
208 return;
209 }
210
Bhalchandra Gajare98a28cd2012-05-16 12:00:20 -0700211 if (machine_is_msm8930_mtp()
212 || machine_is_msm8930_fluid()) {
213 pr_debug("%s: Free speaker boost gpio %u\n",
214 __func__, SPKR_BOOST_GPIO);
215 gpio_direction_output(SPKR_BOOST_GPIO, 0);
216 gpio_free(SPKR_BOOST_GPIO);
217 }
Asish Bhattacharyac71827a2012-03-05 10:11:45 -0800218
219 pm8xxx_spk_enable(MSM8930_SPK_OFF);
220 msm8930_ext_spk_pamp = 0;
221 pr_debug("%s: slepping 4 ms after turning on external "
222 " Left Speaker Ampl\n", __func__);
223 usleep_range(4000, 4000);
224
225 } else {
226
227 pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
228 __func__, spk);
229 return;
230 }
231}
232
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530233static int msm8930_spkramp_event(struct snd_soc_dapm_widget *w,
234 struct snd_kcontrol *k, int event)
235{
236 pr_debug("%s() %x\n", __func__, SND_SOC_DAPM_EVENT_ON(event));
Asish Bhattacharyac71827a2012-03-05 10:11:45 -0800237 if (SND_SOC_DAPM_EVENT_ON(event)) {
238 if (!strncmp(w->name, "Ext Spk Left Pos", 17))
239 msm8960_ext_spk_power_amp_on(SPK_AMP_POS);
240 else if (!strncmp(w->name, "Ext Spk Left Neg", 17))
241 msm8960_ext_spk_power_amp_on(SPK_AMP_NEG);
242 else {
243 pr_err("%s() Invalid Speaker Widget = %s\n",
244 __func__, w->name);
245 return -EINVAL;
246 }
247 } else {
248 if (!strncmp(w->name, "Ext Spk Left Pos", 17))
249 msm8960_ext_spk_power_amp_off(SPK_AMP_POS);
250 else if (!strncmp(w->name, "Ext Spk Left Neg", 17))
251 msm8960_ext_spk_power_amp_off(SPK_AMP_NEG);
252 else {
253 pr_err("%s() Invalid Speaker Widget = %s\n",
254 __func__, w->name);
255 return -EINVAL;
256 }
257 }
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530258 return 0;
259}
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800260
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -0700261static int msm8930_enable_codec_ext_clk(
262 struct snd_soc_codec *codec, int enable,
263 bool dapm)
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530264{
265 pr_debug("%s: enable = %d\n", __func__, enable);
266 if (enable) {
267 clk_users++;
268 pr_debug("%s: clk_users = %d\n", __func__, clk_users);
269 if (clk_users != 1)
270 return 0;
271
272 if (codec_clk) {
273 clk_set_rate(codec_clk, SITAR_EXT_CLK_RATE);
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800274 clk_prepare_enable(codec_clk);
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -0700275 sitar_mclk_enable(codec, 1, dapm);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530276 } else {
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800277 pr_err("%s: Error setting Sitar MCLK\n", __func__);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530278 clk_users--;
279 return -EINVAL;
280 }
281 } else {
282 pr_debug("%s: clk_users = %d\n", __func__, clk_users);
283 if (clk_users == 0)
284 return 0;
285 clk_users--;
286 if (!clk_users) {
287 pr_debug("%s: disabling MCLK. clk_users = %d\n",
288 __func__, clk_users);
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -0700289 sitar_mclk_enable(codec, 0, dapm);
Bhalchandra Gajare2776af12012-04-27 16:59:39 -0700290 clk_disable_unprepare(codec_clk);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530291 }
292 }
293 return 0;
294}
295
296static int msm8930_mclk_event(struct snd_soc_dapm_widget *w,
297 struct snd_kcontrol *kcontrol, int event)
298{
299 pr_debug("%s: event = %d\n", __func__, event);
300
301 switch (event) {
302 case SND_SOC_DAPM_PRE_PMU:
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -0700303 return msm8930_enable_codec_ext_clk(w->codec, 1, true);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530304 case SND_SOC_DAPM_POST_PMD:
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -0700305 return msm8930_enable_codec_ext_clk(w->codec, 0, true);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530306 }
307 return 0;
308}
309
310static const struct snd_soc_dapm_widget msm8930_dapm_widgets[] = {
311
312 SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
313 msm8930_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
314
315 SND_SOC_DAPM_SPK("Ext Spk Left Pos", msm8930_spkramp_event),
Asish Bhattacharyac71827a2012-03-05 10:11:45 -0800316 SND_SOC_DAPM_SPK("Ext Spk Left Neg", msm8930_spkramp_event),
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530317
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530318 SND_SOC_DAPM_MIC("Headset Mic", NULL),
319 SND_SOC_DAPM_MIC("Digital Mic1", NULL),
320 SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
321 SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
322
323 SND_SOC_DAPM_MIC("Digital Mic1", NULL),
324 SND_SOC_DAPM_MIC("Digital Mic2", NULL),
325 SND_SOC_DAPM_MIC("Digital Mic3", NULL),
326 SND_SOC_DAPM_MIC("Digital Mic4", NULL),
327
328};
329
330static const struct snd_soc_dapm_route common_audio_map[] = {
331
332 {"RX_BIAS", NULL, "MCLK"},
333 {"LDO_H", NULL, "MCLK"},
334
335 {"MIC BIAS1 Internal1", NULL, "MCLK"},
336 {"MIC BIAS2 Internal1", NULL, "MCLK"},
337
338 /* Speaker path */
339 {"Ext Spk Left Pos", NULL, "LINEOUT1"},
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800340 {"Ext Spk Left Neg", NULL, "LINEOUT2"},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530341
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800342 /* Headset Mic */
Bhalchandra Gajare553fb9e2012-06-26 14:48:54 -0700343 {"AMIC2", NULL, "MIC BIAS2 External"},
344 {"MIC BIAS2 External", NULL, "Headset Mic"},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530345
346 /* Microphone path */
Bhalchandra Gajare18314d52012-06-06 19:03:01 -0700347 {"AMIC1", NULL, "MIC BIAS2 External"},
348 {"MIC BIAS2 External", NULL, "ANCLeft Headset Mic"},
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800349
Bhalchandra Gajare18314d52012-06-06 19:03:01 -0700350 {"AMIC3", NULL, "MIC BIAS2 External"},
351 {"MIC BIAS2 External", NULL, "ANCRight Headset Mic"},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530352
353 {"HEADPHONE", NULL, "LDO_H"},
354
355 /**
356 * The digital Mic routes are setup considering
357 * fluid as default device.
358 */
359
360 /**
Bhalchandra Gajaree6a30f72012-05-23 19:46:21 -0700361 * Digital Mic1. Front Bottom left Mic on Fluid and MTP.
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530362 * Digital Mic GM5 on CDP mainboard.
Bhalchandra Gajaree6a30f72012-05-23 19:46:21 -0700363 * Conncted to DMIC1 Input on Sitar codec.
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530364 */
365 {"DMIC1", NULL, "MIC BIAS1 External"},
366 {"MIC BIAS1 External", NULL, "Digital Mic1"},
367
368 /**
Bhalchandra Gajaree6a30f72012-05-23 19:46:21 -0700369 * Digital Mic2. Back top MIC on Fluid.
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530370 * Digital Mic GM6 on CDP mainboard.
Bhalchandra Gajaree6a30f72012-05-23 19:46:21 -0700371 * Conncted to DMIC2 Input on Sitar codec.
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530372 */
373 {"DMIC2", NULL, "MIC BIAS1 External"},
374 {"MIC BIAS1 External", NULL, "Digital Mic2"},
375 /**
376 * Digital Mic3. Back Bottom Digital Mic on Fluid.
377 * Digital Mic GM1 on CDP mainboard.
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800378 * Conncted to DMIC4 Input on Sitar codec.
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530379 */
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800380 {"DMIC3", NULL, "MIC BIAS1 External"},
381 {"MIC BIAS1 External", NULL, "Digital Mic3"},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530382
383 /**
384 * Digital Mic4. Back top Digital Mic on Fluid.
385 * Digital Mic GM2 on CDP mainboard.
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800386 * Conncted to DMIC3 Input on Sitar codec.
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530387 */
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800388 {"DMIC4", NULL, "MIC BIAS1 External"},
389 {"MIC BIAS1 External", NULL, "Digital Mic4"},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530390
391
392};
393
394static const char *spk_function[] = {"Off", "On"};
395static const char *slim0_rx_ch_text[] = {"One", "Two"};
396static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
397
Vicky Sehrawat53f5c2e2012-11-05 17:54:13 -0800398static const char * const hdmi_rate[] = {"Default", "Variable"};
399
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530400static const struct soc_enum msm8930_enum[] = {
401 SOC_ENUM_SINGLE_EXT(2, spk_function),
402 SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
403 SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
Vicky Sehrawat53f5c2e2012-11-05 17:54:13 -0800404 SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530405};
406
407static const char *btsco_rate_text[] = {"8000", "16000"};
408static const struct soc_enum msm8930_btsco_enum[] = {
409 SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
410};
411
412static int msm8930_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol,
413 struct snd_ctl_elem_value *ucontrol)
414{
415 pr_debug("%s: msm8930_slim_0_rx_ch = %d\n", __func__,
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800416 msm8930_slim_0_rx_ch);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530417 ucontrol->value.integer.value[0] = msm8930_slim_0_rx_ch - 1;
418 return 0;
419}
420
421static int msm8930_slim_0_rx_ch_put(struct snd_kcontrol *kcontrol,
422 struct snd_ctl_elem_value *ucontrol)
423{
424 msm8930_slim_0_rx_ch = ucontrol->value.integer.value[0] + 1;
425
426 pr_debug("%s: msm8930_slim_0_rx_ch = %d\n", __func__,
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800427 msm8930_slim_0_rx_ch);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530428 return 1;
429}
430
431static int msm8930_slim_0_tx_ch_get(struct snd_kcontrol *kcontrol,
432 struct snd_ctl_elem_value *ucontrol)
433{
434 pr_debug("%s: msm8930_slim_0_tx_ch = %d\n", __func__,
435 msm8930_slim_0_tx_ch);
436 ucontrol->value.integer.value[0] = msm8930_slim_0_tx_ch - 1;
437 return 0;
438}
439
440static int msm8930_slim_0_tx_ch_put(struct snd_kcontrol *kcontrol,
441 struct snd_ctl_elem_value *ucontrol)
442{
443 msm8930_slim_0_tx_ch = ucontrol->value.integer.value[0] + 1;
444
445 pr_debug("%s: msm8930_slim_0_tx_ch = %d\n", __func__,
446 msm8930_slim_0_tx_ch);
447 return 1;
448}
449
450static int msm8930_btsco_rate_get(struct snd_kcontrol *kcontrol,
451 struct snd_ctl_elem_value *ucontrol)
452{
453 pr_debug("%s: msm8930_btsco_rate = %d", __func__, msm8930_btsco_rate);
454 ucontrol->value.integer.value[0] = msm8930_btsco_rate;
455 return 0;
456}
457
458static int msm8930_btsco_rate_put(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
460{
Kuirong Wangfd8e0b32012-05-30 19:45:04 -0700461
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530462 switch (ucontrol->value.integer.value[0]) {
Kuirong Wangfd8e0b32012-05-30 19:45:04 -0700463 case 8000:
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530464 msm8930_btsco_rate = BTSCO_RATE_8KHZ;
465 break;
Kuirong Wangfd8e0b32012-05-30 19:45:04 -0700466 case 16000:
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530467 msm8930_btsco_rate = BTSCO_RATE_16KHZ;
468 break;
469 default:
470 msm8930_btsco_rate = BTSCO_RATE_8KHZ;
471 break;
472 }
473 pr_debug("%s: msm8930_btsco_rate = %d\n", __func__, msm8930_btsco_rate);
474 return 0;
475}
476
Bhalchandra Gajare97676792012-05-22 17:41:45 -0700477static const char *pmic_spk_gain_text[] = {
478 "NEG_6_DB", "NEG_4_DB", "NEG_2_DB", "ZERO_DB", "POS_2_DB", "POS_4_DB",
479 "POS_6_DB", "POS_8_DB", "POS_10_DB", "POS_12_DB", "POS_14_DB",
480 "POS_16_DB", "POS_18_DB", "POS_20_DB", "POS_22_DB", "POS_24_DB"
481};
482
483static const struct soc_enum msm8960_pmic_spk_gain_enum[] = {
484 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(pmic_spk_gain_text),
485 pmic_spk_gain_text),
486};
487
488static int msm8930_pmic_gain_get(struct snd_kcontrol *kcontrol,
489 struct snd_ctl_elem_value *ucontrol)
490{
491 pr_debug("%s: msm8930_pmic_spk_gain = %d\n", __func__,
492 msm8930_pmic_spk_gain);
493 ucontrol->value.integer.value[0] = msm8930_pmic_spk_gain;
494 return 0;
495}
496
497static int msm8930_pmic_gain_put(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
499{
500 int ret = 0;
501 msm8930_pmic_spk_gain = ucontrol->value.integer.value[0];
Bhalchandra Gajareb28275f2012-08-13 12:32:12 -0700502 if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
503 ret = pm8xxx_spk_gain(msm8930_pmic_spk_gain);
Bhalchandra Gajare97676792012-05-22 17:41:45 -0700504 pr_debug("%s: msm8930_pmic_spk_gain = %d"
505 " ucontrol->value.integer.value[0] = %d\n", __func__,
506 msm8930_pmic_spk_gain,
507 (int) ucontrol->value.integer.value[0]);
508 return ret;
509}
510
Vicky Sehrawat53f5c2e2012-11-05 17:54:13 -0800511static int msm8930_hdmi_rate_put(struct snd_kcontrol *kcontrol,
512 struct snd_ctl_elem_value *ucontrol)
513{
514 hdmi_rate_variable = ucontrol->value.integer.value[0];
515 pr_debug("%s: hdmi_rate_variable = %d\n", __func__, hdmi_rate_variable);
516 return 0;
517}
518
519static int msm8930_hdmi_rate_get(struct snd_kcontrol *kcontrol,
520 struct snd_ctl_elem_value *ucontrol)
521{
522 ucontrol->value.integer.value[0] = hdmi_rate_variable;
523 return 0;
524}
525
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530526static const struct snd_kcontrol_new sitar_msm8930_controls[] = {
527 SOC_ENUM_EXT("Speaker Function", msm8930_enum[0], msm8930_get_spk,
528 msm8930_set_spk),
529 SOC_ENUM_EXT("SLIM_0_RX Channels", msm8930_enum[1],
530 msm8930_slim_0_rx_ch_get, msm8930_slim_0_rx_ch_put),
531 SOC_ENUM_EXT("SLIM_0_TX Channels", msm8930_enum[2],
532 msm8930_slim_0_tx_ch_get, msm8930_slim_0_tx_ch_put),
Bhalchandra Gajare97676792012-05-22 17:41:45 -0700533 SOC_ENUM_EXT("PMIC SPK Gain", msm8960_pmic_spk_gain_enum[0],
534 msm8930_pmic_gain_get, msm8930_pmic_gain_put),
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530535 SOC_ENUM_EXT("Internal BTSCO SampleRate", msm8930_btsco_enum[0],
536 msm8930_btsco_rate_get, msm8930_btsco_rate_put),
Vicky Sehrawat53f5c2e2012-11-05 17:54:13 -0800537 SOC_ENUM_EXT("HDMI RX Rate", msm8930_enum[3],
538 msm8930_hdmi_rate_get,
539 msm8930_hdmi_rate_put),
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530540};
541
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800542static void *def_sitar_mbhc_cal(void)
543{
544 void *sitar_cal;
545 struct sitar_mbhc_btn_detect_cfg *btn_cfg;
546 u16 *btn_low, *btn_high;
547 u8 *n_ready, *n_cic, *gain;
548
549 sitar_cal = kzalloc(SITAR_MBHC_CAL_SIZE(SITAR_MBHC_DEF_BUTTONS,
550 SITAR_MBHC_DEF_RLOADS),
551 GFP_KERNEL);
552 if (!sitar_cal) {
553 pr_err("%s: out of memory\n", __func__);
554 return NULL;
555 }
556
557#define S(X, Y) ((SITAR_MBHC_CAL_GENERAL_PTR(sitar_cal)->X) = (Y))
558 S(t_ldoh, 100);
559 S(t_bg_fast_settle, 100);
560 S(t_shutdown_plug_rem, 255);
561 S(mbhc_nsa, 4);
562 S(mbhc_navg, 4);
563#undef S
564#define S(X, Y) ((SITAR_MBHC_CAL_PLUG_DET_PTR(sitar_cal)->X) = (Y))
565 S(mic_current, SITAR_PID_MIC_5_UA);
566 S(hph_current, SITAR_PID_MIC_5_UA);
567 S(t_mic_pid, 100);
568 S(t_ins_complete, 250);
569 S(t_ins_retry, 200);
570#undef S
571#define S(X, Y) ((SITAR_MBHC_CAL_PLUG_TYPE_PTR(sitar_cal)->X) = (Y))
572 S(v_no_mic, 30);
Bhalchandra Gajare18314d52012-06-06 19:03:01 -0700573 S(v_hs_max, 1650);
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800574#undef S
575#define S(X, Y) ((SITAR_MBHC_CAL_BTN_DET_PTR(sitar_cal)->X) = (Y))
576 S(c[0], 62);
577 S(c[1], 124);
578 S(nc, 1);
579 S(n_meas, 3);
580 S(mbhc_nsc, 11);
581 S(n_btn_meas, 1);
582 S(n_btn_con, 2);
583 S(num_btn, SITAR_MBHC_DEF_BUTTONS);
584 S(v_btn_press_delta_sta, 100);
585 S(v_btn_press_delta_cic, 50);
586#undef S
587 btn_cfg = SITAR_MBHC_CAL_BTN_DET_PTR(sitar_cal);
588 btn_low = sitar_mbhc_cal_btn_det_mp(btn_cfg, SITAR_BTN_DET_V_BTN_LOW);
589 btn_high = sitar_mbhc_cal_btn_det_mp(btn_cfg, SITAR_BTN_DET_V_BTN_HIGH);
590 btn_low[0] = -50;
591 btn_high[0] = 10;
592 btn_low[1] = 11;
593 btn_high[1] = 38;
594 btn_low[2] = 39;
595 btn_high[2] = 64;
596 btn_low[3] = 65;
597 btn_high[3] = 91;
598 btn_low[4] = 92;
599 btn_high[4] = 115;
600 btn_low[5] = 116;
601 btn_high[5] = 141;
602 btn_low[6] = 142;
603 btn_high[6] = 163;
604 btn_low[7] = 164;
605 btn_high[7] = 250;
606 n_ready = sitar_mbhc_cal_btn_det_mp(btn_cfg, SITAR_BTN_DET_N_READY);
607 n_ready[0] = 48;
608 n_ready[1] = 38;
609 n_cic = sitar_mbhc_cal_btn_det_mp(btn_cfg, SITAR_BTN_DET_N_CIC);
610 n_cic[0] = 60;
611 n_cic[1] = 47;
612 gain = sitar_mbhc_cal_btn_det_mp(btn_cfg, SITAR_BTN_DET_GAIN);
613 gain[0] = 11;
614 gain[1] = 9;
615
616 return sitar_cal;
617}
618
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530619static int msm8930_hw_params(struct snd_pcm_substream *substream,
620 struct snd_pcm_hw_params *params)
621{
622 struct snd_soc_pcm_runtime *rtd = substream->private_data;
623 struct snd_soc_dai *codec_dai = rtd->codec_dai;
624 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
625 int ret = 0;
626 unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
627 unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
628
629 pr_debug("%s: ch=%d\n", __func__,
630 msm8930_slim_0_rx_ch);
631 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
632 ret = snd_soc_dai_get_channel_map(codec_dai,
633 &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
634 if (ret < 0) {
635 pr_err("%s: failed to get codec chan map\n", __func__);
636 goto end;
637 }
638
639 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
640 msm8930_slim_0_rx_ch, rx_ch);
641 if (ret < 0) {
642 pr_err("%s: failed to set cpu chan map\n", __func__);
643 goto end;
644 }
645 ret = snd_soc_dai_set_channel_map(codec_dai, 0, 0,
646 msm8930_slim_0_rx_ch, rx_ch);
647 if (ret < 0) {
648 pr_err("%s: failed to set codec channel map\n",
649 __func__);
650 goto end;
651 }
652 } else {
653 ret = snd_soc_dai_get_channel_map(codec_dai,
654 &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
655 if (ret < 0) {
656 pr_err("%s: failed to get codec chan map\n", __func__);
657 goto end;
658 }
659 ret = snd_soc_dai_set_channel_map(cpu_dai,
660 msm8930_slim_0_tx_ch, tx_ch, 0 , 0);
661 if (ret < 0) {
662 pr_err("%s: failed to set cpu chan map\n", __func__);
663 goto end;
664 }
665 ret = snd_soc_dai_set_channel_map(codec_dai,
666 msm8930_slim_0_tx_ch, tx_ch, 0, 0);
667 if (ret < 0) {
668 pr_err("%s: failed to set codec channel map\n",
669 __func__);
670 goto end;
671 }
672
673 }
674end:
675 return ret;
676}
677
678static int msm8930_audrx_init(struct snd_soc_pcm_runtime *rtd)
679{
680 int err;
681 struct snd_soc_codec *codec = rtd->codec;
682 struct snd_soc_dapm_context *dapm = &codec->dapm;
683 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
684
685 pr_debug("%s()\n", __func__);
686
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530687 snd_soc_dapm_new_controls(dapm, msm8930_dapm_widgets,
688 ARRAY_SIZE(msm8930_dapm_widgets));
689
690 snd_soc_dapm_add_routes(dapm, common_audio_map,
691 ARRAY_SIZE(common_audio_map));
692
693 snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Pos");
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800694 snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Neg");
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530695
696 snd_soc_dapm_sync(dapm);
697
698 err = snd_soc_jack_new(codec, "Headset Jack",
699 (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR),
700 &hs_jack);
701 if (err) {
702 pr_err("failed to create new jack\n");
703 return err;
704 }
705
706 err = snd_soc_jack_new(codec, "Button Jack",
Bhalchandra Gajare7708ee32012-05-24 17:37:37 -0700707 SITAR_JACK_BUTTON_MASK, &button_jack);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530708 if (err) {
709 pr_err("failed to create new jack\n");
710 return err;
711 }
712 codec_clk = clk_get(cpu_dai->dev, "osr_clk");
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -0800713
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -0700714 mbhc_cfg.gpio = 37;
715 mbhc_cfg.gpio_irq = gpio_to_irq(mbhc_cfg.gpio);
716 sitar_hs_detect(codec, &mbhc_cfg);
717
Bhalchandra Gajareb28275f2012-08-13 12:32:12 -0700718 if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) {
719 /* Initialize default PMIC speaker gain */
720 pm8xxx_spk_gain(DEFAULT_PMIC_SPK_GAIN);
721 }
Bhalchandra Gajare97676792012-05-22 17:41:45 -0700722
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530723 return 0;
724}
725
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530726static int msm8930_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
727 struct snd_pcm_hw_params *params)
728{
729 struct snd_interval *rate = hw_param_interval(params,
730 SNDRV_PCM_HW_PARAM_RATE);
731
732 struct snd_interval *channels = hw_param_interval(params,
733 SNDRV_PCM_HW_PARAM_CHANNELS);
734
735 pr_debug("%s()\n", __func__);
736 rate->min = rate->max = 48000;
737 channels->min = channels->max = msm8930_slim_0_rx_ch;
738
739 return 0;
740}
741
742static int msm8930_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
743 struct snd_pcm_hw_params *params)
744{
745 struct snd_interval *rate = hw_param_interval(params,
746 SNDRV_PCM_HW_PARAM_RATE);
747
748 struct snd_interval *channels = hw_param_interval(params,
749 SNDRV_PCM_HW_PARAM_CHANNELS);
750
751 pr_debug("%s()\n", __func__);
752 rate->min = rate->max = 48000;
753 channels->min = channels->max = msm8930_slim_0_tx_ch;
754
755 return 0;
756}
757
758static int msm8930_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
759 struct snd_pcm_hw_params *params)
760{
761 struct snd_interval *rate = hw_param_interval(params,
762 SNDRV_PCM_HW_PARAM_RATE);
763
764 pr_debug("%s()\n", __func__);
765 rate->min = rate->max = 48000;
766
767 return 0;
768}
769
770static int msm8930_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
771 struct snd_pcm_hw_params *params)
772{
773 struct snd_interval *rate = hw_param_interval(params,
774 SNDRV_PCM_HW_PARAM_RATE);
775
776 struct snd_interval *channels = hw_param_interval(params,
777 SNDRV_PCM_HW_PARAM_CHANNELS);
778
Vicky Sehrawat53f5c2e2012-11-05 17:54:13 -0800779 if (!hdmi_rate_variable)
780 rate->min = rate->max = 48000;
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530781 channels->min = channels->max = 2;
782
783 return 0;
784}
785
786static int msm8930_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
787 struct snd_pcm_hw_params *params)
788{
789 struct snd_interval *rate = hw_param_interval(params,
790 SNDRV_PCM_HW_PARAM_RATE);
791
792 struct snd_interval *channels = hw_param_interval(params,
793 SNDRV_PCM_HW_PARAM_CHANNELS);
794
795 rate->min = rate->max = msm8930_btsco_rate;
796 channels->min = channels->max = msm8930_btsco_ch;
797
798 return 0;
799}
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530800
Bhalchandra Gajare2e0893e2012-05-24 00:39:47 -0700801static int msm8930_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
802 struct snd_pcm_hw_params *params)
803{
804 struct snd_interval *rate = hw_param_interval(params,
805 SNDRV_PCM_HW_PARAM_RATE);
806
807 struct snd_interval *channels = hw_param_interval(params,
808 SNDRV_PCM_HW_PARAM_CHANNELS);
809
810 /* PCM only supports mono output with 8khz sample rate */
811 rate->min = rate->max = 8000;
812 channels->min = channels->max = 1;
813
814 return 0;
815}
816
Jayasena Sangaraboina6b4de782012-10-23 16:52:01 -0700817static int msm8930_proxy_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
818 struct snd_pcm_hw_params *params)
819{
820 struct snd_interval *rate = hw_param_interval(params,
821 SNDRV_PCM_HW_PARAM_RATE);
822
823 pr_debug("%s()\n", __func__);
824 rate->min = rate->max = 48000;
825
826 return 0;
827}
828
Bhalchandra Gajare2e0893e2012-05-24 00:39:47 -0700829static int msm8930_aux_pcm_get_gpios(void)
830{
831 int ret = 0;
832
833 pr_debug("%s\n", __func__);
834
835 ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT");
836 if (ret < 0) {
837 pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT",
838 __func__, GPIO_AUX_PCM_DOUT);
839
840 goto fail_dout;
841 }
842
843 ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN");
844 if (ret < 0) {
845 pr_err("%s: Failed to request gpio(%d): AUX PCM DIN",
846 __func__, GPIO_AUX_PCM_DIN);
847 goto fail_din;
848 }
849
850 ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC");
851 if (ret < 0) {
852 pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC",
853 __func__, GPIO_AUX_PCM_SYNC);
854 goto fail_sync;
855 }
856
857 ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK");
858 if (ret < 0) {
859 pr_err("%s: Failed to request gpio(%d): AUX PCM CLK",
860 __func__, GPIO_AUX_PCM_CLK);
861 goto fail_clk;
862 }
863
864 return 0;
865
866fail_clk:
867 gpio_free(GPIO_AUX_PCM_SYNC);
868fail_sync:
869 gpio_free(GPIO_AUX_PCM_DIN);
870fail_din:
871 gpio_free(GPIO_AUX_PCM_DOUT);
872fail_dout:
873
874 return ret;
875}
876
877static int msm8930_aux_pcm_free_gpios(void)
878{
879 gpio_free(GPIO_AUX_PCM_DIN);
880 gpio_free(GPIO_AUX_PCM_DOUT);
881 gpio_free(GPIO_AUX_PCM_SYNC);
882 gpio_free(GPIO_AUX_PCM_CLK);
883
884 return 0;
885}
886
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530887static int msm8930_startup(struct snd_pcm_substream *substream)
888{
889 pr_debug("%s(): substream = %s stream = %d\n", __func__,
890 substream->name, substream->stream);
891 return 0;
892}
893
Bhalchandra Gajare2e0893e2012-05-24 00:39:47 -0700894static int msm8930_auxpcm_startup(struct snd_pcm_substream *substream)
895{
896 int ret = 0;
897
Kuirong Wang892c9ad2012-09-20 11:43:17 -0700898 pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
899 __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
900 if (atomic_inc_return(&auxpcm_rsc_ref) == 1)
901 ret = msm8930_aux_pcm_get_gpios();
Bhalchandra Gajare2e0893e2012-05-24 00:39:47 -0700902 if (ret < 0) {
903 pr_err("%s: Aux PCM GPIO request failed\n", __func__);
904 return -EINVAL;
905 }
906 return 0;
907
908}
909
910static void msm8930_auxpcm_shutdown(struct snd_pcm_substream *substream)
911{
Kuirong Wang892c9ad2012-09-20 11:43:17 -0700912 pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
913 __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
914 if (atomic_dec_return(&auxpcm_rsc_ref) == 0)
915 msm8930_aux_pcm_free_gpios();
Bhalchandra Gajare2e0893e2012-05-24 00:39:47 -0700916}
917
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530918static void msm8930_shutdown(struct snd_pcm_substream *substream)
919{
920 pr_debug("%s(): substream = %s stream = %d\n", __func__,
921 substream->name, substream->stream);
922}
923
924static struct snd_soc_ops msm8930_be_ops = {
925 .startup = msm8930_startup,
926 .hw_params = msm8930_hw_params,
927 .shutdown = msm8930_shutdown,
928};
929
Bhalchandra Gajare2e0893e2012-05-24 00:39:47 -0700930static struct snd_soc_ops msm8930_auxpcm_be_ops = {
931 .startup = msm8930_auxpcm_startup,
932 .shutdown = msm8930_auxpcm_shutdown,
933};
934
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530935/* Digital audio interface glue - connects codec <---> CPU */
936static struct snd_soc_dai_link msm8930_dai[] = {
937 /* FrontEnd DAI Links */
938 {
939 .name = "MSM8930 Media1",
940 .stream_name = "MultiMedia1",
941 .cpu_dai_name = "MultiMedia1",
942 .platform_name = "msm-pcm-dsp",
943 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -0700944 .codec_dai_name = "snd-soc-dummy-dai",
945 .codec_name = "snd-soc-dummy",
946 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
947 .ignore_suspend = 1,
948 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530949 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
950 },
951 {
952 .name = "MSM8930 Media2",
953 .stream_name = "MultiMedia2",
954 .cpu_dai_name = "MultiMedia2",
Asish Bhattacharyae2601ae2012-07-18 21:13:21 +0530955 .platform_name = "msm-multi-ch-pcm-dsp",
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530956 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -0700957 .codec_dai_name = "snd-soc-dummy-dai",
958 .codec_name = "snd-soc-dummy",
959 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
960 .ignore_suspend = 1,
961 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530962 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
963 },
964 {
965 .name = "Circuit-Switch Voice",
966 .stream_name = "CS-Voice",
967 .cpu_dai_name = "CS-VOICE",
968 .platform_name = "msm-pcm-voice",
969 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -0700970 .codec_dai_name = "snd-soc-dummy-dai",
971 .codec_name = "snd-soc-dummy",
972 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530973 .be_id = MSM_FRONTEND_DAI_CS_VOICE,
974 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
975 .ignore_suspend = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -0700976 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530977 },
978 {
979 .name = "MSM VoIP",
980 .stream_name = "VoIP",
981 .cpu_dai_name = "VoIP",
982 .platform_name = "msm-voip-dsp",
983 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -0700984 .codec_dai_name = "snd-soc-dummy-dai",
985 .codec_name = "snd-soc-dummy",
986 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
987 .ignore_suspend = 1,
988 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530989 .be_id = MSM_FRONTEND_DAI_VOIP,
990 },
991 {
992 .name = "MSM8930 LPA",
993 .stream_name = "LPA",
994 .cpu_dai_name = "MultiMedia3",
995 .platform_name = "msm-pcm-lpa",
996 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -0700997 .codec_dai_name = "snd-soc-dummy-dai",
998 .codec_name = "snd-soc-dummy",
999 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
1000 .ignore_suspend = 1,
1001 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301002 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3,
1003 },
1004 /* Hostless PMC purpose */
1005 {
1006 .name = "SLIMBUS_0 Hostless",
1007 .stream_name = "SLIMBUS_0 Hostless",
1008 .cpu_dai_name = "SLIMBUS0_HOSTLESS",
1009 .platform_name = "msm-pcm-hostless",
1010 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001011 .codec_dai_name = "snd-soc-dummy-dai",
1012 .codec_name = "snd-soc-dummy",
1013 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301014 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1015 .ignore_suspend = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001016 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301017 /* .be_id = do not care */
1018 },
1019 {
1020 .name = "INT_FM Hostless",
1021 .stream_name = "INT_FM Hostless",
1022 .cpu_dai_name = "INT_FM_HOSTLESS",
1023 .platform_name = "msm-pcm-hostless",
1024 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001025 .codec_dai_name = "snd-soc-dummy-dai",
1026 .codec_name = "snd-soc-dummy",
1027 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301028 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1029 .ignore_suspend = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001030 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301031 /* .be_id = do not care */
1032 },
1033 {
1034 .name = "MSM AFE-PCM RX",
1035 .stream_name = "AFE-PROXY RX",
1036 .cpu_dai_name = "msm-dai-q6.241",
1037 .codec_name = "msm-stub-codec.1",
1038 .codec_dai_name = "msm-stub-rx",
1039 .platform_name = "msm-pcm-afe",
1040 .ignore_suspend = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001041 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301042 },
1043 {
1044 .name = "MSM AFE-PCM TX",
1045 .stream_name = "AFE-PROXY TX",
1046 .cpu_dai_name = "msm-dai-q6.240",
1047 .codec_name = "msm-stub-codec.1",
1048 .codec_dai_name = "msm-stub-tx",
1049 .platform_name = "msm-pcm-afe",
1050 .ignore_suspend = 1,
1051 },
1052 {
1053 .name = "MSM8930 Compr",
1054 .stream_name = "COMPR",
1055 .cpu_dai_name = "MultiMedia4",
1056 .platform_name = "msm-compr-dsp",
1057 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001058 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
1059 .codec_dai_name = "snd-soc-dummy-dai",
1060 .codec_name = "snd-soc-dummy",
1061 .ignore_suspend = 1,
1062 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301063 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
1064 },
1065 {
1066 .name = "AUXPCM Hostless",
1067 .stream_name = "AUXPCM Hostless",
1068 .cpu_dai_name = "AUXPCM_HOSTLESS",
1069 .platform_name = "msm-pcm-hostless",
1070 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001071 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301072 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1073 .ignore_suspend = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001074 .ignore_pmdown_time = 1, /* this dainlink has playback support */
1075 .codec_dai_name = "snd-soc-dummy-dai",
1076 .codec_name = "snd-soc-dummy",
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301077 },
1078 /* HDMI Hostless */
1079 {
1080 .name = "HDMI_RX_HOSTLESS",
1081 .stream_name = "HDMI_RX_HOSTLESS",
1082 .cpu_dai_name = "HDMI_HOSTLESS",
1083 .platform_name = "msm-pcm-hostless",
1084 .dynamic = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001085 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301086 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301087 .ignore_suspend = 1,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001088 .ignore_pmdown_time = 1, /* this dainlink has playback support */
1089 .codec_dai_name = "snd-soc-dummy-dai",
1090 .codec_name = "snd-soc-dummy",
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301091 },
Jayasena Sangaraboina99bf09c2012-07-17 12:03:08 -07001092 {
1093 .name = "VoLTE",
1094 .stream_name = "VoLTE",
1095 .cpu_dai_name = "VoLTE",
1096 .platform_name = "msm-pcm-voice",
1097 .dynamic = 1,
1098 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1099 SND_SOC_DPCM_TRIGGER_POST},
1100 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1101 .ignore_suspend = 1,
1102 /* this dainlink has playback support */
1103 .ignore_pmdown_time = 1,
1104 .codec_dai_name = "snd-soc-dummy-dai",
1105 .codec_name = "snd-soc-dummy",
1106 .be_id = MSM_FRONTEND_DAI_VOLTE,
1107 },
1108 {
1109 .name = "SGLTE",
1110 .stream_name = "SGLTE",
1111 .cpu_dai_name = "SGLTE",
1112 .platform_name = "msm-pcm-voice",
1113 .dynamic = 1,
1114 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1115 SND_SOC_DPCM_TRIGGER_POST},
1116 .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
1117 .ignore_suspend = 1,
1118 /* this dainlink has playback support */
1119 .ignore_pmdown_time = 1,
1120 .codec_dai_name = "snd-soc-dummy-dai",
1121 .codec_name = "snd-soc-dummy",
1122 .be_id = MSM_FRONTEND_DAI_SGLTE,
1123 },
1124 {
1125 .name = "MSM8960 LowLatency",
1126 .stream_name = "MultiMedia5",
1127 .cpu_dai_name = "MultiMedia5",
1128 .platform_name = "msm-lowlatency-pcm-dsp",
1129 .dynamic = 1,
1130 .codec_dai_name = "snd-soc-dummy-dai",
1131 .codec_name = "snd-soc-dummy",
1132 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
1133 SND_SOC_DPCM_TRIGGER_POST},
1134 .ignore_suspend = 1,
1135 /* this dainlink has playback support */
1136 .ignore_pmdown_time = 1,
1137 .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
1138 },
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301139 /* Backend DAI Links */
1140 {
1141 .name = LPASS_BE_SLIMBUS_0_RX,
1142 .stream_name = "Slimbus Playback",
1143 .cpu_dai_name = "msm-dai-q6.16384",
1144 .platform_name = "msm-pcm-routing",
1145 .codec_name = "sitar_codec",
1146 .codec_dai_name = "sitar_rx1",
1147 .no_pcm = 1,
1148 .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
1149 .init = &msm8930_audrx_init,
1150 .be_hw_params_fixup = msm8930_slim_0_rx_be_hw_params_fixup,
1151 .ops = &msm8930_be_ops,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001152 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301153 },
1154 {
1155 .name = LPASS_BE_SLIMBUS_0_TX,
1156 .stream_name = "Slimbus Capture",
1157 .cpu_dai_name = "msm-dai-q6.16385",
1158 .platform_name = "msm-pcm-routing",
1159 .codec_name = "sitar_codec",
1160 .codec_dai_name = "sitar_tx1",
1161 .no_pcm = 1,
1162 .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
1163 .be_hw_params_fixup = msm8930_slim_0_tx_be_hw_params_fixup,
1164 .ops = &msm8930_be_ops,
1165 },
1166 /* Backend BT/FM DAI Links */
1167 {
1168 .name = LPASS_BE_INT_BT_SCO_RX,
1169 .stream_name = "Internal BT-SCO Playback",
1170 .cpu_dai_name = "msm-dai-q6.12288",
1171 .platform_name = "msm-pcm-routing",
1172 .codec_name = "msm-stub-codec.1",
1173 .codec_dai_name = "msm-stub-rx",
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301174 .no_pcm = 1,
1175 .be_id = MSM_BACKEND_DAI_INT_BT_SCO_RX,
1176 .be_hw_params_fixup = msm8930_btsco_be_hw_params_fixup,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001177 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301178 },
1179 {
1180 .name = LPASS_BE_INT_BT_SCO_TX,
1181 .stream_name = "Internal BT-SCO Capture",
1182 .cpu_dai_name = "msm-dai-q6.12289",
1183 .platform_name = "msm-pcm-routing",
1184 .codec_name = "msm-stub-codec.1",
1185 .codec_dai_name = "msm-stub-tx",
1186 .no_pcm = 1,
1187 .be_id = MSM_BACKEND_DAI_INT_BT_SCO_TX,
1188 .be_hw_params_fixup = msm8930_btsco_be_hw_params_fixup,
1189 },
1190 {
1191 .name = LPASS_BE_INT_FM_RX,
1192 .stream_name = "Internal FM Playback",
1193 .cpu_dai_name = "msm-dai-q6.12292",
1194 .platform_name = "msm-pcm-routing",
1195 .codec_name = "msm-stub-codec.1",
1196 .codec_dai_name = "msm-stub-rx",
1197 .no_pcm = 1,
1198 .be_id = MSM_BACKEND_DAI_INT_FM_RX,
1199 .be_hw_params_fixup = msm8930_be_hw_params_fixup,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001200 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301201 },
1202 {
1203 .name = LPASS_BE_INT_FM_TX,
1204 .stream_name = "Internal FM Capture",
1205 .cpu_dai_name = "msm-dai-q6.12293",
1206 .platform_name = "msm-pcm-routing",
1207 .codec_name = "msm-stub-codec.1",
1208 .codec_dai_name = "msm-stub-tx",
1209 .no_pcm = 1,
1210 .be_id = MSM_BACKEND_DAI_INT_FM_TX,
1211 .be_hw_params_fixup = msm8930_be_hw_params_fixup,
1212 },
1213 /* HDMI BACK END DAI Link */
1214 {
1215 .name = LPASS_BE_HDMI,
1216 .stream_name = "HDMI Playback",
1217 .cpu_dai_name = "msm-dai-q6-hdmi.8",
1218 .platform_name = "msm-pcm-routing",
1219 .codec_name = "msm-stub-codec.1",
1220 .codec_dai_name = "msm-stub-rx",
1221 .no_pcm = 1,
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301222 .be_id = MSM_BACKEND_DAI_HDMI_RX,
1223 .be_hw_params_fixup = msm8930_hdmi_be_hw_params_fixup,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001224 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301225 },
1226 /* Backend AFE DAI Links */
1227 {
1228 .name = LPASS_BE_AFE_PCM_RX,
1229 .stream_name = "AFE Playback",
1230 .cpu_dai_name = "msm-dai-q6.224",
1231 .platform_name = "msm-pcm-routing",
1232 .codec_name = "msm-stub-codec.1",
1233 .codec_dai_name = "msm-stub-rx",
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301234 .no_pcm = 1,
1235 .be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
Jayasena Sangaraboina6b4de782012-10-23 16:52:01 -07001236 .be_hw_params_fixup = msm8930_proxy_be_hw_params_fixup,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001237 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301238 },
1239 {
1240 .name = LPASS_BE_AFE_PCM_TX,
1241 .stream_name = "AFE Capture",
1242 .cpu_dai_name = "msm-dai-q6.225",
1243 .platform_name = "msm-pcm-routing",
1244 .codec_name = "msm-stub-codec.1",
1245 .codec_dai_name = "msm-stub-tx",
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301246 .no_pcm = 1,
1247 .be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
Jayasena Sangaraboina6b4de782012-10-23 16:52:01 -07001248 .be_hw_params_fixup = msm8930_proxy_be_hw_params_fixup,
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301249 },
Bhalchandra Gajare2e0893e2012-05-24 00:39:47 -07001250 /* AUX PCM Backend DAI Links */
1251 {
1252 .name = LPASS_BE_AUXPCM_RX,
1253 .stream_name = "AUX PCM Playback",
1254 .cpu_dai_name = "msm-dai-q6.2",
1255 .platform_name = "msm-pcm-routing",
1256 .codec_name = "msm-stub-codec.1",
1257 .codec_dai_name = "msm-stub-rx",
1258 .no_pcm = 1,
1259 .be_id = MSM_BACKEND_DAI_AUXPCM_RX,
1260 .be_hw_params_fixup = msm8930_auxpcm_be_params_fixup,
1261 .ops = &msm8930_auxpcm_be_ops,
1262 },
1263 {
1264 .name = LPASS_BE_AUXPCM_TX,
1265 .stream_name = "AUX PCM Capture",
1266 .cpu_dai_name = "msm-dai-q6.3",
1267 .platform_name = "msm-pcm-routing",
1268 .codec_name = "msm-stub-codec.1",
1269 .codec_dai_name = "msm-stub-tx",
1270 .no_pcm = 1,
1271 .be_id = MSM_BACKEND_DAI_AUXPCM_TX,
1272 .be_hw_params_fixup = msm8930_auxpcm_be_params_fixup,
Kuirong Wang892c9ad2012-09-20 11:43:17 -07001273 .ops = &msm8930_auxpcm_be_ops,
Bhalchandra Gajare2e0893e2012-05-24 00:39:47 -07001274 },
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301275 /* Incall Music BACK END DAI Link */
1276 {
1277 .name = LPASS_BE_VOICE_PLAYBACK_TX,
1278 .stream_name = "Voice Farend Playback",
1279 .cpu_dai_name = "msm-dai-q6.32773",
1280 .platform_name = "msm-pcm-routing",
1281 .codec_name = "msm-stub-codec.1",
1282 .codec_dai_name = "msm-stub-rx",
1283 .no_pcm = 1,
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301284 .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
1285 .be_hw_params_fixup = msm8930_be_hw_params_fixup,
1286 },
1287 /* Incall Record Uplink BACK END DAI Link */
1288 {
1289 .name = LPASS_BE_INCALL_RECORD_TX,
1290 .stream_name = "Voice Uplink Capture",
1291 .cpu_dai_name = "msm-dai-q6.32772",
1292 .platform_name = "msm-pcm-routing",
1293 .codec_name = "msm-stub-codec.1",
1294 .codec_dai_name = "msm-stub-tx",
1295 .no_pcm = 1,
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301296 .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
1297 .be_hw_params_fixup = msm8930_be_hw_params_fixup,
1298 },
1299 /* Incall Record Downlink BACK END DAI Link */
1300 {
1301 .name = LPASS_BE_INCALL_RECORD_RX,
1302 .stream_name = "Voice Downlink Capture",
1303 .cpu_dai_name = "msm-dai-q6.32771",
1304 .platform_name = "msm-pcm-routing",
1305 .codec_name = "msm-stub-codec.1",
1306 .codec_dai_name = "msm-stub-tx",
1307 .no_pcm = 1,
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301308 .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
1309 .be_hw_params_fixup = msm8930_be_hw_params_fixup,
Steve Mucklef132c6c2012-06-06 18:30:57 -07001310 .ignore_pmdown_time = 1, /* this dainlink has playback support */
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301311 },
1312};
1313
1314struct snd_soc_card snd_soc_card_msm8930 = {
1315 .name = "msm8930-sitar-snd-card",
1316 .dai_link = msm8930_dai,
1317 .num_links = ARRAY_SIZE(msm8930_dai),
Steve Mucklef132c6c2012-06-06 18:30:57 -07001318 .controls = sitar_msm8930_controls,
1319 .num_controls = ARRAY_SIZE(sitar_msm8930_controls),
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301320};
1321
1322static struct platform_device *msm8930_snd_device;
1323
1324static int msm8930_configure_headset_mic_gpios(void)
1325{
1326 int ret;
1327 ret = gpio_request(80, "US_EURO_SWITCH");
1328 if (ret) {
1329 pr_err("%s: Failed to request gpio 80\n", __func__);
1330 return ret;
1331 }
1332 ret = gpio_direction_output(80, 0);
1333 if (ret) {
1334 pr_err("%s: Unable to set direction\n", __func__);
1335 gpio_free(80);
1336 }
1337 msm8930_headset_gpios_configured = 0;
1338 return 0;
1339}
1340static void msm8930_free_headset_mic_gpios(void)
1341{
1342 if (msm8930_headset_gpios_configured)
1343 gpio_free(80);
1344}
1345
1346static int __init msm8930_audio_init(void)
1347{
1348 int ret;
1349
Stepan Moskovchenkoc6a603a2012-09-21 20:32:17 -07001350 if (!soc_class_is_msm8930()) {
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301351 pr_err("%s: Not the right machine type\n", __func__);
1352 return -ENODEV ;
1353 }
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -07001354 mbhc_cfg.calibration = def_sitar_mbhc_cal();
1355 if (!mbhc_cfg.calibration) {
Asish Bhattacharyaf868a1f2012-03-05 10:07:44 -08001356 pr_err("Calibration data allocation failed\n");
1357 return -ENOMEM;
1358 }
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301359
1360 msm8930_snd_device = platform_device_alloc("soc-audio", 0);
1361 if (!msm8930_snd_device) {
1362 pr_err("Platform device allocation failed\n");
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -07001363 kfree(mbhc_cfg.calibration);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301364 return -ENOMEM;
1365 }
1366
1367 platform_set_drvdata(msm8930_snd_device, &snd_soc_card_msm8930);
1368 ret = platform_device_add(msm8930_snd_device);
1369 if (ret) {
1370 platform_device_put(msm8930_snd_device);
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -07001371 kfree(mbhc_cfg.calibration);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301372 return ret;
1373 }
1374
1375 if (msm8930_configure_headset_mic_gpios()) {
1376 pr_err("%s Fail to configure headset mic gpios\n", __func__);
1377 msm8930_headset_gpios_configured = 0;
1378 } else
1379 msm8930_headset_gpios_configured = 1;
1380
Kuirong Wang892c9ad2012-09-20 11:43:17 -07001381 atomic_set(&auxpcm_rsc_ref, 0);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301382 return ret;
1383
1384}
1385module_init(msm8930_audio_init);
1386
1387static void __exit msm8930_audio_exit(void)
1388{
Stepan Moskovchenkoc6a603a2012-09-21 20:32:17 -07001389 if (!soc_class_is_msm8930()) {
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301390 pr_err("%s: Not the right machine type\n", __func__);
1391 return ;
1392 }
1393 msm8930_free_headset_mic_gpios();
1394 platform_device_unregister(msm8930_snd_device);
Bhalchandra Gajare466aafe2012-05-02 17:55:26 -07001395 kfree(mbhc_cfg.calibration);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301396}
1397module_exit(msm8930_audio_exit);
1398
1399MODULE_DESCRIPTION("ALSA SoC MSM8930");
1400MODULE_LICENSE("GPL v2");