1edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan/* 2edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * tps80031.c -- TI TPS80031/TPS80032 mfd core driver. 3edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * 4edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * MFD core driver for TI TPS80031/TPS80032 Fully Integrated 5edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * Power Management with Power Path and Battery Charger 6edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * 7edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * Copyright (c) 2012, NVIDIA Corporation. 8edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * 9edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * Author: Laxman Dewangan <ldewangan@nvidia.com> 10edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * 11edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * This program is free software; you can redistribute it and/or 12edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * modify it under the terms of the GNU General Public License as 13edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * published by the Free Software Foundation version 2. 14edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * 15edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, 16edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * whether express or implied; without even the implied warranty of 17edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * General Public License for more details. 19edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * 20edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * You should have received a copy of the GNU General Public License 21edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * along with this program; if not, write to the Free Software 22edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 23edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * 02111-1307, USA 24edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan */ 25edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 26edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/err.h> 27edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/i2c.h> 28edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/init.h> 29edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/interrupt.h> 30edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/irq.h> 31edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/mfd/core.h> 32edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/mfd/tps80031.h> 33edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/module.h> 34edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/pm.h> 35edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/regmap.h> 36edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#include <linux/slab.h> 37edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 38edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic struct resource tps80031_rtc_resources[] = { 39edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 40edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .start = TPS80031_INT_RTC_ALARM, 41edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .end = TPS80031_INT_RTC_ALARM, 42edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .flags = IORESOURCE_IRQ, 43edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 44edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 45edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 46edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan/* TPS80031 sub mfd devices */ 4730fe2b5bd5cd732a329ef31062d9d96eee7d18e4Geert Uytterhoevenstatic const struct mfd_cell tps80031_cell[] = { 48edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 49edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .name = "tps80031-pmic", 50edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 51edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 52edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .name = "tps80031-clock", 53edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 54edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 55edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .name = "tps80031-rtc", 56edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .num_resources = ARRAY_SIZE(tps80031_rtc_resources), 57edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .resources = tps80031_rtc_resources, 58edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 59edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 60edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .name = "tps80031-gpadc", 61edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 62edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 63edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .name = "tps80031-fuel-gauge", 64edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 65edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 66edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .name = "tps80031-charger", 67edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 68edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 69edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 70edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic int tps80031_slave_address[TPS80031_NUM_SLAVES] = { 71edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_I2C_ID0_ADDR, 72edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_I2C_ID1_ADDR, 73edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_I2C_ID2_ADDR, 74edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_I2C_ID3_ADDR, 75edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 76edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 77edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstruct tps80031_pupd_data { 78edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan u8 reg; 79edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan u8 pullup_bit; 80edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan u8 pulldown_bit; 81edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 82edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 83edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#define TPS80031_IRQ(_reg, _mask) \ 84edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { \ 85edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .reg_offset = (TPS80031_INT_MSK_LINE_##_reg) - \ 86edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_INT_MSK_LINE_A, \ 87edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .mask = BIT(_mask), \ 88edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 89edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 90edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic const struct regmap_irq tps80031_main_irqs[] = { 91edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_PWRON] = TPS80031_IRQ(A, 0), 92edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_RPWRON] = TPS80031_IRQ(A, 1), 93edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_SYS_VLOW] = TPS80031_IRQ(A, 2), 94edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_RTC_ALARM] = TPS80031_IRQ(A, 3), 95edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_RTC_PERIOD] = TPS80031_IRQ(A, 4), 96edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_HOT_DIE] = TPS80031_IRQ(A, 5), 97edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_VXX_SHORT] = TPS80031_IRQ(A, 6), 98edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_SPDURATION] = TPS80031_IRQ(A, 7), 99edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_WATCHDOG] = TPS80031_IRQ(B, 0), 100edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_BAT] = TPS80031_IRQ(B, 1), 101edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_SIM] = TPS80031_IRQ(B, 2), 102edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_MMC] = TPS80031_IRQ(B, 3), 103edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_RES] = TPS80031_IRQ(B, 4), 104edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_GPADC_RT] = TPS80031_IRQ(B, 5), 105edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_GPADC_SW2_EOC] = TPS80031_IRQ(B, 6), 106edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_CC_AUTOCAL] = TPS80031_IRQ(B, 7), 107edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_ID_WKUP] = TPS80031_IRQ(C, 0), 108edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_VBUSS_WKUP] = TPS80031_IRQ(C, 1), 109edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_ID] = TPS80031_IRQ(C, 2), 110edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_VBUS] = TPS80031_IRQ(C, 3), 111edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_CHRG_CTRL] = TPS80031_IRQ(C, 4), 112edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_EXT_CHRG] = TPS80031_IRQ(C, 5), 113edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_INT_CHRG] = TPS80031_IRQ(C, 6), 114edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_INT_RES2] = TPS80031_IRQ(C, 7), 115edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 116edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 117edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic struct regmap_irq_chip tps80031_irq_chip = { 118edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .name = "tps80031", 119edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .irqs = tps80031_main_irqs, 120edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .num_irqs = ARRAY_SIZE(tps80031_main_irqs), 121edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .num_regs = 3, 122edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .status_base = TPS80031_INT_STS_A, 123edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .mask_base = TPS80031_INT_MSK_LINE_A, 124edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 125edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 126edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan#define PUPD_DATA(_reg, _pulldown_bit, _pullup_bit) \ 127edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { \ 128edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .reg = TPS80031_CFG_INPUT_PUPD##_reg, \ 129edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .pulldown_bit = _pulldown_bit, \ 130edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .pullup_bit = _pullup_bit, \ 131edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 132edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 133edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic const struct tps80031_pupd_data tps80031_pupds[] = { 134edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_PREQ1] = PUPD_DATA(1, BIT(0), BIT(1)), 135edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_PREQ2A] = PUPD_DATA(1, BIT(2), BIT(3)), 136edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_PREQ2B] = PUPD_DATA(1, BIT(4), BIT(5)), 137edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_PREQ2C] = PUPD_DATA(1, BIT(6), BIT(7)), 138edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_PREQ3] = PUPD_DATA(2, BIT(0), BIT(1)), 139edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_NRES_WARM] = PUPD_DATA(2, 0, BIT(2)), 140edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_PWM_FORCE] = PUPD_DATA(2, BIT(5), 0), 141edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_CHRG_EXT_CHRG_STATZ] = PUPD_DATA(2, 0, BIT(6)), 142edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_SIM] = PUPD_DATA(3, BIT(0), BIT(1)), 143edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_MMC] = PUPD_DATA(3, BIT(2), BIT(3)), 144edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_GPADC_START] = PUPD_DATA(3, BIT(4), 0), 145edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_DVSI2C_SCL] = PUPD_DATA(4, 0, BIT(0)), 146edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_DVSI2C_SDA] = PUPD_DATA(4, 0, BIT(1)), 147edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_CTLI2C_SCL] = PUPD_DATA(4, 0, BIT(2)), 148edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan [TPS80031_CTLI2C_SDA] = PUPD_DATA(4, 0, BIT(3)), 149edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 150edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic struct tps80031 *tps80031_power_off_dev; 151edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 152edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganint tps80031_ext_power_req_config(struct device *dev, 153edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan unsigned long ext_ctrl_flag, int preq_bit, 154edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int state_reg_add, int trans_reg_add) 155edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 156edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan u8 res_ass_reg = 0; 157edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int preq_mask_bit = 0; 158edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int ret; 159edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 160edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (!(ext_ctrl_flag & TPS80031_EXT_PWR_REQ)) 161edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return 0; 162edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 163edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ext_ctrl_flag & TPS80031_PWR_REQ_INPUT_PREQ1) { 164edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan res_ass_reg = TPS80031_PREQ1_RES_ASS_A + (preq_bit >> 3); 165edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan preq_mask_bit = 5; 166edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } else if (ext_ctrl_flag & TPS80031_PWR_REQ_INPUT_PREQ2) { 167edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan res_ass_reg = TPS80031_PREQ2_RES_ASS_A + (preq_bit >> 3); 168edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan preq_mask_bit = 6; 169edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } else if (ext_ctrl_flag & TPS80031_PWR_REQ_INPUT_PREQ3) { 170edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan res_ass_reg = TPS80031_PREQ3_RES_ASS_A + (preq_bit >> 3); 171edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan preq_mask_bit = 7; 172edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 173edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 174edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan /* Configure REQ_ASS registers */ 175edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = tps80031_set_bits(dev, TPS80031_SLAVE_ID1, res_ass_reg, 176edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan BIT(preq_bit & 0x7)); 177edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) { 178edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(dev, "reg 0x%02x setbit failed, err = %d\n", 179edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan res_ass_reg, ret); 180edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return ret; 181edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 182edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 183edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan /* Unmask the PREQ */ 184edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = tps80031_clr_bits(dev, TPS80031_SLAVE_ID1, 185edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_PHOENIX_MSK_TRANSITION, BIT(preq_mask_bit)); 186edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) { 187edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(dev, "reg 0x%02x clrbit failed, err = %d\n", 188edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_PHOENIX_MSK_TRANSITION, ret); 189edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return ret; 190edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 191edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 192edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan /* Switch regulator control to resource now */ 193edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ext_ctrl_flag & (TPS80031_PWR_REQ_INPUT_PREQ2 | 194edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_PWR_REQ_INPUT_PREQ3)) { 195edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = tps80031_update(dev, TPS80031_SLAVE_ID1, state_reg_add, 196edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 0x0, TPS80031_STATE_MASK); 197edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) 198edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(dev, "reg 0x%02x update failed, err = %d\n", 199edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan state_reg_add, ret); 200edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } else { 201edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = tps80031_update(dev, TPS80031_SLAVE_ID1, trans_reg_add, 202edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_TRANS_SLEEP_OFF, 203edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_TRANS_SLEEP_MASK); 204edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) 205edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(dev, "reg 0x%02x update failed, err = %d\n", 206edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan trans_reg_add, ret); 207edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 208edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return ret; 209edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 210edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman DewanganEXPORT_SYMBOL_GPL(tps80031_ext_power_req_config); 211edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 212edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic void tps80031_power_off(void) 213edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 214edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_info(tps80031_power_off_dev->dev, "switching off PMU\n"); 215edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031_write(tps80031_power_off_dev->dev, TPS80031_SLAVE_ID1, 216edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_PHOENIX_DEV_ON, TPS80031_DEVOFF); 217edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 218edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 219edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic void tps80031_pupd_init(struct tps80031 *tps80031, 220edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan struct tps80031_platform_data *pdata) 221edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 222edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan struct tps80031_pupd_init_data *pupd_init_data = pdata->pupd_init_data; 223edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int data_size = pdata->pupd_init_data_size; 224edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int i; 225edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 226edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan for (i = 0; i < data_size; ++i) { 227edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan struct tps80031_pupd_init_data *pupd_init = &pupd_init_data[i]; 228edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan const struct tps80031_pupd_data *pupd = 229edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan &tps80031_pupds[pupd_init->input_pin]; 230edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan u8 update_value = 0; 231edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan u8 update_mask = pupd->pulldown_bit | pupd->pullup_bit; 232edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 233edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (pupd_init->setting == TPS80031_PUPD_PULLDOWN) 234edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan update_value = pupd->pulldown_bit; 235edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan else if (pupd_init->setting == TPS80031_PUPD_PULLUP) 236edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan update_value = pupd->pullup_bit; 237edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 238edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031_update(tps80031->dev, TPS80031_SLAVE_ID1, pupd->reg, 239edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan update_value, update_mask); 240edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 241edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 242edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 243edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic int tps80031_init_ext_control(struct tps80031 *tps80031, 244edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan struct tps80031_platform_data *pdata) 245edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 246edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan struct device *dev = tps80031->dev; 247edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int ret; 248edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int i; 249edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 250edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan /* Clear all external control for this rail */ 251edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan for (i = 0; i < 9; ++i) { 252edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = tps80031_write(dev, TPS80031_SLAVE_ID1, 253edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_PREQ1_RES_ASS_A + i, 0); 254edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) { 255edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(dev, "reg 0x%02x write failed, err = %d\n", 256edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_PREQ1_RES_ASS_A + i, ret); 257edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return ret; 258edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 259edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 260edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 261edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan /* Mask the PREQ */ 262edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = tps80031_set_bits(dev, TPS80031_SLAVE_ID1, 263edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_PHOENIX_MSK_TRANSITION, 0x7 << 5); 264edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) { 265edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(dev, "reg 0x%02x set_bits failed, err = %d\n", 266edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_PHOENIX_MSK_TRANSITION, ret); 267edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return ret; 268edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 269edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return ret; 270edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 271edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 272612b95cd7926d1a583e68f12e10b44b7ac80ca17Greg Kroah-Hartmanstatic int tps80031_irq_init(struct tps80031 *tps80031, int irq, int irq_base) 273edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 274edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan struct device *dev = tps80031->dev; 275edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int i, ret; 276edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 277edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan /* 278edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * The MASK register used for updating status register when 279edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * interrupt occurs and LINE register used to pass the status 280edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * to actual interrupt line. As per datasheet: 281edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * When INT_MSK_LINE [i] is set to 1, the associated interrupt 282edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * number i is INT line masked, which means that no interrupt is 283edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * generated on the INT line. 284edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * When INT_MSK_LINE [i] is set to 0, the associated interrupt 285edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * number i is line enabled: An interrupt is generated on the 286edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * INT line. 287edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * In any case, the INT_STS [i] status bit may or may not be updated, 288edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * only linked to the INT_MSK_STS [i] configuration register bit. 289edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * 290edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * When INT_MSK_STS [i] is set to 1, the associated interrupt number 291edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * i is status masked, which means that no interrupt is stored in 292edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * the INT_STS[i] status bit. Note that no interrupt number i is 293edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * generated on the INT line, even if the INT_MSK_LINE [i] register 294edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * bit is set to 0. 295edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * When INT_MSK_STS [i] is set to 0, the associated interrupt number i 296edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * is status enabled: An interrupt status is updated in the INT_STS [i] 297edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * register. The interrupt may or may not be generated on the INT line, 298edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan * depending on the INT_MSK_LINE [i] configuration register bit. 299edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan */ 300edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan for (i = 0; i < 3; i++) 301edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031_write(dev, TPS80031_SLAVE_ID2, 302edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_INT_MSK_STS_A + i, 0x00); 303edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 304edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = regmap_add_irq_chip(tps80031->regmap[TPS80031_SLAVE_ID2], irq, 305edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan IRQF_ONESHOT, irq_base, 306edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan &tps80031_irq_chip, &tps80031->irq_data); 307edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) { 308edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(dev, "add irq failed, err = %d\n", ret); 309edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return ret; 310edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 311edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return ret; 312edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 313edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 314edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic bool rd_wr_reg_id0(struct device *dev, unsigned int reg) 315edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 316edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan switch (reg) { 317edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_SMPS1_CFG_FORCE ... TPS80031_SMPS2_CFG_VOLTAGE: 318edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return true; 319edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan default: 320edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return false; 321edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 322edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 323edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 324edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic bool rd_wr_reg_id1(struct device *dev, unsigned int reg) 325edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 326edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan switch (reg) { 327edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_SECONDS_REG ... TPS80031_RTC_RESET_STATUS_REG: 328edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_VALIDITY0 ... TPS80031_VALIDITY7: 329edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_PHOENIX_START_CONDITION ... TPS80031_KEY_PRESS_DUR_CFG: 330edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_SMPS4_CFG_TRANS ... TPS80031_SMPS3_CFG_VOLTAGE: 331edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_BROADCAST_ADDR_ALL ... TPS80031_BROADCAST_ADDR_CLK_RST: 332edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_VANA_CFG_TRANS ... TPS80031_LDO7_CFG_VOLTAGE: 333edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_REGEN1_CFG_TRANS ... TPS80031_TMP_CFG_STATE: 334edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_PREQ1_RES_ASS_A ... TPS80031_PREQ3_RES_ASS_C: 335edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_SMPS_OFFSET ... TPS80031_BATDEBOUNCING: 336edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_CFG_INPUT_PUPD1 ... TPS80031_CFG_SMPS_PD: 337edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_BACKUP_REG: 338edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return true; 339edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan default: 340edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return false; 341edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 342edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 343edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 344edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic bool is_volatile_reg_id1(struct device *dev, unsigned int reg) 345edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 346edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan switch (reg) { 347edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_SMPS4_CFG_TRANS ... TPS80031_SMPS3_CFG_VOLTAGE: 348edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_VANA_CFG_TRANS ... TPS80031_LDO7_CFG_VOLTAGE: 349edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_REGEN1_CFG_TRANS ... TPS80031_TMP_CFG_STATE: 350edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_PREQ1_RES_ASS_A ... TPS80031_PREQ3_RES_ASS_C: 351edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_SMPS_OFFSET ... TPS80031_BATDEBOUNCING: 352edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_CFG_INPUT_PUPD1 ... TPS80031_CFG_SMPS_PD: 353edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return true; 354edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan default: 355edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return false; 356edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 357edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 358edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 359edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic bool rd_wr_reg_id2(struct device *dev, unsigned int reg) 360edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 361edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan switch (reg) { 362edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_USB_VENDOR_ID_LSB ... TPS80031_USB_OTG_REVISION: 363edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_GPADC_CTRL ... TPS80031_CTRL_P1: 364edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_RTCH0_LSB ... TPS80031_GPCH0_MSB: 365edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_TOGGLE1 ... TPS80031_VIBMODE: 366edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_PWM1ON ... TPS80031_PWM2OFF: 367edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_FG_REG_00 ... TPS80031_FG_REG_11: 368edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_INT_STS_A ... TPS80031_INT_MSK_STS_C: 369edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_CONTROLLER_CTRL2 ... TPS80031_LED_PWM_CTRL2: 370edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return true; 371edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan default: 372edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return false; 373edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 374edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 375edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 376edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic bool rd_wr_reg_id3(struct device *dev, unsigned int reg) 377edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 378edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan switch (reg) { 379edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan case TPS80031_GPADC_TRIM0 ... TPS80031_GPADC_TRIM18: 380edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return true; 381edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan default: 382edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return false; 383edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 384edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 385edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 386edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic const struct regmap_config tps80031_regmap_configs[] = { 387edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 388edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .reg_bits = 8, 389edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .val_bits = 8, 390edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .writeable_reg = rd_wr_reg_id0, 391edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .readable_reg = rd_wr_reg_id0, 392edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .max_register = TPS80031_MAX_REGISTER, 393edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 394edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 395edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .reg_bits = 8, 396edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .val_bits = 8, 397edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .writeable_reg = rd_wr_reg_id1, 398edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .readable_reg = rd_wr_reg_id1, 399edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .volatile_reg = is_volatile_reg_id1, 400edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .max_register = TPS80031_MAX_REGISTER, 401edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 402edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 403edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .reg_bits = 8, 404edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .val_bits = 8, 405edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .writeable_reg = rd_wr_reg_id2, 406edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .readable_reg = rd_wr_reg_id2, 407edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .max_register = TPS80031_MAX_REGISTER, 408edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 409edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { 410edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .reg_bits = 8, 411edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .val_bits = 8, 412edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .writeable_reg = rd_wr_reg_id3, 413edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .readable_reg = rd_wr_reg_id3, 414edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .max_register = TPS80031_MAX_REGISTER, 415edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 416edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 417edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 418612b95cd7926d1a583e68f12e10b44b7ac80ca17Greg Kroah-Hartmanstatic int tps80031_probe(struct i2c_client *client, 419612b95cd7926d1a583e68f12e10b44b7ac80ca17Greg Kroah-Hartman const struct i2c_device_id *id) 420edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 421334a41ce9b753ec615e8c6c50ee07d6197190610Jingoo Han struct tps80031_platform_data *pdata = dev_get_platdata(&client->dev); 422edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan struct tps80031 *tps80031; 423edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int ret; 424edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan uint8_t es_version; 425edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan uint8_t ep_ver; 426edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int i; 427edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 428edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (!pdata) { 429edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(&client->dev, "tps80031 requires platform data\n"); 430edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return -EINVAL; 431edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 432edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 433edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031 = devm_kzalloc(&client->dev, sizeof(*tps80031), GFP_KERNEL); 434edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (!tps80031) { 435edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(&client->dev, "Malloc failed for tps80031\n"); 436edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return -ENOMEM; 437edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 438edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 439edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan for (i = 0; i < TPS80031_NUM_SLAVES; i++) { 440edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (tps80031_slave_address[i] == client->addr) 441edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031->clients[i] = client; 442edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan else 443edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031->clients[i] = i2c_new_dummy(client->adapter, 444edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031_slave_address[i]); 445edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (!tps80031->clients[i]) { 446edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(&client->dev, "can't attach client %d\n", i); 447edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = -ENOMEM; 448edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan goto fail_client_reg; 449edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 450edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 451edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan i2c_set_clientdata(tps80031->clients[i], tps80031); 452edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031->regmap[i] = devm_regmap_init_i2c(tps80031->clients[i], 453edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan &tps80031_regmap_configs[i]); 454edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (IS_ERR(tps80031->regmap[i])) { 455edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = PTR_ERR(tps80031->regmap[i]); 456edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(&client->dev, 457edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan "regmap %d init failed, err %d\n", i, ret); 458edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan goto fail_client_reg; 459edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 460edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 461edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 462edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = tps80031_read(&client->dev, TPS80031_SLAVE_ID3, 463edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_JTAGVERNUM, &es_version); 464edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) { 465edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(&client->dev, 466edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan "Silicon version number read failed: %d\n", ret); 467edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan goto fail_client_reg; 468edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 469edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 470edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = tps80031_read(&client->dev, TPS80031_SLAVE_ID3, 471edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan TPS80031_EPROM_REV, &ep_ver); 472edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) { 473edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(&client->dev, 474edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan "Silicon eeprom version read failed: %d\n", ret); 475edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan goto fail_client_reg; 476edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 477edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 478edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_info(&client->dev, "ES version 0x%02x and EPROM version 0x%02x\n", 479edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan es_version, ep_ver); 480edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031->es_version = es_version; 481edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031->dev = &client->dev; 482edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan i2c_set_clientdata(client, tps80031); 483edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031->chip_info = id->driver_data; 484edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 485edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = tps80031_irq_init(tps80031, client->irq, pdata->irq_base); 486edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret) { 487edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(&client->dev, "IRQ init failed: %d\n", ret); 488edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan goto fail_client_reg; 489edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 490edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 491edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031_pupd_init(tps80031, pdata); 492edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 493edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031_init_ext_control(tps80031, pdata); 494edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 495edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan ret = mfd_add_devices(tps80031->dev, -1, 496edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031_cell, ARRAY_SIZE(tps80031_cell), 497edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan NULL, 0, 498edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan regmap_irq_get_domain(tps80031->irq_data)); 499edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (ret < 0) { 500edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret); 501edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan goto fail_mfd_add; 502edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 503edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 504edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (pdata->use_power_off && !pm_power_off) { 505edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031_power_off_dev = tps80031; 506edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan pm_power_off = tps80031_power_off; 507edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 508edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return 0; 509edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 510edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganfail_mfd_add: 511edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan regmap_del_irq_chip(client->irq, tps80031->irq_data); 512edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 513edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganfail_client_reg: 514edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan for (i = 0; i < TPS80031_NUM_SLAVES; i++) { 515edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (tps80031->clients[i] && (tps80031->clients[i] != client)) 516edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan i2c_unregister_device(tps80031->clients[i]); 517edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 518edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return ret; 519edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 520edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 521612b95cd7926d1a583e68f12e10b44b7ac80ca17Greg Kroah-Hartmanstatic int tps80031_remove(struct i2c_client *client) 522edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 523edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan struct tps80031 *tps80031 = i2c_get_clientdata(client); 524edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan int i; 525edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 526edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (tps80031_power_off_dev == tps80031) { 527edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan tps80031_power_off_dev = NULL; 528edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan pm_power_off = NULL; 529edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 530edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 531edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan mfd_remove_devices(tps80031->dev); 532edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 533edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan regmap_del_irq_chip(client->irq, tps80031->irq_data); 534edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 535edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan for (i = 0; i < TPS80031_NUM_SLAVES; i++) { 536edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan if (tps80031->clients[i] != client) 537edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan i2c_unregister_device(tps80031->clients[i]); 538edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan } 539edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return 0; 540edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 541edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 542edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic const struct i2c_device_id tps80031_id_table[] = { 543edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { "tps80031", TPS80031 }, 544edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan { "tps80032", TPS80032 }, 545f69b01c5ce4f8ecc95605e4115d653e65c2e4dccAxel Lin { } 546edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 547edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman DewanganMODULE_DEVICE_TABLE(i2c, tps80031_id_table); 548edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 549edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic struct i2c_driver tps80031_driver = { 550edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .driver = { 551edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .name = "tps80031", 552edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .owner = THIS_MODULE, 553edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan }, 554edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .probe = tps80031_probe, 555612b95cd7926d1a583e68f12e10b44b7ac80ca17Greg Kroah-Hartman .remove = tps80031_remove, 556edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan .id_table = tps80031_id_table, 557edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan}; 558edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 559edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic int __init tps80031_init(void) 560edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 561edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan return i2c_add_driver(&tps80031_driver); 562edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 563edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangansubsys_initcall(tps80031_init); 564edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 565edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganstatic void __exit tps80031_exit(void) 566edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan{ 567edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan i2c_del_driver(&tps80031_driver); 568edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan} 569edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewanganmodule_exit(tps80031_exit); 570edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman Dewangan 571edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman DewanganMODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 572edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman DewanganMODULE_DESCRIPTION("TPS80031 core driver"); 573edd7eabc85e2f8d76a933b9639bebfe7f98861e4Laxman DewanganMODULE_LICENSE("GPL v2"); 574