/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2021 MediaTek Inc. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mtk_charger_intf.h" #include "rt9750.h" #ifdef CONFIG_RT_REGMAP #include #endif #define RT9750_DRV_VERSION "1.0.10_MTK" #define I2C_ACCESS_MAX_RETRY 5 struct rt9750_desc { int regmap_represent_slave_addr; const char *regmap_name; const char *chg_dev_name; const char *alias_name; u32 vbat_reg; u32 vout_reg; u32 iococp; u32 wdt; }; static struct rt9750_desc rt9750_default_desc = { .regmap_represent_slave_addr = RT9750_SLAVE_ADDR, .regmap_name = "rt9750", .alias_name = "rt9750", .chg_dev_name = "primary_load_switch", .vbat_reg = 4400000, /* uV */ .vout_reg = 5000000, /* uV */ .iococp = 5000000, /* uA */ .wdt = 2000000, /* us */ }; struct rt9750_info { struct i2c_client *i2c; struct device *dev; struct rt9750_desc *desc; struct charger_device *chg_dev; struct charger_properties chg_props; struct mutex i2c_access_lock; struct mutex adc_access_lock; struct mutex gpio_access_lock; u32 intr_gpio; u32 en_gpio; int irq; u8 chip_rev; bool is_chip_en; #if 0 struct task_struct *task; #endif #ifdef CONFIG_RT_REGMAP struct rt_regmap_device *regmap_dev; struct rt_regmap_properties *regmap_prop; #endif }; static u32 rt9750_wdt[] = { 0, 500000, 1000000, 2000000, }; /* us */ enum rt9750_irq_idx { RT9750_IRQIDX_EVT1 = 0, RT9750_IRQIDX_EVT2, RT9750_IRQIDX_MAX, }; static u8 rt9750_irqmask[RT9750_IRQIDX_MAX] = { 0xEF, 0xFF, }; static const u8 rt9750_irq_maskall[RT9750_IRQIDX_MAX] = { 0xEF, 0xFF, }; struct irq_mapping_tbl { const char *name; const int id; }; #define RT9750_IRQ_MAPPING(_name, _id) {.name = #_name, .id = _id} static const struct irq_mapping_tbl rt9750_irq_mapping_tbl[] = { RT9750_IRQ_MAPPING(ibus_irev_flt, 0), RT9750_IRQ_MAPPING(tbat_otp_flt, 1), RT9750_IRQ_MAPPING(tbus_otp_flt, 2), RT9750_IRQ_MAPPING(vout_reg_ldo, 3), RT9750_IRQ_MAPPING(vbat_reg_ldo, 5), RT9750_IRQ_MAPPING(ibus_reg_ldo, 6), RT9750_IRQ_MAPPING(vbus_ovp_flt, 7), RT9750_IRQ_MAPPING(ioc_flt, 8), RT9750_IRQ_MAPPING(tshut_flt, 9), RT9750_IRQ_MAPPING(bat_insert, 10), RT9750_IRQ_MAPPING(vbus_insert, 11), RT9750_IRQ_MAPPING(vdrop_ovp_flt, 12), RT9750_IRQ_MAPPING(vdrop_alm_flt, 13), RT9750_IRQ_MAPPING(adc_done, 14), RT9750_IRQ_MAPPING(lowchg_alm_flt, 15), }; /* ========= */ /* RT Regmap */ /* ========= */ #ifdef CONFIG_RT_REGMAP RT_REG_DECL(RT9750_REG_CORE_CTRL0, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_EVENT1_MASK, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_EVENT2_MASK, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_EVENT1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_EVENT2, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_EVENT1_EN, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_CONTROL, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_ADC_CTRL, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_SAMPLE_EN, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_PROT_DLYOCP, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VBUS_OVP, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VOUT_REG, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VDROP_OVP, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VDROP_ALM, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VBAT_REG, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_IBUS_OCP, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_TBUS_OTP, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_TBAT_OTP, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VBUS_ADC2, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VBUS_ADC1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_IBUS_ADC2, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_IBUS_ADC1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VOUT_ADC2, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VOUT_ADC1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VDROP_ADC2, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VDROP_ADC1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VBAT_ADC2, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_VBAT_ADC1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_TBUS_ADC2, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_TBUS_ADC1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_TBAT_ADC2, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_TBAT_ADC1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_TDIE_ADC1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_EVENT_STATUS1, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_EVENT_STATUS2, 1, RT_VOLATILE, {}); RT_REG_DECL(RT9750_REG_EVENT_STATUS, 1, RT_VOLATILE, {}); static const rt_register_map_t rt9750_regmap_map[] = { RT_REG(RT9750_REG_CORE_CTRL0), RT_REG(RT9750_REG_EVENT1_MASK), RT_REG(RT9750_REG_EVENT2_MASK), RT_REG(RT9750_REG_EVENT1), RT_REG(RT9750_REG_EVENT2), RT_REG(RT9750_REG_EVENT1_EN), RT_REG(RT9750_REG_CONTROL), RT_REG(RT9750_REG_ADC_CTRL), RT_REG(RT9750_REG_SAMPLE_EN), RT_REG(RT9750_REG_PROT_DLYOCP), RT_REG(RT9750_REG_VBUS_OVP), RT_REG(RT9750_REG_VOUT_REG), RT_REG(RT9750_REG_VDROP_OVP), RT_REG(RT9750_REG_VDROP_ALM), RT_REG(RT9750_REG_VBAT_REG), RT_REG(RT9750_REG_IBUS_OCP), RT_REG(RT9750_REG_TBUS_OTP), RT_REG(RT9750_REG_TBAT_OTP), RT_REG(RT9750_REG_VBUS_ADC2), RT_REG(RT9750_REG_VBUS_ADC1), RT_REG(RT9750_REG_IBUS_ADC2), RT_REG(RT9750_REG_IBUS_ADC1), RT_REG(RT9750_REG_VOUT_ADC2), RT_REG(RT9750_REG_VOUT_ADC1), RT_REG(RT9750_REG_VDROP_ADC2), RT_REG(RT9750_REG_VDROP_ADC1), RT_REG(RT9750_REG_VBAT_ADC2), RT_REG(RT9750_REG_VBAT_ADC1), RT_REG(RT9750_REG_TBUS_ADC2), RT_REG(RT9750_REG_TBUS_ADC1), RT_REG(RT9750_REG_TBAT_ADC2), RT_REG(RT9750_REG_TBAT_ADC1), RT_REG(RT9750_REG_TDIE_ADC1), RT_REG(RT9750_REG_EVENT_STATUS1), RT_REG(RT9750_REG_EVENT_STATUS2), RT_REG(RT9750_REG_EVENT_STATUS), }; #endif /* CONFIG_RT_REGMAP */ static const unsigned char rt9750_reg_addr[] = { RT9750_REG_CORE_CTRL0, RT9750_REG_EVENT1_MASK, RT9750_REG_EVENT2_MASK, RT9750_REG_EVENT1, RT9750_REG_EVENT2, RT9750_REG_EVENT1_EN, RT9750_REG_CONTROL, RT9750_REG_ADC_CTRL, RT9750_REG_SAMPLE_EN, RT9750_REG_PROT_DLYOCP, RT9750_REG_VBUS_OVP, RT9750_REG_VOUT_REG, RT9750_REG_VDROP_OVP, RT9750_REG_VDROP_ALM, RT9750_REG_VBAT_REG, RT9750_REG_IBUS_OCP, RT9750_REG_TBUS_OTP, RT9750_REG_TBAT_OTP, RT9750_REG_VBUS_ADC2, RT9750_REG_VBUS_ADC1, RT9750_REG_IBUS_ADC2, RT9750_REG_IBUS_ADC1, RT9750_REG_VOUT_ADC2, RT9750_REG_VOUT_ADC1, RT9750_REG_VDROP_ADC2, RT9750_REG_VDROP_ADC1, RT9750_REG_VBAT_ADC2, RT9750_REG_VBAT_ADC1, RT9750_REG_TBUS_ADC2, RT9750_REG_TBUS_ADC1, RT9750_REG_TBAT_ADC2, RT9750_REG_TBAT_ADC1, RT9750_REG_TDIE_ADC1, RT9750_REG_EVENT_STATUS1, RT9750_REG_EVENT_STATUS2, RT9750_REG_EVENT_STATUS, }; /* ========================= */ /* I2C operations */ /* ========================= */ static inline bool rt9750_is_chip_en(struct rt9750_info *info) { int en = 0; en = gpio_get_value(info->en_gpio); if ((en && !info->is_chip_en) || (!en && info->is_chip_en)) dev_notice(info->dev, "%s: en not sync(%d, %d)\n", __func__, en, info->is_chip_en); return en ? true : false; } static int rt9750_device_read(void *client, u32 addr, int leng, void *dst) { int ret = 0; struct i2c_client *i2c = NULL; i2c = (struct i2c_client *)client; ret = i2c_smbus_read_i2c_block_data(i2c, addr, leng, dst); return ret; } static int rt9750_device_write(void *client, u32 addr, int leng, const void *src) { int ret = 0; struct i2c_client *i2c = NULL; i2c = (struct i2c_client *)client; ret = i2c_smbus_write_i2c_block_data(i2c, addr, leng, src); return ret; } #ifdef CONFIG_RT_REGMAP static struct rt_regmap_fops rt9750_regmap_fops = { .read_device = rt9750_device_read, .write_device = rt9750_device_write, }; static int rt9750_register_rt_regmap(struct rt9750_info *info) { int ret = 0; struct i2c_client *i2c = info->i2c; struct rt_regmap_properties *prop = NULL; dev_info(info->dev, "%s\n", __func__); prop = devm_kzalloc(&i2c->dev, sizeof(struct rt_regmap_properties), GFP_KERNEL); if (!prop) return -ENOMEM; prop->name = info->desc->regmap_name; prop->aliases = info->desc->regmap_name; prop->register_num = ARRAY_SIZE(rt9750_regmap_map); prop->rm = rt9750_regmap_map; prop->rt_regmap_mode = RT_SINGLE_BYTE | RT_CACHE_DISABLE | RT_IO_PASS_THROUGH; prop->io_log_en = 0; info->regmap_prop = prop; info->regmap_dev = rt_regmap_device_register_ex( info->regmap_prop, &rt9750_regmap_fops, &i2c->dev, i2c, info->desc->regmap_represent_slave_addr, info ); if (!info->regmap_dev) { dev_notice(&i2c->dev, "register regmap device failed\n"); return -EIO; } return ret; } #endif /* CONFIG_RT_REGMAP */ static inline int _rt9750_i2c_write_byte(struct rt9750_info *info, u8 cmd, u8 data) { int ret = 0, retry = 0; do { #ifdef CONFIG_RT_REGMAP ret = rt_regmap_block_write(info->regmap_dev, cmd, 1, &data); #else ret = rt9750_device_write(info->i2c, cmd, 1, &data); #endif retry++; if (ret < 0) mdelay(20); } while (ret < 0 && retry < I2C_ACCESS_MAX_RETRY); if (ret < 0) dev_notice(info->dev, "%s: I2CW[0x%02X] = 0x%02X fail\n", __func__, cmd, data); else dev_dbg_ratelimited(info->dev, "%s: I2CW[0x%02X] = 0x%02X\n", __func__, cmd, data); return ret; } #if 0 static int rt9750_i2c_write_byte(struct rt9750_info *info, u8 cmd, u8 data) { int ret = 0, en = 0; mutex_lock(&info->i2c_access_lock); mutex_lock(&info->gpio_access_lock); if (rt9750_is_chip_en(info)) ret = _rt9750_i2c_write_byte(info, cmd, data); mutex_unlock(&info->gpio_access_lock); mutex_unlock(&info->i2c_access_lock); return ret; } #endif static inline int _rt9750_i2c_read_byte(struct rt9750_info *info, u8 cmd) { int ret = 0, ret_val = 0, retry = 0; do { #ifdef CONFIG_RT_REGMAP ret = rt_regmap_block_read(info->regmap_dev, cmd, 1, &ret_val); #else ret = rt9750_device_read(info->i2c, cmd, 1, &ret_val); #endif retry++; if (ret < 0) msleep(20); } while (ret < 0 && retry < I2C_ACCESS_MAX_RETRY); if (ret < 0) { dev_notice(info->dev, "%s: I2CR[0x%02X] fail\n", __func__, cmd); return ret; } ret_val = ret_val & 0xFF; dev_dbg_ratelimited(info->dev, "%s: I2CR[0x%02X] = 0x%02X\n", __func__, cmd, ret_val); return ret_val; } static int rt9750_i2c_read_byte(struct rt9750_info *info, u8 cmd) { int ret = 0; mutex_lock(&info->i2c_access_lock); mutex_lock(&info->gpio_access_lock); if (rt9750_is_chip_en(info)) ret = _rt9750_i2c_read_byte(info, cmd); mutex_unlock(&info->gpio_access_lock); mutex_unlock(&info->i2c_access_lock); if (ret < 0) return ret; return (ret & 0xFF); } static inline int _rt9750_i2c_block_write(struct rt9750_info *info, u8 cmd, u32 leng, const u8 *data) { int ret = 0; #ifdef CONFIG_RT_REGMAP ret = rt_regmap_block_write(info->regmap_dev, cmd, leng, data); #else ret = rt9750_device_write(info->i2c, cmd, leng, data); #endif return ret; } static int rt9750_i2c_block_write(struct rt9750_info *info, u8 cmd, u32 leng, const u8 *data) { int ret = 0; mutex_lock(&info->i2c_access_lock); mutex_lock(&info->gpio_access_lock); if (rt9750_is_chip_en(info)) ret = _rt9750_i2c_block_write(info, cmd, leng, data); mutex_unlock(&info->gpio_access_lock); mutex_unlock(&info->i2c_access_lock); return ret; } static inline int _rt9750_i2c_block_read(struct rt9750_info *info, u8 cmd, u32 leng, u8 *data) { int ret = 0; #ifdef CONFIG_RT_REGMAP ret = rt_regmap_block_read(info->regmap_dev, cmd, leng, data); #else ret = rt9750_device_read(info->i2c, cmd, leng, data); #endif return ret; } static int rt9750_i2c_block_read(struct rt9750_info *info, u8 cmd, u32 leng, u8 *data) { int ret = 0; mutex_lock(&info->i2c_access_lock); mutex_lock(&info->gpio_access_lock); if (rt9750_is_chip_en(info)) ret = _rt9750_i2c_block_read(info, cmd, leng, data); mutex_unlock(&info->gpio_access_lock); mutex_unlock(&info->i2c_access_lock); return ret; } static int rt9750_i2c_test_bit(struct rt9750_info *info, u8 cmd, u8 shift) { int ret = 0; ret = rt9750_i2c_read_byte(info, cmd); if (ret < 0) return ret; ret = ret & (1 << shift); return ret; } static int rt9750_i2c_update_bits(struct rt9750_info *info, u8 cmd, u8 data, u8 mask) { int ret = 0; u8 reg_data = 0; mutex_lock(&info->i2c_access_lock); mutex_lock(&info->gpio_access_lock); if (rt9750_is_chip_en(info)) { ret = _rt9750_i2c_read_byte(info, cmd); if (ret < 0) goto out; reg_data = ret & 0xFF; reg_data &= ~mask; reg_data |= (data & mask); ret = _rt9750_i2c_write_byte(info, cmd, reg_data); } out: mutex_unlock(&info->gpio_access_lock); mutex_unlock(&info->i2c_access_lock); return ret; } static inline int rt9750_set_bit(struct rt9750_info *info, u8 reg, u8 mask) { return rt9750_i2c_update_bits(info, reg, mask, mask); } static inline int rt9750_clr_bit(struct rt9750_info *info, u8 reg, u8 mask) { return rt9750_i2c_update_bits(info, reg, 0x00, mask); } /* ========================= */ /* Internal function */ /* ========================= */ static u8 rt9750_find_closest_reg_value(const u32 min, const u32 max, const u32 step, const u32 num, const u32 target) { u32 i = 0, cur_val = 0, next_val = 0; /* Smaller than minimum supported value, use minimum one */ if (target < min) return 0; for (i = 0; i < num - 1; i++) { cur_val = min + i * step; next_val = cur_val + step; if (cur_val > max) cur_val = max; if (next_val > max) next_val = max; if (target >= cur_val && target < next_val) return i; } /* Greater than maximum supported value, use maximum one */ return num - 1; } static u8 rt9750_find_closest_reg_value_via_table(const u32 *value_table, const u32 table_size, const u32 target_value) { u32 i = 0; /* Smaller than minimum supported value, use minimum one */ if (target_value < value_table[0]) return 0; for (i = 0; i < table_size - 1; i++) { if (target_value >= value_table[i] && target_value < value_table[i + 1]) return i; } /* Greater than maximum supported value, use maximum one */ return table_size - 1; } static u32 rt9750_find_closest_real_value(const u32 min, const u32 max, const u32 step, const u8 reg_val) { u32 ret_val = 0; ret_val = min + reg_val * step; if (ret_val > max) ret_val = max; return ret_val; } static int rt9750_is_hw_exist(struct rt9750_info *info) { int ret = 0; u8 dev_id = 0, chip_rev = 0; ret = i2c_smbus_read_byte_data(info->i2c, RT9750_REG_CORE_CTRL0); if (ret < 0) return false; dev_id = ret & 0x07; chip_rev = ret & 0x38; if (dev_id != RT9750_DEVICE_ID) { dev_notice(info->dev, "%s: device id is incorrect\n", __func__); return false; } dev_info(info->dev, "%s: E%d(0x%02X)\n", __func__, chip_rev + 1, chip_rev); info->chip_rev = chip_rev; return true; } static inline const char *rt9750_get_irq_name(struct rt9750_info *info, int irqnum) { int i = 0; for (i = 0; i < ARRAY_SIZE(rt9750_irq_mapping_tbl); i++) { if (rt9750_irq_mapping_tbl[i].id == irqnum) return rt9750_irq_mapping_tbl[i].name; } return "not found"; } static inline void rt9750_irq_mask(struct rt9750_info *info, int irqnum) { dev_dbg(info->dev, "%s: irq = %d, %s\n", __func__, irqnum, rt9750_get_irq_name(info, irqnum)); rt9750_irqmask[irqnum / 8] |= (1 << (irqnum % 8)); } static inline void rt9750_irq_unmask(struct rt9750_info *info, int irqnum) { dev_dbg(info->dev, "%s: irq = %d, %s\n", __func__, irqnum, rt9750_get_irq_name(info, irqnum)); rt9750_irqmask[irqnum / 8] &= ~(1 << (irqnum % 8)); } static int rt9750_ibus_irev_flt_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_tbat_otp_flt_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_tbus_otp_flt_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_vout_reg_ldo_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_vbat_reg_ldo_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_ibus_reg_ldo_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_vbus_ovp_flt_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_ioc_flt_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_tshut_flt_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_bat_insert_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_vbus_insert_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_vdrop_ovp_flt_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_vdrop_alm_flt_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_adc_done_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } static int rt9750_lowchg_alm_flt_irq_handler(struct rt9750_info *info) { dev_info(info->dev, "%s\n", __func__); return 0; } typedef int (*rt9750_irq_fptr)(struct rt9750_info *); static rt9750_irq_fptr rt9750_irq_handler_tbl[16] = { rt9750_ibus_irev_flt_irq_handler, rt9750_tbat_otp_flt_irq_handler, rt9750_tbus_otp_flt_irq_handler, rt9750_vout_reg_ldo_irq_handler, NULL, rt9750_vbat_reg_ldo_irq_handler, rt9750_ibus_reg_ldo_irq_handler, rt9750_vbus_ovp_flt_irq_handler, rt9750_ioc_flt_irq_handler, rt9750_tshut_flt_irq_handler, rt9750_bat_insert_irq_handler, rt9750_vbus_insert_irq_handler, rt9750_vdrop_ovp_flt_irq_handler, rt9750_vdrop_alm_flt_irq_handler, rt9750_adc_done_irq_handler, rt9750_lowchg_alm_flt_irq_handler, }; static irqreturn_t rt9750_irq_handler(int irq, void *data) { int ret = 0, i = 0, j = 0; struct rt9750_info *info = (struct rt9750_info *)data; u8 evt[RT9750_IRQIDX_MAX] = {0}; u8 mask[RT9750_IRQIDX_MAX] = {0}; dev_info(info->dev, "%s\n", __func__); ret = rt9750_i2c_block_read(info, RT9750_REG_EVENT1, RT9750_IRQIDX_MAX, evt); if (ret < 0) { dev_notice(info->dev, "%s: read irq data failed\n", __func__); goto err_read_irq; } ret = rt9750_i2c_block_read(info, RT9750_REG_EVENT1_MASK, RT9750_IRQIDX_MAX, mask); if (ret < 0) { dev_notice(info->dev, "%s: read irq mask failed\n", __func__); goto err_read_irq; } for (i = 0; i < RT9750_IRQIDX_MAX; i++) { evt[i] &= ~mask[i]; for (j = 0; j < 8; j++) { if (!(evt[i] & (1 << j))) continue; if (rt9750_irq_handler_tbl[i * 8 + j]) rt9750_irq_handler_tbl[i * 8 + j](info); } } err_read_irq: return IRQ_HANDLED; } static int rt9750_register_irq(struct rt9750_info *info) { int ret = 0, len = 0; char *name = NULL; /* request gpio */ len = strlen(info->desc->chg_dev_name); name = devm_kzalloc(info->dev, len + 10, GFP_KERNEL); snprintf(name, len + 10, "%s_irq_gpio", info->desc->chg_dev_name); ret = devm_gpio_request_one(info->dev, info->intr_gpio, GPIOF_IN, name); if (ret < 0) { dev_notice(info->dev, "%s: gpio request fail\n", __func__); goto err; } ret = gpio_to_irq(info->intr_gpio); if (ret < 0) { dev_notice(info->dev, "%s: irq mapping fail\n", __func__); goto err; } info->irq = ret; dev_info(info->dev, "%s: irq = %d\n", __func__, info->irq); /* Request threaded IRQ */ name = devm_kzalloc(info->dev, len + 5, GFP_KERNEL); snprintf(name, len + 5, "%s_irq", info->desc->chg_dev_name); ret = devm_request_threaded_irq(info->dev, info->irq, NULL, rt9750_irq_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, info); if (ret < 0) { dev_notice(info->dev, "%s: request thread irq fail\n", __func__); goto err; } return 0; err: return ret; } static inline int rt9750_get_irq_number(struct rt9750_info *info, const char *name) { int i = 0; if (!name) { dev_notice(info->dev, "%s: null name\n", __func__); return -EINVAL; } for (i = 0; i < ARRAY_SIZE(rt9750_irq_mapping_tbl); i++) { if (!strcmp(name, rt9750_irq_mapping_tbl[i].name)) return rt9750_irq_mapping_tbl[i].id; } return -EINVAL; } static int rt9750_parse_dt(struct rt9750_info *info, struct device *dev) { int ret = 0, irqcnt = 0, irqnum = 0, len = 0; struct rt9750_desc *desc = NULL; struct device_node *np = dev->of_node; char *en_name = NULL; const char *name = NULL; dev_info(info->dev, "%s\n", __func__); if (!np) { dev_notice(info->dev, "%s: no device node\n", __func__); return -EINVAL; } info->desc = &rt9750_default_desc; desc = devm_kzalloc(dev, sizeof(struct rt9750_desc), GFP_KERNEL); if (!desc) return -ENOMEM; memcpy(desc, &rt9750_default_desc, sizeof(struct rt9750_desc)); if (of_property_read_string(np, "charger_name", &desc->chg_dev_name) < 0) dev_notice(info->dev, "%s: no charger name\n", __func__); #if (!defined(CONFIG_MTK_GPIO) || defined(CONFIG_MTK_GPIOLIB_STAND)) ret = of_get_named_gpio(np, "rt,intr_gpio", 0); if (ret < 0) return ret; info->intr_gpio = ret; ret = of_get_named_gpio(np, "rt,en_gpio", 0); if (ret < 0) return ret; info->en_gpio = ret; #else ret = of_property_read_u32(np, "rt,intr_gpio_num", &info->intr_gpio); if (ret < 0) return ret; ret = of_property_read_u32(np, "rt,en_gpio_num", &info->en_gpio); if (ret < 0) return ret; #endif dev_info(info->dev, "%s: intr/en gpio = %d, %d\n", __func__, info->intr_gpio, info->en_gpio); len = strlen(desc->chg_dev_name); en_name = devm_kzalloc(info->dev, len + 9, GFP_KERNEL); snprintf(en_name, len + 9, "%s_en_gpio", desc->chg_dev_name); /* request en gpio */ ret = devm_gpio_request_one(info->dev, info->en_gpio, GPIOF_DIR_OUT, en_name); if (ret < 0) { dev_notice(info->dev, "%s: en gpio request fail\n", __func__); return ret; } if (of_property_read_string(np, "regmap_name", &desc->regmap_name) < 0) dev_notice(info->dev, "%s: no regmap name\n", __func__); if (of_property_read_string(np, "alias_name", &desc->alias_name) < 0) dev_notice(info->dev, "%s: no alias name\n", __func__); if (of_property_read_u32(np, "vout_reg", &desc->vout_reg) < 0) dev_notice(info->dev, "%s: no vout regulation\n", __func__); if (of_property_read_u32(np, "vbat_reg", &desc->vbat_reg) < 0) dev_notice(info->dev, "%s: no vbat regulation\n", __func__); if (of_property_read_u32(np, "iococp", &desc->iococp) < 0) dev_notice(info->dev, "%s: no iococp\n", __func__); if (of_property_read_u32(np, "wdt", &desc->wdt) < 0) dev_notice(info->dev, "%s: no wdt\n", __func__); while (true) { ret = of_property_read_string_index(np, "interrupt-names", irqcnt, &name); if (ret < 0) break; irqcnt++; irqnum = rt9750_get_irq_number(info, name); if (irqnum >= 0) rt9750_irq_unmask(info, irqnum); } info->desc = desc; info->chg_props.alias_name = info->desc->alias_name; dev_info(info->dev, "%s: chg_name:%s alias:%s\n", __func__, info->desc->chg_dev_name, info->chg_props.alias_name); return 0; } static int rt9750_set_wdt(struct rt9750_info *info, const u32 us) { int ret = 0; u8 wdt_reg = 0; wdt_reg = rt9750_find_closest_reg_value_via_table(rt9750_wdt, ARRAY_SIZE(rt9750_wdt), us); dev_info(info->dev, "%s: set wdt = %dms(0x%02X)\n", __func__, us / 1000, wdt_reg); ret = rt9750_i2c_update_bits( info, RT9750_REG_CONTROL, wdt_reg << RT9750_SHIFT_WDT, RT9750_MASK_WDT ); return ret; } static int rt9750_get_vout(struct rt9750_info *info, u32 *vout) { int ret = 0; u8 reg_vout = 0; ret = rt9750_i2c_read_byte(info, RT9750_REG_VOUT_REG); if (ret < 0) return ret; reg_vout = ((ret & RT9750_MASK_VOUT) >> RT9750_SHIFT_VOUT) & 0xFF; *vout = rt9750_find_closest_real_value(RT9750_VOUT_MIN, RT9750_VOUT_MAX, RT9750_VOUT_STEP, reg_vout); return ret; } static int rt9750_set_vout(struct rt9750_info *info, u32 uV) { int ret = 0; u8 reg_vout = 0; reg_vout = rt9750_find_closest_reg_value( RT9750_VOUT_MIN, RT9750_VOUT_MAX, RT9750_VOUT_STEP, RT9750_VOUT_NUM, uV ); dev_info(info->dev, "%s: vout = %d (0x%02X)\n", __func__, uV, reg_vout); ret = rt9750_i2c_update_bits( info, RT9750_REG_VOUT_REG, reg_vout << RT9750_SHIFT_VOUT, RT9750_MASK_VOUT ); return ret; } static int rt9750_get_vbat(struct rt9750_info *info, u32 *vbat) { int ret = 0; u8 reg_vbat = 0; ret = rt9750_i2c_read_byte(info, RT9750_REG_VBAT_REG); if (ret < 0) return ret; reg_vbat = ((ret & RT9750_MASK_VBAT) >> RT9750_SHIFT_VBAT) & 0xFF; *vbat = rt9750_find_closest_real_value(RT9750_VBAT_MIN, RT9750_VBAT_MAX, RT9750_VBAT_STEP, reg_vbat); return ret; } static int rt9750_set_vbat(struct rt9750_info *info, u32 uV) { int ret = 0; u8 reg_vbat = 0; reg_vbat = rt9750_find_closest_reg_value( RT9750_VBAT_MIN, RT9750_VBAT_MAX, RT9750_VBAT_STEP, RT9750_VBAT_NUM, uV ); dev_info(info->dev, "%s: vbat = %d (0x%02X)\n", __func__, uV, reg_vbat); ret = rt9750_i2c_update_bits( info, RT9750_REG_VBAT_REG, reg_vbat << RT9750_SHIFT_VBAT, RT9750_MASK_VBAT ); return ret; } static int rt9750_set_iococp(struct rt9750_info *info, u32 uA) { int ret = 0; u8 reg_iococp = 0; reg_iococp = rt9750_find_closest_reg_value(RT9750_IOCOCP_MIN, RT9750_IOCOCP_MAX, RT9750_IOCOCP_STEP, RT9750_IOCOCP_NUM, uA); dev_info(info->dev, "%s: iococp = %d (0x%02X)\n", __func__, uA, reg_iococp); ret = rt9750_i2c_update_bits( info, RT9750_REG_PROT_DLYOCP, reg_iococp << RT9750_SHIFT_IOCOCP, RT9750_MASK_IOCOCP ); return ret; } static int rt9750_maskall_irq(struct rt9750_info *info) { int ret = 0; dev_info(info->dev, "%s\n", __func__); ret = rt9750_i2c_block_write(info, RT9750_REG_EVENT1_MASK, ARRAY_SIZE(rt9750_irq_maskall), rt9750_irq_maskall); return ret; } static int rt9750_init_irq(struct rt9750_info *info) { int ret = 0; dev_info(info->dev, "%s\n", __func__); ret = rt9750_i2c_block_write(info, RT9750_REG_EVENT1_MASK, ARRAY_SIZE(rt9750_irqmask), rt9750_irqmask); return ret; } static int rt9750_init_setting(struct rt9750_info *info) { int ret = 0; u8 evt[RT9750_IRQIDX_MAX] = {0}; ret = rt9750_maskall_irq(info); if (ret < 0) dev_notice(info->dev, "%s: mask all irq fail\n", __func__); /* clear evt */ ret = rt9750_i2c_block_read(info, RT9750_REG_EVENT1, RT9750_IRQIDX_MAX, evt); if (ret < 0) dev_notice(info->dev, "%s: read irq data fail\n", __func__); ret = rt9750_set_wdt(info, info->desc->wdt); if (ret < 0) dev_notice(info->dev, "%s: set wdt failed\n", __func__); ret = rt9750_set_vout(info, info->desc->vout_reg); if (ret < 0) dev_notice(info->dev, "%s: set vout failed\n", __func__); ret = rt9750_set_vbat(info, info->desc->vbat_reg); if (ret < 0) dev_notice(info->dev, "%s: set vbat failed\n", __func__); ret = rt9750_set_iococp(info, info->desc->iococp); if (ret < 0) dev_notice(info->dev, "%s: set iococp failed\n", __func__); ret = rt9750_init_irq(info); if (ret < 0) dev_notice(info->dev, "%s: init irq fail\n", __func__); return ret; } static int rt9750_is_switch_enable(struct rt9750_info *info, bool *en) { int ret = 0; ret = rt9750_i2c_test_bit(info, RT9750_REG_CONTROL, RT9750_SHIFT_CHG_EN); if (ret < 0) { *en = false; return ret; } *en = (ret == 0 ? false : true); dev_info(info->dev, "%s: enable = %d\n", __func__, *en); return ret; } #if 0 static int rt9750_get_vbus_adc(struct rt9750_info *info, u32 *vbus_adc) { int ret = 0; u8 data[2] = {0}; ret = rt9750_i2c_block_read(info, RT9750_REG_VBUS_ADC2, 2, data); if (ret < 0) { dev_notice(info->dev, "%s: get vbus adc failed\n", __func__); return ret; } *vbus_adc = ((data[0] & RT9750_MASK_VBUS_ADC2) << 8) + data[1]; dev_info(info->dev, "%s: vbus_adc = %dmV\n", __func__, *vbus_adc); return ret; } static int rt9750_get_vout_adc(struct rt9750_info *info, u32 *vout_adc) { int ret = 0; u8 data[2] = {0}; ret = rt9750_i2c_block_read(info, RT9750_REG_VOUT_ADC2, 2, data); if (ret < 0) { dev_notice(info->dev, "%s: get vout adc failed\n", __func__); return ret; } *vout_adc = ((data[0] & RT9750_MASK_VOUT_ADC2) << 8) + data[1]; dev_info(info->dev, "%s: vout_adc = %dmV\n", __func__, *vout_adc); return ret; } static int rt9750_get_vdrop_adc(struct rt9750_info *info, u32 *vdrop_adc) { int ret = 0; u8 data[2] = {0}; ret = rt9750_i2c_block_read(info, RT9750_REG_VDROP_ADC2, 2, data); if (ret < 0) { dev_notice(info->dev, "%s: get vdrop adc failed\n", __func__); return ret; } *vdrop_adc = ((data[0] & RT9750_MASK_VDROP_ADC2) << 8) + data[1]; dev_info(info->dev, "%s: vdrop_adc = %dmV\n", __func__, *vdrop_adc); return ret; } static int rt9750_get_vbat_adc(struct rt9750_info *info, u32 *vbat_adc) { int ret = 0; u8 data[2] = {0}; ret = rt9750_i2c_block_read(info, RT9750_REG_VBAT_ADC2, 2, data); if (ret < 0) { dev_notice(info->dev, "%s: get vbat adc failed\n", __func__); return ret; } *vbat_adc = ((data[0] & RT9750_MASK_VBAT_ADC2) << 8) + data[1]; dev_info(info->dev, "%s: vbat_adc = %dmV\n", __func__, *vbat_adc); return ret; } static int rt9750_get_tbat_adc(struct rt9750_info *info, u32 *tbat_adc) { int ret = 0; u8 data[2] = {0}; ret = rt9750_i2c_block_read(info, RT9750_REG_TBAT_ADC2, 2, data); if (ret < 0) { dev_notice(info->dev, "%s: get tbat adc failed\n", __func__); return ret; } *tbat_adc = ((data[0] & RT9750_MASK_TBAT_ADC2) << 8) + data[1]; dev_info(info->dev, "%s: tbat_adc = %ddegree\n", __func__, *tbat_adc); return ret; } static int rt9750_get_tbus_adc(struct rt9750_info *info, u32 *tbus_adc) { int ret = 0; u8 data[2] = {0}; ret = rt9750_i2c_block_read(info, RT9750_REG_TBUS_ADC2, 2, data); if (ret < 0) { dev_notice(info->dev, "%s: get tbus adc failed\n", __func__); return ret; } *tbus_adc = ((data[0] & RT9750_MASK_TBUS_ADC2) << 8) + data[1]; dev_info(info->dev, "%s: tbus_adc = %ddegree\n", __func__, *tbus_adc); return ret; } #endif /* ========================= */ /* Released function */ /* ========================= */ static int rt9750_dump_register(struct charger_device *chg_dev) { int i = 0, ret = 0; u32 vout = 0, vbat = 0; bool en = false; struct rt9750_info *info = dev_get_drvdata(&chg_dev->dev); ret = rt9750_get_vout(info, &vout); ret = rt9750_get_vbat(info, &vbat); ret = rt9750_is_switch_enable(info, &en); for (i = 0; i < ARRAY_SIZE(rt9750_reg_addr); i++) { ret = rt9750_i2c_read_byte(info, rt9750_reg_addr[i]); if (ret < 0) return ret; } dev_info(info->dev, "%s: VOUT = %dmV, VBAT = %dmV, SWITCH_EN = %d\n", __func__, vout / 1000, vbat / 1000, en); return ret; } static int _rt9750_enable_chip(struct rt9750_info *info, bool en) { dev_info(info->dev, "%s\n", __func__); mutex_lock(&info->gpio_access_lock); if (en) { /* Lock I2C to solve I2C SDA drop problem */ i2c_lock_adapter(info->i2c->adapter); gpio_set_value(info->en_gpio, 1); dev_info(info->dev, "%s: set gpio high\n", __func__); udelay(10); i2c_unlock_adapter(info->i2c->adapter); /* wait rt9750 enable, at least 200us */ mdelay(1); } else { gpio_set_value(info->en_gpio, 0); dev_info(info->dev, "%s: set gpio low\n", __func__); } info->is_chip_en = en; mutex_unlock(&info->gpio_access_lock); return 0; } static int rt9750_enable_chip(struct charger_device *chg_dev, bool en) { int ret = 0; struct rt9750_info *info = dev_get_drvdata(&chg_dev->dev); ret = _rt9750_enable_chip(info, en); if (ret < 0) { dev_notice(info->dev, "%s: enable chip failed\n", __func__); return ret; } if (en) { ret = rt9750_init_setting(info); if (ret < 0) dev_notice(info->dev, "%s: init setting failed\n", __func__); } return ret; } static int rt9750_enable_switch(struct charger_device *chg_dev, bool en) { int ret = 0; struct rt9750_info *info = dev_get_drvdata(&chg_dev->dev); dev_info(info->dev, "%s, enable = %d\n", __func__, en); ret = (en ? rt9750_set_bit : rt9750_clr_bit) (info, RT9750_REG_CONTROL, RT9750_MASK_CHG_EN); return ret; } static int rt9750_set_ibusoc(struct charger_device *chg_dev, u32 uA) { int ret = 0; struct rt9750_info *info = dev_get_drvdata(&chg_dev->dev); u8 reg_ibusoc = 0; reg_ibusoc = rt9750_find_closest_reg_value(RT9750_IBUSOC_MIN, RT9750_IBUSOC_MAX, RT9750_IBUSOC_STEP, RT9750_IBUSOC_NUM, uA); dev_info(info->dev, "%s: ibusoc = %d (0x%02X)\n", __func__, uA, reg_ibusoc); ret = rt9750_i2c_update_bits( info, RT9750_REG_IBUS_OCP, reg_ibusoc << RT9750_SHIFT_IBUS_OCP, RT9750_MASK_IBUS_OCP ); return ret; } static int rt9750_set_vbusov(struct charger_device *chg_dev, u32 uV) { int ret = 0; struct rt9750_info *info = dev_get_drvdata(&chg_dev->dev); u8 reg_vbusov = 0; reg_vbusov = rt9750_find_closest_reg_value(RT9750_VBUSOV_MIN, RT9750_VBUSOV_MAX, RT9750_VBUSOV_STEP, RT9750_VBUSOV_NUM, uV); dev_info(info->dev, "%s: vbusov = %d (0x%02X)\n", __func__, uV, reg_vbusov); ret = rt9750_i2c_update_bits( info, RT9750_REG_VBUS_OVP, reg_vbusov << RT9750_SHIFT_VBUSOVP, RT9750_MASK_VBUSOVP ); return ret; } static int rt9750_kick_wdt(struct charger_device *chg_dev) { int ret = 0; u32 vout = 0; struct rt9750_info *info = dev_get_drvdata(&chg_dev->dev); /* Any I2C operation can kick wdt */ dev_info(info->dev, "%s\n", __func__); ret = rt9750_get_vout(info, &vout); return ret; } static int rt9750_get_ibus_adc(struct charger_device *chg_dev, u32 *ibus_adc) { int ret = 0; u8 data[2] = {0}; struct rt9750_info *info = dev_get_drvdata(&chg_dev->dev); ret = rt9750_i2c_block_read(info, RT9750_REG_IBUS_ADC2, 2, data); if (ret < 0) { dev_notice(info->dev, "%s: get ibus adc failed\n", __func__); return ret; } *ibus_adc = ((data[0] & RT9750_MASK_IBUS_ADC2) << 8) + data[1]; *ibus_adc *= 1000; /* uA */ dev_info(info->dev, "%s: ibus_adc = %dmA\n", __func__, *ibus_adc); return ret; } static int rt9750_get_tdie_adc(struct charger_device *chg_dev, int *tdie_adc_min, int *tdie_adc_max) { int ret = 0; struct rt9750_info *info = dev_get_drvdata(&chg_dev->dev); ret = rt9750_i2c_read_byte(info, RT9750_REG_TDIE_ADC1); if (ret < 0) { dev_notice(info->dev, "%s: get vbus adc failed\n", __func__); return ret; } *tdie_adc_min = ret; *tdie_adc_max = ret; dev_info(info->dev, "%s: tdie_adc = %ddegree\n", __func__, *tdie_adc_min); return ret; } static struct charger_ops rt9750_chg_ops = { .enable_chip = rt9750_enable_chip, .enable_direct_charging = rt9750_enable_switch, .dump_registers = rt9750_dump_register, .kick_direct_charging_wdt = rt9750_kick_wdt, .set_direct_charging_ibusoc = rt9750_set_ibusoc, .set_direct_charging_vbusov = rt9750_set_vbusov, .get_ibus_adc = rt9750_get_ibus_adc, .get_tchg_adc = rt9750_get_tdie_adc, }; /* ========================= */ /* I2C driver function */ /* ========================= */ #if 0 static int rt9750_dbg_thread(void *data) { int ret = 0; u32 ibus_adc = 0; int tdie_min = 0, tdie_max = 0; bool en = false; struct rt9750_info *info = (struct rt9750_info *)data; dev_info(info->dev, "%s\n", __func__); ret = rt9750_enable_chip(info->chg_dev, true); while (1) { ret = rt9750_get_ibus_adc(info->chg_dev, &ibus_adc); ret = rt9750_get_tdie_adc(info->chg_dev, &tdie_min, &tdie_max); ret = rt9750_set_ibusoc(info->chg_dev, 6000000); ret = rt9750_set_vbusov(info->chg_dev, 6000000); ret = rt9750_is_switch_enable(info, &en); msleep(2000); }; return ret; } #endif static int rt9750_probe(struct i2c_client *i2c, const struct i2c_device_id *dev_id) { int ret = 0; struct rt9750_info *info = NULL; pr_info("%s: %s\n", __func__, RT9750_DRV_VERSION); info = devm_kzalloc(&i2c->dev, sizeof(struct rt9750_info), GFP_KERNEL); if (!info) return -ENOMEM; info->i2c = i2c; info->dev = &i2c->dev; info->is_chip_en = false; mutex_init(&info->i2c_access_lock); mutex_init(&info->adc_access_lock); mutex_init(&info->gpio_access_lock); ret = rt9750_parse_dt(info, &i2c->dev); if (ret < 0) { dev_notice(info->dev, "%s: parse dt failed\n", __func__); goto err_parse_dt; } /* Enable Chip */ ret = _rt9750_enable_chip(info, true); if (ret < 0) { dev_notice(info->dev, "%s: enable chip failed\n", __func__); goto err_enable_chip; } /* Is HW exist */ if (!rt9750_is_hw_exist(info)) { dev_notice(info->dev, "%s: no rt9750 exists\n", __func__); ret = -ENODEV; goto err_no_dev; } i2c_set_clientdata(i2c, info); #ifdef CONFIG_RT_REGMAP ret = rt9750_register_rt_regmap(info); if (ret < 0) goto err_register_regmap; #endif /* Register charger device */ info->chg_dev = charger_device_register(info->desc->chg_dev_name, &i2c->dev, info, &rt9750_chg_ops, &info->chg_props); if (IS_ERR_OR_NULL(info->chg_dev)) { ret = PTR_ERR(info->chg_dev); goto err_register_chg_dev; } ret = rt9750_register_irq(info); if (ret < 0) { dev_notice(info->dev, "%s: register irq failed\n", __func__); goto err_register_irq; } rt9750_dump_register(info->chg_dev); /* Disable Chip */ ret = _rt9750_enable_chip(info, false); if (ret < 0) { dev_notice(info->dev, "%s: disable chip failed\n", __func__); goto err_disable_chip; } #if 0 info->task = kthread_create(rt9750_dbg_thread, (void *)info, "dbg_thread"); if (IS_ERR(info->task)) dev_notice(info->dev, "%s: create dbg thread failed\n", __func__); wake_up_process(info->task); #endif dev_info(info->dev, "%s: ends\n", __func__); return ret; err_disable_chip: err_register_irq: err_register_chg_dev: #ifdef CONFIG_RT_REGMAP rt_regmap_device_unregister(info->regmap_dev); err_register_regmap: #endif err_no_dev: _rt9750_enable_chip(info, false); err_enable_chip: err_parse_dt: mutex_destroy(&info->i2c_access_lock); mutex_destroy(&info->adc_access_lock); mutex_destroy(&info->gpio_access_lock); return ret; } static int rt9750_remove(struct i2c_client *i2c) { int ret = 0; struct rt9750_info *info = i2c_get_clientdata(i2c); pr_info("%s\n", __func__); if (info) { #ifdef CONFIG_RT_REGMAP rt_regmap_device_unregister(info->regmap_dev); #endif charger_device_unregister(info->chg_dev); mutex_destroy(&info->i2c_access_lock); mutex_destroy(&info->adc_access_lock); mutex_destroy(&info->gpio_access_lock); } return ret; } static void rt9750_shutdown(struct i2c_client *i2c) { pr_info("%s\n", __func__); } static const struct i2c_device_id rt9750_i2c_id[] = { {"rt9750", 0}, {} }; #ifdef CONFIG_OF static const struct of_device_id rt9750_of_match[] = { { .compatible = "richtek,rt9750", }, {}, }; #else /* Not define CONFIG_OF */ #define RT9750_BUSNUM 0 static struct i2c_board_info rt9750_i2c_board_info __initdata = { I2C_BOARD_INFO("rt9750", rt9750_SALVE_ADDR) }; #endif /* CONFIG_OF */ static struct i2c_driver rt9750_i2c_driver = { .driver = { .name = "rt9750", .owner = THIS_MODULE, #ifdef CONFIG_OF .of_match_table = rt9750_of_match, #endif }, .probe = rt9750_probe, .remove = rt9750_remove, .shutdown = rt9750_shutdown, .id_table = rt9750_i2c_id, }; static int __init rt9750_init(void) { int ret = 0; #ifdef CONFIG_OF pr_info("%s: with dts\n", __func__); #else pr_info("%s: without dts\n", __func__); i2c_register_board_info(RT9750_BUSNUM, &rt9750_i2c_board_info, 1); #endif ret = i2c_add_driver(&rt9750_i2c_driver); if (ret < 0) pr_notice("%s: register i2c driver failed\n", __func__); return ret; } module_init(rt9750_init); static void __exit rt9750_exit(void) { i2c_del_driver(&rt9750_i2c_driver); } module_exit(rt9750_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("ShuFanLee "); MODULE_DESCRIPTION("RT9750 Load Switch Driver"); MODULE_VERSION(RT9750_DRV_VERSION); /* * Version Note * 1.0.10 * (1) Use GPIO API instead of pinctrl * (2) Add IRQ handlers for each IRQ * * 1.0.9 * (1) Modify init sequence in probe function * (2) Change pr_xxx to dev_xxx * * 1.0.8 * (1) Modify unit of get_ibus to uA * (2) Modify load switch name to primary_load_switch * * 1.0.7 * (1) Add 1ms delay after enabling chip * * 1.0.6 * (1) Disable chip if probed failed * * 1.0.5 * (1) Unregister charger device if probe failed * (2) Mask all irqs for now * * 1.0.4 * (1) Add set_iococp * (2) Init iococp in init_setting * * 1.0.3 * (1) Remove registering power supply class * * 1.0.2 * (1) Add interface for setting ibusoc/vbusov * (2) Write initial setting every time after enabling chip * (3) Init vout_reg/vbat_reg in init_setting * * 1.0.1 * (1) Add gpio lock for rt9750_enable_chip * * 1.0.0 * First Release */