static int psc_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; u32 mode; dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i" " periods=%i buffer_size=%i buffer_bytes=%i\n", __func__, substream, params_period_size(params), params_period_bytes(params), params_periods(params), params_buffer_size(params), params_buffer_bytes(params)); switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: mode = MPC52xx_PSC_SICR_SIM_CODEC_8; break; case SNDRV_PCM_FORMAT_S16_BE: mode = MPC52xx_PSC_SICR_SIM_CODEC_16; break; case SNDRV_PCM_FORMAT_S24_BE: mode = MPC52xx_PSC_SICR_SIM_CODEC_24; break; case SNDRV_PCM_FORMAT_S32_BE: mode = MPC52xx_PSC_SICR_SIM_CODEC_32; break; default: dev_dbg(psc_dma->dev, "invalid format\n"); return -EINVAL; } out_be32(&psc_dma->psc_regs->sicr, psc_dma->sicr | mode); return 0; }
static int tcc_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct tcc_pcm_dma_params *dma_data; if (substream->pcm->device == __I2S_DEV_NUM__) { if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dma_data = &tcc_i2s_pcm_stereo_out; } else if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) { dma_data = &tcc_i2s_pcm_stereo_in; } snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); // Set DAI clock tcc_i2s_set_clock(params_rate(params)); } alsa_dbg("=====================\n"); alsa_dbg("= rate : %d\n", params_rate(params)); alsa_dbg("= channels : %d\n", params_channels(params)); alsa_dbg("= period_size : %d\n", params_period_size(params)); return 0; }
static int nusmart_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct nusmart_runtime_data *rtd_prv = runtime->private_data; size_t totsize = params_buffer_bytes(params); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = totsize; rtd_prv->rcv_bytes_count = 0; rtd_prv->tran_bytes_count = 0; rtd_prv->rate = params_rate(params); rtd_prv->fmt = params_format(params); DBG_PRINT("buffer_bytes = 0x%x, perd_bytes = 0x%x, perd_size = %d, ch = %d, fmt = %d, rate = %d \n", params_buffer_bytes(params), params_period_bytes(params), params_period_size(params), params_channels(params), params_format(params), params_rate(params) ); return 0; }
static int jz_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); struct jz_pcm_runtime_data *prtd = substream->runtime->private_data; struct jz_pcm_dma_params *dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); struct dma_slave_config slave_config; int ret; DMA_SUBSTREAM_MSG(substream, "%s enter\n", __func__); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { slave_config.direction = DMA_TO_DEVICE; slave_config.dst_addr = dma_params->dma_addr; } else { slave_config.direction = DMA_FROM_DEVICE; slave_config.src_addr = dma_params->dma_addr; } slave_config.dst_addr_width = dma_params->buswidth; slave_config.dst_maxburst = dma_params->max_burst; slave_config.src_addr_width = dma_params->buswidth; /*jz dmaengine needed*/ slave_config.src_maxburst = dma_params->max_burst; ret = dmaengine_slave_config(prtd->dma_chan, &slave_config); if (ret) return ret; #ifdef CONFIG_JZ_ASOC_DMA_HRTIMER_MODE { unsigned long long time_ns; time_ns = 1000LL * 1000 * 1000 * params_period_size(params); do_div(time_ns, params_rate(params)); prtd->expires = ns_to_ktime(time_ns); } #else prtd->delayed_jiffies = 2 * (params_period_size(params) * HZ /params_rate(params)); #endif return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); }
static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; int i; unsigned long dma_addr; imx_ssi_dma_alloc(substream); iprtd->size = params_buffer_bytes(params); iprtd->periods = params_periods(params); iprtd->period = params_period_bytes(params); iprtd->offset = 0; iprtd->period_time = HZ / (params_rate(params) / params_period_size(params)); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); if (iprtd->sg_count != iprtd->periods) { kfree(iprtd->sg_list); iprtd->sg_list = kcalloc(iprtd->periods + 1, sizeof(struct scatterlist), GFP_KERNEL); if (!iprtd->sg_list) return -ENOMEM; iprtd->sg_count = iprtd->periods + 1; } sg_init_table(iprtd->sg_list, iprtd->sg_count); dma_addr = runtime->dma_addr; for (i = 0; i < iprtd->periods; i++) { iprtd->sg_list[i].page_link = 0; iprtd->sg_list[i].offset = 0; iprtd->sg_list[i].dma_address = dma_addr; iprtd->sg_list[i].length = iprtd->period; dma_addr += iprtd->period; } /* close the loop */ iprtd->sg_list[iprtd->sg_count - 1].offset = 0; iprtd->sg_list[iprtd->sg_count - 1].length = 0; iprtd->sg_list[iprtd->sg_count - 1].page_link = ((unsigned long) iprtd->sg_list | 0x01) & ~0x02; return 0; }
static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; iprtd->size = params_buffer_bytes(params); iprtd->periods = params_periods(params); iprtd->period = params_period_bytes(params) ; iprtd->offset = 0; iprtd->last_offset = 0; iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); return 0; }
static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ali_voice *pvoice = runtime->private_data; struct snd_ali_voice *evoice = pvoice->extra; int err; err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) return err; /* voice management */ if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) { if (!evoice) { evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1); if (!evoice) return -ENOMEM; pvoice->extra = evoice; evoice->substream = substream; } } else { if (evoice) { snd_ali_free_voice(codec, evoice); pvoice->extra = evoice = NULL; } } return 0; }
static int snd_mvf_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_pcm_runtime *runtime = substream->runtime; struct mvf_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_dma_params *dma_params; int ret; dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); ret = mvf_sai_dma_alloc(substream, params); if (ret) return ret; iprtd->size = params_buffer_bytes(params); iprtd->periods = params_periods(params); iprtd->period_bytes = params_period_bytes(params); iprtd->offset = 0; iprtd->period_time = HZ / (params_rate(params) / params_period_size(params)); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); return 0; }
static int s5pc1xx_12s1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *socdai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai_link *dai = rtd->dai; struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); unsigned long iismod; if(g_spdif_out) return s5pc1xx_spdif_hw_params(substream, params, socdai); else s5pc1xx_spdif_power_off(); s3cdbg("Entered %s\n", __FUNCTION__); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dai->cpu_dai->dma_data = i2s->dma_playback; } else { dai->cpu_dai->dma_data = i2s->dma_capture; } /* Working copies of registers */ iismod = readl(i2s->regs + S5PC1XX_IISMOD); iismod &= ~S5PC1XX_IISMOD_BLCMASK; /* Multi channel enable */ switch (params_channels(params)) { case 1: s3cdbg("s3c i2s: 1 channel\n"); break; case 2: s3cdbg("s3c i2s: 2 channel\n"); break; case 4: s3cdbg("s3c i2s: 4 channel\n"); break; case 6: s3cdbg("s3c i2s: 6 channel\n"); break; default: printk(KERN_ERR "s3c-i2s-v32: %d channels unsupported\n", params_channels(params)); return -EINVAL; } /* Set the bit rate */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod |= S5PC1XX_IISMOD_BLC8BIT; break; case SNDRV_PCM_FORMAT_S16_LE: iismod |= S5PC1XX_IISMOD_BLC16BIT; break; case SNDRV_PCM_FORMAT_S24_LE: iismod |= S5PC1XX_IISMOD_BLC24BIT; break; default: return -EINVAL; } writel(iismod, i2s->regs + S5PC1XX_IISMOD); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) s3cdbg("%s : IISMOD [0x%08x]\n",__FUNCTION__, readl(i2s->regs + S5PC1XX_IISMOD)); s3cdbg("s3c: params_channels %d\n", params_channels(params)); s3cdbg("s3c: params_format %d\n", params_format(params)); s3cdbg("s3c: params_subformat %d\n", params_subformat(params)); s3cdbg("s3c: params_period_size %d\n", params_period_size(params)); s3cdbg("s3c: params_period_bytes %d\n", params_period_bytes(params)); s3cdbg("s3c: params_periods %d\n", params_periods(params)); s3cdbg("s3c: params_buffer_size %d\n", params_buffer_size(params)); s3cdbg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params)); return 0; }
static int bcm947xx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct bcm947xx_runtime_data *brtd = runtime->private_data; //struct bcm947xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; bcm947xx_i2s_info_t *snd_bcm = rtd->dai->cpu_dai->private_data; unsigned long totbytes; unsigned int dma_ofs; unsigned long flags; DBG("%s %s\n", __FUNCTION__, bcm947xx_direction_str(substream)); /* RX DMA requires a data offset due to the RX status header. * Although there is a register setting to make the status header offset * zero, it doesn't seem to work with 4709. */ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { dma_ofs = BCM947XX_DMA_RXOFS_BYTES; } else { dma_ofs = 0; } /* Total bytes in the DMA buffer (excluding period fragement), including unused and * header bytes. */ totbytes = params_buffer_bytes(params); totbytes += params_periods(params) * (BCM947XX_DMA_DATA_BYTES_MAX - params_period_bytes(params)); /* Account for period fragment. */ if (params_buffer_bytes(params) > params_periods(params) * params_period_bytes(params)) { totbytes += dma_ofs; } snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); spin_lock_irqsave(&brtd->lock, flags); brtd->dma_limit = params_periods(params); //runtime->hw.periods_min; brtd->dma_period = params_period_bytes(params); /* Virtual address of our runtime buffer */ brtd->dma_start = (dma_addr_t)runtime->dma_area; brtd->dma_end = brtd->dma_start + totbytes; brtd->dma_ofs = dma_ofs; if (!(snd_bcm->in_use & ~(1 << substream->stream))) { /* Other stream not in-use (we own the settings). */ /* It's safe to set the joint settings and mark as in-use. */ bcm947xx_pcm_set_joint_duplex_settings(snd_bcm, params); snd_bcm->in_use |= (1 << substream->stream); } else if (!bcm947xx_pcm_joint_duplex_settings_equal(snd_bcm, params)) { /* Joint settings don't match; therefore, we're not in-use; bail. */ DBG("%s joint duplex settings not equal\n", __FUNCTION__); snd_pcm_set_runtime_buffer(substream, NULL); snd_bcm->in_use &= ~(1 << substream->stream); return -EBUSY; } else { /* Joint settings matched, and perhaps our first time; mark as in-use! */ snd_bcm->in_use |= (1 << substream->stream); } spin_unlock_irqrestore(&brtd->lock, flags); if (BCM947XX_PCM_DEBUG_ON) { size_t buffer_size = params_buffer_size(params); size_t buffer_bytes = params_buffer_bytes(params); size_t period_size = params_period_size(params); size_t period_bytes = params_period_bytes(params); size_t periods = params_periods(params); DBG("%s: dma_limit %d dma_ofs %d dma_addr %p dma_bytes %d dma_start %p dma_end %p\n", __FUNCTION__, brtd->dma_limit, brtd->dma_ofs, (void *)runtime->dma_addr, runtime->dma_bytes, (void *)brtd->dma_start, (void *)brtd->dma_end); DBG("%s: buffer_size %d buffer_bytes %d\n", __FUNCTION__, buffer_size, buffer_bytes); DBG("%s: period_size %d period_bytes %d periods %d\n", __FUNCTION__, period_size, period_bytes, periods); } return 0; }
static int s3c_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; unsigned long iiscon; unsigned long iismod; unsigned long iisfcon; s3cdbg("Entered %s\n", __FUNCTION__); writel((readl(S3C2410_MISCCR) & ~(7<<8))|(1<<8), S3C2410_MISCCR); /*Set I2C port to controll WM8753 codec*/ s3c2410_gpio_pullup(S3C2410_GPE15, 0); s3c2410_gpio_pullup(S3C2410_GPE14, 0); s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_IICSDA); s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_IICSCL); #if defined CONFIG_SND_SOC_I2S_V40 /* Configure the I2S pins in correct mode */ writel(0x0, S3C2450_GPESEL); s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK); s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); writel(readl(S3C2410_GPEUP)| 0x3ff, S3C2410_GPEUP); writel(readl(S3C2450_GPBSEL)|(0x3<<3), S3C2450_GPBSEL); writel(readl(S3C2410_GPBUP)|(0xF<<18), S3C2410_GPBUP); #elif defined CONFIG_SND_SOC_I2S_V32 /* Configure the I2S pins in correct mode */ writel(0x0, S3C2450_GPLSEL); s3c2410_gpio_cfgpin(S3C2410_GPL4, S3C2450_GPL4_I2S1_SCLK); s3c2410_gpio_cfgpin(S3C2410_GPL5, S3C2450_GPL5_I2S1_CDCLK); s3c2410_gpio_cfgpin(S3C2410_GPL6, S3C2450_GPL6_I2S1_SDI); s3c2410_gpio_cfgpin(S3C2410_GPL7, S3C2450_GPL7_I2S1_SDO); s3c2410_gpio_cfgpin(S3C2443_GPJ13, S3C2450_GPJ13_I2S1_LRCK); writel(readl(S3C2410_GPLUP)| (0xf<<4), S3C2410_GPLUP); writel(readl(S3C2443_GPJDN)| (0x3<<26), S3C2443_GPJDN); #else printk("Error: S3C2450 I2S configration \n",); #endif if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; } else { rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in; } /* Working copies of registers */ iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); iisfcon = readl(s3c24xx_i2s.regs + S3C2443_IISFIC); iiscon |= S3C_IIS0CON_TXDMACTIVE; iiscon |= S3C_IIS0CON_RXDMACTIVE; iismod &= ~S3C_IIS0MOD_CLK_MASK; iismod |= S3C_IIS0MOD_IMS_EXTERNAL_MASTER| S3C_IIS0MOD_INTERNAL_CLK; iismod &= ~S3C_IIS0MOD_MODE_MASK; iismod |= S3C_IIS0MOD_TXRXMODE; /* Multi channel enable */ iismod &= ~S3C_IIS0MOD_DCE_MASK; switch (params_channels(params)) { case 6: printk("s3c i2s: 5.1channel\n"); iismod |= S3C_IIS0MOD_DCE_SD1; iismod |= S3C_IIS0MOD_DCE_SD2; break; case 4: printk("s3c i2s: 4 channel\n"); iismod |= S3C_IIS0MOD_DCE_SD1; break; case 2: printk("s3c i2s: 2 channel\n"); break; default: printk(KERN_ERR "s3c-i2s-v40: %d channels unsupported\n", params_channels(params)); return -EINVAL; } /* Set the bit rate */ #if 0 iismod &= ~0x6000; #endif switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod |= S3C_IIS0MOD_8BIT; iismod &= ~S3C_IIS0MOD_BFS_MASK; iismod |= S3C_IIS0MOD_32FS; iismod &= ~S3C_IIS0MOD_FS_MASK; iismod |= S3C_IIS0MOD_384FS; break; case SNDRV_PCM_FORMAT_S16_LE: iismod &= ~S3C_IIS0MOD_FS_MASK; iismod &= ~S3C_IIS0MOD_BFS_MASK; iismod |= S3C_IIS0MOD_384FS | S3C_IIS0MOD_32FS; iismod &= ~S3C_IIS0MOD_BLC_MASK; iismod |= S3C_IIS0MOD_16BIT; break; case SNDRV_PCM_FORMAT_S24_LE: iismod &= ~S3C_IIS0MOD_FS_MASK; iismod &= ~S3C_IIS0MOD_BFS_MASK; iismod |= S3C_IIS0MOD_384FS | S3C_IIS0MOD_48FS; iismod &= ~S3C_IIS0MOD_BLC_MASK; iismod |= S3C_IIS0MOD_24BIT; break; default: return -EINVAL; } iisfcon |= S3C_IIS_TX_FLUSH; iisfcon |= S3C_IIS_RX_FLUSH; writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); iismod &= ~S3C_IIS0MOD_FM_MASK; writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); writel(iisfcon, s3c24xx_i2s.regs + S3C2443_IISFIC); /* Tx, Rx fifo flush bit clear */ iisfcon &= ~(S3C_IIS_TX_FLUSH | S3C_IIS_RX_FLUSH); writel(iisfcon, s3c24xx_i2s.regs + S3C2443_IISFIC); s3cdbg("s3c iis mode: 0x%08x\n", readl(s3c24xx_i2s.regs + S3C2410_IISMOD)); s3cdbg("s3c: params_channels %d\n", params_channels(params)); s3cdbg("s3c: params_format %d\n", params_format(params)); s3cdbg("s3c: params_subformat %d\n", params_subformat(params)); s3cdbg("s3c: params_period_size %d\n", params_period_size(params)); s3cdbg("s3c: params_period_bytes %d\n", params_period_bytes(params)); s3cdbg("s3c: params_periods %d\n", params_periods(params)); s3cdbg("s3c: params_buffer_size %d\n", params_buffer_size(params)); s3cdbg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params)); s3cdbg("s3c: params_tick_time %d\n", params_tick_time(params)); return 0; }
static int s3c_i2s_v50_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; unsigned long iiscon; unsigned long iismod; unsigned long iisfcon; s3cdbg("Entered %s\n", __FUNCTION__); s5pc1xx_i2s.master = 1; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { rtd->dai->cpu_dai->dma_data = &s5pc1xx_i2s_pcm_stereo_out; } else { rtd->dai->cpu_dai->dma_data = &s5pc1xx_i2s_pcm_stereo_in; } /* Working copies of registers */ iiscon = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0CON); iismod = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0MOD); iisfcon = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0FIC); /* is port used by another stream */ if (!(iiscon & S3C64XX_IIS0CON_I2SACTIVE)) { /* Clear BFS field [2:1] */ iismod &= ~(0x3<<1); iismod |= S3C64XX_IIS0MOD_32FS | S3C64XX_IIS0MOD_INTERNAL_CLK; if (!s5pc1xx_i2s.master) iismod |= S3C64XX_IISMOD_SLAVE; else iismod |= S3C64XX_IIS0MOD_IMS_EXTERNAL_MASTER; } iiscon |= S3C64XX_IISCON_FTXURINTEN; iiscon |= S3C64XX_IIS0CON_TXDMACTIVE; iiscon |= S3C64XX_IIS0CON_RXDMACTIVE; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { iismod |= S3C64XX_IIS0MOD_TXMODE; iisfcon |= S3C64XX_IIS_TX_FLUSH; } else { iismod |= S3C64XX_IIS0MOD_RXMODE; iisfcon |= S3C64XX_IIS_RX_FLUSH; } /* Multi channel enable */ iismod &= ~S3C64XX_IIS0MOD_DCE_MASK; switch (params_channels(params)) { case 6: printk("s3c i2s: 5.1channel\n"); iismod |= S3C64XX_IIS0MOD_DCE_SD2; iismod |= S3C64XX_IIS0MOD_DCE_SD2; break; case 4: printk("s3c i2s: 4 channel\n"); iismod |= S3C64XX_IIS0MOD_DCE_SD2; break; case 2: printk("s3c i2s: 2 channel\n"); break; default: printk(KERN_ERR "s3c-i2s-v50: %d channels unsupported\n", params_channels(params)); return -EINVAL; } /* Set the bit rate */ iismod &= ~0x6000; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: iismod &= ~S3C64XX_IIS0MOD_FS_MASK; iismod |= S3C64XX_IIS0MOD_256FS | S3C64XX_IIS0MOD_32FS; iismod &= ~(0x3<<13); iismod |= S3C64XX_IIS0MOD_16BIT; break; case SNDRV_PCM_FORMAT_S8: iismod |= S3C64XX_IIS0MOD_8BIT; break; case SNDRV_PCM_FORMAT_S24_LE: iismod &= ~S3C64XX_IIS0MOD_FS_MASK; iismod |= S3C64XX_IIS0MOD_384FS | S3C64XX_IIS0MOD_48FS; iismod &= ~(0x3<<13); iismod |= S3C64XX_IIS0MOD_24BIT; break; default: return -EINVAL; } writel(iisfcon, s5pc1xx_i2s.regs + S3C64XX_IIS0FIC); writel(iiscon, s5pc1xx_i2s.regs + S3C64XX_IIS0CON); writel(iismod, s5pc1xx_i2s.regs + S3C64XX_IIS0MOD); // Tx, Rx fifo flush bit clear iisfcon &= ~(S3C64XX_IIS_TX_FLUSH | S3C64XX_IIS_RX_FLUSH); writel(iisfcon, s5pc1xx_i2s.regs + S3C64XX_IIS0FIC); s3cdbg("s3c iis mode: 0x%08x\n", readl(s5pc1xx_i2s.regs + S3C64XX_IIS0MOD)); s3cdbg("s3c: params_channels %d\n", params_channels(params)); s3cdbg("s3c: params_format %d\n", params_format(params)); s3cdbg("s3c: params_subformat %d\n", params_subformat(params)); s3cdbg("s3c: params_period_size %d\n", params_period_size(params)); s3cdbg("s3c: params_period_bytes %d\n", params_period_bytes(params)); s3cdbg("s3c: params_periods %d\n", params_periods(params)); s3cdbg("s3c: params_buffer_size %d\n", params_buffer_size(params)); s3cdbg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params)); // s3cdbg("s3c: params_tick_time %d\n", params_tick_time(params)); s3cdbg("hw_params: IISCON: %lx IISMOD: %lx\n", iiscon, iismod); return 0; }
static int s3c_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; u32 iismod; debug_msg("%s\n", __FUNCTION__); #ifdef CONFIG_S3C_DMA_PL080_SOL rtd->dai->cpu_dai->dma_data = s3c_i2s_dai.dma_data; #endif #ifdef CONFIG_S3C_DMA_PL080 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) rtd->dai->cpu_dai->dma_data = &s3c_i2s_pcm_stereo_out; else rtd->dai->cpu_dai->dma_data = &s3c_i2s_pcm_stereo_in; #endif /* Working copies of register */ iismod = readl(s3c_i2s.regs + S3C_IISMOD); iismod &= ~S3C_IISMOD_BLCMASK; #ifdef CONFIG_S3C_DMA_PL080 /* TODO */ switch(params_channels(params)) { case 1: s3c_i2s_pcm_stereo_in.dma_size = 2; break; case 2: s3c_i2s_pcm_stereo_in.dma_size = 4; break; case 4: break; case 6: break; default: break; } #endif /* RFS & BFS are set by dai_link(machine specific) code via set_clkdiv */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod |= S3C_IISMOD_8BIT; break; case SNDRV_PCM_FORMAT_S16_LE: iismod |= S3C_IISMOD_16BIT; break; case SNDRV_PCM_FORMAT_S24_LE: iismod |= S3C_IISMOD_24BIT; break; default: return -EINVAL; } writel(iismod, s3c_i2s.regs + S3C_IISMOD); debug_msg("s3c iis mode: 0x%08x\n", readl(s3c6410_i2s.regs + S3C64XX_IIS0MOD)); debug_msg("s3c: params_channels %d\n", params_channels(params)); debug_msg("s3c: params_format %d\n", params_format(params)); debug_msg("s3c: params_subformat %d\n", params_subformat(params)); debug_msg("s3c: params_period_size %d\n", params_period_size(params)); debug_msg("s3c: params_period_bytes %d\n", params_period_bytes(params)); debug_msg("s3c: params_periods %d\n", params_periods(params)); debug_msg("s3c: params_buffer_size %d\n", params_buffer_size(params)); debug_msg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params)); debug_msg("hw_params: IISMOD: %x\n", iismod); return 0; }
static int spdif_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct rockchip_spdif_info *spdif = to_info(dai); void __iomem *regs = spdif->regs; unsigned long flags; int cfgr, dmac, intcr, chnsr_byte[5] = {0}; int data_type, err_flag, data_len, data_info; int bs_num, repetition, burst_info; RK_SPDIF_DBG("Entered %s\n", __func__); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dai->playback_dma_data = &spdif->dma_playback; } else { pr_err("spdif:Capture is not supported\n"); return -EINVAL; } spin_lock_irqsave(&spdif->lock, flags); cfgr = readl(regs + CFGR) & CFGR_VALID_DATA_MASK; cfgr &= ~CFGR_VALID_DATA_MASK; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: cfgr |= CFGR_VALID_DATA_16bit; break; case SNDRV_PCM_FORMAT_S20_3LE: cfgr |= CFGR_VALID_DATA_20bit; break; case SNDRV_PCM_FORMAT_S24_LE: cfgr |= CFGR_VALID_DATA_24bit; break; default: goto err; } cfgr &= ~CFGR_HALFWORD_TX_MASK; cfgr |= CFGR_HALFWORD_TX_ENABLE; /* set most MCLK:192kHz */ cfgr &= ~CFGR_CLK_RATE_MASK; cfgr |= (1<<16); cfgr &= ~CFGR_JUSTIFIED_MASK; cfgr |= CFGR_JUSTIFIED_RIGHT; cfgr &= ~CFGR_CSE_MASK; cfgr |= CFGR_CSE_DISABLE; cfgr &= ~CFGR_LINEAR_MASK; cfgr |= CFGR_LINEAR_PCM; /* stream type*/ if (!snd_pcm_format_linear(params_format(params))) cfgr |= CFGR_NON_LINEAR_PCM; cfgr &= ~CFGR_PRE_CHANGE_MASK; cfgr |= CFGR_PRE_CHANGE_ENALBLE; writel(cfgr, regs + CFGR); intcr = readl(regs + INTCR) & INTCR_SDBEIE_MASK; intcr |= INTCR_SDBEIE_ENABLE; writel(intcr, regs + INTCR); dmac = readl(regs + DMACR) & DMACR_TRAN_DMA_MASK & (~DMACR_TRAN_DATA_LEVEL_MASK); dmac |= 0x10; writel(dmac, regs + DMACR); /* * channel byte 0: * Bit 1 * 1 Main data field represents linear PCM samples. * 0 Main data field used for purposes other purposes. */ chnsr_byte[0] = (0x0) | (0x0 << 1) | (0x0 << 2) | (0x0 << 3) | (0x00 << 6); chnsr_byte[1] = (0x0); chnsr_byte[2] = (0x0) | (0x0 << 4) | (0x0 << 6); chnsr_byte[3] = (0x00) | (0x00); chnsr_byte[4] = (0x0 << 4) | (0x01 << 1 | 0x0); /* set stream type */ if (!snd_pcm_format_linear(params_format(params))) { chnsr_byte[0] |= (0x1<<1); chnsr_byte[4] = (0x0<<4)|(0x00<<1|0x0); } writel((chnsr_byte[4] << 16) | (chnsr_byte[4]), regs + SPDIF_CHNSR02_ADDR); writel((chnsr_byte[3] << 24) | (chnsr_byte[2] << 16) | (chnsr_byte[3] << 8) | (chnsr_byte[2]), regs + SPDIF_CHNSR01_ADDR); writel((chnsr_byte[1] << 24) | (chnsr_byte[0] << 16) | (chnsr_byte[1] << 8) | (chnsr_byte[0]), regs + SPDIF_CHNSR00_ADDR); /* set non-linear params */ if (!snd_pcm_format_linear(params_format(params))) { switch (params_format(params)) { case SNDRV_NON_LINEAR_PCM_FORMAT_AC3: /* bit0:6 AC-3:0x01, DTS-I -II -III:11,12,13 */ data_type = burst_info_DATA_TYPE_AC3; /* * repetition:AC-3:1536 * DTS-I -II -III:512,1024,2048 EAC3:6144 */ repetition = 1536; break; case SNDRV_NON_LINEAR_PCM_FORMAT_DTS_I: data_type = BURST_INFO_DATA_TYPE_DTS_I; repetition = 512; break; case SNDRV_NON_LINEAR_PCM_FORMAT_EAC3: data_type = burst_info_DATA_TYPE_EAC3; repetition = 6144; break; default: return -EINVAL; } err_flag = 0x0; data_len = params_period_size(params) * 2 * 16; data_info = 0; bs_num = 0x0; burst_info = (data_len << 16) | (bs_num << 13) | (data_info << 8) | (err_flag << 7) | data_type; writel(burst_info, regs + SPDIF_BURST_INFO); writel(repetition, regs + SPDIF_REPETTION); } spin_unlock_irqrestore(&spdif->lock, flags); return 0; err: spin_unlock_irqrestore(&spdif->lock, flags); return -EINVAL; }