Commit b83a313b authored by Mark Brown's avatar Mark Brown

regmap: Add generic non-memory mapped register access API

There are many places in the tree where we implement register access for
devices on non-memory mapped buses, especially I2C and SPI. Since hardware
designers seem to have settled on a relatively consistent set of register
interfaces this can be effectively factored out into shared code.  There
are a standard set of formats for marshalling data for exchange with the
device, with the actual I/O mechanisms generally being simple byte
streams.

We create an abstraction for marshaling data into formats which can be
sent on the control interfaces, and create a standard method for
plugging in actual transport underneath that.

This is mostly a refactoring and renaming of the bottom level of the
existing code for sharing register I/O which we have in ASoC. A
subsequent patch in this series converts ASoC to use this.  The main
difference in interface is that reads return values by writing to a
location provided by a pointer rather than in the return value, ensuring
we can use the full range of the type for register data.  We also use
unsigned types rather than ints for the same reason.

As some of the devices can have very large register maps the existing
ASoC code also contains infrastructure for managing register caches.
This cache work will be moved over in a future stage to allow for
separate review, the current patch only deals with the physical I/O.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: default avatarLiam Girdwood <lrg@ti.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
Acked-by: default avatarWolfram Sang <w.sang@pengutronix.de>
Acked-by: default avatarGrant Likely <grant.likely@secretlab.ca>
parent 620917de
......@@ -5313,6 +5313,13 @@ L: reiserfs-devel@vger.kernel.org
S: Supported
F: fs/reiserfs/
REGISTER MAP ABSTRACTION
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git
S: Supported
F: drivers/base/regmap/
F: include/linux/regmap.h
RFKILL
M: Johannes Berg <johannes@sipsolutions.net>
L: linux-wireless@vger.kernel.org
......
......@@ -168,4 +168,6 @@ config SYS_HYPERVISOR
bool
default n
source "drivers/base/regmap/Kconfig"
endmenu
......@@ -18,6 +18,7 @@ ifeq ($(CONFIG_SYSFS),y)
obj-$(CONFIG_MODULES) += module.o
endif
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
obj-$(CONFIG_REGMAP) += regmap/
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
# Generic register map support. There are no user servicable options here,
# this is an API intended to be used by other kernel subsystems. These
# subsystems should select the appropriate symbols.
config REGMAP
bool
obj-$(CONFIG_REGMAP) += regmap.o
This diff is collapsed.
#ifndef __LINUX_REGMAP_H
#define __LINUX_REGMAP_H
/*
* Register map access API
*
* Copyright 2011 Wolfson Microelectronics plc
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/device.h>
#include <linux/list.h>
#include <linux/module.h>
struct regmap_config {
int reg_bits;
int val_bits;
};
typedef int (*regmap_hw_write)(struct device *dev, const void *data,
size_t count);
typedef int (*regmap_hw_gather_write)(struct device *dev,
const void *reg, size_t reg_len,
const void *val, size_t val_len);
typedef int (*regmap_hw_read)(struct device *dev,
const void *reg_buf, size_t reg_size,
void *val_buf, size_t val_size);
/**
* Description of a hardware bus for the register map infrastructure.
*
* @list: Internal use.
* @type: Bus type, used to identify bus to be used for a device.
* @write: Write operation.
* @gather_write: Write operation with split register/value, return -ENOTSUPP
* if not implemented on a given device.
* @read: Read operation. Data is returned in the buffer used to transmit
* data.
* @owner: Module with the bus implementation, used to pin the implementation
* in memory.
* @read_flag_mask: Mask to be set in the top byte of the register when doing
* a read.
*/
struct regmap_bus {
struct list_head list;
struct bus_type *type;
regmap_hw_write write;
regmap_hw_gather_write gather_write;
regmap_hw_read read;
struct module *owner;
u8 read_flag_mask;
};
struct regmap *regmap_init(struct device *dev,
const struct regmap_bus *bus,
const struct regmap_config *config);
void regmap_exit(struct regmap *map);
int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
int regmap_raw_write(struct regmap *map, unsigned int reg,
const void *val, size_t val_len);
int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val);
int regmap_raw_read(struct regmap *map, unsigned int reg,
void *val, size_t val_len);
int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
size_t val_count);
int regmap_update_bits(struct regmap *map, unsigned int reg,
unsigned int mask, unsigned int val);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment