Bladeren bron

touch: goodix: add support for dual touch with SPI

Add changes to support secondary touch with SPI on
goodix driver.

Change-Id: I7bf5ac146b2e2f6d616041fa6aedb3a27be24b8f
Signed-off-by: Raviteja Tamatam <[email protected]>
Raviteja Tamatam 2 jaren geleden
bovenliggende
commit
173c930db6

+ 21 - 11
goodix_berlin_driver/goodix_brl_spi.c

@@ -32,7 +32,7 @@
 #define SPI_READ_FLAG   0xF1
 
 static struct platform_device *goodix_pdev;
-struct goodix_bus_interface goodix_spi_bus;
+struct goodix_bus_interface goodix_spi_bus[MAX_SUPPORTED_TOUCH_PANELS];
 
 /**
  * goodix_spi_read_bra- read device register through spi bus
@@ -191,7 +191,7 @@ static void goodix_pdev_release(struct device *dev)
 
 static int goodix_spi_probe(struct spi_device *spi)
 {
-	int ret = 0;
+	int ret = 0, idx;
 
 	ts_info("goodix spi probe in");
 
@@ -210,20 +210,30 @@ static int goodix_spi_probe(struct spi_device *spi)
 	if (ret < 0)
 		return ret;
 
-	goodix_spi_bus.ic_type = ret;
-	goodix_spi_bus.bus_type = GOODIX_BUS_TYPE_SPI;
-	goodix_spi_bus.dev = &spi->dev;
-	if (goodix_spi_bus.ic_type == IC_TYPE_BERLIN_A)
-		goodix_spi_bus.read = goodix_spi_read_bra;
+	idx = goodix_get_touch_type(spi->dev.of_node);
+	if (idx < 0 || idx >= MAX_SUPPORTED_TOUCH_PANELS) {
+		ts_err("unsupported touch type idx:%d", idx);
+		return -ENODEV;
+	}
+
+	goodix_spi_bus[idx].ic_type = ret;
+	goodix_spi_bus[idx].bus_type = GOODIX_BUS_TYPE_SPI;
+	goodix_spi_bus[idx].dev = &spi->dev;
+	if (goodix_spi_bus[idx].ic_type == IC_TYPE_BERLIN_A)
+		goodix_spi_bus[idx].read = goodix_spi_read_bra;
 	else
-		goodix_spi_bus.read = goodix_spi_read;
-	goodix_spi_bus.write = goodix_spi_write;
+		goodix_spi_bus[idx].read = goodix_spi_read;
+	goodix_spi_bus[idx].write = goodix_spi_write;
 	/* ts core device */
 	goodix_pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
 	if (!goodix_pdev)
 		return -ENOMEM;
 
-	goodix_pdev->name = GOODIX_CORE_DRIVER_NAME;
+	if (idx)
+		goodix_pdev->name = GOODIX_CORE_DEVICE_2_NAME;
+	else
+		goodix_pdev->name = GOODIX_CORE_DEVICE_NAME;
+
 	goodix_pdev->id = 0;
 	goodix_pdev->num_resources = 0;
 	/*
@@ -231,7 +241,7 @@ static int goodix_spi_probe(struct spi_device *spi)
 	 * /sys/devices/platfrom/goodix_ts.0
 	 * goodix_pdev->dev.parent = &client->dev;
 	 */
-	goodix_pdev->dev.platform_data = &goodix_spi_bus;
+	goodix_pdev->dev.platform_data = &goodix_spi_bus[idx];
 	goodix_pdev->dev.release = goodix_pdev_release;
 
 	/*

+ 28 - 5
goodix_berlin_driver/goodix_ts_core.c

@@ -60,6 +60,7 @@ static void goodix_register_for_panel_events(struct device_node *dp,
 
 struct goodix_module goodix_modules;
 int core_module_prob_sate = CORE_MODULE_UNPROBED;
+struct mutex goodix_later_init_tmutex;
 
 int goodix_ts_esd_init(struct goodix_ts_core *cd);
 
@@ -2010,6 +2011,14 @@ static int goodix_generic_noti_callback(struct notifier_block *self,
 int goodix_ts_stage2_init(struct goodix_ts_core *cd)
 {
 	int ret;
+	struct goodix_bus_interface *bus_interface;
+	struct device_node *node;
+	bool is_primary;
+
+	bus_interface = cd->bus;
+	node = bus_interface->dev->of_node;
+	is_primary = (goodix_get_touch_type(node) == PRIMARY_TOUCH_IDX) ? 1 : 0;
+
 
 	/* alloc/config/register input device */
 	ret = goodix_ts_input_dev_config(cd);
@@ -2037,7 +2046,7 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
 	ts_info("success register irq");
 
 #if defined(CONFIG_DRM)
-	if (cd->touch_environment && !strcmp(cd->touch_environment, "pvm"))
+	if (is_primary && cd->touch_environment && !strcmp(cd->touch_environment, "pvm"))
 		goodix_register_for_panel_events(cd->bus->dev->of_node, cd);
 
 #elif defined(CONFIG_FB)
@@ -2052,6 +2061,9 @@ skip_goodix_ts_irq_setup:
 	/* create sysfs files */
 	goodix_ts_sysfs_init(cd);
 
+	if (!is_primary)
+		return 0;
+
 	/* create procfs files */
 	goodix_ts_procfs_init(cd);
 
@@ -2110,6 +2122,7 @@ static int goodix_later_init_thread(void *data)
 	struct goodix_ts_core *cd = data;
 	struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
 
+	mutex_lock(&goodix_later_init_tmutex);
 #ifdef CONFIG_ARCH_QTI_VM
 	goto skip_to_stage2_init;
 #endif
@@ -2173,7 +2186,7 @@ skip_to_stage2_init:
 		goto uninit_fw;
 	}
 	cd->init_stage = CORE_INIT_STAGE2;
-
+	mutex_unlock(&goodix_later_init_tmutex);
 	return 0;
 
 uninit_fw:
@@ -2185,6 +2198,7 @@ err_out:
 		kfree(cd->ic_configs[i]);
 		cd->ic_configs[i] = NULL;
 	}
+	mutex_unlock(&goodix_later_init_tmutex);
 	return ret;
 }
 
@@ -2450,9 +2464,13 @@ static int goodix_ts_probe(struct platform_device *pdev)
 	struct device_node *node;
 	bool qts_en = false;
 	struct qts_vendor_data qts_vendor_data;
+	bool is_primary;
 
 	ts_info("goodix_ts_probe IN");
 
+	if (!core_module_prob_sate)
+		mutex_init(&goodix_later_init_tmutex);
+
 	bus_interface = pdev->dev.platform_data;
 	if (!bus_interface) {
 		ts_err("Invalid touch device");
@@ -2460,6 +2478,7 @@ static int goodix_ts_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 	node = bus_interface->dev->of_node;
+	is_primary = (goodix_get_touch_type(node) == PRIMARY_TOUCH_IDX) ? 1 : 0;
 
 #if defined(CONFIG_DRM)
 	ret = goodix_check_dt(node);
@@ -2521,7 +2540,9 @@ static int goodix_ts_probe(struct platform_device *pdev)
 		ret = -EINVAL;
 		goto err_out;
 	}
-	goodix_core_module_init();
+
+	if (is_primary)
+		goodix_core_module_init();
 	/* touch core layer is a platform driver */
 	core_data->pdev = pdev;
 	platform_set_drvdata(pdev, core_data);
@@ -2557,7 +2578,8 @@ skip_to_power_gpio_setup:
 	goodix_ts_register_notifier(&core_data->ts_notifier);
 
 	/* debug node init */
-	goodix_tools_init();
+	if (is_primary)
+		goodix_tools_init();
 
 	core_data->init_stage = CORE_INIT_STAGE1;
 	goodix_modules.core_data = core_data;
@@ -2622,7 +2644,8 @@ static const struct dev_pm_ops dev_pm_ops = {
 #endif
 
 static const struct platform_device_id ts_core_ids[] = {
-	{.name = GOODIX_CORE_DRIVER_NAME},
+	{.name = GOODIX_CORE_DEVICE_NAME},
+	{.name = GOODIX_CORE_DEVICE_2_NAME},
 	{}
 };
 MODULE_DEVICE_TABLE(platform, ts_core_ids);

+ 9 - 0
goodix_berlin_driver/goodix_ts_core.h

@@ -45,6 +45,8 @@
 
 #define GOODIX_CORE_DRIVER_NAME			"goodix_ts"
 #define GOODIX_PEN_DRIVER_NAME			"goodix_ts,pen"
+#define GOODIX_CORE_DEVICE_NAME			"goodix_ts"
+#define GOODIX_CORE_DEVICE_2_NAME		"goodix_ts2"
 #define GOODIX_DRIVER_VERSION			"v1.2.4"
 #define GOODIX_MAX_TOUCH				10
 #define GOODIX_PEN_MAX_PRESSURE			4096
@@ -117,6 +119,12 @@ enum CHECKSUM_MODE {
 	CHECKSUM_MODE_U16_LE,
 };
 
+enum DUAL_TOUCH_TYPE {
+	PRIMARY_TOUCH_IDX,
+	SECONDARY_TOUCH_IDX,
+	MAX_SUPPORTED_TOUCH_PANELS,
+};
+
 #define MAX_SCAN_FREQ_NUM            8
 #define MAX_SCAN_RATE_NUM            8
 #define MAX_FREQ_NUM_STYLUS          8
@@ -689,6 +697,7 @@ int inspect_module_init(void);
 void inspect_module_exit(void);
 int goodix_tools_init(void);
 void goodix_tools_exit(void);
+int goodix_get_touch_type(struct device_node *np);
 
 /* goodix FB test */
 /*

+ 22 - 0
goodix_berlin_driver/goodix_ts_utils.c

@@ -183,3 +183,25 @@ int goodix_get_ic_type(struct device_node *node)
 
 	return ret;
 }
+
+/* get touch type */
+int goodix_get_touch_type(struct device_node *node)
+{
+	const char *touch_type;
+	int ret;
+
+	ret = of_property_read_string(node, "goodix,touch-type", &touch_type);
+	if (ret) {
+		ts_err("No touch type found\n");
+		return -EINVAL;
+	}
+
+	if (!strcmp(touch_type, "primary"))
+		ret = PRIMARY_TOUCH_IDX;
+	else if (!strcmp(touch_type, "secondary"))
+		ret = SECONDARY_TOUCH_IDX;
+	else
+		ret = -EINVAL;
+
+	return ret;
+}

+ 6 - 8
qts/qts_core.c

@@ -1669,10 +1669,14 @@ int qts_client_register(struct qts_vendor_data qts_vendor_data)
 			pr_err("mem allocation failed\n");
 			return -EPROBE_DEFER;
 		}
+		mutex_init(&qts_data_entries->qts_data_entries_lock);
+		qts_data_entries->qts_kset = kset_create_and_add("qts", NULL, kernel_kobj);
+		if (!qts_data_entries->qts_kset) {
+			pr_err("qts kset create failed\n");
+			return -ENOMEM;
+		}
 	}
 
-	mutex_init(&qts_data_entries->qts_data_entries_lock);
-
 	mutex_lock(&qts_data_entries->qts_data_entries_lock);
 
 	if (qts_vendor_data.bus_type == QTS_BUS_TYPE_I2C)
@@ -1708,12 +1712,6 @@ int qts_client_register(struct qts_vendor_data qts_vendor_data)
 
 	qts_trusted_touch_init(qts_data);
 
-	qts_data_entries->qts_kset = kset_create_and_add("qts", NULL, kernel_kobj);
-	if (!qts_data_entries->qts_kset) {
-		pr_err("qts kset create failed\n");
-		return -ENOMEM;
-	}
-
 	mutex_init(&(qts_data->qts_clk_io_ctrl_mutex));
 	if (qts_data->tui_supported)
 		qts_create_sysfs(qts_data);