aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-10-28 16:01:33 -0400
committerMark Brown <broonie@linaro.org>2013-10-28 16:01:33 -0400
commitf2783f0e9cac215df5b7ee0a903adfeabde90b24 (patch)
tree5635cba8b9e97467326531caf0d3a4ba46abe038
parentbee54e310e579c8760bc4e8215853c625d8c7895 (diff)
parenta0102375ee82db1e08324b1a21484854cf2c1677 (diff)
Merge remote-tracking branch 'regmap/topic/field' into regmap-next
-rw-r--r--drivers/base/regmap/internal.h3
-rw-r--r--drivers/base/regmap/regmap.c103
-rw-r--r--include/linux/regmap.h13
3 files changed, 119 insertions, 0 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 6873b4ce03f9..33414b1de201 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -180,6 +180,9 @@ struct regmap_field {
180 /* lsb */ 180 /* lsb */
181 unsigned int shift; 181 unsigned int shift;
182 unsigned int reg; 182 unsigned int reg;
183
184 unsigned int id_size;
185 unsigned int id_offset;
183}; 186};
184 187
185#ifdef CONFIG_DEBUG_FS 188#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index d0ce2fef43a3..c7111d0d16fb 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -813,6 +813,8 @@ static void regmap_field_init(struct regmap_field *rm_field,
813 rm_field->reg = reg_field.reg; 813 rm_field->reg = reg_field.reg;
814 rm_field->shift = reg_field.lsb; 814 rm_field->shift = reg_field.lsb;
815 rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb); 815 rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
816 rm_field->id_size = reg_field.id_size;
817 rm_field->id_offset = reg_field.id_offset;
816} 818}
817 819
818/** 820/**
@@ -1425,6 +1427,74 @@ int regmap_field_write(struct regmap_field *field, unsigned int val)
1425} 1427}
1426EXPORT_SYMBOL_GPL(regmap_field_write); 1428EXPORT_SYMBOL_GPL(regmap_field_write);
1427 1429
1430/**
1431 * regmap_field_update_bits(): Perform a read/modify/write cycle
1432 * on the register field
1433 *
1434 * @field: Register field to write to
1435 * @mask: Bitmask to change
1436 * @val: Value to be written
1437 *
1438 * A value of zero will be returned on success, a negative errno will
1439 * be returned in error cases.
1440 */
1441int regmap_field_update_bits(struct regmap_field *field, unsigned int mask, unsigned int val)
1442{
1443 mask = (mask << field->shift) & field->mask;
1444
1445 return regmap_update_bits(field->regmap, field->reg,
1446 mask, val << field->shift);
1447}
1448EXPORT_SYMBOL_GPL(regmap_field_update_bits);
1449
1450/**
1451 * regmap_fields_write(): Write a value to a single register field with port ID
1452 *
1453 * @field: Register field to write to
1454 * @id: port ID
1455 * @val: Value to be written
1456 *
1457 * A value of zero will be returned on success, a negative errno will
1458 * be returned in error cases.
1459 */
1460int regmap_fields_write(struct regmap_field *field, unsigned int id,
1461 unsigned int val)
1462{
1463 if (id >= field->id_size)
1464 return -EINVAL;
1465
1466 return regmap_update_bits(field->regmap,
1467 field->reg + (field->id_offset * id),
1468 field->mask, val << field->shift);
1469}
1470EXPORT_SYMBOL_GPL(regmap_fields_write);
1471
1472/**
1473 * regmap_fields_update_bits(): Perform a read/modify/write cycle
1474 * on the register field
1475 *
1476 * @field: Register field to write to
1477 * @id: port ID
1478 * @mask: Bitmask to change
1479 * @val: Value to be written
1480 *
1481 * A value of zero will be returned on success, a negative errno will
1482 * be returned in error cases.
1483 */
1484int regmap_fields_update_bits(struct regmap_field *field, unsigned int id,
1485 unsigned int mask, unsigned int val)
1486{
1487 if (id >= field->id_size)
1488 return -EINVAL;
1489
1490 mask = (mask << field->shift) & field->mask;
1491
1492 return regmap_update_bits(field->regmap,
1493 field->reg + (field->id_offset * id),
1494 mask, val << field->shift);
1495}
1496EXPORT_SYMBOL_GPL(regmap_fields_update_bits);
1497
1428/* 1498/*
1429 * regmap_bulk_write(): Write multiple registers to the device 1499 * regmap_bulk_write(): Write multiple registers to the device
1430 * 1500 *
@@ -1736,6 +1806,39 @@ int regmap_field_read(struct regmap_field *field, unsigned int *val)
1736EXPORT_SYMBOL_GPL(regmap_field_read); 1806EXPORT_SYMBOL_GPL(regmap_field_read);
1737 1807
1738/** 1808/**
1809 * regmap_fields_read(): Read a value to a single register field with port ID
1810 *
1811 * @field: Register field to read from
1812 * @id: port ID
1813 * @val: Pointer to store read value
1814 *
1815 * A value of zero will be returned on success, a negative errno will
1816 * be returned in error cases.
1817 */
1818int regmap_fields_read(struct regmap_field *field, unsigned int id,
1819 unsigned int *val)
1820{
1821 int ret;
1822 unsigned int reg_val;
1823
1824 if (id >= field->id_size)
1825 return -EINVAL;
1826
1827 ret = regmap_read(field->regmap,
1828 field->reg + (field->id_offset * id),
1829 &reg_val);
1830 if (ret != 0)
1831 return ret;
1832
1833 reg_val &= field->mask;
1834 reg_val >>= field->shift;
1835 *val = reg_val;
1836
1837 return ret;
1838}
1839EXPORT_SYMBOL_GPL(regmap_fields_read);
1840
1841/**
1739 * regmap_bulk_read(): Read multiple registers from the device 1842 * regmap_bulk_read(): Read multiple registers from the device
1740 * 1843 *
1741 * @map: Register map to write to 1844 * @map: Register map to write to
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 114565befbd2..dc90b8c134a1 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -431,11 +431,15 @@ bool regmap_reg_in_ranges(unsigned int reg,
431 * @reg: Offset of the register within the regmap bank 431 * @reg: Offset of the register within the regmap bank
432 * @lsb: lsb of the register field. 432 * @lsb: lsb of the register field.
433 * @reg: msb of the register field. 433 * @reg: msb of the register field.
434 * @id_size: port size if it has some ports
435 * @id_offset: address offset for each ports
434 */ 436 */
435struct reg_field { 437struct reg_field {
436 unsigned int reg; 438 unsigned int reg;
437 unsigned int lsb; 439 unsigned int lsb;
438 unsigned int msb; 440 unsigned int msb;
441 unsigned int id_size;
442 unsigned int id_offset;
439}; 443};
440 444
441#define REG_FIELD(_reg, _lsb, _msb) { \ 445#define REG_FIELD(_reg, _lsb, _msb) { \
@@ -454,6 +458,15 @@ void devm_regmap_field_free(struct device *dev, struct regmap_field *field);
454 458
455int regmap_field_read(struct regmap_field *field, unsigned int *val); 459int regmap_field_read(struct regmap_field *field, unsigned int *val);
456int regmap_field_write(struct regmap_field *field, unsigned int val); 460int regmap_field_write(struct regmap_field *field, unsigned int val);
461int regmap_field_update_bits(struct regmap_field *field,
462 unsigned int mask, unsigned int val);
463
464int regmap_fields_write(struct regmap_field *field, unsigned int id,
465 unsigned int val);
466int regmap_fields_read(struct regmap_field *field, unsigned int id,
467 unsigned int *val);
468int regmap_fields_update_bits(struct regmap_field *field, unsigned int id,
469 unsigned int mask, unsigned int val);
457 470
458/** 471/**
459 * Description of an IRQ for the generic regmap irq_chip. 472 * Description of an IRQ for the generic regmap irq_chip.