2013-06-25 05:08:38 +04:00
/*
* max77693 . c - Regulator driver for the Maxim 77693
*
* Copyright ( C ) 2013 Samsung Electronics
* Jonghwa Lee < jonghwa3 . lee @ samsung . 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 .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
* This driver is based on max77686 . c
*/
# include <linux/err.h>
# include <linux/slab.h>
# include <linux/platform_device.h>
# include <linux/module.h>
# include <linux/export.h>
# include <linux/regulator/driver.h>
# include <linux/regulator/machine.h>
# include <linux/mfd/max77693.h>
# include <linux/mfd/max77693-private.h>
# include <linux/regulator/of_regulator.h>
2014-05-21 10:52:47 +04:00
# include <linux/regmap.h>
2013-06-25 05:08:38 +04:00
# define CHGIN_ILIM_STEP_20mA 20000
/*
* CHARGER regulator - Min : 20 mA , Max : 2580 mA , step : 20 mA
* 0x00 , 0x01 , 0x2 , 0x03 = 60 mA
* 0x04 ~ 0x7E = ( 60 + ( X - 3 ) * 20 ) mA
*/
static int max77693_chg_get_current_limit ( struct regulator_dev * rdev )
{
unsigned int chg_min_uA = rdev - > constraints - > min_uA ;
unsigned int chg_max_uA = rdev - > constraints - > max_uA ;
2014-05-21 10:52:47 +04:00
unsigned int reg , sel ;
2013-06-25 05:08:38 +04:00
unsigned int val ;
int ret ;
2014-05-21 10:52:47 +04:00
ret = regmap_read ( rdev - > regmap , MAX77693_CHG_REG_CHG_CNFG_09 , & reg ) ;
2013-06-25 05:08:38 +04:00
if ( ret < 0 )
return ret ;
sel = reg & CHG_CNFG_09_CHGIN_ILIM_MASK ;
/* the first four codes for charger current are all 60mA */
if ( sel < = 3 )
sel = 0 ;
else
sel - = 3 ;
val = chg_min_uA + CHGIN_ILIM_STEP_20mA * sel ;
if ( val > chg_max_uA )
return - EINVAL ;
return val ;
}
static int max77693_chg_set_current_limit ( struct regulator_dev * rdev ,
int min_uA , int max_uA )
{
unsigned int chg_min_uA = rdev - > constraints - > min_uA ;
int sel = 0 ;
while ( chg_min_uA + CHGIN_ILIM_STEP_20mA * sel < min_uA )
sel + + ;
2013-06-29 07:37:29 +04:00
if ( chg_min_uA + CHGIN_ILIM_STEP_20mA * sel > max_uA )
2013-06-25 05:08:38 +04:00
return - EINVAL ;
/* the first four codes for charger current are all 60mA */
sel + = 3 ;
2014-05-21 10:52:47 +04:00
return regmap_write ( rdev - > regmap ,
2013-06-25 05:08:38 +04:00
MAX77693_CHG_REG_CHG_CNFG_09 , sel ) ;
}
/* end of CHARGER regulator ops */
static const unsigned int max77693_safeout_table [ ] = {
4850000 ,
4900000 ,
4950000 ,
3300000 ,
} ;
static struct regulator_ops max77693_safeout_ops = {
. list_voltage = regulator_list_voltage_table ,
. 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 ,
} ;
static struct regulator_ops max77693_charger_ops = {
2015-04-29 13:58:28 +03:00
. is_enabled = regulator_is_enabled_regmap ,
2013-06-25 05:08:38 +04:00
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. get_current_limit = max77693_chg_get_current_limit ,
. set_current_limit = max77693_chg_set_current_limit ,
} ;
# define regulator_desc_esafeout(_num) { \
. name = " ESAFEOUT " # _num , \
. id = MAX77693_ESAFEOUT # # _num , \
2015-03-26 13:35:58 +03:00
. of_match = of_match_ptr ( " ESAFEOUT " # _num ) , \
. regulators_node = of_match_ptr ( " regulators " ) , \
2013-06-25 05:08:38 +04:00
. n_voltages = 4 , \
. ops = & max77693_safeout_ops , \
. type = REGULATOR_VOLTAGE , \
2013-12-24 17:37:50 +04:00
. owner = THIS_MODULE , \
2013-06-25 05:08:38 +04:00
. volt_table = max77693_safeout_table , \
. vsel_reg = MAX77693_CHG_REG_SAFEOUT_CTRL , \
. vsel_mask = SAFEOUT_CTRL_SAFEOUT # # _num # # _MASK , \
. enable_reg = MAX77693_CHG_REG_SAFEOUT_CTRL , \
. enable_mask = SAFEOUT_CTRL_ENSAFEOUT # # _num # # _MASK , \
}
2014-10-27 18:44:12 +03:00
static const struct regulator_desc regulators [ ] = {
2013-06-25 05:08:38 +04:00
regulator_desc_esafeout ( 1 ) ,
regulator_desc_esafeout ( 2 ) ,
{
. name = " CHARGER " ,
. id = MAX77693_CHARGER ,
2015-03-26 13:35:58 +03:00
. of_match = of_match_ptr ( " CHARGER " ) ,
. regulators_node = of_match_ptr ( " regulators " ) ,
2013-06-25 05:08:38 +04:00
. ops = & max77693_charger_ops ,
. type = REGULATOR_CURRENT ,
. owner = THIS_MODULE ,
. enable_reg = MAX77693_CHG_REG_CHG_CNFG_00 ,
. enable_mask = CHG_CNFG_00_CHG_MASK |
CHG_CNFG_00_BUCK_MASK ,
2015-04-29 13:58:28 +03:00
. enable_val = CHG_CNFG_00_CHG_MASK | CHG_CNFG_00_BUCK_MASK ,
2013-06-25 05:08:38 +04:00
} ,
} ;
static int max77693_pmic_probe ( struct platform_device * pdev )
{
struct max77693_dev * iodev = dev_get_drvdata ( pdev - > dev . parent ) ;
2015-03-26 13:35:58 +03:00
int i ;
2014-11-03 17:07:05 +03:00
struct regulator_config config = { } ;
2013-06-25 05:08:38 +04:00
2015-03-26 13:35:58 +03:00
config . dev = iodev - > dev ;
2013-06-25 05:08:38 +04:00
config . regmap = iodev - > regmap ;
2015-03-26 13:35:58 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( regulators ) ; i + + ) {
2014-03-10 12:32:46 +04:00
struct regulator_dev * rdev ;
2013-06-25 05:08:38 +04:00
2014-03-10 12:32:46 +04:00
rdev = devm_regulator_register ( & pdev - > dev ,
2015-03-26 13:35:58 +03:00
& regulators [ i ] , & config ) ;
2014-03-10 12:32:46 +04:00
if ( IS_ERR ( rdev ) ) {
dev_err ( & pdev - > dev ,
2015-03-26 13:35:58 +03:00
" Failed to initialize regulator-%d \n " , i ) ;
2014-03-10 12:32:46 +04:00
return PTR_ERR ( rdev ) ;
2013-06-25 05:08:38 +04:00
}
}
return 0 ;
}
static const struct platform_device_id max77693_pmic_id [ ] = {
{ " max77693-pmic " , 0 } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( platform , max77693_pmic_id ) ;
static struct platform_driver max77693_pmic_driver = {
. driver = {
. name = " max77693-pmic " ,
} ,
. probe = max77693_pmic_probe ,
. id_table = max77693_pmic_id ,
} ;
module_platform_driver ( max77693_pmic_driver ) ;
MODULE_DESCRIPTION ( " MAXIM MAX77693 regulator driver " ) ;
MODULE_AUTHOR ( " Jonghwa Lee <jonghwa3.lee@samsung.com> " ) ;
MODULE_LICENSE ( " GPL " ) ;