summaryrefslogtreecommitdiff
path: root/sound/soc/meson
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/meson')
-rw-r--r--sound/soc/meson/axg-fifo.c34
-rw-r--r--sound/soc/meson/axg-fifo.h2
-rw-r--r--sound/soc/meson/axg-frddr.c143
-rw-r--r--sound/soc/meson/axg-tdm-formatter.c6
-rw-r--r--sound/soc/meson/axg-tdm-formatter.h11
-rw-r--r--sound/soc/meson/axg-tdmin.c16
-rw-r--r--sound/soc/meson/axg-tdmout.c29
-rw-r--r--sound/soc/meson/axg-toddr.c53
8 files changed, 274 insertions, 20 deletions
diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c
index 75e5e480fda2..01c1c7db2510 100644
--- a/sound/soc/meson/axg-fifo.c
+++ b/sound/soc/meson/axg-fifo.c
@@ -19,7 +19,7 @@
* This file implements the platform operations common to the playback and
* capture frontend DAI. The logic behind this two types of fifo is very
* similar but some difference exist.
- * These differences the respective DAI drivers
+ * These differences are handled in the respective DAI drivers
*/
static struct snd_pcm_hardware axg_fifo_hw = {
@@ -133,6 +133,23 @@ static int axg_fifo_pcm_hw_params(struct snd_pcm_substream *ss,
return 0;
}
+static int g12a_fifo_pcm_hw_params(struct snd_pcm_substream *ss,
+ struct snd_pcm_hw_params *params)
+{
+ struct axg_fifo *fifo = axg_fifo_data(ss);
+ struct snd_pcm_runtime *runtime = ss->runtime;
+ int ret;
+
+ ret = axg_fifo_pcm_hw_params(ss, params);
+ if (ret)
+ return ret;
+
+ /* Set the initial memory address of the DMA */
+ regmap_write(fifo->map, FIFO_INIT_ADDR, runtime->dma_addr);
+
+ return 0;
+}
+
static int axg_fifo_pcm_hw_free(struct snd_pcm_substream *ss)
{
struct axg_fifo *fifo = axg_fifo_data(ss);
@@ -262,6 +279,17 @@ const struct snd_pcm_ops axg_fifo_pcm_ops = {
};
EXPORT_SYMBOL_GPL(axg_fifo_pcm_ops);
+const struct snd_pcm_ops g12a_fifo_pcm_ops = {
+ .open = axg_fifo_pcm_open,
+ .close = axg_fifo_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = g12a_fifo_pcm_hw_params,
+ .hw_free = axg_fifo_pcm_hw_free,
+ .pointer = axg_fifo_pcm_pointer,
+ .trigger = axg_fifo_pcm_trigger,
+};
+EXPORT_SYMBOL_GPL(g12a_fifo_pcm_ops);
+
int axg_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, unsigned int type)
{
struct snd_card *card = rtd->card->snd_card;
@@ -278,7 +306,7 @@ static const struct regmap_config axg_fifo_regmap_cfg = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
- .max_register = FIFO_STATUS2,
+ .max_register = FIFO_INIT_ADDR,
};
int axg_fifo_probe(struct platform_device *pdev)
@@ -339,6 +367,6 @@ int axg_fifo_probe(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(axg_fifo_probe);
-MODULE_DESCRIPTION("Amlogic AXG fifo driver");
+MODULE_DESCRIPTION("Amlogic AXG/G12A fifo driver");
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/meson/axg-fifo.h b/sound/soc/meson/axg-fifo.h
index d9f516cfbeda..5caf81241dfe 100644
--- a/sound/soc/meson/axg-fifo.h
+++ b/sound/soc/meson/axg-fifo.h
@@ -60,6 +60,7 @@ struct snd_soc_pcm_runtime;
#define FIFO_STATUS1 0x14
#define STATUS1_INT_STS(x) ((x) << 0)
#define FIFO_STATUS2 0x18
+#define FIFO_INIT_ADDR 0x24
struct axg_fifo {
struct regmap *map;
@@ -74,6 +75,7 @@ struct axg_fifo_match_data {
};
extern const struct snd_pcm_ops axg_fifo_pcm_ops;
+extern const struct snd_pcm_ops g12a_fifo_pcm_ops;
int axg_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, unsigned int type);
int axg_fifo_probe(struct platform_device *pdev);
diff --git a/sound/soc/meson/axg-frddr.c b/sound/soc/meson/axg-frddr.c
index a6f6f6a2eca8..2b8807737b2b 100644
--- a/sound/soc/meson/axg-frddr.c
+++ b/sound/soc/meson/axg-frddr.c
@@ -3,7 +3,9 @@
// Copyright (c) 2018 BayLibre, SAS.
// Author: Jerome Brunet <jbrunet@baylibre.com>
-/* This driver implements the frontend playback DAI of AXG based SoCs */
+/*
+ * This driver implements the frontend playback DAI of AXG and G12A based SoCs
+ */
#include <linux/clk.h>
#include <linux/regmap.h>
@@ -14,7 +16,29 @@
#include "axg-fifo.h"
-#define CTRL0_FRDDR_PP_MODE BIT(30)
+#define CTRL0_FRDDR_PP_MODE BIT(30)
+#define CTRL0_SEL1_EN_SHIFT 3
+#define CTRL0_SEL2_SHIFT 4
+#define CTRL0_SEL2_EN_SHIFT 7
+#define CTRL0_SEL3_SHIFT 8
+#define CTRL0_SEL3_EN_SHIFT 11
+#define CTRL1_FRDDR_FORCE_FINISH BIT(12)
+
+static int g12a_frddr_dai_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
+
+ /* Reset the read pointer to the FIFO_INIT_ADDR */
+ regmap_update_bits(fifo->map, FIFO_CTRL1,
+ CTRL1_FRDDR_FORCE_FINISH, 0);
+ regmap_update_bits(fifo->map, FIFO_CTRL1,
+ CTRL1_FRDDR_FORCE_FINISH, CTRL1_FRDDR_FORCE_FINISH);
+ regmap_update_bits(fifo->map, FIFO_CTRL1,
+ CTRL1_FRDDR_FORCE_FINISH, 0);
+
+ return 0;
+}
static int axg_frddr_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
@@ -119,10 +143,123 @@ static const struct axg_fifo_match_data axg_frddr_match_data = {
.dai_drv = &axg_frddr_dai_drv
};
+static const struct snd_soc_dai_ops g12a_frddr_ops = {
+ .prepare = g12a_frddr_dai_prepare,
+ .startup = axg_frddr_dai_startup,
+ .shutdown = axg_frddr_dai_shutdown,
+};
+
+static struct snd_soc_dai_driver g12a_frddr_dai_drv = {
+ .name = "FRDDR",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = AXG_FIFO_CH_MAX,
+ .rates = AXG_FIFO_RATES,
+ .formats = AXG_FIFO_FORMATS,
+ },
+ .ops = &g12a_frddr_ops,
+ .pcm_new = axg_frddr_pcm_new,
+};
+
+static const char * const g12a_frddr_sel_texts[] = {
+ "OUT 0", "OUT 1", "OUT 2", "OUT 3", "OUT 4",
+};
+
+static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel1_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT,
+ g12a_frddr_sel_texts);
+static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel2_enum, FIFO_CTRL0, CTRL0_SEL2_SHIFT,
+ g12a_frddr_sel_texts);
+static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel3_enum, FIFO_CTRL0, CTRL0_SEL3_SHIFT,
+ g12a_frddr_sel_texts);
+
+static const struct snd_kcontrol_new g12a_frddr_out1_demux =
+ SOC_DAPM_ENUM("Output Src 1", g12a_frddr_sel1_enum);
+static const struct snd_kcontrol_new g12a_frddr_out2_demux =
+ SOC_DAPM_ENUM("Output Src 2", g12a_frddr_sel2_enum);
+static const struct snd_kcontrol_new g12a_frddr_out3_demux =
+ SOC_DAPM_ENUM("Output Src 3", g12a_frddr_sel3_enum);
+
+static const struct snd_kcontrol_new g12a_frddr_out1_enable =
+ SOC_DAPM_SINGLE_AUTODISABLE("Switch", FIFO_CTRL0,
+ CTRL0_SEL1_EN_SHIFT, 1, 0);
+static const struct snd_kcontrol_new g12a_frddr_out2_enable =
+ SOC_DAPM_SINGLE_AUTODISABLE("Switch", FIFO_CTRL0,
+ CTRL0_SEL2_EN_SHIFT, 1, 0);
+static const struct snd_kcontrol_new g12a_frddr_out3_enable =
+ SOC_DAPM_SINGLE_AUTODISABLE("Switch", FIFO_CTRL0,
+ CTRL0_SEL3_EN_SHIFT, 1, 0);
+
+static const struct snd_soc_dapm_widget g12a_frddr_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_OUT("SRC 1", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SRC 2", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SRC 3", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_SWITCH("SRC 1 EN", SND_SOC_NOPM, 0, 0,
+ &g12a_frddr_out1_enable),
+ SND_SOC_DAPM_SWITCH("SRC 2 EN", SND_SOC_NOPM, 0, 0,
+ &g12a_frddr_out2_enable),
+ SND_SOC_DAPM_SWITCH("SRC 3 EN", SND_SOC_NOPM, 0, 0,
+ &g12a_frddr_out3_enable),
+ SND_SOC_DAPM_DEMUX("SINK 1 SEL", SND_SOC_NOPM, 0, 0,
+ &g12a_frddr_out1_demux),
+ SND_SOC_DAPM_DEMUX("SINK 2 SEL", SND_SOC_NOPM, 0, 0,
+ &g12a_frddr_out2_demux),
+ SND_SOC_DAPM_DEMUX("SINK 3 SEL", SND_SOC_NOPM, 0, 0,
+ &g12a_frddr_out3_demux),
+ SND_SOC_DAPM_AIF_OUT("OUT 0", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("OUT 1", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("OUT 4", NULL, 0, SND_SOC_NOPM, 0, 0),
+};
+
+static const struct snd_soc_dapm_route g12a_frddr_dapm_routes[] = {
+ { "SRC 1", NULL, "Playback" },
+ { "SRC 2", NULL, "Playback" },
+ { "SRC 3", NULL, "Playback" },
+ { "SRC 1 EN", "Switch", "SRC 1" },
+ { "SRC 2 EN", "Switch", "SRC 2" },
+ { "SRC 3 EN", "Switch", "SRC 3" },
+ { "SINK 1 SEL", NULL, "SRC 1 EN" },
+ { "SINK 2 SEL", NULL, "SRC 2 EN" },
+ { "SINK 3 SEL", NULL, "SRC 3 EN" },
+ { "OUT 0", "OUT 0", "SINK 1 SEL" },
+ { "OUT 1", "OUT 1", "SINK 1 SEL" },
+ { "OUT 2", "OUT 2", "SINK 1 SEL" },
+ { "OUT 3", "OUT 3", "SINK 1 SEL" },
+ { "OUT 4", "OUT 4", "SINK 1 SEL" },
+ { "OUT 0", "OUT 0", "SINK 2 SEL" },
+ { "OUT 1", "OUT 1", "SINK 2 SEL" },
+ { "OUT 2", "OUT 2", "SINK 2 SEL" },
+ { "OUT 3", "OUT 3", "SINK 2 SEL" },
+ { "OUT 4", "OUT 4", "SINK 2 SEL" },
+ { "OUT 0", "OUT 0", "SINK 3 SEL" },
+ { "OUT 1", "OUT 1", "SINK 3 SEL" },
+ { "OUT 2", "OUT 2", "SINK 3 SEL" },
+ { "OUT 3", "OUT 3", "SINK 3 SEL" },
+ { "OUT 4", "OUT 4", "SINK 3 SEL" },
+};
+
+static const struct snd_soc_component_driver g12a_frddr_component_drv = {
+ .dapm_widgets = g12a_frddr_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(g12a_frddr_dapm_widgets),
+ .dapm_routes = g12a_frddr_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(g12a_frddr_dapm_routes),
+ .ops = &g12a_fifo_pcm_ops
+};
+
+static const struct axg_fifo_match_data g12a_frddr_match_data = {
+ .component_drv = &g12a_frddr_component_drv,
+ .dai_drv = &g12a_frddr_dai_drv
+};
+
static const struct of_device_id axg_frddr_of_match[] = {
{
.compatible = "amlogic,axg-frddr",
.data = &axg_frddr_match_data,
+ }, {
+ .compatible = "amlogic,g12a-frddr",
+ .data = &g12a_frddr_match_data,
}, {}
};
MODULE_DEVICE_TABLE(of, axg_frddr_of_match);
@@ -136,6 +273,6 @@ static struct platform_driver axg_frddr_pdrv = {
};
module_platform_driver(axg_frddr_pdrv);
-MODULE_DESCRIPTION("Amlogic AXG playback fifo driver");
+MODULE_DESCRIPTION("Amlogic AXG/G12A playback fifo driver");
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/meson/axg-tdm-formatter.c b/sound/soc/meson/axg-tdm-formatter.c
index 43e390f9358a..0c6cce5c5773 100644
--- a/sound/soc/meson/axg-tdm-formatter.c
+++ b/sound/soc/meson/axg-tdm-formatter.c
@@ -68,7 +68,7 @@ EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks);
static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter)
{
struct axg_tdm_stream *ts = formatter->stream;
- bool invert = formatter->drv->invert_sclk;
+ bool invert = formatter->drv->quirks->invert_sclk;
int ret;
/* Do nothing if the formatter is already enabled */
@@ -85,7 +85,9 @@ static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter)
return ret;
/* Setup the stream parameter in the formatter */
- ret = formatter->drv->ops->prepare(formatter->map, formatter->stream);
+ ret = formatter->drv->ops->prepare(formatter->map,
+ formatter->drv->quirks,
+ formatter->stream);
if (ret)
return ret;
diff --git a/sound/soc/meson/axg-tdm-formatter.h b/sound/soc/meson/axg-tdm-formatter.h
index cf947caf3cb1..9ef98e955cb2 100644
--- a/sound/soc/meson/axg-tdm-formatter.h
+++ b/sound/soc/meson/axg-tdm-formatter.h
@@ -14,18 +14,25 @@ struct regmap;
struct snd_soc_dapm_widget;
struct snd_kcontrol;
+struct axg_tdm_formatter_hw {
+ unsigned int skew_offset;
+ bool invert_sclk;
+};
+
struct axg_tdm_formatter_ops {
struct axg_tdm_stream *(*get_stream)(struct snd_soc_dapm_widget *w);
void (*enable)(struct regmap *map);
void (*disable)(struct regmap *map);
- int (*prepare)(struct regmap *map, struct axg_tdm_stream *ts);
+ int (*prepare)(struct regmap *map,
+ const struct axg_tdm_formatter_hw *quirks,
+ struct axg_tdm_stream *ts);
};
struct axg_tdm_formatter_driver {
const struct snd_soc_component_driver *component_drv;
const struct regmap_config *regmap_cfg;
const struct axg_tdm_formatter_ops *ops;
- bool invert_sclk;
+ const struct axg_tdm_formatter_hw *quirks;
};
int axg_tdm_formatter_set_channel_masks(struct regmap *map,
diff --git a/sound/soc/meson/axg-tdmin.c b/sound/soc/meson/axg-tdmin.c
index bbac44c81688..a790f925a4ef 100644
--- a/sound/soc/meson/axg-tdmin.c
+++ b/sound/soc/meson/axg-tdmin.c
@@ -107,21 +107,22 @@ static void axg_tdmin_disable(struct regmap *map)
regmap_update_bits(map, TDMIN_CTRL, TDMIN_CTRL_ENABLE, 0);
}
-static int axg_tdmin_prepare(struct regmap *map, struct axg_tdm_stream *ts)
+static int axg_tdmin_prepare(struct regmap *map,
+ const struct axg_tdm_formatter_hw *quirks,
+ struct axg_tdm_stream *ts)
{
- unsigned int val = 0;
+ unsigned int val, skew = quirks->skew_offset;
/* Set stream skew */
switch (ts->iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
case SND_SOC_DAIFMT_DSP_A:
- val |= TDMIN_CTRL_IN_BIT_SKEW(3);
+ skew += 1;
break;
case SND_SOC_DAIFMT_LEFT_J:
case SND_SOC_DAIFMT_RIGHT_J:
case SND_SOC_DAIFMT_DSP_B:
- val = TDMIN_CTRL_IN_BIT_SKEW(2);
break;
default:
@@ -130,6 +131,8 @@ static int axg_tdmin_prepare(struct regmap *map, struct axg_tdm_stream *ts)
return -EINVAL;
}
+ val = TDMIN_CTRL_IN_BIT_SKEW(skew);
+
/* Set stream format mode */
switch (ts->iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
@@ -204,7 +207,10 @@ static const struct axg_tdm_formatter_driver axg_tdmin_drv = {
.component_drv = &axg_tdmin_component_drv,
.regmap_cfg = &axg_tdmin_regmap_cfg,
.ops = &axg_tdmin_ops,
- .invert_sclk = false,
+ .quirks = &(const struct axg_tdm_formatter_hw) {
+ .invert_sclk = false,
+ .skew_offset = 2,
+ },
};
static const struct of_device_id axg_tdmin_of_match[] = {
diff --git a/sound/soc/meson/axg-tdmout.c b/sound/soc/meson/axg-tdmout.c
index f73368ee1088..527bfc4487e0 100644
--- a/sound/soc/meson/axg-tdmout.c
+++ b/sound/soc/meson/axg-tdmout.c
@@ -124,21 +124,22 @@ static void axg_tdmout_disable(struct regmap *map)
regmap_update_bits(map, TDMOUT_CTRL0, TDMOUT_CTRL0_ENABLE, 0);
}
-static int axg_tdmout_prepare(struct regmap *map, struct axg_tdm_stream *ts)
+static int axg_tdmout_prepare(struct regmap *map,
+ const struct axg_tdm_formatter_hw *quirks,
+ struct axg_tdm_stream *ts)
{
- unsigned int val = 0;
+ unsigned int val, skew = quirks->skew_offset;
/* Set the stream skew */
switch (ts->iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
case SND_SOC_DAIFMT_DSP_A:
- val |= TDMOUT_CTRL0_INIT_BITNUM(1);
break;
case SND_SOC_DAIFMT_LEFT_J:
case SND_SOC_DAIFMT_RIGHT_J:
case SND_SOC_DAIFMT_DSP_B:
- val |= TDMOUT_CTRL0_INIT_BITNUM(2);
+ skew += 1;
break;
default:
@@ -147,6 +148,8 @@ static int axg_tdmout_prepare(struct regmap *map, struct axg_tdm_stream *ts)
return -EINVAL;
}
+ val = TDMOUT_CTRL0_INIT_BITNUM(skew);
+
/* Set the slot width */
val |= TDMOUT_CTRL0_BITNUM(ts->iface->slot_width - 1);
@@ -234,13 +237,29 @@ static const struct axg_tdm_formatter_driver axg_tdmout_drv = {
.component_drv = &axg_tdmout_component_drv,
.regmap_cfg = &axg_tdmout_regmap_cfg,
.ops = &axg_tdmout_ops,
- .invert_sclk = true,
+ .quirks = &(const struct axg_tdm_formatter_hw) {
+ .invert_sclk = true,
+ .skew_offset = 1,
+ },
+};
+
+static const struct axg_tdm_formatter_driver g12a_tdmout_drv = {
+ .component_drv = &axg_tdmout_component_drv,
+ .regmap_cfg = &axg_tdmout_regmap_cfg,
+ .ops = &axg_tdmout_ops,
+ .quirks = &(const struct axg_tdm_formatter_hw) {
+ .invert_sclk = true,
+ .skew_offset = 2,
+ },
};
static const struct of_device_id axg_tdmout_of_match[] = {
{
.compatible = "amlogic,axg-tdmout",
.data = &axg_tdmout_drv,
+ }, {
+ .compatible = "amlogic,g12a-tdmout",
+ .data = &g12a_tdmout_drv,
}, {}
};
MODULE_DEVICE_TABLE(of, axg_tdmout_of_match);
diff --git a/sound/soc/meson/axg-toddr.c b/sound/soc/meson/axg-toddr.c
index 0e9ca3882ae5..4f63e434fad4 100644
--- a/sound/soc/meson/axg-toddr.c
+++ b/sound/soc/meson/axg-toddr.c
@@ -24,6 +24,7 @@
#define CTRL0_TODDR_MSB_POS(x) ((x) << 8)
#define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3)
#define CTRL0_TODDR_LSB_POS(x) ((x) << 3)
+#define CTRL1_TODDR_FORCE_FINISH BIT(25)
#define TODDR_MSB_POS 31
@@ -33,6 +34,22 @@ static int axg_toddr_pcm_new(struct snd_soc_pcm_runtime *rtd,
return axg_fifo_pcm_new(rtd, SNDRV_PCM_STREAM_CAPTURE);
}
+static int g12a_toddr_dai_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
+
+ /* Reset the write pointer to the FIFO_INIT_ADDR */
+ regmap_update_bits(fifo->map, FIFO_CTRL1,
+ CTRL1_TODDR_FORCE_FINISH, 0);
+ regmap_update_bits(fifo->map, FIFO_CTRL1,
+ CTRL1_TODDR_FORCE_FINISH, CTRL1_TODDR_FORCE_FINISH);
+ regmap_update_bits(fifo->map, FIFO_CTRL1,
+ CTRL1_TODDR_FORCE_FINISH, 0);
+
+ return 0;
+}
+
static int axg_toddr_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -172,10 +189,46 @@ static const struct axg_fifo_match_data axg_toddr_match_data = {
.dai_drv = &axg_toddr_dai_drv
};
+static const struct snd_soc_dai_ops g12a_toddr_ops = {
+ .prepare = g12a_toddr_dai_prepare,
+ .hw_params = axg_toddr_dai_hw_params,
+ .startup = axg_toddr_dai_startup,
+ .shutdown = axg_toddr_dai_shutdown,
+};
+
+static struct snd_soc_dai_driver g12a_toddr_dai_drv = {
+ .name = "TODDR",
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = AXG_FIFO_CH_MAX,
+ .rates = AXG_FIFO_RATES,
+ .formats = AXG_FIFO_FORMATS,
+ },
+ .ops = &g12a_toddr_ops,
+ .pcm_new = axg_toddr_pcm_new,
+};
+
+static const struct snd_soc_component_driver g12a_toddr_component_drv = {
+ .dapm_widgets = axg_toddr_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(axg_toddr_dapm_widgets),
+ .dapm_routes = axg_toddr_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(axg_toddr_dapm_routes),
+ .ops = &g12a_fifo_pcm_ops
+};
+
+static const struct axg_fifo_match_data g12a_toddr_match_data = {
+ .component_drv = &g12a_toddr_component_drv,
+ .dai_drv = &g12a_toddr_dai_drv
+};
+
static const struct of_device_id axg_toddr_of_match[] = {
{
.compatible = "amlogic,axg-toddr",
.data = &axg_toddr_match_data,
+ }, {
+ .compatible = "amlogic,g12a-toddr",
+ .data = &g12a_toddr_match_data,
}, {}
};
MODULE_DEVICE_TABLE(of, axg_toddr_of_match);