Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ROHM BD9571MWV-M and BD9574MWF-M GPIO driver
0004  *
0005  * Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com>
0006  *
0007  * Based on the TPS65086 driver
0008  *
0009  * NOTE: Interrupts are not supported yet.
0010  */
0011 
0012 #include <linux/gpio/driver.h>
0013 #include <linux/mfd/rohm-generic.h>
0014 #include <linux/module.h>
0015 #include <linux/platform_device.h>
0016 
0017 #include <linux/mfd/bd9571mwv.h>
0018 
0019 struct bd9571mwv_gpio {
0020     struct regmap *regmap;
0021     struct gpio_chip chip;
0022 };
0023 
0024 static int bd9571mwv_gpio_get_direction(struct gpio_chip *chip,
0025                        unsigned int offset)
0026 {
0027     struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
0028     int ret, val;
0029 
0030     ret = regmap_read(gpio->regmap, BD9571MWV_GPIO_DIR, &val);
0031     if (ret < 0)
0032         return ret;
0033     if (val & BIT(offset))
0034         return GPIO_LINE_DIRECTION_IN;
0035 
0036     return GPIO_LINE_DIRECTION_OUT;
0037 }
0038 
0039 static int bd9571mwv_gpio_direction_input(struct gpio_chip *chip,
0040                      unsigned int offset)
0041 {
0042     struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
0043 
0044     regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_DIR, BIT(offset), 0);
0045 
0046     return 0;
0047 }
0048 
0049 static int bd9571mwv_gpio_direction_output(struct gpio_chip *chip,
0050                       unsigned int offset, int value)
0051 {
0052     struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
0053 
0054     /* Set the initial value */
0055     regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_OUT,
0056                BIT(offset), value ? BIT(offset) : 0);
0057     regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_DIR,
0058                BIT(offset), BIT(offset));
0059 
0060     return 0;
0061 }
0062 
0063 static int bd9571mwv_gpio_get(struct gpio_chip *chip, unsigned int offset)
0064 {
0065     struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
0066     int ret, val;
0067 
0068     ret = regmap_read(gpio->regmap, BD9571MWV_GPIO_IN, &val);
0069     if (ret < 0)
0070         return ret;
0071 
0072     return val & BIT(offset);
0073 }
0074 
0075 static void bd9571mwv_gpio_set(struct gpio_chip *chip, unsigned int offset,
0076                   int value)
0077 {
0078     struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip);
0079 
0080     regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_OUT,
0081                BIT(offset), value ? BIT(offset) : 0);
0082 }
0083 
0084 static const struct gpio_chip template_chip = {
0085     .label          = "bd9571mwv-gpio",
0086     .owner          = THIS_MODULE,
0087     .get_direction      = bd9571mwv_gpio_get_direction,
0088     .direction_input    = bd9571mwv_gpio_direction_input,
0089     .direction_output   = bd9571mwv_gpio_direction_output,
0090     .get            = bd9571mwv_gpio_get,
0091     .set            = bd9571mwv_gpio_set,
0092     .base           = -1,
0093     .ngpio          = 2,
0094     .can_sleep      = true,
0095 };
0096 
0097 static int bd9571mwv_gpio_probe(struct platform_device *pdev)
0098 {
0099     struct bd9571mwv_gpio *gpio;
0100 
0101     gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
0102     if (!gpio)
0103         return -ENOMEM;
0104 
0105     gpio->regmap = dev_get_regmap(pdev->dev.parent, NULL);
0106     gpio->chip = template_chip;
0107     gpio->chip.parent = pdev->dev.parent;
0108 
0109     return devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
0110 }
0111 
0112 static const struct platform_device_id bd9571mwv_gpio_id_table[] = {
0113     { "bd9571mwv-gpio", ROHM_CHIP_TYPE_BD9571 },
0114     { "bd9574mwf-gpio", ROHM_CHIP_TYPE_BD9574 },
0115     { /* sentinel */ }
0116 };
0117 MODULE_DEVICE_TABLE(platform, bd9571mwv_gpio_id_table);
0118 
0119 static struct platform_driver bd9571mwv_gpio_driver = {
0120     .driver = {
0121         .name = "bd9571mwv-gpio",
0122     },
0123     .probe = bd9571mwv_gpio_probe,
0124     .id_table = bd9571mwv_gpio_id_table,
0125 };
0126 module_platform_driver(bd9571mwv_gpio_driver);
0127 
0128 MODULE_AUTHOR("Marek Vasut <marek.vasut+renesas@gmail.com>");
0129 MODULE_DESCRIPTION("BD9571MWV GPIO driver");
0130 MODULE_LICENSE("GPL v2");