1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Driver for the NTP8918 Audio Amplifier 4 * 5 * Copyright (c) 2024, SaluteDevices. All Rights Reserved. 6 * 7 * Author: Igor Prusov <ivprusov@salutedevices.com> 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/clk.h> 12 #include <linux/reset.h> 13 #include <linux/i2c.h> 14 #include <linux/regmap.h> 15 #include <linux/clk.h> 16 #include <linux/clk-provider.h> 17 18 #include <sound/initval.h> 19 #include <sound/core.h> 20 #include <sound/pcm.h> 21 #include <sound/pcm_params.h> 22 #include <sound/soc.h> 23 #include <sound/soc-component.h> 24 #include <sound/tlv.h> 25 26 #include "ntpfw.h" 27 28 #define NTP8918_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 29 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) 30 31 #define NTP8918_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 32 SNDRV_PCM_FMTBIT_S20_3LE | \ 33 SNDRV_PCM_FMTBIT_S24_LE | \ 34 SNDRV_PCM_FMTBIT_S32_LE) 35 36 #define NTP8918_INPUT_FMT 0x0 37 #define NTP8918_INPUT_FMT_MASTER_MODE BIT(0) 38 #define NTP8918_INPUT_FMT_GSA_MODE BIT(1) 39 #define NTP8918_GSA_FMT 0x1 40 #define NTP8918_GSA_BS_MASK GENMASK(3, 2) 41 #define NTP8918_GSA_BS(x) ((x) << 2) 42 #define NTP8918_GSA_RIGHT_J BIT(0) 43 #define NTP8918_GSA_LSB BIT(1) 44 #define NTP8918_MCLK_FREQ_CTRL 0x2 45 #define NTP8918_MCLK_FREQ_MCF GENMASK(1, 0) 46 #define NTP8918_MASTER_VOL 0x0C 47 #define NTP8918_CHNL_A_VOL 0x17 48 #define NTP8918_CHNL_B_VOL 0x18 49 #define NTP8918_SOFT_MUTE 0x33 50 #define NTP8918_SOFT_MUTE_SM1 BIT(0) 51 #define NTP8918_SOFT_MUTE_SM2 BIT(1) 52 #define NTP8918_PWM_SWITCH 0x34 53 #define NTP8918_PWM_MASK_CTRL0 0x35 54 #define REG_MAX NTP8918_PWM_MASK_CTRL0 55 56 #define NTP8918_FW_NAME "eq_8918.bin" 57 #define NTP8918_FW_MAGIC 0x38393138 /* "8918" */ 58 59 struct ntp8918_priv { 60 struct i2c_client *i2c; 61 struct clk *bck; 62 struct reset_control *reset; 63 unsigned int format; 64 }; 65 66 static const DECLARE_TLV_DB_SCALE(ntp8918_master_vol_scale, -12550, 50, 0); 67 68 static const struct snd_kcontrol_new ntp8918_vol_control[] = { 69 SOC_SINGLE_RANGE_TLV("Playback Volume", NTP8918_MASTER_VOL, 0, 70 0x04, 0xff, 0, ntp8918_master_vol_scale), 71 SOC_SINGLE("Playback Switch", NTP8918_PWM_MASK_CTRL0, 1, 1, 1), 72 }; 73 74 static void ntp8918_reset_gpio(struct ntp8918_priv *ntp8918) 75 { 76 /* 77 * Proper initialization sequence for NTP8918 amplifier requires driving 78 * /RESET signal low during power up for at least 0.1us. The sequence is, 79 * according to NTP8918 datasheet, 6.2 Timing Sequence 1: 80 * Deassert for T2 >= 1ms... 81 */ 82 reset_control_deassert(ntp8918->reset); 83 fsleep(1000); 84 85 /* ...Assert for T3 >= 0.1us... */ 86 reset_control_assert(ntp8918->reset); 87 fsleep(1); 88 89 /* ...Deassert, and wait for T4 >= 0.5ms before sound on sequence. */ 90 reset_control_deassert(ntp8918->reset); 91 fsleep(500); 92 } 93 94 static const struct reg_sequence ntp8918_sound_off[] = { 95 { NTP8918_MASTER_VOL, 0 }, 96 }; 97 98 static const struct reg_sequence ntp8918_sound_on[] = { 99 { NTP8918_MASTER_VOL, 0b11 }, 100 }; 101 102 static int ntp8918_load_firmware(struct ntp8918_priv *ntp8918) 103 { 104 int ret; 105 106 ret = ntpfw_load(ntp8918->i2c, NTP8918_FW_NAME, NTP8918_FW_MAGIC); 107 if (ret == -ENOENT) { 108 dev_warn_once(&ntp8918->i2c->dev, "Could not find firmware %s\n", 109 NTP8918_FW_NAME); 110 return 0; 111 } 112 113 return ret; 114 } 115 116 static int ntp8918_snd_suspend(struct snd_soc_component *component) 117 { 118 struct ntp8918_priv *ntp8918 = snd_soc_component_get_drvdata(component); 119 120 regcache_cache_only(component->regmap, true); 121 122 regmap_multi_reg_write_bypassed(component->regmap, 123 ntp8918_sound_off, 124 ARRAY_SIZE(ntp8918_sound_off)); 125 126 /* 127 * According to NTP8918 datasheet, 6.2 Timing Sequence 1: 128 * wait after sound off for T6 >= 0.5ms 129 */ 130 fsleep(500); 131 reset_control_assert(ntp8918->reset); 132 133 regcache_mark_dirty(component->regmap); 134 clk_disable_unprepare(ntp8918->bck); 135 136 return 0; 137 } 138 139 static int ntp8918_snd_resume(struct snd_soc_component *component) 140 { 141 struct ntp8918_priv *ntp8918 = snd_soc_component_get_drvdata(component); 142 int ret; 143 144 ret = clk_prepare_enable(ntp8918->bck); 145 if (ret) 146 return ret; 147 148 ntp8918_reset_gpio(ntp8918); 149 150 regmap_multi_reg_write_bypassed(component->regmap, 151 ntp8918_sound_on, 152 ARRAY_SIZE(ntp8918_sound_on)); 153 154 ret = ntp8918_load_firmware(ntp8918); 155 if (ret) { 156 dev_err(&ntp8918->i2c->dev, "Failed to load firmware\n"); 157 return ret; 158 } 159 160 regcache_cache_only(component->regmap, false); 161 snd_soc_component_cache_sync(component); 162 163 return 0; 164 } 165 166 static int ntp8918_probe(struct snd_soc_component *component) 167 { 168 int ret; 169 struct ntp8918_priv *ntp8918 = snd_soc_component_get_drvdata(component); 170 struct device *dev = component->dev; 171 172 ret = snd_soc_add_component_controls(component, ntp8918_vol_control, 173 ARRAY_SIZE(ntp8918_vol_control)); 174 if (ret) 175 return dev_err_probe(dev, ret, "Failed to add controls\n"); 176 177 ret = ntp8918_load_firmware(ntp8918); 178 if (ret) 179 return dev_err_probe(dev, ret, "Failed to load firmware\n"); 180 181 return 0; 182 } 183 184 static const struct snd_soc_dapm_widget ntp8918_dapm_widgets[] = { 185 SND_SOC_DAPM_DAC("AIFIN", "Playback", SND_SOC_NOPM, 0, 0), 186 187 SND_SOC_DAPM_OUTPUT("OUT1"), 188 SND_SOC_DAPM_OUTPUT("OUT2"), 189 }; 190 191 static const struct snd_soc_dapm_route ntp8918_dapm_routes[] = { 192 { "OUT1", NULL, "AIFIN" }, 193 { "OUT2", NULL, "AIFIN" }, 194 }; 195 196 static const struct snd_soc_component_driver soc_component_ntp8918 = { 197 .probe = ntp8918_probe, 198 .suspend = ntp8918_snd_suspend, 199 .resume = ntp8918_snd_resume, 200 .dapm_widgets = ntp8918_dapm_widgets, 201 .num_dapm_widgets = ARRAY_SIZE(ntp8918_dapm_widgets), 202 .dapm_routes = ntp8918_dapm_routes, 203 .num_dapm_routes = ARRAY_SIZE(ntp8918_dapm_routes), 204 }; 205 206 static int ntp8918_hw_params(struct snd_pcm_substream *substream, 207 struct snd_pcm_hw_params *params, 208 struct snd_soc_dai *dai) 209 { 210 struct snd_soc_component *component = dai->component; 211 struct ntp8918_priv *ntp8918 = snd_soc_component_get_drvdata(component); 212 unsigned int input_fmt = 0; 213 unsigned int gsa_fmt = 0; 214 unsigned int gsa_fmt_mask; 215 unsigned int mcf; 216 int bclk; 217 int ret; 218 219 bclk = snd_soc_params_to_bclk(params); 220 switch (bclk) { 221 case 3072000: 222 case 2822400: 223 mcf = 0; 224 break; 225 case 6144000: 226 mcf = 1; 227 break; 228 case 2048000: 229 mcf = 2; 230 break; 231 default: 232 return -EINVAL; 233 } 234 235 ret = snd_soc_component_update_bits(component, NTP8918_MCLK_FREQ_CTRL, 236 NTP8918_MCLK_FREQ_MCF, mcf); 237 if (ret) 238 return ret; 239 240 switch (ntp8918->format) { 241 case SND_SOC_DAIFMT_I2S: 242 break; 243 case SND_SOC_DAIFMT_RIGHT_J: 244 input_fmt |= NTP8918_INPUT_FMT_GSA_MODE; 245 gsa_fmt |= NTP8918_GSA_RIGHT_J; 246 break; 247 case SND_SOC_DAIFMT_LEFT_J: 248 input_fmt |= NTP8918_INPUT_FMT_GSA_MODE; 249 break; 250 } 251 252 ret = snd_soc_component_update_bits(component, NTP8918_INPUT_FMT, 253 NTP8918_INPUT_FMT_MASTER_MODE | 254 NTP8918_INPUT_FMT_GSA_MODE, 255 input_fmt); 256 257 if (!(input_fmt & NTP8918_INPUT_FMT_GSA_MODE) || ret < 0) 258 return ret; 259 260 switch (params_width(params)) { 261 case 24: 262 gsa_fmt |= NTP8918_GSA_BS(0); 263 break; 264 case 20: 265 gsa_fmt |= NTP8918_GSA_BS(1); 266 break; 267 case 18: 268 gsa_fmt |= NTP8918_GSA_BS(2); 269 break; 270 case 16: 271 gsa_fmt |= NTP8918_GSA_BS(3); 272 break; 273 default: 274 return -EINVAL; 275 } 276 277 gsa_fmt_mask = NTP8918_GSA_BS_MASK | 278 NTP8918_GSA_RIGHT_J | 279 NTP8918_GSA_LSB; 280 return snd_soc_component_update_bits(component, NTP8918_GSA_FMT, 281 gsa_fmt_mask, gsa_fmt); 282 } 283 284 static int ntp8918_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 285 { 286 struct snd_soc_component *component = dai->component; 287 struct ntp8918_priv *ntp8918 = snd_soc_component_get_drvdata(component); 288 289 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 290 case SND_SOC_DAIFMT_I2S: 291 case SND_SOC_DAIFMT_RIGHT_J: 292 case SND_SOC_DAIFMT_LEFT_J: 293 ntp8918->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 294 break; 295 default: 296 return -EINVAL; 297 } 298 return 0; 299 } 300 301 static int ntp8918_digital_mute(struct snd_soc_dai *dai, int mute, int stream) 302 { 303 unsigned int mute_mask = NTP8918_SOFT_MUTE_SM1 | 304 NTP8918_SOFT_MUTE_SM2; 305 306 return snd_soc_component_update_bits(dai->component, NTP8918_SOFT_MUTE, 307 mute_mask, mute ? mute_mask : 0); 308 } 309 310 static const struct snd_soc_dai_ops ntp8918_dai_ops = { 311 .hw_params = ntp8918_hw_params, 312 .set_fmt = ntp8918_set_fmt, 313 .mute_stream = ntp8918_digital_mute, 314 }; 315 316 static struct snd_soc_dai_driver ntp8918_dai = { 317 .name = "ntp8918-amplifier", 318 .playback = { 319 .stream_name = "Playback", 320 .channels_min = 1, 321 .channels_max = 2, 322 .rates = NTP8918_RATES, 323 .formats = NTP8918_FORMATS, 324 }, 325 .ops = &ntp8918_dai_ops, 326 }; 327 328 static const struct regmap_config ntp8918_regmap = { 329 .reg_bits = 8, 330 .val_bits = 8, 331 .max_register = REG_MAX, 332 .cache_type = REGCACHE_MAPLE, 333 }; 334 335 static int ntp8918_i2c_probe(struct i2c_client *i2c) 336 { 337 struct ntp8918_priv *ntp8918; 338 int ret; 339 struct regmap *regmap; 340 341 ntp8918 = devm_kzalloc(&i2c->dev, sizeof(*ntp8918), GFP_KERNEL); 342 if (!ntp8918) 343 return -ENOMEM; 344 345 ntp8918->i2c = i2c; 346 347 ntp8918->reset = devm_reset_control_get_shared(&i2c->dev, NULL); 348 if (IS_ERR(ntp8918->reset)) 349 return dev_err_probe(&i2c->dev, PTR_ERR(ntp8918->reset), "Failed to get reset\n"); 350 351 dev_set_drvdata(&i2c->dev, ntp8918); 352 353 ntp8918_reset_gpio(ntp8918); 354 355 regmap = devm_regmap_init_i2c(i2c, &ntp8918_regmap); 356 if (IS_ERR(regmap)) 357 return dev_err_probe(&i2c->dev, PTR_ERR(regmap), 358 "Failed to allocate regmap\n"); 359 360 ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_ntp8918, 361 &ntp8918_dai, 1); 362 if (ret) 363 return dev_err_probe(&i2c->dev, ret, 364 "Failed to register component\n"); 365 366 ntp8918->bck = devm_clk_get_enabled(&i2c->dev, "bck"); 367 if (IS_ERR(ntp8918->bck)) 368 return dev_err_probe(&i2c->dev, PTR_ERR(ntp8918->bck), "failed to get bck clock\n"); 369 370 return 0; 371 } 372 373 static const struct i2c_device_id ntp8918_i2c_id[] = { 374 { "ntp8918", 0 }, 375 {} 376 }; 377 MODULE_DEVICE_TABLE(i2c, ntp8918_i2c_id); 378 379 static const struct of_device_id ntp8918_of_match[] = { 380 {.compatible = "neofidelity,ntp8918"}, 381 {} 382 }; 383 MODULE_DEVICE_TABLE(of, ntp8918_of_match); 384 385 static struct i2c_driver ntp8918_i2c_driver = { 386 .probe = ntp8918_i2c_probe, 387 .id_table = ntp8918_i2c_id, 388 .driver = { 389 .name = "ntp8918", 390 .of_match_table = ntp8918_of_match, 391 }, 392 }; 393 module_i2c_driver(ntp8918_i2c_driver); 394 395 MODULE_AUTHOR("Igor Prusov <ivprusov@salutedevices.com>"); 396 MODULE_DESCRIPTION("NTP8918 Audio Amplifier Driver"); 397 MODULE_LICENSE("GPL"); 398