Linux Audio

Check our new training course

Loading...
v5.9
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Device access for Dialog DA9055 PMICs.
  4 *
  5 * Copyright(c) 2012 Dialog Semiconductor Ltd.
  6 *
  7 * Author: David Dajun Chen <dchen@diasemi.com>
 
 
 
 
 
  8 */
  9
 10#include <linux/module.h>
 11#include <linux/device.h>
 12#include <linux/input.h>
 13#include <linux/irq.h>
 14#include <linux/mutex.h>
 15
 16#include <linux/mfd/core.h>
 17#include <linux/mfd/da9055/core.h>
 18#include <linux/mfd/da9055/pdata.h>
 19#include <linux/mfd/da9055/reg.h>
 20
 21#define DA9055_IRQ_NONKEY_MASK		0x01
 22#define DA9055_IRQ_ALM_MASK		0x02
 23#define DA9055_IRQ_TICK_MASK		0x04
 24#define DA9055_IRQ_ADC_MASK		0x08
 25#define DA9055_IRQ_BUCK_ILIM_MASK	0x08
 26
 27static bool da9055_register_readable(struct device *dev, unsigned int reg)
 28{
 29	switch (reg) {
 30	case DA9055_REG_STATUS_A:
 31	case DA9055_REG_STATUS_B:
 32	case DA9055_REG_EVENT_A:
 33	case DA9055_REG_EVENT_B:
 34	case DA9055_REG_EVENT_C:
 35	case DA9055_REG_IRQ_MASK_A:
 36	case DA9055_REG_IRQ_MASK_B:
 37	case DA9055_REG_IRQ_MASK_C:
 38
 39	case DA9055_REG_CONTROL_A:
 40	case DA9055_REG_CONTROL_B:
 41	case DA9055_REG_CONTROL_C:
 42	case DA9055_REG_CONTROL_D:
 43	case DA9055_REG_CONTROL_E:
 44
 45	case DA9055_REG_ADC_MAN:
 46	case DA9055_REG_ADC_CONT:
 47	case DA9055_REG_VSYS_MON:
 48	case DA9055_REG_ADC_RES_L:
 49	case DA9055_REG_ADC_RES_H:
 50	case DA9055_REG_VSYS_RES:
 51	case DA9055_REG_ADCIN1_RES:
 52	case DA9055_REG_ADCIN2_RES:
 53	case DA9055_REG_ADCIN3_RES:
 54
 55	case DA9055_REG_COUNT_S:
 56	case DA9055_REG_COUNT_MI:
 57	case DA9055_REG_COUNT_H:
 58	case DA9055_REG_COUNT_D:
 59	case DA9055_REG_COUNT_MO:
 60	case DA9055_REG_COUNT_Y:
 61	case DA9055_REG_ALARM_H:
 62	case DA9055_REG_ALARM_D:
 63	case DA9055_REG_ALARM_MI:
 64	case DA9055_REG_ALARM_MO:
 65	case DA9055_REG_ALARM_Y:
 66
 67	case DA9055_REG_GPIO0_1:
 68	case DA9055_REG_GPIO2:
 69	case DA9055_REG_GPIO_MODE0_2:
 70
 71	case DA9055_REG_BCORE_CONT:
 72	case DA9055_REG_BMEM_CONT:
 73	case DA9055_REG_LDO1_CONT:
 74	case DA9055_REG_LDO2_CONT:
 75	case DA9055_REG_LDO3_CONT:
 76	case DA9055_REG_LDO4_CONT:
 77	case DA9055_REG_LDO5_CONT:
 78	case DA9055_REG_LDO6_CONT:
 79	case DA9055_REG_BUCK_LIM:
 80	case DA9055_REG_BCORE_MODE:
 81	case DA9055_REG_VBCORE_A:
 82	case DA9055_REG_VBMEM_A:
 83	case DA9055_REG_VLDO1_A:
 84	case DA9055_REG_VLDO2_A:
 85	case DA9055_REG_VLDO3_A:
 86	case DA9055_REG_VLDO4_A:
 87	case DA9055_REG_VLDO5_A:
 88	case DA9055_REG_VLDO6_A:
 89	case DA9055_REG_VBCORE_B:
 90	case DA9055_REG_VBMEM_B:
 91	case DA9055_REG_VLDO1_B:
 92	case DA9055_REG_VLDO2_B:
 93	case DA9055_REG_VLDO3_B:
 94	case DA9055_REG_VLDO4_B:
 95	case DA9055_REG_VLDO5_B:
 96	case DA9055_REG_VLDO6_B:
 97		return true;
 98	default:
 99		return false;
100	}
101}
102
103static bool da9055_register_writeable(struct device *dev, unsigned int reg)
104{
105	switch (reg) {
106	case DA9055_REG_STATUS_A:
107	case DA9055_REG_STATUS_B:
108	case DA9055_REG_EVENT_A:
109	case DA9055_REG_EVENT_B:
110	case DA9055_REG_EVENT_C:
111	case DA9055_REG_IRQ_MASK_A:
112	case DA9055_REG_IRQ_MASK_B:
113	case DA9055_REG_IRQ_MASK_C:
114
115	case DA9055_REG_CONTROL_A:
116	case DA9055_REG_CONTROL_B:
117	case DA9055_REG_CONTROL_C:
118	case DA9055_REG_CONTROL_D:
119	case DA9055_REG_CONTROL_E:
120
121	case DA9055_REG_ADC_MAN:
122	case DA9055_REG_ADC_CONT:
123	case DA9055_REG_VSYS_MON:
124	case DA9055_REG_ADC_RES_L:
125	case DA9055_REG_ADC_RES_H:
126	case DA9055_REG_VSYS_RES:
127	case DA9055_REG_ADCIN1_RES:
128	case DA9055_REG_ADCIN2_RES:
129	case DA9055_REG_ADCIN3_RES:
130
131	case DA9055_REG_COUNT_S:
132	case DA9055_REG_COUNT_MI:
133	case DA9055_REG_COUNT_H:
134	case DA9055_REG_COUNT_D:
135	case DA9055_REG_COUNT_MO:
136	case DA9055_REG_COUNT_Y:
137	case DA9055_REG_ALARM_H:
138	case DA9055_REG_ALARM_D:
139	case DA9055_REG_ALARM_MI:
140	case DA9055_REG_ALARM_MO:
141	case DA9055_REG_ALARM_Y:
142
143	case DA9055_REG_GPIO0_1:
144	case DA9055_REG_GPIO2:
145	case DA9055_REG_GPIO_MODE0_2:
146
147	case DA9055_REG_BCORE_CONT:
148	case DA9055_REG_BMEM_CONT:
149	case DA9055_REG_LDO1_CONT:
150	case DA9055_REG_LDO2_CONT:
151	case DA9055_REG_LDO3_CONT:
152	case DA9055_REG_LDO4_CONT:
153	case DA9055_REG_LDO5_CONT:
154	case DA9055_REG_LDO6_CONT:
155	case DA9055_REG_BUCK_LIM:
156	case DA9055_REG_BCORE_MODE:
157	case DA9055_REG_VBCORE_A:
158	case DA9055_REG_VBMEM_A:
159	case DA9055_REG_VLDO1_A:
160	case DA9055_REG_VLDO2_A:
161	case DA9055_REG_VLDO3_A:
162	case DA9055_REG_VLDO4_A:
163	case DA9055_REG_VLDO5_A:
164	case DA9055_REG_VLDO6_A:
165	case DA9055_REG_VBCORE_B:
166	case DA9055_REG_VBMEM_B:
167	case DA9055_REG_VLDO1_B:
168	case DA9055_REG_VLDO2_B:
169	case DA9055_REG_VLDO3_B:
170	case DA9055_REG_VLDO4_B:
171	case DA9055_REG_VLDO5_B:
172	case DA9055_REG_VLDO6_B:
173		return true;
174	default:
175		return false;
176	}
177}
178
179static bool da9055_register_volatile(struct device *dev, unsigned int reg)
180{
181	switch (reg) {
182	case DA9055_REG_STATUS_A:
183	case DA9055_REG_STATUS_B:
184	case DA9055_REG_EVENT_A:
185	case DA9055_REG_EVENT_B:
186	case DA9055_REG_EVENT_C:
187
188	case DA9055_REG_CONTROL_A:
189	case DA9055_REG_CONTROL_E:
190
191	case DA9055_REG_ADC_MAN:
192	case DA9055_REG_ADC_RES_L:
193	case DA9055_REG_ADC_RES_H:
194	case DA9055_REG_VSYS_RES:
195	case DA9055_REG_ADCIN1_RES:
196	case DA9055_REG_ADCIN2_RES:
197	case DA9055_REG_ADCIN3_RES:
198
199	case DA9055_REG_COUNT_S:
200	case DA9055_REG_COUNT_MI:
201	case DA9055_REG_COUNT_H:
202	case DA9055_REG_COUNT_D:
203	case DA9055_REG_COUNT_MO:
204	case DA9055_REG_COUNT_Y:
205	case DA9055_REG_ALARM_MI:
206
207	case DA9055_REG_BCORE_CONT:
208	case DA9055_REG_BMEM_CONT:
209	case DA9055_REG_LDO1_CONT:
210	case DA9055_REG_LDO2_CONT:
211	case DA9055_REG_LDO3_CONT:
212	case DA9055_REG_LDO4_CONT:
213	case DA9055_REG_LDO5_CONT:
214	case DA9055_REG_LDO6_CONT:
215		return true;
216	default:
217		return false;
218	}
219}
220
221static const struct regmap_irq da9055_irqs[] = {
222	[DA9055_IRQ_NONKEY] = {
223		.reg_offset = 0,
224		.mask = DA9055_IRQ_NONKEY_MASK,
225	},
226	[DA9055_IRQ_ALARM] = {
227		.reg_offset = 0,
228		.mask = DA9055_IRQ_ALM_MASK,
229	},
230	[DA9055_IRQ_TICK] = {
231		.reg_offset = 0,
232		.mask = DA9055_IRQ_TICK_MASK,
233	},
234	[DA9055_IRQ_HWMON] = {
235		.reg_offset = 0,
236		.mask = DA9055_IRQ_ADC_MASK,
237	},
238	[DA9055_IRQ_REGULATOR] = {
239		.reg_offset = 1,
240		.mask = DA9055_IRQ_BUCK_ILIM_MASK,
241	},
242};
243
244const struct regmap_config da9055_regmap_config = {
245	.reg_bits = 8,
246	.val_bits = 8,
247
248	.cache_type = REGCACHE_RBTREE,
249
250	.max_register = DA9055_MAX_REGISTER_CNT,
251	.readable_reg = da9055_register_readable,
252	.writeable_reg = da9055_register_writeable,
253	.volatile_reg = da9055_register_volatile,
254};
255EXPORT_SYMBOL_GPL(da9055_regmap_config);
256
257static struct resource da9055_onkey_resource = {
258	.name = "ONKEY",
259	.start = DA9055_IRQ_NONKEY,
260	.end   = DA9055_IRQ_NONKEY,
261	.flags = IORESOURCE_IRQ,
262};
263
264static struct resource da9055_rtc_resource[] = {
265	{
266		.name = "ALM",
267		.start = DA9055_IRQ_ALARM,
268		.end   = DA9055_IRQ_ALARM,
269		.flags = IORESOURCE_IRQ,
270	},
271	{
272		.name = "TICK",
273		.start = DA9055_IRQ_TICK,
274		.end   = DA9055_IRQ_TICK,
275		.flags = IORESOURCE_IRQ,
276	},
277};
278
279static struct resource da9055_hwmon_resource = {
280	.name = "HWMON",
281	.start = DA9055_IRQ_HWMON,
282	.end   = DA9055_IRQ_HWMON,
283	.flags = IORESOURCE_IRQ,
284};
285
286static struct resource da9055_ld05_6_resource = {
287	.name = "REGULATOR",
288	.start = DA9055_IRQ_REGULATOR,
289	.end   = DA9055_IRQ_REGULATOR,
290	.flags = IORESOURCE_IRQ,
291};
292
293static const struct mfd_cell da9055_devs[] = {
294	{
295		.of_compatible = "dlg,da9055-gpio",
296		.name = "da9055-gpio",
297	},
298	{
299		.of_compatible = "dlg,da9055-regulator",
300		.name = "da9055-regulator",
301		.id = 1,
302	},
303	{
304		.of_compatible = "dlg,da9055-regulator",
305		.name = "da9055-regulator",
306		.id = 2,
307	},
308	{
309		.of_compatible = "dlg,da9055-regulator",
310		.name = "da9055-regulator",
311		.id = 3,
312	},
313	{
314		.of_compatible = "dlg,da9055-regulator",
315		.name = "da9055-regulator",
316		.id = 4,
317	},
318	{
319		.of_compatible = "dlg,da9055-regulator",
320		.name = "da9055-regulator",
321		.id = 5,
322	},
323	{
324		.of_compatible = "dlg,da9055-regulator",
325		.name = "da9055-regulator",
326		.id = 6,
327	},
328	{
329		.of_compatible = "dlg,da9055-regulator",
330		.name = "da9055-regulator",
331		.id = 7,
332		.resources = &da9055_ld05_6_resource,
333		.num_resources = 1,
334	},
335	{
336		.of_compatible = "dlg,da9055-regulator",
337		.name = "da9055-regulator",
338		.resources = &da9055_ld05_6_resource,
339		.num_resources = 1,
340		.id = 8,
341	},
342	{
343		.of_compatible = "dlg,da9055-onkey",
344		.name = "da9055-onkey",
345		.resources = &da9055_onkey_resource,
346		.num_resources = 1,
347	},
348	{
349		.of_compatible = "dlg,da9055-rtc",
350		.name = "da9055-rtc",
351		.resources = da9055_rtc_resource,
352		.num_resources = ARRAY_SIZE(da9055_rtc_resource),
353	},
354	{
355		.of_compatible = "dlg,da9055-hwmon",
356		.name = "da9055-hwmon",
357		.resources = &da9055_hwmon_resource,
358		.num_resources = 1,
359	},
360	{
361		.of_compatible = "dlg,da9055-watchdog",
362		.name = "da9055-watchdog",
363	},
364};
365
366static const struct regmap_irq_chip da9055_regmap_irq_chip = {
367	.name = "da9055_irq",
368	.status_base = DA9055_REG_EVENT_A,
369	.mask_base = DA9055_REG_IRQ_MASK_A,
370	.ack_base = DA9055_REG_EVENT_A,
371	.num_regs = 3,
372	.irqs = da9055_irqs,
373	.num_irqs = ARRAY_SIZE(da9055_irqs),
374};
375
376int da9055_device_init(struct da9055 *da9055)
377{
378	struct da9055_pdata *pdata = dev_get_platdata(da9055->dev);
379	int ret;
380	uint8_t clear_events[3] = {0xFF, 0xFF, 0xFF};
381
382	if (pdata && pdata->init != NULL)
383		pdata->init(da9055);
384
385	if (!pdata || !pdata->irq_base)
386		da9055->irq_base = -1;
387	else
388		da9055->irq_base = pdata->irq_base;
389
390	ret = da9055_group_write(da9055, DA9055_REG_EVENT_A, 3, clear_events);
391	if (ret < 0)
392		return ret;
393
394	ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
395				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
396				  da9055->irq_base, &da9055_regmap_irq_chip,
397				  &da9055->irq_data);
398	if (ret < 0)
399		return ret;
400
401	da9055->irq_base = regmap_irq_chip_get_base(da9055->irq_data);
402
403	ret = mfd_add_devices(da9055->dev, -1,
404			      da9055_devs, ARRAY_SIZE(da9055_devs),
405			      NULL, da9055->irq_base, NULL);
406	if (ret)
407		goto err;
408
409	return 0;
410
411err:
412	mfd_remove_devices(da9055->dev);
413	return ret;
414}
415
416void da9055_device_exit(struct da9055 *da9055)
417{
418	regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
419	mfd_remove_devices(da9055->dev);
420}
421
422MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
423MODULE_LICENSE("GPL");
424MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
v4.10.11
 
  1/*
  2 * Device access for Dialog DA9055 PMICs.
  3 *
  4 * Copyright(c) 2012 Dialog Semiconductor Ltd.
  5 *
  6 * Author: David Dajun Chen <dchen@diasemi.com>
  7 *
  8 *  This program is free software; you can redistribute  it and/or modify it
  9 *  under  the terms of  the GNU General  Public License as published by the
 10 *  Free Software Foundation;  either version 2 of the  License, or (at your
 11 *  option) any later version.
 12 */
 13
 14#include <linux/module.h>
 15#include <linux/device.h>
 16#include <linux/input.h>
 17#include <linux/irq.h>
 18#include <linux/mutex.h>
 19
 20#include <linux/mfd/core.h>
 21#include <linux/mfd/da9055/core.h>
 22#include <linux/mfd/da9055/pdata.h>
 23#include <linux/mfd/da9055/reg.h>
 24
 25#define DA9055_IRQ_NONKEY_MASK		0x01
 26#define DA9055_IRQ_ALM_MASK		0x02
 27#define DA9055_IRQ_TICK_MASK		0x04
 28#define DA9055_IRQ_ADC_MASK		0x08
 29#define DA9055_IRQ_BUCK_ILIM_MASK	0x08
 30
 31static bool da9055_register_readable(struct device *dev, unsigned int reg)
 32{
 33	switch (reg) {
 34	case DA9055_REG_STATUS_A:
 35	case DA9055_REG_STATUS_B:
 36	case DA9055_REG_EVENT_A:
 37	case DA9055_REG_EVENT_B:
 38	case DA9055_REG_EVENT_C:
 39	case DA9055_REG_IRQ_MASK_A:
 40	case DA9055_REG_IRQ_MASK_B:
 41	case DA9055_REG_IRQ_MASK_C:
 42
 43	case DA9055_REG_CONTROL_A:
 44	case DA9055_REG_CONTROL_B:
 45	case DA9055_REG_CONTROL_C:
 46	case DA9055_REG_CONTROL_D:
 47	case DA9055_REG_CONTROL_E:
 48
 49	case DA9055_REG_ADC_MAN:
 50	case DA9055_REG_ADC_CONT:
 51	case DA9055_REG_VSYS_MON:
 52	case DA9055_REG_ADC_RES_L:
 53	case DA9055_REG_ADC_RES_H:
 54	case DA9055_REG_VSYS_RES:
 55	case DA9055_REG_ADCIN1_RES:
 56	case DA9055_REG_ADCIN2_RES:
 57	case DA9055_REG_ADCIN3_RES:
 58
 59	case DA9055_REG_COUNT_S:
 60	case DA9055_REG_COUNT_MI:
 61	case DA9055_REG_COUNT_H:
 62	case DA9055_REG_COUNT_D:
 63	case DA9055_REG_COUNT_MO:
 64	case DA9055_REG_COUNT_Y:
 65	case DA9055_REG_ALARM_H:
 66	case DA9055_REG_ALARM_D:
 67	case DA9055_REG_ALARM_MI:
 68	case DA9055_REG_ALARM_MO:
 69	case DA9055_REG_ALARM_Y:
 70
 71	case DA9055_REG_GPIO0_1:
 72	case DA9055_REG_GPIO2:
 73	case DA9055_REG_GPIO_MODE0_2:
 74
 75	case DA9055_REG_BCORE_CONT:
 76	case DA9055_REG_BMEM_CONT:
 77	case DA9055_REG_LDO1_CONT:
 78	case DA9055_REG_LDO2_CONT:
 79	case DA9055_REG_LDO3_CONT:
 80	case DA9055_REG_LDO4_CONT:
 81	case DA9055_REG_LDO5_CONT:
 82	case DA9055_REG_LDO6_CONT:
 83	case DA9055_REG_BUCK_LIM:
 84	case DA9055_REG_BCORE_MODE:
 85	case DA9055_REG_VBCORE_A:
 86	case DA9055_REG_VBMEM_A:
 87	case DA9055_REG_VLDO1_A:
 88	case DA9055_REG_VLDO2_A:
 89	case DA9055_REG_VLDO3_A:
 90	case DA9055_REG_VLDO4_A:
 91	case DA9055_REG_VLDO5_A:
 92	case DA9055_REG_VLDO6_A:
 93	case DA9055_REG_VBCORE_B:
 94	case DA9055_REG_VBMEM_B:
 95	case DA9055_REG_VLDO1_B:
 96	case DA9055_REG_VLDO2_B:
 97	case DA9055_REG_VLDO3_B:
 98	case DA9055_REG_VLDO4_B:
 99	case DA9055_REG_VLDO5_B:
100	case DA9055_REG_VLDO6_B:
101		return true;
102	default:
103		return false;
104	}
105}
106
107static bool da9055_register_writeable(struct device *dev, unsigned int reg)
108{
109	switch (reg) {
110	case DA9055_REG_STATUS_A:
111	case DA9055_REG_STATUS_B:
112	case DA9055_REG_EVENT_A:
113	case DA9055_REG_EVENT_B:
114	case DA9055_REG_EVENT_C:
115	case DA9055_REG_IRQ_MASK_A:
116	case DA9055_REG_IRQ_MASK_B:
117	case DA9055_REG_IRQ_MASK_C:
118
119	case DA9055_REG_CONTROL_A:
120	case DA9055_REG_CONTROL_B:
121	case DA9055_REG_CONTROL_C:
122	case DA9055_REG_CONTROL_D:
123	case DA9055_REG_CONTROL_E:
124
125	case DA9055_REG_ADC_MAN:
126	case DA9055_REG_ADC_CONT:
127	case DA9055_REG_VSYS_MON:
128	case DA9055_REG_ADC_RES_L:
129	case DA9055_REG_ADC_RES_H:
130	case DA9055_REG_VSYS_RES:
131	case DA9055_REG_ADCIN1_RES:
132	case DA9055_REG_ADCIN2_RES:
133	case DA9055_REG_ADCIN3_RES:
134
135	case DA9055_REG_COUNT_S:
136	case DA9055_REG_COUNT_MI:
137	case DA9055_REG_COUNT_H:
138	case DA9055_REG_COUNT_D:
139	case DA9055_REG_COUNT_MO:
140	case DA9055_REG_COUNT_Y:
141	case DA9055_REG_ALARM_H:
142	case DA9055_REG_ALARM_D:
143	case DA9055_REG_ALARM_MI:
144	case DA9055_REG_ALARM_MO:
145	case DA9055_REG_ALARM_Y:
146
147	case DA9055_REG_GPIO0_1:
148	case DA9055_REG_GPIO2:
149	case DA9055_REG_GPIO_MODE0_2:
150
151	case DA9055_REG_BCORE_CONT:
152	case DA9055_REG_BMEM_CONT:
153	case DA9055_REG_LDO1_CONT:
154	case DA9055_REG_LDO2_CONT:
155	case DA9055_REG_LDO3_CONT:
156	case DA9055_REG_LDO4_CONT:
157	case DA9055_REG_LDO5_CONT:
158	case DA9055_REG_LDO6_CONT:
159	case DA9055_REG_BUCK_LIM:
160	case DA9055_REG_BCORE_MODE:
161	case DA9055_REG_VBCORE_A:
162	case DA9055_REG_VBMEM_A:
163	case DA9055_REG_VLDO1_A:
164	case DA9055_REG_VLDO2_A:
165	case DA9055_REG_VLDO3_A:
166	case DA9055_REG_VLDO4_A:
167	case DA9055_REG_VLDO5_A:
168	case DA9055_REG_VLDO6_A:
169	case DA9055_REG_VBCORE_B:
170	case DA9055_REG_VBMEM_B:
171	case DA9055_REG_VLDO1_B:
172	case DA9055_REG_VLDO2_B:
173	case DA9055_REG_VLDO3_B:
174	case DA9055_REG_VLDO4_B:
175	case DA9055_REG_VLDO5_B:
176	case DA9055_REG_VLDO6_B:
177		return true;
178	default:
179		return false;
180	}
181}
182
183static bool da9055_register_volatile(struct device *dev, unsigned int reg)
184{
185	switch (reg) {
186	case DA9055_REG_STATUS_A:
187	case DA9055_REG_STATUS_B:
188	case DA9055_REG_EVENT_A:
189	case DA9055_REG_EVENT_B:
190	case DA9055_REG_EVENT_C:
191
192	case DA9055_REG_CONTROL_A:
193	case DA9055_REG_CONTROL_E:
194
195	case DA9055_REG_ADC_MAN:
196	case DA9055_REG_ADC_RES_L:
197	case DA9055_REG_ADC_RES_H:
198	case DA9055_REG_VSYS_RES:
199	case DA9055_REG_ADCIN1_RES:
200	case DA9055_REG_ADCIN2_RES:
201	case DA9055_REG_ADCIN3_RES:
202
203	case DA9055_REG_COUNT_S:
204	case DA9055_REG_COUNT_MI:
205	case DA9055_REG_COUNT_H:
206	case DA9055_REG_COUNT_D:
207	case DA9055_REG_COUNT_MO:
208	case DA9055_REG_COUNT_Y:
209	case DA9055_REG_ALARM_MI:
210
211	case DA9055_REG_BCORE_CONT:
212	case DA9055_REG_BMEM_CONT:
213	case DA9055_REG_LDO1_CONT:
214	case DA9055_REG_LDO2_CONT:
215	case DA9055_REG_LDO3_CONT:
216	case DA9055_REG_LDO4_CONT:
217	case DA9055_REG_LDO5_CONT:
218	case DA9055_REG_LDO6_CONT:
219		return true;
220	default:
221		return false;
222	}
223}
224
225static const struct regmap_irq da9055_irqs[] = {
226	[DA9055_IRQ_NONKEY] = {
227		.reg_offset = 0,
228		.mask = DA9055_IRQ_NONKEY_MASK,
229	},
230	[DA9055_IRQ_ALARM] = {
231		.reg_offset = 0,
232		.mask = DA9055_IRQ_ALM_MASK,
233	},
234	[DA9055_IRQ_TICK] = {
235		.reg_offset = 0,
236		.mask = DA9055_IRQ_TICK_MASK,
237	},
238	[DA9055_IRQ_HWMON] = {
239		.reg_offset = 0,
240		.mask = DA9055_IRQ_ADC_MASK,
241	},
242	[DA9055_IRQ_REGULATOR] = {
243		.reg_offset = 1,
244		.mask = DA9055_IRQ_BUCK_ILIM_MASK,
245	},
246};
247
248const struct regmap_config da9055_regmap_config = {
249	.reg_bits = 8,
250	.val_bits = 8,
251
252	.cache_type = REGCACHE_RBTREE,
253
254	.max_register = DA9055_MAX_REGISTER_CNT,
255	.readable_reg = da9055_register_readable,
256	.writeable_reg = da9055_register_writeable,
257	.volatile_reg = da9055_register_volatile,
258};
259EXPORT_SYMBOL_GPL(da9055_regmap_config);
260
261static struct resource da9055_onkey_resource = {
262	.name = "ONKEY",
263	.start = DA9055_IRQ_NONKEY,
264	.end   = DA9055_IRQ_NONKEY,
265	.flags = IORESOURCE_IRQ,
266};
267
268static struct resource da9055_rtc_resource[] = {
269	{
270		.name = "ALM",
271		.start = DA9055_IRQ_ALARM,
272		.end   = DA9055_IRQ_ALARM,
273		.flags = IORESOURCE_IRQ,
274	},
275	{
276		.name = "TICK",
277		.start = DA9055_IRQ_TICK,
278		.end   = DA9055_IRQ_TICK,
279		.flags = IORESOURCE_IRQ,
280	},
281};
282
283static struct resource da9055_hwmon_resource = {
284	.name = "HWMON",
285	.start = DA9055_IRQ_HWMON,
286	.end   = DA9055_IRQ_HWMON,
287	.flags = IORESOURCE_IRQ,
288};
289
290static struct resource da9055_ld05_6_resource = {
291	.name = "REGULATOR",
292	.start = DA9055_IRQ_REGULATOR,
293	.end   = DA9055_IRQ_REGULATOR,
294	.flags = IORESOURCE_IRQ,
295};
296
297static const struct mfd_cell da9055_devs[] = {
298	{
299		.of_compatible = "dlg,da9055-gpio",
300		.name = "da9055-gpio",
301	},
302	{
303		.of_compatible = "dlg,da9055-regulator",
304		.name = "da9055-regulator",
305		.id = 1,
306	},
307	{
308		.of_compatible = "dlg,da9055-regulator",
309		.name = "da9055-regulator",
310		.id = 2,
311	},
312	{
313		.of_compatible = "dlg,da9055-regulator",
314		.name = "da9055-regulator",
315		.id = 3,
316	},
317	{
318		.of_compatible = "dlg,da9055-regulator",
319		.name = "da9055-regulator",
320		.id = 4,
321	},
322	{
323		.of_compatible = "dlg,da9055-regulator",
324		.name = "da9055-regulator",
325		.id = 5,
326	},
327	{
328		.of_compatible = "dlg,da9055-regulator",
329		.name = "da9055-regulator",
330		.id = 6,
331	},
332	{
333		.of_compatible = "dlg,da9055-regulator",
334		.name = "da9055-regulator",
335		.id = 7,
336		.resources = &da9055_ld05_6_resource,
337		.num_resources = 1,
338	},
339	{
340		.of_compatible = "dlg,da9055-regulator",
341		.name = "da9055-regulator",
342		.resources = &da9055_ld05_6_resource,
343		.num_resources = 1,
344		.id = 8,
345	},
346	{
347		.of_compatible = "dlg,da9055-onkey",
348		.name = "da9055-onkey",
349		.resources = &da9055_onkey_resource,
350		.num_resources = 1,
351	},
352	{
353		.of_compatible = "dlg,da9055-rtc",
354		.name = "da9055-rtc",
355		.resources = da9055_rtc_resource,
356		.num_resources = ARRAY_SIZE(da9055_rtc_resource),
357	},
358	{
359		.of_compatible = "dlg,da9055-hwmon",
360		.name = "da9055-hwmon",
361		.resources = &da9055_hwmon_resource,
362		.num_resources = 1,
363	},
364	{
365		.of_compatible = "dlg,da9055-watchdog",
366		.name = "da9055-watchdog",
367	},
368};
369
370static const struct regmap_irq_chip da9055_regmap_irq_chip = {
371	.name = "da9055_irq",
372	.status_base = DA9055_REG_EVENT_A,
373	.mask_base = DA9055_REG_IRQ_MASK_A,
374	.ack_base = DA9055_REG_EVENT_A,
375	.num_regs = 3,
376	.irqs = da9055_irqs,
377	.num_irqs = ARRAY_SIZE(da9055_irqs),
378};
379
380int da9055_device_init(struct da9055 *da9055)
381{
382	struct da9055_pdata *pdata = dev_get_platdata(da9055->dev);
383	int ret;
384	uint8_t clear_events[3] = {0xFF, 0xFF, 0xFF};
385
386	if (pdata && pdata->init != NULL)
387		pdata->init(da9055);
388
389	if (!pdata || !pdata->irq_base)
390		da9055->irq_base = -1;
391	else
392		da9055->irq_base = pdata->irq_base;
393
394	ret = da9055_group_write(da9055, DA9055_REG_EVENT_A, 3, clear_events);
395	if (ret < 0)
396		return ret;
397
398	ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
399				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
400				  da9055->irq_base, &da9055_regmap_irq_chip,
401				  &da9055->irq_data);
402	if (ret < 0)
403		return ret;
404
405	da9055->irq_base = regmap_irq_chip_get_base(da9055->irq_data);
406
407	ret = mfd_add_devices(da9055->dev, -1,
408			      da9055_devs, ARRAY_SIZE(da9055_devs),
409			      NULL, da9055->irq_base, NULL);
410	if (ret)
411		goto err;
412
413	return 0;
414
415err:
416	mfd_remove_devices(da9055->dev);
417	return ret;
418}
419
420void da9055_device_exit(struct da9055 *da9055)
421{
422	regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
423	mfd_remove_devices(da9055->dev);
424}
425
426MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
427MODULE_LICENSE("GPL");
428MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");