xref: /OK3568_Linux_fs/kernel/drivers/extcon/extcon-max77843.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // extcon-max77843.c - Maxim MAX77843 extcon driver to support
4*4882a593Smuzhiyun //			MUIC(Micro USB Interface Controller)
5*4882a593Smuzhiyun //
6*4882a593Smuzhiyun // Copyright (C) 2015 Samsung Electronics
7*4882a593Smuzhiyun // Author: Jaewon Kim <jaewon02.kim@samsung.com>
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/extcon-provider.h>
10*4882a593Smuzhiyun #include <linux/i2c.h>
11*4882a593Smuzhiyun #include <linux/interrupt.h>
12*4882a593Smuzhiyun #include <linux/kernel.h>
13*4882a593Smuzhiyun #include <linux/mfd/max77693-common.h>
14*4882a593Smuzhiyun #include <linux/mfd/max77843-private.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/platform_device.h>
17*4882a593Smuzhiyun #include <linux/workqueue.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define DELAY_MS_DEFAULT		15000	/* unit: millisecond */
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun enum max77843_muic_status {
22*4882a593Smuzhiyun 	MAX77843_MUIC_STATUS1 = 0,
23*4882a593Smuzhiyun 	MAX77843_MUIC_STATUS2,
24*4882a593Smuzhiyun 	MAX77843_MUIC_STATUS3,
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun 	MAX77843_MUIC_STATUS_NUM,
27*4882a593Smuzhiyun };
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun struct max77843_muic_info {
30*4882a593Smuzhiyun 	struct device *dev;
31*4882a593Smuzhiyun 	struct max77693_dev *max77843;
32*4882a593Smuzhiyun 	struct extcon_dev *edev;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	struct mutex mutex;
35*4882a593Smuzhiyun 	struct work_struct irq_work;
36*4882a593Smuzhiyun 	struct delayed_work wq_detcable;
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	u8 status[MAX77843_MUIC_STATUS_NUM];
39*4882a593Smuzhiyun 	int prev_cable_type;
40*4882a593Smuzhiyun 	int prev_chg_type;
41*4882a593Smuzhiyun 	int prev_gnd_type;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	bool irq_adc;
44*4882a593Smuzhiyun 	bool irq_chg;
45*4882a593Smuzhiyun };
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun enum max77843_muic_cable_group {
48*4882a593Smuzhiyun 	MAX77843_CABLE_GROUP_ADC = 0,
49*4882a593Smuzhiyun 	MAX77843_CABLE_GROUP_ADC_GND,
50*4882a593Smuzhiyun 	MAX77843_CABLE_GROUP_CHG,
51*4882a593Smuzhiyun };
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun enum max77843_muic_adc_debounce_time {
54*4882a593Smuzhiyun 	MAX77843_DEBOUNCE_TIME_5MS = 0,
55*4882a593Smuzhiyun 	MAX77843_DEBOUNCE_TIME_10MS,
56*4882a593Smuzhiyun 	MAX77843_DEBOUNCE_TIME_25MS,
57*4882a593Smuzhiyun 	MAX77843_DEBOUNCE_TIME_38_62MS,
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /* Define accessory cable type */
61*4882a593Smuzhiyun enum max77843_muic_accessory_type {
62*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_GROUND = 0,
63*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_SEND_END_BUTTON,
64*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S1_BUTTON,
65*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S2_BUTTON,
66*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S3_BUTTON,
67*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S4_BUTTON,
68*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S5_BUTTON,
69*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S6_BUTTON,
70*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S7_BUTTON,
71*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S8_BUTTON,
72*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S9_BUTTON,
73*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S10_BUTTON,
74*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S11_BUTTON,
75*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_REMOTE_S12_BUTTON,
76*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_RESERVED_ACC_1,
77*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_RESERVED_ACC_2,
78*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_RESERVED_ACC_3, /* SmartDock */
79*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_RESERVED_ACC_4,
80*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_RESERVED_ACC_5,
81*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2,
82*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_PHONE_POWERED_DEV,
83*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_TTY_CONVERTER,
84*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_UART_CABLE,
85*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_CEA936A_TYPE1_CHG,
86*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF,
87*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON,
88*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_AV_CABLE_NOLOAD,
89*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_CEA936A_TYPE2_CHG,
90*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF,
91*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_FACTORY_MODE_UART_ON,
92*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE1,
93*4882a593Smuzhiyun 	MAX77843_MUIC_ADC_OPEN,
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	/*
96*4882a593Smuzhiyun 	 * The below accessories should check
97*4882a593Smuzhiyun 	 * not only ADC value but also ADC1K and VBVolt value.
98*4882a593Smuzhiyun 	 */
99*4882a593Smuzhiyun 						/* Offset|ADC1K|VBVolt| */
100*4882a593Smuzhiyun 	MAX77843_MUIC_GND_USB_HOST = 0x100,	/*    0x1|    0|     0| */
101*4882a593Smuzhiyun 	MAX77843_MUIC_GND_USB_HOST_VB = 0x101,	/*    0x1|    0|     1| */
102*4882a593Smuzhiyun 	MAX77843_MUIC_GND_MHL = 0x102,		/*    0x1|    1|     0| */
103*4882a593Smuzhiyun 	MAX77843_MUIC_GND_MHL_VB = 0x103,	/*    0x1|    1|     1| */
104*4882a593Smuzhiyun };
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun /* Define charger cable type */
107*4882a593Smuzhiyun enum max77843_muic_charger_type {
108*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_NONE = 0,
109*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_USB,
110*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_DOWNSTREAM,
111*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_DEDICATED,
112*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_SPECIAL_500MA,
113*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_SPECIAL_1A,
114*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_SPECIAL_BIAS,
115*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_RESERVED,
116*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_GND,
117*4882a593Smuzhiyun 	MAX77843_MUIC_CHG_DOCK,
118*4882a593Smuzhiyun };
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun static const unsigned int max77843_extcon_cable[] = {
121*4882a593Smuzhiyun 	EXTCON_USB,
122*4882a593Smuzhiyun 	EXTCON_USB_HOST,
123*4882a593Smuzhiyun 	EXTCON_CHG_USB_SDP,
124*4882a593Smuzhiyun 	EXTCON_CHG_USB_DCP,
125*4882a593Smuzhiyun 	EXTCON_CHG_USB_CDP,
126*4882a593Smuzhiyun 	EXTCON_CHG_USB_FAST,
127*4882a593Smuzhiyun 	EXTCON_CHG_USB_SLOW,
128*4882a593Smuzhiyun 	EXTCON_DISP_MHL,
129*4882a593Smuzhiyun 	EXTCON_DOCK,
130*4882a593Smuzhiyun 	EXTCON_JIG,
131*4882a593Smuzhiyun 	EXTCON_NONE,
132*4882a593Smuzhiyun };
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun struct max77843_muic_irq {
135*4882a593Smuzhiyun 	unsigned int irq;
136*4882a593Smuzhiyun 	const char *name;
137*4882a593Smuzhiyun 	unsigned int virq;
138*4882a593Smuzhiyun };
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun static struct max77843_muic_irq max77843_muic_irqs[] = {
141*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT1_ADC,		"MUIC-ADC" },
142*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT1_ADCERROR,	"MUIC-ADC_ERROR" },
143*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT1_ADC1K,		"MUIC-ADC1K" },
144*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT2_CHGTYP,	"MUIC-CHGTYP" },
145*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT2_CHGDETRUN,	"MUIC-CHGDETRUN" },
146*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT2_DCDTMR,	"MUIC-DCDTMR" },
147*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT2_DXOVP,		"MUIC-DXOVP" },
148*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT2_VBVOLT,	"MUIC-VBVOLT" },
149*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT3_VBADC,		"MUIC-VBADC" },
150*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT3_VDNMON,	"MUIC-VDNMON" },
151*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT3_DNRES,		"MUIC-DNRES" },
152*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT3_MPNACK,	"MUIC-MPNACK"},
153*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT3_MRXBUFOW,	"MUIC-MRXBUFOW"},
154*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT3_MRXTRF,	"MUIC-MRXTRF"},
155*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT3_MRXPERR,	"MUIC-MRXPERR"},
156*4882a593Smuzhiyun 	{ MAX77843_MUIC_IRQ_INT3_MRXRDY,	"MUIC-MRXRDY"},
157*4882a593Smuzhiyun };
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun static const struct regmap_config max77843_muic_regmap_config = {
160*4882a593Smuzhiyun 	.reg_bits       = 8,
161*4882a593Smuzhiyun 	.val_bits       = 8,
162*4882a593Smuzhiyun 	.max_register   = MAX77843_MUIC_REG_END,
163*4882a593Smuzhiyun };
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun static const struct regmap_irq max77843_muic_irq[] = {
166*4882a593Smuzhiyun 	/* INT1 interrupt */
167*4882a593Smuzhiyun 	{ .reg_offset = 0, .mask = MAX77843_MUIC_ADC, },
168*4882a593Smuzhiyun 	{ .reg_offset = 0, .mask = MAX77843_MUIC_ADCERROR, },
169*4882a593Smuzhiyun 	{ .reg_offset = 0, .mask = MAX77843_MUIC_ADC1K, },
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	/* INT2 interrupt */
172*4882a593Smuzhiyun 	{ .reg_offset = 1, .mask = MAX77843_MUIC_CHGTYP, },
173*4882a593Smuzhiyun 	{ .reg_offset = 1, .mask = MAX77843_MUIC_CHGDETRUN, },
174*4882a593Smuzhiyun 	{ .reg_offset = 1, .mask = MAX77843_MUIC_DCDTMR, },
175*4882a593Smuzhiyun 	{ .reg_offset = 1, .mask = MAX77843_MUIC_DXOVP, },
176*4882a593Smuzhiyun 	{ .reg_offset = 1, .mask = MAX77843_MUIC_VBVOLT, },
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	/* INT3 interrupt */
179*4882a593Smuzhiyun 	{ .reg_offset = 2, .mask = MAX77843_MUIC_VBADC, },
180*4882a593Smuzhiyun 	{ .reg_offset = 2, .mask = MAX77843_MUIC_VDNMON, },
181*4882a593Smuzhiyun 	{ .reg_offset = 2, .mask = MAX77843_MUIC_DNRES, },
182*4882a593Smuzhiyun 	{ .reg_offset = 2, .mask = MAX77843_MUIC_MPNACK, },
183*4882a593Smuzhiyun 	{ .reg_offset = 2, .mask = MAX77843_MUIC_MRXBUFOW, },
184*4882a593Smuzhiyun 	{ .reg_offset = 2, .mask = MAX77843_MUIC_MRXTRF, },
185*4882a593Smuzhiyun 	{ .reg_offset = 2, .mask = MAX77843_MUIC_MRXPERR, },
186*4882a593Smuzhiyun 	{ .reg_offset = 2, .mask = MAX77843_MUIC_MRXRDY, },
187*4882a593Smuzhiyun };
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun static const struct regmap_irq_chip max77843_muic_irq_chip = {
190*4882a593Smuzhiyun 	.name           = "max77843-muic",
191*4882a593Smuzhiyun 	.status_base    = MAX77843_MUIC_REG_INT1,
192*4882a593Smuzhiyun 	.mask_base      = MAX77843_MUIC_REG_INTMASK1,
193*4882a593Smuzhiyun 	.mask_invert    = true,
194*4882a593Smuzhiyun 	.num_regs       = 3,
195*4882a593Smuzhiyun 	.irqs           = max77843_muic_irq,
196*4882a593Smuzhiyun 	.num_irqs       = ARRAY_SIZE(max77843_muic_irq),
197*4882a593Smuzhiyun };
198*4882a593Smuzhiyun 
max77843_muic_set_path(struct max77843_muic_info * info,u8 val,bool attached,bool nobccomp)199*4882a593Smuzhiyun static int max77843_muic_set_path(struct max77843_muic_info *info,
200*4882a593Smuzhiyun 		u8 val, bool attached, bool nobccomp)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	struct max77693_dev *max77843 = info->max77843;
203*4882a593Smuzhiyun 	int ret = 0;
204*4882a593Smuzhiyun 	unsigned int ctrl1, ctrl2;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	if (attached)
207*4882a593Smuzhiyun 		ctrl1 = val;
208*4882a593Smuzhiyun 	else
209*4882a593Smuzhiyun 		ctrl1 = MAX77843_MUIC_CONTROL1_SW_OPEN;
210*4882a593Smuzhiyun 	if (nobccomp) {
211*4882a593Smuzhiyun 		/* Disable BC1.2 protocol and force manual switch control */
212*4882a593Smuzhiyun 		ctrl1 |= MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK;
213*4882a593Smuzhiyun 	}
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	ret = regmap_update_bits(max77843->regmap_muic,
216*4882a593Smuzhiyun 			MAX77843_MUIC_REG_CONTROL1,
217*4882a593Smuzhiyun 			MAX77843_MUIC_CONTROL1_COM_SW |
218*4882a593Smuzhiyun 				MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK,
219*4882a593Smuzhiyun 			ctrl1);
220*4882a593Smuzhiyun 	if (ret < 0) {
221*4882a593Smuzhiyun 		dev_err(info->dev, "Cannot switch MUIC port\n");
222*4882a593Smuzhiyun 		return ret;
223*4882a593Smuzhiyun 	}
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	if (attached)
226*4882a593Smuzhiyun 		ctrl2 = MAX77843_MUIC_CONTROL2_CPEN_MASK;
227*4882a593Smuzhiyun 	else
228*4882a593Smuzhiyun 		ctrl2 = MAX77843_MUIC_CONTROL2_LOWPWR_MASK;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	ret = regmap_update_bits(max77843->regmap_muic,
231*4882a593Smuzhiyun 			MAX77843_MUIC_REG_CONTROL2,
232*4882a593Smuzhiyun 			MAX77843_MUIC_CONTROL2_LOWPWR_MASK |
233*4882a593Smuzhiyun 			MAX77843_MUIC_CONTROL2_CPEN_MASK, ctrl2);
234*4882a593Smuzhiyun 	if (ret < 0) {
235*4882a593Smuzhiyun 		dev_err(info->dev, "Cannot update lowpower mode\n");
236*4882a593Smuzhiyun 		return ret;
237*4882a593Smuzhiyun 	}
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	dev_dbg(info->dev,
240*4882a593Smuzhiyun 		"CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
241*4882a593Smuzhiyun 		ctrl1, ctrl2, attached ? "attached" : "detached");
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	return 0;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun 
max77843_charger_set_otg_vbus(struct max77843_muic_info * info,bool on)246*4882a593Smuzhiyun static void max77843_charger_set_otg_vbus(struct max77843_muic_info *info,
247*4882a593Smuzhiyun 		 bool on)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun 	struct max77693_dev *max77843 = info->max77843;
250*4882a593Smuzhiyun 	unsigned int cnfg00;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	if (on)
253*4882a593Smuzhiyun 		cnfg00 = MAX77843_CHG_OTG_MASK | MAX77843_CHG_BOOST_MASK;
254*4882a593Smuzhiyun 	else
255*4882a593Smuzhiyun 		cnfg00 = MAX77843_CHG_ENABLE | MAX77843_CHG_BUCK_MASK;
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	regmap_update_bits(max77843->regmap_chg, MAX77843_CHG_REG_CHG_CNFG_00,
258*4882a593Smuzhiyun 			   MAX77843_CHG_MODE_MASK, cnfg00);
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun 
max77843_muic_get_cable_type(struct max77843_muic_info * info,enum max77843_muic_cable_group group,bool * attached)261*4882a593Smuzhiyun static int max77843_muic_get_cable_type(struct max77843_muic_info *info,
262*4882a593Smuzhiyun 		enum max77843_muic_cable_group group, bool *attached)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun 	int adc, chg_type, cable_type, gnd_type;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	adc = info->status[MAX77843_MUIC_STATUS1] &
267*4882a593Smuzhiyun 			MAX77843_MUIC_STATUS1_ADC_MASK;
268*4882a593Smuzhiyun 	adc >>= MAX77843_MUIC_STATUS1_ADC_SHIFT;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	switch (group) {
271*4882a593Smuzhiyun 	case MAX77843_CABLE_GROUP_ADC:
272*4882a593Smuzhiyun 		if (adc == MAX77843_MUIC_ADC_OPEN) {
273*4882a593Smuzhiyun 			*attached = false;
274*4882a593Smuzhiyun 			cable_type = info->prev_cable_type;
275*4882a593Smuzhiyun 			info->prev_cable_type = MAX77843_MUIC_ADC_OPEN;
276*4882a593Smuzhiyun 		} else {
277*4882a593Smuzhiyun 			*attached = true;
278*4882a593Smuzhiyun 			cable_type = info->prev_cable_type = adc;
279*4882a593Smuzhiyun 		}
280*4882a593Smuzhiyun 		break;
281*4882a593Smuzhiyun 	case MAX77843_CABLE_GROUP_CHG:
282*4882a593Smuzhiyun 		chg_type = info->status[MAX77843_MUIC_STATUS2] &
283*4882a593Smuzhiyun 				MAX77843_MUIC_STATUS2_CHGTYP_MASK;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 		/* Check GROUND accessory with charger cable */
286*4882a593Smuzhiyun 		if (adc == MAX77843_MUIC_ADC_GROUND) {
287*4882a593Smuzhiyun 			if (chg_type == MAX77843_MUIC_CHG_NONE) {
288*4882a593Smuzhiyun 				/*
289*4882a593Smuzhiyun 				 * The following state when charger cable is
290*4882a593Smuzhiyun 				 * disconnected but the GROUND accessory still
291*4882a593Smuzhiyun 				 * connected.
292*4882a593Smuzhiyun 				 */
293*4882a593Smuzhiyun 				*attached = false;
294*4882a593Smuzhiyun 				cable_type = info->prev_chg_type;
295*4882a593Smuzhiyun 				info->prev_chg_type = MAX77843_MUIC_CHG_NONE;
296*4882a593Smuzhiyun 			} else {
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 				/*
299*4882a593Smuzhiyun 				 * The following state when charger cable is
300*4882a593Smuzhiyun 				 * connected on the GROUND accessory.
301*4882a593Smuzhiyun 				 */
302*4882a593Smuzhiyun 				*attached = true;
303*4882a593Smuzhiyun 				cable_type = MAX77843_MUIC_CHG_GND;
304*4882a593Smuzhiyun 				info->prev_chg_type = MAX77843_MUIC_CHG_GND;
305*4882a593Smuzhiyun 			}
306*4882a593Smuzhiyun 			break;
307*4882a593Smuzhiyun 		}
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 		if (adc == MAX77843_MUIC_ADC_RESERVED_ACC_3) { /* SmartDock */
310*4882a593Smuzhiyun 			if (chg_type == MAX77843_MUIC_CHG_NONE) {
311*4882a593Smuzhiyun 				*attached = false;
312*4882a593Smuzhiyun 				cable_type = info->prev_chg_type;
313*4882a593Smuzhiyun 				info->prev_chg_type = MAX77843_MUIC_CHG_NONE;
314*4882a593Smuzhiyun 			} else {
315*4882a593Smuzhiyun 				*attached = true;
316*4882a593Smuzhiyun 				cable_type = MAX77843_MUIC_CHG_DOCK;
317*4882a593Smuzhiyun 				info->prev_chg_type = MAX77843_MUIC_CHG_DOCK;
318*4882a593Smuzhiyun 			}
319*4882a593Smuzhiyun 			break;
320*4882a593Smuzhiyun 		}
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 		if (chg_type == MAX77843_MUIC_CHG_NONE) {
323*4882a593Smuzhiyun 			*attached = false;
324*4882a593Smuzhiyun 			cable_type = info->prev_chg_type;
325*4882a593Smuzhiyun 			info->prev_chg_type = MAX77843_MUIC_CHG_NONE;
326*4882a593Smuzhiyun 		} else {
327*4882a593Smuzhiyun 			*attached = true;
328*4882a593Smuzhiyun 			cable_type = info->prev_chg_type = chg_type;
329*4882a593Smuzhiyun 		}
330*4882a593Smuzhiyun 		break;
331*4882a593Smuzhiyun 	case MAX77843_CABLE_GROUP_ADC_GND:
332*4882a593Smuzhiyun 		if (adc == MAX77843_MUIC_ADC_OPEN) {
333*4882a593Smuzhiyun 			*attached = false;
334*4882a593Smuzhiyun 			cable_type = info->prev_gnd_type;
335*4882a593Smuzhiyun 			info->prev_gnd_type = MAX77843_MUIC_ADC_OPEN;
336*4882a593Smuzhiyun 		} else {
337*4882a593Smuzhiyun 			*attached = true;
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 			/*
340*4882a593Smuzhiyun 			 * Offset|ADC1K|VBVolt|
341*4882a593Smuzhiyun 			 *    0x1|    0|     0| USB-HOST
342*4882a593Smuzhiyun 			 *    0x1|    0|     1| USB-HOST with VB
343*4882a593Smuzhiyun 			 *    0x1|    1|     0| MHL
344*4882a593Smuzhiyun 			 *    0x1|    1|     1| MHL with VB
345*4882a593Smuzhiyun 			 */
346*4882a593Smuzhiyun 			/* Get ADC1K register bit */
347*4882a593Smuzhiyun 			gnd_type = (info->status[MAX77843_MUIC_STATUS1] &
348*4882a593Smuzhiyun 					MAX77843_MUIC_STATUS1_ADC1K_MASK);
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 			/* Get VBVolt register bit */
351*4882a593Smuzhiyun 			gnd_type |= (info->status[MAX77843_MUIC_STATUS2] &
352*4882a593Smuzhiyun 					MAX77843_MUIC_STATUS2_VBVOLT_MASK);
353*4882a593Smuzhiyun 			gnd_type >>= MAX77843_MUIC_STATUS2_VBVOLT_SHIFT;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 			/* Offset of GND cable */
356*4882a593Smuzhiyun 			gnd_type |= MAX77843_MUIC_GND_USB_HOST;
357*4882a593Smuzhiyun 			cable_type = info->prev_gnd_type = gnd_type;
358*4882a593Smuzhiyun 		}
359*4882a593Smuzhiyun 		break;
360*4882a593Smuzhiyun 	default:
361*4882a593Smuzhiyun 		dev_err(info->dev, "Unknown cable group (%d)\n", group);
362*4882a593Smuzhiyun 		cable_type = -EINVAL;
363*4882a593Smuzhiyun 		break;
364*4882a593Smuzhiyun 	}
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	return cable_type;
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun 
max77843_muic_adc_gnd_handler(struct max77843_muic_info * info)369*4882a593Smuzhiyun static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info)
370*4882a593Smuzhiyun {
371*4882a593Smuzhiyun 	int ret, gnd_cable_type;
372*4882a593Smuzhiyun 	bool attached;
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	gnd_cable_type = max77843_muic_get_cable_type(info,
375*4882a593Smuzhiyun 			MAX77843_CABLE_GROUP_ADC_GND, &attached);
376*4882a593Smuzhiyun 	dev_dbg(info->dev, "external connector is %s (gnd:0x%02x)\n",
377*4882a593Smuzhiyun 			attached ? "attached" : "detached", gnd_cable_type);
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	switch (gnd_cable_type) {
380*4882a593Smuzhiyun 	case MAX77843_MUIC_GND_USB_HOST:
381*4882a593Smuzhiyun 	case MAX77843_MUIC_GND_USB_HOST_VB:
382*4882a593Smuzhiyun 		ret = max77843_muic_set_path(info,
383*4882a593Smuzhiyun 					     MAX77843_MUIC_CONTROL1_SW_USB,
384*4882a593Smuzhiyun 					     attached, false);
385*4882a593Smuzhiyun 		if (ret < 0)
386*4882a593Smuzhiyun 			return ret;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 		extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached);
389*4882a593Smuzhiyun 		max77843_charger_set_otg_vbus(info, attached);
390*4882a593Smuzhiyun 		break;
391*4882a593Smuzhiyun 	case MAX77843_MUIC_GND_MHL_VB:
392*4882a593Smuzhiyun 	case MAX77843_MUIC_GND_MHL:
393*4882a593Smuzhiyun 		ret = max77843_muic_set_path(info,
394*4882a593Smuzhiyun 					     MAX77843_MUIC_CONTROL1_SW_OPEN,
395*4882a593Smuzhiyun 					     attached, false);
396*4882a593Smuzhiyun 		if (ret < 0)
397*4882a593Smuzhiyun 			return ret;
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 		extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached);
400*4882a593Smuzhiyun 		break;
401*4882a593Smuzhiyun 	default:
402*4882a593Smuzhiyun 		dev_err(info->dev, "failed to detect %s accessory(gnd:0x%x)\n",
403*4882a593Smuzhiyun 			attached ? "attached" : "detached", gnd_cable_type);
404*4882a593Smuzhiyun 		return -EINVAL;
405*4882a593Smuzhiyun 	}
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	return 0;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun 
max77843_muic_jig_handler(struct max77843_muic_info * info,int cable_type,bool attached)410*4882a593Smuzhiyun static int max77843_muic_jig_handler(struct max77843_muic_info *info,
411*4882a593Smuzhiyun 		int cable_type, bool attached)
412*4882a593Smuzhiyun {
413*4882a593Smuzhiyun 	int ret;
414*4882a593Smuzhiyun 	u8 path = MAX77843_MUIC_CONTROL1_SW_OPEN;
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	dev_dbg(info->dev, "external connector is %s (adc:0x%02x)\n",
417*4882a593Smuzhiyun 			attached ? "attached" : "detached", cable_type);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	switch (cable_type) {
420*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF:
421*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON:
422*4882a593Smuzhiyun 		path = MAX77843_MUIC_CONTROL1_SW_USB;
423*4882a593Smuzhiyun 		break;
424*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF:
425*4882a593Smuzhiyun 		path = MAX77843_MUIC_CONTROL1_SW_UART;
426*4882a593Smuzhiyun 		break;
427*4882a593Smuzhiyun 	default:
428*4882a593Smuzhiyun 		return -EINVAL;
429*4882a593Smuzhiyun 	}
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	ret = max77843_muic_set_path(info, path, attached, false);
432*4882a593Smuzhiyun 	if (ret < 0)
433*4882a593Smuzhiyun 		return ret;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	extcon_set_state_sync(info->edev, EXTCON_JIG, attached);
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	return 0;
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun 
max77843_muic_dock_handler(struct max77843_muic_info * info,bool attached)440*4882a593Smuzhiyun static int max77843_muic_dock_handler(struct max77843_muic_info *info,
441*4882a593Smuzhiyun 		bool attached)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	int ret;
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	dev_dbg(info->dev, "external connector is %s (adc: 0x10)\n",
446*4882a593Smuzhiyun 			attached ? "attached" : "detached");
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	ret = max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_USB,
449*4882a593Smuzhiyun 				     attached, attached);
450*4882a593Smuzhiyun 	if (ret < 0)
451*4882a593Smuzhiyun 		return ret;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached);
454*4882a593Smuzhiyun 	extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached);
455*4882a593Smuzhiyun 	extcon_set_state_sync(info->edev, EXTCON_DOCK, attached);
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	return 0;
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun 
max77843_muic_adc_handler(struct max77843_muic_info * info)460*4882a593Smuzhiyun static int max77843_muic_adc_handler(struct max77843_muic_info *info)
461*4882a593Smuzhiyun {
462*4882a593Smuzhiyun 	int ret, cable_type;
463*4882a593Smuzhiyun 	bool attached;
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	cable_type = max77843_muic_get_cable_type(info,
466*4882a593Smuzhiyun 			MAX77843_CABLE_GROUP_ADC, &attached);
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	dev_dbg(info->dev,
469*4882a593Smuzhiyun 		"external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
470*4882a593Smuzhiyun 		attached ? "attached" : "detached", cable_type,
471*4882a593Smuzhiyun 		info->prev_cable_type);
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	switch (cable_type) {
474*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_RESERVED_ACC_3: /* SmartDock */
475*4882a593Smuzhiyun 		ret = max77843_muic_dock_handler(info, attached);
476*4882a593Smuzhiyun 		if (ret < 0)
477*4882a593Smuzhiyun 			return ret;
478*4882a593Smuzhiyun 		break;
479*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_GROUND:
480*4882a593Smuzhiyun 		ret = max77843_muic_adc_gnd_handler(info);
481*4882a593Smuzhiyun 		if (ret < 0)
482*4882a593Smuzhiyun 			return ret;
483*4882a593Smuzhiyun 		break;
484*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF:
485*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON:
486*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF:
487*4882a593Smuzhiyun 		ret = max77843_muic_jig_handler(info, cable_type, attached);
488*4882a593Smuzhiyun 		if (ret < 0)
489*4882a593Smuzhiyun 			return ret;
490*4882a593Smuzhiyun 		break;
491*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_SEND_END_BUTTON:
492*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S1_BUTTON:
493*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S2_BUTTON:
494*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S3_BUTTON:
495*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S4_BUTTON:
496*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S5_BUTTON:
497*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S6_BUTTON:
498*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S7_BUTTON:
499*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S8_BUTTON:
500*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S9_BUTTON:
501*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S10_BUTTON:
502*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S11_BUTTON:
503*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_REMOTE_S12_BUTTON:
504*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_RESERVED_ACC_1:
505*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_RESERVED_ACC_2:
506*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_RESERVED_ACC_4:
507*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_RESERVED_ACC_5:
508*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2:
509*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_PHONE_POWERED_DEV:
510*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_TTY_CONVERTER:
511*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_UART_CABLE:
512*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_CEA936A_TYPE1_CHG:
513*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_AV_CABLE_NOLOAD:
514*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_CEA936A_TYPE2_CHG:
515*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_FACTORY_MODE_UART_ON:
516*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE1:
517*4882a593Smuzhiyun 	case MAX77843_MUIC_ADC_OPEN:
518*4882a593Smuzhiyun 		dev_err(info->dev,
519*4882a593Smuzhiyun 			"accessory is %s but it isn't used (adc:0x%x)\n",
520*4882a593Smuzhiyun 			attached ? "attached" : "detached", cable_type);
521*4882a593Smuzhiyun 		return -EAGAIN;
522*4882a593Smuzhiyun 	default:
523*4882a593Smuzhiyun 		dev_err(info->dev,
524*4882a593Smuzhiyun 			"failed to detect %s accessory (adc:0x%x)\n",
525*4882a593Smuzhiyun 			attached ? "attached" : "detached", cable_type);
526*4882a593Smuzhiyun 		return -EINVAL;
527*4882a593Smuzhiyun 	}
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	return 0;
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun 
max77843_muic_chg_handler(struct max77843_muic_info * info)532*4882a593Smuzhiyun static int max77843_muic_chg_handler(struct max77843_muic_info *info)
533*4882a593Smuzhiyun {
534*4882a593Smuzhiyun 	int ret, chg_type, gnd_type;
535*4882a593Smuzhiyun 	bool attached;
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	chg_type = max77843_muic_get_cable_type(info,
538*4882a593Smuzhiyun 			MAX77843_CABLE_GROUP_CHG, &attached);
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	dev_dbg(info->dev,
541*4882a593Smuzhiyun 		"external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
542*4882a593Smuzhiyun 		attached ? "attached" : "detached",
543*4882a593Smuzhiyun 		chg_type, info->prev_chg_type);
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 	switch (chg_type) {
546*4882a593Smuzhiyun 	case MAX77843_MUIC_CHG_USB:
547*4882a593Smuzhiyun 		ret = max77843_muic_set_path(info,
548*4882a593Smuzhiyun 					     MAX77843_MUIC_CONTROL1_SW_USB,
549*4882a593Smuzhiyun 					     attached, false);
550*4882a593Smuzhiyun 		if (ret < 0)
551*4882a593Smuzhiyun 			return ret;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 		extcon_set_state_sync(info->edev, EXTCON_USB, attached);
554*4882a593Smuzhiyun 		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
555*4882a593Smuzhiyun 					attached);
556*4882a593Smuzhiyun 		break;
557*4882a593Smuzhiyun 	case MAX77843_MUIC_CHG_DOWNSTREAM:
558*4882a593Smuzhiyun 		ret = max77843_muic_set_path(info,
559*4882a593Smuzhiyun 					     MAX77843_MUIC_CONTROL1_SW_OPEN,
560*4882a593Smuzhiyun 					     attached, false);
561*4882a593Smuzhiyun 		if (ret < 0)
562*4882a593Smuzhiyun 			return ret;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP,
565*4882a593Smuzhiyun 					attached);
566*4882a593Smuzhiyun 		break;
567*4882a593Smuzhiyun 	case MAX77843_MUIC_CHG_DEDICATED:
568*4882a593Smuzhiyun 		ret = max77843_muic_set_path(info,
569*4882a593Smuzhiyun 					     MAX77843_MUIC_CONTROL1_SW_OPEN,
570*4882a593Smuzhiyun 					     attached, false);
571*4882a593Smuzhiyun 		if (ret < 0)
572*4882a593Smuzhiyun 			return ret;
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,
575*4882a593Smuzhiyun 					attached);
576*4882a593Smuzhiyun 		break;
577*4882a593Smuzhiyun 	case MAX77843_MUIC_CHG_SPECIAL_500MA:
578*4882a593Smuzhiyun 		ret = max77843_muic_set_path(info,
579*4882a593Smuzhiyun 					     MAX77843_MUIC_CONTROL1_SW_OPEN,
580*4882a593Smuzhiyun 					     attached, false);
581*4882a593Smuzhiyun 		if (ret < 0)
582*4882a593Smuzhiyun 			return ret;
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW,
585*4882a593Smuzhiyun 					attached);
586*4882a593Smuzhiyun 		break;
587*4882a593Smuzhiyun 	case MAX77843_MUIC_CHG_SPECIAL_1A:
588*4882a593Smuzhiyun 		ret = max77843_muic_set_path(info,
589*4882a593Smuzhiyun 					     MAX77843_MUIC_CONTROL1_SW_OPEN,
590*4882a593Smuzhiyun 					     attached, false);
591*4882a593Smuzhiyun 		if (ret < 0)
592*4882a593Smuzhiyun 			return ret;
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST,
595*4882a593Smuzhiyun 					attached);
596*4882a593Smuzhiyun 		break;
597*4882a593Smuzhiyun 	case MAX77843_MUIC_CHG_GND:
598*4882a593Smuzhiyun 		gnd_type = max77843_muic_get_cable_type(info,
599*4882a593Smuzhiyun 				MAX77843_CABLE_GROUP_ADC_GND, &attached);
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 		/* Charger cable on MHL accessory is attach or detach */
602*4882a593Smuzhiyun 		if (gnd_type == MAX77843_MUIC_GND_MHL_VB)
603*4882a593Smuzhiyun 			extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,
604*4882a593Smuzhiyun 						true);
605*4882a593Smuzhiyun 		else if (gnd_type == MAX77843_MUIC_GND_MHL)
606*4882a593Smuzhiyun 			extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,
607*4882a593Smuzhiyun 						false);
608*4882a593Smuzhiyun 		break;
609*4882a593Smuzhiyun 	case MAX77843_MUIC_CHG_DOCK:
610*4882a593Smuzhiyun 		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, attached);
611*4882a593Smuzhiyun 		break;
612*4882a593Smuzhiyun 	case MAX77843_MUIC_CHG_NONE:
613*4882a593Smuzhiyun 		break;
614*4882a593Smuzhiyun 	default:
615*4882a593Smuzhiyun 		dev_err(info->dev,
616*4882a593Smuzhiyun 			"failed to detect %s accessory (chg_type:0x%x)\n",
617*4882a593Smuzhiyun 			attached ? "attached" : "detached", chg_type);
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 		max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_OPEN,
620*4882a593Smuzhiyun 				       attached, false);
621*4882a593Smuzhiyun 		return -EINVAL;
622*4882a593Smuzhiyun 	}
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun 	return 0;
625*4882a593Smuzhiyun }
626*4882a593Smuzhiyun 
max77843_muic_irq_work(struct work_struct * work)627*4882a593Smuzhiyun static void max77843_muic_irq_work(struct work_struct *work)
628*4882a593Smuzhiyun {
629*4882a593Smuzhiyun 	struct max77843_muic_info *info = container_of(work,
630*4882a593Smuzhiyun 			struct max77843_muic_info, irq_work);
631*4882a593Smuzhiyun 	struct max77693_dev *max77843 = info->max77843;
632*4882a593Smuzhiyun 	int ret = 0;
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	mutex_lock(&info->mutex);
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 	ret = regmap_bulk_read(max77843->regmap_muic,
637*4882a593Smuzhiyun 			MAX77843_MUIC_REG_STATUS1, info->status,
638*4882a593Smuzhiyun 			MAX77843_MUIC_STATUS_NUM);
639*4882a593Smuzhiyun 	if (ret) {
640*4882a593Smuzhiyun 		dev_err(info->dev, "Cannot read STATUS registers\n");
641*4882a593Smuzhiyun 		mutex_unlock(&info->mutex);
642*4882a593Smuzhiyun 		return;
643*4882a593Smuzhiyun 	}
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 	if (info->irq_adc) {
646*4882a593Smuzhiyun 		ret = max77843_muic_adc_handler(info);
647*4882a593Smuzhiyun 		if (ret)
648*4882a593Smuzhiyun 			dev_err(info->dev, "Unknown cable type\n");
649*4882a593Smuzhiyun 		info->irq_adc = false;
650*4882a593Smuzhiyun 	}
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 	if (info->irq_chg) {
653*4882a593Smuzhiyun 		ret = max77843_muic_chg_handler(info);
654*4882a593Smuzhiyun 		if (ret)
655*4882a593Smuzhiyun 			dev_err(info->dev, "Unknown charger type\n");
656*4882a593Smuzhiyun 		info->irq_chg = false;
657*4882a593Smuzhiyun 	}
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 	mutex_unlock(&info->mutex);
660*4882a593Smuzhiyun }
661*4882a593Smuzhiyun 
max77843_muic_irq_handler(int irq,void * data)662*4882a593Smuzhiyun static irqreturn_t max77843_muic_irq_handler(int irq, void *data)
663*4882a593Smuzhiyun {
664*4882a593Smuzhiyun 	struct max77843_muic_info *info = data;
665*4882a593Smuzhiyun 	int i, irq_type = -1;
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(max77843_muic_irqs); i++)
668*4882a593Smuzhiyun 		if (irq == max77843_muic_irqs[i].virq)
669*4882a593Smuzhiyun 			irq_type = max77843_muic_irqs[i].irq;
670*4882a593Smuzhiyun 
671*4882a593Smuzhiyun 	switch (irq_type) {
672*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT1_ADC:
673*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT1_ADCERROR:
674*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT1_ADC1K:
675*4882a593Smuzhiyun 		info->irq_adc = true;
676*4882a593Smuzhiyun 		break;
677*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT2_CHGTYP:
678*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT2_CHGDETRUN:
679*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT2_DCDTMR:
680*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT2_DXOVP:
681*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT2_VBVOLT:
682*4882a593Smuzhiyun 		info->irq_chg = true;
683*4882a593Smuzhiyun 		break;
684*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT3_VBADC:
685*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT3_VDNMON:
686*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT3_DNRES:
687*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT3_MPNACK:
688*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT3_MRXBUFOW:
689*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT3_MRXTRF:
690*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT3_MRXPERR:
691*4882a593Smuzhiyun 	case MAX77843_MUIC_IRQ_INT3_MRXRDY:
692*4882a593Smuzhiyun 		break;
693*4882a593Smuzhiyun 	default:
694*4882a593Smuzhiyun 		dev_err(info->dev, "Cannot recognize IRQ(%d)\n", irq_type);
695*4882a593Smuzhiyun 		break;
696*4882a593Smuzhiyun 	}
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	schedule_work(&info->irq_work);
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 	return IRQ_HANDLED;
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun 
max77843_muic_detect_cable_wq(struct work_struct * work)703*4882a593Smuzhiyun static void max77843_muic_detect_cable_wq(struct work_struct *work)
704*4882a593Smuzhiyun {
705*4882a593Smuzhiyun 	struct max77843_muic_info *info = container_of(to_delayed_work(work),
706*4882a593Smuzhiyun 			struct max77843_muic_info, wq_detcable);
707*4882a593Smuzhiyun 	struct max77693_dev *max77843 = info->max77843;
708*4882a593Smuzhiyun 	int chg_type, adc, ret;
709*4882a593Smuzhiyun 	bool attached;
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun 	mutex_lock(&info->mutex);
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun 	ret = regmap_bulk_read(max77843->regmap_muic,
714*4882a593Smuzhiyun 			MAX77843_MUIC_REG_STATUS1, info->status,
715*4882a593Smuzhiyun 			MAX77843_MUIC_STATUS_NUM);
716*4882a593Smuzhiyun 	if (ret) {
717*4882a593Smuzhiyun 		dev_err(info->dev, "Cannot read STATUS registers\n");
718*4882a593Smuzhiyun 		goto err_cable_wq;
719*4882a593Smuzhiyun 	}
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	adc = max77843_muic_get_cable_type(info,
722*4882a593Smuzhiyun 			MAX77843_CABLE_GROUP_ADC, &attached);
723*4882a593Smuzhiyun 	if (attached && adc != MAX77843_MUIC_ADC_OPEN) {
724*4882a593Smuzhiyun 		ret = max77843_muic_adc_handler(info);
725*4882a593Smuzhiyun 		if (ret < 0) {
726*4882a593Smuzhiyun 			dev_err(info->dev, "Cannot detect accessory\n");
727*4882a593Smuzhiyun 			goto err_cable_wq;
728*4882a593Smuzhiyun 		}
729*4882a593Smuzhiyun 	}
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun 	chg_type = max77843_muic_get_cable_type(info,
732*4882a593Smuzhiyun 			MAX77843_CABLE_GROUP_CHG, &attached);
733*4882a593Smuzhiyun 	if (attached && chg_type != MAX77843_MUIC_CHG_NONE) {
734*4882a593Smuzhiyun 		ret = max77843_muic_chg_handler(info);
735*4882a593Smuzhiyun 		if (ret < 0) {
736*4882a593Smuzhiyun 			dev_err(info->dev, "Cannot detect charger accessory\n");
737*4882a593Smuzhiyun 			goto err_cable_wq;
738*4882a593Smuzhiyun 		}
739*4882a593Smuzhiyun 	}
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun err_cable_wq:
742*4882a593Smuzhiyun 	mutex_unlock(&info->mutex);
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun 
max77843_muic_set_debounce_time(struct max77843_muic_info * info,enum max77843_muic_adc_debounce_time time)745*4882a593Smuzhiyun static int max77843_muic_set_debounce_time(struct max77843_muic_info *info,
746*4882a593Smuzhiyun 		enum max77843_muic_adc_debounce_time time)
747*4882a593Smuzhiyun {
748*4882a593Smuzhiyun 	struct max77693_dev *max77843 = info->max77843;
749*4882a593Smuzhiyun 	int ret;
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun 	switch (time) {
752*4882a593Smuzhiyun 	case MAX77843_DEBOUNCE_TIME_5MS:
753*4882a593Smuzhiyun 	case MAX77843_DEBOUNCE_TIME_10MS:
754*4882a593Smuzhiyun 	case MAX77843_DEBOUNCE_TIME_25MS:
755*4882a593Smuzhiyun 	case MAX77843_DEBOUNCE_TIME_38_62MS:
756*4882a593Smuzhiyun 		ret = regmap_update_bits(max77843->regmap_muic,
757*4882a593Smuzhiyun 				MAX77843_MUIC_REG_CONTROL4,
758*4882a593Smuzhiyun 				MAX77843_MUIC_CONTROL4_ADCDBSET_MASK,
759*4882a593Smuzhiyun 				time << MAX77843_MUIC_CONTROL4_ADCDBSET_SHIFT);
760*4882a593Smuzhiyun 		if (ret < 0) {
761*4882a593Smuzhiyun 			dev_err(info->dev, "Cannot write MUIC regmap\n");
762*4882a593Smuzhiyun 			return ret;
763*4882a593Smuzhiyun 		}
764*4882a593Smuzhiyun 		break;
765*4882a593Smuzhiyun 	default:
766*4882a593Smuzhiyun 		dev_err(info->dev, "Invalid ADC debounce time\n");
767*4882a593Smuzhiyun 		return -EINVAL;
768*4882a593Smuzhiyun 	}
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 	return 0;
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun 
max77843_init_muic_regmap(struct max77693_dev * max77843)773*4882a593Smuzhiyun static int max77843_init_muic_regmap(struct max77693_dev *max77843)
774*4882a593Smuzhiyun {
775*4882a593Smuzhiyun 	int ret;
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun 	max77843->i2c_muic = i2c_new_dummy_device(max77843->i2c->adapter,
778*4882a593Smuzhiyun 			I2C_ADDR_MUIC);
779*4882a593Smuzhiyun 	if (IS_ERR(max77843->i2c_muic)) {
780*4882a593Smuzhiyun 		dev_err(&max77843->i2c->dev,
781*4882a593Smuzhiyun 				"Cannot allocate I2C device for MUIC\n");
782*4882a593Smuzhiyun 		return PTR_ERR(max77843->i2c_muic);
783*4882a593Smuzhiyun 	}
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	i2c_set_clientdata(max77843->i2c_muic, max77843);
786*4882a593Smuzhiyun 
787*4882a593Smuzhiyun 	max77843->regmap_muic = devm_regmap_init_i2c(max77843->i2c_muic,
788*4882a593Smuzhiyun 			&max77843_muic_regmap_config);
789*4882a593Smuzhiyun 	if (IS_ERR(max77843->regmap_muic)) {
790*4882a593Smuzhiyun 		ret = PTR_ERR(max77843->regmap_muic);
791*4882a593Smuzhiyun 		goto err_muic_i2c;
792*4882a593Smuzhiyun 	}
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	ret = regmap_add_irq_chip(max77843->regmap_muic, max77843->irq,
795*4882a593Smuzhiyun 			IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
796*4882a593Smuzhiyun 			0, &max77843_muic_irq_chip, &max77843->irq_data_muic);
797*4882a593Smuzhiyun 	if (ret < 0) {
798*4882a593Smuzhiyun 		dev_err(&max77843->i2c->dev, "Cannot add MUIC IRQ chip\n");
799*4882a593Smuzhiyun 		goto err_muic_i2c;
800*4882a593Smuzhiyun 	}
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 	return 0;
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun err_muic_i2c:
805*4882a593Smuzhiyun 	i2c_unregister_device(max77843->i2c_muic);
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun 	return ret;
808*4882a593Smuzhiyun }
809*4882a593Smuzhiyun 
max77843_muic_probe(struct platform_device * pdev)810*4882a593Smuzhiyun static int max77843_muic_probe(struct platform_device *pdev)
811*4882a593Smuzhiyun {
812*4882a593Smuzhiyun 	struct max77693_dev *max77843 = dev_get_drvdata(pdev->dev.parent);
813*4882a593Smuzhiyun 	struct max77843_muic_info *info;
814*4882a593Smuzhiyun 	unsigned int id;
815*4882a593Smuzhiyun 	int cable_type;
816*4882a593Smuzhiyun 	bool attached;
817*4882a593Smuzhiyun 	int i, ret;
818*4882a593Smuzhiyun 
819*4882a593Smuzhiyun 	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
820*4882a593Smuzhiyun 	if (!info)
821*4882a593Smuzhiyun 		return -ENOMEM;
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun 	info->dev = &pdev->dev;
824*4882a593Smuzhiyun 	info->max77843 = max77843;
825*4882a593Smuzhiyun 
826*4882a593Smuzhiyun 	platform_set_drvdata(pdev, info);
827*4882a593Smuzhiyun 	mutex_init(&info->mutex);
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	/* Initialize i2c and regmap */
830*4882a593Smuzhiyun 	ret = max77843_init_muic_regmap(max77843);
831*4882a593Smuzhiyun 	if (ret) {
832*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Failed to init MUIC regmap\n");
833*4882a593Smuzhiyun 		return ret;
834*4882a593Smuzhiyun 	}
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	/* Turn off auto detection configuration */
837*4882a593Smuzhiyun 	ret = regmap_update_bits(max77843->regmap_muic,
838*4882a593Smuzhiyun 			MAX77843_MUIC_REG_CONTROL4,
839*4882a593Smuzhiyun 			MAX77843_MUIC_CONTROL4_USBAUTO_MASK |
840*4882a593Smuzhiyun 			MAX77843_MUIC_CONTROL4_FCTAUTO_MASK,
841*4882a593Smuzhiyun 			CONTROL4_AUTO_DISABLE);
842*4882a593Smuzhiyun 
843*4882a593Smuzhiyun 	/* Initialize extcon device */
844*4882a593Smuzhiyun 	info->edev = devm_extcon_dev_allocate(&pdev->dev,
845*4882a593Smuzhiyun 			max77843_extcon_cable);
846*4882a593Smuzhiyun 	if (IS_ERR(info->edev)) {
847*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Failed to allocate memory for extcon\n");
848*4882a593Smuzhiyun 		ret = PTR_ERR(info->edev);
849*4882a593Smuzhiyun 		goto err_muic_irq;
850*4882a593Smuzhiyun 	}
851*4882a593Smuzhiyun 
852*4882a593Smuzhiyun 	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
853*4882a593Smuzhiyun 	if (ret) {
854*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Failed to register extcon device\n");
855*4882a593Smuzhiyun 		goto err_muic_irq;
856*4882a593Smuzhiyun 	}
857*4882a593Smuzhiyun 
858*4882a593Smuzhiyun 	/* Set ADC debounce time */
859*4882a593Smuzhiyun 	max77843_muic_set_debounce_time(info, MAX77843_DEBOUNCE_TIME_25MS);
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun 	/* Set initial path for UART when JIG is connected to get serial logs */
862*4882a593Smuzhiyun 	ret = regmap_bulk_read(max77843->regmap_muic,
863*4882a593Smuzhiyun 			MAX77843_MUIC_REG_STATUS1, info->status,
864*4882a593Smuzhiyun 			MAX77843_MUIC_STATUS_NUM);
865*4882a593Smuzhiyun 	if (ret) {
866*4882a593Smuzhiyun 		dev_err(info->dev, "Cannot read STATUS registers\n");
867*4882a593Smuzhiyun 		goto err_muic_irq;
868*4882a593Smuzhiyun 	}
869*4882a593Smuzhiyun 	cable_type = max77843_muic_get_cable_type(info, MAX77843_CABLE_GROUP_ADC,
870*4882a593Smuzhiyun 					 &attached);
871*4882a593Smuzhiyun 	if (attached && cable_type == MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF)
872*4882a593Smuzhiyun 		max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_UART,
873*4882a593Smuzhiyun 				       true, false);
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun 	/* Check revision number of MUIC device */
876*4882a593Smuzhiyun 	ret = regmap_read(max77843->regmap_muic, MAX77843_MUIC_REG_ID, &id);
877*4882a593Smuzhiyun 	if (ret < 0) {
878*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Failed to read revision number\n");
879*4882a593Smuzhiyun 		goto err_muic_irq;
880*4882a593Smuzhiyun 	}
881*4882a593Smuzhiyun 	dev_info(info->dev, "MUIC device ID : 0x%x\n", id);
882*4882a593Smuzhiyun 
883*4882a593Smuzhiyun 	/* Support virtual irq domain for max77843 MUIC device */
884*4882a593Smuzhiyun 	INIT_WORK(&info->irq_work, max77843_muic_irq_work);
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	/* Clear IRQ bits before request IRQs */
887*4882a593Smuzhiyun 	ret = regmap_bulk_read(max77843->regmap_muic,
888*4882a593Smuzhiyun 			MAX77843_MUIC_REG_INT1, info->status,
889*4882a593Smuzhiyun 			MAX77843_MUIC_STATUS_NUM);
890*4882a593Smuzhiyun 	if (ret) {
891*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Failed to Clear IRQ bits\n");
892*4882a593Smuzhiyun 		goto err_muic_irq;
893*4882a593Smuzhiyun 	}
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(max77843_muic_irqs); i++) {
896*4882a593Smuzhiyun 		struct max77843_muic_irq *muic_irq = &max77843_muic_irqs[i];
897*4882a593Smuzhiyun 		int virq = 0;
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun 		virq = regmap_irq_get_virq(max77843->irq_data_muic,
900*4882a593Smuzhiyun 				muic_irq->irq);
901*4882a593Smuzhiyun 		if (virq <= 0) {
902*4882a593Smuzhiyun 			ret = -EINVAL;
903*4882a593Smuzhiyun 			goto err_muic_irq;
904*4882a593Smuzhiyun 		}
905*4882a593Smuzhiyun 		muic_irq->virq = virq;
906*4882a593Smuzhiyun 
907*4882a593Smuzhiyun 		ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
908*4882a593Smuzhiyun 				max77843_muic_irq_handler, IRQF_NO_SUSPEND,
909*4882a593Smuzhiyun 				muic_irq->name, info);
910*4882a593Smuzhiyun 		if (ret) {
911*4882a593Smuzhiyun 			dev_err(&pdev->dev,
912*4882a593Smuzhiyun 				"Failed to request irq (IRQ: %d, error: %d)\n",
913*4882a593Smuzhiyun 				muic_irq->irq, ret);
914*4882a593Smuzhiyun 			goto err_muic_irq;
915*4882a593Smuzhiyun 		}
916*4882a593Smuzhiyun 	}
917*4882a593Smuzhiyun 
918*4882a593Smuzhiyun 	/* Detect accessory after completing the initialization of platform */
919*4882a593Smuzhiyun 	INIT_DELAYED_WORK(&info->wq_detcable, max77843_muic_detect_cable_wq);
920*4882a593Smuzhiyun 	queue_delayed_work(system_power_efficient_wq,
921*4882a593Smuzhiyun 			&info->wq_detcable, msecs_to_jiffies(DELAY_MS_DEFAULT));
922*4882a593Smuzhiyun 
923*4882a593Smuzhiyun 	return 0;
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun err_muic_irq:
926*4882a593Smuzhiyun 	regmap_del_irq_chip(max77843->irq, max77843->irq_data_muic);
927*4882a593Smuzhiyun 	i2c_unregister_device(max77843->i2c_muic);
928*4882a593Smuzhiyun 
929*4882a593Smuzhiyun 	return ret;
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun 
max77843_muic_remove(struct platform_device * pdev)932*4882a593Smuzhiyun static int max77843_muic_remove(struct platform_device *pdev)
933*4882a593Smuzhiyun {
934*4882a593Smuzhiyun 	struct max77843_muic_info *info = platform_get_drvdata(pdev);
935*4882a593Smuzhiyun 	struct max77693_dev *max77843 = info->max77843;
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun 	cancel_work_sync(&info->irq_work);
938*4882a593Smuzhiyun 	regmap_del_irq_chip(max77843->irq, max77843->irq_data_muic);
939*4882a593Smuzhiyun 	i2c_unregister_device(max77843->i2c_muic);
940*4882a593Smuzhiyun 
941*4882a593Smuzhiyun 	return 0;
942*4882a593Smuzhiyun }
943*4882a593Smuzhiyun 
944*4882a593Smuzhiyun static const struct platform_device_id max77843_muic_id[] = {
945*4882a593Smuzhiyun 	{ "max77843-muic", },
946*4882a593Smuzhiyun 	{ /* sentinel */ },
947*4882a593Smuzhiyun };
948*4882a593Smuzhiyun MODULE_DEVICE_TABLE(platform, max77843_muic_id);
949*4882a593Smuzhiyun 
950*4882a593Smuzhiyun static struct platform_driver max77843_muic_driver = {
951*4882a593Smuzhiyun 	.driver		= {
952*4882a593Smuzhiyun 		.name		= "max77843-muic",
953*4882a593Smuzhiyun 	},
954*4882a593Smuzhiyun 	.probe		= max77843_muic_probe,
955*4882a593Smuzhiyun 	.remove		= max77843_muic_remove,
956*4882a593Smuzhiyun 	.id_table	= max77843_muic_id,
957*4882a593Smuzhiyun };
958*4882a593Smuzhiyun 
max77843_muic_init(void)959*4882a593Smuzhiyun static int __init max77843_muic_init(void)
960*4882a593Smuzhiyun {
961*4882a593Smuzhiyun 	return platform_driver_register(&max77843_muic_driver);
962*4882a593Smuzhiyun }
963*4882a593Smuzhiyun subsys_initcall(max77843_muic_init);
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun MODULE_DESCRIPTION("Maxim MAX77843 Extcon driver");
966*4882a593Smuzhiyun MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
967*4882a593Smuzhiyun MODULE_LICENSE("GPL");
968