linux/drivers/extcon/extcon-max77693.c
<<
>>
Prefs
   1/*
   2 * extcon-max77693.c - MAX77693 extcon driver to support MAX77693 MUIC
   3 *
   4 * Copyright (C) 2012 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/slab.h>
  22#include <linux/interrupt.h>
  23#include <linux/err.h>
  24#include <linux/platform_device.h>
  25#include <linux/mfd/max77693.h>
  26#include <linux/mfd/max77693-private.h>
  27#include <linux/extcon.h>
  28#include <linux/regmap.h>
  29#include <linux/irqdomain.h>
  30
  31#define DEV_NAME                        "max77693-muic"
  32
  33/* MAX77693 MUIC - STATUS1~3 Register */
  34#define STATUS1_ADC_SHIFT               (0)
  35#define STATUS1_ADCLOW_SHIFT            (5)
  36#define STATUS1_ADCERR_SHIFT            (6)
  37#define STATUS1_ADC1K_SHIFT             (7)
  38#define STATUS1_ADC_MASK                (0x1f << STATUS1_ADC_SHIFT)
  39#define STATUS1_ADCLOW_MASK             (0x1 << STATUS1_ADCLOW_SHIFT)
  40#define STATUS1_ADCERR_MASK             (0x1 << STATUS1_ADCERR_SHIFT)
  41#define STATUS1_ADC1K_MASK              (0x1 << STATUS1_ADC1K_SHIFT)
  42
  43#define STATUS2_CHGTYP_SHIFT            (0)
  44#define STATUS2_CHGDETRUN_SHIFT         (3)
  45#define STATUS2_DCDTMR_SHIFT            (4)
  46#define STATUS2_DXOVP_SHIFT             (5)
  47#define STATUS2_VBVOLT_SHIFT            (6)
  48#define STATUS2_VIDRM_SHIFT             (7)
  49#define STATUS2_CHGTYP_MASK             (0x7 << STATUS2_CHGTYP_SHIFT)
  50#define STATUS2_CHGDETRUN_MASK          (0x1 << STATUS2_CHGDETRUN_SHIFT)
  51#define STATUS2_DCDTMR_MASK             (0x1 << STATUS2_DCDTMR_SHIFT)
  52#define STATUS2_DXOVP_MASK              (0x1 << STATUS2_DXOVP_SHIFT)
  53#define STATUS2_VBVOLT_MASK             (0x1 << STATUS2_VBVOLT_SHIFT)
  54#define STATUS2_VIDRM_MASK              (0x1 << STATUS2_VIDRM_SHIFT)
  55
  56#define STATUS3_OVP_SHIFT               (2)
  57#define STATUS3_OVP_MASK                (0x1 << STATUS3_OVP_SHIFT)
  58
  59/* MAX77693 CDETCTRL1~2 register */
  60#define CDETCTRL1_CHGDETEN_SHIFT        (0)
  61#define CDETCTRL1_CHGTYPMAN_SHIFT       (1)
  62#define CDETCTRL1_DCDEN_SHIFT           (2)
  63#define CDETCTRL1_DCD2SCT_SHIFT         (3)
  64#define CDETCTRL1_CDDELAY_SHIFT         (4)
  65#define CDETCTRL1_DCDCPL_SHIFT          (5)
  66#define CDETCTRL1_CDPDET_SHIFT          (7)
  67#define CDETCTRL1_CHGDETEN_MASK         (0x1 << CDETCTRL1_CHGDETEN_SHIFT)
  68#define CDETCTRL1_CHGTYPMAN_MASK        (0x1 << CDETCTRL1_CHGTYPMAN_SHIFT)
  69#define CDETCTRL1_DCDEN_MASK            (0x1 << CDETCTRL1_DCDEN_SHIFT)
  70#define CDETCTRL1_DCD2SCT_MASK          (0x1 << CDETCTRL1_DCD2SCT_SHIFT)
  71#define CDETCTRL1_CDDELAY_MASK          (0x1 << CDETCTRL1_CDDELAY_SHIFT)
  72#define CDETCTRL1_DCDCPL_MASK           (0x1 << CDETCTRL1_DCDCPL_SHIFT)
  73#define CDETCTRL1_CDPDET_MASK           (0x1 << CDETCTRL1_CDPDET_SHIFT)
  74
  75#define CDETCTRL2_VIDRMEN_SHIFT         (1)
  76#define CDETCTRL2_DXOVPEN_SHIFT         (3)
  77#define CDETCTRL2_VIDRMEN_MASK          (0x1 << CDETCTRL2_VIDRMEN_SHIFT)
  78#define CDETCTRL2_DXOVPEN_MASK          (0x1 << CDETCTRL2_DXOVPEN_SHIFT)
  79
  80/* MAX77693 MUIC - CONTROL1~3 register */
  81#define COMN1SW_SHIFT                   (0)
  82#define COMP2SW_SHIFT                   (3)
  83#define COMN1SW_MASK                    (0x7 << COMN1SW_SHIFT)
  84#define COMP2SW_MASK                    (0x7 << COMP2SW_SHIFT)
  85#define COMP_SW_MASK                    (COMP2SW_MASK | COMN1SW_MASK)
  86#define CONTROL1_SW_USB                 ((1 << COMP2SW_SHIFT) \
  87                                                | (1 << COMN1SW_SHIFT))
  88#define CONTROL1_SW_AUDIO               ((2 << COMP2SW_SHIFT) \
  89                                                | (2 << COMN1SW_SHIFT))
  90#define CONTROL1_SW_UART                ((3 << COMP2SW_SHIFT) \
  91                                                | (3 << COMN1SW_SHIFT))
  92#define CONTROL1_SW_OPEN                ((0 << COMP2SW_SHIFT) \
  93                                                | (0 << COMN1SW_SHIFT))
  94
  95#define CONTROL2_LOWPWR_SHIFT           (0)
  96#define CONTROL2_ADCEN_SHIFT            (1)
  97#define CONTROL2_CPEN_SHIFT             (2)
  98#define CONTROL2_SFOUTASRT_SHIFT        (3)
  99#define CONTROL2_SFOUTORD_SHIFT         (4)
 100#define CONTROL2_ACCDET_SHIFT           (5)
 101#define CONTROL2_USBCPINT_SHIFT         (6)
 102#define CONTROL2_RCPS_SHIFT             (7)
 103#define CONTROL2_LOWPWR_MASK            (0x1 << CONTROL2_LOWPWR_SHIFT)
 104#define CONTROL2_ADCEN_MASK             (0x1 << CONTROL2_ADCEN_SHIFT)
 105#define CONTROL2_CPEN_MASK              (0x1 << CONTROL2_CPEN_SHIFT)
 106#define CONTROL2_SFOUTASRT_MASK         (0x1 << CONTROL2_SFOUTASRT_SHIFT)
 107#define CONTROL2_SFOUTORD_MASK          (0x1 << CONTROL2_SFOUTORD_SHIFT)
 108#define CONTROL2_ACCDET_MASK            (0x1 << CONTROL2_ACCDET_SHIFT)
 109#define CONTROL2_USBCPINT_MASK          (0x1 << CONTROL2_USBCPINT_SHIFT)
 110#define CONTROL2_RCPS_MASK              (0x1 << CONTROL2_RCPS_SHIFT)
 111
 112#define CONTROL3_JIGSET_SHIFT           (0)
 113#define CONTROL3_BTLDSET_SHIFT          (2)
 114#define CONTROL3_ADCDBSET_SHIFT         (4)
 115#define CONTROL3_JIGSET_MASK            (0x3 << CONTROL3_JIGSET_SHIFT)
 116#define CONTROL3_BTLDSET_MASK           (0x3 << CONTROL3_BTLDSET_SHIFT)
 117#define CONTROL3_ADCDBSET_MASK          (0x3 << CONTROL3_ADCDBSET_SHIFT)
 118
 119enum max77693_muic_adc_debounce_time {
 120        ADC_DEBOUNCE_TIME_5MS = 0,
 121        ADC_DEBOUNCE_TIME_10MS,
 122        ADC_DEBOUNCE_TIME_25MS,
 123        ADC_DEBOUNCE_TIME_38_62MS,
 124};
 125
 126struct max77693_muic_info {
 127        struct device *dev;
 128        struct max77693_dev *max77693;
 129        struct extcon_dev *edev;
 130        int prev_adc;
 131        int prev_adc_gnd;
 132        int prev_chg_type;
 133        u8 status[2];
 134
 135        int irq;
 136        struct work_struct irq_work;
 137        struct mutex mutex;
 138};
 139
 140enum max77693_muic_charger_type {
 141        MAX77693_CHARGER_TYPE_NONE = 0,
 142        MAX77693_CHARGER_TYPE_USB,
 143        MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT,
 144        MAX77693_CHARGER_TYPE_DEDICATED_CHG,
 145        MAX77693_CHARGER_TYPE_APPLE_500MA,
 146        MAX77693_CHARGER_TYPE_APPLE_1A_2A,
 147        MAX77693_CHARGER_TYPE_DEAD_BATTERY = 7,
 148};
 149
 150/**
 151 * struct max77693_muic_irq
 152 * @irq: the index of irq list of MUIC device.
 153 * @name: the name of irq.
 154 * @virq: the virtual irq to use irq domain
 155 */
 156struct max77693_muic_irq {
 157        unsigned int irq;
 158        const char *name;
 159        unsigned int virq;
 160};
 161
 162static struct max77693_muic_irq muic_irqs[] = {
 163        { MAX77693_MUIC_IRQ_INT1_ADC,           "muic-ADC" },
 164        { MAX77693_MUIC_IRQ_INT1_ADC_LOW,       "muic-ADCLOW" },
 165        { MAX77693_MUIC_IRQ_INT1_ADC_ERR,       "muic-ADCError" },
 166        { MAX77693_MUIC_IRQ_INT1_ADC1K,         "muic-ADC1K" },
 167        { MAX77693_MUIC_IRQ_INT2_CHGTYP,        "muic-CHGTYP" },
 168        { MAX77693_MUIC_IRQ_INT2_CHGDETREUN,    "muic-CHGDETREUN" },
 169        { MAX77693_MUIC_IRQ_INT2_DCDTMR,        "muic-DCDTMR" },
 170        { MAX77693_MUIC_IRQ_INT2_DXOVP,         "muic-DXOVP" },
 171        { MAX77693_MUIC_IRQ_INT2_VBVOLT,        "muic-VBVOLT" },
 172        { MAX77693_MUIC_IRQ_INT2_VIDRM,         "muic-VIDRM" },
 173        { MAX77693_MUIC_IRQ_INT3_EOC,           "muic-EOC" },
 174        { MAX77693_MUIC_IRQ_INT3_CGMBC,         "muic-CGMBC" },
 175        { MAX77693_MUIC_IRQ_INT3_OVP,           "muic-OVP" },
 176        { MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR,    "muic-MBCCHG_ERR" },
 177        { MAX77693_MUIC_IRQ_INT3_CHG_ENABLED,   "muic-CHG_ENABLED" },
 178        { MAX77693_MUIC_IRQ_INT3_BAT_DET,       "muic-BAT_DET" },
 179};
 180
 181/* Define supported accessory type */
 182enum max77693_muic_acc_type {
 183        MAX77693_MUIC_ADC_GROUND = 0x0,
 184        MAX77693_MUIC_ADC_SEND_END_BUTTON,
 185        MAX77693_MUIC_ADC_REMOTE_S1_BUTTON,
 186        MAX77693_MUIC_ADC_REMOTE_S2_BUTTON,
 187        MAX77693_MUIC_ADC_REMOTE_S3_BUTTON,
 188        MAX77693_MUIC_ADC_REMOTE_S4_BUTTON,
 189        MAX77693_MUIC_ADC_REMOTE_S5_BUTTON,
 190        MAX77693_MUIC_ADC_REMOTE_S6_BUTTON,
 191        MAX77693_MUIC_ADC_REMOTE_S7_BUTTON,
 192        MAX77693_MUIC_ADC_REMOTE_S8_BUTTON,
 193        MAX77693_MUIC_ADC_REMOTE_S9_BUTTON,
 194        MAX77693_MUIC_ADC_REMOTE_S10_BUTTON,
 195        MAX77693_MUIC_ADC_REMOTE_S11_BUTTON,
 196        MAX77693_MUIC_ADC_REMOTE_S12_BUTTON,
 197        MAX77693_MUIC_ADC_RESERVED_ACC_1,
 198        MAX77693_MUIC_ADC_RESERVED_ACC_2,
 199        MAX77693_MUIC_ADC_RESERVED_ACC_3,
 200        MAX77693_MUIC_ADC_RESERVED_ACC_4,
 201        MAX77693_MUIC_ADC_RESERVED_ACC_5,
 202        MAX77693_MUIC_ADC_CEA936_AUDIO,
 203        MAX77693_MUIC_ADC_PHONE_POWERED_DEV,
 204        MAX77693_MUIC_ADC_TTY_CONVERTER,
 205        MAX77693_MUIC_ADC_UART_CABLE,
 206        MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG,
 207        MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF,
 208        MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON,
 209        MAX77693_MUIC_ADC_AV_CABLE_NOLOAD,
 210        MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG,
 211        MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF,
 212        MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON,
 213        MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE,
 214        MAX77693_MUIC_ADC_OPEN,
 215
 216        /* The below accessories have same ADC value so ADCLow and
 217           ADC1K bit is used to separate specific accessory */
 218        MAX77693_MUIC_GND_USB_OTG = 0x100,      /* ADC:0x0, ADCLow:0, ADC1K:0 */
 219        MAX77693_MUIC_GND_AV_CABLE_LOAD = 0x102,/* ADC:0x0, ADCLow:1, ADC1K:0 */
 220        MAX77693_MUIC_GND_MHL_CABLE = 0x103,    /* ADC:0x0, ADCLow:1, ADC1K:1 */
 221};
 222
 223/* MAX77693 MUIC device support below list of accessories(external connector) */
 224const char *max77693_extcon_cable[] = {
 225        [0] = "USB",
 226        [1] = "USB-Host",
 227        [2] = "TA",
 228        [3] = "Fast-charger",
 229        [4] = "Slow-charger",
 230        [5] = "Charge-downstream",
 231        [6] = "MHL",
 232        [7] = "Audio-video-load",
 233        [8] = "Audio-video-noload",
 234        [9] = "JIG",
 235
 236        NULL,
 237};
 238
 239static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
 240                enum max77693_muic_adc_debounce_time time)
 241{
 242        int ret = 0;
 243        u8 ctrl3;
 244
 245        switch (time) {
 246        case ADC_DEBOUNCE_TIME_5MS:
 247        case ADC_DEBOUNCE_TIME_10MS:
 248        case ADC_DEBOUNCE_TIME_25MS:
 249        case ADC_DEBOUNCE_TIME_38_62MS:
 250                ret = max77693_read_reg(info->max77693->regmap_muic,
 251                                MAX77693_MUIC_REG_CTRL3, &ctrl3);
 252                ctrl3 &= ~CONTROL3_ADCDBSET_MASK;
 253                ctrl3 |= (time << CONTROL3_ADCDBSET_SHIFT);
 254
 255                ret = max77693_write_reg(info->max77693->regmap_muic,
 256                                MAX77693_MUIC_REG_CTRL3, ctrl3);
 257                if (ret) {
 258                        dev_err(info->dev, "failed to set ADC debounce time\n");
 259                        ret = -EINVAL;
 260                }
 261                break;
 262        default:
 263                dev_err(info->dev, "invalid ADC debounce time\n");
 264                ret = -EINVAL;
 265                break;
 266        }
 267
 268        return ret;
 269};
 270
 271static int max77693_muic_set_path(struct max77693_muic_info *info,
 272                u8 val, bool attached)
 273{
 274        int ret = 0;
 275        u8 ctrl1, ctrl2 = 0;
 276
 277        if (attached)
 278                ctrl1 = val;
 279        else
 280                ctrl1 = CONTROL1_SW_OPEN;
 281
 282        ret = max77693_update_reg(info->max77693->regmap_muic,
 283                        MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK);
 284        if (ret < 0) {
 285                dev_err(info->dev, "failed to update MUIC register\n");
 286                goto out;
 287        }
 288
 289        if (attached)
 290                ctrl2 |= CONTROL2_CPEN_MASK;    /* LowPwr=0, CPEn=1 */
 291        else
 292                ctrl2 |= CONTROL2_LOWPWR_MASK;  /* LowPwr=1, CPEn=0 */
 293
 294        ret = max77693_update_reg(info->max77693->regmap_muic,
 295                        MAX77693_MUIC_REG_CTRL2, ctrl2,
 296                        CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK);
 297        if (ret < 0) {
 298                dev_err(info->dev, "failed to update MUIC register\n");
 299                goto out;
 300        }
 301
 302        dev_info(info->dev,
 303                "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
 304                ctrl1, ctrl2, attached ? "attached" : "detached");
 305out:
 306        return ret;
 307}
 308
 309static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info,
 310                bool attached)
 311{
 312        int ret = 0;
 313        int type;
 314        int adc, adc1k, adclow;
 315
 316        if (attached) {
 317                adc = info->status[0] & STATUS1_ADC_MASK;
 318                adclow = info->status[0] & STATUS1_ADCLOW_MASK;
 319                adclow >>= STATUS1_ADCLOW_SHIFT;
 320                adc1k = info->status[0] & STATUS1_ADC1K_MASK;
 321                adc1k >>= STATUS1_ADC1K_SHIFT;
 322
 323                /**
 324                 * [0x1][ADCLow][ADC1K]
 325                 * [0x1    0       0  ] : USB_OTG
 326                 * [0x1    1       0  ] : Audio Video Cable with load
 327                 * [0x1    1       1  ] : MHL
 328                 */
 329                type = ((0x1 << 8) | (adclow << 1) | adc1k);
 330
 331                /* Store previous ADC value to handle accessory
 332                   when accessory will be detached */
 333                info->prev_adc = adc;
 334                info->prev_adc_gnd = type;
 335        } else
 336                type = info->prev_adc_gnd;
 337
 338        switch (type) {
 339        case MAX77693_MUIC_GND_USB_OTG:
 340                /* USB_OTG */
 341                ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached);
 342                if (ret < 0)
 343                        goto out;
 344                extcon_set_cable_state(info->edev, "USB-Host", attached);
 345                break;
 346        case MAX77693_MUIC_GND_AV_CABLE_LOAD:
 347                /* Audio Video Cable with load */
 348                ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
 349                if (ret < 0)
 350                        goto out;
 351                extcon_set_cable_state(info->edev,
 352                                "Audio-video-load", attached);
 353                break;
 354        case MAX77693_MUIC_GND_MHL_CABLE:
 355                /* MHL */
 356                extcon_set_cable_state(info->edev, "MHL", attached);
 357                break;
 358        default:
 359                dev_err(info->dev, "faild to detect %s accessory\n",
 360                        attached ? "attached" : "detached");
 361                dev_err(info->dev, "- adc:0x%x, adclow:0x%x, adc1k:0x%x\n",
 362                        adc, adclow, adc1k);
 363                ret = -EINVAL;
 364                break;
 365        }
 366
 367out:
 368        return ret;
 369}
 370
 371static int max77693_muic_adc_handler(struct max77693_muic_info *info,
 372                int curr_adc, bool attached)
 373{
 374        int ret = 0;
 375        int adc;
 376
 377        if (attached) {
 378                /* Store ADC value to handle accessory
 379                   when accessory will be detached */
 380                info->prev_adc = curr_adc;
 381                adc = curr_adc;
 382        } else
 383                adc = info->prev_adc;
 384
 385        dev_info(info->dev,
 386                "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
 387                attached ? "attached" : "detached", curr_adc, info->prev_adc);
 388
 389        switch (adc) {
 390        case MAX77693_MUIC_ADC_GROUND:
 391                /* USB_OTG/MHL/Audio */
 392                max77693_muic_adc_ground_handler(info, attached);
 393                break;
 394        case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF:
 395        case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON:
 396                /* USB */
 397                ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached);
 398                if (ret < 0)
 399                        goto out;
 400                extcon_set_cable_state(info->edev, "USB", attached);
 401                break;
 402        case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF:
 403        case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON:
 404                /* JIG */
 405                ret = max77693_muic_set_path(info, CONTROL1_SW_UART, attached);
 406                if (ret < 0)
 407                        goto out;
 408                extcon_set_cable_state(info->edev, "JIG", attached);
 409                break;
 410        case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE:
 411                /* Audio Video cable with no-load */
 412                ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
 413                if (ret < 0)
 414                        goto out;
 415                extcon_set_cable_state(info->edev,
 416                                "Audio-video-noload", attached);
 417                break;
 418        case MAX77693_MUIC_ADC_SEND_END_BUTTON:
 419        case MAX77693_MUIC_ADC_REMOTE_S1_BUTTON:
 420        case MAX77693_MUIC_ADC_REMOTE_S2_BUTTON:
 421        case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON:
 422        case MAX77693_MUIC_ADC_REMOTE_S4_BUTTON:
 423        case MAX77693_MUIC_ADC_REMOTE_S5_BUTTON:
 424        case MAX77693_MUIC_ADC_REMOTE_S6_BUTTON:
 425        case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON:
 426        case MAX77693_MUIC_ADC_REMOTE_S8_BUTTON:
 427        case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON:
 428        case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON:
 429        case MAX77693_MUIC_ADC_REMOTE_S11_BUTTON:
 430        case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON:
 431        case MAX77693_MUIC_ADC_RESERVED_ACC_1:
 432        case MAX77693_MUIC_ADC_RESERVED_ACC_2:
 433        case MAX77693_MUIC_ADC_RESERVED_ACC_3:
 434        case MAX77693_MUIC_ADC_RESERVED_ACC_4:
 435        case MAX77693_MUIC_ADC_RESERVED_ACC_5:
 436        case MAX77693_MUIC_ADC_CEA936_AUDIO:
 437        case MAX77693_MUIC_ADC_PHONE_POWERED_DEV:
 438        case MAX77693_MUIC_ADC_TTY_CONVERTER:
 439        case MAX77693_MUIC_ADC_UART_CABLE:
 440        case MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG:
 441        case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD:
 442        case MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG:
 443                /* This accessory isn't used in general case if it is specially
 444                   needed to detect additional accessory, should implement
 445                   proper operation when this accessory is attached/detached. */
 446                dev_info(info->dev,
 447                        "accessory is %s but it isn't used (adc:0x%x)\n",
 448                        attached ? "attached" : "detached", adc);
 449                goto out;
 450        default:
 451                dev_err(info->dev,
 452                        "failed to detect %s accessory (adc:0x%x)\n",
 453                        attached ? "attached" : "detached", adc);
 454                ret = -EINVAL;
 455                goto out;
 456        }
 457
 458out:
 459        return ret;
 460}
 461
 462static int max77693_muic_chg_handler(struct max77693_muic_info *info,
 463                int curr_chg_type, bool attached)
 464{
 465        int ret = 0;
 466        int chg_type;
 467
 468        if (attached) {
 469                /* Store previous charger type to control
 470                   when charger accessory will be detached */
 471                info->prev_chg_type = curr_chg_type;
 472                chg_type = curr_chg_type;
 473        } else
 474                chg_type = info->prev_chg_type;
 475
 476        dev_info(info->dev,
 477                "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
 478                        attached ? "attached" : "detached",
 479                        curr_chg_type, info->prev_chg_type);
 480
 481        switch (chg_type) {
 482        case MAX77693_CHARGER_TYPE_USB:
 483                ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached);
 484                if (ret < 0)
 485                        goto out;
 486                extcon_set_cable_state(info->edev, "USB", attached);
 487                break;
 488        case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT:
 489                extcon_set_cable_state(info->edev,
 490                                "Charge-downstream", attached);
 491                break;
 492        case MAX77693_CHARGER_TYPE_DEDICATED_CHG:
 493                extcon_set_cable_state(info->edev, "TA", attached);
 494                break;
 495        case MAX77693_CHARGER_TYPE_APPLE_500MA:
 496                extcon_set_cable_state(info->edev, "Slow-charger", attached);
 497                break;
 498        case MAX77693_CHARGER_TYPE_APPLE_1A_2A:
 499                extcon_set_cable_state(info->edev, "Fast-charger", attached);
 500                break;
 501        case MAX77693_CHARGER_TYPE_DEAD_BATTERY:
 502                break;
 503        default:
 504                dev_err(info->dev,
 505                        "failed to detect %s accessory (chg_type:0x%x)\n",
 506                        attached ? "attached" : "detached", chg_type);
 507                ret = -EINVAL;
 508                goto out;
 509        }
 510
 511out:
 512        return ret;
 513}
 514
 515static void max77693_muic_irq_work(struct work_struct *work)
 516{
 517        struct max77693_muic_info *info = container_of(work,
 518                        struct max77693_muic_info, irq_work);
 519        int curr_adc, curr_chg_type;
 520        int irq_type = -1;
 521        int i, ret = 0;
 522        bool attached = true;
 523
 524        if (!info->edev)
 525                return;
 526
 527        mutex_lock(&info->mutex);
 528
 529        for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++)
 530                if (info->irq == muic_irqs[i].virq)
 531                        irq_type = muic_irqs[i].irq;
 532
 533        ret = max77693_bulk_read(info->max77693->regmap_muic,
 534                        MAX77693_MUIC_REG_STATUS1, 2, info->status);
 535        if (ret) {
 536                dev_err(info->dev, "failed to read MUIC register\n");
 537                mutex_unlock(&info->mutex);
 538                return;
 539        }
 540
 541        switch (irq_type) {
 542        case MAX77693_MUIC_IRQ_INT1_ADC:
 543        case MAX77693_MUIC_IRQ_INT1_ADC_LOW:
 544        case MAX77693_MUIC_IRQ_INT1_ADC_ERR:
 545        case MAX77693_MUIC_IRQ_INT1_ADC1K:
 546                /* Handle all of accessory except for
 547                   type of charger accessory */
 548                curr_adc = info->status[0] & STATUS1_ADC_MASK;
 549                curr_adc >>= STATUS1_ADC_SHIFT;
 550
 551                /* Check accossory state which is either detached or attached */
 552                if (curr_adc == MAX77693_MUIC_ADC_OPEN)
 553                        attached = false;
 554
 555                ret = max77693_muic_adc_handler(info, curr_adc, attached);
 556                break;
 557        case MAX77693_MUIC_IRQ_INT2_CHGTYP:
 558        case MAX77693_MUIC_IRQ_INT2_CHGDETREUN:
 559        case MAX77693_MUIC_IRQ_INT2_DCDTMR:
 560        case MAX77693_MUIC_IRQ_INT2_DXOVP:
 561        case MAX77693_MUIC_IRQ_INT2_VBVOLT:
 562        case MAX77693_MUIC_IRQ_INT2_VIDRM:
 563                /* Handle charger accessory */
 564                curr_chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
 565                curr_chg_type >>= STATUS2_CHGTYP_SHIFT;
 566
 567                /* Check charger accossory state which
 568                   is either detached or attached */
 569                if (curr_chg_type == MAX77693_CHARGER_TYPE_NONE)
 570                        attached = false;
 571
 572                ret = max77693_muic_chg_handler(info, curr_chg_type, attached);
 573                break;
 574        case MAX77693_MUIC_IRQ_INT3_EOC:
 575        case MAX77693_MUIC_IRQ_INT3_CGMBC:
 576        case MAX77693_MUIC_IRQ_INT3_OVP:
 577        case MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR:
 578        case MAX77693_MUIC_IRQ_INT3_CHG_ENABLED:
 579        case MAX77693_MUIC_IRQ_INT3_BAT_DET:
 580                break;
 581        default:
 582                dev_err(info->dev, "muic interrupt: irq %d occurred\n",
 583                                irq_type);
 584                break;
 585        }
 586
 587        if (ret < 0)
 588                dev_err(info->dev, "failed to handle MUIC interrupt\n");
 589
 590        mutex_unlock(&info->mutex);
 591
 592        return;
 593}
 594
 595static irqreturn_t max77693_muic_irq_handler(int irq, void *data)
 596{
 597        struct max77693_muic_info *info = data;
 598
 599        info->irq = irq;
 600        schedule_work(&info->irq_work);
 601
 602        return IRQ_HANDLED;
 603}
 604
 605static struct regmap_config max77693_muic_regmap_config = {
 606        .reg_bits = 8,
 607        .val_bits = 8,
 608};
 609
 610static int max77693_muic_detect_accessory(struct max77693_muic_info *info)
 611{
 612        int ret = 0;
 613        int adc, chg_type;
 614
 615        mutex_lock(&info->mutex);
 616
 617        /* Read STATUSx register to detect accessory */
 618        ret = max77693_bulk_read(info->max77693->regmap_muic,
 619                        MAX77693_MUIC_REG_STATUS1, 2, info->status);
 620        if (ret) {
 621                dev_err(info->dev, "failed to read MUIC register\n");
 622                mutex_unlock(&info->mutex);
 623                return -EINVAL;
 624        }
 625
 626        adc = info->status[0] & STATUS1_ADC_MASK;
 627        adc >>= STATUS1_ADC_SHIFT;
 628
 629        if (adc != MAX77693_MUIC_ADC_OPEN) {
 630                dev_info(info->dev,
 631                        "external connector is attached (adc:0x%02x)\n", adc);
 632
 633                ret = max77693_muic_adc_handler(info, adc, true);
 634                if (ret < 0)
 635                        dev_err(info->dev, "failed to detect accessory\n");
 636                goto out;
 637        }
 638
 639        chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
 640        chg_type >>= STATUS2_CHGTYP_SHIFT;
 641
 642        if (chg_type != MAX77693_CHARGER_TYPE_NONE) {
 643                dev_info(info->dev,
 644                        "external connector is attached (chg_type:0x%x)\n",
 645                        chg_type);
 646
 647                max77693_muic_chg_handler(info, chg_type, true);
 648                if (ret < 0)
 649                        dev_err(info->dev, "failed to detect charger accessory\n");
 650        }
 651
 652out:
 653        mutex_unlock(&info->mutex);
 654        return ret;
 655}
 656
 657static int __devinit max77693_muic_probe(struct platform_device *pdev)
 658{
 659        struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
 660        struct max77693_muic_info *info;
 661        int ret, i;
 662        u8 id;
 663
 664        info = kzalloc(sizeof(struct max77693_muic_info), GFP_KERNEL);
 665        if (!info) {
 666                dev_err(&pdev->dev, "failed to allocate memory\n");
 667                ret = -ENOMEM;
 668                goto err_kfree;
 669        }
 670        info->dev = &pdev->dev;
 671        info->max77693 = max77693;
 672        if (info->max77693->regmap_muic)
 673                dev_dbg(&pdev->dev, "allocate register map\n");
 674        else {
 675                info->max77693->regmap_muic = devm_regmap_init_i2c(
 676                                                info->max77693->muic,
 677                                                &max77693_muic_regmap_config);
 678                if (IS_ERR(info->max77693->regmap_muic)) {
 679                        ret = PTR_ERR(info->max77693->regmap_muic);
 680                        dev_err(max77693->dev,
 681                                "failed to allocate register map: %d\n", ret);
 682                        goto err_regmap;
 683                }
 684        }
 685        platform_set_drvdata(pdev, info);
 686        mutex_init(&info->mutex);
 687
 688        INIT_WORK(&info->irq_work, max77693_muic_irq_work);
 689
 690        /* Support irq domain for MAX77693 MUIC device */
 691        for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
 692                struct max77693_muic_irq *muic_irq = &muic_irqs[i];
 693                int virq = 0;
 694
 695                virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq);
 696                if (!virq)
 697                        goto err_irq;
 698                muic_irq->virq = virq;
 699
 700                ret = request_threaded_irq(virq, NULL,
 701                                max77693_muic_irq_handler,
 702                                0, muic_irq->name, info);
 703                if (ret) {
 704                        dev_err(&pdev->dev,
 705                                "failed: irq request (IRQ: %d,"
 706                                " error :%d)\n",
 707                                muic_irq->irq, ret);
 708
 709                        for (i = i - 1; i >= 0; i--)
 710                                free_irq(muic_irq->virq, info);
 711                        goto err_irq;
 712                }
 713        }
 714
 715        /* Initialize extcon device */
 716        info->edev = kzalloc(sizeof(struct extcon_dev), GFP_KERNEL);
 717        if (!info->edev) {
 718                dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
 719                ret = -ENOMEM;
 720                goto err_irq;
 721        }
 722        info->edev->name = DEV_NAME;
 723        info->edev->supported_cable = max77693_extcon_cable;
 724        ret = extcon_dev_register(info->edev, NULL);
 725        if (ret) {
 726                dev_err(&pdev->dev, "failed to register extcon device\n");
 727                goto err_extcon;
 728        }
 729
 730        /* Check revision number of MUIC device*/
 731        ret = max77693_read_reg(info->max77693->regmap_muic,
 732                        MAX77693_MUIC_REG_ID, &id);
 733        if (ret < 0) {
 734                dev_err(&pdev->dev, "failed to read revision number\n");
 735                goto err_extcon;
 736        }
 737        dev_info(info->dev, "device ID : 0x%x\n", id);
 738
 739        /* Set ADC debounce time */
 740        max77693_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);
 741
 742        /* Detect accessory on boot */
 743        max77693_muic_detect_accessory(info);
 744
 745        return ret;
 746
 747err_extcon:
 748        kfree(info->edev);
 749err_irq:
 750err_regmap:
 751        kfree(info);
 752err_kfree:
 753        return ret;
 754}
 755
 756static int __devexit max77693_muic_remove(struct platform_device *pdev)
 757{
 758        struct max77693_muic_info *info = platform_get_drvdata(pdev);
 759        int i;
 760
 761        for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
 762                free_irq(muic_irqs[i].virq, info);
 763        cancel_work_sync(&info->irq_work);
 764        extcon_dev_unregister(info->edev);
 765        kfree(info);
 766
 767        return 0;
 768}
 769
 770static struct platform_driver max77693_muic_driver = {
 771        .driver         = {
 772                .name   = DEV_NAME,
 773                .owner  = THIS_MODULE,
 774        },
 775        .probe          = max77693_muic_probe,
 776        .remove         = __devexit_p(max77693_muic_remove),
 777};
 778
 779module_platform_driver(max77693_muic_driver);
 780
 781MODULE_DESCRIPTION("Maxim MAX77693 Extcon driver");
 782MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
 783MODULE_LICENSE("GPL");
 784MODULE_ALIAS("platform:extcon-max77693");
 785
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.