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