aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/sonypi.c
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 /drivers/char/sonypi.c
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>
Diffstat (limited to 'drivers/char/sonypi.c')
-rw-r--r--drivers/char/sonypi.c117
1 files changed, 97 insertions, 20 deletions
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",