diff options
Diffstat (limited to 'drivers/extcon')
-rw-r--r-- | drivers/extcon/Kconfig | 7 | ||||
-rw-r--r-- | drivers/extcon/Makefile | 1 | ||||
-rw-r--r-- | drivers/extcon/devres.c | 50 | ||||
-rw-r--r-- | drivers/extcon/extcon-intel-int3496.c | 2 | ||||
-rw-r--r-- | drivers/extcon/extcon-max77693.c | 5 | ||||
-rw-r--r-- | drivers/extcon/extcon-usbc-cros-ec.c | 417 | ||||
-rw-r--r-- | drivers/extcon/extcon.c | 279 |
7 files changed, 588 insertions, 173 deletions
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 6d50071f07d5..a7bca4207f44 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -150,4 +150,11 @@ config EXTCON_USB_GPIO Say Y here to enable GPIO based USB cable detection extcon support. Used typically if GPIO is used for USB ID pin detection. +config EXTCON_USBC_CROS_EC + tristate "ChromeOS Embedded Controller EXTCON support" + depends on MFD_CROS_EC + help + Say Y here to enable USB Type C cable detection extcon support when + using Chrome OS EC based USB Type-C ports. + endif diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index ecfa95804427..a73624e76193 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_EXTCON_QCOM_SPMI_MISC) += extcon-qcom-spmi-misc.o obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o +obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o diff --git a/drivers/extcon/devres.c b/drivers/extcon/devres.c index 186fd735eb28..f599aeddf8e5 100644 --- a/drivers/extcon/devres.c +++ b/drivers/extcon/devres.c @@ -1,5 +1,5 @@ /* - * drivers/extcon/devres.c - EXTCON device's resource management + * drivers/extcon/devres.c - EXTCON device's resource management * * Copyright (C) 2016 Samsung Electronics * Author: Chanwoo Choi <cw00.choi@samsung.com> @@ -59,10 +59,9 @@ static void devm_extcon_dev_notifier_all_unreg(struct device *dev, void *res) /** * devm_extcon_dev_allocate - Allocate managed extcon device - * @dev: device owning the extcon device being created - * @supported_cable: Array of supported extcon ending with EXTCON_NONE. - * If supported_cable is NULL, cable name related APIs - * are disabled. + * @dev: the device owning the extcon device being created + * @supported_cable: the array of the supported external connectors + * ending with EXTCON_NONE. * * This function manages automatically the memory of extcon device using device * resource management and simplify the control of freeing the memory of extcon @@ -97,8 +96,8 @@ EXPORT_SYMBOL_GPL(devm_extcon_dev_allocate); /** * devm_extcon_dev_free() - Resource-managed extcon_dev_unregister() - * @dev: device the extcon belongs to - * @edev: the extcon device to unregister + * @dev: the device owning the extcon device being created + * @edev: the extcon device to be freed * * Free the memory that is allocated with devm_extcon_dev_allocate() * function. @@ -112,10 +111,9 @@ EXPORT_SYMBOL_GPL(devm_extcon_dev_free); /** * devm_extcon_dev_register() - Resource-managed extcon_dev_register() - * @dev: device to allocate extcon device - * @edev: the new extcon device to register + * @dev: the device owning the extcon device being created + * @edev: the extcon device to be registered * - * Managed extcon_dev_register() function. If extcon device is attached with * this function, that extcon device is automatically unregistered on driver * detach. Internally this function calls extcon_dev_register() function. * To get more information, refer that function. @@ -149,8 +147,8 @@ EXPORT_SYMBOL_GPL(devm_extcon_dev_register); /** * devm_extcon_dev_unregister() - Resource-managed extcon_dev_unregister() - * @dev: device the extcon belongs to - * @edev: the extcon device to unregister + * @dev: the device owning the extcon device being created + * @edev: the extcon device to unregistered * * Unregister extcon device that is registered with devm_extcon_dev_register() * function. @@ -164,10 +162,10 @@ EXPORT_SYMBOL_GPL(devm_extcon_dev_unregister); /** * devm_extcon_register_notifier() - Resource-managed extcon_register_notifier() - * @dev: device to allocate extcon device - * @edev: the extcon device that has the external connecotr. - * @id: the unique id of each external connector in extcon enumeration. - * @nb: a notifier block to be registered. + * @dev: the device owning the extcon device being created + * @edev: the extcon device + * @id: the unique id among the extcon enumeration + * @nb: a notifier block to be registered * * This function manages automatically the notifier of extcon device using * device resource management and simplify the control of unregistering @@ -208,10 +206,10 @@ EXPORT_SYMBOL(devm_extcon_register_notifier); /** * devm_extcon_unregister_notifier() - Resource-managed extcon_unregister_notifier() - * @dev: device to allocate extcon device - * @edev: the extcon device that has the external connecotr. - * @id: the unique id of each external connector in extcon enumeration. - * @nb: a notifier block to be registered. + * @dev: the device owning the extcon device being created + * @edev: the extcon device + * @id: the unique id among the extcon enumeration + * @nb: a notifier block to be registered */ void devm_extcon_unregister_notifier(struct device *dev, struct extcon_dev *edev, unsigned int id, @@ -225,9 +223,9 @@ EXPORT_SYMBOL(devm_extcon_unregister_notifier); /** * devm_extcon_register_notifier_all() * - Resource-managed extcon_register_notifier_all() - * @dev: device to allocate extcon device - * @edev: the extcon device that has the external connecotr. - * @nb: a notifier block to be registered. + * @dev: the device owning the extcon device being created + * @edev: the extcon device + * @nb: a notifier block to be registered * * This function manages automatically the notifier of extcon device using * device resource management and simplify the control of unregistering @@ -263,9 +261,9 @@ EXPORT_SYMBOL(devm_extcon_register_notifier_all); /** * devm_extcon_unregister_notifier_all() * - Resource-managed extcon_unregister_notifier_all() - * @dev: device to allocate extcon device - * @edev: the extcon device that has the external connecotr. - * @nb: a notifier block to be registered. + * @dev: the device owning the extcon device being created + * @edev: the extcon device + * @nb: a notifier block to be registered */ void devm_extcon_unregister_notifier_all(struct device *dev, struct extcon_dev *edev, diff --git a/drivers/extcon/extcon-intel-int3496.c b/drivers/extcon/extcon-intel-int3496.c index d9f9afe45961..1a45e745717d 100644 --- a/drivers/extcon/extcon-intel-int3496.c +++ b/drivers/extcon/extcon-intel-int3496.c @@ -171,7 +171,7 @@ static int int3496_remove(struct platform_device *pdev) return 0; } -static struct acpi_device_id int3496_acpi_match[] = { +static const struct acpi_device_id int3496_acpi_match[] = { { "INT3496" }, { } }; diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 62163468f205..7a5856809047 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -811,9 +811,8 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) */ extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, attached); - if (!cable_attached) - extcon_set_state_sync(info->edev, - EXTCON_DISP_MHL, cable_attached); + extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, + cable_attached); break; } diff --git a/drivers/extcon/extcon-usbc-cros-ec.c b/drivers/extcon/extcon-usbc-cros-ec.c new file mode 100644 index 000000000000..598956f1dcae --- /dev/null +++ b/drivers/extcon/extcon-usbc-cros-ec.c @@ -0,0 +1,417 @@ +/** + * drivers/extcon/extcon-usbc-cros-ec - ChromeOS Embedded Controller extcon + * + * Copyright (C) 2017 Google, Inc + * Author: Benson Leung <bleung@chromium.org> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/extcon.h> +#include <linux/kernel.h> +#include <linux/mfd/cros_ec.h> +#include <linux/module.h> +#include <linux/notifier.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/sched.h> + +struct cros_ec_extcon_info { + struct device *dev; + struct extcon_dev *edev; + + int port_id; + + struct cros_ec_device *ec; + + struct notifier_block notifier; + + bool dp; /* DisplayPort enabled */ + bool mux; /* SuperSpeed (usb3) enabled */ + unsigned int power_type; +}; + +static const unsigned int usb_type_c_cable[] = { + EXTCON_DISP_DP, + EXTCON_NONE, +}; + +/** + * cros_ec_pd_command() - Send a command to the EC. + * @info: pointer to struct cros_ec_extcon_info + * @command: EC command + * @version: EC command version + * @outdata: EC command output data + * @outsize: Size of outdata + * @indata: EC command input data + * @insize: Size of indata + * + * Return: 0 on success, <0 on failure. + */ +static int cros_ec_pd_command(struct cros_ec_extcon_info *info, + unsigned int command, + unsigned int version, + void *outdata, + unsigned int outsize, + void *indata, + unsigned int insize) +{ + struct cros_ec_command *msg; + int ret; + + msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->version = version; + msg->command = command; + msg->outsize = outsize; + msg->insize = insize; + + if (outsize) + memcpy(msg->data, outdata, outsize); + + ret = cros_ec_cmd_xfer_status(info->ec, msg); + if (ret >= 0 && insize) + memcpy(indata, msg->data, insize); + + kfree(msg); + return ret; +} + +/** + * cros_ec_usb_get_power_type() - Get power type info about PD device attached + * to given port. + * @info: pointer to struct cros_ec_extcon_info + * + * Return: power type on success, <0 on failure. + */ +static int cros_ec_usb_get_power_type(struct cros_ec_extcon_info *info) +{ + struct ec_params_usb_pd_power_info req; + struct ec_response_usb_pd_power_info resp; + int ret; + + req.port = info->port_id; + ret = cros_ec_pd_command(info, EC_CMD_USB_PD_POWER_INFO, 0, + &req, sizeof(req), &resp, sizeof(resp)); + if (ret < 0) + return ret; + + return resp.type; +} + +/** + * cros_ec_usb_get_pd_mux_state() - Get PD mux state for given port. + * @info: pointer to struct cros_ec_extcon_info + * + * Return: PD mux state on success, <0 on failure. + */ +static int cros_ec_usb_get_pd_mux_state(struct cros_ec_extcon_info *info) +{ + struct ec_params_usb_pd_mux_info req; + struct ec_response_usb_pd_mux_info resp; + int ret; + + req.port = info->port_id; + ret = cros_ec_pd_command(info, EC_CMD_USB_PD_MUX_INFO, 0, + &req, sizeof(req), + &resp, sizeof(resp)); + if (ret < 0) + return ret; + + return resp.flags; +} + +/** + * cros_ec_usb_get_role() - Get role info about possible PD device attached to a + * given port. + * @info: pointer to struct cros_ec_extcon_info + * @polarity: pointer to cable polarity (return value) + * + * Return: role info on success, -ENOTCONN if no cable is connected, <0 on + * failure. + */ +static int cros_ec_usb_get_role(struct cros_ec_extcon_info *info, + bool *polarity) +{ + struct ec_params_usb_pd_control pd_control; + struct ec_response_usb_pd_control_v1 resp; + int ret; + + pd_control.port = info->port_id; + pd_control.role = USB_PD_CTRL_ROLE_NO_CHANGE; + pd_control.mux = USB_PD_CTRL_MUX_NO_CHANGE; + ret = cros_ec_pd_command(info, EC_CMD_USB_PD_CONTROL, 1, + &pd_control, sizeof(pd_control), + &resp, sizeof(resp)); + if (ret < 0) + return ret; + + if (!(resp.enabled & PD_CTRL_RESP_ENABLED_CONNECTED)) + return -ENOTCONN; + + *polarity = resp.polarity; + + return resp.role; +} + +/** + * cros_ec_pd_get_num_ports() - Get number of EC charge ports. + * @info: pointer to struct cros_ec_extcon_info + * + * Return: number of ports on success, <0 on failure. + */ +static int cros_ec_pd_get_num_ports(struct cros_ec_extcon_info *info) +{ + struct ec_response_usb_pd_ports resp; + int ret; + + ret = cros_ec_pd_command(info, EC_CMD_USB_PD_PORTS, + 0, NULL, 0, &resp, sizeof(resp)); + if (ret < 0) + return ret; + + return resp.num_ports; +} + +static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, + bool force) +{ + struct device *dev = info->dev; + int role, power_type; + bool polarity = false; + bool dp = false; + bool mux = false; + bool hpd = false; + + power_type = cros_ec_usb_get_power_type(info); + if (power_type < 0) { + dev_err(dev, "failed getting power type err = %d\n", + power_type); + return power_type; + } + + role = cros_ec_usb_get_role(info, &polarity); + if (role < 0) { + if (role != -ENOTCONN) { + dev_err(dev, "failed getting role err = %d\n", role); + return role; + } + } else { + int pd_mux_state; + + pd_mux_state = cros_ec_usb_get_pd_mux_state(info); + if (pd_mux_state < 0) + pd_mux_state = USB_PD_MUX_USB_ENABLED; + + dp = pd_mux_state & USB_PD_MUX_DP_ENABLED; + mux = pd_mux_state & USB_PD_MUX_USB_ENABLED; + hpd = pd_mux_state & USB_PD_MUX_HPD_IRQ; + } + + if (force || info->dp != dp || info->mux != mux || + info->power_type != power_type) { + + info->dp = dp; + info->mux = mux; + info->power_type = power_type; + + extcon_set_state(info->edev, EXTCON_DISP_DP, dp); + + extcon_set_property(info->edev, EXTCON_DISP_DP, + EXTCON_PROP_USB_TYPEC_POLARITY, + (union extcon_property_value)(int)polarity); + extcon_set_property(info->edev, EXTCON_DISP_DP, + EXTCON_PROP_USB_SS, + (union extcon_property_value)(int)mux); + extcon_set_property(info->edev, EXTCON_DISP_DP, + EXTCON_PROP_DISP_HPD, + (union extcon_property_value)(int)hpd); + + extcon_sync(info->edev, EXTCON_DISP_DP); + + } else if (hpd) { + extcon_set_property(info->edev, EXTCON_DISP_DP, + EXTCON_PROP_DISP_HPD, + (union extcon_property_value)(int)hpd); + extcon_sync(info->edev, EXTCON_DISP_DP); + } + + return 0; +} + +static int extcon_cros_ec_event(struct notifier_block *nb, + unsigned long queued_during_suspend, + void *_notify) +{ + struct cros_ec_extcon_info *info; + struct cros_ec_device *ec; + u32 host_event; + + info = container_of(nb, struct cros_ec_extcon_info, notifier); + ec = info->ec; + + host_event = cros_ec_get_host_event(ec); + if (host_event & (EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU) | + EC_HOST_EVENT_MASK(EC_HOST_EVENT_USB_MUX))) { + extcon_cros_ec_detect_cable(info, false); + return NOTIFY_OK; + } + + return NOTIFY_DONE; +} + +static int extcon_cros_ec_probe(struct platform_device *pdev) +{ + struct cros_ec_extcon_info *info; + struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + int numports, ret; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = dev; + info->ec = ec; + + if (np) { + u32 port; + + ret = of_property_read_u32(np, "google,usb-port-id", &port); + if (ret < 0) { + dev_err(dev, "Missing google,usb-port-id property\n"); + return ret; + } + info->port_id = port; + } else { + info->port_id = pdev->id; + } + + numports = cros_ec_pd_get_num_ports(info); + if (numports < 0) { + dev_err(dev, "failed getting number of ports! ret = %d\n", + numports); + return numports; + } + + if (info->port_id >= numports) { + dev_err(dev, "This system only supports %d ports\n", numports); + return -ENODEV; + } + + info->edev = devm_extcon_dev_allocate(dev, usb_type_c_cable); + if (IS_ERR(info->edev)) { + dev_err(dev, "failed to allocate extcon device\n"); + return -ENOMEM; + } + + ret = devm_extcon_dev_register(dev, info->edev); + if (ret < 0) { + dev_err(dev, "failed to register extcon device\n"); + return ret; + } + + extcon_set_property_capability(info->edev, EXTCON_DISP_DP, + EXTCON_PROP_USB_TYPEC_POLARITY); + extcon_set_property_capability(info->edev, EXTCON_DISP_DP, + EXTCON_PROP_USB_SS); + extcon_set_property_capability(info->edev, EXTCON_DISP_DP, + EXTCON_PROP_DISP_HPD); + + platform_set_drvdata(pdev, info); + + /* Get PD events from the EC */ + info->notifier.notifier_call = extcon_cros_ec_event; + ret = blocking_notifier_chain_register(&info->ec->event_notifier, + &info->notifier); + if (ret < 0) { + dev_err(dev, "failed to register notifier\n"); + return ret; + } + + /* Perform initial detection */ + ret = extcon_cros_ec_detect_cable(info, true); + if (ret < 0) { + dev_err(dev, "failed to detect initial cable state\n"); + goto unregister_notifier; + } + + return 0; + +unregister_notifier: + blocking_notifier_chain_unregister(&info->ec->event_notifier, + &info->notifier); + return ret; +} + +static int extcon_cros_ec_remove(struct platform_device *pdev) +{ + struct cros_ec_extcon_info *info = platform_get_drvdata(pdev); + + blocking_notifier_chain_unregister(&info->ec->event_notifier, + &info->notifier); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int extcon_cros_ec_suspend(struct device *dev) +{ + return 0; +} + +static int extcon_cros_ec_resume(struct device *dev) +{ + int ret; + struct cros_ec_extcon_info *info = dev_get_drvdata(dev); + + ret = extcon_cros_ec_detect_cable(info, true); + if (ret < 0) + dev_err(dev, "failed to detect cable state on resume\n"); + + return 0; +} + +static const struct dev_pm_ops extcon_cros_ec_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(extcon_cros_ec_suspend, extcon_cros_ec_resume) +}; + +#define DEV_PM_OPS (&extcon_cros_ec_dev_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ + +#ifdef CONFIG_OF +static const struct of_device_id extcon_cros_ec_of_match[] = { + { .compatible = "google,extcon-usbc-cros-ec" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, extcon_cros_ec_of_match); +#endif /* CONFIG_OF */ + +static struct platform_driver extcon_cros_ec_driver = { + .driver = { + .name = "extcon-usbc-cros-ec", + .of_match_table = of_match_ptr(extcon_cros_ec_of_match), + .pm = DEV_PM_OPS, + }, + .remove = extcon_cros_ec_remove, + .probe = extcon_cros_ec_probe, +}; + +module_platform_driver(extcon_cros_ec_driver); + +MODULE_DESCRIPTION("ChromeOS Embedded Controller extcon driver"); +MODULE_AUTHOR("Benson Leung <bleung@chromium.org>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 8eccf7b14937..35e9fb885486 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -1,7 +1,5 @@ /* - * drivers/extcon/extcon.c - External Connector (extcon) framework. - * - * External connector (extcon) class driver + * drivers/extcon/extcon.c - External Connector (extcon) framework. * * Copyright (C) 2015 Samsung Electronics * Author: Chanwoo Choi <cw00.choi@samsung.com> @@ -37,7 +35,6 @@ #include "extcon.h" #define SUPPORTED_CABLE_MAX 32 -#define CABLE_NAME_MAX 30 struct __extcon_info { unsigned int type; @@ -200,13 +197,13 @@ struct __extcon_info { }; /** - * struct extcon_cable - An internal data for each cable of extcon device. - * @edev: The extcon device - * @cable_index: Index of this cable in the edev - * @attr_g: Attribute group for the cable + * struct extcon_cable - An internal data for an external connector. + * @edev: the extcon device + * @cable_index: the index of this cable in the edev + * @attr_g: the attribute group for the cable * @attr_name: "name" sysfs entry * @attr_state: "state" sysfs entry - * @attrs: Array pointing to attr_name and attr_state for attr_g + * @attrs: the array pointing to attr_name and attr_state for attr_g */ struct extcon_cable { struct extcon_dev *edev; @@ -234,15 +231,6 @@ static struct class *extcon_class; static LIST_HEAD(extcon_dev_list); static DEFINE_MUTEX(extcon_dev_list_lock); -/** - * check_mutually_exclusive - Check if new_state violates mutually_exclusive - * condition. - * @edev: the extcon device - * @new_state: new cable attach status for @edev - * - * Returns 0 if nothing violates. Returns the index + 1 for the first - * violated condition. - */ static int check_mutually_exclusive(struct extcon_dev *edev, u32 new_state) { int i = 0; @@ -417,11 +405,13 @@ static ssize_t cable_state_show(struct device *dev, } /** - * extcon_sync() - Synchronize the states for both the attached/detached - * @edev: the extcon device that has the cable. + * extcon_sync() - Synchronize the state for an external connector. + * @edev: the extcon device + * + * Note that this function send a notification in order to synchronize + * the state and property of an external connector. * - * This function send a notification to synchronize the all states of a - * specific external connector + * Returns 0 if success or error number if fail. */ int extcon_sync(struct extcon_dev *edev, unsigned int id) { @@ -497,9 +487,11 @@ int extcon_sync(struct extcon_dev *edev, unsigned int id) EXPORT_SYMBOL_GPL(extcon_sync); /** - * extcon_get_state() - Get the state of a external connector. - * @edev: the extcon device that has the cable. - * @id: the unique id of each external connector in extcon enumeration. + * extcon_get_state() - Get the state of an external connector. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * + * Returns 0 if success or error number if fail. */ int extcon_get_state(struct extcon_dev *edev, const unsigned int id) { @@ -522,20 +514,19 @@ int extcon_get_state(struct extcon_dev *edev, const unsigned int id) EXPORT_SYMBOL_GPL(extcon_get_state); /** - * extcon_set_state() - Set the state of a external connector. - * without a notification. - * @edev: the extcon device that has the cable. - * @id: the unique id of each external connector - * in extcon enumeration. - * @state: the new cable status. The default semantics is - * true: attached / false: detached. + * extcon_set_state() - Set the state of an external connector. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * @state: the new state of an external connector. + * the default semantics is true: attached / false: detached. + * + * Note that this function set the state of an external connector without + * a notification. To synchronize the state of an external connector, + * have to use extcon_set_state_sync() and extcon_sync(). * - * This function only set the state of a external connector without - * a notification. To synchronize the data of a external connector, - * use extcon_set_state_sync() and extcon_sync(). + * Returns 0 if success or error number if fail. */ -int extcon_set_state(struct extcon_dev *edev, unsigned int id, - bool cable_state) +int extcon_set_state(struct extcon_dev *edev, unsigned int id, bool state) { unsigned long flags; int index, ret = 0; @@ -550,11 +541,11 @@ int extcon_set_state(struct extcon_dev *edev, unsigned int id, spin_lock_irqsave(&edev->lock, flags); /* Check whether the external connector's state is changed. */ - if (!is_extcon_changed(edev, index, cable_state)) + if (!is_extcon_changed(edev, index, state)) goto out; if (check_mutually_exclusive(edev, - (edev->state & ~BIT(index)) | (cable_state & BIT(index)))) { + (edev->state & ~BIT(index)) | (state & BIT(index)))) { ret = -EPERM; goto out; } @@ -563,11 +554,11 @@ int extcon_set_state(struct extcon_dev *edev, unsigned int id, * Initialize the value of extcon property before setting * the detached state for an external connector. */ - if (!cable_state) + if (!state) init_property(edev, id, index); - /* Update the state for a external connector. */ - if (cable_state) + /* Update the state for an external connector. */ + if (state) edev->state |= BIT(index); else edev->state &= ~(BIT(index)); @@ -579,19 +570,18 @@ out: EXPORT_SYMBOL_GPL(extcon_set_state); /** - * extcon_set_state_sync() - Set the state of a external connector - * with a notification. - * @edev: the extcon device that has the cable. - * @id: the unique id of each external connector - * in extcon enumeration. - * @state: the new cable status. The default semantics is - * true: attached / false: detached. + * extcon_set_state_sync() - Set the state of an external connector with sync. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * @state: the new state of external connector. + * the default semantics is true: attached / false: detached. + * + * Note that this function set the state of external connector + * and synchronize the state by sending a notification. * - * This function set the state of external connector and synchronize the data - * by usning a notification. + * Returns 0 if success or error number if fail. */ -int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, - bool cable_state) +int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, bool state) { int ret, index; unsigned long flags; @@ -602,12 +592,12 @@ int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, /* Check whether the external connector's state is changed. */ spin_lock_irqsave(&edev->lock, flags); - ret = is_extcon_changed(edev, index, cable_state); + ret = is_extcon_changed(edev, index, state); spin_unlock_irqrestore(&edev->lock, flags); if (!ret) return 0; - ret = extcon_set_state(edev, id, cable_state); + ret = extcon_set_state(edev, id, state); if (ret < 0) return ret; @@ -616,19 +606,18 @@ int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, EXPORT_SYMBOL_GPL(extcon_set_state_sync); /** - * extcon_get_property() - Get the property value of a specific cable. - * @edev: the extcon device that has the cable. - * @id: the unique id of each external connector - * in extcon enumeration. - * @prop: the property id among enum extcon_property. - * @prop_val: the pointer which store the value of property. + * extcon_get_property() - Get the property value of an external connector. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * @prop: the property id indicating an extcon property + * @prop_val: the pointer which store the value of extcon property * - * When getting the property value of external connector, the external connector - * should be attached. If detached state, function just return 0 without - * property value. Also, the each property should be included in the list of - * supported properties according to the type of external connectors. + * Note that when getting the property value of external connector, + * the external connector should be attached. If detached state, function + * return 0 without property value. Also, the each property should be + * included in the list of supported properties according to extcon type. * - * Returns 0 if success or error number if fail + * Returns 0 if success or error number if fail. */ int extcon_get_property(struct extcon_dev *edev, unsigned int id, unsigned int prop, @@ -698,17 +687,16 @@ int extcon_get_property(struct extcon_dev *edev, unsigned int id, EXPORT_SYMBOL_GPL(extcon_get_property); /** - * extcon_set_property() - Set the property value of a specific cable. - * @edev: the extcon device that has the cable. - * @id: the unique id of each external connector - * in extcon enumeration. - * @prop: the property id among enum extcon_property. - * @prop_val: the pointer including the new value of property. + * extcon_set_property() - Set the property value of an external connector. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * @prop: the property id indicating an extcon property + * @prop_val: the pointer including the new value of extcon property * - * The each property should be included in the list of supported properties - * according to the type of external connectors. + * Note that each property should be included in the list of supported + * properties according to the extcon type. * - * Returns 0 if success or error number if fail + * Returns 0 if success or error number if fail. */ int extcon_set_property(struct extcon_dev *edev, unsigned int id, unsigned int prop, @@ -766,15 +754,14 @@ int extcon_set_property(struct extcon_dev *edev, unsigned int id, EXPORT_SYMBOL_GPL(extcon_set_property); /** - * extcon_set_property_sync() - Set the property value of a specific cable - with a notification. - * @prop_val: the pointer including the new value of property. + * extcon_set_property_sync() - Set property of an external connector with sync. + * @prop_val: the pointer including the new value of extcon property * - * When setting the property value of external connector, the external connector - * should be attached. The each property should be included in the list of - * supported properties according to the type of external connectors. + * Note that when setting the property value of external connector, + * the external connector should be attached. The each property should + * be included in the list of supported properties according to extcon type. * - * Returns 0 if success or error number if fail + * Returns 0 if success or error number if fail. */ int extcon_set_property_sync(struct extcon_dev *edev, unsigned int id, unsigned int prop, @@ -791,12 +778,11 @@ int extcon_set_property_sync(struct extcon_dev *edev, unsigned int id, EXPORT_SYMBOL_GPL(extcon_set_property_sync); /** - * extcon_get_property_capability() - Get the capability of property - * of an external connector. - * @edev: the extcon device that has the cable. - * @id: the unique id of each external connector - * in extcon enumeration. - * @prop: the property id among enum extcon_property. + * extcon_get_property_capability() - Get the capability of the property + * for an external connector. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * @prop: the property id indicating an extcon property * * Returns 1 if the property is available or 0 if not available. */ @@ -822,18 +808,17 @@ int extcon_get_property_capability(struct extcon_dev *edev, unsigned int id, EXPORT_SYMBOL_GPL(extcon_get_property_capability); /** - * extcon_set_property_capability() - Set the capability of a property - * of an external connector. - * @edev: the extcon device that has the cable. - * @id: the unique id of each external connector - * in extcon enumeration. - * @prop: the property id among enum extcon_property. + * extcon_set_property_capability() - Set the capability of the property + * for an external connector. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * @prop: the property id indicating an extcon property * - * This function set the capability of a property for an external connector - * to mark the bit in capability bitmap which mean the available state of - * a property. + * Note that this function set the capability of the property + * for an external connector in order to mark the bit in capability + * bitmap which mean the available state of the property. * - * Returns 0 if success or error number if fail + * Returns 0 if success or error number if fail. */ int extcon_set_property_capability(struct extcon_dev *edev, unsigned int id, unsigned int prop) @@ -881,8 +866,10 @@ int extcon_set_property_capability(struct extcon_dev *edev, unsigned int id, EXPORT_SYMBOL_GPL(extcon_set_property_capability); /** - * extcon_get_extcon_dev() - Get the extcon device instance from the name - * @extcon_name: The extcon name provided with extcon_dev_register() + * extcon_get_extcon_dev() - Get the extcon device instance from the name. + * @extcon_name: the extcon name provided with extcon_dev_register() + * + * Return the pointer of extcon device if success or ERR_PTR(err) if fail. */ struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) { @@ -904,15 +891,17 @@ out: EXPORT_SYMBOL_GPL(extcon_get_extcon_dev); /** - * extcon_register_notifier() - Register a notifiee to get notified by - * any attach status changes from the extcon. - * @edev: the extcon device that has the external connecotr. - * @id: the unique id of each external connector in extcon enumeration. - * @nb: a notifier block to be registered. + * extcon_register_notifier() - Register a notifier block to get notified by + * any state changes from the extcon. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * @nb: a notifier block to be registered * * Note that the second parameter given to the callback of nb (val) is - * "old_state", not the current state. The current state can be retrieved - * by looking at the third pameter (edev pointer)'s state value. + * the current state of an external connector and the third pameter + * is the pointer of extcon device. + * + * Returns 0 if success or error number if fail. */ int extcon_register_notifier(struct extcon_dev *edev, unsigned int id, struct notifier_block *nb) @@ -936,10 +925,12 @@ int extcon_register_notifier(struct extcon_dev *edev, unsigned int id, EXPORT_SYMBOL_GPL(extcon_register_notifier); /** - * extcon_unregister_notifier() - Unregister a notifiee from the extcon device. - * @edev: the extcon device that has the external connecotr. - * @id: the unique id of each external connector in extcon enumeration. - * @nb: a notifier block to be registered. + * extcon_unregister_notifier() - Unregister a notifier block from the extcon. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * @nb: a notifier block to be registered + * + * Returns 0 if success or error number if fail. */ int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id, struct notifier_block *nb) @@ -963,16 +954,16 @@ int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id, EXPORT_SYMBOL_GPL(extcon_unregister_notifier); /** - * extcon_register_notifier_all() - Register a notifier block for all connectors - * @edev: the extcon device that has the external connector. - * @nb: a notifier block to be registered. + * extcon_register_notifier_all() - Register a notifier block for all connectors. + * @edev: the extcon device + * @nb: a notifier block to be registered * - * This function registers a notifier block in order to receive the state - * change of all supported external connectors from extcon device. + * Note that this function registers a notifier block in order to receive + * the state change of all supported external connectors from extcon device. * And the second parameter given to the callback of nb (val) is - * the current state and third parameter is the edev pointer. + * the current state and the third pameter is the pointer of extcon device. * - * Returns 0 if success or error number if fail + * Returns 0 if success or error number if fail. */ int extcon_register_notifier_all(struct extcon_dev *edev, struct notifier_block *nb) @@ -993,10 +984,10 @@ EXPORT_SYMBOL_GPL(extcon_register_notifier_all); /** * extcon_unregister_notifier_all() - Unregister a notifier block from extcon. - * @edev: the extcon device that has the external connecotr. - * @nb: a notifier block to be registered. + * @edev: the extcon device + * @nb: a notifier block to be registered * - * Returns 0 if success or error number if fail + * Returns 0 if success or error number if fail. */ int extcon_unregister_notifier_all(struct extcon_dev *edev, struct notifier_block *nb) @@ -1045,15 +1036,14 @@ static void dummy_sysfs_dev_release(struct device *dev) /* * extcon_dev_allocate() - Allocate the memory of extcon device. - * @supported_cable: Array of supported extcon ending with EXTCON_NONE. - * If supported_cable is NULL, cable name related APIs - * are disabled. + * @supported_cable: the array of the supported external connectors + * ending with EXTCON_NONE. * - * This function allocates the memory for extcon device without allocating - * memory in each extcon provider driver and initialize default setting for - * extcon device. + * Note that this function allocates the memory for extcon device + * and initialize default setting for the extcon device. * - * Return the pointer of extcon device if success or ERR_PTR(err) if fail + * Returns the pointer memory of allocated extcon_dev if success + * or ERR_PTR(err) if fail. */ struct extcon_dev *extcon_dev_allocate(const unsigned int *supported_cable) { @@ -1074,7 +1064,7 @@ struct extcon_dev *extcon_dev_allocate(const unsigned int *supported_cable) /* * extcon_dev_free() - Free the memory of extcon device. - * @edev: the extcon device to free + * @edev: the extcon device */ void extcon_dev_free(struct extcon_dev *edev) { @@ -1083,13 +1073,18 @@ void extcon_dev_free(struct extcon_dev *edev) EXPORT_SYMBOL_GPL(extcon_dev_free); /** - * extcon_dev_register() - Register a new extcon device - * @edev : the new extcon device (should be allocated before calling) + * extcon_dev_register() - Register an new extcon device + * @edev: the extcon device to be registered * * Among the members of edev struct, please set the "user initializing data" - * in any case and set the "optional callbacks" if required. However, please * do not set the values of "internal data", which are initialized by * this function. + * + * Note that before calling this funciton, have to allocate the memory + * of an extcon device by using the extcon_dev_allocate(). And the extcon + * dev should include the supported_cable information. + * + * Returns 0 if success or error number if fail. */ int extcon_dev_register(struct extcon_dev *edev) { @@ -1296,7 +1291,7 @@ EXPORT_SYMBOL_GPL(extcon_dev_register); /** * extcon_dev_unregister() - Unregister the extcon device. - * @edev: the extcon device instance to be unregistered. + * @edev: the extcon device to be unregistered. * * Note that this does not call kfree(edev) because edev was not allocated * by this class. @@ -1342,11 +1337,11 @@ EXPORT_SYMBOL_GPL(extcon_dev_unregister); #ifdef CONFIG_OF /* - * extcon_get_edev_by_phandle - Get the extcon device from devicetree - * @dev - instance to the given device - * @index - index into list of extcon_dev + * extcon_get_edev_by_phandle - Get the extcon device from devicetree. + * @dev : the instance to the given device + * @index : the index into list of extcon_dev * - * return the instance of extcon device + * Return the pointer of extcon device if success or ERR_PTR(err) if fail. */ struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index) { @@ -1363,8 +1358,8 @@ struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index) node = of_parse_phandle(dev->of_node, "extcon", index); if (!node) { - dev_dbg(dev, "failed to get phandle in %s node\n", - dev->of_node->full_name); + dev_dbg(dev, "failed to get phandle in %pOF node\n", + dev->of_node); return ERR_PTR(-ENODEV); } @@ -1411,8 +1406,6 @@ static void __exit extcon_class_exit(void) module_exit(extcon_class_exit); MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); -MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>"); -MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); -MODULE_DESCRIPTION("External connector (extcon) class driver"); -MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("External Connector (extcon) framework"); +MODULE_LICENSE("GPL v2"); |