1 /*
2 * Copyright (c) 2023 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <zephyr/acpi/acpi.h>
9 #include "soc.h"
10 #include "soc_gpio.h"
11
12 #define GET_GPIO_BASE_NUM ("\\_SB.GINF")
13
gpio_info_acpi_get(uint32_t bank_idx,uint32_t field_idx,uint32_t * ret_val)14 static int gpio_info_acpi_get(uint32_t bank_idx, uint32_t field_idx, uint32_t *ret_val)
15 {
16 int status;
17 ACPI_OBJECT args[2];
18 ACPI_OBJECT_LIST arg_list;
19 ACPI_OBJECT gpio_obj;
20
21 arg_list.Count = ARRAY_SIZE(args);
22 arg_list.Pointer = args;
23
24 args[0].Type = ACPI_TYPE_INTEGER;
25 args[0].Integer.Value = bank_idx;
26
27 args[1].Type = ACPI_TYPE_INTEGER;
28 args[1].Integer.Value = field_idx;
29
30 status = acpi_invoke_method(GET_GPIO_BASE_NUM, &arg_list, &gpio_obj);
31 if (status) {
32 return status;
33 }
34
35 if (gpio_obj.Type == ACPI_TYPE_INTEGER) {
36 *ret_val = gpio_obj.Integer.Value;
37 }
38
39 return status;
40 }
41
soc_acpi_gpio_resource_get(int bank_idx,char * hid,char * uid,struct gpio_acpi_res * res)42 int soc_acpi_gpio_resource_get(int bank_idx, char *hid, char *uid, struct gpio_acpi_res *res)
43 {
44 int ret;
45 struct acpi_dev *acpi_child;
46 struct acpi_irq_resource irq_res;
47 struct acpi_mmio_resource mmio_res;
48 uint32_t field_val[7];
49 uint16_t irqs[CONFIG_ACPI_IRQ_VECTOR_MAX];
50 struct acpi_reg_base reg_base[CONFIG_ACPI_MMIO_ENTRIES_MAX];
51
52 acpi_child = acpi_device_get(hid, uid);
53 if (!acpi_child) {
54 printk("acpi_device_get failed\n");
55 return -EIO;
56 }
57
58 mmio_res.mmio_max = ARRAY_SIZE(reg_base);
59 mmio_res.reg_base = reg_base;
60 ret = acpi_device_mmio_get(acpi_child, &mmio_res);
61 if (ret) {
62 printk("acpi_device_mmio_get failed\n");
63 return ret;
64 }
65
66 irq_res.irq_vector_max = ARRAY_SIZE(irqs);
67 irq_res.irqs = irqs;
68 ret = acpi_device_irq_get(acpi_child, &irq_res);
69 if (ret) {
70 printk("acpi_device_irq_get failed\n");
71 return ret;
72 }
73
74 res->irq = irq_res.irqs[0];
75 res->irq_flags = irq_res.flags;
76
77 if (ACPI_RESOURCE_TYPE_GET(&mmio_res) == ACPI_RES_TYPE_MEM) {
78 for (int i = 0; i < ARRAY_SIZE(field_val); i++) {
79 ret = gpio_info_acpi_get(bank_idx, i, &field_val[i]);
80 if (ret) {
81 printk("gpio_info_acpi_get failed\n");
82 return ret;
83 }
84 }
85
86 res->reg_base = ACPI_MMIO_GET(&mmio_res) & (~0x0FFFFFF);
87 res->reg_base += field_val[0];
88 res->len = ACPI_RESOURCE_SIZE_GET(&mmio_res);
89 res->num_pins = field_val[1];
90 res->pad_base = field_val[2];
91 res->host_owner_reg = field_val[3];
92 res->pad_owner_reg = field_val[4];
93 res->intr_stat_reg = field_val[5] - 0x40;
94 res->base_num = field_val[6];
95 } else {
96 printk("ACPI_RES_TYPE_MEM failed\n");
97 return -ENODEV;
98 }
99
100 return 0;
101 }
102