0001
0002
0003
0004
0005
0006
0007
0008
0009
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
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 { }
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");