.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Motorola CPCAP PMIC core driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2016 Tony Lindgren <tony@atomide.com> |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License version 2 as |
---|
8 | | - * published by the Free Software Foundation. |
---|
9 | 6 | */ |
---|
10 | 7 | |
---|
11 | 8 | #include <linux/device.h> |
---|
.. | .. |
---|
18 | 15 | #include <linux/regmap.h> |
---|
19 | 16 | #include <linux/sysfs.h> |
---|
20 | 17 | |
---|
| 18 | +#include <linux/mfd/core.h> |
---|
21 | 19 | #include <linux/mfd/motorola-cpcap.h> |
---|
22 | 20 | #include <linux/spi/spi.h> |
---|
23 | 21 | |
---|
.. | .. |
---|
99 | 97 | .ack_base = CPCAP_REG_MI1, |
---|
100 | 98 | .mask_base = CPCAP_REG_MIM1, |
---|
101 | 99 | .use_ack = true, |
---|
102 | | - .ack_invert = true, |
---|
| 100 | + .clear_ack = true, |
---|
103 | 101 | }, |
---|
104 | 102 | { |
---|
105 | 103 | .name = "cpcap-m2", |
---|
.. | .. |
---|
108 | 106 | .ack_base = CPCAP_REG_MI2, |
---|
109 | 107 | .mask_base = CPCAP_REG_MIM2, |
---|
110 | 108 | .use_ack = true, |
---|
111 | | - .ack_invert = true, |
---|
| 109 | + .clear_ack = true, |
---|
112 | 110 | }, |
---|
113 | 111 | { |
---|
114 | 112 | .name = "cpcap1-4", |
---|
.. | .. |
---|
117 | 115 | .ack_base = CPCAP_REG_INT1, |
---|
118 | 116 | .mask_base = CPCAP_REG_INTM1, |
---|
119 | 117 | .use_ack = true, |
---|
120 | | - .ack_invert = true, |
---|
| 118 | + .clear_ack = true, |
---|
121 | 119 | }, |
---|
122 | 120 | }; |
---|
123 | 121 | |
---|
.. | .. |
---|
216 | 214 | .val_format_endian = REGMAP_ENDIAN_LITTLE, |
---|
217 | 215 | }; |
---|
218 | 216 | |
---|
| 217 | +#ifdef CONFIG_PM_SLEEP |
---|
| 218 | +static int cpcap_suspend(struct device *dev) |
---|
| 219 | +{ |
---|
| 220 | + struct spi_device *spi = to_spi_device(dev); |
---|
| 221 | + |
---|
| 222 | + disable_irq(spi->irq); |
---|
| 223 | + |
---|
| 224 | + return 0; |
---|
| 225 | +} |
---|
| 226 | + |
---|
| 227 | +static int cpcap_resume(struct device *dev) |
---|
| 228 | +{ |
---|
| 229 | + struct spi_device *spi = to_spi_device(dev); |
---|
| 230 | + |
---|
| 231 | + enable_irq(spi->irq); |
---|
| 232 | + |
---|
| 233 | + return 0; |
---|
| 234 | +} |
---|
| 235 | +#endif |
---|
| 236 | + |
---|
| 237 | +static SIMPLE_DEV_PM_OPS(cpcap_pm, cpcap_suspend, cpcap_resume); |
---|
| 238 | + |
---|
| 239 | +static const struct mfd_cell cpcap_mfd_devices[] = { |
---|
| 240 | + { |
---|
| 241 | + .name = "cpcap_adc", |
---|
| 242 | + .of_compatible = "motorola,mapphone-cpcap-adc", |
---|
| 243 | + }, { |
---|
| 244 | + .name = "cpcap_battery", |
---|
| 245 | + .of_compatible = "motorola,cpcap-battery", |
---|
| 246 | + }, { |
---|
| 247 | + .name = "cpcap-charger", |
---|
| 248 | + .of_compatible = "motorola,mapphone-cpcap-charger", |
---|
| 249 | + }, { |
---|
| 250 | + .name = "cpcap-regulator", |
---|
| 251 | + .of_compatible = "motorola,mapphone-cpcap-regulator", |
---|
| 252 | + }, { |
---|
| 253 | + .name = "cpcap-rtc", |
---|
| 254 | + .of_compatible = "motorola,cpcap-rtc", |
---|
| 255 | + }, { |
---|
| 256 | + .name = "cpcap-pwrbutton", |
---|
| 257 | + .of_compatible = "motorola,cpcap-pwrbutton", |
---|
| 258 | + }, { |
---|
| 259 | + .name = "cpcap-usb-phy", |
---|
| 260 | + .of_compatible = "motorola,mapphone-cpcap-usb-phy", |
---|
| 261 | + }, { |
---|
| 262 | + .name = "cpcap-led", |
---|
| 263 | + .id = 0, |
---|
| 264 | + .of_compatible = "motorola,cpcap-led-red", |
---|
| 265 | + }, { |
---|
| 266 | + .name = "cpcap-led", |
---|
| 267 | + .id = 1, |
---|
| 268 | + .of_compatible = "motorola,cpcap-led-green", |
---|
| 269 | + }, { |
---|
| 270 | + .name = "cpcap-led", |
---|
| 271 | + .id = 2, |
---|
| 272 | + .of_compatible = "motorola,cpcap-led-blue", |
---|
| 273 | + }, { |
---|
| 274 | + .name = "cpcap-led", |
---|
| 275 | + .id = 3, |
---|
| 276 | + .of_compatible = "motorola,cpcap-led-adl", |
---|
| 277 | + }, { |
---|
| 278 | + .name = "cpcap-led", |
---|
| 279 | + .id = 4, |
---|
| 280 | + .of_compatible = "motorola,cpcap-led-cp", |
---|
| 281 | + }, { |
---|
| 282 | + .name = "cpcap-codec", |
---|
| 283 | + } |
---|
| 284 | +}; |
---|
| 285 | + |
---|
219 | 286 | static int cpcap_probe(struct spi_device *spi) |
---|
220 | 287 | { |
---|
221 | 288 | const struct of_device_id *match; |
---|
.. | .. |
---|
260 | 327 | if (ret) |
---|
261 | 328 | return ret; |
---|
262 | 329 | |
---|
263 | | - return devm_of_platform_populate(&cpcap->spi->dev); |
---|
| 330 | + /* Parent SPI controller uses DMA, CPCAP and child devices do not */ |
---|
| 331 | + spi->dev.coherent_dma_mask = 0; |
---|
| 332 | + spi->dev.dma_mask = &spi->dev.coherent_dma_mask; |
---|
| 333 | + |
---|
| 334 | + return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices, |
---|
| 335 | + ARRAY_SIZE(cpcap_mfd_devices), NULL, 0, NULL); |
---|
264 | 336 | } |
---|
265 | 337 | |
---|
266 | 338 | static struct spi_driver cpcap_driver = { |
---|
267 | 339 | .driver = { |
---|
268 | 340 | .name = "cpcap-core", |
---|
269 | 341 | .of_match_table = cpcap_of_match, |
---|
| 342 | + .pm = &cpcap_pm, |
---|
270 | 343 | }, |
---|
271 | 344 | .probe = cpcap_probe, |
---|
272 | 345 | }; |
---|