38 #include <linux/module.h>
39 #include <linux/sched.h>
40 #include <linux/input.h>
41 #include <linux/pci.h>
45 #include <linux/poll.h>
47 #include <linux/wait.h>
55 #include <asm/uaccess.h>
58 #include <linux/sonypi.h>
60 #define SONYPI_DRIVER_VERSION "1.26"
67 static int minor = -1;
70 "minor number of the misc device, default is -1 (automatic)");
79 "set this if your Fn keys do not generate any event");
84 "set this if you have a MotionEye camera (PictureBook series)");
89 "set this if you want to enable backward compatibility mode");
91 static unsigned long mask = 0xffffffff;
94 "set this to the mask of event you want to enable (see doc)");
96 static int useinput = 1;
99 "set this if you would like sonypi to feed events to the input subsystem");
101 static int check_ioport = 1;
104 "set this to 0 if you think the automatic ioport check for sony-laptop is wrong");
106 #define SONYPI_DEVICE_MODEL_TYPE1 1
107 #define SONYPI_DEVICE_MODEL_TYPE2 2
108 #define SONYPI_DEVICE_MODEL_TYPE3 3
111 #define SONYPI_IRQ_PORT 0x8034
112 #define SONYPI_IRQ_SHIFT 22
113 #define SONYPI_TYPE1_BASE 0x50
114 #define SONYPI_G10A (SONYPI_TYPE1_BASE+0x14)
115 #define SONYPI_TYPE1_REGION_SIZE 0x08
116 #define SONYPI_TYPE1_EVTYPE_OFFSET 0x04
119 #define SONYPI_SIRQ 0x9b
120 #define SONYPI_SLOB 0x9c
121 #define SONYPI_SHIB 0x9d
122 #define SONYPI_TYPE2_REGION_SIZE 0x20
123 #define SONYPI_TYPE2_EVTYPE_OFFSET 0x12
126 #define SONYPI_TYPE3_BASE 0x40
127 #define SONYPI_TYPE3_GID2 (SONYPI_TYPE3_BASE+0x48)
128 #define SONYPI_TYPE3_MISC (SONYPI_TYPE3_BASE+0x6d)
129 #define SONYPI_TYPE3_REGION_SIZE 0x20
130 #define SONYPI_TYPE3_EVTYPE_OFFSET 0x12
133 #define SONYPI_BAT_FLAGS 0x81
134 #define SONYPI_LCD_LIGHT 0x96
135 #define SONYPI_BAT1_PCTRM 0xa0
136 #define SONYPI_BAT1_LEFT 0xa2
137 #define SONYPI_BAT1_MAXRT 0xa4
138 #define SONYPI_BAT2_PCTRM 0xa8
139 #define SONYPI_BAT2_LEFT 0xaa
140 #define SONYPI_BAT2_MAXRT 0xac
141 #define SONYPI_BAT1_MAXTK 0xb0
142 #define SONYPI_BAT1_FULL 0xb2
143 #define SONYPI_BAT2_MAXTK 0xb8
144 #define SONYPI_BAT2_FULL 0xba
147 #define SONYPI_FAN0_STATUS 0x93
148 #define SONYPI_TEMP_STATUS 0xC1
151 #define SONYPI_DATA_IOPORT 0x62
152 #define SONYPI_CST_IOPORT 0x66
179 sonypi_type2_ioport_list;
203 static struct sonypi_irq_list *sonypi_type3_irq_list = sonypi_type2_irq_list;
205 #define SONYPI_CAMERA_BRIGHTNESS 0
206 #define SONYPI_CAMERA_CONTRAST 1
207 #define SONYPI_CAMERA_HUE 2
208 #define SONYPI_CAMERA_COLOR 3
209 #define SONYPI_CAMERA_SHARPNESS 4
211 #define SONYPI_CAMERA_PICTURE 5
212 #define SONYPI_CAMERA_EXPOSURE_MASK 0xC
213 #define SONYPI_CAMERA_WHITE_BALANCE_MASK 0x3
214 #define SONYPI_CAMERA_PICTURE_MODE_MASK 0x30
215 #define SONYPI_CAMERA_MUTE_MASK 0x40
218 #define SONYPI_CAMERA_AGC 6
219 #define SONYPI_CAMERA_AGC_MASK 0x30
220 #define SONYPI_CAMERA_SHUTTER_MASK 0x7
222 #define SONYPI_CAMERA_SHUTDOWN_REQUEST 7
223 #define SONYPI_CAMERA_CONTROL 0x10
225 #define SONYPI_CAMERA_STATUS 7
226 #define SONYPI_CAMERA_STATUS_READY 0x2
227 #define SONYPI_CAMERA_STATUS_POSITION 0x4
229 #define SONYPI_DIRECTION_BACKWARDS 0x4
231 #define SONYPI_CAMERA_REVISION 8
232 #define SONYPI_CAMERA_ROMVERSION 9
235 #define SONYPI_JOGGER_MASK 0x00000001
236 #define SONYPI_CAPTURE_MASK 0x00000002
237 #define SONYPI_FNKEY_MASK 0x00000004
238 #define SONYPI_BLUETOOTH_MASK 0x00000008
239 #define SONYPI_PKEY_MASK 0x00000010
240 #define SONYPI_BACK_MASK 0x00000020
241 #define SONYPI_HELP_MASK 0x00000040
242 #define SONYPI_LID_MASK 0x00000080
243 #define SONYPI_ZOOM_MASK 0x00000100
244 #define SONYPI_THUMBPHRASE_MASK 0x00000200
245 #define SONYPI_MEYE_MASK 0x00000400
246 #define SONYPI_MEMORYSTICK_MASK 0x00000800
247 #define SONYPI_BATTERY_MASK 0x00001000
248 #define SONYPI_WIRELESS_MASK 0x00002000
391 static struct sonypi_eventtypes {
396 } sonypi_eventtypes[] = {
432 #define SONYPI_BUF_SIZE 128
438 } sonypi_inputkeys[] = {
478 static struct sonypi_device {
495 struct input_dev *input_jog_dev;
496 struct input_dev *input_key_dev;
498 struct kfifo input_fifo;
502 #define ITERATIONS_LONG 10000
503 #define ITERATIONS_SHORT 10
505 #define wait_on_command(quiet, command, iterations) { \
506 unsigned int n = iterations; \
507 while (--n && (command)) \
509 if (!n && (verbose || !quiet)) \
510 printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __func__, __LINE__); \
514 #define SONYPI_ACPI_ACTIVE (!acpi_disabled)
516 #define SONYPI_ACPI_ACTIVE 0
520 static struct acpi_device *sonypi_acpi_device;
521 static int acpi_driver_registered;
555 static int ec_read16(
u8 addr,
u16 *value)
558 if (sonypi_ec_read(addr, &val_lb))
560 if (sonypi_ec_read(addr + 1, &val_hb))
562 *value = val_lb | (val_hb << 8);
567 static void sonypi_type1_srs(
void)
571 pci_read_config_dword(sonypi_device.dev,
SONYPI_G10A, &v);
572 v = (v & 0xFFFF0000) | ((
u32) sonypi_device.ioport1);
573 pci_write_config_dword(sonypi_device.dev,
SONYPI_G10A, v);
575 pci_read_config_dword(sonypi_device.dev,
SONYPI_G10A, &v);
576 v = (v & 0xFFF0FFFF) |
577 (((
u32) sonypi_device.ioport1 ^ sonypi_device.ioport2) << 16);
578 pci_write_config_dword(sonypi_device.dev,
SONYPI_G10A, v);
585 pci_read_config_dword(sonypi_device.dev,
SONYPI_G10A, &v);
586 v = (v & 0xFF1FFFFF) | 0x00C00000;
587 pci_write_config_dword(sonypi_device.dev,
SONYPI_G10A, v);
590 static void sonypi_type2_srs(
void)
592 if (sonypi_ec_write(
SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8))
594 if (sonypi_ec_write(
SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF))
596 if (sonypi_ec_write(
SONYPI_SIRQ, sonypi_device.bits))
601 static void sonypi_type3_srs(
void)
611 v16 = (sonypi_device.ioport1 & 0xFFF0) | 0x01;
614 v8 = (v8 & 0xCF) | 0x10;
619 static void sonypi_type1_dis(
void)
623 pci_read_config_dword(sonypi_device.dev,
SONYPI_G10A, &v);
625 pci_write_config_dword(sonypi_device.dev,
SONYPI_G10A, v);
632 static void sonypi_type2_dis(
void)
642 static void sonypi_type3_dis(
void)
654 outb(dev, sonypi_device.ioport2);
655 v1 =
inb_p(sonypi_device.ioport2);
656 v2 =
inb_p(sonypi_device.ioport1);
660 static u8 sonypi_call2(
u8 dev,
u8 fn)
665 outb(dev, sonypi_device.ioport2);
667 outb(fn, sonypi_device.ioport1);
668 v1 =
inb_p(sonypi_device.ioport1);
672 static u8 sonypi_call3(
u8 dev,
u8 fn,
u8 v)
677 outb(dev, sonypi_device.ioport2);
679 outb(fn, sonypi_device.ioport1);
681 outb(v, sonypi_device.ioport1);
682 v1 =
inb_p(sonypi_device.ioport1);
688 static u8 sonypi_read(
u8 fn)
694 v1 = sonypi_call2(0x8f, fn);
695 v2 = sonypi_call2(0x8f, fn);
696 if (v1 == v2 && v1 != 0xff)
704 static void sonypi_set(
u8 fn,
u8 v)
710 static int sonypi_camera_ready(
void)
719 static void sonypi_camera_off(
void)
723 if (!sonypi_device.camera_power)
726 sonypi_call2(0x91, 0);
727 sonypi_device.camera_power = 0;
731 static void sonypi_camera_on(
void)
735 if (sonypi_device.camera_power)
738 for (j = 5; j > 0; j--) {
740 while (sonypi_call2(0x91, 0x1))
744 for (i = 400; i > 0; i--) {
745 if (sonypi_camera_ready())
758 sonypi_set(0x10, 0x5a);
759 sonypi_device.camera_power = 1;
763 static void sonypi_setbluetoothpower(
u8 state)
767 if (sonypi_device.bluetooth_power == state)
770 sonypi_call2(0x96, state);
772 sonypi_device.bluetooth_power =
state;
780 sizeof(kp), &sonypi_device.input_fifo_lock)
783 input_report_key(kp.dev, kp.key, 0);
788 static void sonypi_report_input_event(
u8 event)
790 struct input_dev *jog_dev = sonypi_device.input_jog_dev;
791 struct input_dev *key_dev = sonypi_device.input_key_dev;
804 input_report_rel(jog_dev,
REL_WHEEL, -1);
818 for (i = 0; sonypi_inputkeys[
i].sonypiev; i++)
819 if (event == sonypi_inputkeys[i].
sonypiev) {
821 kp.
key = sonypi_inputkeys[
i].inputev;
828 input_report_key(kp.
dev, kp.
key, 1);
831 (
unsigned char *)&kp,
sizeof(kp),
832 &sonypi_device.input_fifo_lock);
843 v1 =
inb_p(sonypi_device.ioport1);
844 v2 =
inb_p(sonypi_device.ioport1 + sonypi_device.evtype_offset);
846 for (i = 0; sonypi_eventtypes[
i].model; i++) {
847 if (sonypi_device.model != sonypi_eventtypes[i].model)
849 if ((v2 & sonypi_eventtypes[i].
data) !=
850 sonypi_eventtypes[i].data)
852 if (!(
mask & sonypi_eventtypes[i].
mask))
854 for (j = 0; sonypi_eventtypes[
i].events[
j].event; j++) {
855 if (v1 == sonypi_eventtypes[i].
events[j].data) {
856 event = sonypi_eventtypes[
i].events[
j].event;
864 "sonypi: unknown event port1=0x%02x,port2=0x%02x\n",
874 "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
877 sonypi_report_input_event(event);
880 if (sonypi_acpi_device)
881 acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
885 sizeof(event), &sonypi_device.fifo_lock);
892 static int sonypi_misc_fasync(
int fd,
struct file *filp,
int on)
894 return fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
900 sonypi_device.open_count--;
909 if (!sonypi_device.open_count)
911 sonypi_device.open_count++;
917 static ssize_t sonypi_misc_read(
struct file *file,
char __user *
buf,
923 if ((
kfifo_len(&sonypi_device.fifo) == 0) &&
932 while (ret < count &&
934 &sonypi_device.fifo_lock) ==
sizeof(c))) {
941 struct inode *inode = file->
f_path.dentry->d_inode;
948 static unsigned int sonypi_misc_poll(
struct file *file,
poll_table *
wait)
950 poll_wait(file, &sonypi_device.fifo_proc_list, wait);
956 static long sonypi_misc_ioctl(
struct file *
fp,
957 unsigned int cmd,
unsigned long arg)
1024 val8 = sonypi_device.bluetooth_power;
1033 sonypi_setbluetoothpower(val8);
1070 .read = sonypi_misc_read,
1071 .poll = sonypi_misc_poll,
1072 .open = sonypi_misc_open,
1073 .release = sonypi_misc_release,
1074 .fasync = sonypi_misc_fasync,
1075 .unlocked_ioctl = sonypi_misc_ioctl,
1079 static struct miscdevice sonypi_misc_device = {
1082 .fops = &sonypi_misc_fops,
1085 static void sonypi_enable(
unsigned int camera_on)
1087 switch (sonypi_device.model) {
1100 sonypi_call2(0x81, 0xff);
1101 sonypi_call1(compat ? 0x92 : 0x82);
1107 if (camera && camera_on)
1111 static int sonypi_disable(
void)
1113 sonypi_call2(0x81, 0);
1115 sonypi_camera_off();
1121 switch (sonypi_device.model) {
1137 static int sonypi_acpi_add(
struct acpi_device *
device)
1139 sonypi_acpi_device = device;
1140 strcpy(acpi_device_name(device),
"Sony laptop hotkeys");
1141 strcpy(acpi_device_class(device),
"sony/hotkey");
1145 static int sonypi_acpi_remove(
struct acpi_device *device,
int type)
1147 sonypi_acpi_device =
NULL;
1156 static struct acpi_driver sonypi_acpi_driver = {
1159 .ids = sonypi_device_ids,
1161 .add = sonypi_acpi_add,
1162 .remove = sonypi_acpi_remove,
1169 struct input_dev *jog_dev;
1170 struct input_dev *key_dev;
1174 sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
1178 jog_dev->name =
"Sony Vaio Jogdial";
1179 jog_dev->id.bustype =
BUS_ISA;
1181 jog_dev->dev.parent = &pdev->
dev;
1187 sonypi_device.input_key_dev = key_dev = input_allocate_device();
1190 goto err_free_jogdev;
1193 key_dev->name =
"Sony Vaio Keys";
1194 key_dev->id.bustype =
BUS_ISA;
1196 key_dev->dev.parent = &pdev->
dev;
1200 for (i = 0; sonypi_inputkeys[
i].sonypiev; i++)
1201 if (sonypi_inputkeys[i].
inputev)
1202 set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
1204 error = input_register_device(jog_dev);
1206 goto err_free_keydev;
1208 error = input_register_device(key_dev);
1210 goto err_unregister_jogdev;
1214 err_unregister_jogdev:
1215 input_unregister_device(jog_dev);
1219 input_free_device(key_dev);
1220 sonypi_device.input_key_dev =
NULL;
1222 input_free_device(jog_dev);
1223 sonypi_device.input_jog_dev =
NULL;
1228 static int __devinit sonypi_setup_ioports(
struct sonypi_device *dev,
1240 while (check_ioport && check->
port1) {
1242 sonypi_device.region_size,
1243 "Sony Programmable I/O Device Check")) {
1244 printk(
KERN_ERR "sonypi: ioport 0x%.4x busy, using sony-laptop? "
1245 "if not use check_ioport=0\n",
1253 while (ioport_list->
port1) {
1256 sonypi_device.region_size,
1257 "Sony Programmable I/O Device")) {
1258 dev->ioport1 = ioport_list->
port1;
1259 dev->ioport2 = ioport_list->
port2;
1268 static int __devinit sonypi_setup_irq(
struct sonypi_device *dev,
1271 while (irq_list->
irq) {
1275 dev->irq = irq_list->
irq;
1276 dev->bits = irq_list->
bits;
1285 static void __devinit sonypi_display_info(
void)
1288 "verbose = %d, fnkeyinit = %s, camera = %s, "
1289 "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n",
1290 sonypi_device.model,
1292 fnkeyinit ?
"on" :
"off",
1293 camera ?
"on" :
"off",
1294 compat ?
"on" :
"off",
1296 useinput ?
"on" :
"off",
1298 printk(
KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
1300 sonypi_device.ioport1, sonypi_device.ioport2);
1304 sonypi_misc_device.
minor);
1315 "and report failures, see also "
1316 "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");
1327 sonypi_device.bluetooth_power = -1;
1344 goto err_put_pcidev;
1347 sonypi_device.dev =
pcidev;
1350 ioport_list = sonypi_type1_ioport_list;
1353 irq_list = sonypi_type1_irq_list;
1355 ioport_list = sonypi_type2_ioport_list;
1358 irq_list = sonypi_type2_irq_list;
1360 ioport_list = sonypi_type3_ioport_list;
1363 irq_list = sonypi_type3_irq_list;
1366 error = sonypi_setup_ioports(&sonypi_device, ioport_list);
1369 goto err_disable_pcidev;
1372 error = sonypi_setup_irq(&sonypi_device, irq_list);
1375 goto err_free_ioports;
1386 sonypi_display_info();
1390 error = sonypi_create_input_devices(dev);
1393 "sonypi: failed to create input devices\n");
1394 goto err_miscdev_unregister;
1402 goto err_inpdev_unregister;
1405 INIT_WORK(&sonypi_device.input_work, input_keyrelease);
1412 err_inpdev_unregister:
1413 input_unregister_device(sonypi_device.input_key_dev);
1414 input_unregister_device(sonypi_device.input_jog_dev);
1415 err_miscdev_unregister:
1418 free_irq(sonypi_device.irq, sonypi_irq);
1420 release_region(sonypi_device.ioport1, sonypi_device.region_size);
1439 input_unregister_device(sonypi_device.input_key_dev);
1440 input_unregister_device(sonypi_device.input_jog_dev);
1446 free_irq(sonypi_device.irq, sonypi_irq);
1447 release_region(sonypi_device.ioport1, sonypi_device.region_size);
1449 if (sonypi_device.dev) {
1459 #ifdef CONFIG_PM_SLEEP
1460 static int old_camera_power;
1462 static int sonypi_suspend(
struct device *dev)
1464 old_camera_power = sonypi_device.camera_power;
1470 static int sonypi_resume(
struct device *dev)
1472 sonypi_enable(old_camera_power);
1477 #define SONYPI_PM (&sonypi_pm)
1479 #define SONYPI_PM NULL
1493 .probe = sonypi_probe,
1495 .shutdown = sonypi_shutdown,
1502 .ident =
"Sony Vaio",
1509 .ident =
"Sony Vaio",
1518 static int __init sonypi_init(
void)
1523 "sonypi: Sony Programmable I/O Controller Driver v%s.\n",
1534 if (!sonypi_platform_device) {
1536 goto err_driver_unregister;
1541 goto err_free_device;
1545 acpi_driver_registered = 1;
1552 err_driver_unregister:
1557 static void __exit sonypi_exit(
void)
1560 if (acpi_driver_registered)