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