aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-pcm.c')
-rw-r--r--sound/soc/soc-pcm.c99
1 files changed, 89 insertions, 10 deletions
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index ca36fd6746fc..5bd8270beea4 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -632,6 +632,33 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
632 return 0; 632 return 0;
633} 633}
634 634
635int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream, int cmd)
636{
637 struct snd_soc_pcm_runtime *rtd = substream->private_data;
638 struct snd_soc_platform *platform = rtd->platform;
639 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
640 struct snd_soc_dai *codec_dai = rtd->codec_dai;
641 int ret;
642
643 if (codec_dai->driver->ops->bespoke_trigger) {
644 ret = codec_dai->driver->ops->bespoke_trigger(substream, cmd, codec_dai);
645 if (ret < 0)
646 return ret;
647 }
648
649 if (platform->driver->bespoke_trigger) {
650 ret = platform->driver->bespoke_trigger(substream, cmd);
651 if (ret < 0)
652 return ret;
653 }
654
655 if (cpu_dai->driver->ops->bespoke_trigger) {
656 ret = cpu_dai->driver->ops->bespoke_trigger(substream, cmd, cpu_dai);
657 if (ret < 0)
658 return ret;
659 }
660 return 0;
661}
635/* 662/*
636 * soc level wrapper for pointer callback 663 * soc level wrapper for pointer callback
637 * If cpu_dai, codec_dai, platform driver has the delay callback, than 664 * If cpu_dai, codec_dai, platform driver has the delay callback, than
@@ -1507,6 +1534,18 @@ int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
1507 1534
1508 ret = soc_pcm_trigger(substream, cmd); 1535 ret = soc_pcm_trigger(substream, cmd);
1509 break; 1536 break;
1537 case SND_SOC_DPCM_TRIGGER_BESPOKE:
1538 /* bespoke trigger() - handles both FE and BEs */
1539
1540 dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd %d\n",
1541 fe->dai_link->name, cmd);
1542
1543 ret = soc_pcm_bespoke_trigger(substream, cmd);
1544 if (ret < 0) {
1545 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1546 goto out;
1547 }
1548 break;
1510 default: 1549 default:
1511 dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd, 1550 dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd,
1512 fe->dai_link->name); 1551 fe->dai_link->name);
@@ -1610,14 +1649,30 @@ out:
1610 1649
1611static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream) 1650static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
1612{ 1651{
1652 struct snd_pcm_substream *substream =
1653 snd_soc_dpcm_get_substream(fe, stream);
1654 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
1613 int err; 1655 int err;
1614 1656
1615 dev_dbg(fe->dev, "runtime %s close on FE %s\n", 1657 dev_dbg(fe->dev, "runtime %s close on FE %s\n",
1616 stream ? "capture" : "playback", fe->dai_link->name); 1658 stream ? "capture" : "playback", fe->dai_link->name);
1617 1659
1618 err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP); 1660 if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
1619 if (err < 0) 1661 /* call bespoke trigger - FE takes care of all BE triggers */
1620 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err); 1662 dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd stop\n",
1663 fe->dai_link->name);
1664
1665 err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP);
1666 if (err < 0)
1667 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err);
1668 } else {
1669 dev_dbg(fe->dev, "dpcm: trigger FE %s cmd stop\n",
1670 fe->dai_link->name);
1671
1672 err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP);
1673 if (err < 0)
1674 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err);
1675 }
1621 1676
1622 err = dpcm_be_dai_hw_free(fe, stream); 1677 err = dpcm_be_dai_hw_free(fe, stream);
1623 if (err < 0) 1678 if (err < 0)
@@ -1635,7 +1690,10 @@ static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
1635 1690
1636static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) 1691static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
1637{ 1692{
1693 struct snd_pcm_substream *substream =
1694 snd_soc_dpcm_get_substream(fe, stream);
1638 struct snd_soc_dpcm *dpcm; 1695 struct snd_soc_dpcm *dpcm;
1696 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
1639 int ret; 1697 int ret;
1640 1698
1641 dev_dbg(fe->dev, "runtime %s open on FE %s\n", 1699 dev_dbg(fe->dev, "runtime %s open on FE %s\n",
@@ -1682,14 +1740,26 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
1682 fe->dpcm[stream].state == SND_SOC_DPCM_STATE_STOP) 1740 fe->dpcm[stream].state == SND_SOC_DPCM_STATE_STOP)
1683 return 0; 1741 return 0;
1684 1742
1685 dev_dbg(fe->dev, "dpcm: trigger FE %s cmd start\n", 1743 if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
1686 fe->dai_link->name); 1744 /* call trigger on the frontend - FE takes care of all BE triggers */
1745 dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd start\n",
1746 fe->dai_link->name);
1687 1747
1688 ret = dpcm_be_dai_trigger(fe, stream, 1748 ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START);
1689 SNDRV_PCM_TRIGGER_START); 1749 if (ret < 0) {
1690 if (ret < 0) { 1750 dev_err(fe->dev,"dpcm: bespoke trigger FE failed %d\n", ret);
1691 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); 1751 goto hw_free;
1692 goto hw_free; 1752 }
1753 } else {
1754 dev_dbg(fe->dev, "dpcm: trigger FE %s cmd start\n",
1755 fe->dai_link->name);
1756
1757 ret = dpcm_be_dai_trigger(fe, stream,
1758 SNDRV_PCM_TRIGGER_START);
1759 if (ret < 0) {
1760 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1761 goto hw_free;
1762 }
1693 } 1763 }
1694 1764
1695 return 0; 1765 return 0;
@@ -2120,6 +2190,15 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
2120} 2190}
2121EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); 2191EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params);
2122 2192
2193int snd_soc_platform_trigger(struct snd_pcm_substream *substream,
2194 int cmd, struct snd_soc_platform *platform)
2195{
2196 if (platform->driver->ops->trigger)
2197 return platform->driver->ops->trigger(substream, cmd);
2198 return 0;
2199}
2200EXPORT_SYMBOL_GPL(snd_soc_platform_trigger);
2201
2123#ifdef CONFIG_DEBUG_FS 2202#ifdef CONFIG_DEBUG_FS
2124static char *dpcm_state_string(enum snd_soc_dpcm_state state) 2203static char *dpcm_state_string(enum snd_soc_dpcm_state state)
2125{ 2204{