e44855f9d5a5bbf842084cb579e2762651b47148
[linux-2.6.git] / sound / soc / tegra / tegra_cs42l73.c
1 /*
2  * tegra_cs42l73.c - Tegra machine ASoC driver for boards using CS42L73 codec.
3  *
4  * Author: Vijay Mali <vmali@nvidia.com>
5  * Copyright (C) 2011-2012, NVIDIA, Inc.
6  *
7  * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24 #include <asm/mach-types.h>
25
26 #include <linux/clk.h>
27 #include <linux/module.h>
28 #include <linux/platform_device.h>
29 #include <linux/slab.h>
30 #include <linux/gpio.h>
31 #include <linux/regulator/consumer.h>
32 #include <linux/delay.h>
33 #ifdef CONFIG_SWITCH
34 #include <linux/switch.h>
35 #endif
36 #include <mach/tegra_asoc_pdata.h>
37 #include <mach/gpio-tegra.h>
38
39 #include <sound/core.h>
40 #include <sound/jack.h>
41 #include <sound/pcm.h>
42 #include <sound/pcm_params.h>
43 #include <sound/soc.h>
44
45 #include "../codecs/cs42l73.h"
46
47 #include "tegra_pcm.h"
48 #include "tegra_asoc_utils.h"
49
50 #define DRV_NAME "tegra-snd-cs42l73"
51
52 #define GPIO_SPKR_EN    BIT(0)
53 #define GPIO_HP_MUTE    BIT(1)
54 #define GPIO_INT_MIC_EN BIT(2)
55 #define GPIO_EXT_MIC_EN BIT(3)
56 #define GPIO_HP_DET     BIT(4)
57
58 struct tegra_cs42l73 {
59         struct tegra_asoc_utils_data util_data;
60         struct tegra_asoc_platform_data *pdata;
61         struct regulator *spk_reg;
62         struct regulator *dmic_reg;
63         struct regulator *cdc_en;
64         int gpio_requested;
65         enum snd_soc_bias_level bias_level;
66         int clock_enabled;
67 };
68
69 static int tegra_cs42l73_hw_params(struct snd_pcm_substream *substream,
70                                         struct snd_pcm_hw_params *params)
71 {
72         struct snd_soc_pcm_runtime *rtd = substream->private_data;
73         struct snd_soc_dai *codec_dai = rtd->codec_dai;
74         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
75         struct snd_soc_codec *codec = rtd->codec;
76         struct snd_soc_card *card = codec->card;
77         struct tegra_cs42l73 *machine = snd_soc_card_get_drvdata(card);
78         struct tegra_asoc_platform_data *pdata = machine->pdata;
79         int srate, mclk, i2s_daifmt;
80         int err, rate;
81
82         srate = params_rate(params);
83         mclk = 256 * srate;
84
85         i2s_daifmt = SND_SOC_DAIFMT_NB_NF;
86         i2s_daifmt |= pdata->i2s_param[HIFI_CODEC].is_i2s_master ?
87                         SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;
88
89         switch (pdata->i2s_param[HIFI_CODEC].i2s_mode) {
90         case TEGRA_DAIFMT_I2S:
91                 i2s_daifmt |= SND_SOC_DAIFMT_I2S;
92                 break;
93         case TEGRA_DAIFMT_DSP_A:
94                 i2s_daifmt |= SND_SOC_DAIFMT_DSP_A;
95                 break;
96         case TEGRA_DAIFMT_DSP_B:
97                 i2s_daifmt |= SND_SOC_DAIFMT_DSP_B;
98                 break;
99         case TEGRA_DAIFMT_LEFT_J:
100                 i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J;
101                 break;
102         case TEGRA_DAIFMT_RIGHT_J:
103                 i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J;
104                 break;
105         default:
106                 dev_err(card->dev, "Can't configure i2s format\n");
107                 return -EINVAL;
108         }
109
110         err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
111         if (err < 0) {
112                 if (!(machine->util_data.set_mclk % mclk)) {
113                         mclk = machine->util_data.set_mclk;
114                 } else {
115                         dev_err(card->dev, "Can't configure clocks\n");
116                         return err;
117                 }
118         }
119
120         tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
121
122         rate = clk_get_rate(machine->util_data.clk_cdev1);
123
124         err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt);
125         if (err < 0) {
126                 dev_err(card->dev, "codec_dai fmt not set\n");
127                 return err;
128         }
129
130         err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt);
131         if (err < 0) {
132                 dev_err(card->dev, "cpu_dai fmt not set\n");
133                 return err;
134         }
135
136         err = snd_soc_dai_set_sysclk(codec_dai, 0, rate, SND_SOC_CLOCK_IN);
137         if (err < 0) {
138                 dev_err(card->dev, "codec_dai clock not set\n");
139                 return err;
140         }
141
142         return 0;
143 }
144
145 static int tegra_hw_free(struct snd_pcm_substream *substream)
146 {
147         struct snd_soc_pcm_runtime *rtd = substream->private_data;
148         struct tegra_cs42l73 *machine = snd_soc_card_get_drvdata(rtd->card);
149
150         tegra_asoc_utils_lock_clk_rate(&machine->util_data, 0);
151
152         return 0;
153 }
154
155 static struct snd_soc_ops tegra_cs42l73_ops = {
156         .hw_params = tegra_cs42l73_hw_params,
157         .hw_free = tegra_hw_free,
158 };
159
160 static struct snd_soc_jack tegra_cs42l73_hp_jack;
161
162 static struct snd_soc_jack_gpio tegra_cs42l73_hp_jack_gpio = {
163         .name = "headphone detect",
164         .report = SND_JACK_HEADPHONE,
165         .debounce_time = 150,
166         .invert = 1,
167 };
168
169 static int tegra_cs42l73_event_headset_mic(struct snd_soc_dapm_widget *w,
170                                         struct snd_kcontrol *k, int event)
171 {
172
173         struct snd_soc_codec *codec = w->codec;
174         snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 0);
175         snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 0);
176         snd_soc_update_bits(codec, CS42L73_PWRCTL2, PDN_MIC2_BIAS, 0);
177
178         /* Unmask MIC2_SDET interrupt */
179         snd_soc_update_bits(codec, CS42L73_IM1, MIC2_SDET, 1);
180
181         printk(KERN_ERR"[VIJAY] %s +\n", __func__);
182         return 0;
183 }
184
185 static const struct snd_soc_dapm_widget tegra_cs42l73_dapm_widgets[] = {
186         SND_SOC_DAPM_HP("Headphone", NULL),
187         SND_SOC_DAPM_MIC("Headset Mic", tegra_cs42l73_event_headset_mic),
188 };
189
190 static const struct snd_soc_dapm_route tegra_cs42l73_audio_map[] = {
191         {"MIC2", NULL, "Headset Mic"},
192         /* Headphone (L+R)->  HPOUTA, HPOUTB */
193         {"Headphone", NULL, "HPOUTA"},
194         {"Headphone", NULL, "HPOUTB"},
195 };
196
197 static const struct snd_kcontrol_new tegra_cs42l73_controls[] = {
198         SOC_DAPM_PIN_SWITCH("Headphone"),
199         SOC_DAPM_PIN_SWITCH("Headset Mic"),
200 };
201
202 static int tegra_cs42l73_init(struct snd_soc_pcm_runtime *rtd)
203 {
204         struct snd_soc_codec *codec = rtd->codec;
205         struct snd_soc_dapm_context *dapm = &codec->dapm;
206         struct snd_soc_card *card = codec->card;
207         struct tegra_cs42l73 *machine = snd_soc_card_get_drvdata(card);
208         struct tegra_asoc_platform_data *pdata = machine->pdata;
209         int ret;
210
211         if (gpio_is_valid(pdata->gpio_spkr_en)) {
212                 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
213                 if (ret) {
214                         dev_err(card->dev, "cannot get spkr_en gpio\n");
215                         return ret;
216                 }
217                 machine->gpio_requested |= GPIO_SPKR_EN;
218
219                 gpio_direction_output(pdata->gpio_spkr_en, 0);
220         }
221
222         if (gpio_is_valid(pdata->gpio_hp_mute)) {
223                 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
224                 if (ret) {
225                         dev_err(card->dev, "cannot get hp_mute gpio\n");
226                         return ret;
227                 }
228                 machine->gpio_requested |= GPIO_HP_MUTE;
229
230                 gpio_direction_output(pdata->gpio_hp_mute, 0);
231         }
232
233         if (gpio_is_valid(pdata->gpio_int_mic_en)) {
234                 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
235                 if (ret) {
236                         dev_err(card->dev, "cannot get int_mic_en gpio\n");
237                         return ret;
238                 }
239                 machine->gpio_requested |= GPIO_INT_MIC_EN;
240
241                 /* Disable int mic; enable signal is active-high */
242                 gpio_direction_output(pdata->gpio_int_mic_en, 0);
243         }
244
245         if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
246                 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
247                 if (ret) {
248                         dev_err(card->dev, "cannot get ext_mic_en gpio\n");
249                         return ret;
250                 }
251                 machine->gpio_requested |= GPIO_EXT_MIC_EN;
252
253                 /* Disable ext mic; enable signal is active-low */
254                 gpio_direction_output(pdata->gpio_ext_mic_en, 1);
255         }
256
257         machine->bias_level = SND_SOC_BIAS_STANDBY;
258         machine->clock_enabled = 1;
259
260         ret = snd_soc_add_card_controls(card, tegra_cs42l73_controls,
261                         ARRAY_SIZE(tegra_cs42l73_controls));
262         if (ret < 0)
263                 return ret;
264
265         snd_soc_dapm_new_controls(dapm, tegra_cs42l73_dapm_widgets,
266                         ARRAY_SIZE(tegra_cs42l73_dapm_widgets));
267
268         snd_soc_dapm_add_routes(dapm, tegra_cs42l73_audio_map,
269                                 ARRAY_SIZE(tegra_cs42l73_audio_map));
270
271         ret = tegra_asoc_utils_register_ctls(&machine->util_data);
272         if (ret < 0)
273                 return ret;
274
275         /* FIXME: Calculate automatically based on DAPM routes? */
276         snd_soc_dapm_nc_pin(dapm, "LOUTL");
277         snd_soc_dapm_nc_pin(dapm, "LOUTR");
278
279         snd_soc_dapm_sync(dapm);
280
281         return 0;
282 }
283
284 static struct snd_soc_dai_link tegra_cs42l73_dai[] = {
285         {
286                 .name = "CS42L73",
287                 .stream_name = "VSP Playback Record",
288                 .codec_name = "cs42l73.0-004a",
289                 .platform_name = "tegra-pcm-audio",
290                 .cpu_dai_name = "tegra30-i2s.1",
291                 .codec_dai_name = "cs42l73-vsp",
292                 .init = tegra_cs42l73_init,
293                 .ops = &tegra_cs42l73_ops,
294         },
295 };
296
297 static int tegra_cs42l73_resume_pre(struct snd_soc_card *card)
298 {
299         int val;
300         struct snd_soc_jack_gpio *gpio = &tegra_cs42l73_hp_jack_gpio;
301
302         if (gpio_is_valid(gpio->gpio)) {
303                 val = gpio_get_value(gpio->gpio);
304                 val = gpio->invert ? !val : val;
305                 snd_soc_jack_report(gpio->jack, val, gpio->report);
306         }
307
308         return 0;
309 }
310
311 static int tegra_cs42l73_set_bias_level(struct snd_soc_card *card,
312         struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
313 {
314         struct tegra_cs42l73 *machine = snd_soc_card_get_drvdata(card);
315
316         if (machine->bias_level == SND_SOC_BIAS_OFF &&
317                 level != SND_SOC_BIAS_OFF && (!machine->clock_enabled)) {
318                 machine->clock_enabled = 1;
319                 tegra_asoc_utils_clk_enable(&machine->util_data);
320                 machine->bias_level = level;
321         }
322
323         return 0;
324 }
325
326 static int tegra_cs42l73_set_bias_level_post(struct snd_soc_card *card,
327         struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
328 {
329         struct tegra_cs42l73 *machine = snd_soc_card_get_drvdata(card);
330
331         if (machine->bias_level != SND_SOC_BIAS_OFF &&
332                 level == SND_SOC_BIAS_OFF && machine->clock_enabled) {
333                 machine->clock_enabled = 0;
334                 tegra_asoc_utils_clk_disable(&machine->util_data);
335         }
336
337         machine->bias_level = level;
338
339         return 0 ;
340 }
341
342 static struct snd_soc_card snd_soc_tegra_cs42l73 = {
343         .name = "tegra-cs42l73",
344         .owner = THIS_MODULE,
345         .dai_link = tegra_cs42l73_dai,
346         .num_links = ARRAY_SIZE(tegra_cs42l73_dai),
347         .resume_pre = tegra_cs42l73_resume_pre,
348         .set_bias_level = tegra_cs42l73_set_bias_level,
349         .set_bias_level_post = tegra_cs42l73_set_bias_level_post,
350 };
351
352 static __devinit int tegra_cs42l73_driver_probe(struct platform_device *pdev)
353 {
354         struct snd_soc_card *card = &snd_soc_tegra_cs42l73;
355         struct tegra_cs42l73 *machine;
356         struct tegra_asoc_platform_data *pdata;
357         int ret;
358         pdata = pdev->dev.platform_data;
359         if (!pdata) {
360                 dev_err(&pdev->dev, "No platform data supplied\n");
361                 return -EINVAL;
362         }
363
364         if (pdata->codec_name)
365                 card->dai_link->codec_name = pdata->codec_name;
366
367         if (pdata->codec_dai_name)
368                 card->dai_link->codec_dai_name = pdata->codec_dai_name;
369
370         machine = kzalloc(sizeof(struct tegra_cs42l73), GFP_KERNEL);
371         if (!machine) {
372                 dev_err(&pdev->dev, "Can't allocate tegra_cs42l73 struct\n");
373                 return -ENOMEM;
374         }
375
376         if (gpio_is_valid(pdata->gpio_ldo1_en)) {
377                 ret = gpio_request(pdata->gpio_ldo1_en, "cs42l73");
378                 if (ret)
379                         dev_err(&pdev->dev, "Fail gpio_request AUDIO_LDO1\n");
380
381                 ret = gpio_direction_output(pdata->gpio_ldo1_en, 0);
382                 if (ret)
383                         dev_err(&pdev->dev, "Fail gpio_direction AUDIO_LDO1\n");
384
385                 msleep(200);
386         }
387
388         machine->pdata = pdata;
389
390         ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev, card);
391         if (ret)
392                 goto err_free_machine;
393
394         machine->spk_reg = regulator_get(&pdev->dev, "vdd_spk");
395         if (IS_ERR(machine->spk_reg)) {
396                 dev_info(&pdev->dev, "No speaker regulator found\n");
397                 machine->spk_reg = 0;
398         }
399
400         machine->dmic_reg = regulator_get(&pdev->dev, "vdd_mic");
401         if (IS_ERR(machine->dmic_reg)) {
402                 dev_info(&pdev->dev, "No digital mic regulator found\n");
403                 machine->dmic_reg = 0;
404         } else
405                 regulator_enable(machine->dmic_reg);
406
407         card->dev = &pdev->dev;
408         platform_set_drvdata(pdev, card);
409         snd_soc_card_set_drvdata(card, machine);
410         card->dapm.idle_bias_off = 1;
411         ret = snd_soc_register_card(card);
412         if (ret) {
413                 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
414                         ret);
415                 goto err_unregister_switch;
416         }
417
418         if (!card->instantiated) {
419                 ret = -ENODEV;
420                 dev_err(&pdev->dev, "sound card not instantiated (%d)\n",
421                         ret);
422                 goto err_unregister_card;
423         }
424
425         ret = tegra_asoc_utils_set_parent(&machine->util_data,
426                                 pdata->i2s_param[HIFI_CODEC].is_i2s_master);
427         if (ret) {
428                 dev_err(&pdev->dev, "tegra_asoc_utils_set_parent failed (%d)\n",
429                         ret);
430                 goto err_unregister_card;
431         }
432
433 printk(KERN_ERR"%s Checkpoint ... (10)\n", __func__);
434         return 0;
435
436 err_unregister_card:
437         snd_soc_unregister_card(card);
438 err_unregister_switch:
439         tegra_asoc_utils_fini(&machine->util_data);
440 err_free_machine:
441         kfree(machine);
442         return ret;
443 }
444
445 static int __devexit tegra_cs42l73_driver_remove(struct platform_device *pdev)
446 {
447         struct snd_soc_card *card = platform_get_drvdata(pdev);
448         struct tegra_cs42l73 *machine = snd_soc_card_get_drvdata(card);
449         struct tegra_asoc_platform_data *pdata = machine->pdata;
450
451         if (machine->gpio_requested & GPIO_HP_DET)
452                 snd_soc_jack_free_gpios(&tegra_cs42l73_hp_jack,
453                                         1,
454                                         &tegra_cs42l73_hp_jack_gpio);
455         if (machine->gpio_requested & GPIO_EXT_MIC_EN)
456                 gpio_free(pdata->gpio_ext_mic_en);
457         if (machine->gpio_requested & GPIO_INT_MIC_EN)
458                 gpio_free(pdata->gpio_int_mic_en);
459         if (machine->gpio_requested & GPIO_HP_MUTE)
460                 gpio_free(pdata->gpio_hp_mute);
461         if (machine->gpio_requested & GPIO_SPKR_EN)
462                 gpio_free(pdata->gpio_spkr_en);
463         machine->gpio_requested = 0;
464
465         if (machine->spk_reg)
466                 regulator_put(machine->spk_reg);
467         if (machine->dmic_reg)
468                 regulator_put(machine->dmic_reg);
469
470         if (machine->cdc_en) {
471                 regulator_disable(machine->cdc_en);
472                 regulator_put(machine->cdc_en);
473         }
474
475         if (gpio_is_valid(pdata->gpio_ldo1_en)) {
476                 gpio_set_value(pdata->gpio_ldo1_en, 0);
477                 gpio_free(pdata->gpio_ldo1_en);
478         }
479
480         snd_soc_unregister_card(card);
481
482         tegra_asoc_utils_fini(&machine->util_data);
483
484         kfree(machine);
485
486         return 0;
487 }
488
489 static struct platform_driver tegra_cs42l73_driver = {
490         .driver = {
491                 .name = DRV_NAME,
492                 .owner = THIS_MODULE,
493                 .pm = &snd_soc_pm_ops,
494         },
495         .probe = tegra_cs42l73_driver_probe,
496         .remove = __devexit_p(tegra_cs42l73_driver_remove),
497 };
498
499 static int __init tegra_cs42l73_modinit(void)
500 {
501         return platform_driver_register(&tegra_cs42l73_driver);
502 }
503 module_init(tegra_cs42l73_modinit);
504
505 static void __exit tegra_cs42l73_modexit(void)
506 {
507         platform_driver_unregister(&tegra_cs42l73_driver);
508 }
509 module_exit(tegra_cs42l73_modexit);
510
511 MODULE_AUTHOR("Vijay Mali <vmali@nvidia.com>");
512 MODULE_DESCRIPTION("Tegra+CS42L73 machine ASoC driver");
513 MODULE_LICENSE("GPL");
514 MODULE_ALIAS("platform:" DRV_NAME);