*参照元 [#ld3a9dc2] #backlinks *説明 [#u7f6ece0] -パス: 複数あり --CONFIG_REGMAP 有効: [[linux-4.4.1/drivers/base/regmap/regmap.c]] --CONFIG_REGMAP 無効: [[linux-4.4.1/include/linux/regmap.h]] -FIXME: これは何? --説明 **引数 [#k5c6efd0] -struct regmap *map -- --[[linux-4.4.1/regmap]] -unsigned int reg -- -const void *val -- -size_t val_count -- **返り値 [#m6be09c9] -int -- **参考 [#s37a4ad7] *実装 [#ed39fd67] **CONFIG_REGMAP 有効: drivers/base/regmap/regmap.c [#he618773] /* * regmap_bulk_write(): Write multiple registers to the device * * @map: Register map to write to * @reg: First register to be write from * @val: Block of data to be written, in native register size for device * @val_count: Number of registers to write * * This function is intended to be used for writing a large block of * data to the device either in single transfer or multiple transfer. * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ 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; size_t total_size = val_bytes * val_count; if (map->bus && !map->format.parse_inplace) return -EINVAL; if (reg % map->reg_stride) return -EINVAL; - --map->format は struct regmap_format 型 --[[linux-4.4.1/regmap_format]] /* * Some devices don't support bulk write, for * them we have a series of single write operations in the first two if * blocks. * * The first if block is used for memory mapped io. It does not allow * val_bytes of 3 for example. * The second one is used for busses which do not have this limitation * and can write arbitrary value lengths. */ if (!map->bus) { 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 - --[[linux-4.4.1/CONFIG_64BIT]] case 8: ival = *(u64 *)(val + (i * val_bytes)); break; #endif default: ret = -EINVAL; goto out; } ret = _regmap_write(map, reg + (i * map->reg_stride), ival); if (ret != 0) goto out; - --[[linux-4.4.1/_regmap_write()]] } out: map->unlock(map->lock_arg); } else if (map->use_single_write || (map->max_raw_write && map->max_raw_write < total_size)) { int chunk_stride = map->reg_stride; size_t chunk_size = val_bytes; size_t chunk_count = val_count; if (!map->use_single_write) { chunk_size = map->max_raw_write; if (chunk_size % val_bytes) chunk_size -= chunk_size % val_bytes; chunk_count = total_size / chunk_size; chunk_stride *= chunk_size / val_bytes; } map->lock(map->lock_arg); /* Write as many bytes as possible with chunk_size */ for (i = 0; i < chunk_count; i++) { ret = _regmap_raw_write(map, reg + (i * chunk_stride), val + (i * chunk_size), chunk_size); if (ret) break; - --[[linux-4.4.1/_regmap_raw_write()]] } /* Write remaining bytes */ if (!ret && chunk_size * i < total_size) { ret = _regmap_raw_write(map, reg + (i * chunk_stride), val + (i * chunk_size), total_size - i * chunk_size); } map->unlock(map->lock_arg); } else { void *wval; if (!val_count) return -EINVAL; wval = kmemdup(val, val_count * val_bytes, map->alloc_flags); if (!wval) { dev_err(map->dev, "Error in memory allocation\n"); return -ENOMEM; } for (i = 0; i < val_count * val_bytes; i += val_bytes) map->format.parse_inplace(wval + i); - --[[linux-4.4.1/kmemdup()]] --map->format は struct regmap_format 型 --[[linux-4.4.1/regmap_format]] map->lock(map->lock_arg); ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); map->unlock(map->lock_arg); kfree(wval); - --[[linux-4.4.1/kfree()]] } return ret; } EXPORT_SYMBOL_GPL(regmap_bulk_write); -GPL ライセンスのモジュールにのみシンボルを公開する。 --[[linux-4.4.1/EXPORT_SYMBOL_GPL()]] **CONFIG_REGMAP 無効: include/linux/regmap.h [#x3a87025] static inline int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, size_t val_count) { WARN_ONCE(1, "regmap API is disabled"); - --[[linux-4.4.1/WARN_ONCE()]] return -EINVAL; } *コメント [#b142b58a]