// SPDX-License-Identifier: GPL-2.0-only
/*
 * HTC Shift touchscreen driver
 *
 * Copyright (C) 2008 Pau Oliva Fora <pof@eslack.org>
 */

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/isa.h>
#include <linux/ioport.h>
#include <linux/dmi.h>

MODULE_AUTHOR("Pau Oliva Fora <pau@eslack.org>");
MODULE_DESCRIPTION("HTC Shift touchscreen driver");
MODULE_LICENSE("GPL");

#define HTCPEN_PORT_IRQ_CLEAR	0x068
#define HTCPEN_PORT_INIT	0x06c
#define HTCPEN_PORT_INDEX	0x0250
#define HTCPEN_PORT_DATA	0x0251
#define HTCPEN_IRQ		3

#define DEVICE_ENABLE		0xa2
#define DEVICE_DISABLE		0xa3

#define X_INDEX			3
#define Y_INDEX			5
#define TOUCH_INDEX		0xb
#define LSB_XY_INDEX		0xc
#define X_AXIS_MAX		2040
#define Y_AXIS_MAX		2040

static bool invert_x;
module_param(invert_x, bool, 0644);
MODULE_PARM_DESC(invert_x, "If set, X axis is inverted");
static bool invert_y;
module_param(invert_y, bool, 0644);
MODULE_PARM_DESC(invert_y, "If set, Y axis is inverted");

static irqreturn_t htcpen_interrupt(int irq, void *handle)
{
	struct input_dev *htcpen_dev = handle;
	unsigned short x, y, xy;

	/* 0 = press; 1 = release */
	outb_p(TOUCH_INDEX, HTCPEN_PORT_INDEX);

	if (inb_p(HTCPEN_PORT_DATA)) {
		input_report_key(htcpen_dev, BTN_TOUCH, 0);
	} else {
		outb_p(X_INDEX, HTCPEN_PORT_INDEX);
		x = inb_p(HTCPEN_PORT_DATA);

		outb_p(Y_INDEX, HTCPEN_PORT_INDEX);
		y = inb_p(HTCPEN_PORT_DATA);

		outb_p(LSB_XY_INDEX, HTCPEN_PORT_INDEX);
		xy = inb_p(HTCPEN_PORT_DATA);

		/* get high resolution value of X and Y using LSB */
		x = X_AXIS_MAX - ((x * 8) + ((xy >> 4) & 0xf));
		y = (y * 8) + (xy & 0xf);
		if (invert_x)
			x = X_AXIS_MAX - x;
		if (invert_y)
			y = Y_AXIS_MAX - y;

		if (x != X_AXIS_MAX && x != 0) {
			input_report_key(htcpen_dev, BTN_TOUCH, 1);
			input_report_abs(htcpen_dev, ABS_X, x);
			input_report_abs(htcpen_dev, ABS_Y, y);
		}
	}

	input_sync(htcpen_dev);

	inb_p(HTCPEN_PORT_IRQ_CLEAR);

	return IRQ_HANDLED;
}

static int htcpen_open(struct input_dev *dev)
{
	outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT);

	return 0;
}

static void htcpen_close(struct input_dev *dev)
{
	outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT);
	synchronize_irq(HTCPEN_IRQ);
}

static int htcpen_isa_probe(struct device *dev, unsigned int id)
{
	struct input_dev *htcpen_dev;
	int err = -EBUSY;

	if (!request_region(HTCPEN_PORT_IRQ_CLEAR, 1, "htcpen")) {
		printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
			HTCPEN_PORT_IRQ_CLEAR);
		goto request_region1_failed;
	}

	if (!request_region(HTCPEN_PORT_INIT, 1, "htcpen")) {
		printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
			HTCPEN_PORT_INIT);
		goto request_region2_failed;
	}

	if (!request_region(HTCPEN_PORT_INDEX, 2, "htcpen")) {
		printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
			HTCPEN_PORT_INDEX);
		goto request_region3_failed;
	}

	htcpen_dev = input_allocate_device();
	if (!htcpen_dev) {
		printk(KERN_ERR "htcpen: can't allocate device\n");
		err = -ENOMEM;
		goto input_alloc_failed;
	}

	htcpen_dev->name = "HTC Shift EC TouchScreen";
	htcpen_dev->id.bustype = BUS_ISA;

	htcpen_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
	htcpen_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
	input_set_abs_params(htcpen_dev, ABS_X, 0, X_AXIS_MAX, 0, 0);
	input_set_abs_params(htcpen_dev, ABS_Y, 0, Y_AXIS_MAX, 0, 0);

	htcpen_dev->open = htcpen_open;
	htcpen_dev->close = htcpen_close;

	err = request_irq(HTCPEN_IRQ, htcpen_interrupt, 0, "htcpen",
			htcpen_dev);
	if (err) {
		printk(KERN_ERR "htcpen: irq busy\n");
		goto request_irq_failed;
	}

	inb_p(HTCPEN_PORT_IRQ_CLEAR);

	err = input_register_device(htcpen_dev);
	if (err)
		goto input_register_failed;

	dev_set_drvdata(dev, htcpen_dev);

	return 0;

 input_register_failed:
	free_irq(HTCPEN_IRQ, htcpen_dev);
 request_irq_failed:
	input_free_device(htcpen_dev);
 input_alloc_failed:
	release_region(HTCPEN_PORT_INDEX, 2);
 request_region3_failed:
	release_region(HTCPEN_PORT_INIT, 1);
 request_region2_failed:
	release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
 request_region1_failed:
	return err;
}

static int htcpen_isa_remove(struct device *dev, unsigned int id)
{
	struct input_dev *htcpen_dev = dev_get_drvdata(dev);

	input_unregister_device(htcpen_dev);

	free_irq(HTCPEN_IRQ, htcpen_dev);

	release_region(HTCPEN_PORT_INDEX, 2);
	release_region(HTCPEN_PORT_INIT, 1);
	release_region(HTCPEN_PORT_IRQ_CLEAR, 1);

	return 0;
}

#ifdef CONFIG_PM
static int htcpen_isa_suspend(struct device *dev, unsigned int n,
				pm_message_t state)
{
	outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT);

	return 0;
}

static int htcpen_isa_resume(struct device *dev, unsigned int n)
{
	outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT);

	return 0;
}
#endif

static struct isa_driver htcpen_isa_driver = {
	.probe		= htcpen_isa_probe,
	.remove		= htcpen_isa_remove,
#ifdef CONFIG_PM
	.suspend	= htcpen_isa_suspend,
	.resume		= htcpen_isa_resume,
#endif
	.driver = {
		.owner	= THIS_MODULE,
		.name	= "htcpen",
	}
};

static const struct dmi_system_id htcshift_dmi_table[] __initconst = {
	{
		.ident = "Shift",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "High Tech Computer Corp"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Shift"),
		},
	},
	{ }
};
MODULE_DEVICE_TABLE(dmi, htcshift_dmi_table);

static int __init htcpen_isa_init(void)
{
	if (!dmi_check_system(htcshift_dmi_table))
		return -ENODEV;

	return isa_register_driver(&htcpen_isa_driver, 1);
}

static void __exit htcpen_isa_exit(void)
{
	isa_unregister_driver(&htcpen_isa_driver);
}

module_init(htcpen_isa_init);
module_exit(htcpen_isa_exit);
