···110110 int (*reg_write)(void *context, unsigned int reg, unsigned int val);111111 int (*reg_update_bits)(void *context, unsigned int reg,112112 unsigned int mask, unsigned int val);113113+ /* Bulk read/write */114114+ int (*read)(void *context, const void *reg_buf, size_t reg_size,115115+ void *val_buf, size_t val_size);116116+ int (*write)(void *context, const void *data, size_t count);113117114118 bool defer_caching;115119
+40-36
drivers/base/regmap/regmap.c
···838838 map->reg_stride_order = ilog2(map->reg_stride);839839 else840840 map->reg_stride_order = -1;841841- map->use_single_read = config->use_single_read || !bus || !bus->read;842842- map->use_single_write = config->use_single_write || !bus || !bus->write;843843- map->can_multi_write = config->can_multi_write && bus && bus->write;841841+ map->use_single_read = config->use_single_read || !(config->read || (bus && bus->read));842842+ map->use_single_write = config->use_single_write || !(config->write || (bus && bus->write));843843+ map->can_multi_write = config->can_multi_write && (config->write || (bus && bus->write));844844 if (bus) {845845 map->max_raw_read = bus->max_raw_read;846846 map->max_raw_write = bus->max_raw_write;847847+ } else if (config->max_raw_read && config->max_raw_write) {848848+ map->max_raw_read = config->max_raw_read;849849+ map->max_raw_write = config->max_raw_write;847850 }848851 map->dev = dev;849852 map->bus = bus;···880877 map->read_flag_mask = bus->read_flag_mask;881878 }882879883883- if (!bus) {880880+ if (config && config->read && config->write) {881881+ map->reg_read = _regmap_bus_read;882882+883883+ /* Bulk read/write */884884+ map->read = config->read;885885+ map->write = config->write;886886+887887+ reg_endian = REGMAP_ENDIAN_NATIVE;888888+ val_endian = REGMAP_ENDIAN_NATIVE;889889+ } else if (!bus) {884890 map->reg_read = config->reg_read;885891 map->reg_write = config->reg_write;886892 map->reg_update_bits = config->reg_update_bits;···906894 } else {907895 map->reg_read = _regmap_bus_read;908896 map->reg_update_bits = bus->reg_update_bits;909909- }897897+ /* Bulk read/write */898898+ map->read = bus->read;899899+ map->write = bus->write;910900911911- reg_endian = regmap_get_reg_endian(bus, config);912912- val_endian = regmap_get_val_endian(dev, bus, config);901901+ reg_endian = regmap_get_reg_endian(bus, config);902902+ val_endian = regmap_get_val_endian(dev, bus, config);903903+ }913904914905 switch (config->reg_bits + map->reg_shift) {915906 case 2:···16861671 size_t len;16871672 int i;1688167316891689- WARN_ON(!map->bus);16901690-16911674 /* Check for unwritable or noinc registers in range16921675 * before we start16931676 */···17671754 val = work_val;17681755 }1769175617701770- if (map->async && map->bus->async_write) {17571757+ if (map->async && map->bus && map->bus->async_write) {17711758 struct regmap_async *async;1772175917731760 trace_regmap_async_write_start(map, reg, val_len);···18351822 * write.18361823 */18371824 if (val == work_val)18381838- ret = map->bus->write(map->bus_context, map->work_buf,18391839- map->format.reg_bytes +18401840- map->format.pad_bytes +18411841- val_len);18251825+ ret = map->write(map->bus_context, map->work_buf,18261826+ map->format.reg_bytes +18271827+ map->format.pad_bytes +18281828+ val_len);18421829 else if (map->bus->gather_write)18431830 ret = map->bus->gather_write(map->bus_context, map->work_buf,18441831 map->format.reg_bytes +···18571844 memcpy(buf, map->work_buf, map->format.reg_bytes);18581845 memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,18591846 val, val_len);18601860- ret = map->bus->write(map->bus_context, buf, len);18471847+ ret = map->write(map->bus_context, buf, len);1861184818621849 kfree(buf);18631850 } else if (ret != 0 && !map->cache_bypass && map->format.parse_val) {···19141901 struct regmap_range_node *range;19151902 struct regmap *map = context;1916190319171917- WARN_ON(!map->bus || !map->format.format_write);19041904+ WARN_ON(!map->format.format_write);1918190519191906 range = _regmap_range_lookup(map, reg);19201907 if (range) {···1929191619301917 trace_regmap_hw_write_start(map, reg, 1);1931191819321932- ret = map->bus->write(map->bus_context, map->work_buf,19331933- map->format.buf_size);19191919+ ret = map->write(map->bus_context, map->work_buf, map->format.buf_size);1934192019351921 trace_regmap_hw_write_done(map, reg, 1);19361922···19491937{19501938 struct regmap *map = context;1951193919521952- WARN_ON(!map->bus || !map->format.format_val);19401940+ WARN_ON(!map->format.format_val);1953194119541942 map->format.format_val(map->work_buf + map->format.reg_bytes19551943 + map->format.pad_bytes, val, 0);···1963195119641952static inline void *_regmap_map_get_context(struct regmap *map)19651953{19661966- return (map->bus) ? map : map->bus_context;19541954+ return (map->bus || (!map->bus && map->read)) ? map : map->bus_context;19671955}1968195619691957int _regmap_write(struct regmap *map, unsigned int reg,···23752363 u8 = buf;23762364 *u8 |= map->write_flag_mask;2377236523782378- ret = map->bus->write(map->bus_context, buf, len);23662366+ ret = map->write(map->bus_context, buf, len);2379236723802368 kfree(buf);23812369···26812669 struct regmap_range_node *range;26822670 int ret;2683267126842684- WARN_ON(!map->bus);26852685-26862686- if (!map->bus || !map->bus->read)26722672+ if (!map->read)26872673 return -EINVAL;2688267426892675 range = _regmap_range_lookup(map, reg);···26992689 map->read_flag_mask);27002690 trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes);2701269127022702- ret = map->bus->read(map->bus_context, map->work_buf,27032703- map->format.reg_bytes + map->format.pad_bytes,27042704- val, val_len);26922692+ ret = map->read(map->bus_context, map->work_buf,26932693+ map->format.reg_bytes + map->format.pad_bytes,26942694+ val, val_len);2705269527062696 trace_regmap_hw_read_done(map, reg, val_len / map->format.val_bytes);27072697···28122802 unsigned int v;28132803 int ret, i;2814280428152815- if (!map->bus)28162816- return -EINVAL;28172805 if (val_len % map->format.val_bytes)28182806 return -EINVAL;28192807 if (!IS_ALIGNED(reg, map->reg_stride))···28262818 size_t chunk_count, chunk_bytes;28272819 size_t chunk_regs = val_count;2828282028292829- if (!map->bus->read) {28212821+ if (!map->read) {28302822 ret = -ENOTSUPP;28312823 goto out;28322824 }···28862878 * @val: Pointer to data buffer28872879 * @val_len: Length of output buffer in bytes.28882880 *28892889- * The regmap API usually assumes that bulk bus read operations will read a28812881+ * The regmap API usually assumes that bulk read operations will read a28902882 * range of registers. Some devices have certain registers for which a read28912883 * operation read will read from an internal FIFO.28922884 *···29042896 size_t read_len;29052897 int ret;2906289829072907- if (!map->bus)29082908- return -EINVAL;29092909- if (!map->bus->read)29102910- return -ENOTSUPP;29112899 if (val_len % map->format.val_bytes)29122900 return -EINVAL;29132901 if (!IS_ALIGNED(reg, map->reg_stride))···30173013 if (val_count == 0)30183014 return -EINVAL;3019301530203020- if (map->bus && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {30163016+ if (map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {30213017 ret = regmap_raw_read(map, reg, val, val_bytes * val_count);30223018 if (ret != 0)30233019 return ret;
+12
include/linux/regmap.h
···299299 * if the function require special handling with lock and reg300300 * handling and the operation cannot be represented as a simple301301 * update_bits operation on a bus such as SPI, I2C, etc.302302+ * @read: Optional callback that if filled will be used to perform all the303303+ * bulk reads from the registers. Data is returned in the buffer used304304+ * to transmit data.305305+ * @write: Same as above for writing.306306+ * @max_raw_read: Max raw read size that can be used on the device.307307+ * @max_raw_write: Max raw write size that can be used on the device.302308 * @fast_io: Register IO is fast. Use a spinlock instead of a mutex303309 * to perform locking. This field is ignored if custom lock/unlock304310 * functions are used (see fields lock/unlock of struct regmap_config).···391385 int (*reg_write)(void *context, unsigned int reg, unsigned int val);392386 int (*reg_update_bits)(void *context, unsigned int reg,393387 unsigned int mask, unsigned int val);388388+ /* Bulk read/write */389389+ int (*read)(void *context, const void *reg_buf, size_t reg_size,390390+ void *val_buf, size_t val_size);391391+ int (*write)(void *context, const void *data, size_t count);392392+ size_t max_raw_read;393393+ size_t max_raw_write;394394395395 bool fast_io;396396