brintos

brintos / linux-shallow public Read only

0
0
Text · 3.5 KiB · e896531 Raw
151 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2007-2010 ST-Ericsson4 * Register access functions for the ABX500 Mixed Signal IC family.5 * Author: Mattias Wallin <mattias.wallin@stericsson.com>6 */7 8#include <linux/list.h>9#include <linux/slab.h>10#include <linux/err.h>11#include <linux/init.h>12#include <linux/export.h>13#include <linux/mfd/abx500.h>14 15static LIST_HEAD(abx500_list);16 17struct abx500_device_entry {18	struct list_head list;19	struct abx500_ops ops;20	struct device *dev;21};22 23static void lookup_ops(struct device *dev, struct abx500_ops **ops)24{25	struct abx500_device_entry *dev_entry;26 27	*ops = NULL;28	list_for_each_entry(dev_entry, &abx500_list, list) {29		if (dev_entry->dev == dev) {30			*ops = &dev_entry->ops;31			return;32		}33	}34}35 36int abx500_register_ops(struct device *dev, struct abx500_ops *ops)37{38	struct abx500_device_entry *dev_entry;39 40	dev_entry = devm_kzalloc(dev, sizeof(*dev_entry), GFP_KERNEL);41	if (!dev_entry)42		return -ENOMEM;43 44	dev_entry->dev = dev;45	memcpy(&dev_entry->ops, ops, sizeof(*ops));46 47	list_add_tail(&dev_entry->list, &abx500_list);48	return 0;49}50EXPORT_SYMBOL(abx500_register_ops);51 52void abx500_remove_ops(struct device *dev)53{54	struct abx500_device_entry *dev_entry, *tmp;55 56	list_for_each_entry_safe(dev_entry, tmp, &abx500_list, list)57		if (dev_entry->dev == dev)58			list_del(&dev_entry->list);59}60EXPORT_SYMBOL(abx500_remove_ops);61 62int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,63	u8 value)64{65	struct abx500_ops *ops;66 67	lookup_ops(dev->parent, &ops);68	if (ops && ops->set_register)69		return ops->set_register(dev, bank, reg, value);70	else71		return -ENOTSUPP;72}73EXPORT_SYMBOL(abx500_set_register_interruptible);74 75int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg,76	u8 *value)77{78	struct abx500_ops *ops;79 80	lookup_ops(dev->parent, &ops);81	if (ops && ops->get_register)82		return ops->get_register(dev, bank, reg, value);83	else84		return -ENOTSUPP;85}86EXPORT_SYMBOL(abx500_get_register_interruptible);87 88int abx500_get_register_page_interruptible(struct device *dev, u8 bank,89	u8 first_reg, u8 *regvals, u8 numregs)90{91	struct abx500_ops *ops;92 93	lookup_ops(dev->parent, &ops);94	if (ops && ops->get_register_page)95		return ops->get_register_page(dev, bank,96			first_reg, regvals, numregs);97	else98		return -ENOTSUPP;99}100EXPORT_SYMBOL(abx500_get_register_page_interruptible);101 102int abx500_mask_and_set_register_interruptible(struct device *dev, u8 bank,103	u8 reg, u8 bitmask, u8 bitvalues)104{105	struct abx500_ops *ops;106 107	lookup_ops(dev->parent, &ops);108	if (ops && ops->mask_and_set_register)109		return ops->mask_and_set_register(dev, bank,110			reg, bitmask, bitvalues);111	else112		return -ENOTSUPP;113}114EXPORT_SYMBOL(abx500_mask_and_set_register_interruptible);115 116int abx500_get_chip_id(struct device *dev)117{118	struct abx500_ops *ops;119 120	lookup_ops(dev->parent, &ops);121	if (ops && ops->get_chip_id)122		return ops->get_chip_id(dev);123	else124		return -ENOTSUPP;125}126EXPORT_SYMBOL(abx500_get_chip_id);127 128int abx500_event_registers_startup_state_get(struct device *dev, u8 *event)129{130	struct abx500_ops *ops;131 132	lookup_ops(dev->parent, &ops);133	if (ops && ops->event_registers_startup_state_get)134		return ops->event_registers_startup_state_get(dev, event);135	else136		return -ENOTSUPP;137}138EXPORT_SYMBOL(abx500_event_registers_startup_state_get);139 140int abx500_startup_irq_enabled(struct device *dev, unsigned int irq)141{142	struct abx500_ops *ops;143 144	lookup_ops(dev->parent, &ops);145	if (ops && ops->startup_irq_enabled)146		return ops->startup_irq_enabled(dev, irq);147	else148		return -ENOTSUPP;149}150EXPORT_SYMBOL(abx500_startup_irq_enabled);151