From: Wilfred Mallawa <wilfred.mall...@wdc.com> Changes from V1: * Instead of needing all field bits to be set we clear the field if any are set. If the field is 0/clear then no change.
Adds a helper macro that implements the register `w1c` functionality. Ex: uint32_t data = FIELD32_1CLEAR(val, REG, FIELD); If ANY bits of the specified `FIELD` is set then the respective field is cleared and returned to `data`. If the field is cleared (0), then no change and val is returned. Signed-off-by: Wilfred Mallawa <wilfred.mall...@wdc.com> --- include/hw/registerfields.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h index 1330ca77de..4a6a228339 100644 --- a/include/hw/registerfields.h +++ b/include/hw/registerfields.h @@ -115,6 +115,28 @@ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ _d; }) +/* + * Clear the specified field in reg_val if + * any field bits are set, else no changes made. Implements + * single/multi-bit `w1c` + * + */ +#define FIELD8_1CLEAR(reg_val, reg, field) \ + (FIELD_EX8(reg_val, reg, field) ? \ + FIELD_DP8(reg_val, reg, field, 0x00) : reg_val) + +#define FIELD16_1CLEAR(reg_val, reg, field) \ + (FIELD_EX16(reg_val, reg, field) ? \ + FIELD_DP16(reg_val, reg, field, 0x00) : reg_val) + +#define FIELD32_1CLEAR(reg_val, reg, field) \ + (FIELD_EX32(reg_val, reg, field) ? \ + FIELD_DP32(reg_val, reg, field, 0x00) : reg_val) + +#define FIELD64_1CLEAR(reg_val, reg, field) \ + (FIELD_EX64(reg_val, reg, field) ? \ + FIELD_DP64(reg_val, reg, field, 0x00) : reg_val) + #define FIELD_SDP8(storage, reg, field, val) ({ \ struct { \ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \ -- 2.37.3