Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * extcon-rt8973a.c - Richtek RT8973A extcon driver to support USB switches
0004  *
0005  * Copyright (c) 2014 Samsung Electronics Co., Ltd
0006  * Author: Chanwoo Choi <cw00.choi@samsung.com>
0007  */
0008 
0009 #include <linux/err.h>
0010 #include <linux/i2c.h>
0011 #include <linux/input.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/irqdomain.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/regmap.h>
0018 #include <linux/slab.h>
0019 #include <linux/extcon-provider.h>
0020 
0021 #include "extcon-rt8973a.h"
0022 
0023 #define DELAY_MS_DEFAULT        20000   /* unit: millisecond */
0024 
0025 struct muic_irq {
0026     unsigned int irq;
0027     const char *name;
0028     unsigned int virq;
0029 };
0030 
0031 struct reg_data {
0032     u8 reg;
0033     u8 mask;
0034     u8 val;
0035     bool invert;
0036 };
0037 
0038 struct rt8973a_muic_info {
0039     struct device *dev;
0040     struct extcon_dev *edev;
0041 
0042     struct i2c_client *i2c;
0043     struct regmap *regmap;
0044 
0045     struct regmap_irq_chip_data *irq_data;
0046     struct muic_irq *muic_irqs;
0047     unsigned int num_muic_irqs;
0048     int irq;
0049     bool irq_attach;
0050     bool irq_detach;
0051     bool irq_ovp;
0052     bool irq_otp;
0053     struct work_struct irq_work;
0054 
0055     struct reg_data *reg_data;
0056     unsigned int num_reg_data;
0057     bool auto_config;
0058 
0059     struct mutex mutex;
0060 
0061     /*
0062      * Use delayed workqueue to detect cable state and then
0063      * notify cable state to notifiee/platform through uevent.
0064      * After completing the booting of platform, the extcon provider
0065      * driver should notify cable state to upper layer.
0066      */
0067     struct delayed_work wq_detcable;
0068 };
0069 
0070 /* Default value of RT8973A register to bring up MUIC device. */
0071 static struct reg_data rt8973a_reg_data[] = {
0072     {
0073         .reg = RT8973A_REG_CONTROL1,
0074         .mask = RT8973A_REG_CONTROL1_ADC_EN_MASK
0075             | RT8973A_REG_CONTROL1_USB_CHD_EN_MASK
0076             | RT8973A_REG_CONTROL1_CHGTYP_MASK
0077             | RT8973A_REG_CONTROL1_SWITCH_OPEN_MASK
0078             | RT8973A_REG_CONTROL1_AUTO_CONFIG_MASK
0079             | RT8973A_REG_CONTROL1_INTM_MASK,
0080         .val = RT8973A_REG_CONTROL1_ADC_EN_MASK
0081             | RT8973A_REG_CONTROL1_USB_CHD_EN_MASK
0082             | RT8973A_REG_CONTROL1_CHGTYP_MASK,
0083         .invert = false,
0084     },
0085     { /* sentinel */ }
0086 };
0087 
0088 /* List of detectable cables */
0089 static const unsigned int rt8973a_extcon_cable[] = {
0090     EXTCON_USB,
0091     EXTCON_USB_HOST,
0092     EXTCON_CHG_USB_SDP,
0093     EXTCON_CHG_USB_DCP,
0094     EXTCON_JIG,
0095     EXTCON_NONE,
0096 };
0097 
0098 /* Define OVP (Over Voltage Protection), OTP (Over Temperature Protection) */
0099 enum rt8973a_event_type {
0100     RT8973A_EVENT_ATTACH = 1,
0101     RT8973A_EVENT_DETACH,
0102     RT8973A_EVENT_OVP,
0103     RT8973A_EVENT_OTP,
0104 };
0105 
0106 /* Define supported accessory type */
0107 enum rt8973a_muic_acc_type {
0108     RT8973A_MUIC_ADC_OTG = 0x0,
0109     RT8973A_MUIC_ADC_AUDIO_SEND_END_BUTTON,
0110     RT8973A_MUIC_ADC_AUDIO_REMOTE_S1_BUTTON,
0111     RT8973A_MUIC_ADC_AUDIO_REMOTE_S2_BUTTON,
0112     RT8973A_MUIC_ADC_AUDIO_REMOTE_S3_BUTTON,
0113     RT8973A_MUIC_ADC_AUDIO_REMOTE_S4_BUTTON,
0114     RT8973A_MUIC_ADC_AUDIO_REMOTE_S5_BUTTON,
0115     RT8973A_MUIC_ADC_AUDIO_REMOTE_S6_BUTTON,
0116     RT8973A_MUIC_ADC_AUDIO_REMOTE_S7_BUTTON,
0117     RT8973A_MUIC_ADC_AUDIO_REMOTE_S8_BUTTON,
0118     RT8973A_MUIC_ADC_AUDIO_REMOTE_S9_BUTTON,
0119     RT8973A_MUIC_ADC_AUDIO_REMOTE_S10_BUTTON,
0120     RT8973A_MUIC_ADC_AUDIO_REMOTE_S11_BUTTON,
0121     RT8973A_MUIC_ADC_AUDIO_REMOTE_S12_BUTTON,
0122     RT8973A_MUIC_ADC_RESERVED_ACC_1,
0123     RT8973A_MUIC_ADC_RESERVED_ACC_2,
0124     RT8973A_MUIC_ADC_RESERVED_ACC_3,
0125     RT8973A_MUIC_ADC_RESERVED_ACC_4,
0126     RT8973A_MUIC_ADC_RESERVED_ACC_5,
0127     RT8973A_MUIC_ADC_AUDIO_TYPE2,
0128     RT8973A_MUIC_ADC_PHONE_POWERED_DEV,
0129     RT8973A_MUIC_ADC_UNKNOWN_ACC_1,
0130     RT8973A_MUIC_ADC_UNKNOWN_ACC_2,
0131     RT8973A_MUIC_ADC_TA,
0132     RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB,
0133     RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB,
0134     RT8973A_MUIC_ADC_UNKNOWN_ACC_3,
0135     RT8973A_MUIC_ADC_UNKNOWN_ACC_4,
0136     RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART,
0137     RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART,
0138     RT8973A_MUIC_ADC_UNKNOWN_ACC_5,
0139     RT8973A_MUIC_ADC_OPEN = 0x1f,
0140 
0141     /*
0142      * The below accessories has same ADC value (0x1f).
0143      * So, Device type1 is used to separate specific accessory.
0144      */
0145                     /* |---------|--ADC| */
0146                     /* |    [7:5]|[4:0]| */
0147     RT8973A_MUIC_ADC_USB = 0x3f,    /* |      001|11111| */
0148 };
0149 
0150 /* List of supported interrupt for RT8973A */
0151 static struct muic_irq rt8973a_muic_irqs[] = {
0152     { RT8973A_INT1_ATTACH,      "muic-attach" },
0153     { RT8973A_INT1_DETACH,      "muic-detach" },
0154     { RT8973A_INT1_CHGDET,      "muic-chgdet" },
0155     { RT8973A_INT1_DCD_T,       "muic-dcd-t" },
0156     { RT8973A_INT1_OVP,     "muic-ovp" },
0157     { RT8973A_INT1_CONNECT,     "muic-connect" },
0158     { RT8973A_INT1_ADC_CHG,     "muic-adc-chg" },
0159     { RT8973A_INT1_OTP,     "muic-otp" },
0160     { RT8973A_INT2_UVLO,        "muic-uvlo" },
0161     { RT8973A_INT2_POR,     "muic-por" },
0162     { RT8973A_INT2_OTP_FET,     "muic-otp-fet" },
0163     { RT8973A_INT2_OVP_FET,     "muic-ovp-fet" },
0164     { RT8973A_INT2_OCP_LATCH,   "muic-ocp-latch" },
0165     { RT8973A_INT2_OCP,     "muic-ocp" },
0166     { RT8973A_INT2_OVP_OCP,     "muic-ovp-ocp" },
0167 };
0168 
0169 /* Define interrupt list of RT8973A to register regmap_irq */
0170 static const struct regmap_irq rt8973a_irqs[] = {
0171     /* INT1 interrupts */
0172     { .reg_offset = 0, .mask = RT8973A_INT1_ATTACH_MASK, },
0173     { .reg_offset = 0, .mask = RT8973A_INT1_DETACH_MASK, },
0174     { .reg_offset = 0, .mask = RT8973A_INT1_CHGDET_MASK, },
0175     { .reg_offset = 0, .mask = RT8973A_INT1_DCD_T_MASK, },
0176     { .reg_offset = 0, .mask = RT8973A_INT1_OVP_MASK, },
0177     { .reg_offset = 0, .mask = RT8973A_INT1_CONNECT_MASK, },
0178     { .reg_offset = 0, .mask = RT8973A_INT1_ADC_CHG_MASK, },
0179     { .reg_offset = 0, .mask = RT8973A_INT1_OTP_MASK, },
0180 
0181     /* INT2 interrupts */
0182     { .reg_offset = 1, .mask = RT8973A_INT2_UVLOT_MASK,},
0183     { .reg_offset = 1, .mask = RT8973A_INT2_POR_MASK, },
0184     { .reg_offset = 1, .mask = RT8973A_INT2_OTP_FET_MASK, },
0185     { .reg_offset = 1, .mask = RT8973A_INT2_OVP_FET_MASK, },
0186     { .reg_offset = 1, .mask = RT8973A_INT2_OCP_LATCH_MASK, },
0187     { .reg_offset = 1, .mask = RT8973A_INT2_OCP_MASK, },
0188     { .reg_offset = 1, .mask = RT8973A_INT2_OVP_OCP_MASK, },
0189 };
0190 
0191 static const struct regmap_irq_chip rt8973a_muic_irq_chip = {
0192     .name           = "rt8973a",
0193     .status_base        = RT8973A_REG_INT1,
0194     .mask_base      = RT8973A_REG_INTM1,
0195     .num_regs       = 2,
0196     .irqs           = rt8973a_irqs,
0197     .num_irqs       = ARRAY_SIZE(rt8973a_irqs),
0198 };
0199 
0200 /* Define regmap configuration of RT8973A for I2C communication  */
0201 static bool rt8973a_muic_volatile_reg(struct device *dev, unsigned int reg)
0202 {
0203     switch (reg) {
0204     case RT8973A_REG_INTM1:
0205     case RT8973A_REG_INTM2:
0206         return true;
0207     default:
0208         break;
0209     }
0210     return false;
0211 }
0212 
0213 static const struct regmap_config rt8973a_muic_regmap_config = {
0214     .reg_bits   = 8,
0215     .val_bits   = 8,
0216     .volatile_reg   = rt8973a_muic_volatile_reg,
0217     .max_register   = RT8973A_REG_END,
0218 };
0219 
0220 /* Change DM_CON/DP_CON/VBUSIN switch according to cable type */
0221 static int rt8973a_muic_set_path(struct rt8973a_muic_info *info,
0222                 unsigned int con_sw, bool attached)
0223 {
0224     int ret;
0225 
0226     /*
0227      * Don't need to set h/w path according to cable type
0228      * if Auto-configuration mode of CONTROL1 register is true.
0229      */
0230     if (info->auto_config)
0231         return 0;
0232 
0233     if (!attached)
0234         con_sw  = DM_DP_SWITCH_UART;
0235 
0236     switch (con_sw) {
0237     case DM_DP_SWITCH_OPEN:
0238     case DM_DP_SWITCH_USB:
0239     case DM_DP_SWITCH_UART:
0240         ret = regmap_update_bits(info->regmap, RT8973A_REG_MANUAL_SW1,
0241                     RT8973A_REG_MANUAL_SW1_DP_MASK |
0242                     RT8973A_REG_MANUAL_SW1_DM_MASK,
0243                     con_sw);
0244         if (ret < 0) {
0245             dev_err(info->dev,
0246                 "cannot update DM_CON/DP_CON switch\n");
0247             return ret;
0248         }
0249         break;
0250     default:
0251         dev_err(info->dev, "Unknown DM_CON/DP_CON switch type (%d)\n",
0252                 con_sw);
0253         return -EINVAL;
0254     }
0255 
0256     return 0;
0257 }
0258 
0259 static int rt8973a_muic_get_cable_type(struct rt8973a_muic_info *info)
0260 {
0261     unsigned int adc, dev1;
0262     int ret, cable_type;
0263 
0264     /* Read ADC value according to external cable or button */
0265     ret = regmap_read(info->regmap, RT8973A_REG_ADC, &adc);
0266     if (ret) {
0267         dev_err(info->dev, "failed to read ADC register\n");
0268         return ret;
0269     }
0270     cable_type = adc & RT8973A_REG_ADC_MASK;
0271 
0272     /* Read Device 1 reigster to identify correct cable type */
0273     ret = regmap_read(info->regmap, RT8973A_REG_DEV1, &dev1);
0274     if (ret) {
0275         dev_err(info->dev, "failed to read DEV1 register\n");
0276         return ret;
0277     }
0278 
0279     switch (adc) {
0280     case RT8973A_MUIC_ADC_OPEN:
0281         if (dev1 & RT8973A_REG_DEV1_USB_MASK)
0282             cable_type = RT8973A_MUIC_ADC_USB;
0283         else if (dev1 & RT8973A_REG_DEV1_DCPORT_MASK)
0284             cable_type = RT8973A_MUIC_ADC_TA;
0285         else
0286             cable_type = RT8973A_MUIC_ADC_OPEN;
0287         break;
0288     default:
0289         break;
0290     }
0291 
0292     return cable_type;
0293 }
0294 
0295 static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info,
0296                     enum rt8973a_event_type event)
0297 {
0298     static unsigned int prev_cable_type;
0299     unsigned int con_sw = DM_DP_SWITCH_UART;
0300     int ret, cable_type;
0301     unsigned int id;
0302     bool attached = false;
0303 
0304     switch (event) {
0305     case RT8973A_EVENT_ATTACH:
0306         cable_type = rt8973a_muic_get_cable_type(info);
0307         attached = true;
0308         break;
0309     case RT8973A_EVENT_DETACH:
0310         cable_type = prev_cable_type;
0311         attached = false;
0312         break;
0313     case RT8973A_EVENT_OVP:
0314     case RT8973A_EVENT_OTP:
0315         dev_warn(info->dev,
0316             "happen Over %s issue. Need to disconnect all cables\n",
0317             event == RT8973A_EVENT_OVP ? "Voltage" : "Temperature");
0318         cable_type = prev_cable_type;
0319         attached = false;
0320         break;
0321     default:
0322         dev_err(info->dev,
0323             "Cannot handle this event (event:%d)\n", event);
0324         return -EINVAL;
0325     }
0326     prev_cable_type = cable_type;
0327 
0328     switch (cable_type) {
0329     case RT8973A_MUIC_ADC_OTG:
0330         id = EXTCON_USB_HOST;
0331         con_sw = DM_DP_SWITCH_USB;
0332         break;
0333     case RT8973A_MUIC_ADC_TA:
0334         id = EXTCON_CHG_USB_DCP;
0335         con_sw = DM_DP_SWITCH_OPEN;
0336         break;
0337     case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB:
0338     case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB:
0339         id = EXTCON_JIG;
0340         con_sw = DM_DP_SWITCH_USB;
0341         break;
0342     case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART:
0343     case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART:
0344         id = EXTCON_JIG;
0345         con_sw = DM_DP_SWITCH_UART;
0346         break;
0347     case RT8973A_MUIC_ADC_USB:
0348         id = EXTCON_USB;
0349         con_sw = DM_DP_SWITCH_USB;
0350         break;
0351     case RT8973A_MUIC_ADC_OPEN:
0352         return 0;
0353     case RT8973A_MUIC_ADC_UNKNOWN_ACC_1:
0354     case RT8973A_MUIC_ADC_UNKNOWN_ACC_2:
0355     case RT8973A_MUIC_ADC_UNKNOWN_ACC_3:
0356     case RT8973A_MUIC_ADC_UNKNOWN_ACC_4:
0357     case RT8973A_MUIC_ADC_UNKNOWN_ACC_5:
0358         dev_warn(info->dev,
0359             "Unknown accessory type (adc:0x%x)\n", cable_type);
0360         return 0;
0361     case RT8973A_MUIC_ADC_AUDIO_SEND_END_BUTTON:
0362     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S1_BUTTON:
0363     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S2_BUTTON:
0364     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S3_BUTTON:
0365     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S4_BUTTON:
0366     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S5_BUTTON:
0367     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S6_BUTTON:
0368     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S7_BUTTON:
0369     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S8_BUTTON:
0370     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S9_BUTTON:
0371     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S10_BUTTON:
0372     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S11_BUTTON:
0373     case RT8973A_MUIC_ADC_AUDIO_REMOTE_S12_BUTTON:
0374     case RT8973A_MUIC_ADC_AUDIO_TYPE2:
0375         dev_warn(info->dev,
0376             "Audio device/button type (adc:0x%x)\n", cable_type);
0377         return 0;
0378     case RT8973A_MUIC_ADC_RESERVED_ACC_1:
0379     case RT8973A_MUIC_ADC_RESERVED_ACC_2:
0380     case RT8973A_MUIC_ADC_RESERVED_ACC_3:
0381     case RT8973A_MUIC_ADC_RESERVED_ACC_4:
0382     case RT8973A_MUIC_ADC_RESERVED_ACC_5:
0383     case RT8973A_MUIC_ADC_PHONE_POWERED_DEV:
0384         return 0;
0385     default:
0386         dev_err(info->dev,
0387             "Cannot handle this cable_type (adc:0x%x)\n",
0388             cable_type);
0389         return -EINVAL;
0390     }
0391 
0392     /* Change internal hardware path(DM_CON/DP_CON) */
0393     ret = rt8973a_muic_set_path(info, con_sw, attached);
0394     if (ret < 0)
0395         return ret;
0396 
0397     /* Change the state of external accessory */
0398     extcon_set_state_sync(info->edev, id, attached);
0399     if (id == EXTCON_USB)
0400         extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
0401                     attached);
0402 
0403     return 0;
0404 }
0405 
0406 static void rt8973a_muic_irq_work(struct work_struct *work)
0407 {
0408     struct rt8973a_muic_info *info = container_of(work,
0409             struct rt8973a_muic_info, irq_work);
0410     int ret = 0;
0411 
0412     if (!info->edev)
0413         return;
0414 
0415     mutex_lock(&info->mutex);
0416 
0417     /* Detect attached or detached cables */
0418     if (info->irq_attach) {
0419         ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_ATTACH);
0420         info->irq_attach = false;
0421     }
0422 
0423     if (info->irq_detach) {
0424         ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_DETACH);
0425         info->irq_detach = false;
0426     }
0427 
0428     if (info->irq_ovp) {
0429         ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_OVP);
0430         info->irq_ovp = false;
0431     }
0432 
0433     if (info->irq_otp) {
0434         ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_OTP);
0435         info->irq_otp = false;
0436     }
0437 
0438     if (ret < 0)
0439         dev_err(info->dev, "failed to handle MUIC interrupt\n");
0440 
0441     mutex_unlock(&info->mutex);
0442 }
0443 
0444 static irqreturn_t rt8973a_muic_irq_handler(int irq, void *data)
0445 {
0446     struct rt8973a_muic_info *info = data;
0447     int i, irq_type = -1;
0448 
0449     for (i = 0; i < info->num_muic_irqs; i++)
0450         if (irq == info->muic_irqs[i].virq)
0451             irq_type = info->muic_irqs[i].irq;
0452 
0453     switch (irq_type) {
0454     case RT8973A_INT1_ATTACH:
0455         info->irq_attach = true;
0456         break;
0457     case RT8973A_INT1_DETACH:
0458         info->irq_detach = true;
0459         break;
0460     case RT8973A_INT1_OVP:
0461         info->irq_ovp = true;
0462         break;
0463     case RT8973A_INT1_OTP:
0464         info->irq_otp = true;
0465         break;
0466     case RT8973A_INT1_CHGDET:
0467     case RT8973A_INT1_DCD_T:
0468     case RT8973A_INT1_CONNECT:
0469     case RT8973A_INT1_ADC_CHG:
0470     case RT8973A_INT2_UVLO:
0471     case RT8973A_INT2_POR:
0472     case RT8973A_INT2_OTP_FET:
0473     case RT8973A_INT2_OVP_FET:
0474     case RT8973A_INT2_OCP_LATCH:
0475     case RT8973A_INT2_OCP:
0476     case RT8973A_INT2_OVP_OCP:
0477     default:
0478         dev_dbg(info->dev,
0479             "Cannot handle this interrupt (%d)\n", irq_type);
0480         break;
0481     }
0482 
0483     schedule_work(&info->irq_work);
0484 
0485     return IRQ_HANDLED;
0486 }
0487 
0488 static void rt8973a_muic_detect_cable_wq(struct work_struct *work)
0489 {
0490     struct rt8973a_muic_info *info = container_of(to_delayed_work(work),
0491                 struct rt8973a_muic_info, wq_detcable);
0492     int ret;
0493 
0494     /* Notify the state of connector cable or not  */
0495     ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_ATTACH);
0496     if (ret < 0)
0497         dev_warn(info->dev, "failed to detect cable state\n");
0498 }
0499 
0500 static void rt8973a_init_dev_type(struct rt8973a_muic_info *info)
0501 {
0502     unsigned int data, vendor_id, version_id;
0503     int i, ret;
0504 
0505     /* To test I2C, Print version_id and vendor_id of RT8973A */
0506     ret = regmap_read(info->regmap, RT8973A_REG_DEVICE_ID, &data);
0507     if (ret) {
0508         dev_err(info->dev,
0509             "failed to read DEVICE_ID register: %d\n", ret);
0510         return;
0511     }
0512 
0513     vendor_id = ((data & RT8973A_REG_DEVICE_ID_VENDOR_MASK) >>
0514                 RT8973A_REG_DEVICE_ID_VENDOR_SHIFT);
0515     version_id = ((data & RT8973A_REG_DEVICE_ID_VERSION_MASK) >>
0516                 RT8973A_REG_DEVICE_ID_VERSION_SHIFT);
0517 
0518     dev_info(info->dev, "Device type: version: 0x%x, vendor: 0x%x\n",
0519                 version_id, vendor_id);
0520 
0521     /* Initiazle the register of RT8973A device to bring-up */
0522     for (i = 0; i < info->num_reg_data; i++) {
0523         u8 reg = info->reg_data[i].reg;
0524         u8 mask = info->reg_data[i].mask;
0525         u8 val = 0;
0526 
0527         if (info->reg_data[i].invert)
0528             val = ~info->reg_data[i].val;
0529         else
0530             val = info->reg_data[i].val;
0531 
0532         regmap_update_bits(info->regmap, reg, mask, val);
0533     }
0534 
0535     /* Check whether RT8973A is auto switching mode or not */
0536     ret = regmap_read(info->regmap, RT8973A_REG_CONTROL1, &data);
0537     if (ret) {
0538         dev_err(info->dev,
0539             "failed to read CONTROL1 register: %d\n", ret);
0540         return;
0541     }
0542 
0543     data &= RT8973A_REG_CONTROL1_AUTO_CONFIG_MASK;
0544     if (data) {
0545         info->auto_config = true;
0546         dev_info(info->dev,
0547             "Enable Auto-configuration for internal path\n");
0548     }
0549 }
0550 
0551 static int rt8973a_muic_i2c_probe(struct i2c_client *i2c,
0552                  const struct i2c_device_id *id)
0553 {
0554     struct device_node *np = i2c->dev.of_node;
0555     struct rt8973a_muic_info *info;
0556     int i, ret, irq_flags;
0557 
0558     if (!np)
0559         return -EINVAL;
0560 
0561     info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL);
0562     if (!info)
0563         return -ENOMEM;
0564     i2c_set_clientdata(i2c, info);
0565 
0566     info->dev = &i2c->dev;
0567     info->i2c = i2c;
0568     info->irq = i2c->irq;
0569     info->muic_irqs = rt8973a_muic_irqs;
0570     info->num_muic_irqs = ARRAY_SIZE(rt8973a_muic_irqs);
0571     info->reg_data = rt8973a_reg_data;
0572     info->num_reg_data = ARRAY_SIZE(rt8973a_reg_data);
0573 
0574     mutex_init(&info->mutex);
0575 
0576     INIT_WORK(&info->irq_work, rt8973a_muic_irq_work);
0577 
0578     info->regmap = devm_regmap_init_i2c(i2c, &rt8973a_muic_regmap_config);
0579     if (IS_ERR(info->regmap)) {
0580         ret = PTR_ERR(info->regmap);
0581         dev_err(info->dev, "failed to allocate register map: %d\n",
0582                    ret);
0583         return ret;
0584     }
0585 
0586     /* Support irq domain for RT8973A MUIC device */
0587     irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED;
0588     ret = regmap_add_irq_chip(info->regmap, info->irq, irq_flags, 0,
0589                   &rt8973a_muic_irq_chip, &info->irq_data);
0590     if (ret != 0) {
0591         dev_err(info->dev, "failed to add irq_chip (irq:%d, err:%d)\n",
0592                     info->irq, ret);
0593         return ret;
0594     }
0595 
0596     for (i = 0; i < info->num_muic_irqs; i++) {
0597         struct muic_irq *muic_irq = &info->muic_irqs[i];
0598         int virq = 0;
0599 
0600         virq = regmap_irq_get_virq(info->irq_data, muic_irq->irq);
0601         if (virq <= 0)
0602             return -EINVAL;
0603         muic_irq->virq = virq;
0604 
0605         ret = devm_request_threaded_irq(info->dev, virq, NULL,
0606                         rt8973a_muic_irq_handler,
0607                         IRQF_NO_SUSPEND | IRQF_ONESHOT,
0608                         muic_irq->name, info);
0609         if (ret) {
0610             dev_err(info->dev,
0611                 "failed: irq request (IRQ: %d, error :%d)\n",
0612                 muic_irq->irq, ret);
0613             return ret;
0614         }
0615     }
0616 
0617     /* Allocate extcon device */
0618     info->edev = devm_extcon_dev_allocate(info->dev, rt8973a_extcon_cable);
0619     if (IS_ERR(info->edev)) {
0620         dev_err(info->dev, "failed to allocate memory for extcon\n");
0621         return -ENOMEM;
0622     }
0623 
0624     /* Register extcon device */
0625     ret = devm_extcon_dev_register(info->dev, info->edev);
0626     if (ret) {
0627         dev_err(info->dev, "failed to register extcon device\n");
0628         return ret;
0629     }
0630 
0631     /*
0632      * Detect accessory after completing the initialization of platform
0633      *
0634      * - Use delayed workqueue to detect cable state and then
0635      * notify cable state to notifiee/platform through uevent.
0636      * After completing the booting of platform, the extcon provider
0637      * driver should notify cable state to upper layer.
0638      */
0639     INIT_DELAYED_WORK(&info->wq_detcable, rt8973a_muic_detect_cable_wq);
0640     queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
0641             msecs_to_jiffies(DELAY_MS_DEFAULT));
0642 
0643     /* Initialize RT8973A device and print vendor id and version id */
0644     rt8973a_init_dev_type(info);
0645 
0646     return 0;
0647 }
0648 
0649 static int rt8973a_muic_i2c_remove(struct i2c_client *i2c)
0650 {
0651     struct rt8973a_muic_info *info = i2c_get_clientdata(i2c);
0652 
0653     regmap_del_irq_chip(info->irq, info->irq_data);
0654 
0655     return 0;
0656 }
0657 
0658 static const struct of_device_id rt8973a_dt_match[] = {
0659     { .compatible = "richtek,rt8973a-muic" },
0660     { },
0661 };
0662 MODULE_DEVICE_TABLE(of, rt8973a_dt_match);
0663 
0664 #ifdef CONFIG_PM_SLEEP
0665 static int rt8973a_muic_suspend(struct device *dev)
0666 {
0667     struct i2c_client *i2c = to_i2c_client(dev);
0668     struct rt8973a_muic_info *info = i2c_get_clientdata(i2c);
0669 
0670     enable_irq_wake(info->irq);
0671 
0672     return 0;
0673 }
0674 
0675 static int rt8973a_muic_resume(struct device *dev)
0676 {
0677     struct i2c_client *i2c = to_i2c_client(dev);
0678     struct rt8973a_muic_info *info = i2c_get_clientdata(i2c);
0679 
0680     disable_irq_wake(info->irq);
0681 
0682     return 0;
0683 }
0684 #endif
0685 
0686 static SIMPLE_DEV_PM_OPS(rt8973a_muic_pm_ops,
0687              rt8973a_muic_suspend, rt8973a_muic_resume);
0688 
0689 static const struct i2c_device_id rt8973a_i2c_id[] = {
0690     { "rt8973a", TYPE_RT8973A },
0691     { }
0692 };
0693 MODULE_DEVICE_TABLE(i2c, rt8973a_i2c_id);
0694 
0695 static struct i2c_driver rt8973a_muic_i2c_driver = {
0696     .driver     = {
0697         .name   = "rt8973a",
0698         .pm = &rt8973a_muic_pm_ops,
0699         .of_match_table = rt8973a_dt_match,
0700     },
0701     .probe  = rt8973a_muic_i2c_probe,
0702     .remove = rt8973a_muic_i2c_remove,
0703     .id_table = rt8973a_i2c_id,
0704 };
0705 
0706 static int __init rt8973a_muic_i2c_init(void)
0707 {
0708     return i2c_add_driver(&rt8973a_muic_i2c_driver);
0709 }
0710 subsys_initcall(rt8973a_muic_i2c_init);
0711 
0712 MODULE_DESCRIPTION("Richtek RT8973A Extcon driver");
0713 MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
0714 MODULE_LICENSE("GPL");