brintos

brintos / linux-shallow public Read only

0
0
Text · 10.5 KiB · c22fdde Raw
391 lines · c
1// SPDX-License-Identifier: GPL-2.0+2//3// Copyright (c) 2013 Samsung Electronics Co., Ltd4//		http://www.samsung.com5 6#include <linux/bug.h>7#include <linux/err.h>8#include <linux/slab.h>9#include <linux/module.h>10#include <linux/of.h>11#include <linux/regmap.h>12#include <linux/platform_device.h>13#include <linux/regulator/driver.h>14#include <linux/regulator/machine.h>15#include <linux/regulator/of_regulator.h>16#include <linux/mfd/samsung/core.h>17#include <linux/mfd/samsung/s2mpa01.h>18 19struct s2mpa01_info {20	int ramp_delay24;21	int ramp_delay3;22	int ramp_delay5;23	int ramp_delay16;24	int ramp_delay7;25	int ramp_delay8910;26};27 28static int get_ramp_delay(int ramp_delay)29{30	unsigned char cnt = 0;31 32	ramp_delay /= 6250;33 34	while (true) {35		ramp_delay = ramp_delay >> 1;36		if (ramp_delay == 0)37			break;38		cnt++;39	}40 41	if (cnt > 3)42		cnt = 3;43 44	return cnt;45}46 47static int s2mpa01_regulator_set_voltage_time_sel(struct regulator_dev *rdev,48				   unsigned int old_selector,49				   unsigned int new_selector)50{51	struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);52	unsigned int ramp_delay = 0;53	int old_volt, new_volt;54 55	switch (rdev_get_id(rdev)) {56	case S2MPA01_BUCK2:57	case S2MPA01_BUCK4:58		ramp_delay = s2mpa01->ramp_delay24;59		break;60	case S2MPA01_BUCK3:61		ramp_delay = s2mpa01->ramp_delay3;62		break;63	case S2MPA01_BUCK5:64		ramp_delay = s2mpa01->ramp_delay5;65		break;66	case S2MPA01_BUCK1:67	case S2MPA01_BUCK6:68		ramp_delay = s2mpa01->ramp_delay16;69		break;70	case S2MPA01_BUCK7:71		ramp_delay = s2mpa01->ramp_delay7;72		break;73	case S2MPA01_BUCK8:74	case S2MPA01_BUCK9:75	case S2MPA01_BUCK10:76		ramp_delay = s2mpa01->ramp_delay8910;77		break;78	}79 80	if (ramp_delay == 0)81		ramp_delay = rdev->desc->ramp_delay;82 83	old_volt = rdev->desc->min_uV + (rdev->desc->uV_step * old_selector);84	new_volt = rdev->desc->min_uV + (rdev->desc->uV_step * new_selector);85 86	return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay);87}88 89static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)90{91	struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);92	unsigned int ramp_val, ramp_shift, ramp_reg = S2MPA01_REG_RAMP2;93	unsigned int ramp_enable = 1, enable_shift = 0;94	int ret;95 96	switch (rdev_get_id(rdev)) {97	case S2MPA01_BUCK1:98		enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT;99		if (!ramp_delay) {100			ramp_enable = 0;101			break;102		}103 104		if (ramp_delay > s2mpa01->ramp_delay16)105			s2mpa01->ramp_delay16 = ramp_delay;106		else107			ramp_delay = s2mpa01->ramp_delay16;108 109		ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;110		break;111	case S2MPA01_BUCK2:112		enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT;113		if (!ramp_delay) {114			ramp_enable = 0;115			break;116		}117 118		if (ramp_delay > s2mpa01->ramp_delay24)119			s2mpa01->ramp_delay24 = ramp_delay;120		else121			ramp_delay = s2mpa01->ramp_delay24;122 123		ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;124		ramp_reg = S2MPA01_REG_RAMP1;125		break;126	case S2MPA01_BUCK3:127		enable_shift = S2MPA01_BUCK3_RAMP_EN_SHIFT;128		if (!ramp_delay) {129			ramp_enable = 0;130			break;131		}132 133		s2mpa01->ramp_delay3 = ramp_delay;134		ramp_shift = S2MPA01_BUCK3_RAMP_SHIFT;135		ramp_reg = S2MPA01_REG_RAMP1;136		break;137	case S2MPA01_BUCK4:138		enable_shift = S2MPA01_BUCK4_RAMP_EN_SHIFT;139		if (!ramp_delay) {140			ramp_enable = 0;141			break;142		}143 144		if (ramp_delay > s2mpa01->ramp_delay24)145			s2mpa01->ramp_delay24 = ramp_delay;146		else147			ramp_delay = s2mpa01->ramp_delay24;148 149		ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;150		ramp_reg = S2MPA01_REG_RAMP1;151		break;152	case S2MPA01_BUCK5:153		s2mpa01->ramp_delay5 = ramp_delay;154		ramp_shift = S2MPA01_BUCK5_RAMP_SHIFT;155		break;156	case S2MPA01_BUCK6:157		if (ramp_delay > s2mpa01->ramp_delay16)158			s2mpa01->ramp_delay16 = ramp_delay;159		else160			ramp_delay = s2mpa01->ramp_delay16;161 162		ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;163		break;164	case S2MPA01_BUCK7:165		s2mpa01->ramp_delay7 = ramp_delay;166		ramp_shift = S2MPA01_BUCK7_RAMP_SHIFT;167		break;168	case S2MPA01_BUCK8:169	case S2MPA01_BUCK9:170	case S2MPA01_BUCK10:171		if (ramp_delay > s2mpa01->ramp_delay8910)172			s2mpa01->ramp_delay8910 = ramp_delay;173		else174			ramp_delay = s2mpa01->ramp_delay8910;175 176		ramp_shift = S2MPA01_BUCK8910_RAMP_SHIFT;177		break;178	default:179		return 0;180	}181 182	if (!ramp_enable)183		goto ramp_disable;184 185	/* Ramp delay can be enabled/disabled only for buck[1234] */186	if (rdev_get_id(rdev) >= S2MPA01_BUCK1 &&187			rdev_get_id(rdev) <= S2MPA01_BUCK4) {188		ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,189					 1 << enable_shift, 1 << enable_shift);190		if (ret) {191			dev_err(&rdev->dev, "failed to enable ramp rate\n");192			return ret;193		}194	}195 196	ramp_val = get_ramp_delay(ramp_delay);197 198	return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift,199				  ramp_val << ramp_shift);200 201ramp_disable:202	return regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,203				  1 << enable_shift, 0);204}205 206static const struct regulator_ops s2mpa01_ldo_ops = {207	.list_voltage		= regulator_list_voltage_linear,208	.map_voltage		= regulator_map_voltage_linear,209	.is_enabled		= regulator_is_enabled_regmap,210	.enable			= regulator_enable_regmap,211	.disable		= regulator_disable_regmap,212	.get_voltage_sel	= regulator_get_voltage_sel_regmap,213	.set_voltage_sel	= regulator_set_voltage_sel_regmap,214	.set_voltage_time_sel	= regulator_set_voltage_time_sel,215};216 217static const struct regulator_ops s2mpa01_buck_ops = {218	.list_voltage		= regulator_list_voltage_linear,219	.map_voltage		= regulator_map_voltage_linear,220	.is_enabled		= regulator_is_enabled_regmap,221	.enable			= regulator_enable_regmap,222	.disable		= regulator_disable_regmap,223	.get_voltage_sel	= regulator_get_voltage_sel_regmap,224	.set_voltage_sel	= regulator_set_voltage_sel_regmap,225	.set_voltage_time_sel	= s2mpa01_regulator_set_voltage_time_sel,226	.set_ramp_delay		= s2mpa01_set_ramp_delay,227};228 229#define regulator_desc_ldo(num, step) {			\230	.name		= "LDO"#num,			\231	.of_match	= of_match_ptr("LDO"#num),	\232	.regulators_node = of_match_ptr("regulators"),	\233	.id		= S2MPA01_LDO##num,		\234	.ops		= &s2mpa01_ldo_ops,		\235	.type		= REGULATOR_VOLTAGE,		\236	.owner		= THIS_MODULE,			\237	.min_uV		= MIN_800_MV,			\238	.uV_step	= step,				\239	.n_voltages	= S2MPA01_LDO_N_VOLTAGES,	\240	.vsel_reg	= S2MPA01_REG_L1CTRL + num - 1,	\241	.vsel_mask	= S2MPA01_LDO_VSEL_MASK,	\242	.enable_reg	= S2MPA01_REG_L1CTRL + num - 1,	\243	.enable_mask	= S2MPA01_ENABLE_MASK		\244}245 246#define regulator_desc_buck1_4(num)	{			\247	.name		= "BUCK"#num,				\248	.of_match	= of_match_ptr("BUCK"#num),		\249	.regulators_node = of_match_ptr("regulators"),		\250	.id		= S2MPA01_BUCK##num,			\251	.ops		= &s2mpa01_buck_ops,			\252	.type		= REGULATOR_VOLTAGE,			\253	.owner		= THIS_MODULE,				\254	.min_uV		= MIN_600_MV,				\255	.uV_step	= STEP_6_25_MV,				\256	.n_voltages	= S2MPA01_BUCK_N_VOLTAGES,		\257	.ramp_delay	= S2MPA01_RAMP_DELAY,			\258	.vsel_reg	= S2MPA01_REG_B1CTRL2 + (num - 1) * 2,	\259	.vsel_mask	= S2MPA01_BUCK_VSEL_MASK,		\260	.enable_reg	= S2MPA01_REG_B1CTRL1 + (num - 1) * 2,	\261	.enable_mask	= S2MPA01_ENABLE_MASK			\262}263 264#define regulator_desc_buck5	{				\265	.name		= "BUCK5",				\266	.of_match	= of_match_ptr("BUCK5"),		\267	.regulators_node = of_match_ptr("regulators"),		\268	.id		= S2MPA01_BUCK5,			\269	.ops		= &s2mpa01_buck_ops,			\270	.type		= REGULATOR_VOLTAGE,			\271	.owner		= THIS_MODULE,				\272	.min_uV		= MIN_800_MV,				\273	.uV_step	= STEP_6_25_MV,				\274	.n_voltages	= S2MPA01_BUCK_N_VOLTAGES,		\275	.ramp_delay	= S2MPA01_RAMP_DELAY,			\276	.vsel_reg	= S2MPA01_REG_B5CTRL2,			\277	.vsel_mask	= S2MPA01_BUCK_VSEL_MASK,		\278	.enable_reg	= S2MPA01_REG_B5CTRL1,			\279	.enable_mask	= S2MPA01_ENABLE_MASK			\280}281 282#define regulator_desc_buck6_10(num, min, step) {			\283	.name		= "BUCK"#num,				\284	.of_match	= of_match_ptr("BUCK"#num),		\285	.regulators_node = of_match_ptr("regulators"),		\286	.id		= S2MPA01_BUCK##num,			\287	.ops		= &s2mpa01_buck_ops,			\288	.type		= REGULATOR_VOLTAGE,			\289	.owner		= THIS_MODULE,				\290	.min_uV		= min,					\291	.uV_step	= step,					\292	.n_voltages	= S2MPA01_BUCK_N_VOLTAGES,		\293	.ramp_delay	= S2MPA01_RAMP_DELAY,			\294	.vsel_reg	= S2MPA01_REG_B6CTRL2 + (num - 6) * 2,	\295	.vsel_mask	= S2MPA01_BUCK_VSEL_MASK,		\296	.enable_reg	= S2MPA01_REG_B6CTRL1 + (num - 6) * 2,	\297	.enable_mask	= S2MPA01_ENABLE_MASK			\298}299 300static const struct regulator_desc regulators[] = {301	regulator_desc_ldo(1, STEP_25_MV),302	regulator_desc_ldo(2, STEP_50_MV),303	regulator_desc_ldo(3, STEP_50_MV),304	regulator_desc_ldo(4, STEP_50_MV),305	regulator_desc_ldo(5, STEP_25_MV),306	regulator_desc_ldo(6, STEP_25_MV),307	regulator_desc_ldo(7, STEP_50_MV),308	regulator_desc_ldo(8, STEP_50_MV),309	regulator_desc_ldo(9, STEP_50_MV),310	regulator_desc_ldo(10, STEP_50_MV),311	regulator_desc_ldo(11, STEP_50_MV),312	regulator_desc_ldo(12, STEP_50_MV),313	regulator_desc_ldo(13, STEP_50_MV),314	regulator_desc_ldo(14, STEP_50_MV),315	regulator_desc_ldo(15, STEP_50_MV),316	regulator_desc_ldo(16, STEP_50_MV),317	regulator_desc_ldo(17, STEP_50_MV),318	regulator_desc_ldo(18, STEP_50_MV),319	regulator_desc_ldo(19, STEP_50_MV),320	regulator_desc_ldo(20, STEP_50_MV),321	regulator_desc_ldo(21, STEP_50_MV),322	regulator_desc_ldo(22, STEP_50_MV),323	regulator_desc_ldo(23, STEP_50_MV),324	regulator_desc_ldo(24, STEP_50_MV),325	regulator_desc_ldo(25, STEP_50_MV),326	regulator_desc_ldo(26, STEP_25_MV),327	regulator_desc_buck1_4(1),328	regulator_desc_buck1_4(2),329	regulator_desc_buck1_4(3),330	regulator_desc_buck1_4(4),331	regulator_desc_buck5,332	regulator_desc_buck6_10(6, MIN_600_MV, STEP_6_25_MV),333	regulator_desc_buck6_10(7, MIN_600_MV, STEP_6_25_MV),334	regulator_desc_buck6_10(8, MIN_800_MV, STEP_12_5_MV),335	regulator_desc_buck6_10(9, MIN_1500_MV, STEP_12_5_MV),336	regulator_desc_buck6_10(10, MIN_1000_MV, STEP_12_5_MV),337};338 339static int s2mpa01_pmic_probe(struct platform_device *pdev)340{341	struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);342	struct regulator_config config = { };343	struct s2mpa01_info *s2mpa01;344	int i;345 346	s2mpa01 = devm_kzalloc(&pdev->dev, sizeof(*s2mpa01), GFP_KERNEL);347	if (!s2mpa01)348		return -ENOMEM;349 350	config.dev = iodev->dev;351	config.regmap = iodev->regmap_pmic;352	config.driver_data = s2mpa01;353 354	for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) {355		struct regulator_dev *rdev;356 357		rdev = devm_regulator_register(&pdev->dev,358						&regulators[i], &config);359		if (IS_ERR(rdev)) {360			dev_err(&pdev->dev, "regulator init failed for %d\n",361				i);362			return PTR_ERR(rdev);363		}364	}365 366	return 0;367}368 369static const struct platform_device_id s2mpa01_pmic_id[] = {370	{ "s2mpa01-pmic", 0},371	{ },372};373MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id);374 375static struct platform_driver s2mpa01_pmic_driver = {376	.driver = {377		.name = "s2mpa01-pmic",378		.probe_type = PROBE_PREFER_ASYNCHRONOUS,379	},380	.probe = s2mpa01_pmic_probe,381	.id_table = s2mpa01_pmic_id,382};383 384module_platform_driver(s2mpa01_pmic_driver);385 386/* Module information */387MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");388MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>");389MODULE_DESCRIPTION("Samsung S2MPA01 Regulator Driver");390MODULE_LICENSE("GPL");391