Lines Matching +full:fan +full:- +full:0
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * fan_core.c - ACPI Fan core Driver
20 #include "fan.h"
24 {"", 0},
32 struct acpi_device *device = cdev->devdata; in fan_get_max_state()
33 struct acpi_fan *fan = acpi_driver_data(device); in fan_get_max_state() local
35 if (fan->acpi4) { in fan_get_max_state()
36 if (fan->fif.fine_grain_ctrl) in fan_get_max_state()
37 *state = 100 / fan->fif.step_size; in fan_get_max_state()
39 *state = fan->fps_count - 1; in fan_get_max_state()
44 return 0; in fan_get_max_state()
52 int ret = 0; in acpi_fan_get_fst()
54 status = acpi_evaluate_object(device->handle, "_FST", NULL, &buffer); in acpi_fan_get_fst()
56 dev_err(&device->dev, "Get fan state failed\n"); in acpi_fan_get_fst()
57 return -ENODEV; in acpi_fan_get_fst()
61 if (!obj || obj->type != ACPI_TYPE_PACKAGE || in acpi_fan_get_fst()
62 obj->package.count != 3 || in acpi_fan_get_fst()
63 obj->package.elements[1].type != ACPI_TYPE_INTEGER) { in acpi_fan_get_fst()
64 dev_err(&device->dev, "Invalid _FST data\n"); in acpi_fan_get_fst()
65 ret = -EINVAL; in acpi_fan_get_fst()
69 fst->revision = obj->package.elements[0].integer.value; in acpi_fan_get_fst()
70 fst->control = obj->package.elements[1].integer.value; in acpi_fan_get_fst()
71 fst->speed = obj->package.elements[2].integer.value; in acpi_fan_get_fst()
80 struct acpi_fan *fan = acpi_driver_data(device); in fan_get_state_acpi4() local
88 if (fan->fif.fine_grain_ctrl) { in fan_get_state_acpi4()
91 dev_dbg(&device->dev, "Invalid control value returned\n"); in fan_get_state_acpi4()
95 *state = (int) fst.control / fan->fif.step_size; in fan_get_state_acpi4()
96 return 0; in fan_get_state_acpi4()
100 for (i = 0; i < fan->fps_count; i++) { in fan_get_state_acpi4()
101 if (fst.control == fan->fps[i].control) in fan_get_state_acpi4()
104 if (i == fan->fps_count) { in fan_get_state_acpi4()
105 dev_dbg(&device->dev, "Invalid control value returned\n"); in fan_get_state_acpi4()
106 return -EINVAL; in fan_get_state_acpi4()
125 0 : (acpi_state == ACPI_STATE_D0 ? 1 : -1); in fan_get_state()
126 return 0; in fan_get_state()
132 struct acpi_device *device = cdev->devdata; in fan_get_cur_state()
133 struct acpi_fan *fan = acpi_driver_data(device); in fan_get_cur_state() local
135 if (fan->acpi4) in fan_get_cur_state()
143 if (state != 0 && state != 1) in fan_set_state()
144 return -EINVAL; in fan_set_state()
152 struct acpi_fan *fan = acpi_driver_data(device); in fan_set_state_acpi4() local
157 if (fan->fif.fine_grain_ctrl) in fan_set_state_acpi4()
158 max_state = 100 / fan->fif.step_size; in fan_set_state_acpi4()
160 max_state = fan->fps_count - 1; in fan_set_state_acpi4()
163 return -EINVAL; in fan_set_state_acpi4()
165 if (fan->fif.fine_grain_ctrl) { in fan_set_state_acpi4()
166 value *= fan->fif.step_size; in fan_set_state_acpi4()
168 if (value + fan->fif.step_size > 100) in fan_set_state_acpi4()
171 value = fan->fps[state].control; in fan_set_state_acpi4()
174 status = acpi_execute_simple_method(device->handle, "_FSL", value); in fan_set_state_acpi4()
176 dev_dbg(&device->dev, "Failed to set state by _FSL\n"); in fan_set_state_acpi4()
177 return -ENODEV; in fan_set_state_acpi4()
180 return 0; in fan_set_state_acpi4()
186 struct acpi_device *device = cdev->devdata; in fan_set_cur_state()
187 struct acpi_fan *fan = acpi_driver_data(device); in fan_set_cur_state() local
189 if (fan->acpi4) in fan_set_cur_state()
201 /* --------------------------------------------------------------------------
203 * --------------------------------------------------------------------------
208 return acpi_has_method(device->handle, "_FST"); in acpi_fan_has_fst()
213 return acpi_has_method(device->handle, "_FIF") && in acpi_fan_is_acpi4()
214 acpi_has_method(device->handle, "_FPS") && in acpi_fan_is_acpi4()
215 acpi_has_method(device->handle, "_FSL"); in acpi_fan_is_acpi4()
221 struct acpi_fan *fan = acpi_driver_data(device); in acpi_fan_get_fif() local
228 status = acpi_evaluate_object(device->handle, "_FIF", NULL, &buffer); in acpi_fan_get_fif()
233 if (!obj || obj->type != ACPI_TYPE_PACKAGE) { in acpi_fan_get_fif()
234 dev_err(&device->dev, "Invalid _FIF data\n"); in acpi_fan_get_fif()
235 status = -EINVAL; in acpi_fan_get_fif()
241 dev_err(&device->dev, "Invalid _FIF element\n"); in acpi_fan_get_fif()
242 status = -EINVAL; in acpi_fan_get_fif()
246 fan->fif.revision = fields[0]; in acpi_fan_get_fif()
247 fan->fif.fine_grain_ctrl = fields[1]; in acpi_fan_get_fif()
248 fan->fif.step_size = fields[2]; in acpi_fan_get_fif()
249 fan->fif.low_speed_notification = fields[3]; in acpi_fan_get_fif()
251 /* If there is a bug in step size and set as 0, change to 1 */ in acpi_fan_get_fif()
252 if (!fan->fif.step_size) in acpi_fan_get_fif()
253 fan->fif.step_size = 1; in acpi_fan_get_fif()
254 /* If step size > 9, change to 9 (by spec valid values 1-9) */ in acpi_fan_get_fif()
255 else if (fan->fif.step_size > 9) in acpi_fan_get_fif()
256 fan->fif.step_size = 9; in acpi_fan_get_fif()
266 return fps1->speed - fps2->speed; in acpi_fan_speed_cmp()
271 struct acpi_fan *fan = acpi_driver_data(device); in acpi_fan_get_fps() local
277 status = acpi_evaluate_object(device->handle, "_FPS", NULL, &buffer); in acpi_fan_get_fps()
282 if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count < 2) { in acpi_fan_get_fps()
283 dev_err(&device->dev, "Invalid _FPS data\n"); in acpi_fan_get_fps()
284 status = -EINVAL; in acpi_fan_get_fps()
288 fan->fps_count = obj->package.count - 1; /* minus revision field */ in acpi_fan_get_fps()
289 fan->fps = devm_kcalloc(&device->dev, in acpi_fan_get_fps()
290 fan->fps_count, sizeof(struct acpi_fan_fps), in acpi_fan_get_fps()
292 if (!fan->fps) { in acpi_fan_get_fps()
293 dev_err(&device->dev, "Not enough memory\n"); in acpi_fan_get_fps()
294 status = -ENOMEM; in acpi_fan_get_fps()
297 for (i = 0; i < fan->fps_count; i++) { in acpi_fan_get_fps()
300 &fan->fps[i] }; in acpi_fan_get_fps()
301 status = acpi_extract_package(&obj->package.elements[i + 1], in acpi_fan_get_fps()
304 dev_err(&device->dev, "Invalid _FPS element\n"); in acpi_fan_get_fps()
309 /* sort the state array according to fan speed in increase order */ in acpi_fan_get_fps()
310 sort(fan->fps, fan->fps_count, sizeof(*fan->fps), in acpi_fan_get_fps()
320 int result = 0; in acpi_fan_probe()
322 struct acpi_fan *fan; in acpi_fan_probe() local
323 struct acpi_device *device = ACPI_COMPANION(&pdev->dev); in acpi_fan_probe()
326 fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL); in acpi_fan_probe()
327 if (!fan) { in acpi_fan_probe()
328 dev_err(&device->dev, "No memory for fan\n"); in acpi_fan_probe()
329 return -ENOMEM; in acpi_fan_probe()
331 device->driver_data = fan; in acpi_fan_probe()
332 platform_set_drvdata(pdev, fan); in acpi_fan_probe()
335 fan->has_fst = true; in acpi_fan_probe()
336 fan->acpi4 = acpi_fan_is_acpi4(device); in acpi_fan_probe()
339 if (fan->acpi4) { in acpi_fan_probe()
349 if (fan->has_fst) { in acpi_fan_probe()
359 if (!fan->acpi4) { in acpi_fan_probe()
362 dev_err(&device->dev, "Failed to set initial power state\n"); in acpi_fan_probe()
367 if (!strncmp(pdev->name, "PNP0C0B", strlen("PNP0C0B"))) in acpi_fan_probe()
368 name = "Fan"; in acpi_fan_probe()
379 dev_dbg(&pdev->dev, "registered as cooling_device%d\n", cdev->id); in acpi_fan_probe()
381 fan->cdev = cdev; in acpi_fan_probe()
382 result = sysfs_create_link(&pdev->dev.kobj, in acpi_fan_probe()
383 &cdev->device.kobj, in acpi_fan_probe()
386 dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n"); in acpi_fan_probe()
390 result = sysfs_create_link(&cdev->device.kobj, in acpi_fan_probe()
391 &pdev->dev.kobj, in acpi_fan_probe()
394 dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n"); in acpi_fan_probe()
398 return 0; in acpi_fan_probe()
401 sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling"); in acpi_fan_probe()
405 if (fan->has_fst) in acpi_fan_probe()
413 struct acpi_fan *fan = platform_get_drvdata(pdev); in acpi_fan_remove() local
415 if (fan->has_fst) { in acpi_fan_remove()
416 struct acpi_device *device = ACPI_COMPANION(&pdev->dev); in acpi_fan_remove()
420 sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling"); in acpi_fan_remove()
421 sysfs_remove_link(&fan->cdev->device.kobj, "device"); in acpi_fan_remove()
422 thermal_cooling_device_unregister(fan->cdev); in acpi_fan_remove()
428 struct acpi_fan *fan = dev_get_drvdata(dev); in acpi_fan_suspend() local
429 if (fan->acpi4) in acpi_fan_suspend()
430 return 0; in acpi_fan_suspend()
440 struct acpi_fan *fan = dev_get_drvdata(dev); in acpi_fan_resume() local
442 if (fan->acpi4) in acpi_fan_resume()
443 return 0; in acpi_fan_resume()
447 dev_err(dev, "Error updating fan power state\n"); in acpi_fan_resume()
470 .name = "acpi-fan",
479 MODULE_DESCRIPTION("ACPI Fan Driver");