1 /* 2 * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ 3 * Keerthy <j-keerthy@ti.com> 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 10 * kind, whether expressed or implied; without even the implied warranty 11 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License version 2 for more details. 13 * 14 * Based on the TPS65218 driver 15 */ 16 17 #include <linux/gpio/driver.h> 18 #include <linux/module.h> 19 #include <linux/platform_device.h> 20 #include <linux/regmap.h> 21 22 #include <linux/mfd/lp873x.h> 23 24 #define BITS_PER_GPO 0x4 25 #define LP873X_GPO_CTRL_OD 0x2 26 27 struct lp873x_gpio { 28 struct gpio_chip chip; 29 struct lp873x *lp873; 30 }; 31 32 static int lp873x_gpio_get_direction(struct gpio_chip *chip, 33 unsigned int offset) 34 { 35 /* This device is output only */ 36 return 0; 37 } 38 39 static int lp873x_gpio_direction_input(struct gpio_chip *chip, 40 unsigned int offset) 41 { 42 /* This device is output only */ 43 return -EINVAL; 44 } 45 46 static int lp873x_gpio_direction_output(struct gpio_chip *chip, 47 unsigned int offset, int value) 48 { 49 struct lp873x_gpio *gpio = gpiochip_get_data(chip); 50 51 /* Set the initial value */ 52 return regmap_update_bits(gpio->lp873->regmap, LP873X_REG_GPO_CTRL, 53 BIT(offset * BITS_PER_GPO), 54 value ? BIT(offset * BITS_PER_GPO) : 0); 55 } 56 57 static int lp873x_gpio_get(struct gpio_chip *chip, unsigned int offset) 58 { 59 struct lp873x_gpio *gpio = gpiochip_get_data(chip); 60 int ret, val; 61 62 ret = regmap_read(gpio->lp873->regmap, LP873X_REG_GPO_CTRL, &val); 63 if (ret < 0) 64 return ret; 65 66 return val & BIT(offset * BITS_PER_GPO); 67 } 68 69 static void lp873x_gpio_set(struct gpio_chip *chip, unsigned int offset, 70 int value) 71 { 72 struct lp873x_gpio *gpio = gpiochip_get_data(chip); 73 74 regmap_update_bits(gpio->lp873->regmap, LP873X_REG_GPO_CTRL, 75 BIT(offset * BITS_PER_GPO), 76 value ? BIT(offset * BITS_PER_GPO) : 0); 77 } 78 79 static int lp873x_gpio_request(struct gpio_chip *gc, unsigned int offset) 80 { 81 struct lp873x_gpio *gpio = gpiochip_get_data(gc); 82 int ret; 83 84 switch (offset) { 85 case 0: 86 /* No MUX Set up Needed for GPO */ 87 break; 88 case 1: 89 /* Setup the CLKIN_PIN_SEL MUX to GPO2 */ 90 ret = regmap_update_bits(gpio->lp873->regmap, LP873X_REG_CONFIG, 91 LP873X_CONFIG_CLKIN_PIN_SEL, 0); 92 if (ret) 93 return ret; 94 95 break; 96 default: 97 return -EINVAL; 98 } 99 100 return 0; 101 } 102 103 static int lp873x_gpio_set_config(struct gpio_chip *gc, unsigned offset, 104 unsigned long config) 105 { 106 struct lp873x_gpio *gpio = gpiochip_get_data(gc); 107 108 switch (pinconf_to_config_param(config)) { 109 case PIN_CONFIG_DRIVE_OPEN_DRAIN: 110 return regmap_update_bits(gpio->lp873->regmap, 111 LP873X_REG_GPO_CTRL, 112 BIT(offset * BITS_PER_GPO + 113 LP873X_GPO_CTRL_OD), 114 BIT(offset * BITS_PER_GPO + 115 LP873X_GPO_CTRL_OD)); 116 117 case PIN_CONFIG_DRIVE_PUSH_PULL: 118 return regmap_update_bits(gpio->lp873->regmap, 119 LP873X_REG_GPO_CTRL, 120 BIT(offset * BITS_PER_GPO + 121 LP873X_GPO_CTRL_OD), 0); 122 default: 123 return -ENOTSUPP; 124 } 125 } 126 127 static const struct gpio_chip template_chip = { 128 .label = "lp873x-gpio", 129 .owner = THIS_MODULE, 130 .request = lp873x_gpio_request, 131 .get_direction = lp873x_gpio_get_direction, 132 .direction_input = lp873x_gpio_direction_input, 133 .direction_output = lp873x_gpio_direction_output, 134 .get = lp873x_gpio_get, 135 .set = lp873x_gpio_set, 136 .set_config = lp873x_gpio_set_config, 137 .base = -1, 138 .ngpio = 2, 139 .can_sleep = true, 140 }; 141 142 static int lp873x_gpio_probe(struct platform_device *pdev) 143 { 144 struct lp873x_gpio *gpio; 145 int ret; 146 147 gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); 148 if (!gpio) 149 return -ENOMEM; 150 151 platform_set_drvdata(pdev, gpio); 152 153 gpio->lp873 = dev_get_drvdata(pdev->dev.parent); 154 gpio->chip = template_chip; 155 gpio->chip.parent = gpio->lp873->dev; 156 157 ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); 158 if (ret < 0) { 159 dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); 160 return ret; 161 } 162 163 return 0; 164 } 165 166 static const struct platform_device_id lp873x_gpio_id_table[] = { 167 { "lp873x-gpio", }, 168 { /* sentinel */ } 169 }; 170 MODULE_DEVICE_TABLE(platform, lp873x_gpio_id_table); 171 172 static struct platform_driver lp873x_gpio_driver = { 173 .driver = { 174 .name = "lp873x-gpio", 175 }, 176 .probe = lp873x_gpio_probe, 177 .id_table = lp873x_gpio_id_table, 178 }; 179 module_platform_driver(lp873x_gpio_driver); 180 181 MODULE_AUTHOR("Keerthy <j-keerthy@ti.com>"); 182 MODULE_DESCRIPTION("LP873X GPIO driver"); 183 MODULE_LICENSE("GPL v2"); 184