tfa989x.c (11886B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2021 Stephan Gerhold 4 * 5 * Register definitions/sequences taken from various tfa98xx kernel drivers: 6 * Copyright (C) 2014-2020 NXP Semiconductors, All Rights Reserved. 7 * Copyright (C) 2013 Sony Mobile Communications Inc. 8 */ 9 10#include <linux/gpio/consumer.h> 11#include <linux/i2c.h> 12#include <linux/module.h> 13#include <linux/regmap.h> 14#include <linux/regulator/consumer.h> 15#include <sound/soc.h> 16 17#define TFA989X_STATUSREG 0x00 18#define TFA989X_BATTERYVOLTAGE 0x01 19#define TFA989X_TEMPERATURE 0x02 20#define TFA989X_REVISIONNUMBER 0x03 21#define TFA989X_REVISIONNUMBER_REV_MSK GENMASK(7, 0) /* device revision */ 22#define TFA989X_I2SREG 0x04 23#define TFA989X_I2SREG_RCV 2 /* receiver mode */ 24#define TFA989X_I2SREG_CHSA 6 /* amplifier input select */ 25#define TFA989X_I2SREG_CHSA_MSK GENMASK(7, 6) 26#define TFA989X_I2SREG_I2SSR 12 /* sample rate */ 27#define TFA989X_I2SREG_I2SSR_MSK GENMASK(15, 12) 28#define TFA989X_BAT_PROT 0x05 29#define TFA989X_AUDIO_CTR 0x06 30#define TFA989X_DCDCBOOST 0x07 31#define TFA989X_SPKR_CALIBRATION 0x08 32#define TFA989X_SYS_CTRL 0x09 33#define TFA989X_SYS_CTRL_PWDN 0 /* power down */ 34#define TFA989X_SYS_CTRL_I2CR 1 /* I2C reset */ 35#define TFA989X_SYS_CTRL_CFE 2 /* enable CoolFlux DSP */ 36#define TFA989X_SYS_CTRL_AMPE 3 /* enable amplifier */ 37#define TFA989X_SYS_CTRL_DCA 4 /* enable boost */ 38#define TFA989X_SYS_CTRL_SBSL 5 /* DSP configured */ 39#define TFA989X_SYS_CTRL_AMPC 6 /* amplifier enabled by DSP */ 40#define TFA989X_I2S_SEL_REG 0x0a 41#define TFA989X_I2S_SEL_REG_SPKR_MSK GENMASK(10, 9) /* speaker impedance */ 42#define TFA989X_I2S_SEL_REG_DCFG_MSK GENMASK(14, 11) /* DCDC compensation */ 43#define TFA989X_PWM_CONTROL 0x41 44#define TFA989X_CURRENTSENSE1 0x46 45#define TFA989X_CURRENTSENSE2 0x47 46#define TFA989X_CURRENTSENSE3 0x48 47#define TFA989X_CURRENTSENSE4 0x49 48 49#define TFA9895_REVISION 0x12 50#define TFA9897_REVISION 0x97 51 52struct tfa989x_rev { 53 unsigned int rev; 54 int (*init)(struct regmap *regmap); 55}; 56 57struct tfa989x { 58 const struct tfa989x_rev *rev; 59 struct regulator *vddd_supply; 60 struct gpio_desc *rcv_gpiod; 61}; 62 63static bool tfa989x_writeable_reg(struct device *dev, unsigned int reg) 64{ 65 return reg > TFA989X_REVISIONNUMBER; 66} 67 68static bool tfa989x_volatile_reg(struct device *dev, unsigned int reg) 69{ 70 return reg < TFA989X_REVISIONNUMBER; 71} 72 73static const struct regmap_config tfa989x_regmap = { 74 .reg_bits = 8, 75 .val_bits = 16, 76 77 .writeable_reg = tfa989x_writeable_reg, 78 .volatile_reg = tfa989x_volatile_reg, 79 .cache_type = REGCACHE_RBTREE, 80}; 81 82static const char * const chsa_text[] = { "Left", "Right", /* "DSP" */ }; 83static SOC_ENUM_SINGLE_DECL(chsa_enum, TFA989X_I2SREG, TFA989X_I2SREG_CHSA, chsa_text); 84static const struct snd_kcontrol_new chsa_mux = SOC_DAPM_ENUM("Amp Input", chsa_enum); 85 86static const struct snd_soc_dapm_widget tfa989x_dapm_widgets[] = { 87 SND_SOC_DAPM_OUTPUT("OUT"), 88 SND_SOC_DAPM_SUPPLY("POWER", TFA989X_SYS_CTRL, TFA989X_SYS_CTRL_PWDN, 1, NULL, 0), 89 SND_SOC_DAPM_OUT_DRV("AMPE", TFA989X_SYS_CTRL, TFA989X_SYS_CTRL_AMPE, 0, NULL, 0), 90 91 SND_SOC_DAPM_MUX("Amp Input", SND_SOC_NOPM, 0, 0, &chsa_mux), 92 SND_SOC_DAPM_AIF_IN("AIFINL", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0), 93 SND_SOC_DAPM_AIF_IN("AIFINR", "HiFi Playback", 1, SND_SOC_NOPM, 0, 0), 94}; 95 96static const struct snd_soc_dapm_route tfa989x_dapm_routes[] = { 97 {"OUT", NULL, "AMPE"}, 98 {"AMPE", NULL, "POWER"}, 99 {"AMPE", NULL, "Amp Input"}, 100 {"Amp Input", "Left", "AIFINL"}, 101 {"Amp Input", "Right", "AIFINR"}, 102}; 103 104static int tfa989x_put_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 105{ 106 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 107 struct tfa989x *tfa989x = snd_soc_component_get_drvdata(component); 108 109 gpiod_set_value_cansleep(tfa989x->rcv_gpiod, ucontrol->value.enumerated.item[0]); 110 111 return snd_soc_put_enum_double(kcontrol, ucontrol); 112} 113 114static const char * const mode_text[] = { "Speaker", "Receiver" }; 115static SOC_ENUM_SINGLE_DECL(mode_enum, TFA989X_I2SREG, TFA989X_I2SREG_RCV, mode_text); 116static const struct snd_kcontrol_new tfa989x_mode_controls[] = { 117 SOC_ENUM_EXT("Mode", mode_enum, snd_soc_get_enum_double, tfa989x_put_mode), 118}; 119 120static int tfa989x_probe(struct snd_soc_component *component) 121{ 122 struct tfa989x *tfa989x = snd_soc_component_get_drvdata(component); 123 124 if (tfa989x->rev->rev == TFA9897_REVISION) 125 return snd_soc_add_component_controls(component, tfa989x_mode_controls, 126 ARRAY_SIZE(tfa989x_mode_controls)); 127 128 return 0; 129} 130 131static const struct snd_soc_component_driver tfa989x_component = { 132 .probe = tfa989x_probe, 133 .dapm_widgets = tfa989x_dapm_widgets, 134 .num_dapm_widgets = ARRAY_SIZE(tfa989x_dapm_widgets), 135 .dapm_routes = tfa989x_dapm_routes, 136 .num_dapm_routes = ARRAY_SIZE(tfa989x_dapm_routes), 137 .use_pmdown_time = 1, 138 .endianness = 1, 139 .non_legacy_dai_naming = 1, 140}; 141 142static const unsigned int tfa989x_rates[] = { 143 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 144}; 145 146static int tfa989x_find_sample_rate(unsigned int rate) 147{ 148 int i; 149 150 for (i = 0; i < ARRAY_SIZE(tfa989x_rates); ++i) 151 if (tfa989x_rates[i] == rate) 152 return i; 153 154 return -EINVAL; 155} 156 157static int tfa989x_hw_params(struct snd_pcm_substream *substream, 158 struct snd_pcm_hw_params *params, 159 struct snd_soc_dai *dai) 160{ 161 struct snd_soc_component *component = dai->component; 162 int sr; 163 164 sr = tfa989x_find_sample_rate(params_rate(params)); 165 if (sr < 0) 166 return sr; 167 168 return snd_soc_component_update_bits(component, TFA989X_I2SREG, 169 TFA989X_I2SREG_I2SSR_MSK, 170 sr << TFA989X_I2SREG_I2SSR); 171} 172 173static const struct snd_soc_dai_ops tfa989x_dai_ops = { 174 .hw_params = tfa989x_hw_params, 175}; 176 177static struct snd_soc_dai_driver tfa989x_dai = { 178 .name = "tfa989x-hifi", 179 .playback = { 180 .stream_name = "HiFi Playback", 181 .formats = SNDRV_PCM_FMTBIT_S16_LE, 182 .rates = SNDRV_PCM_RATE_8000_48000, 183 .rate_min = 8000, 184 .rate_max = 48000, 185 .channels_min = 1, 186 .channels_max = 2, 187 }, 188 .ops = &tfa989x_dai_ops, 189}; 190 191static const struct reg_sequence tfa9895_reg_init[] = { 192 /* some other registers must be set for optimal amplifier behaviour */ 193 { TFA989X_BAT_PROT, 0x13ab }, 194 { TFA989X_AUDIO_CTR, 0x001f }, 195 196 /* peak voltage protection is always on, but may be written */ 197 { TFA989X_SPKR_CALIBRATION, 0x3c4e }, 198 199 /* TFA989X_SYSCTRL_DCA = 0 */ 200 { TFA989X_SYS_CTRL, 0x024d }, 201 { TFA989X_PWM_CONTROL, 0x0308 }, 202 { TFA989X_CURRENTSENSE4, 0x0e82 }, 203}; 204 205static int tfa9895_init(struct regmap *regmap) 206{ 207 return regmap_multi_reg_write(regmap, tfa9895_reg_init, 208 ARRAY_SIZE(tfa9895_reg_init)); 209} 210 211static const struct tfa989x_rev tfa9895_rev = { 212 .rev = TFA9895_REVISION, 213 .init = tfa9895_init, 214}; 215 216static int tfa9897_init(struct regmap *regmap) 217{ 218 int ret; 219 220 /* Reduce slewrate by clearing iddqtestbst to avoid booster damage */ 221 ret = regmap_write(regmap, TFA989X_CURRENTSENSE3, 0x0300); 222 if (ret) 223 return ret; 224 225 /* Enable clipping */ 226 ret = regmap_clear_bits(regmap, TFA989X_CURRENTSENSE4, 0x1); 227 if (ret) 228 return ret; 229 230 /* Set required TDM configuration */ 231 return regmap_write(regmap, 0x14, 0x0); 232} 233 234static const struct tfa989x_rev tfa9897_rev = { 235 .rev = TFA9897_REVISION, 236 .init = tfa9897_init, 237}; 238 239/* 240 * Note: At the moment this driver bypasses the "CoolFlux DSP" built into the 241 * TFA989X amplifiers. Unfortunately, there seems to be absolutely 242 * no documentation for it - the public "short datasheets" do not provide 243 * any information about the DSP or available registers. 244 * 245 * Usually the TFA989X amplifiers are configured through proprietary userspace 246 * libraries. There are also some (rather complex) kernel drivers but even those 247 * rely on obscure firmware blobs for configuration (so-called "containers"). 248 * They seem to contain different "profiles" with tuned speaker settings, sample 249 * rates and volume steps (which would be better exposed as separate ALSA mixers). 250 * 251 * Bypassing the DSP disables volume control (and perhaps some speaker 252 * optimization?), but at least allows using the speaker without obscure 253 * kernel drivers and firmware. 254 * 255 * Ideally NXP (or now Goodix) should release proper documentation for these 256 * amplifiers so that support for the "CoolFlux DSP" can be implemented properly. 257 */ 258static int tfa989x_dsp_bypass(struct regmap *regmap) 259{ 260 int ret; 261 262 /* Clear CHSA to bypass DSP and take input from I2S 1 left channel */ 263 ret = regmap_clear_bits(regmap, TFA989X_I2SREG, TFA989X_I2SREG_CHSA_MSK); 264 if (ret) 265 return ret; 266 267 /* Set DCDC compensation to off and speaker impedance to 8 ohm */ 268 ret = regmap_update_bits(regmap, TFA989X_I2S_SEL_REG, 269 TFA989X_I2S_SEL_REG_DCFG_MSK | 270 TFA989X_I2S_SEL_REG_SPKR_MSK, 271 TFA989X_I2S_SEL_REG_SPKR_MSK); 272 if (ret) 273 return ret; 274 275 /* Set DCDC to follower mode and disable CoolFlux DSP */ 276 return regmap_clear_bits(regmap, TFA989X_SYS_CTRL, 277 BIT(TFA989X_SYS_CTRL_DCA) | 278 BIT(TFA989X_SYS_CTRL_CFE) | 279 BIT(TFA989X_SYS_CTRL_AMPC)); 280} 281 282static void tfa989x_regulator_disable(void *data) 283{ 284 struct tfa989x *tfa989x = data; 285 286 regulator_disable(tfa989x->vddd_supply); 287} 288 289static int tfa989x_i2c_probe(struct i2c_client *i2c) 290{ 291 struct device *dev = &i2c->dev; 292 const struct tfa989x_rev *rev; 293 struct tfa989x *tfa989x; 294 struct regmap *regmap; 295 unsigned int val; 296 int ret; 297 298 rev = device_get_match_data(dev); 299 if (!rev) { 300 dev_err(dev, "unknown device revision\n"); 301 return -ENODEV; 302 } 303 304 tfa989x = devm_kzalloc(dev, sizeof(*tfa989x), GFP_KERNEL); 305 if (!tfa989x) 306 return -ENOMEM; 307 308 tfa989x->rev = rev; 309 i2c_set_clientdata(i2c, tfa989x); 310 311 tfa989x->vddd_supply = devm_regulator_get(dev, "vddd"); 312 if (IS_ERR(tfa989x->vddd_supply)) 313 return dev_err_probe(dev, PTR_ERR(tfa989x->vddd_supply), 314 "Failed to get vddd regulator\n"); 315 316 if (tfa989x->rev->rev == TFA9897_REVISION) { 317 tfa989x->rcv_gpiod = devm_gpiod_get_optional(dev, "rcv", GPIOD_OUT_LOW); 318 if (IS_ERR(tfa989x->rcv_gpiod)) 319 return PTR_ERR(tfa989x->rcv_gpiod); 320 } 321 322 regmap = devm_regmap_init_i2c(i2c, &tfa989x_regmap); 323 if (IS_ERR(regmap)) 324 return PTR_ERR(regmap); 325 326 ret = regulator_enable(tfa989x->vddd_supply); 327 if (ret) { 328 dev_err(dev, "Failed to enable vddd regulator: %d\n", ret); 329 return ret; 330 } 331 332 ret = devm_add_action_or_reset(dev, tfa989x_regulator_disable, tfa989x); 333 if (ret) 334 return ret; 335 336 /* Bypass regcache for reset and init sequence */ 337 regcache_cache_bypass(regmap, true); 338 339 /* Dummy read to generate i2c clocks, required on some devices */ 340 regmap_read(regmap, TFA989X_REVISIONNUMBER, &val); 341 342 ret = regmap_read(regmap, TFA989X_REVISIONNUMBER, &val); 343 if (ret) { 344 dev_err(dev, "failed to read revision number: %d\n", ret); 345 return ret; 346 } 347 348 val &= TFA989X_REVISIONNUMBER_REV_MSK; 349 if (val != rev->rev) { 350 dev_err(dev, "invalid revision number, expected %#x, got %#x\n", 351 rev->rev, val); 352 return -ENODEV; 353 } 354 355 ret = regmap_write(regmap, TFA989X_SYS_CTRL, BIT(TFA989X_SYS_CTRL_I2CR)); 356 if (ret) { 357 dev_err(dev, "failed to reset I2C registers: %d\n", ret); 358 return ret; 359 } 360 361 ret = rev->init(regmap); 362 if (ret) { 363 dev_err(dev, "failed to initialize registers: %d\n", ret); 364 return ret; 365 } 366 367 ret = tfa989x_dsp_bypass(regmap); 368 if (ret) { 369 dev_err(dev, "failed to enable DSP bypass: %d\n", ret); 370 return ret; 371 } 372 regcache_cache_bypass(regmap, false); 373 374 return devm_snd_soc_register_component(dev, &tfa989x_component, 375 &tfa989x_dai, 1); 376} 377 378static const struct of_device_id tfa989x_of_match[] = { 379 { .compatible = "nxp,tfa9895", .data = &tfa9895_rev }, 380 { .compatible = "nxp,tfa9897", .data = &tfa9897_rev }, 381 { } 382}; 383MODULE_DEVICE_TABLE(of, tfa989x_of_match); 384 385static struct i2c_driver tfa989x_i2c_driver = { 386 .driver = { 387 .name = "tfa989x", 388 .of_match_table = tfa989x_of_match, 389 }, 390 .probe_new = tfa989x_i2c_probe, 391}; 392module_i2c_driver(tfa989x_i2c_driver); 393 394MODULE_DESCRIPTION("ASoC NXP/Goodix TFA989X (TFA1) driver"); 395MODULE_AUTHOR("Stephan Gerhold <stephan@gerhold.net>"); 396MODULE_LICENSE("GPL");