From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751450AbcHAFv3 (ORCPT ); Mon, 1 Aug 2016 01:51:29 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:36846 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750743AbcHAFvC (ORCPT ); Mon, 1 Aug 2016 01:51:02 -0400 X-AuditID: cbfee68e-f79cb6d000006cfe-4e-579ee3428f36 From: Chanwoo Choi To: linux-kernel@vger.kernel.org Cc: cw00.choi@samsung.com, myungjoo.ham@samsung.com, zyw@rock-chips.com, groeck@chromium.org, chanwoo@kernel.org Subject: [PATCH v2 3/6] extcon: Add the support for the capability of each property Date: Mon, 01 Aug 2016 14:50:51 +0900 Message-id: <1470030654-6641-4-git-send-email-cw00.choi@samsung.com> X-Mailer: git-send-email 1.8.0 In-reply-to: <1470030654-6641-1-git-send-email-cw00.choi@samsung.com> References: <1470030654-6641-1-git-send-email-cw00.choi@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrOLMWRmVeSWpSXmKPExsWyRsSkQNf58bxwg8tzmC0m3rjCYnH9y3NW i1OvljFbXN41h83iduMKNov5D3YwO7B5zG64yOKxaVUnm8ffWftZPPq2rGL0+LxJLoA1issm JTUnsyy1SN8ugStj1pyNjAVHbCumnvjH1MC4yKiLkZNDQsBEom/7D2YIW0ziwr31bF2MXBxC AisYJV6cnMkCV7RsDTNEYimjxMRpfxghnC+MEvuWLWACqWIT0JLY/+IGG4gtIqAgsbn3GSuI zSxQJDH/9GuwFcICoRLrJv5mBLFZBFQlFjz/B2bzCrhIvDv2kBFim5zEhz2P2EFsTgFXiWd7 u8CuEAKqObVlNRPIYgmB6ewS1/beZoUYJCDxbfIhoCIOoISsxKYDUO9IShxccYNlAqPwAkaG VYyiqQXJBcVJ6UVGesWJucWleel6yfm5mxiB4X3637O+HYw3D1gfYhTgYFTi4eVgmhcuxJpY VlyZe4jRFGjDRGYp0eR8YBTllcQbGpsZWZiamBobmVuaKYnzJkj9DBYSSE8sSc1OTS1ILYov Ks1JLT7EyMTBKdXA2PY3pFw0tPZYicTqQ3P6jH7MX3fdv/n74kd9WXwzA3YsDxUPKnH9uUGD V+68aoVw8QLTY0tkWcLT723j+dk8PenextVGHV59MTqrGt99YA3murVq+5QDqrJ20Q1cRVKn Zmdt3CHZOtfA9/mEMtHUmt+lL+31IoyuaXZkFLUsMcliPPNyxStpJZbijERDLeai4kQAxEWW DmoCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrCIsWRmVeSWpSXmKPExsVy+t9jAV2nx/PCDf6usbKYeOMKi8X1L89Z LU69WsZscXnXHDaL240r2CzmP9jB7MDmMbvhIovHplWdbB5/Z+1n8ejbsorR4/MmuQDWqAZG m4zUxJTUIoXUvOT8lMy8dFsl7+B453hTMwNDXUNLC3MlhbzE3FRbJRefAF23zBygE5QUyhJz SoFCAYnFxUr6dpgmhIa46VrANEbo+oYEwfUYGaCBhDWMGbPmbGQsOGJbMfXEP6YGxkVGXYyc HBICJhJ9y9YwQ9hiEhfurWfrYuTiEBJYyigxcdofRgjnC6PEvmULmECq2AS0JPa/uMEGYosI KEhs7n3GCmIzCxRJzD/9GmySsECoxLqJvxlBbBYBVYkFz/+B2bwCLhLvjj1khNgmJ/FhzyN2 EJtTwFXi2d4uFhBbCKjm1JbVTBMYeRcwMqxilEgtSC4oTkrPNcxLLdcrTswtLs1L10vOz93E CI6hZ1I7GA/ucj/EKMDBqMTDm+A/L1yINbGsuDL3EKMEB7OSCO/Hh0Ah3pTEyqrUovz4otKc 1OJDjKZAh01klhJNzgfGd15JvKGxiZmRpZG5oYWRsbmSOO/j/+vChATSE0tSs1NTC1KLYPqY ODilGhjT8hnK4rRTohMWRHX393Jrvv4u6j1hEc/09v8l3Cms87cX73/Y//XJDrU28QSTuF3+ f0rD54kyXxDIrb0ge6z1x37jtw2Latv1LrAYNE20eG+4NPh4pO8O34DUEMkrbxZWTc+c8H+L 8+JqLqWfmlXrdyxprHnfPef0tUQ3zWnHzjqFn/zak6nEUpyRaKjFXFScCAAeEijztwIAAA== DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds the support of the property capability setting. This function decides the supported properties of each external connector on extcon provider driver. Ths list of new extcon APIs to get/set the capability of property as following: - int extcon_get_property_capability(struct extcon_dev *edev, unsigned int id, unsigned int prop); - int extcon_set_property_capability(struct extcon_dev *edev, unsigned int id, unsigned int prop); Signed-off-by: Chanwoo Choi Tested-by: Chris Zhong --- drivers/extcon/extcon.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/extcon.h | 22 ++++++++ 2 files changed, 163 insertions(+) diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 4027aee08ce5..10b201b161ac 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -201,6 +201,11 @@ struct extcon_cable { union extcon_property_value chg_propval[EXTCON_PROP_CHG_CNT]; union extcon_property_value jack_propval[EXTCON_PROP_JACK_CNT]; union extcon_property_value disp_propval[EXTCON_PROP_DISP_CNT]; + + unsigned long usb_bits[BITS_TO_LONGS(EXTCON_PROP_USB_CNT)]; + unsigned long chg_bits[BITS_TO_LONGS(EXTCON_PROP_CHG_CNT)]; + unsigned long jack_bits[BITS_TO_LONGS(EXTCON_PROP_JACK_CNT)]; + unsigned long disp_bits[BITS_TO_LONGS(EXTCON_PROP_DISP_CNT)]; }; static struct class *extcon_class; @@ -297,6 +302,39 @@ static bool is_extcon_property_supported(unsigned int id, unsigned int prop) return !!(extcon_info[id].type & type); } +static int is_extcon_property_capability(struct extcon_dev *edev, + unsigned int id, int index,unsigned int prop) +{ + struct extcon_cable *cable; + int type, ret; + + /* Check whether the property is supported or not. */ + type = get_extcon_type(prop); + if (type < 0) + return type; + + cable = &edev->cables[index]; + + switch (type) { + case EXTCON_TYPE_USB: + ret = test_bit(prop - EXTCON_PROP_USB_MIN, cable->usb_bits); + break; + case EXTCON_TYPE_CHG: + ret = test_bit(prop - EXTCON_PROP_CHG_MIN, cable->chg_bits); + break; + case EXTCON_TYPE_JACK: + ret = test_bit(prop - EXTCON_PROP_JACK_MIN, cable->jack_bits); + break; + case EXTCON_TYPE_DISP: + ret = test_bit(prop - EXTCON_PROP_DISP_MIN, cable->disp_bits); + break; + default: + ret = -EINVAL; + } + + return ret; +} + static void init_property(struct extcon_dev *edev, unsigned int id, int index) { unsigned int type = extcon_info[id].type; @@ -554,6 +592,12 @@ int extcon_get_property(struct extcon_dev *edev, unsigned int id, spin_lock_irqsave(&edev->lock, flags); + /* Check whether the property is available or not. */ + if (!is_extcon_property_capability(edev, id, index, prop)) { + spin_unlock_irqrestore(&edev->lock, flags); + return -EPERM; + } + /* * Check whether the external connector is attached. * If external connector is detached, the user can not @@ -626,6 +670,12 @@ int extcon_set_property(struct extcon_dev *edev, unsigned int id, spin_lock_irqsave(&edev->lock, flags); + /* Check whether the property is available or not. */ + if (!is_extcon_property_capability(edev, id, index, prop)) { + spin_unlock_irqrestore(&edev->lock, flags); + return -EPERM; + } + cable = &edev->cables[index]; /* Set the property value according to extcon type */ @@ -654,6 +704,97 @@ int extcon_set_property(struct extcon_dev *edev, unsigned int id, EXPORT_SYMBOL_GPL(extcon_set_property); /** + * 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. + * + * Returns 1 if the property is available or 0 if not available. + */ +int extcon_get_property_capability(struct extcon_dev *edev, unsigned int id, + unsigned int prop) +{ + int index; + + if (!edev) + return -EINVAL; + + /* Check whether the property is supported or not */ + if (!is_extcon_property_supported(id, prop)) + return -EINVAL; + + /* Find the cable index of external connector by using id */ + index = find_cable_index_by_id(edev, id); + if (index < 0) + return index; + + return is_extcon_property_capability(edev, id, index, prop); +} +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. + * + * 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. + * + * Returns 0 if success or error number if fail + */ +int extcon_set_property_capability(struct extcon_dev *edev, unsigned int id, + unsigned int prop) +{ + struct extcon_cable *cable; + int index, type, ret = 0; + + if (!edev) + return -EINVAL; + + /* Check whether the property is supported or not. */ + if (!is_extcon_property_supported(id, prop)) + return -EINVAL; + + /* Find the cable index of external connector by using id. */ + index = find_cable_index_by_id(edev, id); + if (index < 0) + return index; + + /* Check whether the property is supported or not. */ + type = get_extcon_type(prop); + if (type < 0) + return type; + + cable = &edev->cables[index]; + + switch (type) { + case EXTCON_TYPE_USB: + __set_bit(prop - EXTCON_PROP_USB_MIN, cable->usb_bits); + break; + case EXTCON_TYPE_CHG: + __set_bit(prop - EXTCON_PROP_CHG_MIN, cable->chg_bits); + break; + case EXTCON_TYPE_JACK: + __set_bit(prop - EXTCON_PROP_JACK_MIN, cable->jack_bits); + break; + case EXTCON_TYPE_DISP: + __set_bit(prop - EXTCON_PROP_DISP_MIN, cable->disp_bits); + break; + default: + ret = -EINVAL; + } + + return ret; +} +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() */ diff --git a/include/linux/extcon.h b/include/linux/extcon.h index 5a97e52abefb..80b740d81b1f 100644 --- a/include/linux/extcon.h +++ b/include/linux/extcon.h @@ -240,6 +240,16 @@ extern int extcon_set_property(struct extcon_dev *edev, unsigned int id, union extcon_property_value prop_val); /* + * get/set_property_capability set the capability of the property for each + * external connector. They are used to set the capability of the property + * of each external connector based on the id and property. + */ +extern int extcon_get_property_capability(struct extcon_dev *edev, + unsigned int id, unsigned int prop); +extern int extcon_set_property_capability(struct extcon_dev *edev, + unsigned int id, unsigned int prop); + +/* * Following APIs are to monitor every action of a notifier. * Registrar gets notified for every external port of a connection device. * Probably this could be used to debug an action of notifier; however, @@ -325,6 +335,18 @@ static inline int extcon_set_property(struct extcon_dev *edev, unsigned int id, return 0; } +static inline int extcon_get_property_capability(struct extcon_dev *edev, + unsigned int id, unsigned int prop) +{ + return 0; +} + +static inline int extcon_set_property_capability(struct extcon_dev *edev, + unsigned int id, unsigned int prop) +{ + return 0; +} + static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) { return NULL; -- 1.9.1