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