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