183f14103SKeerthy /* 283f14103SKeerthy * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ 383f14103SKeerthy * Keerthy <j-keerthy@ti.com> 483f14103SKeerthy * 583f14103SKeerthy * This program is free software; you can redistribute it and/or 683f14103SKeerthy * modify it under the terms of the GNU General Public License version 2 as 783f14103SKeerthy * published by the Free Software Foundation. 883f14103SKeerthy * 983f14103SKeerthy * This program is distributed "as is" WITHOUT ANY WARRANTY of any 1083f14103SKeerthy * kind, whether expressed or implied; without even the implied warranty 1183f14103SKeerthy * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1283f14103SKeerthy * GNU General Public License version 2 for more details. 1383f14103SKeerthy * 1483f14103SKeerthy * Based on the TPS65218 driver 1583f14103SKeerthy */ 1683f14103SKeerthy 1783f14103SKeerthy #include <linux/gpio.h> 1883f14103SKeerthy #include <linux/module.h> 1983f14103SKeerthy #include <linux/platform_device.h> 2083f14103SKeerthy #include <linux/regmap.h> 2183f14103SKeerthy 2283f14103SKeerthy #include <linux/mfd/lp873x.h> 2383f14103SKeerthy 2483f14103SKeerthy #define BITS_PER_GPO 0x4 2583f14103SKeerthy #define LP873X_GPO_CTRL_OD 0x2 2683f14103SKeerthy 2783f14103SKeerthy struct lp873x_gpio { 2883f14103SKeerthy struct gpio_chip chip; 2983f14103SKeerthy struct lp873x *lp873; 3083f14103SKeerthy }; 3183f14103SKeerthy 3283f14103SKeerthy static int lp873x_gpio_get_direction(struct gpio_chip *chip, 3383f14103SKeerthy unsigned int offset) 3483f14103SKeerthy { 3583f14103SKeerthy /* This device is output only */ 3683f14103SKeerthy return 0; 3783f14103SKeerthy } 3883f14103SKeerthy 3983f14103SKeerthy static int lp873x_gpio_direction_input(struct gpio_chip *chip, 4083f14103SKeerthy unsigned int offset) 4183f14103SKeerthy { 4283f14103SKeerthy /* This device is output only */ 4383f14103SKeerthy return -EINVAL; 4483f14103SKeerthy } 4583f14103SKeerthy 4683f14103SKeerthy static int lp873x_gpio_direction_output(struct gpio_chip *chip, 4783f14103SKeerthy unsigned int offset, int value) 4883f14103SKeerthy { 4983f14103SKeerthy struct lp873x_gpio *gpio = gpiochip_get_data(chip); 5083f14103SKeerthy 5183f14103SKeerthy /* Set the initial value */ 5283f14103SKeerthy return regmap_update_bits(gpio->lp873->regmap, LP873X_REG_GPO_CTRL, 5383f14103SKeerthy BIT(offset * BITS_PER_GPO), 5483f14103SKeerthy value ? BIT(offset * BITS_PER_GPO) : 0); 5583f14103SKeerthy } 5683f14103SKeerthy 5783f14103SKeerthy static int lp873x_gpio_get(struct gpio_chip *chip, unsigned int offset) 5883f14103SKeerthy { 5983f14103SKeerthy struct lp873x_gpio *gpio = gpiochip_get_data(chip); 6083f14103SKeerthy int ret, val; 6183f14103SKeerthy 6283f14103SKeerthy ret = regmap_read(gpio->lp873->regmap, LP873X_REG_GPO_CTRL, &val); 6383f14103SKeerthy if (ret < 0) 6483f14103SKeerthy return ret; 6583f14103SKeerthy 6683f14103SKeerthy return val & BIT(offset * BITS_PER_GPO); 6783f14103SKeerthy } 6883f14103SKeerthy 6983f14103SKeerthy static void lp873x_gpio_set(struct gpio_chip *chip, unsigned int offset, 7083f14103SKeerthy int value) 7183f14103SKeerthy { 7283f14103SKeerthy struct lp873x_gpio *gpio = gpiochip_get_data(chip); 7383f14103SKeerthy 7483f14103SKeerthy regmap_update_bits(gpio->lp873->regmap, LP873X_REG_GPO_CTRL, 7583f14103SKeerthy BIT(offset * BITS_PER_GPO), 7683f14103SKeerthy value ? BIT(offset * BITS_PER_GPO) : 0); 7783f14103SKeerthy } 7883f14103SKeerthy 7983f14103SKeerthy static int lp873x_gpio_request(struct gpio_chip *gc, unsigned int offset) 8083f14103SKeerthy { 8183f14103SKeerthy struct lp873x_gpio *gpio = gpiochip_get_data(gc); 8283f14103SKeerthy int ret; 8383f14103SKeerthy 8483f14103SKeerthy switch (offset) { 8583f14103SKeerthy case 0: 8683f14103SKeerthy /* No MUX Set up Needed for GPO */ 8783f14103SKeerthy break; 8883f14103SKeerthy case 1: 8983f14103SKeerthy /* Setup the CLKIN_PIN_SEL MUX to GPO2 */ 9083f14103SKeerthy ret = regmap_update_bits(gpio->lp873->regmap, LP873X_REG_CONFIG, 9183f14103SKeerthy LP873X_CONFIG_CLKIN_PIN_SEL, 0); 9283f14103SKeerthy if (ret) 9383f14103SKeerthy return ret; 9483f14103SKeerthy 9583f14103SKeerthy break; 9683f14103SKeerthy default: 9783f14103SKeerthy return -EINVAL; 9883f14103SKeerthy } 9983f14103SKeerthy 10083f14103SKeerthy return 0; 10183f14103SKeerthy } 10283f14103SKeerthy 10383f14103SKeerthy static int lp873x_gpio_set_single_ended(struct gpio_chip *gc, 10483f14103SKeerthy unsigned int offset, 10583f14103SKeerthy enum single_ended_mode mode) 10683f14103SKeerthy { 10783f14103SKeerthy struct lp873x_gpio *gpio = gpiochip_get_data(gc); 10883f14103SKeerthy 10983f14103SKeerthy switch (mode) { 11083f14103SKeerthy case LINE_MODE_OPEN_DRAIN: 11183f14103SKeerthy return regmap_update_bits(gpio->lp873->regmap, 11283f14103SKeerthy LP873X_REG_GPO_CTRL, 11383f14103SKeerthy BIT(offset * BITS_PER_GPO + 11483f14103SKeerthy LP873X_GPO_CTRL_OD), 11583f14103SKeerthy BIT(offset * BITS_PER_GPO + 11683f14103SKeerthy LP873X_GPO_CTRL_OD)); 11783f14103SKeerthy case LINE_MODE_PUSH_PULL: 11883f14103SKeerthy return regmap_update_bits(gpio->lp873->regmap, 11983f14103SKeerthy LP873X_REG_GPO_CTRL, 12083f14103SKeerthy BIT(offset * BITS_PER_GPO + 12183f14103SKeerthy LP873X_GPO_CTRL_OD), 0); 12283f14103SKeerthy default: 12383f14103SKeerthy return -ENOTSUPP; 12483f14103SKeerthy } 12583f14103SKeerthy } 12683f14103SKeerthy 127e35b5ab0SJulia Lawall static const struct gpio_chip template_chip = { 12883f14103SKeerthy .label = "lp873x-gpio", 12983f14103SKeerthy .owner = THIS_MODULE, 13083f14103SKeerthy .request = lp873x_gpio_request, 13183f14103SKeerthy .get_direction = lp873x_gpio_get_direction, 13283f14103SKeerthy .direction_input = lp873x_gpio_direction_input, 13383f14103SKeerthy .direction_output = lp873x_gpio_direction_output, 13483f14103SKeerthy .get = lp873x_gpio_get, 13583f14103SKeerthy .set = lp873x_gpio_set, 13683f14103SKeerthy .set_single_ended = lp873x_gpio_set_single_ended, 13783f14103SKeerthy .base = -1, 13883f14103SKeerthy .ngpio = 2, 13983f14103SKeerthy .can_sleep = true, 14083f14103SKeerthy }; 14183f14103SKeerthy 14283f14103SKeerthy static int lp873x_gpio_probe(struct platform_device *pdev) 14383f14103SKeerthy { 14483f14103SKeerthy struct lp873x_gpio *gpio; 14583f14103SKeerthy int ret; 14683f14103SKeerthy 14783f14103SKeerthy gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); 14883f14103SKeerthy if (!gpio) 14983f14103SKeerthy return -ENOMEM; 15083f14103SKeerthy 15183f14103SKeerthy platform_set_drvdata(pdev, gpio); 15283f14103SKeerthy 15383f14103SKeerthy gpio->lp873 = dev_get_drvdata(pdev->dev.parent); 15483f14103SKeerthy gpio->chip = template_chip; 15583f14103SKeerthy gpio->chip.parent = gpio->lp873->dev; 15683f14103SKeerthy 1579d99c41aSWei Yongjun ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); 15883f14103SKeerthy if (ret < 0) { 15983f14103SKeerthy dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); 16083f14103SKeerthy return ret; 16183f14103SKeerthy } 16283f14103SKeerthy 16383f14103SKeerthy return 0; 16483f14103SKeerthy } 16583f14103SKeerthy 16683f14103SKeerthy static const struct platform_device_id lp873x_gpio_id_table[] = { 16783f14103SKeerthy { "lp873x-gpio", }, 16883f14103SKeerthy { /* sentinel */ } 16983f14103SKeerthy }; 17083f14103SKeerthy MODULE_DEVICE_TABLE(platform, lp873x_gpio_id_table); 17183f14103SKeerthy 17283f14103SKeerthy static struct platform_driver lp873x_gpio_driver = { 17383f14103SKeerthy .driver = { 17483f14103SKeerthy .name = "lp873x-gpio", 17583f14103SKeerthy }, 17683f14103SKeerthy .probe = lp873x_gpio_probe, 17783f14103SKeerthy .id_table = lp873x_gpio_id_table, 17883f14103SKeerthy }; 17983f14103SKeerthy module_platform_driver(lp873x_gpio_driver); 18083f14103SKeerthy 18183f14103SKeerthy MODULE_AUTHOR("Keerthy <j-keerthy@ti.com>"); 18283f14103SKeerthy MODULE_DESCRIPTION("LP873X GPIO driver"); 18383f14103SKeerthy MODULE_LICENSE("GPL v2"); 184