0001
0002
0003
0004
0005
0006
0007 #include <linux/clk.h>
0008 #include <linux/device.h>
0009 #include <linux/module.h>
0010 #include <linux/of_platform.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/pm_runtime.h>
0013 #include <linux/regmap.h>
0014 #include <sound/pcm_params.h>
0015 #include <sound/soc.h>
0016 #include "tegra210_admaif.h"
0017 #include "tegra_cif.h"
0018 #include "tegra_pcm.h"
0019
0020 #define CH_REG(offset, reg, id) \
0021 ((offset) + (reg) + (TEGRA_ADMAIF_CHANNEL_REG_STRIDE * (id)))
0022
0023 #define CH_TX_REG(reg, id) CH_REG(admaif->soc_data->tx_base, reg, id)
0024
0025 #define CH_RX_REG(reg, id) CH_REG(admaif->soc_data->rx_base, reg, id)
0026
0027 #define REG_DEFAULTS(id, rx_ctrl, tx_ctrl, tx_base, rx_base) \
0028 { CH_REG(rx_base, TEGRA_ADMAIF_RX_INT_MASK, id), 0x00000001 }, \
0029 { CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), 0x00007700 }, \
0030 { CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl }, \
0031 { CH_REG(tx_base, TEGRA_ADMAIF_TX_INT_MASK, id), 0x00000001 }, \
0032 { CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), 0x00007700 }, \
0033 { CH_REG(tx_base, TEGRA_ADMAIF_TX_FIFO_CTRL, id), tx_ctrl }
0034
0035 #define ADMAIF_REG_DEFAULTS(id, chip) \
0036 REG_DEFAULTS((id) - 1, \
0037 chip ## _ADMAIF_RX ## id ## _FIFO_CTRL_REG_DEFAULT, \
0038 chip ## _ADMAIF_TX ## id ## _FIFO_CTRL_REG_DEFAULT, \
0039 chip ## _ADMAIF_TX_BASE, \
0040 chip ## _ADMAIF_RX_BASE)
0041
0042 static const struct reg_default tegra186_admaif_reg_defaults[] = {
0043 {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA186_ADMAIF_GLOBAL_BASE), 0x00000003},
0044 ADMAIF_REG_DEFAULTS(1, TEGRA186),
0045 ADMAIF_REG_DEFAULTS(2, TEGRA186),
0046 ADMAIF_REG_DEFAULTS(3, TEGRA186),
0047 ADMAIF_REG_DEFAULTS(4, TEGRA186),
0048 ADMAIF_REG_DEFAULTS(5, TEGRA186),
0049 ADMAIF_REG_DEFAULTS(6, TEGRA186),
0050 ADMAIF_REG_DEFAULTS(7, TEGRA186),
0051 ADMAIF_REG_DEFAULTS(8, TEGRA186),
0052 ADMAIF_REG_DEFAULTS(9, TEGRA186),
0053 ADMAIF_REG_DEFAULTS(10, TEGRA186),
0054 ADMAIF_REG_DEFAULTS(11, TEGRA186),
0055 ADMAIF_REG_DEFAULTS(12, TEGRA186),
0056 ADMAIF_REG_DEFAULTS(13, TEGRA186),
0057 ADMAIF_REG_DEFAULTS(14, TEGRA186),
0058 ADMAIF_REG_DEFAULTS(15, TEGRA186),
0059 ADMAIF_REG_DEFAULTS(16, TEGRA186),
0060 ADMAIF_REG_DEFAULTS(17, TEGRA186),
0061 ADMAIF_REG_DEFAULTS(18, TEGRA186),
0062 ADMAIF_REG_DEFAULTS(19, TEGRA186),
0063 ADMAIF_REG_DEFAULTS(20, TEGRA186)
0064 };
0065
0066 static const struct reg_default tegra210_admaif_reg_defaults[] = {
0067 {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA210_ADMAIF_GLOBAL_BASE), 0x00000003},
0068 ADMAIF_REG_DEFAULTS(1, TEGRA210),
0069 ADMAIF_REG_DEFAULTS(2, TEGRA210),
0070 ADMAIF_REG_DEFAULTS(3, TEGRA210),
0071 ADMAIF_REG_DEFAULTS(4, TEGRA210),
0072 ADMAIF_REG_DEFAULTS(5, TEGRA210),
0073 ADMAIF_REG_DEFAULTS(6, TEGRA210),
0074 ADMAIF_REG_DEFAULTS(7, TEGRA210),
0075 ADMAIF_REG_DEFAULTS(8, TEGRA210),
0076 ADMAIF_REG_DEFAULTS(9, TEGRA210),
0077 ADMAIF_REG_DEFAULTS(10, TEGRA210)
0078 };
0079
0080 static bool tegra_admaif_wr_reg(struct device *dev, unsigned int reg)
0081 {
0082 struct tegra_admaif *admaif = dev_get_drvdata(dev);
0083 unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
0084 unsigned int num_ch = admaif->soc_data->num_ch;
0085 unsigned int rx_base = admaif->soc_data->rx_base;
0086 unsigned int tx_base = admaif->soc_data->tx_base;
0087 unsigned int global_base = admaif->soc_data->global_base;
0088 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
0089 unsigned int rx_max = rx_base + (num_ch * ch_stride);
0090 unsigned int tx_max = tx_base + (num_ch * ch_stride);
0091
0092 if ((reg >= rx_base) && (reg < rx_max)) {
0093 reg = (reg - rx_base) % ch_stride;
0094 if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
0095 (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) ||
0096 (reg == TEGRA_ADMAIF_RX_SOFT_RESET) ||
0097 (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL))
0098 return true;
0099 } else if ((reg >= tx_base) && (reg < tx_max)) {
0100 reg = (reg - tx_base) % ch_stride;
0101 if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
0102 (reg == TEGRA_ADMAIF_TX_FIFO_CTRL) ||
0103 (reg == TEGRA_ADMAIF_TX_SOFT_RESET) ||
0104 (reg == TEGRA_ADMAIF_CH_ACIF_TX_CTRL))
0105 return true;
0106 } else if ((reg >= global_base) && (reg < reg_max)) {
0107 if (reg == (global_base + TEGRA_ADMAIF_GLOBAL_ENABLE))
0108 return true;
0109 }
0110
0111 return false;
0112 }
0113
0114 static bool tegra_admaif_rd_reg(struct device *dev, unsigned int reg)
0115 {
0116 struct tegra_admaif *admaif = dev_get_drvdata(dev);
0117 unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
0118 unsigned int num_ch = admaif->soc_data->num_ch;
0119 unsigned int rx_base = admaif->soc_data->rx_base;
0120 unsigned int tx_base = admaif->soc_data->tx_base;
0121 unsigned int global_base = admaif->soc_data->global_base;
0122 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
0123 unsigned int rx_max = rx_base + (num_ch * ch_stride);
0124 unsigned int tx_max = tx_base + (num_ch * ch_stride);
0125
0126 if ((reg >= rx_base) && (reg < rx_max)) {
0127 reg = (reg - rx_base) % ch_stride;
0128 if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
0129 (reg == TEGRA_ADMAIF_RX_STATUS) ||
0130 (reg == TEGRA_ADMAIF_RX_INT_STATUS) ||
0131 (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) ||
0132 (reg == TEGRA_ADMAIF_RX_SOFT_RESET) ||
0133 (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL))
0134 return true;
0135 } else if ((reg >= tx_base) && (reg < tx_max)) {
0136 reg = (reg - tx_base) % ch_stride;
0137 if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
0138 (reg == TEGRA_ADMAIF_TX_STATUS) ||
0139 (reg == TEGRA_ADMAIF_TX_INT_STATUS) ||
0140 (reg == TEGRA_ADMAIF_TX_FIFO_CTRL) ||
0141 (reg == TEGRA_ADMAIF_TX_SOFT_RESET) ||
0142 (reg == TEGRA_ADMAIF_CH_ACIF_TX_CTRL))
0143 return true;
0144 } else if ((reg >= global_base) && (reg < reg_max)) {
0145 if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_ENABLE)) ||
0146 (reg == (global_base + TEGRA_ADMAIF_GLOBAL_CG_0)) ||
0147 (reg == (global_base + TEGRA_ADMAIF_GLOBAL_STATUS)) ||
0148 (reg == (global_base +
0149 TEGRA_ADMAIF_GLOBAL_RX_ENABLE_STATUS)) ||
0150 (reg == (global_base +
0151 TEGRA_ADMAIF_GLOBAL_TX_ENABLE_STATUS)))
0152 return true;
0153 }
0154
0155 return false;
0156 }
0157
0158 static bool tegra_admaif_volatile_reg(struct device *dev, unsigned int reg)
0159 {
0160 struct tegra_admaif *admaif = dev_get_drvdata(dev);
0161 unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
0162 unsigned int num_ch = admaif->soc_data->num_ch;
0163 unsigned int rx_base = admaif->soc_data->rx_base;
0164 unsigned int tx_base = admaif->soc_data->tx_base;
0165 unsigned int global_base = admaif->soc_data->global_base;
0166 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
0167 unsigned int rx_max = rx_base + (num_ch * ch_stride);
0168 unsigned int tx_max = tx_base + (num_ch * ch_stride);
0169
0170 if ((reg >= rx_base) && (reg < rx_max)) {
0171 reg = (reg - rx_base) % ch_stride;
0172 if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
0173 (reg == TEGRA_ADMAIF_RX_STATUS) ||
0174 (reg == TEGRA_ADMAIF_RX_INT_STATUS) ||
0175 (reg == TEGRA_ADMAIF_RX_SOFT_RESET))
0176 return true;
0177 } else if ((reg >= tx_base) && (reg < tx_max)) {
0178 reg = (reg - tx_base) % ch_stride;
0179 if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
0180 (reg == TEGRA_ADMAIF_TX_STATUS) ||
0181 (reg == TEGRA_ADMAIF_TX_INT_STATUS) ||
0182 (reg == TEGRA_ADMAIF_TX_SOFT_RESET))
0183 return true;
0184 } else if ((reg >= global_base) && (reg < reg_max)) {
0185 if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_STATUS)) ||
0186 (reg == (global_base +
0187 TEGRA_ADMAIF_GLOBAL_RX_ENABLE_STATUS)) ||
0188 (reg == (global_base +
0189 TEGRA_ADMAIF_GLOBAL_TX_ENABLE_STATUS)))
0190 return true;
0191 }
0192
0193 return false;
0194 }
0195
0196 static const struct regmap_config tegra210_admaif_regmap_config = {
0197 .reg_bits = 32,
0198 .reg_stride = 4,
0199 .val_bits = 32,
0200 .max_register = TEGRA210_ADMAIF_LAST_REG,
0201 .writeable_reg = tegra_admaif_wr_reg,
0202 .readable_reg = tegra_admaif_rd_reg,
0203 .volatile_reg = tegra_admaif_volatile_reg,
0204 .reg_defaults = tegra210_admaif_reg_defaults,
0205 .num_reg_defaults = TEGRA210_ADMAIF_CHANNEL_COUNT * 6 + 1,
0206 .cache_type = REGCACHE_FLAT,
0207 };
0208
0209 static const struct regmap_config tegra186_admaif_regmap_config = {
0210 .reg_bits = 32,
0211 .reg_stride = 4,
0212 .val_bits = 32,
0213 .max_register = TEGRA186_ADMAIF_LAST_REG,
0214 .writeable_reg = tegra_admaif_wr_reg,
0215 .readable_reg = tegra_admaif_rd_reg,
0216 .volatile_reg = tegra_admaif_volatile_reg,
0217 .reg_defaults = tegra186_admaif_reg_defaults,
0218 .num_reg_defaults = TEGRA186_ADMAIF_CHANNEL_COUNT * 6 + 1,
0219 .cache_type = REGCACHE_FLAT,
0220 };
0221
0222 static int __maybe_unused tegra_admaif_runtime_suspend(struct device *dev)
0223 {
0224 struct tegra_admaif *admaif = dev_get_drvdata(dev);
0225
0226 regcache_cache_only(admaif->regmap, true);
0227 regcache_mark_dirty(admaif->regmap);
0228
0229 return 0;
0230 }
0231
0232 static int __maybe_unused tegra_admaif_runtime_resume(struct device *dev)
0233 {
0234 struct tegra_admaif *admaif = dev_get_drvdata(dev);
0235
0236 regcache_cache_only(admaif->regmap, false);
0237 regcache_sync(admaif->regmap);
0238
0239 return 0;
0240 }
0241
0242 static int tegra_admaif_set_pack_mode(struct regmap *map, unsigned int reg,
0243 int valid_bit)
0244 {
0245 switch (valid_bit) {
0246 case DATA_8BIT:
0247 regmap_update_bits(map, reg, PACK8_EN_MASK, PACK8_EN);
0248 regmap_update_bits(map, reg, PACK16_EN_MASK, 0);
0249 break;
0250 case DATA_16BIT:
0251 regmap_update_bits(map, reg, PACK16_EN_MASK, PACK16_EN);
0252 regmap_update_bits(map, reg, PACK8_EN_MASK, 0);
0253 break;
0254 case DATA_32BIT:
0255 regmap_update_bits(map, reg, PACK16_EN_MASK, 0);
0256 regmap_update_bits(map, reg, PACK8_EN_MASK, 0);
0257 break;
0258 default:
0259 return -EINVAL;
0260 }
0261
0262 return 0;
0263 }
0264
0265 static int tegra_admaif_hw_params(struct snd_pcm_substream *substream,
0266 struct snd_pcm_hw_params *params,
0267 struct snd_soc_dai *dai)
0268 {
0269 struct device *dev = dai->dev;
0270 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
0271 struct tegra_cif_conf cif_conf;
0272 unsigned int reg, path;
0273 int valid_bit, channels;
0274
0275 memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
0276
0277 switch (params_format(params)) {
0278 case SNDRV_PCM_FORMAT_S8:
0279 cif_conf.audio_bits = TEGRA_ACIF_BITS_8;
0280 cif_conf.client_bits = TEGRA_ACIF_BITS_8;
0281 valid_bit = DATA_8BIT;
0282 break;
0283 case SNDRV_PCM_FORMAT_S16_LE:
0284 cif_conf.audio_bits = TEGRA_ACIF_BITS_16;
0285 cif_conf.client_bits = TEGRA_ACIF_BITS_16;
0286 valid_bit = DATA_16BIT;
0287 break;
0288 case SNDRV_PCM_FORMAT_S32_LE:
0289 cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
0290 cif_conf.client_bits = TEGRA_ACIF_BITS_32;
0291 valid_bit = DATA_32BIT;
0292 break;
0293 default:
0294 dev_err(dev, "unsupported format!\n");
0295 return -EOPNOTSUPP;
0296 }
0297
0298 channels = params_channels(params);
0299 cif_conf.client_ch = channels;
0300 cif_conf.audio_ch = channels;
0301
0302 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0303 path = ADMAIF_TX_PATH;
0304 reg = CH_TX_REG(TEGRA_ADMAIF_CH_ACIF_TX_CTRL, dai->id);
0305 } else {
0306 path = ADMAIF_RX_PATH;
0307 reg = CH_RX_REG(TEGRA_ADMAIF_CH_ACIF_RX_CTRL, dai->id);
0308 }
0309
0310 cif_conf.mono_conv = admaif->mono_to_stereo[path][dai->id];
0311 cif_conf.stereo_conv = admaif->stereo_to_mono[path][dai->id];
0312
0313 tegra_admaif_set_pack_mode(admaif->regmap, reg, valid_bit);
0314
0315 tegra_set_cif(admaif->regmap, reg, &cif_conf);
0316
0317 return 0;
0318 }
0319
0320 static int tegra_admaif_start(struct snd_soc_dai *dai, int direction)
0321 {
0322 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
0323 unsigned int reg, mask, val;
0324
0325 switch (direction) {
0326 case SNDRV_PCM_STREAM_PLAYBACK:
0327 mask = TX_ENABLE_MASK;
0328 val = TX_ENABLE;
0329 reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
0330 break;
0331 case SNDRV_PCM_STREAM_CAPTURE:
0332 mask = RX_ENABLE_MASK;
0333 val = RX_ENABLE;
0334 reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
0335 break;
0336 default:
0337 return -EINVAL;
0338 }
0339
0340 regmap_update_bits(admaif->regmap, reg, mask, val);
0341
0342 return 0;
0343 }
0344
0345 static int tegra_admaif_stop(struct snd_soc_dai *dai, int direction)
0346 {
0347 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
0348 unsigned int enable_reg, status_reg, reset_reg, mask, val;
0349 char *dir_name;
0350 int err, enable;
0351
0352 switch (direction) {
0353 case SNDRV_PCM_STREAM_PLAYBACK:
0354 mask = TX_ENABLE_MASK;
0355 enable = TX_ENABLE;
0356 dir_name = "TX";
0357 enable_reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
0358 status_reg = CH_TX_REG(TEGRA_ADMAIF_TX_STATUS, dai->id);
0359 reset_reg = CH_TX_REG(TEGRA_ADMAIF_TX_SOFT_RESET, dai->id);
0360 break;
0361 case SNDRV_PCM_STREAM_CAPTURE:
0362 mask = RX_ENABLE_MASK;
0363 enable = RX_ENABLE;
0364 dir_name = "RX";
0365 enable_reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
0366 status_reg = CH_RX_REG(TEGRA_ADMAIF_RX_STATUS, dai->id);
0367 reset_reg = CH_RX_REG(TEGRA_ADMAIF_RX_SOFT_RESET, dai->id);
0368 break;
0369 default:
0370 return -EINVAL;
0371 }
0372
0373
0374 regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable);
0375
0376
0377 err = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val,
0378 !(val & enable), 10, 10000);
0379 if (err < 0)
0380 dev_warn(dai->dev, "timeout: failed to disable ADMAIF%d_%s\n",
0381 dai->id + 1, dir_name);
0382
0383
0384 regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET);
0385
0386
0387 err = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val,
0388 !(val & SW_RESET_MASK & SW_RESET),
0389 10, 10000);
0390 if (err) {
0391 dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n",
0392 dai->id + 1, dir_name);
0393 return err;
0394 }
0395
0396 return 0;
0397 }
0398
0399 static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
0400 struct snd_soc_dai *dai)
0401 {
0402 int err;
0403
0404 err = snd_dmaengine_pcm_trigger(substream, cmd);
0405 if (err)
0406 return err;
0407
0408 switch (cmd) {
0409 case SNDRV_PCM_TRIGGER_START:
0410 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0411 case SNDRV_PCM_TRIGGER_RESUME:
0412 return tegra_admaif_start(dai, substream->stream);
0413 case SNDRV_PCM_TRIGGER_STOP:
0414 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0415 case SNDRV_PCM_TRIGGER_SUSPEND:
0416 return tegra_admaif_stop(dai, substream->stream);
0417 default:
0418 return -EINVAL;
0419 }
0420 }
0421
0422 static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
0423 .hw_params = tegra_admaif_hw_params,
0424 .trigger = tegra_admaif_trigger,
0425 };
0426
0427 static int tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol *kcontrol,
0428 struct snd_ctl_elem_value *ucontrol)
0429 {
0430 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0431 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
0432 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
0433
0434 ucontrol->value.enumerated.item[0] =
0435 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
0436
0437 return 0;
0438 }
0439
0440 static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol,
0441 struct snd_ctl_elem_value *ucontrol)
0442 {
0443 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0444 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
0445 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
0446 unsigned int value = ucontrol->value.enumerated.item[0];
0447
0448 if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg])
0449 return 0;
0450
0451 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
0452
0453 return 1;
0454 }
0455
0456 static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol,
0457 struct snd_ctl_elem_value *ucontrol)
0458 {
0459 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0460 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
0461 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
0462
0463 ucontrol->value.enumerated.item[0] =
0464 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
0465
0466 return 0;
0467 }
0468
0469 static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol,
0470 struct snd_ctl_elem_value *ucontrol)
0471 {
0472 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0473 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
0474 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
0475 unsigned int value = ucontrol->value.enumerated.item[0];
0476
0477 if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg])
0478 return 0;
0479
0480 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
0481
0482 return 1;
0483 }
0484
0485 static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol,
0486 struct snd_ctl_elem_value *ucontrol)
0487 {
0488 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0489 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
0490 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
0491
0492 ucontrol->value.enumerated.item[0] =
0493 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
0494
0495 return 0;
0496 }
0497
0498 static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol,
0499 struct snd_ctl_elem_value *ucontrol)
0500 {
0501 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0502 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
0503 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
0504 unsigned int value = ucontrol->value.enumerated.item[0];
0505
0506 if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg])
0507 return 0;
0508
0509 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
0510
0511 return 1;
0512 }
0513
0514 static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol,
0515 struct snd_ctl_elem_value *ucontrol)
0516 {
0517 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0518 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
0519 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
0520
0521 ucontrol->value.enumerated.item[0] =
0522 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
0523
0524 return 0;
0525 }
0526
0527 static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol,
0528 struct snd_ctl_elem_value *ucontrol)
0529 {
0530 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0531 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
0532 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
0533 unsigned int value = ucontrol->value.enumerated.item[0];
0534
0535 if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg])
0536 return 0;
0537
0538 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
0539
0540 return 1;
0541 }
0542
0543 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
0544 {
0545 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
0546
0547 dai->capture_dma_data = &admaif->capture_dma_data[dai->id];
0548 dai->playback_dma_data = &admaif->playback_dma_data[dai->id];
0549
0550 return 0;
0551 }
0552
0553 #define DAI(dai_name) \
0554 { \
0555 .name = dai_name, \
0556 .probe = tegra_admaif_dai_probe, \
0557 .playback = { \
0558 .stream_name = dai_name " Playback", \
0559 .channels_min = 1, \
0560 .channels_max = 16, \
0561 .rates = SNDRV_PCM_RATE_8000_192000, \
0562 .formats = SNDRV_PCM_FMTBIT_S8 | \
0563 SNDRV_PCM_FMTBIT_S16_LE | \
0564 SNDRV_PCM_FMTBIT_S32_LE, \
0565 }, \
0566 .capture = { \
0567 .stream_name = dai_name " Capture", \
0568 .channels_min = 1, \
0569 .channels_max = 16, \
0570 .rates = SNDRV_PCM_RATE_8000_192000, \
0571 .formats = SNDRV_PCM_FMTBIT_S8 | \
0572 SNDRV_PCM_FMTBIT_S16_LE | \
0573 SNDRV_PCM_FMTBIT_S32_LE, \
0574 }, \
0575 .ops = &tegra_admaif_dai_ops, \
0576 }
0577
0578 static struct snd_soc_dai_driver tegra210_admaif_cmpnt_dais[] = {
0579 DAI("ADMAIF1"),
0580 DAI("ADMAIF2"),
0581 DAI("ADMAIF3"),
0582 DAI("ADMAIF4"),
0583 DAI("ADMAIF5"),
0584 DAI("ADMAIF6"),
0585 DAI("ADMAIF7"),
0586 DAI("ADMAIF8"),
0587 DAI("ADMAIF9"),
0588 DAI("ADMAIF10"),
0589 };
0590
0591 static struct snd_soc_dai_driver tegra186_admaif_cmpnt_dais[] = {
0592 DAI("ADMAIF1"),
0593 DAI("ADMAIF2"),
0594 DAI("ADMAIF3"),
0595 DAI("ADMAIF4"),
0596 DAI("ADMAIF5"),
0597 DAI("ADMAIF6"),
0598 DAI("ADMAIF7"),
0599 DAI("ADMAIF8"),
0600 DAI("ADMAIF9"),
0601 DAI("ADMAIF10"),
0602 DAI("ADMAIF11"),
0603 DAI("ADMAIF12"),
0604 DAI("ADMAIF13"),
0605 DAI("ADMAIF14"),
0606 DAI("ADMAIF15"),
0607 DAI("ADMAIF16"),
0608 DAI("ADMAIF17"),
0609 DAI("ADMAIF18"),
0610 DAI("ADMAIF19"),
0611 DAI("ADMAIF20"),
0612 };
0613
0614 static const char * const tegra_admaif_stereo_conv_text[] = {
0615 "CH0", "CH1", "AVG",
0616 };
0617
0618 static const char * const tegra_admaif_mono_conv_text[] = {
0619 "Zero", "Copy",
0620 };
0621
0622
0623
0624
0625
0626 #define NV_SOC_ENUM_EXT(xname, xreg, xhandler_get, xhandler_put, xenum_text) \
0627 { \
0628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
0629 .info = snd_soc_info_enum_double, \
0630 .name = xname, \
0631 .get = xhandler_get, \
0632 .put = xhandler_put, \
0633 .private_value = (unsigned long)&(struct soc_enum) \
0634 SOC_ENUM_SINGLE(xreg, 0, ARRAY_SIZE(xenum_text), xenum_text) \
0635 }
0636
0637 #define TEGRA_ADMAIF_CIF_CTRL(reg) \
0638 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1, \
0639 tegra210_admaif_pget_mono_to_stereo, \
0640 tegra210_admaif_pput_mono_to_stereo, \
0641 tegra_admaif_mono_conv_text), \
0642 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1, \
0643 tegra210_admaif_pget_stereo_to_mono, \
0644 tegra210_admaif_pput_stereo_to_mono, \
0645 tegra_admaif_stereo_conv_text), \
0646 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \
0647 tegra210_admaif_cget_mono_to_stereo, \
0648 tegra210_admaif_cput_mono_to_stereo, \
0649 tegra_admaif_mono_conv_text), \
0650 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \
0651 tegra210_admaif_cget_stereo_to_mono, \
0652 tegra210_admaif_cput_stereo_to_mono, \
0653 tegra_admaif_stereo_conv_text)
0654
0655 static struct snd_kcontrol_new tegra210_admaif_controls[] = {
0656 TEGRA_ADMAIF_CIF_CTRL(1),
0657 TEGRA_ADMAIF_CIF_CTRL(2),
0658 TEGRA_ADMAIF_CIF_CTRL(3),
0659 TEGRA_ADMAIF_CIF_CTRL(4),
0660 TEGRA_ADMAIF_CIF_CTRL(5),
0661 TEGRA_ADMAIF_CIF_CTRL(6),
0662 TEGRA_ADMAIF_CIF_CTRL(7),
0663 TEGRA_ADMAIF_CIF_CTRL(8),
0664 TEGRA_ADMAIF_CIF_CTRL(9),
0665 TEGRA_ADMAIF_CIF_CTRL(10),
0666 };
0667
0668 static struct snd_kcontrol_new tegra186_admaif_controls[] = {
0669 TEGRA_ADMAIF_CIF_CTRL(1),
0670 TEGRA_ADMAIF_CIF_CTRL(2),
0671 TEGRA_ADMAIF_CIF_CTRL(3),
0672 TEGRA_ADMAIF_CIF_CTRL(4),
0673 TEGRA_ADMAIF_CIF_CTRL(5),
0674 TEGRA_ADMAIF_CIF_CTRL(6),
0675 TEGRA_ADMAIF_CIF_CTRL(7),
0676 TEGRA_ADMAIF_CIF_CTRL(8),
0677 TEGRA_ADMAIF_CIF_CTRL(9),
0678 TEGRA_ADMAIF_CIF_CTRL(10),
0679 TEGRA_ADMAIF_CIF_CTRL(11),
0680 TEGRA_ADMAIF_CIF_CTRL(12),
0681 TEGRA_ADMAIF_CIF_CTRL(13),
0682 TEGRA_ADMAIF_CIF_CTRL(14),
0683 TEGRA_ADMAIF_CIF_CTRL(15),
0684 TEGRA_ADMAIF_CIF_CTRL(16),
0685 TEGRA_ADMAIF_CIF_CTRL(17),
0686 TEGRA_ADMAIF_CIF_CTRL(18),
0687 TEGRA_ADMAIF_CIF_CTRL(19),
0688 TEGRA_ADMAIF_CIF_CTRL(20),
0689 };
0690
0691 static const struct snd_soc_component_driver tegra210_admaif_cmpnt = {
0692 .controls = tegra210_admaif_controls,
0693 .num_controls = ARRAY_SIZE(tegra210_admaif_controls),
0694 .pcm_construct = tegra_pcm_construct,
0695 .open = tegra_pcm_open,
0696 .close = tegra_pcm_close,
0697 .hw_params = tegra_pcm_hw_params,
0698 .pointer = tegra_pcm_pointer,
0699 };
0700
0701 static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
0702 .controls = tegra186_admaif_controls,
0703 .num_controls = ARRAY_SIZE(tegra186_admaif_controls),
0704 .pcm_construct = tegra_pcm_construct,
0705 .open = tegra_pcm_open,
0706 .close = tegra_pcm_close,
0707 .hw_params = tegra_pcm_hw_params,
0708 .pointer = tegra_pcm_pointer,
0709 };
0710
0711 static const struct tegra_admaif_soc_data soc_data_tegra210 = {
0712 .num_ch = TEGRA210_ADMAIF_CHANNEL_COUNT,
0713 .cmpnt = &tegra210_admaif_cmpnt,
0714 .dais = tegra210_admaif_cmpnt_dais,
0715 .regmap_conf = &tegra210_admaif_regmap_config,
0716 .global_base = TEGRA210_ADMAIF_GLOBAL_BASE,
0717 .tx_base = TEGRA210_ADMAIF_TX_BASE,
0718 .rx_base = TEGRA210_ADMAIF_RX_BASE,
0719 };
0720
0721 static const struct tegra_admaif_soc_data soc_data_tegra186 = {
0722 .num_ch = TEGRA186_ADMAIF_CHANNEL_COUNT,
0723 .cmpnt = &tegra186_admaif_cmpnt,
0724 .dais = tegra186_admaif_cmpnt_dais,
0725 .regmap_conf = &tegra186_admaif_regmap_config,
0726 .global_base = TEGRA186_ADMAIF_GLOBAL_BASE,
0727 .tx_base = TEGRA186_ADMAIF_TX_BASE,
0728 .rx_base = TEGRA186_ADMAIF_RX_BASE,
0729 };
0730
0731 static const struct of_device_id tegra_admaif_of_match[] = {
0732 { .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
0733 { .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 },
0734 {},
0735 };
0736 MODULE_DEVICE_TABLE(of, tegra_admaif_of_match);
0737
0738 static int tegra_admaif_probe(struct platform_device *pdev)
0739 {
0740 struct tegra_admaif *admaif;
0741 void __iomem *regs;
0742 struct resource *res;
0743 int err, i;
0744
0745 admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
0746 if (!admaif)
0747 return -ENOMEM;
0748
0749 admaif->soc_data = of_device_get_match_data(&pdev->dev);
0750
0751 dev_set_drvdata(&pdev->dev, admaif);
0752
0753 admaif->capture_dma_data =
0754 devm_kcalloc(&pdev->dev,
0755 admaif->soc_data->num_ch,
0756 sizeof(struct snd_dmaengine_dai_dma_data),
0757 GFP_KERNEL);
0758 if (!admaif->capture_dma_data)
0759 return -ENOMEM;
0760
0761 admaif->playback_dma_data =
0762 devm_kcalloc(&pdev->dev,
0763 admaif->soc_data->num_ch,
0764 sizeof(struct snd_dmaengine_dai_dma_data),
0765 GFP_KERNEL);
0766 if (!admaif->playback_dma_data)
0767 return -ENOMEM;
0768
0769 for (i = 0; i < ADMAIF_PATHS; i++) {
0770 admaif->mono_to_stereo[i] =
0771 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
0772 sizeof(unsigned int), GFP_KERNEL);
0773 if (!admaif->mono_to_stereo[i])
0774 return -ENOMEM;
0775
0776 admaif->stereo_to_mono[i] =
0777 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
0778 sizeof(unsigned int), GFP_KERNEL);
0779 if (!admaif->stereo_to_mono[i])
0780 return -ENOMEM;
0781 }
0782
0783 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
0784 if (IS_ERR(regs))
0785 return PTR_ERR(regs);
0786
0787 admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
0788 admaif->soc_data->regmap_conf);
0789 if (IS_ERR(admaif->regmap)) {
0790 dev_err(&pdev->dev, "regmap init failed\n");
0791 return PTR_ERR(admaif->regmap);
0792 }
0793
0794 regcache_cache_only(admaif->regmap, true);
0795
0796 regmap_update_bits(admaif->regmap, admaif->soc_data->global_base +
0797 TEGRA_ADMAIF_GLOBAL_ENABLE, 1, 1);
0798
0799 for (i = 0; i < admaif->soc_data->num_ch; i++) {
0800 admaif->playback_dma_data[i].addr = res->start +
0801 CH_TX_REG(TEGRA_ADMAIF_TX_FIFO_WRITE, i);
0802
0803 admaif->capture_dma_data[i].addr = res->start +
0804 CH_RX_REG(TEGRA_ADMAIF_RX_FIFO_READ, i);
0805
0806 admaif->playback_dma_data[i].addr_width = 32;
0807
0808 if (of_property_read_string_index(pdev->dev.of_node,
0809 "dma-names", (i * 2) + 1,
0810 &admaif->playback_dma_data[i].chan_name) < 0) {
0811 dev_err(&pdev->dev,
0812 "missing property nvidia,dma-names\n");
0813
0814 return -ENODEV;
0815 }
0816
0817 admaif->capture_dma_data[i].addr_width = 32;
0818
0819 if (of_property_read_string_index(pdev->dev.of_node,
0820 "dma-names",
0821 (i * 2),
0822 &admaif->capture_dma_data[i].chan_name) < 0) {
0823 dev_err(&pdev->dev,
0824 "missing property nvidia,dma-names\n");
0825
0826 return -ENODEV;
0827 }
0828 }
0829
0830 err = devm_snd_soc_register_component(&pdev->dev,
0831 admaif->soc_data->cmpnt,
0832 admaif->soc_data->dais,
0833 admaif->soc_data->num_ch);
0834 if (err) {
0835 dev_err(&pdev->dev,
0836 "can't register ADMAIF component, err: %d\n", err);
0837 return err;
0838 }
0839
0840 pm_runtime_enable(&pdev->dev);
0841
0842 return 0;
0843 }
0844
0845 static int tegra_admaif_remove(struct platform_device *pdev)
0846 {
0847 pm_runtime_disable(&pdev->dev);
0848
0849 return 0;
0850 }
0851
0852 static const struct dev_pm_ops tegra_admaif_pm_ops = {
0853 SET_RUNTIME_PM_OPS(tegra_admaif_runtime_suspend,
0854 tegra_admaif_runtime_resume, NULL)
0855 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
0856 pm_runtime_force_resume)
0857 };
0858
0859 static struct platform_driver tegra_admaif_driver = {
0860 .probe = tegra_admaif_probe,
0861 .remove = tegra_admaif_remove,
0862 .driver = {
0863 .name = "tegra210-admaif",
0864 .of_match_table = tegra_admaif_of_match,
0865 .pm = &tegra_admaif_pm_ops,
0866 },
0867 };
0868 module_platform_driver(tegra_admaif_driver);
0869
0870 MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>");
0871 MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver");
0872 MODULE_LICENSE("GPL v2");