/*
 * Generic linux-input device driver for keyboard devices
 *
 * Copyright (c) 2001 Brian S. Julin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL").
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *
 * References:
 * HP-HIL Technical Reference Manual.  Hewlett Packard Product No. 45918A
 *
 */

#include <linux/hil.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/semaphore.h>
#include <linux/slab.h>
#include <linux/pci_ids.h>

#define PREFIX "HIL KEYB: "
#define HIL_GENERIC_NAME "HIL keyboard"

MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("serio:ty03pr25id00ex*");

#define HIL_KBD_MAX_LENGTH 16

#define HIL_KBD_SET1_UPBIT 0x01
#define HIL_KBD_SET1_SHIFT 1
static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly =
	{ HIL_KEYCODES_SET1 };

#define HIL_KBD_SET2_UPBIT 0x01
#define HIL_KBD_SET2_SHIFT 1
/* Set2 is user defined */

#define HIL_KBD_SET3_UPBIT 0x80
#define HIL_KBD_SET3_SHIFT 0
static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] __read_mostly =
	{ HIL_KEYCODES_SET3 };

static const char hil_language[][16] = { HIL_LOCALE_MAP };

struct hil_kbd {
	struct input_dev *dev;
	struct serio *serio;

	/* Input buffer and index for packets from HIL bus. */
	hil_packet data[HIL_KBD_MAX_LENGTH];
	int idx4; /* four counts per packet */

	/* Raw device info records from HIL bus, see hil.h for fields. */
	char	idd[HIL_KBD_MAX_LENGTH];	/* DID byte and IDD record */
	char	rsc[HIL_KBD_MAX_LENGTH];	/* RSC record */
	char	exd[HIL_KBD_MAX_LENGTH];	/* EXD record */
	char	rnm[HIL_KBD_MAX_LENGTH + 1];	/* RNM record + NULL term. */

	/* Something to sleep around with. */
	struct semaphore sem;
};

/* Process a complete packet after transfer from the HIL */
static void hil_kbd_process_record(struct hil_kbd *kbd)
{
	struct input_dev *dev = kbd->dev;
	hil_packet *data = kbd->data;
	hil_packet p;
	int idx, i, cnt;

	idx = kbd->idx4/4;
	p = data[idx - 1];

	if ((p & ~HIL_CMDCT_POL) ==
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
		goto report;
	if ((p & ~HIL_CMDCT_RPL) ==
	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
		goto report;

	/* Not a poll response.  See if we are loading config records. */
	switch (p & HIL_PKT_DATA_MASK) {
	case HIL_CMD_IDD:
		for (i = 0; i < idx; i++)
			kbd->idd[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_KBD_MAX_LENGTH; i++)
			kbd->idd[i] = 0;
		break;

	case HIL_CMD_RSC:
		for (i = 0; i < idx; i++)
			kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_KBD_MAX_LENGTH; i++)
			kbd->rsc[i] = 0;
		break;

	case HIL_CMD_EXD:
		for (i = 0; i < idx; i++)
			kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_KBD_MAX_LENGTH; i++)
			kbd->exd[i] = 0;
		break;

	case HIL_CMD_RNM:
		for (i = 0; i < idx; i++)
			kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
		for (; i < HIL_KBD_MAX_LENGTH + 1; i++)
			kbd->rnm[i] = '\0';
		break;

	default:
		/* These occur when device isn't present */
		if (p == (HIL_ERR_INT | HIL_PKT_CMD))
			break;
		/* Anything else we'd like to know about. */
		printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
		break;
	}
	goto out;

 report:
	cnt = 1;
	switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) {
	case HIL_POL_CHARTYPE_NONE:
		break;

	case HIL_POL_CHARTYPE_ASCII:
		while (cnt < idx - 1)
			input_report_key(dev, kbd->data[cnt++] & 0x7f, 1);
		break;

	case HIL_POL_CHARTYPE_RSVD1:
	case HIL_POL_CHARTYPE_RSVD2:
	case HIL_POL_CHARTYPE_BINARY:
		while (cnt < idx - 1)
			input_report_key(dev, kbd->data[cnt++], 1);
		break;

	case HIL_POL_CHARTYPE_SET1:
		while (cnt < idx - 1) {
			unsigned int key;
			int up;
			key = kbd->data[cnt++];
			up = key & HIL_KBD_SET1_UPBIT;
			key &= (~HIL_KBD_SET1_UPBIT & 0xff);
			key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT];
			if (key != KEY_RESERVED)
				input_report_key(dev, key, !up);
		}
		break;

	case HIL_POL_CHARTYPE_SET2:
		while (cnt < idx - 1) {
			unsigned int key;
			int up;
			key = kbd->data[cnt++];
			up = key & HIL_KBD_SET2_UPBIT;
			key &= (~HIL_KBD_SET1_UPBIT & 0xff);
			key = key >> HIL_KBD_SET2_SHIFT;
			if (key != KEY_RESERVED)
				input_report_key(dev, key, !up);
		}
		break;

	case HIL_POL_CHARTYPE_SET3:
		while (cnt < idx - 1) {
			unsigned int key;
			int up;
			key = kbd->data[cnt++];
			up = key & HIL_KBD_SET3_UPBIT;
			key &= (~HIL_KBD_SET1_UPBIT & 0xff);
			key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT];
			if (key != KEY_RESERVED)
				input_report_key(dev, key, !up);
		}
		break;
	}
 out:
	kbd->idx4 = 0;
	up(&kbd->sem);
}

static void hil_kbd_process_err(struct hil_kbd *kbd)
{
	printk(KERN_WARNING PREFIX "errored HIL packet\n");
	kbd->idx4 = 0;
	up(&kbd->sem);
}

static irqreturn_t hil_kbd_interrupt(struct serio *serio,
				unsigned char data, unsigned int flags)
{
	struct hil_kbd *kbd;
	hil_packet packet;
	int idx;

	kbd = serio_get_drvdata(serio);
	BUG_ON(kbd == NULL);

	if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) {
		hil_kbd_process_err(kbd);
		return IRQ_HANDLED;
	}
	idx = kbd->idx4/4;
	if (!(kbd->idx4 % 4))
		kbd->data[idx] = 0;
	packet = kbd->data[idx];
	packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8);
	kbd->data[idx] = packet;

	/* Records of N 4-byte hil_packets must terminate with a command. */
	if ((++(kbd->idx4)) % 4)
		return IRQ_HANDLED;
	if ((packet & 0xffff0000) != HIL_ERR_INT) {
		hil_kbd_process_err(kbd);
		return IRQ_HANDLED;
	}
	if (packet & HIL_PKT_CMD)
		hil_kbd_process_record(kbd);
	return IRQ_HANDLED;
}

static void hil_kbd_disconnect(struct serio *serio)
{
	struct hil_kbd *kbd;

	kbd = serio_get_drvdata(serio);
	BUG_ON(kbd == NULL);

	serio_close(serio);
	input_unregister_device(kbd->dev);
	kfree(kbd);
}

static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
{
	struct hil_kbd	*kbd;
	uint8_t		did, *idd;
	int		i;

	kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
	if (!kbd)
		return -ENOMEM;

	kbd->dev = input_allocate_device();
	if (!kbd->dev)
		goto bail0;

	if (serio_open(serio, drv))
		goto bail1;

	serio_set_drvdata(serio, kbd);
	kbd->serio = serio;

	init_MUTEX_LOCKED(&kbd->sem);

	/* Get device info.  MLC driver supplies devid/status/etc. */
	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_IDD);
	down(&kbd->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_RSC);
	down(&kbd->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_RNM);
	down(&kbd->sem);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_EXD);
	down(&kbd->sem);

	up(&kbd->sem);

	did = kbd->idd[0];
	idd = kbd->idd + 1;
	switch (did & HIL_IDD_DID_TYPE_MASK) {
	case HIL_IDD_DID_TYPE_KB_INTEGRAL:
	case HIL_IDD_DID_TYPE_KB_ITF:
	case HIL_IDD_DID_TYPE_KB_RSVD:
	case HIL_IDD_DID_TYPE_CHAR:
		printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n",
			did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]);
		break;
	default:
		goto bail2;
	}

	if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) {
		printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n");
		goto bail2;
	}

	kbd->dev->evbit[0]	= BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
	kbd->dev->ledbit[0]	= BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
		BIT_MASK(LED_SCROLLL);
	kbd->dev->keycodemax	= HIL_KEYCODES_SET1_TBLSIZE;
	kbd->dev->keycodesize	= sizeof(hil_kbd_set1[0]);
	kbd->dev->keycode	= hil_kbd_set1;
	kbd->dev->name		= strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME;
	kbd->dev->phys		= "hpkbd/input0";	/* XXX */

	kbd->dev->id.bustype	= BUS_HIL;
	kbd->dev->id.vendor	= PCI_VENDOR_ID_HP;
	kbd->dev->id.product	= 0x0001; /* TODO: get from kbd->rsc */
	kbd->dev->id.version	= 0x0100; /* TODO: get from kbd->rsc */
	kbd->dev->dev.parent	= &serio->dev;

	for (i = 0; i < 128; i++) {
		set_bit(hil_kbd_set1[i], kbd->dev->keybit);
		set_bit(hil_kbd_set3[i], kbd->dev->keybit);
	}
	clear_bit(0, kbd->dev->keybit);

	input_register_device(kbd->dev);
	printk(KERN_INFO "input: %s, ID: %d\n",
		kbd->dev->name, did);

	serio->write(serio, 0);
	serio->write(serio, 0);
	serio->write(serio, HIL_PKT_CMD >> 8);
	serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */
	down(&kbd->sem);
	up(&kbd->sem);

	return 0;
 bail2:
	serio_close(serio);
	serio_set_drvdata(serio, NULL);
 bail1:
	input_free_device(kbd->dev);
 bail0:
	kfree(kbd);
	return -EIO;
}

static struct serio_device_id hil_kbd_ids[] = {
	{
		.type = SERIO_HIL_MLC,
		.proto = SERIO_HIL,
		.id = SERIO_ANY,
		.extra = SERIO_ANY,
	},
	{ 0 }
};

static struct serio_driver hil_kbd_serio_drv = {
	.driver		= {
		.name	= "hil_kbd",
	},
	.description	= "HP HIL keyboard driver",
	.id_table	= hil_kbd_ids,
	.connect	= hil_kbd_connect,
	.disconnect	= hil_kbd_disconnect,
	.interrupt	= hil_kbd_interrupt
};

static int __init hil_kbd_init(void)
{
	return serio_register_driver(&hil_kbd_serio_drv);
}

static void __exit hil_kbd_exit(void)
{
	serio_unregister_driver(&hil_kbd_serio_drv);
}

module_init(hil_kbd_init);
module_exit(hil_kbd_exit);
