diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-02-12 09:19:43 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-02-14 17:03:32 -0500 |
commit | 8eaeb21925563075ae036c2e5ba8d041b70e18fa (patch) | |
tree | 165075722500d35cd6c6b459d2be638e491df718 /drivers/base | |
parent | c9157198417076c0c2664ba997e7b0217f61fcce (diff) |
regmap: add regmap_bulk_write() for register write
The bulk_write() supports the data transfer to multi
register which takes the data into cpu_endianness format
and does formatting of data to device format before
sending to device.
The transfer can be completed in single transfer or multiple
transfer based on data formatting.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/regmap/regmap.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 74a6d4f8e3b8..2366b6299f07 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c | |||
@@ -473,6 +473,56 @@ int regmap_raw_write(struct regmap *map, unsigned int reg, | |||
473 | } | 473 | } |
474 | EXPORT_SYMBOL_GPL(regmap_raw_write); | 474 | EXPORT_SYMBOL_GPL(regmap_raw_write); |
475 | 475 | ||
476 | /* | ||
477 | * regmap_bulk_write(): Write multiple registers to the device | ||
478 | * | ||
479 | * @map: Register map to write to | ||
480 | * @reg: First register to be write from | ||
481 | * @val: Block of data to be written, in native register size for device | ||
482 | * @val_count: Number of registers to write | ||
483 | * | ||
484 | * This function is intended to be used for writing a large block of | ||
485 | * data to be device either in single transfer or multiple transfer. | ||
486 | * | ||
487 | * A value of zero will be returned on success, a negative errno will | ||
488 | * be returned in error cases. | ||
489 | */ | ||
490 | int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, | ||
491 | size_t val_count) | ||
492 | { | ||
493 | int ret = 0, i; | ||
494 | size_t val_bytes = map->format.val_bytes; | ||
495 | void *wval; | ||
496 | |||
497 | if (!map->format.parse_val) | ||
498 | return -EINVAL; | ||
499 | |||
500 | mutex_lock(&map->lock); | ||
501 | |||
502 | /* No formatting is require if val_byte is 1 */ | ||
503 | if (val_bytes == 1) { | ||
504 | wval = (void *)val; | ||
505 | } else { | ||
506 | wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL); | ||
507 | if (!wval) { | ||
508 | ret = -ENOMEM; | ||
509 | dev_err(map->dev, "Error in memory allocation\n"); | ||
510 | goto out; | ||
511 | } | ||
512 | for (i = 0; i < val_count * val_bytes; i += val_bytes) | ||
513 | map->format.parse_val(wval + i); | ||
514 | } | ||
515 | ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); | ||
516 | |||
517 | if (val_bytes != 1) | ||
518 | kfree(wval); | ||
519 | |||
520 | out: | ||
521 | mutex_unlock(&map->lock); | ||
522 | return ret; | ||
523 | } | ||
524 | EXPORT_SYMBOL_GPL(regmap_bulk_write); | ||
525 | |||
476 | static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, | 526 | static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, |
477 | unsigned int val_len) | 527 | unsigned int val_len) |
478 | { | 528 | { |