linux/sound/soc/codecs/ssm2518.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * SSM2518 amplifier audio driver
   4 *
   5 * Copyright 2013 Analog Devices Inc.
   6 *  Author: Lars-Peter Clausen <lars@metafoo.de>
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/init.h>
  11#include <linux/i2c.h>
  12#include <linux/regmap.h>
  13#include <linux/slab.h>
  14#include <linux/gpio.h>
  15#include <linux/of_gpio.h>
  16#include <linux/platform_data/ssm2518.h>
  17#include <sound/core.h>
  18#include <sound/pcm.h>
  19#include <sound/pcm_params.h>
  20#include <sound/soc.h>
  21#include <sound/initval.h>
  22#include <sound/tlv.h>
  23
  24#include "ssm2518.h"
  25
  26#define SSM2518_REG_POWER1              0x00
  27#define SSM2518_REG_CLOCK               0x01
  28#define SSM2518_REG_SAI_CTRL1           0x02
  29#define SSM2518_REG_SAI_CTRL2           0x03
  30#define SSM2518_REG_CHAN_MAP            0x04
  31#define SSM2518_REG_LEFT_VOL            0x05
  32#define SSM2518_REG_RIGHT_VOL           0x06
  33#define SSM2518_REG_MUTE_CTRL           0x07
  34#define SSM2518_REG_FAULT_CTRL          0x08
  35#define SSM2518_REG_POWER2              0x09
  36#define SSM2518_REG_DRC_1               0x0a
  37#define SSM2518_REG_DRC_2               0x0b
  38#define SSM2518_REG_DRC_3               0x0c
  39#define SSM2518_REG_DRC_4               0x0d
  40#define SSM2518_REG_DRC_5               0x0e
  41#define SSM2518_REG_DRC_6               0x0f
  42#define SSM2518_REG_DRC_7               0x10
  43#define SSM2518_REG_DRC_8               0x11
  44#define SSM2518_REG_DRC_9               0x12
  45
  46#define SSM2518_POWER1_RESET                    BIT(7)
  47#define SSM2518_POWER1_NO_BCLK                  BIT(5)
  48#define SSM2518_POWER1_MCS_MASK                 (0xf << 1)
  49#define SSM2518_POWER1_MCS_64FS                 (0x0 << 1)
  50#define SSM2518_POWER1_MCS_128FS                (0x1 << 1)
  51#define SSM2518_POWER1_MCS_256FS                (0x2 << 1)
  52#define SSM2518_POWER1_MCS_384FS                (0x3 << 1)
  53#define SSM2518_POWER1_MCS_512FS                (0x4 << 1)
  54#define SSM2518_POWER1_MCS_768FS                (0x5 << 1)
  55#define SSM2518_POWER1_MCS_100FS                (0x6 << 1)
  56#define SSM2518_POWER1_MCS_200FS                (0x7 << 1)
  57#define SSM2518_POWER1_MCS_400FS                (0x8 << 1)
  58#define SSM2518_POWER1_SPWDN                    BIT(0)
  59
  60#define SSM2518_CLOCK_ASR                       BIT(0)
  61
  62#define SSM2518_SAI_CTRL1_FMT_MASK              (0x3 << 5)
  63#define SSM2518_SAI_CTRL1_FMT_I2S               (0x0 << 5)
  64#define SSM2518_SAI_CTRL1_FMT_LJ                (0x1 << 5)
  65#define SSM2518_SAI_CTRL1_FMT_RJ_24BIT          (0x2 << 5)
  66#define SSM2518_SAI_CTRL1_FMT_RJ_16BIT          (0x3 << 5)
  67
  68#define SSM2518_SAI_CTRL1_SAI_MASK              (0x7 << 2)
  69#define SSM2518_SAI_CTRL1_SAI_I2S               (0x0 << 2)
  70#define SSM2518_SAI_CTRL1_SAI_TDM_2             (0x1 << 2)
  71#define SSM2518_SAI_CTRL1_SAI_TDM_4             (0x2 << 2)
  72#define SSM2518_SAI_CTRL1_SAI_TDM_8             (0x3 << 2)
  73#define SSM2518_SAI_CTRL1_SAI_TDM_16            (0x4 << 2)
  74#define SSM2518_SAI_CTRL1_SAI_MONO              (0x5 << 2)
  75
  76#define SSM2518_SAI_CTRL1_FS_MASK               (0x3)
  77#define SSM2518_SAI_CTRL1_FS_8000_12000         (0x0)
  78#define SSM2518_SAI_CTRL1_FS_16000_24000        (0x1)
  79#define SSM2518_SAI_CTRL1_FS_32000_48000        (0x2)
  80#define SSM2518_SAI_CTRL1_FS_64000_96000        (0x3)
  81
  82#define SSM2518_SAI_CTRL2_BCLK_INTERAL          BIT(7)
  83#define SSM2518_SAI_CTRL2_LRCLK_PULSE           BIT(6)
  84#define SSM2518_SAI_CTRL2_LRCLK_INVERT          BIT(5)
  85#define SSM2518_SAI_CTRL2_MSB                   BIT(4)
  86#define SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK       (0x3 << 2)
  87#define SSM2518_SAI_CTRL2_SLOT_WIDTH_32         (0x0 << 2)
  88#define SSM2518_SAI_CTRL2_SLOT_WIDTH_24         (0x1 << 2)
  89#define SSM2518_SAI_CTRL2_SLOT_WIDTH_16         (0x2 << 2)
  90#define SSM2518_SAI_CTRL2_BCLK_INVERT           BIT(1)
  91
  92#define SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET      4
  93#define SSM2518_CHAN_MAP_RIGHT_SLOT_MASK        0xf0
  94#define SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET       0
  95#define SSM2518_CHAN_MAP_LEFT_SLOT_MASK         0x0f
  96
  97#define SSM2518_MUTE_CTRL_ANA_GAIN              BIT(5)
  98#define SSM2518_MUTE_CTRL_MUTE_MASTER           BIT(0)
  99
 100#define SSM2518_POWER2_APWDN                    BIT(0)
 101
 102#define SSM2518_DAC_MUTE                        BIT(6)
 103#define SSM2518_DAC_FS_MASK                     0x07
 104#define SSM2518_DAC_FS_8000                     0x00
 105#define SSM2518_DAC_FS_16000                    0x01
 106#define SSM2518_DAC_FS_32000                    0x02
 107#define SSM2518_DAC_FS_64000                    0x03
 108#define SSM2518_DAC_FS_128000                   0x04
 109
 110struct ssm2518 {
 111        struct regmap *regmap;
 112        bool right_j;
 113
 114        unsigned int sysclk;
 115        const struct snd_pcm_hw_constraint_list *constraints;
 116
 117        int enable_gpio;
 118};
 119
 120static const struct reg_default ssm2518_reg_defaults[] = {
 121        { 0x00, 0x05 },
 122        { 0x01, 0x00 },
 123        { 0x02, 0x02 },
 124        { 0x03, 0x00 },
 125        { 0x04, 0x10 },
 126        { 0x05, 0x40 },
 127        { 0x06, 0x40 },
 128        { 0x07, 0x81 },
 129        { 0x08, 0x0c },
 130        { 0x09, 0x99 },
 131        { 0x0a, 0x7c },
 132        { 0x0b, 0x5b },
 133        { 0x0c, 0x57 },
 134        { 0x0d, 0x89 },
 135        { 0x0e, 0x8c },
 136        { 0x0f, 0x77 },
 137        { 0x10, 0x26 },
 138        { 0x11, 0x1c },
 139        { 0x12, 0x97 },
 140};
 141
 142static const DECLARE_TLV_DB_MINMAX_MUTE(ssm2518_vol_tlv, -7125, 2400);
 143static const DECLARE_TLV_DB_SCALE(ssm2518_compressor_tlv, -3400, 200, 0);
 144static const DECLARE_TLV_DB_SCALE(ssm2518_expander_tlv, -8100, 300, 0);
 145static const DECLARE_TLV_DB_SCALE(ssm2518_noise_gate_tlv, -9600, 300, 0);
 146static const DECLARE_TLV_DB_SCALE(ssm2518_post_drc_tlv, -2400, 300, 0);
 147
 148static const DECLARE_TLV_DB_RANGE(ssm2518_limiter_tlv,
 149        0, 7, TLV_DB_SCALE_ITEM(-2200, 200, 0),
 150        7, 15, TLV_DB_SCALE_ITEM(-800, 100, 0),
 151);
 152
 153static const char * const ssm2518_drc_peak_detector_attack_time_text[] = {
 154        "0 ms", "0.1 ms", "0.19 ms", "0.37 ms", "0.75 ms", "1.5 ms", "3 ms",
 155        "6 ms", "12 ms", "24 ms", "48 ms", "96 ms", "192 ms", "384 ms",
 156        "768 ms", "1536 ms",
 157};
 158
 159static const char * const ssm2518_drc_peak_detector_release_time_text[] = {
 160        "0 ms", "1.5 ms", "3 ms", "6 ms", "12 ms", "24 ms", "48 ms", "96 ms",
 161        "192 ms", "384 ms", "768 ms", "1536 ms", "3072 ms", "6144 ms",
 162        "12288 ms", "24576 ms"
 163};
 164
 165static const char * const ssm2518_drc_hold_time_text[] = {
 166        "0 ms", "0.67 ms", "1.33 ms", "2.67 ms", "5.33 ms", "10.66 ms",
 167        "21.32 ms", "42.64 ms", "85.28 ms", "170.56 ms", "341.12 ms",
 168        "682.24 ms", "1364 ms",
 169};
 170
 171static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum,
 172        SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text);
 173static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum,
 174        SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text);
 175static SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum,
 176        SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text);
 177static SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum,
 178        SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text);
 179static SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum,
 180        SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text);
 181static SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum,
 182        SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text);
 183static SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum,
 184        SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text);
 185
 186static const struct snd_kcontrol_new ssm2518_snd_controls[] = {
 187        SOC_SINGLE("Playback De-emphasis Switch", SSM2518_REG_MUTE_CTRL,
 188                        4, 1, 0),
 189        SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2518_REG_LEFT_VOL,
 190                        SSM2518_REG_RIGHT_VOL, 0, 0xff, 1, ssm2518_vol_tlv),
 191        SOC_DOUBLE("Master Playback Switch", SSM2518_REG_MUTE_CTRL, 2, 1, 1, 1),
 192
 193        SOC_SINGLE("Amp Low Power Mode Switch", SSM2518_REG_POWER2, 4, 1, 0),
 194        SOC_SINGLE("DAC Low Power Mode Switch", SSM2518_REG_POWER2, 3, 1, 0),
 195
 196        SOC_SINGLE("DRC Limiter Switch", SSM2518_REG_DRC_1, 5, 1, 0),
 197        SOC_SINGLE("DRC Compressor Switch", SSM2518_REG_DRC_1, 4, 1, 0),
 198        SOC_SINGLE("DRC Expander Switch", SSM2518_REG_DRC_1, 3, 1, 0),
 199        SOC_SINGLE("DRC Noise Gate Switch", SSM2518_REG_DRC_1, 2, 1, 0),
 200        SOC_DOUBLE("DRC Switch", SSM2518_REG_DRC_1, 0, 1, 1, 0),
 201
 202        SOC_SINGLE_TLV("DRC Limiter Threshold Volume",
 203                        SSM2518_REG_DRC_3, 4, 15, 1, ssm2518_limiter_tlv),
 204        SOC_SINGLE_TLV("DRC Compressor Lower Threshold Volume",
 205                        SSM2518_REG_DRC_3, 0, 15, 1, ssm2518_compressor_tlv),
 206        SOC_SINGLE_TLV("DRC Expander Upper Threshold Volume", SSM2518_REG_DRC_4,
 207                        4, 15, 1, ssm2518_expander_tlv),
 208        SOC_SINGLE_TLV("DRC Noise Gate Threshold Volume",
 209                        SSM2518_REG_DRC_4, 0, 15, 1, ssm2518_noise_gate_tlv),
 210        SOC_SINGLE_TLV("DRC Upper Output Threshold Volume",
 211                        SSM2518_REG_DRC_5, 4, 15, 1, ssm2518_limiter_tlv),
 212        SOC_SINGLE_TLV("DRC Lower Output Threshold Volume",
 213                        SSM2518_REG_DRC_5, 0, 15, 1, ssm2518_noise_gate_tlv),
 214        SOC_SINGLE_TLV("DRC Post Volume", SSM2518_REG_DRC_8,
 215                        2, 15, 1, ssm2518_post_drc_tlv),
 216
 217        SOC_ENUM("DRC Peak Detector Attack Time",
 218                ssm2518_drc_peak_detector_attack_time_enum),
 219        SOC_ENUM("DRC Peak Detector Release Time",
 220                ssm2518_drc_peak_detector_release_time_enum),
 221        SOC_ENUM("DRC Attack Time", ssm2518_drc_attack_time_enum),
 222        SOC_ENUM("DRC Decay Time", ssm2518_drc_decay_time_enum),
 223        SOC_ENUM("DRC Hold Time", ssm2518_drc_hold_time_enum),
 224        SOC_ENUM("DRC Noise Gate Hold Time",
 225                ssm2518_drc_noise_gate_hold_time_enum),
 226        SOC_ENUM("DRC RMS Averaging Time", ssm2518_drc_rms_averaging_time_enum),
 227};
 228
 229static const struct snd_soc_dapm_widget ssm2518_dapm_widgets[] = {
 230        SND_SOC_DAPM_DAC("DACL", "HiFi Playback", SSM2518_REG_POWER2, 1, 1),
 231        SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SSM2518_REG_POWER2, 2, 1),
 232
 233        SND_SOC_DAPM_OUTPUT("OUTL"),
 234        SND_SOC_DAPM_OUTPUT("OUTR"),
 235};
 236
 237static const struct snd_soc_dapm_route ssm2518_routes[] = {
 238        { "OUTL", NULL, "DACL" },
 239        { "OUTR", NULL, "DACR" },
 240};
 241
 242struct ssm2518_mcs_lut {
 243        unsigned int rate;
 244        const unsigned int *sysclks;
 245};
 246
 247static const unsigned int ssm2518_sysclks_2048000[] = {
 248        2048000, 4096000, 8192000, 12288000, 16384000, 24576000,
 249        3200000, 6400000, 12800000, 0
 250};
 251
 252static const unsigned int ssm2518_sysclks_2822000[] = {
 253        2822000, 5644800, 11289600, 16934400, 22579200, 33868800,
 254        4410000, 8820000, 17640000, 0
 255};
 256
 257static const unsigned int ssm2518_sysclks_3072000[] = {
 258        3072000, 6144000, 12288000, 16384000, 24576000, 38864000,
 259        4800000, 9600000, 19200000, 0
 260};
 261
 262static const struct ssm2518_mcs_lut ssm2518_mcs_lut[] = {
 263        { 8000,  ssm2518_sysclks_2048000, },
 264        { 11025, ssm2518_sysclks_2822000, },
 265        { 12000, ssm2518_sysclks_3072000, },
 266        { 16000, ssm2518_sysclks_2048000, },
 267        { 24000, ssm2518_sysclks_3072000, },
 268        { 22050, ssm2518_sysclks_2822000, },
 269        { 32000, ssm2518_sysclks_2048000, },
 270        { 44100, ssm2518_sysclks_2822000, },
 271        { 48000, ssm2518_sysclks_3072000, },
 272        { 96000, ssm2518_sysclks_3072000, },
 273};
 274
 275static const unsigned int ssm2518_rates_2048000[] = {
 276        8000, 16000, 32000,
 277};
 278
 279static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2048000 = {
 280        .list = ssm2518_rates_2048000,
 281        .count = ARRAY_SIZE(ssm2518_rates_2048000),
 282};
 283
 284static const unsigned int ssm2518_rates_2822000[] = {
 285        11025, 22050, 44100,
 286};
 287
 288static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2822000 = {
 289        .list = ssm2518_rates_2822000,
 290        .count = ARRAY_SIZE(ssm2518_rates_2822000),
 291};
 292
 293static const unsigned int ssm2518_rates_3072000[] = {
 294        12000, 24000, 48000, 96000,
 295};
 296
 297static const struct snd_pcm_hw_constraint_list ssm2518_constraints_3072000 = {
 298        .list = ssm2518_rates_3072000,
 299        .count = ARRAY_SIZE(ssm2518_rates_3072000),
 300};
 301
 302static const unsigned int ssm2518_rates_12288000[] = {
 303        8000, 12000, 16000, 24000, 32000, 48000, 96000,
 304};
 305
 306static const struct snd_pcm_hw_constraint_list ssm2518_constraints_12288000 = {
 307        .list = ssm2518_rates_12288000,
 308        .count = ARRAY_SIZE(ssm2518_rates_12288000),
 309};
 310
 311static int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
 312        unsigned int rate)
 313{
 314        const unsigned int *sysclks = NULL;
 315        int i;
 316
 317        for (i = 0; i < ARRAY_SIZE(ssm2518_mcs_lut); i++) {
 318                if (ssm2518_mcs_lut[i].rate == rate) {
 319                        sysclks = ssm2518_mcs_lut[i].sysclks;
 320                        break;
 321                }
 322        }
 323
 324        if (!sysclks)
 325                return -EINVAL;
 326
 327        for (i = 0; sysclks[i]; i++) {
 328                if (sysclks[i] == ssm2518->sysclk)
 329                        return i;
 330        }
 331
 332        return -EINVAL;
 333}
 334
 335static int ssm2518_hw_params(struct snd_pcm_substream *substream,
 336        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 337{
 338        struct snd_soc_component *component = dai->component;
 339        struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
 340        unsigned int rate = params_rate(params);
 341        unsigned int ctrl1, ctrl1_mask;
 342        int mcs;
 343        int ret;
 344
 345        mcs = ssm2518_lookup_mcs(ssm2518, rate);
 346        if (mcs < 0)
 347                return mcs;
 348
 349        ctrl1_mask = SSM2518_SAI_CTRL1_FS_MASK;
 350
 351        if (rate >= 8000 && rate <= 12000)
 352                ctrl1 = SSM2518_SAI_CTRL1_FS_8000_12000;
 353        else if (rate >= 16000 && rate <= 24000)
 354                ctrl1 = SSM2518_SAI_CTRL1_FS_16000_24000;
 355        else if (rate >= 32000 && rate <= 48000)
 356                ctrl1 = SSM2518_SAI_CTRL1_FS_32000_48000;
 357        else if (rate >= 64000 && rate <= 96000)
 358                ctrl1 = SSM2518_SAI_CTRL1_FS_64000_96000;
 359        else
 360                return -EINVAL;
 361
 362        if (ssm2518->right_j) {
 363                switch (params_width(params)) {
 364                case 16:
 365                        ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_16BIT;
 366                        break;
 367                case 24:
 368                        ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
 369                        break;
 370                default:
 371                        return -EINVAL;
 372                }
 373                ctrl1_mask |= SSM2518_SAI_CTRL1_FMT_MASK;
 374        }
 375
 376        /* Disable auto samplerate detection */
 377        ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_CLOCK,
 378                                SSM2518_CLOCK_ASR, SSM2518_CLOCK_ASR);
 379        if (ret < 0)
 380                return ret;
 381
 382        ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
 383                                ctrl1_mask, ctrl1);
 384        if (ret < 0)
 385                return ret;
 386
 387        return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
 388                                SSM2518_POWER1_MCS_MASK, mcs << 1);
 389}
 390
 391static int ssm2518_mute(struct snd_soc_dai *dai, int mute, int direction)
 392{
 393        struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
 394        unsigned int val;
 395
 396        if (mute)
 397                val = SSM2518_MUTE_CTRL_MUTE_MASTER;
 398        else
 399                val = 0;
 400
 401        return regmap_update_bits(ssm2518->regmap, SSM2518_REG_MUTE_CTRL,
 402                        SSM2518_MUTE_CTRL_MUTE_MASTER, val);
 403}
 404
 405static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 406{
 407        struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
 408        unsigned int ctrl1 = 0, ctrl2 = 0;
 409        bool invert_fclk;
 410        int ret;
 411
 412        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 413        case SND_SOC_DAIFMT_CBS_CFS:
 414                break;
 415        default:
 416                return -EINVAL;
 417        }
 418
 419        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 420        case SND_SOC_DAIFMT_NB_NF:
 421                invert_fclk = false;
 422                break;
 423        case SND_SOC_DAIFMT_IB_NF:
 424                ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
 425                invert_fclk = false;
 426                break;
 427        case SND_SOC_DAIFMT_NB_IF:
 428                invert_fclk = true;
 429                break;
 430        case SND_SOC_DAIFMT_IB_IF:
 431                ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
 432                invert_fclk = true;
 433                break;
 434        default:
 435                return -EINVAL;
 436        }
 437
 438        ssm2518->right_j = false;
 439        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 440        case SND_SOC_DAIFMT_I2S:
 441                ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
 442                break;
 443        case SND_SOC_DAIFMT_LEFT_J:
 444                ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
 445                invert_fclk = !invert_fclk;
 446                break;
 447        case SND_SOC_DAIFMT_RIGHT_J:
 448                ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
 449                ssm2518->right_j = true;
 450                invert_fclk = !invert_fclk;
 451                break;
 452        case SND_SOC_DAIFMT_DSP_A:
 453                ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
 454                ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
 455                invert_fclk = false;
 456                break;
 457        case SND_SOC_DAIFMT_DSP_B:
 458                ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
 459                ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
 460                invert_fclk = false;
 461                break;
 462        default:
 463                return -EINVAL;
 464        }
 465
 466        if (invert_fclk)
 467                ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_INVERT;
 468
 469        ret = regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL1, ctrl1);
 470        if (ret)
 471                return ret;
 472
 473        return regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL2, ctrl2);
 474}
 475
 476static int ssm2518_set_power(struct ssm2518 *ssm2518, bool enable)
 477{
 478        int ret = 0;
 479
 480        if (!enable) {
 481                ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
 482                        SSM2518_POWER1_SPWDN, SSM2518_POWER1_SPWDN);
 483                regcache_mark_dirty(ssm2518->regmap);
 484        }
 485
 486        if (gpio_is_valid(ssm2518->enable_gpio))
 487                gpio_set_value(ssm2518->enable_gpio, enable);
 488
 489        regcache_cache_only(ssm2518->regmap, !enable);
 490
 491        if (enable) {
 492                ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
 493                        SSM2518_POWER1_SPWDN | SSM2518_POWER1_RESET, 0x00);
 494                regcache_sync(ssm2518->regmap);
 495        }
 496
 497        return ret;
 498}
 499
 500static int ssm2518_set_bias_level(struct snd_soc_component *component,
 501        enum snd_soc_bias_level level)
 502{
 503        struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
 504        int ret = 0;
 505
 506        switch (level) {
 507        case SND_SOC_BIAS_ON:
 508                break;
 509        case SND_SOC_BIAS_PREPARE:
 510                break;
 511        case SND_SOC_BIAS_STANDBY:
 512                if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 513                        ret = ssm2518_set_power(ssm2518, true);
 514                break;
 515        case SND_SOC_BIAS_OFF:
 516                ret = ssm2518_set_power(ssm2518, false);
 517                break;
 518        }
 519
 520        return ret;
 521}
 522
 523static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 524        unsigned int rx_mask, int slots, int width)
 525{
 526        struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
 527        unsigned int ctrl1, ctrl2;
 528        int left_slot, right_slot;
 529        int ret;
 530
 531        if (slots == 0)
 532                return regmap_update_bits(ssm2518->regmap,
 533                        SSM2518_REG_SAI_CTRL1, SSM2518_SAI_CTRL1_SAI_MASK,
 534                        SSM2518_SAI_CTRL1_SAI_I2S);
 535
 536        if (tx_mask == 0 || rx_mask != 0)
 537                return -EINVAL;
 538
 539        if (slots == 1) {
 540                if (tx_mask != 1)
 541                        return -EINVAL;
 542                left_slot = 0;
 543                right_slot = 0;
 544        } else {
 545                /* We assume the left channel < right channel */
 546                left_slot = __ffs(tx_mask);
 547                tx_mask &= ~(1 << left_slot);
 548                if (tx_mask == 0) {
 549                        right_slot = left_slot;
 550                } else {
 551                        right_slot = __ffs(tx_mask);
 552                        tx_mask &= ~(1 << right_slot);
 553                }
 554        }
 555
 556        if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
 557                return -EINVAL;
 558
 559        switch (width) {
 560        case 16:
 561                ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_16;
 562                break;
 563        case 24:
 564                ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_24;
 565                break;
 566        case 32:
 567                ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_32;
 568                break;
 569        default:
 570                return -EINVAL;
 571        }
 572
 573        switch (slots) {
 574        case 1:
 575                ctrl1 = SSM2518_SAI_CTRL1_SAI_MONO;
 576                break;
 577        case 2:
 578                ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_2;
 579                break;
 580        case 4:
 581                ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_4;
 582                break;
 583        case 8:
 584                ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_8;
 585                break;
 586        case 16:
 587                ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_16;
 588                break;
 589        default:
 590                return -EINVAL;
 591        }
 592
 593        ret = regmap_write(ssm2518->regmap, SSM2518_REG_CHAN_MAP,
 594                (left_slot << SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET) |
 595                (right_slot << SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET));
 596        if (ret)
 597                return ret;
 598
 599        ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
 600                SSM2518_SAI_CTRL1_SAI_MASK, ctrl1);
 601        if (ret)
 602                return ret;
 603
 604        return regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL2,
 605                SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK, ctrl2);
 606}
 607
 608static int ssm2518_startup(struct snd_pcm_substream *substream,
 609        struct snd_soc_dai *dai)
 610{
 611        struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
 612
 613        if (ssm2518->constraints)
 614                snd_pcm_hw_constraint_list(substream->runtime, 0,
 615                                SNDRV_PCM_HW_PARAM_RATE, ssm2518->constraints);
 616
 617        return 0;
 618}
 619
 620#define SSM2518_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
 621                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32)
 622
 623static const struct snd_soc_dai_ops ssm2518_dai_ops = {
 624        .startup = ssm2518_startup,
 625        .hw_params      = ssm2518_hw_params,
 626        .mute_stream    = ssm2518_mute,
 627        .set_fmt        = ssm2518_set_dai_fmt,
 628        .set_tdm_slot   = ssm2518_set_tdm_slot,
 629        .no_capture_mute = 1,
 630};
 631
 632static struct snd_soc_dai_driver ssm2518_dai = {
 633        .name = "ssm2518-hifi",
 634        .playback = {
 635                .stream_name = "Playback",
 636                .channels_min = 2,
 637                .channels_max = 2,
 638                .rates = SNDRV_PCM_RATE_8000_96000,
 639                .formats = SSM2518_FORMATS,
 640        },
 641        .ops = &ssm2518_dai_ops,
 642};
 643
 644static int ssm2518_set_sysclk(struct snd_soc_component *component, int clk_id,
 645        int source, unsigned int freq, int dir)
 646{
 647        struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
 648        unsigned int val;
 649
 650        if (clk_id != SSM2518_SYSCLK)
 651                return -EINVAL;
 652
 653        switch (source) {
 654        case SSM2518_SYSCLK_SRC_MCLK:
 655                val = 0;
 656                break;
 657        case SSM2518_SYSCLK_SRC_BCLK:
 658                /* In this case the bitclock is used as the system clock, and
 659                 * the bitclock signal needs to be connected to the MCLK pin and
 660                 * the BCLK pin is left unconnected */
 661                val = SSM2518_POWER1_NO_BCLK;
 662                break;
 663        default:
 664                return -EINVAL;
 665        }
 666
 667        switch (freq) {
 668        case 0:
 669                ssm2518->constraints = NULL;
 670                break;
 671        case 2048000:
 672        case 4096000:
 673        case 8192000:
 674        case 3200000:
 675        case 6400000:
 676        case 12800000:
 677                ssm2518->constraints = &ssm2518_constraints_2048000;
 678                break;
 679        case 2822000:
 680        case 5644800:
 681        case 11289600:
 682        case 16934400:
 683        case 22579200:
 684        case 33868800:
 685        case 4410000:
 686        case 8820000:
 687        case 17640000:
 688                ssm2518->constraints = &ssm2518_constraints_2822000;
 689                break;
 690        case 3072000:
 691        case 6144000:
 692        case 38864000:
 693        case 4800000:
 694        case 9600000:
 695        case 19200000:
 696                ssm2518->constraints = &ssm2518_constraints_3072000;
 697                break;
 698        case 12288000:
 699        case 16384000:
 700        case 24576000:
 701                ssm2518->constraints = &ssm2518_constraints_12288000;
 702                break;
 703        default:
 704                return -EINVAL;
 705        }
 706
 707        ssm2518->sysclk = freq;
 708
 709        return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
 710                        SSM2518_POWER1_NO_BCLK, val);
 711}
 712
 713static const struct snd_soc_component_driver ssm2518_component_driver = {
 714        .set_bias_level         = ssm2518_set_bias_level,
 715        .set_sysclk             = ssm2518_set_sysclk,
 716        .controls               = ssm2518_snd_controls,
 717        .num_controls           = ARRAY_SIZE(ssm2518_snd_controls),
 718        .dapm_widgets           = ssm2518_dapm_widgets,
 719        .num_dapm_widgets       = ARRAY_SIZE(ssm2518_dapm_widgets),
 720        .dapm_routes            = ssm2518_routes,
 721        .num_dapm_routes        = ARRAY_SIZE(ssm2518_routes),
 722        .use_pmdown_time        = 1,
 723        .endianness             = 1,
 724        .non_legacy_dai_naming  = 1,
 725};
 726
 727static const struct regmap_config ssm2518_regmap_config = {
 728        .val_bits = 8,
 729        .reg_bits = 8,
 730
 731        .max_register = SSM2518_REG_DRC_9,
 732
 733        .cache_type = REGCACHE_RBTREE,
 734        .reg_defaults = ssm2518_reg_defaults,
 735        .num_reg_defaults = ARRAY_SIZE(ssm2518_reg_defaults),
 736};
 737
 738static int ssm2518_i2c_probe(struct i2c_client *i2c,
 739        const struct i2c_device_id *id)
 740{
 741        struct ssm2518_platform_data *pdata = i2c->dev.platform_data;
 742        struct ssm2518 *ssm2518;
 743        int ret;
 744
 745        ssm2518 = devm_kzalloc(&i2c->dev, sizeof(*ssm2518), GFP_KERNEL);
 746        if (ssm2518 == NULL)
 747                return -ENOMEM;
 748
 749        if (pdata) {
 750                ssm2518->enable_gpio = pdata->enable_gpio;
 751        } else if (i2c->dev.of_node) {
 752                ssm2518->enable_gpio = of_get_gpio(i2c->dev.of_node, 0);
 753                if (ssm2518->enable_gpio < 0 && ssm2518->enable_gpio != -ENOENT)
 754                        return ssm2518->enable_gpio;
 755        } else {
 756                ssm2518->enable_gpio = -1;
 757        }
 758
 759        if (gpio_is_valid(ssm2518->enable_gpio)) {
 760                ret = devm_gpio_request_one(&i2c->dev, ssm2518->enable_gpio,
 761                                GPIOF_OUT_INIT_HIGH, "SSM2518 nSD");
 762                if (ret)
 763                        return ret;
 764        }
 765
 766        i2c_set_clientdata(i2c, ssm2518);
 767
 768        ssm2518->regmap = devm_regmap_init_i2c(i2c, &ssm2518_regmap_config);
 769        if (IS_ERR(ssm2518->regmap))
 770                return PTR_ERR(ssm2518->regmap);
 771
 772        /*
 773         * The reset bit is obviously volatile, but we need to be able to cache
 774         * the other bits in the register, so we can't just mark the whole
 775         * register as volatile. Since this is the only place where we'll ever
 776         * touch the reset bit just bypass the cache for this operation.
 777         */
 778        regcache_cache_bypass(ssm2518->regmap, true);
 779        ret = regmap_write(ssm2518->regmap, SSM2518_REG_POWER1,
 780                        SSM2518_POWER1_RESET);
 781        regcache_cache_bypass(ssm2518->regmap, false);
 782        if (ret)
 783                return ret;
 784
 785        ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER2,
 786                                SSM2518_POWER2_APWDN, 0x00);
 787        if (ret)
 788                return ret;
 789
 790        ret = ssm2518_set_power(ssm2518, false);
 791        if (ret)
 792                return ret;
 793
 794        return devm_snd_soc_register_component(&i2c->dev,
 795                        &ssm2518_component_driver,
 796                        &ssm2518_dai, 1);
 797}
 798
 799#ifdef CONFIG_OF
 800static const struct of_device_id ssm2518_dt_ids[] = {
 801        { .compatible = "adi,ssm2518", },
 802        { }
 803};
 804MODULE_DEVICE_TABLE(of, ssm2518_dt_ids);
 805#endif
 806
 807static const struct i2c_device_id ssm2518_i2c_ids[] = {
 808        { "ssm2518", 0 },
 809        { }
 810};
 811MODULE_DEVICE_TABLE(i2c, ssm2518_i2c_ids);
 812
 813static struct i2c_driver ssm2518_driver = {
 814        .driver = {
 815                .name = "ssm2518",
 816                .of_match_table = of_match_ptr(ssm2518_dt_ids),
 817        },
 818        .probe = ssm2518_i2c_probe,
 819        .id_table = ssm2518_i2c_ids,
 820};
 821module_i2c_driver(ssm2518_driver);
 822
 823MODULE_DESCRIPTION("ASoC SSM2518 driver");
 824MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 825MODULE_LICENSE("GPL");
 826