Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Sony Programmable I/O Control Device driver for VAIO
0004  *
0005  * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
0006  *
0007  * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net>
0008  *
0009  * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
0010  *
0011  * Copyright (C) 2001-2002 AlcĂ´ve <www.alcove.com>
0012  *
0013  * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
0014  *
0015  * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp>
0016  *
0017  * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp>
0018  *
0019  * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
0020  *
0021  * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
0022  */
0023 
0024 #include <linux/module.h>
0025 #include <linux/sched.h>
0026 #include <linux/input.h>
0027 #include <linux/pci.h>
0028 #include <linux/init.h>
0029 #include <linux/interrupt.h>
0030 #include <linux/miscdevice.h>
0031 #include <linux/poll.h>
0032 #include <linux/delay.h>
0033 #include <linux/wait.h>
0034 #include <linux/acpi.h>
0035 #include <linux/dmi.h>
0036 #include <linux/err.h>
0037 #include <linux/kfifo.h>
0038 #include <linux/platform_device.h>
0039 #include <linux/gfp.h>
0040 
0041 #include <linux/uaccess.h>
0042 #include <asm/io.h>
0043 
0044 #include <linux/sonypi.h>
0045 
0046 #define SONYPI_DRIVER_VERSION    "1.26"
0047 
0048 MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
0049 MODULE_DESCRIPTION("Sony Programmable I/O Control Device driver");
0050 MODULE_LICENSE("GPL");
0051 MODULE_VERSION(SONYPI_DRIVER_VERSION);
0052 
0053 static int minor = -1;
0054 module_param(minor, int, 0);
0055 MODULE_PARM_DESC(minor,
0056          "minor number of the misc device, default is -1 (automatic)");
0057 
0058 static int verbose;     /* = 0 */
0059 module_param(verbose, int, 0644);
0060 MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)");
0061 
0062 static int fnkeyinit;       /* = 0 */
0063 module_param(fnkeyinit, int, 0444);
0064 MODULE_PARM_DESC(fnkeyinit,
0065          "set this if your Fn keys do not generate any event");
0066 
0067 static int camera;      /* = 0 */
0068 module_param(camera, int, 0444);
0069 MODULE_PARM_DESC(camera,
0070          "set this if you have a MotionEye camera (PictureBook series)");
0071 
0072 static int compat;      /* = 0 */
0073 module_param(compat, int, 0444);
0074 MODULE_PARM_DESC(compat,
0075          "set this if you want to enable backward compatibility mode");
0076 
0077 static unsigned long mask = 0xffffffff;
0078 module_param(mask, ulong, 0644);
0079 MODULE_PARM_DESC(mask,
0080          "set this to the mask of event you want to enable (see doc)");
0081 
0082 static int useinput = 1;
0083 module_param(useinput, int, 0444);
0084 MODULE_PARM_DESC(useinput,
0085          "set this if you would like sonypi to feed events to the input subsystem");
0086 
0087 static int check_ioport = 1;
0088 module_param(check_ioport, int, 0444);
0089 MODULE_PARM_DESC(check_ioport,
0090          "set this to 0 if you think the automatic ioport check for sony-laptop is wrong");
0091 
0092 #define SONYPI_DEVICE_MODEL_TYPE1   1
0093 #define SONYPI_DEVICE_MODEL_TYPE2   2
0094 #define SONYPI_DEVICE_MODEL_TYPE3   3
0095 
0096 /* type1 models use those */
0097 #define SONYPI_IRQ_PORT         0x8034
0098 #define SONYPI_IRQ_SHIFT        22
0099 #define SONYPI_TYPE1_BASE       0x50
0100 #define SONYPI_G10A         (SONYPI_TYPE1_BASE+0x14)
0101 #define SONYPI_TYPE1_REGION_SIZE    0x08
0102 #define SONYPI_TYPE1_EVTYPE_OFFSET  0x04
0103 
0104 /* type2 series specifics */
0105 #define SONYPI_SIRQ         0x9b
0106 #define SONYPI_SLOB         0x9c
0107 #define SONYPI_SHIB         0x9d
0108 #define SONYPI_TYPE2_REGION_SIZE    0x20
0109 #define SONYPI_TYPE2_EVTYPE_OFFSET  0x12
0110 
0111 /* type3 series specifics */
0112 #define SONYPI_TYPE3_BASE       0x40
0113 #define SONYPI_TYPE3_GID2       (SONYPI_TYPE3_BASE+0x48) /* 16 bits */
0114 #define SONYPI_TYPE3_MISC       (SONYPI_TYPE3_BASE+0x6d) /* 8 bits  */
0115 #define SONYPI_TYPE3_REGION_SIZE    0x20
0116 #define SONYPI_TYPE3_EVTYPE_OFFSET  0x12
0117 
0118 /* battery / brightness addresses */
0119 #define SONYPI_BAT_FLAGS    0x81
0120 #define SONYPI_LCD_LIGHT    0x96
0121 #define SONYPI_BAT1_PCTRM   0xa0
0122 #define SONYPI_BAT1_LEFT    0xa2
0123 #define SONYPI_BAT1_MAXRT   0xa4
0124 #define SONYPI_BAT2_PCTRM   0xa8
0125 #define SONYPI_BAT2_LEFT    0xaa
0126 #define SONYPI_BAT2_MAXRT   0xac
0127 #define SONYPI_BAT1_MAXTK   0xb0
0128 #define SONYPI_BAT1_FULL    0xb2
0129 #define SONYPI_BAT2_MAXTK   0xb8
0130 #define SONYPI_BAT2_FULL    0xba
0131 
0132 /* FAN0 information (reverse engineered from ACPI tables) */
0133 #define SONYPI_FAN0_STATUS  0x93
0134 #define SONYPI_TEMP_STATUS  0xC1
0135 
0136 /* ioports used for brightness and type2 events */
0137 #define SONYPI_DATA_IOPORT  0x62
0138 #define SONYPI_CST_IOPORT   0x66
0139 
0140 /* The set of possible ioports */
0141 struct sonypi_ioport_list {
0142     u16 port1;
0143     u16 port2;
0144 };
0145 
0146 static struct sonypi_ioport_list sonypi_type1_ioport_list[] = {
0147     { 0x10c0, 0x10c4 }, /* looks like the default on C1Vx */
0148     { 0x1080, 0x1084 },
0149     { 0x1090, 0x1094 },
0150     { 0x10a0, 0x10a4 },
0151     { 0x10b0, 0x10b4 },
0152     { 0x0, 0x0 }
0153 };
0154 
0155 static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
0156     { 0x1080, 0x1084 },
0157     { 0x10a0, 0x10a4 },
0158     { 0x10c0, 0x10c4 },
0159     { 0x10e0, 0x10e4 },
0160     { 0x0, 0x0 }
0161 };
0162 
0163 /* same as in type 2 models */
0164 static struct sonypi_ioport_list *sonypi_type3_ioport_list =
0165     sonypi_type2_ioport_list;
0166 
0167 /* The set of possible interrupts */
0168 struct sonypi_irq_list {
0169     u16 irq;
0170     u16 bits;
0171 };
0172 
0173 static struct sonypi_irq_list sonypi_type1_irq_list[] = {
0174     { 11, 0x2 },    /* IRQ 11, GO22=0,GO23=1 in AML */
0175     { 10, 0x1 },    /* IRQ 10, GO22=1,GO23=0 in AML */
0176     {  5, 0x0 },    /* IRQ  5, GO22=0,GO23=0 in AML */
0177     {  0, 0x3 } /* no IRQ, GO22=1,GO23=1 in AML */
0178 };
0179 
0180 static struct sonypi_irq_list sonypi_type2_irq_list[] = {
0181     { 11, 0x80 },   /* IRQ 11, 0x80 in SIRQ in AML */
0182     { 10, 0x40 },   /* IRQ 10, 0x40 in SIRQ in AML */
0183     {  9, 0x20 },   /* IRQ  9, 0x20 in SIRQ in AML */
0184     {  6, 0x10 },   /* IRQ  6, 0x10 in SIRQ in AML */
0185     {  0, 0x00 }    /* no IRQ, 0x00 in SIRQ in AML */
0186 };
0187 
0188 /* same as in type2 models */
0189 static struct sonypi_irq_list *sonypi_type3_irq_list = sonypi_type2_irq_list;
0190 
0191 #define SONYPI_CAMERA_BRIGHTNESS        0
0192 #define SONYPI_CAMERA_CONTRAST          1
0193 #define SONYPI_CAMERA_HUE           2
0194 #define SONYPI_CAMERA_COLOR         3
0195 #define SONYPI_CAMERA_SHARPNESS         4
0196 
0197 #define SONYPI_CAMERA_PICTURE           5
0198 #define SONYPI_CAMERA_EXPOSURE_MASK     0xC
0199 #define SONYPI_CAMERA_WHITE_BALANCE_MASK    0x3
0200 #define SONYPI_CAMERA_PICTURE_MODE_MASK     0x30
0201 #define SONYPI_CAMERA_MUTE_MASK         0x40
0202 
0203 /* the rest don't need a loop until not 0xff */
0204 #define SONYPI_CAMERA_AGC           6
0205 #define SONYPI_CAMERA_AGC_MASK          0x30
0206 #define SONYPI_CAMERA_SHUTTER_MASK      0x7
0207 
0208 #define SONYPI_CAMERA_SHUTDOWN_REQUEST      7
0209 #define SONYPI_CAMERA_CONTROL           0x10
0210 
0211 #define SONYPI_CAMERA_STATUS            7
0212 #define SONYPI_CAMERA_STATUS_READY      0x2
0213 #define SONYPI_CAMERA_STATUS_POSITION       0x4
0214 
0215 #define SONYPI_DIRECTION_BACKWARDS      0x4
0216 
0217 #define SONYPI_CAMERA_REVISION          8
0218 #define SONYPI_CAMERA_ROMVERSION        9
0219 
0220 /* Event masks */
0221 #define SONYPI_JOGGER_MASK          0x00000001
0222 #define SONYPI_CAPTURE_MASK         0x00000002
0223 #define SONYPI_FNKEY_MASK           0x00000004
0224 #define SONYPI_BLUETOOTH_MASK           0x00000008
0225 #define SONYPI_PKEY_MASK            0x00000010
0226 #define SONYPI_BACK_MASK            0x00000020
0227 #define SONYPI_HELP_MASK            0x00000040
0228 #define SONYPI_LID_MASK             0x00000080
0229 #define SONYPI_ZOOM_MASK            0x00000100
0230 #define SONYPI_THUMBPHRASE_MASK         0x00000200
0231 #define SONYPI_MEYE_MASK            0x00000400
0232 #define SONYPI_MEMORYSTICK_MASK         0x00000800
0233 #define SONYPI_BATTERY_MASK         0x00001000
0234 #define SONYPI_WIRELESS_MASK            0x00002000
0235 
0236 struct sonypi_event {
0237     u8  data;
0238     u8  event;
0239 };
0240 
0241 /* The set of possible button release events */
0242 static struct sonypi_event sonypi_releaseev[] = {
0243     { 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED },
0244     { 0, 0 }
0245 };
0246 
0247 /* The set of possible jogger events  */
0248 static struct sonypi_event sonypi_joggerev[] = {
0249     { 0x1f, SONYPI_EVENT_JOGDIAL_UP },
0250     { 0x01, SONYPI_EVENT_JOGDIAL_DOWN },
0251     { 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED },
0252     { 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED },
0253     { 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP },
0254     { 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN },
0255     { 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED },
0256     { 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED },
0257     { 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP },
0258     { 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN },
0259     { 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED },
0260     { 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED },
0261     { 0x40, SONYPI_EVENT_JOGDIAL_PRESSED },
0262     { 0, 0 }
0263 };
0264 
0265 /* The set of possible capture button events */
0266 static struct sonypi_event sonypi_captureev[] = {
0267     { 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED },
0268     { 0x07, SONYPI_EVENT_CAPTURE_PRESSED },
0269     { 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED },
0270     { 0, 0 }
0271 };
0272 
0273 /* The set of possible fnkeys events */
0274 static struct sonypi_event sonypi_fnkeyev[] = {
0275     { 0x10, SONYPI_EVENT_FNKEY_ESC },
0276     { 0x11, SONYPI_EVENT_FNKEY_F1 },
0277     { 0x12, SONYPI_EVENT_FNKEY_F2 },
0278     { 0x13, SONYPI_EVENT_FNKEY_F3 },
0279     { 0x14, SONYPI_EVENT_FNKEY_F4 },
0280     { 0x15, SONYPI_EVENT_FNKEY_F5 },
0281     { 0x16, SONYPI_EVENT_FNKEY_F6 },
0282     { 0x17, SONYPI_EVENT_FNKEY_F7 },
0283     { 0x18, SONYPI_EVENT_FNKEY_F8 },
0284     { 0x19, SONYPI_EVENT_FNKEY_F9 },
0285     { 0x1a, SONYPI_EVENT_FNKEY_F10 },
0286     { 0x1b, SONYPI_EVENT_FNKEY_F11 },
0287     { 0x1c, SONYPI_EVENT_FNKEY_F12 },
0288     { 0x1f, SONYPI_EVENT_FNKEY_RELEASED },
0289     { 0x21, SONYPI_EVENT_FNKEY_1 },
0290     { 0x22, SONYPI_EVENT_FNKEY_2 },
0291     { 0x31, SONYPI_EVENT_FNKEY_D },
0292     { 0x32, SONYPI_EVENT_FNKEY_E },
0293     { 0x33, SONYPI_EVENT_FNKEY_F },
0294     { 0x34, SONYPI_EVENT_FNKEY_S },
0295     { 0x35, SONYPI_EVENT_FNKEY_B },
0296     { 0x36, SONYPI_EVENT_FNKEY_ONLY },
0297     { 0, 0 }
0298 };
0299 
0300 /* The set of possible program key events */
0301 static struct sonypi_event sonypi_pkeyev[] = {
0302     { 0x01, SONYPI_EVENT_PKEY_P1 },
0303     { 0x02, SONYPI_EVENT_PKEY_P2 },
0304     { 0x04, SONYPI_EVENT_PKEY_P3 },
0305     { 0x5c, SONYPI_EVENT_PKEY_P1 },
0306     { 0, 0 }
0307 };
0308 
0309 /* The set of possible bluetooth events */
0310 static struct sonypi_event sonypi_blueev[] = {
0311     { 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED },
0312     { 0x59, SONYPI_EVENT_BLUETOOTH_ON },
0313     { 0x5a, SONYPI_EVENT_BLUETOOTH_OFF },
0314     { 0, 0 }
0315 };
0316 
0317 /* The set of possible wireless events */
0318 static struct sonypi_event sonypi_wlessev[] = {
0319     { 0x59, SONYPI_EVENT_WIRELESS_ON },
0320     { 0x5a, SONYPI_EVENT_WIRELESS_OFF },
0321     { 0, 0 }
0322 };
0323 
0324 /* The set of possible back button events */
0325 static struct sonypi_event sonypi_backev[] = {
0326     { 0x20, SONYPI_EVENT_BACK_PRESSED },
0327     { 0, 0 }
0328 };
0329 
0330 /* The set of possible help button events */
0331 static struct sonypi_event sonypi_helpev[] = {
0332     { 0x3b, SONYPI_EVENT_HELP_PRESSED },
0333     { 0, 0 }
0334 };
0335 
0336 
0337 /* The set of possible lid events */
0338 static struct sonypi_event sonypi_lidev[] = {
0339     { 0x51, SONYPI_EVENT_LID_CLOSED },
0340     { 0x50, SONYPI_EVENT_LID_OPENED },
0341     { 0, 0 }
0342 };
0343 
0344 /* The set of possible zoom events */
0345 static struct sonypi_event sonypi_zoomev[] = {
0346     { 0x39, SONYPI_EVENT_ZOOM_PRESSED },
0347     { 0, 0 }
0348 };
0349 
0350 /* The set of possible thumbphrase events */
0351 static struct sonypi_event sonypi_thumbphraseev[] = {
0352     { 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED },
0353     { 0, 0 }
0354 };
0355 
0356 /* The set of possible motioneye camera events */
0357 static struct sonypi_event sonypi_meyeev[] = {
0358     { 0x00, SONYPI_EVENT_MEYE_FACE },
0359     { 0x01, SONYPI_EVENT_MEYE_OPPOSITE },
0360     { 0, 0 }
0361 };
0362 
0363 /* The set of possible memorystick events */
0364 static struct sonypi_event sonypi_memorystickev[] = {
0365     { 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT },
0366     { 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT },
0367     { 0, 0 }
0368 };
0369 
0370 /* The set of possible battery events */
0371 static struct sonypi_event sonypi_batteryev[] = {
0372     { 0x20, SONYPI_EVENT_BATTERY_INSERT },
0373     { 0x30, SONYPI_EVENT_BATTERY_REMOVE },
0374     { 0, 0 }
0375 };
0376 
0377 static struct sonypi_eventtypes {
0378     int         model;
0379     u8          data;
0380     unsigned long       mask;
0381     struct sonypi_event *   events;
0382 } sonypi_eventtypes[] = {
0383     { SONYPI_DEVICE_MODEL_TYPE1, 0, 0xffffffff, sonypi_releaseev },
0384     { SONYPI_DEVICE_MODEL_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
0385     { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev },
0386     { SONYPI_DEVICE_MODEL_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
0387     { SONYPI_DEVICE_MODEL_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
0388     { SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
0389     { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
0390     { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
0391     { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
0392     { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
0393 
0394     { SONYPI_DEVICE_MODEL_TYPE2, 0, 0xffffffff, sonypi_releaseev },
0395     { SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev },
0396     { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
0397     { SONYPI_DEVICE_MODEL_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
0398     { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
0399     { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
0400     { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
0401     { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev },
0402     { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_HELP_MASK, sonypi_helpev },
0403     { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
0404     { SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
0405     { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
0406     { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
0407     { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
0408 
0409     { SONYPI_DEVICE_MODEL_TYPE3, 0, 0xffffffff, sonypi_releaseev },
0410     { SONYPI_DEVICE_MODEL_TYPE3, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
0411     { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
0412     { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
0413     { SONYPI_DEVICE_MODEL_TYPE3, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
0414     { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
0415     { 0 }
0416 };
0417 
0418 #define SONYPI_BUF_SIZE 128
0419 
0420 /* Correspondance table between sonypi events and input layer events */
0421 static struct {
0422     int sonypiev;
0423     int inputev;
0424 } sonypi_inputkeys[] = {
0425     { SONYPI_EVENT_CAPTURE_PRESSED,     KEY_CAMERA },
0426     { SONYPI_EVENT_FNKEY_ONLY,      KEY_FN },
0427     { SONYPI_EVENT_FNKEY_ESC,       KEY_FN_ESC },
0428     { SONYPI_EVENT_FNKEY_F1,        KEY_FN_F1 },
0429     { SONYPI_EVENT_FNKEY_F2,        KEY_FN_F2 },
0430     { SONYPI_EVENT_FNKEY_F3,        KEY_FN_F3 },
0431     { SONYPI_EVENT_FNKEY_F4,        KEY_FN_F4 },
0432     { SONYPI_EVENT_FNKEY_F5,        KEY_FN_F5 },
0433     { SONYPI_EVENT_FNKEY_F6,        KEY_FN_F6 },
0434     { SONYPI_EVENT_FNKEY_F7,        KEY_FN_F7 },
0435     { SONYPI_EVENT_FNKEY_F8,        KEY_FN_F8 },
0436     { SONYPI_EVENT_FNKEY_F9,        KEY_FN_F9 },
0437     { SONYPI_EVENT_FNKEY_F10,       KEY_FN_F10 },
0438     { SONYPI_EVENT_FNKEY_F11,       KEY_FN_F11 },
0439     { SONYPI_EVENT_FNKEY_F12,       KEY_FN_F12 },
0440     { SONYPI_EVENT_FNKEY_1,         KEY_FN_1 },
0441     { SONYPI_EVENT_FNKEY_2,         KEY_FN_2 },
0442     { SONYPI_EVENT_FNKEY_D,         KEY_FN_D },
0443     { SONYPI_EVENT_FNKEY_E,         KEY_FN_E },
0444     { SONYPI_EVENT_FNKEY_F,         KEY_FN_F },
0445     { SONYPI_EVENT_FNKEY_S,         KEY_FN_S },
0446     { SONYPI_EVENT_FNKEY_B,         KEY_FN_B },
0447     { SONYPI_EVENT_BLUETOOTH_PRESSED,   KEY_BLUE },
0448     { SONYPI_EVENT_BLUETOOTH_ON,        KEY_BLUE },
0449     { SONYPI_EVENT_PKEY_P1,         KEY_PROG1 },
0450     { SONYPI_EVENT_PKEY_P2,         KEY_PROG2 },
0451     { SONYPI_EVENT_PKEY_P3,         KEY_PROG3 },
0452     { SONYPI_EVENT_BACK_PRESSED,        KEY_BACK },
0453     { SONYPI_EVENT_HELP_PRESSED,        KEY_HELP },
0454     { SONYPI_EVENT_ZOOM_PRESSED,        KEY_ZOOM },
0455     { SONYPI_EVENT_THUMBPHRASE_PRESSED,     BTN_THUMB },
0456     { 0, 0 },
0457 };
0458 
0459 struct sonypi_keypress {
0460     struct input_dev *dev;
0461     int key;
0462 };
0463 
0464 static struct sonypi_device {
0465     struct pci_dev *dev;
0466     u16 irq;
0467     u16 bits;
0468     u16 ioport1;
0469     u16 ioport2;
0470     u16 region_size;
0471     u16 evtype_offset;
0472     int camera_power;
0473     int bluetooth_power;
0474     struct mutex lock;
0475     struct kfifo fifo;
0476     spinlock_t fifo_lock;
0477     wait_queue_head_t fifo_proc_list;
0478     struct fasync_struct *fifo_async;
0479     int open_count;
0480     int model;
0481     struct input_dev *input_jog_dev;
0482     struct input_dev *input_key_dev;
0483     struct work_struct input_work;
0484     struct kfifo input_fifo;
0485     spinlock_t input_fifo_lock;
0486 } sonypi_device;
0487 
0488 #define ITERATIONS_LONG     10000
0489 #define ITERATIONS_SHORT    10
0490 
0491 #define wait_on_command(quiet, command, iterations) { \
0492     unsigned int n = iterations; \
0493     while (--n && (command)) \
0494         udelay(1); \
0495     if (!n && (verbose || !quiet)) \
0496         printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __func__, __LINE__); \
0497 }
0498 
0499 #ifdef CONFIG_ACPI
0500 #define SONYPI_ACPI_ACTIVE (!acpi_disabled)
0501 #else
0502 #define SONYPI_ACPI_ACTIVE 0
0503 #endif              /* CONFIG_ACPI */
0504 
0505 #ifdef CONFIG_ACPI
0506 static struct acpi_device *sonypi_acpi_device;
0507 static int acpi_driver_registered;
0508 #endif
0509 
0510 static int sonypi_ec_write(u8 addr, u8 value)
0511 {
0512 #ifdef CONFIG_ACPI
0513     if (SONYPI_ACPI_ACTIVE)
0514         return ec_write(addr, value);
0515 #endif
0516     wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
0517     outb_p(0x81, SONYPI_CST_IOPORT);
0518     wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
0519     outb_p(addr, SONYPI_DATA_IOPORT);
0520     wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
0521     outb_p(value, SONYPI_DATA_IOPORT);
0522     wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
0523     return 0;
0524 }
0525 
0526 static int sonypi_ec_read(u8 addr, u8 *value)
0527 {
0528 #ifdef CONFIG_ACPI
0529     if (SONYPI_ACPI_ACTIVE)
0530         return ec_read(addr, value);
0531 #endif
0532     wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
0533     outb_p(0x80, SONYPI_CST_IOPORT);
0534     wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
0535     outb_p(addr, SONYPI_DATA_IOPORT);
0536     wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
0537     *value = inb_p(SONYPI_DATA_IOPORT);
0538     return 0;
0539 }
0540 
0541 static int ec_read16(u8 addr, u16 *value)
0542 {
0543     u8 val_lb, val_hb;
0544     if (sonypi_ec_read(addr, &val_lb))
0545         return -1;
0546     if (sonypi_ec_read(addr + 1, &val_hb))
0547         return -1;
0548     *value = val_lb | (val_hb << 8);
0549     return 0;
0550 }
0551 
0552 /* Initializes the device - this comes from the AML code in the ACPI bios */
0553 static void sonypi_type1_srs(void)
0554 {
0555     u32 v;
0556 
0557     pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
0558     v = (v & 0xFFFF0000) | ((u32) sonypi_device.ioport1);
0559     pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
0560 
0561     pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
0562     v = (v & 0xFFF0FFFF) |
0563         (((u32) sonypi_device.ioport1 ^ sonypi_device.ioport2) << 16);
0564     pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
0565 
0566     v = inl(SONYPI_IRQ_PORT);
0567     v &= ~(((u32) 0x3) << SONYPI_IRQ_SHIFT);
0568     v |= (((u32) sonypi_device.bits) << SONYPI_IRQ_SHIFT);
0569     outl(v, SONYPI_IRQ_PORT);
0570 
0571     pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
0572     v = (v & 0xFF1FFFFF) | 0x00C00000;
0573     pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
0574 }
0575 
0576 static void sonypi_type2_srs(void)
0577 {
0578     if (sonypi_ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8))
0579         printk(KERN_WARNING "ec_write failed\n");
0580     if (sonypi_ec_write(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF))
0581         printk(KERN_WARNING "ec_write failed\n");
0582     if (sonypi_ec_write(SONYPI_SIRQ, sonypi_device.bits))
0583         printk(KERN_WARNING "ec_write failed\n");
0584     udelay(10);
0585 }
0586 
0587 static void sonypi_type3_srs(void)
0588 {
0589     u16 v16;
0590     u8  v8;
0591 
0592     /* This model type uses the same initialization of
0593      * the embedded controller as the type2 models. */
0594     sonypi_type2_srs();
0595 
0596     /* Initialization of PCI config space of the LPC interface bridge. */
0597     v16 = (sonypi_device.ioport1 & 0xFFF0) | 0x01;
0598     pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, v16);
0599     pci_read_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, &v8);
0600     v8 = (v8 & 0xCF) | 0x10;
0601     pci_write_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, v8);
0602 }
0603 
0604 /* Disables the device - this comes from the AML code in the ACPI bios */
0605 static void sonypi_type1_dis(void)
0606 {
0607     u32 v;
0608 
0609     pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
0610     v = v & 0xFF3FFFFF;
0611     pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
0612 
0613     v = inl(SONYPI_IRQ_PORT);
0614     v |= (0x3 << SONYPI_IRQ_SHIFT);
0615     outl(v, SONYPI_IRQ_PORT);
0616 }
0617 
0618 static void sonypi_type2_dis(void)
0619 {
0620     if (sonypi_ec_write(SONYPI_SHIB, 0))
0621         printk(KERN_WARNING "ec_write failed\n");
0622     if (sonypi_ec_write(SONYPI_SLOB, 0))
0623         printk(KERN_WARNING "ec_write failed\n");
0624     if (sonypi_ec_write(SONYPI_SIRQ, 0))
0625         printk(KERN_WARNING "ec_write failed\n");
0626 }
0627 
0628 static void sonypi_type3_dis(void)
0629 {
0630     sonypi_type2_dis();
0631     udelay(10);
0632     pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, 0);
0633 }
0634 
0635 static u8 sonypi_call1(u8 dev)
0636 {
0637     u8 v1, v2;
0638 
0639     wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
0640     outb(dev, sonypi_device.ioport2);
0641     v1 = inb_p(sonypi_device.ioport2);
0642     v2 = inb_p(sonypi_device.ioport1);
0643     return v2;
0644 }
0645 
0646 static u8 sonypi_call2(u8 dev, u8 fn)
0647 {
0648     u8 v1;
0649 
0650     wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
0651     outb(dev, sonypi_device.ioport2);
0652     wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
0653     outb(fn, sonypi_device.ioport1);
0654     v1 = inb_p(sonypi_device.ioport1);
0655     return v1;
0656 }
0657 
0658 static u8 sonypi_call3(u8 dev, u8 fn, u8 v)
0659 {
0660     u8 v1;
0661 
0662     wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
0663     outb(dev, sonypi_device.ioport2);
0664     wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
0665     outb(fn, sonypi_device.ioport1);
0666     wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
0667     outb(v, sonypi_device.ioport1);
0668     v1 = inb_p(sonypi_device.ioport1);
0669     return v1;
0670 }
0671 
0672 #if 0
0673 /* Get brightness, hue etc. Unreliable... */
0674 static u8 sonypi_read(u8 fn)
0675 {
0676     u8 v1, v2;
0677     int n = 100;
0678 
0679     while (n--) {
0680         v1 = sonypi_call2(0x8f, fn);
0681         v2 = sonypi_call2(0x8f, fn);
0682         if (v1 == v2 && v1 != 0xff)
0683             return v1;
0684     }
0685     return 0xff;
0686 }
0687 #endif
0688 
0689 /* Set brightness, hue etc */
0690 static void sonypi_set(u8 fn, u8 v)
0691 {
0692     wait_on_command(0, sonypi_call3(0x90, fn, v), ITERATIONS_SHORT);
0693 }
0694 
0695 /* Tests if the camera is ready */
0696 static int sonypi_camera_ready(void)
0697 {
0698     u8 v;
0699 
0700     v = sonypi_call2(0x8f, SONYPI_CAMERA_STATUS);
0701     return (v != 0xff && (v & SONYPI_CAMERA_STATUS_READY));
0702 }
0703 
0704 /* Turns the camera off */
0705 static void sonypi_camera_off(void)
0706 {
0707     sonypi_set(SONYPI_CAMERA_PICTURE, SONYPI_CAMERA_MUTE_MASK);
0708 
0709     if (!sonypi_device.camera_power)
0710         return;
0711 
0712     sonypi_call2(0x91, 0);
0713     sonypi_device.camera_power = 0;
0714 }
0715 
0716 /* Turns the camera on */
0717 static void sonypi_camera_on(void)
0718 {
0719     int i, j;
0720 
0721     if (sonypi_device.camera_power)
0722         return;
0723 
0724     for (j = 5; j > 0; j--) {
0725 
0726         while (sonypi_call2(0x91, 0x1))
0727             msleep(10);
0728         sonypi_call1(0x93);
0729 
0730         for (i = 400; i > 0; i--) {
0731             if (sonypi_camera_ready())
0732                 break;
0733             msleep(10);
0734         }
0735         if (i)
0736             break;
0737     }
0738 
0739     if (j == 0) {
0740         printk(KERN_WARNING "sonypi: failed to power on camera\n");
0741         return;
0742     }
0743 
0744     sonypi_set(0x10, 0x5a);
0745     sonypi_device.camera_power = 1;
0746 }
0747 
0748 /* sets the bluetooth subsystem power state */
0749 static void sonypi_setbluetoothpower(u8 state)
0750 {
0751     state = !!state;
0752 
0753     if (sonypi_device.bluetooth_power == state)
0754         return;
0755 
0756     sonypi_call2(0x96, state);
0757     sonypi_call1(0x82);
0758     sonypi_device.bluetooth_power = state;
0759 }
0760 
0761 static void input_keyrelease(struct work_struct *work)
0762 {
0763     struct sonypi_keypress kp;
0764 
0765     while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
0766              sizeof(kp), &sonypi_device.input_fifo_lock)
0767             == sizeof(kp)) {
0768         msleep(10);
0769         input_report_key(kp.dev, kp.key, 0);
0770         input_sync(kp.dev);
0771     }
0772 }
0773 
0774 static void sonypi_report_input_event(u8 event)
0775 {
0776     struct input_dev *jog_dev = sonypi_device.input_jog_dev;
0777     struct input_dev *key_dev = sonypi_device.input_key_dev;
0778     struct sonypi_keypress kp = { NULL };
0779     int i;
0780 
0781     switch (event) {
0782     case SONYPI_EVENT_JOGDIAL_UP:
0783     case SONYPI_EVENT_JOGDIAL_UP_PRESSED:
0784         input_report_rel(jog_dev, REL_WHEEL, 1);
0785         input_sync(jog_dev);
0786         break;
0787 
0788     case SONYPI_EVENT_JOGDIAL_DOWN:
0789     case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED:
0790         input_report_rel(jog_dev, REL_WHEEL, -1);
0791         input_sync(jog_dev);
0792         break;
0793 
0794     case SONYPI_EVENT_JOGDIAL_PRESSED:
0795         kp.key = BTN_MIDDLE;
0796         kp.dev = jog_dev;
0797         break;
0798 
0799     case SONYPI_EVENT_FNKEY_RELEASED:
0800         /* Nothing, not all VAIOs generate this event */
0801         break;
0802 
0803     default:
0804         for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
0805             if (event == sonypi_inputkeys[i].sonypiev) {
0806                 kp.dev = key_dev;
0807                 kp.key = sonypi_inputkeys[i].inputev;
0808                 break;
0809             }
0810         break;
0811     }
0812 
0813     if (kp.dev) {
0814         input_report_key(kp.dev, kp.key, 1);
0815         input_sync(kp.dev);
0816         kfifo_in_locked(&sonypi_device.input_fifo,
0817             (unsigned char *)&kp, sizeof(kp),
0818             &sonypi_device.input_fifo_lock);
0819         schedule_work(&sonypi_device.input_work);
0820     }
0821 }
0822 
0823 /* Interrupt handler: some event is available */
0824 static irqreturn_t sonypi_irq(int irq, void *dev_id)
0825 {
0826     u8 v1, v2, event = 0;
0827     int i, j;
0828 
0829     v1 = inb_p(sonypi_device.ioport1);
0830     v2 = inb_p(sonypi_device.ioport1 + sonypi_device.evtype_offset);
0831 
0832     for (i = 0; sonypi_eventtypes[i].model; i++) {
0833         if (sonypi_device.model != sonypi_eventtypes[i].model)
0834             continue;
0835         if ((v2 & sonypi_eventtypes[i].data) !=
0836             sonypi_eventtypes[i].data)
0837             continue;
0838         if (!(mask & sonypi_eventtypes[i].mask))
0839             continue;
0840         for (j = 0; sonypi_eventtypes[i].events[j].event; j++) {
0841             if (v1 == sonypi_eventtypes[i].events[j].data) {
0842                 event = sonypi_eventtypes[i].events[j].event;
0843                 goto found;
0844             }
0845         }
0846     }
0847 
0848     if (verbose)
0849         printk(KERN_WARNING
0850                "sonypi: unknown event port1=0x%02x,port2=0x%02x\n",
0851                v1, v2);
0852     /* We need to return IRQ_HANDLED here because there *are*
0853      * events belonging to the sonypi device we don't know about,
0854      * but we still don't want those to pollute the logs... */
0855     return IRQ_HANDLED;
0856 
0857 found:
0858     if (verbose > 1)
0859         printk(KERN_INFO
0860                "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
0861 
0862     if (useinput)
0863         sonypi_report_input_event(event);
0864 
0865     kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event,
0866             sizeof(event), &sonypi_device.fifo_lock);
0867     kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
0868     wake_up_interruptible(&sonypi_device.fifo_proc_list);
0869 
0870     return IRQ_HANDLED;
0871 }
0872 
0873 static int sonypi_misc_fasync(int fd, struct file *filp, int on)
0874 {
0875     return fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
0876 }
0877 
0878 static int sonypi_misc_release(struct inode *inode, struct file *file)
0879 {
0880     mutex_lock(&sonypi_device.lock);
0881     sonypi_device.open_count--;
0882     mutex_unlock(&sonypi_device.lock);
0883     return 0;
0884 }
0885 
0886 static int sonypi_misc_open(struct inode *inode, struct file *file)
0887 {
0888     mutex_lock(&sonypi_device.lock);
0889     /* Flush input queue on first open */
0890     if (!sonypi_device.open_count)
0891         kfifo_reset(&sonypi_device.fifo);
0892     sonypi_device.open_count++;
0893     mutex_unlock(&sonypi_device.lock);
0894 
0895     return 0;
0896 }
0897 
0898 static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
0899                 size_t count, loff_t *pos)
0900 {
0901     ssize_t ret;
0902     unsigned char c;
0903 
0904     if ((kfifo_len(&sonypi_device.fifo) == 0) &&
0905         (file->f_flags & O_NONBLOCK))
0906         return -EAGAIN;
0907 
0908     ret = wait_event_interruptible(sonypi_device.fifo_proc_list,
0909                        kfifo_len(&sonypi_device.fifo) != 0);
0910     if (ret)
0911         return ret;
0912 
0913     while (ret < count &&
0914            (kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c),
0915                  &sonypi_device.fifo_lock) == sizeof(c))) {
0916         if (put_user(c, buf++))
0917             return -EFAULT;
0918         ret++;
0919     }
0920 
0921     if (ret > 0) {
0922         struct inode *inode = file_inode(file);
0923         inode->i_atime = current_time(inode);
0924     }
0925 
0926     return ret;
0927 }
0928 
0929 static __poll_t sonypi_misc_poll(struct file *file, poll_table *wait)
0930 {
0931     poll_wait(file, &sonypi_device.fifo_proc_list, wait);
0932     if (kfifo_len(&sonypi_device.fifo))
0933         return EPOLLIN | EPOLLRDNORM;
0934     return 0;
0935 }
0936 
0937 static long sonypi_misc_ioctl(struct file *fp,
0938                  unsigned int cmd, unsigned long arg)
0939 {
0940     long ret = 0;
0941     void __user *argp = (void __user *)arg;
0942     u8 val8;
0943     u16 val16;
0944 
0945     mutex_lock(&sonypi_device.lock);
0946     switch (cmd) {
0947     case SONYPI_IOCGBRT:
0948         if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) {
0949             ret = -EIO;
0950             break;
0951         }
0952         if (copy_to_user(argp, &val8, sizeof(val8)))
0953             ret = -EFAULT;
0954         break;
0955     case SONYPI_IOCSBRT:
0956         if (copy_from_user(&val8, argp, sizeof(val8))) {
0957             ret = -EFAULT;
0958             break;
0959         }
0960         if (sonypi_ec_write(SONYPI_LCD_LIGHT, val8))
0961             ret = -EIO;
0962         break;
0963     case SONYPI_IOCGBAT1CAP:
0964         if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
0965             ret = -EIO;
0966             break;
0967         }
0968         if (copy_to_user(argp, &val16, sizeof(val16)))
0969             ret = -EFAULT;
0970         break;
0971     case SONYPI_IOCGBAT1REM:
0972         if (ec_read16(SONYPI_BAT1_LEFT, &val16)) {
0973             ret = -EIO;
0974             break;
0975         }
0976         if (copy_to_user(argp, &val16, sizeof(val16)))
0977             ret = -EFAULT;
0978         break;
0979     case SONYPI_IOCGBAT2CAP:
0980         if (ec_read16(SONYPI_BAT2_FULL, &val16)) {
0981             ret = -EIO;
0982             break;
0983         }
0984         if (copy_to_user(argp, &val16, sizeof(val16)))
0985             ret = -EFAULT;
0986         break;
0987     case SONYPI_IOCGBAT2REM:
0988         if (ec_read16(SONYPI_BAT2_LEFT, &val16)) {
0989             ret = -EIO;
0990             break;
0991         }
0992         if (copy_to_user(argp, &val16, sizeof(val16)))
0993             ret = -EFAULT;
0994         break;
0995     case SONYPI_IOCGBATFLAGS:
0996         if (sonypi_ec_read(SONYPI_BAT_FLAGS, &val8)) {
0997             ret = -EIO;
0998             break;
0999         }
1000         val8 &= 0x07;
1001         if (copy_to_user(argp, &val8, sizeof(val8)))
1002             ret = -EFAULT;
1003         break;
1004     case SONYPI_IOCGBLUE:
1005         val8 = sonypi_device.bluetooth_power;
1006         if (copy_to_user(argp, &val8, sizeof(val8)))
1007             ret = -EFAULT;
1008         break;
1009     case SONYPI_IOCSBLUE:
1010         if (copy_from_user(&val8, argp, sizeof(val8))) {
1011             ret = -EFAULT;
1012             break;
1013         }
1014         sonypi_setbluetoothpower(val8);
1015         break;
1016     /* FAN Controls */
1017     case SONYPI_IOCGFAN:
1018         if (sonypi_ec_read(SONYPI_FAN0_STATUS, &val8)) {
1019             ret = -EIO;
1020             break;
1021         }
1022         if (copy_to_user(argp, &val8, sizeof(val8)))
1023             ret = -EFAULT;
1024         break;
1025     case SONYPI_IOCSFAN:
1026         if (copy_from_user(&val8, argp, sizeof(val8))) {
1027             ret = -EFAULT;
1028             break;
1029         }
1030         if (sonypi_ec_write(SONYPI_FAN0_STATUS, val8))
1031             ret = -EIO;
1032         break;
1033     /* GET Temperature (useful under APM) */
1034     case SONYPI_IOCGTEMP:
1035         if (sonypi_ec_read(SONYPI_TEMP_STATUS, &val8)) {
1036             ret = -EIO;
1037             break;
1038         }
1039         if (copy_to_user(argp, &val8, sizeof(val8)))
1040             ret = -EFAULT;
1041         break;
1042     default:
1043         ret = -EINVAL;
1044     }
1045     mutex_unlock(&sonypi_device.lock);
1046     return ret;
1047 }
1048 
1049 static const struct file_operations sonypi_misc_fops = {
1050     .owner      = THIS_MODULE,
1051     .read       = sonypi_misc_read,
1052     .poll       = sonypi_misc_poll,
1053     .open       = sonypi_misc_open,
1054     .release    = sonypi_misc_release,
1055     .fasync     = sonypi_misc_fasync,
1056     .unlocked_ioctl = sonypi_misc_ioctl,
1057     .llseek     = no_llseek,
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 int sonypi_acpi_remove(struct acpi_device *device)
1127 {
1128     sonypi_acpi_device = NULL;
1129     return 0;
1130 }
1131 
1132 static const struct acpi_device_id sonypi_device_ids[] = {
1133     {"SNY6001", 0},
1134     {"", 0},
1135 };
1136 
1137 static struct acpi_driver sonypi_acpi_driver = {
1138     .name           = "sonypi",
1139     .class          = "hkey",
1140     .ids            = sonypi_device_ids,
1141     .ops            = {
1142                    .add = sonypi_acpi_add,
1143                .remove = sonypi_acpi_remove,
1144     },
1145 };
1146 #endif
1147 
1148 static int sonypi_create_input_devices(struct platform_device *pdev)
1149 {
1150     struct input_dev *jog_dev;
1151     struct input_dev *key_dev;
1152     int i;
1153     int error;
1154 
1155     sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
1156     if (!jog_dev)
1157         return -ENOMEM;
1158 
1159     jog_dev->name = "Sony Vaio Jogdial";
1160     jog_dev->id.bustype = BUS_ISA;
1161     jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
1162     jog_dev->dev.parent = &pdev->dev;
1163 
1164     jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
1165     jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
1166     jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
1167 
1168     sonypi_device.input_key_dev = key_dev = input_allocate_device();
1169     if (!key_dev) {
1170         error = -ENOMEM;
1171         goto err_free_jogdev;
1172     }
1173 
1174     key_dev->name = "Sony Vaio Keys";
1175     key_dev->id.bustype = BUS_ISA;
1176     key_dev->id.vendor = PCI_VENDOR_ID_SONY;
1177     key_dev->dev.parent = &pdev->dev;
1178 
1179     /* Initialize the Input Drivers: special keys */
1180     key_dev->evbit[0] = BIT_MASK(EV_KEY);
1181     for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
1182         if (sonypi_inputkeys[i].inputev)
1183             set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
1184 
1185     error = input_register_device(jog_dev);
1186     if (error)
1187         goto err_free_keydev;
1188 
1189     error = input_register_device(key_dev);
1190     if (error)
1191         goto err_unregister_jogdev;
1192 
1193     return 0;
1194 
1195  err_unregister_jogdev:
1196     input_unregister_device(jog_dev);
1197     /* Set to NULL so we don't free it again below */
1198     jog_dev = NULL;
1199  err_free_keydev:
1200     input_free_device(key_dev);
1201     sonypi_device.input_key_dev = NULL;
1202  err_free_jogdev:
1203     input_free_device(jog_dev);
1204     sonypi_device.input_jog_dev = NULL;
1205 
1206     return error;
1207 }
1208 
1209 static int sonypi_setup_ioports(struct sonypi_device *dev,
1210                 const struct sonypi_ioport_list *ioport_list)
1211 {
1212     /* try to detect if sony-laptop is being used and thus
1213      * has already requested one of the known ioports.
1214      * As in the deprecated check_region this is racy has we have
1215      * multiple ioports available and one of them can be requested
1216      * between this check and the subsequent request. Anyway, as an
1217      * attempt to be some more user-friendly as we currently are,
1218      * this is enough.
1219      */
1220     const struct sonypi_ioport_list *check = ioport_list;
1221     while (check_ioport && check->port1) {
1222         if (!request_region(check->port1,
1223                    sonypi_device.region_size,
1224                    "Sony Programmable I/O Device Check")) {
1225             printk(KERN_ERR "sonypi: ioport 0x%.4x busy, using sony-laptop? "
1226                     "if not use check_ioport=0\n",
1227                     check->port1);
1228             return -EBUSY;
1229         }
1230         release_region(check->port1, sonypi_device.region_size);
1231         check++;
1232     }
1233 
1234     while (ioport_list->port1) {
1235 
1236         if (request_region(ioport_list->port1,
1237                    sonypi_device.region_size,
1238                    "Sony Programmable I/O Device")) {
1239             dev->ioport1 = ioport_list->port1;
1240             dev->ioport2 = ioport_list->port2;
1241             return 0;
1242         }
1243         ioport_list++;
1244     }
1245 
1246     return -EBUSY;
1247 }
1248 
1249 static int sonypi_setup_irq(struct sonypi_device *dev,
1250                       const struct sonypi_irq_list *irq_list)
1251 {
1252     while (irq_list->irq) {
1253 
1254         if (!request_irq(irq_list->irq, sonypi_irq,
1255                  IRQF_SHARED, "sonypi", sonypi_irq)) {
1256             dev->irq = irq_list->irq;
1257             dev->bits = irq_list->bits;
1258             return 0;
1259         }
1260         irq_list++;
1261     }
1262 
1263     return -EBUSY;
1264 }
1265 
1266 static void sonypi_display_info(void)
1267 {
1268     printk(KERN_INFO "sonypi: detected type%d model, "
1269            "verbose = %d, fnkeyinit = %s, camera = %s, "
1270            "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n",
1271            sonypi_device.model,
1272            verbose,
1273            fnkeyinit ? "on" : "off",
1274            camera ? "on" : "off",
1275            compat ? "on" : "off",
1276            mask,
1277            useinput ? "on" : "off",
1278            SONYPI_ACPI_ACTIVE ? "on" : "off");
1279     printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
1280            sonypi_device.irq,
1281            sonypi_device.ioport1, sonypi_device.ioport2);
1282 
1283     if (minor == -1)
1284         printk(KERN_INFO "sonypi: device allocated minor is %d\n",
1285                sonypi_misc_device.minor);
1286 }
1287 
1288 static int sonypi_probe(struct platform_device *dev)
1289 {
1290     const struct sonypi_ioport_list *ioport_list;
1291     const struct sonypi_irq_list *irq_list;
1292     struct pci_dev *pcidev;
1293     int error;
1294 
1295     printk(KERN_WARNING "sonypi: please try the sony-laptop module instead "
1296             "and report failures, see also "
1297             "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");
1298 
1299     spin_lock_init(&sonypi_device.fifo_lock);
1300     error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
1301     if (error) {
1302         printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
1303         return error;
1304     }
1305 
1306     init_waitqueue_head(&sonypi_device.fifo_proc_list);
1307     mutex_init(&sonypi_device.lock);
1308     sonypi_device.bluetooth_power = -1;
1309 
1310     if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1311                      PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
1312         sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1;
1313     else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1314                       PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
1315         sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
1316     else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1317                       PCI_DEVICE_ID_INTEL_ICH7_1, NULL)))
1318         sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
1319     else
1320         sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
1321 
1322     if (pcidev && pci_enable_device(pcidev)) {
1323         printk(KERN_ERR "sonypi: pci_enable_device failed\n");
1324         error = -EIO;
1325         goto err_put_pcidev;
1326     }
1327 
1328     sonypi_device.dev = pcidev;
1329 
1330     if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) {
1331         ioport_list = sonypi_type1_ioport_list;
1332         sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
1333         sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET;
1334         irq_list = sonypi_type1_irq_list;
1335     } else if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
1336         ioport_list = sonypi_type2_ioport_list;
1337         sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
1338         sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET;
1339         irq_list = sonypi_type2_irq_list;
1340     } else {
1341         ioport_list = sonypi_type3_ioport_list;
1342         sonypi_device.region_size = SONYPI_TYPE3_REGION_SIZE;
1343         sonypi_device.evtype_offset = SONYPI_TYPE3_EVTYPE_OFFSET;
1344         irq_list = sonypi_type3_irq_list;
1345     }
1346 
1347     error = sonypi_setup_ioports(&sonypi_device, ioport_list);
1348     if (error) {
1349         printk(KERN_ERR "sonypi: failed to request ioports\n");
1350         goto err_disable_pcidev;
1351     }
1352 
1353     error = sonypi_setup_irq(&sonypi_device, irq_list);
1354     if (error) {
1355         printk(KERN_ERR "sonypi: request_irq failed\n");
1356         goto err_free_ioports;
1357     }
1358 
1359     if (minor != -1)
1360         sonypi_misc_device.minor = minor;
1361     error = misc_register(&sonypi_misc_device);
1362     if (error) {
1363         printk(KERN_ERR "sonypi: misc_register failed\n");
1364         goto err_free_irq;
1365     }
1366 
1367     sonypi_display_info();
1368 
1369     if (useinput) {
1370 
1371         error = sonypi_create_input_devices(dev);
1372         if (error) {
1373             printk(KERN_ERR
1374                 "sonypi: failed to create input devices\n");
1375             goto err_miscdev_unregister;
1376         }
1377 
1378         spin_lock_init(&sonypi_device.input_fifo_lock);
1379         error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
1380                 GFP_KERNEL);
1381         if (error) {
1382             printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
1383             goto err_inpdev_unregister;
1384         }
1385 
1386         INIT_WORK(&sonypi_device.input_work, input_keyrelease);
1387     }
1388 
1389     sonypi_enable(0);
1390 
1391     return 0;
1392 
1393  err_inpdev_unregister:
1394     input_unregister_device(sonypi_device.input_key_dev);
1395     input_unregister_device(sonypi_device.input_jog_dev);
1396  err_miscdev_unregister:
1397     misc_deregister(&sonypi_misc_device);
1398  err_free_irq:
1399     free_irq(sonypi_device.irq, sonypi_irq);
1400  err_free_ioports:
1401     release_region(sonypi_device.ioport1, sonypi_device.region_size);
1402  err_disable_pcidev:
1403     if (pcidev)
1404         pci_disable_device(pcidev);
1405  err_put_pcidev:
1406     pci_dev_put(pcidev);
1407     kfifo_free(&sonypi_device.fifo);
1408 
1409     return error;
1410 }
1411 
1412 static int sonypi_remove(struct platform_device *dev)
1413 {
1414     sonypi_disable();
1415 
1416     synchronize_irq(sonypi_device.irq);
1417     flush_work(&sonypi_device.input_work);
1418 
1419     if (useinput) {
1420         input_unregister_device(sonypi_device.input_key_dev);
1421         input_unregister_device(sonypi_device.input_jog_dev);
1422         kfifo_free(&sonypi_device.input_fifo);
1423     }
1424 
1425     misc_deregister(&sonypi_misc_device);
1426 
1427     free_irq(sonypi_device.irq, sonypi_irq);
1428     release_region(sonypi_device.ioport1, sonypi_device.region_size);
1429 
1430     if (sonypi_device.dev) {
1431         pci_disable_device(sonypi_device.dev);
1432         pci_dev_put(sonypi_device.dev);
1433     }
1434 
1435     kfifo_free(&sonypi_device.fifo);
1436 
1437     return 0;
1438 }
1439 
1440 #ifdef CONFIG_PM_SLEEP
1441 static int old_camera_power;
1442 
1443 static int sonypi_suspend(struct device *dev)
1444 {
1445     old_camera_power = sonypi_device.camera_power;
1446     sonypi_disable();
1447 
1448     return 0;
1449 }
1450 
1451 static int sonypi_resume(struct device *dev)
1452 {
1453     sonypi_enable(old_camera_power);
1454     return 0;
1455 }
1456 
1457 static SIMPLE_DEV_PM_OPS(sonypi_pm, sonypi_suspend, sonypi_resume);
1458 #define SONYPI_PM   (&sonypi_pm)
1459 #else
1460 #define SONYPI_PM   NULL
1461 #endif
1462 
1463 static void sonypi_shutdown(struct platform_device *dev)
1464 {
1465     sonypi_disable();
1466 }
1467 
1468 static struct platform_driver sonypi_driver = {
1469     .driver     = {
1470         .name   = "sonypi",
1471         .pm = SONYPI_PM,
1472     },
1473     .probe      = sonypi_probe,
1474     .remove     = sonypi_remove,
1475     .shutdown   = sonypi_shutdown,
1476 };
1477 
1478 static struct platform_device *sonypi_platform_device;
1479 
1480 static const struct dmi_system_id sonypi_dmi_table[] __initconst = {
1481     {
1482         .ident = "Sony Vaio",
1483         .matches = {
1484             DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
1485             DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"),
1486         },
1487     },
1488     {
1489         .ident = "Sony Vaio",
1490         .matches = {
1491             DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
1492             DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"),
1493         },
1494     },
1495     { }
1496 };
1497 
1498 static int __init sonypi_init(void)
1499 {
1500     int error;
1501 
1502     printk(KERN_INFO
1503         "sonypi: Sony Programmable I/O Controller Driver v%s.\n",
1504         SONYPI_DRIVER_VERSION);
1505 
1506     if (!dmi_check_system(sonypi_dmi_table))
1507         return -ENODEV;
1508 
1509     error = platform_driver_register(&sonypi_driver);
1510     if (error)
1511         return error;
1512 
1513     sonypi_platform_device = platform_device_alloc("sonypi", -1);
1514     if (!sonypi_platform_device) {
1515         error = -ENOMEM;
1516         goto err_driver_unregister;
1517     }
1518 
1519     error = platform_device_add(sonypi_platform_device);
1520     if (error)
1521         goto err_free_device;
1522 
1523 #ifdef CONFIG_ACPI
1524     if (acpi_bus_register_driver(&sonypi_acpi_driver) >= 0)
1525         acpi_driver_registered = 1;
1526 #endif
1527 
1528     return 0;
1529 
1530  err_free_device:
1531     platform_device_put(sonypi_platform_device);
1532  err_driver_unregister:
1533     platform_driver_unregister(&sonypi_driver);
1534     return error;
1535 }
1536 
1537 static void __exit sonypi_exit(void)
1538 {
1539 #ifdef CONFIG_ACPI
1540     if (acpi_driver_registered)
1541         acpi_bus_unregister_driver(&sonypi_acpi_driver);
1542 #endif
1543     platform_device_unregister(sonypi_platform_device);
1544     platform_driver_unregister(&sonypi_driver);
1545     printk(KERN_INFO "sonypi: removed.\n");
1546 }
1547 
1548 module_init(sonypi_init);
1549 module_exit(sonypi_exit);