FILE
rt9123.c
File preview with syntax highlighting.
linux-6.19.14/sound/soc/codecs/rt9123.c
1// SPDX-License-Identifier: GPL-2.0-only 2// 3// rt9123.c -- RT9123 (SW I2C Mode) ALSA SoC Codec driver 4// 5// Author: ChiYuan Huang <cy_huang@richtek.com> 6 7#include <linux/acpi.h> 8#include <linux/bitfield.h> 9#include <linux/bits.h> 10#include <linux/byteorder/generic.h> 11#include <linux/delay.h> 12#include <linux/err.h> 13#include <linux/gpio/consumer.h> 14#include <linux/i2c.h> 15#include <linux/kernel.h> 16#include <linux/mod_devicetable.h> 17#include <linux/module.h> 18#include <linux/of.h> 19#include <linux/pm_runtime.h> 20#include <linux/property.h> 21#include <linux/regmap.h> 22#include <sound/pcm.h> 23#include <sound/pcm_params.h> 24#include <sound/soc.h> 25#include <sound/soc-dai.h> 26#include <sound/soc-dapm.h> 27#include <sound/tlv.h> 28 29#define RT9123_REG_AMPCTRL 0x01 30#define RT9123_REG_I2SOPT 0x02 31#define RT9123_REG_TDMRX 0x03 32#define RT9123_REG_SILVOLEN 0x04 33#define RT9123_REG_VOLGAIN 0x12 34#define RT9123_REG_ANAFLAG 0x36 35#define RT9123_REG_COMBOID 0xF7 36 37#define RT9123_MASK_SWRST BIT(15) 38#define RT9123_MASK_SWMUTE BIT(14) 39#define RT9123_MASK_AMPON BIT(12) 40#define RT9123_MASK_AUDBIT GENMASK(14, 12) 41#define RT9123_MASK_AUDFMT GENMASK(11, 8) 42#define RT9123_MASK_TDMRXLOC GENMASK(4, 0) 43#define RT9123_MASK_VENID GENMASK(15, 4) 44 45#define RT9123_FIXED_VENID 0x340 46 47struct rt9123_priv { 48 struct gpio_desc *enable; 49 unsigned int dai_fmt; 50 int tdm_slots; 51 int tdm_slot_width; 52}; 53 54static int rt9123_enable_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 55 int event) 56{ 57 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 58 struct device *dev = comp->dev; 59 unsigned int enable; 60 int ret; 61 62 switch (event) { 63 case SND_SOC_DAPM_POST_PMU: 64 enable = 1; 65 break; 66 case SND_SOC_DAPM_POST_PMD: 67 enable = 0; 68 break; 69 default: 70 return -EINVAL; 71 } 72 73 ret = pm_runtime_resume_and_get(dev); 74 if (ret) 75 return ret; 76 77 /* AMPON bit is located in volatile RG, use pm_runtime to guarantee the RG access */ 78 snd_soc_component_write_field(comp, RT9123_REG_AMPCTRL, RT9123_MASK_AMPON, enable); 79 80 pm_runtime_put_autosuspend(dev); 81 82 return 0; 83} 84 85static const struct snd_soc_dapm_widget rt9123_dapm_widgets[] = { 86 SND_SOC_DAPM_OUTPUT("SPK"), 87 SND_SOC_DAPM_OUT_DRV_E("Amp Drv", SND_SOC_NOPM, 0, 0, NULL, 0, rt9123_enable_event, 88 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 89}; 90 91static const struct snd_soc_dapm_route rt9123_dapm_routes[] = { 92 { "Amp Drv", NULL, "HiFi Playback" }, 93 { "SPK", NULL, "Amp Drv" }, 94}; 95 96static const DECLARE_TLV_DB_SCALE(dig_tlv, -10375, 25, 0); 97static const DECLARE_TLV_DB_RANGE(ana_tlv, 98 0, 0, TLV_DB_SCALE_ITEM(-1200, 0, 0), 99 1, 9, TLV_DB_SCALE_ITEM(0, 150, 0), 100 10, 10, TLV_DB_SCALE_ITEM(1400, 0, 0)); 101static const char * const pwmfreq_text[] = { "300KHz", "325KHz", "350KHz", "375KHz" }; 102static const struct soc_enum rt9123_pwm_freq_enum = 103 SOC_ENUM_SINGLE(RT9123_REG_AMPCTRL, 4, ARRAY_SIZE(pwmfreq_text), pwmfreq_text); 104static const char * const i2sch_text[] = { "(L+R)/2", "LCH", "RCH", "(L+R)/2" }; 105static const struct soc_enum rt9123_i2sch_select_enum = 106 SOC_ENUM_SINGLE(RT9123_REG_I2SOPT, 4, ARRAY_SIZE(i2sch_text), i2sch_text); 107 108static int rt9123_kcontrol_name_comp(struct snd_kcontrol *kcontrol, const char *s) 109{ 110 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 111 const char *kctlname = kcontrol->id.name; 112 113 if (comp && comp->name_prefix) 114 kctlname += strlen(comp->name_prefix) + 1; 115 116 return strcmp(kctlname, s); 117} 118 119static int rt9123_xhandler_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 120{ 121 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 122 struct device *dev = comp->dev; 123 int ret; 124 125 ret = pm_runtime_resume_and_get(dev); 126 if (ret) 127 return ret; 128 129 /* 130 * Since the RG bitfield for 'Speaker Volume' and 'PWM Frequency Select' are located in 131 * volatile RG address, special handling here with pm runtime API to guarantee RG read 132 * operation. 133 */ 134 if (rt9123_kcontrol_name_comp(kcontrol, "Speaker Volume") == 0) 135 ret = snd_soc_get_volsw(kcontrol, ucontrol); 136 else 137 ret = snd_soc_get_enum_double(kcontrol, ucontrol); 138 139 if (ret < 0) 140 dev_err(dev, "Failed to get control (%d)\n", ret); 141 142 pm_runtime_put_autosuspend(dev); 143 return ret; 144} 145 146static int rt9123_xhandler_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 147{ 148 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 149 struct device *dev = comp->dev; 150 int ret; 151 152 ret = pm_runtime_resume_and_get(dev); 153 if (ret) 154 return ret; 155 156 /* 157 * Since the RG bitfield for 'Speaker Volume' and 'PWM Frequency Select' are located in 158 * volatile RG address, special handling here with pm runtime API to guarantee RG write 159 * operation. 160 */ 161 if (rt9123_kcontrol_name_comp(kcontrol, "Speaker Volume") == 0) 162 ret = snd_soc_put_volsw(kcontrol, ucontrol); 163 else 164 ret = snd_soc_put_enum_double(kcontrol, ucontrol); 165 166 if (ret < 0) 167 dev_err(dev, "Failed to put control (%d)\n", ret); 168 169 pm_runtime_put_autosuspend(dev); 170 return ret; 171} 172 173static const struct snd_kcontrol_new rt9123_controls[] = { 174 SOC_SINGLE_TLV("Master Volume", RT9123_REG_VOLGAIN, 2, 511, 1, dig_tlv), 175 SOC_SINGLE_EXT_TLV("Speaker Volume", RT9123_REG_AMPCTRL, 0, 10, 0, rt9123_xhandler_get, 176 rt9123_xhandler_put, ana_tlv), 177 SOC_ENUM_EXT("PWM Frequency Select", rt9123_pwm_freq_enum, rt9123_xhandler_get, 178 rt9123_xhandler_put), 179 SOC_ENUM("I2S CH Select", rt9123_i2sch_select_enum), 180 SOC_SINGLE("Silence Detect Switch", RT9123_REG_SILVOLEN, 14, 1, 0), 181}; 182 183static const struct snd_soc_component_driver rt9123_comp_driver = { 184 .controls = rt9123_controls, 185 .num_controls = ARRAY_SIZE(rt9123_controls), 186 .dapm_widgets = rt9123_dapm_widgets, 187 .num_dapm_widgets = ARRAY_SIZE(rt9123_dapm_widgets), 188 .dapm_routes = rt9123_dapm_routes, 189 .num_dapm_routes = ARRAY_SIZE(rt9123_dapm_routes), 190 .use_pmdown_time = 1, 191 .endianness = 1, 192}; 193 194static int rt9123_dai_set_format(struct snd_soc_dai *dai, unsigned int fmt) 195{ 196 struct rt9123_priv *rt9123 = snd_soc_dai_get_drvdata(dai); 197 198 rt9123->dai_fmt = fmt; 199 return 0; 200} 201 202static int rt9123_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 203 unsigned int rx_mask, int slots, int slot_width) 204{ 205 struct rt9123_priv *rt9123 = snd_soc_dai_get_drvdata(dai); 206 struct snd_soc_component *comp = dai->component; 207 struct device *dev = dai->dev; 208 unsigned int rx_loc; 209 210 dev_dbg(dev, "(slots, slot_width) = (%d, %d), (txmask, rxmask) = 0x%x, 0x%x\n", slots, 211 slot_width, tx_mask, rx_mask); 212 213 if (slots <= 0 || slot_width <= 0 || slots % 2 || slot_width % 8 || 214 slots * slot_width > 256) { 215 dev_err(dev, "Invalid slot parameter (%d, %d)\n", slots, slot_width); 216 return -EINVAL; 217 } 218 219 if (!rx_mask || hweight_long(rx_mask) > 1 || ffs(rx_mask) > slots) { 220 dev_err(dev, "Invalid rx_mask 0x%08x, slots = %d\n", rx_mask, slots); 221 return -EINVAL; 222 } 223 224 /* Configure rx channel data location */ 225 rx_loc = (ffs(rx_mask) - 1) * slot_width / 8; 226 snd_soc_component_write_field(comp, RT9123_REG_TDMRX, RT9123_MASK_TDMRXLOC, rx_loc); 227 228 rt9123->tdm_slots = slots; 229 rt9123->tdm_slot_width = slot_width; 230 231 return 0; 232} 233 234static int rt9123_dai_hw_params(struct snd_pcm_substream *substream, 235 struct snd_pcm_hw_params *param, struct snd_soc_dai *dai) 236{ 237 struct rt9123_priv *rt9123 = snd_soc_dai_get_drvdata(dai); 238 struct snd_soc_component *comp = dai->component; 239 unsigned int fmtval, width, slot_width; 240 struct device *dev = dai->dev; 241 unsigned int audfmt, audbit; 242 243 fmtval = FIELD_GET(SND_SOC_DAIFMT_FORMAT_MASK, rt9123->dai_fmt); 244 if (rt9123->tdm_slots && fmtval != SND_SOC_DAIFMT_DSP_A && fmtval != SND_SOC_DAIFMT_DSP_B) { 245 dev_err(dev, "TDM only can support DSP_A or DSP_B format\n"); 246 return -EINVAL; 247 } 248 249 switch (fmtval) { 250 case SND_SOC_DAIFMT_I2S: 251 audfmt = 0; 252 break; 253 case SND_SOC_DAIFMT_LEFT_J: 254 audfmt = 1; 255 break; 256 case SND_SOC_DAIFMT_RIGHT_J: 257 audfmt = 2; 258 break; 259 case SND_SOC_DAIFMT_DSP_B: 260 audfmt = rt9123->tdm_slots ? 4 : 3; 261 break; 262 case SND_SOC_DAIFMT_DSP_A: 263 audfmt = rt9123->tdm_slots ? 12 : 11; 264 break; 265 default: 266 dev_err(dev, "Unsupported format %d\n", fmtval); 267 return -EINVAL; 268 } 269 270 switch (width = params_width(param)) { 271 case 16: 272 audbit = 0; 273 break; 274 case 20: 275 audbit = 1; 276 break; 277 case 24: 278 audbit = 2; 279 break; 280 case 32: 281 audbit = 3; 282 break; 283 case 8: 284 audbit = 4; 285 break; 286 default: 287 dev_err(dev, "Unsupported width %d\n", width); 288 return -EINVAL; 289 } 290 291 slot_width = params_physical_width(param); 292 if (rt9123->tdm_slots && slot_width > rt9123->tdm_slot_width) { 293 dev_err(dev, "Slot width is larger than TDM slot width\n"); 294 return -EINVAL; 295 } 296 297 snd_soc_component_write_field(comp, RT9123_REG_I2SOPT, RT9123_MASK_AUDFMT, audfmt); 298 snd_soc_component_write_field(comp, RT9123_REG_I2SOPT, RT9123_MASK_AUDBIT, audbit); 299 300 return 0; 301} 302 303static const struct snd_soc_dai_ops rt9123_dai_ops = { 304 .set_fmt = rt9123_dai_set_format, 305 .set_tdm_slot = rt9123_dai_set_tdm_slot, 306 .hw_params = rt9123_dai_hw_params, 307}; 308 309static struct snd_soc_dai_driver rt9123_dai_driver = { 310 .name = "HiFi", 311 .playback = { 312 .stream_name = "HiFi Playback", 313 .formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S24 | 314 SNDRV_PCM_FMTBIT_S32, 315 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 316 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_24000 | 317 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 318 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | 319 SNDRV_PCM_RATE_96000, 320 .rate_min = 8000, 321 .rate_max = 96000, 322 .channels_min = 1, 323 .channels_max = 2, 324 }, 325 .ops = &rt9123_dai_ops, 326}; 327 328static bool rt9123_readable_reg(struct device *dev, unsigned int reg) 329{ 330 switch (reg) { 331 case 0x00 ... 0x05: 332 case 0x12 ... 0x13: 333 case 0x20 ... 0x21: 334 case 0x36: 335 return true; 336 default: 337 return false; 338 } 339} 340 341static bool rt9123_writeable_reg(struct device *dev, unsigned int reg) 342{ 343 switch (reg) { 344 case 0x01 ... 0x05: 345 case 0x12 ... 0x13: 346 case 0x20 ... 0x21: 347 return true; 348 default: 349 return false; 350 } 351} 352 353static bool rt9123_volatile_reg(struct device *dev, unsigned int reg) 354{ 355 switch (reg) { 356 case 0x01: 357 case 0x20: 358 case 0x36: 359 return true; 360 default: 361 return false; 362 } 363} 364 365static const struct regmap_config rt9123_regmap_config = { 366 .name = "rt9123", 367 .reg_bits = 8, 368 .val_bits = 16, 369 .val_format_endian = REGMAP_ENDIAN_BIG, 370 .readable_reg = rt9123_readable_reg, 371 .writeable_reg = rt9123_writeable_reg, 372 .volatile_reg = rt9123_volatile_reg, 373 .cache_type = REGCACHE_MAPLE, 374 .num_reg_defaults_raw = RT9123_REG_ANAFLAG + 1, 375}; 376 377static int rt9123_i2c_probe(struct i2c_client *i2c) 378{ 379 struct device *dev = &i2c->dev; 380 struct rt9123_priv *rt9123; 381 struct regmap *regmap; 382 __be16 value; 383 u16 venid; 384 int ret; 385 386 rt9123 = devm_kzalloc(dev, sizeof(*rt9123), GFP_KERNEL); 387 if (!rt9123) 388 return -ENOMEM; 389 390 rt9123->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); 391 if (IS_ERR(rt9123->enable)) 392 return PTR_ERR(rt9123->enable); 393 else if (rt9123->enable) 394 usleep_range(250, 350); 395 else 396 dev_dbg(dev, "No 'enable' GPIO specified, treat it as default on\n"); 397 398 /* Check vendor id information */ 399 ret = i2c_smbus_read_i2c_block_data(i2c, RT9123_REG_COMBOID, sizeof(value), (u8 *)&value); 400 if (ret < 0) 401 return dev_err_probe(dev, ret, "Failed to read vendor-id\n"); 402 403 venid = be16_to_cpu(value); 404 if ((venid & RT9123_MASK_VENID) != RT9123_FIXED_VENID) 405 return dev_err_probe(dev, -ENODEV, "Incorrect vendor-id 0x%04x\n", venid); 406 407 /* Trigger RG reset before regmap init cache */ 408 value = cpu_to_be16(RT9123_MASK_SWRST); 409 ret = i2c_smbus_write_i2c_block_data(i2c, RT9123_REG_AMPCTRL, sizeof(value), (u8 *)&value); 410 if (ret) 411 return dev_err_probe(dev, ret, "Failed to trigger RG reset\n"); 412 413 /* Need to wait 10ms for the reset to complete */ 414 usleep_range(10000, 11000); 415 416 regmap = devm_regmap_init_i2c(i2c, &rt9123_regmap_config); 417 if (IS_ERR(regmap)) 418 return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n"); 419 420 i2c_set_clientdata(i2c, rt9123); 421 422 pm_runtime_set_autosuspend_delay(dev, 500); 423 pm_runtime_use_autosuspend(dev); 424 pm_runtime_set_active(dev); 425 ret = devm_pm_runtime_enable(dev); 426 if (ret) 427 return dev_err_probe(dev, ret, "Failed to enable pm runtime\n"); 428 429 return devm_snd_soc_register_component(dev, &rt9123_comp_driver, &rt9123_dai_driver, 1); 430} 431 432#ifdef CONFIG_PM 433static int rt9123_runtime_suspend(struct device *dev) 434{ 435 struct rt9123_priv *rt9123 = dev_get_drvdata(dev); 436 struct regmap *regmap = dev_get_regmap(dev, NULL); 437 438 if (rt9123->enable) { 439 regcache_cache_only(regmap, true); 440 regcache_mark_dirty(regmap); 441 gpiod_set_value(rt9123->enable, 0); 442 } 443 444 return 0; 445} 446 447static int rt9123_runtime_resume(struct device *dev) 448{ 449 struct rt9123_priv *rt9123 = dev_get_drvdata(dev); 450 struct regmap *regmap = dev_get_regmap(dev, NULL); 451 int ret; 452 453 if (rt9123->enable) { 454 gpiod_set_value(rt9123->enable, 1); 455 usleep_range(250, 350); 456 457 regcache_cache_only(regmap, false); 458 ret = regcache_sync(regmap); 459 if (ret) 460 return ret; 461 } 462 463 return 0; 464} 465#endif 466 467static const struct dev_pm_ops rt9123_dev_pm_ops = { 468 SET_RUNTIME_PM_OPS(rt9123_runtime_suspend, rt9123_runtime_resume, NULL) 469}; 470 471#ifdef CONFIG_OF 472static const struct of_device_id rt9123_device_id[] = { 473 { .compatible = "richtek,rt9123" }, 474 {} 475}; 476MODULE_DEVICE_TABLE(of, rt9123_device_id); 477#endif 478 479#ifdef CONFIG_ACPI 480static const struct acpi_device_id rt9123_acpi_match[] = { 481 { "RT9123", 0 }, 482 {} 483}; 484MODULE_DEVICE_TABLE(acpi, rt9123_acpi_match); 485#endif 486 487static struct i2c_driver rt9123_i2c_driver = { 488 .driver = { 489 .name = "rt9123", 490 .of_match_table = of_match_ptr(rt9123_device_id), 491 .acpi_match_table = ACPI_PTR(rt9123_acpi_match), 492 .pm = pm_ptr(&rt9123_dev_pm_ops), 493 }, 494 .probe = rt9123_i2c_probe, 495}; 496module_i2c_driver(rt9123_i2c_driver); 497 498MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 499MODULE_DESCRIPTION("ASoC rt9123 Driver"); 500MODULE_LICENSE("GPL");
~/
Read-only file preview.