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