2 * gpiolib support for Wolfson Arizona class devices
4 * Copyright 2012 Wolfson Microelectronics PLC.
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
15 #include <linux/kernel.h>
16 #include <linux/slab.h>
17 #include <linux/module.h>
18 #include <linux/gpio.h>
19 #include <linux/platform_device.h>
20 #include <linux/seq_file.h>
22 #include <linux/mfd/arizona/core.h>
23 #include <linux/mfd/arizona/pdata.h>
24 #include <linux/mfd/arizona/registers.h>
27 struct arizona
*arizona
;
28 struct gpio_chip gpio_chip
;
31 static int arizona_gpio_direction_in(struct gpio_chip
*chip
, unsigned offset
)
33 struct arizona_gpio
*arizona_gpio
= gpiochip_get_data(chip
);
34 struct arizona
*arizona
= arizona_gpio
->arizona
;
36 return regmap_update_bits(arizona
->regmap
, ARIZONA_GPIO1_CTRL
+ offset
,
37 ARIZONA_GPN_DIR
, ARIZONA_GPN_DIR
);
40 static int arizona_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
42 struct arizona_gpio
*arizona_gpio
= gpiochip_get_data(chip
);
43 struct arizona
*arizona
= arizona_gpio
->arizona
;
47 ret
= regmap_read(arizona
->regmap
, ARIZONA_GPIO1_CTRL
+ offset
, &val
);
51 if (val
& ARIZONA_GPN_LVL
)
57 static int arizona_gpio_direction_out(struct gpio_chip
*chip
,
58 unsigned offset
, int value
)
60 struct arizona_gpio
*arizona_gpio
= gpiochip_get_data(chip
);
61 struct arizona
*arizona
= arizona_gpio
->arizona
;
64 value
= ARIZONA_GPN_LVL
;
66 return regmap_update_bits(arizona
->regmap
, ARIZONA_GPIO1_CTRL
+ offset
,
67 ARIZONA_GPN_DIR
| ARIZONA_GPN_LVL
, value
);
70 static void arizona_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
72 struct arizona_gpio
*arizona_gpio
= gpiochip_get_data(chip
);
73 struct arizona
*arizona
= arizona_gpio
->arizona
;
76 value
= ARIZONA_GPN_LVL
;
78 regmap_update_bits(arizona
->regmap
, ARIZONA_GPIO1_CTRL
+ offset
,
79 ARIZONA_GPN_LVL
, value
);
82 static const struct gpio_chip template_chip
= {
85 .direction_input
= arizona_gpio_direction_in
,
86 .get
= arizona_gpio_get
,
87 .direction_output
= arizona_gpio_direction_out
,
88 .set
= arizona_gpio_set
,
92 static int arizona_gpio_probe(struct platform_device
*pdev
)
94 struct arizona
*arizona
= dev_get_drvdata(pdev
->dev
.parent
);
95 struct arizona_pdata
*pdata
= dev_get_platdata(arizona
->dev
);
96 struct arizona_gpio
*arizona_gpio
;
99 arizona_gpio
= devm_kzalloc(&pdev
->dev
, sizeof(*arizona_gpio
),
104 arizona_gpio
->arizona
= arizona
;
105 arizona_gpio
->gpio_chip
= template_chip
;
106 arizona_gpio
->gpio_chip
.parent
= &pdev
->dev
;
107 #ifdef CONFIG_OF_GPIO
108 arizona_gpio
->gpio_chip
.of_node
= arizona
->dev
->of_node
;
111 switch (arizona
->type
) {
118 arizona_gpio
->gpio_chip
.ngpio
= 5;
122 arizona_gpio
->gpio_chip
.ngpio
= 2;
125 dev_err(&pdev
->dev
, "Unknown chip variant %d\n",
130 if (pdata
&& pdata
->gpio_base
)
131 arizona_gpio
->gpio_chip
.base
= pdata
->gpio_base
;
133 arizona_gpio
->gpio_chip
.base
= -1;
135 ret
= devm_gpiochip_add_data(&pdev
->dev
, &arizona_gpio
->gpio_chip
,
138 dev_err(&pdev
->dev
, "Could not register gpiochip, %d\n",
146 static struct platform_driver arizona_gpio_driver
= {
147 .driver
.name
= "arizona-gpio",
148 .probe
= arizona_gpio_probe
,
151 module_platform_driver(arizona_gpio_driver
);
153 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
154 MODULE_DESCRIPTION("GPIO interface for Arizona devices");
155 MODULE_LICENSE("GPL");
156 MODULE_ALIAS("platform:arizona-gpio");