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