1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Audio driver for AK5558 ADC 4 // 5 // Copyright (C) 2015 Asahi Kasei Microdevices Corporation 6 // Copyright 2018 NXP 7 8 #include <linux/delay.h> 9 #include <linux/gpio/consumer.h> 10 #include <linux/i2c.h> 11 #include <linux/module.h> 12 #include <linux/pm_runtime.h> 13 #include <linux/regmap.h> 14 #include <linux/slab.h> 15 16 #include <sound/initval.h> 17 #include <sound/pcm.h> 18 #include <sound/pcm_params.h> 19 #include <sound/soc.h> 20 #include <sound/soc-dapm.h> 21 #include <sound/tlv.h> 22 23 #include "ak5558.h" 24 25 /* AK5558 Codec Private Data */ 26 struct ak5558_priv { 27 struct snd_soc_component component; 28 struct regmap *regmap; 29 struct i2c_client *i2c; 30 struct gpio_desc *reset_gpiod; /* Reset & Power down GPIO */ 31 int slots; 32 int slot_width; 33 }; 34 35 /* ak5558 register cache & default register settings */ 36 static const struct reg_default ak5558_reg[] = { 37 { 0x0, 0xFF }, /* 0x00 AK5558_00_POWER_MANAGEMENT1 */ 38 { 0x1, 0x01 }, /* 0x01 AK5558_01_POWER_MANAGEMENT2 */ 39 { 0x2, 0x01 }, /* 0x02 AK5558_02_CONTROL1 */ 40 { 0x3, 0x00 }, /* 0x03 AK5558_03_CONTROL2 */ 41 { 0x4, 0x00 }, /* 0x04 AK5558_04_CONTROL3 */ 42 { 0x5, 0x00 } /* 0x05 AK5558_05_DSD */ 43 }; 44 45 static const char * const mono_texts[] = { 46 "8 Slot", "2 Slot", "4 Slot", "1 Slot", 47 }; 48 49 static const struct soc_enum ak5558_mono_enum[] = { 50 SOC_ENUM_SINGLE(AK5558_01_POWER_MANAGEMENT2, 1, 51 ARRAY_SIZE(mono_texts), mono_texts), 52 }; 53 54 static const char * const digfil_texts[] = { 55 "Sharp Roll-Off", "Show Roll-Off", 56 "Short Delay Sharp Roll-Off", "Short Delay Show Roll-Off", 57 }; 58 59 static const struct soc_enum ak5558_adcset_enum[] = { 60 SOC_ENUM_SINGLE(AK5558_04_CONTROL3, 0, 61 ARRAY_SIZE(digfil_texts), digfil_texts), 62 }; 63 64 static const struct snd_kcontrol_new ak5558_snd_controls[] = { 65 SOC_ENUM("AK5558 Monaural Mode", ak5558_mono_enum[0]), 66 SOC_ENUM("AK5558 Digital Filter", ak5558_adcset_enum[0]), 67 }; 68 69 static const struct snd_soc_dapm_widget ak5558_dapm_widgets[] = { 70 /* Analog Input */ 71 SND_SOC_DAPM_INPUT("AIN1"), 72 SND_SOC_DAPM_INPUT("AIN2"), 73 SND_SOC_DAPM_INPUT("AIN3"), 74 SND_SOC_DAPM_INPUT("AIN4"), 75 SND_SOC_DAPM_INPUT("AIN5"), 76 SND_SOC_DAPM_INPUT("AIN6"), 77 SND_SOC_DAPM_INPUT("AIN7"), 78 SND_SOC_DAPM_INPUT("AIN8"), 79 80 SND_SOC_DAPM_ADC("ADC Ch1", NULL, AK5558_00_POWER_MANAGEMENT1, 0, 0), 81 SND_SOC_DAPM_ADC("ADC Ch2", NULL, AK5558_00_POWER_MANAGEMENT1, 1, 0), 82 SND_SOC_DAPM_ADC("ADC Ch3", NULL, AK5558_00_POWER_MANAGEMENT1, 2, 0), 83 SND_SOC_DAPM_ADC("ADC Ch4", NULL, AK5558_00_POWER_MANAGEMENT1, 3, 0), 84 SND_SOC_DAPM_ADC("ADC Ch5", NULL, AK5558_00_POWER_MANAGEMENT1, 4, 0), 85 SND_SOC_DAPM_ADC("ADC Ch6", NULL, AK5558_00_POWER_MANAGEMENT1, 5, 0), 86 SND_SOC_DAPM_ADC("ADC Ch7", NULL, AK5558_00_POWER_MANAGEMENT1, 6, 0), 87 SND_SOC_DAPM_ADC("ADC Ch8", NULL, AK5558_00_POWER_MANAGEMENT1, 7, 0), 88 89 SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0), 90 }; 91 92 static const struct snd_soc_dapm_route ak5558_intercon[] = { 93 {"ADC Ch1", NULL, "AIN1"}, 94 {"SDTO", NULL, "ADC Ch1"}, 95 96 {"ADC Ch2", NULL, "AIN2"}, 97 {"SDTO", NULL, "ADC Ch2"}, 98 99 {"ADC Ch3", NULL, "AIN3"}, 100 {"SDTO", NULL, "ADC Ch3"}, 101 102 {"ADC Ch4", NULL, "AIN4"}, 103 {"SDTO", NULL, "ADC Ch4"}, 104 105 {"ADC Ch5", NULL, "AIN5"}, 106 {"SDTO", NULL, "ADC Ch5"}, 107 108 {"ADC Ch6", NULL, "AIN6"}, 109 {"SDTO", NULL, "ADC Ch6"}, 110 111 {"ADC Ch7", NULL, "AIN7"}, 112 {"SDTO", NULL, "ADC Ch7"}, 113 114 {"ADC Ch8", NULL, "AIN8"}, 115 {"SDTO", NULL, "ADC Ch8"}, 116 }; 117 118 static int ak5558_set_mcki(struct snd_soc_component *component) 119 { 120 return snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_CKS, 121 AK5558_CKS_AUTO); 122 } 123 124 static int ak5558_hw_params(struct snd_pcm_substream *substream, 125 struct snd_pcm_hw_params *params, 126 struct snd_soc_dai *dai) 127 { 128 struct snd_soc_component *component = dai->component; 129 struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component); 130 u8 bits; 131 int pcm_width = max(params_physical_width(params), ak5558->slot_width); 132 133 switch (pcm_width) { 134 case 16: 135 bits = AK5558_DIF_24BIT_MODE; 136 break; 137 case 32: 138 bits = AK5558_DIF_32BIT_MODE; 139 break; 140 default: 141 return -EINVAL; 142 } 143 144 snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_BITS, bits); 145 146 return 0; 147 } 148 149 static int ak5558_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 150 { 151 struct snd_soc_component *component = dai->component; 152 u8 format; 153 154 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 155 case SND_SOC_DAIFMT_CBS_CFS: 156 break; 157 case SND_SOC_DAIFMT_CBM_CFM: 158 break; 159 case SND_SOC_DAIFMT_CBS_CFM: 160 case SND_SOC_DAIFMT_CBM_CFS: 161 default: 162 dev_err(dai->dev, "Clock mode unsupported"); 163 return -EINVAL; 164 } 165 166 /* set master/slave audio interface */ 167 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 168 case SND_SOC_DAIFMT_I2S: 169 format = AK5558_DIF_I2S_MODE; 170 break; 171 case SND_SOC_DAIFMT_LEFT_J: 172 format = AK5558_DIF_MSB_MODE; 173 break; 174 case SND_SOC_DAIFMT_DSP_B: 175 format = AK5558_DIF_MSB_MODE; 176 break; 177 default: 178 return -EINVAL; 179 } 180 181 snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_DIF, format); 182 183 return 0; 184 } 185 186 static int ak5558_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 187 unsigned int rx_mask, int slots, 188 int slot_width) 189 { 190 struct snd_soc_component *component = dai->component; 191 struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component); 192 int tdm_mode; 193 194 ak5558->slots = slots; 195 ak5558->slot_width = slot_width; 196 197 switch (slots * slot_width) { 198 case 128: 199 tdm_mode = AK5558_MODE_TDM128; 200 break; 201 case 256: 202 tdm_mode = AK5558_MODE_TDM256; 203 break; 204 case 512: 205 tdm_mode = AK5558_MODE_TDM512; 206 break; 207 default: 208 tdm_mode = AK5558_MODE_NORMAL; 209 break; 210 } 211 212 snd_soc_component_update_bits(component, AK5558_03_CONTROL2, AK5558_MODE_BITS, 213 tdm_mode); 214 return 0; 215 } 216 217 #define AK5558_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 218 SNDRV_PCM_FMTBIT_S24_LE |\ 219 SNDRV_PCM_FMTBIT_S32_LE) 220 221 static const unsigned int ak5558_rates[] = { 222 8000, 11025, 16000, 22050, 223 32000, 44100, 48000, 88200, 224 96000, 176400, 192000, 352800, 225 384000, 705600, 768000, 1411200, 226 2822400, 227 }; 228 229 static const struct snd_pcm_hw_constraint_list ak5558_rate_constraints = { 230 .count = ARRAY_SIZE(ak5558_rates), 231 .list = ak5558_rates, 232 }; 233 234 static int ak5558_startup(struct snd_pcm_substream *substream, 235 struct snd_soc_dai *dai) 236 { 237 return snd_pcm_hw_constraint_list(substream->runtime, 0, 238 SNDRV_PCM_HW_PARAM_RATE, 239 &ak5558_rate_constraints); 240 } 241 242 static const struct snd_soc_dai_ops ak5558_dai_ops = { 243 .startup = ak5558_startup, 244 .hw_params = ak5558_hw_params, 245 246 .set_fmt = ak5558_set_dai_fmt, 247 .set_tdm_slot = ak5558_set_tdm_slot, 248 }; 249 250 static struct snd_soc_dai_driver ak5558_dai = { 251 .name = "ak5558-aif", 252 .capture = { 253 .stream_name = "Capture", 254 .channels_min = 1, 255 .channels_max = 8, 256 .rates = SNDRV_PCM_RATE_KNOT, 257 .formats = AK5558_FORMATS, 258 }, 259 .ops = &ak5558_dai_ops, 260 }; 261 262 static void ak5558_power_off(struct ak5558_priv *ak5558) 263 { 264 if (!ak5558->reset_gpiod) 265 return; 266 267 gpiod_set_value_cansleep(ak5558->reset_gpiod, 0); 268 usleep_range(1000, 2000); 269 } 270 271 static void ak5558_power_on(struct ak5558_priv *ak5558) 272 { 273 if (!ak5558->reset_gpiod) 274 return; 275 276 gpiod_set_value_cansleep(ak5558->reset_gpiod, 1); 277 usleep_range(1000, 2000); 278 } 279 280 static int ak5558_probe(struct snd_soc_component *component) 281 { 282 struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component); 283 284 ak5558_power_on(ak5558); 285 return ak5558_set_mcki(component); 286 } 287 288 static void ak5558_remove(struct snd_soc_component *component) 289 { 290 struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component); 291 292 ak5558_power_off(ak5558); 293 } 294 295 static int __maybe_unused ak5558_runtime_suspend(struct device *dev) 296 { 297 struct ak5558_priv *ak5558 = dev_get_drvdata(dev); 298 299 regcache_cache_only(ak5558->regmap, true); 300 ak5558_power_off(ak5558); 301 302 return 0; 303 } 304 305 static int __maybe_unused ak5558_runtime_resume(struct device *dev) 306 { 307 struct ak5558_priv *ak5558 = dev_get_drvdata(dev); 308 309 ak5558_power_off(ak5558); 310 ak5558_power_on(ak5558); 311 312 regcache_cache_only(ak5558->regmap, false); 313 regcache_mark_dirty(ak5558->regmap); 314 315 return regcache_sync(ak5558->regmap); 316 } 317 318 static const struct dev_pm_ops ak5558_pm = { 319 SET_RUNTIME_PM_OPS(ak5558_runtime_suspend, ak5558_runtime_resume, NULL) 320 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 321 pm_runtime_force_resume) 322 }; 323 324 static const struct snd_soc_component_driver soc_codec_dev_ak5558 = { 325 .probe = ak5558_probe, 326 .remove = ak5558_remove, 327 .controls = ak5558_snd_controls, 328 .num_controls = ARRAY_SIZE(ak5558_snd_controls), 329 .dapm_widgets = ak5558_dapm_widgets, 330 .num_dapm_widgets = ARRAY_SIZE(ak5558_dapm_widgets), 331 .dapm_routes = ak5558_intercon, 332 .num_dapm_routes = ARRAY_SIZE(ak5558_intercon), 333 .idle_bias_on = 1, 334 .use_pmdown_time = 1, 335 .endianness = 1, 336 .non_legacy_dai_naming = 1, 337 }; 338 339 static const struct regmap_config ak5558_regmap = { 340 .reg_bits = 8, 341 .val_bits = 8, 342 343 .max_register = AK5558_05_DSD, 344 .reg_defaults = ak5558_reg, 345 .num_reg_defaults = ARRAY_SIZE(ak5558_reg), 346 .cache_type = REGCACHE_RBTREE, 347 }; 348 349 static int ak5558_i2c_probe(struct i2c_client *i2c) 350 { 351 struct ak5558_priv *ak5558; 352 int ret = 0; 353 354 ak5558 = devm_kzalloc(&i2c->dev, sizeof(*ak5558), GFP_KERNEL); 355 if (!ak5558) 356 return -ENOMEM; 357 358 ak5558->regmap = devm_regmap_init_i2c(i2c, &ak5558_regmap); 359 if (IS_ERR(ak5558->regmap)) 360 return PTR_ERR(ak5558->regmap); 361 362 i2c_set_clientdata(i2c, ak5558); 363 ak5558->i2c = i2c; 364 365 ak5558->reset_gpiod = devm_gpiod_get_optional(&i2c->dev, "reset", 366 GPIOD_OUT_LOW); 367 if (IS_ERR(ak5558->reset_gpiod)) 368 return PTR_ERR(ak5558->reset_gpiod); 369 370 ret = devm_snd_soc_register_component(&i2c->dev, 371 &soc_codec_dev_ak5558, 372 &ak5558_dai, 1); 373 if (ret) 374 return ret; 375 376 pm_runtime_enable(&i2c->dev); 377 378 return 0; 379 } 380 381 static int ak5558_i2c_remove(struct i2c_client *i2c) 382 { 383 pm_runtime_disable(&i2c->dev); 384 385 return 0; 386 } 387 388 static const struct of_device_id ak5558_i2c_dt_ids[] = { 389 { .compatible = "asahi-kasei,ak5558"}, 390 { } 391 }; 392 393 static struct i2c_driver ak5558_i2c_driver = { 394 .driver = { 395 .name = "ak5558", 396 .of_match_table = of_match_ptr(ak5558_i2c_dt_ids), 397 .pm = &ak5558_pm, 398 }, 399 .probe_new = ak5558_i2c_probe, 400 .remove = ak5558_i2c_remove, 401 }; 402 403 module_i2c_driver(ak5558_i2c_driver); 404 405 MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>"); 406 MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>"); 407 MODULE_DESCRIPTION("ASoC AK5558 ADC driver"); 408 MODULE_LICENSE("GPL v2"); 409