187ba5badSKris Bahnsen // SPDX-License-Identifier: GPL-2.0 29c668632SLucile Quirion /* 39c668632SLucile Quirion * Digital I/O driver for Technologic Systems I2C FPGA Core 49c668632SLucile Quirion * 503fe0035SMark Featherston * Copyright (C) 2015, 2018 Technologic Systems 69c668632SLucile Quirion * Copyright (C) 2016 Savoir-Faire Linux 79c668632SLucile Quirion */ 89c668632SLucile Quirion 99c668632SLucile Quirion #include <linux/gpio/driver.h> 109c668632SLucile Quirion #include <linux/i2c.h> 119c668632SLucile Quirion #include <linux/of_device.h> 129c668632SLucile Quirion #include <linux/module.h> 139c668632SLucile Quirion #include <linux/regmap.h> 149c668632SLucile Quirion 159c668632SLucile Quirion #define DEFAULT_PIN_NUMBER 32 169c668632SLucile Quirion /* 179c668632SLucile Quirion * Register bits used by the GPIO device 189c668632SLucile Quirion * Some boards, such as TS-7970 do not have a separate input bit 199c668632SLucile Quirion */ 209c668632SLucile Quirion #define TS4900_GPIO_OE 0x01 219c668632SLucile Quirion #define TS4900_GPIO_OUT 0x02 229c668632SLucile Quirion #define TS4900_GPIO_IN 0x04 239c668632SLucile Quirion #define TS7970_GPIO_IN 0x02 249c668632SLucile Quirion 259c668632SLucile Quirion struct ts4900_gpio_priv { 269c668632SLucile Quirion struct regmap *regmap; 279c668632SLucile Quirion struct gpio_chip gpio_chip; 289c668632SLucile Quirion unsigned int input_bit; 299c668632SLucile Quirion }; 309c668632SLucile Quirion 319c668632SLucile Quirion static int ts4900_gpio_get_direction(struct gpio_chip *chip, 329c668632SLucile Quirion unsigned int offset) 339c668632SLucile Quirion { 349c668632SLucile Quirion struct ts4900_gpio_priv *priv = gpiochip_get_data(chip); 359c668632SLucile Quirion unsigned int reg; 369c668632SLucile Quirion 379c668632SLucile Quirion regmap_read(priv->regmap, offset, ®); 389c668632SLucile Quirion 39e42615ecSMatti Vaittinen if (reg & TS4900_GPIO_OE) 40e42615ecSMatti Vaittinen return GPIO_LINE_DIRECTION_OUT; 41e42615ecSMatti Vaittinen 42e42615ecSMatti Vaittinen return GPIO_LINE_DIRECTION_IN; 439c668632SLucile Quirion } 449c668632SLucile Quirion 459c668632SLucile Quirion static int ts4900_gpio_direction_input(struct gpio_chip *chip, 469c668632SLucile Quirion unsigned int offset) 479c668632SLucile Quirion { 489c668632SLucile Quirion struct ts4900_gpio_priv *priv = gpiochip_get_data(chip); 499c668632SLucile Quirion 50576892a8SKris Bahnsen /* 51576892a8SKris Bahnsen * Only clear the OE bit here, requires a RMW. Prevents a potential issue 52576892a8SKris Bahnsen * with OE and DAT getting to the physical pin at different times. 539c668632SLucile Quirion */ 5403fe0035SMark Featherston return regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OE, 0); 559c668632SLucile Quirion } 569c668632SLucile Quirion 579c668632SLucile Quirion static int ts4900_gpio_direction_output(struct gpio_chip *chip, 589c668632SLucile Quirion unsigned int offset, int value) 599c668632SLucile Quirion { 609c668632SLucile Quirion struct ts4900_gpio_priv *priv = gpiochip_get_data(chip); 6103fe0035SMark Featherston unsigned int reg; 629c668632SLucile Quirion int ret; 639c668632SLucile Quirion 64576892a8SKris Bahnsen /* 65576892a8SKris Bahnsen * If changing from an input to an output, we need to first set the 66576892a8SKris Bahnsen * GPIO's DAT bit to what is requested and then set the OE bit. This 67576892a8SKris Bahnsen * prevents a glitch that can occur on the IO line. 6803fe0035SMark Featherston */ 6903fe0035SMark Featherston regmap_read(priv->regmap, offset, ®); 7003fe0035SMark Featherston if (!(reg & TS4900_GPIO_OE)) { 7103fe0035SMark Featherston if (value) 7203fe0035SMark Featherston reg = TS4900_GPIO_OUT; 7303fe0035SMark Featherston else 7403fe0035SMark Featherston reg &= ~TS4900_GPIO_OUT; 7503fe0035SMark Featherston 7603fe0035SMark Featherston regmap_write(priv->regmap, offset, reg); 7703fe0035SMark Featherston } 7803fe0035SMark Featherston 799c668632SLucile Quirion if (value) 809c668632SLucile Quirion ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE | 819c668632SLucile Quirion TS4900_GPIO_OUT); 829c668632SLucile Quirion else 839c668632SLucile Quirion ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE); 849c668632SLucile Quirion 859c668632SLucile Quirion return ret; 869c668632SLucile Quirion } 879c668632SLucile Quirion 889c668632SLucile Quirion static int ts4900_gpio_get(struct gpio_chip *chip, unsigned int offset) 899c668632SLucile Quirion { 909c668632SLucile Quirion struct ts4900_gpio_priv *priv = gpiochip_get_data(chip); 919c668632SLucile Quirion unsigned int reg; 929c668632SLucile Quirion 939c668632SLucile Quirion regmap_read(priv->regmap, offset, ®); 949c668632SLucile Quirion 959c668632SLucile Quirion return !!(reg & priv->input_bit); 969c668632SLucile Quirion } 979c668632SLucile Quirion 989c668632SLucile Quirion static void ts4900_gpio_set(struct gpio_chip *chip, unsigned int offset, 999c668632SLucile Quirion int value) 1009c668632SLucile Quirion { 1019c668632SLucile Quirion struct ts4900_gpio_priv *priv = gpiochip_get_data(chip); 1029c668632SLucile Quirion 1039c668632SLucile Quirion if (value) 1049c668632SLucile Quirion regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OUT, 1059c668632SLucile Quirion TS4900_GPIO_OUT); 1069c668632SLucile Quirion else 1079c668632SLucile Quirion regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OUT, 0); 1089c668632SLucile Quirion } 1099c668632SLucile Quirion 1109c668632SLucile Quirion static const struct regmap_config ts4900_regmap_config = { 1119c668632SLucile Quirion .reg_bits = 16, 1129c668632SLucile Quirion .val_bits = 8, 1139c668632SLucile Quirion }; 1149c668632SLucile Quirion 115e35b5ab0SJulia Lawall static const struct gpio_chip template_chip = { 1169c668632SLucile Quirion .label = "ts4900-gpio", 1179c668632SLucile Quirion .owner = THIS_MODULE, 1189c668632SLucile Quirion .get_direction = ts4900_gpio_get_direction, 1199c668632SLucile Quirion .direction_input = ts4900_gpio_direction_input, 1209c668632SLucile Quirion .direction_output = ts4900_gpio_direction_output, 1219c668632SLucile Quirion .get = ts4900_gpio_get, 1229c668632SLucile Quirion .set = ts4900_gpio_set, 1239c668632SLucile Quirion .base = -1, 1249c668632SLucile Quirion .can_sleep = true, 1259c668632SLucile Quirion }; 1269c668632SLucile Quirion 1279c668632SLucile Quirion static const struct of_device_id ts4900_gpio_of_match_table[] = { 1289c668632SLucile Quirion { 1299c668632SLucile Quirion .compatible = "technologic,ts4900-gpio", 1309c668632SLucile Quirion .data = (void *)TS4900_GPIO_IN, 1319c668632SLucile Quirion }, { 1329c668632SLucile Quirion .compatible = "technologic,ts7970-gpio", 1339c668632SLucile Quirion .data = (void *)TS7970_GPIO_IN, 1349c668632SLucile Quirion }, 1359c668632SLucile Quirion { /* sentinel */ }, 1369c668632SLucile Quirion }; 1379c668632SLucile Quirion MODULE_DEVICE_TABLE(of, ts4900_gpio_of_match_table); 1389c668632SLucile Quirion 139bf08ce13SStephen Kitt static int ts4900_gpio_probe(struct i2c_client *client) 1409c668632SLucile Quirion { 1419c668632SLucile Quirion struct ts4900_gpio_priv *priv; 1429c668632SLucile Quirion u32 ngpio; 1439c668632SLucile Quirion int ret; 1449c668632SLucile Quirion 1459c668632SLucile Quirion if (of_property_read_u32(client->dev.of_node, "ngpios", &ngpio)) 1469c668632SLucile Quirion ngpio = DEFAULT_PIN_NUMBER; 1479c668632SLucile Quirion 1489c668632SLucile Quirion priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); 1499c668632SLucile Quirion if (!priv) 1509c668632SLucile Quirion return -ENOMEM; 1519c668632SLucile Quirion 1529c668632SLucile Quirion priv->gpio_chip = template_chip; 1539c668632SLucile Quirion priv->gpio_chip.label = "ts4900-gpio"; 1549c668632SLucile Quirion priv->gpio_chip.ngpio = ngpio; 1559c668632SLucile Quirion priv->gpio_chip.parent = &client->dev; 15681317c5aSThierry Reding priv->input_bit = (uintptr_t)of_device_get_match_data(&client->dev); 1579c668632SLucile Quirion 1589c668632SLucile Quirion priv->regmap = devm_regmap_init_i2c(client, &ts4900_regmap_config); 1599c668632SLucile Quirion if (IS_ERR(priv->regmap)) { 1609c668632SLucile Quirion ret = PTR_ERR(priv->regmap); 1619c668632SLucile Quirion dev_err(&client->dev, "Failed to allocate register map: %d\n", 1629c668632SLucile Quirion ret); 1639c668632SLucile Quirion return ret; 1649c668632SLucile Quirion } 1659c668632SLucile Quirion 1669c668632SLucile Quirion ret = devm_gpiochip_add_data(&client->dev, &priv->gpio_chip, priv); 1679c668632SLucile Quirion if (ret < 0) { 1689c668632SLucile Quirion dev_err(&client->dev, "Unable to register gpiochip\n"); 1699c668632SLucile Quirion return ret; 1709c668632SLucile Quirion } 1719c668632SLucile Quirion 1729c668632SLucile Quirion i2c_set_clientdata(client, priv); 1739c668632SLucile Quirion 1749c668632SLucile Quirion return 0; 1759c668632SLucile Quirion } 1769c668632SLucile Quirion 1779c668632SLucile Quirion static const struct i2c_device_id ts4900_gpio_id_table[] = { 1789c668632SLucile Quirion { "ts4900-gpio", }, 1799c668632SLucile Quirion { /* sentinel */ } 1809c668632SLucile Quirion }; 1819c668632SLucile Quirion MODULE_DEVICE_TABLE(i2c, ts4900_gpio_id_table); 1829c668632SLucile Quirion 1839c668632SLucile Quirion static struct i2c_driver ts4900_gpio_driver = { 1849c668632SLucile Quirion .driver = { 1859c668632SLucile Quirion .name = "ts4900-gpio", 1869c668632SLucile Quirion .of_match_table = ts4900_gpio_of_match_table, 1879c668632SLucile Quirion }, 188*b41cabb7SUwe Kleine-König .probe = ts4900_gpio_probe, 1899c668632SLucile Quirion .id_table = ts4900_gpio_id_table, 1909c668632SLucile Quirion }; 1919c668632SLucile Quirion module_i2c_driver(ts4900_gpio_driver); 1929c668632SLucile Quirion 1939c668632SLucile Quirion MODULE_AUTHOR("Technologic Systems"); 1949c668632SLucile Quirion MODULE_DESCRIPTION("GPIO interface for Technologic Systems I2C-FPGA core"); 1959c668632SLucile Quirion MODULE_LICENSE("GPL"); 196