1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Broadcom BCM590xx PMU
5 * Copyright 2014 Linaro Limited
6 * Author: Matt Porter <mporter@linaro.org>
10 #include <linux/i2c.h>
11 #include <linux/init.h>
12 #include <linux/mfd/bcm590xx.h>
13 #include <linux/mfd/core.h>
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
17 #include <linux/of_device.h>
18 #include <linux/regmap.h>
19 #include <linux/slab.h>
21 static const struct mfd_cell bcm590xx_devs
[] = {
23 .name
= "bcm590xx-vregs",
27 static const struct regmap_config bcm590xx_regmap_config_pri
= {
30 .max_register
= BCM590XX_MAX_REGISTER_PRI
,
31 .cache_type
= REGCACHE_RBTREE
,
34 static const struct regmap_config bcm590xx_regmap_config_sec
= {
37 .max_register
= BCM590XX_MAX_REGISTER_SEC
,
38 .cache_type
= REGCACHE_RBTREE
,
41 static int bcm590xx_i2c_probe(struct i2c_client
*i2c_pri
,
42 const struct i2c_device_id
*id
)
44 struct bcm590xx
*bcm590xx
;
47 bcm590xx
= devm_kzalloc(&i2c_pri
->dev
, sizeof(*bcm590xx
), GFP_KERNEL
);
51 i2c_set_clientdata(i2c_pri
, bcm590xx
);
52 bcm590xx
->dev
= &i2c_pri
->dev
;
53 bcm590xx
->i2c_pri
= i2c_pri
;
55 bcm590xx
->regmap_pri
= devm_regmap_init_i2c(i2c_pri
,
56 &bcm590xx_regmap_config_pri
);
57 if (IS_ERR(bcm590xx
->regmap_pri
)) {
58 ret
= PTR_ERR(bcm590xx
->regmap_pri
);
59 dev_err(&i2c_pri
->dev
, "primary regmap init failed: %d\n", ret
);
63 /* Secondary I2C slave address is the base address with A(2) asserted */
64 bcm590xx
->i2c_sec
= i2c_new_dummy_device(i2c_pri
->adapter
,
65 i2c_pri
->addr
| BIT(2));
66 if (IS_ERR(bcm590xx
->i2c_sec
)) {
67 dev_err(&i2c_pri
->dev
, "failed to add secondary I2C device\n");
68 return PTR_ERR(bcm590xx
->i2c_sec
);
70 i2c_set_clientdata(bcm590xx
->i2c_sec
, bcm590xx
);
72 bcm590xx
->regmap_sec
= devm_regmap_init_i2c(bcm590xx
->i2c_sec
,
73 &bcm590xx_regmap_config_sec
);
74 if (IS_ERR(bcm590xx
->regmap_sec
)) {
75 ret
= PTR_ERR(bcm590xx
->regmap_sec
);
76 dev_err(&bcm590xx
->i2c_sec
->dev
,
77 "secondary regmap init failed: %d\n", ret
);
81 ret
= devm_mfd_add_devices(&i2c_pri
->dev
, -1, bcm590xx_devs
,
82 ARRAY_SIZE(bcm590xx_devs
), NULL
, 0, NULL
);
84 dev_err(&i2c_pri
->dev
, "failed to add sub-devices: %d\n", ret
);
91 i2c_unregister_device(bcm590xx
->i2c_sec
);
95 static const struct of_device_id bcm590xx_of_match
[] = {
96 { .compatible
= "brcm,bcm59056" },
99 MODULE_DEVICE_TABLE(of
, bcm590xx_of_match
);
101 static const struct i2c_device_id bcm590xx_i2c_id
[] = {
105 MODULE_DEVICE_TABLE(i2c
, bcm590xx_i2c_id
);
107 static struct i2c_driver bcm590xx_i2c_driver
= {
110 .of_match_table
= bcm590xx_of_match
,
112 .probe
= bcm590xx_i2c_probe
,
113 .id_table
= bcm590xx_i2c_id
,
115 module_i2c_driver(bcm590xx_i2c_driver
);
117 MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
118 MODULE_DESCRIPTION("BCM590xx multi-function driver");
119 MODULE_LICENSE("GPL v2");