diff options
Diffstat (limited to 'drivers/video/backlight/mbp_nvidia_bl.c')
-rw-r--r-- | drivers/video/backlight/mbp_nvidia_bl.c | 191 |
1 files changed, 155 insertions, 36 deletions
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 65864c50045..3bb4c0a50c6 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -27,73 +27,192 @@ static struct backlight_device *mbp_backlight_device; -static struct dmi_system_id __initdata mbp_device_table[] = { +/* Structure to be passed to the DMI_MATCH function. */ +struct dmi_match_data { + /* I/O resource to allocate. */ + unsigned long iostart; + unsigned long iolen; + /* Backlight operations structure. */ + struct backlight_ops backlight_ops; +}; + +/* Module parameters. */ +static int debug; +module_param_named(debug, debug, int, 0644); +MODULE_PARM_DESC(debug, "Set to one to enable debugging messages."); + +/* + * Implementation for MacBooks with Intel chipset. + */ +static int intel_chipset_send_intensity(struct backlight_device *bd) +{ + int intensity = bd->props.brightness; + + if (debug) + printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n", + intensity); + + outb(0x04 | (intensity << 4), 0xb3); + outb(0xbf, 0xb2); + return 0; +} + +static int intel_chipset_get_intensity(struct backlight_device *bd) +{ + int intensity; + + outb(0x03, 0xb3); + outb(0xbf, 0xb2); + intensity = inb(0xb3) >> 4; + + if (debug) + printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n", + intensity); + + return intensity; +} + +static const struct dmi_match_data intel_chipset_data = { + .iostart = 0xb2, + .iolen = 2, + .backlight_ops = { + .options = BL_CORE_SUSPENDRESUME, + .get_brightness = intel_chipset_get_intensity, + .update_status = intel_chipset_send_intensity, + } +}; + +/* + * Implementation for MacBooks with Nvidia chipset. + */ +static int nvidia_chipset_send_intensity(struct backlight_device *bd) +{ + int intensity = bd->props.brightness; + + if (debug) + printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n", + intensity); + + outb(0x04 | (intensity << 4), 0x52f); + outb(0xbf, 0x52e); + return 0; +} + +static int nvidia_chipset_get_intensity(struct backlight_device *bd) +{ + int intensity; + + outb(0x03, 0x52f); + outb(0xbf, 0x52e); + intensity = inb(0x52f) >> 4; + + if (debug) + printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n", + intensity); + + return intensity; +} + +static const struct dmi_match_data nvidia_chipset_data = { + .iostart = 0x52e, + .iolen = 2, + .backlight_ops = { + .options = BL_CORE_SUSPENDRESUME, + .get_brightness = nvidia_chipset_get_intensity, + .update_status = nvidia_chipset_send_intensity + } +}; + +/* + * 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; + + printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident); + return 1; +} + +static const struct dmi_system_id __initdata mbp_device_table[] = { { - .ident = "3,1", - .matches = { + .callback = mbp_dmi_match, + .ident = "MacBookPro 3,1", + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"), }, + .driver_data = (void *)&intel_chipset_data, }, { - .ident = "3,2", - .matches = { + .callback = mbp_dmi_match, + .ident = "MacBookPro 3,2", + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"), }, + .driver_data = (void *)&intel_chipset_data, }, { - .ident = "4,1", - .matches = { + .callback = mbp_dmi_match, + .ident = "MacBookPro 4,1", + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"), }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 5,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,1"), + }, + .driver_data = (void *)&nvidia_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBookAir 2,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2,1"), + }, + .driver_data = (void *)&nvidia_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBookPro 5,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"), + }, + .driver_data = (void *)&nvidia_chipset_data, }, { } }; -static int mbp_send_intensity(struct backlight_device *bd) -{ - int intensity = bd->props.brightness; - - outb(0x04 | (intensity << 4), 0xb3); - outb(0xbf, 0xb2); - - return 0; -} - -static int mbp_get_intensity(struct backlight_device *bd) -{ - outb(0x03, 0xb3); - outb(0xbf, 0xb2); - return inb(0xb3) >> 4; -} - -static struct backlight_ops mbp_ops = { - .options = BL_CORE_SUSPENDRESUME, - .get_brightness = mbp_get_intensity, - .update_status = mbp_send_intensity, -}; - static int __init mbp_init(void) { if (!dmi_check_system(mbp_device_table)) return -ENODEV; - if (!request_region(0xb2, 2, "Macbook Pro backlight")) + if (!request_region(driver_data->iostart, driver_data->iolen, + "Macbook Pro backlight")) return -ENXIO; mbp_backlight_device = backlight_device_register("mbp_backlight", - NULL, NULL, - &mbp_ops); + NULL, NULL, &driver_data->backlight_ops); if (IS_ERR(mbp_backlight_device)) { - release_region(0xb2, 2); + release_region(driver_data->iostart, driver_data->iolen); return PTR_ERR(mbp_backlight_device); } mbp_backlight_device->props.max_brightness = 15; mbp_backlight_device->props.brightness = - mbp_get_intensity(mbp_backlight_device); + driver_data->backlight_ops.get_brightness(mbp_backlight_device); backlight_update_status(mbp_backlight_device); return 0; @@ -103,7 +222,7 @@ static void __exit mbp_exit(void) { backlight_device_unregister(mbp_backlight_device); - release_region(0xb2, 2); + release_region(driver_data->iostart, driver_data->iolen); } module_init(mbp_init); |