ark1668e_adc_codec.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. * ARKADC - ark digital-to-analog converter
  3. *
  4. */
  5. #include <linux/module.h>
  6. #include <sound/soc.h>
  7. #include <linux/io.h>
  8. #include <linux/slab.h>
  9. #include "ark1668e_i2s.h"
  10. struct ark_sdadc {
  11. struct device *dev;
  12. void __iomem *sys_base;//sys_base
  13. void __iomem *i2s_base;//i2s_base
  14. unsigned int vol_l;
  15. unsigned int vol_r;
  16. int extdata; //true:external-i2s or false:internal-codec-in(LINEIN/MICIN)
  17. };
  18. #define ARKADC_RATES \
  19. (SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
  20. SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
  21. SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
  22. SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_8000)
  23. #define ARKADC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
  24. static int ark_sdadc_startup(struct snd_pcm_substream *substream,
  25. struct snd_soc_dai *dai)
  26. {//printk("==============[%s]:[ %d]\n", __FUNCTION__, __LINE__);
  27. return 0 ;
  28. }
  29. static void ark_sdadc_shutdown(struct snd_pcm_substream *substream,
  30. struct snd_soc_dai *dai)
  31. {
  32. }
  33. static int ark_sdadc_hw_params(struct snd_pcm_substream *substream,
  34. struct snd_pcm_hw_params *params,
  35. struct snd_soc_dai *dai)
  36. {
  37. unsigned int val,val_test;
  38. struct ark_sdadc *i2s = snd_soc_dai_get_drvdata(dai);
  39. //printk("==============[sys_base = 0x%08x i2s_base = 0x%08x]\n",i2s->sys_base,i2s->i2s_base);
  40. if(substream->stream == SNDRV_PCM_STREAM_CAPTURE){
  41. val = readl(i2s->sys_base + rSYS_DEVICE_CLK_CFG3);
  42. //val &= ~(1<<6);//I2SCLK
  43. //val |=(0x1<<0)|(0x1<<7)|(0x1<<2);
  44. if(i2s->extdata){
  45. //external codec i2s
  46. val &= ~(0xff<<1);
  47. val |= (1<<6);//I2S1CLK
  48. val |=(0x1<<0)|(1<<6)|(0x1<<7)|(0x1<<2);
  49. }else{
  50. //internal codec audio
  51. val &= ~(1<<6);//I2SCLK
  52. val |=(0x1<<0)|(0x1<<7)|(0x1<<2);
  53. }
  54. writel(val, i2s->sys_base + rSYS_DEVICE_CLK_CFG3);
  55. val = readl(i2s->sys_base + rSYS_PLL_RFCK_CTL);
  56. //val &= ~(1<<16);//IntI2SClk_pre
  57. val |=(0x1<<17);//IntI2S1Clk_pre
  58. writel(val, i2s->sys_base + rSYS_PLL_RFCK_CTL);
  59. val = readl(i2s->sys_base + rSYS_PAD_CTRL0F);
  60. val &= ~(1<<28);
  61. //val &= ~(0xf<<12);
  62. //val &= ~(1<<11);
  63. //val |= (0x7<<8);
  64. if(i2s->extdata){
  65. val |= (0xf<<8); //external codec i2s
  66. }else{
  67. val &= ~((1<<8)|(1<<9)|(1<<10)); //internal codec audio
  68. //val |= (0x1<<11);
  69. //val &= ~(1<<11);//0:i2s_bclk_out 1: i2s1_bclk_out
  70. //val &= ~(1<<15);//0:i2s_sync_out 1: i2s1_sync_out
  71. }
  72. //val &= ~(1<<8);//0;audio_codec_dout 1: i2s_sadata_in
  73. //val &= ~(1<<11);//0:i2s_bclk_out 1: i2s1_bclk_out
  74. //val &= ~(1<<15);//0:i2s_sync_out 1: i2s1_sync_out
  75. writel(val, i2s->sys_base + rSYS_PAD_CTRL0F);
  76. val = readl(i2s->sys_base + rSYS_AUDIO_CFG_0);
  77. //val &= ~(1<<0);//Slave
  78. val |= (1<<0);//Master
  79. if(!i2s->extdata){
  80. val &= ~(1<<13);//0:RMICIN 1: RLINEIN
  81. val &= ~(1<<14);//0:LMICIN 1:LLINEIN
  82. }
  83. val &= ~(1<<21);
  84. val &= ~(1<<22);
  85. //val |=(0x3<<13)|(0x1<<9)|(0xf<<1);
  86. val |=(0x1<<9)|(0xf<<1);
  87. writel(val, i2s->sys_base + rSYS_AUDIO_CFG_0);
  88. //set volume
  89. val = readl(i2s->sys_base + rSYS_AUDIO_CFG_1);
  90. val &= ~(0xf<<6);
  91. //val |= ((0x1<<7)|(0x1<<9));//L: Power-down mode R:Normal mode //for ksw only
  92. //val |= ((0x1<<6)|(0x1<<8));//L:Normal mode R: Power-down mode
  93. val |= (0x5f<<19)|(0x5f<<12);//volume gain control
  94. writel(val, i2s->sys_base + rSYS_AUDIO_CFG_1);
  95. if(!i2s->extdata){
  96. val = readl(i2s->sys_base + rSYS_AUDIO_CFG_5);
  97. val &=~(0x1<<17);//MICBPD add:20220214
  98. writel(val,i2s->sys_base + rSYS_AUDIO_CFG_5);
  99. }
  100. // val = readl(i2s->sys_base + rSYS_AUDIO_CFG_5);
  101. // val |=(0x1<<31);
  102. // writel(val,i2s->sys_base + rSYS_AUDIO_CFG_5);
  103. val = readl(i2s->sys_base + rSYS_PAD_CTRL06);
  104. val &= ~(1<<31);
  105. writel(val, i2s->sys_base + rSYS_PAD_CTRL06);
  106. }else if(substream->stream == SNDRV_PCM_STREAM_CAPTURE){
  107. }
  108. return 0;
  109. }
  110. static int ark_sdadc_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  111. int clk_id, unsigned int freq, int dir)
  112. {
  113. return 0;
  114. }
  115. static int ark_sdadc_set_dai_fmt(struct snd_soc_dai *codec_dai,
  116. unsigned int fmt)
  117. {
  118. return 0;
  119. }
  120. static const struct snd_soc_dai_ops ark_sdadc_dai_ops = {
  121. .startup = ark_sdadc_startup,
  122. .shutdown = ark_sdadc_shutdown,
  123. .hw_params = ark_sdadc_hw_params,
  124. .set_sysclk = ark_sdadc_set_dai_sysclk,
  125. .set_fmt = ark_sdadc_set_dai_fmt,
  126. };
  127. static struct snd_soc_dai_driver ark_sdadc_dai = {
  128. .name = "ark-sdadc-codec",
  129. .capture = {
  130. .stream_name = "Capture",
  131. .channels_min = 2,
  132. .channels_max = 2,
  133. .rates = ARKADC_RATES,
  134. .formats = ARKADC_FORMATS,
  135. },
  136. .ops = &ark_sdadc_dai_ops,
  137. };
  138. //static int ark_sdadc_codec_probe(struct snd_soc_codec *codec)
  139. static int ark_sdadc_codec_probe(struct snd_soc_component *component)
  140. {
  141. return 0;
  142. }
  143. static const struct snd_soc_dapm_widget ark_sdadc_dapm_widgets[] = {
  144. SND_SOC_DAPM_INPUT("MICIN"),
  145. SND_SOC_DAPM_INPUT("RLINEIN"),
  146. SND_SOC_DAPM_INPUT("LLINEIN"),
  147. };
  148. static struct snd_soc_component_driver ark_sdadc_component_driver = {
  149. .probe = ark_sdadc_codec_probe,
  150. .dapm_widgets = ark_sdadc_dapm_widgets,
  151. .num_dapm_widgets = ARRAY_SIZE(ark_sdadc_dapm_widgets),
  152. };
  153. static int ark_sdadc_probe(struct platform_device *pdev)
  154. {
  155. struct ark_sdadc *adc;
  156. struct resource *res;
  157. struct device *dev = &pdev->dev;
  158. int ret;
  159. adc = devm_kzalloc(dev, sizeof(*adc), GFP_KERNEL);
  160. if (!adc)
  161. return -ENOMEM;
  162. if (of_property_read_u32(pdev->dev.of_node, "left-volume", &adc->vol_l))
  163. adc->vol_l = 110;
  164. if (of_property_read_u32(pdev->dev.of_node, "right-volume", &adc->vol_r))
  165. adc->vol_r = 110;
  166. //printk(">>>>>>>>>>>>>>>>>>left-volume = %d,right-volume = %d \n",adc->vol_l,adc->vol_r);
  167. if (of_property_read_bool(pdev->dev.of_node, "external-i2s"))
  168. adc->extdata = 1;
  169. //printk(">>>>>>>>>>>>>>>>>>adc->extdata = %d \n",adc->extdata);
  170. platform_set_drvdata(pdev, adc);
  171. //i2s resource
  172. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  173. adc->i2s_base = ioremap(res->start, resource_size(res));
  174. if (IS_ERR(adc->i2s_base))
  175. return PTR_ERR(adc->i2s_base);
  176. //sys resource
  177. res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  178. //printk("==============[resource_size = 0x%08x]\n",resource_size(res));
  179. adc->sys_base = ioremap(res->start, resource_size(res));
  180. if (IS_ERR(adc->sys_base))
  181. return PTR_ERR(adc->sys_base);
  182. //printk("ADC:==============[sys_base = 0x%08x i2s_base = 0x%08x]\n",adc->sys_base,adc->i2s_base);
  183. // ret = snd_soc_register_codec(dev, &ark_sdadc_codec_driver,
  184. // &ark_sdadc_dai,
  185. // 1);
  186. ret = devm_snd_soc_register_component(dev, &ark_sdadc_component_driver,
  187. &ark_sdadc_dai,
  188. 1);
  189. if (ret) {
  190. dev_err(dev, "failed to register codec: %d\n", ret);
  191. goto err;
  192. }
  193. return 0;
  194. err:
  195. iounmap(adc->i2s_base);
  196. err_2:
  197. iounmap(adc->sys_base);
  198. return ret;
  199. }
  200. static int ark_sdadc_remove(struct platform_device *pdev)
  201. {
  202. //snd_soc_unregister_codec(&pdev->dev);
  203. snd_soc_unregister_component(&pdev->dev);
  204. struct ark_sdadc *adc = dev_get_drvdata(&pdev->dev);
  205. iounmap(adc->i2s_base);
  206. iounmap(adc->sys_base);
  207. return 0;
  208. }
  209. static const struct of_device_id ark_sdadc_match[] = {
  210. { .compatible = "arkmicro,ark1668e-sdadc", },
  211. {},
  212. };
  213. static struct platform_driver ark_sdadc_driver = {
  214. .driver = {
  215. .name = "ark-sdadc",
  216. .of_match_table = of_match_ptr(ark_sdadc_match),
  217. },
  218. .probe = ark_sdadc_probe,
  219. .remove = ark_sdadc_remove,
  220. };
  221. module_platform_driver(ark_sdadc_driver);
  222. MODULE_DESCRIPTION("ARK adc codec driver");
  223. MODULE_AUTHOR("Sim");
  224. MODULE_LICENSE("GPL v2");