Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) // Copyright (C) 2020 ROHM Semiconductors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5) #include <linux/mfd/rohm-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) static int set_dvs_level(const struct regulator_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) 			 struct device_node *np, struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 			 char *prop, unsigned int reg, unsigned int mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) 			 unsigned int omask, unsigned int oreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) 	uint32_t uv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 	ret = of_property_read_u32(np, prop, &uv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 		if (ret != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 	if (uv == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 		if (omask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 			return regmap_update_bits(regmap, oreg, omask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 	for (i = 0; i < desc->n_voltages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 		ret = regulator_desc_list_voltage_linear_range(desc, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 		if (ret == uv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 			i <<= ffs(desc->vsel_mask) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 			ret = regmap_update_bits(regmap, reg, mask, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 			if (omask && !ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 				ret = regmap_update_bits(regmap, oreg, omask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 							 omask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 			  struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 			  const struct regulator_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 			  struct regmap *regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 	int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 	char *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 	unsigned int reg, mask, omask, oreg = desc->enable_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 	for (i = 0; i < ROHM_DVS_LEVEL_VALID_AMOUNT && !ret; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 		int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 		bit = BIT(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 		if (dvs->level_map & bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 			switch (bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 			case ROHM_DVS_LEVEL_RUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 				prop = "rohm,dvs-run-voltage";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 				reg = dvs->run_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 				mask = dvs->run_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 				omask = dvs->run_on_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 			case ROHM_DVS_LEVEL_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 				prop = "rohm,dvs-idle-voltage";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 				reg = dvs->idle_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 				mask = dvs->idle_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 				omask = dvs->idle_on_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 			case ROHM_DVS_LEVEL_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 				prop = "rohm,dvs-suspend-voltage";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 				reg = dvs->suspend_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 				mask = dvs->suspend_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 				omask = dvs->suspend_on_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 			case ROHM_DVS_LEVEL_LPSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 				prop = "rohm,dvs-lpsr-voltage";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 				reg = dvs->lpsr_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 				mask = dvs->lpsr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 				omask = dvs->lpsr_on_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 			ret = set_dvs_level(desc, np, regmap, prop, reg, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 					    omask, oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) EXPORT_SYMBOL(rohm_regulator_set_dvs_levels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) MODULE_DESCRIPTION("Generic helpers for ROHM PMIC regulator drivers");