| 1 |
|
| 2 | |
| 3 | * Register map access API internal header
|
| 4 | *
|
| 5 | * Copyright 2011 Wolfson Microelectronics plc
|
| 6 | *
|
| 7 | * Author: Mark Brown <[email protected]>
|
| 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 | s8 reg_shift;
|
| 36 | void (*format_write)(struct regmap *map,
|
| 37 | unsigned int reg, unsigned int val);
|
| 38 | void (*format_reg)(void *buf, unsigned int reg, unsigned int shift);
|
| 39 | void (*format_val)(void *buf, unsigned int val, unsigned int shift);
|
| 40 | unsigned int (*parse_val)(const void *buf);
|
| 41 | void (*parse_inplace)(void *buf);
|
| 42 | };
|
| 43 |
|
| 44 | struct regmap_async {
|
| 45 | struct list_head list;
|
| 46 | struct regmap *map;
|
| 47 | void *work_buf;
|
| 48 | };
|
| 49 |
|
| 50 | struct regmap {
|
| 51 | union {
|
| 52 | struct mutex mutex;
|
| 53 | struct {
|
| 54 | spinlock_t spinlock;
|
| 55 | unsigned long spinlock_flags;
|
| 56 | };
|
| 57 | struct {
|
| 58 | raw_spinlock_t raw_spinlock;
|
| 59 | unsigned long raw_spinlock_flags;
|
| 60 | };
|
| 61 | };
|
| 62 | struct lock_class_key *lock_key;
|
| 63 | regmap_lock lock;
|
| 64 | regmap_unlock unlock;
|
| 65 | void *lock_arg;
|
| 66 | gfp_t alloc_flags;
|
| 67 | unsigned int reg_base;
|
| 68 |
|
| 69 | struct device *dev;
|
| 70 | void *work_buf;
|
| 71 | struct regmap_format format;
|
| 72 | const struct regmap_bus *bus;
|
| 73 | void *bus_context;
|
| 74 | const char *name;
|
| 75 |
|
| 76 | spinlock_t async_lock;
|
| 77 | wait_queue_head_t async_waitq;
|
| 78 | struct list_head async_list;
|
| 79 | struct list_head async_free;
|
| 80 | int async_ret;
|
| 81 | bool async;
|
| 82 |
|
| 83 | #ifdef CONFIG_DEBUG_FS
|
| 84 | bool debugfs_disable;
|
| 85 | struct dentry *debugfs;
|
| 86 | const char *debugfs_name;
|
| 87 | int debugfs_dummy_id;
|
| 88 |
|
| 89 | unsigned int debugfs_reg_len;
|
| 90 | unsigned int debugfs_val_len;
|
| 91 | unsigned int debugfs_tot_len;
|
| 92 |
|
| 93 | struct list_head debugfs_off_cache;
|
| 94 | struct mutex cache_lock;
|
| 95 | #endif
|
| 96 |
|
| 97 | unsigned int max_register;
|
| 98 | bool max_register_is_set;
|
| 99 | bool (*writeable_reg)(struct device *dev, unsigned int reg);
|
| 100 | bool (*readable_reg)(struct device *dev, unsigned int reg);
|
| 101 | bool (*volatile_reg)(struct device *dev, unsigned int reg);
|
| 102 | bool (*precious_reg)(struct device *dev, unsigned int reg);
|
| 103 | bool (*writeable_noinc_reg)(struct device *dev, unsigned int reg);
|
| 104 | bool (*readable_noinc_reg)(struct device *dev, unsigned int reg);
|
| 105 | const struct regmap_access_table *wr_table;
|
| 106 | const struct regmap_access_table *rd_table;
|
| 107 | const struct regmap_access_table *volatile_table;
|
| 108 | const struct regmap_access_table *precious_table;
|
| 109 | const struct regmap_access_table *wr_noinc_table;
|
| 110 | const struct regmap_access_table *rd_noinc_table;
|
| 111 |
|
| 112 | int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
|
| 113 | int (*reg_write)(void *context, unsigned int reg, unsigned int val);
|
| 114 | int (*reg_update_bits)(void *context, unsigned int reg,
|
| 115 | unsigned int mask, unsigned int val);
|
| 116 |
|
| 117 | int (*read)(void *context, const void *reg_buf, size_t reg_size,
|
| 118 | void *val_buf, size_t val_size);
|
| 119 | int (*write)(void *context, const void *data, size_t count);
|
| 120 |
|
| 121 | int (*reg_default_cb)(struct device *dev, unsigned int reg,
|
| 122 | unsigned int *val);
|
| 123 |
|
| 124 | unsigned long read_flag_mask;
|
| 125 | unsigned long write_flag_mask;
|
| 126 |
|
| 127 |
|
| 128 | int reg_shift;
|
| 129 | int reg_stride;
|
| 130 | int reg_stride_order;
|
| 131 |
|
| 132 | bool defer_caching;
|
| 133 |
|
| 134 |
|
| 135 | bool force_write_field;
|
| 136 |
|
| 137 |
|
| 138 | const struct regcache_ops *cache_ops;
|
| 139 | enum regcache_type cache_type;
|
| 140 |
|
| 141 |
|
| 142 | unsigned int cache_size_raw;
|
| 143 |
|
| 144 | unsigned int cache_word_size;
|
| 145 |
|
| 146 | unsigned int num_reg_defaults;
|
| 147 |
|
| 148 | unsigned int num_reg_defaults_raw;
|
| 149 |
|
| 150 |
|
| 151 | bool cache_only;
|
| 152 |
|
| 153 | bool cache_bypass;
|
| 154 |
|
| 155 | bool cache_free;
|
| 156 |
|
| 157 | struct reg_default *reg_defaults;
|
| 158 | const void *reg_defaults_raw;
|
| 159 | void *cache;
|
| 160 |
|
| 161 | bool cache_dirty;
|
| 162 |
|
| 163 | bool no_sync_defaults;
|
| 164 |
|
| 165 | struct reg_sequence *patch;
|
| 166 | unsigned int patch_regs;
|
| 167 |
|
| 168 |
|
| 169 | bool can_sleep;
|
| 170 |
|
| 171 |
|
| 172 | bool use_single_read;
|
| 173 |
|
| 174 | bool use_single_write;
|
| 175 |
|
| 176 | bool can_multi_write;
|
| 177 |
|
| 178 |
|
| 179 | size_t max_raw_read;
|
| 180 | size_t max_raw_write;
|
| 181 |
|
| 182 | struct rb_root range_tree;
|
| 183 | void *selector_work_buf;
|
| 184 |
|
| 185 | struct hwspinlock *hwlock;
|
| 186 | };
|
| 187 |
|
| 188 | struct regcache_ops {
|
| 189 | const char *name;
|
| 190 | enum regcache_type type;
|
| 191 | int (*init)(struct regmap *map);
|
| 192 | void (*exit)(struct regmap *map);
|
| 193 | int (*populate)(struct regmap *map);
|
| 194 | #ifdef CONFIG_DEBUG_FS
|
| 195 | void (*debugfs_init)(struct regmap *map);
|
| 196 | #endif
|
| 197 | int (*read)(struct regmap *map, unsigned int reg, unsigned int *value);
|
| 198 | int (*write)(struct regmap *map, unsigned int reg, unsigned int value);
|
| 199 | int (*sync)(struct regmap *map, unsigned int min, unsigned int max);
|
| 200 | int (*drop)(struct regmap *map, unsigned int min, unsigned int max);
|
| 201 | };
|
| 202 |
|
| 203 | bool regmap_cached(struct regmap *map, unsigned int reg);
|
| 204 | bool regmap_writeable(struct regmap *map, unsigned int reg);
|
| 205 | bool regmap_readable(struct regmap *map, unsigned int reg);
|
| 206 | bool regmap_volatile(struct regmap *map, unsigned int reg);
|
| 207 | bool regmap_precious(struct regmap *map, unsigned int reg);
|
| 208 | bool regmap_writeable_noinc(struct regmap *map, unsigned int reg);
|
| 209 | bool regmap_readable_noinc(struct regmap *map, unsigned int reg);
|
| 210 |
|
| 211 | int _regmap_write(struct regmap *map, unsigned int reg,
|
| 212 | unsigned int val);
|
| 213 |
|
| 214 | struct regmap_range_node {
|
| 215 | struct rb_node node;
|
| 216 | const char *name;
|
| 217 | struct regmap *map;
|
| 218 |
|
| 219 | unsigned int range_min;
|
| 220 | unsigned int range_max;
|
| 221 |
|
| 222 | unsigned int selector_reg;
|
| 223 | unsigned int selector_mask;
|
| 224 | int selector_shift;
|
| 225 |
|
| 226 | unsigned int window_start;
|
| 227 | unsigned int window_len;
|
| 228 | };
|
| 229 |
|
| 230 | struct regmap_field {
|
| 231 | struct regmap *regmap;
|
| 232 | unsigned int mask;
|
| 233 |
|
| 234 | unsigned int shift;
|
| 235 | unsigned int reg;
|
| 236 |
|
| 237 | unsigned int id_size;
|
| 238 | unsigned int id_offset;
|
| 239 | };
|
| 240 |
|
| 241 | #ifdef CONFIG_DEBUG_FS
|
| 242 | extern void regmap_debugfs_initcall(void);
|
| 243 | extern void regmap_debugfs_init(struct regmap *map);
|
| 244 | extern void regmap_debugfs_exit(struct regmap *map);
|
| 245 |
|
| 246 | static inline void regmap_debugfs_disable(struct regmap *map)
|
| 247 | {
|
| 248 | map->debugfs_disable = true;
|
| 249 | }
|
| 250 |
|
| 251 | #else
|
| 252 | static inline void regmap_debugfs_initcall(void) { }
|
| 253 | static inline void regmap_debugfs_init(struct regmap *map) { }
|
| 254 | static inline void regmap_debugfs_exit(struct regmap *map) { }
|
| 255 | static inline void regmap_debugfs_disable(struct regmap *map) { }
|
| 256 | #endif
|
| 257 |
|
| 258 |
|
| 259 | int regcache_init(struct regmap *map, const struct regmap_config *config);
|
| 260 | void regcache_exit(struct regmap *map);
|
| 261 | int regcache_read(struct regmap *map,
|
| 262 | unsigned int reg, unsigned int *value);
|
| 263 | int regcache_write(struct regmap *map,
|
| 264 | unsigned int reg, unsigned int value);
|
| 265 | int regcache_sync(struct regmap *map);
|
| 266 | int regcache_sync_block(struct regmap *map, void *block,
|
| 267 | unsigned long *cache_present,
|
| 268 | unsigned int block_base, unsigned int start,
|
| 269 | unsigned int end);
|
| 270 | bool regcache_reg_needs_sync(struct regmap *map, unsigned int reg,
|
| 271 | unsigned int val);
|
| 272 |
|
| 273 | static inline const void *regcache_get_val_addr(struct regmap *map,
|
| 274 | const void *base,
|
| 275 | unsigned int idx)
|
| 276 | {
|
| 277 | return base + (map->cache_word_size * idx);
|
| 278 | }
|
| 279 |
|
| 280 | unsigned int regcache_get_val(struct regmap *map, const void *base,
|
| 281 | unsigned int idx);
|
| 282 | void regcache_set_val(struct regmap *map, void *base, unsigned int idx,
|
| 283 | unsigned int val);
|
| 284 | int regcache_lookup_reg(struct regmap *map, unsigned int reg);
|
| 285 | int regcache_sync_val(struct regmap *map, unsigned int reg, unsigned int val);
|
| 286 |
|
| 287 | int _regmap_raw_write(struct regmap *map, unsigned int reg,
|
| 288 | const void *val, size_t val_len, bool noinc);
|
| 289 |
|
| 290 | void regmap_async_complete_cb(struct regmap_async *async, int ret);
|
| 291 |
|
| 292 | enum regmap_endian regmap_get_val_endian(struct device *dev,
|
| 293 | const struct regmap_bus *bus,
|
| 294 | const struct regmap_config *config);
|
| 295 |
|
| 296 | extern struct regcache_ops regcache_flat_sparse_ops;
|
| 297 | extern struct regcache_ops regcache_rbtree_ops;
|
| 298 | extern struct regcache_ops regcache_maple_ops;
|
| 299 | extern struct regcache_ops regcache_flat_ops;
|
| 300 |
|
| 301 | static inline const char *regmap_name(const struct regmap *map)
|
| 302 | {
|
| 303 | if (map->dev)
|
| 304 | return dev_name(map->dev);
|
| 305 |
|
| 306 | return map->name;
|
| 307 | }
|
| 308 |
|
| 309 | static inline unsigned int regmap_get_offset(const struct regmap *map,
|
| 310 | unsigned int index)
|
| 311 | {
|
| 312 | if (map->reg_stride_order >= 0)
|
| 313 | return index << map->reg_stride_order;
|
| 314 | else
|
| 315 | return index * map->reg_stride;
|
| 316 | }
|
| 317 |
|
| 318 | static inline unsigned int regcache_get_index_by_order(const struct regmap *map,
|
| 319 | unsigned int reg)
|
| 320 | {
|
| 321 | return reg >> map->reg_stride_order;
|
| 322 | }
|
| 323 |
|
| 324 | struct regmap_ram_data {
|
| 325 | unsigned int *vals;
|
| 326 | bool *read;
|
| 327 | bool *written;
|
| 328 | enum regmap_endian reg_endian;
|
| 329 | bool (*noinc_reg)(struct regmap_ram_data *data, unsigned int reg);
|
| 330 | };
|
| 331 |
|
| 332 | |
| 333 | * Create a test register map with data stored in RAM, not intended
|
| 334 | * for practical use.
|
| 335 |
|
| 336 | struct regmap *__regmap_init_ram(struct device *dev,
|
| 337 | const struct regmap_config *config,
|
| 338 | struct regmap_ram_data *data,
|
| 339 | struct lock_class_key *lock_key,
|
| 340 | const char *lock_name);
|
| 341 |
|
| 342 | #define regmap_init_ram(dev, config, data) \
|
| 343 | __regmap_lockdep_wrapper(__regmap_init_ram, #dev, dev, config, data)
|
| 344 |
|
| 345 | struct regmap *__regmap_init_raw_ram(struct device *dev,
|
| 346 | const struct regmap_config *config,
|
| 347 | struct regmap_ram_data *data,
|
| 348 | struct lock_class_key *lock_key,
|
| 349 | const char *lock_name);
|
| 350 |
|
| 351 | #define regmap_init_raw_ram(dev, config, data) \
|
| 352 | __regmap_lockdep_wrapper(__regmap_init_raw_ram, #dev, dev, config, data)
|
| 353 |
|
| 354 | #endif
|