Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/gpio/gpio-bd71828.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
// Copyright (C) 2018 ROHM Semiconductors
3
4
#include <linux/gpio/driver.h>
5
#include <linux/mfd/rohm-bd71828.h>
6
#include <linux/module.h>
7
#include <linux/platform_device.h>
8
#include <linux/regmap.h>
9
10
#define GPIO_OUT_REG(off) (BD71828_REG_GPIO_CTRL1 + (off))
11
#define HALL_GPIO_OFFSET 3
12
13
struct bd71828_gpio {
14
struct regmap *regmap;
15
struct device *dev;
16
struct gpio_chip gpio;
17
};
18
19
static int bd71828_gpio_set(struct gpio_chip *chip, unsigned int offset,
20
int value)
21
{
22
struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
23
u8 val = (value) ? BD71828_GPIO_OUT_HI : BD71828_GPIO_OUT_LO;
24
25
/*
26
* The HALL input pin can only be used as input. If this is the pin
27
* we are dealing with - then we are done
28
*/
29
if (offset == HALL_GPIO_OFFSET)
30
return 0;
31
32
return regmap_update_bits(bdgpio->regmap, GPIO_OUT_REG(offset),
33
BD71828_GPIO_OUT_MASK, val);
34
}
35
36
static int bd71828_gpio_get(struct gpio_chip *chip, unsigned int offset)
37
{
38
int ret;
39
unsigned int val;
40
struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
41
42
if (offset == HALL_GPIO_OFFSET)
43
ret = regmap_read(bdgpio->regmap, BD71828_REG_IO_STAT,
44
&val);
45
else
46
ret = regmap_read(bdgpio->regmap, GPIO_OUT_REG(offset),
47
&val);
48
if (!ret)
49
ret = (val & BD71828_GPIO_OUT_MASK);
50
51
return ret;
52
}
53
54
static int bd71828_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
55
unsigned long config)
56
{
57
struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
58
59
if (offset == HALL_GPIO_OFFSET)
60
return -ENOTSUPP;
61
62
switch (pinconf_to_config_param(config)) {
63
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
64
return regmap_update_bits(bdgpio->regmap,
65
GPIO_OUT_REG(offset),
66
BD71828_GPIO_DRIVE_MASK,
67
BD71828_GPIO_OPEN_DRAIN);
68
case PIN_CONFIG_DRIVE_PUSH_PULL:
69
return regmap_update_bits(bdgpio->regmap,
70
GPIO_OUT_REG(offset),
71
BD71828_GPIO_DRIVE_MASK,
72
BD71828_GPIO_PUSH_PULL);
73
default:
74
break;
75
}
76
return -ENOTSUPP;
77
}
78
79
static int bd71828_get_direction(struct gpio_chip *chip, unsigned int offset)
80
{
81
/*
82
* Pin usage is selected by OTP data. We can't read it runtime. Hence
83
* we trust that if the pin is not excluded by "gpio-reserved-ranges"
84
* the OTP configuration is set to OUT. (Other pins but HALL input pin
85
* on BD71828 can't really be used for general purpose input - input
86
* states are used for specific cases like regulator control or
87
* PMIC_ON_REQ.
88
*/
89
if (offset == HALL_GPIO_OFFSET)
90
return GPIO_LINE_DIRECTION_IN;
91
92
return GPIO_LINE_DIRECTION_OUT;
93
}
94
95
static int bd71828_probe(struct platform_device *pdev)
96
{
97
struct device *dev = &pdev->dev;
98
struct bd71828_gpio *bdgpio;
99
100
bdgpio = devm_kzalloc(dev, sizeof(*bdgpio), GFP_KERNEL);
101
if (!bdgpio)
102
return -ENOMEM;
103
104
bdgpio->dev = dev;
105
bdgpio->gpio.parent = dev->parent;
106
bdgpio->gpio.label = "bd71828-gpio";
107
bdgpio->gpio.owner = THIS_MODULE;
108
bdgpio->gpio.get_direction = bd71828_get_direction;
109
bdgpio->gpio.set_config = bd71828_gpio_set_config;
110
bdgpio->gpio.can_sleep = true;
111
bdgpio->gpio.get = bd71828_gpio_get;
112
bdgpio->gpio.set = bd71828_gpio_set;
113
bdgpio->gpio.base = -1;
114
115
/*
116
* See if we need some implementation to mark some PINs as
117
* not controllable based on DT info or if core can handle
118
* "gpio-reserved-ranges" and exclude them from control
119
*/
120
bdgpio->gpio.ngpio = 4;
121
bdgpio->regmap = dev_get_regmap(dev->parent, NULL);
122
if (!bdgpio->regmap)
123
return -ENODEV;
124
125
return devm_gpiochip_add_data(dev, &bdgpio->gpio, bdgpio);
126
}
127
128
static struct platform_driver bd71828_gpio = {
129
.driver = {
130
.name = "bd71828-gpio"
131
},
132
.probe = bd71828_probe,
133
};
134
135
module_platform_driver(bd71828_gpio);
136
137
MODULE_AUTHOR("Matti Vaittinen <[email protected]>");
138
MODULE_DESCRIPTION("BD71828 voltage regulator driver");
139
MODULE_LICENSE("GPL");
140
MODULE_ALIAS("platform:bd71828-gpio");
141
142