in regmap/regmap.c [2249:2310]
int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
size_t val_count)
{
int ret = 0, i;
size_t val_bytes = map->format.val_bytes;
if (!IS_ALIGNED(reg, map->reg_stride))
return -EINVAL;
/*
* Some devices don't support bulk write, for them we have a series of
* single write operations.
*/
if (!map->bus || !map->format.parse_inplace) {
map->lock(map->lock_arg);
for (i = 0; i < val_count; i++) {
unsigned int ival;
switch (val_bytes) {
case 1:
ival = *(u8 *)(val + (i * val_bytes));
break;
case 2:
ival = *(u16 *)(val + (i * val_bytes));
break;
case 4:
ival = *(u32 *)(val + (i * val_bytes));
break;
#ifdef CONFIG_64BIT
case 8:
ival = *(u64 *)(val + (i * val_bytes));
break;
#endif
default:
ret = -EINVAL;
goto out;
}
ret = _regmap_write(map,
reg + regmap_get_offset(map, i),
ival);
if (ret != 0)
goto out;
}
out:
map->unlock(map->lock_arg);
} else {
void *wval;
wval = kmemdup(val, val_count * val_bytes, map->alloc_flags);
if (!wval)
return -ENOMEM;
for (i = 0; i < val_count * val_bytes; i += val_bytes)
map->format.parse_inplace(wval + i);
ret = regmap_raw_write(map, reg, wval, val_bytes * val_count);
kfree(wval);
}
return ret;
}