2 * rk30_i2s.c -- ALSA SoC ROCKCHIP IIS Audio Layer Platform driver
4 * Driver for rockchip iis audio
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.
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/interrupt.h>
17 #include <linux/device.h>
18 #include <linux/delay.h>
19 #include <linux/clk.h>
20 #include <linux/version.h>
22 #include <linux/of_gpio.h>
23 #include <linux/clk.h>
25 #include <linux/platform_device.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/regmap.h>
28 #include <linux/rockchip/cpu.h>
29 #include <linux/rockchip/cru.h>
30 #include <linux/rockchip/grf.h>
31 #include <linux/slab.h>
33 #include <sound/core.h>
34 #include <sound/pcm.h>
35 #include <sound/pcm_params.h>
36 #include <sound/initval.h>
37 #include <sound/soc.h>
38 #include <sound/dmaengine_pcm.h>
40 #include <linux/spinlock.h>
41 #include <linux/workqueue.h>
47 #include "../../../drivers/video/rockchip/hdmi/rockchip-hdmi.h"
50 #define I2S_DBG(x...) printk(KERN_INFO x)
52 #define I2S_DBG(x...) do { } while (0)
55 #define pheadi2s ((pI2S_REG)(i2s->regs))
59 static DEFINE_SPINLOCK(lock);
61 struct rk30_i2s_info {
64 struct clk *i2s_clk;// i2s clk ,is bclk lrck
65 struct clk *i2s_mclk;//i2s mclk,rk32xx can different i2s clk.
67 struct snd_dmaengine_dai_dma_data capture_dma_data;
68 struct snd_dmaengine_dai_dma_data playback_dma_data;
70 bool i2s_tx_status;//active = true;
73 struct delayed_work clk_delayed_work;
77 #define I2S_CLR_ERROR_COUNT 10// check I2S_CLR reg
78 static struct rk30_i2s_info *rk30_i2s;
80 #if 0 /*defined (CONFIG_RK_HDMI) && defined (CONFIG_SND_RK_SOC_HDMI_I2S)*/
81 extern int hdmi_get_hotplug(void);
83 #define hdmi_get_hotplug() 0
88 static inline struct rk30_i2s_info *to_info(struct snd_soc_dai *dai)
90 return snd_soc_dai_get_drvdata(dai);
94 *Turn on or off the transmission path.
96 static void rockchip_snd_txctrl(struct rk30_i2s_info *i2s, int on)
100 bool is_need_delay = false;
101 int clr_error_count = I2S_CLR_ERROR_COUNT;
103 spin_lock_irqsave(&lock, flags);
105 opr = readl(&(pheadi2s->I2S_DMACR));
106 xfer = readl(&(pheadi2s->I2S_XFER));
107 clr = readl(&(pheadi2s->I2S_CLR));
109 I2S_DBG("rockchip_snd_txctrl: %s\n", on ? "on" : "off");
112 if ((opr & I2S_TRAN_DMA_ENABLE) == 0) {
113 opr |= I2S_TRAN_DMA_ENABLE;
114 writel(opr, &(pheadi2s->I2S_DMACR));
117 if ((xfer & I2S_TX_TRAN_START) == 0 || (xfer & I2S_RX_TRAN_START) == 0) {
118 xfer |= I2S_TX_TRAN_START;
119 xfer |= I2S_RX_TRAN_START;
120 writel(xfer, &(pheadi2s->I2S_XFER));
123 i2s->i2s_tx_status = 1;
126 i2s->i2s_tx_status = 0;
127 opr &= ~I2S_TRAN_DMA_ENABLE;
128 writel(opr, &(pheadi2s->I2S_DMACR));
130 if (i2s->i2s_rx_status == 0 && hdmi_get_hotplug() == 0) {
131 xfer &= ~I2S_TX_TRAN_START;
132 xfer &= ~I2S_RX_TRAN_START;
133 writel(xfer, &(pheadi2s->I2S_XFER));
137 writel(clr, &(pheadi2s->I2S_CLR));
139 is_need_delay = true;
141 I2S_DBG("rockchip_snd_txctrl: stop xfer\n");
145 spin_unlock_irqrestore(&lock, flags);
148 while(readl(&(pheadi2s->I2S_CLR)) && clr_error_count){
151 if(clr_error_count == 0)
152 printk("%s: i2s clr reg warning =%d\n",__FUNCTION__,readl(&(pheadi2s->I2S_CLR)));
157 static void rockchip_snd_rxctrl(struct rk30_i2s_info *i2s, int on)
161 bool is_need_delay = false;
162 int clr_error_count = I2S_CLR_ERROR_COUNT;
164 spin_lock_irqsave(&lock, flags);
166 opr = readl(&(pheadi2s->I2S_DMACR));
167 xfer = readl(&(pheadi2s->I2S_XFER));
168 clr = readl(&(pheadi2s->I2S_CLR));
170 I2S_DBG("rockchip_snd_rxctrl: %s\n", on ? "on" : "off");
173 if ((opr & I2S_RECE_DMA_ENABLE) == 0) {
174 opr |= I2S_RECE_DMA_ENABLE;
175 writel(opr, &(pheadi2s->I2S_DMACR));
178 if ((xfer & I2S_TX_TRAN_START)==0 || (xfer & I2S_RX_TRAN_START) == 0) {
179 xfer |= I2S_RX_TRAN_START;
180 xfer |= I2S_TX_TRAN_START;
181 writel(xfer, &(pheadi2s->I2S_XFER));
184 i2s->i2s_rx_status = 1;
186 i2s->i2s_rx_status = 0;
188 opr &= ~I2S_RECE_DMA_ENABLE;
189 writel(opr, &(pheadi2s->I2S_DMACR));
191 if (i2s->i2s_tx_status == 0 && hdmi_get_hotplug() == 0) {
192 xfer &= ~I2S_RX_TRAN_START;
193 xfer &= ~I2S_TX_TRAN_START;
194 writel(xfer, &(pheadi2s->I2S_XFER));
198 writel(clr, &(pheadi2s->I2S_CLR));
200 is_need_delay = true;
202 I2S_DBG("rockchip_snd_rxctrl: stop xfer\n");
206 spin_unlock_irqrestore(&lock, flags);
209 while(readl(&(pheadi2s->I2S_CLR)) && clr_error_count){
212 if(clr_error_count == 0)
213 printk("%s: i2s clr reg warning =%d\n",__FUNCTION__,readl(&(pheadi2s->I2S_CLR)));
219 * Set Rockchip I2S DAI format
221 static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
224 struct rk30_i2s_info *i2s = to_info(cpu_dai);
226 u32 iis_ckr_value;//clock generation register
230 I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
232 spin_lock_irqsave(&lock, flags);
234 tx_ctl = readl(&(pheadi2s->I2S_TXCR));
235 iis_ckr_value = readl(&(pheadi2s->I2S_CKR));
237 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
238 case SND_SOC_DAIFMT_CBM_CFM:
239 //Codec is master, so set cpu slave.
240 iis_ckr_value &= ~I2S_MODE_MASK;
241 iis_ckr_value |= I2S_SLAVE_MODE;
243 case SND_SOC_DAIFMT_CBS_CFS:
244 //Codec is slave, so set cpu master.
245 iis_ckr_value &= ~I2S_MODE_MASK;
246 iis_ckr_value |= I2S_MASTER_MODE;
249 I2S_DBG("unknwon master/slave format\n");
254 writel(iis_ckr_value, &(pheadi2s->I2S_CKR));
256 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
257 case SND_SOC_DAIFMT_RIGHT_J:
258 tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode
259 tx_ctl |= I2S_BUS_MODE_RSJM;
261 case SND_SOC_DAIFMT_LEFT_J:
262 tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode
263 tx_ctl |= I2S_BUS_MODE_LSJM;
265 case SND_SOC_DAIFMT_I2S:
266 tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode
267 tx_ctl |= I2S_BUS_MODE_NOR;
270 I2S_DBG("Unknown data format\n");
275 I2S_DBG("Enter::%s----%d, I2S_TXCR=0x%X\n",__FUNCTION__,__LINE__,tx_ctl);
277 writel(tx_ctl, &(pheadi2s->I2S_TXCR));
279 rx_ctl = tx_ctl & 0x00007FFF;
280 writel(rx_ctl, &(pheadi2s->I2S_RXCR));
284 spin_unlock_irqrestore(&lock, flags);
289 static int SR2FS(int samplerate)
291 switch (samplerate) {
293 return HDMI_AUDIO_FS_32000;
295 return HDMI_AUDIO_FS_44100;
297 return HDMI_AUDIO_FS_48000;
299 return HDMI_AUDIO_FS_88200;
301 return HDMI_AUDIO_FS_96000;
303 return HDMI_AUDIO_FS_176400;
305 return HDMI_AUDIO_FS_192000;
307 I2S_DBG("SR2FS %d unsupport.", samplerate);
308 return HDMI_AUDIO_FS_44100;
312 static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
313 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
315 struct rk30_i2s_info *i2s = to_info(dai);
319 struct hdmi_audio hdmi_audio_cfg;
321 I2S_DBG("Enter %s, %d \n", __func__, __LINE__);
322 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
323 dai->playback_dma_data = &i2s->playback_dma_data;
325 dai->capture_dma_data = &i2s->capture_dma_data;
327 spin_lock_irqsave(&lock, flags);
329 /* Working copies of register */
330 iismod = readl(&(pheadi2s->I2S_TXCR));
332 iismod &= (~((1<<5)-1));
333 switch (params_format(params)) {
334 case SNDRV_PCM_FORMAT_S8:
335 iismod |= SAMPLE_DATA_8bit;
337 case SNDRV_PCM_FORMAT_S16_LE:
338 iismod |= I2S_DATA_WIDTH(15);
340 case SNDRV_PCM_FORMAT_S20_3LE:
341 iismod |= I2S_DATA_WIDTH(19);
343 case SNDRV_PCM_FORMAT_S24_LE:
344 case SNDRV_PCM_FORMAT_S24_3LE:
345 iismod |= I2S_DATA_WIDTH(23);
347 case SNDRV_PCM_FORMAT_S32_LE:
348 iismod |= I2S_DATA_WIDTH(31);
351 iismod &= ~CHANNLE_4_EN;
352 switch (params_channels(params)) {
354 iismod |= CHANNLE_4_EN;
357 iismod |= CHANNEL_3_EN;
360 iismod |= CHANNEL_2_EN;
363 iismod |= CHANNEL_1_EN;
366 I2S_DBG("%d channels not supported\n",
367 params_channels(params));
370 /* set hdmi codec params */
371 if (HW_PARAMS_FLAG_NLPCM == params->flags)
372 hdmi_audio_cfg.type = HDMI_AUDIO_NLPCM;
374 hdmi_audio_cfg.type = HDMI_AUDIO_LPCM;
375 hdmi_audio_cfg.channel = params_channels(params);
376 hdmi_audio_cfg.rate = SR2FS(params_rate(params));
377 hdmi_audio_cfg.word_length = HDMI_AUDIO_WORD_LENGTH_16bit;
378 hdmi_config_audio(&hdmi_audio_cfg);
380 dmarc = readl(&(pheadi2s->I2S_DMACR));
382 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
383 dmarc = ((dmarc & 0xFFFFFE00) | 16);
385 dmarc = ((dmarc & 0xFE00FFFF) | 16<<16);
387 writel(dmarc, &(pheadi2s->I2S_DMACR));
389 I2S_DBG("Enter %s, %d I2S_TXCR=0x%08X\n", __func__, __LINE__, iismod);
391 writel(iismod, &(pheadi2s->I2S_TXCR));
393 iismod = iismod & 0x00007FFF;
394 writel(iismod, &(pheadi2s->I2S_RXCR));
396 spin_unlock_irqrestore(&lock, flags);
401 static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
403 struct rk30_i2s_info *i2s = to_info(dai);
406 I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
409 case SNDRV_PCM_TRIGGER_START:
410 case SNDRV_PCM_TRIGGER_RESUME:
411 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
412 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
413 rockchip_snd_rxctrl(i2s, 1);
415 rockchip_snd_txctrl(i2s, 1);
417 case SNDRV_PCM_TRIGGER_SUSPEND:
418 case SNDRV_PCM_TRIGGER_STOP:
419 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
420 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
421 rockchip_snd_rxctrl(i2s, 0);
423 rockchip_snd_txctrl(i2s, 0);
434 * Set Rockchip I2S MCLK source
436 static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
437 int clk_id, unsigned int freq, int dir)
439 struct rk30_i2s_info *i2s = to_info(cpu_dai);
441 I2S_DBG("Enter:%s, %d, i2s=0x%p, freq=%d\n", __FUNCTION__, __LINE__, i2s, freq);
443 /*add scu clk source and enable clk*/
444 clk_set_rate(i2s->i2s_clk, freq);
449 * Set Rockchip Clock dividers
451 static int rockchip_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
454 struct rk30_i2s_info *i2s;
459 i2s = to_info(cpu_dai);
461 spin_lock_irqsave(&lock, flags);
463 //stereo mode MCLK/SCK=4
464 reg = readl(&(pheadi2s->I2S_CKR));
466 I2S_DBG("Enter:%s, %d, div_id=0x%08X, div=0x%08X\n", __FUNCTION__, __LINE__, div_id, div);
468 //when i2s in master mode ,must set codec pll div
470 case ROCKCHIP_DIV_BCLK:
471 reg &= ~I2S_TX_SCLK_DIV_MASK;
472 reg |= I2S_TX_SCLK_DIV(div);
473 reg &= ~I2S_RX_SCLK_DIV_MASK;
474 reg |= I2S_RX_SCLK_DIV(div);
476 case ROCKCHIP_DIV_MCLK:
477 reg &= ~I2S_MCLK_DIV_MASK;
478 reg |= I2S_MCLK_DIV(div);
480 case ROCKCHIP_DIV_PRESCALER:
486 writel(reg, &(pheadi2s->I2S_CKR));
489 spin_unlock_irqrestore(&lock, flags);
494 static struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
495 .trigger = rockchip_i2s_trigger,
496 .hw_params = rockchip_i2s_hw_params,
497 .set_fmt = rockchip_i2s_set_fmt,
498 .set_clkdiv = rockchip_i2s_set_clkdiv,
499 .set_sysclk = rockchip_i2s_set_sysclk,
502 #define ROCKCHIP_I2S_STEREO_RATES SNDRV_PCM_RATE_8000_192000
503 #define ROCKCHIP_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
504 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
506 struct snd_soc_dai_driver rockchip_i2s_dai[] = {
508 .name = "rockchip-i2s.0",
513 .rates = ROCKCHIP_I2S_STEREO_RATES,
514 .formats = ROCKCHIP_I2S_FORMATS,
519 .rates = ROCKCHIP_I2S_STEREO_RATES,
520 .formats = ROCKCHIP_I2S_FORMATS,
522 .ops = &rockchip_i2s_dai_ops,
523 .symmetric_rates = 1,
526 .name = "rockchip-i2s.1",
531 .rates = ROCKCHIP_I2S_STEREO_RATES,
532 .formats = ROCKCHIP_I2S_FORMATS,
537 .rates = ROCKCHIP_I2S_STEREO_RATES,
538 .formats = ROCKCHIP_I2S_FORMATS,
540 .ops = &rockchip_i2s_dai_ops,
541 .symmetric_rates = 1,
545 static const struct snd_soc_component_driver rockchip_i2s_component = {
546 .name = "rockchip-i2s",
550 static int rockchip_i2s_suspend_noirq(struct device *dev)
552 I2S_DBG("Enter %s, %d\n", __func__, __LINE__);
554 return pinctrl_pm_select_sleep_state(dev);
557 static int rockchip_i2s_resume_noirq(struct device *dev)
559 I2S_DBG("Enter %s, %d\n", __func__, __LINE__);
561 return pinctrl_pm_select_default_state(dev);
564 #define rockchip_i2s_suspend_noirq NULL
565 #define rockchip_i2s_resume_noirq NULL
569 static void set_clk_later_work(struct work_struct *work)
571 struct rk30_i2s_info *i2s = container_of(work, struct rk30_i2s_info,
572 clk_delayed_work.work);
574 clk_set_rate(i2s->i2s_clk, 11289600);
575 if(!IS_ERR(i2s->i2s_mclk) )
576 clk_set_rate(i2s->i2s_mclk, 11289600);
580 static int rockchip_i2s_probe(struct platform_device *pdev)
582 struct device_node *node = pdev->dev.of_node;
583 struct rk30_i2s_info *i2s;
584 struct resource *mem, *memregion;
588 I2S_DBG("%s()\n", __FUNCTION__);
590 ret = of_property_read_u32(node, "i2s-id", &pdev->id);
592 dev_err(&pdev->dev, "%s() Can not read property: id\n", __FUNCTION__);
597 if (soc_is_rk3126b()) {
600 /* rk3126b has no i2s1 controller(i2s_8ch) */
602 pr_info("rk3126b has no i2s1 controller\n");
607 ret = of_property_read_u32(node, "sdi_source",
616 val = readl_relaxed(RK_GRF_VIRT + 0x0140);
617 val = val | 0x04000400;
618 writel_relaxed(val, RK_GRF_VIRT + 0x0140);
622 if(pdev->id >= MAX_I2S) {
623 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
628 i2s = devm_kzalloc(&pdev->dev, sizeof(struct rk30_i2s_info), GFP_KERNEL);
630 dev_err(&pdev->dev, "Can't allocate i2s info\n");
637 i2s->i2s_hclk = clk_get(&pdev->dev, "i2s_hclk");
638 if(IS_ERR(i2s->i2s_hclk) ) {
639 dev_err(&pdev->dev, "get i2s_hclk failed.\n");
641 clk_prepare_enable(i2s->i2s_hclk);
644 i2s->i2s_clk= clk_get(&pdev->dev, "i2s_clk");
645 if (IS_ERR(i2s->i2s_clk)) {
646 dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
647 ret = PTR_ERR(i2s->i2s_clk);
651 INIT_DELAYED_WORK(&i2s->clk_delayed_work, set_clk_later_work);
652 schedule_delayed_work(&i2s->clk_delayed_work, msecs_to_jiffies(10));
654 clk_set_rate(i2s->iis_clk, 11289600);
656 clk_prepare_enable(i2s->i2s_clk);
658 i2s->i2s_mclk= clk_get(&pdev->dev, "i2s_mclk");
659 if(IS_ERR(i2s->i2s_mclk) ) {
660 printk("This platfrom have not i2s_mclk,no need to set i2s_mclk.\n");
665 clk_set_rate(i2s->i2s_mclk, 11289600);
667 clk_prepare_enable(i2s->i2s_mclk);
670 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
672 dev_err(&pdev->dev, "No memory resource\n");
677 memregion = devm_request_mem_region(&pdev->dev, mem->start,
678 resource_size(mem), "rockchip-i2s");
680 dev_err(&pdev->dev, "Memory region already claimed\n");
685 i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
687 dev_err(&pdev->dev, "ioremap failed\n");
692 regs_base = mem->start;
694 i2s->playback_dma_data.addr = regs_base + I2S_TXR_BUFF;
695 i2s->playback_dma_data.addr_width = 4;
696 i2s->playback_dma_data.maxburst = 16;
698 i2s->capture_dma_data.addr = regs_base + I2S_RXR_BUFF;
699 i2s->capture_dma_data.addr_width = 4;
700 i2s->capture_dma_data.maxburst = 16;
702 i2s->i2s_tx_status = false;
703 i2s->i2s_rx_status = false;
705 pm_runtime_enable(&pdev->dev);
706 if (!pm_runtime_enabled(&pdev->dev)) {
707 ret = rockchip_i2s_resume_noirq(&pdev->dev);
712 //set dev name to driver->name.id for sound card register
713 dev_set_name(&pdev->dev, "%s.%d", pdev->dev.driver->name, pdev->id);
715 ret = snd_soc_register_component(&pdev->dev, &rockchip_i2s_component,
716 &rockchip_i2s_dai[pdev->id], 1);
719 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
724 ret = rockchip_pcm_platform_register(&pdev->dev);
726 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
727 goto err_unregister_component;
730 /* Mark ourselves as in TXRX mode so we can run through our cleanup
731 * process without warnings. */
732 rockchip_snd_txctrl(i2s, 0);
733 rockchip_snd_rxctrl(i2s, 0);
735 dev_set_drvdata(&pdev->dev, i2s);
738 err_unregister_component:
739 snd_soc_unregister_component(&pdev->dev);
741 if (!pm_runtime_status_suspended(&pdev->dev))
742 rockchip_i2s_suspend_noirq(&pdev->dev);
744 pm_runtime_disable(&pdev->dev);
746 clk_put(i2s->i2s_clk);
752 static int rockchip_i2s_remove(struct platform_device *pdev)
754 rockchip_pcm_platform_unregister(&pdev->dev);
755 snd_soc_unregister_component(&pdev->dev);
761 static const struct of_device_id exynos_i2s_match[] = {
762 { .compatible = "rockchip-i2s"},
765 MODULE_DEVICE_TABLE(of, exynos_i2s_match);
768 static const struct dev_pm_ops rockchip_i2s_pm_ops = {
769 .suspend_noirq = rockchip_i2s_suspend_noirq,
770 .resume_noirq = rockchip_i2s_resume_noirq,
773 static struct platform_driver rockchip_i2s_driver = {
774 .probe = rockchip_i2s_probe,
775 .remove = rockchip_i2s_remove,
777 .name = "rockchip-i2s",
778 .owner = THIS_MODULE,
779 .of_match_table = of_match_ptr(exynos_i2s_match),
780 .pm = &rockchip_i2s_pm_ops,
784 static int __init rockchip_i2s_init(void)
786 return platform_driver_register(&rockchip_i2s_driver);
788 subsys_initcall_sync(rockchip_i2s_init);
790 static void __exit rockchip_i2s_exit(void)
792 platform_driver_unregister(&rockchip_i2s_driver);
794 module_exit(rockchip_i2s_exit);
796 /* Module information */
797 MODULE_AUTHOR("rockchip");
798 MODULE_DESCRIPTION("ROCKCHIP IIS ASoC Interface");
799 MODULE_LICENSE("GPL");
802 #ifdef CONFIG_PROC_FS
803 #include <linux/proc_fs.h>
804 #include <linux/seq_file.h>
805 static int proc_i2s_show(struct seq_file *s, void *v)
808 struct rk30_i2s_info *i2s = rk30_i2s;
810 printk("========Show I2S reg========\n");
812 printk("I2S_TXCR = 0x%08X\n", readl(&(pheadi2s->I2S_TXCR)));
813 printk("I2S_RXCR = 0x%08X\n", readl(&(pheadi2s->I2S_RXCR)));
814 printk("I2S_CKR = 0x%08X\n", readl(&(pheadi2s->I2S_CKR)));
815 printk("I2S_DMACR = 0x%08X\n", readl(&(pheadi2s->I2S_DMACR)));
816 printk("I2S_INTCR = 0x%08X\n", readl(&(pheadi2s->I2S_INTCR)));
817 printk("I2S_INTSR = 0x%08X\n", readl(&(pheadi2s->I2S_INTSR)));
818 printk("I2S_XFER = 0x%08X\n", readl(&(pheadi2s->I2S_XFER)));
820 printk("========Show I2S reg========\n");
822 writel(0x0000000F, &(pheadi2s->I2S_TXCR));
823 writel(0x0000000F, &(pheadi2s->I2S_RXCR));
824 writel(0x00071f1F, &(pheadi2s->I2S_CKR));
825 writel(0x001F0110, &(pheadi2s->I2S_DMACR));
826 writel(0x00000003, &(pheadi2s->I2S_XFER));
829 writel(0x5555aaaa, &(pheadi2s->I2S_TXDR));
835 static ssize_t i2s_reg_write(struct file *file,
836 const char __user *user_buf, size_t count, loff_t *ppos)
838 struct rk30_i2s_info *i2s=rk30_i2s;
845 buf_size = min(count, (sizeof(buf)-1));
846 if (copy_from_user(buf, user_buf, buf_size))
850 while (*start == ' ')
852 value = simple_strtoul(start, &start, 10);
854 printk("test --- freq = %ld ret=%d\n",value,clk_set_rate(i2s->i2s_clk, value));
858 static int proc_i2s_open(struct inode *inode, struct file *file)
860 return single_open(file, proc_i2s_show, NULL);
863 static const struct file_operations proc_i2s_fops = {
864 .open = proc_i2s_open,
866 .write = i2s_reg_write,
868 .release = single_release,
871 static int __init i2s_proc_init(void)
873 proc_create("i2s_reg", 0, NULL, &proc_i2s_fops);
876 late_initcall(i2s_proc_init);
877 #endif /* CONFIG_PROC_FS */