+
+static inline uint32_t
+stm_spread_mask(uint16_t mask) {
+ uint32_t m = mask;
+
+ /* 0000000000000000mmmmmmmmmmmmmmmm */
+ m = (m & 0xff) | ((m & 0xff00) << 8);
+ /* 00000000mmmmmmmm00000000mmmmmmmm */
+ m = (m & 0x000f000f) | ((m & 0x00f000f0) << 4);
+ /* 0000mmmm0000mmmm0000mmmm0000mmmm */
+ m = (m & 0x03030303) | ((m & 0x0c0c0c0c) << 2);
+ /* 00mm00mm00mm00mm00mm00mm00mm00mm */
+ m = (m & 0x11111111) | ((m & 0x22222222) << 2);
+ /* 0m0m0m0m0m0m0m0m0m0m0m0m0m0m0m0m */
+ return m;
+}
+
+static inline void
+stm_moder_set_mask(struct stm_gpio *gpio, uint16_t mask, uint32_t value) {
+ uint32_t bits32 = stm_spread_mask(mask);
+ uint32_t mask32 = 3 * bits32;
+ uint32_t value32 = (value & 3) * bits32;
+
+ gpio->moder = ((gpio->moder & ~mask32) | value32);
+}
+