1 /* SPDX-License-Identifier: GPL-2.0-only */
13 uint8_t pmh7_register_read(uint16_t reg
)
15 outb(reg
& 0xff, EC_LENOVO_PMH7_ADDR_L
);
16 outb((reg
& 0xff00) >> 8, EC_LENOVO_PMH7_ADDR_H
);
17 return inb(EC_LENOVO_PMH7_DATA
);
20 void pmh7_register_write(uint16_t reg
, uint8_t val
)
22 outb(reg
& 0xff, EC_LENOVO_PMH7_ADDR_L
);
23 outb((reg
& 0xff00) >> 8, EC_LENOVO_PMH7_ADDR_H
);
24 outb(val
, EC_LENOVO_PMH7_DATA
);
27 void pmh7_register_set_bit(uint16_t reg
, uint8_t bit
)
31 val
= pmh7_register_read(reg
);
32 pmh7_register_write(reg
, val
| (1 << bit
));
35 void pmh7_register_clear_bit(uint16_t reg
, uint8_t bit
)
39 val
= pmh7_register_read(reg
);
40 pmh7_register_write(reg
, val
& ~(1 << bit
));
43 uint8_t pmh7_register_read_bit(int16_t reg
, uint8_t bit
)
47 val
= pmh7_register_read(reg
);
48 return (val
>> bit
) & 1;
51 void print_usage(const char *name
)
53 printf("usage: %s\n", name
);
55 " -h, --help: print this help\n"
56 " -d, --dump: print registers\n"
57 " -w, --write <addr> <data>: write to register\n"
58 " -r, --read <addr>: read from register\n"
59 " -b, --read-bit <addr> <bit> read bit\n"
60 " -c, --clear-bit <addr> <bit> clear bit\n"
61 " -s, --set-bit <addr> <bit> set bit\n"
63 "Attention! Writing to PMH7 registers is very dangerous, as you\n"
64 " directly manipulate the power rails, enable lines,\n"
65 " interrupt lines or something else of the device.\n"
66 " Proceed with caution."
70 enum action
{HELP
, DUMP
, WRITE
, READ
, READBIT
, CLEAR
, SET
};
72 int main(int argc
, char *argv
[])
74 enum action act
= HELP
;
75 int opt
, option_index
= 0;
76 long input_addr
= 0, input_data
= 0;
78 static struct option long_options
[] = {
83 {"read-bit", 1, 0, 'b'},
84 {"clear-bit", 1, 0, 'c'},
85 {"set-bit", 1, 0, 's'},
89 if (argv
[1] == NULL
) {
94 while ((opt
= getopt_long(argc
, argv
, "hdw:r:c:s:b:",
95 long_options
, &option_index
)) != EOF
) {
102 input_addr
= strtoul(optarg
, NULL
, 16);
110 input_addr
= strtoul(optarg
, NULL
, 16);
112 if (optind
< argc
&& *argv
[optind
] != '-') {
113 input_data
= strtoul(argv
[optind
], NULL
, 16);
117 "Error: -%c option requires two arguments\n",
141 fprintf(stderr
, "Error: Extra parameter found.\n");
142 print_usage(argv
[0]);
147 print_usage(argv
[0]);
151 if (input_addr
> 0x1ff) {
153 "Error: <addr> cannot be greater than 9 bits long.\n");
157 if (act
== SET
|| act
== CLEAR
|| act
== READBIT
) {
158 if (input_data
> 7) {
160 "Error: <bit> cannot be greater than 7.\n");
164 if (input_data
> 0xff) {
166 "Error: <data> cannot be greater than 8 bits long.\n");
171 if (geteuid() != 0) {
172 fprintf(stderr
, "You must be root.\n");
176 if (ioperm(EC_LENOVO_PMH7_BASE
, 0x10, 1)) {
177 fprintf(stderr
, "ioperm: %s\n", strerror(errno
));
183 for (int i
= 0; i
< 0x200; i
++) {
184 if ((i
% 0x10) == 0) {
189 printf("%02x ", pmh7_register_read(i
));
195 printf("%02x\n", pmh7_register_read(input_addr
));
199 pmh7_register_write(input_addr
, input_data
);
203 printf("%d\n", pmh7_register_read_bit(input_addr
, input_data
));
207 pmh7_register_clear_bit(input_addr
, input_data
);
211 pmh7_register_set_bit(input_addr
, input_data
);