2009-09-09 13:31:00 +04:00
/*
* drivers / regulator / ab3100 . c
*
* Copyright ( C ) 2008 - 2009 ST - Ericsson AB
* License terms : GNU General Public License ( GPL ) version 2
* Low - level control of the AB3100 IC Low Dropout ( LDO )
* regulators , external regulator and buck converter
* Author : Mattias Wallin < mattias . wallin @ stericsson . com >
* Author : Linus Walleij < linus . walleij @ stericsson . com >
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/err.h>
# include <linux/platform_device.h>
# include <linux/regulator/driver.h>
2012-08-10 12:32:35 +04:00
# include <linux/mfd/ab3100.h>
2010-05-01 20:26:07 +04:00
# include <linux/mfd/abx500.h>
2009-09-09 13:31:00 +04:00
/* LDO registers and some handy masking definitions for AB3100 */
# define AB3100_LDO_A 0x40
# define AB3100_LDO_C 0x41
# define AB3100_LDO_D 0x42
# define AB3100_LDO_E 0x43
# define AB3100_LDO_E_SLEEP 0x44
# define AB3100_LDO_F 0x45
# define AB3100_LDO_G 0x46
# define AB3100_LDO_H 0x47
# define AB3100_LDO_H_SLEEP_MODE 0
# define AB3100_LDO_H_SLEEP_EN 2
# define AB3100_LDO_ON 4
# define AB3100_LDO_H_VSEL_AC 5
# define AB3100_LDO_K 0x48
# define AB3100_LDO_EXT 0x49
# define AB3100_BUCK 0x4A
# define AB3100_BUCK_SLEEP 0x4B
# define AB3100_REG_ON_MASK 0x10
/**
* struct ab3100_regulator
* A struct passed around the individual regulator functions
* @ platform_device : platform device holding this regulator
2010-05-01 20:26:20 +04:00
* @ dev : handle to the device
2009-09-09 13:31:00 +04:00
* @ plfdata : AB3100 platform data passed in at probe time
* @ regreg : regulator register number in the AB3100
*/
struct ab3100_regulator {
struct regulator_dev * rdev ;
2010-05-01 20:26:20 +04:00
struct device * dev ;
2009-09-09 13:31:00 +04:00
struct ab3100_platform_data * plfdata ;
u8 regreg ;
} ;
/* The order in which registers are initialized */
static const u8 ab3100_reg_init_order [ AB3100_NUM_REGULATORS + 2 ] = {
AB3100_LDO_A ,
AB3100_LDO_C ,
AB3100_LDO_E ,
AB3100_LDO_E_SLEEP ,
AB3100_LDO_F ,
AB3100_LDO_G ,
AB3100_LDO_H ,
AB3100_LDO_K ,
AB3100_LDO_EXT ,
AB3100_BUCK ,
AB3100_BUCK_SLEEP ,
AB3100_LDO_D ,
} ;
/* Preset (hardware defined) voltages for these regulators */
# define LDO_A_VOLTAGE 2750000
# define LDO_C_VOLTAGE 2650000
# define LDO_D_VOLTAGE 2650000
2012-05-20 06:31:58 +04:00
static const unsigned int ldo_e_buck_typ_voltages [ ] = {
2009-09-09 13:31:00 +04:00
1800000 ,
1400000 ,
1300000 ,
1200000 ,
1100000 ,
1050000 ,
900000 ,
} ;
2012-05-20 06:31:58 +04:00
static const unsigned int ldo_f_typ_voltages [ ] = {
2009-09-09 13:31:00 +04:00
1800000 ,
1400000 ,
1300000 ,
1200000 ,
1100000 ,
1050000 ,
2500000 ,
2650000 ,
} ;
2012-05-20 06:31:58 +04:00
static const unsigned int ldo_g_typ_voltages [ ] = {
2009-09-09 13:31:00 +04:00
2850000 ,
2750000 ,
1800000 ,
1500000 ,
} ;
2012-05-20 06:31:58 +04:00
static const unsigned int ldo_h_typ_voltages [ ] = {
2009-09-09 13:31:00 +04:00
2750000 ,
1800000 ,
1500000 ,
1200000 ,
} ;
2012-05-20 06:31:58 +04:00
static const unsigned int ldo_k_typ_voltages [ ] = {
2009-09-09 13:31:00 +04:00
2750000 ,
1800000 ,
} ;
/* The regulator devices */
static struct ab3100_regulator
ab3100_regulators [ AB3100_NUM_REGULATORS ] = {
{
. regreg = AB3100_LDO_A ,
} ,
{
. regreg = AB3100_LDO_C ,
} ,
{
. regreg = AB3100_LDO_D ,
} ,
{
. regreg = AB3100_LDO_E ,
} ,
{
. regreg = AB3100_LDO_F ,
} ,
{
. regreg = AB3100_LDO_G ,
} ,
{
. regreg = AB3100_LDO_H ,
} ,
{
. regreg = AB3100_LDO_K ,
} ,
{
. regreg = AB3100_LDO_EXT ,
/* No voltages for the external regulator */
} ,
{
. regreg = AB3100_BUCK ,
} ,
} ;
/*
* General functions for enable , disable and is_enabled used for
* LDO : A , C , E , F , G , H , K , EXT and BUCK
*/
static int ab3100_enable_regulator ( struct regulator_dev * reg )
{
2012-07-05 05:38:15 +04:00
struct ab3100_regulator * abreg = rdev_get_drvdata ( reg ) ;
2009-09-09 13:31:00 +04:00
int err ;
u8 regval ;
2010-05-01 20:26:20 +04:00
err = abx500_get_register_interruptible ( abreg - > dev , 0 , abreg - > regreg ,
2009-09-09 13:31:00 +04:00
& regval ) ;
if ( err ) {
dev_warn ( & reg - > dev , " failed to get regid %d value \n " ,
abreg - > regreg ) ;
return err ;
}
/* The regulator is already on, no reason to go further */
if ( regval & AB3100_REG_ON_MASK )
return 0 ;
regval | = AB3100_REG_ON_MASK ;
2010-05-01 20:26:20 +04:00
err = abx500_set_register_interruptible ( abreg - > dev , 0 , abreg - > regreg ,
2009-09-09 13:31:00 +04:00
regval ) ;
if ( err ) {
dev_warn ( & reg - > dev , " failed to set regid %d value \n " ,
abreg - > regreg ) ;
return err ;
}
return 0 ;
}
static int ab3100_disable_regulator ( struct regulator_dev * reg )
{
2012-07-05 05:38:15 +04:00
struct ab3100_regulator * abreg = rdev_get_drvdata ( reg ) ;
2009-09-09 13:31:00 +04:00
int err ;
u8 regval ;
/*
* LDO D is a special regulator . When it is disabled , the entire
* system is shut down . So this is handled specially .
*/
2009-10-28 19:30:15 +03:00
pr_info ( " Called ab3100_disable_regulator \n " ) ;
2009-09-09 13:31:00 +04:00
if ( abreg - > regreg = = AB3100_LDO_D ) {
dev_info ( & reg - > dev , " disabling LDO D - shut down system \n " ) ;
/* Setting LDO D to 0x00 cuts the power to the SoC */
2010-05-01 20:26:20 +04:00
return abx500_set_register_interruptible ( abreg - > dev , 0 ,
2009-09-09 13:31:00 +04:00
AB3100_LDO_D , 0x00U ) ;
}
/*
* All other regulators are handled here
*/
2010-05-01 20:26:20 +04:00
err = abx500_get_register_interruptible ( abreg - > dev , 0 , abreg - > regreg ,
2009-09-09 13:31:00 +04:00
& regval ) ;
if ( err ) {
dev_err ( & reg - > dev , " unable to get register 0x%x \n " ,
abreg - > regreg ) ;
return err ;
}
regval & = ~ AB3100_REG_ON_MASK ;
2010-05-01 20:26:20 +04:00
return abx500_set_register_interruptible ( abreg - > dev , 0 , abreg - > regreg ,
2009-09-09 13:31:00 +04:00
regval ) ;
}
static int ab3100_is_enabled_regulator ( struct regulator_dev * reg )
{
2012-07-05 05:38:15 +04:00
struct ab3100_regulator * abreg = rdev_get_drvdata ( reg ) ;
2009-09-09 13:31:00 +04:00
u8 regval ;
int err ;
2010-05-01 20:26:20 +04:00
err = abx500_get_register_interruptible ( abreg - > dev , 0 , abreg - > regreg ,
2009-09-09 13:31:00 +04:00
& regval ) ;
if ( err ) {
dev_err ( & reg - > dev , " unable to get register 0x%x \n " ,
abreg - > regreg ) ;
return err ;
}
return regval & AB3100_REG_ON_MASK ;
}
static int ab3100_get_voltage_regulator ( struct regulator_dev * reg )
{
2012-07-05 05:38:15 +04:00
struct ab3100_regulator * abreg = rdev_get_drvdata ( reg ) ;
2009-09-09 13:31:00 +04:00
u8 regval ;
int err ;
/*
* For variable types , read out setting and index into
* supplied voltage list .
*/
2010-05-01 20:26:20 +04:00
err = abx500_get_register_interruptible ( abreg - > dev , 0 ,
2009-09-09 13:31:00 +04:00
abreg - > regreg , & regval ) ;
if ( err ) {
dev_warn ( & reg - > dev ,
" failed to get regulator value in register %02x \n " ,
abreg - > regreg ) ;
return err ;
}
/* The 3 highest bits index voltages */
regval & = 0xE0 ;
regval > > = 5 ;
2012-05-20 06:31:58 +04:00
if ( regval > = reg - > desc - > n_voltages ) {
2009-09-09 13:31:00 +04:00
dev_err ( & reg - > dev ,
" regulator register %02x contains an illegal voltage setting \n " ,
abreg - > regreg ) ;
return - EINVAL ;
}
2012-05-20 06:31:58 +04:00
return reg - > desc - > volt_table [ regval ] ;
2009-09-09 13:31:00 +04:00
}
2012-03-20 06:14:40 +04:00
static int ab3100_set_voltage_regulator_sel ( struct regulator_dev * reg ,
unsigned selector )
2009-09-09 13:31:00 +04:00
{
2012-07-05 05:38:15 +04:00
struct ab3100_regulator * abreg = rdev_get_drvdata ( reg ) ;
2009-09-09 13:31:00 +04:00
u8 regval ;
int err ;
2010-11-10 17:38:29 +03:00
2010-05-01 20:26:20 +04:00
err = abx500_get_register_interruptible ( abreg - > dev , 0 ,
2009-09-09 13:31:00 +04:00
abreg - > regreg , & regval ) ;
if ( err ) {
dev_warn ( & reg - > dev ,
" failed to get regulator register %02x \n " ,
abreg - > regreg ) ;
return err ;
}
/* The highest three bits control the variable regulators */
regval & = ~ 0xE0 ;
2012-03-20 06:14:40 +04:00
regval | = ( selector < < 5 ) ;
2009-09-09 13:31:00 +04:00
2010-05-01 20:26:20 +04:00
err = abx500_set_register_interruptible ( abreg - > dev , 0 ,
2009-09-09 13:31:00 +04:00
abreg - > regreg , regval ) ;
if ( err )
dev_warn ( & reg - > dev , " failed to set regulator register %02x \n " ,
abreg - > regreg ) ;
return err ;
}
static int ab3100_set_suspend_voltage_regulator ( struct regulator_dev * reg ,
int uV )
{
2012-07-05 05:38:15 +04:00
struct ab3100_regulator * abreg = rdev_get_drvdata ( reg ) ;
2009-09-09 13:31:00 +04:00
u8 regval ;
int err ;
int bestindex ;
u8 targetreg ;
if ( abreg - > regreg = = AB3100_LDO_E )
targetreg = AB3100_LDO_E_SLEEP ;
else if ( abreg - > regreg = = AB3100_BUCK )
targetreg = AB3100_BUCK_SLEEP ;
else
return - EINVAL ;
/* LDO E and BUCK have special suspend voltages you can set */
2012-05-17 09:06:18 +04:00
bestindex = regulator_map_voltage_iterate ( reg , uV , uV ) ;
2009-09-09 13:31:00 +04:00
2010-05-01 20:26:20 +04:00
err = abx500_get_register_interruptible ( abreg - > dev , 0 ,
2009-09-09 13:31:00 +04:00
targetreg , & regval ) ;
if ( err ) {
dev_warn ( & reg - > dev ,
" failed to get regulator register %02x \n " ,
targetreg ) ;
return err ;
}
/* The highest three bits control the variable regulators */
regval & = ~ 0xE0 ;
regval | = ( bestindex < < 5 ) ;
2010-05-01 20:26:20 +04:00
err = abx500_set_register_interruptible ( abreg - > dev , 0 ,
2009-09-09 13:31:00 +04:00
targetreg , regval ) ;
if ( err )
dev_warn ( & reg - > dev , " failed to set regulator register %02x \n " ,
abreg - > regreg ) ;
return err ;
}
/*
* The external regulator can just define a fixed voltage .
*/
static int ab3100_get_voltage_regulator_external ( struct regulator_dev * reg )
{
2012-07-05 05:38:15 +04:00
struct ab3100_regulator * abreg = rdev_get_drvdata ( reg ) ;
2009-09-09 13:31:00 +04:00
return abreg - > plfdata - > external_voltage ;
}
static struct regulator_ops regulator_ops_fixed = {
2012-06-11 06:14:28 +04:00
. list_voltage = regulator_list_voltage_linear ,
2009-09-09 13:31:00 +04:00
. enable = ab3100_enable_regulator ,
. disable = ab3100_disable_regulator ,
. is_enabled = ab3100_is_enabled_regulator ,
} ;
static struct regulator_ops regulator_ops_variable = {
. enable = ab3100_enable_regulator ,
. disable = ab3100_disable_regulator ,
. is_enabled = ab3100_is_enabled_regulator ,
. get_voltage = ab3100_get_voltage_regulator ,
2012-03-20 06:14:40 +04:00
. set_voltage_sel = ab3100_set_voltage_regulator_sel ,
2012-05-20 06:31:58 +04:00
. list_voltage = regulator_list_voltage_table ,
2009-09-09 13:31:00 +04:00
} ;
static struct regulator_ops regulator_ops_variable_sleepable = {
. enable = ab3100_enable_regulator ,
. disable = ab3100_disable_regulator ,
. is_enabled = ab3100_is_enabled_regulator ,
. get_voltage = ab3100_get_voltage_regulator ,
2012-03-20 06:14:40 +04:00
. set_voltage_sel = ab3100_set_voltage_regulator_sel ,
2009-09-09 13:31:00 +04:00
. set_suspend_voltage = ab3100_set_suspend_voltage_regulator ,
2012-05-20 06:31:58 +04:00
. list_voltage = regulator_list_voltage_table ,
2009-09-09 13:31:00 +04:00
} ;
/*
* LDO EXT is an external regulator so it is really
* not possible to set any voltage locally here , AB3100
* is an on / off switch plain an simple . The external
* voltage is defined in the board set - up if any .
*/
static struct regulator_ops regulator_ops_external = {
. enable = ab3100_enable_regulator ,
. disable = ab3100_disable_regulator ,
. is_enabled = ab3100_is_enabled_regulator ,
. get_voltage = ab3100_get_voltage_regulator_external ,
} ;
static struct regulator_desc
ab3100_regulator_desc [ AB3100_NUM_REGULATORS ] = {
{
. name = " LDO_A " ,
. id = AB3100_LDO_A ,
. ops = & regulator_ops_fixed ,
2012-06-11 06:14:28 +04:00
. n_voltages = 1 ,
2009-09-09 13:31:00 +04:00
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2012-06-11 06:14:28 +04:00
. min_uV = LDO_A_VOLTAGE ,
2012-07-04 06:03:23 +04:00
. enable_time = 200 ,
2009-09-09 13:31:00 +04:00
} ,
{
. name = " LDO_C " ,
. id = AB3100_LDO_C ,
. ops = & regulator_ops_fixed ,
2012-06-11 06:14:28 +04:00
. n_voltages = 1 ,
2009-09-09 13:31:00 +04:00
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2012-06-11 06:14:28 +04:00
. min_uV = LDO_C_VOLTAGE ,
2012-07-04 06:03:23 +04:00
. enable_time = 200 ,
2009-09-09 13:31:00 +04:00
} ,
{
. name = " LDO_D " ,
. id = AB3100_LDO_D ,
. ops = & regulator_ops_fixed ,
2012-06-11 06:14:28 +04:00
. n_voltages = 1 ,
2009-09-09 13:31:00 +04:00
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2012-06-11 06:14:28 +04:00
. min_uV = LDO_D_VOLTAGE ,
2012-07-04 06:03:23 +04:00
. enable_time = 200 ,
2009-09-09 13:31:00 +04:00
} ,
{
. name = " LDO_E " ,
. id = AB3100_LDO_E ,
. ops = & regulator_ops_variable_sleepable ,
2009-09-17 11:17:33 +04:00
. n_voltages = ARRAY_SIZE ( ldo_e_buck_typ_voltages ) ,
2012-05-20 06:31:58 +04:00
. volt_table = ldo_e_buck_typ_voltages ,
2009-09-09 13:31:00 +04:00
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2012-07-04 06:03:23 +04:00
. enable_time = 200 ,
2009-09-09 13:31:00 +04:00
} ,
{
. name = " LDO_F " ,
. id = AB3100_LDO_F ,
. ops = & regulator_ops_variable ,
2009-09-17 11:17:33 +04:00
. n_voltages = ARRAY_SIZE ( ldo_f_typ_voltages ) ,
2012-05-20 06:31:58 +04:00
. volt_table = ldo_f_typ_voltages ,
2009-09-09 13:31:00 +04:00
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2012-07-04 06:03:23 +04:00
. enable_time = 600 ,
2009-09-09 13:31:00 +04:00
} ,
{
. name = " LDO_G " ,
. id = AB3100_LDO_G ,
. ops = & regulator_ops_variable ,
2009-09-17 11:17:33 +04:00
. n_voltages = ARRAY_SIZE ( ldo_g_typ_voltages ) ,
2012-05-20 06:31:58 +04:00
. volt_table = ldo_g_typ_voltages ,
2009-09-09 13:31:00 +04:00
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2012-07-04 06:03:23 +04:00
. enable_time = 400 ,
2009-09-09 13:31:00 +04:00
} ,
{
. name = " LDO_H " ,
. id = AB3100_LDO_H ,
. ops = & regulator_ops_variable ,
2009-09-17 11:17:33 +04:00
. n_voltages = ARRAY_SIZE ( ldo_h_typ_voltages ) ,
2012-05-20 06:31:58 +04:00
. volt_table = ldo_h_typ_voltages ,
2009-09-09 13:31:00 +04:00
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2012-07-04 06:03:23 +04:00
. enable_time = 200 ,
2009-09-09 13:31:00 +04:00
} ,
{
. name = " LDO_K " ,
. id = AB3100_LDO_K ,
. ops = & regulator_ops_variable ,
2009-09-17 11:17:33 +04:00
. n_voltages = ARRAY_SIZE ( ldo_k_typ_voltages ) ,
2012-05-20 06:31:58 +04:00
. volt_table = ldo_k_typ_voltages ,
2009-09-09 13:31:00 +04:00
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2012-07-04 06:03:23 +04:00
. enable_time = 200 ,
2009-09-09 13:31:00 +04:00
} ,
{
. name = " LDO_EXT " ,
. id = AB3100_LDO_EXT ,
. ops = & regulator_ops_external ,
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2009-09-09 13:31:00 +04:00
} ,
{
. name = " BUCK " ,
. id = AB3100_BUCK ,
. ops = & regulator_ops_variable_sleepable ,
2009-09-17 11:17:33 +04:00
. n_voltages = ARRAY_SIZE ( ldo_e_buck_typ_voltages ) ,
2012-08-06 19:11:40 +04:00
. volt_table = ldo_e_buck_typ_voltages ,
2009-09-09 13:31:00 +04:00
. type = REGULATOR_VOLTAGE ,
2010-05-13 13:33:01 +04:00
. owner = THIS_MODULE ,
2012-07-04 06:03:23 +04:00
. enable_time = 1000 ,
2009-09-09 13:31:00 +04:00
} ,
} ;
/*
* NOTE : the following functions are regulators pluralis - it is the
* binding to the AB3100 core driver and the parent platform device
* for all the different regulators .
*/
2012-11-19 22:22:22 +04:00
static int ab3100_regulators_probe ( struct platform_device * pdev )
2009-09-09 13:31:00 +04:00
{
2011-04-06 02:41:43 +04:00
struct ab3100_platform_data * plfdata = pdev - > dev . platform_data ;
2012-04-04 03:50:22 +04:00
struct regulator_config config = { } ;
2009-09-09 13:31:00 +04:00
int err = 0 ;
u8 data ;
int i ;
/* Check chip state */
2010-05-01 20:26:20 +04:00
err = abx500_get_register_interruptible ( & pdev - > dev , 0 ,
2009-09-09 13:31:00 +04:00
AB3100_LDO_D , & data ) ;
if ( err ) {
dev_err ( & pdev - > dev , " could not read initial status of LDO_D \n " ) ;
return err ;
}
if ( data & 0x10 )
dev_notice ( & pdev - > dev ,
" chip is already in active mode (Warm start) \n " ) ;
else
dev_notice ( & pdev - > dev ,
" chip is in inactive mode (Cold start) \n " ) ;
/* Set up regulators */
for ( i = 0 ; i < ARRAY_SIZE ( ab3100_reg_init_order ) ; i + + ) {
2010-05-01 20:26:20 +04:00
err = abx500_set_register_interruptible ( & pdev - > dev , 0 ,
2009-09-09 13:31:00 +04:00
ab3100_reg_init_order [ i ] ,
plfdata - > reg_initvals [ i ] ) ;
if ( err ) {
dev_err ( & pdev - > dev , " regulator initialization failed with error %d \n " ,
err ) ;
return err ;
}
}
/* Register the regulators */
for ( i = 0 ; i < AB3100_NUM_REGULATORS ; i + + ) {
struct ab3100_regulator * reg = & ab3100_regulators [ i ] ;
struct regulator_dev * rdev ;
/*
* Initialize per - regulator struct .
* Inherit platform data , this comes down from the
* i2c boarddata , from the machine . So if you want to
* see what it looks like for a certain machine , go
* into the machine I2C setup .
*/
2010-05-01 20:26:20 +04:00
reg - > dev = & pdev - > dev ;
2009-09-09 13:31:00 +04:00
reg - > plfdata = plfdata ;
2012-04-04 03:50:22 +04:00
config . dev = & pdev - > dev ;
config . driver_data = reg ;
config . init_data = & plfdata - > reg_constraints [ i ] ;
2009-09-09 13:31:00 +04:00
/*
* Register the regulator , pass around
* the ab3100_regulator struct
*/
2012-04-04 03:50:22 +04:00
rdev = regulator_register ( & ab3100_regulator_desc [ i ] , & config ) ;
2009-09-09 13:31:00 +04:00
if ( IS_ERR ( rdev ) ) {
err = PTR_ERR ( rdev ) ;
dev_err ( & pdev - > dev ,
" %s: failed to register regulator %s err %d \n " ,
__func__ , ab3100_regulator_desc [ i ] . name ,
err ) ;
/* remove the already registered regulators */
2010-08-14 17:31:01 +04:00
while ( - - i > = 0 )
2009-09-09 13:31:00 +04:00
regulator_unregister ( ab3100_regulators [ i ] . rdev ) ;
return err ;
}
/* Then set a pointer back to the registered regulator */
reg - > rdev = rdev ;
}
return 0 ;
}
2010-02-24 10:37:50 +03:00
static int __devexit ab3100_regulators_remove ( struct platform_device * pdev )
2009-09-09 13:31:00 +04:00
{
int i ;
for ( i = 0 ; i < AB3100_NUM_REGULATORS ; i + + ) {
struct ab3100_regulator * reg = & ab3100_regulators [ i ] ;
regulator_unregister ( reg - > rdev ) ;
}
return 0 ;
}
static struct platform_driver ab3100_regulators_driver = {
. driver = {
. name = " ab3100-regulators " ,
. owner = THIS_MODULE ,
} ,
. probe = ab3100_regulators_probe ,
2012-11-19 22:20:42 +04:00
. remove = ab3100_regulators_remove ,
2009-09-09 13:31:00 +04:00
} ;
static __init int ab3100_regulators_init ( void )
{
return platform_driver_register ( & ab3100_regulators_driver ) ;
}
static __exit void ab3100_regulators_exit ( void )
{
2009-10-28 19:30:15 +03:00
platform_driver_unregister ( & ab3100_regulators_driver ) ;
2009-09-09 13:31:00 +04:00
}
subsys_initcall ( ab3100_regulators_init ) ;
module_exit ( ab3100_regulators_exit ) ;
MODULE_AUTHOR ( " Mattias Wallin <mattias.wallin@stericsson.com> " ) ;
MODULE_DESCRIPTION ( " AB3100 Regulator driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " platform:ab3100-regulators " ) ;