2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2014-03-12 03:33:54 +04:00
/*
* Broadcom BCM590xx PMU
*
* Copyright 2014 Linaro Limited
* Author : Matt Porter < mporter @ linaro . org >
*/
# include <linux/err.h>
# include <linux/i2c.h>
# include <linux/init.h>
# include <linux/mfd/bcm590xx.h>
# include <linux/mfd/core.h>
# include <linux/module.h>
# include <linux/moduleparam.h>
# include <linux/of.h>
# include <linux/of_device.h>
# include <linux/regmap.h>
# include <linux/slab.h>
static const struct mfd_cell bcm590xx_devs [ ] = {
{
. name = " bcm590xx-vregs " ,
} ,
} ;
2014-04-24 03:21:31 +04:00
static const struct regmap_config bcm590xx_regmap_config_pri = {
2014-03-12 03:33:54 +04:00
. reg_bits = 8 ,
. val_bits = 8 ,
2014-04-24 03:21:31 +04:00
. max_register = BCM590XX_MAX_REGISTER_PRI ,
2014-03-12 03:33:54 +04:00
. cache_type = REGCACHE_RBTREE ,
} ;
2014-04-24 03:21:31 +04:00
static const struct regmap_config bcm590xx_regmap_config_sec = {
. reg_bits = 8 ,
. val_bits = 8 ,
. max_register = BCM590XX_MAX_REGISTER_SEC ,
. cache_type = REGCACHE_RBTREE ,
} ;
2022-11-19 01:42:37 +03:00
static int bcm590xx_i2c_probe ( struct i2c_client * i2c_pri )
2014-03-12 03:33:54 +04:00
{
struct bcm590xx * bcm590xx ;
int ret ;
2014-04-24 03:21:31 +04:00
bcm590xx = devm_kzalloc ( & i2c_pri - > dev , sizeof ( * bcm590xx ) , GFP_KERNEL ) ;
2014-03-12 03:33:54 +04:00
if ( ! bcm590xx )
return - ENOMEM ;
2014-04-24 03:21:31 +04:00
i2c_set_clientdata ( i2c_pri , bcm590xx ) ;
bcm590xx - > dev = & i2c_pri - > dev ;
bcm590xx - > i2c_pri = i2c_pri ;
2014-03-12 03:33:54 +04:00
2014-04-24 03:21:31 +04:00
bcm590xx - > regmap_pri = devm_regmap_init_i2c ( i2c_pri ,
& bcm590xx_regmap_config_pri ) ;
if ( IS_ERR ( bcm590xx - > regmap_pri ) ) {
ret = PTR_ERR ( bcm590xx - > regmap_pri ) ;
dev_err ( & i2c_pri - > dev , " primary regmap init failed: %d \n " , ret ) ;
2014-03-12 03:33:54 +04:00
return ret ;
}
2014-04-24 03:21:31 +04:00
/* Secondary I2C slave address is the base address with A(2) asserted */
2019-07-22 20:26:11 +03:00
bcm590xx - > i2c_sec = i2c_new_dummy_device ( i2c_pri - > adapter ,
2014-04-24 03:21:31 +04:00
i2c_pri - > addr | BIT ( 2 ) ) ;
2019-07-22 20:26:11 +03:00
if ( IS_ERR ( bcm590xx - > i2c_sec ) ) {
2014-04-24 03:21:31 +04:00
dev_err ( & i2c_pri - > dev , " failed to add secondary I2C device \n " ) ;
2019-07-22 20:26:11 +03:00
return PTR_ERR ( bcm590xx - > i2c_sec ) ;
2014-04-24 03:21:31 +04:00
}
i2c_set_clientdata ( bcm590xx - > i2c_sec , bcm590xx ) ;
bcm590xx - > regmap_sec = devm_regmap_init_i2c ( bcm590xx - > i2c_sec ,
& bcm590xx_regmap_config_sec ) ;
if ( IS_ERR ( bcm590xx - > regmap_sec ) ) {
ret = PTR_ERR ( bcm590xx - > regmap_sec ) ;
dev_err ( & bcm590xx - > i2c_sec - > dev ,
" secondary regmap init failed: %d \n " , ret ) ;
goto err ;
}
2016-04-07 21:43:00 +03:00
ret = devm_mfd_add_devices ( & i2c_pri - > dev , - 1 , bcm590xx_devs ,
ARRAY_SIZE ( bcm590xx_devs ) , NULL , 0 , NULL ) ;
2014-04-24 03:21:31 +04:00
if ( ret < 0 ) {
dev_err ( & i2c_pri - > dev , " failed to add sub-devices: %d \n " , ret ) ;
goto err ;
}
return 0 ;
2014-03-12 03:33:54 +04:00
2014-04-24 03:21:31 +04:00
err :
i2c_unregister_device ( bcm590xx - > i2c_sec ) ;
2014-03-12 03:33:54 +04:00
return ret ;
}
static const struct of_device_id bcm590xx_of_match [ ] = {
{ . compatible = " brcm,bcm59056 " } ,
{ }
} ;
2014-03-15 05:24:50 +04:00
MODULE_DEVICE_TABLE ( of , bcm590xx_of_match ) ;
2014-03-12 03:33:54 +04:00
static const struct i2c_device_id bcm590xx_i2c_id [ ] = {
{ " bcm59056 " } ,
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , bcm590xx_i2c_id ) ;
static struct i2c_driver bcm590xx_i2c_driver = {
. driver = {
. name = " bcm590xx " ,
2020-11-20 19:21:18 +03:00
. of_match_table = bcm590xx_of_match ,
2014-03-12 03:33:54 +04:00
} ,
2022-11-19 01:42:37 +03:00
. probe_new = bcm590xx_i2c_probe ,
2014-03-12 03:33:54 +04:00
. id_table = bcm590xx_i2c_id ,
} ;
module_i2c_driver ( bcm590xx_i2c_driver ) ;
MODULE_AUTHOR ( " Matt Porter <mporter@linaro.org> " ) ;
MODULE_DESCRIPTION ( " BCM590xx multi-function driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;