// SPDX-License-Identifier: GPL-2.0-only
//
// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>

#include <linux/crc8.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>

#define DRV_NAME			"pinephone-keyboard"

#define PPKB_CRC8_POLYNOMIAL		0x07

#define PPKB_DEVICE_ID_HI		0x00
#define PPKB_DEVICE_ID_HI_VALUE			'K'
#define PPKB_DEVICE_ID_LO		0x01
#define PPKB_DEVICE_ID_LO_VALUE			'B'
#define PPKB_FW_REVISION		0x02
#define PPKB_FW_FEATURES		0x03
#define PPKB_MATRIX_SIZE		0x06
#define PPKB_SCAN_CRC			0x07
#define PPKB_SCAN_DATA			0x08
#define PPKB_SYS_CONFIG			0x20
#define PPKB_SYS_CONFIG_DISABLE_SCAN		BIT(0)
#define PPKB_SYS_SMBUS_COMMAND		0x21
#define PPKB_SYS_SMBUS_DATA		0x22
#define PPKB_SYS_COMMAND		0x23
#define PPKB_SYS_COMMAND_SMBUS_READ		0x91
#define PPKB_SYS_COMMAND_SMBUS_WRITE		0xa1

#define PPKB_ROWS			6
#define PPKB_COLS			12

/* Size of the scan buffer, including the CRC byte at the beginning. */
#define PPKB_BUF_LEN			(1 + PPKB_COLS)

static const uint32_t ppkb_keymap[] = {
	KEY(0,  0, KEY_ESC),
	KEY(0,  1, KEY_1),
	KEY(0,  2, KEY_2),
	KEY(0,  3, KEY_3),
	KEY(0,  4, KEY_4),
	KEY(0,  5, KEY_5),
	KEY(0,  6, KEY_6),
	KEY(0,  7, KEY_7),
	KEY(0,  8, KEY_8),
	KEY(0,  9, KEY_9),
	KEY(0, 10, KEY_0),
	KEY(0, 11, KEY_BACKSPACE),

	KEY(1,  0, KEY_TAB),
	KEY(1,  1, KEY_Q),
	KEY(1,  2, KEY_W),
	KEY(1,  3, KEY_E),
	KEY(1,  4, KEY_R),
	KEY(1,  5, KEY_T),
	KEY(1,  6, KEY_Y),
	KEY(1,  7, KEY_U),
	KEY(1,  8, KEY_I),
	KEY(1,  9, KEY_O),
	KEY(1, 10, KEY_P),
	KEY(1, 11, KEY_ENTER),

	KEY(2,  0, KEY_LEFTMETA),
	KEY(2,  1, KEY_A),
	KEY(2,  2, KEY_S),
	KEY(2,  3, KEY_D),
	KEY(2,  4, KEY_F),
	KEY(2,  5, KEY_G),
	KEY(2,  6, KEY_H),
	KEY(2,  7, KEY_J),
	KEY(2,  8, KEY_K),
	KEY(2,  9, KEY_L),
	KEY(2, 10, KEY_SEMICOLON),

	KEY(3,  0, KEY_LEFTSHIFT),
	KEY(3,  1, KEY_Z),
	KEY(3,  2, KEY_X),
	KEY(3,  3, KEY_C),
	KEY(3,  4, KEY_V),
	KEY(3,  5, KEY_B),
	KEY(3,  6, KEY_N),
	KEY(3,  7, KEY_M),
	KEY(3,  8, KEY_COMMA),
	KEY(3,  9, KEY_DOT),
	KEY(3, 10, KEY_SLASH),

	KEY(4,  1, KEY_LEFTCTRL),
	KEY(4,  4, KEY_SPACE),
	KEY(4,  6, KEY_APOSTROPHE),
	KEY(4,  8, KEY_RIGHTBRACE),
	KEY(4,  9, KEY_LEFTBRACE),

	KEY(5,  2, KEY_FN),
	KEY(5,  3, KEY_LEFTALT),
	KEY(5,  5, KEY_RIGHTALT),

	/* FN layer */
	KEY(PPKB_ROWS + 0,  0, KEY_FN_ESC),
	KEY(PPKB_ROWS + 0,  1, KEY_F1),
	KEY(PPKB_ROWS + 0,  2, KEY_F2),
	KEY(PPKB_ROWS + 0,  3, KEY_F3),
	KEY(PPKB_ROWS + 0,  4, KEY_F4),
	KEY(PPKB_ROWS + 0,  5, KEY_F5),
	KEY(PPKB_ROWS + 0,  6, KEY_F6),
	KEY(PPKB_ROWS + 0,  7, KEY_F7),
	KEY(PPKB_ROWS + 0,  8, KEY_F8),
	KEY(PPKB_ROWS + 0,  9, KEY_F9),
	KEY(PPKB_ROWS + 0, 10, KEY_F10),
	KEY(PPKB_ROWS + 0, 11, KEY_DELETE),

	KEY(PPKB_ROWS + 1, 10, KEY_PAGEUP),

	KEY(PPKB_ROWS + 2,  0, KEY_SYSRQ),
	KEY(PPKB_ROWS + 2,  9, KEY_PAGEDOWN),
	KEY(PPKB_ROWS + 2, 10, KEY_INSERT),

	KEY(PPKB_ROWS + 3,  0, KEY_LEFTSHIFT),
	KEY(PPKB_ROWS + 3,  8, KEY_HOME),
	KEY(PPKB_ROWS + 3,  9, KEY_UP),
	KEY(PPKB_ROWS + 3, 10, KEY_END),

	KEY(PPKB_ROWS + 4, 1, KEY_LEFTCTRL),
	KEY(PPKB_ROWS + 4, 6, KEY_LEFT),
	KEY(PPKB_ROWS + 4, 8, KEY_RIGHT),
	KEY(PPKB_ROWS + 4, 9, KEY_DOWN),

	KEY(PPKB_ROWS + 5, 3, KEY_LEFTALT),
	KEY(PPKB_ROWS + 5, 5, KEY_RIGHTALT),
};

static const struct matrix_keymap_data ppkb_keymap_data = {
	.keymap		= ppkb_keymap,
	.keymap_size	= ARRAY_SIZE(ppkb_keymap),
};

struct pinephone_keyboard {
	struct i2c_adapter adapter;
	struct input_dev *input;
	u8 buf[2][PPKB_BUF_LEN];
	u8 crc_table[CRC8_TABLE_SIZE];
	u8 fn_state[PPKB_COLS];
	bool buf_swap;
	bool fn_pressed;
};

static int ppkb_adap_smbus_xfer(struct i2c_adapter *adap, u16 addr,
				unsigned short flags, char read_write,
				u8 command, int size,
				union i2c_smbus_data *data)
{
	struct i2c_client *client = adap->algo_data;
	u8 buf[3];
	int ret;

	buf[0] = command;
	buf[1] = data->byte;
	buf[2] = read_write == I2C_SMBUS_READ ? PPKB_SYS_COMMAND_SMBUS_READ
					      : PPKB_SYS_COMMAND_SMBUS_WRITE;

	ret = i2c_smbus_write_i2c_block_data(client, PPKB_SYS_SMBUS_COMMAND,
					     sizeof(buf), buf);
	if (ret)
		return ret;

	/* Read back the command status until it passes or fails. */
	do {
		usleep_range(300, 500);
		ret = i2c_smbus_read_byte_data(client, PPKB_SYS_COMMAND);
	} while (ret == buf[2]);
	if (ret < 0)
		return ret;
	/* Commands return 0x00 on success and 0xff on failure. */
	if (ret)
		return -EIO;

	if (read_write == I2C_SMBUS_READ) {
		ret = i2c_smbus_read_byte_data(client, PPKB_SYS_SMBUS_DATA);
		if (ret < 0)
			return ret;

		data->byte = ret;
	}

	return 0;
}

static u32 ppkg_adap_functionality(struct i2c_adapter *adap)
{
	return I2C_FUNC_SMBUS_BYTE_DATA;
}

static const struct i2c_algorithm ppkb_adap_algo = {
	.smbus_xfer		= ppkb_adap_smbus_xfer,
	.functionality		= ppkg_adap_functionality,
};

static void ppkb_update(struct i2c_client *client)
{
	struct pinephone_keyboard *ppkb = i2c_get_clientdata(client);
	unsigned short *keymap = ppkb->input->keycode;
	int row_shift = get_count_order(PPKB_COLS);
	u8 *old_buf = ppkb->buf[!ppkb->buf_swap];
	u8 *new_buf = ppkb->buf[ppkb->buf_swap];
	int col, crc, ret, row;
	struct device *dev = &client->dev;

	ret = i2c_smbus_read_i2c_block_data(client, PPKB_SCAN_CRC,
					    PPKB_BUF_LEN, new_buf);
	if (ret != PPKB_BUF_LEN) {
		dev_err(dev, "Failed to read scan data: %d\n", ret);
		return;
	}

	crc = crc8(ppkb->crc_table, &new_buf[1], PPKB_COLS, CRC8_INIT_VALUE);
	if (crc != new_buf[0]) {
		dev_err(dev, "Bad scan data (%02x != %02x)\n", crc, new_buf[0]);
		return;
	}

	ppkb->buf_swap = !ppkb->buf_swap;

	for (col = 0; col < PPKB_COLS; ++col) {
		u8 old = old_buf[1 + col];
		u8 new = new_buf[1 + col];
		u8 changed = old ^ new;

		if (!changed)
			continue;

		for (row = 0; row < PPKB_ROWS; ++row) {
			u8 mask = BIT(row);
			u8 value = new & mask;
			unsigned short code;
			bool fn_state;

			if (!(changed & mask))
				continue;

			/*
			 * Save off the FN key state when the key was pressed,
			 * and use that to determine the code during a release.
			 */
			fn_state = value ? ppkb->fn_pressed : ppkb->fn_state[col] & mask;
			if (fn_state)
				ppkb->fn_state[col] ^= mask;

			/* The FN layer is a second set of rows. */
			code = MATRIX_SCAN_CODE(fn_state ? PPKB_ROWS + row : row,
						col, row_shift);
			input_event(ppkb->input, EV_MSC, MSC_SCAN, code);
			input_report_key(ppkb->input, keymap[code], value);
			if (keymap[code] == KEY_FN)
				ppkb->fn_pressed = value;
		}
	}
	input_sync(ppkb->input);
}

static irqreturn_t ppkb_irq_thread(int irq, void *data)
{
	struct i2c_client *client = data;

	ppkb_update(client);

	return IRQ_HANDLED;
}

static int ppkb_set_scan(struct i2c_client *client, bool enable)
{
	struct device *dev = &client->dev;
	int ret, val;

	ret = i2c_smbus_read_byte_data(client, PPKB_SYS_CONFIG);
	if (ret < 0) {
		dev_err(dev, "Failed to read config: %d\n", ret);
		return ret;
	}

	if (enable)
		val = ret & ~PPKB_SYS_CONFIG_DISABLE_SCAN;
	else
		val = ret | PPKB_SYS_CONFIG_DISABLE_SCAN;

	ret = i2c_smbus_write_byte_data(client, PPKB_SYS_CONFIG, val);
	if (ret) {
		dev_err(dev, "Failed to write config: %d\n", ret);
		return ret;
	}

	return 0;
}

static int ppkb_open(struct input_dev *input)
{
	struct i2c_client *client = input_get_drvdata(input);
	int error;

	error = ppkb_set_scan(client, true);
	if (error)
		return error;

	return 0;
}

static void ppkb_close(struct input_dev *input)
{
	struct i2c_client *client = input_get_drvdata(input);

	ppkb_set_scan(client, false);
}

static int ppkb_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	unsigned int phys_rows, phys_cols;
	struct pinephone_keyboard *ppkb;
	u8 info[PPKB_MATRIX_SIZE + 1];
	struct device_node *i2c_bus;
	int ret;
	int error;

	error = devm_regulator_get_enable(dev, "vbat");
	if (error) {
		dev_err(dev, "Failed to get VBAT supply: %d\n", error);
		return error;
	}

	ret = i2c_smbus_read_i2c_block_data(client, 0, sizeof(info), info);
	if (ret != sizeof(info)) {
		error = ret < 0 ? ret : -EIO;
		dev_err(dev, "Failed to read device ID: %d\n", error);
		return error;
	}

	if (info[PPKB_DEVICE_ID_HI] != PPKB_DEVICE_ID_HI_VALUE ||
	    info[PPKB_DEVICE_ID_LO] != PPKB_DEVICE_ID_LO_VALUE) {
		dev_warn(dev, "Unexpected device ID: %#02x %#02x\n",
			 info[PPKB_DEVICE_ID_HI], info[PPKB_DEVICE_ID_LO]);
		return -ENODEV;
	}

	dev_info(dev, "Found firmware version %d.%d features %#x\n",
		 info[PPKB_FW_REVISION] >> 4,
		 info[PPKB_FW_REVISION] & 0xf,
		 info[PPKB_FW_FEATURES]);

	phys_rows = info[PPKB_MATRIX_SIZE] & 0xf;
	phys_cols = info[PPKB_MATRIX_SIZE] >> 4;
	if (phys_rows != PPKB_ROWS || phys_cols != PPKB_COLS) {
		dev_err(dev, "Unexpected keyboard size %ux%u\n",
			phys_rows, phys_cols);
		return -EINVAL;
	}

	/* Disable scan by default to save power. */
	error = ppkb_set_scan(client, false);
	if (error)
		return error;

	ppkb = devm_kzalloc(dev, sizeof(*ppkb), GFP_KERNEL);
	if (!ppkb)
		return -ENOMEM;

	i2c_set_clientdata(client, ppkb);

	i2c_bus = of_get_child_by_name(dev->of_node, "i2c");
	if (i2c_bus) {
		ppkb->adapter.owner = THIS_MODULE;
		ppkb->adapter.algo = &ppkb_adap_algo;
		ppkb->adapter.algo_data = client;
		ppkb->adapter.dev.parent = dev;
		ppkb->adapter.dev.of_node = i2c_bus;
		strscpy(ppkb->adapter.name, DRV_NAME, sizeof(ppkb->adapter.name));

		error = devm_i2c_add_adapter(dev, &ppkb->adapter);
		if (error) {
			dev_err(dev, "Failed to add I2C adapter: %d\n", error);
			return error;
		}
	}

	crc8_populate_msb(ppkb->crc_table, PPKB_CRC8_POLYNOMIAL);

	ppkb->input = devm_input_allocate_device(dev);
	if (!ppkb->input)
		return -ENOMEM;

	input_set_drvdata(ppkb->input, client);

	ppkb->input->name = "PinePhone Keyboard";
	ppkb->input->phys = DRV_NAME "/input0";
	ppkb->input->id.bustype = BUS_I2C;
	ppkb->input->open = ppkb_open;
	ppkb->input->close = ppkb_close;

	input_set_capability(ppkb->input, EV_MSC, MSC_SCAN);
	__set_bit(EV_REP, ppkb->input->evbit);

	error = matrix_keypad_build_keymap(&ppkb_keymap_data, NULL,
					   2 * PPKB_ROWS, PPKB_COLS, NULL,
					   ppkb->input);
	if (error) {
		dev_err(dev, "Failed to build keymap: %d\n", error);
		return error;
	}

	error = input_register_device(ppkb->input);
	if (error) {
		dev_err(dev, "Failed to register input: %d\n", error);
		return error;
	}

	error = devm_request_threaded_irq(dev, client->irq,
					  NULL, ppkb_irq_thread,
					  IRQF_ONESHOT, client->name, client);
	if (error) {
		dev_err(dev, "Failed to request IRQ: %d\n", error);
		return error;
	}

	return 0;
}

static const struct of_device_id ppkb_of_match[] = {
	{ .compatible = "pine64,pinephone-keyboard" },
	{ }
};
MODULE_DEVICE_TABLE(of, ppkb_of_match);

static struct i2c_driver ppkb_driver = {
	.probe		= ppkb_probe,
	.driver		= {
		.name		= DRV_NAME,
		.of_match_table = ppkb_of_match,
	},
};
module_i2c_driver(ppkb_driver);

MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
MODULE_DESCRIPTION("Pine64 PinePhone keyboard driver");
MODULE_LICENSE("GPL");
