xref: /openbmc/linux/drivers/mfd/abx500-core.c (revision fa661258)
1fa661258SMattias Wallin /*
2fa661258SMattias Wallin  * Copyright (C) 2007-2010 ST-Ericsson
3fa661258SMattias Wallin  * License terms: GNU General Public License (GPL) version 2
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>
11fa661258SMattias Wallin #include <linux/mfd/abx500.h>
12fa661258SMattias Wallin 
13fa661258SMattias Wallin static LIST_HEAD(abx500_list);
14fa661258SMattias Wallin 
15fa661258SMattias Wallin struct abx500_device_entry {
16fa661258SMattias Wallin 	struct list_head list;
17fa661258SMattias Wallin 	struct abx500_ops ops;
18fa661258SMattias Wallin 	struct device *dev;
19fa661258SMattias Wallin };
20fa661258SMattias Wallin 
21fa661258SMattias Wallin static void lookup_ops(struct device *dev, struct abx500_ops **ops)
22fa661258SMattias Wallin {
23fa661258SMattias Wallin 	struct abx500_device_entry *dev_entry;
24fa661258SMattias Wallin 
25fa661258SMattias Wallin 	*ops = NULL;
26fa661258SMattias Wallin 	list_for_each_entry(dev_entry, &abx500_list, list) {
27fa661258SMattias Wallin 		if (dev_entry->dev == dev) {
28fa661258SMattias Wallin 			*ops = &dev_entry->ops;
29fa661258SMattias Wallin 			return;
30fa661258SMattias Wallin 		}
31fa661258SMattias Wallin 	}
32fa661258SMattias Wallin }
33fa661258SMattias Wallin 
34fa661258SMattias Wallin int abx500_register_ops(struct device *dev, struct abx500_ops *ops)
35fa661258SMattias Wallin {
36fa661258SMattias Wallin 	struct abx500_device_entry *dev_entry;
37fa661258SMattias Wallin 
38fa661258SMattias Wallin 	dev_entry = kzalloc(sizeof(struct abx500_device_entry), GFP_KERNEL);
39fa661258SMattias Wallin 	if (IS_ERR(dev_entry)) {
40fa661258SMattias Wallin 		dev_err(dev, "register_ops kzalloc failed");
41fa661258SMattias Wallin 		return -ENOMEM;
42fa661258SMattias Wallin 	}
43fa661258SMattias Wallin 	dev_entry->dev = dev;
44fa661258SMattias Wallin 	memcpy(&dev_entry->ops, ops, sizeof(struct abx500_ops));
45fa661258SMattias Wallin 
46fa661258SMattias Wallin 	list_add_tail(&dev_entry->list, &abx500_list);
47fa661258SMattias Wallin 	return 0;
48fa661258SMattias Wallin }
49fa661258SMattias Wallin EXPORT_SYMBOL(abx500_register_ops);
50fa661258SMattias Wallin 
51fa661258SMattias Wallin void abx500_remove_ops(struct device *dev)
52fa661258SMattias Wallin {
53fa661258SMattias Wallin 	struct abx500_device_entry *dev_entry, *tmp;
54fa661258SMattias Wallin 
55fa661258SMattias Wallin 	list_for_each_entry_safe(dev_entry, tmp, &abx500_list, list)
56fa661258SMattias Wallin 	{
57fa661258SMattias Wallin 		if (dev_entry->dev == dev) {
58fa661258SMattias Wallin 			list_del(&dev_entry->list);
59fa661258SMattias Wallin 			kfree(dev_entry);
60fa661258SMattias Wallin 		}
61fa661258SMattias Wallin 	}
62fa661258SMattias Wallin }
63fa661258SMattias Wallin EXPORT_SYMBOL(abx500_remove_ops);
64fa661258SMattias Wallin 
65fa661258SMattias Wallin int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
66fa661258SMattias Wallin 	u8 value)
67fa661258SMattias Wallin {
68fa661258SMattias Wallin 	struct abx500_ops *ops;
69fa661258SMattias Wallin 
70fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
71fa661258SMattias Wallin 	if ((ops != NULL) && (ops->set_register != NULL))
72fa661258SMattias Wallin 		return ops->set_register(dev, bank, reg, value);
73fa661258SMattias Wallin 	else
74fa661258SMattias Wallin 		return -ENOTSUPP;
75fa661258SMattias Wallin }
76fa661258SMattias Wallin EXPORT_SYMBOL(abx500_set_register_interruptible);
77fa661258SMattias Wallin 
78fa661258SMattias Wallin int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg,
79fa661258SMattias Wallin 	u8 *value)
80fa661258SMattias Wallin {
81fa661258SMattias Wallin 	struct abx500_ops *ops;
82fa661258SMattias Wallin 
83fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
84fa661258SMattias Wallin 	if ((ops != NULL) && (ops->get_register != NULL))
85fa661258SMattias Wallin 		return ops->get_register(dev, bank, reg, value);
86fa661258SMattias Wallin 	else
87fa661258SMattias Wallin 		return -ENOTSUPP;
88fa661258SMattias Wallin }
89fa661258SMattias Wallin EXPORT_SYMBOL(abx500_get_register_interruptible);
90fa661258SMattias Wallin 
91fa661258SMattias Wallin int abx500_get_register_page_interruptible(struct device *dev, u8 bank,
92fa661258SMattias Wallin 	u8 first_reg, u8 *regvals, u8 numregs)
93fa661258SMattias Wallin {
94fa661258SMattias Wallin 	struct abx500_ops *ops;
95fa661258SMattias Wallin 
96fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
97fa661258SMattias Wallin 	if ((ops != NULL) && (ops->get_register_page != NULL))
98fa661258SMattias Wallin 		return ops->get_register_page(dev, bank,
99fa661258SMattias Wallin 			first_reg, regvals, numregs);
100fa661258SMattias Wallin 	else
101fa661258SMattias Wallin 		return -ENOTSUPP;
102fa661258SMattias Wallin }
103fa661258SMattias Wallin EXPORT_SYMBOL(abx500_get_register_page_interruptible);
104fa661258SMattias Wallin 
105fa661258SMattias Wallin int abx500_mask_and_set_register_interruptible(struct device *dev, u8 bank,
106fa661258SMattias Wallin 	u8 reg, u8 bitmask, u8 bitvalues)
107fa661258SMattias Wallin {
108fa661258SMattias Wallin 	struct abx500_ops *ops;
109fa661258SMattias Wallin 
110fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
111fa661258SMattias Wallin 	if ((ops != NULL) && (ops->mask_and_set_register != NULL))
112fa661258SMattias Wallin 		return ops->mask_and_set_register(dev, bank,
113fa661258SMattias Wallin 			reg, bitmask, bitvalues);
114fa661258SMattias Wallin 	else
115fa661258SMattias Wallin 		return -ENOTSUPP;
116fa661258SMattias Wallin }
117fa661258SMattias Wallin EXPORT_SYMBOL(abx500_mask_and_set_register_interruptible);
118fa661258SMattias Wallin 
119fa661258SMattias Wallin int abx500_get_chip_id(struct device *dev)
120fa661258SMattias Wallin {
121fa661258SMattias Wallin 	struct abx500_ops *ops;
122fa661258SMattias Wallin 
123fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
124fa661258SMattias Wallin 	if ((ops != NULL) && (ops->get_chip_id != NULL))
125fa661258SMattias Wallin 		return ops->get_chip_id(dev);
126fa661258SMattias Wallin 	else
127fa661258SMattias Wallin 		return -ENOTSUPP;
128fa661258SMattias Wallin }
129fa661258SMattias Wallin EXPORT_SYMBOL(abx500_get_chip_id);
130fa661258SMattias Wallin 
131fa661258SMattias Wallin int abx500_event_registers_startup_state_get(struct device *dev, u8 *event)
132fa661258SMattias Wallin {
133fa661258SMattias Wallin 	struct abx500_ops *ops;
134fa661258SMattias Wallin 
135fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
136fa661258SMattias Wallin 	if ((ops != NULL) && (ops->event_registers_startup_state_get != NULL))
137fa661258SMattias Wallin 		return ops->event_registers_startup_state_get(dev, event);
138fa661258SMattias Wallin 	else
139fa661258SMattias Wallin 		return -ENOTSUPP;
140fa661258SMattias Wallin }
141fa661258SMattias Wallin EXPORT_SYMBOL(abx500_event_registers_startup_state_get);
142fa661258SMattias Wallin 
143fa661258SMattias Wallin int abx500_startup_irq_enabled(struct device *dev, unsigned int irq)
144fa661258SMattias Wallin {
145fa661258SMattias Wallin 	struct abx500_ops *ops;
146fa661258SMattias Wallin 
147fa661258SMattias Wallin 	lookup_ops(dev->parent, &ops);
148fa661258SMattias Wallin 	if ((ops != NULL) && (ops->startup_irq_enabled != NULL))
149fa661258SMattias Wallin 		return ops->startup_irq_enabled(dev, irq);
150fa661258SMattias Wallin 	else
151fa661258SMattias Wallin 		return -ENOTSUPP;
152fa661258SMattias Wallin }
153fa661258SMattias Wallin EXPORT_SYMBOL(abx500_startup_irq_enabled);
154fa661258SMattias Wallin 
155fa661258SMattias Wallin MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>");
156fa661258SMattias Wallin MODULE_DESCRIPTION("ABX500 core driver");
157fa661258SMattias Wallin MODULE_LICENSE("GPL");
158