2 * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
16 * GPIO driver for Altera Arria10 MAX5 System Resource Chip
18 * Adapted from gpio-tps65910.c
21 #include <linux/gpio/driver.h>
22 #include <linux/mfd/altera-a10sr.h>
23 #include <linux/module.h>
26 * struct altr_a10sr_gpio - Altera Max5 GPIO device private data structure
27 * @gp: : instance of the gpio_chip
28 * @regmap: the regmap from the parent device.
30 struct altr_a10sr_gpio
{
32 struct regmap
*regmap
;
35 static int altr_a10sr_gpio_get(struct gpio_chip
*chip
, unsigned int offset
)
37 struct altr_a10sr_gpio
*gpio
= gpiochip_get_data(chip
);
40 ret
= regmap_read(gpio
->regmap
, ALTR_A10SR_PBDSW_REG
, &val
);
44 return !!(val
& BIT(offset
- ALTR_A10SR_LED_VALID_SHIFT
));
47 static void altr_a10sr_gpio_set(struct gpio_chip
*chip
, unsigned int offset
,
50 struct altr_a10sr_gpio
*gpio
= gpiochip_get_data(chip
);
52 regmap_update_bits(gpio
->regmap
, ALTR_A10SR_LED_REG
,
53 BIT(ALTR_A10SR_LED_VALID_SHIFT
+ offset
),
54 value
? BIT(ALTR_A10SR_LED_VALID_SHIFT
+ offset
)
58 static int altr_a10sr_gpio_direction_input(struct gpio_chip
*gc
,
61 if (nr
>= (ALTR_A10SR_IN_VALID_RANGE_LO
- ALTR_A10SR_LED_VALID_SHIFT
))
66 static int altr_a10sr_gpio_direction_output(struct gpio_chip
*gc
,
67 unsigned int nr
, int value
)
69 if (nr
<= (ALTR_A10SR_OUT_VALID_RANGE_HI
- ALTR_A10SR_LED_VALID_SHIFT
)) {
70 altr_a10sr_gpio_set(gc
, nr
, value
);
76 static const struct gpio_chip altr_a10sr_gc
= {
77 .label
= "altr_a10sr_gpio",
79 .get
= altr_a10sr_gpio_get
,
80 .set
= altr_a10sr_gpio_set
,
81 .direction_input
= altr_a10sr_gpio_direction_input
,
82 .direction_output
= altr_a10sr_gpio_direction_output
,
88 static int altr_a10sr_gpio_probe(struct platform_device
*pdev
)
90 struct altr_a10sr_gpio
*gpio
;
92 struct altr_a10sr
*a10sr
= dev_get_drvdata(pdev
->dev
.parent
);
94 gpio
= devm_kzalloc(&pdev
->dev
, sizeof(*gpio
), GFP_KERNEL
);
98 gpio
->regmap
= a10sr
->regmap
;
100 gpio
->gp
= altr_a10sr_gc
;
101 gpio
->gp
.parent
= pdev
->dev
.parent
;
102 gpio
->gp
.of_node
= pdev
->dev
.of_node
;
104 ret
= devm_gpiochip_add_data(&pdev
->dev
, &gpio
->gp
, gpio
);
106 dev_err(&pdev
->dev
, "Could not register gpiochip, %d\n", ret
);
110 platform_set_drvdata(pdev
, gpio
);
115 static const struct of_device_id altr_a10sr_gpio_of_match
[] = {
116 { .compatible
= "altr,a10sr-gpio" },
119 MODULE_DEVICE_TABLE(of
, altr_a10sr_gpio_of_match
);
121 static struct platform_driver altr_a10sr_gpio_driver
= {
122 .probe
= altr_a10sr_gpio_probe
,
124 .name
= "altr_a10sr_gpio",
125 .of_match_table
= of_match_ptr(altr_a10sr_gpio_of_match
),
128 module_platform_driver(altr_a10sr_gpio_driver
);
130 MODULE_LICENSE("GPL v2");
131 MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>");
132 MODULE_DESCRIPTION("Altera Arria10 System Resource Chip GPIO");