xref: /openbmc/linux/drivers/gpio/gpio-ts4900.c (revision 81317c5a)
19c668632SLucile Quirion /*
29c668632SLucile Quirion  * Digital I/O driver for Technologic Systems I2C FPGA Core
39c668632SLucile Quirion  *
49c668632SLucile Quirion  * Copyright (C) 2015 Technologic Systems
59c668632SLucile Quirion  * Copyright (C) 2016 Savoir-Faire Linux
69c668632SLucile Quirion  *
79c668632SLucile Quirion  * This program is free software; you can redistribute it and/or
89c668632SLucile Quirion  * modify it under the terms of the GNU General Public License version 2 as
99c668632SLucile Quirion  * published by the Free Software Foundation.
109c668632SLucile Quirion  *
119c668632SLucile Quirion  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
129c668632SLucile Quirion  * kind, whether expressed or implied; without even the implied warranty
139c668632SLucile Quirion  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
149c668632SLucile Quirion  * GNU General Public License version 2 for more details.
159c668632SLucile Quirion  */
169c668632SLucile Quirion 
179c668632SLucile Quirion #include <linux/gpio/driver.h>
189c668632SLucile Quirion #include <linux/i2c.h>
199c668632SLucile Quirion #include <linux/of_device.h>
209c668632SLucile Quirion #include <linux/module.h>
219c668632SLucile Quirion #include <linux/regmap.h>
229c668632SLucile Quirion 
239c668632SLucile Quirion #define DEFAULT_PIN_NUMBER	32
249c668632SLucile Quirion /*
259c668632SLucile Quirion  * Register bits used by the GPIO device
269c668632SLucile Quirion  * Some boards, such as TS-7970 do not have a separate input bit
279c668632SLucile Quirion  */
289c668632SLucile Quirion #define TS4900_GPIO_OE		0x01
299c668632SLucile Quirion #define TS4900_GPIO_OUT		0x02
309c668632SLucile Quirion #define TS4900_GPIO_IN		0x04
319c668632SLucile Quirion #define TS7970_GPIO_IN		0x02
329c668632SLucile Quirion 
339c668632SLucile Quirion struct ts4900_gpio_priv {
349c668632SLucile Quirion 	struct regmap *regmap;
359c668632SLucile Quirion 	struct gpio_chip gpio_chip;
369c668632SLucile Quirion 	unsigned int input_bit;
379c668632SLucile Quirion };
389c668632SLucile Quirion 
399c668632SLucile Quirion static int ts4900_gpio_get_direction(struct gpio_chip *chip,
409c668632SLucile Quirion 				     unsigned int offset)
419c668632SLucile Quirion {
429c668632SLucile Quirion 	struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
439c668632SLucile Quirion 	unsigned int reg;
449c668632SLucile Quirion 
459c668632SLucile Quirion 	regmap_read(priv->regmap, offset, &reg);
469c668632SLucile Quirion 
479c668632SLucile Quirion 	return !(reg & TS4900_GPIO_OE);
489c668632SLucile Quirion }
499c668632SLucile Quirion 
509c668632SLucile Quirion static int ts4900_gpio_direction_input(struct gpio_chip *chip,
519c668632SLucile Quirion 				       unsigned int offset)
529c668632SLucile Quirion {
539c668632SLucile Quirion 	struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
549c668632SLucile Quirion 
559c668632SLucile Quirion 	/*
569c668632SLucile Quirion 	 * This will clear the output enable bit, the other bits are
579c668632SLucile Quirion 	 * dontcare when this is cleared
589c668632SLucile Quirion 	 */
599c668632SLucile Quirion 	return regmap_write(priv->regmap, offset, 0);
609c668632SLucile Quirion }
619c668632SLucile Quirion 
629c668632SLucile Quirion static int ts4900_gpio_direction_output(struct gpio_chip *chip,
639c668632SLucile Quirion 					unsigned int offset, int value)
649c668632SLucile Quirion {
659c668632SLucile Quirion 	struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
669c668632SLucile Quirion 	int ret;
679c668632SLucile Quirion 
689c668632SLucile Quirion 	if (value)
699c668632SLucile Quirion 		ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE |
709c668632SLucile Quirion 							 TS4900_GPIO_OUT);
719c668632SLucile Quirion 	else
729c668632SLucile Quirion 		ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE);
739c668632SLucile Quirion 
749c668632SLucile Quirion 	return ret;
759c668632SLucile Quirion }
769c668632SLucile Quirion 
779c668632SLucile Quirion static int ts4900_gpio_get(struct gpio_chip *chip, unsigned int offset)
789c668632SLucile Quirion {
799c668632SLucile Quirion 	struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
809c668632SLucile Quirion 	unsigned int reg;
819c668632SLucile Quirion 
829c668632SLucile Quirion 	regmap_read(priv->regmap, offset, &reg);
839c668632SLucile Quirion 
849c668632SLucile Quirion 	return !!(reg & priv->input_bit);
859c668632SLucile Quirion }
869c668632SLucile Quirion 
879c668632SLucile Quirion static void ts4900_gpio_set(struct gpio_chip *chip, unsigned int offset,
889c668632SLucile Quirion 			    int value)
899c668632SLucile Quirion {
909c668632SLucile Quirion 	struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
919c668632SLucile Quirion 
929c668632SLucile Quirion 	if (value)
939c668632SLucile Quirion 		regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OUT,
949c668632SLucile Quirion 				   TS4900_GPIO_OUT);
959c668632SLucile Quirion 	else
969c668632SLucile Quirion 		regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OUT, 0);
979c668632SLucile Quirion }
989c668632SLucile Quirion 
999c668632SLucile Quirion static const struct regmap_config ts4900_regmap_config = {
1009c668632SLucile Quirion 	.reg_bits = 16,
1019c668632SLucile Quirion 	.val_bits = 8,
1029c668632SLucile Quirion };
1039c668632SLucile Quirion 
104e35b5ab0SJulia Lawall static const struct gpio_chip template_chip = {
1059c668632SLucile Quirion 	.label			= "ts4900-gpio",
1069c668632SLucile Quirion 	.owner			= THIS_MODULE,
1079c668632SLucile Quirion 	.get_direction		= ts4900_gpio_get_direction,
1089c668632SLucile Quirion 	.direction_input	= ts4900_gpio_direction_input,
1099c668632SLucile Quirion 	.direction_output	= ts4900_gpio_direction_output,
1109c668632SLucile Quirion 	.get			= ts4900_gpio_get,
1119c668632SLucile Quirion 	.set			= ts4900_gpio_set,
1129c668632SLucile Quirion 	.base			= -1,
1139c668632SLucile Quirion 	.can_sleep		= true,
1149c668632SLucile Quirion };
1159c668632SLucile Quirion 
1169c668632SLucile Quirion static const struct of_device_id ts4900_gpio_of_match_table[] = {
1179c668632SLucile Quirion 	{
1189c668632SLucile Quirion 		.compatible = "technologic,ts4900-gpio",
1199c668632SLucile Quirion 		.data = (void *)TS4900_GPIO_IN,
1209c668632SLucile Quirion 	}, {
1219c668632SLucile Quirion 		.compatible = "technologic,ts7970-gpio",
1229c668632SLucile Quirion 		.data = (void *)TS7970_GPIO_IN,
1239c668632SLucile Quirion 	},
1249c668632SLucile Quirion 	{ /* sentinel */ },
1259c668632SLucile Quirion };
1269c668632SLucile Quirion MODULE_DEVICE_TABLE(of, ts4900_gpio_of_match_table);
1279c668632SLucile Quirion 
1289c668632SLucile Quirion static int ts4900_gpio_probe(struct i2c_client *client,
1299c668632SLucile Quirion 			const struct i2c_device_id *id)
1309c668632SLucile Quirion {
1319c668632SLucile Quirion 	struct ts4900_gpio_priv *priv;
1329c668632SLucile Quirion 	u32 ngpio;
1339c668632SLucile Quirion 	int ret;
1349c668632SLucile Quirion 
1359c668632SLucile Quirion 	if (of_property_read_u32(client->dev.of_node, "ngpios", &ngpio))
1369c668632SLucile Quirion 		ngpio = DEFAULT_PIN_NUMBER;
1379c668632SLucile Quirion 
1389c668632SLucile Quirion 	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
1399c668632SLucile Quirion 	if (!priv)
1409c668632SLucile Quirion 		return -ENOMEM;
1419c668632SLucile Quirion 
1429c668632SLucile Quirion 	priv->gpio_chip = template_chip;
1439c668632SLucile Quirion 	priv->gpio_chip.label = "ts4900-gpio";
1449c668632SLucile Quirion 	priv->gpio_chip.ngpio = ngpio;
1459c668632SLucile Quirion 	priv->gpio_chip.parent = &client->dev;
14681317c5aSThierry Reding 	priv->input_bit = (uintptr_t)of_device_get_match_data(&client->dev);
1479c668632SLucile Quirion 
1489c668632SLucile Quirion 	priv->regmap = devm_regmap_init_i2c(client, &ts4900_regmap_config);
1499c668632SLucile Quirion 	if (IS_ERR(priv->regmap)) {
1509c668632SLucile Quirion 		ret = PTR_ERR(priv->regmap);
1519c668632SLucile Quirion 		dev_err(&client->dev, "Failed to allocate register map: %d\n",
1529c668632SLucile Quirion 			ret);
1539c668632SLucile Quirion 		return ret;
1549c668632SLucile Quirion 	}
1559c668632SLucile Quirion 
1569c668632SLucile Quirion 	ret = devm_gpiochip_add_data(&client->dev, &priv->gpio_chip, priv);
1579c668632SLucile Quirion 	if (ret < 0) {
1589c668632SLucile Quirion 		dev_err(&client->dev, "Unable to register gpiochip\n");
1599c668632SLucile Quirion 		return ret;
1609c668632SLucile Quirion 	}
1619c668632SLucile Quirion 
1629c668632SLucile Quirion 	i2c_set_clientdata(client, priv);
1639c668632SLucile Quirion 
1649c668632SLucile Quirion 	return 0;
1659c668632SLucile Quirion }
1669c668632SLucile Quirion 
1679c668632SLucile Quirion static const struct i2c_device_id ts4900_gpio_id_table[] = {
1689c668632SLucile Quirion 	{ "ts4900-gpio", },
1699c668632SLucile Quirion 	{ /* sentinel */ }
1709c668632SLucile Quirion };
1719c668632SLucile Quirion MODULE_DEVICE_TABLE(i2c, ts4900_gpio_id_table);
1729c668632SLucile Quirion 
1739c668632SLucile Quirion static struct i2c_driver ts4900_gpio_driver = {
1749c668632SLucile Quirion 	.driver = {
1759c668632SLucile Quirion 		.name = "ts4900-gpio",
1769c668632SLucile Quirion 		.of_match_table = ts4900_gpio_of_match_table,
1779c668632SLucile Quirion 	},
1789c668632SLucile Quirion 	.probe = ts4900_gpio_probe,
1799c668632SLucile Quirion 	.id_table = ts4900_gpio_id_table,
1809c668632SLucile Quirion };
1819c668632SLucile Quirion module_i2c_driver(ts4900_gpio_driver);
1829c668632SLucile Quirion 
1839c668632SLucile Quirion MODULE_AUTHOR("Technologic Systems");
1849c668632SLucile Quirion MODULE_DESCRIPTION("GPIO interface for Technologic Systems I2C-FPGA core");
1859c668632SLucile Quirion MODULE_LICENSE("GPL");
186