ssm2518.c (23077B)
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{ 740 struct ssm2518_platform_data *pdata = i2c->dev.platform_data; 741 struct ssm2518 *ssm2518; 742 int ret; 743 744 ssm2518 = devm_kzalloc(&i2c->dev, sizeof(*ssm2518), GFP_KERNEL); 745 if (ssm2518 == NULL) 746 return -ENOMEM; 747 748 if (pdata) { 749 ssm2518->enable_gpio = pdata->enable_gpio; 750 } else if (i2c->dev.of_node) { 751 ssm2518->enable_gpio = of_get_gpio(i2c->dev.of_node, 0); 752 if (ssm2518->enable_gpio < 0 && ssm2518->enable_gpio != -ENOENT) 753 return ssm2518->enable_gpio; 754 } else { 755 ssm2518->enable_gpio = -1; 756 } 757 758 if (gpio_is_valid(ssm2518->enable_gpio)) { 759 ret = devm_gpio_request_one(&i2c->dev, ssm2518->enable_gpio, 760 GPIOF_OUT_INIT_HIGH, "SSM2518 nSD"); 761 if (ret) 762 return ret; 763 } 764 765 i2c_set_clientdata(i2c, ssm2518); 766 767 ssm2518->regmap = devm_regmap_init_i2c(i2c, &ssm2518_regmap_config); 768 if (IS_ERR(ssm2518->regmap)) 769 return PTR_ERR(ssm2518->regmap); 770 771 /* 772 * The reset bit is obviously volatile, but we need to be able to cache 773 * the other bits in the register, so we can't just mark the whole 774 * register as volatile. Since this is the only place where we'll ever 775 * touch the reset bit just bypass the cache for this operation. 776 */ 777 regcache_cache_bypass(ssm2518->regmap, true); 778 ret = regmap_write(ssm2518->regmap, SSM2518_REG_POWER1, 779 SSM2518_POWER1_RESET); 780 regcache_cache_bypass(ssm2518->regmap, false); 781 if (ret) 782 return ret; 783 784 ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER2, 785 SSM2518_POWER2_APWDN, 0x00); 786 if (ret) 787 return ret; 788 789 ret = ssm2518_set_power(ssm2518, false); 790 if (ret) 791 return ret; 792 793 return devm_snd_soc_register_component(&i2c->dev, 794 &ssm2518_component_driver, 795 &ssm2518_dai, 1); 796} 797 798#ifdef CONFIG_OF 799static const struct of_device_id ssm2518_dt_ids[] = { 800 { .compatible = "adi,ssm2518", }, 801 { } 802}; 803MODULE_DEVICE_TABLE(of, ssm2518_dt_ids); 804#endif 805 806static const struct i2c_device_id ssm2518_i2c_ids[] = { 807 { "ssm2518", 0 }, 808 { } 809}; 810MODULE_DEVICE_TABLE(i2c, ssm2518_i2c_ids); 811 812static struct i2c_driver ssm2518_driver = { 813 .driver = { 814 .name = "ssm2518", 815 .of_match_table = of_match_ptr(ssm2518_dt_ids), 816 }, 817 .probe_new = ssm2518_i2c_probe, 818 .id_table = ssm2518_i2c_ids, 819}; 820module_i2c_driver(ssm2518_driver); 821 822MODULE_DESCRIPTION("ASoC SSM2518 driver"); 823MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 824MODULE_LICENSE("GPL");