File Index
Files and directories
Sign in
FILE

gpio-tps68470.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpio/gpio-tps68470.c C
  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 int 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	return regmap_update_bits(regmap, reg, BIT(offset),
 86				  value ? BIT(offset) : 0);
 87}
 88
 89static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset,
 90				int value)
 91{
 92	struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
 93	struct regmap *regmap = tps68470_gpio->tps68470_regmap;
 94	int ret;
 95
 96	/* Set the initial value */
 97	ret = tps68470_gpio_set(gc, offset, value);
 98	if (ret)
 99		return ret;
100
101	/* rest are always outputs */
102	if (offset >= TPS68470_N_REGULAR_GPIO)
103		return 0;
104
105	return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset),
106				 TPS68470_GPIO_MODE_MASK,
107				 TPS68470_GPIO_MODE_OUT_CMOS);
108}
109
110static int tps68470_gpio_input(struct gpio_chip *gc, unsigned int offset)
111{
112	struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
113	struct regmap *regmap = tps68470_gpio->tps68470_regmap;
114
115	/* rest are always outputs */
116	if (offset >= TPS68470_N_REGULAR_GPIO)
117		return -EINVAL;
118
119	return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset),
120				   TPS68470_GPIO_MODE_MASK, 0x00);
121}
122
123static const char *tps68470_names[TPS68470_N_GPIO] = {
124	"gpio.0", "gpio.1", "gpio.2", "gpio.3",
125	"gpio.4", "gpio.5", "gpio.6",
126	"s_enable", "s_idle", "s_resetn",
127};
128
129static int tps68470_gpio_probe(struct platform_device *pdev)
130{
131	struct tps68470_gpio_data *tps68470_gpio;
132
133	tps68470_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps68470_gpio),
134				     GFP_KERNEL);
135	if (!tps68470_gpio)
136		return -ENOMEM;
137
138	tps68470_gpio->tps68470_regmap = dev_get_drvdata(pdev->dev.parent);
139	tps68470_gpio->gc.label = "tps68470-gpio";
140	tps68470_gpio->gc.owner = THIS_MODULE;
141	tps68470_gpio->gc.direction_input = tps68470_gpio_input;
142	tps68470_gpio->gc.direction_output = tps68470_gpio_output;
143	tps68470_gpio->gc.get = tps68470_gpio_get;
144	tps68470_gpio->gc.get_direction = tps68470_gpio_get_direction;
145	tps68470_gpio->gc.set = tps68470_gpio_set;
146	tps68470_gpio->gc.can_sleep = true;
147	tps68470_gpio->gc.names = tps68470_names;
148	tps68470_gpio->gc.ngpio = TPS68470_N_GPIO;
149	tps68470_gpio->gc.base = -1;
150	tps68470_gpio->gc.parent = &pdev->dev;
151
152	return devm_gpiochip_add_data(&pdev->dev, &tps68470_gpio->gc, tps68470_gpio);
153}
154
155static struct platform_driver tps68470_gpio_driver = {
156	.driver = {
157		   .name = "tps68470-gpio",
158	},
159	.probe = tps68470_gpio_probe,
160};
161module_platform_driver(tps68470_gpio_driver);
162
163MODULE_ALIAS("platform:tps68470-gpio");
164MODULE_DESCRIPTION("GPIO driver for TPS68470 PMIC");
165MODULE_LICENSE("GPL v2");
~/ Read-only file preview.