cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

extcon-max14577.c (22107B)


      1// SPDX-License-Identifier: GPL-2.0+
      2//
      3// extcon-max14577.c - MAX14577/77836 extcon driver to support MUIC
      4//
      5// Copyright (C) 2013,2014 Samsung Electronics
      6// Chanwoo Choi <cw00.choi@samsung.com>
      7// Krzysztof Kozlowski <krzk@kernel.org>
      8
      9#include <linux/devm-helpers.h>
     10#include <linux/kernel.h>
     11#include <linux/module.h>
     12#include <linux/i2c.h>
     13#include <linux/interrupt.h>
     14#include <linux/platform_device.h>
     15#include <linux/mfd/max14577.h>
     16#include <linux/mfd/max14577-private.h>
     17#include <linux/extcon-provider.h>
     18
     19#define	DELAY_MS_DEFAULT		17000		/* unit: millisecond */
     20
     21enum max14577_muic_adc_debounce_time {
     22	ADC_DEBOUNCE_TIME_5MS = 0,
     23	ADC_DEBOUNCE_TIME_10MS,
     24	ADC_DEBOUNCE_TIME_25MS,
     25	ADC_DEBOUNCE_TIME_38_62MS,
     26};
     27
     28enum max14577_muic_status {
     29	MAX14577_MUIC_STATUS1 = 0,
     30	MAX14577_MUIC_STATUS2 = 1,
     31	MAX14577_MUIC_STATUS_END,
     32};
     33
     34/**
     35 * struct max14577_muic_irq
     36 * @irq: the index of irq list of MUIC device.
     37 * @name: the name of irq.
     38 * @virq: the virtual irq to use irq domain
     39 */
     40struct max14577_muic_irq {
     41	unsigned int irq;
     42	const char *name;
     43	unsigned int virq;
     44};
     45
     46static struct max14577_muic_irq max14577_muic_irqs[] = {
     47	{ MAX14577_IRQ_INT1_ADC,	"muic-ADC" },
     48	{ MAX14577_IRQ_INT1_ADCLOW,	"muic-ADCLOW" },
     49	{ MAX14577_IRQ_INT1_ADCERR,	"muic-ADCError" },
     50	{ MAX14577_IRQ_INT2_CHGTYP,	"muic-CHGTYP" },
     51	{ MAX14577_IRQ_INT2_CHGDETRUN,	"muic-CHGDETRUN" },
     52	{ MAX14577_IRQ_INT2_DCDTMR,	"muic-DCDTMR" },
     53	{ MAX14577_IRQ_INT2_DBCHG,	"muic-DBCHG" },
     54	{ MAX14577_IRQ_INT2_VBVOLT,	"muic-VBVOLT" },
     55};
     56
     57static struct max14577_muic_irq max77836_muic_irqs[] = {
     58	{ MAX14577_IRQ_INT1_ADC,	"muic-ADC" },
     59	{ MAX14577_IRQ_INT1_ADCLOW,	"muic-ADCLOW" },
     60	{ MAX14577_IRQ_INT1_ADCERR,	"muic-ADCError" },
     61	{ MAX77836_IRQ_INT1_ADC1K,	"muic-ADC1K" },
     62	{ MAX14577_IRQ_INT2_CHGTYP,	"muic-CHGTYP" },
     63	{ MAX14577_IRQ_INT2_CHGDETRUN,	"muic-CHGDETRUN" },
     64	{ MAX14577_IRQ_INT2_DCDTMR,	"muic-DCDTMR" },
     65	{ MAX14577_IRQ_INT2_DBCHG,	"muic-DBCHG" },
     66	{ MAX14577_IRQ_INT2_VBVOLT,	"muic-VBVOLT" },
     67	{ MAX77836_IRQ_INT2_VIDRM,	"muic-VIDRM" },
     68};
     69
     70struct max14577_muic_info {
     71	struct device *dev;
     72	struct max14577 *max14577;
     73	struct extcon_dev *edev;
     74	int prev_cable_type;
     75	int prev_chg_type;
     76	u8 status[MAX14577_MUIC_STATUS_END];
     77
     78	struct max14577_muic_irq *muic_irqs;
     79	unsigned int muic_irqs_num;
     80	bool irq_adc;
     81	bool irq_chg;
     82	struct work_struct irq_work;
     83	struct mutex mutex;
     84
     85	/*
     86	 * Use delayed workqueue to detect cable state and then
     87	 * notify cable state to notifiee/platform through uevent.
     88	 * After completing the booting of platform, the extcon provider
     89	 * driver should notify cable state to upper layer.
     90	 */
     91	struct delayed_work wq_detcable;
     92
     93	/*
     94	 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
     95	 * h/w path of COMP2/COMN1 on CONTROL1 register.
     96	 */
     97	int path_usb;
     98	int path_uart;
     99};
    100
    101enum max14577_muic_cable_group {
    102	MAX14577_CABLE_GROUP_ADC = 0,
    103	MAX14577_CABLE_GROUP_CHG,
    104};
    105
    106/* Define supported accessory type */
    107enum max14577_muic_acc_type {
    108	MAX14577_MUIC_ADC_GROUND = 0x0,
    109	MAX14577_MUIC_ADC_SEND_END_BUTTON,
    110	MAX14577_MUIC_ADC_REMOTE_S1_BUTTON,
    111	MAX14577_MUIC_ADC_REMOTE_S2_BUTTON,
    112	MAX14577_MUIC_ADC_REMOTE_S3_BUTTON,
    113	MAX14577_MUIC_ADC_REMOTE_S4_BUTTON,
    114	MAX14577_MUIC_ADC_REMOTE_S5_BUTTON,
    115	MAX14577_MUIC_ADC_REMOTE_S6_BUTTON,
    116	MAX14577_MUIC_ADC_REMOTE_S7_BUTTON,
    117	MAX14577_MUIC_ADC_REMOTE_S8_BUTTON,
    118	MAX14577_MUIC_ADC_REMOTE_S9_BUTTON,
    119	MAX14577_MUIC_ADC_REMOTE_S10_BUTTON,
    120	MAX14577_MUIC_ADC_REMOTE_S11_BUTTON,
    121	MAX14577_MUIC_ADC_REMOTE_S12_BUTTON,
    122	MAX14577_MUIC_ADC_RESERVED_ACC_1,
    123	MAX14577_MUIC_ADC_RESERVED_ACC_2,
    124	MAX14577_MUIC_ADC_RESERVED_ACC_3,
    125	MAX14577_MUIC_ADC_RESERVED_ACC_4,
    126	MAX14577_MUIC_ADC_RESERVED_ACC_5,
    127	MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE2,
    128	MAX14577_MUIC_ADC_PHONE_POWERED_DEV,
    129	MAX14577_MUIC_ADC_TTY_CONVERTER,
    130	MAX14577_MUIC_ADC_UART_CABLE,
    131	MAX14577_MUIC_ADC_CEA936A_TYPE1_CHG,
    132	MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF,
    133	MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON,
    134	MAX14577_MUIC_ADC_AV_CABLE_NOLOAD,
    135	MAX14577_MUIC_ADC_CEA936A_TYPE2_CHG,
    136	MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF,
    137	MAX14577_MUIC_ADC_FACTORY_MODE_UART_ON,
    138	MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE1, /* with Remote and Simple Ctrl */
    139	MAX14577_MUIC_ADC_OPEN,
    140};
    141
    142static const unsigned int max14577_extcon_cable[] = {
    143	EXTCON_USB,
    144	EXTCON_CHG_USB_SDP,
    145	EXTCON_CHG_USB_DCP,
    146	EXTCON_CHG_USB_FAST,
    147	EXTCON_CHG_USB_SLOW,
    148	EXTCON_CHG_USB_CDP,
    149	EXTCON_JIG,
    150	EXTCON_NONE,
    151};
    152
    153/*
    154 * max14577_muic_set_debounce_time - Set the debounce time of ADC
    155 * @info: the instance including private data of max14577 MUIC
    156 * @time: the debounce time of ADC
    157 */
    158static int max14577_muic_set_debounce_time(struct max14577_muic_info *info,
    159		enum max14577_muic_adc_debounce_time time)
    160{
    161	u8 ret;
    162
    163	switch (time) {
    164	case ADC_DEBOUNCE_TIME_5MS:
    165	case ADC_DEBOUNCE_TIME_10MS:
    166	case ADC_DEBOUNCE_TIME_25MS:
    167	case ADC_DEBOUNCE_TIME_38_62MS:
    168		ret = max14577_update_reg(info->max14577->regmap,
    169					  MAX14577_MUIC_REG_CONTROL3,
    170					  CTRL3_ADCDBSET_MASK,
    171					  time << CTRL3_ADCDBSET_SHIFT);
    172		if (ret) {
    173			dev_err(info->dev, "failed to set ADC debounce time\n");
    174			return ret;
    175		}
    176		break;
    177	default:
    178		dev_err(info->dev, "invalid ADC debounce time\n");
    179		return -EINVAL;
    180	}
    181
    182	return 0;
    183};
    184
    185/*
    186 * max14577_muic_set_path - Set hardware line according to attached cable
    187 * @info: the instance including private data of max14577 MUIC
    188 * @value: the path according to attached cable
    189 * @attached: the state of cable (true:attached, false:detached)
    190 *
    191 * The max14577 MUIC device share outside H/W line among a varity of cables
    192 * so, this function set internal path of H/W line according to the type of
    193 * attached cable.
    194 */
    195static int max14577_muic_set_path(struct max14577_muic_info *info,
    196		u8 val, bool attached)
    197{
    198	u8 ctrl1, ctrl2 = 0;
    199	int ret;
    200
    201	/* Set open state to path before changing hw path */
    202	ret = max14577_update_reg(info->max14577->regmap,
    203				MAX14577_MUIC_REG_CONTROL1,
    204				CLEAR_IDBEN_MICEN_MASK, CTRL1_SW_OPEN);
    205	if (ret < 0) {
    206		dev_err(info->dev, "failed to update MUIC register\n");
    207		return ret;
    208	}
    209
    210	if (attached)
    211		ctrl1 = val;
    212	else
    213		ctrl1 = CTRL1_SW_OPEN;
    214
    215	ret = max14577_update_reg(info->max14577->regmap,
    216				MAX14577_MUIC_REG_CONTROL1,
    217				CLEAR_IDBEN_MICEN_MASK, ctrl1);
    218	if (ret < 0) {
    219		dev_err(info->dev, "failed to update MUIC register\n");
    220		return ret;
    221	}
    222
    223	if (attached)
    224		ctrl2 |= CTRL2_CPEN_MASK;	/* LowPwr=0, CPEn=1 */
    225	else
    226		ctrl2 |= CTRL2_LOWPWR_MASK;	/* LowPwr=1, CPEn=0 */
    227
    228	ret = max14577_update_reg(info->max14577->regmap,
    229			MAX14577_REG_CONTROL2,
    230			CTRL2_LOWPWR_MASK | CTRL2_CPEN_MASK, ctrl2);
    231	if (ret < 0) {
    232		dev_err(info->dev, "failed to update MUIC register\n");
    233		return ret;
    234	}
    235
    236	dev_dbg(info->dev,
    237		"CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
    238		ctrl1, ctrl2, attached ? "attached" : "detached");
    239
    240	return 0;
    241}
    242
    243/*
    244 * max14577_muic_get_cable_type - Return cable type and check cable state
    245 * @info: the instance including private data of max14577 MUIC
    246 * @group: the path according to attached cable
    247 * @attached: store cable state and return
    248 *
    249 * This function check the cable state either attached or detached,
    250 * and then divide precise type of cable according to cable group.
    251 *	- max14577_CABLE_GROUP_ADC
    252 *	- max14577_CABLE_GROUP_CHG
    253 */
    254static int max14577_muic_get_cable_type(struct max14577_muic_info *info,
    255		enum max14577_muic_cable_group group, bool *attached)
    256{
    257	int cable_type = 0;
    258	int adc;
    259	int chg_type;
    260
    261	switch (group) {
    262	case MAX14577_CABLE_GROUP_ADC:
    263		/*
    264		 * Read ADC value to check cable type and decide cable state
    265		 * according to cable type
    266		 */
    267		adc = info->status[MAX14577_MUIC_STATUS1] & STATUS1_ADC_MASK;
    268		adc >>= STATUS1_ADC_SHIFT;
    269
    270		/*
    271		 * Check current cable state/cable type and store cable type
    272		 * (info->prev_cable_type) for handling cable when cable is
    273		 * detached.
    274		 */
    275		if (adc == MAX14577_MUIC_ADC_OPEN) {
    276			*attached = false;
    277
    278			cable_type = info->prev_cable_type;
    279			info->prev_cable_type = MAX14577_MUIC_ADC_OPEN;
    280		} else {
    281			*attached = true;
    282
    283			cable_type = info->prev_cable_type = adc;
    284		}
    285		break;
    286	case MAX14577_CABLE_GROUP_CHG:
    287		/*
    288		 * Read charger type to check cable type and decide cable state
    289		 * according to type of charger cable.
    290		 */
    291		chg_type = info->status[MAX14577_MUIC_STATUS2] &
    292			STATUS2_CHGTYP_MASK;
    293		chg_type >>= STATUS2_CHGTYP_SHIFT;
    294
    295		if (chg_type == MAX14577_CHARGER_TYPE_NONE) {
    296			*attached = false;
    297
    298			cable_type = info->prev_chg_type;
    299			info->prev_chg_type = MAX14577_CHARGER_TYPE_NONE;
    300		} else {
    301			*attached = true;
    302
    303			/*
    304			 * Check current cable state/cable type and store cable
    305			 * type(info->prev_chg_type) for handling cable when
    306			 * charger cable is detached.
    307			 */
    308			cable_type = info->prev_chg_type = chg_type;
    309		}
    310
    311		break;
    312	default:
    313		dev_err(info->dev, "Unknown cable group (%d)\n", group);
    314		cable_type = -EINVAL;
    315		break;
    316	}
    317
    318	return cable_type;
    319}
    320
    321static int max14577_muic_jig_handler(struct max14577_muic_info *info,
    322		int cable_type, bool attached)
    323{
    324	int ret = 0;
    325	u8 path = CTRL1_SW_OPEN;
    326
    327	dev_dbg(info->dev,
    328		"external connector is %s (adc:0x%02x)\n",
    329		attached ? "attached" : "detached", cable_type);
    330
    331	switch (cable_type) {
    332	case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF:	/* ADC_JIG_USB_OFF */
    333	case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON:	/* ADC_JIG_USB_ON */
    334		/* PATH:AP_USB */
    335		path = CTRL1_SW_USB;
    336		break;
    337	case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF:	/* ADC_JIG_UART_OFF */
    338		/* PATH:AP_UART */
    339		path = CTRL1_SW_UART;
    340		break;
    341	default:
    342		dev_err(info->dev, "failed to detect %s jig cable\n",
    343			attached ? "attached" : "detached");
    344		return -EINVAL;
    345	}
    346
    347	ret = max14577_muic_set_path(info, path, attached);
    348	if (ret < 0)
    349		return ret;
    350
    351	extcon_set_state_sync(info->edev, EXTCON_JIG, attached);
    352
    353	return 0;
    354}
    355
    356static int max14577_muic_adc_handler(struct max14577_muic_info *info)
    357{
    358	int cable_type;
    359	bool attached;
    360	int ret = 0;
    361
    362	/* Check accessory state which is either detached or attached */
    363	cable_type = max14577_muic_get_cable_type(info,
    364				MAX14577_CABLE_GROUP_ADC, &attached);
    365
    366	dev_dbg(info->dev,
    367		"external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
    368		attached ? "attached" : "detached", cable_type,
    369		info->prev_cable_type);
    370
    371	switch (cable_type) {
    372	case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF:
    373	case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON:
    374	case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF:
    375		/* JIG */
    376		ret = max14577_muic_jig_handler(info, cable_type, attached);
    377		if (ret < 0)
    378			return ret;
    379		break;
    380	case MAX14577_MUIC_ADC_GROUND:
    381	case MAX14577_MUIC_ADC_SEND_END_BUTTON:
    382	case MAX14577_MUIC_ADC_REMOTE_S1_BUTTON:
    383	case MAX14577_MUIC_ADC_REMOTE_S2_BUTTON:
    384	case MAX14577_MUIC_ADC_REMOTE_S3_BUTTON:
    385	case MAX14577_MUIC_ADC_REMOTE_S4_BUTTON:
    386	case MAX14577_MUIC_ADC_REMOTE_S5_BUTTON:
    387	case MAX14577_MUIC_ADC_REMOTE_S6_BUTTON:
    388	case MAX14577_MUIC_ADC_REMOTE_S7_BUTTON:
    389	case MAX14577_MUIC_ADC_REMOTE_S8_BUTTON:
    390	case MAX14577_MUIC_ADC_REMOTE_S9_BUTTON:
    391	case MAX14577_MUIC_ADC_REMOTE_S10_BUTTON:
    392	case MAX14577_MUIC_ADC_REMOTE_S11_BUTTON:
    393	case MAX14577_MUIC_ADC_REMOTE_S12_BUTTON:
    394	case MAX14577_MUIC_ADC_RESERVED_ACC_1:
    395	case MAX14577_MUIC_ADC_RESERVED_ACC_2:
    396	case MAX14577_MUIC_ADC_RESERVED_ACC_3:
    397	case MAX14577_MUIC_ADC_RESERVED_ACC_4:
    398	case MAX14577_MUIC_ADC_RESERVED_ACC_5:
    399	case MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE2:
    400	case MAX14577_MUIC_ADC_PHONE_POWERED_DEV:
    401	case MAX14577_MUIC_ADC_TTY_CONVERTER:
    402	case MAX14577_MUIC_ADC_UART_CABLE:
    403	case MAX14577_MUIC_ADC_CEA936A_TYPE1_CHG:
    404	case MAX14577_MUIC_ADC_AV_CABLE_NOLOAD:
    405	case MAX14577_MUIC_ADC_CEA936A_TYPE2_CHG:
    406	case MAX14577_MUIC_ADC_FACTORY_MODE_UART_ON:
    407	case MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE1:
    408		/*
    409		 * This accessory isn't used in general case if it is specially
    410		 * needed to detect additional accessory, should implement
    411		 * proper operation when this accessory is attached/detached.
    412		 */
    413		dev_info(info->dev,
    414			"accessory is %s but it isn't used (adc:0x%x)\n",
    415			attached ? "attached" : "detached", cable_type);
    416		return -EAGAIN;
    417	default:
    418		dev_err(info->dev,
    419			"failed to detect %s accessory (adc:0x%x)\n",
    420			attached ? "attached" : "detached", cable_type);
    421		return -EINVAL;
    422	}
    423
    424	return 0;
    425}
    426
    427static int max14577_muic_chg_handler(struct max14577_muic_info *info)
    428{
    429	int chg_type;
    430	bool attached;
    431	int ret = 0;
    432
    433	chg_type = max14577_muic_get_cable_type(info,
    434				MAX14577_CABLE_GROUP_CHG, &attached);
    435
    436	dev_dbg(info->dev,
    437		"external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
    438			attached ? "attached" : "detached",
    439			chg_type, info->prev_chg_type);
    440
    441	switch (chg_type) {
    442	case MAX14577_CHARGER_TYPE_USB:
    443		/* PATH:AP_USB */
    444		ret = max14577_muic_set_path(info, info->path_usb, attached);
    445		if (ret < 0)
    446			return ret;
    447
    448		extcon_set_state_sync(info->edev, EXTCON_USB, attached);
    449		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
    450					attached);
    451		break;
    452	case MAX14577_CHARGER_TYPE_DEDICATED_CHG:
    453		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,
    454					attached);
    455		break;
    456	case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT:
    457		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP,
    458					attached);
    459		break;
    460	case MAX14577_CHARGER_TYPE_SPECIAL_500MA:
    461		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW,
    462					attached);
    463		break;
    464	case MAX14577_CHARGER_TYPE_SPECIAL_1A:
    465		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST,
    466					attached);
    467		break;
    468	case MAX14577_CHARGER_TYPE_NONE:
    469	case MAX14577_CHARGER_TYPE_DEAD_BATTERY:
    470		break;
    471	default:
    472		dev_err(info->dev,
    473			"failed to detect %s accessory (chg_type:0x%x)\n",
    474			attached ? "attached" : "detached", chg_type);
    475		return -EINVAL;
    476	}
    477
    478	return 0;
    479}
    480
    481static void max14577_muic_irq_work(struct work_struct *work)
    482{
    483	struct max14577_muic_info *info = container_of(work,
    484			struct max14577_muic_info, irq_work);
    485	int ret = 0;
    486
    487	if (!info->edev)
    488		return;
    489
    490	mutex_lock(&info->mutex);
    491
    492	ret = max14577_bulk_read(info->max14577->regmap,
    493			MAX14577_MUIC_REG_STATUS1, info->status, 2);
    494	if (ret) {
    495		dev_err(info->dev, "failed to read MUIC register\n");
    496		mutex_unlock(&info->mutex);
    497		return;
    498	}
    499
    500	if (info->irq_adc) {
    501		ret = max14577_muic_adc_handler(info);
    502		info->irq_adc = false;
    503	}
    504	if (info->irq_chg) {
    505		ret = max14577_muic_chg_handler(info);
    506		info->irq_chg = false;
    507	}
    508
    509	if (ret < 0)
    510		dev_err(info->dev, "failed to handle MUIC interrupt\n");
    511
    512	mutex_unlock(&info->mutex);
    513}
    514
    515/*
    516 * Sets irq_adc or irq_chg in max14577_muic_info and returns 1.
    517 * Returns 0 if irq_type does not match registered IRQ for this device type.
    518 */
    519static int max14577_parse_irq(struct max14577_muic_info *info, int irq_type)
    520{
    521	switch (irq_type) {
    522	case MAX14577_IRQ_INT1_ADC:
    523	case MAX14577_IRQ_INT1_ADCLOW:
    524	case MAX14577_IRQ_INT1_ADCERR:
    525		/*
    526		 * Handle all of accessory except for
    527		 * type of charger accessory.
    528		 */
    529		info->irq_adc = true;
    530		return 1;
    531	case MAX14577_IRQ_INT2_CHGTYP:
    532	case MAX14577_IRQ_INT2_CHGDETRUN:
    533	case MAX14577_IRQ_INT2_DCDTMR:
    534	case MAX14577_IRQ_INT2_DBCHG:
    535	case MAX14577_IRQ_INT2_VBVOLT:
    536		/* Handle charger accessory */
    537		info->irq_chg = true;
    538		return 1;
    539	default:
    540		return 0;
    541	}
    542}
    543
    544/*
    545 * Sets irq_adc or irq_chg in max14577_muic_info and returns 1.
    546 * Returns 0 if irq_type does not match registered IRQ for this device type.
    547 */
    548static int max77836_parse_irq(struct max14577_muic_info *info, int irq_type)
    549{
    550	/* First check common max14577 interrupts */
    551	if (max14577_parse_irq(info, irq_type))
    552		return 1;
    553
    554	switch (irq_type) {
    555	case MAX77836_IRQ_INT1_ADC1K:
    556		info->irq_adc = true;
    557		return 1;
    558	case MAX77836_IRQ_INT2_VIDRM:
    559		/* Handle charger accessory */
    560		info->irq_chg = true;
    561		return 1;
    562	default:
    563		return 0;
    564	}
    565}
    566
    567static irqreturn_t max14577_muic_irq_handler(int irq, void *data)
    568{
    569	struct max14577_muic_info *info = data;
    570	int i, irq_type = -1;
    571	bool irq_parsed;
    572
    573	/*
    574	 * We may be called multiple times for different nested IRQ-s.
    575	 * Including changes in INT1_ADC and INT2_CGHTYP at once.
    576	 * However we only need to know whether it was ADC, charger
    577	 * or both interrupts so decode IRQ and turn on proper flags.
    578	 */
    579	for (i = 0; i < info->muic_irqs_num; i++)
    580		if (irq == info->muic_irqs[i].virq)
    581			irq_type = info->muic_irqs[i].irq;
    582
    583	switch (info->max14577->dev_type) {
    584	case MAXIM_DEVICE_TYPE_MAX77836:
    585		irq_parsed = max77836_parse_irq(info, irq_type);
    586		break;
    587	case MAXIM_DEVICE_TYPE_MAX14577:
    588	default:
    589		irq_parsed = max14577_parse_irq(info, irq_type);
    590		break;
    591	}
    592
    593	if (!irq_parsed) {
    594		dev_err(info->dev, "muic interrupt: irq %d occurred, skipped\n",
    595				irq_type);
    596		return IRQ_HANDLED;
    597	}
    598	schedule_work(&info->irq_work);
    599
    600	return IRQ_HANDLED;
    601}
    602
    603static int max14577_muic_detect_accessory(struct max14577_muic_info *info)
    604{
    605	int ret = 0;
    606	int adc;
    607	int chg_type;
    608	bool attached;
    609
    610	mutex_lock(&info->mutex);
    611
    612	/* Read STATUSx register to detect accessory */
    613	ret = max14577_bulk_read(info->max14577->regmap,
    614			MAX14577_MUIC_REG_STATUS1, info->status, 2);
    615	if (ret) {
    616		dev_err(info->dev, "failed to read MUIC register\n");
    617		mutex_unlock(&info->mutex);
    618		return ret;
    619	}
    620
    621	adc = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_ADC,
    622					&attached);
    623	if (attached && adc != MAX14577_MUIC_ADC_OPEN) {
    624		ret = max14577_muic_adc_handler(info);
    625		if (ret < 0) {
    626			dev_err(info->dev, "Cannot detect accessory\n");
    627			mutex_unlock(&info->mutex);
    628			return ret;
    629		}
    630	}
    631
    632	chg_type = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_CHG,
    633					&attached);
    634	if (attached && chg_type != MAX14577_CHARGER_TYPE_NONE) {
    635		ret = max14577_muic_chg_handler(info);
    636		if (ret < 0) {
    637			dev_err(info->dev, "Cannot detect charger accessory\n");
    638			mutex_unlock(&info->mutex);
    639			return ret;
    640		}
    641	}
    642
    643	mutex_unlock(&info->mutex);
    644
    645	return 0;
    646}
    647
    648static void max14577_muic_detect_cable_wq(struct work_struct *work)
    649{
    650	struct max14577_muic_info *info = container_of(to_delayed_work(work),
    651				struct max14577_muic_info, wq_detcable);
    652
    653	max14577_muic_detect_accessory(info);
    654}
    655
    656static int max14577_muic_probe(struct platform_device *pdev)
    657{
    658	struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
    659	struct max14577_muic_info *info;
    660	int delay_jiffies;
    661	int cable_type;
    662	bool attached;
    663	int ret;
    664	int i;
    665	u8 id;
    666
    667	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
    668	if (!info)
    669		return -ENOMEM;
    670
    671	info->dev = &pdev->dev;
    672	info->max14577 = max14577;
    673
    674	platform_set_drvdata(pdev, info);
    675	mutex_init(&info->mutex);
    676
    677	ret = devm_work_autocancel(&pdev->dev, &info->irq_work,
    678				   max14577_muic_irq_work);
    679	if (ret)
    680		return ret;
    681
    682	switch (max14577->dev_type) {
    683	case MAXIM_DEVICE_TYPE_MAX77836:
    684		info->muic_irqs = max77836_muic_irqs;
    685		info->muic_irqs_num = ARRAY_SIZE(max77836_muic_irqs);
    686		break;
    687	case MAXIM_DEVICE_TYPE_MAX14577:
    688	default:
    689		info->muic_irqs = max14577_muic_irqs;
    690		info->muic_irqs_num = ARRAY_SIZE(max14577_muic_irqs);
    691	}
    692
    693	/* Support irq domain for max14577 MUIC device */
    694	for (i = 0; i < info->muic_irqs_num; i++) {
    695		struct max14577_muic_irq *muic_irq = &info->muic_irqs[i];
    696		int virq = 0;
    697
    698		virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq);
    699		if (virq <= 0)
    700			return -EINVAL;
    701		muic_irq->virq = virq;
    702
    703		ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
    704				max14577_muic_irq_handler,
    705				IRQF_NO_SUSPEND,
    706				muic_irq->name, info);
    707		if (ret) {
    708			dev_err(&pdev->dev,
    709				"failed: irq request (IRQ: %d, error :%d)\n",
    710				muic_irq->irq, ret);
    711			return ret;
    712		}
    713	}
    714
    715	/* Initialize extcon device */
    716	info->edev = devm_extcon_dev_allocate(&pdev->dev,
    717					      max14577_extcon_cable);
    718	if (IS_ERR(info->edev)) {
    719		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
    720		return PTR_ERR(info->edev);
    721	}
    722
    723	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
    724	if (ret) {
    725		dev_err(&pdev->dev, "failed to register extcon device\n");
    726		return ret;
    727	}
    728
    729	/* Default h/w line path */
    730	info->path_usb = CTRL1_SW_USB;
    731	info->path_uart = CTRL1_SW_UART;
    732	delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
    733
    734	/* Set initial path for UART when JIG is connected to get serial logs */
    735	ret = max14577_bulk_read(info->max14577->regmap,
    736			MAX14577_MUIC_REG_STATUS1, info->status, 2);
    737	if (ret) {
    738		dev_err(info->dev, "Cannot read STATUS registers\n");
    739		return ret;
    740	}
    741	cable_type = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_ADC,
    742					 &attached);
    743	if (attached && cable_type == MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF)
    744		max14577_muic_set_path(info, info->path_uart, true);
    745
    746	/* Check revision number of MUIC device*/
    747	ret = max14577_read_reg(info->max14577->regmap,
    748			MAX14577_REG_DEVICEID, &id);
    749	if (ret < 0) {
    750		dev_err(&pdev->dev, "failed to read revision number\n");
    751		return ret;
    752	}
    753	dev_info(info->dev, "device ID : 0x%x\n", id);
    754
    755	/* Set ADC debounce time */
    756	max14577_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);
    757
    758	/*
    759	 * Detect accessory after completing the initialization of platform
    760	 *
    761	 * - Use delayed workqueue to detect cable state and then
    762	 * notify cable state to notifiee/platform through uevent.
    763	 * After completing the booting of platform, the extcon provider
    764	 * driver should notify cable state to upper layer.
    765	 */
    766	INIT_DELAYED_WORK(&info->wq_detcable, max14577_muic_detect_cable_wq);
    767	queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
    768			delay_jiffies);
    769
    770	return ret;
    771}
    772
    773static const struct platform_device_id max14577_muic_id[] = {
    774	{ "max14577-muic", MAXIM_DEVICE_TYPE_MAX14577, },
    775	{ "max77836-muic", MAXIM_DEVICE_TYPE_MAX77836, },
    776	{ }
    777};
    778MODULE_DEVICE_TABLE(platform, max14577_muic_id);
    779
    780static const struct of_device_id of_max14577_muic_dt_match[] = {
    781	{ .compatible = "maxim,max14577-muic",
    782	  .data = (void *)MAXIM_DEVICE_TYPE_MAX14577, },
    783	{ .compatible = "maxim,max77836-muic",
    784	  .data = (void *)MAXIM_DEVICE_TYPE_MAX77836, },
    785	{ },
    786};
    787MODULE_DEVICE_TABLE(of, of_max14577_muic_dt_match);
    788
    789static struct platform_driver max14577_muic_driver = {
    790	.driver		= {
    791		.name	= "max14577-muic",
    792		.of_match_table = of_max14577_muic_dt_match,
    793	},
    794	.probe		= max14577_muic_probe,
    795	.id_table	= max14577_muic_id,
    796};
    797
    798module_platform_driver(max14577_muic_driver);
    799
    800MODULE_DESCRIPTION("Maxim 14577/77836 Extcon driver");
    801MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <krzk@kernel.org>");
    802MODULE_LICENSE("GPL");
    803MODULE_ALIAS("platform:extcon-max14577");