colibri-imx6ull: fix vidargs
[oweals/u-boot.git] / include / regmap.h
index 3b7eea5f49344dfa1f71098edc5e3ffb57aa8907..0854200a9c162811a96b47e3d14f6e0779b3121c 100644 (file)
@@ -7,6 +7,33 @@
 #ifndef __REGMAP_H
 #define __REGMAP_H
 
+/**
+ * DOC: Overview
+ *
+ * Regmaps are an abstraction mechanism that allows device drivers to access
+ * register maps irrespective of the underlying bus architecture. This entails
+ * that for devices that support multiple busses (e.g. I2C and SPI for a GPIO
+ * expander chip) only one driver has to be written. This driver will
+ * instantiate a regmap with a backend depending on the bus the device is
+ * attached to, and use the regmap API to access the register map through that
+ * bus transparently.
+ *
+ * Read and write functions are supplied, which can read/write data of
+ * arbitrary length from/to the regmap.
+ *
+ * The endianness of regmap accesses is selectable for each map through device
+ * tree settings via the boolean "little-endian", "big-endian", and
+ * "native-endian" properties.
+ *
+ * Furthermore, the register map described by a regmap can be split into
+ * multiple disjoint areas called ranges. In this way, register maps with
+ * "holes", i.e. areas of addressable memory that are not part of the register
+ * map, can be accessed in a concise manner.
+ *
+ * Currently, only a bare "mem" backend for regmaps is supported, which
+ * accesses the register map as regular IO-mapped memory.
+ */
+
 /**
  * enum regmap_size_t - Access sizes for regmap reads and writes
  *
@@ -22,6 +49,19 @@ enum regmap_size_t {
        REGMAP_SIZE_64 = 8,
 };
 
+/**
+ * enum regmap_endianness_t - Endianness for regmap reads and writes
+ *
+ * @REGMAP_NATIVE_ENDIAN: Native endian read/write accesses
+ * @REGMAP_LITTLE_ENDIAN: Little endian read/write accesses
+ * @REGMAP_BIG_ENDIAN: Big endian read/write accesses
+ */
+enum regmap_endianness_t {
+       REGMAP_NATIVE_ENDIAN,
+       REGMAP_LITTLE_ENDIAN,
+       REGMAP_BIG_ENDIAN,
+};
+
 /**
  * struct regmap_range - a register map range
  *
@@ -40,6 +80,7 @@ struct regmap_range {
  * @ranges:            Array of ranges
  */
 struct regmap {
+       enum regmap_endianness_t endianness;
        int range_count;
        struct regmap_range ranges[0];
 };
@@ -198,6 +239,56 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
 #define regmap_get(map, type, member, valp) \
        regmap_range_get(map, 0, type, member, valp)
 
+/**
+ * regmap_read_poll_timeout - Poll until a condition is met or a timeout occurs
+ *
+ * @map:       Regmap to read from
+ * @addr:      Offset to poll
+ * @val:       Unsigned integer variable to read the value into
+ * @cond:      Break condition (usually involving @val)
+ * @sleep_us:  Maximum time to sleep between reads in us (0 tight-loops).
+ * @timeout_ms:        Timeout in ms, 0 means never timeout
+ * @test_add_time: Used for sandbox testing - amount of time to add after
+ *             starting the loop (0 if not testing)
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read
+ * error return value in case of a error read. In the two former cases,
+ * the last read value at @addr is stored in @val. Must not be called
+ * from atomic context if sleep_us or timeout_us are used.
+ *
+ * This is modelled after the regmap_read_poll_timeout macros in linux but
+ * with millisecond timeout.
+ *
+ * The _test version is for sandbox testing only. Do not use this in normal
+ * code as it advances the timer.
+ */
+#define regmap_read_poll_timeout_test(map, addr, val, cond, sleep_us, \
+                                     timeout_ms, test_add_time) \
+({ \
+       unsigned long __start = get_timer(0); \
+       int __ret; \
+       for (;;) { \
+               __ret = regmap_read((map), (addr), &(val)); \
+               if (__ret) \
+                       break; \
+               if (cond) \
+                       break; \
+               if (IS_ENABLED(CONFIG_SANDBOX) && test_add_time) \
+                       timer_test_add_offset(test_add_time); \
+               if ((timeout_ms) && get_timer(__start) > (timeout_ms)) { \
+                       __ret = regmap_read((map), (addr), &(val)); \
+                       break; \
+               } \
+               if ((sleep_us)) \
+                       udelay((sleep_us)); \
+       } \
+       __ret ?: ((cond) ? 0 : -ETIMEDOUT); \
+})
+
+#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_ms) \
+       regmap_read_poll_timeout_test(map, addr, val, cond, sleep_us, \
+                                     timeout_ms, 0) \
+
 /**
  * regmap_update_bits() - Perform a read/modify/write using a mask
  *
@@ -239,6 +330,8 @@ int regmap_init_mem(ofnode node, struct regmap **mapp);
 int regmap_init_mem_platdata(struct udevice *dev, fdt_val_t *reg, int count,
                             struct regmap **mapp);
 
+int regmap_init_mem_index(ofnode node, struct regmap **mapp, int index);
+
 /**
  * regmap_get_range() - Obtain the base memory address of a regmap range
  *