/*
 * MC12XS6_F.h
 * Register map for the Gen4 eSwitch of 12XS6|F family
 *
 */
 
#ifndef G4XS_MC12XS6_F_H_
#define G4XS_MC12XS6_F_H_

/* Serial input register addresses. */

/* Initialization 1 input address. */
#define G4XS_SI_INIT1_ADDR 0x0000U

#define G4XS_SOA0_MASK 0x0001
#define G4XS_SOA1_MASK 0x0002
#define G4XS_SOA2_MASK 0x0004
#define G4XS_SOA3_MASK 0x0008
#define G4XS_SOA_MODE_MASK 0x0010
#define G4XS_MUX0_MASK 0x0020
#define G4XS_MUX1_MASK 0x0040
#define G4XS_MUX2_MASK 0x0080
#define G4XS_SYNC_EN0_MASK 0x0100
#define G4XS_SYNC_EN1_MASK 0x0200
#define G4XS_WD_SEL_MASK 0x0400

#define G4XS_SOA0_SHIFT 0x00
#define G4XS_SOA1_SHIFT 0x01
#define G4XS_SOA2_SHIFT 0x02
#define G4XS_SOA3_SHIFT 0x03
#define G4XS_SOA_MODE_SHIFT 0x04
#define G4XS_MUX0_SHIFT 0x05
#define G4XS_MUX1_SHIFT 0x06
#define G4XS_MUX2_SHIFT 0x07
#define G4XS_SYNC_EN0_SHIFT 0x08
#define G4XS_SYNC_EN1_SHIFT 0x09
#define G4XS_WD_SEL_SHIFT 0x0A

/* SOA address settings (address of next SO data word). */
#define G4XS_SOA_SET_ADDR(reg, addr) ((reg & 0xFFF0) | (addr & 0x000F))

/* SOA mode settings */
/* Default - after read, the SO address returns to quick status register. */
#define G4XS_SOA_MODE_SINGLE_READ (0x00 << G4XS_SOA_MODE_SHIFT) 
/* The programmed SO address is used for the next and all further read commands until a new programming. */
#define G4XS_SOA_MODE_ALL_READS (0x01 << G4XS_SOA_MODE_SHIFT)

/* MUX settings (CSNS multiplexer). */
#define G4XS_MUX_OFF ((0x00 << G4XS_MUX2_SHIFT) | (0x00 << G4XS_MUX1_SHIFT) | (0x00 << G4XS_MUX0_SHIFT))
#define G4XS_MUX_OUT1_CURRENT ((0x00 << G4XS_MUX2_SHIFT) | (0x00 << G4XS_MUX1_SHIFT) | (0x01 << G4XS_MUX0_SHIFT))
#define G4XS_MUX_OUT2_CURRENT ((0x00 << G4XS_MUX2_SHIFT) | (0x01 << G4XS_MUX1_SHIFT) | (0x00 << G4XS_MUX0_SHIFT))
#define G4XS_MUX_OUT3_CURRENT ((0x00 << G4XS_MUX2_SHIFT) | (0x01 << G4XS_MUX1_SHIFT) | (0x01 << G4XS_MUX0_SHIFT))
#define G4XS_MUX_OUT4_CURRENT ((0x01 << G4XS_MUX2_SHIFT) | (0x00 << G4XS_MUX1_SHIFT) | (0x00 << G4XS_MUX0_SHIFT))
#define G4XS_MUX_OUT5_CURRENT ((0x01 << G4XS_MUX2_SHIFT) | (0x00 << G4XS_MUX1_SHIFT) | (0x01 << G4XS_MUX0_SHIFT))
#define G4XS_MUX_VBAT_MONITOR ((0x01 << G4XS_MUX2_SHIFT) | (0x01 << G4XS_MUX1_SHIFT) | (0x00 << G4XS_MUX0_SHIFT))
#define G4XS_MUX_CTRL_DIE_TMP ((0x01 << G4XS_MUX2_SHIFT) | (0x01 << G4XS_MUX1_SHIFT) | (0x01 << G4XS_MUX0_SHIFT))

/* SYNC settings (a current sense synchronization). Available during Normal mode only. Behavior depends on the selected MUX settings. */
/* Inactive. */
#define G4XS_SYNC_OFF ((0x00 << G4XS_SYNC_EN1_SHIFT) | (0x00 << G4XS_SYNC_EN0_SHIFT))
/* CSNS SYNC is active (low) when CSNS is valid, during switching the output of MUX, CSNS SYNC is inactive (high). */
#define G4XS_SYNC_VALID ((0x00 << G4XS_SYNC_EN1_SHIFT) | (0x01 << G4XS_SYNC_EN0_SHIFT))
/* As above, but after a change of the MUX, the CSNS SYNC is inactive (high) until the next PWM cycle is started. */
#define G4XS_SYNC_TRIG0 ((0x01 << G4XS_SYNC_EN1_SHIFT) | (0x00 << G4XS_SYNC_EN0_SHIFT)) 
/* Pulses (active low) from the middle of the CSNS pulse to its end are generated. Switching phases
(output and MUX) and the time from the MUX switching to the next middle of the CSNS pulse are blanked (high). */
#define G4XS_SYNC_TRIG12 ((0x01 << G4XS_SYNC_EN1_SHIFT) | (0x01 << G4XS_SYNC_EN0_SHIFT))

/* WD settings (SPI watchdog timeout). */
#define G4XS_WD_SEL_32MS (0x00 << G4XS_WD_SEL_SHIFT)
#define G4XS_WD_SEL_128MS (0x01 << G4XS_WD_SEL_SHIFT)

/* Initialization 2 input address. */
#define G4XS_SI_INIT2_ADDR 0x1000U

#define G4XS_OTW_SEL_MASK 0x0001
#define G4XS_PWM_SYNC_MASK 0x0002
#define G4XS_OCHI_OD1_MASK 0x0004
#define G4XS_OCHI_OD2_MASK 0x0008
#define G4XS_OCHI_OD3_MASK 0x0010
#define G4XS_OCHI_OD4_MASK 0x0020
#define G4XS_OCHI_OD5_MASK 0x0040
#define G4XS_NO_HID0_MASK 0x0080
#define G4XS_NO_HID1_MASK 0x0100
#define G4XS_OCHI_TRANSIENT 0x0200
#define G4XS_OCHI_THERMAL 0x0400

#define G4XS_OTW_SEL_SHIFT 0x00
#define G4XS_PWM_SYNC_SHIFT 0x01
#define G4XS_OCHI_OD1_SHIFT 0x02
#define G4XS_OCHI_OD2_SHIFT 0x03
#define G4XS_OCHI_OD3_SHIFT 0x04
#define G4XS_OCHI_OD4_SHIFT 0x05
#define G4XS_OCHI_OD5_SHIFT 0x06
#define G4XS_NO_HID0_SHIFT 0x07
#define G4XS_NO_HID1_SHIFT 0x08
#define G4XS_OCHI_TRANSIENT_SHIFT 0x09
#define G4XS_OCHI_THERMAL_SHIFT 0x0A

/* OTW settings (over temperature warning threshold). */
#define G4XS_OTW_HIGH (0x00 << G4XS_OTW_SEL_SHIFT) // default
#define G4XS_OTW_LOW (0x01 << G4XS_OTW_SEL_SHIFT)

/* PWM sync settings (the synchronization of the switching phases between different devices). */
/* All counters of the PWM module are reset with the positive edge of the CSB. */
#define G4XS_PWM_SYNC_ENABLE (0x01 << G4XS_PWM_SYNC_SHIFT)
/* No action is executed. */
#define G4XS_PWM_SYNC_DISABLE (0x00 << G4XS_PWM_SYNC_SHIFT)

/* OCHI settings (OCHI window on load demand). */
#define G4XS_OCHI_OD1_ENABLE (0x01 << G4XS_OCHI_OD1_SHIFT)
#define G4XS_OCHI_OD1_DISABLE (0x00 << G4XS_OCHI_OD1_SHIFT)
#define G4XS_OCHI_OD2_ENABLE (0x01 << G4XS_OCHI_OD2_SHIFT)
#define G4XS_OCHI_OD2_DISABLE (0x00 << G4XS_OCHI_OD2_SHIFT)
#define G4XS_OCHI_OD3_ENABLE (0x01 << G4XS_OCHI_OD3_SHIFT)
#define G4XS_OCHI_OD3_DISABLE (0x00 << G4XS_OCHI_OD3_SHIFT)
#define G4XS_OCHI_OD4_ENABLE (0x01 << G4XS_OCHI_OD4_SHIFT)
#define G4XS_OCHI_OD4_DISABLE (0x00 << G4XS_OCHI_OD4_SHIFT)
#define G4XS_OCHI_OD5_ENABLE (0x01 << G4XS_OCHI_OD5_SHIFT)
#define G4XS_OCHI_OD5_DISABLE (0x00 << G4XS_OCHI_OD5_SHIFT)

/* HID settings (HID ballast profile).*/
#define G4XS_HID_ALL ((0x00 << G4XS_NO_HID1_SHIFT) | (0x00 << G4XS_NO_HID0_SHIFT))
#define G4XS_HID_CH3 ((0x00 << G4XS_NO_HID1_SHIFT) | (0x01 << G4XS_NO_HID0_SHIFT))
#define G4XS_HID_CH3_CH4 ((0x01 << G4XS_NO_HID1_SHIFT) | (0x00 << G4XS_NO_HID0_SHIFT))
#define G4XS_HID_UNAVAILABLE ((0x01 << G4XS_NO_HID1_SHIFT) | (0x01 << G4XS_NO_HID0_SHIFT))

/* OCHI transient settings (the OCHIx levels dynamically evaluated during the OFF to ON output transition). */
/* The output is protected with OCHIx levels depending on the output voltage. */
#define G4XS_OCHI_TRANSIENT_ENABLE (0x01 << G4XS_OCHI_TRANSIENT_SHIFT)
/* The output is protected with default OCHIx levels. */
#define G4XS_OCHI_TRANSIENT_DISABLE (0x00 << G4XS_OCHI_TRANSIENT_SHIFT)

/* OCHI thermal settings (the OCHI1 level automatically adujsted in regards to the control die temperature).*/
/* The output is protected with the adjusted OCHI1 level. */
#define G4XS_OCHI_THERMAL_ENABLE (0x01 << G4XS_OCHI_THERMAL_SHIFT)
/* The output is protected with default OCHI1 level. */
#define G4XS_OCHI_THERMAL_DISABLE (0x00 << G4XS_OCHI_THERMAL_SHIFT)

/* CH1 control input address. */
#define G4XS_SI_CH1_CTRL_ADDR 0x2000U

/* CH2 control input address. */
#define G4XS_SI_CH2_CTRL_ADDR 0x3000U

/* CH3 control input address. */
#define G4XS_SI_CH3_CTRL_ADDR 0x4000U

/* CH4 control input address. */
#define G4XS_SI_CH4_CTRL_ADDR 0x5000U

/* CH5 control input address. */
#define G4XS_SI_CH5_CTRL_ADDR 0x6000U

/* CH6 control input address. */
#define G4XS_SI_CH6_CTRL_ADDR 0x7000U

/* Common for all CHx control input registers. */
#define G4XS_PWM0X_MASK 0x0001
#define G4XS_PWM1X_MASK 0x0002
#define G4XS_PWM2X_MASK 0x0004
#define G4XS_PWM3X_MASK 0x0008
#define G4XS_PWM4X_MASK 0x0010
#define G4XS_PWM5X_MASK 0x0020
#define G4XS_PWM6X_MASK 0x0040
#define G4XS_PWM7X_MASK 0x0080
#define G4XS_ONX_MASK 0x0100
#define G4XS_PH0X_MASK 0x0200
#define G4XS_PH1X_MASK 0x0400

#define G4XS_PWM0X_SHIFT 0x00
#define G4XS_PWM1X_SHIFT 0x01
#define G4XS_PWM2X_SHIFT 0x02
#define G4XS_PWM3X_SHIFT 0x03
#define G4XS_PWM4X_SHIFT 0x04
#define G4XS_PWM5X_SHIFT 0x05
#define G4XS_PWM6X_SHIFT 0x06
#define G4XS_PWM7X_SHIFT 0x07
#define G4XS_ONX_SHIFT 0x08
#define G4XS_PH0X_SHIFT 0x09
#define G4XS_PH1X_SHIFT 0x0A

/* PWM duty settings */
#define G4XS_CHX_CTRL_SET_PWM_DUTY(reg, duty) ((reg & 0xFF00) | ((duty) & 0x00FF))
#define G4XS_CHX_CTRL_GET_PWM_DUTY(reg) (reg & 0x00FF)

/* Channel X on/off including OCHI settings */
#define G4XS_CHX_CTRL_ONX_ENABLE (0x01 << G4XS_ONX_SHIFT)
#define G4XS_CHX_CTRL_ONX_DISABLE (0x00 << G4XS_ONX_SHIFT)

/* Channel X phase settings */
#define G4XS_CHX_PHASE_0 ((0x00 << G4XS_PH1X_SHIFT) | (0x00 << G4XS_PH0X_SHIFT))
#define G4XS_CHX_PHASE_90 ((0x00 << G4XS_PH1X_SHIFT) | (0x01 << G4XS_PH0X_SHIFT))
#define G4XS_CHX_PHASE_180 ((0x01 << G4XS_PH1X_SHIFT) | (0x00 << G4XS_PH0X_SHIFT))
#define G4XS_CHX_PHASE_270 ((0x01 << G4XS_PH1X_SHIFT) | (0x01 << G4XS_PH0X_SHIFT))

/* Output control input address. */
#define G4XS_SI_OUT_CTRL_ADDR 0x8000U

#define G4XS_ON1_MASK 0x0001
#define G4XS_ON2_MASK 0x0002
#define G4XS_ON3_MASK 0x0004
#define G4XS_ON4_MASK 0x0008
#define G4XS_ON5_MASK 0x0010
#define G4XS_ON6_MASK 0x0020
#define G4XS_PSF1_MASK 0x0040
#define G4XS_PSF2_MASK 0x0080
#define G4XS_PSF3_MASK 0x0100
#define G4XS_PSF4_MASK 0x0200
#define G4XS_PSF5_MASK 0x0400

#define G4XS_ON1_SHIFT 0x00
#define G4XS_ON2_SHIFT 0x01
#define G4XS_ON3_SHIFT 0x02
#define G4XS_ON4_SHIFT 0x03
#define G4XS_ON5_SHIFT 0x04
#define G4XS_ON6_SHIFT 0x05
#define G4XS_PSF1_SHIFT 0x06
#define G4XS_PSF2_SHIFT 0x07
#define G4XS_PSF3_SHIFT 0x08
#define G4XS_PSF4_SHIFT 0x09
#define G4XS_PSF5_SHIFT 0x0A

/* Channel on/off settings. */
#define G4XS_OUT_CTRL_ON1_ENABLE (0x01 << G4XS_ON1_SHIFT)
#define G4XS_OUT_CTRL_ON1_DISABLE (0x00 << G4XS_ON1_SHIFT)
#define G4XS_OUT_CTRL_ON2_ENABLE (0x01 << G4XS_ON2_SHIFT)
#define G4XS_OUT_CTRL_ON2_DISABLE (0x00 << G4XS_ON2_SHIFT)
#define G4XS_OUT_CTRL_ON3_ENABLE (0x01 << G4XS_ON3_SHIFT)
#define G4XS_OUT_CTRL_ON3_DISABLE (0x00 << G4XS_ON3_SHIFT)
#define G4XS_OUT_CTRL_ON4_ENABLE (0x01 << G4XS_ON4_SHIFT)
#define G4XS_OUT_CTRL_ON4_DISABLE (0x00 << G4XS_ON4_SHIFT)
#define G4XS_OUT_CTRL_ON5_ENABLE (0x01 << G4XS_ON5_SHIFT)
#define G4XS_OUT_CTRL_ON5_DISABLE (0x00 << G4XS_ON5_SHIFT)
#define G4XS_OUT_CTRL_ON6_ENABLE (0x01 << G4XS_ON6_SHIFT)
#define G4XS_OUT_CTRL_ON6_DISABLE (0x00 << G4XS_ON6_SHIFT)

/* Pulse skipping feature settings (to interpolate the duty cycle values between F7 and FF). */
#define G4XS_PSF1_ENABLE (0x01 << G4XS_PSF1_SHIFT)
#define G4XS_PSF1_DISABLE (0x00 << G4XS_PSF1_SHIFT)
#define G4XS_PSF2_ENABLE (0x01 << G4XS_PSF2_SHIFT)
#define G4XS_PSF2_DISABLE (0x00 << G4XS_PSF2_SHIFT)
#define G4XS_PSF3_ENABLE (0x01 << G4XS_PSF3_SHIFT)
#define G4XS_PSF3_DISABLE (0x00 << G4XS_PSF3_SHIFT)
#define G4XS_PSF4_ENABLE (0x01 << G4XS_PSF4_SHIFT)
#define G4XS_PSF4_DISABLE (0x00 << G4XS_PSF4_SHIFT)
#define G4XS_PSF5_ENABLE (0x01 << G4XS_PSF5_SHIFT)
#define G4XS_PSF5_DISABLE (0x00 << G4XS_PSF5_SHIFT)

/* Global PWM control 1 input address. */
#define G4XS_SI_GPWM_CTRL_1_ADDR 0x9000U

#define G4XS_GPWM_EN1_MASK 0x0001
#define G4XS_GPWM_EN2_MASK 0x0002
#define G4XS_GPWM_EN3_MASK 0x0004
#define G4XS_GPWM_EN4_MASK 0x0008
#define G4XS_GPWM_EN5_MASK 0x0010
#define G4XS_GPWM_EN6_MASK 0x0020

#define G4XS_GPWM_EN1_SHIFT 0x00
#define G4XS_GPWM_EN2_SHIFT 0x01
#define G4XS_GPWM_EN3_SHIFT 0x02
#define G4XS_GPWM_EN4_SHIFT 0x03
#define G4XS_GPWM_EN5_SHIFT 0x04
#define G4XS_GPWM_EN6_SHIFT 0x05

/* Global PWM control settings. */
#define G4XS_GPWM1_ENABLE (0x01 << G4XS_GPWM_EN1_SHIFT)
#define G4XS_GPWM1_DISABLE (0x00 << G4XS_GPWM_EN1_SHIFT)
#define G4XS_GPWM2_ENABLE (0x01 << G4XS_GPWM_EN2_SHIFT)
#define G4XS_GPWM2_DISABLE (0x00 << G4XS_GPWM_EN2_SHIFT)
#define G4XS_GPWM3_ENABLE (0x01 << G4XS_GPWM_EN3_SHIFT)
#define G4XS_GPWM3_DISABLE (0x00 << G4XS_GPWM_EN3_SHIFT)
#define G4XS_GPWM4_ENABLE (0x01 << G4XS_GPWM_EN4_SHIFT)
#define G4XS_GPWM4_DISABLE (0x00 << G4XS_GPWM_EN4_SHIFT)
#define G4XS_GPWM5_ENABLE (0x01 << G4XS_GPWM_EN5_SHIFT)
#define G4XS_GPWM5_DISABLE (0x00 << G4XS_GPWM_EN5_SHIFT)
#define G4XS_GPWM6_ENABLE (0x01 << G4XS_GPWM_EN6_SHIFT)
#define G4XS_GPWM6_DISABLE (0x00 << G4XS_GPWM_EN6_SHIFT)

/* Global PWM control 2 input address. */
#define G4XS_SI_GPWM_CTRL_2_ADDR 0x9400U

#define G4XS_GPWM0_MASK 0x0001
#define G4XS_GPWM1_MASK 0x0002
#define G4XS_GPWM2_MASK 0x0004
#define G4XS_GPWM3_MASK 0x0008
#define G4XS_GPWM4_MASK 0x0010
#define G4XS_GPWM5_MASK 0x0020
#define G4XS_GPWM6_MASK 0x0040
#define G4XS_GPWM7_MASK 0x0080

#define G4XS_GPWM0_SHIFT 0x00
#define G4XS_GPWM1_SHIFT 0x01
#define G4XS_GPWM2_SHIFT 0x02
#define G4XS_GPWM3_SHIFT 0x03
#define G4XS_GPWM4_SHIFT 0x04
#define G4XS_GPWM5_SHIFT 0x05
#define G4XS_GPWM6_SHIFT 0x06
#define G4XS_GPWM7_SHIFT 0x07

/* Global PWM duty settings. */
#define G4XS_SET_GPWM_DUTY(reg, duty) ((reg & 0xFF00) | ((duty) & 0x00FF))
#define G4XS_GET_GPWM_DUTY(reg) (reg & 0x00FF)

/* Over current control 1 input address. */
#define G4XS_SI_OC_CTRL_1_ADDR 0xA000U

#define G4XS_ACM_EN1_MASK 0x0001
#define G4XS_ACM_EN2_MASK 0x0002
#define G4XS_ACM_EN3_MASK 0x0004
#define G4XS_ACM_EN4_MASK 0x0008
#define G4XS_ACM_EN5_MASK 0x0010
#define G4XS_OCLO1_MASK 0x0020
#define G4XS_OCLO2_MASK 0x0040
#define G4XS_OCLO3_MASK 0x0080
#define G4XS_OCLO4_MASK 0x0100
#define G4XS_OCLO5_MASK 0x0200

#define G4XS_ACM_EN1_SHIFT 0x00
#define G4XS_ACM_EN2_SHIFT 0x01
#define G4XS_ACM_EN3_SHIFT 0x02
#define G4XS_ACM_EN4_SHIFT 0x03
#define G4XS_ACM_EN5_SHIFT 0x04
#define G4XS_OCLO1_SHIFT 0x05
#define G4XS_OCLO2_SHIFT 0x06
#define G4XS_OCLO3_SHIFT 0x07
#define G4XS_OCLO4_SHIFT 0x08
#define G4XS_OCLO5_SHIFT 0x09

/* ACM settings (advance current sense mode). */
#define G4XS_ACM1_ENABLE (0x01 << G4XS_ACM_EN1_SHIFT)
#define G4XS_ACM1_DISABLE (0x00 << G4XS_ACM_EN1_SHIFT) // default and during fail mode
#define G4XS_ACM2_ENABLE (0x01 << G4XS_ACM_EN2_SHIFT)
#define G4XS_ACM2_DISABLE (0x00 << G4XS_ACM_EN2_SHIFT)
#define G4XS_ACM3_ENABLE (0x01 << G4XS_ACM_EN3_SHIFT)
#define G4XS_ACM3_DISABLE (0x00 << G4XS_ACM_EN3_SHIFT)
#define G4XS_ACM4_ENABLE (0x01 << G4XS_ACM_EN4_SHIFT)
#define G4XS_ACM4_DISABLE (0x00 << G4XS_ACM_EN4_SHIFT)
#define G4XS_ACM5_ENABLE (0x01 << G4XS_ACM_EN5_SHIFT)
#define G4XS_ACM5_DISABLE (0x00 << G4XS_ACM_EN5_SHIFT)

/* OCLO threshold settings. */
/* The output is protected with the higher OCLO threshold (default status and during fail mode). */
#define G4XS_OCLO1_THRESHOLD_HIGH (0x00 << G4XS_OCLO1_SHIFT)
/* The lower OCLO threshold is applied. */
#define G4XS_OCLO1_THRESHOLD_LOW (0x01 << G4XS_OCLO1_SHIFT)
#define G4XS_OCLO2_THRESHOLD_HIGH (0x00 << G4XS_OCLO2_SHIFT)
#define G4XS_OCLO2_THRESHOLD_LOW (0x01 << G4XS_OCLO2_SHIFT)
#define G4XS_OCLO3_THRESHOLD_HIGH (0x00 << G4XS_OCLO3_SHIFT)
#define G4XS_OCLO3_THRESHOLD_LOW (0x01 << G4XS_OCLO3_SHIFT)
#define G4XS_OCLO4_THRESHOLD_HIGH (0x00 << G4XS_OCLO4_SHIFT)
#define G4XS_OCLO4_THRESHOLD_LOW (0x01 << G4XS_OCLO4_SHIFT)
#define G4XS_OCLO5_THRESHOLD_HIGH (0x00 << G4XS_OCLO5_SHIFT)
#define G4XS_OCLO5_THRESHOLD_LOW (0x01 << G4XS_OCLO5_SHIFT)

/* Over current control 2 input address. */
#define G4XS_SI_OC_CTRL_2_ADDR 0xA400U

#define G4XS_SHORT_OCHI1_MASK 0x0001
#define G4XS_SHORT_OCHI2_MASK 0x0002
#define G4XS_SHORT_OCHI3_MASK 0x0004
#define G4XS_SHORT_OCHI4_MASK 0x0008
#define G4XS_SHORT_OCHI5_MASK 0x0010
#define G4XS_NO_OCHI1_MASK 0x0020
#define G4XS_NO_OCHI2_MASK 0x0040
#define G4XS_NO_OCHI3_MASK 0x0080
#define G4XS_NO_OCHI4_MASK 0x0100
#define G4XS_NO_OCHI5_MASK 0x0200

#define G4XS_SHORT_OCHI1_SHIFT 0x00
#define G4XS_SHORT_OCHI2_SHIFT 0x01
#define G4XS_SHORT_OCHI3_SHIFT 0x02
#define G4XS_SHORT_OCHI4_SHIFT 0x03
#define G4XS_SHORT_OCHI5_SHIFT 0x04
#define G4XS_NO_OCHI1_SHIFT 0x05
#define G4XS_NO_OCHI2_SHIFT 0x06
#define G4XS_NO_OCHI3_SHIFT 0x07
#define G4XS_NO_OCHI4_SHIFT 0x08
#define G4XS_NO_OCHI5_SHIFT 0x09

/* Short OCHI settings (to accelerate the availability of the CSNS diagnosis and to reduce the potential stress
   inside the switch during an overload condition). */
#define G4XS_SHORT_OCHI1_ENABLE (0x01 << G4XS_SHORT_OCHI1_SHIFT)
#define G4XS_SHORT_OCHI1_DISABLE (0x00 << G4XS_SHORT_OCHI1_SHIFT) // default and during fail mode
#define G4XS_SHORT_OCHI2_ENABLE (0x01 << G4XS_SHORT_OCHI2_SHIFT)
#define G4XS_SHORT_OCHI2_DISABLE (0x00 << G4XS_SHORT_OCHI2_SHIFT)
#define G4XS_SHORT_OCHI3_ENABLE (0x01 << G4XS_SHORT_OCHI3_SHIFT)
#define G4XS_SHORT_OCHI3_DISABLE (0x00 << G4XS_SHORT_OCHI3_SHIFT)
#define G4XS_SHORT_OCHI4_ENABLE (0x01 << G4XS_SHORT_OCHI4_SHIFT)
#define G4XS_SHORT_OCHI4_DISABLE (0x00 << G4XS_SHORT_OCHI4_SHIFT)
#define G4XS_SHORT_OCHI5_ENABLE (0x01 << G4XS_SHORT_OCHI5_SHIFT)
#define G4XS_SHORT_OCHI5_DISABLE (0x00 << G4XS_SHORT_OCHI5_SHIFT)

/* No OCHI settings (to accelerate the availability of the CSNS diagnosis). */
/* The turn on of the output is provided without OCHI windows. */
#define G4XS_NO_OCHI1_ENABLE (0x01 << G4XS_NO_OCHI1_SHIFT)
/* The regular OCHI window is applied (default status and during fail mode). */
#define G4XS_NO_OCHI1_DISABLE (0x00 << G4XS_NO_OCHI1_SHIFT)
#define G4XS_NO_OCHI2_ENABLE (0x01 << G4XS_NO_OCHI2_SHIFT)
#define G4XS_NO_OCHI2_DISABLE (0x00 << G4XS_NO_OCHI2_SHIFT)
#define G4XS_NO_OCHI3_ENABLE (0x01 << G4XS_NO_OCHI3_SHIFT)
#define G4XS_NO_OCHI3_DISABLE (0x00 << G4XS_NO_OCHI3_SHIFT)
#define G4XS_NO_OCHI4_ENABLE (0x01 << G4XS_NO_OCHI4_SHIFT)
#define G4XS_NO_OCHI4_DISABLE (0x00 << G4XS_NO_OCHI4_SHIFT)
#define G4XS_NO_OCHI5_ENABLE (0x01 << G4XS_NO_OCHI5_SHIFT)
#define G4XS_NO_OCHI5_DISABLE (0x00 << G4XS_NO_OCHI5_SHIFT)

/* Input enable input address. */
#define G4XS_SI_IE_ADDR 0xB000U

#define G4XS_INEN01_MASK 0x0001
#define G4XS_INEN11_MASK 0x0002
#define G4XS_INEN02_MASK 0x0004
#define G4XS_INEN12_MASK 0x0008
#define G4XS_INEN03_MASK 0x0010
#define G4XS_INEN13_MASK 0x0020
#define G4XS_INEN04_MASK 0x0040
#define G4XS_INEN14_MASK 0x0080

#define G4XS_INEN01_SHIFT 0x00
#define G4XS_INEN11_SHIFT 0x01
#define G4XS_INEN02_SHIFT 0x02
#define G4XS_INEN12_SHIFT 0x03
#define G4XS_INEN03_SHIFT 0x04
#define G4XS_INEN13_SHIFT 0x05
#define G4XS_INEN04_SHIFT 0x06
#define G4XS_INEN14_SHIFT 0x07

/* Input enable settings (see table 8 in datasheet). */
#define G4XS_INEN1_00 ((0x00 << G4XS_INEN11_SHIFT) | (0x00 << G4XS_INEN01_SHIFT))
#define G4XS_INEN1_01 ((0x00 << G4XS_INEN11_SHIFT) | (0x01 << G4XS_INEN01_SHIFT))
#define G4XS_INEN1_10 ((0x01 << G4XS_INEN11_SHIFT) | (0x00 << G4XS_INEN01_SHIFT))
#define G4XS_INEN1_11 ((0x01 << G4XS_INEN11_SHIFT) | (0x01 << G4XS_INEN01_SHIFT))
#define G4XS_INEN2_00 ((0x00 << G4XS_INEN12_SHIFT) | (0x00 << G4XS_INEN02_SHIFT))
#define G4XS_INEN2_01 ((0x00 << G4XS_INEN12_SHIFT) | (0x01 << G4XS_INEN02_SHIFT))
#define G4XS_INEN2_10 ((0x01 << G4XS_INEN12_SHIFT) | (0x00 << G4XS_INEN02_SHIFT))
#define G4XS_INEN2_11 ((0x01 << G4XS_INEN12_SHIFT) | (0x01 << G4XS_INEN02_SHIFT))
#define G4XS_INEN3_00 ((0x00 << G4XS_INEN13_SHIFT) | (0x00 << G4XS_INEN03_SHIFT))
#define G4XS_INEN3_01 ((0x00 << G4XS_INEN13_SHIFT) | (0x01 << G4XS_INEN03_SHIFT))
#define G4XS_INEN3_10 ((0x01 << G4XS_INEN13_SHIFT) | (0x00 << G4XS_INEN03_SHIFT))
#define G4XS_INEN3_11 ((0x01 << G4XS_INEN13_SHIFT) | (0x01 << G4XS_INEN03_SHIFT))
#define G4XS_INEN4_00 ((0x00 << G4XS_INEN14_SHIFT) | (0x00 << G4XS_INEN04_SHIFT))
#define G4XS_INEN4_01 ((0x00 << G4XS_INEN14_SHIFT) | (0x01 << G4XS_INEN04_SHIFT))
#define G4XS_INEN4_10 ((0x01 << G4XS_INEN14_SHIFT) | (0x00 << G4XS_INEN04_SHIFT))
#define G4XS_INEN4_11 ((0x01 << G4XS_INEN14_SHIFT) | (0x01 << G4XS_INEN04_SHIFT))

/* Prescaler settings 1 input address. */
#define G4XS_SI_PS1_ADDR 0xC000U

#define G4XS_PRS01_MASK 0x0001
#define G4XS_PRS11_MASK 0x0002
#define G4XS_PRS02_MASK 0x0004
#define G4XS_PRS12_MASK 0x0008
#define G4XS_PRS03_MASK 0x0010
#define G4XS_PRS13_MASK 0x0020
#define G4XS_PRS04_MASK 0x0040
#define G4XS_PRS14_MASK 0x0080
#define G4XS_PRS05_MASK 0x0100
#define G4XS_PRS15_MASK 0x0200

#define G4XS_PRS01_SHIFT 0x00
#define G4XS_PRS11_SHIFT 0x01
#define G4XS_PRS02_SHIFT 0x02
#define G4XS_PRS12_SHIFT 0x03
#define G4XS_PRS03_SHIFT 0x04
#define G4XS_PRS13_SHIFT 0x05
#define G4XS_PRS04_SHIFT 0x06
#define G4XS_PRS14_SHIFT 0x07
#define G4XS_PRS05_SHIFT 0x08
#define G4XS_PRS15_SHIFT 0x09

/* Prescaler settings 2 input address. */
#define G4XS_SI_PS2_ADDR 0xC400U

#define G4XS_PRS06_MASK 0x0001
#define G4XS_PRS16_MASK 0x0002

#define G4XS_PRS06_SHIFT 0x00
#define G4XS_PRS16_SHIFT 0x01

/* Prescaler feature settings (output pulse shaping). */
/* 25Hz - 100Hz */
#define G4XS_PRS1_4 ((0x00 << G4XS_PRS11_SHIFT) | (0x00 << G4XS_PRS01_SHIFT))
/* 50Hz - 200Hz */
#define G4XS_PRS1_2 ((0x00 << G4XS_PRS11_SHIFT) | (0x01 << G4XS_PRS01_SHIFT))
/* 100Hz - 400Hz */
#define G4XS_PRS1_1 ((0x01 << G4XS_PRS11_SHIFT) | (0x00 << G4XS_PRS01_SHIFT))
#define G4XS_PRS2_4 ((0x00 << G4XS_PRS12_SHIFT) | (0x00 << G4XS_PRS02_SHIFT))
#define G4XS_PRS2_2 ((0x00 << G4XS_PRS12_SHIFT) | (0x01 << G4XS_PRS02_SHIFT))
#define G4XS_PRS2_1 ((0x01 << G4XS_PRS12_SHIFT) | (0x00 << G4XS_PRS02_SHIFT))
#define G4XS_PRS3_4 ((0x00 << G4XS_PRS13_SHIFT) | (0x00 << G4XS_PRS03_SHIFT))
#define G4XS_PRS3_2 ((0x00 << G4XS_PRS13_SHIFT) | (0x01 << G4XS_PRS03_SHIFT))
#define G4XS_PRS3_1 ((0x01 << G4XS_PRS13_SHIFT) | (0x00 << G4XS_PRS03_SHIFT))
#define G4XS_PRS4_4 ((0x00 << G4XS_PRS14_SHIFT) | (0x00 << G4XS_PRS04_SHIFT))
#define G4XS_PRS4_2 ((0x00 << G4XS_PRS14_SHIFT) | (0x01 << G4XS_PRS04_SHIFT))
#define G4XS_PRS4_1 ((0x01 << G4XS_PRS14_SHIFT) | (0x00 << G4XS_PRS04_SHIFT))
#define G4XS_PRS5_4 ((0x00 << G4XS_PRS15_SHIFT) | (0x00 << G4XS_PRS05_SHIFT))
#define G4XS_PRS5_2 ((0x00 << G4XS_PRS15_SHIFT) | (0x01 << G4XS_PRS05_SHIFT))
#define G4XS_PRS5_1 ((0x01 << G4XS_PRS15_SHIFT) | (0x00 << G4XS_PRS05_SHIFT))
#define G4XS_PRS6_4 ((0x00 << G4XS_PRS16_SHIFT) | (0x00 << G4XS_PRS06_SHIFT))
#define G4XS_PRS6_2 ((0x00 << G4XS_PRS16_SHIFT) | (0x01 << G4XS_PRS06_SHIFT))
#define G4XS_PRS6_1 ((0x01 << G4XS_PRS16_SHIFT) | (0x00 << G4XS_PRS06_SHIFT))

/* OL control input address. */
#define G4XS_SI_OL_CTRL_ADDR 0xD000U

#define G4XS_OLOFF_EN1_MASK 0x0001
#define G4XS_OLOFF_EN2_MASK 0x0002
#define G4XS_OLOFF_EN3_MASK 0x0004
#define G4XS_OLOFF_EN4_MASK 0x0008
#define G4XS_OLOFF_EN5_MASK 0x0010
#define G4XS_OLON_DGL1_MASK 0x0020
#define G4XS_OLON_DGL2_MASK 0x0040
#define G4XS_OLON_DGL3_MASK 0x0080
#define G4XS_OLON_DGL4_MASK 0x0100
#define G4XS_OLON_DGL5_MASK 0x0200

#define G4XS_OLOFF_EN1_SHIFT 0x00
#define G4XS_OLOFF_EN2_SHIFT 0x01
#define G4XS_OLOFF_EN3_SHIFT 0x02
#define G4XS_OLOFF_EN4_SHIFT 0x03
#define G4XS_OLOFF_EN5_SHIFT 0x04
#define G4XS_OLON_DGL1_SHIFT 0x05
#define G4XS_OLON_DGL2_SHIFT 0x06
#define G4XS_OLON_DGL3_SHIFT 0x07
#define G4XS_OLON_DGL4_SHIFT 0x08
#define G4XS_OLON_DGL5_SHIFT 0x09

/* OLOFF settings (open load detection in off state ). */
/* The diagnosis mode is started. */
#define G4XS_OLOFF1_ENABLE (0x01 << G4XS_OLOFF_EN1_SHIFT)
/* The diagnosis mode is disabled (default). */
#define G4XS_OLOFF1_DISABLE (0x00 << G4XS_OLOFF_EN1_SHIFT)
#define G4XS_OLOFF2_ENABLE (0x01 << G4XS_OLOFF_EN2_SHIFT)
#define G4XS_OLOFF2_DISABLE (0x00 << G4XS_OLOFF_EN2_SHIFT)
#define G4XS_OLOFF3_ENABLE (0x01 << G4XS_OLOFF_EN3_SHIFT)
#define G4XS_OLOFF3_DISABLE (0x00 << G4XS_OLOFF_EN3_SHIFT)
#define G4XS_OLOFF4_ENABLE (0x01 << G4XS_OLOFF_EN4_SHIFT)
#define G4XS_OLOFF4_DISABLE (0x00 << G4XS_OLOFF_EN4_SHIFT)
#define G4XS_OLOFF5_ENABLE (0x01 << G4XS_OLOFF_EN5_SHIFT)
#define G4XS_OLOFF5_DISABLE (0x00 << G4XS_OLOFF_EN5_SHIFT)

/* OLON DGL settings (de-glitch time in on state after open load has been detected). */
/* bulb mode */
#define G4XS_OLON_DGL1_64US (0x00 << G4XS_OLON_DGL1_SHIFT)
/* converter mode */
#define G4XS_OLON_DGL1_2MS (0x01 << G4XS_OLON_DGL1_SHIFT)
#define G4XS_OLON_DGL2_64US (0x00 << G4XS_OLON_DGL2_SHIFT)
#define G4XS_OLON_DGL2_2MS (0x01 << G4XS_OLON_DGL2_SHIFT)
#define G4XS_OLON_DGL3_64US (0x00 << G4XS_OLON_DGL3_SHIFT)
#define G4XS_OLON_DGL3_2MS (0x01 << G4XS_OLON_DGL3_SHIFT)
#define G4XS_OLON_DGL4_64US (0x00 << G4XS_OLON_DGL4_SHIFT)
#define G4XS_OLON_DGL4_2MS (0x01 << G4XS_OLON_DGL4_SHIFT)
#define G4XS_OLON_DGL5_64US (0x00 << G4XS_OLON_DGL5_SHIFT)
#define G4XS_OLON_DGL5_2MS (0x01 << G4XS_OLON_DGL5_SHIFT)

/* OLLED control input address. */
#define G4XS_SI_OLLED_CTRL_ADDR 0xD400U

#define G4XS_OLLED_EN1_MASK 0x0001
#define G4XS_OLLED_EN2_MASK 0x0002
#define G4XS_OLLED_EN3_MASK 0x0004
#define G4XS_OLLED_EN4_MASK 0x0008
#define G4XS_OLLED_EN5_MASK 0x0010
#define G4XS_OLLED_TRIG_MASK 0x0020

#define G4XS_OLLED_EN1_SHIFT 0x00
#define G4XS_OLLED_EN2_SHIFT 0x01
#define G4XS_OLLED_EN3_SHIFT 0x02
#define G4XS_OLLED_EN4_SHIFT 0x03
#define G4XS_OLLED_EN5_SHIFT 0x04
#define G4XS_OLLED_TRIG_SHIFT 0x05

/* OLLED mode settings (open load detection in on state - for detection of small load currents). */
/* the OLLED detection is enabled */
#define G4XS_OLLED1_ENABLE (0x01 << G4XS_OLLED_EN1_SHIFT)
/* the standard open load in on state (OLON) is enabled */
#define G4XS_OLLED1_DISABLE (0x00 << G4XS_OLLED_EN1_SHIFT)
#define G4XS_OLLED2_ENABLE (0x01 << G4XS_OLLED_EN2_SHIFT)
#define G4XS_OLLED2_DISABLE (0x00 << G4XS_OLLED_EN2_SHIFT)
#define G4XS_OLLED3_ENABLE (0x01 << G4XS_OLLED_EN3_SHIFT)
#define G4XS_OLLED3_DISABLE (0x00 << G4XS_OLLED_EN3_SHIFT)
#define G4XS_OLLED4_ENABLE (0x01 << G4XS_OLLED_EN4_SHIFT)
#define G4XS_OLLED4_DISABLE (0x00 << G4XS_OLLED_EN4_SHIFT)
#define G4XS_OLLED5_ENABLE (0x01 << G4XS_OLLED_EN5_SHIFT)
#define G4XS_OLLED5_DISABLE (0x00 << G4XS_OLLED_EN5_SHIFT)

/* OLLED detection trigger settings. */
#define G4XS_SET_OLLED_TRG (0x01 << G4XS_OLLED_TRIG_SHIFT) /* the trigger bit is reset after the detection */

/* Increment / decrement input address. */
#define G4XS_SI_INC_DEC_ADDR 0xE000U

#define G4XS_INCR01_MASK 0x0001
#define G4XS_INCR11_MASK 0x0002
#define G4XS_INCR02_MASK 0x0004
#define G4XS_INCR12_MASK 0x0008
#define G4XS_INCR03_MASK 0x0010
#define G4XS_INCR13_MASK 0x0020
#define G4XS_INCR04_MASK 0x0040
#define G4XS_INCR14_MASK 0x0080
#define G4XS_INCR05_MASK 0x0100
#define G4XS_INCR15_MASK 0x0200
#define G4XS_INCR_SGN_MASK 0x0400

#define G4XS_INCR01_SHIFT 0x00
#define G4XS_INCR11_SHIFT 0x01
#define G4XS_INCR02_SHIFT 0x02
#define G4XS_INCR12_SHIFT 0x03
#define G4XS_INCR03_SHIFT 0x04
#define G4XS_INCR13_SHIFT 0x05
#define G4XS_INCR04_SHIFT 0x06
#define G4XS_INCR14_SHIFT 0x07
#define G4XS_INCR05_SHIFT 0x08
#define G4XS_INCR15_SHIFT 0x09
#define G4XS_INCR_SGN_SHIFT 0x0A

/* Increment / decrement settings. */
#define G4XS_INC1_NO ((0x00 << G4XS_INCR11_SHIFT) | (0x00 << G4XS_INCR01_SHIFT))
#define G4XS_INC1_4LSB ((0x00 << G4XS_INCR11_SHIFT) | (0x01 << G4XS_INCR01_SHIFT))
#define G4XS_INC1_8LSB ((0x01 << G4XS_INCR11_SHIFT) | (0x00 << G4XS_INCR01_SHIFT))
#define G4XS_INC1_16LSB ((0x01 << G4XS_INCR11_SHIFT) | (0x01 << G4XS_INCR01_SHIFT))
#define G4XS_INC2_NO ((0x00 << G4XS_INCR12_SHIFT) | (0x00 << G4XS_INCR02_SHIFT))
#define G4XS_INC2_4LSB ((0x00 << G4XS_INCR12_SHIFT) | (0x01 << G4XS_INCR02_SHIFT))
#define G4XS_INC2_8LSB ((0x01 << G4XS_INCR12_SHIFT) | (0x00 << G4XS_INCR02_SHIFT))
#define G4XS_INC2_16LSB ((0x01 << G4XS_INCR12_SHIFT) | (0x01 << G4XS_INCR02_SHIFT))
#define G4XS_INC3_NO ((0x00 << G4XS_INCR13_SHIFT) | (0x00 << G4XS_INCR03_SHIFT))
#define G4XS_INC3_4LSB ((0x00 << G4XS_INCR13_SHIFT) | (0x01 << G4XS_INCR03_SHIFT))
#define G4XS_INC3_8LSB ((0x01 << G4XS_INCR13_SHIFT) | (0x00 << G4XS_INCR03_SHIFT))
#define G4XS_INC3_16LSB ((0x01 << G4XS_INCR13_SHIFT) | (0x01 << G4XS_INCR03_SHIFT))
#define G4XS_INC4_NO ((0x00 << G4XS_INCR14_SHIFT) | (0x00 << G4XS_INCR04_SHIFT))
#define G4XS_INC4_4LSB ((0x00 << G4XS_INCR14_SHIFT) | (0x01 << G4XS_INCR04_SHIFT))
#define G4XS_INC4_8LSB ((0x01 << G4XS_INCR14_SHIFT) | (0x00 << G4XS_INCR04_SHIFT))
#define G4XS_INC4_16LSB ((0x01 << G4XS_INCR14_SHIFT) | (0x01 << G4XS_INCR04_SHIFT))
#define G4XS_INC5_NO ((0x00 << G4XS_INCR15_SHIFT) | (0x00 << G4XS_INCR05_SHIFT))
#define G4XS_INC5_4LSB ((0x00 << G4XS_INCR15_SHIFT) | (0x01 << G4XS_INCR05_SHIFT))
#define G4XS_INC5_8LSB ((0x01 << G4XS_INCR15_SHIFT) | (0x00 << G4XS_INCR05_SHIFT))
#define G4XS_INC5_16LSB ((0x01 << G4XS_INCR15_SHIFT) | (0x01 << G4XS_INCR05_SHIFT))

/* Test mode input address. */
#define G4XS_SI_TEST_MODE_ADDR 0xF000U

/* Common for all input registers. */
#define G4XS_WD_MASK 0x0800
#define G4XS_WD_SHIFT 0x0B

/* Toggle WD bit. */
#define G4XS_TOGGLE_WD(reg) (reg ^ G4XS_WD_MASK)

/* Serial output register addresses. */

/* Quick status output address. */
#define G4XS_SO_QS_ADDR 0x1000U

#define G4XS_QSF1_MASK 0x0001
#define G4XS_QSF2_MASK 0x0002
#define G4XS_QSF3_MASK 0x0004
#define G4XS_QSF4_MASK 0x0008
#define G4XS_QSF5_MASK 0x0010
#define G4XS_CLKF_MASK 0x0020
#define G4XS_RCF_MASK 0x0040
#define G4XS_CPF_MASK 0x0080

#define G4XS_QSF1_SHIFT 0x00
#define G4XS_QSF2_SHIFT 0x01
#define G4XS_QSF3_SHIFT 0x02
#define G4XS_QSF4_SHIFT 0x03
#define G4XS_QSF5_SHIFT 0x04
#define G4XS_CLKF_SHIFT 0x05
#define G4XS_RCF_SHIFT 0x06
#define G4XS_CPF_SHIFT 0x07

/* QS register getters. */
/* Quick status (OC | OTW | OTS | OLON | OLOFF). */
#define G4XS_GET_QSF1(reg) ((reg & G4XS_QSF1_MASK) >> G4XS_QSF1_SHIFT)
#define G4XS_GET_QSF2(reg) ((reg & G4XS_QSF2_MASK) >> G4XS_QSF2_SHIFT)
#define G4XS_GET_QSF3(reg) ((reg & G4XS_QSF3_MASK) >> G4XS_QSF3_SHIFT)
#define G4XS_GET_QSF4(reg) ((reg & G4XS_QSF4_MASK) >> G4XS_QSF4_SHIFT)
#define G4XS_GET_QSF5(reg) ((reg & G4XS_QSF5_MASK) >> G4XS_QSF5_SHIFT)
/* PWM clock fail flag. */
#define G4XS_GET_CLKF(reg) ((reg & G4XS_CLKF_MASK) >> G4XS_CLKF_SHIFT)
/* Register clear flag. */
#define G4XS_GET_RCF(reg) ((reg & G4XS_RCF_MASK) >> G4XS_RCF_SHIFT)
/* Charge pump flag. */
#define G4XS_GET_CPF(reg) ((reg & G4XS_CPF_MASK) >> G4XS_CPF_SHIFT)

/* CH1 status output address. */
#define G4XS_SO_CH1_STATUS_ADDR 0x2000U

/* CH2 status output address. */
#define G4XS_SO_CH2_STATUS_ADDR 0x3000U

/* CH3 status output address. */
#define G4XS_SO_CH3_STATUS_ADDR 0x4000U

/* CH4 status output address. */
#define G4XS_SO_CH4_STATUS_ADDR 0x5000U

/* CH5 status output address. */
#define G4XS_SO_CH5_STATUS_ADDR 0x6000U

/* Common for all CHx status output registers. */
#define G4XS_OLOFFX_MASK 0x0001
#define G4XS_OLONX_MASK 0x0002
#define G4XS_OC0X_MASK 0x0004
#define G4XS_OC1X_MASK 0x0008
#define G4XS_OC2X_MASK 0x0010
#define G4XS_OTWX_MASK 0x0020
#define G4XS_OTSX_MASK 0x0040

#define G4XS_OLOFFX_SHIFT 0x00
#define G4XS_OLONX_SHIFT 0x01
#define G4XS_OC0X_SHIFT 0x02
#define G4XS_OC1X_SHIFT 0x03
#define G4XS_OC2X_SHIFT 0x04
#define G4XS_OTWX_SHIFT 0x05
#define G4XS_OTSX_SHIFT 0x06

/* CHx status registers getters. */
/* Open load in off state status. */
#define G4XS_GET_OLOFFX(reg)((reg & G4XS_OLOFFX_MASK) >> G4XS_OLOFFX_SHIFT)
/* Open load in on state status. */
#define G4XS_GET_OLONX(reg) ((reg & G4XS_OLONX_MASK) >> G4XS_OLONX_SHIFT)
/* Over current status (see table in datasheet to interpret values). */
#define G4XS_GET_OCX(reg) ((reg & (G4XS_OC0X_MASK | G4XS_OC1X_MASK | G4XS_OC2X_MASK)) >> G4XS_OC0X_SHIFT)
/* Over temperature warning. */
#define G4XS_GET_OTWX(reg) ((reg & G4XS_OTWX_MASK) >> G4XS_OTWX_SHIFT)
/* Over temperature shutdown. */
#define G4XS_GET_OTSX(reg) ((reg & G4XS_OTSX_MASK) >> G4XS_OTSX_SHIFT)

/* Device status output address. */
#define G4XS_SO_DEVICE_STATUS_ADDR 0x7000U

#define G4XS_ILIMP_MASK 0x0001
#define G4XS_SPIF_MASK 0x0002
#define G4XS_UVF_MASK 0x0004
#define G4XS_OVF_MASK 0x0008
#define G4XS_TMF_MASK 0x0010

#define G4XS_ILIMP_SHIFT 0x00
#define G4XS_SPIF_SHIFT 0x01
#define G4XS_UVF_SHIFT 0x02
#define G4XS_OVF_SHIFT 0x03
#define G4XS_TMF_SHIFT 0x04

/* Device status register getters. */
/* Status of LIMP input after de-glitcher. */
#define G4XS_GET_ILIMP(reg) ((reg & G4XS_ILIMP_MASK) >> G4XS_ILIMP_SHIFT)
/* SPI fail flag. */
#define G4XS_GET_SPIF(reg) ((reg & G4XS_SPIF_MASK) >> G4XS_SPIF_SHIFT)
/* Under voltage flag. */
#define G4XS_GET_UVF(reg) ((reg & G4XS_UVF_MASK) >> G4XS_UVF_SHIFT)
/* Over voltage flag. */
#define G4XS_GET_OVF(reg) ((reg & G4XS_OVF_MASK) >> G4XS_OVF_SHIFT)
/* Test mode activation flag. */
#define G4XS_GET_TMF(reg) ((reg & G4XS_TMF_MASK) >> G4XS_TMF_SHIFT)

/* Common for Quick status, CHx status and Device status output registers. */
#define G4XS_OLF_MASK 0x0100
#define G4XS_OVLF_MASK 0x0200
#define G4XS_DSF_MASK 0x0400

#define G4XS_OLF_SHIFT 0x08
#define G4XS_OVLF_SHIFT 0x09
#define G4XS_DSF_SHIFT 0x0A

/* Getters. */
/* Open load flag (wired or of all OL signals). */
#define G4XS_GET_OLF(reg) ((reg & G4XS_OLF_MASK) >> G4XS_OLF_SHIFT)
/* Over load flag (wired or of all OC and OTS signals). */
#define G4XS_GET_OVLF(reg) ((reg & G4XS_OVLF_MASK) >> G4XS_OVLF_SHIFT)
/* Device status flag (UVF | OVF | CPF | RCF | CLKF | TMF). */
#define G4XS_GET_DSF(reg) ((reg & G4XS_DSF_MASK) >> G4XS_DSF_SHIFT)

/* IO status output address. */
#define G4XS_SO_IO_STATUS_ADDR 0x8000U

#define G4XS_OUT1_MASK 0x0001
#define G4XS_OUT2_MASK 0x0002
#define G4XS_OUT3_MASK 0x0004
#define G4XS_OUT4_MASK 0x0008
#define G4XS_OUT5_MASK 0x0010
#define G4XS_IIN1_MASK 0x0020
#define G4XS_IIN2_MASK 0x0040
#define G4XS_IIN3_MASK 0x0080
#define G4XS_IIN4_MASK 0x0100
#define G4XS_TOGGLE_MASK 0x0200

#define G4XS_OUT1_SHIFT 0x00
#define G4XS_OUT2_SHIFT 0x01
#define G4XS_OUT3_SHIFT 0x02
#define G4XS_OUT4_SHIFT 0x03
#define G4XS_OUT5_SHIFT 0x04
#define G4XS_IIN1_SHIFT 0x05
#define G4XS_IIN2_SHIFT 0x06
#define G4XS_IIN3_SHIFT 0x07
#define G4XS_IIN4_SHIFT 0x08
#define G4XS_TOGGLE_SHIFT 0x09

/* IO status register getters. */
/* Status of VBAT/2 comparator. */
#define G4XS_GET_OUT1(reg) ((reg & G4XS_OUT1_MASK) >> G4XS_OUT1_SHIFT)
#define G4XS_GET_OUT2(reg) ((reg & G4XS_OUT2_MASK) >> G4XS_OUT2_SHIFT)
#define G4XS_GET_OUT3(reg) ((reg & G4XS_OUT3_MASK) >> G4XS_OUT3_SHIFT)
#define G4XS_GET_OUT4(reg) ((reg & G4XS_OUT4_MASK) >> G4XS_OUT4_SHIFT)
#define G4XS_GET_OUT5(reg) ((reg & G4XS_OUT5_MASK) >> G4XS_OUT5_SHIFT)
/* Status of INx pin after de-glitcher. */
#define G4XS_GET_IIN1(reg) ((reg & G4XS_IIN1_MASK) >> G4XS_IIN1_SHIFT)
#define G4XS_GET_IIN2(reg) ((reg & G4XS_IIN2_MASK) >> G4XS_IIN2_SHIFT)
#define G4XS_GET_IIN3(reg) ((reg & G4XS_IIN3_MASK) >> G4XS_IIN3_SHIFT)
#define G4XS_GET_IIN4(reg) ((reg & G4XS_IIN4_MASK) >> G4XS_IIN4_SHIFT)
/* Status of INx_ON signals (OR of all INx_ON signals). */
#define G4XS_GET_TOGGLE(reg) ((reg & G4XS_TOGGLE_MASK) >> G4XS_TOGGLE_SHIFT)

/* Device ID output address. */
#define G4XS_SO_DEVICE_ID_ADDR 0x9000U

#define G4XS_DEVID0_MASK 0x0001
#define G4XS_DEVID1_MASK 0x0002
#define G4XS_DEVID2_MASK 0x0004
#define G4XS_DEVID3_MASK 0x0008
#define G4XS_DEVID4_MASK 0x0010
#define G4XS_DEVID5_MASK 0x0020
#define G4XS_DEVID6_MASK 0x0040
#define G4XS_DEVID7_MASK 0x0080
#define G4XS_UVF2_MASK 0x0100

#define G4XS_DEVID0_SHIFT 0x00
#define G4XS_DEVID1_SHIFT 0x01
#define G4XS_DEVID2_SHIFT 0x02
#define G4XS_DEVID3_SHIFT 0x03
#define G4XS_DEVID4_SHIFT 0x04
#define G4XS_DEVID5_SHIFT 0x05
#define G4XS_DEVID6_SHIFT 0x06
#define G4XS_DEVID7_SHIFT 0x07
#define G4XS_UVF2_SHIFT 0x08

/* Device ID register getters. */
#define G4XS_GET_DEV_TYPE(reg) (reg & 0x0003)
#define G4XS_GET_DEV_FAMILY(reg) ((reg & 0x0018) >> G4XS_DEVID3_SHIFT)
#define G4XS_GET_DEV_STATUS(reg) ((reg & 0x00E0) >> G4XS_DEVID5_SHIFT)

#define G4XS_GET_UVF2(reg) ((reg & G4XS_UVF2_MASK) >> G4XS_UVF2_SHIFT)

/* Common for all output registers. */
#define G4XS_FM_MASK 0x0800
#define G4XS_FM_SHIFT 0x0B

/* Getters. */
/* Fail mode flag. */
#define G4XS_GET_FM(reg) ((reg & G4XS_FM_MASK) >> G4XS_FM_SHIFT)

/* Test mode output address. */
#define G4XS_SO_TEST_MODE_ADDR 0xF000U

#endif

