uboot/drivers/sound/max98088.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * max98088.c -- MAX98088 ALSA SoC Audio driver
   4 *
   5 * Copyright 2010 Maxim Integrated Products
   6 *
   7 * Modified for U-Boot by Chih-Chung Chang (chihchung@chromium.org),
   8 * following the changes made in max98095.c
   9 */
  10
  11#include <common.h>
  12#include <audio_codec.h>
  13#include <div64.h>
  14#include <dm.h>
  15#include <i2c.h>
  16#include <i2s.h>
  17#include <log.h>
  18#include <sound.h>
  19#include <asm/gpio.h>
  20#include "maxim_codec.h"
  21#include "max98088.h"
  22
  23/* codec mclk clock divider coefficients. Index 0 is reserved. */
  24static const int rate_table[] = {0, 8000, 11025, 16000, 22050, 24000, 32000,
  25                                 44100, 48000, 88200, 96000};
  26
  27/*
  28 * codec mclk clock divider coefficients based on sampling rate
  29 *
  30 * @param rate sampling rate
  31 * @param value address of indexvalue to be stored
  32 *
  33 * @return      0 for success or negative error code.
  34 */
  35static int rate_value(int rate, u8 *value)
  36{
  37        int i;
  38
  39        for (i = 1; i < ARRAY_SIZE(rate_table); i++) {
  40                if (rate_table[i] >= rate) {
  41                        *value = i;
  42                        return 0;
  43                }
  44        }
  45        *value = 1;
  46
  47        return -EINVAL;
  48}
  49
  50/*
  51 * Sets hw params for max98088
  52 *
  53 * @priv: max98088 information pointer
  54 * @rate: Sampling rate
  55 * @bits_per_sample: Bits per sample
  56 *
  57 * @return -EIO for error, 0 for success.
  58 */
  59int max98088_hw_params(struct maxim_priv *priv, unsigned int rate,
  60                       unsigned int bits_per_sample)
  61{
  62        int error;
  63        u8 regval;
  64
  65        switch (bits_per_sample) {
  66        case 16:
  67                error = maxim_bic_or(priv, M98088_REG_DAI1_FORMAT,
  68                                     M98088_DAI_WS, 0);
  69                break;
  70        case 24:
  71                error = maxim_bic_or(priv, M98088_REG_DAI1_FORMAT,
  72                                     M98088_DAI_WS, M98088_DAI_WS);
  73                break;
  74        default:
  75                debug("%s: Illegal bits per sample %d.\n",
  76                      __func__, bits_per_sample);
  77                return -EINVAL;
  78        }
  79
  80        error |= maxim_bic_or(priv, M98088_REG_PWR_SYS, M98088_SHDNRUN, 0);
  81
  82        if (rate_value(rate, &regval)) {
  83                debug("%s: Failed to set sample rate to %d.\n",
  84                      __func__, rate);
  85                return -EIO;
  86        }
  87
  88        error |= maxim_bic_or(priv, M98088_REG_DAI1_CLKMODE,
  89                              M98088_CLKMODE_MASK, regval << 4);
  90        priv->rate = rate;
  91
  92        /* Update sample rate mode */
  93        if (rate < 50000)
  94                error |= maxim_bic_or(priv, M98088_REG_DAI1_FILTERS,
  95                                      M98088_DAI_DHF, 0);
  96        else
  97                error |= maxim_bic_or(priv, M98088_REG_DAI1_FILTERS,
  98                                      M98088_DAI_DHF, M98088_DAI_DHF);
  99
 100        error |= maxim_bic_or(priv, M98088_REG_PWR_SYS, M98088_SHDNRUN,
 101                              M98088_SHDNRUN);
 102
 103        if (error < 0) {
 104                debug("%s: Error setting hardware params.\n", __func__);
 105                return -EIO;
 106        }
 107        priv->rate = rate;
 108
 109        return 0;
 110}
 111
 112/*
 113 * Configures Audio interface system clock for the given frequency
 114 *
 115 * @priv: max98088 information
 116 * @freq: Sampling frequency in Hz
 117 *
 118 * @return -EIO for error, 0 for success.
 119 */
 120int max98088_set_sysclk(struct maxim_priv *priv, unsigned int freq)
 121{
 122        int error = 0;
 123        u8 pwr;
 124
 125        /* Requested clock frequency is already setup */
 126        if (freq == priv->sysclk)
 127                return 0;
 128
 129        /*
 130         * Setup clocks for slave mode, and using the PLL
 131         * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
 132         *         0x02 (when master clk is 20MHz to 30MHz)..
 133         */
 134        if (freq >= 10000000 && freq < 20000000) {
 135                error = maxim_i2c_write(priv, M98088_REG_SYS_CLK, 0x10);
 136        } else if ((freq >= 20000000) && (freq < 30000000)) {
 137                error = maxim_i2c_write(priv, M98088_REG_SYS_CLK, 0x20);
 138        } else {
 139                debug("%s: Invalid master clock frequency\n", __func__);
 140                return -EIO;
 141        }
 142
 143        error |= maxim_i2c_read(priv, M98088_REG_PWR_SYS, &pwr);
 144        if (pwr & M98088_SHDNRUN) {
 145                error |= maxim_bic_or(priv, M98088_REG_PWR_SYS,
 146                                      M98088_SHDNRUN, 0);
 147                error |= maxim_bic_or(priv, M98088_REG_PWR_SYS,
 148                                      M98088_SHDNRUN, M98088_SHDNRUN);
 149        }
 150
 151        debug("%s: Clock at %uHz\n", __func__, freq);
 152        if (error < 0)
 153                return -EIO;
 154
 155        priv->sysclk = freq;
 156
 157        return 0;
 158}
 159
 160/*
 161 * Sets Max98090 I2S format
 162 *
 163 * @priv: max98088 information
 164 * @fmt: i2S format - supports a subset of the options defined in i2s.h.
 165 *
 166 * @return -EIO for error, 0 for success.
 167 */
 168int max98088_set_fmt(struct maxim_priv *priv, int fmt)
 169{
 170        u8 reg15val;
 171        u8 reg14val = 0;
 172        int error = 0;
 173
 174        if (fmt == priv->fmt)
 175                return 0;
 176
 177        priv->fmt = fmt;
 178
 179        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 180        case SND_SOC_DAIFMT_CBS_CFS:
 181                /* Slave mode PLL */
 182                error |= maxim_i2c_write(priv, M98088_REG_DAI1_CLKCFG_HI,
 183                                            0x80);
 184                error |= maxim_i2c_write(priv, M98088_REG_DAI1_CLKCFG_LO,
 185                                            0x00);
 186                break;
 187        case SND_SOC_DAIFMT_CBM_CFM:
 188                /* Set to master mode */
 189                reg14val |= M98088_DAI_MAS;
 190                break;
 191        case SND_SOC_DAIFMT_CBS_CFM:
 192        case SND_SOC_DAIFMT_CBM_CFS:
 193        default:
 194                debug("%s: Clock mode unsupported\n", __func__);
 195                return -EINVAL;
 196        }
 197
 198        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 199        case SND_SOC_DAIFMT_I2S:
 200                reg14val |= M98088_DAI_DLY;
 201                break;
 202        case SND_SOC_DAIFMT_LEFT_J:
 203                break;
 204        default:
 205                debug("%s: Unrecognized format.\n", __func__);
 206                return -EINVAL;
 207        }
 208
 209        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 210        case SND_SOC_DAIFMT_NB_NF:
 211                break;
 212        case SND_SOC_DAIFMT_NB_IF:
 213                reg14val |= M98088_DAI_WCI;
 214                break;
 215        case SND_SOC_DAIFMT_IB_NF:
 216                reg14val |= M98088_DAI_BCI;
 217                break;
 218        case SND_SOC_DAIFMT_IB_IF:
 219                reg14val |= M98088_DAI_BCI | M98088_DAI_WCI;
 220                break;
 221        default:
 222                debug("%s: Unrecognized inversion settings.\n",  __func__);
 223                return -EINVAL;
 224        }
 225
 226        error |= maxim_bic_or(priv, M98088_REG_DAI1_FORMAT,
 227                              M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
 228                              M98088_DAI_WCI, reg14val);
 229        reg15val = M98088_DAI_BSEL64;
 230        error |= maxim_i2c_write(priv, M98088_REG_DAI1_CLOCK, reg15val);
 231
 232        if (error < 0) {
 233                debug("%s: Error setting i2s format.\n", __func__);
 234                return -EIO;
 235        }
 236
 237        return 0;
 238}
 239
 240/*
 241 * max98088_reset() - reset the audio codec
 242 *
 243 * @priv: max98088 information
 244 * @return -EIO for error, 0 for success.
 245 */
 246static int max98088_reset(struct maxim_priv *priv)
 247{
 248        int ret, i;
 249        u8 val;
 250
 251        /*
 252         * Reset to hardware default for registers, as there is not a soft
 253         * reset hardware control register.
 254         */
 255        for (i = M98088_REG_IRQ_ENABLE; i <= M98088_REG_PWR_SYS; i++) {
 256                switch (i) {
 257                case M98088_REG_BIAS_CNTL:
 258                        val = 0xf0;
 259                        break;
 260                case M98088_REG_DAC_BIAS2:
 261                        val = 0x0f;
 262                        break;
 263                default:
 264                        val = 0;
 265                }
 266                ret = maxim_i2c_write(priv, i, val);
 267                if (ret < 0) {
 268                        debug("%s: Failed to reset: %d\n", __func__, ret);
 269                        return ret;
 270                }
 271        }
 272
 273        return 0;
 274}
 275
 276/**
 277 * max98088_device_init() - Initialise max98088 codec device
 278 *
 279 * @priv: max98088 information
 280 *
 281 * @return -EIO for error, 0 for success.
 282 */
 283static int max98088_device_init(struct maxim_priv *priv)
 284{
 285        unsigned char id;
 286        int error = 0;
 287
 288        /* reset the codec, the DSP core, and disable all interrupts */
 289        error = max98088_reset(priv);
 290        if (error != 0) {
 291                debug("Reset\n");
 292                return error;
 293        }
 294
 295        /* initialize private data */
 296        priv->sysclk = -1U;
 297        priv->rate = -1U;
 298        priv->fmt = -1U;
 299
 300        error = maxim_i2c_read(priv, M98088_REG_REV_ID, &id);
 301        if (error < 0) {
 302                debug("%s: Failure reading hardware revision: %d\n",
 303                      __func__, id);
 304                return -EIO;
 305        }
 306        debug("%s: Hardware revision: %d\n", __func__, id);
 307
 308        return 0;
 309}
 310
 311static int max98088_setup_interface(struct maxim_priv *priv)
 312{
 313        int error;
 314
 315        /* Reading interrupt status to clear them */
 316        error = maxim_i2c_write(priv, M98088_REG_PWR_SYS, M98088_PWRSV);
 317        error |= maxim_i2c_write(priv, M98088_REG_IRQ_ENABLE, 0x00);
 318
 319        /*
 320         * initialize registers to hardware default configuring audio
 321         * interface2 to DAI1
 322         */
 323        error |= maxim_i2c_write(priv, M98088_REG_MIX_DAC,
 324                                 M98088_DAI1L_TO_DACL | M98088_DAI1R_TO_DACR);
 325        error |= maxim_i2c_write(priv, M98088_REG_BIAS_CNTL, 0xF0);
 326        error |= maxim_i2c_write(priv, M98088_REG_DAC_BIAS2, 0x0F);
 327        error |= maxim_i2c_write(priv, M98088_REG_DAI1_IOCFG,
 328                                 M98088_S2NORMAL | M98088_SDATA);
 329
 330        /*
 331         * route DACL and DACR output to headphone and speakers
 332         * Ordering: DACL, DACR, DACL, DACR
 333         */
 334        error |= maxim_i2c_write(priv, M98088_REG_MIX_SPK_LEFT, 1);
 335        error |= maxim_i2c_write(priv, M98088_REG_MIX_SPK_RIGHT, 1);
 336        error |= maxim_i2c_write(priv, M98088_REG_MIX_HP_LEFT, 1);
 337        error |= maxim_i2c_write(priv, M98088_REG_MIX_HP_RIGHT, 1);
 338
 339        /* set volume: -12db */
 340        error |= maxim_i2c_write(priv, M98088_REG_LVL_SPK_L, 0x0f);
 341        error |= maxim_i2c_write(priv, M98088_REG_LVL_SPK_R, 0x0f);
 342
 343        /* set volume: -22db */
 344        error |= maxim_i2c_write(priv, M98088_REG_LVL_HP_L, 0x0d);
 345        error |= maxim_i2c_write(priv, M98088_REG_LVL_HP_R, 0x0d);
 346
 347        /* power enable */
 348        error |= maxim_i2c_write(priv, M98088_REG_PWR_EN_OUT,
 349                                 M98088_HPLEN | M98088_HPREN | M98088_SPLEN |
 350                                 M98088_SPREN | M98088_DALEN | M98088_DAREN);
 351        if (error < 0)
 352                return -EIO;
 353
 354        return 0;
 355}
 356
 357static int max98088_do_init(struct maxim_priv *priv, int sampling_rate,
 358                            int mclk_freq, int bits_per_sample)
 359{
 360        int ret = 0;
 361
 362        ret = max98088_setup_interface(priv);
 363        if (ret < 0) {
 364                debug("%s: max98088 setup interface failed\n", __func__);
 365                return ret;
 366        }
 367
 368        ret = max98088_set_sysclk(priv, mclk_freq);
 369        if (ret < 0) {
 370                debug("%s: max98088 codec set sys clock failed\n", __func__);
 371                return ret;
 372        }
 373
 374        ret = max98088_hw_params(priv, sampling_rate, bits_per_sample);
 375
 376        if (ret == 0) {
 377                ret = max98088_set_fmt(priv, SND_SOC_DAIFMT_I2S |
 378                                       SND_SOC_DAIFMT_NB_NF |
 379                                       SND_SOC_DAIFMT_CBS_CFS);
 380        }
 381
 382        return ret;
 383}
 384
 385static int max98088_set_params(struct udevice *dev, int interface, int rate,
 386                               int mclk_freq, int bits_per_sample,
 387                               uint channels)
 388{
 389        struct maxim_priv *priv = dev_get_priv(dev);
 390
 391        return max98088_do_init(priv, rate, mclk_freq, bits_per_sample);
 392}
 393
 394static int max98088_probe(struct udevice *dev)
 395{
 396        struct maxim_priv *priv = dev_get_priv(dev);
 397        int ret;
 398
 399        priv->dev = dev;
 400        ret = max98088_device_init(priv);
 401        if (ret < 0) {
 402                debug("%s: max98088 codec chip init failed\n", __func__);
 403                return ret;
 404        }
 405
 406        return 0;
 407}
 408
 409static const struct audio_codec_ops max98088_ops = {
 410        .set_params     = max98088_set_params,
 411};
 412
 413static const struct udevice_id max98088_ids[] = {
 414        { .compatible = "maxim,max98088" },
 415        { }
 416};
 417
 418U_BOOT_DRIVER(max98088) = {
 419        .name           = "max98088",
 420        .id             = UCLASS_AUDIO_CODEC,
 421        .of_match       = max98088_ids,
 422        .probe          = max98088_probe,
 423        .ops            = &max98088_ops,
 424        .priv_auto      = sizeof(struct maxim_priv),
 425};
 426