Linux Audio

Check our new training course

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