Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */ 2 : : /* 3 : : * Register map access API internal header 4 : : * 5 : : * Copyright 2011 Wolfson Microelectronics plc 6 : : * 7 : : * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 8 : : */ 9 : : 10 : : #ifndef _REGMAP_INTERNAL_H 11 : : #define _REGMAP_INTERNAL_H 12 : : 13 : : #include <linux/device.h> 14 : : #include <linux/regmap.h> 15 : : #include <linux/fs.h> 16 : : #include <linux/list.h> 17 : : #include <linux/wait.h> 18 : : 19 : : struct regmap; 20 : : struct regcache_ops; 21 : : 22 : : struct regmap_debugfs_off_cache { 23 : : struct list_head list; 24 : : off_t min; 25 : : off_t max; 26 : : unsigned int base_reg; 27 : : unsigned int max_reg; 28 : : }; 29 : : 30 : : struct regmap_format { 31 : : size_t buf_size; 32 : : size_t reg_bytes; 33 : : size_t pad_bytes; 34 : : size_t val_bytes; 35 : : void (*format_write)(struct regmap *map, 36 : : unsigned int reg, unsigned int val); 37 : : void (*format_reg)(void *buf, unsigned int reg, unsigned int shift); 38 : : void (*format_val)(void *buf, unsigned int val, unsigned int shift); 39 : : unsigned int (*parse_val)(const void *buf); 40 : : void (*parse_inplace)(void *buf); 41 : : }; 42 : : 43 : : struct regmap_async { 44 : : struct list_head list; 45 : : struct regmap *map; 46 : : void *work_buf; 47 : : }; 48 : : 49 : : struct regmap { 50 : : union { 51 : : struct mutex mutex; 52 : : struct { 53 : : spinlock_t spinlock; 54 : : unsigned long spinlock_flags; 55 : : }; 56 : : }; 57 : : regmap_lock lock; 58 : : regmap_unlock unlock; 59 : : void *lock_arg; /* This is passed to lock/unlock functions */ 60 : : gfp_t alloc_flags; 61 : : 62 : : struct device *dev; /* Device we do I/O on */ 63 : : void *work_buf; /* Scratch buffer used to format I/O */ 64 : : struct regmap_format format; /* Buffer format */ 65 : : const struct regmap_bus *bus; 66 : : void *bus_context; 67 : : const char *name; 68 : : 69 : : bool async; 70 : : spinlock_t async_lock; 71 : : wait_queue_head_t async_waitq; 72 : : struct list_head async_list; 73 : : struct list_head async_free; 74 : : int async_ret; 75 : : 76 : : #ifdef CONFIG_DEBUG_FS 77 : : bool debugfs_disable; 78 : : struct dentry *debugfs; 79 : : const char *debugfs_name; 80 : : 81 : : unsigned int debugfs_reg_len; 82 : : unsigned int debugfs_val_len; 83 : : unsigned int debugfs_tot_len; 84 : : 85 : : struct list_head debugfs_off_cache; 86 : : struct mutex cache_lock; 87 : : #endif 88 : : 89 : : unsigned int max_register; 90 : : bool (*writeable_reg)(struct device *dev, unsigned int reg); 91 : : bool (*readable_reg)(struct device *dev, unsigned int reg); 92 : : bool (*volatile_reg)(struct device *dev, unsigned int reg); 93 : : bool (*precious_reg)(struct device *dev, unsigned int reg); 94 : : bool (*writeable_noinc_reg)(struct device *dev, unsigned int reg); 95 : : bool (*readable_noinc_reg)(struct device *dev, unsigned int reg); 96 : : const struct regmap_access_table *wr_table; 97 : : const struct regmap_access_table *rd_table; 98 : : const struct regmap_access_table *volatile_table; 99 : : const struct regmap_access_table *precious_table; 100 : : const struct regmap_access_table *wr_noinc_table; 101 : : const struct regmap_access_table *rd_noinc_table; 102 : : 103 : : int (*reg_read)(void *context, unsigned int reg, unsigned int *val); 104 : : int (*reg_write)(void *context, unsigned int reg, unsigned int val); 105 : : int (*reg_update_bits)(void *context, unsigned int reg, 106 : : unsigned int mask, unsigned int val); 107 : : 108 : : bool defer_caching; 109 : : 110 : : unsigned long read_flag_mask; 111 : : unsigned long write_flag_mask; 112 : : 113 : : /* number of bits to (left) shift the reg value when formatting*/ 114 : : int reg_shift; 115 : : int reg_stride; 116 : : int reg_stride_order; 117 : : 118 : : /* regcache specific members */ 119 : : const struct regcache_ops *cache_ops; 120 : : enum regcache_type cache_type; 121 : : 122 : : /* number of bytes in reg_defaults_raw */ 123 : : unsigned int cache_size_raw; 124 : : /* number of bytes per word in reg_defaults_raw */ 125 : : unsigned int cache_word_size; 126 : : /* number of entries in reg_defaults */ 127 : : unsigned int num_reg_defaults; 128 : : /* number of entries in reg_defaults_raw */ 129 : : unsigned int num_reg_defaults_raw; 130 : : 131 : : /* if set, only the cache is modified not the HW */ 132 : : bool cache_only; 133 : : /* if set, only the HW is modified not the cache */ 134 : : bool cache_bypass; 135 : : /* if set, remember to free reg_defaults_raw */ 136 : : bool cache_free; 137 : : 138 : : struct reg_default *reg_defaults; 139 : : const void *reg_defaults_raw; 140 : : void *cache; 141 : : /* if set, the cache contains newer data than the HW */ 142 : : bool cache_dirty; 143 : : /* if set, the HW registers are known to match map->reg_defaults */ 144 : : bool no_sync_defaults; 145 : : 146 : : struct reg_sequence *patch; 147 : : int patch_regs; 148 : : 149 : : /* if set, converts bulk read to single read */ 150 : : bool use_single_read; 151 : : /* if set, converts bulk write to single write */ 152 : : bool use_single_write; 153 : : /* if set, the device supports multi write mode */ 154 : : bool can_multi_write; 155 : : 156 : : /* if set, raw reads/writes are limited to this size */ 157 : : size_t max_raw_read; 158 : : size_t max_raw_write; 159 : : 160 : : struct rb_root range_tree; 161 : : void *selector_work_buf; /* Scratch buffer used for selector */ 162 : : 163 : : struct hwspinlock *hwlock; 164 : : }; 165 : : 166 : : struct regcache_ops { 167 : : const char *name; 168 : : enum regcache_type type; 169 : : int (*init)(struct regmap *map); 170 : : int (*exit)(struct regmap *map); 171 : : #ifdef CONFIG_DEBUG_FS 172 : : void (*debugfs_init)(struct regmap *map); 173 : : #endif 174 : : int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); 175 : : int (*write)(struct regmap *map, unsigned int reg, unsigned int value); 176 : : int (*sync)(struct regmap *map, unsigned int min, unsigned int max); 177 : : int (*drop)(struct regmap *map, unsigned int min, unsigned int max); 178 : : }; 179 : : 180 : : bool regmap_cached(struct regmap *map, unsigned int reg); 181 : : bool regmap_writeable(struct regmap *map, unsigned int reg); 182 : : bool regmap_readable(struct regmap *map, unsigned int reg); 183 : : bool regmap_volatile(struct regmap *map, unsigned int reg); 184 : : bool regmap_precious(struct regmap *map, unsigned int reg); 185 : : bool regmap_writeable_noinc(struct regmap *map, unsigned int reg); 186 : : bool regmap_readable_noinc(struct regmap *map, unsigned int reg); 187 : : 188 : : int _regmap_write(struct regmap *map, unsigned int reg, 189 : : unsigned int val); 190 : : 191 : : struct regmap_range_node { 192 : : struct rb_node node; 193 : : const char *name; 194 : : struct regmap *map; 195 : : 196 : : unsigned int range_min; 197 : : unsigned int range_max; 198 : : 199 : : unsigned int selector_reg; 200 : : unsigned int selector_mask; 201 : : int selector_shift; 202 : : 203 : : unsigned int window_start; 204 : : unsigned int window_len; 205 : : }; 206 : : 207 : : struct regmap_field { 208 : : struct regmap *regmap; 209 : : unsigned int mask; 210 : : /* lsb */ 211 : : unsigned int shift; 212 : : unsigned int reg; 213 : : 214 : : unsigned int id_size; 215 : : unsigned int id_offset; 216 : : }; 217 : : 218 : : #ifdef CONFIG_DEBUG_FS 219 : : extern void regmap_debugfs_initcall(void); 220 : : extern void regmap_debugfs_init(struct regmap *map, const char *name); 221 : : extern void regmap_debugfs_exit(struct regmap *map); 222 : : 223 : : static inline void regmap_debugfs_disable(struct regmap *map) 224 : : { 225 : 0 : map->debugfs_disable = true; 226 : : } 227 : : 228 : : #else 229 : : static inline void regmap_debugfs_initcall(void) { } 230 : : static inline void regmap_debugfs_init(struct regmap *map, const char *name) { } 231 : : static inline void regmap_debugfs_exit(struct regmap *map) { } 232 : : static inline void regmap_debugfs_disable(struct regmap *map) { } 233 : : #endif 234 : : 235 : : /* regcache core declarations */ 236 : : int regcache_init(struct regmap *map, const struct regmap_config *config); 237 : : void regcache_exit(struct regmap *map); 238 : : int regcache_read(struct regmap *map, 239 : : unsigned int reg, unsigned int *value); 240 : : int regcache_write(struct regmap *map, 241 : : unsigned int reg, unsigned int value); 242 : : int regcache_sync(struct regmap *map); 243 : : int regcache_sync_block(struct regmap *map, void *block, 244 : : unsigned long *cache_present, 245 : : unsigned int block_base, unsigned int start, 246 : : unsigned int end); 247 : : 248 : : static inline const void *regcache_get_val_addr(struct regmap *map, 249 : : const void *base, 250 : : unsigned int idx) 251 : : { 252 : 0 : return base + (map->cache_word_size * idx); 253 : : } 254 : : 255 : : unsigned int regcache_get_val(struct regmap *map, const void *base, 256 : : unsigned int idx); 257 : : bool regcache_set_val(struct regmap *map, void *base, unsigned int idx, 258 : : unsigned int val); 259 : : int regcache_lookup_reg(struct regmap *map, unsigned int reg); 260 : : 261 : : int _regmap_raw_write(struct regmap *map, unsigned int reg, 262 : : const void *val, size_t val_len); 263 : : 264 : : void regmap_async_complete_cb(struct regmap_async *async, int ret); 265 : : 266 : : enum regmap_endian regmap_get_val_endian(struct device *dev, 267 : : const struct regmap_bus *bus, 268 : : const struct regmap_config *config); 269 : : 270 : : extern struct regcache_ops regcache_rbtree_ops; 271 : : extern struct regcache_ops regcache_lzo_ops; 272 : : extern struct regcache_ops regcache_flat_ops; 273 : : 274 : : static inline const char *regmap_name(const struct regmap *map) 275 : : { 276 : 0 : if (map->dev) 277 : : return dev_name(map->dev); 278 : : 279 : 0 : return map->name; 280 : : } 281 : : 282 : : static inline unsigned int regmap_get_offset(const struct regmap *map, 283 : : unsigned int index) 284 : : { 285 : 0 : if (map->reg_stride_order >= 0) 286 : 0 : return index << map->reg_stride_order; 287 : : else 288 : 0 : return index * map->reg_stride; 289 : : } 290 : : 291 : : static inline unsigned int regcache_get_index_by_order(const struct regmap *map, 292 : : unsigned int reg) 293 : : { 294 : 0 : return reg >> map->reg_stride_order; 295 : : } 296 : : 297 : : #endif