2010-07-13 20:18:56 +04:00
/*
* Copyright ( C ) ST - Ericsson SA 2010
*
* License Terms : GNU General Public License v2
*
2010-12-10 13:08:44 +03:00
* Authors : Sundar Iyer < sundar . iyer @ stericsson . com > for ST - Ericsson
* Bengt Jonsson < bengt . g . jonsson @ stericsson . com > for ST - Ericsson
2010-07-13 20:18:56 +04:00
*
* AB8500 peripheral regulators
*
2010-12-10 13:08:44 +03:00
* AB8500 supports the following regulators :
* VAUX1 / 2 / 3 , VINTCORE , VTVOUT , VAUDIO , VAMIC1 / 2 , VDMIC , VANA
2010-07-13 20:18:56 +04:00
*/
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/err.h>
# include <linux/platform_device.h>
# include <linux/mfd/ab8500.h>
2010-09-10 19:47:56 +04:00
# include <linux/mfd/abx500.h>
2010-07-13 20:18:56 +04:00
# include <linux/regulator/driver.h>
# include <linux/regulator/machine.h>
# include <linux/regulator/ab8500.h>
/**
* struct ab8500_regulator_info - ab8500 regulator information
2010-12-10 13:08:44 +03:00
* @ dev : device pointer
2010-07-13 20:18:56 +04:00
* @ desc : regulator description
* @ regulator_dev : regulator device
* @ max_uV : maximum voltage ( for variable voltage supplies )
* @ min_uV : minimum voltage ( for variable voltage supplies )
* @ fixed_uV : typical voltage ( for fixed voltage supplies )
2010-09-10 19:47:56 +04:00
* @ update_bank : bank to control on / off
2010-07-13 20:18:56 +04:00
* @ update_reg : register to control on / off
2010-12-10 13:08:44 +03:00
* @ update_mask : mask to enable / disable regulator
* @ update_val_enable : bits to enable the regulator in normal ( high power ) mode
2010-09-10 19:47:56 +04:00
* @ voltage_bank : bank to control regulator voltage
2010-07-13 20:18:56 +04:00
* @ voltage_reg : register to control regulator voltage
* @ voltage_mask : mask to control regulator voltage
2010-12-10 13:08:44 +03:00
* @ voltages : supported voltage table
2010-07-13 20:18:56 +04:00
* @ voltages_len : number of supported voltages for the regulator
*/
struct ab8500_regulator_info {
struct device * dev ;
struct regulator_desc desc ;
struct regulator_dev * regulator ;
int max_uV ;
int min_uV ;
int fixed_uV ;
2010-09-10 19:47:56 +04:00
u8 update_bank ;
u8 update_reg ;
2010-12-10 13:08:44 +03:00
u8 update_mask ;
u8 update_val_enable ;
2010-09-10 19:47:56 +04:00
u8 voltage_bank ;
u8 voltage_reg ;
u8 voltage_mask ;
2010-12-10 13:08:44 +03:00
int const * voltages ;
2010-07-13 20:18:56 +04:00
int voltages_len ;
} ;
/* voltage tables for the vauxn/vintcore supplies */
static const int ldo_vauxn_voltages [ ] = {
1100000 ,
1200000 ,
1300000 ,
1400000 ,
1500000 ,
1800000 ,
1850000 ,
1900000 ,
2500000 ,
2650000 ,
2700000 ,
2750000 ,
2800000 ,
2900000 ,
3000000 ,
3300000 ,
} ;
2010-12-10 13:08:43 +03:00
static const int ldo_vaux3_voltages [ ] = {
1200000 ,
1500000 ,
1800000 ,
2100000 ,
2500000 ,
2750000 ,
2790000 ,
2910000 ,
} ;
2010-07-13 20:18:56 +04:00
static const int ldo_vintcore_voltages [ ] = {
1200000 ,
1225000 ,
1250000 ,
1275000 ,
1300000 ,
1325000 ,
1350000 ,
} ;
static int ab8500_regulator_enable ( struct regulator_dev * rdev )
{
2010-12-10 13:08:45 +03:00
int ret ;
2010-07-13 20:18:56 +04:00
struct ab8500_regulator_info * info = rdev_get_drvdata ( rdev ) ;
2010-12-10 13:08:45 +03:00
if ( info = = NULL ) {
dev_err ( rdev_get_dev ( rdev ) , " regulator info null pointer \n " ) ;
2010-07-13 20:18:56 +04:00
return - EINVAL ;
2010-12-10 13:08:45 +03:00
}
2010-07-13 20:18:56 +04:00
2010-09-10 19:47:56 +04:00
ret = abx500_mask_and_set_register_interruptible ( info - > dev ,
2010-12-10 13:08:44 +03:00
info - > update_bank , info - > update_reg ,
info - > update_mask , info - > update_val_enable ) ;
2010-07-13 20:18:56 +04:00
if ( ret < 0 )
dev_err ( rdev_get_dev ( rdev ) ,
" couldn't set enable bits for regulator \n " ) ;
2010-12-10 13:08:46 +03:00
dev_vdbg ( rdev_get_dev ( rdev ) ,
" %s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x \n " ,
info - > desc . name , info - > update_bank , info - > update_reg ,
info - > update_mask , info - > update_val_enable ) ;
2010-07-13 20:18:56 +04:00
return ret ;
}
static int ab8500_regulator_disable ( struct regulator_dev * rdev )
{
2010-12-10 13:08:45 +03:00
int ret ;
2010-07-13 20:18:56 +04:00
struct ab8500_regulator_info * info = rdev_get_drvdata ( rdev ) ;
2010-12-10 13:08:45 +03:00
if ( info = = NULL ) {
dev_err ( rdev_get_dev ( rdev ) , " regulator info null pointer \n " ) ;
2010-07-13 20:18:56 +04:00
return - EINVAL ;
2010-12-10 13:08:45 +03:00
}
2010-07-13 20:18:56 +04:00
2010-09-10 19:47:56 +04:00
ret = abx500_mask_and_set_register_interruptible ( info - > dev ,
2010-12-10 13:08:44 +03:00
info - > update_bank , info - > update_reg ,
info - > update_mask , 0x0 ) ;
2010-07-13 20:18:56 +04:00
if ( ret < 0 )
dev_err ( rdev_get_dev ( rdev ) ,
" couldn't set disable bits for regulator \n " ) ;
2010-12-10 13:08:46 +03:00
dev_vdbg ( rdev_get_dev ( rdev ) ,
" %s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x \n " ,
info - > desc . name , info - > update_bank , info - > update_reg ,
info - > update_mask , 0x0 ) ;
2010-07-13 20:18:56 +04:00
return ret ;
}
static int ab8500_regulator_is_enabled ( struct regulator_dev * rdev )
{
2010-12-10 13:08:45 +03:00
int ret ;
2010-07-13 20:18:56 +04:00
struct ab8500_regulator_info * info = rdev_get_drvdata ( rdev ) ;
2010-12-10 13:08:46 +03:00
u8 regval ;
2010-07-13 20:18:56 +04:00
2010-12-10 13:08:45 +03:00
if ( info = = NULL ) {
dev_err ( rdev_get_dev ( rdev ) , " regulator info null pointer \n " ) ;
2010-07-13 20:18:56 +04:00
return - EINVAL ;
2010-12-10 13:08:45 +03:00
}
2010-07-13 20:18:56 +04:00
2010-09-10 19:47:56 +04:00
ret = abx500_get_register_interruptible ( info - > dev ,
2010-12-10 13:08:46 +03:00
info - > update_bank , info - > update_reg , & regval ) ;
2010-07-13 20:18:56 +04:00
if ( ret < 0 ) {
dev_err ( rdev_get_dev ( rdev ) ,
" couldn't read 0x%x register \n " , info - > update_reg ) ;
return ret ;
}
2010-12-10 13:08:46 +03:00
dev_vdbg ( rdev_get_dev ( rdev ) ,
" %s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, "
" 0x%x \n " ,
info - > desc . name , info - > update_bank , info - > update_reg ,
info - > update_mask , regval ) ;
if ( regval & info - > update_mask )
2010-07-13 20:18:56 +04:00
return true ;
else
return false ;
}
static int ab8500_list_voltage ( struct regulator_dev * rdev , unsigned selector )
{
struct ab8500_regulator_info * info = rdev_get_drvdata ( rdev ) ;
2010-12-10 13:08:45 +03:00
if ( info = = NULL ) {
dev_err ( rdev_get_dev ( rdev ) , " regulator info null pointer \n " ) ;
2010-07-13 20:18:56 +04:00
return - EINVAL ;
2010-12-10 13:08:45 +03:00
}
2010-07-13 20:18:56 +04:00
/* return the uV for the fixed regulators */
if ( info - > fixed_uV )
return info - > fixed_uV ;
2010-09-04 19:06:41 +04:00
if ( selector > = info - > voltages_len )
2010-07-13 20:18:56 +04:00
return - EINVAL ;
2010-12-10 13:08:44 +03:00
return info - > voltages [ selector ] ;
2010-07-13 20:18:56 +04:00
}
static int ab8500_regulator_get_voltage ( struct regulator_dev * rdev )
{
2010-12-10 13:08:46 +03:00
int ret , val ;
2010-07-13 20:18:56 +04:00
struct ab8500_regulator_info * info = rdev_get_drvdata ( rdev ) ;
2010-12-10 13:08:46 +03:00
u8 regval ;
2010-07-13 20:18:56 +04:00
2010-12-10 13:08:45 +03:00
if ( info = = NULL ) {
dev_err ( rdev_get_dev ( rdev ) , " regulator info null pointer \n " ) ;
2010-07-13 20:18:56 +04:00
return - EINVAL ;
2010-12-10 13:08:45 +03:00
}
2010-07-13 20:18:56 +04:00
2010-12-10 13:08:46 +03:00
ret = abx500_get_register_interruptible ( info - > dev ,
info - > voltage_bank , info - > voltage_reg , & regval ) ;
2010-07-13 20:18:56 +04:00
if ( ret < 0 ) {
dev_err ( rdev_get_dev ( rdev ) ,
" couldn't read voltage reg for regulator \n " ) ;
return ret ;
}
2010-12-10 13:08:46 +03:00
dev_vdbg ( rdev_get_dev ( rdev ) ,
" %s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, "
" 0x%x \n " ,
info - > desc . name , info - > voltage_bank , info - > voltage_reg ,
info - > voltage_mask , regval ) ;
2010-07-13 20:18:56 +04:00
/* vintcore has a different layout */
2010-12-10 13:08:46 +03:00
val = regval & info - > voltage_mask ;
2010-12-10 13:08:45 +03:00
if ( info - > desc . id = = AB8500_LDO_INTCORE )
2010-12-10 13:08:46 +03:00
ret = info - > voltages [ val > > 0x3 ] ;
2010-07-13 20:18:56 +04:00
else
2010-12-10 13:08:46 +03:00
ret = info - > voltages [ val ] ;
2010-07-13 20:18:56 +04:00
return ret ;
}
static int ab8500_get_best_voltage_index ( struct regulator_dev * rdev ,
int min_uV , int max_uV )
{
struct ab8500_regulator_info * info = rdev_get_drvdata ( rdev ) ;
int i ;
/* check the supported voltage */
for ( i = 0 ; i < info - > voltages_len ; i + + ) {
2010-12-10 13:08:44 +03:00
if ( ( info - > voltages [ i ] > = min_uV ) & &
( info - > voltages [ i ] < = max_uV ) )
2010-07-13 20:18:56 +04:00
return i ;
}
return - EINVAL ;
}
static int ab8500_regulator_set_voltage ( struct regulator_dev * rdev ,
2010-11-10 17:38:29 +03:00
int min_uV , int max_uV ,
unsigned * selector )
2010-07-13 20:18:56 +04:00
{
2010-12-10 13:08:45 +03:00
int ret ;
2010-07-13 20:18:56 +04:00
struct ab8500_regulator_info * info = rdev_get_drvdata ( rdev ) ;
2010-12-10 13:08:46 +03:00
u8 regval ;
2010-07-13 20:18:56 +04:00
2010-12-10 13:08:45 +03:00
if ( info = = NULL ) {
dev_err ( rdev_get_dev ( rdev ) , " regulator info null pointer \n " ) ;
2010-07-13 20:18:56 +04:00
return - EINVAL ;
2010-12-10 13:08:45 +03:00
}
2010-07-13 20:18:56 +04:00
/* get the appropriate voltages within the range */
ret = ab8500_get_best_voltage_index ( rdev , min_uV , max_uV ) ;
if ( ret < 0 ) {
dev_err ( rdev_get_dev ( rdev ) ,
" couldn't get best voltage for regulator \n " ) ;
return ret ;
}
2010-11-10 17:38:29 +03:00
* selector = ret ;
2010-07-13 20:18:56 +04:00
/* set the registers for the request */
2010-12-10 13:08:46 +03:00
regval = ( u8 ) ret ;
2010-09-10 19:47:56 +04:00
ret = abx500_mask_and_set_register_interruptible ( info - > dev ,
2010-12-10 13:08:46 +03:00
info - > voltage_bank , info - > voltage_reg ,
info - > voltage_mask , regval ) ;
2010-07-13 20:18:56 +04:00
if ( ret < 0 )
dev_err ( rdev_get_dev ( rdev ) ,
" couldn't set voltage reg for regulator \n " ) ;
2010-12-10 13:08:46 +03:00
dev_vdbg ( rdev_get_dev ( rdev ) ,
" %s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, "
" 0x%x \n " ,
info - > desc . name , info - > voltage_bank , info - > voltage_reg ,
info - > voltage_mask , regval ) ;
2010-07-13 20:18:56 +04:00
return ret ;
}
static struct regulator_ops ab8500_regulator_ops = {
. enable = ab8500_regulator_enable ,
. disable = ab8500_regulator_disable ,
. is_enabled = ab8500_regulator_is_enabled ,
. get_voltage = ab8500_regulator_get_voltage ,
. set_voltage = ab8500_regulator_set_voltage ,
. list_voltage = ab8500_list_voltage ,
} ;
static int ab8500_fixed_get_voltage ( struct regulator_dev * rdev )
{
struct ab8500_regulator_info * info = rdev_get_drvdata ( rdev ) ;
2010-12-10 13:08:45 +03:00
if ( info = = NULL ) {
dev_err ( rdev_get_dev ( rdev ) , " regulator info null pointer \n " ) ;
2010-07-13 20:18:56 +04:00
return - EINVAL ;
2010-12-10 13:08:45 +03:00
}
2010-07-13 20:18:56 +04:00
return info - > fixed_uV ;
}
2010-12-10 13:08:47 +03:00
static struct regulator_ops ab8500_regulator_fixed_ops = {
2010-07-13 20:18:56 +04:00
. enable = ab8500_regulator_enable ,
. disable = ab8500_regulator_disable ,
. is_enabled = ab8500_regulator_is_enabled ,
. get_voltage = ab8500_fixed_get_voltage ,
. list_voltage = ab8500_list_voltage ,
} ;
2010-12-10 13:08:47 +03:00
static struct ab8500_regulator_info
ab8500_regulator_info [ AB8500_NUM_REGULATORS ] = {
2010-07-13 20:18:56 +04:00
/*
2010-12-10 13:08:44 +03:00
* Variable Voltage Regulators
* name , min mV , max mV ,
* update bank , reg , mask , enable val
* volt bank , reg , mask , table , table length
2010-07-13 20:18:56 +04:00
*/
2010-12-10 13:08:47 +03:00
[ AB8500_LDO_AUX1 ] = {
. desc = {
. name = " LDO-AUX1 " ,
. ops = & ab8500_regulator_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_AUX1 ,
. owner = THIS_MODULE ,
. n_voltages = ARRAY_SIZE ( ldo_vauxn_voltages ) ,
} ,
. min_uV = 1100000 ,
. max_uV = 3300000 ,
. update_bank = 0x04 ,
. update_reg = 0x09 ,
. update_mask = 0x03 ,
. update_val_enable = 0x01 ,
. voltage_bank = 0x04 ,
. voltage_reg = 0x1f ,
. voltage_mask = 0x0f ,
. voltages = ldo_vauxn_voltages ,
. voltages_len = ARRAY_SIZE ( ldo_vauxn_voltages ) ,
} ,
[ AB8500_LDO_AUX2 ] = {
. desc = {
. name = " LDO-AUX2 " ,
. ops = & ab8500_regulator_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_AUX2 ,
. owner = THIS_MODULE ,
. n_voltages = ARRAY_SIZE ( ldo_vauxn_voltages ) ,
} ,
. min_uV = 1100000 ,
. max_uV = 3300000 ,
. update_bank = 0x04 ,
. update_reg = 0x09 ,
. update_mask = 0x0c ,
. update_val_enable = 0x04 ,
. voltage_bank = 0x04 ,
. voltage_reg = 0x20 ,
. voltage_mask = 0x0f ,
. voltages = ldo_vauxn_voltages ,
. voltages_len = ARRAY_SIZE ( ldo_vauxn_voltages ) ,
} ,
[ AB8500_LDO_AUX3 ] = {
. desc = {
. name = " LDO-AUX3 " ,
. ops = & ab8500_regulator_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_AUX3 ,
. owner = THIS_MODULE ,
. n_voltages = ARRAY_SIZE ( ldo_vaux3_voltages ) ,
} ,
. min_uV = 1100000 ,
. max_uV = 3300000 ,
. update_bank = 0x04 ,
. update_reg = 0x0a ,
. update_mask = 0x03 ,
. update_val_enable = 0x01 ,
. voltage_bank = 0x04 ,
. voltage_reg = 0x21 ,
. voltage_mask = 0x07 ,
. voltages = ldo_vaux3_voltages ,
. voltages_len = ARRAY_SIZE ( ldo_vaux3_voltages ) ,
} ,
[ AB8500_LDO_INTCORE ] = {
. desc = {
. name = " LDO-INTCORE " ,
. ops = & ab8500_regulator_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_INTCORE ,
. owner = THIS_MODULE ,
. n_voltages = ARRAY_SIZE ( ldo_vintcore_voltages ) ,
} ,
. min_uV = 1100000 ,
. max_uV = 3300000 ,
. update_bank = 0x03 ,
. update_reg = 0x80 ,
. update_mask = 0x44 ,
. update_val_enable = 0x04 ,
. voltage_bank = 0x03 ,
. voltage_reg = 0x80 ,
. voltage_mask = 0x38 ,
. voltages = ldo_vintcore_voltages ,
. voltages_len = ARRAY_SIZE ( ldo_vintcore_voltages ) ,
} ,
2010-07-13 20:18:56 +04:00
/*
2010-12-10 13:08:44 +03:00
* Fixed Voltage Regulators
* name , fixed mV ,
* update bank , reg , mask , enable val
2010-07-13 20:18:56 +04:00
*/
2010-12-10 13:08:47 +03:00
[ AB8500_LDO_TVOUT ] = {
. desc = {
. name = " LDO-TVOUT " ,
. ops = & ab8500_regulator_fixed_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_TVOUT ,
. owner = THIS_MODULE ,
. n_voltages = 1 ,
} ,
. fixed_uV = 2000000 ,
. update_bank = 0x03 ,
. update_reg = 0x80 ,
. update_mask = 0x82 ,
. update_val_enable = 0x02 ,
} ,
[ AB8500_LDO_AUDIO ] = {
. desc = {
. name = " LDO-AUDIO " ,
. ops = & ab8500_regulator_fixed_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_AUDIO ,
. owner = THIS_MODULE ,
. n_voltages = 1 ,
} ,
. fixed_uV = 2000000 ,
. update_bank = 0x03 ,
. update_reg = 0x83 ,
. update_mask = 0x02 ,
. update_val_enable = 0x02 ,
} ,
[ AB8500_LDO_ANAMIC1 ] = {
. desc = {
. name = " LDO-ANAMIC1 " ,
. ops = & ab8500_regulator_fixed_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_ANAMIC1 ,
. owner = THIS_MODULE ,
. n_voltages = 1 ,
} ,
. fixed_uV = 2050000 ,
. update_bank = 0x03 ,
. update_reg = 0x83 ,
. update_mask = 0x08 ,
. update_val_enable = 0x08 ,
} ,
[ AB8500_LDO_ANAMIC2 ] = {
. desc = {
. name = " LDO-ANAMIC2 " ,
. ops = & ab8500_regulator_fixed_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_ANAMIC2 ,
. owner = THIS_MODULE ,
. n_voltages = 1 ,
} ,
. fixed_uV = 2050000 ,
. update_bank = 0x03 ,
. update_reg = 0x83 ,
. update_mask = 0x10 ,
. update_val_enable = 0x10 ,
} ,
[ AB8500_LDO_DMIC ] = {
. desc = {
. name = " LDO-DMIC " ,
. ops = & ab8500_regulator_fixed_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_DMIC ,
. owner = THIS_MODULE ,
. n_voltages = 1 ,
} ,
. fixed_uV = 1800000 ,
. update_bank = 0x03 ,
. update_reg = 0x83 ,
. update_mask = 0x04 ,
. update_val_enable = 0x04 ,
} ,
[ AB8500_LDO_ANA ] = {
. desc = {
. name = " LDO-ANA " ,
. ops = & ab8500_regulator_fixed_ops ,
. type = REGULATOR_VOLTAGE ,
. id = AB8500_LDO_ANA ,
. owner = THIS_MODULE ,
. n_voltages = 1 ,
} ,
. fixed_uV = 1200000 ,
. update_bank = 0x04 ,
. update_reg = 0x06 ,
. update_mask = 0x0c ,
. update_val_enable = 0x04 ,
} ,
2010-07-13 20:18:56 +04:00
} ;
static __devinit int ab8500_regulator_probe ( struct platform_device * pdev )
{
struct ab8500 * ab8500 = dev_get_drvdata ( pdev - > dev . parent ) ;
2010-08-14 13:03:16 +04:00
struct ab8500_platform_data * pdata ;
2010-07-13 20:18:56 +04:00
int i , err ;
if ( ! ab8500 ) {
dev_err ( & pdev - > dev , " null mfd parent \n " ) ;
return - EINVAL ;
}
2010-08-14 13:03:16 +04:00
pdata = dev_get_platdata ( ab8500 - > dev ) ;
2010-12-10 13:08:45 +03:00
if ( ! pdata ) {
dev_err ( & pdev - > dev , " null pdata \n " ) ;
return - EINVAL ;
}
2010-07-13 20:18:56 +04:00
2010-12-10 13:08:40 +03:00
/* make sure the platform data has the correct size */
if ( pdata - > num_regulator ! = ARRAY_SIZE ( ab8500_regulator_info ) ) {
dev_err ( & pdev - > dev , " platform configuration error \n " ) ;
return - EINVAL ;
}
2010-07-13 20:18:56 +04:00
/* register all regulators */
for ( i = 0 ; i < ARRAY_SIZE ( ab8500_regulator_info ) ; i + + ) {
struct ab8500_regulator_info * info = NULL ;
/* assign per-regulator data */
info = & ab8500_regulator_info [ i ] ;
info - > dev = & pdev - > dev ;
2010-12-10 13:08:43 +03:00
/* fix for hardware before ab8500v2.0 */
if ( abx500_get_chip_id ( info - > dev ) < 0x20 ) {
if ( info - > desc . id = = AB8500_LDO_AUX3 ) {
info - > desc . n_voltages =
ARRAY_SIZE ( ldo_vauxn_voltages ) ;
2010-12-10 13:08:44 +03:00
info - > voltages = ldo_vauxn_voltages ;
2010-12-10 13:08:43 +03:00
info - > voltages_len =
ARRAY_SIZE ( ldo_vauxn_voltages ) ;
info - > voltage_mask = 0xf ;
}
}
/* register regulator with framework */
2010-07-13 20:18:56 +04:00
info - > regulator = regulator_register ( & info - > desc , & pdev - > dev ,
2010-12-10 13:08:40 +03:00
& pdata - > regulator [ i ] , info ) ;
2010-07-13 20:18:56 +04:00
if ( IS_ERR ( info - > regulator ) ) {
err = PTR_ERR ( info - > regulator ) ;
dev_err ( & pdev - > dev , " failed to register regulator %s \n " ,
info - > desc . name ) ;
/* when we fail, un-register all earlier regulators */
2010-08-14 17:44:04 +04:00
while ( - - i > = 0 ) {
2010-07-13 20:18:56 +04:00
info = & ab8500_regulator_info [ i ] ;
regulator_unregister ( info - > regulator ) ;
}
return err ;
}
2010-12-10 13:08:46 +03:00
dev_vdbg ( rdev_get_dev ( info - > regulator ) ,
" %s-probed \n " , info - > desc . name ) ;
2010-07-13 20:18:56 +04:00
}
return 0 ;
}
static __devexit int ab8500_regulator_remove ( struct platform_device * pdev )
{
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( ab8500_regulator_info ) ; i + + ) {
struct ab8500_regulator_info * info = NULL ;
info = & ab8500_regulator_info [ i ] ;
2010-12-10 13:08:46 +03:00
dev_vdbg ( rdev_get_dev ( info - > regulator ) ,
" %s-remove \n " , info - > desc . name ) ;
2010-07-13 20:18:56 +04:00
regulator_unregister ( info - > regulator ) ;
}
return 0 ;
}
static struct platform_driver ab8500_regulator_driver = {
. probe = ab8500_regulator_probe ,
. remove = __devexit_p ( ab8500_regulator_remove ) ,
. driver = {
. name = " ab8500-regulator " ,
. owner = THIS_MODULE ,
} ,
} ;
static int __init ab8500_regulator_init ( void )
{
int ret ;
ret = platform_driver_register ( & ab8500_regulator_driver ) ;
if ( ret ! = 0 )
pr_err ( " Failed to register ab8500 regulator: %d \n " , ret ) ;
return ret ;
}
subsys_initcall ( ab8500_regulator_init ) ;
static void __exit ab8500_regulator_exit ( void )
{
platform_driver_unregister ( & ab8500_regulator_driver ) ;
}
module_exit ( ab8500_regulator_exit ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_AUTHOR ( " Sundar Iyer <sundar.iyer@stericsson.com> " ) ;
MODULE_DESCRIPTION ( " Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC " ) ;
MODULE_ALIAS ( " platform:ab8500-regulator " ) ;