diff options
Diffstat (limited to 'sound/soc/meson')
-rw-r--r-- | sound/soc/meson/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/meson/Makefile | 50 | ||||
-rw-r--r-- | sound/soc/meson/aiu-fifo-i2s.c | 2 | ||||
-rw-r--r-- | sound/soc/meson/aiu-fifo-spdif.c | 2 | ||||
-rw-r--r-- | sound/soc/meson/aiu-fifo.c | 2 | ||||
-rw-r--r-- | sound/soc/meson/aiu-fifo.h | 4 | ||||
-rw-r--r-- | sound/soc/meson/aiu.c | 2 | ||||
-rw-r--r-- | sound/soc/meson/axg-card.c | 23 | ||||
-rw-r--r-- | sound/soc/meson/axg-fifo.c | 27 | ||||
-rw-r--r-- | sound/soc/meson/axg-frddr.c | 4 | ||||
-rw-r--r-- | sound/soc/meson/axg-tdm-formatter.c | 40 | ||||
-rw-r--r-- | sound/soc/meson/axg-tdm-interface.c | 59 | ||||
-rw-r--r-- | sound/soc/meson/axg-tdm.h | 7 | ||||
-rw-r--r-- | sound/soc/meson/axg-toddr.c | 4 | ||||
-rw-r--r-- | sound/soc/meson/gx-card.c | 5 | ||||
-rw-r--r-- | sound/soc/meson/meson-card-utils.c | 10 | ||||
-rw-r--r-- | sound/soc/meson/t9015.c | 4 |
17 files changed, 155 insertions, 91 deletions
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig index b93ea33739f2..6458d5dc4902 100644 --- a/sound/soc/meson/Kconfig +++ b/sound/soc/meson/Kconfig @@ -99,6 +99,7 @@ config SND_MESON_AXG_PDM config SND_MESON_CARD_UTILS tristate + select SND_DYNAMIC_MINORS config SND_MESON_CODEC_GLUE tristate diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile index e446bc980481..24078e4396b0 100644 --- a/sound/soc/meson/Makefile +++ b/sound/soc/meson/Makefile @@ -1,30 +1,30 @@ # SPDX-License-Identifier: (GPL-2.0 OR MIT) -snd-soc-meson-aiu-objs := aiu.o -snd-soc-meson-aiu-objs += aiu-acodec-ctrl.o -snd-soc-meson-aiu-objs += aiu-codec-ctrl.o -snd-soc-meson-aiu-objs += aiu-encoder-i2s.o -snd-soc-meson-aiu-objs += aiu-encoder-spdif.o -snd-soc-meson-aiu-objs += aiu-fifo.o -snd-soc-meson-aiu-objs += aiu-fifo-i2s.o -snd-soc-meson-aiu-objs += aiu-fifo-spdif.o -snd-soc-meson-axg-fifo-objs := axg-fifo.o -snd-soc-meson-axg-frddr-objs := axg-frddr.o -snd-soc-meson-axg-toddr-objs := axg-toddr.o -snd-soc-meson-axg-tdm-formatter-objs := axg-tdm-formatter.o -snd-soc-meson-axg-tdm-interface-objs := axg-tdm-interface.o -snd-soc-meson-axg-tdmin-objs := axg-tdmin.o -snd-soc-meson-axg-tdmout-objs := axg-tdmout.o -snd-soc-meson-axg-sound-card-objs := axg-card.o -snd-soc-meson-axg-spdifin-objs := axg-spdifin.o -snd-soc-meson-axg-spdifout-objs := axg-spdifout.o -snd-soc-meson-axg-pdm-objs := axg-pdm.o -snd-soc-meson-card-utils-objs := meson-card-utils.o -snd-soc-meson-codec-glue-objs := meson-codec-glue.o -snd-soc-meson-gx-sound-card-objs := gx-card.o -snd-soc-meson-g12a-toacodec-objs := g12a-toacodec.o -snd-soc-meson-g12a-tohdmitx-objs := g12a-tohdmitx.o -snd-soc-meson-t9015-objs := t9015.o +snd-soc-meson-aiu-y := aiu.o +snd-soc-meson-aiu-y += aiu-acodec-ctrl.o +snd-soc-meson-aiu-y += aiu-codec-ctrl.o +snd-soc-meson-aiu-y += aiu-encoder-i2s.o +snd-soc-meson-aiu-y += aiu-encoder-spdif.o +snd-soc-meson-aiu-y += aiu-fifo.o +snd-soc-meson-aiu-y += aiu-fifo-i2s.o +snd-soc-meson-aiu-y += aiu-fifo-spdif.o +snd-soc-meson-axg-fifo-y := axg-fifo.o +snd-soc-meson-axg-frddr-y := axg-frddr.o +snd-soc-meson-axg-toddr-y := axg-toddr.o +snd-soc-meson-axg-tdm-formatter-y := axg-tdm-formatter.o +snd-soc-meson-axg-tdm-interface-y := axg-tdm-interface.o +snd-soc-meson-axg-tdmin-y := axg-tdmin.o +snd-soc-meson-axg-tdmout-y := axg-tdmout.o +snd-soc-meson-axg-sound-card-y := axg-card.o +snd-soc-meson-axg-spdifin-y := axg-spdifin.o +snd-soc-meson-axg-spdifout-y := axg-spdifout.o +snd-soc-meson-axg-pdm-y := axg-pdm.o +snd-soc-meson-card-utils-y := meson-card-utils.o +snd-soc-meson-codec-glue-y := meson-codec-glue.o +snd-soc-meson-gx-sound-card-y := gx-card.o +snd-soc-meson-g12a-toacodec-y := g12a-toacodec.o +snd-soc-meson-g12a-tohdmitx-y := g12a-tohdmitx.o +snd-soc-meson-t9015-y := t9015.o obj-$(CONFIG_SND_MESON_AIU) += snd-soc-meson-aiu.o obj-$(CONFIG_SND_MESON_AXG_FIFO) += snd-soc-meson-axg-fifo.o diff --git a/sound/soc/meson/aiu-fifo-i2s.c b/sound/soc/meson/aiu-fifo-i2s.c index 7d833500c799..eccbc16b293a 100644 --- a/sound/soc/meson/aiu-fifo-i2s.c +++ b/sound/soc/meson/aiu-fifo-i2s.c @@ -25,7 +25,7 @@ #define AIU_FIFO_I2S_BLOCK 256 -static struct snd_pcm_hardware fifo_i2s_pcm = { +static const struct snd_pcm_hardware fifo_i2s_pcm = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/soc/meson/aiu-fifo-spdif.c b/sound/soc/meson/aiu-fifo-spdif.c index fa91f3c53fa4..e0e00ec026dc 100644 --- a/sound/soc/meson/aiu-fifo-spdif.c +++ b/sound/soc/meson/aiu-fifo-spdif.c @@ -27,7 +27,7 @@ #define AIU_FIFO_SPDIF_BLOCK 8 -static struct snd_pcm_hardware fifo_spdif_pcm = { +static const struct snd_pcm_hardware fifo_spdif_pcm = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/soc/meson/aiu-fifo.c b/sound/soc/meson/aiu-fifo.c index 4041ff8e437f..b222bde1f61b 100644 --- a/sound/soc/meson/aiu-fifo.c +++ b/sound/soc/meson/aiu-fifo.c @@ -25,7 +25,7 @@ static struct snd_soc_dai *aiu_fifo_dai(struct snd_pcm_substream *ss) { - struct snd_soc_pcm_runtime *rtd = ss->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(ss); return snd_soc_rtd_to_cpu(rtd, 0); } diff --git a/sound/soc/meson/aiu-fifo.h b/sound/soc/meson/aiu-fifo.h index 42ce266677cc..b02cfcc4de7f 100644 --- a/sound/soc/meson/aiu-fifo.h +++ b/sound/soc/meson/aiu-fifo.h @@ -18,7 +18,7 @@ struct snd_pcm_hw_params; struct platform_device; struct aiu_fifo { - struct snd_pcm_hardware *pcm; + const struct snd_pcm_hardware *pcm; unsigned int mem_offset; unsigned int fifo_block; struct clk *pclk; @@ -38,8 +38,6 @@ int aiu_fifo_prepare(struct snd_pcm_substream *substream, int aiu_fifo_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai); -int aiu_fifo_hw_free(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai); int aiu_fifo_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai); void aiu_fifo_shutdown(struct snd_pcm_substream *substream, diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c index 5d1419ed7a62..f2890111c1d2 100644 --- a/sound/soc/meson/aiu.c +++ b/sound/soc/meson/aiu.c @@ -345,7 +345,7 @@ MODULE_DEVICE_TABLE(of, aiu_of_match); static struct platform_driver aiu_pdrv = { .probe = aiu_probe, - .remove_new = aiu_remove, + .remove = aiu_remove, .driver = { .name = "meson-aiu", .of_match_table = aiu_of_match, diff --git a/sound/soc/meson/axg-card.c b/sound/soc/meson/axg-card.c index 3180aa4d3a15..a2dfccb7990f 100644 --- a/sound/soc/meson/axg-card.c +++ b/sound/soc/meson/axg-card.c @@ -43,7 +43,7 @@ static int axg_card_tdm_be_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card); struct axg_dai_link_tdm_data *be = - (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num]; + (struct axg_dai_link_tdm_data *)priv->link_data[rtd->id]; return meson_card_i2s_set_sysclk(substream, params, be->mclk_fs); } @@ -56,7 +56,7 @@ static int axg_card_tdm_dai_init(struct snd_soc_pcm_runtime *rtd) { struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card); struct axg_dai_link_tdm_data *be = - (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num]; + (struct axg_dai_link_tdm_data *)priv->link_data[rtd->id]; struct snd_soc_dai *codec_dai; int ret, i; @@ -86,7 +86,7 @@ static int axg_card_tdm_dai_lb_init(struct snd_soc_pcm_runtime *rtd) { struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card); struct axg_dai_link_tdm_data *be = - (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num]; + (struct axg_dai_link_tdm_data *)priv->link_data[rtd->id]; int ret; /* The loopback rx_mask is the pad tx_mask */ @@ -104,7 +104,7 @@ static int axg_card_add_tdm_loopback(struct snd_soc_card *card, int *index) { struct meson_card *priv = snd_soc_card_get_drvdata(card); - struct snd_soc_dai_link *pad = &card->dai_link[*index]; + struct snd_soc_dai_link *pad; struct snd_soc_dai_link *lb; struct snd_soc_dai_link_component *dlc; int ret; @@ -114,6 +114,7 @@ static int axg_card_add_tdm_loopback(struct snd_soc_card *card, if (ret) return ret; + pad = &card->dai_link[*index]; lb = &card->dai_link[*index + 1]; lb->name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-lb", pad->name); @@ -132,7 +133,7 @@ static int axg_card_add_tdm_loopback(struct snd_soc_card *card, lb->stream_name = lb->name; lb->cpus->of_node = pad->cpus->of_node; lb->cpus->dai_name = "TDM Loopback"; - lb->dpcm_capture = 1; + lb->capture_only = 1; lb->no_pcm = 1; lb->ops = &axg_card_tdm_be_ops; lb->init = axg_card_tdm_dai_lb_init; @@ -176,7 +177,7 @@ static int axg_card_parse_cpu_tdm_slots(struct snd_soc_card *card, /* Disable playback is the interface has no tx slots */ if (!tx) - link->dpcm_playback = 0; + link->capture_only = 1; for (i = 0, rx = 0; i < AXG_TDM_NUM_LANES; i++) { snprintf(propname, 32, "dai-tdm-slot-rx-mask-%d", i); @@ -186,9 +187,9 @@ static int axg_card_parse_cpu_tdm_slots(struct snd_soc_card *card, /* Disable capture is the interface has no rx slots */ if (!rx) - link->dpcm_capture = 0; + link->playback_only = 1; - /* ... but the interface should at least have one of them */ + /* ... but the interface should at least have one direction */ if (!tx && !rx) { dev_err(card->dev, "tdm link has no cpu slots\n"); return -EINVAL; @@ -275,7 +276,7 @@ static int axg_card_parse_tdm(struct snd_soc_card *card, return ret; /* Add loopback if the pad dai has playback */ - if (link->dpcm_playback) { + if (!link->capture_only) { ret = axg_card_add_tdm_loopback(card, index); if (ret) return ret; @@ -318,6 +319,7 @@ static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np, dai_link->cpus = cpu; dai_link->num_cpus = 1; + dai_link->nonatomic = true; ret = meson_card_parse_dai(card, np, dai_link->cpus); if (ret) @@ -338,7 +340,6 @@ static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np, dai_link->num_c2c_params = 1; } else { dai_link->no_pcm = 1; - snd_soc_dai_link_set_capabilities(dai_link); if (axg_card_cpu_is_tdm_iface(dai_link->cpus->of_node)) ret = axg_card_parse_tdm(card, np, index); } @@ -360,7 +361,7 @@ MODULE_DEVICE_TABLE(of, axg_card_of_match); static struct platform_driver axg_card_pdrv = { .probe = meson_card_probe, - .remove_new = meson_card_remove, + .remove = meson_card_remove, .driver = { .name = "axg-sound-card", .of_match_table = axg_card_of_match, diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c index bebee0ca8e38..75909196b769 100644 --- a/sound/soc/meson/axg-fifo.c +++ b/sound/soc/meson/axg-fifo.c @@ -23,7 +23,7 @@ * These differences are handled in the respective DAI drivers */ -static struct snd_pcm_hardware axg_fifo_hw = { +static const struct snd_pcm_hardware axg_fifo_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -32,7 +32,7 @@ static struct snd_pcm_hardware axg_fifo_hw = { SNDRV_PCM_INFO_NO_PERIOD_WAKEUP), .formats = AXG_FIFO_FORMATS, .rate_min = 5512, - .rate_max = 384000, + .rate_max = 768000, .channels_min = 1, .channels_max = AXG_FIFO_CH_MAX, .period_bytes_min = AXG_FIFO_BURST, @@ -46,7 +46,7 @@ static struct snd_pcm_hardware axg_fifo_hw = { static struct snd_soc_dai *axg_fifo_dai(struct snd_pcm_substream *ss) { - struct snd_soc_pcm_runtime *rtd = ss->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(ss); return snd_soc_rtd_to_cpu(rtd, 0); } @@ -204,18 +204,19 @@ static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id) unsigned int status; regmap_read(fifo->map, FIFO_STATUS1, &status); - status = FIELD_GET(STATUS1_INT_STS, status); - if (status & FIFO_INT_COUNT_REPEAT) - snd_pcm_period_elapsed(ss); - else + axg_fifo_ack_irq(fifo, status); + + if (status & ~FIFO_INT_COUNT_REPEAT) dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n", status); - /* Ack irqs */ - axg_fifo_ack_irq(fifo, status); + if (status & FIFO_INT_COUNT_REPEAT) { + snd_pcm_period_elapsed(ss); + return IRQ_HANDLED; + } - return IRQ_RETVAL(status); + return IRQ_NONE; } int axg_fifo_pcm_open(struct snd_soc_component *component, @@ -243,8 +244,10 @@ int axg_fifo_pcm_open(struct snd_soc_component *component, if (ret) return ret; - ret = request_irq(fifo->irq, axg_fifo_pcm_irq_block, 0, - dev_name(dev), ss); + /* Use the threaded irq handler only with non-atomic links */ + ret = request_threaded_irq(fifo->irq, NULL, + axg_fifo_pcm_irq_block, + IRQF_ONESHOT, dev_name(dev), ss); if (ret) return ret; diff --git a/sound/soc/meson/axg-frddr.c b/sound/soc/meson/axg-frddr.c index e97d43ae7fd2..e70c8c34c7db 100644 --- a/sound/soc/meson/axg-frddr.c +++ b/sound/soc/meson/axg-frddr.c @@ -112,7 +112,7 @@ static struct snd_soc_dai_driver axg_frddr_dai_drv = { .channels_max = AXG_FIFO_CH_MAX, .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 5515, - .rate_max = 384000, + .rate_max = 768000, .formats = AXG_FIFO_FORMATS, }, .ops = &axg_frddr_ops, @@ -189,7 +189,7 @@ static struct snd_soc_dai_driver g12a_frddr_dai_drv = { .channels_max = AXG_FIFO_CH_MAX, .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 5515, - .rate_max = 384000, + .rate_max = 768000, .formats = AXG_FIFO_FORMATS, }, .ops = &g12a_frddr_ops, diff --git a/sound/soc/meson/axg-tdm-formatter.c b/sound/soc/meson/axg-tdm-formatter.c index 63333a2b0a9c..a6579efd3775 100644 --- a/sound/soc/meson/axg-tdm-formatter.c +++ b/sound/soc/meson/axg-tdm-formatter.c @@ -392,6 +392,46 @@ void axg_tdm_stream_free(struct axg_tdm_stream *ts) } EXPORT_SYMBOL_GPL(axg_tdm_stream_free); +int axg_tdm_stream_set_cont_clocks(struct axg_tdm_stream *ts, + unsigned int fmt) +{ + int ret = 0; + + if (fmt & SND_SOC_DAIFMT_CONT) { + /* Clock are already enabled - skipping */ + if (ts->clk_enabled) + return 0; + + ret = clk_prepare_enable(ts->iface->mclk); + if (ret) + return ret; + + ret = clk_prepare_enable(ts->iface->sclk); + if (ret) + goto err_sclk; + + ret = clk_prepare_enable(ts->iface->lrclk); + if (ret) + goto err_lrclk; + + ts->clk_enabled = true; + return 0; + } + + /* Clocks are already disabled - skipping */ + if (!ts->clk_enabled) + return 0; + + clk_disable_unprepare(ts->iface->lrclk); +err_lrclk: + clk_disable_unprepare(ts->iface->sclk); +err_sclk: + clk_disable_unprepare(ts->iface->mclk); + ts->clk_enabled = false; + return ret; +} +EXPORT_SYMBOL_GPL(axg_tdm_stream_set_cont_clocks); + MODULE_DESCRIPTION("Amlogic AXG TDM formatter driver"); MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c index bf708717635b..421b5d719fb3 100644 --- a/sound/soc/meson/axg-tdm-interface.c +++ b/sound/soc/meson/axg-tdm-interface.c @@ -309,6 +309,7 @@ static int axg_tdm_iface_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); + struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); int ret; switch (iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -346,7 +347,11 @@ static int axg_tdm_iface_hw_params(struct snd_pcm_substream *substream, return ret; } - return 0; + ret = axg_tdm_stream_set_cont_clocks(ts, iface->fmt); + if (ret) + dev_err(dai->dev, "failed to apply continuous clock setting\n"); + + return ret; } static int axg_tdm_iface_hw_free(struct snd_pcm_substream *substream, @@ -354,19 +359,32 @@ static int axg_tdm_iface_hw_free(struct snd_pcm_substream *substream, { struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); - /* Stop all attached formatters */ - axg_tdm_stream_stop(ts); - - return 0; + return axg_tdm_stream_set_cont_clocks(ts, 0); } -static int axg_tdm_iface_prepare(struct snd_pcm_substream *substream, +static int axg_tdm_iface_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) { - struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); + struct axg_tdm_stream *ts = + snd_soc_dai_get_dma_data(dai, substream); - /* Force all attached formatters to update */ - return axg_tdm_stream_reset(ts); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + axg_tdm_stream_start(ts); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_STOP: + axg_tdm_stream_stop(ts); + break; + default: + return -EINVAL; + } + + return 0; } static int axg_tdm_iface_remove_dai(struct snd_soc_dai *dai) @@ -412,8 +430,8 @@ static const struct snd_soc_dai_ops axg_tdm_iface_ops = { .set_fmt = axg_tdm_iface_set_fmt, .startup = axg_tdm_iface_startup, .hw_params = axg_tdm_iface_hw_params, - .prepare = axg_tdm_iface_prepare, .hw_free = axg_tdm_iface_hw_free, + .trigger = axg_tdm_iface_trigger, }; /* TDM Backend DAIs */ @@ -424,14 +442,18 @@ static const struct snd_soc_dai_driver axg_tdm_iface_dai_drv[] = { .stream_name = "Playback", .channels_min = 1, .channels_max = AXG_TDM_CHANNEL_MAX, - .rates = AXG_TDM_RATES, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 5512, + .rate_max = 768000, .formats = AXG_TDM_FORMATS, }, .capture = { .stream_name = "Capture", .channels_min = 1, .channels_max = AXG_TDM_CHANNEL_MAX, - .rates = AXG_TDM_RATES, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 5512, + .rate_max = 768000, .formats = AXG_TDM_FORMATS, }, .id = TDM_IFACE_PAD, @@ -443,7 +465,9 @@ static const struct snd_soc_dai_driver axg_tdm_iface_dai_drv[] = { .stream_name = "Loopback", .channels_min = 1, .channels_max = AXG_TDM_CHANNEL_MAX, - .rates = AXG_TDM_RATES, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 5512, + .rate_max = 768000, .formats = AXG_TDM_FORMATS, }, .id = TDM_IFACE_LOOPBACK, @@ -505,7 +529,6 @@ static int axg_tdm_iface_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct snd_soc_dai_driver *dai_drv; struct axg_tdm_iface *iface; - int i; iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL); if (!iface) @@ -517,15 +540,11 @@ static int axg_tdm_iface_probe(struct platform_device *pdev) * We'll change the number of channel provided by DAI stream, so dpcm * channel merge can be done properly */ - dai_drv = devm_kcalloc(dev, ARRAY_SIZE(axg_tdm_iface_dai_drv), - sizeof(*dai_drv), GFP_KERNEL); + dai_drv = devm_kmemdup_array(dev, axg_tdm_iface_dai_drv, ARRAY_SIZE(axg_tdm_iface_dai_drv), + sizeof(axg_tdm_iface_dai_drv[0]), GFP_KERNEL); if (!dai_drv) return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(axg_tdm_iface_dai_drv); i++) - memcpy(&dai_drv[i], &axg_tdm_iface_dai_drv[i], - sizeof(*dai_drv)); - /* Bit clock provided on the pad */ iface->sclk = devm_clk_get(dev, "sclk"); if (IS_ERR(iface->sclk)) diff --git a/sound/soc/meson/axg-tdm.h b/sound/soc/meson/axg-tdm.h index 42f7470b9a7f..acfcd48f8a00 100644 --- a/sound/soc/meson/axg-tdm.h +++ b/sound/soc/meson/axg-tdm.h @@ -15,8 +15,6 @@ #define AXG_TDM_NUM_LANES 4 #define AXG_TDM_CHANNEL_MAX 128 -#define AXG_TDM_RATES (SNDRV_PCM_RATE_5512 | \ - SNDRV_PCM_RATE_8000_384000) #define AXG_TDM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S20_LE | \ @@ -58,12 +56,17 @@ struct axg_tdm_stream { unsigned int physical_width; u32 *mask; bool ready; + + /* For continuous clock tracking */ + bool clk_enabled; }; struct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface); void axg_tdm_stream_free(struct axg_tdm_stream *ts); int axg_tdm_stream_start(struct axg_tdm_stream *ts); void axg_tdm_stream_stop(struct axg_tdm_stream *ts); +int axg_tdm_stream_set_cont_clocks(struct axg_tdm_stream *ts, + unsigned int fmt); static inline int axg_tdm_stream_reset(struct axg_tdm_stream *ts) { diff --git a/sound/soc/meson/axg-toddr.c b/sound/soc/meson/axg-toddr.c index e03a6e21c1c6..03512da4092b 100644 --- a/sound/soc/meson/axg-toddr.c +++ b/sound/soc/meson/axg-toddr.c @@ -131,7 +131,7 @@ static struct snd_soc_dai_driver axg_toddr_dai_drv = { .channels_max = AXG_FIFO_CH_MAX, .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 5515, - .rate_max = 384000, + .rate_max = 768000, .formats = AXG_FIFO_FORMATS, }, .ops = &axg_toddr_ops, @@ -228,7 +228,7 @@ static struct snd_soc_dai_driver g12a_toddr_dai_drv = { .channels_max = AXG_FIFO_CH_MAX, .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 5515, - .rate_max = 384000, + .rate_max = 768000, .formats = AXG_FIFO_FORMATS, }, .ops = &g12a_toddr_ops, diff --git a/sound/soc/meson/gx-card.c b/sound/soc/meson/gx-card.c index f1539e542638..b408cc2bbc91 100644 --- a/sound/soc/meson/gx-card.c +++ b/sound/soc/meson/gx-card.c @@ -32,7 +32,7 @@ static int gx_card_i2s_be_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card); struct gx_dai_link_i2s_data *be = - (struct gx_dai_link_i2s_data *)priv->link_data[rtd->num]; + (struct gx_dai_link_i2s_data *)priv->link_data[rtd->id]; return meson_card_i2s_set_sysclk(substream, params, be->mclk_fs); } @@ -107,7 +107,6 @@ static int gx_card_add_link(struct snd_soc_card *card, struct device_node *np, dai_link->num_c2c_params = 1; } else { dai_link->no_pcm = 1; - snd_soc_dai_link_set_capabilities(dai_link); /* Check if the cpu is the i2s encoder and parse i2s data */ if (gx_card_cpu_identify(dai_link->cpus, "I2S Encoder")) ret = gx_card_parse_i2s(card, np, index); @@ -130,7 +129,7 @@ MODULE_DEVICE_TABLE(of, gx_card_of_match); static struct platform_driver gx_card_pdrv = { .probe = meson_card_probe, - .remove_new = meson_card_remove, + .remove = meson_card_remove, .driver = { .name = "gx-sound-card", .of_match_table = gx_card_of_match, diff --git a/sound/soc/meson/meson-card-utils.c b/sound/soc/meson/meson-card-utils.c index ed6c7e2f609c..68531183fb60 100644 --- a/sound/soc/meson/meson-card-utils.c +++ b/sound/soc/meson/meson-card-utils.c @@ -119,10 +119,10 @@ unsigned int meson_card_parse_daifmt(struct device_node *node, /* If no master is provided, default to cpu master */ if (!bitclkmaster || bitclkmaster == cpu_node) { daifmt |= (!framemaster || framemaster == cpu_node) ? - SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBS_CFM; + SND_SOC_DAIFMT_CBC_CFC : SND_SOC_DAIFMT_CBC_CFP; } else { daifmt |= (!framemaster || framemaster == cpu_node) ? - SND_SOC_DAIFMT_CBM_CFS : SND_SOC_DAIFMT_CBM_CFM; + SND_SOC_DAIFMT_CBP_CFC : SND_SOC_DAIFMT_CBP_CFP; } of_node_put(bitclkmaster); @@ -186,9 +186,9 @@ int meson_card_set_fe_link(struct snd_soc_card *card, link->dpcm_merged_rate = 1; if (is_playback) - link->dpcm_playback = 1; + link->playback_only = 1; else - link->dpcm_capture = 1; + link->capture_only = 1; return meson_card_set_link_name(card, link, node, "fe"); } @@ -231,7 +231,7 @@ static int meson_card_parse_of_optional(struct snd_soc_card *card, const char *p)) { /* If property is not provided, don't fail ... */ - if (!of_property_read_bool(card->dev->of_node, propname)) + if (!of_property_present(card->dev->of_node, propname)) return 0; /* ... but do fail if it is provided and the parsing fails */ diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c index 571f65788c59..a80e9c9d6288 100644 --- a/sound/soc/meson/t9015.c +++ b/sound/soc/meson/t9015.c @@ -57,11 +57,11 @@ static int t9015_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int val; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: val = I2S_MODE; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: val = 0; break; |