^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, ®_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");