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