in asus_atk0110.c [820:936]
static int atk_add_sensor(struct atk_data *data, union acpi_object *obj)
{
struct device *dev = &data->acpi_dev->dev;
union acpi_object *flags;
union acpi_object *name;
union acpi_object *limit1;
union acpi_object *limit2;
union acpi_object *enable;
struct atk_sensor_data *sensor;
char const *base_name;
char const *limit1_name;
char const *limit2_name;
u64 type;
int err;
int *num;
int start;
if (obj->type != ACPI_TYPE_PACKAGE) {
/* wft is this? */
dev_warn(dev, "Unknown type for ACPI object: (%d)\n",
obj->type);
return -EINVAL;
}
err = validate_hwmon_pack(data, obj);
if (err)
return err;
/* Ok, we have a valid hwmon package */
type = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS)->integer.value
& ATK_TYPE_MASK;
switch (type) {
case HWMON_TYPE_VOLT:
base_name = "in";
limit1_name = "min";
limit2_name = "max";
num = &data->voltage_count;
start = 0;
break;
case HWMON_TYPE_TEMP:
base_name = "temp";
limit1_name = "max";
limit2_name = "crit";
num = &data->temperature_count;
start = 1;
break;
case HWMON_TYPE_FAN:
base_name = "fan";
limit1_name = "min";
limit2_name = "max";
num = &data->fan_count;
start = 1;
break;
default:
dev_warn(dev, "Unknown sensor type: %#llx\n", type);
return -EINVAL;
}
enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
if (!enable->integer.value)
/* sensor is disabled */
return 0;
flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
if (!sensor)
return -ENOMEM;
sensor->acpi_name = devm_kstrdup(dev, name->string.pointer, GFP_KERNEL);
if (!sensor->acpi_name)
return -ENOMEM;
INIT_LIST_HEAD(&sensor->list);
sensor->type = type;
sensor->data = data;
sensor->id = flags->integer.value;
sensor->limit1 = limit1->integer.value;
if (data->old_interface)
sensor->limit2 = limit2->integer.value;
else
/* The upper limit is expressed as delta from lower limit */
sensor->limit2 = sensor->limit1 + limit2->integer.value;
snprintf(sensor->input_attr_name, ATTR_NAME_SIZE,
"%s%d_input", base_name, start + *num);
atk_init_attribute(&sensor->input_attr,
sensor->input_attr_name,
atk_input_show);
snprintf(sensor->label_attr_name, ATTR_NAME_SIZE,
"%s%d_label", base_name, start + *num);
atk_init_attribute(&sensor->label_attr,
sensor->label_attr_name,
atk_label_show);
snprintf(sensor->limit1_attr_name, ATTR_NAME_SIZE,
"%s%d_%s", base_name, start + *num, limit1_name);
atk_init_attribute(&sensor->limit1_attr,
sensor->limit1_attr_name,
atk_limit1_show);
snprintf(sensor->limit2_attr_name, ATTR_NAME_SIZE,
"%s%d_%s", base_name, start + *num, limit2_name);
atk_init_attribute(&sensor->limit2_attr,
sensor->limit2_attr_name,
atk_limit2_show);
list_add(&sensor->list, &data->sensor_list);
(*num)++;
return 1;
}