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: Peng Wang <penwang@codeaurora.org>
This commit is contained in:
Peng Wang 2020-11-03 15:07:02 +08:00
parent 4153972078
commit a98c378b89
3 changed files with 125 additions and 0 deletions

View File

@ -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

View File

@ -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

116
drivers/char/rb5_fan.c Normal file
View File

@ -0,0 +1,116 @@
// 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");