2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2014-09-01 12:28:34 +04:00
/*
2017-07-20 10:32:42 +03:00
* Device driver for Hi6421 PMIC
2014-09-01 12:28:34 +04:00
*
* Copyright ( c ) < 2011 - 2014 > HiSilicon Technologies Co . , Ltd .
* http : //www.hisilicon.com
2017-07-20 10:32:42 +03:00
* Copyright ( c ) < 2013 - 2017 > Linaro Ltd .
2014-09-01 12:28:34 +04:00
* http : //www.linaro.org
*
* Author : Guodong Xu < guodong . xu @ linaro . org >
*/
# include <linux/device.h>
# include <linux/err.h>
# include <linux/mfd/core.h>
2017-07-20 10:32:42 +03:00
# include <linux/mfd/hi6421-pmic.h>
2014-09-01 12:28:34 +04:00
# include <linux/module.h>
2017-07-20 10:32:42 +03:00
# include <linux/of_device.h>
2014-09-01 12:28:34 +04:00
# include <linux/platform_device.h>
# include <linux/regmap.h>
static const struct mfd_cell hi6421_devs [ ] = {
{ . name = " hi6421-regulator " , } ,
} ;
2017-07-20 10:32:42 +03:00
static const struct mfd_cell hi6421v530_devs [ ] = {
{ . name = " hi6421v530-regulator " , } ,
} ;
2015-01-05 12:01:21 +03:00
static const struct regmap_config hi6421_regmap_config = {
2014-09-01 12:28:34 +04:00
. reg_bits = 32 ,
. reg_stride = 4 ,
. val_bits = 8 ,
. max_register = HI6421_REG_TO_BUS_ADDR ( HI6421_REG_MAX ) ,
} ;
2017-07-20 10:32:42 +03:00
static const struct of_device_id of_hi6421_pmic_match [ ] = {
{
. compatible = " hisilicon,hi6421-pmic " ,
. data = ( void * ) HI6421
} ,
{
. compatible = " hisilicon,hi6421v530-pmic " ,
. data = ( void * ) HI6421_V530
} ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , of_hi6421_pmic_match ) ;
2014-09-01 12:28:34 +04:00
static int hi6421_pmic_probe ( struct platform_device * pdev )
{
struct hi6421_pmic * pmic ;
struct resource * res ;
2017-07-20 10:32:42 +03:00
const struct of_device_id * id ;
const struct mfd_cell * subdevs ;
enum hi6421_type type ;
2014-09-01 12:28:34 +04:00
void __iomem * base ;
2017-07-20 10:32:42 +03:00
int n_subdevs , ret ;
id = of_match_device ( of_hi6421_pmic_match , & pdev - > dev ) ;
if ( ! id )
return - EINVAL ;
type = ( enum hi6421_type ) id - > data ;
2014-09-01 12:28:34 +04:00
pmic = devm_kzalloc ( & pdev - > dev , sizeof ( * pmic ) , GFP_KERNEL ) ;
if ( ! pmic )
return - ENOMEM ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
base = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( base ) )
return PTR_ERR ( base ) ;
pmic - > regmap = devm_regmap_init_mmio_clk ( & pdev - > dev , NULL , base ,
& hi6421_regmap_config ) ;
if ( IS_ERR ( pmic - > regmap ) ) {
2017-07-20 10:32:41 +03:00
dev_err ( & pdev - > dev , " Failed to initialise Regmap: %ld \n " ,
PTR_ERR ( pmic - > regmap ) ) ;
2014-09-01 12:28:34 +04:00
return PTR_ERR ( pmic - > regmap ) ;
}
2017-07-20 10:32:42 +03:00
platform_set_drvdata ( pdev , pmic ) ;
switch ( type ) {
case HI6421 :
/* set over-current protection debounce 8ms */
regmap_update_bits ( pmic - > regmap , HI6421_OCP_DEB_CTRL_REG ,
2014-09-01 12:28:34 +04:00
( HI6421_OCP_DEB_SEL_MASK
| HI6421_OCP_EN_DEBOUNCE_MASK
| HI6421_OCP_AUTO_STOP_MASK ) ,
( HI6421_OCP_DEB_SEL_8MS
| HI6421_OCP_EN_DEBOUNCE_ENABLE ) ) ;
2017-07-20 10:32:42 +03:00
subdevs = hi6421_devs ;
n_subdevs = ARRAY_SIZE ( hi6421_devs ) ;
break ;
case HI6421_V530 :
subdevs = hi6421v530_devs ;
n_subdevs = ARRAY_SIZE ( hi6421v530_devs ) ;
break ;
default :
dev_err ( & pdev - > dev , " Unknown device type %d \n " ,
( unsigned int ) type ) ;
return - EINVAL ;
}
2014-09-01 12:28:34 +04:00
2017-07-20 10:32:42 +03:00
ret = devm_mfd_add_devices ( & pdev - > dev , PLATFORM_DEVID_NONE ,
subdevs , n_subdevs , NULL , 0 , NULL ) ;
2014-09-01 12:28:34 +04:00
if ( ret ) {
2017-07-20 10:32:41 +03:00
dev_err ( & pdev - > dev , " Failed to add child devices: %d \n " , ret ) ;
2014-09-01 12:28:34 +04:00
return ret ;
}
return 0 ;
}
static struct platform_driver hi6421_pmic_driver = {
. driver = {
2017-07-20 10:32:42 +03:00
. name = " hi6421_pmic " ,
. of_match_table = of_hi6421_pmic_match ,
2014-09-01 12:28:34 +04:00
} ,
. probe = hi6421_pmic_probe ,
} ;
module_platform_driver ( hi6421_pmic_driver ) ;
MODULE_AUTHOR ( " Guodong Xu <guodong.xu@linaro.org> " ) ;
MODULE_DESCRIPTION ( " Hi6421 PMIC driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;