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