2 * drivers/gpio/gpio-rk8xx.c
3 * Driver for Rockchip RK8xx PMIC GPIO
5 * Copyright (C) 2017, Rockchip Technology Co., Ltd.
6 * Author: Chen Jianhong <chenjh@rock-chips.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13 * kind, whether express or implied; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <linux/err.h>
19 #include <linux/gpio.h>
20 #include <linux/init.h>
21 #include <linux/i2c.h>
22 #include <linux/mfd/rk808.h>
23 #include <linux/module.h>
24 #include <linux/kernel.h>
26 #include <linux/platform_device.h>
28 #define RK805_GPIO_REG RK805_OUT_REG
29 #define RK805_OUT0_VALMASK BIT(0)
30 #define RK805_OUT1_VALMASK BIT(1)
32 struct rk8xx_gpio_reg {
39 struct rk8xx_gpio_info {
41 struct gpio_chip gpio_chip;
42 struct rk8xx_gpio_reg *gpio_reg;
46 static int rk8xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
49 struct rk8xx_gpio_info *gi = dev_get_drvdata(chip->dev);
52 if (gi->gpio_reg[offset].fun_msk) {
53 err = regmap_update_bits(gi->rk8xx->regmap,
54 gi->gpio_reg[offset].reg,
55 gi->gpio_reg[offset].fun_msk,
56 gi->gpio_reg[offset].fun_msk);
58 dev_err(chip->dev, "set gpio%d func fail: %d\n",
65 if (gi->gpio_reg[offset].dir_msk) {
66 err = regmap_update_bits(gi->rk8xx->regmap,
67 gi->gpio_reg[offset].reg,
68 gi->gpio_reg[offset].dir_msk,
71 dev_err(chip->dev, "set gpio%d input fail: %d\n",
80 static int rk8xx_gpio_direction_output(struct gpio_chip *chip,
81 unsigned offset, int value)
84 struct rk8xx_gpio_info *gi = dev_get_drvdata(chip->dev);
87 if (gi->gpio_reg[offset].fun_msk) {
88 err = regmap_update_bits(gi->rk8xx->regmap,
89 gi->gpio_reg[offset].reg,
90 gi->gpio_reg[offset].fun_msk,
91 gi->gpio_reg[offset].fun_msk);
93 dev_err(chip->dev, "set gpio%d func fail: %d\n",
100 if (gi->gpio_reg[offset].dir_msk) {
101 err = regmap_update_bits(gi->rk8xx->regmap,
102 gi->gpio_reg[offset].reg,
103 gi->gpio_reg[offset].dir_msk,
104 gi->gpio_reg[offset].dir_msk);
107 "set gpio%d output fail: %d\n", offset, err);
113 err = regmap_update_bits(gi->rk8xx->regmap,
114 gi->gpio_reg[offset].reg,
115 gi->gpio_reg[offset].val_msk,
116 gi->gpio_reg[offset].val_msk);
118 err = regmap_update_bits(gi->rk8xx->regmap,
119 gi->gpio_reg[offset].reg,
120 gi->gpio_reg[offset].val_msk,
123 dev_err(chip->dev, "set gpio%d value fail: %d\n", offset, err);
130 static int rk8xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
134 struct rk8xx_gpio_info *gi = dev_get_drvdata(chip->dev);
136 err = regmap_read(gi->rk8xx->regmap, gi->gpio_reg[offset].reg, &val);
138 dev_err(chip->dev, "get gpio%d value fail: %d\n", offset, err);
142 return (val & gi->gpio_reg[offset].val_msk) ? 1 : 0;
145 static void rk8xx_gpio_set_value(struct gpio_chip *chip,
146 unsigned offset, int value)
149 struct rk8xx_gpio_info *gi = dev_get_drvdata(chip->dev);
152 err = regmap_update_bits(gi->rk8xx->regmap,
153 gi->gpio_reg[offset].reg,
154 gi->gpio_reg[offset].val_msk,
155 gi->gpio_reg[offset].val_msk);
157 err = regmap_update_bits(gi->rk8xx->regmap,
158 gi->gpio_reg[offset].reg,
159 gi->gpio_reg[offset].val_msk,
162 dev_err(chip->dev, "set gpio%d value fail: %d\n", offset, err);
165 /* rk805: two gpio: output only */
166 static struct rk8xx_gpio_reg rk805_gpio_reg[] = {
168 .reg = RK805_GPIO_REG,
169 .val_msk = RK805_OUT0_VALMASK,
172 .reg = RK805_GPIO_REG,
173 .val_msk = RK805_OUT1_VALMASK,
177 static int rk8xx_gpio_probe(struct platform_device *pdev)
179 struct rk808 *rk8xx = dev_get_drvdata(pdev->dev.parent);
180 struct rk8xx_gpio_info *gi;
181 struct device_node *np;
184 np = of_get_child_by_name(pdev->dev.parent->of_node, "gpio");
186 if (!of_device_is_available(np)) {
187 dev_info(&pdev->dev, "device is disabled\n");
192 gi = devm_kzalloc(&pdev->dev, sizeof(*gi), GFP_KERNEL);
196 switch (rk8xx->variant) {
198 gi->gpio_reg = rk805_gpio_reg;
199 gi->gpio_nr = ARRAY_SIZE(rk805_gpio_reg);
202 dev_err(&pdev->dev, "unsupported RK8XX ID %lu\n",
208 gi->gpio_chip.base = -1;
209 gi->gpio_chip.can_sleep = true;
210 gi->gpio_chip.dev = &pdev->dev;
211 gi->gpio_chip.ngpio = gi->gpio_nr;
212 gi->gpio_chip.label = pdev->name;
213 gi->gpio_chip.get = rk8xx_gpio_get_value;
214 gi->gpio_chip.set = rk8xx_gpio_set_value;
215 gi->gpio_chip.direction_input = rk8xx_gpio_direction_input;
216 gi->gpio_chip.direction_output = rk8xx_gpio_direction_output;
217 gi->gpio_chip.owner = THIS_MODULE;
218 #ifdef CONFIG_OF_GPIO
219 gi->gpio_chip.of_node = rk8xx->i2c->dev.of_node;
221 platform_set_drvdata(pdev, gi);
223 ret = gpiochip_add(&gi->gpio_chip);
225 dev_err(&pdev->dev, "register rk8xx gpiochip fail: %d\n", ret);
230 static int rk8xx_gpio_remove(struct platform_device *pdev)
232 struct rk8xx_gpio_info *gi = platform_get_drvdata(pdev);
234 gpiochip_remove(&gi->gpio_chip);
239 static struct platform_driver rk8xx_gpio_driver = {
240 .probe = rk8xx_gpio_probe,
241 .remove = rk8xx_gpio_remove,
243 .name = "rk8xx-gpio",
244 .owner = THIS_MODULE,
248 static int rk8xx_gpio_init(void)
250 return platform_driver_register(&rk8xx_gpio_driver);
252 subsys_initcall(rk8xx_gpio_init);
254 static void rk8xx_gpio_exit(void)
256 platform_driver_unregister(&rk8xx_gpio_driver);
258 module_exit(rk8xx_gpio_exit);
260 MODULE_LICENSE("GPL v2");
261 MODULE_DESCRIPTION("RK8xx GPIO driver");
262 MODULE_AUTHOR("Chen Jianhong <chenjh@rock-chips.com>");