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