static void mcasp_start_tx(struct davinci_audio_dev *dev) { u8 offset = 0, i; u32 cnt; mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR); mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); for (i = 0; i < dev->num_serializer; i++) { if (dev->serial_dir[i] == TX_MODE) { offset = i; break; } } /* wait for TX ready */ cnt = 0; while (!(mcasp_get_reg(dev->base + DAVINCI_MCASP_XRSRCTL_REG(offset)) & TXSTATE) && (cnt < 100000)) cnt++; mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); }
static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val) { int i = 0; mcasp_set_bits(regs, val); /* programming GBLCTL needs to read back from GBLCTL and verfiy */ /* loop count is to avoid the lock-up */ for (i = 0; i < 1000; i++) { if ((mcasp_get_reg(regs) & val) == val) break; } if (i == 1000 && ((mcasp_get_reg(regs) & val) != val)) printk(KERN_ERR "GBLCTL write error\n"); }
static irqreturn_t mcasp_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { struct platform_device *pdev = dev_id; struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_machine *machine = socdev->machine; struct snd_soc_cpu_dai *cpu_dai; struct davinci_audio_dev *dev; int link_cnt; void __iomem *base; for (link_cnt = 0; link_cnt < machine->num_links; link_cnt++) { cpu_dai = machine->dai_link[link_cnt].cpu_dai; dev = cpu_dai->private_data; base = dev->base; if (mcasp_get_reg(base + DAVINCI_MCASP_TXSTAT_REG) & 0x1) { mcasp_clr_bits(base + DAVINCI_MCASP_EVTCTLX_REG, 1); schedule_delayed_work(&dev->workq, HZ >> 4); } }
static int davinci_mcasp_suspend(struct platform_device *pdev, pm_message_t state) { int ret = 0, idx; struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev); if (dev->version == MCASP_VERSION_3) { dev->gblctlx = mcasp_get_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG); dev->txmask = mcasp_get_reg(dev->base + DAVINCI_MCASP_TXMASK_REG); dev->txfmt = mcasp_get_reg(dev->base + DAVINCI_MCASP_TXFMT_REG); dev->txfmctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_TXFMCTL_REG); dev->aclkxctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_ACLKXCTL_REG); dev->ahclkxctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG); dev->txtdm = mcasp_get_reg(dev->base + DAVINCI_MCASP_TXTDM_REG); dev->wfifoctl = mcasp_get_reg(dev->base + MCASP_VER3_WFIFOCTL); dev->gblctlr = mcasp_get_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG); dev->rxmask = mcasp_get_reg(dev->base + DAVINCI_MCASP_RXMASK_REG); dev->rxfmt = mcasp_get_reg(dev->base + DAVINCI_MCASP_RXFMT_REG); dev->rxfmctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_RXFMCTL_REG); dev->aclkrctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_ACLKRCTL_REG); dev->ahclkrctl = mcasp_get_reg(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG); dev->rxtdm = mcasp_get_reg(dev->base + DAVINCI_MCASP_RXTDM_REG); dev->rfifoctl = mcasp_get_reg(dev->base + MCASP_VER3_RFIFOCTL); for (idx = 0; idx < dev->num_serializer; idx++) { dev->xrsrctl[idx] = mcasp_get_reg(dev->base + DAVINCI_MCASP_XRSRCTL_REG(idx)); } dev->pfunc = mcasp_get_reg(dev->base + DAVINCI_MCASP_PFUNC_REG); dev->pdir = mcasp_get_reg(dev->base + DAVINCI_MCASP_PDIR_REG); } ret = pm_runtime_put_sync(&pdev->dev); if (ret < 0) dev_err(&pdev->dev, "failed to get runtime pm\n"); /* only values < 0 indicate errors */ return IS_ERR_VALUE(ret) ? ret : 0; }
static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val) { mcasp_set_bits(regs, val); while ((mcasp_get_reg(regs) & val) != val); }