Lines Matching +full:mapphone +full:- +full:cpcap +full:- +full:charger
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Motorola CPCAP PMIC core driver
19 #include <linux/mfd/motorola-cpcap.h>
43 return -EINVAL; in cpcap_sense_irq()
57 return cpcap_sense_irq(regmap, virq - irq_base); in cpcap_sense_virq()
61 static int cpcap_check_revision(struct cpcap_ddata *cpcap) in cpcap_check_revision() argument
66 ret = cpcap_get_vendor(&cpcap->spi->dev, cpcap->regmap, &vendor); in cpcap_check_revision()
70 ret = cpcap_get_revision(&cpcap->spi->dev, cpcap->regmap, &rev); in cpcap_check_revision()
74 dev_info(&cpcap->spi->dev, "CPCAP vendor: %s rev: %i.%i (%x)\n", in cpcap_check_revision()
80 dev_info(&cpcap->spi->dev, in cpcap_check_revision()
81 "Please add old CPCAP revision support as needed\n"); in cpcap_check_revision()
82 return -ENODEV; in cpcap_check_revision()
90 * irq chip is for register banks 1 - 4 and is available for drivers to use.
94 .name = "cpcap-m2",
103 .name = "cpcap-m2",
112 .name = "cpcap1-4",
122 static void cpcap_init_one_regmap_irq(struct cpcap_ddata *cpcap, in cpcap_init_one_regmap_irq() argument
129 reg_offset = irq - irq_base; in cpcap_init_one_regmap_irq()
130 reg_offset /= cpcap->regmap_conf->val_bits; in cpcap_init_one_regmap_irq()
131 reg_offset *= cpcap->regmap_conf->reg_stride; in cpcap_init_one_regmap_irq()
133 bit = irq % cpcap->regmap_conf->val_bits; in cpcap_init_one_regmap_irq()
136 rirq->reg_offset = reg_offset; in cpcap_init_one_regmap_irq()
137 rirq->mask = mask; in cpcap_init_one_regmap_irq()
140 static int cpcap_init_irq_chip(struct cpcap_ddata *cpcap, int irq_chip, in cpcap_init_irq_chip() argument
147 struct regmap_irq *rirq = &cpcap->irqs[i]; in cpcap_init_irq_chip()
149 cpcap_init_one_regmap_irq(cpcap, rirq, irq_start, i); in cpcap_init_irq_chip()
151 chip->irqs = &cpcap->irqs[irq_start]; in cpcap_init_irq_chip()
152 chip->num_irqs = nr_irqs; in cpcap_init_irq_chip()
153 chip->irq_drv_data = cpcap; in cpcap_init_irq_chip()
155 ret = devm_regmap_add_irq_chip(&cpcap->spi->dev, cpcap->regmap, in cpcap_init_irq_chip()
156 cpcap->spi->irq, in cpcap_init_irq_chip()
157 irq_get_trigger_type(cpcap->spi->irq) | in cpcap_init_irq_chip()
158 IRQF_SHARED, -1, in cpcap_init_irq_chip()
159 chip, &cpcap->irqdata[irq_chip]); in cpcap_init_irq_chip()
161 dev_err(&cpcap->spi->dev, "could not add irq chip %i: %i\n", in cpcap_init_irq_chip()
169 static int cpcap_init_irq(struct cpcap_ddata *cpcap) in cpcap_init_irq() argument
173 cpcap->irqs = devm_kzalloc(&cpcap->spi->dev, in cpcap_init_irq()
174 array3_size(sizeof(*cpcap->irqs), in cpcap_init_irq()
176 cpcap->regmap_conf->val_bits), in cpcap_init_irq()
178 if (!cpcap->irqs) in cpcap_init_irq()
179 return -ENOMEM; in cpcap_init_irq()
181 ret = cpcap_init_irq_chip(cpcap, 0, 0, 16); in cpcap_init_irq()
185 ret = cpcap_init_irq_chip(cpcap, 1, 16, 16); in cpcap_init_irq()
189 ret = cpcap_init_irq_chip(cpcap, 2, 32, 64); in cpcap_init_irq()
193 enable_irq_wake(cpcap->spi->irq); in cpcap_init_irq()
199 { .compatible = "motorola,cpcap", },
206 { .name = "cpcap", },
228 disable_irq(spi->irq); in cpcap_suspend()
237 enable_irq(spi->irq); in cpcap_resume()
247 .of_compatible = "motorola,mapphone-cpcap-adc",
250 .of_compatible = "motorola,cpcap-battery",
252 .name = "cpcap-charger",
253 .of_compatible = "motorola,mapphone-cpcap-charger",
255 .name = "cpcap-regulator",
256 .of_compatible = "motorola,mapphone-cpcap-regulator",
258 .name = "cpcap-rtc",
259 .of_compatible = "motorola,cpcap-rtc",
261 .name = "cpcap-pwrbutton",
262 .of_compatible = "motorola,cpcap-pwrbutton",
264 .name = "cpcap-usb-phy",
265 .of_compatible = "motorola,mapphone-cpcap-usb-phy",
267 .name = "cpcap-led",
269 .of_compatible = "motorola,cpcap-led-red",
271 .name = "cpcap-led",
273 .of_compatible = "motorola,cpcap-led-green",
275 .name = "cpcap-led",
277 .of_compatible = "motorola,cpcap-led-blue",
279 .name = "cpcap-led",
281 .of_compatible = "motorola,cpcap-led-adl",
283 .name = "cpcap-led",
285 .of_compatible = "motorola,cpcap-led-cp",
287 .name = "cpcap-codec",
293 struct cpcap_ddata *cpcap; in cpcap_probe() local
296 cpcap = devm_kzalloc(&spi->dev, sizeof(*cpcap), GFP_KERNEL); in cpcap_probe()
297 if (!cpcap) in cpcap_probe()
298 return -ENOMEM; in cpcap_probe()
300 cpcap->spi = spi; in cpcap_probe()
301 spi_set_drvdata(spi, cpcap); in cpcap_probe()
303 spi->bits_per_word = 16; in cpcap_probe()
304 spi->mode = SPI_MODE_0 | SPI_CS_HIGH; in cpcap_probe()
310 cpcap->regmap_conf = &cpcap_regmap_config; in cpcap_probe()
311 cpcap->regmap = devm_regmap_init_spi(spi, &cpcap_regmap_config); in cpcap_probe()
312 if (IS_ERR(cpcap->regmap)) { in cpcap_probe()
313 ret = PTR_ERR(cpcap->regmap); in cpcap_probe()
314 dev_err(&cpcap->spi->dev, "Failed to initialize regmap: %d\n", in cpcap_probe()
320 ret = cpcap_check_revision(cpcap); in cpcap_probe()
322 dev_err(&cpcap->spi->dev, "Failed to detect CPCAP: %i\n", ret); in cpcap_probe()
326 ret = cpcap_init_irq(cpcap); in cpcap_probe()
330 /* Parent SPI controller uses DMA, CPCAP and child devices do not */ in cpcap_probe()
331 spi->dev.coherent_dma_mask = 0; in cpcap_probe()
332 spi->dev.dma_mask = &spi->dev.coherent_dma_mask; in cpcap_probe()
334 return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices, in cpcap_probe()
340 .name = "cpcap-core",
349 MODULE_ALIAS("platform:cpcap");
350 MODULE_DESCRIPTION("CPCAP driver");