2012-04-04 11:14:00 +04:00
/*
* Regulator driver for RICOH RC5T583 power management chip .
*
* Copyright ( c ) 2011 - 2012 , NVIDIA CORPORATION . All rights reserved .
* Author : Laxman dewangan < ldewangan @ nvidia . com >
*
* based on code
* Copyright ( C ) 2011 RICOH COMPANY , LTD
*
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*
* This program is distributed in the hope it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*
*/
# include <linux/module.h>
# include <linux/init.h>
# include <linux/slab.h>
# include <linux/err.h>
# include <linux/platform_device.h>
# include <linux/regulator/driver.h>
# include <linux/regulator/machine.h>
# include <linux/gpio.h>
# include <linux/mfd/rc5t583.h>
struct rc5t583_regulator_info {
int deepsleep_id ;
/* Regulator register address.*/
uint8_t reg_disc_reg ;
uint8_t disc_bit ;
uint8_t deepsleep_reg ;
/* Regulator specific turn-on delay and voltage settling time*/
int enable_uv_per_us ;
/* Used by regulator core */
struct regulator_desc desc ;
} ;
struct rc5t583_regulator {
struct rc5t583_regulator_info * reg_info ;
struct regulator_dev * rdev ;
} ;
static int rc5t583_regulator_enable_time ( struct regulator_dev * rdev )
{
struct rc5t583_regulator * reg = rdev_get_drvdata ( rdev ) ;
2012-04-24 05:56:43 +04:00
int vsel = regulator_get_voltage_sel_regmap ( rdev ) ;
2012-05-14 06:54:46 +04:00
int curr_uV = regulator_list_voltage_linear ( rdev , vsel ) ;
2012-04-24 05:56:43 +04:00
2012-04-04 11:14:00 +04:00
return DIV_ROUND_UP ( curr_uV , reg - > reg_info - > enable_uv_per_us ) ;
}
2017-01-28 18:18:51 +03:00
static const struct regulator_ops rc5t583_ops = {
2012-04-17 10:11:31 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
2012-04-04 11:14:00 +04:00
. enable_time = rc5t583_regulator_enable_time ,
2012-04-24 05:56:43 +04:00
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
2012-05-14 06:55:50 +04:00
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
2012-05-14 06:54:46 +04:00
. list_voltage = regulator_list_voltage_linear ,
2012-05-14 06:55:50 +04:00
. map_voltage = regulator_map_voltage_linear ,
2012-06-19 05:26:52 +04:00
. set_voltage_time_sel = regulator_set_voltage_time_sel ,
2012-04-04 11:14:00 +04:00
} ;
2012-04-06 04:01:36 +04:00
# define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \
_vout_mask , _min_mv , _max_mv , _step_uV , _enable_mv ) \
2012-04-04 11:14:00 +04:00
{ \
. reg_disc_reg = RC5T583_REG_ # # _disc_reg , \
. disc_bit = _disc_bit , \
2012-04-06 04:01:36 +04:00
. deepsleep_reg = RC5T583_REG_ # # _id # # DAC_DS , \
2012-04-04 11:14:00 +04:00
. enable_uv_per_us = _enable_mv * 1000 , \
. deepsleep_id = RC5T583_DS_ # # _id , \
. desc = { \
. name = " rc5t583-regulator- " # _id , \
. id = RC5T583_REGULATOR_ # # _id , \
2012-04-05 10:04:48 +04:00
. n_voltages = ( _max_mv - _min_mv ) * 1000 / _step_uV + 1 , \
2012-04-04 11:14:00 +04:00
. ops = & rc5t583_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
2012-04-24 05:56:43 +04:00
. vsel_reg = RC5T583_REG_ # # _id # # DAC , \
. vsel_mask = _vout_mask , \
2012-04-17 10:11:31 +04:00
. enable_reg = RC5T583_REG_ # # _en_reg , \
. enable_mask = BIT ( _en_bit ) , \
2012-05-14 06:54:46 +04:00
. min_uV = _min_mv * 1000 , \
. uV_step = _step_uV , \
2012-06-19 05:26:52 +04:00
. ramp_delay = 40 * 1000 , \
2012-04-04 11:14:00 +04:00
} , \
}
static struct rc5t583_regulator_info rc5t583_reg_info [ RC5T583_REGULATOR_MAX ] = {
2012-04-06 04:01:36 +04:00
RC5T583_REG ( DC0 , DC0CTL , 0 , DC0CTL , 1 , 0x7F , 700 , 1500 , 12500 , 4 ) ,
RC5T583_REG ( DC1 , DC1CTL , 0 , DC1CTL , 1 , 0x7F , 700 , 1500 , 12500 , 14 ) ,
RC5T583_REG ( DC2 , DC2CTL , 0 , DC2CTL , 1 , 0x7F , 900 , 2400 , 12500 , 14 ) ,
RC5T583_REG ( DC3 , DC3CTL , 0 , DC3CTL , 1 , 0x7F , 900 , 2400 , 12500 , 14 ) ,
RC5T583_REG ( LDO0 , LDOEN2 , 0 , LDODIS2 , 0 , 0x7F , 900 , 3400 , 25000 , 160 ) ,
RC5T583_REG ( LDO1 , LDOEN2 , 1 , LDODIS2 , 1 , 0x7F , 900 , 3400 , 25000 , 160 ) ,
RC5T583_REG ( LDO2 , LDOEN2 , 2 , LDODIS2 , 2 , 0x7F , 900 , 3400 , 25000 , 160 ) ,
RC5T583_REG ( LDO3 , LDOEN2 , 3 , LDODIS2 , 3 , 0x7F , 900 , 3400 , 25000 , 160 ) ,
RC5T583_REG ( LDO4 , LDOEN2 , 4 , LDODIS2 , 4 , 0x3F , 750 , 1500 , 12500 , 133 ) ,
RC5T583_REG ( LDO5 , LDOEN2 , 5 , LDODIS2 , 5 , 0x7F , 900 , 3400 , 25000 , 267 ) ,
RC5T583_REG ( LDO6 , LDOEN2 , 6 , LDODIS2 , 6 , 0x7F , 900 , 3400 , 25000 , 133 ) ,
RC5T583_REG ( LDO7 , LDOEN2 , 7 , LDODIS2 , 7 , 0x7F , 900 , 3400 , 25000 , 233 ) ,
RC5T583_REG ( LDO8 , LDOEN1 , 0 , LDODIS1 , 0 , 0x7F , 900 , 3400 , 25000 , 233 ) ,
RC5T583_REG ( LDO9 , LDOEN1 , 1 , LDODIS1 , 1 , 0x7F , 900 , 3400 , 25000 , 133 ) ,
2012-04-04 11:14:00 +04:00
} ;
2012-11-19 22:22:22 +04:00
static int rc5t583_regulator_probe ( struct platform_device * pdev )
2012-04-04 11:14:00 +04:00
{
struct rc5t583 * rc5t583 = dev_get_drvdata ( pdev - > dev . parent ) ;
struct rc5t583_platform_data * pdata = dev_get_platdata ( rc5t583 - > dev ) ;
2012-04-04 03:50:22 +04:00
struct regulator_config config = { } ;
2012-04-04 11:14:00 +04:00
struct rc5t583_regulator * reg = NULL ;
struct rc5t583_regulator * regs ;
struct regulator_dev * rdev ;
struct rc5t583_regulator_info * ri ;
int ret ;
int id ;
if ( ! pdata ) {
dev_err ( & pdev - > dev , " No platform data, exiting... \n " ) ;
return - ENODEV ;
}
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
regs = devm_kcalloc ( & pdev - > dev ,
RC5T583_REGULATOR_MAX ,
sizeof ( struct rc5t583_regulator ) ,
GFP_KERNEL ) ;
2014-02-20 12:53:10 +04:00
if ( ! regs )
2012-04-04 11:14:00 +04:00
return - ENOMEM ;
for ( id = 0 ; id < RC5T583_REGULATOR_MAX ; + + id ) {
reg = & regs [ id ] ;
ri = & rc5t583_reg_info [ id ] ;
reg - > reg_info = ri ;
if ( ri - > deepsleep_id = = RC5T583_DS_NONE )
goto skip_ext_pwr_config ;
ret = rc5t583_ext_power_req_config ( rc5t583 - > dev ,
ri - > deepsleep_id ,
pdata - > regulator_ext_pwr_control [ id ] ,
pdata - > regulator_deepsleep_slot [ id ] ) ;
/*
* Configuring external control is not a major issue ,
* just give warning .
*/
if ( ret < 0 )
dev_warn ( & pdev - > dev ,
" Failed to configure ext control %d \n " , id ) ;
skip_ext_pwr_config :
2012-04-04 03:50:22 +04:00
config . dev = & pdev - > dev ;
2014-02-06 10:49:11 +04:00
config . init_data = pdata - > reg_init_data [ id ] ;
2012-04-04 03:50:22 +04:00
config . driver_data = reg ;
2012-04-17 10:11:31 +04:00
config . regmap = rc5t583 - > regmap ;
2012-04-04 03:50:22 +04:00
2013-09-04 10:31:02 +04:00
rdev = devm_regulator_register ( & pdev - > dev , & ri - > desc , & config ) ;
2012-04-04 15:52:35 +04:00
if ( IS_ERR ( rdev ) ) {
2012-04-04 11:14:00 +04:00
dev_err ( & pdev - > dev , " Failed to register regulator %s \n " ,
ri - > desc . name ) ;
2013-09-04 10:31:02 +04:00
return PTR_ERR ( rdev ) ;
2012-04-04 11:14:00 +04:00
}
reg - > rdev = rdev ;
}
platform_set_drvdata ( pdev , regs ) ;
return 0 ;
}
static struct platform_driver rc5t583_regulator_driver = {
. driver = {
. name = " rc5t583-regulator " ,
} ,
. probe = rc5t583_regulator_probe ,
} ;
static int __init rc5t583_regulator_init ( void )
{
return platform_driver_register ( & rc5t583_regulator_driver ) ;
}
subsys_initcall ( rc5t583_regulator_init ) ;
static void __exit rc5t583_regulator_exit ( void )
{
platform_driver_unregister ( & rc5t583_regulator_driver ) ;
}
module_exit ( rc5t583_regulator_exit ) ;
MODULE_AUTHOR ( " Laxman Dewangan <ldewangan@nvidia.com> " ) ;
MODULE_DESCRIPTION ( " RC5T583 regulator driver " ) ;
MODULE_ALIAS ( " platform:rc5t583-regulator " ) ;
2012-04-06 09:28:33 +04:00
MODULE_LICENSE ( " GPL v2 " ) ;