0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/devm-helpers.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/i2c.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/mfd/max14577.h>
0016 #include <linux/mfd/max14577-private.h>
0017 #include <linux/extcon-provider.h>
0018
0019 #define DELAY_MS_DEFAULT 17000
0020
0021 enum max14577_muic_adc_debounce_time {
0022 ADC_DEBOUNCE_TIME_5MS = 0,
0023 ADC_DEBOUNCE_TIME_10MS,
0024 ADC_DEBOUNCE_TIME_25MS,
0025 ADC_DEBOUNCE_TIME_38_62MS,
0026 };
0027
0028 enum max14577_muic_status {
0029 MAX14577_MUIC_STATUS1 = 0,
0030 MAX14577_MUIC_STATUS2 = 1,
0031 MAX14577_MUIC_STATUS_END,
0032 };
0033
0034
0035
0036
0037
0038
0039
0040 struct max14577_muic_irq {
0041 unsigned int irq;
0042 const char *name;
0043 unsigned int virq;
0044 };
0045
0046 static struct max14577_muic_irq max14577_muic_irqs[] = {
0047 { MAX14577_IRQ_INT1_ADC, "muic-ADC" },
0048 { MAX14577_IRQ_INT1_ADCLOW, "muic-ADCLOW" },
0049 { MAX14577_IRQ_INT1_ADCERR, "muic-ADCError" },
0050 { MAX14577_IRQ_INT2_CHGTYP, "muic-CHGTYP" },
0051 { MAX14577_IRQ_INT2_CHGDETRUN, "muic-CHGDETRUN" },
0052 { MAX14577_IRQ_INT2_DCDTMR, "muic-DCDTMR" },
0053 { MAX14577_IRQ_INT2_DBCHG, "muic-DBCHG" },
0054 { MAX14577_IRQ_INT2_VBVOLT, "muic-VBVOLT" },
0055 };
0056
0057 static struct max14577_muic_irq max77836_muic_irqs[] = {
0058 { MAX14577_IRQ_INT1_ADC, "muic-ADC" },
0059 { MAX14577_IRQ_INT1_ADCLOW, "muic-ADCLOW" },
0060 { MAX14577_IRQ_INT1_ADCERR, "muic-ADCError" },
0061 { MAX77836_IRQ_INT1_ADC1K, "muic-ADC1K" },
0062 { MAX14577_IRQ_INT2_CHGTYP, "muic-CHGTYP" },
0063 { MAX14577_IRQ_INT2_CHGDETRUN, "muic-CHGDETRUN" },
0064 { MAX14577_IRQ_INT2_DCDTMR, "muic-DCDTMR" },
0065 { MAX14577_IRQ_INT2_DBCHG, "muic-DBCHG" },
0066 { MAX14577_IRQ_INT2_VBVOLT, "muic-VBVOLT" },
0067 { MAX77836_IRQ_INT2_VIDRM, "muic-VIDRM" },
0068 };
0069
0070 struct max14577_muic_info {
0071 struct device *dev;
0072 struct max14577 *max14577;
0073 struct extcon_dev *edev;
0074 int prev_cable_type;
0075 int prev_chg_type;
0076 u8 status[MAX14577_MUIC_STATUS_END];
0077
0078 struct max14577_muic_irq *muic_irqs;
0079 unsigned int muic_irqs_num;
0080 bool irq_adc;
0081 bool irq_chg;
0082 struct work_struct irq_work;
0083 struct mutex mutex;
0084
0085
0086
0087
0088
0089
0090
0091 struct delayed_work wq_detcable;
0092
0093
0094
0095
0096
0097 int path_usb;
0098 int path_uart;
0099 };
0100
0101 enum max14577_muic_cable_group {
0102 MAX14577_CABLE_GROUP_ADC = 0,
0103 MAX14577_CABLE_GROUP_CHG,
0104 };
0105
0106
0107 enum max14577_muic_acc_type {
0108 MAX14577_MUIC_ADC_GROUND = 0x0,
0109 MAX14577_MUIC_ADC_SEND_END_BUTTON,
0110 MAX14577_MUIC_ADC_REMOTE_S1_BUTTON,
0111 MAX14577_MUIC_ADC_REMOTE_S2_BUTTON,
0112 MAX14577_MUIC_ADC_REMOTE_S3_BUTTON,
0113 MAX14577_MUIC_ADC_REMOTE_S4_BUTTON,
0114 MAX14577_MUIC_ADC_REMOTE_S5_BUTTON,
0115 MAX14577_MUIC_ADC_REMOTE_S6_BUTTON,
0116 MAX14577_MUIC_ADC_REMOTE_S7_BUTTON,
0117 MAX14577_MUIC_ADC_REMOTE_S8_BUTTON,
0118 MAX14577_MUIC_ADC_REMOTE_S9_BUTTON,
0119 MAX14577_MUIC_ADC_REMOTE_S10_BUTTON,
0120 MAX14577_MUIC_ADC_REMOTE_S11_BUTTON,
0121 MAX14577_MUIC_ADC_REMOTE_S12_BUTTON,
0122 MAX14577_MUIC_ADC_RESERVED_ACC_1,
0123 MAX14577_MUIC_ADC_RESERVED_ACC_2,
0124 MAX14577_MUIC_ADC_RESERVED_ACC_3,
0125 MAX14577_MUIC_ADC_RESERVED_ACC_4,
0126 MAX14577_MUIC_ADC_RESERVED_ACC_5,
0127 MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE2,
0128 MAX14577_MUIC_ADC_PHONE_POWERED_DEV,
0129 MAX14577_MUIC_ADC_TTY_CONVERTER,
0130 MAX14577_MUIC_ADC_UART_CABLE,
0131 MAX14577_MUIC_ADC_CEA936A_TYPE1_CHG,
0132 MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF,
0133 MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON,
0134 MAX14577_MUIC_ADC_AV_CABLE_NOLOAD,
0135 MAX14577_MUIC_ADC_CEA936A_TYPE2_CHG,
0136 MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF,
0137 MAX14577_MUIC_ADC_FACTORY_MODE_UART_ON,
0138 MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE1,
0139 MAX14577_MUIC_ADC_OPEN,
0140 };
0141
0142 static const unsigned int max14577_extcon_cable[] = {
0143 EXTCON_USB,
0144 EXTCON_CHG_USB_SDP,
0145 EXTCON_CHG_USB_DCP,
0146 EXTCON_CHG_USB_FAST,
0147 EXTCON_CHG_USB_SLOW,
0148 EXTCON_CHG_USB_CDP,
0149 EXTCON_JIG,
0150 EXTCON_NONE,
0151 };
0152
0153
0154
0155
0156
0157
0158 static int max14577_muic_set_debounce_time(struct max14577_muic_info *info,
0159 enum max14577_muic_adc_debounce_time time)
0160 {
0161 u8 ret;
0162
0163 switch (time) {
0164 case ADC_DEBOUNCE_TIME_5MS:
0165 case ADC_DEBOUNCE_TIME_10MS:
0166 case ADC_DEBOUNCE_TIME_25MS:
0167 case ADC_DEBOUNCE_TIME_38_62MS:
0168 ret = max14577_update_reg(info->max14577->regmap,
0169 MAX14577_MUIC_REG_CONTROL3,
0170 CTRL3_ADCDBSET_MASK,
0171 time << CTRL3_ADCDBSET_SHIFT);
0172 if (ret) {
0173 dev_err(info->dev, "failed to set ADC debounce time\n");
0174 return ret;
0175 }
0176 break;
0177 default:
0178 dev_err(info->dev, "invalid ADC debounce time\n");
0179 return -EINVAL;
0180 }
0181
0182 return 0;
0183 };
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 static int max14577_muic_set_path(struct max14577_muic_info *info,
0196 u8 val, bool attached)
0197 {
0198 u8 ctrl1, ctrl2 = 0;
0199 int ret;
0200
0201
0202 ret = max14577_update_reg(info->max14577->regmap,
0203 MAX14577_MUIC_REG_CONTROL1,
0204 CLEAR_IDBEN_MICEN_MASK, CTRL1_SW_OPEN);
0205 if (ret < 0) {
0206 dev_err(info->dev, "failed to update MUIC register\n");
0207 return ret;
0208 }
0209
0210 if (attached)
0211 ctrl1 = val;
0212 else
0213 ctrl1 = CTRL1_SW_OPEN;
0214
0215 ret = max14577_update_reg(info->max14577->regmap,
0216 MAX14577_MUIC_REG_CONTROL1,
0217 CLEAR_IDBEN_MICEN_MASK, ctrl1);
0218 if (ret < 0) {
0219 dev_err(info->dev, "failed to update MUIC register\n");
0220 return ret;
0221 }
0222
0223 if (attached)
0224 ctrl2 |= CTRL2_CPEN_MASK;
0225 else
0226 ctrl2 |= CTRL2_LOWPWR_MASK;
0227
0228 ret = max14577_update_reg(info->max14577->regmap,
0229 MAX14577_REG_CONTROL2,
0230 CTRL2_LOWPWR_MASK | CTRL2_CPEN_MASK, ctrl2);
0231 if (ret < 0) {
0232 dev_err(info->dev, "failed to update MUIC register\n");
0233 return ret;
0234 }
0235
0236 dev_dbg(info->dev,
0237 "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
0238 ctrl1, ctrl2, attached ? "attached" : "detached");
0239
0240 return 0;
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 static int max14577_muic_get_cable_type(struct max14577_muic_info *info,
0255 enum max14577_muic_cable_group group, bool *attached)
0256 {
0257 int cable_type = 0;
0258 int adc;
0259 int chg_type;
0260
0261 switch (group) {
0262 case MAX14577_CABLE_GROUP_ADC:
0263
0264
0265
0266
0267 adc = info->status[MAX14577_MUIC_STATUS1] & STATUS1_ADC_MASK;
0268 adc >>= STATUS1_ADC_SHIFT;
0269
0270
0271
0272
0273
0274
0275 if (adc == MAX14577_MUIC_ADC_OPEN) {
0276 *attached = false;
0277
0278 cable_type = info->prev_cable_type;
0279 info->prev_cable_type = MAX14577_MUIC_ADC_OPEN;
0280 } else {
0281 *attached = true;
0282
0283 cable_type = info->prev_cable_type = adc;
0284 }
0285 break;
0286 case MAX14577_CABLE_GROUP_CHG:
0287
0288
0289
0290
0291 chg_type = info->status[MAX14577_MUIC_STATUS2] &
0292 STATUS2_CHGTYP_MASK;
0293 chg_type >>= STATUS2_CHGTYP_SHIFT;
0294
0295 if (chg_type == MAX14577_CHARGER_TYPE_NONE) {
0296 *attached = false;
0297
0298 cable_type = info->prev_chg_type;
0299 info->prev_chg_type = MAX14577_CHARGER_TYPE_NONE;
0300 } else {
0301 *attached = true;
0302
0303
0304
0305
0306
0307
0308 cable_type = info->prev_chg_type = chg_type;
0309 }
0310
0311 break;
0312 default:
0313 dev_err(info->dev, "Unknown cable group (%d)\n", group);
0314 cable_type = -EINVAL;
0315 break;
0316 }
0317
0318 return cable_type;
0319 }
0320
0321 static int max14577_muic_jig_handler(struct max14577_muic_info *info,
0322 int cable_type, bool attached)
0323 {
0324 int ret = 0;
0325 u8 path = CTRL1_SW_OPEN;
0326
0327 dev_dbg(info->dev,
0328 "external connector is %s (adc:0x%02x)\n",
0329 attached ? "attached" : "detached", cable_type);
0330
0331 switch (cable_type) {
0332 case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF:
0333 case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON:
0334
0335 path = CTRL1_SW_USB;
0336 break;
0337 case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF:
0338
0339 path = CTRL1_SW_UART;
0340 break;
0341 default:
0342 dev_err(info->dev, "failed to detect %s jig cable\n",
0343 attached ? "attached" : "detached");
0344 return -EINVAL;
0345 }
0346
0347 ret = max14577_muic_set_path(info, path, attached);
0348 if (ret < 0)
0349 return ret;
0350
0351 extcon_set_state_sync(info->edev, EXTCON_JIG, attached);
0352
0353 return 0;
0354 }
0355
0356 static int max14577_muic_adc_handler(struct max14577_muic_info *info)
0357 {
0358 int cable_type;
0359 bool attached;
0360 int ret = 0;
0361
0362
0363 cable_type = max14577_muic_get_cable_type(info,
0364 MAX14577_CABLE_GROUP_ADC, &attached);
0365
0366 dev_dbg(info->dev,
0367 "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
0368 attached ? "attached" : "detached", cable_type,
0369 info->prev_cable_type);
0370
0371 switch (cable_type) {
0372 case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF:
0373 case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON:
0374 case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF:
0375
0376 ret = max14577_muic_jig_handler(info, cable_type, attached);
0377 if (ret < 0)
0378 return ret;
0379 break;
0380 case MAX14577_MUIC_ADC_GROUND:
0381 case MAX14577_MUIC_ADC_SEND_END_BUTTON:
0382 case MAX14577_MUIC_ADC_REMOTE_S1_BUTTON:
0383 case MAX14577_MUIC_ADC_REMOTE_S2_BUTTON:
0384 case MAX14577_MUIC_ADC_REMOTE_S3_BUTTON:
0385 case MAX14577_MUIC_ADC_REMOTE_S4_BUTTON:
0386 case MAX14577_MUIC_ADC_REMOTE_S5_BUTTON:
0387 case MAX14577_MUIC_ADC_REMOTE_S6_BUTTON:
0388 case MAX14577_MUIC_ADC_REMOTE_S7_BUTTON:
0389 case MAX14577_MUIC_ADC_REMOTE_S8_BUTTON:
0390 case MAX14577_MUIC_ADC_REMOTE_S9_BUTTON:
0391 case MAX14577_MUIC_ADC_REMOTE_S10_BUTTON:
0392 case MAX14577_MUIC_ADC_REMOTE_S11_BUTTON:
0393 case MAX14577_MUIC_ADC_REMOTE_S12_BUTTON:
0394 case MAX14577_MUIC_ADC_RESERVED_ACC_1:
0395 case MAX14577_MUIC_ADC_RESERVED_ACC_2:
0396 case MAX14577_MUIC_ADC_RESERVED_ACC_3:
0397 case MAX14577_MUIC_ADC_RESERVED_ACC_4:
0398 case MAX14577_MUIC_ADC_RESERVED_ACC_5:
0399 case MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE2:
0400 case MAX14577_MUIC_ADC_PHONE_POWERED_DEV:
0401 case MAX14577_MUIC_ADC_TTY_CONVERTER:
0402 case MAX14577_MUIC_ADC_UART_CABLE:
0403 case MAX14577_MUIC_ADC_CEA936A_TYPE1_CHG:
0404 case MAX14577_MUIC_ADC_AV_CABLE_NOLOAD:
0405 case MAX14577_MUIC_ADC_CEA936A_TYPE2_CHG:
0406 case MAX14577_MUIC_ADC_FACTORY_MODE_UART_ON:
0407 case MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE1:
0408
0409
0410
0411
0412
0413 dev_info(info->dev,
0414 "accessory is %s but it isn't used (adc:0x%x)\n",
0415 attached ? "attached" : "detached", cable_type);
0416 return -EAGAIN;
0417 default:
0418 dev_err(info->dev,
0419 "failed to detect %s accessory (adc:0x%x)\n",
0420 attached ? "attached" : "detached", cable_type);
0421 return -EINVAL;
0422 }
0423
0424 return 0;
0425 }
0426
0427 static int max14577_muic_chg_handler(struct max14577_muic_info *info)
0428 {
0429 int chg_type;
0430 bool attached;
0431 int ret = 0;
0432
0433 chg_type = max14577_muic_get_cable_type(info,
0434 MAX14577_CABLE_GROUP_CHG, &attached);
0435
0436 dev_dbg(info->dev,
0437 "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
0438 attached ? "attached" : "detached",
0439 chg_type, info->prev_chg_type);
0440
0441 switch (chg_type) {
0442 case MAX14577_CHARGER_TYPE_USB:
0443
0444 ret = max14577_muic_set_path(info, info->path_usb, attached);
0445 if (ret < 0)
0446 return ret;
0447
0448 extcon_set_state_sync(info->edev, EXTCON_USB, attached);
0449 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
0450 attached);
0451 break;
0452 case MAX14577_CHARGER_TYPE_DEDICATED_CHG:
0453 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,
0454 attached);
0455 break;
0456 case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT:
0457 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP,
0458 attached);
0459 break;
0460 case MAX14577_CHARGER_TYPE_SPECIAL_500MA:
0461 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW,
0462 attached);
0463 break;
0464 case MAX14577_CHARGER_TYPE_SPECIAL_1A:
0465 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST,
0466 attached);
0467 break;
0468 case MAX14577_CHARGER_TYPE_NONE:
0469 case MAX14577_CHARGER_TYPE_DEAD_BATTERY:
0470 break;
0471 default:
0472 dev_err(info->dev,
0473 "failed to detect %s accessory (chg_type:0x%x)\n",
0474 attached ? "attached" : "detached", chg_type);
0475 return -EINVAL;
0476 }
0477
0478 return 0;
0479 }
0480
0481 static void max14577_muic_irq_work(struct work_struct *work)
0482 {
0483 struct max14577_muic_info *info = container_of(work,
0484 struct max14577_muic_info, irq_work);
0485 int ret = 0;
0486
0487 if (!info->edev)
0488 return;
0489
0490 mutex_lock(&info->mutex);
0491
0492 ret = max14577_bulk_read(info->max14577->regmap,
0493 MAX14577_MUIC_REG_STATUS1, info->status, 2);
0494 if (ret) {
0495 dev_err(info->dev, "failed to read MUIC register\n");
0496 mutex_unlock(&info->mutex);
0497 return;
0498 }
0499
0500 if (info->irq_adc) {
0501 ret = max14577_muic_adc_handler(info);
0502 info->irq_adc = false;
0503 }
0504 if (info->irq_chg) {
0505 ret = max14577_muic_chg_handler(info);
0506 info->irq_chg = false;
0507 }
0508
0509 if (ret < 0)
0510 dev_err(info->dev, "failed to handle MUIC interrupt\n");
0511
0512 mutex_unlock(&info->mutex);
0513 }
0514
0515
0516
0517
0518
0519 static int max14577_parse_irq(struct max14577_muic_info *info, int irq_type)
0520 {
0521 switch (irq_type) {
0522 case MAX14577_IRQ_INT1_ADC:
0523 case MAX14577_IRQ_INT1_ADCLOW:
0524 case MAX14577_IRQ_INT1_ADCERR:
0525
0526
0527
0528
0529 info->irq_adc = true;
0530 return 1;
0531 case MAX14577_IRQ_INT2_CHGTYP:
0532 case MAX14577_IRQ_INT2_CHGDETRUN:
0533 case MAX14577_IRQ_INT2_DCDTMR:
0534 case MAX14577_IRQ_INT2_DBCHG:
0535 case MAX14577_IRQ_INT2_VBVOLT:
0536
0537 info->irq_chg = true;
0538 return 1;
0539 default:
0540 return 0;
0541 }
0542 }
0543
0544
0545
0546
0547
0548 static int max77836_parse_irq(struct max14577_muic_info *info, int irq_type)
0549 {
0550
0551 if (max14577_parse_irq(info, irq_type))
0552 return 1;
0553
0554 switch (irq_type) {
0555 case MAX77836_IRQ_INT1_ADC1K:
0556 info->irq_adc = true;
0557 return 1;
0558 case MAX77836_IRQ_INT2_VIDRM:
0559
0560 info->irq_chg = true;
0561 return 1;
0562 default:
0563 return 0;
0564 }
0565 }
0566
0567 static irqreturn_t max14577_muic_irq_handler(int irq, void *data)
0568 {
0569 struct max14577_muic_info *info = data;
0570 int i, irq_type = -1;
0571 bool irq_parsed;
0572
0573
0574
0575
0576
0577
0578
0579 for (i = 0; i < info->muic_irqs_num; i++)
0580 if (irq == info->muic_irqs[i].virq)
0581 irq_type = info->muic_irqs[i].irq;
0582
0583 switch (info->max14577->dev_type) {
0584 case MAXIM_DEVICE_TYPE_MAX77836:
0585 irq_parsed = max77836_parse_irq(info, irq_type);
0586 break;
0587 case MAXIM_DEVICE_TYPE_MAX14577:
0588 default:
0589 irq_parsed = max14577_parse_irq(info, irq_type);
0590 break;
0591 }
0592
0593 if (!irq_parsed) {
0594 dev_err(info->dev, "muic interrupt: irq %d occurred, skipped\n",
0595 irq_type);
0596 return IRQ_HANDLED;
0597 }
0598 schedule_work(&info->irq_work);
0599
0600 return IRQ_HANDLED;
0601 }
0602
0603 static int max14577_muic_detect_accessory(struct max14577_muic_info *info)
0604 {
0605 int ret = 0;
0606 int adc;
0607 int chg_type;
0608 bool attached;
0609
0610 mutex_lock(&info->mutex);
0611
0612
0613 ret = max14577_bulk_read(info->max14577->regmap,
0614 MAX14577_MUIC_REG_STATUS1, info->status, 2);
0615 if (ret) {
0616 dev_err(info->dev, "failed to read MUIC register\n");
0617 mutex_unlock(&info->mutex);
0618 return ret;
0619 }
0620
0621 adc = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_ADC,
0622 &attached);
0623 if (attached && adc != MAX14577_MUIC_ADC_OPEN) {
0624 ret = max14577_muic_adc_handler(info);
0625 if (ret < 0) {
0626 dev_err(info->dev, "Cannot detect accessory\n");
0627 mutex_unlock(&info->mutex);
0628 return ret;
0629 }
0630 }
0631
0632 chg_type = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_CHG,
0633 &attached);
0634 if (attached && chg_type != MAX14577_CHARGER_TYPE_NONE) {
0635 ret = max14577_muic_chg_handler(info);
0636 if (ret < 0) {
0637 dev_err(info->dev, "Cannot detect charger accessory\n");
0638 mutex_unlock(&info->mutex);
0639 return ret;
0640 }
0641 }
0642
0643 mutex_unlock(&info->mutex);
0644
0645 return 0;
0646 }
0647
0648 static void max14577_muic_detect_cable_wq(struct work_struct *work)
0649 {
0650 struct max14577_muic_info *info = container_of(to_delayed_work(work),
0651 struct max14577_muic_info, wq_detcable);
0652
0653 max14577_muic_detect_accessory(info);
0654 }
0655
0656 static int max14577_muic_probe(struct platform_device *pdev)
0657 {
0658 struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
0659 struct max14577_muic_info *info;
0660 int delay_jiffies;
0661 int cable_type;
0662 bool attached;
0663 int ret;
0664 int i;
0665 u8 id;
0666
0667 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
0668 if (!info)
0669 return -ENOMEM;
0670
0671 info->dev = &pdev->dev;
0672 info->max14577 = max14577;
0673
0674 platform_set_drvdata(pdev, info);
0675 mutex_init(&info->mutex);
0676
0677 ret = devm_work_autocancel(&pdev->dev, &info->irq_work,
0678 max14577_muic_irq_work);
0679 if (ret)
0680 return ret;
0681
0682 switch (max14577->dev_type) {
0683 case MAXIM_DEVICE_TYPE_MAX77836:
0684 info->muic_irqs = max77836_muic_irqs;
0685 info->muic_irqs_num = ARRAY_SIZE(max77836_muic_irqs);
0686 break;
0687 case MAXIM_DEVICE_TYPE_MAX14577:
0688 default:
0689 info->muic_irqs = max14577_muic_irqs;
0690 info->muic_irqs_num = ARRAY_SIZE(max14577_muic_irqs);
0691 }
0692
0693
0694 for (i = 0; i < info->muic_irqs_num; i++) {
0695 struct max14577_muic_irq *muic_irq = &info->muic_irqs[i];
0696 int virq = 0;
0697
0698 virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq);
0699 if (virq <= 0)
0700 return -EINVAL;
0701 muic_irq->virq = virq;
0702
0703 ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
0704 max14577_muic_irq_handler,
0705 IRQF_NO_SUSPEND,
0706 muic_irq->name, info);
0707 if (ret) {
0708 dev_err(&pdev->dev,
0709 "failed: irq request (IRQ: %d, error :%d)\n",
0710 muic_irq->irq, ret);
0711 return ret;
0712 }
0713 }
0714
0715
0716 info->edev = devm_extcon_dev_allocate(&pdev->dev,
0717 max14577_extcon_cable);
0718 if (IS_ERR(info->edev)) {
0719 dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
0720 return PTR_ERR(info->edev);
0721 }
0722
0723 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
0724 if (ret) {
0725 dev_err(&pdev->dev, "failed to register extcon device\n");
0726 return ret;
0727 }
0728
0729
0730 info->path_usb = CTRL1_SW_USB;
0731 info->path_uart = CTRL1_SW_UART;
0732 delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
0733
0734
0735 ret = max14577_bulk_read(info->max14577->regmap,
0736 MAX14577_MUIC_REG_STATUS1, info->status, 2);
0737 if (ret) {
0738 dev_err(info->dev, "Cannot read STATUS registers\n");
0739 return ret;
0740 }
0741 cable_type = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_ADC,
0742 &attached);
0743 if (attached && cable_type == MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF)
0744 max14577_muic_set_path(info, info->path_uart, true);
0745
0746
0747 ret = max14577_read_reg(info->max14577->regmap,
0748 MAX14577_REG_DEVICEID, &id);
0749 if (ret < 0) {
0750 dev_err(&pdev->dev, "failed to read revision number\n");
0751 return ret;
0752 }
0753 dev_info(info->dev, "device ID : 0x%x\n", id);
0754
0755
0756 max14577_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766 INIT_DELAYED_WORK(&info->wq_detcable, max14577_muic_detect_cable_wq);
0767 queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
0768 delay_jiffies);
0769
0770 return ret;
0771 }
0772
0773 static const struct platform_device_id max14577_muic_id[] = {
0774 { "max14577-muic", MAXIM_DEVICE_TYPE_MAX14577, },
0775 { "max77836-muic", MAXIM_DEVICE_TYPE_MAX77836, },
0776 { }
0777 };
0778 MODULE_DEVICE_TABLE(platform, max14577_muic_id);
0779
0780 static const struct of_device_id of_max14577_muic_dt_match[] = {
0781 { .compatible = "maxim,max14577-muic",
0782 .data = (void *)MAXIM_DEVICE_TYPE_MAX14577, },
0783 { .compatible = "maxim,max77836-muic",
0784 .data = (void *)MAXIM_DEVICE_TYPE_MAX77836, },
0785 { },
0786 };
0787 MODULE_DEVICE_TABLE(of, of_max14577_muic_dt_match);
0788
0789 static struct platform_driver max14577_muic_driver = {
0790 .driver = {
0791 .name = "max14577-muic",
0792 .of_match_table = of_max14577_muic_dt_match,
0793 },
0794 .probe = max14577_muic_probe,
0795 .id_table = max14577_muic_id,
0796 };
0797
0798 module_platform_driver(max14577_muic_driver);
0799
0800 MODULE_DESCRIPTION("Maxim 14577/77836 Extcon driver");
0801 MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <krzk@kernel.org>");
0802 MODULE_LICENSE("GPL");
0803 MODULE_ALIAS("platform:extcon-max14577");