1fa225cbcSrjs/*
2fa225cbcSrjs * Copyright © 2009 Intel Corporation
3fa225cbcSrjs *
4fa225cbcSrjs * Permission is hereby granted, free of charge, to any person obtaining a
5fa225cbcSrjs * copy of this software and associated documentation files (the "Software"),
6fa225cbcSrjs * to deal in the Software without restriction, including without limitation
7fa225cbcSrjs * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8fa225cbcSrjs * and/or sell copies of the Software, and to permit persons to whom the
9fa225cbcSrjs * Software is furnished to do so, subject to the following conditions:
10fa225cbcSrjs *
11fa225cbcSrjs * The above copyright notice and this permission notice (including the next
12fa225cbcSrjs * paragraph) shall be included in all copies or substantial portions of the
13fa225cbcSrjs * Software.
14fa225cbcSrjs *
15fa225cbcSrjs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16fa225cbcSrjs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17fa225cbcSrjs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18fa225cbcSrjs * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19fa225cbcSrjs * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20fa225cbcSrjs * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21fa225cbcSrjs * DEALINGS IN THE SOFTWARE.
22fa225cbcSrjs *
23fa225cbcSrjs * Authors:
24fa225cbcSrjs *    Zhenyu Wang <zhenyu.z.wang@intel.com>
25fa225cbcSrjs *
26fa225cbcSrjs */
27fa225cbcSrjs
28fa225cbcSrjs#include <stdio.h>
29fa225cbcSrjs#include <stdlib.h>
30fa225cbcSrjs#include <string.h>
31fa225cbcSrjs#include <stdarg.h>
32fa225cbcSrjs#include <pciaccess.h>
33fa225cbcSrjs#include <err.h>
34fa225cbcSrjs#include <fcntl.h>
35fa225cbcSrjs#include <unistd.h>
36fa225cbcSrjs#include <dirent.h>
37fa225cbcSrjs#include <sys/stat.h>
38fa225cbcSrjs#include <sys/types.h>
39fa225cbcSrjs
40fa225cbcSrjs#include "reg_dumper.h"
41fa225cbcSrjs#include "../i810_reg.h"
42fa225cbcSrjs#include "../i830_bios.h"
43fa225cbcSrjs
44fa225cbcSrjsenum lid_status {
45fa225cbcSrjs    LID_UNKNOWN = -1,
46fa225cbcSrjs    LID_OPEN,
47fa225cbcSrjs    LID_CLOSE,
48fa225cbcSrjs};
49fa225cbcSrjs
50fa225cbcSrjs#define ACPI_BUTTON "/proc/acpi/button/"
51fa225cbcSrjs#define ACPI_LID "/proc/acpi/button/lid/"
52fa225cbcSrjs
53fa225cbcSrjsstatic int
54fa225cbcSrjsi830_lvds_acpi_lid_state(void)
55fa225cbcSrjs{
56fa225cbcSrjs    int fd;
57fa225cbcSrjs    DIR *button_dir;
58fa225cbcSrjs    DIR *lid_dir;
59fa225cbcSrjs    struct dirent *lid_dent;
60fa225cbcSrjs    char *state_name;
61fa225cbcSrjs    char state[64];
62fa225cbcSrjs    enum lid_status ret = LID_UNKNOWN;
63fa225cbcSrjs
64fa225cbcSrjs    button_dir = opendir(ACPI_BUTTON);
65fa225cbcSrjs    /* If acpi button driver is not loaded, bypass ACPI check method */
66fa225cbcSrjs    if (button_dir == NULL)
67fa225cbcSrjs	goto out;
68fa225cbcSrjs    closedir(button_dir);
69fa225cbcSrjs
70fa225cbcSrjs    lid_dir = opendir(ACPI_LID);
71fa225cbcSrjs
72fa225cbcSrjs    /* no acpi lid object found */
73fa225cbcSrjs    if (lid_dir == NULL)
74fa225cbcSrjs	goto out;
75fa225cbcSrjs
76fa225cbcSrjs    while (1) {
77fa225cbcSrjs	lid_dent = readdir(lid_dir);
78fa225cbcSrjs	if (lid_dent == NULL) {
79fa225cbcSrjs	    /* no LID object */
80fa225cbcSrjs	    closedir(lid_dir);
81fa225cbcSrjs	    goto out;
82fa225cbcSrjs	}
83fa225cbcSrjs	if (strcmp(lid_dent->d_name, ".") &&
84fa225cbcSrjs		strcmp(lid_dent->d_name, "..")) {
85fa225cbcSrjs	    break;
86fa225cbcSrjs	}
87fa225cbcSrjs    }
88fa225cbcSrjs    state_name = malloc(strlen(ACPI_LID) + strlen(lid_dent->d_name) + 7);
89fa225cbcSrjs    memset(state_name, 0, sizeof(state_name));
90fa225cbcSrjs    strcat(state_name, ACPI_LID);
91fa225cbcSrjs    strcat(state_name, lid_dent->d_name);
92fa225cbcSrjs    strcat(state_name, "/state");
93fa225cbcSrjs
94fa225cbcSrjs    closedir(lid_dir);
95fa225cbcSrjs
96fa225cbcSrjs    if ((fd = open(state_name, O_RDONLY)) == -1) {
97fa225cbcSrjs	free(state_name);
98fa225cbcSrjs	goto out;
99fa225cbcSrjs    }
100fa225cbcSrjs    free(state_name);
101fa225cbcSrjs    if (read(fd, state, 64) == -1) {
102fa225cbcSrjs	close(fd);
103fa225cbcSrjs	goto out;
104fa225cbcSrjs    }
105fa225cbcSrjs    close(fd);
106fa225cbcSrjs    if (strstr(state, "open"))
107fa225cbcSrjs	ret = LID_OPEN;
108fa225cbcSrjs    else if (strstr(state, "closed"))
109fa225cbcSrjs	ret = LID_CLOSE;
110fa225cbcSrjs    else /* "unsupported" */
111fa225cbcSrjs	ret = LID_UNKNOWN;
112fa225cbcSrjs
113fa225cbcSrjsout:
114fa225cbcSrjs    return ret;
115fa225cbcSrjs}
116fa225cbcSrjs
117fa225cbcSrjsint main(int argc, char **argv)
118fa225cbcSrjs{
119fa225cbcSrjs    I830Rec i830;
120fa225cbcSrjs    I830Ptr pI830 = &i830;
121fa225cbcSrjs    int swf14, acpi_lid;
122fa225cbcSrjs
123fa225cbcSrjs    intel_i830rec_init(pI830);
124fa225cbcSrjs
125fa225cbcSrjs    while (1) {
126fa225cbcSrjs	swf14 = INREG(SWF14);
127fa225cbcSrjs
128fa225cbcSrjs	printf("Intel LVDS Lid status:\n");
129fa225cbcSrjs	printf("\tSWF14(0x%x) : %s\n", swf14, swf14 & SWF14_LID_SWITCH_EN ? "close" : "open");
130fa225cbcSrjs
131fa225cbcSrjs	acpi_lid = i830_lvds_acpi_lid_state();
132fa225cbcSrjs	switch (acpi_lid) {
133fa225cbcSrjs	    case LID_UNKNOWN:
134fa225cbcSrjs		printf("\tACPI Lid state : unknown\n");
135fa225cbcSrjs		break;
136fa225cbcSrjs	    case LID_OPEN:
137fa225cbcSrjs		printf("\tACPI Lid state : open\n");
138fa225cbcSrjs		break;
139fa225cbcSrjs	    case LID_CLOSE:
140fa225cbcSrjs		printf("\tACPI Lid state : close\n");
141fa225cbcSrjs		break;
142fa225cbcSrjs	}
143fa225cbcSrjs	sleep(2);
144fa225cbcSrjs    }
145fa225cbcSrjs    return 0;
146fa225cbcSrjs}
147