int tegra_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct tegra_runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct tegra_pcm_dma_params * dmap; int i; snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); /* Limit dma_req_count to period count */ if (prtd->dma_req_count > params_periods(params)) prtd->dma_req_count = params_periods(params); dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); if (dmap) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { for (i = 0; i < prtd->dma_req_count; i++) setup_dma_tx_request(&prtd->dma_req[i], dmap); } else { for (i = 0; i < prtd->dma_req_count; i++) setup_dma_rx_request(&prtd->dma_req[i], dmap); } } for (i = 0; i < prtd->dma_req_count; i++) prtd->dma_req[i].size = params_period_bytes(params); return 0; }
/* * hw_params callback */ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream); struct cx23885_audio_buffer *buf; int ret; if (substream->runtime->dma_area) { dsp_buffer_free(chip); substream->runtime->dma_area = NULL; } chip->period_size = params_period_bytes(hw_params); chip->num_periods = params_periods(hw_params); chip->dma_size = chip->period_size * params_periods(hw_params); BUG_ON(!chip->dma_size); BUG_ON(chip->num_periods & (chip->num_periods-1)); buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (NULL == buf) return -ENOMEM; buf->bpl = chip->period_size; chip->buf = buf; ret = cx23885_alsa_dma_init(chip, (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); if (ret < 0) goto error; ret = cx23885_alsa_dma_map(chip); if (ret < 0) goto error; ret = cx23885_risc_databuffer(chip->pci, &buf->risc, buf->sglist, chip->period_size, chip->num_periods, 1); if (ret < 0) goto error; /* Loop back to start of program */ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC); buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ substream->runtime->dma_area = chip->buf->vaddr; substream->runtime->dma_bytes = chip->dma_size; substream->runtime->dma_addr = 0; return 0; error: kfree(buf); chip->buf = NULL; return ret; }
static int s3c_idma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct lpam_i2s_pdata *prtd = substream->runtime->private_data; unsigned long idma_totbytes; pr_debug("Entered %s\n", __func__); idma_totbytes = params_buffer_bytes(params); prtd->end = LP_TXBUFF_ADDR + idma_totbytes; prtd->period = params_periods(params); s3c_idma.dma_end = prtd->end; s3c_idma.period_val = prtd->period; snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); memset(runtime->dma_area, 0, LP_BUFSIZE); runtime->dma_bytes = idma_totbytes; s3c_idma_setcallbk(s3c_idma_done, params_period_bytes(params)); prtd->start = runtime->dma_addr; prtd->pos = prtd->start; prtd->end = prtd->start + idma_totbytes; printk("DmaAddr=@%x Total=%lubytes PrdSz=%u #Prds=%u\n", prtd->start, idma_totbytes, params_period_bytes(params), prtd->period); return 0; }
static int snd_atiixp_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct atiixp_modem *chip = snd_pcm_substream_chip(substream); struct atiixp_dma *dma = substream->runtime->private_data; int err; int i; err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) return err; dma->buf_addr = substream->runtime->dma_addr; dma->buf_bytes = params_buffer_bytes(hw_params); err = atiixp_build_dma_packets(chip, dma, substream, params_periods(hw_params), params_period_bytes(hw_params)); if (err < 0) return err; /* */ for (i = 0; i < NUM_ATI_CODECS; i++) { if (! chip->ac97[i]) continue; snd_ac97_write(chip->ac97[i], AC97_LINE1_RATE, params_rate(hw_params)); snd_ac97_write(chip->ac97[i], AC97_LINE1_LEVEL, 0); } return err; }
static int txx9aclc_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 snd_soc_device *socdev = rtd->socdev; struct snd_pcm_runtime *runtime = substream->runtime; struct txx9aclc_dmadata *dmadata = runtime->private_data; int ret; ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); if (ret < 0) return ret; dev_dbg(socdev->dev, "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd " "runtime->min_align %ld\n", (unsigned long)runtime->dma_area, (unsigned long)runtime->dma_addr, runtime->dma_bytes, runtime->min_align); dev_dbg(socdev->dev, "periods %d period_bytes %d stream %d\n", params_periods(params), params_period_bytes(params), substream->stream); dmadata->substream = substream; dmadata->pos = 0; return 0; }
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 idma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct idma_ctrl *prtd = substream->runtime->private_data; u32 ahb = readl(idma.regs + I2SAHB); pr_debug("Entered %s\n", __func__); ahb |= (AHB_DMARLD | AHB_INTMASK); writel(ahb, idma.regs + I2SAHB); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); memset(runtime->dma_area, 0, runtime->dma_bytes); prtd->start = prtd->pos = runtime->dma_addr; prtd->period = params_periods(params); prtd->periodsz = params_period_bytes(params); prtd->end = prtd->start + runtime->dma_bytes; idma_setcallbk(substream, idma_done); #ifndef PRODUCT_SHIP pr_info("I:%s:DmaAddr=@%x Total=%d PrdSz=%d #Prds=%d dma_area=0x%x\n", (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "P" : "C", prtd->start, runtime->dma_bytes, prtd->periodsz, prtd->period, (unsigned int)runtime->dma_area); #endif return 0; }
static int idma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct idma_ctrl *prtd = substream->runtime->private_data; u32 mod = readl(idma.regs + I2SMOD); u32 ahb = readl(idma.regs + I2SAHB); ahb |= (AHB_DMARLD | AHB_INTMASK); mod |= MOD_TXS_IDMA; writel(ahb, idma.regs + I2SAHB); writel(mod, idma.regs + I2SMOD); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); prtd->start = prtd->pos = runtime->dma_addr; prtd->period = params_periods(params); prtd->periodsz = params_period_bytes(params); prtd->end = runtime->dma_addr + runtime->dma_bytes; idma_setcallbk(substream, idma_done); return 0; }
static int smi2021_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { int size, rc; size = params_period_bytes(hw_params) * params_periods(hw_params); rc = pcm_buffer_alloc(substream, size); if (rc < 0) return rc; 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; 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; }
/* * PCM operations */ static int lpc313x_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct lpc313x_dma_data *prtd = runtime->private_data; /* this may get called several times by oss emulation * with different params */ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); prtd->dma_buffer = runtime->dma_addr; prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; prtd->period_size = params_period_bytes(params); prtd->num_periods = params_periods(params); return 0; }
static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream); struct cs5535audio_dma *dma = substream->runtime->private_data; int err; err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) return err; dma->buf_addr = substream->runtime->dma_addr; dma->buf_bytes = params_buffer_bytes(hw_params); err = cs5535audio_build_dma_packets(cs5535au, dma, substream, params_periods(hw_params), params_period_bytes(hw_params)); return err; }
/* * hw_params callback: * allocate the buffer and build up the buffer description table */ static int snd_via82xx_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct via82xx_modem *chip = snd_pcm_substream_chip(substream); struct viadev *viadev = substream->runtime->private_data; int err; err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) return err; err = build_via_table(viadev, substream, chip->pci, params_periods(hw_params), params_period_bytes(hw_params)); if (err < 0) return err; snd_ac97_write(chip->ac97, AC97_LINE1_RATE, params_rate(hw_params)); snd_ac97_write(chip->ac97, AC97_LINE1_LEVEL, 0); return 0; }
/* * hw_params - allocate the buffer and set up buffer descriptors */ static int snd_atiixp_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *hw_params) { atiixp_t *chip = snd_pcm_substream_chip(substream); atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data; int err; err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) return err; dma->buf_addr = substream->runtime->dma_addr; dma->buf_bytes = params_buffer_bytes(hw_params); err = atiixp_build_dma_packets(chip, dma, substream, params_periods(hw_params), params_period_bytes(hw_params)); if (err < 0) return err; if (dma->ac97_pcm_type >= 0) { struct ac97_pcm *pcm = chip->pcms[dma->ac97_pcm_type]; /* PCM is bound to AC97 codec(s) * set up the AC97 codecs */ if (dma->pcm_open_flag) { snd_ac97_pcm_close(pcm); dma->pcm_open_flag = 0; } err = snd_ac97_pcm_open(pcm, params_rate(hw_params), params_channels(hw_params), pcm->r[0].slots); if (err >= 0) dma->pcm_open_flag = 1; } return err; }
static int s3c_idma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct lpam_i2s_pdata *prtd = substream->runtime->private_data; pr_debug("Entered %s\n", __func__); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); memset(runtime->dma_area, 0, runtime->dma_bytes); prtd->start = prtd->pos = runtime->dma_addr; prtd->period = params_periods(params); prtd->periodsz = params_period_bytes(params); prtd->end = LP_TXBUFF_ADDR + runtime->dma_bytes; s3c_idma_setcallbk(substream, s3c_idma_done); pr_info("DmaAddr=@%x Total=%dbytes PrdSz=%d #Prds=%d dma_area=0x%x\n", prtd->start, runtime->dma_bytes, prtd->periodsz, prtd->period, (unsigned int)runtime->dma_area); 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 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 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 rockchip_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct rockchip_runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) struct rockchip_pcm_dma_params *dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) struct rockchip_pcm_dma_params *dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); #else struct rockchip_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; #endif unsigned long totbytes = params_buffer_bytes(params); int ret = 0; DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma) return 0; /* this may get called several times by oss emulation * with different params -HW */ if (prtd->params == NULL) { /* prepare DMA */ prtd->params = dma; #ifdef CONFIG_SND_I2S_DMA_EVENT_DYNAMIC DBG("params %p, client %p, channel %d\n", prtd->params,prtd->params->client, prtd->params->channel); ret = rk29_dma_request(prtd->params->channel, prtd->params->client, NULL); DBG("Enter::%s, %d, ret=%d, Channel=%d\n", __FUNCTION__, __LINE__, ret, prtd->params->channel); if (ret) { DBG(KERN_ERR "failed to get dma channel\n"); return ret; } #endif } ret = rk29_dma_set_buffdone_fn(prtd->params->channel, rk29_audio_buffdone); if(ret < 0){ DBG(KERN_ERR "failed to rk29_dma_set_buffdone_fn\n"); return ret; } snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = totbytes; spin_lock_irq(&prtd->lock); prtd->dma_loaded = 0; prtd->dma_limit = params_periods(params);//runtime->hw.periods_min; prtd->dma_period = params_period_bytes(params); prtd->dma_start = runtime->dma_addr; prtd->dma_pos = prtd->dma_start; prtd->dma_end = prtd->dma_start + prtd->dma_limit*prtd->dma_period; prtd->transfer_first = 1; prtd->curr = NULL; prtd->next = NULL; prtd->end = NULL; spin_unlock_irq(&prtd->lock); printk(KERN_DEBUG "i2s dma info:periodsize(%ld),limit(%d),buffersize(%d),over(%d)\n", prtd->dma_period,prtd->dma_limit,totbytes,totbytes-(prtd->dma_period*prtd->dma_limit)); return ret; }
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 s5p_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; unsigned long idma_totbytes; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ #ifdef CONFIG_S5P64XX_LPAUDIO idma_totbytes = params_buffer_bytes(params) * CONFIG_ANDROID_BUF_NUM; s3c_i2s.idma_end = LP_TXBUFF_ADDR + idma_totbytes; s3c_i2s.idma_period = params_periods(params); #endif rtd->dai->cpu_dai->dma_data = &s3c_i2s_pcm_stereo_out; } else rtd->dai->cpu_dai->dma_data = &s3c_i2s_pcm_stereo_in; /* Working copies of register */ iismod = readl(s3c_i2s.regs + S3C_IISMOD); #ifdef CONFIG_SND_S5P_RP iismod &= ~(S3C_IISMOD_BLCMASK | S3C_IISMOD_BLCPMASK | S3C_IISMOD_BLCSMASK); #else iismod &= ~(S3C_IISMOD_BLCMASK | S3C_IISMOD_BLCMASK_LP); #endif /* 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; } /* RFS & BFS are set by dai_link(machine specific) code via set_clkdiv */ #ifdef CONFIG_SND_S5P_RP /* Set same pcm format for primary & secondary port */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod |= S3C_IISMOD_8BIT | S3C_IISMOD_S8BIT | S3C_IISMOD_P8BIT; break; case SNDRV_PCM_FORMAT_S16_LE: iismod |= S3C_IISMOD_16BIT | S3C_IISMOD_S16BIT | S3C_IISMOD_P16BIT; break; case SNDRV_PCM_FORMAT_S24_LE: iismod |= S3C_IISMOD_24BIT | S3C_IISMOD_S24BIT | S3C_IISMOD_P24BIT; break; default: return -EINVAL; } #else switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod |= S3C_IISMOD_8BIT | S3C_IISMOD_8BIT_LP; break; case SNDRV_PCM_FORMAT_S16_LE: iismod |= S3C_IISMOD_16BIT | S3C_IISMOD_16BIT_LP; break; case SNDRV_PCM_FORMAT_S24_LE: iismod |= S3C_IISMOD_24BIT | S3C_IISMOD_24BIT_LP; break; default: return -EINVAL; } #endif writel(iismod, s3c_i2s.regs + S3C_IISMOD); 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; }
/* hw_params callback */ static int snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * hw_params) { chip_t *chip = snd_pcm_substream_chip(substream); stream_t *stream = (stream_t *) (substream->runtime->private_data); snd_pcm_sgbuf_t *sgbuf; int err; // Alloc buffer memory. err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) { printk(KERN_ERR "Vortex: pcm page alloc failed!\n"); return err; } //sgbuf = (snd_pcm_sgbuf_t *) substream->runtime->dma_private; sgbuf = snd_pcm_substream_sgbuf(substream); /* printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params), params_period_bytes(hw_params), params_channels(hw_params)); */ // Make audio routes and config buffer DMA. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { int dma, type = VORTEX_PCM_TYPE(substream->pcm); /* Dealloc any routes. */ if (stream != NULL) vortex_adb_allocroute(chip, stream->dma, stream->nr_ch, stream->dir, stream->type); /* Alloc routes. */ dma = vortex_adb_allocroute(chip, -1, params_channels(hw_params), substream->stream, type); if (dma < 0) return dma; stream = substream->runtime->private_data = &chip->dma_adb[dma]; stream->substream = substream; /* Setup Buffers. */ vortex_adbdma_setbuffers(chip, dma, sgbuf, params_period_bytes(hw_params), params_periods(hw_params)); } #ifndef CHIP_AU8810 else { /* if (stream != NULL) vortex_wt_allocroute(chip, substream->number, 0); */ vortex_wt_allocroute(chip, substream->number, params_channels(hw_params)); stream = substream->runtime->private_data = &chip->dma_wt[substream->number]; stream->dma = substream->number; stream->substream = substream; vortex_wtdma_setbuffers(chip, substream->number, sgbuf, params_period_bytes(hw_params), params_periods(hw_params)); } #endif return 0; }
static int dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; unsigned long totbytes = params_buffer_bytes(params); struct s3c_dma_params *dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); struct samsung_dma_req req; struct samsung_dma_config config; pr_debug("Entered %s\n", __func__); /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma) return 0; /* this may get called several times by oss emulation * with different params -HW */ if (prtd->params == NULL) { /* prepare DMA */ prtd->params = dma; pr_debug("params %p, client %p, channel %d\n", prtd->params, prtd->params->client, prtd->params->channel); prtd->params->ops = samsung_dma_get_ops(); req.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); req.client = prtd->params->client; config.direction = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); config.width = prtd->params->dma_size; config.maxburst = 1; config.fifo = prtd->params->dma_addr; prtd->params->ch = prtd->params->ops->request( prtd->params->channel, &req); prtd->params->ops->config(prtd->params->ch, &config); } snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = totbytes; spin_lock_irq(&prtd->lock); prtd->dma_loaded = 0; prtd->dma_period = params_period_bytes(params); prtd->dma_start = runtime->dma_addr; prtd->dma_pos = prtd->dma_start; prtd->dma_end = prtd->dma_start + totbytes; if (runtime->dma_addr > EXYNOS_PA_AUDSS) prtd->dram_used = true; else prtd->dram_used = false; spin_unlock_irq(&prtd->lock); pr_debug("ADMA:%s:DmaAddr=@%x Total=%d PrdSz=%d #Prds=%d dma_area=0x%x\n", (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "P" : "C", prtd->dma_start, runtime->dma_bytes, params_period_bytes(params), params_periods(params), (unsigned int)runtime->dma_area); return 0; }
/* hw_params callback */ static int snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { vortex_t *chip = snd_pcm_substream_chip(substream); stream_t *stream = (stream_t *) (substream->runtime->private_data); int err; // Alloc buffer memory. err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) { dev_err(chip->card->dev, "Vortex: pcm page alloc failed!\n"); return err; } /* pr_info( "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params), params_period_bytes(hw_params), params_channels(hw_params)); */ spin_lock_irq(&chip->lock); // Make audio routes and config buffer DMA. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { int dma, type = VORTEX_PCM_TYPE(substream->pcm); /* Dealloc any routes. */ if (stream != NULL) vortex_adb_allocroute(chip, stream->dma, stream->nr_ch, stream->dir, stream->type, substream->number); /* Alloc routes. */ dma = vortex_adb_allocroute(chip, -1, params_channels(hw_params), substream->stream, type, substream->number); if (dma < 0) { spin_unlock_irq(&chip->lock); return dma; } stream = substream->runtime->private_data = &chip->dma_adb[dma]; stream->substream = substream; /* Setup Buffers. */ vortex_adbdma_setbuffers(chip, dma, params_period_bytes(hw_params), params_periods(hw_params)); if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) { chip->pcm_vol[substream->number].active = 1; vortex_notify_pcm_vol_change(chip->card, chip->pcm_vol[substream->number].kctl, 1); } } #ifndef CHIP_AU8810 else { /* if (stream != NULL) vortex_wt_allocroute(chip, substream->number, 0); */ vortex_wt_allocroute(chip, substream->number, params_channels(hw_params)); stream = substream->runtime->private_data = &chip->dma_wt[substream->number]; stream->dma = substream->number; stream->substream = substream; vortex_wtdma_setbuffers(chip, substream->number, params_period_bytes(hw_params), params_periods(hw_params)); } #endif spin_unlock_irq(&chip->lock); return 0; }
static int msm_afe_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_dma_buffer *dma_buf = &substream->dma_buffer; struct pcm_afe_info *prtd = runtime->private_data; struct afe_audio_buffer *buf; int dir, rc; pr_debug("%s:\n", __func__); mutex_lock(&prtd->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) dir = IN; else dir = OUT; rc = q6afe_audio_client_buf_alloc_contiguous(dir, prtd->audio_client, (params_buffer_bytes(params) / params_periods(params)), params_periods(params)); pr_debug("params_buffer_bytes(params) = %d\n", (params_buffer_bytes(params))); pr_debug("params_periods(params) = %d\n", (params_periods(params))); pr_debug("params_periodsize(params) = %d\n", (params_buffer_bytes(params) / params_periods(params))); if (rc < 0) { pr_err("Audio Start: Buffer Allocation failed rc = %d\n", rc); mutex_unlock(&prtd->lock); return -ENOMEM; } buf = prtd->audio_client->port[dir].buf; if (buf == NULL || buf[0].data == NULL) { mutex_unlock(&prtd->lock); return -ENOMEM; } pr_debug("%s:buf = %p\n", __func__, buf); dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; dma_buf->dev.dev = substream->pcm->card->dev; dma_buf->private_data = NULL; dma_buf->area = buf[0].data; dma_buf->addr = buf[0].phys; dma_buf->bytes = params_buffer_bytes(params); if (!dma_buf->area) { pr_err("%s:MSM AFE physical memory allocation failed\n", __func__); mutex_unlock(&prtd->lock); return -ENOMEM; } memset(dma_buf->area, 0, params_buffer_bytes(params)); prtd->dma_addr = (u32) dma_buf->addr; mutex_unlock(&prtd->lock); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); rc = afe_memory_map(dma_buf->addr, dma_buf->bytes, prtd->audio_client); if (rc < 0) pr_err("fail to map memory to DSP\n"); return rc; }
static int dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; unsigned long totbytes = params_buffer_bytes(params); struct s3c_dma_params *dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); int ret = 0; pr_debug("Entered %s\n", __func__); /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma) return 0; /* this may get called several times by oss emulation * with different params -HW */ if (prtd->params == NULL) { /* prepare DMA */ prtd->params = dma; pr_debug("params %p, client %p, channel %d\n", prtd->params, prtd->params->client, prtd->params->channel); ret = s3c2410_dma_request(prtd->params->channel, prtd->params->client, NULL); if (ret < 0) { printk(KERN_ERR "failed to get dma channel\n"); return ret; } /* use the circular buffering if we have it available. */ if (s3c_dma_has_circular()) s3c2410_dma_setflags(prtd->params->channel, S3C2410_DMAF_CIRCULAR); } s3c2410_dma_set_buffdone_fn(prtd->params->channel, audio_buffdone); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = totbytes; spin_lock_irq(&prtd->lock); prtd->dma_loaded = 0; prtd->dma_limit = runtime->hw.periods_min; prtd->dma_period = params_period_bytes(params); prtd->dma_start = runtime->dma_addr; prtd->dma_pos = prtd->dma_start; prtd->dma_end = prtd->dma_start + totbytes; pr_debug("G:%s:DmaAddr=@%x Total=%d PrdSz=%d #Prds=%d dma_area=0x%x\n", (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "P" : "C", prtd->dma_start, runtime->dma_bytes, params_period_bytes(params), params_periods(params), (unsigned int)runtime->dma_area); spin_unlock_irq(&prtd->lock); return 0; }
static int s3c_dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct s3c24xx_runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data; unsigned long totbytes = params_buffer_bytes(params); unsigned int periods = params_periods(params); int ret = 0; pr_debug("Entered %s\n", __func__); if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { totbytes *= CONFIG_ANDROID_BUF_NUM; } /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma) return 0; /* this may get called several times by oss emulation * with different params -HW */ if (prtd->params == NULL) { /* prepare DMA */ prtd->params = dma; pr_debug("params %p, client %p, channel %d\n", prtd->params, prtd->params->client, prtd->params->channel); ret = s3c2410_dma_request(prtd->params->channel, prtd->params->client, NULL); if (ret < 0) { printk(KERN_ERR "failed to get dma channel\n"); return ret; } /* use the circular buffering if we have it available. */ /* if (s3c_dma_has_circular()) s3c2410_dma_setflags(prtd->params->channel, S3C2410_DMAF_CIRCULAR);*/ //sayanta commented..need to check fucntionality } s3c2410_dma_set_buffdone_fn(prtd->params->channel, s3c24xx_audio_buffdone); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = totbytes; spin_lock_irq(&prtd->lock); prtd->dma_loaded = 0; prtd->dma_limit = runtime->hw.periods_min; prtd->dma_period = params_period_bytes(params); prtd->dma_start = runtime->dma_addr; prtd->dma_pos = prtd->dma_start; prtd->dma_end = prtd->dma_start + totbytes; spin_unlock_irq(&prtd->lock); printk("%s: DmaAddr=@%x Total=%lubytes PrdSz=%u #Prds=%u, dmaEnd 0x%x\n", __func__, runtime->dma_addr, totbytes, params_period_bytes(params), periods, prtd->dma_end); // pr_debug("Finishing %s ..dma_period=%u..dma_bytes=%lu..dma_limit=%d..\n",__func__,prtd->dma_period,totbytes,prtd->dma_limit); 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; }