2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2009-10-08 10:03:57 +04:00
/*
* Regulators driver for Marvell 88 PM8607
*
* Copyright ( C ) 2009 Marvell International Ltd .
2014-02-26 05:22:05 +04:00
* Haojian Zhuang < haojian . zhuang @ marvell . com >
2009-10-08 10:03:57 +04:00
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/err.h>
2012-09-21 14:06:52 +04:00
# include <linux/of.h>
# include <linux/regulator/of_regulator.h>
2009-10-08 10:03:57 +04:00
# include <linux/platform_device.h>
# include <linux/regulator/driver.h>
# include <linux/regulator/machine.h>
2010-01-08 14:01:24 +03:00
# include <linux/mfd/88pm860x.h>
2011-07-18 00:28:23 +04:00
# include <linux/module.h>
2009-10-08 10:03:57 +04:00
struct pm8607_regulator_info {
struct regulator_desc desc ;
2010-05-04 17:54:51 +04:00
unsigned int * vol_suspend ;
2009-10-08 10:03:57 +04:00
int slope_double ;
} ;
2010-05-04 17:54:51 +04:00
static const unsigned int BUCK1_table [ ] = {
725000 , 750000 , 775000 , 800000 , 825000 , 850000 , 875000 , 900000 ,
925000 , 950000 , 975000 , 1000000 , 1025000 , 1050000 , 1075000 , 1100000 ,
1125000 , 1150000 , 1175000 , 1200000 , 1225000 , 1250000 , 1275000 , 1300000 ,
1325000 , 1350000 , 1375000 , 1400000 , 1425000 , 1450000 , 1475000 , 1500000 ,
0 , 25000 , 50000 , 75000 , 100000 , 125000 , 150000 , 175000 ,
200000 , 225000 , 250000 , 275000 , 300000 , 325000 , 350000 , 375000 ,
400000 , 425000 , 450000 , 475000 , 500000 , 525000 , 550000 , 575000 ,
600000 , 625000 , 650000 , 675000 , 700000 , 725000 , 750000 , 775000 ,
} ;
2009-10-08 10:03:57 +04:00
2010-05-04 17:54:51 +04:00
static const unsigned int BUCK1_suspend_table [ ] = {
0 , 25000 , 50000 , 75000 , 100000 , 125000 , 150000 , 175000 ,
200000 , 225000 , 250000 , 275000 , 300000 , 325000 , 350000 , 375000 ,
400000 , 425000 , 450000 , 475000 , 500000 , 525000 , 550000 , 575000 ,
600000 , 625000 , 650000 , 675000 , 700000 , 725000 , 750000 , 775000 ,
800000 , 825000 , 850000 , 875000 , 900000 , 925000 , 950000 , 975000 ,
1000000 , 1025000 , 1050000 , 1075000 , 1100000 , 1125000 , 1150000 , 1175000 ,
1200000 , 1225000 , 1250000 , 1275000 , 1300000 , 1325000 , 1350000 , 1375000 ,
1400000 , 1425000 , 1450000 , 1475000 , 1500000 , 1500000 , 1500000 , 1500000 ,
} ;
static const unsigned int BUCK2_table [ ] = {
0 , 50000 , 100000 , 150000 , 200000 , 250000 , 300000 , 350000 ,
400000 , 450000 , 500000 , 550000 , 600000 , 650000 , 700000 , 750000 ,
800000 , 850000 , 900000 , 950000 , 1000000 , 1050000 , 1100000 , 1150000 ,
1200000 , 1250000 , 1300000 , 1350000 , 1400000 , 1450000 , 1500000 , 1550000 ,
1600000 , 1650000 , 1700000 , 1750000 , 1800000 , 1850000 , 1900000 , 1950000 ,
2000000 , 2050000 , 2100000 , 2150000 , 2200000 , 2250000 , 2300000 , 2350000 ,
2400000 , 2450000 , 2500000 , 2550000 , 2600000 , 2650000 , 2700000 , 2750000 ,
2800000 , 2850000 , 2900000 , 2950000 , 3000000 , 3000000 , 3000000 , 3000000 ,
} ;
static const unsigned int BUCK2_suspend_table [ ] = {
0 , 50000 , 100000 , 150000 , 200000 , 250000 , 300000 , 350000 ,
400000 , 450000 , 500000 , 550000 , 600000 , 650000 , 700000 , 750000 ,
800000 , 850000 , 900000 , 950000 , 1000000 , 1050000 , 1100000 , 1150000 ,
1200000 , 1250000 , 1300000 , 1350000 , 1400000 , 1450000 , 1500000 , 1550000 ,
1600000 , 1650000 , 1700000 , 1750000 , 1800000 , 1850000 , 1900000 , 1950000 ,
2000000 , 2050000 , 2100000 , 2150000 , 2200000 , 2250000 , 2300000 , 2350000 ,
2400000 , 2450000 , 2500000 , 2550000 , 2600000 , 2650000 , 2700000 , 2750000 ,
2800000 , 2850000 , 2900000 , 2950000 , 3000000 , 3000000 , 3000000 , 3000000 ,
} ;
static const unsigned int BUCK3_table [ ] = {
2014-02-26 05:22:05 +04:00
0 , 25000 , 50000 , 75000 , 100000 , 125000 , 150000 , 175000 ,
2010-05-04 17:54:51 +04:00
200000 , 225000 , 250000 , 275000 , 300000 , 325000 , 350000 , 375000 ,
400000 , 425000 , 450000 , 475000 , 500000 , 525000 , 550000 , 575000 ,
600000 , 625000 , 650000 , 675000 , 700000 , 725000 , 750000 , 775000 ,
800000 , 825000 , 850000 , 875000 , 900000 , 925000 , 950000 , 975000 ,
1000000 , 1025000 , 1050000 , 1075000 , 1100000 , 1125000 , 1150000 , 1175000 ,
1200000 , 1225000 , 1250000 , 1275000 , 1300000 , 1325000 , 1350000 , 1375000 ,
1400000 , 1425000 , 1450000 , 1475000 , 1500000 , 1500000 , 1500000 , 1500000 ,
} ;
static const unsigned int BUCK3_suspend_table [ ] = {
2014-02-26 05:22:05 +04:00
0 , 25000 , 50000 , 75000 , 100000 , 125000 , 150000 , 175000 ,
2010-05-04 17:54:51 +04:00
200000 , 225000 , 250000 , 275000 , 300000 , 325000 , 350000 , 375000 ,
400000 , 425000 , 450000 , 475000 , 500000 , 525000 , 550000 , 575000 ,
600000 , 625000 , 650000 , 675000 , 700000 , 725000 , 750000 , 775000 ,
800000 , 825000 , 850000 , 875000 , 900000 , 925000 , 950000 , 975000 ,
1000000 , 1025000 , 1050000 , 1075000 , 1100000 , 1125000 , 1150000 , 1175000 ,
1200000 , 1225000 , 1250000 , 1275000 , 1300000 , 1325000 , 1350000 , 1375000 ,
1400000 , 1425000 , 1450000 , 1475000 , 1500000 , 1500000 , 1500000 , 1500000 ,
} ;
static const unsigned int LDO1_table [ ] = {
1800000 , 1200000 , 2800000 , 0 ,
} ;
static const unsigned int LDO1_suspend_table [ ] = {
1800000 , 1200000 , 0 , 0 ,
} ;
static const unsigned int LDO2_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 3300000 ,
} ;
static const unsigned int LDO2_suspend_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 ,
} ;
static const unsigned int LDO3_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 3300000 ,
} ;
static const unsigned int LDO3_suspend_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 ,
} ;
static const unsigned int LDO4_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2900000 , 3300000 ,
} ;
static const unsigned int LDO4_suspend_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2900000 , 2900000 ,
} ;
static const unsigned int LDO5_table [ ] = {
2900000 , 3000000 , 3100000 , 3300000 ,
} ;
static const unsigned int LDO5_suspend_table [ ] = {
2900000 , 0 , 0 , 0 ,
} ;
static const unsigned int LDO6_table [ ] = {
1800000 , 1850000 , 2600000 , 2650000 , 2700000 , 2750000 , 2800000 , 3300000 ,
} ;
static const unsigned int LDO6_suspend_table [ ] = {
1800000 , 1850000 , 2600000 , 2650000 , 2700000 , 2750000 , 2800000 , 2900000 ,
} ;
static const unsigned int LDO7_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 ,
} ;
static const unsigned int LDO7_suspend_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 ,
} ;
static const unsigned int LDO8_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 ,
} ;
static const unsigned int LDO8_suspend_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 ,
} ;
static const unsigned int LDO9_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 3300000 ,
} ;
static const unsigned int LDO9_suspend_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 ,
} ;
static const unsigned int LDO10_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 3300000 ,
1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 ,
} ;
static const unsigned int LDO10_suspend_table [ ] = {
1800000 , 1850000 , 1900000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 ,
1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 ,
} ;
static const unsigned int LDO12_table [ ] = {
1800000 , 1900000 , 2700000 , 2800000 , 2900000 , 3000000 , 3100000 , 3300000 ,
1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 ,
} ;
static const unsigned int LDO12_suspend_table [ ] = {
1800000 , 1900000 , 2700000 , 2800000 , 2900000 , 2900000 , 2900000 , 2900000 ,
1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 , 1200000 ,
} ;
static const unsigned int LDO13_table [ ] = {
2012-02-23 15:52:08 +04:00
1200000 , 1300000 , 1800000 , 2000000 , 2500000 , 2800000 , 3000000 , 0 ,
2010-05-04 17:54:51 +04:00
} ;
static const unsigned int LDO13_suspend_table [ ] = {
0 ,
} ;
static const unsigned int LDO14_table [ ] = {
1800000 , 1850000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 , 3300000 ,
} ;
static const unsigned int LDO14_suspend_table [ ] = {
1800000 , 1850000 , 2700000 , 2750000 , 2800000 , 2850000 , 2900000 , 2900000 ,
} ;
2009-10-08 10:03:57 +04:00
static int pm8607_list_voltage ( struct regulator_dev * rdev , unsigned index )
{
struct pm8607_regulator_info * info = rdev_get_drvdata ( rdev ) ;
2019-02-26 15:40:58 +03:00
int ret ;
ret = regulator_list_voltage_table ( rdev , index ) ;
if ( ret < 0 )
return ret ;
if ( info - > slope_double )
ret < < = 1 ;
2009-10-08 10:03:57 +04:00
return ret ;
}
2017-01-28 16:28:34 +03:00
static const struct regulator_ops pm8607_regulator_ops = {
2012-03-28 10:58:29 +04:00
. list_voltage = pm8607_list_voltage ,
2012-12-24 05:14:38 +04:00
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
2012-04-24 05:52:32 +04:00
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
2012-04-17 07:32:57 +04:00
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. is_enabled = regulator_is_enabled_regmap ,
2009-10-08 10:03:57 +04:00
} ;
2017-01-28 16:28:34 +03:00
static const struct regulator_ops pm8606_preg_ops = {
2013-03-05 10:16:58 +04:00
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. is_enabled = regulator_is_enabled_regmap ,
2012-09-17 08:19:06 +04:00
} ;
# define PM8606_PREG(ereg, ebit) \
{ \
. desc = { \
. name = " PREG " , \
2019-03-19 10:39:27 +03:00
. of_match = of_match_ptr ( " PREG " ) , \
. regulators_node = of_match_ptr ( " regulators " ) , \
2012-09-17 08:19:06 +04:00
. ops = & pm8606_preg_ops , \
. type = REGULATOR_CURRENT , \
. id = PM8606_ID_PREG , \
. owner = THIS_MODULE , \
. enable_reg = PM8606_ # # ereg , \
. enable_mask = ( ebit ) , \
2013-03-05 10:16:58 +04:00
. enable_is_inverted = true , \
2012-09-17 08:19:06 +04:00
} , \
}
2012-03-28 10:59:23 +04:00
# define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \
2009-10-08 10:03:57 +04:00
{ \
. desc = { \
2010-05-04 17:54:51 +04:00
. name = # vreg , \
2019-03-19 10:39:27 +03:00
. of_match = of_match_ptr ( # vreg ) , \
. regulators_node = of_match_ptr ( " regulators " ) , \
2009-10-08 10:03:57 +04:00
. ops = & pm8607_regulator_ops , \
. type = REGULATOR_VOLTAGE , \
2010-05-04 17:54:51 +04:00
. id = PM8607_ID_ # # vreg , \
2009-10-08 10:03:57 +04:00
. owner = THIS_MODULE , \
2019-02-26 15:40:58 +03:00
. volt_table = vreg # # _table , \
2012-03-28 10:59:23 +04:00
. n_voltages = ARRAY_SIZE ( vreg # # _table ) , \
2012-04-24 05:52:32 +04:00
. vsel_reg = PM8607_ # # vreg , \
. vsel_mask = ARRAY_SIZE ( vreg # # _table ) - 1 , \
2012-12-24 05:14:38 +04:00
. apply_reg = PM8607_ # # ureg , \
. apply_bit = ( ubit ) , \
2012-04-17 07:32:57 +04:00
. enable_reg = PM8607_ # # ereg , \
. enable_mask = 1 < < ( ebit ) , \
2009-10-08 10:03:57 +04:00
} , \
. slope_double = ( 0 ) , \
2010-05-04 17:54:51 +04:00
. vol_suspend = ( unsigned int * ) & vreg # # _suspend_table , \
2009-10-08 10:03:57 +04:00
}
2012-03-28 10:59:23 +04:00
# define PM8607_LDO(_id, vreg, shift, ereg, ebit) \
2009-10-08 10:03:57 +04:00
{ \
. desc = { \
. name = " LDO " # _id , \
2019-03-19 10:39:27 +03:00
. of_match = of_match_ptr ( " LDO " # _id ) , \
. regulators_node = of_match_ptr ( " regulators " ) , \
2009-10-08 10:03:57 +04:00
. ops = & pm8607_regulator_ops , \
. type = REGULATOR_VOLTAGE , \
. id = PM8607_ID_LDO # # _id , \
. owner = THIS_MODULE , \
2019-02-26 15:40:58 +03:00
. volt_table = LDO # # _id # # _table , \
2012-03-28 10:59:23 +04:00
. n_voltages = ARRAY_SIZE ( LDO # # _id # # _table ) , \
2012-04-24 05:52:32 +04:00
. vsel_reg = PM8607_ # # vreg , \
. vsel_mask = ( ARRAY_SIZE ( LDO # # _id # # _table ) - 1 ) < < ( shift ) , \
2012-04-17 07:32:57 +04:00
. enable_reg = PM8607_ # # ereg , \
. enable_mask = 1 < < ( ebit ) , \
2009-10-08 10:03:57 +04:00
} , \
. slope_double = ( 0 ) , \
2010-05-04 17:54:51 +04:00
. vol_suspend = ( unsigned int * ) & LDO # # _id # # _suspend_table , \
2009-10-08 10:03:57 +04:00
}
static struct pm8607_regulator_info pm8607_regulator_info [ ] = {
2012-12-24 05:14:38 +04:00
PM8607_DVC ( BUCK1 , GO , BIT ( 0 ) , SUPPLIES_EN11 , 0 ) ,
PM8607_DVC ( BUCK2 , GO , BIT ( 1 ) , SUPPLIES_EN11 , 1 ) ,
PM8607_DVC ( BUCK3 , GO , BIT ( 2 ) , SUPPLIES_EN11 , 2 ) ,
2012-03-28 10:59:23 +04:00
PM8607_LDO ( 1 , LDO1 , 0 , SUPPLIES_EN11 , 3 ) ,
PM8607_LDO ( 2 , LDO2 , 0 , SUPPLIES_EN11 , 4 ) ,
PM8607_LDO ( 3 , LDO3 , 0 , SUPPLIES_EN11 , 5 ) ,
PM8607_LDO ( 4 , LDO4 , 0 , SUPPLIES_EN11 , 6 ) ,
PM8607_LDO ( 5 , LDO5 , 0 , SUPPLIES_EN11 , 7 ) ,
PM8607_LDO ( 6 , LDO6 , 0 , SUPPLIES_EN12 , 0 ) ,
PM8607_LDO ( 7 , LDO7 , 0 , SUPPLIES_EN12 , 1 ) ,
PM8607_LDO ( 8 , LDO8 , 0 , SUPPLIES_EN12 , 2 ) ,
PM8607_LDO ( 9 , LDO9 , 0 , SUPPLIES_EN12 , 3 ) ,
PM8607_LDO ( 10 , LDO10 , 0 , SUPPLIES_EN12 , 4 ) ,
PM8607_LDO ( 12 , LDO12 , 0 , SUPPLIES_EN12 , 5 ) ,
PM8607_LDO ( 13 , VIBRATOR_SET , 1 , VIBRATOR_SET , 0 ) ,
PM8607_LDO ( 14 , LDO14 , 0 , SUPPLIES_EN12 , 6 ) ,
2012-09-17 08:19:07 +04:00
} ;
2012-09-17 08:19:06 +04:00
2012-09-17 08:19:07 +04:00
static struct pm8607_regulator_info pm8606_regulator_info [ ] = {
2012-09-17 08:19:06 +04:00
PM8606_PREG ( PREREGULATORB , 5 ) ,
2009-10-08 10:03:57 +04:00
} ;
2012-11-19 22:22:22 +04:00
static int pm8607_regulator_probe ( struct platform_device * pdev )
2009-10-08 10:03:57 +04:00
{
2011-03-07 18:43:11 +03:00
struct pm860x_chip * chip = dev_get_drvdata ( pdev - > dev . parent ) ;
struct pm8607_regulator_info * info = NULL ;
2013-07-30 12:20:47 +04:00
struct regulator_init_data * pdata = dev_get_platdata ( & pdev - > dev ) ;
2012-04-04 03:50:22 +04:00
struct regulator_config config = { } ;
2019-02-26 15:40:59 +03:00
struct regulator_dev * rdev ;
2011-05-06 13:21:23 +04:00
struct resource * res ;
2009-10-08 10:03:57 +04:00
int i ;
2012-08-07 22:42:48 +04:00
res = platform_get_resource ( pdev , IORESOURCE_REG , 0 ) ;
2012-09-17 08:19:07 +04:00
if ( res ) {
/* There're resources in 88PM8607 regulator driver */
for ( i = 0 ; i < ARRAY_SIZE ( pm8607_regulator_info ) ; i + + ) {
info = & pm8607_regulator_info [ i ] ;
if ( info - > desc . vsel_reg = = res - > start )
break ;
}
if ( i = = ARRAY_SIZE ( pm8607_regulator_info ) ) {
dev_err ( & pdev - > dev , " Failed to find regulator %llu \n " ,
( unsigned long long ) res - > start ) ;
return - EINVAL ;
}
} else {
/* There's no resource in 88PM8606 PREG regulator driver */
info = & pm8606_regulator_info [ 0 ] ;
/* i is used to check regulator ID */
i = - 1 ;
2009-10-08 10:03:57 +04:00
}
2011-03-07 18:43:11 +03:00
/* check DVC ramp slope double */
2019-02-26 15:40:59 +03:00
if ( ( i = = PM8607_ID_BUCK3 ) & & chip - > buck3_double )
2011-05-06 13:21:23 +04:00
info - > slope_double = 1 ;
2011-03-07 18:43:11 +03:00
2019-03-19 10:39:27 +03:00
config . dev = chip - > dev ;
2012-04-04 03:50:22 +04:00
config . driver_data = info ;
2019-03-19 10:39:27 +03:00
if ( pdata )
config . init_data = pdata ;
2012-09-21 14:06:52 +04:00
2012-04-17 07:32:57 +04:00
if ( chip - > id = = CHIP_PM8607 )
config . regmap = chip - > regmap ;
else
config . regmap = chip - > regmap_companion ;
2019-02-26 15:40:59 +03:00
rdev = devm_regulator_register ( & pdev - > dev , & info - > desc , & config ) ;
if ( IS_ERR ( rdev ) ) {
2009-10-08 10:03:57 +04:00
dev_err ( & pdev - > dev , " failed to register regulator %s \n " ,
info - > desc . name ) ;
2019-02-26 15:40:59 +03:00
return PTR_ERR ( rdev ) ;
2009-10-08 10:03:57 +04:00
}
platform_set_drvdata ( pdev , info ) ;
return 0 ;
}
2015-05-01 18:45:05 +03:00
static const struct platform_device_id pm8607_regulator_driver_ids [ ] = {
2012-09-17 08:19:06 +04:00
{
. name = " 88pm860x-regulator " ,
. driver_data = 0 ,
} , {
. name = " 88pm860x-preg " ,
. driver_data = 0 ,
} ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( platform , pm8607_regulator_driver_ids ) ;
2010-04-29 21:33:50 +04:00
static struct platform_driver pm8607_regulator_driver = {
. driver = {
. name = " 88pm860x-regulator " ,
} ,
. probe = pm8607_regulator_probe ,
2012-09-17 08:19:06 +04:00
. id_table = pm8607_regulator_driver_ids ,
2009-10-08 10:03:57 +04:00
} ;
static int __init pm8607_regulator_init ( void )
{
2010-04-29 21:33:50 +04:00
return platform_driver_register ( & pm8607_regulator_driver ) ;
2009-10-08 10:03:57 +04:00
}
subsys_initcall ( pm8607_regulator_init ) ;
static void __exit pm8607_regulator_exit ( void )
{
2010-04-29 21:33:50 +04:00
platform_driver_unregister ( & pm8607_regulator_driver ) ;
2009-10-08 10:03:57 +04:00
}
module_exit ( pm8607_regulator_exit ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Haojian Zhuang <haojian.zhuang@marvell.com> " ) ;
MODULE_DESCRIPTION ( " Regulator Driver for Marvell 88PM8607 PMIC " ) ;
MODULE_ALIAS ( " platform:88pm8607-regulator " ) ;