2011-12-09 18:18:20 +04:00
/*
* da9052 - regulator . c : Regulator driver for DA9052
*
* Copyright ( c ) 2011 Dialog Semiconductor Ltd .
*
* Author : David Dajun Chen < dchen @ diasemi . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
*/
# include <linux/module.h>
# include <linux/moduleparam.h>
# include <linux/init.h>
# include <linux/err.h>
# include <linux/platform_device.h>
# include <linux/regulator/driver.h>
# include <linux/regulator/machine.h>
2012-04-13 17:37:41 +04:00
# ifdef CONFIG_OF
2012-04-16 12:54:24 +04:00
# include <linux/of.h>
2012-04-13 17:37:41 +04:00
# include <linux/regulator/of_regulator.h>
# endif
2011-12-09 18:18:20 +04:00
# include <linux/mfd/da9052/da9052.h>
# include <linux/mfd/da9052/reg.h>
# include <linux/mfd/da9052/pdata.h>
/* Buck step size */
# define DA9052_BUCK_PERI_3uV_STEP 100000
# define DA9052_BUCK_PERI_REG_MAP_UPTO_3uV 24
# define DA9052_CONST_3uV 3000000
# define DA9052_MIN_UA 0
# define DA9052_MAX_UA 3
# define DA9052_CURRENT_RANGE 4
/* Bit masks */
# define DA9052_BUCK_ILIM_MASK_EVEN 0x0c
# define DA9052_BUCK_ILIM_MASK_ODD 0xc0
2012-03-15 15:58:39 +04:00
/* DA9052 REGULATOR IDs */
# define DA9052_ID_BUCK1 0
# define DA9052_ID_BUCK2 1
# define DA9052_ID_BUCK3 2
# define DA9052_ID_BUCK4 3
# define DA9052_ID_LDO1 4
# define DA9052_ID_LDO2 5
# define DA9052_ID_LDO3 6
# define DA9052_ID_LDO4 7
# define DA9052_ID_LDO5 8
# define DA9052_ID_LDO6 9
# define DA9052_ID_LDO7 10
# define DA9052_ID_LDO8 11
# define DA9052_ID_LDO9 12
# define DA9052_ID_LDO10 13
2011-12-09 18:18:20 +04:00
static const u32 da9052_current_limits [ 3 ] [ 4 ] = {
{ 700000 , 800000 , 1000000 , 1200000 } , /* DA9052-BC BUCKs */
{ 1600000 , 2000000 , 2400000 , 3000000 } , /* DA9053-AA/Bx BUCK-CORE */
{ 800000 , 1000000 , 1200000 , 1500000 } , /* DA9053-AA/Bx BUCK-PRO,
* BUCK - MEM and BUCK - PERI
*/
} ;
struct da9052_regulator_info {
struct regulator_desc reg_desc ;
int step_uV ;
int min_uV ;
int max_uV ;
2013-10-16 13:33:59 +04:00
unsigned char activate_bit ;
2011-12-09 18:18:20 +04:00
} ;
struct da9052_regulator {
struct da9052 * da9052 ;
struct da9052_regulator_info * info ;
struct regulator_dev * rdev ;
} ;
static int verify_range ( struct da9052_regulator_info * info ,
int min_uV , int max_uV )
{
if ( min_uV > info - > max_uV | | max_uV < info - > min_uV )
return - EINVAL ;
return 0 ;
}
static int da9052_dcdc_get_current_limit ( struct regulator_dev * rdev )
{
struct da9052_regulator * regulator = rdev_get_drvdata ( rdev ) ;
int offset = rdev_get_id ( rdev ) ;
int ret , row = 2 ;
ret = da9052_reg_read ( regulator - > da9052 , DA9052_BUCKA_REG + offset / 2 ) ;
if ( ret < 0 )
return ret ;
/* Determine the even or odd position of the buck current limit
* register field
*/
if ( offset % 2 = = 0 )
ret = ( ret & DA9052_BUCK_ILIM_MASK_EVEN ) > > 2 ;
else
ret = ( ret & DA9052_BUCK_ILIM_MASK_ODD ) > > 6 ;
/* Select the appropriate current limit range */
if ( regulator - > da9052 - > chip_id = = DA9052 )
row = 0 ;
else if ( offset = = 0 )
row = 1 ;
return da9052_current_limits [ row ] [ ret ] ;
}
static int da9052_dcdc_set_current_limit ( struct regulator_dev * rdev , int min_uA ,
int max_uA )
{
struct da9052_regulator * regulator = rdev_get_drvdata ( rdev ) ;
int offset = rdev_get_id ( rdev ) ;
int reg_val = 0 ;
int i , row = 2 ;
/* Select the appropriate current limit range */
if ( regulator - > da9052 - > chip_id = = DA9052 )
row = 0 ;
else if ( offset = = 0 )
row = 1 ;
2012-08-08 16:23:54 +04:00
for ( i = DA9052_CURRENT_RANGE - 1 ; i > = 0 ; i - - ) {
2012-11-26 11:23:38 +04:00
if ( ( min_uA < = da9052_current_limits [ row ] [ i ] ) & &
( da9052_current_limits [ row ] [ i ] < = max_uA ) ) {
2011-12-09 18:18:20 +04:00
reg_val = i ;
break ;
}
}
2012-11-26 11:23:38 +04:00
if ( i < 0 )
return - EINVAL ;
2011-12-09 18:18:20 +04:00
/* Determine the even or odd position of the buck current limit
* register field
*/
if ( offset % 2 = = 0 )
return da9052_reg_update ( regulator - > da9052 ,
DA9052_BUCKA_REG + offset / 2 ,
DA9052_BUCK_ILIM_MASK_EVEN ,
reg_val < < 2 ) ;
else
return da9052_reg_update ( regulator - > da9052 ,
DA9052_BUCKA_REG + offset / 2 ,
DA9052_BUCK_ILIM_MASK_ODD ,
reg_val < < 6 ) ;
}
static int da9052_list_voltage ( struct regulator_dev * rdev ,
unsigned int selector )
{
struct da9052_regulator * regulator = rdev_get_drvdata ( rdev ) ;
struct da9052_regulator_info * info = regulator - > info ;
2012-03-15 16:00:07 +04:00
int id = rdev_get_id ( rdev ) ;
2011-12-09 18:18:20 +04:00
int volt_uV ;
2012-03-15 16:00:07 +04:00
if ( ( id = = DA9052_ID_BUCK4 ) & & ( regulator - > da9052 - > chip_id = = DA9052 )
& & ( selector > = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV ) ) {
volt_uV = ( ( DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info - > step_uV )
+ info - > min_uV ) ;
volt_uV + = ( selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV )
* ( DA9052_BUCK_PERI_3uV_STEP ) ;
} else {
volt_uV = ( selector * info - > step_uV ) + info - > min_uV ;
}
2011-12-09 18:18:20 +04:00
if ( volt_uV > info - > max_uV )
return - EINVAL ;
return volt_uV ;
}
2012-05-16 09:12:35 +04:00
static int da9052_map_voltage ( struct regulator_dev * rdev ,
int min_uV , int max_uV )
2011-12-09 18:18:20 +04:00
{
struct da9052_regulator * regulator = rdev_get_drvdata ( rdev ) ;
struct da9052_regulator_info * info = regulator - > info ;
2012-03-15 16:00:07 +04:00
int id = rdev_get_id ( rdev ) ;
2012-05-16 09:12:35 +04:00
int ret , sel ;
2011-12-09 18:18:20 +04:00
ret = verify_range ( info , min_uV , max_uV ) ;
if ( ret < 0 )
return ret ;
if ( min_uV < info - > min_uV )
min_uV = info - > min_uV ;
2012-03-15 16:00:07 +04:00
if ( ( id = = DA9052_ID_BUCK4 ) & & ( regulator - > da9052 - > chip_id = = DA9052 )
& & ( min_uV > = DA9052_CONST_3uV ) ) {
2012-05-16 09:12:35 +04:00
sel = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
DIV_ROUND_UP ( min_uV - DA9052_CONST_3uV ,
DA9052_BUCK_PERI_3uV_STEP ) ;
2012-03-15 16:00:07 +04:00
} else {
2012-05-16 09:12:35 +04:00
sel = DIV_ROUND_UP ( min_uV - info - > min_uV , info - > step_uV ) ;
2012-03-15 16:00:07 +04:00
}
2011-12-09 18:18:20 +04:00
2012-05-16 09:12:35 +04:00
ret = da9052_list_voltage ( rdev , sel ) ;
2011-12-09 18:18:20 +04:00
if ( ret < 0 )
return ret ;
2012-05-16 09:12:35 +04:00
return sel ;
}
2013-10-16 13:33:59 +04:00
static int da9052_regulator_set_voltage_sel ( struct regulator_dev * rdev ,
unsigned int selector )
{
struct da9052_regulator * regulator = rdev_get_drvdata ( rdev ) ;
struct da9052_regulator_info * info = regulator - > info ;
int id = rdev_get_id ( rdev ) ;
int ret ;
ret = da9052_reg_update ( regulator - > da9052 , rdev - > desc - > vsel_reg ,
rdev - > desc - > vsel_mask , selector ) ;
if ( ret < 0 )
return ret ;
/* Some LDOs and DCDCs are DVC controlled which requires enabling of
* the activate bit to implment the changes on the output .
*/
switch ( id ) {
case DA9052_ID_BUCK1 :
case DA9052_ID_BUCK2 :
case DA9052_ID_BUCK3 :
case DA9052_ID_LDO2 :
case DA9052_ID_LDO3 :
ret = da9052_reg_update ( regulator - > da9052 , DA9052_SUPPLY_REG ,
info - > activate_bit , info - > activate_bit ) ;
break ;
}
return ret ;
}
2014-02-06 18:35:21 +04:00
static int da9052_regulator_set_voltage_time_sel ( struct regulator_dev * rdev ,
unsigned int old_sel ,
unsigned int new_sel )
{
struct da9052_regulator * regulator = rdev_get_drvdata ( rdev ) ;
struct da9052_regulator_info * info = regulator - > info ;
int id = rdev_get_id ( rdev ) ;
int ret = 0 ;
/* The DVC controlled LDOs and DCDCs ramp with 6.25mV/µs after enabling
* the activate bit .
*/
switch ( id ) {
case DA9052_ID_BUCK1 :
case DA9052_ID_BUCK2 :
case DA9052_ID_BUCK3 :
case DA9052_ID_LDO2 :
case DA9052_ID_LDO3 :
ret = ( new_sel - old_sel ) * info - > step_uV / 6250 ;
break ;
}
return ret ;
}
2015-12-19 18:07:09 +03:00
static const struct regulator_ops da9052_dcdc_ops = {
2011-12-09 18:18:20 +04:00
. get_current_limit = da9052_dcdc_get_current_limit ,
. set_current_limit = da9052_dcdc_set_current_limit ,
. list_voltage = da9052_list_voltage ,
2012-05-16 09:12:35 +04:00
. map_voltage = da9052_map_voltage ,
2012-04-24 05:54:38 +04:00
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
2013-10-16 13:33:59 +04:00
. set_voltage_sel = da9052_regulator_set_voltage_sel ,
2014-02-06 18:35:21 +04:00
. set_voltage_time_sel = da9052_regulator_set_voltage_time_sel ,
2012-04-17 07:34:32 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
2011-12-09 18:18:20 +04:00
} ;
2015-12-19 18:07:09 +03:00
static const struct regulator_ops da9052_ldo_ops = {
2011-12-09 18:18:20 +04:00
. list_voltage = da9052_list_voltage ,
2012-05-16 09:12:35 +04:00
. map_voltage = da9052_map_voltage ,
2012-04-24 05:54:38 +04:00
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
2013-10-16 13:33:59 +04:00
. set_voltage_sel = da9052_regulator_set_voltage_sel ,
2014-02-06 18:35:21 +04:00
. set_voltage_time_sel = da9052_regulator_set_voltage_time_sel ,
2012-04-17 07:34:32 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
2011-12-09 18:18:20 +04:00
} ;
# define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \
{ \
. reg_desc = { \
2012-03-15 15:58:39 +04:00
. name = # _id , \
2011-12-09 18:18:20 +04:00
. ops = & da9052_ldo_ops , \
. type = REGULATOR_VOLTAGE , \
2012-03-15 15:58:39 +04:00
. id = DA9052_ID_ # # _id , \
2012-03-05 16:04:32 +04:00
. n_voltages = ( max - min ) / step + 1 , \
2011-12-09 18:18:20 +04:00
. owner = THIS_MODULE , \
2012-04-24 05:54:38 +04:00
. vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_ # # _id , \
. vsel_mask = ( 1 < < ( sbits ) ) - 1 , \
2012-04-17 07:34:32 +04:00
. enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_ # # _id , \
. enable_mask = 1 < < ( ebits ) , \
2011-12-09 18:18:20 +04:00
} , \
. min_uV = ( min ) * 1000 , \
. max_uV = ( max ) * 1000 , \
. step_uV = ( step ) * 1000 , \
2013-10-16 13:33:59 +04:00
. activate_bit = ( abits ) , \
2011-12-09 18:18:20 +04:00
}
# define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \
{ \
. reg_desc = { \
2012-03-15 15:58:39 +04:00
. name = # _id , \
2011-12-09 18:18:20 +04:00
. ops = & da9052_dcdc_ops , \
. type = REGULATOR_VOLTAGE , \
2012-03-15 15:58:39 +04:00
. id = DA9052_ID_ # # _id , \
2012-03-05 16:04:32 +04:00
. n_voltages = ( max - min ) / step + 1 , \
2011-12-09 18:18:20 +04:00
. owner = THIS_MODULE , \
2012-04-24 05:54:38 +04:00
. vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_ # # _id , \
. vsel_mask = ( 1 < < ( sbits ) ) - 1 , \
2012-04-17 07:34:32 +04:00
. enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_ # # _id , \
. enable_mask = 1 < < ( ebits ) , \
2011-12-09 18:18:20 +04:00
} , \
. min_uV = ( min ) * 1000 , \
. max_uV = ( max ) * 1000 , \
. step_uV = ( step ) * 1000 , \
2013-10-16 13:33:59 +04:00
. activate_bit = ( abits ) , \
2011-12-09 18:18:20 +04:00
}
2011-12-20 13:12:00 +04:00
static struct da9052_regulator_info da9052_regulator_info [ ] = {
2012-03-15 15:58:39 +04:00
DA9052_DCDC ( BUCK1 , 25 , 500 , 2075 , 6 , 6 , DA9052_SUPPLY_VBCOREGO ) ,
DA9052_DCDC ( BUCK2 , 25 , 500 , 2075 , 6 , 6 , DA9052_SUPPLY_VBPROGO ) ,
regulator: da9053/52: Fix incorrectly stated minimum and maximum voltage limits
This fix alters the minimum and maximum BUCK voltage limits for DA9052 and
DA9053. It does so for the following cases:
DA9052
- BUCK3 (MEM)
min: 0.925V -> 0.950V
max: 2.500V -> 2.525V
DA9053
- BUCK3 (MEM)
min: 0.925V -> 0.950V
max: 2.500V -> 2.525V
- BUCK4 (PERI)
min: 0.925V -> 0.950V
max: 2.500V -> 2.525V
The voltage range remains the same, but the limits are shifted by +0.025V.
This change is provided on DA9052:MEM, DA9053:MEM and DA9053:PERI
and is a voltage difference of 0.025V, compared to those measured before
this fix is applied. The patch has the effect of decreasing *all* measured
voltages on those BUCKs when compared against the previously measured
values for the same software voltage request.
For example, with this fix applied for DA9052:MEM, DA9053:MEM and
DA9053:PERI, the following is true.
Because the previous software defined slot 0 as being 0.925V, if a request
for 0.950V was previously sent, the slot 1 voltage would have been used.
This would have corresponded to an actual measured voltage of 0.975V. But,
with this patch fix, and with slot 0 properly aligned to 0.950V, if a
voltage of 0.950V is requested by software, a measured value of 0.950V will
be provided.
Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2016-07-20 17:53:58 +03:00
DA9052_DCDC ( BUCK3 , 25 , 950 , 2525 , 6 , 6 , DA9052_SUPPLY_VBMEMGO ) ,
2012-03-15 16:00:07 +04:00
DA9052_DCDC ( BUCK4 , 50 , 1800 , 3600 , 5 , 6 , 0 ) ,
2012-03-15 15:58:39 +04:00
DA9052_LDO ( LDO1 , 50 , 600 , 1800 , 5 , 6 , 0 ) ,
2012-03-15 16:00:07 +04:00
DA9052_LDO ( LDO2 , 25 , 600 , 1800 , 6 , 6 , DA9052_SUPPLY_VLDO2GO ) ,
DA9052_LDO ( LDO3 , 25 , 1725 , 3300 , 6 , 6 , DA9052_SUPPLY_VLDO3GO ) ,
2012-03-15 15:58:39 +04:00
DA9052_LDO ( LDO4 , 25 , 1725 , 3300 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO5 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO6 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO7 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO8 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO9 , 50 , 1250 , 3650 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO10 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
2011-12-09 18:18:20 +04:00
} ;
2011-12-20 13:12:00 +04:00
static struct da9052_regulator_info da9053_regulator_info [ ] = {
2012-03-15 15:58:39 +04:00
DA9052_DCDC ( BUCK1 , 25 , 500 , 2075 , 6 , 6 , DA9052_SUPPLY_VBCOREGO ) ,
DA9052_DCDC ( BUCK2 , 25 , 500 , 2075 , 6 , 6 , DA9052_SUPPLY_VBPROGO ) ,
regulator: da9053/52: Fix incorrectly stated minimum and maximum voltage limits
This fix alters the minimum and maximum BUCK voltage limits for DA9052 and
DA9053. It does so for the following cases:
DA9052
- BUCK3 (MEM)
min: 0.925V -> 0.950V
max: 2.500V -> 2.525V
DA9053
- BUCK3 (MEM)
min: 0.925V -> 0.950V
max: 2.500V -> 2.525V
- BUCK4 (PERI)
min: 0.925V -> 0.950V
max: 2.500V -> 2.525V
The voltage range remains the same, but the limits are shifted by +0.025V.
This change is provided on DA9052:MEM, DA9053:MEM and DA9053:PERI
and is a voltage difference of 0.025V, compared to those measured before
this fix is applied. The patch has the effect of decreasing *all* measured
voltages on those BUCKs when compared against the previously measured
values for the same software voltage request.
For example, with this fix applied for DA9052:MEM, DA9053:MEM and
DA9053:PERI, the following is true.
Because the previous software defined slot 0 as being 0.925V, if a request
for 0.950V was previously sent, the slot 1 voltage would have been used.
This would have corresponded to an actual measured voltage of 0.975V. But,
with this patch fix, and with slot 0 properly aligned to 0.950V, if a
voltage of 0.950V is requested by software, a measured value of 0.950V will
be provided.
Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2016-07-20 17:53:58 +03:00
DA9052_DCDC ( BUCK3 , 25 , 950 , 2525 , 6 , 6 , DA9052_SUPPLY_VBMEMGO ) ,
DA9052_DCDC ( BUCK4 , 25 , 950 , 2525 , 6 , 6 , 0 ) ,
2012-03-15 15:58:39 +04:00
DA9052_LDO ( LDO1 , 50 , 600 , 1800 , 5 , 6 , 0 ) ,
2012-03-15 16:00:07 +04:00
DA9052_LDO ( LDO2 , 25 , 600 , 1800 , 6 , 6 , DA9052_SUPPLY_VLDO2GO ) ,
DA9052_LDO ( LDO3 , 25 , 1725 , 3300 , 6 , 6 , DA9052_SUPPLY_VLDO3GO ) ,
2012-03-15 15:58:39 +04:00
DA9052_LDO ( LDO4 , 25 , 1725 , 3300 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO5 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO6 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO7 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO8 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO9 , 50 , 1250 , 3650 , 6 , 6 , 0 ) ,
DA9052_LDO ( LDO10 , 50 , 1200 , 3600 , 6 , 6 , 0 ) ,
2011-12-09 18:18:20 +04:00
} ;
static inline struct da9052_regulator_info * find_regulator_info ( u8 chip_id ,
int id )
{
struct da9052_regulator_info * info ;
int i ;
2011-12-15 17:29:53 +04:00
switch ( chip_id ) {
case DA9052 :
2011-12-09 18:18:20 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( da9052_regulator_info ) ; i + + ) {
info = & da9052_regulator_info [ i ] ;
if ( info - > reg_desc . id = = id )
return info ;
}
2011-12-15 17:29:53 +04:00
break ;
case DA9053_AA :
case DA9053_BA :
case DA9053_BB :
2015-10-16 11:55:54 +03:00
case DA9053_BC :
2011-12-09 18:18:20 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( da9053_regulator_info ) ; i + + ) {
info = & da9053_regulator_info [ i ] ;
if ( info - > reg_desc . id = = id )
return info ;
}
2011-12-15 17:29:53 +04:00
break ;
2011-12-09 18:18:20 +04:00
}
return NULL ;
}
2012-11-19 22:22:22 +04:00
static int da9052_regulator_probe ( struct platform_device * pdev )
2011-12-09 18:18:20 +04:00
{
2015-05-15 17:27:40 +03:00
const struct mfd_cell * cell = mfd_get_cell ( pdev ) ;
2012-04-04 03:50:22 +04:00
struct regulator_config config = { } ;
2011-12-09 18:18:20 +04:00
struct da9052_regulator * regulator ;
struct da9052 * da9052 ;
struct da9052_pdata * pdata ;
2011-12-15 17:29:53 +04:00
regulator = devm_kzalloc ( & pdev - > dev , sizeof ( struct da9052_regulator ) ,
GFP_KERNEL ) ;
2011-12-09 18:18:20 +04:00
if ( ! regulator )
return - ENOMEM ;
da9052 = dev_get_drvdata ( pdev - > dev . parent ) ;
2013-07-30 12:20:47 +04:00
pdata = dev_get_platdata ( da9052 - > dev ) ;
2011-12-09 18:18:20 +04:00
regulator - > da9052 = da9052 ;
regulator - > info = find_regulator_info ( regulator - > da9052 - > chip_id ,
2015-05-15 17:27:40 +03:00
cell - > id ) ;
2011-12-09 18:18:20 +04:00
if ( regulator - > info = = NULL ) {
dev_err ( & pdev - > dev , " invalid regulator ID specified \n " ) ;
2012-04-05 08:08:58 +04:00
return - EINVAL ;
2011-12-09 18:18:20 +04:00
}
2012-04-04 03:50:22 +04:00
config . dev = & pdev - > dev ;
config . driver_data = regulator ;
2012-04-17 07:34:32 +04:00
config . regmap = da9052 - > regmap ;
2012-04-13 17:37:41 +04:00
if ( pdata & & pdata - > regulators ) {
2015-05-15 17:27:40 +03:00
config . init_data = pdata - > regulators [ cell - > id ] ;
2012-04-13 17:37:41 +04:00
} else {
# ifdef CONFIG_OF
2014-09-10 07:50:39 +04:00
struct device_node * nproot = da9052 - > dev - > of_node ;
struct device_node * np ;
2012-04-13 17:37:41 +04:00
if ( ! nproot )
return - ENODEV ;
2014-02-14 15:49:56 +04:00
nproot = of_get_child_by_name ( nproot , " regulators " ) ;
2012-04-13 17:37:41 +04:00
if ( ! nproot )
return - ENODEV ;
2012-07-07 05:46:45 +04:00
for_each_child_of_node ( nproot , np ) {
2012-04-13 17:37:41 +04:00
if ( ! of_node_cmp ( np - > name ,
regulator - > info - > reg_desc . name ) ) {
config . init_data = of_get_regulator_init_data (
2014-11-10 16:43:53 +03:00
& pdev - > dev , np ,
& regulator - > info - > reg_desc ) ;
2012-07-12 18:23:25 +04:00
config . of_node = np ;
2012-04-13 17:37:41 +04:00
break ;
}
}
2013-01-27 17:16:56 +04:00
of_node_put ( nproot ) ;
2012-04-13 17:37:41 +04:00
# endif
}
2012-04-04 03:50:22 +04:00
2013-09-03 10:24:46 +04:00
regulator - > rdev = devm_regulator_register ( & pdev - > dev ,
& regulator - > info - > reg_desc ,
& config ) ;
2011-12-09 18:18:20 +04:00
if ( IS_ERR ( regulator - > rdev ) ) {
dev_err ( & pdev - > dev , " failed to register regulator %s \n " ,
regulator - > info - > reg_desc . name ) ;
2012-04-05 08:08:58 +04:00
return PTR_ERR ( regulator - > rdev ) ;
2011-12-09 18:18:20 +04:00
}
platform_set_drvdata ( pdev , regulator ) ;
return 0 ;
}
static struct platform_driver da9052_regulator_driver = {
. probe = da9052_regulator_probe ,
. driver = {
. name = " da9052-regulator " ,
} ,
} ;
static int __init da9052_regulator_init ( void )
{
return platform_driver_register ( & da9052_regulator_driver ) ;
}
subsys_initcall ( da9052_regulator_init ) ;
static void __exit da9052_regulator_exit ( void )
{
platform_driver_unregister ( & da9052_regulator_driver ) ;
}
module_exit ( da9052_regulator_exit ) ;
MODULE_AUTHOR ( " David Dajun Chen <dchen@diasemi.com> " ) ;
MODULE_DESCRIPTION ( " Power Regulator driver for Dialog DA9052 PMIC " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " platform:da9052-regulator " ) ;