cq93vc.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
  4. *
  5. * Copyright (C) 2010 Texas Instruments, Inc
  6. *
  7. * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
  8. */
  9. #include <linux/module.h>
  10. #include <linux/moduleparam.h>
  11. #include <linux/init.h>
  12. #include <linux/io.h>
  13. #include <linux/delay.h>
  14. #include <linux/pm.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/device.h>
  17. #include <linux/slab.h>
  18. #include <linux/clk.h>
  19. #include <linux/mfd/davinci_voicecodec.h>
  20. #include <linux/spi/spi.h>
  21. #include <sound/core.h>
  22. #include <sound/pcm.h>
  23. #include <sound/pcm_params.h>
  24. #include <sound/soc.h>
  25. #include <sound/initval.h>
  26. static const struct snd_kcontrol_new cq93vc_snd_controls[] = {
  27. SOC_SINGLE("PGA Capture Volume", DAVINCI_VC_REG05, 0, 0x03, 0),
  28. SOC_SINGLE("Mono DAC Playback Volume", DAVINCI_VC_REG09, 0, 0x3f, 0),
  29. };
  30. static int cq93vc_mute(struct snd_soc_dai *dai, int mute, int direction)
  31. {
  32. struct snd_soc_component *component = dai->component;
  33. u8 reg;
  34. if (mute)
  35. reg = DAVINCI_VC_REG09_MUTE;
  36. else
  37. reg = 0;
  38. snd_soc_component_update_bits(component, DAVINCI_VC_REG09, DAVINCI_VC_REG09_MUTE,
  39. reg);
  40. return 0;
  41. }
  42. static int cq93vc_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  43. int clk_id, unsigned int freq, int dir)
  44. {
  45. switch (freq) {
  46. case 22579200:
  47. case 27000000:
  48. case 33868800:
  49. return 0;
  50. }
  51. return -EINVAL;
  52. }
  53. static int cq93vc_set_bias_level(struct snd_soc_component *component,
  54. enum snd_soc_bias_level level)
  55. {
  56. switch (level) {
  57. case SND_SOC_BIAS_ON:
  58. snd_soc_component_write(component, DAVINCI_VC_REG12,
  59. DAVINCI_VC_REG12_POWER_ALL_ON);
  60. break;
  61. case SND_SOC_BIAS_PREPARE:
  62. break;
  63. case SND_SOC_BIAS_STANDBY:
  64. snd_soc_component_write(component, DAVINCI_VC_REG12,
  65. DAVINCI_VC_REG12_POWER_ALL_OFF);
  66. break;
  67. case SND_SOC_BIAS_OFF:
  68. /* force all power off */
  69. snd_soc_component_write(component, DAVINCI_VC_REG12,
  70. DAVINCI_VC_REG12_POWER_ALL_OFF);
  71. break;
  72. }
  73. return 0;
  74. }
  75. #define CQ93VC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
  76. #define CQ93VC_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
  77. static const struct snd_soc_dai_ops cq93vc_dai_ops = {
  78. .mute_stream = cq93vc_mute,
  79. .set_sysclk = cq93vc_set_dai_sysclk,
  80. .no_capture_mute = 1,
  81. };
  82. static struct snd_soc_dai_driver cq93vc_dai = {
  83. .name = "cq93vc-hifi",
  84. .playback = {
  85. .stream_name = "Playback",
  86. .channels_min = 1,
  87. .channels_max = 2,
  88. .rates = CQ93VC_RATES,
  89. .formats = CQ93VC_FORMATS,},
  90. .capture = {
  91. .stream_name = "Capture",
  92. .channels_min = 1,
  93. .channels_max = 2,
  94. .rates = CQ93VC_RATES,
  95. .formats = CQ93VC_FORMATS,},
  96. .ops = &cq93vc_dai_ops,
  97. };
  98. static int cq93vc_probe(struct snd_soc_component *component)
  99. {
  100. struct davinci_vc *davinci_vc = component->dev->platform_data;
  101. snd_soc_component_init_regmap(component, davinci_vc->regmap);
  102. return 0;
  103. }
  104. static const struct snd_soc_component_driver soc_component_dev_cq93vc = {
  105. .set_bias_level = cq93vc_set_bias_level,
  106. .probe = cq93vc_probe,
  107. .controls = cq93vc_snd_controls,
  108. .num_controls = ARRAY_SIZE(cq93vc_snd_controls),
  109. .idle_bias_on = 1,
  110. .use_pmdown_time = 1,
  111. .endianness = 1,
  112. .non_legacy_dai_naming = 1,
  113. };
  114. static int cq93vc_platform_probe(struct platform_device *pdev)
  115. {
  116. return devm_snd_soc_register_component(&pdev->dev,
  117. &soc_component_dev_cq93vc, &cq93vc_dai, 1);
  118. }
  119. static int cq93vc_platform_remove(struct platform_device *pdev)
  120. {
  121. return 0;
  122. }
  123. static struct platform_driver cq93vc_codec_driver = {
  124. .driver = {
  125. .name = "cq93vc-codec",
  126. },
  127. .probe = cq93vc_platform_probe,
  128. .remove = cq93vc_platform_remove,
  129. };
  130. module_platform_driver(cq93vc_codec_driver);
  131. MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC CQ0093 Voice Codec Driver");
  132. MODULE_AUTHOR("Miguel Aguilar");
  133. MODULE_LICENSE("GPL");