aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon
diff options
context:
space:
mode:
authorChanwoo Choi <cw00.choi@samsung.com>2016-07-25 08:15:19 -0400
committerChanwoo Choi <cw00.choi@samsung.com>2016-08-07 22:17:22 -0400
commit7f2a0a1699b51bfd738f1e0b15e057996fe1f259 (patch)
treedf2537d5d727507e9ff6611587b787dc52278a50 /drivers/extcon
parent792e7e9e5d4358bc6157152b2c07b94eb9e261b0 (diff)
extcon: Add the support for the capability of each property
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 <cw00.choi@samsung.com> Tested-by: Chris Zhong <zyw@rock-chips.com> Tested-by: Guenter Roeck <groeck@chromium.org> Reviewed-by: Guenter Roeck <groeck@chromium.org>
Diffstat (limited to 'drivers/extcon')
-rw-r--r--drivers/extcon/extcon.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
index 37fa4b51c5a1..599fc377a965 100644
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -201,6 +201,11 @@ struct extcon_cable {
201 union extcon_property_value chg_propval[EXTCON_PROP_CHG_CNT]; 201 union extcon_property_value chg_propval[EXTCON_PROP_CHG_CNT];
202 union extcon_property_value jack_propval[EXTCON_PROP_JACK_CNT]; 202 union extcon_property_value jack_propval[EXTCON_PROP_JACK_CNT];
203 union extcon_property_value disp_propval[EXTCON_PROP_DISP_CNT]; 203 union extcon_property_value disp_propval[EXTCON_PROP_DISP_CNT];
204
205 unsigned long usb_bits[BITS_TO_LONGS(EXTCON_PROP_USB_CNT)];
206 unsigned long chg_bits[BITS_TO_LONGS(EXTCON_PROP_CHG_CNT)];
207 unsigned long jack_bits[BITS_TO_LONGS(EXTCON_PROP_JACK_CNT)];
208 unsigned long disp_bits[BITS_TO_LONGS(EXTCON_PROP_DISP_CNT)];
204}; 209};
205 210
206static struct class *extcon_class; 211static struct class *extcon_class;
@@ -297,6 +302,39 @@ static bool is_extcon_property_supported(unsigned int id, unsigned int prop)
297 return !!(extcon_info[id].type & type); 302 return !!(extcon_info[id].type & type);
298} 303}
299 304
305static int is_extcon_property_capability(struct extcon_dev *edev,
306 unsigned int id, int index,unsigned int prop)
307{
308 struct extcon_cable *cable;
309 int type, ret;
310
311 /* Check whether the property is supported or not. */
312 type = get_extcon_type(prop);
313 if (type < 0)
314 return type;
315
316 cable = &edev->cables[index];
317
318 switch (type) {
319 case EXTCON_TYPE_USB:
320 ret = test_bit(prop - EXTCON_PROP_USB_MIN, cable->usb_bits);
321 break;
322 case EXTCON_TYPE_CHG:
323 ret = test_bit(prop - EXTCON_PROP_CHG_MIN, cable->chg_bits);
324 break;
325 case EXTCON_TYPE_JACK:
326 ret = test_bit(prop - EXTCON_PROP_JACK_MIN, cable->jack_bits);
327 break;
328 case EXTCON_TYPE_DISP:
329 ret = test_bit(prop - EXTCON_PROP_DISP_MIN, cable->disp_bits);
330 break;
331 default:
332 ret = -EINVAL;
333 }
334
335 return ret;
336}
337
300static void init_property(struct extcon_dev *edev, unsigned int id, int index) 338static void init_property(struct extcon_dev *edev, unsigned int id, int index)
301{ 339{
302 unsigned int type = extcon_info[id].type; 340 unsigned int type = extcon_info[id].type;
@@ -554,6 +592,12 @@ int extcon_get_property(struct extcon_dev *edev, unsigned int id,
554 592
555 spin_lock_irqsave(&edev->lock, flags); 593 spin_lock_irqsave(&edev->lock, flags);
556 594
595 /* Check whether the property is available or not. */
596 if (!is_extcon_property_capability(edev, id, index, prop)) {
597 spin_unlock_irqrestore(&edev->lock, flags);
598 return -EPERM;
599 }
600
557 /* 601 /*
558 * Check whether the external connector is attached. 602 * Check whether the external connector is attached.
559 * If external connector is detached, the user can not 603 * If external connector is detached, the user can not
@@ -626,6 +670,12 @@ int extcon_set_property(struct extcon_dev *edev, unsigned int id,
626 670
627 spin_lock_irqsave(&edev->lock, flags); 671 spin_lock_irqsave(&edev->lock, flags);
628 672
673 /* Check whether the property is available or not. */
674 if (!is_extcon_property_capability(edev, id, index, prop)) {
675 spin_unlock_irqrestore(&edev->lock, flags);
676 return -EPERM;
677 }
678
629 cable = &edev->cables[index]; 679 cable = &edev->cables[index];
630 680
631 /* Set the property value according to extcon type */ 681 /* Set the property value according to extcon type */
@@ -654,6 +704,96 @@ int extcon_set_property(struct extcon_dev *edev, unsigned int id,
654EXPORT_SYMBOL_GPL(extcon_set_property); 704EXPORT_SYMBOL_GPL(extcon_set_property);
655 705
656/** 706/**
707 * extcon_get_property_capability() - Get the capability of property
708 * of an external connector.
709 * @edev: the extcon device that has the cable.
710 * @id: the unique id of each external connector
711 * in extcon enumeration.
712 * @prop: the property id among enum extcon_property.
713 *
714 * Returns 1 if the property is available or 0 if not available.
715 */
716int extcon_get_property_capability(struct extcon_dev *edev, unsigned int id,
717 unsigned int prop)
718{
719 int index;
720
721 if (!edev)
722 return -EINVAL;
723
724 /* Check whether the property is supported or not */
725 if (!is_extcon_property_supported(id, prop))
726 return -EINVAL;
727
728 /* Find the cable index of external connector by using id */
729 index = find_cable_index_by_id(edev, id);
730 if (index < 0)
731 return index;
732
733 return is_extcon_property_capability(edev, id, index, prop);
734}
735EXPORT_SYMBOL_GPL(extcon_get_property_capability);
736
737/**
738 * extcon_set_property_capability() - Set the capability of a property
739 * of an external connector.
740 * @edev: the extcon device that has the cable.
741 * @id: the unique id of each external connector
742 * in extcon enumeration.
743 * @prop: the property id among enum extcon_property.
744 *
745 * This function set the capability of a property for an external connector
746 * to mark the bit in capability bitmap which mean the available state of
747 * a property.
748 *
749 * Returns 0 if success or error number if fail
750 */
751int extcon_set_property_capability(struct extcon_dev *edev, unsigned int id,
752 unsigned int prop)
753{
754 struct extcon_cable *cable;
755 int index, type, ret = 0;
756
757 if (!edev)
758 return -EINVAL;
759
760 /* Check whether the property is supported or not. */
761 if (!is_extcon_property_supported(id, prop))
762 return -EINVAL;
763
764 /* Find the cable index of external connector by using id. */
765 index = find_cable_index_by_id(edev, id);
766 if (index < 0)
767 return index;
768
769 type = get_extcon_type(prop);
770 if (type < 0)
771 return type;
772
773 cable = &edev->cables[index];
774
775 switch (type) {
776 case EXTCON_TYPE_USB:
777 __set_bit(prop - EXTCON_PROP_USB_MIN, cable->usb_bits);
778 break;
779 case EXTCON_TYPE_CHG:
780 __set_bit(prop - EXTCON_PROP_CHG_MIN, cable->chg_bits);
781 break;
782 case EXTCON_TYPE_JACK:
783 __set_bit(prop - EXTCON_PROP_JACK_MIN, cable->jack_bits);
784 break;
785 case EXTCON_TYPE_DISP:
786 __set_bit(prop - EXTCON_PROP_DISP_MIN, cable->disp_bits);
787 break;
788 default:
789 ret = -EINVAL;
790 }
791
792 return ret;
793}
794EXPORT_SYMBOL_GPL(extcon_set_property_capability);
795
796/**
657 * extcon_get_extcon_dev() - Get the extcon device instance from the name 797 * extcon_get_extcon_dev() - Get the extcon device instance from the name
658 * @extcon_name: The extcon name provided with extcon_dev_register() 798 * @extcon_name: The extcon name provided with extcon_dev_register()
659 */ 799 */