brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · 2bba27b Raw
125 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (c) 2019, Linaro Limited3 4#include <linux/mod_devicetable.h>5#include <linux/module.h>6#include <linux/gpio/driver.h>7#include <linux/platform_device.h>8#include <linux/regmap.h>9#include <linux/slab.h>10 11#define WCD_PIN_MASK(p) BIT(p)12#define WCD_REG_DIR_CTL_OFFSET 0x4213#define WCD_REG_VAL_CTL_OFFSET 0x4314#define WCD934X_NPINS		515 16struct wcd_gpio_data {17	struct regmap *map;18	struct gpio_chip chip;19};20 21static int wcd_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)22{23	struct wcd_gpio_data *data = gpiochip_get_data(chip);24	unsigned int value;25	int ret;26 27	ret = regmap_read(data->map, WCD_REG_DIR_CTL_OFFSET, &value);28	if (ret < 0)29		return ret;30 31	if (value & WCD_PIN_MASK(pin))32		return GPIO_LINE_DIRECTION_OUT;33 34	return GPIO_LINE_DIRECTION_IN;35}36 37static int wcd_gpio_direction_input(struct gpio_chip *chip, unsigned int pin)38{39	struct wcd_gpio_data *data = gpiochip_get_data(chip);40 41	return regmap_update_bits(data->map, WCD_REG_DIR_CTL_OFFSET,42				  WCD_PIN_MASK(pin), 0);43}44 45static int wcd_gpio_direction_output(struct gpio_chip *chip, unsigned int pin,46				     int val)47{48	struct wcd_gpio_data *data = gpiochip_get_data(chip);49 50	regmap_update_bits(data->map, WCD_REG_DIR_CTL_OFFSET,51			   WCD_PIN_MASK(pin), WCD_PIN_MASK(pin));52 53	return regmap_update_bits(data->map, WCD_REG_VAL_CTL_OFFSET,54				  WCD_PIN_MASK(pin),55				  val ? WCD_PIN_MASK(pin) : 0);56}57 58static int wcd_gpio_get(struct gpio_chip *chip, unsigned int pin)59{60	struct wcd_gpio_data *data = gpiochip_get_data(chip);61	unsigned int value;62 63	regmap_read(data->map, WCD_REG_VAL_CTL_OFFSET, &value);64 65	return !!(value & WCD_PIN_MASK(pin));66}67 68static void wcd_gpio_set(struct gpio_chip *chip, unsigned int pin, int val)69{70	struct wcd_gpio_data *data = gpiochip_get_data(chip);71 72	regmap_update_bits(data->map, WCD_REG_VAL_CTL_OFFSET,73			   WCD_PIN_MASK(pin), val ? WCD_PIN_MASK(pin) : 0);74}75 76static int wcd_gpio_probe(struct platform_device *pdev)77{78	struct device *dev = &pdev->dev;79	struct wcd_gpio_data *data;80	struct gpio_chip *chip;81 82	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);83	if (!data)84		return -ENOMEM;85 86	data->map = dev_get_regmap(dev->parent, NULL);87	if (!data->map) {88		dev_err(dev, "%s: failed to get regmap\n", __func__);89		return  -EINVAL;90	}91 92	chip = &data->chip;93	chip->direction_input  = wcd_gpio_direction_input;94	chip->direction_output = wcd_gpio_direction_output;95	chip->get_direction = wcd_gpio_get_direction;96	chip->get = wcd_gpio_get;97	chip->set = wcd_gpio_set;98	chip->parent = dev;99	chip->base = -1;100	chip->ngpio = WCD934X_NPINS;101	chip->label = dev_name(dev);102	chip->can_sleep = false;103 104	return devm_gpiochip_add_data(dev, chip, data);105}106 107static const struct of_device_id wcd_gpio_of_match[] = {108	{ .compatible = "qcom,wcd9340-gpio" },109	{ .compatible = "qcom,wcd9341-gpio" },110	{ }111};112MODULE_DEVICE_TABLE(of, wcd_gpio_of_match);113 114static struct platform_driver wcd_gpio_driver = {115	.driver = {116		   .name = "wcd934x-gpio",117		   .of_match_table = wcd_gpio_of_match,118	},119	.probe = wcd_gpio_probe,120};121 122module_platform_driver(wcd_gpio_driver);123MODULE_DESCRIPTION("Qualcomm Technologies, Inc WCD GPIO control driver");124MODULE_LICENSE("GPL v2");125