/* * driver/mfd/tps80031.c * * Core driver for TI TPS80031 * * Copyright (C) 2011 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include #include #include #include #include #include #include #include #include #include /* interrupt related registers */ #define TPS80031_INT_STS_A 0xD0 #define TPS80031_INT_STS_B 0xD1 #define TPS80031_INT_STS_C 0xD2 #define TPS80031_INT_MSK_LINE_A 0xD3 #define TPS80031_INT_MSK_LINE_B 0xD4 #define TPS80031_INT_MSK_LINE_C 0xD5 #define TPS80031_INT_MSK_STS_A 0xD6 #define TPS80031_INT_MSK_STS_B 0xD7 #define TPS80031_INT_MSK_STS_C 0xD8 #define TPS80031_CONTROLLER_STAT1 0xE3 #define CONTROLLER_STAT1_BAT_TEMP 0 #define CONTROLLER_STAT1_BAT_REMOVED 1 #define CONTROLLER_STAT1_VBUS_DET 2 #define CONTROLLER_STAT1_VAC_DET 3 #define CONTROLLER_STAT1_FAULT_WDG 4 #define CONTROLLER_STAT1_LINCH_GATED 6 #define TPS80031_CONTROLLER_INT_MASK 0xE0 #define CONTROLLER_INT_MASK_MVAC_DET 0 #define CONTROLLER_INT_MASK_MVBUS_DET 1 #define CONTROLLER_INT_MASK_MBAT_TEMP 2 #define CONTROLLER_INT_MASK_MFAULT_WDG 3 #define CONTROLLER_INT_MASK_MBAT_REMOVED 4 #define CONTROLLER_INT_MASK_MLINCH_GATED 5 #define CHARGE_CONTROL_SUB_INT_MASK 0x3F /* Version number related register */ #define TPS80031_JTAGVERNUM 0x87 /* Epprom version */ #define TPS80031_EPROM_REV 0xDF /* External control register */ #define REGEN1_BASE_ADD 0xAE #define REGEN2_BASE_ADD 0xB1 #define SYSEN_BASE_ADD 0xB4 /* device control registers */ #define TPS80031_PHOENIX_DEV_ON 0x25 #define DEVOFF 1 #define CLK32KAO_BASE_ADD 0xBA #define CLK32KG_BASE_ADD 0xBD #define CLK32KAUDIO_BASE_ADD 0xC0 #define EXT_CONTROL_CFG_TRANS 0 #define EXT_CONTROL_CFG_STATE 1 #define STATE_OFF 0x00 #define STATE_ON 0x01 #define STATE_MASK 0x03 #define TRANS_SLEEP_OFF 0x00 #define TRANS_SLEEP_ON 0x04 #define TRANS_SLEEP_MASK 0x0C #define TPS_NUM_SLAVES 4 #define EXT_PWR_REQ (PWR_REQ_INPUT_PREQ1 | PWR_REQ_INPUT_PREQ2 | \ PWR_REQ_INPUT_PREQ3) #define TPS80031_PREQ1_RES_ASS_A 0xD7 #define TPS80031_PREQ2_RES_ASS_A 0xDA #define TPS80031_PREQ3_RES_ASS_A 0xDD #define TPS80031_PHOENIX_MSK_TRANSITION 0x20 static u8 pmc_ext_control_base[] = { REGEN1_BASE_ADD, REGEN2_BASE_ADD, SYSEN_BASE_ADD, }; static u8 pmc_clk32k_control_base[] = { CLK32KAO_BASE_ADD, CLK32KG_BASE_ADD, CLK32KAUDIO_BASE_ADD, }; struct tps80031_irq_data { u8 mask_reg; u8 mask_mask; u8 is_sec_int; u8 parent_int; u8 mask_sec_int_reg; u8 int_mask_bit; u8 int_sec_sts_reg; u8 int_sts_bit; }; #define TPS80031_IRQ(_reg, _mask) \ { \ .mask_reg = (TPS80031_INT_MSK_LINE_##_reg) - \ TPS80031_INT_MSK_LINE_A, \ .mask_mask = (_mask), \ } #define TPS80031_IRQ_SEC(_reg, _mask, _pint, _sint_mask_bit, _sint_sts_bit) \ { \ .mask_reg = (TPS80031_INT_MSK_LINE_##_reg) - \ TPS80031_INT_MSK_LINE_A, \ .mask_mask = (_mask), \ .is_sec_int = true, \ .parent_int = TPS80031_INT_##_pint, \ .mask_sec_int_reg = TPS80031_CONTROLLER_INT_MASK, \ .int_mask_bit = CONTROLLER_INT_MASK_##_sint_mask_bit, \ .int_sec_sts_reg = TPS80031_CONTROLLER_STAT1, \ .int_sts_bit = CONTROLLER_STAT1_##_sint_sts_bit \ } static const struct tps80031_irq_data tps80031_irqs[] = { [TPS80031_INT_PWRON] = TPS80031_IRQ(A, 0), [TPS80031_INT_RPWRON] = TPS80031_IRQ(A, 1), [TPS80031_INT_SYS_VLOW] = TPS80031_IRQ(A, 2), [TPS80031_INT_RTC_ALARM] = TPS80031_IRQ(A, 3), [TPS80031_INT_RTC_PERIOD] = TPS80031_IRQ(A, 4), [TPS80031_INT_HOT_DIE] = TPS80031_IRQ(A, 5), [TPS80031_INT_VXX_SHORT] = TPS80031_IRQ(A, 6), [TPS80031_INT_SPDURATION] = TPS80031_IRQ(A, 7), [TPS80031_INT_WATCHDOG] = TPS80031_IRQ(B, 0), [TPS80031_INT_BAT] = TPS80031_IRQ(B, 1), [TPS80031_INT_SIM] = TPS80031_IRQ(B, 2), [TPS80031_INT_MMC] = TPS80031_IRQ(B, 3), [TPS80031_INT_RES] = TPS80031_IRQ(B, 4), [TPS80031_INT_GPADC_RT] = TPS80031_IRQ(B, 5), [TPS80031_INT_GPADC_SW2_EOC] = TPS80031_IRQ(B, 6), [TPS80031_INT_CC_AUTOCAL] = TPS80031_IRQ(B, 7), [TPS80031_INT_ID_WKUP] = TPS80031_IRQ(C, 0), [TPS80031_INT_VBUSS_WKUP] = TPS80031_IRQ(C, 1), [TPS80031_INT_ID] = TPS80031_IRQ(C, 2), [TPS80031_INT_VBUS] = TPS80031_IRQ(C, 3), [TPS80031_INT_CHRG_CTRL] = TPS80031_IRQ(C, 4), [TPS80031_INT_EXT_CHRG] = TPS80031_IRQ(C, 5), [TPS80031_INT_INT_CHRG] = TPS80031_IRQ(C, 6), [TPS80031_INT_RES2] = TPS80031_IRQ(C, 7), [TPS80031_INT_BAT_TEMP_OVRANGE] = TPS80031_IRQ_SEC(C, 4, CHRG_CTRL, MBAT_TEMP, BAT_TEMP), [TPS80031_INT_BAT_REMOVED] = TPS80031_IRQ_SEC(C, 4, CHRG_CTRL, MBAT_REMOVED, BAT_REMOVED), [TPS80031_INT_VBUS_DET] = TPS80031_IRQ_SEC(C, 4, CHRG_CTRL, MVBUS_DET, VBUS_DET), [TPS80031_INT_VAC_DET] = TPS80031_IRQ_SEC(C, 4, CHRG_CTRL, MVAC_DET, VAC_DET), [TPS80031_INT_FAULT_WDG] = TPS80031_IRQ_SEC(C, 4, CHRG_CTRL, MFAULT_WDG, FAULT_WDG), [TPS80031_INT_LINCH_GATED] = TPS80031_IRQ_SEC(C, 4, CHRG_CTRL, MLINCH_GATED, LINCH_GATED), }; static const int controller_stat1_irq_nr[] = { TPS80031_INT_BAT_TEMP_OVRANGE, TPS80031_INT_BAT_REMOVED, TPS80031_INT_VBUS_DET, TPS80031_INT_VAC_DET, TPS80031_INT_FAULT_WDG, 0, TPS80031_INT_LINCH_GATED, 0 }; /* Structure for TPS80031 Slaves */ struct tps80031_client { struct i2c_client *client; struct mutex lock; u8 addr; }; struct tps80031 { struct device *dev; unsigned long chip_info; int es_version; struct gpio_chip gpio; struct irq_chip irq_chip; struct mutex irq_lock; int irq_base; u32 irq_en; u8 mask_cache[3]; u8 mask_reg[3]; u8 cont_int_mask_reg; u8 cont_int_mask_cache; u8 cont_int_en; u8 prev_cont_stat1; struct tps80031_client tps_clients[TPS_NUM_SLAVES]; }; static inline int __tps80031_read(struct i2c_client *client, int reg, uint8_t *val) { int ret; ret = i2c_smbus_read_byte_data(client, reg); if (ret < 0) { dev_err(&client->dev, "failed reading from addr 0x%02x, reg 0x%02x\n", client->addr, reg); return ret; } *val = (uint8_t)ret; return 0; } static inline int __tps80031_reads(struct i2c_client *client, int reg, int len, uint8_t *val) { int ret; ret = i2c_smbus_read_i2c_block_data(client, reg, len, val); if (ret < 0) { dev_err(&client->dev, "failed reading from addr 0x%02x, reg 0x%02x\n", client->addr, reg); return ret; } return 0; } static inline int __tps80031_write(struct i2c_client *client, int reg, uint8_t val) { int ret; ret = i2c_smbus_write_byte_data(client, reg, val); if (ret < 0) { dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n", val, reg); return ret; } return 0; } static inline int __tps80031_writes(struct i2c_client *client, int reg, int len, uint8_t *val) { int ret; ret = i2c_smbus_write_i2c_block_data(client, reg, len, val); if (ret < 0) { dev_err(&client->dev, "failed writings to 0x%02x\n", reg); return ret; } return 0; } int tps80031_write(struct device *dev, int sid, int reg, uint8_t val) { struct tps80031 *tps80031 = dev_get_drvdata(dev); struct tps80031_client *tps = &tps80031->tps_clients[sid]; int ret; mutex_lock(&tps->lock); ret = __tps80031_write(tps->client, reg, val); mutex_unlock(&tps->lock); return ret; } EXPORT_SYMBOL_GPL(tps80031_write); int tps80031_writes(struct device *dev, int sid, int reg, int len, uint8_t *val) { struct tps80031 *tps80031 = dev_get_drvdata(dev); struct tps80031_client *tps = &tps80031->tps_clients[sid]; int ret; mutex_lock(&tps->lock); ret = __tps80031_writes(tps->client, reg, len, val); mutex_unlock(&tps->lock); return ret; } EXPORT_SYMBOL_GPL(tps80031_writes); int tps80031_read(struct device *dev, int sid, int reg, uint8_t *val) { struct tps80031 *tps80031 = dev_get_drvdata(dev); struct tps80031_client *tps = &tps80031->tps_clients[sid]; return __tps80031_read(tps->client, reg, val); } EXPORT_SYMBOL_GPL(tps80031_read); int tps80031_reads(struct device *dev, int sid, int reg, int len, uint8_t *val) { struct tps80031 *tps80031 = dev_get_drvdata(dev); struct tps80031_client *tps = &tps80031->tps_clients[sid]; return __tps80031_reads(tps->client, reg, len, val); } EXPORT_SYMBOL_GPL(tps80031_reads); int tps80031_set_bits(struct device *dev, int sid, int reg, uint8_t bit_mask) { struct tps80031 *tps80031 = dev_get_drvdata(dev); struct tps80031_client *tps = &tps80031->tps_clients[sid]; uint8_t reg_val; int ret = 0; mutex_lock(&tps->lock); ret = __tps80031_read(tps->client, reg, ®_val); if (ret) goto out; if ((reg_val & bit_mask) != bit_mask) { reg_val |= bit_mask; ret = __tps80031_write(tps->client, reg, reg_val); } out: mutex_unlock(&tps->lock); return ret; } EXPORT_SYMBOL_GPL(tps80031_set_bits); int tps80031_clr_bits(struct device *dev, int sid, int reg, uint8_t bit_mask) { struct tps80031 *tps80031 = dev_get_drvdata(dev); struct tps80031_client *tps = &tps80031->tps_clients[sid]; uint8_t reg_val; int ret = 0; mutex_lock(&tps->lock); ret = __tps80031_read(tps->client, reg, ®_val); if (ret) goto out; if (reg_val & bit_mask) { reg_val &= ~bit_mask; ret = __tps80031_write(tps->client, reg, reg_val); } out: mutex_unlock(&tps->lock); return ret; } EXPORT_SYMBOL_GPL(tps80031_clr_bits); int tps80031_update(struct device *dev, int sid, int reg, uint8_t val, uint8_t mask) { struct tps80031 *tps80031 = dev_get_drvdata(dev); struct tps80031_client *tps = &tps80031->tps_clients[sid]; uint8_t reg_val; int ret = 0; mutex_lock(&tps->lock); ret = __tps80031_read(tps->client, reg, ®_val); if (ret) goto out; if ((reg_val & mask) != val) { reg_val = (reg_val & ~mask) | (val & mask); ret = __tps80031_write(tps->client, reg, reg_val); } out: mutex_unlock(&tps->lock); return ret; } EXPORT_SYMBOL_GPL(tps80031_update); int tps80031_force_update(struct device *dev, int sid, int reg, uint8_t val, uint8_t mask) { struct tps80031 *tps80031 = dev_get_drvdata(dev); struct tps80031_client *tps = &tps80031->tps_clients[sid]; uint8_t reg_val; int ret = 0; mutex_lock(&tps->lock); ret = __tps80031_read(tps->client, reg, ®_val); if (ret) goto out; reg_val = (reg_val & ~mask) | (val & mask); ret = __tps80031_write(tps->client, reg, reg_val); out: mutex_unlock(&tps->lock); return ret; } EXPORT_SYMBOL_GPL(tps80031_force_update); int tps80031_ext_power_req_config(struct device *dev, unsigned long ext_ctrl_flag, int preq_bit, int state_reg_add, int trans_reg_add) { u8 res_ass_reg = 0; int preq_mask_bit = 0; int ret; if (!(ext_ctrl_flag & EXT_PWR_REQ)) return 0; if (ext_ctrl_flag & PWR_REQ_INPUT_PREQ1) { res_ass_reg = TPS80031_PREQ1_RES_ASS_A + (preq_bit >> 3); preq_mask_bit = 5; } else if (ext_ctrl_flag & PWR_REQ_INPUT_PREQ2) { res_ass_reg = TPS80031_PREQ2_RES_ASS_A + (preq_bit >> 3); preq_mask_bit = 6; } else if (ext_ctrl_flag & PWR_REQ_INPUT_PREQ3) { res_ass_reg = TPS80031_PREQ3_RES_ASS_A + (preq_bit >> 3); preq_mask_bit = 7; } /* Configure REQ_ASS registers */ ret = tps80031_set_bits(dev, SLAVE_ID1, res_ass_reg, BIT(preq_bit & 0x7)); if (ret < 0) { dev_err(dev, "%s() Not able to set bit %d of " "reg %d error %d\n", __func__, preq_bit, res_ass_reg, ret); return ret; } /* Unmask the PREQ */ ret = tps80031_clr_bits(dev, SLAVE_ID1, TPS80031_PHOENIX_MSK_TRANSITION, BIT(preq_mask_bit)); if (ret < 0) { dev_err(dev, "%s() Not able to clear bit %d of " "reg %d error %d\n", __func__, preq_mask_bit, TPS80031_PHOENIX_MSK_TRANSITION, ret); return ret; } /* Switch regulator control to resource now */ if (ext_ctrl_flag & (PWR_REQ_INPUT_PREQ2 | PWR_REQ_INPUT_PREQ3)) { ret = tps80031_update(dev, SLAVE_ID1, state_reg_add, 0x0, STATE_MASK); if (ret < 0) dev_err(dev, "%s() Error in writing the STATE " "register %d error %d\n", __func__, state_reg_add, ret); } else { ret = tps80031_update(dev, SLAVE_ID1, trans_reg_add, TRANS_SLEEP_OFF, TRANS_SLEEP_MASK); if (ret < 0) dev_err(dev, "%s() Error in writing the TRANS " "register %d error %d\n", __func__, trans_reg_add, ret); } return ret; } EXPORT_SYMBOL_GPL(tps80031_ext_power_req_config); unsigned long tps80031_get_chip_info(struct device *dev) { struct tps80031 *tps80031 = dev_get_drvdata(dev); return tps80031->chip_info; } EXPORT_SYMBOL_GPL(tps80031_get_chip_info); int tps80031_get_pmu_version(struct device *dev) { struct tps80031 *tps80031 = dev_get_drvdata(dev); return tps80031->es_version; } EXPORT_SYMBOL_GPL(tps80031_get_pmu_version); static struct tps80031 *tps80031_dev; int tps80031_power_off(void) { struct tps80031_client *tps = &tps80031_dev->tps_clients[SLAVE_ID1]; if (!tps->client) return -EINVAL; dev_info(&tps->client->dev, "switching off PMU\n"); return __tps80031_write(tps->client, TPS80031_PHOENIX_DEV_ON, DEVOFF); } static void tps80031_init_ext_control(struct tps80031 *tps80031, struct tps80031_platform_data *pdata) { int ret; int i; /* Clear all external control for this rail */ for (i = 0; i < 9; ++i) { tps80031_write(tps80031->dev, SLAVE_ID1, TPS80031_PREQ1_RES_ASS_A + i, 0); if (ret < 0) dev_err(tps80031->dev, "%s() Error in clearing " "register %02x\n", __func__, TPS80031_PREQ1_RES_ASS_A + i); } /* Mask the PREQ */ ret = tps80031_set_bits(tps80031->dev, SLAVE_ID1, TPS80031_PHOENIX_MSK_TRANSITION, 0x7 << 5); if (ret < 0) dev_err(tps80031->dev, "%s() Not able to mask register " "0x%02x\n", __func__, TPS80031_PHOENIX_MSK_TRANSITION); } static int tps80031_gpio_get(struct gpio_chip *gc, unsigned offset) { struct tps80031 *tps80031 = container_of(gc, struct tps80031, gpio); struct tps80031_client *tps = &tps80031->tps_clients[SLAVE_ID1]; uint8_t state; uint8_t trans; int ret; ret = __tps80031_read(tps->client, pmc_ext_control_base[offset] + EXT_CONTROL_CFG_STATE, &state); if (ret) return ret; if (state != 0) { ret = __tps80031_read(tps->client, pmc_ext_control_base[offset] + EXT_CONTROL_CFG_TRANS, &trans); if (ret) return ret; return trans & 0x1; } return 0; } static void tps80031_gpio_set(struct gpio_chip *gc, unsigned offset, int value) { struct tps80031 *tps80031 = container_of(gc, struct tps80031, gpio); tps80031_update(tps80031->dev, SLAVE_ID1, pmc_ext_control_base[offset] + EXT_CONTROL_CFG_TRANS, value, 0x1); } static int tps80031_gpio_input(struct gpio_chip *gc, unsigned offset) { return -EIO; } static int tps80031_gpio_output(struct gpio_chip *gc, unsigned offset, int value) { tps80031_gpio_set(gc, offset, value); return 0; } static int tps80031_gpio_enable(struct gpio_chip *gc, unsigned offset) { struct tps80031 *tps80031 = container_of(gc, struct tps80031, gpio); int ret; ret = tps80031_update(tps80031->dev, SLAVE_ID1, pmc_ext_control_base[offset] + EXT_CONTROL_CFG_STATE, STATE_ON, STATE_MASK); if (ret) return ret; return tps80031_write(tps80031->dev, SLAVE_ID1, pmc_ext_control_base[offset] + EXT_CONTROL_CFG_TRANS, 0x0); } static void tps80031_gpio_disable(struct gpio_chip *gc, unsigned offset) { struct tps80031 *tps80031 = container_of(gc, struct tps80031, gpio); tps80031_update(tps80031->dev, SLAVE_ID1, pmc_ext_control_base[offset] + EXT_CONTROL_CFG_STATE, STATE_OFF, STATE_MASK); } static void tps80031_gpio_init(struct tps80031 *tps80031, struct tps80031_platform_data *pdata) { int ret; int gpio_base = pdata->gpio_base; struct tps80031_client *tps = &tps80031->tps_clients[SLAVE_ID1]; struct tps80031_gpio_init_data *gpio_init_data = pdata->gpio_init_data; int data_size = pdata->gpio_init_data_size; static int preq_bit_pos[TPS80031_GPIO_NR] = {16, 17, 18}; int base_add; int i; if (gpio_base <= 0) return; /* Configure the external request mode */ for (i = 0; i < data_size; ++i) { struct tps80031_gpio_init_data *gpio_pd = &gpio_init_data[i]; base_add = pmc_ext_control_base[gpio_pd->gpio_nr]; if (gpio_pd->ext_ctrl_flag & EXT_PWR_REQ) { ret = tps80031_ext_power_req_config(tps80031->dev, gpio_pd->ext_ctrl_flag, preq_bit_pos[gpio_pd->gpio_nr], base_add + EXT_CONTROL_CFG_STATE, base_add + EXT_CONTROL_CFG_TRANS); if (ret < 0) dev_warn(tps80031->dev, "Ext pwrreq GPIO " "sleep control fails\n"); } if (gpio_pd->ext_ctrl_flag & PWR_OFF_ON_SLEEP) { ret = tps80031_update(tps80031->dev, SLAVE_ID1, base_add + EXT_CONTROL_CFG_TRANS, 0x0, 0xC); if (ret < 0) dev_warn(tps80031->dev, "GPIO OFF on sleep " "control fails\n"); } if (gpio_pd->ext_ctrl_flag & PWR_ON_ON_SLEEP) { ret = tps80031_update(tps80031->dev, SLAVE_ID1, base_add + EXT_CONTROL_CFG_TRANS, 0x4, 0xC); if (ret < 0) dev_warn(tps80031->dev, "GPIO ON on sleep " "control fails\n"); } } tps80031->gpio.owner = THIS_MODULE; tps80031->gpio.label = tps->client->name; tps80031->gpio.dev = tps80031->dev; tps80031->gpio.base = gpio_base; tps80031->gpio.ngpio = TPS80031_GPIO_NR; tps80031->gpio.can_sleep = 1; tps80031->gpio.request = tps80031_gpio_enable; tps80031->gpio.free = tps80031_gpio_disable; tps80031->gpio.direction_input = tps80031_gpio_input; tps80031->gpio.direction_output = tps80031_gpio_output; tps80031->gpio.set = tps80031_gpio_set; tps80031->gpio.get = tps80031_gpio_get; ret = gpiochip_add(&tps80031->gpio); if (ret) dev_warn(tps80031->dev, "GPIO registration failed: %d\n", ret); } static int __remove_subdev(struct device *dev, void *unused) { platform_device_unregister(to_platform_device(dev)); return 0; } static int tps80031_remove_subdevs(struct tps80031 *tps80031) { return device_for_each_child(tps80031->dev, NULL, __remove_subdev); } static void tps80031_irq_lock(struct irq_data *data) { struct tps80031 *tps80031 = irq_data_get_irq_chip_data(data); mutex_lock(&tps80031->irq_lock); } static void tps80031_irq_enable(struct irq_data *data) { struct tps80031 *tps80031 = irq_data_get_irq_chip_data(data); unsigned int __irq = data->irq - tps80031->irq_base; const struct tps80031_irq_data *irq_data = &tps80031_irqs[__irq]; if (irq_data->is_sec_int) { tps80031->cont_int_mask_reg &= ~(1 << irq_data->int_mask_bit); tps80031->cont_int_en |= (1 << irq_data->int_mask_bit); tps80031->mask_reg[irq_data->mask_reg] &= ~(1 << irq_data->mask_mask); tps80031->irq_en |= (1 << irq_data->parent_int); } else tps80031->mask_reg[irq_data->mask_reg] &= ~(1 << irq_data->mask_mask); tps80031->irq_en |= (1 << __irq); } static void tps80031_irq_disable(struct irq_data *data) { struct tps80031 *tps80031 = irq_data_get_irq_chip_data(data); unsigned int __irq = data->irq - tps80031->irq_base; const struct tps80031_irq_data *irq_data = &tps80031_irqs[__irq]; if (irq_data->is_sec_int) { tps80031->cont_int_mask_reg |= (1 << irq_data->int_mask_bit); tps80031->cont_int_en &= ~(1 << irq_data->int_mask_bit); if (!tps80031->cont_int_en) { tps80031->mask_reg[irq_data->mask_reg] |= (1 << irq_data->mask_mask); tps80031->irq_en &= ~(1 << irq_data->parent_int); } tps80031->irq_en &= ~(1 << __irq); } else tps80031->mask_reg[irq_data->mask_reg] |= (1 << irq_data->mask_mask); tps80031->irq_en &= ~(1 << __irq); } static void tps80031_irq_sync_unlock(struct irq_data *data) { struct tps80031 *tps80031 = irq_data_get_irq_chip_data(data); int i; for (i = 0; i < ARRAY_SIZE(tps80031->mask_reg); i++) { if (tps80031->mask_reg[i] != tps80031->mask_cache[i]) { if (!WARN_ON(tps80031_write(tps80031->dev, SLAVE_ID2, TPS80031_INT_MSK_LINE_A + i, tps80031->mask_reg[i]))) if (!WARN_ON(tps80031_write(tps80031->dev, SLAVE_ID2, TPS80031_INT_MSK_STS_A + i, tps80031->mask_reg[i]))) tps80031->mask_cache[i] = tps80031->mask_reg[i]; } } if (tps80031->cont_int_mask_reg != tps80031->cont_int_mask_cache) { if (!WARN_ON(tps80031_write(tps80031->dev, SLAVE_ID2, TPS80031_CONTROLLER_INT_MASK, tps80031->cont_int_mask_reg))) tps80031->cont_int_mask_cache = tps80031->cont_int_mask_reg; } mutex_unlock(&tps80031->irq_lock); } static irqreturn_t tps80031_charge_control_irq(int irq, void *data) { struct tps80031 *tps80031 = data; int ret = 0; int i; u8 cont_sts; u8 org_sts; if (irq != (tps80031->irq_base + TPS80031_INT_CHRG_CTRL)) { dev_err(tps80031->dev, "%s() Got the illegal interrupt %d\n", __func__, irq); return IRQ_NONE; } ret = tps80031_read(tps80031->dev, SLAVE_ID2, TPS80031_CONTROLLER_STAT1, &org_sts); if (ret < 0) { dev_err(tps80031->dev, "%s(): failed to read controller state1 " "status %d\n", __func__, ret); return IRQ_NONE; } /* Get change from last interrupt and mask for interested interrupt * for charge control interrupt */ cont_sts = org_sts ^ tps80031->prev_cont_stat1; tps80031->prev_cont_stat1 = org_sts; /* Clear watchdog timer state */ tps80031->prev_cont_stat1 &= ~(1 << 4); cont_sts &= 0x5F; for (i = 0; i < 8; ++i) { if (!controller_stat1_irq_nr[i]) continue; if ((cont_sts & BIT(i)) && (tps80031->irq_en & BIT(controller_stat1_irq_nr[i]))) handle_nested_irq(tps80031->irq_base + controller_stat1_irq_nr[i]); cont_sts &= ~BIT(i); } return IRQ_HANDLED; } static irqreturn_t tps80031_irq(int irq, void *data) { struct tps80031 *tps80031 = data; int ret = 0; u32 acks; int i; uint8_t tmp[3]; ret = tps80031_reads(tps80031->dev, SLAVE_ID2, TPS80031_INT_STS_A, 3, tmp); if (ret < 0) { dev_err(tps80031->dev, "failed to read interrupt status\n"); return IRQ_NONE; } acks = (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]; if (acks) { ret = tps80031_writes(tps80031->dev, SLAVE_ID2, TPS80031_INT_STS_A, 3, tmp); if (ret < 0) { dev_err(tps80031->dev, "failed to write " "interrupt status\n"); return IRQ_NONE; } while (acks) { i = __ffs(acks); if (tps80031->irq_en & (1 << i)) handle_nested_irq(tps80031->irq_base + i); acks &= ~(1 << i); } } return IRQ_HANDLED; } static int __devinit tps80031_irq_init(struct tps80031 *tps80031, int irq, int irq_base) { int i, ret; if (!irq_base) { dev_warn(tps80031->dev, "No interrupt support on IRQ base\n"); return -EINVAL; } mutex_init(&tps80031->irq_lock); for (i = 0; i < 3; i++) { tps80031->mask_reg[i] = 0xFF; tps80031->mask_cache[i] = tps80031->mask_reg[i]; tps80031_write(tps80031->dev, SLAVE_ID2, TPS80031_INT_MSK_LINE_A + i, tps80031->mask_cache[i]); tps80031_write(tps80031->dev, SLAVE_ID2, TPS80031_INT_MSK_STS_A + i, 0xFF); tps80031_write(tps80031->dev, SLAVE_ID2, TPS80031_INT_STS_A + i, 0xFF); } ret = tps80031_read(tps80031->dev, SLAVE_ID2, TPS80031_CONTROLLER_INT_MASK, &tps80031->cont_int_mask_reg); if (ret < 0) { dev_err(tps80031->dev, "Error in reading the controller_mask " "register %d\n", ret); return ret; } tps80031->cont_int_mask_reg |= CHARGE_CONTROL_SUB_INT_MASK; tps80031->cont_int_mask_cache = tps80031->cont_int_mask_reg; tps80031->cont_int_en = 0; ret = tps80031_write(tps80031->dev, SLAVE_ID2, TPS80031_CONTROLLER_INT_MASK, tps80031->cont_int_mask_reg); if (ret < 0) { dev_err(tps80031->dev, "Error in writing the controller_mask " "register %d\n", ret); return ret; } ret = tps80031_read(tps80031->dev, SLAVE_ID2, TPS80031_CONTROLLER_STAT1, &tps80031->prev_cont_stat1); if (ret < 0) { dev_err(tps80031->dev, "%s(): failed to read controller state1 " "status %d\n", __func__, ret); return ret; } /* Clear watch dog interrupt status in status */ tps80031->prev_cont_stat1 &= ~(1 << 4); tps80031->irq_base = irq_base; tps80031->irq_chip.name = "tps80031"; tps80031->irq_chip.irq_enable = tps80031_irq_enable; tps80031->irq_chip.irq_disable = tps80031_irq_disable; tps80031->irq_chip.irq_bus_lock = tps80031_irq_lock; tps80031->irq_chip.irq_bus_sync_unlock = tps80031_irq_sync_unlock; for (i = 0; i < TPS80031_INT_NR; i++) { int __irq = i + tps80031->irq_base; irq_set_chip_data(__irq, tps80031); irq_set_chip_and_handler(__irq, &tps80031->irq_chip, handle_simple_irq); irq_set_nested_thread(__irq, 1); #ifdef CONFIG_ARM set_irq_flags(__irq, IRQF_VALID); #endif } ret = request_threaded_irq(irq, NULL, tps80031_irq, IRQF_ONESHOT, "tps80031", tps80031); /* register the isr for the secondary interrupt */ if (!ret) ret = request_threaded_irq(irq_base + TPS80031_INT_CHRG_CTRL, NULL, tps80031_charge_control_irq, IRQF_ONESHOT, "80031_chg_ctl", tps80031); if (!ret) { device_init_wakeup(tps80031->dev, 1); enable_irq_wake(irq); } return ret; } static void tps80031_clk32k_enable(struct tps80031 *tps80031, int base_add) { int ret; ret = tps80031_update(tps80031->dev, SLAVE_ID1, base_add + EXT_CONTROL_CFG_STATE, STATE_ON, STATE_MASK); if (!ret) ret = tps80031_update(tps80031->dev, SLAVE_ID1, base_add + EXT_CONTROL_CFG_TRANS, STATE_ON, STATE_MASK); if (ret < 0) dev_err(tps80031->dev, "Error in updating clock register\n"); } static void tps80031_clk32k_init(struct tps80031 *tps80031, struct tps80031_platform_data *pdata) { int ret; struct tps80031_clk32k_init_data *clk32_idata = pdata->clk32k_init_data; int data_size = pdata->clk32k_init_data_size; static int clk32k_preq_bit_pos[TPS80031_CLOCK32K_NR] = {-1, 20, 19}; int base_add; int i; if (!clk32_idata || !data_size) return; /* Configure the external request mode */ for (i = 0; i < data_size; ++i) { struct tps80031_clk32k_init_data *clk32_pd = &clk32_idata[i]; base_add = pmc_clk32k_control_base[clk32_pd->clk32k_nr]; if (clk32_pd->enable) tps80031_clk32k_enable(tps80031, base_add); if ((clk32_pd->ext_ctrl_flag & EXT_PWR_REQ) && (clk32k_preq_bit_pos[clk32_pd->clk32k_nr] != -1)) { ret = tps80031_ext_power_req_config(tps80031->dev, clk32_pd->ext_ctrl_flag, clk32k_preq_bit_pos[clk32_pd->clk32k_nr], base_add + EXT_CONTROL_CFG_STATE, base_add + EXT_CONTROL_CFG_TRANS); if (ret < 0) dev_warn(tps80031->dev, "Clk32 ext control " "fails\n"); } if (clk32_pd->ext_ctrl_flag & PWR_OFF_ON_SLEEP) { ret = tps80031_update(tps80031->dev, SLAVE_ID1, base_add + EXT_CONTROL_CFG_TRANS, 0x0, 0xC); if (ret < 0) dev_warn(tps80031->dev, "clk OFF on sleep " "control fails\n"); } if (clk32_pd->ext_ctrl_flag & PWR_ON_ON_SLEEP) { ret = tps80031_update(tps80031->dev, SLAVE_ID1, base_add + EXT_CONTROL_CFG_TRANS, 0x4, 0xC); if (ret < 0) dev_warn(tps80031->dev, "clk ON sleep " "control fails\n"); } } } static int __devinit tps80031_add_subdevs(struct tps80031 *tps80031, struct tps80031_platform_data *pdata) { struct tps80031_subdev_info *subdev; struct platform_device *pdev; int i, ret = 0; for (i = 0; i < pdata->num_subdevs; i++) { subdev = &pdata->subdevs[i]; pdev = platform_device_alloc(subdev->name, subdev->id); pdev->dev.parent = tps80031->dev; pdev->dev.platform_data = subdev->platform_data; ret = platform_device_add(pdev); if (ret) goto failed; } return 0; failed: tps80031_remove_subdevs(tps80031); return ret; } #ifdef CONFIG_DEBUG_FS #include #include static void print_regs(const char *header, struct seq_file *s, int sid, int start_offset, int end_offset) { struct tps80031 *tps80031 = s->private; struct tps80031_client *tps = &tps80031->tps_clients[sid]; uint8_t reg_val; int i; int ret; seq_printf(s, "%s\n", header); for (i = start_offset; i <= end_offset; ++i) { ret = __tps80031_read(tps->client, i, ®_val); if (ret >= 0) seq_printf(s, "Addr = 0x%02x Reg 0x%02x Value 0x%02x\n", tps->client->addr, i, reg_val); } seq_printf(s, "------------------\n"); } static int dbg_tps_show(struct seq_file *s, void *unused) { seq_printf(s, "TPS80031 Registers\n"); seq_printf(s, "------------------\n"); print_regs("VIO Regs", s, SLAVE_ID1, 0x47, 0x49); print_regs("VIO Regs", s, SLAVE_ID0, 0x49, 0x4A); print_regs("SMPS1 Regs", s, SLAVE_ID1, 0x53, 0x54); print_regs("SMPS1 Regs", s, SLAVE_ID0, 0x55, 0x56); print_regs("SMPS1 Regs", s, SLAVE_ID1, 0x57, 0x57); print_regs("SMPS2 Regs", s, SLAVE_ID1, 0x59, 0x5B); print_regs("SMPS2 Regs", s, SLAVE_ID0, 0x5B, 0x5C); print_regs("SMPS2 Regs", s, SLAVE_ID1, 0x5C, 0x5D); print_regs("SMPS3 Regs", s, SLAVE_ID1, 0x65, 0x68); print_regs("SMPS4 Regs", s, SLAVE_ID1, 0x41, 0x44); print_regs("VANA Regs", s, SLAVE_ID1, 0x81, 0x83); print_regs("VRTC Regs", s, SLAVE_ID1, 0xC3, 0xC4); print_regs("LDO1 Regs", s, SLAVE_ID1, 0x9D, 0x9F); print_regs("LDO2 Regs", s, SLAVE_ID1, 0x85, 0x87); print_regs("LDO3 Regs", s, SLAVE_ID1, 0x8D, 0x8F); print_regs("LDO4 Regs", s, SLAVE_ID1, 0x89, 0x8B); print_regs("LDO5 Regs", s, SLAVE_ID1, 0x99, 0x9B); print_regs("LDO6 Regs", s, SLAVE_ID1, 0x91, 0x93); print_regs("LDO7 Regs", s, SLAVE_ID1, 0xA5, 0xA7); print_regs("LDOUSB Regs", s, SLAVE_ID1, 0xA1, 0xA3); print_regs("LDOLN Regs", s, SLAVE_ID1, 0x95, 0x97); print_regs("REGEN1 Regs", s, SLAVE_ID1, 0xAE, 0xAF); print_regs("REGEN2 Regs", s, SLAVE_ID1, 0xB1, 0xB2); print_regs("SYSEN Regs", s, SLAVE_ID1, 0xB4, 0xB5); print_regs("CLK32KAO Regs", s, SLAVE_ID1, 0xBA, 0xBB); print_regs("CLK32KG Regs", s, SLAVE_ID1, 0xBD, 0xBE); print_regs("CLK32KAUD Regs", s, SLAVE_ID1, 0xC0, 0xC1); print_regs("INT Regs", s, SLAVE_ID2, 0xD0, 0xD8); print_regs("PREQ Regs", s, SLAVE_ID1, 0xD7, 0xDF); print_regs("MASK_PH Regs", s, SLAVE_ID1, 0x20, 0x21); print_regs("PMC MISC Regs", s, SLAVE_ID1, 0xE0, 0xEF); print_regs("CONT_STATE", s, SLAVE_ID2, 0xE0, 0xE4); print_regs("VERNUM Regs", s, SLAVE_ID3, 0x87, 0x87); print_regs("EEPROM Regs", s, SLAVE_ID3, 0xDF, 0xDF); print_regs("CHARGE Regs", s, SLAVE_ID2, 0xDA, 0xF5); return 0; } static int dbg_tps_open(struct inode *inode, struct file *file) { return single_open(file, dbg_tps_show, inode->i_private); } static const struct file_operations debug_fops = { .open = dbg_tps_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static void __init tps80031_debuginit(struct tps80031 *tps) { (void)debugfs_create_file("tps80031", S_IRUGO, NULL, tps, &debug_fops); } #else static void __init tps80031_debuginit(struct tps80031 *tpsi) { return; } #endif static int __devexit tps80031_i2c_remove(struct i2c_client *client) { struct tps80031 *tps80031 = i2c_get_clientdata(client); int i; if (client->irq) free_irq(client->irq, tps80031); if (tps80031->gpio.owner != NULL) if (gpiochip_remove(&tps80031->gpio) < 0) dev_err(&client->dev, "Error in removing the gpio driver\n"); for (i = 0; i < TPS_NUM_SLAVES; i++) { struct tps80031_client *tps = &tps80031->tps_clients[i]; if (tps->client && tps->client != client) i2c_unregister_device(tps->client); tps80031->tps_clients[i].client = NULL; mutex_destroy(&tps->lock); } kfree(tps80031); return 0; } static int __devinit tps80031_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct tps80031_platform_data *pdata = client->dev.platform_data; struct tps80031 *tps80031; struct tps80031_client *tps; int ret; int jtag_ver; int ep_ver; int i; if (!pdata) { dev_err(&client->dev, "tps80031 requires platform data\n"); return -ENOTSUPP; } jtag_ver = i2c_smbus_read_byte_data(client, TPS80031_JTAGVERNUM); if (jtag_ver < 0) { dev_err(&client->dev, "Silicon version number read" " failed: %d\n", jtag_ver); return -EIO; } ep_ver = i2c_smbus_read_byte_data(client, TPS80031_EPROM_REV); if (ep_ver < 0) { dev_err(&client->dev, "Silicon eeprom version read" " failed: %d\n", ep_ver); return -EIO; } dev_info(&client->dev, "Jtag version 0x%02x and Eeprom version 0x%02x\n", jtag_ver, ep_ver); tps80031 = kzalloc(sizeof(struct tps80031), GFP_KERNEL); if (tps80031 == NULL) return -ENOMEM; tps80031->es_version = jtag_ver; tps80031->dev = &client->dev; i2c_set_clientdata(client, tps80031); tps80031->chip_info = id->driver_data; /* Set up slaves */ tps80031->tps_clients[SLAVE_ID0].addr = I2C_ID0_ADDR; tps80031->tps_clients[SLAVE_ID1].addr = I2C_ID1_ADDR; tps80031->tps_clients[SLAVE_ID2].addr = I2C_ID2_ADDR; tps80031->tps_clients[SLAVE_ID3].addr = I2C_ID3_ADDR; for (i = 0; i < TPS_NUM_SLAVES; i++) { tps = &tps80031->tps_clients[i]; if (tps->addr == client->addr) tps->client = client; else tps->client = i2c_new_dummy(client->adapter, tps->addr); if (!tps->client) { dev_err(&client->dev, "can't attach client %d\n", i); ret = -ENOMEM; goto fail; } i2c_set_clientdata(tps->client, tps80031); mutex_init(&tps->lock); } if (client->irq) { ret = tps80031_irq_init(tps80031, client->irq, pdata->irq_base); if (ret) { dev_err(&client->dev, "IRQ init failed: %d\n", ret); goto fail; } } tps80031_init_ext_control(tps80031, pdata); ret = tps80031_add_subdevs(tps80031, pdata); if (ret) { dev_err(&client->dev, "add devices failed: %d\n", ret); goto fail; } tps80031_gpio_init(tps80031, pdata); tps80031_clk32k_init(tps80031, pdata); tps80031_debuginit(tps80031); tps80031_dev = tps80031; return 0; fail: tps80031_i2c_remove(client); return ret; } #ifdef CONFIG_PM static int tps80031_i2c_suspend(struct i2c_client *client, pm_message_t state) { if (client->irq) disable_irq(client->irq); return 0; } static int tps80031_i2c_resume(struct i2c_client *client) { if (client->irq) enable_irq(client->irq); return 0; } #endif static const struct i2c_device_id tps80031_id_table[] = { { "tps80031", TPS80031 }, { "tps80032", TPS80032 }, }; MODULE_DEVICE_TABLE(i2c, tps80031_id_table); static struct i2c_driver tps80031_driver = { .driver = { .name = "tps80031", .owner = THIS_MODULE, }, .probe = tps80031_i2c_probe, .remove = __devexit_p(tps80031_i2c_remove), #ifdef CONFIG_PM .suspend = tps80031_i2c_suspend, .resume = tps80031_i2c_resume, #endif .id_table = tps80031_id_table, }; static int __init tps80031_init(void) { return i2c_add_driver(&tps80031_driver); } subsys_initcall(tps80031_init); static void __exit tps80031_exit(void) { i2c_del_driver(&tps80031_driver); } module_exit(tps80031_exit); MODULE_DESCRIPTION("TPS80031 core driver"); MODULE_LICENSE("GPL");