diff options
Diffstat (limited to 'drivers/char/sonypi.c')
| -rw-r--r-- | drivers/char/sonypi.c | 118 |
1 files changed, 97 insertions, 21 deletions
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index cefbe985e55c..36ae9ad2598c 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 */ | ||
| 171 | static 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 */ |
| 163 | struct sonypi_irq_list { | 175 | struct 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 */ | ||
| 196 | static 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 | ||
| 227 | struct sonypi_event { | 243 | struct 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 */ | ||
| 325 | static 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 */ |
| 309 | static struct sonypi_event sonypi_backev[] = { | 332 | static struct sonypi_event sonypi_backev[] = { |
| 310 | { 0x20, SONYPI_EVENT_BACK_PRESSED }, | 333 | { 0x20, SONYPI_EVENT_BACK_PRESSED }, |
| @@ -383,7 +406,6 @@ static struct sonypi_eventtypes { | |||
| 383 | { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, | 406 | { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, |
| 384 | { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev }, | 407 | { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev }, |
| 385 | { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev }, | 408 | { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev }, |
| 386 | { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev }, | ||
| 387 | { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_HELP_MASK, sonypi_helpev }, | 409 | { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_HELP_MASK, sonypi_helpev }, |
| 388 | { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev }, | 410 | { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev }, |
| 389 | { SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev }, | 411 | { SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev }, |
| @@ -391,6 +413,12 @@ static struct sonypi_eventtypes { | |||
| 391 | { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, | 413 | { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, |
| 392 | { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, | 414 | { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, |
| 393 | 415 | ||
| 416 | { SONYPI_DEVICE_MODEL_TYPE3, 0, 0xffffffff, sonypi_releaseev }, | ||
| 417 | { SONYPI_DEVICE_MODEL_TYPE3, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, | ||
| 418 | { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev }, | ||
| 419 | { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, | ||
| 420 | { SONYPI_DEVICE_MODEL_TYPE3, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, | ||
| 421 | { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, | ||
| 394 | { 0 } | 422 | { 0 } |
| 395 | }; | 423 | }; |
| 396 | 424 | ||
| @@ -563,6 +591,23 @@ static void sonypi_type2_srs(void) | |||
| 563 | udelay(10); | 591 | udelay(10); |
| 564 | } | 592 | } |
| 565 | 593 | ||
| 594 | static void sonypi_type3_srs(void) | ||
| 595 | { | ||
| 596 | u16 v16; | ||
| 597 | u8 v8; | ||
| 598 | |||
| 599 | /* This model type uses the same initialiazation of | ||
| 600 | * the embedded controller as the type2 models. */ | ||
| 601 | sonypi_type2_srs(); | ||
| 602 | |||
| 603 | /* Initialization of PCI config space of the LPC interface bridge. */ | ||
| 604 | v16 = (sonypi_device.ioport1 & 0xFFF0) | 0x01; | ||
| 605 | pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, v16); | ||
| 606 | pci_read_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, &v8); | ||
| 607 | v8 = (v8 & 0xCF) | 0x10; | ||
| 608 | pci_write_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, v8); | ||
| 609 | } | ||
| 610 | |||
| 566 | /* Disables the device - this comes from the AML code in the ACPI bios */ | 611 | /* Disables the device - this comes from the AML code in the ACPI bios */ |
| 567 | static void sonypi_type1_dis(void) | 612 | static void sonypi_type1_dis(void) |
| 568 | { | 613 | { |
| @@ -587,6 +632,13 @@ static void sonypi_type2_dis(void) | |||
| 587 | printk(KERN_WARNING "ec_write failed\n"); | 632 | printk(KERN_WARNING "ec_write failed\n"); |
| 588 | } | 633 | } |
| 589 | 634 | ||
| 635 | static void sonypi_type3_dis(void) | ||
| 636 | { | ||
| 637 | sonypi_type2_dis(); | ||
| 638 | udelay(10); | ||
| 639 | pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, 0); | ||
| 640 | } | ||
| 641 | |||
| 590 | static u8 sonypi_call1(u8 dev) | 642 | static u8 sonypi_call1(u8 dev) |
| 591 | { | 643 | { |
| 592 | u8 v1, v2; | 644 | u8 v1, v2; |
| @@ -1067,10 +1119,17 @@ static struct miscdevice sonypi_misc_device = { | |||
| 1067 | 1119 | ||
| 1068 | static void sonypi_enable(unsigned int camera_on) | 1120 | static void sonypi_enable(unsigned int camera_on) |
| 1069 | { | 1121 | { |
| 1070 | if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) | 1122 | switch (sonypi_device.model) { |
| 1071 | sonypi_type2_srs(); | 1123 | case SONYPI_DEVICE_MODEL_TYPE1: |
| 1072 | else | ||
| 1073 | sonypi_type1_srs(); | 1124 | sonypi_type1_srs(); |
| 1125 | break; | ||
| 1126 | case SONYPI_DEVICE_MODEL_TYPE2: | ||
| 1127 | sonypi_type2_srs(); | ||
| 1128 | break; | ||
| 1129 | case SONYPI_DEVICE_MODEL_TYPE3: | ||
| 1130 | sonypi_type3_srs(); | ||
| 1131 | break; | ||
| 1132 | } | ||
| 1074 | 1133 | ||
| 1075 | sonypi_call1(0x82); | 1134 | sonypi_call1(0x82); |
| 1076 | sonypi_call2(0x81, 0xff); | 1135 | sonypi_call2(0x81, 0xff); |
| @@ -1094,10 +1153,18 @@ static int sonypi_disable(void) | |||
| 1094 | if (!SONYPI_ACPI_ACTIVE && fnkeyinit) | 1153 | if (!SONYPI_ACPI_ACTIVE && fnkeyinit) |
| 1095 | outb(0xf1, 0xb2); | 1154 | outb(0xf1, 0xb2); |
| 1096 | 1155 | ||
| 1097 | if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) | 1156 | switch (sonypi_device.model) { |
| 1098 | sonypi_type2_dis(); | 1157 | case SONYPI_DEVICE_MODEL_TYPE1: |
| 1099 | else | ||
| 1100 | sonypi_type1_dis(); | 1158 | sonypi_type1_dis(); |
| 1159 | break; | ||
| 1160 | case SONYPI_DEVICE_MODEL_TYPE2: | ||
| 1161 | sonypi_type2_dis(); | ||
| 1162 | break; | ||
| 1163 | case SONYPI_DEVICE_MODEL_TYPE3: | ||
| 1164 | sonypi_type3_dis(); | ||
| 1165 | break; | ||
| 1166 | } | ||
| 1167 | |||
| 1101 | return 0; | 1168 | return 0; |
| 1102 | } | 1169 | } |
| 1103 | 1170 | ||
| @@ -1143,12 +1210,16 @@ static int __devinit sonypi_probe(void) | |||
| 1143 | struct sonypi_irq_list *irq_list; | 1210 | struct sonypi_irq_list *irq_list; |
| 1144 | struct pci_dev *pcidev; | 1211 | struct pci_dev *pcidev; |
| 1145 | 1212 | ||
| 1146 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1213 | if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 1147 | PCI_DEVICE_ID_INTEL_82371AB_3, NULL); | 1214 | PCI_DEVICE_ID_INTEL_82371AB_3, NULL))) |
| 1215 | sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1; | ||
| 1216 | else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
| 1217 | PCI_DEVICE_ID_INTEL_ICH6_1, NULL))) | ||
| 1218 | sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; | ||
| 1219 | else | ||
| 1220 | sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2; | ||
| 1148 | 1221 | ||
| 1149 | sonypi_device.dev = pcidev; | 1222 | sonypi_device.dev = pcidev; |
| 1150 | sonypi_device.model = pcidev ? | ||
| 1151 | SONYPI_DEVICE_MODEL_TYPE1 : SONYPI_DEVICE_MODEL_TYPE2; | ||
| 1152 | 1223 | ||
| 1153 | spin_lock_init(&sonypi_device.fifo_lock); | 1224 | spin_lock_init(&sonypi_device.fifo_lock); |
| 1154 | sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, | 1225 | sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, |
| @@ -1176,16 +1247,22 @@ static int __devinit sonypi_probe(void) | |||
| 1176 | goto out_miscreg; | 1247 | goto out_miscreg; |
| 1177 | } | 1248 | } |
| 1178 | 1249 | ||
| 1179 | if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) { | 1250 | |
| 1251 | if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) { | ||
| 1252 | ioport_list = sonypi_type1_ioport_list; | ||
| 1253 | sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE; | ||
| 1254 | sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET; | ||
| 1255 | irq_list = sonypi_type1_irq_list; | ||
| 1256 | } else if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) { | ||
| 1180 | ioport_list = sonypi_type2_ioport_list; | 1257 | ioport_list = sonypi_type2_ioport_list; |
| 1181 | sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE; | 1258 | sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE; |
| 1182 | sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET; | 1259 | sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET; |
| 1183 | irq_list = sonypi_type2_irq_list; | 1260 | irq_list = sonypi_type2_irq_list; |
| 1184 | } else { | 1261 | } else { |
| 1185 | ioport_list = sonypi_type1_ioport_list; | 1262 | ioport_list = sonypi_type3_ioport_list; |
| 1186 | sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE; | 1263 | sonypi_device.region_size = SONYPI_TYPE3_REGION_SIZE; |
| 1187 | sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET; | 1264 | sonypi_device.evtype_offset = SONYPI_TYPE3_EVTYPE_OFFSET; |
| 1188 | irq_list = sonypi_type1_irq_list; | 1265 | irq_list = sonypi_type3_irq_list; |
| 1189 | } | 1266 | } |
| 1190 | 1267 | ||
| 1191 | for (i = 0; ioport_list[i].port1; i++) { | 1268 | for (i = 0; ioport_list[i].port1; i++) { |
| @@ -1274,11 +1351,10 @@ static int __devinit sonypi_probe(void) | |||
| 1274 | 1351 | ||
| 1275 | printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver" | 1352 | printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver" |
| 1276 | "v%s.\n", SONYPI_DRIVER_VERSION); | 1353 | "v%s.\n", SONYPI_DRIVER_VERSION); |
| 1277 | printk(KERN_INFO "sonypi: detected %s model, " | 1354 | printk(KERN_INFO "sonypi: detected type%d model, " |
| 1278 | "verbose = %d, fnkeyinit = %s, camera = %s, " | 1355 | "verbose = %d, fnkeyinit = %s, camera = %s, " |
| 1279 | "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n", | 1356 | "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n", |
| 1280 | (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ? | 1357 | sonypi_device.model, |
| 1281 | "type1" : "type2", | ||
| 1282 | verbose, | 1358 | verbose, |
| 1283 | fnkeyinit ? "on" : "off", | 1359 | fnkeyinit ? "on" : "off", |
| 1284 | camera ? "on" : "off", | 1360 | camera ? "on" : "off", |
