aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound/soc/meson/axg-frddr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/meson/axg-frddr.c')
-rw-r--r--sound/soc/meson/axg-frddr.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/sound/soc/meson/axg-frddr.c b/sound/soc/meson/axg-frddr.c
index c3ae8ac30745..e70c8c34c7db 100644
--- a/sound/soc/meson/axg-frddr.c
+++ b/sound/soc/meson/axg-frddr.c
@@ -7,10 +7,12 @@
* This driver implements the frontend playback DAI of AXG and G12A based SoCs
*/
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/regmap.h>
#include <linux/module.h>
#include <linux/of_platform.h>
+#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
@@ -46,11 +48,28 @@ static int g12a_frddr_dai_prepare(struct snd_pcm_substream *substream,
return 0;
}
+static int axg_frddr_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
+ unsigned int period, depth, val;
+
+ period = params_period_bytes(params);
+
+ /* Trim the FIFO depth if the period is small to improve latency */
+ depth = min(period, fifo->depth);
+ val = (depth / AXG_FIFO_BURST) - 1;
+ regmap_update_bits(fifo->map, FIFO_CTRL1, CTRL1_FRDDR_DEPTH,
+ FIELD_PREP(CTRL1_FRDDR_DEPTH, val));
+
+ return 0;
+}
+
static int axg_frddr_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
- unsigned int val;
int ret;
/* Enable pclk to access registers and clock the fifo ip */
@@ -61,11 +80,6 @@ static int axg_frddr_dai_startup(struct snd_pcm_substream *substream,
/* Apply single buffer mode to the interface */
regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_FRDDR_PP_MODE, 0);
- /* Use all fifo depth */
- val = (fifo->depth / AXG_FIFO_BURST) - 1;
- regmap_update_bits(fifo->map, FIFO_CTRL1, CTRL1_FRDDR_DEPTH_MASK,
- CTRL1_FRDDR_DEPTH(val));
-
return 0;
}
@@ -84,8 +98,10 @@ static int axg_frddr_pcm_new(struct snd_soc_pcm_runtime *rtd,
}
static const struct snd_soc_dai_ops axg_frddr_ops = {
+ .hw_params = axg_frddr_dai_hw_params,
.startup = axg_frddr_dai_startup,
.shutdown = axg_frddr_dai_shutdown,
+ .pcm_new = axg_frddr_pcm_new,
};
static struct snd_soc_dai_driver axg_frddr_dai_drv = {
@@ -94,11 +110,12 @@ static struct snd_soc_dai_driver axg_frddr_dai_drv = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = AXG_FIFO_CH_MAX,
- .rates = AXG_FIFO_RATES,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ .rate_min = 5515,
+ .rate_max = 768000,
.formats = AXG_FIFO_FORMATS,
},
.ops = &axg_frddr_ops,
- .pcm_new = axg_frddr_pcm_new,
};
static const char * const axg_frddr_sel_texts[] = {
@@ -147,6 +164,7 @@ static const struct snd_soc_component_driver axg_frddr_component_drv = {
.hw_free = axg_fifo_pcm_hw_free,
.pointer = axg_fifo_pcm_pointer,
.trigger = axg_fifo_pcm_trigger,
+ .legacy_dai_naming = 1,
};
static const struct axg_fifo_match_data axg_frddr_match_data = {
@@ -157,8 +175,10 @@ static const struct axg_fifo_match_data axg_frddr_match_data = {
static const struct snd_soc_dai_ops g12a_frddr_ops = {
.prepare = g12a_frddr_dai_prepare,
+ .hw_params = axg_frddr_dai_hw_params,
.startup = axg_frddr_dai_startup,
.shutdown = axg_frddr_dai_shutdown,
+ .pcm_new = axg_frddr_pcm_new,
};
static struct snd_soc_dai_driver g12a_frddr_dai_drv = {
@@ -167,11 +187,12 @@ static struct snd_soc_dai_driver g12a_frddr_dai_drv = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = AXG_FIFO_CH_MAX,
- .rates = AXG_FIFO_RATES,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ .rate_min = 5515,
+ .rate_max = 768000,
.formats = AXG_FIFO_FORMATS,
},
.ops = &g12a_frddr_ops,
- .pcm_new = axg_frddr_pcm_new,
};
static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel1_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT,
@@ -271,6 +292,7 @@ static const struct snd_soc_component_driver g12a_frddr_component_drv = {
.hw_free = axg_fifo_pcm_hw_free,
.pointer = axg_fifo_pcm_pointer,
.trigger = axg_fifo_pcm_trigger,
+ .legacy_dai_naming = 1,
};
static const struct axg_fifo_match_data g12a_frddr_match_data = {
@@ -341,6 +363,7 @@ static const struct snd_soc_component_driver sm1_frddr_component_drv = {
.hw_free = axg_fifo_pcm_hw_free,
.pointer = axg_fifo_pcm_pointer,
.trigger = axg_fifo_pcm_trigger,
+ .legacy_dai_naming = 1,
};
static const struct axg_fifo_match_data sm1_frddr_match_data = {