~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/video/backlight/apple_bl.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Backlight Driver for Intel-based Apples
 
3
 *
 
4
 *  Copyright (c) Red Hat <mjg@redhat.com>
 
5
 *  Based on code from Pommed:
 
6
 *  Copyright (C) 2006 Nicolas Boichat <nicolas @boichat.ch>
 
7
 *  Copyright (C) 2006 Felipe Alfaro Solana <felipe_alfaro @linuxmail.org>
 
8
 *  Copyright (C) 2007 Julien BLACHE <jb@jblache.org>
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License version 2 as
 
12
 *  published by the Free Software Foundation.
 
13
 *
 
14
 *  This driver triggers SMIs which cause the firmware to change the
 
15
 *  backlight brightness. This is icky in many ways, but it's impractical to
 
16
 *  get at the firmware code in order to figure out what it's actually doing.
 
17
 */
 
18
 
 
19
#include <linux/module.h>
 
20
#include <linux/kernel.h>
 
21
#include <linux/init.h>
 
22
#include <linux/backlight.h>
 
23
#include <linux/err.h>
 
24
#include <linux/io.h>
 
25
#include <linux/pci.h>
 
26
#include <linux/acpi.h>
 
27
 
 
28
static struct backlight_device *apple_backlight_device;
 
29
 
 
30
struct hw_data {
 
31
        /* I/O resource to allocate. */
 
32
        unsigned long iostart;
 
33
        unsigned long iolen;
 
34
        /* Backlight operations structure. */
 
35
        const struct backlight_ops backlight_ops;
 
36
        void (*set_brightness)(int);
 
37
};
 
38
 
 
39
static const struct hw_data *hw_data;
 
40
 
 
41
#define DRIVER "apple_backlight: "
 
42
 
 
43
/* Module parameters. */
 
44
static int debug;
 
45
module_param_named(debug, debug, int, 0644);
 
46
MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
 
47
 
 
48
/*
 
49
 * Implementation for machines with Intel chipset.
 
50
 */
 
51
static void intel_chipset_set_brightness(int intensity)
 
52
{
 
53
        outb(0x04 | (intensity << 4), 0xb3);
 
54
        outb(0xbf, 0xb2);
 
55
}
 
56
 
 
57
static int intel_chipset_send_intensity(struct backlight_device *bd)
 
58
{
 
59
        int intensity = bd->props.brightness;
 
60
 
 
61
        if (debug)
 
62
                printk(KERN_DEBUG DRIVER "setting brightness to %d\n",
 
63
                       intensity);
 
64
 
 
65
        intel_chipset_set_brightness(intensity);
 
66
        return 0;
 
67
}
 
68
 
 
69
static int intel_chipset_get_intensity(struct backlight_device *bd)
 
70
{
 
71
        int intensity;
 
72
 
 
73
        outb(0x03, 0xb3);
 
74
        outb(0xbf, 0xb2);
 
75
        intensity = inb(0xb3) >> 4;
 
76
 
 
77
        if (debug)
 
78
                printk(KERN_DEBUG DRIVER "read brightness of %d\n",
 
79
                       intensity);
 
80
 
 
81
        return intensity;
 
82
}
 
83
 
 
84
static const struct hw_data intel_chipset_data = {
 
85
        .iostart = 0xb2,
 
86
        .iolen = 2,
 
87
        .backlight_ops  = {
 
88
                .options        = BL_CORE_SUSPENDRESUME,
 
89
                .get_brightness = intel_chipset_get_intensity,
 
90
                .update_status  = intel_chipset_send_intensity,
 
91
        },
 
92
        .set_brightness = intel_chipset_set_brightness,
 
93
};
 
94
 
 
95
/*
 
96
 * Implementation for machines with Nvidia chipset.
 
97
 */
 
98
static void nvidia_chipset_set_brightness(int intensity)
 
99
{
 
100
        outb(0x04 | (intensity << 4), 0x52f);
 
101
        outb(0xbf, 0x52e);
 
102
}
 
103
 
 
104
static int nvidia_chipset_send_intensity(struct backlight_device *bd)
 
105
{
 
106
        int intensity = bd->props.brightness;
 
107
 
 
108
        if (debug)
 
109
                printk(KERN_DEBUG DRIVER "setting brightness to %d\n",
 
110
                       intensity);
 
111
 
 
112
        nvidia_chipset_set_brightness(intensity);
 
113
        return 0;
 
114
}
 
115
 
 
116
static int nvidia_chipset_get_intensity(struct backlight_device *bd)
 
117
{
 
118
        int intensity;
 
119
 
 
120
        outb(0x03, 0x52f);
 
121
        outb(0xbf, 0x52e);
 
122
        intensity = inb(0x52f) >> 4;
 
123
 
 
124
        if (debug)
 
125
                printk(KERN_DEBUG DRIVER "read brightness of %d\n",
 
126
                       intensity);
 
127
 
 
128
        return intensity;
 
129
}
 
130
 
 
131
static const struct hw_data nvidia_chipset_data = {
 
132
        .iostart = 0x52e,
 
133
        .iolen = 2,
 
134
        .backlight_ops          = {
 
135
                .options        = BL_CORE_SUSPENDRESUME,
 
136
                .get_brightness = nvidia_chipset_get_intensity,
 
137
                .update_status  = nvidia_chipset_send_intensity
 
138
        },
 
139
        .set_brightness = nvidia_chipset_set_brightness,
 
140
};
 
141
 
 
142
static int __devinit apple_bl_add(struct acpi_device *dev)
 
143
{
 
144
        struct backlight_properties props;
 
145
        struct pci_dev *host;
 
146
        int intensity;
 
147
 
 
148
        host = pci_get_bus_and_slot(0, 0);
 
149
 
 
150
        if (!host) {
 
151
                printk(KERN_ERR DRIVER "unable to find PCI host\n");
 
152
                return -ENODEV;
 
153
        }
 
154
 
 
155
        if (host->vendor == PCI_VENDOR_ID_INTEL)
 
156
                hw_data = &intel_chipset_data;
 
157
        else if (host->vendor == PCI_VENDOR_ID_NVIDIA)
 
158
                hw_data = &nvidia_chipset_data;
 
159
 
 
160
        pci_dev_put(host);
 
161
 
 
162
        if (!hw_data) {
 
163
                printk(KERN_ERR DRIVER "unknown hardware\n");
 
164
                return -ENODEV;
 
165
        }
 
166
 
 
167
        /* Check that the hardware responds - this may not work under EFI */
 
168
 
 
169
        intensity = hw_data->backlight_ops.get_brightness(NULL);
 
170
 
 
171
        if (!intensity) {
 
172
                hw_data->set_brightness(1);
 
173
                if (!hw_data->backlight_ops.get_brightness(NULL))
 
174
                        return -ENODEV;
 
175
 
 
176
                hw_data->set_brightness(0);
 
177
        }
 
178
 
 
179
        if (!request_region(hw_data->iostart, hw_data->iolen,
 
180
                            "Apple backlight"))
 
181
                return -ENXIO;
 
182
 
 
183
        memset(&props, 0, sizeof(struct backlight_properties));
 
184
        props.type = BACKLIGHT_PLATFORM;
 
185
        props.max_brightness = 15;
 
186
        apple_backlight_device = backlight_device_register("apple_backlight",
 
187
                                  NULL, NULL, &hw_data->backlight_ops, &props);
 
188
 
 
189
        if (IS_ERR(apple_backlight_device)) {
 
190
                release_region(hw_data->iostart, hw_data->iolen);
 
191
                return PTR_ERR(apple_backlight_device);
 
192
        }
 
193
 
 
194
        apple_backlight_device->props.brightness =
 
195
                hw_data->backlight_ops.get_brightness(apple_backlight_device);
 
196
        backlight_update_status(apple_backlight_device);
 
197
 
 
198
        return 0;
 
199
}
 
200
 
 
201
static int __devexit apple_bl_remove(struct acpi_device *dev, int type)
 
202
{
 
203
        backlight_device_unregister(apple_backlight_device);
 
204
 
 
205
        release_region(hw_data->iostart, hw_data->iolen);
 
206
        hw_data = NULL;
 
207
        return 0;
 
208
}
 
209
 
 
210
static const struct acpi_device_id apple_bl_ids[] = {
 
211
        {"APP0002", 0},
 
212
        {"", 0},
 
213
};
 
214
 
 
215
static struct acpi_driver apple_bl_driver = {
 
216
        .name = "Apple backlight",
 
217
        .ids = apple_bl_ids,
 
218
        .ops = {
 
219
                .add = apple_bl_add,
 
220
                .remove = apple_bl_remove,
 
221
        },
 
222
};
 
223
 
 
224
static int __init apple_bl_init(void)
 
225
{
 
226
        return acpi_bus_register_driver(&apple_bl_driver);
 
227
}
 
228
 
 
229
static void __exit apple_bl_exit(void)
 
230
{
 
231
        acpi_bus_unregister_driver(&apple_bl_driver);
 
232
}
 
233
 
 
234
module_init(apple_bl_init);
 
235
module_exit(apple_bl_exit);
 
236
 
 
237
MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
 
238
MODULE_DESCRIPTION("Apple Backlight Driver");
 
239
MODULE_LICENSE("GPL");
 
240
MODULE_DEVICE_TABLE(acpi, apple_bl_ids);
 
241
MODULE_ALIAS("mbp_nvidia_bl");