11b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan/* 21b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * Core driver access RC5T583 power management chip. 31b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * 41b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved. 51b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * Author: Laxman dewangan <ldewangan@nvidia.com> 61b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * 71b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * Based on code 81b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * Copyright (C) 2011 RICOH COMPANY,LTD 91b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * 101b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * This program is free software; you can redistribute it and/or modify it 111b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * under the terms and conditions of the GNU General Public License, 121b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * version 2, as published by the Free Software Foundation. 131b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * 141b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * This program is distributed in the hope it will be useful, but WITHOUT 151b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 161b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 171b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * more details. 181b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * 191b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * You should have received a copy of the GNU General Public License 201b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * along with this program. If not, see <http://www.gnu.org/licenses/>. 211b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan * 221b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan */ 231b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/interrupt.h> 241b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/irq.h> 251b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/kernel.h> 261b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/module.h> 271b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/init.h> 281b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/err.h> 291b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/slab.h> 301b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/i2c.h> 311b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/mfd/core.h> 321b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/mfd/rc5t583.h> 331b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#include <linux/regmap.h> 341b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 351b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#define RICOH_ONOFFSEL_REG 0x10 361b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#define RICOH_SWCTL_REG 0x5E 371b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 381b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstruct deepsleep_control_data { 391b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan u8 reg_add; 401b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan u8 ds_pos_bit; 411b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan}; 421b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 431b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#define DEEPSLEEP_INIT(_id, _reg, _pos) \ 441b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan { \ 451b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .reg_add = RC5T583_##_reg, \ 461b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .ds_pos_bit = _pos, \ 471b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 481b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 491b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic struct deepsleep_control_data deepsleep_data[] = { 501b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(DC0, SLPSEQ1, 0), 511b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(DC1, SLPSEQ1, 4), 521b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(DC2, SLPSEQ2, 0), 531b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(DC3, SLPSEQ2, 4), 541b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO0, SLPSEQ3, 0), 551b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO1, SLPSEQ3, 4), 561b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO2, SLPSEQ4, 0), 571b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO3, SLPSEQ4, 4), 581b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO4, SLPSEQ5, 0), 591b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO5, SLPSEQ5, 4), 601b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO6, SLPSEQ6, 0), 611b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO7, SLPSEQ6, 4), 621b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO8, SLPSEQ7, 0), 631b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(LDO9, SLPSEQ7, 4), 641b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(PSO0, SLPSEQ8, 0), 651b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(PSO1, SLPSEQ8, 4), 661b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(PSO2, SLPSEQ9, 0), 671b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(PSO3, SLPSEQ9, 4), 681b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(PSO4, SLPSEQ10, 0), 691b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(PSO5, SLPSEQ10, 4), 701b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(PSO6, SLPSEQ11, 0), 711b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan DEEPSLEEP_INIT(PSO7, SLPSEQ11, 4), 721b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan}; 731b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 741b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan#define EXT_PWR_REQ \ 751b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan (RC5T583_EXT_PWRREQ1_CONTROL | RC5T583_EXT_PWRREQ2_CONTROL) 761b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 775ac98553afe41ffb5513fa8aac6df699a70231a3Geert Uytterhoevenstatic const struct mfd_cell rc5t583_subdevs[] = { 78e1277f45d8748ff59608b140780f75390cb5400cLaxman Dewangan {.name = "rc5t583-gpio",}, 791b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan {.name = "rc5t583-regulator",}, 801b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan {.name = "rc5t583-rtc", }, 811b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan {.name = "rc5t583-key", } 821b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan}; 831b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 841b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic int __rc5t583_set_ext_pwrreq1_control(struct device *dev, 851b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan int id, int ext_pwr, int slots) 861b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan{ 871b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan int ret; 880dd96360e21ec7963aeba253261db87a32e728c6Venu Byravarasu uint8_t sleepseq_val = 0; 891b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan unsigned int en_bit; 901b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan unsigned int slot_bit; 911b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 921b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (id == RC5T583_DS_DC0) { 931b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(dev, "PWRREQ1 is invalid control for rail %d\n", id); 941b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return -EINVAL; 951b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 961b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 971b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan en_bit = deepsleep_data[id].ds_pos_bit; 981b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan slot_bit = en_bit + 1; 991b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_read(dev, deepsleep_data[id].reg_add, &sleepseq_val); 1001b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret < 0) { 1011b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(dev, "Error in reading reg 0x%x\n", 1021b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan deepsleep_data[id].reg_add); 1031b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return ret; 1041b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 1051b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1061b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan sleepseq_val &= ~(0xF << en_bit); 1071b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan sleepseq_val |= BIT(en_bit); 1081b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan sleepseq_val |= ((slots & 0x7) << slot_bit); 1091b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_set_bits(dev, RICOH_ONOFFSEL_REG, BIT(1)); 1101b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret < 0) { 1111b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(dev, "Error in updating the 0x%02x register\n", 1121b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan RICOH_ONOFFSEL_REG); 1131b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return ret; 1141b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 1151b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1161b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_write(dev, deepsleep_data[id].reg_add, sleepseq_val); 1171b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret < 0) { 1181b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(dev, "Error in writing reg 0x%x\n", 1191b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan deepsleep_data[id].reg_add); 1201b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return ret; 1211b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 1221b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1231b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (id == RC5T583_DS_LDO4) { 1241b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_write(dev, RICOH_SWCTL_REG, 0x1); 1251b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret < 0) 1261b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(dev, "Error in writing reg 0x%x\n", 1271b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan RICOH_SWCTL_REG); 1281b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 1291b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return ret; 1301b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan} 1311b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1321b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic int __rc5t583_set_ext_pwrreq2_control(struct device *dev, 1331b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan int id, int ext_pwr) 1341b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan{ 1351b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan int ret; 1361b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1371b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (id != RC5T583_DS_DC0) { 1381b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(dev, "PWRREQ2 is invalid control for rail %d\n", id); 1391b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return -EINVAL; 1401b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 1411b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1421b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_set_bits(dev, RICOH_ONOFFSEL_REG, BIT(2)); 1431b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret < 0) 1441b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(dev, "Error in updating the ONOFFSEL 0x10 register\n"); 1451b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return ret; 1461b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan} 1471b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1481b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganint rc5t583_ext_power_req_config(struct device *dev, int ds_id, 1491b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan int ext_pwr_req, int deepsleep_slot_nr) 1501b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan{ 1511b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if ((ext_pwr_req & EXT_PWR_REQ) == EXT_PWR_REQ) 1521b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return -EINVAL; 1531b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1541b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ext_pwr_req & RC5T583_EXT_PWRREQ1_CONTROL) 1551b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return __rc5t583_set_ext_pwrreq1_control(dev, ds_id, 1561b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ext_pwr_req, deepsleep_slot_nr); 1571b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1581b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ext_pwr_req & RC5T583_EXT_PWRREQ2_CONTROL) 1591b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return __rc5t583_set_ext_pwrreq2_control(dev, 1601b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ds_id, ext_pwr_req); 1611b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return 0; 1621b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan} 16382ea267f7dc853a5e6a724916a70a10656efdfc2Paul GortmakerEXPORT_SYMBOL(rc5t583_ext_power_req_config); 1641b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1651b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583, 1661b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan struct rc5t583_platform_data *pdata) 1671b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan{ 1681b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan int ret; 1691b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan int i; 1701b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan uint8_t on_off_val = 0; 1711b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1721b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan /* Clear ONOFFSEL register */ 1731b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (pdata->enable_shutdown) 1741b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan on_off_val = 0x1; 1751b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1761b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_write(rc5t583->dev, RICOH_ONOFFSEL_REG, on_off_val); 1771b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret < 0) 1781b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_warn(rc5t583->dev, "Error in writing reg %d error: %d\n", 1791b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan RICOH_ONOFFSEL_REG, ret); 1801b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1811b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_write(rc5t583->dev, RICOH_SWCTL_REG, 0x0); 1821b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret < 0) 1831b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_warn(rc5t583->dev, "Error in writing reg %d error: %d\n", 1841b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan RICOH_SWCTL_REG, ret); 1851b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1861b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan /* Clear sleep sequence register */ 1871b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan for (i = RC5T583_SLPSEQ1; i <= RC5T583_SLPSEQ11; ++i) { 1881b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_write(rc5t583->dev, i, 0x0); 1891b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret < 0) 1901b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_warn(rc5t583->dev, 1911b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan "Error in writing reg 0x%02x error: %d\n", 1921b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan i, ret); 1931b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 1941b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return 0; 1951b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan} 1961b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 1971b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic bool volatile_reg(struct device *dev, unsigned int reg) 1981b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan{ 1991b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan /* Enable caching in interrupt registers */ 2001b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan switch (reg) { 2011b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_INT_EN_SYS1: 2021b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_INT_EN_SYS2: 2031b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_INT_EN_DCDC: 2041b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_INT_EN_RTC: 2051b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_INT_EN_ADC1: 2061b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_INT_EN_ADC2: 2071b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_INT_EN_ADC3: 2081b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_GPIO_GPEDGE1: 2091b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_GPIO_GPEDGE2: 2101b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_GPIO_EN_INT: 2111b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return false; 2121b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2131b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan case RC5T583_GPIO_MON_IOIN: 2141b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan /* This is gpio input register */ 2151b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return true; 2161b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2171b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan default: 2181b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan /* Enable caching in gpio registers */ 2191b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if ((reg >= RC5T583_GPIO_IOSEL) && 2201b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan (reg <= RC5T583_GPIO_GPOFUNC)) 2211b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return false; 2221b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2231b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan /* Enable caching in sleep seq registers */ 2241b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if ((reg >= RC5T583_SLPSEQ1) && (reg <= RC5T583_SLPSEQ11)) 2251b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return false; 2261b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2271b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan /* Enable caching of regulator registers */ 2281b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if ((reg >= RC5T583_REG_DC0CTL) && (reg <= RC5T583_REG_SR3CTL)) 2291b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return false; 2301b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if ((reg >= RC5T583_REG_LDOEN1) && 2311b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan (reg <= RC5T583_REG_LDO9DAC_DS)) 2321b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return false; 2331b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2341b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan break; 2351b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 2361b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2371b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return true; 2381b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan} 2391b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2401b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic const struct regmap_config rc5t583_regmap_config = { 2411b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .reg_bits = 8, 2421b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .val_bits = 8, 2431b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .volatile_reg = volatile_reg, 2441b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .max_register = RC5T583_MAX_REGS, 2451b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .num_reg_defaults_raw = RC5T583_MAX_REGS, 2461b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .cache_type = REGCACHE_RBTREE, 2471b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan}; 2481b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 249f791be492f76dea7b0641ed227a60eeb2fa7e255Bill Pembertonstatic int rc5t583_i2c_probe(struct i2c_client *i2c, 2501b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan const struct i2c_device_id *id) 2511b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan{ 2521b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan struct rc5t583 *rc5t583; 253334a41ce9b753ec615e8c6c50ee07d6197190610Jingoo Han struct rc5t583_platform_data *pdata = dev_get_platdata(&i2c->dev); 2541b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan int ret; 2551b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan bool irq_init_success = false; 2561b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2571b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (!pdata) { 2581b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(&i2c->dev, "Err: Platform data not found\n"); 2591b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return -EINVAL; 2601b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 2611b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2621b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan rc5t583 = devm_kzalloc(&i2c->dev, sizeof(struct rc5t583), GFP_KERNEL); 2631b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (!rc5t583) { 2641b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(&i2c->dev, "Memory allocation failed\n"); 2651b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return -ENOMEM; 2661b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 2671b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2681b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan rc5t583->dev = &i2c->dev; 2691b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan i2c_set_clientdata(i2c, rc5t583); 2701b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 271f8dddc0cfe9f56ed74fd5efde8d0754f5fb73a3fAxel Lin rc5t583->regmap = devm_regmap_init_i2c(i2c, &rc5t583_regmap_config); 2721b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (IS_ERR(rc5t583->regmap)) { 2731b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = PTR_ERR(rc5t583->regmap); 2741b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); 2751b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return ret; 2761b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 2771b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2781b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_clear_ext_power_req(rc5t583, pdata); 2791b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret < 0) 280f8dddc0cfe9f56ed74fd5efde8d0754f5fb73a3fAxel Lin return ret; 2811b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2821b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (i2c->irq) { 2831b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = rc5t583_irq_init(rc5t583, i2c->irq, pdata->irq_base); 2845a4432b9544bc84168267f8e51798f7fe9b1af24Masanari Iida /* Still continue with warning, if irq init fails */ 2851b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret) 2861b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_warn(&i2c->dev, "IRQ init failed: %d\n", ret); 2871b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan else 2881b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan irq_init_success = true; 2891b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 2901b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2911b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, 2920848c94fb4a5cc213a7fb0fb3a5721ad6e16f096Mark Brown ARRAY_SIZE(rc5t583_subdevs), NULL, 0, NULL); 2931b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (ret) { 2941b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret); 2951b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan goto err_add_devs; 2961b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan } 2971b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 2981b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return 0; 2991b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3001b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganerr_add_devs: 3011b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan if (irq_init_success) 3021b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan rc5t583_irq_exit(rc5t583); 3031b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return ret; 3041b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan} 3051b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3064740f73fe5388ab5d22d552d2a0dacc62418a70cBill Pembertonstatic int rc5t583_i2c_remove(struct i2c_client *i2c) 3071b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan{ 3081b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan struct rc5t583 *rc5t583 = i2c_get_clientdata(i2c); 3091b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3101b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan mfd_remove_devices(rc5t583->dev); 3111b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan rc5t583_irq_exit(rc5t583); 3121b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return 0; 3131b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan} 3141b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3151b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic const struct i2c_device_id rc5t583_i2c_id[] = { 3161b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan {.name = "rc5t583", .driver_data = 0}, 3171b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan {} 3181b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan}; 3191b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3201b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman DewanganMODULE_DEVICE_TABLE(i2c, rc5t583_i2c_id); 3211b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3221b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic struct i2c_driver rc5t583_i2c_driver = { 3231b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .driver = { 3241b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .name = "rc5t583", 3251b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .owner = THIS_MODULE, 3261b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan }, 3271b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .probe = rc5t583_i2c_probe, 32884449216b01f9c2b4c9b1882f9d6abba07b7b7caBill Pemberton .remove = rc5t583_i2c_remove, 3291b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan .id_table = rc5t583_i2c_id, 3301b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan}; 3311b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3321b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic int __init rc5t583_i2c_init(void) 3331b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan{ 3341b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan return i2c_add_driver(&rc5t583_i2c_driver); 3351b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan} 3361b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangansubsys_initcall(rc5t583_i2c_init); 3371b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3381b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganstatic void __exit rc5t583_i2c_exit(void) 3391b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan{ 3401b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan i2c_del_driver(&rc5t583_i2c_driver); 3411b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan} 3421b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3431b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewanganmodule_exit(rc5t583_i2c_exit); 3441b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman Dewangan 3451b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman DewanganMODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 3461b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman DewanganMODULE_DESCRIPTION("RICOH RC5T583 power management system device driver"); 3471b1247dd75aa5cf5fae54a3bec7280046e9c7957Laxman DewanganMODULE_LICENSE("GPL v2"); 348