xref: /openbmc/linux/drivers/mfd/abx500-core.c (revision af873fce)
1af873fceSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2fa661258SMattias Wallin /*
3fa661258SMattias Wallin  * Copyright (C) 2007-2010 ST-Ericsson
4fa661258SMattias Wallin  * Register access functions for the ABX500 Mixed Signal IC family.
5fa661258SMattias Wallin  * Author: Mattias Wallin <mattias.wallin@stericsson.com>
6fa661258SMattias Wallin  */
7fa661258SMattias Wallin 
8fa661258SMattias Wallin #include <linux/list.h>
9fa661258SMattias Wallin #include <linux/slab.h>
10fa661258SMattias Wallin #include <linux/err.h>
11fdae7ba3SPaul Gortmaker #include <linux/init.h>
12fdae7ba3SPaul Gortmaker #include <linux/export.h>
13fa661258SMattias Wallin #include <linux/mfd/abx500.h>
14fa661258SMattias Wallin 
15fa661258SMattias Wallin static LIST_HEAD(abx500_list);
16fa661258SMattias Wallin 
17fa661258SMattias Wallin struct abx500_device_entry {
18fa661258SMattias Wallin 	struct list_head list;
19fa661258SMattias Wallin 	struct abx500_ops ops;
20fa661258SMattias Wallin 	struct device *dev;
21fa661258SMattias Wallin };
22fa661258SMattias Wallin 
lookup_ops(struct device * dev,struct abx500_ops ** ops)23fa661258SMattias Wallin static void lookup_ops(struct device *dev, struct abx500_ops **ops)
24fa661258SMattias Wallin {
25fa661258SMattias Wallin 	struct abx500_device_entry *dev_entry;
26fa661258SMattias Wallin 
27fa661258SMattias Wallin 	*ops = NULL;
28fa661258SMattias Wallin 	list_for_each_entry(dev_entry, &abx500_list, list) {
29fa661258SMattias Wallin 		if (dev_entry->dev == dev) {
30fa661258SMattias Wallin 			*ops = &dev_entry->ops;
31fa661258SMattias Wallin 			return;
32fa661258SMattias Wallin 		}
33fa661258SMattias Wallin 	}
34fa661258SMattias Wallin }
35fa661258SMattias Wallin 
abx500_register_ops(struct device * dev,struct abx500_ops * ops)36fa661258SMattias Wallin int abx500_register_ops(struct device *dev, struct abx500_ops *ops)
37fa661258SMattias Wallin {
38fa661258SMattias Wallin 	struct abx500_device_entry *dev_entry;
39fa661258SMattias Wallin 
405053e3a3SMarkus Elfring 	dev_entry = devm_kzalloc(dev, sizeof(*dev_entry), GFP_KERNEL);
41a5e20bfaSMarkus Elfring 	if (!dev_entry)
42fa661258SMattias Wallin 		return -ENOMEM;
43a5e20bfaSMarkus Elfring 
44fa661258SMattias Wallin 	dev_entry->dev = dev;
455053e3a3SMarkus Elfring 	memcpy(&dev_entry->ops, ops, sizeof(*ops));
46fa661258SMattias Wallin 
47fa661258SMattias Wallin 	list_add_tail(&dev_entry->list, &abx500_list);
48fa661258SMattias Wallin 	return 0;
49fa661258SMattias Wallin }
50fa661258SMattias Wallin EXPORT_SYMBOL(abx500_register_ops);
51fa661258SMattias Wallin 
abx500_remove_ops(struct device * dev)52fa661258SMattias Wallin void abx500_remove_ops(struct device *dev)
53fa661258SMattias Wallin {
54fa661258SMattias Wallin 	struct abx500_device_entry *dev_entry, *tmp;
55fa661258SMattias Wallin 
56fa661258SMattias Wallin 	list_for_each_entry_safe(dev_entry, tmp, &abx500_list, list)
57c211b6b9SLee Jones 		if (dev_entry->dev == dev)
58fa661258SMattias Wallin 			list_del(&dev_entry->list);
59fa661258SMattias Wallin }
60fa661258SMattias Wallin EXPORT_SYMBOL(abx500_remove_ops);
61fa661258SMattias Wallin 
abx500_set_register_interruptible(struct device * dev,u8 bank,u8 reg,u8 value)62fa661258SMattias Wallin int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
63fa661258SMattias Wallin 	u8 value)
64fa661258SMattias Wallin {
65fa661258SMattias Wallin 	struct abx500_ops *ops;
66fa661258SMattias Wallin 
67fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
686271299dSMarkus Elfring 	if (ops && ops->set_register)
69fa661258SMattias Wallin 		return ops->set_register(dev, bank, reg, value);
70fa661258SMattias Wallin 	else
71fa661258SMattias Wallin 		return -ENOTSUPP;
72fa661258SMattias Wallin }
73fa661258SMattias Wallin EXPORT_SYMBOL(abx500_set_register_interruptible);
74fa661258SMattias Wallin 
abx500_get_register_interruptible(struct device * dev,u8 bank,u8 reg,u8 * value)75fa661258SMattias Wallin int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg,
76fa661258SMattias Wallin 	u8 *value)
77fa661258SMattias Wallin {
78fa661258SMattias Wallin 	struct abx500_ops *ops;
79fa661258SMattias Wallin 
80fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
816271299dSMarkus Elfring 	if (ops && ops->get_register)
82fa661258SMattias Wallin 		return ops->get_register(dev, bank, reg, value);
83fa661258SMattias Wallin 	else
84fa661258SMattias Wallin 		return -ENOTSUPP;
85fa661258SMattias Wallin }
86fa661258SMattias Wallin EXPORT_SYMBOL(abx500_get_register_interruptible);
87fa661258SMattias Wallin 
abx500_get_register_page_interruptible(struct device * dev,u8 bank,u8 first_reg,u8 * regvals,u8 numregs)88fa661258SMattias Wallin int abx500_get_register_page_interruptible(struct device *dev, u8 bank,
89fa661258SMattias Wallin 	u8 first_reg, u8 *regvals, u8 numregs)
90fa661258SMattias Wallin {
91fa661258SMattias Wallin 	struct abx500_ops *ops;
92fa661258SMattias Wallin 
93fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
946271299dSMarkus Elfring 	if (ops && ops->get_register_page)
95fa661258SMattias Wallin 		return ops->get_register_page(dev, bank,
96fa661258SMattias Wallin 			first_reg, regvals, numregs);
97fa661258SMattias Wallin 	else
98fa661258SMattias Wallin 		return -ENOTSUPP;
99fa661258SMattias Wallin }
100fa661258SMattias Wallin EXPORT_SYMBOL(abx500_get_register_page_interruptible);
101fa661258SMattias Wallin 
abx500_mask_and_set_register_interruptible(struct device * dev,u8 bank,u8 reg,u8 bitmask,u8 bitvalues)102fa661258SMattias Wallin int abx500_mask_and_set_register_interruptible(struct device *dev, u8 bank,
103fa661258SMattias Wallin 	u8 reg, u8 bitmask, u8 bitvalues)
104fa661258SMattias Wallin {
105fa661258SMattias Wallin 	struct abx500_ops *ops;
106fa661258SMattias Wallin 
107fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
1086271299dSMarkus Elfring 	if (ops && ops->mask_and_set_register)
109fa661258SMattias Wallin 		return ops->mask_and_set_register(dev, bank,
110fa661258SMattias Wallin 			reg, bitmask, bitvalues);
111fa661258SMattias Wallin 	else
112fa661258SMattias Wallin 		return -ENOTSUPP;
113fa661258SMattias Wallin }
114fa661258SMattias Wallin EXPORT_SYMBOL(abx500_mask_and_set_register_interruptible);
115fa661258SMattias Wallin 
abx500_get_chip_id(struct device * dev)116fa661258SMattias Wallin int abx500_get_chip_id(struct device *dev)
117fa661258SMattias Wallin {
118fa661258SMattias Wallin 	struct abx500_ops *ops;
119fa661258SMattias Wallin 
120fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
1216271299dSMarkus Elfring 	if (ops && ops->get_chip_id)
122fa661258SMattias Wallin 		return ops->get_chip_id(dev);
123fa661258SMattias Wallin 	else
124fa661258SMattias Wallin 		return -ENOTSUPP;
125fa661258SMattias Wallin }
126fa661258SMattias Wallin EXPORT_SYMBOL(abx500_get_chip_id);
127fa661258SMattias Wallin 
abx500_event_registers_startup_state_get(struct device * dev,u8 * event)128fa661258SMattias Wallin int abx500_event_registers_startup_state_get(struct device *dev, u8 *event)
129fa661258SMattias Wallin {
130fa661258SMattias Wallin 	struct abx500_ops *ops;
131fa661258SMattias Wallin 
132fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
1336271299dSMarkus Elfring 	if (ops && ops->event_registers_startup_state_get)
134fa661258SMattias Wallin 		return ops->event_registers_startup_state_get(dev, event);
135fa661258SMattias Wallin 	else
136fa661258SMattias Wallin 		return -ENOTSUPP;
137fa661258SMattias Wallin }
138fa661258SMattias Wallin EXPORT_SYMBOL(abx500_event_registers_startup_state_get);
139fa661258SMattias Wallin 
abx500_startup_irq_enabled(struct device * dev,unsigned int irq)140fa661258SMattias Wallin int abx500_startup_irq_enabled(struct device *dev, unsigned int irq)
141fa661258SMattias Wallin {
142fa661258SMattias Wallin 	struct abx500_ops *ops;
143fa661258SMattias Wallin 
144fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
1456271299dSMarkus Elfring 	if (ops && ops->startup_irq_enabled)
146fa661258SMattias Wallin 		return ops->startup_irq_enabled(dev, irq);
147fa661258SMattias Wallin 	else
148fa661258SMattias Wallin 		return -ENOTSUPP;
149fa661258SMattias Wallin }
150fa661258SMattias Wallin EXPORT_SYMBOL(abx500_startup_irq_enabled);
151