brintos

brintos / linux-shallow public Read only

0
0
Text · 5.0 KiB · 3075f25 Raw
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