diff options
| author | Anthony Olech <anthony.olech.opensource@diasemi.com> | 2013-10-11 10:31:11 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@linaro.org> | 2013-10-14 10:09:16 -0400 |
| commit | e33fabd365596178e72f62bb4b89f0aaad0509ad (patch) | |
| tree | 6c0aad1f15bc40d0596cd4678658ad51022029fc | |
| parent | 61e6cfa80de5760bbe406f4e815b7739205754d2 (diff) | |
regmap: new API regmap_multi_reg_write() definition
New API regmap_multi_reg_write() is defined that allows a set of reg,val
pairs to be written to a I2C client device as one block transfer from the
point of view of a single I2C master system.
A simple demonstration implementation is included that just splits the
block write request into a sequence of single register writes.
The implementation will be modified later to support those I2C clients
that implement the alternative non-standard MULTIWRITE block write mode
so to achieve a single I2C transfer that will be atomic even in multiple
I2C master systems.
Signed-off-by: Anthony Olech <anthony.olech.opensource@diasemi.com>
Signed-off-by: David Dajun Chen <david.chen@diasemi.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
| -rw-r--r-- | drivers/base/regmap/regmap.c | 41 | ||||
| -rw-r--r-- | include/linux/regmap.h | 2 |
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 7d689a15c500..c42ad69e527f 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
| @@ -1439,6 +1439,47 @@ out: | |||
| 1439 | } | 1439 | } |
| 1440 | EXPORT_SYMBOL_GPL(regmap_bulk_write); | 1440 | EXPORT_SYMBOL_GPL(regmap_bulk_write); |
| 1441 | 1441 | ||
| 1442 | /* | ||
| 1443 | * regmap_multi_reg_write(): Write multiple registers to the device | ||
| 1444 | * | ||
| 1445 | * where the set of register are supplied in any order | ||
| 1446 | * | ||
| 1447 | * @map: Register map to write to | ||
| 1448 | * @regs: Array of structures containing register,value to be written | ||
| 1449 | * @num_regs: Number of registers to write | ||
| 1450 | * | ||
| 1451 | * This function is intended to be used for writing a large block of data | ||
| 1452 | * atomically to the device in single transfer for those I2C client devices | ||
| 1453 | * that implement this alternative block write mode. | ||
| 1454 | * | ||
| 1455 | * A value of zero will be returned on success, a negative errno will | ||
| 1456 | * be returned in error cases. | ||
| 1457 | */ | ||
| 1458 | int regmap_multi_reg_write(struct regmap *map, struct reg_default *regs, | ||
| 1459 | int num_regs) | ||
| 1460 | { | ||
| 1461 | int ret = 0, i; | ||
| 1462 | |||
| 1463 | for (i = 0; i < num_regs; i++) { | ||
| 1464 | int reg = regs[i].reg; | ||
| 1465 | if (reg % map->reg_stride) | ||
| 1466 | return -EINVAL; | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | map->lock(map->lock_arg); | ||
| 1470 | |||
| 1471 | for (i = 0; i < num_regs; i++) { | ||
| 1472 | ret = _regmap_write(map, regs[i].reg, regs[i].def); | ||
| 1473 | if (ret != 0) | ||
| 1474 | goto out; | ||
| 1475 | } | ||
| 1476 | out: | ||
| 1477 | map->unlock(map->lock_arg); | ||
| 1478 | |||
| 1479 | return ret; | ||
| 1480 | } | ||
| 1481 | EXPORT_SYMBOL_GPL(regmap_multi_reg_write); | ||
| 1482 | |||
| 1442 | /** | 1483 | /** |
| 1443 | * regmap_raw_write_async(): Write raw values to one or more registers | 1484 | * regmap_raw_write_async(): Write raw values to one or more registers |
| 1444 | * asynchronously | 1485 | * asynchronously |
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index a10380bfbeac..4b933a31f84f 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
| @@ -378,6 +378,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg, | |||
| 378 | const void *val, size_t val_len); | 378 | const void *val, size_t val_len); |
| 379 | int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, | 379 | int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, |
| 380 | size_t val_count); | 380 | size_t val_count); |
| 381 | int regmap_multi_reg_write(struct regmap *map, struct reg_default *regs, | ||
| 382 | int num_regs); | ||
| 381 | int regmap_raw_write_async(struct regmap *map, unsigned int reg, | 383 | int regmap_raw_write_async(struct regmap *map, unsigned int reg, |
| 382 | const void *val, size_t val_len); | 384 | const void *val, size_t val_len); |
| 383 | int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val); | 385 | int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val); |
