Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 //
0003 // tegra210_admaif.c - Tegra ADMAIF driver
0004 //
0005 // Copyright (c) 2020 NVIDIA CORPORATION.  All rights reserved.
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     /* Disable TX/RX channel */
0374     regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable);
0375 
0376     /* Wait until ADMAIF TX/RX status is disabled */
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     /* SW reset */
0384     regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET);
0385 
0386     /* Wait till SW reset is complete */
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  * Below macro is added to avoid looping over all ADMAIFx controls related
0624  * to mono/stereo conversions in get()/put() callbacks.
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");