public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: Aaron Lu <aaron.lu@intel.com>
To: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Artem Savkov <artem.savkov@gmail.com>,
	Cheppes <cheppes@mailinator.com>,
	Luis Medinas <lmedinas@gmail.com>,
	ACPI Devel Mailing List <linux-acpi@vger.kernel.org>,
	Zhang Rui <rui.zhang@intel.com>
Subject: [PATCH] acpi: video: enhance the quirk detect logic of _BQC
Date: Sun, 07 Apr 2013 09:56:07 +0800	[thread overview]
Message-ID: <5160D237.50307@intel.com> (raw)

Currently we decide if the _BQC is using index by first setting the
level to maximum, and then check if _BQC returned maximum; if not, we
say it is using index.

This is not true for some buggy systems, where the _BQC method will
always return a constant value(e.g. 0 or 100 for the two broken system)
and thus break the current logic. So this patch tries to enhance the
quirk detect logic for _BQC: we do this by picking a test_level, it can
be the maximum level or the mininum one based on some condition. And we
don't make the assumption that if _BQC returned a value that is not what
we just set, it must be using an index. Instead, we will compare the
value returned from _BQC and if it doesn't match, see if the returned
value is an index. And if still no, clear the capability of _BQC.

Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=42861
Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=56011
Reported-and-tested-by: Artem Savkov <artem.savkov@gmail.com>
Reported-by: Luis Medinas <lmedinas@gmail.com>
Reported-by: Cheppes <cheppes@mailinator.com>
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
---
Thanks Cheppes <cheppes@mailinator.com> for the suggestion of choosing
different levels to test, and also for the help of in code comment
correction.

 drivers/acpi/video.c | 67 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 57 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 3cdd047..306ea2a 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -632,6 +632,56 @@ acpi_video_cmp_level(const void *a, const void *b)
 }
 
 /*
+ * Decides if _BQC/_BCQ for this system is usable
+ *
+ * We do this by changing the level first and then read out the current
+ * brightness level, if the value does not match, find out if it is using
+ * index. If not, clear the _BQC/_BCQ capability.
+ */
+static int acpi_video_bqc_quirk(struct acpi_video_device *device,
+				int max_level, int current_level)
+{
+	struct acpi_video_device_brightness *br = device->brightness;
+	int result;
+	unsigned long long level;
+	int test_level;
+
+	/* don't mess with existing known broken systems */
+	if (bqc_offset_aml_bug_workaround)
+		return 0;
+
+	/*
+	 * Some systems always report current brightness level as maximum
+	 * through _BQC, we need to test another value for them.
+	 */
+	test_level = current_level == max_level ? br->levels[2] : max_level;
+
+	result = acpi_video_device_lcd_set_level(device, test_level);
+	if (result)
+		return result;
+
+	result = acpi_video_device_lcd_get_level_current(device, &level, true);
+	if (result)
+		return result;
+
+	if (level != test_level) {
+		/* buggy _BQC found, need to find out if it uses index */
+		if (level < br->count) {
+			if (br->flags._BCL_reversed)
+				level = br->count - 3 - level;
+			if (br->levels[level + 2] == test_level)
+				br->flags._BQC_use_index = 1;
+		}
+
+		if (!br->flags._BQC_use_index)
+			device->cap._BQC = device->cap._BCQ = 0;
+	}
+
+	return 0;
+}
+
+
+/*
  *  Arg:	
  *  	device	: video output device (LCD, CRT, ..)
  *
@@ -742,18 +792,15 @@ acpi_video_init_brightness(struct acpi_video_device *device)
 	if (result)
 		goto out_free_levels;
 
-	/*
-	 * Set the level to maximum and check if _BQC uses indexed value
-	 */
-	result = acpi_video_device_lcd_set_level(device, max_level);
-	if (result)
-		goto out_free_levels;
-
-	result = acpi_video_device_lcd_get_level_current(device, &level, true);
+	result = acpi_video_bqc_quirk(device, max_level, level_old);
 	if (result)
 		goto out_free_levels;
-
-	br->flags._BQC_use_index = (level == max_level ? 0 : 1);
+	/*
+	 * cap._BQC may get cleared due to _BQC is found to be broken
+	 * in acpi_video_bqc_quirk, so check again here.
+	 */
+	if (!device->cap._BQC)
+		goto set_level;
 
 	if (use_bios_initial_backlight) {
 		level = acpi_video_bqc_value_to_level(device, level_old);
-- 
1.8.1.4


             reply	other threads:[~2013-04-07  1:54 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-07  1:56 Aaron Lu [this message]
2013-04-17 14:54 ` [PATCH] acpi: video: enhance the quirk detect logic of _BQC Zhang Rui
2013-04-22 12:19   ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5160D237.50307@intel.com \
    --to=aaron.lu@intel.com \
    --cc=artem.savkov@gmail.com \
    --cc=cheppes@mailinator.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=lmedinas@gmail.com \
    --cc=rjw@sisk.pl \
    --cc=rui.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox