extcon: allow to get/set related data structure for a specific cable

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
index 60adc04..533d10f 100644
--- a/drivers/extcon/extcon-class.c
+++ b/drivers/extcon/extcon-class.c
@@ -545,6 +545,36 @@
 }
 EXPORT_SYMBOL_GPL(extcon_unregister_notifier);
 
+/**
+ * extcon_cable_set_data() - Set the data structure for a cable
+ * @edev:	the extcon device
+ * @cable_index:	the cable index of the correspondant
+ * @type:	type of the data structure
+ * @data:
+ */
+void extcon_cable_set_data(struct extcon_dev *edev, int cable_index,
+			   enum extcon_cable_type type,
+			   union extcon_cable_data data)
+{
+	edev->cables[cable_index].type = type;
+	edev->cables[cable_index].data = data;
+}
+
+/**
+ * extcon_cable_get_data() - Get the data structure for a cable
+ * @edev:	the extcon device
+ * @cable_index:	the cable index of the correspondant
+ * @type:	type of the data structure
+ * @data:	the corresponding data structure (e.g., regulator)
+ */
+void extcon_cable_get_data(struct extcon_dev *edev, int cable_index,
+			   enum extcon_cable_type *type,
+			   union extcon_cable_data *data)
+{
+	*type = edev->cables[cable_index].type;
+	*data = edev->cables[cable_index].data;
+}
+
 static struct device_attribute extcon_attrs[] = {
 	__ATTR(state, S_IRUGO | S_IWUSR, state_show, state_store),
 	__ATTR_RO(name),
diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index fcb51c8..e107d32 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -27,6 +27,11 @@
 #include <linux/notifier.h>
 #include <linux/sysfs.h>
 
+/* For the cable types */
+#include <linux/regulator/consumer.h>
+#include <linux/power_supply.h>
+#include <linux/power/charger-manager.h>
+
 #define SUPPORTED_CABLE_MAX	32
 #define CABLE_NAME_MAX		30
 
@@ -137,6 +142,21 @@
 	struct device_attribute *d_attrs_muex;
 };
 
+enum extcon_cable_type {
+	EXTCON_CT_NONE = 0,
+	EXTCON_CT_REGULATOR,
+	EXTCON_CT_PSY,
+	EXTCON_CT_CHARGER_MANAGER,
+	/* Please add other related standards when needed */
+};
+
+union extcon_cable_data {
+	struct regualtor *reg;	/* EXTCON_CT_REGULATOR */
+	struct power_supply *psy; /* EXTCON_CT_PSY */
+	struct charger_cable *charger; /* EXTCON_CT_CHARGER_MANAGER */
+	/* Please add accordingly with enum extcon_cable_type */
+};
+
 /**
  * struct extcon_cable	- An internal data for each cable of extcon device.
  * @edev:	The extcon device
@@ -145,6 +165,8 @@
  * @attr_name:	"name" sysfs entry
  * @attr_state:	"state" sysfs entry
  * @attrs:	Array pointing to attr_name and attr_state for attr_g
+ * @type:	The type of @data.
+ * @data:	The data structure representing the status and states of this cable.
  */
 struct extcon_cable {
 	struct extcon_dev *edev;
@@ -155,6 +177,9 @@
 	struct device_attribute attr_state;
 
 	struct attribute *attrs[3]; /* to be fed to attr_g.attrs */
+
+	enum extcon_cable_type type;
+	union extcon_cable_data data;
 };
 
 /**
@@ -185,6 +210,17 @@
 extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);
 
 /*
+ * Following APIs are for managing the status and states of each cable.
+ * For example, if a cable is represented as a regulator, then the cable
+ * may have struct regulator as its data.
+ */
+extern void extcon_cable_set_data(struct extcon_dev *edev, int cable_index,
+				  enum extcon_cable_type type,
+				  union extcon_cable_data data);
+extern void extcon_cable_get_data(struct extcon_dev *edev, int cable_index,
+				  enum extcon_cable_type *type,
+				  union extcon_cable_data *data);
+/*
  * get/set/update_state access the 32b encoded state value, which represents
  * states of all possible cables of the multistate port. For example, if one
  * calls extcon_set_state(edev, 0x7), it may mean that all the three cables
@@ -246,6 +282,14 @@
 
 static inline void extcon_dev_unregister(struct extcon_dev *edev) { }
 
+static void extcon_cable_set_data(struct extcon_dev *edev, int cable_index,
+				 enum extcon_cable_type type,
+				 union extcon_cable_data data) { }
+
+static void extcon_cable_get_data(struct extcon_dev *edev, int cable_index,
+				 enum extcon_cable_type *type,
+				 union extcon_cable_data *data) { }
+
 static inline u32 extcon_get_state(struct extcon_dev *edev)
 {
 	return 0;