0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/errno.h>
0013 #include <linux/gpio/driver.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regmap.h>
0016 #include <linux/mfd/tps65218.h>
0017
0018 struct tps65218_gpio {
0019 struct tps65218 *tps65218;
0020 struct gpio_chip gpio_chip;
0021 };
0022
0023 static int tps65218_gpio_get(struct gpio_chip *gc, unsigned offset)
0024 {
0025 struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc);
0026 struct tps65218 *tps65218 = tps65218_gpio->tps65218;
0027 unsigned int val;
0028 int ret;
0029
0030 ret = regmap_read(tps65218->regmap, TPS65218_REG_ENABLE2, &val);
0031 if (ret)
0032 return ret;
0033
0034 return !!(val & (TPS65218_ENABLE2_GPIO1 << offset));
0035 }
0036
0037 static void tps65218_gpio_set(struct gpio_chip *gc, unsigned offset,
0038 int value)
0039 {
0040 struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc);
0041 struct tps65218 *tps65218 = tps65218_gpio->tps65218;
0042
0043 if (value)
0044 tps65218_set_bits(tps65218, TPS65218_REG_ENABLE2,
0045 TPS65218_ENABLE2_GPIO1 << offset,
0046 TPS65218_ENABLE2_GPIO1 << offset,
0047 TPS65218_PROTECT_L1);
0048 else
0049 tps65218_clear_bits(tps65218, TPS65218_REG_ENABLE2,
0050 TPS65218_ENABLE2_GPIO1 << offset,
0051 TPS65218_PROTECT_L1);
0052 }
0053
0054 static int tps65218_gpio_output(struct gpio_chip *gc, unsigned offset,
0055 int value)
0056 {
0057
0058 tps65218_gpio_set(gc, offset, value);
0059 return 0;
0060 }
0061
0062 static int tps65218_gpio_input(struct gpio_chip *gc, unsigned offset)
0063 {
0064 return -EPERM;
0065 }
0066
0067 static int tps65218_gpio_request(struct gpio_chip *gc, unsigned offset)
0068 {
0069 struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc);
0070 struct tps65218 *tps65218 = tps65218_gpio->tps65218;
0071 int ret;
0072
0073 if (gpiochip_line_is_open_source(gc, offset)) {
0074 dev_err(gc->parent, "can't work as open source\n");
0075 return -EINVAL;
0076 }
0077
0078 switch (offset) {
0079 case 0:
0080 if (!gpiochip_line_is_open_drain(gc, offset)) {
0081 dev_err(gc->parent, "GPO1 works only as open drain\n");
0082 return -EINVAL;
0083 }
0084
0085
0086 ret = tps65218_clear_bits(tps65218, TPS65218_REG_SEQ7,
0087 TPS65218_SEQ7_GPO1_SEQ_MASK,
0088 TPS65218_PROTECT_L1);
0089 if (ret)
0090 return ret;
0091
0092
0093 ret = tps65218_clear_bits(tps65218, TPS65218_REG_CONFIG1,
0094 TPS65218_CONFIG1_IO1_SEL,
0095 TPS65218_PROTECT_L1);
0096 if (ret)
0097 return ret;
0098
0099 break;
0100 case 1:
0101
0102 ret = tps65218_clear_bits(tps65218, TPS65218_REG_CONFIG1,
0103 TPS65218_CONFIG1_IO1_SEL,
0104 TPS65218_PROTECT_L1);
0105 if (ret)
0106 return ret;
0107
0108 break;
0109
0110 case 2:
0111 if (!gpiochip_line_is_open_drain(gc, offset)) {
0112 dev_err(gc->parent, "GPO3 works only as open drain\n");
0113 return -EINVAL;
0114 }
0115
0116
0117 ret = tps65218_clear_bits(tps65218, TPS65218_REG_SEQ7,
0118 TPS65218_SEQ7_GPO3_SEQ_MASK,
0119 TPS65218_PROTECT_L1);
0120 if (ret)
0121 return ret;
0122
0123
0124 ret = tps65218_clear_bits(tps65218, TPS65218_REG_CONFIG2,
0125 TPS65218_CONFIG2_DC12_RST,
0126 TPS65218_PROTECT_L1);
0127 if (ret)
0128 return ret;
0129
0130 break;
0131 default:
0132 return -EINVAL;
0133 }
0134
0135 return 0;
0136 }
0137
0138 static int tps65218_gpio_set_config(struct gpio_chip *gc, unsigned offset,
0139 unsigned long config)
0140 {
0141 struct tps65218_gpio *tps65218_gpio = gpiochip_get_data(gc);
0142 struct tps65218 *tps65218 = tps65218_gpio->tps65218;
0143 enum pin_config_param param = pinconf_to_config_param(config);
0144
0145 switch (offset) {
0146 case 0:
0147 case 2:
0148
0149 if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN)
0150 return 0;
0151 return -ENOTSUPP;
0152 case 1:
0153
0154 if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN)
0155 return tps65218_clear_bits(tps65218,
0156 TPS65218_REG_CONFIG1,
0157 TPS65218_CONFIG1_GPO2_BUF,
0158 TPS65218_PROTECT_L1);
0159 if (param == PIN_CONFIG_DRIVE_PUSH_PULL)
0160 return tps65218_set_bits(tps65218,
0161 TPS65218_REG_CONFIG1,
0162 TPS65218_CONFIG1_GPO2_BUF,
0163 TPS65218_CONFIG1_GPO2_BUF,
0164 TPS65218_PROTECT_L1);
0165 return -ENOTSUPP;
0166 default:
0167 break;
0168 }
0169 return -ENOTSUPP;
0170 }
0171
0172 static const struct gpio_chip template_chip = {
0173 .label = "gpio-tps65218",
0174 .owner = THIS_MODULE,
0175 .request = tps65218_gpio_request,
0176 .direction_output = tps65218_gpio_output,
0177 .direction_input = tps65218_gpio_input,
0178 .get = tps65218_gpio_get,
0179 .set = tps65218_gpio_set,
0180 .set_config = tps65218_gpio_set_config,
0181 .can_sleep = true,
0182 .ngpio = 3,
0183 .base = -1,
0184 };
0185
0186 static int tps65218_gpio_probe(struct platform_device *pdev)
0187 {
0188 struct tps65218 *tps65218 = dev_get_drvdata(pdev->dev.parent);
0189 struct tps65218_gpio *tps65218_gpio;
0190
0191 tps65218_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65218_gpio),
0192 GFP_KERNEL);
0193 if (!tps65218_gpio)
0194 return -ENOMEM;
0195
0196 tps65218_gpio->tps65218 = tps65218;
0197 tps65218_gpio->gpio_chip = template_chip;
0198 tps65218_gpio->gpio_chip.parent = &pdev->dev;
0199
0200 return devm_gpiochip_add_data(&pdev->dev, &tps65218_gpio->gpio_chip,
0201 tps65218_gpio);
0202 }
0203
0204 static const struct of_device_id tps65218_dt_match[] = {
0205 { .compatible = "ti,tps65218-gpio" },
0206 { }
0207 };
0208 MODULE_DEVICE_TABLE(of, tps65218_dt_match);
0209
0210 static const struct platform_device_id tps65218_gpio_id_table[] = {
0211 { "tps65218-gpio", },
0212 { }
0213 };
0214 MODULE_DEVICE_TABLE(platform, tps65218_gpio_id_table);
0215
0216 static struct platform_driver tps65218_gpio_driver = {
0217 .driver = {
0218 .name = "tps65218-gpio",
0219 .of_match_table = of_match_ptr(tps65218_dt_match)
0220 },
0221 .probe = tps65218_gpio_probe,
0222 .id_table = tps65218_gpio_id_table,
0223 };
0224
0225 module_platform_driver(tps65218_gpio_driver);
0226
0227 MODULE_AUTHOR("Nicolas Saenz Julienne <nicolassaenzj@gmail.com>");
0228 MODULE_DESCRIPTION("GPO interface for TPS65218 PMICs");
0229 MODULE_LICENSE("GPL v2");