0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/gpio/consumer.h>
0011 #include <linux/i2c.h>
0012 #include <linux/mfd/sy7636a.h>
0013 #include <linux/module.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regulator/driver.h>
0016 #include <linux/regulator/machine.h>
0017 #include <linux/regmap.h>
0018
0019 struct sy7636a_data {
0020 struct regmap *regmap;
0021 struct gpio_desc *pgood_gpio;
0022 };
0023
0024 static int sy7636a_get_vcom_voltage_op(struct regulator_dev *rdev)
0025 {
0026 int ret;
0027 unsigned int val, val_h;
0028
0029 ret = regmap_read(rdev->regmap, SY7636A_REG_VCOM_ADJUST_CTRL_L, &val);
0030 if (ret)
0031 return ret;
0032
0033 ret = regmap_read(rdev->regmap, SY7636A_REG_VCOM_ADJUST_CTRL_H, &val_h);
0034 if (ret)
0035 return ret;
0036
0037 val |= (val_h << VCOM_ADJUST_CTRL_SHIFT);
0038
0039 return (val & VCOM_ADJUST_CTRL_MASK) * VCOM_ADJUST_CTRL_SCAL;
0040 }
0041
0042 static int sy7636a_get_status(struct regulator_dev *rdev)
0043 {
0044 struct sy7636a_data *data = dev_get_drvdata(rdev->dev.parent);
0045 int ret = 0;
0046
0047 ret = gpiod_get_value_cansleep(data->pgood_gpio);
0048 if (ret < 0)
0049 dev_err(&rdev->dev, "Failed to read pgood gpio: %d\n", ret);
0050
0051 return ret;
0052 }
0053
0054 static const struct regulator_ops sy7636a_vcom_volt_ops = {
0055 .get_voltage = sy7636a_get_vcom_voltage_op,
0056 .enable = regulator_enable_regmap,
0057 .disable = regulator_disable_regmap,
0058 .is_enabled = regulator_is_enabled_regmap,
0059 .get_status = sy7636a_get_status,
0060 };
0061
0062 static const struct regulator_desc desc = {
0063 .name = "vcom",
0064 .id = 0,
0065 .ops = &sy7636a_vcom_volt_ops,
0066 .type = REGULATOR_VOLTAGE,
0067 .owner = THIS_MODULE,
0068 .enable_reg = SY7636A_REG_OPERATION_MODE_CRL,
0069 .enable_mask = SY7636A_OPERATION_MODE_CRL_ONOFF,
0070 .regulators_node = of_match_ptr("regulators"),
0071 .of_match = of_match_ptr("vcom"),
0072 };
0073
0074 static int sy7636a_regulator_probe(struct platform_device *pdev)
0075 {
0076 struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
0077 struct regulator_config config = { };
0078 struct regulator_dev *rdev;
0079 struct gpio_desc *gdp;
0080 struct sy7636a_data *data;
0081 int ret;
0082
0083 if (!regmap)
0084 return -EPROBE_DEFER;
0085
0086 gdp = devm_gpiod_get(pdev->dev.parent, "epd-pwr-good", GPIOD_IN);
0087 if (IS_ERR(gdp)) {
0088 dev_err(pdev->dev.parent, "Power good GPIO fault %ld\n", PTR_ERR(gdp));
0089 return PTR_ERR(gdp);
0090 }
0091
0092 data = devm_kzalloc(&pdev->dev, sizeof(struct sy7636a_data), GFP_KERNEL);
0093 if (!data)
0094 return -ENOMEM;
0095
0096 data->regmap = regmap;
0097 data->pgood_gpio = gdp;
0098
0099 platform_set_drvdata(pdev, data);
0100
0101 ret = regmap_write(regmap, SY7636A_REG_POWER_ON_DELAY_TIME, 0x0);
0102 if (ret) {
0103 dev_err(pdev->dev.parent, "Failed to initialize regulator: %d\n", ret);
0104 return ret;
0105 }
0106
0107 config.dev = &pdev->dev;
0108 config.dev->of_node = pdev->dev.parent->of_node;
0109 config.regmap = regmap;
0110
0111 rdev = devm_regulator_register(&pdev->dev, &desc, &config);
0112 if (IS_ERR(rdev)) {
0113 dev_err(pdev->dev.parent, "Failed to register %s regulator\n",
0114 pdev->name);
0115 return PTR_ERR(rdev);
0116 }
0117
0118 return 0;
0119 }
0120
0121 static const struct platform_device_id sy7636a_regulator_id_table[] = {
0122 { "sy7636a-regulator", },
0123 { }
0124 };
0125 MODULE_DEVICE_TABLE(platform, sy7636a_regulator_id_table);
0126
0127 static struct platform_driver sy7636a_regulator_driver = {
0128 .driver = {
0129 .name = "sy7636a-regulator",
0130 },
0131 .probe = sy7636a_regulator_probe,
0132 .id_table = sy7636a_regulator_id_table,
0133 };
0134 module_platform_driver(sy7636a_regulator_driver);
0135
0136 MODULE_AUTHOR("Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com>");
0137 MODULE_DESCRIPTION("SY7636A voltage regulator driver");
0138 MODULE_LICENSE("GPL v2");