xref: /OK3568_Linux_fs/u-boot/include/regmap.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2015 Google, Inc
3*4882a593Smuzhiyun  * Written by Simon Glass <sjg@chromium.org>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifndef __REGMAP_H
9*4882a593Smuzhiyun #define __REGMAP_H
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /**
12*4882a593Smuzhiyun  * struct regmap_range - a register map range
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * @start:	Start address
15*4882a593Smuzhiyun  * @size:	Size in bytes
16*4882a593Smuzhiyun  */
17*4882a593Smuzhiyun struct regmap_range {
18*4882a593Smuzhiyun 	ulong start;
19*4882a593Smuzhiyun 	ulong size;
20*4882a593Smuzhiyun };
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun /**
23*4882a593Smuzhiyun  * struct regmap - a way of accessing hardware/bus registers
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * @base:	Base address of register map
26*4882a593Smuzhiyun  * @range_count: Number of ranges available within the map
27*4882a593Smuzhiyun  * @range:	Pointer to the list of ranges, allocated if @range_count > 1
28*4882a593Smuzhiyun  * @base_range:	If @range_count is <= 1, @range points here
29*4882a593Smuzhiyun  */
30*4882a593Smuzhiyun struct regmap {
31*4882a593Smuzhiyun 	phys_addr_t base;
32*4882a593Smuzhiyun 	int range_count;
33*4882a593Smuzhiyun 	struct regmap_range *range, base_range;
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /*
37*4882a593Smuzhiyun  * Interface to provide access to registers either through a direct memory
38*4882a593Smuzhiyun  * bus or through a peripheral bus like I2C, SPI.
39*4882a593Smuzhiyun  */
40*4882a593Smuzhiyun int regmap_write(struct regmap *map, uint offset, uint val);
41*4882a593Smuzhiyun int regmap_read(struct regmap *map, uint offset, uint *valp);
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #define regmap_write32(map, ptr, member, val) \
44*4882a593Smuzhiyun 	regmap_write(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), val)
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun #define regmap_read32(map, ptr, member, valp) \
47*4882a593Smuzhiyun 	regmap_read(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), valp)
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /**
50*4882a593Smuzhiyun  * regmap_read_poll_timeout - Poll until a condition is met or a timeout occurs
51*4882a593Smuzhiyun  *
52*4882a593Smuzhiyun  * @map:	Regmap to read from
53*4882a593Smuzhiyun  * @addr:	Offset to poll
54*4882a593Smuzhiyun  * @val:	Unsigned integer variable to read the value into
55*4882a593Smuzhiyun  * @cond:	Break condition (usually involving @val)
56*4882a593Smuzhiyun  * @sleep_us:	Maximum time to sleep between reads in us (0 tight-loops).
57*4882a593Smuzhiyun  * @timeout_ms:	Timeout in ms, 0 means never timeout
58*4882a593Smuzhiyun  *
59*4882a593Smuzhiyun  * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read
60*4882a593Smuzhiyun  * error return value in case of a error read. In the two former cases,
61*4882a593Smuzhiyun  * the last read value at @addr is stored in @val. Must not be called
62*4882a593Smuzhiyun  * from atomic context if sleep_us or timeout_us are used.
63*4882a593Smuzhiyun  *
64*4882a593Smuzhiyun  * This is modelled after the regmap_read_poll_timeout macros in linux but
65*4882a593Smuzhiyun  * with millisecond timeout.
66*4882a593Smuzhiyun  */
67*4882a593Smuzhiyun #define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_ms) \
68*4882a593Smuzhiyun ({ \
69*4882a593Smuzhiyun 	unsigned long __start = get_timer(0); \
70*4882a593Smuzhiyun 	int __ret; \
71*4882a593Smuzhiyun 	for (;;) { \
72*4882a593Smuzhiyun 		__ret = regmap_read((map), (addr), &(val)); \
73*4882a593Smuzhiyun 		if (__ret) \
74*4882a593Smuzhiyun 			break; \
75*4882a593Smuzhiyun 		if (cond) \
76*4882a593Smuzhiyun 			break; \
77*4882a593Smuzhiyun 		if ((timeout_ms) && get_timer(__start) > (timeout_ms)) { \
78*4882a593Smuzhiyun 			__ret = regmap_read((map), (addr), &(val)); \
79*4882a593Smuzhiyun 			break; \
80*4882a593Smuzhiyun 		} \
81*4882a593Smuzhiyun 		if ((sleep_us)) \
82*4882a593Smuzhiyun 			udelay((sleep_us)); \
83*4882a593Smuzhiyun 	} \
84*4882a593Smuzhiyun 	__ret ?: ((cond) ? 0 : -ETIMEDOUT); \
85*4882a593Smuzhiyun })
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun /**
88*4882a593Smuzhiyun  * regmap_update_bits() - Perform a read/modify/write using a mask
89*4882a593Smuzhiyun  *
90*4882a593Smuzhiyun  * @map:	The map returned by regmap_init_mem*()
91*4882a593Smuzhiyun  * @offset:	Offset of the memory
92*4882a593Smuzhiyun  * @mask:	Mask to apply to the read value
93*4882a593Smuzhiyun  * @val:	Value to apply to the value to write
94*4882a593Smuzhiyun  */
95*4882a593Smuzhiyun int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /**
98*4882a593Smuzhiyun  * regmap_init_mem() - Set up a new register map that uses memory access
99*4882a593Smuzhiyun  *
100*4882a593Smuzhiyun  * Use regmap_uninit() to free it.
101*4882a593Smuzhiyun  *
102*4882a593Smuzhiyun  * @dev:	Device that uses this map
103*4882a593Smuzhiyun  * @mapp:	Returns allocated map
104*4882a593Smuzhiyun  */
105*4882a593Smuzhiyun int regmap_init_mem(struct udevice *dev, struct regmap **mapp);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /**
108*4882a593Smuzhiyun  * regmap_init_mem_platdata() - Set up a new memory register map for of-platdata
109*4882a593Smuzhiyun  *
110*4882a593Smuzhiyun  * This creates a new regmap with a list of regions passed in, rather than
111*4882a593Smuzhiyun  * using the device tree. It only supports 32-bit machines.
112*4882a593Smuzhiyun  *
113*4882a593Smuzhiyun  * Use regmap_uninit() to free it.
114*4882a593Smuzhiyun  *
115*4882a593Smuzhiyun  * @dev:	Device that uses this map
116*4882a593Smuzhiyun  * @reg:	List of address, size pairs
117*4882a593Smuzhiyun  * @count:	Number of pairs (e.g. 1 if the regmap has a single entry)
118*4882a593Smuzhiyun  * @mapp:	Returns allocated map
119*4882a593Smuzhiyun  */
120*4882a593Smuzhiyun int regmap_init_mem_platdata(struct udevice *dev, fdt_val_t *reg, int count,
121*4882a593Smuzhiyun 			     struct regmap **mapp);
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun /**
124*4882a593Smuzhiyun  * regmap_get_range() - Obtain the base memory address of a regmap range
125*4882a593Smuzhiyun  *
126*4882a593Smuzhiyun  * @map:	Regmap to query
127*4882a593Smuzhiyun  * @range_num:	Range to look up
128*4882a593Smuzhiyun  */
129*4882a593Smuzhiyun void *regmap_get_range(struct regmap *map, unsigned int range_num);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun /**
132*4882a593Smuzhiyun  * regmap_uninit() - free a previously inited regmap
133*4882a593Smuzhiyun  */
134*4882a593Smuzhiyun int regmap_uninit(struct regmap *map);
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun #endif
137