/*
 * DF-4966 mask_check — dce110 id_to_offset I2C-pad SDA wrong-bit
 *
 * hw_translate_dce110.c:189-190 assigns
 *     info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;  (0x100)
 * to EVERY GPIO_ID_DDC_DATA line, and en=GPIO_DDC_LINE_I2C_PAD
 * only swaps the offset to mmDC_GPIO_I2CPAD_A (0x4899).  But the DCE11
 * register DC_GPIO_I2CPAD_A defines SCL at bit 0 (0x1) and SDA at bit 1
 * (0x2), unlike the DDCx_A/VGA registers where CLK=bit0/DATA=bit8.
 * The DDC_DATA (SDA) translation for the I2C pad therefore carries a
 * mask for a bit that does not exist in the target register.
 */
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>

#define mmDC_GPIO_DDC1_A		0x4869
#define mmDC_GPIO_I2CPAD_A		0x4899
#define DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK	0x100
#define DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK	0x1
#define DC_GPIO_I2CPAD_A__DC_GPIO_SCL_A_MASK	0x1
#define DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK	0x2
#define DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK	0x100

int main(void)
{
	uint32_t ddc_data_i2cpad_mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
	uint32_t ddc_clk_i2cpad_mask  = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
	uint32_t ddc_data_ddc1_mask   = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;

	printf("register DC_GPIO_I2CPAD_A (0x%x) real fields: SCL=0x%x SDA=0x%x\n",
	       mmDC_GPIO_I2CPAD_A,
	       DC_GPIO_I2CPAD_A__DC_GPIO_SCL_A_MASK,
	       DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK);

	printf("id_to_offset(DDC_DATA, I2C_PAD) mask = 0x%x -> %s\n",
	       ddc_data_i2cpad_mask,
	       ddc_data_i2cpad_mask == DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK ?
	       "correct" :
	       "WRONG: selects bit 8; SDA is bit 1 — reserved-bit write / dead-bit read");
	printf("id_to_offset(DDC_CLOCK, I2C_PAD) mask = 0x%x -> %s\n",
	       ddc_clk_i2cpad_mask,
	       ddc_clk_i2cpad_mask == DC_GPIO_I2CPAD_A__DC_GPIO_SCL_A_MASK ?
	       "correct (by coincidence: DDC CLK bit == SCL bit)" :
	       "wrong");
	printf("control: id_to_offset(DDC_DATA, DDC1) mask = 0x%x vs DC_GPIO_DDC1DATA_A_MASK=0x%x -> %s\n",
	       ddc_data_ddc1_mask, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK,
	       ddc_data_ddc1_mask == DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK ?
	       "correct (shared mask valid for real DDC lines)" : "wrong");

	/*
	 * Consequence: hw_gpio/hw_ddc program the pad via
	 *   REG_UPDATE(DC_GPIO_DDC1_A.. / DC_GPIO_I2CPAD_A, mask, ...)
	 * i.e. read-modify-write of 0x4899 with mask 0x100 — sets/reads an
	 * undefined bit while never touching the real SDA bit (0x2).
	 */
	return 0;
}
