gpio-tps68470.c (4654B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * GPIO driver for TPS68470 PMIC 4 * 5 * Copyright (C) 2017 Intel Corporation 6 * 7 * Authors: 8 * Antti Laakso <antti.laakso@intel.com> 9 * Tianshu Qiu <tian.shu.qiu@intel.com> 10 * Jian Xu Zheng <jian.xu.zheng@intel.com> 11 * Yuning Pu <yuning.pu@intel.com> 12 */ 13 14#include <linux/gpio/driver.h> 15#include <linux/mfd/tps68470.h> 16#include <linux/module.h> 17#include <linux/platform_device.h> 18#include <linux/regmap.h> 19 20#define TPS68470_N_LOGIC_OUTPUT 3 21#define TPS68470_N_REGULAR_GPIO 7 22#define TPS68470_N_GPIO (TPS68470_N_LOGIC_OUTPUT + TPS68470_N_REGULAR_GPIO) 23 24struct tps68470_gpio_data { 25 struct regmap *tps68470_regmap; 26 struct gpio_chip gc; 27}; 28 29static int tps68470_gpio_get(struct gpio_chip *gc, unsigned int offset) 30{ 31 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 32 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 33 unsigned int reg = TPS68470_REG_GPDO; 34 int val, ret; 35 36 if (offset >= TPS68470_N_REGULAR_GPIO) { 37 offset -= TPS68470_N_REGULAR_GPIO; 38 reg = TPS68470_REG_SGPO; 39 } 40 41 ret = regmap_read(regmap, reg, &val); 42 if (ret) { 43 dev_err(tps68470_gpio->gc.parent, "reg 0x%x read failed\n", 44 TPS68470_REG_SGPO); 45 return ret; 46 } 47 return !!(val & BIT(offset)); 48} 49 50static int tps68470_gpio_get_direction(struct gpio_chip *gc, 51 unsigned int offset) 52{ 53 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 54 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 55 int val, ret; 56 57 /* rest are always outputs */ 58 if (offset >= TPS68470_N_REGULAR_GPIO) 59 return GPIO_LINE_DIRECTION_OUT; 60 61 ret = regmap_read(regmap, TPS68470_GPIO_CTL_REG_A(offset), &val); 62 if (ret) { 63 dev_err(tps68470_gpio->gc.parent, "reg 0x%x read failed\n", 64 TPS68470_GPIO_CTL_REG_A(offset)); 65 return ret; 66 } 67 68 val &= TPS68470_GPIO_MODE_MASK; 69 return val >= TPS68470_GPIO_MODE_OUT_CMOS ? GPIO_LINE_DIRECTION_OUT : 70 GPIO_LINE_DIRECTION_IN; 71} 72 73static void tps68470_gpio_set(struct gpio_chip *gc, unsigned int offset, 74 int value) 75{ 76 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 77 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 78 unsigned int reg = TPS68470_REG_GPDO; 79 80 if (offset >= TPS68470_N_REGULAR_GPIO) { 81 reg = TPS68470_REG_SGPO; 82 offset -= TPS68470_N_REGULAR_GPIO; 83 } 84 85 regmap_update_bits(regmap, reg, BIT(offset), value ? BIT(offset) : 0); 86} 87 88static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset, 89 int value) 90{ 91 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 92 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 93 94 /* rest are always outputs */ 95 if (offset >= TPS68470_N_REGULAR_GPIO) 96 return 0; 97 98 /* Set the initial value */ 99 tps68470_gpio_set(gc, offset, value); 100 101 return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset), 102 TPS68470_GPIO_MODE_MASK, 103 TPS68470_GPIO_MODE_OUT_CMOS); 104} 105 106static int tps68470_gpio_input(struct gpio_chip *gc, unsigned int offset) 107{ 108 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 109 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 110 111 /* rest are always outputs */ 112 if (offset >= TPS68470_N_REGULAR_GPIO) 113 return -EINVAL; 114 115 return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset), 116 TPS68470_GPIO_MODE_MASK, 0x00); 117} 118 119static const char *tps68470_names[TPS68470_N_GPIO] = { 120 "gpio.0", "gpio.1", "gpio.2", "gpio.3", 121 "gpio.4", "gpio.5", "gpio.6", 122 "s_enable", "s_idle", "s_resetn", 123}; 124 125static int tps68470_gpio_probe(struct platform_device *pdev) 126{ 127 struct tps68470_gpio_data *tps68470_gpio; 128 129 tps68470_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps68470_gpio), 130 GFP_KERNEL); 131 if (!tps68470_gpio) 132 return -ENOMEM; 133 134 tps68470_gpio->tps68470_regmap = dev_get_drvdata(pdev->dev.parent); 135 tps68470_gpio->gc.label = "tps68470-gpio"; 136 tps68470_gpio->gc.owner = THIS_MODULE; 137 tps68470_gpio->gc.direction_input = tps68470_gpio_input; 138 tps68470_gpio->gc.direction_output = tps68470_gpio_output; 139 tps68470_gpio->gc.get = tps68470_gpio_get; 140 tps68470_gpio->gc.get_direction = tps68470_gpio_get_direction; 141 tps68470_gpio->gc.set = tps68470_gpio_set; 142 tps68470_gpio->gc.can_sleep = true; 143 tps68470_gpio->gc.names = tps68470_names; 144 tps68470_gpio->gc.ngpio = TPS68470_N_GPIO; 145 tps68470_gpio->gc.base = -1; 146 tps68470_gpio->gc.parent = &pdev->dev; 147 148 return devm_gpiochip_add_data(&pdev->dev, &tps68470_gpio->gc, tps68470_gpio); 149} 150 151static struct platform_driver tps68470_gpio_driver = { 152 .driver = { 153 .name = "tps68470-gpio", 154 }, 155 .probe = tps68470_gpio_probe, 156}; 157module_platform_driver(tps68470_gpio_driver); 158 159MODULE_ALIAS("platform:tps68470-gpio"); 160MODULE_DESCRIPTION("GPIO driver for TPS68470 PMIC"); 161MODULE_LICENSE("GPL v2");