struct i2s_dai {
/* Platform device for this DAI */
struct platform_device *pdev;
- /* Memory mapped SFR region */
- void __iomem *addr;
+
/* Frame Clock */
unsigned frmclk;
/*
struct platform_device *pdev;
struct platform_device *pdev_sec;
+ /* Memory mapped SFR region */
+ void __iomem *addr;
+
/* Spinlock protecting access to the device's registers */
spinlock_t spinlock;
/* If operating in SoC-Slave mode */
static inline bool is_slave(struct i2s_dai *i2s)
{
- u32 mod = readl(i2s->addr + I2SMOD);
+ struct samsung_i2s_priv *priv = i2s->priv;
+
+ u32 mod = readl(priv->addr + I2SMOD);
return (mod & (1 << i2s->variant_regs->mss_off)) ? true : false;
}
if (!i2s)
return false;
- active = readl(i2s->addr + I2SCON);
+ active = readl(i2s->priv->addr + I2SCON);
if (is_secondary(i2s))
active &= CON_TXSDMA_ACTIVE;
if (!i2s)
return false;
- active = readl(i2s->addr + I2SCON) & CON_RXDMA_ACTIVE;
+ active = readl(i2s->priv->addr + I2SCON) & CON_RXDMA_ACTIVE;
return active ? true : false;
}
/* Read RCLK of I2S (in multiples of LRCLK) */
static inline unsigned get_rfs(struct i2s_dai *i2s)
{
+ struct samsung_i2s_priv *priv = i2s->priv;
u32 rfs;
- rfs = readl(i2s->addr + I2SMOD) >> i2s->variant_regs->rfs_off;
+
+ rfs = readl(priv->addr + I2SMOD) >> i2s->variant_regs->rfs_off;
rfs &= i2s->variant_regs->rfs_mask;
switch (rfs) {
/* Write RCLK of I2S (in multiples of LRCLK) */
static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
{
- u32 mod = readl(i2s->addr + I2SMOD);
+ struct samsung_i2s_priv *priv = i2s->priv;
+ u32 mod = readl(priv->addr + I2SMOD);
int rfs_shift = i2s->variant_regs->rfs_off;
mod &= ~(i2s->variant_regs->rfs_mask << rfs_shift);
break;
}
- writel(mod, i2s->addr + I2SMOD);
+ writel(mod, priv->addr + I2SMOD);
}
/* Read Bit-Clock of I2S (in multiples of LRCLK) */
static inline unsigned get_bfs(struct i2s_dai *i2s)
{
+ struct samsung_i2s_priv *priv = i2s->priv;
u32 bfs;
- bfs = readl(i2s->addr + I2SMOD) >> i2s->variant_regs->bfs_off;
+
+ bfs = readl(priv->addr + I2SMOD) >> i2s->variant_regs->bfs_off;
bfs &= i2s->variant_regs->bfs_mask;
switch (bfs) {
/* Write Bit-Clock of I2S (in multiples of LRCLK) */
static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
{
- u32 mod = readl(i2s->addr + I2SMOD);
+ struct samsung_i2s_priv *priv = i2s->priv;
+ u32 mod = readl(priv->addr + I2SMOD);
int tdm = i2s->quirks & QUIRK_SUPPORTS_TDM;
int bfs_shift = i2s->variant_regs->bfs_off;
return;
}
- writel(mod, i2s->addr + I2SMOD);
+ writel(mod, priv->addr + I2SMOD);
}
/* Sample-Size */
static inline int get_blc(struct i2s_dai *i2s)
{
- int blc = readl(i2s->addr + I2SMOD);
+ int blc = readl(i2s->priv->addr + I2SMOD);
blc = (blc >> 13) & 0x3;
/* TX Channel Control */
static void i2s_txctrl(struct i2s_dai *i2s, int on)
{
- void __iomem *addr = i2s->addr;
+ struct samsung_i2s_priv *priv = i2s->priv;
+ void __iomem *addr = priv->addr;
int txr_off = i2s->variant_regs->txr_off;
u32 con = readl(addr + I2SCON);
u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
/* RX Channel Control */
static void i2s_rxctrl(struct i2s_dai *i2s, int on)
{
- void __iomem *addr = i2s->addr;
+ struct samsung_i2s_priv *priv = i2s->priv;
+ void __iomem *addr = priv->addr;
int txr_off = i2s->variant_regs->txr_off;
u32 con = readl(addr + I2SCON);
u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off);
return;
if (is_secondary(i2s))
- fic = i2s->addr + I2SFICS;
+ fic = i2s->priv->addr + I2SFICS;
else
- fic = i2s->addr + I2SFIC;
+ fic = i2s->priv->addr + I2SFIC;
/* Flush the FIFO */
writel(readl(fic) | flush, fic);
pm_runtime_get_sync(dai->dev);
spin_lock_irqsave(i2s->lock, flags);
- mod = readl(i2s->addr + I2SMOD);
+ mod = readl(priv->addr + I2SMOD);
spin_unlock_irqrestore(i2s->lock, flags);
switch (clk_id) {
}
spin_lock_irqsave(i2s->lock, flags);
- mod = readl(i2s->addr + I2SMOD);
+ mod = readl(priv->addr + I2SMOD);
mod = (mod & ~mask) | val;
- writel(mod, i2s->addr + I2SMOD);
+ writel(mod, priv->addr + I2SMOD);
spin_unlock_irqrestore(i2s->lock, flags);
done:
pm_runtime_put(dai->dev);
pm_runtime_get_sync(dai->dev);
spin_lock_irqsave(i2s->lock, flags);
- mod = readl(i2s->addr + I2SMOD);
+ mod = readl(priv->addr + I2SMOD);
/*
* Don't change the I2S mode if any controller is active on this
* channel.
mod &= ~(sdf_mask | lrp_rlow | mod_slave);
mod |= tmp;
- writel(mod, i2s->addr + I2SMOD);
+ writel(mod, priv->addr + I2SMOD);
spin_unlock_irqrestore(i2s->lock, flags);
pm_runtime_put(dai->dev);
}
spin_lock_irqsave(i2s->lock, flags);
- mod = readl(i2s->addr + I2SMOD);
+ mod = readl(priv->addr + I2SMOD);
mod = (mod & ~mask) | val;
- writel(mod, i2s->addr + I2SMOD);
+ writel(mod, priv->addr + I2SMOD);
spin_unlock_irqrestore(i2s->lock, flags);
snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
i2s->mode |= DAI_MANAGER;
if (!any_active(i2s) && (i2s->quirks & QUIRK_NEED_RSTCLR))
- writel(CON_RSTCLR, i2s->addr + I2SCON);
+ writel(CON_RSTCLR, i2s->priv->addr + I2SCON);
spin_unlock_irqrestore(&lock, flags);
if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
psr = priv->rclk_srcrate / i2s->frmclk / rfs;
- writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
+ writel(((psr - 1) << 8) | PSR_PSREN, priv->addr + I2SPSR);
dev_dbg(&i2s->pdev->dev,
"RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
priv->rclk_srcrate, psr, rfs, bfs);
static snd_pcm_sframes_t
i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
+ struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
struct i2s_dai *i2s = to_info(dai);
- u32 reg = readl(i2s->addr + I2SFIC);
+ u32 reg = readl(priv->addr + I2SFIC);
snd_pcm_sframes_t delay;
const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
delay = FIC_RXCOUNT(reg);
else if (is_secondary(i2s))
- delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS));
+ delay = FICS_TXCOUNT(readl(priv->addr + I2SFICS));
else
delay = (reg >> i2s_regs->ftx0cnt_off) & 0x7f;
static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
{
+ struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
struct i2s_dai *i2s = to_info(dai);
struct i2s_dai *other = get_other_dai(i2s);
unsigned long flags;
&i2s->dma_capture);
if (i2s->quirks & QUIRK_NEED_RSTCLR)
- writel(CON_RSTCLR, i2s->addr + I2SCON);
+ writel(CON_RSTCLR, priv->addr + I2SCON);
if (i2s->quirks & QUIRK_SUPPORTS_IDMA)
- idma_reg_addr_init(i2s->addr,
+ idma_reg_addr_init(priv->addr,
i2s->sec_dai->idma_playback.addr);
}
static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
{
+ struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai);
struct i2s_dai *i2s = to_info(dai);
unsigned long flags;
if (!is_secondary(i2s)) {
if (i2s->quirks & QUIRK_NEED_RSTCLR) {
spin_lock_irqsave(i2s->lock, flags);
- writel(0, i2s->addr + I2SCON);
+ writel(0, priv->addr + I2SCON);
spin_unlock_irqrestore(i2s->lock, flags);
}
}
static int i2s_runtime_suspend(struct device *dev)
{
struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
- struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
- priv->suspend_i2smod = readl(i2s->addr + I2SMOD);
- priv->suspend_i2scon = readl(i2s->addr + I2SCON);
- priv->suspend_i2spsr = readl(i2s->addr + I2SPSR);
+ priv->suspend_i2smod = readl(priv->addr + I2SMOD);
+ priv->suspend_i2scon = readl(priv->addr + I2SCON);
+ priv->suspend_i2spsr = readl(priv->addr + I2SPSR);
if (priv->op_clk)
clk_disable_unprepare(priv->op_clk);
static int i2s_runtime_resume(struct device *dev)
{
struct samsung_i2s_priv *priv = dev_get_drvdata(dev);
- struct i2s_dai *i2s = samsung_i2s_get_pri_dai(dev);
int ret;
ret = clk_prepare_enable(priv->clk);
}
}
- writel(priv->suspend_i2scon, i2s->addr + I2SCON);
- writel(priv->suspend_i2smod, i2s->addr + I2SMOD);
- writel(priv->suspend_i2spsr, i2s->addr + I2SPSR);
+ writel(priv->suspend_i2scon, priv->addr + I2SCON);
+ writel(priv->suspend_i2smod, priv->addr + I2SMOD);
+ writel(priv->suspend_i2spsr, priv->addr + I2SPSR);
return 0;
}
if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
/* Activate the prescaler */
- u32 val = readl(i2s->addr + I2SPSR);
- writel(val | PSR_PSREN, i2s->addr + I2SPSR);
+ u32 val = readl(priv->addr + I2SPSR);
+ writel(val | PSR_PSREN, priv->addr + I2SPSR);
priv->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev,
i2s_clk_name[CLK_I2S_RCLK_SRC], p_names,
ARRAY_SIZE(p_names),
CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
- i2s->addr + I2SMOD, reg_info->rclksrc_off,
+ priv->addr + I2SMOD, reg_info->rclksrc_off,
1, 0, i2s->lock);
priv->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
i2s_clk_name[CLK_I2S_RCLK_PSR],
i2s_clk_name[CLK_I2S_RCLK_SRC],
CLK_SET_RATE_PARENT,
- i2s->addr + I2SPSR, 8, 6, 0, i2s->lock);
+ priv->addr + I2SPSR, 8, 6, 0, i2s->lock);
p_names[0] = i2s_clk_name[CLK_I2S_RCLK_PSR];
priv->clk_data.clk_num = 2;
priv->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev,
i2s_clk_name[CLK_I2S_CDCLK], p_names[0],
CLK_SET_RATE_PARENT,
- i2s->addr + I2SMOD, reg_info->cdclkcon_off,
+ priv->addr + I2SMOD, reg_info->cdclkcon_off,
CLK_GATE_SET_TO_DISABLE, i2s->lock);
priv->clk_data.clk_num += 1;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- pri_dai->addr = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(pri_dai->addr))
- return PTR_ERR(pri_dai->addr);
+ priv->addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->addr))
+ return PTR_ERR(priv->addr);
regs_base = res->start;
}
sec_dai->dma_playback.addr_width = 4;
- sec_dai->addr = pri_dai->addr;
sec_dai->quirks = quirks;
sec_dai->idma_playback.addr = idma_addr;
sec_dai->pri_dai = pri_dai;