[PATCH 2/3] Input: himax_hx83112b - Add HX83112A support

Luca Weiss <[email protected]>
Newsgroups org.kernel.vger.phone-devel,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-input,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The HX83112A touch controller works nearly identical to other supported
chips, we just need a small dance before we can start using the
touchscreen.

For that a new 'init' callback is introduced to facilitate that.

Assisted-by: Gemini:gemini-3.1-pro
Signed-off-by: Luca Weiss <[email protected]>
---
 drivers/input/touchscreen/himax_hx83112b.c | 46 ++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c
index 0aa67dfacbad..cc8b904d88e6 100644
--- a/drivers/input/touchscreen/himax_hx83112b.c
+++ b/drivers/input/touchscreen/himax_hx83112b.c
@@ -62,6 +62,7 @@ struct himax_ts_data;
 struct himax_chip {
 	u32 id;
 	int (*check_id)(struct himax_ts_data *ts);
+	int (*init)(struct himax_ts_data *ts);
 	int (*read_events)(struct himax_ts_data *ts, struct himax_event *event,
 			   size_t length);
 };
@@ -364,6 +365,12 @@ static int himax_probe(struct i2c_client *client)
 			return error;
 	}
 
+	if (ts->chip->init) {
+		error = ts->chip->init(ts);
+		if (error)
+			return error;
+	}
+
 	error = himax_input_register(ts);
 	if (error)
 		return error;
@@ -395,10 +402,47 @@ static int himax_resume(struct device *dev)
 
 static DEFINE_SIMPLE_DEV_PM_OPS(himax_pm_ops, himax_suspend, himax_resume);
 
+static int hx83112a_init(struct himax_ts_data *ts)
+{
+	int error;
+	u32 buf[2];
+
+	/*
+	 * By default, the chip boots into safe mode. We clear the FW ISR
+	 * register and perform a second hardware reset to boot normally.
+	 */
+	buf[0] = 0x9000005c;
+	buf[1] = 0x00000000;
+	error = regmap_bulk_write(ts->regmap, HIMAX_AHB_ADDR_BYTE_0, buf, 2);
+	if (error)
+		return error;
+
+	himax_reset(ts);
+
+	/* Give the MCU time to reload firmware */
+	msleep(100);
+
+	/* Enable the touch algorithm */
+	buf[0] = 0x1000748c;
+	buf[1] = 0xa55aa55a;
+	error = regmap_bulk_write(ts->regmap, HIMAX_AHB_ADDR_BYTE_0, buf, 2);
+	if (error)
+		return error;
+
+	return 0;
+}
+
 static const struct himax_chip hx83100a_chip = {
 	.read_events = hx83100a_read_events,
 };
 
+static const struct himax_chip hx83112a_chip = {
+	.id = 0x83112a,
+	.check_id = himax_check_product_id,
+	.init = hx83112a_init,
+	.read_events = himax_read_events,
+};
+
 static const struct himax_chip hx83112b_chip = {
 	.id = 0x83112b,
 	.check_id = himax_check_product_id,
@@ -407,6 +451,7 @@ static const struct himax_chip hx83112b_chip = {
 
 static const struct i2c_device_id himax_ts_id[] = {
 	{ .name = "hx83100a", .driver_data = (kernel_ulong_t)&hx83100a_chip },
+	{ .name = "hx83112a", .driver_data = (kernel_ulong_t)&hx83112a_chip },
 	{ .name = "hx83112b", .driver_data = (kernel_ulong_t)&hx83112b_chip },
 	{ /* sentinel */ }
 };
@@ -415,6 +460,7 @@ MODULE_DEVICE_TABLE(i2c, himax_ts_id);
 #ifdef CONFIG_OF
 static const struct of_device_id himax_of_match[] = {
 	{ .compatible = "himax,hx83100a", .data = &hx83100a_chip },
+	{ .compatible = "himax,hx83112a", .data = &hx83112a_chip },
 	{ .compatible = "himax,hx83112b", .data = &hx83112b_chip },
 	{ /* sentinel */ }
 };

-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.