192 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// Copyright (C) 2018 BayLibre SAS4// Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>5//6// GPIO driver for MAXIM 77650/77651 charger/power-supply.7 8#include <linux/gpio/driver.h>9#include <linux/i2c.h>10#include <linux/mfd/max77650.h>11#include <linux/module.h>12#include <linux/platform_device.h>13#include <linux/regmap.h>14 15#define MAX77650_GPIO_DIR_MASK BIT(0)16#define MAX77650_GPIO_INVAL_MASK BIT(1)17#define MAX77650_GPIO_DRV_MASK BIT(2)18#define MAX77650_GPIO_OUTVAL_MASK BIT(3)19#define MAX77650_GPIO_DEBOUNCE_MASK BIT(4)20 21#define MAX77650_GPIO_DIR_OUT 0x0022#define MAX77650_GPIO_DIR_IN BIT(0)23#define MAX77650_GPIO_OUT_LOW 0x0024#define MAX77650_GPIO_OUT_HIGH BIT(3)25#define MAX77650_GPIO_DRV_OPEN_DRAIN 0x0026#define MAX77650_GPIO_DRV_PUSH_PULL BIT(2)27#define MAX77650_GPIO_DEBOUNCE BIT(4)28 29#define MAX77650_GPIO_DIR_BITS(_reg) \30 ((_reg) & MAX77650_GPIO_DIR_MASK)31#define MAX77650_GPIO_INVAL_BITS(_reg) \32 (((_reg) & MAX77650_GPIO_INVAL_MASK) >> 1)33 34struct max77650_gpio_chip {35 struct regmap *map;36 struct gpio_chip gc;37 int irq;38};39 40static int max77650_gpio_direction_input(struct gpio_chip *gc,41 unsigned int offset)42{43 struct max77650_gpio_chip *chip = gpiochip_get_data(gc);44 45 return regmap_update_bits(chip->map,46 MAX77650_REG_CNFG_GPIO,47 MAX77650_GPIO_DIR_MASK,48 MAX77650_GPIO_DIR_IN);49}50 51static int max77650_gpio_direction_output(struct gpio_chip *gc,52 unsigned int offset, int value)53{54 struct max77650_gpio_chip *chip = gpiochip_get_data(gc);55 int mask, regval;56 57 mask = MAX77650_GPIO_DIR_MASK | MAX77650_GPIO_OUTVAL_MASK;58 regval = value ? MAX77650_GPIO_OUT_HIGH : MAX77650_GPIO_OUT_LOW;59 regval |= MAX77650_GPIO_DIR_OUT;60 61 return regmap_update_bits(chip->map,62 MAX77650_REG_CNFG_GPIO, mask, regval);63}64 65static void max77650_gpio_set_value(struct gpio_chip *gc,66 unsigned int offset, int value)67{68 struct max77650_gpio_chip *chip = gpiochip_get_data(gc);69 int rv, regval;70 71 regval = value ? MAX77650_GPIO_OUT_HIGH : MAX77650_GPIO_OUT_LOW;72 73 rv = regmap_update_bits(chip->map, MAX77650_REG_CNFG_GPIO,74 MAX77650_GPIO_OUTVAL_MASK, regval);75 if (rv)76 dev_err(gc->parent, "cannot set GPIO value: %d\n", rv);77}78 79static int max77650_gpio_get_value(struct gpio_chip *gc,80 unsigned int offset)81{82 struct max77650_gpio_chip *chip = gpiochip_get_data(gc);83 unsigned int val;84 int rv;85 86 rv = regmap_read(chip->map, MAX77650_REG_CNFG_GPIO, &val);87 if (rv)88 return rv;89 90 return MAX77650_GPIO_INVAL_BITS(val);91}92 93static int max77650_gpio_get_direction(struct gpio_chip *gc,94 unsigned int offset)95{96 struct max77650_gpio_chip *chip = gpiochip_get_data(gc);97 unsigned int val;98 int rv;99 100 rv = regmap_read(chip->map, MAX77650_REG_CNFG_GPIO, &val);101 if (rv)102 return rv;103 104 return MAX77650_GPIO_DIR_BITS(val);105}106 107static int max77650_gpio_set_config(struct gpio_chip *gc,108 unsigned int offset, unsigned long cfg)109{110 struct max77650_gpio_chip *chip = gpiochip_get_data(gc);111 112 switch (pinconf_to_config_param(cfg)) {113 case PIN_CONFIG_DRIVE_OPEN_DRAIN:114 return regmap_update_bits(chip->map,115 MAX77650_REG_CNFG_GPIO,116 MAX77650_GPIO_DRV_MASK,117 MAX77650_GPIO_DRV_OPEN_DRAIN);118 case PIN_CONFIG_DRIVE_PUSH_PULL:119 return regmap_update_bits(chip->map,120 MAX77650_REG_CNFG_GPIO,121 MAX77650_GPIO_DRV_MASK,122 MAX77650_GPIO_DRV_PUSH_PULL);123 case PIN_CONFIG_INPUT_DEBOUNCE:124 return regmap_update_bits(chip->map,125 MAX77650_REG_CNFG_GPIO,126 MAX77650_GPIO_DEBOUNCE_MASK,127 MAX77650_GPIO_DEBOUNCE);128 default:129 return -ENOTSUPP;130 }131}132 133static int max77650_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)134{135 struct max77650_gpio_chip *chip = gpiochip_get_data(gc);136 137 return chip->irq;138}139 140static int max77650_gpio_probe(struct platform_device *pdev)141{142 struct max77650_gpio_chip *chip;143 struct device *dev, *parent;144 struct i2c_client *i2c;145 146 dev = &pdev->dev;147 parent = dev->parent;148 i2c = to_i2c_client(parent);149 150 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);151 if (!chip)152 return -ENOMEM;153 154 chip->map = dev_get_regmap(parent, NULL);155 if (!chip->map)156 return -ENODEV;157 158 chip->irq = platform_get_irq_byname(pdev, "GPI");159 if (chip->irq < 0)160 return chip->irq;161 162 chip->gc.base = -1;163 chip->gc.ngpio = 1;164 chip->gc.label = i2c->name;165 chip->gc.parent = dev;166 chip->gc.owner = THIS_MODULE;167 chip->gc.can_sleep = true;168 169 chip->gc.direction_input = max77650_gpio_direction_input;170 chip->gc.direction_output = max77650_gpio_direction_output;171 chip->gc.set = max77650_gpio_set_value;172 chip->gc.get = max77650_gpio_get_value;173 chip->gc.get_direction = max77650_gpio_get_direction;174 chip->gc.set_config = max77650_gpio_set_config;175 chip->gc.to_irq = max77650_gpio_to_irq;176 177 return devm_gpiochip_add_data(dev, &chip->gc, chip);178}179 180static struct platform_driver max77650_gpio_driver = {181 .driver = {182 .name = "max77650-gpio",183 },184 .probe = max77650_gpio_probe,185};186module_platform_driver(max77650_gpio_driver);187 188MODULE_DESCRIPTION("MAXIM 77650/77651 GPIO driver");189MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");190MODULE_LICENSE("GPL v2");191MODULE_ALIAS("platform:max77650-gpio");192