1 /* 2 * GPIO driver for TPS68470 PMIC 3 * 4 * Copyright (C) 2017 Intel Corporation 5 * 6 * Authors: 7 * Antti Laakso <antti.laakso@intel.com> 8 * Tianshu Qiu <tian.shu.qiu@intel.com> 9 * Jian Xu Zheng <jian.xu.zheng@intel.com> 10 * Yuning Pu <yuning.pu@intel.com> 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License as 14 * published by the Free Software Foundation version 2. 15 * 16 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 17 * kind, whether express or implied; without even the implied warranty 18 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 */ 21 22 #include <linux/gpio/driver.h> 23 #include <linux/mfd/tps68470.h> 24 #include <linux/module.h> 25 #include <linux/platform_device.h> 26 #include <linux/regmap.h> 27 28 #define TPS68470_N_LOGIC_OUTPUT 3 29 #define TPS68470_N_REGULAR_GPIO 7 30 #define TPS68470_N_GPIO (TPS68470_N_LOGIC_OUTPUT + TPS68470_N_REGULAR_GPIO) 31 32 struct tps68470_gpio_data { 33 struct regmap *tps68470_regmap; 34 struct gpio_chip gc; 35 }; 36 37 static int tps68470_gpio_get(struct gpio_chip *gc, unsigned int offset) 38 { 39 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 40 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 41 unsigned int reg = TPS68470_REG_GPDO; 42 int val, ret; 43 44 if (offset >= TPS68470_N_REGULAR_GPIO) { 45 offset -= TPS68470_N_REGULAR_GPIO; 46 reg = TPS68470_REG_SGPO; 47 } 48 49 ret = regmap_read(regmap, reg, &val); 50 if (ret) { 51 dev_err(tps68470_gpio->gc.parent, "reg 0x%x read failed\n", 52 TPS68470_REG_SGPO); 53 return ret; 54 } 55 return !!(val & BIT(offset)); 56 } 57 58 /* Return 0 if output, 1 if input */ 59 static int tps68470_gpio_get_direction(struct gpio_chip *gc, 60 unsigned int offset) 61 { 62 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 63 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 64 int val, ret; 65 66 /* rest are always outputs */ 67 if (offset >= TPS68470_N_REGULAR_GPIO) 68 return 0; 69 70 ret = regmap_read(regmap, TPS68470_GPIO_CTL_REG_A(offset), &val); 71 if (ret) { 72 dev_err(tps68470_gpio->gc.parent, "reg 0x%x read failed\n", 73 TPS68470_GPIO_CTL_REG_A(offset)); 74 return ret; 75 } 76 77 val &= TPS68470_GPIO_MODE_MASK; 78 return val >= TPS68470_GPIO_MODE_OUT_CMOS ? 0 : 1; 79 } 80 81 static void tps68470_gpio_set(struct gpio_chip *gc, unsigned int offset, 82 int value) 83 { 84 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 85 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 86 unsigned int reg = TPS68470_REG_GPDO; 87 88 if (offset >= TPS68470_N_REGULAR_GPIO) { 89 reg = TPS68470_REG_SGPO; 90 offset -= TPS68470_N_REGULAR_GPIO; 91 } 92 93 regmap_update_bits(regmap, reg, BIT(offset), value ? BIT(offset) : 0); 94 } 95 96 static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset, 97 int value) 98 { 99 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 100 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 101 102 /* rest are always outputs */ 103 if (offset >= TPS68470_N_REGULAR_GPIO) 104 return 0; 105 106 /* Set the initial value */ 107 tps68470_gpio_set(gc, offset, value); 108 109 return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset), 110 TPS68470_GPIO_MODE_MASK, 111 TPS68470_GPIO_MODE_OUT_CMOS); 112 } 113 114 static int tps68470_gpio_input(struct gpio_chip *gc, unsigned int offset) 115 { 116 struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); 117 struct regmap *regmap = tps68470_gpio->tps68470_regmap; 118 119 /* rest are always outputs */ 120 if (offset >= TPS68470_N_REGULAR_GPIO) 121 return -EINVAL; 122 123 return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset), 124 TPS68470_GPIO_MODE_MASK, 0x00); 125 } 126 127 static const char *tps68470_names[TPS68470_N_GPIO] = { 128 "gpio.0", "gpio.1", "gpio.2", "gpio.3", 129 "gpio.4", "gpio.5", "gpio.6", 130 "s_enable", "s_idle", "s_resetn", 131 }; 132 133 static int tps68470_gpio_probe(struct platform_device *pdev) 134 { 135 struct tps68470_gpio_data *tps68470_gpio; 136 int ret; 137 138 tps68470_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps68470_gpio), 139 GFP_KERNEL); 140 if (!tps68470_gpio) 141 return -ENOMEM; 142 143 tps68470_gpio->tps68470_regmap = dev_get_drvdata(pdev->dev.parent); 144 tps68470_gpio->gc.label = "tps68470-gpio"; 145 tps68470_gpio->gc.owner = THIS_MODULE; 146 tps68470_gpio->gc.direction_input = tps68470_gpio_input; 147 tps68470_gpio->gc.direction_output = tps68470_gpio_output; 148 tps68470_gpio->gc.get = tps68470_gpio_get; 149 tps68470_gpio->gc.get_direction = tps68470_gpio_get_direction; 150 tps68470_gpio->gc.set = tps68470_gpio_set; 151 tps68470_gpio->gc.can_sleep = true; 152 tps68470_gpio->gc.names = tps68470_names; 153 tps68470_gpio->gc.ngpio = TPS68470_N_GPIO; 154 tps68470_gpio->gc.base = -1; 155 tps68470_gpio->gc.parent = &pdev->dev; 156 157 ret = devm_gpiochip_add_data(&pdev->dev, &tps68470_gpio->gc, 158 tps68470_gpio); 159 if (ret < 0) { 160 dev_err(&pdev->dev, "Failed to register gpio_chip: %d\n", ret); 161 return ret; 162 } 163 164 platform_set_drvdata(pdev, tps68470_gpio); 165 166 return ret; 167 } 168 169 static struct platform_driver tps68470_gpio_driver = { 170 .driver = { 171 .name = "tps68470-gpio", 172 }, 173 .probe = tps68470_gpio_probe, 174 }; 175 176 builtin_platform_driver(tps68470_gpio_driver) 177