xref: /openbmc/linux/drivers/mfd/rohm-bd9576.c (revision b1b3ced3)
1*b1b3ced3SMatti Vaittinen // SPDX-License-Identifier: GPL-2.0-or-later
2*b1b3ced3SMatti Vaittinen /*
3*b1b3ced3SMatti Vaittinen  * Copyright (C) 2021 ROHM Semiconductors
4*b1b3ced3SMatti Vaittinen  *
5*b1b3ced3SMatti Vaittinen  * ROHM BD9576MUF and BD9573MUF PMIC driver
6*b1b3ced3SMatti Vaittinen  */
7*b1b3ced3SMatti Vaittinen 
8*b1b3ced3SMatti Vaittinen #include <linux/i2c.h>
9*b1b3ced3SMatti Vaittinen #include <linux/interrupt.h>
10*b1b3ced3SMatti Vaittinen #include <linux/ioport.h>
11*b1b3ced3SMatti Vaittinen #include <linux/irq.h>
12*b1b3ced3SMatti Vaittinen #include <linux/mfd/core.h>
13*b1b3ced3SMatti Vaittinen #include <linux/mfd/rohm-bd957x.h>
14*b1b3ced3SMatti Vaittinen #include <linux/mfd/rohm-generic.h>
15*b1b3ced3SMatti Vaittinen #include <linux/module.h>
16*b1b3ced3SMatti Vaittinen #include <linux/of_device.h>
17*b1b3ced3SMatti Vaittinen #include <linux/regmap.h>
18*b1b3ced3SMatti Vaittinen #include <linux/types.h>
19*b1b3ced3SMatti Vaittinen 
20*b1b3ced3SMatti Vaittinen static struct mfd_cell bd9573_mfd_cells[] = {
21*b1b3ced3SMatti Vaittinen 	{ .name = "bd9573-regulator", },
22*b1b3ced3SMatti Vaittinen 	{ .name = "bd9576-wdt", },
23*b1b3ced3SMatti Vaittinen };
24*b1b3ced3SMatti Vaittinen 
25*b1b3ced3SMatti Vaittinen static struct mfd_cell bd9576_mfd_cells[] = {
26*b1b3ced3SMatti Vaittinen 	{ .name = "bd9576-regulator", },
27*b1b3ced3SMatti Vaittinen 	{ .name = "bd9576-wdt", },
28*b1b3ced3SMatti Vaittinen };
29*b1b3ced3SMatti Vaittinen 
30*b1b3ced3SMatti Vaittinen static const struct regmap_range volatile_ranges[] = {
31*b1b3ced3SMatti Vaittinen 	regmap_reg_range(BD957X_REG_SMRB_ASSERT, BD957X_REG_SMRB_ASSERT),
32*b1b3ced3SMatti Vaittinen 	regmap_reg_range(BD957X_REG_PMIC_INTERNAL_STAT,
33*b1b3ced3SMatti Vaittinen 			 BD957X_REG_PMIC_INTERNAL_STAT),
34*b1b3ced3SMatti Vaittinen 	regmap_reg_range(BD957X_REG_INT_THERM_STAT, BD957X_REG_INT_THERM_STAT),
35*b1b3ced3SMatti Vaittinen 	regmap_reg_range(BD957X_REG_INT_OVP_STAT, BD957X_REG_INT_SYS_STAT),
36*b1b3ced3SMatti Vaittinen 	regmap_reg_range(BD957X_REG_INT_MAIN_STAT, BD957X_REG_INT_MAIN_STAT),
37*b1b3ced3SMatti Vaittinen };
38*b1b3ced3SMatti Vaittinen 
39*b1b3ced3SMatti Vaittinen static const struct regmap_access_table volatile_regs = {
40*b1b3ced3SMatti Vaittinen 	.yes_ranges = &volatile_ranges[0],
41*b1b3ced3SMatti Vaittinen 	.n_yes_ranges = ARRAY_SIZE(volatile_ranges),
42*b1b3ced3SMatti Vaittinen };
43*b1b3ced3SMatti Vaittinen 
44*b1b3ced3SMatti Vaittinen static struct regmap_config bd957x_regmap = {
45*b1b3ced3SMatti Vaittinen 	.reg_bits = 8,
46*b1b3ced3SMatti Vaittinen 	.val_bits = 8,
47*b1b3ced3SMatti Vaittinen 	.volatile_table = &volatile_regs,
48*b1b3ced3SMatti Vaittinen 	.max_register = BD957X_MAX_REGISTER,
49*b1b3ced3SMatti Vaittinen 	.cache_type = REGCACHE_RBTREE,
50*b1b3ced3SMatti Vaittinen };
51*b1b3ced3SMatti Vaittinen 
52*b1b3ced3SMatti Vaittinen static int bd957x_i2c_probe(struct i2c_client *i2c,
53*b1b3ced3SMatti Vaittinen 			     const struct i2c_device_id *id)
54*b1b3ced3SMatti Vaittinen {
55*b1b3ced3SMatti Vaittinen 	int ret;
56*b1b3ced3SMatti Vaittinen 	struct regmap *regmap;
57*b1b3ced3SMatti Vaittinen 	struct mfd_cell *cells;
58*b1b3ced3SMatti Vaittinen 	int num_cells;
59*b1b3ced3SMatti Vaittinen 	unsigned long chip_type;
60*b1b3ced3SMatti Vaittinen 
61*b1b3ced3SMatti Vaittinen 	chip_type = (unsigned long)of_device_get_match_data(&i2c->dev);
62*b1b3ced3SMatti Vaittinen 
63*b1b3ced3SMatti Vaittinen 	switch (chip_type) {
64*b1b3ced3SMatti Vaittinen 	case ROHM_CHIP_TYPE_BD9576:
65*b1b3ced3SMatti Vaittinen 		cells = bd9576_mfd_cells;
66*b1b3ced3SMatti Vaittinen 		num_cells = ARRAY_SIZE(bd9576_mfd_cells);
67*b1b3ced3SMatti Vaittinen 		break;
68*b1b3ced3SMatti Vaittinen 	case ROHM_CHIP_TYPE_BD9573:
69*b1b3ced3SMatti Vaittinen 		cells = bd9573_mfd_cells;
70*b1b3ced3SMatti Vaittinen 		num_cells = ARRAY_SIZE(bd9573_mfd_cells);
71*b1b3ced3SMatti Vaittinen 		break;
72*b1b3ced3SMatti Vaittinen 	default:
73*b1b3ced3SMatti Vaittinen 		dev_err(&i2c->dev, "Unknown device type");
74*b1b3ced3SMatti Vaittinen 		return -EINVAL;
75*b1b3ced3SMatti Vaittinen 	}
76*b1b3ced3SMatti Vaittinen 
77*b1b3ced3SMatti Vaittinen 	regmap = devm_regmap_init_i2c(i2c, &bd957x_regmap);
78*b1b3ced3SMatti Vaittinen 	if (IS_ERR(regmap)) {
79*b1b3ced3SMatti Vaittinen 		dev_err(&i2c->dev, "Failed to initialize Regmap\n");
80*b1b3ced3SMatti Vaittinen 		return PTR_ERR(regmap);
81*b1b3ced3SMatti Vaittinen 	}
82*b1b3ced3SMatti Vaittinen 
83*b1b3ced3SMatti Vaittinen 	ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, cells,
84*b1b3ced3SMatti Vaittinen 				   num_cells, NULL, 0, NULL);
85*b1b3ced3SMatti Vaittinen 	if (ret)
86*b1b3ced3SMatti Vaittinen 		dev_err(&i2c->dev, "Failed to create subdevices\n");
87*b1b3ced3SMatti Vaittinen 
88*b1b3ced3SMatti Vaittinen 	return ret;
89*b1b3ced3SMatti Vaittinen }
90*b1b3ced3SMatti Vaittinen 
91*b1b3ced3SMatti Vaittinen static const struct of_device_id bd957x_of_match[] = {
92*b1b3ced3SMatti Vaittinen 	{ .compatible = "rohm,bd9576", .data = (void *)ROHM_CHIP_TYPE_BD9576, },
93*b1b3ced3SMatti Vaittinen 	{ .compatible = "rohm,bd9573", .data = (void *)ROHM_CHIP_TYPE_BD9573, },
94*b1b3ced3SMatti Vaittinen 	{ },
95*b1b3ced3SMatti Vaittinen };
96*b1b3ced3SMatti Vaittinen MODULE_DEVICE_TABLE(of, bd957x_of_match);
97*b1b3ced3SMatti Vaittinen 
98*b1b3ced3SMatti Vaittinen static struct i2c_driver bd957x_drv = {
99*b1b3ced3SMatti Vaittinen 	.driver = {
100*b1b3ced3SMatti Vaittinen 		.name = "rohm-bd957x",
101*b1b3ced3SMatti Vaittinen 		.of_match_table = bd957x_of_match,
102*b1b3ced3SMatti Vaittinen 	},
103*b1b3ced3SMatti Vaittinen 	.probe = &bd957x_i2c_probe,
104*b1b3ced3SMatti Vaittinen };
105*b1b3ced3SMatti Vaittinen module_i2c_driver(bd957x_drv);
106*b1b3ced3SMatti Vaittinen 
107*b1b3ced3SMatti Vaittinen MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
108*b1b3ced3SMatti Vaittinen MODULE_DESCRIPTION("ROHM BD9576MUF and BD9573MUF Power Management IC driver");
109*b1b3ced3SMatti Vaittinen MODULE_LICENSE("GPL");
110