Commit f381f906 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull regmap updates from Mark Brown:
 "A very quiet release for regmap this time around:

   - Fix an endianness issue for I2C devices connected via SMBus where
     we were getting two layers both trying to do endianness handling.
   - Use a union to reduce the size of the regmap struct.
   - A couple of smaller fixes"

* tag 'regmap-v3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
  regmap: Fix i2c word access when using SMBus access functions
  regmap: Export regmap_get_val_endian
  regmap: ac97: Clean up indentation
  regmap: correct the description of structure element in reg_field
  regmap: Move spinlock_flags into the union
parents 5c30c3cc 1aff0310
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -51,9 +51,11 @@ struct regmap_async {
struct regmap {
	union {
		struct mutex mutex;
		struct {
			spinlock_t spinlock;
	};
			unsigned long spinlock_flags;
		};
	};
	regmap_lock lock;
	regmap_unlock unlock;
	void *lock_arg; /* This is passed to lock/unlock functions */
@@ -233,6 +235,10 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,

void regmap_async_complete_cb(struct regmap_async *async, int ret);

enum regmap_endian regmap_get_val_endian(struct device *dev,
					 const struct regmap_bus *bus,
					 const struct regmap_config *config);

extern struct regcache_ops regcache_rbtree_ops;
extern struct regcache_ops regcache_lzo_ops;
extern struct regcache_ops regcache_flat_ops;
+45 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/i2c.h>
#include <linux/module.h>

#include "internal.h"

static int regmap_smbus_byte_reg_read(void *context, unsigned int reg,
				      unsigned int *val)
@@ -87,6 +88,42 @@ static struct regmap_bus regmap_smbus_word = {
	.reg_read = regmap_smbus_word_reg_read,
};

static int regmap_smbus_word_read_swapped(void *context, unsigned int reg,
					  unsigned int *val)
{
	struct device *dev = context;
	struct i2c_client *i2c = to_i2c_client(dev);
	int ret;

	if (reg > 0xff)
		return -EINVAL;

	ret = i2c_smbus_read_word_swapped(i2c, reg);
	if (ret < 0)
		return ret;

	*val = ret;

	return 0;
}

static int regmap_smbus_word_write_swapped(void *context, unsigned int reg,
					   unsigned int val)
{
	struct device *dev = context;
	struct i2c_client *i2c = to_i2c_client(dev);

	if (val > 0xffff || reg > 0xff)
		return -EINVAL;

	return i2c_smbus_write_word_swapped(i2c, reg, val);
}

static struct regmap_bus regmap_smbus_word_swapped = {
	.reg_write = regmap_smbus_word_write_swapped,
	.reg_read = regmap_smbus_word_read_swapped,
};

static int regmap_i2c_write(void *context, const void *data, size_t count)
{
	struct device *dev = context;
@@ -180,7 +217,14 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
	else if (config->val_bits == 16 && config->reg_bits == 8 &&
		 i2c_check_functionality(i2c->adapter,
					 I2C_FUNC_SMBUS_WORD_DATA))
		switch (regmap_get_val_endian(&i2c->dev, NULL, config)) {
		case REGMAP_ENDIAN_LITTLE:
			return &regmap_smbus_word;
		case REGMAP_ENDIAN_BIG:
			return &regmap_smbus_word_swapped;
		default:		/* everything else is not supported */
			break;
		}
	else if (config->val_bits == 8 && config->reg_bits == 8 &&
		 i2c_check_functionality(i2c->adapter,
					 I2C_FUNC_SMBUS_BYTE_DATA))
+4 −3
Original line number Diff line number Diff line
@@ -473,7 +473,7 @@ static enum regmap_endian regmap_get_reg_endian(const struct regmap_bus *bus,
	return REGMAP_ENDIAN_BIG;
}

static enum regmap_endian regmap_get_val_endian(struct device *dev,
enum regmap_endian regmap_get_val_endian(struct device *dev,
					 const struct regmap_bus *bus,
					 const struct regmap_config *config)
{
@@ -513,6 +513,7 @@ static enum regmap_endian regmap_get_val_endian(struct device *dev,
	/* Use this if no other value was found */
	return REGMAP_ENDIAN_BIG;
}
EXPORT_SYMBOL_GPL(regmap_get_val_endian);

/**
 * regmap_init(): Initialise register map
+1 −1
Original line number Diff line number Diff line
@@ -468,7 +468,7 @@ bool regmap_reg_in_ranges(unsigned int reg,
 *
 * @reg: Offset of the register within the regmap bank
 * @lsb: lsb of the register field.
 * @reg: msb of the register field.
 * @msb: msb of the register field.
 * @id_size: port size if it has some ports
 * @id_offset: address offset for each ports
 */
+2 −2

File changed.

Contains only whitespace changes.