2 * Broadcom BCM590xx PMU
4 * Copyright 2014 Linaro Limited
5 * Author: Matt Porter <mporter@linaro.org>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
13 #include <linux/err.h>
14 #include <linux/i2c.h>
15 #include <linux/init.h>
16 #include <linux/mfd/bcm590xx.h>
17 #include <linux/mfd/core.h>
18 #include <linux/module.h>
19 #include <linux/moduleparam.h>
21 #include <linux/of_device.h>
22 #include <linux/regmap.h>
23 #include <linux/slab.h>
25 static const struct mfd_cell bcm590xx_devs
[] = {
27 .name
= "bcm590xx-vregs",
31 static const struct regmap_config bcm590xx_regmap_config_pri
= {
34 .max_register
= BCM590XX_MAX_REGISTER_PRI
,
35 .cache_type
= REGCACHE_RBTREE
,
38 static const struct regmap_config bcm590xx_regmap_config_sec
= {
41 .max_register
= BCM590XX_MAX_REGISTER_SEC
,
42 .cache_type
= REGCACHE_RBTREE
,
45 static int bcm590xx_i2c_probe(struct i2c_client
*i2c_pri
,
46 const struct i2c_device_id
*id
)
48 struct bcm590xx
*bcm590xx
;
51 bcm590xx
= devm_kzalloc(&i2c_pri
->dev
, sizeof(*bcm590xx
), GFP_KERNEL
);
55 i2c_set_clientdata(i2c_pri
, bcm590xx
);
56 bcm590xx
->dev
= &i2c_pri
->dev
;
57 bcm590xx
->i2c_pri
= i2c_pri
;
59 bcm590xx
->regmap_pri
= devm_regmap_init_i2c(i2c_pri
,
60 &bcm590xx_regmap_config_pri
);
61 if (IS_ERR(bcm590xx
->regmap_pri
)) {
62 ret
= PTR_ERR(bcm590xx
->regmap_pri
);
63 dev_err(&i2c_pri
->dev
, "primary regmap init failed: %d\n", ret
);
67 /* Secondary I2C slave address is the base address with A(2) asserted */
68 bcm590xx
->i2c_sec
= i2c_new_dummy(i2c_pri
->adapter
,
69 i2c_pri
->addr
| BIT(2));
70 if (IS_ERR_OR_NULL(bcm590xx
->i2c_sec
)) {
71 dev_err(&i2c_pri
->dev
, "failed to add secondary I2C device\n");
74 i2c_set_clientdata(bcm590xx
->i2c_sec
, bcm590xx
);
76 bcm590xx
->regmap_sec
= devm_regmap_init_i2c(bcm590xx
->i2c_sec
,
77 &bcm590xx_regmap_config_sec
);
78 if (IS_ERR(bcm590xx
->regmap_sec
)) {
79 ret
= PTR_ERR(bcm590xx
->regmap_sec
);
80 dev_err(&bcm590xx
->i2c_sec
->dev
,
81 "secondary regmap init failed: %d\n", ret
);
85 ret
= mfd_add_devices(&i2c_pri
->dev
, -1, bcm590xx_devs
,
86 ARRAY_SIZE(bcm590xx_devs
), NULL
, 0, NULL
);
88 dev_err(&i2c_pri
->dev
, "failed to add sub-devices: %d\n", ret
);
95 i2c_unregister_device(bcm590xx
->i2c_sec
);
99 static int bcm590xx_i2c_remove(struct i2c_client
*i2c
)
101 mfd_remove_devices(&i2c
->dev
);
105 static const struct of_device_id bcm590xx_of_match
[] = {
106 { .compatible
= "brcm,bcm59056" },
109 MODULE_DEVICE_TABLE(of
, bcm590xx_of_match
);
111 static const struct i2c_device_id bcm590xx_i2c_id
[] = {
115 MODULE_DEVICE_TABLE(i2c
, bcm590xx_i2c_id
);
117 static struct i2c_driver bcm590xx_i2c_driver
= {
120 .owner
= THIS_MODULE
,
121 .of_match_table
= of_match_ptr(bcm590xx_of_match
),
123 .probe
= bcm590xx_i2c_probe
,
124 .remove
= bcm590xx_i2c_remove
,
125 .id_table
= bcm590xx_i2c_id
,
127 module_i2c_driver(bcm590xx_i2c_driver
);
129 MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
130 MODULE_DESCRIPTION("BCM590xx multi-function driver");
131 MODULE_LICENSE("GPL v2");
132 MODULE_ALIAS("i2c:bcm590xx");