int regmap_bulk_read()

in regmap/regmap.c [2993:3056]


int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
		     size_t val_count)
{
	int ret, i;
	size_t val_bytes = map->format.val_bytes;
	bool vol = regmap_volatile_range(map, reg, val_count);

	if (!IS_ALIGNED(reg, map->reg_stride))
		return -EINVAL;
	if (val_count == 0)
		return -EINVAL;

	if (map->bus && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {
		ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
		if (ret != 0)
			return ret;

		for (i = 0; i < val_count * val_bytes; i += val_bytes)
			map->format.parse_inplace(val + i);
	} else {
#ifdef CONFIG_64BIT
		u64 *u64 = val;
#endif
		u32 *u32 = val;
		u16 *u16 = val;
		u8 *u8 = val;

		map->lock(map->lock_arg);

		for (i = 0; i < val_count; i++) {
			unsigned int ival;

			ret = _regmap_read(map, reg + regmap_get_offset(map, i),
					   &ival);
			if (ret != 0)
				goto out;

			switch (map->format.val_bytes) {
#ifdef CONFIG_64BIT
			case 8:
				u64[i] = ival;
				break;
#endif
			case 4:
				u32[i] = ival;
				break;
			case 2:
				u16[i] = ival;
				break;
			case 1:
				u8[i] = ival;
				break;
			default:
				ret = -EINVAL;
				goto out;
			}
		}

out:
		map->unlock(map->lock_arg);
	}

	return ret;
}