1c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/*
2c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * helpers.c  --  Voltage/Current Regulator framework helper functions.
3c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
4c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Copyright 2007, 2008 Wolfson Microelectronics PLC.
5c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Copyright 2008 SlimLogic Ltd.
6c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
7c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *  This program is free software; you can redistribute  it and/or modify it
8c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *  under  the terms of  the GNU General  Public License as published by the
9c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *  Free Software Foundation;  either version 2 of the  License, or (at your
10c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *  option) any later version.
11c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
12c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
13c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
14c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/kernel.h>
15c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/err.h>
16c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/delay.h>
17c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/regmap.h>
18c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/regulator/consumer.h>
19c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/regulator/driver.h>
20c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/module.h>
21c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
22c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
23c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_is_enabled_regmap - standard is_enabled() for regmap users
24c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
25c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on
26c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
27c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the
28c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * enable_reg and enable_mask fields in their descriptor and then use
29c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * this as their is_enabled operation, saving some code.
30c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
31c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_is_enabled_regmap(struct regulator_dev *rdev)
32c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
33c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	unsigned int val;
34c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int ret;
35c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
36c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
37c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (ret != 0)
38c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return ret;
39c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
40ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	val &= rdev->desc->enable_mask;
41ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione
42ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	if (rdev->desc->enable_is_inverted) {
43ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		if (rdev->desc->enable_val)
44ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione			return val != rdev->desc->enable_val;
45ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		return val == 0;
46ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	} else {
47ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		if (rdev->desc->enable_val)
48ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione			return val == rdev->desc->enable_val;
49ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		return val != 0;
50ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	}
51c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
52c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
53c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
54c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
55c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_enable_regmap - standard enable() for regmap users
56c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
57c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on
58c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
59c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the
60c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * enable_reg and enable_mask fields in their descriptor and then use
61c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * this as their enable() operation, saving some code.
62c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
63c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_enable_regmap(struct regulator_dev *rdev)
64c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
65c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	unsigned int val;
66c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
67ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	if (rdev->desc->enable_is_inverted) {
68ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		val = rdev->desc->disable_val;
69ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	} else {
70ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		val = rdev->desc->enable_val;
71ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		if (!val)
72ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione			val = rdev->desc->enable_mask;
73ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	}
74c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
75c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
76c4a54b8d54218a75b94ab9947449e688869df00dMark Brown				  rdev->desc->enable_mask, val);
77c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
78c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_enable_regmap);
79c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
80c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
81c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_disable_regmap - standard disable() for regmap users
82c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
83c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on
84c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
85c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the
86c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * enable_reg and enable_mask fields in their descriptor and then use
87c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * this as their disable() operation, saving some code.
88c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
89c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_disable_regmap(struct regulator_dev *rdev)
90c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
91c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	unsigned int val;
92c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
93ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	if (rdev->desc->enable_is_inverted) {
94ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		val = rdev->desc->enable_val;
95ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		if (!val)
96ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione			val = rdev->desc->enable_mask;
97ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	} else {
98ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		val = rdev->desc->disable_val;
99ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	}
100c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
101c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
102c4a54b8d54218a75b94ab9947449e688869df00dMark Brown				  rdev->desc->enable_mask, val);
103c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
104c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_disable_regmap);
105c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
106c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
107c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
108c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
109c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on
110c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
111c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the
112c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * vsel_reg and vsel_mask fields in their descriptor and then use this
113c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * as their get_voltage_vsel operation, saving some code.
114c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
115c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
116c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
117c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	unsigned int val;
118c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int ret;
119c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
120c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
121c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (ret != 0)
122c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return ret;
123c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
124c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	val &= rdev->desc->vsel_mask;
125c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	val >>= ffs(rdev->desc->vsel_mask) - 1;
126c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
127c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	return val;
128c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
129c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
130c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
131c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
132c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
133c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
134c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on
135c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @sel: Selector to set
136c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
137c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the
138c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * vsel_reg and vsel_mask fields in their descriptor and then use this
139c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * as their set_voltage_vsel operation, saving some code.
140c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
141c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
142c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
143c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int ret;
144c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
145c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	sel <<= ffs(rdev->desc->vsel_mask) - 1;
146c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
147c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
148c4a54b8d54218a75b94ab9947449e688869df00dMark Brown				  rdev->desc->vsel_mask, sel);
149c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (ret)
150c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return ret;
151c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
152c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (rdev->desc->apply_bit)
153c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
154c4a54b8d54218a75b94ab9947449e688869df00dMark Brown					 rdev->desc->apply_bit,
155c4a54b8d54218a75b94ab9947449e688869df00dMark Brown					 rdev->desc->apply_bit);
156c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	return ret;
157c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
158c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
159c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
160c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
161c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_map_voltage_iterate - map_voltage() based on list_voltage()
162c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
163c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: Regulator to operate on
164c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @min_uV: Lower bound for voltage
165c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @max_uV: Upper bound for voltage
166c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
167c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Drivers implementing set_voltage_sel() and list_voltage() can use
168c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * this as their map_voltage() operation.  It will find a suitable
169c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * voltage by calling list_voltage() until it gets something in bounds
170c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * for the requested voltages.
171c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
172c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_map_voltage_iterate(struct regulator_dev *rdev,
173c4a54b8d54218a75b94ab9947449e688869df00dMark Brown				  int min_uV, int max_uV)
174c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
175c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int best_val = INT_MAX;
176c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int selector = 0;
177c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int i, ret;
178c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
179c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	/* Find the smallest voltage that falls within the specified
180c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	 * range.
181c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	 */
182c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	for (i = 0; i < rdev->desc->n_voltages; i++) {
183c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		ret = rdev->desc->ops->list_voltage(rdev, i);
184c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		if (ret < 0)
185c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			continue;
186c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
187c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		if (ret < best_val && ret >= min_uV && ret <= max_uV) {
188c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			best_val = ret;
189c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			selector = i;
190c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		}
191c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	}
192c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
193c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (best_val != INT_MAX)
194c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return selector;
195c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	else
196c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return -EINVAL;
197c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
198c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);
199c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
200c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
201c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
202c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
203c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: Regulator to operate on
204c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @min_uV: Lower bound for voltage
205c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @max_uV: Upper bound for voltage
206c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
207c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Drivers that have ascendant voltage list can use this as their
208c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * map_voltage() operation.
209c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
210c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_map_voltage_ascend(struct regulator_dev *rdev,
211c4a54b8d54218a75b94ab9947449e688869df00dMark Brown				 int min_uV, int max_uV)
212c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
213c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int i, ret;
214c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
215c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	for (i = 0; i < rdev->desc->n_voltages; i++) {
216c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		ret = rdev->desc->ops->list_voltage(rdev, i);
217c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		if (ret < 0)
218c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			continue;
219c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
220c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		if (ret > max_uV)
221c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			break;
222c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
223c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		if (ret >= min_uV && ret <= max_uV)
224c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			return i;
225c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	}
226c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
227c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	return -EINVAL;
228c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
229c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_map_voltage_ascend);
230c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
231c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
232c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_map_voltage_linear - map_voltage() for simple linear mappings
233c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
234c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: Regulator to operate on
235c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @min_uV: Lower bound for voltage
236c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @max_uV: Upper bound for voltage
237c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
238c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Drivers providing min_uV and uV_step in their regulator_desc can
239c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * use this as their map_voltage() operation.
240c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
241c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_map_voltage_linear(struct regulator_dev *rdev,
242c4a54b8d54218a75b94ab9947449e688869df00dMark Brown				 int min_uV, int max_uV)
243c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
244c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int ret, voltage;
245c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
246c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	/* Allow uV_step to be 0 for fixed voltage */
247c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) {
248c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV)
249c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			return 0;
250c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		else
251c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			return -EINVAL;
252c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	}
253c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
254c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (!rdev->desc->uV_step) {
255c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		BUG_ON(!rdev->desc->uV_step);
256c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return -EINVAL;
257c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	}
258c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
259c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (min_uV < rdev->desc->min_uV)
260c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		min_uV = rdev->desc->min_uV;
261c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
262c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
263c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (ret < 0)
264c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return ret;
265c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
266c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	ret += rdev->desc->linear_min_sel;
267c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
268c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	/* Map back into a voltage to verify we're still in bounds */
269c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	voltage = rdev->desc->ops->list_voltage(rdev, ret);
270c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (voltage < min_uV || voltage > max_uV)
271c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return -EINVAL;
272c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
273c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	return ret;
274c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
275c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
276c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
277c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
278c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_map_voltage_linear - map_voltage() for multiple linear ranges
279c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
280c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: Regulator to operate on
281c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @min_uV: Lower bound for voltage
282c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @max_uV: Upper bound for voltage
283c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
284c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Drivers providing linear_ranges in their descriptor can use this as
285c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * their map_voltage() callback.
286c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
287c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_map_voltage_linear_range(struct regulator_dev *rdev,
288c4a54b8d54218a75b94ab9947449e688869df00dMark Brown				       int min_uV, int max_uV)
289c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
290c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	const struct regulator_linear_range *range;
291c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int ret = -EINVAL;
292c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int voltage, i;
293c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
294c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (!rdev->desc->n_linear_ranges) {
295c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		BUG_ON(!rdev->desc->n_linear_ranges);
296c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return -EINVAL;
297c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	}
298c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
299c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
300e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin		int linear_max_uV;
301e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin
302c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		range = &rdev->desc->linear_ranges[i];
303e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin		linear_max_uV = range->min_uV +
304e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin			(range->max_sel - range->min_sel) * range->uV_step;
305c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
306e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin		if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV))
307c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			continue;
308c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
309c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		if (min_uV <= range->min_uV)
310c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			min_uV = range->min_uV;
311c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
312c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		/* range->uV_step == 0 means fixed voltage range */
313c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		if (range->uV_step == 0) {
314c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			ret = 0;
315c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		} else {
316c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			ret = DIV_ROUND_UP(min_uV - range->min_uV,
317c4a54b8d54218a75b94ab9947449e688869df00dMark Brown					   range->uV_step);
318c4a54b8d54218a75b94ab9947449e688869df00dMark Brown			if (ret < 0)
319c4a54b8d54218a75b94ab9947449e688869df00dMark Brown				return ret;
320c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		}
321c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
322c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		ret += range->min_sel;
323c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
324c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		break;
325c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	}
326c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
327c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (i == rdev->desc->n_linear_ranges)
328c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return -EINVAL;
329c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
330c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	/* Map back into a voltage to verify we're still in bounds */
331c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	voltage = rdev->desc->ops->list_voltage(rdev, ret);
332c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (voltage < min_uV || voltage > max_uV)
333c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return -EINVAL;
334c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
335c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	return ret;
336c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
337c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
338c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
339c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
340d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * regulator_list_voltage_linear - List voltages with simple calculation
341d295f7670127eb241d81e96e003b380c77c2b254Axel Lin *
342d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @rdev: Regulator device
343d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @selector: Selector to convert into a voltage
344d295f7670127eb241d81e96e003b380c77c2b254Axel Lin *
345d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * Regulators with a simple linear mapping between voltages and
346d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * selectors can set min_uV and uV_step in the regulator descriptor
347d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * and then use this function as their list_voltage() operation,
348d295f7670127eb241d81e96e003b380c77c2b254Axel Lin */
349d295f7670127eb241d81e96e003b380c77c2b254Axel Linint regulator_list_voltage_linear(struct regulator_dev *rdev,
350d295f7670127eb241d81e96e003b380c77c2b254Axel Lin				  unsigned int selector)
351d295f7670127eb241d81e96e003b380c77c2b254Axel Lin{
352d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	if (selector >= rdev->desc->n_voltages)
353d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		return -EINVAL;
354d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	if (selector < rdev->desc->linear_min_sel)
355d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		return 0;
356d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
357d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	selector -= rdev->desc->linear_min_sel;
358d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
359d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
360d295f7670127eb241d81e96e003b380c77c2b254Axel Lin}
361d295f7670127eb241d81e96e003b380c77c2b254Axel LinEXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
362d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
363d295f7670127eb241d81e96e003b380c77c2b254Axel Lin/**
364d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * regulator_list_voltage_linear_range - List voltages for linear ranges
365d295f7670127eb241d81e96e003b380c77c2b254Axel Lin *
366d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @rdev: Regulator device
367d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @selector: Selector to convert into a voltage
368d295f7670127eb241d81e96e003b380c77c2b254Axel Lin *
369d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * Regulators with a series of simple linear mappings between voltages
370d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * and selectors can set linear_ranges in the regulator descriptor and
371d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * then use this function as their list_voltage() operation,
372d295f7670127eb241d81e96e003b380c77c2b254Axel Lin */
373d295f7670127eb241d81e96e003b380c77c2b254Axel Linint regulator_list_voltage_linear_range(struct regulator_dev *rdev,
374d295f7670127eb241d81e96e003b380c77c2b254Axel Lin					unsigned int selector)
375d295f7670127eb241d81e96e003b380c77c2b254Axel Lin{
376d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	const struct regulator_linear_range *range;
377d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	int i;
378d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
379d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	if (!rdev->desc->n_linear_ranges) {
380d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		BUG_ON(!rdev->desc->n_linear_ranges);
381d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		return -EINVAL;
382d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	}
383d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
384d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
385d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		range = &rdev->desc->linear_ranges[i];
386d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
387d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		if (!(selector >= range->min_sel &&
388d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		      selector <= range->max_sel))
389d295f7670127eb241d81e96e003b380c77c2b254Axel Lin			continue;
390d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
391d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		selector -= range->min_sel;
392d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
393d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		return range->min_uV + (range->uV_step * selector);
394d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	}
395d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
396d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	return -EINVAL;
397d295f7670127eb241d81e96e003b380c77c2b254Axel Lin}
398d295f7670127eb241d81e96e003b380c77c2b254Axel LinEXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
399d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
400d295f7670127eb241d81e96e003b380c77c2b254Axel Lin/**
401d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * regulator_list_voltage_table - List voltages with table based mapping
402d295f7670127eb241d81e96e003b380c77c2b254Axel Lin *
403d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @rdev: Regulator device
404d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @selector: Selector to convert into a voltage
405d295f7670127eb241d81e96e003b380c77c2b254Axel Lin *
406d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * Regulators with table based mapping between voltages and
407d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * selectors can set volt_table in the regulator descriptor
408d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * and then use this function as their list_voltage() operation.
409d295f7670127eb241d81e96e003b380c77c2b254Axel Lin */
410d295f7670127eb241d81e96e003b380c77c2b254Axel Linint regulator_list_voltage_table(struct regulator_dev *rdev,
411d295f7670127eb241d81e96e003b380c77c2b254Axel Lin				 unsigned int selector)
412d295f7670127eb241d81e96e003b380c77c2b254Axel Lin{
413d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	if (!rdev->desc->volt_table) {
414d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		BUG_ON(!rdev->desc->volt_table);
415d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		return -EINVAL;
416d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	}
417d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
418d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	if (selector >= rdev->desc->n_voltages)
419d295f7670127eb241d81e96e003b380c77c2b254Axel Lin		return -EINVAL;
420d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
421d295f7670127eb241d81e96e003b380c77c2b254Axel Lin	return rdev->desc->volt_table[selector];
422d295f7670127eb241d81e96e003b380c77c2b254Axel Lin}
423d295f7670127eb241d81e96e003b380c77c2b254Axel LinEXPORT_SYMBOL_GPL(regulator_list_voltage_table);
424d295f7670127eb241d81e96e003b380c77c2b254Axel Lin
425d295f7670127eb241d81e96e003b380c77c2b254Axel Lin/**
426c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_set_bypass_regmap - Default set_bypass() using regmap
427c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
428c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: device to operate on.
429c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @enable: state to set.
430c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
431c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
432c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
433c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	unsigned int val;
434c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
435ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	if (enable) {
436ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		val = rdev->desc->bypass_val_on;
437ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		if (!val)
438ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione			val = rdev->desc->bypass_mask;
439ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	} else {
440ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione		val = rdev->desc->bypass_val_off;
441ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione	}
442c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
443c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
444c4a54b8d54218a75b94ab9947449e688869df00dMark Brown				  rdev->desc->bypass_mask, val);
445c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
446c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
447c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
448c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/**
449c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_get_bypass_regmap - Default get_bypass() using regmap
450c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *
451c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: device to operate on.
452c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @enable: current state.
453c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */
454c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
455c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{
456c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	unsigned int val;
457c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	int ret;
458c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
459c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
460c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	if (ret != 0)
461c4a54b8d54218a75b94ab9947449e688869df00dMark Brown		return ret;
462c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
463c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	*enable = val & rdev->desc->bypass_mask;
464c4a54b8d54218a75b94ab9947449e688869df00dMark Brown
465c4a54b8d54218a75b94ab9947449e688869df00dMark Brown	return 0;
466c4a54b8d54218a75b94ab9947449e688869df00dMark Brown}
467c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
468