linux/drivers/extcon/extcon-max14577.c
<<
>>
Prefs
   1/*
   2 * extcon-max14577.c - MAX14577 extcon driver to support MAX14577 MUIC
   3 *
   4 * Copyright (C) 2013 Samsung Electrnoics
   5 * Chanwoo Choi <cw00.choi@samsung.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 */
  17
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/i2c.h>
  21#include <linux/interrupt.h>
  22#include <linux/platform_device.h>
  23#include <linux/mfd/max14577.h>
  24#include <linux/mfd/max14577-private.h>
  25#include <linux/extcon.h>
  26
  27#define DEV_NAME                        "max14577-muic"
  28#define DELAY_MS_DEFAULT                17000           /* unit: millisecond */
  29
  30enum max14577_muic_adc_debounce_time {
  31        ADC_DEBOUNCE_TIME_5MS = 0,
  32        ADC_DEBOUNCE_TIME_10MS,
  33        ADC_DEBOUNCE_TIME_25MS,
  34        ADC_DEBOUNCE_TIME_38_62MS,
  35};
  36
  37enum max14577_muic_status {
  38        MAX14577_MUIC_STATUS1 = 0,
  39        MAX14577_MUIC_STATUS2 = 1,
  40        MAX14577_MUIC_STATUS_END,
  41};
  42
  43struct max14577_muic_info {
  44        struct device *dev;
  45        struct max14577 *max14577;
  46        struct extcon_dev *edev;
  47        int prev_cable_type;
  48        int prev_chg_type;
  49        u8 status[MAX14577_MUIC_STATUS_END];
  50
  51        bool irq_adc;
  52        bool irq_chg;
  53        struct work_struct irq_work;
  54        struct mutex mutex;
  55
  56        /*
  57         * Use delayed workqueue to detect cable state and then
  58         * notify cable state to notifiee/platform through uevent.
  59         * After completing the booting of platform, the extcon provider
  60         * driver should notify cable state to upper layer.
  61         */
  62        struct delayed_work wq_detcable;
  63
  64        /*
  65         * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
  66         * h/w path of COMP2/COMN1 on CONTROL1 register.
  67         */
  68        int path_usb;
  69        int path_uart;
  70};
  71
  72enum max14577_muic_cable_group {
  73        MAX14577_CABLE_GROUP_ADC = 0,
  74        MAX14577_CABLE_GROUP_CHG,
  75};
  76
  77/**
  78 * struct max14577_muic_irq
  79 * @irq: the index of irq list of MUIC device.
  80 * @name: the name of irq.
  81 * @virq: the virtual irq to use irq domain
  82 */
  83struct max14577_muic_irq {
  84        unsigned int irq;
  85        const char *name;
  86        unsigned int virq;
  87};
  88
  89static struct max14577_muic_irq muic_irqs[] = {
  90        { MAX14577_IRQ_INT1_ADC,        "muic-ADC" },
  91        { MAX14577_IRQ_INT1_ADCLOW,     "muic-ADCLOW" },
  92        { MAX14577_IRQ_INT1_ADCERR,     "muic-ADCError" },
  93        { MAX14577_IRQ_INT2_CHGTYP,     "muic-CHGTYP" },
  94        { MAX14577_IRQ_INT2_CHGDETRUN,  "muic-CHGDETRUN" },
  95        { MAX14577_IRQ_INT2_DCDTMR,     "muic-DCDTMR" },
  96        { MAX14577_IRQ_INT2_DBCHG,      "muic-DBCHG" },
  97        { MAX14577_IRQ_INT2_VBVOLT,     "muic-VBVOLT" },
  98};
  99
 100/* Define supported accessory type */
 101enum max14577_muic_acc_type {
 102        MAX14577_MUIC_ADC_GROUND = 0x0,
 103        MAX14577_MUIC_ADC_SEND_END_BUTTON,
 104        MAX14577_MUIC_ADC_REMOTE_S1_BUTTON,
 105        MAX14577_MUIC_ADC_REMOTE_S2_BUTTON,
 106        MAX14577_MUIC_ADC_REMOTE_S3_BUTTON,
 107        MAX14577_MUIC_ADC_REMOTE_S4_BUTTON,
 108        MAX14577_MUIC_ADC_REMOTE_S5_BUTTON,
 109        MAX14577_MUIC_ADC_REMOTE_S6_BUTTON,
 110        MAX14577_MUIC_ADC_REMOTE_S7_BUTTON,
 111        MAX14577_MUIC_ADC_REMOTE_S8_BUTTON,
 112        MAX14577_MUIC_ADC_REMOTE_S9_BUTTON,
 113        MAX14577_MUIC_ADC_REMOTE_S10_BUTTON,
 114        MAX14577_MUIC_ADC_REMOTE_S11_BUTTON,
 115        MAX14577_MUIC_ADC_REMOTE_S12_BUTTON,
 116        MAX14577_MUIC_ADC_RESERVED_ACC_1,
 117        MAX14577_MUIC_ADC_RESERVED_ACC_2,
 118        MAX14577_MUIC_ADC_RESERVED_ACC_3,
 119        MAX14577_MUIC_ADC_RESERVED_ACC_4,
 120        MAX14577_MUIC_ADC_RESERVED_ACC_5,
 121        MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE2,
 122        MAX14577_MUIC_ADC_PHONE_POWERED_DEV,
 123        MAX14577_MUIC_ADC_TTY_CONVERTER,
 124        MAX14577_MUIC_ADC_UART_CABLE,
 125        MAX14577_MUIC_ADC_CEA936A_TYPE1_CHG,
 126        MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF,
 127        MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON,
 128        MAX14577_MUIC_ADC_AV_CABLE_NOLOAD,
 129        MAX14577_MUIC_ADC_CEA936A_TYPE2_CHG,
 130        MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF,
 131        MAX14577_MUIC_ADC_FACTORY_MODE_UART_ON,
 132        MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE1, /* with Remote and Simple Ctrl */
 133        MAX14577_MUIC_ADC_OPEN,
 134};
 135
 136/* max14577 MUIC device support below list of accessories(external connector) */
 137enum {
 138        EXTCON_CABLE_USB = 0,
 139        EXTCON_CABLE_TA,
 140        EXTCON_CABLE_FAST_CHARGER,
 141        EXTCON_CABLE_SLOW_CHARGER,
 142        EXTCON_CABLE_CHARGE_DOWNSTREAM,
 143        EXTCON_CABLE_JIG_USB_ON,
 144        EXTCON_CABLE_JIG_USB_OFF,
 145        EXTCON_CABLE_JIG_UART_OFF,
 146        EXTCON_CABLE_JIG_UART_ON,
 147
 148        _EXTCON_CABLE_NUM,
 149};
 150
 151static const char *max14577_extcon_cable[] = {
 152        [EXTCON_CABLE_USB]                      = "USB",
 153        [EXTCON_CABLE_TA]                       = "TA",
 154        [EXTCON_CABLE_FAST_CHARGER]             = "Fast-charger",
 155        [EXTCON_CABLE_SLOW_CHARGER]             = "Slow-charger",
 156        [EXTCON_CABLE_CHARGE_DOWNSTREAM]        = "Charge-downstream",
 157        [EXTCON_CABLE_JIG_USB_ON]               = "JIG-USB-ON",
 158        [EXTCON_CABLE_JIG_USB_OFF]              = "JIG-USB-OFF",
 159        [EXTCON_CABLE_JIG_UART_OFF]             = "JIG-UART-OFF",
 160        [EXTCON_CABLE_JIG_UART_ON]              = "JIG-UART-ON",
 161
 162        NULL,
 163};
 164
 165/*
 166 * max14577_muic_set_debounce_time - Set the debounce time of ADC
 167 * @info: the instance including private data of max14577 MUIC
 168 * @time: the debounce time of ADC
 169 */
 170static int max14577_muic_set_debounce_time(struct max14577_muic_info *info,
 171                enum max14577_muic_adc_debounce_time time)
 172{
 173        u8 ret;
 174
 175        switch (time) {
 176        case ADC_DEBOUNCE_TIME_5MS:
 177        case ADC_DEBOUNCE_TIME_10MS:
 178        case ADC_DEBOUNCE_TIME_25MS:
 179        case ADC_DEBOUNCE_TIME_38_62MS:
 180                ret = max14577_update_reg(info->max14577->regmap,
 181                                          MAX14577_MUIC_REG_CONTROL3,
 182                                          CTRL3_ADCDBSET_MASK,
 183                                          time << CTRL3_ADCDBSET_SHIFT);
 184                if (ret) {
 185                        dev_err(info->dev, "failed to set ADC debounce time\n");
 186                        return ret;
 187                }
 188                break;
 189        default:
 190                dev_err(info->dev, "invalid ADC debounce time\n");
 191                return -EINVAL;
 192        }
 193
 194        return 0;
 195};
 196
 197/*
 198 * max14577_muic_set_path - Set hardware line according to attached cable
 199 * @info: the instance including private data of max14577 MUIC
 200 * @value: the path according to attached cable
 201 * @attached: the state of cable (true:attached, false:detached)
 202 *
 203 * The max14577 MUIC device share outside H/W line among a varity of cables
 204 * so, this function set internal path of H/W line according to the type of
 205 * attached cable.
 206 */
 207static int max14577_muic_set_path(struct max14577_muic_info *info,
 208                u8 val, bool attached)
 209{
 210        int ret = 0;
 211        u8 ctrl1, ctrl2 = 0;
 212
 213        /* Set open state to path before changing hw path */
 214        ret = max14577_update_reg(info->max14577->regmap,
 215                                MAX14577_MUIC_REG_CONTROL1,
 216                                CLEAR_IDBEN_MICEN_MASK, CTRL1_SW_OPEN);
 217        if (ret < 0) {
 218                dev_err(info->dev, "failed to update MUIC register\n");
 219                return ret;
 220        }
 221
 222        if (attached)
 223                ctrl1 = val;
 224        else
 225                ctrl1 = CTRL1_SW_OPEN;
 226
 227        ret = max14577_update_reg(info->max14577->regmap,
 228                                MAX14577_MUIC_REG_CONTROL1,
 229                                CLEAR_IDBEN_MICEN_MASK, ctrl1);
 230        if (ret < 0) {
 231                dev_err(info->dev, "failed to update MUIC register\n");
 232                return ret;
 233        }
 234
 235        if (attached)
 236                ctrl2 |= CTRL2_CPEN_MASK;       /* LowPwr=0, CPEn=1 */
 237        else
 238                ctrl2 |= CTRL2_LOWPWR_MASK;     /* LowPwr=1, CPEn=0 */
 239
 240        ret = max14577_update_reg(info->max14577->regmap,
 241                        MAX14577_REG_CONTROL2,
 242                        CTRL2_LOWPWR_MASK | CTRL2_CPEN_MASK, ctrl2);
 243        if (ret < 0) {
 244                dev_err(info->dev, "failed to update MUIC register\n");
 245                return ret;
 246        }
 247
 248        dev_dbg(info->dev,
 249                "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
 250                ctrl1, ctrl2, attached ? "attached" : "detached");
 251
 252        return 0;
 253}
 254
 255/*
 256 * max14577_muic_get_cable_type - Return cable type and check cable state
 257 * @info: the instance including private data of max14577 MUIC
 258 * @group: the path according to attached cable
 259 * @attached: store cable state and return
 260 *
 261 * This function check the cable state either attached or detached,
 262 * and then divide precise type of cable according to cable group.
 263 *      - max14577_CABLE_GROUP_ADC
 264 *      - max14577_CABLE_GROUP_CHG
 265 */
 266static int max14577_muic_get_cable_type(struct max14577_muic_info *info,
 267                enum max14577_muic_cable_group group, bool *attached)
 268{
 269        int cable_type = 0;
 270        int adc;
 271        int chg_type;
 272
 273        switch (group) {
 274        case MAX14577_CABLE_GROUP_ADC:
 275                /*
 276                 * Read ADC value to check cable type and decide cable state
 277                 * according to cable type
 278                 */
 279                adc = info->status[MAX14577_MUIC_STATUS1] & STATUS1_ADC_MASK;
 280                adc >>= STATUS1_ADC_SHIFT;
 281
 282                /*
 283                 * Check current cable state/cable type and store cable type
 284                 * (info->prev_cable_type) for handling cable when cable is
 285                 * detached.
 286                 */
 287                if (adc == MAX14577_MUIC_ADC_OPEN) {
 288                        *attached = false;
 289
 290                        cable_type = info->prev_cable_type;
 291                        info->prev_cable_type = MAX14577_MUIC_ADC_OPEN;
 292                } else {
 293                        *attached = true;
 294
 295                        cable_type = info->prev_cable_type = adc;
 296                }
 297                break;
 298        case MAX14577_CABLE_GROUP_CHG:
 299                /*
 300                 * Read charger type to check cable type and decide cable state
 301                 * according to type of charger cable.
 302                 */
 303                chg_type = info->status[MAX14577_MUIC_STATUS2] &
 304                        STATUS2_CHGTYP_MASK;
 305                chg_type >>= STATUS2_CHGTYP_SHIFT;
 306
 307                if (chg_type == MAX14577_CHARGER_TYPE_NONE) {
 308                        *attached = false;
 309
 310                        cable_type = info->prev_chg_type;
 311                        info->prev_chg_type = MAX14577_CHARGER_TYPE_NONE;
 312                } else {
 313                        *attached = true;
 314
 315                        /*
 316                         * Check current cable state/cable type and store cable
 317                         * type(info->prev_chg_type) for handling cable when
 318                         * charger cable is detached.
 319                         */
 320                        cable_type = info->prev_chg_type = chg_type;
 321                }
 322
 323                break;
 324        default:
 325                dev_err(info->dev, "Unknown cable group (%d)\n", group);
 326                cable_type = -EINVAL;
 327                break;
 328        }
 329
 330        return cable_type;
 331}
 332
 333static int max14577_muic_jig_handler(struct max14577_muic_info *info,
 334                int cable_type, bool attached)
 335{
 336        char cable_name[32];
 337        int ret = 0;
 338        u8 path = CTRL1_SW_OPEN;
 339
 340        dev_dbg(info->dev,
 341                "external connector is %s (adc:0x%02x)\n",
 342                attached ? "attached" : "detached", cable_type);
 343
 344        switch (cable_type) {
 345        case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF:    /* ADC_JIG_USB_OFF */
 346                /* PATH:AP_USB */
 347                strcpy(cable_name, "JIG-USB-OFF");
 348                path = CTRL1_SW_USB;
 349                break;
 350        case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON:     /* ADC_JIG_USB_ON */
 351                /* PATH:AP_USB */
 352                strcpy(cable_name, "JIG-USB-ON");
 353                path = CTRL1_SW_USB;
 354                break;
 355        case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF:   /* ADC_JIG_UART_OFF */
 356                /* PATH:AP_UART */
 357                strcpy(cable_name, "JIG-UART-OFF");
 358                path = CTRL1_SW_UART;
 359                break;
 360        default:
 361                dev_err(info->dev, "failed to detect %s jig cable\n",
 362                        attached ? "attached" : "detached");
 363                return -EINVAL;
 364        }
 365
 366        ret = max14577_muic_set_path(info, path, attached);
 367        if (ret < 0)
 368                return ret;
 369
 370        extcon_set_cable_state(info->edev, cable_name, attached);
 371
 372        return 0;
 373}
 374
 375static int max14577_muic_adc_handler(struct max14577_muic_info *info)
 376{
 377        int cable_type;
 378        bool attached;
 379        int ret = 0;
 380
 381        /* Check accessory state which is either detached or attached */
 382        cable_type = max14577_muic_get_cable_type(info,
 383                                MAX14577_CABLE_GROUP_ADC, &attached);
 384
 385        dev_dbg(info->dev,
 386                "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
 387                attached ? "attached" : "detached", cable_type,
 388                info->prev_cable_type);
 389
 390        switch (cable_type) {
 391        case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF:
 392        case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON:
 393        case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF:
 394                /* JIG */
 395                ret = max14577_muic_jig_handler(info, cable_type, attached);
 396                if (ret < 0)
 397                        return ret;
 398                break;
 399        case MAX14577_MUIC_ADC_GROUND:
 400        case MAX14577_MUIC_ADC_SEND_END_BUTTON:
 401        case MAX14577_MUIC_ADC_REMOTE_S1_BUTTON:
 402        case MAX14577_MUIC_ADC_REMOTE_S2_BUTTON:
 403        case MAX14577_MUIC_ADC_REMOTE_S3_BUTTON:
 404        case MAX14577_MUIC_ADC_REMOTE_S4_BUTTON:
 405        case MAX14577_MUIC_ADC_REMOTE_S5_BUTTON:
 406        case MAX14577_MUIC_ADC_REMOTE_S6_BUTTON:
 407        case MAX14577_MUIC_ADC_REMOTE_S7_BUTTON:
 408        case MAX14577_MUIC_ADC_REMOTE_S8_BUTTON:
 409        case MAX14577_MUIC_ADC_REMOTE_S9_BUTTON:
 410        case MAX14577_MUIC_ADC_REMOTE_S10_BUTTON:
 411        case MAX14577_MUIC_ADC_REMOTE_S11_BUTTON:
 412        case MAX14577_MUIC_ADC_REMOTE_S12_BUTTON:
 413        case MAX14577_MUIC_ADC_RESERVED_ACC_1:
 414        case MAX14577_MUIC_ADC_RESERVED_ACC_2:
 415        case MAX14577_MUIC_ADC_RESERVED_ACC_3:
 416        case MAX14577_MUIC_ADC_RESERVED_ACC_4:
 417        case MAX14577_MUIC_ADC_RESERVED_ACC_5:
 418        case MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE2:
 419        case MAX14577_MUIC_ADC_PHONE_POWERED_DEV:
 420        case MAX14577_MUIC_ADC_TTY_CONVERTER:
 421        case MAX14577_MUIC_ADC_UART_CABLE:
 422        case MAX14577_MUIC_ADC_CEA936A_TYPE1_CHG:
 423        case MAX14577_MUIC_ADC_AV_CABLE_NOLOAD:
 424        case MAX14577_MUIC_ADC_CEA936A_TYPE2_CHG:
 425        case MAX14577_MUIC_ADC_FACTORY_MODE_UART_ON:
 426        case MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE1:
 427                /*
 428                 * This accessory isn't used in general case if it is specially
 429                 * needed to detect additional accessory, should implement
 430                 * proper operation when this accessory is attached/detached.
 431                 */
 432                dev_info(info->dev,
 433                        "accessory is %s but it isn't used (adc:0x%x)\n",
 434                        attached ? "attached" : "detached", cable_type);
 435                return -EAGAIN;
 436        default:
 437                dev_err(info->dev,
 438                        "failed to detect %s accessory (adc:0x%x)\n",
 439                        attached ? "attached" : "detached", cable_type);
 440                return -EINVAL;
 441        }
 442
 443        return 0;
 444}
 445
 446static int max14577_muic_chg_handler(struct max14577_muic_info *info)
 447{
 448        int chg_type;
 449        bool attached;
 450        int ret = 0;
 451
 452        chg_type = max14577_muic_get_cable_type(info,
 453                                MAX14577_CABLE_GROUP_CHG, &attached);
 454
 455        dev_dbg(info->dev,
 456                "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
 457                        attached ? "attached" : "detached",
 458                        chg_type, info->prev_chg_type);
 459
 460        switch (chg_type) {
 461        case MAX14577_CHARGER_TYPE_USB:
 462                /* PATH:AP_USB */
 463                ret = max14577_muic_set_path(info, info->path_usb, attached);
 464                if (ret < 0)
 465                        return ret;
 466
 467                extcon_set_cable_state(info->edev, "USB", attached);
 468                break;
 469        case MAX14577_CHARGER_TYPE_DEDICATED_CHG:
 470                extcon_set_cable_state(info->edev, "TA", attached);
 471                break;
 472        case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT:
 473                extcon_set_cable_state(info->edev,
 474                                "Charge-downstream", attached);
 475                break;
 476        case MAX14577_CHARGER_TYPE_SPECIAL_500MA:
 477                extcon_set_cable_state(info->edev, "Slow-charger", attached);
 478                break;
 479        case MAX14577_CHARGER_TYPE_SPECIAL_1A:
 480                extcon_set_cable_state(info->edev, "Fast-charger", attached);
 481                break;
 482        case MAX14577_CHARGER_TYPE_NONE:
 483        case MAX14577_CHARGER_TYPE_DEAD_BATTERY:
 484                break;
 485        default:
 486                dev_err(info->dev,
 487                        "failed to detect %s accessory (chg_type:0x%x)\n",
 488                        attached ? "attached" : "detached", chg_type);
 489                return -EINVAL;
 490        }
 491
 492        return 0;
 493}
 494
 495static void max14577_muic_irq_work(struct work_struct *work)
 496{
 497        struct max14577_muic_info *info = container_of(work,
 498                        struct max14577_muic_info, irq_work);
 499        int ret = 0;
 500
 501        if (!info->edev)
 502                return;
 503
 504        mutex_lock(&info->mutex);
 505
 506        ret = max14577_bulk_read(info->max14577->regmap,
 507                        MAX14577_MUIC_REG_STATUS1, info->status, 2);
 508        if (ret) {
 509                dev_err(info->dev, "failed to read MUIC register\n");
 510                mutex_unlock(&info->mutex);
 511                return;
 512        }
 513
 514        if (info->irq_adc) {
 515                ret = max14577_muic_adc_handler(info);
 516                info->irq_adc = false;
 517        }
 518        if (info->irq_chg) {
 519                ret = max14577_muic_chg_handler(info);
 520                info->irq_chg = false;
 521        }
 522
 523        if (ret < 0)
 524                dev_err(info->dev, "failed to handle MUIC interrupt\n");
 525
 526        mutex_unlock(&info->mutex);
 527
 528        return;
 529}
 530
 531static irqreturn_t max14577_muic_irq_handler(int irq, void *data)
 532{
 533        struct max14577_muic_info *info = data;
 534        int i, irq_type = -1;
 535
 536        /*
 537         * We may be called multiple times for different nested IRQ-s.
 538         * Including changes in INT1_ADC and INT2_CGHTYP at once.
 539         * However we only need to know whether it was ADC, charger
 540         * or both interrupts so decode IRQ and turn on proper flags.
 541         */
 542        for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
 543                if (irq == muic_irqs[i].virq)
 544                        irq_type = muic_irqs[i].irq;
 545
 546        switch (irq_type) {
 547        case MAX14577_IRQ_INT1_ADC:
 548        case MAX14577_IRQ_INT1_ADCLOW:
 549        case MAX14577_IRQ_INT1_ADCERR:
 550                /* Handle all of accessory except for
 551                   type of charger accessory */
 552                info->irq_adc = true;
 553                break;
 554        case MAX14577_IRQ_INT2_CHGTYP:
 555        case MAX14577_IRQ_INT2_CHGDETRUN:
 556        case MAX14577_IRQ_INT2_DCDTMR:
 557        case MAX14577_IRQ_INT2_DBCHG:
 558        case MAX14577_IRQ_INT2_VBVOLT:
 559                /* Handle charger accessory */
 560                info->irq_chg = true;
 561                break;
 562        default:
 563                dev_err(info->dev, "muic interrupt: irq %d occurred, skipped\n",
 564                                irq_type);
 565                return IRQ_HANDLED;
 566        }
 567        schedule_work(&info->irq_work);
 568
 569        return IRQ_HANDLED;
 570}
 571
 572static int max14577_muic_detect_accessory(struct max14577_muic_info *info)
 573{
 574        int ret = 0;
 575        int adc;
 576        int chg_type;
 577        bool attached;
 578
 579        mutex_lock(&info->mutex);
 580
 581        /* Read STATUSx register to detect accessory */
 582        ret = max14577_bulk_read(info->max14577->regmap,
 583                        MAX14577_MUIC_REG_STATUS1, info->status, 2);
 584        if (ret) {
 585                dev_err(info->dev, "failed to read MUIC register\n");
 586                mutex_unlock(&info->mutex);
 587                return ret;
 588        }
 589
 590        adc = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_ADC,
 591                                        &attached);
 592        if (attached && adc != MAX14577_MUIC_ADC_OPEN) {
 593                ret = max14577_muic_adc_handler(info);
 594                if (ret < 0) {
 595                        dev_err(info->dev, "Cannot detect accessory\n");
 596                        mutex_unlock(&info->mutex);
 597                        return ret;
 598                }
 599        }
 600
 601        chg_type = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_CHG,
 602                                        &attached);
 603        if (attached && chg_type != MAX14577_CHARGER_TYPE_NONE) {
 604                ret = max14577_muic_chg_handler(info);
 605                if (ret < 0) {
 606                        dev_err(info->dev, "Cannot detect charger accessory\n");
 607                        mutex_unlock(&info->mutex);
 608                        return ret;
 609                }
 610        }
 611
 612        mutex_unlock(&info->mutex);
 613
 614        return 0;
 615}
 616
 617static void max14577_muic_detect_cable_wq(struct work_struct *work)
 618{
 619        struct max14577_muic_info *info = container_of(to_delayed_work(work),
 620                                struct max14577_muic_info, wq_detcable);
 621
 622        max14577_muic_detect_accessory(info);
 623}
 624
 625static int max14577_muic_probe(struct platform_device *pdev)
 626{
 627        struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
 628        struct max14577_muic_info *info;
 629        int delay_jiffies;
 630        int ret;
 631        int i;
 632        u8 id;
 633
 634        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 635        if (!info) {
 636                dev_err(&pdev->dev, "failed to allocate memory\n");
 637                return -ENOMEM;
 638        }
 639        info->dev = &pdev->dev;
 640        info->max14577 = max14577;
 641
 642        platform_set_drvdata(pdev, info);
 643        mutex_init(&info->mutex);
 644
 645        INIT_WORK(&info->irq_work, max14577_muic_irq_work);
 646
 647        /* Support irq domain for max14577 MUIC device */
 648        for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
 649                struct max14577_muic_irq *muic_irq = &muic_irqs[i];
 650                unsigned int virq = 0;
 651
 652                virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq);
 653                if (!virq)
 654                        return -EINVAL;
 655                muic_irq->virq = virq;
 656
 657                ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
 658                                max14577_muic_irq_handler,
 659                                IRQF_NO_SUSPEND,
 660                                muic_irq->name, info);
 661                if (ret) {
 662                        dev_err(&pdev->dev,
 663                                "failed: irq request (IRQ: %d,"
 664                                " error :%d)\n",
 665                                muic_irq->irq, ret);
 666                        return ret;
 667                }
 668        }
 669
 670        /* Initialize extcon device */
 671        info->edev = devm_kzalloc(&pdev->dev, sizeof(*info->edev), GFP_KERNEL);
 672        if (!info->edev) {
 673                dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
 674                return -ENOMEM;
 675        }
 676        info->edev->name = DEV_NAME;
 677        info->edev->supported_cable = max14577_extcon_cable;
 678        ret = extcon_dev_register(info->edev);
 679        if (ret) {
 680                dev_err(&pdev->dev, "failed to register extcon device\n");
 681                return ret;
 682        }
 683
 684        /* Default h/w line path */
 685        info->path_usb = CTRL1_SW_USB;
 686        info->path_uart = CTRL1_SW_UART;
 687        delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
 688
 689        /* Set initial path for UART */
 690        max14577_muic_set_path(info, info->path_uart, true);
 691
 692        /* Check revision number of MUIC device*/
 693        ret = max14577_read_reg(info->max14577->regmap,
 694                        MAX14577_REG_DEVICEID, &id);
 695        if (ret < 0) {
 696                dev_err(&pdev->dev, "failed to read revision number\n");
 697                goto err_extcon;
 698        }
 699        dev_info(info->dev, "device ID : 0x%x\n", id);
 700
 701        /* Set ADC debounce time */
 702        max14577_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);
 703
 704        /*
 705         * Detect accessory after completing the initialization of platform
 706         *
 707         * - Use delayed workqueue to detect cable state and then
 708         * notify cable state to notifiee/platform through uevent.
 709         * After completing the booting of platform, the extcon provider
 710         * driver should notify cable state to upper layer.
 711         */
 712        INIT_DELAYED_WORK(&info->wq_detcable, max14577_muic_detect_cable_wq);
 713        ret = queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
 714                        delay_jiffies);
 715        if (ret < 0) {
 716                dev_err(&pdev->dev,
 717                        "failed to schedule delayed work for cable detect\n");
 718                goto err_extcon;
 719        }
 720
 721        return ret;
 722
 723err_extcon:
 724        extcon_dev_unregister(info->edev);
 725        return ret;
 726}
 727
 728static int max14577_muic_remove(struct platform_device *pdev)
 729{
 730        struct max14577_muic_info *info = platform_get_drvdata(pdev);
 731
 732        cancel_work_sync(&info->irq_work);
 733        extcon_dev_unregister(info->edev);
 734
 735        return 0;
 736}
 737
 738static struct platform_driver max14577_muic_driver = {
 739        .driver         = {
 740                .name   = DEV_NAME,
 741                .owner  = THIS_MODULE,
 742        },
 743        .probe          = max14577_muic_probe,
 744        .remove         = max14577_muic_remove,
 745};
 746
 747module_platform_driver(max14577_muic_driver);
 748
 749MODULE_DESCRIPTION("MAXIM 14577 Extcon driver");
 750MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
 751MODULE_LICENSE("GPL");
 752MODULE_ALIAS("platform:extcon-max14577");
 753