1 // SPDX-License-Identifier: GPL-2.0-only
3 * ROHM BD9571MWV-M and BD9574MWF-M GPIO driver
5 * Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com>
7 * Based on the TPS65086 driver
9 * NOTE: Interrupts are not supported yet.
12 #include <linux/gpio/driver.h>
13 #include <linux/mfd/rohm-generic.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
17 #include <linux/mfd/bd9571mwv.h>
19 struct bd9571mwv_gpio
{
20 struct regmap
*regmap
;
21 struct gpio_chip chip
;
24 static int bd9571mwv_gpio_get_direction(struct gpio_chip
*chip
,
27 struct bd9571mwv_gpio
*gpio
= gpiochip_get_data(chip
);
30 ret
= regmap_read(gpio
->regmap
, BD9571MWV_GPIO_DIR
, &val
);
33 if (val
& BIT(offset
))
34 return GPIO_LINE_DIRECTION_IN
;
36 return GPIO_LINE_DIRECTION_OUT
;
39 static int bd9571mwv_gpio_direction_input(struct gpio_chip
*chip
,
42 struct bd9571mwv_gpio
*gpio
= gpiochip_get_data(chip
);
44 regmap_update_bits(gpio
->regmap
, BD9571MWV_GPIO_DIR
, BIT(offset
), 0);
49 static int bd9571mwv_gpio_direction_output(struct gpio_chip
*chip
,
50 unsigned int offset
, int value
)
52 struct bd9571mwv_gpio
*gpio
= gpiochip_get_data(chip
);
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
));
63 static int bd9571mwv_gpio_get(struct gpio_chip
*chip
, unsigned int offset
)
65 struct bd9571mwv_gpio
*gpio
= gpiochip_get_data(chip
);
68 ret
= regmap_read(gpio
->regmap
, BD9571MWV_GPIO_IN
, &val
);
72 return val
& BIT(offset
);
75 static void bd9571mwv_gpio_set(struct gpio_chip
*chip
, unsigned int offset
,
78 struct bd9571mwv_gpio
*gpio
= gpiochip_get_data(chip
);
80 regmap_update_bits(gpio
->regmap
, BD9571MWV_GPIO_OUT
,
81 BIT(offset
), value
? BIT(offset
) : 0);
84 static const struct gpio_chip template_chip
= {
85 .label
= "bd9571mwv-gpio",
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
,
97 static int bd9571mwv_gpio_probe(struct platform_device
*pdev
)
99 struct bd9571mwv_gpio
*gpio
;
101 gpio
= devm_kzalloc(&pdev
->dev
, sizeof(*gpio
), GFP_KERNEL
);
105 gpio
->regmap
= dev_get_regmap(pdev
->dev
.parent
, NULL
);
106 gpio
->chip
= template_chip
;
107 gpio
->chip
.parent
= pdev
->dev
.parent
;
109 return devm_gpiochip_add_data(&pdev
->dev
, &gpio
->chip
, gpio
);
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
},
117 MODULE_DEVICE_TABLE(platform
, bd9571mwv_gpio_id_table
);
119 static struct platform_driver bd9571mwv_gpio_driver
= {
121 .name
= "bd9571mwv-gpio",
123 .probe
= bd9571mwv_gpio_probe
,
124 .id_table
= bd9571mwv_gpio_id_table
,
126 module_platform_driver(bd9571mwv_gpio_driver
);
128 MODULE_AUTHOR("Marek Vasut <marek.vasut+renesas@gmail.com>");
129 MODULE_DESCRIPTION("BD9571MWV GPIO driver");
130 MODULE_LICENSE("GPL v2");