1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 ROHM Semiconductors
3 // gpio-bd70528.c ROHM BD70528MWV gpio driver
5 #include <linux/gpio/driver.h>
6 #include <linux/mfd/rohm-bd70528.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/regmap.h>
11 #define GPIO_IN_REG(offset) (BD70528_REG_GPIO1_IN + (offset) * 2)
12 #define GPIO_OUT_REG(offset) (BD70528_REG_GPIO1_OUT + (offset) * 2)
15 struct rohm_regmap_dev chip
;
16 struct gpio_chip gpio
;
19 static int bd70528_set_debounce(struct bd70528_gpio
*bdgpio
,
20 unsigned int offset
, unsigned int debounce
)
26 val
= BD70528_DEBOUNCE_DISABLE
;
29 val
= BD70528_DEBOUNCE_15MS
;
32 val
= BD70528_DEBOUNCE_30MS
;
35 val
= BD70528_DEBOUNCE_50MS
;
38 dev_err(bdgpio
->chip
.dev
,
39 "Invalid debounce value %u\n", debounce
);
42 return regmap_update_bits(bdgpio
->chip
.regmap
, GPIO_IN_REG(offset
),
43 BD70528_DEBOUNCE_MASK
, val
);
46 static int bd70528_get_direction(struct gpio_chip
*chip
, unsigned int offset
)
48 struct bd70528_gpio
*bdgpio
= gpiochip_get_data(chip
);
51 /* Do we need to do something to IRQs here? */
52 ret
= regmap_read(bdgpio
->chip
.regmap
, GPIO_OUT_REG(offset
), &val
);
54 dev_err(bdgpio
->chip
.dev
, "Could not read gpio direction\n");
57 if (val
& BD70528_GPIO_OUT_EN_MASK
)
58 return GPIO_LINE_DIRECTION_OUT
;
60 return GPIO_LINE_DIRECTION_IN
;
63 static int bd70528_gpio_set_config(struct gpio_chip
*chip
, unsigned int offset
,
66 struct bd70528_gpio
*bdgpio
= gpiochip_get_data(chip
);
68 switch (pinconf_to_config_param(config
)) {
69 case PIN_CONFIG_DRIVE_OPEN_DRAIN
:
70 return regmap_update_bits(bdgpio
->chip
.regmap
,
72 BD70528_GPIO_DRIVE_MASK
,
73 BD70528_GPIO_OPEN_DRAIN
);
75 case PIN_CONFIG_DRIVE_PUSH_PULL
:
76 return regmap_update_bits(bdgpio
->chip
.regmap
,
78 BD70528_GPIO_DRIVE_MASK
,
79 BD70528_GPIO_PUSH_PULL
);
81 case PIN_CONFIG_INPUT_DEBOUNCE
:
82 return bd70528_set_debounce(bdgpio
, offset
,
83 pinconf_to_config_argument(config
));
91 static int bd70528_direction_input(struct gpio_chip
*chip
, unsigned int offset
)
93 struct bd70528_gpio
*bdgpio
= gpiochip_get_data(chip
);
95 /* Do we need to do something to IRQs here? */
96 return regmap_update_bits(bdgpio
->chip
.regmap
, GPIO_OUT_REG(offset
),
97 BD70528_GPIO_OUT_EN_MASK
,
98 BD70528_GPIO_OUT_DISABLE
);
101 static void bd70528_gpio_set(struct gpio_chip
*chip
, unsigned int offset
,
105 struct bd70528_gpio
*bdgpio
= gpiochip_get_data(chip
);
106 u8 val
= (value
) ? BD70528_GPIO_OUT_HI
: BD70528_GPIO_OUT_LO
;
108 ret
= regmap_update_bits(bdgpio
->chip
.regmap
, GPIO_OUT_REG(offset
),
109 BD70528_GPIO_OUT_MASK
, val
);
111 dev_err(bdgpio
->chip
.dev
, "Could not set gpio to %d\n", value
);
114 static int bd70528_direction_output(struct gpio_chip
*chip
, unsigned int offset
,
117 struct bd70528_gpio
*bdgpio
= gpiochip_get_data(chip
);
119 bd70528_gpio_set(chip
, offset
, value
);
120 return regmap_update_bits(bdgpio
->chip
.regmap
, GPIO_OUT_REG(offset
),
121 BD70528_GPIO_OUT_EN_MASK
,
122 BD70528_GPIO_OUT_ENABLE
);
125 #define GPIO_IN_STATE_MASK(offset) (BD70528_GPIO_IN_STATE_BASE << (offset))
127 static int bd70528_gpio_get_o(struct bd70528_gpio
*bdgpio
, unsigned int offset
)
132 ret
= regmap_read(bdgpio
->chip
.regmap
, GPIO_OUT_REG(offset
), &val
);
134 ret
= !!(val
& BD70528_GPIO_OUT_MASK
);
136 dev_err(bdgpio
->chip
.dev
, "GPIO (out) state read failed\n");
141 static int bd70528_gpio_get_i(struct bd70528_gpio
*bdgpio
, unsigned int offset
)
146 ret
= regmap_read(bdgpio
->chip
.regmap
, BD70528_REG_GPIO_STATE
, &val
);
149 ret
= !(val
& GPIO_IN_STATE_MASK(offset
));
151 dev_err(bdgpio
->chip
.dev
, "GPIO (in) state read failed\n");
156 static int bd70528_gpio_get(struct gpio_chip
*chip
, unsigned int offset
)
159 struct bd70528_gpio
*bdgpio
= gpiochip_get_data(chip
);
162 * There is a race condition where someone might be changing the
163 * GPIO direction after we get it but before we read the value. But
164 * application design where GPIO direction may be changed just when
165 * we read GPIO value would be pointless as reader could not know
166 * whether the returned high/low state is caused by input or output.
167 * Or then there must be other ways to mitigate the issue. Thus
168 * locking would make no sense.
170 ret
= bd70528_get_direction(chip
, offset
);
171 if (ret
== GPIO_LINE_DIRECTION_OUT
)
172 ret
= bd70528_gpio_get_o(bdgpio
, offset
);
173 else if (ret
== GPIO_LINE_DIRECTION_IN
)
174 ret
= bd70528_gpio_get_i(bdgpio
, offset
);
176 dev_err(bdgpio
->chip
.dev
, "failed to read GPIO direction\n");
181 static int bd70528_probe(struct platform_device
*pdev
)
183 struct bd70528_gpio
*bdgpio
;
184 struct rohm_regmap_dev
*bd70528
;
187 bd70528
= dev_get_drvdata(pdev
->dev
.parent
);
189 dev_err(&pdev
->dev
, "No MFD driver data\n");
193 bdgpio
= devm_kzalloc(&pdev
->dev
, sizeof(*bdgpio
),
197 bdgpio
->chip
.dev
= &pdev
->dev
;
198 bdgpio
->gpio
.parent
= pdev
->dev
.parent
;
199 bdgpio
->gpio
.label
= "bd70528-gpio";
200 bdgpio
->gpio
.owner
= THIS_MODULE
;
201 bdgpio
->gpio
.get_direction
= bd70528_get_direction
;
202 bdgpio
->gpio
.direction_input
= bd70528_direction_input
;
203 bdgpio
->gpio
.direction_output
= bd70528_direction_output
;
204 bdgpio
->gpio
.set_config
= bd70528_gpio_set_config
;
205 bdgpio
->gpio
.can_sleep
= true;
206 bdgpio
->gpio
.get
= bd70528_gpio_get
;
207 bdgpio
->gpio
.set
= bd70528_gpio_set
;
208 bdgpio
->gpio
.ngpio
= 4;
209 bdgpio
->gpio
.base
= -1;
210 #ifdef CONFIG_OF_GPIO
211 bdgpio
->gpio
.of_node
= pdev
->dev
.parent
->of_node
;
213 bdgpio
->chip
.regmap
= bd70528
->regmap
;
215 ret
= devm_gpiochip_add_data(&pdev
->dev
, &bdgpio
->gpio
,
218 dev_err(&pdev
->dev
, "gpio_init: Failed to add bd70528-gpio\n");
223 static struct platform_driver bd70528_gpio
= {
225 .name
= "bd70528-gpio"
227 .probe
= bd70528_probe
,
230 module_platform_driver(bd70528_gpio
);
232 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
233 MODULE_DESCRIPTION("BD70528 voltage regulator driver");
234 MODULE_LICENSE("GPL");
235 MODULE_ALIAS("platform:bd70528-gpio");