// SPDX-License-Identifier: GPL-2.0-only
/*
 * SMBus driver for ACPI Embedded Controller (v0.1)
 *
 * Copyright (c) 2007 Alexey Starikovskiy
 */

#include <linux/acpi.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include "sbshc.h"

#define PREFIX "ACPI: "

#define ACPI_SMB_HC_CLASS	"smbus_host_ctl"
#define ACPI_SMB_HC_DEVICE_NAME	"ACPI SMBus HC"

struct acpi_smb_hc {
	struct acpi_ec *ec;
	struct mutex lock;
	wait_queue_head_t wait;
	u8 offset;
	u8 query_bit;
	smbus_alarm_callback callback;
	void *context;
	bool done;
};

static int acpi_smbus_hc_add(struct acpi_device *device);
static int acpi_smbus_hc_remove(struct acpi_device *device);

static const struct acpi_device_id sbs_device_ids[] = {
	{"ACPI0001", 0},
	{"ACPI0005", 0},
	{"", 0},
};

MODULE_DEVICE_TABLE(acpi, sbs_device_ids);

static struct acpi_driver acpi_smb_hc_driver = {
	.name = "smbus_hc",
	.class = ACPI_SMB_HC_CLASS,
	.ids = sbs_device_ids,
	.ops = {
		.add = acpi_smbus_hc_add,
		.remove = acpi_smbus_hc_remove,
		},
};

union acpi_smb_status {
	u8 raw;
	struct {
		u8 status:5;
		u8 reserved:1;
		u8 alarm:1;
		u8 done:1;
	} fields;
};

enum acpi_smb_status_codes {
	SMBUS_OK = 0,
	SMBUS_UNKNOWN_FAILURE = 0x07,
	SMBUS_DEVICE_ADDRESS_NACK = 0x10,
	SMBUS_DEVICE_ERROR = 0x11,
	SMBUS_DEVICE_COMMAND_ACCESS_DENIED = 0x12,
	SMBUS_UNKNOWN_ERROR = 0x13,
	SMBUS_DEVICE_ACCESS_DENIED = 0x17,
	SMBUS_TIMEOUT = 0x18,
	SMBUS_HOST_UNSUPPORTED_PROTOCOL = 0x19,
	SMBUS_BUSY = 0x1a,
	SMBUS_PEC_ERROR = 0x1f,
};

enum acpi_smb_offset {
	ACPI_SMB_PROTOCOL = 0,	/* protocol, PEC */
	ACPI_SMB_STATUS = 1,	/* status */
	ACPI_SMB_ADDRESS = 2,	/* address */
	ACPI_SMB_COMMAND = 3,	/* command */
	ACPI_SMB_DATA = 4,	/* 32 data registers */
	ACPI_SMB_BLOCK_COUNT = 0x24,	/* number of data bytes */
	ACPI_SMB_ALARM_ADDRESS = 0x25,	/* alarm address */
	ACPI_SMB_ALARM_DATA = 0x26,	/* 2 bytes alarm data */
};

static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
{
	return ec_read(hc->offset + address, data);
}

static inline int smb_hc_write(struct acpi_smb_hc *hc, u8 address, u8 data)
{
	return ec_write(hc->offset + address, data);
}

static int wait_transaction_complete(struct acpi_smb_hc *hc, int timeout)
{
	if (wait_event_timeout(hc->wait, hc->done, msecs_to_jiffies(timeout)))
		return 0;
	return -ETIME;
}

static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol,
				  u8 address, u8 command, u8 *data, u8 length)
{
	int ret = -EFAULT, i;
	u8 temp, sz = 0;

	if (!hc) {
		printk(KERN_ERR PREFIX "host controller is not configured\n");
		return ret;
	}

	mutex_lock(&hc->lock);
	hc->done = false;
	if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
		goto end;
	if (temp) {
		ret = -EBUSY;
		goto end;
	}
	smb_hc_write(hc, ACPI_SMB_COMMAND, command);
	if (!(protocol & 0x01)) {
		smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length);
		for (i = 0; i < length; ++i)
			smb_hc_write(hc, ACPI_SMB_DATA + i, data[i]);
	}
	smb_hc_write(hc, ACPI_SMB_ADDRESS, address << 1);
	smb_hc_write(hc, ACPI_SMB_PROTOCOL, protocol);
	/*
	 * Wait for completion. Save the status code, data size,
	 * and data into the return package (if required by the protocol).
	 */
	ret = wait_transaction_complete(hc, 1000);
	if (ret || !(protocol & 0x01))
		goto end;
	switch (protocol) {
	case SMBUS_RECEIVE_BYTE:
	case SMBUS_READ_BYTE:
		sz = 1;
		break;
	case SMBUS_READ_WORD:
		sz = 2;
		break;
	case SMBUS_READ_BLOCK:
		if (smb_hc_read(hc, ACPI_SMB_BLOCK_COUNT, &sz)) {
			ret = -EFAULT;
			goto end;
		}
		sz &= 0x1f;
		break;
	}
	for (i = 0; i < sz; ++i)
		smb_hc_read(hc, ACPI_SMB_DATA + i, &data[i]);
      end:
	mutex_unlock(&hc->lock);
	return ret;
}

int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
		    u8 command, u8 *data)
{
	return acpi_smbus_transaction(hc, protocol, address, command, data, 0);
}

EXPORT_SYMBOL_GPL(acpi_smbus_read);

int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 address,
		     u8 command, u8 *data, u8 length)
{
	return acpi_smbus_transaction(hc, protocol, address, command, data, length);
}

EXPORT_SYMBOL_GPL(acpi_smbus_write);

int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
				 smbus_alarm_callback callback, void *context)
{
	mutex_lock(&hc->lock);
	hc->callback = callback;
	hc->context = context;
	mutex_unlock(&hc->lock);
	return 0;
}

EXPORT_SYMBOL_GPL(acpi_smbus_register_callback);

int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc)
{
	mutex_lock(&hc->lock);
	hc->callback = NULL;
	hc->context = NULL;
	mutex_unlock(&hc->lock);
	acpi_os_wait_events_complete();
	return 0;
}

EXPORT_SYMBOL_GPL(acpi_smbus_unregister_callback);

static inline void acpi_smbus_callback(void *context)
{
	struct acpi_smb_hc *hc = context;
	if (hc->callback)
		hc->callback(hc->context);
}

static int smbus_alarm(void *context)
{
	struct acpi_smb_hc *hc = context;
	union acpi_smb_status status;
	u8 address;
	if (smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw))
		return 0;
	/* Check if it is only a completion notify */
	if (status.fields.done && status.fields.status == SMBUS_OK) {
		hc->done = true;
		wake_up(&hc->wait);
	}
	if (!status.fields.alarm)
		return 0;
	mutex_lock(&hc->lock);
	smb_hc_read(hc, ACPI_SMB_ALARM_ADDRESS, &address);
	status.fields.alarm = 0;
	smb_hc_write(hc, ACPI_SMB_STATUS, status.raw);
	/* We are only interested in events coming from known devices */
	switch (address >> 1) {
		case ACPI_SBS_CHARGER:
		case ACPI_SBS_MANAGER:
		case ACPI_SBS_BATTERY:
			acpi_os_execute(OSL_NOTIFY_HANDLER,
					acpi_smbus_callback, hc);
		default:;
	}
	mutex_unlock(&hc->lock);
	return 0;
}

typedef int (*acpi_ec_query_func) (void *data);

extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
			      acpi_handle handle, acpi_ec_query_func func,
			      void *data);

static int acpi_smbus_hc_add(struct acpi_device *device)
{
	int status;
	unsigned long long val;
	struct acpi_smb_hc *hc;

	if (!device)
		return -EINVAL;

	status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
	if (ACPI_FAILURE(status)) {
		printk(KERN_ERR PREFIX "error obtaining _EC.\n");
		return -EIO;
	}

	strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS);

	hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL);
	if (!hc)
		return -ENOMEM;
	mutex_init(&hc->lock);
	init_waitqueue_head(&hc->wait);

	hc->ec = acpi_driver_data(device->parent);
	hc->offset = (val >> 8) & 0xff;
	hc->query_bit = val & 0xff;
	device->driver_data = hc;

	acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
	dev_info(&device->dev, "SBS HC: offset = 0x%0x, query_bit = 0x%0x\n",
		 hc->offset, hc->query_bit);

	return 0;
}

extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);

static int acpi_smbus_hc_remove(struct acpi_device *device)
{
	struct acpi_smb_hc *hc;

	if (!device)
		return -EINVAL;

	hc = acpi_driver_data(device);
	acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
	acpi_os_wait_events_complete();
	kfree(hc);
	device->driver_data = NULL;
	return 0;
}

module_acpi_driver(acpi_smb_hc_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexey Starikovskiy");
MODULE_DESCRIPTION("ACPI SMBus HC driver");
