linux/sound/soc/sunxi/sun4i-i2s.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2015 Andrea Venturi
 * Andrea Venturi <[email protected]>
 *
 * Copyright (C) 2016 Maxime Ripard
 * Maxime Ripard <[email protected]>
 */

#include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>

#include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>

#define SUN4I_I2S_CTRL_REG
#define SUN4I_I2S_CTRL_SDO_EN_MASK
#define SUN4I_I2S_CTRL_SDO_EN(sdo)
#define SUN4I_I2S_CTRL_MODE_MASK
#define SUN4I_I2S_CTRL_MODE_SLAVE
#define SUN4I_I2S_CTRL_MODE_MASTER
#define SUN4I_I2S_CTRL_TX_EN
#define SUN4I_I2S_CTRL_RX_EN
#define SUN4I_I2S_CTRL_GL_EN

#define SUN4I_I2S_FMT0_REG
#define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK
#define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED
#define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL
#define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK
#define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED
#define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL
#define SUN4I_I2S_FMT0_SR_MASK
#define SUN4I_I2S_FMT0_SR(sr)
#define SUN4I_I2S_FMT0_WSS_MASK
#define SUN4I_I2S_FMT0_WSS(wss)
#define SUN4I_I2S_FMT0_FMT_MASK
#define SUN4I_I2S_FMT0_FMT_RIGHT_J
#define SUN4I_I2S_FMT0_FMT_LEFT_J
#define SUN4I_I2S_FMT0_FMT_I2S

#define SUN4I_I2S_FMT1_REG
#define SUN4I_I2S_FMT1_REG_SEXT_MASK
#define SUN4I_I2S_FMT1_REG_SEXT(sext)

#define SUN4I_I2S_FIFO_TX_REG
#define SUN4I_I2S_FIFO_RX_REG

#define SUN4I_I2S_FIFO_CTRL_REG
#define SUN4I_I2S_FIFO_CTRL_FLUSH_TX
#define SUN4I_I2S_FIFO_CTRL_FLUSH_RX
#define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK
#define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode)
#define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK
#define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode)

#define SUN4I_I2S_FIFO_STA_REG

#define SUN4I_I2S_DMA_INT_CTRL_REG
#define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN
#define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN

#define SUN4I_I2S_INT_STA_REG

#define SUN4I_I2S_CLK_DIV_REG
#define SUN4I_I2S_CLK_DIV_MCLK_EN
#define SUN4I_I2S_CLK_DIV_BCLK_MASK
#define SUN4I_I2S_CLK_DIV_BCLK(bclk)
#define SUN4I_I2S_CLK_DIV_MCLK_MASK
#define SUN4I_I2S_CLK_DIV_MCLK(mclk)

#define SUN4I_I2S_TX_CNT_REG
#define SUN4I_I2S_RX_CNT_REG

#define SUN4I_I2S_TX_CHAN_SEL_REG
#define SUN4I_I2S_CHAN_SEL_MASK
#define SUN4I_I2S_CHAN_SEL(num_chan)

#define SUN4I_I2S_TX_CHAN_MAP_REG
#define SUN4I_I2S_TX_CHAN_MAP(chan, sample)

#define SUN4I_I2S_RX_CHAN_SEL_REG
#define SUN4I_I2S_RX_CHAN_MAP_REG

/* Defines required for sun8i-h3 support */
#define SUN8I_I2S_CTRL_BCLK_OUT
#define SUN8I_I2S_CTRL_LRCK_OUT

#define SUN8I_I2S_CTRL_MODE_MASK
#define SUN8I_I2S_CTRL_MODE_RIGHT
#define SUN8I_I2S_CTRL_MODE_LEFT
#define SUN8I_I2S_CTRL_MODE_PCM

#define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK
#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED
#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL
#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK
#define SUN8I_I2S_FMT0_LRCK_PERIOD(period)
#define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK
#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED
#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL

#define SUN8I_I2S_FMT1_REG_SEXT_MASK
#define SUN8I_I2S_FMT1_REG_SEXT(sext)

#define SUN8I_I2S_INT_STA_REG
#define SUN8I_I2S_FIFO_TX_REG

#define SUN8I_I2S_CHAN_CFG_REG
#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK
#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan)
#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK
#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan)

#define SUN8I_I2S_TX_CHAN_MAP_REG
#define SUN8I_I2S_TX_CHAN_SEL_REG
#define SUN8I_I2S_TX_CHAN_OFFSET_MASK
#define SUN8I_I2S_TX_CHAN_OFFSET(offset)
#define SUN8I_I2S_TX_CHAN_EN_MASK
#define SUN8I_I2S_TX_CHAN_EN(num_chan)

#define SUN8I_I2S_RX_CHAN_SEL_REG
#define SUN8I_I2S_RX_CHAN_MAP_REG

/* Defines required for sun50i-h6 support */
#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK
#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)
#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK
#define SUN50I_H6_I2S_TX_CHAN_SEL(chan)
#define SUN50I_H6_I2S_TX_CHAN_EN_MASK
#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan)

#define SUN50I_H6_I2S_TX_CHAN_SEL_REG(pin)
#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG(pin)
#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG(pin)

#define SUN50I_H6_I2S_RX_CHAN_SEL_REG
#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG
#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG

#define SUN50I_R329_I2S_RX_CHAN_MAP0_REG
#define SUN50I_R329_I2S_RX_CHAN_MAP1_REG
#define SUN50I_R329_I2S_RX_CHAN_MAP2_REG
#define SUN50I_R329_I2S_RX_CHAN_MAP3_REG

struct sun4i_i2s;

/**
 * struct sun4i_i2s_quirks - Differences between SoC variants.
 * @has_reset: SoC needs reset deasserted.
 * @pcm_formats: available PCM formats.
 * @reg_offset_txdata: offset of the tx fifo.
 * @sun4i_i2s_regmap: regmap config to use.
 * @field_clkdiv_mclk_en: regmap field to enable mclk output.
 * @field_fmt_wss: regmap field to set word select size.
 * @field_fmt_sr: regmap field to set sample resolution.
 * @num_din_pins: input pins
 * @num_dout_pins: output pins (currently set but unused)
 * @bclk_dividers: bit clock dividers array
 * @num_bclk_dividers: number of bit clock dividers
 * @mclk_dividers: mclk dividers array
 * @num_mclk_dividers: number of mclk dividers
 * @get_bclk_parent_rate: callback to get bclk parent rate
 * @get_sr: callback to get sample resolution
 * @get_wss: callback to get word select size
 * @set_chan_cfg: callback to set channel configuration
 * @set_fmt: callback to set format
 */
struct sun4i_i2s_quirks {};

struct sun4i_i2s {};

struct sun4i_i2s_clk_div {};

static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] =;

static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] =;

static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] =;

static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
{}

static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
{}

static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
				  unsigned long parent_rate,
				  unsigned int sampling_rate,
				  unsigned int channels,
				  unsigned int word_size)
{}

static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
				  unsigned long parent_rate,
				  unsigned long mclk_rate)
{}

static int sun4i_i2s_oversample_rates[] =;
static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
{}

static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
				  unsigned int rate,
				  unsigned int slots,
				  unsigned int slot_width)
{}

static int sun4i_i2s_get_sr(unsigned int width)
{}

static int sun4i_i2s_get_wss(unsigned int width)
{}

static int sun8i_i2s_get_sr_wss(unsigned int width)
{}

static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
				  unsigned int channels, unsigned int slots,
				  unsigned int slot_width)
{}

static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
				  unsigned int channels, unsigned int slots,
				  unsigned int slot_width)
{}

static int sun50i_h6_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
				      unsigned int channels, unsigned int slots,
				      unsigned int slot_width)
{}

static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
			       struct snd_pcm_hw_params *params,
			       struct snd_soc_dai *dai)
{}

static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
				 unsigned int fmt)
{}

static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
				 unsigned int fmt)
{}

static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
				     unsigned int fmt)
{}

static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{}

static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
{}

static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
{}

static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
{}

static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
{}

static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
			     struct snd_soc_dai *dai)
{}

static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
				unsigned int freq, int dir)
{}

static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai *dai,
				  unsigned int tx_mask, unsigned int rx_mask,
				  int slots, int slot_width)
{}

static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
{}

static int sun4i_i2s_dai_startup(struct snd_pcm_substream *sub, struct snd_soc_dai *dai)
{}

static const struct snd_soc_dai_ops sun4i_i2s_dai_ops =;

#define SUN4I_FORMATS_ALL

static struct snd_soc_dai_driver sun4i_i2s_dai =;

static const struct snd_soc_component_driver sun4i_i2s_component =;

static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
{}

static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
{}

static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
{}

static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
{}

static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
{}

static const struct reg_default sun4i_i2s_reg_defaults[] =;

static const struct reg_default sun8i_i2s_reg_defaults[] =;

static const struct reg_default sun50i_h6_i2s_reg_defaults[] =;

static const struct regmap_config sun4i_i2s_regmap_config =;

static const struct regmap_config sun8i_i2s_regmap_config =;

static const struct regmap_config sun50i_h6_i2s_regmap_config =;

static int sun4i_i2s_runtime_resume(struct device *dev)
{}

static int sun4i_i2s_runtime_suspend(struct device *dev)
{}

#define SUN4I_FORMATS_A10
#define SUN4I_FORMATS_H3

static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks =;

static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks =;

/*
 * This doesn't describe the TDM controller documented in the A83t
 * datasheet, but the three undocumented I2S controller that use the
 * older design.
 */
static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks =;

static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks =;

static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks =;

static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks =;

static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks =;

static int sun4i_i2s_init_regmap_fields(struct device *dev,
					struct sun4i_i2s *i2s)
{}

static int sun4i_i2s_probe(struct platform_device *pdev)
{}

static void sun4i_i2s_remove(struct platform_device *pdev)
{}

static const struct of_device_id sun4i_i2s_match[] =;
MODULE_DEVICE_TABLE(of, sun4i_i2s_match);

static const struct dev_pm_ops sun4i_i2s_pm_ops =;

static struct platform_driver sun4i_i2s_driver =;
module_platform_driver();

MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();