mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
drm/rockchip: ebc: sy7636a: Add support for monitor power fault event
When a power failure occurs, the sy7636a power good(PGOOD) pin will be pulled low and the fault flag will be set. Change-Id: I69c090b61fefeea36a2481395ab02132d2fe565b Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
This commit is contained in:
@@ -16,8 +16,11 @@
|
||||
#define SY7636A_MAX_ENABLE_GPIO_NUM 4
|
||||
|
||||
struct sy7636a_data {
|
||||
struct platform_device *pdev;
|
||||
struct regmap *regmap;
|
||||
struct gpio_descs *enable_gpio;
|
||||
struct gpio_desc *pgood_gpio;
|
||||
int pgood_irq;
|
||||
/*
|
||||
* When registering a new regulator, regulator core will try to
|
||||
* call "set_suspend_disable" to check whether regulator device
|
||||
@@ -28,6 +31,25 @@ struct sy7636a_data {
|
||||
int vcom_uV;
|
||||
};
|
||||
|
||||
static int sy7636a_power_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct sy7636a_data *data = rdev->reg_data;
|
||||
int ret;
|
||||
|
||||
ret = regulator_enable_regmap(rdev);
|
||||
enable_irq(data->pgood_irq);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sy7636a_power_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct sy7636a_data *data = rdev->reg_data;
|
||||
|
||||
disable_irq(data->pgood_irq);
|
||||
return regulator_disable_regmap(rdev);
|
||||
}
|
||||
|
||||
static int sy7636a_get_vcom_voltage_op(struct regulator_dev *rdev)
|
||||
{
|
||||
int ret;
|
||||
@@ -153,8 +175,8 @@ static int sy7636a_resume(struct regulator_dev *rdev)
|
||||
static const struct regulator_ops sy7636a_vcom_volt_ops = {
|
||||
.set_voltage = sy7636a_set_vcom_voltage_op,
|
||||
.get_voltage = sy7636a_get_vcom_voltage_op,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.enable = sy7636a_power_enable,
|
||||
.disable = sy7636a_power_disable,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.get_status = sy7636a_get_status,
|
||||
.set_suspend_disable = sy7636a_set_suspend_disable,
|
||||
@@ -173,6 +195,28 @@ static const struct regulator_desc desc = {
|
||||
.of_match = of_match_ptr("vcom"),
|
||||
};
|
||||
|
||||
static irqreturn_t sy7636a_power_good_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct sy7636a_data *data = dev_id;
|
||||
struct regmap *regmap = data->regmap;
|
||||
struct platform_device *pdev = data->pdev;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, SY7636A_REG_FAULT_FLAG, &val);
|
||||
if (ret) {
|
||||
dev_err(pdev->dev.parent, "sy7636a failed to read fault flag\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(val & SY7636A_FAULT_FLAG_PG) || (val & SY7636A_FAULT_FLAG_FAULT))
|
||||
dev_err(pdev->dev.parent, "sy7636a power fault flag:%d\n",
|
||||
val >> SY7636A_FAULT_FLAG_FAULT_SHIFT);
|
||||
|
||||
out:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int sy7636a_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
@@ -188,6 +232,7 @@ static int sy7636a_regulator_probe(struct platform_device *pdev)
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->pdev = pdev;
|
||||
data->regmap = regmap;
|
||||
data->initial_suspend = true;
|
||||
|
||||
@@ -199,6 +244,26 @@ static int sy7636a_regulator_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(data->enable_gpio);
|
||||
}
|
||||
|
||||
data->pgood_irq = -1;
|
||||
data->pgood_gpio = devm_gpiod_get(pdev->dev.parent, "pgood", GPIOD_IN);
|
||||
if (IS_ERR(data->pgood_gpio)) {
|
||||
dev_warn(pdev->dev.parent, "Failed to get sy7636a pgood gpio %ld\n",
|
||||
PTR_ERR(data->pgood_gpio));
|
||||
} else {
|
||||
data->pgood_irq = gpiod_to_irq(data->pgood_gpio);
|
||||
if (data->pgood_irq < 0) {
|
||||
dev_err(pdev->dev.parent, "Failed to get sy7636a power good int irq\n");
|
||||
} else {
|
||||
ret = devm_request_threaded_irq(pdev->dev.parent, data->pgood_irq, NULL,
|
||||
sy7636a_power_good_irq_handler,
|
||||
IRQF_TRIGGER_FALLING |
|
||||
IRQF_ONESHOT |
|
||||
IRQF_NO_AUTOEN, "sy7636a", data);
|
||||
if (ret)
|
||||
dev_err(pdev->dev.parent, "Failed to request sy7636a irq\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* sy7636a needs 2.5ms to enter active mode after enable */
|
||||
usleep_range(2500, 2600);
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#define SY7636A_REG_VLDO_VOLTAGE_ADJULST_CTRL 0x03
|
||||
#define SY7636A_REG_POWER_ON_DELAY_TIME 0x06
|
||||
#define SY7636A_REG_FAULT_FLAG 0x07
|
||||
#define SY7636A_FAULT_FLAG_FAULT GENMASK(4, 1)
|
||||
#define SY7636A_FAULT_FLAG_FAULT_SHIFT 1
|
||||
#define SY7636A_FAULT_FLAG_PG BIT(0)
|
||||
#define SY7636A_REG_TERMISTOR_READOUT 0x08
|
||||
|
||||
|
||||
Reference in New Issue
Block a user