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;
 243
 244        switch (time) {
 245        case ADC_DEBOUNCE_TIME_5MS:
 246        case ADC_DEBOUNCE_TIME_10MS:
 247        case ADC_DEBOUNCE_TIME_25MS:
 248        case ADC_DEBOUNCE_TIME_38_62MS:
 249                ret = max77693_update_reg(info->max77693->regmap_muic,
 250                                          MAX77693_MUIC_REG_CTRL3,
 251                                          time << CONTROL3_ADCDBSET_SHIFT,
 252                                          CONTROL3_ADCDBSET_MASK);
 253                if (ret)
 254                        dev_err(info->dev, "failed to set ADC debounce time\n");
 255                break;
 256        default:
 257                dev_err(info->dev, "invalid ADC debounce time\n");
 258                ret = -EINVAL;
 259                break;
 260        }
 261
 262        return ret;
 263};
 264
 265static int max77693_muic_set_path(struct max77693_muic_info *info,
 266                u8 val, bool attached)
 267{
 268        int ret = 0;
 269        u8 ctrl1, ctrl2 = 0;
 270
 271        if (attached)
 272                ctrl1 = val;
 273        else
 274                ctrl1 = CONTROL1_SW_OPEN;
 275
 276        ret = max77693_update_reg(info->max77693->regmap_muic,
 277                        MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK);
 278        if (ret < 0) {
 279                dev_err(info->dev, "failed to update MUIC register\n");
 280                goto out;
 281        }
 282
 283        if (attached)
 284                ctrl2 |= CONTROL2_CPEN_MASK;    /* LowPwr=0, CPEn=1 */
 285        else
 286                ctrl2 |= CONTROL2_LOWPWR_MASK;  /* LowPwr=1, CPEn=0 */
 287
 288        ret = max77693_update_reg(info->max77693->regmap_muic,
 289                        MAX77693_MUIC_REG_CTRL2, ctrl2,
 290                        CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK);
 291        if (ret < 0) {
 292                dev_err(info->dev, "failed to update MUIC register\n");
 293                goto out;
 294        }
 295
 296        dev_info(info->dev,
 297                "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
 298                ctrl1, ctrl2, attached ? "attached" : "detached");
 299out:
 300        return ret;
 301}
 302
 303static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info,
 304                bool attached)
 305{
 306        int ret = 0;
 307        int type;
 308        int adc, adc1k, adclow;
 309
 310        if (attached) {
 311                adc = info->status[0] & STATUS1_ADC_MASK;
 312                adclow = info->status[0] & STATUS1_ADCLOW_MASK;
 313                adclow >>= STATUS1_ADCLOW_SHIFT;
 314                adc1k = info->status[0] & STATUS1_ADC1K_MASK;
 315                adc1k >>= STATUS1_ADC1K_SHIFT;
 316
 317                /**
 318                 * [0x1][ADCLow][ADC1K]
 319                 * [0x1    0       0  ] : USB_OTG
 320                 * [0x1    1       0  ] : Audio Video Cable with load
 321                 * [0x1    1       1  ] : MHL
 322                 */
 323                type = ((0x1 << 8) | (adclow << 1) | adc1k);
 324
 325                /* Store previous ADC value to handle accessory
 326                   when accessory will be detached */
 327                info->prev_adc = adc;
 328                info->prev_adc_gnd = type;
 329        } else
 330                type = info->prev_adc_gnd;
 331
 332        switch (type) {
 333        case MAX77693_MUIC_GND_USB_OTG:
 334                /* USB_OTG */
 335                ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached);
 336                if (ret < 0)
 337                        goto out;
 338                extcon_set_cable_state(info->edev, "USB-Host", attached);
 339                break;
 340        case MAX77693_MUIC_GND_AV_CABLE_LOAD:
 341                /* Audio Video Cable with load */
 342                ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
 343                if (ret < 0)
 344                        goto out;
 345                extcon_set_cable_state(info->edev,
 346                                "Audio-video-load", attached);
 347                break;
 348        case MAX77693_MUIC_GND_MHL_CABLE:
 349                /* MHL */
 350                extcon_set_cable_state(info->edev, "MHL", attached);
 351                break;
 352        default:
 353                dev_err(info->dev, "failed to detect %s accessory\n",
 354                        attached ? "attached" : "detached");
 355                dev_err(info->dev, "- adc:0x%x, adclow:0x%x, adc1k:0x%x\n",
 356                        adc, adclow, adc1k);
 357                ret = -EINVAL;
 358                break;
 359        }
 360
 361out:
 362        return ret;
 363}
 364
 365static int max77693_muic_adc_handler(struct max77693_muic_info *info,
 366                int curr_adc, bool attached)
 367{
 368        int ret = 0;
 369        int adc;
 370
 371        if (attached) {
 372                /* Store ADC value to handle accessory
 373                   when accessory will be detached */
 374                info->prev_adc = curr_adc;
 375                adc = curr_adc;
 376        } else
 377                adc = info->prev_adc;
 378
 379        dev_info(info->dev,
 380                "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
 381                attached ? "attached" : "detached", curr_adc, info->prev_adc);
 382
 383        switch (adc) {
 384        case MAX77693_MUIC_ADC_GROUND:
 385                /* USB_OTG/MHL/Audio */
 386                max77693_muic_adc_ground_handler(info, attached);
 387                break;
 388        case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF:
 389        case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON:
 390                /* USB */
 391                ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached);
 392                if (ret < 0)
 393                        goto out;
 394                extcon_set_cable_state(info->edev, "USB", attached);
 395                break;
 396        case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF:
 397        case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON:
 398                /* JIG */
 399                ret = max77693_muic_set_path(info, CONTROL1_SW_UART, attached);
 400                if (ret < 0)
 401                        goto out;
 402                extcon_set_cable_state(info->edev, "JIG", attached);
 403                break;
 404        case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE:
 405                /* Audio Video cable with no-load */
 406                ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
 407                if (ret < 0)
 408                        goto out;
 409                extcon_set_cable_state(info->edev,
 410                                "Audio-video-noload", attached);
 411                break;
 412        case MAX77693_MUIC_ADC_SEND_END_BUTTON:
 413        case MAX77693_MUIC_ADC_REMOTE_S1_BUTTON:
 414        case MAX77693_MUIC_ADC_REMOTE_S2_BUTTON:
 415        case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON:
 416        case MAX77693_MUIC_ADC_REMOTE_S4_BUTTON:
 417        case MAX77693_MUIC_ADC_REMOTE_S5_BUTTON:
 418        case MAX77693_MUIC_ADC_REMOTE_S6_BUTTON:
 419        case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON:
 420        case MAX77693_MUIC_ADC_REMOTE_S8_BUTTON:
 421        case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON:
 422        case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON:
 423        case MAX77693_MUIC_ADC_REMOTE_S11_BUTTON:
 424        case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON:
 425        case MAX77693_MUIC_ADC_RESERVED_ACC_1:
 426        case MAX77693_MUIC_ADC_RESERVED_ACC_2:
 427        case MAX77693_MUIC_ADC_RESERVED_ACC_3:
 428        case MAX77693_MUIC_ADC_RESERVED_ACC_4:
 429        case MAX77693_MUIC_ADC_RESERVED_ACC_5:
 430        case MAX77693_MUIC_ADC_CEA936_AUDIO:
 431        case MAX77693_MUIC_ADC_PHONE_POWERED_DEV:
 432        case MAX77693_MUIC_ADC_TTY_CONVERTER:
 433        case MAX77693_MUIC_ADC_UART_CABLE:
 434        case MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG:
 435        case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD:
 436        case MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG:
 437                /* This accessory isn't used in general case if it is specially
 438                   needed to detect additional accessory, should implement
 439                   proper operation when this accessory is attached/detached. */
 440                dev_info(info->dev,
 441                        "accessory is %s but it isn't used (adc:0x%x)\n",
 442                        attached ? "attached" : "detached", adc);
 443                goto out;
 444        default:
 445                dev_err(info->dev,
 446                        "failed to detect %s accessory (adc:0x%x)\n",
 447                        attached ? "attached" : "detached", adc);
 448                ret = -EINVAL;
 449                goto out;
 450        }
 451
 452out:
 453        return ret;
 454}
 455
 456static int max77693_muic_chg_handler(struct max77693_muic_info *info,
 457                int curr_chg_type, bool attached)
 458{
 459        int ret = 0;
 460        int chg_type;
 461
 462        if (attached) {
 463                /* Store previous charger type to control
 464                   when charger accessory will be detached */
 465                info->prev_chg_type = curr_chg_type;
 466                chg_type = curr_chg_type;
 467        } else
 468                chg_type = info->prev_chg_type;
 469
 470        dev_info(info->dev,
 471                "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
 472                        attached ? "attached" : "detached",
 473                        curr_chg_type, info->prev_chg_type);
 474
 475        switch (chg_type) {
 476        case MAX77693_CHARGER_TYPE_USB:
 477                ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached);
 478                if (ret < 0)
 479                        goto out;
 480                extcon_set_cable_state(info->edev, "USB", attached);
 481                break;
 482        case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT:
 483                extcon_set_cable_state(info->edev,
 484                                "Charge-downstream", attached);
 485                break;
 486        case MAX77693_CHARGER_TYPE_DEDICATED_CHG:
 487                extcon_set_cable_state(info->edev, "TA", attached);
 488                break;
 489        case MAX77693_CHARGER_TYPE_APPLE_500MA:
 490                extcon_set_cable_state(info->edev, "Slow-charger", attached);
 491                break;
 492        case MAX77693_CHARGER_TYPE_APPLE_1A_2A:
 493                extcon_set_cable_state(info->edev, "Fast-charger", attached);
 494                break;
 495        case MAX77693_CHARGER_TYPE_DEAD_BATTERY:
 496                break;
 497        default:
 498                dev_err(info->dev,
 499                        "failed to detect %s accessory (chg_type:0x%x)\n",
 500                        attached ? "attached" : "detached", chg_type);
 501                ret = -EINVAL;
 502                goto out;
 503        }
 504
 505out:
 506        return ret;
 507}
 508
 509static void max77693_muic_irq_work(struct work_struct *work)
 510{
 511        struct max77693_muic_info *info = container_of(work,
 512                        struct max77693_muic_info, irq_work);
 513        int curr_adc, curr_chg_type;
 514        int irq_type = -1;
 515        int i, ret = 0;
 516        bool attached = true;
 517
 518        if (!info->edev)
 519                return;
 520
 521        mutex_lock(&info->mutex);
 522
 523        for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++)
 524                if (info->irq == muic_irqs[i].virq)
 525                        irq_type = muic_irqs[i].irq;
 526
 527        ret = max77693_bulk_read(info->max77693->regmap_muic,
 528                        MAX77693_MUIC_REG_STATUS1, 2, info->status);
 529        if (ret) {
 530                dev_err(info->dev, "failed to read MUIC register\n");
 531                mutex_unlock(&info->mutex);
 532                return;
 533        }
 534
 535        switch (irq_type) {
 536        case MAX77693_MUIC_IRQ_INT1_ADC:
 537        case MAX77693_MUIC_IRQ_INT1_ADC_LOW:
 538        case MAX77693_MUIC_IRQ_INT1_ADC_ERR:
 539        case MAX77693_MUIC_IRQ_INT1_ADC1K:
 540                /* Handle all of accessory except for
 541                   type of charger accessory */
 542                curr_adc = info->status[0] & STATUS1_ADC_MASK;
 543                curr_adc >>= STATUS1_ADC_SHIFT;
 544
 545                /* Check accessory state which is either detached or attached */
 546                if (curr_adc == MAX77693_MUIC_ADC_OPEN)
 547                        attached = false;
 548
 549                ret = max77693_muic_adc_handler(info, curr_adc, attached);
 550                break;
 551        case MAX77693_MUIC_IRQ_INT2_CHGTYP:
 552        case MAX77693_MUIC_IRQ_INT2_CHGDETREUN:
 553        case MAX77693_MUIC_IRQ_INT2_DCDTMR:
 554        case MAX77693_MUIC_IRQ_INT2_DXOVP:
 555        case MAX77693_MUIC_IRQ_INT2_VBVOLT:
 556        case MAX77693_MUIC_IRQ_INT2_VIDRM:
 557                /* Handle charger accessory */
 558                curr_chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
 559                curr_chg_type >>= STATUS2_CHGTYP_SHIFT;
 560
 561                /* Check charger accessory state which
 562                   is either detached or attached */
 563                if (curr_chg_type == MAX77693_CHARGER_TYPE_NONE)
 564                        attached = false;
 565
 566                ret = max77693_muic_chg_handler(info, curr_chg_type, attached);
 567                break;
 568        case MAX77693_MUIC_IRQ_INT3_EOC:
 569        case MAX77693_MUIC_IRQ_INT3_CGMBC:
 570        case MAX77693_MUIC_IRQ_INT3_OVP:
 571        case MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR:
 572        case MAX77693_MUIC_IRQ_INT3_CHG_ENABLED:
 573        case MAX77693_MUIC_IRQ_INT3_BAT_DET:
 574                break;
 575        default:
 576                dev_err(info->dev, "muic interrupt: irq %d occurred\n",
 577                                irq_type);
 578                break;
 579        }
 580
 581        if (ret < 0)
 582                dev_err(info->dev, "failed to handle MUIC interrupt\n");
 583
 584        mutex_unlock(&info->mutex);
 585
 586        return;
 587}
 588
 589static irqreturn_t max77693_muic_irq_handler(int irq, void *data)
 590{
 591        struct max77693_muic_info *info = data;
 592
 593        info->irq = irq;
 594        schedule_work(&info->irq_work);
 595
 596        return IRQ_HANDLED;
 597}
 598
 599static struct regmap_config max77693_muic_regmap_config = {
 600        .reg_bits = 8,
 601        .val_bits = 8,
 602};
 603
 604static int max77693_muic_detect_accessory(struct max77693_muic_info *info)
 605{
 606        int ret = 0;
 607        int adc, chg_type;
 608
 609        mutex_lock(&info->mutex);
 610
 611        /* Read STATUSx register to detect accessory */
 612        ret = max77693_bulk_read(info->max77693->regmap_muic,
 613                        MAX77693_MUIC_REG_STATUS1, 2, info->status);
 614        if (ret) {
 615                dev_err(info->dev, "failed to read MUIC register\n");
 616                mutex_unlock(&info->mutex);
 617                return -EINVAL;
 618        }
 619
 620        adc = info->status[0] & STATUS1_ADC_MASK;
 621        adc >>= STATUS1_ADC_SHIFT;
 622
 623        if (adc != MAX77693_MUIC_ADC_OPEN) {
 624                dev_info(info->dev,
 625                        "external connector is attached (adc:0x%02x)\n", adc);
 626
 627                ret = max77693_muic_adc_handler(info, adc, true);
 628                if (ret < 0)
 629                        dev_err(info->dev, "failed to detect accessory\n");
 630                goto out;
 631        }
 632
 633        chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
 634        chg_type >>= STATUS2_CHGTYP_SHIFT;
 635
 636        if (chg_type != MAX77693_CHARGER_TYPE_NONE) {
 637                dev_info(info->dev,
 638                        "external connector is attached (chg_type:0x%x)\n",
 639                        chg_type);
 640
 641                max77693_muic_chg_handler(info, chg_type, true);
 642                if (ret < 0)
 643                        dev_err(info->dev, "failed to detect charger accessory\n");
 644        }
 645
 646out:
 647        mutex_unlock(&info->mutex);
 648        return ret;
 649}
 650
 651static int __devinit max77693_muic_probe(struct platform_device *pdev)
 652{
 653        struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
 654        struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);
 655        struct max77693_muic_platform_data *muic_pdata = pdata->muic_data;
 656        struct max77693_muic_info *info;
 657        int ret, i;
 658        u8 id;
 659
 660        info = kzalloc(sizeof(struct max77693_muic_info), GFP_KERNEL);
 661        if (!info) {
 662                dev_err(&pdev->dev, "failed to allocate memory\n");
 663                ret = -ENOMEM;
 664                goto err_kfree;
 665        }
 666        info->dev = &pdev->dev;
 667        info->max77693 = max77693;
 668        if (info->max77693->regmap_muic)
 669                dev_dbg(&pdev->dev, "allocate register map\n");
 670        else {
 671                info->max77693->regmap_muic = devm_regmap_init_i2c(
 672                                                info->max77693->muic,
 673                                                &max77693_muic_regmap_config);
 674                if (IS_ERR(info->max77693->regmap_muic)) {
 675                        ret = PTR_ERR(info->max77693->regmap_muic);
 676                        dev_err(max77693->dev,
 677                                "failed to allocate register map: %d\n", ret);
 678                        goto err_regmap;
 679                }
 680        }
 681        platform_set_drvdata(pdev, info);
 682        mutex_init(&info->mutex);
 683
 684        INIT_WORK(&info->irq_work, max77693_muic_irq_work);
 685
 686        /* Support irq domain for MAX77693 MUIC device */
 687        for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
 688                struct max77693_muic_irq *muic_irq = &muic_irqs[i];
 689                int virq = 0;
 690
 691                virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq);
 692                if (!virq)
 693                        goto err_irq;
 694                muic_irq->virq = virq;
 695
 696                ret = request_threaded_irq(virq, NULL,
 697                                max77693_muic_irq_handler,
 698                                IRQF_ONESHOT, muic_irq->name, info);
 699                if (ret) {
 700                        dev_err(&pdev->dev,
 701                                "failed: irq request (IRQ: %d,"
 702                                " error :%d)\n",
 703                                muic_irq->irq, ret);
 704
 705                        for (i = i - 1; i >= 0; i--)
 706                                free_irq(muic_irq->virq, info);
 707                        goto err_irq;
 708                }
 709        }
 710
 711        /* Initialize extcon device */
 712        info->edev = kzalloc(sizeof(struct extcon_dev), GFP_KERNEL);
 713        if (!info->edev) {
 714                dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
 715                ret = -ENOMEM;
 716                goto err_irq;
 717        }
 718        info->edev->name = DEV_NAME;
 719        info->edev->supported_cable = max77693_extcon_cable;
 720        ret = extcon_dev_register(info->edev, NULL);
 721        if (ret) {
 722                dev_err(&pdev->dev, "failed to register extcon device\n");
 723                goto err_extcon;
 724        }
 725
 726        /* Initialize MUIC register by using platform data */
 727        for (i = 0 ; i < muic_pdata->num_init_data ; i++) {
 728                enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR;
 729
 730                max77693_write_reg(info->max77693->regmap_muic,
 731                                muic_pdata->init_data[i].addr,
 732                                muic_pdata->init_data[i].data);
 733
 734                switch (muic_pdata->init_data[i].addr) {
 735                case MAX77693_MUIC_REG_INTMASK1:
 736                        irq_src = MUIC_INT1;
 737                        break;
 738                case MAX77693_MUIC_REG_INTMASK2:
 739                        irq_src = MUIC_INT2;
 740                        break;
 741                case MAX77693_MUIC_REG_INTMASK3:
 742                        irq_src = MUIC_INT3;
 743                        break;
 744                }
 745
 746                if (irq_src < MAX77693_IRQ_GROUP_NR)
 747                        info->max77693->irq_masks_cur[irq_src]
 748                                = muic_pdata->init_data[i].data;
 749        }
 750
 751        /* Check revision number of MUIC device*/
 752        ret = max77693_read_reg(info->max77693->regmap_muic,
 753                        MAX77693_MUIC_REG_ID, &id);
 754        if (ret < 0) {
 755                dev_err(&pdev->dev, "failed to read revision number\n");
 756                goto err_extcon;
 757        }
 758        dev_info(info->dev, "device ID : 0x%x\n", id);
 759
 760        /* Set ADC debounce time */
 761        max77693_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);
 762
 763        /* Detect accessory on boot */
 764        max77693_muic_detect_accessory(info);
 765
 766        return ret;
 767
 768err_extcon:
 769        kfree(info->edev);
 770err_irq:
 771err_regmap:
 772        kfree(info);
 773err_kfree:
 774        return ret;
 775}
 776
 777static int __devexit max77693_muic_remove(struct platform_device *pdev)
 778{
 779        struct max77693_muic_info *info = platform_get_drvdata(pdev);
 780        int i;
 781
 782        for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
 783                free_irq(muic_irqs[i].virq, info);
 784        cancel_work_sync(&info->irq_work);
 785        extcon_dev_unregister(info->edev);
 786        kfree(info->edev);
 787        kfree(info);
 788
 789        return 0;
 790}
 791
 792static struct platform_driver max77693_muic_driver = {
 793        .driver         = {
 794                .name   = DEV_NAME,
 795                .owner  = THIS_MODULE,
 796        },
 797        .probe          = max77693_muic_probe,
 798        .remove         = __devexit_p(max77693_muic_remove),
 799};
 800
 801module_platform_driver(max77693_muic_driver);
 802
 803MODULE_DESCRIPTION("Maxim MAX77693 Extcon driver");
 804MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
 805MODULE_LICENSE("GPL");
 806MODULE_ALIAS("platform:extcon-max77693");
 807
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.