Lines Matching +full:fan +full:-
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * fan_core.c - ACPI Fan core Driver
20 #include "fan.h"
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()
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()
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()
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()
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()
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, "_FIF") && in acpi_fan_is_acpi4()
209 acpi_has_method(device->handle, "_FPS") && in acpi_fan_is_acpi4()
210 acpi_has_method(device->handle, "_FSL") && in acpi_fan_is_acpi4()
211 acpi_has_method(device->handle, "_FST"); in acpi_fan_is_acpi4()
217 struct acpi_fan *fan = acpi_driver_data(device); in acpi_fan_get_fif() local
224 status = acpi_evaluate_object(device->handle, "_FIF", NULL, &buffer); in acpi_fan_get_fif()
229 if (!obj || obj->type != ACPI_TYPE_PACKAGE) { in acpi_fan_get_fif()
230 dev_err(&device->dev, "Invalid _FIF data\n"); in acpi_fan_get_fif()
231 status = -EINVAL; in acpi_fan_get_fif()
237 dev_err(&device->dev, "Invalid _FIF element\n"); in acpi_fan_get_fif()
238 status = -EINVAL; in acpi_fan_get_fif()
242 fan->fif.revision = fields[0]; in acpi_fan_get_fif()
243 fan->fif.fine_grain_ctrl = fields[1]; in acpi_fan_get_fif()
244 fan->fif.step_size = fields[2]; in acpi_fan_get_fif()
245 fan->fif.low_speed_notification = fields[3]; in acpi_fan_get_fif()
248 if (!fan->fif.step_size) in acpi_fan_get_fif()
249 fan->fif.step_size = 1; in acpi_fan_get_fif()
250 /* If step size > 9, change to 9 (by spec valid values 1-9) */ in acpi_fan_get_fif()
251 else if (fan->fif.step_size > 9) in acpi_fan_get_fif()
252 fan->fif.step_size = 9; in acpi_fan_get_fif()
262 return fps1->speed - fps2->speed; in acpi_fan_speed_cmp()
267 struct acpi_fan *fan = acpi_driver_data(device); in acpi_fan_get_fps() local
273 status = acpi_evaluate_object(device->handle, "_FPS", NULL, &buffer); in acpi_fan_get_fps()
278 if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count < 2) { in acpi_fan_get_fps()
279 dev_err(&device->dev, "Invalid _FPS data\n"); in acpi_fan_get_fps()
280 status = -EINVAL; in acpi_fan_get_fps()
284 fan->fps_count = obj->package.count - 1; /* minus revision field */ in acpi_fan_get_fps()
285 fan->fps = devm_kcalloc(&device->dev, in acpi_fan_get_fps()
286 fan->fps_count, sizeof(struct acpi_fan_fps), in acpi_fan_get_fps()
288 if (!fan->fps) { in acpi_fan_get_fps()
289 dev_err(&device->dev, "Not enough memory\n"); in acpi_fan_get_fps()
290 status = -ENOMEM; in acpi_fan_get_fps()
293 for (i = 0; i < fan->fps_count; i++) { in acpi_fan_get_fps()
296 &fan->fps[i] }; in acpi_fan_get_fps()
297 status = acpi_extract_package(&obj->package.elements[i + 1], in acpi_fan_get_fps()
300 dev_err(&device->dev, "Invalid _FPS element\n"); in acpi_fan_get_fps()
305 /* sort the state array according to fan speed in increase order */ in acpi_fan_get_fps()
306 sort(fan->fps, fan->fps_count, sizeof(*fan->fps), in acpi_fan_get_fps()
318 struct acpi_fan *fan; in acpi_fan_probe() local
319 struct acpi_device *device = ACPI_COMPANION(&pdev->dev); in acpi_fan_probe()
322 fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL); in acpi_fan_probe()
323 if (!fan) { in acpi_fan_probe()
324 dev_err(&device->dev, "No memory for fan\n"); in acpi_fan_probe()
325 return -ENOMEM; in acpi_fan_probe()
327 device->driver_data = fan; in acpi_fan_probe()
328 platform_set_drvdata(pdev, fan); in acpi_fan_probe()
347 fan->acpi4 = true; in acpi_fan_probe()
351 dev_err(&device->dev, "Failed to set initial power state\n"); in acpi_fan_probe()
356 if (!strncmp(pdev->name, "PNP0C0B", strlen("PNP0C0B"))) in acpi_fan_probe()
357 name = "Fan"; in acpi_fan_probe()
368 dev_dbg(&pdev->dev, "registered as cooling_device%d\n", cdev->id); in acpi_fan_probe()
370 fan->cdev = cdev; in acpi_fan_probe()
371 result = sysfs_create_link(&pdev->dev.kobj, in acpi_fan_probe()
372 &cdev->device.kobj, in acpi_fan_probe()
375 dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n"); in acpi_fan_probe()
377 result = sysfs_create_link(&cdev->device.kobj, in acpi_fan_probe()
378 &pdev->dev.kobj, in acpi_fan_probe()
381 dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n"); in acpi_fan_probe()
388 if (fan->acpi4) in acpi_fan_probe()
396 struct acpi_fan *fan = platform_get_drvdata(pdev); in acpi_fan_remove() local
398 if (fan->acpi4) { in acpi_fan_remove()
399 struct acpi_device *device = ACPI_COMPANION(&pdev->dev); in acpi_fan_remove()
403 sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling"); in acpi_fan_remove()
404 sysfs_remove_link(&fan->cdev->device.kobj, "device"); in acpi_fan_remove()
405 thermal_cooling_device_unregister(fan->cdev); in acpi_fan_remove()
411 struct acpi_fan *fan = dev_get_drvdata(dev); in acpi_fan_suspend() local
412 if (fan->acpi4) in acpi_fan_suspend()
423 struct acpi_fan *fan = dev_get_drvdata(dev); in acpi_fan_resume() local
425 if (fan->acpi4) in acpi_fan_resume()
430 dev_err(dev, "Error updating fan power state\n"); in acpi_fan_resume()
453 .name = "acpi-fan",
462 MODULE_DESCRIPTION("ACPI Fan Driver");