Linux Audio

Check our new training course

Loading...
v6.2
  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");
v5.4
  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
 50/* Return 0 if output, 1 if input */
 51static int tps68470_gpio_get_direction(struct gpio_chip *gc,
 52				       unsigned int offset)
 53{
 54	struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc);
 55	struct regmap *regmap = tps68470_gpio->tps68470_regmap;
 56	int val, ret;
 57
 58	/* rest are always outputs */
 59	if (offset >= TPS68470_N_REGULAR_GPIO)
 60		return 0;
 61
 62	ret = regmap_read(regmap, TPS68470_GPIO_CTL_REG_A(offset), &val);
 63	if (ret) {
 64		dev_err(tps68470_gpio->gc.parent, "reg 0x%x read failed\n",
 65			TPS68470_GPIO_CTL_REG_A(offset));
 66		return ret;
 67	}
 68
 69	val &= TPS68470_GPIO_MODE_MASK;
 70	return val >= TPS68470_GPIO_MODE_OUT_CMOS ? 0 : 1;
 
 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	int ret;
129
130	tps68470_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps68470_gpio),
131				     GFP_KERNEL);
132	if (!tps68470_gpio)
133		return -ENOMEM;
134
135	tps68470_gpio->tps68470_regmap = dev_get_drvdata(pdev->dev.parent);
136	tps68470_gpio->gc.label = "tps68470-gpio";
137	tps68470_gpio->gc.owner = THIS_MODULE;
138	tps68470_gpio->gc.direction_input = tps68470_gpio_input;
139	tps68470_gpio->gc.direction_output = tps68470_gpio_output;
140	tps68470_gpio->gc.get = tps68470_gpio_get;
141	tps68470_gpio->gc.get_direction = tps68470_gpio_get_direction;
142	tps68470_gpio->gc.set = tps68470_gpio_set;
143	tps68470_gpio->gc.can_sleep = true;
144	tps68470_gpio->gc.names = tps68470_names;
145	tps68470_gpio->gc.ngpio = TPS68470_N_GPIO;
146	tps68470_gpio->gc.base = -1;
147	tps68470_gpio->gc.parent = &pdev->dev;
148
149	ret = devm_gpiochip_add_data(&pdev->dev, &tps68470_gpio->gc,
150				     tps68470_gpio);
151	if (ret < 0) {
152		dev_err(&pdev->dev, "Failed to register gpio_chip: %d\n", ret);
153		return ret;
154	}
155
156	platform_set_drvdata(pdev, tps68470_gpio);
157
158	return ret;
159}
160
161static struct platform_driver tps68470_gpio_driver = {
162	.driver = {
163		   .name = "tps68470-gpio",
164	},
165	.probe = tps68470_gpio_probe,
166};
 
167
168builtin_platform_driver(tps68470_gpio_driver)