Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Analog Devices ADAU7118 8 channel PDM-to-I2S/TDM Converter driver
0004 //
0005 // Copyright 2019 Analog Devices Inc.
0006 
0007 #include <linux/bitfield.h>
0008 #include <linux/module.h>
0009 #include <linux/regmap.h>
0010 #include <linux/regulator/consumer.h>
0011 #include <sound/pcm_params.h>
0012 #include <sound/soc.h>
0013 
0014 #include "adau7118.h"
0015 
0016 #define ADAU7118_DEC_RATIO_MASK     GENMASK(1, 0)
0017 #define ADAU7118_DEC_RATIO(x)       FIELD_PREP(ADAU7118_DEC_RATIO_MASK, x)
0018 #define ADAU7118_CLK_MAP_MASK       GENMASK(7, 4)
0019 #define ADAU7118_SLOT_WIDTH_MASK    GENMASK(5, 4)
0020 #define ADAU7118_SLOT_WIDTH(x)      FIELD_PREP(ADAU7118_SLOT_WIDTH_MASK, x)
0021 #define ADAU7118_TRISTATE_MASK      BIT(6)
0022 #define ADAU7118_TRISTATE(x)        FIELD_PREP(ADAU7118_TRISTATE_MASK, x)
0023 #define ADAU7118_DATA_FMT_MASK      GENMASK(3, 1)
0024 #define ADAU7118_DATA_FMT(x)        FIELD_PREP(ADAU7118_DATA_FMT_MASK, x)
0025 #define ADAU7118_SAI_MODE_MASK      BIT(0)
0026 #define ADAU7118_SAI_MODE(x)        FIELD_PREP(ADAU7118_SAI_MODE_MASK, x)
0027 #define ADAU7118_LRCLK_BCLK_POL_MASK    GENMASK(1, 0)
0028 #define ADAU7118_LRCLK_BCLK_POL(x) \
0029                 FIELD_PREP(ADAU7118_LRCLK_BCLK_POL_MASK, x)
0030 #define ADAU7118_SPT_SLOT_MASK      GENMASK(7, 4)
0031 #define ADAU7118_SPT_SLOT(x)        FIELD_PREP(ADAU7118_SPT_SLOT_MASK, x)
0032 #define ADAU7118_FULL_SOFT_R_MASK   BIT(1)
0033 #define ADAU7118_FULL_SOFT_R(x)     FIELD_PREP(ADAU7118_FULL_SOFT_R_MASK, x)
0034 
0035 struct adau7118_data {
0036     struct regmap *map;
0037     struct device *dev;
0038     struct regulator *iovdd;
0039     struct regulator *dvdd;
0040     u32 slot_width;
0041     u32 slots;
0042     bool hw_mode;
0043     bool right_j;
0044 };
0045 
0046 /* Input Enable */
0047 static const struct snd_kcontrol_new adau7118_dapm_pdm_control[4] = {
0048     SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 0, 1, 0),
0049     SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 1, 1, 0),
0050     SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 2, 1, 0),
0051     SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 3, 1, 0),
0052 };
0053 
0054 static const struct snd_soc_dapm_widget adau7118_widgets_sw[] = {
0055     /* Input Enable Switches */
0056     SND_SOC_DAPM_SWITCH("PDM0", SND_SOC_NOPM, 0, 0,
0057                 &adau7118_dapm_pdm_control[0]),
0058     SND_SOC_DAPM_SWITCH("PDM1", SND_SOC_NOPM, 0, 0,
0059                 &adau7118_dapm_pdm_control[1]),
0060     SND_SOC_DAPM_SWITCH("PDM2", SND_SOC_NOPM, 0, 0,
0061                 &adau7118_dapm_pdm_control[2]),
0062     SND_SOC_DAPM_SWITCH("PDM3", SND_SOC_NOPM, 0, 0,
0063                 &adau7118_dapm_pdm_control[3]),
0064 
0065     /* PDM Clocks */
0066     SND_SOC_DAPM_SUPPLY("PDM_CLK0", ADAU7118_REG_ENABLES, 4, 0, NULL, 0),
0067     SND_SOC_DAPM_SUPPLY("PDM_CLK1", ADAU7118_REG_ENABLES, 5, 0, NULL, 0),
0068 
0069     /* Output channels */
0070     SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, ADAU7118_REG_SPT_CX(0),
0071                  0, 0),
0072     SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 0, ADAU7118_REG_SPT_CX(1),
0073                  0, 0),
0074     SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 0, ADAU7118_REG_SPT_CX(2),
0075                  0, 0),
0076     SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 0, ADAU7118_REG_SPT_CX(3),
0077                  0, 0),
0078     SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 0, ADAU7118_REG_SPT_CX(4),
0079                  0, 0),
0080     SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 0, ADAU7118_REG_SPT_CX(5),
0081                  0, 0),
0082     SND_SOC_DAPM_AIF_OUT("AIF1TX7", "Capture", 0, ADAU7118_REG_SPT_CX(6),
0083                  0, 0),
0084     SND_SOC_DAPM_AIF_OUT("AIF1TX8", "Capture", 0, ADAU7118_REG_SPT_CX(7),
0085                  0, 0),
0086 };
0087 
0088 static const struct snd_soc_dapm_route adau7118_routes_sw[] = {
0089     { "PDM0", "Capture Switch", "PDM_DAT0" },
0090     { "PDM1", "Capture Switch", "PDM_DAT1" },
0091     { "PDM2", "Capture Switch", "PDM_DAT2" },
0092     { "PDM3", "Capture Switch", "PDM_DAT3" },
0093     { "AIF1TX1", NULL, "PDM0" },
0094     { "AIF1TX2", NULL, "PDM0" },
0095     { "AIF1TX3", NULL, "PDM1" },
0096     { "AIF1TX4", NULL, "PDM1" },
0097     { "AIF1TX5", NULL, "PDM2" },
0098     { "AIF1TX6", NULL, "PDM2" },
0099     { "AIF1TX7", NULL, "PDM3" },
0100     { "AIF1TX8", NULL, "PDM3" },
0101     { "Capture", NULL, "PDM_CLK0" },
0102     { "Capture", NULL, "PDM_CLK1" },
0103 };
0104 
0105 static const struct snd_soc_dapm_widget adau7118_widgets_hw[] = {
0106     SND_SOC_DAPM_AIF_OUT("AIF1TX", "Capture", 0, SND_SOC_NOPM, 0, 0),
0107 };
0108 
0109 static const struct snd_soc_dapm_route adau7118_routes_hw[] = {
0110     { "AIF1TX", NULL, "PDM_DAT0" },
0111     { "AIF1TX", NULL, "PDM_DAT1" },
0112     { "AIF1TX", NULL, "PDM_DAT2" },
0113     { "AIF1TX", NULL, "PDM_DAT3" },
0114 };
0115 
0116 static const struct snd_soc_dapm_widget adau7118_widgets[] = {
0117     SND_SOC_DAPM_INPUT("PDM_DAT0"),
0118     SND_SOC_DAPM_INPUT("PDM_DAT1"),
0119     SND_SOC_DAPM_INPUT("PDM_DAT2"),
0120     SND_SOC_DAPM_INPUT("PDM_DAT3"),
0121 };
0122 
0123 static int adau7118_set_channel_map(struct snd_soc_dai *dai,
0124                     unsigned int tx_num, unsigned int *tx_slot,
0125                     unsigned int rx_num, unsigned int *rx_slot)
0126 {
0127     struct adau7118_data *st =
0128         snd_soc_component_get_drvdata(dai->component);
0129     int chan, ret;
0130 
0131     dev_dbg(st->dev, "Set channel map, %d", tx_num);
0132 
0133     for (chan = 0; chan < tx_num; chan++) {
0134         ret = snd_soc_component_update_bits(dai->component,
0135                     ADAU7118_REG_SPT_CX(chan),
0136                     ADAU7118_SPT_SLOT_MASK,
0137                     ADAU7118_SPT_SLOT(tx_slot[chan]));
0138         if (ret < 0)
0139             return ret;
0140     }
0141 
0142     return 0;
0143 }
0144 
0145 static int adau7118_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0146 {
0147     struct adau7118_data *st =
0148         snd_soc_component_get_drvdata(dai->component);
0149     int ret = 0;
0150     u32 regval;
0151 
0152     dev_dbg(st->dev, "Set format, fmt:%d\n", fmt);
0153 
0154     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0155     case SND_SOC_DAIFMT_I2S:
0156         ret = snd_soc_component_update_bits(dai->component,
0157                             ADAU7118_REG_SPT_CTRL1,
0158                             ADAU7118_DATA_FMT_MASK,
0159                             ADAU7118_DATA_FMT(0));
0160         break;
0161     case SND_SOC_DAIFMT_LEFT_J:
0162         ret = snd_soc_component_update_bits(dai->component,
0163                             ADAU7118_REG_SPT_CTRL1,
0164                             ADAU7118_DATA_FMT_MASK,
0165                             ADAU7118_DATA_FMT(1));
0166         break;
0167     case SND_SOC_DAIFMT_RIGHT_J:
0168         st->right_j = true;
0169         break;
0170     default:
0171         dev_err(st->dev, "Invalid format %d",
0172             fmt & SND_SOC_DAIFMT_FORMAT_MASK);
0173         return -EINVAL;
0174     }
0175 
0176     if (ret < 0)
0177         return ret;
0178 
0179     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0180     case SND_SOC_DAIFMT_NB_NF:
0181         regval = ADAU7118_LRCLK_BCLK_POL(0);
0182         break;
0183     case SND_SOC_DAIFMT_NB_IF:
0184         regval = ADAU7118_LRCLK_BCLK_POL(2);
0185         break;
0186     case SND_SOC_DAIFMT_IB_NF:
0187         regval = ADAU7118_LRCLK_BCLK_POL(1);
0188         break;
0189     case SND_SOC_DAIFMT_IB_IF:
0190         regval = ADAU7118_LRCLK_BCLK_POL(3);
0191         break;
0192     default:
0193         dev_err(st->dev, "Invalid Inv mask %d",
0194             fmt & SND_SOC_DAIFMT_INV_MASK);
0195         return -EINVAL;
0196     }
0197 
0198     ret = snd_soc_component_update_bits(dai->component,
0199                         ADAU7118_REG_SPT_CTRL2,
0200                         ADAU7118_LRCLK_BCLK_POL_MASK,
0201                         regval);
0202     if (ret < 0)
0203         return ret;
0204 
0205     return 0;
0206 }
0207 
0208 static int adau7118_set_tristate(struct snd_soc_dai *dai, int tristate)
0209 {
0210     struct adau7118_data *st =
0211         snd_soc_component_get_drvdata(dai->component);
0212     int ret;
0213 
0214     dev_dbg(st->dev, "Set tristate, %d\n", tristate);
0215 
0216     ret = snd_soc_component_update_bits(dai->component,
0217                         ADAU7118_REG_SPT_CTRL1,
0218                         ADAU7118_TRISTATE_MASK,
0219                         ADAU7118_TRISTATE(tristate));
0220     if (ret < 0)
0221         return ret;
0222 
0223     return 0;
0224 }
0225 
0226 static int adau7118_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
0227                  unsigned int rx_mask, int slots,
0228                  int slot_width)
0229 {
0230     struct adau7118_data *st =
0231         snd_soc_component_get_drvdata(dai->component);
0232     int ret = 0;
0233     u32 regval;
0234 
0235     dev_dbg(st->dev, "Set tdm, slots:%d width:%d\n", slots, slot_width);
0236 
0237     switch (slot_width) {
0238     case 32:
0239         regval = ADAU7118_SLOT_WIDTH(0);
0240         break;
0241     case 24:
0242         regval = ADAU7118_SLOT_WIDTH(2);
0243         break;
0244     case 16:
0245         regval = ADAU7118_SLOT_WIDTH(1);
0246         break;
0247     default:
0248         dev_err(st->dev, "Invalid slot width:%d\n", slot_width);
0249         return -EINVAL;
0250     }
0251 
0252     ret = snd_soc_component_update_bits(dai->component,
0253                         ADAU7118_REG_SPT_CTRL1,
0254                         ADAU7118_SLOT_WIDTH_MASK, regval);
0255     if (ret < 0)
0256         return ret;
0257 
0258     st->slot_width = slot_width;
0259     st->slots = slots;
0260 
0261     return 0;
0262 }
0263 
0264 static int adau7118_hw_params(struct snd_pcm_substream *substream,
0265                   struct snd_pcm_hw_params *params,
0266                   struct snd_soc_dai *dai)
0267 {
0268     struct adau7118_data *st =
0269         snd_soc_component_get_drvdata(dai->component);
0270     u32 data_width = params_width(params), slots_width;
0271     int ret;
0272     u32 regval;
0273 
0274     if (!st->slots) {
0275         /* set stereo mode */
0276         ret = snd_soc_component_update_bits(dai->component,
0277                             ADAU7118_REG_SPT_CTRL1,
0278                             ADAU7118_SAI_MODE_MASK,
0279                             ADAU7118_SAI_MODE(0));
0280         if (ret < 0)
0281             return ret;
0282 
0283         slots_width = 32;
0284     } else {
0285         slots_width = st->slot_width;
0286     }
0287 
0288     if (data_width > slots_width) {
0289         dev_err(st->dev, "Invalid data_width:%d, slots_width:%d",
0290             data_width, slots_width);
0291         return -EINVAL;
0292     }
0293 
0294     if (st->right_j) {
0295         switch (slots_width - data_width) {
0296         case 8:
0297             /* delay bclck by 8 */
0298             regval = ADAU7118_DATA_FMT(2);
0299             break;
0300         case 12:
0301             /* delay bclck by 12 */
0302             regval = ADAU7118_DATA_FMT(3);
0303             break;
0304         case 16:
0305             /* delay bclck by 16 */
0306             regval = ADAU7118_DATA_FMT(4);
0307             break;
0308         default:
0309             dev_err(st->dev,
0310                 "Cannot set right_j setting, slot_w:%d, data_w:%d\n",
0311                     slots_width, data_width);
0312             return -EINVAL;
0313         }
0314 
0315         ret = snd_soc_component_update_bits(dai->component,
0316                             ADAU7118_REG_SPT_CTRL1,
0317                             ADAU7118_DATA_FMT_MASK,
0318                             regval);
0319         if (ret < 0)
0320             return ret;
0321     }
0322 
0323     return 0;
0324 }
0325 
0326 static int adau7118_set_bias_level(struct snd_soc_component *component,
0327                    enum snd_soc_bias_level level)
0328 {
0329     struct adau7118_data *st = snd_soc_component_get_drvdata(component);
0330     int ret = 0;
0331 
0332     dev_dbg(st->dev, "Set bias level %d\n", level);
0333 
0334     switch (level) {
0335     case SND_SOC_BIAS_ON:
0336     case SND_SOC_BIAS_PREPARE:
0337         break;
0338 
0339     case SND_SOC_BIAS_STANDBY:
0340         if (snd_soc_component_get_bias_level(component) ==
0341                             SND_SOC_BIAS_OFF) {
0342             /* power on */
0343             ret = regulator_enable(st->iovdd);
0344             if (ret)
0345                 return ret;
0346 
0347             /* there's no timing constraints before enabling dvdd */
0348             ret = regulator_enable(st->dvdd);
0349             if (ret) {
0350                 regulator_disable(st->iovdd);
0351                 return ret;
0352             }
0353 
0354             if (st->hw_mode)
0355                 return 0;
0356 
0357             regcache_cache_only(st->map, false);
0358             /* sync cache */
0359             ret = snd_soc_component_cache_sync(component);
0360         }
0361         break;
0362     case SND_SOC_BIAS_OFF:
0363         /* power off */
0364         ret = regulator_disable(st->dvdd);
0365         if (ret)
0366             return ret;
0367 
0368         ret = regulator_disable(st->iovdd);
0369         if (ret)
0370             return ret;
0371 
0372         if (st->hw_mode)
0373             return 0;
0374 
0375         /* cache only */
0376         regcache_mark_dirty(st->map);
0377         regcache_cache_only(st->map, true);
0378 
0379         break;
0380     }
0381 
0382     return ret;
0383 }
0384 
0385 static int adau7118_component_probe(struct snd_soc_component *component)
0386 {
0387     struct adau7118_data *st = snd_soc_component_get_drvdata(component);
0388     struct snd_soc_dapm_context *dapm =
0389                     snd_soc_component_get_dapm(component);
0390     int ret = 0;
0391 
0392     if (st->hw_mode) {
0393         ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_hw,
0394                     ARRAY_SIZE(adau7118_widgets_hw));
0395         if (ret)
0396             return ret;
0397 
0398         ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_hw,
0399                           ARRAY_SIZE(adau7118_routes_hw));
0400     } else {
0401         snd_soc_component_init_regmap(component, st->map);
0402         ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_sw,
0403                     ARRAY_SIZE(adau7118_widgets_sw));
0404         if (ret)
0405             return ret;
0406 
0407         ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_sw,
0408                           ARRAY_SIZE(adau7118_routes_sw));
0409     }
0410 
0411     return ret;
0412 }
0413 
0414 static const struct snd_soc_dai_ops adau7118_ops = {
0415     .hw_params = adau7118_hw_params,
0416     .set_channel_map = adau7118_set_channel_map,
0417     .set_fmt = adau7118_set_fmt,
0418     .set_tdm_slot = adau7118_set_tdm_slot,
0419     .set_tristate = adau7118_set_tristate,
0420 };
0421 
0422 static struct snd_soc_dai_driver adau7118_dai = {
0423     .name = "adau7118-hifi-capture",
0424     .capture = {
0425         .stream_name = "Capture",
0426         .channels_min = 1,
0427         .channels_max = 8,
0428         .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |
0429             SNDRV_PCM_FMTBIT_S20_LE | SNDRV_PCM_FMTBIT_S24_LE |
0430             SNDRV_PCM_FMTBIT_S24_3LE,
0431         .rates = SNDRV_PCM_RATE_CONTINUOUS,
0432         .rate_min = 4000,
0433         .rate_max = 192000,
0434         .sig_bits = 24,
0435     },
0436 };
0437 
0438 static const struct snd_soc_component_driver adau7118_component_driver = {
0439     .probe          = adau7118_component_probe,
0440     .set_bias_level     = adau7118_set_bias_level,
0441     .dapm_widgets       = adau7118_widgets,
0442     .num_dapm_widgets   = ARRAY_SIZE(adau7118_widgets),
0443     .use_pmdown_time    = 1,
0444     .endianness     = 1,
0445 };
0446 
0447 static void adau7118_regulator_disable(void *data)
0448 {
0449     struct adau7118_data *st = data;
0450     int ret;
0451     /*
0452      * If we fail to disable DVDD, don't bother in trying IOVDD. We
0453      * actually don't want to be left in the situation where DVDD
0454      * is enabled and IOVDD is disabled.
0455      */
0456     ret = regulator_disable(st->dvdd);
0457     if (ret)
0458         return;
0459 
0460     regulator_disable(st->iovdd);
0461 }
0462 
0463 static int adau7118_regulator_setup(struct adau7118_data *st)
0464 {
0465     st->iovdd = devm_regulator_get(st->dev, "iovdd");
0466     if (IS_ERR(st->iovdd)) {
0467         dev_err(st->dev, "Could not get iovdd: %ld\n",
0468             PTR_ERR(st->iovdd));
0469         return PTR_ERR(st->iovdd);
0470     }
0471 
0472     st->dvdd = devm_regulator_get(st->dev, "dvdd");
0473     if (IS_ERR(st->dvdd)) {
0474         dev_err(st->dev, "Could not get dvdd: %ld\n",
0475             PTR_ERR(st->dvdd));
0476         return PTR_ERR(st->dvdd);
0477     }
0478     /* just assume the device is in reset */
0479     if (!st->hw_mode) {
0480         regcache_mark_dirty(st->map);
0481         regcache_cache_only(st->map, true);
0482     }
0483 
0484     return devm_add_action_or_reset(st->dev, adau7118_regulator_disable,
0485                     st);
0486 }
0487 
0488 static int adau7118_parset_dt(const struct adau7118_data *st)
0489 {
0490     int ret;
0491     u32 dec_ratio = 0;
0492     /* 4 inputs */
0493     u32 clk_map[4], regval;
0494 
0495     if (st->hw_mode)
0496         return 0;
0497 
0498     ret = device_property_read_u32(st->dev, "adi,decimation-ratio",
0499                        &dec_ratio);
0500     if (!ret) {
0501         switch (dec_ratio) {
0502         case 64:
0503             regval = ADAU7118_DEC_RATIO(0);
0504             break;
0505         case 32:
0506             regval = ADAU7118_DEC_RATIO(1);
0507             break;
0508         case 16:
0509             regval = ADAU7118_DEC_RATIO(2);
0510             break;
0511         default:
0512             dev_err(st->dev, "Invalid dec ratio: %u", dec_ratio);
0513             return -EINVAL;
0514         }
0515 
0516         ret = regmap_update_bits(st->map,
0517                      ADAU7118_REG_DEC_RATIO_CLK_MAP,
0518                      ADAU7118_DEC_RATIO_MASK, regval);
0519         if (ret)
0520             return ret;
0521     }
0522 
0523     ret = device_property_read_u32_array(st->dev, "adi,pdm-clk-map",
0524                          clk_map, ARRAY_SIZE(clk_map));
0525     if (!ret) {
0526         int pdm;
0527         u32 _clk_map = 0;
0528 
0529         for (pdm = 0; pdm < ARRAY_SIZE(clk_map); pdm++)
0530             _clk_map |= (clk_map[pdm] << (pdm + 4));
0531 
0532         ret = regmap_update_bits(st->map,
0533                      ADAU7118_REG_DEC_RATIO_CLK_MAP,
0534                      ADAU7118_CLK_MAP_MASK, _clk_map);
0535         if (ret)
0536             return ret;
0537     }
0538 
0539     return 0;
0540 }
0541 
0542 int adau7118_probe(struct device *dev, struct regmap *map, bool hw_mode)
0543 {
0544     struct adau7118_data *st;
0545     int ret;
0546 
0547     st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
0548     if (!st)
0549         return -ENOMEM;
0550 
0551     st->dev = dev;
0552     st->hw_mode = hw_mode;
0553     dev_set_drvdata(dev, st);
0554 
0555     if (!hw_mode) {
0556         st->map = map;
0557         adau7118_dai.ops = &adau7118_ops;
0558         /*
0559          * Perform a full soft reset. This will set all register's
0560          * with their reset values.
0561          */
0562         ret = regmap_update_bits(map, ADAU7118_REG_RESET,
0563                      ADAU7118_FULL_SOFT_R_MASK,
0564                      ADAU7118_FULL_SOFT_R(1));
0565         if (ret)
0566             return ret;
0567     }
0568 
0569     ret = adau7118_parset_dt(st);
0570     if (ret)
0571         return ret;
0572 
0573     ret = adau7118_regulator_setup(st);
0574     if (ret)
0575         return ret;
0576 
0577     return devm_snd_soc_register_component(dev,
0578                            &adau7118_component_driver,
0579                            &adau7118_dai, 1);
0580 }
0581 EXPORT_SYMBOL_GPL(adau7118_probe);
0582 
0583 MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
0584 MODULE_DESCRIPTION("ADAU7118 8 channel PDM-to-I2S/TDM Converter driver");
0585 MODULE_LICENSE("GPL");