Loading include/sound/soc-dai.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -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, Loading sound/soc/mxs/mxs-saif.c +25 −5 Original line number Original line Diff line number Diff line Loading @@ -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) Loading @@ -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 Loading @@ -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), Loading @@ -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 */ Loading @@ -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: Loading sound/soc/mxs/mxs-saif.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -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); Loading sound/soc/mxs/mxs-sgtl5000.c +3 −17 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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 Loading
include/sound/soc-dai.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -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, Loading
sound/soc/mxs/mxs-saif.c +25 −5 Original line number Original line Diff line number Diff line Loading @@ -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) Loading @@ -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 Loading @@ -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), Loading @@ -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 */ Loading @@ -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: Loading
sound/soc/mxs/mxs-saif.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -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); Loading
sound/soc/mxs/mxs-sgtl5000.c +3 −17 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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