blob: 22c0e3d876290d56fdea4b9bd09cd23d8bf44a7a [file] [log] [blame]
Thomas Gleixner03761482019-05-28 09:57:24 -07001// SPDX-License-Identifier: GPL-2.0-only
Rabin Vincent62579262010-05-19 11:39:02 +02002/*
3 * Copyright (C) ST-Ericsson SA 2010
4 *
Rabin Vincent62579262010-05-19 11:39:02 +02005 * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
6 * Author: Rabin Vincent <rabin.vincent@stericsson.com>
Mattias Wallinadceed62011-03-02 11:51:11 +01007 * Author: Mattias Wallin <mattias.wallin@stericsson.com>
Rabin Vincent62579262010-05-19 11:39:02 +02008 */
9
10#include <linux/kernel.h>
11#include <linux/slab.h>
12#include <linux/init.h>
13#include <linux/irq.h>
Lee Jones06e589e2012-06-20 13:56:37 +010014#include <linux/irqdomain.h>
Rabin Vincent62579262010-05-19 11:39:02 +020015#include <linux/delay.h>
16#include <linux/interrupt.h>
Paul Gortmaker31cbae22016-10-29 21:24:36 -040017#include <linux/moduleparam.h>
Rabin Vincent62579262010-05-19 11:39:02 +020018#include <linux/platform_device.h>
19#include <linux/mfd/core.h>
Mattias Wallin47c16972010-09-10 17:47:56 +020020#include <linux/mfd/abx500.h>
Linus Walleijee66e652011-12-02 14:16:33 +010021#include <linux/mfd/abx500/ab8500.h>
Lee Jonesd28f1db2012-05-19 17:21:37 +020022#include <linux/mfd/dbx500-prcmu.h>
Lee Jones6bc4a562012-05-17 14:45:13 +010023#include <linux/of.h>
24#include <linux/of_device.h>
Rabin Vincent62579262010-05-19 11:39:02 +020025
26/*
27 * Interrupt register offsets
28 * Bank : 0x0E
29 */
Mattias Wallin47c16972010-09-10 17:47:56 +020030#define AB8500_IT_SOURCE1_REG 0x00
31#define AB8500_IT_SOURCE2_REG 0x01
32#define AB8500_IT_SOURCE3_REG 0x02
33#define AB8500_IT_SOURCE4_REG 0x03
34#define AB8500_IT_SOURCE5_REG 0x04
35#define AB8500_IT_SOURCE6_REG 0x05
36#define AB8500_IT_SOURCE7_REG 0x06
37#define AB8500_IT_SOURCE8_REG 0x07
Linus Walleijd6255522012-02-20 21:42:24 +010038#define AB9540_IT_SOURCE13_REG 0x0C
Mattias Wallin47c16972010-09-10 17:47:56 +020039#define AB8500_IT_SOURCE19_REG 0x12
40#define AB8500_IT_SOURCE20_REG 0x13
41#define AB8500_IT_SOURCE21_REG 0x14
42#define AB8500_IT_SOURCE22_REG 0x15
43#define AB8500_IT_SOURCE23_REG 0x16
44#define AB8500_IT_SOURCE24_REG 0x17
Rabin Vincent62579262010-05-19 11:39:02 +020045
46/*
47 * latch registers
48 */
Mattias Wallin47c16972010-09-10 17:47:56 +020049#define AB8500_IT_LATCH1_REG 0x20
50#define AB8500_IT_LATCH2_REG 0x21
51#define AB8500_IT_LATCH3_REG 0x22
52#define AB8500_IT_LATCH4_REG 0x23
53#define AB8500_IT_LATCH5_REG 0x24
54#define AB8500_IT_LATCH6_REG 0x25
55#define AB8500_IT_LATCH7_REG 0x26
56#define AB8500_IT_LATCH8_REG 0x27
57#define AB8500_IT_LATCH9_REG 0x28
58#define AB8500_IT_LATCH10_REG 0x29
Mattias Wallin92d50a42010-12-07 11:20:47 +010059#define AB8500_IT_LATCH12_REG 0x2B
Linus Walleijd6255522012-02-20 21:42:24 +010060#define AB9540_IT_LATCH13_REG 0x2C
Mattias Wallin47c16972010-09-10 17:47:56 +020061#define AB8500_IT_LATCH19_REG 0x32
62#define AB8500_IT_LATCH20_REG 0x33
63#define AB8500_IT_LATCH21_REG 0x34
64#define AB8500_IT_LATCH22_REG 0x35
65#define AB8500_IT_LATCH23_REG 0x36
66#define AB8500_IT_LATCH24_REG 0x37
Rabin Vincent62579262010-05-19 11:39:02 +020067
68/*
69 * mask registers
70 */
71
Mattias Wallin47c16972010-09-10 17:47:56 +020072#define AB8500_IT_MASK1_REG 0x40
73#define AB8500_IT_MASK2_REG 0x41
74#define AB8500_IT_MASK3_REG 0x42
75#define AB8500_IT_MASK4_REG 0x43
76#define AB8500_IT_MASK5_REG 0x44
77#define AB8500_IT_MASK6_REG 0x45
78#define AB8500_IT_MASK7_REG 0x46
79#define AB8500_IT_MASK8_REG 0x47
80#define AB8500_IT_MASK9_REG 0x48
81#define AB8500_IT_MASK10_REG 0x49
82#define AB8500_IT_MASK11_REG 0x4A
83#define AB8500_IT_MASK12_REG 0x4B
84#define AB8500_IT_MASK13_REG 0x4C
85#define AB8500_IT_MASK14_REG 0x4D
86#define AB8500_IT_MASK15_REG 0x4E
87#define AB8500_IT_MASK16_REG 0x4F
88#define AB8500_IT_MASK17_REG 0x50
89#define AB8500_IT_MASK18_REG 0x51
90#define AB8500_IT_MASK19_REG 0x52
91#define AB8500_IT_MASK20_REG 0x53
92#define AB8500_IT_MASK21_REG 0x54
93#define AB8500_IT_MASK22_REG 0x55
94#define AB8500_IT_MASK23_REG 0x56
95#define AB8500_IT_MASK24_REG 0x57
Lee Jonesa29264b2013-02-25 14:34:26 +000096#define AB8500_IT_MASK25_REG 0x58
Rabin Vincent62579262010-05-19 11:39:02 +020097
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +020098/*
99 * latch hierarchy registers
100 */
101#define AB8500_IT_LATCHHIER1_REG 0x60
102#define AB8500_IT_LATCHHIER2_REG 0x61
103#define AB8500_IT_LATCHHIER3_REG 0x62
Lee Jones3e1a4982013-02-25 14:57:35 +0000104#define AB8540_IT_LATCHHIER4_REG 0x63
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +0200105
106#define AB8500_IT_LATCHHIER_NUM 3
Lee Jones3e1a4982013-02-25 14:57:35 +0000107#define AB8540_IT_LATCHHIER_NUM 4
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +0200108
Mattias Wallin47c16972010-09-10 17:47:56 +0200109#define AB8500_REV_REG 0x80
Linus Walleij0f6208372012-02-20 21:42:10 +0100110#define AB8500_IC_NAME_REG 0x82
Mattias Walline5c238c2011-03-02 11:52:36 +0100111#define AB8500_SWITCH_OFF_STATUS 0x00
Rabin Vincent62579262010-05-19 11:39:02 +0200112
Andrew Lynnb4a31032011-10-11 10:49:47 +0200113#define AB8500_TURN_ON_STATUS 0x00
Lee Jones500e69a2015-10-28 09:15:02 +0000114#define AB8505_TURN_ON_STATUS_2 0x04
Andrew Lynnb4a31032011-10-11 10:49:47 +0200115
Rajkumar Kasirajanf04a9d8a2012-05-30 16:32:37 +0530116#define AB8500_CH_USBCH_STAT1_REG 0x02
117#define VBUS_DET_DBNC100 0x02
118#define VBUS_DET_DBNC1 0x01
119
120static DEFINE_SPINLOCK(on_stat_lock);
121static u8 turn_on_stat_mask = 0xFF;
122static u8 turn_on_stat_set;
Rickard Andersson6ef94182012-04-17 09:30:57 +0200123static bool no_bm; /* No battery management */
Paul Gortmaker31cbae22016-10-29 21:24:36 -0400124/*
125 * not really modular, but the easiest way to keep compat with existing
126 * bootargs behaviour is to continue using module_param here.
127 */
Rickard Andersson6ef94182012-04-17 09:30:57 +0200128module_param(no_bm, bool, S_IRUGO);
129
Linus Walleijd6255522012-02-20 21:42:24 +0100130#define AB9540_MODEM_CTRL2_REG 0x23
131#define AB9540_MODEM_CTRL2_SWDBBRSTN_BIT BIT(2)
132
Rabin Vincent62579262010-05-19 11:39:02 +0200133/*
134 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
Linus Walleij2ced4452012-02-20 21:42:17 +0100135 * numbers are indexed into this array with (num / 8). The interupts are
136 * defined in linux/mfd/ab8500.h
Rabin Vincent62579262010-05-19 11:39:02 +0200137 *
138 * This is one off from the register names, i.e. AB8500_IT_MASK1_REG is at
139 * offset 0.
140 */
Linus Walleij2ced4452012-02-20 21:42:17 +0100141/* AB8500 support */
Rabin Vincent62579262010-05-19 11:39:02 +0200142static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = {
Mattias Wallin92d50a42010-12-07 11:20:47 +0100143 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21,
Rabin Vincent62579262010-05-19 11:39:02 +0200144};
145
Lee Jonesa29264b2013-02-25 14:34:26 +0000146/* AB9540 / AB8505 support */
Linus Walleijd6255522012-02-20 21:42:24 +0100147static const int ab9540_irq_regoffset[AB9540_NUM_IRQ_REGS] = {
Lee Jonesa29264b2013-02-25 14:34:26 +0000148 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22, 23
Linus Walleijd6255522012-02-20 21:42:24 +0100149};
150
Lee Jones3e1a4982013-02-25 14:57:35 +0000151/* AB8540 support */
152static const int ab8540_irq_regoffset[AB8540_NUM_IRQ_REGS] = {
Lee Jones7ccf40b2014-05-08 14:11:37 +0100153 0, 1, 2, 3, 4, -1, -1, -1, -1, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22,
154 23, 25, 26, 27, 28, 29, 30, 31,
Lee Jones3e1a4982013-02-25 14:57:35 +0000155};
156
Linus Walleij0f6208372012-02-20 21:42:10 +0100157static const char ab8500_version_str[][7] = {
158 [AB8500_VERSION_AB8500] = "AB8500",
159 [AB8500_VERSION_AB8505] = "AB8505",
160 [AB8500_VERSION_AB9540] = "AB9540",
161 [AB8500_VERSION_AB8540] = "AB8540",
162};
163
Lee Jones822672a2012-06-20 13:56:38 +0100164static int ab8500_prcmu_write(struct ab8500 *ab8500, u16 addr, u8 data)
Lee Jonesd28f1db2012-05-19 17:21:37 +0200165{
166 int ret;
167
168 ret = prcmu_abb_write((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1);
169 if (ret < 0)
170 dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
171 return ret;
172}
173
Lee Jones822672a2012-06-20 13:56:38 +0100174static int ab8500_prcmu_write_masked(struct ab8500 *ab8500, u16 addr, u8 mask,
Lee Jonesd28f1db2012-05-19 17:21:37 +0200175 u8 data)
176{
177 int ret;
178
179 ret = prcmu_abb_write_masked((u8)(addr >> 8), (u8)(addr & 0xFF), &data,
180 &mask, 1);
181 if (ret < 0)
182 dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
183 return ret;
184}
185
Lee Jones822672a2012-06-20 13:56:38 +0100186static int ab8500_prcmu_read(struct ab8500 *ab8500, u16 addr)
Lee Jonesd28f1db2012-05-19 17:21:37 +0200187{
188 int ret;
189 u8 data;
190
191 ret = prcmu_abb_read((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1);
192 if (ret < 0) {
193 dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
194 return ret;
195 }
196 return (int)data;
197}
198
Mattias Wallin47c16972010-09-10 17:47:56 +0200199static int ab8500_get_chip_id(struct device *dev)
200{
Mattias Wallin6bce7bf2010-12-02 15:08:32 +0100201 struct ab8500 *ab8500;
202
203 if (!dev)
204 return -EINVAL;
205 ab8500 = dev_get_drvdata(dev->parent);
206 return ab8500 ? (int)ab8500->chip_id : -EINVAL;
Mattias Wallin47c16972010-09-10 17:47:56 +0200207}
208
209static int set_register_interruptible(struct ab8500 *ab8500, u8 bank,
210 u8 reg, u8 data)
Rabin Vincent62579262010-05-19 11:39:02 +0200211{
212 int ret;
Mattias Wallin47c16972010-09-10 17:47:56 +0200213 /*
214 * Put the u8 bank and u8 register together into a an u16.
215 * The bank on higher 8 bits and register in lower 8 bits.
Lee Jones500e69a2015-10-28 09:15:02 +0000216 */
Mattias Wallin47c16972010-09-10 17:47:56 +0200217 u16 addr = ((u16)bank) << 8 | reg;
Rabin Vincent62579262010-05-19 11:39:02 +0200218
219 dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data);
220
Rabin Vincent392cbd12012-03-08 14:01:46 +0100221 mutex_lock(&ab8500->lock);
Mattias Wallin47c16972010-09-10 17:47:56 +0200222
223 ret = ab8500->write(ab8500, addr, data);
224 if (ret < 0)
225 dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
226 addr, ret);
227 mutex_unlock(&ab8500->lock);
228
229 return ret;
230}
231
232static int ab8500_set_register(struct device *dev, u8 bank,
233 u8 reg, u8 value)
234{
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200235 int ret;
Mattias Wallin47c16972010-09-10 17:47:56 +0200236 struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
237
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200238 atomic_inc(&ab8500->transfer_ongoing);
239 ret = set_register_interruptible(ab8500, bank, reg, value);
240 atomic_dec(&ab8500->transfer_ongoing);
241 return ret;
Mattias Wallin47c16972010-09-10 17:47:56 +0200242}
243
244static int get_register_interruptible(struct ab8500 *ab8500, u8 bank,
245 u8 reg, u8 *value)
246{
247 int ret;
Mattias Wallin47c16972010-09-10 17:47:56 +0200248 u16 addr = ((u16)bank) << 8 | reg;
249
Rabin Vincent392cbd12012-03-08 14:01:46 +0100250 mutex_lock(&ab8500->lock);
Mattias Wallin47c16972010-09-10 17:47:56 +0200251
252 ret = ab8500->read(ab8500, addr);
253 if (ret < 0)
254 dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
255 addr, ret);
256 else
257 *value = ret;
258
259 mutex_unlock(&ab8500->lock);
260 dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret);
261
Dan Carpenter10628e32018-10-25 15:43:44 +0300262 return (ret < 0) ? ret : 0;
Mattias Wallin47c16972010-09-10 17:47:56 +0200263}
264
265static int ab8500_get_register(struct device *dev, u8 bank,
266 u8 reg, u8 *value)
267{
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200268 int ret;
Mattias Wallin47c16972010-09-10 17:47:56 +0200269 struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
270
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200271 atomic_inc(&ab8500->transfer_ongoing);
272 ret = get_register_interruptible(ab8500, bank, reg, value);
273 atomic_dec(&ab8500->transfer_ongoing);
274 return ret;
Mattias Wallin47c16972010-09-10 17:47:56 +0200275}
276
277static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank,
278 u8 reg, u8 bitmask, u8 bitvalues)
279{
280 int ret;
Mattias Wallin47c16972010-09-10 17:47:56 +0200281 u16 addr = ((u16)bank) << 8 | reg;
282
Rabin Vincent392cbd12012-03-08 14:01:46 +0100283 mutex_lock(&ab8500->lock);
Mattias Wallin47c16972010-09-10 17:47:56 +0200284
Mattias Nilssonbc628fd2012-03-08 14:02:20 +0100285 if (ab8500->write_masked == NULL) {
286 u8 data;
287
288 ret = ab8500->read(ab8500, addr);
289 if (ret < 0) {
290 dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
291 addr, ret);
292 goto out;
293 }
294
295 data = (u8)ret;
296 data = (~bitmask & data) | (bitmask & bitvalues);
297
298 ret = ab8500->write(ab8500, addr, data);
299 if (ret < 0)
300 dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
301 addr, ret);
302
303 dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr,
304 data);
Mattias Wallin47c16972010-09-10 17:47:56 +0200305 goto out;
306 }
Mattias Nilssonbc628fd2012-03-08 14:02:20 +0100307 ret = ab8500->write_masked(ab8500, addr, bitmask, bitvalues);
Rabin Vincent62579262010-05-19 11:39:02 +0200308 if (ret < 0)
Mattias Nilssonbc628fd2012-03-08 14:02:20 +0100309 dev_err(ab8500->dev, "failed to modify reg %#x: %d\n", addr,
310 ret);
Rabin Vincent62579262010-05-19 11:39:02 +0200311out:
312 mutex_unlock(&ab8500->lock);
313 return ret;
314}
Mattias Wallin47c16972010-09-10 17:47:56 +0200315
316static int ab8500_mask_and_set_register(struct device *dev,
317 u8 bank, u8 reg, u8 bitmask, u8 bitvalues)
318{
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200319 int ret;
Mattias Wallin47c16972010-09-10 17:47:56 +0200320 struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
321
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200322 atomic_inc(&ab8500->transfer_ongoing);
Lee Jones7ccf40b2014-05-08 14:11:37 +0100323 ret = mask_and_set_register_interruptible(ab8500, bank, reg,
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200324 bitmask, bitvalues);
325 atomic_dec(&ab8500->transfer_ongoing);
326 return ret;
Mattias Wallin47c16972010-09-10 17:47:56 +0200327}
328
329static struct abx500_ops ab8500_ops = {
330 .get_chip_id = ab8500_get_chip_id,
331 .get_register = ab8500_get_register,
332 .set_register = ab8500_set_register,
333 .get_register_page = NULL,
334 .set_register_page = NULL,
335 .mask_and_set_register = ab8500_mask_and_set_register,
336 .event_registers_startup_state_get = NULL,
337 .startup_irq_enabled = NULL,
Mian Yousaf Kaukab1d843a62012-01-27 11:35:41 +0100338 .dump_all_banks = ab8500_dump_all_banks,
Mattias Wallin47c16972010-09-10 17:47:56 +0200339};
Rabin Vincent62579262010-05-19 11:39:02 +0200340
Mark Brown9505a0a2010-12-11 13:16:08 +0000341static void ab8500_irq_lock(struct irq_data *data)
Rabin Vincent62579262010-05-19 11:39:02 +0200342{
Mark Brown9505a0a2010-12-11 13:16:08 +0000343 struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
Rabin Vincent62579262010-05-19 11:39:02 +0200344
345 mutex_lock(&ab8500->irq_lock);
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200346 atomic_inc(&ab8500->transfer_ongoing);
Rabin Vincent62579262010-05-19 11:39:02 +0200347}
348
Mark Brown9505a0a2010-12-11 13:16:08 +0000349static void ab8500_irq_sync_unlock(struct irq_data *data)
Rabin Vincent62579262010-05-19 11:39:02 +0200350{
Mark Brown9505a0a2010-12-11 13:16:08 +0000351 struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
Rabin Vincent62579262010-05-19 11:39:02 +0200352 int i;
353
Linus Walleij2ced4452012-02-20 21:42:17 +0100354 for (i = 0; i < ab8500->mask_size; i++) {
Rabin Vincent62579262010-05-19 11:39:02 +0200355 u8 old = ab8500->oldmask[i];
356 u8 new = ab8500->mask[i];
357 int reg;
358
359 if (new == old)
360 continue;
361
Linus Walleij0f6208372012-02-20 21:42:10 +0100362 /*
363 * Interrupt register 12 doesn't exist prior to AB8500 version
364 * 2.0
365 */
366 if (ab8500->irq_reg_offset[i] == 11 &&
367 is_ab8500_1p1_or_earlier(ab8500))
Mattias Wallin92d50a42010-12-07 11:20:47 +0100368 continue;
369
Lee Jones3e1a4982013-02-25 14:57:35 +0000370 if (ab8500->irq_reg_offset[i] < 0)
371 continue;
372
Rabin Vincent62579262010-05-19 11:39:02 +0200373 ab8500->oldmask[i] = new;
374
Linus Walleij2ced4452012-02-20 21:42:17 +0100375 reg = AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i];
Mattias Wallin47c16972010-09-10 17:47:56 +0200376 set_register_interruptible(ab8500, AB8500_INTERRUPT, reg, new);
Rabin Vincent62579262010-05-19 11:39:02 +0200377 }
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200378 atomic_dec(&ab8500->transfer_ongoing);
Rabin Vincent62579262010-05-19 11:39:02 +0200379 mutex_unlock(&ab8500->irq_lock);
380}
381
Mark Brown9505a0a2010-12-11 13:16:08 +0000382static void ab8500_irq_mask(struct irq_data *data)
Rabin Vincent62579262010-05-19 11:39:02 +0200383{
Mark Brown9505a0a2010-12-11 13:16:08 +0000384 struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
Lee Jones06e589e2012-06-20 13:56:37 +0100385 int offset = data->hwirq;
Rabin Vincent62579262010-05-19 11:39:02 +0200386 int index = offset / 8;
387 int mask = 1 << (offset % 8);
388
389 ab8500->mask[index] |= mask;
Lee Jones9c677b92012-12-20 11:23:42 +0000390
391 /* The AB8500 GPIOs have two interrupts each (rising & falling). */
392 if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R)
393 ab8500->mask[index + 2] |= mask;
394 if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
395 ab8500->mask[index + 1] |= mask;
396 if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
Linus Walleije2ddf462013-02-06 21:54:34 +0100397 /* Here the falling IRQ is one bit lower */
398 ab8500->mask[index] |= (mask << 1);
Rabin Vincent62579262010-05-19 11:39:02 +0200399}
400
Mark Brown9505a0a2010-12-11 13:16:08 +0000401static void ab8500_irq_unmask(struct irq_data *data)
Rabin Vincent62579262010-05-19 11:39:02 +0200402{
Mark Brown9505a0a2010-12-11 13:16:08 +0000403 struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
Lee Jones9c677b92012-12-20 11:23:42 +0000404 unsigned int type = irqd_get_trigger_type(data);
Lee Jones06e589e2012-06-20 13:56:37 +0100405 int offset = data->hwirq;
Rabin Vincent62579262010-05-19 11:39:02 +0200406 int index = offset / 8;
407 int mask = 1 << (offset % 8);
408
Lee Jones9c677b92012-12-20 11:23:42 +0000409 if (type & IRQ_TYPE_EDGE_RISING)
410 ab8500->mask[index] &= ~mask;
411
412 /* The AB8500 GPIOs have two interrupts each (rising & falling). */
413 if (type & IRQ_TYPE_EDGE_FALLING) {
414 if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R)
415 ab8500->mask[index + 2] &= ~mask;
Lee Jones7ccf40b2014-05-08 14:11:37 +0100416 else if (offset >= AB9540_INT_GPIO50R &&
417 offset <= AB9540_INT_GPIO54R)
Lee Jones9c677b92012-12-20 11:23:42 +0000418 ab8500->mask[index + 1] &= ~mask;
Lee Jones7ccf40b2014-05-08 14:11:37 +0100419 else if (offset == AB8540_INT_GPIO43R ||
420 offset == AB8540_INT_GPIO44R)
Linus Walleije2ddf462013-02-06 21:54:34 +0100421 /* Here the falling IRQ is one bit lower */
422 ab8500->mask[index] &= ~(mask << 1);
Lee Jones9c677b92012-12-20 11:23:42 +0000423 else
424 ab8500->mask[index] &= ~mask;
Linus Walleije2ddf462013-02-06 21:54:34 +0100425 } else {
Lee Jones9c677b92012-12-20 11:23:42 +0000426 /* Satisfies the case where type is not set. */
427 ab8500->mask[index] &= ~mask;
Linus Walleije2ddf462013-02-06 21:54:34 +0100428 }
Rabin Vincent62579262010-05-19 11:39:02 +0200429}
430
Lee Jones40f6e5a2013-01-07 12:23:48 +0000431static int ab8500_irq_set_type(struct irq_data *data, unsigned int type)
432{
433 return 0;
Rabin Vincent62579262010-05-19 11:39:02 +0200434}
435
436static struct irq_chip ab8500_irq_chip = {
437 .name = "ab8500",
Mark Brown9505a0a2010-12-11 13:16:08 +0000438 .irq_bus_lock = ab8500_irq_lock,
439 .irq_bus_sync_unlock = ab8500_irq_sync_unlock,
440 .irq_mask = ab8500_irq_mask,
Virupax Sadashivpetimathe6f93062011-10-11 10:49:17 +0200441 .irq_disable = ab8500_irq_mask,
Mark Brown9505a0a2010-12-11 13:16:08 +0000442 .irq_unmask = ab8500_irq_unmask,
Lee Jones40f6e5a2013-01-07 12:23:48 +0000443 .irq_set_type = ab8500_irq_set_type,
Rabin Vincent62579262010-05-19 11:39:02 +0200444};
445
Lee Jones3e1a4982013-02-25 14:57:35 +0000446static void update_latch_offset(u8 *offset, int i)
447{
448 /* Fix inconsistent ITFromLatch25 bit mapping... */
449 if (unlikely(*offset == 17))
Lee Jones500e69a2015-10-28 09:15:02 +0000450 *offset = 24;
Lee Jones3e1a4982013-02-25 14:57:35 +0000451 /* Fix inconsistent ab8540 bit mapping... */
452 if (unlikely(*offset == 16))
Lee Jones500e69a2015-10-28 09:15:02 +0000453 *offset = 25;
Lee Jones7ccf40b2014-05-08 14:11:37 +0100454 if ((i == 3) && (*offset >= 24))
Lee Jones500e69a2015-10-28 09:15:02 +0000455 *offset += 2;
Lee Jones3e1a4982013-02-25 14:57:35 +0000456}
457
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +0200458static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500,
459 int latch_offset, u8 latch_val)
460{
Fabio Baltieri7a93fb32013-03-21 14:49:44 +0100461 int int_bit, line, i;
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +0200462
Fabio Baltieri7a93fb32013-03-21 14:49:44 +0100463 for (i = 0; i < ab8500->mask_size; i++)
464 if (ab8500->irq_reg_offset[i] == latch_offset)
465 break;
466
467 if (i >= ab8500->mask_size) {
468 dev_err(ab8500->dev, "Register offset 0x%2x not declared\n",
469 latch_offset);
470 return -ENXIO;
471 }
472
473 /* ignore masked out interrupts */
474 latch_val &= ~ab8500->mask[i];
475
476 while (latch_val) {
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +0200477 int_bit = __ffs(latch_val);
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +0200478 line = (i << 3) + int_bit;
479 latch_val &= ~(1 << int_bit);
480
Linus Walleije2ddf462013-02-06 21:54:34 +0100481 /*
482 * This handles the falling edge hwirqs from the GPIO
483 * lines. Route them back to the line registered for the
484 * rising IRQ, as this is merely a flag for the same IRQ
485 * in linux terms.
486 */
487 if (line >= AB8500_INT_GPIO6F && line <= AB8500_INT_GPIO41F)
488 line -= 16;
489 if (line >= AB9540_INT_GPIO50F && line <= AB9540_INT_GPIO54F)
490 line -= 8;
491 if (line == AB8540_INT_GPIO43F || line == AB8540_INT_GPIO44F)
492 line += 1;
493
Linus Walleijed83d302013-12-03 15:11:54 +0100494 handle_nested_irq(irq_create_mapping(ab8500->domain, line));
Fabio Baltieri7a93fb32013-03-21 14:49:44 +0100495 }
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +0200496
497 return 0;
498}
499
500static int ab8500_handle_hierarchical_latch(struct ab8500 *ab8500,
501 int hier_offset, u8 hier_val)
502{
503 int latch_bit, status;
504 u8 latch_offset, latch_val;
505
506 do {
507 latch_bit = __ffs(hier_val);
508 latch_offset = (hier_offset << 3) + latch_bit;
509
Lee Jones3e1a4982013-02-25 14:57:35 +0000510 update_latch_offset(&latch_offset, hier_offset);
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +0200511
512 status = get_register_interruptible(ab8500,
513 AB8500_INTERRUPT,
514 AB8500_IT_LATCH1_REG + latch_offset,
515 &latch_val);
516 if (status < 0 || latch_val == 0)
517 goto discard;
518
519 status = ab8500_handle_hierarchical_line(ab8500,
520 latch_offset, latch_val);
521 if (status < 0)
522 return status;
523discard:
524 hier_val &= ~(1 << latch_bit);
525 } while (hier_val);
526
527 return 0;
528}
529
530static irqreturn_t ab8500_hierarchical_irq(int irq, void *dev)
531{
532 struct ab8500 *ab8500 = dev;
533 u8 i;
534
535 dev_vdbg(ab8500->dev, "interrupt\n");
536
537 /* Hierarchical interrupt version */
Lee Jones3e1a4982013-02-25 14:57:35 +0000538 for (i = 0; i < (ab8500->it_latchhier_num); i++) {
Michel JAOUEN7ccfe9b2012-05-07 15:02:03 +0200539 int status;
540 u8 hier_val;
541
542 status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
543 AB8500_IT_LATCHHIER1_REG + i, &hier_val);
544 if (status < 0 || hier_val == 0)
545 continue;
546
547 status = ab8500_handle_hierarchical_latch(ab8500, i, hier_val);
548 if (status < 0)
549 break;
550 }
551 return IRQ_HANDLED;
552}
553
Lee Jones06e589e2012-06-20 13:56:37 +0100554static int ab8500_irq_map(struct irq_domain *d, unsigned int virq,
555 irq_hw_number_t hwirq)
556{
557 struct ab8500 *ab8500 = d->host_data;
558
559 if (!ab8500)
560 return -EINVAL;
561
562 irq_set_chip_data(virq, ab8500);
563 irq_set_chip_and_handler(virq, &ab8500_irq_chip,
564 handle_simple_irq);
565 irq_set_nested_thread(virq, 1);
Lee Jones06e589e2012-06-20 13:56:37 +0100566 irq_set_noprobe(virq);
Rabin Vincent62579262010-05-19 11:39:02 +0200567
568 return 0;
569}
570
Krzysztof Kozlowski7ce7b262015-04-27 21:54:13 +0900571static const struct irq_domain_ops ab8500_irq_ops = {
Lee Jones7ccf40b2014-05-08 14:11:37 +0100572 .map = ab8500_irq_map,
573 .xlate = irq_domain_xlate_twocell,
Lee Jones06e589e2012-06-20 13:56:37 +0100574};
575
576static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np)
Rabin Vincent62579262010-05-19 11:39:02 +0200577{
Linus Walleij2ced4452012-02-20 21:42:17 +0100578 int num_irqs;
Rabin Vincent62579262010-05-19 11:39:02 +0200579
Lee Jones3e1a4982013-02-25 14:57:35 +0000580 if (is_ab8540(ab8500))
581 num_irqs = AB8540_NR_IRQS;
582 else if (is_ab9540(ab8500))
Linus Walleijd6255522012-02-20 21:42:24 +0100583 num_irqs = AB9540_NR_IRQS;
Bengt Jonssona9823622012-03-08 14:01:57 +0100584 else if (is_ab8505(ab8500))
585 num_irqs = AB8505_NR_IRQS;
Linus Walleijd6255522012-02-20 21:42:24 +0100586 else
587 num_irqs = AB8500_NR_IRQS;
Linus Walleij2ced4452012-02-20 21:42:17 +0100588
Linus Walleijf1d11f32012-10-18 18:18:44 +0200589 /* If ->irq_base is zero this will give a linear mapping */
Grygorii Strashko7602e052014-06-02 19:27:58 +0300590 ab8500->domain = irq_domain_add_simple(ab8500->dev->of_node,
Lee Jones500e69a2015-10-28 09:15:02 +0000591 num_irqs, 0,
592 &ab8500_irq_ops, ab8500);
Lee Jones06e589e2012-06-20 13:56:37 +0100593
594 if (!ab8500->domain) {
595 dev_err(ab8500->dev, "Failed to create irqdomain\n");
Lee Jones500e69a2015-10-28 09:15:02 +0000596 return -ENODEV;
Lee Jones06e589e2012-06-20 13:56:37 +0100597 }
598
599 return 0;
Rabin Vincent62579262010-05-19 11:39:02 +0200600}
601
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200602int ab8500_suspend(struct ab8500 *ab8500)
603{
604 if (atomic_read(&ab8500->transfer_ongoing))
605 return -EINVAL;
Lee Jonesf3556302014-07-02 11:13:42 +0100606
607 return 0;
Jonas Aaberg112a80d2012-04-17 09:30:33 +0200608}
609
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100610static const struct mfd_cell ab8500_bm_devs[] = {
Linus Walleij417c0fc2021-03-12 09:36:02 +0100611 MFD_CELL_OF("ab8500-charger", NULL, NULL, 0, 0,
612 "stericsson,ab8500-charger"),
613 MFD_CELL_OF("ab8500-btemp", NULL, NULL, 0, 0,
614 "stericsson,ab8500-btemp"),
615 MFD_CELL_OF("ab8500-fg", NULL, NULL, 0, 0,
616 "stericsson,ab8500-fg"),
617 MFD_CELL_OF("ab8500-chargalg", NULL, NULL, 0, 0,
618 "stericsson,ab8500-chargalg"),
Rickard Andersson6ef94182012-04-17 09:30:57 +0200619};
620
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100621static const struct mfd_cell ab8500_devs[] = {
Lee Jones4b106fb2013-02-25 14:42:00 +0000622#ifdef CONFIG_DEBUG_FS
Lee Jonesdb783e72020-12-17 08:34:20 +0000623 MFD_CELL_OF("ab8500-debug",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000624 NULL, NULL, 0, 0, "stericsson,ab8500-debug"),
Lee Jones4b106fb2013-02-25 14:42:00 +0000625#endif
Lee Jonesdb783e72020-12-17 08:34:20 +0000626 MFD_CELL_OF("ab8500-sysctrl",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000627 NULL, NULL, 0, 0, "stericsson,ab8500-sysctrl"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000628 MFD_CELL_OF("ab8500-ext-regulator",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000629 NULL, NULL, 0, 0, "stericsson,ab8500-ext-regulator"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000630 MFD_CELL_OF("ab8500-regulator",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000631 NULL, NULL, 0, 0, "stericsson,ab8500-regulator"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000632 MFD_CELL_OF("ab8500-clk",
Linus Walleij702204c2019-12-11 12:46:39 +0100633 NULL, NULL, 0, 0, "stericsson,ab8500-clk"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000634 MFD_CELL_OF("ab8500-gpadc",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000635 NULL, NULL, 0, 0, "stericsson,ab8500-gpadc"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000636 MFD_CELL_OF("ab8500-rtc",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000637 NULL, NULL, 0, 0, "stericsson,ab8500-rtc"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000638 MFD_CELL_OF("ab8500-acc-det",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000639 NULL, NULL, 0, 0, "stericsson,ab8500-acc-det"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000640 MFD_CELL_OF("ab8500-poweron-key",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000641 NULL, NULL, 0, 0, "stericsson,ab8500-poweron-key"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000642 MFD_CELL_OF("ab8500-pwm",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000643 NULL, NULL, 0, 1, "stericsson,ab8500-pwm"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000644 MFD_CELL_OF("ab8500-pwm",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000645 NULL, NULL, 0, 2, "stericsson,ab8500-pwm"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000646 MFD_CELL_OF("ab8500-pwm",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000647 NULL, NULL, 0, 3, "stericsson,ab8500-pwm"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000648 MFD_CELL_OF("ab8500-denc",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000649 NULL, NULL, 0, 0, "stericsson,ab8500-denc"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000650 MFD_CELL_OF("pinctrl-ab8500",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000651 NULL, NULL, 0, 0, "stericsson,ab8500-gpio"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000652 MFD_CELL_OF("abx500-temp",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000653 NULL, NULL, 0, 0, "stericsson,abx500-temp"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000654 MFD_CELL_OF("ab8500-usb",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000655 NULL, NULL, 0, 0, "stericsson,ab8500-usb"),
Lee Jonesdb783e72020-12-17 08:34:20 +0000656 MFD_CELL_OF("ab8500-codec",
Lee Jonesf4d41ad2016-02-10 15:35:36 +0000657 NULL, NULL, 0, 0, "stericsson,ab8500-codec"),
Lee Jones4b106fb2013-02-25 14:42:00 +0000658};
659
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100660static const struct mfd_cell ab9540_devs[] = {
Lee Jones4b106fb2013-02-25 14:42:00 +0000661#ifdef CONFIG_DEBUG_FS
662 {
663 .name = "ab8500-debug",
Lee Jones4b106fb2013-02-25 14:42:00 +0000664 },
665#endif
666 {
667 .name = "ab8500-sysctrl",
668 },
669 {
Lee Jones53f325b2013-06-07 16:07:47 +0100670 .name = "ab8500-ext-regulator",
671 },
672 {
Lee Jones4b106fb2013-02-25 14:42:00 +0000673 .name = "ab8500-regulator",
Virupax Sadashivpetimath44f72e52012-04-17 09:30:14 +0200674 },
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000675 {
Ulf Hansson9ee17672012-11-20 14:57:25 +0100676 .name = "abx500-clk",
677 .of_compatible = "stericsson,abx500-clk",
678 },
679 {
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000680 .name = "ab8500-gpadc",
681 .of_compatible = "stericsson,ab8500-gpadc",
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000682 },
Lee Jones4b106fb2013-02-25 14:42:00 +0000683 {
684 .name = "ab8500-rtc",
Lee Jones4b106fb2013-02-25 14:42:00 +0000685 },
686 {
687 .name = "ab8500-acc-det",
Lee Jones4b106fb2013-02-25 14:42:00 +0000688 },
689 {
690 .name = "ab8500-poweron-key",
Lee Jones4b106fb2013-02-25 14:42:00 +0000691 },
692 {
693 .name = "ab8500-pwm",
694 .id = 1,
695 },
696 {
Lee Jones4b106fb2013-02-25 14:42:00 +0000697 .name = "abx500-temp",
Lee Jones4b106fb2013-02-25 14:42:00 +0000698 },
Linus Walleijd6255522012-02-20 21:42:24 +0100699 {
Lee Jonese64d9052013-01-16 15:09:36 +0000700 .name = "pinctrl-ab9540",
701 .of_compatible = "stericsson,ab9540-gpio",
Linus Walleijd6255522012-02-20 21:42:24 +0100702 },
703 {
704 .name = "ab9540-usb",
Linus Walleijd6255522012-02-20 21:42:24 +0100705 },
Virupax Sadashivpetimath44f72e52012-04-17 09:30:14 +0200706 {
707 .name = "ab9540-codec",
708 },
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000709 {
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000710 .name = "ab-iddet",
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000711 },
Virupax Sadashivpetimath44f72e52012-04-17 09:30:14 +0200712};
713
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000714/* Device list for ab8505 */
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100715static const struct mfd_cell ab8505_devs[] = {
Lee Jones4b106fb2013-02-25 14:42:00 +0000716#ifdef CONFIG_DEBUG_FS
717 {
718 .name = "ab8500-debug",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100719 .of_compatible = "stericsson,ab8500-debug",
Lee Jones4b106fb2013-02-25 14:42:00 +0000720 },
721#endif
722 {
723 .name = "ab8500-sysctrl",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100724 .of_compatible = "stericsson,ab8500-sysctrl",
Lee Jones4b106fb2013-02-25 14:42:00 +0000725 },
726 {
727 .name = "ab8500-regulator",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100728 .of_compatible = "stericsson,ab8505-regulator",
Lee Jones4b106fb2013-02-25 14:42:00 +0000729 },
730 {
Ulf Hansson9ee17672012-11-20 14:57:25 +0100731 .name = "abx500-clk",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100732 .of_compatible = "stericsson,ab8500-clk",
Ulf Hansson9ee17672012-11-20 14:57:25 +0100733 },
734 {
Lee Jones4b106fb2013-02-25 14:42:00 +0000735 .name = "ab8500-gpadc",
Lee Jones955de2e2013-05-08 14:29:09 +0100736 .of_compatible = "stericsson,ab8500-gpadc",
Lee Jones4b106fb2013-02-25 14:42:00 +0000737 },
738 {
739 .name = "ab8500-rtc",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100740 .of_compatible = "stericsson,ab8500-rtc",
Lee Jones4b106fb2013-02-25 14:42:00 +0000741 },
742 {
743 .name = "ab8500-acc-det",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100744 .of_compatible = "stericsson,ab8500-acc-det",
Lee Jones4b106fb2013-02-25 14:42:00 +0000745 },
746 {
747 .name = "ab8500-poweron-key",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100748 .of_compatible = "stericsson,ab8500-poweron-key",
Lee Jones4b106fb2013-02-25 14:42:00 +0000749 },
750 {
751 .name = "ab8500-pwm",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100752 .of_compatible = "stericsson,ab8500-pwm",
Lee Jones4b106fb2013-02-25 14:42:00 +0000753 .id = 1,
754 },
755 {
Lee Joneseb696c32013-05-07 11:29:55 +0100756 .name = "pinctrl-ab8505",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100757 .of_compatible = "stericsson,ab8505-gpio",
Lee Jones4b106fb2013-02-25 14:42:00 +0000758 },
759 {
760 .name = "ab8500-usb",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100761 .of_compatible = "stericsson,ab8500-usb",
Lee Jones4b106fb2013-02-25 14:42:00 +0000762 },
763 {
764 .name = "ab8500-codec",
Stephan Gerhold1c0769d2019-11-17 23:10:53 +0100765 .of_compatible = "stericsson,ab8500-codec",
Lee Jones4b106fb2013-02-25 14:42:00 +0000766 },
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000767 {
768 .name = "ab-iddet",
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000769 },
770};
771
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100772static const struct mfd_cell ab8540_devs[] = {
Lee Jones4b106fb2013-02-25 14:42:00 +0000773#ifdef CONFIG_DEBUG_FS
774 {
775 .name = "ab8500-debug",
Lee Jones4b106fb2013-02-25 14:42:00 +0000776 },
777#endif
778 {
779 .name = "ab8500-sysctrl",
780 },
781 {
Lee Jones53f325b2013-06-07 16:07:47 +0100782 .name = "ab8500-ext-regulator",
783 },
784 {
Lee Jones4b106fb2013-02-25 14:42:00 +0000785 .name = "ab8500-regulator",
786 },
787 {
Ulf Hansson9ee17672012-11-20 14:57:25 +0100788 .name = "abx500-clk",
789 .of_compatible = "stericsson,abx500-clk",
790 },
791 {
Lee Jones4b106fb2013-02-25 14:42:00 +0000792 .name = "ab8500-gpadc",
Lee Jones955de2e2013-05-08 14:29:09 +0100793 .of_compatible = "stericsson,ab8500-gpadc",
Lee Jones4b106fb2013-02-25 14:42:00 +0000794 },
795 {
Lee Jones4b106fb2013-02-25 14:42:00 +0000796 .name = "ab8500-acc-det",
Lee Jones4b106fb2013-02-25 14:42:00 +0000797 },
798 {
799 .name = "ab8500-poweron-key",
Lee Jones4b106fb2013-02-25 14:42:00 +0000800 },
801 {
802 .name = "ab8500-pwm",
803 .id = 1,
804 },
805 {
Lee Jones4b106fb2013-02-25 14:42:00 +0000806 .name = "abx500-temp",
Lee Jones4b106fb2013-02-25 14:42:00 +0000807 },
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000808 {
Lee Joneseb696c32013-05-07 11:29:55 +0100809 .name = "pinctrl-ab8540",
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000810 },
811 {
812 .name = "ab8540-usb",
Lee Jonesc0eda9a2013-02-12 15:04:09 +0000813 },
814 {
815 .name = "ab8540-codec",
816 },
817 {
Virupax Sadashivpetimath44f72e52012-04-17 09:30:14 +0200818 .name = "ab-iddet",
Virupax Sadashivpetimath44f72e52012-04-17 09:30:14 +0200819 },
Linus Walleijd6255522012-02-20 21:42:24 +0100820};
821
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100822static const struct mfd_cell ab8540_cut1_devs[] = {
Alexandre Torgue9c717cf2013-05-24 11:59:47 +0200823 {
824 .name = "ab8500-rtc",
825 .of_compatible = "stericsson,ab8500-rtc",
Alexandre Torgue9c717cf2013-05-24 11:59:47 +0200826 },
827};
828
Geert Uytterhoeven5ac98552013-11-18 14:33:06 +0100829static const struct mfd_cell ab8540_cut2_devs[] = {
Alexandre Torgue9c717cf2013-05-24 11:59:47 +0200830 {
831 .name = "ab8540-rtc",
832 .of_compatible = "stericsson,ab8540-rtc",
Alexandre Torgue9c717cf2013-05-24 11:59:47 +0200833 },
834};
835
Mattias Wallincca69b62010-12-02 15:09:36 +0100836static ssize_t show_chip_id(struct device *dev,
837 struct device_attribute *attr, char *buf)
838{
839 struct ab8500 *ab8500;
840
841 ab8500 = dev_get_drvdata(dev);
Lee Jonese436ddf2013-02-26 10:09:41 +0000842
Mattias Wallincca69b62010-12-02 15:09:36 +0100843 return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL);
844}
845
Mattias Walline5c238c2011-03-02 11:52:36 +0100846/*
847 * ab8500 has switched off due to (SWITCH_OFF_STATUS):
848 * 0x01 Swoff bit programming
849 * 0x02 Thermal protection activation
850 * 0x04 Vbat lower then BattOk falling threshold
851 * 0x08 Watchdog expired
852 * 0x10 Non presence of 32kHz clock
853 * 0x20 Battery level lower than power on reset threshold
854 * 0x40 Power on key 1 pressed longer than 10 seconds
855 * 0x80 DB8500 thermal shutdown
856 */
857static ssize_t show_switch_off_status(struct device *dev,
858 struct device_attribute *attr, char *buf)
859{
860 int ret;
861 u8 value;
862 struct ab8500 *ab8500;
863
864 ab8500 = dev_get_drvdata(dev);
865 ret = get_register_interruptible(ab8500, AB8500_RTC,
866 AB8500_SWITCH_OFF_STATUS, &value);
867 if (ret < 0)
868 return ret;
869 return sprintf(buf, "%#x\n", value);
870}
871
Rajkumar Kasirajanf04a9d8a2012-05-30 16:32:37 +0530872/* use mask and set to override the register turn_on_stat value */
873void ab8500_override_turn_on_stat(u8 mask, u8 set)
874{
875 spin_lock(&on_stat_lock);
876 turn_on_stat_mask = mask;
877 turn_on_stat_set = set;
878 spin_unlock(&on_stat_lock);
879}
880
Andrew Lynnb4a31032011-10-11 10:49:47 +0200881/*
882 * ab8500 has turned on due to (TURN_ON_STATUS):
883 * 0x01 PORnVbat
884 * 0x02 PonKey1dbF
885 * 0x04 PonKey2dbF
886 * 0x08 RTCAlarm
887 * 0x10 MainChDet
888 * 0x20 VbusDet
889 * 0x40 UsbIDDetect
890 * 0x80 Reserved
891 */
892static ssize_t show_turn_on_status(struct device *dev,
893 struct device_attribute *attr, char *buf)
894{
895 int ret;
896 u8 value;
897 struct ab8500 *ab8500;
898
899 ab8500 = dev_get_drvdata(dev);
900 ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK,
901 AB8500_TURN_ON_STATUS, &value);
902 if (ret < 0)
903 return ret;
Rajkumar Kasirajanf04a9d8a2012-05-30 16:32:37 +0530904
905 /*
906 * In L9540, turn_on_status register is not updated correctly if
907 * the device is rebooted with AC/USB charger connected. Due to
908 * this, the device boots android instead of entering into charge
909 * only mode. Read the AC/USB status register to detect the charger
910 * presence and update the turn on status manually.
911 */
912 if (is_ab9540(ab8500)) {
913 spin_lock(&on_stat_lock);
914 value = (value & turn_on_stat_mask) | turn_on_stat_set;
915 spin_unlock(&on_stat_lock);
916 }
917
Andrew Lynnb4a31032011-10-11 10:49:47 +0200918 return sprintf(buf, "%#x\n", value);
919}
920
Lee Jones93ff7222012-05-31 16:16:36 +0200921static ssize_t show_turn_on_status_2(struct device *dev,
922 struct device_attribute *attr, char *buf)
923{
924 int ret;
925 u8 value;
926 struct ab8500 *ab8500;
927
928 ab8500 = dev_get_drvdata(dev);
929 ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK,
930 AB8505_TURN_ON_STATUS_2, &value);
931 if (ret < 0)
932 return ret;
933 return sprintf(buf, "%#x\n", (value & 0x1));
934}
935
Linus Walleijd6255522012-02-20 21:42:24 +0100936static ssize_t show_ab9540_dbbrstn(struct device *dev,
937 struct device_attribute *attr, char *buf)
938{
939 struct ab8500 *ab8500;
940 int ret;
941 u8 value;
942
943 ab8500 = dev_get_drvdata(dev);
944
945 ret = get_register_interruptible(ab8500, AB8500_REGU_CTRL2,
946 AB9540_MODEM_CTRL2_REG, &value);
947 if (ret < 0)
948 return ret;
949
950 return sprintf(buf, "%d\n",
951 (value & AB9540_MODEM_CTRL2_SWDBBRSTN_BIT) ? 1 : 0);
952}
953
954static ssize_t store_ab9540_dbbrstn(struct device *dev,
955 struct device_attribute *attr, const char *buf, size_t count)
956{
957 struct ab8500 *ab8500;
958 int ret = count;
959 int err;
960 u8 bitvalues;
961
962 ab8500 = dev_get_drvdata(dev);
963
964 if (count > 0) {
965 switch (buf[0]) {
966 case '0':
967 bitvalues = 0;
968 break;
969 case '1':
970 bitvalues = AB9540_MODEM_CTRL2_SWDBBRSTN_BIT;
971 break;
972 default:
973 goto exit;
974 }
975
976 err = mask_and_set_register_interruptible(ab8500,
977 AB8500_REGU_CTRL2, AB9540_MODEM_CTRL2_REG,
978 AB9540_MODEM_CTRL2_SWDBBRSTN_BIT, bitvalues);
979 if (err)
980 dev_info(ab8500->dev,
981 "Failed to set DBBRSTN %c, err %#x\n",
982 buf[0], err);
983 }
984
985exit:
986 return ret;
987}
988
Mattias Wallincca69b62010-12-02 15:09:36 +0100989static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL);
Mattias Walline5c238c2011-03-02 11:52:36 +0100990static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL);
Andrew Lynnb4a31032011-10-11 10:49:47 +0200991static DEVICE_ATTR(turn_on_status, S_IRUGO, show_turn_on_status, NULL);
Lee Jones93ff7222012-05-31 16:16:36 +0200992static DEVICE_ATTR(turn_on_status_2, S_IRUGO, show_turn_on_status_2, NULL);
Linus Walleijd6255522012-02-20 21:42:24 +0100993static DEVICE_ATTR(dbbrstn, S_IRUGO | S_IWUSR,
994 show_ab9540_dbbrstn, store_ab9540_dbbrstn);
Mattias Wallincca69b62010-12-02 15:09:36 +0100995
996static struct attribute *ab8500_sysfs_entries[] = {
997 &dev_attr_chip_id.attr,
Mattias Walline5c238c2011-03-02 11:52:36 +0100998 &dev_attr_switch_off_status.attr,
Andrew Lynnb4a31032011-10-11 10:49:47 +0200999 &dev_attr_turn_on_status.attr,
Mattias Wallincca69b62010-12-02 15:09:36 +01001000 NULL,
1001};
1002
Lee Jones93ff7222012-05-31 16:16:36 +02001003static struct attribute *ab8505_sysfs_entries[] = {
1004 &dev_attr_turn_on_status_2.attr,
1005 NULL,
1006};
1007
Linus Walleijd6255522012-02-20 21:42:24 +01001008static struct attribute *ab9540_sysfs_entries[] = {
1009 &dev_attr_chip_id.attr,
1010 &dev_attr_switch_off_status.attr,
1011 &dev_attr_turn_on_status.attr,
1012 &dev_attr_dbbrstn.attr,
1013 NULL,
1014};
1015
Arvind Yadav52557dc2017-07-10 11:07:22 +05301016static const struct attribute_group ab8500_attr_group = {
Mattias Wallincca69b62010-12-02 15:09:36 +01001017 .attrs = ab8500_sysfs_entries,
1018};
1019
Arvind Yadav52557dc2017-07-10 11:07:22 +05301020static const struct attribute_group ab8505_attr_group = {
Lee Jones93ff7222012-05-31 16:16:36 +02001021 .attrs = ab8505_sysfs_entries,
1022};
1023
Arvind Yadav52557dc2017-07-10 11:07:22 +05301024static const struct attribute_group ab9540_attr_group = {
Linus Walleijd6255522012-02-20 21:42:24 +01001025 .attrs = ab9540_sysfs_entries,
1026};
1027
Bill Pembertonf791be42012-11-19 13:23:04 -05001028static int ab8500_probe(struct platform_device *pdev)
Rabin Vincent62579262010-05-19 11:39:02 +02001029{
Lee Jones500e69a2015-10-28 09:15:02 +00001030 static const char * const switch_off_status[] = {
Jonas Aabergb04c530c2012-06-29 17:46:12 +02001031 "Swoff bit programming",
1032 "Thermal protection activation",
1033 "Vbat lower then BattOk falling threshold",
1034 "Watchdog expired",
1035 "Non presence of 32kHz clock",
1036 "Battery level lower than power on reset threshold",
1037 "Power on key 1 pressed longer than 10 seconds",
1038 "DB8500 thermal shutdown"};
Lee Jones500e69a2015-10-28 09:15:02 +00001039 static const char * const turn_on_status[] = {
Mattias Wallinabee26c2012-09-28 09:34:24 +02001040 "Battery rising (Vbat)",
1041 "Power On Key 1 dbF",
1042 "Power On Key 2 dbF",
1043 "RTC Alarm",
1044 "Main Charger Detect",
1045 "Vbus Detect (USB)",
1046 "USB ID Detect",
1047 "UART Factory Mode Detect"};
Lee Jonesd28f1db2012-05-19 17:21:37 +02001048 const struct platform_device_id *platid = platform_get_device_id(pdev);
Lee Jones6bc4a562012-05-17 14:45:13 +01001049 enum ab8500_version version = AB8500_VERSION_UNDEFINED;
1050 struct device_node *np = pdev->dev.of_node;
Lee Jonesd28f1db2012-05-19 17:21:37 +02001051 struct ab8500 *ab8500;
1052 struct resource *resource;
Rabin Vincent62579262010-05-19 11:39:02 +02001053 int ret;
1054 int i;
Mattias Wallin47c16972010-09-10 17:47:56 +02001055 u8 value;
Rabin Vincent62579262010-05-19 11:39:02 +02001056
Lee Jones7ccf40b2014-05-08 14:11:37 +01001057 ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL);
Lee Jonesd28f1db2012-05-19 17:21:37 +02001058 if (!ab8500)
1059 return -ENOMEM;
1060
Lee Jonesd28f1db2012-05-19 17:21:37 +02001061 ab8500->dev = &pdev->dev;
1062
1063 resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
Linus Walleijf864c462014-02-04 00:35:56 +01001064 if (!resource) {
1065 dev_err(&pdev->dev, "no IRQ resource\n");
Lee Jones8c4203c2012-11-05 16:10:35 +01001066 return -ENODEV;
Linus Walleijf864c462014-02-04 00:35:56 +01001067 }
Lee Jonesd28f1db2012-05-19 17:21:37 +02001068
1069 ab8500->irq = resource->start;
1070
Lee Jones822672a2012-06-20 13:56:38 +01001071 ab8500->read = ab8500_prcmu_read;
1072 ab8500->write = ab8500_prcmu_write;
1073 ab8500->write_masked = ab8500_prcmu_write_masked;
Lee Jonesd28f1db2012-05-19 17:21:37 +02001074
Rabin Vincent62579262010-05-19 11:39:02 +02001075 mutex_init(&ab8500->lock);
1076 mutex_init(&ab8500->irq_lock);
Jonas Aaberg112a80d2012-04-17 09:30:33 +02001077 atomic_set(&ab8500->transfer_ongoing, 0);
Rabin Vincent62579262010-05-19 11:39:02 +02001078
Lee Jonesd28f1db2012-05-19 17:21:37 +02001079 platform_set_drvdata(pdev, ab8500);
1080
Lee Jones6bc4a562012-05-17 14:45:13 +01001081 if (platid)
1082 version = platid->driver_data;
Lee Jones6bc4a562012-05-17 14:45:13 +01001083
Linus Walleij0f6208372012-02-20 21:42:10 +01001084 if (version != AB8500_VERSION_UNDEFINED)
1085 ab8500->version = version;
1086 else {
1087 ret = get_register_interruptible(ab8500, AB8500_MISC,
1088 AB8500_IC_NAME_REG, &value);
Linus Walleijf864c462014-02-04 00:35:56 +01001089 if (ret < 0) {
1090 dev_err(&pdev->dev, "could not probe HW\n");
Lee Jones8c4203c2012-11-05 16:10:35 +01001091 return ret;
Linus Walleijf864c462014-02-04 00:35:56 +01001092 }
Linus Walleij0f6208372012-02-20 21:42:10 +01001093
1094 ab8500->version = value;
1095 }
1096
Mattias Wallin47c16972010-09-10 17:47:56 +02001097 ret = get_register_interruptible(ab8500, AB8500_MISC,
1098 AB8500_REV_REG, &value);
Rabin Vincent62579262010-05-19 11:39:02 +02001099 if (ret < 0)
Lee Jones8c4203c2012-11-05 16:10:35 +01001100 return ret;
Rabin Vincent62579262010-05-19 11:39:02 +02001101
Mattias Wallin47c16972010-09-10 17:47:56 +02001102 ab8500->chip_id = value;
Rabin Vincent62579262010-05-19 11:39:02 +02001103
Linus Walleij0f6208372012-02-20 21:42:10 +01001104 dev_info(ab8500->dev, "detected chip, %s rev. %1x.%1x\n",
1105 ab8500_version_str[ab8500->version],
1106 ab8500->chip_id >> 4,
1107 ab8500->chip_id & 0x0F);
1108
Lee Jones3e1a4982013-02-25 14:57:35 +00001109 /* Configure AB8540 */
1110 if (is_ab8540(ab8500)) {
1111 ab8500->mask_size = AB8540_NUM_IRQ_REGS;
1112 ab8500->irq_reg_offset = ab8540_irq_regoffset;
1113 ab8500->it_latchhier_num = AB8540_IT_LATCHHIER_NUM;
Lee Jones7ccf40b2014-05-08 14:11:37 +01001114 } /* Configure AB8500 or AB9540 IRQ */
Lee Jones3e1a4982013-02-25 14:57:35 +00001115 else if (is_ab9540(ab8500) || is_ab8505(ab8500)) {
Linus Walleijd6255522012-02-20 21:42:24 +01001116 ab8500->mask_size = AB9540_NUM_IRQ_REGS;
1117 ab8500->irq_reg_offset = ab9540_irq_regoffset;
Lee Jones3e1a4982013-02-25 14:57:35 +00001118 ab8500->it_latchhier_num = AB8500_IT_LATCHHIER_NUM;
Linus Walleijd6255522012-02-20 21:42:24 +01001119 } else {
1120 ab8500->mask_size = AB8500_NUM_IRQ_REGS;
1121 ab8500->irq_reg_offset = ab8500_irq_regoffset;
Lee Jones3e1a4982013-02-25 14:57:35 +00001122 ab8500->it_latchhier_num = AB8500_IT_LATCHHIER_NUM;
Linus Walleijd6255522012-02-20 21:42:24 +01001123 }
Lee Jones7ccf40b2014-05-08 14:11:37 +01001124 ab8500->mask = devm_kzalloc(&pdev->dev, ab8500->mask_size,
1125 GFP_KERNEL);
Linus Walleij2ced4452012-02-20 21:42:17 +01001126 if (!ab8500->mask)
1127 return -ENOMEM;
Lee Jones7ccf40b2014-05-08 14:11:37 +01001128 ab8500->oldmask = devm_kzalloc(&pdev->dev, ab8500->mask_size,
1129 GFP_KERNEL);
Lee Jones8c4203c2012-11-05 16:10:35 +01001130 if (!ab8500->oldmask)
1131 return -ENOMEM;
1132
Mattias Walline5c238c2011-03-02 11:52:36 +01001133 /*
1134 * ab8500 has switched off due to (SWITCH_OFF_STATUS):
1135 * 0x01 Swoff bit programming
1136 * 0x02 Thermal protection activation
1137 * 0x04 Vbat lower then BattOk falling threshold
1138 * 0x08 Watchdog expired
1139 * 0x10 Non presence of 32kHz clock
1140 * 0x20 Battery level lower than power on reset threshold
1141 * 0x40 Power on key 1 pressed longer than 10 seconds
1142 * 0x80 DB8500 thermal shutdown
1143 */
1144
1145 ret = get_register_interruptible(ab8500, AB8500_RTC,
1146 AB8500_SWITCH_OFF_STATUS, &value);
1147 if (ret < 0)
1148 return ret;
Jonas Aabergb04c530c2012-06-29 17:46:12 +02001149 dev_info(ab8500->dev, "switch off cause(s) (%#x): ", value);
1150
1151 if (value) {
1152 for (i = 0; i < ARRAY_SIZE(switch_off_status); i++) {
1153 if (value & 1)
Lee Jones7ccf40b2014-05-08 14:11:37 +01001154 pr_cont(" \"%s\"", switch_off_status[i]);
Jonas Aabergb04c530c2012-06-29 17:46:12 +02001155 value = value >> 1;
1156
1157 }
Lee Jones7ccf40b2014-05-08 14:11:37 +01001158 pr_cont("\n");
Jonas Aabergb04c530c2012-06-29 17:46:12 +02001159 } else {
Lee Jones7ccf40b2014-05-08 14:11:37 +01001160 pr_cont(" None\n");
Jonas Aabergb04c530c2012-06-29 17:46:12 +02001161 }
Mattias Wallinabee26c2012-09-28 09:34:24 +02001162 ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK,
1163 AB8500_TURN_ON_STATUS, &value);
1164 if (ret < 0)
1165 return ret;
1166 dev_info(ab8500->dev, "turn on reason(s) (%#x): ", value);
1167
1168 if (value) {
1169 for (i = 0; i < ARRAY_SIZE(turn_on_status); i++) {
1170 if (value & 1)
Lee Jones7ccf40b2014-05-08 14:11:37 +01001171 pr_cont("\"%s\" ", turn_on_status[i]);
Mattias Wallinabee26c2012-09-28 09:34:24 +02001172 value = value >> 1;
1173 }
Lee Jones7ccf40b2014-05-08 14:11:37 +01001174 pr_cont("\n");
Mattias Wallinabee26c2012-09-28 09:34:24 +02001175 } else {
Lee Jones7ccf40b2014-05-08 14:11:37 +01001176 pr_cont("None\n");
Mattias Wallinabee26c2012-09-28 09:34:24 +02001177 }
Mattias Walline5c238c2011-03-02 11:52:36 +01001178
Rajkumar Kasirajanf04a9d8a2012-05-30 16:32:37 +05301179 if (is_ab9540(ab8500)) {
1180 ret = get_register_interruptible(ab8500, AB8500_CHARGER,
1181 AB8500_CH_USBCH_STAT1_REG, &value);
1182 if (ret < 0)
1183 return ret;
1184 if ((value & VBUS_DET_DBNC1) && (value & VBUS_DET_DBNC100))
1185 ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON,
1186 AB8500_VBUS_DET);
1187 }
Rabin Vincent62579262010-05-19 11:39:02 +02001188
1189 /* Clear and mask all interrupts */
Linus Walleij2ced4452012-02-20 21:42:17 +01001190 for (i = 0; i < ab8500->mask_size; i++) {
Linus Walleij0f6208372012-02-20 21:42:10 +01001191 /*
1192 * Interrupt register 12 doesn't exist prior to AB8500 version
1193 * 2.0
1194 */
1195 if (ab8500->irq_reg_offset[i] == 11 &&
1196 is_ab8500_1p1_or_earlier(ab8500))
Mattias Wallin92d50a42010-12-07 11:20:47 +01001197 continue;
Rabin Vincent62579262010-05-19 11:39:02 +02001198
Lee Jones3e1a4982013-02-25 14:57:35 +00001199 if (ab8500->irq_reg_offset[i] < 0)
1200 continue;
1201
Mattias Wallin47c16972010-09-10 17:47:56 +02001202 get_register_interruptible(ab8500, AB8500_INTERRUPT,
Linus Walleij2ced4452012-02-20 21:42:17 +01001203 AB8500_IT_LATCH1_REG + ab8500->irq_reg_offset[i],
Mattias Wallin92d50a42010-12-07 11:20:47 +01001204 &value);
Mattias Wallin47c16972010-09-10 17:47:56 +02001205 set_register_interruptible(ab8500, AB8500_INTERRUPT,
Linus Walleij2ced4452012-02-20 21:42:17 +01001206 AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i], 0xff);
Rabin Vincent62579262010-05-19 11:39:02 +02001207 }
1208
Mattias Wallin47c16972010-09-10 17:47:56 +02001209 ret = abx500_register_ops(ab8500->dev, &ab8500_ops);
1210 if (ret)
Lee Jones8c4203c2012-11-05 16:10:35 +01001211 return ret;
Mattias Wallin47c16972010-09-10 17:47:56 +02001212
Linus Walleij2ced4452012-02-20 21:42:17 +01001213 for (i = 0; i < ab8500->mask_size; i++)
Rabin Vincent62579262010-05-19 11:39:02 +02001214 ab8500->mask[i] = ab8500->oldmask[i] = 0xff;
1215
Lee Jones06e589e2012-06-20 13:56:37 +01001216 ret = ab8500_irq_init(ab8500, np);
1217 if (ret)
Lee Jones8c4203c2012-11-05 16:10:35 +01001218 return ret;
Rabin Vincent62579262010-05-19 11:39:02 +02001219
Dariusz Szymczakf348fef2012-11-26 13:31:26 +01001220 ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL,
1221 ab8500_hierarchical_irq,
1222 IRQF_ONESHOT | IRQF_NO_SUSPEND,
1223 "ab8500", ab8500);
1224 if (ret)
1225 return ret;
Rabin Vincent62579262010-05-19 11:39:02 +02001226
Lee Jonesbad76992012-07-02 17:10:56 +02001227 if (is_ab9540(ab8500))
1228 ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
1229 ARRAY_SIZE(ab9540_devs), NULL,
Linus Walleijf864c462014-02-04 00:35:56 +01001230 0, ab8500->domain);
Alexandre Torgue9c717cf2013-05-24 11:59:47 +02001231 else if (is_ab8540(ab8500)) {
Lee Jonesc0eda9a2013-02-12 15:04:09 +00001232 ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs,
1233 ARRAY_SIZE(ab8540_devs), NULL,
Linus Walleijf864c462014-02-04 00:35:56 +01001234 0, ab8500->domain);
Alexandre Torgue9c717cf2013-05-24 11:59:47 +02001235 if (ret)
1236 return ret;
1237
1238 if (is_ab8540_1p2_or_earlier(ab8500))
1239 ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut1_devs,
1240 ARRAY_SIZE(ab8540_cut1_devs), NULL,
Linus Walleijf864c462014-02-04 00:35:56 +01001241 0, ab8500->domain);
Alexandre Torgue9c717cf2013-05-24 11:59:47 +02001242 else /* ab8540 >= cut2 */
1243 ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut2_devs,
1244 ARRAY_SIZE(ab8540_cut2_devs), NULL,
Linus Walleijf864c462014-02-04 00:35:56 +01001245 0, ab8500->domain);
Alexandre Torgue9c717cf2013-05-24 11:59:47 +02001246 } else if (is_ab8505(ab8500))
Lee Jonesc0eda9a2013-02-12 15:04:09 +00001247 ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs,
1248 ARRAY_SIZE(ab8505_devs), NULL,
Linus Walleijf864c462014-02-04 00:35:56 +01001249 0, ab8500->domain);
Lee Jonesbad76992012-07-02 17:10:56 +02001250 else
1251 ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
1252 ARRAY_SIZE(ab8500_devs), NULL,
Linus Walleijf864c462014-02-04 00:35:56 +01001253 0, ab8500->domain);
Lee Jonesbad76992012-07-02 17:10:56 +02001254 if (ret)
Lee Jones8c4203c2012-11-05 16:10:35 +01001255 return ret;
Linus Walleijd6255522012-02-20 21:42:24 +01001256
Rickard Andersson6ef94182012-04-17 09:30:57 +02001257 if (!no_bm) {
1258 /* Add battery management devices */
1259 ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
1260 ARRAY_SIZE(ab8500_bm_devs), NULL,
Linus Walleijf864c462014-02-04 00:35:56 +01001261 0, ab8500->domain);
Rickard Andersson6ef94182012-04-17 09:30:57 +02001262 if (ret)
1263 dev_err(ab8500->dev, "error adding bm devices\n");
1264 }
1265
Lee Jonese436ddf2013-02-26 10:09:41 +00001266 if (((is_ab8505(ab8500) || is_ab9540(ab8500)) &&
1267 ab8500->chip_id >= AB8500_CUT2P0) || is_ab8540(ab8500))
Linus Walleijd6255522012-02-20 21:42:24 +01001268 ret = sysfs_create_group(&ab8500->dev->kobj,
1269 &ab9540_attr_group);
1270 else
1271 ret = sysfs_create_group(&ab8500->dev->kobj,
1272 &ab8500_attr_group);
Lee Jones93ff7222012-05-31 16:16:36 +02001273
1274 if ((is_ab8505(ab8500) || is_ab9540(ab8500)) &&
1275 ab8500->chip_id >= AB8500_CUT2P0)
1276 ret = sysfs_create_group(&ab8500->dev->kobj,
1277 &ab8505_attr_group);
1278
Mattias Wallincca69b62010-12-02 15:09:36 +01001279 if (ret)
1280 dev_err(ab8500->dev, "error creating sysfs entries\n");
Lee Jones06e589e2012-06-20 13:56:37 +01001281
1282 return ret;
Rabin Vincent62579262010-05-19 11:39:02 +02001283}
1284
Lee Jonesd28f1db2012-05-19 17:21:37 +02001285static const struct platform_device_id ab8500_id[] = {
1286 { "ab8500-core", AB8500_VERSION_AB8500 },
Stephan Gerhold1c0769d2019-11-17 23:10:53 +01001287 { "ab8505-core", AB8500_VERSION_AB8505 },
Lee Jonesd28f1db2012-05-19 17:21:37 +02001288 { "ab9540-i2c", AB8500_VERSION_AB9540 },
1289 { "ab8540-i2c", AB8500_VERSION_AB8540 },
1290 { }
1291};
1292
1293static struct platform_driver ab8500_core_driver = {
1294 .driver = {
1295 .name = "ab8500-core",
Paul Gortmaker31cbae22016-10-29 21:24:36 -04001296 .suppress_bind_attrs = true,
Lee Jonesd28f1db2012-05-19 17:21:37 +02001297 },
1298 .probe = ab8500_probe,
Lee Jonesd28f1db2012-05-19 17:21:37 +02001299 .id_table = ab8500_id,
1300};
1301
1302static int __init ab8500_core_init(void)
1303{
1304 return platform_driver_register(&ab8500_core_driver);
1305}
Lee Jonesba7cbc32012-06-11 16:25:00 +01001306core_initcall(ab8500_core_init);