From: Martin Filip <bugtraq@smoula.net>
To: linux-kernel@vger.kernel.org
Subject: Macbook Pro 5,5 nvidia backlight fix
Date: Mon, 05 Jul 2010 17:27:00 +0200 [thread overview]
Message-ID: <4C31F9C4.8090609@smoula.net> (raw)
Hello,
I've MacBookPro5,5 with nVidia Corporation C79 [GeForce 9400M]. Until
now (last tested 2.6.34) it has broken brightness control in mbp_nvidia_bl.
I've patch is based on:
http://spuriousinterrupt.org/stuff/mbp_nvidia_bl-add_mmio_backlight_reg-2.6.31rc1.diff
Maybe someone involved with this module can merge this one?
Patch for 2.6.34:
diff -ruN a/drivers/video/backlight/mbp_nvidia_bl.c
b/drivers/video/backlight/mbp_nvidia_bl.c
--- a/drivers/video/backlight/mbp_nvidia_bl.c 2010-05-16
23:17:36.000000000 +0200
+++ b/drivers/video/backlight/mbp_nvidia_bl.c 2010-07-05
13:02:23.000000000 +0200
@@ -24,6 +24,7 @@
#include <linux/err.h>
#include <linux/dmi.h>
#include <linux/io.h>
+#include <linux/pci.h>
static struct backlight_device *mbp_backlight_device;
@@ -32,6 +33,12 @@
/* I/O resource to allocate. */
unsigned long iostart;
unsigned long iolen;
+
+ /* ... or MMIO region to allocate. */
+ unsigned long memstart;
+ unsigned long memlen;
+ void *membase;
+
/* Backlight operations structure. */
const struct backlight_ops backlight_ops;
};
@@ -41,6 +48,9 @@
module_param_named(debug, debug, int, 0644);
MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
+static /* const */ struct dmi_match_data *driver_data;
+
+
/*
* Implementation for MacBooks with Intel chipset.
*/
@@ -123,11 +133,58 @@
}
};
+#define NV_PDISPLAY_OFFSET 0x610000
+#define NV_PDISPLAY_SOR0_REGS_BRIGHTNESS 0xc084
+#define NV_PDISPLAY_SOR0_REGS_BRIGHTNESS_CONTROL_ENABLED 0x80000000
+
+/* leave the driver's max_brightness value at 15 to avoid reworking how
+ * the driver works entirely. we can just scale to the 'real' max of 1024
+ */
+#define NV_PDISPLAY_BACKLIGHT_MAX 1024
+static int nvidia_chipset_send_intensity_mmio(struct backlight_device *bd)
+{
+ int intensity = bd->props.brightness;
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
+ intensity);
+
+ writel((intensity * NV_PDISPLAY_BACKLIGHT_MAX / 15) |
NV_PDISPLAY_SOR0_REGS_BRIGHTNESS_CONTROL_ENABLED,
+ driver_data->membase + NV_PDISPLAY_OFFSET +
NV_PDISPLAY_SOR0_REGS_BRIGHTNESS);
+
+ return 0;
+}
+
+static int nvidia_chipset_get_intensity_mmio(struct backlight_device *bd)
+{
+ int intensity;
+ unsigned int val = readl(driver_data->membase + NV_PDISPLAY_OFFSET +
NV_PDISPLAY_SOR0_REGS_BRIGHTNESS);
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %u\n",
+ val);
+
+ /* convert to level between 0 and 15 */
+ intensity = (((double)val / NV_PDISPLAY_BACKLIGHT_MAX * 15) + 0.5);
+ return intensity;
+}
+
+static const struct dmi_match_data nvidia_chipset_data_mmio = {
+ .iolen = 0,
+ .backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .get_brightness = nvidia_chipset_get_intensity_mmio,
+ .update_status = nvidia_chipset_send_intensity_mmio
+ }
+};
+
+
/*
* DMI matching.
*/
static /* const */ struct dmi_match_data *driver_data;
+
static int mbp_dmi_match(const struct dmi_system_id *id)
{
driver_data = id->driver_data;
@@ -136,6 +193,35 @@
return 1;
}
+
+static int mbp_dmi_match_mmio(const struct dmi_system_id *id)
+{
+ struct pci_dev *pdev = NULL;
+
+ driver_data = id->driver_data;
+
+ printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident);
+
+ while((pdev = pci_get_device(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, pdev))) {
+ if((pdev->class >> 16) != PCI_BASE_CLASS_DISPLAY) /* XXX: should we
use PCI_CLASS_DISPLAY_VGA? */
+ continue;
+
+ driver_data->memstart = pdev->resource[0].start;
+ driver_data->memlen = pdev->resource[0].end - pdev->resource[0].start
+ 1;
+ if (debug)
+ printk(KERN_DEBUG "Found video device, memstart=0x%lx, memlen=0x%lx\n",
+ driver_data->memstart, driver_data->memlen);
+ return 1;
+ }
+
+ driver_data = NULL;
+ printk(KERN_ERR "mbp_nvidia_bl: Couldn't find PCI device\n");
+
+ return 0;
+}
+
+
+
static const struct dmi_system_id __initdata mbp_device_table[] = {
{
.callback = mbp_dmi_match,
@@ -281,27 +367,35 @@
},
.driver_data = (void *)&nvidia_chipset_data,
},
- {
- .callback = mbp_dmi_match,
- .ident = "MacBookPro 5,5",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,5"),
- },
- .driver_data = (void *)&nvidia_chipset_data,
- },
+ {
+ .callback = mbp_dmi_match_mmio,
+ .ident = "MacBookPro 5,5",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,5"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data_mmio,
+ },
{ }
};
static int __init mbp_init(void)
{
struct backlight_properties props;
- if (!dmi_check_system(mbp_device_table))
+ if (!dmi_check_system(mbp_device_table) || !driver_data)
return -ENODEV;
- if (!request_region(driver_data->iostart, driver_data->iolen,
+ if (driver_data->iolen != 0) {
+ if (!request_region(driver_data->iostart, driver_data->iolen,
"Macbook Pro backlight"))
return -ENXIO;
+ } else if (driver_data->memlen != 0) {
+ driver_data->membase = ioremap(driver_data->memstart,
+ driver_data->memlen);
+
+ if (!driver_data->membase)
+ return -ENXIO;
+ }
memset(&props, 0, sizeof(struct backlight_properties));
props.max_brightness = 15;
@@ -310,7 +404,11 @@
&driver_data->backlight_ops,
&props);
if (IS_ERR(mbp_backlight_device)) {
- release_region(driver_data->iostart, driver_data->iolen);
+ if (driver_data->iolen != 0)
+ release_region(driver_data->iostart, driver_data->iolen);
+ else if (driver_data->memlen != 0)
+ iounmap(driver_data->membase);
+
return PTR_ERR(mbp_backlight_device);
}
@@ -325,7 +423,10 @@
{
backlight_device_unregister(mbp_backlight_device);
- release_region(driver_data->iostart, driver_data->iolen);
+ if (driver_data->iolen != 0)
+ release_region(driver_data->iostart, driver_data->iolen);
+ else if (driver_data->membase)
+ iounmap(driver_data->membase);
}
module_init(mbp_init);
Thank you for your time
--
Martin Filip
e-mail: nexus@smoula.net
jabberID: nexus@smoula.net
http://www.smoula.net
next reply other threads:[~2010-07-05 15:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-05 15:27 Martin Filip [this message]
2010-07-05 17:25 ` Macbook Pro 5,5 nvidia backlight fix Matthew Garrett
[not found] ` <4C321A0D.20008@smoula.net>
2010-07-05 17:48 ` Matthew Garrett
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=4C31F9C4.8090609@smoula.net \
--to=bugtraq@smoula.net \
--cc=linux-kernel@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.