if (int3472->n_sensor_gpios >= INT3472_MAX_SENSOR_GPIOS) {
dev_warn(int3472->dev, "Too many GPIOs mapped\n"); return -EINVAL;
}
ret = skl_int3472_fill_gpiod_lookup(&int3472->gpios.table[int3472->n_sensor_gpios],
agpio, con_id, gpio_flags); if (ret) return ret;
int3472->n_sensor_gpios++;
return0;
}
/* This should *really* only be used when there's no other way... */ staticstruct gpio_desc *
skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, struct acpi_resource_gpio *agpio, constchar *con_id, unsignedlong gpio_flags)
{ struct gpio_desc *desc; int ret;
for (i = 0; i < ARRAY_SIZE(int3472_gpio_map); i++) { /* *Mapthefirmware-providedGPIOtowhateveradriverexpects *(asinDTbindings).Firstcheckifthetypematcheswiththe *GPIOmap,thenfurthercheckthatthedevice_HIDmatches.
*/ if (*type != int3472_gpio_map[i].type_from) continue;
if (!acpi_dev_hid_uid_match(adev, int3472_gpio_map[i].hid, NULL)) continue;
dev_dbg(int3472->dev, "mapping type 0x%02x pin to 0x%02x %s\n",
*type, int3472_gpio_map[i].type_to, int3472_gpio_map[i].con_id);
pin = FIELD_GET(INT3472_GPIO_DSM_PIN, obj->integer.value); /* Pin field is not really used under Windows and wraps around at 8 bits */ if (pin != (agpio->pin_table[0] & 0xff))
dev_dbg(int3472->dev, FW_BUG "%s %s pin number mismatch _DSM %d resource %d\n",
con_id, agpio->resource_source.string_ptr, pin, agpio->pin_table[0]);
active_value = FIELD_GET(INT3472_GPIO_DSM_SENSOR_ON_VAL, obj->integer.value); if (!active_value)
gpio_flags ^= GPIO_ACTIVE_LOW;
switch (type) { case INT3472_GPIO_TYPE_RESET: case INT3472_GPIO_TYPE_POWERDOWN: case INT3472_GPIO_TYPE_HOTPLUG_DETECT:
ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, con_id, gpio_flags); if (ret)
err_msg = "Failed to map GPIO pin to sensor\n";
break; case INT3472_GPIO_TYPE_CLK_ENABLE: case INT3472_GPIO_TYPE_PRIVACY_LED: case INT3472_GPIO_TYPE_POWER_ENABLE: case INT3472_GPIO_TYPE_HANDSHAKE:
gpio = skl_int3472_gpiod_get_from_temp_lookup(int3472, agpio, con_id, gpio_flags); if (IS_ERR(gpio)) {
ret = PTR_ERR(gpio);
err_msg = "Failed to get GPIO\n"; break;
}
switch (type) { case INT3472_GPIO_TYPE_CLK_ENABLE:
ret = skl_int3472_register_gpio_clock(int3472, gpio); if (ret)
err_msg = "Failed to register clock\n";
break; case INT3472_GPIO_TYPE_PRIVACY_LED:
ret = skl_int3472_register_pled(int3472, gpio); if (ret)
err_msg = "Failed to register LED\n";
break; case INT3472_GPIO_TYPE_POWER_ENABLE:
ret = skl_int3472_register_regulator(int3472, gpio,
GPIO_REGULATOR_ENABLE_TIME,
con_id,
int3472->quirks.avdd_second_sensor); if (ret)
err_msg = "Failed to map power-enable to sensor\n";
break; case INT3472_GPIO_TYPE_HANDSHAKE: /* Setups using a handshake pin need 25 ms enable delay */
ret = skl_int3472_register_regulator(int3472, gpio, 25 * USEC_PER_MSEC,
con_id, NULL); if (ret)
err_msg = "Failed to map handshake to sensor\n";
break; default: /* Never reached */
ret = -EINVAL; break;
}
if (ret)
gpiod_put(gpio);
break; default:
dev_warn(int3472->dev, "GPIO type 0x%02x unknown; the sensor may not work\n",
type);
ret = 1; break;
}
int3472->ngpios++;
ACPI_FREE(obj);
if (ret < 0) return dev_err_probe(int3472->dev, ret, err_msg);
/* Tell acpi_dev_get_resources() to not make a copy of the resource */ return1;
}
int int3472_discrete_parse_crs(struct int3472_discrete_device *int3472)
{
LIST_HEAD(resource_list); int ret;
skl_int3472_log_sensor_module_name(int3472);
ret = acpi_dev_get_resources(int3472->adev, &resource_list,
skl_int3472_handle_gpio_resources,
int3472); if (ret < 0) return ret;
acpi_dev_free_resource_list(&resource_list);
/* Register _DSM based clock (no-op if a GPIO clock was already registered) */
ret = skl_int3472_register_dsm_clock(int3472); if (ret < 0) return ret;
id = dmi_first_match(skl_int3472_discrete_quirks); if (id)
quirks = id->driver_data;
ret = skl_int3472_fill_cldb(adev, &cldb); if (ret) {
dev_err(&pdev->dev, "Couldn't fill CLDB structure\n"); return ret;
}
if (cldb.control_logic_type != 1) {
dev_err(&pdev->dev, "Unsupported control logic type %u\n",
cldb.control_logic_type); return -EINVAL;
}
/* Max num GPIOs we've seen plus a terminator */
int3472 = devm_kzalloc(&pdev->dev, struct_size(int3472, gpios.table,
INT3472_MAX_SENSOR_GPIOS + 1), GFP_KERNEL); if (!int3472) return -ENOMEM;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.