* [PATCH] toshiba_acpi: Add SCI operations and adapt Illumination code
@ 2012-05-03 20:46 Azael Avalos
2012-05-03 21:50 ` Seth Forshee
0 siblings, 1 reply; 2+ messages in thread
From: Azael Avalos @ 2012-05-03 20:46 UTC (permalink / raw)
To: Matthew Garrett, platform-driver-x86
SCI stands for Software Configuration Interface and
it is supposed to be present on all Toshiba models.
Illumination code is now adapted to use SCI calls and
is not registered unless the SCI is present.
Signed-off-by: Azael <coproscefalo@gmail.com>
---
Please consider applying this as a fix for 3.4 or 3.5.
This will fix up things for a proper Illumination check,
as it stands now its just "checking" the SCI and not
the Illumination support per se.
I'll gladly fix this if it causes merging trouble because
of the other patches sent.
drivers/platform/x86/toshiba_acpi.c | 172 +++++++++++++++++++++--------------
1 files changed, 104 insertions(+), 68 deletions(-)
diff --git a/drivers/platform/x86/toshiba_acpi.c
b/drivers/platform/x86/toshiba_acpi.c
index ee79ce6..12b5459 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -84,13 +84,23 @@ MODULE_LICENSE("GPL");
#define HCI_WORDS 6
/* operations */
-#define HCI_SET 0xff00
+#define SCI_SUPPORT_CHECK 0xf000
+#define SCI_OPEN 0xf100
+#define SCI_CLOSE 0xf200
+#define SCI_GET 0xf300
+#define SCI_SET 0xf400
#define HCI_GET 0xfe00
+#define HCI_SET 0xff00
+
/* return codes */
#define HCI_SUCCESS 0x0000
#define HCI_FAILURE 0x1000
#define HCI_NOT_SUPPORTED 0x8000
+#define SCI_ALREADY_OPEN 0x8100
+#define SCI_NOT_OPENED 0x8200
+#define SCI_INPUT_DATA_ERROR 0x8300
+#define SCI_NOT_PRESENT 0x8600
#define HCI_EMPTY 0x8c00
/* registers */
@@ -100,6 +110,7 @@ MODULE_LICENSE("GPL");
#define HCI_HOTKEY_EVENT 0x001e
#define HCI_LCD_BRIGHTNESS 0x002a
#define HCI_WIRELESS 0x0056
+#define SCI_ILLUMINATION 0x014e
/* field definitions */
#define HCI_HOTKEY_DISABLE 0x0b
@@ -128,6 +139,7 @@ struct toshiba_acpi_dev {
int last_key_event;
int key_event_valid;
+ unsigned int sci_opened:1;
unsigned int illumination_supported:1;
unsigned int video_supported:1;
unsigned int fan_supported:1;
@@ -286,21 +298,78 @@ static acpi_status hci_read2(struct
toshiba_acpi_dev *dev, u32 reg,
return status;
}
-/* Illumination support */
-static int toshiba_illumination_available(struct toshiba_acpi_dev *dev)
+/* sci functions */
+static int sci_open(struct toshiba_acpi_dev *dev)
{
- u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 };
+ u32 in[HCI_WORDS] = { SCI_OPEN, 0, 0, 0, 0, 0 };
u32 out[HCI_WORDS];
acpi_status status;
- in[0] = 0xf100;
status = hci_raw(dev, in, out);
if (ACPI_FAILURE(status)) {
- pr_info("Illumination device not available\n");
+ pr_err("ACPI call to open SCI failed.\n");
+ return 0;
+ } else if (out[0] == SCI_NOT_PRESENT) {
+ pr_info("Toshiba SCI is not present.\n");
return 0;
+ } else if (out[0] == SCI_ALREADY_OPEN) {
+ pr_notice("Toshiba SCI already opened.\n");
}
- in[0] = 0xf400;
+
+ return 1;
+}
+
+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))
+ pr_err("ACPI call to close SCI failed.\n");
+ else if (out[0] == SCI_NOT_PRESENT)
+ pr_info("Toshiba SCI is not present.\n");
+ else if (out[0] == SCI_NOT_OPENED)
+ pr_notice("Toshiba SCI not opened.\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)
+{
+ u32 value, result;
+ acpi_status status;
+
+ status = sci_read(dev, SCI_ILLUMINATION, &value, &result);
+ if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
+ pr_err("ACPI call for illumination failed.\n");
+ return 0;
+ } else if (result == HCI_NOT_SUPPORTED) {
+ pr_info("Illumination device not available\n");
+ return 0;
+ }
+
return 1;
}
@@ -309,82 +378,38 @@ static void toshiba_illumination_set(struct
led_classdev *cdev,
{
struct toshiba_acpi_dev *dev = container_of(cdev,
struct toshiba_acpi_dev, led_dev);
- u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 };
- u32 out[HCI_WORDS];
+ u32 state, result;
acpi_status status;
- /* First request : initialize communication. */
- in[0] = 0xf100;
- status = hci_raw(dev, in, out);
- if (ACPI_FAILURE(status)) {
- pr_info("Illumination device not available\n");
+ /* Switch the illumination on/off */
+ state = (brightness) ? 1 : 0;
+ status = sci_write(dev, SCI_ILLUMINATION, state, &result);
+ if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
+ pr_err("ACPI call for illumination failed.\n");
return;
+ } else if (result == HCI_NOT_SUPPORTED) {
+ pr_info("Illumination not supported\n");
}
-
- if (brightness) {
- /* Switch the illumination on */
- in[0] = 0xf400;
- in[1] = 0x14e;
- in[2] = 1;
- status = hci_raw(dev, in, out);
- if (ACPI_FAILURE(status)) {
- pr_info("ACPI call for illumination failed\n");
- return;
- }
- } else {
- /* Switch the illumination off */
- in[0] = 0xf400;
- in[1] = 0x14e;
- in[2] = 0;
- status = hci_raw(dev, in, out);
- if (ACPI_FAILURE(status)) {
- pr_info("ACPI call for illumination failed.\n");
- return;
- }
- }
-
- /* Last request : close communication. */
- in[0] = 0xf200;
- in[1] = 0;
- in[2] = 0;
- hci_raw(dev, in, out);
}
static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev)
{
struct toshiba_acpi_dev *dev = container_of(cdev,
struct toshiba_acpi_dev, led_dev);
- u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 };
- u32 out[HCI_WORDS];
+ u32 state, result;
acpi_status status;
- enum led_brightness result;
-
- /* First request : initialize communication. */
- in[0] = 0xf100;
- status = hci_raw(dev, in, out);
- if (ACPI_FAILURE(status)) {
- pr_info("Illumination device not available\n");
- return LED_OFF;
- }
/* Check the illumination */
- in[0] = 0xf300;
- in[1] = 0x14e;
- status = hci_raw(dev, in, out);
- if (ACPI_FAILURE(status)) {
- pr_info("ACPI call for illumination failed.\n");
+ status = sci_read(dev, SCI_ILLUMINATION, &state, &result);
+ if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
+ pr_err("ACPI call for illumination failed.\n");
+ return LED_OFF;
+ } else if (result == HCI_NOT_SUPPORTED) {
+ pr_info("Illumination not supported\n");
return LED_OFF;
}
- result = out[2] ? LED_FULL : LED_OFF;
-
- /* Last request : close communication. */
- in[0] = 0xf200;
- in[1] = 0;
- in[2] = 0;
- hci_raw(dev, in, out);
-
- return result;
+ return state ? LED_FULL : LED_OFF;
}
/* Bluetooth rfkill handlers */
@@ -1047,6 +1072,9 @@ static int toshiba_acpi_remove(struct
acpi_device *acpi_dev, int type)
if (dev->illumination_supported)
led_classdev_unregister(&dev->led_dev);
+ if (dev->sci_opened)
+ sci_close(dev);
+
if (toshiba_acpi)
toshiba_acpi = NULL;
@@ -1099,6 +1127,14 @@ static int __devinit toshiba_acpi_add(struct
acpi_device *acpi_dev)
dev->method_hci = hci_method;
acpi_dev->driver_data = dev;
+ /* Open Toshiba SCI, if present */
+ ret = sci_open(dev);
+ if (ret == 0) {
+ pr_info("Toshiba SCI could not be opened.\n");
+ dev->sci_opened = 0;
+ } else
+ dev->sci_opened = 1;
+
if (toshiba_acpi_setup_keyboard(dev))
pr_info("Unable to activate hotkeys\n");
@@ -1141,7 +1177,7 @@ static int __devinit toshiba_acpi_add(struct
acpi_device *acpi_dev)
}
}
- if (toshiba_illumination_available(dev)) {
+ if (dev->sci_opened && toshiba_illumination_available(dev)) {
dev->led_dev.name = "toshiba::illumination";
dev->led_dev.max_brightness = 1;
dev->led_dev.brightness_set = toshiba_illumination_set;
--
1.7.3.4
--
-- El mundo apesta y vosotros apestais tambien --
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] toshiba_acpi: Add SCI operations and adapt Illumination code
2012-05-03 20:46 [PATCH] toshiba_acpi: Add SCI operations and adapt Illumination code Azael Avalos
@ 2012-05-03 21:50 ` Seth Forshee
0 siblings, 0 replies; 2+ messages in thread
From: Seth Forshee @ 2012-05-03 21:50 UTC (permalink / raw)
To: Azael Avalos; +Cc: Matthew Garrett, platform-driver-x86
On Thu, May 03, 2012 at 02:46:56PM -0600, Azael Avalos wrote:
> SCI stands for Software Configuration Interface and
> it is supposed to be present on all Toshiba models.
>
> Illumination code is now adapted to use SCI calls and
> is not registered unless the SCI is present.
>
> Signed-off-by: Azael <coproscefalo@gmail.com>
One tiny little style problem, otherwise this looks okay to me.
Also worth noting is that I tested an earlier but nearly identical
version of this patch on an NB505 (no illumination support) and saw no
adverse effects.
> @@ -1099,6 +1127,14 @@ static int __devinit toshiba_acpi_add(struct
> acpi_device *acpi_dev)
> dev->method_hci = hci_method;
> acpi_dev->driver_data = dev;
>
> + /* Open Toshiba SCI, if present */
> + ret = sci_open(dev);
> + if (ret == 0) {
> + pr_info("Toshiba SCI could not be opened.\n");
> + dev->sci_opened = 0;
> + } else
> + dev->sci_opened = 1;
> +
Kernel style dictates that when one branch of a conditional has braces,
all other branches should also have braces.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-05-03 21:50 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-03 20:46 [PATCH] toshiba_acpi: Add SCI operations and adapt Illumination code Azael Avalos
2012-05-03 21:50 ` Seth Forshee
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox