Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/gpio/gpio-bd9571mwv.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* ROHM BD9571MWV-M and BD9574MWF-M GPIO driver
4
*
5
* Copyright (C) 2017 Marek Vasut <[email protected]>
6
*
7
* Based on the TPS65086 driver
8
*
9
* NOTE: Interrupts are not supported yet.
10
*/
11
12
#include <linux/gpio/driver.h>
13
#include <linux/mfd/rohm-generic.h>
14
#include <linux/module.h>
15
#include <linux/platform_device.h>
16
17
#include <linux/mfd/bd9571mwv.h>
18
19
struct bd9571mwv_gpio {
20
struct regmap *regmap;
21
struct gpio_chip chip;
22
};
23
24
static int bd9571mwv_gpio_get_direction(struct gpio_chip *chip,
25
unsigned int offset)
26
{
27
struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
28
int ret, val;
29
30
ret = regmap_read(gpio->regmap, BD9571MWV_GPIO_DIR, &val);
31
if (ret < 0)
32
return ret;
33
if (val & BIT(offset))
34
return GPIO_LINE_DIRECTION_IN;
35
36
return GPIO_LINE_DIRECTION_OUT;
37
}
38
39
static int bd9571mwv_gpio_direction_input(struct gpio_chip *chip,
40
unsigned int offset)
41
{
42
struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
43
44
regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_DIR, BIT(offset), 0);
45
46
return 0;
47
}
48
49
static int bd9571mwv_gpio_direction_output(struct gpio_chip *chip,
50
unsigned int offset, int value)
51
{
52
struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
53
54
/* Set the initial value */
55
regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_OUT,
56
BIT(offset), value ? BIT(offset) : 0);
57
regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_DIR,
58
BIT(offset), BIT(offset));
59
60
return 0;
61
}
62
63
static int bd9571mwv_gpio_get(struct gpio_chip *chip, unsigned int offset)
64
{
65
struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
66
int ret, val;
67
68
ret = regmap_read(gpio->regmap, BD9571MWV_GPIO_IN, &val);
69
if (ret < 0)
70
return ret;
71
72
return val & BIT(offset);
73
}
74
75
static int bd9571mwv_gpio_set(struct gpio_chip *chip, unsigned int offset,
76
int value)
77
{
78
struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
79
80
return regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_OUT,
81
BIT(offset), value ? BIT(offset) : 0);
82
}
83
84
static const struct gpio_chip template_chip = {
85
.label = "bd9571mwv-gpio",
86
.owner = THIS_MODULE,
87
.get_direction = bd9571mwv_gpio_get_direction,
88
.direction_input = bd9571mwv_gpio_direction_input,
89
.direction_output = bd9571mwv_gpio_direction_output,
90
.get = bd9571mwv_gpio_get,
91
.set = bd9571mwv_gpio_set,
92
.base = -1,
93
.ngpio = 2,
94
.can_sleep = true,
95
};
96
97
static int bd9571mwv_gpio_probe(struct platform_device *pdev)
98
{
99
struct bd9571mwv_gpio *gpio;
100
101
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
102
if (!gpio)
103
return -ENOMEM;
104
105
gpio->regmap = dev_get_regmap(pdev->dev.parent, NULL);
106
gpio->chip = template_chip;
107
gpio->chip.parent = pdev->dev.parent;
108
109
return devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
110
}
111
112
static const struct platform_device_id bd9571mwv_gpio_id_table[] = {
113
{ "bd9571mwv-gpio", ROHM_CHIP_TYPE_BD9571 },
114
{ "bd9574mwf-gpio", ROHM_CHIP_TYPE_BD9574 },
115
{ /* sentinel */ }
116
};
117
MODULE_DEVICE_TABLE(platform, bd9571mwv_gpio_id_table);
118
119
static struct platform_driver bd9571mwv_gpio_driver = {
120
.driver = {
121
.name = "bd9571mwv-gpio",
122
},
123
.probe = bd9571mwv_gpio_probe,
124
.id_table = bd9571mwv_gpio_id_table,
125
};
126
module_platform_driver(bd9571mwv_gpio_driver);
127
128
MODULE_AUTHOR("Marek Vasut <[email protected]>");
129
MODULE_DESCRIPTION("BD9571MWV GPIO driver");
130
MODULE_LICENSE("GPL v2");
131
132