summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2011-09-05 20:46:32 +0200
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-09-05 14:55:57 -0700
commit6f306441e97f8f9d27c43a536360fe221f675a71 (patch)
tree2b7b74cef26e9e5e4de46dad0862998ac896993f /drivers
parentd813ae9a105219255c07d382059de831186c10d0 (diff)
downloadlinux-stable-6f306441e97f8f9d27c43a536360fe221f675a71.tar.gz
linux-stable-6f306441e97f8f9d27c43a536360fe221f675a71.tar.bz2
linux-stable-6f306441e97f8f9d27c43a536360fe221f675a71.zip
regmap: Add support for device specific write and read flag masks.
Some buses like SPI have no standard notation of read or write operations. The general scheme here is to set or clear specific bits in the register address to indicate whether the operation is a read or write. We already support having a read flag mask per bus, but as there is no standard the bits which need to be set or cleared differ between devices and vendors, thus we need a mechanism to specify them per device. This patch adds two new entries to the regmap_config struct, read_flag_mask and write_flag_mask. These will be or'ed onto the top byte when doing a read or write operation. If both masks are empty the device will fallback to the regmap_bus masks. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/regmap/internal.h3
-rw-r--r--drivers/base/regmap/regmap.c15
2 files changed, 15 insertions, 3 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 5ab3fefa4b05..7e14d5a6f53e 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -46,6 +46,9 @@ struct regmap {
bool (*readable_reg)(struct device *dev, unsigned int reg);
bool (*volatile_reg)(struct device *dev, unsigned int reg);
bool (*precious_reg)(struct device *dev, unsigned int reg);
+
+ u8 read_flag_mask;
+ u8 write_flag_mask;
};
bool regmap_writeable(struct regmap *map, unsigned int reg);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 86b184776199..e7adfe70e425 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -147,6 +147,13 @@ struct regmap *regmap_init(struct device *dev,
map->volatile_reg = config->volatile_reg;
map->precious_reg = config->precious_reg;
+ if (config->read_flag_mask || config->write_flag_mask) {
+ map->read_flag_mask = config->read_flag_mask;
+ map->write_flag_mask = config->write_flag_mask;
+ } else {
+ map->read_flag_mask = bus->read_flag_mask;
+ }
+
switch (config->reg_bits) {
case 4:
switch (config->val_bits) {
@@ -226,6 +233,7 @@ EXPORT_SYMBOL_GPL(regmap_exit);
static int _regmap_raw_write(struct regmap *map, unsigned int reg,
const void *val, size_t val_len)
{
+ u8 *u8 = map->work_buf;
void *buf;
int ret = -ENOTSUPP;
size_t len;
@@ -239,6 +247,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
map->format.format_reg(map->work_buf, reg);
+ u8[0] |= map->write_flag_mask;
+
trace_regmap_hw_write_start(map->dev, reg,
val_len / map->format.val_bytes);
@@ -366,13 +376,12 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
map->format.format_reg(map->work_buf, reg);
/*
- * Some buses flag reads by setting the high bits in the
+ * Some buses or devices flag reads by setting the high bits in the
* register addresss; since it's always the high bits for all
* current formats we can do this here rather than in
* formatting. This may break if we get interesting formats.
*/
- if (map->bus->read_flag_mask)
- u8[0] |= map->bus->read_flag_mask;
+ u8[0] |= map->read_flag_mask;
trace_regmap_hw_read_start(map->dev, reg,
val_len / map->format.val_bytes);