linux/drivers/extcon/extcon-arizona.c
<<
>>
Prefs
   1/*
   2 * extcon-arizona.c - Extcon driver Wolfson Arizona devices
   3 *
   4 *  Copyright (C) 2012 Wolfson Microelectronics plc
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/module.h>
  19#include <linux/i2c.h>
  20#include <linux/slab.h>
  21#include <linux/interrupt.h>
  22#include <linux/err.h>
  23#include <linux/gpio.h>
  24#include <linux/input.h>
  25#include <linux/platform_device.h>
  26#include <linux/pm_runtime.h>
  27#include <linux/regulator/consumer.h>
  28#include <linux/extcon.h>
  29
  30#include <sound/soc.h>
  31
  32#include <linux/mfd/arizona/core.h>
  33#include <linux/mfd/arizona/pdata.h>
  34#include <linux/mfd/arizona/registers.h>
  35
  36#define ARIZONA_MAX_MICD_RANGE 8
  37
  38#define ARIZONA_ACCDET_MODE_MIC 0
  39#define ARIZONA_ACCDET_MODE_HPL 1
  40#define ARIZONA_ACCDET_MODE_HPR 2
  41
  42#define ARIZONA_HPDET_MAX 10000
  43
  44#define HPDET_DEBOUNCE 500
  45#define DEFAULT_MICD_TIMEOUT 2000
  46
  47struct arizona_extcon_info {
  48        struct device *dev;
  49        struct arizona *arizona;
  50        struct mutex lock;
  51        struct regulator *micvdd;
  52        struct input_dev *input;
  53
  54        u16 last_jackdet;
  55
  56        int micd_mode;
  57        const struct arizona_micd_config *micd_modes;
  58        int micd_num_modes;
  59
  60        const struct arizona_micd_range *micd_ranges;
  61        int num_micd_ranges;
  62
  63        int micd_timeout;
  64
  65        bool micd_reva;
  66        bool micd_clamp;
  67
  68        struct delayed_work hpdet_work;
  69        struct delayed_work micd_detect_work;
  70        struct delayed_work micd_timeout_work;
  71
  72        bool hpdet_active;
  73        bool hpdet_done;
  74        bool hpdet_retried;
  75
  76        int num_hpdet_res;
  77        unsigned int hpdet_res[3];
  78
  79        bool mic;
  80        bool detecting;
  81        int jack_flips;
  82
  83        int hpdet_ip;
  84
  85        struct extcon_dev edev;
  86};
  87
  88static const struct arizona_micd_config micd_default_modes[] = {
  89        { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 },
  90        { 0,                  2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 },
  91};
  92
  93static const struct arizona_micd_range micd_default_ranges[] = {
  94        { .max =  11, .key = BTN_0 },
  95        { .max =  28, .key = BTN_1 },
  96        { .max =  54, .key = BTN_2 },
  97        { .max = 100, .key = BTN_3 },
  98        { .max = 186, .key = BTN_4 },
  99        { .max = 430, .key = BTN_5 },
 100};
 101
 102static const int arizona_micd_levels[] = {
 103        3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
 104        49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
 105        105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
 106        270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
 107        1257,
 108};
 109
 110#define ARIZONA_CABLE_MECHANICAL 0
 111#define ARIZONA_CABLE_MICROPHONE 1
 112#define ARIZONA_CABLE_HEADPHONE  2
 113#define ARIZONA_CABLE_LINEOUT    3
 114
 115static const char *arizona_cable[] = {
 116        "Mechanical",
 117        "Microphone",
 118        "Headphone",
 119        "Line-out",
 120        NULL,
 121};
 122
 123static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info);
 124
 125static void arizona_extcon_do_magic(struct arizona_extcon_info *info,
 126                                    unsigned int magic)
 127{
 128        struct arizona *arizona = info->arizona;
 129        int ret;
 130
 131        mutex_lock(&arizona->dapm->card->dapm_mutex);
 132
 133        arizona->hpdet_magic = magic;
 134
 135        /* Keep the HP output stages disabled while doing the magic */
 136        if (magic) {
 137                ret = regmap_update_bits(arizona->regmap,
 138                                         ARIZONA_OUTPUT_ENABLES_1,
 139                                         ARIZONA_OUT1L_ENA |
 140                                         ARIZONA_OUT1R_ENA, 0);
 141                if (ret != 0)
 142                        dev_warn(arizona->dev,
 143                                "Failed to disable headphone outputs: %d\n",
 144                                 ret);
 145        }
 146
 147        ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000,
 148                                 magic);
 149        if (ret != 0)
 150                dev_warn(arizona->dev, "Failed to do magic: %d\n",
 151                                 ret);
 152
 153        ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000,
 154                                 magic);
 155        if (ret != 0)
 156                dev_warn(arizona->dev, "Failed to do magic: %d\n",
 157                         ret);
 158
 159        /* Restore the desired state while not doing the magic */
 160        if (!magic) {
 161                ret = regmap_update_bits(arizona->regmap,
 162                                         ARIZONA_OUTPUT_ENABLES_1,
 163                                         ARIZONA_OUT1L_ENA |
 164                                         ARIZONA_OUT1R_ENA, arizona->hp_ena);
 165                if (ret != 0)
 166                        dev_warn(arizona->dev,
 167                                 "Failed to restore headphone outputs: %d\n",
 168                                 ret);
 169        }
 170
 171        mutex_unlock(&arizona->dapm->card->dapm_mutex);
 172}
 173
 174static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
 175{
 176        struct arizona *arizona = info->arizona;
 177
 178        mode %= info->micd_num_modes;
 179
 180        if (arizona->pdata.micd_pol_gpio > 0)
 181                gpio_set_value_cansleep(arizona->pdata.micd_pol_gpio,
 182                                        info->micd_modes[mode].gpio);
 183        regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
 184                           ARIZONA_MICD_BIAS_SRC_MASK,
 185                           info->micd_modes[mode].bias);
 186        regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
 187                           ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
 188
 189        info->micd_mode = mode;
 190
 191        dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode);
 192}
 193
 194static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info)
 195{
 196        switch (info->micd_modes[0].bias >> ARIZONA_MICD_BIAS_SRC_SHIFT) {
 197        case 1:
 198                return "MICBIAS1";
 199        case 2:
 200                return "MICBIAS2";
 201        case 3:
 202                return "MICBIAS3";
 203        default:
 204                return "MICVDD";
 205        }
 206}
 207
 208static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info)
 209{
 210        struct arizona *arizona = info->arizona;
 211        const char *widget = arizona_extcon_get_micbias(info);
 212        struct snd_soc_dapm_context *dapm = arizona->dapm;
 213        int ret;
 214
 215        mutex_lock(&dapm->card->dapm_mutex);
 216
 217        ret = snd_soc_dapm_force_enable_pin(dapm, widget);
 218        if (ret != 0)
 219                dev_warn(arizona->dev, "Failed to enable %s: %d\n",
 220                         widget, ret);
 221
 222        mutex_unlock(&dapm->card->dapm_mutex);
 223
 224        snd_soc_dapm_sync(dapm);
 225
 226        if (!arizona->pdata.micd_force_micbias) {
 227                mutex_lock(&dapm->card->dapm_mutex);
 228
 229                ret = snd_soc_dapm_disable_pin(arizona->dapm, widget);
 230                if (ret != 0)
 231                        dev_warn(arizona->dev, "Failed to disable %s: %d\n",
 232                                 widget, ret);
 233
 234                mutex_unlock(&dapm->card->dapm_mutex);
 235
 236                snd_soc_dapm_sync(dapm);
 237        }
 238}
 239
 240static void arizona_start_mic(struct arizona_extcon_info *info)
 241{
 242        struct arizona *arizona = info->arizona;
 243        bool change;
 244        int ret;
 245
 246        /* Microphone detection can't use idle mode */
 247        pm_runtime_get(info->dev);
 248
 249        if (info->detecting) {
 250                ret = regulator_allow_bypass(info->micvdd, false);
 251                if (ret != 0) {
 252                        dev_err(arizona->dev,
 253                                "Failed to regulate MICVDD: %d\n",
 254                                ret);
 255                }
 256        }
 257
 258        ret = regulator_enable(info->micvdd);
 259        if (ret != 0) {
 260                dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
 261                        ret);
 262        }
 263
 264        if (info->micd_reva) {
 265                regmap_write(arizona->regmap, 0x80, 0x3);
 266                regmap_write(arizona->regmap, 0x294, 0);
 267                regmap_write(arizona->regmap, 0x80, 0x0);
 268        }
 269
 270        regmap_update_bits(arizona->regmap,
 271                           ARIZONA_ACCESSORY_DETECT_MODE_1,
 272                           ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
 273
 274        arizona_extcon_pulse_micbias(info);
 275
 276        regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
 277                                 ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
 278                                 &change);
 279        if (!change) {
 280                regulator_disable(info->micvdd);
 281                pm_runtime_put_autosuspend(info->dev);
 282        }
 283}
 284
 285static void arizona_stop_mic(struct arizona_extcon_info *info)
 286{
 287        struct arizona *arizona = info->arizona;
 288        const char *widget = arizona_extcon_get_micbias(info);
 289        struct snd_soc_dapm_context *dapm = arizona->dapm;
 290        bool change;
 291        int ret;
 292
 293        regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
 294                                 ARIZONA_MICD_ENA, 0,
 295                                 &change);
 296
 297        mutex_lock(&dapm->card->dapm_mutex);
 298
 299        ret = snd_soc_dapm_disable_pin(dapm, widget);
 300        if (ret != 0)
 301                dev_warn(arizona->dev,
 302                         "Failed to disable %s: %d\n",
 303                         widget, ret);
 304
 305        mutex_unlock(&dapm->card->dapm_mutex);
 306
 307        snd_soc_dapm_sync(dapm);
 308
 309        if (info->micd_reva) {
 310                regmap_write(arizona->regmap, 0x80, 0x3);
 311                regmap_write(arizona->regmap, 0x294, 2);
 312                regmap_write(arizona->regmap, 0x80, 0x0);
 313        }
 314
 315        ret = regulator_allow_bypass(info->micvdd, true);
 316        if (ret != 0) {
 317                dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
 318                        ret);
 319        }
 320
 321        if (change) {
 322                regulator_disable(info->micvdd);
 323                pm_runtime_mark_last_busy(info->dev);
 324                pm_runtime_put_autosuspend(info->dev);
 325        }
 326}
 327
 328static struct {
 329        unsigned int factor_a;
 330        unsigned int factor_b;
 331} arizona_hpdet_b_ranges[] = {
 332        {  5528,   362464 },
 333        { 11084,  6186851 },
 334        { 11065, 65460395 },
 335};
 336
 337static struct {
 338        int min;
 339        int max;
 340} arizona_hpdet_c_ranges[] = {
 341        { 0,       30 },
 342        { 8,      100 },
 343        { 100,   1000 },
 344        { 1000, 10000 },
 345};
 346
 347static int arizona_hpdet_read(struct arizona_extcon_info *info)
 348{
 349        struct arizona *arizona = info->arizona;
 350        unsigned int val, range;
 351        int ret;
 352
 353        ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
 354        if (ret != 0) {
 355                dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
 356                        ret);
 357                return ret;
 358        }
 359
 360        switch (info->hpdet_ip) {
 361        case 0:
 362                if (!(val & ARIZONA_HP_DONE)) {
 363                        dev_err(arizona->dev, "HPDET did not complete: %x\n",
 364                                val);
 365                        return -EAGAIN;
 366                }
 367
 368                val &= ARIZONA_HP_LVL_MASK;
 369                break;
 370
 371        case 1:
 372                if (!(val & ARIZONA_HP_DONE_B)) {
 373                        dev_err(arizona->dev, "HPDET did not complete: %x\n",
 374                                val);
 375                        return -EAGAIN;
 376                }
 377
 378                ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
 379                if (ret != 0) {
 380                        dev_err(arizona->dev, "Failed to read HP value: %d\n",
 381                                ret);
 382                        return -EAGAIN;
 383                }
 384
 385                regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
 386                            &range);
 387                range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
 388                           >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
 389
 390                if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
 391                    (val < 100 || val > 0x3fb)) {
 392                        range++;
 393                        dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
 394                                range);
 395                        regmap_update_bits(arizona->regmap,
 396                                           ARIZONA_HEADPHONE_DETECT_1,
 397                                           ARIZONA_HP_IMPEDANCE_RANGE_MASK,
 398                                           range <<
 399                                           ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
 400                        return -EAGAIN;
 401                }
 402
 403                /* If we go out of range report top of range */
 404                if (val < 100 || val > 0x3fb) {
 405                        dev_dbg(arizona->dev, "Measurement out of range\n");
 406                        return ARIZONA_HPDET_MAX;
 407                }
 408
 409                dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
 410                        val, range);
 411
 412                val = arizona_hpdet_b_ranges[range].factor_b
 413                        / ((val * 100) -
 414                           arizona_hpdet_b_ranges[range].factor_a);
 415                break;
 416
 417        default:
 418                dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
 419                         info->hpdet_ip);
 420        case 2:
 421                if (!(val & ARIZONA_HP_DONE_B)) {
 422                        dev_err(arizona->dev, "HPDET did not complete: %x\n",
 423                                val);
 424                        return -EAGAIN;
 425                }
 426
 427                val &= ARIZONA_HP_LVL_B_MASK;
 428
 429                regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
 430                            &range);
 431                range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
 432                           >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
 433
 434                /* Skip up or down a range? */
 435                if (range && (val < arizona_hpdet_c_ranges[range].min)) {
 436                        range--;
 437                        dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
 438                                arizona_hpdet_c_ranges[range].min,
 439                                arizona_hpdet_c_ranges[range].max);
 440                        regmap_update_bits(arizona->regmap,
 441                                           ARIZONA_HEADPHONE_DETECT_1,
 442                                           ARIZONA_HP_IMPEDANCE_RANGE_MASK,
 443                                           range <<
 444                                           ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
 445                        return -EAGAIN;
 446                }
 447
 448                if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
 449                    (val >= arizona_hpdet_c_ranges[range].max)) {
 450                        range++;
 451                        dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
 452                                arizona_hpdet_c_ranges[range].min,
 453                                arizona_hpdet_c_ranges[range].max);
 454                        regmap_update_bits(arizona->regmap,
 455                                           ARIZONA_HEADPHONE_DETECT_1,
 456                                           ARIZONA_HP_IMPEDANCE_RANGE_MASK,
 457                                           range <<
 458                                           ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
 459                        return -EAGAIN;
 460                }
 461        }
 462
 463        dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
 464        return val;
 465}
 466
 467static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
 468                               bool *mic)
 469{
 470        struct arizona *arizona = info->arizona;
 471        int id_gpio = arizona->pdata.hpdet_id_gpio;
 472
 473        /*
 474         * If we're using HPDET for accessory identification we need
 475         * to take multiple measurements, step through them in sequence.
 476         */
 477        if (arizona->pdata.hpdet_acc_id) {
 478                info->hpdet_res[info->num_hpdet_res++] = *reading;
 479
 480                /* Only check the mic directly if we didn't already ID it */
 481                if (id_gpio && info->num_hpdet_res == 1) {
 482                        dev_dbg(arizona->dev, "Measuring mic\n");
 483
 484                        regmap_update_bits(arizona->regmap,
 485                                           ARIZONA_ACCESSORY_DETECT_MODE_1,
 486                                           ARIZONA_ACCDET_MODE_MASK |
 487                                           ARIZONA_ACCDET_SRC,
 488                                           ARIZONA_ACCDET_MODE_HPR |
 489                                           info->micd_modes[0].src);
 490
 491                        gpio_set_value_cansleep(id_gpio, 1);
 492
 493                        regmap_update_bits(arizona->regmap,
 494                                           ARIZONA_HEADPHONE_DETECT_1,
 495                                           ARIZONA_HP_POLL, ARIZONA_HP_POLL);
 496                        return -EAGAIN;
 497                }
 498
 499                /* OK, got both.  Now, compare... */
 500                dev_dbg(arizona->dev, "HPDET measured %d %d\n",
 501                        info->hpdet_res[0], info->hpdet_res[1]);
 502
 503                /* Take the headphone impedance for the main report */
 504                *reading = info->hpdet_res[0];
 505
 506                /* Sometimes we get false readings due to slow insert */
 507                if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
 508                        dev_dbg(arizona->dev, "Retrying high impedance\n");
 509                        info->num_hpdet_res = 0;
 510                        info->hpdet_retried = true;
 511                        arizona_start_hpdet_acc_id(info);
 512                        pm_runtime_put(info->dev);
 513                        return -EAGAIN;
 514                }
 515
 516                /*
 517                 * If we measure the mic as 
 518                 */
 519                if (!id_gpio || info->hpdet_res[1] > 50) {
 520                        dev_dbg(arizona->dev, "Detected mic\n");
 521                        *mic = true;
 522                        info->detecting = true;
 523                } else {
 524                        dev_dbg(arizona->dev, "Detected headphone\n");
 525                }
 526
 527                /* Make sure everything is reset back to the real polarity */
 528                regmap_update_bits(arizona->regmap,
 529                                   ARIZONA_ACCESSORY_DETECT_MODE_1,
 530                                   ARIZONA_ACCDET_SRC,
 531                                   info->micd_modes[0].src);
 532        }
 533
 534        return 0;
 535}
 536
 537static irqreturn_t arizona_hpdet_irq(int irq, void *data)
 538{
 539        struct arizona_extcon_info *info = data;
 540        struct arizona *arizona = info->arizona;
 541        int id_gpio = arizona->pdata.hpdet_id_gpio;
 542        int report = ARIZONA_CABLE_HEADPHONE;
 543        int ret, reading;
 544        bool mic = false;
 545
 546        mutex_lock(&info->lock);
 547
 548        /* If we got a spurious IRQ for some reason then ignore it */
 549        if (!info->hpdet_active) {
 550                dev_warn(arizona->dev, "Spurious HPDET IRQ\n");
 551                mutex_unlock(&info->lock);
 552                return IRQ_NONE;
 553        }
 554
 555        /* If the cable was removed while measuring ignore the result */
 556        ret = extcon_get_cable_state_(&info->edev, ARIZONA_CABLE_MECHANICAL);
 557        if (ret < 0) {
 558                dev_err(arizona->dev, "Failed to check cable state: %d\n",
 559                        ret);
 560                goto out;
 561        } else if (!ret) {
 562                dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
 563                goto done;
 564        }
 565
 566        ret = arizona_hpdet_read(info);
 567        if (ret == -EAGAIN) {
 568                goto out;
 569        } else if (ret < 0) {
 570                goto done;
 571        }
 572        reading = ret;
 573
 574        /* Reset back to starting range */
 575        regmap_update_bits(arizona->regmap,
 576                           ARIZONA_HEADPHONE_DETECT_1,
 577                           ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
 578                           0);
 579
 580        ret = arizona_hpdet_do_id(info, &reading, &mic);
 581        if (ret == -EAGAIN) {
 582                goto out;
 583        } else if (ret < 0) {
 584                goto done;
 585        }
 586
 587        /* Report high impedence cables as line outputs */
 588        if (reading >= 5000)
 589                report = ARIZONA_CABLE_LINEOUT;
 590        else
 591                report = ARIZONA_CABLE_HEADPHONE;
 592
 593        ret = extcon_set_cable_state_(&info->edev, report, true);
 594        if (ret != 0)
 595                dev_err(arizona->dev, "Failed to report HP/line: %d\n",
 596                        ret);
 597
 598        arizona_extcon_do_magic(info, 0);
 599
 600done:
 601        if (id_gpio)
 602                gpio_set_value_cansleep(id_gpio, 0);
 603
 604        /* Revert back to MICDET mode */
 605        regmap_update_bits(arizona->regmap,
 606                           ARIZONA_ACCESSORY_DETECT_MODE_1,
 607                           ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
 608
 609        /* If we have a mic then reenable MICDET */
 610        if (mic || info->mic)
 611                arizona_start_mic(info);
 612
 613        if (info->hpdet_active) {
 614                pm_runtime_put_autosuspend(info->dev);
 615                info->hpdet_active = false;
 616        }
 617
 618        info->hpdet_done = true;
 619
 620out:
 621        mutex_unlock(&info->lock);
 622
 623        return IRQ_HANDLED;
 624}
 625
 626static void arizona_identify_headphone(struct arizona_extcon_info *info)
 627{
 628        struct arizona *arizona = info->arizona;
 629        int ret;
 630
 631        if (info->hpdet_done)
 632                return;
 633
 634        dev_dbg(arizona->dev, "Starting HPDET\n");
 635
 636        /* Make sure we keep the device enabled during the measurement */
 637        pm_runtime_get(info->dev);
 638
 639        info->hpdet_active = true;
 640
 641        if (info->mic)
 642                arizona_stop_mic(info);
 643
 644        arizona_extcon_do_magic(info, 0x4000);
 645
 646        ret = regmap_update_bits(arizona->regmap,
 647                                 ARIZONA_ACCESSORY_DETECT_MODE_1,
 648                                 ARIZONA_ACCDET_MODE_MASK,
 649                                 ARIZONA_ACCDET_MODE_HPL);
 650        if (ret != 0) {
 651                dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
 652                goto err;
 653        }
 654
 655        ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
 656                                 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
 657        if (ret != 0) {
 658                dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
 659                        ret);
 660                goto err;
 661        }
 662
 663        return;
 664
 665err:
 666        regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
 667                           ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
 668
 669        /* Just report headphone */
 670        ret = extcon_update_state(&info->edev,
 671                                  1 << ARIZONA_CABLE_HEADPHONE,
 672                                  1 << ARIZONA_CABLE_HEADPHONE);
 673        if (ret != 0)
 674                dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
 675
 676        if (info->mic)
 677                arizona_start_mic(info);
 678
 679        info->hpdet_active = false;
 680}
 681
 682static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
 683{
 684        struct arizona *arizona = info->arizona;
 685        int hp_reading = 32;
 686        bool mic;
 687        int ret;
 688
 689        dev_dbg(arizona->dev, "Starting identification via HPDET\n");
 690
 691        /* Make sure we keep the device enabled during the measurement */
 692        pm_runtime_get_sync(info->dev);
 693
 694        info->hpdet_active = true;
 695
 696        arizona_extcon_do_magic(info, 0x4000);
 697
 698        ret = regmap_update_bits(arizona->regmap,
 699                                 ARIZONA_ACCESSORY_DETECT_MODE_1,
 700                                 ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,
 701                                 info->micd_modes[0].src |
 702                                 ARIZONA_ACCDET_MODE_HPL);
 703        if (ret != 0) {
 704                dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret);
 705                goto err;
 706        }
 707
 708        if (arizona->pdata.hpdet_acc_id_line) {
 709                ret = regmap_update_bits(arizona->regmap,
 710                                         ARIZONA_HEADPHONE_DETECT_1,
 711                                         ARIZONA_HP_POLL, ARIZONA_HP_POLL);
 712                if (ret != 0) {
 713                        dev_err(arizona->dev,
 714                                "Can't start HPDETL measurement: %d\n",
 715                                ret);
 716                        goto err;
 717                }
 718        } else {
 719                arizona_hpdet_do_id(info, &hp_reading, &mic);
 720        }
 721
 722        return;
 723
 724err:
 725        regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
 726                           ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
 727
 728        /* Just report headphone */
 729        ret = extcon_update_state(&info->edev,
 730                                  1 << ARIZONA_CABLE_HEADPHONE,
 731                                  1 << ARIZONA_CABLE_HEADPHONE);
 732        if (ret != 0)
 733                dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
 734
 735        info->hpdet_active = false;
 736}
 737
 738static void arizona_micd_timeout_work(struct work_struct *work)
 739{
 740        struct arizona_extcon_info *info = container_of(work,
 741                                                        struct arizona_extcon_info,
 742                                                        micd_timeout_work.work);
 743
 744        mutex_lock(&info->lock);
 745
 746        dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n");
 747        arizona_identify_headphone(info);
 748
 749        info->detecting = false;
 750
 751        arizona_stop_mic(info);
 752
 753        mutex_unlock(&info->lock);
 754}
 755
 756static void arizona_micd_detect(struct work_struct *work)
 757{
 758        struct arizona_extcon_info *info = container_of(work,
 759                                                        struct arizona_extcon_info,
 760                                                        micd_detect_work.work);
 761        struct arizona *arizona = info->arizona;
 762        unsigned int val = 0, lvl;
 763        int ret, i, key;
 764
 765        cancel_delayed_work_sync(&info->micd_timeout_work);
 766
 767        mutex_lock(&info->lock);
 768
 769        for (i = 0; i < 10 && !(val & 0x7fc); i++) {
 770                ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
 771                if (ret != 0) {
 772                        dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret);
 773                        mutex_unlock(&info->lock);
 774                        return;
 775                }
 776
 777                dev_dbg(arizona->dev, "MICDET: %x\n", val);
 778
 779                if (!(val & ARIZONA_MICD_VALID)) {
 780                        dev_warn(arizona->dev, "Microphone detection state invalid\n");
 781                        mutex_unlock(&info->lock);
 782                        return;
 783                }
 784        }
 785
 786        if (i == 10 && !(val & 0x7fc)) {
 787                dev_err(arizona->dev, "Failed to get valid MICDET value\n");
 788                mutex_unlock(&info->lock);
 789                return;
 790        }
 791
 792        /* Due to jack detect this should never happen */
 793        if (!(val & ARIZONA_MICD_STS)) {
 794                dev_warn(arizona->dev, "Detected open circuit\n");
 795                info->detecting = false;
 796                goto handled;
 797        }
 798
 799        /* If we got a high impedence we should have a headset, report it. */
 800        if (info->detecting && (val & 0x400)) {
 801                arizona_identify_headphone(info);
 802
 803                ret = extcon_update_state(&info->edev,
 804                                          1 << ARIZONA_CABLE_MICROPHONE,
 805                                          1 << ARIZONA_CABLE_MICROPHONE);
 806
 807                if (ret != 0)
 808                        dev_err(arizona->dev, "Headset report failed: %d\n",
 809                                ret);
 810
 811                /* Don't need to regulate for button detection */
 812                ret = regulator_allow_bypass(info->micvdd, false);
 813                if (ret != 0) {
 814                        dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
 815                                ret);
 816                }
 817
 818                info->mic = true;
 819                info->detecting = false;
 820                goto handled;
 821        }
 822
 823        /* If we detected a lower impedence during initial startup
 824         * then we probably have the wrong polarity, flip it.  Don't
 825         * do this for the lowest impedences to speed up detection of
 826         * plain headphones.  If both polarities report a low
 827         * impedence then give up and report headphones.
 828         */
 829        if (info->detecting && (val & 0x3f8)) {
 830                if (info->jack_flips >= info->micd_num_modes * 10) {
 831                        dev_dbg(arizona->dev, "Detected HP/line\n");
 832                        arizona_identify_headphone(info);
 833
 834                        info->detecting = false;
 835
 836                        arizona_stop_mic(info);
 837                } else {
 838                        info->micd_mode++;
 839                        if (info->micd_mode == info->micd_num_modes)
 840                                info->micd_mode = 0;
 841                        arizona_extcon_set_mode(info, info->micd_mode);
 842
 843                        info->jack_flips++;
 844                }
 845
 846                goto handled;
 847        }
 848
 849        /*
 850         * If we're still detecting and we detect a short then we've
 851         * got a headphone.  Otherwise it's a button press.
 852         */
 853        if (val & 0x3fc) {
 854                if (info->mic) {
 855                        dev_dbg(arizona->dev, "Mic button detected\n");
 856
 857                        lvl = val & ARIZONA_MICD_LVL_MASK;
 858                        lvl >>= ARIZONA_MICD_LVL_SHIFT;
 859
 860                        for (i = 0; i < info->num_micd_ranges; i++)
 861                                input_report_key(info->input,
 862                                                 info->micd_ranges[i].key, 0);
 863
 864                        WARN_ON(!lvl);
 865                        WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges);
 866                        if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
 867                                key = info->micd_ranges[ffs(lvl) - 1].key;
 868                                input_report_key(info->input, key, 1);
 869                                input_sync(info->input);
 870                        }
 871
 872                } else if (info->detecting) {
 873                        dev_dbg(arizona->dev, "Headphone detected\n");
 874                        info->detecting = false;
 875                        arizona_stop_mic(info);
 876
 877                        arizona_identify_headphone(info);
 878                } else {
 879                        dev_warn(arizona->dev, "Button with no mic: %x\n",
 880                                 val);
 881                }
 882        } else {
 883                dev_dbg(arizona->dev, "Mic button released\n");
 884                for (i = 0; i < info->num_micd_ranges; i++)
 885                        input_report_key(info->input,
 886                                         info->micd_ranges[i].key, 0);
 887                input_sync(info->input);
 888                arizona_extcon_pulse_micbias(info);
 889        }
 890
 891handled:
 892        if (info->detecting)
 893                schedule_delayed_work(&info->micd_timeout_work,
 894                                      msecs_to_jiffies(info->micd_timeout));
 895
 896        pm_runtime_mark_last_busy(info->dev);
 897        mutex_unlock(&info->lock);
 898}
 899
 900static irqreturn_t arizona_micdet(int irq, void *data)
 901{
 902        struct arizona_extcon_info *info = data;
 903        struct arizona *arizona = info->arizona;
 904        int debounce = arizona->pdata.micd_detect_debounce;
 905
 906        cancel_delayed_work_sync(&info->micd_detect_work);
 907        cancel_delayed_work_sync(&info->micd_timeout_work);
 908
 909        mutex_lock(&info->lock);
 910        if (!info->detecting)
 911                debounce = 0;
 912        mutex_unlock(&info->lock);
 913
 914        if (debounce)
 915                schedule_delayed_work(&info->micd_detect_work,
 916                                      msecs_to_jiffies(debounce));
 917        else
 918                arizona_micd_detect(&info->micd_detect_work.work);
 919
 920        return IRQ_HANDLED;
 921}
 922
 923static void arizona_hpdet_work(struct work_struct *work)
 924{
 925        struct arizona_extcon_info *info = container_of(work,
 926                                                        struct arizona_extcon_info,
 927                                                        hpdet_work.work);
 928
 929        mutex_lock(&info->lock);
 930        arizona_start_hpdet_acc_id(info);
 931        mutex_unlock(&info->lock);
 932}
 933
 934static irqreturn_t arizona_jackdet(int irq, void *data)
 935{
 936        struct arizona_extcon_info *info = data;
 937        struct arizona *arizona = info->arizona;
 938        unsigned int val, present, mask;
 939        bool cancelled_hp, cancelled_mic;
 940        int ret, i;
 941
 942        cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
 943        cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
 944
 945        pm_runtime_get_sync(info->dev);
 946
 947        mutex_lock(&info->lock);
 948
 949        if (arizona->pdata.jd_gpio5) {
 950                mask = ARIZONA_MICD_CLAMP_STS;
 951                present = 0;
 952        } else {
 953                mask = ARIZONA_JD1_STS;
 954                present = ARIZONA_JD1_STS;
 955        }
 956
 957        ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
 958        if (ret != 0) {
 959                dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
 960                        ret);
 961                mutex_unlock(&info->lock);
 962                pm_runtime_put_autosuspend(info->dev);
 963                return IRQ_NONE;
 964        }
 965
 966        val &= mask;
 967        if (val == info->last_jackdet) {
 968                dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
 969                if (cancelled_hp)
 970                        schedule_delayed_work(&info->hpdet_work,
 971                                              msecs_to_jiffies(HPDET_DEBOUNCE));
 972
 973                if (cancelled_mic)
 974                        schedule_delayed_work(&info->micd_timeout_work,
 975                                              msecs_to_jiffies(info->micd_timeout));
 976
 977                goto out;
 978        }
 979        info->last_jackdet = val;
 980
 981        if (info->last_jackdet == present) {
 982                dev_dbg(arizona->dev, "Detected jack\n");
 983                ret = extcon_set_cable_state_(&info->edev,
 984                                              ARIZONA_CABLE_MECHANICAL, true);
 985
 986                if (ret != 0)
 987                        dev_err(arizona->dev, "Mechanical report failed: %d\n",
 988                                ret);
 989
 990                if (!arizona->pdata.hpdet_acc_id) {
 991                        info->detecting = true;
 992                        info->mic = false;
 993                        info->jack_flips = 0;
 994
 995                        arizona_start_mic(info);
 996                } else {
 997                        schedule_delayed_work(&info->hpdet_work,
 998                                              msecs_to_jiffies(HPDET_DEBOUNCE));
 999                }
1000
1001                regmap_update_bits(arizona->regmap,
1002                                   ARIZONA_JACK_DETECT_DEBOUNCE,
1003                                   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0);
1004        } else {
1005                dev_dbg(arizona->dev, "Detected jack removal\n");
1006
1007                arizona_stop_mic(info);
1008
1009                info->num_hpdet_res = 0;
1010                for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
1011                        info->hpdet_res[i] = 0;
1012                info->mic = false;
1013                info->hpdet_done = false;
1014                info->hpdet_retried = false;
1015
1016                for (i = 0; i < info->num_micd_ranges; i++)
1017                        input_report_key(info->input,
1018                                         info->micd_ranges[i].key, 0);
1019                input_sync(info->input);
1020
1021                ret = extcon_update_state(&info->edev, 0xffffffff, 0);
1022                if (ret != 0)
1023                        dev_err(arizona->dev, "Removal report failed: %d\n",
1024                                ret);
1025
1026                regmap_update_bits(arizona->regmap,
1027                                   ARIZONA_JACK_DETECT_DEBOUNCE,
1028                                   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
1029                                   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
1030        }
1031
1032        if (arizona->pdata.micd_timeout)
1033                info->micd_timeout = arizona->pdata.micd_timeout;
1034        else
1035                info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1036
1037        /* Clear trig_sts to make sure DCVDD is not forced up */
1038        regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1039                     ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
1040                     ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
1041                     ARIZONA_JD1_FALL_TRIG_STS |
1042                     ARIZONA_JD1_RISE_TRIG_STS);
1043
1044out:
1045        mutex_unlock(&info->lock);
1046
1047        pm_runtime_mark_last_busy(info->dev);
1048        pm_runtime_put_autosuspend(info->dev);
1049
1050        return IRQ_HANDLED;
1051}
1052
1053/* Map a level onto a slot in the register bank */
1054static void arizona_micd_set_level(struct arizona *arizona, int index,
1055                                   unsigned int level)
1056{
1057        int reg;
1058        unsigned int mask;
1059
1060        reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1061
1062        if (!(index % 2)) {
1063                mask = 0x3f00;
1064                level <<= 8;
1065        } else {
1066                mask = 0x3f;
1067        }
1068
1069        /* Program the level itself */
1070        regmap_update_bits(arizona->regmap, reg, mask, level);
1071}
1072
1073static int arizona_extcon_probe(struct platform_device *pdev)
1074{
1075        struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1076        struct arizona_pdata *pdata;
1077        struct arizona_extcon_info *info;
1078        unsigned int val;
1079        int jack_irq_fall, jack_irq_rise;
1080        int ret, mode, i, j;
1081
1082        if (!arizona->dapm || !arizona->dapm->card)
1083                return -EPROBE_DEFER;
1084
1085        pdata = dev_get_platdata(arizona->dev);
1086
1087        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
1088        if (!info) {
1089                dev_err(&pdev->dev, "Failed to allocate memory\n");
1090                ret = -ENOMEM;
1091                goto err;
1092        }
1093
1094        info->micvdd = devm_regulator_get(arizona->dev, "MICVDD");
1095        if (IS_ERR(info->micvdd)) {
1096                ret = PTR_ERR(info->micvdd);
1097                dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
1098                goto err;
1099        }
1100
1101        mutex_init(&info->lock);
1102        info->arizona = arizona;
1103        info->dev = &pdev->dev;
1104        info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
1105        INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
1106        INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
1107        INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
1108        platform_set_drvdata(pdev, info);
1109
1110        switch (arizona->type) {
1111        case WM5102:
1112                switch (arizona->rev) {
1113                case 0:
1114                        info->micd_reva = true;
1115                        break;
1116                default:
1117                        info->micd_clamp = true;
1118                        info->hpdet_ip = 1;
1119                        break;
1120                }
1121                break;
1122        default:
1123                break;
1124        }
1125
1126        info->edev.name = "Headset Jack";
1127        info->edev.supported_cable = arizona_cable;
1128
1129        ret = extcon_dev_register(&info->edev, arizona->dev);
1130        if (ret < 0) {
1131                dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
1132                        ret);
1133                goto err;
1134        }
1135
1136        info->input = devm_input_allocate_device(&pdev->dev);
1137        if (!info->input) {
1138                dev_err(arizona->dev, "Can't allocate input dev\n");
1139                ret = -ENOMEM;
1140                goto err_register;
1141        }
1142
1143        info->input->name = "Headset";
1144        info->input->phys = "arizona/extcon";
1145        info->input->dev.parent = &pdev->dev;
1146
1147        if (pdata->num_micd_configs) {
1148                info->micd_modes = pdata->micd_configs;
1149                info->micd_num_modes = pdata->num_micd_configs;
1150        } else {
1151                info->micd_modes = micd_default_modes;
1152                info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
1153        }
1154
1155        if (arizona->pdata.micd_pol_gpio > 0) {
1156                if (info->micd_modes[0].gpio)
1157                        mode = GPIOF_OUT_INIT_HIGH;
1158                else
1159                        mode = GPIOF_OUT_INIT_LOW;
1160
1161                ret = devm_gpio_request_one(&pdev->dev,
1162                                            arizona->pdata.micd_pol_gpio,
1163                                            mode,
1164                                            "MICD polarity");
1165                if (ret != 0) {
1166                        dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1167                                arizona->pdata.micd_pol_gpio, ret);
1168                        goto err_register;
1169                }
1170        }
1171
1172        if (arizona->pdata.hpdet_id_gpio > 0) {
1173                ret = devm_gpio_request_one(&pdev->dev,
1174                                            arizona->pdata.hpdet_id_gpio,
1175                                            GPIOF_OUT_INIT_LOW,
1176                                            "HPDET");
1177                if (ret != 0) {
1178                        dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1179                                arizona->pdata.hpdet_id_gpio, ret);
1180                        goto err_register;
1181                }
1182        }
1183
1184        if (arizona->pdata.micd_bias_start_time)
1185                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1186                                   ARIZONA_MICD_BIAS_STARTTIME_MASK,
1187                                   arizona->pdata.micd_bias_start_time
1188                                   << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
1189
1190        if (arizona->pdata.micd_rate)
1191                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1192                                   ARIZONA_MICD_RATE_MASK,
1193                                   arizona->pdata.micd_rate
1194                                   << ARIZONA_MICD_RATE_SHIFT);
1195
1196        if (arizona->pdata.micd_dbtime)
1197                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1198                                   ARIZONA_MICD_DBTIME_MASK,
1199                                   arizona->pdata.micd_dbtime
1200                                   << ARIZONA_MICD_DBTIME_SHIFT);
1201
1202        BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40);
1203
1204        if (arizona->pdata.num_micd_ranges) {
1205                info->micd_ranges = pdata->micd_ranges;
1206                info->num_micd_ranges = pdata->num_micd_ranges;
1207        } else {
1208                info->micd_ranges = micd_default_ranges;
1209                info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1210        }
1211
1212        if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1213                dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1214                        arizona->pdata.num_micd_ranges);
1215        }
1216
1217        if (info->num_micd_ranges > 1) {
1218                for (i = 1; i < info->num_micd_ranges; i++) {
1219                        if (info->micd_ranges[i - 1].max >
1220                            info->micd_ranges[i].max) {
1221                                dev_err(arizona->dev,
1222                                        "MICD ranges must be sorted\n");
1223                                ret = -EINVAL;
1224                                goto err_input;
1225                        }
1226                }
1227        }
1228
1229        /* Disable all buttons by default */
1230        regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1231                           ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1232
1233        /* Set up all the buttons the user specified */
1234        for (i = 0; i < info->num_micd_ranges; i++) {
1235                for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++)
1236                        if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1237                                break;
1238
1239                if (j == ARRAY_SIZE(arizona_micd_levels)) {
1240                        dev_err(arizona->dev, "Unsupported MICD level %d\n",
1241                                info->micd_ranges[i].max);
1242                        ret = -EINVAL;
1243                        goto err_input;
1244                }
1245
1246                dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1247                        arizona_micd_levels[j], i);
1248
1249                arizona_micd_set_level(arizona, i, j);
1250                input_set_capability(info->input, EV_KEY,
1251                                     info->micd_ranges[i].key);
1252
1253                /* Enable reporting of that range */
1254                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1255                                   1 << i, 1 << i);
1256        }
1257
1258        /* Set all the remaining keys to a maximum */
1259        for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1260                arizona_micd_set_level(arizona, i, 0x3f);
1261
1262        /*
1263         * If we have a clamp use it, activating in conjunction with
1264         * GPIO5 if that is connected for jack detect operation.
1265         */
1266        if (info->micd_clamp) {
1267                if (arizona->pdata.jd_gpio5) {
1268                        /* Put the GPIO into input mode with optional pull */
1269                        val = 0xc101;
1270                        if (arizona->pdata.jd_gpio5_nopull)
1271                                val &= ~ARIZONA_GPN_PU;
1272
1273                        regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
1274                                     val);
1275
1276                        regmap_update_bits(arizona->regmap,
1277                                           ARIZONA_MICD_CLAMP_CONTROL,
1278                                           ARIZONA_MICD_CLAMP_MODE_MASK, 0x9);
1279                } else {
1280                        regmap_update_bits(arizona->regmap,
1281                                           ARIZONA_MICD_CLAMP_CONTROL,
1282                                           ARIZONA_MICD_CLAMP_MODE_MASK, 0x4);
1283                }
1284
1285                regmap_update_bits(arizona->regmap,
1286                                   ARIZONA_JACK_DETECT_DEBOUNCE,
1287                                   ARIZONA_MICD_CLAMP_DB,
1288                                   ARIZONA_MICD_CLAMP_DB);
1289        }
1290
1291        arizona_extcon_set_mode(info, 0);
1292
1293        pm_runtime_enable(&pdev->dev);
1294        pm_runtime_idle(&pdev->dev);
1295        pm_runtime_get_sync(&pdev->dev);
1296
1297        if (arizona->pdata.jd_gpio5) {
1298                jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1299                jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1300        } else {
1301                jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1302                jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1303        }
1304
1305        ret = arizona_request_irq(arizona, jack_irq_rise,
1306                                  "JACKDET rise", arizona_jackdet, info);
1307        if (ret != 0) {
1308                dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
1309                        ret);
1310                goto err_input;
1311        }
1312
1313        ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
1314        if (ret != 0) {
1315                dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
1316                        ret);
1317                goto err_rise;
1318        }
1319
1320        ret = arizona_request_irq(arizona, jack_irq_fall,
1321                                  "JACKDET fall", arizona_jackdet, info);
1322        if (ret != 0) {
1323                dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
1324                goto err_rise_wake;
1325        }
1326
1327        ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
1328        if (ret != 0) {
1329                dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
1330                        ret);
1331                goto err_fall;
1332        }
1333
1334        ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
1335                                  "MICDET", arizona_micdet, info);
1336        if (ret != 0) {
1337                dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
1338                goto err_fall_wake;
1339        }
1340
1341        ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
1342                                  "HPDET", arizona_hpdet_irq, info);
1343        if (ret != 0) {
1344                dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
1345                goto err_micdet;
1346        }
1347
1348        arizona_clk32k_enable(arizona);
1349        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
1350                           ARIZONA_JD1_DB, ARIZONA_JD1_DB);
1351        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1352                           ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
1353
1354        ret = regulator_allow_bypass(info->micvdd, true);
1355        if (ret != 0)
1356                dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
1357                         ret);
1358
1359        pm_runtime_put(&pdev->dev);
1360
1361        ret = input_register_device(info->input);
1362        if (ret) {
1363                dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
1364                goto err_hpdet;
1365        }
1366
1367        return 0;
1368
1369err_hpdet:
1370        arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
1371err_micdet:
1372        arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
1373err_fall_wake:
1374        arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1375err_fall:
1376        arizona_free_irq(arizona, jack_irq_fall, info);
1377err_rise_wake:
1378        arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1379err_rise:
1380        arizona_free_irq(arizona, jack_irq_rise, info);
1381err_input:
1382err_register:
1383        pm_runtime_disable(&pdev->dev);
1384        extcon_dev_unregister(&info->edev);
1385err:
1386        return ret;
1387}
1388
1389static int arizona_extcon_remove(struct platform_device *pdev)
1390{
1391        struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1392        struct arizona *arizona = info->arizona;
1393        int jack_irq_rise, jack_irq_fall;
1394
1395        pm_runtime_disable(&pdev->dev);
1396
1397        regmap_update_bits(arizona->regmap,
1398                           ARIZONA_MICD_CLAMP_CONTROL,
1399                           ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1400
1401        if (arizona->pdata.jd_gpio5) {
1402                jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1403                jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1404        } else {
1405                jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1406                jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1407        }
1408
1409        arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1410        arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1411        arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
1412        arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
1413        arizona_free_irq(arizona, jack_irq_rise, info);
1414        arizona_free_irq(arizona, jack_irq_fall, info);
1415        cancel_delayed_work_sync(&info->hpdet_work);
1416        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1417                           ARIZONA_JD1_ENA, 0);
1418        arizona_clk32k_disable(arizona);
1419        extcon_dev_unregister(&info->edev);
1420
1421        return 0;
1422}
1423
1424static struct platform_driver arizona_extcon_driver = {
1425        .driver         = {
1426                .name   = "arizona-extcon",
1427                .owner  = THIS_MODULE,
1428        },
1429        .probe          = arizona_extcon_probe,
1430        .remove         = arizona_extcon_remove,
1431};
1432
1433module_platform_driver(arizona_extcon_driver);
1434
1435MODULE_DESCRIPTION("Arizona Extcon driver");
1436MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1437MODULE_LICENSE("GPL");
1438MODULE_ALIAS("platform:extcon-arizona");
1439
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.