xref: /openbmc/linux/sound/soc/meson/axg-toddr.c (revision af8e6bbf)
17ed4877bSJerome Brunet // SPDX-License-Identifier: (GPL-2.0 OR MIT)
27ed4877bSJerome Brunet //
37ed4877bSJerome Brunet // Copyright (c) 2018 BayLibre, SAS.
47ed4877bSJerome Brunet // Author: Jerome Brunet <jbrunet@baylibre.com>
57ed4877bSJerome Brunet 
67ed4877bSJerome Brunet /* This driver implements the frontend capture DAI of AXG based SoCs */
77ed4877bSJerome Brunet 
8af8e6bbfSJerome Brunet #include <linux/bitfield.h>
97ed4877bSJerome Brunet #include <linux/clk.h>
107ed4877bSJerome Brunet #include <linux/regmap.h>
117ed4877bSJerome Brunet #include <linux/module.h>
127ed4877bSJerome Brunet #include <linux/of_platform.h>
137ed4877bSJerome Brunet #include <sound/pcm_params.h>
147ed4877bSJerome Brunet #include <sound/soc.h>
157ed4877bSJerome Brunet #include <sound/soc-dai.h>
167ed4877bSJerome Brunet 
177ed4877bSJerome Brunet #include "axg-fifo.h"
187ed4877bSJerome Brunet 
197ed4877bSJerome Brunet #define CTRL0_TODDR_SEL_RESAMPLE	BIT(30)
207ed4877bSJerome Brunet #define CTRL0_TODDR_EXT_SIGNED		BIT(29)
217ed4877bSJerome Brunet #define CTRL0_TODDR_PP_MODE		BIT(28)
229c4b205aSJerome Brunet #define CTRL0_TODDR_SYNC_CH		BIT(27)
23af8e6bbfSJerome Brunet #define CTRL0_TODDR_TYPE		GENMASK(15, 13)
24af8e6bbfSJerome Brunet #define CTRL0_TODDR_MSB_POS		GENMASK(12, 8)
25af8e6bbfSJerome Brunet #define CTRL0_TODDR_LSB_POS		GENMASK(7, 3)
26a3c23a8aSJerome Brunet #define CTRL1_TODDR_FORCE_FINISH	BIT(25)
275ac825c3SJerome Brunet #define CTRL1_SEL_SHIFT			28
287ed4877bSJerome Brunet 
29984463a9SJerome Brunet #define TODDR_MSB_POS	31
30984463a9SJerome Brunet 
axg_toddr_pcm_new(struct snd_soc_pcm_runtime * rtd,struct snd_soc_dai * dai)317ed4877bSJerome Brunet static int axg_toddr_pcm_new(struct snd_soc_pcm_runtime *rtd,
327ed4877bSJerome Brunet 			     struct snd_soc_dai *dai)
337ed4877bSJerome Brunet {
347ed4877bSJerome Brunet 	return axg_fifo_pcm_new(rtd, SNDRV_PCM_STREAM_CAPTURE);
357ed4877bSJerome Brunet }
367ed4877bSJerome Brunet 
g12a_toddr_dai_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)37a3c23a8aSJerome Brunet static int g12a_toddr_dai_prepare(struct snd_pcm_substream *substream,
38a3c23a8aSJerome Brunet 				  struct snd_soc_dai *dai)
39a3c23a8aSJerome Brunet {
40a3c23a8aSJerome Brunet 	struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
41a3c23a8aSJerome Brunet 
42a3c23a8aSJerome Brunet 	/* Reset the write pointer to the FIFO_INIT_ADDR */
43a3c23a8aSJerome Brunet 	regmap_update_bits(fifo->map, FIFO_CTRL1,
44a3c23a8aSJerome Brunet 			   CTRL1_TODDR_FORCE_FINISH, 0);
45a3c23a8aSJerome Brunet 	regmap_update_bits(fifo->map, FIFO_CTRL1,
46a3c23a8aSJerome Brunet 			   CTRL1_TODDR_FORCE_FINISH, CTRL1_TODDR_FORCE_FINISH);
47a3c23a8aSJerome Brunet 	regmap_update_bits(fifo->map, FIFO_CTRL1,
48a3c23a8aSJerome Brunet 			   CTRL1_TODDR_FORCE_FINISH, 0);
49a3c23a8aSJerome Brunet 
50a3c23a8aSJerome Brunet 	return 0;
51a3c23a8aSJerome Brunet }
52a3c23a8aSJerome Brunet 
axg_toddr_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)537ed4877bSJerome Brunet static int axg_toddr_dai_hw_params(struct snd_pcm_substream *substream,
547ed4877bSJerome Brunet 				   struct snd_pcm_hw_params *params,
557ed4877bSJerome Brunet 				   struct snd_soc_dai *dai)
567ed4877bSJerome Brunet {
577ed4877bSJerome Brunet 	struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
58984463a9SJerome Brunet 	unsigned int type, width;
597ed4877bSJerome Brunet 
607ed4877bSJerome Brunet 	switch (params_physical_width(params)) {
617ed4877bSJerome Brunet 	case 8:
627ed4877bSJerome Brunet 		type = 0; /* 8 samples of 8 bits */
637ed4877bSJerome Brunet 		break;
647ed4877bSJerome Brunet 	case 16:
657ed4877bSJerome Brunet 		type = 2; /* 4 samples of 16 bits - right justified */
667ed4877bSJerome Brunet 		break;
677ed4877bSJerome Brunet 	case 32:
687ed4877bSJerome Brunet 		type = 4; /* 2 samples of 32 bits - right justified */
697ed4877bSJerome Brunet 		break;
707ed4877bSJerome Brunet 	default:
717ed4877bSJerome Brunet 		return -EINVAL;
727ed4877bSJerome Brunet 	}
737ed4877bSJerome Brunet 
747ed4877bSJerome Brunet 	width = params_width(params);
757ed4877bSJerome Brunet 
767ed4877bSJerome Brunet 	regmap_update_bits(fifo->map, FIFO_CTRL0,
77af8e6bbfSJerome Brunet 			   CTRL0_TODDR_TYPE |
78af8e6bbfSJerome Brunet 			   CTRL0_TODDR_MSB_POS |
79af8e6bbfSJerome Brunet 			   CTRL0_TODDR_LSB_POS,
80af8e6bbfSJerome Brunet 			   FIELD_PREP(CTRL0_TODDR_TYPE, type) |
81af8e6bbfSJerome Brunet 			   FIELD_PREP(CTRL0_TODDR_MSB_POS, TODDR_MSB_POS) |
82af8e6bbfSJerome Brunet 			   FIELD_PREP(CTRL0_TODDR_LSB_POS, TODDR_MSB_POS - (width - 1)));
837ed4877bSJerome Brunet 
847ed4877bSJerome Brunet 	return 0;
857ed4877bSJerome Brunet }
867ed4877bSJerome Brunet 
axg_toddr_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)877ed4877bSJerome Brunet static int axg_toddr_dai_startup(struct snd_pcm_substream *substream,
887ed4877bSJerome Brunet 				 struct snd_soc_dai *dai)
897ed4877bSJerome Brunet {
907ed4877bSJerome Brunet 	struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
917ed4877bSJerome Brunet 	int ret;
927ed4877bSJerome Brunet 
937ed4877bSJerome Brunet 	/* Enable pclk to access registers and clock the fifo ip */
947ed4877bSJerome Brunet 	ret = clk_prepare_enable(fifo->pclk);
957ed4877bSJerome Brunet 	if (ret)
967ed4877bSJerome Brunet 		return ret;
977ed4877bSJerome Brunet 
987ed4877bSJerome Brunet 	/* Select orginal data - resampling not supported ATM */
997ed4877bSJerome Brunet 	regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_SEL_RESAMPLE, 0);
1007ed4877bSJerome Brunet 
1017ed4877bSJerome Brunet 	/* Only signed format are supported ATM */
1027ed4877bSJerome Brunet 	regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_EXT_SIGNED,
1037ed4877bSJerome Brunet 			   CTRL0_TODDR_EXT_SIGNED);
1047ed4877bSJerome Brunet 
1057ed4877bSJerome Brunet 	/* Apply single buffer mode to the interface */
1067ed4877bSJerome Brunet 	regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_PP_MODE, 0);
1077ed4877bSJerome Brunet 
1087ed4877bSJerome Brunet 	return 0;
1097ed4877bSJerome Brunet }
1107ed4877bSJerome Brunet 
axg_toddr_dai_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)1117ed4877bSJerome Brunet static void axg_toddr_dai_shutdown(struct snd_pcm_substream *substream,
1127ed4877bSJerome Brunet 				   struct snd_soc_dai *dai)
1137ed4877bSJerome Brunet {
1147ed4877bSJerome Brunet 	struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
1157ed4877bSJerome Brunet 
1167ed4877bSJerome Brunet 	clk_disable_unprepare(fifo->pclk);
1177ed4877bSJerome Brunet }
1187ed4877bSJerome Brunet 
1197ed4877bSJerome Brunet static const struct snd_soc_dai_ops axg_toddr_ops = {
1207ed4877bSJerome Brunet 	.hw_params	= axg_toddr_dai_hw_params,
1217ed4877bSJerome Brunet 	.startup	= axg_toddr_dai_startup,
1227ed4877bSJerome Brunet 	.shutdown	= axg_toddr_dai_shutdown,
1232d3155a9SKuninori Morimoto 	.pcm_new	= axg_toddr_pcm_new,
1247ed4877bSJerome Brunet };
1257ed4877bSJerome Brunet 
1267ed4877bSJerome Brunet static struct snd_soc_dai_driver axg_toddr_dai_drv = {
1277ed4877bSJerome Brunet 	.name = "TODDR",
1287ed4877bSJerome Brunet 	.capture = {
1297ed4877bSJerome Brunet 		.stream_name	= "Capture",
1307ed4877bSJerome Brunet 		.channels_min	= 1,
1317ed4877bSJerome Brunet 		.channels_max	= AXG_FIFO_CH_MAX,
1327ed4877bSJerome Brunet 		.rates		= AXG_FIFO_RATES,
1337ed4877bSJerome Brunet 		.formats	= AXG_FIFO_FORMATS,
1347ed4877bSJerome Brunet 	},
1357ed4877bSJerome Brunet 	.ops		= &axg_toddr_ops,
1367ed4877bSJerome Brunet };
1377ed4877bSJerome Brunet 
1387ed4877bSJerome Brunet static const char * const axg_toddr_sel_texts[] = {
1396beced21SJerome Brunet 	"IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7"
1407ed4877bSJerome Brunet };
1417ed4877bSJerome Brunet 
1426beced21SJerome Brunet static SOC_ENUM_SINGLE_DECL(axg_toddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT,
1436beced21SJerome Brunet 			    axg_toddr_sel_texts);
1447ed4877bSJerome Brunet 
1457ed4877bSJerome Brunet static const struct snd_kcontrol_new axg_toddr_in_mux =
1467ed4877bSJerome Brunet 	SOC_DAPM_ENUM("Input Source", axg_toddr_sel_enum);
1477ed4877bSJerome Brunet 
1487ed4877bSJerome Brunet static const struct snd_soc_dapm_widget axg_toddr_dapm_widgets[] = {
1497ed4877bSJerome Brunet 	SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &axg_toddr_in_mux),
1507ed4877bSJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0),
1517ed4877bSJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0),
1527ed4877bSJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0),
1537ed4877bSJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0),
1547ed4877bSJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0),
1556beced21SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0),
1567ed4877bSJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0),
1576beced21SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0),
1587ed4877bSJerome Brunet };
1597ed4877bSJerome Brunet 
1607ed4877bSJerome Brunet static const struct snd_soc_dapm_route axg_toddr_dapm_routes[] = {
1617ed4877bSJerome Brunet 	{ "Capture", NULL, "SRC SEL" },
1627ed4877bSJerome Brunet 	{ "SRC SEL", "IN 0", "IN 0" },
1637ed4877bSJerome Brunet 	{ "SRC SEL", "IN 1", "IN 1" },
1647ed4877bSJerome Brunet 	{ "SRC SEL", "IN 2", "IN 2" },
1657ed4877bSJerome Brunet 	{ "SRC SEL", "IN 3", "IN 3" },
1667ed4877bSJerome Brunet 	{ "SRC SEL", "IN 4", "IN 4" },
1676beced21SJerome Brunet 	{ "SRC SEL", "IN 5", "IN 5" },
1687ed4877bSJerome Brunet 	{ "SRC SEL", "IN 6", "IN 6" },
1696beced21SJerome Brunet 	{ "SRC SEL", "IN 7", "IN 7" },
1707ed4877bSJerome Brunet };
1717ed4877bSJerome Brunet 
1727ed4877bSJerome Brunet static const struct snd_soc_component_driver axg_toddr_component_drv = {
1737ed4877bSJerome Brunet 	.dapm_widgets		= axg_toddr_dapm_widgets,
1747ed4877bSJerome Brunet 	.num_dapm_widgets	= ARRAY_SIZE(axg_toddr_dapm_widgets),
1757ed4877bSJerome Brunet 	.dapm_routes		= axg_toddr_dapm_routes,
1767ed4877bSJerome Brunet 	.num_dapm_routes	= ARRAY_SIZE(axg_toddr_dapm_routes),
177bb4ba744SKuninori Morimoto 	.open			= axg_fifo_pcm_open,
178bb4ba744SKuninori Morimoto 	.close			= axg_fifo_pcm_close,
179bb4ba744SKuninori Morimoto 	.hw_params		= axg_fifo_pcm_hw_params,
180bb4ba744SKuninori Morimoto 	.hw_free		= axg_fifo_pcm_hw_free,
181bb4ba744SKuninori Morimoto 	.pointer		= axg_fifo_pcm_pointer,
182bb4ba744SKuninori Morimoto 	.trigger		= axg_fifo_pcm_trigger,
183d8572da0SCharles Keepax 	.legacy_dai_naming	= 1,
1847ed4877bSJerome Brunet };
1857ed4877bSJerome Brunet 
1867ed4877bSJerome Brunet static const struct axg_fifo_match_data axg_toddr_match_data = {
187864cee90SJerome Brunet 	.field_threshold	= REG_FIELD(FIFO_CTRL1, 16, 23),
1887ed4877bSJerome Brunet 	.component_drv		= &axg_toddr_component_drv,
1897ed4877bSJerome Brunet 	.dai_drv		= &axg_toddr_dai_drv
1907ed4877bSJerome Brunet };
1917ed4877bSJerome Brunet 
g12a_toddr_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)1929c4b205aSJerome Brunet static int g12a_toddr_dai_startup(struct snd_pcm_substream *substream,
1939c4b205aSJerome Brunet 				 struct snd_soc_dai *dai)
1949c4b205aSJerome Brunet {
1959c4b205aSJerome Brunet 	struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
1969c4b205aSJerome Brunet 	int ret;
1979c4b205aSJerome Brunet 
1989c4b205aSJerome Brunet 	ret = axg_toddr_dai_startup(substream, dai);
1999c4b205aSJerome Brunet 	if (ret)
2009c4b205aSJerome Brunet 		return ret;
2019c4b205aSJerome Brunet 
2029c4b205aSJerome Brunet 	/*
2039c4b205aSJerome Brunet 	 * Make sure the first channel ends up in the at beginning of the output
2049c4b205aSJerome Brunet 	 * As weird as it looks, without this the first channel may be misplaced
2059c4b205aSJerome Brunet 	 * in memory, with a random shift of 2 channels.
2069c4b205aSJerome Brunet 	 */
2079c4b205aSJerome Brunet 	regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_SYNC_CH,
2089c4b205aSJerome Brunet 			   CTRL0_TODDR_SYNC_CH);
2099c4b205aSJerome Brunet 
2109c4b205aSJerome Brunet 	return 0;
2119c4b205aSJerome Brunet }
2129c4b205aSJerome Brunet 
213a3c23a8aSJerome Brunet static const struct snd_soc_dai_ops g12a_toddr_ops = {
214a3c23a8aSJerome Brunet 	.prepare	= g12a_toddr_dai_prepare,
215a3c23a8aSJerome Brunet 	.hw_params	= axg_toddr_dai_hw_params,
2169c4b205aSJerome Brunet 	.startup	= g12a_toddr_dai_startup,
217a3c23a8aSJerome Brunet 	.shutdown	= axg_toddr_dai_shutdown,
2182d3155a9SKuninori Morimoto 	.pcm_new	= axg_toddr_pcm_new,
219a3c23a8aSJerome Brunet };
220a3c23a8aSJerome Brunet 
221a3c23a8aSJerome Brunet static struct snd_soc_dai_driver g12a_toddr_dai_drv = {
222a3c23a8aSJerome Brunet 	.name = "TODDR",
223a3c23a8aSJerome Brunet 	.capture = {
224a3c23a8aSJerome Brunet 		.stream_name	= "Capture",
225a3c23a8aSJerome Brunet 		.channels_min	= 1,
226a3c23a8aSJerome Brunet 		.channels_max	= AXG_FIFO_CH_MAX,
227a3c23a8aSJerome Brunet 		.rates		= AXG_FIFO_RATES,
228a3c23a8aSJerome Brunet 		.formats	= AXG_FIFO_FORMATS,
229a3c23a8aSJerome Brunet 	},
230a3c23a8aSJerome Brunet 	.ops		= &g12a_toddr_ops,
231a3c23a8aSJerome Brunet };
232a3c23a8aSJerome Brunet 
233a3c23a8aSJerome Brunet static const struct snd_soc_component_driver g12a_toddr_component_drv = {
234a3c23a8aSJerome Brunet 	.dapm_widgets		= axg_toddr_dapm_widgets,
235a3c23a8aSJerome Brunet 	.num_dapm_widgets	= ARRAY_SIZE(axg_toddr_dapm_widgets),
236a3c23a8aSJerome Brunet 	.dapm_routes		= axg_toddr_dapm_routes,
237a3c23a8aSJerome Brunet 	.num_dapm_routes	= ARRAY_SIZE(axg_toddr_dapm_routes),
238bb4ba744SKuninori Morimoto 	.open			= axg_fifo_pcm_open,
239bb4ba744SKuninori Morimoto 	.close			= axg_fifo_pcm_close,
240bb4ba744SKuninori Morimoto 	.hw_params		= g12a_fifo_pcm_hw_params,
241bb4ba744SKuninori Morimoto 	.hw_free		= axg_fifo_pcm_hw_free,
242bb4ba744SKuninori Morimoto 	.pointer		= axg_fifo_pcm_pointer,
243bb4ba744SKuninori Morimoto 	.trigger		= axg_fifo_pcm_trigger,
244d8572da0SCharles Keepax 	.legacy_dai_naming	= 1,
245a3c23a8aSJerome Brunet };
246a3c23a8aSJerome Brunet 
247a3c23a8aSJerome Brunet static const struct axg_fifo_match_data g12a_toddr_match_data = {
248864cee90SJerome Brunet 	.field_threshold	= REG_FIELD(FIFO_CTRL1, 16, 23),
249a3c23a8aSJerome Brunet 	.component_drv		= &g12a_toddr_component_drv,
250a3c23a8aSJerome Brunet 	.dai_drv		= &g12a_toddr_dai_drv
251a3c23a8aSJerome Brunet };
252a3c23a8aSJerome Brunet 
2535ac825c3SJerome Brunet static const char * const sm1_toddr_sel_texts[] = {
2545ac825c3SJerome Brunet 	"IN 0", "IN 1", "IN 2",  "IN 3",  "IN 4",  "IN 5",  "IN 6",  "IN 7",
2555ac825c3SJerome Brunet 	"IN 8", "IN 9", "IN 10", "IN 11", "IN 12", "IN 13", "IN 14", "IN 15"
2565ac825c3SJerome Brunet };
2575ac825c3SJerome Brunet 
2585ac825c3SJerome Brunet static SOC_ENUM_SINGLE_DECL(sm1_toddr_sel_enum, FIFO_CTRL1, CTRL1_SEL_SHIFT,
2595ac825c3SJerome Brunet 			    sm1_toddr_sel_texts);
2605ac825c3SJerome Brunet 
2615ac825c3SJerome Brunet static const struct snd_kcontrol_new sm1_toddr_in_mux =
2625ac825c3SJerome Brunet 	SOC_DAPM_ENUM("Input Source", sm1_toddr_sel_enum);
2635ac825c3SJerome Brunet 
2645ac825c3SJerome Brunet static const struct snd_soc_dapm_widget sm1_toddr_dapm_widgets[] = {
2655ac825c3SJerome Brunet 	SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &sm1_toddr_in_mux),
2665ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 0",  NULL, 0, SND_SOC_NOPM, 0, 0),
2675ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 1",  NULL, 0, SND_SOC_NOPM, 0, 0),
2685ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 2",  NULL, 0, SND_SOC_NOPM, 0, 0),
2695ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 3",  NULL, 0, SND_SOC_NOPM, 0, 0),
2705ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 4",  NULL, 0, SND_SOC_NOPM, 0, 0),
2715ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 5",  NULL, 0, SND_SOC_NOPM, 0, 0),
2725ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 6",  NULL, 0, SND_SOC_NOPM, 0, 0),
2735ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 7",  NULL, 0, SND_SOC_NOPM, 0, 0),
2745ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 8",  NULL, 0, SND_SOC_NOPM, 0, 0),
2755ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 9",  NULL, 0, SND_SOC_NOPM, 0, 0),
2765ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 10", NULL, 0, SND_SOC_NOPM, 0, 0),
2775ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 11", NULL, 0, SND_SOC_NOPM, 0, 0),
2785ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 12", NULL, 0, SND_SOC_NOPM, 0, 0),
2795ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 13", NULL, 0, SND_SOC_NOPM, 0, 0),
2805ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 14", NULL, 0, SND_SOC_NOPM, 0, 0),
2815ac825c3SJerome Brunet 	SND_SOC_DAPM_AIF_IN("IN 15", NULL, 0, SND_SOC_NOPM, 0, 0),
2825ac825c3SJerome Brunet };
2835ac825c3SJerome Brunet 
2845ac825c3SJerome Brunet static const struct snd_soc_dapm_route sm1_toddr_dapm_routes[] = {
2855ac825c3SJerome Brunet 	{ "Capture", NULL, "SRC SEL" },
2865ac825c3SJerome Brunet 	{ "SRC SEL", "IN 0",  "IN 0" },
2875ac825c3SJerome Brunet 	{ "SRC SEL", "IN 1",  "IN 1" },
2885ac825c3SJerome Brunet 	{ "SRC SEL", "IN 2",  "IN 2" },
2895ac825c3SJerome Brunet 	{ "SRC SEL", "IN 3",  "IN 3" },
2905ac825c3SJerome Brunet 	{ "SRC SEL", "IN 4",  "IN 4" },
2915ac825c3SJerome Brunet 	{ "SRC SEL", "IN 5",  "IN 5" },
2925ac825c3SJerome Brunet 	{ "SRC SEL", "IN 6",  "IN 6" },
2935ac825c3SJerome Brunet 	{ "SRC SEL", "IN 7",  "IN 7" },
2945ac825c3SJerome Brunet 	{ "SRC SEL", "IN 8",  "IN 8" },
2955ac825c3SJerome Brunet 	{ "SRC SEL", "IN 9",  "IN 9" },
2965ac825c3SJerome Brunet 	{ "SRC SEL", "IN 10", "IN 10" },
2975ac825c3SJerome Brunet 	{ "SRC SEL", "IN 11", "IN 11" },
2985ac825c3SJerome Brunet 	{ "SRC SEL", "IN 12", "IN 12" },
2995ac825c3SJerome Brunet 	{ "SRC SEL", "IN 13", "IN 13" },
3005ac825c3SJerome Brunet 	{ "SRC SEL", "IN 14", "IN 14" },
3015ac825c3SJerome Brunet 	{ "SRC SEL", "IN 15", "IN 15" },
3025ac825c3SJerome Brunet };
3035ac825c3SJerome Brunet 
3045ac825c3SJerome Brunet static const struct snd_soc_component_driver sm1_toddr_component_drv = {
3055ac825c3SJerome Brunet 	.dapm_widgets		= sm1_toddr_dapm_widgets,
3065ac825c3SJerome Brunet 	.num_dapm_widgets	= ARRAY_SIZE(sm1_toddr_dapm_widgets),
3075ac825c3SJerome Brunet 	.dapm_routes		= sm1_toddr_dapm_routes,
3085ac825c3SJerome Brunet 	.num_dapm_routes	= ARRAY_SIZE(sm1_toddr_dapm_routes),
309bb4ba744SKuninori Morimoto 	.open			= axg_fifo_pcm_open,
310bb4ba744SKuninori Morimoto 	.close			= axg_fifo_pcm_close,
311bb4ba744SKuninori Morimoto 	.hw_params		= g12a_fifo_pcm_hw_params,
312bb4ba744SKuninori Morimoto 	.hw_free		= axg_fifo_pcm_hw_free,
313bb4ba744SKuninori Morimoto 	.pointer		= axg_fifo_pcm_pointer,
314bb4ba744SKuninori Morimoto 	.trigger		= axg_fifo_pcm_trigger,
315d8572da0SCharles Keepax 	.legacy_dai_naming	= 1,
3165ac825c3SJerome Brunet };
3175ac825c3SJerome Brunet 
3185ac825c3SJerome Brunet static const struct axg_fifo_match_data sm1_toddr_match_data = {
319864cee90SJerome Brunet 	.field_threshold	= REG_FIELD(FIFO_CTRL1, 12, 23),
3205ac825c3SJerome Brunet 	.component_drv		= &sm1_toddr_component_drv,
3215ac825c3SJerome Brunet 	.dai_drv		= &g12a_toddr_dai_drv
3225ac825c3SJerome Brunet };
3235ac825c3SJerome Brunet 
3247ed4877bSJerome Brunet static const struct of_device_id axg_toddr_of_match[] = {
3257ed4877bSJerome Brunet 	{
3267ed4877bSJerome Brunet 		.compatible = "amlogic,axg-toddr",
3277ed4877bSJerome Brunet 		.data = &axg_toddr_match_data,
328a3c23a8aSJerome Brunet 	}, {
329a3c23a8aSJerome Brunet 		.compatible = "amlogic,g12a-toddr",
330a3c23a8aSJerome Brunet 		.data = &g12a_toddr_match_data,
3315ac825c3SJerome Brunet 	}, {
3325ac825c3SJerome Brunet 		.compatible = "amlogic,sm1-toddr",
3335ac825c3SJerome Brunet 		.data = &sm1_toddr_match_data,
3347ed4877bSJerome Brunet 	}, {}
3357ed4877bSJerome Brunet };
3367ed4877bSJerome Brunet MODULE_DEVICE_TABLE(of, axg_toddr_of_match);
3377ed4877bSJerome Brunet 
3387ed4877bSJerome Brunet static struct platform_driver axg_toddr_pdrv = {
3397ed4877bSJerome Brunet 	.probe = axg_fifo_probe,
3407ed4877bSJerome Brunet 	.driver = {
3417ed4877bSJerome Brunet 		.name = "axg-toddr",
3427ed4877bSJerome Brunet 		.of_match_table = axg_toddr_of_match,
3437ed4877bSJerome Brunet 	},
3447ed4877bSJerome Brunet };
3457ed4877bSJerome Brunet module_platform_driver(axg_toddr_pdrv);
3467ed4877bSJerome Brunet 
3477ed4877bSJerome Brunet MODULE_DESCRIPTION("Amlogic AXG capture fifo driver");
3487ed4877bSJerome Brunet MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
3497ed4877bSJerome Brunet MODULE_LICENSE("GPL v2");
350