linux/drivers/extcon/extcon-arizona.c
<<
>>
Prefs
   1/*
   2 * extcon-arizona.c - Extcon driver Wolfson Arizona devices
   3 *
   4 *  Copyright (C) 2012-2014 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/consumer.h>
  24#include <linux/gpio.h>
  25#include <linux/input.h>
  26#include <linux/platform_device.h>
  27#include <linux/pm_runtime.h>
  28#include <linux/property.h>
  29#include <linux/regulator/consumer.h>
  30#include <linux/extcon.h>
  31
  32#include <sound/soc.h>
  33
  34#include <linux/mfd/arizona/core.h>
  35#include <linux/mfd/arizona/pdata.h>
  36#include <linux/mfd/arizona/registers.h>
  37#include <dt-bindings/mfd/arizona.h>
  38
  39#define ARIZONA_MAX_MICD_RANGE 8
  40
  41#define ARIZONA_MICD_CLAMP_MODE_JDL      0x4
  42#define ARIZONA_MICD_CLAMP_MODE_JDH      0x5
  43#define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9
  44#define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb
  45
  46#define ARIZONA_TST_CAP_DEFAULT 0x3
  47#define ARIZONA_TST_CAP_CLAMP   0x1
  48
  49#define ARIZONA_HPDET_MAX 10000
  50
  51#define HPDET_DEBOUNCE 500
  52#define DEFAULT_MICD_TIMEOUT 2000
  53
  54#define ARIZONA_HPDET_WAIT_COUNT 15
  55#define ARIZONA_HPDET_WAIT_DELAY_MS 20
  56
  57#define QUICK_HEADPHONE_MAX_OHM 3
  58#define MICROPHONE_MIN_OHM      1257
  59#define MICROPHONE_MAX_OHM      30000
  60
  61#define MICD_DBTIME_TWO_READINGS 2
  62#define MICD_DBTIME_FOUR_READINGS 4
  63
  64#define MICD_LVL_1_TO_7 (ARIZONA_MICD_LVL_1 | ARIZONA_MICD_LVL_2 | \
  65                         ARIZONA_MICD_LVL_3 | ARIZONA_MICD_LVL_4 | \
  66                         ARIZONA_MICD_LVL_5 | ARIZONA_MICD_LVL_6 | \
  67                         ARIZONA_MICD_LVL_7)
  68
  69#define MICD_LVL_0_TO_7 (ARIZONA_MICD_LVL_0 | MICD_LVL_1_TO_7)
  70
  71#define MICD_LVL_0_TO_8 (MICD_LVL_0_TO_7 | ARIZONA_MICD_LVL_8)
  72
  73struct arizona_extcon_info {
  74        struct device *dev;
  75        struct arizona *arizona;
  76        struct mutex lock;
  77        struct regulator *micvdd;
  78        struct input_dev *input;
  79
  80        u16 last_jackdet;
  81
  82        int micd_mode;
  83        const struct arizona_micd_config *micd_modes;
  84        int micd_num_modes;
  85
  86        const struct arizona_micd_range *micd_ranges;
  87        int num_micd_ranges;
  88
  89        int micd_timeout;
  90
  91        bool micd_reva;
  92        bool micd_clamp;
  93
  94        struct delayed_work hpdet_work;
  95        struct delayed_work micd_detect_work;
  96        struct delayed_work micd_timeout_work;
  97
  98        bool hpdet_active;
  99        bool hpdet_done;
 100        bool hpdet_retried;
 101
 102        int num_hpdet_res;
 103        unsigned int hpdet_res[3];
 104
 105        bool mic;
 106        bool detecting;
 107        int jack_flips;
 108
 109        int hpdet_ip_version;
 110
 111        struct extcon_dev *edev;
 112
 113        struct gpio_desc *micd_pol_gpio;
 114};
 115
 116static const struct arizona_micd_config micd_default_modes[] = {
 117        { ARIZONA_ACCDET_SRC, 1, 0 },
 118        { 0,                  2, 1 },
 119};
 120
 121static const struct arizona_micd_range micd_default_ranges[] = {
 122        { .max =  11, .key = BTN_0 },
 123        { .max =  28, .key = BTN_1 },
 124        { .max =  54, .key = BTN_2 },
 125        { .max = 100, .key = BTN_3 },
 126        { .max = 186, .key = BTN_4 },
 127        { .max = 430, .key = BTN_5 },
 128};
 129
 130/* The number of levels in arizona_micd_levels valid for button thresholds */
 131#define ARIZONA_NUM_MICD_BUTTON_LEVELS 64
 132
 133static const int arizona_micd_levels[] = {
 134        3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
 135        49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
 136        105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
 137        270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
 138        1257, 30000,
 139};
 140
 141static const unsigned int arizona_cable[] = {
 142        EXTCON_MECHANICAL,
 143        EXTCON_JACK_MICROPHONE,
 144        EXTCON_JACK_HEADPHONE,
 145        EXTCON_JACK_LINE_OUT,
 146        EXTCON_NONE,
 147};
 148
 149static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info);
 150
 151static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info,
 152                                    bool clamp)
 153{
 154        struct arizona *arizona = info->arizona;
 155        unsigned int mask = 0, val = 0;
 156        unsigned int cap_sel = 0;
 157        int ret;
 158
 159        switch (arizona->type) {
 160        case WM8998:
 161        case WM1814:
 162                mask = 0;
 163                break;
 164        case WM5110:
 165        case WM8280:
 166                mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR |
 167                       ARIZONA_HP1L_SHRTI;
 168                if (clamp) {
 169                        val = ARIZONA_HP1L_SHRTO;
 170                        cap_sel = ARIZONA_TST_CAP_CLAMP;
 171                } else {
 172                        val = ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI;
 173                        cap_sel = ARIZONA_TST_CAP_DEFAULT;
 174                }
 175
 176                ret = regmap_update_bits(arizona->regmap,
 177                                         ARIZONA_HP_TEST_CTRL_1,
 178                                         ARIZONA_HP1_TST_CAP_SEL_MASK,
 179                                         cap_sel);
 180                if (ret != 0)
 181                        dev_warn(arizona->dev,
 182                                 "Failed to set TST_CAP_SEL: %d\n", ret);
 183                break;
 184        default:
 185                mask = ARIZONA_RMV_SHRT_HP1L;
 186                if (clamp)
 187                        val = ARIZONA_RMV_SHRT_HP1L;
 188                break;
 189        }
 190
 191        snd_soc_dapm_mutex_lock(arizona->dapm);
 192
 193        arizona->hpdet_clamp = clamp;
 194
 195        /* Keep the HP output stages disabled while doing the clamp */
 196        if (clamp) {
 197                ret = regmap_update_bits(arizona->regmap,
 198                                         ARIZONA_OUTPUT_ENABLES_1,
 199                                         ARIZONA_OUT1L_ENA |
 200                                         ARIZONA_OUT1R_ENA, 0);
 201                if (ret != 0)
 202                        dev_warn(arizona->dev,
 203                                "Failed to disable headphone outputs: %d\n",
 204                                 ret);
 205        }
 206
 207        if (mask) {
 208                ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1L,
 209                                         mask, val);
 210                if (ret != 0)
 211                        dev_warn(arizona->dev, "Failed to do clamp: %d\n",
 212                                 ret);
 213
 214                ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1R,
 215                                         mask, val);
 216                if (ret != 0)
 217                        dev_warn(arizona->dev, "Failed to do clamp: %d\n",
 218                                 ret);
 219        }
 220
 221        /* Restore the desired state while not doing the clamp */
 222        if (!clamp) {
 223                ret = regmap_update_bits(arizona->regmap,
 224                                         ARIZONA_OUTPUT_ENABLES_1,
 225                                         ARIZONA_OUT1L_ENA |
 226                                         ARIZONA_OUT1R_ENA, arizona->hp_ena);
 227                if (ret != 0)
 228                        dev_warn(arizona->dev,
 229                                 "Failed to restore headphone outputs: %d\n",
 230                                 ret);
 231        }
 232
 233        snd_soc_dapm_mutex_unlock(arizona->dapm);
 234}
 235
 236static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
 237{
 238        struct arizona *arizona = info->arizona;
 239
 240        mode %= info->micd_num_modes;
 241
 242        gpiod_set_value_cansleep(info->micd_pol_gpio,
 243                                 info->micd_modes[mode].gpio);
 244
 245        regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
 246                           ARIZONA_MICD_BIAS_SRC_MASK,
 247                           info->micd_modes[mode].bias <<
 248                           ARIZONA_MICD_BIAS_SRC_SHIFT);
 249        regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
 250                           ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
 251
 252        info->micd_mode = mode;
 253
 254        dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode);
 255}
 256
 257static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info)
 258{
 259        switch (info->micd_modes[0].bias) {
 260        case 1:
 261                return "MICBIAS1";
 262        case 2:
 263                return "MICBIAS2";
 264        case 3:
 265                return "MICBIAS3";
 266        default:
 267                return "MICVDD";
 268        }
 269}
 270
 271static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info)
 272{
 273        struct arizona *arizona = info->arizona;
 274        const char *widget = arizona_extcon_get_micbias(info);
 275        struct snd_soc_dapm_context *dapm = arizona->dapm;
 276        struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
 277        int ret;
 278
 279        ret = snd_soc_component_force_enable_pin(component, widget);
 280        if (ret != 0)
 281                dev_warn(arizona->dev, "Failed to enable %s: %d\n",
 282                         widget, ret);
 283
 284        snd_soc_dapm_sync(dapm);
 285
 286        if (!arizona->pdata.micd_force_micbias) {
 287                ret = snd_soc_component_disable_pin(component, widget);
 288                if (ret != 0)
 289                        dev_warn(arizona->dev, "Failed to disable %s: %d\n",
 290                                 widget, ret);
 291
 292                snd_soc_dapm_sync(dapm);
 293        }
 294}
 295
 296static void arizona_start_mic(struct arizona_extcon_info *info)
 297{
 298        struct arizona *arizona = info->arizona;
 299        bool change;
 300        int ret;
 301        unsigned int mode;
 302
 303        /* Microphone detection can't use idle mode */
 304        pm_runtime_get(info->dev);
 305
 306        if (info->detecting) {
 307                ret = regulator_allow_bypass(info->micvdd, false);
 308                if (ret != 0) {
 309                        dev_err(arizona->dev,
 310                                "Failed to regulate MICVDD: %d\n",
 311                                ret);
 312                }
 313        }
 314
 315        ret = regulator_enable(info->micvdd);
 316        if (ret != 0) {
 317                dev_err(arizona->dev, "Failed to enable MICVDD: %d\n",
 318                        ret);
 319        }
 320
 321        if (info->micd_reva) {
 322                regmap_write(arizona->regmap, 0x80, 0x3);
 323                regmap_write(arizona->regmap, 0x294, 0);
 324                regmap_write(arizona->regmap, 0x80, 0x0);
 325        }
 326
 327        if (info->detecting && arizona->pdata.micd_software_compare)
 328                mode = ARIZONA_ACCDET_MODE_ADC;
 329        else
 330                mode = ARIZONA_ACCDET_MODE_MIC;
 331
 332        regmap_update_bits(arizona->regmap,
 333                           ARIZONA_ACCESSORY_DETECT_MODE_1,
 334                           ARIZONA_ACCDET_MODE_MASK, mode);
 335
 336        arizona_extcon_pulse_micbias(info);
 337
 338        regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
 339                                 ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
 340                                 &change);
 341        if (!change) {
 342                regulator_disable(info->micvdd);
 343                pm_runtime_put_autosuspend(info->dev);
 344        }
 345}
 346
 347static void arizona_stop_mic(struct arizona_extcon_info *info)
 348{
 349        struct arizona *arizona = info->arizona;
 350        const char *widget = arizona_extcon_get_micbias(info);
 351        struct snd_soc_dapm_context *dapm = arizona->dapm;
 352        struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
 353        bool change;
 354        int ret;
 355
 356        regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
 357                                 ARIZONA_MICD_ENA, 0,
 358                                 &change);
 359
 360        ret = snd_soc_component_disable_pin(component, widget);
 361        if (ret != 0)
 362                dev_warn(arizona->dev,
 363                         "Failed to disable %s: %d\n",
 364                         widget, ret);
 365
 366        snd_soc_dapm_sync(dapm);
 367
 368        if (info->micd_reva) {
 369                regmap_write(arizona->regmap, 0x80, 0x3);
 370                regmap_write(arizona->regmap, 0x294, 2);
 371                regmap_write(arizona->regmap, 0x80, 0x0);
 372        }
 373
 374        ret = regulator_allow_bypass(info->micvdd, true);
 375        if (ret != 0) {
 376                dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
 377                        ret);
 378        }
 379
 380        if (change) {
 381                regulator_disable(info->micvdd);
 382                pm_runtime_mark_last_busy(info->dev);
 383                pm_runtime_put_autosuspend(info->dev);
 384        }
 385}
 386
 387static struct {
 388        unsigned int threshold;
 389        unsigned int factor_a;
 390        unsigned int factor_b;
 391} arizona_hpdet_b_ranges[] = {
 392        { 100,  5528,   362464 },
 393        { 169, 11084,  6186851 },
 394        { 169, 11065, 65460395 },
 395};
 396
 397#define ARIZONA_HPDET_B_RANGE_MAX 0x3fb
 398
 399static struct {
 400        int min;
 401        int max;
 402} arizona_hpdet_c_ranges[] = {
 403        { 0,       30 },
 404        { 8,      100 },
 405        { 100,   1000 },
 406        { 1000, 10000 },
 407};
 408
 409static int arizona_hpdet_read(struct arizona_extcon_info *info)
 410{
 411        struct arizona *arizona = info->arizona;
 412        unsigned int val, range;
 413        int ret;
 414
 415        ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
 416        if (ret != 0) {
 417                dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
 418                        ret);
 419                return ret;
 420        }
 421
 422        switch (info->hpdet_ip_version) {
 423        case 0:
 424                if (!(val & ARIZONA_HP_DONE)) {
 425                        dev_err(arizona->dev, "HPDET did not complete: %x\n",
 426                                val);
 427                        return -EAGAIN;
 428                }
 429
 430                val &= ARIZONA_HP_LVL_MASK;
 431                break;
 432
 433        case 1:
 434                if (!(val & ARIZONA_HP_DONE_B)) {
 435                        dev_err(arizona->dev, "HPDET did not complete: %x\n",
 436                                val);
 437                        return -EAGAIN;
 438                }
 439
 440                ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
 441                if (ret != 0) {
 442                        dev_err(arizona->dev, "Failed to read HP value: %d\n",
 443                                ret);
 444                        return -EAGAIN;
 445                }
 446
 447                regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
 448                            &range);
 449                range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
 450                           >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
 451
 452                if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
 453                    (val < arizona_hpdet_b_ranges[range].threshold ||
 454                     val >= ARIZONA_HPDET_B_RANGE_MAX)) {
 455                        range++;
 456                        dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
 457                                range);
 458                        regmap_update_bits(arizona->regmap,
 459                                           ARIZONA_HEADPHONE_DETECT_1,
 460                                           ARIZONA_HP_IMPEDANCE_RANGE_MASK,
 461                                           range <<
 462                                           ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
 463                        return -EAGAIN;
 464                }
 465
 466                /* If we go out of range report top of range */
 467                if (val < arizona_hpdet_b_ranges[range].threshold ||
 468                    val >= ARIZONA_HPDET_B_RANGE_MAX) {
 469                        dev_dbg(arizona->dev, "Measurement out of range\n");
 470                        return ARIZONA_HPDET_MAX;
 471                }
 472
 473                dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
 474                        val, range);
 475
 476                val = arizona_hpdet_b_ranges[range].factor_b
 477                        / ((val * 100) -
 478                           arizona_hpdet_b_ranges[range].factor_a);
 479                break;
 480
 481        case 2:
 482                if (!(val & ARIZONA_HP_DONE_B)) {
 483                        dev_err(arizona->dev, "HPDET did not complete: %x\n",
 484                                val);
 485                        return -EAGAIN;
 486                }
 487
 488                val &= ARIZONA_HP_LVL_B_MASK;
 489                /* Convert to ohms, the value is in 0.5 ohm increments */
 490                val /= 2;
 491
 492                regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
 493                            &range);
 494                range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
 495                           >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
 496
 497                /* Skip up a range, or report? */
 498                if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
 499                    (val >= arizona_hpdet_c_ranges[range].max)) {
 500                        range++;
 501                        dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
 502                                arizona_hpdet_c_ranges[range].min,
 503                                arizona_hpdet_c_ranges[range].max);
 504                        regmap_update_bits(arizona->regmap,
 505                                           ARIZONA_HEADPHONE_DETECT_1,
 506                                           ARIZONA_HP_IMPEDANCE_RANGE_MASK,
 507                                           range <<
 508                                           ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
 509                        return -EAGAIN;
 510                }
 511
 512                if (range && (val < arizona_hpdet_c_ranges[range].min)) {
 513                        dev_dbg(arizona->dev, "Reporting range boundary %d\n",
 514                                arizona_hpdet_c_ranges[range].min);
 515                        val = arizona_hpdet_c_ranges[range].min;
 516                }
 517                break;
 518
 519        default:
 520                dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
 521                         info->hpdet_ip_version);
 522                return -EINVAL;
 523        }
 524
 525        dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
 526        return val;
 527}
 528
 529static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
 530                               bool *mic)
 531{
 532        struct arizona *arizona = info->arizona;
 533        int id_gpio = arizona->pdata.hpdet_id_gpio;
 534
 535        /*
 536         * If we're using HPDET for accessory identification we need
 537         * to take multiple measurements, step through them in sequence.
 538         */
 539        if (arizona->pdata.hpdet_acc_id) {
 540                info->hpdet_res[info->num_hpdet_res++] = *reading;
 541
 542                /* Only check the mic directly if we didn't already ID it */
 543                if (id_gpio && info->num_hpdet_res == 1) {
 544                        dev_dbg(arizona->dev, "Measuring mic\n");
 545
 546                        regmap_update_bits(arizona->regmap,
 547                                           ARIZONA_ACCESSORY_DETECT_MODE_1,
 548                                           ARIZONA_ACCDET_MODE_MASK |
 549                                           ARIZONA_ACCDET_SRC,
 550                                           ARIZONA_ACCDET_MODE_HPR |
 551                                           info->micd_modes[0].src);
 552
 553                        gpio_set_value_cansleep(id_gpio, 1);
 554
 555                        regmap_update_bits(arizona->regmap,
 556                                           ARIZONA_HEADPHONE_DETECT_1,
 557                                           ARIZONA_HP_POLL, ARIZONA_HP_POLL);
 558                        return -EAGAIN;
 559                }
 560
 561                /* OK, got both.  Now, compare... */
 562                dev_dbg(arizona->dev, "HPDET measured %d %d\n",
 563                        info->hpdet_res[0], info->hpdet_res[1]);
 564
 565                /* Take the headphone impedance for the main report */
 566                *reading = info->hpdet_res[0];
 567
 568                /* Sometimes we get false readings due to slow insert */
 569                if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
 570                        dev_dbg(arizona->dev, "Retrying high impedance\n");
 571                        info->num_hpdet_res = 0;
 572                        info->hpdet_retried = true;
 573                        arizona_start_hpdet_acc_id(info);
 574                        pm_runtime_put(info->dev);
 575                        return -EAGAIN;
 576                }
 577
 578                /*
 579                 * If we measure the mic as high impedance
 580                 */
 581                if (!id_gpio || info->hpdet_res[1] > 50) {
 582                        dev_dbg(arizona->dev, "Detected mic\n");
 583                        *mic = true;
 584                        info->detecting = true;
 585                } else {
 586                        dev_dbg(arizona->dev, "Detected headphone\n");
 587                }
 588
 589                /* Make sure everything is reset back to the real polarity */
 590                regmap_update_bits(arizona->regmap,
 591                                   ARIZONA_ACCESSORY_DETECT_MODE_1,
 592                                   ARIZONA_ACCDET_SRC,
 593                                   info->micd_modes[0].src);
 594        }
 595
 596        return 0;
 597}
 598
 599static irqreturn_t arizona_hpdet_irq(int irq, void *data)
 600{
 601        struct arizona_extcon_info *info = data;
 602        struct arizona *arizona = info->arizona;
 603        int id_gpio = arizona->pdata.hpdet_id_gpio;
 604        unsigned int report = EXTCON_JACK_HEADPHONE;
 605        int ret, reading;
 606        bool mic = false;
 607
 608        mutex_lock(&info->lock);
 609
 610        /* If we got a spurious IRQ for some reason then ignore it */
 611        if (!info->hpdet_active) {
 612                dev_warn(arizona->dev, "Spurious HPDET IRQ\n");
 613                mutex_unlock(&info->lock);
 614                return IRQ_NONE;
 615        }
 616
 617        /* If the cable was removed while measuring ignore the result */
 618        ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
 619        if (ret < 0) {
 620                dev_err(arizona->dev, "Failed to check cable state: %d\n",
 621                        ret);
 622                goto out;
 623        } else if (!ret) {
 624                dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
 625                goto done;
 626        }
 627
 628        ret = arizona_hpdet_read(info);
 629        if (ret == -EAGAIN)
 630                goto out;
 631        else if (ret < 0)
 632                goto done;
 633        reading = ret;
 634
 635        /* Reset back to starting range */
 636        regmap_update_bits(arizona->regmap,
 637                           ARIZONA_HEADPHONE_DETECT_1,
 638                           ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
 639                           0);
 640
 641        ret = arizona_hpdet_do_id(info, &reading, &mic);
 642        if (ret == -EAGAIN)
 643                goto out;
 644        else if (ret < 0)
 645                goto done;
 646
 647        /* Report high impedence cables as line outputs */
 648        if (reading >= 5000)
 649                report = EXTCON_JACK_LINE_OUT;
 650        else
 651                report = EXTCON_JACK_HEADPHONE;
 652
 653        ret = extcon_set_state_sync(info->edev, report, true);
 654        if (ret != 0)
 655                dev_err(arizona->dev, "Failed to report HP/line: %d\n",
 656                        ret);
 657
 658done:
 659        /* Reset back to starting range */
 660        regmap_update_bits(arizona->regmap,
 661                           ARIZONA_HEADPHONE_DETECT_1,
 662                           ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,
 663                           0);
 664
 665        arizona_extcon_hp_clamp(info, false);
 666
 667        if (id_gpio)
 668                gpio_set_value_cansleep(id_gpio, 0);
 669
 670        /* Revert back to MICDET mode */
 671        regmap_update_bits(arizona->regmap,
 672                           ARIZONA_ACCESSORY_DETECT_MODE_1,
 673                           ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
 674
 675        /* If we have a mic then reenable MICDET */
 676        if (mic || info->mic)
 677                arizona_start_mic(info);
 678
 679        if (info->hpdet_active) {
 680                pm_runtime_put_autosuspend(info->dev);
 681                info->hpdet_active = false;
 682        }
 683
 684        info->hpdet_done = true;
 685
 686out:
 687        mutex_unlock(&info->lock);
 688
 689        return IRQ_HANDLED;
 690}
 691
 692static void arizona_identify_headphone(struct arizona_extcon_info *info)
 693{
 694        struct arizona *arizona = info->arizona;
 695        int ret;
 696
 697        if (info->hpdet_done)
 698                return;
 699
 700        dev_dbg(arizona->dev, "Starting HPDET\n");
 701
 702        /* Make sure we keep the device enabled during the measurement */
 703        pm_runtime_get(info->dev);
 704
 705        info->hpdet_active = true;
 706
 707        if (info->mic)
 708                arizona_stop_mic(info);
 709
 710        arizona_extcon_hp_clamp(info, true);
 711
 712        ret = regmap_update_bits(arizona->regmap,
 713                                 ARIZONA_ACCESSORY_DETECT_MODE_1,
 714                                 ARIZONA_ACCDET_MODE_MASK,
 715                                 arizona->pdata.hpdet_channel);
 716        if (ret != 0) {
 717                dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);
 718                goto err;
 719        }
 720
 721        ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
 722                                 ARIZONA_HP_POLL, ARIZONA_HP_POLL);
 723        if (ret != 0) {
 724                dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n",
 725                        ret);
 726                goto err;
 727        }
 728
 729        return;
 730
 731err:
 732        regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
 733                           ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
 734
 735        /* Just report headphone */
 736        ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true);
 737        if (ret != 0)
 738                dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
 739
 740        if (info->mic)
 741                arizona_start_mic(info);
 742
 743        info->hpdet_active = false;
 744}
 745
 746static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
 747{
 748        struct arizona *arizona = info->arizona;
 749        int hp_reading = 32;
 750        bool mic;
 751        int ret;
 752
 753        dev_dbg(arizona->dev, "Starting identification via HPDET\n");
 754
 755        /* Make sure we keep the device enabled during the measurement */
 756        pm_runtime_get_sync(info->dev);
 757
 758        info->hpdet_active = true;
 759
 760        arizona_extcon_hp_clamp(info, true);
 761
 762        ret = regmap_update_bits(arizona->regmap,
 763                                 ARIZONA_ACCESSORY_DETECT_MODE_1,
 764                                 ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,
 765                                 info->micd_modes[0].src |
 766                                 arizona->pdata.hpdet_channel);
 767        if (ret != 0) {
 768                dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);
 769                goto err;
 770        }
 771
 772        if (arizona->pdata.hpdet_acc_id_line) {
 773                ret = regmap_update_bits(arizona->regmap,
 774                                         ARIZONA_HEADPHONE_DETECT_1,
 775                                         ARIZONA_HP_POLL, ARIZONA_HP_POLL);
 776                if (ret != 0) {
 777                        dev_err(arizona->dev,
 778                                "Can't start HPDETL measurement: %d\n",
 779                                ret);
 780                        goto err;
 781                }
 782        } else {
 783                arizona_hpdet_do_id(info, &hp_reading, &mic);
 784        }
 785
 786        return;
 787
 788err:
 789        regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
 790                           ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
 791
 792        /* Just report headphone */
 793        ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true);
 794        if (ret != 0)
 795                dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
 796
 797        info->hpdet_active = false;
 798}
 799
 800static void arizona_micd_timeout_work(struct work_struct *work)
 801{
 802        struct arizona_extcon_info *info = container_of(work,
 803                                                struct arizona_extcon_info,
 804                                                micd_timeout_work.work);
 805
 806        mutex_lock(&info->lock);
 807
 808        dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n");
 809
 810        info->detecting = false;
 811
 812        arizona_identify_headphone(info);
 813
 814        arizona_stop_mic(info);
 815
 816        mutex_unlock(&info->lock);
 817}
 818
 819static void arizona_micd_detect(struct work_struct *work)
 820{
 821        struct arizona_extcon_info *info = container_of(work,
 822                                                struct arizona_extcon_info,
 823                                                micd_detect_work.work);
 824        struct arizona *arizona = info->arizona;
 825        unsigned int val = 0, lvl;
 826        int ret, i, key;
 827
 828        cancel_delayed_work_sync(&info->micd_timeout_work);
 829
 830        mutex_lock(&info->lock);
 831
 832        /* If the cable was removed while measuring ignore the result */
 833        ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
 834        if (ret < 0) {
 835                dev_err(arizona->dev, "Failed to check cable state: %d\n",
 836                                ret);
 837                mutex_unlock(&info->lock);
 838                return;
 839        } else if (!ret) {
 840                dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
 841                mutex_unlock(&info->lock);
 842                return;
 843        }
 844
 845        if (info->detecting && arizona->pdata.micd_software_compare) {
 846                /* Must disable MICD before we read the ADCVAL */
 847                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
 848                                   ARIZONA_MICD_ENA, 0);
 849                ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);
 850                if (ret != 0) {
 851                        dev_err(arizona->dev,
 852                                "Failed to read MICDET_ADCVAL: %d\n",
 853                                ret);
 854                        mutex_unlock(&info->lock);
 855                        return;
 856                }
 857
 858                dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);
 859
 860                val &= ARIZONA_MICDET_ADCVAL_MASK;
 861                if (val < ARRAY_SIZE(arizona_micd_levels))
 862                        val = arizona_micd_levels[val];
 863                else
 864                        val = INT_MAX;
 865
 866                if (val <= QUICK_HEADPHONE_MAX_OHM)
 867                        val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;
 868                else if (val <= MICROPHONE_MIN_OHM)
 869                        val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;
 870                else if (val <= MICROPHONE_MAX_OHM)
 871                        val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;
 872                else
 873                        val = ARIZONA_MICD_LVL_8;
 874        }
 875
 876        for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
 877                ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
 878                if (ret != 0) {
 879                        dev_err(arizona->dev,
 880                                "Failed to read MICDET: %d\n", ret);
 881                        mutex_unlock(&info->lock);
 882                        return;
 883                }
 884
 885                dev_dbg(arizona->dev, "MICDET: %x\n", val);
 886
 887                if (!(val & ARIZONA_MICD_VALID)) {
 888                        dev_warn(arizona->dev,
 889                                 "Microphone detection state invalid\n");
 890                        mutex_unlock(&info->lock);
 891                        return;
 892                }
 893        }
 894
 895        if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
 896                dev_err(arizona->dev, "Failed to get valid MICDET value\n");
 897                mutex_unlock(&info->lock);
 898                return;
 899        }
 900
 901        /* Due to jack detect this should never happen */
 902        if (!(val & ARIZONA_MICD_STS)) {
 903                dev_warn(arizona->dev, "Detected open circuit\n");
 904                info->mic = false;
 905                arizona_stop_mic(info);
 906                info->detecting = false;
 907                arizona_identify_headphone(info);
 908                goto handled;
 909        }
 910
 911        /* If we got a high impedence we should have a headset, report it. */
 912        if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
 913                info->mic = true;
 914                info->detecting = false;
 915
 916                arizona_identify_headphone(info);
 917
 918                ret = extcon_set_state_sync(info->edev,
 919                                              EXTCON_JACK_MICROPHONE, true);
 920                if (ret != 0)
 921                        dev_err(arizona->dev, "Headset report failed: %d\n",
 922                                ret);
 923
 924                /* Don't need to regulate for button detection */
 925                ret = regulator_allow_bypass(info->micvdd, true);
 926                if (ret != 0) {
 927                        dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
 928                                ret);
 929                }
 930
 931                goto handled;
 932        }
 933
 934        /* If we detected a lower impedence during initial startup
 935         * then we probably have the wrong polarity, flip it.  Don't
 936         * do this for the lowest impedences to speed up detection of
 937         * plain headphones.  If both polarities report a low
 938         * impedence then give up and report headphones.
 939         */
 940        if (info->detecting && (val & MICD_LVL_1_TO_7)) {
 941                if (info->jack_flips >= info->micd_num_modes * 10) {
 942                        dev_dbg(arizona->dev, "Detected HP/line\n");
 943
 944                        info->detecting = false;
 945
 946                        arizona_identify_headphone(info);
 947
 948                        arizona_stop_mic(info);
 949                } else {
 950                        info->micd_mode++;
 951                        if (info->micd_mode == info->micd_num_modes)
 952                                info->micd_mode = 0;
 953                        arizona_extcon_set_mode(info, info->micd_mode);
 954
 955                        info->jack_flips++;
 956                }
 957
 958                goto handled;
 959        }
 960
 961        /*
 962         * If we're still detecting and we detect a short then we've
 963         * got a headphone.  Otherwise it's a button press.
 964         */
 965        if (val & MICD_LVL_0_TO_7) {
 966                if (info->mic) {
 967                        dev_dbg(arizona->dev, "Mic button detected\n");
 968
 969                        lvl = val & ARIZONA_MICD_LVL_MASK;
 970                        lvl >>= ARIZONA_MICD_LVL_SHIFT;
 971
 972                        for (i = 0; i < info->num_micd_ranges; i++)
 973                                input_report_key(info->input,
 974                                                 info->micd_ranges[i].key, 0);
 975
 976                        WARN_ON(!lvl);
 977                        WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges);
 978                        if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
 979                                key = info->micd_ranges[ffs(lvl) - 1].key;
 980                                input_report_key(info->input, key, 1);
 981                                input_sync(info->input);
 982                        }
 983
 984                } else if (info->detecting) {
 985                        dev_dbg(arizona->dev, "Headphone detected\n");
 986                        info->detecting = false;
 987                        arizona_stop_mic(info);
 988
 989                        arizona_identify_headphone(info);
 990                } else {
 991                        dev_warn(arizona->dev, "Button with no mic: %x\n",
 992                                 val);
 993                }
 994        } else {
 995                dev_dbg(arizona->dev, "Mic button released\n");
 996                for (i = 0; i < info->num_micd_ranges; i++)
 997                        input_report_key(info->input,
 998                                         info->micd_ranges[i].key, 0);
 999                input_sync(info->input);
1000                arizona_extcon_pulse_micbias(info);
1001        }
1002
1003handled:
1004        if (info->detecting) {
1005                if (arizona->pdata.micd_software_compare)
1006                        regmap_update_bits(arizona->regmap,
1007                                           ARIZONA_MIC_DETECT_1,
1008                                           ARIZONA_MICD_ENA,
1009                                           ARIZONA_MICD_ENA);
1010
1011                queue_delayed_work(system_power_efficient_wq,
1012                                   &info->micd_timeout_work,
1013                                   msecs_to_jiffies(info->micd_timeout));
1014        }
1015
1016        pm_runtime_mark_last_busy(info->dev);
1017        mutex_unlock(&info->lock);
1018}
1019
1020static irqreturn_t arizona_micdet(int irq, void *data)
1021{
1022        struct arizona_extcon_info *info = data;
1023        struct arizona *arizona = info->arizona;
1024        int debounce = arizona->pdata.micd_detect_debounce;
1025
1026        cancel_delayed_work_sync(&info->micd_detect_work);
1027        cancel_delayed_work_sync(&info->micd_timeout_work);
1028
1029        mutex_lock(&info->lock);
1030        if (!info->detecting)
1031                debounce = 0;
1032        mutex_unlock(&info->lock);
1033
1034        if (debounce)
1035                queue_delayed_work(system_power_efficient_wq,
1036                                   &info->micd_detect_work,
1037                                   msecs_to_jiffies(debounce));
1038        else
1039                arizona_micd_detect(&info->micd_detect_work.work);
1040
1041        return IRQ_HANDLED;
1042}
1043
1044static void arizona_hpdet_work(struct work_struct *work)
1045{
1046        struct arizona_extcon_info *info = container_of(work,
1047                                                struct arizona_extcon_info,
1048                                                hpdet_work.work);
1049
1050        mutex_lock(&info->lock);
1051        arizona_start_hpdet_acc_id(info);
1052        mutex_unlock(&info->lock);
1053}
1054
1055static int arizona_hpdet_wait(struct arizona_extcon_info *info)
1056{
1057        struct arizona *arizona = info->arizona;
1058        unsigned int val;
1059        int i, ret;
1060
1061        for (i = 0; i < ARIZONA_HPDET_WAIT_COUNT; i++) {
1062                ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2,
1063                                &val);
1064                if (ret) {
1065                        dev_err(arizona->dev,
1066                                "Failed to read HPDET state: %d\n", ret);
1067                        return ret;
1068                }
1069
1070                switch (info->hpdet_ip_version) {
1071                case 0:
1072                        if (val & ARIZONA_HP_DONE)
1073                                return 0;
1074                        break;
1075                default:
1076                        if (val & ARIZONA_HP_DONE_B)
1077                                return 0;
1078                        break;
1079                }
1080
1081                msleep(ARIZONA_HPDET_WAIT_DELAY_MS);
1082        }
1083
1084        dev_warn(arizona->dev, "HPDET did not appear to complete\n");
1085
1086        return -ETIMEDOUT;
1087}
1088
1089static irqreturn_t arizona_jackdet(int irq, void *data)
1090{
1091        struct arizona_extcon_info *info = data;
1092        struct arizona *arizona = info->arizona;
1093        unsigned int val, present, mask;
1094        bool cancelled_hp, cancelled_mic;
1095        int ret, i;
1096
1097        cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
1098        cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
1099
1100        pm_runtime_get_sync(info->dev);
1101
1102        mutex_lock(&info->lock);
1103
1104        if (info->micd_clamp) {
1105                mask = ARIZONA_MICD_CLAMP_STS;
1106                present = 0;
1107        } else {
1108                mask = ARIZONA_JD1_STS;
1109                if (arizona->pdata.jd_invert)
1110                        present = 0;
1111                else
1112                        present = ARIZONA_JD1_STS;
1113        }
1114
1115        ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
1116        if (ret != 0) {
1117                dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
1118                        ret);
1119                mutex_unlock(&info->lock);
1120                pm_runtime_put_autosuspend(info->dev);
1121                return IRQ_NONE;
1122        }
1123
1124        val &= mask;
1125        if (val == info->last_jackdet) {
1126                dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");
1127                if (cancelled_hp)
1128                        queue_delayed_work(system_power_efficient_wq,
1129                                           &info->hpdet_work,
1130                                           msecs_to_jiffies(HPDET_DEBOUNCE));
1131
1132                if (cancelled_mic) {
1133                        int micd_timeout = info->micd_timeout;
1134
1135                        queue_delayed_work(system_power_efficient_wq,
1136                                           &info->micd_timeout_work,
1137                                           msecs_to_jiffies(micd_timeout));
1138                }
1139
1140                goto out;
1141        }
1142        info->last_jackdet = val;
1143
1144        if (info->last_jackdet == present) {
1145                dev_dbg(arizona->dev, "Detected jack\n");
1146                ret = extcon_set_state_sync(info->edev,
1147                                              EXTCON_MECHANICAL, true);
1148
1149                if (ret != 0)
1150                        dev_err(arizona->dev, "Mechanical report failed: %d\n",
1151                                ret);
1152
1153                if (!arizona->pdata.hpdet_acc_id) {
1154                        info->detecting = true;
1155                        info->mic = false;
1156                        info->jack_flips = 0;
1157
1158                        arizona_start_mic(info);
1159                } else {
1160                        queue_delayed_work(system_power_efficient_wq,
1161                                           &info->hpdet_work,
1162                                           msecs_to_jiffies(HPDET_DEBOUNCE));
1163                }
1164
1165                if (info->micd_clamp || !arizona->pdata.jd_invert)
1166                        regmap_update_bits(arizona->regmap,
1167                                           ARIZONA_JACK_DETECT_DEBOUNCE,
1168                                           ARIZONA_MICD_CLAMP_DB |
1169                                           ARIZONA_JD1_DB, 0);
1170        } else {
1171                dev_dbg(arizona->dev, "Detected jack removal\n");
1172
1173                arizona_stop_mic(info);
1174
1175                info->num_hpdet_res = 0;
1176                for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
1177                        info->hpdet_res[i] = 0;
1178                info->mic = false;
1179                info->hpdet_done = false;
1180                info->hpdet_retried = false;
1181
1182                for (i = 0; i < info->num_micd_ranges; i++)
1183                        input_report_key(info->input,
1184                                         info->micd_ranges[i].key, 0);
1185                input_sync(info->input);
1186
1187                for (i = 0; i < ARRAY_SIZE(arizona_cable) - 1; i++) {
1188                        ret = extcon_set_state_sync(info->edev,
1189                                        arizona_cable[i], false);
1190                        if (ret != 0)
1191                                dev_err(arizona->dev,
1192                                        "Removal report failed: %d\n", ret);
1193                }
1194
1195                /*
1196                 * If the jack was removed during a headphone detection we
1197                 * need to wait for the headphone detection to finish, as
1198                 * it can not be aborted. We don't want to be able to start
1199                 * a new headphone detection from a fresh insert until this
1200                 * one is finished.
1201                 */
1202                arizona_hpdet_wait(info);
1203
1204                regmap_update_bits(arizona->regmap,
1205                                   ARIZONA_JACK_DETECT_DEBOUNCE,
1206                                   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
1207                                   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
1208        }
1209
1210        if (arizona->pdata.micd_timeout)
1211                info->micd_timeout = arizona->pdata.micd_timeout;
1212        else
1213                info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1214
1215out:
1216        /* Clear trig_sts to make sure DCVDD is not forced up */
1217        regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1218                     ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
1219                     ARIZONA_MICD_CLAMP_RISE_TRIG_STS |
1220                     ARIZONA_JD1_FALL_TRIG_STS |
1221                     ARIZONA_JD1_RISE_TRIG_STS);
1222
1223        mutex_unlock(&info->lock);
1224
1225        pm_runtime_mark_last_busy(info->dev);
1226        pm_runtime_put_autosuspend(info->dev);
1227
1228        return IRQ_HANDLED;
1229}
1230
1231/* Map a level onto a slot in the register bank */
1232static void arizona_micd_set_level(struct arizona *arizona, int index,
1233                                   unsigned int level)
1234{
1235        int reg;
1236        unsigned int mask;
1237
1238        reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);
1239
1240        if (!(index % 2)) {
1241                mask = 0x3f00;
1242                level <<= 8;
1243        } else {
1244                mask = 0x3f;
1245        }
1246
1247        /* Program the level itself */
1248        regmap_update_bits(arizona->regmap, reg, mask, level);
1249}
1250
1251static int arizona_extcon_get_micd_configs(struct device *dev,
1252                                           struct arizona *arizona)
1253{
1254        const char * const prop = "wlf,micd-configs";
1255        const int entries_per_config = 3;
1256        struct arizona_micd_config *micd_configs;
1257        int nconfs, ret;
1258        int i, j;
1259        u32 *vals;
1260
1261        nconfs = device_property_read_u32_array(arizona->dev, prop, NULL, 0);
1262        if (nconfs <= 0)
1263                return 0;
1264
1265        vals = kcalloc(nconfs, sizeof(u32), GFP_KERNEL);
1266        if (!vals)
1267                return -ENOMEM;
1268
1269        ret = device_property_read_u32_array(arizona->dev, prop, vals, nconfs);
1270        if (ret < 0)
1271                goto out;
1272
1273        nconfs /= entries_per_config;
1274        micd_configs = devm_kcalloc(dev, nconfs, sizeof(*micd_configs),
1275                                    GFP_KERNEL);
1276        if (!micd_configs) {
1277                ret = -ENOMEM;
1278                goto out;
1279        }
1280
1281        for (i = 0, j = 0; i < nconfs; ++i) {
1282                micd_configs[i].src = vals[j++] ? ARIZONA_ACCDET_SRC : 0;
1283                micd_configs[i].bias = vals[j++];
1284                micd_configs[i].gpio = vals[j++];
1285        }
1286
1287        arizona->pdata.micd_configs = micd_configs;
1288        arizona->pdata.num_micd_configs = nconfs;
1289
1290out:
1291        kfree(vals);
1292        return ret;
1293}
1294
1295static int arizona_extcon_device_get_pdata(struct device *dev,
1296                                           struct arizona *arizona)
1297{
1298        struct arizona_pdata *pdata = &arizona->pdata;
1299        unsigned int val = ARIZONA_ACCDET_MODE_HPL;
1300        int ret;
1301
1302        device_property_read_u32(arizona->dev, "wlf,hpdet-channel", &val);
1303        switch (val) {
1304        case ARIZONA_ACCDET_MODE_HPL:
1305        case ARIZONA_ACCDET_MODE_HPR:
1306                pdata->hpdet_channel = val;
1307                break;
1308        default:
1309                dev_err(arizona->dev,
1310                        "Wrong wlf,hpdet-channel DT value %d\n", val);
1311                pdata->hpdet_channel = ARIZONA_ACCDET_MODE_HPL;
1312        }
1313
1314        device_property_read_u32(arizona->dev, "wlf,micd-detect-debounce",
1315                                 &pdata->micd_detect_debounce);
1316
1317        device_property_read_u32(arizona->dev, "wlf,micd-bias-start-time",
1318                                 &pdata->micd_bias_start_time);
1319
1320        device_property_read_u32(arizona->dev, "wlf,micd-rate",
1321                                 &pdata->micd_rate);
1322
1323        device_property_read_u32(arizona->dev, "wlf,micd-dbtime",
1324                                 &pdata->micd_dbtime);
1325
1326        device_property_read_u32(arizona->dev, "wlf,micd-timeout-ms",
1327                                 &pdata->micd_timeout);
1328
1329        pdata->micd_force_micbias = device_property_read_bool(arizona->dev,
1330                                                "wlf,micd-force-micbias");
1331
1332        pdata->micd_software_compare = device_property_read_bool(arizona->dev,
1333                                                "wlf,micd-software-compare");
1334
1335        pdata->jd_invert = device_property_read_bool(arizona->dev,
1336                                                     "wlf,jd-invert");
1337
1338        device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw);
1339
1340        pdata->jd_gpio5 = device_property_read_bool(arizona->dev,
1341                                                    "wlf,use-jd2");
1342        pdata->jd_gpio5_nopull = device_property_read_bool(arizona->dev,
1343                                                "wlf,use-jd2-nopull");
1344
1345        ret = arizona_extcon_get_micd_configs(dev, arizona);
1346        if (ret < 0)
1347                dev_err(arizona->dev, "Failed to read micd configs: %d\n", ret);
1348
1349        return 0;
1350}
1351
1352static int arizona_extcon_probe(struct platform_device *pdev)
1353{
1354        struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1355        struct arizona_pdata *pdata = &arizona->pdata;
1356        struct arizona_extcon_info *info;
1357        unsigned int val;
1358        unsigned int clamp_mode;
1359        int jack_irq_fall, jack_irq_rise;
1360        int ret, mode, i, j;
1361
1362        if (!arizona->dapm || !arizona->dapm->card)
1363                return -EPROBE_DEFER;
1364
1365        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
1366        if (!info)
1367                return -ENOMEM;
1368
1369        if (!dev_get_platdata(arizona->dev))
1370                arizona_extcon_device_get_pdata(&pdev->dev, arizona);
1371
1372        info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
1373        if (IS_ERR(info->micvdd)) {
1374                ret = PTR_ERR(info->micvdd);
1375                dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
1376                return ret;
1377        }
1378
1379        mutex_init(&info->lock);
1380        info->arizona = arizona;
1381        info->dev = &pdev->dev;
1382        info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);
1383        INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);
1384        INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);
1385        INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);
1386        platform_set_drvdata(pdev, info);
1387
1388        switch (arizona->type) {
1389        case WM5102:
1390                switch (arizona->rev) {
1391                case 0:
1392                        info->micd_reva = true;
1393                        break;
1394                default:
1395                        info->micd_clamp = true;
1396                        info->hpdet_ip_version = 1;
1397                        break;
1398                }
1399                break;
1400        case WM5110:
1401        case WM8280:
1402                switch (arizona->rev) {
1403                case 0 ... 2:
1404                        break;
1405                default:
1406                        info->micd_clamp = true;
1407                        info->hpdet_ip_version = 2;
1408                        break;
1409                }
1410                break;
1411        case WM8998:
1412        case WM1814:
1413                info->micd_clamp = true;
1414                info->hpdet_ip_version = 2;
1415                break;
1416        default:
1417                break;
1418        }
1419
1420        info->edev = devm_extcon_dev_allocate(&pdev->dev, arizona_cable);
1421        if (IS_ERR(info->edev)) {
1422                dev_err(&pdev->dev, "failed to allocate extcon device\n");
1423                return -ENOMEM;
1424        }
1425
1426        ret = devm_extcon_dev_register(&pdev->dev, info->edev);
1427        if (ret < 0) {
1428                dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
1429                        ret);
1430                return ret;
1431        }
1432
1433        info->input = devm_input_allocate_device(&pdev->dev);
1434        if (!info->input) {
1435                dev_err(arizona->dev, "Can't allocate input dev\n");
1436                ret = -ENOMEM;
1437                goto err_register;
1438        }
1439
1440        info->input->name = "Headset";
1441        info->input->phys = "arizona/extcon";
1442
1443        if (pdata->num_micd_configs) {
1444                info->micd_modes = pdata->micd_configs;
1445                info->micd_num_modes = pdata->num_micd_configs;
1446        } else {
1447                info->micd_modes = micd_default_modes;
1448                info->micd_num_modes = ARRAY_SIZE(micd_default_modes);
1449        }
1450
1451        if (arizona->pdata.gpsw > 0)
1452                regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1,
1453                                ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw);
1454
1455        if (pdata->micd_pol_gpio > 0) {
1456                if (info->micd_modes[0].gpio)
1457                        mode = GPIOF_OUT_INIT_HIGH;
1458                else
1459                        mode = GPIOF_OUT_INIT_LOW;
1460
1461                ret = devm_gpio_request_one(&pdev->dev, pdata->micd_pol_gpio,
1462                                            mode, "MICD polarity");
1463                if (ret != 0) {
1464                        dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1465                                pdata->micd_pol_gpio, ret);
1466                        goto err_register;
1467                }
1468
1469                info->micd_pol_gpio = gpio_to_desc(pdata->micd_pol_gpio);
1470        } else {
1471                if (info->micd_modes[0].gpio)
1472                        mode = GPIOD_OUT_HIGH;
1473                else
1474                        mode = GPIOD_OUT_LOW;
1475
1476                /* We can't use devm here because we need to do the get
1477                 * against the MFD device, as that is where the of_node
1478                 * will reside, but if we devm against that the GPIO
1479                 * will not be freed if the extcon driver is unloaded.
1480                 */
1481                info->micd_pol_gpio = gpiod_get_optional(arizona->dev,
1482                                                         "wlf,micd-pol",
1483                                                         GPIOD_OUT_LOW);
1484                if (IS_ERR(info->micd_pol_gpio)) {
1485                        ret = PTR_ERR(info->micd_pol_gpio);
1486                        dev_err(arizona->dev,
1487                                "Failed to get microphone polarity GPIO: %d\n",
1488                                ret);
1489                        goto err_register;
1490                }
1491        }
1492
1493        if (arizona->pdata.hpdet_id_gpio > 0) {
1494                ret = devm_gpio_request_one(&pdev->dev,
1495                                            arizona->pdata.hpdet_id_gpio,
1496                                            GPIOF_OUT_INIT_LOW,
1497                                            "HPDET");
1498                if (ret != 0) {
1499                        dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
1500                                arizona->pdata.hpdet_id_gpio, ret);
1501                        goto err_gpio;
1502                }
1503        }
1504
1505        if (arizona->pdata.micd_bias_start_time)
1506                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1507                                   ARIZONA_MICD_BIAS_STARTTIME_MASK,
1508                                   arizona->pdata.micd_bias_start_time
1509                                   << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
1510
1511        if (arizona->pdata.micd_rate)
1512                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1513                                   ARIZONA_MICD_RATE_MASK,
1514                                   arizona->pdata.micd_rate
1515                                   << ARIZONA_MICD_RATE_SHIFT);
1516
1517        switch (arizona->pdata.micd_dbtime) {
1518        case MICD_DBTIME_FOUR_READINGS:
1519                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1520                                   ARIZONA_MICD_DBTIME_MASK,
1521                                   ARIZONA_MICD_DBTIME);
1522                break;
1523        case MICD_DBTIME_TWO_READINGS:
1524                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
1525                                   ARIZONA_MICD_DBTIME_MASK, 0);
1526                break;
1527        default:
1528                break;
1529        }
1530
1531        BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) <
1532                     ARIZONA_NUM_MICD_BUTTON_LEVELS);
1533
1534        if (arizona->pdata.num_micd_ranges) {
1535                info->micd_ranges = pdata->micd_ranges;
1536                info->num_micd_ranges = pdata->num_micd_ranges;
1537        } else {
1538                info->micd_ranges = micd_default_ranges;
1539                info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);
1540        }
1541
1542        if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_RANGE) {
1543                dev_err(arizona->dev, "Too many MICD ranges: %d\n",
1544                        arizona->pdata.num_micd_ranges);
1545        }
1546
1547        if (info->num_micd_ranges > 1) {
1548                for (i = 1; i < info->num_micd_ranges; i++) {
1549                        if (info->micd_ranges[i - 1].max >
1550                            info->micd_ranges[i].max) {
1551                                dev_err(arizona->dev,
1552                                        "MICD ranges must be sorted\n");
1553                                ret = -EINVAL;
1554                                goto err_gpio;
1555                        }
1556                }
1557        }
1558
1559        /* Disable all buttons by default */
1560        regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1561                           ARIZONA_MICD_LVL_SEL_MASK, 0x81);
1562
1563        /* Set up all the buttons the user specified */
1564        for (i = 0; i < info->num_micd_ranges; i++) {
1565                for (j = 0; j < ARIZONA_NUM_MICD_BUTTON_LEVELS; j++)
1566                        if (arizona_micd_levels[j] >= info->micd_ranges[i].max)
1567                                break;
1568
1569                if (j == ARIZONA_NUM_MICD_BUTTON_LEVELS) {
1570                        dev_err(arizona->dev, "Unsupported MICD level %d\n",
1571                                info->micd_ranges[i].max);
1572                        ret = -EINVAL;
1573                        goto err_gpio;
1574                }
1575
1576                dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",
1577                        arizona_micd_levels[j], i);
1578
1579                arizona_micd_set_level(arizona, i, j);
1580                input_set_capability(info->input, EV_KEY,
1581                                     info->micd_ranges[i].key);
1582
1583                /* Enable reporting of that range */
1584                regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,
1585                                   1 << i, 1 << i);
1586        }
1587
1588        /* Set all the remaining keys to a maximum */
1589        for (; i < ARIZONA_MAX_MICD_RANGE; i++)
1590                arizona_micd_set_level(arizona, i, 0x3f);
1591
1592        /*
1593         * If we have a clamp use it, activating in conjunction with
1594         * GPIO5 if that is connected for jack detect operation.
1595         */
1596        if (info->micd_clamp) {
1597                if (arizona->pdata.jd_gpio5) {
1598                        /* Put the GPIO into input mode with optional pull */
1599                        val = 0xc101;
1600                        if (arizona->pdata.jd_gpio5_nopull)
1601                                val &= ~ARIZONA_GPN_PU;
1602
1603                        regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
1604                                     val);
1605
1606                        if (arizona->pdata.jd_invert)
1607                                clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;
1608                        else
1609                                clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;
1610                } else {
1611                        if (arizona->pdata.jd_invert)
1612                                clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;
1613                        else
1614                                clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;
1615                }
1616
1617                regmap_update_bits(arizona->regmap,
1618                                   ARIZONA_MICD_CLAMP_CONTROL,
1619                                   ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);
1620
1621                regmap_update_bits(arizona->regmap,
1622                                   ARIZONA_JACK_DETECT_DEBOUNCE,
1623                                   ARIZONA_MICD_CLAMP_DB,
1624                                   ARIZONA_MICD_CLAMP_DB);
1625        }
1626
1627        arizona_extcon_set_mode(info, 0);
1628
1629        pm_runtime_enable(&pdev->dev);
1630        pm_runtime_idle(&pdev->dev);
1631        pm_runtime_get_sync(&pdev->dev);
1632
1633        if (info->micd_clamp) {
1634                jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1635                jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1636        } else {
1637                jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1638                jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1639        }
1640
1641        ret = arizona_request_irq(arizona, jack_irq_rise,
1642                                  "JACKDET rise", arizona_jackdet, info);
1643        if (ret != 0) {
1644                dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
1645                        ret);
1646                goto err_gpio;
1647        }
1648
1649        ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
1650        if (ret != 0) {
1651                dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
1652                        ret);
1653                goto err_rise;
1654        }
1655
1656        ret = arizona_request_irq(arizona, jack_irq_fall,
1657                                  "JACKDET fall", arizona_jackdet, info);
1658        if (ret != 0) {
1659                dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
1660                goto err_rise_wake;
1661        }
1662
1663        ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
1664        if (ret != 0) {
1665                dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
1666                        ret);
1667                goto err_fall;
1668        }
1669
1670        ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,
1671                                  "MICDET", arizona_micdet, info);
1672        if (ret != 0) {
1673                dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
1674                goto err_fall_wake;
1675        }
1676
1677        ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,
1678                                  "HPDET", arizona_hpdet_irq, info);
1679        if (ret != 0) {
1680                dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
1681                goto err_micdet;
1682        }
1683
1684        arizona_clk32k_enable(arizona);
1685        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,
1686                           ARIZONA_JD1_DB, ARIZONA_JD1_DB);
1687        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1688                           ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
1689
1690        ret = regulator_allow_bypass(info->micvdd, true);
1691        if (ret != 0)
1692                dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
1693                         ret);
1694
1695        pm_runtime_put(&pdev->dev);
1696
1697        ret = input_register_device(info->input);
1698        if (ret) {
1699                dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
1700                goto err_hpdet;
1701        }
1702
1703        return 0;
1704
1705err_hpdet:
1706        arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
1707err_micdet:
1708        arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
1709err_fall_wake:
1710        arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1711err_fall:
1712        arizona_free_irq(arizona, jack_irq_fall, info);
1713err_rise_wake:
1714        arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1715err_rise:
1716        arizona_free_irq(arizona, jack_irq_rise, info);
1717err_gpio:
1718        gpiod_put(info->micd_pol_gpio);
1719err_register:
1720        pm_runtime_disable(&pdev->dev);
1721        return ret;
1722}
1723
1724static int arizona_extcon_remove(struct platform_device *pdev)
1725{
1726        struct arizona_extcon_info *info = platform_get_drvdata(pdev);
1727        struct arizona *arizona = info->arizona;
1728        int jack_irq_rise, jack_irq_fall;
1729
1730        gpiod_put(info->micd_pol_gpio);
1731
1732        pm_runtime_disable(&pdev->dev);
1733
1734        regmap_update_bits(arizona->regmap,
1735                           ARIZONA_MICD_CLAMP_CONTROL,
1736                           ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1737
1738        if (info->micd_clamp) {
1739                jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
1740                jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
1741        } else {
1742                jack_irq_rise = ARIZONA_IRQ_JD_RISE;
1743                jack_irq_fall = ARIZONA_IRQ_JD_FALL;
1744        }
1745
1746        arizona_set_irq_wake(arizona, jack_irq_rise, 0);
1747        arizona_set_irq_wake(arizona, jack_irq_fall, 0);
1748        arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
1749        arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
1750        arizona_free_irq(arizona, jack_irq_rise, info);
1751        arizona_free_irq(arizona, jack_irq_fall, info);
1752        cancel_delayed_work_sync(&info->hpdet_work);
1753        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1754                           ARIZONA_JD1_ENA, 0);
1755        arizona_clk32k_disable(arizona);
1756
1757        return 0;
1758}
1759
1760static struct platform_driver arizona_extcon_driver = {
1761        .driver         = {
1762                .name   = "arizona-extcon",
1763        },
1764        .probe          = arizona_extcon_probe,
1765        .remove         = arizona_extcon_remove,
1766};
1767
1768module_platform_driver(arizona_extcon_driver);
1769
1770MODULE_DESCRIPTION("Arizona Extcon driver");
1771MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1772MODULE_LICENSE("GPL");
1773MODULE_ALIAS("platform:extcon-arizona");
1774