2011-06-24 19:04:18 +09:00
/*
* max8998_charger . c - Power supply consumer driver for the Maxim 8998 / LP3974
*
* Copyright ( C ) 2009 - 2010 Samsung Electronics
* MyungJoo Ham < myungjoo . ham @ 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
*/
# include <linux/err.h>
2011-07-29 21:11:43 -07:00
# include <linux/module.h>
2011-06-24 19:04:18 +09:00
# include <linux/slab.h>
# include <linux/platform_device.h>
# include <linux/power_supply.h>
# include <linux/mfd/max8998.h>
# include <linux/mfd/max8998-private.h>
struct max8998_battery_data {
struct device * dev ;
struct max8998_dev * iodev ;
2015-03-12 08:44:11 +01:00
struct power_supply * battery ;
2011-06-24 19:04:18 +09:00
} ;
static enum power_supply_property max8998_battery_props [ ] = {
POWER_SUPPLY_PROP_PRESENT , /* the presence of battery */
POWER_SUPPLY_PROP_ONLINE , /* charger is active or not */
} ;
/* Note that the charger control is done by a current regulator "CHARGER" */
static int max8998_battery_get_property ( struct power_supply * psy ,
enum power_supply_property psp ,
union power_supply_propval * val )
{
2015-03-12 08:44:11 +01:00
struct max8998_battery_data * max8998 = power_supply_get_drvdata ( psy ) ;
2011-06-24 19:04:18 +09:00
struct i2c_client * i2c = max8998 - > iodev - > i2c ;
int ret ;
u8 reg ;
switch ( psp ) {
case POWER_SUPPLY_PROP_PRESENT :
ret = max8998_read_reg ( i2c , MAX8998_REG_STATUS2 , & reg ) ;
if ( ret )
return ret ;
if ( reg & ( 1 < < 4 ) )
val - > intval = 0 ;
else
val - > intval = 1 ;
break ;
case POWER_SUPPLY_PROP_ONLINE :
ret = max8998_read_reg ( i2c , MAX8998_REG_STATUS2 , & reg ) ;
if ( ret )
return ret ;
if ( reg & ( 1 < < 3 ) )
val - > intval = 0 ;
else
val - > intval = 1 ;
break ;
default :
return - EINVAL ;
}
return 0 ;
}
2015-03-12 08:44:11 +01:00
static const struct power_supply_desc max8998_battery_desc = {
. name = " max8998_pmic " ,
. type = POWER_SUPPLY_TYPE_BATTERY ,
. get_property = max8998_battery_get_property ,
. properties = max8998_battery_props ,
. num_properties = ARRAY_SIZE ( max8998_battery_props ) ,
} ;
2012-11-19 13:22:23 -05:00
static int max8998_battery_probe ( struct platform_device * pdev )
2011-06-24 19:04:18 +09:00
{
struct max8998_dev * iodev = dev_get_drvdata ( pdev - > dev . parent ) ;
struct max8998_platform_data * pdata = dev_get_platdata ( iodev - > dev ) ;
2015-03-12 08:44:11 +01:00
struct power_supply_config psy_cfg = { } ;
2011-06-24 19:04:18 +09:00
struct max8998_battery_data * max8998 ;
struct i2c_client * i2c ;
int ret = 0 ;
if ( ! pdata ) {
dev_err ( pdev - > dev . parent , " No platform init data supplied \n " ) ;
return - ENODEV ;
}
2013-03-11 15:35:14 +09:00
max8998 = devm_kzalloc ( & pdev - > dev , sizeof ( struct max8998_battery_data ) ,
GFP_KERNEL ) ;
2011-06-24 19:04:18 +09:00
if ( ! max8998 )
return - ENOMEM ;
max8998 - > dev = & pdev - > dev ;
max8998 - > iodev = iodev ;
platform_set_drvdata ( pdev , max8998 ) ;
i2c = max8998 - > iodev - > i2c ;
/* Setup "End of Charge" */
/* If EOC value equals 0,
* remain value set from bootloader or default value */
if ( pdata - > eoc > = 10 & & pdata - > eoc < = 45 ) {
max8998_update_reg ( i2c , MAX8998_REG_CHGR1 ,
( pdata - > eoc / 5 - 2 ) < < 5 , 0x7 < < 5 ) ;
} else if ( pdata - > eoc = = 0 ) {
dev_dbg ( max8998 - > dev ,
" EOC value not set: leave it unchanged. \n " ) ;
} else {
dev_err ( max8998 - > dev , " Invalid EOC value \n " ) ;
2015-08-13 10:24:41 +05:30
return - EINVAL ;
2011-06-24 19:04:18 +09:00
}
/* Setup Charge Restart Level */
switch ( pdata - > restart ) {
case 100 :
max8998_update_reg ( i2c , MAX8998_REG_CHGR1 , 0x1 < < 3 , 0x3 < < 3 ) ;
break ;
case 150 :
max8998_update_reg ( i2c , MAX8998_REG_CHGR1 , 0x0 < < 3 , 0x3 < < 3 ) ;
break ;
case 200 :
max8998_update_reg ( i2c , MAX8998_REG_CHGR1 , 0x2 < < 3 , 0x3 < < 3 ) ;
break ;
case - 1 :
max8998_update_reg ( i2c , MAX8998_REG_CHGR1 , 0x3 < < 3 , 0x3 < < 3 ) ;
break ;
case 0 :
dev_dbg ( max8998 - > dev ,
" Restart Level not set: leave it unchanged. \n " ) ;
break ;
default :
dev_err ( max8998 - > dev , " Invalid Restart Level \n " ) ;
2015-08-13 10:24:41 +05:30
return - EINVAL ;
2011-06-24 19:04:18 +09:00
}
/* Setup Charge Full Timeout */
switch ( pdata - > timeout ) {
case 5 :
max8998_update_reg ( i2c , MAX8998_REG_CHGR2 , 0x0 < < 4 , 0x3 < < 4 ) ;
break ;
case 6 :
max8998_update_reg ( i2c , MAX8998_REG_CHGR2 , 0x1 < < 4 , 0x3 < < 4 ) ;
break ;
case 7 :
max8998_update_reg ( i2c , MAX8998_REG_CHGR2 , 0x2 < < 4 , 0x3 < < 4 ) ;
break ;
case - 1 :
max8998_update_reg ( i2c , MAX8998_REG_CHGR2 , 0x3 < < 4 , 0x3 < < 4 ) ;
break ;
case 0 :
dev_dbg ( max8998 - > dev ,
" Full Timeout not set: leave it unchanged. \n " ) ;
2011-08-01 07:41:50 +08:00
break ;
2011-06-24 19:04:18 +09:00
default :
dev_err ( max8998 - > dev , " Invalid Full Timeout value \n " ) ;
2015-08-13 10:24:41 +05:30
return - EINVAL ;
2011-06-24 19:04:18 +09:00
}
2015-03-12 08:44:11 +01:00
psy_cfg . drv_data = max8998 ;
2011-06-24 19:04:18 +09:00
2015-08-13 10:24:41 +05:30
max8998 - > battery = devm_power_supply_register ( max8998 - > dev ,
& max8998_battery_desc ,
& psy_cfg ) ;
2015-03-12 08:44:11 +01:00
if ( IS_ERR ( max8998 - > battery ) ) {
ret = PTR_ERR ( max8998 - > battery ) ;
dev_err ( max8998 - > dev , " failed: power supply register: %d \n " ,
ret ) ;
2015-08-13 10:24:41 +05:30
return ret ;
2011-06-24 19:04:18 +09:00
}
return 0 ;
}
static const struct platform_device_id max8998_battery_id [ ] = {
{ " max8998-battery " , TYPE_MAX8998 } ,
2011-08-01 07:23:00 +08:00
{ }
2011-06-24 19:04:18 +09:00
} ;
static struct platform_driver max8998_battery_driver = {
. driver = {
. name = " max8998-battery " ,
} ,
. probe = max8998_battery_probe ,
. id_table = max8998_battery_id ,
} ;
2011-11-26 12:01:10 +08:00
module_platform_driver ( max8998_battery_driver ) ;
2011-06-24 19:04:18 +09:00
MODULE_DESCRIPTION ( " MAXIM 8998 battery control driver " ) ;
MODULE_AUTHOR ( " MyungJoo Ham <myungjoo.ham@samsung.com> " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " platform:max8998-battery " ) ;