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: Azael Avalos <coproscefalo@gmail.com>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
This commit is contained in:
Azael Avalos 2014-03-25 20:38:29 -06:00 committed by Matthew Garrett
parent 119f449866
commit 84a6273f04

View file

@ -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)
{