// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  fan_attr.c - Create extra attributes for ACPI Fan driver
 *
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *  Copyright (C) 2022 Intel Corporation. All rights reserved.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/acpi.h>

#include "fan.h"

MODULE_LICENSE("GPL");

static ssize_t show_state(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct acpi_fan_fps *fps = container_of(attr, struct acpi_fan_fps, dev_attr);
	int count;

	if (fps->control == 0xFFFFFFFF || fps->control > 100)
		count = scnprintf(buf, PAGE_SIZE, "not-defined:");
	else
		count = scnprintf(buf, PAGE_SIZE, "%lld:", fps->control);

	if (fps->trip_point == 0xFFFFFFFF || fps->trip_point > 9)
		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
	else
		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->trip_point);

	if (fps->speed == 0xFFFFFFFF)
		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
	else
		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->speed);

	if (fps->noise_level == 0xFFFFFFFF)
		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
	else
		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->noise_level * 100);

	if (fps->power == 0xFFFFFFFF)
		count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined\n");
	else
		count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld\n", fps->power);

	return count;
}

static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct acpi_device *acpi_dev = container_of(dev, struct acpi_device, dev);
	struct acpi_fan_fst fst;
	int status;

	status = acpi_fan_get_fst(acpi_dev, &fst);
	if (status)
		return status;

	return sprintf(buf, "%lld\n", fst.speed);
}

static ssize_t show_fine_grain_control(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct acpi_device *acpi_dev = container_of(dev, struct acpi_device, dev);
	struct acpi_fan *fan = acpi_driver_data(acpi_dev);

	return sprintf(buf, "%d\n", fan->fif.fine_grain_ctrl);
}

int acpi_fan_create_attributes(struct acpi_device *device)
{
	struct acpi_fan *fan = acpi_driver_data(device);
	int i, status;

	sysfs_attr_init(&fan->fine_grain_control.attr);
	fan->fine_grain_control.show = show_fine_grain_control;
	fan->fine_grain_control.store = NULL;
	fan->fine_grain_control.attr.name = "fine_grain_control";
	fan->fine_grain_control.attr.mode = 0444;
	status = sysfs_create_file(&device->dev.kobj, &fan->fine_grain_control.attr);
	if (status)
		return status;

	/* _FST is present if we are here */
	sysfs_attr_init(&fan->fst_speed.attr);
	fan->fst_speed.show = show_fan_speed;
	fan->fst_speed.store = NULL;
	fan->fst_speed.attr.name = "fan_speed_rpm";
	fan->fst_speed.attr.mode = 0444;
	status = sysfs_create_file(&device->dev.kobj, &fan->fst_speed.attr);
	if (status)
		goto rem_fine_grain_attr;

	for (i = 0; i < fan->fps_count; ++i) {
		struct acpi_fan_fps *fps = &fan->fps[i];

		snprintf(fps->name, ACPI_FPS_NAME_LEN, "state%d", i);
		sysfs_attr_init(&fps->dev_attr.attr);
		fps->dev_attr.show = show_state;
		fps->dev_attr.store = NULL;
		fps->dev_attr.attr.name = fps->name;
		fps->dev_attr.attr.mode = 0444;
		status = sysfs_create_file(&device->dev.kobj, &fps->dev_attr.attr);
		if (status) {
			int j;

			for (j = 0; j < i; ++j)
				sysfs_remove_file(&device->dev.kobj, &fan->fps[j].dev_attr.attr);
			goto rem_fst_attr;
		}
	}

	return 0;

rem_fst_attr:
	sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);

rem_fine_grain_attr:
	sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);

	return status;
}

void acpi_fan_delete_attributes(struct acpi_device *device)
{
	struct acpi_fan *fan = acpi_driver_data(device);
	int i;

	for (i = 0; i < fan->fps_count; ++i)
		sysfs_remove_file(&device->dev.kobj, &fan->fps[i].dev_attr.attr);

	sysfs_remove_file(&device->dev.kobj, &fan->fst_speed.attr);
	sysfs_remove_file(&device->dev.kobj, &fan->fine_grain_control.attr);
}
