Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * SSM2518 amplifier audio driver
0004  *
0005  * Copyright 2013 Analog Devices Inc.
0006  *  Author: Lars-Peter Clausen <lars@metafoo.de>
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/i2c.h>
0012 #include <linux/regmap.h>
0013 #include <linux/slab.h>
0014 #include <linux/gpio.h>
0015 #include <linux/of_gpio.h>
0016 #include <linux/platform_data/ssm2518.h>
0017 #include <sound/core.h>
0018 #include <sound/pcm.h>
0019 #include <sound/pcm_params.h>
0020 #include <sound/soc.h>
0021 #include <sound/initval.h>
0022 #include <sound/tlv.h>
0023 
0024 #include "ssm2518.h"
0025 
0026 #define SSM2518_REG_POWER1      0x00
0027 #define SSM2518_REG_CLOCK       0x01
0028 #define SSM2518_REG_SAI_CTRL1       0x02
0029 #define SSM2518_REG_SAI_CTRL2       0x03
0030 #define SSM2518_REG_CHAN_MAP        0x04
0031 #define SSM2518_REG_LEFT_VOL        0x05
0032 #define SSM2518_REG_RIGHT_VOL       0x06
0033 #define SSM2518_REG_MUTE_CTRL       0x07
0034 #define SSM2518_REG_FAULT_CTRL      0x08
0035 #define SSM2518_REG_POWER2      0x09
0036 #define SSM2518_REG_DRC_1       0x0a
0037 #define SSM2518_REG_DRC_2       0x0b
0038 #define SSM2518_REG_DRC_3       0x0c
0039 #define SSM2518_REG_DRC_4       0x0d
0040 #define SSM2518_REG_DRC_5       0x0e
0041 #define SSM2518_REG_DRC_6       0x0f
0042 #define SSM2518_REG_DRC_7       0x10
0043 #define SSM2518_REG_DRC_8       0x11
0044 #define SSM2518_REG_DRC_9       0x12
0045 
0046 #define SSM2518_POWER1_RESET            BIT(7)
0047 #define SSM2518_POWER1_NO_BCLK          BIT(5)
0048 #define SSM2518_POWER1_MCS_MASK         (0xf << 1)
0049 #define SSM2518_POWER1_MCS_64FS         (0x0 << 1)
0050 #define SSM2518_POWER1_MCS_128FS        (0x1 << 1)
0051 #define SSM2518_POWER1_MCS_256FS        (0x2 << 1)
0052 #define SSM2518_POWER1_MCS_384FS        (0x3 << 1)
0053 #define SSM2518_POWER1_MCS_512FS        (0x4 << 1)
0054 #define SSM2518_POWER1_MCS_768FS        (0x5 << 1)
0055 #define SSM2518_POWER1_MCS_100FS        (0x6 << 1)
0056 #define SSM2518_POWER1_MCS_200FS        (0x7 << 1)
0057 #define SSM2518_POWER1_MCS_400FS        (0x8 << 1)
0058 #define SSM2518_POWER1_SPWDN            BIT(0)
0059 
0060 #define SSM2518_CLOCK_ASR           BIT(0)
0061 
0062 #define SSM2518_SAI_CTRL1_FMT_MASK      (0x3 << 5)
0063 #define SSM2518_SAI_CTRL1_FMT_I2S       (0x0 << 5)
0064 #define SSM2518_SAI_CTRL1_FMT_LJ        (0x1 << 5)
0065 #define SSM2518_SAI_CTRL1_FMT_RJ_24BIT      (0x2 << 5)
0066 #define SSM2518_SAI_CTRL1_FMT_RJ_16BIT      (0x3 << 5)
0067 
0068 #define SSM2518_SAI_CTRL1_SAI_MASK      (0x7 << 2)
0069 #define SSM2518_SAI_CTRL1_SAI_I2S       (0x0 << 2)
0070 #define SSM2518_SAI_CTRL1_SAI_TDM_2     (0x1 << 2)
0071 #define SSM2518_SAI_CTRL1_SAI_TDM_4     (0x2 << 2)
0072 #define SSM2518_SAI_CTRL1_SAI_TDM_8     (0x3 << 2)
0073 #define SSM2518_SAI_CTRL1_SAI_TDM_16        (0x4 << 2)
0074 #define SSM2518_SAI_CTRL1_SAI_MONO      (0x5 << 2)
0075 
0076 #define SSM2518_SAI_CTRL1_FS_MASK       (0x3)
0077 #define SSM2518_SAI_CTRL1_FS_8000_12000     (0x0)
0078 #define SSM2518_SAI_CTRL1_FS_16000_24000    (0x1)
0079 #define SSM2518_SAI_CTRL1_FS_32000_48000    (0x2)
0080 #define SSM2518_SAI_CTRL1_FS_64000_96000    (0x3)
0081 
0082 #define SSM2518_SAI_CTRL2_BCLK_INTERAL      BIT(7)
0083 #define SSM2518_SAI_CTRL2_LRCLK_PULSE       BIT(6)
0084 #define SSM2518_SAI_CTRL2_LRCLK_INVERT      BIT(5)
0085 #define SSM2518_SAI_CTRL2_MSB           BIT(4)
0086 #define SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK   (0x3 << 2)
0087 #define SSM2518_SAI_CTRL2_SLOT_WIDTH_32     (0x0 << 2)
0088 #define SSM2518_SAI_CTRL2_SLOT_WIDTH_24     (0x1 << 2)
0089 #define SSM2518_SAI_CTRL2_SLOT_WIDTH_16     (0x2 << 2)
0090 #define SSM2518_SAI_CTRL2_BCLK_INVERT       BIT(1)
0091 
0092 #define SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET  4
0093 #define SSM2518_CHAN_MAP_RIGHT_SLOT_MASK    0xf0
0094 #define SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET   0
0095 #define SSM2518_CHAN_MAP_LEFT_SLOT_MASK     0x0f
0096 
0097 #define SSM2518_MUTE_CTRL_ANA_GAIN      BIT(5)
0098 #define SSM2518_MUTE_CTRL_MUTE_MASTER       BIT(0)
0099 
0100 #define SSM2518_POWER2_APWDN            BIT(0)
0101 
0102 #define SSM2518_DAC_MUTE            BIT(6)
0103 #define SSM2518_DAC_FS_MASK         0x07
0104 #define SSM2518_DAC_FS_8000         0x00
0105 #define SSM2518_DAC_FS_16000            0x01
0106 #define SSM2518_DAC_FS_32000            0x02
0107 #define SSM2518_DAC_FS_64000            0x03
0108 #define SSM2518_DAC_FS_128000           0x04
0109 
0110 struct ssm2518 {
0111     struct regmap *regmap;
0112     bool right_j;
0113 
0114     unsigned int sysclk;
0115     const struct snd_pcm_hw_constraint_list *constraints;
0116 
0117     int enable_gpio;
0118 };
0119 
0120 static const struct reg_default ssm2518_reg_defaults[] = {
0121     { 0x00, 0x05 },
0122     { 0x01, 0x00 },
0123     { 0x02, 0x02 },
0124     { 0x03, 0x00 },
0125     { 0x04, 0x10 },
0126     { 0x05, 0x40 },
0127     { 0x06, 0x40 },
0128     { 0x07, 0x81 },
0129     { 0x08, 0x0c },
0130     { 0x09, 0x99 },
0131     { 0x0a, 0x7c },
0132     { 0x0b, 0x5b },
0133     { 0x0c, 0x57 },
0134     { 0x0d, 0x89 },
0135     { 0x0e, 0x8c },
0136     { 0x0f, 0x77 },
0137     { 0x10, 0x26 },
0138     { 0x11, 0x1c },
0139     { 0x12, 0x97 },
0140 };
0141 
0142 static const DECLARE_TLV_DB_MINMAX_MUTE(ssm2518_vol_tlv, -7125, 2400);
0143 static const DECLARE_TLV_DB_SCALE(ssm2518_compressor_tlv, -3400, 200, 0);
0144 static const DECLARE_TLV_DB_SCALE(ssm2518_expander_tlv, -8100, 300, 0);
0145 static const DECLARE_TLV_DB_SCALE(ssm2518_noise_gate_tlv, -9600, 300, 0);
0146 static const DECLARE_TLV_DB_SCALE(ssm2518_post_drc_tlv, -2400, 300, 0);
0147 
0148 static const DECLARE_TLV_DB_RANGE(ssm2518_limiter_tlv,
0149     0, 7, TLV_DB_SCALE_ITEM(-2200, 200, 0),
0150     7, 15, TLV_DB_SCALE_ITEM(-800, 100, 0),
0151 );
0152 
0153 static const char * const ssm2518_drc_peak_detector_attack_time_text[] = {
0154     "0 ms", "0.1 ms", "0.19 ms", "0.37 ms", "0.75 ms", "1.5 ms", "3 ms",
0155     "6 ms", "12 ms", "24 ms", "48 ms", "96 ms", "192 ms", "384 ms",
0156     "768 ms", "1536 ms",
0157 };
0158 
0159 static const char * const ssm2518_drc_peak_detector_release_time_text[] = {
0160     "0 ms", "1.5 ms", "3 ms", "6 ms", "12 ms", "24 ms", "48 ms", "96 ms",
0161     "192 ms", "384 ms", "768 ms", "1536 ms", "3072 ms", "6144 ms",
0162     "12288 ms", "24576 ms"
0163 };
0164 
0165 static const char * const ssm2518_drc_hold_time_text[] = {
0166     "0 ms", "0.67 ms", "1.33 ms", "2.67 ms", "5.33 ms", "10.66 ms",
0167     "21.32 ms", "42.64 ms", "85.28 ms", "170.56 ms", "341.12 ms",
0168     "682.24 ms", "1364 ms",
0169 };
0170 
0171 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum,
0172     SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text);
0173 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum,
0174     SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text);
0175 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum,
0176     SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text);
0177 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum,
0178     SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text);
0179 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum,
0180     SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text);
0181 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum,
0182     SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text);
0183 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum,
0184     SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text);
0185 
0186 static const struct snd_kcontrol_new ssm2518_snd_controls[] = {
0187     SOC_SINGLE("Playback De-emphasis Switch", SSM2518_REG_MUTE_CTRL,
0188             4, 1, 0),
0189     SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2518_REG_LEFT_VOL,
0190             SSM2518_REG_RIGHT_VOL, 0, 0xff, 1, ssm2518_vol_tlv),
0191     SOC_DOUBLE("Master Playback Switch", SSM2518_REG_MUTE_CTRL, 2, 1, 1, 1),
0192 
0193     SOC_SINGLE("Amp Low Power Mode Switch", SSM2518_REG_POWER2, 4, 1, 0),
0194     SOC_SINGLE("DAC Low Power Mode Switch", SSM2518_REG_POWER2, 3, 1, 0),
0195 
0196     SOC_SINGLE("DRC Limiter Switch", SSM2518_REG_DRC_1, 5, 1, 0),
0197     SOC_SINGLE("DRC Compressor Switch", SSM2518_REG_DRC_1, 4, 1, 0),
0198     SOC_SINGLE("DRC Expander Switch", SSM2518_REG_DRC_1, 3, 1, 0),
0199     SOC_SINGLE("DRC Noise Gate Switch", SSM2518_REG_DRC_1, 2, 1, 0),
0200     SOC_DOUBLE("DRC Switch", SSM2518_REG_DRC_1, 0, 1, 1, 0),
0201 
0202     SOC_SINGLE_TLV("DRC Limiter Threshold Volume",
0203             SSM2518_REG_DRC_3, 4, 15, 1, ssm2518_limiter_tlv),
0204     SOC_SINGLE_TLV("DRC Compressor Lower Threshold Volume",
0205             SSM2518_REG_DRC_3, 0, 15, 1, ssm2518_compressor_tlv),
0206     SOC_SINGLE_TLV("DRC Expander Upper Threshold Volume", SSM2518_REG_DRC_4,
0207             4, 15, 1, ssm2518_expander_tlv),
0208     SOC_SINGLE_TLV("DRC Noise Gate Threshold Volume",
0209             SSM2518_REG_DRC_4, 0, 15, 1, ssm2518_noise_gate_tlv),
0210     SOC_SINGLE_TLV("DRC Upper Output Threshold Volume",
0211             SSM2518_REG_DRC_5, 4, 15, 1, ssm2518_limiter_tlv),
0212     SOC_SINGLE_TLV("DRC Lower Output Threshold Volume",
0213             SSM2518_REG_DRC_5, 0, 15, 1, ssm2518_noise_gate_tlv),
0214     SOC_SINGLE_TLV("DRC Post Volume", SSM2518_REG_DRC_8,
0215             2, 15, 1, ssm2518_post_drc_tlv),
0216 
0217     SOC_ENUM("DRC Peak Detector Attack Time",
0218         ssm2518_drc_peak_detector_attack_time_enum),
0219     SOC_ENUM("DRC Peak Detector Release Time",
0220         ssm2518_drc_peak_detector_release_time_enum),
0221     SOC_ENUM("DRC Attack Time", ssm2518_drc_attack_time_enum),
0222     SOC_ENUM("DRC Decay Time", ssm2518_drc_decay_time_enum),
0223     SOC_ENUM("DRC Hold Time", ssm2518_drc_hold_time_enum),
0224     SOC_ENUM("DRC Noise Gate Hold Time",
0225         ssm2518_drc_noise_gate_hold_time_enum),
0226     SOC_ENUM("DRC RMS Averaging Time", ssm2518_drc_rms_averaging_time_enum),
0227 };
0228 
0229 static const struct snd_soc_dapm_widget ssm2518_dapm_widgets[] = {
0230     SND_SOC_DAPM_DAC("DACL", "HiFi Playback", SSM2518_REG_POWER2, 1, 1),
0231     SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SSM2518_REG_POWER2, 2, 1),
0232 
0233     SND_SOC_DAPM_OUTPUT("OUTL"),
0234     SND_SOC_DAPM_OUTPUT("OUTR"),
0235 };
0236 
0237 static const struct snd_soc_dapm_route ssm2518_routes[] = {
0238     { "OUTL", NULL, "DACL" },
0239     { "OUTR", NULL, "DACR" },
0240 };
0241 
0242 struct ssm2518_mcs_lut {
0243     unsigned int rate;
0244     const unsigned int *sysclks;
0245 };
0246 
0247 static const unsigned int ssm2518_sysclks_2048000[] = {
0248     2048000, 4096000, 8192000, 12288000, 16384000, 24576000,
0249     3200000, 6400000, 12800000, 0
0250 };
0251 
0252 static const unsigned int ssm2518_sysclks_2822000[] = {
0253     2822000, 5644800, 11289600, 16934400, 22579200, 33868800,
0254     4410000, 8820000, 17640000, 0
0255 };
0256 
0257 static const unsigned int ssm2518_sysclks_3072000[] = {
0258     3072000, 6144000, 12288000, 16384000, 24576000, 38864000,
0259     4800000, 9600000, 19200000, 0
0260 };
0261 
0262 static const struct ssm2518_mcs_lut ssm2518_mcs_lut[] = {
0263     { 8000,  ssm2518_sysclks_2048000, },
0264     { 11025, ssm2518_sysclks_2822000, },
0265     { 12000, ssm2518_sysclks_3072000, },
0266     { 16000, ssm2518_sysclks_2048000, },
0267     { 24000, ssm2518_sysclks_3072000, },
0268     { 22050, ssm2518_sysclks_2822000, },
0269     { 32000, ssm2518_sysclks_2048000, },
0270     { 44100, ssm2518_sysclks_2822000, },
0271     { 48000, ssm2518_sysclks_3072000, },
0272     { 96000, ssm2518_sysclks_3072000, },
0273 };
0274 
0275 static const unsigned int ssm2518_rates_2048000[] = {
0276     8000, 16000, 32000,
0277 };
0278 
0279 static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2048000 = {
0280     .list = ssm2518_rates_2048000,
0281     .count = ARRAY_SIZE(ssm2518_rates_2048000),
0282 };
0283 
0284 static const unsigned int ssm2518_rates_2822000[] = {
0285     11025, 22050, 44100,
0286 };
0287 
0288 static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2822000 = {
0289     .list = ssm2518_rates_2822000,
0290     .count = ARRAY_SIZE(ssm2518_rates_2822000),
0291 };
0292 
0293 static const unsigned int ssm2518_rates_3072000[] = {
0294     12000, 24000, 48000, 96000,
0295 };
0296 
0297 static const struct snd_pcm_hw_constraint_list ssm2518_constraints_3072000 = {
0298     .list = ssm2518_rates_3072000,
0299     .count = ARRAY_SIZE(ssm2518_rates_3072000),
0300 };
0301 
0302 static const unsigned int ssm2518_rates_12288000[] = {
0303     8000, 12000, 16000, 24000, 32000, 48000, 96000,
0304 };
0305 
0306 static const struct snd_pcm_hw_constraint_list ssm2518_constraints_12288000 = {
0307     .list = ssm2518_rates_12288000,
0308     .count = ARRAY_SIZE(ssm2518_rates_12288000),
0309 };
0310 
0311 static int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
0312     unsigned int rate)
0313 {
0314     const unsigned int *sysclks = NULL;
0315     int i;
0316 
0317     for (i = 0; i < ARRAY_SIZE(ssm2518_mcs_lut); i++) {
0318         if (ssm2518_mcs_lut[i].rate == rate) {
0319             sysclks = ssm2518_mcs_lut[i].sysclks;
0320             break;
0321         }
0322     }
0323 
0324     if (!sysclks)
0325         return -EINVAL;
0326 
0327     for (i = 0; sysclks[i]; i++) {
0328         if (sysclks[i] == ssm2518->sysclk)
0329             return i;
0330     }
0331 
0332     return -EINVAL;
0333 }
0334 
0335 static int ssm2518_hw_params(struct snd_pcm_substream *substream,
0336     struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
0337 {
0338     struct snd_soc_component *component = dai->component;
0339     struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
0340     unsigned int rate = params_rate(params);
0341     unsigned int ctrl1, ctrl1_mask;
0342     int mcs;
0343     int ret;
0344 
0345     mcs = ssm2518_lookup_mcs(ssm2518, rate);
0346     if (mcs < 0)
0347         return mcs;
0348 
0349     ctrl1_mask = SSM2518_SAI_CTRL1_FS_MASK;
0350 
0351     if (rate >= 8000 && rate <= 12000)
0352         ctrl1 = SSM2518_SAI_CTRL1_FS_8000_12000;
0353     else if (rate >= 16000 && rate <= 24000)
0354         ctrl1 = SSM2518_SAI_CTRL1_FS_16000_24000;
0355     else if (rate >= 32000 && rate <= 48000)
0356         ctrl1 = SSM2518_SAI_CTRL1_FS_32000_48000;
0357     else if (rate >= 64000 && rate <= 96000)
0358         ctrl1 = SSM2518_SAI_CTRL1_FS_64000_96000;
0359     else
0360         return -EINVAL;
0361 
0362     if (ssm2518->right_j) {
0363         switch (params_width(params)) {
0364         case 16:
0365             ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_16BIT;
0366             break;
0367         case 24:
0368             ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
0369             break;
0370         default:
0371             return -EINVAL;
0372         }
0373         ctrl1_mask |= SSM2518_SAI_CTRL1_FMT_MASK;
0374     }
0375 
0376     /* Disable auto samplerate detection */
0377     ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_CLOCK,
0378                 SSM2518_CLOCK_ASR, SSM2518_CLOCK_ASR);
0379     if (ret < 0)
0380         return ret;
0381 
0382     ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
0383                 ctrl1_mask, ctrl1);
0384     if (ret < 0)
0385         return ret;
0386 
0387     return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
0388                 SSM2518_POWER1_MCS_MASK, mcs << 1);
0389 }
0390 
0391 static int ssm2518_mute(struct snd_soc_dai *dai, int mute, int direction)
0392 {
0393     struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
0394     unsigned int val;
0395 
0396     if (mute)
0397         val = SSM2518_MUTE_CTRL_MUTE_MASTER;
0398     else
0399         val = 0;
0400 
0401     return regmap_update_bits(ssm2518->regmap, SSM2518_REG_MUTE_CTRL,
0402             SSM2518_MUTE_CTRL_MUTE_MASTER, val);
0403 }
0404 
0405 static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0406 {
0407     struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
0408     unsigned int ctrl1 = 0, ctrl2 = 0;
0409     bool invert_fclk;
0410     int ret;
0411 
0412     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0413     case SND_SOC_DAIFMT_CBC_CFC:
0414         break;
0415     default:
0416         return -EINVAL;
0417     }
0418 
0419     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0420     case SND_SOC_DAIFMT_NB_NF:
0421         invert_fclk = false;
0422         break;
0423     case SND_SOC_DAIFMT_IB_NF:
0424         ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
0425         invert_fclk = false;
0426         break;
0427     case SND_SOC_DAIFMT_NB_IF:
0428         invert_fclk = true;
0429         break;
0430     case SND_SOC_DAIFMT_IB_IF:
0431         ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
0432         invert_fclk = true;
0433         break;
0434     default:
0435         return -EINVAL;
0436     }
0437 
0438     ssm2518->right_j = false;
0439     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0440     case SND_SOC_DAIFMT_I2S:
0441         ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
0442         break;
0443     case SND_SOC_DAIFMT_LEFT_J:
0444         ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
0445         invert_fclk = !invert_fclk;
0446         break;
0447     case SND_SOC_DAIFMT_RIGHT_J:
0448         ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
0449         ssm2518->right_j = true;
0450         invert_fclk = !invert_fclk;
0451         break;
0452     case SND_SOC_DAIFMT_DSP_A:
0453         ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
0454         ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
0455         invert_fclk = false;
0456         break;
0457     case SND_SOC_DAIFMT_DSP_B:
0458         ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
0459         ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
0460         invert_fclk = false;
0461         break;
0462     default:
0463         return -EINVAL;
0464     }
0465 
0466     if (invert_fclk)
0467         ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_INVERT;
0468 
0469     ret = regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL1, ctrl1);
0470     if (ret)
0471         return ret;
0472 
0473     return regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL2, ctrl2);
0474 }
0475 
0476 static int ssm2518_set_power(struct ssm2518 *ssm2518, bool enable)
0477 {
0478     int ret = 0;
0479 
0480     if (!enable) {
0481         ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
0482             SSM2518_POWER1_SPWDN, SSM2518_POWER1_SPWDN);
0483         regcache_mark_dirty(ssm2518->regmap);
0484     }
0485 
0486     if (gpio_is_valid(ssm2518->enable_gpio))
0487         gpio_set_value(ssm2518->enable_gpio, enable);
0488 
0489     regcache_cache_only(ssm2518->regmap, !enable);
0490 
0491     if (enable) {
0492         ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
0493             SSM2518_POWER1_SPWDN | SSM2518_POWER1_RESET, 0x00);
0494         regcache_sync(ssm2518->regmap);
0495     }
0496 
0497     return ret;
0498 }
0499 
0500 static int ssm2518_set_bias_level(struct snd_soc_component *component,
0501     enum snd_soc_bias_level level)
0502 {
0503     struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
0504     int ret = 0;
0505 
0506     switch (level) {
0507     case SND_SOC_BIAS_ON:
0508         break;
0509     case SND_SOC_BIAS_PREPARE:
0510         break;
0511     case SND_SOC_BIAS_STANDBY:
0512         if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
0513             ret = ssm2518_set_power(ssm2518, true);
0514         break;
0515     case SND_SOC_BIAS_OFF:
0516         ret = ssm2518_set_power(ssm2518, false);
0517         break;
0518     }
0519 
0520     return ret;
0521 }
0522 
0523 static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
0524     unsigned int rx_mask, int slots, int width)
0525 {
0526     struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
0527     unsigned int ctrl1, ctrl2;
0528     int left_slot, right_slot;
0529     int ret;
0530 
0531     if (slots == 0)
0532         return regmap_update_bits(ssm2518->regmap,
0533             SSM2518_REG_SAI_CTRL1, SSM2518_SAI_CTRL1_SAI_MASK,
0534             SSM2518_SAI_CTRL1_SAI_I2S);
0535 
0536     if (tx_mask == 0 || rx_mask != 0)
0537         return -EINVAL;
0538 
0539     if (slots == 1) {
0540         if (tx_mask != 1)
0541             return -EINVAL;
0542         left_slot = 0;
0543         right_slot = 0;
0544     } else {
0545         /* We assume the left channel < right channel */
0546         left_slot = __ffs(tx_mask);
0547         tx_mask &= ~(1 << left_slot);
0548         if (tx_mask == 0) {
0549             right_slot = left_slot;
0550         } else {
0551             right_slot = __ffs(tx_mask);
0552             tx_mask &= ~(1 << right_slot);
0553         }
0554     }
0555 
0556     if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
0557         return -EINVAL;
0558 
0559     switch (width) {
0560     case 16:
0561         ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_16;
0562         break;
0563     case 24:
0564         ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_24;
0565         break;
0566     case 32:
0567         ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_32;
0568         break;
0569     default:
0570         return -EINVAL;
0571     }
0572 
0573     switch (slots) {
0574     case 1:
0575         ctrl1 = SSM2518_SAI_CTRL1_SAI_MONO;
0576         break;
0577     case 2:
0578         ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_2;
0579         break;
0580     case 4:
0581         ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_4;
0582         break;
0583     case 8:
0584         ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_8;
0585         break;
0586     case 16:
0587         ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_16;
0588         break;
0589     default:
0590         return -EINVAL;
0591     }
0592 
0593     ret = regmap_write(ssm2518->regmap, SSM2518_REG_CHAN_MAP,
0594         (left_slot << SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET) |
0595         (right_slot << SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET));
0596     if (ret)
0597         return ret;
0598 
0599     ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
0600         SSM2518_SAI_CTRL1_SAI_MASK, ctrl1);
0601     if (ret)
0602         return ret;
0603 
0604     return regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL2,
0605         SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK, ctrl2);
0606 }
0607 
0608 static int ssm2518_startup(struct snd_pcm_substream *substream,
0609     struct snd_soc_dai *dai)
0610 {
0611     struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
0612 
0613     if (ssm2518->constraints)
0614         snd_pcm_hw_constraint_list(substream->runtime, 0,
0615                 SNDRV_PCM_HW_PARAM_RATE, ssm2518->constraints);
0616 
0617     return 0;
0618 }
0619 
0620 #define SSM2518_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
0621             SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32)
0622 
0623 static const struct snd_soc_dai_ops ssm2518_dai_ops = {
0624     .startup = ssm2518_startup,
0625     .hw_params  = ssm2518_hw_params,
0626     .mute_stream    = ssm2518_mute,
0627     .set_fmt    = ssm2518_set_dai_fmt,
0628     .set_tdm_slot   = ssm2518_set_tdm_slot,
0629     .no_capture_mute = 1,
0630 };
0631 
0632 static struct snd_soc_dai_driver ssm2518_dai = {
0633     .name = "ssm2518-hifi",
0634     .playback = {
0635         .stream_name = "Playback",
0636         .channels_min = 2,
0637         .channels_max = 2,
0638         .rates = SNDRV_PCM_RATE_8000_96000,
0639         .formats = SSM2518_FORMATS,
0640     },
0641     .ops = &ssm2518_dai_ops,
0642 };
0643 
0644 static int ssm2518_set_sysclk(struct snd_soc_component *component, int clk_id,
0645     int source, unsigned int freq, int dir)
0646 {
0647     struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
0648     unsigned int val;
0649 
0650     if (clk_id != SSM2518_SYSCLK)
0651         return -EINVAL;
0652 
0653     switch (source) {
0654     case SSM2518_SYSCLK_SRC_MCLK:
0655         val = 0;
0656         break;
0657     case SSM2518_SYSCLK_SRC_BCLK:
0658         /* In this case the bitclock is used as the system clock, and
0659          * the bitclock signal needs to be connected to the MCLK pin and
0660          * the BCLK pin is left unconnected */
0661         val = SSM2518_POWER1_NO_BCLK;
0662         break;
0663     default:
0664         return -EINVAL;
0665     }
0666 
0667     switch (freq) {
0668     case 0:
0669         ssm2518->constraints = NULL;
0670         break;
0671     case 2048000:
0672     case 4096000:
0673     case 8192000:
0674     case 3200000:
0675     case 6400000:
0676     case 12800000:
0677         ssm2518->constraints = &ssm2518_constraints_2048000;
0678         break;
0679     case 2822000:
0680     case 5644800:
0681     case 11289600:
0682     case 16934400:
0683     case 22579200:
0684     case 33868800:
0685     case 4410000:
0686     case 8820000:
0687     case 17640000:
0688         ssm2518->constraints = &ssm2518_constraints_2822000;
0689         break;
0690     case 3072000:
0691     case 6144000:
0692     case 38864000:
0693     case 4800000:
0694     case 9600000:
0695     case 19200000:
0696         ssm2518->constraints = &ssm2518_constraints_3072000;
0697         break;
0698     case 12288000:
0699     case 16384000:
0700     case 24576000:
0701         ssm2518->constraints = &ssm2518_constraints_12288000;
0702         break;
0703     default:
0704         return -EINVAL;
0705     }
0706 
0707     ssm2518->sysclk = freq;
0708 
0709     return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
0710             SSM2518_POWER1_NO_BCLK, val);
0711 }
0712 
0713 static const struct snd_soc_component_driver ssm2518_component_driver = {
0714     .set_bias_level     = ssm2518_set_bias_level,
0715     .set_sysclk     = ssm2518_set_sysclk,
0716     .controls       = ssm2518_snd_controls,
0717     .num_controls       = ARRAY_SIZE(ssm2518_snd_controls),
0718     .dapm_widgets       = ssm2518_dapm_widgets,
0719     .num_dapm_widgets   = ARRAY_SIZE(ssm2518_dapm_widgets),
0720     .dapm_routes        = ssm2518_routes,
0721     .num_dapm_routes    = ARRAY_SIZE(ssm2518_routes),
0722     .use_pmdown_time    = 1,
0723     .endianness     = 1,
0724 };
0725 
0726 static const struct regmap_config ssm2518_regmap_config = {
0727     .val_bits = 8,
0728     .reg_bits = 8,
0729 
0730     .max_register = SSM2518_REG_DRC_9,
0731 
0732     .cache_type = REGCACHE_RBTREE,
0733     .reg_defaults = ssm2518_reg_defaults,
0734     .num_reg_defaults = ARRAY_SIZE(ssm2518_reg_defaults),
0735 };
0736 
0737 static int ssm2518_i2c_probe(struct i2c_client *i2c)
0738 {
0739     struct ssm2518_platform_data *pdata = i2c->dev.platform_data;
0740     struct ssm2518 *ssm2518;
0741     int ret;
0742 
0743     ssm2518 = devm_kzalloc(&i2c->dev, sizeof(*ssm2518), GFP_KERNEL);
0744     if (ssm2518 == NULL)
0745         return -ENOMEM;
0746 
0747     if (pdata) {
0748         ssm2518->enable_gpio = pdata->enable_gpio;
0749     } else if (i2c->dev.of_node) {
0750         ssm2518->enable_gpio = of_get_gpio(i2c->dev.of_node, 0);
0751         if (ssm2518->enable_gpio < 0 && ssm2518->enable_gpio != -ENOENT)
0752             return ssm2518->enable_gpio;
0753     } else {
0754         ssm2518->enable_gpio = -1;
0755     }
0756 
0757     if (gpio_is_valid(ssm2518->enable_gpio)) {
0758         ret = devm_gpio_request_one(&i2c->dev, ssm2518->enable_gpio,
0759                 GPIOF_OUT_INIT_HIGH, "SSM2518 nSD");
0760         if (ret)
0761             return ret;
0762     }
0763 
0764     i2c_set_clientdata(i2c, ssm2518);
0765 
0766     ssm2518->regmap = devm_regmap_init_i2c(i2c, &ssm2518_regmap_config);
0767     if (IS_ERR(ssm2518->regmap))
0768         return PTR_ERR(ssm2518->regmap);
0769 
0770     /*
0771      * The reset bit is obviously volatile, but we need to be able to cache
0772      * the other bits in the register, so we can't just mark the whole
0773      * register as volatile. Since this is the only place where we'll ever
0774      * touch the reset bit just bypass the cache for this operation.
0775      */
0776     regcache_cache_bypass(ssm2518->regmap, true);
0777     ret = regmap_write(ssm2518->regmap, SSM2518_REG_POWER1,
0778             SSM2518_POWER1_RESET);
0779     regcache_cache_bypass(ssm2518->regmap, false);
0780     if (ret)
0781         return ret;
0782 
0783     ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER2,
0784                 SSM2518_POWER2_APWDN, 0x00);
0785     if (ret)
0786         return ret;
0787 
0788     ret = ssm2518_set_power(ssm2518, false);
0789     if (ret)
0790         return ret;
0791 
0792     return devm_snd_soc_register_component(&i2c->dev,
0793             &ssm2518_component_driver,
0794             &ssm2518_dai, 1);
0795 }
0796 
0797 #ifdef CONFIG_OF
0798 static const struct of_device_id ssm2518_dt_ids[] = {
0799     { .compatible = "adi,ssm2518", },
0800     { }
0801 };
0802 MODULE_DEVICE_TABLE(of, ssm2518_dt_ids);
0803 #endif
0804 
0805 static const struct i2c_device_id ssm2518_i2c_ids[] = {
0806     { "ssm2518", 0 },
0807     { }
0808 };
0809 MODULE_DEVICE_TABLE(i2c, ssm2518_i2c_ids);
0810 
0811 static struct i2c_driver ssm2518_driver = {
0812     .driver = {
0813         .name = "ssm2518",
0814         .of_match_table = of_match_ptr(ssm2518_dt_ids),
0815     },
0816     .probe_new = ssm2518_i2c_probe,
0817     .id_table = ssm2518_i2c_ids,
0818 };
0819 module_i2c_driver(ssm2518_driver);
0820 
0821 MODULE_DESCRIPTION("ASoC SSM2518 driver");
0822 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
0823 MODULE_LICENSE("GPL");