Advertisement
Guest User

sunxi-i2s.c for mainline 4.0.x

a guest
Jun 22nd, 2015
380
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 43.54 KB | None | 0 0
  1. ~$ cat ~/src/kernel/linux-sunxi/sound/soc/sunxi/sunxi-i2s.c
  2. /*
  3.  * sunxi-i2s.c
  4.  *
  5.  * (c) 2015 Andrea Venturi <be17068@iperbole.bo.it>
  6.  *
  7.  *  This program is free software; you can redistribute  it and/or modify it
  8.  *  under  the terms of  the GNU General  Public License as published by the
  9.  *  Free Software Foundation;  either version 2 of the  License, or (at your
  10.  *  option) any later version.
  11.  */
  12.  
  13. #include <linux/init.h>
  14. #include <linux/module.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/io.h>
  17. #include <linux/slab.h>
  18. #include <linux/mbus.h>
  19. #include <linux/delay.h>
  20. #include <linux/clk.h>
  21. #include <sound/pcm.h>
  22. #include <sound/pcm_params.h>
  23. #include <sound/soc.h>
  24. //#include <linux/platform_data/asoc-sunxi.h>
  25. #include <linux/of.h>
  26. #include <linux/of_platform.h>
  27. #include <linux/of_address.h>
  28.  
  29. #include <sound/dmaengine_pcm.h>
  30.  
  31.  
  32. #include "sunxi.h"
  33.  
  34. #define DRV_NAME    "sunxi-i2s"
  35.  
  36. #define SUNXI_I2S_FORMATS \
  37.     (SNDRV_PCM_FMTBIT_S16_LE | \
  38.      SNDRV_PCM_FMTBIT_S24_LE | \
  39.      SNDRV_PCM_FMTBIT_S32_LE)
  40.  
  41. #define SUNXI_SPDIF_FORMATS \
  42.     (SNDRV_PCM_FMTBIT_S16_LE | \
  43.      SNDRV_PCM_FMTBIT_S24_LE)
  44.  
  45. // for suspend/resume feature
  46. static int regsave[8];
  47.  
  48. // TODO: Initialize structure on probe, after register default configuration
  49. //static struct sunxi_i2s_info sunxi_iis;
  50. static struct sunxi_i2s_info sunxi_iis = {
  51.         .slave = 0,
  52.         .samp_fs = 48000,
  53.         .samp_res = 24,
  54.         .samp_format = 0,
  55.         .ws_size = 32,
  56.         .mclk_rate = 512,
  57.         .lrc_pol = 0,
  58.         .bclk_pol = 0,
  59.         .pcm_datamode = 0,
  60.         .pcm_sw = 0,
  61.         .pcm_sync_period = 0,
  62.         .pcm_sync_type = 0,
  63.         .pcm_start_slot = 0,
  64.         .pcm_lsb_first = 0,
  65.         .pcm_ch_num = 1,
  66. };
  67.  
  68. typedef struct __BCLK_SET_INF
  69. {  
  70.     __u8        bitpersamp;     // bits per sample - Word Sizes
  71.     __u8        clk_div;        // clock division
  72.     __u16       mult_fs;        // multiplay of sample rate
  73.  
  74. } __bclk_set_inf;
  75.  
  76. typedef struct __MCLK_SET_INF
  77. {      
  78.     __u32       samp_rate;      // sample rate
  79.     __u16       mult_fs;        // multiply of sample rate
  80.        
  81.     __u8        clk_div;        // mpll division
  82.     __u32       mclk;          // select mpll, 24.576MHz/22.5792Mhz
  83.  
  84. } __mclk_set_inf;
  85.  
  86. static __bclk_set_inf BCLK_INF[] =
  87. {  
  88.     // 16bits per sample
  89.     {16,  4, 128}, {16,  6, 192}, {16,  8, 256},
  90.     {16, 12, 384}, {16, 16, 512},
  91.  
  92.     //24 bits per sample
  93.     {24,  4, 192}, {24,  8, 384}, {24, 16, 768},
  94.  
  95.     //32 bits per sample
  96.     {32,  2, 128}, {32,  4, 256}, {32,  6, 384},
  97.     {32,  8, 512}, {32, 12, 768},
  98.  
  99.     //end flag
  100.     {0xff, 0, 0},
  101. };
  102.  
  103. static __mclk_set_inf  MCLK_INF[] =
  104. {
  105.     // 8k bitrate
  106.     {  8000, 128, 24, 24576000}, {  8000, 192, 16, 24576000}, {  8000, 256, 12, 24576000},
  107.     {  8000, 384,  8, 24576000}, {  8000, 512,  6, 24576000}, {  8000, 768,  4, 24576000},
  108.  
  109.     // 16k bitrate
  110.     { 16000, 128, 12, 24576000}, { 16000, 192,  8, 24576000}, { 16000, 256,  6, 24576000},
  111.     { 16000, 384,  4, 24576000}, { 16000, 768,  2, 24576000},
  112.  
  113.     // 32k bitrate
  114.     { 32000, 128,  6, 24576000}, { 32000, 192,  4, 24576000}, { 32000, 384,  2, 24576000},
  115.     { 32000, 768,  1, 24576000},
  116.  
  117.     // 64k bitrate
  118.     { 64000, 192,  2, 24576000}, { 64000, 384,  1, 24576000},
  119.  
  120.     //128k bitrate
  121.     {128000, 192,  1, 24576000},
  122.  
  123.     // 12k bitrate
  124.     { 12000, 128, 16, 24576000}, { 12000, 256, 8, 24576000}, { 12000, 512, 4, 24576000},
  125.  
  126.     // 24k bitrate
  127.     { 24000, 128,  8, 24576000}, { 24000, 256, 4, 24576000}, { 24000, 512, 2, 24576000},
  128.  
  129.     // 48K bitrate
  130.     { 48000, 128,  4, 24576000}, { 48000, 256,  2, 24576000}, { 48000, 512, 1, 24576000},
  131.  
  132.     // 96k bitrate
  133.     { 96000, 128 , 2, 24576000}, { 96000, 256,  1, 24576000},
  134.  
  135.     //192k bitrate
  136.     {192000, 128,  1, 24576000},
  137.  
  138.     //11.025k bitrate
  139.     { 11025, 128, 16, 22579200}, { 11205, 256,  8, 22579200}, { 11205, 512,  4, 22579200},
  140.  
  141.     //22.05k bitrate
  142.     { 22050, 128,  8, 22579200}, { 22050, 256,  4, 22579200},
  143.     { 22050, 512,  2, 22579200},
  144.  
  145.     //44.1k bitrate
  146.     { 44100, 128,  4, 22579200}, { 44100, 256,  2, 22579200}, { 44100, 512,  1, 22579200},
  147.  
  148.     //88.2k bitrate
  149.     { 88200, 128,  2, 22579200}, { 88200, 256,  1, 22579200},
  150.  
  151.     //176.4k bitrate
  152.     {176400, 128, 1, 22579200},
  153.  
  154.     //end flag 0xffffffff
  155.     {0xffffffff, 0, 0, 24576000},
  156. };
  157.  
  158. /*
  159. * TODO: Function description.
  160. */
  161. //static s32 get_clock_divder(u32 sample_rate, u32 sample_width, u32 * mclk_div, u32* mpll, u32* bclk_div, u32* mult_fs)
  162. static s32 sunxi_i2s_divisor_values(u32 * mclk_div, u32* bclk_div, u32* mclk)
  163. {
  164.         u32 i, j, ret = -EINVAL;
  165.  
  166.         printk("[I2S]Entered %s\n", __func__);
  167.  
  168.         for(i=0; i< ARRAY_SIZE(MCLK_INF); i++) {
  169.                  if((MCLK_INF[i].samp_rate == sunxi_iis.samp_fs) && ((MCLK_INF[i].mult_fs == 256) || (MCLK_INF[i].mult_fs == 128))) {
  170.                           for(j=0; j<ARRAY_SIZE(BCLK_INF); j++) {
  171.                                         if((BCLK_INF[j].bitpersamp == sunxi_iis.ws_size) && (BCLK_INF[j].mult_fs == MCLK_INF[i].mult_fs)) {
  172.                                                  //set mclk and bclk division
  173.                                                  *mclk_div = MCLK_INF[i].clk_div;
  174.                                                  *mclk = MCLK_INF[i].mclk;
  175.                                                  *bclk_div = BCLK_INF[j].clk_div;
  176.                                                  sunxi_iis.mclk_rate = MCLK_INF[i].mult_fs;
  177.                                                  ret = 0;
  178.                                                  break;
  179.                                         }
  180.                           }
  181.                  }
  182.                  else if(MCLK_INF[i].samp_rate == 0xffffffff)
  183.                         break;
  184.         }
  185.         return ret;
  186. }
  187.  
  188.  
  189. static int sunxi_i2s_startup(struct snd_pcm_substream *substream,
  190.         struct snd_soc_dai *dai)
  191. {
  192.         struct snd_soc_pcm_runtime *rtd = substream->private_data;
  193.         struct sunxi_priv *priv = snd_soc_card_get_drvdata(rtd->card);
  194.         printk("[I2S]Entered %s\n", __func__);
  195.  
  196.         clk_prepare_enable(priv->clk_apb);
  197.         clk_prepare_enable(priv->clk_module);
  198.     return 0;
  199. }
  200.  
  201. static void sunxi_i2s_shutdown(struct snd_pcm_substream *substream,
  202.                                  struct snd_soc_dai *dai)
  203. {
  204.         struct snd_soc_pcm_runtime *rtd = substream->private_data;
  205.         struct sunxi_priv *priv = snd_soc_card_get_drvdata(rtd->card);
  206.         printk("[I2S]Entered %s\n", __func__);
  207.  
  208.         clk_disable_unprepare(priv->clk_module);
  209.         clk_disable_unprepare(priv->clk_apb);
  210. }
  211.  
  212. static void sunxi_i2s_capture_start(struct sunxi_priv *priv)
  213. {
  214.         printk("[I2S]Entered %s\n", __func__);
  215.         /* flush RXFIFO */
  216.         regmap_update_bits(priv->regmap, SUNXI_DA_FCTL, 0x1 << SUNXI_DA_FCTL_FRX, 0x1 << SUNXI_DA_FCTL_FRX);
  217.  
  218.         /* clear RX counter */
  219.         regmap_update_bits(priv->regmap, SUNXI_DA_RXCNT, 0xffff << SUNXI_DA_RXCNT_RX_CNT, 0x0 << SUNXI_DA_RXCNT_RX_CNT);
  220.  
  221.         /* enable DA_CTL RXEN */
  222.         regmap_update_bits(priv->regmap, SUNXI_DA_CTL, 0x1 << SUNXI_DA_CTL_RXEN, 0x1 << SUNXI_DA_CTL_RXEN);
  223.  
  224.         /* enable DA_INT RX_DRQ */
  225.         regmap_update_bits(priv->regmap, SUNXI_DA_INT, 0x1 << SUNXI_DA_INT_RX_DRQ, 0x1 << SUNXI_DA_INT_RX_DRQ);
  226.  
  227. }
  228.  
  229. static void sunxi_i2s_capture_stop(struct sunxi_priv *priv)                                                            
  230. {                                                                                                                      
  231.         unsigned int rx_counter;                                                                                        
  232.                                                                                                                        
  233.         /* disable DA RX_DRQ */                                                                                        
  234.         regmap_update_bits(priv->regmap, SUNXI_DA_INT, 0x1 << SUNXI_DA_INT_RX_DRQ, 0x0 << SUNXI_DA_INT_RX_DRQ);        
  235.                                                                                                                        
  236.         /* FIXME clear RX counter not doing, want to check */                                                          
  237.         // regmap_update_bits(priv->regmap, SUNXI_DA_RXCNT, 0xffff << SUNXI_DA_RXCNT_RX_CNT, 0x0 << SUNXI_DA_RXCNT_RX_CNT);
  238.  
  239.         regmap_read(priv->regmap, SUNXI_DA_RXCNT, &rx_counter);
  240.         printk("DEB: stop I2S rec: sample counter: %x\n", rx_counter);
  241.  
  242.         /* disable DA_CTL RXEN */
  243.         regmap_update_bits(priv->regmap, SUNXI_DA_CTL, 0x1 << SUNXI_DA_CTL_RXEN, 0x0 << SUNXI_DA_CTL_RXEN);
  244.  
  245.         /* flush RXFIFO */
  246.         regmap_update_bits(priv->regmap, SUNXI_DA_FCTL, 0x1 << SUNXI_DA_FCTL_FRX, 0x0 << SUNXI_DA_FCTL_FRX);
  247.  
  248. }
  249. static void sunxi_i2s_play_start(struct sunxi_priv *priv)
  250. {
  251.         printk("[I2S]Entered %s\n", __func__);
  252.  
  253.  
  254.         /* flush TX FIFO */
  255.         regmap_update_bits(priv->regmap, SUNXI_DA_FCTL, 0x1 << SUNXI_DA_FCTL_FTX, 0x1 << SUNXI_DA_FCTL_FTX);                        
  256.  
  257.         /* clear TX counter */                                                                                                      
  258.         regmap_update_bits(priv->regmap, SUNXI_DA_TXCNT, 0xffff << SUNXI_DA_TXCNT_TX_CNT, 0x0 << SUNXI_DA_TXCNT_TX_CNT);
  259.  
  260.  
  261.         /* enable DA_CTL TXEN */
  262.         regmap_update_bits(priv->regmap, SUNXI_DA_CTL, 0x1 << SUNXI_DA_CTL_TXEN, 0x1 << SUNXI_DA_CTL_TXEN);                        
  263.  
  264.         /* enable DA TX_DRQ */                                                                                                      
  265.         regmap_update_bits(priv->regmap, SUNXI_DA_INT, 0x1 << SUNXI_DA_INT_TX_DRQ, 0x1 << SUNXI_DA_INT_TX_DRQ);
  266.  
  267. }
  268. static void sunxi_i2s_play_stop(struct sunxi_priv *priv)
  269. {
  270.         unsigned int tx_counter;
  271.         /* TODO: see if we need to drive PA GPIO low */
  272.  
  273.         /* disable DA_CTL TXEN */
  274.         regmap_update_bits(priv->regmap, SUNXI_DA_CTL, 0x1 << SUNXI_DA_CTL_TXEN, 0x0 << SUNXI_DA_CTL_TXEN);
  275.  
  276.         /* disable DA TX_DRQ */
  277.         regmap_update_bits(priv->regmap, SUNXI_DA_INT, 0x1 << SUNXI_DA_INT_TX_DRQ, 0x0 << SUNXI_DA_INT_TX_DRQ);
  278.  
  279.         regmap_read(priv->regmap, SUNXI_DA_TXCNT, &tx_counter);
  280.         printk("DEB %s: sample counter: %x\n",  __func__, tx_counter);
  281.  
  282. }
  283.  
  284. static int sunxi_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
  285.                    struct snd_soc_dai *dai)
  286. {
  287.         struct snd_soc_pcm_runtime *rtd = substream->private_data;
  288.         struct sunxi_priv *priv = snd_soc_card_get_drvdata(rtd->card);
  289.  
  290.     printk("DEB: %s, copy from same fnt on i2s 3.4 legacy sunxi-i2s.c\n", __func__);
  291.         switch (cmd) {
  292.         case SNDRV_PCM_TRIGGER_START:
  293.         case SNDRV_PCM_TRIGGER_RESUME:
  294.         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  295.                 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  296.                         sunxi_i2s_capture_start(priv);
  297.                 else
  298.                         sunxi_i2s_play_start(priv);
  299.                 break;
  300.         case SNDRV_PCM_TRIGGER_STOP:
  301.         case SNDRV_PCM_TRIGGER_SUSPEND:
  302.         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  303.                 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
  304.                         sunxi_i2s_capture_stop(priv);
  305.                 else
  306.                         sunxi_i2s_play_stop(priv);
  307.                 break;
  308.         default:
  309.                 return -EINVAL;
  310.         }
  311.  
  312.         return 0;
  313.  
  314. }
  315.  
  316. static int sunxi_i2s_init(struct sunxi_priv *priv)
  317. {
  318.     //unsigned long value;
  319.     //unsigned int reg_data;
  320.         printk("[I2S]Entered %s\n", __func__);
  321.     /*
  322.      * was used for parsing FEX file, and, is suffesful:
  323.      * - setting slave or master
  324.      * - requesting GPIO of I2S ctrl
  325.      * - registering platform driver
  326.      */
  327.  
  328.     return 0;
  329.  
  330. }
  331.  
  332. /*
  333. * TODO: Function Description
  334. * Saved in snd_soc_dai_ops sunxi_iis_dai_ops.
  335. * Function called internally. The Machine Driver doesn't need to call this function because it is called whenever sunxi_i2s_set_clkdiv is called.
  336. * The master clock in Allwinner SoM depends on the sampling frequency.
  337. */
  338. static int sunxi_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir)
  339. {
  340.         //u32 reg_val;
  341.         struct sunxi_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
  342.  
  343.         printk("[I2S]Entered %s\n", __func__);
  344.         if(!sunxi_iis.slave)
  345.         {      
  346.                 switch(clk_id)
  347.                 {      
  348.                         case SUNXI_SET_MCLK:    // Set the master clock frequency.
  349.                                 // TODO - Check if the master clock is needed when slave mode is selected.
  350.                                 if (clk_set_rate(priv->clk_pll2, freq))
  351.                                 {      
  352.                                         pr_err("Try to set the i2s_pll2clk failed!\n");
  353.                                         return -EINVAL;
  354.                                 }
  355.                                 break;
  356.                         case SUNXI_MCLKO_EN:    // Enables the master clock output
  357.                                 if(dir == 1)    // Enable
  358.                     regmap_update_bits(priv->regmap, SUNXI_DA_CLKD, 0x1 << SUNXI_DA_CLKD_MCLKO_EN, 0x1 << SUNXI_DA_CLKD_MCLKO_EN);
  359.                                 if(dir == 0)    // Disable
  360.                     regmap_update_bits(priv->regmap, SUNXI_DA_CLKD, 0x1 << SUNXI_DA_CLKD_MCLKO_EN, 0x0 << SUNXI_DA_CLKD_MCLKO_EN);
  361.                         break;
  362.                 }
  363.         }
  364.         return 0;
  365. }
  366.  
  367. /*
  368. * TODO: Function Description
  369. * Saved in snd_soc_dai_ops sunxi_iis_dai_ops.
  370. */
  371. static int sunxi_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int value)
  372. {
  373.         u32 reg_bk, ret;
  374.         u32 mclk = 0;
  375.         u32 mclk_div = 0;
  376.         u32 bclk_div = 0;
  377.         struct sunxi_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
  378.  
  379.         // Here i should know the sample rate and the FS multiple.
  380.  
  381.         printk("[I2S]Entered %s\n", __func__);
  382.  
  383.         switch (div_id) {
  384.                 case SUNXI_DIV_MCLK:    // Sets MCLKDIV
  385.                 regmap_update_bits(priv->regmap, SUNXI_DA_CLKD, 0xf << SUNXI_DA_CLKD_MCLKDIV, (value & 0xf) << SUNXI_DA_CLKD_MCLKDIV);
  386.                         break;
  387.                 case SUNXI_DIV_BCLK:    // Sets BCLKDIV
  388.                 regmap_update_bits(priv->regmap, SUNXI_DA_CLKD, 0x7 << SUNXI_DA_CLKD_BCLKDIV, (value & 0x7) << SUNXI_DA_CLKD_BCLKDIV);
  389.                         break;
  390.                 case SUNXI_SAMPLING_FREQ:
  391.                         if(!sunxi_iis.slave)
  392.                         {
  393.                                 reg_bk = sunxi_iis.samp_fs;
  394.                                 sunxi_iis.samp_fs = (u32)value;
  395.                                 ret = sunxi_i2s_divisor_values(&mclk_div, &bclk_div, &mclk);    // Get the register values
  396.                                 if(ret != 0)    
  397.                                 {
  398.                                         printk("[I2S]Sampling rate frequency not supported.");
  399.                                         sunxi_iis.samp_fs = reg_bk;
  400.                                         return ret;
  401.                                 }
  402.                                 else
  403.                                 {
  404.                                         sunxi_iis.samp_fs = (u32)value;
  405.                                         sunxi_i2s_set_sysclk(cpu_dai, SUNXI_SET_MCLK, mclk, 0); // Set the master clock.
  406.                         regmap_update_bits(priv->regmap, SUNXI_DA_CLKD, (0xf << SUNXI_DA_CLKD_MCLKDIV)|(0x7 << SUNXI_DA_CLKD_BCLKDIV),
  407.                              ((mclk_div & 0xf) << SUNXI_DA_CLKD_MCLKDIV)|((bclk_div & 0x7) << SUNXI_DA_CLKD_BCLKDIV));
  408.                                 }
  409.                         }
  410.                         else
  411.                                 sunxi_iis.samp_fs = (u32)value;
  412.                         break;  
  413.         }
  414.         return 0;
  415. }
  416.  
  417. /*
  418. * TODO: Function description.
  419. * TODO: Refactor function because the configuration is with wrong scheme. Use a 4bit mask with the configuration option and then the value?
  420. * TODO: Include TX and RX FIFO trigger levels.
  421. * Saved in snd_soc_dai_ops sunxi_iis_dai_ops.
  422. * Configure:
  423. * - Master/Slave.
  424. * - I2S/PCM mode.
  425. * - Signal Inversion.
  426. * - Word Select Size.
  427. * - PCM Registers.
  428. */
  429. static int sunxi_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
  430. {
  431.         u32 reg_val1;
  432.         u32 reg_val2;
  433.         struct sunxi_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
  434.  
  435.         printk("[I2S]Entered %s, FMT: %x\n", __func__, fmt);
  436.  
  437.  
  438.         // Master/Slave Definition
  439.         //reg_val1 = readl(sunxi_iis.regs + SUNXI_IISCTL);
  440.         regmap_read(priv->regmap, SUNXI_DA_CTL, &reg_val1 );
  441.     printk("[I2S] %s: reg DA_CTL: 0x%0x\n", __func__, reg_val1);
  442.         switch(fmt & SND_SOC_DAIFMT_MASTER_MASK){
  443.                 case SND_SOC_DAIFMT_CBS_CFS:   // clk & frm slave
  444.                         reg_val1 &= ~SUNXI_DA_CTL_MS; // 0: I2S Master!
  445.                         printk("[I2S] %s, Master, so codec Slave.\n", __func__);
  446.                         break;
  447.                 case SND_SOC_DAIFMT_CBM_CFM:   // clk & frm master
  448.                         reg_val1 |= SUNXI_DA_CTL_MS; // 1: I2S Slave!
  449.                         printk("[I2S] %s, Slave, so codec Master.\n", __func__);
  450.                         break;
  451.                 default:
  452.                         printk("[I2S] %s: Master-Slave Select unknown mode: (fmt=%x)\n", __func__, fmt);
  453.                         return -EINVAL;
  454.         }
  455.         regmap_write(priv->regmap, SUNXI_DA_CTL, reg_val1 );
  456.         //writel(reg_val1, sunxi_iis.regs + SUNXI_IISCTL);
  457.  
  458.         // I2S or PCM mode.
  459.         regmap_read(priv->regmap, SUNXI_DA_CTL, &reg_val1 );
  460.         regmap_read(priv->regmap, SUNXI_DA_FAT0, &reg_val2 );
  461.     printk("[I2S] %s: reg DA_FAT0: 0x%0x\n", __func__, reg_val2);
  462.         //reg_val1 = readl(sunxi_iis.regs + SUNXI_IISCTL);
  463.         //reg_val2 = readl(sunxi_iis.regs + SUNXI_IISFAT0);       // Register Name in User Manual V1.2: DA_FAT0 - Digital Audio Format Register 0
  464.         switch(fmt & SND_SOC_DAIFMT_FORMAT_MASK)
  465.         {
  466.                 case SND_SOC_DAIFMT_I2S:        /* I2S mode */
  467.                         reg_val1 &= ~SUNXI_DA_CTL_PCM;
  468.                         reg_val2 &= ~SUNXI_DA_FAT0_FMT(3);     // Clear FMT (Bit 1:0)
  469.                         reg_val2 |= SUNXI_DA_FAT0_FMT_STD; //
  470.                         printk("[I2S]sunxi_i2s_set_fmt: Set I2S mode\n");
  471.                         sunxi_iis.samp_format = SND_SOC_DAIFMT_I2S;
  472.                         break;
  473.                 case SND_SOC_DAIFMT_RIGHT_J:    /* Right Justified mode */
  474.                         reg_val1 &= ~SUNXI_DA_CTL_PCM;
  475.                         reg_val2 &= ~SUNXI_DA_FAT0_FMT(3);     // Clear FMT (Bit 1:0)
  476.                         reg_val2 |= SUNXI_DA_FAT0_FMT_RIGHT; //
  477.                         printk("[I2S]sunxi_i2s_set_fmt: Set Right Justified mode\n");
  478.                         sunxi_iis.samp_format = SND_SOC_DAIFMT_RIGHT_J;
  479.                         break;
  480.                 case SND_SOC_DAIFMT_LEFT_J:     /* Left Justified mode */
  481.                         reg_val1 &= ~SUNXI_DA_CTL_PCM;
  482.                         reg_val2 &= ~SUNXI_DA_FAT0_FMT(3);     // Clear FMT (Bit 1:0)
  483.                         reg_val2 |= SUNXI_DA_FAT0_FMT_LEFT; //
  484.                         printk("[I2S]sunxi_i2s_set_fmt: Set Left Justified mode\n");
  485.                         sunxi_iis.samp_format = SND_SOC_DAIFMT_LEFT_J;
  486.                         break;
  487.                 case SND_SOC_DAIFMT_DSP_A:      /* L data msb after FRM LRC */
  488.                         reg_val1 &= ~SUNXI_DA_CTL_PCM;
  489.                         reg_val2 &= ~SUNXI_DA_FAT0_FMT(3);     // Clear FMT (Bit 1:0)
  490.                         reg_val2 |= SUNXI_DA_FAT0_FMT_LEFT; //
  491.                         sunxi_iis.samp_format = SND_SOC_DAIFMT_DSP_A;
  492.                         printk("[I2S]sunxi_i2s_set_fmt: Set L data msb after FRM LRC mode\n");
  493.                         break;
  494.                 case SND_SOC_DAIFMT_DSP_B:      /* L data msb during FRM LRC */
  495.                         reg_val1 |= SUNXI_DA_CTL_PCM;
  496.                         reg_val2 &= ~SUNXI_DA_FAT0_FMT(3);     // Clear FMT (Bit 1:0)
  497.                         reg_val2 |= SUNXI_DA_FAT0_LRCP;
  498.                         sunxi_iis.samp_format = SND_SOC_DAIFMT_DSP_B;
  499.                         printk("[I2S]sunxi_i2s_set_fmt: Set L data msb during FRM LRC mode\n");
  500.                         break;
  501.                 default:
  502.                         printk("[I2S]sunxi_i2s_set_fmt: Unknown mode\n");
  503.                         return -EINVAL;
  504.         }
  505.         regmap_write(priv->regmap, SUNXI_DA_CTL, reg_val1 );
  506.         regmap_write(priv->regmap, SUNXI_DA_FAT0, reg_val2 );
  507.         //writel(reg_val1, sunxi_iis.regs + SUNXI_IISCTL);
  508.         //writel(reg_val2, sunxi_iis.regs + SUNXI_IISFAT0);
  509.  
  510.         // Word select Size
  511.         regmap_read(priv->regmap, SUNXI_DA_FAT0, &reg_val1 );
  512.         //reg_val1 = readl(sunxi_iis.regs + SUNXI_IISFAT0);
  513.         switch(fmt & SND_SOC_DAIFMT_SUNXI_IISFAT0_WSS_MASK)     // TODO: Refactor, wrong configuration scheme.
  514.         {
  515.                 case SND_SOC_DAIFMT_SUNXI_IISFAT0_WSS_16BCLK:
  516.                         reg_val1 &= ~SUNXI_DA_FAT0_WSS_32; /* clear word select size */
  517.                         reg_val1 |= SUNXI_DA_FAT0_WSS_16;
  518.                         sunxi_iis.ws_size = 16;
  519.                         printk("[I2S]sunxi_i2s_set_fmt: Set word select size = 16.\n");
  520.                         break;
  521.                 case SND_SOC_DAIFMT_SUNXI_IISFAT0_WSS_20BCLK:
  522.                         reg_val1 &= ~SUNXI_DA_FAT0_WSS_32; /* clear word select size */
  523.                         reg_val1 |= SUNXI_DA_FAT0_WSS_20;
  524.                         sunxi_iis.ws_size = 20;
  525.                         printk("[I2S]sunxi_i2s_set_fmt: Set word select size = 20.\n");
  526.                         break;
  527.                 case SND_SOC_DAIFMT_SUNXI_IISFAT0_WSS_24BCLK:
  528.                         reg_val1 &= ~SUNXI_DA_FAT0_WSS_32; /* clear word select size */
  529.                         reg_val1 |= SUNXI_DA_FAT0_WSS_24;
  530.                         sunxi_iis.ws_size = 24;
  531.                         printk("[I2S]sunxi_i2s_set_fmt: Set word select size = 24.\n");
  532.                         break;
  533.                 case SND_SOC_DAIFMT_SUNXI_IISFAT0_WSS_32BCLK:
  534.                         reg_val1 &= ~SUNXI_DA_FAT0_WSS_32; /* clear word select size */
  535.                         reg_val1 |= SUNXI_DA_FAT0_WSS_32;
  536.                         sunxi_iis.ws_size = 32;
  537.                         printk("[I2S]sunxi_i2s_set_fmt: Set word select size = 32.\n");
  538.                         break;
  539.                 default:
  540.                         printk("[I2S]sunxi_i2s_set_fmt: Unknown mode.\n");
  541.                         break;
  542.         }
  543.         regmap_write(priv->regmap, SUNXI_DA_FAT0, reg_val1 );
  544.         //writel(reg_val1, sunxi_iis.regs + SUNXI_IISFAT0);
  545.  
  546.         // Signal Inversion
  547.         regmap_read(priv->regmap, SUNXI_DA_FAT0, &reg_val1 );
  548.         //reg_val1 = readl(sunxi_iis.regs + SUNXI_IISFAT0);
  549.         switch(fmt & SND_SOC_DAIFMT_INV_MASK)
  550.         {
  551.                 case SND_SOC_DAIFMT_NB_NF:     /* normal bit clock + frame */
  552.                         reg_val1 &= ~SUNXI_DA_FAT0_LRCP;
  553.                         reg_val1 &= ~SUNXI_DA_FAT0_BCP;
  554.                         sunxi_iis.bclk_pol = 0;
  555.                         sunxi_iis.lrc_pol = 0;
  556.                         printk("[I2S]sunxi_i2s_set_fmt: Normal bit clock + frame\n");
  557.                         break;
  558.                 case SND_SOC_DAIFMT_NB_IF:     /* normal bclk + inverted frame */
  559.                         reg_val1 |= SUNXI_DA_FAT0_LRCP;
  560.                         reg_val1 &= ~SUNXI_DA_FAT0_BCP;
  561.                         sunxi_iis.bclk_pol = 0;
  562.                         sunxi_iis.lrc_pol = 1;
  563.                         printk("[I2S]sunxi_i2s_set_fmt: Normal bclk + inverted frame\n");
  564.                         break;
  565.                 case SND_SOC_DAIFMT_IB_NF:     /* inverted bclk + normal frame */
  566.                         reg_val1 &= ~SUNXI_DA_FAT0_LRCP;
  567.                         reg_val1 |= SUNXI_DA_FAT0_BCP;
  568.                         sunxi_iis.bclk_pol = 1;
  569.                         sunxi_iis.lrc_pol = 0;
  570.                         printk("[I2S]sunxi_i2s_set_fmt: Inverted bclk + normal frame\n");
  571.                         break;
  572.                 case SND_SOC_DAIFMT_IB_IF:     /* inverted bclk + frame */
  573.                         reg_val1 |= SUNXI_DA_FAT0_LRCP;;
  574.                         reg_val1 |= SUNXI_DA_FAT0_BCP;
  575.                         sunxi_iis.bclk_pol = 1;
  576.                         sunxi_iis.lrc_pol = 1;
  577.                         printk("[I2S]sunxi_i2s_set_fmt: Inverted bclk + frame\n");
  578.                         break;
  579.                 default:
  580.                         printk("[I2S]sunxi_i2s_set_fmt: Unknown mode\n");
  581.                         return -EINVAL;
  582.         }
  583.         regmap_write(priv->regmap, SUNXI_DA_FAT0, reg_val1 );
  584.         //writel(reg_val1, sunxi_iis.regs + SUNXI_IISFAT0);
  585. //      sunxi_i2s_printk_register_values();
  586.  
  587.         return 0;
  588. }
  589.  
  590.  
  591. static int sunxi_i2s_hw_params(struct snd_pcm_substream *substream,
  592.                  struct snd_pcm_hw_params *params,
  593.                  struct snd_soc_dai *dai)
  594. {
  595.         struct snd_soc_pcm_runtime *rtd = substream->private_data;
  596.         struct sunxi_priv *priv = snd_soc_card_get_drvdata(rtd->card);
  597.         //int is_mono = !!(params_channels(params) == 1);
  598.         int is_24bit = !!(hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32);
  599.         unsigned int rate = params_rate(params);
  600.         unsigned int hwrate;
  601.  
  602.         printk("[I2S]Entered %s\n", __func__);
  603.         switch (rate) {
  604.         case 176400:
  605.         case 88200:
  606.         case 44100:
  607.         case 33075:
  608.         case 22050:
  609.         case 14700:
  610.         case 11025:
  611.         case 7350:
  612.         default:
  613.                 clk_set_rate(priv->clk_module, 22579200);
  614.                 break;
  615.         case 192000:
  616.         case 96000:
  617.         case 48000:
  618.         case 32000:
  619.         case 24000:
  620.         case 16000:
  621.         case 12000:
  622.         case 8000:
  623.                 clk_set_rate(priv->clk_module, 24576000);
  624.                 break;
  625.         }
  626.  
  627.         switch (rate) {
  628.         case 192000:
  629.         case 176400:
  630.                 hwrate = 6;
  631.                 break;
  632.         case 96000:
  633.         case 88200:
  634.                 hwrate = 7;
  635.                 break;
  636.         default:
  637.         case 48000:
  638.         case 44100:
  639.                 hwrate = 0;
  640.                 break;
  641.         case 32000:
  642.         case 33075:
  643.                 hwrate = 1;
  644.                 break;
  645.         case 24000:
  646.         case 22050:
  647.                 hwrate = 2;
  648.                 break;
  649.         case 16000:
  650.         case 14700:
  651.                 hwrate = 3;
  652.                 break;
  653.         case 12000:
  654.         case 11025:
  655.                 hwrate = 4;
  656.                 break;
  657.         case 8000:
  658.         case 7350:
  659.                 hwrate = 5;
  660.                 break;
  661.         }
  662.  
  663.         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  664.                 printk("[I2S]sunxi_i2s_hw_params: SNDRV_PCM_STREAM_PLAYBACK.\n");
  665.                 switch (params_channels(params)) {      // Enables the outputs and sets the map of the samples, on crescent order.
  666.                 // FIXME: always 2 channels, for draft
  667.                 default:
  668.                         printk("[I2S] %s: channels selected different then 2 but not implemented\n", __func__);
  669.                 case 2:
  670.                         regmap_update_bits(priv->regmap, SUNXI_DA_CTL, SUNXI_DA_CTL_SDO0_EN|SUNXI_DA_CTL_SDO1_EN|SUNXI_DA_CTL_SDO2_EN|SUNXI_DA_CTL_SDO3_EN, SUNXI_DA_CTL_SDO0_EN);
  671.                         regmap_update_bits(priv->regmap, SUNXI_DA_TXCHSEL, 7, SUNXI_DA_TXCHSEL_CHNUM(2)); /* mask 3 lsbs */
  672.                         regmap_update_bits(priv->regmap, SUNXI_DA_TXCHMAP, 0x3f, SUNXI_DA_TXCHMAP_TX_CH(1)|SUNXI_DA_TXCHMAP_TX_CH(2)); //FIXME: ugly masks!
  673.  
  674.                         //reg_val1 |= SUNXI_IISCTL_SDO0EN;
  675.                         //reg_val2 |= SUNXI_TXCHSEL_CHNUM(2); // TX Channel Select 2-ch.
  676.                         //reg_val3 |= ((0x0 << 0) | (0x1 << 4));  // TX Channel0 Mapping 1st sample, TX Channel1 Mapping 2nd sample.
  677.                         printk("[I2S]sunxi_i2s_hw_params: SDO0 enabled, 2 channels selected.\n");
  678.                         break;
  679.                 }
  680.                 if (is_24bit) // FIXME need supporting also 20 bit properly, here it's two bytes only
  681.                         priv->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
  682.                 else
  683.                         priv->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
  684.  
  685.         } else  {
  686.                 printk("[I2S]sunxi_i2s_hw_params: SNDRV_PCM_STREAM_CAPTURE.\n");
  687.                 switch (params_channels(params)) {      // Enables the outputs and sets the map of the samples, on crescent order.
  688.                 // FIXME: always 2 channels, for draft                                                                                  
  689.                 default:
  690.                         printk("[I2S]sunxi_i2s_hw_params: channels selected different then 2 but...\n");
  691.                 case 2:
  692.                         regmap_update_bits(priv->regmap, SUNXI_DA_RXCHSEL, 7, SUNXI_DA_RXCHSEL_CHNUM(2)); /* mask 3 lsbs */
  693.                         regmap_update_bits(priv->regmap, SUNXI_DA_RXCHMAP, 0x3f, SUNXI_DA_RXCHMAP_RX_CH(1)|SUNXI_DA_RXCHMAP_RX_CH(2)); //FIXME: ugly masks!                                                                                
  694.                         printk("[I2S]sunxi_i2s_hw_params: SDO0 enabled, 2 channels selected.\n");
  695.                         break;
  696.                 }
  697.                 if (is_24bit) // FIXME need supporting also 20 bit properly, here it's two bytes only
  698.                         priv->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
  699.                 else
  700.                         priv->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
  701.  
  702.         }
  703.  
  704.         // Sample Rate.
  705.         if(sunxi_iis.slave == 0)        // Only master has to configure the clock registers for sample rate setting.
  706.         {
  707.                 sunxi_iis.samp_fs = params_rate(params);
  708.                 sunxi_i2s_set_clkdiv(dai, SUNXI_SAMPLING_FREQ, sunxi_iis.samp_fs);
  709.         }
  710.  
  711.         return 0;
  712.  
  713. }
  714.  
  715. /*
  716. * TODO: Function Description.
  717. * Saved in snd_soc_dai_driver sunxi_iis_dai.
  718. */
  719. static int sunxi_i2s_dai_probe(struct snd_soc_dai *cpu_dai)
  720. {
  721.         //u32 reg_val;
  722.     struct sunxi_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
  723.  
  724.         printk("[I2S]Entered %s\n", __func__);
  725.  
  726.         // I2S Default Register Configuration
  727.         sunxi_iis.slave = 0, // put as default Master
  728.         sunxi_iis.samp_fs = 48000,
  729.         sunxi_iis.samp_res = 24,
  730.         sunxi_iis.samp_format = SND_SOC_DAIFMT_I2S,
  731.         sunxi_iis.ws_size = 32,
  732.         sunxi_iis.mclk_rate = 512,
  733.         sunxi_iis.lrc_pol = 0,
  734.         sunxi_iis.bclk_pol = 0,
  735.         sunxi_iis.pcm_datamode = 0,
  736.         sunxi_iis.pcm_sw = 0,
  737.         sunxi_iis.pcm_sync_period = 0,
  738.         sunxi_iis.pcm_sync_type = 0,
  739.         sunxi_iis.pcm_start_slot = 0,
  740.         sunxi_iis.pcm_lsb_first = 0,
  741.         sunxi_iis.pcm_ch_num = 2,
  742.  
  743.         // Digital Audio Register Default Values
  744.         // DIGITAL AUDIO CONTROL REGISTER DEF
  745.         regmap_update_bits(priv->regmap, SUNXI_DA_CTL, SUNXI_DA_CTL_GEN, SUNXI_DA_CTL_GEN);
  746.         //reg_val = SUNXI_IISCTL_MS | SUNXI_IISCTL_GEN;
  747.         //writel(reg_val, sunxi_iis.regs + SUNXI_IISCTL);
  748.  
  749.         // DIGITAL AUDIO FORMAT REGISTER 0
  750.         regmap_write(priv->regmap, SUNXI_DA_FAT0, SUNXI_DA_FAT0_FMT_STD|SUNXI_DA_FAT0_SR_24|SUNXI_DA_FAT0_WSS_32);
  751.         //reg_val = SUNXI_IISFAT0_FMT_I2S | SUNXI_IISFAT0_SR_24BIT | SUNXI_IISFAT0_WSS_32BCLK;
  752.         //writel(reg_val, sunxi_iis.regs + SUNXI_IISFAT0);
  753.  
  754.         // FIFO control register. TODO: Understand how to optimize this parameter.
  755.         //reg_val = (1<<0);       // Expanding received sample sign bit at MSB of DA_RXFIFO register. TODO: Check if this configuration works.
  756.         //reg_val |= (1<<2);      // Valid data at the LSB of TXFIFO register
  757.         //reg_val |= SUNXI_IISFCTL_RXTL(0xf);             //RX FIFO trigger level - try to make it multiple of 8 to enable DMA burst of 8.
  758.         //reg_val |= SUNXI_IISFCTL_TXTL(0x40);    //TX FIFO empty trigger level - try to make it multiple of 8 to enable DMA burst of 8
  759.         //writel(reg_val, sunxi_iis.regs + SUNXI_IISFCTL);
  760.         regmap_write(priv->regmap, SUNXI_DA_FCTL, (1<<SUNXI_DA_FCTL_RXOM)|(1<<SUNXI_DA_FCTL_TXIM)|(0x0f<<SUNXI_DA_FCTL_RXTL)|(0x40<<SUNXI_DA_FCTL_TXTL));
  761.  
  762.         //enable MCLK output
  763.         //reg_val = readl(sunxi_iis.regs + SUNXI_IISCLKD);
  764.         //reg_val |= SUNXI_IISCLKD_MCLKOEN;
  765.         //writel(reg_val, sunxi_iis.regs + SUNXI_IISCLKD);
  766.     regmap_update_bits(priv->regmap, SUNXI_DA_CLKD, 0x1 << SUNXI_DA_CLKD_MCLKO_EN, 0x1 << SUNXI_DA_CLKD_MCLKO_EN);
  767.         printk("[IIS-0] sunxi_i2s_set_clkdiv: enable MCLK\n");
  768.  
  769.         printk("[I2S]I2S default register configuration complete.\n");
  770.  
  771.         return 0;
  772. }
  773.  
  774. /*
  775. * TODO: Function Description.
  776. * Saved in snd_soc_dai_driver sunxi_iis_dai.
  777. */
  778. static int sunxi_i2s_dai_remove(struct snd_soc_dai *dai)
  779. {
  780.     struct sunxi_priv *priv = snd_soc_dai_get_drvdata(dai);
  781.         printk("[I2S]Entered %s\n", __func__);
  782.  
  783.         // DIGITAL AUDIO CONTROL REGISTER
  784.         regmap_write(priv->regmap, SUNXI_DA_CTL, 0);
  785.         //writel(0, sunxi_iis.regs + SUNXI_IISCTL);
  786.  
  787.         return 0;
  788. }
  789.  
  790. /*
  791. * TODO: Function description.
  792. */
  793. static void iisregsave(struct sunxi_priv *priv)
  794. {
  795.         printk("[I2S]Entered %s\n", __func__);
  796.  
  797.         regmap_read(priv->regmap, SUNXI_DA_CTL,  &regsave[0]);
  798.         regmap_read(priv->regmap, SUNXI_DA_FAT0,  &regsave[1]);
  799.         regmap_read(priv->regmap, SUNXI_DA_FAT1,  &regsave[2]);
  800.         regmap_read(priv->regmap, SUNXI_DA_FCTL,  &regsave[3]); //| (0x3<<24); // TODO: Bit 24- FRX - Write ‘1’ to flush RX FIFO, self clear to ‘0’. Really needed?
  801.         regmap_read(priv->regmap, SUNXI_DA_INT,  &regsave[4]);
  802.         regmap_read(priv->regmap, SUNXI_DA_CLKD,  &regsave[5]);
  803.         regmap_read(priv->regmap, SUNXI_DA_TXCHSEL,  &regsave[6]);
  804.         regmap_read(priv->regmap, SUNXI_DA_TXCHMAP,  &regsave[7]);
  805. }
  806.  
  807. /*
  808. * TODO: Function description.
  809. */
  810. static void iisregrestore(struct sunxi_priv *priv)
  811. {
  812.         printk("[I2S]Entered %s\n", __func__);
  813.  
  814.         regmap_write(priv->regmap, SUNXI_DA_CTL,  regsave[0]);
  815.         regmap_write(priv->regmap, SUNXI_DA_FAT0, regsave[1]);
  816.         regmap_write(priv->regmap, SUNXI_DA_FAT1, regsave[2]);
  817.         regmap_write(priv->regmap, SUNXI_DA_FCTL, regsave[3]);
  818.         regmap_write(priv->regmap, SUNXI_DA_INT, regsave[4]);
  819.         regmap_write(priv->regmap, SUNXI_DA_CLKD, regsave[5]);
  820.         regmap_write(priv->regmap, SUNXI_DA_TXCHSEL, regsave[6]);
  821.         regmap_write(priv->regmap, SUNXI_DA_TXCHMAP, regsave[7]);
  822. }
  823.  
  824. /*
  825. * TODO: Function Description.
  826. * Saved in snd_soc_dai_driver sunxi_iis_dai.
  827. */
  828. static int sunxi_i2s_suspend(struct snd_soc_dai *cpu_dai)
  829. {
  830.         //u32 reg_val;
  831.     struct sunxi_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
  832.  
  833.         printk("[I2S]Entered %s\n", __func__);
  834.  
  835.         //Global Disable Digital Audio Interface
  836.     regmap_update_bits(priv->regmap, SUNXI_DA_CTL, 0x1 << SUNXI_DA_CTL_GEN, 0x0 << SUNXI_DA_CTL_GEN);
  837.         //reg_val = readl(sunxi_iis.regs + SUNXI_IISCTL);
  838.         //reg_val &= ~SUNXI_IISCTL_GEN;
  839.         //writel(reg_val, sunxi_iis.regs + SUNXI_IISCTL);
  840.  
  841.         iisregsave(priv);
  842.  
  843.         if(!sunxi_iis.slave) {
  844.                 //release the module clock, only for master mode
  845.                 clk_disable(priv->clk_module);
  846.         }
  847.         clk_disable(priv->clk_apb);
  848.  
  849.         //printk("[I2S]PLL2 0x01c20008 = %#x\n", *(volatile int*)0xF1C20008);
  850.         // printk("[I2S]SPECIAL CLK 0x01c20068 = %#x, line= %d\n", *(volatile int*)0xF1C20068, __LINE__);
  851.         // printk("[I2S]SPECIAL CLK 0x01c200B8 = %#x, line = %d\n", *(volatile int*)0xF1C200B8, __LINE__);
  852.         // TODO: Understand this printk!
  853.  
  854.         return 0;
  855. }
  856.  
  857. /*
  858. * TODO: Function Description.
  859. * Saved in snd_soc_dai_driver sunxi_iis_dai.
  860. */
  861. static int sunxi_i2s_resume(struct snd_soc_dai *cpu_dai)
  862. {
  863.         //u32 reg_val;
  864.     struct sunxi_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
  865.  
  866.         printk("[I2S]Entered %s\n", __func__);
  867.  
  868.         //enable the module clock
  869.         clk_enable(priv->clk_apb);
  870.  
  871.         if(!sunxi_iis.slave) {
  872.                 //enable the module clock
  873.                 clk_enable(priv->clk_module);
  874.         }
  875.  
  876.         iisregrestore(priv);
  877.  
  878.         //Global Enable Digital Audio Interface
  879.     regmap_update_bits(priv->regmap, SUNXI_DA_CTL, 0x1 << SUNXI_DA_CTL_GEN, 0x1 << SUNXI_DA_CTL_GEN);
  880.  
  881.         return 0;
  882. }
  883.  
  884.  
  885. static const struct regmap_config sunxi_i2s_regmap_config = {
  886.         .reg_bits = 32,
  887.         .reg_stride = 4,
  888.         .val_bits = 32,
  889.         .max_register = SUNXI_DA_RXCHMAP,
  890. };      
  891.  
  892. static const struct snd_soc_component_driver sunxi_i2s_component = {
  893.     .name       = DRV_NAME,
  894. };
  895.  
  896. static struct snd_soc_dai_ops sunxi_i2s_dai_ops = {
  897.     .startup = sunxi_i2s_startup,
  898.     .shutdown = sunxi_i2s_shutdown,
  899.         .set_sysclk = sunxi_i2s_set_sysclk,
  900.         .set_clkdiv = sunxi_i2s_set_clkdiv,
  901.         .set_fmt        = sunxi_i2s_set_fmt,
  902.         .hw_params      = sunxi_i2s_hw_params,
  903.         .trigger        = sunxi_i2s_trigger,
  904. };
  905.  
  906. static struct snd_soc_dai_driver sunxi_i2s_dai[1] = {
  907.     {
  908.         .name           = "sunxi-i2s-snd-soc-dai-driver",
  909.         .probe          = sunxi_i2s_dai_probe,
  910.         //.remove         = sunxi_i2s_dai_remove,
  911.         //.suspend        = sunxi_i2s_suspend,
  912.         //.resume         = sunxi_i2s_resume,
  913.         .ops            = &sunxi_i2s_dai_ops,
  914.         .capture        = {
  915.             .stream_name = "pcm0c",
  916.             // TODO: Support SNDRV_PCM_FMTBIT_S20_3LE and SNDRV_PCM_FMTBIT_S24_3LE.
  917.             .formats = SUNXI_I2S_CAPTURE_FORMATS,
  918.             .rates = SUNXI_I2S_RATES,
  919.             .rate_min = SNDRV_PCM_RATE_8000,
  920.             .rate_max = SNDRV_PCM_RATE_192000,
  921.             .channels_min = 1,
  922.             .channels_max = 2,
  923.         },
  924.         .playback       = {
  925.             .stream_name = "pcm0p",
  926.             // TODO: Support SNDRV_PCM_FMTBIT_S20_3LE and SNDRV_PCM_FMTBIT_S24_3LE. Implies in changing the word select size in *_set_fmt.
  927.             .formats = SUNXI_I2S_PLAYBACK_FORMATS,
  928.             .rates = SUNXI_I2S_RATES,
  929.             .rate_min = SNDRV_PCM_RATE_8000,
  930.             .rate_max = SNDRV_PCM_RATE_192000,
  931.             .channels_min = 1,
  932.             .channels_max = 2,
  933.         },
  934.         .symmetric_rates = 1,
  935.     },
  936. };
  937.  
  938.  
  939. struct snd_soc_platform_driver sunxi_soc_platform = {
  940.     // this is from kirkwood where it was used for DMA ops, but here we use dmaengine..
  941.         //.ops            = &sunxi_dma_ops,
  942.         //.pcm_new        = kirkwood_dma_new,
  943.         //.pcm_free       = kirkwood_dma_free_dma_buffers,
  944. };
  945.  
  946. #ifdef CONFIG_OF
  947. static const struct of_device_id sunxi_i2s_of_match[] = {
  948.     { .compatible = "allwinner,sun7i-a20-i2s" },
  949.     { }
  950. };
  951. MODULE_DEVICE_TABLE(of, sunxi_i2s_of_match);
  952. #endif
  953.  
  954.  
  955. static int sunxi_digitalaudio_probe(struct platform_device *pdev)
  956. {
  957.         struct device_node *np = pdev->dev.of_node;
  958.         struct  snd_soc_dai_driver *soc_dai  = sunxi_i2s_dai;
  959.         struct sunxi_priv *priv;
  960.         const struct of_device_id *of_id;
  961.         struct device *dev = &pdev->dev;
  962.         struct resource *res;
  963.         void __iomem *base;
  964.  
  965.         // WRONG struct snd_soc_card *card = &sunxi_dev;
  966.         int ret;
  967.  
  968.         printk("[I2S]Entered %s\n", __func__);
  969.  
  970.     //return -ENODEV; // AV test to check if driver is spitted out
  971.         if (!of_device_is_available(np))
  972.                 return -ENODEV;
  973.  
  974.         of_id = of_match_device(sunxi_i2s_of_match, dev);
  975.         if (!of_id)
  976.                 return -EINVAL;
  977.  
  978.         priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  979.         if (!priv)
  980.                 return -ENOMEM;
  981.  
  982.         printk("[AV]alloc ok %s\n", __func__);
  983.         dev_set_drvdata(&pdev->dev, priv);
  984.         dev_err(dev, "%s, [AV]dev err set priv into platform\n", __func__);
  985.  
  986.         priv->revision = (enum sunxi_soc_family)of_id->data;
  987.  
  988.         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  989.         base = devm_ioremap_resource(&pdev->dev, res);
  990.         if (IS_ERR(base))
  991.                 return PTR_ERR(base);
  992.  
  993.         priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
  994.                                              &sunxi_i2s_regmap_config);
  995.         if (IS_ERR(priv->regmap))
  996.                 return PTR_ERR(priv->regmap);
  997.  
  998.         /* Get the clocks from the DT */
  999.         priv->clk_apb = devm_clk_get(dev, "apb");
  1000.         if (IS_ERR(priv->clk_apb)) {
  1001.                 dev_err(dev, "failed to get apb clock\n");
  1002.                 return PTR_ERR(priv->clk_apb);
  1003.         }
  1004.         priv->clk_module = devm_clk_get(dev, "iis");
  1005.         if (IS_ERR(priv->clk_module)) {
  1006.                 dev_err(dev, "failed to get i2s clock\n");
  1007.                 return PTR_ERR(priv->clk_module);
  1008.         }
  1009.  
  1010.         /* Enable the clock on a basic rate */
  1011.         ret = clk_set_rate(priv->clk_module, 24576000);
  1012.         if (ret) {
  1013.                 dev_err(dev, "failed to set i2s base clock rate\n");
  1014.                 return ret;
  1015.         }
  1016.  
  1017.         /* Enable the bus clock */
  1018.         if (clk_prepare_enable(priv->clk_apb)) {
  1019.                 dev_err(dev, "failed to enable apb clock\n");
  1020.                 clk_disable_unprepare(priv->clk_module);
  1021.                 return -EINVAL;
  1022.         }
  1023.  
  1024.         dev_info(dev, "[AV] set clock and rate on i2s, %s\n", __func__);
  1025.  
  1026.         /* DMA configuration for TX FIFO */
  1027.         priv->playback_dma_data.addr = res->start + SUNXI_DA_TXFIFO;
  1028.         priv->playback_dma_data.maxburst = 4;
  1029.         priv->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
  1030.  
  1031.         /* DMA configuration for RX FIFO */
  1032.         priv->capture_dma_data.addr = res->start + SUNXI_DA_RXFIFO;
  1033.         priv->capture_dma_data.maxburst = 4;
  1034.         priv->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
  1035.  
  1036.         ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
  1037.         if (ret) {
  1038.                 dev_err(&pdev->dev, "snd_soc_register_dmaengine failed (%d)\n", ret);
  1039.                 goto err_clk_disable;
  1040.     }
  1041.  
  1042.         ret = devm_snd_soc_register_component(&pdev->dev, &sunxi_i2s_component, soc_dai, 1);
  1043.         if (ret) {
  1044.                 dev_err(&pdev->dev, "snd_soc_register_component failed (%d)\n", ret);
  1045.                 goto err_clk_disable;
  1046.     }
  1047.  
  1048.  
  1049.         ret = snd_soc_register_platform(&pdev->dev, &sunxi_soc_platform);
  1050.         if (ret) {
  1051.                 dev_err(&pdev->dev, "snd_soc_register_platform failed\n");
  1052.                 goto err_platform;
  1053.         }
  1054.  
  1055.         sunxi_i2s_init(priv);
  1056.         return 0;
  1057.  
  1058. err_platform:
  1059.     dev_info(&pdev->dev, "AV snd_soc_register_platform failed\n");
  1060.     snd_soc_unregister_component(&pdev->dev);
  1061. err_clk_disable:
  1062.     dev_info(&pdev->dev, "AV snd_soc_register_* failed\n");
  1063.     if (!IS_ERR(priv->clk_module))
  1064.         clk_disable_unprepare(priv->clk_module);
  1065.         clk_disable_unprepare(priv->clk_apb);
  1066.         return ret;
  1067.  
  1068. }
  1069.  
  1070. static int sunxi_digitalaudio_remove(struct platform_device *pdev)
  1071. {
  1072.     struct sunxi_priv *priv = dev_get_drvdata(&pdev->dev);
  1073.  
  1074.     snd_soc_unregister_platform(&pdev->dev);
  1075.     snd_soc_unregister_component(&pdev->dev);
  1076.  
  1077.     if (!IS_ERR(priv->clk_apb))
  1078.         clk_disable_unprepare(priv->clk_apb);
  1079.     if (!IS_ERR(priv->clk_module))
  1080.         clk_disable_unprepare(priv->clk_module);
  1081.  
  1082.     return 0;
  1083. }
  1084.  
  1085. static struct platform_driver sunxi_i2s_driver = {
  1086.     .probe  = sunxi_digitalaudio_probe,
  1087.     .remove = sunxi_digitalaudio_remove,
  1088.     .driver = {
  1089.         .name = DRV_NAME,
  1090.         .of_match_table = of_match_ptr(sunxi_i2s_of_match),
  1091.     },
  1092. };
  1093.  
  1094. module_platform_driver(sunxi_i2s_driver);
  1095.  
  1096. /* Module information */
  1097. MODULE_DEVICE_TABLE(of, sunxi_i2s_of_match); // autoload from: https://lwn.net/Articles/448502/
  1098. MODULE_AUTHOR("Andrea Venturi, <be17068@iperbole.bo.it>");
  1099. MODULE_DESCRIPTION("Sunxi I2S ASoC Interface");
  1100. MODULE_LICENSE("GPL");
  1101. MODULE_ALIAS("platform:sunxi-i2s");
  1102. buildroot@DISTROBOX:~$
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement