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, ®); 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, ®); 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