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", |