summaryrefslogtreecommitdiff
path: root/drivers/mfd/cros_ec_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/cros_ec_dev.c')
-rw-r--r--drivers/mfd/cros_ec_dev.c91
1 files changed, 75 insertions, 16 deletions
diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index 92f4dfccc3cc..dc80a272726b 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * cros_ec_dev - expose the Chrome OS Embedded Controller to user-space
+ * ChromeOS Embedded Controller
*
* Copyright (C) 2014 Google, Inc.
*/
@@ -10,7 +10,7 @@
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
-#include <linux/of_platform.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_data/cros_ec_chardev.h>
#include <linux/platform_data/cros_ec_commands.h>
@@ -74,6 +74,10 @@ static const struct mfd_cell cros_ec_cec_cells[] = {
{ .name = "cros-ec-cec", },
};
+static const struct mfd_cell cros_ec_gpio_cells[] = {
+ { .name = "cros-ec-gpio", },
+};
+
static const struct mfd_cell cros_ec_rtc_cells[] = {
{ .name = "cros-ec-rtc", },
};
@@ -91,6 +95,26 @@ static const struct mfd_cell cros_usbpd_notify_cells[] = {
{ .name = "cros-usbpd-notify", },
};
+static const struct mfd_cell cros_ec_wdt_cells[] = {
+ { .name = "cros-ec-wdt", }
+};
+
+static const struct mfd_cell cros_ec_led_cells[] = {
+ { .name = "cros-ec-led", },
+};
+
+static const struct mfd_cell cros_ec_keyboard_leds_cells[] = {
+ { .name = "cros-keyboard-leds", },
+};
+
+static const struct mfd_cell cros_ec_ucsi_cells[] = {
+ { .name = "cros_ec_ucsi", },
+};
+
+static const struct mfd_cell cros_ec_charge_control_cells[] = {
+ { .name = "cros-charge-control", },
+};
+
static const struct cros_feature_to_cells cros_subdevices[] = {
{
.id = EC_FEATURE_CEC,
@@ -98,20 +122,46 @@ static const struct cros_feature_to_cells cros_subdevices[] = {
.num_cells = ARRAY_SIZE(cros_ec_cec_cells),
},
{
+ .id = EC_FEATURE_GPIO,
+ .mfd_cells = cros_ec_gpio_cells,
+ .num_cells = ARRAY_SIZE(cros_ec_gpio_cells),
+ },
+ {
.id = EC_FEATURE_RTC,
.mfd_cells = cros_ec_rtc_cells,
.num_cells = ARRAY_SIZE(cros_ec_rtc_cells),
},
{
- .id = EC_FEATURE_USB_PD,
- .mfd_cells = cros_usbpd_charger_cells,
- .num_cells = ARRAY_SIZE(cros_usbpd_charger_cells),
+ .id = EC_FEATURE_UCSI_PPM,
+ .mfd_cells = cros_ec_ucsi_cells,
+ .num_cells = ARRAY_SIZE(cros_ec_ucsi_cells),
+ },
+ {
+ .id = EC_FEATURE_HANG_DETECT,
+ .mfd_cells = cros_ec_wdt_cells,
+ .num_cells = ARRAY_SIZE(cros_ec_wdt_cells),
+ },
+ {
+ .id = EC_FEATURE_LED,
+ .mfd_cells = cros_ec_led_cells,
+ .num_cells = ARRAY_SIZE(cros_ec_led_cells),
+ },
+ {
+ .id = EC_FEATURE_PWM_KEYB,
+ .mfd_cells = cros_ec_keyboard_leds_cells,
+ .num_cells = ARRAY_SIZE(cros_ec_keyboard_leds_cells),
+ },
+ {
+ .id = EC_FEATURE_CHARGER,
+ .mfd_cells = cros_ec_charge_control_cells,
+ .num_cells = ARRAY_SIZE(cros_ec_charge_control_cells),
},
};
static const struct mfd_cell cros_ec_platform_cells[] = {
{ .name = "cros-ec-chardev", },
{ .name = "cros-ec-debugfs", },
+ { .name = "cros-ec-hwmon", },
{ .name = "cros-ec-sysfs", },
};
@@ -215,6 +265,21 @@ static int ec_device_probe(struct platform_device *pdev)
}
/*
+ * UCSI provides power supply information so we don't need to separately
+ * load the cros_usbpd_charger driver.
+ */
+ if (cros_ec_check_features(ec, EC_FEATURE_USB_PD) &&
+ !cros_ec_check_features(ec, EC_FEATURE_UCSI_PPM)) {
+ retval = mfd_add_hotplug_devices(ec->dev,
+ cros_usbpd_charger_cells,
+ ARRAY_SIZE(cros_usbpd_charger_cells));
+
+ if (retval)
+ dev_warn(ec->dev, "failed to add usbpd-charger: %d\n",
+ retval);
+ }
+
+ /*
* Lightbar is a special case. Newer devices support autodetection,
* but older ones do not.
*/
@@ -288,13 +353,12 @@ failed:
return retval;
}
-static int ec_device_remove(struct platform_device *pdev)
+static void ec_device_remove(struct platform_device *pdev)
{
struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev);
mfd_remove_devices(ec->dev);
device_unregister(&ec->class_dev);
- return 0;
}
static const struct platform_device_id cros_ec_id[] = {
@@ -316,22 +380,17 @@ static int __init cros_ec_dev_init(void)
{
int ret;
- ret = class_register(&cros_class);
+ ret = class_register(&cros_class);
if (ret) {
pr_err(CROS_EC_DEV_NAME ": failed to register device class\n");
return ret;
}
- /* Register the driver */
ret = platform_driver_register(&cros_ec_dev_driver);
- if (ret < 0) {
+ if (ret) {
pr_warn(CROS_EC_DEV_NAME ": can't register driver: %d\n", ret);
- goto failed_devreg;
+ class_unregister(&cros_class);
}
- return 0;
-
-failed_devreg:
- class_unregister(&cros_class);
return ret;
}
@@ -345,6 +404,6 @@ module_init(cros_ec_dev_init);
module_exit(cros_ec_dev_exit);
MODULE_AUTHOR("Bill Richardson <wfrichar@chromium.org>");
-MODULE_DESCRIPTION("Userspace interface to the Chrome OS Embedded Controller");
+MODULE_DESCRIPTION("ChromeOS Embedded Controller");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");