1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) STMicroelectronics 2018
3 // Author: Pascal Paillet <p.paillet@st.com>
6 #include <linux/interrupt.h>
7 #include <linux/mfd/core.h>
8 #include <linux/mfd/stpmic1.h>
9 #include <linux/module.h>
10 #include <linux/reboot.h>
12 #include <linux/of_irq.h>
13 #include <linux/of_platform.h>
14 #include <linux/pm_wakeirq.h>
15 #include <linux/regmap.h>
17 #include <dt-bindings/mfd/st,stpmic1.h>
19 #define STPMIC1_MAIN_IRQ 0
21 static const struct regmap_range stpmic1_readable_ranges
[] = {
22 regmap_reg_range(TURN_ON_SR
, VERSION_SR
),
23 regmap_reg_range(MAIN_CR
, LDO6_STDBY_CR
),
24 regmap_reg_range(BST_SW_CR
, BST_SW_CR
),
25 regmap_reg_range(INT_PENDING_R1
, INT_PENDING_R4
),
26 regmap_reg_range(INT_CLEAR_R1
, INT_CLEAR_R4
),
27 regmap_reg_range(INT_MASK_R1
, INT_MASK_R4
),
28 regmap_reg_range(INT_SET_MASK_R1
, INT_SET_MASK_R4
),
29 regmap_reg_range(INT_CLEAR_MASK_R1
, INT_CLEAR_MASK_R4
),
30 regmap_reg_range(INT_SRC_R1
, INT_SRC_R1
),
33 static const struct regmap_range stpmic1_writeable_ranges
[] = {
34 regmap_reg_range(MAIN_CR
, LDO6_STDBY_CR
),
35 regmap_reg_range(BST_SW_CR
, BST_SW_CR
),
36 regmap_reg_range(INT_CLEAR_R1
, INT_CLEAR_R4
),
37 regmap_reg_range(INT_SET_MASK_R1
, INT_SET_MASK_R4
),
38 regmap_reg_range(INT_CLEAR_MASK_R1
, INT_CLEAR_MASK_R4
),
41 static const struct regmap_range stpmic1_volatile_ranges
[] = {
42 regmap_reg_range(TURN_ON_SR
, VERSION_SR
),
43 regmap_reg_range(WCHDG_CR
, WCHDG_CR
),
44 regmap_reg_range(INT_PENDING_R1
, INT_PENDING_R4
),
45 regmap_reg_range(INT_SRC_R1
, INT_SRC_R4
),
48 static const struct regmap_access_table stpmic1_readable_table
= {
49 .yes_ranges
= stpmic1_readable_ranges
,
50 .n_yes_ranges
= ARRAY_SIZE(stpmic1_readable_ranges
),
53 static const struct regmap_access_table stpmic1_writeable_table
= {
54 .yes_ranges
= stpmic1_writeable_ranges
,
55 .n_yes_ranges
= ARRAY_SIZE(stpmic1_writeable_ranges
),
58 static const struct regmap_access_table stpmic1_volatile_table
= {
59 .yes_ranges
= stpmic1_volatile_ranges
,
60 .n_yes_ranges
= ARRAY_SIZE(stpmic1_volatile_ranges
),
63 static const struct regmap_config stpmic1_regmap_config
= {
66 .cache_type
= REGCACHE_MAPLE
,
67 .max_register
= PMIC_MAX_REGISTER_ADDRESS
,
68 .rd_table
= &stpmic1_readable_table
,
69 .wr_table
= &stpmic1_writeable_table
,
70 .volatile_table
= &stpmic1_volatile_table
,
73 static const struct regmap_irq stpmic1_irqs
[] = {
74 REGMAP_IRQ_REG(IT_PONKEY_F
, 0, 0x01),
75 REGMAP_IRQ_REG(IT_PONKEY_R
, 0, 0x02),
76 REGMAP_IRQ_REG(IT_WAKEUP_F
, 0, 0x04),
77 REGMAP_IRQ_REG(IT_WAKEUP_R
, 0, 0x08),
78 REGMAP_IRQ_REG(IT_VBUS_OTG_F
, 0, 0x10),
79 REGMAP_IRQ_REG(IT_VBUS_OTG_R
, 0, 0x20),
80 REGMAP_IRQ_REG(IT_SWOUT_F
, 0, 0x40),
81 REGMAP_IRQ_REG(IT_SWOUT_R
, 0, 0x80),
83 REGMAP_IRQ_REG(IT_CURLIM_BUCK1
, 1, 0x01),
84 REGMAP_IRQ_REG(IT_CURLIM_BUCK2
, 1, 0x02),
85 REGMAP_IRQ_REG(IT_CURLIM_BUCK3
, 1, 0x04),
86 REGMAP_IRQ_REG(IT_CURLIM_BUCK4
, 1, 0x08),
87 REGMAP_IRQ_REG(IT_OCP_OTG
, 1, 0x10),
88 REGMAP_IRQ_REG(IT_OCP_SWOUT
, 1, 0x20),
89 REGMAP_IRQ_REG(IT_OCP_BOOST
, 1, 0x40),
90 REGMAP_IRQ_REG(IT_OVP_BOOST
, 1, 0x80),
92 REGMAP_IRQ_REG(IT_CURLIM_LDO1
, 2, 0x01),
93 REGMAP_IRQ_REG(IT_CURLIM_LDO2
, 2, 0x02),
94 REGMAP_IRQ_REG(IT_CURLIM_LDO3
, 2, 0x04),
95 REGMAP_IRQ_REG(IT_CURLIM_LDO4
, 2, 0x08),
96 REGMAP_IRQ_REG(IT_CURLIM_LDO5
, 2, 0x10),
97 REGMAP_IRQ_REG(IT_CURLIM_LDO6
, 2, 0x20),
98 REGMAP_IRQ_REG(IT_SHORT_SWOTG
, 2, 0x40),
99 REGMAP_IRQ_REG(IT_SHORT_SWOUT
, 2, 0x80),
101 REGMAP_IRQ_REG(IT_TWARN_F
, 3, 0x01),
102 REGMAP_IRQ_REG(IT_TWARN_R
, 3, 0x02),
103 REGMAP_IRQ_REG(IT_VINLOW_F
, 3, 0x04),
104 REGMAP_IRQ_REG(IT_VINLOW_R
, 3, 0x08),
105 REGMAP_IRQ_REG(IT_SWIN_F
, 3, 0x40),
106 REGMAP_IRQ_REG(IT_SWIN_R
, 3, 0x80),
109 static const struct regmap_irq_chip stpmic1_regmap_irq_chip
= {
111 .status_base
= INT_PENDING_R1
,
112 .mask_base
= INT_SET_MASK_R1
,
113 .unmask_base
= INT_CLEAR_MASK_R1
,
114 .mask_unmask_non_inverted
= true,
115 .ack_base
= INT_CLEAR_R1
,
116 .num_regs
= STPMIC1_PMIC_NUM_IRQ_REGS
,
117 .irqs
= stpmic1_irqs
,
118 .num_irqs
= ARRAY_SIZE(stpmic1_irqs
),
121 static int stpmic1_power_off(struct sys_off_data
*data
)
123 struct stpmic1
*ddata
= data
->cb_data
;
125 regmap_update_bits(ddata
->regmap
, MAIN_CR
,
126 SOFTWARE_SWITCH_OFF
, SOFTWARE_SWITCH_OFF
);
131 static int stpmic1_probe(struct i2c_client
*i2c
)
133 struct stpmic1
*ddata
;
134 struct device
*dev
= &i2c
->dev
;
136 struct device_node
*np
= dev
->of_node
;
139 ddata
= devm_kzalloc(dev
, sizeof(struct stpmic1
), GFP_KERNEL
);
143 i2c_set_clientdata(i2c
, ddata
);
146 ddata
->regmap
= devm_regmap_init_i2c(i2c
, &stpmic1_regmap_config
);
147 if (IS_ERR(ddata
->regmap
))
148 return PTR_ERR(ddata
->regmap
);
150 ddata
->irq
= of_irq_get(np
, STPMIC1_MAIN_IRQ
);
151 if (ddata
->irq
< 0) {
152 dev_err(dev
, "Failed to get main IRQ: %d\n", ddata
->irq
);
156 ret
= regmap_read(ddata
->regmap
, VERSION_SR
, ®
);
158 dev_err(dev
, "Unable to read PMIC version\n");
161 dev_info(dev
, "PMIC Chip Version: 0x%x\n", reg
);
163 /* Initialize PMIC IRQ Chip & associated IRQ domains */
164 ret
= devm_regmap_add_irq_chip(dev
, ddata
->regmap
, ddata
->irq
,
165 IRQF_ONESHOT
| IRQF_SHARED
,
166 0, &stpmic1_regmap_irq_chip
,
169 dev_err(dev
, "IRQ Chip registration failed: %d\n", ret
);
173 ret
= devm_register_sys_off_handler(ddata
->dev
,
174 SYS_OFF_MODE_POWER_OFF
,
175 SYS_OFF_PRIO_DEFAULT
,
179 dev_err(ddata
->dev
, "failed to register sys-off handler: %d\n", ret
);
183 return devm_of_platform_populate(dev
);
186 static int stpmic1_suspend(struct device
*dev
)
188 struct i2c_client
*i2c
= to_i2c_client(dev
);
189 struct stpmic1
*pmic_dev
= i2c_get_clientdata(i2c
);
191 disable_irq(pmic_dev
->irq
);
196 static int stpmic1_resume(struct device
*dev
)
198 struct i2c_client
*i2c
= to_i2c_client(dev
);
199 struct stpmic1
*pmic_dev
= i2c_get_clientdata(i2c
);
202 ret
= regcache_sync(pmic_dev
->regmap
);
206 enable_irq(pmic_dev
->irq
);
211 static DEFINE_SIMPLE_DEV_PM_OPS(stpmic1_pm
, stpmic1_suspend
, stpmic1_resume
);
213 static const struct of_device_id stpmic1_of_match
[] = {
214 { .compatible
= "st,stpmic1", },
217 MODULE_DEVICE_TABLE(of
, stpmic1_of_match
);
219 static struct i2c_driver stpmic1_driver
= {
222 .of_match_table
= stpmic1_of_match
,
223 .pm
= pm_sleep_ptr(&stpmic1_pm
),
225 .probe
= stpmic1_probe
,
228 module_i2c_driver(stpmic1_driver
);
230 MODULE_DESCRIPTION("STPMIC1 PMIC Driver");
231 MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
232 MODULE_LICENSE("GPL v2");