mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.4 KiB
98 lines
2.4 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
// Copyright (C) 2020 ROHM Semiconductors |
|
|
|
#include <linux/errno.h> |
|
#include <linux/mfd/rohm-generic.h> |
|
#include <linux/module.h> |
|
#include <linux/of.h> |
|
#include <linux/regmap.h> |
|
#include <linux/regulator/driver.h> |
|
|
|
static int set_dvs_level(const struct regulator_desc *desc, |
|
struct device_node *np, struct regmap *regmap, |
|
char *prop, unsigned int reg, unsigned int mask, |
|
unsigned int omask, unsigned int oreg) |
|
{ |
|
int ret, i; |
|
uint32_t uv; |
|
|
|
ret = of_property_read_u32(np, prop, &uv); |
|
if (ret) { |
|
if (ret != -EINVAL) |
|
return ret; |
|
return 0; |
|
} |
|
|
|
if (uv == 0) { |
|
if (omask) |
|
return regmap_update_bits(regmap, oreg, omask, 0); |
|
} |
|
for (i = 0; i < desc->n_voltages; i++) { |
|
ret = regulator_desc_list_voltage_linear_range(desc, i); |
|
if (ret < 0) |
|
continue; |
|
if (ret == uv) { |
|
i <<= ffs(desc->vsel_mask) - 1; |
|
ret = regmap_update_bits(regmap, reg, mask, i); |
|
if (omask && !ret) |
|
ret = regmap_update_bits(regmap, oreg, omask, |
|
omask); |
|
break; |
|
} |
|
} |
|
return ret; |
|
} |
|
|
|
int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs, |
|
struct device_node *np, |
|
const struct regulator_desc *desc, |
|
struct regmap *regmap) |
|
{ |
|
int i, ret = 0; |
|
char *prop; |
|
unsigned int reg, mask, omask, oreg = desc->enable_reg; |
|
|
|
for (i = 0; i < ROHM_DVS_LEVEL_VALID_AMOUNT && !ret; i++) { |
|
int bit; |
|
|
|
bit = BIT(i); |
|
if (dvs->level_map & bit) { |
|
switch (bit) { |
|
case ROHM_DVS_LEVEL_RUN: |
|
prop = "rohm,dvs-run-voltage"; |
|
reg = dvs->run_reg; |
|
mask = dvs->run_mask; |
|
omask = dvs->run_on_mask; |
|
break; |
|
case ROHM_DVS_LEVEL_IDLE: |
|
prop = "rohm,dvs-idle-voltage"; |
|
reg = dvs->idle_reg; |
|
mask = dvs->idle_mask; |
|
omask = dvs->idle_on_mask; |
|
break; |
|
case ROHM_DVS_LEVEL_SUSPEND: |
|
prop = "rohm,dvs-suspend-voltage"; |
|
reg = dvs->suspend_reg; |
|
mask = dvs->suspend_mask; |
|
omask = dvs->suspend_on_mask; |
|
break; |
|
case ROHM_DVS_LEVEL_LPSR: |
|
prop = "rohm,dvs-lpsr-voltage"; |
|
reg = dvs->lpsr_reg; |
|
mask = dvs->lpsr_mask; |
|
omask = dvs->lpsr_on_mask; |
|
break; |
|
default: |
|
return -EINVAL; |
|
} |
|
ret = set_dvs_level(desc, np, regmap, prop, reg, mask, |
|
omask, oreg); |
|
} |
|
} |
|
return ret; |
|
} |
|
EXPORT_SYMBOL(rohm_regulator_set_dvs_levels); |
|
|
|
MODULE_LICENSE("GPL v2"); |
|
MODULE_AUTHOR("Matti Vaittinen <[email protected]>"); |
|
MODULE_DESCRIPTION("Generic helpers for ROHM PMIC regulator drivers");
|
|
|