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                queue_delayed_work(system_power_efficient_wq,
 894                                   &info->micd_timeout_work,
 895                                   msecs_to_jiffies(info->micd_timeout));
 896
 897        pm_runtime_mark_last_busy(info->dev);
 898        mutex_unlock(&info->lock);
 899}
 900
 901static irqreturn_t arizona_micdet(int irq, void *data)
 902{
 903        struct arizona_extcon_info *info = data;
 904        struct arizona *arizona = info->arizona;
 905        int debounce = arizona->pdata.micd_detect_debounce;
 906
 907        cancel_delayed_work_sync(&info->micd_detect_work);
 908        cancel_delayed_work_sync(&info->micd_timeout_work);
 909
 910        mutex_lock(&info->lock);
 911        if (!info->detecting)
 912                debounce = 0;
 913        mutex_unlock(&info->lock);
 914
 915        if (debounce)
 916                queue_delayed_work(system_power_efficient_wq,
 917                                   &info->micd_detect_work,
 918                                   msecs_to_jiffies(debounce));
 919        else
 920                arizona_micd_detect(&info->micd_detect_work.work);
 921
 922        return IRQ_HANDLED;
 923}
 924
 925static void arizona_hpdet_work(struct work_struct *work)
 926{
 927        struct arizona_extcon_info *info = container_of(work,
 928                                                        struct arizona_extcon_info,
 929                                                        hpdet_work.work);
 930
 931        mutex_lock(&info->lock);
 932        arizona_start_hpdet_acc_id(info);
 933        mutex_unlock(&info->lock);
 934}
 935
 936static irqreturn_t arizona_jackdet(int irq, void *data)
 937{
 938        struct arizona_extcon_info *info = data;
 939        struct arizona *arizona = info->arizona;
 940        unsigned int val, present, mask;
 941        bool cancelled_hp, cancelled_mic;
 942        int ret, i;
 943
 944        cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
 945        cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
 946
 947        pm_runtime_get_sync(info->dev);
 948
 949        mutex_lock(&info->lock);
 950
 951        if (arizona->pdata.jd_gpio5) {
 952                mask = ARIZONA_MICD_CLAMP_STS;
 953                present = 0;
 954        } else {
 955                mask = ARIZONA_JD1_STS;
 956                present = ARIZONA_JD1_STS;
 957        }
 958
 959        ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
 960        if (ret != 0) {
 961                dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
 962                        ret);
 963                mutex_unlock(&info->lock);
 964                pm_runtime_put_autosuspend(info->dev);
 965                return IRQ_NONE;
 966        }
 967
 968        val &= mask;
 969        if (val == info->last_jackdet) {
 970                dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
 971                if (cancelled_hp)
 972                        queue_delayed_work(system_power_efficient_wq,
 973                                           &info->hpdet_work,
 974                                           msecs_to_jiffies(HPDET_DEBOUNCE));
 975
 976                if (cancelled_mic)
 977                        queue_delayed_work(system_power_efficient_wq,
 978                                           &info->micd_timeout_work,
 979                                           msecs_to_jiffies(info->micd_timeout));
 980
 981                goto out;
 982        }
 983        info->last_jackdet = val;
 984
 985        if (info->last_jackdet == present) {
 986                dev_dbg(arizona->dev, "Detected jack\n");
 987                ret = extcon_set_cable_state_(&info->edev,
 988                                              ARIZONA_CABLE_MECHANICAL, true);
 989
 990                if (ret != 0)
 991                        dev_err(arizona->dev, "Mechanical report failed: %d\n",
 992                                ret);
 993
 994                if (!arizona->pdata.hpdet_acc_id) {
 995                        info->detecting = true;
 996                        info->mic = false;
 997                        info->jack_flips = 0;
 998
 999                        arizona_start_mic(info);
1000                } else {
1001                        queue_delayed_work(system_power_efficient_wq,
1002                                           &info->hpdet_work,
1003                                           msecs_to_jiffies(HPDET_DEBOUNCE));
1004                }
1005
1006                regmap_update_bits(arizona->regmap,
1007                                   ARIZONA_JACK_DETECT_DEBOUNCE,
1008                                   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0);
1009        } else {
1010                dev_dbg(arizona->dev, "Detected jack removal\n");
1011
1012                arizona_stop_mic(info);
1013
1014                info->num_hpdet_res = 0;
1015                for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
1016                        info->hpdet_res[i] = 0;
1017                info->mic = false;
1018                info->hpdet_done = false;
1019                info->hpdet_retried = false;
1020
1021                for (i = 0; i < info->num_micd_ranges; i++)
1022                        input_report_key(info->input,
1023                                         info->micd_ranges[i].key, 0);
1024                input_sync(info->input);
1025
1026                ret = extcon_update_state(&info->edev, 0xffffffff, 0);
1027                if (ret != 0)
1028                        dev_err(arizona->dev, "Removal report failed: %d\n",
1029                                ret);
1030
1031                regmap_update_bits(arizona->regmap,
1032                                   ARIZONA_JACK_DETECT_DEBOUNCE,
1033                                   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
1034                                   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
1035        }
1036
1037        if (arizona->pdata.micd_timeout)
1038                info->micd_timeout = arizona->pdata.micd_timeout;
1039        else
1040                info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1041
1042        /* Clear trig_sts to make sure DCVDD is not forced up */
1043        regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1044                     ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
1045                     ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
1046                     ARIZONA_JD1_FALL_TRIG_STS |
1047                     ARIZONA_JD1_RISE_TRIG_STS);
1048
1049out:
1050        mutex_unlock(&info->lock);
1051
1052        pm_runtime_mark_last_busy(info->dev);
1053        pm_runtime_put_autosuspend(info->dev);
1054
1055        return IRQ_HANDLED;
1056}
1057
1058/* Map a level onto a slot in the register bank */
1059static void arizona_micd_set_level(struct arizona *arizona, int index,
1060                                   unsigned int level)
1061{
1062        int reg;
1063        unsigned int mask;
1064
1065        reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1066
1067        if (!(index % 2)) {
1068                mask = 0x3f00;
1069                level <<= 8;
1070        } else {
1071                mask = 0x3f;
1072        }
1073
1074        /* Program the level itself */
1075        regmap_update_bits(arizona->regmap, reg, mask, level);
1076}
1077
1078static int arizona_extcon_probe(struct platform_device *pdev)
1079{
1080        struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1081        struct arizona_pdata *pdata;
1082        struct arizona_extcon_info *info;
1083        unsigned int val;
1084        int jack_irq_fall, jack_irq_rise;
1085        int ret, mode, i, j;
1086
1087        if (!arizona->dapm || !arizona->dapm->card)
1088                return -EPROBE_DEFER;
1089
1090        pdata = dev_get_platdata(arizona->dev);
1091
1092        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
1093        if (!info) {
1094                dev_err(&pdev->dev, "Failed to allocate memory\n");
1095                ret = -ENOMEM;
1096                goto err;
1097        }
1098
1099        info->micvdd = devm_regulator_get(arizona->dev, "MICVDD");
1100        if (IS_ERR(info->micvdd)) {
1101                ret = PTR_ERR(info->micvdd);
1102                dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
1103                goto err;
1104        }
1105
1106        mutex_init(&info->lock);
1107        info->arizona = arizona;
1108        info->dev = &pdev->dev;
1109        info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
1110        INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
1111        INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
1112        INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
1113        platform_set_drvdata(pdev, info);
1114
1115        switch (arizona->type) {
1116        case WM5102:
1117                switch (arizona->rev) {
1118                case 0:
1119                        info->micd_reva = true;
1120                        break;
1121                default:
1122                        info->micd_clamp = true;
1123                        info->hpdet_ip = 1;
1124                        break;
1125                }
1126                break;
1127        default:
1128                break;
1129        }
1130
1131        info->edev.name = "Headset Jack";
1132        info->edev.supported_cable = arizona_cable;
1133
1134        ret = extcon_dev_register(&info->edev, arizona->dev);
1135        if (ret < 0) {
1136                dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
1137                        ret);
1138                goto err;
1139        }
1140
1141        info->input = devm_input_allocate_device(&pdev->dev);
1142        if (!info->input) {
1143                dev_err(arizona->dev, "Can't allocate input dev\n");
1144                ret = -ENOMEM;
1145                goto err_register;
1146        }
1147
1148        info->input->name = "Headset";
1149        info->input->phys = "arizona/extcon";
1150        info->input->dev.parent = &pdev->dev;
1151
1152        if (pdata->num_micd_configs) {
1153                info->micd_modes = pdata->micd_configs;
1154                info->micd_num_modes = pdata->num_micd_configs;
1155        } else {
1156                info->micd_modes = micd_default_modes;
1157                info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
1158        }
1159
1160        if (arizona->pdata.micd_pol_gpio > 0) {
1161                if (info->micd_modes[0].gpio)
1162                        mode = GPIOF_OUT_INIT_HIGH;
1163                else
1164                        mode = GPIOF_OUT_INIT_LOW;
1165
1166                ret = devm_gpio_request_one(&pdev->dev,
1167                                            arizona->pdata.micd_pol_gpio,
1168                                            mode,
1169                                            "MICD polarity");
1170                if (ret != 0) {
1171                        dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1172                                arizona->pdata.micd_pol_gpio, ret);
1173                        goto err_register;
1174                }
1175        }
1176
1177        if (arizona->pdata.hpdet_id_gpio > 0) {
1178                ret = devm_gpio_request_one(&pdev->dev,
1179                                            arizona->pdata.hpdet_id_gpio,
1180                                            GPIOF_OUT_INIT_LOW,
1181                                            "HPDET");
1182                if (ret != 0) {
1183                        dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1184                                arizona->pdata.hpdet_id_gpio, ret);
1185                        goto err_register;
1186                }
1187        }
1188
1189        if (arizona->pdata.micd_bias_start_time)
1190                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1191                                   ARIZONA_MICD_BIAS_STARTTIME_MASK,
1192                                   arizona->pdata.micd_bias_start_time
1193                                   << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
1194
1195        if (arizona->pdata.micd_rate)
1196                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1197                                   ARIZONA_MICD_RATE_MASK,
1198                                   arizona->pdata.micd_rate
1199                                   << ARIZONA_MICD_RATE_SHIFT);
1200
1201        if (arizona->pdata.micd_dbtime)
1202                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1203                                   ARIZONA_MICD_DBTIME_MASK,
1204                                   arizona->pdata.micd_dbtime
1205                                   << ARIZONA_MICD_DBTIME_SHIFT);
1206
1207        BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40);
1208
1209        if (arizona->pdata.num_micd_ranges) {
1210                info->micd_ranges = pdata->micd_ranges;
1211                info->num_micd_ranges = pdata->num_micd_ranges;
1212        } else {
1213                info->micd_ranges = micd_default_ranges;
1214                info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1215        }
1216
1217        if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1218                dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1219                        arizona->pdata.num_micd_ranges);
1220        }
1221
1222        if (info->num_micd_ranges > 1) {
1223                for (i = 1; i < info->num_micd_ranges; i++) {
1224                        if (info->micd_ranges[i - 1].max >
1225                            info->micd_ranges[i].max) {
1226                                dev_err(arizona->dev,
1227                                        "MICD ranges must be sorted\n");
1228                                ret = -EINVAL;
1229                                goto err_input;
1230                        }
1231                }
1232        }
1233
1234        /* Disable all buttons by default */
1235        regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1236                           ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1237
1238        /* Set up all the buttons the user specified */
1239        for (i = 0; i < info->num_micd_ranges; i++) {
1240                for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++)
1241                        if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1242                                break;
1243
1244                if (j == ARRAY_SIZE(arizona_micd_levels)) {
1245                        dev_err(arizona->dev, "Unsupported MICD level %d\n",
1246                                info->micd_ranges[i].max);
1247                        ret = -EINVAL;
1248                        goto err_input;
1249                }
1250
1251                dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1252                        arizona_micd_levels[j], i);
1253
1254                arizona_micd_set_level(arizona, i, j);
1255                input_set_capability(info->input, EV_KEY,
1256                                     info->micd_ranges[i].key);
1257
1258                /* Enable reporting of that range */
1259                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1260                                   1 << i, 1 << i);
1261        }
1262
1263        /* Set all the remaining keys to a maximum */
1264        for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1265                arizona_micd_set_level(arizona, i, 0x3f);
1266
1267        /*
1268         * If we have a clamp use it, activating in conjunction with
1269         * GPIO5 if that is connected for jack detect operation.
1270         */
1271        if (info->micd_clamp) {
1272                if (arizona->pdata.jd_gpio5) {
1273                        /* Put the GPIO into input mode with optional pull */
1274                        val = 0xc101;
1275                        if (arizona->pdata.jd_gpio5_nopull)
1276                                val &= ~ARIZONA_GPN_PU;
1277
1278                        regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
1279                                     val);
1280
1281                        regmap_update_bits(arizona->regmap,
1282                                           ARIZONA_MICD_CLAMP_CONTROL,
1283                                           ARIZONA_MICD_CLAMP_MODE_MASK, 0x9);
1284                } else {
1285                        regmap_update_bits(arizona->regmap,
1286                                           ARIZONA_MICD_CLAMP_CONTROL,
1287                                           ARIZONA_MICD_CLAMP_MODE_MASK, 0x4);
1288                }
1289
1290                regmap_update_bits(arizona->regmap,
1291                                   ARIZONA_JACK_DETECT_DEBOUNCE,
1292                                   ARIZONA_MICD_CLAMP_DB,
1293                                   ARIZONA_MICD_CLAMP_DB);
1294        }
1295
1296        arizona_extcon_set_mode(info, 0);
1297
1298        pm_runtime_enable(&pdev->dev);
1299        pm_runtime_idle(&pdev->dev);
1300        pm_runtime_get_sync(&pdev->dev);
1301
1302        if (arizona->pdata.jd_gpio5) {
1303                jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1304                jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1305        } else {
1306                jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1307                jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1308        }
1309
1310        ret = arizona_request_irq(arizona, jack_irq_rise,
1311                                  "JACKDET rise", arizona_jackdet, info);
1312        if (ret != 0) {
1313                dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
1314                        ret);
1315                goto err_input;
1316        }
1317
1318        ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
1319        if (ret != 0) {
1320                dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
1321                        ret);
1322                goto err_rise;
1323        }
1324
1325        ret = arizona_request_irq(arizona, jack_irq_fall,
1326                                  "JACKDET fall", arizona_jackdet, info);
1327        if (ret != 0) {
1328                dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
1329                goto err_rise_wake;
1330        }
1331
1332        ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
1333        if (ret != 0) {
1334                dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
1335                        ret);
1336                goto err_fall;
1337        }
1338
1339        ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
1340                                  "MICDET", arizona_micdet, info);
1341        if (ret != 0) {
1342                dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
1343                goto err_fall_wake;
1344        }
1345
1346        ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
1347                                  "HPDET", arizona_hpdet_irq, info);
1348        if (ret != 0) {
1349                dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
1350                goto err_micdet;
1351        }
1352
1353        arizona_clk32k_enable(arizona);
1354        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
1355                           ARIZONA_JD1_DB, ARIZONA_JD1_DB);
1356        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1357                           ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
1358
1359        ret = regulator_allow_bypass(info->micvdd, true);
1360        if (ret != 0)
1361                dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
1362                         ret);
1363
1364        pm_runtime_put(&pdev->dev);
1365
1366        ret = input_register_device(info->input);
1367        if (ret) {
1368                dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
1369                goto err_hpdet;
1370        }
1371
1372        return 0;
1373
1374err_hpdet:
1375        arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
1376err_micdet:
1377        arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
1378err_fall_wake:
1379        arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1380err_fall:
1381        arizona_free_irq(arizona, jack_irq_fall, info);
1382err_rise_wake:
1383        arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1384err_rise:
1385        arizona_free_irq(arizona, jack_irq_rise, info);
1386err_input:
1387err_register:
1388        pm_runtime_disable(&pdev->dev);
1389        extcon_dev_unregister(&info->edev);
1390err:
1391        return ret;
1392}
1393
1394static int arizona_extcon_remove(struct platform_device *pdev)
1395{
1396        struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1397        struct arizona *arizona = info->arizona;
1398        int jack_irq_rise, jack_irq_fall;
1399
1400        pm_runtime_disable(&pdev->dev);
1401
1402        regmap_update_bits(arizona->regmap,
1403                           ARIZONA_MICD_CLAMP_CONTROL,
1404                           ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1405
1406        if (arizona->pdata.jd_gpio5) {
1407                jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1408                jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1409        } else {
1410                jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1411                jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1412        }
1413
1414        arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1415        arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1416        arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
1417        arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
1418        arizona_free_irq(arizona, jack_irq_rise, info);
1419        arizona_free_irq(arizona, jack_irq_fall, info);
1420        cancel_delayed_work_sync(&info->hpdet_work);
1421        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1422                           ARIZONA_JD1_ENA, 0);
1423        arizona_clk32k_disable(arizona);
1424        extcon_dev_unregister(&info->edev);
1425
1426        return 0;
1427}
1428
1429static struct platform_driver arizona_extcon_driver = {
1430        .driver         = {
1431                .name   = "arizona-extcon",
1432                .owner  = THIS_MODULE,
1433        },
1434        .probe          = arizona_extcon_probe,
1435        .remove         = arizona_extcon_remove,
1436};
1437
1438module_platform_driver(arizona_extcon_driver);
1439
1440MODULE_DESCRIPTION("Arizona Extcon driver");
1441MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1442MODULE_LICENSE("GPL");
1443MODULE_ALIAS("platform:extcon-arizona");
1444
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.