Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / drivers / mfd / sprd-sc27xx-spi.c
1 /*
2  * Copyright (C) 2017 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <linux/interrupt.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/mfd/core.h>
18 #include <linux/of_device.h>
19 #include <linux/regmap.h>
20 #include <linux/spi/spi.h>
21
22 #define SPRD_PMIC_INT_MASK_STATUS       0x0
23 #define SPRD_PMIC_INT_RAW_STATUS        0x4
24 #define SPRD_PMIC_INT_EN                0x8
25
26 #define SPRD_SC2731_IRQ_BASE            0x140
27 #define SPRD_SC2731_IRQ_NUMS            16
28
29 struct sprd_pmic {
30         struct regmap *regmap;
31         struct device *dev;
32         struct regmap_irq *irqs;
33         struct regmap_irq_chip irq_chip;
34         struct regmap_irq_chip_data *irq_data;
35         int irq;
36 };
37
38 struct sprd_pmic_data {
39         u32 irq_base;
40         u32 num_irqs;
41 };
42
43 /*
44  * Since different PMICs of SC27xx series can have different interrupt
45  * base address and irq number, we should save irq number and irq base
46  * in the device data structure.
47  */
48 static const struct sprd_pmic_data sc2731_data = {
49         .irq_base = SPRD_SC2731_IRQ_BASE,
50         .num_irqs = SPRD_SC2731_IRQ_NUMS,
51 };
52
53 static const struct mfd_cell sprd_pmic_devs[] = {
54         {
55                 .name = "sc27xx-wdt",
56                 .of_compatible = "sprd,sc2731-wdt",
57         }, {
58                 .name = "sc27xx-rtc",
59                 .of_compatible = "sprd,sc2731-rtc",
60         }, {
61                 .name = "sc27xx-charger",
62                 .of_compatible = "sprd,sc2731-charger",
63         }, {
64                 .name = "sc27xx-chg-timer",
65                 .of_compatible = "sprd,sc2731-chg-timer",
66         }, {
67                 .name = "sc27xx-fast-chg",
68                 .of_compatible = "sprd,sc2731-fast-chg",
69         }, {
70                 .name = "sc27xx-chg-wdt",
71                 .of_compatible = "sprd,sc2731-chg-wdt",
72         }, {
73                 .name = "sc27xx-typec",
74                 .of_compatible = "sprd,sc2731-typec",
75         }, {
76                 .name = "sc27xx-flash",
77                 .of_compatible = "sprd,sc2731-flash",
78         }, {
79                 .name = "sc27xx-eic",
80                 .of_compatible = "sprd,sc2731-eic",
81         }, {
82                 .name = "sc27xx-efuse",
83                 .of_compatible = "sprd,sc2731-efuse",
84         }, {
85                 .name = "sc27xx-thermal",
86                 .of_compatible = "sprd,sc2731-thermal",
87         }, {
88                 .name = "sc27xx-adc",
89                 .of_compatible = "sprd,sc2731-adc",
90         }, {
91                 .name = "sc27xx-audio-codec",
92                 .of_compatible = "sprd,sc2731-audio-codec",
93         }, {
94                 .name = "sc27xx-regulator",
95                 .of_compatible = "sprd,sc2731-regulator",
96         }, {
97                 .name = "sc27xx-vibrator",
98                 .of_compatible = "sprd,sc2731-vibrator",
99         }, {
100                 .name = "sc27xx-keypad-led",
101                 .of_compatible = "sprd,sc2731-keypad-led",
102         }, {
103                 .name = "sc27xx-bltc",
104                 .of_compatible = "sprd,sc2731-bltc",
105         }, {
106                 .name = "sc27xx-fgu",
107                 .of_compatible = "sprd,sc2731-fgu",
108         }, {
109                 .name = "sc27xx-7sreset",
110                 .of_compatible = "sprd,sc2731-7sreset",
111         }, {
112                 .name = "sc27xx-poweroff",
113                 .of_compatible = "sprd,sc2731-poweroff",
114         }, {
115                 .name = "sc27xx-syscon",
116                 .of_compatible = "sprd,sc2731-syscon",
117         },
118 };
119
120 static int sprd_pmic_spi_write(void *context, const void *data, size_t count)
121 {
122         struct device *dev = context;
123         struct spi_device *spi = to_spi_device(dev);
124
125         return spi_write(spi, data, count);
126 }
127
128 static int sprd_pmic_spi_read(void *context,
129                               const void *reg, size_t reg_size,
130                               void *val, size_t val_size)
131 {
132         struct device *dev = context;
133         struct spi_device *spi = to_spi_device(dev);
134         u32 rx_buf[2] = { 0 };
135         int ret;
136
137         /* Now we only support one PMIC register to read every time. */
138         if (reg_size != sizeof(u32) || val_size != sizeof(u32))
139                 return -EINVAL;
140
141         /* Copy address to read from into first element of SPI buffer. */
142         memcpy(rx_buf, reg, sizeof(u32));
143         ret = spi_read(spi, rx_buf, 1);
144         if (ret < 0)
145                 return ret;
146
147         memcpy(val, rx_buf, val_size);
148         return 0;
149 }
150
151 static struct regmap_bus sprd_pmic_regmap = {
152         .write = sprd_pmic_spi_write,
153         .read = sprd_pmic_spi_read,
154         .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
155         .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
156 };
157
158 static const struct regmap_config sprd_pmic_config = {
159         .reg_bits = 32,
160         .val_bits = 32,
161         .reg_stride = 4,
162         .max_register = 0xffff,
163 };
164
165 static int sprd_pmic_probe(struct spi_device *spi)
166 {
167         struct sprd_pmic *ddata;
168         const struct sprd_pmic_data *pdata;
169         int ret, i;
170
171         pdata = of_device_get_match_data(&spi->dev);
172         if (!pdata) {
173                 dev_err(&spi->dev, "No matching driver data found\n");
174                 return -EINVAL;
175         }
176
177         ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
178         if (!ddata)
179                 return -ENOMEM;
180
181         ddata->regmap = devm_regmap_init(&spi->dev, &sprd_pmic_regmap,
182                                          &spi->dev, &sprd_pmic_config);
183         if (IS_ERR(ddata->regmap)) {
184                 ret = PTR_ERR(ddata->regmap);
185                 dev_err(&spi->dev, "Failed to allocate register map %d\n", ret);
186                 return ret;
187         }
188
189         spi_set_drvdata(spi, ddata);
190         ddata->dev = &spi->dev;
191         ddata->irq = spi->irq;
192
193         ddata->irq_chip.name = dev_name(&spi->dev);
194         ddata->irq_chip.status_base =
195                 pdata->irq_base + SPRD_PMIC_INT_MASK_STATUS;
196         ddata->irq_chip.mask_base = pdata->irq_base + SPRD_PMIC_INT_EN;
197         ddata->irq_chip.ack_base = 0;
198         ddata->irq_chip.num_regs = 1;
199         ddata->irq_chip.num_irqs = pdata->num_irqs;
200         ddata->irq_chip.mask_invert = true;
201
202         ddata->irqs = devm_kcalloc(&spi->dev,
203                                    pdata->num_irqs, sizeof(struct regmap_irq),
204                                    GFP_KERNEL);
205         if (!ddata->irqs)
206                 return -ENOMEM;
207
208         ddata->irq_chip.irqs = ddata->irqs;
209         for (i = 0; i < pdata->num_irqs; i++) {
210                 ddata->irqs[i].reg_offset = i / pdata->num_irqs;
211                 ddata->irqs[i].mask = BIT(i % pdata->num_irqs);
212         }
213
214         ret = devm_regmap_add_irq_chip(&spi->dev, ddata->regmap, ddata->irq,
215                                        IRQF_ONESHOT | IRQF_NO_SUSPEND, 0,
216                                        &ddata->irq_chip, &ddata->irq_data);
217         if (ret) {
218                 dev_err(&spi->dev, "Failed to add PMIC irq chip %d\n", ret);
219                 return ret;
220         }
221
222         ret = devm_mfd_add_devices(&spi->dev, PLATFORM_DEVID_AUTO,
223                                    sprd_pmic_devs, ARRAY_SIZE(sprd_pmic_devs),
224                                    NULL, 0,
225                                    regmap_irq_get_domain(ddata->irq_data));
226         if (ret) {
227                 dev_err(&spi->dev, "Failed to register device %d\n", ret);
228                 return ret;
229         }
230
231         return 0;
232 }
233
234 static const struct of_device_id sprd_pmic_match[] = {
235         { .compatible = "sprd,sc2731", .data = &sc2731_data },
236         {},
237 };
238 MODULE_DEVICE_TABLE(of, sprd_pmic_match);
239
240 static struct spi_driver sprd_pmic_driver = {
241         .driver = {
242                 .name = "sc27xx-pmic",
243                 .bus = &spi_bus_type,
244                 .of_match_table = sprd_pmic_match,
245         },
246         .probe = sprd_pmic_probe,
247 };
248
249 static int __init sprd_pmic_init(void)
250 {
251         return spi_register_driver(&sprd_pmic_driver);
252 }
253 subsys_initcall(sprd_pmic_init);
254
255 static void __exit sprd_pmic_exit(void)
256 {
257         spi_unregister_driver(&sprd_pmic_driver);
258 }
259 module_exit(sprd_pmic_exit);
260
261 MODULE_LICENSE("GPL v2");
262 MODULE_DESCRIPTION("Spreadtrum SC27xx PMICs driver");
263 MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");