diff options
author | Corentin Chary <corentincj@iksaif.net> | 2009-11-30 15:42:42 -0500 |
---|---|---|
committer | Corentin Chary <corentincj@iksaif.net> | 2010-02-28 13:35:10 -0500 |
commit | 600ad5201d3b9b87159ede7359adccb98635fd48 (patch) | |
tree | d2e361b1e87a96300cacb0e232c6a79a72abe4da /drivers/platform/x86/asus-laptop.c | |
parent | 619d8b1187f2e13f6f848b1b2a4d83c2c9e2a140 (diff) |
asus-laptop: change initialization order
Clean asus-laptop initialization to match new eeepc-laptop code.
Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Diffstat (limited to 'drivers/platform/x86/asus-laptop.c')
-rw-r--r-- | drivers/platform/x86/asus-laptop.c | 369 |
1 files changed, 180 insertions, 189 deletions
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 74463a07d48b..8834405be1fd 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -201,6 +201,8 @@ ASUS_HANDLE(kled_get, ASUS_HOTK_PREFIX "GLKB"); | |||
201 | */ | 201 | */ |
202 | struct asus_hotk { | 202 | struct asus_hotk { |
203 | char *name; /* laptop name */ | 203 | char *name; /* laptop name */ |
204 | |||
205 | struct platform_device *platform_device; | ||
204 | struct acpi_device *device; /* the device we are in */ | 206 | struct acpi_device *device; /* the device we are in */ |
205 | acpi_handle handle; /* the handle of the hotk device */ | 207 | acpi_handle handle; /* the handle of the hotk device */ |
206 | char status; /* status of the hotk, for LEDs, ... */ | 208 | char status; /* status of the hotk, for LEDs, ... */ |
@@ -222,33 +224,6 @@ static struct acpi_table_header *asus_info; | |||
222 | /* The actual device the driver binds to */ | 224 | /* The actual device the driver binds to */ |
223 | static struct asus_hotk *hotk; | 225 | static struct asus_hotk *hotk; |
224 | 226 | ||
225 | /* | ||
226 | * The hotkey driver declaration | ||
227 | */ | ||
228 | static const struct acpi_device_id asus_device_ids[] = { | ||
229 | {"ATK0100", 0}, | ||
230 | {"ATK0101", 0}, | ||
231 | {"", 0}, | ||
232 | }; | ||
233 | MODULE_DEVICE_TABLE(acpi, asus_device_ids); | ||
234 | |||
235 | static int asus_hotk_add(struct acpi_device *device); | ||
236 | static int asus_hotk_remove(struct acpi_device *device, int type); | ||
237 | static void asus_hotk_notify(struct acpi_device *device, u32 event); | ||
238 | |||
239 | static struct acpi_driver asus_hotk_driver = { | ||
240 | .name = ASUS_HOTK_NAME, | ||
241 | .class = ASUS_HOTK_CLASS, | ||
242 | .owner = THIS_MODULE, | ||
243 | .ids = asus_device_ids, | ||
244 | .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, | ||
245 | .ops = { | ||
246 | .add = asus_hotk_add, | ||
247 | .remove = asus_hotk_remove, | ||
248 | .notify = asus_hotk_notify, | ||
249 | }, | ||
250 | }; | ||
251 | |||
252 | /* The backlight device /sys/class/backlight */ | 227 | /* The backlight device /sys/class/backlight */ |
253 | static struct backlight_device *asus_backlight_device; | 228 | static struct backlight_device *asus_backlight_device; |
254 | 229 | ||
@@ -936,7 +911,7 @@ static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode) | |||
936 | return -EINVAL; | 911 | return -EINVAL; |
937 | } | 912 | } |
938 | 913 | ||
939 | static void asus_hotk_notify(struct acpi_device *device, u32 event) | 914 | static void asus_acpi_notify(struct acpi_device *device, u32 event) |
940 | { | 915 | { |
941 | static struct key_entry *key; | 916 | static struct key_entry *key; |
942 | u16 count; | 917 | u16 count; |
@@ -1013,19 +988,49 @@ static struct attribute *asuspf_attributes[] = { | |||
1013 | NULL | 988 | NULL |
1014 | }; | 989 | }; |
1015 | 990 | ||
1016 | static struct attribute_group asuspf_attribute_group = { | 991 | static struct attribute_group platform_attribute_group = { |
1017 | .attrs = asuspf_attributes | 992 | .attrs = asuspf_attributes |
1018 | }; | 993 | }; |
1019 | 994 | ||
1020 | static struct platform_driver asuspf_driver = { | 995 | static int asus_platform_init(void) |
996 | { | ||
997 | int result; | ||
998 | |||
999 | hotk->platform_device = platform_device_alloc(ASUS_HOTK_FILE, -1); | ||
1000 | if (!hotk->platform_device) | ||
1001 | return -ENOMEM; | ||
1002 | |||
1003 | result = platform_device_add(hotk->platform_device); | ||
1004 | if (result) | ||
1005 | goto fail_platform_device; | ||
1006 | |||
1007 | result = sysfs_create_group(&hotk->platform_device->dev.kobj, | ||
1008 | &platform_attribute_group); | ||
1009 | if (result) | ||
1010 | goto fail_sysfs; | ||
1011 | return 0; | ||
1012 | |||
1013 | fail_sysfs: | ||
1014 | platform_device_del(hotk->platform_device); | ||
1015 | fail_platform_device: | ||
1016 | platform_device_put(hotk->platform_device); | ||
1017 | return result; | ||
1018 | } | ||
1019 | |||
1020 | static void asus_platform_exit(void) | ||
1021 | { | ||
1022 | sysfs_remove_group(&hotk->platform_device->dev.kobj, | ||
1023 | &platform_attribute_group); | ||
1024 | platform_device_unregister(hotk->platform_device); | ||
1025 | } | ||
1026 | |||
1027 | static struct platform_driver platform_driver = { | ||
1021 | .driver = { | 1028 | .driver = { |
1022 | .name = ASUS_HOTK_FILE, | 1029 | .name = ASUS_HOTK_FILE, |
1023 | .owner = THIS_MODULE, | 1030 | .owner = THIS_MODULE, |
1024 | } | 1031 | } |
1025 | }; | 1032 | }; |
1026 | 1033 | ||
1027 | static struct platform_device *asuspf_device; | ||
1028 | |||
1029 | static void asus_hotk_add_fs(void) | 1034 | static void asus_hotk_add_fs(void) |
1030 | { | 1035 | { |
1031 | ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL); | 1036 | ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL); |
@@ -1196,7 +1201,7 @@ static int asus_hotk_get_info(void) | |||
1196 | return AE_OK; | 1201 | return AE_OK; |
1197 | } | 1202 | } |
1198 | 1203 | ||
1199 | static int asus_input_init(void) | 1204 | static int asus_input_init(struct device *dev) |
1200 | { | 1205 | { |
1201 | const struct key_entry *key; | 1206 | const struct key_entry *key; |
1202 | int result; | 1207 | int result; |
@@ -1207,6 +1212,7 @@ static int asus_input_init(void) | |||
1207 | return 0; | 1212 | return 0; |
1208 | } | 1213 | } |
1209 | hotk->inputdev->name = "Asus Laptop extra buttons"; | 1214 | hotk->inputdev->name = "Asus Laptop extra buttons"; |
1215 | hotk->inputdev->dev.parent = dev; | ||
1210 | hotk->inputdev->phys = ASUS_HOTK_FILE "/input0"; | 1216 | hotk->inputdev->phys = ASUS_HOTK_FILE "/input0"; |
1211 | hotk->inputdev->id.bustype = BUS_HOST; | 1217 | hotk->inputdev->id.bustype = BUS_HOST; |
1212 | hotk->inputdev->getkeycode = asus_getkeycode; | 1218 | hotk->inputdev->getkeycode = asus_getkeycode; |
@@ -1228,101 +1234,6 @@ static int asus_input_init(void) | |||
1228 | return result; | 1234 | return result; |
1229 | } | 1235 | } |
1230 | 1236 | ||
1231 | static int asus_hotk_check(void) | ||
1232 | { | ||
1233 | int result = 0; | ||
1234 | |||
1235 | result = acpi_bus_get_status(hotk->device); | ||
1236 | if (result) | ||
1237 | return result; | ||
1238 | |||
1239 | if (hotk->device->status.present) { | ||
1240 | result = asus_hotk_get_info(); | ||
1241 | } else { | ||
1242 | pr_err("Hotkey device not present, aborting\n"); | ||
1243 | return -EINVAL; | ||
1244 | } | ||
1245 | |||
1246 | return result; | ||
1247 | } | ||
1248 | |||
1249 | static int asus_hotk_found; | ||
1250 | |||
1251 | static int asus_hotk_add(struct acpi_device *device) | ||
1252 | { | ||
1253 | int result; | ||
1254 | |||
1255 | pr_notice("Asus Laptop Support version %s\n", | ||
1256 | ASUS_LAPTOP_VERSION); | ||
1257 | |||
1258 | hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); | ||
1259 | if (!hotk) | ||
1260 | return -ENOMEM; | ||
1261 | |||
1262 | hotk->handle = device->handle; | ||
1263 | strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); | ||
1264 | strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); | ||
1265 | device->driver_data = hotk; | ||
1266 | hotk->device = device; | ||
1267 | |||
1268 | result = asus_hotk_check(); | ||
1269 | if (result) | ||
1270 | goto end; | ||
1271 | |||
1272 | asus_hotk_add_fs(); | ||
1273 | |||
1274 | asus_hotk_found = 1; | ||
1275 | |||
1276 | /* WLED and BLED are on by default */ | ||
1277 | if (bluetooth_status != -1) | ||
1278 | write_status(bt_switch_handle, !!bluetooth_status, BT_ON); | ||
1279 | if (wireless_status != -1) | ||
1280 | write_status(wl_switch_handle, !!wireless_status, WL_ON); | ||
1281 | |||
1282 | /* If the h/w switch is off, we need to check the real status */ | ||
1283 | write_status(NULL, read_status(BT_ON), BT_ON); | ||
1284 | write_status(NULL, read_status(WL_ON), WL_ON); | ||
1285 | |||
1286 | /* LCD Backlight is on by default */ | ||
1287 | write_status(NULL, 1, LCD_ON); | ||
1288 | |||
1289 | /* Keyboard Backlight is on by default */ | ||
1290 | if (kled_set_handle) | ||
1291 | set_kled_lvl(1); | ||
1292 | |||
1293 | /* LED display is off by default */ | ||
1294 | hotk->ledd_status = 0xFFF; | ||
1295 | |||
1296 | /* Set initial values of light sensor and level */ | ||
1297 | hotk->light_switch = 0; /* Default to light sensor disabled */ | ||
1298 | hotk->light_level = 5; /* level 5 for sensor sensitivity */ | ||
1299 | |||
1300 | if (ls_switch_handle) | ||
1301 | set_light_sens_switch(hotk->light_switch); | ||
1302 | |||
1303 | if (ls_level_handle) | ||
1304 | set_light_sens_level(hotk->light_level); | ||
1305 | |||
1306 | /* GPS is on by default */ | ||
1307 | write_status(NULL, 1, GPS_ON); | ||
1308 | |||
1309 | end: | ||
1310 | if (result) { | ||
1311 | kfree(hotk->name); | ||
1312 | kfree(hotk); | ||
1313 | } | ||
1314 | |||
1315 | return result; | ||
1316 | } | ||
1317 | |||
1318 | static int asus_hotk_remove(struct acpi_device *device, int type) | ||
1319 | { | ||
1320 | kfree(hotk->name); | ||
1321 | kfree(hotk); | ||
1322 | |||
1323 | return 0; | ||
1324 | } | ||
1325 | |||
1326 | static void asus_backlight_exit(void) | 1237 | static void asus_backlight_exit(void) |
1327 | { | 1238 | { |
1328 | if (asus_backlight_device) | 1239 | if (asus_backlight_device) |
@@ -1350,18 +1261,6 @@ static void asus_input_exit(void) | |||
1350 | input_unregister_device(hotk->inputdev); | 1261 | input_unregister_device(hotk->inputdev); |
1351 | } | 1262 | } |
1352 | 1263 | ||
1353 | static void __exit asus_laptop_exit(void) | ||
1354 | { | ||
1355 | asus_backlight_exit(); | ||
1356 | asus_led_exit(); | ||
1357 | asus_input_exit(); | ||
1358 | |||
1359 | acpi_bus_unregister_driver(&asus_hotk_driver); | ||
1360 | sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); | ||
1361 | platform_device_unregister(asuspf_device); | ||
1362 | platform_driver_unregister(&asuspf_driver); | ||
1363 | } | ||
1364 | |||
1365 | static int asus_backlight_init(struct device *dev) | 1264 | static int asus_backlight_init(struct device *dev) |
1366 | { | 1265 | { |
1367 | struct backlight_device *bd; | 1266 | struct backlight_device *bd; |
@@ -1448,87 +1347,179 @@ out: | |||
1448 | return rv; | 1347 | return rv; |
1449 | } | 1348 | } |
1450 | 1349 | ||
1451 | static int __init asus_laptop_init(void) | 1350 | |
1351 | static bool asus_device_present; | ||
1352 | |||
1353 | static int __devinit asus_acpi_init(struct acpi_device *device) | ||
1452 | { | 1354 | { |
1453 | int result; | 1355 | int result = 0; |
1454 | 1356 | ||
1455 | result = acpi_bus_register_driver(&asus_hotk_driver); | 1357 | result = acpi_bus_get_status(hotk->device); |
1456 | if (result < 0) | 1358 | if (result) |
1457 | return result; | 1359 | return result; |
1458 | 1360 | if (!hotk->device->status.present) { | |
1459 | /* | 1361 | pr_err("Hotkey device not present, aborting\n"); |
1460 | * This is a bit of a kludge. We only want this module loaded | ||
1461 | * for ASUS systems, but there's currently no way to probe the | ||
1462 | * ACPI namespace for ASUS HIDs. So we just return failure if | ||
1463 | * we didn't find one, which will cause the module to be | ||
1464 | * unloaded. | ||
1465 | */ | ||
1466 | if (!asus_hotk_found) { | ||
1467 | acpi_bus_unregister_driver(&asus_hotk_driver); | ||
1468 | return -ENODEV; | 1362 | return -ENODEV; |
1469 | } | 1363 | } |
1470 | 1364 | ||
1471 | result = asus_input_init(); | 1365 | result = asus_hotk_get_info(); |
1472 | if (result) | 1366 | if (result) |
1473 | goto fail_input; | 1367 | return result; |
1474 | 1368 | ||
1475 | /* Register platform stuff */ | 1369 | asus_hotk_add_fs(); |
1476 | result = platform_driver_register(&asuspf_driver); | ||
1477 | if (result) | ||
1478 | goto fail_platform_driver; | ||
1479 | 1370 | ||
1480 | asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1); | 1371 | /* WLED and BLED are on by default */ |
1481 | if (!asuspf_device) { | 1372 | write_status(bt_switch_handle, 1, BT_ON); |
1482 | result = -ENOMEM; | 1373 | write_status(wl_switch_handle, 1, WL_ON); |
1483 | goto fail_platform_device1; | ||
1484 | } | ||
1485 | 1374 | ||
1486 | result = platform_device_add(asuspf_device); | 1375 | /* If the h/w switch is off, we need to check the real status */ |
1487 | if (result) | 1376 | write_status(NULL, read_status(BT_ON), BT_ON); |
1488 | goto fail_platform_device2; | 1377 | write_status(NULL, read_status(WL_ON), WL_ON); |
1378 | |||
1379 | /* LCD Backlight is on by default */ | ||
1380 | write_status(NULL, 1, LCD_ON); | ||
1489 | 1381 | ||
1490 | result = sysfs_create_group(&asuspf_device->dev.kobj, | 1382 | /* Keyboard Backlight is on by default */ |
1491 | &asuspf_attribute_group); | 1383 | if (kled_set_handle) |
1384 | set_kled_lvl(1); | ||
1385 | |||
1386 | /* LED display is off by default */ | ||
1387 | hotk->ledd_status = 0xFFF; | ||
1388 | |||
1389 | /* Set initial values of light sensor and level */ | ||
1390 | hotk->light_switch = 0; /* Default to light sensor disabled */ | ||
1391 | hotk->light_level = 5; /* level 5 for sensor sensitivity */ | ||
1392 | |||
1393 | if (ls_switch_handle) | ||
1394 | set_light_sens_switch(hotk->light_switch); | ||
1395 | |||
1396 | if (ls_level_handle) | ||
1397 | set_light_sens_level(hotk->light_level); | ||
1398 | |||
1399 | /* GPS is on by default */ | ||
1400 | write_status(NULL, 1, GPS_ON); | ||
1401 | return result; | ||
1402 | } | ||
1403 | |||
1404 | static int __devinit asus_acpi_add(struct acpi_device *device) | ||
1405 | { | ||
1406 | int result; | ||
1407 | |||
1408 | pr_notice("Asus Laptop Support version %s\n", | ||
1409 | ASUS_LAPTOP_VERSION); | ||
1410 | hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); | ||
1411 | if (!hotk) | ||
1412 | return -ENOMEM; | ||
1413 | hotk->handle = device->handle; | ||
1414 | strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); | ||
1415 | strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); | ||
1416 | device->driver_data = hotk; | ||
1417 | hotk->device = device; | ||
1418 | |||
1419 | result = asus_acpi_init(device); | ||
1492 | if (result) | 1420 | if (result) |
1493 | goto fail_sysfs; | 1421 | goto fail_platform; |
1494 | 1422 | ||
1495 | result = asus_led_init(&asuspf_device->dev); | 1423 | /* |
1424 | * Register the platform device first. It is used as a parent for the | ||
1425 | * sub-devices below. | ||
1426 | */ | ||
1427 | result = asus_platform_init(); | ||
1496 | if (result) | 1428 | if (result) |
1497 | goto fail_led; | 1429 | goto fail_platform; |
1498 | 1430 | ||
1499 | if (!acpi_video_backlight_support()) { | 1431 | if (!acpi_video_backlight_support()) { |
1500 | result = asus_backlight_init(&asuspf_device->dev); | 1432 | result = asus_backlight_init(&hotk->platform_device->dev); |
1501 | if (result) | 1433 | if (result) |
1502 | goto fail_backlight; | 1434 | goto fail_backlight; |
1503 | } else | 1435 | } else |
1504 | pr_info("Brightness ignored, must be controlled by " | 1436 | pr_info("Backlight controlled by ACPI video driver\n"); |
1505 | "ACPI video driver\n"); | ||
1506 | 1437 | ||
1438 | result = asus_input_init(&hotk->platform_device->dev); | ||
1439 | if (result) | ||
1440 | goto fail_input; | ||
1441 | |||
1442 | result = asus_led_init(&hotk->platform_device->dev); | ||
1443 | if (result) | ||
1444 | goto fail_led; | ||
1445 | |||
1446 | asus_device_present = true; | ||
1507 | return 0; | 1447 | return 0; |
1508 | 1448 | ||
1449 | fail_led: | ||
1450 | asus_input_exit(); | ||
1451 | fail_input: | ||
1452 | asus_backlight_exit(); | ||
1509 | fail_backlight: | 1453 | fail_backlight: |
1510 | asus_led_exit(); | 1454 | asus_platform_exit(); |
1455 | fail_platform: | ||
1456 | kfree(hotk->name); | ||
1457 | kfree(hotk); | ||
1511 | 1458 | ||
1512 | fail_led: | 1459 | return result; |
1513 | sysfs_remove_group(&asuspf_device->dev.kobj, | 1460 | } |
1514 | &asuspf_attribute_group); | ||
1515 | 1461 | ||
1516 | fail_sysfs: | 1462 | static int asus_acpi_remove(struct acpi_device *device, int type) |
1517 | platform_device_del(asuspf_device); | 1463 | { |
1464 | asus_backlight_exit(); | ||
1465 | asus_led_exit(); | ||
1466 | asus_input_exit(); | ||
1467 | asus_platform_exit(); | ||
1468 | |||
1469 | kfree(hotk->name); | ||
1470 | kfree(hotk); | ||
1471 | return 0; | ||
1472 | } | ||
1473 | |||
1474 | static const struct acpi_device_id asus_device_ids[] = { | ||
1475 | {"ATK0100", 0}, | ||
1476 | {"ATK0101", 0}, | ||
1477 | {"", 0}, | ||
1478 | }; | ||
1479 | MODULE_DEVICE_TABLE(acpi, asus_device_ids); | ||
1518 | 1480 | ||
1519 | fail_platform_device2: | 1481 | static struct acpi_driver asus_acpi_driver = { |
1520 | platform_device_put(asuspf_device); | 1482 | .name = ASUS_HOTK_NAME, |
1483 | .class = ASUS_HOTK_CLASS, | ||
1484 | .owner = THIS_MODULE, | ||
1485 | .ids = asus_device_ids, | ||
1486 | .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, | ||
1487 | .ops = { | ||
1488 | .add = asus_acpi_add, | ||
1489 | .remove = asus_acpi_remove, | ||
1490 | .notify = asus_acpi_notify, | ||
1491 | }, | ||
1492 | }; | ||
1521 | 1493 | ||
1522 | fail_platform_device1: | 1494 | static int __init asus_laptop_init(void) |
1523 | platform_driver_unregister(&asuspf_driver); | 1495 | { |
1496 | int result; | ||
1524 | 1497 | ||
1525 | fail_platform_driver: | 1498 | result = platform_driver_register(&platform_driver); |
1526 | asus_input_exit(); | 1499 | if (result < 0) |
1500 | return result; | ||
1527 | 1501 | ||
1528 | fail_input: | 1502 | result = acpi_bus_register_driver(&asus_acpi_driver); |
1503 | if (result < 0) | ||
1504 | goto fail_acpi_driver; | ||
1505 | if (!asus_device_present) { | ||
1506 | result = -ENODEV; | ||
1507 | goto fail_no_device; | ||
1508 | } | ||
1509 | return 0; | ||
1529 | 1510 | ||
1511 | fail_no_device: | ||
1512 | acpi_bus_unregister_driver(&asus_acpi_driver); | ||
1513 | fail_acpi_driver: | ||
1514 | platform_driver_unregister(&platform_driver); | ||
1530 | return result; | 1515 | return result; |
1531 | } | 1516 | } |
1532 | 1517 | ||
1518 | static void __exit asus_laptop_exit(void) | ||
1519 | { | ||
1520 | acpi_bus_unregister_driver(&asus_acpi_driver); | ||
1521 | platform_driver_unregister(&platform_driver); | ||
1522 | } | ||
1523 | |||
1533 | module_init(asus_laptop_init); | 1524 | module_init(asus_laptop_init); |
1534 | module_exit(asus_laptop_exit); | 1525 | module_exit(asus_laptop_exit); |