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