2 * Exynos machine ASoC driver for boards using MAX98095 or MAX98088
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/clk.h>
26 #include <linux/of_gpio.h>
28 #include <linux/of_device.h>
30 #include <sound/soc.h>
31 #include <sound/soc-dapm.h>
32 #include <sound/pcm.h>
33 #include <sound/pcm_params.h>
34 #include <sound/jack.h>
35 #include <sound/max98095.h>
36 #include <sound/max98088.h>
38 #include <mach/regs-clock.h>
39 #include <mach/gpio.h>
42 #include "s3c-i2s-v2.h"
43 #include "../codecs/max98095.h"
44 #include "../codecs/max98088.h"
45 #include "codec_plugin.h"
47 #define DRV_NAME "daisy-snd-max98095"
49 struct daisy_max98095 {
50 struct platform_device *pcm_dev;
53 /* Audio clock settings are belonged to board specific part. Every
54 * board can set audio source clock setting which is matched with H/W
55 * like this function-'set_audio_clock_heirachy'.
57 static int set_audio_clock_heirachy(struct platform_device *pdev)
59 struct clk *fout_epll, *mout_epll, *sclk_audbus, *audss, *i2sclk;
62 fout_epll = clk_get(NULL, "fout_epll");
63 if (IS_ERR(fout_epll)) {
64 printk(KERN_WARNING "%s: Cannot find fout_epll.\n",
69 mout_epll = clk_get(NULL, "mout_epll");
70 if (IS_ERR(mout_epll)) {
71 printk(KERN_WARNING "%s: Cannot find mout_epll.\n",
77 sclk_audbus = clk_get(&pdev->dev, "audio-bus");
78 if (IS_ERR(sclk_audbus)) {
79 printk(KERN_WARNING "%s: Cannot find audio-bus.\n",
85 audss = clk_get(&pdev->dev, "mout_audss");
87 printk(KERN_WARNING "%s: Cannot find audss.\n",
93 i2sclk = clk_get(NULL, "i2sclk");
95 printk(KERN_WARNING "%s: Cannot find i2sclk.\n",
101 /* Set audio clock hierarchy for S/PDIF */
102 if (clk_set_parent(mout_epll, fout_epll))
103 printk(KERN_WARNING "Failed to set parent of epll.\n");
104 if (clk_set_parent(sclk_audbus, mout_epll))
105 printk(KERN_WARNING "Failed to set parent of audbus.\n");
106 if (clk_set_parent(audss, fout_epll))
107 printk(KERN_WARNING "Failed to set parent of audss.\n");
108 if (clk_set_parent(i2sclk, sclk_audbus))
109 printk(KERN_WARNING "Failed to set parent of i2sclk.\n");
115 clk_put(sclk_audbus);
124 static int set_epll_rate(unsigned long rate)
127 struct clk *fout_epll;
129 fout_epll = clk_get(NULL, "fout_epll");
131 if (IS_ERR(fout_epll)) {
132 printk(KERN_ERR "%s: failed to get fout_epll\n", __func__);
133 return PTR_ERR(fout_epll);
136 if (rate == clk_get_rate(fout_epll))
139 ret = clk_set_rate(fout_epll, rate);
141 printk(KERN_ERR "failed to clk_set_rate of fout_epll for audio\n");
150 static int daisy_hw_params(struct snd_pcm_substream *substream,
151 struct snd_pcm_hw_params *params)
153 struct snd_soc_pcm_runtime *rtd = substream->private_data;
154 struct snd_soc_dai *codec_dai = rtd->codec_dai;
155 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
156 int bfs, psr, rfs, ret;
159 struct clk *xtal_clk;
161 switch (params_format(params)) {
162 case SNDRV_PCM_FORMAT_U24:
163 case SNDRV_PCM_FORMAT_S24:
166 case SNDRV_PCM_FORMAT_U16_LE:
167 case SNDRV_PCM_FORMAT_S16_LE:
174 switch (params_rate(params)) {
203 rclk = params_rate(params) * rfs;
231 printk(KERN_ERR "rclk = %lu is not yet supported!\n", rclk);
235 ret = set_epll_rate(rclk * psr);
239 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
240 SND_SOC_DAIFMT_NB_NF |
241 SND_SOC_DAIFMT_CBS_CFS);
245 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
246 SND_SOC_DAIFMT_NB_NF |
247 SND_SOC_DAIFMT_CBS_CFS);
251 xtal_clk = clk_get(NULL, "xtal"); /*xtal clk is input to codec MCLK1*/
252 if (IS_ERR(xtal_clk)) {
253 printk(KERN_ERR "%s: failed to get xtal clock\n", __func__);
254 return PTR_ERR(xtal_clk);
257 xtal = clk_get_rate(xtal_clk);
260 ret = snd_soc_dai_set_sysclk(codec_dai, 0, xtal, SND_SOC_CLOCK_IN);
264 ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,
265 0, SND_SOC_CLOCK_OUT);
269 ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs);
277 * MAX98095 DAI operations.
279 static struct snd_soc_ops daisy_ops = {
280 .hw_params = daisy_hw_params,
283 static struct snd_soc_jack daisy_hp_jack;
284 static struct snd_soc_jack_pin daisy_hp_jack_pins[] = {
286 .pin = "Headphone Jack",
287 .mask = SND_JACK_HEADPHONE,
291 static struct snd_soc_jack_gpio daisy_hp_jack_gpio = {
292 .name = "headphone detect",
293 .report = SND_JACK_HEADPHONE,
296 static struct snd_soc_jack daisy_mic_jack;
297 static struct snd_soc_jack_pin daisy_mic_jack_pins[] = {
300 .mask = SND_JACK_MICROPHONE,
304 static struct snd_soc_jack_gpio daisy_mic_jack_gpio = {
305 .name = "mic detect",
306 .report = SND_JACK_MICROPHONE,
309 static const struct snd_soc_dapm_route daisy_audio_map[] = {
310 {"Mic Jack", "NULL", "MICBIAS2"},
311 {"MIC2", "NULL", "Mic Jack"},
314 static const struct snd_soc_dapm_widget daisy_dapm_widgets[] = {
315 SND_SOC_DAPM_MIC("Mic Jack", NULL),
316 SND_SOC_DAPM_HP("Headphone Jack", NULL),
319 static struct snd_soc_jack daisy_hdmi_jack;
321 static int get_hdmi(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_value *ucontrol)
324 struct audio_codec_plugin *plugin;
325 int ret = 0, state = 0;
327 plugin = (struct audio_codec_plugin *)kcontrol->private_value;
332 if (!plugin->ops.hw_params)
335 ret = plugin->ops.get_state(plugin->dev, &state);
339 ucontrol->value.integer.value[0] = (long int)state;
343 static int put_hdmi(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_value *ucontrol)
346 struct audio_codec_plugin *plugin;
349 plugin = (struct audio_codec_plugin *)kcontrol->private_value;
354 if (!plugin->ops.hw_params)
357 state = (int)ucontrol->value.integer.value[0];
358 ret = plugin->ops.set_state(plugin->dev,
359 ucontrol->value.integer.value[0]);
366 static struct snd_kcontrol_new daisy_dapm_controls[] = {
367 SOC_SINGLE_BOOL_EXT("HDMI Playback Switch", 0, get_hdmi, put_hdmi),
370 static int daisy_init(struct snd_soc_pcm_runtime *rtd)
372 struct snd_soc_codec *codec = rtd->codec;
373 struct snd_soc_dapm_context *dapm = &codec->dapm;
374 struct snd_soc_card *card = codec->card;
375 struct device_node *dn = card->dev->of_node;
376 struct audio_codec_plugin *plugin;
379 enum of_gpio_flags flags;
381 daisy_mic_jack_gpio.gpio = of_get_named_gpio_flags(
382 dn, "samsung,mic-det-gpios", 0, &flags);
383 daisy_mic_jack_gpio.invert = !!(flags & OF_GPIO_ACTIVE_LOW);
385 daisy_hp_jack_gpio.gpio = of_get_named_gpio_flags(
386 dn, "samsung,hp-det-gpios", 0, &flags);
387 daisy_hp_jack_gpio.invert = !!(flags & OF_GPIO_ACTIVE_LOW);
390 if (gpio_is_valid(daisy_mic_jack_gpio.gpio)) {
391 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
393 snd_soc_jack_add_pins(&daisy_mic_jack,
394 ARRAY_SIZE(daisy_mic_jack_pins),
395 daisy_mic_jack_pins);
396 snd_soc_jack_add_gpios(&daisy_mic_jack, 1,
397 &daisy_mic_jack_gpio);
400 if (gpio_is_valid(daisy_hp_jack_gpio.gpio)) {
401 snd_soc_jack_new(codec, "Headphone Jack",
402 SND_JACK_HEADPHONE, &daisy_hp_jack);
403 snd_soc_jack_add_pins(&daisy_hp_jack,
404 ARRAY_SIZE(daisy_hp_jack_pins),
406 snd_soc_jack_add_gpios(&daisy_hp_jack, 1,
407 &daisy_hp_jack_gpio);
410 plugin = (void *)daisy_dapm_controls[0].private_value;
412 snd_soc_jack_new(codec, "HDMI Jack",
413 SND_JACK_AVOUT, &daisy_hdmi_jack);
415 /* Microphone BIAS is needed to power the analog mic.
416 * MICBIAS2 is connected to analog mic (MIC3, which is in turn
417 * connected to MIC2 via 'External MIC') on Daisy.
419 * Ultimately, the following should hold:
421 * Microphone in jack => MICBIAS2 enabled &&
422 * 'External Mic' = MIC2
423 * Microphone not in jack => MICBIAS2 disabled &&
424 * 'External Mic' = MIC1
426 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS2");
428 snd_soc_dapm_sync(dapm);
433 static int daisy_resume_post(struct snd_soc_card *card)
435 if (gpio_is_valid(daisy_mic_jack_gpio.gpio))
436 snd_soc_jack_gpio_detect(&daisy_mic_jack_gpio);
438 if (gpio_is_valid(daisy_hp_jack_gpio.gpio))
439 snd_soc_jack_gpio_detect(&daisy_hp_jack_gpio);
444 static int daisy_hdmi_jack_report(int plugged)
446 snd_soc_jack_report(&daisy_hdmi_jack,
447 plugged ? SND_JACK_AVOUT : 0,
452 static struct snd_soc_dai_link daisy_dai[] = {
453 { /* Primary DAI i/f */
454 .name = "MAX98095 RX",
455 .stream_name = "Playback",
456 .cpu_dai_name = "samsung-i2s.0",
457 .codec_dai_name = "HiFi",
458 .platform_name = "samsung-audio",
461 }, { /* Capture i/f */
462 .name = "MAX98095 TX",
463 .stream_name = "Capture",
464 .cpu_dai_name = "samsung-i2s.0",
465 .codec_dai_name = "HiFi",
466 .platform_name = "samsung-audio",
471 static struct snd_soc_card daisy_snd = {
473 .dai_link = daisy_dai,
474 .num_links = ARRAY_SIZE(daisy_dai),
475 .controls = daisy_dapm_controls,
476 .num_controls = ARRAY_SIZE(daisy_dapm_controls),
477 .dapm_widgets = daisy_dapm_widgets,
478 .num_dapm_widgets = ARRAY_SIZE(daisy_dapm_widgets),
479 .dapm_routes = daisy_audio_map,
480 .num_dapm_routes = ARRAY_SIZE(daisy_audio_map),
481 .resume_post = daisy_resume_post,
484 static int plugin_init(struct audio_codec_plugin **pplugin)
486 struct device_node *plugin_node = NULL;
487 struct platform_device *plugin_pdev;
488 struct audio_codec_plugin *plugin;
490 plugin_node = of_find_node_by_name(NULL, "hdmi-audio");
494 plugin_pdev = of_find_device_by_node(plugin_node);
498 plugin = dev_get_drvdata(&plugin_pdev->dev);
504 plugin->jack_cb = daisy_hdmi_jack_report;
509 static __devinit int daisy_max98095_driver_probe(struct platform_device *pdev)
511 struct snd_soc_card *card = &daisy_snd;
512 struct device_node *dn;
513 struct daisy_max98095 *machine;
514 struct audio_codec_plugin *plugin = NULL;
517 if (!pdev->dev.platform_data && !pdev->dev.of_node) {
518 dev_err(&pdev->dev, "No platform data supplied\n");
522 /* The below needs to be replaced with proper full device-tree probing
523 * of the ASoC device, but the core plumbing hasn't been completed yet
524 * so we're doing this only half-way now.
527 if (!of_machine_is_compatible("google,snow") &&
528 !of_machine_is_compatible("google,spring") &&
529 !of_machine_is_compatible("google,daisy"))
532 dn = of_find_compatible_node(NULL, NULL, "maxim,max98095");
534 dn = of_find_compatible_node(NULL, NULL, "maxim,max98089");
539 for (i = 0; i < ARRAY_SIZE(daisy_dai); i++)
540 daisy_dai[i].codec_of_node = of_node_get(dn);
544 machine = devm_kzalloc(&pdev->dev, sizeof(struct daisy_max98095),
547 dev_err(&pdev->dev, "Can't allocate daisy_max98095 struct\n");
551 plugin_init(&plugin);
552 daisy_dapm_controls[0].private_value = (unsigned long)plugin;
554 card->dev = &pdev->dev;
555 platform_set_drvdata(pdev, card);
556 snd_soc_card_set_drvdata(card, machine);
558 machine->pcm_dev = platform_device_register_simple(
559 "daisy-pcm-audio", -1, NULL, 0);
560 if (IS_ERR(machine->pcm_dev)) {
561 dev_err(&pdev->dev, "Can't instantiate daisy-pcm-audio\n");
562 ret = PTR_ERR(machine->pcm_dev);
566 ret = snd_soc_register_card(card);
568 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
572 return set_audio_clock_heirachy(pdev);
575 if (!IS_ERR(machine->pcm_dev))
576 platform_device_unregister(machine->pcm_dev);
580 static int __devexit daisy_max98095_driver_remove(struct platform_device *pdev)
582 struct snd_soc_card *card = platform_get_drvdata(pdev);
583 struct daisy_max98095 *machine = snd_soc_card_get_drvdata(card);
585 snd_soc_unregister_card(card);
587 if (!IS_ERR(machine->pcm_dev))
588 platform_device_unregister(machine->pcm_dev);
593 static const struct of_device_id daisy_max98095_of_match[] __devinitconst = {
594 { .compatible = "google,daisy-audio-max98095", },
595 { .compatible = "google,daisy-audio-max98089", },
599 static struct platform_driver daisy_max98095_driver = {
602 .owner = THIS_MODULE,
603 .pm = &snd_soc_pm_ops,
604 .of_match_table = daisy_max98095_of_match,
606 .probe = daisy_max98095_driver_probe,
607 .remove = __devexit_p(daisy_max98095_driver_remove),
610 module_platform_driver(daisy_max98095_driver);
612 MODULE_DESCRIPTION("ALSA SoC DAISY MAX98095 machine driver");
613 MODULE_LICENSE("GPL");