1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2017 Spreadtrum Communications Inc. |
4 | */ |
5 | |
6 | #include <linux/interrupt.h> |
7 | #include <linux/kernel.h> |
8 | #include <linux/module.h> |
9 | #include <linux/mfd/core.h> |
10 | #include <linux/mfd/sc27xx-pmic.h> |
11 | #include <linux/of.h> |
12 | #include <linux/of_platform.h> |
13 | #include <linux/regmap.h> |
14 | #include <linux/spi/spi.h> |
15 | #include <uapi/linux/usb/charger.h> |
16 | |
17 | #define SPRD_PMIC_INT_MASK_STATUS 0x0 |
18 | #define SPRD_PMIC_INT_RAW_STATUS 0x4 |
19 | #define SPRD_PMIC_INT_EN 0x8 |
20 | |
21 | #define SPRD_SC2730_IRQ_BASE 0x80 |
22 | #define SPRD_SC2730_IRQ_NUMS 10 |
23 | #define SPRD_SC2730_CHG_DET 0x1b9c |
24 | #define SPRD_SC2731_IRQ_BASE 0x140 |
25 | #define SPRD_SC2731_IRQ_NUMS 16 |
26 | #define SPRD_SC2731_CHG_DET 0xedc |
27 | |
28 | /* PMIC charger detection definition */ |
29 | #define SPRD_PMIC_CHG_DET_DELAY_US 200000 |
30 | #define SPRD_PMIC_CHG_DET_TIMEOUT 2000000 |
31 | #define SPRD_PMIC_CHG_DET_DONE BIT(11) |
32 | #define SPRD_PMIC_SDP_TYPE BIT(7) |
33 | #define SPRD_PMIC_DCP_TYPE BIT(6) |
34 | #define SPRD_PMIC_CDP_TYPE BIT(5) |
35 | #define SPRD_PMIC_CHG_TYPE_MASK GENMASK(7, 5) |
36 | |
37 | struct sprd_pmic { |
38 | struct regmap *regmap; |
39 | struct device *dev; |
40 | struct regmap_irq *irqs; |
41 | struct regmap_irq_chip irq_chip; |
42 | struct regmap_irq_chip_data *irq_data; |
43 | const struct sprd_pmic_data *pdata; |
44 | int irq; |
45 | }; |
46 | |
47 | struct sprd_pmic_data { |
48 | u32 irq_base; |
49 | u32 num_irqs; |
50 | u32 charger_det; |
51 | }; |
52 | |
53 | /* |
54 | * Since different PMICs of SC27xx series can have different interrupt |
55 | * base address and irq number, we should save irq number and irq base |
56 | * in the device data structure. |
57 | */ |
58 | static const struct sprd_pmic_data sc2730_data = { |
59 | .irq_base = SPRD_SC2730_IRQ_BASE, |
60 | .num_irqs = SPRD_SC2730_IRQ_NUMS, |
61 | .charger_det = SPRD_SC2730_CHG_DET, |
62 | }; |
63 | |
64 | static const struct sprd_pmic_data sc2731_data = { |
65 | .irq_base = SPRD_SC2731_IRQ_BASE, |
66 | .num_irqs = SPRD_SC2731_IRQ_NUMS, |
67 | .charger_det = SPRD_SC2731_CHG_DET, |
68 | }; |
69 | |
70 | enum usb_charger_type sprd_pmic_detect_charger_type(struct device *dev) |
71 | { |
72 | struct spi_device *spi = to_spi_device(dev); |
73 | struct sprd_pmic *ddata = spi_get_drvdata(spi); |
74 | const struct sprd_pmic_data *pdata = ddata->pdata; |
75 | enum usb_charger_type type; |
76 | u32 val; |
77 | int ret; |
78 | |
79 | ret = regmap_read_poll_timeout(ddata->regmap, pdata->charger_det, val, |
80 | (val & SPRD_PMIC_CHG_DET_DONE), |
81 | SPRD_PMIC_CHG_DET_DELAY_US, |
82 | SPRD_PMIC_CHG_DET_TIMEOUT); |
83 | if (ret) { |
84 | dev_err(&spi->dev, "failed to detect charger type\n" ); |
85 | return UNKNOWN_TYPE; |
86 | } |
87 | |
88 | switch (val & SPRD_PMIC_CHG_TYPE_MASK) { |
89 | case SPRD_PMIC_CDP_TYPE: |
90 | type = CDP_TYPE; |
91 | break; |
92 | case SPRD_PMIC_DCP_TYPE: |
93 | type = DCP_TYPE; |
94 | break; |
95 | case SPRD_PMIC_SDP_TYPE: |
96 | type = SDP_TYPE; |
97 | break; |
98 | default: |
99 | type = UNKNOWN_TYPE; |
100 | break; |
101 | } |
102 | |
103 | return type; |
104 | } |
105 | EXPORT_SYMBOL_GPL(sprd_pmic_detect_charger_type); |
106 | |
107 | static int sprd_pmic_spi_write(void *context, const void *data, size_t count) |
108 | { |
109 | struct device *dev = context; |
110 | struct spi_device *spi = to_spi_device(dev); |
111 | |
112 | return spi_write(spi, buf: data, len: count); |
113 | } |
114 | |
115 | static int sprd_pmic_spi_read(void *context, |
116 | const void *reg, size_t reg_size, |
117 | void *val, size_t val_size) |
118 | { |
119 | struct device *dev = context; |
120 | struct spi_device *spi = to_spi_device(dev); |
121 | u32 rx_buf[2] = { 0 }; |
122 | int ret; |
123 | |
124 | /* Now we only support one PMIC register to read every time. */ |
125 | if (reg_size != sizeof(u32) || val_size != sizeof(u32)) |
126 | return -EINVAL; |
127 | |
128 | /* Copy address to read from into first element of SPI buffer. */ |
129 | memcpy(rx_buf, reg, sizeof(u32)); |
130 | ret = spi_read(spi, buf: rx_buf, len: 1); |
131 | if (ret < 0) |
132 | return ret; |
133 | |
134 | memcpy(val, rx_buf, val_size); |
135 | return 0; |
136 | } |
137 | |
138 | static struct regmap_bus sprd_pmic_regmap = { |
139 | .write = sprd_pmic_spi_write, |
140 | .read = sprd_pmic_spi_read, |
141 | .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, |
142 | .val_format_endian_default = REGMAP_ENDIAN_NATIVE, |
143 | }; |
144 | |
145 | static const struct regmap_config sprd_pmic_config = { |
146 | .reg_bits = 32, |
147 | .val_bits = 32, |
148 | .reg_stride = 4, |
149 | .max_register = 0xffff, |
150 | }; |
151 | |
152 | static int sprd_pmic_probe(struct spi_device *spi) |
153 | { |
154 | struct sprd_pmic *ddata; |
155 | const struct sprd_pmic_data *pdata; |
156 | int ret, i; |
157 | |
158 | pdata = of_device_get_match_data(dev: &spi->dev); |
159 | if (!pdata) { |
160 | dev_err(&spi->dev, "No matching driver data found\n" ); |
161 | return -EINVAL; |
162 | } |
163 | |
164 | ddata = devm_kzalloc(dev: &spi->dev, size: sizeof(*ddata), GFP_KERNEL); |
165 | if (!ddata) |
166 | return -ENOMEM; |
167 | |
168 | ddata->regmap = devm_regmap_init(&spi->dev, &sprd_pmic_regmap, |
169 | &spi->dev, &sprd_pmic_config); |
170 | if (IS_ERR(ptr: ddata->regmap)) { |
171 | ret = PTR_ERR(ptr: ddata->regmap); |
172 | dev_err(&spi->dev, "Failed to allocate register map %d\n" , ret); |
173 | return ret; |
174 | } |
175 | |
176 | spi_set_drvdata(spi, data: ddata); |
177 | ddata->dev = &spi->dev; |
178 | ddata->irq = spi->irq; |
179 | ddata->pdata = pdata; |
180 | |
181 | ddata->irq_chip.name = dev_name(dev: &spi->dev); |
182 | ddata->irq_chip.status_base = |
183 | pdata->irq_base + SPRD_PMIC_INT_MASK_STATUS; |
184 | ddata->irq_chip.unmask_base = pdata->irq_base + SPRD_PMIC_INT_EN; |
185 | ddata->irq_chip.ack_base = 0; |
186 | ddata->irq_chip.num_regs = 1; |
187 | ddata->irq_chip.num_irqs = pdata->num_irqs; |
188 | |
189 | ddata->irqs = devm_kcalloc(dev: &spi->dev, |
190 | n: pdata->num_irqs, size: sizeof(struct regmap_irq), |
191 | GFP_KERNEL); |
192 | if (!ddata->irqs) |
193 | return -ENOMEM; |
194 | |
195 | ddata->irq_chip.irqs = ddata->irqs; |
196 | for (i = 0; i < pdata->num_irqs; i++) |
197 | ddata->irqs[i].mask = BIT(i); |
198 | |
199 | ret = devm_regmap_add_irq_chip(dev: &spi->dev, map: ddata->regmap, irq: ddata->irq, |
200 | IRQF_ONESHOT, irq_base: 0, |
201 | chip: &ddata->irq_chip, data: &ddata->irq_data); |
202 | if (ret) { |
203 | dev_err(&spi->dev, "Failed to add PMIC irq chip %d\n" , ret); |
204 | return ret; |
205 | } |
206 | |
207 | ret = devm_of_platform_populate(dev: &spi->dev); |
208 | if (ret) { |
209 | dev_err(&spi->dev, "Failed to populate sub-devices %d\n" , ret); |
210 | return ret; |
211 | } |
212 | |
213 | device_init_wakeup(dev: &spi->dev, enable: true); |
214 | return 0; |
215 | } |
216 | |
217 | static int sprd_pmic_suspend(struct device *dev) |
218 | { |
219 | struct sprd_pmic *ddata = dev_get_drvdata(dev); |
220 | |
221 | if (device_may_wakeup(dev)) |
222 | enable_irq_wake(irq: ddata->irq); |
223 | |
224 | return 0; |
225 | } |
226 | |
227 | static int sprd_pmic_resume(struct device *dev) |
228 | { |
229 | struct sprd_pmic *ddata = dev_get_drvdata(dev); |
230 | |
231 | if (device_may_wakeup(dev)) |
232 | disable_irq_wake(irq: ddata->irq); |
233 | |
234 | return 0; |
235 | } |
236 | |
237 | static DEFINE_SIMPLE_DEV_PM_OPS(sprd_pmic_pm_ops, |
238 | sprd_pmic_suspend, sprd_pmic_resume); |
239 | |
240 | static const struct of_device_id sprd_pmic_match[] = { |
241 | { .compatible = "sprd,sc2730" , .data = &sc2730_data }, |
242 | { .compatible = "sprd,sc2731" , .data = &sc2731_data }, |
243 | {}, |
244 | }; |
245 | MODULE_DEVICE_TABLE(of, sprd_pmic_match); |
246 | |
247 | static const struct spi_device_id sprd_pmic_spi_ids[] = { |
248 | { .name = "sc2730" , .driver_data = (unsigned long)&sc2730_data }, |
249 | { .name = "sc2731" , .driver_data = (unsigned long)&sc2731_data }, |
250 | {}, |
251 | }; |
252 | MODULE_DEVICE_TABLE(spi, sprd_pmic_spi_ids); |
253 | |
254 | static struct spi_driver sprd_pmic_driver = { |
255 | .driver = { |
256 | .name = "sc27xx-pmic" , |
257 | .of_match_table = sprd_pmic_match, |
258 | .pm = pm_sleep_ptr(&sprd_pmic_pm_ops), |
259 | }, |
260 | .probe = sprd_pmic_probe, |
261 | .id_table = sprd_pmic_spi_ids, |
262 | }; |
263 | |
264 | static int __init sprd_pmic_init(void) |
265 | { |
266 | return spi_register_driver(&sprd_pmic_driver); |
267 | } |
268 | subsys_initcall(sprd_pmic_init); |
269 | |
270 | static void __exit sprd_pmic_exit(void) |
271 | { |
272 | spi_unregister_driver(sdrv: &sprd_pmic_driver); |
273 | } |
274 | module_exit(sprd_pmic_exit); |
275 | |
276 | MODULE_LICENSE("GPL v2" ); |
277 | MODULE_DESCRIPTION("Spreadtrum SC27xx PMICs driver" ); |
278 | MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>" ); |
279 | |