twl6040.c (32198B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * ALSA SoC TWL6040 codec driver 4 * 5 * Author: Misael Lopez Cruz <x0052729@ti.com> 6 */ 7 8#include <linux/module.h> 9#include <linux/moduleparam.h> 10#include <linux/init.h> 11#include <linux/delay.h> 12#include <linux/pm.h> 13#include <linux/platform_device.h> 14#include <linux/slab.h> 15#include <linux/mfd/twl6040.h> 16 17#include <sound/core.h> 18#include <sound/pcm.h> 19#include <sound/pcm_params.h> 20#include <sound/soc.h> 21#include <sound/soc-dapm.h> 22#include <sound/initval.h> 23#include <sound/tlv.h> 24 25#include "twl6040.h" 26 27enum twl6040_dai_id { 28 TWL6040_DAI_LEGACY = 0, 29 TWL6040_DAI_UL, 30 TWL6040_DAI_DL1, 31 TWL6040_DAI_DL2, 32 TWL6040_DAI_VIB, 33}; 34 35#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000 36#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 37 38#define TWL6040_OUTHS_0dB 0x00 39#define TWL6040_OUTHS_M30dB 0x0F 40#define TWL6040_OUTHF_0dB 0x03 41#define TWL6040_OUTHF_M52dB 0x1D 42 43#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1) 44 45struct twl6040_jack_data { 46 struct snd_soc_jack *jack; 47 struct delayed_work work; 48 int report; 49}; 50 51/* codec private data */ 52struct twl6040_data { 53 int plug_irq; 54 int codec_powered; 55 int pll; 56 int pll_power_mode; 57 int hs_power_mode; 58 int hs_power_mode_locked; 59 bool dl1_unmuted; 60 bool dl2_unmuted; 61 u8 dl12_cache[TWL6040_REG_HFRCTL - TWL6040_REG_HSLCTL + 1]; 62 unsigned int clk_in; 63 unsigned int sysclk; 64 struct twl6040_jack_data hs_jack; 65 struct snd_soc_component *component; 66 struct mutex mutex; 67}; 68 69/* set of rates for each pll: low-power and high-performance */ 70static const unsigned int lp_rates[] = { 71 8000, 72 11250, 73 16000, 74 22500, 75 32000, 76 44100, 77 48000, 78 88200, 79 96000, 80}; 81 82static const unsigned int hp_rates[] = { 83 8000, 84 16000, 85 32000, 86 48000, 87 96000, 88}; 89 90static const struct snd_pcm_hw_constraint_list sysclk_constraints[] = { 91 { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, }, 92 { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, 93}; 94 95#define to_twl6040(component) dev_get_drvdata((component)->dev->parent) 96 97static unsigned int twl6040_read(struct snd_soc_component *component, unsigned int reg) 98{ 99 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 100 struct twl6040 *twl6040 = to_twl6040(component); 101 u8 value; 102 103 if (reg >= TWL6040_CACHEREGNUM) 104 return -EIO; 105 106 switch (reg) { 107 case TWL6040_REG_HSLCTL: 108 case TWL6040_REG_HSRCTL: 109 case TWL6040_REG_EARCTL: 110 case TWL6040_REG_HFLCTL: 111 case TWL6040_REG_HFRCTL: 112 value = priv->dl12_cache[reg - TWL6040_REG_HSLCTL]; 113 break; 114 default: 115 value = twl6040_reg_read(twl6040, reg); 116 break; 117 } 118 119 return value; 120} 121 122static bool twl6040_can_write_to_chip(struct snd_soc_component *component, 123 unsigned int reg) 124{ 125 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 126 127 switch (reg) { 128 case TWL6040_REG_HSLCTL: 129 case TWL6040_REG_HSRCTL: 130 case TWL6040_REG_EARCTL: 131 /* DL1 path */ 132 return priv->dl1_unmuted; 133 case TWL6040_REG_HFLCTL: 134 case TWL6040_REG_HFRCTL: 135 return priv->dl2_unmuted; 136 default: 137 return true; 138 } 139} 140 141static inline void twl6040_update_dl12_cache(struct snd_soc_component *component, 142 u8 reg, u8 value) 143{ 144 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 145 146 switch (reg) { 147 case TWL6040_REG_HSLCTL: 148 case TWL6040_REG_HSRCTL: 149 case TWL6040_REG_EARCTL: 150 case TWL6040_REG_HFLCTL: 151 case TWL6040_REG_HFRCTL: 152 priv->dl12_cache[reg - TWL6040_REG_HSLCTL] = value; 153 break; 154 default: 155 break; 156 } 157} 158 159static int twl6040_write(struct snd_soc_component *component, 160 unsigned int reg, unsigned int value) 161{ 162 struct twl6040 *twl6040 = to_twl6040(component); 163 164 if (reg >= TWL6040_CACHEREGNUM) 165 return -EIO; 166 167 twl6040_update_dl12_cache(component, reg, value); 168 if (twl6040_can_write_to_chip(component, reg)) 169 return twl6040_reg_write(twl6040, reg, value); 170 else 171 return 0; 172} 173 174static void twl6040_init_chip(struct snd_soc_component *component) 175{ 176 twl6040_read(component, TWL6040_REG_TRIM1); 177 twl6040_read(component, TWL6040_REG_TRIM2); 178 twl6040_read(component, TWL6040_REG_TRIM3); 179 twl6040_read(component, TWL6040_REG_HSOTRIM); 180 twl6040_read(component, TWL6040_REG_HFOTRIM); 181 182 /* Change chip defaults */ 183 /* No imput selected for microphone amplifiers */ 184 twl6040_write(component, TWL6040_REG_MICLCTL, 0x18); 185 twl6040_write(component, TWL6040_REG_MICRCTL, 0x18); 186 187 /* 188 * We need to lower the default gain values, so the ramp code 189 * can work correctly for the first playback. 190 * This reduces the pop noise heard at the first playback. 191 */ 192 twl6040_write(component, TWL6040_REG_HSGAIN, 0xff); 193 twl6040_write(component, TWL6040_REG_EARCTL, 0x1e); 194 twl6040_write(component, TWL6040_REG_HFLGAIN, 0x1d); 195 twl6040_write(component, TWL6040_REG_HFRGAIN, 0x1d); 196 twl6040_write(component, TWL6040_REG_LINEGAIN, 0); 197} 198 199/* set headset dac and driver power mode */ 200static int headset_power_mode(struct snd_soc_component *component, int high_perf) 201{ 202 int hslctl, hsrctl; 203 int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE; 204 205 hslctl = twl6040_read(component, TWL6040_REG_HSLCTL); 206 hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL); 207 208 if (high_perf) { 209 hslctl &= ~mask; 210 hsrctl &= ~mask; 211 } else { 212 hslctl |= mask; 213 hsrctl |= mask; 214 } 215 216 twl6040_write(component, TWL6040_REG_HSLCTL, hslctl); 217 twl6040_write(component, TWL6040_REG_HSRCTL, hsrctl); 218 219 return 0; 220} 221 222static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, 223 struct snd_kcontrol *kcontrol, int event) 224{ 225 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 226 u8 hslctl, hsrctl; 227 228 /* 229 * Workaround for Headset DC offset caused pop noise: 230 * Both HS DAC need to be turned on (before the HS driver) and off at 231 * the same time. 232 */ 233 hslctl = twl6040_read(component, TWL6040_REG_HSLCTL); 234 hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL); 235 if (SND_SOC_DAPM_EVENT_ON(event)) { 236 hslctl |= TWL6040_HSDACENA; 237 hsrctl |= TWL6040_HSDACENA; 238 } else { 239 hslctl &= ~TWL6040_HSDACENA; 240 hsrctl &= ~TWL6040_HSDACENA; 241 } 242 twl6040_write(component, TWL6040_REG_HSLCTL, hslctl); 243 twl6040_write(component, TWL6040_REG_HSRCTL, hsrctl); 244 245 msleep(1); 246 return 0; 247} 248 249static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w, 250 struct snd_kcontrol *kcontrol, int event) 251{ 252 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 253 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 254 int ret = 0; 255 256 if (SND_SOC_DAPM_EVENT_ON(event)) { 257 /* Earphone doesn't support low power mode */ 258 priv->hs_power_mode_locked = 1; 259 ret = headset_power_mode(component, 1); 260 } else { 261 priv->hs_power_mode_locked = 0; 262 ret = headset_power_mode(component, priv->hs_power_mode); 263 } 264 265 msleep(1); 266 267 return ret; 268} 269 270static void twl6040_hs_jack_report(struct snd_soc_component *component, 271 struct snd_soc_jack *jack, int report) 272{ 273 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 274 int status; 275 276 mutex_lock(&priv->mutex); 277 278 /* Sync status */ 279 status = twl6040_read(component, TWL6040_REG_STATUS); 280 if (status & TWL6040_PLUGCOMP) 281 snd_soc_jack_report(jack, report, report); 282 else 283 snd_soc_jack_report(jack, 0, report); 284 285 mutex_unlock(&priv->mutex); 286} 287 288void twl6040_hs_jack_detect(struct snd_soc_component *component, 289 struct snd_soc_jack *jack, int report) 290{ 291 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 292 struct twl6040_jack_data *hs_jack = &priv->hs_jack; 293 294 hs_jack->jack = jack; 295 hs_jack->report = report; 296 297 twl6040_hs_jack_report(component, hs_jack->jack, hs_jack->report); 298} 299EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect); 300 301static void twl6040_accessory_work(struct work_struct *work) 302{ 303 struct twl6040_data *priv = container_of(work, 304 struct twl6040_data, hs_jack.work.work); 305 struct snd_soc_component *component = priv->component; 306 struct twl6040_jack_data *hs_jack = &priv->hs_jack; 307 308 twl6040_hs_jack_report(component, hs_jack->jack, hs_jack->report); 309} 310 311/* audio interrupt handler */ 312static irqreturn_t twl6040_audio_handler(int irq, void *data) 313{ 314 struct snd_soc_component *component = data; 315 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 316 317 queue_delayed_work(system_power_efficient_wq, 318 &priv->hs_jack.work, msecs_to_jiffies(200)); 319 320 return IRQ_HANDLED; 321} 322 323static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol, 324 struct snd_ctl_elem_value *ucontrol) 325{ 326 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); 327 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 328 unsigned int val; 329 330 /* Do not allow changes while Input/FF efect is running */ 331 val = twl6040_read(component, e->reg); 332 if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL)) 333 return -EBUSY; 334 335 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 336} 337 338/* 339 * MICATT volume control: 340 * from -6 to 0 dB in 6 dB steps 341 */ 342static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0); 343 344/* 345 * MICGAIN volume control: 346 * from 6 to 30 dB in 6 dB steps 347 */ 348static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0); 349 350/* 351 * AFMGAIN volume control: 352 * from -18 to 24 dB in 6 dB steps 353 */ 354static DECLARE_TLV_DB_SCALE(afm_amp_tlv, -1800, 600, 0); 355 356/* 357 * HSGAIN volume control: 358 * from -30 to 0 dB in 2 dB steps 359 */ 360static DECLARE_TLV_DB_SCALE(hs_tlv, -3000, 200, 0); 361 362/* 363 * HFGAIN volume control: 364 * from -52 to 6 dB in 2 dB steps 365 */ 366static DECLARE_TLV_DB_SCALE(hf_tlv, -5200, 200, 0); 367 368/* 369 * EPGAIN volume control: 370 * from -24 to 6 dB in 2 dB steps 371 */ 372static DECLARE_TLV_DB_SCALE(ep_tlv, -2400, 200, 0); 373 374/* Left analog microphone selection */ 375static const char *twl6040_amicl_texts[] = 376 {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"}; 377 378/* Right analog microphone selection */ 379static const char *twl6040_amicr_texts[] = 380 {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"}; 381 382static const struct soc_enum twl6040_enum[] = { 383 SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 384 ARRAY_SIZE(twl6040_amicl_texts), twl6040_amicl_texts), 385 SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 386 ARRAY_SIZE(twl6040_amicr_texts), twl6040_amicr_texts), 387}; 388 389static const char *twl6040_hs_texts[] = { 390 "Off", "HS DAC", "Line-In amp" 391}; 392 393static const struct soc_enum twl6040_hs_enum[] = { 394 SOC_ENUM_SINGLE(TWL6040_REG_HSLCTL, 5, ARRAY_SIZE(twl6040_hs_texts), 395 twl6040_hs_texts), 396 SOC_ENUM_SINGLE(TWL6040_REG_HSRCTL, 5, ARRAY_SIZE(twl6040_hs_texts), 397 twl6040_hs_texts), 398}; 399 400static const char *twl6040_hf_texts[] = { 401 "Off", "HF DAC", "Line-In amp" 402}; 403 404static const struct soc_enum twl6040_hf_enum[] = { 405 SOC_ENUM_SINGLE(TWL6040_REG_HFLCTL, 2, ARRAY_SIZE(twl6040_hf_texts), 406 twl6040_hf_texts), 407 SOC_ENUM_SINGLE(TWL6040_REG_HFRCTL, 2, ARRAY_SIZE(twl6040_hf_texts), 408 twl6040_hf_texts), 409}; 410 411static const char *twl6040_vibrapath_texts[] = { 412 "Input FF", "Audio PDM" 413}; 414 415static const struct soc_enum twl6040_vibra_enum[] = { 416 SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLL, 1, 417 ARRAY_SIZE(twl6040_vibrapath_texts), 418 twl6040_vibrapath_texts), 419 SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLR, 1, 420 ARRAY_SIZE(twl6040_vibrapath_texts), 421 twl6040_vibrapath_texts), 422}; 423 424static const struct snd_kcontrol_new amicl_control = 425 SOC_DAPM_ENUM("Route", twl6040_enum[0]); 426 427static const struct snd_kcontrol_new amicr_control = 428 SOC_DAPM_ENUM("Route", twl6040_enum[1]); 429 430/* Headset DAC playback switches */ 431static const struct snd_kcontrol_new hsl_mux_controls = 432 SOC_DAPM_ENUM("Route", twl6040_hs_enum[0]); 433 434static const struct snd_kcontrol_new hsr_mux_controls = 435 SOC_DAPM_ENUM("Route", twl6040_hs_enum[1]); 436 437/* Handsfree DAC playback switches */ 438static const struct snd_kcontrol_new hfl_mux_controls = 439 SOC_DAPM_ENUM("Route", twl6040_hf_enum[0]); 440 441static const struct snd_kcontrol_new hfr_mux_controls = 442 SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]); 443 444static const struct snd_kcontrol_new ep_path_enable_control = 445 SOC_DAPM_SINGLE_VIRT("Switch", 1); 446 447static const struct snd_kcontrol_new auxl_switch_control = 448 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 6, 1, 0); 449 450static const struct snd_kcontrol_new auxr_switch_control = 451 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 6, 1, 0); 452 453/* Vibra playback switches */ 454static const struct snd_kcontrol_new vibral_mux_controls = 455 SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[0], 456 snd_soc_dapm_get_enum_double, 457 twl6040_soc_dapm_put_vibra_enum); 458 459static const struct snd_kcontrol_new vibrar_mux_controls = 460 SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[1], 461 snd_soc_dapm_get_enum_double, 462 twl6040_soc_dapm_put_vibra_enum); 463 464/* Headset power mode */ 465static const char *twl6040_power_mode_texts[] = { 466 "Low-Power", "High-Performance", 467}; 468 469static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum, 470 twl6040_power_mode_texts); 471 472static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, 473 struct snd_ctl_elem_value *ucontrol) 474{ 475 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 476 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 477 478 ucontrol->value.enumerated.item[0] = priv->hs_power_mode; 479 480 return 0; 481} 482 483static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, 484 struct snd_ctl_elem_value *ucontrol) 485{ 486 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 487 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 488 int high_perf = ucontrol->value.enumerated.item[0]; 489 int ret = 0; 490 491 if (!priv->hs_power_mode_locked) 492 ret = headset_power_mode(component, high_perf); 493 494 if (!ret) 495 priv->hs_power_mode = high_perf; 496 497 return ret; 498} 499 500static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, 501 struct snd_ctl_elem_value *ucontrol) 502{ 503 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 504 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 505 506 ucontrol->value.enumerated.item[0] = priv->pll_power_mode; 507 508 return 0; 509} 510 511static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, 512 struct snd_ctl_elem_value *ucontrol) 513{ 514 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 515 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 516 517 priv->pll_power_mode = ucontrol->value.enumerated.item[0]; 518 519 return 0; 520} 521 522int twl6040_get_dl1_gain(struct snd_soc_component *component) 523{ 524 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 525 526 if (snd_soc_dapm_get_pin_status(dapm, "EP")) 527 return -1; /* -1dB */ 528 529 if (snd_soc_dapm_get_pin_status(dapm, "HSOR") || 530 snd_soc_dapm_get_pin_status(dapm, "HSOL")) { 531 532 u8 val = twl6040_read(component, TWL6040_REG_HSLCTL); 533 if (val & TWL6040_HSDACMODE) 534 /* HSDACL in LP mode */ 535 return -8; /* -8dB */ 536 else 537 /* HSDACL in HP mode */ 538 return -1; /* -1dB */ 539 } 540 return 0; /* 0dB */ 541} 542EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain); 543 544int twl6040_get_clk_id(struct snd_soc_component *component) 545{ 546 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 547 548 return priv->pll_power_mode; 549} 550EXPORT_SYMBOL_GPL(twl6040_get_clk_id); 551 552int twl6040_get_trim_value(struct snd_soc_component *component, enum twl6040_trim trim) 553{ 554 if (unlikely(trim >= TWL6040_TRIM_INVAL)) 555 return -EINVAL; 556 557 return twl6040_read(component, TWL6040_REG_TRIM1 + trim); 558} 559EXPORT_SYMBOL_GPL(twl6040_get_trim_value); 560 561int twl6040_get_hs_step_size(struct snd_soc_component *component) 562{ 563 struct twl6040 *twl6040 = to_twl6040(component); 564 565 if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3) 566 /* For ES under ES_1.3 HS step is 2 mV */ 567 return 2; 568 else 569 /* For ES_1.3 HS step is 1 mV */ 570 return 1; 571} 572EXPORT_SYMBOL_GPL(twl6040_get_hs_step_size); 573 574static const struct snd_kcontrol_new twl6040_snd_controls[] = { 575 /* Capture gains */ 576 SOC_DOUBLE_TLV("Capture Preamplifier Volume", 577 TWL6040_REG_MICGAIN, 6, 7, 1, 1, mic_preamp_tlv), 578 SOC_DOUBLE_TLV("Capture Volume", 579 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv), 580 581 /* AFM gains */ 582 SOC_DOUBLE_TLV("Aux FM Volume", 583 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv), 584 585 /* Playback gains */ 586 SOC_DOUBLE_TLV("Headset Playback Volume", 587 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), 588 SOC_DOUBLE_R_TLV("Handsfree Playback Volume", 589 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), 590 SOC_SINGLE_TLV("Earphone Playback Volume", 591 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), 592 593 SOC_ENUM_EXT("Headset Power Mode", twl6040_power_mode_enum, 594 twl6040_headset_power_get_enum, 595 twl6040_headset_power_put_enum), 596 597 /* Left HS PDM data routed to Right HSDAC */ 598 SOC_SINGLE("Headset Mono to Stereo Playback Switch", 599 TWL6040_REG_HSRCTL, 7, 1, 0), 600 601 /* Left HF PDM data routed to Right HFDAC */ 602 SOC_SINGLE("Handsfree Mono to Stereo Playback Switch", 603 TWL6040_REG_HFRCTL, 5, 1, 0), 604 605 SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum, 606 twl6040_pll_get_enum, twl6040_pll_put_enum), 607}; 608 609static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { 610 /* Inputs */ 611 SND_SOC_DAPM_INPUT("MAINMIC"), 612 SND_SOC_DAPM_INPUT("HSMIC"), 613 SND_SOC_DAPM_INPUT("SUBMIC"), 614 SND_SOC_DAPM_INPUT("AFML"), 615 SND_SOC_DAPM_INPUT("AFMR"), 616 617 /* Outputs */ 618 SND_SOC_DAPM_OUTPUT("HSOL"), 619 SND_SOC_DAPM_OUTPUT("HSOR"), 620 SND_SOC_DAPM_OUTPUT("HFL"), 621 SND_SOC_DAPM_OUTPUT("HFR"), 622 SND_SOC_DAPM_OUTPUT("EP"), 623 SND_SOC_DAPM_OUTPUT("AUXL"), 624 SND_SOC_DAPM_OUTPUT("AUXR"), 625 SND_SOC_DAPM_OUTPUT("VIBRAL"), 626 SND_SOC_DAPM_OUTPUT("VIBRAR"), 627 628 /* Analog input muxes for the capture amplifiers */ 629 SND_SOC_DAPM_MUX("Analog Left Capture Route", 630 SND_SOC_NOPM, 0, 0, &amicl_control), 631 SND_SOC_DAPM_MUX("Analog Right Capture Route", 632 SND_SOC_NOPM, 0, 0, &amicr_control), 633 634 /* Analog capture PGAs */ 635 SND_SOC_DAPM_PGA("MicAmpL", 636 TWL6040_REG_MICLCTL, 0, 0, NULL, 0), 637 SND_SOC_DAPM_PGA("MicAmpR", 638 TWL6040_REG_MICRCTL, 0, 0, NULL, 0), 639 640 /* Auxiliary FM PGAs */ 641 SND_SOC_DAPM_PGA("AFMAmpL", 642 TWL6040_REG_MICLCTL, 1, 0, NULL, 0), 643 SND_SOC_DAPM_PGA("AFMAmpR", 644 TWL6040_REG_MICRCTL, 1, 0, NULL, 0), 645 646 /* ADCs */ 647 SND_SOC_DAPM_ADC("ADC Left", NULL, TWL6040_REG_MICLCTL, 2, 0), 648 SND_SOC_DAPM_ADC("ADC Right", NULL, TWL6040_REG_MICRCTL, 2, 0), 649 650 /* Microphone bias */ 651 SND_SOC_DAPM_SUPPLY("Headset Mic Bias", 652 TWL6040_REG_AMICBCTL, 0, 0, NULL, 0), 653 SND_SOC_DAPM_SUPPLY("Main Mic Bias", 654 TWL6040_REG_AMICBCTL, 4, 0, NULL, 0), 655 SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias", 656 TWL6040_REG_DMICBCTL, 0, 0, NULL, 0), 657 SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias", 658 TWL6040_REG_DMICBCTL, 4, 0, NULL, 0), 659 660 /* DACs */ 661 SND_SOC_DAPM_DAC("HSDAC Left", NULL, SND_SOC_NOPM, 0, 0), 662 SND_SOC_DAPM_DAC("HSDAC Right", NULL, SND_SOC_NOPM, 0, 0), 663 SND_SOC_DAPM_DAC("HFDAC Left", NULL, TWL6040_REG_HFLCTL, 0, 0), 664 SND_SOC_DAPM_DAC("HFDAC Right", NULL, TWL6040_REG_HFRCTL, 0, 0), 665 /* Virtual DAC for vibra path (DL4 channel) */ 666 SND_SOC_DAPM_DAC("VIBRA DAC", NULL, SND_SOC_NOPM, 0, 0), 667 668 SND_SOC_DAPM_MUX("Handsfree Left Playback", 669 SND_SOC_NOPM, 0, 0, &hfl_mux_controls), 670 SND_SOC_DAPM_MUX("Handsfree Right Playback", 671 SND_SOC_NOPM, 0, 0, &hfr_mux_controls), 672 /* Analog playback Muxes */ 673 SND_SOC_DAPM_MUX("Headset Left Playback", 674 SND_SOC_NOPM, 0, 0, &hsl_mux_controls), 675 SND_SOC_DAPM_MUX("Headset Right Playback", 676 SND_SOC_NOPM, 0, 0, &hsr_mux_controls), 677 678 SND_SOC_DAPM_MUX("Vibra Left Playback", SND_SOC_NOPM, 0, 0, 679 &vibral_mux_controls), 680 SND_SOC_DAPM_MUX("Vibra Right Playback", SND_SOC_NOPM, 0, 0, 681 &vibrar_mux_controls), 682 683 SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0, 684 &ep_path_enable_control), 685 SND_SOC_DAPM_SWITCH("AUXL Playback", SND_SOC_NOPM, 0, 0, 686 &auxl_switch_control), 687 SND_SOC_DAPM_SWITCH("AUXR Playback", SND_SOC_NOPM, 0, 0, 688 &auxr_switch_control), 689 690 /* Analog playback drivers */ 691 SND_SOC_DAPM_OUT_DRV("HF Left Driver", 692 TWL6040_REG_HFLCTL, 4, 0, NULL, 0), 693 SND_SOC_DAPM_OUT_DRV("HF Right Driver", 694 TWL6040_REG_HFRCTL, 4, 0, NULL, 0), 695 SND_SOC_DAPM_OUT_DRV("HS Left Driver", 696 TWL6040_REG_HSLCTL, 2, 0, NULL, 0), 697 SND_SOC_DAPM_OUT_DRV("HS Right Driver", 698 TWL6040_REG_HSRCTL, 2, 0, NULL, 0), 699 SND_SOC_DAPM_OUT_DRV_E("Earphone Driver", 700 TWL6040_REG_EARCTL, 0, 0, NULL, 0, 701 twl6040_ep_drv_event, 702 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 703 SND_SOC_DAPM_OUT_DRV("Vibra Left Driver", 704 TWL6040_REG_VIBCTLL, 0, 0, NULL, 0), 705 SND_SOC_DAPM_OUT_DRV("Vibra Right Driver", 706 TWL6040_REG_VIBCTLR, 0, 0, NULL, 0), 707 708 SND_SOC_DAPM_SUPPLY("Vibra Left Control", TWL6040_REG_VIBCTLL, 2, 0, 709 NULL, 0), 710 SND_SOC_DAPM_SUPPLY("Vibra Right Control", TWL6040_REG_VIBCTLR, 2, 0, 711 NULL, 0), 712 SND_SOC_DAPM_SUPPLY_S("HSDAC Power", 1, SND_SOC_NOPM, 0, 0, 713 twl6040_hs_dac_event, 714 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 715 716 /* Analog playback PGAs */ 717 SND_SOC_DAPM_PGA("HF Left PGA", 718 TWL6040_REG_HFLCTL, 1, 0, NULL, 0), 719 SND_SOC_DAPM_PGA("HF Right PGA", 720 TWL6040_REG_HFRCTL, 1, 0, NULL, 0), 721 722}; 723 724static const struct snd_soc_dapm_route intercon[] = { 725 /* Stream -> DAC mapping */ 726 {"HSDAC Left", NULL, "Legacy Playback"}, 727 {"HSDAC Left", NULL, "Headset Playback"}, 728 {"HSDAC Right", NULL, "Legacy Playback"}, 729 {"HSDAC Right", NULL, "Headset Playback"}, 730 731 {"HFDAC Left", NULL, "Legacy Playback"}, 732 {"HFDAC Left", NULL, "Handsfree Playback"}, 733 {"HFDAC Right", NULL, "Legacy Playback"}, 734 {"HFDAC Right", NULL, "Handsfree Playback"}, 735 736 {"VIBRA DAC", NULL, "Legacy Playback"}, 737 {"VIBRA DAC", NULL, "Vibra Playback"}, 738 739 /* ADC -> Stream mapping */ 740 {"Legacy Capture" , NULL, "ADC Left"}, 741 {"Capture", NULL, "ADC Left"}, 742 {"Legacy Capture", NULL, "ADC Right"}, 743 {"Capture" , NULL, "ADC Right"}, 744 745 /* Capture path */ 746 {"Analog Left Capture Route", "Headset Mic", "HSMIC"}, 747 {"Analog Left Capture Route", "Main Mic", "MAINMIC"}, 748 {"Analog Left Capture Route", "Aux/FM Left", "AFML"}, 749 750 {"Analog Right Capture Route", "Headset Mic", "HSMIC"}, 751 {"Analog Right Capture Route", "Sub Mic", "SUBMIC"}, 752 {"Analog Right Capture Route", "Aux/FM Right", "AFMR"}, 753 754 {"MicAmpL", NULL, "Analog Left Capture Route"}, 755 {"MicAmpR", NULL, "Analog Right Capture Route"}, 756 757 {"ADC Left", NULL, "MicAmpL"}, 758 {"ADC Right", NULL, "MicAmpR"}, 759 760 /* AFM path */ 761 {"AFMAmpL", NULL, "AFML"}, 762 {"AFMAmpR", NULL, "AFMR"}, 763 764 {"HSDAC Left", NULL, "HSDAC Power"}, 765 {"HSDAC Right", NULL, "HSDAC Power"}, 766 767 {"Headset Left Playback", "HS DAC", "HSDAC Left"}, 768 {"Headset Left Playback", "Line-In amp", "AFMAmpL"}, 769 770 {"Headset Right Playback", "HS DAC", "HSDAC Right"}, 771 {"Headset Right Playback", "Line-In amp", "AFMAmpR"}, 772 773 {"HS Left Driver", NULL, "Headset Left Playback"}, 774 {"HS Right Driver", NULL, "Headset Right Playback"}, 775 776 {"HSOL", NULL, "HS Left Driver"}, 777 {"HSOR", NULL, "HS Right Driver"}, 778 779 /* Earphone playback path */ 780 {"Earphone Playback", "Switch", "HSDAC Left"}, 781 {"Earphone Driver", NULL, "Earphone Playback"}, 782 {"EP", NULL, "Earphone Driver"}, 783 784 {"Handsfree Left Playback", "HF DAC", "HFDAC Left"}, 785 {"Handsfree Left Playback", "Line-In amp", "AFMAmpL"}, 786 787 {"Handsfree Right Playback", "HF DAC", "HFDAC Right"}, 788 {"Handsfree Right Playback", "Line-In amp", "AFMAmpR"}, 789 790 {"HF Left PGA", NULL, "Handsfree Left Playback"}, 791 {"HF Right PGA", NULL, "Handsfree Right Playback"}, 792 793 {"HF Left Driver", NULL, "HF Left PGA"}, 794 {"HF Right Driver", NULL, "HF Right PGA"}, 795 796 {"HFL", NULL, "HF Left Driver"}, 797 {"HFR", NULL, "HF Right Driver"}, 798 799 {"AUXL Playback", "Switch", "HF Left PGA"}, 800 {"AUXR Playback", "Switch", "HF Right PGA"}, 801 802 {"AUXL", NULL, "AUXL Playback"}, 803 {"AUXR", NULL, "AUXR Playback"}, 804 805 /* Vibrator paths */ 806 {"Vibra Left Playback", "Audio PDM", "VIBRA DAC"}, 807 {"Vibra Right Playback", "Audio PDM", "VIBRA DAC"}, 808 809 {"Vibra Left Driver", NULL, "Vibra Left Playback"}, 810 {"Vibra Right Driver", NULL, "Vibra Right Playback"}, 811 {"Vibra Left Driver", NULL, "Vibra Left Control"}, 812 {"Vibra Right Driver", NULL, "Vibra Right Control"}, 813 814 {"VIBRAL", NULL, "Vibra Left Driver"}, 815 {"VIBRAR", NULL, "Vibra Right Driver"}, 816}; 817 818static int twl6040_set_bias_level(struct snd_soc_component *component, 819 enum snd_soc_bias_level level) 820{ 821 struct twl6040 *twl6040 = to_twl6040(component); 822 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 823 int ret = 0; 824 825 switch (level) { 826 case SND_SOC_BIAS_ON: 827 break; 828 case SND_SOC_BIAS_PREPARE: 829 break; 830 case SND_SOC_BIAS_STANDBY: 831 if (priv->codec_powered) { 832 /* Select low power PLL in standby */ 833 ret = twl6040_set_pll(twl6040, TWL6040_SYSCLK_SEL_LPPLL, 834 32768, 19200000); 835 break; 836 } 837 838 ret = twl6040_power(twl6040, 1); 839 if (ret) 840 break; 841 842 priv->codec_powered = 1; 843 844 /* Set external boost GPO */ 845 twl6040_write(component, TWL6040_REG_GPOCTL, 0x02); 846 break; 847 case SND_SOC_BIAS_OFF: 848 if (!priv->codec_powered) 849 break; 850 851 twl6040_power(twl6040, 0); 852 priv->codec_powered = 0; 853 break; 854 } 855 856 return ret; 857} 858 859static int twl6040_startup(struct snd_pcm_substream *substream, 860 struct snd_soc_dai *dai) 861{ 862 struct snd_soc_component *component = dai->component; 863 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 864 865 snd_pcm_hw_constraint_list(substream->runtime, 0, 866 SNDRV_PCM_HW_PARAM_RATE, 867 &sysclk_constraints[priv->pll_power_mode]); 868 869 return 0; 870} 871 872static int twl6040_hw_params(struct snd_pcm_substream *substream, 873 struct snd_pcm_hw_params *params, 874 struct snd_soc_dai *dai) 875{ 876 struct snd_soc_component *component = dai->component; 877 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 878 int rate; 879 880 rate = params_rate(params); 881 switch (rate) { 882 case 11250: 883 case 22500: 884 case 44100: 885 case 88200: 886 /* These rates are not supported when HPPLL is in use */ 887 if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) { 888 dev_err(component->dev, "HPPLL does not support rate %d\n", 889 rate); 890 return -EINVAL; 891 } 892 priv->sysclk = 17640000; 893 break; 894 case 8000: 895 case 16000: 896 case 32000: 897 case 48000: 898 case 96000: 899 priv->sysclk = 19200000; 900 break; 901 default: 902 dev_err(component->dev, "unsupported rate %d\n", rate); 903 return -EINVAL; 904 } 905 906 return 0; 907} 908 909static int twl6040_prepare(struct snd_pcm_substream *substream, 910 struct snd_soc_dai *dai) 911{ 912 struct snd_soc_component *component = dai->component; 913 struct twl6040 *twl6040 = to_twl6040(component); 914 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 915 int ret; 916 917 if (!priv->sysclk) { 918 dev_err(component->dev, 919 "no mclk configured, call set_sysclk() on init\n"); 920 return -EINVAL; 921 } 922 923 ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk); 924 if (ret) { 925 dev_err(component->dev, "Can not set PLL (%d)\n", ret); 926 return -EPERM; 927 } 928 929 return 0; 930} 931 932static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, 933 int clk_id, unsigned int freq, int dir) 934{ 935 struct snd_soc_component *component = codec_dai->component; 936 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 937 938 switch (clk_id) { 939 case TWL6040_SYSCLK_SEL_LPPLL: 940 case TWL6040_SYSCLK_SEL_HPPLL: 941 priv->pll = clk_id; 942 priv->clk_in = freq; 943 break; 944 default: 945 dev_err(component->dev, "unknown clk_id %d\n", clk_id); 946 return -EINVAL; 947 } 948 949 return 0; 950} 951 952static void twl6040_mute_path(struct snd_soc_component *component, enum twl6040_dai_id id, 953 int mute) 954{ 955 struct twl6040 *twl6040 = to_twl6040(component); 956 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 957 int hslctl, hsrctl, earctl; 958 int hflctl, hfrctl; 959 960 switch (id) { 961 case TWL6040_DAI_DL1: 962 hslctl = twl6040_read(component, TWL6040_REG_HSLCTL); 963 hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL); 964 earctl = twl6040_read(component, TWL6040_REG_EARCTL); 965 966 if (mute) { 967 /* Power down drivers and DACs */ 968 earctl &= ~0x01; 969 hslctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA); 970 hsrctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA); 971 972 } 973 974 twl6040_reg_write(twl6040, TWL6040_REG_EARCTL, earctl); 975 twl6040_reg_write(twl6040, TWL6040_REG_HSLCTL, hslctl); 976 twl6040_reg_write(twl6040, TWL6040_REG_HSRCTL, hsrctl); 977 priv->dl1_unmuted = !mute; 978 break; 979 case TWL6040_DAI_DL2: 980 hflctl = twl6040_read(component, TWL6040_REG_HFLCTL); 981 hfrctl = twl6040_read(component, TWL6040_REG_HFRCTL); 982 983 if (mute) { 984 /* Power down drivers and DACs */ 985 hflctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA | 986 TWL6040_HFDRVENA | TWL6040_HFSWENA); 987 hfrctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA | 988 TWL6040_HFDRVENA | TWL6040_HFSWENA); 989 } 990 991 twl6040_reg_write(twl6040, TWL6040_REG_HFLCTL, hflctl); 992 twl6040_reg_write(twl6040, TWL6040_REG_HFRCTL, hfrctl); 993 priv->dl2_unmuted = !mute; 994 break; 995 default: 996 break; 997 } 998} 999 1000static int twl6040_mute_stream(struct snd_soc_dai *dai, int mute, int direction) 1001{ 1002 switch (dai->id) { 1003 case TWL6040_DAI_LEGACY: 1004 twl6040_mute_path(dai->component, TWL6040_DAI_DL1, mute); 1005 twl6040_mute_path(dai->component, TWL6040_DAI_DL2, mute); 1006 break; 1007 case TWL6040_DAI_DL1: 1008 case TWL6040_DAI_DL2: 1009 twl6040_mute_path(dai->component, dai->id, mute); 1010 break; 1011 default: 1012 break; 1013 } 1014 1015 return 0; 1016} 1017 1018static const struct snd_soc_dai_ops twl6040_dai_ops = { 1019 .startup = twl6040_startup, 1020 .hw_params = twl6040_hw_params, 1021 .prepare = twl6040_prepare, 1022 .set_sysclk = twl6040_set_dai_sysclk, 1023 .mute_stream = twl6040_mute_stream, 1024 .no_capture_mute = 1, 1025}; 1026 1027static struct snd_soc_dai_driver twl6040_dai[] = { 1028{ 1029 .name = "twl6040-legacy", 1030 .id = TWL6040_DAI_LEGACY, 1031 .playback = { 1032 .stream_name = "Legacy Playback", 1033 .channels_min = 1, 1034 .channels_max = 5, 1035 .rates = TWL6040_RATES, 1036 .formats = TWL6040_FORMATS, 1037 }, 1038 .capture = { 1039 .stream_name = "Legacy Capture", 1040 .channels_min = 1, 1041 .channels_max = 2, 1042 .rates = TWL6040_RATES, 1043 .formats = TWL6040_FORMATS, 1044 }, 1045 .ops = &twl6040_dai_ops, 1046}, 1047{ 1048 .name = "twl6040-ul", 1049 .id = TWL6040_DAI_UL, 1050 .capture = { 1051 .stream_name = "Capture", 1052 .channels_min = 1, 1053 .channels_max = 2, 1054 .rates = TWL6040_RATES, 1055 .formats = TWL6040_FORMATS, 1056 }, 1057 .ops = &twl6040_dai_ops, 1058}, 1059{ 1060 .name = "twl6040-dl1", 1061 .id = TWL6040_DAI_DL1, 1062 .playback = { 1063 .stream_name = "Headset Playback", 1064 .channels_min = 1, 1065 .channels_max = 2, 1066 .rates = TWL6040_RATES, 1067 .formats = TWL6040_FORMATS, 1068 }, 1069 .ops = &twl6040_dai_ops, 1070}, 1071{ 1072 .name = "twl6040-dl2", 1073 .id = TWL6040_DAI_DL2, 1074 .playback = { 1075 .stream_name = "Handsfree Playback", 1076 .channels_min = 1, 1077 .channels_max = 2, 1078 .rates = TWL6040_RATES, 1079 .formats = TWL6040_FORMATS, 1080 }, 1081 .ops = &twl6040_dai_ops, 1082}, 1083{ 1084 .name = "twl6040-vib", 1085 .id = TWL6040_DAI_VIB, 1086 .playback = { 1087 .stream_name = "Vibra Playback", 1088 .channels_min = 1, 1089 .channels_max = 1, 1090 .rates = SNDRV_PCM_RATE_CONTINUOUS, 1091 .formats = TWL6040_FORMATS, 1092 }, 1093 .ops = &twl6040_dai_ops, 1094}, 1095}; 1096 1097static int twl6040_probe(struct snd_soc_component *component) 1098{ 1099 struct twl6040_data *priv; 1100 struct platform_device *pdev = to_platform_device(component->dev); 1101 int ret = 0; 1102 1103 priv = devm_kzalloc(component->dev, sizeof(*priv), GFP_KERNEL); 1104 if (priv == NULL) 1105 return -ENOMEM; 1106 1107 snd_soc_component_set_drvdata(component, priv); 1108 1109 priv->component = component; 1110 1111 priv->plug_irq = platform_get_irq(pdev, 0); 1112 if (priv->plug_irq < 0) 1113 return priv->plug_irq; 1114 1115 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); 1116 1117 mutex_init(&priv->mutex); 1118 1119 ret = request_threaded_irq(priv->plug_irq, NULL, 1120 twl6040_audio_handler, 1121 IRQF_NO_SUSPEND | IRQF_ONESHOT, 1122 "twl6040_irq_plug", component); 1123 if (ret) { 1124 dev_err(component->dev, "PLUG IRQ request failed: %d\n", ret); 1125 return ret; 1126 } 1127 1128 snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); 1129 twl6040_init_chip(component); 1130 1131 return 0; 1132} 1133 1134static void twl6040_remove(struct snd_soc_component *component) 1135{ 1136 struct twl6040_data *priv = snd_soc_component_get_drvdata(component); 1137 1138 free_irq(priv->plug_irq, component); 1139} 1140 1141static const struct snd_soc_component_driver soc_component_dev_twl6040 = { 1142 .probe = twl6040_probe, 1143 .remove = twl6040_remove, 1144 .read = twl6040_read, 1145 .write = twl6040_write, 1146 .set_bias_level = twl6040_set_bias_level, 1147 .controls = twl6040_snd_controls, 1148 .num_controls = ARRAY_SIZE(twl6040_snd_controls), 1149 .dapm_widgets = twl6040_dapm_widgets, 1150 .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), 1151 .dapm_routes = intercon, 1152 .num_dapm_routes = ARRAY_SIZE(intercon), 1153 .suspend_bias_off = 1, 1154 .idle_bias_on = 1, 1155 .endianness = 1, 1156 .non_legacy_dai_naming = 1, 1157}; 1158 1159static int twl6040_codec_probe(struct platform_device *pdev) 1160{ 1161 return devm_snd_soc_register_component(&pdev->dev, 1162 &soc_component_dev_twl6040, 1163 twl6040_dai, ARRAY_SIZE(twl6040_dai)); 1164} 1165 1166static struct platform_driver twl6040_codec_driver = { 1167 .driver = { 1168 .name = "twl6040-codec", 1169 }, 1170 .probe = twl6040_codec_probe, 1171}; 1172 1173module_platform_driver(twl6040_codec_driver); 1174 1175MODULE_DESCRIPTION("ASoC TWL6040 codec driver"); 1176MODULE_AUTHOR("Misael Lopez Cruz"); 1177MODULE_LICENSE("GPL");