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