Blame view
drivers/gpio/gpio-adp5520.c
3.94 KB
80503b23b treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
ef72af408 gpio: gpio suppor... |
2 3 4 5 |
/* * GPIO driver for Analog Devices ADP5520 MFD PMICs * * Copyright 2009 Analog Devices Inc. |
ef72af408 gpio: gpio suppor... |
6 7 8 |
*/ #include <linux/module.h> |
5a0e3ad6a include cleanup: ... |
9 |
#include <linux/slab.h> |
ef72af408 gpio: gpio suppor... |
10 11 12 13 |
#include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/mfd/adp5520.h> |
8a3b4f20d gpio: adp5520: In... |
14 |
#include <linux/gpio/driver.h> |
ef72af408 gpio: gpio suppor... |
15 16 17 18 19 20 21 22 23 24 25 26 |
struct adp5520_gpio { struct device *master; struct gpio_chip gpio_chip; unsigned char lut[ADP5520_MAXGPIOS]; unsigned long output; }; static int adp5520_gpio_get_value(struct gpio_chip *chip, unsigned off) { struct adp5520_gpio *dev; uint8_t reg_val; |
5060e0e89 gpio: adp5520: us... |
27 |
dev = gpiochip_get_data(chip); |
ef72af408 gpio: gpio suppor... |
28 29 30 31 32 33 34 |
/* * There are dedicated registers for GPIO IN/OUT. * Make sure we return the right value, even when configured as output */ if (test_bit(off, &dev->output)) |
7c29a4766 gpio: adp5520: re... |
35 |
adp5520_read(dev->master, ADP5520_GPIO_OUT, ®_val); |
ef72af408 gpio: gpio suppor... |
36 |
else |
7c29a4766 gpio: adp5520: re... |
37 |
adp5520_read(dev->master, ADP5520_GPIO_IN, ®_val); |
ef72af408 gpio: gpio suppor... |
38 39 40 41 42 43 44 45 |
return !!(reg_val & dev->lut[off]); } static void adp5520_gpio_set_value(struct gpio_chip *chip, unsigned off, int val) { struct adp5520_gpio *dev; |
5060e0e89 gpio: adp5520: us... |
46 |
dev = gpiochip_get_data(chip); |
ef72af408 gpio: gpio suppor... |
47 48 |
if (val) |
7c29a4766 gpio: adp5520: re... |
49 |
adp5520_set_bits(dev->master, ADP5520_GPIO_OUT, dev->lut[off]); |
ef72af408 gpio: gpio suppor... |
50 |
else |
7c29a4766 gpio: adp5520: re... |
51 |
adp5520_clr_bits(dev->master, ADP5520_GPIO_OUT, dev->lut[off]); |
ef72af408 gpio: gpio suppor... |
52 53 54 55 56 |
} static int adp5520_gpio_direction_input(struct gpio_chip *chip, unsigned off) { struct adp5520_gpio *dev; |
5060e0e89 gpio: adp5520: us... |
57 |
dev = gpiochip_get_data(chip); |
ef72af408 gpio: gpio suppor... |
58 59 |
clear_bit(off, &dev->output); |
7c29a4766 gpio: adp5520: re... |
60 61 |
return adp5520_clr_bits(dev->master, ADP5520_GPIO_CFG_2, dev->lut[off]); |
ef72af408 gpio: gpio suppor... |
62 63 64 65 66 67 68 |
} static int adp5520_gpio_direction_output(struct gpio_chip *chip, unsigned off, int val) { struct adp5520_gpio *dev; int ret = 0; |
5060e0e89 gpio: adp5520: us... |
69 |
dev = gpiochip_get_data(chip); |
ef72af408 gpio: gpio suppor... |
70 71 72 73 |
set_bit(off, &dev->output); if (val) |
7c29a4766 gpio: adp5520: re... |
74 75 |
ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_OUT, dev->lut[off]); |
ef72af408 gpio: gpio suppor... |
76 |
else |
7c29a4766 gpio: adp5520: re... |
77 78 |
ret |= adp5520_clr_bits(dev->master, ADP5520_GPIO_OUT, dev->lut[off]); |
ef72af408 gpio: gpio suppor... |
79 |
|
7c29a4766 gpio: adp5520: re... |
80 81 |
ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_CFG_2, dev->lut[off]); |
ef72af408 gpio: gpio suppor... |
82 83 84 |
return ret; } |
3836309d9 gpio: remove use ... |
85 |
static int adp5520_gpio_probe(struct platform_device *pdev) |
ef72af408 gpio: gpio suppor... |
86 |
{ |
e56aee189 gpio: use dev_get... |
87 |
struct adp5520_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); |
ef72af408 gpio: gpio suppor... |
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
struct adp5520_gpio *dev; struct gpio_chip *gc; int ret, i, gpios; unsigned char ctl_mask = 0; if (pdata == NULL) { dev_err(&pdev->dev, "missing platform data "); return -ENODEV; } if (pdev->id != ID_ADP5520) { dev_err(&pdev->dev, "only ADP5520 supports GPIO "); return -ENODEV; } |
24bb3813d gpio: adp5520: us... |
104 |
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); |
e8a71aaa8 gpio: adp5520: re... |
105 |
if (dev == NULL) |
ef72af408 gpio: gpio suppor... |
106 |
return -ENOMEM; |
ef72af408 gpio: gpio suppor... |
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
dev->master = pdev->dev.parent; for (gpios = 0, i = 0; i < ADP5520_MAXGPIOS; i++) if (pdata->gpio_en_mask & (1 << i)) dev->lut[gpios++] = 1 << i; if (gpios < 1) { ret = -EINVAL; goto err; } gc = &dev->gpio_chip; gc->direction_input = adp5520_gpio_direction_input; gc->direction_output = adp5520_gpio_direction_output; gc->get = adp5520_gpio_get_value; gc->set = adp5520_gpio_set_value; |
9fb1f39eb gpio/pinctrl: mak... |
124 |
gc->can_sleep = true; |
ef72af408 gpio: gpio suppor... |
125 126 127 128 129 |
gc->base = pdata->gpio_start; gc->ngpio = gpios; gc->label = pdev->name; gc->owner = THIS_MODULE; |
7c29a4766 gpio: adp5520: re... |
130 |
ret = adp5520_clr_bits(dev->master, ADP5520_GPIO_CFG_1, |
ef72af408 gpio: gpio suppor... |
131 |
pdata->gpio_en_mask); |
7c29a4766 gpio: adp5520: re... |
132 133 |
if (pdata->gpio_en_mask & ADP5520_GPIO_C3) ctl_mask |= ADP5520_C3_MODE; |
ef72af408 gpio: gpio suppor... |
134 |
|
7c29a4766 gpio: adp5520: re... |
135 136 |
if (pdata->gpio_en_mask & ADP5520_GPIO_R3) ctl_mask |= ADP5520_R3_MODE; |
ef72af408 gpio: gpio suppor... |
137 138 |
if (ctl_mask) |
7c29a4766 gpio: adp5520: re... |
139 |
ret = adp5520_set_bits(dev->master, ADP5520_LED_CONTROL, |
ef72af408 gpio: gpio suppor... |
140 |
ctl_mask); |
7c29a4766 gpio: adp5520: re... |
141 |
ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_PULLUP, |
ef72af408 gpio: gpio suppor... |
142 143 144 145 146 147 148 |
pdata->gpio_pullup_mask); if (ret) { dev_err(&pdev->dev, "failed to write "); goto err; } |
8ae6ace12 gpio: adp5520: Us... |
149 |
ret = devm_gpiochip_add_data(&pdev->dev, &dev->gpio_chip, dev); |
ef72af408 gpio: gpio suppor... |
150 151 152 153 154 155 156 |
if (ret) goto err; platform_set_drvdata(pdev, dev); return 0; err: |
ef72af408 gpio: gpio suppor... |
157 158 |
return ret; } |
ef72af408 gpio: gpio suppor... |
159 160 161 |
static struct platform_driver adp5520_gpio_driver = { .driver = { .name = "adp5520-gpio", |
ef72af408 gpio: gpio suppor... |
162 163 |
}, .probe = adp5520_gpio_probe, |
ef72af408 gpio: gpio suppor... |
164 |
}; |
6f61415e9 gpio: Convert GPI... |
165 |
module_platform_driver(adp5520_gpio_driver); |
ef72af408 gpio: gpio suppor... |
166 |
|
be887843f drivers: gpio: Up... |
167 |
MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); |
ef72af408 gpio: gpio suppor... |
168 169 170 |
MODULE_DESCRIPTION("GPIO ADP5520 Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:adp5520-gpio"); |