Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * extcon-sm5502.c - Silicon Mitus SM5502 extcon drvier to support USB switches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2014 Samsung Electronics Co., Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Author: Chanwoo Choi <cw00.choi@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/extcon-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "extcon-sm5502.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define	DELAY_MS_DEFAULT		17000	/* unit: millisecond */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) struct muic_irq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	unsigned int virq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) struct reg_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	bool invert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) struct sm5502_muic_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	struct extcon_dev *edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	struct i2c_client *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	struct regmap_irq_chip_data *irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct muic_irq *muic_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	unsigned int num_muic_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	bool irq_attach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	bool irq_detach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	struct work_struct irq_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	struct reg_data *reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	unsigned int num_reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	 * Use delayed workqueue to detect cable state and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	 * notify cable state to notifiee/platform through uevent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	 * After completing the booting of platform, the extcon provider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	 * driver should notify cable state to upper layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct delayed_work wq_detcable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) /* Default value of SM5502 register to bring up MUIC device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static struct reg_data sm5502_reg_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		.reg = SM5502_REG_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		.val = SM5502_REG_RESET_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		.invert = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		.reg = SM5502_REG_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		.val = SM5502_REG_CONTROL_MASK_INT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		.invert = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		.reg = SM5502_REG_INTMASK1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		.val = SM5502_REG_INTM1_KP_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			| SM5502_REG_INTM1_LKP_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			| SM5502_REG_INTM1_LKR_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		.invert = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		.reg = SM5502_REG_INTMASK2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		.val = SM5502_REG_INTM2_VBUS_DET_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			| SM5502_REG_INTM2_REV_ACCE_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			| SM5502_REG_INTM2_ADC_CHG_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			| SM5502_REG_INTM2_STUCK_KEY_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			| SM5502_REG_INTM2_STUCK_KEY_RCV_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			| SM5502_REG_INTM2_MHL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		.invert = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) /* List of detectable cables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static const unsigned int sm5502_extcon_cable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	EXTCON_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	EXTCON_USB_HOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	EXTCON_CHG_USB_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	EXTCON_CHG_USB_DCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	EXTCON_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Define supported accessory type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) enum sm5502_muic_acc_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	SM5502_MUIC_ADC_GROUND = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	SM5502_MUIC_ADC_SEND_END_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	SM5502_MUIC_ADC_REMOTE_S1_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	SM5502_MUIC_ADC_REMOTE_S2_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	SM5502_MUIC_ADC_REMOTE_S3_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	SM5502_MUIC_ADC_REMOTE_S4_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	SM5502_MUIC_ADC_REMOTE_S5_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	SM5502_MUIC_ADC_REMOTE_S6_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	SM5502_MUIC_ADC_REMOTE_S7_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	SM5502_MUIC_ADC_REMOTE_S8_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	SM5502_MUIC_ADC_REMOTE_S9_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	SM5502_MUIC_ADC_REMOTE_S10_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	SM5502_MUIC_ADC_REMOTE_S11_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	SM5502_MUIC_ADC_REMOTE_S12_BUTTON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	SM5502_MUIC_ADC_RESERVED_ACC_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	SM5502_MUIC_ADC_RESERVED_ACC_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	SM5502_MUIC_ADC_RESERVED_ACC_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	SM5502_MUIC_ADC_RESERVED_ACC_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	SM5502_MUIC_ADC_RESERVED_ACC_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	SM5502_MUIC_ADC_AUDIO_TYPE2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	SM5502_MUIC_ADC_PHONE_POWERED_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	SM5502_MUIC_ADC_TTY_CONVERTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	SM5502_MUIC_ADC_UART_CABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	SM5502_MUIC_ADC_TYPE1_CHARGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	SM5502_MUIC_ADC_AUDIO_VIDEO_CABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	SM5502_MUIC_ADC_TYPE2_CHARGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	SM5502_MUIC_ADC_AUDIO_TYPE1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	SM5502_MUIC_ADC_OPEN = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	 * The below accessories have same ADC value (0x1f or 0x1e).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	 * So, Device type1 is used to separate specific accessory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 							/* |---------|--ADC| */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 							/* |    [7:5]|[4:0]| */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	SM5502_MUIC_ADC_AUDIO_TYPE1_FULL_REMOTE = 0x3e,	/* |      001|11110| */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	SM5502_MUIC_ADC_AUDIO_TYPE1_SEND_END = 0x5e,	/* |      010|11110| */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 							/* |Dev Type1|--ADC| */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	SM5502_MUIC_ADC_OPEN_USB = 0x5f,		/* |      010|11111| */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	SM5502_MUIC_ADC_OPEN_TA = 0xdf,			/* |      110|11111| */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	SM5502_MUIC_ADC_OPEN_USB_OTG = 0xff,		/* |      111|11111| */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* List of supported interrupt for SM5502 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static struct muic_irq sm5502_muic_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	{ SM5502_IRQ_INT1_ATTACH,	"muic-attach" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	{ SM5502_IRQ_INT1_DETACH,	"muic-detach" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	{ SM5502_IRQ_INT1_KP,		"muic-kp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	{ SM5502_IRQ_INT1_LKP,		"muic-lkp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	{ SM5502_IRQ_INT1_LKR,		"muic-lkr" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	{ SM5502_IRQ_INT1_OVP_EVENT,	"muic-ovp-event" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	{ SM5502_IRQ_INT1_OCP_EVENT,	"muic-ocp-event" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	{ SM5502_IRQ_INT1_OVP_OCP_DIS,	"muic-ovp-ocp-dis" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	{ SM5502_IRQ_INT2_VBUS_DET,	"muic-vbus-det" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	{ SM5502_IRQ_INT2_REV_ACCE,	"muic-rev-acce" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	{ SM5502_IRQ_INT2_ADC_CHG,	"muic-adc-chg" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	{ SM5502_IRQ_INT2_STUCK_KEY,	"muic-stuck-key" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	{ SM5502_IRQ_INT2_STUCK_KEY_RCV, "muic-stuck-key-rcv" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	{ SM5502_IRQ_INT2_MHL,		"muic-mhl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* Define interrupt list of SM5502 to register regmap_irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static const struct regmap_irq sm5502_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	/* INT1 interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	{ .reg_offset = 0, .mask = SM5502_IRQ_INT1_ATTACH_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	{ .reg_offset = 0, .mask = SM5502_IRQ_INT1_DETACH_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	{ .reg_offset = 0, .mask = SM5502_IRQ_INT1_KP_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	{ .reg_offset = 0, .mask = SM5502_IRQ_INT1_LKP_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	{ .reg_offset = 0, .mask = SM5502_IRQ_INT1_LKR_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	{ .reg_offset = 0, .mask = SM5502_IRQ_INT1_OVP_EVENT_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	{ .reg_offset = 0, .mask = SM5502_IRQ_INT1_OCP_EVENT_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	{ .reg_offset = 0, .mask = SM5502_IRQ_INT1_OVP_OCP_DIS_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	/* INT2 interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	{ .reg_offset = 1, .mask = SM5502_IRQ_INT2_VBUS_DET_MASK,},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	{ .reg_offset = 1, .mask = SM5502_IRQ_INT2_REV_ACCE_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	{ .reg_offset = 1, .mask = SM5502_IRQ_INT2_ADC_CHG_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	{ .reg_offset = 1, .mask = SM5502_IRQ_INT2_STUCK_KEY_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	{ .reg_offset = 1, .mask = SM5502_IRQ_INT2_STUCK_KEY_RCV_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	{ .reg_offset = 1, .mask = SM5502_IRQ_INT2_MHL_MASK, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static const struct regmap_irq_chip sm5502_muic_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	.name			= "sm5502",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	.status_base		= SM5502_REG_INT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	.mask_base		= SM5502_REG_INTMASK1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	.mask_invert		= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	.num_regs		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	.irqs			= sm5502_irqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	.num_irqs		= ARRAY_SIZE(sm5502_irqs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* Define regmap configuration of SM5502 for I2C communication  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static bool sm5502_muic_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	case SM5502_REG_INTMASK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	case SM5502_REG_INTMASK2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static const struct regmap_config sm5502_muic_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	.reg_bits	= 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	.val_bits	= 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	.volatile_reg	= sm5502_muic_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	.max_register	= SM5502_REG_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* Change DM_CON/DP_CON/VBUSIN switch according to cable type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int sm5502_muic_set_path(struct sm5502_muic_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 				unsigned int con_sw, unsigned int vbus_sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 				bool attached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (!attached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		con_sw	= DM_DP_SWITCH_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		vbus_sw	= VBUSIN_SWITCH_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	switch (con_sw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	case DM_DP_SWITCH_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	case DM_DP_SWITCH_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	case DM_DP_SWITCH_AUDIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	case DM_DP_SWITCH_UART:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		ret = regmap_update_bits(info->regmap, SM5502_REG_MANUAL_SW1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 					 SM5502_REG_MANUAL_SW1_DP_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 					 SM5502_REG_MANUAL_SW1_DM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 					 con_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			dev_err(info->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 				"cannot update DM_CON/DP_CON switch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		dev_err(info->dev, "Unknown DM_CON/DP_CON switch type (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				con_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	switch (vbus_sw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	case VBUSIN_SWITCH_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	case VBUSIN_SWITCH_VBUSOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	case VBUSIN_SWITCH_MIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	case VBUSIN_SWITCH_VBUSOUT_WITH_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		ret = regmap_update_bits(info->regmap, SM5502_REG_MANUAL_SW1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 					 SM5502_REG_MANUAL_SW1_VBUSIN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 					 vbus_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			dev_err(info->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 				"cannot update VBUSIN switch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		dev_err(info->dev, "Unknown VBUS switch type (%d)\n", vbus_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* Return cable type of attached or detached accessories */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	unsigned int cable_type, adc, dev_type1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	/* Read ADC value according to external cable or button */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	ret = regmap_read(info->regmap, SM5502_REG_ADC, &adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		dev_err(info->dev, "failed to read ADC register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	 * If ADC is SM5502_MUIC_ADC_GROUND(0x0), external cable hasn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	 * connected with to MUIC device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	cable_type = adc & SM5502_REG_ADC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	if (cable_type == SM5502_MUIC_ADC_GROUND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		return SM5502_MUIC_ADC_GROUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	switch (cable_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	case SM5502_MUIC_ADC_GROUND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	case SM5502_MUIC_ADC_SEND_END_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	case SM5502_MUIC_ADC_REMOTE_S1_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	case SM5502_MUIC_ADC_REMOTE_S2_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	case SM5502_MUIC_ADC_REMOTE_S3_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	case SM5502_MUIC_ADC_REMOTE_S4_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	case SM5502_MUIC_ADC_REMOTE_S5_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	case SM5502_MUIC_ADC_REMOTE_S6_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	case SM5502_MUIC_ADC_REMOTE_S7_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	case SM5502_MUIC_ADC_REMOTE_S8_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	case SM5502_MUIC_ADC_REMOTE_S9_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	case SM5502_MUIC_ADC_REMOTE_S10_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	case SM5502_MUIC_ADC_REMOTE_S11_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	case SM5502_MUIC_ADC_REMOTE_S12_BUTTON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	case SM5502_MUIC_ADC_RESERVED_ACC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	case SM5502_MUIC_ADC_RESERVED_ACC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	case SM5502_MUIC_ADC_RESERVED_ACC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	case SM5502_MUIC_ADC_RESERVED_ACC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	case SM5502_MUIC_ADC_RESERVED_ACC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	case SM5502_MUIC_ADC_AUDIO_TYPE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	case SM5502_MUIC_ADC_PHONE_POWERED_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	case SM5502_MUIC_ADC_TTY_CONVERTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	case SM5502_MUIC_ADC_UART_CABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	case SM5502_MUIC_ADC_TYPE1_CHARGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	case SM5502_MUIC_ADC_AUDIO_VIDEO_CABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	case SM5502_MUIC_ADC_TYPE2_CHARGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	case SM5502_MUIC_ADC_AUDIO_TYPE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		 * Check whether cable type is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		 * SM5502_MUIC_ADC_AUDIO_TYPE1_FULL_REMOTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		 * or SM5502_MUIC_ADC_AUDIO_TYPE1_SEND_END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		 * by using Button event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	case SM5502_MUIC_ADC_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		ret = regmap_read(info->regmap, SM5502_REG_DEV_TYPE1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 				  &dev_type1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			dev_err(info->dev, "failed to read DEV_TYPE1 reg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		switch (dev_type1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		case SM5502_REG_DEV_TYPE1_USB_SDP_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			cable_type = SM5502_MUIC_ADC_OPEN_USB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		case SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			cable_type = SM5502_MUIC_ADC_OPEN_TA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		case SM5502_REG_DEV_TYPE1_USB_OTG_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			cable_type = SM5502_MUIC_ADC_OPEN_USB_OTG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			dev_dbg(info->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 				"cannot identify the cable type: adc(0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 				adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		dev_err(info->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			"failed to identify the cable type: adc(0x%x)\n", adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	return cable_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static int sm5502_muic_cable_handler(struct sm5502_muic_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 				     bool attached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	static unsigned int prev_cable_type = SM5502_MUIC_ADC_GROUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	unsigned int cable_type = SM5502_MUIC_ADC_GROUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	unsigned int con_sw = DM_DP_SWITCH_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	unsigned int vbus_sw = VBUSIN_SWITCH_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	/* Get the type of attached or detached cable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (attached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		cable_type = sm5502_muic_get_cable_type(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		cable_type = prev_cable_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	prev_cable_type = cable_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	switch (cable_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	case SM5502_MUIC_ADC_OPEN_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		id	= EXTCON_USB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		con_sw	= DM_DP_SWITCH_USB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		vbus_sw	= VBUSIN_SWITCH_VBUSOUT_WITH_USB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	case SM5502_MUIC_ADC_OPEN_TA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		id	= EXTCON_CHG_USB_DCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		con_sw	= DM_DP_SWITCH_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		vbus_sw	= VBUSIN_SWITCH_VBUSOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	case SM5502_MUIC_ADC_OPEN_USB_OTG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		id	= EXTCON_USB_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		con_sw	= DM_DP_SWITCH_USB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		vbus_sw	= VBUSIN_SWITCH_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		dev_dbg(info->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			"cannot handle this cable_type (0x%x)\n", cable_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	/* Change internal hardware path(DM_CON/DP_CON, VBUSIN) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	ret = sm5502_muic_set_path(info, con_sw, vbus_sw, attached);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	/* Change the state of external accessory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	extcon_set_state_sync(info->edev, id, attached);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	if (id == EXTCON_USB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 					attached);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static void sm5502_muic_irq_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	struct sm5502_muic_info *info = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			struct sm5502_muic_info, irq_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (!info->edev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	mutex_lock(&info->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	/* Detect attached or detached cables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if (info->irq_attach) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		ret = sm5502_muic_cable_handler(info, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		info->irq_attach = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	if (info->irq_detach) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		ret = sm5502_muic_cable_handler(info, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		info->irq_detach = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		dev_err(info->dev, "failed to handle MUIC interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	mutex_unlock(&info->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)  * Sets irq_attach or irq_detach in sm5502_muic_info and returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)  * Returns -ESRCH if irq_type does not match registered IRQ for this dev type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int sm5502_parse_irq(struct sm5502_muic_info *info, int irq_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	switch (irq_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	case SM5502_IRQ_INT1_ATTACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		info->irq_attach = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	case SM5502_IRQ_INT1_DETACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		info->irq_detach = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	case SM5502_IRQ_INT1_KP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	case SM5502_IRQ_INT1_LKP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	case SM5502_IRQ_INT1_LKR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	case SM5502_IRQ_INT1_OVP_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	case SM5502_IRQ_INT1_OCP_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	case SM5502_IRQ_INT1_OVP_OCP_DIS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	case SM5502_IRQ_INT2_VBUS_DET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	case SM5502_IRQ_INT2_REV_ACCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	case SM5502_IRQ_INT2_ADC_CHG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	case SM5502_IRQ_INT2_STUCK_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	case SM5502_IRQ_INT2_STUCK_KEY_RCV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	case SM5502_IRQ_INT2_MHL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	struct sm5502_muic_info *info = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	int i, irq_type = -1, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	for (i = 0; i < info->num_muic_irqs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		if (irq == info->muic_irqs[i].virq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			irq_type = info->muic_irqs[i].irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	ret = sm5502_parse_irq(info, irq_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		dev_warn(info->dev, "cannot handle is interrupt:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 				    irq_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	schedule_work(&info->irq_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static void sm5502_muic_detect_cable_wq(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	struct sm5502_muic_info *info = container_of(to_delayed_work(work),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 				struct sm5502_muic_info, wq_detcable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	/* Notify the state of connector cable or not  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	ret = sm5502_muic_cable_handler(info, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		dev_warn(info->dev, "failed to detect cable state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static void sm5502_init_dev_type(struct sm5502_muic_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	unsigned int reg_data, vendor_id, version_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	/* To test I2C, Print version_id and vendor_id of SM5502 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	ret = regmap_read(info->regmap, SM5502_REG_DEVICE_ID, &reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		dev_err(info->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			"failed to read DEVICE_ID register: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	vendor_id = ((reg_data & SM5502_REG_DEVICE_ID_VENDOR_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 				SM5502_REG_DEVICE_ID_VENDOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	version_id = ((reg_data & SM5502_REG_DEVICE_ID_VERSION_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 				SM5502_REG_DEVICE_ID_VERSION_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	dev_info(info->dev, "Device type: version: 0x%x, vendor: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 			    version_id, vendor_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	/* Initiazle the register of SM5502 device to bring-up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	for (i = 0; i < info->num_reg_data; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		unsigned int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		if (!info->reg_data[i].invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			val |= ~info->reg_data[i].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 			val = info->reg_data[i].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		regmap_write(info->regmap, info->reg_data[i].reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static int sm5022_muic_i2c_probe(struct i2c_client *i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 				 const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	struct device_node *np = i2c->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	struct sm5502_muic_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	int i, ret, irq_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	i2c_set_clientdata(i2c, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	info->dev = &i2c->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	info->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	info->irq = i2c->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	info->muic_irqs = sm5502_muic_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	info->num_muic_irqs = ARRAY_SIZE(sm5502_muic_irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	info->reg_data = sm5502_reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	info->num_reg_data = ARRAY_SIZE(sm5502_reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	mutex_init(&info->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	INIT_WORK(&info->irq_work, sm5502_muic_irq_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	info->regmap = devm_regmap_init_i2c(i2c, &sm5502_muic_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	if (IS_ERR(info->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		ret = PTR_ERR(info->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		dev_err(info->dev, "failed to allocate register map: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 				   ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	/* Support irq domain for SM5502 MUIC device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	ret = regmap_add_irq_chip(info->regmap, info->irq, irq_flags, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 				  &sm5502_muic_irq_chip, &info->irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		dev_err(info->dev, "failed to request IRQ %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 				    info->irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	for (i = 0; i < info->num_muic_irqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		struct muic_irq *muic_irq = &info->muic_irqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		int virq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		virq = regmap_irq_get_virq(info->irq_data, muic_irq->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		if (virq <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		muic_irq->virq = virq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		ret = devm_request_threaded_irq(info->dev, virq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 						sm5502_muic_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 						IRQF_NO_SUSPEND | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 						muic_irq->name, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			dev_err(info->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 				"failed: irq request (IRQ: %d, error :%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 				muic_irq->irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	/* Allocate extcon device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	info->edev = devm_extcon_dev_allocate(info->dev, sm5502_extcon_cable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	if (IS_ERR(info->edev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		dev_err(info->dev, "failed to allocate memory for extcon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	/* Register extcon device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	ret = devm_extcon_dev_register(info->dev, info->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		dev_err(info->dev, "failed to register extcon device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	 * Detect accessory after completing the initialization of platform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	 * - Use delayed workqueue to detect cable state and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	 * notify cable state to notifiee/platform through uevent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	 * After completing the booting of platform, the extcon provider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	 * driver should notify cable state to upper layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	INIT_DELAYED_WORK(&info->wq_detcable, sm5502_muic_detect_cable_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 			msecs_to_jiffies(DELAY_MS_DEFAULT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	/* Initialize SM5502 device and print vendor id and version id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	sm5502_init_dev_type(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static int sm5502_muic_i2c_remove(struct i2c_client *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	regmap_del_irq_chip(info->irq, info->irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static const struct of_device_id sm5502_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	{ .compatible = "siliconmitus,sm5502-muic" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) MODULE_DEVICE_TABLE(of, sm5502_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static int sm5502_muic_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	enable_irq_wake(info->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static int sm5502_muic_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	disable_irq_wake(info->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static SIMPLE_DEV_PM_OPS(sm5502_muic_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 			 sm5502_muic_suspend, sm5502_muic_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static const struct i2c_device_id sm5502_i2c_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	{ "sm5502", TYPE_SM5502 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) MODULE_DEVICE_TABLE(i2c, sm5502_i2c_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static struct i2c_driver sm5502_muic_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		.name	= "sm5502",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		.pm	= &sm5502_muic_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		.of_match_table = sm5502_dt_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	.probe	= sm5022_muic_i2c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	.remove	= sm5502_muic_i2c_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	.id_table = sm5502_i2c_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static int __init sm5502_muic_i2c_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	return i2c_add_driver(&sm5502_muic_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) subsys_initcall(sm5502_muic_i2c_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) MODULE_DESCRIPTION("Silicon Mitus SM5502 Extcon driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) MODULE_LICENSE("GPL");