Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (ltc2992) Add support for GPIOs.

LTC2992 has 4 open-drain GPIOS. This patch exports to user
space the 4 GPIOs using the GPIO driver Linux API.

Signed-off-by: Alexandru Tachici <alexandru.tachici@analog.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Alexandru Tachici and committed by
Guenter Roeck
9ca26df1 b0bd407e

+160 -1
+1
drivers/hwmon/Kconfig
··· 874 874 config SENSORS_LTC2992 875 875 tristate "Linear Technology LTC2992" 876 876 depends on I2C 877 + depends on GPIOLIB 877 878 help 878 879 If you say yes here you get support for Linear Technology LTC2992 879 880 I2C System Monitor. The LTC2992 measures current, voltage, and
+159 -1
drivers/hwmon/ltc2992.c
··· 8 8 #include <linux/bitfield.h> 9 9 #include <linux/bitops.h> 10 10 #include <linux/err.h> 11 + #include <linux/gpio/driver.h> 11 12 #include <linux/hwmon.h> 12 13 #include <linux/i2c.h> 13 14 #include <linux/kernel.h> ··· 55 54 #define LTC2992_G4_MAX_THRESH 0x74 56 55 #define LTC2992_G4_MIN_THRESH 0x76 57 56 #define LTC2992_FAULT3 0x92 57 + #define LTC2992_GPIO_STATUS 0x95 58 + #define LTC2992_GPIO_IO_CTRL 0x96 59 + #define LTC2992_GPIO_CTRL 0x97 58 60 59 61 #define LTC2992_POWER(x) (LTC2992_POWER1 + ((x) * 0x32)) 60 62 #define LTC2992_POWER_MAX(x) (LTC2992_POWER1_MAX + ((x) * 0x32)) ··· 100 96 #define LTC2992_VADC_UV_LSB 25000 101 97 #define LTC2992_VADC_GPIO_UV_LSB 500 102 98 99 + #define LTC2992_GPIO_NR 4 100 + #define LTC2992_GPIO1_BIT 7 101 + #define LTC2992_GPIO2_BIT 6 102 + #define LTC2992_GPIO3_BIT 0 103 + #define LTC2992_GPIO4_BIT 6 104 + #define LTC2992_GPIO_BIT(x) (LTC2992_GPIO_NR - (x) - 1) 105 + 103 106 struct ltc2992_state { 104 107 struct i2c_client *client; 108 + struct gpio_chip gc; 109 + struct mutex gpio_mutex; /* lock for gpio access */ 110 + const char *gpio_names[LTC2992_GPIO_NR]; 105 111 struct regmap *regmap; 106 112 u32 r_sense_uohm[2]; 107 113 }; ··· 125 111 u8 alarm; 126 112 u8 min_alarm_msk; 127 113 u8 max_alarm_msk; 114 + u8 ctrl; 115 + u8 ctrl_bit; 128 116 }; 129 117 130 118 static const struct ltc2992_gpio_regs ltc2992_gpio_addr_map[] = { ··· 139 123 .alarm = LTC2992_FAULT1, 140 124 .min_alarm_msk = LTC2992_GPIO1_FAULT_MSK(0), 141 125 .max_alarm_msk = LTC2992_GPIO1_FAULT_MSK(1), 126 + .ctrl = LTC2992_GPIO_IO_CTRL, 127 + .ctrl_bit = LTC2992_GPIO1_BIT, 142 128 }, 143 129 { 144 130 .data = LTC2992_G2, ··· 151 133 .alarm = LTC2992_FAULT2, 152 134 .min_alarm_msk = LTC2992_GPIO2_FAULT_MSK(0), 153 135 .max_alarm_msk = LTC2992_GPIO2_FAULT_MSK(1), 136 + .ctrl = LTC2992_GPIO_IO_CTRL, 137 + .ctrl_bit = LTC2992_GPIO2_BIT, 154 138 }, 155 139 { 156 140 .data = LTC2992_G3, ··· 163 143 .alarm = LTC2992_FAULT3, 164 144 .min_alarm_msk = LTC2992_GPIO3_FAULT_MSK(0), 165 145 .max_alarm_msk = LTC2992_GPIO3_FAULT_MSK(1), 146 + .ctrl = LTC2992_GPIO_IO_CTRL, 147 + .ctrl_bit = LTC2992_GPIO3_BIT, 166 148 }, 167 149 { 168 150 .data = LTC2992_G4, ··· 175 153 .alarm = LTC2992_FAULT3, 176 154 .min_alarm_msk = LTC2992_GPIO4_FAULT_MSK(0), 177 155 .max_alarm_msk = LTC2992_GPIO4_FAULT_MSK(1), 156 + .ctrl = LTC2992_GPIO_CTRL, 157 + .ctrl_bit = LTC2992_GPIO4_BIT, 178 158 }, 159 + }; 160 + 161 + static const char *ltc2992_gpio_names[LTC2992_GPIO_NR] = { 162 + "GPIO1", "GPIO2", "GPIO3", "GPIO4", 179 163 }; 180 164 181 165 static int ltc2992_read_reg(struct ltc2992_state *st, u8 addr, const u8 reg_len) 182 166 { 183 167 u8 regvals[4]; 184 - int ret; 185 168 int val; 169 + int ret; 186 170 int i; 187 171 188 172 ret = regmap_bulk_read(st->regmap, addr, regvals, reg_len); ··· 211 183 regvals[reg_len - i - 1] = (val >> (i * 8)) & 0xFF; 212 184 213 185 return regmap_bulk_write(st->regmap, addr, regvals, reg_len); 186 + } 187 + 188 + static int ltc2992_gpio_get(struct gpio_chip *chip, unsigned int offset) 189 + { 190 + struct ltc2992_state *st = gpiochip_get_data(chip); 191 + unsigned long gpio_status; 192 + int reg; 193 + 194 + mutex_lock(&st->gpio_mutex); 195 + reg = ltc2992_read_reg(st, LTC2992_GPIO_STATUS, 1); 196 + mutex_unlock(&st->gpio_mutex); 197 + 198 + if (reg < 0) 199 + return reg; 200 + 201 + gpio_status = reg; 202 + 203 + return !test_bit(LTC2992_GPIO_BIT(offset), &gpio_status); 204 + } 205 + 206 + static int ltc2992_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, 207 + unsigned long *bits) 208 + { 209 + struct ltc2992_state *st = gpiochip_get_data(chip); 210 + unsigned long gpio_status; 211 + unsigned int gpio_nr; 212 + int reg; 213 + 214 + mutex_lock(&st->gpio_mutex); 215 + reg = ltc2992_read_reg(st, LTC2992_GPIO_STATUS, 1); 216 + mutex_unlock(&st->gpio_mutex); 217 + 218 + if (reg < 0) 219 + return reg; 220 + 221 + gpio_status = reg; 222 + 223 + gpio_nr = 0; 224 + for_each_set_bit_from(gpio_nr, mask, LTC2992_GPIO_NR) { 225 + if (test_bit(LTC2992_GPIO_BIT(gpio_nr), &gpio_status)) 226 + set_bit(gpio_nr, bits); 227 + } 228 + 229 + return 0; 230 + } 231 + 232 + static void ltc2992_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) 233 + { 234 + struct ltc2992_state *st = gpiochip_get_data(chip); 235 + unsigned long gpio_ctrl; 236 + int reg; 237 + 238 + mutex_lock(&st->gpio_mutex); 239 + reg = ltc2992_read_reg(st, ltc2992_gpio_addr_map[offset].ctrl, 1); 240 + if (reg < 0) { 241 + mutex_unlock(&st->gpio_mutex); 242 + return; 243 + } 244 + 245 + gpio_ctrl = reg; 246 + assign_bit(ltc2992_gpio_addr_map[offset].ctrl_bit, &gpio_ctrl, value); 247 + 248 + ltc2992_write_reg(st, ltc2992_gpio_addr_map[offset].ctrl, 1, gpio_ctrl); 249 + mutex_unlock(&st->gpio_mutex); 250 + } 251 + 252 + static void ltc2992_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask, 253 + unsigned long *bits) 254 + { 255 + struct ltc2992_state *st = gpiochip_get_data(chip); 256 + unsigned long gpio_ctrl_io = 0; 257 + unsigned long gpio_ctrl = 0; 258 + unsigned int gpio_nr; 259 + 260 + for_each_set_bit(gpio_nr, mask, LTC2992_GPIO_NR) { 261 + if (gpio_nr < 3) 262 + assign_bit(ltc2992_gpio_addr_map[gpio_nr].ctrl_bit, &gpio_ctrl_io, true); 263 + 264 + if (gpio_nr == 3) 265 + assign_bit(ltc2992_gpio_addr_map[gpio_nr].ctrl_bit, &gpio_ctrl, true); 266 + } 267 + 268 + mutex_lock(&st->gpio_mutex); 269 + ltc2992_write_reg(st, LTC2992_GPIO_IO_CTRL, 1, gpio_ctrl_io); 270 + ltc2992_write_reg(st, LTC2992_GPIO_CTRL, 1, gpio_ctrl); 271 + mutex_unlock(&st->gpio_mutex); 272 + } 273 + 274 + static int ltc2992_config_gpio(struct ltc2992_state *st) 275 + { 276 + const char *name = dev_name(&st->client->dev); 277 + char *gpio_name; 278 + int ret; 279 + int i; 280 + 281 + ret = ltc2992_write_reg(st, LTC2992_GPIO_IO_CTRL, 1, 0); 282 + if (ret < 0) 283 + return ret; 284 + 285 + mutex_init(&st->gpio_mutex); 286 + 287 + for (i = 0; i < ARRAY_SIZE(st->gpio_names); i++) { 288 + gpio_name = devm_kasprintf(&st->client->dev, GFP_KERNEL, "ltc2992-%x-%s", 289 + st->client->addr, ltc2992_gpio_names[i]); 290 + if (!gpio_name) 291 + return -ENOMEM; 292 + 293 + st->gpio_names[i] = gpio_name; 294 + } 295 + 296 + st->gc.label = name; 297 + st->gc.parent = &st->client->dev; 298 + st->gc.owner = THIS_MODULE; 299 + st->gc.base = -1; 300 + st->gc.names = st->gpio_names; 301 + st->gc.ngpio = ARRAY_SIZE(st->gpio_names); 302 + st->gc.get = ltc2992_gpio_get; 303 + st->gc.get_multiple = ltc2992_gpio_get_multiple; 304 + st->gc.set = ltc2992_gpio_set; 305 + st->gc.set_multiple = ltc2992_gpio_set_multiple; 306 + 307 + ret = devm_gpiochip_add_data(&st->client->dev, &st->gc, st); 308 + if (ret) 309 + dev_err(&st->client->dev, "GPIO registering failed (%d)\n", ret); 310 + 311 + return ret; 214 312 } 215 313 216 314 static umode_t ltc2992_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, ··· 930 776 return PTR_ERR(st->regmap); 931 777 932 778 ret = ltc2992_parse_dt(st); 779 + if (ret < 0) 780 + return ret; 781 + 782 + ret = ltc2992_config_gpio(st); 933 783 if (ret < 0) 934 784 return ret; 935 785