root/sound/soc/codecs/twl6040.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. twl6040_read
  2. twl6040_can_write_to_chip
  3. twl6040_update_dl12_cache
  4. twl6040_write
  5. twl6040_init_chip
  6. headset_power_mode
  7. twl6040_hs_dac_event
  8. twl6040_ep_drv_event
  9. twl6040_hs_jack_report
  10. twl6040_hs_jack_detect
  11. twl6040_accessory_work
  12. twl6040_audio_handler
  13. twl6040_soc_dapm_put_vibra_enum
  14. twl6040_headset_power_get_enum
  15. twl6040_headset_power_put_enum
  16. twl6040_pll_get_enum
  17. twl6040_pll_put_enum
  18. twl6040_get_dl1_gain
  19. twl6040_get_clk_id
  20. twl6040_get_trim_value
  21. twl6040_get_hs_step_size
  22. twl6040_set_bias_level
  23. twl6040_startup
  24. twl6040_hw_params
  25. twl6040_prepare
  26. twl6040_set_dai_sysclk
  27. twl6040_mute_path
  28. twl6040_digital_mute
  29. twl6040_probe
  30. twl6040_remove
  31. twl6040_codec_probe

   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 
  27 enum 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 
  45 struct twl6040_jack_data {
  46         struct snd_soc_jack *jack;
  47         struct delayed_work work;
  48         int report;
  49 };
  50 
  51 /* codec private data */
  52 struct 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 */
  70 static 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 
  82 static const unsigned int hp_rates[] = {
  83         8000,
  84         16000,
  85         32000,
  86         48000,
  87         96000,
  88 };
  89 
  90 static 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 
  97 static 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 
 122 static 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 
 141 static 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 
 159 static 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 
 174 static 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 */
 200 static 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 
 222 static 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 
 249 static 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 
 270 static 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 
 288 void 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 }
 299 EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
 300 
 301 static 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 */
 312 static 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 
 323 static 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  */
 342 static 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  */
 348 static 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  */
 354 static 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  */
 360 static 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  */
 366 static 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  */
 372 static DECLARE_TLV_DB_SCALE(ep_tlv, -2400, 200, 0);
 373 
 374 /* Left analog microphone selection */
 375 static const char *twl6040_amicl_texts[] =
 376         {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"};
 377 
 378 /* Right analog microphone selection */
 379 static const char *twl6040_amicr_texts[] =
 380         {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
 381 
 382 static 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 
 389 static const char *twl6040_hs_texts[] = {
 390         "Off", "HS DAC", "Line-In amp"
 391 };
 392 
 393 static 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 
 400 static const char *twl6040_hf_texts[] = {
 401         "Off", "HF DAC", "Line-In amp"
 402 };
 403 
 404 static 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 
 411 static const char *twl6040_vibrapath_texts[] = {
 412         "Input FF", "Audio PDM"
 413 };
 414 
 415 static 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 
 424 static const struct snd_kcontrol_new amicl_control =
 425         SOC_DAPM_ENUM("Route", twl6040_enum[0]);
 426 
 427 static const struct snd_kcontrol_new amicr_control =
 428         SOC_DAPM_ENUM("Route", twl6040_enum[1]);
 429 
 430 /* Headset DAC playback switches */
 431 static const struct snd_kcontrol_new hsl_mux_controls =
 432         SOC_DAPM_ENUM("Route", twl6040_hs_enum[0]);
 433 
 434 static const struct snd_kcontrol_new hsr_mux_controls =
 435         SOC_DAPM_ENUM("Route", twl6040_hs_enum[1]);
 436 
 437 /* Handsfree DAC playback switches */
 438 static const struct snd_kcontrol_new hfl_mux_controls =
 439         SOC_DAPM_ENUM("Route", twl6040_hf_enum[0]);
 440 
 441 static const struct snd_kcontrol_new hfr_mux_controls =
 442         SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
 443 
 444 static const struct snd_kcontrol_new ep_path_enable_control =
 445         SOC_DAPM_SINGLE_VIRT("Switch", 1);
 446 
 447 static const struct snd_kcontrol_new auxl_switch_control =
 448         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 6, 1, 0);
 449 
 450 static const struct snd_kcontrol_new auxr_switch_control =
 451         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 6, 1, 0);
 452 
 453 /* Vibra playback switches */
 454 static 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 
 459 static 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 */
 465 static const char *twl6040_power_mode_texts[] = {
 466         "Low-Power", "High-Performance",
 467 };
 468 
 469 static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum,
 470                                 twl6040_power_mode_texts);
 471 
 472 static 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 
 483 static 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 
 500 static 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 
 511 static 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 
 522 int 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 }
 542 EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain);
 543 
 544 int 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 }
 550 EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
 551 
 552 int 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 }
 559 EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
 560 
 561 int 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 }
 572 EXPORT_SYMBOL_GPL(twl6040_get_hs_step_size);
 573 
 574 static 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 
 609 static 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 
 724 static 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 
 818 static 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 
 859 static 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 
 872 static 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 
 909 static 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 
 932 static 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 
 952 static 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 
1000 static int twl6040_digital_mute(struct snd_soc_dai *dai, int mute)
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 
1018 static 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         .digital_mute   = twl6040_digital_mute,
1024 };
1025 
1026 static struct snd_soc_dai_driver twl6040_dai[] = {
1027 {
1028         .name = "twl6040-legacy",
1029         .id = TWL6040_DAI_LEGACY,
1030         .playback = {
1031                 .stream_name = "Legacy Playback",
1032                 .channels_min = 1,
1033                 .channels_max = 5,
1034                 .rates = TWL6040_RATES,
1035                 .formats = TWL6040_FORMATS,
1036         },
1037         .capture = {
1038                 .stream_name = "Legacy Capture",
1039                 .channels_min = 1,
1040                 .channels_max = 2,
1041                 .rates = TWL6040_RATES,
1042                 .formats = TWL6040_FORMATS,
1043         },
1044         .ops = &twl6040_dai_ops,
1045 },
1046 {
1047         .name = "twl6040-ul",
1048         .id = TWL6040_DAI_UL,
1049         .capture = {
1050                 .stream_name = "Capture",
1051                 .channels_min = 1,
1052                 .channels_max = 2,
1053                 .rates = TWL6040_RATES,
1054                 .formats = TWL6040_FORMATS,
1055         },
1056         .ops = &twl6040_dai_ops,
1057 },
1058 {
1059         .name = "twl6040-dl1",
1060         .id = TWL6040_DAI_DL1,
1061         .playback = {
1062                 .stream_name = "Headset Playback",
1063                 .channels_min = 1,
1064                 .channels_max = 2,
1065                 .rates = TWL6040_RATES,
1066                 .formats = TWL6040_FORMATS,
1067         },
1068         .ops = &twl6040_dai_ops,
1069 },
1070 {
1071         .name = "twl6040-dl2",
1072         .id = TWL6040_DAI_DL2,
1073         .playback = {
1074                 .stream_name = "Handsfree Playback",
1075                 .channels_min = 1,
1076                 .channels_max = 2,
1077                 .rates = TWL6040_RATES,
1078                 .formats = TWL6040_FORMATS,
1079         },
1080         .ops = &twl6040_dai_ops,
1081 },
1082 {
1083         .name = "twl6040-vib",
1084         .id = TWL6040_DAI_VIB,
1085         .playback = {
1086                 .stream_name = "Vibra Playback",
1087                 .channels_min = 1,
1088                 .channels_max = 1,
1089                 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1090                 .formats = TWL6040_FORMATS,
1091         },
1092         .ops = &twl6040_dai_ops,
1093 },
1094 };
1095 
1096 static int twl6040_probe(struct snd_soc_component *component)
1097 {
1098         struct twl6040_data *priv;
1099         struct platform_device *pdev = to_platform_device(component->dev);
1100         int ret = 0;
1101 
1102         priv = devm_kzalloc(component->dev, sizeof(*priv), GFP_KERNEL);
1103         if (priv == NULL)
1104                 return -ENOMEM;
1105 
1106         snd_soc_component_set_drvdata(component, priv);
1107 
1108         priv->component = component;
1109 
1110         priv->plug_irq = platform_get_irq(pdev, 0);
1111         if (priv->plug_irq < 0)
1112                 return priv->plug_irq;
1113 
1114         INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);
1115 
1116         mutex_init(&priv->mutex);
1117 
1118         ret = request_threaded_irq(priv->plug_irq, NULL,
1119                                         twl6040_audio_handler,
1120                                         IRQF_NO_SUSPEND | IRQF_ONESHOT,
1121                                         "twl6040_irq_plug", component);
1122         if (ret) {
1123                 dev_err(component->dev, "PLUG IRQ request failed: %d\n", ret);
1124                 return ret;
1125         }
1126 
1127         snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
1128         twl6040_init_chip(component);
1129 
1130         return 0;
1131 }
1132 
1133 static void twl6040_remove(struct snd_soc_component *component)
1134 {
1135         struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
1136 
1137         free_irq(priv->plug_irq, component);
1138 }
1139 
1140 static const struct snd_soc_component_driver soc_component_dev_twl6040 = {
1141         .probe                  = twl6040_probe,
1142         .remove                 = twl6040_remove,
1143         .read                   = twl6040_read,
1144         .write                  = twl6040_write,
1145         .set_bias_level         = twl6040_set_bias_level,
1146         .controls               = twl6040_snd_controls,
1147         .num_controls           = ARRAY_SIZE(twl6040_snd_controls),
1148         .dapm_widgets           = twl6040_dapm_widgets,
1149         .num_dapm_widgets       = ARRAY_SIZE(twl6040_dapm_widgets),
1150         .dapm_routes            = intercon,
1151         .num_dapm_routes        = ARRAY_SIZE(intercon),
1152         .suspend_bias_off       = 1,
1153         .idle_bias_on           = 1,
1154         .endianness             = 1,
1155         .non_legacy_dai_naming  = 1,
1156 };
1157 
1158 static int twl6040_codec_probe(struct platform_device *pdev)
1159 {
1160         return devm_snd_soc_register_component(&pdev->dev,
1161                                       &soc_component_dev_twl6040,
1162                                       twl6040_dai, ARRAY_SIZE(twl6040_dai));
1163 }
1164 
1165 static struct platform_driver twl6040_codec_driver = {
1166         .driver = {
1167                 .name = "twl6040-codec",
1168         },
1169         .probe = twl6040_codec_probe,
1170 };
1171 
1172 module_platform_driver(twl6040_codec_driver);
1173 
1174 MODULE_DESCRIPTION("ASoC TWL6040 codec driver");
1175 MODULE_AUTHOR("Misael Lopez Cruz");
1176 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */