2018-08-07 19:18:26 +03:00
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (c) 2012-2014 Samsung Electronics Co., Ltd
// http://www.samsung.com
2012-07-11 16:08:17 +04:00
# include <linux/bug.h>
# include <linux/err.h>
2018-11-15 11:01:17 +03:00
# include <linux/gpio/consumer.h>
2012-07-11 16:08:17 +04:00
# include <linux/slab.h>
# include <linux/module.h>
2013-06-29 16:51:17 +04:00
# include <linux/of.h>
2013-06-29 16:51:16 +04:00
# include <linux/regmap.h>
2012-07-11 16:08:17 +04:00
# include <linux/platform_device.h>
# include <linux/regulator/driver.h>
# include <linux/regulator/machine.h>
2013-06-29 16:51:17 +04:00
# include <linux/regulator/of_regulator.h>
2012-07-11 16:08:17 +04:00
# include <linux/mfd/samsung/core.h>
# include <linux/mfd/samsung/s2mps11.h>
2014-11-18 11:59:40 +03:00
# include <linux/mfd/samsung/s2mps13.h>
2014-03-07 14:10:50 +04:00
# include <linux/mfd/samsung/s2mps14.h>
2015-11-20 13:37:52 +03:00
# include <linux/mfd/samsung/s2mps15.h>
2014-06-25 11:14:45 +04:00
# include <linux/mfd/samsung/s2mpu02.h>
2013-06-29 16:51:17 +04:00
2015-06-24 13:48:43 +03:00
/* The highest number of possible regulators for supported devices. */
# define S2MPS_REGULATOR_MAX S2MPS13_REGULATOR_MAX
2012-07-11 16:08:17 +04:00
struct s2mps11_info {
int ramp_delay2 ;
int ramp_delay34 ;
int ramp_delay5 ;
int ramp_delay16 ;
int ramp_delay7810 ;
int ramp_delay9 ;
2014-06-25 11:14:45 +04:00
enum sec_device_type dev_type ;
2014-03-07 14:10:51 +04:00
/*
2014-11-18 11:59:40 +03:00
* One bit for each S2MPS13 / S2MPS14 / S2MPU02 regulator whether
* the suspend mode was enabled .
2014-03-07 14:10:51 +04:00
*/
2015-06-24 13:48:43 +03:00
DECLARE_BITMAP ( suspend_state , S2MPS_REGULATOR_MAX ) ;
2014-06-25 11:14:45 +04:00
2016-02-18 08:57:03 +03:00
/*
* Array ( size : number of regulators ) with GPIO - s for external
* sleep control .
*/
2018-11-15 11:01:17 +03:00
struct gpio_desc * * ext_control_gpiod ;
2012-07-11 16:08:17 +04:00
} ;
static int get_ramp_delay ( int ramp_delay )
{
unsigned char cnt = 0 ;
2013-06-24 15:20:55 +04:00
ramp_delay / = 6250 ;
2012-07-11 16:08:17 +04:00
while ( true ) {
ramp_delay = ramp_delay > > 1 ;
if ( ramp_delay = = 0 )
break ;
cnt + + ;
}
2013-08-05 10:08:37 +04:00
if ( cnt > 3 )
cnt = 3 ;
2012-07-11 16:08:17 +04:00
return cnt ;
}
2013-06-24 15:20:56 +04:00
static int s2mps11_regulator_set_voltage_time_sel ( struct regulator_dev * rdev ,
unsigned int old_selector ,
unsigned int new_selector )
{
struct s2mps11_info * s2mps11 = rdev_get_drvdata ( rdev ) ;
unsigned int ramp_delay = 0 ;
int old_volt , new_volt ;
2014-01-27 03:57:12 +04:00
switch ( rdev_get_id ( rdev ) ) {
2013-06-24 15:20:56 +04:00
case S2MPS11_BUCK2 :
ramp_delay = s2mps11 - > ramp_delay2 ;
break ;
case S2MPS11_BUCK3 :
case S2MPS11_BUCK4 :
ramp_delay = s2mps11 - > ramp_delay34 ;
break ;
case S2MPS11_BUCK5 :
ramp_delay = s2mps11 - > ramp_delay5 ;
break ;
case S2MPS11_BUCK6 :
case S2MPS11_BUCK1 :
ramp_delay = s2mps11 - > ramp_delay16 ;
break ;
case S2MPS11_BUCK7 :
case S2MPS11_BUCK8 :
case S2MPS11_BUCK10 :
ramp_delay = s2mps11 - > ramp_delay7810 ;
break ;
case S2MPS11_BUCK9 :
ramp_delay = s2mps11 - > ramp_delay9 ;
}
if ( ramp_delay = = 0 )
ramp_delay = rdev - > desc - > ramp_delay ;
old_volt = rdev - > desc - > min_uV + ( rdev - > desc - > uV_step * old_selector ) ;
new_volt = rdev - > desc - > min_uV + ( rdev - > desc - > uV_step * new_selector ) ;
return DIV_ROUND_UP ( abs ( new_volt - old_volt ) , ramp_delay ) ;
}
2013-06-29 16:51:16 +04:00
static int s2mps11_set_ramp_delay ( struct regulator_dev * rdev , int ramp_delay )
{
struct s2mps11_info * s2mps11 = rdev_get_drvdata ( rdev ) ;
unsigned int ramp_val , ramp_shift , ramp_reg = S2MPS11_REG_RAMP_BUCK ;
unsigned int ramp_enable = 1 , enable_shift = 0 ;
int ret ;
2014-01-27 03:57:12 +04:00
switch ( rdev_get_id ( rdev ) ) {
2013-06-29 16:51:16 +04:00
case S2MPS11_BUCK1 :
if ( ramp_delay > s2mps11 - > ramp_delay16 )
s2mps11 - > ramp_delay16 = ramp_delay ;
else
ramp_delay = s2mps11 - > ramp_delay16 ;
ramp_shift = S2MPS11_BUCK16_RAMP_SHIFT ;
break ;
case S2MPS11_BUCK2 :
enable_shift = S2MPS11_BUCK2_RAMP_EN_SHIFT ;
if ( ! ramp_delay ) {
ramp_enable = 0 ;
break ;
}
s2mps11 - > ramp_delay2 = ramp_delay ;
ramp_shift = S2MPS11_BUCK2_RAMP_SHIFT ;
ramp_reg = S2MPS11_REG_RAMP ;
break ;
case S2MPS11_BUCK3 :
enable_shift = S2MPS11_BUCK3_RAMP_EN_SHIFT ;
if ( ! ramp_delay ) {
ramp_enable = 0 ;
break ;
}
if ( ramp_delay > s2mps11 - > ramp_delay34 )
s2mps11 - > ramp_delay34 = ramp_delay ;
else
ramp_delay = s2mps11 - > ramp_delay34 ;
ramp_shift = S2MPS11_BUCK34_RAMP_SHIFT ;
ramp_reg = S2MPS11_REG_RAMP ;
break ;
case S2MPS11_BUCK4 :
enable_shift = S2MPS11_BUCK4_RAMP_EN_SHIFT ;
if ( ! ramp_delay ) {
ramp_enable = 0 ;
break ;
}
if ( ramp_delay > s2mps11 - > ramp_delay34 )
s2mps11 - > ramp_delay34 = ramp_delay ;
else
ramp_delay = s2mps11 - > ramp_delay34 ;
ramp_shift = S2MPS11_BUCK34_RAMP_SHIFT ;
ramp_reg = S2MPS11_REG_RAMP ;
break ;
case S2MPS11_BUCK5 :
s2mps11 - > ramp_delay5 = ramp_delay ;
ramp_shift = S2MPS11_BUCK5_RAMP_SHIFT ;
break ;
case S2MPS11_BUCK6 :
enable_shift = S2MPS11_BUCK6_RAMP_EN_SHIFT ;
if ( ! ramp_delay ) {
ramp_enable = 0 ;
break ;
}
if ( ramp_delay > s2mps11 - > ramp_delay16 )
s2mps11 - > ramp_delay16 = ramp_delay ;
else
ramp_delay = s2mps11 - > ramp_delay16 ;
ramp_shift = S2MPS11_BUCK16_RAMP_SHIFT ;
break ;
case S2MPS11_BUCK7 :
case S2MPS11_BUCK8 :
case S2MPS11_BUCK10 :
if ( ramp_delay > s2mps11 - > ramp_delay7810 )
s2mps11 - > ramp_delay7810 = ramp_delay ;
else
ramp_delay = s2mps11 - > ramp_delay7810 ;
ramp_shift = S2MPS11_BUCK7810_RAMP_SHIFT ;
break ;
case S2MPS11_BUCK9 :
s2mps11 - > ramp_delay9 = ramp_delay ;
ramp_shift = S2MPS11_BUCK9_RAMP_SHIFT ;
break ;
default :
return 0 ;
}
if ( ! ramp_enable )
goto ramp_disable ;
2014-05-06 10:37:36 +04:00
/* Ramp delay can be enabled/disabled only for buck[2346] */
if ( ( rdev_get_id ( rdev ) > = S2MPS11_BUCK2 & &
rdev_get_id ( rdev ) < = S2MPS11_BUCK4 ) | |
rdev_get_id ( rdev ) = = S2MPS11_BUCK6 ) {
ret = regmap_update_bits ( rdev - > regmap , S2MPS11_REG_RAMP ,
1 < < enable_shift , 1 < < enable_shift ) ;
if ( ret ) {
dev_err ( & rdev - > dev , " failed to enable ramp rate \n " ) ;
return ret ;
}
2013-06-29 16:51:16 +04:00
}
ramp_val = get_ramp_delay ( ramp_delay ) ;
2013-08-05 10:08:37 +04:00
return regmap_update_bits ( rdev - > regmap , ramp_reg , 0x3 < < ramp_shift ,
ramp_val < < ramp_shift ) ;
2013-06-29 16:51:16 +04:00
ramp_disable :
2013-08-03 13:10:42 +04:00
return regmap_update_bits ( rdev - > regmap , S2MPS11_REG_RAMP ,
1 < < enable_shift , 0 ) ;
2013-06-29 16:51:16 +04:00
}
2017-03-11 22:01:22 +03:00
static const struct regulator_ops s2mps11_ldo_ops = {
2012-07-11 16:08:17 +04:00
. list_voltage = regulator_list_voltage_linear ,
. map_voltage = regulator_map_voltage_linear ,
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
. set_voltage_time_sel = regulator_set_voltage_time_sel ,
} ;
2017-03-11 22:01:22 +03:00
static const struct regulator_ops s2mps11_buck_ops = {
2012-07-11 16:08:17 +04:00
. list_voltage = regulator_list_voltage_linear ,
. map_voltage = regulator_map_voltage_linear ,
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
2013-06-24 15:20:56 +04:00
. set_voltage_time_sel = s2mps11_regulator_set_voltage_time_sel ,
2013-06-29 16:51:16 +04:00
. set_ramp_delay = s2mps11_set_ramp_delay ,
2012-07-11 16:08:17 +04:00
} ;
2014-07-15 15:02:53 +04:00
# define regulator_desc_s2mps11_ldo(num, step) { \
2012-07-11 16:08:17 +04:00
. name = " LDO " # num , \
. id = S2MPS11_LDO # # num , \
. ops = & s2mps11_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
2016-04-18 16:33:10 +03:00
. ramp_delay = RAMP_DELAY_12_MVUS , \
2014-07-15 15:02:51 +04:00
. min_uV = MIN_800_MV , \
2014-07-15 15:02:53 +04:00
. uV_step = step , \
2012-07-11 16:08:17 +04:00
. n_voltages = S2MPS11_LDO_N_VOLTAGES , \
. vsel_reg = S2MPS11_REG_L1CTRL + num - 1 , \
2012-07-12 05:35:50 +04:00
. vsel_mask = S2MPS11_LDO_VSEL_MASK , \
2012-07-11 16:08:17 +04:00
. enable_reg = S2MPS11_REG_L1CTRL + num - 1 , \
. enable_mask = S2MPS11_ENABLE_MASK \
}
2014-03-07 14:10:50 +04:00
# define regulator_desc_s2mps11_buck1_4(num) { \
2012-07-11 16:08:17 +04:00
. name = " BUCK " # num , \
. id = S2MPS11_BUCK # # num , \
. ops = & s2mps11_buck_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
2014-07-15 15:02:51 +04:00
. min_uV = MIN_600_MV , \
. uV_step = STEP_6_25_MV , \
2012-07-11 16:08:17 +04:00
. n_voltages = S2MPS11_BUCK_N_VOLTAGES , \
2013-06-24 15:20:55 +04:00
. ramp_delay = S2MPS11_RAMP_DELAY , \
2012-07-11 16:08:17 +04:00
. vsel_reg = S2MPS11_REG_B1CTRL2 + ( num - 1 ) * 2 , \
2012-07-12 05:35:50 +04:00
. vsel_mask = S2MPS11_BUCK_VSEL_MASK , \
2012-07-11 16:08:17 +04:00
. enable_reg = S2MPS11_REG_B1CTRL1 + ( num - 1 ) * 2 , \
. enable_mask = S2MPS11_ENABLE_MASK \
}
2014-03-07 14:10:50 +04:00
# define regulator_desc_s2mps11_buck5 { \
2012-07-11 16:08:17 +04:00
. name = " BUCK5 " , \
. id = S2MPS11_BUCK5 , \
. ops = & s2mps11_buck_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
2014-07-15 15:02:51 +04:00
. min_uV = MIN_600_MV , \
. uV_step = STEP_6_25_MV , \
2012-07-11 16:08:17 +04:00
. n_voltages = S2MPS11_BUCK_N_VOLTAGES , \
2013-06-24 15:20:55 +04:00
. ramp_delay = S2MPS11_RAMP_DELAY , \
2012-07-11 16:08:17 +04:00
. vsel_reg = S2MPS11_REG_B5CTRL2 , \
2012-07-12 05:35:50 +04:00
. vsel_mask = S2MPS11_BUCK_VSEL_MASK , \
2012-07-11 16:08:17 +04:00
. enable_reg = S2MPS11_REG_B5CTRL1 , \
. enable_mask = S2MPS11_ENABLE_MASK \
}
2016-03-28 07:09:56 +03:00
# define regulator_desc_s2mps11_buck67810(num, min, step) { \
2012-07-11 16:08:17 +04:00
. name = " BUCK " # num , \
. id = S2MPS11_BUCK # # num , \
. ops = & s2mps11_buck_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
2014-07-15 15:02:53 +04:00
. min_uV = min , \
. uV_step = step , \
2012-07-11 16:08:17 +04:00
. n_voltages = S2MPS11_BUCK_N_VOLTAGES , \
2013-06-24 15:20:55 +04:00
. ramp_delay = S2MPS11_RAMP_DELAY , \
2012-07-11 16:08:17 +04:00
. vsel_reg = S2MPS11_REG_B6CTRL2 + ( num - 6 ) * 2 , \
2012-07-12 05:35:50 +04:00
. vsel_mask = S2MPS11_BUCK_VSEL_MASK , \
2012-07-11 16:08:17 +04:00
. enable_reg = S2MPS11_REG_B6CTRL1 + ( num - 6 ) * 2 , \
. enable_mask = S2MPS11_ENABLE_MASK \
}
2016-03-28 07:09:56 +03:00
# define regulator_desc_s2mps11_buck9 { \
. name = " BUCK9 " , \
. id = S2MPS11_BUCK9 , \
. ops = & s2mps11_buck_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = MIN_3000_MV , \
. uV_step = STEP_25_MV , \
. n_voltages = S2MPS11_BUCK9_N_VOLTAGES , \
. ramp_delay = S2MPS11_RAMP_DELAY , \
. vsel_reg = S2MPS11_REG_B9CTRL2 , \
. vsel_mask = S2MPS11_BUCK9_VSEL_MASK , \
. enable_reg = S2MPS11_REG_B9CTRL1 , \
. enable_mask = S2MPS11_ENABLE_MASK \
}
2014-03-03 19:53:51 +04:00
static const struct regulator_desc s2mps11_regulators [ ] = {
2014-07-15 15:02:53 +04:00
regulator_desc_s2mps11_ldo ( 1 , STEP_25_MV ) ,
regulator_desc_s2mps11_ldo ( 2 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 3 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 4 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 5 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 6 , STEP_25_MV ) ,
regulator_desc_s2mps11_ldo ( 7 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 8 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 9 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 10 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 11 , STEP_25_MV ) ,
regulator_desc_s2mps11_ldo ( 12 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 13 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 14 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 15 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 16 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 17 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 18 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 19 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 20 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 21 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 22 , STEP_25_MV ) ,
regulator_desc_s2mps11_ldo ( 23 , STEP_25_MV ) ,
regulator_desc_s2mps11_ldo ( 24 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 25 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 26 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 27 , STEP_25_MV ) ,
regulator_desc_s2mps11_ldo ( 28 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 29 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 30 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 31 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 32 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 33 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 34 , STEP_50_MV ) ,
2019-02-09 20:14:14 +03:00
regulator_desc_s2mps11_ldo ( 35 , STEP_25_MV ) ,
2014-07-15 15:02:53 +04:00
regulator_desc_s2mps11_ldo ( 36 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 37 , STEP_50_MV ) ,
regulator_desc_s2mps11_ldo ( 38 , STEP_50_MV ) ,
2014-03-07 14:10:50 +04:00
regulator_desc_s2mps11_buck1_4 ( 1 ) ,
regulator_desc_s2mps11_buck1_4 ( 2 ) ,
regulator_desc_s2mps11_buck1_4 ( 3 ) ,
regulator_desc_s2mps11_buck1_4 ( 4 ) ,
regulator_desc_s2mps11_buck5 ,
2016-03-28 07:09:56 +03:00
regulator_desc_s2mps11_buck67810 ( 6 , MIN_600_MV , STEP_6_25_MV ) ,
2019-02-09 20:14:14 +03:00
regulator_desc_s2mps11_buck67810 ( 7 , MIN_600_MV , STEP_12_5_MV ) ,
regulator_desc_s2mps11_buck67810 ( 8 , MIN_600_MV , STEP_12_5_MV ) ,
2016-03-28 07:09:56 +03:00
regulator_desc_s2mps11_buck9 ,
regulator_desc_s2mps11_buck67810 ( 10 , MIN_750_MV , STEP_12_5_MV ) ,
2014-03-07 14:10:50 +04:00
} ;
2017-03-11 22:01:22 +03:00
static const struct regulator_ops s2mps14_reg_ops ;
2014-11-18 11:59:40 +03:00
# define regulator_desc_s2mps13_ldo(num, min, step, min_sel) { \
. name = " LDO " # num , \
. id = S2MPS13_LDO # # num , \
. ops = & s2mps14_reg_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = min , \
. uV_step = step , \
. linear_min_sel = min_sel , \
. n_voltages = S2MPS14_LDO_N_VOLTAGES , \
. vsel_reg = S2MPS13_REG_L1CTRL + num - 1 , \
. vsel_mask = S2MPS14_LDO_VSEL_MASK , \
. enable_reg = S2MPS13_REG_L1CTRL + num - 1 , \
. enable_mask = S2MPS14_ENABLE_MASK \
}
# define regulator_desc_s2mps13_buck(num, min, step, min_sel) { \
. name = " BUCK " # num , \
. id = S2MPS13_BUCK # # num , \
. ops = & s2mps14_reg_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = min , \
. uV_step = step , \
. linear_min_sel = min_sel , \
. n_voltages = S2MPS14_BUCK_N_VOLTAGES , \
. ramp_delay = S2MPS13_BUCK_RAMP_DELAY , \
. vsel_reg = S2MPS13_REG_B1OUT + ( num - 1 ) * 2 , \
. vsel_mask = S2MPS14_BUCK_VSEL_MASK , \
. enable_reg = S2MPS13_REG_B1CTRL + ( num - 1 ) * 2 , \
. enable_mask = S2MPS14_ENABLE_MASK \
}
2015-01-08 05:04:07 +03:00
# define regulator_desc_s2mps13_buck7(num, min, step, min_sel) { \
. name = " BUCK " # num , \
. id = S2MPS13_BUCK # # num , \
. ops = & s2mps14_reg_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = min , \
. uV_step = step , \
. linear_min_sel = min_sel , \
. n_voltages = S2MPS14_BUCK_N_VOLTAGES , \
. ramp_delay = S2MPS13_BUCK_RAMP_DELAY , \
. vsel_reg = S2MPS13_REG_B1OUT + ( num ) * 2 - 1 , \
. vsel_mask = S2MPS14_BUCK_VSEL_MASK , \
. enable_reg = S2MPS13_REG_B1CTRL + ( num - 1 ) * 2 , \
. enable_mask = S2MPS14_ENABLE_MASK \
}
# define regulator_desc_s2mps13_buck8_10(num, min, step, min_sel) { \
. name = " BUCK " # num , \
. id = S2MPS13_BUCK # # num , \
. ops = & s2mps14_reg_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = min , \
. uV_step = step , \
. linear_min_sel = min_sel , \
. n_voltages = S2MPS14_BUCK_N_VOLTAGES , \
. ramp_delay = S2MPS13_BUCK_RAMP_DELAY , \
. vsel_reg = S2MPS13_REG_B1OUT + ( num ) * 2 - 1 , \
. vsel_mask = S2MPS14_BUCK_VSEL_MASK , \
. enable_reg = S2MPS13_REG_B1CTRL + ( num ) * 2 - 1 , \
. enable_mask = S2MPS14_ENABLE_MASK \
}
2014-11-18 11:59:40 +03:00
static const struct regulator_desc s2mps13_regulators [ ] = {
regulator_desc_s2mps13_ldo ( 1 , MIN_800_MV , STEP_12_5_MV , 0x00 ) ,
regulator_desc_s2mps13_ldo ( 2 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 3 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 4 , MIN_800_MV , STEP_12_5_MV , 0x00 ) ,
regulator_desc_s2mps13_ldo ( 5 , MIN_800_MV , STEP_12_5_MV , 0x00 ) ,
regulator_desc_s2mps13_ldo ( 6 , MIN_800_MV , STEP_12_5_MV , 0x00 ) ,
regulator_desc_s2mps13_ldo ( 7 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 8 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 9 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 10 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 11 , MIN_800_MV , STEP_25_MV , 0x10 ) ,
regulator_desc_s2mps13_ldo ( 12 , MIN_800_MV , STEP_25_MV , 0x10 ) ,
regulator_desc_s2mps13_ldo ( 13 , MIN_800_MV , STEP_25_MV , 0x10 ) ,
regulator_desc_s2mps13_ldo ( 14 , MIN_800_MV , STEP_12_5_MV , 0x00 ) ,
regulator_desc_s2mps13_ldo ( 15 , MIN_800_MV , STEP_12_5_MV , 0x00 ) ,
regulator_desc_s2mps13_ldo ( 16 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 17 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 18 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 19 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 20 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 21 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 22 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 23 , MIN_800_MV , STEP_12_5_MV , 0x00 ) ,
regulator_desc_s2mps13_ldo ( 24 , MIN_800_MV , STEP_12_5_MV , 0x00 ) ,
regulator_desc_s2mps13_ldo ( 25 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 26 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 27 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 28 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 29 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 30 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 31 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 32 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 33 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 34 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 35 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 36 , MIN_800_MV , STEP_12_5_MV , 0x00 ) ,
regulator_desc_s2mps13_ldo ( 37 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 38 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_ldo ( 39 , MIN_1000_MV , STEP_25_MV , 0x08 ) ,
regulator_desc_s2mps13_ldo ( 40 , MIN_1400_MV , STEP_50_MV , 0x0C ) ,
regulator_desc_s2mps13_buck ( 1 , MIN_500_MV , STEP_6_25_MV , 0x10 ) ,
regulator_desc_s2mps13_buck ( 2 , MIN_500_MV , STEP_6_25_MV , 0x10 ) ,
regulator_desc_s2mps13_buck ( 3 , MIN_500_MV , STEP_6_25_MV , 0x10 ) ,
regulator_desc_s2mps13_buck ( 4 , MIN_500_MV , STEP_6_25_MV , 0x10 ) ,
regulator_desc_s2mps13_buck ( 5 , MIN_500_MV , STEP_6_25_MV , 0x10 ) ,
regulator_desc_s2mps13_buck ( 6 , MIN_500_MV , STEP_6_25_MV , 0x10 ) ,
2015-01-08 05:04:07 +03:00
regulator_desc_s2mps13_buck7 ( 7 , MIN_500_MV , STEP_6_25_MV , 0x10 ) ,
regulator_desc_s2mps13_buck8_10 ( 8 , MIN_1000_MV , STEP_12_5_MV , 0x20 ) ,
regulator_desc_s2mps13_buck8_10 ( 9 , MIN_1000_MV , STEP_12_5_MV , 0x20 ) ,
regulator_desc_s2mps13_buck8_10 ( 10 , MIN_500_MV , STEP_6_25_MV , 0x10 ) ,
2014-11-18 11:59:40 +03:00
} ;
2014-03-07 14:10:51 +04:00
static int s2mps14_regulator_enable ( struct regulator_dev * rdev )
{
struct s2mps11_info * s2mps11 = rdev_get_drvdata ( rdev ) ;
unsigned int val ;
2014-06-25 11:14:45 +04:00
switch ( s2mps11 - > dev_type ) {
2014-11-18 11:59:40 +03:00
case S2MPS13X :
2014-06-25 11:14:45 +04:00
case S2MPS14X :
2015-06-24 13:48:43 +03:00
if ( test_bit ( rdev_get_id ( rdev ) , s2mps11 - > suspend_state ) )
2014-06-25 11:14:45 +04:00
val = S2MPS14_ENABLE_SUSPEND ;
2018-11-15 11:01:17 +03:00
else if ( s2mps11 - > ext_control_gpiod [ rdev_get_id ( rdev ) ] )
2014-06-25 11:14:45 +04:00
val = S2MPS14_ENABLE_EXT_CONTROL ;
else
val = rdev - > desc - > enable_mask ;
break ;
case S2MPU02 :
2015-06-24 13:48:43 +03:00
if ( test_bit ( rdev_get_id ( rdev ) , s2mps11 - > suspend_state ) )
2014-06-25 11:14:45 +04:00
val = S2MPU02_ENABLE_SUSPEND ;
else
val = rdev - > desc - > enable_mask ;
break ;
default :
return - EINVAL ;
2015-04-23 15:24:32 +03:00
}
2014-03-07 14:10:51 +04:00
return regmap_update_bits ( rdev - > regmap , rdev - > desc - > enable_reg ,
rdev - > desc - > enable_mask , val ) ;
}
static int s2mps14_regulator_set_suspend_disable ( struct regulator_dev * rdev )
{
int ret ;
2014-06-25 11:14:45 +04:00
unsigned int val , state ;
2014-03-07 14:10:51 +04:00
struct s2mps11_info * s2mps11 = rdev_get_drvdata ( rdev ) ;
2014-06-25 11:14:45 +04:00
int rdev_id = rdev_get_id ( rdev ) ;
2014-03-07 14:10:51 +04:00
2014-06-25 11:14:45 +04:00
/* Below LDO should be always on or does not support suspend mode. */
switch ( s2mps11 - > dev_type ) {
2014-11-18 11:59:40 +03:00
case S2MPS13X :
2014-06-25 11:14:45 +04:00
case S2MPS14X :
switch ( rdev_id ) {
case S2MPS14_LDO3 :
return 0 ;
default :
state = S2MPS14_ENABLE_SUSPEND ;
break ;
2015-04-23 15:24:32 +03:00
}
2014-06-25 11:14:45 +04:00
break ;
case S2MPU02 :
switch ( rdev_id ) {
case S2MPU02_LDO13 :
case S2MPU02_LDO14 :
case S2MPU02_LDO15 :
case S2MPU02_LDO17 :
case S2MPU02_BUCK7 :
state = S2MPU02_DISABLE_SUSPEND ;
break ;
default :
state = S2MPU02_ENABLE_SUSPEND ;
break ;
2015-04-23 15:24:32 +03:00
}
2014-06-25 11:14:45 +04:00
break ;
default :
return - EINVAL ;
2015-04-23 15:24:32 +03:00
}
2014-03-07 14:10:51 +04:00
ret = regmap_read ( rdev - > regmap , rdev - > desc - > enable_reg , & val ) ;
if ( ret < 0 )
return ret ;
2015-06-24 13:48:43 +03:00
set_bit ( rdev_get_id ( rdev ) , s2mps11 - > suspend_state ) ;
2014-03-07 14:10:51 +04:00
/*
* Don ' t enable suspend mode if regulator is already disabled because
* this would effectively for a short time turn on the regulator after
* resuming .
* However we still want to toggle the suspend_state bit for regulator
* in case if it got enabled before suspending the system .
*/
if ( ! ( val & rdev - > desc - > enable_mask ) )
return 0 ;
return regmap_update_bits ( rdev - > regmap , rdev - > desc - > enable_reg ,
2014-06-25 11:14:45 +04:00
rdev - > desc - > enable_mask , state ) ;
2014-03-07 14:10:51 +04:00
}
2017-03-11 22:01:22 +03:00
static const struct regulator_ops s2mps14_reg_ops = {
2014-03-07 14:10:50 +04:00
. list_voltage = regulator_list_voltage_linear ,
. map_voltage = regulator_map_voltage_linear ,
. is_enabled = regulator_is_enabled_regmap ,
2014-03-07 14:10:51 +04:00
. enable = s2mps14_regulator_enable ,
2014-03-07 14:10:50 +04:00
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
. set_voltage_time_sel = regulator_set_voltage_time_sel ,
2014-03-07 14:10:51 +04:00
. set_suspend_disable = s2mps14_regulator_set_suspend_disable ,
2014-03-07 14:10:50 +04:00
} ;
2014-07-15 15:02:53 +04:00
# define regulator_desc_s2mps14_ldo(num, min, step) { \
2014-03-07 14:10:50 +04:00
. name = " LDO " # num , \
. id = S2MPS14_LDO # # num , \
. ops = & s2mps14_reg_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
2014-07-15 15:02:53 +04:00
. min_uV = min , \
. uV_step = step , \
2014-03-07 14:10:50 +04:00
. n_voltages = S2MPS14_LDO_N_VOLTAGES , \
. vsel_reg = S2MPS14_REG_L1CTRL + num - 1 , \
. vsel_mask = S2MPS14_LDO_VSEL_MASK , \
. enable_reg = S2MPS14_REG_L1CTRL + num - 1 , \
. enable_mask = S2MPS14_ENABLE_MASK \
}
2014-07-15 15:02:53 +04:00
regulator: s2mps11: Fix dw_mmc failure on Gear 2
Invalid buck4 configuration for linear mapping of voltage in S2MPS14
regulators caused boot failure on Gear 2 (dw_mmc-exynos):
[ 3.569137] EXT4-fs (mmcblk0p15): mounted filesystem with ordered data mode. Opts: (null)
[ 3.571716] VFS: Mounted root (ext4 filesystem) readonly on device 179:15.
[ 3.629842] mmcblk0: error -110 sending status command, retrying
[ 3.630244] mmcblk0: error -110 sending status command, retrying
[ 3.636292] mmcblk0: error -110 sending status command, aborting
Buck4 voltage regulator has different minimal voltage value than other
bucks. Commit merging multiple regulator description macros caused to
use linear_min_sel from buck[1235] regulators as value for buck4. This
lead to lower voltage of buck4 than required.
Output of the buck4 is used internally as power source for
LDO{3,4,7,11,19,20,21,23}. On Gear 2 board LDO11 is used as MMC
regulator (V_EMMC_1.8V).
Fixes: 5a867cf28893 ("regulator: s2mps11: Optimize the regulator description macro")
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: <stable@vger.kernel.org>
2014-12-11 16:40:21 +03:00
# define regulator_desc_s2mps14_buck(num, min, step, min_sel) { \
2014-03-07 14:10:50 +04:00
. name = " BUCK " # num , \
. id = S2MPS14_BUCK # # num , \
. ops = & s2mps14_reg_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
2014-07-15 15:02:53 +04:00
. min_uV = min , \
. uV_step = step , \
2014-03-07 14:10:50 +04:00
. n_voltages = S2MPS14_BUCK_N_VOLTAGES , \
regulator: s2mps11: Fix dw_mmc failure on Gear 2
Invalid buck4 configuration for linear mapping of voltage in S2MPS14
regulators caused boot failure on Gear 2 (dw_mmc-exynos):
[ 3.569137] EXT4-fs (mmcblk0p15): mounted filesystem with ordered data mode. Opts: (null)
[ 3.571716] VFS: Mounted root (ext4 filesystem) readonly on device 179:15.
[ 3.629842] mmcblk0: error -110 sending status command, retrying
[ 3.630244] mmcblk0: error -110 sending status command, retrying
[ 3.636292] mmcblk0: error -110 sending status command, aborting
Buck4 voltage regulator has different minimal voltage value than other
bucks. Commit merging multiple regulator description macros caused to
use linear_min_sel from buck[1235] regulators as value for buck4. This
lead to lower voltage of buck4 than required.
Output of the buck4 is used internally as power source for
LDO{3,4,7,11,19,20,21,23}. On Gear 2 board LDO11 is used as MMC
regulator (V_EMMC_1.8V).
Fixes: 5a867cf28893 ("regulator: s2mps11: Optimize the regulator description macro")
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: <stable@vger.kernel.org>
2014-12-11 16:40:21 +03:00
. linear_min_sel = min_sel , \
2014-03-07 14:10:50 +04:00
. ramp_delay = S2MPS14_BUCK_RAMP_DELAY , \
. vsel_reg = S2MPS14_REG_B1CTRL2 + ( num - 1 ) * 2 , \
. vsel_mask = S2MPS14_BUCK_VSEL_MASK , \
. enable_reg = S2MPS14_REG_B1CTRL1 + ( num - 1 ) * 2 , \
. enable_mask = S2MPS14_ENABLE_MASK \
}
static const struct regulator_desc s2mps14_regulators [ ] = {
2014-07-15 15:02:53 +04:00
regulator_desc_s2mps14_ldo ( 1 , MIN_800_MV , STEP_12_5_MV ) ,
regulator_desc_s2mps14_ldo ( 2 , MIN_800_MV , STEP_12_5_MV ) ,
regulator_desc_s2mps14_ldo ( 3 , MIN_800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 4 , MIN_800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 5 , MIN_800_MV , STEP_12_5_MV ) ,
regulator_desc_s2mps14_ldo ( 6 , MIN_800_MV , STEP_12_5_MV ) ,
regulator_desc_s2mps14_ldo ( 7 , MIN_800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 8 , MIN_1800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 9 , MIN_800_MV , STEP_12_5_MV ) ,
regulator_desc_s2mps14_ldo ( 10 , MIN_800_MV , STEP_12_5_MV ) ,
regulator_desc_s2mps14_ldo ( 11 , MIN_800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 12 , MIN_1800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 13 , MIN_1800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 14 , MIN_1800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 15 , MIN_1800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 16 , MIN_1800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 17 , MIN_1800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 18 , MIN_1800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 19 , MIN_800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 20 , MIN_800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 21 , MIN_800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 22 , MIN_800_MV , STEP_12_5_MV ) ,
regulator_desc_s2mps14_ldo ( 23 , MIN_800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 24 , MIN_1800_MV , STEP_25_MV ) ,
regulator_desc_s2mps14_ldo ( 25 , MIN_1800_MV , STEP_25_MV ) ,
regulator: s2mps11: Fix dw_mmc failure on Gear 2
Invalid buck4 configuration for linear mapping of voltage in S2MPS14
regulators caused boot failure on Gear 2 (dw_mmc-exynos):
[ 3.569137] EXT4-fs (mmcblk0p15): mounted filesystem with ordered data mode. Opts: (null)
[ 3.571716] VFS: Mounted root (ext4 filesystem) readonly on device 179:15.
[ 3.629842] mmcblk0: error -110 sending status command, retrying
[ 3.630244] mmcblk0: error -110 sending status command, retrying
[ 3.636292] mmcblk0: error -110 sending status command, aborting
Buck4 voltage regulator has different minimal voltage value than other
bucks. Commit merging multiple regulator description macros caused to
use linear_min_sel from buck[1235] regulators as value for buck4. This
lead to lower voltage of buck4 than required.
Output of the buck4 is used internally as power source for
LDO{3,4,7,11,19,20,21,23}. On Gear 2 board LDO11 is used as MMC
regulator (V_EMMC_1.8V).
Fixes: 5a867cf28893 ("regulator: s2mps11: Optimize the regulator description macro")
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: <stable@vger.kernel.org>
2014-12-11 16:40:21 +03:00
regulator_desc_s2mps14_buck ( 1 , MIN_600_MV , STEP_6_25_MV ,
S2MPS14_BUCK1235_START_SEL ) ,
regulator_desc_s2mps14_buck ( 2 , MIN_600_MV , STEP_6_25_MV ,
S2MPS14_BUCK1235_START_SEL ) ,
regulator_desc_s2mps14_buck ( 3 , MIN_600_MV , STEP_6_25_MV ,
S2MPS14_BUCK1235_START_SEL ) ,
regulator_desc_s2mps14_buck ( 4 , MIN_1400_MV , STEP_12_5_MV ,
S2MPS14_BUCK4_START_SEL ) ,
regulator_desc_s2mps14_buck ( 5 , MIN_600_MV , STEP_6_25_MV ,
S2MPS14_BUCK1235_START_SEL ) ,
2012-07-11 16:08:17 +04:00
} ;
2017-03-11 22:01:22 +03:00
static const struct regulator_ops s2mps15_reg_ldo_ops = {
2015-11-20 13:37:52 +03:00
. list_voltage = regulator_list_voltage_linear_range ,
. map_voltage = regulator_map_voltage_linear_range ,
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
} ;
2017-03-11 22:01:22 +03:00
static const struct regulator_ops s2mps15_reg_buck_ops = {
2015-11-20 13:37:52 +03:00
. list_voltage = regulator_list_voltage_linear_range ,
. map_voltage = regulator_map_voltage_linear_range ,
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
. set_voltage_time_sel = regulator_set_voltage_time_sel ,
} ;
# define regulator_desc_s2mps15_ldo(num, range) { \
. name = " LDO " # num , \
. id = S2MPS15_LDO # # num , \
. ops = & s2mps15_reg_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. linear_ranges = range , \
. n_linear_ranges = ARRAY_SIZE ( range ) , \
. n_voltages = S2MPS15_LDO_N_VOLTAGES , \
. vsel_reg = S2MPS15_REG_L1CTRL + num - 1 , \
. vsel_mask = S2MPS15_LDO_VSEL_MASK , \
. enable_reg = S2MPS15_REG_L1CTRL + num - 1 , \
. enable_mask = S2MPS15_ENABLE_MASK \
}
# define regulator_desc_s2mps15_buck(num, range) { \
. name = " BUCK " # num , \
. id = S2MPS15_BUCK # # num , \
. ops = & s2mps15_reg_buck_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. linear_ranges = range , \
. n_linear_ranges = ARRAY_SIZE ( range ) , \
. ramp_delay = 12500 , \
. n_voltages = S2MPS15_BUCK_N_VOLTAGES , \
. vsel_reg = S2MPS15_REG_B1CTRL2 + ( ( num - 1 ) * 2 ) , \
. vsel_mask = S2MPS15_BUCK_VSEL_MASK , \
. enable_reg = S2MPS15_REG_B1CTRL1 + ( ( num - 1 ) * 2 ) , \
. enable_mask = S2MPS15_ENABLE_MASK \
}
/* voltage range for s2mps15 LDO 3, 5, 15, 16, 18, 20, 23 and 27 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges1 [ ] = {
REGULATOR_LINEAR_RANGE ( 1000000 , 0xc , 0x38 , 25000 ) ,
} ;
/* voltage range for s2mps15 LDO 2, 6, 14, 17, 19, 21, 24 and 25 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges2 [ ] = {
REGULATOR_LINEAR_RANGE ( 1800000 , 0x0 , 0x3f , 25000 ) ,
} ;
/* voltage range for s2mps15 LDO 4, 11, 12, 13, 22 and 26 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges3 [ ] = {
REGULATOR_LINEAR_RANGE ( 700000 , 0x0 , 0x34 , 12500 ) ,
} ;
/* voltage range for s2mps15 LDO 7, 8, 9 and 10 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges4 [ ] = {
2016-07-12 08:56:43 +03:00
REGULATOR_LINEAR_RANGE ( 700000 , 0x10 , 0x20 , 25000 ) ,
2015-11-20 13:37:52 +03:00
} ;
/* voltage range for s2mps15 LDO 1 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges5 [ ] = {
REGULATOR_LINEAR_RANGE ( 500000 , 0x0 , 0x20 , 12500 ) ,
} ;
/* voltage range for s2mps15 BUCK 1, 2, 3, 4, 5, 6 and 7 */
static const struct regulator_linear_range s2mps15_buck_voltage_ranges1 [ ] = {
2016-07-12 08:56:43 +03:00
REGULATOR_LINEAR_RANGE ( 500000 , 0x20 , 0xc0 , 6250 ) ,
2015-11-20 13:37:52 +03:00
} ;
/* voltage range for s2mps15 BUCK 8, 9 and 10 */
static const struct regulator_linear_range s2mps15_buck_voltage_ranges2 [ ] = {
2016-07-12 08:56:43 +03:00
REGULATOR_LINEAR_RANGE ( 1000000 , 0x20 , 0x78 , 12500 ) ,
2015-11-20 13:37:52 +03:00
} ;
static const struct regulator_desc s2mps15_regulators [ ] = {
regulator_desc_s2mps15_ldo ( 1 , s2mps15_ldo_voltage_ranges5 ) ,
regulator_desc_s2mps15_ldo ( 2 , s2mps15_ldo_voltage_ranges2 ) ,
regulator_desc_s2mps15_ldo ( 3 , s2mps15_ldo_voltage_ranges1 ) ,
regulator_desc_s2mps15_ldo ( 4 , s2mps15_ldo_voltage_ranges3 ) ,
regulator_desc_s2mps15_ldo ( 5 , s2mps15_ldo_voltage_ranges1 ) ,
regulator_desc_s2mps15_ldo ( 6 , s2mps15_ldo_voltage_ranges2 ) ,
regulator_desc_s2mps15_ldo ( 7 , s2mps15_ldo_voltage_ranges4 ) ,
regulator_desc_s2mps15_ldo ( 8 , s2mps15_ldo_voltage_ranges4 ) ,
regulator_desc_s2mps15_ldo ( 9 , s2mps15_ldo_voltage_ranges4 ) ,
regulator_desc_s2mps15_ldo ( 10 , s2mps15_ldo_voltage_ranges4 ) ,
regulator_desc_s2mps15_ldo ( 11 , s2mps15_ldo_voltage_ranges3 ) ,
regulator_desc_s2mps15_ldo ( 12 , s2mps15_ldo_voltage_ranges3 ) ,
regulator_desc_s2mps15_ldo ( 13 , s2mps15_ldo_voltage_ranges3 ) ,
regulator_desc_s2mps15_ldo ( 14 , s2mps15_ldo_voltage_ranges2 ) ,
regulator_desc_s2mps15_ldo ( 15 , s2mps15_ldo_voltage_ranges1 ) ,
regulator_desc_s2mps15_ldo ( 16 , s2mps15_ldo_voltage_ranges1 ) ,
regulator_desc_s2mps15_ldo ( 17 , s2mps15_ldo_voltage_ranges2 ) ,
regulator_desc_s2mps15_ldo ( 18 , s2mps15_ldo_voltage_ranges1 ) ,
regulator_desc_s2mps15_ldo ( 19 , s2mps15_ldo_voltage_ranges2 ) ,
regulator_desc_s2mps15_ldo ( 20 , s2mps15_ldo_voltage_ranges1 ) ,
regulator_desc_s2mps15_ldo ( 21 , s2mps15_ldo_voltage_ranges2 ) ,
regulator_desc_s2mps15_ldo ( 22 , s2mps15_ldo_voltage_ranges3 ) ,
regulator_desc_s2mps15_ldo ( 23 , s2mps15_ldo_voltage_ranges1 ) ,
regulator_desc_s2mps15_ldo ( 24 , s2mps15_ldo_voltage_ranges2 ) ,
regulator_desc_s2mps15_ldo ( 25 , s2mps15_ldo_voltage_ranges2 ) ,
regulator_desc_s2mps15_ldo ( 26 , s2mps15_ldo_voltage_ranges3 ) ,
regulator_desc_s2mps15_ldo ( 27 , s2mps15_ldo_voltage_ranges1 ) ,
regulator_desc_s2mps15_buck ( 1 , s2mps15_buck_voltage_ranges1 ) ,
regulator_desc_s2mps15_buck ( 2 , s2mps15_buck_voltage_ranges1 ) ,
regulator_desc_s2mps15_buck ( 3 , s2mps15_buck_voltage_ranges1 ) ,
regulator_desc_s2mps15_buck ( 4 , s2mps15_buck_voltage_ranges1 ) ,
regulator_desc_s2mps15_buck ( 5 , s2mps15_buck_voltage_ranges1 ) ,
regulator_desc_s2mps15_buck ( 6 , s2mps15_buck_voltage_ranges1 ) ,
regulator_desc_s2mps15_buck ( 7 , s2mps15_buck_voltage_ranges1 ) ,
regulator_desc_s2mps15_buck ( 8 , s2mps15_buck_voltage_ranges2 ) ,
regulator_desc_s2mps15_buck ( 9 , s2mps15_buck_voltage_ranges2 ) ,
regulator_desc_s2mps15_buck ( 10 , s2mps15_buck_voltage_ranges2 ) ,
} ;
2014-04-14 12:09:07 +04:00
static int s2mps14_pmic_enable_ext_control ( struct s2mps11_info * s2mps11 ,
struct regulator_dev * rdev )
{
return regmap_update_bits ( rdev - > regmap , rdev - > desc - > enable_reg ,
rdev - > desc - > enable_mask , S2MPS14_ENABLE_EXT_CONTROL ) ;
}
static void s2mps14_pmic_dt_parse_ext_control_gpio ( struct platform_device * pdev ,
2014-04-14 12:09:06 +04:00
struct of_regulator_match * rdata , struct s2mps11_info * s2mps11 )
2014-04-14 12:09:07 +04:00
{
2018-11-15 11:01:17 +03:00
struct gpio_desc * * gpio = s2mps11 - > ext_control_gpiod ;
2014-04-14 12:09:07 +04:00
unsigned int i ;
unsigned int valid_regulators [ 3 ] = { S2MPS14_LDO10 , S2MPS14_LDO11 ,
S2MPS14_LDO12 } ;
for ( i = 0 ; i < ARRAY_SIZE ( valid_regulators ) ; i + + ) {
unsigned int reg = valid_regulators [ i ] ;
if ( ! rdata [ reg ] . init_data | | ! rdata [ reg ] . of_node )
continue ;
2018-11-15 11:01:17 +03:00
gpio [ reg ] = devm_gpiod_get_from_of_node ( & pdev - > dev ,
rdata [ reg ] . of_node ,
" samsung,ext-control-gpios " ,
0 ,
GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE ,
" s2mps11-regulator " ) ;
if ( IS_ERR ( gpio [ reg ] ) ) {
dev_err ( & pdev - > dev , " Failed to get control GPIO for %d/%s \n " ,
reg , rdata [ reg ] . name ) ;
continue ;
}
if ( gpio [ reg ] )
dev_dbg ( & pdev - > dev , " Using GPIO for ext-control over %d/%s \n " ,
reg , rdata [ reg ] . name ) ;
2014-04-14 12:09:07 +04:00
}
}
static int s2mps11_pmic_dt_parse ( struct platform_device * pdev ,
2016-02-18 08:57:03 +03:00
struct of_regulator_match * rdata , struct s2mps11_info * s2mps11 ,
unsigned int rdev_num )
2014-04-14 12:09:06 +04:00
{
struct device_node * reg_np ;
reg_np = of_get_child_by_name ( pdev - > dev . parent - > of_node , " regulators " ) ;
if ( ! reg_np ) {
dev_err ( & pdev - > dev , " could not find regulators sub-node \n " ) ;
return - EINVAL ;
}
2016-02-18 08:57:03 +03:00
of_regulator_match ( & pdev - > dev , reg_np , rdata , rdev_num ) ;
2014-06-25 11:14:45 +04:00
if ( s2mps11 - > dev_type = = S2MPS14X )
2014-04-14 12:09:07 +04:00
s2mps14_pmic_dt_parse_ext_control_gpio ( pdev , rdata , s2mps11 ) ;
2014-04-14 12:09:06 +04:00
of_node_put ( reg_np ) ;
return 0 ;
}
2014-06-25 11:14:45 +04:00
static int s2mpu02_set_ramp_delay ( struct regulator_dev * rdev , int ramp_delay )
{
unsigned int ramp_val , ramp_shift , ramp_reg ;
switch ( rdev_get_id ( rdev ) ) {
case S2MPU02_BUCK1 :
ramp_shift = S2MPU02_BUCK1_RAMP_SHIFT ;
break ;
case S2MPU02_BUCK2 :
ramp_shift = S2MPU02_BUCK2_RAMP_SHIFT ;
break ;
case S2MPU02_BUCK3 :
ramp_shift = S2MPU02_BUCK3_RAMP_SHIFT ;
break ;
case S2MPU02_BUCK4 :
ramp_shift = S2MPU02_BUCK4_RAMP_SHIFT ;
break ;
default :
return 0 ;
}
ramp_reg = S2MPU02_REG_RAMP1 ;
ramp_val = get_ramp_delay ( ramp_delay ) ;
return regmap_update_bits ( rdev - > regmap , ramp_reg ,
S2MPU02_BUCK1234_RAMP_MASK < < ramp_shift ,
ramp_val < < ramp_shift ) ;
}
2017-03-11 22:01:22 +03:00
static const struct regulator_ops s2mpu02_ldo_ops = {
2014-06-25 11:14:45 +04:00
. list_voltage = regulator_list_voltage_linear ,
. map_voltage = regulator_map_voltage_linear ,
. is_enabled = regulator_is_enabled_regmap ,
. enable = s2mps14_regulator_enable ,
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
. set_voltage_time_sel = regulator_set_voltage_time_sel ,
. set_suspend_disable = s2mps14_regulator_set_suspend_disable ,
} ;
2017-03-11 22:01:22 +03:00
static const struct regulator_ops s2mpu02_buck_ops = {
2014-06-25 11:14:45 +04:00
. list_voltage = regulator_list_voltage_linear ,
. map_voltage = regulator_map_voltage_linear ,
. is_enabled = regulator_is_enabled_regmap ,
. enable = s2mps14_regulator_enable ,
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
. set_voltage_time_sel = regulator_set_voltage_time_sel ,
. set_suspend_disable = s2mps14_regulator_set_suspend_disable ,
. set_ramp_delay = s2mpu02_set_ramp_delay ,
} ;
# define regulator_desc_s2mpu02_ldo1(num) { \
. name = " LDO " # num , \
. id = S2MPU02_LDO # # num , \
. ops = & s2mpu02_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = S2MPU02_LDO_MIN_900MV , \
. uV_step = S2MPU02_LDO_STEP_12_5MV , \
. linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL , \
. n_voltages = S2MPU02_LDO_N_VOLTAGES , \
. vsel_reg = S2MPU02_REG_L1CTRL , \
. vsel_mask = S2MPU02_LDO_VSEL_MASK , \
. enable_reg = S2MPU02_REG_L1CTRL , \
. enable_mask = S2MPU02_ENABLE_MASK \
}
# define regulator_desc_s2mpu02_ldo2(num) { \
. name = " LDO " # num , \
. id = S2MPU02_LDO # # num , \
. ops = & s2mpu02_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = S2MPU02_LDO_MIN_1050MV , \
. uV_step = S2MPU02_LDO_STEP_25MV , \
. linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL , \
. n_voltages = S2MPU02_LDO_N_VOLTAGES , \
. vsel_reg = S2MPU02_REG_L2CTRL1 , \
. vsel_mask = S2MPU02_LDO_VSEL_MASK , \
. enable_reg = S2MPU02_REG_L2CTRL1 , \
. enable_mask = S2MPU02_ENABLE_MASK \
}
# define regulator_desc_s2mpu02_ldo3(num) { \
. name = " LDO " # num , \
. id = S2MPU02_LDO # # num , \
. ops = & s2mpu02_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = S2MPU02_LDO_MIN_900MV , \
. uV_step = S2MPU02_LDO_STEP_12_5MV , \
. linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL , \
. n_voltages = S2MPU02_LDO_N_VOLTAGES , \
. vsel_reg = S2MPU02_REG_L3CTRL + num - 3 , \
. vsel_mask = S2MPU02_LDO_VSEL_MASK , \
. enable_reg = S2MPU02_REG_L3CTRL + num - 3 , \
. enable_mask = S2MPU02_ENABLE_MASK \
}
# define regulator_desc_s2mpu02_ldo4(num) { \
. name = " LDO " # num , \
. id = S2MPU02_LDO # # num , \
. ops = & s2mpu02_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = S2MPU02_LDO_MIN_1050MV , \
. uV_step = S2MPU02_LDO_STEP_25MV , \
. linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL , \
. n_voltages = S2MPU02_LDO_N_VOLTAGES , \
. vsel_reg = S2MPU02_REG_L3CTRL + num - 3 , \
. vsel_mask = S2MPU02_LDO_VSEL_MASK , \
. enable_reg = S2MPU02_REG_L3CTRL + num - 3 , \
. enable_mask = S2MPU02_ENABLE_MASK \
}
# define regulator_desc_s2mpu02_ldo5(num) { \
. name = " LDO " # num , \
. id = S2MPU02_LDO # # num , \
. ops = & s2mpu02_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = S2MPU02_LDO_MIN_1600MV , \
. uV_step = S2MPU02_LDO_STEP_50MV , \
. linear_min_sel = S2MPU02_LDO_GROUP3_START_SEL , \
. n_voltages = S2MPU02_LDO_N_VOLTAGES , \
. vsel_reg = S2MPU02_REG_L3CTRL + num - 3 , \
. vsel_mask = S2MPU02_LDO_VSEL_MASK , \
. enable_reg = S2MPU02_REG_L3CTRL + num - 3 , \
. enable_mask = S2MPU02_ENABLE_MASK \
}
# define regulator_desc_s2mpu02_buck1234(num) { \
. name = " BUCK " # num , \
. id = S2MPU02_BUCK # # num , \
. ops = & s2mpu02_buck_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = S2MPU02_BUCK1234_MIN_600MV , \
. uV_step = S2MPU02_BUCK1234_STEP_6_25MV , \
. n_voltages = S2MPU02_BUCK_N_VOLTAGES , \
. linear_min_sel = S2MPU02_BUCK1234_START_SEL , \
. ramp_delay = S2MPU02_BUCK_RAMP_DELAY , \
. vsel_reg = S2MPU02_REG_B1CTRL2 + ( num - 1 ) * 2 , \
. vsel_mask = S2MPU02_BUCK_VSEL_MASK , \
. enable_reg = S2MPU02_REG_B1CTRL1 + ( num - 1 ) * 2 , \
. enable_mask = S2MPU02_ENABLE_MASK \
}
# define regulator_desc_s2mpu02_buck5(num) { \
. name = " BUCK " # num , \
. id = S2MPU02_BUCK # # num , \
. ops = & s2mpu02_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = S2MPU02_BUCK5_MIN_1081_25MV , \
. uV_step = S2MPU02_BUCK5_STEP_6_25MV , \
. n_voltages = S2MPU02_BUCK_N_VOLTAGES , \
. linear_min_sel = S2MPU02_BUCK5_START_SEL , \
. ramp_delay = S2MPU02_BUCK_RAMP_DELAY , \
. vsel_reg = S2MPU02_REG_B5CTRL2 , \
. vsel_mask = S2MPU02_BUCK_VSEL_MASK , \
. enable_reg = S2MPU02_REG_B5CTRL1 , \
. enable_mask = S2MPU02_ENABLE_MASK \
}
# define regulator_desc_s2mpu02_buck6(num) { \
. name = " BUCK " # num , \
. id = S2MPU02_BUCK # # num , \
. ops = & s2mpu02_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = S2MPU02_BUCK6_MIN_1700MV , \
. uV_step = S2MPU02_BUCK6_STEP_2_50MV , \
. n_voltages = S2MPU02_BUCK_N_VOLTAGES , \
. linear_min_sel = S2MPU02_BUCK6_START_SEL , \
. ramp_delay = S2MPU02_BUCK_RAMP_DELAY , \
. vsel_reg = S2MPU02_REG_B6CTRL2 , \
. vsel_mask = S2MPU02_BUCK_VSEL_MASK , \
. enable_reg = S2MPU02_REG_B6CTRL1 , \
. enable_mask = S2MPU02_ENABLE_MASK \
}
# define regulator_desc_s2mpu02_buck7(num) { \
. name = " BUCK " # num , \
. id = S2MPU02_BUCK # # num , \
. ops = & s2mpu02_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. min_uV = S2MPU02_BUCK7_MIN_900MV , \
. uV_step = S2MPU02_BUCK7_STEP_6_25MV , \
. n_voltages = S2MPU02_BUCK_N_VOLTAGES , \
. linear_min_sel = S2MPU02_BUCK7_START_SEL , \
. ramp_delay = S2MPU02_BUCK_RAMP_DELAY , \
. vsel_reg = S2MPU02_REG_B7CTRL2 , \
. vsel_mask = S2MPU02_BUCK_VSEL_MASK , \
. enable_reg = S2MPU02_REG_B7CTRL1 , \
. enable_mask = S2MPU02_ENABLE_MASK \
}
static const struct regulator_desc s2mpu02_regulators [ ] = {
regulator_desc_s2mpu02_ldo1 ( 1 ) ,
regulator_desc_s2mpu02_ldo2 ( 2 ) ,
regulator_desc_s2mpu02_ldo4 ( 3 ) ,
regulator_desc_s2mpu02_ldo5 ( 4 ) ,
regulator_desc_s2mpu02_ldo4 ( 5 ) ,
regulator_desc_s2mpu02_ldo3 ( 6 ) ,
regulator_desc_s2mpu02_ldo3 ( 7 ) ,
regulator_desc_s2mpu02_ldo4 ( 8 ) ,
regulator_desc_s2mpu02_ldo5 ( 9 ) ,
regulator_desc_s2mpu02_ldo3 ( 10 ) ,
regulator_desc_s2mpu02_ldo4 ( 11 ) ,
regulator_desc_s2mpu02_ldo5 ( 12 ) ,
regulator_desc_s2mpu02_ldo5 ( 13 ) ,
regulator_desc_s2mpu02_ldo5 ( 14 ) ,
regulator_desc_s2mpu02_ldo5 ( 15 ) ,
regulator_desc_s2mpu02_ldo5 ( 16 ) ,
regulator_desc_s2mpu02_ldo4 ( 17 ) ,
regulator_desc_s2mpu02_ldo5 ( 18 ) ,
regulator_desc_s2mpu02_ldo3 ( 19 ) ,
regulator_desc_s2mpu02_ldo4 ( 20 ) ,
regulator_desc_s2mpu02_ldo5 ( 21 ) ,
regulator_desc_s2mpu02_ldo5 ( 22 ) ,
regulator_desc_s2mpu02_ldo5 ( 23 ) ,
regulator_desc_s2mpu02_ldo4 ( 24 ) ,
regulator_desc_s2mpu02_ldo5 ( 25 ) ,
regulator_desc_s2mpu02_ldo4 ( 26 ) ,
regulator_desc_s2mpu02_ldo5 ( 27 ) ,
regulator_desc_s2mpu02_ldo5 ( 28 ) ,
regulator_desc_s2mpu02_buck1234 ( 1 ) ,
regulator_desc_s2mpu02_buck1234 ( 2 ) ,
regulator_desc_s2mpu02_buck1234 ( 3 ) ,
regulator_desc_s2mpu02_buck1234 ( 4 ) ,
regulator_desc_s2mpu02_buck5 ( 5 ) ,
regulator_desc_s2mpu02_buck6 ( 6 ) ,
regulator_desc_s2mpu02_buck7 ( 7 ) ,
} ;
2012-11-19 22:22:22 +04:00
static int s2mps11_pmic_probe ( struct platform_device * pdev )
2012-07-11 16:08:17 +04:00
{
struct sec_pmic_dev * iodev = dev_get_drvdata ( pdev - > dev . parent ) ;
2014-04-14 12:09:06 +04:00
struct sec_platform_data * pdata = NULL ;
2014-02-28 14:01:50 +04:00
struct of_regulator_match * rdata = NULL ;
2012-07-11 16:08:17 +04:00
struct regulator_config config = { } ;
struct s2mps11_info * s2mps11 ;
2016-02-18 08:57:03 +03:00
unsigned int rdev_num = 0 ;
2014-02-28 14:01:50 +04:00
int i , ret = 0 ;
2014-03-03 19:53:51 +04:00
const struct regulator_desc * regulators ;
2012-07-11 16:08:17 +04:00
s2mps11 = devm_kzalloc ( & pdev - > dev , sizeof ( struct s2mps11_info ) ,
GFP_KERNEL ) ;
if ( ! s2mps11 )
return - ENOMEM ;
2014-06-25 11:14:45 +04:00
s2mps11 - > dev_type = platform_get_device_id ( pdev ) - > driver_data ;
switch ( s2mps11 - > dev_type ) {
2014-03-03 19:53:51 +04:00
case S2MPS11X :
2016-02-18 08:57:03 +03:00
rdev_num = ARRAY_SIZE ( s2mps11_regulators ) ;
2014-03-03 19:53:51 +04:00
regulators = s2mps11_regulators ;
2016-02-18 03:35:07 +03:00
BUILD_BUG_ON ( S2MPS_REGULATOR_MAX < ARRAY_SIZE ( s2mps11_regulators ) ) ;
2014-03-03 19:53:51 +04:00
break ;
2014-11-18 11:59:40 +03:00
case S2MPS13X :
2016-02-18 08:57:03 +03:00
rdev_num = ARRAY_SIZE ( s2mps13_regulators ) ;
2014-11-18 11:59:40 +03:00
regulators = s2mps13_regulators ;
2016-02-18 03:35:07 +03:00
BUILD_BUG_ON ( S2MPS_REGULATOR_MAX < ARRAY_SIZE ( s2mps13_regulators ) ) ;
2014-11-18 11:59:40 +03:00
break ;
2014-03-07 14:10:50 +04:00
case S2MPS14X :
2016-02-18 08:57:03 +03:00
rdev_num = ARRAY_SIZE ( s2mps14_regulators ) ;
2014-03-07 14:10:50 +04:00
regulators = s2mps14_regulators ;
2016-02-18 03:35:07 +03:00
BUILD_BUG_ON ( S2MPS_REGULATOR_MAX < ARRAY_SIZE ( s2mps14_regulators ) ) ;
2014-03-07 14:10:50 +04:00
break ;
2015-11-20 13:37:52 +03:00
case S2MPS15X :
2016-02-18 08:57:03 +03:00
rdev_num = ARRAY_SIZE ( s2mps15_regulators ) ;
2015-11-20 13:37:52 +03:00
regulators = s2mps15_regulators ;
2016-02-18 03:35:07 +03:00
BUILD_BUG_ON ( S2MPS_REGULATOR_MAX < ARRAY_SIZE ( s2mps15_regulators ) ) ;
2015-11-20 13:37:52 +03:00
break ;
2014-06-25 11:14:45 +04:00
case S2MPU02 :
2016-02-18 08:57:03 +03:00
rdev_num = ARRAY_SIZE ( s2mpu02_regulators ) ;
2014-06-25 11:14:45 +04:00
regulators = s2mpu02_regulators ;
2016-02-18 03:35:07 +03:00
BUILD_BUG_ON ( S2MPS_REGULATOR_MAX < ARRAY_SIZE ( s2mpu02_regulators ) ) ;
2014-06-25 11:14:45 +04:00
break ;
2014-03-03 19:53:51 +04:00
default :
2014-06-25 11:14:45 +04:00
dev_err ( & pdev - > dev , " Invalid device type: %u \n " ,
s2mps11 - > dev_type ) ;
2014-03-03 19:53:51 +04:00
return - EINVAL ;
2015-04-23 15:24:32 +03:00
}
2014-02-28 14:01:50 +04:00
2018-11-20 15:38:44 +03:00
s2mps11 - > ext_control_gpiod = devm_kcalloc ( & pdev - > dev , rdev_num ,
sizeof ( * s2mps11 - > ext_control_gpiod ) , GFP_KERNEL ) ;
2018-11-15 11:01:17 +03:00
if ( ! s2mps11 - > ext_control_gpiod )
2014-04-14 12:09:07 +04:00
return - ENOMEM ;
2013-06-29 16:51:18 +04:00
if ( ! iodev - > dev - > of_node ) {
2014-04-14 12:09:06 +04:00
if ( iodev - > pdata ) {
pdata = iodev - > pdata ;
2013-06-29 16:51:18 +04:00
goto common_reg ;
} else {
dev_err ( pdev - > dev . parent ,
" Platform data or DT node not supplied \n " ) ;
return - ENODEV ;
}
}
2013-06-29 16:51:17 +04:00
treewide: kzalloc() -> kcalloc()
The kzalloc() function has a 2-factor argument form, kcalloc(). This
patch replaces cases of:
kzalloc(a * b, gfp)
with:
kcalloc(a * b, gfp)
as well as handling cases of:
kzalloc(a * b * c, gfp)
with:
kzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kzalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kzalloc(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.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kzalloc
+ kcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- 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 E1, E2, E3;
constant C1, C2, C3;
@@
(
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- 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 THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kzalloc(sizeof(THING) * C2, ...)
|
kzalloc(sizeof(TYPE) * C2, ...)
|
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(C1 * C2, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:03:40 +03:00
rdata = kcalloc ( rdev_num , sizeof ( * rdata ) , GFP_KERNEL ) ;
2014-02-28 14:01:50 +04:00
if ( ! rdata )
return - ENOMEM ;
2016-02-18 08:57:03 +03:00
for ( i = 0 ; i < rdev_num ; i + + )
2013-06-29 16:51:17 +04:00
rdata [ i ] . name = regulators [ i ] . name ;
2016-02-18 08:57:03 +03:00
ret = s2mps11_pmic_dt_parse ( pdev , rdata , s2mps11 , rdev_num ) ;
2014-04-14 12:09:06 +04:00
if ( ret )
2014-02-28 14:01:50 +04:00
goto out ;
2013-06-29 16:51:17 +04:00
common_reg :
platform_set_drvdata ( pdev , s2mps11 ) ;
2012-07-11 16:08:17 +04:00
2013-06-29 16:51:17 +04:00
config . dev = & pdev - > dev ;
2013-12-11 18:07:43 +04:00
config . regmap = iodev - > regmap_pmic ;
2013-06-29 16:51:17 +04:00
config . driver_data = s2mps11 ;
2016-02-18 08:57:03 +03:00
for ( i = 0 ; i < rdev_num ; i + + ) {
2014-02-28 14:01:48 +04:00
struct regulator_dev * regulator ;
2014-04-14 12:09:06 +04:00
if ( pdata ) {
2013-06-29 16:51:17 +04:00
config . init_data = pdata - > regulators [ i ] . initdata ;
2014-01-30 17:51:19 +04:00
config . of_node = pdata - > regulators [ i ] . reg_node ;
2013-06-29 16:51:17 +04:00
} else {
config . init_data = rdata [ i ] . init_data ;
config . of_node = rdata [ i ] . of_node ;
}
2018-11-15 11:01:17 +03:00
config . ena_gpiod = s2mps11 - > ext_control_gpiod [ i ] ;
2018-12-06 15:43:51 +03:00
/*
* Hand the GPIO descriptor management over to the regulator
* core , remove it from devres management .
*/
if ( config . ena_gpiod )
devm_gpiod_unhinge ( & pdev - > dev , config . ena_gpiod ) ;
2014-02-28 14:01:48 +04:00
regulator = devm_regulator_register ( & pdev - > dev ,
2013-09-04 10:42:15 +04:00
& regulators [ i ] , & config ) ;
2014-02-28 14:01:48 +04:00
if ( IS_ERR ( regulator ) ) {
ret = PTR_ERR ( regulator ) ;
2012-07-12 05:37:37 +04:00
dev_err ( & pdev - > dev , " regulator init failed for %d \n " ,
i ) ;
2014-02-28 14:01:50 +04:00
goto out ;
2012-07-11 16:08:17 +04:00
}
2014-04-14 12:09:07 +04:00
2018-11-15 11:01:17 +03:00
if ( s2mps11 - > ext_control_gpiod [ i ] ) {
2014-04-14 12:09:07 +04:00
ret = s2mps14_pmic_enable_ext_control ( s2mps11 ,
regulator ) ;
if ( ret < 0 ) {
dev_err ( & pdev - > dev ,
" failed to enable GPIO control over %s: %d \n " ,
regulator - > desc - > name , ret ) ;
goto out ;
}
}
2012-07-11 16:08:17 +04:00
}
2014-02-28 14:01:50 +04:00
out :
kfree ( rdata ) ;
return ret ;
2012-07-11 16:08:17 +04:00
}
static const struct platform_device_id s2mps11_pmic_id [ ] = {
2015-11-20 13:48:26 +03:00
{ " s2mps11-regulator " , S2MPS11X } ,
{ " s2mps13-regulator " , S2MPS13X } ,
{ " s2mps14-regulator " , S2MPS14X } ,
2015-11-20 13:37:52 +03:00
{ " s2mps15-regulator " , S2MPS15X } ,
2015-11-20 13:48:26 +03:00
{ " s2mpu02-regulator " , S2MPU02 } ,
2012-07-11 16:08:17 +04:00
{ } ,
} ;
MODULE_DEVICE_TABLE ( platform , s2mps11_pmic_id ) ;
static struct platform_driver s2mps11_pmic_driver = {
. driver = {
. name = " s2mps11-pmic " ,
} ,
. probe = s2mps11_pmic_probe ,
. id_table = s2mps11_pmic_id ,
} ;
2016-04-06 16:49:46 +03:00
module_platform_driver ( s2mps11_pmic_driver ) ;
2012-07-11 16:08:17 +04:00
/* Module information */
MODULE_AUTHOR ( " Sangbeom Kim <sbkim73@samsung.com> " ) ;
2015-11-20 13:37:52 +03:00
MODULE_DESCRIPTION ( " SAMSUNG S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver " ) ;
2012-07-11 16:08:17 +04:00
MODULE_LICENSE ( " GPL " ) ;