// SPDX-License-Identifier: GPL-2.0+
/*
 *  HID driver for Google Hammer device.
 *
 *  Copyright (c) 2017 Google Inc.
 *  Author: Wei-Ning Huang <wnhuang@google.com>
 */

/*
 * 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/acpi.h>
#include <linux/hid.h>
#include <linux/input/vivaldi-fmap.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_data/cros_ec_commands.h>
#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_device.h>
#include <linux/unaligned.h>

#include "hid-ids.h"
#include "hid-vivaldi-common.h"

/*
 * C(hrome)B(ase)A(ttached)S(witch) - switch exported by Chrome EC and reporting
 * state of the "Whiskers" base - attached or detached. Whiskers USB device also
 * reports position of the keyboard - folded or not. Combining base state and
 * position allows us to generate proper "Tablet mode" events.
 */
struct cbas_ec {
	struct device *dev;	/* The platform device (EC) */
	struct input_dev *input;
	bool base_present;
	bool base_folded;
	struct notifier_block notifier;
};

static struct cbas_ec cbas_ec;
static DEFINE_SPINLOCK(cbas_ec_lock);
static DEFINE_MUTEX(cbas_ec_reglock);

static bool cbas_parse_base_state(const void *data)
{
	u32 switches = get_unaligned_le32(data);

	return !!(switches & BIT(EC_MKBP_BASE_ATTACHED));
}

static int cbas_ec_query_base(struct cros_ec_device *ec_dev, bool get_state,
				  bool *state)
{
	struct ec_params_mkbp_info *params;
	struct cros_ec_command *msg;
	int ret;

	msg = kzalloc(struct_size(msg, data, max(sizeof(u32), sizeof(*params))),
		      GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	msg->command = EC_CMD_MKBP_INFO;
	msg->version = 1;
	msg->outsize = sizeof(*params);
	msg->insize = sizeof(u32);
	params = (struct ec_params_mkbp_info *)msg->data;
	params->info_type = get_state ?
		EC_MKBP_INFO_CURRENT : EC_MKBP_INFO_SUPPORTED;
	params->event_type = EC_MKBP_EVENT_SWITCH;

	ret = cros_ec_cmd_xfer_status(ec_dev, msg);
	if (ret >= 0) {
		if (ret != sizeof(u32)) {
			dev_warn(ec_dev->dev, "wrong result size: %d != %zu\n",
				 ret, sizeof(u32));
			ret = -EPROTO;
		} else {
			*state = cbas_parse_base_state(msg->data);
			ret = 0;
		}
	}

	kfree(msg);

	return ret;
}

static int cbas_ec_notify(struct notifier_block *nb,
			      unsigned long queued_during_suspend,
			      void *_notify)
{
	struct cros_ec_device *ec = _notify;
	unsigned long flags;
	bool base_present;

	if (ec->event_data.event_type == EC_MKBP_EVENT_SWITCH) {
		base_present = cbas_parse_base_state(
					&ec->event_data.data.switches);
		dev_dbg(cbas_ec.dev,
			"%s: base: %d\n", __func__, base_present);

		if (device_may_wakeup(cbas_ec.dev) ||
		    !queued_during_suspend) {

			pm_wakeup_event(cbas_ec.dev, 0);

			spin_lock_irqsave(&cbas_ec_lock, flags);

			/*
			 * While input layer dedupes the events, we do not want
			 * to disrupt the state reported by the base by
			 * overriding it with state reported by the LID. Only
			 * report changes, as we assume that on attach the base
			 * is not folded.
			 */
			if (base_present != cbas_ec.base_present) {
				input_report_switch(cbas_ec.input,
						    SW_TABLET_MODE,
						    !base_present);
				input_sync(cbas_ec.input);
				cbas_ec.base_present = base_present;
			}

			spin_unlock_irqrestore(&cbas_ec_lock, flags);
		}
	}

	return NOTIFY_OK;
}

static __maybe_unused int cbas_ec_resume(struct device *dev)
{
	struct cros_ec_device *ec = dev_get_drvdata(dev->parent);
	bool base_present;
	int error;

	error = cbas_ec_query_base(ec, true, &base_present);
	if (error) {
		dev_warn(dev, "failed to fetch base state on resume: %d\n",
			 error);
	} else {
		spin_lock_irq(&cbas_ec_lock);

		cbas_ec.base_present = base_present;

		/*
		 * Only report if base is disconnected. If base is connected,
		 * it will resend its state on resume, and we'll update it
		 * in hammer_event().
		 */
		if (!cbas_ec.base_present) {
			input_report_switch(cbas_ec.input, SW_TABLET_MODE, 1);
			input_sync(cbas_ec.input);
		}

		spin_unlock_irq(&cbas_ec_lock);
	}

	return 0;
}

static SIMPLE_DEV_PM_OPS(cbas_ec_pm_ops, NULL, cbas_ec_resume);

static void cbas_ec_set_input(struct input_dev *input)
{
	/* Take the lock so hammer_event() does not race with us here */
	spin_lock_irq(&cbas_ec_lock);
	cbas_ec.input = input;
	spin_unlock_irq(&cbas_ec_lock);
}

static int __cbas_ec_probe(struct platform_device *pdev)
{
	struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
	struct input_dev *input;
	bool base_supported;
	int error;

	error = cbas_ec_query_base(ec, false, &base_supported);
	if (error)
		return error;

	if (!base_supported)
		return -ENXIO;

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

	input->name = "Whiskers Tablet Mode Switch";
	input->id.bustype = BUS_HOST;

	input_set_capability(input, EV_SW, SW_TABLET_MODE);

	error = input_register_device(input);
	if (error) {
		dev_err(&pdev->dev, "cannot register input device: %d\n",
			error);
		return error;
	}

	/* Seed the state */
	error = cbas_ec_query_base(ec, true, &cbas_ec.base_present);
	if (error) {
		dev_err(&pdev->dev, "cannot query base state: %d\n", error);
		return error;
	}

	if (!cbas_ec.base_present)
		cbas_ec.base_folded = false;

	dev_dbg(&pdev->dev, "%s: base: %d, folded: %d\n", __func__,
		cbas_ec.base_present, cbas_ec.base_folded);

	input_report_switch(input, SW_TABLET_MODE,
			    !cbas_ec.base_present || cbas_ec.base_folded);

	cbas_ec_set_input(input);

	cbas_ec.dev = &pdev->dev;
	cbas_ec.notifier.notifier_call = cbas_ec_notify;
	error = blocking_notifier_chain_register(&ec->event_notifier,
						 &cbas_ec.notifier);
	if (error) {
		dev_err(&pdev->dev, "cannot register notifier: %d\n", error);
		cbas_ec_set_input(NULL);
		return error;
	}

	device_init_wakeup(&pdev->dev, true);
	return 0;
}

static int cbas_ec_probe(struct platform_device *pdev)
{
	int retval;

	mutex_lock(&cbas_ec_reglock);

	if (cbas_ec.input) {
		retval = -EBUSY;
		goto out;
	}

	retval = __cbas_ec_probe(pdev);

out:
	mutex_unlock(&cbas_ec_reglock);
	return retval;
}

static void cbas_ec_remove(struct platform_device *pdev)
{
	struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);

	mutex_lock(&cbas_ec_reglock);

	blocking_notifier_chain_unregister(&ec->event_notifier,
					   &cbas_ec.notifier);
	cbas_ec_set_input(NULL);

	mutex_unlock(&cbas_ec_reglock);
}

#ifdef CONFIG_ACPI
static const struct acpi_device_id cbas_ec_acpi_ids[] = {
	{ "GOOG000B", 0 },
	{ }
};
MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids);
#endif

#ifdef CONFIG_OF
static const struct of_device_id cbas_ec_of_match[] = {
	{ .compatible = "google,cros-cbas" },
	{ },
};
MODULE_DEVICE_TABLE(of, cbas_ec_of_match);
#endif

static struct platform_driver cbas_ec_driver = {
	.probe = cbas_ec_probe,
	.remove = cbas_ec_remove,
	.driver = {
		.name = "cbas_ec",
		.acpi_match_table = ACPI_PTR(cbas_ec_acpi_ids),
		.of_match_table = of_match_ptr(cbas_ec_of_match),
		.pm = &cbas_ec_pm_ops,
	},
};

#define MAX_BRIGHTNESS 100

struct hammer_kbd_leds {
	struct led_classdev cdev;
	struct hid_device *hdev;
	u8 buf[2] ____cacheline_aligned;
};

static int hammer_kbd_brightness_set_blocking(struct led_classdev *cdev,
		enum led_brightness br)
{
	struct hammer_kbd_leds *led = container_of(cdev,
						   struct hammer_kbd_leds,
						   cdev);
	int ret;

	led->buf[0] = 0;
	led->buf[1] = br;

	/*
	 * Request USB HID device to be in Full On mode, so that sending
	 * hardware output report and hardware raw request won't fail.
	 */
	ret = hid_hw_power(led->hdev, PM_HINT_FULLON);
	if (ret < 0) {
		hid_err(led->hdev, "failed: device not resumed %d\n", ret);
		return ret;
	}

	ret = hid_hw_output_report(led->hdev, led->buf, sizeof(led->buf));
	if (ret == -ENOSYS)
		ret = hid_hw_raw_request(led->hdev, 0, led->buf,
					 sizeof(led->buf),
					 HID_OUTPUT_REPORT,
					 HID_REQ_SET_REPORT);
	if (ret < 0)
		hid_err(led->hdev, "failed to set keyboard backlight: %d\n",
			ret);

	/* Request USB HID device back to Normal Mode. */
	hid_hw_power(led->hdev, PM_HINT_NORMAL);

	return ret;
}

static int hammer_register_leds(struct hid_device *hdev)
{
	struct hammer_kbd_leds *kbd_backlight;

	kbd_backlight = devm_kzalloc(&hdev->dev, sizeof(*kbd_backlight),
				     GFP_KERNEL);
	if (!kbd_backlight)
		return -ENOMEM;

	kbd_backlight->hdev = hdev;
	kbd_backlight->cdev.name = "hammer::kbd_backlight";
	kbd_backlight->cdev.max_brightness = MAX_BRIGHTNESS;
	kbd_backlight->cdev.brightness_set_blocking =
		hammer_kbd_brightness_set_blocking;
	kbd_backlight->cdev.flags = LED_HW_PLUGGABLE;

	/* Set backlight to 0% initially. */
	hammer_kbd_brightness_set_blocking(&kbd_backlight->cdev, 0);

	return devm_led_classdev_register(&hdev->dev, &kbd_backlight->cdev);
}

#define HID_UP_GOOGLEVENDOR	0xffd10000
#define HID_VD_KBD_FOLDED	0x00000019
#define HID_USAGE_KBD_FOLDED	(HID_UP_GOOGLEVENDOR | HID_VD_KBD_FOLDED)

/* HID usage for keyboard backlight (Alphanumeric display brightness) */
#define HID_AD_BRIGHTNESS	0x00140046

static int hammer_input_mapping(struct hid_device *hdev, struct hid_input *hi,
				struct hid_field *field,
				struct hid_usage *usage,
				unsigned long **bit, int *max)
{
	if (usage->hid == HID_USAGE_KBD_FOLDED) {
		/*
		 * We do not want to have this usage mapped as it will get
		 * mixed in with "base attached" signal and delivered over
		 * separate input device for tablet switch mode.
		 */
		return -1;
	}

	return 0;
}

static void hammer_folded_event(struct hid_device *hdev, bool folded)
{
	unsigned long flags;

	spin_lock_irqsave(&cbas_ec_lock, flags);

	/*
	 * If we are getting events from Whiskers that means that it
	 * is attached to the lid.
	 */
	cbas_ec.base_present = true;
	cbas_ec.base_folded = folded;
	hid_dbg(hdev, "%s: base: %d, folded: %d\n", __func__,
		cbas_ec.base_present, cbas_ec.base_folded);

	if (cbas_ec.input) {
		input_report_switch(cbas_ec.input, SW_TABLET_MODE, folded);
		input_sync(cbas_ec.input);
	}

	spin_unlock_irqrestore(&cbas_ec_lock, flags);
}

static int hammer_event(struct hid_device *hid, struct hid_field *field,
			struct hid_usage *usage, __s32 value)
{
	if (usage->hid == HID_USAGE_KBD_FOLDED) {
		hammer_folded_event(hid, value);
		return 1; /* We handled this event */
	}

	return 0;
}

static bool hammer_has_folded_event(struct hid_device *hdev)
{
	return !!hid_find_field(hdev, HID_INPUT_REPORT,
				HID_GD_KEYBOARD, HID_USAGE_KBD_FOLDED);
}

static bool hammer_has_backlight_control(struct hid_device *hdev)
{
	return !!hid_find_field(hdev, HID_OUTPUT_REPORT,
				HID_GD_KEYBOARD, HID_AD_BRIGHTNESS);
}

static void hammer_get_folded_state(struct hid_device *hdev)
{
	struct hid_report *report;
	char *buf;
	int len, rlen;
	int a;

	report = hdev->report_enum[HID_INPUT_REPORT].report_id_hash[0x0];

	if (!report || report->maxfield < 1)
		return;

	len = hid_report_len(report) + 1;

	buf = kmalloc(len, GFP_KERNEL);
	if (!buf)
		return;

	rlen = hid_hw_raw_request(hdev, report->id, buf, len, report->type, HID_REQ_GET_REPORT);

	if (rlen != len) {
		hid_warn(hdev, "Unable to read base folded state: %d (expected %d)\n", rlen, len);
		goto out;
	}

	for (a = 0; a < report->maxfield; a++) {
		struct hid_field *field = report->field[a];

		if (field->usage->hid == HID_USAGE_KBD_FOLDED) {
			u32 value = hid_field_extract(hdev, buf+1,
					field->report_offset, field->report_size);

			hammer_folded_event(hdev, value);
			break;
		}
	}

out:
	kfree(buf);
}

static void hammer_stop(void *hdev)
{
	hid_hw_stop(hdev);
}

static int hammer_probe(struct hid_device *hdev,
			const struct hid_device_id *id)
{
	struct vivaldi_data *vdata;
	int error;

	vdata = devm_kzalloc(&hdev->dev, sizeof(*vdata), GFP_KERNEL);
	if (!vdata)
		return -ENOMEM;

	hid_set_drvdata(hdev, vdata);

	error = hid_parse(hdev);
	if (error)
		return error;

	error = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (error)
		return error;

	error = devm_add_action(&hdev->dev, hammer_stop, hdev);
	if (error)
		return error;

	/*
	 * We always want to poll for, and handle tablet mode events from
	 * devices that have folded usage, even when nobody has opened the input
	 * device. This also prevents the hid core from dropping early tablet
	 * mode events from the device.
	 */
	if (hammer_has_folded_event(hdev)) {
		hdev->quirks |= HID_QUIRK_ALWAYS_POLL;
		error = hid_hw_open(hdev);
		if (error)
			return error;

		hammer_get_folded_state(hdev);
	}

	if (hammer_has_backlight_control(hdev)) {
		error = hammer_register_leds(hdev);
		if (error)
			hid_warn(hdev,
				"Failed to register keyboard backlight: %d\n",
				error);
	}

	return 0;
}

static void hammer_remove(struct hid_device *hdev)
{
	unsigned long flags;

	if (hammer_has_folded_event(hdev)) {
		hid_hw_close(hdev);

		/*
		 * If we are disconnecting then most likely Whiskers is
		 * being removed. Even if it is not removed, without proper
		 * keyboard we should not stay in clamshell mode.
		 *
		 * The reason for doing it here and not waiting for signal
		 * from EC, is that on some devices there are high leakage
		 * on Whiskers pins and we do not detect disconnect reliably,
		 * resulting in devices being stuck in clamshell mode.
		 */
		spin_lock_irqsave(&cbas_ec_lock, flags);
		if (cbas_ec.input && cbas_ec.base_present) {
			input_report_switch(cbas_ec.input, SW_TABLET_MODE, 1);
			input_sync(cbas_ec.input);
		}
		cbas_ec.base_present = false;
		spin_unlock_irqrestore(&cbas_ec_lock, flags);
	}

	/* Unregistering LEDs and stopping the hardware is done via devm */
}

static const struct hid_device_id hammer_devices[] = {
	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_VIVALDI,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_EEL) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_JEWEL) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
		     USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WHISKERS) },
	{ }
};
MODULE_DEVICE_TABLE(hid, hammer_devices);

static struct hid_driver hammer_driver = {
	.name = "hammer",
	.id_table = hammer_devices,
	.probe = hammer_probe,
	.remove = hammer_remove,
	.feature_mapping = vivaldi_feature_mapping,
	.input_mapping = hammer_input_mapping,
	.event = hammer_event,
	.driver = {
		.dev_groups = vivaldi_attribute_groups,
	},
};

static int __init hammer_init(void)
{
	int error;

	error = platform_driver_register(&cbas_ec_driver);
	if (error)
		return error;

	error = hid_register_driver(&hammer_driver);
	if (error) {
		platform_driver_unregister(&cbas_ec_driver);
		return error;
	}

	return 0;
}
module_init(hammer_init);

static void __exit hammer_exit(void)
{
	hid_unregister_driver(&hammer_driver);
	platform_driver_unregister(&cbas_ec_driver);
}
module_exit(hammer_exit);

MODULE_DESCRIPTION("HID driver for Google Hammer device.");
MODULE_LICENSE("GPL");
