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-rt8973a.c (19265B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * extcon-rt8973a.c - Richtek RT8973A extcon driver to support USB switches
      4 *
      5 * Copyright (c) 2014 Samsung Electronics Co., Ltd
      6 * Author: Chanwoo Choi <cw00.choi@samsung.com>
      7 */
      8
      9#include <linux/err.h>
     10#include <linux/i2c.h>
     11#include <linux/input.h>
     12#include <linux/interrupt.h>
     13#include <linux/irqdomain.h>
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/platform_device.h>
     17#include <linux/regmap.h>
     18#include <linux/slab.h>
     19#include <linux/extcon-provider.h>
     20
     21#include "extcon-rt8973a.h"
     22
     23#define	DELAY_MS_DEFAULT		20000	/* unit: millisecond */
     24
     25struct muic_irq {
     26	unsigned int irq;
     27	const char *name;
     28	unsigned int virq;
     29};
     30
     31struct reg_data {
     32	u8 reg;
     33	u8 mask;
     34	u8 val;
     35	bool invert;
     36};
     37
     38struct rt8973a_muic_info {
     39	struct device *dev;
     40	struct extcon_dev *edev;
     41
     42	struct i2c_client *i2c;
     43	struct regmap *regmap;
     44
     45	struct regmap_irq_chip_data *irq_data;
     46	struct muic_irq *muic_irqs;
     47	unsigned int num_muic_irqs;
     48	int irq;
     49	bool irq_attach;
     50	bool irq_detach;
     51	bool irq_ovp;
     52	bool irq_otp;
     53	struct work_struct irq_work;
     54
     55	struct reg_data *reg_data;
     56	unsigned int num_reg_data;
     57	bool auto_config;
     58
     59	struct mutex mutex;
     60
     61	/*
     62	 * Use delayed workqueue to detect cable state and then
     63	 * notify cable state to notifiee/platform through uevent.
     64	 * After completing the booting of platform, the extcon provider
     65	 * driver should notify cable state to upper layer.
     66	 */
     67	struct delayed_work wq_detcable;
     68};
     69
     70/* Default value of RT8973A register to bring up MUIC device. */
     71static struct reg_data rt8973a_reg_data[] = {
     72	{
     73		.reg = RT8973A_REG_CONTROL1,
     74		.mask = RT8973A_REG_CONTROL1_ADC_EN_MASK
     75			| RT8973A_REG_CONTROL1_USB_CHD_EN_MASK
     76			| RT8973A_REG_CONTROL1_CHGTYP_MASK
     77			| RT8973A_REG_CONTROL1_SWITCH_OPEN_MASK
     78			| RT8973A_REG_CONTROL1_AUTO_CONFIG_MASK
     79			| RT8973A_REG_CONTROL1_INTM_MASK,
     80		.val = RT8973A_REG_CONTROL1_ADC_EN_MASK
     81			| RT8973A_REG_CONTROL1_USB_CHD_EN_MASK
     82			| RT8973A_REG_CONTROL1_CHGTYP_MASK,
     83		.invert = false,
     84	},
     85	{ /* sentinel */ }
     86};
     87
     88/* List of detectable cables */
     89static const unsigned int rt8973a_extcon_cable[] = {
     90	EXTCON_USB,
     91	EXTCON_USB_HOST,
     92	EXTCON_CHG_USB_SDP,
     93	EXTCON_CHG_USB_DCP,
     94	EXTCON_JIG,
     95	EXTCON_NONE,
     96};
     97
     98/* Define OVP (Over Voltage Protection), OTP (Over Temperature Protection) */
     99enum rt8973a_event_type {
    100	RT8973A_EVENT_ATTACH = 1,
    101	RT8973A_EVENT_DETACH,
    102	RT8973A_EVENT_OVP,
    103	RT8973A_EVENT_OTP,
    104};
    105
    106/* Define supported accessory type */
    107enum rt8973a_muic_acc_type {
    108	RT8973A_MUIC_ADC_OTG = 0x0,
    109	RT8973A_MUIC_ADC_AUDIO_SEND_END_BUTTON,
    110	RT8973A_MUIC_ADC_AUDIO_REMOTE_S1_BUTTON,
    111	RT8973A_MUIC_ADC_AUDIO_REMOTE_S2_BUTTON,
    112	RT8973A_MUIC_ADC_AUDIO_REMOTE_S3_BUTTON,
    113	RT8973A_MUIC_ADC_AUDIO_REMOTE_S4_BUTTON,
    114	RT8973A_MUIC_ADC_AUDIO_REMOTE_S5_BUTTON,
    115	RT8973A_MUIC_ADC_AUDIO_REMOTE_S6_BUTTON,
    116	RT8973A_MUIC_ADC_AUDIO_REMOTE_S7_BUTTON,
    117	RT8973A_MUIC_ADC_AUDIO_REMOTE_S8_BUTTON,
    118	RT8973A_MUIC_ADC_AUDIO_REMOTE_S9_BUTTON,
    119	RT8973A_MUIC_ADC_AUDIO_REMOTE_S10_BUTTON,
    120	RT8973A_MUIC_ADC_AUDIO_REMOTE_S11_BUTTON,
    121	RT8973A_MUIC_ADC_AUDIO_REMOTE_S12_BUTTON,
    122	RT8973A_MUIC_ADC_RESERVED_ACC_1,
    123	RT8973A_MUIC_ADC_RESERVED_ACC_2,
    124	RT8973A_MUIC_ADC_RESERVED_ACC_3,
    125	RT8973A_MUIC_ADC_RESERVED_ACC_4,
    126	RT8973A_MUIC_ADC_RESERVED_ACC_5,
    127	RT8973A_MUIC_ADC_AUDIO_TYPE2,
    128	RT8973A_MUIC_ADC_PHONE_POWERED_DEV,
    129	RT8973A_MUIC_ADC_UNKNOWN_ACC_1,
    130	RT8973A_MUIC_ADC_UNKNOWN_ACC_2,
    131	RT8973A_MUIC_ADC_TA,
    132	RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB,
    133	RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB,
    134	RT8973A_MUIC_ADC_UNKNOWN_ACC_3,
    135	RT8973A_MUIC_ADC_UNKNOWN_ACC_4,
    136	RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART,
    137	RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART,
    138	RT8973A_MUIC_ADC_UNKNOWN_ACC_5,
    139	RT8973A_MUIC_ADC_OPEN = 0x1f,
    140
    141	/*
    142	 * The below accessories has same ADC value (0x1f).
    143	 * So, Device type1 is used to separate specific accessory.
    144	 */
    145					/* |---------|--ADC| */
    146					/* |    [7:5]|[4:0]| */
    147	RT8973A_MUIC_ADC_USB = 0x3f,	/* |      001|11111| */
    148};
    149
    150/* List of supported interrupt for RT8973A */
    151static struct muic_irq rt8973a_muic_irqs[] = {
    152	{ RT8973A_INT1_ATTACH,		"muic-attach" },
    153	{ RT8973A_INT1_DETACH,		"muic-detach" },
    154	{ RT8973A_INT1_CHGDET,		"muic-chgdet" },
    155	{ RT8973A_INT1_DCD_T,		"muic-dcd-t" },
    156	{ RT8973A_INT1_OVP,		"muic-ovp" },
    157	{ RT8973A_INT1_CONNECT,		"muic-connect" },
    158	{ RT8973A_INT1_ADC_CHG,		"muic-adc-chg" },
    159	{ RT8973A_INT1_OTP,		"muic-otp" },
    160	{ RT8973A_INT2_UVLO,		"muic-uvlo" },
    161	{ RT8973A_INT2_POR,		"muic-por" },
    162	{ RT8973A_INT2_OTP_FET,		"muic-otp-fet" },
    163	{ RT8973A_INT2_OVP_FET,		"muic-ovp-fet" },
    164	{ RT8973A_INT2_OCP_LATCH,	"muic-ocp-latch" },
    165	{ RT8973A_INT2_OCP,		"muic-ocp" },
    166	{ RT8973A_INT2_OVP_OCP,		"muic-ovp-ocp" },
    167};
    168
    169/* Define interrupt list of RT8973A to register regmap_irq */
    170static const struct regmap_irq rt8973a_irqs[] = {
    171	/* INT1 interrupts */
    172	{ .reg_offset = 0, .mask = RT8973A_INT1_ATTACH_MASK, },
    173	{ .reg_offset = 0, .mask = RT8973A_INT1_DETACH_MASK, },
    174	{ .reg_offset = 0, .mask = RT8973A_INT1_CHGDET_MASK, },
    175	{ .reg_offset = 0, .mask = RT8973A_INT1_DCD_T_MASK, },
    176	{ .reg_offset = 0, .mask = RT8973A_INT1_OVP_MASK, },
    177	{ .reg_offset = 0, .mask = RT8973A_INT1_CONNECT_MASK, },
    178	{ .reg_offset = 0, .mask = RT8973A_INT1_ADC_CHG_MASK, },
    179	{ .reg_offset = 0, .mask = RT8973A_INT1_OTP_MASK, },
    180
    181	/* INT2 interrupts */
    182	{ .reg_offset = 1, .mask = RT8973A_INT2_UVLOT_MASK,},
    183	{ .reg_offset = 1, .mask = RT8973A_INT2_POR_MASK, },
    184	{ .reg_offset = 1, .mask = RT8973A_INT2_OTP_FET_MASK, },
    185	{ .reg_offset = 1, .mask = RT8973A_INT2_OVP_FET_MASK, },
    186	{ .reg_offset = 1, .mask = RT8973A_INT2_OCP_LATCH_MASK, },
    187	{ .reg_offset = 1, .mask = RT8973A_INT2_OCP_MASK, },
    188	{ .reg_offset = 1, .mask = RT8973A_INT2_OVP_OCP_MASK, },
    189};
    190
    191static const struct regmap_irq_chip rt8973a_muic_irq_chip = {
    192	.name			= "rt8973a",
    193	.status_base		= RT8973A_REG_INT1,
    194	.mask_base		= RT8973A_REG_INTM1,
    195	.mask_invert		= false,
    196	.num_regs		= 2,
    197	.irqs			= rt8973a_irqs,
    198	.num_irqs		= ARRAY_SIZE(rt8973a_irqs),
    199};
    200
    201/* Define regmap configuration of RT8973A for I2C communication  */
    202static bool rt8973a_muic_volatile_reg(struct device *dev, unsigned int reg)
    203{
    204	switch (reg) {
    205	case RT8973A_REG_INTM1:
    206	case RT8973A_REG_INTM2:
    207		return true;
    208	default:
    209		break;
    210	}
    211	return false;
    212}
    213
    214static const struct regmap_config rt8973a_muic_regmap_config = {
    215	.reg_bits	= 8,
    216	.val_bits	= 8,
    217	.volatile_reg	= rt8973a_muic_volatile_reg,
    218	.max_register	= RT8973A_REG_END,
    219};
    220
    221/* Change DM_CON/DP_CON/VBUSIN switch according to cable type */
    222static int rt8973a_muic_set_path(struct rt8973a_muic_info *info,
    223				unsigned int con_sw, bool attached)
    224{
    225	int ret;
    226
    227	/*
    228	 * Don't need to set h/w path according to cable type
    229	 * if Auto-configuration mode of CONTROL1 register is true.
    230	 */
    231	if (info->auto_config)
    232		return 0;
    233
    234	if (!attached)
    235		con_sw	= DM_DP_SWITCH_UART;
    236
    237	switch (con_sw) {
    238	case DM_DP_SWITCH_OPEN:
    239	case DM_DP_SWITCH_USB:
    240	case DM_DP_SWITCH_UART:
    241		ret = regmap_update_bits(info->regmap, RT8973A_REG_MANUAL_SW1,
    242					RT8973A_REG_MANUAL_SW1_DP_MASK |
    243					RT8973A_REG_MANUAL_SW1_DM_MASK,
    244					con_sw);
    245		if (ret < 0) {
    246			dev_err(info->dev,
    247				"cannot update DM_CON/DP_CON switch\n");
    248			return ret;
    249		}
    250		break;
    251	default:
    252		dev_err(info->dev, "Unknown DM_CON/DP_CON switch type (%d)\n",
    253				con_sw);
    254		return -EINVAL;
    255	}
    256
    257	return 0;
    258}
    259
    260static int rt8973a_muic_get_cable_type(struct rt8973a_muic_info *info)
    261{
    262	unsigned int adc, dev1;
    263	int ret, cable_type;
    264
    265	/* Read ADC value according to external cable or button */
    266	ret = regmap_read(info->regmap, RT8973A_REG_ADC, &adc);
    267	if (ret) {
    268		dev_err(info->dev, "failed to read ADC register\n");
    269		return ret;
    270	}
    271	cable_type = adc & RT8973A_REG_ADC_MASK;
    272
    273	/* Read Device 1 reigster to identify correct cable type */
    274	ret = regmap_read(info->regmap, RT8973A_REG_DEV1, &dev1);
    275	if (ret) {
    276		dev_err(info->dev, "failed to read DEV1 register\n");
    277		return ret;
    278	}
    279
    280	switch (adc) {
    281	case RT8973A_MUIC_ADC_OPEN:
    282		if (dev1 & RT8973A_REG_DEV1_USB_MASK)
    283			cable_type = RT8973A_MUIC_ADC_USB;
    284		else if (dev1 & RT8973A_REG_DEV1_DCPORT_MASK)
    285			cable_type = RT8973A_MUIC_ADC_TA;
    286		else
    287			cable_type = RT8973A_MUIC_ADC_OPEN;
    288		break;
    289	default:
    290		break;
    291	}
    292
    293	return cable_type;
    294}
    295
    296static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info,
    297					enum rt8973a_event_type event)
    298{
    299	static unsigned int prev_cable_type;
    300	unsigned int con_sw = DM_DP_SWITCH_UART;
    301	int ret, cable_type;
    302	unsigned int id;
    303	bool attached = false;
    304
    305	switch (event) {
    306	case RT8973A_EVENT_ATTACH:
    307		cable_type = rt8973a_muic_get_cable_type(info);
    308		attached = true;
    309		break;
    310	case RT8973A_EVENT_DETACH:
    311		cable_type = prev_cable_type;
    312		attached = false;
    313		break;
    314	case RT8973A_EVENT_OVP:
    315	case RT8973A_EVENT_OTP:
    316		dev_warn(info->dev,
    317			"happen Over %s issue. Need to disconnect all cables\n",
    318			event == RT8973A_EVENT_OVP ? "Voltage" : "Temperature");
    319		cable_type = prev_cable_type;
    320		attached = false;
    321		break;
    322	default:
    323		dev_err(info->dev,
    324			"Cannot handle this event (event:%d)\n", event);
    325		return -EINVAL;
    326	}
    327	prev_cable_type = cable_type;
    328
    329	switch (cable_type) {
    330	case RT8973A_MUIC_ADC_OTG:
    331		id = EXTCON_USB_HOST;
    332		con_sw = DM_DP_SWITCH_USB;
    333		break;
    334	case RT8973A_MUIC_ADC_TA:
    335		id = EXTCON_CHG_USB_DCP;
    336		con_sw = DM_DP_SWITCH_OPEN;
    337		break;
    338	case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB:
    339	case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB:
    340		id = EXTCON_JIG;
    341		con_sw = DM_DP_SWITCH_USB;
    342		break;
    343	case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART:
    344	case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART:
    345		id = EXTCON_JIG;
    346		con_sw = DM_DP_SWITCH_UART;
    347		break;
    348	case RT8973A_MUIC_ADC_USB:
    349		id = EXTCON_USB;
    350		con_sw = DM_DP_SWITCH_USB;
    351		break;
    352	case RT8973A_MUIC_ADC_OPEN:
    353		return 0;
    354	case RT8973A_MUIC_ADC_UNKNOWN_ACC_1:
    355	case RT8973A_MUIC_ADC_UNKNOWN_ACC_2:
    356	case RT8973A_MUIC_ADC_UNKNOWN_ACC_3:
    357	case RT8973A_MUIC_ADC_UNKNOWN_ACC_4:
    358	case RT8973A_MUIC_ADC_UNKNOWN_ACC_5:
    359		dev_warn(info->dev,
    360			"Unknown accessory type (adc:0x%x)\n", cable_type);
    361		return 0;
    362	case RT8973A_MUIC_ADC_AUDIO_SEND_END_BUTTON:
    363	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S1_BUTTON:
    364	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S2_BUTTON:
    365	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S3_BUTTON:
    366	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S4_BUTTON:
    367	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S5_BUTTON:
    368	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S6_BUTTON:
    369	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S7_BUTTON:
    370	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S8_BUTTON:
    371	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S9_BUTTON:
    372	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S10_BUTTON:
    373	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S11_BUTTON:
    374	case RT8973A_MUIC_ADC_AUDIO_REMOTE_S12_BUTTON:
    375	case RT8973A_MUIC_ADC_AUDIO_TYPE2:
    376		dev_warn(info->dev,
    377			"Audio device/button type (adc:0x%x)\n", cable_type);
    378		return 0;
    379	case RT8973A_MUIC_ADC_RESERVED_ACC_1:
    380	case RT8973A_MUIC_ADC_RESERVED_ACC_2:
    381	case RT8973A_MUIC_ADC_RESERVED_ACC_3:
    382	case RT8973A_MUIC_ADC_RESERVED_ACC_4:
    383	case RT8973A_MUIC_ADC_RESERVED_ACC_5:
    384	case RT8973A_MUIC_ADC_PHONE_POWERED_DEV:
    385		return 0;
    386	default:
    387		dev_err(info->dev,
    388			"Cannot handle this cable_type (adc:0x%x)\n",
    389			cable_type);
    390		return -EINVAL;
    391	}
    392
    393	/* Change internal hardware path(DM_CON/DP_CON) */
    394	ret = rt8973a_muic_set_path(info, con_sw, attached);
    395	if (ret < 0)
    396		return ret;
    397
    398	/* Change the state of external accessory */
    399	extcon_set_state_sync(info->edev, id, attached);
    400	if (id == EXTCON_USB)
    401		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
    402					attached);
    403
    404	return 0;
    405}
    406
    407static void rt8973a_muic_irq_work(struct work_struct *work)
    408{
    409	struct rt8973a_muic_info *info = container_of(work,
    410			struct rt8973a_muic_info, irq_work);
    411	int ret = 0;
    412
    413	if (!info->edev)
    414		return;
    415
    416	mutex_lock(&info->mutex);
    417
    418	/* Detect attached or detached cables */
    419	if (info->irq_attach) {
    420		ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_ATTACH);
    421		info->irq_attach = false;
    422	}
    423
    424	if (info->irq_detach) {
    425		ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_DETACH);
    426		info->irq_detach = false;
    427	}
    428
    429	if (info->irq_ovp) {
    430		ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_OVP);
    431		info->irq_ovp = false;
    432	}
    433
    434	if (info->irq_otp) {
    435		ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_OTP);
    436		info->irq_otp = false;
    437	}
    438
    439	if (ret < 0)
    440		dev_err(info->dev, "failed to handle MUIC interrupt\n");
    441
    442	mutex_unlock(&info->mutex);
    443}
    444
    445static irqreturn_t rt8973a_muic_irq_handler(int irq, void *data)
    446{
    447	struct rt8973a_muic_info *info = data;
    448	int i, irq_type = -1;
    449
    450	for (i = 0; i < info->num_muic_irqs; i++)
    451		if (irq == info->muic_irqs[i].virq)
    452			irq_type = info->muic_irqs[i].irq;
    453
    454	switch (irq_type) {
    455	case RT8973A_INT1_ATTACH:
    456		info->irq_attach = true;
    457		break;
    458	case RT8973A_INT1_DETACH:
    459		info->irq_detach = true;
    460		break;
    461	case RT8973A_INT1_OVP:
    462		info->irq_ovp = true;
    463		break;
    464	case RT8973A_INT1_OTP:
    465		info->irq_otp = true;
    466		break;
    467	case RT8973A_INT1_CHGDET:
    468	case RT8973A_INT1_DCD_T:
    469	case RT8973A_INT1_CONNECT:
    470	case RT8973A_INT1_ADC_CHG:
    471	case RT8973A_INT2_UVLO:
    472	case RT8973A_INT2_POR:
    473	case RT8973A_INT2_OTP_FET:
    474	case RT8973A_INT2_OVP_FET:
    475	case RT8973A_INT2_OCP_LATCH:
    476	case RT8973A_INT2_OCP:
    477	case RT8973A_INT2_OVP_OCP:
    478	default:
    479		dev_dbg(info->dev,
    480			"Cannot handle this interrupt (%d)\n", irq_type);
    481		break;
    482	}
    483
    484	schedule_work(&info->irq_work);
    485
    486	return IRQ_HANDLED;
    487}
    488
    489static void rt8973a_muic_detect_cable_wq(struct work_struct *work)
    490{
    491	struct rt8973a_muic_info *info = container_of(to_delayed_work(work),
    492				struct rt8973a_muic_info, wq_detcable);
    493	int ret;
    494
    495	/* Notify the state of connector cable or not  */
    496	ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_ATTACH);
    497	if (ret < 0)
    498		dev_warn(info->dev, "failed to detect cable state\n");
    499}
    500
    501static void rt8973a_init_dev_type(struct rt8973a_muic_info *info)
    502{
    503	unsigned int data, vendor_id, version_id;
    504	int i, ret;
    505
    506	/* To test I2C, Print version_id and vendor_id of RT8973A */
    507	ret = regmap_read(info->regmap, RT8973A_REG_DEVICE_ID, &data);
    508	if (ret) {
    509		dev_err(info->dev,
    510			"failed to read DEVICE_ID register: %d\n", ret);
    511		return;
    512	}
    513
    514	vendor_id = ((data & RT8973A_REG_DEVICE_ID_VENDOR_MASK) >>
    515				RT8973A_REG_DEVICE_ID_VENDOR_SHIFT);
    516	version_id = ((data & RT8973A_REG_DEVICE_ID_VERSION_MASK) >>
    517				RT8973A_REG_DEVICE_ID_VERSION_SHIFT);
    518
    519	dev_info(info->dev, "Device type: version: 0x%x, vendor: 0x%x\n",
    520			    version_id, vendor_id);
    521
    522	/* Initiazle the register of RT8973A device to bring-up */
    523	for (i = 0; i < info->num_reg_data; i++) {
    524		u8 reg = info->reg_data[i].reg;
    525		u8 mask = info->reg_data[i].mask;
    526		u8 val = 0;
    527
    528		if (info->reg_data[i].invert)
    529			val = ~info->reg_data[i].val;
    530		else
    531			val = info->reg_data[i].val;
    532
    533		regmap_update_bits(info->regmap, reg, mask, val);
    534	}
    535
    536	/* Check whether RT8973A is auto switching mode or not */
    537	ret = regmap_read(info->regmap, RT8973A_REG_CONTROL1, &data);
    538	if (ret) {
    539		dev_err(info->dev,
    540			"failed to read CONTROL1 register: %d\n", ret);
    541		return;
    542	}
    543
    544	data &= RT8973A_REG_CONTROL1_AUTO_CONFIG_MASK;
    545	if (data) {
    546		info->auto_config = true;
    547		dev_info(info->dev,
    548			"Enable Auto-configuration for internal path\n");
    549	}
    550}
    551
    552static int rt8973a_muic_i2c_probe(struct i2c_client *i2c,
    553				 const struct i2c_device_id *id)
    554{
    555	struct device_node *np = i2c->dev.of_node;
    556	struct rt8973a_muic_info *info;
    557	int i, ret, irq_flags;
    558
    559	if (!np)
    560		return -EINVAL;
    561
    562	info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL);
    563	if (!info)
    564		return -ENOMEM;
    565	i2c_set_clientdata(i2c, info);
    566
    567	info->dev = &i2c->dev;
    568	info->i2c = i2c;
    569	info->irq = i2c->irq;
    570	info->muic_irqs = rt8973a_muic_irqs;
    571	info->num_muic_irqs = ARRAY_SIZE(rt8973a_muic_irqs);
    572	info->reg_data = rt8973a_reg_data;
    573	info->num_reg_data = ARRAY_SIZE(rt8973a_reg_data);
    574
    575	mutex_init(&info->mutex);
    576
    577	INIT_WORK(&info->irq_work, rt8973a_muic_irq_work);
    578
    579	info->regmap = devm_regmap_init_i2c(i2c, &rt8973a_muic_regmap_config);
    580	if (IS_ERR(info->regmap)) {
    581		ret = PTR_ERR(info->regmap);
    582		dev_err(info->dev, "failed to allocate register map: %d\n",
    583				   ret);
    584		return ret;
    585	}
    586
    587	/* Support irq domain for RT8973A MUIC device */
    588	irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED;
    589	ret = regmap_add_irq_chip(info->regmap, info->irq, irq_flags, 0,
    590				  &rt8973a_muic_irq_chip, &info->irq_data);
    591	if (ret != 0) {
    592		dev_err(info->dev, "failed to add irq_chip (irq:%d, err:%d)\n",
    593				    info->irq, ret);
    594		return ret;
    595	}
    596
    597	for (i = 0; i < info->num_muic_irqs; i++) {
    598		struct muic_irq *muic_irq = &info->muic_irqs[i];
    599		int virq = 0;
    600
    601		virq = regmap_irq_get_virq(info->irq_data, muic_irq->irq);
    602		if (virq <= 0)
    603			return -EINVAL;
    604		muic_irq->virq = virq;
    605
    606		ret = devm_request_threaded_irq(info->dev, virq, NULL,
    607						rt8973a_muic_irq_handler,
    608						IRQF_NO_SUSPEND | IRQF_ONESHOT,
    609						muic_irq->name, info);
    610		if (ret) {
    611			dev_err(info->dev,
    612				"failed: irq request (IRQ: %d, error :%d)\n",
    613				muic_irq->irq, ret);
    614			return ret;
    615		}
    616	}
    617
    618	/* Allocate extcon device */
    619	info->edev = devm_extcon_dev_allocate(info->dev, rt8973a_extcon_cable);
    620	if (IS_ERR(info->edev)) {
    621		dev_err(info->dev, "failed to allocate memory for extcon\n");
    622		return -ENOMEM;
    623	}
    624
    625	/* Register extcon device */
    626	ret = devm_extcon_dev_register(info->dev, info->edev);
    627	if (ret) {
    628		dev_err(info->dev, "failed to register extcon device\n");
    629		return ret;
    630	}
    631
    632	/*
    633	 * Detect accessory after completing the initialization of platform
    634	 *
    635	 * - Use delayed workqueue to detect cable state and then
    636	 * notify cable state to notifiee/platform through uevent.
    637	 * After completing the booting of platform, the extcon provider
    638	 * driver should notify cable state to upper layer.
    639	 */
    640	INIT_DELAYED_WORK(&info->wq_detcable, rt8973a_muic_detect_cable_wq);
    641	queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
    642			msecs_to_jiffies(DELAY_MS_DEFAULT));
    643
    644	/* Initialize RT8973A device and print vendor id and version id */
    645	rt8973a_init_dev_type(info);
    646
    647	return 0;
    648}
    649
    650static int rt8973a_muic_i2c_remove(struct i2c_client *i2c)
    651{
    652	struct rt8973a_muic_info *info = i2c_get_clientdata(i2c);
    653
    654	regmap_del_irq_chip(info->irq, info->irq_data);
    655
    656	return 0;
    657}
    658
    659static const struct of_device_id rt8973a_dt_match[] = {
    660	{ .compatible = "richtek,rt8973a-muic" },
    661	{ },
    662};
    663MODULE_DEVICE_TABLE(of, rt8973a_dt_match);
    664
    665#ifdef CONFIG_PM_SLEEP
    666static int rt8973a_muic_suspend(struct device *dev)
    667{
    668	struct i2c_client *i2c = to_i2c_client(dev);
    669	struct rt8973a_muic_info *info = i2c_get_clientdata(i2c);
    670
    671	enable_irq_wake(info->irq);
    672
    673	return 0;
    674}
    675
    676static int rt8973a_muic_resume(struct device *dev)
    677{
    678	struct i2c_client *i2c = to_i2c_client(dev);
    679	struct rt8973a_muic_info *info = i2c_get_clientdata(i2c);
    680
    681	disable_irq_wake(info->irq);
    682
    683	return 0;
    684}
    685#endif
    686
    687static SIMPLE_DEV_PM_OPS(rt8973a_muic_pm_ops,
    688			 rt8973a_muic_suspend, rt8973a_muic_resume);
    689
    690static const struct i2c_device_id rt8973a_i2c_id[] = {
    691	{ "rt8973a", TYPE_RT8973A },
    692	{ }
    693};
    694MODULE_DEVICE_TABLE(i2c, rt8973a_i2c_id);
    695
    696static struct i2c_driver rt8973a_muic_i2c_driver = {
    697	.driver		= {
    698		.name	= "rt8973a",
    699		.pm	= &rt8973a_muic_pm_ops,
    700		.of_match_table = rt8973a_dt_match,
    701	},
    702	.probe	= rt8973a_muic_i2c_probe,
    703	.remove	= rt8973a_muic_i2c_remove,
    704	.id_table = rt8973a_i2c_id,
    705};
    706
    707static int __init rt8973a_muic_i2c_init(void)
    708{
    709	return i2c_add_driver(&rt8973a_muic_i2c_driver);
    710}
    711subsys_initcall(rt8973a_muic_i2c_init);
    712
    713MODULE_DESCRIPTION("Richtek RT8973A Extcon driver");
    714MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
    715MODULE_LICENSE("GPL");