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