e750_wm9705.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * e750-wm9705.c -- SoC audio for e750
  4. *
  5. * Copyright 2007 (c) Ian Molton <[email protected]>
  6. */
  7. #include <linux/module.h>
  8. #include <linux/moduleparam.h>
  9. #include <linux/gpio/consumer.h>
  10. #include <sound/core.h>
  11. #include <sound/pcm.h>
  12. #include <sound/soc.h>
  13. #include <linux/platform_data/asoc-pxa.h>
  14. #include <asm/mach-types.h>
  15. static struct gpio_desc *gpiod_spk_amp, *gpiod_hp_amp;
  16. static int e750_spk_amp_event(struct snd_soc_dapm_widget *w,
  17. struct snd_kcontrol *kcontrol, int event)
  18. {
  19. if (event & SND_SOC_DAPM_PRE_PMU)
  20. gpiod_set_value(gpiod_spk_amp, 1);
  21. else if (event & SND_SOC_DAPM_POST_PMD)
  22. gpiod_set_value(gpiod_spk_amp, 0);
  23. return 0;
  24. }
  25. static int e750_hp_amp_event(struct snd_soc_dapm_widget *w,
  26. struct snd_kcontrol *kcontrol, int event)
  27. {
  28. if (event & SND_SOC_DAPM_PRE_PMU)
  29. gpiod_set_value(gpiod_hp_amp, 1);
  30. else if (event & SND_SOC_DAPM_POST_PMD)
  31. gpiod_set_value(gpiod_hp_amp, 0);
  32. return 0;
  33. }
  34. static const struct snd_soc_dapm_widget e750_dapm_widgets[] = {
  35. SND_SOC_DAPM_HP("Headphone Jack", NULL),
  36. SND_SOC_DAPM_SPK("Speaker", NULL),
  37. SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
  38. SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
  39. e750_hp_amp_event, SND_SOC_DAPM_PRE_PMU |
  40. SND_SOC_DAPM_POST_PMD),
  41. SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
  42. e750_spk_amp_event, SND_SOC_DAPM_PRE_PMU |
  43. SND_SOC_DAPM_POST_PMD),
  44. };
  45. static const struct snd_soc_dapm_route audio_map[] = {
  46. {"Headphone Amp", NULL, "HPOUTL"},
  47. {"Headphone Amp", NULL, "HPOUTR"},
  48. {"Headphone Jack", NULL, "Headphone Amp"},
  49. {"Speaker Amp", NULL, "MONOOUT"},
  50. {"Speaker", NULL, "Speaker Amp"},
  51. {"MIC1", NULL, "Mic (Internal)"},
  52. };
  53. SND_SOC_DAILINK_DEFS(ac97,
  54. DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
  55. DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-hifi")),
  56. DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
  57. SND_SOC_DAILINK_DEFS(ac97_aux,
  58. DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
  59. DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-aux")),
  60. DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
  61. static struct snd_soc_dai_link e750_dai[] = {
  62. {
  63. .name = "AC97",
  64. .stream_name = "AC97 HiFi",
  65. SND_SOC_DAILINK_REG(ac97),
  66. /* use ops to check startup state */
  67. },
  68. {
  69. .name = "AC97 Aux",
  70. .stream_name = "AC97 Aux",
  71. SND_SOC_DAILINK_REG(ac97_aux),
  72. },
  73. };
  74. static struct snd_soc_card e750 = {
  75. .name = "Toshiba e750",
  76. .owner = THIS_MODULE,
  77. .dai_link = e750_dai,
  78. .num_links = ARRAY_SIZE(e750_dai),
  79. .dapm_widgets = e750_dapm_widgets,
  80. .num_dapm_widgets = ARRAY_SIZE(e750_dapm_widgets),
  81. .dapm_routes = audio_map,
  82. .num_dapm_routes = ARRAY_SIZE(audio_map),
  83. .fully_routed = true,
  84. };
  85. static int e750_probe(struct platform_device *pdev)
  86. {
  87. struct snd_soc_card *card = &e750;
  88. int ret;
  89. gpiod_hp_amp = devm_gpiod_get(&pdev->dev, "Headphone amp", GPIOD_OUT_LOW);
  90. ret = PTR_ERR_OR_ZERO(gpiod_hp_amp);
  91. if (ret)
  92. return ret;
  93. gpiod_spk_amp = devm_gpiod_get(&pdev->dev, "Speaker amp", GPIOD_OUT_LOW);
  94. ret = PTR_ERR_OR_ZERO(gpiod_spk_amp);
  95. if (ret)
  96. return ret;
  97. card->dev = &pdev->dev;
  98. ret = devm_snd_soc_register_card(&pdev->dev, card);
  99. if (ret)
  100. dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
  101. ret);
  102. return ret;
  103. }
  104. static int e750_remove(struct platform_device *pdev)
  105. {
  106. return 0;
  107. }
  108. static struct platform_driver e750_driver = {
  109. .driver = {
  110. .name = "e750-audio",
  111. .pm = &snd_soc_pm_ops,
  112. },
  113. .probe = e750_probe,
  114. .remove = e750_remove,
  115. };
  116. module_platform_driver(e750_driver);
  117. /* Module information */
  118. MODULE_AUTHOR("Ian Molton <[email protected]>");
  119. MODULE_DESCRIPTION("ALSA SoC driver for e750");
  120. MODULE_LICENSE("GPL v2");
  121. MODULE_ALIAS("platform:e750-audio");