gpio-lp3943.c (5458B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * TI/National Semiconductor LP3943 GPIO driver 4 * 5 * Copyright 2013 Texas Instruments 6 * 7 * Author: Milo Kim <milo.kim@ti.com> 8 */ 9 10#include <linux/bitops.h> 11#include <linux/err.h> 12#include <linux/gpio/driver.h> 13#include <linux/i2c.h> 14#include <linux/mfd/lp3943.h> 15#include <linux/module.h> 16#include <linux/platform_device.h> 17#include <linux/slab.h> 18 19enum lp3943_gpios { 20 LP3943_GPIO1, 21 LP3943_GPIO2, 22 LP3943_GPIO3, 23 LP3943_GPIO4, 24 LP3943_GPIO5, 25 LP3943_GPIO6, 26 LP3943_GPIO7, 27 LP3943_GPIO8, 28 LP3943_GPIO9, 29 LP3943_GPIO10, 30 LP3943_GPIO11, 31 LP3943_GPIO12, 32 LP3943_GPIO13, 33 LP3943_GPIO14, 34 LP3943_GPIO15, 35 LP3943_GPIO16, 36 LP3943_MAX_GPIO, 37}; 38 39struct lp3943_gpio { 40 struct gpio_chip chip; 41 struct lp3943 *lp3943; 42 u16 input_mask; /* 1 = GPIO is input direction, 0 = output */ 43}; 44 45static int lp3943_gpio_request(struct gpio_chip *chip, unsigned offset) 46{ 47 struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip); 48 struct lp3943 *lp3943 = lp3943_gpio->lp3943; 49 50 /* Return an error if the pin is already assigned */ 51 if (test_and_set_bit(offset, &lp3943->pin_used)) 52 return -EBUSY; 53 54 return 0; 55} 56 57static void lp3943_gpio_free(struct gpio_chip *chip, unsigned offset) 58{ 59 struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip); 60 struct lp3943 *lp3943 = lp3943_gpio->lp3943; 61 62 clear_bit(offset, &lp3943->pin_used); 63} 64 65static int lp3943_gpio_set_mode(struct lp3943_gpio *lp3943_gpio, u8 offset, 66 u8 val) 67{ 68 struct lp3943 *lp3943 = lp3943_gpio->lp3943; 69 const struct lp3943_reg_cfg *mux = lp3943->mux_cfg; 70 71 return lp3943_update_bits(lp3943, mux[offset].reg, mux[offset].mask, 72 val << mux[offset].shift); 73} 74 75static int lp3943_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 76{ 77 struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip); 78 79 lp3943_gpio->input_mask |= BIT(offset); 80 81 return lp3943_gpio_set_mode(lp3943_gpio, offset, LP3943_GPIO_IN); 82} 83 84static int lp3943_get_gpio_in_status(struct lp3943_gpio *lp3943_gpio, 85 struct gpio_chip *chip, unsigned offset) 86{ 87 u8 addr, read; 88 int err; 89 90 switch (offset) { 91 case LP3943_GPIO1 ... LP3943_GPIO8: 92 addr = LP3943_REG_GPIO_A; 93 break; 94 case LP3943_GPIO9 ... LP3943_GPIO16: 95 addr = LP3943_REG_GPIO_B; 96 offset = offset - 8; 97 break; 98 default: 99 return -EINVAL; 100 } 101 102 err = lp3943_read_byte(lp3943_gpio->lp3943, addr, &read); 103 if (err) 104 return err; 105 106 return !!(read & BIT(offset)); 107} 108 109static int lp3943_get_gpio_out_status(struct lp3943_gpio *lp3943_gpio, 110 struct gpio_chip *chip, unsigned offset) 111{ 112 struct lp3943 *lp3943 = lp3943_gpio->lp3943; 113 const struct lp3943_reg_cfg *mux = lp3943->mux_cfg; 114 u8 read; 115 int err; 116 117 err = lp3943_read_byte(lp3943, mux[offset].reg, &read); 118 if (err) 119 return err; 120 121 read = (read & mux[offset].mask) >> mux[offset].shift; 122 123 if (read == LP3943_GPIO_OUT_HIGH) 124 return 1; 125 else if (read == LP3943_GPIO_OUT_LOW) 126 return 0; 127 else 128 return -EINVAL; 129} 130 131static int lp3943_gpio_get(struct gpio_chip *chip, unsigned offset) 132{ 133 struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip); 134 135 /* 136 * Limitation: 137 * LP3943 doesn't have the GPIO direction register. It provides 138 * only input and output status registers. 139 * So, direction info is required to handle the 'get' operation. 140 * This variable is updated whenever the direction is changed and 141 * it is used here. 142 */ 143 144 if (lp3943_gpio->input_mask & BIT(offset)) 145 return lp3943_get_gpio_in_status(lp3943_gpio, chip, offset); 146 else 147 return lp3943_get_gpio_out_status(lp3943_gpio, chip, offset); 148} 149 150static void lp3943_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 151{ 152 struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip); 153 u8 data; 154 155 if (value) 156 data = LP3943_GPIO_OUT_HIGH; 157 else 158 data = LP3943_GPIO_OUT_LOW; 159 160 lp3943_gpio_set_mode(lp3943_gpio, offset, data); 161} 162 163static int lp3943_gpio_direction_output(struct gpio_chip *chip, unsigned offset, 164 int value) 165{ 166 struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip); 167 168 lp3943_gpio_set(chip, offset, value); 169 lp3943_gpio->input_mask &= ~BIT(offset); 170 171 return 0; 172} 173 174static const struct gpio_chip lp3943_gpio_chip = { 175 .label = "lp3943", 176 .owner = THIS_MODULE, 177 .request = lp3943_gpio_request, 178 .free = lp3943_gpio_free, 179 .direction_input = lp3943_gpio_direction_input, 180 .get = lp3943_gpio_get, 181 .direction_output = lp3943_gpio_direction_output, 182 .set = lp3943_gpio_set, 183 .base = -1, 184 .ngpio = LP3943_MAX_GPIO, 185 .can_sleep = 1, 186}; 187 188static int lp3943_gpio_probe(struct platform_device *pdev) 189{ 190 struct lp3943 *lp3943 = dev_get_drvdata(pdev->dev.parent); 191 struct lp3943_gpio *lp3943_gpio; 192 193 lp3943_gpio = devm_kzalloc(&pdev->dev, sizeof(*lp3943_gpio), 194 GFP_KERNEL); 195 if (!lp3943_gpio) 196 return -ENOMEM; 197 198 lp3943_gpio->lp3943 = lp3943; 199 lp3943_gpio->chip = lp3943_gpio_chip; 200 lp3943_gpio->chip.parent = &pdev->dev; 201 202 platform_set_drvdata(pdev, lp3943_gpio); 203 204 return devm_gpiochip_add_data(&pdev->dev, &lp3943_gpio->chip, 205 lp3943_gpio); 206} 207 208static const struct of_device_id lp3943_gpio_of_match[] = { 209 { .compatible = "ti,lp3943-gpio", }, 210 { } 211}; 212MODULE_DEVICE_TABLE(of, lp3943_gpio_of_match); 213 214static struct platform_driver lp3943_gpio_driver = { 215 .probe = lp3943_gpio_probe, 216 .driver = { 217 .name = "lp3943-gpio", 218 .of_match_table = lp3943_gpio_of_match, 219 }, 220}; 221module_platform_driver(lp3943_gpio_driver); 222 223MODULE_DESCRIPTION("LP3943 GPIO driver"); 224MODULE_ALIAS("platform:lp3943-gpio"); 225MODULE_AUTHOR("Milo Kim"); 226MODULE_LICENSE("GPL");