diff --git a/drivers/input/touchscreen/zinitix.c b/drivers/input/touchscreen/zinitix.c
index ea807b972f26..440ffc7c9b32 100644
--- a/drivers/input/touchscreen/zinitix.c
+++ b/drivers/input/touchscreen/zinitix.c
@@ -34,6 +34,8 @@
 #define ZINITIX_DEBUG_REG			0x0115 /* 0~7 */
 
 #define ZINITIX_TOUCH_MODE			0x0010
+#define ZINITIX_MODE_TOUCH_POINT		0x02
+#define ZINITIX_MODE_CALIBRATION		0x07
 #define ZINITIX_CHIP_REVISION			0x0011
 #define ZINITIX_CHIP_BT404			0x4040
 #define ZINITIX_CHIP_BT532			0x5320
@@ -49,7 +51,11 @@
 
 #define ZINITIX_DATA_VERSION_REG		0x0013
 #define ZINITIX_SUPPORTED_FINGER_NUM		0x0015
-#define ZINITIX_EEPROM_INFO			0x0018
+
+#define BT4X2_EEPROM_INFO			0x0014
+#define BT4X3_EEPROM_INFO			0x0018
+#define ZINITIX_EEPROM_HW_CALIB			BIT(0)
+
 #define ZINITIX_INITIAL_TOUCH_MODE		0x0019
 
 #define ZINITIX_TOTAL_NUMBER_OF_X		0x0060
@@ -57,6 +63,8 @@
 
 #define ZINITIX_DELAY_RAW_FOR_HOST		0x007f
 
+#define BT4X2_EEPROM_INFO_REG			0x00aa
+
 #define ZINITIX_BUTTON_SUPPORTED_NUM		0x00B0
 #define ZINITIX_BUTTON_SENSITIVITY		0x00B2
 #define ZINITIX_DUMMY_BUTTON_SENSITIVITY	0X00C8
@@ -75,8 +83,6 @@
 
 #define ZINITIX_RAWDATA_REG			0x0200
 
-#define ZINITIX_EEPROM_INFO_REG			0x0018
-
 #define ZINITIX_INT_ENABLE_FLAG			0x00f0
 #define ZINITIX_PERIODICAL_INTERRUPT_INTERVAL	0x00f1
 
@@ -120,7 +126,6 @@
 #define SUB_BIT_UPDATE				BIT(4)
 #define SUB_BIT_WAIT				BIT(5)
 
-#define DEFAULT_TOUCH_POINT_MODE		2
 #define MAX_SUPPORTED_FINGER_NUM		5
 
 #define CHIP_ON_DELAY				15 // ms
@@ -153,8 +158,33 @@ struct bt541_ts_data {
 	u16 chip_revision;
 	u16 firmware_version;
 	u16 regdata_version;
+	u16 eeprom_info_reg;
 };
 
+static bool zinitix_is_4x2(struct bt541_ts_data *bt541)
+{
+	u16 ver;
+
+	/* The revision is the high nybbles so shift down */
+	ver = bt541->chip_revision >> 4;
+	/* Skip middle digit */
+	ver &= 0xf0f;
+
+	return (ver == 0x402);
+}
+
+static bool zinitix_is_4x3_and_above(struct bt541_ts_data *bt541)
+{
+	u16 ver;
+
+	/* The revision is the high nybbles so shift down */
+	ver = bt541->chip_revision >> 4;
+	/* Skip middle digit */
+	ver &= 0xf0f;
+
+	return (ver >= 0x403);
+}
+
 static int zinitix_read_data(struct i2c_client *client,
 			     u16 reg, void *values, size_t length)
 {
@@ -209,12 +239,92 @@ static u16 zinitix_get_u16_reg(struct bt541_ts_data *bt541, u16 vreg)
         return le16_to_cpu(val);
 }
 
+static int zinitix_calibrate(struct bt541_ts_data *bt541)
+{
+	struct i2c_client *client = bt541->client;
+	int maxsec = 10;
+	int error;
+	u16 val;
+
+	dev_info(bt541->dev, "HW calibration - calibrating\n");
+
+	error = zinitix_write_u16(client, ZINITIX_TOUCH_MODE,
+				  ZINITIX_MODE_CALIBRATION);
+	if (error)
+		return error;
+	error = zinitix_write_cmd(client, ZINITIX_CALIBRATE_CMD);
+	if (error)
+		return error;
+	error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
+	if (error)
+		return error;
+	msleep(1);
+	error = zinitix_write_cmd(client, ZINITIX_CLEAR_INT_STATUS_CMD);
+	if (error)
+		return error;
+
+	/* Wait for hardware calibration to commence */
+	do {
+		msleep(1000);
+		val = zinitix_get_u16_reg(bt541, bt541->eeprom_info_reg);
+		maxsec --;
+	} while ((val & ZINITIX_EEPROM_HW_CALIB) && maxsec);
+
+	if (!maxsec) {
+		dev_err(bt541->dev, "timeout waiting for HW calibration\n");
+		return -ETIMEDOUT;
+	}
+
+	/* Get out of calibration mode */
+	error = zinitix_write_u16(client, ZINITIX_TOUCH_MODE,
+				  bt541->zinitix_mode);
+	if (error)
+		return error;
+
+	error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);
+	if (error)
+		return error;
+
+	msleep(10);
+
+	error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
+	if (error)
+		return error;
+
+	if (zinitix_is_4x3_and_above(bt541)) {
+		error = zinitix_write_cmd(client, ZINITIX_SAVE_CALIBRATION_CMD);
+		if (error)
+			return error;
+		msleep(500);
+	}
+
+	if (zinitix_is_4x2(bt541)) {
+		error = zinitix_write_cmd(client, ZINITIX_SAVE_STATUS_CMD);
+		if (error)
+			return error;
+		/* Wait for fusing EEPROM */
+		msleep(1000);
+		error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
+		if (error)
+			return error;
+	}
+
+	error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);
+	if (error)
+		return error;
+
+	dev_info(bt541->dev, "HW calibration complete\n");
+
+	return 0;
+}
+
 static int zinitix_init_touch(struct bt541_ts_data *bt541)
 {
 	struct i2c_client *client = bt541->client;
 	int i;
 	int error;
 	static bool read_static = false;
+	u16 val;
 
 	error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
 	if (error) {
@@ -237,9 +347,20 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
 			 "chip revision %04x firmware version %04x regdata version %04x\n",
 			 bt541->chip_revision, bt541->firmware_version,
 			 bt541->regdata_version);
+		if (zinitix_is_4x2(bt541))
+			bt541->eeprom_info_reg = BT4X2_EEPROM_INFO_REG;
+		else
+			bt541->eeprom_info_reg = BT4X3_EEPROM_INFO;
 		read_static = true;
 	}
 
+	val = zinitix_get_u16_reg(bt541, bt541->eeprom_info_reg);
+	if (val & ZINITIX_EEPROM_HW_CALIB) {
+		error = zinitix_calibrate(bt541);
+		if (error)
+			return error;
+	}
+
 	error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);
 	if (error) {
 		dev_err(bt541->dev,
@@ -273,6 +394,11 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
 	if (error)
 		return error;
 
+	/* Software calibration */
+	error = zinitix_write_cmd(client, ZINITIX_CALIBRATE_CMD);
+	if (error)
+		return error;
+
 	error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG,
 				  BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE |
 					BIT_UP);
@@ -584,10 +710,10 @@ static int zinitix_ts_probe(struct i2c_client *client)
 					 &bt541->zinitix_mode);
 	if (error < 0) {
 		/* fall back to mode 2 */
-		bt541->zinitix_mode = DEFAULT_TOUCH_POINT_MODE;
+		bt541->zinitix_mode = ZINITIX_MODE_TOUCH_POINT;
 	}
 
-	if (bt541->zinitix_mode != 2) {
+	if (bt541->zinitix_mode != ZINITIX_MODE_TOUCH_POINT) {
 		/*
 		 * If there are devices that don't support mode 2, support
 		 * for other modes (0, 1) will be needed.
