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 #define SUN4I_I2S_FMT0_POLARITY_INVERTED (1) 50 #define SUN4I_I2S_FMT0_POLARITY_NORMAL (0) 51 52 #define SUN4I_I2S_FMT1_REG 0x08 53 #define SUN4I_I2S_FIFO_TX_REG 0x0c 54 #define SUN4I_I2S_FIFO_RX_REG 0x10 55 56 #define SUN4I_I2S_FIFO_CTRL_REG 0x14 57 #define SUN4I_I2S_FIFO_CTRL_FLUSH_TX BIT(25) 58 #define SUN4I_I2S_FIFO_CTRL_FLUSH_RX BIT(24) 59 #define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK BIT(2) 60 #define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode) ((mode) << 2) 61 #define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK GENMASK(1, 0) 62 #define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode) (mode) 63 64 #define SUN4I_I2S_FIFO_STA_REG 0x18 65 66 #define SUN4I_I2S_DMA_INT_CTRL_REG 0x1c 67 #define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN BIT(7) 68 #define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN BIT(3) 69 70 #define SUN4I_I2S_INT_STA_REG 0x20 71 72 #define SUN4I_I2S_CLK_DIV_REG 0x24 73 #define SUN4I_I2S_CLK_DIV_MCLK_EN BIT(7) 74 #define SUN4I_I2S_CLK_DIV_BCLK_MASK GENMASK(6, 4) 75 #define SUN4I_I2S_CLK_DIV_BCLK(bclk) ((bclk) << 4) 76 #define SUN4I_I2S_CLK_DIV_MCLK_MASK GENMASK(3, 0) 77 #define SUN4I_I2S_CLK_DIV_MCLK(mclk) ((mclk) << 0) 78 79 #define SUN4I_I2S_RX_CNT_REG 0x28 80 #define SUN4I_I2S_TX_CNT_REG 0x2c 81 82 #define SUN4I_I2S_TX_CHAN_SEL_REG 0x30 83 #define SUN4I_I2S_CHAN_SEL(num_chan) (((num_chan) - 1) << 0) 84 85 #define SUN4I_I2S_TX_CHAN_MAP_REG 0x34 86 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample) ((sample) << (chan << 2)) 87 88 #define SUN4I_I2S_RX_CHAN_SEL_REG 0x38 89 #define SUN4I_I2S_RX_CHAN_MAP_REG 0x3c 90 91 /* Defines required for sun8i-h3 support */ 92 #define SUN8I_I2S_CTRL_BCLK_OUT BIT(18) 93 #define SUN8I_I2S_CTRL_LRCK_OUT BIT(17) 94 95 #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) 96 #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8) 97 98 #define SUN8I_I2S_INT_STA_REG 0x0c 99 #define SUN8I_I2S_FIFO_TX_REG 0x20 100 101 #define SUN8I_I2S_CHAN_CFG_REG 0x30 102 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK GENMASK(6, 4) 103 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan) ((chan - 1) << 4) 104 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK GENMASK(2, 0) 105 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) (chan - 1) 106 107 #define SUN8I_I2S_TX_CHAN_MAP_REG 0x44 108 #define SUN8I_I2S_TX_CHAN_SEL_REG 0x34 109 #define SUN8I_I2S_TX_CHAN_OFFSET_MASK GENMASK(13, 11) 110 #define SUN8I_I2S_TX_CHAN_OFFSET(offset) (offset << 12) 111 #define SUN8I_I2S_TX_CHAN_EN_MASK GENMASK(11, 4) 112 #define SUN8I_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1) << 4) 113 114 #define SUN8I_I2S_RX_CHAN_SEL_REG 0x54 115 #define SUN8I_I2S_RX_CHAN_MAP_REG 0x58 116 117 /** 118 * struct sun4i_i2s_quirks - Differences between SoC variants. 119 * 120 * @has_reset: SoC needs reset deasserted. 121 * @has_slave_select_bit: SoC has a bit to enable slave mode. 122 * @has_fmt_set_lrck_period: SoC requires lrclk period to be set. 123 * @has_chcfg: tx and rx slot number need to be set. 124 * @has_chsel_tx_chen: SoC requires that the tx channels are enabled. 125 * @has_chsel_offset: SoC uses offset for selecting dai operational mode. 126 * @reg_offset_txdata: offset of the tx fifo. 127 * @sun4i_i2s_regmap: regmap config to use. 128 * @mclk_offset: Value by which mclkdiv needs to be adjusted. 129 * @bclk_offset: Value by which bclkdiv needs to be adjusted. 130 * @fmt_offset: Value by which wss and sr needs to be adjusted. 131 * @field_clkdiv_mclk_en: regmap field to enable mclk output. 132 * @field_fmt_wss: regmap field to set word select size. 133 * @field_fmt_sr: regmap field to set sample resolution. 134 * @field_fmt_bclk: regmap field to set clk polarity. 135 * @field_fmt_lrclk: regmap field to set frame polarity. 136 * @field_fmt_mode: regmap field to set the operational mode. 137 * @field_txchanmap: location of the tx channel mapping register. 138 * @field_rxchanmap: location of the rx channel mapping register. 139 * @field_txchansel: location of the tx channel select bit fields. 140 * @field_rxchansel: location of the rx channel select bit fields. 141 */ 142 struct sun4i_i2s_quirks { 143 bool has_reset; 144 bool has_slave_select_bit; 145 bool has_fmt_set_lrck_period; 146 bool has_chcfg; 147 bool has_chsel_tx_chen; 148 bool has_chsel_offset; 149 unsigned int reg_offset_txdata; /* TX FIFO */ 150 const struct regmap_config *sun4i_i2s_regmap; 151 unsigned int mclk_offset; 152 unsigned int bclk_offset; 153 unsigned int fmt_offset; 154 155 /* Register fields for i2s */ 156 struct reg_field field_clkdiv_mclk_en; 157 struct reg_field field_fmt_wss; 158 struct reg_field field_fmt_sr; 159 struct reg_field field_fmt_bclk; 160 struct reg_field field_fmt_lrclk; 161 struct reg_field field_fmt_mode; 162 struct reg_field field_txchanmap; 163 struct reg_field field_rxchanmap; 164 struct reg_field field_txchansel; 165 struct reg_field field_rxchansel; 166 }; 167 168 struct sun4i_i2s { 169 struct clk *bus_clk; 170 struct clk *mod_clk; 171 struct regmap *regmap; 172 struct reset_control *rst; 173 174 unsigned int mclk_freq; 175 176 struct snd_dmaengine_dai_dma_data capture_dma_data; 177 struct snd_dmaengine_dai_dma_data playback_dma_data; 178 179 /* Register fields for i2s */ 180 struct regmap_field *field_clkdiv_mclk_en; 181 struct regmap_field *field_fmt_wss; 182 struct regmap_field *field_fmt_sr; 183 struct regmap_field *field_fmt_bclk; 184 struct regmap_field *field_fmt_lrclk; 185 struct regmap_field *field_fmt_mode; 186 struct regmap_field *field_txchanmap; 187 struct regmap_field *field_rxchanmap; 188 struct regmap_field *field_txchansel; 189 struct regmap_field *field_rxchansel; 190 191 const struct sun4i_i2s_quirks *variant; 192 }; 193 194 struct sun4i_i2s_clk_div { 195 u8 div; 196 u8 val; 197 }; 198 199 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = { 200 { .div = 2, .val = 0 }, 201 { .div = 4, .val = 1 }, 202 { .div = 6, .val = 2 }, 203 { .div = 8, .val = 3 }, 204 { .div = 12, .val = 4 }, 205 { .div = 16, .val = 5 }, 206 /* TODO - extend divide ratio supported by newer SoCs */ 207 }; 208 209 static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = { 210 { .div = 1, .val = 0 }, 211 { .div = 2, .val = 1 }, 212 { .div = 4, .val = 2 }, 213 { .div = 6, .val = 3 }, 214 { .div = 8, .val = 4 }, 215 { .div = 12, .val = 5 }, 216 { .div = 16, .val = 6 }, 217 { .div = 24, .val = 7 }, 218 /* TODO - extend divide ratio supported by newer SoCs */ 219 }; 220 221 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s, 222 unsigned int oversample_rate, 223 unsigned int word_size) 224 { 225 int div = oversample_rate / word_size / 2; 226 int i; 227 228 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) { 229 const struct sun4i_i2s_clk_div *bdiv = &sun4i_i2s_bclk_div[i]; 230 231 if (bdiv->div == div) 232 return bdiv->val; 233 } 234 235 return -EINVAL; 236 } 237 238 static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s, 239 unsigned int oversample_rate, 240 unsigned int module_rate, 241 unsigned int sampling_rate) 242 { 243 int div = module_rate / sampling_rate / oversample_rate; 244 int i; 245 246 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_mclk_div); i++) { 247 const struct sun4i_i2s_clk_div *mdiv = &sun4i_i2s_mclk_div[i]; 248 249 if (mdiv->div == div) 250 return mdiv->val; 251 } 252 253 return -EINVAL; 254 } 255 256 static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 }; 257 static bool sun4i_i2s_oversample_is_valid(unsigned int oversample) 258 { 259 int i; 260 261 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_oversample_rates); i++) 262 if (sun4i_i2s_oversample_rates[i] == oversample) 263 return true; 264 265 return false; 266 } 267 268 static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai, 269 unsigned int rate, 270 unsigned int word_size) 271 { 272 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 273 unsigned int oversample_rate, clk_rate; 274 int bclk_div, mclk_div; 275 int ret; 276 277 switch (rate) { 278 case 176400: 279 case 88200: 280 case 44100: 281 case 22050: 282 case 11025: 283 clk_rate = 22579200; 284 break; 285 286 case 192000: 287 case 128000: 288 case 96000: 289 case 64000: 290 case 48000: 291 case 32000: 292 case 24000: 293 case 16000: 294 case 12000: 295 case 8000: 296 clk_rate = 24576000; 297 break; 298 299 default: 300 dev_err(dai->dev, "Unsupported sample rate: %u\n", rate); 301 return -EINVAL; 302 } 303 304 ret = clk_set_rate(i2s->mod_clk, clk_rate); 305 if (ret) 306 return ret; 307 308 oversample_rate = i2s->mclk_freq / rate; 309 if (!sun4i_i2s_oversample_is_valid(oversample_rate)) { 310 dev_err(dai->dev, "Unsupported oversample rate: %d\n", 311 oversample_rate); 312 return -EINVAL; 313 } 314 315 bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate, 316 word_size); 317 if (bclk_div < 0) { 318 dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div); 319 return -EINVAL; 320 } 321 322 mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate, 323 clk_rate, rate); 324 if (mclk_div < 0) { 325 dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div); 326 return -EINVAL; 327 } 328 329 /* Adjust the clock division values if needed */ 330 bclk_div += i2s->variant->bclk_offset; 331 mclk_div += i2s->variant->mclk_offset; 332 333 regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG, 334 SUN4I_I2S_CLK_DIV_BCLK(bclk_div) | 335 SUN4I_I2S_CLK_DIV_MCLK(mclk_div)); 336 337 regmap_field_write(i2s->field_clkdiv_mclk_en, 1); 338 339 /* Set sync period */ 340 if (i2s->variant->has_fmt_set_lrck_period) 341 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, 342 SUN8I_I2S_FMT0_LRCK_PERIOD_MASK, 343 SUN8I_I2S_FMT0_LRCK_PERIOD(32)); 344 345 return 0; 346 } 347 348 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, 349 struct snd_pcm_hw_params *params, 350 struct snd_soc_dai *dai) 351 { 352 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 353 int sr, wss, channels; 354 u32 width; 355 356 channels = params_channels(params); 357 if (channels != 2) { 358 dev_err(dai->dev, "Unsupported number of channels: %d\n", 359 channels); 360 return -EINVAL; 361 } 362 363 if (i2s->variant->has_chcfg) { 364 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, 365 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK, 366 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels)); 367 regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, 368 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK, 369 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels)); 370 } 371 372 /* Map the channels for playback and capture */ 373 regmap_field_write(i2s->field_txchanmap, 0x76543210); 374 regmap_field_write(i2s->field_rxchanmap, 0x00003210); 375 376 /* Configure the channels */ 377 regmap_field_write(i2s->field_txchansel, 378 SUN4I_I2S_CHAN_SEL(params_channels(params))); 379 380 regmap_field_write(i2s->field_rxchansel, 381 SUN4I_I2S_CHAN_SEL(params_channels(params))); 382 383 if (i2s->variant->has_chsel_tx_chen) 384 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, 385 SUN8I_I2S_TX_CHAN_EN_MASK, 386 SUN8I_I2S_TX_CHAN_EN(channels)); 387 388 switch (params_physical_width(params)) { 389 case 16: 390 width = DMA_SLAVE_BUSWIDTH_2_BYTES; 391 break; 392 default: 393 dev_err(dai->dev, "Unsupported physical sample width: %d\n", 394 params_physical_width(params)); 395 return -EINVAL; 396 } 397 i2s->playback_dma_data.addr_width = width; 398 399 switch (params_width(params)) { 400 case 16: 401 sr = 0; 402 wss = 0; 403 break; 404 405 default: 406 dev_err(dai->dev, "Unsupported sample width: %d\n", 407 params_width(params)); 408 return -EINVAL; 409 } 410 411 regmap_field_write(i2s->field_fmt_wss, 412 wss + i2s->variant->fmt_offset); 413 regmap_field_write(i2s->field_fmt_sr, 414 sr + i2s->variant->fmt_offset); 415 416 return sun4i_i2s_set_clk_rate(dai, params_rate(params), 417 params_width(params)); 418 } 419 420 static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 421 { 422 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 423 u32 val; 424 u32 offset = 0; 425 u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; 426 u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; 427 428 /* DAI Mode */ 429 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 430 case SND_SOC_DAIFMT_I2S: 431 val = SUN4I_I2S_FMT0_FMT_I2S; 432 offset = 1; 433 break; 434 case SND_SOC_DAIFMT_LEFT_J: 435 val = SUN4I_I2S_FMT0_FMT_LEFT_J; 436 break; 437 case SND_SOC_DAIFMT_RIGHT_J: 438 val = SUN4I_I2S_FMT0_FMT_RIGHT_J; 439 break; 440 default: 441 dev_err(dai->dev, "Unsupported format: %d\n", 442 fmt & SND_SOC_DAIFMT_FORMAT_MASK); 443 return -EINVAL; 444 } 445 446 if (i2s->variant->has_chsel_offset) { 447 /* 448 * offset being set indicates that we're connected to an i2s 449 * device, however offset is only used on the sun8i block and 450 * i2s shares the same setting with the LJ format. Increment 451 * val so that the bit to value to write is correct. 452 */ 453 if (offset > 0) 454 val++; 455 /* blck offset determines whether i2s or LJ */ 456 regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, 457 SUN8I_I2S_TX_CHAN_OFFSET_MASK, 458 SUN8I_I2S_TX_CHAN_OFFSET(offset)); 459 } 460 461 regmap_field_write(i2s->field_fmt_mode, val); 462 463 /* DAI clock polarity */ 464 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 465 case SND_SOC_DAIFMT_IB_IF: 466 /* Invert both clocks */ 467 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; 468 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; 469 break; 470 case SND_SOC_DAIFMT_IB_NF: 471 /* Invert bit clock */ 472 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; 473 break; 474 case SND_SOC_DAIFMT_NB_IF: 475 /* Invert frame clock */ 476 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; 477 break; 478 case SND_SOC_DAIFMT_NB_NF: 479 break; 480 default: 481 dev_err(dai->dev, "Unsupported clock polarity: %d\n", 482 fmt & SND_SOC_DAIFMT_INV_MASK); 483 return -EINVAL; 484 } 485 486 regmap_field_write(i2s->field_fmt_bclk, bclk_polarity); 487 regmap_field_write(i2s->field_fmt_lrclk, lrclk_polarity); 488 489 if (i2s->variant->has_slave_select_bit) { 490 /* DAI clock master masks */ 491 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 492 case SND_SOC_DAIFMT_CBS_CFS: 493 /* BCLK and LRCLK master */ 494 val = SUN4I_I2S_CTRL_MODE_MASTER; 495 break; 496 case SND_SOC_DAIFMT_CBM_CFM: 497 /* BCLK and LRCLK slave */ 498 val = SUN4I_I2S_CTRL_MODE_SLAVE; 499 break; 500 default: 501 dev_err(dai->dev, "Unsupported slave setting: %d\n", 502 fmt & SND_SOC_DAIFMT_MASTER_MASK); 503 return -EINVAL; 504 } 505 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 506 SUN4I_I2S_CTRL_MODE_MASK, 507 val); 508 } else { 509 /* 510 * The newer i2s block does not have a slave select bit, 511 * instead the clk pins are configured as inputs. 512 */ 513 /* DAI clock master masks */ 514 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 515 case SND_SOC_DAIFMT_CBS_CFS: 516 /* BCLK and LRCLK master */ 517 val = SUN8I_I2S_CTRL_BCLK_OUT | 518 SUN8I_I2S_CTRL_LRCK_OUT; 519 break; 520 case SND_SOC_DAIFMT_CBM_CFM: 521 /* BCLK and LRCLK slave */ 522 val = 0; 523 break; 524 default: 525 dev_err(dai->dev, "Unsupported slave setting: %d\n", 526 fmt & SND_SOC_DAIFMT_MASTER_MASK); 527 return -EINVAL; 528 } 529 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 530 SUN8I_I2S_CTRL_BCLK_OUT | 531 SUN8I_I2S_CTRL_LRCK_OUT, 532 val); 533 } 534 535 /* Set significant bits in our FIFOs */ 536 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, 537 SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK | 538 SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK, 539 SUN4I_I2S_FIFO_CTRL_TX_MODE(1) | 540 SUN4I_I2S_FIFO_CTRL_RX_MODE(1)); 541 return 0; 542 } 543 544 static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s) 545 { 546 /* Flush RX FIFO */ 547 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, 548 SUN4I_I2S_FIFO_CTRL_FLUSH_RX, 549 SUN4I_I2S_FIFO_CTRL_FLUSH_RX); 550 551 /* Clear RX counter */ 552 regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0); 553 554 /* Enable RX Block */ 555 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 556 SUN4I_I2S_CTRL_RX_EN, 557 SUN4I_I2S_CTRL_RX_EN); 558 559 /* Enable RX DRQ */ 560 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG, 561 SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN, 562 SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN); 563 } 564 565 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s) 566 { 567 /* Flush TX FIFO */ 568 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, 569 SUN4I_I2S_FIFO_CTRL_FLUSH_TX, 570 SUN4I_I2S_FIFO_CTRL_FLUSH_TX); 571 572 /* Clear TX counter */ 573 regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0); 574 575 /* Enable TX Block */ 576 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 577 SUN4I_I2S_CTRL_TX_EN, 578 SUN4I_I2S_CTRL_TX_EN); 579 580 /* Enable TX DRQ */ 581 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG, 582 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN, 583 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN); 584 } 585 586 static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s) 587 { 588 /* Disable RX Block */ 589 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 590 SUN4I_I2S_CTRL_RX_EN, 591 0); 592 593 /* Disable RX DRQ */ 594 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG, 595 SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN, 596 0); 597 } 598 599 static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s) 600 { 601 /* Disable TX Block */ 602 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 603 SUN4I_I2S_CTRL_TX_EN, 604 0); 605 606 /* Disable TX DRQ */ 607 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG, 608 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN, 609 0); 610 } 611 612 static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 613 struct snd_soc_dai *dai) 614 { 615 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 616 617 switch (cmd) { 618 case SNDRV_PCM_TRIGGER_START: 619 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 620 case SNDRV_PCM_TRIGGER_RESUME: 621 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 622 sun4i_i2s_start_playback(i2s); 623 else 624 sun4i_i2s_start_capture(i2s); 625 break; 626 627 case SNDRV_PCM_TRIGGER_STOP: 628 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 629 case SNDRV_PCM_TRIGGER_SUSPEND: 630 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 631 sun4i_i2s_stop_playback(i2s); 632 else 633 sun4i_i2s_stop_capture(i2s); 634 break; 635 636 default: 637 return -EINVAL; 638 } 639 640 return 0; 641 } 642 643 static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, 644 unsigned int freq, int dir) 645 { 646 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 647 648 if (clk_id != 0) 649 return -EINVAL; 650 651 i2s->mclk_freq = freq; 652 653 return 0; 654 } 655 656 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = { 657 .hw_params = sun4i_i2s_hw_params, 658 .set_fmt = sun4i_i2s_set_fmt, 659 .set_sysclk = sun4i_i2s_set_sysclk, 660 .trigger = sun4i_i2s_trigger, 661 }; 662 663 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai) 664 { 665 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 666 667 snd_soc_dai_init_dma_data(dai, 668 &i2s->playback_dma_data, 669 &i2s->capture_dma_data); 670 671 snd_soc_dai_set_drvdata(dai, i2s); 672 673 return 0; 674 } 675 676 static struct snd_soc_dai_driver sun4i_i2s_dai = { 677 .probe = sun4i_i2s_dai_probe, 678 .capture = { 679 .stream_name = "Capture", 680 .channels_min = 2, 681 .channels_max = 2, 682 .rates = SNDRV_PCM_RATE_8000_192000, 683 .formats = SNDRV_PCM_FMTBIT_S16_LE, 684 }, 685 .playback = { 686 .stream_name = "Playback", 687 .channels_min = 2, 688 .channels_max = 2, 689 .rates = SNDRV_PCM_RATE_8000_192000, 690 .formats = SNDRV_PCM_FMTBIT_S16_LE, 691 }, 692 .ops = &sun4i_i2s_dai_ops, 693 .symmetric_rates = 1, 694 }; 695 696 static const struct snd_soc_component_driver sun4i_i2s_component = { 697 .name = "sun4i-dai", 698 }; 699 700 static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg) 701 { 702 switch (reg) { 703 case SUN4I_I2S_FIFO_TX_REG: 704 return false; 705 706 default: 707 return true; 708 } 709 } 710 711 static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg) 712 { 713 switch (reg) { 714 case SUN4I_I2S_FIFO_RX_REG: 715 case SUN4I_I2S_FIFO_STA_REG: 716 return false; 717 718 default: 719 return true; 720 } 721 } 722 723 static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg) 724 { 725 switch (reg) { 726 case SUN4I_I2S_FIFO_RX_REG: 727 case SUN4I_I2S_INT_STA_REG: 728 case SUN4I_I2S_RX_CNT_REG: 729 case SUN4I_I2S_TX_CNT_REG: 730 return true; 731 732 default: 733 return false; 734 } 735 } 736 737 static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg) 738 { 739 switch (reg) { 740 case SUN8I_I2S_FIFO_TX_REG: 741 return false; 742 743 default: 744 return true; 745 } 746 } 747 748 static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg) 749 { 750 if (reg == SUN8I_I2S_INT_STA_REG) 751 return true; 752 if (reg == SUN8I_I2S_FIFO_TX_REG) 753 return false; 754 755 return sun4i_i2s_volatile_reg(dev, reg); 756 } 757 758 static const struct reg_default sun4i_i2s_reg_defaults[] = { 759 { SUN4I_I2S_CTRL_REG, 0x00000000 }, 760 { SUN4I_I2S_FMT0_REG, 0x0000000c }, 761 { SUN4I_I2S_FMT1_REG, 0x00004020 }, 762 { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 }, 763 { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 }, 764 { SUN4I_I2S_CLK_DIV_REG, 0x00000000 }, 765 { SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 }, 766 { SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 }, 767 { SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 }, 768 { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 }, 769 }; 770 771 static const struct reg_default sun8i_i2s_reg_defaults[] = { 772 { SUN4I_I2S_CTRL_REG, 0x00060000 }, 773 { SUN4I_I2S_FMT0_REG, 0x00000033 }, 774 { SUN4I_I2S_FMT1_REG, 0x00000030 }, 775 { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 }, 776 { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 }, 777 { SUN4I_I2S_CLK_DIV_REG, 0x00000000 }, 778 { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 }, 779 { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 }, 780 { SUN8I_I2S_TX_CHAN_MAP_REG, 0x00000000 }, 781 { SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 }, 782 { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 }, 783 }; 784 785 static const struct regmap_config sun4i_i2s_regmap_config = { 786 .reg_bits = 32, 787 .reg_stride = 4, 788 .val_bits = 32, 789 .max_register = SUN4I_I2S_RX_CHAN_MAP_REG, 790 791 .cache_type = REGCACHE_FLAT, 792 .reg_defaults = sun4i_i2s_reg_defaults, 793 .num_reg_defaults = ARRAY_SIZE(sun4i_i2s_reg_defaults), 794 .writeable_reg = sun4i_i2s_wr_reg, 795 .readable_reg = sun4i_i2s_rd_reg, 796 .volatile_reg = sun4i_i2s_volatile_reg, 797 }; 798 799 static const struct regmap_config sun8i_i2s_regmap_config = { 800 .reg_bits = 32, 801 .reg_stride = 4, 802 .val_bits = 32, 803 .max_register = SUN8I_I2S_RX_CHAN_MAP_REG, 804 .cache_type = REGCACHE_FLAT, 805 .reg_defaults = sun8i_i2s_reg_defaults, 806 .num_reg_defaults = ARRAY_SIZE(sun8i_i2s_reg_defaults), 807 .writeable_reg = sun4i_i2s_wr_reg, 808 .readable_reg = sun8i_i2s_rd_reg, 809 .volatile_reg = sun8i_i2s_volatile_reg, 810 }; 811 812 static int sun4i_i2s_runtime_resume(struct device *dev) 813 { 814 struct sun4i_i2s *i2s = dev_get_drvdata(dev); 815 int ret; 816 817 ret = clk_prepare_enable(i2s->bus_clk); 818 if (ret) { 819 dev_err(dev, "Failed to enable bus clock\n"); 820 return ret; 821 } 822 823 regcache_cache_only(i2s->regmap, false); 824 regcache_mark_dirty(i2s->regmap); 825 826 ret = regcache_sync(i2s->regmap); 827 if (ret) { 828 dev_err(dev, "Failed to sync regmap cache\n"); 829 goto err_disable_clk; 830 } 831 832 /* Enable the whole hardware block */ 833 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 834 SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN); 835 836 /* Enable the first output line */ 837 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 838 SUN4I_I2S_CTRL_SDO_EN_MASK, 839 SUN4I_I2S_CTRL_SDO_EN(0)); 840 841 ret = clk_prepare_enable(i2s->mod_clk); 842 if (ret) { 843 dev_err(dev, "Failed to enable module clock\n"); 844 goto err_disable_clk; 845 } 846 847 return 0; 848 849 err_disable_clk: 850 clk_disable_unprepare(i2s->bus_clk); 851 return ret; 852 } 853 854 static int sun4i_i2s_runtime_suspend(struct device *dev) 855 { 856 struct sun4i_i2s *i2s = dev_get_drvdata(dev); 857 858 clk_disable_unprepare(i2s->mod_clk); 859 860 /* Disable our output lines */ 861 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 862 SUN4I_I2S_CTRL_SDO_EN_MASK, 0); 863 864 /* Disable the whole hardware block */ 865 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, 866 SUN4I_I2S_CTRL_GL_EN, 0); 867 868 regcache_cache_only(i2s->regmap, true); 869 870 clk_disable_unprepare(i2s->bus_clk); 871 872 return 0; 873 } 874 875 static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { 876 .has_reset = false, 877 .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, 878 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, 879 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), 880 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), 881 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), 882 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), 883 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 884 .has_slave_select_bit = true, 885 .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), 886 .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), 887 .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), 888 .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), 889 .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), 890 }; 891 892 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { 893 .has_reset = true, 894 .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, 895 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, 896 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), 897 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), 898 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), 899 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), 900 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 901 .has_slave_select_bit = true, 902 .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), 903 .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), 904 .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), 905 .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), 906 .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), 907 }; 908 909 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { 910 .has_reset = true, 911 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 912 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, 913 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), 914 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), 915 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), 916 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), 917 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 918 .has_slave_select_bit = true, 919 .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), 920 .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), 921 .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), 922 .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), 923 .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), 924 }; 925 926 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { 927 .has_reset = true, 928 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 929 .sun4i_i2s_regmap = &sun8i_i2s_regmap_config, 930 .mclk_offset = 1, 931 .bclk_offset = 2, 932 .fmt_offset = 3, 933 .has_fmt_set_lrck_period = true, 934 .has_chcfg = true, 935 .has_chsel_tx_chen = true, 936 .has_chsel_offset = true, 937 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), 938 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), 939 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6), 940 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 941 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19), 942 .field_fmt_mode = REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5), 943 .field_txchanmap = REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31), 944 .field_rxchanmap = REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31), 945 .field_txchansel = REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2), 946 .field_rxchansel = REG_FIELD(SUN8I_I2S_RX_CHAN_SEL_REG, 0, 2), 947 }; 948 949 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { 950 .has_reset = true, 951 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 952 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, 953 .has_slave_select_bit = true, 954 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), 955 .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), 956 .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), 957 .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), 958 .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), 959 .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), 960 .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), 961 .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), 962 .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), 963 .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), 964 }; 965 966 static int sun4i_i2s_init_regmap_fields(struct device *dev, 967 struct sun4i_i2s *i2s) 968 { 969 i2s->field_clkdiv_mclk_en = 970 devm_regmap_field_alloc(dev, i2s->regmap, 971 i2s->variant->field_clkdiv_mclk_en); 972 if (IS_ERR(i2s->field_clkdiv_mclk_en)) 973 return PTR_ERR(i2s->field_clkdiv_mclk_en); 974 975 i2s->field_fmt_wss = 976 devm_regmap_field_alloc(dev, i2s->regmap, 977 i2s->variant->field_fmt_wss); 978 if (IS_ERR(i2s->field_fmt_wss)) 979 return PTR_ERR(i2s->field_fmt_wss); 980 981 i2s->field_fmt_sr = 982 devm_regmap_field_alloc(dev, i2s->regmap, 983 i2s->variant->field_fmt_sr); 984 if (IS_ERR(i2s->field_fmt_sr)) 985 return PTR_ERR(i2s->field_fmt_sr); 986 987 i2s->field_fmt_bclk = 988 devm_regmap_field_alloc(dev, i2s->regmap, 989 i2s->variant->field_fmt_bclk); 990 if (IS_ERR(i2s->field_fmt_bclk)) 991 return PTR_ERR(i2s->field_fmt_bclk); 992 993 i2s->field_fmt_lrclk = 994 devm_regmap_field_alloc(dev, i2s->regmap, 995 i2s->variant->field_fmt_lrclk); 996 if (IS_ERR(i2s->field_fmt_lrclk)) 997 return PTR_ERR(i2s->field_fmt_lrclk); 998 999 i2s->field_fmt_mode = 1000 devm_regmap_field_alloc(dev, i2s->regmap, 1001 i2s->variant->field_fmt_mode); 1002 if (IS_ERR(i2s->field_fmt_mode)) 1003 return PTR_ERR(i2s->field_fmt_mode); 1004 1005 i2s->field_txchanmap = 1006 devm_regmap_field_alloc(dev, i2s->regmap, 1007 i2s->variant->field_txchanmap); 1008 if (IS_ERR(i2s->field_txchanmap)) 1009 return PTR_ERR(i2s->field_txchanmap); 1010 1011 i2s->field_rxchanmap = 1012 devm_regmap_field_alloc(dev, i2s->regmap, 1013 i2s->variant->field_rxchanmap); 1014 if (IS_ERR(i2s->field_rxchanmap)) 1015 return PTR_ERR(i2s->field_rxchanmap); 1016 1017 i2s->field_txchansel = 1018 devm_regmap_field_alloc(dev, i2s->regmap, 1019 i2s->variant->field_txchansel); 1020 if (IS_ERR(i2s->field_txchansel)) 1021 return PTR_ERR(i2s->field_txchansel); 1022 1023 i2s->field_rxchansel = 1024 devm_regmap_field_alloc(dev, i2s->regmap, 1025 i2s->variant->field_rxchansel); 1026 return PTR_ERR_OR_ZERO(i2s->field_rxchansel); 1027 } 1028 1029 static int sun4i_i2s_probe(struct platform_device *pdev) 1030 { 1031 struct sun4i_i2s *i2s; 1032 struct resource *res; 1033 void __iomem *regs; 1034 int irq, ret; 1035 1036 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); 1037 if (!i2s) 1038 return -ENOMEM; 1039 platform_set_drvdata(pdev, i2s); 1040 1041 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1042 regs = devm_ioremap_resource(&pdev->dev, res); 1043 if (IS_ERR(regs)) 1044 return PTR_ERR(regs); 1045 1046 irq = platform_get_irq(pdev, 0); 1047 if (irq < 0) { 1048 dev_err(&pdev->dev, "Can't retrieve our interrupt\n"); 1049 return irq; 1050 } 1051 1052 i2s->variant = of_device_get_match_data(&pdev->dev); 1053 if (!i2s->variant) { 1054 dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); 1055 return -ENODEV; 1056 } 1057 1058 i2s->bus_clk = devm_clk_get(&pdev->dev, "apb"); 1059 if (IS_ERR(i2s->bus_clk)) { 1060 dev_err(&pdev->dev, "Can't get our bus clock\n"); 1061 return PTR_ERR(i2s->bus_clk); 1062 } 1063 1064 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, 1065 i2s->variant->sun4i_i2s_regmap); 1066 if (IS_ERR(i2s->regmap)) { 1067 dev_err(&pdev->dev, "Regmap initialisation failed\n"); 1068 return PTR_ERR(i2s->regmap); 1069 } 1070 1071 i2s->mod_clk = devm_clk_get(&pdev->dev, "mod"); 1072 if (IS_ERR(i2s->mod_clk)) { 1073 dev_err(&pdev->dev, "Can't get our mod clock\n"); 1074 return PTR_ERR(i2s->mod_clk); 1075 } 1076 1077 if (i2s->variant->has_reset) { 1078 i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); 1079 if (IS_ERR(i2s->rst)) { 1080 dev_err(&pdev->dev, "Failed to get reset control\n"); 1081 return PTR_ERR(i2s->rst); 1082 } 1083 } 1084 1085 if (!IS_ERR(i2s->rst)) { 1086 ret = reset_control_deassert(i2s->rst); 1087 if (ret) { 1088 dev_err(&pdev->dev, 1089 "Failed to deassert the reset control\n"); 1090 return -EINVAL; 1091 } 1092 } 1093 1094 i2s->playback_dma_data.addr = res->start + 1095 i2s->variant->reg_offset_txdata; 1096 i2s->playback_dma_data.maxburst = 8; 1097 1098 i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG; 1099 i2s->capture_dma_data.maxburst = 8; 1100 1101 pm_runtime_enable(&pdev->dev); 1102 if (!pm_runtime_enabled(&pdev->dev)) { 1103 ret = sun4i_i2s_runtime_resume(&pdev->dev); 1104 if (ret) 1105 goto err_pm_disable; 1106 } 1107 1108 ret = devm_snd_soc_register_component(&pdev->dev, 1109 &sun4i_i2s_component, 1110 &sun4i_i2s_dai, 1); 1111 if (ret) { 1112 dev_err(&pdev->dev, "Could not register DAI\n"); 1113 goto err_suspend; 1114 } 1115 1116 ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 1117 if (ret) { 1118 dev_err(&pdev->dev, "Could not register PCM\n"); 1119 goto err_suspend; 1120 } 1121 1122 ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s); 1123 if (ret) { 1124 dev_err(&pdev->dev, "Could not initialise regmap fields\n"); 1125 goto err_suspend; 1126 } 1127 1128 return 0; 1129 1130 err_suspend: 1131 if (!pm_runtime_status_suspended(&pdev->dev)) 1132 sun4i_i2s_runtime_suspend(&pdev->dev); 1133 err_pm_disable: 1134 pm_runtime_disable(&pdev->dev); 1135 if (!IS_ERR(i2s->rst)) 1136 reset_control_assert(i2s->rst); 1137 1138 return ret; 1139 } 1140 1141 static int sun4i_i2s_remove(struct platform_device *pdev) 1142 { 1143 struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev); 1144 1145 snd_dmaengine_pcm_unregister(&pdev->dev); 1146 1147 pm_runtime_disable(&pdev->dev); 1148 if (!pm_runtime_status_suspended(&pdev->dev)) 1149 sun4i_i2s_runtime_suspend(&pdev->dev); 1150 1151 if (!IS_ERR(i2s->rst)) 1152 reset_control_assert(i2s->rst); 1153 1154 return 0; 1155 } 1156 1157 static const struct of_device_id sun4i_i2s_match[] = { 1158 { 1159 .compatible = "allwinner,sun4i-a10-i2s", 1160 .data = &sun4i_a10_i2s_quirks, 1161 }, 1162 { 1163 .compatible = "allwinner,sun6i-a31-i2s", 1164 .data = &sun6i_a31_i2s_quirks, 1165 }, 1166 { 1167 .compatible = "allwinner,sun8i-a83t-i2s", 1168 .data = &sun8i_a83t_i2s_quirks, 1169 }, 1170 { 1171 .compatible = "allwinner,sun8i-h3-i2s", 1172 .data = &sun8i_h3_i2s_quirks, 1173 }, 1174 { 1175 .compatible = "allwinner,sun50i-a64-codec-i2s", 1176 .data = &sun50i_a64_codec_i2s_quirks, 1177 }, 1178 {} 1179 }; 1180 MODULE_DEVICE_TABLE(of, sun4i_i2s_match); 1181 1182 static const struct dev_pm_ops sun4i_i2s_pm_ops = { 1183 .runtime_resume = sun4i_i2s_runtime_resume, 1184 .runtime_suspend = sun4i_i2s_runtime_suspend, 1185 }; 1186 1187 static struct platform_driver sun4i_i2s_driver = { 1188 .probe = sun4i_i2s_probe, 1189 .remove = sun4i_i2s_remove, 1190 .driver = { 1191 .name = "sun4i-i2s", 1192 .of_match_table = sun4i_i2s_match, 1193 .pm = &sun4i_i2s_pm_ops, 1194 }, 1195 }; 1196 module_platform_driver(sun4i_i2s_driver); 1197 1198 MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>"); 1199 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 1200 MODULE_DESCRIPTION("Allwinner A10 I2S driver"); 1201 MODULE_LICENSE("GPL"); 1202