linux/sound/soc/codecs/wm8523.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * wm8523.c  --  WM8523 ALSA SoC Audio driver
   4 *
   5 * Copyright 2009 Wolfson Microelectronics plc
   6 *
   7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/moduleparam.h>
  12#include <linux/init.h>
  13#include <linux/delay.h>
  14#include <linux/pm.h>
  15#include <linux/i2c.h>
  16#include <linux/regmap.h>
  17#include <linux/regulator/consumer.h>
  18#include <linux/slab.h>
  19#include <linux/of_device.h>
  20#include <sound/core.h>
  21#include <sound/pcm.h>
  22#include <sound/pcm_params.h>
  23#include <sound/soc.h>
  24#include <sound/initval.h>
  25#include <sound/tlv.h>
  26
  27#include "wm8523.h"
  28
  29#define WM8523_NUM_SUPPLIES 2
  30static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
  31        "AVDD",
  32        "LINEVDD",
  33};
  34
  35#define WM8523_NUM_RATES 7
  36
  37/* codec private data */
  38struct wm8523_priv {
  39        struct regmap *regmap;
  40        struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
  41        unsigned int sysclk;
  42        unsigned int rate_constraint_list[WM8523_NUM_RATES];
  43        struct snd_pcm_hw_constraint_list rate_constraint;
  44};
  45
  46static const struct reg_default wm8523_reg_defaults[] = {
  47        { 2, 0x0000 },     /* R2 - PSCTRL1 */
  48        { 3, 0x1812 },     /* R3 - AIF_CTRL1 */
  49        { 4, 0x0000 },     /* R4 - AIF_CTRL2 */
  50        { 5, 0x0001 },     /* R5 - DAC_CTRL3 */
  51        { 6, 0x0190 },     /* R6 - DAC_GAINL */
  52        { 7, 0x0190 },     /* R7 - DAC_GAINR */
  53        { 8, 0x0000 },     /* R8 - ZERO_DETECT */
  54};
  55
  56static bool wm8523_volatile_register(struct device *dev, unsigned int reg)
  57{
  58        switch (reg) {
  59        case WM8523_DEVICE_ID:
  60        case WM8523_REVISION:
  61                return true;
  62        default:
  63                return false;
  64        }
  65}
  66
  67static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0);
  68
  69static const char *wm8523_zd_count_text[] = {
  70        "1024",
  71        "2048",
  72};
  73
  74static SOC_ENUM_SINGLE_DECL(wm8523_zc_count, WM8523_ZERO_DETECT, 0,
  75                            wm8523_zd_count_text);
  76
  77static const struct snd_kcontrol_new wm8523_controls[] = {
  78SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
  79                 0, 448, 0, dac_tlv),
  80SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
  81SOC_SINGLE("Playback Deemphasis Switch", WM8523_AIF_CTRL1, 8, 1, 0),
  82SOC_DOUBLE("Playback Switch", WM8523_DAC_CTRL3, 2, 3, 1, 1),
  83SOC_SINGLE("Volume Ramp Up Switch", WM8523_DAC_CTRL3, 1, 1, 0),
  84SOC_SINGLE("Volume Ramp Down Switch", WM8523_DAC_CTRL3, 0, 1, 0),
  85SOC_ENUM("Zero Detect Count", wm8523_zc_count),
  86};
  87
  88static const struct snd_soc_dapm_widget wm8523_dapm_widgets[] = {
  89SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
  90SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
  91SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
  92};
  93
  94static const struct snd_soc_dapm_route wm8523_dapm_routes[] = {
  95        { "LINEVOUTL", NULL, "DAC" },
  96        { "LINEVOUTR", NULL, "DAC" },
  97};
  98
  99static const struct {
 100        int value;
 101        int ratio;
 102} lrclk_ratios[WM8523_NUM_RATES] = {
 103        { 1, 128 },
 104        { 2, 192 },
 105        { 3, 256 },
 106        { 4, 384 },
 107        { 5, 512 },
 108        { 6, 768 },
 109        { 7, 1152 },
 110};
 111
 112static const struct {
 113        int value;
 114        int ratio;
 115} bclk_ratios[] = {
 116        { 2, 32 },
 117        { 3, 64 },
 118        { 4, 128 },
 119};
 120
 121static int wm8523_startup(struct snd_pcm_substream *substream,
 122                          struct snd_soc_dai *dai)
 123{
 124        struct snd_soc_component *component = dai->component;
 125        struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 126
 127        /* The set of sample rates that can be supported depends on the
 128         * MCLK supplied to the CODEC - enforce this.
 129         */
 130        if (!wm8523->sysclk) {
 131                dev_err(component->dev,
 132                        "No MCLK configured, call set_sysclk() on init\n");
 133                return -EINVAL;
 134        }
 135
 136        snd_pcm_hw_constraint_list(substream->runtime, 0,
 137                                   SNDRV_PCM_HW_PARAM_RATE,
 138                                   &wm8523->rate_constraint);
 139
 140        return 0;
 141}
 142
 143static int wm8523_hw_params(struct snd_pcm_substream *substream,
 144                            struct snd_pcm_hw_params *params,
 145                            struct snd_soc_dai *dai)
 146{
 147        struct snd_soc_component *component = dai->component;
 148        struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 149        int i;
 150        u16 aifctrl1 = snd_soc_component_read(component, WM8523_AIF_CTRL1);
 151        u16 aifctrl2 = snd_soc_component_read(component, WM8523_AIF_CTRL2);
 152
 153        /* Find a supported LRCLK ratio */
 154        for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
 155                if (wm8523->sysclk / params_rate(params) ==
 156                    lrclk_ratios[i].ratio)
 157                        break;
 158        }
 159
 160        /* Should never happen, should be handled by constraints */
 161        if (i == ARRAY_SIZE(lrclk_ratios)) {
 162                dev_err(component->dev, "MCLK/fs ratio %d unsupported\n",
 163                        wm8523->sysclk / params_rate(params));
 164                return -EINVAL;
 165        }
 166
 167        aifctrl2 &= ~WM8523_SR_MASK;
 168        aifctrl2 |= lrclk_ratios[i].value;
 169
 170        if (aifctrl1 & WM8523_AIF_MSTR) {
 171                /* Find a fs->bclk ratio */
 172                for (i = 0; i < ARRAY_SIZE(bclk_ratios); i++)
 173                        if (params_width(params) * 2 <= bclk_ratios[i].ratio)
 174                                break;
 175
 176                if (i == ARRAY_SIZE(bclk_ratios)) {
 177                        dev_err(component->dev,
 178                                "No matching BCLK/fs ratio for word length %d\n",
 179                                params_width(params));
 180                        return -EINVAL;
 181                }
 182
 183                aifctrl2 &= ~WM8523_BCLKDIV_MASK;
 184                aifctrl2 |= bclk_ratios[i].value << WM8523_BCLKDIV_SHIFT;
 185        }
 186
 187        aifctrl1 &= ~WM8523_WL_MASK;
 188        switch (params_width(params)) {
 189        case 16:
 190                break;
 191        case 20:
 192                aifctrl1 |= 0x8;
 193                break;
 194        case 24:
 195                aifctrl1 |= 0x10;
 196                break;
 197        case 32:
 198                aifctrl1 |= 0x18;
 199                break;
 200        }
 201
 202        snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1);
 203        snd_soc_component_write(component, WM8523_AIF_CTRL2, aifctrl2);
 204
 205        return 0;
 206}
 207
 208static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 209                int clk_id, unsigned int freq, int dir)
 210{
 211        struct snd_soc_component *component = codec_dai->component;
 212        struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 213        unsigned int val;
 214        int i;
 215
 216        wm8523->sysclk = freq;
 217
 218        wm8523->rate_constraint.count = 0;
 219        for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
 220                val = freq / lrclk_ratios[i].ratio;
 221                /* Check that it's a standard rate since core can't
 222                 * cope with others and having the odd rates confuses
 223                 * constraint matching.
 224                 */
 225                switch (val) {
 226                case 8000:
 227                case 11025:
 228                case 16000:
 229                case 22050:
 230                case 32000:
 231                case 44100:
 232                case 48000:
 233                case 64000:
 234                case 88200:
 235                case 96000:
 236                case 176400:
 237                case 192000:
 238                        dev_dbg(component->dev, "Supported sample rate: %dHz\n",
 239                                val);
 240                        wm8523->rate_constraint_list[i] = val;
 241                        wm8523->rate_constraint.count++;
 242                        break;
 243                default:
 244                        dev_dbg(component->dev, "Skipping sample rate: %dHz\n",
 245                                val);
 246                }
 247        }
 248
 249        /* Need at least one supported rate... */
 250        if (wm8523->rate_constraint.count == 0)
 251                return -EINVAL;
 252
 253        return 0;
 254}
 255
 256
 257static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
 258                unsigned int fmt)
 259{
 260        struct snd_soc_component *component = codec_dai->component;
 261        u16 aifctrl1 = snd_soc_component_read(component, WM8523_AIF_CTRL1);
 262
 263        aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK |
 264                      WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK);
 265
 266        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 267        case SND_SOC_DAIFMT_CBM_CFM:
 268                aifctrl1 |= WM8523_AIF_MSTR;
 269                break;
 270        case SND_SOC_DAIFMT_CBS_CFS:
 271                break;
 272        default:
 273                return -EINVAL;
 274        }
 275
 276        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 277        case SND_SOC_DAIFMT_I2S:
 278                aifctrl1 |= 0x0002;
 279                break;
 280        case SND_SOC_DAIFMT_RIGHT_J:
 281                break;
 282        case SND_SOC_DAIFMT_LEFT_J:
 283                aifctrl1 |= 0x0001;
 284                break;
 285        case SND_SOC_DAIFMT_DSP_A:
 286                aifctrl1 |= 0x0003;
 287                break;
 288        case SND_SOC_DAIFMT_DSP_B:
 289                aifctrl1 |= 0x0023;
 290                break;
 291        default:
 292                return -EINVAL;
 293        }
 294
 295        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 296        case SND_SOC_DAIFMT_NB_NF:
 297                break;
 298        case SND_SOC_DAIFMT_IB_IF:
 299                aifctrl1 |= WM8523_BCLK_INV | WM8523_LRCLK_INV;
 300                break;
 301        case SND_SOC_DAIFMT_IB_NF:
 302                aifctrl1 |= WM8523_BCLK_INV;
 303                break;
 304        case SND_SOC_DAIFMT_NB_IF:
 305                aifctrl1 |= WM8523_LRCLK_INV;
 306                break;
 307        default:
 308                return -EINVAL;
 309        }
 310
 311        snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1);
 312
 313        return 0;
 314}
 315
 316static int wm8523_set_bias_level(struct snd_soc_component *component,
 317                                 enum snd_soc_bias_level level)
 318{
 319        struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 320        int ret;
 321
 322        switch (level) {
 323        case SND_SOC_BIAS_ON:
 324                break;
 325
 326        case SND_SOC_BIAS_PREPARE:
 327                /* Full power on */
 328                snd_soc_component_update_bits(component, WM8523_PSCTRL1,
 329                                    WM8523_SYS_ENA_MASK, 3);
 330                break;
 331
 332        case SND_SOC_BIAS_STANDBY:
 333                if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 334                        ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
 335                                                    wm8523->supplies);
 336                        if (ret != 0) {
 337                                dev_err(component->dev,
 338                                        "Failed to enable supplies: %d\n",
 339                                        ret);
 340                                return ret;
 341                        }
 342
 343                        /* Sync back default/cached values */
 344                        regcache_sync(wm8523->regmap);
 345
 346                        /* Initial power up */
 347                        snd_soc_component_update_bits(component, WM8523_PSCTRL1,
 348                                            WM8523_SYS_ENA_MASK, 1);
 349
 350                        msleep(100);
 351                }
 352
 353                /* Power up to mute */
 354                snd_soc_component_update_bits(component, WM8523_PSCTRL1,
 355                                    WM8523_SYS_ENA_MASK, 2);
 356
 357                break;
 358
 359        case SND_SOC_BIAS_OFF:
 360                /* The chip runs through the power down sequence for us. */
 361                snd_soc_component_update_bits(component, WM8523_PSCTRL1,
 362                                    WM8523_SYS_ENA_MASK, 0);
 363                msleep(100);
 364
 365                regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies),
 366                                       wm8523->supplies);
 367                break;
 368        }
 369        return 0;
 370}
 371
 372#define WM8523_RATES SNDRV_PCM_RATE_8000_192000
 373
 374#define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
 375                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 376
 377static const struct snd_soc_dai_ops wm8523_dai_ops = {
 378        .startup        = wm8523_startup,
 379        .hw_params      = wm8523_hw_params,
 380        .set_sysclk     = wm8523_set_dai_sysclk,
 381        .set_fmt        = wm8523_set_dai_fmt,
 382};
 383
 384static struct snd_soc_dai_driver wm8523_dai = {
 385        .name = "wm8523-hifi",
 386        .playback = {
 387                .stream_name = "Playback",
 388                .channels_min = 2,  /* Mono modes not yet supported */
 389                .channels_max = 2,
 390                .rates = WM8523_RATES,
 391                .formats = WM8523_FORMATS,
 392        },
 393        .ops = &wm8523_dai_ops,
 394};
 395
 396static int wm8523_probe(struct snd_soc_component *component)
 397{
 398        struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 399
 400        wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
 401        wm8523->rate_constraint.count =
 402                ARRAY_SIZE(wm8523->rate_constraint_list);
 403
 404        /* Change some default settings - latch VU and enable ZC */
 405        snd_soc_component_update_bits(component, WM8523_DAC_GAINR,
 406                            WM8523_DACR_VU, WM8523_DACR_VU);
 407        snd_soc_component_update_bits(component, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
 408
 409        return 0;
 410}
 411
 412static const struct snd_soc_component_driver soc_component_dev_wm8523 = {
 413        .probe                  = wm8523_probe,
 414        .set_bias_level         = wm8523_set_bias_level,
 415        .controls               = wm8523_controls,
 416        .num_controls           = ARRAY_SIZE(wm8523_controls),
 417        .dapm_widgets           = wm8523_dapm_widgets,
 418        .num_dapm_widgets       = ARRAY_SIZE(wm8523_dapm_widgets),
 419        .dapm_routes            = wm8523_dapm_routes,
 420        .num_dapm_routes        = ARRAY_SIZE(wm8523_dapm_routes),
 421        .suspend_bias_off       = 1,
 422        .idle_bias_on           = 1,
 423        .use_pmdown_time        = 1,
 424        .endianness             = 1,
 425        .non_legacy_dai_naming  = 1,
 426};
 427
 428static const struct of_device_id wm8523_of_match[] = {
 429        { .compatible = "wlf,wm8523" },
 430        { },
 431};
 432MODULE_DEVICE_TABLE(of, wm8523_of_match);
 433
 434static const struct regmap_config wm8523_regmap = {
 435        .reg_bits = 8,
 436        .val_bits = 16,
 437        .max_register = WM8523_ZERO_DETECT,
 438
 439        .reg_defaults = wm8523_reg_defaults,
 440        .num_reg_defaults = ARRAY_SIZE(wm8523_reg_defaults),
 441        .cache_type = REGCACHE_RBTREE,
 442
 443        .volatile_reg = wm8523_volatile_register,
 444};
 445
 446static int wm8523_i2c_probe(struct i2c_client *i2c,
 447                            const struct i2c_device_id *id)
 448{
 449        struct wm8523_priv *wm8523;
 450        unsigned int val;
 451        int ret, i;
 452
 453        wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv),
 454                              GFP_KERNEL);
 455        if (wm8523 == NULL)
 456                return -ENOMEM;
 457
 458        wm8523->regmap = devm_regmap_init_i2c(i2c, &wm8523_regmap);
 459        if (IS_ERR(wm8523->regmap)) {
 460                ret = PTR_ERR(wm8523->regmap);
 461                dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
 462                return ret;
 463        }
 464
 465        for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
 466                wm8523->supplies[i].supply = wm8523_supply_names[i];
 467
 468        ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8523->supplies),
 469                                      wm8523->supplies);
 470        if (ret != 0) {
 471                dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
 472                return ret;
 473        }
 474
 475        ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
 476                                    wm8523->supplies);
 477        if (ret != 0) {
 478                dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
 479                return ret;
 480        }
 481
 482        ret = regmap_read(wm8523->regmap, WM8523_DEVICE_ID, &val);
 483        if (ret < 0) {
 484                dev_err(&i2c->dev, "Failed to read ID register\n");
 485                goto err_enable;
 486        }
 487        if (val != 0x8523) {
 488                dev_err(&i2c->dev, "Device is not a WM8523, ID is %x\n", ret);
 489                ret = -EINVAL;
 490                goto err_enable;
 491        }
 492
 493        ret = regmap_read(wm8523->regmap, WM8523_REVISION, &val);
 494        if (ret < 0) {
 495                dev_err(&i2c->dev, "Failed to read revision register\n");
 496                goto err_enable;
 497        }
 498        dev_info(&i2c->dev, "revision %c\n",
 499                 (val & WM8523_CHIP_REV_MASK) + 'A');
 500
 501        ret = regmap_write(wm8523->regmap, WM8523_DEVICE_ID, 0x8523);
 502        if (ret != 0) {
 503                dev_err(&i2c->dev, "Failed to reset device: %d\n", ret);
 504                goto err_enable;
 505        }
 506
 507        regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
 508
 509        i2c_set_clientdata(i2c, wm8523);
 510
 511        ret = devm_snd_soc_register_component(&i2c->dev,
 512                        &soc_component_dev_wm8523, &wm8523_dai, 1);
 513
 514        return ret;
 515
 516err_enable:
 517        regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
 518        return ret;
 519}
 520
 521static const struct i2c_device_id wm8523_i2c_id[] = {
 522        { "wm8523", 0 },
 523        { }
 524};
 525MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
 526
 527static struct i2c_driver wm8523_i2c_driver = {
 528        .driver = {
 529                .name = "wm8523",
 530                .of_match_table = wm8523_of_match,
 531        },
 532        .probe =    wm8523_i2c_probe,
 533        .id_table = wm8523_i2c_id,
 534};
 535
 536module_i2c_driver(wm8523_i2c_driver);
 537
 538MODULE_DESCRIPTION("ASoC WM8523 driver");
 539MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 540MODULE_LICENSE("GPL");
 541