Newer
Older
/*
* 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/slab.h>
#include <linux/export.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/rbtree.h>
#define CREATE_TRACE_POINTS
#include <trace/events/regmap.h>
/*
* Sometimes for failures during very early init the trace
* infrastructure isn't available early enough to be used. For this
* sort of problem defining LOG_DEVICE will add printks for basic
* register I/O on a specific device.
*/
#undef LOG_DEVICE
static int _regmap_update_bits(struct regmap *map, unsigned int reg,
unsigned int mask, unsigned int val,
bool *change);
bool regmap_writeable(struct regmap *map, unsigned int reg)
{
if (map->max_register && reg > map->max_register)
return false;
if (map->writeable_reg)
return map->writeable_reg(map->dev, reg);
return true;
}
bool regmap_readable(struct regmap *map, unsigned int reg)
{
if (map->max_register && reg > map->max_register)
return false;
if (map->format.format_write)
return false;
if (map->readable_reg)
return map->readable_reg(map->dev, reg);
return true;
}
bool regmap_volatile(struct regmap *map, unsigned int reg)
{
if (!regmap_readable(map, reg))
return false;
if (map->volatile_reg)
return map->volatile_reg(map->dev, reg);
return true;
}
bool regmap_precious(struct regmap *map, unsigned int reg)
{
if (!regmap_readable(map, reg))
return false;
if (map->precious_reg)
return map->precious_reg(map->dev, reg);
return false;
}
Lars-Peter Clausen
committed
static bool regmap_volatile_range(struct regmap *map, unsigned int reg,
unsigned int num)
{
unsigned int i;
for (i = 0; i < num; i++)
if (!regmap_volatile(map, reg + i))
return false;
return true;
}
static void regmap_format_2_6_write(struct regmap *map,
unsigned int reg, unsigned int val)
{
u8 *out = map->work_buf;
*out = (reg << 6) | val;
}
static void regmap_format_4_12_write(struct regmap *map,
unsigned int reg, unsigned int val)
{
__be16 *out = map->work_buf;
*out = cpu_to_be16((reg << 12) | val);
}
static void regmap_format_7_9_write(struct regmap *map,
unsigned int reg, unsigned int val)
{
__be16 *out = map->work_buf;
*out = cpu_to_be16((reg << 9) | val);
}
static void regmap_format_10_14_write(struct regmap *map,
unsigned int reg, unsigned int val)
{
u8 *out = map->work_buf;
out[2] = val;
out[1] = (val >> 8) | (reg << 6);
out[0] = reg >> 2;
}
static void regmap_format_8(void *buf, unsigned int val, unsigned int shift)
{
u8 *b = buf;
b[0] = val << shift;
static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift)
{
__be16 *b = buf;
b[0] = cpu_to_be16(val << shift);
static void regmap_format_16_native(void *buf, unsigned int val,
unsigned int shift)
{
*(u16 *)buf = val << shift;
}
static void regmap_format_24(void *buf, unsigned int val, unsigned int shift)
val <<= shift;
b[0] = val >> 16;
b[1] = val >> 8;
b[2] = val;
}
static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift)
{
__be32 *b = buf;
b[0] = cpu_to_be32(val << shift);
static void regmap_format_32_native(void *buf, unsigned int val,
unsigned int shift)
{
*(u32 *)buf = val << shift;
}
static unsigned int regmap_parse_8(void *buf)
{
u8 *b = buf;
return b[0];
}
static unsigned int regmap_parse_16_be(void *buf)
{
__be16 *b = buf;
b[0] = be16_to_cpu(b[0]);
return b[0];
}
static unsigned int regmap_parse_16_native(void *buf)
{
return *(u16 *)buf;
}
static unsigned int regmap_parse_24(void *buf)
{
u8 *b = buf;
unsigned int ret = b[2];
ret |= ((unsigned int)b[1]) << 8;
ret |= ((unsigned int)b[0]) << 16;
return ret;
Loading
Loading full blame...