switch (audio->rate) {
case HDMI_AUDIO_FS_32000:
- mclk_fs = FS_64;
+ mclk_fs = FS_128;
rate = AUDIO_32K;
if (hdmi_dev->tmdsclk >= 594000000)
N = N_32K_HIGHCLK;
CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 32);
break;
case HDMI_AUDIO_FS_44100:
- mclk_fs = FS_64;
+ mclk_fs = FS_128;
rate = AUDIO_441K;
if (hdmi_dev->tmdsclk >= 594000000)
N = N_441K_HIGHCLK;
CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 441);
break;
case HDMI_AUDIO_FS_48000:
- mclk_fs = FS_64;
+ mclk_fs = FS_128;
rate = AUDIO_48K;
if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
N = N_48K_HIGHCLK;
CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 48);
break;
case HDMI_AUDIO_FS_88200:
- mclk_fs = FS_64;
+ mclk_fs = FS_128;
rate = AUDIO_882K;
if (hdmi_dev->tmdsclk >= 594000000)
N = N_882K_HIGHCLK;
CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 882);
break;
case HDMI_AUDIO_FS_96000:
- mclk_fs = FS_64;
+ mclk_fs = FS_128;
rate = AUDIO_96K;
if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
N = N_96K_HIGHCLK;
CTS = CALC_CTS(N, hdmi_dev->tmdsclk/1000, 96);
break;
case HDMI_AUDIO_FS_176400:
- mclk_fs = FS_64;
+ mclk_fs = FS_128;
rate = AUDIO_1764K;
if (hdmi_dev->tmdsclk >= 594000000)
N = N_1764K_HIGHCLK;
CTS = CALC_CTS(N, hdmi_dev->tmdsclk/100, 1764);
break;
case HDMI_AUDIO_FS_192000:
- mclk_fs = FS_64;
+ mclk_fs = FS_128;
rate = AUDIO_192K;
if (hdmi_dev->tmdsclk >= 594000000) /*FS_153.6*/
N = N_192K_HIGHCLK;
/* set channel status register */
hdmi_msk_reg(hdmi_dev, FC_AUDSCHNLS7,
m_AUDIO_SAMPLE_RATE, v_AUDIO_SAMPLE_RATE(rate));
- /* hdmi_writel(hdmi_dev, FC_AUDSCHNLS2, 0x1); */
- /* hdmi_writel(hdmi_dev, FC_AUDSCHNLS8, ((~rate) << 4) | 0x2); */
+ hdmi_writel(hdmi_dev, FC_AUDSCHNLS8, ((~rate) << 4) | 0x2);
hdmi_dev_config_aai(hdmi_dev, audio);
.digital_mute = rk1000_codec_mute,
};
-#define RK1000_CODEC_RATES SNDRV_PCM_RATE_8000_96000
+#define RK1000_CODEC_RATES SNDRV_PCM_RATE_8000_192000
#define RK1000_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
.playback = {
.stream_name = "Playback",
.channels_min = 1,
- .channels_max = 2,
+ .channels_max = 8,
.rates = RK1000_CODEC_RATES,
.formats = RK1000_CODEC_FORMATS,
},
#include "rk_pcm.h"
#include "rk_i2s.h"
+#include "../../../drivers/video/rockchip/hdmi/rockchip-hdmi.h"
#if 0
#define I2S_DBG(x...) printk(KERN_INFO x)
#define hdmi_get_hotplug() 0
#endif
+
+
static inline struct rk30_i2s_info *to_info(struct snd_soc_dai *dai)
{
return snd_soc_dai_get_drvdata(dai);
return ret;
}
+static int SR2FS(int samplerate)
+{
+ switch (samplerate) {
+ case 32000:
+ return HDMI_AUDIO_FS_32000;
+ case 44100:
+ return HDMI_AUDIO_FS_44100;
+ case 48000:
+ return HDMI_AUDIO_FS_48000;
+ case 88200:
+ return HDMI_AUDIO_FS_88200;
+ case 96000:
+ return HDMI_AUDIO_FS_96000;
+ case 176400:
+ return HDMI_AUDIO_FS_176400;
+ case 192000:
+ return HDMI_AUDIO_FS_192000;
+ default:
+ I2S_DBG("SR2FS %d unsupport.", samplerate);
+ return HDMI_AUDIO_FS_44100;
+ }
+}
+
static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
u32 iismod;
u32 dmarc;
unsigned long flags;
+ struct hdmi_audio hdmi_audio_cfg;
I2S_DBG("Enter %s, %d \n", __func__, __LINE__);
-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dai->playback_dma_data = &i2s->playback_dma_data;
else
iismod |= I2S_DATA_WIDTH(19);
break;
case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
iismod |= I2S_DATA_WIDTH(23);
break;
case SNDRV_PCM_FORMAT_S32_LE:
iismod |= I2S_DATA_WIDTH(31);
break;
}
+ iismod &= ~CHANNLE_4_EN;
+ switch (params_channels(params)) {
+ case 8:
+ iismod |= CHANNLE_4_EN;
+ break;
+ case 6:
+ iismod |= CHANNEL_3_EN;
+ break;
+ case 4:
+ iismod |= CHANNEL_2_EN;
+ break;
+ case 2:
+ iismod |= CHANNEL_1_EN;
+ break;
+ default:
+ I2S_DBG("%d channels not supported\n",
+ params_channels(params));
+ return -EINVAL;
+ }
+ /* set hdmi codec params */
+ if (HW_PARAMS_FLAG_NLPCM == params->flags)
+ hdmi_audio_cfg.type = HDMI_AUDIO_NLPCM;
+ else
+ hdmi_audio_cfg.type = HDMI_AUDIO_LPCM;
+ hdmi_audio_cfg.channel = params_channels(params);
+ hdmi_audio_cfg.rate = SR2FS(params_rate(params));
+ hdmi_audio_cfg.word_length = HDMI_AUDIO_WORD_LENGTH_16bit;
+ hdmi_config_audio(&hdmi_audio_cfg);
-// writel((16<<24) |(16<<18)|(16<<12)|(16<<6)|16, &(pheadi2s->I2S_FIFOLR));
dmarc = readl(&(pheadi2s->I2S_DMACR));
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
.set_sysclk = rockchip_i2s_set_sysclk,
};
-#define ROCKCHIP_I2S_STEREO_RATES SNDRV_PCM_RATE_8000_96000
+#define ROCKCHIP_I2S_STEREO_RATES SNDRV_PCM_RATE_8000_192000
#define ROCKCHIP_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
__func__, __LINE__,
params_rate(params));
- div_bclk = 63;
+ div_bclk = 127;
div_mclk = pll_out/(params_rate(params)*(div_bclk+1))-1;
snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 2,
.channels_max = 8,
- .buffer_bytes_max = 128*1024,
+ .buffer_bytes_max = 2*1024*1024,/*128*1024,*/
.period_bytes_min = 64,
- .period_bytes_max = 32*1024,//2048*4,///PAGE_SIZE*2,
+ .period_bytes_max = 512*1024,/*32*1024,//2048*4,///PAGE_SIZE*2,*/
.periods_min = 3,
.periods_max = 128,
.fifo_size = 16,
.pcm_hardware = &rockchip_pcm_hardware,
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
.compat_filter_fn = NULL,
- .prealloc_buffer_size = PAGE_SIZE * 32,
+ .prealloc_buffer_size = PAGE_SIZE * 512,
};
int rockchip_pcm_platform_register(struct device *dev)
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
unsigned int dai_fmt = rtd->dai_link->dai_fmt;
int ret;
+ unsigned int pll_out = 0;
+ int div_bclk, div_mclk;
DBG("Enter::%s----%d\n", __func__, __LINE__);
/* set codec DAI configuration */
__func__);
return ret;
}
+
+ switch (params_rate(params)) {
+ case 8000:
+ case 16000:
+ case 24000:
+ case 32000:
+ case 48000:
+ case 96000:
+ pll_out = 12288000;
+ break;
+ case 11025:
+ case 22050:
+ case 44100:
+ case 88200:
+ pll_out = 11289600;
+ break;
+ case 176400:
+ pll_out = 11289600*2;
+ break;
+ case 192000:
+ pll_out = 12288000*2;
+ break;
+ default:
+ DBG("Enter:%s, %d, Error rate=%d\n", __func__,
+ __LINE__, params_rate(params));
+ return -EINVAL;
+ break;
+ }
+ DBG("Enter:%s, %d, rate=%d\n", __func__, __LINE__, params_rate(params));
+ snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN);
+
+ div_bclk = 127;
+ div_mclk = pll_out/(params_rate(params)*128) - 1;
+
+ snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
+ snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, div_bclk);
+ snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
return 0;
}