brintos

brintos / linux-shallow public Read only

0
0
Text · 36.6 KiB · 2c567e0 Raw
1281 lines · c
1// SPDX-License-Identifier: GPL-2.0+2//3// extcon-max77693.c - MAX77693 extcon driver to support MAX77693 MUIC4//5// Copyright (C) 2012 Samsung Electrnoics6// Chanwoo Choi <cw00.choi@samsung.com>7 8#include <linux/devm-helpers.h>9#include <linux/kernel.h>10#include <linux/module.h>11#include <linux/i2c.h>12#include <linux/slab.h>13#include <linux/input.h>14#include <linux/interrupt.h>15#include <linux/err.h>16#include <linux/platform_device.h>17#include <linux/mfd/max77693.h>18#include <linux/mfd/max77693-common.h>19#include <linux/mfd/max77693-private.h>20#include <linux/extcon-provider.h>21#include <linux/regmap.h>22#include <linux/irqdomain.h>23 24#define	DEV_NAME			"max77693-muic"25#define	DELAY_MS_DEFAULT		20000		/* unit: millisecond */26 27/*28 * Default value of MAX77693 register to bring up MUIC device.29 * If user don't set some initial value for MUIC device through platform data,30 * extcon-max77693 driver use 'default_init_data' to bring up base operation31 * of MAX77693 MUIC device.32 */33static struct max77693_reg_data default_init_data[] = {34	{35		/* STATUS2 - [3]ChgDetRun */36		.addr = MAX77693_MUIC_REG_STATUS2,37		.data = MAX77693_STATUS2_CHGDETRUN_MASK,38	}, {39		/* INTMASK1 - Unmask [3]ADC1KM,[0]ADCM */40		.addr = MAX77693_MUIC_REG_INTMASK1,41		.data = INTMASK1_ADC1K_MASK42			| INTMASK1_ADC_MASK,43	}, {44		/* INTMASK2 - Unmask [0]ChgTypM */45		.addr = MAX77693_MUIC_REG_INTMASK2,46		.data = INTMASK2_CHGTYP_MASK,47	}, {48		/* INTMASK3 - Mask all of interrupts */49		.addr = MAX77693_MUIC_REG_INTMASK3,50		.data = 0x0,51	}, {52		/* CDETCTRL2 */53		.addr = MAX77693_MUIC_REG_CDETCTRL2,54		.data = CDETCTRL2_VIDRMEN_MASK55			| CDETCTRL2_DXOVPEN_MASK,56	},57};58 59enum max77693_muic_adc_debounce_time {60	ADC_DEBOUNCE_TIME_5MS = 0,61	ADC_DEBOUNCE_TIME_10MS,62	ADC_DEBOUNCE_TIME_25MS,63	ADC_DEBOUNCE_TIME_38_62MS,64};65 66struct max77693_muic_info {67	struct device *dev;68	struct max77693_dev *max77693;69	struct extcon_dev *edev;70	int prev_cable_type;71	int prev_cable_type_gnd;72	int prev_chg_type;73	int prev_button_type;74	u8 status[2];75 76	int irq;77	struct work_struct irq_work;78	struct mutex mutex;79 80	/*81	 * Use delayed workqueue to detect cable state and then82	 * notify cable state to notifiee/platform through uevent.83	 * After completing the booting of platform, the extcon provider84	 * driver should notify cable state to upper layer.85	 */86	struct delayed_work wq_detcable;87 88	/* Button of dock device */89	struct input_dev *dock;90 91	/*92	 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB93	 * h/w path of COMP2/COMN1 on CONTROL1 register.94	 */95	int path_usb;96	int path_uart;97};98 99enum max77693_muic_cable_group {100	MAX77693_CABLE_GROUP_ADC = 0,101	MAX77693_CABLE_GROUP_ADC_GND,102	MAX77693_CABLE_GROUP_CHG,103	MAX77693_CABLE_GROUP_VBVOLT,104};105 106enum max77693_muic_charger_type {107	MAX77693_CHARGER_TYPE_NONE = 0,108	MAX77693_CHARGER_TYPE_USB,109	MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT,110	MAX77693_CHARGER_TYPE_DEDICATED_CHG,111	MAX77693_CHARGER_TYPE_APPLE_500MA,112	MAX77693_CHARGER_TYPE_APPLE_1A_2A,113	MAX77693_CHARGER_TYPE_DEAD_BATTERY = 7,114};115 116/**117 * struct max77693_muic_irq118 * @irq: the index of irq list of MUIC device.119 * @name: the name of irq.120 * @virq: the virtual irq to use irq domain121 */122struct max77693_muic_irq {123	unsigned int irq;124	const char *name;125	unsigned int virq;126};127 128static struct max77693_muic_irq muic_irqs[] = {129	{ MAX77693_MUIC_IRQ_INT1_ADC,		"muic-ADC" },130	{ MAX77693_MUIC_IRQ_INT1_ADC_LOW,	"muic-ADCLOW" },131	{ MAX77693_MUIC_IRQ_INT1_ADC_ERR,	"muic-ADCError" },132	{ MAX77693_MUIC_IRQ_INT1_ADC1K,		"muic-ADC1K" },133	{ MAX77693_MUIC_IRQ_INT2_CHGTYP,	"muic-CHGTYP" },134	{ MAX77693_MUIC_IRQ_INT2_CHGDETREUN,	"muic-CHGDETREUN" },135	{ MAX77693_MUIC_IRQ_INT2_DCDTMR,	"muic-DCDTMR" },136	{ MAX77693_MUIC_IRQ_INT2_DXOVP,		"muic-DXOVP" },137	{ MAX77693_MUIC_IRQ_INT2_VBVOLT,	"muic-VBVOLT" },138	{ MAX77693_MUIC_IRQ_INT2_VIDRM,		"muic-VIDRM" },139	{ MAX77693_MUIC_IRQ_INT3_EOC,		"muic-EOC" },140	{ MAX77693_MUIC_IRQ_INT3_CGMBC,		"muic-CGMBC" },141	{ MAX77693_MUIC_IRQ_INT3_OVP,		"muic-OVP" },142	{ MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR,	"muic-MBCCHG_ERR" },143	{ MAX77693_MUIC_IRQ_INT3_CHG_ENABLED,	"muic-CHG_ENABLED" },144	{ MAX77693_MUIC_IRQ_INT3_BAT_DET,	"muic-BAT_DET" },145};146 147/* Define supported accessory type */148enum max77693_muic_acc_type {149	MAX77693_MUIC_ADC_GROUND = 0x0,150	MAX77693_MUIC_ADC_SEND_END_BUTTON,151	MAX77693_MUIC_ADC_REMOTE_S1_BUTTON,152	MAX77693_MUIC_ADC_REMOTE_S2_BUTTON,153	MAX77693_MUIC_ADC_REMOTE_S3_BUTTON,154	MAX77693_MUIC_ADC_REMOTE_S4_BUTTON,155	MAX77693_MUIC_ADC_REMOTE_S5_BUTTON,156	MAX77693_MUIC_ADC_REMOTE_S6_BUTTON,157	MAX77693_MUIC_ADC_REMOTE_S7_BUTTON,158	MAX77693_MUIC_ADC_REMOTE_S8_BUTTON,159	MAX77693_MUIC_ADC_REMOTE_S9_BUTTON,160	MAX77693_MUIC_ADC_REMOTE_S10_BUTTON,161	MAX77693_MUIC_ADC_REMOTE_S11_BUTTON,162	MAX77693_MUIC_ADC_REMOTE_S12_BUTTON,163	MAX77693_MUIC_ADC_RESERVED_ACC_1,164	MAX77693_MUIC_ADC_RESERVED_ACC_2,165	MAX77693_MUIC_ADC_RESERVED_ACC_3,166	MAX77693_MUIC_ADC_RESERVED_ACC_4,167	MAX77693_MUIC_ADC_RESERVED_ACC_5,168	MAX77693_MUIC_ADC_CEA936_AUDIO,169	MAX77693_MUIC_ADC_PHONE_POWERED_DEV,170	MAX77693_MUIC_ADC_TTY_CONVERTER,171	MAX77693_MUIC_ADC_UART_CABLE,172	MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG,173	MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF,174	MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON,175	MAX77693_MUIC_ADC_AV_CABLE_NOLOAD,176	MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG,177	MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF,178	MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON,179	MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE,180	MAX77693_MUIC_ADC_OPEN,181 182	/*183	 * The below accessories have same ADC value so ADCLow and184	 * ADC1K bit is used to separate specific accessory.185	 */186						/* ADC|VBVolot|ADCLow|ADC1K| */187	MAX77693_MUIC_GND_USB_HOST = 0x100,	/* 0x0|      0|     0|    0| */188	MAX77693_MUIC_GND_USB_HOST_VB = 0x104,	/* 0x0|      1|     0|    0| */189	MAX77693_MUIC_GND_AV_CABLE_LOAD = 0x102,/* 0x0|      0|     1|    0| */190	MAX77693_MUIC_GND_MHL = 0x103,		/* 0x0|      0|     1|    1| */191	MAX77693_MUIC_GND_MHL_VB = 0x107,	/* 0x0|      1|     1|    1| */192};193 194/*195 * MAX77693 MUIC device support below list of accessories(external connector)196 */197static const unsigned int max77693_extcon_cable[] = {198	EXTCON_USB,199	EXTCON_USB_HOST,200	EXTCON_CHG_USB_SDP,201	EXTCON_CHG_USB_DCP,202	EXTCON_CHG_USB_FAST,203	EXTCON_CHG_USB_SLOW,204	EXTCON_CHG_USB_CDP,205	EXTCON_DISP_MHL,206	EXTCON_JIG,207	EXTCON_DOCK,208	EXTCON_NONE,209};210 211/*212 * max77693_muic_set_debounce_time - Set the debounce time of ADC213 * @info: the instance including private data of max77693 MUIC214 * @time: the debounce time of ADC215 */216static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,217		enum max77693_muic_adc_debounce_time time)218{219	int ret;220 221	switch (time) {222	case ADC_DEBOUNCE_TIME_5MS:223	case ADC_DEBOUNCE_TIME_10MS:224	case ADC_DEBOUNCE_TIME_25MS:225	case ADC_DEBOUNCE_TIME_38_62MS:226		/*227		 * Don't touch BTLDset, JIGset when you want to change adc228		 * debounce time. If it writes other than 0 to BTLDset, JIGset229		 * muic device will be reset and loose current state.230		 */231		ret = regmap_write(info->max77693->regmap_muic,232				  MAX77693_MUIC_REG_CTRL3,233				  time << MAX77693_CONTROL3_ADCDBSET_SHIFT);234		if (ret) {235			dev_err(info->dev, "failed to set ADC debounce time\n");236			return ret;237		}238		break;239	default:240		dev_err(info->dev, "invalid ADC debounce time\n");241		return -EINVAL;242	}243 244	return 0;245};246 247/*248 * max77693_muic_set_path - Set hardware line according to attached cable249 * @info: the instance including private data of max77693 MUIC250 * @value: the path according to attached cable251 * @attached: the state of cable (true:attached, false:detached)252 *253 * The max77693 MUIC device share outside H/W line among a varity of cables254 * so, this function set internal path of H/W line according to the type of255 * attached cable.256 */257static int max77693_muic_set_path(struct max77693_muic_info *info,258		u8 val, bool attached)259{260	int ret;261	unsigned int ctrl1, ctrl2 = 0;262 263	if (attached)264		ctrl1 = val;265	else266		ctrl1 = MAX77693_CONTROL1_SW_OPEN;267 268	ret = regmap_update_bits(info->max77693->regmap_muic,269			MAX77693_MUIC_REG_CTRL1, COMP_SW_MASK, ctrl1);270	if (ret < 0) {271		dev_err(info->dev, "failed to update MUIC register\n");272		return ret;273	}274 275	if (attached)276		ctrl2 |= MAX77693_CONTROL2_CPEN_MASK;	/* LowPwr=0, CPEn=1 */277	else278		ctrl2 |= MAX77693_CONTROL2_LOWPWR_MASK;	/* LowPwr=1, CPEn=0 */279 280	ret = regmap_update_bits(info->max77693->regmap_muic,281			MAX77693_MUIC_REG_CTRL2,282			MAX77693_CONTROL2_LOWPWR_MASK | MAX77693_CONTROL2_CPEN_MASK,283			ctrl2);284	if (ret < 0) {285		dev_err(info->dev, "failed to update MUIC register\n");286		return ret;287	}288 289	dev_info(info->dev,290		"CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",291		ctrl1, ctrl2, attached ? "attached" : "detached");292 293	return 0;294}295 296/*297 * max77693_muic_get_cable_type - Return cable type and check cable state298 * @info: the instance including private data of max77693 MUIC299 * @group: the path according to attached cable300 * @attached: store cable state and return301 *302 * This function check the cable state either attached or detached,303 * and then divide precise type of cable according to cable group.304 *	- MAX77693_CABLE_GROUP_ADC305 *	- MAX77693_CABLE_GROUP_ADC_GND306 *	- MAX77693_CABLE_GROUP_CHG307 *	- MAX77693_CABLE_GROUP_VBVOLT308 */309static int max77693_muic_get_cable_type(struct max77693_muic_info *info,310		enum max77693_muic_cable_group group, bool *attached)311{312	int cable_type = 0;313	int adc;314	int adc1k;315	int adclow;316	int vbvolt;317	int chg_type;318 319	switch (group) {320	case MAX77693_CABLE_GROUP_ADC:321		/*322		 * Read ADC value to check cable type and decide cable state323		 * according to cable type324		 */325		adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;326		adc >>= MAX77693_STATUS1_ADC_SHIFT;327 328		/*329		 * Check current cable state/cable type and store cable type330		 * (info->prev_cable_type) for handling cable when cable is331		 * detached.332		 */333		if (adc == MAX77693_MUIC_ADC_OPEN) {334			*attached = false;335 336			cable_type = info->prev_cable_type;337			info->prev_cable_type = MAX77693_MUIC_ADC_OPEN;338		} else {339			*attached = true;340 341			cable_type = info->prev_cable_type = adc;342		}343		break;344	case MAX77693_CABLE_GROUP_ADC_GND:345		/*346		 * Read ADC value to check cable type and decide cable state347		 * according to cable type348		 */349		adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;350		adc >>= MAX77693_STATUS1_ADC_SHIFT;351 352		/*353		 * Check current cable state/cable type and store cable type354		 * (info->prev_cable_type/_gnd) for handling cable when cable355		 * is detached.356		 */357		if (adc == MAX77693_MUIC_ADC_OPEN) {358			*attached = false;359 360			cable_type = info->prev_cable_type_gnd;361			info->prev_cable_type_gnd = MAX77693_MUIC_ADC_OPEN;362		} else {363			*attached = true;364 365			adclow = info->status[0] & MAX77693_STATUS1_ADCLOW_MASK;366			adclow >>= MAX77693_STATUS1_ADCLOW_SHIFT;367			adc1k = info->status[0] & MAX77693_STATUS1_ADC1K_MASK;368			adc1k >>= MAX77693_STATUS1_ADC1K_SHIFT;369 370			vbvolt = info->status[1] & MAX77693_STATUS2_VBVOLT_MASK;371			vbvolt >>= MAX77693_STATUS2_VBVOLT_SHIFT;372 373			/**374			 * [0x1|VBVolt|ADCLow|ADC1K]375			 * [0x1|     0|     0|    0] USB_HOST376			 * [0x1|     1|     0|    0] USB_HSOT_VB377			 * [0x1|     0|     1|    0] Audio Video cable with load378			 * [0x1|     0|     1|    1] MHL without charging cable379			 * [0x1|     1|     1|    1] MHL with charging cable380			 */381			cable_type = ((0x1 << 8)382					| (vbvolt << 2)383					| (adclow << 1)384					| adc1k);385 386			info->prev_cable_type = adc;387			info->prev_cable_type_gnd = cable_type;388		}389 390		break;391	case MAX77693_CABLE_GROUP_CHG:392		/*393		 * Read charger type to check cable type and decide cable state394		 * according to type of charger cable.395		 */396		chg_type = info->status[1] & MAX77693_STATUS2_CHGTYP_MASK;397		chg_type >>= MAX77693_STATUS2_CHGTYP_SHIFT;398 399		if (chg_type == MAX77693_CHARGER_TYPE_NONE) {400			*attached = false;401 402			cable_type = info->prev_chg_type;403			info->prev_chg_type = MAX77693_CHARGER_TYPE_NONE;404		} else {405			*attached = true;406 407			/*408			 * Check current cable state/cable type and store cable409			 * type(info->prev_chg_type) for handling cable when410			 * charger cable is detached.411			 */412			cable_type = info->prev_chg_type = chg_type;413		}414 415		break;416	case MAX77693_CABLE_GROUP_VBVOLT:417		/*418		 * Read ADC value to check cable type and decide cable state419		 * according to cable type420		 */421		adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;422		adc >>= MAX77693_STATUS1_ADC_SHIFT;423		chg_type = info->status[1] & MAX77693_STATUS2_CHGTYP_MASK;424		chg_type >>= MAX77693_STATUS2_CHGTYP_SHIFT;425 426		if (adc == MAX77693_MUIC_ADC_OPEN427				&& chg_type == MAX77693_CHARGER_TYPE_NONE)428			*attached = false;429		else430			*attached = true;431 432		/*433		 * Read vbvolt field, if vbvolt is 1,434		 * this cable is used for charging.435		 */436		vbvolt = info->status[1] & MAX77693_STATUS2_VBVOLT_MASK;437		vbvolt >>= MAX77693_STATUS2_VBVOLT_SHIFT;438 439		cable_type = vbvolt;440		break;441	default:442		dev_err(info->dev, "Unknown cable group (%d)\n", group);443		cable_type = -EINVAL;444		break;445	}446 447	return cable_type;448}449 450static int max77693_muic_dock_handler(struct max77693_muic_info *info,451		int cable_type, bool attached)452{453	int ret = 0;454	int vbvolt;455	bool cable_attached;456	unsigned int dock_id;457 458	dev_info(info->dev,459		"external connector is %s (adc:0x%02x)\n",460		attached ? "attached" : "detached", cable_type);461 462	switch (cable_type) {463	case MAX77693_MUIC_ADC_RESERVED_ACC_3:		/* Dock-Smart */464		/*465		 * Check power cable whether attached or detached state.466		 * The Dock-Smart device need surely external power supply.467		 * If power cable(USB/TA) isn't connected to Dock device,468		 * user can't use Dock-Smart for desktop mode.469		 */470		vbvolt = max77693_muic_get_cable_type(info,471				MAX77693_CABLE_GROUP_VBVOLT, &cable_attached);472		if (attached && !vbvolt) {473			dev_warn(info->dev,474				"Cannot detect external power supply\n");475			return 0;476		}477 478		/*479		 * Notify Dock/MHL state.480		 * - Dock device include three type of cable which481		 * are HDMI, USB for mouse/keyboard and micro-usb port482		 * for USB/TA cable. Dock device need always exteranl483		 * power supply(USB/TA cable through micro-usb cable). Dock484		 * device support screen output of target to separate485		 * monitor and mouse/keyboard for desktop mode.486		 *487		 * Features of 'USB/TA cable with Dock device'488		 * - Support MHL489		 * - Support external output feature of audio490		 * - Support charging through micro-usb port without data491		 *	     connection if TA cable is connected to target.492		 * - Support charging and data connection through micro-usb port493		 *           if USB cable is connected between target and host494		 *	     device.495		 * - Support OTG(On-The-Go) device (Ex: Mouse/Keyboard)496		 */497		ret = max77693_muic_set_path(info, info->path_usb, attached);498		if (ret < 0)499			return ret;500 501		extcon_set_state_sync(info->edev, EXTCON_DOCK, attached);502		extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached);503		goto out;504	case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE:	/* Dock-Desk */505		dock_id = EXTCON_DOCK;506		break;507	case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD:		/* Dock-Audio */508		dock_id = EXTCON_DOCK;509		if (!attached) {510			extcon_set_state_sync(info->edev, EXTCON_USB, false);511			extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,512						false);513		}514		break;515	default:516		dev_err(info->dev, "failed to detect %s dock device\n",517			attached ? "attached" : "detached");518		return -EINVAL;519	}520 521	/* Dock-Car/Desk/Audio, PATH:AUDIO */522	ret = max77693_muic_set_path(info, MAX77693_CONTROL1_SW_AUDIO,523					attached);524	if (ret < 0)525		return ret;526	extcon_set_state_sync(info->edev, dock_id, attached);527 528out:529	return 0;530}531 532static int max77693_muic_dock_button_handler(struct max77693_muic_info *info,533		int button_type, bool attached)534{535	struct input_dev *dock = info->dock;536	unsigned int code;537 538	switch (button_type) {539	case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON-1540		... MAX77693_MUIC_ADC_REMOTE_S3_BUTTON+1:541		/* DOCK_KEY_PREV */542		code = KEY_PREVIOUSSONG;543		break;544	case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON-1545		... MAX77693_MUIC_ADC_REMOTE_S7_BUTTON+1:546		/* DOCK_KEY_NEXT */547		code = KEY_NEXTSONG;548		break;549	case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON:550		/* DOCK_VOL_DOWN */551		code = KEY_VOLUMEDOWN;552		break;553	case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON:554		/* DOCK_VOL_UP */555		code = KEY_VOLUMEUP;556		break;557	case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON-1558		... MAX77693_MUIC_ADC_REMOTE_S12_BUTTON+1:559		/* DOCK_KEY_PLAY_PAUSE */560		code = KEY_PLAYPAUSE;561		break;562	default:563		dev_err(info->dev,564			"failed to detect %s key (adc:0x%x)\n",565			attached ? "pressed" : "released", button_type);566		return -EINVAL;567	}568 569	input_event(dock, EV_KEY, code, attached);570	input_sync(dock);571 572	return 0;573}574 575static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info)576{577	int cable_type_gnd;578	int ret = 0;579	bool attached;580 581	cable_type_gnd = max77693_muic_get_cable_type(info,582				MAX77693_CABLE_GROUP_ADC_GND, &attached);583 584	switch (cable_type_gnd) {585	case MAX77693_MUIC_GND_USB_HOST:586	case MAX77693_MUIC_GND_USB_HOST_VB:587		/* USB_HOST, PATH: AP_USB */588		ret = max77693_muic_set_path(info, MAX77693_CONTROL1_SW_USB,589						attached);590		if (ret < 0)591			return ret;592		extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached);593		break;594	case MAX77693_MUIC_GND_AV_CABLE_LOAD:595		/* Audio Video Cable with load, PATH:AUDIO */596		ret = max77693_muic_set_path(info, MAX77693_CONTROL1_SW_AUDIO,597						attached);598		if (ret < 0)599			return ret;600		extcon_set_state_sync(info->edev, EXTCON_USB, attached);601		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,602					attached);603		break;604	case MAX77693_MUIC_GND_MHL:605	case MAX77693_MUIC_GND_MHL_VB:606		/* MHL or MHL with USB/TA cable */607		extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached);608		break;609	default:610		dev_err(info->dev, "failed to detect %s cable of gnd type\n",611			attached ? "attached" : "detached");612		return -EINVAL;613	}614 615	return 0;616}617 618static int max77693_muic_jig_handler(struct max77693_muic_info *info,619		int cable_type, bool attached)620{621	int ret = 0;622	u8 path = MAX77693_CONTROL1_SW_OPEN;623 624	dev_info(info->dev,625		"external connector is %s (adc:0x%02x)\n",626		attached ? "attached" : "detached", cable_type);627 628	switch (cable_type) {629	case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF:	/* ADC_JIG_USB_OFF */630	case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON:	/* ADC_JIG_USB_ON */631		/* PATH:AP_USB */632		path = MAX77693_CONTROL1_SW_USB;633		break;634	case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF:	/* ADC_JIG_UART_OFF */635	case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON:	/* ADC_JIG_UART_ON */636		/* PATH:AP_UART */637		path = MAX77693_CONTROL1_SW_UART;638		break;639	default:640		dev_err(info->dev, "failed to detect %s jig cable\n",641			attached ? "attached" : "detached");642		return -EINVAL;643	}644 645	ret = max77693_muic_set_path(info, path, attached);646	if (ret < 0)647		return ret;648 649	extcon_set_state_sync(info->edev, EXTCON_JIG, attached);650 651	return 0;652}653 654static int max77693_muic_adc_handler(struct max77693_muic_info *info)655{656	int cable_type;657	int button_type;658	bool attached;659	int ret = 0;660 661	/* Check accessory state which is either detached or attached */662	cable_type = max77693_muic_get_cable_type(info,663				MAX77693_CABLE_GROUP_ADC, &attached);664 665	dev_info(info->dev,666		"external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",667		attached ? "attached" : "detached", cable_type,668		info->prev_cable_type);669 670	switch (cable_type) {671	case MAX77693_MUIC_ADC_GROUND:672		/* USB_HOST/MHL/Audio */673		max77693_muic_adc_ground_handler(info);674		break;675	case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF:676	case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON:677	case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF:678	case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON:679		/* JIG */680		ret = max77693_muic_jig_handler(info, cable_type, attached);681		if (ret < 0)682			return ret;683		break;684	case MAX77693_MUIC_ADC_RESERVED_ACC_3:		/* Dock-Smart */685	case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE:	/* Dock-Desk */686	case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD:		/* Dock-Audio */687		/*688		 * DOCK device689		 *690		 * The MAX77693 MUIC device can detect total 34 cable type691		 * except of charger cable and MUIC device didn't define692		 * specfic role of cable in the range of from 0x01 to 0x12693		 * of ADC value. So, can use/define cable with no role according694		 * to schema of hardware board.695		 */696		ret = max77693_muic_dock_handler(info, cable_type, attached);697		if (ret < 0)698			return ret;699		break;700	case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON:      /* DOCK_KEY_PREV */701	case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON:      /* DOCK_KEY_NEXT */702	case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON:      /* DOCK_VOL_DOWN */703	case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON:     /* DOCK_VOL_UP */704	case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON:     /* DOCK_KEY_PLAY_PAUSE */705		/*706		 * Button of DOCK device707		 * - the Prev/Next/Volume Up/Volume Down/Play-Pause button708		 *709		 * The MAX77693 MUIC device can detect total 34 cable type710		 * except of charger cable and MUIC device didn't define711		 * specfic role of cable in the range of from 0x01 to 0x12712		 * of ADC value. So, can use/define cable with no role according713		 * to schema of hardware board.714		 */715		if (attached)716			button_type = info->prev_button_type = cable_type;717		else718			button_type = info->prev_button_type;719 720		ret = max77693_muic_dock_button_handler(info, button_type,721							attached);722		if (ret < 0)723			return ret;724		break;725	case MAX77693_MUIC_ADC_SEND_END_BUTTON:726	case MAX77693_MUIC_ADC_REMOTE_S1_BUTTON:727	case MAX77693_MUIC_ADC_REMOTE_S2_BUTTON:728	case MAX77693_MUIC_ADC_REMOTE_S4_BUTTON:729	case MAX77693_MUIC_ADC_REMOTE_S5_BUTTON:730	case MAX77693_MUIC_ADC_REMOTE_S6_BUTTON:731	case MAX77693_MUIC_ADC_REMOTE_S8_BUTTON:732	case MAX77693_MUIC_ADC_REMOTE_S11_BUTTON:733	case MAX77693_MUIC_ADC_RESERVED_ACC_1:734	case MAX77693_MUIC_ADC_RESERVED_ACC_2:735	case MAX77693_MUIC_ADC_RESERVED_ACC_4:736	case MAX77693_MUIC_ADC_RESERVED_ACC_5:737	case MAX77693_MUIC_ADC_CEA936_AUDIO:738	case MAX77693_MUIC_ADC_PHONE_POWERED_DEV:739	case MAX77693_MUIC_ADC_TTY_CONVERTER:740	case MAX77693_MUIC_ADC_UART_CABLE:741	case MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG:742	case MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG:743		/*744		 * This accessory isn't used in general case if it is specially745		 * needed to detect additional accessory, should implement746		 * proper operation when this accessory is attached/detached.747		 */748		dev_info(info->dev,749			"accessory is %s but it isn't used (adc:0x%x)\n",750			attached ? "attached" : "detached", cable_type);751		return -EAGAIN;752	default:753		dev_err(info->dev,754			"failed to detect %s accessory (adc:0x%x)\n",755			attached ? "attached" : "detached", cable_type);756		return -EINVAL;757	}758 759	return 0;760}761 762static int max77693_muic_chg_handler(struct max77693_muic_info *info)763{764	int chg_type;765	int cable_type_gnd;766	int cable_type;767	bool attached;768	bool cable_attached;769	int ret = 0;770 771	chg_type = max77693_muic_get_cable_type(info,772				MAX77693_CABLE_GROUP_CHG, &attached);773 774	dev_info(info->dev,775		"external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",776			attached ? "attached" : "detached",777			chg_type, info->prev_chg_type);778 779	switch (chg_type) {780	case MAX77693_CHARGER_TYPE_USB:781	case MAX77693_CHARGER_TYPE_DEDICATED_CHG:782	case MAX77693_CHARGER_TYPE_NONE:783		/* Check MAX77693_CABLE_GROUP_ADC_GND type */784		cable_type_gnd = max77693_muic_get_cable_type(info,785					MAX77693_CABLE_GROUP_ADC_GND,786					&cable_attached);787		switch (cable_type_gnd) {788		case MAX77693_MUIC_GND_MHL:789		case MAX77693_MUIC_GND_MHL_VB:790			/*791			 * MHL cable with USB/TA cable792			 * - MHL cable include two port(HDMI line and separate793			 * micro-usb port. When the target connect MHL cable,794			 * extcon driver check whether USB/TA cable is795			 * connected. If USB/TA cable is connected, extcon796			 * driver notify state to notifiee for charging battery.797			 *798			 * Features of 'USB/TA with MHL cable'799			 * - Support MHL800			 * - Support charging through micro-usb port without801			 *   data connection802			 */803			extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,804						attached);805			extcon_set_state_sync(info->edev, EXTCON_DISP_MHL,806						cable_attached);807			break;808		}809 810		/* Check MAX77693_CABLE_GROUP_ADC type */811		cable_type = max77693_muic_get_cable_type(info,812					MAX77693_CABLE_GROUP_ADC,813					&cable_attached);814		switch (cable_type) {815		case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD:		/* Dock-Audio */816			/*817			 * Dock-Audio device with USB/TA cable818			 * - Dock device include two port(Dock-Audio and micro-819			 * usb port). When the target connect Dock-Audio device,820			 * extcon driver check whether USB/TA cable is connected821			 * or not. If USB/TA cable is connected, extcon driver822			 * notify state to notifiee for charging battery.823			 *824			 * Features of 'USB/TA cable with Dock-Audio device'825			 * - Support external output feature of audio.826			 * - Support charging through micro-usb port without827			 *   data connection.828			 */829			extcon_set_state_sync(info->edev, EXTCON_USB,830						attached);831			extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,832						attached);833 834			if (!cable_attached)835				extcon_set_state_sync(info->edev, EXTCON_DOCK,836							cable_attached);837			break;838		case MAX77693_MUIC_ADC_RESERVED_ACC_3:		/* Dock-Smart */839			/*840			 * Dock-Smart device with USB/TA cable841			 * - Dock-Desk device include three type of cable which842			 * are HDMI, USB for mouse/keyboard and micro-usb port843			 * for USB/TA cable. Dock-Smart device need always844			 * exteranl power supply(USB/TA cable through micro-usb845			 * cable). Dock-Smart device support screen output of846			 * target to separate monitor and mouse/keyboard for847			 * desktop mode.848			 *849			 * Features of 'USB/TA cable with Dock-Smart device'850			 * - Support MHL851			 * - Support external output feature of audio852			 * - Support charging through micro-usb port without853			 *   data connection if TA cable is connected to target.854			 * - Support charging and data connection through micro-855			 *   usb port if USB cable is connected between target856			 *   and host device857			 * - Support OTG(On-The-Go) device (Ex: Mouse/Keyboard)858			 */859			ret = max77693_muic_set_path(info, info->path_usb,860						    attached);861			if (ret < 0)862				return ret;863 864			extcon_set_state_sync(info->edev, EXTCON_DOCK,865						attached);866			extcon_set_state_sync(info->edev, EXTCON_DISP_MHL,867						attached);868			break;869		}870 871		/* Check MAX77693_CABLE_GROUP_CHG type */872		switch (chg_type) {873		case MAX77693_CHARGER_TYPE_NONE:874			/*875			 * When MHL(with USB/TA cable) or Dock-Audio with USB/TA876			 * cable is attached, muic device happen below two irq.877			 * - 'MAX77693_MUIC_IRQ_INT1_ADC' for detecting878			 *    MHL/Dock-Audio.879			 * - 'MAX77693_MUIC_IRQ_INT2_CHGTYP' for detecting880			 *    USB/TA cable connected to MHL or Dock-Audio.881			 * Always, happen eariler MAX77693_MUIC_IRQ_INT1_ADC882			 * irq than MAX77693_MUIC_IRQ_INT2_CHGTYP irq.883			 *884			 * If user attach MHL (with USB/TA cable and immediately885			 * detach MHL with USB/TA cable before MAX77693_MUIC_IRQ886			 * _INT2_CHGTYP irq is happened, USB/TA cable remain887			 * connected state to target. But USB/TA cable isn't888			 * connected to target. The user be face with unusual889			 * action. So, driver should check this situation in890			 * spite of, that previous charger type is N/A.891			 */892			break;893		case MAX77693_CHARGER_TYPE_USB:894			/* Only USB cable, PATH:AP_USB */895			ret = max77693_muic_set_path(info, info->path_usb,896						    attached);897			if (ret < 0)898				return ret;899 900			extcon_set_state_sync(info->edev, EXTCON_USB,901						attached);902			extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,903						attached);904			break;905		case MAX77693_CHARGER_TYPE_DEDICATED_CHG:906			/* Only TA cable */907			extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,908						attached);909			break;910		}911		break;912	case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT:913		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP,914					attached);915		break;916	case MAX77693_CHARGER_TYPE_APPLE_500MA:917		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW,918					attached);919		break;920	case MAX77693_CHARGER_TYPE_APPLE_1A_2A:921		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST,922					attached);923		break;924	case MAX77693_CHARGER_TYPE_DEAD_BATTERY:925		break;926	default:927		dev_err(info->dev,928			"failed to detect %s accessory (chg_type:0x%x)\n",929			attached ? "attached" : "detached", chg_type);930		return -EINVAL;931	}932 933	return 0;934}935 936static void max77693_muic_irq_work(struct work_struct *work)937{938	struct max77693_muic_info *info = container_of(work,939			struct max77693_muic_info, irq_work);940	int irq_type = -1;941	int i, ret = 0;942 943	if (!info->edev)944		return;945 946	mutex_lock(&info->mutex);947 948	for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)949		if (info->irq == muic_irqs[i].virq)950			irq_type = muic_irqs[i].irq;951 952	ret = regmap_bulk_read(info->max77693->regmap_muic,953			MAX77693_MUIC_REG_STATUS1, info->status, 2);954	if (ret) {955		dev_err(info->dev, "failed to read MUIC register\n");956		mutex_unlock(&info->mutex);957		return;958	}959 960	switch (irq_type) {961	case MAX77693_MUIC_IRQ_INT1_ADC:962	case MAX77693_MUIC_IRQ_INT1_ADC_LOW:963	case MAX77693_MUIC_IRQ_INT1_ADC_ERR:964	case MAX77693_MUIC_IRQ_INT1_ADC1K:965		/*966		 * Handle all of accessory except for967		 * type of charger accessory.968		 */969		ret = max77693_muic_adc_handler(info);970		break;971	case MAX77693_MUIC_IRQ_INT2_CHGTYP:972	case MAX77693_MUIC_IRQ_INT2_CHGDETREUN:973	case MAX77693_MUIC_IRQ_INT2_DCDTMR:974	case MAX77693_MUIC_IRQ_INT2_DXOVP:975	case MAX77693_MUIC_IRQ_INT2_VBVOLT:976	case MAX77693_MUIC_IRQ_INT2_VIDRM:977		/* Handle charger accessory */978		ret = max77693_muic_chg_handler(info);979		break;980	case MAX77693_MUIC_IRQ_INT3_EOC:981	case MAX77693_MUIC_IRQ_INT3_CGMBC:982	case MAX77693_MUIC_IRQ_INT3_OVP:983	case MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR:984	case MAX77693_MUIC_IRQ_INT3_CHG_ENABLED:985	case MAX77693_MUIC_IRQ_INT3_BAT_DET:986		break;987	default:988		dev_err(info->dev, "muic interrupt: irq %d occurred\n",989				irq_type);990		mutex_unlock(&info->mutex);991		return;992	}993 994	if (ret < 0)995		dev_err(info->dev, "failed to handle MUIC interrupt\n");996 997	mutex_unlock(&info->mutex);998}999 1000static irqreturn_t max77693_muic_irq_handler(int irq, void *data)1001{1002	struct max77693_muic_info *info = data;1003 1004	info->irq = irq;1005	schedule_work(&info->irq_work);1006 1007	return IRQ_HANDLED;1008}1009 1010static const struct regmap_config max77693_muic_regmap_config = {1011	.reg_bits = 8,1012	.val_bits = 8,1013};1014 1015static int max77693_muic_detect_accessory(struct max77693_muic_info *info)1016{1017	int ret = 0;1018	int adc;1019	int chg_type;1020	bool attached;1021 1022	mutex_lock(&info->mutex);1023 1024	/* Read STATUSx register to detect accessory */1025	ret = regmap_bulk_read(info->max77693->regmap_muic,1026			MAX77693_MUIC_REG_STATUS1, info->status, 2);1027	if (ret) {1028		dev_err(info->dev, "failed to read MUIC register\n");1029		mutex_unlock(&info->mutex);1030		return ret;1031	}1032 1033	adc = max77693_muic_get_cable_type(info, MAX77693_CABLE_GROUP_ADC,1034					&attached);1035	if (attached && adc != MAX77693_MUIC_ADC_OPEN) {1036		ret = max77693_muic_adc_handler(info);1037		if (ret < 0) {1038			dev_err(info->dev, "Cannot detect accessory\n");1039			mutex_unlock(&info->mutex);1040			return ret;1041		}1042	}1043 1044	chg_type = max77693_muic_get_cable_type(info, MAX77693_CABLE_GROUP_CHG,1045					&attached);1046	if (attached && chg_type != MAX77693_CHARGER_TYPE_NONE) {1047		ret = max77693_muic_chg_handler(info);1048		if (ret < 0) {1049			dev_err(info->dev, "Cannot detect charger accessory\n");1050			mutex_unlock(&info->mutex);1051			return ret;1052		}1053	}1054 1055	mutex_unlock(&info->mutex);1056 1057	return 0;1058}1059 1060static void max77693_muic_detect_cable_wq(struct work_struct *work)1061{1062	struct max77693_muic_info *info = container_of(to_delayed_work(work),1063				struct max77693_muic_info, wq_detcable);1064 1065	max77693_muic_detect_accessory(info);1066}1067 1068static int max77693_muic_probe(struct platform_device *pdev)1069{1070	struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);1071	struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);1072	struct max77693_muic_info *info;1073	struct max77693_reg_data *init_data;1074	int num_init_data;1075	int delay_jiffies;1076	int cable_type;1077	bool attached;1078	int ret;1079	int i;1080	unsigned int id;1081 1082	info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info),1083				   GFP_KERNEL);1084	if (!info)1085		return -ENOMEM;1086 1087	info->dev = &pdev->dev;1088	info->max77693 = max77693;1089	if (info->max77693->regmap_muic) {1090		dev_dbg(&pdev->dev, "allocate register map\n");1091	} else {1092		info->max77693->regmap_muic = devm_regmap_init_i2c(1093						info->max77693->i2c_muic,1094						&max77693_muic_regmap_config);1095		if (IS_ERR(info->max77693->regmap_muic)) {1096			ret = PTR_ERR(info->max77693->regmap_muic);1097			dev_err(max77693->dev,1098				"failed to allocate register map: %d\n", ret);1099			return ret;1100		}1101	}1102 1103	/* Register input device for button of dock device */1104	info->dock = devm_input_allocate_device(&pdev->dev);1105	if (!info->dock) {1106		dev_err(&pdev->dev, "%s: failed to allocate input\n", __func__);1107		return -ENOMEM;1108	}1109	info->dock->name = "max77693-muic/dock";1110	info->dock->phys = "max77693-muic/extcon";1111	info->dock->dev.parent = &pdev->dev;1112 1113	__set_bit(EV_REP, info->dock->evbit);1114 1115	input_set_capability(info->dock, EV_KEY, KEY_VOLUMEUP);1116	input_set_capability(info->dock, EV_KEY, KEY_VOLUMEDOWN);1117	input_set_capability(info->dock, EV_KEY, KEY_PLAYPAUSE);1118	input_set_capability(info->dock, EV_KEY, KEY_PREVIOUSSONG);1119	input_set_capability(info->dock, EV_KEY, KEY_NEXTSONG);1120 1121	ret = input_register_device(info->dock);1122	if (ret < 0) {1123		dev_err(&pdev->dev, "Cannot register input device error(%d)\n",1124				ret);1125		return ret;1126	}1127 1128	platform_set_drvdata(pdev, info);1129	mutex_init(&info->mutex);1130 1131	ret = devm_work_autocancel(&pdev->dev, &info->irq_work,1132				   max77693_muic_irq_work);1133	if (ret)1134		return ret;1135 1136	/* Support irq domain for MAX77693 MUIC device */1137	for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {1138		struct max77693_muic_irq *muic_irq = &muic_irqs[i];1139		int virq;1140 1141		virq = regmap_irq_get_virq(max77693->irq_data_muic,1142					muic_irq->irq);1143		if (virq <= 0)1144			return -EINVAL;1145		muic_irq->virq = virq;1146 1147		ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,1148				max77693_muic_irq_handler,1149				IRQF_NO_SUSPEND,1150				muic_irq->name, info);1151		if (ret) {1152			dev_err(&pdev->dev,1153				"failed: irq request (IRQ: %d, error :%d)\n",1154				muic_irq->irq, ret);1155			return ret;1156		}1157	}1158 1159	/* Initialize extcon device */1160	info->edev = devm_extcon_dev_allocate(&pdev->dev,1161					      max77693_extcon_cable);1162	if (IS_ERR(info->edev)) {1163		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");1164		return PTR_ERR(info->edev);1165	}1166 1167	ret = devm_extcon_dev_register(&pdev->dev, info->edev);1168	if (ret) {1169		dev_err(&pdev->dev, "failed to register extcon device\n");1170		return ret;1171	}1172 1173	/* Initialize MUIC register by using platform data or default data */1174	if (pdata && pdata->muic_data) {1175		init_data = pdata->muic_data->init_data;1176		num_init_data = pdata->muic_data->num_init_data;1177	} else {1178		init_data = default_init_data;1179		num_init_data = ARRAY_SIZE(default_init_data);1180	}1181 1182	for (i = 0; i < num_init_data; i++) {1183		regmap_write(info->max77693->regmap_muic,1184				init_data[i].addr,1185				init_data[i].data);1186	}1187 1188	if (pdata && pdata->muic_data) {1189		struct max77693_muic_platform_data *muic_pdata1190						   = pdata->muic_data;1191 1192		/*1193		 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB1194		 * h/w path of COMP2/COMN1 on CONTROL1 register.1195		 */1196		if (muic_pdata->path_uart)1197			info->path_uart = muic_pdata->path_uart;1198		else1199			info->path_uart = MAX77693_CONTROL1_SW_UART;1200 1201		if (muic_pdata->path_usb)1202			info->path_usb = muic_pdata->path_usb;1203		else1204			info->path_usb = MAX77693_CONTROL1_SW_USB;1205 1206		/*1207		 * Default delay time for detecting cable state1208		 * after certain time.1209		 */1210		if (muic_pdata->detcable_delay_ms)1211			delay_jiffies =1212				msecs_to_jiffies(muic_pdata->detcable_delay_ms);1213		else1214			delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);1215	} else {1216		info->path_usb = MAX77693_CONTROL1_SW_USB;1217		info->path_uart = MAX77693_CONTROL1_SW_UART;1218		delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);1219	}1220 1221	/* Set initial path for UART when JIG is connected to get serial logs */1222	ret = regmap_bulk_read(info->max77693->regmap_muic,1223			MAX77693_MUIC_REG_STATUS1, info->status, 2);1224	if (ret) {1225		dev_err(info->dev, "failed to read MUIC register\n");1226		return ret;1227	}1228	cable_type = max77693_muic_get_cable_type(info,1229					   MAX77693_CABLE_GROUP_ADC, &attached);1230	if (attached && (cable_type == MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON ||1231			 cable_type == MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF))1232		max77693_muic_set_path(info, info->path_uart, true);1233 1234	/* Check revision number of MUIC device*/1235	ret = regmap_read(info->max77693->regmap_muic,1236			MAX77693_MUIC_REG_ID, &id);1237	if (ret < 0) {1238		dev_err(&pdev->dev, "failed to read revision number\n");1239		return ret;1240	}1241	dev_info(info->dev, "device ID : 0x%x\n", id);1242 1243	/* Set ADC debounce time */1244	max77693_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);1245 1246	/*1247	 * Detect accessory after completing the initialization of platform1248	 *1249	 * - Use delayed workqueue to detect cable state and then1250	 * notify cable state to notifiee/platform through uevent.1251	 * After completing the booting of platform, the extcon provider1252	 * driver should notify cable state to upper layer.1253	 */1254	INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq);1255	queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,1256			delay_jiffies);1257 1258	return ret;1259}1260 1261static const struct of_device_id of_max77693_muic_dt_match[] = {1262	{ .compatible = "maxim,max77693-muic", },1263	{ /* sentinel */ },1264};1265MODULE_DEVICE_TABLE(of, of_max77693_muic_dt_match);1266 1267static struct platform_driver max77693_muic_driver = {1268	.driver		= {1269		.name	= DEV_NAME,1270		.of_match_table = of_max77693_muic_dt_match,1271	},1272	.probe		= max77693_muic_probe,1273};1274 1275module_platform_driver(max77693_muic_driver);1276 1277MODULE_DESCRIPTION("Maxim MAX77693 Extcon driver");1278MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");1279MODULE_LICENSE("GPL");1280MODULE_ALIAS("platform:max77693-muic");1281