hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/mfd/rohm-bd718x7.c
....@@ -2,26 +2,21 @@
22 //
33 // Copyright (C) 2018 ROHM Semiconductors
44 //
5
-// ROHM BD71837MWV PMIC driver
5
+// ROHM BD71837MWV and BD71847MWV PMIC driver
66 //
7
-// Datasheet available from
7
+// Datasheet for BD71837MWV available from
88 // https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
99
10
+#include <linux/gpio_keys.h>
1011 #include <linux/i2c.h>
1112 #include <linux/input.h>
1213 #include <linux/interrupt.h>
1314 #include <linux/mfd/rohm-bd718x7.h>
1415 #include <linux/mfd/core.h>
1516 #include <linux/module.h>
17
+#include <linux/of_device.h>
1618 #include <linux/regmap.h>
17
-
18
-/*
19
- * gpio_keys.h requires definiton of bool. It is brought in
20
- * by above includes. Keep this as last until gpio_keys.h gets fixed.
21
- */
22
-#include <linux/gpio_keys.h>
23
-
24
-static const u8 supported_revisions[] = { 0xA2 /* BD71837 */ };
19
+#include <linux/types.h>
2520
2621 static struct gpio_keys_button button = {
2722 .code = KEY_POWER,
....@@ -45,32 +40,42 @@
4540 { .name = "bd71837-pmic", },
4641 };
4742
48
-static const struct regmap_irq bd71837_irqs[] = {
49
- REGMAP_IRQ_REG(BD71837_INT_SWRST, 0, BD71837_INT_SWRST_MASK),
50
- REGMAP_IRQ_REG(BD71837_INT_PWRBTN_S, 0, BD71837_INT_PWRBTN_S_MASK),
51
- REGMAP_IRQ_REG(BD71837_INT_PWRBTN_L, 0, BD71837_INT_PWRBTN_L_MASK),
52
- REGMAP_IRQ_REG(BD71837_INT_PWRBTN, 0, BD71837_INT_PWRBTN_MASK),
53
- REGMAP_IRQ_REG(BD71837_INT_WDOG, 0, BD71837_INT_WDOG_MASK),
54
- REGMAP_IRQ_REG(BD71837_INT_ON_REQ, 0, BD71837_INT_ON_REQ_MASK),
55
- REGMAP_IRQ_REG(BD71837_INT_STBY_REQ, 0, BD71837_INT_STBY_REQ_MASK),
43
+static struct mfd_cell bd71847_mfd_cells[] = {
44
+ {
45
+ .name = "gpio-keys",
46
+ .platform_data = &bd718xx_powerkey_data,
47
+ .pdata_size = sizeof(bd718xx_powerkey_data),
48
+ },
49
+ { .name = "bd71847-clk", },
50
+ { .name = "bd71847-pmic", },
5651 };
5752
58
-static struct regmap_irq_chip bd71837_irq_chip = {
59
- .name = "bd71837-irq",
60
- .irqs = bd71837_irqs,
61
- .num_irqs = ARRAY_SIZE(bd71837_irqs),
53
+static const struct regmap_irq bd718xx_irqs[] = {
54
+ REGMAP_IRQ_REG(BD718XX_INT_SWRST, 0, BD718XX_INT_SWRST_MASK),
55
+ REGMAP_IRQ_REG(BD718XX_INT_PWRBTN_S, 0, BD718XX_INT_PWRBTN_S_MASK),
56
+ REGMAP_IRQ_REG(BD718XX_INT_PWRBTN_L, 0, BD718XX_INT_PWRBTN_L_MASK),
57
+ REGMAP_IRQ_REG(BD718XX_INT_PWRBTN, 0, BD718XX_INT_PWRBTN_MASK),
58
+ REGMAP_IRQ_REG(BD718XX_INT_WDOG, 0, BD718XX_INT_WDOG_MASK),
59
+ REGMAP_IRQ_REG(BD718XX_INT_ON_REQ, 0, BD718XX_INT_ON_REQ_MASK),
60
+ REGMAP_IRQ_REG(BD718XX_INT_STBY_REQ, 0, BD718XX_INT_STBY_REQ_MASK),
61
+};
62
+
63
+static struct regmap_irq_chip bd718xx_irq_chip = {
64
+ .name = "bd718xx-irq",
65
+ .irqs = bd718xx_irqs,
66
+ .num_irqs = ARRAY_SIZE(bd718xx_irqs),
6267 .num_regs = 1,
6368 .irq_reg_stride = 1,
64
- .status_base = BD71837_REG_IRQ,
65
- .mask_base = BD71837_REG_MIRQ,
66
- .ack_base = BD71837_REG_IRQ,
69
+ .status_base = BD718XX_REG_IRQ,
70
+ .mask_base = BD718XX_REG_MIRQ,
71
+ .ack_base = BD718XX_REG_IRQ,
6772 .init_ack_masked = true,
6873 .mask_invert = false,
6974 };
7075
7176 static const struct regmap_range pmic_status_range = {
72
- .range_min = BD71837_REG_IRQ,
73
- .range_max = BD71837_REG_POW_STATE,
77
+ .range_min = BD718XX_REG_IRQ,
78
+ .range_max = BD718XX_REG_POW_STATE,
7479 };
7580
7681 static const struct regmap_access_table volatile_regs = {
....@@ -78,88 +83,110 @@
7883 .n_yes_ranges = 1,
7984 };
8085
81
-static const struct regmap_config bd71837_regmap_config = {
86
+static const struct regmap_config bd718xx_regmap_config = {
8287 .reg_bits = 8,
8388 .val_bits = 8,
8489 .volatile_table = &volatile_regs,
85
- .max_register = BD71837_MAX_REGISTER - 1,
90
+ .max_register = BD718XX_MAX_REGISTER - 1,
8691 .cache_type = REGCACHE_RBTREE,
8792 };
8893
89
-static int bd71837_i2c_probe(struct i2c_client *i2c,
94
+static int bd718xx_init_press_duration(struct bd718xx *bd718xx)
95
+{
96
+ struct device* dev = bd718xx->chip.dev;
97
+ u32 short_press_ms, long_press_ms;
98
+ u32 short_press_value, long_press_value;
99
+ int ret;
100
+
101
+ ret = of_property_read_u32(dev->of_node, "rohm,short-press-ms",
102
+ &short_press_ms);
103
+ if (!ret) {
104
+ short_press_value = min(15u, (short_press_ms + 250) / 500);
105
+ ret = regmap_update_bits(bd718xx->chip.regmap,
106
+ BD718XX_REG_PWRONCONFIG0,
107
+ BD718XX_PWRBTN_PRESS_DURATION_MASK,
108
+ short_press_value);
109
+ if (ret) {
110
+ dev_err(dev, "Failed to init pwron short press\n");
111
+ return ret;
112
+ }
113
+ }
114
+
115
+ ret = of_property_read_u32(dev->of_node, "rohm,long-press-ms",
116
+ &long_press_ms);
117
+ if (!ret) {
118
+ long_press_value = min(15u, (long_press_ms + 500) / 1000);
119
+ ret = regmap_update_bits(bd718xx->chip.regmap,
120
+ BD718XX_REG_PWRONCONFIG1,
121
+ BD718XX_PWRBTN_PRESS_DURATION_MASK,
122
+ long_press_value);
123
+ if (ret) {
124
+ dev_err(dev, "Failed to init pwron long press\n");
125
+ return ret;
126
+ }
127
+ }
128
+
129
+ return 0;
130
+}
131
+
132
+static int bd718xx_i2c_probe(struct i2c_client *i2c,
90133 const struct i2c_device_id *id)
91134 {
92
- struct bd71837 *bd71837;
93
- int ret, i;
94
- unsigned int val;
135
+ struct bd718xx *bd718xx;
136
+ int ret;
137
+ unsigned int chip_type;
138
+ struct mfd_cell *mfd;
139
+ int cells;
95140
96
- bd71837 = devm_kzalloc(&i2c->dev, sizeof(struct bd71837), GFP_KERNEL);
97
-
98
- if (!bd71837)
99
- return -ENOMEM;
100
-
101
- bd71837->chip_irq = i2c->irq;
102
-
103
- if (!bd71837->chip_irq) {
141
+ if (!i2c->irq) {
104142 dev_err(&i2c->dev, "No IRQ configured\n");
105143 return -EINVAL;
106144 }
107145
108
- bd71837->dev = &i2c->dev;
109
- dev_set_drvdata(&i2c->dev, bd71837);
146
+ bd718xx = devm_kzalloc(&i2c->dev, sizeof(struct bd718xx), GFP_KERNEL);
110147
111
- bd71837->regmap = devm_regmap_init_i2c(i2c, &bd71837_regmap_config);
112
- if (IS_ERR(bd71837->regmap)) {
148
+ if (!bd718xx)
149
+ return -ENOMEM;
150
+
151
+ bd718xx->chip_irq = i2c->irq;
152
+ chip_type = (unsigned int)(uintptr_t)
153
+ of_device_get_match_data(&i2c->dev);
154
+ switch (chip_type) {
155
+ case ROHM_CHIP_TYPE_BD71837:
156
+ mfd = bd71837_mfd_cells;
157
+ cells = ARRAY_SIZE(bd71837_mfd_cells);
158
+ break;
159
+ case ROHM_CHIP_TYPE_BD71847:
160
+ mfd = bd71847_mfd_cells;
161
+ cells = ARRAY_SIZE(bd71847_mfd_cells);
162
+ break;
163
+ default:
164
+ dev_err(&i2c->dev, "Unknown device type");
165
+ return -EINVAL;
166
+ }
167
+ bd718xx->chip.dev = &i2c->dev;
168
+ dev_set_drvdata(&i2c->dev, bd718xx);
169
+
170
+ bd718xx->chip.regmap = devm_regmap_init_i2c(i2c,
171
+ &bd718xx_regmap_config);
172
+ if (IS_ERR(bd718xx->chip.regmap)) {
113173 dev_err(&i2c->dev, "regmap initialization failed\n");
114
- return PTR_ERR(bd71837->regmap);
174
+ return PTR_ERR(bd718xx->chip.regmap);
115175 }
116176
117
- ret = regmap_read(bd71837->regmap, BD71837_REG_REV, &val);
118
- if (ret) {
119
- dev_err(&i2c->dev, "Read BD71837_REG_DEVICE failed\n");
120
- return ret;
121
- }
122
- for (i = 0; i < ARRAY_SIZE(supported_revisions); i++)
123
- if (supported_revisions[i] == val)
124
- break;
125
-
126
- if (i == ARRAY_SIZE(supported_revisions)) {
127
- dev_err(&i2c->dev, "Unsupported chip revision\n");
128
- return -ENODEV;
129
- }
130
-
131
- ret = devm_regmap_add_irq_chip(&i2c->dev, bd71837->regmap,
132
- bd71837->chip_irq, IRQF_ONESHOT, 0,
133
- &bd71837_irq_chip, &bd71837->irq_data);
177
+ ret = devm_regmap_add_irq_chip(&i2c->dev, bd718xx->chip.regmap,
178
+ bd718xx->chip_irq, IRQF_ONESHOT, 0,
179
+ &bd718xx_irq_chip, &bd718xx->irq_data);
134180 if (ret) {
135181 dev_err(&i2c->dev, "Failed to add irq_chip\n");
136182 return ret;
137183 }
138184
139
- /* Configure short press to 10 milliseconds */
140
- ret = regmap_update_bits(bd71837->regmap,
141
- BD71837_REG_PWRONCONFIG0,
142
- BD718XX_PWRBTN_PRESS_DURATION_MASK,
143
- BD718XX_PWRBTN_SHORT_PRESS_10MS);
144
- if (ret) {
145
- dev_err(&i2c->dev,
146
- "Failed to configure button short press timeout\n");
185
+ ret = bd718xx_init_press_duration(bd718xx);
186
+ if (ret)
147187 return ret;
148
- }
149188
150
- /* Configure long press to 10 seconds */
151
- ret = regmap_update_bits(bd71837->regmap,
152
- BD71837_REG_PWRONCONFIG1,
153
- BD718XX_PWRBTN_PRESS_DURATION_MASK,
154
- BD718XX_PWRBTN_LONG_PRESS_10S);
155
-
156
- if (ret) {
157
- dev_err(&i2c->dev,
158
- "Failed to configure button long press timeout\n");
159
- return ret;
160
- }
161
-
162
- ret = regmap_irq_get_virq(bd71837->irq_data, BD71837_INT_PWRBTN_S);
189
+ ret = regmap_irq_get_virq(bd718xx->irq_data, BD718XX_INT_PWRBTN_S);
163190
164191 if (ret < 0) {
165192 dev_err(&i2c->dev, "Failed to get the IRQ\n");
....@@ -168,44 +195,54 @@
168195
169196 button.irq = ret;
170197
171
- ret = devm_mfd_add_devices(bd71837->dev, PLATFORM_DEVID_AUTO,
172
- bd71837_mfd_cells,
173
- ARRAY_SIZE(bd71837_mfd_cells), NULL, 0,
174
- regmap_irq_get_domain(bd71837->irq_data));
198
+ ret = devm_mfd_add_devices(bd718xx->chip.dev, PLATFORM_DEVID_AUTO,
199
+ mfd, cells, NULL, 0,
200
+ regmap_irq_get_domain(bd718xx->irq_data));
175201 if (ret)
176202 dev_err(&i2c->dev, "Failed to create subdevices\n");
177203
178204 return ret;
179205 }
180206
181
-static const struct of_device_id bd71837_of_match[] = {
182
- { .compatible = "rohm,bd71837", },
207
+static const struct of_device_id bd718xx_of_match[] = {
208
+ {
209
+ .compatible = "rohm,bd71837",
210
+ .data = (void *)ROHM_CHIP_TYPE_BD71837,
211
+ },
212
+ {
213
+ .compatible = "rohm,bd71847",
214
+ .data = (void *)ROHM_CHIP_TYPE_BD71847,
215
+ },
216
+ {
217
+ .compatible = "rohm,bd71850",
218
+ .data = (void *)ROHM_CHIP_TYPE_BD71847,
219
+ },
183220 { }
184221 };
185
-MODULE_DEVICE_TABLE(of, bd71837_of_match);
222
+MODULE_DEVICE_TABLE(of, bd718xx_of_match);
186223
187
-static struct i2c_driver bd71837_i2c_driver = {
224
+static struct i2c_driver bd718xx_i2c_driver = {
188225 .driver = {
189226 .name = "rohm-bd718x7",
190
- .of_match_table = bd71837_of_match,
227
+ .of_match_table = bd718xx_of_match,
191228 },
192
- .probe = bd71837_i2c_probe,
229
+ .probe = bd718xx_i2c_probe,
193230 };
194231
195
-static int __init bd71837_i2c_init(void)
232
+static int __init bd718xx_i2c_init(void)
196233 {
197
- return i2c_add_driver(&bd71837_i2c_driver);
234
+ return i2c_add_driver(&bd718xx_i2c_driver);
198235 }
199236
200237 /* Initialise early so consumer devices can complete system boot */
201
-subsys_initcall(bd71837_i2c_init);
238
+subsys_initcall(bd718xx_i2c_init);
202239
203
-static void __exit bd71837_i2c_exit(void)
240
+static void __exit bd718xx_i2c_exit(void)
204241 {
205
- i2c_del_driver(&bd71837_i2c_driver);
242
+ i2c_del_driver(&bd718xx_i2c_driver);
206243 }
207
-module_exit(bd71837_i2c_exit);
244
+module_exit(bd718xx_i2c_exit);
208245
209246 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
210
-MODULE_DESCRIPTION("ROHM BD71837 Power Management IC driver");
247
+MODULE_DESCRIPTION("ROHM BD71837/BD71847 Power Management IC driver");
211248 MODULE_LICENSE("GPL");