/*
 *  HID driver for some samsung "special" devices
 *
 *  Copyright (c) 1999 Andreas Gal
 *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
 *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
 *  Copyright (c) 2006-2007 Jiri Kosina
 *  Copyright (c) 2008 Jiri Slaby
 *  Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>
 *
 *
 *  This driver supports several HID devices:
 *
 *  [0419:0001] Samsung IrDA remote controller (reports as Cypress USB Mouse).
 *	various hid report fixups for different variants.
 *
 *  [0419:0600] Creative Desktop Wireless 6000 keyboard/mouse combo
 *	several key mappings used from the consumer usage page
 *	deviate from the USB HUT 1.12 standard.
 *
 */

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 */

#include <linux/device.h>
#include <linux/usb.h>
#include <linux/hid.h>
#include <linux/module.h>

#include "hid-ids.h"

/*
 * There are several variants for 0419:0001:
 *
 * 1. 184 byte report descriptor
 * Vendor specific report #4 has a size of 48 bit,
 * and therefore is not accepted when inspecting the descriptors.
 * As a workaround we reinterpret the report as:
 *   Variable type, count 6, size 8 bit, log. maximum 255
 * The burden to reconstruct the data is moved into user space.
 *
 * 2. 203 byte report descriptor
 * Report #4 has an array field with logical range 0..18 instead of 1..15.
 *
 * 3. 135 byte report descriptor
 * Report #4 has an array field with logical range 0..17 instead of 1..14.
 *
 * 4. 171 byte report descriptor
 * Report #3 has an array field with logical range 0..1 instead of 1..3.
 */
static inline void samsung_irda_dev_trace(struct hid_device *hdev,
		unsigned int rsize)
{
	hid_info(hdev, "fixing up Samsung IrDA %d byte report descriptor\n",
		 rsize);
}

static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int *rsize)
{
	if (*rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
			rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
			rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
			rdesc[182] == 0x40) {
		samsung_irda_dev_trace(hdev, 184);
		rdesc[176] = 0xff;
		rdesc[178] = 0x08;
		rdesc[180] = 0x06;
		rdesc[182] = 0x42;
	} else
	if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
			rdesc[194] == 0x25 && rdesc[195] == 0x12) {
		samsung_irda_dev_trace(hdev, 203);
		rdesc[193] = 0x1;
		rdesc[195] = 0xf;
	} else
	if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
			rdesc[126] == 0x25 && rdesc[127] == 0x11) {
		samsung_irda_dev_trace(hdev, 135);
		rdesc[125] = 0x1;
		rdesc[127] = 0xe;
	} else
	if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
			rdesc[162] == 0x25 && rdesc[163] == 0x01) {
		samsung_irda_dev_trace(hdev, 171);
		rdesc[161] = 0x1;
		rdesc[163] = 0x3;
	}
	return rdesc;
}

#define samsung_kbd_mouse_map_key_clear(c) \
	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))

static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
	unsigned long **bit, int *max)
{
	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
	unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber;

	if (1 != ifnum || HID_UP_CONSUMER != (usage->hid & HID_USAGE_PAGE))
		return 0;

	dbg_hid("samsung wireless keyboard/mouse input mapping event [0x%x]\n",
		usage->hid & HID_USAGE);

	switch (usage->hid & HID_USAGE) {
	/* report 2 */
	case 0x183: samsung_kbd_mouse_map_key_clear(KEY_MEDIA); break;
	case 0x195: samsung_kbd_mouse_map_key_clear(KEY_EMAIL);	break;
	case 0x196: samsung_kbd_mouse_map_key_clear(KEY_CALC); break;
	case 0x197: samsung_kbd_mouse_map_key_clear(KEY_COMPUTER); break;
	case 0x22b: samsung_kbd_mouse_map_key_clear(KEY_SEARCH); break;
	case 0x22c: samsung_kbd_mouse_map_key_clear(KEY_WWW); break;
	case 0x22d: samsung_kbd_mouse_map_key_clear(KEY_BACK); break;
	case 0x22e: samsung_kbd_mouse_map_key_clear(KEY_FORWARD); break;
	case 0x22f: samsung_kbd_mouse_map_key_clear(KEY_FAVORITES); break;
	case 0x230: samsung_kbd_mouse_map_key_clear(KEY_REFRESH); break;
	case 0x231: samsung_kbd_mouse_map_key_clear(KEY_STOP); break;
	default:
		return 0;
	}

	return 1;
}

static int samsung_kbd_input_mapping(struct hid_device *hdev,
	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
	unsigned long **bit, int *max)
{
	if (!(HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE) ||
			HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)))
		return 0;

	dbg_hid("samsung wireless keyboard input mapping event [0x%x]\n",
		usage->hid & HID_USAGE);

	if (HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)) {
		switch (usage->hid & HID_USAGE) {
		set_bit(EV_REP, hi->input->evbit);
		/* Only for UK keyboard */
		/* key found */
#ifdef CONFIG_HID_KK_UPGRADE
		case 0x32:
			samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE);
			break;
		case 0x64:
			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
			break;
#else
		case 0x32:
			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
			break;
		case 0x64:
			samsung_kbd_mouse_map_key_clear(KEY_102ND);
			break;
#endif
		/* Only for BR keyboard */
		case 0x87:
			samsung_kbd_mouse_map_key_clear(KEY_RO);
			break;
		default:
			return 0;
		}
	}

	if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
		switch (usage->hid & HID_USAGE) {
		/* report 2 */
		/* MENU */
		case 0x040:
			samsung_kbd_mouse_map_key_clear(KEY_MENU);
			break;
		case 0x18a:
			samsung_kbd_mouse_map_key_clear(KEY_MAIL);
			break;
		case 0x196:
			samsung_kbd_mouse_map_key_clear(KEY_WWW);
			break;
		case 0x19e:
			samsung_kbd_mouse_map_key_clear(KEY_SCREENLOCK);
			break;
		case 0x221:
			samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
			break;
		case 0x223:
			samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
			break;
		/* RECENTAPPS */
		case 0x301:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY1);
			break;
		/* APPLICATION */
		case 0x302:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY2);
			break;
		/* Voice search */
		case 0x305:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY4);
			break;
		/* QPANEL on/off */
		case 0x306:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY5);
			break;
		/* SIP on/off */
		case 0x307:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY3);
			break;
		/* LANG */
		case 0x308:
			samsung_kbd_mouse_map_key_clear(KEY_LANGUAGE);
			break;
		case 0x30a:
			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
			break;
		case 0x30b:
			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
			break;
		default:
			return 0;
		}
	}

	return 1;
}

static int samsung_gamepad_input_mapping(struct hid_device *hdev,
	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
	unsigned long **bit, int *max)
{
	if (!(HID_UP_BUTTON == (usage->hid & HID_USAGE_PAGE) ||
			HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)))
		return 0;

	dbg_hid("samsung wireless gamepad input mapping event [0x%x], %ld, %ld, [0x%x]\n",
		usage->hid & HID_USAGE, hi->input->evbit[0], hi->input->absbit[0], usage->hid & HID_USAGE_PAGE);

	if (HID_UP_BUTTON == (usage->hid & HID_USAGE_PAGE)) {
		switch (usage->hid & HID_USAGE) {
		case 0x01:
			samsung_kbd_mouse_map_key_clear(BTN_A);
			break;
		case 0x02:
			samsung_kbd_mouse_map_key_clear(BTN_B);
			break;
		case 0x03:
			samsung_kbd_mouse_map_key_clear(BTN_C);
			break;
		case 0x04:
			samsung_kbd_mouse_map_key_clear(BTN_X);
			break;
		case 0x05:
			samsung_kbd_mouse_map_key_clear(BTN_Y);
			break;
		case 0x06:
			samsung_kbd_mouse_map_key_clear(BTN_Z);
			break;
		case 0x07:
			samsung_kbd_mouse_map_key_clear(BTN_TL);
			break;
		case 0x08:
			samsung_kbd_mouse_map_key_clear(BTN_TR);
			break;
		case 0x09:
			samsung_kbd_mouse_map_key_clear(BTN_TL2);
			break;
		case 0x0a:
			samsung_kbd_mouse_map_key_clear(BTN_TR2);
			break;
		case 0x0b:
			samsung_kbd_mouse_map_key_clear(BTN_SELECT);
			break;
		case 0x0c:
			samsung_kbd_mouse_map_key_clear(BTN_START);
			break;
		case 0x0d:
			samsung_kbd_mouse_map_key_clear(BTN_MODE);
			break;
		case 0x0e:
			samsung_kbd_mouse_map_key_clear(BTN_THUMBL);
			break;
		case 0x0f:
			samsung_kbd_mouse_map_key_clear(BTN_THUMBR);
			break;
		case 0x10:
			samsung_kbd_mouse_map_key_clear(BTN_GAME);
			break;
		default:
			return 0;
		}
	}

	if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
		switch (usage->hid & HID_USAGE) {
		case 0x040:
			samsung_kbd_mouse_map_key_clear(KEY_MENU);
			break;
		case 0x223:
			samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
			break;
		case 0x224:
			samsung_kbd_mouse_map_key_clear(KEY_BACK);
			break;

		/* Screen Capture */
		case 0x303:
			samsung_kbd_mouse_map_key_clear(KEY_SYSRQ);
			break;

		default:
			return 0;
		}
	}

	return 1;
}

static int samsung_actionmouse_input_mapping(struct hid_device *hdev,
	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
	unsigned long **bit, int *max)
{

	dbg_hid("samsung wireless actionmouse input mapping event [0x%x], [0x%x], %ld, %ld, [0x%x]\n",
			usage->hid, usage->hid & HID_USAGE, hi->input->evbit[0], hi->input->absbit[0],
			usage->hid & HID_USAGE_PAGE);

	if (((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) && ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON))
		return 0;

	switch (usage->hid & HID_USAGE) {
	case 0x301:
		samsung_kbd_mouse_map_key_clear(KEY_RECENT);
		break;
	default:
		return 0;
	}

	return 1;
}

static int samsung_universal_kbd_input_mapping(struct hid_device *hdev,
	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
	unsigned long **bit, int *max)
{
	if (!(HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE) ||
			HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)))
		return 0;

	dbg_hid("samsung wireless keyboard input mapping event [0x%x]\n",
		usage->hid & HID_USAGE);

	if (HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)) {
		switch (usage->hid & HID_USAGE) {
		set_bit(EV_REP, hi->input->evbit);
		/* Only for UK keyboard */
		/* key found */
#ifdef CONFIG_HID_KK_UPGRADE
		case 0x32:
			samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE);
			break;
		case 0x64:
			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
			break;
#else
		case 0x32:
			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
			break;
		case 0x64:
			samsung_kbd_mouse_map_key_clear(KEY_102ND);
			break;
#endif
		/* Only for BR keyboard */
		case 0x87:
			samsung_kbd_mouse_map_key_clear(KEY_RO);
			break;
		default:
			return 0;
		}
	}

	if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
		switch (usage->hid & HID_USAGE) {
		/* report 2 */
		/* MENU */
		case 0x040:
			samsung_kbd_mouse_map_key_clear(KEY_MENU);
			break;
		case 0x18a:
			samsung_kbd_mouse_map_key_clear(KEY_MAIL);
			break;
		case 0x196:
			samsung_kbd_mouse_map_key_clear(KEY_WWW);
			break;
		case 0x19e:
			samsung_kbd_mouse_map_key_clear(KEY_SCREENLOCK);
			break;
		case 0x221:
			samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
			break;
		case 0x223:
			samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
			break;
		/* RECENTAPPS */
		case 0x301:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY1);
			break;
		/* APPLICATION */
		case 0x302:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY2);
			break;
		/* Voice search */
		case 0x305:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY4);
			break;
		/* QPANEL on/off */
		case 0x306:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY5);
			break;
		/* SIP on/off */
		case 0x307:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY3);
			break;
		/* LANG */
		case 0x308:
			samsung_kbd_mouse_map_key_clear(KEY_LANGUAGE);
			break;
		case 0x30a:
			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
			break;
		case 0x070:
			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
			break;
		case 0x30b:
			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
			break;
		case 0x06f:
			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
			break;
		/* S-Finder */
		case 0x304:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY7);
			break;
		/* Screen Capture */
		case 0x303:
			samsung_kbd_mouse_map_key_clear(KEY_SYSRQ);
			break;
		/* Multi Window */
		case 0x309:
			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY9);
			break;
		/* HotKey App 1 */
		case 0x071:
			samsung_kbd_mouse_map_key_clear(BTN_HOTKEY_APP1);
			break;
		/* HotKey App 2 */
		case 0x072:
			samsung_kbd_mouse_map_key_clear(BTN_HOTKEY_APP2);
			break;
		/* HotKey App 3 */
		case 0x073:
			samsung_kbd_mouse_map_key_clear(BTN_HOTKEY_APP3);
			break;
		/* Dex */
		case 0x06e:
			samsung_kbd_mouse_map_key_clear(KEY_DEX_ON);
			break;
		default:
			return 0;
		}
	}

	return 1;
}

static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
	unsigned int *rsize)
{
	if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)
		rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize);
	return rdesc;
}

static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,
	struct hid_field *field, struct hid_usage *usage,
	unsigned long **bit, int *max)
{
	int ret = 0;

	if (USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE == hdev->product)
		ret = samsung_kbd_mouse_input_mapping(hdev,
			hi, field, usage, bit, max);
	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD)
		ret = samsung_kbd_input_mapping(hdev,
			hi, field, usage, bit, max);
	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD)
		ret = samsung_gamepad_input_mapping(hdev,
			hi, field, usage, bit, max);
	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE)
		ret = samsung_actionmouse_input_mapping(hdev,
			hi, field, usage, bit, max);
	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD)
		ret = samsung_universal_kbd_input_mapping(hdev,
			hi, field, usage, bit, max);
	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD)
		ret = samsung_universal_kbd_input_mapping(hdev,
			hi, field, usage, bit, max);

	return ret;
}

static int samsung_probe(struct hid_device *hdev,
		const struct hid_device_id *id)
{
	int ret;
	unsigned int cmask = HID_CONNECT_DEFAULT;

	if (!(hid_is_usb(hdev) || hdev->bus == BUS_BLUETOOTH))
		return -EINVAL;

	ret = hid_parse(hdev);
	if (ret) {
		hid_err(hdev, "parse failed\n");
		goto err_free;
	}

	if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) {
		if (hdev->rsize == 184) {
			/* disable hidinput, force hiddev */
			cmask = (cmask & ~HID_CONNECT_HIDINPUT) |
				HID_CONNECT_HIDDEV_FORCE;
		}
	}

	ret = hid_hw_start(hdev, cmask);
	if (ret) {
		hid_err(hdev, "hw start failed\n");
		goto err_free;
	}

	return 0;
err_free:
	return ret;
}

static const struct hid_device_id samsung_devices[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD) },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD) },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE) },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD) },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD) },
	{ }
};
MODULE_DEVICE_TABLE(hid, samsung_devices);

static struct hid_driver samsung_driver = {
	.name = "samsung",
	.id_table = samsung_devices,
	.report_fixup = samsung_report_fixup,
	.input_mapping = samsung_input_mapping,
	.probe = samsung_probe,
};
module_hid_driver(samsung_driver);

MODULE_LICENSE("GPL");
