xref: /aosp_15_r20/external/coreboot/src/drivers/nxp/uwb/uwb.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi_device.h>
4 #include <acpi/acpigen.h>
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/spi.h>
8 #include <spi-generic.h>
9 #include <stdio.h>
10 
11 #include "chip.h"
12 
spi_acpi_get_bus(const struct device * dev)13 static int spi_acpi_get_bus(const struct device *dev)
14 {
15 	struct device *spi_dev;
16 	struct device_operations *ops;
17 
18 	if (!dev->upstream || !dev->upstream->dev)
19 		return -1;
20 
21 	spi_dev = dev->upstream->dev;
22 	ops = spi_dev->ops;
23 
24 	if (ops && ops->ops_spi_bus && ops->ops_spi_bus->dev_to_bus)
25 		return ops->ops_spi_bus->dev_to_bus(spi_dev);
26 
27 	return -1;
28 }
29 
write_gpio(struct acpi_gpio * gpio,int * curr_index)30 static int write_gpio(struct acpi_gpio *gpio, int *curr_index)
31 {
32 	int ret = -1;
33 
34 	if (gpio->pin_count == 0)
35 		return ret;
36 
37 	acpi_device_write_gpio(gpio);
38 	ret = *curr_index;
39 	(*curr_index)++;
40 
41 	return ret;
42 }
43 
nxp_uwb_fill_ssdt(const struct device * dev)44 static void nxp_uwb_fill_ssdt(const struct device *dev)
45 {
46 	struct drivers_nxp_uwb_config *config = dev->chip_info;
47 	const char *scope = acpi_device_scope(dev);
48 	const char *path = acpi_device_path(dev);
49 	struct acpi_spi spi = {
50 		.device_select = dev->path.spi.cs,
51 		.speed = config->speed ? : 1 * MHz,
52 		.resource = scope,
53 		.device_select_polarity = SPI_POLARITY_LOW,
54 		.wire_mode = SPI_4_WIRE_MODE,
55 		.data_bit_length = 8,
56 		.clock_phase = SPI_CLOCK_PHASE_FIRST,
57 		.clock_polarity = SPI_POLARITY_LOW,
58 	};
59 	int curr_index = 0;
60 	int irq_gpio_index = -1;
61 	int ce_gpio_index = -1;
62 	int ri_gpio_index = -1;
63 
64 	if (!scope)
65 		return;
66 
67 	if (spi_acpi_get_bus(dev) == -1) {
68 		printk(BIOS_ERR, "%s: Cannot get bus for device.\n",
69 		       dev_path(dev));
70 		return;
71 	}
72 
73 	/* Device */
74 	acpigen_write_scope(scope);
75 	acpigen_write_device(acpi_device_name(dev));
76 	acpigen_write_name_string("_HID", ACPI_DT_NAMESPACE_HID);
77 	acpigen_write_name_integer("_UID", config->uid);
78 	if (config->desc)
79 		acpigen_write_name_string("_DDN", config->desc);
80 	acpigen_write_STA(acpi_device_status(dev));
81 
82 	/* Resources */
83 	acpigen_write_name("_CRS");
84 	acpigen_write_resourcetemplate_header();
85 	acpi_device_write_spi(&spi);
86 	irq_gpio_index = write_gpio(&config->irq_gpio, &curr_index);
87 	ce_gpio_index = write_gpio(&config->ce_gpio, &curr_index);
88 	ri_gpio_index = write_gpio(&config->ri_gpio, &curr_index);
89 	acpigen_write_resourcetemplate_footer();
90 
91 	struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
92 	acpi_dp_add_string(dsd, "compatible", "nxp,sr1xx");
93 	acpi_dp_add_gpio(dsd, "nxp,sr1xx-irq-gpios", path, irq_gpio_index, 0,
94 			 config->irq_gpio.active_low);
95 
96 	acpi_dp_add_gpio(dsd, "nxp,sr1xx-ce-gpios", path, ce_gpio_index, 0,
97 			 config->ce_gpio.active_low);
98 
99 	acpi_dp_add_gpio(dsd, "nxp,sr1xx-ri-gpios", path, ri_gpio_index, 0,
100 			 config->ri_gpio.active_low);
101 	acpi_dp_write(dsd);
102 
103 	acpigen_write_device_end();
104 	acpigen_write_scope_end();
105 
106 	printk(BIOS_INFO, "%s: %s at %s\n", path,
107 	       config->desc ? : dev->chip_ops->name, dev_path(dev));
108 }
109 
nxp_uwb_name(const struct device * dev)110 static const char *nxp_uwb_name(const struct device *dev)
111 {
112 	struct drivers_nxp_uwb_config *config = dev->chip_info;
113 	static char name[ACPI_NAME_BUFFER_SIZE];
114 
115 	if (config->name)
116 		snprintf(name, sizeof(name), "%s", config->name);
117 	else
118 		snprintf(name, sizeof(name), "UWB%1X", spi_acpi_get_bus(dev));
119 	name[4] = '\0';
120 	return name;
121 }
122 
123 static struct device_operations nxp_uwb_ops = {
124 	.read_resources		= noop_read_resources,
125 	.set_resources		= noop_set_resources,
126 	.acpi_name		= nxp_uwb_name,
127 	.acpi_fill_ssdt		= nxp_uwb_fill_ssdt,
128 };
129 
nxb_uwb_enable(struct device * dev)130 static void nxb_uwb_enable(struct device *dev)
131 {
132 	dev->ops = &nxp_uwb_ops;
133 }
134 
135 struct chip_operations drivers_nxp_uwb_ops = {
136 	.name = "NXP UWB Device",
137 	.enable_dev = nxb_uwb_enable
138 };
139