|
2 | 2 | /* Author: Dan Scally <djrscally@gmail.com> */
|
3 | 3 |
|
4 | 4 | #include <linux/acpi.h>
|
| 5 | +#include <linux/array_size.h> |
5 | 6 | #include <linux/bitfield.h>
|
6 | 7 | #include <linux/device.h>
|
7 | 8 | #include <linux/gpio/consumer.h>
|
@@ -122,10 +123,53 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472,
|
122 | 123 | return desc;
|
123 | 124 | }
|
124 | 125 |
|
125 |
| -static void int3472_get_func_and_polarity(u8 type, const char **func, |
126 |
| - unsigned long *gpio_flags) |
| 126 | +/** |
| 127 | + * struct int3472_gpio_map - Map GPIOs to whatever is expected by the |
| 128 | + * sensor driver (as in DT bindings) |
| 129 | + * @hid: The ACPI HID of the device without the instance number e.g. INT347E |
| 130 | + * @type_from: The GPIO type from ACPI ?SDT |
| 131 | + * @type_to: The assigned GPIO type, typically same as @type_from |
| 132 | + * @func: The function, e.g. "enable" |
| 133 | + * @polarity_low: GPIO_ACTIVE_LOW true if the @polarity_low is true, |
| 134 | + * GPIO_ACTIVE_HIGH otherwise |
| 135 | + */ |
| 136 | +struct int3472_gpio_map { |
| 137 | + const char *hid; |
| 138 | + u8 type_from; |
| 139 | + u8 type_to; |
| 140 | + bool polarity_low; |
| 141 | + const char *func; |
| 142 | +}; |
| 143 | + |
| 144 | +static const struct int3472_gpio_map int3472_gpio_map[] = { |
| 145 | + { "INT347E", INT3472_GPIO_TYPE_RESET, INT3472_GPIO_TYPE_RESET, false, "enable" }, |
| 146 | +}; |
| 147 | + |
| 148 | +static void int3472_get_func_and_polarity(struct acpi_device *adev, u8 *type, |
| 149 | + const char **func, unsigned long *gpio_flags) |
127 | 150 | {
|
128 |
| - switch (type) { |
| 151 | + unsigned int i; |
| 152 | + |
| 153 | + for (i = 0; i < ARRAY_SIZE(int3472_gpio_map); i++) { |
| 154 | + /* |
| 155 | + * Map the firmware-provided GPIO to whatever a driver expects |
| 156 | + * (as in DT bindings). First check if the type matches with the |
| 157 | + * GPIO map, then further check that the device _HID matches. |
| 158 | + */ |
| 159 | + if (*type != int3472_gpio_map[i].type_from) |
| 160 | + continue; |
| 161 | + |
| 162 | + if (!acpi_dev_hid_uid_match(adev, int3472_gpio_map[i].hid, NULL)) |
| 163 | + continue; |
| 164 | + |
| 165 | + *type = int3472_gpio_map[i].type_to; |
| 166 | + *gpio_flags = int3472_gpio_map[i].polarity_low ? |
| 167 | + GPIO_ACTIVE_LOW : GPIO_ACTIVE_HIGH; |
| 168 | + *func = int3472_gpio_map[i].func; |
| 169 | + return; |
| 170 | + } |
| 171 | + |
| 172 | + switch (*type) { |
129 | 173 | case INT3472_GPIO_TYPE_RESET:
|
130 | 174 | *func = "reset";
|
131 | 175 | *gpio_flags = GPIO_ACTIVE_LOW;
|
@@ -218,7 +262,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
|
218 | 262 |
|
219 | 263 | type = FIELD_GET(INT3472_GPIO_DSM_TYPE, obj->integer.value);
|
220 | 264 |
|
221 |
| - int3472_get_func_and_polarity(type, &func, &gpio_flags); |
| 265 | + int3472_get_func_and_polarity(int3472->sensor, &type, &func, &gpio_flags); |
222 | 266 |
|
223 | 267 | pin = FIELD_GET(INT3472_GPIO_DSM_PIN, obj->integer.value);
|
224 | 268 | /* Pin field is not really used under Windows and wraps around at 8 bits */
|
|
0 commit comments