diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
index a0d4dabf03b8..45a9cb1d4f14 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
@@ -40,6 +40,7 @@ properties:
       - edt,edt-ft5506
       - evervision,ev-ft5726
       - focaltech,ft6236
+      - dfr,dfr0550
 
   reg:
     maxItems: 1
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 06662f2258b1..a3622d6e8e65 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -84,6 +84,7 @@ enum edt_ver {
 	EDT_M12,
 	EV_FT,
 	GENERIC_FT,
+	DFR,
 };
 
 struct edt_reg_addr {
@@ -134,6 +135,7 @@ struct edt_ft5x06_ts_data {
 
 struct edt_i2c_chip_data {
 	int  max_support_points;
+	bool dfr;
 };
 
 static int edt_ft5x06_ts_readwrite(struct i2c_client *client,
@@ -195,6 +197,7 @@ static void edt_ft5x06_process(struct edt_ft5x06_ts_data *tsdata)
 	int i, type, x, y, id;
 	int offset, tplen, datalen, crclen;
 	int error;
+	int num_points;
 
 	switch (tsdata->version) {
 	case EDT_M06:
@@ -202,6 +205,7 @@ static void edt_ft5x06_process(struct edt_ft5x06_ts_data *tsdata)
 		offset = 5; /* where the actual touch data starts */
 		tplen = 4;  /* data comes in so called frames */
 		crclen = 1; /* length of the crc data */
+		datalen = tplen * tsdata->max_support_points + offset + crclen;
 		break;
 
 	case EDT_M09:
@@ -212,6 +216,14 @@ static void edt_ft5x06_process(struct edt_ft5x06_ts_data *tsdata)
 		offset = 3;
 		tplen = 6;
 		crclen = 0;
+		datalen = tplen * tsdata->max_support_points + offset + crclen;
+		break;
+	/* DFR needs to read 1 byte R2 for num points */
+	case DFR:
+		cmd = 0x2;
+		offset = 3;
+		crclen = 0;
+		datalen = 1;
 		break;
 
 	default:
@@ -219,7 +231,6 @@ static void edt_ft5x06_process(struct edt_ft5x06_ts_data *tsdata)
 	}
 
 	memset(rdbuf, 0, sizeof(rdbuf));
-	datalen = tplen * tsdata->max_support_points + offset + crclen;
 
 	error = edt_ft5x06_ts_readwrite(tsdata->client,
 					sizeof(cmd), &cmd,
@@ -242,11 +253,31 @@ static void edt_ft5x06_process(struct edt_ft5x06_ts_data *tsdata)
 
 		if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, datalen))
 			return;
+		num_points = tsdata->max_support_points;
+	} else if (tsdata->version == DFR) {
+		num_points = min(rdbuf[0] & 0xf, tsdata->max_support_points);
+	} else {
+		num_points = min(rdbuf[2] & 0xf, tsdata->max_support_points);
 	}
 
-	for (i = 0; i < tsdata->max_support_points; i++) {
+	for (i = 0; i < num_points; i++) {
 		u8 *buf = &rdbuf[i * tplen + offset];
 
+		/* DFR must read each point in separate transaction */
+		if (tsdata->version == DFR) {
+			cmd = 3+6*i;
+			datalen = 4;
+			buf = rdbuf;
+			error = edt_ft5x06_ts_readwrite(tsdata->client,
+							sizeof(cmd), &cmd,
+							datalen, buf);
+			if (error) {
+				dev_err_ratelimited(dev, "Unable to fetch point data, error: %d\n",
+						    error);
+				return;
+			}
+		}
+
 		type = buf[0] >> 6;
 		/* ignore Reserved events */
 		if (type == TOUCH_EVENT_RESERVED)
@@ -1072,6 +1103,9 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
 		reg_addr->reg_num_x = NO_REGISTER;
 		reg_addr->reg_num_y = NO_REGISTER;
 		break;
+
+	case DFR:
+		break;
 	}
 }
 
@@ -1206,21 +1240,29 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
 	tsdata->input = input;
 	tsdata->factory_mode = false;
 
-	error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
-	if (error) {
-		dev_err(&client->dev, "touchscreen probe failed\n");
-		return error;
+	if (chip_data->dfr) {
+		tsdata->version = DFR;
+		snprintf(tsdata->name, EDT_NAME_LEN, "DFROBOT");
+		fw_version[0] = 0;
+	} else {
+		error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
+		if (error) {
+			dev_err(&client->dev, "touchscreen probe failed\n");
+			return error;
+		}
 	}
 
 	/*
 	 * Dummy read access. EP0700MLP1 returns bogus data on the first
 	 * register read access and ignores writes.
 	 */
-	edt_ft5x06_ts_readwrite(tsdata->client, 2, buf, 2, buf);
+	if (!chip_data->dfr) /* this gets the DFR controller out of sync */
+		edt_ft5x06_ts_readwrite(tsdata->client, 2, buf, 2, buf);
 
 	edt_ft5x06_ts_set_regs(tsdata);
 	edt_ft5x06_ts_get_defaults(&client->dev, tsdata);
-	edt_ft5x06_ts_get_parameters(tsdata);
+	if (!chip_data->dfr)
+		edt_ft5x06_ts_get_parameters(tsdata);
 
 	dev_dbg(&client->dev,
 		"Model \"%s\", Rev. \"%s\", %dx%d sensors\n",
@@ -1423,12 +1465,18 @@ static const struct edt_i2c_chip_data edt_ft6236_data = {
 	.max_support_points = 2,
 };
 
+static const struct edt_i2c_chip_data edt_dfr0550_data = {
+	.max_support_points = 5,
+	.dfr = true,
+};
+
 static const struct i2c_device_id edt_ft5x06_ts_id[] = {
 	{ .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },
 	{ .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data },
 	{ .name = "ev-ft5726", .driver_data = (long)&edt_ft5506_data },
 	/* Note no edt- prefix for compatibility with the ft6236.c driver */
 	{ .name = "ft6236", .driver_data = (long)&edt_ft6236_data },
+	{ .name = "dfr0550", .driver_data = (long)&edt_dfr0550_data },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
@@ -1441,6 +1489,7 @@ static const struct of_device_id edt_ft5x06_of_match[] = {
 	{ .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data },
 	/* Note focaltech vendor prefix for compatibility with ft6236.c */
 	{ .compatible = "focaltech,ft6236", .data = &edt_ft6236_data },
+	{ .compatible = "dfr,dfr0550", .data = &edt_dfr0550_data },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
