Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * wm8523.c  --  WM8523 ALSA SoC Audio driver
0004  *
0005  * Copyright 2009 Wolfson Microelectronics plc
0006  *
0007  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/moduleparam.h>
0012 #include <linux/init.h>
0013 #include <linux/delay.h>
0014 #include <linux/pm.h>
0015 #include <linux/i2c.h>
0016 #include <linux/regmap.h>
0017 #include <linux/regulator/consumer.h>
0018 #include <linux/slab.h>
0019 #include <linux/of_device.h>
0020 #include <sound/core.h>
0021 #include <sound/pcm.h>
0022 #include <sound/pcm_params.h>
0023 #include <sound/soc.h>
0024 #include <sound/initval.h>
0025 #include <sound/tlv.h>
0026 
0027 #include "wm8523.h"
0028 
0029 #define WM8523_NUM_SUPPLIES 2
0030 static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
0031     "AVDD",
0032     "LINEVDD",
0033 };
0034 
0035 #define WM8523_NUM_RATES 7
0036 
0037 /* codec private data */
0038 struct wm8523_priv {
0039     struct regmap *regmap;
0040     struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
0041     unsigned int sysclk;
0042     unsigned int rate_constraint_list[WM8523_NUM_RATES];
0043     struct snd_pcm_hw_constraint_list rate_constraint;
0044 };
0045 
0046 static const struct reg_default wm8523_reg_defaults[] = {
0047     { 2, 0x0000 },     /* R2 - PSCTRL1 */
0048     { 3, 0x1812 },     /* R3 - AIF_CTRL1 */
0049     { 4, 0x0000 },     /* R4 - AIF_CTRL2 */
0050     { 5, 0x0001 },     /* R5 - DAC_CTRL3 */
0051     { 6, 0x0190 },     /* R6 - DAC_GAINL */
0052     { 7, 0x0190 },     /* R7 - DAC_GAINR */
0053     { 8, 0x0000 },     /* R8 - ZERO_DETECT */
0054 };
0055 
0056 static bool wm8523_volatile_register(struct device *dev, unsigned int reg)
0057 {
0058     switch (reg) {
0059     case WM8523_DEVICE_ID:
0060     case WM8523_REVISION:
0061         return true;
0062     default:
0063         return false;
0064     }
0065 }
0066 
0067 static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0);
0068 
0069 static const char *wm8523_zd_count_text[] = {
0070     "1024",
0071     "2048",
0072 };
0073 
0074 static SOC_ENUM_SINGLE_DECL(wm8523_zc_count, WM8523_ZERO_DETECT, 0,
0075                 wm8523_zd_count_text);
0076 
0077 static const struct snd_kcontrol_new wm8523_controls[] = {
0078 SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
0079          0, 448, 0, dac_tlv),
0080 SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
0081 SOC_SINGLE("Playback Deemphasis Switch", WM8523_AIF_CTRL1, 8, 1, 0),
0082 SOC_DOUBLE("Playback Switch", WM8523_DAC_CTRL3, 2, 3, 1, 1),
0083 SOC_SINGLE("Volume Ramp Up Switch", WM8523_DAC_CTRL3, 1, 1, 0),
0084 SOC_SINGLE("Volume Ramp Down Switch", WM8523_DAC_CTRL3, 0, 1, 0),
0085 SOC_ENUM("Zero Detect Count", wm8523_zc_count),
0086 };
0087 
0088 static const struct snd_soc_dapm_widget wm8523_dapm_widgets[] = {
0089 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
0090 SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
0091 SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
0092 };
0093 
0094 static const struct snd_soc_dapm_route wm8523_dapm_routes[] = {
0095     { "LINEVOUTL", NULL, "DAC" },
0096     { "LINEVOUTR", NULL, "DAC" },
0097 };
0098 
0099 static const struct {
0100     int value;
0101     int ratio;
0102 } lrclk_ratios[WM8523_NUM_RATES] = {
0103     { 1, 128 },
0104     { 2, 192 },
0105     { 3, 256 },
0106     { 4, 384 },
0107     { 5, 512 },
0108     { 6, 768 },
0109     { 7, 1152 },
0110 };
0111 
0112 static const struct {
0113     int value;
0114     int ratio;
0115 } bclk_ratios[] = {
0116     { 2, 32 },
0117     { 3, 64 },
0118     { 4, 128 },
0119 };
0120 
0121 static int wm8523_startup(struct snd_pcm_substream *substream,
0122               struct snd_soc_dai *dai)
0123 {
0124     struct snd_soc_component *component = dai->component;
0125     struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
0126 
0127     /* The set of sample rates that can be supported depends on the
0128      * MCLK supplied to the CODEC - enforce this.
0129      */
0130     if (!wm8523->sysclk) {
0131         dev_err(component->dev,
0132             "No MCLK configured, call set_sysclk() on init\n");
0133         return -EINVAL;
0134     }
0135 
0136     snd_pcm_hw_constraint_list(substream->runtime, 0,
0137                    SNDRV_PCM_HW_PARAM_RATE,
0138                    &wm8523->rate_constraint);
0139 
0140     return 0;
0141 }
0142 
0143 static int wm8523_hw_params(struct snd_pcm_substream *substream,
0144                 struct snd_pcm_hw_params *params,
0145                 struct snd_soc_dai *dai)
0146 {
0147     struct snd_soc_component *component = dai->component;
0148     struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
0149     int i;
0150     u16 aifctrl1 = snd_soc_component_read(component, WM8523_AIF_CTRL1);
0151     u16 aifctrl2 = snd_soc_component_read(component, WM8523_AIF_CTRL2);
0152 
0153     /* Find a supported LRCLK ratio */
0154     for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
0155         if (wm8523->sysclk / params_rate(params) ==
0156             lrclk_ratios[i].ratio)
0157             break;
0158     }
0159 
0160     /* Should never happen, should be handled by constraints */
0161     if (i == ARRAY_SIZE(lrclk_ratios)) {
0162         dev_err(component->dev, "MCLK/fs ratio %d unsupported\n",
0163             wm8523->sysclk / params_rate(params));
0164         return -EINVAL;
0165     }
0166 
0167     aifctrl2 &= ~WM8523_SR_MASK;
0168     aifctrl2 |= lrclk_ratios[i].value;
0169 
0170     if (aifctrl1 & WM8523_AIF_MSTR) {
0171         /* Find a fs->bclk ratio */
0172         for (i = 0; i < ARRAY_SIZE(bclk_ratios); i++)
0173             if (params_width(params) * 2 <= bclk_ratios[i].ratio)
0174                 break;
0175 
0176         if (i == ARRAY_SIZE(bclk_ratios)) {
0177             dev_err(component->dev,
0178                 "No matching BCLK/fs ratio for word length %d\n",
0179                 params_width(params));
0180             return -EINVAL;
0181         }
0182 
0183         aifctrl2 &= ~WM8523_BCLKDIV_MASK;
0184         aifctrl2 |= bclk_ratios[i].value << WM8523_BCLKDIV_SHIFT;
0185     }
0186 
0187     aifctrl1 &= ~WM8523_WL_MASK;
0188     switch (params_width(params)) {
0189     case 16:
0190         break;
0191     case 20:
0192         aifctrl1 |= 0x8;
0193         break;
0194     case 24:
0195         aifctrl1 |= 0x10;
0196         break;
0197     case 32:
0198         aifctrl1 |= 0x18;
0199         break;
0200     }
0201 
0202     snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1);
0203     snd_soc_component_write(component, WM8523_AIF_CTRL2, aifctrl2);
0204 
0205     return 0;
0206 }
0207 
0208 static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
0209         int clk_id, unsigned int freq, int dir)
0210 {
0211     struct snd_soc_component *component = codec_dai->component;
0212     struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
0213     unsigned int val;
0214     int i;
0215 
0216     wm8523->sysclk = freq;
0217 
0218     wm8523->rate_constraint.count = 0;
0219     for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
0220         val = freq / lrclk_ratios[i].ratio;
0221         /* Check that it's a standard rate since core can't
0222          * cope with others and having the odd rates confuses
0223          * constraint matching.
0224          */
0225         switch (val) {
0226         case 8000:
0227         case 11025:
0228         case 16000:
0229         case 22050:
0230         case 32000:
0231         case 44100:
0232         case 48000:
0233         case 64000:
0234         case 88200:
0235         case 96000:
0236         case 176400:
0237         case 192000:
0238             dev_dbg(component->dev, "Supported sample rate: %dHz\n",
0239                 val);
0240             wm8523->rate_constraint_list[i] = val;
0241             wm8523->rate_constraint.count++;
0242             break;
0243         default:
0244             dev_dbg(component->dev, "Skipping sample rate: %dHz\n",
0245                 val);
0246         }
0247     }
0248 
0249     /* Need at least one supported rate... */
0250     if (wm8523->rate_constraint.count == 0)
0251         return -EINVAL;
0252 
0253     return 0;
0254 }
0255 
0256 
0257 static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
0258         unsigned int fmt)
0259 {
0260     struct snd_soc_component *component = codec_dai->component;
0261     u16 aifctrl1 = snd_soc_component_read(component, WM8523_AIF_CTRL1);
0262 
0263     aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK |
0264               WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK);
0265 
0266     switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
0267     case SND_SOC_DAIFMT_CBM_CFM:
0268         aifctrl1 |= WM8523_AIF_MSTR;
0269         break;
0270     case SND_SOC_DAIFMT_CBS_CFS:
0271         break;
0272     default:
0273         return -EINVAL;
0274     }
0275 
0276     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0277     case SND_SOC_DAIFMT_I2S:
0278         aifctrl1 |= 0x0002;
0279         break;
0280     case SND_SOC_DAIFMT_RIGHT_J:
0281         break;
0282     case SND_SOC_DAIFMT_LEFT_J:
0283         aifctrl1 |= 0x0001;
0284         break;
0285     case SND_SOC_DAIFMT_DSP_A:
0286         aifctrl1 |= 0x0003;
0287         break;
0288     case SND_SOC_DAIFMT_DSP_B:
0289         aifctrl1 |= 0x0023;
0290         break;
0291     default:
0292         return -EINVAL;
0293     }
0294 
0295     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0296     case SND_SOC_DAIFMT_NB_NF:
0297         break;
0298     case SND_SOC_DAIFMT_IB_IF:
0299         aifctrl1 |= WM8523_BCLK_INV | WM8523_LRCLK_INV;
0300         break;
0301     case SND_SOC_DAIFMT_IB_NF:
0302         aifctrl1 |= WM8523_BCLK_INV;
0303         break;
0304     case SND_SOC_DAIFMT_NB_IF:
0305         aifctrl1 |= WM8523_LRCLK_INV;
0306         break;
0307     default:
0308         return -EINVAL;
0309     }
0310 
0311     snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1);
0312 
0313     return 0;
0314 }
0315 
0316 static int wm8523_set_bias_level(struct snd_soc_component *component,
0317                  enum snd_soc_bias_level level)
0318 {
0319     struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
0320     int ret;
0321 
0322     switch (level) {
0323     case SND_SOC_BIAS_ON:
0324         break;
0325 
0326     case SND_SOC_BIAS_PREPARE:
0327         /* Full power on */
0328         snd_soc_component_update_bits(component, WM8523_PSCTRL1,
0329                     WM8523_SYS_ENA_MASK, 3);
0330         break;
0331 
0332     case SND_SOC_BIAS_STANDBY:
0333         if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
0334             ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
0335                             wm8523->supplies);
0336             if (ret != 0) {
0337                 dev_err(component->dev,
0338                     "Failed to enable supplies: %d\n",
0339                     ret);
0340                 return ret;
0341             }
0342 
0343             /* Sync back default/cached values */
0344             regcache_sync(wm8523->regmap);
0345 
0346             /* Initial power up */
0347             snd_soc_component_update_bits(component, WM8523_PSCTRL1,
0348                         WM8523_SYS_ENA_MASK, 1);
0349 
0350             msleep(100);
0351         }
0352 
0353         /* Power up to mute */
0354         snd_soc_component_update_bits(component, WM8523_PSCTRL1,
0355                     WM8523_SYS_ENA_MASK, 2);
0356 
0357         break;
0358 
0359     case SND_SOC_BIAS_OFF:
0360         /* The chip runs through the power down sequence for us. */
0361         snd_soc_component_update_bits(component, WM8523_PSCTRL1,
0362                     WM8523_SYS_ENA_MASK, 0);
0363         msleep(100);
0364 
0365         regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies),
0366                        wm8523->supplies);
0367         break;
0368     }
0369     return 0;
0370 }
0371 
0372 #define WM8523_RATES SNDRV_PCM_RATE_8000_192000
0373 
0374 #define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
0375             SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
0376 
0377 static const struct snd_soc_dai_ops wm8523_dai_ops = {
0378     .startup    = wm8523_startup,
0379     .hw_params  = wm8523_hw_params,
0380     .set_sysclk = wm8523_set_dai_sysclk,
0381     .set_fmt    = wm8523_set_dai_fmt,
0382 };
0383 
0384 static struct snd_soc_dai_driver wm8523_dai = {
0385     .name = "wm8523-hifi",
0386     .playback = {
0387         .stream_name = "Playback",
0388         .channels_min = 2,  /* Mono modes not yet supported */
0389         .channels_max = 2,
0390         .rates = WM8523_RATES,
0391         .formats = WM8523_FORMATS,
0392     },
0393     .ops = &wm8523_dai_ops,
0394 };
0395 
0396 static int wm8523_probe(struct snd_soc_component *component)
0397 {
0398     struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
0399 
0400     wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
0401     wm8523->rate_constraint.count =
0402         ARRAY_SIZE(wm8523->rate_constraint_list);
0403 
0404     /* Change some default settings - latch VU and enable ZC */
0405     snd_soc_component_update_bits(component, WM8523_DAC_GAINR,
0406                 WM8523_DACR_VU, WM8523_DACR_VU);
0407     snd_soc_component_update_bits(component, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
0408 
0409     return 0;
0410 }
0411 
0412 static const struct snd_soc_component_driver soc_component_dev_wm8523 = {
0413     .probe          = wm8523_probe,
0414     .set_bias_level     = wm8523_set_bias_level,
0415     .controls       = wm8523_controls,
0416     .num_controls       = ARRAY_SIZE(wm8523_controls),
0417     .dapm_widgets       = wm8523_dapm_widgets,
0418     .num_dapm_widgets   = ARRAY_SIZE(wm8523_dapm_widgets),
0419     .dapm_routes        = wm8523_dapm_routes,
0420     .num_dapm_routes    = ARRAY_SIZE(wm8523_dapm_routes),
0421     .suspend_bias_off   = 1,
0422     .idle_bias_on       = 1,
0423     .use_pmdown_time    = 1,
0424     .endianness     = 1,
0425 };
0426 
0427 static const struct of_device_id wm8523_of_match[] = {
0428     { .compatible = "wlf,wm8523" },
0429     { },
0430 };
0431 MODULE_DEVICE_TABLE(of, wm8523_of_match);
0432 
0433 static const struct regmap_config wm8523_regmap = {
0434     .reg_bits = 8,
0435     .val_bits = 16,
0436     .max_register = WM8523_ZERO_DETECT,
0437 
0438     .reg_defaults = wm8523_reg_defaults,
0439     .num_reg_defaults = ARRAY_SIZE(wm8523_reg_defaults),
0440     .cache_type = REGCACHE_RBTREE,
0441 
0442     .volatile_reg = wm8523_volatile_register,
0443 };
0444 
0445 static int wm8523_i2c_probe(struct i2c_client *i2c)
0446 {
0447     struct wm8523_priv *wm8523;
0448     unsigned int val;
0449     int ret, i;
0450 
0451     wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv),
0452                   GFP_KERNEL);
0453     if (wm8523 == NULL)
0454         return -ENOMEM;
0455 
0456     wm8523->regmap = devm_regmap_init_i2c(i2c, &wm8523_regmap);
0457     if (IS_ERR(wm8523->regmap)) {
0458         ret = PTR_ERR(wm8523->regmap);
0459         dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
0460         return ret;
0461     }
0462 
0463     for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
0464         wm8523->supplies[i].supply = wm8523_supply_names[i];
0465 
0466     ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8523->supplies),
0467                       wm8523->supplies);
0468     if (ret != 0) {
0469         dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
0470         return ret;
0471     }
0472 
0473     ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
0474                     wm8523->supplies);
0475     if (ret != 0) {
0476         dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
0477         return ret;
0478     }
0479 
0480     ret = regmap_read(wm8523->regmap, WM8523_DEVICE_ID, &val);
0481     if (ret < 0) {
0482         dev_err(&i2c->dev, "Failed to read ID register\n");
0483         goto err_enable;
0484     }
0485     if (val != 0x8523) {
0486         dev_err(&i2c->dev, "Device is not a WM8523, ID is %x\n", ret);
0487         ret = -EINVAL;
0488         goto err_enable;
0489     }
0490 
0491     ret = regmap_read(wm8523->regmap, WM8523_REVISION, &val);
0492     if (ret < 0) {
0493         dev_err(&i2c->dev, "Failed to read revision register\n");
0494         goto err_enable;
0495     }
0496     dev_info(&i2c->dev, "revision %c\n",
0497          (val & WM8523_CHIP_REV_MASK) + 'A');
0498 
0499     ret = regmap_write(wm8523->regmap, WM8523_DEVICE_ID, 0x8523);
0500     if (ret != 0) {
0501         dev_err(&i2c->dev, "Failed to reset device: %d\n", ret);
0502         goto err_enable;
0503     }
0504 
0505     regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
0506 
0507     i2c_set_clientdata(i2c, wm8523);
0508 
0509     ret = devm_snd_soc_register_component(&i2c->dev,
0510             &soc_component_dev_wm8523, &wm8523_dai, 1);
0511 
0512     return ret;
0513 
0514 err_enable:
0515     regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
0516     return ret;
0517 }
0518 
0519 static const struct i2c_device_id wm8523_i2c_id[] = {
0520     { "wm8523", 0 },
0521     { }
0522 };
0523 MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
0524 
0525 static struct i2c_driver wm8523_i2c_driver = {
0526     .driver = {
0527         .name = "wm8523",
0528         .of_match_table = wm8523_of_match,
0529     },
0530     .probe_new = wm8523_i2c_probe,
0531     .id_table = wm8523_i2c_id,
0532 };
0533 
0534 module_i2c_driver(wm8523_i2c_driver);
0535 
0536 MODULE_DESCRIPTION("ASoC WM8523 driver");
0537 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
0538 MODULE_LICENSE("GPL");