Lines Matching +full:ecx +full:- +full:1000
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * dell-smm-hwmon.c -- Linux driver for accessing the SMM BIOS on Dell laptops.
9 * Copyright (C) 2013, 2014 Guenter Roeck <linux@roeck-us.net>
59 #define I8K_FAN_RPM_THRESHOLD 1000
72 #define DELL_SMM_WMI_GUID "F1DDEE52-063C-4784-A11E-8A06684B9B01"
81 unsigned int ecx; member
191 return -EBUSY; in i8k_smm_func()
197 "+a" (regs->eax), in i8k_smm_func()
198 "+b" (regs->ebx), in i8k_smm_func()
199 "+c" (regs->ecx), in i8k_smm_func()
200 "+d" (regs->edx), in i8k_smm_func()
201 "+S" (regs->esi), in i8k_smm_func()
202 "+D" (regs->edi)); in i8k_smm_func()
205 return -EINVAL; in i8k_smm_func()
237 return -ENODATA; in wmi_parse_register()
241 return -ENOMSG; in wmi_parse_register()
244 return -ENODATA; in wmi_parse_register()
255 ®s->eax, in wmi_parse_response()
256 ®s->ebx, in wmi_parse_response()
257 ®s->ecx, in wmi_parse_response()
258 ®s->edx in wmi_parse_response()
266 return -ENODATA; in wmi_parse_response()
268 ret = wmi_parse_register(buffer + offset, length - offset, registers[i]); in wmi_parse_response()
276 return -ENOMSG; in wmi_parse_response()
286 sizeof(regs->eax), in wmi_smm_call()
287 regs->eax, in wmi_smm_call()
288 sizeof(regs->ebx), in wmi_smm_call()
289 regs->ebx, in wmi_smm_call()
290 sizeof(regs->ecx), in wmi_smm_call()
291 regs->ecx, in wmi_smm_call()
292 sizeof(regs->edx), in wmi_smm_call()
293 regs->edx in wmi_smm_call()
305 return -EIO; in wmi_smm_call()
309 return -ENODATA; in wmi_smm_call()
311 if (obj->type != ACPI_TYPE_BUFFER) { in wmi_smm_call()
312 ret = -ENOMSG; in wmi_smm_call()
317 ret = wmi_parse_response(obj->buffer.pointer, obj->buffer.length, regs); in wmi_smm_call()
327 unsigned int eax = regs->eax; in dell_smm_call()
328 unsigned int ebx = regs->ebx; in dell_smm_call()
334 ret = ops->smm_call(ops->smm_dev, regs); in dell_smm_call()
338 eax, ebx, regs->eax & 0xffff, ret, duration); in dell_smm_call()
346 if ((regs->eax & 0xffff) == 0xffff || regs->eax == eax) in dell_smm_call()
347 return -EINVAL; in dell_smm_call()
363 return -EINVAL; in i8k_get_fan_status()
365 return dell_smm_call(data->ops, ®s) ? : regs.eax & 0xff; in i8k_get_fan_status()
379 return -EINVAL; in i8k_get_fan_speed()
381 return dell_smm_call(data->ops, ®s) ? : (regs.eax & 0xffff) * data->i8k_fan_mult; in i8k_get_fan_speed()
395 return -EINVAL; in _i8k_get_fan_type()
397 return dell_smm_call(data->ops, ®s) ? : regs.eax & 0xff; in _i8k_get_fan_type()
403 if (data->fan_type[fan] == INT_MIN) in i8k_get_fan_type()
404 data->fan_type[fan] = _i8k_get_fan_type(data, fan); in i8k_get_fan_type()
406 return data->fan_type[fan]; in i8k_get_fan_type()
420 return -EINVAL; in i8k_get_fan_nominal_speed()
422 return dell_smm_call(data->ops, ®s) ? : (regs.eax & 0xffff); in i8k_get_fan_nominal_speed()
433 return -EINVAL; in i8k_enable_fan_auto_mode()
436 return dell_smm_call(data->ops, ®s); in i8k_enable_fan_auto_mode()
447 return -EINVAL; in i8k_set_fan()
449 speed = (speed < 0) ? 0 : ((speed > data->i8k_fan_max) ? data->i8k_fan_max : speed); in i8k_set_fan()
452 return dell_smm_call(data->ops, ®s); in i8k_set_fan()
462 return dell_smm_call(data->ops, ®s) ? : regs.eax & 0xff; in i8k_get_temp_type()
475 return dell_smm_call(data->ops, ®s) ? : regs.eax & 0xff; in _i8k_get_temp()
486 # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees in i8k_get_temp()
494 * Return -ENODATA for all invalid temperatures. in i8k_get_temp()
502 return -ENODATA; in i8k_get_temp()
516 return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1; in dell_smm_get_signature()
529 rc = dell_smm_call(data->ops, ®s); in i8k_get_fn_status()
553 rc = dell_smm_call(data->ops, ®s); in i8k_get_power_status()
572 return -EINVAL; in i8k_ioctl()
576 if (!isdigit(data->bios_version[0]) || !isdigit(data->bios_version[1]) || in i8k_ioctl()
577 !isdigit(data->bios_version[2])) in i8k_ioctl()
578 return -EINVAL; in i8k_ioctl()
580 val = (data->bios_version[0] << 16) | in i8k_ioctl()
581 (data->bios_version[1] << 8) | data->bios_version[2]; in i8k_ioctl()
584 return -EFAULT; in i8k_ioctl()
589 return -EPERM; in i8k_ioctl()
591 if (copy_to_user(argp, data->bios_machineid, sizeof(data->bios_machineid))) in i8k_ioctl()
592 return -EFAULT; in i8k_ioctl()
609 return -EFAULT; in i8k_ioctl()
612 return -EINVAL; in i8k_ioctl()
619 return -EFAULT; in i8k_ioctl()
622 return -EINVAL; in i8k_ioctl()
629 return -EPERM; in i8k_ioctl()
632 return -EFAULT; in i8k_ioctl()
635 return -EINVAL; in i8k_ioctl()
638 return -EFAULT; in i8k_ioctl()
640 mutex_lock(&data->i8k_mutex); in i8k_ioctl()
646 mutex_unlock(&data->i8k_mutex); in i8k_ioctl()
650 return -ENOIOCTLCMD; in i8k_ioctl()
657 return -EFAULT; in i8k_ioctl()
667 struct dell_smm_data *data = seq->private; in i8k_proc_show()
680 ac_power = -1; in i8k_proc_show()
698 data->bios_version, in i8k_proc_show()
699 (restricted && !capable(CAP_SYS_ADMIN)) ? "-1" : data->bios_machineid, in i8k_proc_show()
729 strscpy(data->bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), in i8k_init_procfs()
730 sizeof(data->bios_version)); in i8k_init_procfs()
731 strscpy(data->bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), in i8k_init_procfs()
732 sizeof(data->bios_machineid)); in i8k_init_procfs()
749 struct dell_smm_cooling_data *cdata = dev->devdata; in dell_smm_get_max_state()
751 *state = cdata->data->i8k_fan_max; in dell_smm_get_max_state()
758 struct dell_smm_cooling_data *cdata = dev->devdata; in dell_smm_get_cur_state()
761 ret = i8k_get_fan_status(cdata->data, cdata->fan_num); in dell_smm_get_cur_state()
772 struct dell_smm_cooling_data *cdata = dev->devdata; in dell_smm_set_cur_state()
773 struct dell_smm_data *data = cdata->data; in dell_smm_set_cur_state()
776 if (state > data->i8k_fan_max) in dell_smm_set_cur_state()
777 return -EINVAL; in dell_smm_set_cur_state()
779 mutex_lock(&data->i8k_mutex); in dell_smm_set_cur_state()
780 ret = i8k_set_fan(data, cdata->fan_num, (int)state); in dell_smm_set_cur_state()
781 mutex_unlock(&data->i8k_mutex); in dell_smm_set_cur_state()
802 if (data->temp_type[channel] >= 0 || _i8k_get_temp(data, channel) >= 0) in dell_smm_is_visible()
807 if (data->temp_type[channel] >= 0) in dell_smm_is_visible()
821 if (data->fan[channel]) in dell_smm_is_visible()
826 if (data->fan[channel] && !disallow_fan_type_call) in dell_smm_is_visible()
833 if (data->fan_nominal_speed[channel]) in dell_smm_is_visible()
847 if (data->fan[channel]) in dell_smm_is_visible()
857 * Thus we can only provide write-only access for now. in dell_smm_is_visible()
877 int mult = data->i8k_fan_mult; in dell_smm_read()
888 *val = ret * 1000; in dell_smm_read()
906 *val = data->fan_nominal_speed[channel][0] * mult; in dell_smm_read()
910 *val = data->fan_nominal_speed[channel][data->i8k_fan_max] * mult; in dell_smm_read()
918 if (ret > data->i8k_fan_max) in dell_smm_read()
919 ret = data->i8k_fan_max; in dell_smm_read()
921 *val = data->fan_nominal_speed[channel][ret] * mult; in dell_smm_read()
935 *val = clamp_val(ret * data->i8k_pwm_mult, 0, 255); in dell_smm_read()
946 return -EOPNOTSUPP; in dell_smm_read()
963 type = ARRAY_SIZE(fan_labels) - 1; in dell_smm_fan_label()
977 *str = temp_labels[data->temp_type[channel]]; in dell_smm_read_string()
996 return -EOPNOTSUPP; in dell_smm_read_string()
1011 pwm = clamp_val(DIV_ROUND_CLOSEST(val, data->i8k_pwm_mult), 0, in dell_smm_write()
1012 data->i8k_fan_max); in dell_smm_write()
1014 mutex_lock(&data->i8k_mutex); in dell_smm_write()
1016 mutex_unlock(&data->i8k_mutex); in dell_smm_write()
1024 return -EINVAL; in dell_smm_write()
1031 mutex_lock(&data->i8k_mutex); in dell_smm_write()
1033 mutex_unlock(&data->i8k_mutex); in dell_smm_write()
1047 return -EOPNOTSUPP; in dell_smm_write()
1100 name = kasprintf(GFP_KERNEL, "dell-smm-fan%u", fan_num + 1); in dell_smm_init_cdev()
1102 return -ENOMEM; in dell_smm_init_cdev()
1106 cdata->fan_num = fan_num; in dell_smm_init_cdev()
1107 cdata->data = data; in dell_smm_init_cdev()
1115 ret = -ENOMEM; in dell_smm_init_cdev()
1131 data->temp_type[i] = i8k_get_temp_type(data, i); in dell_smm_init_hwmon()
1132 if (data->temp_type[i] < 0) in dell_smm_init_hwmon()
1135 if (data->temp_type[i] >= ARRAY_SIZE(temp_labels)) in dell_smm_init_hwmon()
1136 data->temp_type[i] = ARRAY_SIZE(temp_labels) - 1; in dell_smm_init_hwmon()
1140 data->fan_type[i] = INT_MIN; in dell_smm_init_hwmon()
1148 data->fan[i] = true; in dell_smm_init_hwmon()
1158 data->fan_nominal_speed[i] = devm_kmalloc_array(dev, data->i8k_fan_max + 1, in dell_smm_init_hwmon()
1159 sizeof(*data->fan_nominal_speed[i]), in dell_smm_init_hwmon()
1161 if (!data->fan_nominal_speed[i]) in dell_smm_init_hwmon()
1164 for (state = 0; state <= data->i8k_fan_max; state++) { in dell_smm_init_hwmon()
1168 devm_kfree(dev, data->fan_nominal_speed[i]); in dell_smm_init_hwmon()
1169 data->fan_nominal_speed[i] = NULL; in dell_smm_init_hwmon()
1172 data->fan_nominal_speed[i][state] = err; in dell_smm_init_hwmon()
1179 data->i8k_fan_mult = 1; in dell_smm_init_hwmon()
1195 return -ENOMEM; in dell_smm_init_data()
1197 mutex_init(&data->i8k_mutex); in dell_smm_init_data()
1200 data->ops = ops; in dell_smm_init_data()
1202 data->i8k_fan_mult = fan_mult ? : I8K_FAN_MULT; in dell_smm_init_data()
1203 data->i8k_fan_max = fan_max ? : I8K_FAN_HIGH; in dell_smm_init_data()
1204 data->i8k_pwm_mult = DIV_ROUND_UP(255, data->i8k_fan_max); in dell_smm_init_data()
1530 ret = dell_smm_init_data(&pdev->dev, &i8k_smm_ops); in dell_smm_probe()
1534 ret = dell_smm_init_hwmon(&pdev->dev); in dell_smm_probe()
1538 i8k_init_procfs(&pdev->dev); in dell_smm_probe()
1559 ops = devm_kzalloc(&wdev->dev, sizeof(*ops), GFP_KERNEL); in dell_smm_wmi_probe()
1561 return -ENOMEM; in dell_smm_wmi_probe()
1563 ops->smm_call = wmi_smm_call; in dell_smm_wmi_probe()
1564 ops->smm_dev = &wdev->dev; in dell_smm_wmi_probe()
1568 return -ENODEV; in dell_smm_wmi_probe()
1570 ret = dell_smm_init_data(&wdev->dev, ops); in dell_smm_wmi_probe()
1574 return dell_smm_init_hwmon(&wdev->dev); in dell_smm_wmi_probe()
1624 if (id && id->driver_data) { in dell_smm_init_dmi()
1625 config = id->driver_data; in dell_smm_init_dmi()
1626 if (!fan_mult && config->fan_mult) in dell_smm_init_dmi()
1627 fan_mult = config->fan_mult; in dell_smm_init_dmi()
1629 if (!fan_max && config->fan_max) in dell_smm_init_dmi()
1630 fan_max = config->fan_max; in dell_smm_init_dmi()
1634 if (id && id->driver_data) { in dell_smm_init_dmi()
1635 control = id->driver_data; in dell_smm_init_dmi()
1636 manual_fan = control->manual_fan; in dell_smm_init_dmi()
1637 auto_fan = control->auto_fan; in dell_smm_init_dmi()
1647 return -ENODEV; in dell_smm_legacy_check()
1659 return -ENODEV; in dell_smm_legacy_check()