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