Merge remote-tracking branch 'asoc/topic/mxs' into asoc-next
This commit is contained in:
commit
10abe843d5
|
@ -169,6 +169,13 @@ struct snd_soc_dai_ops {
|
||||||
struct snd_soc_dai *);
|
struct snd_soc_dai *);
|
||||||
int (*prepare)(struct snd_pcm_substream *,
|
int (*prepare)(struct snd_pcm_substream *,
|
||||||
struct snd_soc_dai *);
|
struct snd_soc_dai *);
|
||||||
|
/*
|
||||||
|
* NOTE: Commands passed to the trigger function are not necessarily
|
||||||
|
* compatible with the current state of the dai. For example this
|
||||||
|
* sequence of commands is possible: START STOP STOP.
|
||||||
|
* So do not unconditionally use refcounting functions in the trigger
|
||||||
|
* function, e.g. clk_enable/disable.
|
||||||
|
*/
|
||||||
int (*trigger)(struct snd_pcm_substream *, int,
|
int (*trigger)(struct snd_pcm_substream *, int,
|
||||||
struct snd_soc_dai *);
|
struct snd_soc_dai *);
|
||||||
int (*bespoke_trigger)(struct snd_pcm_substream *, int,
|
int (*bespoke_trigger)(struct snd_pcm_substream *, int,
|
||||||
|
|
|
@ -494,6 +494,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
|
struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
|
||||||
struct mxs_saif *master_saif;
|
struct mxs_saif *master_saif;
|
||||||
u32 delay;
|
u32 delay;
|
||||||
|
int ret;
|
||||||
|
|
||||||
master_saif = mxs_saif_get_master(saif);
|
master_saif = mxs_saif_get_master(saif);
|
||||||
if (!master_saif)
|
if (!master_saif)
|
||||||
|
@ -503,23 +504,37 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
case SNDRV_PCM_TRIGGER_RESUME:
|
case SNDRV_PCM_TRIGGER_RESUME:
|
||||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||||
|
if (saif->state == MXS_SAIF_STATE_RUNNING)
|
||||||
|
return 0;
|
||||||
|
|
||||||
dev_dbg(cpu_dai->dev, "start\n");
|
dev_dbg(cpu_dai->dev, "start\n");
|
||||||
|
|
||||||
clk_enable(master_saif->clk);
|
ret = clk_enable(master_saif->clk);
|
||||||
if (!master_saif->mclk_in_use)
|
if (ret) {
|
||||||
__raw_writel(BM_SAIF_CTRL_RUN,
|
dev_err(saif->dev, "Failed to enable master clock\n");
|
||||||
master_saif->base + SAIF_CTRL + MXS_SET_ADDR);
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the saif's master is not himself, we also need to enable
|
* If the saif's master is not himself, we also need to enable
|
||||||
* itself clk for its internal basic logic to work.
|
* itself clk for its internal basic logic to work.
|
||||||
*/
|
*/
|
||||||
if (saif != master_saif) {
|
if (saif != master_saif) {
|
||||||
clk_enable(saif->clk);
|
ret = clk_enable(saif->clk);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(saif->dev, "Failed to enable master clock\n");
|
||||||
|
clk_disable(master_saif->clk);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
__raw_writel(BM_SAIF_CTRL_RUN,
|
__raw_writel(BM_SAIF_CTRL_RUN,
|
||||||
saif->base + SAIF_CTRL + MXS_SET_ADDR);
|
saif->base + SAIF_CTRL + MXS_SET_ADDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!master_saif->mclk_in_use)
|
||||||
|
__raw_writel(BM_SAIF_CTRL_RUN,
|
||||||
|
master_saif->base + SAIF_CTRL + MXS_SET_ADDR);
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
/*
|
/*
|
||||||
* write data to saif data register to trigger
|
* write data to saif data register to trigger
|
||||||
|
@ -543,6 +558,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
master_saif->ongoing = 1;
|
master_saif->ongoing = 1;
|
||||||
|
saif->state = MXS_SAIF_STATE_RUNNING;
|
||||||
|
|
||||||
dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n",
|
dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n",
|
||||||
__raw_readl(saif->base + SAIF_CTRL),
|
__raw_readl(saif->base + SAIF_CTRL),
|
||||||
|
@ -555,6 +571,9 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||||
case SNDRV_PCM_TRIGGER_STOP:
|
case SNDRV_PCM_TRIGGER_STOP:
|
||||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||||
|
if (saif->state == MXS_SAIF_STATE_STOPPED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
dev_dbg(cpu_dai->dev, "stop\n");
|
dev_dbg(cpu_dai->dev, "stop\n");
|
||||||
|
|
||||||
/* wait a while for the current sample to complete */
|
/* wait a while for the current sample to complete */
|
||||||
|
@ -575,6 +594,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
master_saif->ongoing = 0;
|
master_saif->ongoing = 0;
|
||||||
|
saif->state = MXS_SAIF_STATE_STOPPED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -124,6 +124,11 @@ struct mxs_saif {
|
||||||
|
|
||||||
u32 fifo_underrun;
|
u32 fifo_underrun;
|
||||||
u32 fifo_overrun;
|
u32 fifo_overrun;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MXS_SAIF_STATE_STOPPED,
|
||||||
|
MXS_SAIF_STATE_RUNNING,
|
||||||
|
} state;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int mxs_saif_put_mclk(unsigned int saif_id);
|
extern int mxs_saif_put_mclk(unsigned int saif_id);
|
||||||
|
|
|
@ -122,14 +122,12 @@ static struct snd_soc_card mxs_sgtl5000 = {
|
||||||
.num_links = ARRAY_SIZE(mxs_sgtl5000_dai),
|
.num_links = ARRAY_SIZE(mxs_sgtl5000_dai),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mxs_sgtl5000_probe_dt(struct platform_device *pdev)
|
static int mxs_sgtl5000_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct snd_soc_card *card = &mxs_sgtl5000;
|
||||||
|
int ret, i;
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
struct device_node *saif_np[2], *codec_np;
|
struct device_node *saif_np[2], *codec_np;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!np)
|
|
||||||
return 1; /* no device tree */
|
|
||||||
|
|
||||||
saif_np[0] = of_parse_phandle(np, "saif-controllers", 0);
|
saif_np[0] = of_parse_phandle(np, "saif-controllers", 0);
|
||||||
saif_np[1] = of_parse_phandle(np, "saif-controllers", 1);
|
saif_np[1] = of_parse_phandle(np, "saif-controllers", 1);
|
||||||
|
@ -152,18 +150,6 @@ static int mxs_sgtl5000_probe_dt(struct platform_device *pdev)
|
||||||
of_node_put(saif_np[0]);
|
of_node_put(saif_np[0]);
|
||||||
of_node_put(saif_np[1]);
|
of_node_put(saif_np[1]);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mxs_sgtl5000_probe(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct snd_soc_card *card = &mxs_sgtl5000;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mxs_sgtl5000_probe_dt(pdev);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w).
|
* Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w).
|
||||||
* The Sgtl5000 sysclk is derived from saif0 mclk and it's range
|
* The Sgtl5000 sysclk is derived from saif0 mclk and it's range
|
||||||
|
|
Loading…
Reference in New Issue