aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Waling <erikw@acc.umu.se>2005-09-06 18:17:02 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:57:24 -0400
commitd2052c1676a39cae101a81f3da8a4ade8b668c88 (patch)
treebc812cc27e1800a1849cdebb97a6dc0bba5b8c93
parent2865cf001878d22d5fd12e5215621dffbcad76dc (diff)
[PATCH] sonypi SPIC initialisation fix
Newer Sony VAIO models (VGN-S480, VGN-S460, VGN-S3XP etc) use a new method to initialize the SPIC device. The new way to initialize (and disable) the device comes directly from the AML code in the _CRS, _SRS and _DIS methods from the DSDT table. This patch adds support for the new models. Signed-off-by: Erik Waling <erikw@acc.umu.se> Signed-off-by: Stelian Pop <stelian@popies.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--Documentation/sonypi.txt10
-rw-r--r--drivers/char/sonypi.c117
-rw-r--r--include/linux/sonypi.h2
3 files changed, 109 insertions, 20 deletions
diff --git a/Documentation/sonypi.txt b/Documentation/sonypi.txt
index 0f3b2405d09e..c1237a925505 100644
--- a/Documentation/sonypi.txt
+++ b/Documentation/sonypi.txt
@@ -99,6 +99,7 @@ statically linked into the kernel). Those options are:
99 SONYPI_MEYE_MASK 0x0400 99 SONYPI_MEYE_MASK 0x0400
100 SONYPI_MEMORYSTICK_MASK 0x0800 100 SONYPI_MEMORYSTICK_MASK 0x0800
101 SONYPI_BATTERY_MASK 0x1000 101 SONYPI_BATTERY_MASK 0x1000
102 SONYPI_WIRELESS_MASK 0x2000
102 103
103 useinput: if set (which is the default) two input devices are 104 useinput: if set (which is the default) two input devices are
104 created, one which interprets the jogdial events as 105 created, one which interprets the jogdial events as
@@ -137,6 +138,15 @@ Bugs:
137 speed handling etc). Use ACPI instead of APM if it works on your 138 speed handling etc). Use ACPI instead of APM if it works on your
138 laptop. 139 laptop.
139 140
141 - sonypi lacks the ability to distinguish between certain key
142 events on some models.
143
144 - some models with the nvidia card (geforce go 6200 tc) uses a
145 different way to adjust the backlighting of the screen. There
146 is a userspace utility to adjust the brightness on those models,
147 which can be downloaded from
148 http://www.acc.umu.se/~erikw/program/smartdimmer-0.1.tar.bz2
149
140 - since all development was done by reverse engineering, there is 150 - since all development was done by reverse engineering, there is
141 _absolutely no guarantee_ that this driver will not crash your 151 _absolutely no guarantee_ that this driver will not crash your
142 laptop. Permanently. 152 laptop. Permanently.
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index cefbe985e55c..35cf1edbc179 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -98,12 +98,13 @@ MODULE_PARM_DESC(useinput,
98 98
99#define SONYPI_DEVICE_MODEL_TYPE1 1 99#define SONYPI_DEVICE_MODEL_TYPE1 1
100#define SONYPI_DEVICE_MODEL_TYPE2 2 100#define SONYPI_DEVICE_MODEL_TYPE2 2
101#define SONYPI_DEVICE_MODEL_TYPE3 3
101 102
102/* type1 models use those */ 103/* type1 models use those */
103#define SONYPI_IRQ_PORT 0x8034 104#define SONYPI_IRQ_PORT 0x8034
104#define SONYPI_IRQ_SHIFT 22 105#define SONYPI_IRQ_SHIFT 22
105#define SONYPI_BASE 0x50 106#define SONYPI_TYPE1_BASE 0x50
106#define SONYPI_G10A (SONYPI_BASE+0x14) 107#define SONYPI_G10A (SONYPI_TYPE1_BASE+0x14)
107#define SONYPI_TYPE1_REGION_SIZE 0x08 108#define SONYPI_TYPE1_REGION_SIZE 0x08
108#define SONYPI_TYPE1_EVTYPE_OFFSET 0x04 109#define SONYPI_TYPE1_EVTYPE_OFFSET 0x04
109 110
@@ -114,6 +115,13 @@ MODULE_PARM_DESC(useinput,
114#define SONYPI_TYPE2_REGION_SIZE 0x20 115#define SONYPI_TYPE2_REGION_SIZE 0x20
115#define SONYPI_TYPE2_EVTYPE_OFFSET 0x12 116#define SONYPI_TYPE2_EVTYPE_OFFSET 0x12
116 117
118/* type3 series specifics */
119#define SONYPI_TYPE3_BASE 0x40
120#define SONYPI_TYPE3_GID2 (SONYPI_TYPE3_BASE+0x48) /* 16 bits */
121#define SONYPI_TYPE3_MISC (SONYPI_TYPE3_BASE+0x6d) /* 8 bits */
122#define SONYPI_TYPE3_REGION_SIZE 0x20
123#define SONYPI_TYPE3_EVTYPE_OFFSET 0x12
124
117/* battery / brightness addresses */ 125/* battery / brightness addresses */
118#define SONYPI_BAT_FLAGS 0x81 126#define SONYPI_BAT_FLAGS 0x81
119#define SONYPI_LCD_LIGHT 0x96 127#define SONYPI_LCD_LIGHT 0x96
@@ -159,6 +167,10 @@ static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
159 { 0x0, 0x0 } 167 { 0x0, 0x0 }
160}; 168};
161 169
170/* same as in type 2 models */
171static struct sonypi_ioport_list *sonypi_type3_ioport_list =
172 sonypi_type2_ioport_list;
173
162/* The set of possible interrupts */ 174/* The set of possible interrupts */
163struct sonypi_irq_list { 175struct sonypi_irq_list {
164 u16 irq; 176 u16 irq;
@@ -180,6 +192,9 @@ static struct sonypi_irq_list sonypi_type2_irq_list[] = {
180 { 0, 0x00 } /* no IRQ, 0x00 in SIRQ in AML */ 192 { 0, 0x00 } /* no IRQ, 0x00 in SIRQ in AML */
181}; 193};
182 194
195/* same as in type2 models */
196static struct sonypi_irq_list *sonypi_type3_irq_list = sonypi_type2_irq_list;
197
183#define SONYPI_CAMERA_BRIGHTNESS 0 198#define SONYPI_CAMERA_BRIGHTNESS 0
184#define SONYPI_CAMERA_CONTRAST 1 199#define SONYPI_CAMERA_CONTRAST 1
185#define SONYPI_CAMERA_HUE 2 200#define SONYPI_CAMERA_HUE 2
@@ -223,6 +238,7 @@ static struct sonypi_irq_list sonypi_type2_irq_list[] = {
223#define SONYPI_MEYE_MASK 0x00000400 238#define SONYPI_MEYE_MASK 0x00000400
224#define SONYPI_MEMORYSTICK_MASK 0x00000800 239#define SONYPI_MEMORYSTICK_MASK 0x00000800
225#define SONYPI_BATTERY_MASK 0x00001000 240#define SONYPI_BATTERY_MASK 0x00001000
241#define SONYPI_WIRELESS_MASK 0x00002000
226 242
227struct sonypi_event { 243struct sonypi_event {
228 u8 data; 244 u8 data;
@@ -305,6 +321,13 @@ static struct sonypi_event sonypi_blueev[] = {
305 { 0, 0 } 321 { 0, 0 }
306}; 322};
307 323
324/* The set of possible wireless events */
325static struct sonypi_event sonypi_wlessev[] = {
326 { 0x59, SONYPI_EVENT_WIRELESS_ON },
327 { 0x5a, SONYPI_EVENT_WIRELESS_OFF },
328 { 0, 0 }
329};
330
308/* The set of possible back button events */ 331/* The set of possible back button events */
309static struct sonypi_event sonypi_backev[] = { 332static struct sonypi_event sonypi_backev[] = {
310 { 0x20, SONYPI_EVENT_BACK_PRESSED }, 333 { 0x20, SONYPI_EVENT_BACK_PRESSED },
@@ -391,6 +414,12 @@ static struct sonypi_eventtypes {
391 { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, 414 { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
392 { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, 415 { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
393 416
417 { SONYPI_DEVICE_MODEL_TYPE3, 0, 0xffffffff, sonypi_releaseev },
418 { SONYPI_DEVICE_MODEL_TYPE3, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
419 { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
420 { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
421 { SONYPI_DEVICE_MODEL_TYPE3, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
422 { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
394 { 0 } 423 { 0 }
395}; 424};
396 425
@@ -563,6 +592,23 @@ static void sonypi_type2_srs(void)
563 udelay(10); 592 udelay(10);
564} 593}
565 594
595static void sonypi_type3_srs(void)
596{
597 u16 v16;
598 u8 v8;
599
600 /* This model type uses the same initialiazation of
601 * the embedded controller as the type2 models. */
602 sonypi_type2_srs();
603
604 /* Initialization of PCI config space of the LPC interface bridge. */
605 v16 = (sonypi_device.ioport1 & 0xFFF0) | 0x01;
606 pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, v16);
607 pci_read_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, &v8);
608 v8 = (v8 & 0xCF) | 0x10;
609 pci_write_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, v8);
610}
611
566/* Disables the device - this comes from the AML code in the ACPI bios */ 612/* Disables the device - this comes from the AML code in the ACPI bios */
567static void sonypi_type1_dis(void) 613static void sonypi_type1_dis(void)
568{ 614{
@@ -587,6 +633,13 @@ static void sonypi_type2_dis(void)
587 printk(KERN_WARNING "ec_write failed\n"); 633 printk(KERN_WARNING "ec_write failed\n");
588} 634}
589 635
636static void sonypi_type3_dis(void)
637{
638 sonypi_type2_dis();
639 udelay(10);
640 pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, 0);
641}
642
590static u8 sonypi_call1(u8 dev) 643static u8 sonypi_call1(u8 dev)
591{ 644{
592 u8 v1, v2; 645 u8 v1, v2;
@@ -1067,10 +1120,17 @@ static struct miscdevice sonypi_misc_device = {
1067 1120
1068static void sonypi_enable(unsigned int camera_on) 1121static void sonypi_enable(unsigned int camera_on)
1069{ 1122{
1070 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) 1123 switch (sonypi_device.model) {
1071 sonypi_type2_srs(); 1124 case SONYPI_DEVICE_MODEL_TYPE1:
1072 else
1073 sonypi_type1_srs(); 1125 sonypi_type1_srs();
1126 break;
1127 case SONYPI_DEVICE_MODEL_TYPE2:
1128 sonypi_type2_srs();
1129 break;
1130 case SONYPI_DEVICE_MODEL_TYPE3:
1131 sonypi_type3_srs();
1132 break;
1133 }
1074 1134
1075 sonypi_call1(0x82); 1135 sonypi_call1(0x82);
1076 sonypi_call2(0x81, 0xff); 1136 sonypi_call2(0x81, 0xff);
@@ -1094,10 +1154,18 @@ static int sonypi_disable(void)
1094 if (!SONYPI_ACPI_ACTIVE && fnkeyinit) 1154 if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
1095 outb(0xf1, 0xb2); 1155 outb(0xf1, 0xb2);
1096 1156
1097 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) 1157 switch (sonypi_device.model) {
1098 sonypi_type2_dis(); 1158 case SONYPI_DEVICE_MODEL_TYPE1:
1099 else
1100 sonypi_type1_dis(); 1159 sonypi_type1_dis();
1160 break;
1161 case SONYPI_DEVICE_MODEL_TYPE2:
1162 sonypi_type2_dis();
1163 break;
1164 case SONYPI_DEVICE_MODEL_TYPE3:
1165 sonypi_type3_dis();
1166 break;
1167 }
1168
1101 return 0; 1169 return 0;
1102} 1170}
1103 1171
@@ -1143,12 +1211,16 @@ static int __devinit sonypi_probe(void)
1143 struct sonypi_irq_list *irq_list; 1211 struct sonypi_irq_list *irq_list;
1144 struct pci_dev *pcidev; 1212 struct pci_dev *pcidev;
1145 1213
1146 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1214 if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1147 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 1215 PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
1216 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1;
1217 else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1218 PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
1219 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
1220 else
1221 sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
1148 1222
1149 sonypi_device.dev = pcidev; 1223 sonypi_device.dev = pcidev;
1150 sonypi_device.model = pcidev ?
1151 SONYPI_DEVICE_MODEL_TYPE1 : SONYPI_DEVICE_MODEL_TYPE2;
1152 1224
1153 spin_lock_init(&sonypi_device.fifo_lock); 1225 spin_lock_init(&sonypi_device.fifo_lock);
1154 sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, 1226 sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
@@ -1176,16 +1248,22 @@ static int __devinit sonypi_probe(void)
1176 goto out_miscreg; 1248 goto out_miscreg;
1177 } 1249 }
1178 1250
1179 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) { 1251
1252 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) {
1253 ioport_list = sonypi_type1_ioport_list;
1254 sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
1255 sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET;
1256 irq_list = sonypi_type1_irq_list;
1257 } else if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
1180 ioport_list = sonypi_type2_ioport_list; 1258 ioport_list = sonypi_type2_ioport_list;
1181 sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE; 1259 sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
1182 sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET; 1260 sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET;
1183 irq_list = sonypi_type2_irq_list; 1261 irq_list = sonypi_type2_irq_list;
1184 } else { 1262 } else {
1185 ioport_list = sonypi_type1_ioport_list; 1263 ioport_list = sonypi_type3_ioport_list;
1186 sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE; 1264 sonypi_device.region_size = SONYPI_TYPE3_REGION_SIZE;
1187 sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET; 1265 sonypi_device.evtype_offset = SONYPI_TYPE3_EVTYPE_OFFSET;
1188 irq_list = sonypi_type1_irq_list; 1266 irq_list = sonypi_type3_irq_list;
1189 } 1267 }
1190 1268
1191 for (i = 0; ioport_list[i].port1; i++) { 1269 for (i = 0; ioport_list[i].port1; i++) {
@@ -1274,11 +1352,10 @@ static int __devinit sonypi_probe(void)
1274 1352
1275 printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver" 1353 printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver"
1276 "v%s.\n", SONYPI_DRIVER_VERSION); 1354 "v%s.\n", SONYPI_DRIVER_VERSION);
1277 printk(KERN_INFO "sonypi: detected %s model, " 1355 printk(KERN_INFO "sonypi: detected type%d model, "
1278 "verbose = %d, fnkeyinit = %s, camera = %s, " 1356 "verbose = %d, fnkeyinit = %s, camera = %s, "
1279 "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n", 1357 "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n",
1280 (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ? 1358 sonypi_device.model,
1281 "type1" : "type2",
1282 verbose, 1359 verbose,
1283 fnkeyinit ? "on" : "off", 1360 fnkeyinit ? "on" : "off",
1284 camera ? "on" : "off", 1361 camera ? "on" : "off",
diff --git a/include/linux/sonypi.h b/include/linux/sonypi.h
index 768cbba617d0..f56d24734950 100644
--- a/include/linux/sonypi.h
+++ b/include/linux/sonypi.h
@@ -99,6 +99,8 @@
99#define SONYPI_EVENT_BATTERY_INSERT 57 99#define SONYPI_EVENT_BATTERY_INSERT 57
100#define SONYPI_EVENT_BATTERY_REMOVE 58 100#define SONYPI_EVENT_BATTERY_REMOVE 58
101#define SONYPI_EVENT_FNKEY_RELEASED 59 101#define SONYPI_EVENT_FNKEY_RELEASED 59
102#define SONYPI_EVENT_WIRELESS_ON 60
103#define SONYPI_EVENT_WIRELESS_OFF 61
102 104
103/* get/set brightness */ 105/* get/set brightness */
104#define SONYPI_IOCGBRT _IOR('v', 0, __u8) 106#define SONYPI_IOCGBRT _IOR('v', 0, __u8)