162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0 OR MIT) 262306a36Sopenharmony_ci// 362306a36Sopenharmony_ci// Copyright (c) 2018 BayLibre, SAS. 462306a36Sopenharmony_ci// Author: Jerome Brunet <jbrunet@baylibre.com> 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci/* This driver implements the frontend capture DAI of AXG based SoCs */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/clk.h> 962306a36Sopenharmony_ci#include <linux/regmap.h> 1062306a36Sopenharmony_ci#include <linux/module.h> 1162306a36Sopenharmony_ci#include <linux/of_platform.h> 1262306a36Sopenharmony_ci#include <sound/pcm_params.h> 1362306a36Sopenharmony_ci#include <sound/soc.h> 1462306a36Sopenharmony_ci#include <sound/soc-dai.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "axg-fifo.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define CTRL0_TODDR_SEL_RESAMPLE BIT(30) 1962306a36Sopenharmony_ci#define CTRL0_TODDR_EXT_SIGNED BIT(29) 2062306a36Sopenharmony_ci#define CTRL0_TODDR_PP_MODE BIT(28) 2162306a36Sopenharmony_ci#define CTRL0_TODDR_SYNC_CH BIT(27) 2262306a36Sopenharmony_ci#define CTRL0_TODDR_TYPE_MASK GENMASK(15, 13) 2362306a36Sopenharmony_ci#define CTRL0_TODDR_TYPE(x) ((x) << 13) 2462306a36Sopenharmony_ci#define CTRL0_TODDR_MSB_POS_MASK GENMASK(12, 8) 2562306a36Sopenharmony_ci#define CTRL0_TODDR_MSB_POS(x) ((x) << 8) 2662306a36Sopenharmony_ci#define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3) 2762306a36Sopenharmony_ci#define CTRL0_TODDR_LSB_POS(x) ((x) << 3) 2862306a36Sopenharmony_ci#define CTRL1_TODDR_FORCE_FINISH BIT(25) 2962306a36Sopenharmony_ci#define CTRL1_SEL_SHIFT 28 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define TODDR_MSB_POS 31 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistatic int axg_toddr_pcm_new(struct snd_soc_pcm_runtime *rtd, 3462306a36Sopenharmony_ci struct snd_soc_dai *dai) 3562306a36Sopenharmony_ci{ 3662306a36Sopenharmony_ci return axg_fifo_pcm_new(rtd, SNDRV_PCM_STREAM_CAPTURE); 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic int g12a_toddr_dai_prepare(struct snd_pcm_substream *substream, 4062306a36Sopenharmony_ci struct snd_soc_dai *dai) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci /* Reset the write pointer to the FIFO_INIT_ADDR */ 4562306a36Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL1, 4662306a36Sopenharmony_ci CTRL1_TODDR_FORCE_FINISH, 0); 4762306a36Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL1, 4862306a36Sopenharmony_ci CTRL1_TODDR_FORCE_FINISH, CTRL1_TODDR_FORCE_FINISH); 4962306a36Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL1, 5062306a36Sopenharmony_ci CTRL1_TODDR_FORCE_FINISH, 0); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci return 0; 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic int axg_toddr_dai_hw_params(struct snd_pcm_substream *substream, 5662306a36Sopenharmony_ci struct snd_pcm_hw_params *params, 5762306a36Sopenharmony_ci struct snd_soc_dai *dai) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 6062306a36Sopenharmony_ci unsigned int type, width; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci switch (params_physical_width(params)) { 6362306a36Sopenharmony_ci case 8: 6462306a36Sopenharmony_ci type = 0; /* 8 samples of 8 bits */ 6562306a36Sopenharmony_ci break; 6662306a36Sopenharmony_ci case 16: 6762306a36Sopenharmony_ci type = 2; /* 4 samples of 16 bits - right justified */ 6862306a36Sopenharmony_ci break; 6962306a36Sopenharmony_ci case 32: 7062306a36Sopenharmony_ci type = 4; /* 2 samples of 32 bits - right justified */ 7162306a36Sopenharmony_ci break; 7262306a36Sopenharmony_ci default: 7362306a36Sopenharmony_ci return -EINVAL; 7462306a36Sopenharmony_ci } 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci width = params_width(params); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, 7962306a36Sopenharmony_ci CTRL0_TODDR_TYPE_MASK | 8062306a36Sopenharmony_ci CTRL0_TODDR_MSB_POS_MASK | 8162306a36Sopenharmony_ci CTRL0_TODDR_LSB_POS_MASK, 8262306a36Sopenharmony_ci CTRL0_TODDR_TYPE(type) | 8362306a36Sopenharmony_ci CTRL0_TODDR_MSB_POS(TODDR_MSB_POS) | 8462306a36Sopenharmony_ci CTRL0_TODDR_LSB_POS(TODDR_MSB_POS - (width - 1))); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci return 0; 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic int axg_toddr_dai_startup(struct snd_pcm_substream *substream, 9062306a36Sopenharmony_ci struct snd_soc_dai *dai) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 9362306a36Sopenharmony_ci int ret; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci /* Enable pclk to access registers and clock the fifo ip */ 9662306a36Sopenharmony_ci ret = clk_prepare_enable(fifo->pclk); 9762306a36Sopenharmony_ci if (ret) 9862306a36Sopenharmony_ci return ret; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /* Select orginal data - resampling not supported ATM */ 10162306a36Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_SEL_RESAMPLE, 0); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci /* Only signed format are supported ATM */ 10462306a36Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_EXT_SIGNED, 10562306a36Sopenharmony_ci CTRL0_TODDR_EXT_SIGNED); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci /* Apply single buffer mode to the interface */ 10862306a36Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_PP_MODE, 0); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci return 0; 11162306a36Sopenharmony_ci} 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_cistatic void axg_toddr_dai_shutdown(struct snd_pcm_substream *substream, 11462306a36Sopenharmony_ci struct snd_soc_dai *dai) 11562306a36Sopenharmony_ci{ 11662306a36Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci clk_disable_unprepare(fifo->pclk); 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic const struct snd_soc_dai_ops axg_toddr_ops = { 12262306a36Sopenharmony_ci .hw_params = axg_toddr_dai_hw_params, 12362306a36Sopenharmony_ci .startup = axg_toddr_dai_startup, 12462306a36Sopenharmony_ci .shutdown = axg_toddr_dai_shutdown, 12562306a36Sopenharmony_ci .pcm_new = axg_toddr_pcm_new, 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic struct snd_soc_dai_driver axg_toddr_dai_drv = { 12962306a36Sopenharmony_ci .name = "TODDR", 13062306a36Sopenharmony_ci .capture = { 13162306a36Sopenharmony_ci .stream_name = "Capture", 13262306a36Sopenharmony_ci .channels_min = 1, 13362306a36Sopenharmony_ci .channels_max = AXG_FIFO_CH_MAX, 13462306a36Sopenharmony_ci .rates = AXG_FIFO_RATES, 13562306a36Sopenharmony_ci .formats = AXG_FIFO_FORMATS, 13662306a36Sopenharmony_ci }, 13762306a36Sopenharmony_ci .ops = &axg_toddr_ops, 13862306a36Sopenharmony_ci}; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistatic const char * const axg_toddr_sel_texts[] = { 14162306a36Sopenharmony_ci "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7" 14262306a36Sopenharmony_ci}; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(axg_toddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, 14562306a36Sopenharmony_ci axg_toddr_sel_texts); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistatic const struct snd_kcontrol_new axg_toddr_in_mux = 14862306a36Sopenharmony_ci SOC_DAPM_ENUM("Input Source", axg_toddr_sel_enum); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget axg_toddr_dapm_widgets[] = { 15162306a36Sopenharmony_ci SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &axg_toddr_in_mux), 15262306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), 15362306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), 15462306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), 15562306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), 15662306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), 15762306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0), 15862306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0), 15962306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0), 16062306a36Sopenharmony_ci}; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistatic const struct snd_soc_dapm_route axg_toddr_dapm_routes[] = { 16362306a36Sopenharmony_ci { "Capture", NULL, "SRC SEL" }, 16462306a36Sopenharmony_ci { "SRC SEL", "IN 0", "IN 0" }, 16562306a36Sopenharmony_ci { "SRC SEL", "IN 1", "IN 1" }, 16662306a36Sopenharmony_ci { "SRC SEL", "IN 2", "IN 2" }, 16762306a36Sopenharmony_ci { "SRC SEL", "IN 3", "IN 3" }, 16862306a36Sopenharmony_ci { "SRC SEL", "IN 4", "IN 4" }, 16962306a36Sopenharmony_ci { "SRC SEL", "IN 5", "IN 5" }, 17062306a36Sopenharmony_ci { "SRC SEL", "IN 6", "IN 6" }, 17162306a36Sopenharmony_ci { "SRC SEL", "IN 7", "IN 7" }, 17262306a36Sopenharmony_ci}; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic const struct snd_soc_component_driver axg_toddr_component_drv = { 17562306a36Sopenharmony_ci .dapm_widgets = axg_toddr_dapm_widgets, 17662306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(axg_toddr_dapm_widgets), 17762306a36Sopenharmony_ci .dapm_routes = axg_toddr_dapm_routes, 17862306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(axg_toddr_dapm_routes), 17962306a36Sopenharmony_ci .open = axg_fifo_pcm_open, 18062306a36Sopenharmony_ci .close = axg_fifo_pcm_close, 18162306a36Sopenharmony_ci .hw_params = axg_fifo_pcm_hw_params, 18262306a36Sopenharmony_ci .hw_free = axg_fifo_pcm_hw_free, 18362306a36Sopenharmony_ci .pointer = axg_fifo_pcm_pointer, 18462306a36Sopenharmony_ci .trigger = axg_fifo_pcm_trigger, 18562306a36Sopenharmony_ci .legacy_dai_naming = 1, 18662306a36Sopenharmony_ci}; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_cistatic const struct axg_fifo_match_data axg_toddr_match_data = { 18962306a36Sopenharmony_ci .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), 19062306a36Sopenharmony_ci .component_drv = &axg_toddr_component_drv, 19162306a36Sopenharmony_ci .dai_drv = &axg_toddr_dai_drv 19262306a36Sopenharmony_ci}; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_cistatic int g12a_toddr_dai_startup(struct snd_pcm_substream *substream, 19562306a36Sopenharmony_ci struct snd_soc_dai *dai) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 19862306a36Sopenharmony_ci int ret; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci ret = axg_toddr_dai_startup(substream, dai); 20162306a36Sopenharmony_ci if (ret) 20262306a36Sopenharmony_ci return ret; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci /* 20562306a36Sopenharmony_ci * Make sure the first channel ends up in the at beginning of the output 20662306a36Sopenharmony_ci * As weird as it looks, without this the first channel may be misplaced 20762306a36Sopenharmony_ci * in memory, with a random shift of 2 channels. 20862306a36Sopenharmony_ci */ 20962306a36Sopenharmony_ci regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_SYNC_CH, 21062306a36Sopenharmony_ci CTRL0_TODDR_SYNC_CH); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci return 0; 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistatic const struct snd_soc_dai_ops g12a_toddr_ops = { 21662306a36Sopenharmony_ci .prepare = g12a_toddr_dai_prepare, 21762306a36Sopenharmony_ci .hw_params = axg_toddr_dai_hw_params, 21862306a36Sopenharmony_ci .startup = g12a_toddr_dai_startup, 21962306a36Sopenharmony_ci .shutdown = axg_toddr_dai_shutdown, 22062306a36Sopenharmony_ci .pcm_new = axg_toddr_pcm_new, 22162306a36Sopenharmony_ci}; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_cistatic struct snd_soc_dai_driver g12a_toddr_dai_drv = { 22462306a36Sopenharmony_ci .name = "TODDR", 22562306a36Sopenharmony_ci .capture = { 22662306a36Sopenharmony_ci .stream_name = "Capture", 22762306a36Sopenharmony_ci .channels_min = 1, 22862306a36Sopenharmony_ci .channels_max = AXG_FIFO_CH_MAX, 22962306a36Sopenharmony_ci .rates = AXG_FIFO_RATES, 23062306a36Sopenharmony_ci .formats = AXG_FIFO_FORMATS, 23162306a36Sopenharmony_ci }, 23262306a36Sopenharmony_ci .ops = &g12a_toddr_ops, 23362306a36Sopenharmony_ci}; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic const struct snd_soc_component_driver g12a_toddr_component_drv = { 23662306a36Sopenharmony_ci .dapm_widgets = axg_toddr_dapm_widgets, 23762306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(axg_toddr_dapm_widgets), 23862306a36Sopenharmony_ci .dapm_routes = axg_toddr_dapm_routes, 23962306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(axg_toddr_dapm_routes), 24062306a36Sopenharmony_ci .open = axg_fifo_pcm_open, 24162306a36Sopenharmony_ci .close = axg_fifo_pcm_close, 24262306a36Sopenharmony_ci .hw_params = g12a_fifo_pcm_hw_params, 24362306a36Sopenharmony_ci .hw_free = axg_fifo_pcm_hw_free, 24462306a36Sopenharmony_ci .pointer = axg_fifo_pcm_pointer, 24562306a36Sopenharmony_ci .trigger = axg_fifo_pcm_trigger, 24662306a36Sopenharmony_ci .legacy_dai_naming = 1, 24762306a36Sopenharmony_ci}; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic const struct axg_fifo_match_data g12a_toddr_match_data = { 25062306a36Sopenharmony_ci .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), 25162306a36Sopenharmony_ci .component_drv = &g12a_toddr_component_drv, 25262306a36Sopenharmony_ci .dai_drv = &g12a_toddr_dai_drv 25362306a36Sopenharmony_ci}; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistatic const char * const sm1_toddr_sel_texts[] = { 25662306a36Sopenharmony_ci "IN 0", "IN 1", "IN 2", "IN 3", "IN 4", "IN 5", "IN 6", "IN 7", 25762306a36Sopenharmony_ci "IN 8", "IN 9", "IN 10", "IN 11", "IN 12", "IN 13", "IN 14", "IN 15" 25862306a36Sopenharmony_ci}; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(sm1_toddr_sel_enum, FIFO_CTRL1, CTRL1_SEL_SHIFT, 26162306a36Sopenharmony_ci sm1_toddr_sel_texts); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_cistatic const struct snd_kcontrol_new sm1_toddr_in_mux = 26462306a36Sopenharmony_ci SOC_DAPM_ENUM("Input Source", sm1_toddr_sel_enum); 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget sm1_toddr_dapm_widgets[] = { 26762306a36Sopenharmony_ci SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &sm1_toddr_in_mux), 26862306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), 26962306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), 27062306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), 27162306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), 27262306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), 27362306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 5", NULL, 0, SND_SOC_NOPM, 0, 0), 27462306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0), 27562306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 7", NULL, 0, SND_SOC_NOPM, 0, 0), 27662306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 8", NULL, 0, SND_SOC_NOPM, 0, 0), 27762306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 9", NULL, 0, SND_SOC_NOPM, 0, 0), 27862306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 10", NULL, 0, SND_SOC_NOPM, 0, 0), 27962306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 11", NULL, 0, SND_SOC_NOPM, 0, 0), 28062306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 12", NULL, 0, SND_SOC_NOPM, 0, 0), 28162306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 13", NULL, 0, SND_SOC_NOPM, 0, 0), 28262306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 14", NULL, 0, SND_SOC_NOPM, 0, 0), 28362306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("IN 15", NULL, 0, SND_SOC_NOPM, 0, 0), 28462306a36Sopenharmony_ci}; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_cistatic const struct snd_soc_dapm_route sm1_toddr_dapm_routes[] = { 28762306a36Sopenharmony_ci { "Capture", NULL, "SRC SEL" }, 28862306a36Sopenharmony_ci { "SRC SEL", "IN 0", "IN 0" }, 28962306a36Sopenharmony_ci { "SRC SEL", "IN 1", "IN 1" }, 29062306a36Sopenharmony_ci { "SRC SEL", "IN 2", "IN 2" }, 29162306a36Sopenharmony_ci { "SRC SEL", "IN 3", "IN 3" }, 29262306a36Sopenharmony_ci { "SRC SEL", "IN 4", "IN 4" }, 29362306a36Sopenharmony_ci { "SRC SEL", "IN 5", "IN 5" }, 29462306a36Sopenharmony_ci { "SRC SEL", "IN 6", "IN 6" }, 29562306a36Sopenharmony_ci { "SRC SEL", "IN 7", "IN 7" }, 29662306a36Sopenharmony_ci { "SRC SEL", "IN 8", "IN 8" }, 29762306a36Sopenharmony_ci { "SRC SEL", "IN 9", "IN 9" }, 29862306a36Sopenharmony_ci { "SRC SEL", "IN 10", "IN 10" }, 29962306a36Sopenharmony_ci { "SRC SEL", "IN 11", "IN 11" }, 30062306a36Sopenharmony_ci { "SRC SEL", "IN 12", "IN 12" }, 30162306a36Sopenharmony_ci { "SRC SEL", "IN 13", "IN 13" }, 30262306a36Sopenharmony_ci { "SRC SEL", "IN 14", "IN 14" }, 30362306a36Sopenharmony_ci { "SRC SEL", "IN 15", "IN 15" }, 30462306a36Sopenharmony_ci}; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_cistatic const struct snd_soc_component_driver sm1_toddr_component_drv = { 30762306a36Sopenharmony_ci .dapm_widgets = sm1_toddr_dapm_widgets, 30862306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(sm1_toddr_dapm_widgets), 30962306a36Sopenharmony_ci .dapm_routes = sm1_toddr_dapm_routes, 31062306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(sm1_toddr_dapm_routes), 31162306a36Sopenharmony_ci .open = axg_fifo_pcm_open, 31262306a36Sopenharmony_ci .close = axg_fifo_pcm_close, 31362306a36Sopenharmony_ci .hw_params = g12a_fifo_pcm_hw_params, 31462306a36Sopenharmony_ci .hw_free = axg_fifo_pcm_hw_free, 31562306a36Sopenharmony_ci .pointer = axg_fifo_pcm_pointer, 31662306a36Sopenharmony_ci .trigger = axg_fifo_pcm_trigger, 31762306a36Sopenharmony_ci .legacy_dai_naming = 1, 31862306a36Sopenharmony_ci}; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic const struct axg_fifo_match_data sm1_toddr_match_data = { 32162306a36Sopenharmony_ci .field_threshold = REG_FIELD(FIFO_CTRL1, 12, 23), 32262306a36Sopenharmony_ci .component_drv = &sm1_toddr_component_drv, 32362306a36Sopenharmony_ci .dai_drv = &g12a_toddr_dai_drv 32462306a36Sopenharmony_ci}; 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_cistatic const struct of_device_id axg_toddr_of_match[] = { 32762306a36Sopenharmony_ci { 32862306a36Sopenharmony_ci .compatible = "amlogic,axg-toddr", 32962306a36Sopenharmony_ci .data = &axg_toddr_match_data, 33062306a36Sopenharmony_ci }, { 33162306a36Sopenharmony_ci .compatible = "amlogic,g12a-toddr", 33262306a36Sopenharmony_ci .data = &g12a_toddr_match_data, 33362306a36Sopenharmony_ci }, { 33462306a36Sopenharmony_ci .compatible = "amlogic,sm1-toddr", 33562306a36Sopenharmony_ci .data = &sm1_toddr_match_data, 33662306a36Sopenharmony_ci }, {} 33762306a36Sopenharmony_ci}; 33862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, axg_toddr_of_match); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_cistatic struct platform_driver axg_toddr_pdrv = { 34162306a36Sopenharmony_ci .probe = axg_fifo_probe, 34262306a36Sopenharmony_ci .driver = { 34362306a36Sopenharmony_ci .name = "axg-toddr", 34462306a36Sopenharmony_ci .of_match_table = axg_toddr_of_match, 34562306a36Sopenharmony_ci }, 34662306a36Sopenharmony_ci}; 34762306a36Sopenharmony_cimodule_platform_driver(axg_toddr_pdrv); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ciMODULE_DESCRIPTION("Amlogic AXG capture fifo driver"); 35062306a36Sopenharmony_ciMODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 35162306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 352