Commit 84a6273f authored by Azael Avalos's avatar Azael Avalos Committed by Matthew Garrett
Browse files

toshiba_acpi: Add System Configuration Interface

SCI stands for System Configuration Interface,
which aim is to conceal differences in hardware
between different models.

This patch introduces four new calls: sci_open,
sci_close, sci_read and sci_write, along with
its definitions and return codes which will be
used by later patches.

More information about the SCI can be found at
Jonathan Buzzard's website [1].

[1] http://www.buzzard.me.uk/toshiba/docs.html



Signed-off-by: default avatarAzael Avalos <coproscefalo@gmail.com>
Signed-off-by: default avatarMatthew Garrett <matthew.garrett@nebula.com>
parent 119f4498
Loading
Loading
Loading
Loading
+79 −0
Original line number Diff line number Diff line
@@ -77,6 +77,9 @@ MODULE_LICENSE("GPL");
 * However the ACPI methods seem to be incomplete in some areas (for
 * example they allow setting, but not reading, the LCD brightness value),
 * so this is still useful.
 * 
 * SCI stands for "System Configuration Interface" which aim is to
 * conceal differences in hardware between different models.
 */

#define HCI_WORDS			6
@@ -84,12 +87,20 @@ MODULE_LICENSE("GPL");
/* operations */
#define HCI_SET				0xff00
#define HCI_GET				0xfe00
#define SCI_OPEN			0xf100
#define SCI_CLOSE			0xf200
#define SCI_GET				0xf300
#define SCI_SET				0xf400

/* return codes */
#define HCI_SUCCESS			0x0000
#define HCI_FAILURE			0x1000
#define HCI_NOT_SUPPORTED		0x8000
#define HCI_EMPTY			0x8c00
#define SCI_OPEN_CLOSE_OK		0x0044
#define SCI_ALREADY_OPEN		0x8100
#define SCI_NOT_OPENED			0x8200
#define SCI_NOT_PRESENT			0x8600

/* registers */
#define HCI_FAN				0x0004
@@ -280,6 +291,74 @@ static acpi_status hci_read2(struct toshiba_acpi_dev *dev, u32 reg,
	return status;
}

/* common sci tasks
 */

static int sci_open(struct toshiba_acpi_dev *dev)
{
	u32 in[HCI_WORDS] = { SCI_OPEN, 0, 0, 0, 0, 0 };
	u32 out[HCI_WORDS];
	acpi_status status;

	status = hci_raw(dev, in, out);
	if  (ACPI_FAILURE(status) || out[0] == HCI_FAILURE) {
		pr_err("ACPI call to open SCI failed\n");
		return 0;
	}

	if (out[0] == SCI_OPEN_CLOSE_OK) {
		return 1;
	} else if (out[0] == SCI_ALREADY_OPEN) {
		pr_info("Toshiba SCI already opened\n");
		return 1;
	} else if (out[0] == SCI_NOT_PRESENT) {
		pr_info("Toshiba SCI is not present\n");
	}

	return 0;
}

static void sci_close(struct toshiba_acpi_dev *dev)
{
	u32 in[HCI_WORDS] = { SCI_CLOSE, 0, 0, 0, 0, 0 };
	u32 out[HCI_WORDS];
	acpi_status status;

	status = hci_raw(dev, in, out);
	if (ACPI_FAILURE(status) || out[0] == HCI_FAILURE) {
		pr_err("ACPI call to close SCI failed\n");
		return;
	}

	if (out[0] == SCI_OPEN_CLOSE_OK)
		return;
	else if (out[0] == SCI_NOT_OPENED)
		pr_info("Toshiba SCI not opened\n");
	else if (out[0] == SCI_NOT_PRESENT)
		pr_info("Toshiba SCI is not present\n");
}

static acpi_status sci_read(struct toshiba_acpi_dev *dev, u32 reg,
			    u32 *out1, u32 *result)
{
	u32 in[HCI_WORDS] = { SCI_GET, reg, 0, 0, 0, 0 };
	u32 out[HCI_WORDS];
	acpi_status status = hci_raw(dev, in, out);
	*out1 = out[2];
	*result = (ACPI_SUCCESS(status)) ? out[0] : HCI_FAILURE;
	return status;
}

static acpi_status sci_write(struct toshiba_acpi_dev *dev, u32 reg,
			     u32 in1, u32 *result)
{
	u32 in[HCI_WORDS] = { SCI_SET, reg, in1, 0, 0, 0 };
	u32 out[HCI_WORDS];
	acpi_status status = hci_raw(dev, in, out);
	*result = (ACPI_SUCCESS(status)) ? out[0] : HCI_FAILURE;
	return status;
}

/* Illumination support */
static int toshiba_illumination_available(struct toshiba_acpi_dev *dev)
{