18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0 OR MIT) 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// Copyright (c) 2018 BayLibre, SAS. 48c2ecf20Sopenharmony_ci// Author: Jerome Brunet <jbrunet@baylibre.com> 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci/* This driver implements the frontend capture DAI of AXG based SoCs */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/clk.h> 98c2ecf20Sopenharmony_ci#include <linux/regmap.h> 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <linux/of_platform.h> 128c2ecf20Sopenharmony_ci#include <sound/pcm_params.h> 138c2ecf20Sopenharmony_ci#include <sound/soc.h> 148c2ecf20Sopenharmony_ci#include <sound/soc-dai.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include "axg-fifo.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define CTRL0_TODDR_SEL_RESAMPLE BIT(30) 198c2ecf20Sopenharmony_ci#define CTRL0_TODDR_EXT_SIGNED BIT(29) 208c2ecf20Sopenharmony_ci#define CTRL0_TODDR_PP_MODE BIT(28) 218c2ecf20Sopenharmony_ci#define CTRL0_TODDR_SYNC_CH BIT(27) 228c2ecf20Sopenharmony_ci#define CTRL0_TODDR_TYPE_MASK GENMASK(15, 13) 238c2ecf20Sopenharmony_ci#define CTRL0_TODDR_TYPE(x) ((x) << 13) 248c2ecf20Sopenharmony_ci#define CTRL0_TODDR_MSB_POS_MASK GENMASK(12, 8) 258c2ecf20Sopenharmony_ci#define CTRL0_TODDR_MSB_POS(x) ((x) << 8) 268c2ecf20Sopenharmony_ci#define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3) 278c2ecf20Sopenharmony_ci#define CTRL0_TODDR_LSB_POS(x) ((x) << 3) 288c2ecf20Sopenharmony_ci#define CTRL1_TODDR_FORCE_FINISH BIT(25) 298c2ecf20Sopenharmony_ci#define CTRL1_SEL_SHIFT 28 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define TODDR_MSB_POS 31 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistatic int axg_toddr_pcm_new(struct snd_soc_pcm_runtime *rtd, 348c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci return axg_fifo_pcm_new(rtd, SNDRV_PCM_STREAM_CAPTURE); 378c2ecf20Sopenharmony_ci} 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic int g12a_toddr_dai_prepare(struct snd_pcm_substream *substream, 408c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci /* Reset the write pointer to the FIFO_INIT_ADDR */ 458c2ecf20Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL1, 468c2ecf20Sopenharmony_ci CTRL1_TODDR_FORCE_FINISH, 0); 478c2ecf20Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL1, 488c2ecf20Sopenharmony_ci CTRL1_TODDR_FORCE_FINISH, CTRL1_TODDR_FORCE_FINISH); 498c2ecf20Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL1, 508c2ecf20Sopenharmony_ci CTRL1_TODDR_FORCE_FINISH, 0); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci return 0; 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic int axg_toddr_dai_hw_params(struct snd_pcm_substream *substream, 568c2ecf20Sopenharmony_ci struct snd_pcm_hw_params *params, 578c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 608c2ecf20Sopenharmony_ci unsigned int type, width; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci switch (params_physical_width(params)) { 638c2ecf20Sopenharmony_ci case 8: 648c2ecf20Sopenharmony_ci type = 0; /* 8 samples of 8 bits */ 658c2ecf20Sopenharmony_ci break; 668c2ecf20Sopenharmony_ci case 16: 678c2ecf20Sopenharmony_ci type = 2; /* 4 samples of 16 bits - right justified */ 688c2ecf20Sopenharmony_ci break; 698c2ecf20Sopenharmony_ci case 32: 708c2ecf20Sopenharmony_ci type = 4; /* 2 samples of 32 bits - right justified */ 718c2ecf20Sopenharmony_ci break; 728c2ecf20Sopenharmony_ci default: 738c2ecf20Sopenharmony_ci return -EINVAL; 748c2ecf20Sopenharmony_ci } 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci width = params_width(params); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, 798c2ecf20Sopenharmony_ci CTRL0_TODDR_TYPE_MASK | 808c2ecf20Sopenharmony_ci CTRL0_TODDR_MSB_POS_MASK | 818c2ecf20Sopenharmony_ci CTRL0_TODDR_LSB_POS_MASK, 828c2ecf20Sopenharmony_ci CTRL0_TODDR_TYPE(type) | 838c2ecf20Sopenharmony_ci CTRL0_TODDR_MSB_POS(TODDR_MSB_POS) | 848c2ecf20Sopenharmony_ci CTRL0_TODDR_LSB_POS(TODDR_MSB_POS - (width - 1))); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci return 0; 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic int axg_toddr_dai_startup(struct snd_pcm_substream *substream, 908c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 938c2ecf20Sopenharmony_ci int ret; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci /* Enable pclk to access registers and clock the fifo ip */ 968c2ecf20Sopenharmony_ci ret = clk_prepare_enable(fifo->pclk); 978c2ecf20Sopenharmony_ci if (ret) 988c2ecf20Sopenharmony_ci return ret; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci /* Select orginal data - resampling not supported ATM */ 1018c2ecf20Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_SEL_RESAMPLE, 0); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci /* Only signed format are supported ATM */ 1048c2ecf20Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_EXT_SIGNED, 1058c2ecf20Sopenharmony_ci CTRL0_TODDR_EXT_SIGNED); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci /* Apply single buffer mode to the interface */ 1088c2ecf20Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_PP_MODE, 0); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci return 0; 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic void axg_toddr_dai_shutdown(struct snd_pcm_substream *substream, 1148c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci clk_disable_unprepare(fifo->pclk); 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic const struct snd_soc_dai_ops axg_toddr_ops = { 1228c2ecf20Sopenharmony_ci .hw_params = axg_toddr_dai_hw_params, 1238c2ecf20Sopenharmony_ci .startup = axg_toddr_dai_startup, 1248c2ecf20Sopenharmony_ci .shutdown = axg_toddr_dai_shutdown, 1258c2ecf20Sopenharmony_ci}; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistatic struct snd_soc_dai_driver axg_toddr_dai_drv = { 1288c2ecf20Sopenharmony_ci .name = "TODDR", 1298c2ecf20Sopenharmony_ci .capture = { 1308c2ecf20Sopenharmony_ci .stream_name = "Capture", 1318c2ecf20Sopenharmony_ci .channels_min = 1, 1328c2ecf20Sopenharmony_ci .channels_max = AXG_FIFO_CH_MAX, 1338c2ecf20Sopenharmony_ci .rates = AXG_FIFO_RATES, 1348c2ecf20Sopenharmony_ci .formats = AXG_FIFO_FORMATS, 1358c2ecf20Sopenharmony_ci }, 1368c2ecf20Sopenharmony_ci .ops = &axg_toddr_ops, 1378c2ecf20Sopenharmony_ci .pcm_new = axg_toddr_pcm_new, 1388c2ecf20Sopenharmony_ci}; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistatic const char * const axg_toddr_sel_texts[] = { 1418c2ecf20Sopenharmony_ci "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7" 1428c2ecf20Sopenharmony_ci}; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(axg_toddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, 1458c2ecf20Sopenharmony_ci axg_toddr_sel_texts); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new axg_toddr_in_mux = 1488c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Input Source", axg_toddr_sel_enum); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget axg_toddr_dapm_widgets[] = { 1518c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &axg_toddr_in_mux), 1528c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), 1538c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), 1548c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), 1558c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), 1568c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), 1578c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0), 1588c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0), 1598c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0), 1608c2ecf20Sopenharmony_ci}; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route axg_toddr_dapm_routes[] = { 1638c2ecf20Sopenharmony_ci { "Capture", NULL, "SRC SEL" }, 1648c2ecf20Sopenharmony_ci { "SRC SEL", "IN 0", "IN 0" }, 1658c2ecf20Sopenharmony_ci { "SRC SEL", "IN 1", "IN 1" }, 1668c2ecf20Sopenharmony_ci { "SRC SEL", "IN 2", "IN 2" }, 1678c2ecf20Sopenharmony_ci { "SRC SEL", "IN 3", "IN 3" }, 1688c2ecf20Sopenharmony_ci { "SRC SEL", "IN 4", "IN 4" }, 1698c2ecf20Sopenharmony_ci { "SRC SEL", "IN 5", "IN 5" }, 1708c2ecf20Sopenharmony_ci { "SRC SEL", "IN 6", "IN 6" }, 1718c2ecf20Sopenharmony_ci { "SRC SEL", "IN 7", "IN 7" }, 1728c2ecf20Sopenharmony_ci}; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_cistatic const struct snd_soc_component_driver axg_toddr_component_drv = { 1758c2ecf20Sopenharmony_ci .dapm_widgets = axg_toddr_dapm_widgets, 1768c2ecf20Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(axg_toddr_dapm_widgets), 1778c2ecf20Sopenharmony_ci .dapm_routes = axg_toddr_dapm_routes, 1788c2ecf20Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(axg_toddr_dapm_routes), 1798c2ecf20Sopenharmony_ci .open = axg_fifo_pcm_open, 1808c2ecf20Sopenharmony_ci .close = axg_fifo_pcm_close, 1818c2ecf20Sopenharmony_ci .hw_params = axg_fifo_pcm_hw_params, 1828c2ecf20Sopenharmony_ci .hw_free = axg_fifo_pcm_hw_free, 1838c2ecf20Sopenharmony_ci .pointer = axg_fifo_pcm_pointer, 1848c2ecf20Sopenharmony_ci .trigger = axg_fifo_pcm_trigger, 1858c2ecf20Sopenharmony_ci}; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistatic const struct axg_fifo_match_data axg_toddr_match_data = { 1888c2ecf20Sopenharmony_ci .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), 1898c2ecf20Sopenharmony_ci .component_drv = &axg_toddr_component_drv, 1908c2ecf20Sopenharmony_ci .dai_drv = &axg_toddr_dai_drv 1918c2ecf20Sopenharmony_ci}; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic int g12a_toddr_dai_startup(struct snd_pcm_substream *substream, 1948c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 1958c2ecf20Sopenharmony_ci{ 1968c2ecf20Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 1978c2ecf20Sopenharmony_ci int ret; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci ret = axg_toddr_dai_startup(substream, dai); 2008c2ecf20Sopenharmony_ci if (ret) 2018c2ecf20Sopenharmony_ci return ret; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci /* 2048c2ecf20Sopenharmony_ci * Make sure the first channel ends up in the at beginning of the output 2058c2ecf20Sopenharmony_ci * As weird as it looks, without this the first channel may be misplaced 2068c2ecf20Sopenharmony_ci * in memory, with a random shift of 2 channels. 2078c2ecf20Sopenharmony_ci */ 2088c2ecf20Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_SYNC_CH, 2098c2ecf20Sopenharmony_ci CTRL0_TODDR_SYNC_CH); 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci return 0; 2128c2ecf20Sopenharmony_ci} 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistatic const struct snd_soc_dai_ops g12a_toddr_ops = { 2158c2ecf20Sopenharmony_ci .prepare = g12a_toddr_dai_prepare, 2168c2ecf20Sopenharmony_ci .hw_params = axg_toddr_dai_hw_params, 2178c2ecf20Sopenharmony_ci .startup = g12a_toddr_dai_startup, 2188c2ecf20Sopenharmony_ci .shutdown = axg_toddr_dai_shutdown, 2198c2ecf20Sopenharmony_ci}; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_cistatic struct snd_soc_dai_driver g12a_toddr_dai_drv = { 2228c2ecf20Sopenharmony_ci .name = "TODDR", 2238c2ecf20Sopenharmony_ci .capture = { 2248c2ecf20Sopenharmony_ci .stream_name = "Capture", 2258c2ecf20Sopenharmony_ci .channels_min = 1, 2268c2ecf20Sopenharmony_ci .channels_max = AXG_FIFO_CH_MAX, 2278c2ecf20Sopenharmony_ci .rates = AXG_FIFO_RATES, 2288c2ecf20Sopenharmony_ci .formats = AXG_FIFO_FORMATS, 2298c2ecf20Sopenharmony_ci }, 2308c2ecf20Sopenharmony_ci .ops = &g12a_toddr_ops, 2318c2ecf20Sopenharmony_ci .pcm_new = axg_toddr_pcm_new, 2328c2ecf20Sopenharmony_ci}; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic const struct snd_soc_component_driver g12a_toddr_component_drv = { 2358c2ecf20Sopenharmony_ci .dapm_widgets = axg_toddr_dapm_widgets, 2368c2ecf20Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(axg_toddr_dapm_widgets), 2378c2ecf20Sopenharmony_ci .dapm_routes = axg_toddr_dapm_routes, 2388c2ecf20Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(axg_toddr_dapm_routes), 2398c2ecf20Sopenharmony_ci .open = axg_fifo_pcm_open, 2408c2ecf20Sopenharmony_ci .close = axg_fifo_pcm_close, 2418c2ecf20Sopenharmony_ci .hw_params = g12a_fifo_pcm_hw_params, 2428c2ecf20Sopenharmony_ci .hw_free = axg_fifo_pcm_hw_free, 2438c2ecf20Sopenharmony_ci .pointer = axg_fifo_pcm_pointer, 2448c2ecf20Sopenharmony_ci .trigger = axg_fifo_pcm_trigger, 2458c2ecf20Sopenharmony_ci}; 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_cistatic const struct axg_fifo_match_data g12a_toddr_match_data = { 2488c2ecf20Sopenharmony_ci .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), 2498c2ecf20Sopenharmony_ci .component_drv = &g12a_toddr_component_drv, 2508c2ecf20Sopenharmony_ci .dai_drv = &g12a_toddr_dai_drv 2518c2ecf20Sopenharmony_ci}; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_cistatic const char * const sm1_toddr_sel_texts[] = { 2548c2ecf20Sopenharmony_ci "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7", 2558c2ecf20Sopenharmony_ci "IN 8", "IN 9", "IN 10", "IN 11", "IN 12", "IN 13", "IN 14", "IN 15" 2568c2ecf20Sopenharmony_ci}; 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(sm1_toddr_sel_enum, FIFO_CTRL1, CTRL1_SEL_SHIFT, 2598c2ecf20Sopenharmony_ci sm1_toddr_sel_texts); 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new sm1_toddr_in_mux = 2628c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Input Source", sm1_toddr_sel_enum); 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget sm1_toddr_dapm_widgets[] = { 2658c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &sm1_toddr_in_mux), 2668c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), 2678c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), 2688c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), 2698c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), 2708c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), 2718c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0), 2728c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0), 2738c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0), 2748c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 8", NULL, 0, SND_SOC_NOPM, 0, 0), 2758c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 9", NULL, 0, SND_SOC_NOPM, 0, 0), 2768c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 10", NULL, 0, SND_SOC_NOPM, 0, 0), 2778c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 11", NULL, 0, SND_SOC_NOPM, 0, 0), 2788c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 12", NULL, 0, SND_SOC_NOPM, 0, 0), 2798c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 13", NULL, 0, SND_SOC_NOPM, 0, 0), 2808c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 14", NULL, 0, SND_SOC_NOPM, 0, 0), 2818c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 15", NULL, 0, SND_SOC_NOPM, 0, 0), 2828c2ecf20Sopenharmony_ci}; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route sm1_toddr_dapm_routes[] = { 2858c2ecf20Sopenharmony_ci { "Capture", NULL, "SRC SEL" }, 2868c2ecf20Sopenharmony_ci { "SRC SEL", "IN 0", "IN 0" }, 2878c2ecf20Sopenharmony_ci { "SRC SEL", "IN 1", "IN 1" }, 2888c2ecf20Sopenharmony_ci { "SRC SEL", "IN 2", "IN 2" }, 2898c2ecf20Sopenharmony_ci { "SRC SEL", "IN 3", "IN 3" }, 2908c2ecf20Sopenharmony_ci { "SRC SEL", "IN 4", "IN 4" }, 2918c2ecf20Sopenharmony_ci { "SRC SEL", "IN 5", "IN 5" }, 2928c2ecf20Sopenharmony_ci { "SRC SEL", "IN 6", "IN 6" }, 2938c2ecf20Sopenharmony_ci { "SRC SEL", "IN 7", "IN 7" }, 2948c2ecf20Sopenharmony_ci { "SRC SEL", "IN 8", "IN 8" }, 2958c2ecf20Sopenharmony_ci { "SRC SEL", "IN 9", "IN 9" }, 2968c2ecf20Sopenharmony_ci { "SRC SEL", "IN 10", "IN 10" }, 2978c2ecf20Sopenharmony_ci { "SRC SEL", "IN 11", "IN 11" }, 2988c2ecf20Sopenharmony_ci { "SRC SEL", "IN 12", "IN 12" }, 2998c2ecf20Sopenharmony_ci { "SRC SEL", "IN 13", "IN 13" }, 3008c2ecf20Sopenharmony_ci { "SRC SEL", "IN 14", "IN 14" }, 3018c2ecf20Sopenharmony_ci { "SRC SEL", "IN 15", "IN 15" }, 3028c2ecf20Sopenharmony_ci}; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic const struct snd_soc_component_driver sm1_toddr_component_drv = { 3058c2ecf20Sopenharmony_ci .dapm_widgets = sm1_toddr_dapm_widgets, 3068c2ecf20Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(sm1_toddr_dapm_widgets), 3078c2ecf20Sopenharmony_ci .dapm_routes = sm1_toddr_dapm_routes, 3088c2ecf20Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(sm1_toddr_dapm_routes), 3098c2ecf20Sopenharmony_ci .open = axg_fifo_pcm_open, 3108c2ecf20Sopenharmony_ci .close = axg_fifo_pcm_close, 3118c2ecf20Sopenharmony_ci .hw_params = g12a_fifo_pcm_hw_params, 3128c2ecf20Sopenharmony_ci .hw_free = axg_fifo_pcm_hw_free, 3138c2ecf20Sopenharmony_ci .pointer = axg_fifo_pcm_pointer, 3148c2ecf20Sopenharmony_ci .trigger = axg_fifo_pcm_trigger, 3158c2ecf20Sopenharmony_ci}; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic const struct axg_fifo_match_data sm1_toddr_match_data = { 3188c2ecf20Sopenharmony_ci .field_threshold = REG_FIELD(FIFO_CTRL1, 12, 23), 3198c2ecf20Sopenharmony_ci .component_drv = &sm1_toddr_component_drv, 3208c2ecf20Sopenharmony_ci .dai_drv = &g12a_toddr_dai_drv 3218c2ecf20Sopenharmony_ci}; 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_cistatic const struct of_device_id axg_toddr_of_match[] = { 3248c2ecf20Sopenharmony_ci { 3258c2ecf20Sopenharmony_ci .compatible = "amlogic,axg-toddr", 3268c2ecf20Sopenharmony_ci .data = &axg_toddr_match_data, 3278c2ecf20Sopenharmony_ci }, { 3288c2ecf20Sopenharmony_ci .compatible = "amlogic,g12a-toddr", 3298c2ecf20Sopenharmony_ci .data = &g12a_toddr_match_data, 3308c2ecf20Sopenharmony_ci }, { 3318c2ecf20Sopenharmony_ci .compatible = "amlogic,sm1-toddr", 3328c2ecf20Sopenharmony_ci .data = &sm1_toddr_match_data, 3338c2ecf20Sopenharmony_ci }, {} 3348c2ecf20Sopenharmony_ci}; 3358c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, axg_toddr_of_match); 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_cistatic struct platform_driver axg_toddr_pdrv = { 3388c2ecf20Sopenharmony_ci .probe = axg_fifo_probe, 3398c2ecf20Sopenharmony_ci .driver = { 3408c2ecf20Sopenharmony_ci .name = "axg-toddr", 3418c2ecf20Sopenharmony_ci .of_match_table = axg_toddr_of_match, 3428c2ecf20Sopenharmony_ci }, 3438c2ecf20Sopenharmony_ci}; 3448c2ecf20Sopenharmony_cimodule_platform_driver(axg_toddr_pdrv); 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Amlogic AXG capture fifo driver"); 3478c2ecf20Sopenharmony_ciMODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 3488c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 349