linux/sound/soc/codecs/tas2552.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * tas2552.c - ALSA SoC Texas Instruments TAS2552 Mono Audio Amplifier
   4 *
   5 * Copyright (C) 2014 Texas Instruments Incorporated -  http://www.ti.com
   6 *
   7 * Author: Dan Murphy <dmurphy@ti.com>
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/errno.h>
  12#include <linux/device.h>
  13#include <linux/i2c.h>
  14#include <linux/gpio.h>
  15#include <linux/of_gpio.h>
  16#include <linux/pm_runtime.h>
  17#include <linux/regmap.h>
  18#include <linux/slab.h>
  19
  20#include <linux/gpio/consumer.h>
  21#include <linux/regulator/consumer.h>
  22
  23#include <sound/pcm.h>
  24#include <sound/pcm_params.h>
  25#include <sound/soc.h>
  26#include <sound/soc-dapm.h>
  27#include <sound/tlv.h>
  28#include <sound/tas2552-plat.h>
  29#include <dt-bindings/sound/tas2552.h>
  30
  31#include "tas2552.h"
  32
  33static const struct reg_default tas2552_reg_defs[] = {
  34        {TAS2552_CFG_1, 0x22},
  35        {TAS2552_CFG_3, 0x80},
  36        {TAS2552_DOUT, 0x00},
  37        {TAS2552_OUTPUT_DATA, 0xc0},
  38        {TAS2552_PDM_CFG, 0x01},
  39        {TAS2552_PGA_GAIN, 0x00},
  40        {TAS2552_BOOST_APT_CTRL, 0x0f},
  41        {TAS2552_RESERVED_0D, 0xbe},
  42        {TAS2552_LIMIT_RATE_HYS, 0x08},
  43        {TAS2552_CFG_2, 0xef},
  44        {TAS2552_SER_CTRL_1, 0x00},
  45        {TAS2552_SER_CTRL_2, 0x00},
  46        {TAS2552_PLL_CTRL_1, 0x10},
  47        {TAS2552_PLL_CTRL_2, 0x00},
  48        {TAS2552_PLL_CTRL_3, 0x00},
  49        {TAS2552_BTIP, 0x8f},
  50        {TAS2552_BTS_CTRL, 0x80},
  51        {TAS2552_LIMIT_RELEASE, 0x04},
  52        {TAS2552_LIMIT_INT_COUNT, 0x00},
  53        {TAS2552_EDGE_RATE_CTRL, 0x40},
  54        {TAS2552_VBAT_DATA, 0x00},
  55};
  56
  57#define TAS2552_NUM_SUPPLIES    3
  58static const char *tas2552_supply_names[TAS2552_NUM_SUPPLIES] = {
  59        "vbat",         /* vbat voltage */
  60        "iovdd",        /* I/O Voltage */
  61        "avdd",         /* Analog DAC Voltage */
  62};
  63
  64struct tas2552_data {
  65        struct snd_soc_component *component;
  66        struct regmap *regmap;
  67        struct i2c_client *tas2552_client;
  68        struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES];
  69        struct gpio_desc *enable_gpio;
  70        unsigned char regs[TAS2552_VBAT_DATA];
  71        unsigned int pll_clkin;
  72        int pll_clk_id;
  73        unsigned int pdm_clk;
  74        int pdm_clk_id;
  75
  76        unsigned int dai_fmt;
  77        unsigned int tdm_delay;
  78};
  79
  80static int tas2552_post_event(struct snd_soc_dapm_widget *w,
  81                              struct snd_kcontrol *kcontrol, int event)
  82{
  83        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  84
  85        switch (event) {
  86        case SND_SOC_DAPM_POST_PMU:
  87                snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xc0);
  88                snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5),
  89                                    (1 << 5));
  90                snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 0);
  91                snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS, 0);
  92                break;
  93        case SND_SOC_DAPM_POST_PMD:
  94                snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS,
  95                                    TAS2552_SWS);
  96                snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 1);
  97                snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0);
  98                snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xbe);
  99                break;
 100        }
 101        return 0;
 102}
 103
 104/* Input mux controls */
 105static const char * const tas2552_input_texts[] = {
 106        "Digital", "Analog" };
 107static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7,
 108                            tas2552_input_texts);
 109
 110static const struct snd_kcontrol_new tas2552_input_mux_control =
 111        SOC_DAPM_ENUM("Route", tas2552_input_mux_enum);
 112
 113static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] =
 114{
 115        SND_SOC_DAPM_INPUT("IN"),
 116
 117        /* MUX Controls */
 118        SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0,
 119                         &tas2552_input_mux_control),
 120
 121        SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
 122        SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
 123        SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0),
 124        SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0),
 125        SND_SOC_DAPM_POST("Post Event", tas2552_post_event),
 126
 127        SND_SOC_DAPM_OUTPUT("OUT")
 128};
 129
 130static const struct snd_soc_dapm_route tas2552_audio_map[] = {
 131        {"DAC", NULL, "DAC IN"},
 132        {"Input selection", "Digital", "DAC"},
 133        {"Input selection", "Analog", "IN"},
 134        {"ClassD", NULL, "Input selection"},
 135        {"OUT", NULL, "ClassD"},
 136        {"ClassD", NULL, "PLL"},
 137};
 138
 139#ifdef CONFIG_PM
 140static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown)
 141{
 142        u8 cfg1_reg = 0;
 143
 144        if (!tas2552->component)
 145                return;
 146
 147        if (sw_shutdown)
 148                cfg1_reg = TAS2552_SWS;
 149
 150        snd_soc_component_update_bits(tas2552->component, TAS2552_CFG_1, TAS2552_SWS,
 151                            cfg1_reg);
 152}
 153#endif
 154
 155static int tas2552_setup_pll(struct snd_soc_component *component,
 156                             struct snd_pcm_hw_params *params)
 157{
 158        struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 159        bool bypass_pll = false;
 160        unsigned int pll_clk = params_rate(params) * 512;
 161        unsigned int pll_clkin = tas2552->pll_clkin;
 162        u8 pll_enable;
 163
 164        if (!pll_clkin) {
 165                if (tas2552->pll_clk_id != TAS2552_PLL_CLKIN_BCLK)
 166                        return -EINVAL;
 167
 168                pll_clkin = snd_soc_params_to_bclk(params);
 169                pll_clkin += tas2552->tdm_delay;
 170        }
 171
 172        pll_enable = snd_soc_component_read32(component, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
 173        snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
 174
 175        if (pll_clkin == pll_clk)
 176                bypass_pll = true;
 177
 178        if (bypass_pll) {
 179                /* By pass the PLL configuration */
 180                snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_2,
 181                                    TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS);
 182        } else {
 183                /* Fill in the PLL control registers for J & D
 184                 * pll_clk = (.5 * pll_clkin * J.D) / 2^p
 185                 * Need to fill in J and D here based on incoming freq
 186                 */
 187                unsigned int d, q, t;
 188                u8 j;
 189                u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK;
 190                u8 p = snd_soc_component_read32(component, TAS2552_PLL_CTRL_1);
 191
 192                p = (p >> 7);
 193
 194recalc:
 195                t = (pll_clk * 2) << p;
 196                j = t / pll_clkin;
 197                d = t % pll_clkin;
 198                t = pll_clkin / 10000;
 199                q = d / (t + 1);
 200                d = q + ((9999 - pll_clkin % 10000) * (d / t - q)) / 10000;
 201
 202                if (d && (pll_clkin < 512000 || pll_clkin > 9200000)) {
 203                        if (tas2552->pll_clk_id == TAS2552_PLL_CLKIN_BCLK) {
 204                                pll_clkin = 1800000;
 205                                pll_sel = (TAS2552_PLL_CLKIN_1_8_FIXED << 3) &
 206                                                        TAS2552_PLL_SRC_MASK;
 207                        } else {
 208                                pll_clkin = snd_soc_params_to_bclk(params);
 209                                pll_clkin += tas2552->tdm_delay;
 210                                pll_sel = (TAS2552_PLL_CLKIN_BCLK << 3) &
 211                                                        TAS2552_PLL_SRC_MASK;
 212                        }
 213                        goto recalc;
 214                }
 215
 216                snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
 217                                    pll_sel);
 218
 219                snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_1,
 220                                    TAS2552_PLL_J_MASK, j);
 221                /* Will clear the PLL_BYPASS bit */
 222                snd_soc_component_write(component, TAS2552_PLL_CTRL_2,
 223                              TAS2552_PLL_D_UPPER(d));
 224                snd_soc_component_write(component, TAS2552_PLL_CTRL_3,
 225                              TAS2552_PLL_D_LOWER(d));
 226        }
 227
 228        /* Restore PLL status */
 229        snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
 230                            pll_enable);
 231
 232        return 0;
 233}
 234
 235static int tas2552_hw_params(struct snd_pcm_substream *substream,
 236                             struct snd_pcm_hw_params *params,
 237                             struct snd_soc_dai *dai)
 238{
 239        struct snd_soc_component *component = dai->component;
 240        struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 241        int cpf;
 242        u8 ser_ctrl1_reg, wclk_rate;
 243
 244        switch (params_width(params)) {
 245        case 16:
 246                ser_ctrl1_reg = TAS2552_WORDLENGTH_16BIT;
 247                cpf = 32 + tas2552->tdm_delay;
 248                break;
 249        case 20:
 250                ser_ctrl1_reg = TAS2552_WORDLENGTH_20BIT;
 251                cpf = 64 + tas2552->tdm_delay;
 252                break;
 253        case 24:
 254                ser_ctrl1_reg = TAS2552_WORDLENGTH_24BIT;
 255                cpf = 64 + tas2552->tdm_delay;
 256                break;
 257        case 32:
 258                ser_ctrl1_reg = TAS2552_WORDLENGTH_32BIT;
 259                cpf = 64 + tas2552->tdm_delay;
 260                break;
 261        default:
 262                dev_err(component->dev, "Not supported sample size: %d\n",
 263                        params_width(params));
 264                return -EINVAL;
 265        }
 266
 267        if (cpf <= 32)
 268                ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_32;
 269        else if (cpf <= 64)
 270                ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_64;
 271        else if (cpf <= 128)
 272                ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_128;
 273        else
 274                ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_256;
 275
 276        snd_soc_component_update_bits(component, TAS2552_SER_CTRL_1,
 277                            TAS2552_WORDLENGTH_MASK | TAS2552_CLKSPERFRAME_MASK,
 278                            ser_ctrl1_reg);
 279
 280        switch (params_rate(params)) {
 281        case 8000:
 282                wclk_rate = TAS2552_WCLK_FREQ_8KHZ;
 283                break;
 284        case 11025:
 285        case 12000:
 286                wclk_rate = TAS2552_WCLK_FREQ_11_12KHZ;
 287                break;
 288        case 16000:
 289                wclk_rate = TAS2552_WCLK_FREQ_16KHZ;
 290                break;
 291        case 22050:
 292        case 24000:
 293                wclk_rate = TAS2552_WCLK_FREQ_22_24KHZ;
 294                break;
 295        case 32000:
 296                wclk_rate = TAS2552_WCLK_FREQ_32KHZ;
 297                break;
 298        case 44100:
 299        case 48000:
 300                wclk_rate = TAS2552_WCLK_FREQ_44_48KHZ;
 301                break;
 302        case 88200:
 303        case 96000:
 304                wclk_rate = TAS2552_WCLK_FREQ_88_96KHZ;
 305                break;
 306        case 176400:
 307        case 192000:
 308                wclk_rate = TAS2552_WCLK_FREQ_176_192KHZ;
 309                break;
 310        default:
 311                dev_err(component->dev, "Not supported sample rate: %d\n",
 312                        params_rate(params));
 313                return -EINVAL;
 314        }
 315
 316        snd_soc_component_update_bits(component, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
 317                            wclk_rate);
 318
 319        return tas2552_setup_pll(component, params);
 320}
 321
 322#define TAS2552_DAI_FMT_MASK    (TAS2552_BCLKDIR | \
 323                                 TAS2552_WCLKDIR | \
 324                                 TAS2552_DATAFORMAT_MASK)
 325static int tas2552_prepare(struct snd_pcm_substream *substream,
 326                           struct snd_soc_dai *dai)
 327{
 328        struct snd_soc_component *component = dai->component;
 329        struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 330        int delay = 0;
 331
 332        /* TDM slot selection only valid in DSP_A/_B mode */
 333        if (tas2552->dai_fmt == SND_SOC_DAIFMT_DSP_A)
 334                delay += (tas2552->tdm_delay + 1);
 335        else if (tas2552->dai_fmt == SND_SOC_DAIFMT_DSP_B)
 336                delay += tas2552->tdm_delay;
 337
 338        /* Configure data delay */
 339        snd_soc_component_write(component, TAS2552_SER_CTRL_2, delay);
 340
 341        return 0;
 342}
 343
 344static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 345{
 346        struct snd_soc_component *component = dai->component;
 347        struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 348        u8 serial_format;
 349
 350        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 351        case SND_SOC_DAIFMT_CBS_CFS:
 352                serial_format = 0x00;
 353                break;
 354        case SND_SOC_DAIFMT_CBS_CFM:
 355                serial_format = TAS2552_WCLKDIR;
 356                break;
 357        case SND_SOC_DAIFMT_CBM_CFS:
 358                serial_format = TAS2552_BCLKDIR;
 359                break;
 360        case SND_SOC_DAIFMT_CBM_CFM:
 361                serial_format = (TAS2552_BCLKDIR | TAS2552_WCLKDIR);
 362                break;
 363        default:
 364                dev_vdbg(component->dev, "DAI Format master is not found\n");
 365                return -EINVAL;
 366        }
 367
 368        switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
 369                       SND_SOC_DAIFMT_INV_MASK)) {
 370        case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
 371                break;
 372        case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
 373        case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
 374                serial_format |= TAS2552_DATAFORMAT_DSP;
 375                break;
 376        case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
 377                serial_format |= TAS2552_DATAFORMAT_RIGHT_J;
 378                break;
 379        case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
 380                serial_format |= TAS2552_DATAFORMAT_LEFT_J;
 381                break;
 382        default:
 383                dev_vdbg(component->dev, "DAI Format is not found\n");
 384                return -EINVAL;
 385        }
 386        tas2552->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 387
 388        snd_soc_component_update_bits(component, TAS2552_SER_CTRL_1, TAS2552_DAI_FMT_MASK,
 389                            serial_format);
 390        return 0;
 391}
 392
 393static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 394                                  unsigned int freq, int dir)
 395{
 396        struct snd_soc_component *component = dai->component;
 397        struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
 398        u8 reg, mask, val;
 399
 400        switch (clk_id) {
 401        case TAS2552_PLL_CLKIN_MCLK:
 402        case TAS2552_PLL_CLKIN_IVCLKIN:
 403                if (freq < 512000 || freq > 24576000) {
 404                        /* out of range PLL_CLKIN, fall back to use BCLK */
 405                        dev_warn(component->dev, "Out of range PLL_CLKIN: %u\n",
 406                                 freq);
 407                        clk_id = TAS2552_PLL_CLKIN_BCLK;
 408                        freq = 0;
 409                }
 410                /* fall through */
 411        case TAS2552_PLL_CLKIN_BCLK:
 412        case TAS2552_PLL_CLKIN_1_8_FIXED:
 413                mask = TAS2552_PLL_SRC_MASK;
 414                val = (clk_id << 3) & mask; /* bit 4:5 in the register */
 415                reg = TAS2552_CFG_1;
 416                tas2552->pll_clk_id = clk_id;
 417                tas2552->pll_clkin = freq;
 418                break;
 419        case TAS2552_PDM_CLK_PLL:
 420        case TAS2552_PDM_CLK_IVCLKIN:
 421        case TAS2552_PDM_CLK_BCLK:
 422        case TAS2552_PDM_CLK_MCLK:
 423                mask = TAS2552_PDM_CLK_SEL_MASK;
 424                val = (clk_id >> 1) & mask; /* bit 0:1 in the register */
 425                reg = TAS2552_PDM_CFG;
 426                tas2552->pdm_clk_id = clk_id;
 427                tas2552->pdm_clk = freq;
 428                break;
 429        default:
 430                dev_err(component->dev, "Invalid clk id: %d\n", clk_id);
 431                return -EINVAL;
 432        }
 433
 434        snd_soc_component_update_bits(component, reg, mask, val);
 435
 436        return 0;
 437}
 438
 439static int tas2552_set_dai_tdm_slot(struct snd_soc_dai *dai,
 440                                    unsigned int tx_mask, unsigned int rx_mask,
 441                                    int slots, int slot_width)
 442{
 443        struct snd_soc_component *component = dai->component;
 444        struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 445        unsigned int lsb;
 446
 447        if (unlikely(!tx_mask)) {
 448                dev_err(component->dev, "tx masks need to be non 0\n");
 449                return -EINVAL;
 450        }
 451
 452        /* TDM based on DSP mode requires slots to be adjacent */
 453        lsb = __ffs(tx_mask);
 454        if ((lsb + 1) != __fls(tx_mask)) {
 455                dev_err(component->dev, "Invalid mask, slots must be adjacent\n");
 456                return -EINVAL;
 457        }
 458
 459        tas2552->tdm_delay = lsb * slot_width;
 460
 461        /* DOUT in high-impedance on inactive bit clocks */
 462        snd_soc_component_update_bits(component, TAS2552_DOUT,
 463                            TAS2552_SDOUT_TRISTATE, TAS2552_SDOUT_TRISTATE);
 464
 465        return 0;
 466}
 467
 468static int tas2552_mute(struct snd_soc_dai *dai, int mute)
 469{
 470        u8 cfg1_reg = 0;
 471        struct snd_soc_component *component = dai->component;
 472
 473        if (mute)
 474                cfg1_reg |= TAS2552_MUTE;
 475
 476        snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_MUTE, cfg1_reg);
 477
 478        return 0;
 479}
 480
 481#ifdef CONFIG_PM
 482static int tas2552_runtime_suspend(struct device *dev)
 483{
 484        struct tas2552_data *tas2552 = dev_get_drvdata(dev);
 485
 486        tas2552_sw_shutdown(tas2552, 1);
 487
 488        regcache_cache_only(tas2552->regmap, true);
 489        regcache_mark_dirty(tas2552->regmap);
 490
 491        gpiod_set_value(tas2552->enable_gpio, 0);
 492
 493        return 0;
 494}
 495
 496static int tas2552_runtime_resume(struct device *dev)
 497{
 498        struct tas2552_data *tas2552 = dev_get_drvdata(dev);
 499
 500        gpiod_set_value(tas2552->enable_gpio, 1);
 501
 502        tas2552_sw_shutdown(tas2552, 0);
 503
 504        regcache_cache_only(tas2552->regmap, false);
 505        regcache_sync(tas2552->regmap);
 506
 507        return 0;
 508}
 509#endif
 510
 511static const struct dev_pm_ops tas2552_pm = {
 512        SET_RUNTIME_PM_OPS(tas2552_runtime_suspend, tas2552_runtime_resume,
 513                           NULL)
 514};
 515
 516static const struct snd_soc_dai_ops tas2552_speaker_dai_ops = {
 517        .hw_params      = tas2552_hw_params,
 518        .prepare        = tas2552_prepare,
 519        .set_sysclk     = tas2552_set_dai_sysclk,
 520        .set_fmt        = tas2552_set_dai_fmt,
 521        .set_tdm_slot   = tas2552_set_dai_tdm_slot,
 522        .digital_mute = tas2552_mute,
 523};
 524
 525/* Formats supported by TAS2552 driver. */
 526#define TAS2552_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
 527                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 528
 529/* TAS2552 dai structure. */
 530static struct snd_soc_dai_driver tas2552_dai[] = {
 531        {
 532                .name = "tas2552-amplifier",
 533                .playback = {
 534                        .stream_name = "Playback",
 535                        .channels_min = 2,
 536                        .channels_max = 2,
 537                        .rates = SNDRV_PCM_RATE_8000_192000,
 538                        .formats = TAS2552_FORMATS,
 539                },
 540                .ops = &tas2552_speaker_dai_ops,
 541        },
 542};
 543
 544/*
 545 * DAC digital volumes. From -7 to 24 dB in 1 dB steps
 546 */
 547static DECLARE_TLV_DB_SCALE(dac_tlv, -700, 100, 0);
 548
 549static const char * const tas2552_din_source_select[] = {
 550        "Muted",
 551        "Left",
 552        "Right",
 553        "Left + Right average",
 554};
 555static SOC_ENUM_SINGLE_DECL(tas2552_din_source_enum,
 556                            TAS2552_CFG_3, 3,
 557                            tas2552_din_source_select);
 558
 559static const struct snd_kcontrol_new tas2552_snd_controls[] = {
 560        SOC_SINGLE_TLV("Speaker Driver Playback Volume",
 561                         TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv),
 562        SOC_ENUM("DIN source", tas2552_din_source_enum),
 563};
 564
 565static int tas2552_component_probe(struct snd_soc_component *component)
 566{
 567        struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 568        int ret;
 569
 570        tas2552->component = component;
 571
 572        ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
 573                                    tas2552->supplies);
 574
 575        if (ret != 0) {
 576                dev_err(component->dev, "Failed to enable supplies: %d\n",
 577                        ret);
 578                return ret;
 579        }
 580
 581        gpiod_set_value(tas2552->enable_gpio, 1);
 582
 583        ret = pm_runtime_get_sync(component->dev);
 584        if (ret < 0) {
 585                dev_err(component->dev, "Enabling device failed: %d\n",
 586                        ret);
 587                goto probe_fail;
 588        }
 589
 590        snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE);
 591        snd_soc_component_write(component, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
 592                                            TAS2552_DIN_SRC_SEL_AVG_L_R);
 593        snd_soc_component_write(component, TAS2552_OUTPUT_DATA,
 594                      TAS2552_PDM_DATA_SEL_V_I |
 595                      TAS2552_R_DATA_OUT(TAS2552_DATA_OUT_V_DATA));
 596        snd_soc_component_write(component, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 |
 597                                                     TAS2552_APT_THRESH_20_17);
 598
 599        snd_soc_component_write(component, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN |
 600                                            TAS2552_LIM_EN);
 601
 602        return 0;
 603
 604probe_fail:
 605        gpiod_set_value(tas2552->enable_gpio, 0);
 606
 607        regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
 608                                        tas2552->supplies);
 609        return ret;
 610}
 611
 612static void tas2552_component_remove(struct snd_soc_component *component)
 613{
 614        struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 615
 616        pm_runtime_put(component->dev);
 617
 618        gpiod_set_value(tas2552->enable_gpio, 0);
 619};
 620
 621#ifdef CONFIG_PM
 622static int tas2552_suspend(struct snd_soc_component *component)
 623{
 624        struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 625        int ret;
 626
 627        ret = regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
 628                                        tas2552->supplies);
 629
 630        if (ret != 0)
 631                dev_err(component->dev, "Failed to disable supplies: %d\n",
 632                        ret);
 633        return ret;
 634}
 635
 636static int tas2552_resume(struct snd_soc_component *component)
 637{
 638        struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 639        int ret;
 640
 641        ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
 642                                    tas2552->supplies);
 643
 644        if (ret != 0) {
 645                dev_err(component->dev, "Failed to enable supplies: %d\n",
 646                        ret);
 647        }
 648
 649        return ret;
 650}
 651#else
 652#define tas2552_suspend NULL
 653#define tas2552_resume NULL
 654#endif
 655
 656static const struct snd_soc_component_driver soc_component_dev_tas2552 = {
 657        .probe                  = tas2552_component_probe,
 658        .remove                 = tas2552_component_remove,
 659        .suspend                = tas2552_suspend,
 660        .resume                 = tas2552_resume,
 661        .controls               = tas2552_snd_controls,
 662        .num_controls           = ARRAY_SIZE(tas2552_snd_controls),
 663        .dapm_widgets           = tas2552_dapm_widgets,
 664        .num_dapm_widgets       = ARRAY_SIZE(tas2552_dapm_widgets),
 665        .dapm_routes            = tas2552_audio_map,
 666        .num_dapm_routes        = ARRAY_SIZE(tas2552_audio_map),
 667        .idle_bias_on           = 1,
 668        .endianness             = 1,
 669        .non_legacy_dai_naming  = 1,
 670};
 671
 672static const struct regmap_config tas2552_regmap_config = {
 673        .reg_bits = 8,
 674        .val_bits = 8,
 675
 676        .max_register = TAS2552_MAX_REG,
 677        .reg_defaults = tas2552_reg_defs,
 678        .num_reg_defaults = ARRAY_SIZE(tas2552_reg_defs),
 679        .cache_type = REGCACHE_RBTREE,
 680};
 681
 682static int tas2552_probe(struct i2c_client *client,
 683                           const struct i2c_device_id *id)
 684{
 685        struct device *dev;
 686        struct tas2552_data *data;
 687        int ret;
 688        int i;
 689
 690        dev = &client->dev;
 691        data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
 692        if (data == NULL)
 693                return -ENOMEM;
 694
 695        data->enable_gpio = devm_gpiod_get_optional(dev, "enable",
 696                                                    GPIOD_OUT_LOW);
 697        if (IS_ERR(data->enable_gpio))
 698                return PTR_ERR(data->enable_gpio);
 699
 700        data->tas2552_client = client;
 701        data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config);
 702        if (IS_ERR(data->regmap)) {
 703                ret = PTR_ERR(data->regmap);
 704                dev_err(&client->dev, "Failed to allocate register map: %d\n",
 705                        ret);
 706                return ret;
 707        }
 708
 709        for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
 710                data->supplies[i].supply = tas2552_supply_names[i];
 711
 712        ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
 713                                      data->supplies);
 714        if (ret != 0) {
 715                dev_err(dev, "Failed to request supplies: %d\n", ret);
 716                return ret;
 717        }
 718
 719        pm_runtime_set_active(&client->dev);
 720        pm_runtime_set_autosuspend_delay(&client->dev, 1000);
 721        pm_runtime_use_autosuspend(&client->dev);
 722        pm_runtime_enable(&client->dev);
 723        pm_runtime_mark_last_busy(&client->dev);
 724        pm_runtime_put_sync_autosuspend(&client->dev);
 725
 726        dev_set_drvdata(&client->dev, data);
 727
 728        ret = devm_snd_soc_register_component(&client->dev,
 729                                      &soc_component_dev_tas2552,
 730                                      tas2552_dai, ARRAY_SIZE(tas2552_dai));
 731        if (ret < 0)
 732                dev_err(&client->dev, "Failed to register component: %d\n", ret);
 733
 734        return ret;
 735}
 736
 737static int tas2552_i2c_remove(struct i2c_client *client)
 738{
 739        pm_runtime_disable(&client->dev);
 740        return 0;
 741}
 742
 743static const struct i2c_device_id tas2552_id[] = {
 744        { "tas2552", 0 },
 745        { }
 746};
 747MODULE_DEVICE_TABLE(i2c, tas2552_id);
 748
 749#if IS_ENABLED(CONFIG_OF)
 750static const struct of_device_id tas2552_of_match[] = {
 751        { .compatible = "ti,tas2552", },
 752        {},
 753};
 754MODULE_DEVICE_TABLE(of, tas2552_of_match);
 755#endif
 756
 757static struct i2c_driver tas2552_i2c_driver = {
 758        .driver = {
 759                .name = "tas2552",
 760                .of_match_table = of_match_ptr(tas2552_of_match),
 761                .pm = &tas2552_pm,
 762        },
 763        .probe = tas2552_probe,
 764        .remove = tas2552_i2c_remove,
 765        .id_table = tas2552_id,
 766};
 767
 768module_i2c_driver(tas2552_i2c_driver);
 769
 770MODULE_AUTHOR("Dan Muprhy <dmurphy@ti.com>");
 771MODULE_DESCRIPTION("TAS2552 Audio amplifier driver");
 772MODULE_LICENSE("GPL");
 773