Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a98c378b authored by Peng Wang's avatar Peng Wang
Browse files

msm: fan: Add driver to control fan on RB5



Add driver to control fan on QRB5165 with PM8150L gpio10.

Change-Id: I09d4a3f359c952fd81be6149cbc0b9435d53bb9d
Signed-off-by: default avatarPeng Wang <penwang@codeaurora.org>
parent 41539720
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -587,6 +587,14 @@ config ADI
	  and SSM (Silicon Secured Memory).  Intended consumers of this
	  driver include crash and makedumpfile.

config RB5_FAN_CONTROLLER
	tristate "RB5 fan controller driver support"
	help
	  The driver supports the fan controller on QRB5165 device.
	  The driver controls fan with PM8150L gpio10. It outputs
	  high to the pin, which is defined in device-tree as
	  qcom,pwr-enable-gpio.

endmenu

config RANDOM_TRUST_CPU
+1 −0
Original line number Diff line number Diff line
@@ -73,3 +73,4 @@ obj-$(CONFIG_VSERVICES_SERIAL_CLIENT) += vs_serial_client.o
CFLAGS_vs_serial_client.o	 += -Werror
obj-$(CONFIG_VSERVICES_SERIAL_SERVER)	+= vs_serial_server.o
CFLAGS_vs_serial_server.o	+= -Werror
obj-$(CONFIG_RB5_FAN_CONTROLLER)	+= rb5_fan.o

drivers/char/rb5_fan.c

0 → 100644
+116 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only

/**
 * Driver for control fan on QRB5165.
 *
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/kernel.h>

#define DEV_NAME "rb5_fan"

static int major;
static struct class *fan_class;

static u32 pwr_enable_gpio;

static const struct file_operations fan_fops = {
	.owner		= THIS_MODULE,
};

static int fan_probe(struct platform_device *pdev)
{
	struct device *dev = NULL;
	struct device_node *np = pdev->dev.of_node;

	pr_debug(DEV_NAME ": probe\n");

	major = register_chrdev(0, DEV_NAME, &fan_fops);
	if (major < 0) {
		pr_warn(DEV_NAME ": unable to get major %d\n", major);
		return major;
	}

	fan_class = class_create(THIS_MODULE, DEV_NAME);
	if (IS_ERR(fan_class))
		return PTR_ERR(fan_class);

	dev = device_create(fan_class, NULL, MKDEV(major, 0), NULL, DEV_NAME);
	if (IS_ERR(dev)) {
		pr_err(DEV_NAME ": failed to create device %d\n", dev);
		return PTR_ERR(dev);
	}

	pwr_enable_gpio = of_get_named_gpio(np, "qcom,pwr-enable-gpio", 0);
	if (!gpio_is_valid(pwr_enable_gpio)) {
		pr_err("%s qcom,pwr-enable-gpio not specified\n", __func__);
		goto error;
	}
	if (gpio_request(pwr_enable_gpio, "qcom,pwr-enable-gpio")) {
		pr_err("qcom,pwr-enable-gpio request failed\n");
		goto error;
	}
	gpio_direction_output(pwr_enable_gpio, 0);
	gpio_set_value(pwr_enable_gpio, 1);
	pr_debug("%s gpio:%d set to high\n", __func__, pwr_enable_gpio);
	return 0;

error:
	gpio_free(pwr_enable_gpio);
	return -EINVAL;
}

static int fan_remove(struct platform_device *pdev)
{
	pr_debug(DEV_NAME ": remove\n");
	gpio_free(pwr_enable_gpio);
	device_destroy(fan_class, MKDEV(major, 0));
	class_destroy(fan_class);
	unregister_chrdev(major, DEV_NAME);
	return 0;
}

static const struct of_device_id of_fan_dt_match[] = {
	{.compatible	= "qcom,rb5_fan_controller"},
	{},
};

MODULE_DEVICE_TABLE(of, of_fan_dt_match);

static struct platform_driver fan_driver = {
	.probe	= fan_probe,
	.remove	= fan_remove,
	.driver	= {
		.name	= DEV_NAME,
		.of_match_table	= of_fan_dt_match,
	},
};

static int __init fan_init(void)
{
	pr_debug(DEV_NAME ": init\n");
	return platform_driver_register(&fan_driver);
}

static void __exit fan_exit(void)
{
	pr_debug(DEV_NAME ": exit\n");
	platform_driver_unregister(&fan_driver);
}

module_init(fan_init);
module_exit(fan_exit);

MODULE_DESCRIPTION("Driver to control fan");
MODULE_LICENSE("GPL v2");