1 // SPDX-License-Identifier: GPL-2.0+
3 // extcon-max77843.c - Maxim MAX77843 extcon driver to support
4 // MUIC(Micro USB Interface Controller)
6 // Copyright (C) 2015 Samsung Electronics
7 // Author: Jaewon Kim <jaewon02.kim@samsung.com>
9 #include <linux/extcon-provider.h>
10 #include <linux/i2c.h>
11 #include <linux/interrupt.h>
12 #include <linux/kernel.h>
13 #include <linux/mfd/max77693-common.h>
14 #include <linux/mfd/max77843-private.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/workqueue.h>
19 #define DELAY_MS_DEFAULT 15000 /* unit: millisecond */
21 enum max77843_muic_status
{
22 MAX77843_MUIC_STATUS1
= 0,
23 MAX77843_MUIC_STATUS2
,
24 MAX77843_MUIC_STATUS3
,
26 MAX77843_MUIC_STATUS_NUM
,
29 struct max77843_muic_info
{
31 struct max77693_dev
*max77843
;
32 struct extcon_dev
*edev
;
35 struct work_struct irq_work
;
36 struct delayed_work wq_detcable
;
38 u8 status
[MAX77843_MUIC_STATUS_NUM
];
47 enum max77843_muic_cable_group
{
48 MAX77843_CABLE_GROUP_ADC
= 0,
49 MAX77843_CABLE_GROUP_ADC_GND
,
50 MAX77843_CABLE_GROUP_CHG
,
53 enum max77843_muic_adc_debounce_time
{
54 MAX77843_DEBOUNCE_TIME_5MS
= 0,
55 MAX77843_DEBOUNCE_TIME_10MS
,
56 MAX77843_DEBOUNCE_TIME_25MS
,
57 MAX77843_DEBOUNCE_TIME_38_62MS
,
60 /* Define accessory cable type */
61 enum max77843_muic_accessory_type
{
62 MAX77843_MUIC_ADC_GROUND
= 0,
63 MAX77843_MUIC_ADC_SEND_END_BUTTON
,
64 MAX77843_MUIC_ADC_REMOTE_S1_BUTTON
,
65 MAX77843_MUIC_ADC_REMOTE_S2_BUTTON
,
66 MAX77843_MUIC_ADC_REMOTE_S3_BUTTON
,
67 MAX77843_MUIC_ADC_REMOTE_S4_BUTTON
,
68 MAX77843_MUIC_ADC_REMOTE_S5_BUTTON
,
69 MAX77843_MUIC_ADC_REMOTE_S6_BUTTON
,
70 MAX77843_MUIC_ADC_REMOTE_S7_BUTTON
,
71 MAX77843_MUIC_ADC_REMOTE_S8_BUTTON
,
72 MAX77843_MUIC_ADC_REMOTE_S9_BUTTON
,
73 MAX77843_MUIC_ADC_REMOTE_S10_BUTTON
,
74 MAX77843_MUIC_ADC_REMOTE_S11_BUTTON
,
75 MAX77843_MUIC_ADC_REMOTE_S12_BUTTON
,
76 MAX77843_MUIC_ADC_RESERVED_ACC_1
,
77 MAX77843_MUIC_ADC_RESERVED_ACC_2
,
78 MAX77843_MUIC_ADC_RESERVED_ACC_3
, /* SmartDock */
79 MAX77843_MUIC_ADC_RESERVED_ACC_4
,
80 MAX77843_MUIC_ADC_RESERVED_ACC_5
,
81 MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2
,
82 MAX77843_MUIC_ADC_PHONE_POWERED_DEV
,
83 MAX77843_MUIC_ADC_TTY_CONVERTER
,
84 MAX77843_MUIC_ADC_UART_CABLE
,
85 MAX77843_MUIC_ADC_CEA936A_TYPE1_CHG
,
86 MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF
,
87 MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON
,
88 MAX77843_MUIC_ADC_AV_CABLE_NOLOAD
,
89 MAX77843_MUIC_ADC_CEA936A_TYPE2_CHG
,
90 MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF
,
91 MAX77843_MUIC_ADC_FACTORY_MODE_UART_ON
,
92 MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE1
,
93 MAX77843_MUIC_ADC_OPEN
,
96 * The below accessories should check
97 * not only ADC value but also ADC1K and VBVolt value.
99 /* Offset|ADC1K|VBVolt| */
100 MAX77843_MUIC_GND_USB_HOST
= 0x100, /* 0x1| 0| 0| */
101 MAX77843_MUIC_GND_USB_HOST_VB
= 0x101, /* 0x1| 0| 1| */
102 MAX77843_MUIC_GND_MHL
= 0x102, /* 0x1| 1| 0| */
103 MAX77843_MUIC_GND_MHL_VB
= 0x103, /* 0x1| 1| 1| */
106 /* Define charger cable type */
107 enum max77843_muic_charger_type
{
108 MAX77843_MUIC_CHG_NONE
= 0,
109 MAX77843_MUIC_CHG_USB
,
110 MAX77843_MUIC_CHG_DOWNSTREAM
,
111 MAX77843_MUIC_CHG_DEDICATED
,
112 MAX77843_MUIC_CHG_SPECIAL_500MA
,
113 MAX77843_MUIC_CHG_SPECIAL_1A
,
114 MAX77843_MUIC_CHG_SPECIAL_BIAS
,
115 MAX77843_MUIC_CHG_RESERVED
,
116 MAX77843_MUIC_CHG_GND
,
117 MAX77843_MUIC_CHG_DOCK
,
120 static const unsigned int max77843_extcon_cable
[] = {
134 struct max77843_muic_irq
{
140 static struct max77843_muic_irq max77843_muic_irqs
[] = {
141 { MAX77843_MUIC_IRQ_INT1_ADC
, "MUIC-ADC" },
142 { MAX77843_MUIC_IRQ_INT1_ADCERROR
, "MUIC-ADC_ERROR" },
143 { MAX77843_MUIC_IRQ_INT1_ADC1K
, "MUIC-ADC1K" },
144 { MAX77843_MUIC_IRQ_INT2_CHGTYP
, "MUIC-CHGTYP" },
145 { MAX77843_MUIC_IRQ_INT2_CHGDETRUN
, "MUIC-CHGDETRUN" },
146 { MAX77843_MUIC_IRQ_INT2_DCDTMR
, "MUIC-DCDTMR" },
147 { MAX77843_MUIC_IRQ_INT2_DXOVP
, "MUIC-DXOVP" },
148 { MAX77843_MUIC_IRQ_INT2_VBVOLT
, "MUIC-VBVOLT" },
149 { MAX77843_MUIC_IRQ_INT3_VBADC
, "MUIC-VBADC" },
150 { MAX77843_MUIC_IRQ_INT3_VDNMON
, "MUIC-VDNMON" },
151 { MAX77843_MUIC_IRQ_INT3_DNRES
, "MUIC-DNRES" },
152 { MAX77843_MUIC_IRQ_INT3_MPNACK
, "MUIC-MPNACK"},
153 { MAX77843_MUIC_IRQ_INT3_MRXBUFOW
, "MUIC-MRXBUFOW"},
154 { MAX77843_MUIC_IRQ_INT3_MRXTRF
, "MUIC-MRXTRF"},
155 { MAX77843_MUIC_IRQ_INT3_MRXPERR
, "MUIC-MRXPERR"},
156 { MAX77843_MUIC_IRQ_INT3_MRXRDY
, "MUIC-MRXRDY"},
159 static const struct regmap_config max77843_muic_regmap_config
= {
162 .max_register
= MAX77843_MUIC_REG_END
,
165 static const struct regmap_irq max77843_muic_irq
[] = {
167 { .reg_offset
= 0, .mask
= MAX77843_MUIC_ADC
, },
168 { .reg_offset
= 0, .mask
= MAX77843_MUIC_ADCERROR
, },
169 { .reg_offset
= 0, .mask
= MAX77843_MUIC_ADC1K
, },
172 { .reg_offset
= 1, .mask
= MAX77843_MUIC_CHGTYP
, },
173 { .reg_offset
= 1, .mask
= MAX77843_MUIC_CHGDETRUN
, },
174 { .reg_offset
= 1, .mask
= MAX77843_MUIC_DCDTMR
, },
175 { .reg_offset
= 1, .mask
= MAX77843_MUIC_DXOVP
, },
176 { .reg_offset
= 1, .mask
= MAX77843_MUIC_VBVOLT
, },
179 { .reg_offset
= 2, .mask
= MAX77843_MUIC_VBADC
, },
180 { .reg_offset
= 2, .mask
= MAX77843_MUIC_VDNMON
, },
181 { .reg_offset
= 2, .mask
= MAX77843_MUIC_DNRES
, },
182 { .reg_offset
= 2, .mask
= MAX77843_MUIC_MPNACK
, },
183 { .reg_offset
= 2, .mask
= MAX77843_MUIC_MRXBUFOW
, },
184 { .reg_offset
= 2, .mask
= MAX77843_MUIC_MRXTRF
, },
185 { .reg_offset
= 2, .mask
= MAX77843_MUIC_MRXPERR
, },
186 { .reg_offset
= 2, .mask
= MAX77843_MUIC_MRXRDY
, },
189 static const struct regmap_irq_chip max77843_muic_irq_chip
= {
190 .name
= "max77843-muic",
191 .status_base
= MAX77843_MUIC_REG_INT1
,
192 .unmask_base
= MAX77843_MUIC_REG_INTMASK1
,
194 .irqs
= max77843_muic_irq
,
195 .num_irqs
= ARRAY_SIZE(max77843_muic_irq
),
198 static int max77843_muic_set_path(struct max77843_muic_info
*info
,
199 u8 val
, bool attached
, bool nobccomp
)
201 struct max77693_dev
*max77843
= info
->max77843
;
203 unsigned int ctrl1
, ctrl2
;
208 ctrl1
= MAX77843_MUIC_CONTROL1_SW_OPEN
;
210 /* Disable BC1.2 protocol and force manual switch control */
211 ctrl1
|= MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK
;
214 ret
= regmap_update_bits(max77843
->regmap_muic
,
215 MAX77843_MUIC_REG_CONTROL1
,
216 MAX77843_MUIC_CONTROL1_COM_SW
|
217 MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK
,
220 dev_err(info
->dev
, "Cannot switch MUIC port\n");
225 ctrl2
= MAX77843_MUIC_CONTROL2_CPEN_MASK
;
227 ctrl2
= MAX77843_MUIC_CONTROL2_LOWPWR_MASK
;
229 ret
= regmap_update_bits(max77843
->regmap_muic
,
230 MAX77843_MUIC_REG_CONTROL2
,
231 MAX77843_MUIC_CONTROL2_LOWPWR_MASK
|
232 MAX77843_MUIC_CONTROL2_CPEN_MASK
, ctrl2
);
234 dev_err(info
->dev
, "Cannot update lowpower mode\n");
239 "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
240 ctrl1
, ctrl2
, attached
? "attached" : "detached");
245 static void max77843_charger_set_otg_vbus(struct max77843_muic_info
*info
,
248 struct max77693_dev
*max77843
= info
->max77843
;
252 cnfg00
= MAX77843_CHG_OTG_MASK
| MAX77843_CHG_BOOST_MASK
;
254 cnfg00
= MAX77843_CHG_ENABLE
| MAX77843_CHG_BUCK_MASK
;
256 regmap_update_bits(max77843
->regmap_chg
, MAX77843_CHG_REG_CHG_CNFG_00
,
257 MAX77843_CHG_MODE_MASK
, cnfg00
);
260 static int max77843_muic_get_cable_type(struct max77843_muic_info
*info
,
261 enum max77843_muic_cable_group group
, bool *attached
)
263 int adc
, chg_type
, cable_type
, gnd_type
;
265 adc
= info
->status
[MAX77843_MUIC_STATUS1
] &
266 MAX77843_MUIC_STATUS1_ADC_MASK
;
267 adc
>>= MAX77843_MUIC_STATUS1_ADC_SHIFT
;
270 case MAX77843_CABLE_GROUP_ADC
:
271 if (adc
== MAX77843_MUIC_ADC_OPEN
) {
273 cable_type
= info
->prev_cable_type
;
274 info
->prev_cable_type
= MAX77843_MUIC_ADC_OPEN
;
277 cable_type
= info
->prev_cable_type
= adc
;
280 case MAX77843_CABLE_GROUP_CHG
:
281 chg_type
= info
->status
[MAX77843_MUIC_STATUS2
] &
282 MAX77843_MUIC_STATUS2_CHGTYP_MASK
;
284 /* Check GROUND accessory with charger cable */
285 if (adc
== MAX77843_MUIC_ADC_GROUND
) {
286 if (chg_type
== MAX77843_MUIC_CHG_NONE
) {
288 * The following state when charger cable is
289 * disconnected but the GROUND accessory still
293 cable_type
= info
->prev_chg_type
;
294 info
->prev_chg_type
= MAX77843_MUIC_CHG_NONE
;
298 * The following state when charger cable is
299 * connected on the GROUND accessory.
302 cable_type
= MAX77843_MUIC_CHG_GND
;
303 info
->prev_chg_type
= MAX77843_MUIC_CHG_GND
;
308 if (adc
== MAX77843_MUIC_ADC_RESERVED_ACC_3
) { /* SmartDock */
309 if (chg_type
== MAX77843_MUIC_CHG_NONE
) {
311 cable_type
= info
->prev_chg_type
;
312 info
->prev_chg_type
= MAX77843_MUIC_CHG_NONE
;
315 cable_type
= MAX77843_MUIC_CHG_DOCK
;
316 info
->prev_chg_type
= MAX77843_MUIC_CHG_DOCK
;
321 if (chg_type
== MAX77843_MUIC_CHG_NONE
) {
323 cable_type
= info
->prev_chg_type
;
324 info
->prev_chg_type
= MAX77843_MUIC_CHG_NONE
;
327 cable_type
= info
->prev_chg_type
= chg_type
;
330 case MAX77843_CABLE_GROUP_ADC_GND
:
331 if (adc
== MAX77843_MUIC_ADC_OPEN
) {
333 cable_type
= info
->prev_gnd_type
;
334 info
->prev_gnd_type
= MAX77843_MUIC_ADC_OPEN
;
339 * Offset|ADC1K|VBVolt|
340 * 0x1| 0| 0| USB-HOST
341 * 0x1| 0| 1| USB-HOST with VB
343 * 0x1| 1| 1| MHL with VB
345 /* Get ADC1K register bit */
346 gnd_type
= (info
->status
[MAX77843_MUIC_STATUS1
] &
347 MAX77843_MUIC_STATUS1_ADC1K_MASK
);
349 /* Get VBVolt register bit */
350 gnd_type
|= (info
->status
[MAX77843_MUIC_STATUS2
] &
351 MAX77843_MUIC_STATUS2_VBVOLT_MASK
);
352 gnd_type
>>= MAX77843_MUIC_STATUS2_VBVOLT_SHIFT
;
354 /* Offset of GND cable */
355 gnd_type
|= MAX77843_MUIC_GND_USB_HOST
;
356 cable_type
= info
->prev_gnd_type
= gnd_type
;
360 dev_err(info
->dev
, "Unknown cable group (%d)\n", group
);
361 cable_type
= -EINVAL
;
368 static int max77843_muic_adc_gnd_handler(struct max77843_muic_info
*info
)
370 int ret
, gnd_cable_type
;
373 gnd_cable_type
= max77843_muic_get_cable_type(info
,
374 MAX77843_CABLE_GROUP_ADC_GND
, &attached
);
375 dev_dbg(info
->dev
, "external connector is %s (gnd:0x%02x)\n",
376 attached
? "attached" : "detached", gnd_cable_type
);
378 switch (gnd_cable_type
) {
379 case MAX77843_MUIC_GND_USB_HOST
:
380 case MAX77843_MUIC_GND_USB_HOST_VB
:
381 ret
= max77843_muic_set_path(info
,
382 MAX77843_MUIC_CONTROL1_SW_USB
,
387 extcon_set_state_sync(info
->edev
, EXTCON_USB_HOST
, attached
);
388 max77843_charger_set_otg_vbus(info
, attached
);
390 case MAX77843_MUIC_GND_MHL_VB
:
391 case MAX77843_MUIC_GND_MHL
:
392 ret
= max77843_muic_set_path(info
,
393 MAX77843_MUIC_CONTROL1_SW_OPEN
,
398 extcon_set_state_sync(info
->edev
, EXTCON_DISP_MHL
, attached
);
401 dev_err(info
->dev
, "failed to detect %s accessory(gnd:0x%x)\n",
402 attached
? "attached" : "detached", gnd_cable_type
);
409 static int max77843_muic_jig_handler(struct max77843_muic_info
*info
,
410 int cable_type
, bool attached
)
413 u8 path
= MAX77843_MUIC_CONTROL1_SW_OPEN
;
415 dev_dbg(info
->dev
, "external connector is %s (adc:0x%02x)\n",
416 attached
? "attached" : "detached", cable_type
);
418 switch (cable_type
) {
419 case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF
:
420 case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON
:
421 path
= MAX77843_MUIC_CONTROL1_SW_USB
;
423 case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF
:
424 path
= MAX77843_MUIC_CONTROL1_SW_UART
;
430 ret
= max77843_muic_set_path(info
, path
, attached
, false);
434 extcon_set_state_sync(info
->edev
, EXTCON_JIG
, attached
);
439 static int max77843_muic_dock_handler(struct max77843_muic_info
*info
,
444 dev_dbg(info
->dev
, "external connector is %s (adc: 0x10)\n",
445 attached
? "attached" : "detached");
447 ret
= max77843_muic_set_path(info
, MAX77843_MUIC_CONTROL1_SW_USB
,
452 extcon_set_state_sync(info
->edev
, EXTCON_DISP_MHL
, attached
);
453 extcon_set_state_sync(info
->edev
, EXTCON_USB_HOST
, attached
);
454 extcon_set_state_sync(info
->edev
, EXTCON_DOCK
, attached
);
459 static int max77843_muic_adc_handler(struct max77843_muic_info
*info
)
464 cable_type
= max77843_muic_get_cable_type(info
,
465 MAX77843_CABLE_GROUP_ADC
, &attached
);
468 "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
469 attached
? "attached" : "detached", cable_type
,
470 info
->prev_cable_type
);
472 switch (cable_type
) {
473 case MAX77843_MUIC_ADC_RESERVED_ACC_3
: /* SmartDock */
474 ret
= max77843_muic_dock_handler(info
, attached
);
478 case MAX77843_MUIC_ADC_GROUND
:
479 ret
= max77843_muic_adc_gnd_handler(info
);
483 case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF
:
484 case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON
:
485 case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF
:
486 ret
= max77843_muic_jig_handler(info
, cable_type
, attached
);
490 case MAX77843_MUIC_ADC_SEND_END_BUTTON
:
491 case MAX77843_MUIC_ADC_REMOTE_S1_BUTTON
:
492 case MAX77843_MUIC_ADC_REMOTE_S2_BUTTON
:
493 case MAX77843_MUIC_ADC_REMOTE_S3_BUTTON
:
494 case MAX77843_MUIC_ADC_REMOTE_S4_BUTTON
:
495 case MAX77843_MUIC_ADC_REMOTE_S5_BUTTON
:
496 case MAX77843_MUIC_ADC_REMOTE_S6_BUTTON
:
497 case MAX77843_MUIC_ADC_REMOTE_S7_BUTTON
:
498 case MAX77843_MUIC_ADC_REMOTE_S8_BUTTON
:
499 case MAX77843_MUIC_ADC_REMOTE_S9_BUTTON
:
500 case MAX77843_MUIC_ADC_REMOTE_S10_BUTTON
:
501 case MAX77843_MUIC_ADC_REMOTE_S11_BUTTON
:
502 case MAX77843_MUIC_ADC_REMOTE_S12_BUTTON
:
503 case MAX77843_MUIC_ADC_RESERVED_ACC_1
:
504 case MAX77843_MUIC_ADC_RESERVED_ACC_2
:
505 case MAX77843_MUIC_ADC_RESERVED_ACC_4
:
506 case MAX77843_MUIC_ADC_RESERVED_ACC_5
:
507 case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2
:
508 case MAX77843_MUIC_ADC_PHONE_POWERED_DEV
:
509 case MAX77843_MUIC_ADC_TTY_CONVERTER
:
510 case MAX77843_MUIC_ADC_UART_CABLE
:
511 case MAX77843_MUIC_ADC_CEA936A_TYPE1_CHG
:
512 case MAX77843_MUIC_ADC_AV_CABLE_NOLOAD
:
513 case MAX77843_MUIC_ADC_CEA936A_TYPE2_CHG
:
514 case MAX77843_MUIC_ADC_FACTORY_MODE_UART_ON
:
515 case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE1
:
516 case MAX77843_MUIC_ADC_OPEN
:
518 "accessory is %s but it isn't used (adc:0x%x)\n",
519 attached
? "attached" : "detached", cable_type
);
523 "failed to detect %s accessory (adc:0x%x)\n",
524 attached
? "attached" : "detached", cable_type
);
531 static int max77843_muic_chg_handler(struct max77843_muic_info
*info
)
533 int ret
, chg_type
, gnd_type
;
536 chg_type
= max77843_muic_get_cable_type(info
,
537 MAX77843_CABLE_GROUP_CHG
, &attached
);
540 "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
541 attached
? "attached" : "detached",
542 chg_type
, info
->prev_chg_type
);
545 case MAX77843_MUIC_CHG_USB
:
546 ret
= max77843_muic_set_path(info
,
547 MAX77843_MUIC_CONTROL1_SW_USB
,
552 extcon_set_state_sync(info
->edev
, EXTCON_USB
, attached
);
553 extcon_set_state_sync(info
->edev
, EXTCON_CHG_USB_SDP
,
556 case MAX77843_MUIC_CHG_DOWNSTREAM
:
557 ret
= max77843_muic_set_path(info
,
558 MAX77843_MUIC_CONTROL1_SW_OPEN
,
563 extcon_set_state_sync(info
->edev
, EXTCON_CHG_USB_CDP
,
566 case MAX77843_MUIC_CHG_DEDICATED
:
567 ret
= max77843_muic_set_path(info
,
568 MAX77843_MUIC_CONTROL1_SW_OPEN
,
573 extcon_set_state_sync(info
->edev
, EXTCON_CHG_USB_DCP
,
576 case MAX77843_MUIC_CHG_SPECIAL_500MA
:
577 ret
= max77843_muic_set_path(info
,
578 MAX77843_MUIC_CONTROL1_SW_OPEN
,
583 extcon_set_state_sync(info
->edev
, EXTCON_CHG_USB_SLOW
,
586 case MAX77843_MUIC_CHG_SPECIAL_1A
:
587 ret
= max77843_muic_set_path(info
,
588 MAX77843_MUIC_CONTROL1_SW_OPEN
,
593 extcon_set_state_sync(info
->edev
, EXTCON_CHG_USB_FAST
,
596 case MAX77843_MUIC_CHG_GND
:
597 gnd_type
= max77843_muic_get_cable_type(info
,
598 MAX77843_CABLE_GROUP_ADC_GND
, &attached
);
600 /* Charger cable on MHL accessory is attach or detach */
601 if (gnd_type
== MAX77843_MUIC_GND_MHL_VB
)
602 extcon_set_state_sync(info
->edev
, EXTCON_CHG_USB_DCP
,
604 else if (gnd_type
== MAX77843_MUIC_GND_MHL
)
605 extcon_set_state_sync(info
->edev
, EXTCON_CHG_USB_DCP
,
608 case MAX77843_MUIC_CHG_DOCK
:
609 extcon_set_state_sync(info
->edev
, EXTCON_CHG_USB_DCP
, attached
);
611 case MAX77843_MUIC_CHG_NONE
:
615 "failed to detect %s accessory (chg_type:0x%x)\n",
616 attached
? "attached" : "detached", chg_type
);
618 max77843_muic_set_path(info
, MAX77843_MUIC_CONTROL1_SW_OPEN
,
626 static void max77843_muic_irq_work(struct work_struct
*work
)
628 struct max77843_muic_info
*info
= container_of(work
,
629 struct max77843_muic_info
, irq_work
);
630 struct max77693_dev
*max77843
= info
->max77843
;
633 mutex_lock(&info
->mutex
);
635 ret
= regmap_bulk_read(max77843
->regmap_muic
,
636 MAX77843_MUIC_REG_STATUS1
, info
->status
,
637 MAX77843_MUIC_STATUS_NUM
);
639 dev_err(info
->dev
, "Cannot read STATUS registers\n");
640 mutex_unlock(&info
->mutex
);
645 ret
= max77843_muic_adc_handler(info
);
647 dev_err(info
->dev
, "Unknown cable type\n");
648 info
->irq_adc
= false;
652 ret
= max77843_muic_chg_handler(info
);
654 dev_err(info
->dev
, "Unknown charger type\n");
655 info
->irq_chg
= false;
658 mutex_unlock(&info
->mutex
);
661 static irqreturn_t
max77843_muic_irq_handler(int irq
, void *data
)
663 struct max77843_muic_info
*info
= data
;
664 int i
, irq_type
= -1;
666 for (i
= 0; i
< ARRAY_SIZE(max77843_muic_irqs
); i
++)
667 if (irq
== max77843_muic_irqs
[i
].virq
)
668 irq_type
= max77843_muic_irqs
[i
].irq
;
671 case MAX77843_MUIC_IRQ_INT1_ADC
:
672 case MAX77843_MUIC_IRQ_INT1_ADCERROR
:
673 case MAX77843_MUIC_IRQ_INT1_ADC1K
:
674 info
->irq_adc
= true;
676 case MAX77843_MUIC_IRQ_INT2_CHGTYP
:
677 case MAX77843_MUIC_IRQ_INT2_CHGDETRUN
:
678 case MAX77843_MUIC_IRQ_INT2_DCDTMR
:
679 case MAX77843_MUIC_IRQ_INT2_DXOVP
:
680 case MAX77843_MUIC_IRQ_INT2_VBVOLT
:
681 info
->irq_chg
= true;
683 case MAX77843_MUIC_IRQ_INT3_VBADC
:
684 case MAX77843_MUIC_IRQ_INT3_VDNMON
:
685 case MAX77843_MUIC_IRQ_INT3_DNRES
:
686 case MAX77843_MUIC_IRQ_INT3_MPNACK
:
687 case MAX77843_MUIC_IRQ_INT3_MRXBUFOW
:
688 case MAX77843_MUIC_IRQ_INT3_MRXTRF
:
689 case MAX77843_MUIC_IRQ_INT3_MRXPERR
:
690 case MAX77843_MUIC_IRQ_INT3_MRXRDY
:
693 dev_err(info
->dev
, "Cannot recognize IRQ(%d)\n", irq_type
);
697 schedule_work(&info
->irq_work
);
702 static void max77843_muic_detect_cable_wq(struct work_struct
*work
)
704 struct max77843_muic_info
*info
= container_of(to_delayed_work(work
),
705 struct max77843_muic_info
, wq_detcable
);
706 struct max77693_dev
*max77843
= info
->max77843
;
707 int chg_type
, adc
, ret
;
710 mutex_lock(&info
->mutex
);
712 ret
= regmap_bulk_read(max77843
->regmap_muic
,
713 MAX77843_MUIC_REG_STATUS1
, info
->status
,
714 MAX77843_MUIC_STATUS_NUM
);
716 dev_err(info
->dev
, "Cannot read STATUS registers\n");
720 adc
= max77843_muic_get_cable_type(info
,
721 MAX77843_CABLE_GROUP_ADC
, &attached
);
722 if (attached
&& adc
!= MAX77843_MUIC_ADC_OPEN
) {
723 ret
= max77843_muic_adc_handler(info
);
725 dev_err(info
->dev
, "Cannot detect accessory\n");
730 chg_type
= max77843_muic_get_cable_type(info
,
731 MAX77843_CABLE_GROUP_CHG
, &attached
);
732 if (attached
&& chg_type
!= MAX77843_MUIC_CHG_NONE
) {
733 ret
= max77843_muic_chg_handler(info
);
735 dev_err(info
->dev
, "Cannot detect charger accessory\n");
741 mutex_unlock(&info
->mutex
);
744 static int max77843_muic_set_debounce_time(struct max77843_muic_info
*info
,
745 enum max77843_muic_adc_debounce_time time
)
747 struct max77693_dev
*max77843
= info
->max77843
;
751 case MAX77843_DEBOUNCE_TIME_5MS
:
752 case MAX77843_DEBOUNCE_TIME_10MS
:
753 case MAX77843_DEBOUNCE_TIME_25MS
:
754 case MAX77843_DEBOUNCE_TIME_38_62MS
:
755 ret
= regmap_update_bits(max77843
->regmap_muic
,
756 MAX77843_MUIC_REG_CONTROL4
,
757 MAX77843_MUIC_CONTROL4_ADCDBSET_MASK
,
758 time
<< MAX77843_MUIC_CONTROL4_ADCDBSET_SHIFT
);
760 dev_err(info
->dev
, "Cannot write MUIC regmap\n");
765 dev_err(info
->dev
, "Invalid ADC debounce time\n");
772 static int max77843_init_muic_regmap(struct max77693_dev
*max77843
)
776 max77843
->i2c_muic
= i2c_new_dummy_device(max77843
->i2c
->adapter
,
778 if (IS_ERR(max77843
->i2c_muic
)) {
779 dev_err(&max77843
->i2c
->dev
,
780 "Cannot allocate I2C device for MUIC\n");
781 return PTR_ERR(max77843
->i2c_muic
);
784 i2c_set_clientdata(max77843
->i2c_muic
, max77843
);
786 max77843
->regmap_muic
= devm_regmap_init_i2c(max77843
->i2c_muic
,
787 &max77843_muic_regmap_config
);
788 if (IS_ERR(max77843
->regmap_muic
)) {
789 ret
= PTR_ERR(max77843
->regmap_muic
);
793 ret
= regmap_add_irq_chip(max77843
->regmap_muic
, max77843
->irq
,
794 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
| IRQF_SHARED
,
795 0, &max77843_muic_irq_chip
, &max77843
->irq_data_muic
);
797 dev_err(&max77843
->i2c
->dev
, "Cannot add MUIC IRQ chip\n");
804 i2c_unregister_device(max77843
->i2c_muic
);
809 static int max77843_muic_probe(struct platform_device
*pdev
)
811 struct max77693_dev
*max77843
= dev_get_drvdata(pdev
->dev
.parent
);
812 struct max77843_muic_info
*info
;
818 info
= devm_kzalloc(&pdev
->dev
, sizeof(*info
), GFP_KERNEL
);
822 info
->dev
= &pdev
->dev
;
823 info
->max77843
= max77843
;
825 platform_set_drvdata(pdev
, info
);
826 mutex_init(&info
->mutex
);
828 /* Initialize i2c and regmap */
829 ret
= max77843_init_muic_regmap(max77843
);
831 dev_err(&pdev
->dev
, "Failed to init MUIC regmap\n");
835 /* Turn off auto detection configuration */
836 ret
= regmap_update_bits(max77843
->regmap_muic
,
837 MAX77843_MUIC_REG_CONTROL4
,
838 MAX77843_MUIC_CONTROL4_USBAUTO_MASK
|
839 MAX77843_MUIC_CONTROL4_FCTAUTO_MASK
,
840 CONTROL4_AUTO_DISABLE
);
842 /* Initialize extcon device */
843 info
->edev
= devm_extcon_dev_allocate(&pdev
->dev
,
844 max77843_extcon_cable
);
845 if (IS_ERR(info
->edev
)) {
846 dev_err(&pdev
->dev
, "Failed to allocate memory for extcon\n");
847 ret
= PTR_ERR(info
->edev
);
851 ret
= devm_extcon_dev_register(&pdev
->dev
, info
->edev
);
853 dev_err(&pdev
->dev
, "Failed to register extcon device\n");
857 /* Set ADC debounce time */
858 max77843_muic_set_debounce_time(info
, MAX77843_DEBOUNCE_TIME_25MS
);
860 /* Set initial path for UART when JIG is connected to get serial logs */
861 ret
= regmap_bulk_read(max77843
->regmap_muic
,
862 MAX77843_MUIC_REG_STATUS1
, info
->status
,
863 MAX77843_MUIC_STATUS_NUM
);
865 dev_err(info
->dev
, "Cannot read STATUS registers\n");
868 cable_type
= max77843_muic_get_cable_type(info
, MAX77843_CABLE_GROUP_ADC
,
870 if (attached
&& cable_type
== MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF
)
871 max77843_muic_set_path(info
, MAX77843_MUIC_CONTROL1_SW_UART
,
874 /* Check revision number of MUIC device */
875 ret
= regmap_read(max77843
->regmap_muic
, MAX77843_MUIC_REG_ID
, &id
);
877 dev_err(&pdev
->dev
, "Failed to read revision number\n");
880 dev_info(info
->dev
, "MUIC device ID : 0x%x\n", id
);
882 /* Support virtual irq domain for max77843 MUIC device */
883 INIT_WORK(&info
->irq_work
, max77843_muic_irq_work
);
885 /* Clear IRQ bits before request IRQs */
886 ret
= regmap_bulk_read(max77843
->regmap_muic
,
887 MAX77843_MUIC_REG_INT1
, info
->status
,
888 MAX77843_MUIC_STATUS_NUM
);
890 dev_err(&pdev
->dev
, "Failed to Clear IRQ bits\n");
894 for (i
= 0; i
< ARRAY_SIZE(max77843_muic_irqs
); i
++) {
895 struct max77843_muic_irq
*muic_irq
= &max77843_muic_irqs
[i
];
898 virq
= regmap_irq_get_virq(max77843
->irq_data_muic
,
904 muic_irq
->virq
= virq
;
906 ret
= devm_request_threaded_irq(&pdev
->dev
, virq
, NULL
,
907 max77843_muic_irq_handler
, IRQF_NO_SUSPEND
,
908 muic_irq
->name
, info
);
911 "Failed to request irq (IRQ: %d, error: %d)\n",
917 /* Detect accessory after completing the initialization of platform */
918 INIT_DELAYED_WORK(&info
->wq_detcable
, max77843_muic_detect_cable_wq
);
919 queue_delayed_work(system_power_efficient_wq
,
920 &info
->wq_detcable
, msecs_to_jiffies(DELAY_MS_DEFAULT
));
925 regmap_del_irq_chip(max77843
->irq
, max77843
->irq_data_muic
);
926 i2c_unregister_device(max77843
->i2c_muic
);
931 static void max77843_muic_remove(struct platform_device
*pdev
)
933 struct max77843_muic_info
*info
= platform_get_drvdata(pdev
);
934 struct max77693_dev
*max77843
= info
->max77843
;
936 cancel_work_sync(&info
->irq_work
);
937 regmap_del_irq_chip(max77843
->irq
, max77843
->irq_data_muic
);
938 i2c_unregister_device(max77843
->i2c_muic
);
941 static const struct platform_device_id max77843_muic_id
[] = {
942 { "max77843-muic", },
945 MODULE_DEVICE_TABLE(platform
, max77843_muic_id
);
947 static const struct of_device_id of_max77843_muic_dt_match
[] = {
948 { .compatible
= "maxim,max77843-muic", },
951 MODULE_DEVICE_TABLE(of
, of_max77843_muic_dt_match
);
953 static struct platform_driver max77843_muic_driver
= {
955 .name
= "max77843-muic",
956 .of_match_table
= of_max77843_muic_dt_match
,
958 .probe
= max77843_muic_probe
,
959 .remove_new
= max77843_muic_remove
,
960 .id_table
= max77843_muic_id
,
963 static int __init
max77843_muic_init(void)
965 return platform_driver_register(&max77843_muic_driver
);
967 subsys_initcall(max77843_muic_init
);
969 MODULE_DESCRIPTION("Maxim MAX77843 Extcon driver");
970 MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
971 MODULE_LICENSE("GPL");