Commit f2783f0e authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'regmap/topic/field' into regmap-next

parents bee54e31 a0102375
...@@ -180,6 +180,9 @@ struct regmap_field { ...@@ -180,6 +180,9 @@ struct regmap_field {
/* lsb */ /* lsb */
unsigned int shift; unsigned int shift;
unsigned int reg; unsigned int reg;
unsigned int id_size;
unsigned int id_offset;
}; };
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
......
...@@ -813,6 +813,8 @@ static void regmap_field_init(struct regmap_field *rm_field, ...@@ -813,6 +813,8 @@ static void regmap_field_init(struct regmap_field *rm_field,
rm_field->reg = reg_field.reg; rm_field->reg = reg_field.reg;
rm_field->shift = reg_field.lsb; rm_field->shift = reg_field.lsb;
rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb); rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
rm_field->id_size = reg_field.id_size;
rm_field->id_offset = reg_field.id_offset;
} }
/** /**
...@@ -1425,6 +1427,74 @@ int regmap_field_write(struct regmap_field *field, unsigned int val) ...@@ -1425,6 +1427,74 @@ int regmap_field_write(struct regmap_field *field, unsigned int val)
} }
EXPORT_SYMBOL_GPL(regmap_field_write); EXPORT_SYMBOL_GPL(regmap_field_write);
/**
* regmap_field_update_bits(): Perform a read/modify/write cycle
* on the register field
*
* @field: Register field to write to
* @mask: Bitmask to change
* @val: Value to be written
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
int regmap_field_update_bits(struct regmap_field *field, unsigned int mask, unsigned int val)
{
mask = (mask << field->shift) & field->mask;
return regmap_update_bits(field->regmap, field->reg,
mask, val << field->shift);
}
EXPORT_SYMBOL_GPL(regmap_field_update_bits);
/**
* regmap_fields_write(): Write a value to a single register field with port ID
*
* @field: Register field to write to
* @id: port ID
* @val: Value to be written
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
int regmap_fields_write(struct regmap_field *field, unsigned int id,
unsigned int val)
{
if (id >= field->id_size)
return -EINVAL;
return regmap_update_bits(field->regmap,
field->reg + (field->id_offset * id),
field->mask, val << field->shift);
}
EXPORT_SYMBOL_GPL(regmap_fields_write);
/**
* regmap_fields_update_bits(): Perform a read/modify/write cycle
* on the register field
*
* @field: Register field to write to
* @id: port ID
* @mask: Bitmask to change
* @val: Value to be written
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
int regmap_fields_update_bits(struct regmap_field *field, unsigned int id,
unsigned int mask, unsigned int val)
{
if (id >= field->id_size)
return -EINVAL;
mask = (mask << field->shift) & field->mask;
return regmap_update_bits(field->regmap,
field->reg + (field->id_offset * id),
mask, val << field->shift);
}
EXPORT_SYMBOL_GPL(regmap_fields_update_bits);
/* /*
* regmap_bulk_write(): Write multiple registers to the device * regmap_bulk_write(): Write multiple registers to the device
* *
...@@ -1735,6 +1805,39 @@ int regmap_field_read(struct regmap_field *field, unsigned int *val) ...@@ -1735,6 +1805,39 @@ int regmap_field_read(struct regmap_field *field, unsigned int *val)
} }
EXPORT_SYMBOL_GPL(regmap_field_read); EXPORT_SYMBOL_GPL(regmap_field_read);
/**
* regmap_fields_read(): Read a value to a single register field with port ID
*
* @field: Register field to read from
* @id: port ID
* @val: Pointer to store read value
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
int regmap_fields_read(struct regmap_field *field, unsigned int id,
unsigned int *val)
{
int ret;
unsigned int reg_val;
if (id >= field->id_size)
return -EINVAL;
ret = regmap_read(field->regmap,
field->reg + (field->id_offset * id),
&reg_val);
if (ret != 0)
return ret;
reg_val &= field->mask;
reg_val >>= field->shift;
*val = reg_val;
return ret;
}
EXPORT_SYMBOL_GPL(regmap_fields_read);
/** /**
* regmap_bulk_read(): Read multiple registers from the device * regmap_bulk_read(): Read multiple registers from the device
* *
......
...@@ -431,11 +431,15 @@ bool regmap_reg_in_ranges(unsigned int reg, ...@@ -431,11 +431,15 @@ bool regmap_reg_in_ranges(unsigned int reg,
* @reg: Offset of the register within the regmap bank * @reg: Offset of the register within the regmap bank
* @lsb: lsb of the register field. * @lsb: lsb of the register field.
* @reg: msb of the register field. * @reg: msb of the register field.
* @id_size: port size if it has some ports
* @id_offset: address offset for each ports
*/ */
struct reg_field { struct reg_field {
unsigned int reg; unsigned int reg;
unsigned int lsb; unsigned int lsb;
unsigned int msb; unsigned int msb;
unsigned int id_size;
unsigned int id_offset;
}; };
#define REG_FIELD(_reg, _lsb, _msb) { \ #define REG_FIELD(_reg, _lsb, _msb) { \
...@@ -454,6 +458,15 @@ void devm_regmap_field_free(struct device *dev, struct regmap_field *field); ...@@ -454,6 +458,15 @@ void devm_regmap_field_free(struct device *dev, struct regmap_field *field);
int regmap_field_read(struct regmap_field *field, unsigned int *val); int regmap_field_read(struct regmap_field *field, unsigned int *val);
int regmap_field_write(struct regmap_field *field, unsigned int val); int regmap_field_write(struct regmap_field *field, unsigned int val);
int regmap_field_update_bits(struct regmap_field *field,
unsigned int mask, unsigned int val);
int regmap_fields_write(struct regmap_field *field, unsigned int id,
unsigned int val);
int regmap_fields_read(struct regmap_field *field, unsigned int id,
unsigned int *val);
int regmap_fields_update_bits(struct regmap_field *field, unsigned int id,
unsigned int mask, unsigned int val);
/** /**
* Description of an IRQ for the generic regmap irq_chip. * Description of an IRQ for the generic regmap irq_chip.
......
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