cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sun4i-i2s.c (45534B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) 2015 Andrea Venturi
      4 * Andrea Venturi <be17068@iperbole.bo.it>
      5 *
      6 * Copyright (C) 2016 Maxime Ripard
      7 * Maxime Ripard <maxime.ripard@free-electrons.com>
      8 */
      9
     10#include <linux/clk.h>
     11#include <linux/dmaengine.h>
     12#include <linux/module.h>
     13#include <linux/of_device.h>
     14#include <linux/platform_device.h>
     15#include <linux/pm_runtime.h>
     16#include <linux/regmap.h>
     17#include <linux/reset.h>
     18
     19#include <sound/dmaengine_pcm.h>
     20#include <sound/pcm_params.h>
     21#include <sound/soc.h>
     22#include <sound/soc-dai.h>
     23
     24#define SUN4I_I2S_CTRL_REG		0x00
     25#define SUN4I_I2S_CTRL_SDO_EN_MASK		GENMASK(11, 8)
     26#define SUN4I_I2S_CTRL_SDO_EN(sdo)			BIT(8 + (sdo))
     27#define SUN4I_I2S_CTRL_MODE_MASK		BIT(5)
     28#define SUN4I_I2S_CTRL_MODE_SLAVE			(1 << 5)
     29#define SUN4I_I2S_CTRL_MODE_MASTER			(0 << 5)
     30#define SUN4I_I2S_CTRL_TX_EN			BIT(2)
     31#define SUN4I_I2S_CTRL_RX_EN			BIT(1)
     32#define SUN4I_I2S_CTRL_GL_EN			BIT(0)
     33
     34#define SUN4I_I2S_FMT0_REG		0x04
     35#define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK	BIT(7)
     36#define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED		(1 << 7)
     37#define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL		(0 << 7)
     38#define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK	BIT(6)
     39#define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED		(1 << 6)
     40#define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL		(0 << 6)
     41#define SUN4I_I2S_FMT0_SR_MASK			GENMASK(5, 4)
     42#define SUN4I_I2S_FMT0_SR(sr)				((sr) << 4)
     43#define SUN4I_I2S_FMT0_WSS_MASK			GENMASK(3, 2)
     44#define SUN4I_I2S_FMT0_WSS(wss)				((wss) << 2)
     45#define SUN4I_I2S_FMT0_FMT_MASK			GENMASK(1, 0)
     46#define SUN4I_I2S_FMT0_FMT_RIGHT_J			(2 << 0)
     47#define SUN4I_I2S_FMT0_FMT_LEFT_J			(1 << 0)
     48#define SUN4I_I2S_FMT0_FMT_I2S				(0 << 0)
     49
     50#define SUN4I_I2S_FMT1_REG		0x08
     51#define SUN4I_I2S_FMT1_REG_SEXT_MASK		BIT(8)
     52#define SUN4I_I2S_FMT1_REG_SEXT(sext)			((sext) << 8)
     53
     54#define SUN4I_I2S_FIFO_TX_REG		0x0c
     55#define SUN4I_I2S_FIFO_RX_REG		0x10
     56
     57#define SUN4I_I2S_FIFO_CTRL_REG		0x14
     58#define SUN4I_I2S_FIFO_CTRL_FLUSH_TX		BIT(25)
     59#define SUN4I_I2S_FIFO_CTRL_FLUSH_RX		BIT(24)
     60#define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK	BIT(2)
     61#define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode)		((mode) << 2)
     62#define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK	GENMASK(1, 0)
     63#define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode)		(mode)
     64
     65#define SUN4I_I2S_FIFO_STA_REG		0x18
     66
     67#define SUN4I_I2S_DMA_INT_CTRL_REG	0x1c
     68#define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN	BIT(7)
     69#define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN	BIT(3)
     70
     71#define SUN4I_I2S_INT_STA_REG		0x20
     72
     73#define SUN4I_I2S_CLK_DIV_REG		0x24
     74#define SUN4I_I2S_CLK_DIV_MCLK_EN		BIT(7)
     75#define SUN4I_I2S_CLK_DIV_BCLK_MASK		GENMASK(6, 4)
     76#define SUN4I_I2S_CLK_DIV_BCLK(bclk)			((bclk) << 4)
     77#define SUN4I_I2S_CLK_DIV_MCLK_MASK		GENMASK(3, 0)
     78#define SUN4I_I2S_CLK_DIV_MCLK(mclk)			((mclk) << 0)
     79
     80#define SUN4I_I2S_TX_CNT_REG		0x28
     81#define SUN4I_I2S_RX_CNT_REG		0x2c
     82
     83#define SUN4I_I2S_TX_CHAN_SEL_REG	0x30
     84#define SUN4I_I2S_CHAN_SEL_MASK			GENMASK(2, 0)
     85#define SUN4I_I2S_CHAN_SEL(num_chan)		(((num_chan) - 1) << 0)
     86
     87#define SUN4I_I2S_TX_CHAN_MAP_REG	0x34
     88#define SUN4I_I2S_TX_CHAN_MAP(chan, sample)	((sample) << (chan << 2))
     89
     90#define SUN4I_I2S_RX_CHAN_SEL_REG	0x38
     91#define SUN4I_I2S_RX_CHAN_MAP_REG	0x3c
     92
     93/* Defines required for sun8i-h3 support */
     94#define SUN8I_I2S_CTRL_BCLK_OUT			BIT(18)
     95#define SUN8I_I2S_CTRL_LRCK_OUT			BIT(17)
     96
     97#define SUN8I_I2S_CTRL_MODE_MASK		GENMASK(5, 4)
     98#define SUN8I_I2S_CTRL_MODE_RIGHT		(2 << 4)
     99#define SUN8I_I2S_CTRL_MODE_LEFT		(1 << 4)
    100#define SUN8I_I2S_CTRL_MODE_PCM			(0 << 4)
    101
    102#define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK	BIT(19)
    103#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED		(1 << 19)
    104#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL		(0 << 19)
    105#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK		GENMASK(17, 8)
    106#define SUN8I_I2S_FMT0_LRCK_PERIOD(period)	((period - 1) << 8)
    107#define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK	BIT(7)
    108#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED		(1 << 7)
    109#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL		(0 << 7)
    110
    111#define SUN8I_I2S_FMT1_REG_SEXT_MASK		GENMASK(5, 4)
    112#define SUN8I_I2S_FMT1_REG_SEXT(sext)			((sext) << 4)
    113
    114#define SUN8I_I2S_INT_STA_REG		0x0c
    115#define SUN8I_I2S_FIFO_TX_REG		0x20
    116
    117#define SUN8I_I2S_CHAN_CFG_REG		0x30
    118#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK	GENMASK(7, 4)
    119#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan)	((chan - 1) << 4)
    120#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK	GENMASK(3, 0)
    121#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan)	(chan - 1)
    122
    123#define SUN8I_I2S_TX_CHAN_MAP_REG	0x44
    124#define SUN8I_I2S_TX_CHAN_SEL_REG	0x34
    125#define SUN8I_I2S_TX_CHAN_OFFSET_MASK		GENMASK(13, 12)
    126#define SUN8I_I2S_TX_CHAN_OFFSET(offset)	(offset << 12)
    127#define SUN8I_I2S_TX_CHAN_EN_MASK		GENMASK(11, 4)
    128#define SUN8I_I2S_TX_CHAN_EN(num_chan)		(((1 << num_chan) - 1) << 4)
    129
    130#define SUN8I_I2S_RX_CHAN_SEL_REG	0x54
    131#define SUN8I_I2S_RX_CHAN_MAP_REG	0x58
    132
    133/* Defines required for sun50i-h6 support */
    134#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK	GENMASK(21, 20)
    135#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)	((offset) << 20)
    136#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK		GENMASK(19, 16)
    137#define SUN50I_H6_I2S_TX_CHAN_SEL(chan)		((chan - 1) << 16)
    138#define SUN50I_H6_I2S_TX_CHAN_EN_MASK		GENMASK(15, 0)
    139#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan)	(((1 << num_chan) - 1))
    140
    141#define SUN50I_H6_I2S_TX_CHAN_SEL_REG(pin)	(0x34 + 4 * (pin))
    142#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG(pin)	(0x44 + 8 * (pin))
    143#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG(pin)	(0x48 + 8 * (pin))
    144
    145#define SUN50I_H6_I2S_RX_CHAN_SEL_REG	0x64
    146#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG	0x68
    147#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG	0x6C
    148
    149#define SUN50I_R329_I2S_RX_CHAN_MAP0_REG 0x68
    150#define SUN50I_R329_I2S_RX_CHAN_MAP1_REG 0x6c
    151#define SUN50I_R329_I2S_RX_CHAN_MAP2_REG 0x70
    152#define SUN50I_R329_I2S_RX_CHAN_MAP3_REG 0x74
    153
    154struct sun4i_i2s;
    155
    156/**
    157 * struct sun4i_i2s_quirks - Differences between SoC variants.
    158 * @has_reset: SoC needs reset deasserted.
    159 * @reg_offset_txdata: offset of the tx fifo.
    160 * @sun4i_i2s_regmap: regmap config to use.
    161 * @field_clkdiv_mclk_en: regmap field to enable mclk output.
    162 * @field_fmt_wss: regmap field to set word select size.
    163 * @field_fmt_sr: regmap field to set sample resolution.
    164 * @bclk_dividers: bit clock dividers array
    165 * @num_bclk_dividers: number of bit clock dividers
    166 * @mclk_dividers: mclk dividers array
    167 * @num_mclk_dividers: number of mclk dividers
    168 * @get_bclk_parent_rate: callback to get bclk parent rate
    169 * @get_sr: callback to get sample resolution
    170 * @get_wss: callback to get word select size
    171 * @set_chan_cfg: callback to set channel configuration
    172 * @set_fmt: callback to set format
    173 */
    174struct sun4i_i2s_quirks {
    175	bool				has_reset;
    176	unsigned int			reg_offset_txdata;	/* TX FIFO */
    177	const struct regmap_config	*sun4i_i2s_regmap;
    178
    179	/* Register fields for i2s */
    180	struct reg_field		field_clkdiv_mclk_en;
    181	struct reg_field		field_fmt_wss;
    182	struct reg_field		field_fmt_sr;
    183
    184	unsigned int			num_din_pins;
    185	unsigned int			num_dout_pins;
    186
    187	const struct sun4i_i2s_clk_div	*bclk_dividers;
    188	unsigned int			num_bclk_dividers;
    189	const struct sun4i_i2s_clk_div	*mclk_dividers;
    190	unsigned int			num_mclk_dividers;
    191
    192	unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *i2s);
    193	int	(*get_sr)(unsigned int width);
    194	int	(*get_wss)(unsigned int width);
    195
    196	/*
    197	 * In the set_chan_cfg() function pointer:
    198	 * @slots: channels per frame + padding slots, regardless of format
    199	 * @slot_width: bits per sample + padding bits, regardless of format
    200	 */
    201	int	(*set_chan_cfg)(const struct sun4i_i2s *i2s,
    202				unsigned int channels,	unsigned int slots,
    203				unsigned int slot_width);
    204	int	(*set_fmt)(const struct sun4i_i2s *i2s, unsigned int fmt);
    205};
    206
    207struct sun4i_i2s {
    208	struct clk	*bus_clk;
    209	struct clk	*mod_clk;
    210	struct regmap	*regmap;
    211	struct reset_control *rst;
    212
    213	unsigned int	format;
    214	unsigned int	mclk_freq;
    215	unsigned int	slots;
    216	unsigned int	slot_width;
    217
    218	struct snd_dmaengine_dai_dma_data	capture_dma_data;
    219	struct snd_dmaengine_dai_dma_data	playback_dma_data;
    220
    221	/* Register fields for i2s */
    222	struct regmap_field	*field_clkdiv_mclk_en;
    223	struct regmap_field	*field_fmt_wss;
    224	struct regmap_field	*field_fmt_sr;
    225
    226	const struct sun4i_i2s_quirks	*variant;
    227};
    228
    229struct sun4i_i2s_clk_div {
    230	u8	div;
    231	u8	val;
    232};
    233
    234static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
    235	{ .div = 2, .val = 0 },
    236	{ .div = 4, .val = 1 },
    237	{ .div = 6, .val = 2 },
    238	{ .div = 8, .val = 3 },
    239	{ .div = 12, .val = 4 },
    240	{ .div = 16, .val = 5 },
    241	/* TODO - extend divide ratio supported by newer SoCs */
    242};
    243
    244static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
    245	{ .div = 1, .val = 0 },
    246	{ .div = 2, .val = 1 },
    247	{ .div = 4, .val = 2 },
    248	{ .div = 6, .val = 3 },
    249	{ .div = 8, .val = 4 },
    250	{ .div = 12, .val = 5 },
    251	{ .div = 16, .val = 6 },
    252	{ .div = 24, .val = 7 },
    253	/* TODO - extend divide ratio supported by newer SoCs */
    254};
    255
    256static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
    257	{ .div = 1, .val = 1 },
    258	{ .div = 2, .val = 2 },
    259	{ .div = 4, .val = 3 },
    260	{ .div = 6, .val = 4 },
    261	{ .div = 8, .val = 5 },
    262	{ .div = 12, .val = 6 },
    263	{ .div = 16, .val = 7 },
    264	{ .div = 24, .val = 8 },
    265	{ .div = 32, .val = 9 },
    266	{ .div = 48, .val = 10 },
    267	{ .div = 64, .val = 11 },
    268	{ .div = 96, .val = 12 },
    269	{ .div = 128, .val = 13 },
    270	{ .div = 176, .val = 14 },
    271	{ .div = 192, .val = 15 },
    272};
    273
    274static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
    275{
    276	return i2s->mclk_freq;
    277}
    278
    279static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
    280{
    281	return clk_get_rate(i2s->mod_clk);
    282}
    283
    284static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
    285				  unsigned long parent_rate,
    286				  unsigned int sampling_rate,
    287				  unsigned int channels,
    288				  unsigned int word_size)
    289{
    290	const struct sun4i_i2s_clk_div *dividers = i2s->variant->bclk_dividers;
    291	int div = parent_rate / sampling_rate / word_size / channels;
    292	int i;
    293
    294	for (i = 0; i < i2s->variant->num_bclk_dividers; i++) {
    295		const struct sun4i_i2s_clk_div *bdiv = &dividers[i];
    296
    297		if (bdiv->div == div)
    298			return bdiv->val;
    299	}
    300
    301	return -EINVAL;
    302}
    303
    304static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
    305				  unsigned long parent_rate,
    306				  unsigned long mclk_rate)
    307{
    308	const struct sun4i_i2s_clk_div *dividers = i2s->variant->mclk_dividers;
    309	int div = parent_rate / mclk_rate;
    310	int i;
    311
    312	for (i = 0; i < i2s->variant->num_mclk_dividers; i++) {
    313		const struct sun4i_i2s_clk_div *mdiv = &dividers[i];
    314
    315		if (mdiv->div == div)
    316			return mdiv->val;
    317	}
    318
    319	return -EINVAL;
    320}
    321
    322static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
    323static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
    324{
    325	int i;
    326
    327	for (i = 0; i < ARRAY_SIZE(sun4i_i2s_oversample_rates); i++)
    328		if (sun4i_i2s_oversample_rates[i] == oversample)
    329			return true;
    330
    331	return false;
    332}
    333
    334static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
    335				  unsigned int rate,
    336				  unsigned int slots,
    337				  unsigned int slot_width)
    338{
    339	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
    340	unsigned int oversample_rate, clk_rate, bclk_parent_rate;
    341	int bclk_div, mclk_div;
    342	int ret;
    343
    344	switch (rate) {
    345	case 176400:
    346	case 88200:
    347	case 44100:
    348	case 22050:
    349	case 11025:
    350		clk_rate = 22579200;
    351		break;
    352
    353	case 192000:
    354	case 128000:
    355	case 96000:
    356	case 64000:
    357	case 48000:
    358	case 32000:
    359	case 24000:
    360	case 16000:
    361	case 12000:
    362	case 8000:
    363		clk_rate = 24576000;
    364		break;
    365
    366	default:
    367		dev_err(dai->dev, "Unsupported sample rate: %u\n", rate);
    368		return -EINVAL;
    369	}
    370
    371	ret = clk_set_rate(i2s->mod_clk, clk_rate);
    372	if (ret)
    373		return ret;
    374
    375	oversample_rate = i2s->mclk_freq / rate;
    376	if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
    377		dev_err(dai->dev, "Unsupported oversample rate: %d\n",
    378			oversample_rate);
    379		return -EINVAL;
    380	}
    381
    382	bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s);
    383	bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate,
    384					  rate, slots, slot_width);
    385	if (bclk_div < 0) {
    386		dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
    387		return -EINVAL;
    388	}
    389
    390	mclk_div = sun4i_i2s_get_mclk_div(i2s, clk_rate, i2s->mclk_freq);
    391	if (mclk_div < 0) {
    392		dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div);
    393		return -EINVAL;
    394	}
    395
    396	regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
    397		     SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
    398		     SUN4I_I2S_CLK_DIV_MCLK(mclk_div));
    399
    400	regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
    401
    402	return 0;
    403}
    404
    405static int sun4i_i2s_get_sr(unsigned int width)
    406{
    407	switch (width) {
    408	case 16:
    409		return 0;
    410	case 20:
    411		return 1;
    412	case 24:
    413		return 2;
    414	}
    415
    416	return -EINVAL;
    417}
    418
    419static int sun4i_i2s_get_wss(unsigned int width)
    420{
    421	switch (width) {
    422	case 16:
    423		return 0;
    424	case 20:
    425		return 1;
    426	case 24:
    427		return 2;
    428	case 32:
    429		return 3;
    430	}
    431
    432	return -EINVAL;
    433}
    434
    435static int sun8i_i2s_get_sr_wss(unsigned int width)
    436{
    437	switch (width) {
    438	case 8:
    439		return 1;
    440	case 12:
    441		return 2;
    442	case 16:
    443		return 3;
    444	case 20:
    445		return 4;
    446	case 24:
    447		return 5;
    448	case 28:
    449		return 6;
    450	case 32:
    451		return 7;
    452	}
    453
    454	return -EINVAL;
    455}
    456
    457static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
    458				  unsigned int channels, unsigned int slots,
    459				  unsigned int slot_width)
    460{
    461	/* Map the channels for playback and capture */
    462	regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210);
    463	regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210);
    464
    465	/* Configure the channels */
    466	regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
    467			   SUN4I_I2S_CHAN_SEL_MASK,
    468			   SUN4I_I2S_CHAN_SEL(channels));
    469	regmap_update_bits(i2s->regmap, SUN4I_I2S_RX_CHAN_SEL_REG,
    470			   SUN4I_I2S_CHAN_SEL_MASK,
    471			   SUN4I_I2S_CHAN_SEL(channels));
    472
    473	return 0;
    474}
    475
    476static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
    477				  unsigned int channels, unsigned int slots,
    478				  unsigned int slot_width)
    479{
    480	unsigned int lrck_period;
    481
    482	/* Map the channels for playback and capture */
    483	regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210);
    484	regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210);
    485
    486	/* Configure the channels */
    487	regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
    488			   SUN4I_I2S_CHAN_SEL_MASK,
    489			   SUN4I_I2S_CHAN_SEL(channels));
    490	regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
    491			   SUN4I_I2S_CHAN_SEL_MASK,
    492			   SUN4I_I2S_CHAN_SEL(channels));
    493
    494	regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
    495			   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
    496			   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
    497	regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
    498			   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
    499			   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
    500
    501	switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
    502	case SND_SOC_DAIFMT_DSP_A:
    503	case SND_SOC_DAIFMT_DSP_B:
    504		lrck_period = slot_width * slots;
    505		break;
    506
    507	case SND_SOC_DAIFMT_LEFT_J:
    508	case SND_SOC_DAIFMT_RIGHT_J:
    509	case SND_SOC_DAIFMT_I2S:
    510		lrck_period = slot_width;
    511		break;
    512
    513	default:
    514		return -EINVAL;
    515	}
    516
    517	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
    518			   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
    519			   SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
    520
    521	regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
    522			   SUN8I_I2S_TX_CHAN_EN_MASK,
    523			   SUN8I_I2S_TX_CHAN_EN(channels));
    524
    525	return 0;
    526}
    527
    528static int sun50i_h6_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
    529				      unsigned int channels, unsigned int slots,
    530				      unsigned int slot_width)
    531{
    532	unsigned int lrck_period;
    533
    534	/* Map the channels for playback and capture */
    535	regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0xFEDCBA98);
    536	regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x76543210);
    537	if (i2s->variant->num_din_pins > 1) {
    538		regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP0_REG, 0x0F0E0D0C);
    539		regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP1_REG, 0x0B0A0908);
    540		regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP2_REG, 0x07060504);
    541		regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP3_REG, 0x03020100);
    542	} else {
    543		regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0xFEDCBA98);
    544		regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x76543210);
    545	}
    546
    547	/* Configure the channels */
    548	regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
    549			   SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
    550			   SUN50I_H6_I2S_TX_CHAN_SEL(channels));
    551	regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
    552			   SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
    553			   SUN50I_H6_I2S_TX_CHAN_SEL(channels));
    554
    555	regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
    556			   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
    557			   SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
    558	regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
    559			   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
    560			   SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
    561
    562	switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
    563	case SND_SOC_DAIFMT_DSP_A:
    564	case SND_SOC_DAIFMT_DSP_B:
    565		lrck_period = slot_width * slots;
    566		break;
    567
    568	case SND_SOC_DAIFMT_LEFT_J:
    569	case SND_SOC_DAIFMT_RIGHT_J:
    570	case SND_SOC_DAIFMT_I2S:
    571		lrck_period = slot_width;
    572		break;
    573
    574	default:
    575		return -EINVAL;
    576	}
    577
    578	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
    579			   SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
    580			   SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
    581
    582	regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
    583			   SUN50I_H6_I2S_TX_CHAN_EN_MASK,
    584			   SUN50I_H6_I2S_TX_CHAN_EN(channels));
    585
    586	return 0;
    587}
    588
    589static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
    590			       struct snd_pcm_hw_params *params,
    591			       struct snd_soc_dai *dai)
    592{
    593	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
    594	unsigned int word_size = params_width(params);
    595	unsigned int slot_width = params_physical_width(params);
    596	unsigned int channels = params_channels(params);
    597
    598	unsigned int slots = channels;
    599
    600	int ret, sr, wss;
    601	u32 width;
    602
    603	if (i2s->slots)
    604		slots = i2s->slots;
    605
    606	if (i2s->slot_width)
    607		slot_width = i2s->slot_width;
    608
    609	ret = i2s->variant->set_chan_cfg(i2s, channels, slots, slot_width);
    610	if (ret < 0) {
    611		dev_err(dai->dev, "Invalid channel configuration\n");
    612		return ret;
    613	}
    614
    615	/* Set significant bits in our FIFOs */
    616	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
    617			   SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
    618			   SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
    619			   SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
    620			   SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
    621
    622	switch (params_physical_width(params)) {
    623	case 16:
    624		width = DMA_SLAVE_BUSWIDTH_2_BYTES;
    625		break;
    626	case 32:
    627		width = DMA_SLAVE_BUSWIDTH_4_BYTES;
    628		break;
    629	default:
    630		dev_err(dai->dev, "Unsupported physical sample width: %d\n",
    631			params_physical_width(params));
    632		return -EINVAL;
    633	}
    634	i2s->playback_dma_data.addr_width = width;
    635
    636	sr = i2s->variant->get_sr(word_size);
    637	if (sr < 0)
    638		return -EINVAL;
    639
    640	wss = i2s->variant->get_wss(slot_width);
    641	if (wss < 0)
    642		return -EINVAL;
    643
    644	regmap_field_write(i2s->field_fmt_wss, wss);
    645	regmap_field_write(i2s->field_fmt_sr, sr);
    646
    647	return sun4i_i2s_set_clk_rate(dai, params_rate(params),
    648				      slots, slot_width);
    649}
    650
    651static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
    652				 unsigned int fmt)
    653{
    654	u32 val;
    655
    656	/* DAI clock polarity */
    657	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    658	case SND_SOC_DAIFMT_IB_IF:
    659		/* Invert both clocks */
    660		val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
    661		      SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
    662		break;
    663	case SND_SOC_DAIFMT_IB_NF:
    664		/* Invert bit clock */
    665		val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED;
    666		break;
    667	case SND_SOC_DAIFMT_NB_IF:
    668		/* Invert frame clock */
    669		val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
    670		break;
    671	case SND_SOC_DAIFMT_NB_NF:
    672		val = 0;
    673		break;
    674	default:
    675		return -EINVAL;
    676	}
    677
    678	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
    679			   SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK |
    680			   SUN4I_I2S_FMT0_BCLK_POLARITY_MASK,
    681			   val);
    682
    683	/* DAI Mode */
    684	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    685	case SND_SOC_DAIFMT_I2S:
    686		val = SUN4I_I2S_FMT0_FMT_I2S;
    687		break;
    688
    689	case SND_SOC_DAIFMT_LEFT_J:
    690		val = SUN4I_I2S_FMT0_FMT_LEFT_J;
    691		break;
    692
    693	case SND_SOC_DAIFMT_RIGHT_J:
    694		val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
    695		break;
    696
    697	default:
    698		return -EINVAL;
    699	}
    700
    701	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
    702			   SUN4I_I2S_FMT0_FMT_MASK, val);
    703
    704	/* DAI clock master masks */
    705	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
    706	case SND_SOC_DAIFMT_CBS_CFS:
    707		/* BCLK and LRCLK master */
    708		val = SUN4I_I2S_CTRL_MODE_MASTER;
    709		break;
    710
    711	case SND_SOC_DAIFMT_CBM_CFM:
    712		/* BCLK and LRCLK slave */
    713		val = SUN4I_I2S_CTRL_MODE_SLAVE;
    714		break;
    715
    716	default:
    717		return -EINVAL;
    718	}
    719	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
    720			   SUN4I_I2S_CTRL_MODE_MASK, val);
    721
    722	return 0;
    723}
    724
    725static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
    726				 unsigned int fmt)
    727{
    728	u32 mode, val;
    729	u8 offset;
    730
    731	/*
    732	 * DAI clock polarity
    733	 *
    734	 * The setup for LRCK contradicts the datasheet, but under a
    735	 * scope it's clear that the LRCK polarity is reversed
    736	 * compared to the expected polarity on the bus.
    737	 */
    738	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    739	case SND_SOC_DAIFMT_IB_IF:
    740		/* Invert both clocks */
    741		val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
    742		break;
    743	case SND_SOC_DAIFMT_IB_NF:
    744		/* Invert bit clock */
    745		val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
    746		      SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
    747		break;
    748	case SND_SOC_DAIFMT_NB_IF:
    749		/* Invert frame clock */
    750		val = 0;
    751		break;
    752	case SND_SOC_DAIFMT_NB_NF:
    753		val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
    754		break;
    755	default:
    756		return -EINVAL;
    757	}
    758
    759	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
    760			   SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
    761			   SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
    762			   val);
    763
    764	/* DAI Mode */
    765	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    766	case SND_SOC_DAIFMT_DSP_A:
    767		mode = SUN8I_I2S_CTRL_MODE_PCM;
    768		offset = 1;
    769		break;
    770
    771	case SND_SOC_DAIFMT_DSP_B:
    772		mode = SUN8I_I2S_CTRL_MODE_PCM;
    773		offset = 0;
    774		break;
    775
    776	case SND_SOC_DAIFMT_I2S:
    777		mode = SUN8I_I2S_CTRL_MODE_LEFT;
    778		offset = 1;
    779		break;
    780
    781	case SND_SOC_DAIFMT_LEFT_J:
    782		mode = SUN8I_I2S_CTRL_MODE_LEFT;
    783		offset = 0;
    784		break;
    785
    786	case SND_SOC_DAIFMT_RIGHT_J:
    787		mode = SUN8I_I2S_CTRL_MODE_RIGHT;
    788		offset = 0;
    789		break;
    790
    791	default:
    792		return -EINVAL;
    793	}
    794
    795	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
    796			   SUN8I_I2S_CTRL_MODE_MASK, mode);
    797	regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
    798			   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
    799			   SUN8I_I2S_TX_CHAN_OFFSET(offset));
    800	regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
    801			   SUN8I_I2S_TX_CHAN_OFFSET_MASK,
    802			   SUN8I_I2S_TX_CHAN_OFFSET(offset));
    803
    804	/* DAI clock master masks */
    805	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
    806	case SND_SOC_DAIFMT_CBS_CFS:
    807		/* BCLK and LRCLK master */
    808		val = SUN8I_I2S_CTRL_BCLK_OUT |	SUN8I_I2S_CTRL_LRCK_OUT;
    809		break;
    810
    811	case SND_SOC_DAIFMT_CBM_CFM:
    812		/* BCLK and LRCLK slave */
    813		val = 0;
    814		break;
    815
    816	default:
    817		return -EINVAL;
    818	}
    819
    820	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
    821			   SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
    822			   val);
    823
    824	/* Set sign extension to pad out LSB with 0 */
    825	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
    826			   SUN8I_I2S_FMT1_REG_SEXT_MASK,
    827			   SUN8I_I2S_FMT1_REG_SEXT(0));
    828
    829	return 0;
    830}
    831
    832static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
    833				     unsigned int fmt)
    834{
    835	u32 mode, val;
    836	u8 offset;
    837
    838	/*
    839	 * DAI clock polarity
    840	 *
    841	 * The setup for LRCK contradicts the datasheet, but under a
    842	 * scope it's clear that the LRCK polarity is reversed
    843	 * compared to the expected polarity on the bus.
    844	 */
    845	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    846	case SND_SOC_DAIFMT_IB_IF:
    847		/* Invert both clocks */
    848		val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
    849		break;
    850	case SND_SOC_DAIFMT_IB_NF:
    851		/* Invert bit clock */
    852		val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
    853		      SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
    854		break;
    855	case SND_SOC_DAIFMT_NB_IF:
    856		/* Invert frame clock */
    857		val = 0;
    858		break;
    859	case SND_SOC_DAIFMT_NB_NF:
    860		val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
    861		break;
    862	default:
    863		return -EINVAL;
    864	}
    865
    866	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
    867			   SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
    868			   SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
    869			   val);
    870
    871	/* DAI Mode */
    872	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    873	case SND_SOC_DAIFMT_DSP_A:
    874		mode = SUN8I_I2S_CTRL_MODE_PCM;
    875		offset = 1;
    876		break;
    877
    878	case SND_SOC_DAIFMT_DSP_B:
    879		mode = SUN8I_I2S_CTRL_MODE_PCM;
    880		offset = 0;
    881		break;
    882
    883	case SND_SOC_DAIFMT_I2S:
    884		mode = SUN8I_I2S_CTRL_MODE_LEFT;
    885		offset = 1;
    886		break;
    887
    888	case SND_SOC_DAIFMT_LEFT_J:
    889		mode = SUN8I_I2S_CTRL_MODE_LEFT;
    890		offset = 0;
    891		break;
    892
    893	case SND_SOC_DAIFMT_RIGHT_J:
    894		mode = SUN8I_I2S_CTRL_MODE_RIGHT;
    895		offset = 0;
    896		break;
    897
    898	default:
    899		return -EINVAL;
    900	}
    901
    902	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
    903			   SUN8I_I2S_CTRL_MODE_MASK, mode);
    904	regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
    905			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
    906			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
    907	regmap_update_bits(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_SEL_REG,
    908			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
    909			   SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset));
    910
    911	/* DAI clock master masks */
    912	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
    913	case SND_SOC_DAIFMT_CBS_CFS:
    914		/* BCLK and LRCLK master */
    915		val = SUN8I_I2S_CTRL_BCLK_OUT |	SUN8I_I2S_CTRL_LRCK_OUT;
    916		break;
    917
    918	case SND_SOC_DAIFMT_CBM_CFM:
    919		/* BCLK and LRCLK slave */
    920		val = 0;
    921		break;
    922
    923	default:
    924		return -EINVAL;
    925	}
    926
    927	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
    928			   SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
    929			   val);
    930
    931	/* Set sign extension to pad out LSB with 0 */
    932	regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
    933			   SUN8I_I2S_FMT1_REG_SEXT_MASK,
    934			   SUN8I_I2S_FMT1_REG_SEXT(0));
    935
    936	return 0;
    937}
    938
    939static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
    940{
    941	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
    942	int ret;
    943
    944	ret = i2s->variant->set_fmt(i2s, fmt);
    945	if (ret) {
    946		dev_err(dai->dev, "Unsupported format configuration\n");
    947		return ret;
    948	}
    949
    950	i2s->format = fmt;
    951
    952	return 0;
    953}
    954
    955static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
    956{
    957	/* Flush RX FIFO */
    958	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
    959			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
    960			   SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
    961
    962	/* Clear RX counter */
    963	regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
    964
    965	/* Enable RX Block */
    966	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
    967			   SUN4I_I2S_CTRL_RX_EN,
    968			   SUN4I_I2S_CTRL_RX_EN);
    969
    970	/* Enable RX DRQ */
    971	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
    972			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
    973			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
    974}
    975
    976static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
    977{
    978	/* Flush TX FIFO */
    979	regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
    980			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
    981			   SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
    982
    983	/* Clear TX counter */
    984	regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
    985
    986	/* Enable TX Block */
    987	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
    988			   SUN4I_I2S_CTRL_TX_EN,
    989			   SUN4I_I2S_CTRL_TX_EN);
    990
    991	/* Enable TX DRQ */
    992	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
    993			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
    994			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
    995}
    996
    997static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
    998{
    999	/* Disable RX Block */
   1000	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
   1001			   SUN4I_I2S_CTRL_RX_EN,
   1002			   0);
   1003
   1004	/* Disable RX DRQ */
   1005	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
   1006			   SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
   1007			   0);
   1008}
   1009
   1010static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
   1011{
   1012	/* Disable TX Block */
   1013	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
   1014			   SUN4I_I2S_CTRL_TX_EN,
   1015			   0);
   1016
   1017	/* Disable TX DRQ */
   1018	regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
   1019			   SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
   1020			   0);
   1021}
   1022
   1023static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
   1024			     struct snd_soc_dai *dai)
   1025{
   1026	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
   1027
   1028	switch (cmd) {
   1029	case SNDRV_PCM_TRIGGER_START:
   1030	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
   1031	case SNDRV_PCM_TRIGGER_RESUME:
   1032		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
   1033			sun4i_i2s_start_playback(i2s);
   1034		else
   1035			sun4i_i2s_start_capture(i2s);
   1036		break;
   1037
   1038	case SNDRV_PCM_TRIGGER_STOP:
   1039	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
   1040	case SNDRV_PCM_TRIGGER_SUSPEND:
   1041		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
   1042			sun4i_i2s_stop_playback(i2s);
   1043		else
   1044			sun4i_i2s_stop_capture(i2s);
   1045		break;
   1046
   1047	default:
   1048		return -EINVAL;
   1049	}
   1050
   1051	return 0;
   1052}
   1053
   1054static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
   1055				unsigned int freq, int dir)
   1056{
   1057	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
   1058
   1059	if (clk_id != 0)
   1060		return -EINVAL;
   1061
   1062	i2s->mclk_freq = freq;
   1063
   1064	return 0;
   1065}
   1066
   1067static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai *dai,
   1068				  unsigned int tx_mask, unsigned int rx_mask,
   1069				  int slots, int slot_width)
   1070{
   1071	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
   1072
   1073	if (slots > 8)
   1074		return -EINVAL;
   1075
   1076	i2s->slots = slots;
   1077	i2s->slot_width = slot_width;
   1078
   1079	return 0;
   1080}
   1081
   1082static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
   1083	.hw_params	= sun4i_i2s_hw_params,
   1084	.set_fmt	= sun4i_i2s_set_fmt,
   1085	.set_sysclk	= sun4i_i2s_set_sysclk,
   1086	.set_tdm_slot	= sun4i_i2s_set_tdm_slot,
   1087	.trigger	= sun4i_i2s_trigger,
   1088};
   1089
   1090static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
   1091{
   1092	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
   1093
   1094	snd_soc_dai_init_dma_data(dai,
   1095				  &i2s->playback_dma_data,
   1096				  &i2s->capture_dma_data);
   1097
   1098	return 0;
   1099}
   1100
   1101#define SUN4I_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
   1102			 SNDRV_PCM_FMTBIT_S20_LE | \
   1103			 SNDRV_PCM_FMTBIT_S24_LE)
   1104
   1105static struct snd_soc_dai_driver sun4i_i2s_dai = {
   1106	.probe = sun4i_i2s_dai_probe,
   1107	.capture = {
   1108		.stream_name = "Capture",
   1109		.channels_min = 1,
   1110		.channels_max = 8,
   1111		.rates = SNDRV_PCM_RATE_8000_192000,
   1112		.formats = SUN4I_FORMATS,
   1113	},
   1114	.playback = {
   1115		.stream_name = "Playback",
   1116		.channels_min = 1,
   1117		.channels_max = 8,
   1118		.rates = SNDRV_PCM_RATE_8000_192000,
   1119		.formats = SUN4I_FORMATS,
   1120	},
   1121	.ops = &sun4i_i2s_dai_ops,
   1122	.symmetric_rate = 1,
   1123};
   1124
   1125static const struct snd_soc_component_driver sun4i_i2s_component = {
   1126	.name	= "sun4i-dai",
   1127};
   1128
   1129static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
   1130{
   1131	switch (reg) {
   1132	case SUN4I_I2S_FIFO_TX_REG:
   1133		return false;
   1134
   1135	default:
   1136		return true;
   1137	}
   1138}
   1139
   1140static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
   1141{
   1142	switch (reg) {
   1143	case SUN4I_I2S_FIFO_RX_REG:
   1144	case SUN4I_I2S_FIFO_STA_REG:
   1145		return false;
   1146
   1147	default:
   1148		return true;
   1149	}
   1150}
   1151
   1152static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
   1153{
   1154	switch (reg) {
   1155	case SUN4I_I2S_FIFO_RX_REG:
   1156	case SUN4I_I2S_INT_STA_REG:
   1157	case SUN4I_I2S_RX_CNT_REG:
   1158	case SUN4I_I2S_TX_CNT_REG:
   1159		return true;
   1160
   1161	default:
   1162		return false;
   1163	}
   1164}
   1165
   1166static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
   1167{
   1168	switch (reg) {
   1169	case SUN8I_I2S_FIFO_TX_REG:
   1170		return false;
   1171
   1172	default:
   1173		return true;
   1174	}
   1175}
   1176
   1177static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
   1178{
   1179	switch (reg) {
   1180	case SUN4I_I2S_FIFO_CTRL_REG:
   1181	case SUN4I_I2S_FIFO_RX_REG:
   1182	case SUN4I_I2S_FIFO_STA_REG:
   1183	case SUN4I_I2S_RX_CNT_REG:
   1184	case SUN4I_I2S_TX_CNT_REG:
   1185	case SUN8I_I2S_FIFO_TX_REG:
   1186	case SUN8I_I2S_INT_STA_REG:
   1187		return true;
   1188
   1189	default:
   1190		return false;
   1191	}
   1192}
   1193
   1194static const struct reg_default sun4i_i2s_reg_defaults[] = {
   1195	{ SUN4I_I2S_CTRL_REG, 0x00000000 },
   1196	{ SUN4I_I2S_FMT0_REG, 0x0000000c },
   1197	{ SUN4I_I2S_FMT1_REG, 0x00004020 },
   1198	{ SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
   1199	{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
   1200	{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
   1201	{ SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
   1202	{ SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
   1203	{ SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
   1204	{ SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
   1205};
   1206
   1207static const struct reg_default sun8i_i2s_reg_defaults[] = {
   1208	{ SUN4I_I2S_CTRL_REG, 0x00060000 },
   1209	{ SUN4I_I2S_FMT0_REG, 0x00000033 },
   1210	{ SUN4I_I2S_FMT1_REG, 0x00000030 },
   1211	{ SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
   1212	{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
   1213	{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
   1214	{ SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
   1215	{ SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
   1216	{ SUN8I_I2S_TX_CHAN_MAP_REG, 0x00000000 },
   1217	{ SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 },
   1218	{ SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
   1219};
   1220
   1221static const struct reg_default sun50i_h6_i2s_reg_defaults[] = {
   1222	{ SUN4I_I2S_CTRL_REG, 0x00060000 },
   1223	{ SUN4I_I2S_FMT0_REG, 0x00000033 },
   1224	{ SUN4I_I2S_FMT1_REG, 0x00000030 },
   1225	{ SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
   1226	{ SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
   1227	{ SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
   1228	{ SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
   1229	{ SUN50I_H6_I2S_TX_CHAN_SEL_REG(0), 0x00000000 },
   1230	{ SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0x00000000 },
   1231	{ SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x00000000 },
   1232	{ SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
   1233	{ SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
   1234	{ SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
   1235};
   1236
   1237static const struct regmap_config sun4i_i2s_regmap_config = {
   1238	.reg_bits	= 32,
   1239	.reg_stride	= 4,
   1240	.val_bits	= 32,
   1241	.max_register	= SUN4I_I2S_RX_CHAN_MAP_REG,
   1242
   1243	.cache_type	= REGCACHE_FLAT,
   1244	.reg_defaults	= sun4i_i2s_reg_defaults,
   1245	.num_reg_defaults	= ARRAY_SIZE(sun4i_i2s_reg_defaults),
   1246	.writeable_reg	= sun4i_i2s_wr_reg,
   1247	.readable_reg	= sun4i_i2s_rd_reg,
   1248	.volatile_reg	= sun4i_i2s_volatile_reg,
   1249};
   1250
   1251static const struct regmap_config sun8i_i2s_regmap_config = {
   1252	.reg_bits	= 32,
   1253	.reg_stride	= 4,
   1254	.val_bits	= 32,
   1255	.max_register	= SUN8I_I2S_RX_CHAN_MAP_REG,
   1256	.cache_type	= REGCACHE_FLAT,
   1257	.reg_defaults	= sun8i_i2s_reg_defaults,
   1258	.num_reg_defaults	= ARRAY_SIZE(sun8i_i2s_reg_defaults),
   1259	.writeable_reg	= sun4i_i2s_wr_reg,
   1260	.readable_reg	= sun8i_i2s_rd_reg,
   1261	.volatile_reg	= sun8i_i2s_volatile_reg,
   1262};
   1263
   1264static const struct regmap_config sun50i_h6_i2s_regmap_config = {
   1265	.reg_bits	= 32,
   1266	.reg_stride	= 4,
   1267	.val_bits	= 32,
   1268	.max_register	= SUN50I_R329_I2S_RX_CHAN_MAP3_REG,
   1269	.cache_type	= REGCACHE_FLAT,
   1270	.reg_defaults	= sun50i_h6_i2s_reg_defaults,
   1271	.num_reg_defaults	= ARRAY_SIZE(sun50i_h6_i2s_reg_defaults),
   1272	.writeable_reg	= sun4i_i2s_wr_reg,
   1273	.readable_reg	= sun8i_i2s_rd_reg,
   1274	.volatile_reg	= sun8i_i2s_volatile_reg,
   1275};
   1276
   1277static int sun4i_i2s_runtime_resume(struct device *dev)
   1278{
   1279	struct sun4i_i2s *i2s = dev_get_drvdata(dev);
   1280	int ret;
   1281
   1282	ret = clk_prepare_enable(i2s->bus_clk);
   1283	if (ret) {
   1284		dev_err(dev, "Failed to enable bus clock\n");
   1285		return ret;
   1286	}
   1287
   1288	regcache_cache_only(i2s->regmap, false);
   1289	regcache_mark_dirty(i2s->regmap);
   1290
   1291	ret = regcache_sync(i2s->regmap);
   1292	if (ret) {
   1293		dev_err(dev, "Failed to sync regmap cache\n");
   1294		goto err_disable_clk;
   1295	}
   1296
   1297	/* Enable the whole hardware block */
   1298	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
   1299			   SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN);
   1300
   1301	/* Enable the first output line */
   1302	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
   1303			   SUN4I_I2S_CTRL_SDO_EN_MASK,
   1304			   SUN4I_I2S_CTRL_SDO_EN(0));
   1305
   1306	ret = clk_prepare_enable(i2s->mod_clk);
   1307	if (ret) {
   1308		dev_err(dev, "Failed to enable module clock\n");
   1309		goto err_disable_clk;
   1310	}
   1311
   1312	return 0;
   1313
   1314err_disable_clk:
   1315	clk_disable_unprepare(i2s->bus_clk);
   1316	return ret;
   1317}
   1318
   1319static int sun4i_i2s_runtime_suspend(struct device *dev)
   1320{
   1321	struct sun4i_i2s *i2s = dev_get_drvdata(dev);
   1322
   1323	clk_disable_unprepare(i2s->mod_clk);
   1324
   1325	/* Disable our output lines */
   1326	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
   1327			   SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
   1328
   1329	/* Disable the whole hardware block */
   1330	regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
   1331			   SUN4I_I2S_CTRL_GL_EN, 0);
   1332
   1333	regcache_cache_only(i2s->regmap, true);
   1334
   1335	clk_disable_unprepare(i2s->bus_clk);
   1336
   1337	return 0;
   1338}
   1339
   1340static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
   1341	.has_reset		= false,
   1342	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
   1343	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
   1344	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
   1345	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
   1346	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
   1347	.bclk_dividers		= sun4i_i2s_bclk_div,
   1348	.num_bclk_dividers	= ARRAY_SIZE(sun4i_i2s_bclk_div),
   1349	.mclk_dividers		= sun4i_i2s_mclk_div,
   1350	.num_mclk_dividers	= ARRAY_SIZE(sun4i_i2s_mclk_div),
   1351	.get_bclk_parent_rate	= sun4i_i2s_get_bclk_parent_rate,
   1352	.get_sr			= sun4i_i2s_get_sr,
   1353	.get_wss		= sun4i_i2s_get_wss,
   1354	.set_chan_cfg		= sun4i_i2s_set_chan_cfg,
   1355	.set_fmt		= sun4i_i2s_set_soc_fmt,
   1356};
   1357
   1358static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
   1359	.has_reset		= true,
   1360	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
   1361	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
   1362	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
   1363	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
   1364	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
   1365	.bclk_dividers		= sun4i_i2s_bclk_div,
   1366	.num_bclk_dividers	= ARRAY_SIZE(sun4i_i2s_bclk_div),
   1367	.mclk_dividers		= sun4i_i2s_mclk_div,
   1368	.num_mclk_dividers	= ARRAY_SIZE(sun4i_i2s_mclk_div),
   1369	.get_bclk_parent_rate	= sun4i_i2s_get_bclk_parent_rate,
   1370	.get_sr			= sun4i_i2s_get_sr,
   1371	.get_wss		= sun4i_i2s_get_wss,
   1372	.set_chan_cfg		= sun4i_i2s_set_chan_cfg,
   1373	.set_fmt		= sun4i_i2s_set_soc_fmt,
   1374};
   1375
   1376/*
   1377 * This doesn't describe the TDM controller documented in the A83t
   1378 * datasheet, but the three undocumented I2S controller that use the
   1379 * older design.
   1380 */
   1381static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
   1382	.has_reset		= true,
   1383	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
   1384	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
   1385	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
   1386	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
   1387	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
   1388	.bclk_dividers		= sun4i_i2s_bclk_div,
   1389	.num_bclk_dividers	= ARRAY_SIZE(sun4i_i2s_bclk_div),
   1390	.mclk_dividers		= sun4i_i2s_mclk_div,
   1391	.num_mclk_dividers	= ARRAY_SIZE(sun4i_i2s_mclk_div),
   1392	.get_bclk_parent_rate	= sun4i_i2s_get_bclk_parent_rate,
   1393	.get_sr			= sun4i_i2s_get_sr,
   1394	.get_wss		= sun4i_i2s_get_wss,
   1395	.set_chan_cfg		= sun4i_i2s_set_chan_cfg,
   1396	.set_fmt		= sun4i_i2s_set_soc_fmt,
   1397};
   1398
   1399static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
   1400	.has_reset		= true,
   1401	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
   1402	.sun4i_i2s_regmap	= &sun8i_i2s_regmap_config,
   1403	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
   1404	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
   1405	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
   1406	.bclk_dividers		= sun8i_i2s_clk_div,
   1407	.num_bclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
   1408	.mclk_dividers		= sun8i_i2s_clk_div,
   1409	.num_mclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
   1410	.get_bclk_parent_rate	= sun8i_i2s_get_bclk_parent_rate,
   1411	.get_sr			= sun8i_i2s_get_sr_wss,
   1412	.get_wss		= sun8i_i2s_get_sr_wss,
   1413	.set_chan_cfg		= sun8i_i2s_set_chan_cfg,
   1414	.set_fmt		= sun8i_i2s_set_soc_fmt,
   1415};
   1416
   1417static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
   1418	.has_reset		= true,
   1419	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
   1420	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
   1421	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
   1422	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
   1423	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
   1424	.bclk_dividers		= sun4i_i2s_bclk_div,
   1425	.num_bclk_dividers	= ARRAY_SIZE(sun4i_i2s_bclk_div),
   1426	.mclk_dividers		= sun4i_i2s_mclk_div,
   1427	.num_mclk_dividers	= ARRAY_SIZE(sun4i_i2s_mclk_div),
   1428	.get_bclk_parent_rate	= sun4i_i2s_get_bclk_parent_rate,
   1429	.get_sr			= sun4i_i2s_get_sr,
   1430	.get_wss		= sun4i_i2s_get_wss,
   1431	.set_chan_cfg		= sun4i_i2s_set_chan_cfg,
   1432	.set_fmt		= sun4i_i2s_set_soc_fmt,
   1433};
   1434
   1435static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
   1436	.has_reset		= true,
   1437	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
   1438	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
   1439	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
   1440	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
   1441	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
   1442	.bclk_dividers		= sun8i_i2s_clk_div,
   1443	.num_bclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
   1444	.mclk_dividers		= sun8i_i2s_clk_div,
   1445	.num_mclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
   1446	.get_bclk_parent_rate	= sun8i_i2s_get_bclk_parent_rate,
   1447	.get_sr			= sun8i_i2s_get_sr_wss,
   1448	.get_wss		= sun8i_i2s_get_sr_wss,
   1449	.set_chan_cfg		= sun50i_h6_i2s_set_chan_cfg,
   1450	.set_fmt		= sun50i_h6_i2s_set_soc_fmt,
   1451};
   1452
   1453static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks = {
   1454	.has_reset		= true,
   1455	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
   1456	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
   1457	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
   1458	.field_fmt_wss		= REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
   1459	.field_fmt_sr		= REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
   1460	.num_din_pins		= 4,
   1461	.num_dout_pins		= 4,
   1462	.bclk_dividers		= sun8i_i2s_clk_div,
   1463	.num_bclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
   1464	.mclk_dividers		= sun8i_i2s_clk_div,
   1465	.num_mclk_dividers	= ARRAY_SIZE(sun8i_i2s_clk_div),
   1466	.get_bclk_parent_rate	= sun8i_i2s_get_bclk_parent_rate,
   1467	.get_sr			= sun8i_i2s_get_sr_wss,
   1468	.get_wss		= sun8i_i2s_get_sr_wss,
   1469	.set_chan_cfg		= sun50i_h6_i2s_set_chan_cfg,
   1470	.set_fmt		= sun50i_h6_i2s_set_soc_fmt,
   1471};
   1472
   1473static int sun4i_i2s_init_regmap_fields(struct device *dev,
   1474					struct sun4i_i2s *i2s)
   1475{
   1476	i2s->field_clkdiv_mclk_en =
   1477		devm_regmap_field_alloc(dev, i2s->regmap,
   1478					i2s->variant->field_clkdiv_mclk_en);
   1479	if (IS_ERR(i2s->field_clkdiv_mclk_en))
   1480		return PTR_ERR(i2s->field_clkdiv_mclk_en);
   1481
   1482	i2s->field_fmt_wss =
   1483			devm_regmap_field_alloc(dev, i2s->regmap,
   1484						i2s->variant->field_fmt_wss);
   1485	if (IS_ERR(i2s->field_fmt_wss))
   1486		return PTR_ERR(i2s->field_fmt_wss);
   1487
   1488	i2s->field_fmt_sr =
   1489			devm_regmap_field_alloc(dev, i2s->regmap,
   1490						i2s->variant->field_fmt_sr);
   1491	if (IS_ERR(i2s->field_fmt_sr))
   1492		return PTR_ERR(i2s->field_fmt_sr);
   1493
   1494	return 0;
   1495}
   1496
   1497static int sun4i_i2s_probe(struct platform_device *pdev)
   1498{
   1499	struct sun4i_i2s *i2s;
   1500	struct resource *res;
   1501	void __iomem *regs;
   1502	int irq, ret;
   1503
   1504	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
   1505	if (!i2s)
   1506		return -ENOMEM;
   1507	platform_set_drvdata(pdev, i2s);
   1508
   1509	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
   1510	if (IS_ERR(regs))
   1511		return PTR_ERR(regs);
   1512
   1513	irq = platform_get_irq(pdev, 0);
   1514	if (irq < 0)
   1515		return irq;
   1516
   1517	i2s->variant = of_device_get_match_data(&pdev->dev);
   1518	if (!i2s->variant) {
   1519		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
   1520		return -ENODEV;
   1521	}
   1522
   1523	i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
   1524	if (IS_ERR(i2s->bus_clk)) {
   1525		dev_err(&pdev->dev, "Can't get our bus clock\n");
   1526		return PTR_ERR(i2s->bus_clk);
   1527	}
   1528
   1529	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
   1530					    i2s->variant->sun4i_i2s_regmap);
   1531	if (IS_ERR(i2s->regmap)) {
   1532		dev_err(&pdev->dev, "Regmap initialisation failed\n");
   1533		return PTR_ERR(i2s->regmap);
   1534	}
   1535
   1536	i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
   1537	if (IS_ERR(i2s->mod_clk)) {
   1538		dev_err(&pdev->dev, "Can't get our mod clock\n");
   1539		return PTR_ERR(i2s->mod_clk);
   1540	}
   1541
   1542	if (i2s->variant->has_reset) {
   1543		i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
   1544		if (IS_ERR(i2s->rst)) {
   1545			dev_err(&pdev->dev, "Failed to get reset control\n");
   1546			return PTR_ERR(i2s->rst);
   1547		}
   1548	}
   1549
   1550	if (!IS_ERR(i2s->rst)) {
   1551		ret = reset_control_deassert(i2s->rst);
   1552		if (ret) {
   1553			dev_err(&pdev->dev,
   1554				"Failed to deassert the reset control\n");
   1555			return -EINVAL;
   1556		}
   1557	}
   1558
   1559	i2s->playback_dma_data.addr = res->start +
   1560					i2s->variant->reg_offset_txdata;
   1561	i2s->playback_dma_data.maxburst = 8;
   1562
   1563	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
   1564	i2s->capture_dma_data.maxburst = 8;
   1565
   1566	pm_runtime_enable(&pdev->dev);
   1567	if (!pm_runtime_enabled(&pdev->dev)) {
   1568		ret = sun4i_i2s_runtime_resume(&pdev->dev);
   1569		if (ret)
   1570			goto err_pm_disable;
   1571	}
   1572
   1573	ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s);
   1574	if (ret) {
   1575		dev_err(&pdev->dev, "Could not initialise regmap fields\n");
   1576		goto err_suspend;
   1577	}
   1578
   1579	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
   1580	if (ret) {
   1581		dev_err(&pdev->dev, "Could not register PCM\n");
   1582		goto err_suspend;
   1583	}
   1584
   1585	ret = devm_snd_soc_register_component(&pdev->dev,
   1586					      &sun4i_i2s_component,
   1587					      &sun4i_i2s_dai, 1);
   1588	if (ret) {
   1589		dev_err(&pdev->dev, "Could not register DAI\n");
   1590		goto err_suspend;
   1591	}
   1592
   1593	return 0;
   1594
   1595err_suspend:
   1596	if (!pm_runtime_status_suspended(&pdev->dev))
   1597		sun4i_i2s_runtime_suspend(&pdev->dev);
   1598err_pm_disable:
   1599	pm_runtime_disable(&pdev->dev);
   1600	if (!IS_ERR(i2s->rst))
   1601		reset_control_assert(i2s->rst);
   1602
   1603	return ret;
   1604}
   1605
   1606static int sun4i_i2s_remove(struct platform_device *pdev)
   1607{
   1608	struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
   1609
   1610	pm_runtime_disable(&pdev->dev);
   1611	if (!pm_runtime_status_suspended(&pdev->dev))
   1612		sun4i_i2s_runtime_suspend(&pdev->dev);
   1613
   1614	if (!IS_ERR(i2s->rst))
   1615		reset_control_assert(i2s->rst);
   1616
   1617	return 0;
   1618}
   1619
   1620static const struct of_device_id sun4i_i2s_match[] = {
   1621	{
   1622		.compatible = "allwinner,sun4i-a10-i2s",
   1623		.data = &sun4i_a10_i2s_quirks,
   1624	},
   1625	{
   1626		.compatible = "allwinner,sun6i-a31-i2s",
   1627		.data = &sun6i_a31_i2s_quirks,
   1628	},
   1629	{
   1630		.compatible = "allwinner,sun8i-a83t-i2s",
   1631		.data = &sun8i_a83t_i2s_quirks,
   1632	},
   1633	{
   1634		.compatible = "allwinner,sun8i-h3-i2s",
   1635		.data = &sun8i_h3_i2s_quirks,
   1636	},
   1637	{
   1638		.compatible = "allwinner,sun50i-a64-codec-i2s",
   1639		.data = &sun50i_a64_codec_i2s_quirks,
   1640	},
   1641	{
   1642		.compatible = "allwinner,sun50i-h6-i2s",
   1643		.data = &sun50i_h6_i2s_quirks,
   1644	},
   1645	{
   1646		.compatible = "allwinner,sun50i-r329-i2s",
   1647		.data = &sun50i_r329_i2s_quirks,
   1648	},
   1649	{}
   1650};
   1651MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
   1652
   1653static const struct dev_pm_ops sun4i_i2s_pm_ops = {
   1654	.runtime_resume		= sun4i_i2s_runtime_resume,
   1655	.runtime_suspend	= sun4i_i2s_runtime_suspend,
   1656};
   1657
   1658static struct platform_driver sun4i_i2s_driver = {
   1659	.probe	= sun4i_i2s_probe,
   1660	.remove	= sun4i_i2s_remove,
   1661	.driver	= {
   1662		.name		= "sun4i-i2s",
   1663		.of_match_table	= sun4i_i2s_match,
   1664		.pm		= &sun4i_i2s_pm_ops,
   1665	},
   1666};
   1667module_platform_driver(sun4i_i2s_driver);
   1668
   1669MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
   1670MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
   1671MODULE_DESCRIPTION("Allwinner A10 I2S driver");
   1672MODULE_LICENSE("GPL");