diff options
author | Mark Brown <broonie@linaro.org> | 2013-10-28 16:01:33 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-10-28 16:01:33 -0400 |
commit | f2783f0e9cac215df5b7ee0a903adfeabde90b24 (patch) | |
tree | 5635cba8b9e97467326531caf0d3a4ba46abe038 | |
parent | bee54e310e579c8760bc4e8215853c625d8c7895 (diff) | |
parent | a0102375ee82db1e08324b1a21484854cf2c1677 (diff) |
Merge remote-tracking branch 'regmap/topic/field' into regmap-next
-rw-r--r-- | drivers/base/regmap/internal.h | 3 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 103 | ||||
-rw-r--r-- | include/linux/regmap.h | 13 |
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 | } |
1426 | EXPORT_SYMBOL_GPL(regmap_field_write); | 1428 | EXPORT_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 | */ | ||
1441 | int 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 | } | ||
1448 | EXPORT_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 | */ | ||
1460 | int 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 | } | ||
1470 | EXPORT_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 | */ | ||
1484 | int 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 | } | ||
1496 | EXPORT_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) | |||
1736 | EXPORT_SYMBOL_GPL(regmap_field_read); | 1806 | EXPORT_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 | */ | ||
1818 | int 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 | ®_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 | } | ||
1839 | EXPORT_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 | */ |
435 | struct reg_field { | 437 | struct 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 | ||
455 | int regmap_field_read(struct regmap_field *field, unsigned int *val); | 459 | int regmap_field_read(struct regmap_field *field, unsigned int *val); |
456 | int regmap_field_write(struct regmap_field *field, unsigned int val); | 460 | int regmap_field_write(struct regmap_field *field, unsigned int val); |
461 | int regmap_field_update_bits(struct regmap_field *field, | ||
462 | unsigned int mask, unsigned int val); | ||
463 | |||
464 | int regmap_fields_write(struct regmap_field *field, unsigned int id, | ||
465 | unsigned int val); | ||
466 | int regmap_fields_read(struct regmap_field *field, unsigned int id, | ||
467 | unsigned int *val); | ||
468 | int 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. |