Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/char/sonypi.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Sony Programmable I/O Control Device driver for VAIO
4
*
5
* Copyright (C) 2007 Mattia Dongili <[email protected]>
6
*
7
* Copyright (C) 2001-2005 Stelian Pop <[email protected]>
8
*
9
* Copyright (C) 2005 Narayanan R S <[email protected]>
10
*
11
* Copyright (C) 2001-2002 AlcĂ´ve <www.alcove.com>
12
*
13
* Copyright (C) 2001 Michael Ashley <[email protected]>
14
*
15
* Copyright (C) 2001 Junichi Morita <[email protected]>
16
*
17
* Copyright (C) 2000 Takaya Kinjo <[email protected]>
18
*
19
* Copyright (C) 2000 Andrew Tridgell <[email protected]>
20
*
21
* Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
22
*/
23
24
#include <linux/module.h>
25
#include <linux/sched.h>
26
#include <linux/input.h>
27
#include <linux/pci.h>
28
#include <linux/init.h>
29
#include <linux/interrupt.h>
30
#include <linux/miscdevice.h>
31
#include <linux/poll.h>
32
#include <linux/delay.h>
33
#include <linux/wait.h>
34
#include <linux/acpi.h>
35
#include <linux/dmi.h>
36
#include <linux/err.h>
37
#include <linux/kfifo.h>
38
#include <linux/platform_device.h>
39
#include <linux/gfp.h>
40
#include <linux/string_choices.h>
41
42
#include <linux/uaccess.h>
43
#include <asm/io.h>
44
45
#include <linux/sonypi.h>
46
47
#define SONYPI_DRIVER_VERSION "1.26"
48
49
MODULE_AUTHOR("Stelian Pop <[email protected]>");
50
MODULE_DESCRIPTION("Sony Programmable I/O Control Device driver");
51
MODULE_LICENSE("GPL");
52
MODULE_VERSION(SONYPI_DRIVER_VERSION);
53
54
static int minor = -1;
55
module_param(minor, int, 0);
56
MODULE_PARM_DESC(minor,
57
"minor number of the misc device, default is -1 (automatic)");
58
59
static int verbose; /* = 0 */
60
module_param(verbose, int, 0644);
61
MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)");
62
63
static int fnkeyinit; /* = 0 */
64
module_param(fnkeyinit, int, 0444);
65
MODULE_PARM_DESC(fnkeyinit,
66
"set this if your Fn keys do not generate any event");
67
68
static int camera; /* = 0 */
69
module_param(camera, int, 0444);
70
MODULE_PARM_DESC(camera,
71
"set this if you have a MotionEye camera (PictureBook series)");
72
73
static int compat; /* = 0 */
74
module_param(compat, int, 0444);
75
MODULE_PARM_DESC(compat,
76
"set this if you want to enable backward compatibility mode");
77
78
static unsigned long mask = 0xffffffff;
79
module_param(mask, ulong, 0644);
80
MODULE_PARM_DESC(mask,
81
"set this to the mask of event you want to enable (see doc)");
82
83
static int useinput = 1;
84
module_param(useinput, int, 0444);
85
MODULE_PARM_DESC(useinput,
86
"set this if you would like sonypi to feed events to the input subsystem");
87
88
static int check_ioport = 1;
89
module_param(check_ioport, int, 0444);
90
MODULE_PARM_DESC(check_ioport,
91
"set this to 0 if you think the automatic ioport check for sony-laptop is wrong");
92
93
#define SONYPI_DEVICE_MODEL_TYPE1 1
94
#define SONYPI_DEVICE_MODEL_TYPE2 2
95
#define SONYPI_DEVICE_MODEL_TYPE3 3
96
97
/* type1 models use those */
98
#define SONYPI_IRQ_PORT 0x8034
99
#define SONYPI_IRQ_SHIFT 22
100
#define SONYPI_TYPE1_BASE 0x50
101
#define SONYPI_G10A (SONYPI_TYPE1_BASE+0x14)
102
#define SONYPI_TYPE1_REGION_SIZE 0x08
103
#define SONYPI_TYPE1_EVTYPE_OFFSET 0x04
104
105
/* type2 series specifics */
106
#define SONYPI_SIRQ 0x9b
107
#define SONYPI_SLOB 0x9c
108
#define SONYPI_SHIB 0x9d
109
#define SONYPI_TYPE2_REGION_SIZE 0x20
110
#define SONYPI_TYPE2_EVTYPE_OFFSET 0x12
111
112
/* type3 series specifics */
113
#define SONYPI_TYPE3_BASE 0x40
114
#define SONYPI_TYPE3_GID2 (SONYPI_TYPE3_BASE+0x48) /* 16 bits */
115
#define SONYPI_TYPE3_MISC (SONYPI_TYPE3_BASE+0x6d) /* 8 bits */
116
#define SONYPI_TYPE3_REGION_SIZE 0x20
117
#define SONYPI_TYPE3_EVTYPE_OFFSET 0x12
118
119
/* battery / brightness addresses */
120
#define SONYPI_BAT_FLAGS 0x81
121
#define SONYPI_LCD_LIGHT 0x96
122
#define SONYPI_BAT1_PCTRM 0xa0
123
#define SONYPI_BAT1_LEFT 0xa2
124
#define SONYPI_BAT1_MAXRT 0xa4
125
#define SONYPI_BAT2_PCTRM 0xa8
126
#define SONYPI_BAT2_LEFT 0xaa
127
#define SONYPI_BAT2_MAXRT 0xac
128
#define SONYPI_BAT1_MAXTK 0xb0
129
#define SONYPI_BAT1_FULL 0xb2
130
#define SONYPI_BAT2_MAXTK 0xb8
131
#define SONYPI_BAT2_FULL 0xba
132
133
/* FAN0 information (reverse engineered from ACPI tables) */
134
#define SONYPI_FAN0_STATUS 0x93
135
#define SONYPI_TEMP_STATUS 0xC1
136
137
/* ioports used for brightness and type2 events */
138
#define SONYPI_DATA_IOPORT 0x62
139
#define SONYPI_CST_IOPORT 0x66
140
141
/* The set of possible ioports */
142
struct sonypi_ioport_list {
143
u16 port1;
144
u16 port2;
145
};
146
147
static struct sonypi_ioport_list sonypi_type1_ioport_list[] = {
148
{ 0x10c0, 0x10c4 }, /* looks like the default on C1Vx */
149
{ 0x1080, 0x1084 },
150
{ 0x1090, 0x1094 },
151
{ 0x10a0, 0x10a4 },
152
{ 0x10b0, 0x10b4 },
153
{ 0x0, 0x0 }
154
};
155
156
static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
157
{ 0x1080, 0x1084 },
158
{ 0x10a0, 0x10a4 },
159
{ 0x10c0, 0x10c4 },
160
{ 0x10e0, 0x10e4 },
161
{ 0x0, 0x0 }
162
};
163
164
/* same as in type 2 models */
165
static struct sonypi_ioport_list *sonypi_type3_ioport_list =
166
sonypi_type2_ioport_list;
167
168
/* The set of possible interrupts */
169
struct sonypi_irq_list {
170
u16 irq;
171
u16 bits;
172
};
173
174
static struct sonypi_irq_list sonypi_type1_irq_list[] = {
175
{ 11, 0x2 }, /* IRQ 11, GO22=0,GO23=1 in AML */
176
{ 10, 0x1 }, /* IRQ 10, GO22=1,GO23=0 in AML */
177
{ 5, 0x0 }, /* IRQ 5, GO22=0,GO23=0 in AML */
178
{ 0, 0x3 } /* no IRQ, GO22=1,GO23=1 in AML */
179
};
180
181
static struct sonypi_irq_list sonypi_type2_irq_list[] = {
182
{ 11, 0x80 }, /* IRQ 11, 0x80 in SIRQ in AML */
183
{ 10, 0x40 }, /* IRQ 10, 0x40 in SIRQ in AML */
184
{ 9, 0x20 }, /* IRQ 9, 0x20 in SIRQ in AML */
185
{ 6, 0x10 }, /* IRQ 6, 0x10 in SIRQ in AML */
186
{ 0, 0x00 } /* no IRQ, 0x00 in SIRQ in AML */
187
};
188
189
/* same as in type2 models */
190
static struct sonypi_irq_list *sonypi_type3_irq_list = sonypi_type2_irq_list;
191
192
#define SONYPI_CAMERA_BRIGHTNESS 0
193
#define SONYPI_CAMERA_CONTRAST 1
194
#define SONYPI_CAMERA_HUE 2
195
#define SONYPI_CAMERA_COLOR 3
196
#define SONYPI_CAMERA_SHARPNESS 4
197
198
#define SONYPI_CAMERA_PICTURE 5
199
#define SONYPI_CAMERA_EXPOSURE_MASK 0xC
200
#define SONYPI_CAMERA_WHITE_BALANCE_MASK 0x3
201
#define SONYPI_CAMERA_PICTURE_MODE_MASK 0x30
202
#define SONYPI_CAMERA_MUTE_MASK 0x40
203
204
/* the rest don't need a loop until not 0xff */
205
#define SONYPI_CAMERA_AGC 6
206
#define SONYPI_CAMERA_AGC_MASK 0x30
207
#define SONYPI_CAMERA_SHUTTER_MASK 0x7
208
209
#define SONYPI_CAMERA_SHUTDOWN_REQUEST 7
210
#define SONYPI_CAMERA_CONTROL 0x10
211
212
#define SONYPI_CAMERA_STATUS 7
213
#define SONYPI_CAMERA_STATUS_READY 0x2
214
#define SONYPI_CAMERA_STATUS_POSITION 0x4
215
216
#define SONYPI_DIRECTION_BACKWARDS 0x4
217
218
#define SONYPI_CAMERA_REVISION 8
219
#define SONYPI_CAMERA_ROMVERSION 9
220
221
/* Event masks */
222
#define SONYPI_JOGGER_MASK 0x00000001
223
#define SONYPI_CAPTURE_MASK 0x00000002
224
#define SONYPI_FNKEY_MASK 0x00000004
225
#define SONYPI_BLUETOOTH_MASK 0x00000008
226
#define SONYPI_PKEY_MASK 0x00000010
227
#define SONYPI_BACK_MASK 0x00000020
228
#define SONYPI_HELP_MASK 0x00000040
229
#define SONYPI_LID_MASK 0x00000080
230
#define SONYPI_ZOOM_MASK 0x00000100
231
#define SONYPI_THUMBPHRASE_MASK 0x00000200
232
#define SONYPI_MEYE_MASK 0x00000400
233
#define SONYPI_MEMORYSTICK_MASK 0x00000800
234
#define SONYPI_BATTERY_MASK 0x00001000
235
#define SONYPI_WIRELESS_MASK 0x00002000
236
237
struct sonypi_event {
238
u8 data;
239
u8 event;
240
};
241
242
/* The set of possible button release events */
243
static struct sonypi_event sonypi_releaseev[] = {
244
{ 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED },
245
{ 0, 0 }
246
};
247
248
/* The set of possible jogger events */
249
static struct sonypi_event sonypi_joggerev[] = {
250
{ 0x1f, SONYPI_EVENT_JOGDIAL_UP },
251
{ 0x01, SONYPI_EVENT_JOGDIAL_DOWN },
252
{ 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED },
253
{ 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED },
254
{ 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP },
255
{ 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN },
256
{ 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED },
257
{ 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED },
258
{ 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP },
259
{ 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN },
260
{ 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED },
261
{ 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED },
262
{ 0x40, SONYPI_EVENT_JOGDIAL_PRESSED },
263
{ 0, 0 }
264
};
265
266
/* The set of possible capture button events */
267
static struct sonypi_event sonypi_captureev[] = {
268
{ 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED },
269
{ 0x07, SONYPI_EVENT_CAPTURE_PRESSED },
270
{ 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED },
271
{ 0, 0 }
272
};
273
274
/* The set of possible fnkeys events */
275
static struct sonypi_event sonypi_fnkeyev[] = {
276
{ 0x10, SONYPI_EVENT_FNKEY_ESC },
277
{ 0x11, SONYPI_EVENT_FNKEY_F1 },
278
{ 0x12, SONYPI_EVENT_FNKEY_F2 },
279
{ 0x13, SONYPI_EVENT_FNKEY_F3 },
280
{ 0x14, SONYPI_EVENT_FNKEY_F4 },
281
{ 0x15, SONYPI_EVENT_FNKEY_F5 },
282
{ 0x16, SONYPI_EVENT_FNKEY_F6 },
283
{ 0x17, SONYPI_EVENT_FNKEY_F7 },
284
{ 0x18, SONYPI_EVENT_FNKEY_F8 },
285
{ 0x19, SONYPI_EVENT_FNKEY_F9 },
286
{ 0x1a, SONYPI_EVENT_FNKEY_F10 },
287
{ 0x1b, SONYPI_EVENT_FNKEY_F11 },
288
{ 0x1c, SONYPI_EVENT_FNKEY_F12 },
289
{ 0x1f, SONYPI_EVENT_FNKEY_RELEASED },
290
{ 0x21, SONYPI_EVENT_FNKEY_1 },
291
{ 0x22, SONYPI_EVENT_FNKEY_2 },
292
{ 0x31, SONYPI_EVENT_FNKEY_D },
293
{ 0x32, SONYPI_EVENT_FNKEY_E },
294
{ 0x33, SONYPI_EVENT_FNKEY_F },
295
{ 0x34, SONYPI_EVENT_FNKEY_S },
296
{ 0x35, SONYPI_EVENT_FNKEY_B },
297
{ 0x36, SONYPI_EVENT_FNKEY_ONLY },
298
{ 0, 0 }
299
};
300
301
/* The set of possible program key events */
302
static struct sonypi_event sonypi_pkeyev[] = {
303
{ 0x01, SONYPI_EVENT_PKEY_P1 },
304
{ 0x02, SONYPI_EVENT_PKEY_P2 },
305
{ 0x04, SONYPI_EVENT_PKEY_P3 },
306
{ 0x5c, SONYPI_EVENT_PKEY_P1 },
307
{ 0, 0 }
308
};
309
310
/* The set of possible bluetooth events */
311
static struct sonypi_event sonypi_blueev[] = {
312
{ 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED },
313
{ 0x59, SONYPI_EVENT_BLUETOOTH_ON },
314
{ 0x5a, SONYPI_EVENT_BLUETOOTH_OFF },
315
{ 0, 0 }
316
};
317
318
/* The set of possible wireless events */
319
static struct sonypi_event sonypi_wlessev[] = {
320
{ 0x59, SONYPI_EVENT_WIRELESS_ON },
321
{ 0x5a, SONYPI_EVENT_WIRELESS_OFF },
322
{ 0, 0 }
323
};
324
325
/* The set of possible back button events */
326
static struct sonypi_event sonypi_backev[] = {
327
{ 0x20, SONYPI_EVENT_BACK_PRESSED },
328
{ 0, 0 }
329
};
330
331
/* The set of possible help button events */
332
static struct sonypi_event sonypi_helpev[] = {
333
{ 0x3b, SONYPI_EVENT_HELP_PRESSED },
334
{ 0, 0 }
335
};
336
337
338
/* The set of possible lid events */
339
static struct sonypi_event sonypi_lidev[] = {
340
{ 0x51, SONYPI_EVENT_LID_CLOSED },
341
{ 0x50, SONYPI_EVENT_LID_OPENED },
342
{ 0, 0 }
343
};
344
345
/* The set of possible zoom events */
346
static struct sonypi_event sonypi_zoomev[] = {
347
{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
348
{ 0, 0 }
349
};
350
351
/* The set of possible thumbphrase events */
352
static struct sonypi_event sonypi_thumbphraseev[] = {
353
{ 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED },
354
{ 0, 0 }
355
};
356
357
/* The set of possible motioneye camera events */
358
static struct sonypi_event sonypi_meyeev[] = {
359
{ 0x00, SONYPI_EVENT_MEYE_FACE },
360
{ 0x01, SONYPI_EVENT_MEYE_OPPOSITE },
361
{ 0, 0 }
362
};
363
364
/* The set of possible memorystick events */
365
static struct sonypi_event sonypi_memorystickev[] = {
366
{ 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT },
367
{ 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT },
368
{ 0, 0 }
369
};
370
371
/* The set of possible battery events */
372
static struct sonypi_event sonypi_batteryev[] = {
373
{ 0x20, SONYPI_EVENT_BATTERY_INSERT },
374
{ 0x30, SONYPI_EVENT_BATTERY_REMOVE },
375
{ 0, 0 }
376
};
377
378
static struct sonypi_eventtypes {
379
int model;
380
u8 data;
381
unsigned long mask;
382
struct sonypi_event * events;
383
} sonypi_eventtypes[] = {
384
{ SONYPI_DEVICE_MODEL_TYPE1, 0, 0xffffffff, sonypi_releaseev },
385
{ SONYPI_DEVICE_MODEL_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
386
{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev },
387
{ SONYPI_DEVICE_MODEL_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
388
{ SONYPI_DEVICE_MODEL_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
389
{ SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
390
{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
391
{ SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
392
{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
393
{ SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
394
395
{ SONYPI_DEVICE_MODEL_TYPE2, 0, 0xffffffff, sonypi_releaseev },
396
{ SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev },
397
{ SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
398
{ SONYPI_DEVICE_MODEL_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
399
{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
400
{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
401
{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
402
{ SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev },
403
{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_HELP_MASK, sonypi_helpev },
404
{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
405
{ SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
406
{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
407
{ SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
408
{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
409
410
{ SONYPI_DEVICE_MODEL_TYPE3, 0, 0xffffffff, sonypi_releaseev },
411
{ SONYPI_DEVICE_MODEL_TYPE3, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
412
{ SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
413
{ SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
414
{ SONYPI_DEVICE_MODEL_TYPE3, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
415
{ SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
416
{ 0 }
417
};
418
419
#define SONYPI_BUF_SIZE 128
420
421
/* Correspondance table between sonypi events and input layer events */
422
static struct {
423
int sonypiev;
424
int inputev;
425
} sonypi_inputkeys[] = {
426
{ SONYPI_EVENT_CAPTURE_PRESSED, KEY_CAMERA },
427
{ SONYPI_EVENT_FNKEY_ONLY, KEY_FN },
428
{ SONYPI_EVENT_FNKEY_ESC, KEY_FN_ESC },
429
{ SONYPI_EVENT_FNKEY_F1, KEY_FN_F1 },
430
{ SONYPI_EVENT_FNKEY_F2, KEY_FN_F2 },
431
{ SONYPI_EVENT_FNKEY_F3, KEY_FN_F3 },
432
{ SONYPI_EVENT_FNKEY_F4, KEY_FN_F4 },
433
{ SONYPI_EVENT_FNKEY_F5, KEY_FN_F5 },
434
{ SONYPI_EVENT_FNKEY_F6, KEY_FN_F6 },
435
{ SONYPI_EVENT_FNKEY_F7, KEY_FN_F7 },
436
{ SONYPI_EVENT_FNKEY_F8, KEY_FN_F8 },
437
{ SONYPI_EVENT_FNKEY_F9, KEY_FN_F9 },
438
{ SONYPI_EVENT_FNKEY_F10, KEY_FN_F10 },
439
{ SONYPI_EVENT_FNKEY_F11, KEY_FN_F11 },
440
{ SONYPI_EVENT_FNKEY_F12, KEY_FN_F12 },
441
{ SONYPI_EVENT_FNKEY_1, KEY_FN_1 },
442
{ SONYPI_EVENT_FNKEY_2, KEY_FN_2 },
443
{ SONYPI_EVENT_FNKEY_D, KEY_FN_D },
444
{ SONYPI_EVENT_FNKEY_E, KEY_FN_E },
445
{ SONYPI_EVENT_FNKEY_F, KEY_FN_F },
446
{ SONYPI_EVENT_FNKEY_S, KEY_FN_S },
447
{ SONYPI_EVENT_FNKEY_B, KEY_FN_B },
448
{ SONYPI_EVENT_BLUETOOTH_PRESSED, KEY_BLUE },
449
{ SONYPI_EVENT_BLUETOOTH_ON, KEY_BLUE },
450
{ SONYPI_EVENT_PKEY_P1, KEY_PROG1 },
451
{ SONYPI_EVENT_PKEY_P2, KEY_PROG2 },
452
{ SONYPI_EVENT_PKEY_P3, KEY_PROG3 },
453
{ SONYPI_EVENT_BACK_PRESSED, KEY_BACK },
454
{ SONYPI_EVENT_HELP_PRESSED, KEY_HELP },
455
{ SONYPI_EVENT_ZOOM_PRESSED, KEY_ZOOM },
456
{ SONYPI_EVENT_THUMBPHRASE_PRESSED, BTN_THUMB },
457
{ 0, 0 },
458
};
459
460
struct sonypi_keypress {
461
struct input_dev *dev;
462
int key;
463
};
464
465
static struct sonypi_device {
466
struct pci_dev *dev;
467
u16 irq;
468
u16 bits;
469
u16 ioport1;
470
u16 ioport2;
471
u16 region_size;
472
u16 evtype_offset;
473
int camera_power;
474
int bluetooth_power;
475
struct mutex lock;
476
struct kfifo fifo;
477
spinlock_t fifo_lock;
478
wait_queue_head_t fifo_proc_list;
479
struct fasync_struct *fifo_async;
480
int open_count;
481
int model;
482
struct input_dev *input_jog_dev;
483
struct input_dev *input_key_dev;
484
struct work_struct input_work;
485
struct kfifo input_fifo;
486
spinlock_t input_fifo_lock;
487
} sonypi_device;
488
489
#define ITERATIONS_LONG 10000
490
#define ITERATIONS_SHORT 10
491
492
#define wait_on_command(quiet, command, iterations) { \
493
unsigned int n = iterations; \
494
while (--n && (command)) \
495
udelay(1); \
496
if (!n && (verbose || !quiet)) \
497
printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __func__, __LINE__); \
498
}
499
500
#ifdef CONFIG_ACPI
501
#define SONYPI_ACPI_ACTIVE (!acpi_disabled)
502
#else
503
#define SONYPI_ACPI_ACTIVE 0
504
#endif /* CONFIG_ACPI */
505
506
#ifdef CONFIG_ACPI
507
static struct acpi_device *sonypi_acpi_device;
508
static int acpi_driver_registered;
509
#endif
510
511
static int sonypi_ec_write(u8 addr, u8 value)
512
{
513
#ifdef CONFIG_ACPI
514
if (SONYPI_ACPI_ACTIVE)
515
return ec_write(addr, value);
516
#endif
517
wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
518
outb_p(0x81, SONYPI_CST_IOPORT);
519
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
520
outb_p(addr, SONYPI_DATA_IOPORT);
521
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
522
outb_p(value, SONYPI_DATA_IOPORT);
523
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
524
return 0;
525
}
526
527
static int sonypi_ec_read(u8 addr, u8 *value)
528
{
529
#ifdef CONFIG_ACPI
530
if (SONYPI_ACPI_ACTIVE)
531
return ec_read(addr, value);
532
#endif
533
wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
534
outb_p(0x80, SONYPI_CST_IOPORT);
535
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
536
outb_p(addr, SONYPI_DATA_IOPORT);
537
wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
538
*value = inb_p(SONYPI_DATA_IOPORT);
539
return 0;
540
}
541
542
static int ec_read16(u8 addr, u16 *value)
543
{
544
u8 val_lb, val_hb;
545
if (sonypi_ec_read(addr, &val_lb))
546
return -1;
547
if (sonypi_ec_read(addr + 1, &val_hb))
548
return -1;
549
*value = val_lb | (val_hb << 8);
550
return 0;
551
}
552
553
/* Initializes the device - this comes from the AML code in the ACPI bios */
554
static void sonypi_type1_srs(void)
555
{
556
u32 v;
557
558
pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
559
v = (v & 0xFFFF0000) | ((u32) sonypi_device.ioport1);
560
pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
561
562
pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
563
v = (v & 0xFFF0FFFF) |
564
(((u32) sonypi_device.ioport1 ^ sonypi_device.ioport2) << 16);
565
pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
566
567
v = inl(SONYPI_IRQ_PORT);
568
v &= ~(((u32) 0x3) << SONYPI_IRQ_SHIFT);
569
v |= (((u32) sonypi_device.bits) << SONYPI_IRQ_SHIFT);
570
outl(v, SONYPI_IRQ_PORT);
571
572
pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
573
v = (v & 0xFF1FFFFF) | 0x00C00000;
574
pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
575
}
576
577
static void sonypi_type2_srs(void)
578
{
579
if (sonypi_ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8))
580
printk(KERN_WARNING "ec_write failed\n");
581
if (sonypi_ec_write(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF))
582
printk(KERN_WARNING "ec_write failed\n");
583
if (sonypi_ec_write(SONYPI_SIRQ, sonypi_device.bits))
584
printk(KERN_WARNING "ec_write failed\n");
585
udelay(10);
586
}
587
588
static void sonypi_type3_srs(void)
589
{
590
u16 v16;
591
u8 v8;
592
593
/* This model type uses the same initialization of
594
* the embedded controller as the type2 models. */
595
sonypi_type2_srs();
596
597
/* Initialization of PCI config space of the LPC interface bridge. */
598
v16 = (sonypi_device.ioport1 & 0xFFF0) | 0x01;
599
pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, v16);
600
pci_read_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, &v8);
601
v8 = (v8 & 0xCF) | 0x10;
602
pci_write_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, v8);
603
}
604
605
/* Disables the device - this comes from the AML code in the ACPI bios */
606
static void sonypi_type1_dis(void)
607
{
608
u32 v;
609
610
pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
611
v = v & 0xFF3FFFFF;
612
pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
613
614
v = inl(SONYPI_IRQ_PORT);
615
v |= (0x3 << SONYPI_IRQ_SHIFT);
616
outl(v, SONYPI_IRQ_PORT);
617
}
618
619
static void sonypi_type2_dis(void)
620
{
621
if (sonypi_ec_write(SONYPI_SHIB, 0))
622
printk(KERN_WARNING "ec_write failed\n");
623
if (sonypi_ec_write(SONYPI_SLOB, 0))
624
printk(KERN_WARNING "ec_write failed\n");
625
if (sonypi_ec_write(SONYPI_SIRQ, 0))
626
printk(KERN_WARNING "ec_write failed\n");
627
}
628
629
static void sonypi_type3_dis(void)
630
{
631
sonypi_type2_dis();
632
udelay(10);
633
pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, 0);
634
}
635
636
static u8 sonypi_call1(u8 dev)
637
{
638
u8 v1, v2;
639
640
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
641
outb(dev, sonypi_device.ioport2);
642
v1 = inb_p(sonypi_device.ioport2);
643
v2 = inb_p(sonypi_device.ioport1);
644
return v2;
645
}
646
647
static u8 sonypi_call2(u8 dev, u8 fn)
648
{
649
u8 v1;
650
651
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
652
outb(dev, sonypi_device.ioport2);
653
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
654
outb(fn, sonypi_device.ioport1);
655
v1 = inb_p(sonypi_device.ioport1);
656
return v1;
657
}
658
659
static u8 sonypi_call3(u8 dev, u8 fn, u8 v)
660
{
661
u8 v1;
662
663
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
664
outb(dev, sonypi_device.ioport2);
665
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
666
outb(fn, sonypi_device.ioport1);
667
wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
668
outb(v, sonypi_device.ioport1);
669
v1 = inb_p(sonypi_device.ioport1);
670
return v1;
671
}
672
673
#if 0
674
/* Get brightness, hue etc. Unreliable... */
675
static u8 sonypi_read(u8 fn)
676
{
677
u8 v1, v2;
678
int n = 100;
679
680
while (n--) {
681
v1 = sonypi_call2(0x8f, fn);
682
v2 = sonypi_call2(0x8f, fn);
683
if (v1 == v2 && v1 != 0xff)
684
return v1;
685
}
686
return 0xff;
687
}
688
#endif
689
690
/* Set brightness, hue etc */
691
static void sonypi_set(u8 fn, u8 v)
692
{
693
wait_on_command(0, sonypi_call3(0x90, fn, v), ITERATIONS_SHORT);
694
}
695
696
/* Tests if the camera is ready */
697
static int sonypi_camera_ready(void)
698
{
699
u8 v;
700
701
v = sonypi_call2(0x8f, SONYPI_CAMERA_STATUS);
702
return (v != 0xff && (v & SONYPI_CAMERA_STATUS_READY));
703
}
704
705
/* Turns the camera off */
706
static void sonypi_camera_off(void)
707
{
708
sonypi_set(SONYPI_CAMERA_PICTURE, SONYPI_CAMERA_MUTE_MASK);
709
710
if (!sonypi_device.camera_power)
711
return;
712
713
sonypi_call2(0x91, 0);
714
sonypi_device.camera_power = 0;
715
}
716
717
/* Turns the camera on */
718
static void sonypi_camera_on(void)
719
{
720
int i, j;
721
722
if (sonypi_device.camera_power)
723
return;
724
725
for (j = 5; j > 0; j--) {
726
727
while (sonypi_call2(0x91, 0x1))
728
msleep(10);
729
sonypi_call1(0x93);
730
731
for (i = 400; i > 0; i--) {
732
if (sonypi_camera_ready())
733
break;
734
msleep(10);
735
}
736
if (i)
737
break;
738
}
739
740
if (j == 0) {
741
printk(KERN_WARNING "sonypi: failed to power on camera\n");
742
return;
743
}
744
745
sonypi_set(0x10, 0x5a);
746
sonypi_device.camera_power = 1;
747
}
748
749
/* sets the bluetooth subsystem power state */
750
static void sonypi_setbluetoothpower(u8 state)
751
{
752
state = !!state;
753
754
if (sonypi_device.bluetooth_power == state)
755
return;
756
757
sonypi_call2(0x96, state);
758
sonypi_call1(0x82);
759
sonypi_device.bluetooth_power = state;
760
}
761
762
static void input_keyrelease(struct work_struct *work)
763
{
764
struct sonypi_keypress kp;
765
766
while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
767
sizeof(kp), &sonypi_device.input_fifo_lock)
768
== sizeof(kp)) {
769
msleep(10);
770
input_report_key(kp.dev, kp.key, 0);
771
input_sync(kp.dev);
772
}
773
}
774
775
static void sonypi_report_input_event(u8 event)
776
{
777
struct input_dev *jog_dev = sonypi_device.input_jog_dev;
778
struct input_dev *key_dev = sonypi_device.input_key_dev;
779
struct sonypi_keypress kp = { NULL };
780
int i;
781
782
switch (event) {
783
case SONYPI_EVENT_JOGDIAL_UP:
784
case SONYPI_EVENT_JOGDIAL_UP_PRESSED:
785
input_report_rel(jog_dev, REL_WHEEL, 1);
786
input_sync(jog_dev);
787
break;
788
789
case SONYPI_EVENT_JOGDIAL_DOWN:
790
case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED:
791
input_report_rel(jog_dev, REL_WHEEL, -1);
792
input_sync(jog_dev);
793
break;
794
795
case SONYPI_EVENT_JOGDIAL_PRESSED:
796
kp.key = BTN_MIDDLE;
797
kp.dev = jog_dev;
798
break;
799
800
case SONYPI_EVENT_FNKEY_RELEASED:
801
/* Nothing, not all VAIOs generate this event */
802
break;
803
804
default:
805
for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
806
if (event == sonypi_inputkeys[i].sonypiev) {
807
kp.dev = key_dev;
808
kp.key = sonypi_inputkeys[i].inputev;
809
break;
810
}
811
break;
812
}
813
814
if (kp.dev) {
815
input_report_key(kp.dev, kp.key, 1);
816
input_sync(kp.dev);
817
kfifo_in_locked(&sonypi_device.input_fifo,
818
(unsigned char *)&kp, sizeof(kp),
819
&sonypi_device.input_fifo_lock);
820
schedule_work(&sonypi_device.input_work);
821
}
822
}
823
824
/* Interrupt handler: some event is available */
825
static irqreturn_t sonypi_irq(int irq, void *dev_id)
826
{
827
u8 v1, v2, event = 0;
828
int i, j;
829
830
v1 = inb_p(sonypi_device.ioport1);
831
v2 = inb_p(sonypi_device.ioport1 + sonypi_device.evtype_offset);
832
833
for (i = 0; sonypi_eventtypes[i].model; i++) {
834
if (sonypi_device.model != sonypi_eventtypes[i].model)
835
continue;
836
if ((v2 & sonypi_eventtypes[i].data) !=
837
sonypi_eventtypes[i].data)
838
continue;
839
if (!(mask & sonypi_eventtypes[i].mask))
840
continue;
841
for (j = 0; sonypi_eventtypes[i].events[j].event; j++) {
842
if (v1 == sonypi_eventtypes[i].events[j].data) {
843
event = sonypi_eventtypes[i].events[j].event;
844
goto found;
845
}
846
}
847
}
848
849
if (verbose)
850
printk(KERN_WARNING
851
"sonypi: unknown event port1=0x%02x,port2=0x%02x\n",
852
v1, v2);
853
/* We need to return IRQ_HANDLED here because there *are*
854
* events belonging to the sonypi device we don't know about,
855
* but we still don't want those to pollute the logs... */
856
return IRQ_HANDLED;
857
858
found:
859
if (verbose > 1)
860
printk(KERN_INFO
861
"sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
862
863
if (useinput)
864
sonypi_report_input_event(event);
865
866
kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event,
867
sizeof(event), &sonypi_device.fifo_lock);
868
kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
869
wake_up_interruptible(&sonypi_device.fifo_proc_list);
870
871
return IRQ_HANDLED;
872
}
873
874
static int sonypi_misc_fasync(int fd, struct file *filp, int on)
875
{
876
return fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
877
}
878
879
static int sonypi_misc_release(struct inode *inode, struct file *file)
880
{
881
mutex_lock(&sonypi_device.lock);
882
sonypi_device.open_count--;
883
mutex_unlock(&sonypi_device.lock);
884
return 0;
885
}
886
887
static int sonypi_misc_open(struct inode *inode, struct file *file)
888
{
889
mutex_lock(&sonypi_device.lock);
890
/* Flush input queue on first open */
891
if (!sonypi_device.open_count)
892
kfifo_reset(&sonypi_device.fifo);
893
sonypi_device.open_count++;
894
mutex_unlock(&sonypi_device.lock);
895
896
return 0;
897
}
898
899
static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
900
size_t count, loff_t *pos)
901
{
902
ssize_t ret;
903
unsigned char c;
904
905
if ((kfifo_len(&sonypi_device.fifo) == 0) &&
906
(file->f_flags & O_NONBLOCK))
907
return -EAGAIN;
908
909
ret = wait_event_interruptible(sonypi_device.fifo_proc_list,
910
kfifo_len(&sonypi_device.fifo) != 0);
911
if (ret)
912
return ret;
913
914
while (ret < count &&
915
(kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c),
916
&sonypi_device.fifo_lock) == sizeof(c))) {
917
if (put_user(c, buf++))
918
return -EFAULT;
919
ret++;
920
}
921
922
if (ret > 0) {
923
struct inode *inode = file_inode(file);
924
inode_set_atime_to_ts(inode, current_time(inode));
925
}
926
927
return ret;
928
}
929
930
static __poll_t sonypi_misc_poll(struct file *file, poll_table *wait)
931
{
932
poll_wait(file, &sonypi_device.fifo_proc_list, wait);
933
if (kfifo_len(&sonypi_device.fifo))
934
return EPOLLIN | EPOLLRDNORM;
935
return 0;
936
}
937
938
static long sonypi_misc_ioctl(struct file *fp,
939
unsigned int cmd, unsigned long arg)
940
{
941
long ret = 0;
942
void __user *argp = (void __user *)arg;
943
u8 val8;
944
u16 val16;
945
946
mutex_lock(&sonypi_device.lock);
947
switch (cmd) {
948
case SONYPI_IOCGBRT:
949
if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) {
950
ret = -EIO;
951
break;
952
}
953
if (copy_to_user(argp, &val8, sizeof(val8)))
954
ret = -EFAULT;
955
break;
956
case SONYPI_IOCSBRT:
957
if (copy_from_user(&val8, argp, sizeof(val8))) {
958
ret = -EFAULT;
959
break;
960
}
961
if (sonypi_ec_write(SONYPI_LCD_LIGHT, val8))
962
ret = -EIO;
963
break;
964
case SONYPI_IOCGBAT1CAP:
965
if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
966
ret = -EIO;
967
break;
968
}
969
if (copy_to_user(argp, &val16, sizeof(val16)))
970
ret = -EFAULT;
971
break;
972
case SONYPI_IOCGBAT1REM:
973
if (ec_read16(SONYPI_BAT1_LEFT, &val16)) {
974
ret = -EIO;
975
break;
976
}
977
if (copy_to_user(argp, &val16, sizeof(val16)))
978
ret = -EFAULT;
979
break;
980
case SONYPI_IOCGBAT2CAP:
981
if (ec_read16(SONYPI_BAT2_FULL, &val16)) {
982
ret = -EIO;
983
break;
984
}
985
if (copy_to_user(argp, &val16, sizeof(val16)))
986
ret = -EFAULT;
987
break;
988
case SONYPI_IOCGBAT2REM:
989
if (ec_read16(SONYPI_BAT2_LEFT, &val16)) {
990
ret = -EIO;
991
break;
992
}
993
if (copy_to_user(argp, &val16, sizeof(val16)))
994
ret = -EFAULT;
995
break;
996
case SONYPI_IOCGBATFLAGS:
997
if (sonypi_ec_read(SONYPI_BAT_FLAGS, &val8)) {
998
ret = -EIO;
999
break;
1000
}
1001
val8 &= 0x07;
1002
if (copy_to_user(argp, &val8, sizeof(val8)))
1003
ret = -EFAULT;
1004
break;
1005
case SONYPI_IOCGBLUE:
1006
val8 = sonypi_device.bluetooth_power;
1007
if (copy_to_user(argp, &val8, sizeof(val8)))
1008
ret = -EFAULT;
1009
break;
1010
case SONYPI_IOCSBLUE:
1011
if (copy_from_user(&val8, argp, sizeof(val8))) {
1012
ret = -EFAULT;
1013
break;
1014
}
1015
sonypi_setbluetoothpower(val8);
1016
break;
1017
/* FAN Controls */
1018
case SONYPI_IOCGFAN:
1019
if (sonypi_ec_read(SONYPI_FAN0_STATUS, &val8)) {
1020
ret = -EIO;
1021
break;
1022
}
1023
if (copy_to_user(argp, &val8, sizeof(val8)))
1024
ret = -EFAULT;
1025
break;
1026
case SONYPI_IOCSFAN:
1027
if (copy_from_user(&val8, argp, sizeof(val8))) {
1028
ret = -EFAULT;
1029
break;
1030
}
1031
if (sonypi_ec_write(SONYPI_FAN0_STATUS, val8))
1032
ret = -EIO;
1033
break;
1034
/* GET Temperature (useful under APM) */
1035
case SONYPI_IOCGTEMP:
1036
if (sonypi_ec_read(SONYPI_TEMP_STATUS, &val8)) {
1037
ret = -EIO;
1038
break;
1039
}
1040
if (copy_to_user(argp, &val8, sizeof(val8)))
1041
ret = -EFAULT;
1042
break;
1043
default:
1044
ret = -EINVAL;
1045
}
1046
mutex_unlock(&sonypi_device.lock);
1047
return ret;
1048
}
1049
1050
static const struct file_operations sonypi_misc_fops = {
1051
.owner = THIS_MODULE,
1052
.read = sonypi_misc_read,
1053
.poll = sonypi_misc_poll,
1054
.open = sonypi_misc_open,
1055
.release = sonypi_misc_release,
1056
.fasync = sonypi_misc_fasync,
1057
.unlocked_ioctl = sonypi_misc_ioctl,
1058
};
1059
1060
static struct miscdevice sonypi_misc_device = {
1061
.minor = MISC_DYNAMIC_MINOR,
1062
.name = "sonypi",
1063
.fops = &sonypi_misc_fops,
1064
};
1065
1066
static void sonypi_enable(unsigned int camera_on)
1067
{
1068
switch (sonypi_device.model) {
1069
case SONYPI_DEVICE_MODEL_TYPE1:
1070
sonypi_type1_srs();
1071
break;
1072
case SONYPI_DEVICE_MODEL_TYPE2:
1073
sonypi_type2_srs();
1074
break;
1075
case SONYPI_DEVICE_MODEL_TYPE3:
1076
sonypi_type3_srs();
1077
break;
1078
}
1079
1080
sonypi_call1(0x82);
1081
sonypi_call2(0x81, 0xff);
1082
sonypi_call1(compat ? 0x92 : 0x82);
1083
1084
/* Enable ACPI mode to get Fn key events */
1085
if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
1086
outb(0xf0, 0xb2);
1087
1088
if (camera && camera_on)
1089
sonypi_camera_on();
1090
}
1091
1092
static int sonypi_disable(void)
1093
{
1094
sonypi_call2(0x81, 0); /* make sure we don't get any more events */
1095
if (camera)
1096
sonypi_camera_off();
1097
1098
/* disable ACPI mode */
1099
if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
1100
outb(0xf1, 0xb2);
1101
1102
switch (sonypi_device.model) {
1103
case SONYPI_DEVICE_MODEL_TYPE1:
1104
sonypi_type1_dis();
1105
break;
1106
case SONYPI_DEVICE_MODEL_TYPE2:
1107
sonypi_type2_dis();
1108
break;
1109
case SONYPI_DEVICE_MODEL_TYPE3:
1110
sonypi_type3_dis();
1111
break;
1112
}
1113
1114
return 0;
1115
}
1116
1117
#ifdef CONFIG_ACPI
1118
static int sonypi_acpi_add(struct acpi_device *device)
1119
{
1120
sonypi_acpi_device = device;
1121
strcpy(acpi_device_name(device), "Sony laptop hotkeys");
1122
strcpy(acpi_device_class(device), "sony/hotkey");
1123
return 0;
1124
}
1125
1126
static void sonypi_acpi_remove(struct acpi_device *device)
1127
{
1128
sonypi_acpi_device = NULL;
1129
}
1130
1131
static const struct acpi_device_id sonypi_device_ids[] = {
1132
{"SNY6001", 0},
1133
{"", 0},
1134
};
1135
1136
static struct acpi_driver sonypi_acpi_driver = {
1137
.name = "sonypi",
1138
.class = "hkey",
1139
.ids = sonypi_device_ids,
1140
.ops = {
1141
.add = sonypi_acpi_add,
1142
.remove = sonypi_acpi_remove,
1143
},
1144
};
1145
#endif
1146
1147
static int sonypi_create_input_devices(struct platform_device *pdev)
1148
{
1149
struct input_dev *jog_dev;
1150
struct input_dev *key_dev;
1151
int i;
1152
int error;
1153
1154
sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
1155
if (!jog_dev)
1156
return -ENOMEM;
1157
1158
jog_dev->name = "Sony Vaio Jogdial";
1159
jog_dev->id.bustype = BUS_ISA;
1160
jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
1161
jog_dev->dev.parent = &pdev->dev;
1162
1163
jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
1164
jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
1165
jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
1166
1167
sonypi_device.input_key_dev = key_dev = input_allocate_device();
1168
if (!key_dev) {
1169
error = -ENOMEM;
1170
goto err_free_jogdev;
1171
}
1172
1173
key_dev->name = "Sony Vaio Keys";
1174
key_dev->id.bustype = BUS_ISA;
1175
key_dev->id.vendor = PCI_VENDOR_ID_SONY;
1176
key_dev->dev.parent = &pdev->dev;
1177
1178
/* Initialize the Input Drivers: special keys */
1179
key_dev->evbit[0] = BIT_MASK(EV_KEY);
1180
for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
1181
if (sonypi_inputkeys[i].inputev)
1182
set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
1183
1184
error = input_register_device(jog_dev);
1185
if (error)
1186
goto err_free_keydev;
1187
1188
error = input_register_device(key_dev);
1189
if (error)
1190
goto err_unregister_jogdev;
1191
1192
return 0;
1193
1194
err_unregister_jogdev:
1195
input_unregister_device(jog_dev);
1196
/* Set to NULL so we don't free it again below */
1197
jog_dev = NULL;
1198
err_free_keydev:
1199
input_free_device(key_dev);
1200
sonypi_device.input_key_dev = NULL;
1201
err_free_jogdev:
1202
input_free_device(jog_dev);
1203
sonypi_device.input_jog_dev = NULL;
1204
1205
return error;
1206
}
1207
1208
static int sonypi_setup_ioports(struct sonypi_device *dev,
1209
const struct sonypi_ioport_list *ioport_list)
1210
{
1211
/* try to detect if sony-laptop is being used and thus
1212
* has already requested one of the known ioports.
1213
* As in the deprecated check_region this is racy has we have
1214
* multiple ioports available and one of them can be requested
1215
* between this check and the subsequent request. Anyway, as an
1216
* attempt to be some more user-friendly as we currently are,
1217
* this is enough.
1218
*/
1219
const struct sonypi_ioport_list *check = ioport_list;
1220
while (check_ioport && check->port1) {
1221
if (!request_region(check->port1,
1222
sonypi_device.region_size,
1223
"Sony Programmable I/O Device Check")) {
1224
printk(KERN_ERR "sonypi: ioport 0x%.4x busy, using sony-laptop? "
1225
"if not use check_ioport=0\n",
1226
check->port1);
1227
return -EBUSY;
1228
}
1229
release_region(check->port1, sonypi_device.region_size);
1230
check++;
1231
}
1232
1233
while (ioport_list->port1) {
1234
1235
if (request_region(ioport_list->port1,
1236
sonypi_device.region_size,
1237
"Sony Programmable I/O Device")) {
1238
dev->ioport1 = ioport_list->port1;
1239
dev->ioport2 = ioport_list->port2;
1240
return 0;
1241
}
1242
ioport_list++;
1243
}
1244
1245
return -EBUSY;
1246
}
1247
1248
static int sonypi_setup_irq(struct sonypi_device *dev,
1249
const struct sonypi_irq_list *irq_list)
1250
{
1251
while (irq_list->irq) {
1252
1253
if (!request_irq(irq_list->irq, sonypi_irq,
1254
IRQF_SHARED, "sonypi", sonypi_irq)) {
1255
dev->irq = irq_list->irq;
1256
dev->bits = irq_list->bits;
1257
return 0;
1258
}
1259
irq_list++;
1260
}
1261
1262
return -EBUSY;
1263
}
1264
1265
static void sonypi_display_info(void)
1266
{
1267
printk(KERN_INFO "sonypi: detected type%d model, "
1268
"verbose = %d, fnkeyinit = %s, camera = %s, "
1269
"compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n",
1270
sonypi_device.model,
1271
verbose,
1272
str_on_off(fnkeyinit),
1273
str_on_off(camera),
1274
str_on_off(compat),
1275
mask,
1276
str_on_off(useinput),
1277
str_on_off(SONYPI_ACPI_ACTIVE));
1278
printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
1279
sonypi_device.irq,
1280
sonypi_device.ioport1, sonypi_device.ioport2);
1281
1282
if (minor == -1)
1283
printk(KERN_INFO "sonypi: device allocated minor is %d\n",
1284
sonypi_misc_device.minor);
1285
}
1286
1287
static int sonypi_probe(struct platform_device *dev)
1288
{
1289
const struct sonypi_ioport_list *ioport_list;
1290
const struct sonypi_irq_list *irq_list;
1291
struct pci_dev *pcidev;
1292
int error;
1293
1294
printk(KERN_WARNING "sonypi: please try the sony-laptop module instead "
1295
"and report failures, see also "
1296
"http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");
1297
1298
spin_lock_init(&sonypi_device.fifo_lock);
1299
error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
1300
if (error) {
1301
printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
1302
return error;
1303
}
1304
1305
init_waitqueue_head(&sonypi_device.fifo_proc_list);
1306
mutex_init(&sonypi_device.lock);
1307
sonypi_device.bluetooth_power = -1;
1308
1309
if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1310
PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
1311
sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1;
1312
else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1313
PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
1314
sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
1315
else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1316
PCI_DEVICE_ID_INTEL_ICH7_1, NULL)))
1317
sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
1318
else
1319
sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
1320
1321
if (pcidev && pci_enable_device(pcidev)) {
1322
printk(KERN_ERR "sonypi: pci_enable_device failed\n");
1323
error = -EIO;
1324
goto err_put_pcidev;
1325
}
1326
1327
sonypi_device.dev = pcidev;
1328
1329
if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) {
1330
ioport_list = sonypi_type1_ioport_list;
1331
sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
1332
sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET;
1333
irq_list = sonypi_type1_irq_list;
1334
} else if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
1335
ioport_list = sonypi_type2_ioport_list;
1336
sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
1337
sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET;
1338
irq_list = sonypi_type2_irq_list;
1339
} else {
1340
ioport_list = sonypi_type3_ioport_list;
1341
sonypi_device.region_size = SONYPI_TYPE3_REGION_SIZE;
1342
sonypi_device.evtype_offset = SONYPI_TYPE3_EVTYPE_OFFSET;
1343
irq_list = sonypi_type3_irq_list;
1344
}
1345
1346
error = sonypi_setup_ioports(&sonypi_device, ioport_list);
1347
if (error) {
1348
printk(KERN_ERR "sonypi: failed to request ioports\n");
1349
goto err_disable_pcidev;
1350
}
1351
1352
error = sonypi_setup_irq(&sonypi_device, irq_list);
1353
if (error) {
1354
printk(KERN_ERR "sonypi: request_irq failed\n");
1355
goto err_free_ioports;
1356
}
1357
1358
if (minor != -1)
1359
sonypi_misc_device.minor = minor;
1360
error = misc_register(&sonypi_misc_device);
1361
if (error) {
1362
printk(KERN_ERR "sonypi: misc_register failed\n");
1363
goto err_free_irq;
1364
}
1365
1366
sonypi_display_info();
1367
1368
if (useinput) {
1369
1370
error = sonypi_create_input_devices(dev);
1371
if (error) {
1372
printk(KERN_ERR
1373
"sonypi: failed to create input devices\n");
1374
goto err_miscdev_unregister;
1375
}
1376
1377
spin_lock_init(&sonypi_device.input_fifo_lock);
1378
error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
1379
GFP_KERNEL);
1380
if (error) {
1381
printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
1382
goto err_inpdev_unregister;
1383
}
1384
1385
INIT_WORK(&sonypi_device.input_work, input_keyrelease);
1386
}
1387
1388
sonypi_enable(0);
1389
1390
return 0;
1391
1392
err_inpdev_unregister:
1393
input_unregister_device(sonypi_device.input_key_dev);
1394
input_unregister_device(sonypi_device.input_jog_dev);
1395
err_miscdev_unregister:
1396
misc_deregister(&sonypi_misc_device);
1397
err_free_irq:
1398
free_irq(sonypi_device.irq, sonypi_irq);
1399
err_free_ioports:
1400
release_region(sonypi_device.ioport1, sonypi_device.region_size);
1401
err_disable_pcidev:
1402
if (pcidev)
1403
pci_disable_device(pcidev);
1404
err_put_pcidev:
1405
pci_dev_put(pcidev);
1406
kfifo_free(&sonypi_device.fifo);
1407
1408
return error;
1409
}
1410
1411
static void sonypi_remove(struct platform_device *dev)
1412
{
1413
sonypi_disable();
1414
1415
synchronize_irq(sonypi_device.irq);
1416
flush_work(&sonypi_device.input_work);
1417
1418
if (useinput) {
1419
input_unregister_device(sonypi_device.input_key_dev);
1420
input_unregister_device(sonypi_device.input_jog_dev);
1421
kfifo_free(&sonypi_device.input_fifo);
1422
}
1423
1424
misc_deregister(&sonypi_misc_device);
1425
1426
free_irq(sonypi_device.irq, sonypi_irq);
1427
release_region(sonypi_device.ioport1, sonypi_device.region_size);
1428
1429
if (sonypi_device.dev) {
1430
pci_disable_device(sonypi_device.dev);
1431
pci_dev_put(sonypi_device.dev);
1432
}
1433
1434
kfifo_free(&sonypi_device.fifo);
1435
}
1436
1437
#ifdef CONFIG_PM_SLEEP
1438
static int old_camera_power;
1439
1440
static int sonypi_suspend(struct device *dev)
1441
{
1442
old_camera_power = sonypi_device.camera_power;
1443
sonypi_disable();
1444
1445
return 0;
1446
}
1447
1448
static int sonypi_resume(struct device *dev)
1449
{
1450
sonypi_enable(old_camera_power);
1451
return 0;
1452
}
1453
1454
static SIMPLE_DEV_PM_OPS(sonypi_pm, sonypi_suspend, sonypi_resume);
1455
#define SONYPI_PM (&sonypi_pm)
1456
#else
1457
#define SONYPI_PM NULL
1458
#endif
1459
1460
static void sonypi_shutdown(struct platform_device *dev)
1461
{
1462
sonypi_disable();
1463
}
1464
1465
static struct platform_driver sonypi_driver = {
1466
.driver = {
1467
.name = "sonypi",
1468
.pm = SONYPI_PM,
1469
},
1470
.probe = sonypi_probe,
1471
.remove = sonypi_remove,
1472
.shutdown = sonypi_shutdown,
1473
};
1474
1475
static struct platform_device *sonypi_platform_device;
1476
1477
static const struct dmi_system_id sonypi_dmi_table[] __initconst = {
1478
{
1479
.ident = "Sony Vaio",
1480
.matches = {
1481
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
1482
DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"),
1483
},
1484
},
1485
{
1486
.ident = "Sony Vaio",
1487
.matches = {
1488
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
1489
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"),
1490
},
1491
},
1492
{ }
1493
};
1494
1495
static int __init sonypi_init(void)
1496
{
1497
int error;
1498
1499
printk(KERN_INFO
1500
"sonypi: Sony Programmable I/O Controller Driver v%s.\n",
1501
SONYPI_DRIVER_VERSION);
1502
1503
if (!dmi_check_system(sonypi_dmi_table))
1504
return -ENODEV;
1505
1506
error = platform_driver_register(&sonypi_driver);
1507
if (error)
1508
return error;
1509
1510
sonypi_platform_device = platform_device_alloc("sonypi", -1);
1511
if (!sonypi_platform_device) {
1512
error = -ENOMEM;
1513
goto err_driver_unregister;
1514
}
1515
1516
error = platform_device_add(sonypi_platform_device);
1517
if (error)
1518
goto err_free_device;
1519
1520
#ifdef CONFIG_ACPI
1521
if (acpi_bus_register_driver(&sonypi_acpi_driver) >= 0)
1522
acpi_driver_registered = 1;
1523
#endif
1524
1525
return 0;
1526
1527
err_free_device:
1528
platform_device_put(sonypi_platform_device);
1529
err_driver_unregister:
1530
platform_driver_unregister(&sonypi_driver);
1531
return error;
1532
}
1533
1534
static void __exit sonypi_exit(void)
1535
{
1536
#ifdef CONFIG_ACPI
1537
if (acpi_driver_registered)
1538
acpi_bus_unregister_driver(&sonypi_acpi_driver);
1539
#endif
1540
platform_device_unregister(sonypi_platform_device);
1541
platform_driver_unregister(&sonypi_driver);
1542
printk(KERN_INFO "sonypi: removed.\n");
1543
}
1544
1545
module_init(sonypi_init);
1546
module_exit(sonypi_exit);
1547
1548