View | Details | Raw Unified | Return to bug 308264
Collapse All | Expand All

(-)a/Documentation/thinkpad-acpi.txt (-108 / +495 lines)
Lines 1-11 Link Here
1
		     ThinkPad ACPI Extras Driver
1
		     ThinkPad ACPI Extras Driver
2
2
3
                            Version 0.14
3
                            Version 0.19
4
                          April 21st, 2007
4
                         January 06th, 2008
5
5
6
               Borislav Deianov <borislav@users.sf.net>
6
               Borislav Deianov <borislav@users.sf.net>
7
	     Henrique de Moraes Holschuh <hmh@hmh.eng.br>
7
             Henrique de Moraes Holschuh <hmh@hmh.eng.br>
8
		      http://ibm-acpi.sf.net/
8
                      http://ibm-acpi.sf.net/
9
9
10
10
11
This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It
11
This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It
Lines 105-114 The version of thinkpad-acpi's sysfs interface is exported by the driver Link Here
105
as a driver attribute (see below).
105
as a driver attribute (see below).
106
106
107
Sysfs driver attributes are on the driver's sysfs attribute space,
107
Sysfs driver attributes are on the driver's sysfs attribute space,
108
for 2.6.20 this is /sys/bus/platform/drivers/thinkpad-acpi/.
108
for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
109
/sys/bus/platform/drivers/thinkpad_hwmon/
109
110
110
Sysfs device attributes are on the driver's sysfs attribute space,
111
Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
111
for 2.6.20 this is /sys/devices/platform/thinkpad-acpi/.
112
space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
113
114
Sysfs device attributes for the sensors and fan are on the
115
thinkpad_hwmon device's sysfs attribute space, but you should locate it
116
looking for a hwmon device with the name attribute of "thinkpad".
112
117
113
Driver version
118
Driver version
114
--------------
119
--------------
Lines 134-187 end of this document. Changes to the sysfs interface done by the kernel Link Here
134
subsystems are not documented here, nor are they tracked by this
139
subsystems are not documented here, nor are they tracked by this
135
attribute.
140
attribute.
136
141
142
Changes to the thinkpad-acpi sysfs interface are only considered
143
non-experimental when they are submitted to Linux mainline, at which
144
point the changes in this interface are documented and interface_version
145
may be updated.  If you are using any thinkpad-acpi features not yet
146
sent to mainline for merging, you do so on your own risk: these features
147
may disappear, or be implemented in a different and incompatible way by
148
the time they are merged in Linux mainline.
149
150
Changes that are backwards-compatible by nature (e.g. the addition of
151
attributes that do not change the way the other attributes work) do not
152
always warrant an update of interface_version.  Therefore, one must
153
expect that an attribute might not be there, and deal with it properly
154
(an attribute not being there *is* a valid way to make it clear that a
155
feature is not available in sysfs).
156
137
Hot keys
157
Hot keys
138
--------
158
--------
139
159
140
procfs: /proc/acpi/ibm/hotkey
160
procfs: /proc/acpi/ibm/hotkey
141
sysfs device attribute: hotkey_*
161
sysfs device attribute: hotkey_*
142
162
143
Without this driver, only the Fn-F4 key (sleep button) generates an
163
In a ThinkPad, the ACPI HKEY handler is responsible for comunicating
144
ACPI event. With the driver loaded, the hotkey feature enabled and the
164
some important events and also keyboard hot key presses to the operating
145
mask set (see below), the various hot keys generate ACPI events in the
165
system.  Enabling the hotkey functionality of thinkpad-acpi signals the
146
following format:
166
firmware that such a driver is present, and modifies how the ThinkPad
167
firmware will behave in many situations.
168
169
The driver enables the hot key feature automatically when loaded.  The
170
feature can later be disabled and enabled back at runtime.  The driver
171
will also restore the hot key feature to its previous state and mask
172
when it is unloaded.
173
174
When the hotkey feature is enabled and the hot key mask is set (see
175
below), the driver will report HKEY events in the following format:
147
176
148
	ibm/hotkey HKEY 00000080 0000xxxx
177
	ibm/hotkey HKEY 00000080 0000xxxx
149
178
150
The last four digits vary depending on the key combination pressed.
179
Some of these events refer to hot key presses, but not all.
151
All labeled Fn-Fx key combinations generate distinct events. In
180
152
addition, the lid microswitch and some docking station buttons may
181
The driver will generate events over the input layer for hot keys and
153
also generate such events.
182
radio switches, and over the ACPI netlink layer for other events.  The
154
183
input layer support accepts the standard IOCTLs to remap the keycodes
155
The bit mask allows some control over which hot keys generate ACPI
184
assigned to each hot key.
156
events. Not all bits in the mask can be modified. Not all bits that
185
157
can be modified do anything. Not all hot keys can be individually
186
The hot key bit mask allows some control over which hot keys generate
158
controlled by the mask. Most recent ThinkPad models honor the
187
events.  If a key is "masked" (bit set to 0 in the mask), the firmware
159
following bits (assuming the hot keys feature has been enabled):
188
will handle it.  If it is "unmasked", it signals the firmware that
160
189
thinkpad-acpi would prefer to handle it, if the firmware would be so
161
	key	bit	behavior when set	behavior when unset
190
kind to allow it (and it often doesn't!).
162
191
163
	Fn-F3			always generates ACPI event
192
Not all bits in the mask can be modified.  Not all bits that can be
164
	Fn-F4			always generates ACPI event
193
modified do anything.  Not all hot keys can be individually controlled
165
	Fn-F5	0010	generate ACPI event	enable/disable Bluetooth
194
by the mask.  Some models do not support the mask at all, and in those
166
	Fn-F7	0040	generate ACPI event	switch LCD and external display
195
models, hot keys cannot be controlled individually.  The behaviour of
167
	Fn-F8	0080	generate ACPI event	expand screen or none
196
the mask is, therefore, higly dependent on the ThinkPad model.
168
	Fn-F9	0100	generate ACPI event	none
197
169
	Fn-F12			always generates ACPI event
198
Note that unmasking some keys prevents their default behavior.  For
170
199
example, if Fn+F5 is unmasked, that key will no longer enable/disable
171
Some models do not support all of the above. For example, the T30 does
200
Bluetooth by itself.
172
not support Fn-F5 and Fn-F9. Other models do not support the mask at
201
173
all. On those models, hot keys cannot be controlled individually.
202
Note also that not all Fn key combinations are supported through ACPI.
174
203
For example, on the X40, the brightness, volume and "Access IBM" buttons
175
Note that enabling ACPI events for some keys prevents their default
204
do not generate ACPI events even with this driver.  They *can* be used
176
behavior. For example, if events for Fn-F5 are enabled, that key will
205
through the "ThinkPad Buttons" utility, see http://www.nongnu.org/tpb/
177
no longer enable/disable Bluetooth by itself. This can still be done
178
from an acpid handler for the ibm/hotkey event.
179
180
Note also that not all Fn key combinations are supported through
181
ACPI. For example, on the X40, the brightness, volume and "Access IBM"
182
buttons do not generate ACPI events even with this driver. They *can*
183
be used through the "ThinkPad Buttons" utility, see
184
http://www.nongnu.org/tpb/
185
206
186
procfs notes:
207
procfs notes:
187
208
Lines 189-199 The following commands can be written to the /proc/acpi/ibm/hotkey file: Link Here
189
210
190
	echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
211
	echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
191
	echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
212
	echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
192
	echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys
213
	echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
193
	echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
214
	echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
194
	... any other 4-hex-digit mask ...
215
	... any other 8-hex-digit mask ...
195
	echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
216
	echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
196
217
218
The procfs interface does not support NVRAM polling control.  So as to
219
maintain maximum bug-to-bug compatibility, it does not report any masks,
220
nor does it allow one to manipulate the hot key mask when the firmware
221
does not support masks at all, even if NVRAM polling is in use.
222
197
sysfs notes:
223
sysfs notes:
198
224
199
	hotkey_bios_enabled:
225
	hotkey_bios_enabled:
Lines 202-208 sysfs notes: Link Here
202
		key feature status will be restored to this value.
228
		key feature status will be restored to this value.
203
229
204
		0: hot keys were disabled
230
		0: hot keys were disabled
205
		1: hot keys were enabled
231
		1: hot keys were enabled (unusual)
206
232
207
	hotkey_bios_mask:
233
	hotkey_bios_mask:
208
		Returns the hot keys mask when thinkpad-acpi was loaded.
234
		Returns the hot keys mask when thinkpad-acpi was loaded.
Lines 210-225 sysfs notes: Link Here
210
		to this value.
236
		to this value.
211
237
212
	hotkey_enable:
238
	hotkey_enable:
213
		Enables/disables the hot keys feature, and reports
239
		Enables/disables the hot keys feature in the ACPI
214
		current status of the hot keys feature.
240
		firmware, and reports current status of the hot keys
241
		feature.  Has no effect on the NVRAM hot key polling
242
		functionality.
215
243
216
		0: disables the hot keys feature / feature disabled
244
		0: disables the hot keys feature / feature disabled
217
		1: enables the hot keys feature / feature enabled
245
		1: enables the hot keys feature / feature enabled
218
246
219
	hotkey_mask:
247
	hotkey_mask:
220
		bit mask to enable ACPI event generation for each hot
248
		bit mask to enable driver-handling (and depending on
221
		key (see above).  Returns the current status of the hot
249
		the firmware, ACPI event generation) for each hot key
222
		keys mask, and allows one to modify it.
250
		(see above).  Returns the current status of the hot keys
251
		mask, and allows one to modify it.
252
253
		Note: when NVRAM polling is active, the firmware mask
254
		will be different from the value returned by
255
		hotkey_mask.  The driver will retain enabled bits for
256
		hotkeys that are under NVRAM polling even if the
257
		firmware refuses them, and will not set these bits on
258
		the firmware hot key mask.
259
260
	hotkey_all_mask:
261
		bit mask that should enable event reporting for all
262
		supported hot keys, when echoed to hotkey_mask above.
263
		Unless you know which events need to be handled
264
		passively (because the firmware *will* handle them
265
		anyway), do *not* use hotkey_all_mask.  Use
266
		hotkey_recommended_mask, instead. You have been warned.
267
268
	hotkey_recommended_mask:
269
		bit mask that should enable event reporting for all
270
		supported hot keys, except those which are always
271
		handled by the firmware anyway.  Echo it to
272
		hotkey_mask above, to use.
273
274
	hotkey_source_mask:
275
		bit mask that selects which hot keys will the driver
276
		poll the NVRAM for.  This is auto-detected by the driver
277
		based on the capabilities reported by the ACPI firmware,
278
		but it can be overridden at runtime.
279
280
		Hot keys whose bits are set in both hotkey_source_mask
281
		and also on hotkey_mask are polled for in NVRAM.  Only a
282
		few hot keys are available through CMOS NVRAM polling.
283
284
		Warning: when in NVRAM mode, the volume up/down/mute
285
		keys are synthesized according to changes in the mixer,
286
		so you have to use volume up or volume down to unmute,
287
		as per the ThinkPad volume mixer user interface.  When
288
		in ACPI event mode, volume up/down/mute are reported as
289
		separate events, but this behaviour may be corrected in
290
		future releases of this driver, in which case the
291
		ThinkPad volume mixer user interface semanthics will be
292
		enforced.
293
294
	hotkey_poll_freq:
295
		frequency in Hz for hot key polling. It must be between
296
		0 and 25 Hz.  Polling is only carried out when strictly
297
		needed.
298
299
		Setting hotkey_poll_freq to zero disables polling, and
300
		will cause hot key presses that require NVRAM polling
301
		to never be reported.
302
303
		Setting hotkey_poll_freq too low will cause repeated
304
		pressings of the same hot key to be misreported as a
305
		single key press, or to not even be detected at all.
306
		The recommended polling frequency is 10Hz.
307
308
	hotkey_radio_sw:
309
		if the ThinkPad has a hardware radio switch, this
310
		attribute will read 0 if the switch is in the "radios
311
		disabled" postition, and 1 if the switch is in the
312
		"radios enabled" position.
313
314
		This attribute has poll()/select() support.
315
316
	hotkey_report_mode:
317
		Returns the state of the procfs ACPI event report mode
318
		filter for hot keys.  If it is set to 1 (the default),
319
		all hot key presses are reported both through the input
320
		layer and also as ACPI events through procfs (but not
321
		through netlink).  If it is set to 2, hot key presses
322
		are reported only through the input layer.
323
324
		This attribute is read-only in kernels 2.6.23 or later,
325
		and read-write on earlier kernels.
326
327
		May return -EPERM (write access locked out by module
328
		parameter) or -EACCES (read-only).
329
330
	wakeup_reason:
331
		Set to 1 if the system is waking up because the user
332
		requested a bay ejection.  Set to 2 if the system is
333
		waking up because the user requested the system to
334
		undock.  Set to zero for normal wake-ups or wake-ups
335
		due to unknown reasons.
336
337
		This attribute has poll()/select() support.
338
339
	wakeup_hotunplug_complete:
340
		Set to 1 if the system was waken up because of an
341
		undock or bay ejection request, and that request
342
		was sucessfully completed.  At this point, it might
343
		be useful to send the system back to sleep, at the
344
		user's choice.  Refer to HKEY events 0x4003 and
345
		0x3003, below.
346
347
		This attribute has poll()/select() support.
348
349
input layer notes:
350
351
A Hot key is mapped to a single input layer EV_KEY event, possibly
352
followed by an EV_MSC MSC_SCAN event that shall contain that key's scan
353
code.  An EV_SYN event will always be generated to mark the end of the
354
event block.
355
356
Do not use the EV_MSC MSC_SCAN events to process keys.  They are to be
357
used as a helper to remap keys, only.  They are particularly useful when
358
remapping KEY_UNKNOWN keys.
359
360
The events are available in an input device, with the following id:
361
362
	Bus:		BUS_HOST
363
	vendor:		0x1014 (PCI_VENDOR_ID_IBM)  or
364
			0x17aa (PCI_VENDOR_ID_LENOVO)
365
	product:	0x5054 ("TP")
366
	version:	0x4101
367
368
The version will have its LSB incremented if the keymap changes in a
369
backwards-compatible way.  The MSB shall always be 0x41 for this input
370
device.  If the MSB is not 0x41, do not use the device as described in
371
this section, as it is either something else (e.g. another input device
372
exported by a thinkpad driver, such as HDAPS) or its functionality has
373
been changed in a non-backwards compatible way.
374
375
Adding other event types for other functionalities shall be considered a
376
backwards-compatible change for this input device.
377
378
Thinkpad-acpi Hot Key event map (version 0x4101):
379
380
ACPI	Scan
381
event	code	Key		Notes
382
383
0x1001	0x00	FN+F1		-
384
0x1002	0x01	FN+F2		IBM: battery (rare)
385
				Lenovo: Screen lock
386
387
0x1003	0x02	FN+F3		Many IBM models always report
388
				this hot key, even with hot keys
389
				disabled or with Fn+F3 masked
390
				off
391
				IBM: screen lock
392
				Lenovo: battery
393
394
0x1004	0x03	FN+F4		Sleep button (ACPI sleep button
395
				semanthics, i.e. sleep-to-RAM).
396
				It is always generate some kind
397
				of event, either the hot key
398
				event or a ACPI sleep button
399
				event. The firmware may
400
				refuse to generate further FN+F4
401
				key presses until a S3 or S4 ACPI
402
				sleep cycle is performed or some
403
				time passes.
404
405
0x1005	0x04	FN+F5		Radio.  Enables/disables
406
				the internal BlueTooth hardware
407
				and W-WAN card if left in control
408
				of the firmware.  Does not affect
409
				the WLAN card.
410
				Should be used to turn on/off all
411
				radios (bluetooth+W-WAN+WLAN),
412
				really.
413
414
0x1006	0x05	FN+F6		-
415
416
0x1007	0x06	FN+F7		Video output cycle.
417
				Do you feel lucky today?
418
419
0x1008	0x07	FN+F8		IBM: toggle screen expand
420
				Lenovo: configure ultranav
421
422
0x1009	0x08	FN+F9		-
423
	..	..		..
424
0x100B	0x0A	FN+F11		-
425
426
0x100C	0x0B	FN+F12		Sleep to disk.  You are always
427
				supposed to handle it yourself,
428
				either through the ACPI event,
429
				or through a hotkey event.
430
				The firmware may refuse to
431
				generate further FN+F4 key
432
				press events until a S3 or S4
433
				ACPI sleep cycle is performed,
434
				or some time passes.
435
436
0x100D	0x0C	FN+BACKSPACE	-
437
0x100E	0x0D	FN+INSERT	-
438
0x100F	0x0E	FN+DELETE	-
439
440
0x1010	0x0F	FN+HOME		Brightness up.  This key is
441
				always handled by the firmware
442
				in IBM ThinkPads, even when
443
				unmasked.  Just leave it alone.
444
				For Lenovo ThinkPads with a new
445
				BIOS, it has to be handled either
446
				by the ACPI OSI, or by userspace.
447
0x1011	0x10	FN+END		Brightness down.  See brightness
448
				up for details.
449
450
0x1012	0x11	FN+PGUP		Thinklight toggle.  This key is
451
				always handled by the firmware,
452
				even when unmasked.
453
454
0x1013	0x12	FN+PGDOWN	-
455
456
0x1014	0x13	FN+SPACE	Zoom key
457
458
0x1015	0x14	VOLUME UP	Internal mixer volume up. This
459
				key is always handled by the
460
				firmware, even when unmasked.
461
				NOTE: Lenovo seems to be changing
462
				this.
463
0x1016	0x15	VOLUME DOWN	Internal mixer volume up. This
464
				key is always handled by the
465
				firmware, even when unmasked.
466
				NOTE: Lenovo seems to be changing
467
				this.
468
0x1017	0x16	MUTE		Mute internal mixer. This
469
				key is always handled by the
470
				firmware, even when unmasked.
471
472
0x1018	0x17	THINKPAD	Thinkpad/Access IBM/Lenovo key
473
474
0x1019	0x18	unknown
475
..	..	..
476
0x1020	0x1F	unknown
477
478
The ThinkPad firmware does not allow one to differentiate when most hot
479
keys are pressed or released (either that, or we don't know how to, yet).
480
For these keys, the driver generates a set of events for a key press and
481
immediately issues the same set of events for a key release.  It is
482
unknown by the driver if the ThinkPad firmware triggered these events on
483
hot key press or release, but the firmware will do it for either one, not
484
both.
485
486
If a key is mapped to KEY_RESERVED, it generates no input events at all.
487
If a key is mapped to KEY_UNKNOWN, it generates an input event that
488
includes an scan code.  If a key is mapped to anything else, it will
489
generate input device EV_KEY events.
490
491
Non hot-key ACPI HKEY event map:
492
0x5001		Lid closed
493
0x5002		Lid opened
494
0x7000		Radio Switch may have changed state
495
496
The above events are not propagated by the driver, except for legacy
497
compatibility purposes when hotkey_report_mode is set to 1.
498
499
0x2304		System is waking up from suspend to undock
500
0x2305		System is waking up from suspend to eject bay
501
0x2404		System is waking up from hibernation to undock
502
0x2405		System is waking up from hibernation to eject bay
503
504
The above events are never propagated by the driver.
505
506
0x3003		Bay ejection (see 0x2x05) complete, can sleep again
507
0x4003		Undocked (see 0x2x04), can sleep again
508
0x5009		Tablet swivel: switched to tablet mode
509
0x500A		Tablet swivel: switched to normal mode
510
0x500B		Tablet pen insterted into its storage bay
511
0x500C		Tablet pen removed from its storage bay
512
0x5010		Brightness level changed (newer Lenovo BIOSes)
513
514
The above events are propagated by the driver.
515
516
Compatibility notes:
517
518
ibm-acpi and thinkpad-acpi 0.15 (mainline kernels before 2.6.23) never
519
supported the input layer, and sent events over the procfs ACPI event
520
interface.
521
522
To avoid sending duplicate events over the input layer and the ACPI
523
event interface, thinkpad-acpi 0.16 implements a module parameter
524
(hotkey_report_mode), and also a sysfs device attribute with the same
525
name.
526
527
Make no mistake here: userspace is expected to switch to using the input
528
layer interface of thinkpad-acpi, together with the ACPI netlink event
529
interface in kernels 2.6.23 and later, or with the ACPI procfs event
530
interface in kernels 2.6.22 and earlier.
531
532
If no hotkey_report_mode module parameter is specified (or it is set to
533
zero), the driver defaults to mode 1 (see below), and on kernels 2.6.22
534
and earlier, also allows one to change the hotkey_report_mode through
535
sysfs.  In kernels 2.6.23 and later, where the netlink ACPI event
536
interface is available, hotkey_report_mode cannot be changed through
537
sysfs (it is read-only).
538
539
If the hotkey_report_mode module parameter is set to 1 or 2, it cannot
540
be changed later through sysfs (any writes will return -EPERM to signal
541
that hotkey_report_mode was locked.  On 2.6.23 and later, where
542
hotkey_report_mode cannot be changed at all, writes will return -EACES).
543
544
hotkey_report_mode set to 1 makes the driver export through the procfs
545
ACPI event interface all hot key presses (which are *also* sent to the
546
input layer).  This is a legacy compatibility behaviour, and it is also
547
the default mode of operation for the driver.
548
549
hotkey_report_mode set to 2 makes the driver filter out the hot key
550
presses from the procfs ACPI event interface, so these events will only
551
be sent through the input layer.  Userspace that has been updated to use
552
the thinkpad-acpi input layer interface should set hotkey_report_mode to
553
2.
554
555
Hot key press events are never sent to the ACPI netlink event interface.
556
Really up-to-date userspace under kernel 2.6.23 and later is to use the
557
netlink interface and the input layer interface, and don't bother at all
558
with hotkey_report_mode.
223
559
224
560
225
Bluetooth
561
Bluetooth
Lines 437-463 CMOS control Link Here
437
procfs: /proc/acpi/ibm/cmos
773
procfs: /proc/acpi/ibm/cmos
438
sysfs device attribute: cmos_command
774
sysfs device attribute: cmos_command
439
775
440
This feature is used internally by the ACPI firmware to control the
776
This feature is mostly used internally by the ACPI firmware to keep the legacy
441
ThinkLight on most newer ThinkPad models. It may also control LCD
777
CMOS NVRAM bits in sync with the current machine state, and to record this
442
brightness, sounds volume and more, but only on some models.
778
state so that the ThinkPad will retain such settings across reboots.
779
780
Some of these commands actually perform actions in some ThinkPad models, but
781
this is expected to disappear more and more in newer models.  As an example, in
782
a T43 and in a X40, commands 12 and 13 still control the ThinkLight state for
783
real, but commands 0 to 2 don't control the mixer anymore (they have been
784
phased out) and just update the NVRAM.
443
785
444
The range of valid cmos command numbers is 0 to 21, but not all have an
786
The range of valid cmos command numbers is 0 to 21, but not all have an
445
effect and the behavior varies from model to model.  Here is the behavior
787
effect and the behavior varies from model to model.  Here is the behavior
446
on the X40 (tpb is the ThinkPad Buttons utility):
788
on the X40 (tpb is the ThinkPad Buttons utility):
447
789
448
	0 - no effect but tpb reports "Volume down"
790
	0 - Related to "Volume down" key press
449
	1 - no effect but tpb reports "Volume up"
791
	1 - Related to "Volume up" key press
450
	2 - no effect but tpb reports "Mute on"
792
	2 - Related to "Mute on" key press
451
	3 - simulate pressing the "Access IBM" button
793
	3 - Related to "Access IBM" key press
452
	4 - LCD brightness up
794
	4 - Related to "LCD brightness up" key pess
453
	5 - LCD brightness down
795
	5 - Related to "LCD brightness down" key press
454
	11 - toggle screen expansion
796
	11 - Related to "toggle screen expansion" key press/function
455
	12 - ThinkLight on
797
	12 - Related to "ThinkLight on"
456
	13 - ThinkLight off
798
	13 - Related to "ThinkLight off"
457
	14 - no effect but tpb reports ThinkLight status change
799
	14 - Related to "ThinkLight" key press (toggle thinklight)
458
800
459
The cmos command interface is prone to firmware split-brain problems, as
801
The cmos command interface is prone to firmware split-brain problems, as
460
in newer ThinkPads it is just a compatibility layer.
802
in newer ThinkPads it is just a compatibility layer.  Do not use it, it is
803
exported just as a debug tool.
461
804
462
LED control -- /proc/acpi/ibm/led
805
LED control -- /proc/acpi/ibm/led
463
---------------------------------
806
---------------------------------
Lines 514-538 Temperature sensors Link Here
514
-------------------
857
-------------------
515
858
516
procfs: /proc/acpi/ibm/thermal
859
procfs: /proc/acpi/ibm/thermal
517
sysfs device attributes: (hwmon) temp*_input
860
sysfs device attributes: (hwmon "thinkpad") temp*_input
518
519
Most ThinkPads include six or more separate temperature sensors but
520
only expose the CPU temperature through the standard ACPI methods.
521
This feature shows readings from up to eight different sensors on older
522
ThinkPads, and it has experimental support for up to sixteen different
523
sensors on newer ThinkPads.
524
861
525
EXPERIMENTAL: The 16-sensors feature is marked EXPERIMENTAL because the
862
Most ThinkPads include six or more separate temperature sensors but only
526
implementation directly accesses hardware registers and may not work as
863
expose the CPU temperature through the standard ACPI methods.  This
527
expected. USE WITH CAUTION! To use this feature, you need to supply the
864
feature shows readings from up to eight different sensors on older
528
experimental=1 parameter when loading the module.  When EXPERIMENTAL
865
ThinkPads, and up to sixteen different sensors on newer ThinkPads.
529
mode is enabled, reading the first 8 sensors on newer ThinkPads will
530
also use an new experimental thermal sensor access mode.
531
866
532
For example, on the X40, a typical output may be:
867
For example, on the X40, a typical output may be:
533
temperatures:   42 42 45 41 36 -128 33 -128
868
temperatures:   42 42 45 41 36 -128 33 -128
534
869
535
EXPERIMENTAL: On the T43/p, a typical output may be:
870
On the T43/p, a typical output may be:
536
temperatures:   48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128
871
temperatures:   48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128
537
872
538
The mapping of thermal sensors to physical locations varies depending on
873
The mapping of thermal sensors to physical locations varies depending on
Lines 562-568 http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p Link Here
562
2:  System board, left side (near PCMCIA slot), reported as HDAPS temp
897
2:  System board, left side (near PCMCIA slot), reported as HDAPS temp
563
3:  PCMCIA slot
898
3:  PCMCIA slot
564
9:  MCH (northbridge) to DRAM Bus
899
9:  MCH (northbridge) to DRAM Bus
565
10: ICH (southbridge), under Mini-PCI card, under touchpad
900
10: Clock-generator, mini-pci card and ICH (southbridge), under Mini-PCI
901
    card, under touchpad
566
11: Power regulator, underside of system board, below F2 key
902
11: Power regulator, underside of system board, below F2 key
567
903
568
The A31 has a very atypical layout for the thermal sensors
904
The A31 has a very atypical layout for the thermal sensors
Lines 673-685 sysfs backlight device "thinkpad_screen" Link Here
673
This feature allows software control of the LCD brightness on ThinkPad
1009
This feature allows software control of the LCD brightness on ThinkPad
674
models which don't have a hardware brightness slider.
1010
models which don't have a hardware brightness slider.
675
1011
676
It has some limitations: the LCD backlight cannot be actually turned on or off
1012
It has some limitations: the LCD backlight cannot be actually turned on or
677
by this interface, and in many ThinkPad models, the "dim while on battery"
1013
off by this interface, and in many ThinkPad models, the "dim while on
678
functionality will be enabled by the BIOS when this interface is used, and
1014
battery" functionality will be enabled by the BIOS when this interface is
679
cannot be controlled.
1015
used, and cannot be controlled.
680
1016
681
The backlight control has eight levels, ranging from 0 to 7.  Some of the
1017
On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control
682
levels may not be distinct.
1018
has eight brightness levels, ranging from 0 to 7.  Some of the levels
1019
may not be distinct.  Later Lenovo models that implement the ACPI
1020
display backlight brightness control methods have 16 levels, ranging
1021
from 0 to 15.
1022
1023
There are two interfaces to the firmware for direct brightness control,
1024
EC and CMOS.  To select which one should be used, use the
1025
brightness_mode module parameter: brightness_mode=1 selects EC mode,
1026
brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC
1027
and CMOS.  The driver tries to autodetect which interface to use.
1028
1029
When display backlight brightness controls are available through the
1030
standard ACPI interface, it is best to use it instead of this direct
1031
ThinkPad-specific interface.  The driver will disable its native
1032
backlight brightness control interface if it detects that the standard
1033
ACPI interface is available in the ThinkPad.
1034
1035
The brightness_enable module parameter can be used to control whether
1036
the LCD brightness control feature will be enabled when available.
1037
brightness_enable=0 forces it to be disabled.  brightness_enable=1
1038
forces it to be enabled when available, even if the standard ACPI
1039
interface is also available.
683
1040
684
Procfs notes:
1041
Procfs notes:
685
1042
Lines 691-701 Procfs notes: Link Here
691
1048
692
Sysfs notes:
1049
Sysfs notes:
693
1050
694
The interface is implemented through the backlight sysfs class, which is poorly
1051
The interface is implemented through the backlight sysfs class, which is
695
documented at this time.
1052
poorly documented at this time.
696
1053
697
Locate the thinkpad_screen device under /sys/class/backlight, and inside it
1054
Locate the thinkpad_screen device under /sys/class/backlight, and inside
698
there will be the following attributes:
1055
it there will be the following attributes:
699
1056
700
	max_brightness:
1057
	max_brightness:
701
		Reads the maximum brightness the hardware can be set to.
1058
		Reads the maximum brightness the hardware can be set to.
Lines 705-721 there will be the following attributes: Link Here
705
		Reads what brightness the screen is set to at this instant.
1062
		Reads what brightness the screen is set to at this instant.
706
1063
707
	brightness:
1064
	brightness:
708
		Writes request the driver to change brightness to the given
1065
		Writes request the driver to change brightness to the
709
		value.  Reads will tell you what brightness the driver is trying
1066
		given value.  Reads will tell you what brightness the
710
		to set the display to when "power" is set to zero and the display
1067
		driver is trying to set the display to when "power" is set
711
		has not been dimmed by a kernel power management event.
1068
		to zero and the display has not been dimmed by a kernel
1069
		power management event.
712
1070
713
	power:
1071
	power:
714
		power management mode, where 0 is "display on", and 1 to 3 will
1072
		power management mode, where 0 is "display on", and 1 to 3
715
		dim the display backlight to brightness level 0 because
1073
		will dim the display backlight to brightness level 0
716
		thinkpad-acpi cannot really turn the backlight off.  Kernel
1074
		because thinkpad-acpi cannot really turn the backlight
717
		power management events can temporarily increase the current
1075
		off.  Kernel power management events can temporarily
718
		power management level, i.e. they can dim the display.
1076
		increase the current power management level, i.e. they can
1077
		dim the display.
719
1078
720
1079
721
Volume control -- /proc/acpi/ibm/volume
1080
Volume control -- /proc/acpi/ibm/volume
Lines 738-744 Fan control and monitoring: fan speed, fan enable/disable Link Here
738
---------------------------------------------------------
1097
---------------------------------------------------------
739
1098
740
procfs: /proc/acpi/ibm/fan
1099
procfs: /proc/acpi/ibm/fan
741
sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable
1100
sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1,
1101
			  pwm1_enable
1102
sysfs hwmon driver attributes: fan_watchdog
742
1103
743
NOTE NOTE NOTE: fan control operations are disabled by default for
1104
NOTE NOTE NOTE: fan control operations are disabled by default for
744
safety reasons.  To enable them, the module parameter "fan_control=1"
1105
safety reasons.  To enable them, the module parameter "fan_control=1"
Lines 777-783 enable it if necessary to avoid overheating. Link Here
777
1138
778
An enabled fan in level "auto" may stop spinning if the EC decides the
1139
An enabled fan in level "auto" may stop spinning if the EC decides the
779
ThinkPad is cool enough and doesn't need the extra airflow.  This is
1140
ThinkPad is cool enough and doesn't need the extra airflow.  This is
780
normal, and the EC will spin the fan up if the varios thermal readings
1141
normal, and the EC will spin the fan up if the various thermal readings
781
rise too much.
1142
rise too much.
782
1143
783
On the X40, this seems to depend on the CPU and HDD temperatures.
1144
On the X40, this seems to depend on the CPU and HDD temperatures.
Lines 880-886 hwmon device attribute fan1_input: Link Here
880
	which can take up to two minutes.  May return rubbish on older
1241
	which can take up to two minutes.  May return rubbish on older
881
	ThinkPads.
1242
	ThinkPads.
882
1243
883
driver attribute fan_watchdog:
1244
hwmon driver attribute fan_watchdog:
884
	Fan safety watchdog timer interval, in seconds.  Minimum is
1245
	Fan safety watchdog timer interval, in seconds.  Minimum is
885
	1 second, maximum is 120 seconds.  0 disables the watchdog.
1246
	1 second, maximum is 120 seconds.  0 disables the watchdog.
886
1247
Lines 945-951 for example: Link Here
945
Enabling debugging output
1306
Enabling debugging output
946
-------------------------
1307
-------------------------
947
1308
948
The module takes a debug paramater which can be used to selectively
1309
The module takes a debug parameter which can be used to selectively
949
enable various classes of debugging output, for example:
1310
enable various classes of debugging output, for example:
950
1311
951
	 modprobe ibm_acpi debug=0xffff
1312
	 modprobe ibm_acpi debug=0xffff
Lines 976-978 Sysfs interface changelog: Link Here
976
1337
977
0x000100:	Initial sysfs support, as a single platform driver and
1338
0x000100:	Initial sysfs support, as a single platform driver and
978
		device.
1339
		device.
1340
0x000200:	Hot key support for 32 hot keys, and radio slider switch
1341
		support.
1342
0x010000:	Hot keys are now handled by default over the input
1343
		layer, the radio switch generates input event EV_RADIO,
1344
		and the driver enables hot key handling by default in
1345
		the firmware.
1346
1347
0x020000:	ABI fix: added a separate hwmon platform device and
1348
		driver, which must be located by name (thinkpad)
1349
		and the hwmon class for libsensors4 (lm-sensors 3)
1350
		compatibility.  Moved all hwmon attributes to this
1351
		new platform device.
1352
1353
0x020100:	Marker for thinkpad-acpi with hot key NVRAM polling
1354
		support.  If you must, use it to know you should not
1355
		start an userspace NVRAM poller (allows to detect when
1356
		NVRAM is compiled out by the user because it is
1357
		unneeded/undesired in the first place).
1358
0x020101:	Marker for thinkpad-acpi with hot key NVRAM polling
1359
		and proper hotkey_mask semanthics (version 8 of the
1360
		NVRAM polling patch).  Some development snapshots of
1361
		0.18 had an earlier version that did strange things
1362
		to hotkey_mask.
1363
1364
0x020200:	Add poll()/select() support to the following attributes:
1365
		hotkey_radio_sw, wakeup_hotunplug_complete, wakeup_reason
(-)a/drivers/misc/Kconfig (-2 / +22 lines)
Lines 141-146 config THINKPAD_ACPI Link Here
141
	depends on X86 && ACPI
141
	depends on X86 && ACPI
142
	select BACKLIGHT_CLASS_DEVICE
142
	select BACKLIGHT_CLASS_DEVICE
143
	select HWMON
143
	select HWMON
144
	select NVRAM
144
	---help---
145
	---help---
145
	  This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
146
	  This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
146
	  support for Fn-Fx key combinations, Bluetooth control, video
147
	  support for Fn-Fx key combinations, Bluetooth control, video
Lines 148-154 config THINKPAD_ACPI Link Here
148
	  For more information about this driver see 
149
	  For more information about this driver see 
149
	  <file:Documentation/thinkpad-acpi.txt> and <http://ibm-acpi.sf.net/> .
150
	  <file:Documentation/thinkpad-acpi.txt> and <http://ibm-acpi.sf.net/> .
150
151
151
	  This driver was formely known as ibm-acpi.
152
	  This driver was formerly known as ibm-acpi.
152
153
153
	  If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
154
	  If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
154
155
Lines 182-191 config THINKPAD_ACPI_BAY Link Here
182
	default y
183
	default y
183
	---help---
184
	---help---
184
	  Allows the thinkpad_acpi driver to handle removable bays.  It will
185
	  Allows the thinkpad_acpi driver to handle removable bays.  It will
185
	  eletrically disable the device in the bay, and also generate
186
	  electrically disable the device in the bay, and also generate
186
	  notifications when the bay lever is ejected or inserted.
187
	  notifications when the bay lever is ejected or inserted.
187
188
188
	  If you are not sure, say Y here.
189
	  If you are not sure, say Y here.
189
190
191
config THINKPAD_ACPI_HOTKEY_POLL
192
	bool "Suport NVRAM polling for hot keys"
193
	depends on THINKPAD_ACPI
194
	default y
195
	---help---
196
	  Some thinkpad models benefit from NVRAM polling to detect a few of
197
	  the hot key press events.  If you know your ThinkPad model does not
198
	  need to do NVRAM polling to support any of the hot keys you use,
199
	  unselecting this option will save about 1kB of memory.
200
201
	  ThinkPads T40 and newer, R52 and newer, and X31 and newer are
202
	  unlikely to need NVRAM polling in their latest BIOS versions.
203
204
	  NVRAM polling can detect at most the following keys: ThinkPad/Access
205
	  IBM, Zoom, Switch Display (fn+F7), ThinkLight, Volume up/down/mute,
206
	  Brightness up/down, Display Expand (fn+F8), Hibernate (fn+F12).
207
208
	  If you are not sure, say Y here.  The driver enables polling only if
209
	  it is strictly necessary to do so.
190
210
191
endmenu
211
endmenu
(-)linux-2.6.22-SL103_BRANCH/drivers/misc/thinkpad_acpi.c (-1851 / +3674 lines)
Lines 3-9 Link Here
3
 *
3
 *
4
 *
4
 *
5
 *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
5
 *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
6
 *  Copyright (C) 2006-2007 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
6
 *  Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
7
 *
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
9
 *  it under the terms of the GNU General Public License as published by
Lines 21-31 Link Here
21
 *  02110-1301, USA.
21
 *  02110-1301, USA.
22
 */
22
 */
23
23
24
#define IBM_VERSION "0.14"
24
#define TPACPI_VERSION "0.19-20080107"
25
#define TPACPI_SYSFS_VERSION 0x000100
25
#define TPACPI_SYSFS_VERSION 0x020200
26
26
27
/*
27
/*
28
 *  Changelog:
28
 *  Changelog:
29
 *  2007-10-20		changelog trimmed down
30
 *
29
 *  2007-03-27  0.14	renamed to thinkpad_acpi and moved to
31
 *  2007-03-27  0.14	renamed to thinkpad_acpi and moved to
30
 *  			drivers/misc.
32
 *  			drivers/misc.
31
 *
33
 *
Lines 33-121 Link Here
33
 *  			changelog now lives in git commit history, and will
35
 *  			changelog now lives in git commit history, and will
34
 *  			not be updated further in-file.
36
 *  			not be updated further in-file.
35
 *
37
 *
36
 *  2005-08-17  0.12	fix compilation on 2.6.13-rc kernels
37
 *  2005-03-17	0.11	support for 600e, 770x
38
 *  2005-03-17	0.11	support for 600e, 770x
38
 *			    thanks to Jamie Lentin <lentinj@dial.pipex.com>
39
 *			    thanks to Jamie Lentin <lentinj@dial.pipex.com>
39
 *			support for 770e, G41
40
 *
40
 *			G40 and G41 don't have a thinklight
41
 *  2005-01-16	0.9	use MODULE_VERSION
41
 *			temperatures no longer experimental
42
 *			experimental brightness control
43
 *			experimental volume control
44
 *			experimental fan enable/disable
45
 *  2005-01-16	0.10	fix module loading on R30, R31
46
 *  2005-01-16	0.9	support for 570, R30, R31
47
 *			ultrabay support on A22p, A3x
48
 *			limit arg for cmos, led, beep, drop experimental status
49
 *			more capable led control on A21e, A22p, T20-22, X20
50
 *			experimental temperatures and fan speed
51
 *			experimental embedded controller register dump
52
 *			mark more functions as __init, drop incorrect __exit
53
 *			use MODULE_VERSION
54
 *			    thanks to Henrik Brix Andersen <brix@gentoo.org>
42
 *			    thanks to Henrik Brix Andersen <brix@gentoo.org>
55
 *			fix parameter passing on module loading
43
 *			fix parameter passing on module loading
56
 *			    thanks to Rusty Russell <rusty@rustcorp.com.au>
44
 *			    thanks to Rusty Russell <rusty@rustcorp.com.au>
57
 *			    thanks to Jim Radford <radford@blackbean.org>
45
 *			    thanks to Jim Radford <radford@blackbean.org>
58
 *  2004-11-08	0.8	fix init error case, don't return from a macro
46
 *  2004-11-08	0.8	fix init error case, don't return from a macro
59
 *			    thanks to Chris Wright <chrisw@osdl.org>
47
 *			    thanks to Chris Wright <chrisw@osdl.org>
60
 *  2004-10-23	0.7	fix module loading on A21e, A22p, T20, T21, X20
61
 *			fix led control on A21e
62
 *  2004-10-19	0.6	use acpi_bus_register_driver() to claim HKEY device
63
 *  2004-10-18	0.5	thinklight support on A21e, G40, R32, T20, T21, X20
64
 *			proc file format changed
65
 *			video_switch command
66
 *			experimental cmos control
67
 *			experimental led control
68
 *			experimental acpi sounds
69
 *  2004-09-16	0.4	support for module parameters
70
 *			hotkey mask can be prefixed by 0x
71
 *			video output switching
72
 *			video expansion control
73
 *			ultrabay eject support
74
 *			removed lcd brightness/on/off control, didn't work
75
 *  2004-08-17	0.3	support for R40
76
 *			lcd off, brightness control
77
 *			thinklight on/off
78
 *  2004-08-14	0.2	support for T series, X20
79
 *			bluetooth enable/disable
80
 *			hotkey events disabled by default
81
 *			removed fan control, currently useless
82
 *  2004-08-09	0.1	initial release, support for X series
83
 */
48
 */
84
49
85
#include "thinkpad_acpi.h"
50
#include <linux/kernel.h>
51
#include <linux/module.h>
52
#include <linux/init.h>
53
#include <linux/types.h>
54
#include <linux/string.h>
55
#include <linux/list.h>
56
#include <linux/mutex.h>
57
#include <linux/kthread.h>
58
#include <linux/freezer.h>
59
#include <linux/delay.h>
60
61
#include <linux/nvram.h>
62
#include <linux/proc_fs.h>
63
#include <linux/sysfs.h>
64
#include <linux/backlight.h>
65
#include <linux/fb.h>
66
#include <linux/platform_device.h>
67
#include <linux/hwmon.h>
68
#include <linux/hwmon-sysfs.h>
69
#include <linux/input.h>
70
#include <asm/uaccess.h>
71
72
#include <linux/dmi.h>
73
#include <linux/jiffies.h>
74
#include <linux/workqueue.h>
75
76
#include <acpi/acpi_drivers.h>
77
#include <acpi/acnamesp.h>
78
79
#include <linux/pci_ids.h>
80
81
82
/* ThinkPad CMOS commands */
83
#define TP_CMOS_VOLUME_DOWN	0
84
#define TP_CMOS_VOLUME_UP	1
85
#define TP_CMOS_VOLUME_MUTE	2
86
#define TP_CMOS_BRIGHTNESS_UP	4
87
#define TP_CMOS_BRIGHTNESS_DOWN	5
88
89
/* NVRAM Addresses */
90
enum tp_nvram_addr {
91
	TP_NVRAM_ADDR_HK2		= 0x57,
92
	TP_NVRAM_ADDR_THINKLIGHT	= 0x58,
93
	TP_NVRAM_ADDR_VIDEO		= 0x59,
94
	TP_NVRAM_ADDR_BRIGHTNESS	= 0x5e,
95
	TP_NVRAM_ADDR_MIXER		= 0x60,
96
};
86
97
87
MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
98
/* NVRAM bit masks */
88
MODULE_DESCRIPTION(IBM_DESC);
99
enum {
89
MODULE_VERSION(IBM_VERSION);
100
	TP_NVRAM_MASK_HKT_THINKPAD	= 0x08,
90
MODULE_LICENSE("GPL");
101
	TP_NVRAM_MASK_HKT_ZOOM		= 0x20,
102
	TP_NVRAM_MASK_HKT_DISPLAY	= 0x40,
103
	TP_NVRAM_MASK_HKT_HIBERNATE	= 0x80,
104
	TP_NVRAM_MASK_THINKLIGHT	= 0x10,
105
	TP_NVRAM_MASK_HKT_DISPEXPND	= 0x30,
106
	TP_NVRAM_MASK_HKT_BRIGHTNESS	= 0x20,
107
	TP_NVRAM_MASK_LEVEL_BRIGHTNESS	= 0x0f,
108
	TP_NVRAM_POS_LEVEL_BRIGHTNESS	= 0,
109
	TP_NVRAM_MASK_MUTE		= 0x40,
110
	TP_NVRAM_MASK_HKT_VOLUME	= 0x80,
111
	TP_NVRAM_MASK_LEVEL_VOLUME	= 0x0f,
112
	TP_NVRAM_POS_LEVEL_VOLUME	= 0,
113
};
91
114
92
/* Please remove this in year 2009 */
115
/* ACPI HIDs */
93
MODULE_ALIAS("ibm_acpi");
116
#define TPACPI_ACPI_HKEY_HID		"IBM0068"
94
117
95
/*
118
/* Input IDs */
96
 * DMI matching for module autoloading
119
#define TPACPI_HKEY_INPUT_PRODUCT	0x5054 /* "TP" */
97
 *
120
#define TPACPI_HKEY_INPUT_VERSION	0x4101
98
 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
121
99
 * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads
122
100
 *
123
/****************************************************************************
101
 * Only models listed in thinkwiki will be supported, so add yours
124
 * Main driver
102
 * if it is not there yet.
103
 */
125
 */
104
#define IBM_BIOS_MODULE_ALIAS(__type) \
105
	MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW")
106
126
107
/* Non-ancient thinkpads */
127
#define TPACPI_NAME "thinkpad"
108
MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
128
#define TPACPI_DESC "ThinkPad ACPI Extras"
109
MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
129
#define TPACPI_FILE TPACPI_NAME "_acpi"
130
#define TPACPI_URL "http://ibm-acpi.sf.net/"
131
#define TPACPI_MAIL "ibm-acpi-devel@lists.sourceforge.net"
132
133
#define TPACPI_PROC_DIR "ibm"
134
#define TPACPI_ACPI_EVENT_PREFIX "ibm"
135
#define TPACPI_DRVR_NAME TPACPI_FILE
136
#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon"
137
138
#define TPACPI_MAX_ACPI_ARGS 3
139
140
/* Debugging */
141
#define TPACPI_LOG TPACPI_FILE ": "
142
#define TPACPI_ERR	   KERN_ERR    TPACPI_LOG
143
#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
144
#define TPACPI_INFO   KERN_INFO   TPACPI_LOG
145
#define TPACPI_DEBUG  KERN_DEBUG  TPACPI_LOG
146
147
#define TPACPI_DBG_ALL		0xffff
148
#define TPACPI_DBG_ALL		0xffff
149
#define TPACPI_DBG_INIT		0x0001
150
#define TPACPI_DBG_EXIT		0x0002
151
#define dbg_printk(a_dbg_level, format, arg...) \
152
	do { if (dbg_level & a_dbg_level) \
153
		printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
154
	} while (0)
155
#ifdef CONFIG_THINKPAD_ACPI_DEBUG
156
#define vdbg_printk(a_dbg_level, format, arg...) \
157
	dbg_printk(a_dbg_level, format, ## arg)
158
static const char *str_supported(int is_supported);
159
#else
160
#define vdbg_printk(a_dbg_level, format, arg...)
161
#endif
110
162
111
/* Ancient thinkpad BIOSes have to be identified by
163
#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
112
 * BIOS type or model number, and there are far less
164
#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
113
 * BIOS types than model numbers... */
165
#define strlencmp(a, b) (strncmp((a), (b), strlen(b)))
114
IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]");
115
IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]");
116
IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
117
166
118
#define __unused __attribute__ ((unused))
167
168
/****************************************************************************
169
 * Driver-wide structs and misc. variables
170
 */
171
172
struct ibm_struct;
173
174
struct tp_acpi_drv_struct {
175
	char *hid;
176
	struct acpi_driver *driver;
177
178
	void (*notify) (struct ibm_struct *, u32);
179
	acpi_handle *handle;
180
	u32 type;
181
	struct acpi_device *device;
182
};
183
184
struct ibm_struct {
185
	char *name;
186
187
	int (*read) (char *);
188
	int (*write) (char *);
189
	void (*exit) (void);
190
	void (*resume) (void);
191
	void (*suspend) (pm_message_t state);
192
193
	struct list_head all_drivers;
194
195
	struct tp_acpi_drv_struct *acpi;
196
197
	struct {
198
		u8 acpi_driver_registered:1;
199
		u8 acpi_notify_installed:1;
200
		u8 proc_created:1;
201
		u8 init_called:1;
202
		u8 experimental:1;
203
	} flags;
204
};
205
206
struct ibm_init_struct {
207
	char param[32];
208
209
	int (*init) (struct ibm_init_struct *);
210
	struct ibm_struct *data;
211
};
212
213
static struct {
214
#ifdef CONFIG_THINKPAD_ACPI_BAY
215
	u32 bay_status:1;
216
	u32 bay_eject:1;
217
	u32 bay_status2:1;
218
	u32 bay_eject2:1;
219
#endif
220
	u32 bluetooth:1;
221
	u32 hotkey:1;
222
	u32 hotkey_mask:1;
223
	u32 hotkey_wlsw:1;
224
	u32 light:1;
225
	u32 light_status:1;
226
	u32 bright_16levels:1;
227
	u32 wan:1;
228
	u32 fan_ctrl_status_undef:1;
229
	u32 input_device_registered:1;
230
	u32 hotkey_report_mode_locked:1;
231
	u32 platform_drv_registered:1;
232
	u32 platform_drv_attrs_registered:1;
233
	u32 sensors_pdrv_registered:1;
234
	u32 sensors_pdrv_attrs_registered:1;
235
	u32 sensors_pdev_attrs_registered:1;
236
	u32 hotkey_poll_active:1;
237
} tp_features;
238
239
struct thinkpad_id_data {
240
	unsigned int vendor;	/* ThinkPad vendor:
241
				 * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
242
243
	char *bios_version_str;	/* Something like 1ZET51WW (1.03z) */
244
	char *ec_version_str;	/* Something like 1ZHT51WW-1.04a */
245
246
	u16 bios_model;		/* Big Endian, TP-1Y = 0x5931, 0 = unknown */
247
	u16 ec_model;
248
249
	char *model_str;
250
};
251
static struct thinkpad_id_data thinkpad_id;
252
253
static enum {
254
	TPACPI_LIFE_INIT = 0,
255
	TPACPI_LIFE_RUNNING,
256
	TPACPI_LIFE_EXITING,
257
} tpacpi_lifecycle;
258
259
static int experimental;
260
static u32 dbg_level;
119
261
120
/****************************************************************************
262
/****************************************************************************
121
 ****************************************************************************
263
 ****************************************************************************
Lines 129-143 IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); Link Here
129
 * ACPI basic handles
271
 * ACPI basic handles
130
 */
272
 */
131
273
132
static acpi_handle root_handle = NULL;
274
static acpi_handle root_handle;
133
275
134
#define IBM_HANDLE(object, parent, paths...)			\
276
#define TPACPI_HANDLE(object, parent, paths...)			\
135
	static acpi_handle  object##_handle;			\
277
	static acpi_handle  object##_handle;			\
136
	static acpi_handle *object##_parent = &parent##_handle;	\
278
	static acpi_handle *object##_parent = &parent##_handle;	\
137
	static char        *object##_path;			\
279
	static char        *object##_path;			\
138
	static char        *object##_paths[] = { paths }
280
	static char        *object##_paths[] = { paths }
139
281
140
IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0",	/* 240, 240x */
282
TPACPI_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0",	/* 240, 240x */
141
	   "\\_SB.PCI.ISA.EC",	/* 570 */
283
	   "\\_SB.PCI.ISA.EC",	/* 570 */
142
	   "\\_SB.PCI0.ISA0.EC0",	/* 600e/x, 770e, 770x */
284
	   "\\_SB.PCI0.ISA0.EC0",	/* 600e/x, 770e, 770x */
143
	   "\\_SB.PCI0.ISA.EC",	/* A21e, A2xm/p, T20-22, X20-21 */
285
	   "\\_SB.PCI0.ISA.EC",	/* A21e, A2xm/p, T20-22, X20-21 */
Lines 146-165 IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0 Link Here
146
	   "\\_SB.PCI0.LPC.EC",	/* all others */
288
	   "\\_SB.PCI0.LPC.EC",	/* all others */
147
	   );
289
	   );
148
290
149
IBM_HANDLE(ecrd, ec, "ECRD");	/* 570 */
291
TPACPI_HANDLE(ecrd, ec, "ECRD");	/* 570 */
150
IBM_HANDLE(ecwr, ec, "ECWR");	/* 570 */
292
TPACPI_HANDLE(ecwr, ec, "ECWR");	/* 570 */
151
152
293
153
/*************************************************************************
294
TPACPI_HANDLE(cmos, root, "\\UCMS",	/* R50, R50e, R50p, R51, */
154
 * Misc ACPI handles
295
					/* T4x, X31, X40 */
155
 */
156
157
IBM_HANDLE(cmos, root, "\\UCMS",	/* R50, R50e, R50p, R51, T4x, X31, X40 */
158
	   "\\CMOS",		/* A3x, G4x, R32, T23, T30, X22-24, X30 */
296
	   "\\CMOS",		/* A3x, G4x, R32, T23, T30, X22-24, X30 */
159
	   "\\CMS",		/* R40, R40e */
297
	   "\\CMS",		/* R40, R40e */
160
	   );			/* all others */
298
	   );			/* all others */
161
299
162
IBM_HANDLE(hkey, ec, "\\_SB.HKEY",	/* 600e/x, 770e, 770x */
300
TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY",	/* 600e/x, 770e, 770x */
163
	   "^HKEY",		/* R30, R31 */
301
	   "^HKEY",		/* R30, R31 */
164
	   "HKEY",		/* all others */
302
	   "HKEY",		/* all others */
165
	   );			/* 570 */
303
	   );			/* 570 */
Lines 174-180 static int acpi_evalf(acpi_handle handle Link Here
174
{
312
{
175
	char *fmt0 = fmt;
313
	char *fmt0 = fmt;
176
	struct acpi_object_list params;
314
	struct acpi_object_list params;
177
	union acpi_object in_objs[IBM_MAX_ACPI_ARGS];
315
	union acpi_object in_objs[TPACPI_MAX_ACPI_ARGS];
178
	struct acpi_buffer result, *resultp;
316
	struct acpi_buffer result, *resultp;
179
	union acpi_object out_obj;
317
	union acpi_object out_obj;
180
	acpi_status status;
318
	acpi_status status;
Lines 184-190 static int acpi_evalf(acpi_handle handle Link Here
184
	int quiet;
322
	int quiet;
185
323
186
	if (!*fmt) {
324
	if (!*fmt) {
187
		printk(IBM_ERR "acpi_evalf() called with empty format\n");
325
		printk(TPACPI_ERR "acpi_evalf() called with empty format\n");
188
		return 0;
326
		return 0;
189
	}
327
	}
190
328
Lines 209-215 static int acpi_evalf(acpi_handle handle Link Here
209
			break;
347
			break;
210
			/* add more types as needed */
348
			/* add more types as needed */
211
		default:
349
		default:
212
			printk(IBM_ERR "acpi_evalf() called "
350
			printk(TPACPI_ERR "acpi_evalf() called "
213
			       "with invalid format character '%c'\n", c);
351
			       "with invalid format character '%c'\n", c);
214
			return 0;
352
			return 0;
215
		}
353
		}
Lines 236-264 static int acpi_evalf(acpi_handle handle Link Here
236
		break;
374
		break;
237
		/* add more types as needed */
375
		/* add more types as needed */
238
	default:
376
	default:
239
		printk(IBM_ERR "acpi_evalf() called "
377
		printk(TPACPI_ERR "acpi_evalf() called "
240
		       "with invalid format character '%c'\n", res_type);
378
		       "with invalid format character '%c'\n", res_type);
241
		return 0;
379
		return 0;
242
	}
380
	}
243
381
244
	if (!success && !quiet)
382
	if (!success && !quiet)
245
		printk(IBM_ERR "acpi_evalf(%s, %s, ...) failed: %d\n",
383
		printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %d\n",
246
		       method, fmt0, status);
384
		       method, fmt0, status);
247
385
248
	return success;
386
	return success;
249
}
387
}
250
388
251
static void __unused acpi_print_int(acpi_handle handle, char *method)
389
static int acpi_ec_read(int i, u8 *p)
252
{
253
	int i;
254
255
	if (acpi_evalf(handle, &i, method, "d"))
256
		printk(IBM_INFO "%s = 0x%x\n", method, i);
257
	else
258
		printk(IBM_ERR "error calling %s\n", method);
259
}
260
261
static int acpi_ec_read(int i, u8 * p)
262
{
390
{
263
	int v;
391
	int v;
264
392
Lines 287-292 static int acpi_ec_write(int i, u8 v) Link Here
287
	return 1;
415
	return 1;
288
}
416
}
289
417
418
#if defined(CONFIG_THINKPAD_ACPI_DOCK) || defined(CONFIG_THINKPAD_ACPI_BAY)
290
static int _sta(acpi_handle handle)
419
static int _sta(acpi_handle handle)
291
{
420
{
292
	int status;
421
	int status;
Lines 296-301 static int _sta(acpi_handle handle) Link Here
296
425
297
	return status;
426
	return status;
298
}
427
}
428
#endif
299
429
300
static int issue_thinkpad_cmos_command(int cmos_cmd)
430
static int issue_thinkpad_cmos_command(int cmos_cmd)
301
{
431
{
Lines 312-317 static int issue_thinkpad_cmos_command(i Link Here
312
 * ACPI device model
442
 * ACPI device model
313
 */
443
 */
314
444
445
#define TPACPI_ACPIHANDLE_INIT(object) \
446
	drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \
447
		object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
448
315
static void drv_acpi_handle_init(char *name,
449
static void drv_acpi_handle_init(char *name,
316
			   acpi_handle *handle, acpi_handle parent,
450
			   acpi_handle *handle, acpi_handle parent,
317
			   char **paths, int num_paths, char **path)
451
			   char **paths, int num_paths, char **path)
Lines 342-347 static void dispatch_acpi_notify(acpi_ha Link Here
342
{
476
{
343
	struct ibm_struct *ibm = data;
477
	struct ibm_struct *ibm = data;
344
478
479
	if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
480
		return;
481
345
	if (!ibm || !ibm->acpi || !ibm->acpi->notify)
482
	if (!ibm || !ibm->acpi || !ibm->acpi->notify)
346
		return;
483
		return;
347
484
Lines 363-387 static int __init setup_acpi_notify(stru Link Here
363
500
364
	rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device);
501
	rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device);
365
	if (rc < 0) {
502
	if (rc < 0) {
366
		printk(IBM_ERR "acpi_bus_get_device(%s) failed: %d\n",
503
		printk(TPACPI_ERR "acpi_bus_get_device(%s) failed: %d\n",
367
			ibm->name, rc);
504
			ibm->name, rc);
368
		return -ENODEV;
505
		return -ENODEV;
369
	}
506
	}
370
507
371
	acpi_driver_data(ibm->acpi->device) = ibm;
508
	acpi_driver_data(ibm->acpi->device) = ibm;
372
	sprintf(acpi_device_class(ibm->acpi->device), "%s/%s",
509
	sprintf(acpi_device_class(ibm->acpi->device), "%s/%s",
373
		IBM_ACPI_EVENT_PREFIX,
510
		TPACPI_ACPI_EVENT_PREFIX,
374
		ibm->name);
511
		ibm->name);
375
512
376
	status = acpi_install_notify_handler(*ibm->acpi->handle,
513
	status = acpi_install_notify_handler(*ibm->acpi->handle,
377
			ibm->acpi->type, dispatch_acpi_notify, ibm);
514
			ibm->acpi->type, dispatch_acpi_notify, ibm);
378
	if (ACPI_FAILURE(status)) {
515
	if (ACPI_FAILURE(status)) {
379
		if (status == AE_ALREADY_EXISTS) {
516
		if (status == AE_ALREADY_EXISTS) {
380
			printk(IBM_NOTICE "another device driver is already handling %s events\n",
517
			printk(TPACPI_NOTICE
381
				ibm->name);
518
			       "another device driver is already "
519
			       "handling %s events\n", ibm->name);
382
		} else {
520
		} else {
383
			printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n",
521
			printk(TPACPI_ERR
384
				ibm->name, status);
522
			       "acpi_install_notify_handler(%s) failed: %d\n",
523
			       ibm->name, status);
385
		}
524
		}
386
		return -ENODEV;
525
		return -ENODEV;
387
	}
526
	}
Lines 405-423 static int __init register_tpacpi_subdri Link Here
405
544
406
	ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
545
	ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
407
	if (!ibm->acpi->driver) {
546
	if (!ibm->acpi->driver) {
408
		printk(IBM_ERR "kzalloc(ibm->driver) failed\n");
547
		printk(TPACPI_ERR "kzalloc(ibm->driver) failed\n");
409
		return -ENOMEM;
548
		return -ENOMEM;
410
	}
549
	}
411
550
412
	sprintf(ibm->acpi->driver->name, "%s_%s", IBM_NAME, ibm->name);
551
	sprintf(ibm->acpi->driver->name, "%s_%s", TPACPI_NAME, ibm->name);
413
	ibm->acpi->driver->ids = ibm->acpi->hid;
552
	ibm->acpi->driver->ids = ibm->acpi->hid;
414
415
	ibm->acpi->driver->ops.add = &tpacpi_device_add;
553
	ibm->acpi->driver->ops.add = &tpacpi_device_add;
416
554
417
	rc = acpi_bus_register_driver(ibm->acpi->driver);
555
	rc = acpi_bus_register_driver(ibm->acpi->driver);
418
	if (rc < 0) {
556
	if (rc < 0) {
419
		printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n",
557
		printk(TPACPI_ERR "acpi_bus_register_driver(%s) failed: %d\n",
420
		       ibm->name, rc);
558
		       ibm->acpi->hid, rc);
421
		kfree(ibm->acpi->driver);
559
		kfree(ibm->acpi->driver);
422
		ibm->acpi->driver = NULL;
560
		ibm->acpi->driver = NULL;
423
	} else if (!rc)
561
	} else if (!rc)
Lines 461-467 static int dispatch_procfs_read(char *pa Link Here
461
}
599
}
462
600
463
static int dispatch_procfs_write(struct file *file,
601
static int dispatch_procfs_write(struct file *file,
464
			const char __user * userbuf,
602
			const char __user *userbuf,
465
			unsigned long count, void *data)
603
			unsigned long count, void *data)
466
{
604
{
467
	struct ibm_struct *ibm = data;
605
	struct ibm_struct *ibm = data;
Lines 511-620 static char *next_cmd(char **cmds) Link Here
511
/****************************************************************************
649
/****************************************************************************
512
 ****************************************************************************
650
 ****************************************************************************
513
 *
651
 *
514
 * Device model: hwmon and platform
652
 * Device model: input, hwmon and platform
515
 *
653
 *
516
 ****************************************************************************
654
 ****************************************************************************
517
 ****************************************************************************/
655
 ****************************************************************************/
518
656
519
static struct platform_device *tpacpi_pdev = NULL;
657
static struct platform_device *tpacpi_pdev;
520
static struct class_device *tpacpi_hwmon = NULL;
658
static struct platform_device *tpacpi_sensors_pdev;
521
659
static struct class_device *tpacpi_hwmon;
522
static struct platform_driver tpacpi_pdriver = {
660
static struct input_dev *tpacpi_inputdev;
523
	.driver = {
661
static struct mutex tpacpi_inputdev_send_mutex;
524
		.name = IBM_DRVR_NAME,
662
static LIST_HEAD(tpacpi_all_drivers);
525
		.owner = THIS_MODULE,
526
	},
527
};
528
529
530
/*************************************************************************
531
 * thinkpad-acpi driver attributes
532
 */
533
534
/* interface_version --------------------------------------------------- */
535
static ssize_t tpacpi_driver_interface_version_show(
536
				struct device_driver *drv,
537
				char *buf)
538
{
539
	return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION);
540
}
541
542
static DRIVER_ATTR(interface_version, S_IRUGO,
543
		tpacpi_driver_interface_version_show, NULL);
544
545
/* debug_level --------------------------------------------------------- */
546
static ssize_t tpacpi_driver_debug_show(struct device_driver *drv,
547
						char *buf)
548
{
549
	return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level);
550
}
551
663
552
static ssize_t tpacpi_driver_debug_store(struct device_driver *drv,
664
static int tpacpi_suspend_handler(struct platform_device *pdev,
553
						const char *buf, size_t count)
665
				  pm_message_t state)
554
{
666
{
555
	unsigned long t;
667
	struct ibm_struct *ibm, *itmp;
556
557
	if (parse_strtoul(buf, 0xffff, &t))
558
		return -EINVAL;
559
560
	dbg_level = t;
561
562
	return count;
563
}
564
668
565
static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
669
	list_for_each_entry_safe(ibm, itmp,
566
		tpacpi_driver_debug_show, tpacpi_driver_debug_store);
670
				 &tpacpi_all_drivers,
671
				 all_drivers) {
672
		if (ibm->suspend)
673
			(ibm->suspend)(state);
674
	}
567
675
568
/* version ------------------------------------------------------------- */
676
	return 0;
569
static ssize_t tpacpi_driver_version_show(struct device_driver *drv,
570
						char *buf)
571
{
572
	return snprintf(buf, PAGE_SIZE, "%s v%s\n", IBM_DESC, IBM_VERSION);
573
}
677
}
574
678
575
static DRIVER_ATTR(version, S_IRUGO,
679
static int tpacpi_resume_handler(struct platform_device *pdev)
576
		tpacpi_driver_version_show, NULL);
577
578
/* --------------------------------------------------------------------- */
579
580
static struct driver_attribute* tpacpi_driver_attributes[] = {
581
	&driver_attr_debug_level, &driver_attr_version,
582
	&driver_attr_interface_version,
583
};
584
585
static int __init tpacpi_create_driver_attributes(struct device_driver *drv)
586
{
680
{
587
	int i, res;
681
	struct ibm_struct *ibm, *itmp;
588
682
589
	i = 0;
683
	list_for_each_entry_safe(ibm, itmp,
590
	res = 0;
684
				 &tpacpi_all_drivers,
591
	while (!res && i < ARRAY_SIZE(tpacpi_driver_attributes)) {
685
				 all_drivers) {
592
		res = driver_create_file(drv, tpacpi_driver_attributes[i]);
686
		if (ibm->resume)
593
		i++;
687
			(ibm->resume)();
594
	}
688
	}
595
689
596
	return res;
690
	return 0;
597
}
691
}
598
692
599
static void tpacpi_remove_driver_attributes(struct device_driver *drv)
693
static struct platform_driver tpacpi_pdriver = {
600
{
694
	.driver = {
601
	int i;
695
		.name = TPACPI_DRVR_NAME,
696
		.owner = THIS_MODULE,
697
	},
698
	.suspend = tpacpi_suspend_handler,
699
	.resume = tpacpi_resume_handler,
700
};
602
701
603
	for(i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++)
702
static struct platform_driver tpacpi_hwmon_pdriver = {
604
		driver_remove_file(drv, tpacpi_driver_attributes[i]);
703
	.driver = {
605
}
704
		.name = TPACPI_HWMON_DRVR_NAME,
705
		.owner = THIS_MODULE,
706
	},
707
};
606
708
607
/*************************************************************************
709
/*************************************************************************
608
 * sysfs support helpers
710
 * sysfs support helpers
609
 */
711
 */
610
712
713
struct attribute_set {
714
	unsigned int members, max_members;
715
	struct attribute_group group;
716
};
717
611
struct attribute_set_obj {
718
struct attribute_set_obj {
612
	struct attribute_set s;
719
	struct attribute_set s;
613
	struct attribute *a;
720
	struct attribute *a;
614
} __attribute__((packed));
721
} __attribute__((packed));
615
722
616
static struct attribute_set *create_attr_set(unsigned int max_members,
723
static struct attribute_set *create_attr_set(unsigned int max_members,
617
						const char* name)
724
						const char *name)
618
{
725
{
619
	struct attribute_set_obj *sobj;
726
	struct attribute_set_obj *sobj;
620
727
Lines 634-641 static struct attribute_set *create_attr Link Here
634
	return &sobj->s;
741
	return &sobj->s;
635
}
742
}
636
743
744
#define destroy_attr_set(_set) \
745
	kfree(_set);
746
637
/* not multi-threaded safe, use it in a single thread per set */
747
/* not multi-threaded safe, use it in a single thread per set */
638
static int add_to_attr_set(struct attribute_set* s, struct attribute *attr)
748
static int add_to_attr_set(struct attribute_set *s, struct attribute *attr)
639
{
749
{
640
	if (!s || !attr)
750
	if (!s || !attr)
641
		return -EINVAL;
751
		return -EINVAL;
Lines 649-655 static int add_to_attr_set(struct attrib Link Here
649
	return 0;
759
	return 0;
650
}
760
}
651
761
652
static int add_many_to_attr_set(struct attribute_set* s,
762
static int add_many_to_attr_set(struct attribute_set *s,
653
			struct attribute **attr,
763
			struct attribute **attr,
654
			unsigned int count)
764
			unsigned int count)
655
{
765
{
Lines 664-680 static int add_many_to_attr_set(struct a Link Here
664
	return 0;
774
	return 0;
665
}
775
}
666
776
667
static void delete_attr_set(struct attribute_set* s, struct kobject *kobj)
777
static void delete_attr_set(struct attribute_set *s, struct kobject *kobj)
668
{
778
{
669
	sysfs_remove_group(kobj, &s->group);
779
	sysfs_remove_group(kobj, &s->group);
670
	destroy_attr_set(s);
780
	destroy_attr_set(s);
671
}
781
}
672
782
783
#define register_attr_set_with_sysfs(_attr_set, _kobj) \
784
	sysfs_create_group(_kobj, &_attr_set->group)
785
673
static int parse_strtoul(const char *buf,
786
static int parse_strtoul(const char *buf,
674
		unsigned long max, unsigned long *value)
787
		unsigned long max, unsigned long *value)
675
{
788
{
676
	char *endp;
789
	char *endp;
677
790
791
	while (*buf && isspace(*buf))
792
		buf++;
678
	*value = simple_strtoul(buf, &endp, 0);
793
	*value = simple_strtoul(buf, &endp, 0);
679
	while (*endp && isspace(*endp))
794
	while (*endp && isspace(*endp))
680
		endp++;
795
		endp++;
Lines 684-689 static int parse_strtoul(const char *buf Link Here
684
	return 0;
799
	return 0;
685
}
800
}
686
801
802
/*************************************************************************
803
 * thinkpad-acpi driver attributes
804
 */
805
806
/* interface_version --------------------------------------------------- */
807
static ssize_t tpacpi_driver_interface_version_show(
808
				struct device_driver *drv,
809
				char *buf)
810
{
811
	return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION);
812
}
813
814
static DRIVER_ATTR(interface_version, S_IRUGO,
815
		tpacpi_driver_interface_version_show, NULL);
816
817
/* debug_level --------------------------------------------------------- */
818
static ssize_t tpacpi_driver_debug_show(struct device_driver *drv,
819
						char *buf)
820
{
821
	return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level);
822
}
823
824
static ssize_t tpacpi_driver_debug_store(struct device_driver *drv,
825
						const char *buf, size_t count)
826
{
827
	unsigned long t;
828
829
	if (parse_strtoul(buf, 0xffff, &t))
830
		return -EINVAL;
831
832
	dbg_level = t;
833
834
	return count;
835
}
836
837
static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
838
		tpacpi_driver_debug_show, tpacpi_driver_debug_store);
839
840
/* version ------------------------------------------------------------- */
841
static ssize_t tpacpi_driver_version_show(struct device_driver *drv,
842
						char *buf)
843
{
844
	return snprintf(buf, PAGE_SIZE, "%s v%s\n",
845
			TPACPI_DESC, TPACPI_VERSION);
846
}
847
848
static DRIVER_ATTR(version, S_IRUGO,
849
		tpacpi_driver_version_show, NULL);
850
851
/* --------------------------------------------------------------------- */
852
853
static struct driver_attribute *tpacpi_driver_attributes[] = {
854
	&driver_attr_debug_level, &driver_attr_version,
855
	&driver_attr_interface_version,
856
};
857
858
static int __init tpacpi_create_driver_attributes(struct device_driver *drv)
859
{
860
	int i, res;
861
862
	i = 0;
863
	res = 0;
864
	while (!res && i < ARRAY_SIZE(tpacpi_driver_attributes)) {
865
		res = driver_create_file(drv, tpacpi_driver_attributes[i]);
866
		i++;
867
	}
868
869
	return res;
870
}
871
872
static void tpacpi_remove_driver_attributes(struct device_driver *drv)
873
{
874
	int i;
875
876
	for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++)
877
		driver_remove_file(drv, tpacpi_driver_attributes[i]);
878
}
879
687
/****************************************************************************
880
/****************************************************************************
688
 ****************************************************************************
881
 ****************************************************************************
689
 *
882
 *
Lines 698-709 static int parse_strtoul(const char *buf Link Here
698
891
699
static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
892
static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
700
{
893
{
701
	printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
894
	printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION);
702
	printk(IBM_INFO "%s\n", IBM_URL);
895
	printk(TPACPI_INFO "%s\n", TPACPI_URL);
703
896
704
	if (ibm_thinkpad_ec_found)
897
	printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n",
705
		printk(IBM_INFO "ThinkPad EC firmware %s\n",
898
		(thinkpad_id.bios_version_str) ?
706
		       ibm_thinkpad_ec_found);
899
			thinkpad_id.bios_version_str : "unknown",
900
		(thinkpad_id.ec_version_str) ?
901
			thinkpad_id.ec_version_str : "unknown");
902
903
	if (thinkpad_id.vendor && thinkpad_id.model_str)
904
		printk(TPACPI_INFO "%s %s\n",
905
			(thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
906
				"IBM" : ((thinkpad_id.vendor ==
907
						PCI_VENDOR_ID_LENOVO) ?
908
					"Lenovo" : "Unknown vendor"),
909
			thinkpad_id.model_str);
707
910
708
	return 0;
911
	return 0;
709
}
912
}
Lines 712-719 static int thinkpad_acpi_driver_read(cha Link Here
712
{
915
{
713
	int len = 0;
916
	int len = 0;
714
917
715
	len += sprintf(p + len, "driver:\t\t%s\n", IBM_DESC);
918
	len += sprintf(p + len, "driver:\t\t%s\n", TPACPI_DESC);
716
	len += sprintf(p + len, "version:\t%s\n", IBM_VERSION);
919
	len += sprintf(p + len, "version:\t%s\n", TPACPI_VERSION);
717
920
718
	return len;
921
	return len;
719
}
922
}
Lines 727-1802 static struct ibm_struct thinkpad_acpi_d Link Here
727
 * Hotkey subdriver
930
 * Hotkey subdriver
728
 */
931
 */
729
932
730
static int hotkey_orig_status;
933
enum {	/* hot key scan codes (derived from ACPI DSDT) */
731
static int hotkey_orig_mask;
934
	TP_ACPI_HOTKEYSCAN_FNF1		= 0,
935
	TP_ACPI_HOTKEYSCAN_FNF2,
936
	TP_ACPI_HOTKEYSCAN_FNF3,
937
	TP_ACPI_HOTKEYSCAN_FNF4,
938
	TP_ACPI_HOTKEYSCAN_FNF5,
939
	TP_ACPI_HOTKEYSCAN_FNF6,
940
	TP_ACPI_HOTKEYSCAN_FNF7,
941
	TP_ACPI_HOTKEYSCAN_FNF8,
942
	TP_ACPI_HOTKEYSCAN_FNF9,
943
	TP_ACPI_HOTKEYSCAN_FNF10,
944
	TP_ACPI_HOTKEYSCAN_FNF11,
945
	TP_ACPI_HOTKEYSCAN_FNF12,
946
	TP_ACPI_HOTKEYSCAN_FNBACKSPACE,
947
	TP_ACPI_HOTKEYSCAN_FNINSERT,
948
	TP_ACPI_HOTKEYSCAN_FNDELETE,
949
	TP_ACPI_HOTKEYSCAN_FNHOME,
950
	TP_ACPI_HOTKEYSCAN_FNEND,
951
	TP_ACPI_HOTKEYSCAN_FNPAGEUP,
952
	TP_ACPI_HOTKEYSCAN_FNPAGEDOWN,
953
	TP_ACPI_HOTKEYSCAN_FNSPACE,
954
	TP_ACPI_HOTKEYSCAN_VOLUMEUP,
955
	TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,
956
	TP_ACPI_HOTKEYSCAN_MUTE,
957
	TP_ACPI_HOTKEYSCAN_THINKPAD,
958
};
732
959
733
static struct attribute_set *hotkey_dev_attributes = NULL;
960
enum {	/* Keys available through NVRAM polling */
961
	TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U,
962
	TPACPI_HKEY_NVRAM_GOOD_MASK  = 0x00fb8000U,
963
};
734
964
735
/* sysfs hotkey enable ------------------------------------------------- */
965
enum {	/* Positions of some of the keys in hotkey masks */
736
static ssize_t hotkey_enable_show(struct device *dev,
966
	TP_ACPI_HKEY_DISPSWTCH_MASK	= 1 << TP_ACPI_HOTKEYSCAN_FNF7,
737
			   struct device_attribute *attr,
967
	TP_ACPI_HKEY_DISPXPAND_MASK	= 1 << TP_ACPI_HOTKEYSCAN_FNF8,
738
			   char *buf)
968
	TP_ACPI_HKEY_HIBERNATE_MASK	= 1 << TP_ACPI_HOTKEYSCAN_FNF12,
739
{
969
	TP_ACPI_HKEY_BRGHTUP_MASK	= 1 << TP_ACPI_HOTKEYSCAN_FNHOME,
740
	int res, status, mask;
970
	TP_ACPI_HKEY_BRGHTDWN_MASK	= 1 << TP_ACPI_HOTKEYSCAN_FNEND,
971
	TP_ACPI_HKEY_THNKLGHT_MASK	= 1 << TP_ACPI_HOTKEYSCAN_FNPAGEUP,
972
	TP_ACPI_HKEY_ZOOM_MASK		= 1 << TP_ACPI_HOTKEYSCAN_FNSPACE,
973
	TP_ACPI_HKEY_VOLUP_MASK		= 1 << TP_ACPI_HOTKEYSCAN_VOLUMEUP,
974
	TP_ACPI_HKEY_VOLDWN_MASK	= 1 << TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,
975
	TP_ACPI_HKEY_MUTE_MASK		= 1 << TP_ACPI_HOTKEYSCAN_MUTE,
976
	TP_ACPI_HKEY_THINKPAD_MASK	= 1 << TP_ACPI_HOTKEYSCAN_THINKPAD,
977
};
741
978
742
	res = hotkey_get(&status, &mask);
979
enum {	/* NVRAM to ACPI HKEY group map */
743
	if (res)
980
	TP_NVRAM_HKEY_GROUP_HK2		= TP_ACPI_HKEY_THINKPAD_MASK |
744
		return res;
981
					  TP_ACPI_HKEY_ZOOM_MASK |
982
					  TP_ACPI_HKEY_DISPSWTCH_MASK |
983
					  TP_ACPI_HKEY_HIBERNATE_MASK,
984
	TP_NVRAM_HKEY_GROUP_BRIGHTNESS	= TP_ACPI_HKEY_BRGHTUP_MASK |
985
					  TP_ACPI_HKEY_BRGHTDWN_MASK,
986
	TP_NVRAM_HKEY_GROUP_VOLUME	= TP_ACPI_HKEY_VOLUP_MASK |
987
					  TP_ACPI_HKEY_VOLDWN_MASK |
988
					  TP_ACPI_HKEY_MUTE_MASK,
989
};
745
990
746
	return snprintf(buf, PAGE_SIZE, "%d\n", status);
991
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
747
}
992
struct tp_nvram_state {
993
       u16 thinkpad_toggle:1;
994
       u16 zoom_toggle:1;
995
       u16 display_toggle:1;
996
       u16 thinklight_toggle:1;
997
       u16 hibernate_toggle:1;
998
       u16 displayexp_toggle:1;
999
       u16 display_state:1;
1000
       u16 brightness_toggle:1;
1001
       u16 volume_toggle:1;
1002
       u16 mute:1;
748
1003
749
static ssize_t hotkey_enable_store(struct device *dev,
1004
       u8 brightness_level;
750
			    struct device_attribute *attr,
1005
       u8 volume_level;
751
			    const char *buf, size_t count)
1006
};
752
{
753
	unsigned long t;
754
	int res, status, mask;
755
1007
756
	if (parse_strtoul(buf, 1, &t))
1008
static struct task_struct *tpacpi_hotkey_task;
757
		return -EINVAL;
1009
static u32 hotkey_source_mask;		/* bit mask 0=ACPI,1=NVRAM */
1010
static int hotkey_poll_freq = 10;	/* Hz */
1011
static struct mutex hotkey_thread_mutex;
1012
static struct mutex hotkey_thread_data_mutex;
1013
static unsigned int hotkey_config_change;
758
1014
759
	res = hotkey_get(&status, &mask);
1015
#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
760
	if (!res)
761
		res = hotkey_set(t, mask);
762
1016
763
	return (res) ? res : count;
1017
#define hotkey_source_mask 0U
764
}
765
1018
766
static struct device_attribute dev_attr_hotkey_enable =
1019
#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
767
	__ATTR(hotkey_enable, S_IWUSR | S_IRUGO,
768
		hotkey_enable_show, hotkey_enable_store);
769
1020
770
/* sysfs hotkey mask --------------------------------------------------- */
1021
static struct mutex hotkey_mutex;
771
static ssize_t hotkey_mask_show(struct device *dev,
772
			   struct device_attribute *attr,
773
			   char *buf)
774
{
775
	int res, status, mask;
776
1022
777
	res = hotkey_get(&status, &mask);
1023
static enum {	/* Reasons for waking up */
778
	if (res)
1024
	TP_ACPI_WAKEUP_NONE = 0,	/* None or unknown */
779
		return res;
1025
	TP_ACPI_WAKEUP_BAYEJ,		/* Bay ejection request */
1026
	TP_ACPI_WAKEUP_UNDOCK,		/* Undock request */
1027
} hotkey_wakeup_reason;
780
1028
781
	return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask);
1029
static int hotkey_autosleep_ack;
782
}
783
1030
784
static ssize_t hotkey_mask_store(struct device *dev,
1031
static int hotkey_orig_status;
785
			    struct device_attribute *attr,
1032
static u32 hotkey_orig_mask;
786
			    const char *buf, size_t count)
1033
static u32 hotkey_all_mask;
1034
static u32 hotkey_reserved_mask;
1035
static u32 hotkey_mask;
1036
1037
static unsigned int hotkey_report_mode;
1038
1039
static u16 *hotkey_keycode_map;
1040
1041
static struct attribute_set *hotkey_dev_attributes;
1042
1043
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1044
#define HOTKEY_CONFIG_CRITICAL_START \
1045
	do { \
1046
		mutex_lock(&hotkey_thread_data_mutex); \
1047
		hotkey_config_change++; \
1048
	} while (0);
1049
#define HOTKEY_CONFIG_CRITICAL_END \
1050
	mutex_unlock(&hotkey_thread_data_mutex);
1051
#else
1052
#define HOTKEY_CONFIG_CRITICAL_START
1053
#define HOTKEY_CONFIG_CRITICAL_END
1054
#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1055
1056
static int hotkey_get_wlsw(int *status)
787
{
1057
{
788
	unsigned long t;
1058
	if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
789
	int res, status, mask;
1059
		return -EIO;
1060
	return 0;
1061
}
790
1062
791
	if (parse_strtoul(buf, 0xffff, &t))
1063
/*
792
		return -EINVAL;
1064
 * Call with hotkey_mutex held
1065
 */
1066
static int hotkey_mask_get(void)
1067
{
1068
	u32 m = 0;
793
1069
794
	res = hotkey_get(&status, &mask);
1070
	if (tp_features.hotkey_mask) {
795
	if (!res)
1071
		if (!acpi_evalf(hkey_handle, &m, "DHKN", "d"))
796
		hotkey_set(status, t);
1072
			return -EIO;
1073
	}
1074
	hotkey_mask = m | (hotkey_source_mask & hotkey_mask);
797
1075
798
	return (res) ? res : count;
1076
	return 0;
799
}
1077
}
800
1078
801
static struct device_attribute dev_attr_hotkey_mask =
1079
/*
802
	__ATTR(hotkey_mask, S_IWUSR | S_IRUGO,
1080
 * Call with hotkey_mutex held
803
		hotkey_mask_show, hotkey_mask_store);
1081
 */
804
1082
static int hotkey_mask_set(u32 mask)
805
/* sysfs hotkey bios_enabled ------------------------------------------- */
806
static ssize_t hotkey_bios_enabled_show(struct device *dev,
807
			   struct device_attribute *attr,
808
			   char *buf)
809
{
1083
{
810
	return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
1084
	int i;
811
}
1085
	int rc = 0;
812
1086
813
static struct device_attribute dev_attr_hotkey_bios_enabled =
1087
	if (tp_features.hotkey_mask) {
814
	__ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
1088
		HOTKEY_CONFIG_CRITICAL_START
1089
		for (i = 0; i < 32; i++) {
1090
			u32 m = 1 << i;
1091
			/* enable in firmware mask only keys not in NVRAM
1092
			 * mode, but enable the key in the cached hotkey_mask
1093
			 * regardless of mode, or the key will end up
1094
			 * disabled by hotkey_mask_get() */
1095
			if (!acpi_evalf(hkey_handle,
1096
					NULL, "MHKM", "vdd", i + 1,
1097
					!!((mask & ~hotkey_source_mask) & m))) {
1098
				rc = -EIO;
1099
				break;
1100
			} else {
1101
				hotkey_mask = (hotkey_mask & ~m) | (mask & m);
1102
			}
1103
		}
1104
		HOTKEY_CONFIG_CRITICAL_END
815
1105
816
/* sysfs hotkey bios_mask ---------------------------------------------- */
1106
		/* hotkey_mask_get must be called unconditionally below */
817
static ssize_t hotkey_bios_mask_show(struct device *dev,
1107
		if (!hotkey_mask_get() && !rc &&
818
			   struct device_attribute *attr,
1108
		    (hotkey_mask & ~hotkey_source_mask) !=
819
			   char *buf)
1109
		     (mask & ~hotkey_source_mask)) {
820
{
1110
			printk(TPACPI_NOTICE
821
	return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask);
1111
			       "requested hot key mask 0x%08x, but "
1112
			       "firmware forced it to 0x%08x\n",
1113
			       mask, hotkey_mask);
1114
		}
1115
	} else {
1116
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1117
		HOTKEY_CONFIG_CRITICAL_START
1118
		hotkey_mask = mask & hotkey_source_mask;
1119
		HOTKEY_CONFIG_CRITICAL_END
1120
		hotkey_mask_get();
1121
		if (hotkey_mask != mask) {
1122
			printk(TPACPI_NOTICE
1123
			       "requested hot key mask 0x%08x, "
1124
			       "forced to 0x%08x (NVRAM poll mask is "
1125
			       "0x%08x): no firmware mask support\n",
1126
			       mask, hotkey_mask, hotkey_source_mask);
1127
		}
1128
#else
1129
		hotkey_mask_get();
1130
		rc = -ENXIO;
1131
#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1132
	}
1133
1134
	return rc;
822
}
1135
}
823
1136
824
static struct device_attribute dev_attr_hotkey_bios_mask =
1137
static int hotkey_status_get(int *status)
825
	__ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
1138
{
1139
	if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
1140
		return -EIO;
826
1141
827
/* --------------------------------------------------------------------- */
1142
	return 0;
1143
}
828
1144
829
static struct attribute *hotkey_mask_attributes[] = {
1145
static int hotkey_status_set(int status)
830
	&dev_attr_hotkey_mask.attr,
1146
{
831
	&dev_attr_hotkey_bios_enabled.attr,
1147
	if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
832
	&dev_attr_hotkey_bios_mask.attr,
1148
		return -EIO;
833
};
834
1149
835
static int __init hotkey_init(struct ibm_init_struct *iibm)
1150
	return 0;
1151
}
1152
1153
static void tpacpi_input_send_radiosw(void)
836
{
1154
{
837
	int res;
1155
	int wlsw;
838
1156
839
	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
1157
	mutex_lock(&tpacpi_inputdev_send_mutex);
840
1158
841
	IBM_ACPIHANDLE_INIT(hkey);
1159
	if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
842
	mutex_init(&hotkey_mutex);
1160
		input_report_switch(tpacpi_inputdev,
1161
				    SW_RADIO, !!wlsw);
1162
		input_sync(tpacpi_inputdev);
1163
	}
843
1164
844
	/* hotkey not supported on 570 */
1165
	mutex_unlock(&tpacpi_inputdev_send_mutex);
845
	tp_features.hotkey = hkey_handle != NULL;
1166
}
846
1167
847
	vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
1168
static void tpacpi_input_send_key(unsigned int scancode)
848
		str_supported(tp_features.hotkey));
1169
{
1170
	unsigned int keycode;
849
1171
850
	if (tp_features.hotkey) {
1172
	keycode = hotkey_keycode_map[scancode];
851
		hotkey_dev_attributes = create_attr_set(4, NULL);
852
		if (!hotkey_dev_attributes)
853
			return -ENOMEM;
854
		res = add_to_attr_set(hotkey_dev_attributes,
855
				&dev_attr_hotkey_enable.attr);
856
		if (res)
857
			return res;
858
1173
859
		/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
1174
	if (keycode != KEY_RESERVED) {
860
		   A30, R30, R31, T20-22, X20-21, X22-24 */
1175
		mutex_lock(&tpacpi_inputdev_send_mutex);
861
		tp_features.hotkey_mask =
862
			acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
863
1176
864
		vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
1177
		input_report_key(tpacpi_inputdev, keycode, 1);
865
			str_supported(tp_features.hotkey_mask));
1178
		if (keycode == KEY_UNKNOWN)
1179
			input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
1180
				    scancode);
1181
		input_sync(tpacpi_inputdev);
866
1182
867
		res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
1183
		input_report_key(tpacpi_inputdev, keycode, 0);
868
		if (!res && tp_features.hotkey_mask) {
1184
		if (keycode == KEY_UNKNOWN)
869
			res = add_many_to_attr_set(hotkey_dev_attributes,
1185
			input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
870
				hotkey_mask_attributes,
1186
				    scancode);
871
				ARRAY_SIZE(hotkey_mask_attributes));
1187
		input_sync(tpacpi_inputdev);
872
		}
873
		if (!res)
874
			res = register_attr_set_with_sysfs(
875
					hotkey_dev_attributes,
876
					&tpacpi_pdev->dev.kobj);
877
1188
878
		if (res)
1189
		mutex_unlock(&tpacpi_inputdev_send_mutex);
879
			return res;
880
	}
1190
	}
881
882
	return (tp_features.hotkey)? 0 : 1;
883
}
1191
}
884
1192
885
static void hotkey_exit(void)
1193
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
886
{
1194
static struct tp_acpi_drv_struct ibm_hotkey_acpidriver;
887
	int res;
888
889
	if (tp_features.hotkey) {
890
		dbg_printk(TPACPI_DBG_EXIT, "restoring original hotkey mask\n");
891
		res = hotkey_set(hotkey_orig_status, hotkey_orig_mask);
892
		if (res)
893
			printk(IBM_ERR "failed to restore hotkey to BIOS defaults\n");
894
	}
895
1195
896
	if (hotkey_dev_attributes) {
1196
static void tpacpi_hotkey_send_key(unsigned int scancode)
897
		delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
1197
{
898
		hotkey_dev_attributes = NULL;
1198
	tpacpi_input_send_key(scancode);
1199
	if (hotkey_report_mode < 2) {
1200
		acpi_bus_generate_event(ibm_hotkey_acpidriver.device,
1201
					0x80, 0x1001 + scancode);
899
	}
1202
	}
900
}
1203
}
901
1204
902
static void hotkey_notify(struct ibm_struct *ibm, u32 event)
1205
static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m)
903
{
1206
{
904
	int hkey;
1207
	u8 d;
905
1208
906
	if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d"))
1209
	if (m & TP_NVRAM_HKEY_GROUP_HK2) {
907
		acpi_bus_generate_event(ibm->acpi->device, event, hkey);
1210
		d = nvram_read_byte(TP_NVRAM_ADDR_HK2);
908
	else {
1211
		n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD);
909
		printk(IBM_ERR "unknown hotkey event %d\n", event);
1212
		n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM);
910
		acpi_bus_generate_event(ibm->acpi->device, event, 0);
1213
		n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY);
1214
		n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE);
1215
	}
1216
	if (m & TP_ACPI_HKEY_THNKLGHT_MASK) {
1217
		d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT);
1218
		n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT);
1219
	}
1220
	if (m & TP_ACPI_HKEY_DISPXPAND_MASK) {
1221
		d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO);
1222
		n->displayexp_toggle =
1223
				!!(d & TP_NVRAM_MASK_HKT_DISPEXPND);
1224
	}
1225
	if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) {
1226
		d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
1227
		n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
1228
				>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
1229
		n->brightness_toggle =
1230
				!!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS);
1231
	}
1232
	if (m & TP_NVRAM_HKEY_GROUP_VOLUME) {
1233
		d = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
1234
		n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME)
1235
				>> TP_NVRAM_POS_LEVEL_VOLUME;
1236
		n->mute = !!(d & TP_NVRAM_MASK_MUTE);
1237
		n->volume_toggle = !!(d & TP_NVRAM_MASK_HKT_VOLUME);
911
	}
1238
	}
912
}
1239
}
913
1240
914
/*
1241
#define TPACPI_COMPARE_KEY(__scancode, __member) \
915
 * Call with hotkey_mutex held
1242
	do { \
916
 */
1243
		if ((mask & (1 << __scancode)) && \
917
static int hotkey_get(int *status, int *mask)
1244
		    oldn->__member != newn->__member) \
1245
		tpacpi_hotkey_send_key(__scancode); \
1246
	} while (0)
1247
1248
#define TPACPI_MAY_SEND_KEY(__scancode) \
1249
	do { if (mask & (1 << __scancode)) \
1250
		tpacpi_hotkey_send_key(__scancode); } while (0)
1251
1252
static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
1253
					   struct tp_nvram_state *newn,
1254
					   u32 mask)
918
{
1255
{
919
	if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
1256
	TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);
920
		return -EIO;
1257
	TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle);
1258
	TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle);
1259
	TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF12, hibernate_toggle);
921
1260
922
	if (tp_features.hotkey_mask)
1261
	TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNPAGEUP, thinklight_toggle);
923
		if (!acpi_evalf(hkey_handle, mask, "DHKN", "d"))
924
			return -EIO;
925
1262
926
	return 0;
1263
	TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF8, displayexp_toggle);
1264
1265
	/* handle volume */
1266
	if (oldn->volume_toggle != newn->volume_toggle) {
1267
		if (oldn->mute != newn->mute) {
1268
			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE);
1269
		}
1270
		if (oldn->volume_level > newn->volume_level) {
1271
			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
1272
		} else if (oldn->volume_level < newn->volume_level) {
1273
			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
1274
		} else if (oldn->mute == newn->mute) {
1275
			/* repeated key presses that didn't change state */
1276
			if (newn->mute) {
1277
				TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE);
1278
			} else if (newn->volume_level != 0) {
1279
				TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
1280
			} else {
1281
				TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
1282
			}
1283
		}
1284
	}
1285
1286
	/* handle brightness */
1287
	if (oldn->brightness_toggle != newn->brightness_toggle) {
1288
		if (oldn->brightness_level < newn->brightness_level) {
1289
			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
1290
		} else if (oldn->brightness_level > newn->brightness_level) {
1291
			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
1292
		} else {
1293
			/* repeated key presses that didn't change state */
1294
			if (newn->brightness_level != 0) {
1295
				TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
1296
			} else {
1297
				TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
1298
			}
1299
		}
1300
	}
927
}
1301
}
928
1302
929
/*
1303
#undef TPACPI_COMPARE_KEY
930
 * Call with hotkey_mutex held
1304
#undef TPACPI_MAY_SEND_KEY
931
 */
1305
932
static int hotkey_set(int status, int mask)
1306
static int hotkey_kthread(void *data)
933
{
1307
{
934
	int i;
1308
	struct tp_nvram_state s[2];
1309
	u32 mask;
1310
	unsigned int si, so;
1311
	unsigned long t;
1312
	unsigned int change_detector, must_reset;
935
1313
936
	if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
1314
	mutex_lock(&hotkey_thread_mutex);
937
		return -EIO;
938
1315
939
	if (tp_features.hotkey_mask)
1316
	if (tpacpi_lifecycle == TPACPI_LIFE_EXITING)
940
		for (i = 0; i < 32; i++) {
1317
		goto exit;
941
			int bit = ((1 << i) & mask) != 0;
1318
942
			if (!acpi_evalf(hkey_handle,
1319
	so = 0;
943
					NULL, "MHKM", "vdd", i + 1, bit))
1320
	si = 1;
944
				return -EIO;
1321
	t = 0;
1322
1323
	/* Initial state for compares */
1324
	mutex_lock(&hotkey_thread_data_mutex);
1325
	change_detector = hotkey_config_change;
1326
	mask = hotkey_source_mask & hotkey_mask;
1327
	mutex_unlock(&hotkey_thread_data_mutex);
1328
	hotkey_read_nvram(&s[so], mask);
1329
1330
	while (!kthread_should_stop() && hotkey_poll_freq) {
1331
		if (t == 0)
1332
			t = 1000/hotkey_poll_freq;
1333
		t = msleep_interruptible(t);
1334
		if (unlikely(kthread_should_stop()))
1335
			break;
1336
		must_reset = try_to_freeze();
1337
		if (t > 0 && !must_reset)
1338
			continue;
1339
1340
		mutex_lock(&hotkey_thread_data_mutex);
1341
		if (must_reset || hotkey_config_change != change_detector) {
1342
			/* forget old state on thaw or config change */
1343
			si = so;
1344
			t = 0;
1345
			change_detector = hotkey_config_change;
1346
		}
1347
		mask = hotkey_source_mask & hotkey_mask;
1348
		mutex_unlock(&hotkey_thread_data_mutex);
1349
1350
		if (likely(mask)) {
1351
			hotkey_read_nvram(&s[si], mask);
1352
			if (likely(si != so)) {
1353
				hotkey_compare_and_issue_event(&s[so], &s[si],
1354
								mask);
1355
			}
945
		}
1356
		}
946
1357
1358
		so = si;
1359
		si ^= 1;
1360
	}
1361
1362
exit:
1363
	mutex_unlock(&hotkey_thread_mutex);
947
	return 0;
1364
	return 0;
948
}
1365
}
949
1366
950
/* procfs -------------------------------------------------------------- */
1367
static void hotkey_poll_stop_sync(void)
951
static int hotkey_read(char *p)
952
{
1368
{
953
	int res, status, mask;
1369
	if (tpacpi_hotkey_task) {
954
	int len = 0;
1370
		if (frozen(tpacpi_hotkey_task) ||
1371
		    freezing(tpacpi_hotkey_task))
1372
			thaw_process(tpacpi_hotkey_task);
1373
1374
		kthread_stop(tpacpi_hotkey_task);
1375
		tpacpi_hotkey_task = NULL;
1376
		mutex_lock(&hotkey_thread_mutex);
1377
		/* at this point, the thread did exit */
1378
		mutex_unlock(&hotkey_thread_mutex);
1379
	}
1380
}
955
1381
956
	if (!tp_features.hotkey) {
1382
/* call with hotkey_mutex held */
957
		len += sprintf(p + len, "status:\t\tnot supported\n");
1383
static void hotkey_poll_setup(int may_warn)
958
		return len;
1384
{
1385
	if ((hotkey_source_mask & hotkey_mask) != 0 &&
1386
	    hotkey_poll_freq > 0 &&
1387
	    (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) {
1388
		if (!tpacpi_hotkey_task) {
1389
			tpacpi_hotkey_task = kthread_run(hotkey_kthread,
1390
							 NULL,
1391
							 TPACPI_FILE "d");
1392
			if (IS_ERR(tpacpi_hotkey_task)) {
1393
				tpacpi_hotkey_task = NULL;
1394
				printk(TPACPI_ERR
1395
				       "could not create kernel thread "
1396
				       "for hotkey polling\n");
1397
			}
1398
		}
1399
	} else {
1400
		hotkey_poll_stop_sync();
1401
		if (may_warn &&
1402
		    hotkey_source_mask != 0 && hotkey_poll_freq == 0) {
1403
			printk(TPACPI_NOTICE
1404
				"hot keys 0x%08x require polling, "
1405
				"which is currently disabled\n",
1406
				hotkey_source_mask);
1407
		}
959
	}
1408
	}
1409
}
960
1410
961
	res = mutex_lock_interruptible(&hotkey_mutex);
1411
static void hotkey_poll_setup_safe(int may_warn)
962
	if (res < 0)
1412
{
963
		return res;
1413
	mutex_lock(&hotkey_mutex);
964
	res = hotkey_get(&status, &mask);
1414
	hotkey_poll_setup(may_warn);
965
	mutex_unlock(&hotkey_mutex);
1415
	mutex_unlock(&hotkey_mutex);
966
	if (res)
1416
}
967
		return res;
968
1417
969
	len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
1418
static int hotkey_inputdev_open(struct input_dev *dev)
970
	if (tp_features.hotkey_mask) {
1419
{
971
		len += sprintf(p + len, "mask:\t\t0x%04x\n", mask);
1420
	switch (tpacpi_lifecycle) {
972
		len += sprintf(p + len,
1421
	case TPACPI_LIFE_INIT:
973
			       "commands:\tenable, disable, reset, <mask>\n");
1422
		/*
974
	} else {
1423
		 * hotkey_init will call hotkey_poll_setup_safe
975
		len += sprintf(p + len, "mask:\t\tnot supported\n");
1424
		 * at the appropriate moment
976
		len += sprintf(p + len, "commands:\tenable, disable, reset\n");
1425
		 */
1426
		return 0;
1427
	case TPACPI_LIFE_EXITING:
1428
		return -EBUSY;
1429
	case TPACPI_LIFE_RUNNING:
1430
		hotkey_poll_setup_safe(0);
1431
		return 0;
977
	}
1432
	}
978
1433
979
	return len;
1434
	/* Should only happen if tpacpi_lifecycle is corrupt */
1435
	BUG();
1436
	return -EBUSY;
980
}
1437
}
981
1438
982
static int hotkey_write(char *buf)
1439
static void hotkey_inputdev_close(struct input_dev *dev)
983
{
1440
{
984
	int res, status, mask;
1441
	/* disable hotkey polling when possible */
985
	char *cmd;
1442
	if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING)
986
	int do_cmd = 0;
1443
		hotkey_poll_setup_safe(0);
1444
}
1445
#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
987
1446
988
	if (!tp_features.hotkey)
1447
/* sysfs hotkey enable ------------------------------------------------- */
989
		return -ENODEV;
1448
static ssize_t hotkey_enable_show(struct device *dev,
1449
			   struct device_attribute *attr,
1450
			   char *buf)
1451
{
1452
	int res, status;
990
1453
991
	res = mutex_lock_interruptible(&hotkey_mutex);
1454
	res = hotkey_status_get(&status);
992
	if (res < 0)
1455
	if (res)
993
		return res;
1456
		return res;
994
1457
995
	res = hotkey_get(&status, &mask);
1458
	return snprintf(buf, PAGE_SIZE, "%d\n", status);
996
	if (res)
1459
}
997
		goto errexit;
998
1460
999
	res = 0;
1461
static ssize_t hotkey_enable_store(struct device *dev,
1000
	while ((cmd = next_cmd(&buf))) {
1462
			    struct device_attribute *attr,
1001
		if (strlencmp(cmd, "enable") == 0) {
1463
			    const char *buf, size_t count)
1002
			status = 1;
1464
{
1003
		} else if (strlencmp(cmd, "disable") == 0) {
1465
	unsigned long t;
1004
			status = 0;
1466
	int res;
1005
		} else if (strlencmp(cmd, "reset") == 0) {
1467
1006
			status = hotkey_orig_status;
1468
	if (parse_strtoul(buf, 1, &t))
1007
			mask = hotkey_orig_mask;
1469
		return -EINVAL;
1008
		} else if (sscanf(cmd, "0x%x", &mask) == 1) {
1009
			/* mask set */
1010
		} else if (sscanf(cmd, "%x", &mask) == 1) {
1011
			/* mask set */
1012
		} else {
1013
			res = -EINVAL;
1014
			goto errexit;
1015
		}
1016
		do_cmd = 1;
1017
	}
1018
1470
1019
	if (do_cmd)
1471
	res = hotkey_status_set(t);
1020
		res = hotkey_set(status, mask);
1021
1472
1022
errexit:
1473
	return (res) ? res : count;
1023
	mutex_unlock(&hotkey_mutex);
1024
	return res;
1025
}
1474
}
1026
1475
1027
static const struct acpi_device_id ibm_htk_device_ids[] = {
1476
static struct device_attribute dev_attr_hotkey_enable =
1028
	{IBM_HKEY_HID, 0},
1477
	__ATTR(hotkey_enable, S_IWUSR | S_IRUGO,
1029
	{"", 0},
1478
		hotkey_enable_show, hotkey_enable_store);
1030
};
1031
1032
static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
1033
	.hid = ibm_htk_device_ids,
1034
	.notify = hotkey_notify,
1035
	.handle = &hkey_handle,
1036
	.type = ACPI_DEVICE_NOTIFY,
1037
};
1038
1039
static struct ibm_struct hotkey_driver_data = {
1040
	.name = "hotkey",
1041
	.read = hotkey_read,
1042
	.write = hotkey_write,
1043
	.exit = hotkey_exit,
1044
	.acpi = &ibm_hotkey_acpidriver,
1045
};
1046
1047
/*************************************************************************
1048
 * Bluetooth subdriver
1049
 */
1050
1479
1051
/* sysfs bluetooth enable ---------------------------------------------- */
1480
/* sysfs hotkey mask --------------------------------------------------- */
1052
static ssize_t bluetooth_enable_show(struct device *dev,
1481
static ssize_t hotkey_mask_show(struct device *dev,
1053
			   struct device_attribute *attr,
1482
			   struct device_attribute *attr,
1054
			   char *buf)
1483
			   char *buf)
1055
{
1484
{
1056
	int status;
1485
	int res;
1057
1486
1058
	status = bluetooth_get_radiosw();
1487
	if (mutex_lock_interruptible(&hotkey_mutex))
1059
	if (status < 0)
1488
		return -ERESTARTSYS;
1060
		return status;
1489
	res = hotkey_mask_get();
1490
	mutex_unlock(&hotkey_mutex);
1061
1491
1062
	return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0);
1492
	return (res)?
1493
		res : snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_mask);
1063
}
1494
}
1064
1495
1065
static ssize_t bluetooth_enable_store(struct device *dev,
1496
static ssize_t hotkey_mask_store(struct device *dev,
1066
			    struct device_attribute *attr,
1497
			    struct device_attribute *attr,
1067
			    const char *buf, size_t count)
1498
			    const char *buf, size_t count)
1068
{
1499
{
1069
	unsigned long t;
1500
	unsigned long t;
1070
	int res;
1501
	int res;
1071
1502
1072
	if (parse_strtoul(buf, 1, &t))
1503
	if (parse_strtoul(buf, 0xffffffffUL, &t))
1073
		return -EINVAL;
1504
		return -EINVAL;
1074
1505
1075
	res = bluetooth_set_radiosw(t);
1506
	if (mutex_lock_interruptible(&hotkey_mutex))
1507
		return -ERESTARTSYS;
1076
1508
1077
	return (res) ? res : count;
1509
	res = hotkey_mask_set(t);
1078
}
1079
1510
1080
static struct device_attribute dev_attr_bluetooth_enable =
1511
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1081
	__ATTR(bluetooth_enable, S_IWUSR | S_IRUGO,
1512
	hotkey_poll_setup(1);
1082
		bluetooth_enable_show, bluetooth_enable_store);
1513
#endif
1083
1514
1084
/* --------------------------------------------------------------------- */
1515
	mutex_unlock(&hotkey_mutex);
1085
1516
1086
static struct attribute *bluetooth_attributes[] = {
1517
	return (res) ? res : count;
1087
	&dev_attr_bluetooth_enable.attr,
1518
}
1088
	NULL
1089
};
1090
1519
1091
static const struct attribute_group bluetooth_attr_group = {
1520
static struct device_attribute dev_attr_hotkey_mask =
1092
	.attrs = bluetooth_attributes,
1521
	__ATTR(hotkey_mask, S_IWUSR | S_IRUGO,
1093
};
1522
		hotkey_mask_show, hotkey_mask_store);
1094
1523
1095
static int __init bluetooth_init(struct ibm_init_struct *iibm)
1524
/* sysfs hotkey bios_enabled ------------------------------------------- */
1525
static ssize_t hotkey_bios_enabled_show(struct device *dev,
1526
			   struct device_attribute *attr,
1527
			   char *buf)
1096
{
1528
{
1097
	int res;
1529
	return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
1098
	int status = 0;
1530
}
1099
1531
1100
	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
1532
static struct device_attribute dev_attr_hotkey_bios_enabled =
1533
	__ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
1101
1534
1102
	IBM_ACPIHANDLE_INIT(hkey);
1535
/* sysfs hotkey bios_mask ---------------------------------------------- */
1536
static ssize_t hotkey_bios_mask_show(struct device *dev,
1537
			   struct device_attribute *attr,
1538
			   char *buf)
1539
{
1540
	return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
1541
}
1103
1542
1104
	/* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
1543
static struct device_attribute dev_attr_hotkey_bios_mask =
1105
	   G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
1544
	__ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
1106
	tp_features.bluetooth = hkey_handle &&
1107
	    acpi_evalf(hkey_handle, &status, "GBDC", "qd");
1108
1545
1109
	vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
1546
/* sysfs hotkey all_mask ----------------------------------------------- */
1110
		str_supported(tp_features.bluetooth),
1547
static ssize_t hotkey_all_mask_show(struct device *dev,
1111
		status);
1548
			   struct device_attribute *attr,
1549
			   char *buf)
1550
{
1551
	return snprintf(buf, PAGE_SIZE, "0x%08x\n",
1552
				hotkey_all_mask | hotkey_source_mask);
1553
}
1112
1554
1113
	if (tp_features.bluetooth) {
1555
static struct device_attribute dev_attr_hotkey_all_mask =
1114
		if (!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
1556
	__ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL);
1115
			/* no bluetooth hardware present in system */
1116
			tp_features.bluetooth = 0;
1117
			dbg_printk(TPACPI_DBG_INIT,
1118
				   "bluetooth hardware not installed\n");
1119
		} else {
1120
			res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
1121
					&bluetooth_attr_group);
1122
			if (res)
1123
				return res;
1124
		}
1125
	}
1126
1557
1127
	return (tp_features.bluetooth)? 0 : 1;
1558
/* sysfs hotkey recommended_mask --------------------------------------- */
1559
static ssize_t hotkey_recommended_mask_show(struct device *dev,
1560
					    struct device_attribute *attr,
1561
					    char *buf)
1562
{
1563
	return snprintf(buf, PAGE_SIZE, "0x%08x\n",
1564
			(hotkey_all_mask | hotkey_source_mask)
1565
			& ~hotkey_reserved_mask);
1128
}
1566
}
1129
1567
1130
static void bluetooth_exit(void)
1568
static struct device_attribute dev_attr_hotkey_recommended_mask =
1569
	__ATTR(hotkey_recommended_mask, S_IRUGO,
1570
		hotkey_recommended_mask_show, NULL);
1571
1572
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1573
1574
/* sysfs hotkey hotkey_source_mask ------------------------------------- */
1575
static ssize_t hotkey_source_mask_show(struct device *dev,
1576
			   struct device_attribute *attr,
1577
			   char *buf)
1131
{
1578
{
1132
	sysfs_remove_group(&tpacpi_pdev->dev.kobj,
1579
	return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_source_mask);
1133
			&bluetooth_attr_group);
1134
}
1580
}
1135
1581
1136
static int bluetooth_get_radiosw(void)
1582
static ssize_t hotkey_source_mask_store(struct device *dev,
1583
			    struct device_attribute *attr,
1584
			    const char *buf, size_t count)
1137
{
1585
{
1138
	int status;
1586
	unsigned long t;
1139
1140
	if (!tp_features.bluetooth)
1141
		return -ENODEV;
1142
1587
1143
	if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
1588
	if (parse_strtoul(buf, 0xffffffffUL, &t) ||
1144
		return -EIO;
1589
		((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0))
1590
		return -EINVAL;
1145
1591
1146
	return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0);
1592
	if (mutex_lock_interruptible(&hotkey_mutex))
1147
}
1593
		return -ERESTARTSYS;
1148
1594
1149
static int bluetooth_set_radiosw(int radio_on)
1595
	HOTKEY_CONFIG_CRITICAL_START
1150
{
1596
	hotkey_source_mask = t;
1151
	int status;
1597
	HOTKEY_CONFIG_CRITICAL_END
1152
1598
1153
	if (!tp_features.bluetooth)
1599
	hotkey_poll_setup(1);
1154
		return -ENODEV;
1155
1600
1156
	if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
1601
	mutex_unlock(&hotkey_mutex);
1157
		return -EIO;
1158
	if (radio_on)
1159
		status |= TP_ACPI_BLUETOOTH_RADIOSSW;
1160
	else
1161
		status &= ~TP_ACPI_BLUETOOTH_RADIOSSW;
1162
	if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
1163
		return -EIO;
1164
1602
1165
	return 0;
1603
	return count;
1166
}
1604
}
1167
1605
1168
/* procfs -------------------------------------------------------------- */
1606
static struct device_attribute dev_attr_hotkey_source_mask =
1169
static int bluetooth_read(char *p)
1607
	__ATTR(hotkey_source_mask, S_IWUSR | S_IRUGO,
1170
{
1608
		hotkey_source_mask_show, hotkey_source_mask_store);
1171
	int len = 0;
1172
	int status = bluetooth_get_radiosw();
1173
1174
	if (!tp_features.bluetooth)
1175
		len += sprintf(p + len, "status:\t\tnot supported\n");
1176
	else {
1177
		len += sprintf(p + len, "status:\t\t%s\n",
1178
				(status)? "enabled" : "disabled");
1179
		len += sprintf(p + len, "commands:\tenable, disable\n");
1180
	}
1181
1609
1182
	return len;
1610
/* sysfs hotkey hotkey_poll_freq --------------------------------------- */
1611
static ssize_t hotkey_poll_freq_show(struct device *dev,
1612
			   struct device_attribute *attr,
1613
			   char *buf)
1614
{
1615
	return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_poll_freq);
1183
}
1616
}
1184
1617
1185
static int bluetooth_write(char *buf)
1618
static ssize_t hotkey_poll_freq_store(struct device *dev,
1619
			    struct device_attribute *attr,
1620
			    const char *buf, size_t count)
1186
{
1621
{
1187
	char *cmd;
1622
	unsigned long t;
1188
1623
1189
	if (!tp_features.bluetooth)
1624
	if (parse_strtoul(buf, 25, &t))
1190
		return -ENODEV;
1625
		return -EINVAL;
1191
1626
1192
	while ((cmd = next_cmd(&buf))) {
1627
	if (mutex_lock_interruptible(&hotkey_mutex))
1193
		if (strlencmp(cmd, "enable") == 0) {
1628
		return -ERESTARTSYS;
1194
			bluetooth_set_radiosw(1);
1195
		} else if (strlencmp(cmd, "disable") == 0) {
1196
			bluetooth_set_radiosw(0);
1197
		} else
1198
			return -EINVAL;
1199
	}
1200
1629
1201
	return 0;
1630
	hotkey_poll_freq = t;
1631
1632
	hotkey_poll_setup(1);
1633
	mutex_unlock(&hotkey_mutex);
1634
1635
	return count;
1202
}
1636
}
1203
1637
1204
static struct ibm_struct bluetooth_driver_data = {
1638
static struct device_attribute dev_attr_hotkey_poll_freq =
1205
	.name = "bluetooth",
1639
	__ATTR(hotkey_poll_freq, S_IWUSR | S_IRUGO,
1206
	.read = bluetooth_read,
1640
		hotkey_poll_freq_show, hotkey_poll_freq_store);
1207
	.write = bluetooth_write,
1208
	.exit = bluetooth_exit,
1209
};
1210
1641
1211
/*************************************************************************
1642
#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1212
 * Wan subdriver
1213
 */
1214
1643
1215
/* sysfs wan enable ---------------------------------------------------- */
1644
/* sysfs hotkey radio_sw (pollable) ------------------------------------ */
1216
static ssize_t wan_enable_show(struct device *dev,
1645
static ssize_t hotkey_radio_sw_show(struct device *dev,
1217
			   struct device_attribute *attr,
1646
			   struct device_attribute *attr,
1218
			   char *buf)
1647
			   char *buf)
1219
{
1648
{
1220
	int status;
1649
	int res, s;
1650
	res = hotkey_get_wlsw(&s);
1651
	if (res < 0)
1652
		return res;
1221
1653
1222
	status = wan_get_radiosw();
1654
	return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
1223
	if (status < 0)
1655
}
1224
		return status;
1225
1656
1226
	return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0);
1657
static struct device_attribute dev_attr_hotkey_radio_sw =
1658
	__ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
1659
1660
static void hotkey_radio_sw_notify_change(void)
1661
{
1662
	if (tp_features.hotkey_wlsw)
1663
		sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
1664
			     "hotkey_radio_sw");
1227
}
1665
}
1228
1666
1229
static ssize_t wan_enable_store(struct device *dev,
1667
/* sysfs hotkey report_mode -------------------------------------------- */
1668
static ssize_t hotkey_report_mode_show(struct device *dev,
1669
			   struct device_attribute *attr,
1670
			   char *buf)
1671
{
1672
	return snprintf(buf, PAGE_SIZE, "%d\n",
1673
		(hotkey_report_mode != 0) ? hotkey_report_mode : 1);
1674
}
1675
1676
static ssize_t hotkey_report_mode_store(struct device *dev,
1230
			    struct device_attribute *attr,
1677
			    struct device_attribute *attr,
1231
			    const char *buf, size_t count)
1678
			    const char *buf, size_t count)
1232
{
1679
{
1233
	unsigned long t;
1680
	unsigned long t;
1234
	int res;
1681
	int res = 0;
1235
1682
1236
	if (parse_strtoul(buf, 1, &t))
1683
	if (parse_strtoul(buf, 2, &t) || (t < 1))
1237
		return -EINVAL;
1684
		return -EINVAL;
1238
1685
1239
	res = wan_set_radiosw(t);
1686
	if (t != hotkey_report_mode) {
1687
		if (tp_features.hotkey_report_mode_locked)
1688
			return -EPERM;
1689
		hotkey_report_mode = t;
1690
		printk(TPACPI_NOTICE "hot key report mode set to %d\n",
1691
			hotkey_report_mode);
1692
	}
1240
1693
1241
	return (res) ? res : count;
1694
	return (res) ? res : count;
1242
}
1695
}
1243
1696
1244
static struct device_attribute dev_attr_wan_enable =
1697
static struct device_attribute dev_attr_hotkey_report_mode =
1245
	__ATTR(wwan_enable, S_IWUSR | S_IRUGO,
1698
	__ATTR(hotkey_report_mode, S_IWUSR | S_IRUGO,
1246
		wan_enable_show, wan_enable_store);
1699
		hotkey_report_mode_show, hotkey_report_mode_store);
1700
1701
/* sysfs wakeup reason (pollable) -------------------------------------- */
1702
static ssize_t hotkey_wakeup_reason_show(struct device *dev,
1703
			   struct device_attribute *attr,
1704
			   char *buf)
1705
{
1706
	return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason);
1707
}
1708
1709
static struct device_attribute dev_attr_hotkey_wakeup_reason =
1710
	__ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL);
1711
1712
void hotkey_wakeup_reason_notify_change(void)
1713
{
1714
	if (tp_features.hotkey_mask)
1715
		sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
1716
			     "wakeup_reason");
1717
}
1718
1719
/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */
1720
static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev,
1721
			   struct device_attribute *attr,
1722
			   char *buf)
1723
{
1724
	return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack);
1725
}
1726
1727
static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete =
1728
	__ATTR(wakeup_hotunplug_complete, S_IRUGO,
1729
	       hotkey_wakeup_hotunplug_complete_show, NULL);
1730
1731
void hotkey_wakeup_hotunplug_complete_notify_change(void)
1732
{
1733
	if (tp_features.hotkey_mask)
1734
		sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
1735
			     "wakeup_hotunplug_complete");
1736
}
1247
1737
1248
/* --------------------------------------------------------------------- */
1738
/* --------------------------------------------------------------------- */
1249
1739
1250
static struct attribute *wan_attributes[] = {
1740
static struct attribute *hotkey_attributes[] __initdata = {
1251
	&dev_attr_wan_enable.attr,
1741
	&dev_attr_hotkey_enable.attr,
1252
	NULL
1742
	&dev_attr_hotkey_bios_enabled.attr,
1743
	&dev_attr_hotkey_report_mode.attr,
1744
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1745
	&dev_attr_hotkey_mask.attr,
1746
	&dev_attr_hotkey_all_mask.attr,
1747
	&dev_attr_hotkey_recommended_mask.attr,
1748
	&dev_attr_hotkey_source_mask.attr,
1749
	&dev_attr_hotkey_poll_freq.attr,
1750
#endif
1253
};
1751
};
1254
1752
1255
static const struct attribute_group wan_attr_group = {
1753
static struct attribute *hotkey_mask_attributes[] __initdata = {
1256
	.attrs = wan_attributes,
1754
	&dev_attr_hotkey_bios_mask.attr,
1755
#ifndef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1756
	&dev_attr_hotkey_mask.attr,
1757
	&dev_attr_hotkey_all_mask.attr,
1758
	&dev_attr_hotkey_recommended_mask.attr,
1759
#endif
1760
	&dev_attr_hotkey_wakeup_reason.attr,
1761
	&dev_attr_hotkey_wakeup_hotunplug_complete.attr,
1257
};
1762
};
1258
1763
1259
static int __init wan_init(struct ibm_init_struct *iibm)
1764
static int __init hotkey_init(struct ibm_init_struct *iibm)
1260
{
1765
{
1261
	int res;
1766
	/* Requirements for changing the default keymaps:
1262
	int status = 0;
1767
	 *
1768
	 * 1. Many of the keys are mapped to KEY_RESERVED for very
1769
	 *    good reasons.  Do not change them unless you have deep
1770
	 *    knowledge on the IBM and Lenovo ThinkPad firmware for
1771
	 *    the various ThinkPad models.  The driver behaves
1772
	 *    differently for KEY_RESERVED: such keys have their
1773
	 *    hot key mask *unset* in mask_recommended, and also
1774
	 *    in the initial hot key mask programmed into the
1775
	 *    firmware at driver load time, which means the firm-
1776
	 *    ware may react very differently if you change them to
1777
	 *    something else;
1778
	 *
1779
	 * 2. You must be subscribed to the linux-thinkpad and
1780
	 *    ibm-acpi-devel mailing lists, and you should read the
1781
	 *    list archives since 2007 if you want to change the
1782
	 *    keymaps.  This requirement exists so that you will
1783
	 *    know the past history of problems with the thinkpad-
1784
	 *    acpi driver keymaps, and also that you will be
1785
	 *    listening to any bug reports;
1786
	 *
1787
	 * 3. Do not send thinkpad-acpi specific patches directly to
1788
	 *    for merging, *ever*.  Send them to the linux-acpi
1789
	 *    mailinglist for comments.  Merging is to be done only
1790
	 *    through acpi-test and the ACPI maintainer.
1791
	 *
1792
	 * If the above is too much to ask, don't change the keymap.
1793
	 * Ask the thinkpad-acpi maintainer to do it, instead.
1794
	 */
1795
	static u16 ibm_keycode_map[] __initdata = {
1796
		/* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
1797
		KEY_FN_F1,	KEY_FN_F2,	KEY_COFFEE,	KEY_SLEEP,
1798
		KEY_WLAN,	KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
1799
		KEY_FN_F9,	KEY_FN_F10,	KEY_FN_F11,	KEY_SUSPEND,
1800
1801
		/* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */
1802
		KEY_UNKNOWN,	/* 0x0C: FN+BACKSPACE */
1803
		KEY_UNKNOWN,	/* 0x0D: FN+INSERT */
1804
		KEY_UNKNOWN,	/* 0x0E: FN+DELETE */
1805
1806
		/* brightness: firmware always reacts to them, unless
1807
		 * X.org did some tricks in the radeon BIOS scratch
1808
		 * registers of *some* models */
1809
		KEY_RESERVED,	/* 0x0F: FN+HOME (brightness up) */
1810
		KEY_RESERVED,	/* 0x10: FN+END (brightness down) */
1811
1812
		/* Thinklight: firmware always react to it */
1813
		KEY_RESERVED,	/* 0x11: FN+PGUP (thinklight toggle) */
1814
1815
		KEY_UNKNOWN,	/* 0x12: FN+PGDOWN */
1816
		KEY_ZOOM,	/* 0x13: FN+SPACE (zoom) */
1817
1818
		/* Volume: firmware always react to it and reprograms
1819
		 * the built-in *extra* mixer.  Never map it to control
1820
		 * another mixer by default. */
1821
		KEY_RESERVED,	/* 0x14: VOLUME UP */
1822
		KEY_RESERVED,	/* 0x15: VOLUME DOWN */
1823
		KEY_RESERVED,	/* 0x16: MUTE */
1824
1825
		KEY_VENDOR,	/* 0x17: Thinkpad/AccessIBM/Lenovo */
1826
1827
		/* (assignments unknown, please report if found) */
1828
		KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
1829
		KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
1830
	};
1831
	static u16 lenovo_keycode_map[] __initdata = {
1832
		/* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
1833
		KEY_FN_F1,	KEY_COFFEE,	KEY_BATTERY,	KEY_SLEEP,
1834
		KEY_WLAN,	KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
1835
		KEY_FN_F9,	KEY_FN_F10,	KEY_FN_F11,	KEY_SUSPEND,
1836
1837
		/* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */
1838
		KEY_UNKNOWN,	/* 0x0C: FN+BACKSPACE */
1839
		KEY_UNKNOWN,	/* 0x0D: FN+INSERT */
1840
		KEY_UNKNOWN,	/* 0x0E: FN+DELETE */
1841
1842
		KEY_RESERVED,	/* 0x0F: FN+HOME (brightness up) */
1843
		KEY_RESERVED,	/* 0x10: FN+END (brightness down) */
1844
1845
		KEY_RESERVED,	/* 0x11: FN+PGUP (thinklight toggle) */
1846
1847
		KEY_UNKNOWN,	/* 0x12: FN+PGDOWN */
1848
		KEY_ZOOM,	/* 0x13: FN+SPACE (zoom) */
1849
1850
		/* Volume: z60/z61, T60 (BIOS version?): firmware always
1851
		 * react to it and reprograms the built-in *extra* mixer.
1852
		 * Never map it to control another mixer by default.
1853
		 *
1854
		 * T60?, T61, R60?, R61: firmware and EC tries to send
1855
		 * these over the regular keyboard, so these are no-ops,
1856
		 * but there are still weird bugs re. MUTE, so do not
1857
		 * change unless you get test reports from all Lenovo
1858
		 * models.  May cause the BIOS to interfere with the
1859
		 * HDA mixer.
1860
		 */
1861
		KEY_RESERVED,	/* 0x14: VOLUME UP */
1862
		KEY_RESERVED,	/* 0x15: VOLUME DOWN */
1863
		KEY_RESERVED,	/* 0x16: MUTE */
1864
1865
		KEY_VENDOR,	/* 0x17: Thinkpad/AccessIBM/Lenovo */
1866
1867
		/* (assignments unknown, please report if found) */
1868
		KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
1869
		KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
1870
	};
1871
1872
#define TPACPI_HOTKEY_MAP_LEN		ARRAY_SIZE(ibm_keycode_map)
1873
#define TPACPI_HOTKEY_MAP_SIZE		sizeof(ibm_keycode_map)
1874
#define TPACPI_HOTKEY_MAP_TYPESIZE	sizeof(ibm_keycode_map[0])
1263
1875
1264
	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
1876
	int res, i;
1877
	int status;
1878
	int hkeyv;
1265
1879
1266
	IBM_ACPIHANDLE_INIT(hkey);
1880
	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
1267
1881
1268
	tp_features.wan = hkey_handle &&
1882
	BUG_ON(!tpacpi_inputdev);
1269
	    acpi_evalf(hkey_handle, &status, "GWAN", "qd");
1883
	BUG_ON(tpacpi_inputdev->open != NULL ||
1884
	       tpacpi_inputdev->close != NULL);
1270
1885
1271
	vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
1886
	TPACPI_ACPIHANDLE_INIT(hkey);
1272
		str_supported(tp_features.wan),
1887
	mutex_init(&hotkey_mutex);
1273
		status);
1274
1888
1275
	if (tp_features.wan) {
1889
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1276
		if (!(status & TP_ACPI_WANCARD_HWPRESENT)) {
1890
	mutex_init(&hotkey_thread_mutex);
1277
			/* no wan hardware present in system */
1891
	mutex_init(&hotkey_thread_data_mutex);
1278
			tp_features.wan = 0;
1892
#endif
1893
1894
	/* hotkey not supported on 570 */
1895
	tp_features.hotkey = hkey_handle != NULL;
1896
1897
	vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
1898
		str_supported(tp_features.hotkey));
1899
1900
	if (tp_features.hotkey) {
1901
		hotkey_dev_attributes = create_attr_set(12, NULL);
1902
		if (!hotkey_dev_attributes)
1903
			return -ENOMEM;
1904
		res = add_many_to_attr_set(hotkey_dev_attributes,
1905
				hotkey_attributes,
1906
				ARRAY_SIZE(hotkey_attributes));
1907
		if (res)
1908
			return res;
1909
1910
		/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
1911
		   A30, R30, R31, T20-22, X20-21, X22-24.  Detected by checking
1912
		   for HKEY interface version 0x100 */
1913
		if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
1914
			if ((hkeyv >> 8) != 1) {
1915
				printk(TPACPI_ERR "unknown version of the "
1916
				       "HKEY interface: 0x%x\n", hkeyv);
1917
				printk(TPACPI_ERR "please report this to %s\n",
1918
				       TPACPI_MAIL);
1919
			} else {
1920
				/*
1921
				 * MHKV 0x100 in A31, R40, R40e,
1922
				 * T4x, X31, and later
1923
				 */
1924
				tp_features.hotkey_mask = 1;
1925
			}
1926
		}
1927
1928
		vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
1929
			str_supported(tp_features.hotkey_mask));
1930
1931
		if (tp_features.hotkey_mask) {
1932
			if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
1933
					"MHKA", "qd")) {
1934
				printk(TPACPI_ERR
1935
				       "missing MHKA handler, "
1936
				       "please report this to %s\n",
1937
				       TPACPI_MAIL);
1938
				/* FN+F12, FN+F4, FN+F3 */
1939
				hotkey_all_mask = 0x080cU;
1940
			}
1941
		}
1942
1943
		/* hotkey_source_mask *must* be zero for
1944
		 * the first hotkey_mask_get */
1945
		res = hotkey_status_get(&hotkey_orig_status);
1946
		if (!res && tp_features.hotkey_mask) {
1947
			res = hotkey_mask_get();
1948
			hotkey_orig_mask = hotkey_mask;
1949
			if (!res) {
1950
				res = add_many_to_attr_set(
1951
					hotkey_dev_attributes,
1952
					hotkey_mask_attributes,
1953
					ARRAY_SIZE(hotkey_mask_attributes));
1954
			}
1955
		}
1956
1957
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1958
		if (tp_features.hotkey_mask) {
1959
			hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
1960
						& ~hotkey_all_mask;
1961
		} else {
1962
			hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
1963
		}
1964
1965
		vdbg_printk(TPACPI_DBG_INIT,
1966
			    "hotkey source mask 0x%08x, polling freq %d\n",
1967
			    hotkey_source_mask, hotkey_poll_freq);
1968
#endif
1969
1970
		/* Not all thinkpads have a hardware radio switch */
1971
		if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
1972
			tp_features.hotkey_wlsw = 1;
1973
			printk(TPACPI_INFO
1974
				"radio switch found; radios are %s\n",
1975
				enabled(status, 0));
1976
			res = add_to_attr_set(hotkey_dev_attributes,
1977
					&dev_attr_hotkey_radio_sw.attr);
1978
		}
1979
1980
		if (!res)
1981
			res = register_attr_set_with_sysfs(
1982
					hotkey_dev_attributes,
1983
					&tpacpi_pdev->dev.kobj);
1984
		if (res)
1985
			return res;
1986
1987
		/* Set up key map */
1988
1989
		hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
1990
						GFP_KERNEL);
1991
		if (!hotkey_keycode_map) {
1992
			printk(TPACPI_ERR
1993
				"failed to allocate memory for key map\n");
1994
			return -ENOMEM;
1995
		}
1996
1997
		if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
1279
			dbg_printk(TPACPI_DBG_INIT,
1998
			dbg_printk(TPACPI_DBG_INIT,
1280
				   "wan hardware not installed\n");
1999
				   "using Lenovo default hot key map\n");
2000
			memcpy(hotkey_keycode_map, &lenovo_keycode_map,
2001
				TPACPI_HOTKEY_MAP_SIZE);
1281
		} else {
2002
		} else {
1282
			res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
2003
			dbg_printk(TPACPI_DBG_INIT,
1283
					&wan_attr_group);
2004
				   "using IBM default hot key map\n");
1284
			if (res)
2005
			memcpy(hotkey_keycode_map, &ibm_keycode_map,
1285
				return res;
2006
				TPACPI_HOTKEY_MAP_SIZE);
2007
		}
2008
2009
		set_bit(EV_KEY, tpacpi_inputdev->evbit);
2010
		set_bit(EV_MSC, tpacpi_inputdev->evbit);
2011
		set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
2012
		tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
2013
		tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
2014
		tpacpi_inputdev->keycode = hotkey_keycode_map;
2015
		for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
2016
			if (hotkey_keycode_map[i] != KEY_RESERVED) {
2017
				set_bit(hotkey_keycode_map[i],
2018
					tpacpi_inputdev->keybit);
2019
			} else {
2020
				if (i < sizeof(hotkey_reserved_mask)*8)
2021
					hotkey_reserved_mask |= 1 << i;
2022
			}
2023
		}
2024
2025
		if (tp_features.hotkey_wlsw) {
2026
			set_bit(EV_SW, tpacpi_inputdev->evbit);
2027
			set_bit(SW_RADIO, tpacpi_inputdev->swbit);
2028
		}
2029
2030
		dbg_printk(TPACPI_DBG_INIT,
2031
				"enabling hot key handling\n");
2032
		res = hotkey_status_set(1);
2033
		if (res)
2034
			return res;
2035
		res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask)
2036
					& ~hotkey_reserved_mask)
2037
					| hotkey_orig_mask);
2038
		if (res < 0 && res != -ENXIO)
2039
			return res;
2040
2041
		if (hotkey_report_mode > 0) {
2042
			tp_features.hotkey_report_mode_locked = 1;
2043
		} else {
2044
			hotkey_report_mode = 1;
2045
			vdbg_printk(TPACPI_DBG_INIT,
2046
					"hot key reporting mode can be "
2047
					"changed at runtime\n");
1286
		}
2048
		}
2049
2050
		dbg_printk(TPACPI_DBG_INIT,
2051
				"legacy hot key reporting over procfs %s\n",
2052
				(hotkey_report_mode < 2) ?
2053
					"enabled" : "disabled");
2054
2055
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2056
		tpacpi_inputdev->open = &hotkey_inputdev_open;
2057
		tpacpi_inputdev->close = &hotkey_inputdev_close;
2058
2059
		hotkey_poll_setup_safe(1);
2060
#endif
1287
	}
2061
	}
1288
2062
1289
	return (tp_features.wan)? 0 : 1;
2063
	return (tp_features.hotkey)? 0 : 1;
1290
}
2064
}
1291
2065
1292
static void wan_exit(void)
2066
static void hotkey_exit(void)
1293
{
2067
{
1294
	sysfs_remove_group(&tpacpi_pdev->dev.kobj,
2068
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1295
		&wan_attr_group);
2069
	hotkey_poll_stop_sync();
2070
#endif
2071
2072
	if (tp_features.hotkey) {
2073
		dbg_printk(TPACPI_DBG_EXIT,
2074
			   "restoring original hot key mask\n");
2075
		/* no short-circuit boolean operator below! */
2076
		if ((hotkey_mask_set(hotkey_orig_mask) |
2077
		     hotkey_status_set(hotkey_orig_status)) != 0)
2078
			printk(TPACPI_ERR
2079
			       "failed to restore hot key mask "
2080
			       "to BIOS defaults\n");
2081
	}
2082
2083
	if (hotkey_dev_attributes) {
2084
		delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
2085
		hotkey_dev_attributes = NULL;
2086
	}
1296
}
2087
}
1297
2088
1298
static int wan_get_radiosw(void)
2089
static void hotkey_notify(struct ibm_struct *ibm, u32 event)
1299
{
2090
{
1300
	int status;
2091
	u32 hkey;
1301
2092
	unsigned int scancode;
1302
	if (!tp_features.wan)
2093
	int send_acpi_ev;
1303
		return -ENODEV;
2094
	int ignore_acpi_ev;
2095
	int unk_ev;
2096
2097
	if (event != 0x80) {
2098
		printk(TPACPI_ERR
2099
		       "unknown HKEY notification event %d\n", event);
2100
		/* forward it to userspace, maybe it knows how to handle it */
2101
		acpi_bus_generate_event(ibm->acpi->device, event, 0);
1304
2102
1305
	if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
2103
		return;
1306
		return -EIO;
2104
	}
1307
2105
1308
	return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0);
2106
	while (1) {
1309
}
2107
		if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
2108
			printk(TPACPI_ERR "failed to retrieve HKEY event\n");
2109
			return;
2110
		}
1310
2111
1311
static int wan_set_radiosw(int radio_on)
2112
		if (hkey == 0) {
1312
{
2113
			/* queue empty */
1313
	int status;
2114
			return;
2115
		}
1314
2116
1315
	if (!tp_features.wan)
2117
		send_acpi_ev = 1;
1316
		return -ENODEV;
2118
		ignore_acpi_ev = 0;
2119
		unk_ev = 0;
2120
2121
		switch (hkey >> 12) {
2122
		case 1:
2123
			/* 0x1000-0x1FFF: key presses */
2124
			scancode = hkey & 0xfff;
2125
			if (scancode > 0 && scancode < 0x21) {
2126
				scancode--;
2127
				if (!(hotkey_source_mask & (1 << scancode))) {
2128
					tpacpi_input_send_key(scancode);
2129
					send_acpi_ev = 0;
2130
				} else {
2131
					ignore_acpi_ev = 1;
2132
				}
2133
			} else {
2134
				unk_ev = 1;
2135
			}
2136
			break;
2137
		case 2:
2138
			/* Wakeup reason */
2139
			switch (hkey) {
2140
			case 0x2304: /* suspend, undock */
2141
			case 0x2404: /* hibernation, undock */
2142
				hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK;
2143
				ignore_acpi_ev = 1;
2144
				break;
2145
			case 0x2305: /* suspend, bay eject */
2146
			case 0x2405: /* hibernation, bay eject */
2147
				hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ;
2148
				ignore_acpi_ev = 1;
2149
				break;
2150
			default:
2151
				unk_ev = 1;
2152
			}
2153
			if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) {
2154
				printk(TPACPI_INFO
2155
				       "woke up due to a hot-unplug "
2156
				       "request...\n");
2157
				hotkey_wakeup_reason_notify_change();
2158
			}
2159
			break;
2160
		case 3:
2161
			/* bay-related wakeups */
2162
			if (hkey == 0x3003) {
2163
				hotkey_autosleep_ack = 1;
2164
				printk(TPACPI_INFO
2165
				       "bay ejected\n");
2166
				hotkey_wakeup_hotunplug_complete_notify_change();
2167
			} else {
2168
				unk_ev = 1;
2169
			}
2170
			break;
2171
		case 4:
2172
			/* dock-related wakeups */
2173
			if (hkey == 0x4003) {
2174
				hotkey_autosleep_ack = 1;
2175
				printk(TPACPI_INFO
2176
				       "undocked\n");
2177
				hotkey_wakeup_hotunplug_complete_notify_change();
2178
			} else {
2179
				unk_ev = 1;
2180
			}
2181
			break;
2182
		case 5:
2183
			/* 0x5000-0x5FFF: human interface helpers */
2184
			switch (hkey) {
2185
			case 0x5010: /* Lenovo new BIOS: brightness changed */
2186
			case 0x5009: /* X61t: swivel up (tablet mode) */
2187
			case 0x500a: /* X61t: swivel down (normal mode) */
2188
			case 0x500b: /* X61t: tablet pen inserted into bay */
2189
			case 0x500c: /* X61t: tablet pen removed from bay */
2190
				break;
2191
			case 0x5001:
2192
			case 0x5002:
2193
				/* LID switch events.  Do not propagate */
2194
				ignore_acpi_ev = 1;
2195
				break;
2196
			default:
2197
				unk_ev = 1;
2198
			}
2199
			break;
2200
		case 7:
2201
			/* 0x7000-0x7FFF: misc */
2202
			if (tp_features.hotkey_wlsw && hkey == 0x7000) {
2203
				tpacpi_input_send_radiosw();
2204
				hotkey_radio_sw_notify_change();
2205
				send_acpi_ev = 0;
2206
				break;
2207
			}
2208
			/* fallthrough to default */
2209
		default:
2210
			unk_ev = 1;
2211
		}
2212
		if (unk_ev) {
2213
			printk(TPACPI_NOTICE
2214
			       "unhandled HKEY event 0x%04x\n", hkey);
2215
		}
1317
2216
1318
	if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
2217
		if (!ignore_acpi_ev &&
1319
		return -EIO;
2218
		    (send_acpi_ev || hotkey_report_mode < 2)) {
1320
	if (radio_on)
2219
			acpi_bus_generate_event(ibm->acpi->device, event, hkey);
1321
		status |= TP_ACPI_WANCARD_RADIOSSW;
2220
		}
1322
	else
2221
	}
1323
		status &= ~TP_ACPI_WANCARD_RADIOSSW;
2222
}
1324
	if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
1325
		return -EIO;
1326
2223
1327
	return 0;
2224
static void hotkey_suspend(pm_message_t state)
2225
{
2226
	/* Do these on suspend, we get the events on early resume! */
2227
	hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE;
2228
	hotkey_autosleep_ack = 0;
2229
}
2230
2231
static void hotkey_resume(void)
2232
{
2233
	if (hotkey_mask_get())
2234
		printk(TPACPI_ERR
2235
		       "error while trying to read hot key mask "
2236
		       "from firmware\n");
2237
	tpacpi_input_send_radiosw();
2238
	hotkey_radio_sw_notify_change();
2239
	hotkey_wakeup_reason_notify_change();
2240
	hotkey_wakeup_hotunplug_complete_notify_change();
2241
#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2242
	hotkey_poll_setup_safe(0);
2243
#endif
1328
}
2244
}
1329
2245
1330
/* procfs -------------------------------------------------------------- */
2246
/* procfs -------------------------------------------------------------- */
1331
static int wan_read(char *p)
2247
static int hotkey_read(char *p)
1332
{
2248
{
2249
	int res, status;
1333
	int len = 0;
2250
	int len = 0;
1334
	int status = wan_get_radiosw();
1335
2251
1336
	if (!tp_features.wan)
2252
	if (!tp_features.hotkey) {
1337
		len += sprintf(p + len, "status:\t\tnot supported\n");
2253
		len += sprintf(p + len, "status:\t\tnot supported\n");
1338
	else {
2254
		return len;
1339
		len += sprintf(p + len, "status:\t\t%s\n",
2255
	}
1340
				(status)? "enabled" : "disabled");
2256
1341
		len += sprintf(p + len, "commands:\tenable, disable\n");
2257
	if (mutex_lock_interruptible(&hotkey_mutex))
2258
		return -ERESTARTSYS;
2259
	res = hotkey_status_get(&status);
2260
	if (!res)
2261
		res = hotkey_mask_get();
2262
	mutex_unlock(&hotkey_mutex);
2263
	if (res)
2264
		return res;
2265
2266
	len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
2267
	if (tp_features.hotkey_mask) {
2268
		len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask);
2269
		len += sprintf(p + len,
2270
			       "commands:\tenable, disable, reset, <mask>\n");
2271
	} else {
2272
		len += sprintf(p + len, "mask:\t\tnot supported\n");
2273
		len += sprintf(p + len, "commands:\tenable, disable, reset\n");
1342
	}
2274
	}
1343
2275
1344
	return len;
2276
	return len;
1345
}
2277
}
1346
2278
1347
static int wan_write(char *buf)
2279
static int hotkey_write(char *buf)
1348
{
2280
{
2281
	int res, status;
2282
	u32 mask;
1349
	char *cmd;
2283
	char *cmd;
1350
2284
1351
	if (!tp_features.wan)
2285
	if (!tp_features.hotkey)
1352
		return -ENODEV;
2286
		return -ENODEV;
1353
2287
2288
	if (mutex_lock_interruptible(&hotkey_mutex))
2289
		return -ERESTARTSYS;
2290
2291
	status = -1;
2292
	mask = hotkey_mask;
2293
2294
	res = 0;
1354
	while ((cmd = next_cmd(&buf))) {
2295
	while ((cmd = next_cmd(&buf))) {
1355
		if (strlencmp(cmd, "enable") == 0) {
2296
		if (strlencmp(cmd, "enable") == 0) {
1356
			wan_set_radiosw(1);
2297
			status = 1;
1357
		} else if (strlencmp(cmd, "disable") == 0) {
2298
		} else if (strlencmp(cmd, "disable") == 0) {
1358
			wan_set_radiosw(0);
2299
			status = 0;
1359
		} else
2300
		} else if (strlencmp(cmd, "reset") == 0) {
1360
			return -EINVAL;
2301
			status = hotkey_orig_status;
2302
			mask = hotkey_orig_mask;
2303
		} else if (sscanf(cmd, "0x%x", &mask) == 1) {
2304
			/* mask set */
2305
		} else if (sscanf(cmd, "%x", &mask) == 1) {
2306
			/* mask set */
2307
		} else {
2308
			res = -EINVAL;
2309
			goto errexit;
2310
		}
1361
	}
2311
	}
2312
	if (status != -1)
2313
		res = hotkey_status_set(status);
1362
2314
1363
	return 0;
2315
	if (!res && mask != hotkey_mask)
2316
		res = hotkey_mask_set(mask);
2317
2318
errexit:
2319
	mutex_unlock(&hotkey_mutex);
2320
	return res;
1364
}
2321
}
1365
2322
1366
static struct ibm_struct wan_driver_data = {
2323
static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
1367
	.name = "wan",
2324
	.hid = TPACPI_ACPI_HKEY_HID,
1368
	.read = wan_read,
2325
	.notify = hotkey_notify,
1369
	.write = wan_write,
2326
	.handle = &hkey_handle,
1370
	.exit = wan_exit,
2327
	.type = ACPI_DEVICE_NOTIFY,
1371
	.flags.experimental = 1,
2328
};
2329
2330
static struct ibm_struct hotkey_driver_data = {
2331
	.name = "hotkey",
2332
	.read = hotkey_read,
2333
	.write = hotkey_write,
2334
	.exit = hotkey_exit,
2335
	.resume = hotkey_resume,
2336
	.suspend = hotkey_suspend,
2337
	.acpi = &ibm_hotkey_acpidriver,
1372
};
2338
};
1373
2339
1374
/*************************************************************************
2340
/*************************************************************************
1375
 * Video subdriver
2341
 * Bluetooth subdriver
1376
 */
2342
 */
1377
2343
1378
static enum video_access_mode video_supported;
2344
enum {
1379
static int video_orig_autosw;
2345
	/* ACPI GBDC/SBDC bits */
1380
2346
	TP_ACPI_BLUETOOTH_HWPRESENT	= 0x01,	/* Bluetooth hw available */
1381
IBM_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA",	/* 570 */
2347
	TP_ACPI_BLUETOOTH_RADIOSSW	= 0x02,	/* Bluetooth radio enabled */
1382
	   "\\_SB.PCI0.AGP0.VID0",	/* 600e/x, 770x */
2348
	TP_ACPI_BLUETOOTH_UNK		= 0x04,	/* unknown function */
1383
	   "\\_SB.PCI0.VID0",	/* 770e */
2349
};
1384
	   "\\_SB.PCI0.VID",	/* A21e, G4x, R50e, X30, X40 */
1385
	   "\\_SB.PCI0.AGP.VID",	/* all others */
1386
	   );				/* R30, R31 */
1387
2350
1388
IBM_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID");	/* G41 */
2351
static int bluetooth_get_radiosw(void);
2352
static int bluetooth_set_radiosw(int radio_on);
1389
2353
1390
static int __init video_init(struct ibm_init_struct *iibm)
2354
/* sysfs bluetooth enable ---------------------------------------------- */
2355
static ssize_t bluetooth_enable_show(struct device *dev,
2356
			   struct device_attribute *attr,
2357
			   char *buf)
1391
{
2358
{
1392
	int ivga;
2359
	int status;
1393
1394
	vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");
1395
2360
1396
	IBM_ACPIHANDLE_INIT(vid);
2361
	status = bluetooth_get_radiosw();
1397
	IBM_ACPIHANDLE_INIT(vid2);
2362
	if (status < 0)
2363
		return status;
1398
2364
1399
	if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
2365
	return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0);
1400
		/* G41, assume IVGA doesn't change */
2366
}
1401
		vid_handle = vid2_handle;
1402
2367
1403
	if (!vid_handle)
2368
static ssize_t bluetooth_enable_store(struct device *dev,
1404
		/* video switching not supported on R30, R31 */
2369
			    struct device_attribute *attr,
1405
		video_supported = TPACPI_VIDEO_NONE;
2370
			    const char *buf, size_t count)
1406
	else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
2371
{
1407
		/* 570 */
2372
	unsigned long t;
1408
		video_supported = TPACPI_VIDEO_570;
2373
	int res;
1409
	else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
1410
		/* 600e/x, 770e, 770x */
1411
		video_supported = TPACPI_VIDEO_770;
1412
	else
1413
		/* all others */
1414
		video_supported = TPACPI_VIDEO_NEW;
1415
2374
1416
	vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n",
2375
	if (parse_strtoul(buf, 1, &t))
1417
		str_supported(video_supported != TPACPI_VIDEO_NONE),
2376
		return -EINVAL;
1418
		video_supported);
1419
2377
1420
	return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1;
2378
	res = bluetooth_set_radiosw(t);
1421
}
1422
2379
1423
static void video_exit(void)
2380
	return (res) ? res : count;
1424
{
1425
	dbg_printk(TPACPI_DBG_EXIT,
1426
		   "restoring original video autoswitch mode\n");
1427
	if (video_autosw_set(video_orig_autosw))
1428
		printk(IBM_ERR "error while trying to restore original "
1429
			"video autoswitch mode\n");
1430
}
2381
}
1431
2382
1432
static int video_outputsw_get(void)
2383
static struct device_attribute dev_attr_bluetooth_enable =
1433
{
2384
	__ATTR(bluetooth_enable, S_IWUSR | S_IRUGO,
1434
	int status = 0;
2385
		bluetooth_enable_show, bluetooth_enable_store);
1435
	int i;
1436
2386
1437
	switch (video_supported) {
2387
/* --------------------------------------------------------------------- */
1438
	case TPACPI_VIDEO_570:
1439
		if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd",
1440
				 TP_ACPI_VIDEO_570_PHSCMD))
1441
			return -EIO;
1442
		status = i & TP_ACPI_VIDEO_570_PHSMASK;
1443
		break;
1444
	case TPACPI_VIDEO_770:
1445
		if (!acpi_evalf(NULL, &i, "\\VCDL", "d"))
1446
			return -EIO;
1447
		if (i)
1448
			status |= TP_ACPI_VIDEO_S_LCD;
1449
		if (!acpi_evalf(NULL, &i, "\\VCDC", "d"))
1450
			return -EIO;
1451
		if (i)
1452
			status |= TP_ACPI_VIDEO_S_CRT;
1453
		break;
1454
	case TPACPI_VIDEO_NEW:
1455
		if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) ||
1456
		    !acpi_evalf(NULL, &i, "\\VCDC", "d"))
1457
			return -EIO;
1458
		if (i)
1459
			status |= TP_ACPI_VIDEO_S_CRT;
1460
2388
1461
		if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) ||
2389
static struct attribute *bluetooth_attributes[] = {
1462
		    !acpi_evalf(NULL, &i, "\\VCDL", "d"))
2390
	&dev_attr_bluetooth_enable.attr,
1463
			return -EIO;
2391
	NULL
1464
		if (i)
2392
};
1465
			status |= TP_ACPI_VIDEO_S_LCD;
1466
		if (!acpi_evalf(NULL, &i, "\\VCDD", "d"))
1467
			return -EIO;
1468
		if (i)
1469
			status |= TP_ACPI_VIDEO_S_DVI;
1470
		break;
1471
	default:
1472
		return -ENOSYS;
1473
	}
1474
2393
1475
	return status;
2394
static const struct attribute_group bluetooth_attr_group = {
1476
}
2395
	.attrs = bluetooth_attributes,
2396
};
1477
2397
1478
static int video_outputsw_set(int status)
2398
static int __init bluetooth_init(struct ibm_init_struct *iibm)
1479
{
2399
{
1480
	int autosw;
2400
	int res;
1481
	int res = 0;
2401
	int status = 0;
1482
2402
1483
	switch (video_supported) {
2403
	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
1484
	case TPACPI_VIDEO_570:
1485
		res = acpi_evalf(NULL, NULL,
1486
				 "\\_SB.PHS2", "vdd",
1487
				 TP_ACPI_VIDEO_570_PHS2CMD,
1488
				 status | TP_ACPI_VIDEO_570_PHS2SET);
1489
		break;
1490
	case TPACPI_VIDEO_770:
1491
		autosw = video_autosw_get();
1492
		if (autosw < 0)
1493
			return autosw;
1494
2404
1495
		res = video_autosw_set(1);
2405
	TPACPI_ACPIHANDLE_INIT(hkey);
1496
		if (res)
1497
			return res;
1498
		res = acpi_evalf(vid_handle, NULL,
1499
				 "ASWT", "vdd", status * 0x100, 0);
1500
		if (!autosw && video_autosw_set(autosw)) {
1501
			printk(IBM_ERR "video auto-switch left enabled due to error\n");
1502
			return -EIO;
1503
		}
1504
		break;
1505
	case TPACPI_VIDEO_NEW:
1506
		res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&
1507
			acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);
1508
		break;
1509
	default:
1510
		return -ENOSYS;
1511
	}
1512
2406
1513
	return (res)? 0 : -EIO;
2407
	/* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
1514
}
2408
	   G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
2409
	tp_features.bluetooth = hkey_handle &&
2410
	    acpi_evalf(hkey_handle, &status, "GBDC", "qd");
1515
2411
1516
static int video_autosw_get(void)
2412
	vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
1517
{
2413
		str_supported(tp_features.bluetooth),
1518
	int autosw = 0;
2414
		status);
1519
2415
1520
	switch (video_supported) {
2416
	if (tp_features.bluetooth) {
1521
	case TPACPI_VIDEO_570:
2417
		if (!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
1522
		if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d"))
2418
			/* no bluetooth hardware present in system */
1523
			return -EIO;
2419
			tp_features.bluetooth = 0;
1524
		break;
2420
			dbg_printk(TPACPI_DBG_INIT,
1525
	case TPACPI_VIDEO_770:
2421
				   "bluetooth hardware not installed\n");
1526
	case TPACPI_VIDEO_NEW:
2422
		} else {
1527
		if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d"))
2423
			res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
1528
			return -EIO;
2424
					&bluetooth_attr_group);
1529
		break;
2425
			if (res)
1530
	default:
2426
				return res;
1531
		return -ENOSYS;
2427
		}
1532
	}
2428
	}
1533
2429
1534
	return autosw & 1;
2430
	return (tp_features.bluetooth)? 0 : 1;
1535
}
2431
}
1536
2432
1537
static int video_autosw_set(int enable)
2433
static void bluetooth_exit(void)
1538
{
2434
{
1539
	if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0))
2435
	sysfs_remove_group(&tpacpi_pdev->dev.kobj,
1540
		return -EIO;
2436
			&bluetooth_attr_group);
1541
	return 0;
1542
}
2437
}
1543
2438
1544
static int video_outputsw_cycle(void)
2439
static int bluetooth_get_radiosw(void)
1545
{
2440
{
1546
	int autosw = video_autosw_get();
2441
	int status;
1547
	int res;
1548
2442
1549
	if (autosw < 0)
2443
	if (!tp_features.bluetooth)
1550
		return autosw;
2444
		return -ENODEV;
1551
2445
1552
	switch (video_supported) {
2446
	if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
1553
	case TPACPI_VIDEO_570:
1554
		res = video_autosw_set(1);
1555
		if (res)
1556
			return res;
1557
		res = acpi_evalf(ec_handle, NULL, "_Q16", "v");
1558
		break;
1559
	case TPACPI_VIDEO_770:
1560
	case TPACPI_VIDEO_NEW:
1561
		res = video_autosw_set(1);
1562
		if (res)
1563
			return res;
1564
		res = acpi_evalf(vid_handle, NULL, "VSWT", "v");
1565
		break;
1566
	default:
1567
		return -ENOSYS;
1568
	}
1569
	if (!autosw && video_autosw_set(autosw)) {
1570
		printk(IBM_ERR "video auto-switch left enabled due to error\n");
1571
		return -EIO;
2447
		return -EIO;
1572
	}
1573
2448
1574
	return (res)? 0 : -EIO;
2449
	return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0);
1575
}
2450
}
1576
2451
1577
static int video_expand_toggle(void)
2452
static int bluetooth_set_radiosw(int radio_on)
1578
{
2453
{
1579
	switch (video_supported) {
2454
	int status;
1580
	case TPACPI_VIDEO_570:
2455
1581
		return acpi_evalf(ec_handle, NULL, "_Q17", "v")?
2456
	if (!tp_features.bluetooth)
1582
			0 : -EIO;
2457
		return -ENODEV;
1583
	case TPACPI_VIDEO_770:
2458
1584
		return acpi_evalf(vid_handle, NULL, "VEXP", "v")?
2459
	if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
1585
			0 : -EIO;
2460
		return -EIO;
1586
	case TPACPI_VIDEO_NEW:
2461
	if (radio_on)
1587
		return acpi_evalf(NULL, NULL, "\\VEXP", "v")?
2462
		status |= TP_ACPI_BLUETOOTH_RADIOSSW;
1588
			0 : -EIO;
2463
	else
1589
	default:
2464
		status &= ~TP_ACPI_BLUETOOTH_RADIOSSW;
1590
		return -ENOSYS;
2465
	if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
1591
	}
2466
		return -EIO;
1592
	/* not reached */
2467
2468
	return 0;
1593
}
2469
}
1594
2470
1595
static int video_read(char *p)
2471
/* procfs -------------------------------------------------------------- */
2472
static int bluetooth_read(char *p)
1596
{
2473
{
1597
	int status, autosw;
1598
	int len = 0;
2474
	int len = 0;
2475
	int status = bluetooth_get_radiosw();
1599
2476
1600
	if (video_supported == TPACPI_VIDEO_NONE) {
2477
	if (!tp_features.bluetooth)
1601
		len += sprintf(p + len, "status:\t\tnot supported\n");
2478
		len += sprintf(p + len, "status:\t\tnot supported\n");
1602
		return len;
2479
	else {
2480
		len += sprintf(p + len, "status:\t\t%s\n",
2481
				(status)? "enabled" : "disabled");
2482
		len += sprintf(p + len, "commands:\tenable, disable\n");
1603
	}
2483
	}
1604
2484
1605
	status = video_outputsw_get();
2485
	return len;
1606
	if (status < 0)
2486
}
1607
		return status;
1608
2487
1609
	autosw = video_autosw_get();
2488
static int bluetooth_write(char *buf)
1610
	if (autosw < 0)
2489
{
1611
		return autosw;
2490
	char *cmd;
1612
2491
1613
	len += sprintf(p + len, "status:\t\tsupported\n");
2492
	if (!tp_features.bluetooth)
1614
	len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
1615
	len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
1616
	if (video_supported == TPACPI_VIDEO_NEW)
1617
		len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
1618
	len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
1619
	len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
1620
	len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
1621
	if (video_supported == TPACPI_VIDEO_NEW)
1622
		len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
1623
	len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
1624
	len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
1625
1626
	return len;
1627
}
1628
1629
static int video_write(char *buf)
1630
{
1631
	char *cmd;
1632
	int enable, disable, status;
1633
	int res;
1634
1635
	if (video_supported == TPACPI_VIDEO_NONE)
1636
		return -ENODEV;
2493
		return -ENODEV;
1637
2494
1638
	enable = 0;
1639
	disable = 0;
1640
1641
	while ((cmd = next_cmd(&buf))) {
2495
	while ((cmd = next_cmd(&buf))) {
1642
		if (strlencmp(cmd, "lcd_enable") == 0) {
2496
		if (strlencmp(cmd, "enable") == 0) {
1643
			enable |= TP_ACPI_VIDEO_S_LCD;
2497
			bluetooth_set_radiosw(1);
1644
		} else if (strlencmp(cmd, "lcd_disable") == 0) {
2498
		} else if (strlencmp(cmd, "disable") == 0) {
1645
			disable |= TP_ACPI_VIDEO_S_LCD;
2499
			bluetooth_set_radiosw(0);
1646
		} else if (strlencmp(cmd, "crt_enable") == 0) {
1647
			enable |= TP_ACPI_VIDEO_S_CRT;
1648
		} else if (strlencmp(cmd, "crt_disable") == 0) {
1649
			disable |= TP_ACPI_VIDEO_S_CRT;
1650
		} else if (video_supported == TPACPI_VIDEO_NEW &&
1651
			   strlencmp(cmd, "dvi_enable") == 0) {
1652
			enable |= TP_ACPI_VIDEO_S_DVI;
1653
		} else if (video_supported == TPACPI_VIDEO_NEW &&
1654
			   strlencmp(cmd, "dvi_disable") == 0) {
1655
			disable |= TP_ACPI_VIDEO_S_DVI;
1656
		} else if (strlencmp(cmd, "auto_enable") == 0) {
1657
			res = video_autosw_set(1);
1658
			if (res)
1659
				return res;
1660
		} else if (strlencmp(cmd, "auto_disable") == 0) {
1661
			res = video_autosw_set(0);
1662
			if (res)
1663
				return res;
1664
		} else if (strlencmp(cmd, "video_switch") == 0) {
1665
			res = video_outputsw_cycle();
1666
			if (res)
1667
				return res;
1668
		} else if (strlencmp(cmd, "expand_toggle") == 0) {
1669
			res = video_expand_toggle();
1670
			if (res)
1671
				return res;
1672
		} else
2500
		} else
1673
			return -EINVAL;
2501
			return -EINVAL;
1674
	}
2502
	}
1675
2503
1676
	if (enable || disable) {
1677
		status = video_outputsw_get();
1678
		if (status < 0)
1679
			return status;
1680
		res = video_outputsw_set((status & ~disable) | enable);
1681
		if (res)
1682
			return res;
1683
	}
1684
1685
	return 0;
2504
	return 0;
1686
}
2505
}
1687
2506
1688
static struct ibm_struct video_driver_data = {
2507
static struct ibm_struct bluetooth_driver_data = {
1689
	.name = "video",
2508
	.name = "bluetooth",
1690
	.read = video_read,
2509
	.read = bluetooth_read,
1691
	.write = video_write,
2510
	.write = bluetooth_write,
1692
	.exit = video_exit,
2511
	.exit = bluetooth_exit,
1693
};
2512
};
1694
2513
1695
/*************************************************************************
2514
/*************************************************************************
1696
 * Light (thinklight) subdriver
2515
 * Wan subdriver
1697
 */
2516
 */
1698
2517
1699
IBM_HANDLE(lght, root, "\\LGHT");	/* A21e, A2xm/p, T20-22, X20-21 */
2518
enum {
1700
IBM_HANDLE(ledb, ec, "LEDB");		/* G4x */
2519
	/* ACPI GWAN/SWAN bits */
2520
	TP_ACPI_WANCARD_HWPRESENT	= 0x01,	/* Wan hw available */
2521
	TP_ACPI_WANCARD_RADIOSSW	= 0x02,	/* Wan radio enabled */
2522
	TP_ACPI_WANCARD_UNK		= 0x04,	/* unknown function */
2523
};
1701
2524
1702
static int __init light_init(struct ibm_init_struct *iibm)
2525
static int wan_get_radiosw(void);
2526
static int wan_set_radiosw(int radio_on);
2527
2528
/* sysfs wan enable ---------------------------------------------------- */
2529
static ssize_t wan_enable_show(struct device *dev,
2530
			   struct device_attribute *attr,
2531
			   char *buf)
1703
{
2532
{
1704
	vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
2533
	int status;
1705
2534
1706
	IBM_ACPIHANDLE_INIT(ledb);
2535
	status = wan_get_radiosw();
1707
	IBM_ACPIHANDLE_INIT(lght);
2536
	if (status < 0)
1708
	IBM_ACPIHANDLE_INIT(cmos);
2537
		return status;
1709
2538
1710
	/* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
2539
	return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0);
1711
	tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
2540
}
1712
2541
1713
	if (tp_features.light)
2542
static ssize_t wan_enable_store(struct device *dev,
1714
		/* light status not supported on
2543
			    struct device_attribute *attr,
1715
		   570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */
2544
			    const char *buf, size_t count)
1716
		tp_features.light_status =
2545
{
1717
			acpi_evalf(ec_handle, NULL, "KBLT", "qv");
2546
	unsigned long t;
2547
	int res;
1718
2548
1719
	vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
2549
	if (parse_strtoul(buf, 1, &t))
1720
		str_supported(tp_features.light));
2550
		return -EINVAL;
1721
2551
1722
	return (tp_features.light)? 0 : 1;
2552
	res = wan_set_radiosw(t);
2553
2554
	return (res) ? res : count;
1723
}
2555
}
1724
2556
1725
static int light_read(char *p)
2557
static struct device_attribute dev_attr_wan_enable =
2558
	__ATTR(wwan_enable, S_IWUSR | S_IRUGO,
2559
		wan_enable_show, wan_enable_store);
2560
2561
/* --------------------------------------------------------------------- */
2562
2563
static struct attribute *wan_attributes[] = {
2564
	&dev_attr_wan_enable.attr,
2565
	NULL
2566
};
2567
2568
static const struct attribute_group wan_attr_group = {
2569
	.attrs = wan_attributes,
2570
};
2571
2572
static int __init wan_init(struct ibm_init_struct *iibm)
1726
{
2573
{
1727
	int len = 0;
2574
	int res;
1728
	int status = 0;
2575
	int status = 0;
1729
2576
1730
	if (!tp_features.light) {
2577
	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
2578
2579
	TPACPI_ACPIHANDLE_INIT(hkey);
2580
2581
	tp_features.wan = hkey_handle &&
2582
	    acpi_evalf(hkey_handle, &status, "GWAN", "qd");
2583
2584
	vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
2585
		str_supported(tp_features.wan),
2586
		status);
2587
2588
	if (tp_features.wan) {
2589
		if (!(status & TP_ACPI_WANCARD_HWPRESENT)) {
2590
			/* no wan hardware present in system */
2591
			tp_features.wan = 0;
2592
			dbg_printk(TPACPI_DBG_INIT,
2593
				   "wan hardware not installed\n");
2594
		} else {
2595
			res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
2596
					&wan_attr_group);
2597
			if (res)
2598
				return res;
2599
		}
2600
	}
2601
2602
	return (tp_features.wan)? 0 : 1;
2603
}
2604
2605
static void wan_exit(void)
2606
{
2607
	sysfs_remove_group(&tpacpi_pdev->dev.kobj,
2608
		&wan_attr_group);
2609
}
2610
2611
static int wan_get_radiosw(void)
2612
{
2613
	int status;
2614
2615
	if (!tp_features.wan)
2616
		return -ENODEV;
2617
2618
	if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
2619
		return -EIO;
2620
2621
	return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0);
2622
}
2623
2624
static int wan_set_radiosw(int radio_on)
2625
{
2626
	int status;
2627
2628
	if (!tp_features.wan)
2629
		return -ENODEV;
2630
2631
	if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
2632
		return -EIO;
2633
	if (radio_on)
2634
		status |= TP_ACPI_WANCARD_RADIOSSW;
2635
	else
2636
		status &= ~TP_ACPI_WANCARD_RADIOSSW;
2637
	if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
2638
		return -EIO;
2639
2640
	return 0;
2641
}
2642
2643
/* procfs -------------------------------------------------------------- */
2644
static int wan_read(char *p)
2645
{
2646
	int len = 0;
2647
	int status = wan_get_radiosw();
2648
2649
	if (!tp_features.wan)
1731
		len += sprintf(p + len, "status:\t\tnot supported\n");
2650
		len += sprintf(p + len, "status:\t\tnot supported\n");
1732
	} else if (!tp_features.light_status) {
2651
	else {
1733
		len += sprintf(p + len, "status:\t\tunknown\n");
2652
		len += sprintf(p + len, "status:\t\t%s\n",
1734
		len += sprintf(p + len, "commands:\ton, off\n");
2653
				(status)? "enabled" : "disabled");
1735
	} else {
2654
		len += sprintf(p + len, "commands:\tenable, disable\n");
1736
		if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
1737
			return -EIO;
1738
		len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
1739
		len += sprintf(p + len, "commands:\ton, off\n");
1740
	}
2655
	}
1741
2656
1742
	return len;
2657
	return len;
1743
}
2658
}
1744
2659
1745
static int light_write(char *buf)
2660
static int wan_write(char *buf)
1746
{
2661
{
1747
	int cmos_cmd, lght_cmd;
1748
	char *cmd;
2662
	char *cmd;
1749
	int success;
1750
2663
1751
	if (!tp_features.light)
2664
	if (!tp_features.wan)
1752
		return -ENODEV;
2665
		return -ENODEV;
1753
2666
1754
	while ((cmd = next_cmd(&buf))) {
2667
	while ((cmd = next_cmd(&buf))) {
1755
		if (strlencmp(cmd, "on") == 0) {
2668
		if (strlencmp(cmd, "enable") == 0) {
1756
			cmos_cmd = 0x0c;
2669
			wan_set_radiosw(1);
1757
			lght_cmd = 1;
2670
		} else if (strlencmp(cmd, "disable") == 0) {
1758
		} else if (strlencmp(cmd, "off") == 0) {
2671
			wan_set_radiosw(0);
1759
			cmos_cmd = 0x0d;
1760
			lght_cmd = 0;
1761
		} else
2672
		} else
1762
			return -EINVAL;
2673
			return -EINVAL;
1763
1764
		success = cmos_handle ?
1765
		    acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) :
1766
		    acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd);
1767
		if (!success)
1768
			return -EIO;
1769
	}
2674
	}
1770
2675
1771
	return 0;
2676
	return 0;
1772
}
2677
}
1773
2678
1774
static struct ibm_struct light_driver_data = {
2679
static struct ibm_struct wan_driver_data = {
1775
	.name = "light",
2680
	.name = "wan",
1776
	.read = light_read,
2681
	.read = wan_read,
1777
	.write = light_write,
2682
	.write = wan_write,
2683
	.exit = wan_exit,
2684
	.flags.experimental = 1,
1778
};
2685
};
1779
2686
1780
/*************************************************************************
2687
/*************************************************************************
1781
 * Dock subdriver
2688
 * Video subdriver
1782
 */
2689
 */
1783
2690
1784
#ifdef CONFIG_THINKPAD_ACPI_DOCK
2691
enum video_access_mode {
1785
2692
	TPACPI_VIDEO_NONE = 0,
1786
IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
2693
	TPACPI_VIDEO_570,	/* 570 */
1787
	   "\\_SB.PCI0.DOCK",	/* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
2694
	TPACPI_VIDEO_770,	/* 600e/x, 770e, 770x */
1788
	   "\\_SB.PCI0.PCI1.DOCK",	/* all others */
2695
	TPACPI_VIDEO_NEW,	/* all others */
1789
	   "\\_SB.PCI.ISA.SLCE",	/* 570 */
2696
};
1790
    );				/* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
1791
2697
1792
/* don't list other alternatives as we install a notify handler on the 570 */
2698
enum {	/* video status flags, based on VIDEO_570 */
1793
IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
2699
	TP_ACPI_VIDEO_S_LCD = 0x01,	/* LCD output enabled */
2700
	TP_ACPI_VIDEO_S_CRT = 0x02,	/* CRT output enabled */
2701
	TP_ACPI_VIDEO_S_DVI = 0x08,	/* DVI output enabled */
2702
};
1794
2703
1795
static const struct acpi_device_id ibm_pci_device_ids[] = {
2704
enum {  /* TPACPI_VIDEO_570 constants */
1796
	{IBM_PCI_HID, 0},
2705
	TP_ACPI_VIDEO_570_PHSCMD = 0x87,	/* unknown magic constant :( */
1797
	{"", 0},
2706
	TP_ACPI_VIDEO_570_PHSMASK = 0x03,	/* PHS bits that map to
2707
						 * video_status_flags */
2708
	TP_ACPI_VIDEO_570_PHS2CMD = 0x8b,	/* unknown magic constant :( */
2709
	TP_ACPI_VIDEO_570_PHS2SET = 0x80,	/* unknown magic constant :( */
1798
};
2710
};
1799
2711
2712
static enum video_access_mode video_supported;
2713
static int video_orig_autosw;
2714
2715
static int video_autosw_get(void);
2716
static int video_autosw_set(int enable);
2717
2718
TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA",	/* 570 */
2719
	   "\\_SB.PCI0.AGP0.VID0",	/* 600e/x, 770x */
2720
	   "\\_SB.PCI0.VID0",	/* 770e */
2721
	   "\\_SB.PCI0.VID",	/* A21e, G4x, R50e, X30, X40 */
2722
	   "\\_SB.PCI0.AGP.VID",	/* all others */
2723
	   );				/* R30, R31 */
2724
2725
TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID");	/* G41 */
2726
2727
static int __init video_init(struct ibm_init_struct *iibm)
2728
{
2729
	int ivga;
2730
2731
	vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");
2732
2733
	TPACPI_ACPIHANDLE_INIT(vid);
2734
	TPACPI_ACPIHANDLE_INIT(vid2);
2735
2736
	if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
2737
		/* G41, assume IVGA doesn't change */
2738
		vid_handle = vid2_handle;
2739
2740
	if (!vid_handle)
2741
		/* video switching not supported on R30, R31 */
2742
		video_supported = TPACPI_VIDEO_NONE;
2743
	else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
2744
		/* 570 */
2745
		video_supported = TPACPI_VIDEO_570;
2746
	else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
2747
		/* 600e/x, 770e, 770x */
2748
		video_supported = TPACPI_VIDEO_770;
2749
	else
2750
		/* all others */
2751
		video_supported = TPACPI_VIDEO_NEW;
2752
2753
	vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n",
2754
		str_supported(video_supported != TPACPI_VIDEO_NONE),
2755
		video_supported);
2756
2757
	return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1;
2758
}
2759
2760
static void video_exit(void)
2761
{
2762
	dbg_printk(TPACPI_DBG_EXIT,
2763
		   "restoring original video autoswitch mode\n");
2764
	if (video_autosw_set(video_orig_autosw))
2765
		printk(TPACPI_ERR "error while trying to restore original "
2766
			"video autoswitch mode\n");
2767
}
2768
2769
static int video_outputsw_get(void)
2770
{
2771
	int status = 0;
2772
	int i;
2773
2774
	switch (video_supported) {
2775
	case TPACPI_VIDEO_570:
2776
		if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd",
2777
				 TP_ACPI_VIDEO_570_PHSCMD))
2778
			return -EIO;
2779
		status = i & TP_ACPI_VIDEO_570_PHSMASK;
2780
		break;
2781
	case TPACPI_VIDEO_770:
2782
		if (!acpi_evalf(NULL, &i, "\\VCDL", "d"))
2783
			return -EIO;
2784
		if (i)
2785
			status |= TP_ACPI_VIDEO_S_LCD;
2786
		if (!acpi_evalf(NULL, &i, "\\VCDC", "d"))
2787
			return -EIO;
2788
		if (i)
2789
			status |= TP_ACPI_VIDEO_S_CRT;
2790
		break;
2791
	case TPACPI_VIDEO_NEW:
2792
		if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) ||
2793
		    !acpi_evalf(NULL, &i, "\\VCDC", "d"))
2794
			return -EIO;
2795
		if (i)
2796
			status |= TP_ACPI_VIDEO_S_CRT;
2797
2798
		if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) ||
2799
		    !acpi_evalf(NULL, &i, "\\VCDL", "d"))
2800
			return -EIO;
2801
		if (i)
2802
			status |= TP_ACPI_VIDEO_S_LCD;
2803
		if (!acpi_evalf(NULL, &i, "\\VCDD", "d"))
2804
			return -EIO;
2805
		if (i)
2806
			status |= TP_ACPI_VIDEO_S_DVI;
2807
		break;
2808
	default:
2809
		return -ENOSYS;
2810
	}
2811
2812
	return status;
2813
}
2814
2815
static int video_outputsw_set(int status)
2816
{
2817
	int autosw;
2818
	int res = 0;
2819
2820
	switch (video_supported) {
2821
	case TPACPI_VIDEO_570:
2822
		res = acpi_evalf(NULL, NULL,
2823
				 "\\_SB.PHS2", "vdd",
2824
				 TP_ACPI_VIDEO_570_PHS2CMD,
2825
				 status | TP_ACPI_VIDEO_570_PHS2SET);
2826
		break;
2827
	case TPACPI_VIDEO_770:
2828
		autosw = video_autosw_get();
2829
		if (autosw < 0)
2830
			return autosw;
2831
2832
		res = video_autosw_set(1);
2833
		if (res)
2834
			return res;
2835
		res = acpi_evalf(vid_handle, NULL,
2836
				 "ASWT", "vdd", status * 0x100, 0);
2837
		if (!autosw && video_autosw_set(autosw)) {
2838
			printk(TPACPI_ERR
2839
			       "video auto-switch left enabled due to error\n");
2840
			return -EIO;
2841
		}
2842
		break;
2843
	case TPACPI_VIDEO_NEW:
2844
		res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&
2845
		      acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);
2846
		break;
2847
	default:
2848
		return -ENOSYS;
2849
	}
2850
2851
	return (res)? 0 : -EIO;
2852
}
2853
2854
static int video_autosw_get(void)
2855
{
2856
	int autosw = 0;
2857
2858
	switch (video_supported) {
2859
	case TPACPI_VIDEO_570:
2860
		if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d"))
2861
			return -EIO;
2862
		break;
2863
	case TPACPI_VIDEO_770:
2864
	case TPACPI_VIDEO_NEW:
2865
		if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d"))
2866
			return -EIO;
2867
		break;
2868
	default:
2869
		return -ENOSYS;
2870
	}
2871
2872
	return autosw & 1;
2873
}
2874
2875
static int video_autosw_set(int enable)
2876
{
2877
	if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0))
2878
		return -EIO;
2879
	return 0;
2880
}
2881
2882
static int video_outputsw_cycle(void)
2883
{
2884
	int autosw = video_autosw_get();
2885
	int res;
2886
2887
	if (autosw < 0)
2888
		return autosw;
2889
2890
	switch (video_supported) {
2891
	case TPACPI_VIDEO_570:
2892
		res = video_autosw_set(1);
2893
		if (res)
2894
			return res;
2895
		res = acpi_evalf(ec_handle, NULL, "_Q16", "v");
2896
		break;
2897
	case TPACPI_VIDEO_770:
2898
	case TPACPI_VIDEO_NEW:
2899
		res = video_autosw_set(1);
2900
		if (res)
2901
			return res;
2902
		res = acpi_evalf(vid_handle, NULL, "VSWT", "v");
2903
		break;
2904
	default:
2905
		return -ENOSYS;
2906
	}
2907
	if (!autosw && video_autosw_set(autosw)) {
2908
		printk(TPACPI_ERR
2909
		       "video auto-switch left enabled due to error\n");
2910
		return -EIO;
2911
	}
2912
2913
	return (res)? 0 : -EIO;
2914
}
2915
2916
static int video_expand_toggle(void)
2917
{
2918
	switch (video_supported) {
2919
	case TPACPI_VIDEO_570:
2920
		return acpi_evalf(ec_handle, NULL, "_Q17", "v")?
2921
			0 : -EIO;
2922
	case TPACPI_VIDEO_770:
2923
		return acpi_evalf(vid_handle, NULL, "VEXP", "v")?
2924
			0 : -EIO;
2925
	case TPACPI_VIDEO_NEW:
2926
		return acpi_evalf(NULL, NULL, "\\VEXP", "v")?
2927
			0 : -EIO;
2928
	default:
2929
		return -ENOSYS;
2930
	}
2931
	/* not reached */
2932
}
2933
2934
static int video_read(char *p)
2935
{
2936
	int status, autosw;
2937
	int len = 0;
2938
2939
	if (video_supported == TPACPI_VIDEO_NONE) {
2940
		len += sprintf(p + len, "status:\t\tnot supported\n");
2941
		return len;
2942
	}
2943
2944
	status = video_outputsw_get();
2945
	if (status < 0)
2946
		return status;
2947
2948
	autosw = video_autosw_get();
2949
	if (autosw < 0)
2950
		return autosw;
2951
2952
	len += sprintf(p + len, "status:\t\tsupported\n");
2953
	len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
2954
	len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
2955
	if (video_supported == TPACPI_VIDEO_NEW)
2956
		len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
2957
	len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
2958
	len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
2959
	len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
2960
	if (video_supported == TPACPI_VIDEO_NEW)
2961
		len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
2962
	len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
2963
	len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
2964
2965
	return len;
2966
}
2967
2968
static int video_write(char *buf)
2969
{
2970
	char *cmd;
2971
	int enable, disable, status;
2972
	int res;
2973
2974
	if (video_supported == TPACPI_VIDEO_NONE)
2975
		return -ENODEV;
2976
2977
	enable = 0;
2978
	disable = 0;
2979
2980
	while ((cmd = next_cmd(&buf))) {
2981
		if (strlencmp(cmd, "lcd_enable") == 0) {
2982
			enable |= TP_ACPI_VIDEO_S_LCD;
2983
		} else if (strlencmp(cmd, "lcd_disable") == 0) {
2984
			disable |= TP_ACPI_VIDEO_S_LCD;
2985
		} else if (strlencmp(cmd, "crt_enable") == 0) {
2986
			enable |= TP_ACPI_VIDEO_S_CRT;
2987
		} else if (strlencmp(cmd, "crt_disable") == 0) {
2988
			disable |= TP_ACPI_VIDEO_S_CRT;
2989
		} else if (video_supported == TPACPI_VIDEO_NEW &&
2990
			   strlencmp(cmd, "dvi_enable") == 0) {
2991
			enable |= TP_ACPI_VIDEO_S_DVI;
2992
		} else if (video_supported == TPACPI_VIDEO_NEW &&
2993
			   strlencmp(cmd, "dvi_disable") == 0) {
2994
			disable |= TP_ACPI_VIDEO_S_DVI;
2995
		} else if (strlencmp(cmd, "auto_enable") == 0) {
2996
			res = video_autosw_set(1);
2997
			if (res)
2998
				return res;
2999
		} else if (strlencmp(cmd, "auto_disable") == 0) {
3000
			res = video_autosw_set(0);
3001
			if (res)
3002
				return res;
3003
		} else if (strlencmp(cmd, "video_switch") == 0) {
3004
			res = video_outputsw_cycle();
3005
			if (res)
3006
				return res;
3007
		} else if (strlencmp(cmd, "expand_toggle") == 0) {
3008
			res = video_expand_toggle();
3009
			if (res)
3010
				return res;
3011
		} else
3012
			return -EINVAL;
3013
	}
3014
3015
	if (enable || disable) {
3016
		status = video_outputsw_get();
3017
		if (status < 0)
3018
			return status;
3019
		res = video_outputsw_set((status & ~disable) | enable);
3020
		if (res)
3021
			return res;
3022
	}
3023
3024
	return 0;
3025
}
3026
3027
static struct ibm_struct video_driver_data = {
3028
	.name = "video",
3029
	.read = video_read,
3030
	.write = video_write,
3031
	.exit = video_exit,
3032
};
3033
3034
/*************************************************************************
3035
 * Light (thinklight) subdriver
3036
 */
3037
3038
TPACPI_HANDLE(lght, root, "\\LGHT");	/* A21e, A2xm/p, T20-22, X20-21 */
3039
TPACPI_HANDLE(ledb, ec, "LEDB");		/* G4x */
3040
3041
static int __init light_init(struct ibm_init_struct *iibm)
3042
{
3043
	vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
3044
3045
	TPACPI_ACPIHANDLE_INIT(ledb);
3046
	TPACPI_ACPIHANDLE_INIT(lght);
3047
	TPACPI_ACPIHANDLE_INIT(cmos);
3048
3049
	/* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
3050
	tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
3051
3052
	if (tp_features.light)
3053
		/* light status not supported on
3054
		   570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */
3055
		tp_features.light_status =
3056
			acpi_evalf(ec_handle, NULL, "KBLT", "qv");
3057
3058
	vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
3059
		str_supported(tp_features.light));
3060
3061
	return (tp_features.light)? 0 : 1;
3062
}
3063
3064
static int light_read(char *p)
3065
{
3066
	int len = 0;
3067
	int status = 0;
3068
3069
	if (!tp_features.light) {
3070
		len += sprintf(p + len, "status:\t\tnot supported\n");
3071
	} else if (!tp_features.light_status) {
3072
		len += sprintf(p + len, "status:\t\tunknown\n");
3073
		len += sprintf(p + len, "commands:\ton, off\n");
3074
	} else {
3075
		if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
3076
			return -EIO;
3077
		len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
3078
		len += sprintf(p + len, "commands:\ton, off\n");
3079
	}
3080
3081
	return len;
3082
}
3083
3084
static int light_write(char *buf)
3085
{
3086
	int cmos_cmd, lght_cmd;
3087
	char *cmd;
3088
	int success;
3089
3090
	if (!tp_features.light)
3091
		return -ENODEV;
3092
3093
	while ((cmd = next_cmd(&buf))) {
3094
		if (strlencmp(cmd, "on") == 0) {
3095
			cmos_cmd = 0x0c;
3096
			lght_cmd = 1;
3097
		} else if (strlencmp(cmd, "off") == 0) {
3098
			cmos_cmd = 0x0d;
3099
			lght_cmd = 0;
3100
		} else
3101
			return -EINVAL;
3102
3103
		success = cmos_handle ?
3104
		    acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) :
3105
		    acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd);
3106
		if (!success)
3107
			return -EIO;
3108
	}
3109
3110
	return 0;
3111
}
3112
3113
static struct ibm_struct light_driver_data = {
3114
	.name = "light",
3115
	.read = light_read,
3116
	.write = light_write,
3117
};
3118
3119
/*************************************************************************
3120
 * Dock subdriver
3121
 */
3122
3123
#ifdef CONFIG_THINKPAD_ACPI_DOCK
3124
3125
static void dock_notify(struct ibm_struct *ibm, u32 event);
3126
static int dock_read(char *p);
3127
static int dock_write(char *buf);
3128
3129
TPACPI_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
3130
	   "\\_SB.PCI0.DOCK",	/* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
3131
	   "\\_SB.PCI0.PCI1.DOCK",	/* all others */
3132
	   "\\_SB.PCI.ISA.SLCE",	/* 570 */
3133
    );				/* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
3134
3135
/* don't list other alternatives as we install a notify handler on the 570 */
3136
TPACPI_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
3137
1800
static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
3138
static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
1801
	{
3139
	{
1802
	 .notify = dock_notify,
3140
	 .notify = dock_notify,
Lines 1804-1810 static struct tp_acpi_drv_struct ibm_doc Link Here
1804
	 .type = ACPI_SYSTEM_NOTIFY,
3142
	 .type = ACPI_SYSTEM_NOTIFY,
1805
	},
3143
	},
1806
	{
3144
	{
1807
	 .hid = ibm_pci_device_ids,
3145
	/* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING.
3146
	 * We just use it to get notifications of dock hotplug
3147
	 * in very old thinkpads */
3148
	 .hid = PCI_ROOT_HID_STRING,
1808
	 .notify = dock_notify,
3149
	 .notify = dock_notify,
1809
	 .handle = &pci_handle,
3150
	 .handle = &pci_handle,
1810
	 .type = ACPI_SYSTEM_NOTIFY,
3151
	 .type = ACPI_SYSTEM_NOTIFY,
Lines 1830-1836 static int __init dock_init(struct ibm_i Link Here
1830
{
3171
{
1831
	vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
3172
	vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
1832
3173
1833
	IBM_ACPIHANDLE_INIT(dock);
3174
	TPACPI_ACPIHANDLE_INIT(dock);
1834
3175
1835
	vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n",
3176
	vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n",
1836
		str_supported(dock_handle != NULL));
3177
		str_supported(dock_handle != NULL));
Lines 1846-1852 static int __init dock_init2(struct ibm_ Link Here
1846
3187
1847
	if (dock_driver_data[0].flags.acpi_driver_registered &&
3188
	if (dock_driver_data[0].flags.acpi_driver_registered &&
1848
	    dock_driver_data[0].flags.acpi_notify_installed) {
3189
	    dock_driver_data[0].flags.acpi_notify_installed) {
1849
		IBM_ACPIHANDLE_INIT(pci);
3190
		TPACPI_ACPIHANDLE_INIT(pci);
1850
		dock2_needed = (pci_handle != NULL);
3191
		dock2_needed = (pci_handle != NULL);
1851
		vdbg_printk(TPACPI_DBG_INIT,
3192
		vdbg_printk(TPACPI_DBG_INIT,
1852
			    "dock PCI handler for the TP 570 is %s\n",
3193
			    "dock PCI handler for the TP 570 is %s\n",
Lines 1863-1870 static int __init dock_init2(struct ibm_ Link Here
1863
static void dock_notify(struct ibm_struct *ibm, u32 event)
3204
static void dock_notify(struct ibm_struct *ibm, u32 event)
1864
{
3205
{
1865
	int docked = dock_docked();
3206
	int docked = dock_docked();
1866
	int pci = ibm->acpi->hid && ibm->acpi->device &&
3207
	int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, PCI_ROOT_HID_STRING);
1867
		acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids);
1868
3208
1869
	if (event == 1 && !pci)	/* 570 */
3209
	if (event == 1 && !pci)	/* 570 */
1870
		acpi_bus_generate_event(ibm->acpi->device, event, 1);	/* button */
3210
		acpi_bus_generate_event(ibm->acpi->device, event, 1);	/* button */
Lines 1877-1883 static void dock_notify(struct ibm_struc Link Here
1877
	else if (event == 0 && docked)
3217
	else if (event == 0 && docked)
1878
		acpi_bus_generate_event(ibm->acpi->device, event, 3);	/* dock */
3218
		acpi_bus_generate_event(ibm->acpi->device, event, 3);	/* dock */
1879
	else {
3219
	else {
1880
		printk(IBM_ERR "unknown dock event %d, status %d\n",
3220
		printk(TPACPI_ERR "unknown dock event %d, status %d\n",
1881
		       event, _sta(dock_handle));
3221
		       event, _sta(dock_handle));
1882
		acpi_bus_generate_event(ibm->acpi->device, event, 0);	/* unknown */
3222
		acpi_bus_generate_event(ibm->acpi->device, event, 0);	/* unknown */
1883
	}
3223
	}
Lines 1929-1946 static int dock_write(char *buf) Link Here
1929
 */
3269
 */
1930
3270
1931
#ifdef CONFIG_THINKPAD_ACPI_BAY
3271
#ifdef CONFIG_THINKPAD_ACPI_BAY
1932
IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",	/* 570 */
3272
3273
TPACPI_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",	/* 570 */
1933
	   "\\_SB.PCI0.IDE0.IDES.IDSM",	/* 600e/x, 770e, 770x */
3274
	   "\\_SB.PCI0.IDE0.IDES.IDSM",	/* 600e/x, 770e, 770x */
1934
	   "\\_SB.PCI0.SATA.SCND.MSTR",	/* T60, X60, Z60 */
3275
	   "\\_SB.PCI0.SATA.SCND.MSTR",	/* T60, X60, Z60 */
1935
	   "\\_SB.PCI0.IDE0.SCND.MSTR",	/* all others */
3276
	   "\\_SB.PCI0.IDE0.SCND.MSTR",	/* all others */
1936
	   );				/* A21e, R30, R31 */
3277
	   );				/* A21e, R30, R31 */
1937
IBM_HANDLE(bay_ej, bay, "_EJ3",	/* 600e/x, A2xm/p, A3x */
3278
TPACPI_HANDLE(bay_ej, bay, "_EJ3",	/* 600e/x, A2xm/p, A3x */
1938
	   "_EJ0",		/* all others */
3279
	   "_EJ0",		/* all others */
1939
	   );			/* 570,A21e,G4x,R30,R31,R32,R40e,R50e */
3280
	   );			/* 570,A21e,G4x,R30,R31,R32,R40e,R50e */
1940
IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV",	/* A3x, R32 */
3281
TPACPI_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV",	/* A3x, R32 */
1941
	   "\\_SB.PCI0.IDE0.IDEP.IDPS",	/* 600e/x, 770e, 770x */
3282
	   "\\_SB.PCI0.IDE0.IDEP.IDPS",	/* 600e/x, 770e, 770x */
1942
	   );				/* all others */
3283
	   );				/* all others */
1943
IBM_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
3284
TPACPI_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
1944
	   "_EJ0",			/* 770x */
3285
	   "_EJ0",			/* 770x */
1945
	   );				/* all others */
3286
	   );				/* all others */
1946
3287
Lines 1948-1959 static int __init bay_init(struct ibm_in Link Here
1948
{
3289
{
1949
	vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n");
3290
	vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n");
1950
3291
1951
	IBM_ACPIHANDLE_INIT(bay);
3292
	TPACPI_ACPIHANDLE_INIT(bay);
1952
	if (bay_handle)
3293
	if (bay_handle)
1953
		IBM_ACPIHANDLE_INIT(bay_ej);
3294
		TPACPI_ACPIHANDLE_INIT(bay_ej);
1954
	IBM_ACPIHANDLE_INIT(bay2);
3295
	TPACPI_ACPIHANDLE_INIT(bay2);
1955
	if (bay2_handle)
3296
	if (bay2_handle)
1956
		IBM_ACPIHANDLE_INIT(bay2_ej);
3297
		TPACPI_ACPIHANDLE_INIT(bay2_ej);
1957
3298
1958
	tp_features.bay_status = bay_handle &&
3299
	tp_features.bay_status = bay_handle &&
1959
		acpi_evalf(bay_handle, NULL, "_STA", "qv");
3300
		acpi_evalf(bay_handle, NULL, "_STA", "qv");
Lines 2079-2085 static int __init cmos_init(struct ibm_i Link Here
2079
	vdbg_printk(TPACPI_DBG_INIT,
3420
	vdbg_printk(TPACPI_DBG_INIT,
2080
		"initializing cmos commands subdriver\n");
3421
		"initializing cmos commands subdriver\n");
2081
3422
2082
	IBM_ACPIHANDLE_INIT(cmos);
3423
	TPACPI_ACPIHANDLE_INIT(cmos);
2083
3424
2084
	vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",
3425
	vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",
2085
		str_supported(cmos_handle != NULL));
3426
		str_supported(cmos_handle != NULL));
Lines 2143-2152 static struct ibm_struct cmos_driver_dat Link Here
2143
 * LED subdriver
3484
 * LED subdriver
2144
 */
3485
 */
2145
3486
3487
enum led_access_mode {
3488
	TPACPI_LED_NONE = 0,
3489
	TPACPI_LED_570,	/* 570 */
3490
	TPACPI_LED_OLD,	/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
3491
	TPACPI_LED_NEW,	/* all others */
3492
};
3493
3494
enum {	/* For TPACPI_LED_OLD */
3495
	TPACPI_LED_EC_HLCL = 0x0c,	/* EC reg to get led to power on */
3496
	TPACPI_LED_EC_HLBL = 0x0d,	/* EC reg to blink a lit led */
3497
	TPACPI_LED_EC_HLMS = 0x0e,	/* EC reg to select led to command */
3498
};
3499
2146
static enum led_access_mode led_supported;
3500
static enum led_access_mode led_supported;
2147
3501
2148
IBM_HANDLE(led, ec, "SLED",	/* 570 */
3502
TPACPI_HANDLE(led, ec, "SLED",	/* 570 */
2149
	   "SYSL",		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
3503
	   "SYSL",		/* 600e/x, 770e, 770x, A21e, A2xm/p, */
3504
				/* T20-22, X20-21 */
2150
	   "LED",		/* all others */
3505
	   "LED",		/* all others */
2151
	   );			/* R30, R31 */
3506
	   );			/* R30, R31 */
2152
3507
Lines 2154-2160 static int __init led_init(struct ibm_in Link Here
2154
{
3509
{
2155
	vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
3510
	vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
2156
3511
2157
	IBM_ACPIHANDLE_INIT(led);
3512
	TPACPI_ACPIHANDLE_INIT(led);
2158
3513
2159
	if (!led_handle)
3514
	if (!led_handle)
2160
		/* led not supported on R30, R31 */
3515
		/* led not supported on R30, R31 */
Lines 2243-2255 static int led_write(char *buf) Link Here
2243
			led = 1 << led;
3598
			led = 1 << led;
2244
			ret = ec_write(TPACPI_LED_EC_HLMS, led);
3599
			ret = ec_write(TPACPI_LED_EC_HLMS, led);
2245
			if (ret >= 0)
3600
			if (ret >= 0)
2246
				ret =
3601
				ret = ec_write(TPACPI_LED_EC_HLBL,
2247
				    ec_write(TPACPI_LED_EC_HLBL,
3602
						led * led_exp_hlbl[ind]);
2248
				    	     led * led_exp_hlbl[ind]);
2249
			if (ret >= 0)
3603
			if (ret >= 0)
2250
				ret =
3604
				ret = ec_write(TPACPI_LED_EC_HLCL,
2251
				    ec_write(TPACPI_LED_EC_HLCL,
3605
						led * led_exp_hlcl[ind]);
2252
				    	     led * led_exp_hlcl[ind]);
2253
			if (ret < 0)
3606
			if (ret < 0)
2254
				return ret;
3607
				return ret;
2255
		} else {
3608
		} else {
Lines 2273-2285 static struct ibm_struct led_driver_data Link Here
2273
 * Beep subdriver
3626
 * Beep subdriver
2274
 */
3627
 */
2275
3628
2276
IBM_HANDLE(beep, ec, "BEEP");	/* all except R30, R31 */
3629
TPACPI_HANDLE(beep, ec, "BEEP");	/* all except R30, R31 */
2277
3630
2278
static int __init beep_init(struct ibm_init_struct *iibm)
3631
static int __init beep_init(struct ibm_init_struct *iibm)
2279
{
3632
{
2280
	vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
3633
	vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
2281
3634
2282
	IBM_ACPIHANDLE_INIT(beep);
3635
	TPACPI_ACPIHANDLE_INIT(beep);
2283
3636
2284
	vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",
3637
	vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",
2285
		str_supported(beep_handle != NULL));
3638
		str_supported(beep_handle != NULL));
Lines 2287-2338 static int __init beep_init(struct ibm_i Link Here
2287
	return (beep_handle)? 0 : 1;
3640
	return (beep_handle)? 0 : 1;
2288
}
3641
}
2289
3642
2290
static int beep_read(char *p)
3643
static int beep_read(char *p)
2291
{
3644
{
2292
	int len = 0;
3645
	int len = 0;
3646
3647
	if (!beep_handle)
3648
		len += sprintf(p + len, "status:\t\tnot supported\n");
3649
	else {
3650
		len += sprintf(p + len, "status:\t\tsupported\n");
3651
		len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n");
3652
	}
3653
3654
	return len;
3655
}
3656
3657
static int beep_write(char *buf)
3658
{
3659
	char *cmd;
3660
	int beep_cmd;
3661
3662
	if (!beep_handle)
3663
		return -ENODEV;
3664
3665
	while ((cmd = next_cmd(&buf))) {
3666
		if (sscanf(cmd, "%u", &beep_cmd) == 1 &&
3667
		    beep_cmd >= 0 && beep_cmd <= 17) {
3668
			/* beep_cmd set */
3669
		} else
3670
			return -EINVAL;
3671
		if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0))
3672
			return -EIO;
3673
	}
3674
3675
	return 0;
3676
}
3677
3678
static struct ibm_struct beep_driver_data = {
3679
	.name = "beep",
3680
	.read = beep_read,
3681
	.write = beep_write,
3682
};
3683
3684
/*************************************************************************
3685
 * Thermal subdriver
3686
 */
3687
3688
enum thermal_access_mode {
3689
	TPACPI_THERMAL_NONE = 0,	/* No thermal support */
3690
	TPACPI_THERMAL_ACPI_TMP07,	/* Use ACPI TMP0-7 */
3691
	TPACPI_THERMAL_ACPI_UPDT,	/* Use ACPI TMP0-7 with UPDT */
3692
	TPACPI_THERMAL_TPEC_8,		/* Use ACPI EC regs, 8 sensors */
3693
	TPACPI_THERMAL_TPEC_16,		/* Use ACPI EC regs, 16 sensors */
3694
};
3695
3696
enum { /* TPACPI_THERMAL_TPEC_* */
3697
	TP_EC_THERMAL_TMP0 = 0x78,	/* ACPI EC regs TMP 0..7 */
3698
	TP_EC_THERMAL_TMP8 = 0xC0,	/* ACPI EC regs TMP 8..15 */
3699
	TP_EC_THERMAL_TMP_NA = -128,	/* ACPI EC sensor not available */
3700
};
3701
3702
#define TPACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
3703
struct ibm_thermal_sensors_struct {
3704
	s32 temp[TPACPI_MAX_THERMAL_SENSORS];
3705
};
3706
3707
static enum thermal_access_mode thermal_read_mode;
3708
3709
/* idx is zero-based */
3710
static int thermal_get_sensor(int idx, s32 *value)
3711
{
3712
	int t;
3713
	s8 tmp;
3714
	char tmpi[5];
3715
3716
	t = TP_EC_THERMAL_TMP0;
3717
3718
	switch (thermal_read_mode) {
3719
#if TPACPI_MAX_THERMAL_SENSORS >= 16
3720
	case TPACPI_THERMAL_TPEC_16:
3721
		if (idx >= 8 && idx <= 15) {
3722
			t = TP_EC_THERMAL_TMP8;
3723
			idx -= 8;
3724
		}
3725
		/* fallthrough */
3726
#endif
3727
	case TPACPI_THERMAL_TPEC_8:
3728
		if (idx <= 7) {
3729
			if (!acpi_ec_read(t + idx, &tmp))
3730
				return -EIO;
3731
			*value = tmp * 1000;
3732
			return 0;
3733
		}
3734
		break;
3735
3736
	case TPACPI_THERMAL_ACPI_UPDT:
3737
		if (idx <= 7) {
3738
			snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
3739
			if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
3740
				return -EIO;
3741
			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
3742
				return -EIO;
3743
			*value = (t - 2732) * 100;
3744
			return 0;
3745
		}
3746
		break;
3747
3748
	case TPACPI_THERMAL_ACPI_TMP07:
3749
		if (idx <= 7) {
3750
			snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
3751
			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
3752
				return -EIO;
3753
			if (t > 127 || t < -127)
3754
				t = TP_EC_THERMAL_TMP_NA;
3755
			*value = t * 1000;
3756
			return 0;
3757
		}
3758
		break;
2293
3759
2294
	if (!beep_handle)
3760
	case TPACPI_THERMAL_NONE:
2295
		len += sprintf(p + len, "status:\t\tnot supported\n");
3761
	default:
2296
	else {
3762
		return -ENOSYS;
2297
		len += sprintf(p + len, "status:\t\tsupported\n");
2298
		len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n");
2299
	}
3763
	}
2300
3764
2301
	return len;
3765
	return -EINVAL;
2302
}
3766
}
2303
3767
2304
static int beep_write(char *buf)
3768
static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
2305
{
3769
{
2306
	char *cmd;
3770
	int res, i;
2307
	int beep_cmd;
3771
	int n;
2308
2309
	if (!beep_handle)
2310
		return -ENODEV;
2311
3772
2312
	while ((cmd = next_cmd(&buf))) {
3773
	n = 8;
2313
		if (sscanf(cmd, "%u", &beep_cmd) == 1 &&
3774
	i = 0;
2314
		    beep_cmd >= 0 && beep_cmd <= 17) {
2315
			/* beep_cmd set */
2316
		} else
2317
			return -EINVAL;
2318
		if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0))
2319
			return -EIO;
2320
	}
2321
3775
2322
	return 0;
3776
	if (!s)
2323
}
3777
		return -EINVAL;
2324
3778
2325
static struct ibm_struct beep_driver_data = {
3779
	if (thermal_read_mode == TPACPI_THERMAL_TPEC_16)
2326
	.name = "beep",
3780
		n = 16;
2327
	.read = beep_read,
2328
	.write = beep_write,
2329
};
2330
3781
2331
/*************************************************************************
3782
	for (i = 0 ; i < n; i++) {
2332
 * Thermal subdriver
3783
		res = thermal_get_sensor(i, &s->temp[i]);
2333
 */
3784
		if (res)
3785
			return res;
3786
	}
2334
3787
2335
static enum thermal_access_mode thermal_read_mode;
3788
	return n;
3789
}
2336
3790
2337
/* sysfs temp##_input -------------------------------------------------- */
3791
/* sysfs temp##_input -------------------------------------------------- */
2338
3792
Lines 2356-2362 static ssize_t thermal_temp_input_show(s Link Here
2356
}
3810
}
2357
3811
2358
#define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \
3812
#define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \
2359
	 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, thermal_temp_input_show, NULL, _idxB)
3813
	 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, \
3814
		     thermal_temp_input_show, NULL, _idxB)
2360
3815
2361
static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = {
3816
static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = {
2362
	THERMAL_SENSOR_ATTR_TEMP(1, 0),
3817
	THERMAL_SENSOR_ATTR_TEMP(1, 0),
Lines 2424-2430 static int __init thermal_init(struct ib Link Here
2424
3879
2425
	acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
3880
	acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
2426
3881
2427
	if (ibm_thinkpad_ec_found && experimental) {
3882
	if (thinkpad_id.ec_model) {
2428
		/*
3883
		/*
2429
		 * Direct EC access mode: sensors at registers
3884
		 * Direct EC access mode: sensors at registers
2430
		 * 0x78-0x7F, 0xC0-0xC7.  Registers return 0x00 for
3885
		 * 0x78-0x7F, 0xC0-0xC7.  Registers return 0x00 for
Lines 2450-2461 static int __init thermal_init(struct ib Link Here
2450
		if (ta1 == 0) {
3905
		if (ta1 == 0) {
2451
			/* This is sheer paranoia, but we handle it anyway */
3906
			/* This is sheer paranoia, but we handle it anyway */
2452
			if (acpi_tmp7) {
3907
			if (acpi_tmp7) {
2453
				printk(IBM_ERR
3908
				printk(TPACPI_ERR
2454
				       "ThinkPad ACPI EC access misbehaving, "
3909
				       "ThinkPad ACPI EC access misbehaving, "
2455
				       "falling back to ACPI TMPx access mode\n");
3910
				       "falling back to ACPI TMPx access "
3911
				       "mode\n");
2456
				thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
3912
				thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
2457
			} else {
3913
			} else {
2458
				printk(IBM_ERR
3914
				printk(TPACPI_ERR
2459
				       "ThinkPad ACPI EC access misbehaving, "
3915
				       "ThinkPad ACPI EC access misbehaving, "
2460
				       "disabling thermal sensors access\n");
3916
				       "disabling thermal sensors access\n");
2461
				thermal_read_mode = TPACPI_THERMAL_NONE;
3917
				thermal_read_mode = TPACPI_THERMAL_NONE;
Lines 2482-2490 static int __init thermal_init(struct ib Link Here
2482
		str_supported(thermal_read_mode != TPACPI_THERMAL_NONE),
3938
		str_supported(thermal_read_mode != TPACPI_THERMAL_NONE),
2483
		thermal_read_mode);
3939
		thermal_read_mode);
2484
3940
2485
	switch(thermal_read_mode) {
3941
	switch (thermal_read_mode) {
2486
	case TPACPI_THERMAL_TPEC_16:
3942
	case TPACPI_THERMAL_TPEC_16:
2487
		res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3943
		res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
2488
				&thermal_temp_input16_group);
3944
				&thermal_temp_input16_group);
2489
		if (res)
3945
		if (res)
2490
			return res;
3946
			return res;
Lines 2492-2498 static int __init thermal_init(struct ib Link Here
2492
	case TPACPI_THERMAL_TPEC_8:
3948
	case TPACPI_THERMAL_TPEC_8:
2493
	case TPACPI_THERMAL_ACPI_TMP07:
3949
	case TPACPI_THERMAL_ACPI_TMP07:
2494
	case TPACPI_THERMAL_ACPI_UPDT:
3950
	case TPACPI_THERMAL_ACPI_UPDT:
2495
		res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3951
		res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
2496
				&thermal_temp_input8_group);
3952
				&thermal_temp_input8_group);
2497
		if (res)
3953
		if (res)
2498
			return res;
3954
			return res;
Lines 2507-2521 static int __init thermal_init(struct ib Link Here
2507
3963
2508
static void thermal_exit(void)
3964
static void thermal_exit(void)
2509
{
3965
{
2510
	switch(thermal_read_mode) {
3966
	switch (thermal_read_mode) {
2511
	case TPACPI_THERMAL_TPEC_16:
3967
	case TPACPI_THERMAL_TPEC_16:
2512
		sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3968
		sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
2513
				   &thermal_temp_input16_group);
3969
				   &thermal_temp_input16_group);
2514
		break;
3970
		break;
2515
	case TPACPI_THERMAL_TPEC_8:
3971
	case TPACPI_THERMAL_TPEC_8:
2516
	case TPACPI_THERMAL_ACPI_TMP07:
3972
	case TPACPI_THERMAL_ACPI_TMP07:
2517
	case TPACPI_THERMAL_ACPI_UPDT:
3973
	case TPACPI_THERMAL_ACPI_UPDT:
2518
		sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3974
		sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
2519
				   &thermal_temp_input16_group);
3975
				   &thermal_temp_input16_group);
2520
		break;
3976
		break;
2521
	case TPACPI_THERMAL_NONE:
3977
	case TPACPI_THERMAL_NONE:
Lines 2524-2609 static void thermal_exit(void) Link Here
2524
	}
3980
	}
2525
}
3981
}
2526
3982
2527
/* idx is zero-based */
2528
static int thermal_get_sensor(int idx, s32 *value)
2529
{
2530
	int t;
2531
	s8 tmp;
2532
	char tmpi[5];
2533
2534
	t = TP_EC_THERMAL_TMP0;
2535
2536
	switch (thermal_read_mode) {
2537
#if TPACPI_MAX_THERMAL_SENSORS >= 16
2538
	case TPACPI_THERMAL_TPEC_16:
2539
		if (idx >= 8 && idx <= 15) {
2540
			t = TP_EC_THERMAL_TMP8;
2541
			idx -= 8;
2542
		}
2543
		/* fallthrough */
2544
#endif
2545
	case TPACPI_THERMAL_TPEC_8:
2546
		if (idx <= 7) {
2547
			if (!acpi_ec_read(t + idx, &tmp))
2548
				return -EIO;
2549
			*value = tmp * 1000;
2550
			return 0;
2551
		}
2552
		break;
2553
2554
	case TPACPI_THERMAL_ACPI_UPDT:
2555
		if (idx <= 7) {
2556
			snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
2557
			if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
2558
				return -EIO;
2559
			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
2560
				return -EIO;
2561
			*value = (t - 2732) * 100;
2562
			return 0;
2563
		}
2564
		break;
2565
2566
	case TPACPI_THERMAL_ACPI_TMP07:
2567
		if (idx <= 7) {
2568
			snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
2569
			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
2570
				return -EIO;
2571
			*value = t * 1000;
2572
			return 0;
2573
		}
2574
		break;
2575
2576
	case TPACPI_THERMAL_NONE:
2577
	default:
2578
		return -ENOSYS;
2579
	}
2580
2581
	return -EINVAL;
2582
}
2583
2584
static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
2585
{
2586
	int res, i;
2587
	int n;
2588
2589
	n = 8;
2590
	i = 0;
2591
2592
	if (!s)
2593
		return -EINVAL;
2594
2595
	if (thermal_read_mode == TPACPI_THERMAL_TPEC_16)
2596
		n = 16;
2597
2598
	for(i = 0 ; i < n; i++) {
2599
		res = thermal_get_sensor(i, &s->temp[i]);
2600
		if (res)
2601
			return res;
2602
	}
2603
2604
	return n;
2605
}
2606
2607
static int thermal_read(char *p)
3983
static int thermal_read(char *p)
2608
{
3984
{
2609
	int len = 0;
3985
	int len = 0;
Lines 2658-2717 static int ecdump_read(char *p) Link Here
2658
				len += sprintf(p + len, "  %02x", v);
4034
				len += sprintf(p + len, "  %02x", v);
2659
			ecdump_regs[i + j] = v;
4035
			ecdump_regs[i + j] = v;
2660
		}
4036
		}
2661
		len += sprintf(p + len, "\n");
4037
		len += sprintf(p + len, "\n");
2662
		if (j != 16)
4038
		if (j != 16)
2663
			break;
4039
			break;
4040
	}
4041
4042
	/* These are way too dangerous to advertise openly... */
4043
#if 0
4044
	len += sprintf(p + len, "commands:\t0x<offset> 0x<value>"
4045
		       " (<offset> is 00-ff, <value> is 00-ff)\n");
4046
	len += sprintf(p + len, "commands:\t0x<offset> <value>  "
4047
		       " (<offset> is 00-ff, <value> is 0-255)\n");
4048
#endif
4049
	return len;
4050
}
4051
4052
static int ecdump_write(char *buf)
4053
{
4054
	char *cmd;
4055
	int i, v;
4056
4057
	while ((cmd = next_cmd(&buf))) {
4058
		if (sscanf(cmd, "0x%x 0x%x", &i, &v) == 2) {
4059
			/* i and v set */
4060
		} else if (sscanf(cmd, "0x%x %u", &i, &v) == 2) {
4061
			/* i and v set */
4062
		} else
4063
			return -EINVAL;
4064
		if (i >= 0 && i < 256 && v >= 0 && v < 256) {
4065
			if (!acpi_ec_write(i, v))
4066
				return -EIO;
4067
		} else
4068
			return -EINVAL;
4069
	}
4070
4071
	return 0;
4072
}
4073
4074
static struct ibm_struct ecdump_driver_data = {
4075
	.name = "ecdump",
4076
	.read = ecdump_read,
4077
	.write = ecdump_write,
4078
	.flags.experimental = 1,
4079
};
4080
4081
/*************************************************************************
4082
 * Backlight/brightness subdriver
4083
 */
4084
4085
#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
4086
4087
static struct backlight_device *ibm_backlight_device;
4088
static int brightness_offset = 0x31;
4089
static int brightness_mode;
4090
static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
4091
4092
static struct mutex brightness_mutex;
4093
4094
/*
4095
 * ThinkPads can read brightness from two places: EC 0x31, or
4096
 * CMOS NVRAM byte 0x5E, bits 0-3.
4097
 */
4098
static int brightness_get(struct backlight_device *bd)
4099
{
4100
	u8 lec = 0, lcmos = 0, level = 0;
4101
4102
	if (brightness_mode & 1) {
4103
		if (!acpi_ec_read(brightness_offset, &lec))
4104
			return -EIO;
4105
		lec &= (tp_features.bright_16levels)? 0x0f : 0x07;
4106
		level = lec;
4107
	};
4108
	if (brightness_mode & 2) {
4109
		lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
4110
			 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
4111
			>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
4112
		lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
4113
		level = lcmos;
4114
	}
4115
4116
	if (brightness_mode == 3 && lec != lcmos) {
4117
		printk(TPACPI_ERR
4118
			"CMOS NVRAM (%u) and EC (%u) do not agree "
4119
			"on display brightness level\n",
4120
			(unsigned int) lcmos,
4121
			(unsigned int) lec);
4122
		return -EIO;
4123
	}
4124
4125
	return level;
4126
}
4127
4128
/* May return EINTR which can always be mapped to ERESTARTSYS */
4129
static int brightness_set(int value)
4130
{
4131
	int cmos_cmd, inc, i, res;
4132
	int current_value;
4133
4134
	if (value > ((tp_features.bright_16levels)? 15 : 7))
4135
		return -EINVAL;
4136
4137
	res = mutex_lock_interruptible(&brightness_mutex);
4138
	if (res < 0)
4139
		return res;
4140
4141
	current_value = brightness_get(NULL);
4142
	if (current_value < 0) {
4143
		res = current_value;
4144
		goto errout;
4145
	}
4146
4147
	cmos_cmd = value > current_value ?
4148
			TP_CMOS_BRIGHTNESS_UP :
4149
			TP_CMOS_BRIGHTNESS_DOWN;
4150
	inc = (value > current_value)? 1 : -1;
4151
4152
	res = 0;
4153
	for (i = current_value; i != value; i += inc) {
4154
		if ((brightness_mode & 2) &&
4155
		    issue_thinkpad_cmos_command(cmos_cmd)) {
4156
			res = -EIO;
4157
			goto errout;
4158
		}
4159
		if ((brightness_mode & 1) &&
4160
		    !acpi_ec_write(brightness_offset, i + inc)) {
4161
			res = -EIO;
4162
			goto errout;;
4163
		}
4164
	}
4165
4166
errout:
4167
	mutex_unlock(&brightness_mutex);
4168
	return res;
4169
}
4170
4171
/* sysfs backlight class ----------------------------------------------- */
4172
4173
static int brightness_update_status(struct backlight_device *bd)
4174
{
4175
	/* it is the backlight class's job (caller) to handle
4176
	 * EINTR and other errors properly */
4177
	return brightness_set(
4178
		(bd->props.fb_blank == FB_BLANK_UNBLANK &&
4179
		 bd->props.power == FB_BLANK_UNBLANK) ?
4180
				bd->props.brightness : 0);
4181
}
4182
4183
static struct backlight_ops ibm_backlight_data = {
4184
	.get_brightness = brightness_get,
4185
	.update_status  = brightness_update_status,
4186
};
4187
4188
/* --------------------------------------------------------------------- */
4189
4190
static int __init tpacpi_query_bcll_levels(acpi_handle handle)
4191
{
4192
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
4193
	union acpi_object *obj;
4194
	int rc;
4195
4196
	if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
4197
		obj = (union acpi_object *)buffer.pointer;
4198
		if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
4199
			printk(TPACPI_ERR "Unknown BCLL data, "
4200
			       "please report this to %s\n", TPACPI_MAIL);
4201
			rc = 0;
4202
		} else {
4203
			rc = obj->package.count;
4204
		}
4205
	} else {
4206
		return 0;
4207
	}
4208
4209
	kfree(buffer.pointer);
4210
	return rc;
4211
}
4212
4213
static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl,
4214
					void *context, void **rv)
4215
{
4216
	char name[ACPI_PATH_SEGMENT_LENGTH];
4217
	struct acpi_buffer buffer = { sizeof(name), &name };
4218
4219
	if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
4220
	    !strncmp("BCLL", name, sizeof(name) - 1)) {
4221
		if (tpacpi_query_bcll_levels(handle) == 16) {
4222
			*rv = handle;
4223
			return AE_CTRL_TERMINATE;
4224
		} else {
4225
			return AE_OK;
4226
		}
4227
	} else {
4228
		return AE_OK;
2664
	}
4229
	}
2665
2666
	/* These are way too dangerous to advertise openly... */
2667
#if 0
2668
	len += sprintf(p + len, "commands:\t0x<offset> 0x<value>"
2669
		       " (<offset> is 00-ff, <value> is 00-ff)\n");
2670
	len += sprintf(p + len, "commands:\t0x<offset> <value>  "
2671
		       " (<offset> is 00-ff, <value> is 0-255)\n");
2672
#endif
2673
	return len;
2674
}
4230
}
2675
4231
2676
static int ecdump_write(char *buf)
4232
static int __init brightness_check_levels(void)
2677
{
4233
{
2678
	char *cmd;
4234
	int status;
2679
	int i, v;
4235
	void *found_node = NULL;
2680
4236
2681
	while ((cmd = next_cmd(&buf))) {
4237
	if (!vid_handle) {
2682
		if (sscanf(cmd, "0x%x 0x%x", &i, &v) == 2) {
4238
		TPACPI_ACPIHANDLE_INIT(vid);
2683
			/* i and v set */
2684
		} else if (sscanf(cmd, "0x%x %u", &i, &v) == 2) {
2685
			/* i and v set */
2686
		} else
2687
			return -EINVAL;
2688
		if (i >= 0 && i < 256 && v >= 0 && v < 256) {
2689
			if (!acpi_ec_write(i, v))
2690
				return -EIO;
2691
		} else
2692
			return -EINVAL;
2693
	}
4239
	}
4240
	if (!vid_handle)
4241
		return 0;
2694
4242
2695
	return 0;
4243
	/* Search for a BCLL package with 16 levels */
4244
	status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3,
4245
					brightness_find_bcll, NULL,
4246
					&found_node);
4247
4248
	return (ACPI_SUCCESS(status) && found_node != NULL);
2696
}
4249
}
2697
4250
2698
static struct ibm_struct ecdump_driver_data = {
4251
static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl,
2699
	.name = "ecdump",
4252
					void *context, void **rv)
2700
	.read = ecdump_read,
4253
{
2701
	.write = ecdump_write,
4254
	char name[ACPI_PATH_SEGMENT_LENGTH];
2702
	.flags.experimental = 1,
4255
	struct acpi_buffer buffer = { sizeof(name), &name };
2703
};
2704
4256
2705
/*************************************************************************
4257
	if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
2706
 * Backlight/brightness subdriver
4258
	    !strncmp("_BCL", name, sizeof(name) - 1)) {
2707
 */
4259
		*rv = handle;
4260
		return AE_CTRL_TERMINATE;
4261
	} else {
4262
		return AE_OK;
4263
	}
4264
}
2708
4265
2709
static struct backlight_device *ibm_backlight_device = NULL;
4266
static int __init brightness_check_std_acpi_support(void)
4267
{
4268
	int status;
4269
	void *found_node = NULL;
2710
4270
2711
static struct backlight_ops ibm_backlight_data = {
4271
	if (!vid_handle) {
2712
        .get_brightness = brightness_get,
4272
		TPACPI_ACPIHANDLE_INIT(vid);
2713
        .update_status  = brightness_update_status,
4273
	}
2714
};
4274
	if (!vid_handle)
4275
		return 0;
4276
4277
	/* Search for a _BCL method, but don't execute it */
4278
	status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
4279
				     brightness_find_bcl, NULL, &found_node);
4280
4281
	return (ACPI_SUCCESS(status) && found_node != NULL);
4282
}
2715
4283
2716
static int __init brightness_init(struct ibm_init_struct *iibm)
4284
static int __init brightness_init(struct ibm_init_struct *iibm)
2717
{
4285
{
Lines 2719-2738 static int __init brightness_init(struct Link Here
2719
4287
2720
	vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
4288
	vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
2721
4289
4290
	mutex_init(&brightness_mutex);
4291
4292
	if (!brightness_enable) {
4293
		dbg_printk(TPACPI_DBG_INIT,
4294
			   "brightness support disabled by "
4295
			   "module parameter\n");
4296
		return 1;
4297
	} else if (brightness_enable > 1) {
4298
		if (brightness_check_std_acpi_support()) {
4299
			printk(TPACPI_NOTICE
4300
			       "standard ACPI backlight interface "
4301
			       "available, not loading native one...\n");
4302
			return 1;
4303
		}
4304
	}
4305
4306
	if (!brightness_mode) {
4307
		if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
4308
			brightness_mode = 2;
4309
		else
4310
			brightness_mode = 3;
4311
4312
		dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
4313
			brightness_mode);
4314
	}
4315
4316
	if (brightness_mode > 3)
4317
		return -EINVAL;
4318
4319
	tp_features.bright_16levels =
4320
			thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO &&
4321
			brightness_check_levels();
4322
2722
	b = brightness_get(NULL);
4323
	b = brightness_get(NULL);
2723
	if (b < 0)
4324
	if (b < 0)
2724
		return b;
4325
		return 1;
4326
4327
	if (tp_features.bright_16levels)
4328
		printk(TPACPI_INFO
4329
		       "detected a 16-level brightness capable ThinkPad\n");
2725
4330
2726
	ibm_backlight_device = backlight_device_register(
4331
	ibm_backlight_device = backlight_device_register(
2727
					TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
4332
					TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
2728
					&ibm_backlight_data);
4333
					&ibm_backlight_data);
2729
	if (IS_ERR(ibm_backlight_device)) {
4334
	if (IS_ERR(ibm_backlight_device)) {
2730
		printk(IBM_ERR "Could not register backlight device\n");
4335
		printk(TPACPI_ERR "Could not register backlight device\n");
2731
		return PTR_ERR(ibm_backlight_device);
4336
		return PTR_ERR(ibm_backlight_device);
2732
	}
4337
	}
2733
	vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
4338
	vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
2734
4339
2735
	ibm_backlight_device->props.max_brightness = 7;
4340
	ibm_backlight_device->props.max_brightness =
4341
				(tp_features.bright_16levels)? 15 : 7;
2736
	ibm_backlight_device->props.brightness = b;
4342
	ibm_backlight_device->props.brightness = b;
2737
	backlight_update_status(ibm_backlight_device);
4343
	backlight_update_status(ibm_backlight_device);
2738
4344
Lines 2749-2804 static void brightness_exit(void) Link Here
2749
	}
4355
	}
2750
}
4356
}
2751
4357
2752
static int brightness_update_status(struct backlight_device *bd)
2753
{
2754
	return brightness_set(
2755
		(bd->props.fb_blank == FB_BLANK_UNBLANK &&
2756
		 bd->props.power == FB_BLANK_UNBLANK) ?
2757
				bd->props.brightness : 0);
2758
}
2759
2760
static int brightness_get(struct backlight_device *bd)
2761
{
2762
	u8 level;
2763
	if (!acpi_ec_read(brightness_offset, &level))
2764
		return -EIO;
2765
2766
	level &= 0x7;
2767
2768
	return level;
2769
}
2770
2771
static int brightness_set(int value)
2772
{
2773
	int cmos_cmd, inc, i;
2774
	int current_value = brightness_get(NULL);
2775
2776
	value &= 7;
2777
2778
	cmos_cmd = value > current_value ? TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN;
2779
	inc = value > current_value ? 1 : -1;
2780
	for (i = current_value; i != value; i += inc) {
2781
		if (issue_thinkpad_cmos_command(cmos_cmd))
2782
			return -EIO;
2783
		if (!acpi_ec_write(brightness_offset, i + inc))
2784
			return -EIO;
2785
	}
2786
2787
	return 0;
2788
}
2789
2790
static int brightness_read(char *p)
4358
static int brightness_read(char *p)
2791
{
4359
{
2792
	int len = 0;
4360
	int len = 0;
2793
	int level;
4361
	int level;
2794
4362
2795
	if ((level = brightness_get(NULL)) < 0) {
4363
	level = brightness_get(NULL);
4364
	if (level < 0) {
2796
		len += sprintf(p + len, "level:\t\tunreadable\n");
4365
		len += sprintf(p + len, "level:\t\tunreadable\n");
2797
	} else {
4366
	} else {
2798
		len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
4367
		len += sprintf(p + len, "level:\t\t%d\n", level);
2799
		len += sprintf(p + len, "commands:\tup, down\n");
4368
		len += sprintf(p + len, "commands:\tup, down\n");
2800
		len += sprintf(p + len, "commands:\tlevel <level>"
4369
		len += sprintf(p + len, "commands:\tlevel <level>"
2801
			       " (<level> is 0-7)\n");
4370
			       " (<level> is 0-%d)\n",
4371
			       (tp_features.bright_16levels) ? 15 : 7);
2802
	}
4372
	}
2803
4373
2804
	return len;
4374
	return len;
Lines 2807-2834 static int brightness_read(char *p) Link Here
2807
static int brightness_write(char *buf)
4377
static int brightness_write(char *buf)
2808
{
4378
{
2809
	int level;
4379
	int level;
2810
	int new_level;
4380
	int rc;
2811
	char *cmd;
4381
	char *cmd;
4382
	int max_level = (tp_features.bright_16levels) ? 15 : 7;
2812
4383
2813
	while ((cmd = next_cmd(&buf))) {
4384
	level = brightness_get(NULL);
2814
		if ((level = brightness_get(NULL)) < 0)
4385
	if (level < 0)
2815
			return level;
4386
		return level;
2816
		level &= 7;
2817
4387
4388
	while ((cmd = next_cmd(&buf))) {
2818
		if (strlencmp(cmd, "up") == 0) {
4389
		if (strlencmp(cmd, "up") == 0) {
2819
			new_level = level == 7 ? 7 : level + 1;
4390
			if (level < max_level)
4391
				level++;
2820
		} else if (strlencmp(cmd, "down") == 0) {
4392
		} else if (strlencmp(cmd, "down") == 0) {
2821
			new_level = level == 0 ? 0 : level - 1;
4393
			if (level > 0)
2822
		} else if (sscanf(cmd, "level %d", &new_level) == 1 &&
4394
				level--;
2823
			   new_level >= 0 && new_level <= 7) {
4395
		} else if (sscanf(cmd, "level %d", &level) == 1 &&
2824
			/* new_level set */
4396
			   level >= 0 && level <= max_level) {
4397
			/* new level set */
2825
		} else
4398
		} else
2826
			return -EINVAL;
4399
			return -EINVAL;
2827
2828
		brightness_set(new_level);
2829
	}
4400
	}
2830
4401
2831
	return 0;
4402
	/*
4403
	 * Now we know what the final level should be, so we try to set it.
4404
	 * Doing it this way makes the syscall restartable in case of EINTR
4405
	 */
4406
	rc = brightness_set(level);
4407
	return (rc == -EINTR)? ERESTARTSYS : rc;
2832
}
4408
}
2833
4409
2834
static struct ibm_struct brightness_driver_data = {
4410
static struct ibm_struct brightness_driver_data = {
Lines 2842-2847 static struct ibm_struct brightness_driv Link Here
2842
 * Volume subdriver
4418
 * Volume subdriver
2843
 */
4419
 */
2844
4420
4421
static int volume_offset = 0x30;
4422
2845
static int volume_read(char *p)
4423
static int volume_read(char *p)
2846
{
4424
{
2847
	int len = 0;
4425
	int len = 0;
Lines 2891-2898 static int volume_write(char *buf) Link Here
2891
		} else
4469
		} else
2892
			return -EINVAL;
4470
			return -EINVAL;
2893
4471
2894
		if (new_level != level) {	/* mute doesn't change */
4472
		if (new_level != level) {
2895
			cmos_cmd = new_level > level ? TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN;
4473
			/* mute doesn't change */
4474
4475
			cmos_cmd = (new_level > level) ?
4476
					TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN;
2896
			inc = new_level > level ? 1 : -1;
4477
			inc = new_level > level ? 1 : -1;
2897
4478
2898
			if (mute && (issue_thinkpad_cmos_command(cmos_cmd) ||
4479
			if (mute && (issue_thinkpad_cmos_command(cmos_cmd) ||
Lines 2904-2917 static int volume_write(char *buf) Link Here
2904
				    !acpi_ec_write(volume_offset, i + inc))
4485
				    !acpi_ec_write(volume_offset, i + inc))
2905
					return -EIO;
4486
					return -EIO;
2906
4487
2907
			if (mute && (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) ||
4488
			if (mute &&
2908
				     !acpi_ec_write(volume_offset,
4489
			    (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) ||
2909
						    new_level + mute)))
4490
			     !acpi_ec_write(volume_offset, new_level + mute))) {
2910
				return -EIO;
4491
				return -EIO;
4492
			}
2911
		}
4493
		}
2912
4494
2913
		if (new_mute != mute) {	/* level doesn't change */
4495
		if (new_mute != mute) {
2914
			cmos_cmd = new_mute ? TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP;
4496
			/* level doesn't change */
4497
4498
			cmos_cmd = (new_mute) ?
4499
				   TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP;
2915
4500
2916
			if (issue_thinkpad_cmos_command(cmos_cmd) ||
4501
			if (issue_thinkpad_cmos_command(cmos_cmd) ||
2917
			    !acpi_ec_write(volume_offset, level + new_mute))
4502
			    !acpi_ec_write(volume_offset, level + new_mute))
Lines 3033-3515 static struct ibm_struct volume_driver_d Link Here
3033
 * 	but the ACPI tables just mention level 7.
4618
 * 	but the ACPI tables just mention level 7.
3034
 */
4619
 */
3035
4620
4621
enum {					/* Fan control constants */
4622
	fan_status_offset = 0x2f,	/* EC register 0x2f */
4623
	fan_rpm_offset = 0x84,		/* EC register 0x84: LSB, 0x85 MSB (RPM)
4624
					 * 0x84 must be read before 0x85 */
4625
4626
	TP_EC_FAN_FULLSPEED = 0x40,	/* EC fan mode: full speed */
4627
	TP_EC_FAN_AUTO	    = 0x80,	/* EC fan mode: auto fan control */
4628
4629
	TPACPI_FAN_LAST_LEVEL = 0x100,	/* Use cached last-seen fan level */
4630
};
4631
4632
enum fan_status_access_mode {
4633
	TPACPI_FAN_NONE = 0,		/* No fan status or control */
4634
	TPACPI_FAN_RD_ACPI_GFAN,	/* Use ACPI GFAN */
4635
	TPACPI_FAN_RD_TPEC,		/* Use ACPI EC regs 0x2f, 0x84-0x85 */
4636
};
4637
4638
enum fan_control_access_mode {
4639
	TPACPI_FAN_WR_NONE = 0,		/* No fan control */
4640
	TPACPI_FAN_WR_ACPI_SFAN,	/* Use ACPI SFAN */
4641
	TPACPI_FAN_WR_TPEC,		/* Use ACPI EC reg 0x2f */
4642
	TPACPI_FAN_WR_ACPI_FANS,	/* Use ACPI FANS and EC reg 0x2f */
4643
};
4644
4645
enum fan_control_commands {
4646
	TPACPI_FAN_CMD_SPEED 	= 0x0001,	/* speed command */
4647
	TPACPI_FAN_CMD_LEVEL 	= 0x0002,	/* level command  */
4648
	TPACPI_FAN_CMD_ENABLE	= 0x0004,	/* enable/disable cmd,
4649
						 * and also watchdog cmd */
4650
};
4651
4652
static int fan_control_allowed;
4653
3036
static enum fan_status_access_mode fan_status_access_mode;
4654
static enum fan_status_access_mode fan_status_access_mode;
3037
static enum fan_control_access_mode fan_control_access_mode;
4655
static enum fan_control_access_mode fan_control_access_mode;
3038
static enum fan_control_commands fan_control_commands;
4656
static enum fan_control_commands fan_control_commands;
3039
4657
3040
static u8 fan_control_initial_status;
4658
static u8 fan_control_initial_status;
3041
static u8 fan_control_desired_level;
4659
static u8 fan_control_desired_level;
4660
static int fan_watchdog_maxinterval;
4661
4662
static struct mutex fan_mutex;
3042
4663
3043
static void fan_watchdog_fire(struct work_struct *ignored);
4664
static void fan_watchdog_fire(struct work_struct *ignored);
3044
static int fan_watchdog_maxinterval;
3045
static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
4665
static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
3046
4666
3047
IBM_HANDLE(fans, ec, "FANS");	/* X31, X40, X41 */
4667
TPACPI_HANDLE(fans, ec, "FANS");	/* X31, X40, X41 */
3048
IBM_HANDLE(gfan, ec, "GFAN",	/* 570 */
4668
TPACPI_HANDLE(gfan, ec, "GFAN",	/* 570 */
3049
	   "\\FSPD",		/* 600e/x, 770e, 770x */
4669
	   "\\FSPD",		/* 600e/x, 770e, 770x */
3050
	   );			/* all others */
4670
	   );			/* all others */
3051
IBM_HANDLE(sfan, ec, "SFAN",	/* 570 */
4671
TPACPI_HANDLE(sfan, ec, "SFAN",	/* 570 */
3052
	   "JFNS",		/* 770x-JL */
4672
	   "JFNS",		/* 770x-JL */
3053
	   );			/* all others */
4673
	   );			/* all others */
3054
4674
3055
/*
4675
/*
3056
 * SYSFS fan layout: hwmon compatible (device)
4676
 * Call with fan_mutex held
3057
 *
3058
 * pwm*_enable:
3059
 * 	0: "disengaged" mode
3060
 * 	1: manual mode
3061
 * 	2: native EC "auto" mode (recommended, hardware default)
3062
 *
3063
 * pwm*: set speed in manual mode, ignored otherwise.
3064
 * 	0 is level 0; 255 is level 7. Intermediate points done with linear
3065
 * 	interpolation.
3066
 *
3067
 * fan*_input: tachometer reading, RPM
3068
 *
3069
 *
3070
 * SYSFS fan layout: extensions
3071
 *
3072
 * fan_watchdog (driver):
3073
 * 	fan watchdog interval in seconds, 0 disables (default), max 120
3074
 */
4677
 */
3075
4678
static void fan_update_desired_level(u8 status)
3076
/* sysfs fan pwm1_enable ----------------------------------------------- */
3077
static ssize_t fan_pwm1_enable_show(struct device *dev,
3078
				    struct device_attribute *attr,
3079
				    char *buf)
3080
{
3081
	int res, mode;
3082
	u8 status;
3083
3084
	res = fan_get_status_safe(&status);
3085
	if (res)
3086
		return res;
3087
3088
	if (unlikely(tp_features.fan_ctrl_status_undef)) {
3089
		if (status != fan_control_initial_status) {
3090
			tp_features.fan_ctrl_status_undef = 0;
3091
		} else {
3092
			/* Return most likely status. In fact, it
3093
			 * might be the only possible status */
3094
			status = TP_EC_FAN_AUTO;
3095
		}
3096
	}
3097
3098
	if (status & TP_EC_FAN_FULLSPEED) {
3099
		mode = 0;
3100
	} else if (status & TP_EC_FAN_AUTO) {
3101
		mode = 2;
3102
	} else
3103
		mode = 1;
3104
3105
	return snprintf(buf, PAGE_SIZE, "%d\n", mode);
3106
}
3107
3108
static ssize_t fan_pwm1_enable_store(struct device *dev,
3109
				     struct device_attribute *attr,
3110
				     const char *buf, size_t count)
3111
{
4679
{
3112
	unsigned long t;
4680
	if ((status &
3113
	int res, level;
4681
	     (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
3114
4682
		if (status > 7)
3115
	if (parse_strtoul(buf, 2, &t))
4683
			fan_control_desired_level = 7;
3116
		return -EINVAL;
4684
		else
3117
4685
			fan_control_desired_level = status;
3118
	switch (t) {
3119
	case 0:
3120
		level = TP_EC_FAN_FULLSPEED;
3121
		break;
3122
	case 1:
3123
		level = TPACPI_FAN_LAST_LEVEL;
3124
		break;
3125
	case 2:
3126
		level = TP_EC_FAN_AUTO;
3127
		break;
3128
	case 3:
3129
		/* reserved for software-controlled auto mode */
3130
		return -ENOSYS;
3131
	default:
3132
		return -EINVAL;
3133
	}
4686
	}
3134
3135
	res = fan_set_level_safe(level);
3136
	if (res == -ENXIO)
3137
		return -EINVAL;
3138
	else if (res < 0)
3139
		return res;
3140
3141
	fan_watchdog_reset();
3142
3143
	return count;
3144
}
4687
}
3145
4688
3146
static struct device_attribute dev_attr_fan_pwm1_enable =
4689
static int fan_get_status(u8 *status)
3147
	__ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
3148
		fan_pwm1_enable_show, fan_pwm1_enable_store);
3149
3150
/* sysfs fan pwm1 ------------------------------------------------------ */
3151
static ssize_t fan_pwm1_show(struct device *dev,
3152
			     struct device_attribute *attr,
3153
			     char *buf)
3154
{
4690
{
3155
	int res;
4691
	u8 s;
3156
	u8 status;
3157
3158
	res = fan_get_status_safe(&status);
3159
	if (res)
3160
		return res;
3161
4692
3162
	if (unlikely(tp_features.fan_ctrl_status_undef)) {
4693
	/* TODO:
3163
		if (status != fan_control_initial_status) {
4694
	 * Add TPACPI_FAN_RD_ACPI_FANS ? */
3164
			tp_features.fan_ctrl_status_undef = 0;
3165
		} else {
3166
			status = TP_EC_FAN_AUTO;
3167
		}
3168
	}
3169
4695
3170
	if ((status &
4696
	switch (fan_status_access_mode) {
3171
	     (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)
4697
	case TPACPI_FAN_RD_ACPI_GFAN:
3172
		status = fan_control_desired_level;
4698
		/* 570, 600e/x, 770e, 770x */
3173
4699
3174
	if (status > 7)
4700
		if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
3175
		status = 7;
4701
			return -EIO;
3176
4702
3177
	return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7);
4703
		if (likely(status))
3178
}
4704
			*status = s & 0x07;
3179
4705
3180
static ssize_t fan_pwm1_store(struct device *dev,
4706
		break;
3181
			      struct device_attribute *attr,
3182
			      const char *buf, size_t count)
3183
{
3184
	unsigned long s;
3185
	int rc;
3186
	u8 status, newlevel;
3187
4707
3188
	if (parse_strtoul(buf, 255, &s))
4708
	case TPACPI_FAN_RD_TPEC:
3189
		return -EINVAL;
4709
		/* all except 570, 600e/x, 770e, 770x */
4710
		if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
4711
			return -EIO;
3190
4712
3191
	/* scale down from 0-255 to 0-7 */
4713
		if (likely(status))
3192
	newlevel = (s >> 5) & 0x07;
4714
			*status = s;
3193
4715
3194
	rc = mutex_lock_interruptible(&fan_mutex);
4716
		break;
3195
	if (rc < 0)
3196
		return rc;
3197
4717
3198
	rc = fan_get_status(&status);
4718
	default:
3199
	if (!rc && (status &
4719
		return -ENXIO;
3200
		    (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
3201
		rc = fan_set_level(newlevel);
3202
		if (rc == -ENXIO)
3203
			rc = -EINVAL;
3204
		else if (!rc) {
3205
			fan_update_desired_level(newlevel);
3206
			fan_watchdog_reset();
3207
		}
3208
	}
4720
	}
3209
4721
3210
	mutex_unlock(&fan_mutex);
4722
	return 0;
3211
	return (rc)? rc : count;
3212
}
4723
}
3213
4724
3214
static struct device_attribute dev_attr_fan_pwm1 =
4725
static int fan_get_status_safe(u8 *status)
3215
	__ATTR(pwm1, S_IWUSR | S_IRUGO,
3216
		fan_pwm1_show, fan_pwm1_store);
3217
3218
/* sysfs fan fan1_input ------------------------------------------------ */
3219
static ssize_t fan_fan1_input_show(struct device *dev,
3220
			   struct device_attribute *attr,
3221
			   char *buf)
3222
{
4726
{
3223
	int res;
4727
	int rc;
3224
	unsigned int speed;
4728
	u8 s;
3225
3226
	res = fan_get_speed(&speed);
3227
	if (res < 0)
3228
		return res;
3229
4729
3230
	return snprintf(buf, PAGE_SIZE, "%u\n", speed);
4730
	if (mutex_lock_interruptible(&fan_mutex))
3231
}
4731
		return -ERESTARTSYS;
4732
	rc = fan_get_status(&s);
4733
	if (!rc)
4734
		fan_update_desired_level(s);
4735
	mutex_unlock(&fan_mutex);
3232
4736
3233
static struct device_attribute dev_attr_fan_fan1_input =
4737
	if (status)
3234
	__ATTR(fan1_input, S_IRUGO,
4738
		*status = s;
3235
		fan_fan1_input_show, NULL);
3236
4739
3237
/* sysfs fan fan_watchdog (driver) ------------------------------------- */
4740
	return rc;
3238
static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
3239
				     char *buf)
3240
{
3241
	return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval);
3242
}
4741
}
3243
4742
3244
static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
4743
static int fan_get_speed(unsigned int *speed)
3245
				      const char *buf, size_t count)
3246
{
4744
{
3247
	unsigned long t;
4745
	u8 hi, lo;
3248
3249
	if (parse_strtoul(buf, 120, &t))
3250
		return -EINVAL;
3251
3252
	if (!fan_control_allowed)
3253
		return -EPERM;
3254
4746
3255
	fan_watchdog_maxinterval = t;
4747
	switch (fan_status_access_mode) {
3256
	fan_watchdog_reset();
4748
	case TPACPI_FAN_RD_TPEC:
4749
		/* all except 570, 600e/x, 770e, 770x */
4750
		if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
4751
			     !acpi_ec_read(fan_rpm_offset + 1, &hi)))
4752
			return -EIO;
3257
4753
3258
	return count;
4754
		if (likely(speed))
3259
}
4755
			*speed = (hi << 8) | lo;
3260
4756
3261
static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
4757
		break;
3262
		fan_fan_watchdog_show, fan_fan_watchdog_store);
3263
4758
3264
/* --------------------------------------------------------------------- */
4759
	default:
3265
static struct attribute *fan_attributes[] = {
4760
		return -ENXIO;
3266
	&dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
4761
	}
3267
	&dev_attr_fan_fan1_input.attr,
3268
	NULL
3269
};
3270
4762
3271
static const struct attribute_group fan_attr_group = {
4763
	return 0;
3272
	.attrs = fan_attributes,
4764
}
3273
};
3274
4765
3275
static int __init fan_init(struct ibm_init_struct *iibm)
4766
static int fan_set_level(int level)
3276
{
4767
{
3277
	int rc;
4768
	if (!fan_control_allowed)
4769
		return -EPERM;
3278
4770
3279
	vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
4771
	switch (fan_control_access_mode) {
4772
	case TPACPI_FAN_WR_ACPI_SFAN:
4773
		if (level >= 0 && level <= 7) {
4774
			if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
4775
				return -EIO;
4776
		} else
4777
			return -EINVAL;
4778
		break;
3280
4779
3281
	mutex_init(&fan_mutex);
4780
	case TPACPI_FAN_WR_ACPI_FANS:
3282
	fan_status_access_mode = TPACPI_FAN_NONE;
4781
	case TPACPI_FAN_WR_TPEC:
3283
	fan_control_access_mode = TPACPI_FAN_WR_NONE;
4782
		if ((level != TP_EC_FAN_AUTO) &&
3284
	fan_control_commands = 0;
4783
		    (level != TP_EC_FAN_FULLSPEED) &&
3285
	fan_watchdog_maxinterval = 0;
4784
		    ((level < 0) || (level > 7)))
3286
	tp_features.fan_ctrl_status_undef = 0;
4785
			return -EINVAL;
3287
	fan_control_desired_level = 7;
3288
4786
3289
	IBM_ACPIHANDLE_INIT(fans);
4787
		/* safety net should the EC not support AUTO
3290
	IBM_ACPIHANDLE_INIT(gfan);
4788
		 * or FULLSPEED mode bits and just ignore them */
3291
	IBM_ACPIHANDLE_INIT(sfan);
4789
		if (level & TP_EC_FAN_FULLSPEED)
4790
			level |= 7;	/* safety min speed 7 */
4791
		else if (level & TP_EC_FAN_FULLSPEED)
4792
			level |= 4;	/* safety min speed 4 */
3292
4793
3293
	if (gfan_handle) {
4794
		if (!acpi_ec_write(fan_status_offset, level))
3294
		/* 570, 600e/x, 770e, 770x */
4795
			return -EIO;
3295
		fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
4796
		else
3296
	} else {
4797
			tp_features.fan_ctrl_status_undef = 0;
3297
		/* all other ThinkPads: note that even old-style
4798
		break;
3298
		 * ThinkPad ECs supports the fan control register */
3299
		if (likely(acpi_ec_read(fan_status_offset,
3300
					&fan_control_initial_status))) {
3301
			fan_status_access_mode = TPACPI_FAN_RD_TPEC;
3302
4799
3303
			/* In some ThinkPads, neither the EC nor the ACPI
4800
	default:
3304
			 * DSDT initialize the fan status, and it ends up
4801
		return -ENXIO;
3305
			 * being set to 0x07 when it *could* be either
3306
			 * 0x07 or 0x80.
3307
			 *
3308
			 * Enable for TP-1Y (T43), TP-78 (R51e),
3309
			 * TP-76 (R52), TP-70 (T43, R52), which are known
3310
			 * to be buggy. */
3311
			if (fan_control_initial_status == 0x07 &&
3312
			    ibm_thinkpad_ec_found &&
3313
			    ((ibm_thinkpad_ec_found[0] == '1' &&
3314
			      ibm_thinkpad_ec_found[1] == 'Y') ||
3315
			     (ibm_thinkpad_ec_found[0] == '7' &&
3316
			      (ibm_thinkpad_ec_found[1] == '6' ||
3317
			       ibm_thinkpad_ec_found[1] == '8' ||
3318
			       ibm_thinkpad_ec_found[1] == '0'))
3319
			    )) {
3320
				printk(IBM_NOTICE
3321
				       "fan_init: initial fan status is "
3322
				       "unknown, assuming it is in auto "
3323
				       "mode\n");
3324
				tp_features.fan_ctrl_status_undef = 1;
3325
			}
3326
		} else {
3327
			printk(IBM_ERR
3328
			       "ThinkPad ACPI EC access misbehaving, "
3329
			       "fan status and control unavailable\n");
3330
			return 1;
3331
		}
3332
	}
4802
	}
4803
	return 0;
4804
}
3333
4805
3334
	if (sfan_handle) {
4806
static int fan_set_level_safe(int level)
3335
		/* 570, 770x-JL */
4807
{
3336
		fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN;
4808
	int rc;
3337
		fan_control_commands |=
3338
		    TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE;
3339
	} else {
3340
		if (!gfan_handle) {
3341
			/* gfan without sfan means no fan control */
3342
			/* all other models implement TP EC 0x2f control */
3343
3344
			if (fans_handle) {
3345
				/* X31, X40, X41 */
3346
				fan_control_access_mode =
3347
				    TPACPI_FAN_WR_ACPI_FANS;
3348
				fan_control_commands |=
3349
				    TPACPI_FAN_CMD_SPEED |
3350
				    TPACPI_FAN_CMD_LEVEL |
3351
				    TPACPI_FAN_CMD_ENABLE;
3352
			} else {
3353
				fan_control_access_mode = TPACPI_FAN_WR_TPEC;
3354
				fan_control_commands |=
3355
				    TPACPI_FAN_CMD_LEVEL |
3356
				    TPACPI_FAN_CMD_ENABLE;
3357
			}
3358
		}
3359
	}
3360
4809
3361
	vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
4810
	if (!fan_control_allowed)
3362
		str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
4811
		return -EPERM;
3363
		  fan_control_access_mode != TPACPI_FAN_WR_NONE),
3364
		fan_status_access_mode, fan_control_access_mode);
3365
4812
3366
	/* fan control master switch */
4813
	if (mutex_lock_interruptible(&fan_mutex))
3367
	if (!fan_control_allowed) {
4814
		return -ERESTARTSYS;
3368
		fan_control_access_mode = TPACPI_FAN_WR_NONE;
3369
		fan_control_commands = 0;
3370
		dbg_printk(TPACPI_DBG_INIT,
3371
			   "fan control features disabled by parameter\n");
3372
	}
3373
4815
3374
	/* update fan_control_desired_level */
4816
	if (level == TPACPI_FAN_LAST_LEVEL)
3375
	if (fan_status_access_mode != TPACPI_FAN_NONE)
4817
		level = fan_control_desired_level;
3376
		fan_get_status_safe(NULL);
3377
4818
3378
	if (fan_status_access_mode != TPACPI_FAN_NONE ||
4819
	rc = fan_set_level(level);
3379
	    fan_control_access_mode != TPACPI_FAN_WR_NONE) {
4820
	if (!rc)
3380
		rc = sysfs_create_group(&tpacpi_pdev->dev.kobj,
4821
		fan_update_desired_level(level);
3381
					 &fan_attr_group);
3382
		if (!(rc < 0))
3383
			rc = driver_create_file(&tpacpi_pdriver.driver,
3384
					&driver_attr_fan_watchdog);
3385
		if (rc < 0)
3386
			return rc;
3387
		return 0;
3388
	} else
3389
		return 1;
3390
}
3391
4822
3392
/*
4823
	mutex_unlock(&fan_mutex);
3393
 * Call with fan_mutex held
4824
	return rc;
3394
 */
3395
static void fan_update_desired_level(u8 status)
3396
{
3397
	if ((status &
3398
	     (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
3399
		if (status > 7)
3400
			fan_control_desired_level = 7;
3401
		else
3402
			fan_control_desired_level = status;
3403
	}
3404
}
4825
}
3405
4826
3406
static int fan_get_status(u8 *status)
4827
static int fan_set_enable(void)
3407
{
4828
{
3408
	u8 s;
4829
	u8 s;
4830
	int rc;
3409
4831
3410
	/* TODO:
4832
	if (!fan_control_allowed)
3411
	 * Add TPACPI_FAN_RD_ACPI_FANS ? */
4833
		return -EPERM;
3412
4834
3413
	switch (fan_status_access_mode) {
4835
	if (mutex_lock_interruptible(&fan_mutex))
3414
	case TPACPI_FAN_RD_ACPI_GFAN:
4836
		return -ERESTARTSYS;
3415
		/* 570, 600e/x, 770e, 770x */
3416
4837
3417
		if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
4838
	switch (fan_control_access_mode) {
3418
			return -EIO;
4839
	case TPACPI_FAN_WR_ACPI_FANS:
4840
	case TPACPI_FAN_WR_TPEC:
4841
		rc = fan_get_status(&s);
4842
		if (rc < 0)
4843
			break;
3419
4844
3420
		if (likely(status))
4845
		/* Don't go out of emergency fan mode */
3421
			*status = s & 0x07;
4846
		if (s != 7) {
4847
			s &= 0x07;
4848
			s |= TP_EC_FAN_AUTO | 4; /* min fan speed 4 */
4849
		}
3422
4850
4851
		if (!acpi_ec_write(fan_status_offset, s))
4852
			rc = -EIO;
4853
		else {
4854
			tp_features.fan_ctrl_status_undef = 0;
4855
			rc = 0;
4856
		}
3423
		break;
4857
		break;
3424
4858
3425
	case TPACPI_FAN_RD_TPEC:
4859
	case TPACPI_FAN_WR_ACPI_SFAN:
3426
		/* all except 570, 600e/x, 770e, 770x */
4860
		rc = fan_get_status(&s);
3427
		if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
4861
		if (rc < 0)
3428
			return -EIO;
4862
			break;
3429
4863
3430
		if (likely(status))
4864
		s &= 0x07;
3431
			*status = s;
4865
4866
		/* Set fan to at least level 4 */
4867
		s |= 4;
3432
4868
4869
		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
4870
			rc = -EIO;
4871
		else
4872
			rc = 0;
3433
		break;
4873
		break;
3434
4874
3435
	default:
4875
	default:
3436
		return -ENXIO;
4876
		rc = -ENXIO;
3437
	}
4877
	}
3438
4878
3439
	return 0;
4879
	mutex_unlock(&fan_mutex);
4880
	return rc;
3440
}
4881
}
3441
4882
3442
static int fan_get_status_safe(u8 *status)
4883
static int fan_set_disable(void)
3443
{
4884
{
3444
	int rc;
4885
	int rc;
3445
	u8 s;
3446
4886
3447
	rc = mutex_lock_interruptible(&fan_mutex);
4887
	if (!fan_control_allowed)
3448
	if (rc < 0)
4888
		return -EPERM;
3449
		return rc;
3450
	rc = fan_get_status(&s);
3451
	if (!rc)
3452
		fan_update_desired_level(s);
3453
	mutex_unlock(&fan_mutex);
3454
4889
3455
	if (status)
4890
	if (mutex_lock_interruptible(&fan_mutex))
3456
		*status = s;
4891
		return -ERESTARTSYS;
3457
4892
3458
	return rc;
4893
	rc = 0;
3459
}
4894
	switch (fan_control_access_mode) {
4895
	case TPACPI_FAN_WR_ACPI_FANS:
4896
	case TPACPI_FAN_WR_TPEC:
4897
		if (!acpi_ec_write(fan_status_offset, 0x00))
4898
			rc = -EIO;
4899
		else {
4900
			fan_control_desired_level = 0;
4901
			tp_features.fan_ctrl_status_undef = 0;
4902
		}
4903
		break;
3460
4904
3461
static void fan_exit(void)
4905
	case TPACPI_FAN_WR_ACPI_SFAN:
3462
{
4906
		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
3463
	vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n");
4907
			rc = -EIO;
4908
		else
4909
			fan_control_desired_level = 0;
4910
		break;
3464
4911
3465
	/* FIXME: can we really do this unconditionally? */
4912
	default:
3466
	sysfs_remove_group(&tpacpi_pdev->dev.kobj, &fan_attr_group);
4913
		rc = -ENXIO;
3467
	driver_remove_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog);
4914
	}
3468
4915
3469
	cancel_delayed_work(&fan_watchdog_task);
4916
3470
	flush_scheduled_work();
4917
	mutex_unlock(&fan_mutex);
4918
	return rc;
3471
}
4919
}
3472
4920
3473
static int fan_get_speed(unsigned int *speed)
4921
static int fan_set_speed(int speed)
3474
{
4922
{
3475
	u8 hi, lo;
4923
	int rc;
3476
4924
3477
	switch (fan_status_access_mode) {
4925
	if (!fan_control_allowed)
3478
	case TPACPI_FAN_RD_TPEC:
4926
		return -EPERM;
3479
		/* all except 570, 600e/x, 770e, 770x */
3480
		if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
3481
			     !acpi_ec_read(fan_rpm_offset + 1, &hi)))
3482
			return -EIO;
3483
4927
3484
		if (likely(speed))
4928
	if (mutex_lock_interruptible(&fan_mutex))
3485
			*speed = (hi << 8) | lo;
4929
		return -ERESTARTSYS;
3486
4930
4931
	rc = 0;
4932
	switch (fan_control_access_mode) {
4933
	case TPACPI_FAN_WR_ACPI_FANS:
4934
		if (speed >= 0 && speed <= 65535) {
4935
			if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
4936
					speed, speed, speed))
4937
				rc = -EIO;
4938
		} else
4939
			rc = -EINVAL;
3487
		break;
4940
		break;
3488
4941
3489
	default:
4942
	default:
3490
		return -ENXIO;
4943
		rc = -ENXIO;
3491
	}
4944
	}
3492
4945
3493
	return 0;
4946
	mutex_unlock(&fan_mutex);
3494
}
4947
	return rc;
3495
3496
static void fan_watchdog_fire(struct work_struct *ignored)
3497
{
3498
	int rc;
3499
3500
	printk(IBM_NOTICE "fan watchdog: enabling fan\n");
3501
	rc = fan_set_enable();
3502
	if (rc < 0) {
3503
		printk(IBM_ERR "fan watchdog: error %d while enabling fan, "
3504
			"will try again later...\n", -rc);
3505
		/* reschedule for later */
3506
		fan_watchdog_reset();
3507
	}
3508
}
4948
}
3509
4949
3510
static void fan_watchdog_reset(void)
4950
static void fan_watchdog_reset(void)
3511
{
4951
{
3512
	static int fan_watchdog_active = 0;
4952
	static int fan_watchdog_active;
3513
4953
3514
	if (fan_control_access_mode == TPACPI_FAN_WR_NONE)
4954
	if (fan_control_access_mode == TPACPI_FAN_WR_NONE)
3515
		return;
4955
		return;
Lines 3517-3720 static void fan_watchdog_reset(void) Link Here
3517
	if (fan_watchdog_active)
4957
	if (fan_watchdog_active)
3518
		cancel_delayed_work(&fan_watchdog_task);
4958
		cancel_delayed_work(&fan_watchdog_task);
3519
4959
3520
	if (fan_watchdog_maxinterval > 0) {
4960
	if (fan_watchdog_maxinterval > 0 &&
4961
	    tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
3521
		fan_watchdog_active = 1;
4962
		fan_watchdog_active = 1;
3522
		if (!schedule_delayed_work(&fan_watchdog_task,
4963
		if (!schedule_delayed_work(&fan_watchdog_task,
3523
				msecs_to_jiffies(fan_watchdog_maxinterval
4964
				msecs_to_jiffies(fan_watchdog_maxinterval
3524
						 * 1000))) {
4965
						 * 1000))) {
3525
			printk(IBM_ERR "failed to schedule the fan watchdog, "
4966
			printk(TPACPI_ERR
4967
			       "failed to schedule the fan watchdog, "
3526
			       "watchdog will not trigger\n");
4968
			       "watchdog will not trigger\n");
3527
		}
4969
		}
3528
	} else
4970
	} else
3529
		fan_watchdog_active = 0;
4971
		fan_watchdog_active = 0;
3530
}
4972
}
3531
4973
3532
static int fan_set_level(int level)
4974
static void fan_watchdog_fire(struct work_struct *ignored)
3533
{
4975
{
3534
	if (!fan_control_allowed)
4976
	int rc;
3535
		return -EPERM;
3536
4977
3537
	switch (fan_control_access_mode) {
4978
	if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
3538
	case TPACPI_FAN_WR_ACPI_SFAN:
4979
		return;
3539
		if (level >= 0 && level <= 7) {
4980
3540
			if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
4981
	printk(TPACPI_NOTICE "fan watchdog: enabling fan\n");
3541
				return -EIO;
4982
	rc = fan_set_enable();
3542
		} else
4983
	if (rc < 0) {
3543
			return -EINVAL;
4984
		printk(TPACPI_ERR "fan watchdog: error %d while enabling fan, "
4985
			"will try again later...\n", -rc);
4986
		/* reschedule for later */
4987
		fan_watchdog_reset();
4988
	}
4989
}
4990
4991
/*
4992
 * SYSFS fan layout: hwmon compatible (device)
4993
 *
4994
 * pwm*_enable:
4995
 * 	0: "disengaged" mode
4996
 * 	1: manual mode
4997
 * 	2: native EC "auto" mode (recommended, hardware default)
4998
 *
4999
 * pwm*: set speed in manual mode, ignored otherwise.
5000
 * 	0 is level 0; 255 is level 7. Intermediate points done with linear
5001
 * 	interpolation.
5002
 *
5003
 * fan*_input: tachometer reading, RPM
5004
 *
5005
 *
5006
 * SYSFS fan layout: extensions
5007
 *
5008
 * fan_watchdog (driver):
5009
 * 	fan watchdog interval in seconds, 0 disables (default), max 120
5010
 */
5011
5012
/* sysfs fan pwm1_enable ----------------------------------------------- */
5013
static ssize_t fan_pwm1_enable_show(struct device *dev,
5014
				    struct device_attribute *attr,
5015
				    char *buf)
5016
{
5017
	int res, mode;
5018
	u8 status;
5019
5020
	res = fan_get_status_safe(&status);
5021
	if (res)
5022
		return res;
5023
5024
	if (unlikely(tp_features.fan_ctrl_status_undef)) {
5025
		if (status != fan_control_initial_status) {
5026
			tp_features.fan_ctrl_status_undef = 0;
5027
		} else {
5028
			/* Return most likely status. In fact, it
5029
			 * might be the only possible status */
5030
			status = TP_EC_FAN_AUTO;
5031
		}
5032
	}
5033
5034
	if (status & TP_EC_FAN_FULLSPEED) {
5035
		mode = 0;
5036
	} else if (status & TP_EC_FAN_AUTO) {
5037
		mode = 2;
5038
	} else
5039
		mode = 1;
5040
5041
	return snprintf(buf, PAGE_SIZE, "%d\n", mode);
5042
}
5043
5044
static ssize_t fan_pwm1_enable_store(struct device *dev,
5045
				     struct device_attribute *attr,
5046
				     const char *buf, size_t count)
5047
{
5048
	unsigned long t;
5049
	int res, level;
5050
5051
	if (parse_strtoul(buf, 2, &t))
5052
		return -EINVAL;
5053
5054
	switch (t) {
5055
	case 0:
5056
		level = TP_EC_FAN_FULLSPEED;
3544
		break;
5057
		break;
5058
	case 1:
5059
		level = TPACPI_FAN_LAST_LEVEL;
5060
		break;
5061
	case 2:
5062
		level = TP_EC_FAN_AUTO;
5063
		break;
5064
	case 3:
5065
		/* reserved for software-controlled auto mode */
5066
		return -ENOSYS;
5067
	default:
5068
		return -EINVAL;
5069
	}
3545
5070
3546
	case TPACPI_FAN_WR_ACPI_FANS:
5071
	res = fan_set_level_safe(level);
3547
	case TPACPI_FAN_WR_TPEC:
5072
	if (res == -ENXIO)
3548
		if ((level != TP_EC_FAN_AUTO) &&
5073
		return -EINVAL;
3549
		    (level != TP_EC_FAN_FULLSPEED) &&
5074
	else if (res < 0)
3550
		    ((level < 0) || (level > 7)))
5075
		return res;
3551
			return -EINVAL;
5076
5077
	fan_watchdog_reset();
5078
5079
	return count;
5080
}
5081
5082
static struct device_attribute dev_attr_fan_pwm1_enable =
5083
	__ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
5084
		fan_pwm1_enable_show, fan_pwm1_enable_store);
3552
5085
3553
		/* safety net should the EC not support AUTO
5086
/* sysfs fan pwm1 ------------------------------------------------------ */
3554
		 * or FULLSPEED mode bits and just ignore them */
5087
static ssize_t fan_pwm1_show(struct device *dev,
3555
		if (level & TP_EC_FAN_FULLSPEED)
5088
			     struct device_attribute *attr,
3556
			level |= 7;	/* safety min speed 7 */
5089
			     char *buf)
3557
		else if (level & TP_EC_FAN_FULLSPEED)
5090
{
3558
			level |= 4;	/* safety min speed 4 */
5091
	int res;
5092
	u8 status;
3559
5093
3560
		if (!acpi_ec_write(fan_status_offset, level))
5094
	res = fan_get_status_safe(&status);
3561
			return -EIO;
5095
	if (res)
3562
		else
5096
		return res;
3563
			tp_features.fan_ctrl_status_undef = 0;
3564
		break;
3565
5097
3566
	default:
5098
	if (unlikely(tp_features.fan_ctrl_status_undef)) {
3567
		return -ENXIO;
5099
		if (status != fan_control_initial_status) {
5100
			tp_features.fan_ctrl_status_undef = 0;
5101
		} else {
5102
			status = TP_EC_FAN_AUTO;
5103
		}
3568
	}
5104
	}
3569
	return 0;
5105
5106
	if ((status &
5107
	     (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)
5108
		status = fan_control_desired_level;
5109
5110
	if (status > 7)
5111
		status = 7;
5112
5113
	return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7);
3570
}
5114
}
3571
5115
3572
static int fan_set_level_safe(int level)
5116
static ssize_t fan_pwm1_store(struct device *dev,
5117
			      struct device_attribute *attr,
5118
			      const char *buf, size_t count)
3573
{
5119
{
5120
	unsigned long s;
3574
	int rc;
5121
	int rc;
5122
	u8 status, newlevel;
3575
5123
3576
	if (!fan_control_allowed)
5124
	if (parse_strtoul(buf, 255, &s))
3577
		return -EPERM;
5125
		return -EINVAL;
3578
5126
3579
	rc = mutex_lock_interruptible(&fan_mutex);
5127
	/* scale down from 0-255 to 0-7 */
3580
	if (rc < 0)
5128
	newlevel = (s >> 5) & 0x07;
3581
		return rc;
3582
5129
3583
	if (level == TPACPI_FAN_LAST_LEVEL)
5130
	if (mutex_lock_interruptible(&fan_mutex))
3584
		level = fan_control_desired_level;
5131
		return -ERESTARTSYS;
3585
5132
3586
	rc = fan_set_level(level);
5133
	rc = fan_get_status(&status);
3587
	if (!rc)
5134
	if (!rc && (status &
3588
		fan_update_desired_level(level);
5135
		    (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
5136
		rc = fan_set_level(newlevel);
5137
		if (rc == -ENXIO)
5138
			rc = -EINVAL;
5139
		else if (!rc) {
5140
			fan_update_desired_level(newlevel);
5141
			fan_watchdog_reset();
5142
		}
5143
	}
3589
5144
3590
	mutex_unlock(&fan_mutex);
5145
	mutex_unlock(&fan_mutex);
3591
	return rc;
5146
	return (rc)? rc : count;
3592
}
5147
}
3593
5148
3594
static int fan_set_enable(void)
5149
static struct device_attribute dev_attr_fan_pwm1 =
5150
	__ATTR(pwm1, S_IWUSR | S_IRUGO,
5151
		fan_pwm1_show, fan_pwm1_store);
5152
5153
/* sysfs fan fan1_input ------------------------------------------------ */
5154
static ssize_t fan_fan1_input_show(struct device *dev,
5155
			   struct device_attribute *attr,
5156
			   char *buf)
3595
{
5157
{
3596
	u8 s;
5158
	int res;
3597
	int rc;
5159
	unsigned int speed;
3598
5160
3599
	if (!fan_control_allowed)
5161
	res = fan_get_speed(&speed);
3600
		return -EPERM;
5162
	if (res < 0)
5163
		return res;
3601
5164
3602
	rc = mutex_lock_interruptible(&fan_mutex);
5165
	return snprintf(buf, PAGE_SIZE, "%u\n", speed);
3603
	if (rc < 0)
5166
}
3604
		return rc;
3605
5167
3606
	switch (fan_control_access_mode) {
5168
static struct device_attribute dev_attr_fan_fan1_input =
3607
	case TPACPI_FAN_WR_ACPI_FANS:
5169
	__ATTR(fan1_input, S_IRUGO,
3608
	case TPACPI_FAN_WR_TPEC:
5170
		fan_fan1_input_show, NULL);
3609
		rc = fan_get_status(&s);
3610
		if (rc < 0)
3611
			break;
3612
5171
3613
		/* Don't go out of emergency fan mode */
5172
/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
3614
		if (s != 7) {
5173
static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
3615
			s &= 0x07;
5174
				     char *buf)
3616
			s |= TP_EC_FAN_AUTO | 4; /* min fan speed 4 */
5175
{
3617
		}
5176
	return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval);
5177
}
3618
5178
3619
		if (!acpi_ec_write(fan_status_offset, s))
5179
static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
3620
			rc = -EIO;
5180
				      const char *buf, size_t count)
3621
		else {
5181
{
3622
			tp_features.fan_ctrl_status_undef = 0;
5182
	unsigned long t;
3623
			rc = 0;
3624
		}
3625
		break;
3626
5183
3627
	case TPACPI_FAN_WR_ACPI_SFAN:
5184
	if (parse_strtoul(buf, 120, &t))
3628
		rc = fan_get_status(&s);
5185
		return -EINVAL;
3629
		if (rc < 0)
3630
			break;
3631
5186
3632
		s &= 0x07;
5187
	if (!fan_control_allowed)
5188
		return -EPERM;
3633
5189
3634
		/* Set fan to at least level 4 */
5190
	fan_watchdog_maxinterval = t;
3635
		s |= 4;
5191
	fan_watchdog_reset();
3636
5192
3637
		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
5193
	return count;
3638
			rc= -EIO;
5194
}
3639
		else
3640
			rc = 0;
3641
		break;
3642
5195
3643
	default:
5196
static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
3644
		rc = -ENXIO;
5197
		fan_fan_watchdog_show, fan_fan_watchdog_store);
3645
	}
3646
5198
3647
	mutex_unlock(&fan_mutex);
5199
/* --------------------------------------------------------------------- */
3648
	return rc;
5200
static struct attribute *fan_attributes[] = {
3649
}
5201
	&dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
5202
	&dev_attr_fan_fan1_input.attr,
5203
	NULL
5204
};
3650
5205
3651
static int fan_set_disable(void)
5206
static const struct attribute_group fan_attr_group = {
5207
	.attrs = fan_attributes,
5208
};
5209
5210
static int __init fan_init(struct ibm_init_struct *iibm)
3652
{
5211
{
3653
	int rc;
5212
	int rc;
3654
5213
3655
	if (!fan_control_allowed)
5214
	vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
3656
		return -EPERM;
3657
5215
3658
	rc = mutex_lock_interruptible(&fan_mutex);
5216
	mutex_init(&fan_mutex);
3659
	if (rc < 0)
5217
	fan_status_access_mode = TPACPI_FAN_NONE;
3660
		return rc;
5218
	fan_control_access_mode = TPACPI_FAN_WR_NONE;
5219
	fan_control_commands = 0;
5220
	fan_watchdog_maxinterval = 0;
5221
	tp_features.fan_ctrl_status_undef = 0;
5222
	fan_control_desired_level = 7;
3661
5223
3662
	rc = 0;
5224
	TPACPI_ACPIHANDLE_INIT(fans);
3663
	switch (fan_control_access_mode) {
5225
	TPACPI_ACPIHANDLE_INIT(gfan);
3664
	case TPACPI_FAN_WR_ACPI_FANS:
5226
	TPACPI_ACPIHANDLE_INIT(sfan);
3665
	case TPACPI_FAN_WR_TPEC:
5227
3666
		if (!acpi_ec_write(fan_status_offset, 0x00))
5228
	if (gfan_handle) {
3667
			rc = -EIO;
5229
		/* 570, 600e/x, 770e, 770x */
3668
		else {
5230
		fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
3669
			fan_control_desired_level = 0;
5231
	} else {
3670
			tp_features.fan_ctrl_status_undef = 0;
5232
		/* all other ThinkPads: note that even old-style
5233
		 * ThinkPad ECs supports the fan control register */
5234
		if (likely(acpi_ec_read(fan_status_offset,
5235
					&fan_control_initial_status))) {
5236
			fan_status_access_mode = TPACPI_FAN_RD_TPEC;
5237
5238
			/* In some ThinkPads, neither the EC nor the ACPI
5239
			 * DSDT initialize the fan status, and it ends up
5240
			 * being set to 0x07 when it *could* be either
5241
			 * 0x07 or 0x80.
5242
			 *
5243
			 * Enable for TP-1Y (T43), TP-78 (R51e),
5244
			 * TP-76 (R52), TP-70 (T43, R52), which are known
5245
			 * to be buggy. */
5246
			if (fan_control_initial_status == 0x07) {
5247
				switch (thinkpad_id.ec_model) {
5248
				case 0x5931: /* TP-1Y */
5249
				case 0x3837: /* TP-78 */
5250
				case 0x3637: /* TP-76 */
5251
				case 0x3037: /* TP-70 */
5252
					printk(TPACPI_NOTICE
5253
					       "fan_init: initial fan status "
5254
					       "is unknown, assuming it is "
5255
					       "in auto mode\n");
5256
					tp_features.fan_ctrl_status_undef = 1;
5257
					;;
5258
				}
5259
			}
5260
		} else {
5261
			printk(TPACPI_ERR
5262
			       "ThinkPad ACPI EC access misbehaving, "
5263
			       "fan status and control unavailable\n");
5264
			return 1;
3671
		}
5265
		}
3672
		break;
5266
	}
3673
5267
3674
	case TPACPI_FAN_WR_ACPI_SFAN:
5268
	if (sfan_handle) {
3675
		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
5269
		/* 570, 770x-JL */
3676
			rc = -EIO;
5270
		fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN;
3677
		else
5271
		fan_control_commands |=
3678
			fan_control_desired_level = 0;
5272
		    TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE;
3679
		break;
5273
	} else {
5274
		if (!gfan_handle) {
5275
			/* gfan without sfan means no fan control */
5276
			/* all other models implement TP EC 0x2f control */
3680
5277
3681
	default:
5278
			if (fans_handle) {
3682
		rc = -ENXIO;
5279
				/* X31, X40, X41 */
5280
				fan_control_access_mode =
5281
				    TPACPI_FAN_WR_ACPI_FANS;
5282
				fan_control_commands |=
5283
				    TPACPI_FAN_CMD_SPEED |
5284
				    TPACPI_FAN_CMD_LEVEL |
5285
				    TPACPI_FAN_CMD_ENABLE;
5286
			} else {
5287
				fan_control_access_mode = TPACPI_FAN_WR_TPEC;
5288
				fan_control_commands |=
5289
				    TPACPI_FAN_CMD_LEVEL |
5290
				    TPACPI_FAN_CMD_ENABLE;
5291
			}
5292
		}
3683
	}
5293
	}
3684
5294
5295
	vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
5296
		str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
5297
		  fan_control_access_mode != TPACPI_FAN_WR_NONE),
5298
		fan_status_access_mode, fan_control_access_mode);
3685
5299
3686
	mutex_unlock(&fan_mutex);
5300
	/* fan control master switch */
3687
	return rc;
5301
	if (!fan_control_allowed) {
5302
		fan_control_access_mode = TPACPI_FAN_WR_NONE;
5303
		fan_control_commands = 0;
5304
		dbg_printk(TPACPI_DBG_INIT,
5305
			   "fan control features disabled by parameter\n");
5306
	}
5307
5308
	/* update fan_control_desired_level */
5309
	if (fan_status_access_mode != TPACPI_FAN_NONE)
5310
		fan_get_status_safe(NULL);
5311
5312
	if (fan_status_access_mode != TPACPI_FAN_NONE ||
5313
	    fan_control_access_mode != TPACPI_FAN_WR_NONE) {
5314
		rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
5315
					 &fan_attr_group);
5316
		if (!(rc < 0))
5317
			rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
5318
					&driver_attr_fan_watchdog);
5319
		if (rc < 0)
5320
			return rc;
5321
		return 0;
5322
	} else
5323
		return 1;
3688
}
5324
}
3689
5325
3690
static int fan_set_speed(int speed)
5326
static void fan_exit(void)
3691
{
5327
{
3692
	int rc;
5328
	vdbg_printk(TPACPI_DBG_EXIT,
3693
5329
		    "cancelling any pending fan watchdog tasks\n");
3694
	if (!fan_control_allowed)
3695
		return -EPERM;
3696
3697
	rc = mutex_lock_interruptible(&fan_mutex);
3698
	if (rc < 0)
3699
		return rc;
3700
3701
	rc = 0;
3702
	switch (fan_control_access_mode) {
3703
	case TPACPI_FAN_WR_ACPI_FANS:
3704
		if (speed >= 0 && speed <= 65535) {
3705
			if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
3706
					speed, speed, speed))
3707
				rc = -EIO;
3708
		} else
3709
			rc = -EINVAL;
3710
		break;
3711
5330
3712
	default:
5331
	/* FIXME: can we really do this unconditionally? */
3713
		rc = -ENXIO;
5332
	sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
3714
	}
5333
	driver_remove_file(&tpacpi_hwmon_pdriver.driver,
5334
			   &driver_attr_fan_watchdog);
3715
5335
3716
	mutex_unlock(&fan_mutex);
5336
	cancel_delayed_work(&fan_watchdog_task);
3717
	return rc;
5337
	flush_scheduled_work();
3718
}
5338
}
3719
5339
3720
static int fan_read(char *p)
5340
static int fan_read(char *p)
Lines 3727-3733 static int fan_read(char *p) Link Here
3727
	switch (fan_status_access_mode) {
5347
	switch (fan_status_access_mode) {
3728
	case TPACPI_FAN_RD_ACPI_GFAN:
5348
	case TPACPI_FAN_RD_ACPI_GFAN:
3729
		/* 570, 600e/x, 770e, 770x */
5349
		/* 570, 600e/x, 770e, 770x */
3730
		if ((rc = fan_get_status_safe(&status)) < 0)
5350
		rc = fan_get_status_safe(&status);
5351
		if (rc < 0)
3731
			return rc;
5352
			return rc;
3732
5353
3733
		len += sprintf(p + len, "status:\t\t%s\n"
5354
		len += sprintf(p + len, "status:\t\t%s\n"
Lines 3737-3743 static int fan_read(char *p) Link Here
3737
5358
3738
	case TPACPI_FAN_RD_TPEC:
5359
	case TPACPI_FAN_RD_TPEC:
3739
		/* all except 570, 600e/x, 770e, 770x */
5360
		/* all except 570, 600e/x, 770e, 770x */
3740
		if ((rc = fan_get_status_safe(&status)) < 0)
5361
		rc = fan_get_status_safe(&status);
5362
		if (rc < 0)
3741
			return rc;
5363
			return rc;
3742
5364
3743
		if (unlikely(tp_features.fan_ctrl_status_undef)) {
5365
		if (unlikely(tp_features.fan_ctrl_status_undef)) {
Lines 3752-3758 static int fan_read(char *p) Link Here
3752
		len += sprintf(p + len, "status:\t\t%s\n",
5374
		len += sprintf(p + len, "status:\t\t%s\n",
3753
			       (status != 0) ? "enabled" : "disabled");
5375
			       (status != 0) ? "enabled" : "disabled");
3754
5376
3755
		if ((rc = fan_get_speed(&speed)) < 0)
5377
		rc = fan_get_speed(&speed);
5378
		if (rc < 0)
3756
			return rc;
5379
			return rc;
3757
5380
3758
		len += sprintf(p + len, "speed:\t\t%d\n", speed);
5381
		len += sprintf(p + len, "speed:\t\t%d\n", speed);
Lines 3788-3795 static int fan_read(char *p) Link Here
3788
5411
3789
	if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
5412
	if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
3790
		len += sprintf(p + len, "commands:\tenable, disable\n"
5413
		len += sprintf(p + len, "commands:\tenable, disable\n"
3791
			       "commands:\twatchdog <timeout> (<timeout> is 0 (off), "
5414
			       "commands:\twatchdog <timeout> (<timeout> "
3792
			       "1-120 (seconds))\n");
5415
			       "is 0 (off), 1-120 (seconds))\n");
3793
5416
3794
	if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
5417
	if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
3795
		len += sprintf(p + len, "commands:\tspeed <speed>"
5418
		len += sprintf(p + len, "commands:\tspeed <speed>"
Lines 3805-3817 static int fan_write_cmd_level(const cha Link Here
3805
	if (strlencmp(cmd, "level auto") == 0)
5428
	if (strlencmp(cmd, "level auto") == 0)
3806
		level = TP_EC_FAN_AUTO;
5429
		level = TP_EC_FAN_AUTO;
3807
	else if ((strlencmp(cmd, "level disengaged") == 0) |
5430
	else if ((strlencmp(cmd, "level disengaged") == 0) |
3808
	         (strlencmp(cmd, "level full-speed") == 0))
5431
			(strlencmp(cmd, "level full-speed") == 0))
3809
		level = TP_EC_FAN_FULLSPEED;
5432
		level = TP_EC_FAN_FULLSPEED;
3810
	else if (sscanf(cmd, "level %d", &level) != 1)
5433
	else if (sscanf(cmd, "level %d", &level) != 1)
3811
		return 0;
5434
		return 0;
3812
5435
3813
	if ((*rc = fan_set_level_safe(level)) == -ENXIO)
5436
	*rc = fan_set_level_safe(level);
3814
		printk(IBM_ERR "level command accepted for unsupported "
5437
	if (*rc == -ENXIO)
5438
		printk(TPACPI_ERR "level command accepted for unsupported "
3815
		       "access mode %d", fan_control_access_mode);
5439
		       "access mode %d", fan_control_access_mode);
3816
5440
3817
	return 1;
5441
	return 1;
Lines 3822-3829 static int fan_write_cmd_enable(const ch Link Here
3822
	if (strlencmp(cmd, "enable") != 0)
5446
	if (strlencmp(cmd, "enable") != 0)
3823
		return 0;
5447
		return 0;
3824
5448
3825
	if ((*rc = fan_set_enable()) == -ENXIO)
5449
	*rc = fan_set_enable();
3826
		printk(IBM_ERR "enable command accepted for unsupported "
5450
	if (*rc == -ENXIO)
5451
		printk(TPACPI_ERR "enable command accepted for unsupported "
3827
		       "access mode %d", fan_control_access_mode);
5452
		       "access mode %d", fan_control_access_mode);
3828
5453
3829
	return 1;
5454
	return 1;
Lines 3834-3841 static int fan_write_cmd_disable(const c Link Here
3834
	if (strlencmp(cmd, "disable") != 0)
5459
	if (strlencmp(cmd, "disable") != 0)
3835
		return 0;
5460
		return 0;
3836
5461
3837
	if ((*rc = fan_set_disable()) == -ENXIO)
5462
	*rc = fan_set_disable();
3838
		printk(IBM_ERR "disable command accepted for unsupported "
5463
	if (*rc == -ENXIO)
5464
		printk(TPACPI_ERR "disable command accepted for unsupported "
3839
		       "access mode %d", fan_control_access_mode);
5465
		       "access mode %d", fan_control_access_mode);
3840
5466
3841
	return 1;
5467
	return 1;
Lines 3851-3858 static int fan_write_cmd_speed(const cha Link Here
3851
	if (sscanf(cmd, "speed %d", &speed) != 1)
5477
	if (sscanf(cmd, "speed %d", &speed) != 1)
3852
		return 0;
5478
		return 0;
3853
5479
3854
	if ((*rc = fan_set_speed(speed)) == -ENXIO)
5480
	*rc = fan_set_speed(speed);
3855
		printk(IBM_ERR "speed command accepted for unsupported "
5481
	if (*rc == -ENXIO)
5482
		printk(TPACPI_ERR "speed command accepted for unsupported "
3856
		       "access mode %d", fan_control_access_mode);
5483
		       "access mode %d", fan_control_access_mode);
3857
5484
3858
	return 1;
5485
	return 1;
Lines 3911-3927 static struct ibm_struct fan_driver_data Link Here
3911
 ****************************************************************************
5538
 ****************************************************************************
3912
 ****************************************************************************/
5539
 ****************************************************************************/
3913
5540
3914
/* /proc support */
5541
/* sysfs name ---------------------------------------------------------- */
3915
static struct proc_dir_entry *proc_dir = NULL;
5542
static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
5543
			   struct device_attribute *attr,
5544
			   char *buf)
5545
{
5546
	return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME);
5547
}
3916
5548
3917
/* Subdriver registry */
5549
static struct device_attribute dev_attr_thinkpad_acpi_pdev_name =
3918
static LIST_HEAD(tpacpi_all_drivers);
5550
	__ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
5551
5552
/* --------------------------------------------------------------------- */
3919
5553
5554
/* /proc support */
5555
static struct proc_dir_entry *proc_dir;
3920
5556
3921
/*
5557
/*
3922
 * Module and infrastructure proble, init and exit handling
5558
 * Module and infrastructure proble, init and exit handling
3923
 */
5559
 */
3924
5560
5561
static int force_load;
5562
3925
#ifdef CONFIG_THINKPAD_ACPI_DEBUG
5563
#ifdef CONFIG_THINKPAD_ACPI_DEBUG
3926
static const char * __init str_supported(int is_supported)
5564
static const char * __init str_supported(int is_supported)
3927
{
5565
{
Lines 3931-3936 static const char * __init str_supported Link Here
3931
}
5569
}
3932
#endif /* CONFIG_THINKPAD_ACPI_DEBUG */
5570
#endif /* CONFIG_THINKPAD_ACPI_DEBUG */
3933
5571
5572
static void ibm_exit(struct ibm_struct *ibm)
5573
{
5574
	dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);
5575
5576
	list_del_init(&ibm->all_drivers);
5577
5578
	if (ibm->flags.acpi_notify_installed) {
5579
		dbg_printk(TPACPI_DBG_EXIT,
5580
			"%s: acpi_remove_notify_handler\n", ibm->name);
5581
		BUG_ON(!ibm->acpi);
5582
		acpi_remove_notify_handler(*ibm->acpi->handle,
5583
					   ibm->acpi->type,
5584
					   dispatch_acpi_notify);
5585
		ibm->flags.acpi_notify_installed = 0;
5586
		ibm->flags.acpi_notify_installed = 0;
5587
	}
5588
5589
	if (ibm->flags.proc_created) {
5590
		dbg_printk(TPACPI_DBG_EXIT,
5591
			"%s: remove_proc_entry\n", ibm->name);
5592
		remove_proc_entry(ibm->name, proc_dir);
5593
		ibm->flags.proc_created = 0;
5594
	}
5595
5596
	if (ibm->flags.acpi_driver_registered) {
5597
		dbg_printk(TPACPI_DBG_EXIT,
5598
			"%s: acpi_bus_unregister_driver\n", ibm->name);
5599
		BUG_ON(!ibm->acpi);
5600
		acpi_bus_unregister_driver(ibm->acpi->driver);
5601
		kfree(ibm->acpi->driver);
5602
		ibm->acpi->driver = NULL;
5603
		ibm->flags.acpi_driver_registered = 0;
5604
	}
5605
5606
	if (ibm->flags.init_called && ibm->exit) {
5607
		ibm->exit();
5608
		ibm->flags.init_called = 0;
5609
	}
5610
5611
	dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name);
5612
}
5613
3934
static int __init ibm_init(struct ibm_init_struct *iibm)
5614
static int __init ibm_init(struct ibm_init_struct *iibm)
3935
{
5615
{
3936
	int ret;
5616
	int ret;
Lines 3967-3973 static int __init ibm_init(struct ibm_in Link Here
3967
		if (ibm->acpi->notify) {
5647
		if (ibm->acpi->notify) {
3968
			ret = setup_acpi_notify(ibm);
5648
			ret = setup_acpi_notify(ibm);
3969
			if (ret == -ENODEV) {
5649
			if (ret == -ENODEV) {
3970
				printk(IBM_NOTICE "disabling subdriver %s\n",
5650
				printk(TPACPI_NOTICE "disabling subdriver %s\n",
3971
					ibm->name);
5651
					ibm->name);
3972
				ret = 0;
5652
				ret = 0;
3973
				goto err_out;
5653
				goto err_out;
Lines 3985-3991 static int __init ibm_init(struct ibm_in Link Here
3985
					  S_IFREG | S_IRUGO | S_IWUSR,
5665
					  S_IFREG | S_IRUGO | S_IWUSR,
3986
					  proc_dir);
5666
					  proc_dir);
3987
		if (!entry) {
5667
		if (!entry) {
3988
			printk(IBM_ERR "unable to create proc entry %s\n",
5668
			printk(TPACPI_ERR "unable to create proc entry %s\n",
3989
			       ibm->name);
5669
			       ibm->name);
3990
			ret = -ENODEV;
5670
			ret = -ENODEV;
3991
			goto err_out;
5671
			goto err_out;
Lines 4011-4067 err_out: Link Here
4011
	return (ret < 0)? ret : 0;
5691
	return (ret < 0)? ret : 0;
4012
}
5692
}
4013
5693
4014
static void ibm_exit(struct ibm_struct *ibm)
4015
{
4016
	dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);
4017
4018
	list_del_init(&ibm->all_drivers);
4019
4020
	if (ibm->flags.acpi_notify_installed) {
4021
		dbg_printk(TPACPI_DBG_EXIT,
4022
			"%s: acpi_remove_notify_handler\n", ibm->name);
4023
		BUG_ON(!ibm->acpi);
4024
		acpi_remove_notify_handler(*ibm->acpi->handle,
4025
					   ibm->acpi->type,
4026
					   dispatch_acpi_notify);
4027
		ibm->flags.acpi_notify_installed = 0;
4028
		ibm->flags.acpi_notify_installed = 0;
4029
	}
4030
4031
	if (ibm->flags.proc_created) {
4032
		dbg_printk(TPACPI_DBG_EXIT,
4033
			"%s: remove_proc_entry\n", ibm->name);
4034
		remove_proc_entry(ibm->name, proc_dir);
4035
		ibm->flags.proc_created = 0;
4036
	}
4037
4038
	if (ibm->flags.acpi_driver_registered) {
4039
		dbg_printk(TPACPI_DBG_EXIT,
4040
			"%s: acpi_bus_unregister_driver\n", ibm->name);
4041
		BUG_ON(!ibm->acpi);
4042
		acpi_bus_unregister_driver(ibm->acpi->driver);
4043
		kfree(ibm->acpi->driver);
4044
		ibm->acpi->driver = NULL;
4045
		ibm->flags.acpi_driver_registered = 0;
4046
	}
4047
4048
	if (ibm->flags.init_called && ibm->exit) {
4049
		ibm->exit();
4050
		ibm->flags.init_called = 0;
4051
	}
4052
4053
	dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name);
4054
}
4055
4056
/* Probing */
5694
/* Probing */
4057
5695
4058
static char *ibm_thinkpad_ec_found = NULL;
5696
static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
4059
4060
static char* __init check_dmi_for_ec(void)
4061
{
5697
{
4062
	struct dmi_device *dev = NULL;
5698
	struct dmi_device *dev = NULL;
4063
	char ec_fw_string[18];
5699
	char ec_fw_string[18];
4064
5700
5701
	if (!tp)
5702
		return;
5703
5704
	memset(tp, 0, sizeof(*tp));
5705
5706
	if (dmi_name_in_vendors("IBM"))
5707
		tp->vendor = PCI_VENDOR_ID_IBM;
5708
	else if (dmi_name_in_vendors("LENOVO"))
5709
		tp->vendor = PCI_VENDOR_ID_LENOVO;
5710
	else
5711
		return;
5712
5713
	tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION),
5714
					GFP_KERNEL);
5715
	if (!tp->bios_version_str)
5716
		return;
5717
	tp->bios_model = tp->bios_version_str[0]
5718
			 | (tp->bios_version_str[1] << 8);
5719
4065
	/*
5720
	/*
4066
	 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
5721
	 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
4067
	 * X32 or newer, all Z series;  Some models must have an
5722
	 * X32 or newer, all Z series;  Some models must have an
Lines 4075-4084 static char* __init check_dmi_for_ec(voi Link Here
4075
			   ec_fw_string) == 1) {
5730
			   ec_fw_string) == 1) {
4076
			ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
5731
			ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
4077
			ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
5732
			ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
4078
			return kstrdup(ec_fw_string, GFP_KERNEL);
5733
5734
			tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
5735
			tp->ec_model = ec_fw_string[0]
5736
					| (ec_fw_string[1] << 8);
5737
			break;
4079
		}
5738
		}
4080
	}
5739
	}
4081
	return NULL;
5740
5741
	tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
5742
					GFP_KERNEL);
5743
	if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
5744
		kfree(tp->model_str);
5745
		tp->model_str = NULL;
5746
	}
4082
}
5747
}
4083
5748
4084
static int __init probe_for_thinkpad(void)
5749
static int __init probe_for_thinkpad(void)
Lines 4092-4104 static int __init probe_for_thinkpad(voi Link Here
4092
	 * Non-ancient models have better DMI tagging, but very old models
5757
	 * Non-ancient models have better DMI tagging, but very old models
4093
	 * don't.
5758
	 * don't.
4094
	 */
5759
	 */
4095
	is_thinkpad = dmi_name_in_vendors("ThinkPad");
5760
	is_thinkpad = (thinkpad_id.model_str != NULL);
4096
5761
4097
	/* ec is required because many other handles are relative to it */
5762
	/* ec is required because many other handles are relative to it */
4098
	IBM_ACPIHANDLE_INIT(ec);
5763
	TPACPI_ACPIHANDLE_INIT(ec);
4099
	if (!ec_handle) {
5764
	if (!ec_handle) {
4100
		if (is_thinkpad)
5765
		if (is_thinkpad)
4101
			printk(IBM_ERR
5766
			printk(TPACPI_ERR
4102
				"Not yet supported ThinkPad detected!\n");
5767
				"Not yet supported ThinkPad detected!\n");
4103
		return -ENODEV;
5768
		return -ENODEV;
4104
	}
5769
	}
Lines 4108-4114 static int __init probe_for_thinkpad(voi Link Here
4108
	 * false positives a damn great deal
5773
	 * false positives a damn great deal
4109
	 */
5774
	 */
4110
	if (!is_thinkpad)
5775
	if (!is_thinkpad)
4111
		is_thinkpad = dmi_name_in_vendors("IBM");
5776
		is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
4112
5777
4113
	if (!is_thinkpad && !force_load)
5778
	if (!is_thinkpad && !force_load)
4114
		return -ENODEV;
5779
		return -ENODEV;
Lines 4197-4205 static int __init set_ibm_param(const ch Link Here
4197
	unsigned int i;
5862
	unsigned int i;
4198
	struct ibm_struct *ibm;
5863
	struct ibm_struct *ibm;
4199
5864
5865
	if (!kp || !kp->name || !val)
5866
		return -EINVAL;
5867
4200
	for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
5868
	for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
4201
		ibm = ibms_init[i].data;
5869
		ibm = ibms_init[i].data;
4202
		BUG_ON(ibm == NULL);
5870
		WARN_ON(ibm == NULL);
5871
5872
		if (!ibm || !ibm->name)
5873
			continue;
4203
5874
4204
		if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
5875
		if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
4205
			if (strlen(val) > sizeof(ibms_init[i].param) - 2)
5876
			if (strlen(val) > sizeof(ibms_init[i].param) - 2)
Lines 4213-4268 static int __init set_ibm_param(const ch Link Here
4213
	return -EINVAL;
5884
	return -EINVAL;
4214
}
5885
}
4215
5886
4216
static int experimental;
4217
module_param(experimental, int, 0);
5887
module_param(experimental, int, 0);
5888
MODULE_PARM_DESC(experimental,
5889
		 "Enables experimental features when non-zero");
4218
5890
4219
static u32 dbg_level;
4220
module_param_named(debug, dbg_level, uint, 0);
5891
module_param_named(debug, dbg_level, uint, 0);
5892
MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
4221
5893
4222
static int force_load;
5894
module_param(force_load, bool, 0);
4223
module_param(force_load, int, 0);
5895
MODULE_PARM_DESC(force_load,
4224
5896
		 "Attempts to load the driver even on a "
4225
static int fan_control_allowed;
5897
		 "mis-identified ThinkPad when true");
4226
module_param_named(fan_control, fan_control_allowed, int, 0);
5898
4227
5899
module_param_named(fan_control, fan_control_allowed, bool, 0);
4228
#define IBM_PARAM(feature) \
5900
MODULE_PARM_DESC(fan_control,
4229
	module_param_call(feature, set_ibm_param, NULL, NULL, 0)
5901
		 "Enables setting fan parameters features when true");
4230
5902
4231
IBM_PARAM(hotkey);
5903
module_param_named(brightness_mode, brightness_mode, int, 0);
4232
IBM_PARAM(bluetooth);
5904
MODULE_PARM_DESC(brightness_mode,
4233
IBM_PARAM(video);
5905
		 "Selects brightness control strategy: "
4234
IBM_PARAM(light);
5906
		 "0=auto, 1=EC, 2=CMOS, 3=both");
5907
5908
module_param(brightness_enable, uint, 0);
5909
MODULE_PARM_DESC(brightness_enable,
5910
		 "Enables backlight control when 1, disables when 0");
5911
5912
module_param(hotkey_report_mode, uint, 0);
5913
MODULE_PARM_DESC(hotkey_report_mode,
5914
		 "used for backwards compatibility with userspace, "
5915
		 "see documentation");
5916
5917
#define TPACPI_PARAM(feature) \
5918
	module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
5919
	MODULE_PARM_DESC(feature, "Simulates thinkpad-aci procfs command " \
5920
			 "at module load, see documentation")
5921
5922
TPACPI_PARAM(hotkey);
5923
TPACPI_PARAM(bluetooth);
5924
TPACPI_PARAM(video);
5925
TPACPI_PARAM(light);
4235
#ifdef CONFIG_THINKPAD_ACPI_DOCK
5926
#ifdef CONFIG_THINKPAD_ACPI_DOCK
4236
IBM_PARAM(dock);
5927
TPACPI_PARAM(dock);
4237
#endif
5928
#endif
4238
#ifdef CONFIG_THINKPAD_ACPI_BAY
5929
#ifdef CONFIG_THINKPAD_ACPI_BAY
4239
IBM_PARAM(bay);
5930
TPACPI_PARAM(bay);
4240
#endif /* CONFIG_THINKPAD_ACPI_BAY */
5931
#endif /* CONFIG_THINKPAD_ACPI_BAY */
4241
IBM_PARAM(cmos);
5932
TPACPI_PARAM(cmos);
4242
IBM_PARAM(led);
5933
TPACPI_PARAM(led);
4243
IBM_PARAM(beep);
5934
TPACPI_PARAM(beep);
4244
IBM_PARAM(ecdump);
5935
TPACPI_PARAM(ecdump);
4245
IBM_PARAM(brightness);
5936
TPACPI_PARAM(brightness);
4246
IBM_PARAM(volume);
5937
TPACPI_PARAM(volume);
4247
IBM_PARAM(fan);
5938
TPACPI_PARAM(fan);
5939
5940
static void thinkpad_acpi_module_exit(void)
5941
{
5942
	struct ibm_struct *ibm, *itmp;
5943
5944
	tpacpi_lifecycle = TPACPI_LIFE_EXITING;
5945
5946
	list_for_each_entry_safe_reverse(ibm, itmp,
5947
					 &tpacpi_all_drivers,
5948
					 all_drivers) {
5949
		ibm_exit(ibm);
5950
	}
5951
5952
	dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
5953
5954
	if (tpacpi_inputdev) {
5955
		if (tp_features.input_device_registered)
5956
			input_unregister_device(tpacpi_inputdev);
5957
		else
5958
			input_free_device(tpacpi_inputdev);
5959
	}
5960
5961
	if (tpacpi_hwmon)
5962
		hwmon_device_unregister(tpacpi_hwmon);
5963
5964
	if (tp_features.sensors_pdev_attrs_registered)
5965
		device_remove_file(&tpacpi_sensors_pdev->dev,
5966
				   &dev_attr_thinkpad_acpi_pdev_name);
5967
	if (tpacpi_sensors_pdev)
5968
		platform_device_unregister(tpacpi_sensors_pdev);
5969
	if (tpacpi_pdev)
5970
		platform_device_unregister(tpacpi_pdev);
5971
5972
	if (tp_features.sensors_pdrv_attrs_registered)
5973
		tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver);
5974
	if (tp_features.platform_drv_attrs_registered)
5975
		tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
5976
5977
	if (tp_features.sensors_pdrv_registered)
5978
		platform_driver_unregister(&tpacpi_hwmon_pdriver);
5979
5980
	if (tp_features.platform_drv_registered)
5981
		platform_driver_unregister(&tpacpi_pdriver);
5982
5983
	if (proc_dir)
5984
		remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
5985
5986
	kfree(thinkpad_id.bios_version_str);
5987
	kfree(thinkpad_id.ec_version_str);
5988
	kfree(thinkpad_id.model_str);
5989
}
5990
4248
5991
4249
static int __init thinkpad_acpi_module_init(void)
5992
static int __init thinkpad_acpi_module_init(void)
4250
{
5993
{
4251
	int ret, i;
5994
	int ret, i;
4252
5995
5996
	tpacpi_lifecycle = TPACPI_LIFE_INIT;
5997
5998
	/* Parameter checking */
5999
	if (hotkey_report_mode > 2)
6000
		return -EINVAL;
6001
4253
	/* Driver-level probe */
6002
	/* Driver-level probe */
6003
6004
	get_thinkpad_model_data(&thinkpad_id);
4254
	ret = probe_for_thinkpad();
6005
	ret = probe_for_thinkpad();
4255
	if (ret)
6006
	if (ret) {
6007
		thinkpad_acpi_module_exit();
4256
		return ret;
6008
		return ret;
6009
	}
4257
6010
4258
	/* Driver initialization */
6011
	/* Driver initialization */
4259
	ibm_thinkpad_ec_found = check_dmi_for_ec();
4260
	IBM_ACPIHANDLE_INIT(ecrd);
4261
	IBM_ACPIHANDLE_INIT(ecwr);
4262
6012
4263
	proc_dir = proc_mkdir(IBM_PROC_DIR, acpi_root_dir);
6013
	TPACPI_ACPIHANDLE_INIT(ecrd);
6014
	TPACPI_ACPIHANDLE_INIT(ecwr);
6015
6016
	proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);
4264
	if (!proc_dir) {
6017
	if (!proc_dir) {
4265
		printk(IBM_ERR "unable to create proc dir " IBM_PROC_DIR);
6018
		printk(TPACPI_ERR
6019
		       "unable to create proc dir " TPACPI_PROC_DIR);
4266
		thinkpad_acpi_module_exit();
6020
		thinkpad_acpi_module_exit();
4267
		return -ENODEV;
6021
		return -ENODEV;
4268
	}
6022
	}
Lines 4270-4305 static int __init thinkpad_acpi_module_i Link Here
4270
6024
4271
	ret = platform_driver_register(&tpacpi_pdriver);
6025
	ret = platform_driver_register(&tpacpi_pdriver);
4272
	if (ret) {
6026
	if (ret) {
4273
		printk(IBM_ERR "unable to register platform driver\n");
6027
		printk(TPACPI_ERR
6028
		       "unable to register main platform driver\n");
4274
		thinkpad_acpi_module_exit();
6029
		thinkpad_acpi_module_exit();
4275
		return ret;
6030
		return ret;
4276
	}
6031
	}
6032
	tp_features.platform_drv_registered = 1;
6033
6034
	ret = platform_driver_register(&tpacpi_hwmon_pdriver);
6035
	if (ret) {
6036
		printk(TPACPI_ERR
6037
		       "unable to register hwmon platform driver\n");
6038
		thinkpad_acpi_module_exit();
6039
		return ret;
6040
	}
6041
	tp_features.sensors_pdrv_registered = 1;
6042
4277
	ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
6043
	ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
6044
	if (!ret) {
6045
		tp_features.platform_drv_attrs_registered = 1;
6046
		ret = tpacpi_create_driver_attributes(
6047
					&tpacpi_hwmon_pdriver.driver);
6048
	}
4278
	if (ret) {
6049
	if (ret) {
4279
		printk(IBM_ERR "unable to create sysfs driver attributes\n");
6050
		printk(TPACPI_ERR
6051
		       "unable to create sysfs driver attributes\n");
4280
		thinkpad_acpi_module_exit();
6052
		thinkpad_acpi_module_exit();
4281
		return ret;
6053
		return ret;
4282
	}
6054
	}
6055
	tp_features.sensors_pdrv_attrs_registered = 1;
4283
6056
4284
6057
4285
	/* Device initialization */
6058
	/* Device initialization */
4286
	tpacpi_pdev = platform_device_register_simple(IBM_DRVR_NAME, -1,
6059
	tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, -1,
4287
							NULL, 0);
6060
							NULL, 0);
4288
	if (IS_ERR(tpacpi_pdev)) {
6061
	if (IS_ERR(tpacpi_pdev)) {
4289
		ret = PTR_ERR(tpacpi_pdev);
6062
		ret = PTR_ERR(tpacpi_pdev);
4290
		tpacpi_pdev = NULL;
6063
		tpacpi_pdev = NULL;
4291
		printk(IBM_ERR "unable to register platform device\n");
6064
		printk(TPACPI_ERR "unable to register platform device\n");
6065
		thinkpad_acpi_module_exit();
6066
		return ret;
6067
	}
6068
	tpacpi_sensors_pdev = platform_device_register_simple(
6069
						TPACPI_HWMON_DRVR_NAME,
6070
						-1, NULL, 0);
6071
	if (IS_ERR(tpacpi_sensors_pdev)) {
6072
		ret = PTR_ERR(tpacpi_sensors_pdev);
6073
		tpacpi_sensors_pdev = NULL;
6074
		printk(TPACPI_ERR
6075
		       "unable to register hwmon platform device\n");
6076
		thinkpad_acpi_module_exit();
6077
		return ret;
6078
	}
6079
	ret = device_create_file(&tpacpi_sensors_pdev->dev,
6080
				 &dev_attr_thinkpad_acpi_pdev_name);
6081
	if (ret) {
6082
		printk(TPACPI_ERR
6083
		       "unable to create sysfs hwmon device attributes\n");
4292
		thinkpad_acpi_module_exit();
6084
		thinkpad_acpi_module_exit();
4293
		return ret;
6085
		return ret;
4294
	}
6086
	}
4295
	tpacpi_hwmon = hwmon_device_register(&tpacpi_pdev->dev);
6087
	tp_features.sensors_pdev_attrs_registered = 1;
6088
	tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
4296
	if (IS_ERR(tpacpi_hwmon)) {
6089
	if (IS_ERR(tpacpi_hwmon)) {
4297
		ret = PTR_ERR(tpacpi_hwmon);
6090
		ret = PTR_ERR(tpacpi_hwmon);
4298
		tpacpi_hwmon = NULL;
6091
		tpacpi_hwmon = NULL;
4299
		printk(IBM_ERR "unable to register hwmon device\n");
6092
		printk(TPACPI_ERR "unable to register hwmon device\n");
4300
		thinkpad_acpi_module_exit();
6093
		thinkpad_acpi_module_exit();
4301
		return ret;
6094
		return ret;
4302
	}
6095
	}
6096
	mutex_init(&tpacpi_inputdev_send_mutex);
6097
	tpacpi_inputdev = input_allocate_device();
6098
	if (!tpacpi_inputdev) {
6099
		printk(TPACPI_ERR "unable to allocate input device\n");
6100
		thinkpad_acpi_module_exit();
6101
		return -ENOMEM;
6102
	} else {
6103
		/* Prepare input device, but don't register */
6104
		tpacpi_inputdev->name = "ThinkPad Extra Buttons";
6105
		tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";
6106
		tpacpi_inputdev->id.bustype = BUS_HOST;
6107
		tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ?
6108
						thinkpad_id.vendor :
6109
						PCI_VENDOR_ID_IBM;
6110
		tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
6111
		tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
6112
	}
4303
	for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
6113
	for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
4304
		ret = ibm_init(&ibms_init[i]);
6114
		ret = ibm_init(&ibms_init[i]);
4305
		if (ret >= 0 && *ibms_init[i].param)
6115
		if (ret >= 0 && *ibms_init[i].param)
Lines 4309-4344 static int __init thinkpad_acpi_module_i Link Here
4309
			return ret;
6119
			return ret;
4310
		}
6120
		}
4311
	}
6121
	}
6122
	ret = input_register_device(tpacpi_inputdev);
6123
	if (ret < 0) {
6124
		printk(TPACPI_ERR "unable to register input device\n");
6125
		thinkpad_acpi_module_exit();
6126
		return ret;
6127
	} else {
6128
		tp_features.input_device_registered = 1;
6129
	}
4312
6130
6131
	tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
4313
	return 0;
6132
	return 0;
4314
}
6133
}
4315
6134
4316
static void thinkpad_acpi_module_exit(void)
6135
/* Please remove this in year 2009 */
4317
{
6136
MODULE_ALIAS("ibm_acpi");
4318
	struct ibm_struct *ibm, *itmp;
4319
4320
	list_for_each_entry_safe_reverse(ibm, itmp,
4321
					 &tpacpi_all_drivers,
4322
					 all_drivers) {
4323
		ibm_exit(ibm);
4324
	}
4325
4326
	dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
4327
4328
	if (tpacpi_hwmon)
4329
		hwmon_device_unregister(tpacpi_hwmon);
4330
6137
4331
	if (tpacpi_pdev)
6138
/*
4332
		platform_device_unregister(tpacpi_pdev);
6139
 * DMI matching for module autoloading
6140
 *
6141
 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
6142
 * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads
6143
 *
6144
 * Only models listed in thinkwiki will be supported, so add yours
6145
 * if it is not there yet.
6146
 */
6147
#define IBM_BIOS_MODULE_ALIAS(__type) \
6148
	MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW")
4333
6149
4334
	tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
6150
/* Non-ancient thinkpads */
4335
	platform_driver_unregister(&tpacpi_pdriver);
6151
MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
6152
MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
4336
6153
4337
	if (proc_dir)
6154
/* Ancient thinkpad BIOSes have to be identified by
4338
		remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
6155
 * BIOS type or model number, and there are far less
6156
 * BIOS types than model numbers... */
6157
IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]");
6158
IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]");
6159
IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
4339
6160
4340
	kfree(ibm_thinkpad_ec_found);
6161
MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
4341
}
6162
MODULE_DESCRIPTION(TPACPI_DESC);
6163
MODULE_VERSION(TPACPI_VERSION);
6164
MODULE_LICENSE("GPL");
4342
6165
4343
module_init(thinkpad_acpi_module_init);
6166
module_init(thinkpad_acpi_module_init);
4344
module_exit(thinkpad_acpi_module_exit);
6167
module_exit(thinkpad_acpi_module_exit);
(-)linux-2.6.22-SL103_BRANCH/include/linux/pci_ids.h (+2 lines)
Lines 2074-2079 Link Here
2074
#define PCI_DEVICE_ID_ALTIMA_AC9100	0x03ea
2070
#define PCI_DEVICE_ID_ALTIMA_AC9100	0x03ea
2075
#define PCI_DEVICE_ID_ALTIMA_AC1003	0x03eb
2071
#define PCI_DEVICE_ID_ALTIMA_AC1003	0x03eb
2076
2072
2073
#define PCI_VENDOR_ID_LENOVO		0x17aa
2074
2077
#define PCI_VENDOR_ID_ARECA		0x17d3
2075
#define PCI_VENDOR_ID_ARECA		0x17d3
2078
#define PCI_DEVICE_ID_ARECA_1110	0x1110
2076
#define PCI_DEVICE_ID_ARECA_1110	0x1110
2079
#define PCI_DEVICE_ID_ARECA_1120	0x1120
2077
#define PCI_DEVICE_ID_ARECA_1120	0x1120
(-)linux-2.6.22-SL103_BRANCH/drivers/misc/thinkpad_acpi.h (-566 lines)
Lines 1-566 Link Here
1
/*
2
 *  thinkpad_acpi.h - ThinkPad ACPI Extras
3
 *
4
 *
5
 *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
6
 *  Copyright (C) 2006-2007 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program; if not, write to the Free Software
20
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21
 *  02110-1301, USA.
22
 */
23
24
#ifndef __THINKPAD_ACPI_H__
25
#define __THINKPAD_ACPI_H__
26
27
#include <linux/kernel.h>
28
#include <linux/module.h>
29
#include <linux/init.h>
30
#include <linux/types.h>
31
#include <linux/string.h>
32
#include <linux/list.h>
33
#include <linux/mutex.h>
34
35
#include <linux/proc_fs.h>
36
#include <linux/sysfs.h>
37
#include <linux/backlight.h>
38
#include <linux/fb.h>
39
#include <linux/platform_device.h>
40
#include <linux/hwmon.h>
41
#include <linux/hwmon-sysfs.h>
42
#include <asm/uaccess.h>
43
44
#include <linux/dmi.h>
45
#include <linux/jiffies.h>
46
#include <linux/workqueue.h>
47
48
#include <acpi/acpi_drivers.h>
49
#include <acpi/acnamesp.h>
50
51
52
/****************************************************************************
53
 * Main driver
54
 */
55
56
#define IBM_NAME "thinkpad"
57
#define IBM_DESC "ThinkPad ACPI Extras"
58
#define IBM_FILE "thinkpad_acpi"
59
#define IBM_URL "http://ibm-acpi.sf.net/"
60
#define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net"
61
62
#define IBM_PROC_DIR "ibm"
63
#define IBM_ACPI_EVENT_PREFIX "ibm"
64
#define IBM_DRVR_NAME IBM_FILE
65
66
#define IBM_LOG IBM_FILE ": "
67
#define IBM_ERR	   KERN_ERR    IBM_LOG
68
#define IBM_NOTICE KERN_NOTICE IBM_LOG
69
#define IBM_INFO   KERN_INFO   IBM_LOG
70
#define IBM_DEBUG  KERN_DEBUG  IBM_LOG
71
72
#define IBM_MAX_ACPI_ARGS 3
73
74
/* ThinkPad CMOS commands */
75
#define TP_CMOS_VOLUME_DOWN	0
76
#define TP_CMOS_VOLUME_UP	1
77
#define TP_CMOS_VOLUME_MUTE	2
78
#define TP_CMOS_BRIGHTNESS_UP	4
79
#define TP_CMOS_BRIGHTNESS_DOWN	5
80
81
#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
82
#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
83
#define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
84
85
/* Debugging */
86
#define TPACPI_DBG_ALL		0xffff
87
#define TPACPI_DBG_ALL		0xffff
88
#define TPACPI_DBG_INIT		0x0001
89
#define TPACPI_DBG_EXIT		0x0002
90
#define dbg_printk(a_dbg_level, format, arg...) \
91
	do { if (dbg_level & a_dbg_level) \
92
		printk(IBM_DEBUG "%s: " format, __func__ , ## arg); } while (0)
93
#ifdef CONFIG_THINKPAD_ACPI_DEBUG
94
#define vdbg_printk(a_dbg_level, format, arg...) \
95
	dbg_printk(a_dbg_level, format, ## arg)
96
static const char *str_supported(int is_supported);
97
#else
98
#define vdbg_printk(a_dbg_level, format, arg...)
99
#endif
100
101
/* ACPI HIDs */
102
#define IBM_HKEY_HID    "IBM0068"
103
#define IBM_PCI_HID     "PNP0A03"
104
105
/* ACPI helpers */
106
static int __must_check acpi_evalf(acpi_handle handle,
107
		      void *res, char *method, char *fmt, ...);
108
static int __must_check acpi_ec_read(int i, u8 * p);
109
static int __must_check acpi_ec_write(int i, u8 v);
110
static int __must_check _sta(acpi_handle handle);
111
112
/* ACPI handles */
113
static acpi_handle root_handle;			/* root namespace */
114
static acpi_handle ec_handle;			/* EC */
115
static acpi_handle ecrd_handle, ecwr_handle;	/* 570 EC access */
116
static acpi_handle cmos_handle, hkey_handle;	/* basic thinkpad handles */
117
118
static void drv_acpi_handle_init(char *name,
119
		   acpi_handle *handle, acpi_handle parent,
120
		   char **paths, int num_paths, char **path);
121
#define IBM_ACPIHANDLE_INIT(object)						\
122
	drv_acpi_handle_init(#object, &object##_handle, *object##_parent,	\
123
		object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
124
125
/* ThinkPad ACPI helpers */
126
static int issue_thinkpad_cmos_command(int cmos_cmd);
127
128
/* procfs support */
129
static struct proc_dir_entry *proc_dir;
130
131
/* procfs helpers */
132
static int dispatch_procfs_read(char *page, char **start, off_t off,
133
		int count, int *eof, void *data);
134
static int dispatch_procfs_write(struct file *file,
135
		const char __user * userbuf,
136
		unsigned long count, void *data);
137
static char *next_cmd(char **cmds);
138
139
/* sysfs support */
140
struct attribute_set {
141
	unsigned int members, max_members;
142
	struct attribute_group group;
143
};
144
145
static struct attribute_set *create_attr_set(unsigned int max_members,
146
						const char* name);
147
#define destroy_attr_set(_set) \
148
	kfree(_set);
149
static int add_to_attr_set(struct attribute_set* s, struct attribute *attr);
150
static int add_many_to_attr_set(struct attribute_set* s,
151
			struct attribute **attr,
152
			unsigned int count);
153
#define register_attr_set_with_sysfs(_attr_set, _kobj) \
154
	sysfs_create_group(_kobj, &_attr_set->group)
155
static void delete_attr_set(struct attribute_set* s, struct kobject *kobj);
156
157
static int parse_strtoul(const char *buf, unsigned long max,
158
			unsigned long *value);
159
160
/* Device model */
161
static struct platform_device *tpacpi_pdev;
162
static struct class_device *tpacpi_hwmon;
163
static struct platform_driver tpacpi_pdriver;
164
static int tpacpi_create_driver_attributes(struct device_driver *drv);
165
static void tpacpi_remove_driver_attributes(struct device_driver *drv);
166
167
/* Module */
168
static int experimental;
169
static u32 dbg_level;
170
static int force_load;
171
static char *ibm_thinkpad_ec_found;
172
173
static char* check_dmi_for_ec(void);
174
static int thinkpad_acpi_module_init(void);
175
static void thinkpad_acpi_module_exit(void);
176
177
178
/****************************************************************************
179
 * Subdrivers
180
 */
181
182
struct ibm_struct;
183
184
struct tp_acpi_drv_struct {
185
	const struct acpi_device_id *hid;
186
	struct acpi_driver *driver;
187
188
	void (*notify) (struct ibm_struct *, u32);
189
	acpi_handle *handle;
190
	u32 type;
191
	struct acpi_device *device;
192
};
193
194
struct ibm_struct {
195
	char *name;
196
197
	int (*read) (char *);
198
	int (*write) (char *);
199
	void (*exit) (void);
200
201
	struct list_head all_drivers;
202
203
	struct tp_acpi_drv_struct *acpi;
204
205
	struct {
206
		u8 acpi_driver_registered:1;
207
		u8 acpi_notify_installed:1;
208
		u8 proc_created:1;
209
		u8 init_called:1;
210
		u8 experimental:1;
211
	} flags;
212
};
213
214
struct ibm_init_struct {
215
	char param[32];
216
217
	int (*init) (struct ibm_init_struct *);
218
	struct ibm_struct *data;
219
};
220
221
static struct {
222
#ifdef CONFIG_THINKPAD_ACPI_BAY
223
	u16 bay_status:1;
224
	u16 bay_eject:1;
225
	u16 bay_status2:1;
226
	u16 bay_eject2:1;
227
#endif
228
	u16 bluetooth:1;
229
	u16 hotkey:1;
230
	u16 hotkey_mask:1;
231
	u16 light:1;
232
	u16 light_status:1;
233
	u16 wan:1;
234
	u16 fan_ctrl_status_undef:1;
235
} tp_features;
236
237
static struct list_head tpacpi_all_drivers;
238
239
static struct ibm_init_struct ibms_init[];
240
static int set_ibm_param(const char *val, struct kernel_param *kp);
241
static int ibm_init(struct ibm_init_struct *iibm);
242
static void ibm_exit(struct ibm_struct *ibm);
243
244
245
/*
246
 * procfs master subdriver
247
 */
248
static int thinkpad_acpi_driver_init(struct ibm_init_struct *iibm);
249
static int thinkpad_acpi_driver_read(char *p);
250
251
252
/*
253
 * Bay subdriver
254
 */
255
256
#ifdef CONFIG_THINKPAD_ACPI_BAY
257
static acpi_handle bay_handle, bay_ej_handle;
258
static acpi_handle bay2_handle, bay2_ej_handle;
259
260
static int bay_init(struct ibm_init_struct *iibm);
261
static void bay_notify(struct ibm_struct *ibm, u32 event);
262
static int bay_read(char *p);
263
static int bay_write(char *buf);
264
#endif /* CONFIG_THINKPAD_ACPI_BAY */
265
266
267
/*
268
 * Beep subdriver
269
 */
270
271
static acpi_handle beep_handle;
272
273
static int beep_read(char *p);
274
static int beep_write(char *buf);
275
276
277
/*
278
 * Bluetooth subdriver
279
 */
280
281
enum {
282
	/* ACPI GBDC/SBDC bits */
283
	TP_ACPI_BLUETOOTH_HWPRESENT	= 0x01,	/* Bluetooth hw available */
284
	TP_ACPI_BLUETOOTH_RADIOSSW	= 0x02,	/* Bluetooth radio enabled */
285
	TP_ACPI_BLUETOOTH_UNK		= 0x04,	/* unknown function */
286
};
287
288
static int bluetooth_init(struct ibm_init_struct *iibm);
289
static int bluetooth_get_radiosw(void);
290
static int bluetooth_set_radiosw(int radio_on);
291
static int bluetooth_read(char *p);
292
static int bluetooth_write(char *buf);
293
294
295
/*
296
 * Brightness (backlight) subdriver
297
 */
298
299
#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
300
301
static struct backlight_device *ibm_backlight_device;
302
static int brightness_offset = 0x31;
303
304
static int brightness_init(struct ibm_init_struct *iibm);
305
static void brightness_exit(void);
306
static int brightness_get(struct backlight_device *bd);
307
static int brightness_set(int value);
308
static int brightness_update_status(struct backlight_device *bd);
309
static int brightness_read(char *p);
310
static int brightness_write(char *buf);
311
312
313
/*
314
 * CMOS subdriver
315
 */
316
317
static int cmos_read(char *p);
318
static int cmos_write(char *buf);
319
320
321
/*
322
 * Dock subdriver
323
 */
324
325
#ifdef CONFIG_THINKPAD_ACPI_DOCK
326
static acpi_handle pci_handle;
327
static acpi_handle dock_handle;
328
329
static void dock_notify(struct ibm_struct *ibm, u32 event);
330
static int dock_read(char *p);
331
static int dock_write(char *buf);
332
#endif /* CONFIG_THINKPAD_ACPI_DOCK */
333
334
335
/*
336
 * EC dump subdriver
337
 */
338
339
static int ecdump_read(char *p) ;
340
static int ecdump_write(char *buf);
341
342
343
/*
344
 * Fan subdriver
345
 */
346
347
enum {					/* Fan control constants */
348
	fan_status_offset = 0x2f,	/* EC register 0x2f */
349
	fan_rpm_offset = 0x84,		/* EC register 0x84: LSB, 0x85 MSB (RPM)
350
					 * 0x84 must be read before 0x85 */
351
352
	TP_EC_FAN_FULLSPEED = 0x40,	/* EC fan mode: full speed */
353
	TP_EC_FAN_AUTO	    = 0x80,	/* EC fan mode: auto fan control */
354
355
	TPACPI_FAN_LAST_LEVEL = 0x100,	/* Use cached last-seen fan level */
356
};
357
358
enum fan_status_access_mode {
359
	TPACPI_FAN_NONE = 0,		/* No fan status or control */
360
	TPACPI_FAN_RD_ACPI_GFAN,	/* Use ACPI GFAN */
361
	TPACPI_FAN_RD_TPEC,		/* Use ACPI EC regs 0x2f, 0x84-0x85 */
362
};
363
364
enum fan_control_access_mode {
365
	TPACPI_FAN_WR_NONE = 0,		/* No fan control */
366
	TPACPI_FAN_WR_ACPI_SFAN,	/* Use ACPI SFAN */
367
	TPACPI_FAN_WR_TPEC,		/* Use ACPI EC reg 0x2f */
368
	TPACPI_FAN_WR_ACPI_FANS,	/* Use ACPI FANS and EC reg 0x2f */
369
};
370
371
enum fan_control_commands {
372
	TPACPI_FAN_CMD_SPEED 	= 0x0001,	/* speed command */
373
	TPACPI_FAN_CMD_LEVEL 	= 0x0002,	/* level command  */
374
	TPACPI_FAN_CMD_ENABLE	= 0x0004,	/* enable/disable cmd,
375
						 * and also watchdog cmd */
376
};
377
378
static int fan_control_allowed;
379
380
static enum fan_status_access_mode fan_status_access_mode;
381
static enum fan_control_access_mode fan_control_access_mode;
382
static enum fan_control_commands fan_control_commands;
383
static u8 fan_control_initial_status;
384
static u8 fan_control_desired_level;
385
static int fan_watchdog_maxinterval;
386
387
static struct mutex fan_mutex;
388
389
static acpi_handle fans_handle, gfan_handle, sfan_handle;
390
391
static int fan_init(struct ibm_init_struct *iibm);
392
static void fan_exit(void);
393
static int fan_get_status(u8 *status);
394
static int fan_get_status_safe(u8 *status);
395
static int fan_get_speed(unsigned int *speed);
396
static void fan_update_desired_level(u8 status);
397
static void fan_watchdog_fire(struct work_struct *ignored);
398
static void fan_watchdog_reset(void);
399
static int fan_set_level(int level);
400
static int fan_set_level_safe(int level);
401
static int fan_set_enable(void);
402
static int fan_set_disable(void);
403
static int fan_set_speed(int speed);
404
static int fan_read(char *p);
405
static int fan_write(char *buf);
406
static int fan_write_cmd_level(const char *cmd, int *rc);
407
static int fan_write_cmd_enable(const char *cmd, int *rc);
408
static int fan_write_cmd_disable(const char *cmd, int *rc);
409
static int fan_write_cmd_speed(const char *cmd, int *rc);
410
static int fan_write_cmd_watchdog(const char *cmd, int *rc);
411
412
413
/*
414
 * Hotkey subdriver
415
 */
416
417
static int hotkey_orig_status;
418
static int hotkey_orig_mask;
419
420
static struct mutex hotkey_mutex;
421
422
static int hotkey_init(struct ibm_init_struct *iibm);
423
static void hotkey_exit(void);
424
static int hotkey_get(int *status, int *mask);
425
static int hotkey_set(int status, int mask);
426
static void hotkey_notify(struct ibm_struct *ibm, u32 event);
427
static int hotkey_read(char *p);
428
static int hotkey_write(char *buf);
429
430
431
/*
432
 * LED subdriver
433
 */
434
435
enum led_access_mode {
436
	TPACPI_LED_NONE = 0,
437
	TPACPI_LED_570,	/* 570 */
438
	TPACPI_LED_OLD,	/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
439
	TPACPI_LED_NEW,	/* all others */
440
};
441
442
enum {	/* For TPACPI_LED_OLD */
443
	TPACPI_LED_EC_HLCL = 0x0c,	/* EC reg to get led to power on */
444
	TPACPI_LED_EC_HLBL = 0x0d,	/* EC reg to blink a lit led */
445
	TPACPI_LED_EC_HLMS = 0x0e,	/* EC reg to select led to command */
446
};
447
448
static enum led_access_mode led_supported;
449
static acpi_handle led_handle;
450
451
static int led_init(struct ibm_init_struct *iibm);
452
static int led_read(char *p);
453
static int led_write(char *buf);
454
455
/*
456
 * Light (thinklight) subdriver
457
 */
458
459
static acpi_handle lght_handle, ledb_handle;
460
461
static int light_init(struct ibm_init_struct *iibm);
462
static int light_read(char *p);
463
static int light_write(char *buf);
464
465
466
/*
467
 * Thermal subdriver
468
 */
469
470
enum thermal_access_mode {
471
	TPACPI_THERMAL_NONE = 0,	/* No thermal support */
472
	TPACPI_THERMAL_ACPI_TMP07,	/* Use ACPI TMP0-7 */
473
	TPACPI_THERMAL_ACPI_UPDT,	/* Use ACPI TMP0-7 with UPDT */
474
	TPACPI_THERMAL_TPEC_8,		/* Use ACPI EC regs, 8 sensors */
475
	TPACPI_THERMAL_TPEC_16,		/* Use ACPI EC regs, 16 sensors */
476
};
477
478
enum { /* TPACPI_THERMAL_TPEC_* */
479
	TP_EC_THERMAL_TMP0 = 0x78,	/* ACPI EC regs TMP 0..7 */
480
	TP_EC_THERMAL_TMP8 = 0xC0,	/* ACPI EC regs TMP 8..15 */
481
	TP_EC_THERMAL_TMP_NA = -128,	/* ACPI EC sensor not available */
482
};
483
484
#define TPACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
485
struct ibm_thermal_sensors_struct {
486
	s32 temp[TPACPI_MAX_THERMAL_SENSORS];
487
};
488
489
static enum thermal_access_mode thermal_read_mode;
490
491
static int thermal_init(struct ibm_init_struct *iibm);
492
static int thermal_get_sensor(int idx, s32 *value);
493
static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s);
494
static int thermal_read(char *p);
495
496
497
/*
498
 * Video subdriver
499
 */
500
501
enum video_access_mode {
502
	TPACPI_VIDEO_NONE = 0,
503
	TPACPI_VIDEO_570,	/* 570 */
504
	TPACPI_VIDEO_770,	/* 600e/x, 770e, 770x */
505
	TPACPI_VIDEO_NEW,	/* all others */
506
};
507
508
enum {	/* video status flags, based on VIDEO_570 */
509
	TP_ACPI_VIDEO_S_LCD = 0x01,	/* LCD output enabled */
510
	TP_ACPI_VIDEO_S_CRT = 0x02,	/* CRT output enabled */
511
	TP_ACPI_VIDEO_S_DVI = 0x08,	/* DVI output enabled */
512
};
513
514
enum {  /* TPACPI_VIDEO_570 constants */
515
	TP_ACPI_VIDEO_570_PHSCMD = 0x87,	/* unknown magic constant :( */
516
	TP_ACPI_VIDEO_570_PHSMASK = 0x03,	/* PHS bits that map to
517
						 * video_status_flags */
518
	TP_ACPI_VIDEO_570_PHS2CMD = 0x8b,	/* unknown magic constant :( */
519
	TP_ACPI_VIDEO_570_PHS2SET = 0x80,	/* unknown magic constant :( */
520
};
521
522
static enum video_access_mode video_supported;
523
static int video_orig_autosw;
524
static acpi_handle vid_handle, vid2_handle;
525
526
static int video_init(struct ibm_init_struct *iibm);
527
static void video_exit(void);
528
static int video_outputsw_get(void);
529
static int video_outputsw_set(int status);
530
static int video_autosw_get(void);
531
static int video_autosw_set(int enable);
532
static int video_outputsw_cycle(void);
533
static int video_expand_toggle(void);
534
static int video_read(char *p);
535
static int video_write(char *buf);
536
537
538
/*
539
 * Volume subdriver
540
 */
541
542
static int volume_offset = 0x30;
543
544
static int volume_read(char *p);
545
static int volume_write(char *buf);
546
547
548
/*
549
 * Wan subdriver
550
 */
551
552
enum {
553
	/* ACPI GWAN/SWAN bits */
554
	TP_ACPI_WANCARD_HWPRESENT	= 0x01,	/* Wan hw available */
555
	TP_ACPI_WANCARD_RADIOSSW	= 0x02,	/* Wan radio enabled */
556
	TP_ACPI_WANCARD_UNK		= 0x04,	/* unknown function */
557
};
558
559
static int wan_init(struct ibm_init_struct *iibm);
560
static int wan_get_radiosw(void);
561
static int wan_set_radiosw(int radio_on);
562
static int wan_read(char *p);
563
static int wan_write(char *buf);
564
565
566
#endif /* __THINKPAD_ACPI_H */

Return to bug 308264