CONFIG_USB_NOTIFIER=y
CONFIG_USB_HW_PARAM=y
CONFIG_USB_DWC3=y
-CONFIG_DUAL_ROLE_USB_INTF=y
+#CONFIG_DUAL_ROLE_USB_INTF=y
+CONFIG_TYPEC=y
CONFIG_USB_GADGET=y
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_ACM=y
static void s2mu106_snk(struct i2c_client *i2c);
static void s2mu106_assert_rd(void *_data);
static void s2mu106_assert_rp(void *_data);
-static int s2mu106_set_attach(struct s2mu106_usbpd_data *pdic_data, u8 mode);
-static int s2mu106_set_detach(struct s2mu106_usbpd_data *pdic_data, u8 mode);
+static void s2mu106_assert_drp(void *_data);
static void s2mu106_usbpd_check_rid(struct s2mu106_usbpd_data *pdic_data);
static int s2mu106_usbpd_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest);
static int s2mu106_usbpd_write_reg(struct i2c_client *i2c, u8 reg, u8 value);
#endif
static void s2mu106_usbpd_detach_init(struct s2mu106_usbpd_data *pdic_data);
static int s2mu106_usbpd_set_cc_control(struct s2mu106_usbpd_data *pdic_data, int val);
+static void s2mu106_usbpd_set_rp_scr_sel(struct s2mu106_usbpd_data *pdic_data,
+ CCIC_RP_SCR_SEL scr_sel);
char *rid_text[] = {
"UNDEFINED",
s2mu106_usbpd_read_reg(i2c, 0xe2, &data[5]);
s2mu106_usbpd_read_reg(i2c, 0xb3, &data[6]);
s2mu106_usbpd_read_reg(i2c, 0xb4, &data[7]);
+ s2mu106_usbpd_read_reg(i2c, 0xf7, &data[8]);
- pr_info("%s, 0x1(%x) 0x18(%x) 0x27(%x) 0x28(%x) 0x40(%x) 0xe2(%x) 0xb3(%x) 0xb4(%x)\n",
- __func__, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
+ pr_info("%s, 0x1(%x) 0x18(%x) 0x27(%x) 0x28(%x) 0x40(%x) 0xe2(%x) 0xb3(%x) 0xb4(%x) 0xf7(%X)\n",
+ __func__, data[0], data[1], data[2], data[3], data[4],
+ data[5], data[6], data[7], data[8]);
}
void s2mu106_rprd_mode_change(struct s2mu106_usbpd_data *usbpd_data, u8 mode)
{
u8 data = 0;
struct i2c_client *i2c = usbpd_data->i2c;
+ struct device *dev = &i2c->dev;
+ struct usbpd_data *pd_data = dev_get_drvdata(dev);
pr_info("%s, mode=0x%x\n", __func__, mode);
mutex_lock(&usbpd_data->lpm_mutex);
switch (mode) {
case TYPE_C_ATTACH_DFP: /* SRC */
- s2mu106_set_detach(usbpd_data, mode);
+ s2mu106_usbpd_set_cc_control(usbpd_data, USBPD_CC_OFF);
+ usbpd_data->status_reg |= PLUG_DETACH;
+ s2mu106_usbpd_set_rp_scr_sel(usbpd_data, PLUG_CTRL_RP0);
+ s2mu106_assert_rp(pd_data);
+ msleep(50);
+ s2mu106_usbpd_set_rp_scr_sel(usbpd_data, PLUG_CTRL_RP80);
msleep(S2MU106_ROLE_SWAP_TIME_MS);
- s2mu106_set_attach(usbpd_data, mode);
+ s2mu106_assert_drp(pd_data);
break;
case TYPE_C_ATTACH_UFP: /* SNK */
- s2mu106_set_detach(usbpd_data, mode);
+ ifconn_event_work(usbpd_data, IFCONN_NOTIFY_MUIC,
+ IFCONN_NOTIFY_ID_ROLE_SWAP,
+ IFCONN_NOTIFY_EVENT_USB_ATTACH_UFP, NULL);
+ s2mu106_usbpd_set_cc_control(usbpd_data, USBPD_CC_OFF);
+ usbpd_data->status_reg |= PLUG_DETACH;
+ s2mu106_assert_rp(pd_data);
+ s2mu106_usbpd_set_rp_scr_sel(usbpd_data, PLUG_CTRL_RP0);
+ msleep(50);
+ s2mu106_assert_rd(pd_data);
+ s2mu106_usbpd_set_rp_scr_sel(usbpd_data, PLUG_CTRL_RP80);
msleep(S2MU106_ROLE_SWAP_TIME_MS);
- s2mu106_set_attach(usbpd_data, mode);
+ s2mu106_assert_drp(pd_data);
break;
case TYPE_C_ATTACH_DRP: /* DRP */
s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
mutex_unlock(&usbpd_data->lpm_mutex);
}
+void usbpd_charger_test_read(struct s2mu106_usbpd_data *usbpd_data)
+{
+ struct power_supply *psy_charger;
+ union power_supply_propval val;
+ int ret = 0;
+
+ psy_charger = power_supply_get_by_name("s2mu106-charger");
+
+ if (psy_charger) {
+ ret = psy_charger->desc->set_property(psy_charger,
+ POWER_SUPPLY_PROP_USBPD_TEST_READ, &val);
+ } else {
+ pr_err("%s: Fail to get psy battery\n", __func__);
+
+ return;
+ }
+}
+
void vbus_turn_on_ctrl(struct s2mu106_usbpd_data *usbpd_data, bool enable)
{
struct power_supply *psy_otg;
union power_supply_propval val;
int ret = 0;
- if (psy_pm) {
+ if (psy_pm)
ret = psy_pm->desc->get_property(psy_pm, POWER_SUPPLY_PROP_VCHGIN, &val);
- } else {
+ else {
pr_err("%s: Fail to get pmeter\n", __func__);
return -1;
}
return 0;
}
+static int s2mu106_usbpd_get_pmeter_current(struct s2mu106_usbpd_data *pdic_data)
+{
+
+ struct power_supply *psy_pm = pdic_data->psy_pm;
+ union power_supply_propval val;
+ int ret = 0;
+
+ if (psy_pm)
+ psy_pm->desc->get_property(psy_pm, POWER_SUPPLY_PROP_ICHGIN, &val);
+ else {
+ pr_err("%s: Fail to get pmeter\n", __func__);
+ return -1;
+ }
+
+ if (ret) {
+ pr_err("%s: fail to set power_suppy pmeter property(%d)\n",
+ __func__, ret);
+ return -1;
+ }
+
+ pdic_data->pm_chgin_i = val.intval;
+
+ return 0;
+}
+
static int s2mu106_usbpd_check_vbus(struct s2mu106_usbpd_data *pdic_data,
int volt, CCIC_VBUS_SEL mode)
{
else if (val == USBPD_SOURCE_ON) {
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
pdic_data->power_role_dual = DUAL_ROLE_PROP_PR_SRC;
+#elif defined(CONFIG_TYPEC)
+ pdic_data->typec_power_role = TYPEC_SOURCE;
+ typec_set_pwr_role(pdic_data->port, pdic_data->typec_power_role);
+#endif
ifconn_event_work(pdic_data, IFCONN_NOTIFY_MUIC,
IFCONN_NOTIFY_ID_ROLE_SWAP, 1/* source */, 0);
-#endif
} else if (val == USBPD_SOURCE_OFF) {
ifconn_event_work(pdic_data, IFCONN_NOTIFY_BATTERY,
IFCONN_NOTIFY_ID_DETACH, 0, 0);
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
pdic_data->power_role_dual = DUAL_ROLE_PROP_PR_SNK;
+#elif defined(CONFIG_TYPEC)
+ pdic_data->typec_power_role = TYPEC_SINK;
+ typec_set_pwr_role(pdic_data->port, pdic_data->typec_power_role);
+#endif
ifconn_event_work(pdic_data, IFCONN_NOTIFY_MUIC,
IFCONN_NOTIFY_ID_ROLE_SWAP, 0/* sink */, 0);
-#endif
}
}
u64 status_reg_val = 0;
msg_header_type header;
int data_obj_num = 0;
- int msg_id = 0;
ret = s2mu106_usbpd_bulk_read(i2c, S2MU106_REG_INT_STATUS0,
S2MU106_MAX_NUM_INT_STATUS, intr);
if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_DR_SWAP)
status_reg_val |= MSG_DR_SWAP;
+ if (intr[0] & S2MU106_REG_INT_STATUS0_MSG_ACCEPT)
+ status_reg_val |= MSG_ACCEPT;
+
/* function that support dp control */
if (intr[4] & S2MU106_REG_INT_STATUS4_MSG_PASS) {
if (intr[3] & S2MU106_REG_INT_STATUS3_UNS_CMD_DATA)
status_reg_val |= MSG_RID;
else {
usbpd_protocol_rx(data);
+ if (data->msg_received == 0)
+ goto out;
+
header = data->protocol_rx.msg_header;
data_obj_num = header.num_data_objs;
- msg_id = header.msg_id;
- pr_info("%s, prev msg_id =(%d), received msg_id =(%d)\n", __func__,
- data->msg_id, msg_id);
-
- if (msg_id == data->msg_id)
- goto out;
- else
- data->msg_id = msg_id;
if (data_obj_num > 0)
s2mu106_usbpd_check_msg(data, &status_reg_val);
- if (intr[0] & S2MU106_REG_INT_STATUS0_MSG_ACCEPT)
- status_reg_val |= MSG_ACCEPT;
-
if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_PSRDY)
status_reg_val |= MSG_PSRDY;
u8 data = 0;
pr_info("%s: scr_sel : (%d)\n", __func__, scr_sel);
switch (scr_sel) {
+ case PLUG_CTRL_RP0:
+ s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
+ data &= ~S2MU106_REG_PLUG_CTRL_RP_SEL_MASK;
+ data |= S2MU106_REG_PLUG_CTRL_RP0;
+ s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, data);
+ break;
case PLUG_CTRL_RP80:
s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
data &= ~S2MU106_REG_PLUG_CTRL_RP_SEL_MASK;
}
}
-static int s2mu106_set_attach(struct s2mu106_usbpd_data *pdic_data, u8 mode)
-{
- u8 data;
- int ret = 0;
- struct i2c_client *i2c = pdic_data->i2c;
- struct device *dev = &i2c->dev;
-
- s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
- data &= ~(S2MU106_REG_PLUG_CTRL_MODE_MASK | S2MU106_REG_PLUG_CTRL_RP_SEL_MASK);
- data |= mode | S2MU106_REG_PLUG_CTRL_RP180;
- s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, data);
-
- s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PD_CTRL, &data);
- data &= ~S2MU106_REG_LPM_EN;
- s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PD_CTRL, data);
-
- dev_info(dev, "%s s2mu106 force to attach\n", __func__);
-
- return ret;
-}
-
-static int s2mu106_set_detach(struct s2mu106_usbpd_data *pdic_data, u8 mode)
-{
- u8 data;
- int ret = 0;
- struct i2c_client *i2c = pdic_data->i2c;
- struct device *dev = &i2c->dev;
-
- if (mode == TYPE_C_ATTACH_DFP) {
- s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_RpRd, &data);
- data |= S2MU106_REG_PLUG_CTRL_RpRd_Rp_Source_Mode;
- s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_RpRd, data);
- } else if (mode == TYPE_C_ATTACH_UFP) {
- s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_RpRd, &data);
- data |= S2MU106_REG_PLUG_CTRL_RpRd_Rd_Sink_Mode;
- s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_RpRd, data);
- }
-
- msleep(50);
-
- s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_RpRd, S2MU106_RESET_REG_00);
- s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
- data &= ~(S2MU106_REG_PLUG_CTRL_MODE_MASK | S2MU106_REG_PLUG_CTRL_RP_SEL_MASK);
- data |= S2MU106_REG_PLUG_CTRL_DFP | S2MU106_REG_PLUG_CTRL_RP0;
- s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, data);
-
- s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PD_CTRL, &data);
- data |= S2MU106_REG_LPM_EN;
- s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PD_CTRL, data);
-
- dev_info(dev, "%s s2mu106 force to detach\n", __func__);
-
- return ret;
-}
-
int s2mu106_set_normal_mode(struct s2mu106_usbpd_data *pdic_data)
{
u8 data;
pdic_data->is_host = HOST_ON;
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
pdic_data->power_role_dual = DUAL_ROLE_PROP_PR_SRC;
+#elif defined(CONFIG_TYPEC)
+ pdic_data->typec_power_role = TYPEC_SOURCE;
+ typec_set_pwr_role(pdic_data->port, pdic_data->typec_power_role);
#endif
#if defined(CONFIG_IFCONN_NOTIFIER)
/* USB */
s2mu106_usbpd_read_reg(i2c, S2MU106_REG_INT_STATUS2, &val);
if (val & S2MU106_REG_INT_STATUS2_WAKEUP)
pr_info("%s auto wakeup success\n", __func__);
+ else {
+ msleep(22);
+ s2mu106_usbpd_set_vbus_wakeup(pdic_data, VBUS_WAKEUP_DISABLE);
+ usleep_range(1000, 1200);
+ s2mu106_usbpd_set_vbus_wakeup(pdic_data, VBUS_WAKEUP_ENABLE);
+ usleep_range(1000, 1200);
+ s2mu106_usbpd_read_reg(i2c, S2MU106_REG_INT_STATUS2, &val);
+ if (val & S2MU106_REG_INT_STATUS2_WAKEUP)
+ pr_info("%s auto wakeup success\n", __func__);
else
s2mu106_usbpd_set_mode(pdic_data, PD_NORMAL_MODE);
+ }
+
s2mu106_set_irq_enable(pdic_data, ENABLED_INT_0, ENABLED_INT_1,
ENABLED_INT_2, ENABLED_INT_3, ENABLED_INT_4,
ENABLED_INT_5);
if (pdic_data->power_role_dual == DUAL_ROLE_PROP_PR_SRC) {
vbus_turn_on_ctrl(pdic_data, VBUS_OFF);
}
+#elif defined(CONFIG_TYPEC)
+ if (pdic_data->typec_power_role == TYPEC_SOURCE) {
+ vbus_turn_on_ctrl(pdic_data, VBUS_OFF);
+ }
#endif
pdic_data->detach_valid = true;
mutex_unlock(&pdic_data->cc_mutex);
pdic_data->is_client = CLIENT_OFF;
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
pdic_data->power_role_dual = DUAL_ROLE_PROP_PR_NONE;
+#elif defined(CONFIG_TYPEC)
+ pdic_data->typec_power_role = TYPEC_SINK;
+ typec_set_pwr_role(pdic_data->port, TYPEC_SINK);
+ pdic_data->typec_data_role = TYPEC_DEVICE;
+ typec_set_data_role(pdic_data->port, TYPEC_DEVICE);
#endif
/* USB */
ifconn_event_work(pdic_data, IFCONN_NOTIFY_USB, IFCONN_NOTIFY_ID_USB,
IFCONN_NOTIFY_ID_ATTACH, IFCONN_NOTIFY_EVENT_DETACH, NULL);
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
pdic_data->power_role_dual = DUAL_ROLE_PROP_PR_NONE;
+#elif defined(CONFIG_TYPEC)
+ pdic_data->typec_power_role = TYPEC_SINK;
+ typec_set_pwr_role(pdic_data->port, pdic_data->typec_power_role);
#endif
/* add to turn off external 5V */
vbus_turn_on_ctrl(pdic_data, VBUS_OFF);
IFCONN_NOTIFY_ID_ATTACH, IFCONN_NOTIFY_EVENT_DETACH, NULL);
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
pdic_data->power_role_dual = DUAL_ROLE_PROP_PR_NONE;
+#elif defined(CONFIG_TYPEC)
+ pdic_data->typec_power_role = TYPEC_SINK;
+ typec_set_pwr_role(pdic_data->port, pdic_data->typec_power_role);
#endif
ifconn_event_work(pdic_data, IFCONN_NOTIFY_USB,
IFCONN_NOTIFY_ID_USB, IFCONN_NOTIFY_EVENT_DETACH, NULL);
pdic_data->is_client = CLIENT_ON;
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
pdic_data->power_role_dual = DUAL_ROLE_PROP_PR_SNK;
+#elif defined(CONFIG_TYPEC)
+ pdic_data->typec_power_role = TYPEC_SINK;
+ typec_set_pwr_role(pdic_data->port, pdic_data->typec_power_role);
#endif
ifconn_event_work(pdic_data,
IFCONN_NOTIFY_USB, IFCONN_NOTIFY_ID_USB,
attach_status = s2mu106_get_status(pd_data, PLUG_ATTACH);
rid_status = s2mu106_get_status(pd_data, MSG_RID);
s2mu106_usbpd_detach_init(pdic_data);
+ s2mu106_usbpd_notify_detach(pdic_data);
if (attach_status) {
ret = s2mu106_check_port_detect(pdic_data);
if (ret >= 0) {
goto hard_reset;
}
}
- s2mu106_usbpd_notify_detach(pdic_data);
+#if 0
mutex_lock(&pdic_data->lpm_mutex);
if (!pdic_data->lpm_mode) {
if (s2mu106_usbpd_lpm_check(pdic_data) > 0) {
ENABLED_INT_2, ENABLED_INT_3, ENABLED_INT_4, ENABLED_INT_5);
}
mutex_unlock(&pdic_data->lpm_mutex);
+#endif
goto out;
}
static void s2mu106_usbpd_init_configure(struct s2mu106_usbpd_data *_data)
{
+ s2mu106_usbpd_test_read(_data);
+ s2mu106_usbpd_get_pmeter_volt(_data);
+ s2mu106_usbpd_get_pmeter_current(_data);
+ pr_info("%s, chgin(%d), chgin_i(%d)\n", __func__,
+ _data->pm_chgin, _data->pm_chgin_i);
+ usbpd_charger_test_read(_data);
s2mu106_set_normal_mode(_data);
+ pr_info("%s, usbpd irq gpio value(%d)\n", __func__,
+ gpio_get_value(_data->irq_gpio));
msleep(25);
_data->detach_valid = true;
s2mu106_set_lpm_mode(_data);
_data->lpcharge_water = false;
#endif
_data->check_rid_wa = false;
+#if defined(CONFIG_TYPEC)
+ _data->typec_power_role = TYPEC_SINK;
+ _data->typec_data_role = TYPEC_DEVICE;
+#endif
}
static int of_s2mu106_dt(struct device *dev,
_data->irq_gpio);
_data->irq_gpio = 0;
}
+ ret = gpio_get_value(_data->irq_gpio);
+ pr_info("%s, usbpd irq gpio value(%d)\n", __func__, ret);
if (of_find_property(np_usbpd, "vconn-en", NULL))
_data->vconn_en = true;
else
mutex_init(&pdic_data->cc_mutex);
wake_lock_init(&pdic_data->wake_lock, WAKE_LOCK_SUSPEND, "pdic_wake");
+#ifdef CONFIG_PM_S2MU106
+ pdic_data->psy_pm = power_supply_get_by_name("s2mu106_pmeter");
+ if (!pdic_data->psy_pm)
+ pr_err("%s: Fail to get pmeter\n", __func__);
+ s2mu106_usbpd_set_pmeter_mode(pdic_data, PM_TYPE_VCHGIN);
+ s2mu106_usbpd_set_pmeter_mode(pdic_data, PM_TYPE_ICHGIN);
+#endif
+
s2mu106_usbpd_init_configure(pdic_data);
s2mu106_usbpd_pdic_data_init(pdic_data);
usbpd_set_ops(dev, &s2mu106_ops);
-#ifdef CONFIG_PM_S2MU106
- pdic_data->psy_pm = power_supply_get_by_name("s2mu106_pmeter");
- if (!pdic_data->psy_pm)
- pr_err("%s: Fail to get pmeter\n", __func__);
-#endif
s2mu106_usbpd_reg_init(pdic_data);
pdic_data->pdic_queue =
#endif
if (pdic_data->rid == REG_RID_UNDF)
pdic_data->rid = REG_RID_MAX;
+#if defined(CONFIG_TYPEC)
+ ret = typec_init(pdic_data);
+ if (ret < 0) {
+ pr_err("failed to init typec\n");
+ goto err_return;
+ }
+#endif
ret = s2mu106_usbpd_irq_init(pdic_data);
if (ret) {
devm_dual_role_instance_unregister(_data->dev,
_data->dual_role);
devm_kfree(_data->dev, _data->desc);
+#elif defined(CONFIG_TYPEC)
+ typec_unregister_port(_data->port);
#endif
disable_irq_wake(_data->i2c->irq);
free_irq(_data->i2c->irq, _data);
dev_err(pd_data->dev, "[Rx] Got SOFTRESET.\n");
state = PRL_Rx_Layer_Reset_for_Receive;
} else {
+ pr_info("%s, prev msg_id =(%d), received msg_id =(%d)\n", __func__,
+ rx->stored_message_id, rx->msg_header.msg_id);
if (rx->stored_message_id == rx->msg_header.msg_id) {
pd_data->id_matched = 0;
return state;
#include <linux/completion.h>
#include <linux/usb_notify.h>
-#if (defined CONFIG_CCIC_NOTIFIER || defined CONFIG_DUAL_ROLE_USB_INTF \
- || defined CONFIG_IFCONN_NOTIFIER)
+#if (defined CONFIG_CCIC_NOTIFIER || defined CONFIG_DUAL_ROLE_USB_INTF)
+#include <linux/ccic/usbpd_ext.h>
+#elif defined(CONFIG_TYPEC)
#include <linux/ccic/usbpd_ext.h>
-#endif
-#if defined CONFIG_IFCONN_NOTIFIER
-#include <linux/ifconn/ifconn_notifier.h>
#endif
#include <linux/ccic/usbpd.h>
+
+#if defined CONFIG_CCIC_S2MU004
+#include <linux/ccic/usbpd-s2mu004.h>
+#elif defined CONFIG_CCIC_S2MU106
#include <linux/ccic/usbpd-s2mu106.h>
+#elif defined CONFIG_CCIC_S2MU205
+#include <linux/ccic/usbpd-s2mu205.h>
+#endif
#if defined(CONFIG_CCIC_NOTIFIER)
static void ccic_event_notifier(struct work_struct *data)
event_work);
break;
}
+
ccic_noti.src = CCIC_NOTIFY_DEV_CCIC;
ccic_noti.dest = event_work->dest;
ccic_noti.id = event_work->id;
extern void ccic_event_work(void *data, int dest, int id, int attach, int event)
{
+#if defined CONFIG_CCIC_S2MU004
+ struct s2mu004_usbpd_data *usbpd_data = data;
+#elif defined CONFIG_CCIC_S2MU106
struct s2mu106_usbpd_data *usbpd_data = data;
+#elif defined CONFIG_CCIC_S2MU205
+ struct s2mu205_usbpd_data *usbpd_data = data;
+#endif
struct ccic_state_work *event_work;
-
+#if defined(CONFIG_TYPEC)
+ struct typec_partner_desc desc;
+ enum typec_pwr_opmode mode;
+#endif
event_work = kmalloc(sizeof(struct ccic_state_work), GFP_ATOMIC);
pr_info("usb: %s,event_work(%p)\n", __func__, event_work);
dual_role_instance_changed(usbpd_data->dual_role);
if (usbpd_data->try_state_change &&
- (usbpd_data->data_role_dual != IFCONN_NOTIFY_EVENT_DETACH)) {
+ (usbpd_data->data_role_dual != USB_STATUS_NOTIFY_DETACH)) {
/* Role change try and new mode detected */
pr_info("usb: %s, reverse_completion\n", __func__);
complete(&usbpd_data->reverse_completion);
}
}
+#elif defined(CONFIG_TYPEC)
+ if (id == CCIC_NOTIFY_ID_USB) {
+ if (usbpd_data->typec_try_state_change &&
+ (event != USB_STATUS_NOTIFY_DETACH)) {
+ // Role change try and new mode detected
+ pr_info("usb: %s, role_reverse_completion\n", __func__);
+ complete(&usbpd_data->role_reverse_completion);
+ }
+
+ if (event == USB_STATUS_NOTIFY_ATTACH_UFP) {
+ mode = typec_get_pd_support(usbpd_data);
+ typec_set_pwr_opmode(usbpd_data->port, mode);
+ desc.usb_pd = mode == TYPEC_PWR_MODE_PD;
+ desc.accessory = TYPEC_ACCESSORY_NONE; /* XXX: handle accessories */
+ desc.identity = NULL;
+ usbpd_data->typec_data_role = TYPEC_DEVICE;
+ typec_set_data_role(usbpd_data->port, TYPEC_DEVICE);
+ usbpd_data->partner = typec_register_partner(usbpd_data->port, &desc);
+ } else if (event == USB_STATUS_NOTIFY_ATTACH_DFP) {
+ mode = typec_get_pd_support(usbpd_data);
+ typec_set_pwr_opmode(usbpd_data->port, mode);
+ desc.usb_pd = mode == TYPEC_PWR_MODE_PD;
+ desc.accessory = TYPEC_ACCESSORY_NONE; /* XXX: handle accessories */
+ desc.identity = NULL;
+ usbpd_data->typec_data_role = TYPEC_HOST;
+ typec_set_data_role(usbpd_data->port, TYPEC_HOST);
+ usbpd_data->partner = typec_register_partner(usbpd_data->port, &desc);
+ } else {
+ if (!IS_ERR(usbpd_data->partner))
+ typec_unregister_partner(usbpd_data->partner);
+ usbpd_data->partner = NULL;
+ }
+ }
#endif
if (queue_work(usbpd_data->ccic_wq, &event_work->ccic_work) == 0) {
{
struct s2mu106_usbpd_data *usbpd_data = pd_data;
struct ifconn_state_work *event_work;
-
+#if defined(CONFIG_TYPEC)
+ struct typec_partner_desc desc;
+ enum typec_pwr_opmode mode;
+#endif
event_work = kmalloc(sizeof(struct ifconn_state_work), GFP_ATOMIC);
INIT_WORK(&event_work->ifconn_work, ifconn_event_notifier);
complete(&usbpd_data->reverse_completion);
}
}
+#elif defined(CONFIG_TYPEC)
+ if (id == IFCONN_NOTIFY_ID_USB) {
+ if (usbpd_data->typec_try_state_change &&
+ (event != IFCONN_NOTIFY_EVENT_DETACH)) {
+ // Role change try and new mode detected
+ pr_info("usb: %s, role_reverse_completion\n", __func__);
+ complete(&usbpd_data->role_reverse_completion);
+ }
+
+ if (event == IFCONN_NOTIFY_EVENT_USB_ATTACH_UFP) {
+ pr_info("usb: %s, line : %d\n", __func__, __LINE__);
+ mode = typec_get_pd_support(usbpd_data);
+ typec_set_pwr_opmode(usbpd_data->port, mode);
+ desc.usb_pd = mode == TYPEC_PWR_MODE_PD;
+ desc.accessory = TYPEC_ACCESSORY_NONE; /* XXX: handle accessories */
+ desc.identity = NULL;
+ usbpd_data->typec_data_role = TYPEC_DEVICE;
+ typec_set_data_role(usbpd_data->port, TYPEC_DEVICE);
+ usbpd_data->partner = typec_register_partner(usbpd_data->port, &desc);
+ } else if (event == IFCONN_NOTIFY_EVENT_USB_ATTACH_DFP) {
+ pr_info("usb: %s, line : %d\n", __func__, __LINE__);
+ mode = typec_get_pd_support(usbpd_data);
+ typec_set_pwr_opmode(usbpd_data->port, mode);
+ desc.usb_pd = mode == TYPEC_PWR_MODE_PD;
+ desc.accessory = TYPEC_ACCESSORY_NONE; /* XXX: handle accessories */
+ desc.identity = NULL;
+ usbpd_data->typec_data_role = TYPEC_HOST;
+ typec_set_data_role(usbpd_data->port, TYPEC_HOST);
+ usbpd_data->partner = typec_register_partner(usbpd_data->port, &desc);
+ } else {
+ pr_info("usb: %s, line : %d\n", __func__, __LINE__);
+ if (!IS_ERR(usbpd_data->partner))
+ typec_unregister_partner(usbpd_data->partner);
+ usbpd_data->partner = NULL;
+ }
+ pr_info("usb: %s, line : %d\n", __func__, __LINE__);
+ }
+ pr_info("usb: %s, line : %d\n", __func__, __LINE__);
#endif
if (queue_work(usbpd_data->ifconn_wq, &event_work->ifconn_work) == 0) {
{
struct delayed_work *delay_work =
container_of(wk, struct delayed_work, work);
+#if defined CONFIG_CCIC_S2MU004
+ struct s2mu004_usbpd_data *usbpd_data =
+ container_of(delay_work, struct s2mu004_usbpd_data, role_swap_work);
+#elif defined CONFIG_CCIC_S2MU106
struct s2mu106_usbpd_data *usbpd_data =
container_of(delay_work, struct s2mu106_usbpd_data, role_swap_work);
+#elif defined CONFIG_CCIC_S2MU205
+ struct s2mu205_usbpd_data *usbpd_data =
+ container_of(delay_work, struct s2mu205_usbpd_data, role_swap_work);
+#endif
int mode = 0;
pr_info("%s: ccic_set_dual_role check again.\n", __func__);
disable_irq(usbpd_data->irq);
/* exit from Disabled state and set mode to DRP */
mode = TYPE_C_ATTACH_DRP;
+#if defined CONFIG_CCIC_S2MU004
+ s2mu004_rprd_mode_change(usbpd_data, mode);
+#elif defined CONFIG_CCIC_S2MU106
s2mu106_rprd_mode_change(usbpd_data, mode);
+#elif defined CONFIG_CCIC_S2MU205
+ s2mu205_rprd_mode_change(usbpd_data, mode);
+#endif
enable_irq(usbpd_data->irq);
}
}
enum dual_role_property prop,
const unsigned int *val)
{
+#if defined CONFIG_CCIC_S2MU004
+ struct s2mu004_usbpd_data *usbpd_data = dual_role_get_drvdata(dual_role);
+#elif defined CONFIG_CCIC_S2MU106
struct s2mu106_usbpd_data *usbpd_data = dual_role_get_drvdata(dual_role);
+#elif defined CONFIG_CCIC_S2MU205
+ struct s2mu205_usbpd_data *usbpd_data = dual_role_get_drvdata(dual_role);
+#endif
struct i2c_client *i2c;
- ifconn_notifier_event_t attached_state;
+ USB_STATUS attached_state;
int mode;
int timeout = 0;
int ret = 0;
attached_state = usbpd_data->data_role_dual;
pr_info("%s : request prop = %d , attached_state = %d\n", __func__, prop, attached_state);
- if (attached_state != IFCONN_NOTIFY_EVENT_USB_ATTACH_DFP
- && attached_state != IFCONN_NOTIFY_EVENT_USB_ATTACH_UFP) {
+ if (attached_state != USB_STATUS_NOTIFY_ATTACH_DFP
+ && attached_state != USB_STATUS_NOTIFY_ATTACH_UFP) {
pr_err("%s : current mode : %d - just return \n", __func__, attached_state);
return 0;
}
- if (attached_state == IFCONN_NOTIFY_EVENT_USB_ATTACH_DFP
+ if (attached_state == USB_STATUS_NOTIFY_ATTACH_DFP
&& *val == DUAL_ROLE_PROP_MODE_DFP) {
pr_err("%s : current mode : %d - request mode : %d just return \n",
__func__, attached_state, *val);
return 0;
}
- if (attached_state == IFCONN_NOTIFY_EVENT_USB_ATTACH_UFP
+ if (attached_state == USB_STATUS_NOTIFY_ATTACH_UFP
&& *val == DUAL_ROLE_PROP_MODE_UFP) {
pr_err("%s : current mode : %d - request mode : %d just return \n",
__func__, attached_state, *val);
return 0;
}
- if (attached_state == IFCONN_NOTIFY_EVENT_USB_ATTACH_DFP) {
+ if (attached_state == USB_STATUS_NOTIFY_ATTACH_DFP) {
/* Current mode DFP and Source */
pr_info("%s: try reversing, from Source to Sink\n", __func__);
/* turns off VBUS first */
vbus_turn_on_ctrl(usbpd_data, 0);
-#if defined(CONFIG_IFCONN_NOTIFIER)
+#if defined(CONFIG_MUIC_SUPPORT_CCIC_OTG_CTRL)
+ muic_disable_otg_detect();
+#endif
+#if defined(CONFIG_CCIC_NOTIFIER)
/* muic */
- ifconn_event_work(usbpd_data, IFCONN_NOTIFY_MUIC,
- IFCONN_NOTIFY_ID_ATTACH, IFCONN_NOTIFY_EVENT_DETACH, NULL);
+ ccic_event_work(usbpd_data,
+ CCIC_NOTIFY_DEV_MUIC, CCIC_NOTIFY_ID_ATTACH, 0/*attach*/, 0/*rprd*/);
#endif
/* exit from Disabled state and set mode to UFP */
mode = TYPE_C_ATTACH_UFP;
usbpd_data->try_state_change = TYPE_C_ATTACH_UFP;
+#if defined CONFIG_CCIC_S2MU004
+ s2mu004_rprd_mode_change(usbpd_data, mode);
+#elif defined CONFIG_CCIC_S2MU106
s2mu106_rprd_mode_change(usbpd_data, mode);
+#elif defined CONFIG_CCIC_S2MU205
+ s2mu205_rprd_mode_change(usbpd_data, mode);
+#endif
} else {
/* Current mode UFP and Sink */
pr_info("%s: try reversing, from Sink to Source\n", __func__);
/* exit from Disabled state and set mode to UFP */
mode = TYPE_C_ATTACH_DFP;
usbpd_data->try_state_change = TYPE_C_ATTACH_DFP;
+#if defined CONFIG_CCIC_S2MU004
+ s2mu004_rprd_mode_change(usbpd_data, mode);
+#elif defined CONFIG_CCIC_S2MU106
s2mu106_rprd_mode_change(usbpd_data, mode);
+#elif defined CONFIG_CCIC_S2MU205
+ s2mu205_rprd_mode_change(usbpd_data, mode);
+#endif
}
reinit_completion(&usbpd_data->reverse_completion);
disable_irq(usbpd_data->irq);
/* exit from Disabled state and set mode to DRP */
mode = TYPE_C_ATTACH_DRP;
+#if defined CONFIG_CCIC_S2MU004
+ s2mu004_rprd_mode_change(usbpd_data, mode);
+#elif defined CONFIG_CCIC_S2MU106
s2mu106_rprd_mode_change(usbpd_data, mode);
+#elif defined CONFIG_CCIC_S2MU205
+ s2mu205_rprd_mode_change(usbpd_data, mode);
+#endif
enable_irq(usbpd_data->irq);
ret = -EIO;
} else {
enum dual_role_property prop,
unsigned int *val)
{
+#if defined CONFIG_CCIC_S2MU004
+ struct s2mu004_usbpd_data *usbpd_data = dual_role_get_drvdata(dual_role);
+#elif defined CONFIG_CCIC_S2MU106
struct s2mu106_usbpd_data *usbpd_data = dual_role_get_drvdata(dual_role);
+#elif defined CONFIG_CCIC_S2MU205
+ struct s2mu205_usbpd_data *usbpd_data = dual_role_get_drvdata(dual_role);
+#endif
- ifconn_notifier_event_t attached_state;
+ USB_STATUS attached_state;
int power_role_dual;
if (!usbpd_data) {
return 0;
}
- if (attached_state == IFCONN_NOTIFY_EVENT_USB_ATTACH_DFP) {
+ if (attached_state == USB_STATUS_NOTIFY_ATTACH_DFP) {
if (prop == DUAL_ROLE_PROP_MODE)
*val = DUAL_ROLE_PROP_MODE_DFP;
else if (prop == DUAL_ROLE_PROP_PR)
*val = DUAL_ROLE_PROP_DR_HOST;
else
return -EINVAL;
- } else if (attached_state == IFCONN_NOTIFY_EVENT_USB_ATTACH_UFP) {
+ } else if (attached_state == USB_STATUS_NOTIFY_ATTACH_UFP) {
if (prop == DUAL_ROLE_PROP_MODE)
*val = DUAL_ROLE_PROP_MODE_UFP;
else if (prop == DUAL_ROLE_PROP_PR)
int dual_role_init(void *_data)
{
+#if defined CONFIG_CCIC_S2MU004
+ struct s2mu004_usbpd_data *pdic_data = _data;
+#elif defined CONFIG_CCIC_S2MU106
struct s2mu106_usbpd_data *pdic_data = _data;
+#elif defined CONFIG_CCIC_S2MU205
+ struct s2mu205_usbpd_data *pdic_data = _data;
+#endif
struct dual_role_phy_desc *desc;
struct dual_role_phy_instance *dual_role;
return 0;
}
+#elif defined(CONFIG_TYPEC)
+void typec_role_swap_check(struct work_struct *wk)
+{
+ struct delayed_work *delay_work =
+ container_of(wk, struct delayed_work, work);
+#if defined CONFIG_CCIC_S2MU004
+ struct s2mu004_usbpd_data *usbpd_data =
+ container_of(delay_work, struct s2mu004_usbpd_data, typec_role_swap_work);
+#elif defined CONFIG_CCIC_S2MU106
+ struct s2mu106_usbpd_data *usbpd_data =
+ container_of(delay_work, struct s2mu106_usbpd_data, typec_role_swap_work);
+#elif defined CONFIG_CCIC_S2MU205
+ struct s2mu205_usbpd_data *usbpd_data =
+ container_of(delay_work, struct s2mu205_usbpd_data, typec_role_swap_work);
+#endif
+
+ pr_info("%s: ccic_set_dual_role check again.\n", __func__);
+ usbpd_data->typec_try_state_change = 0;
+
+ if (usbpd_data->detach_valid) { /* modify here using pd_state */
+ pr_err("%s: ccic_set_dual_role reverse failed, set mode to DRP\n", __func__);
+ disable_irq(usbpd_data->irq);
+ /* exit from Disabled state and set mode to DRP */
+#if defined CONFIG_CCIC_S2MU004
+ s2mu004_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_DRP);
+#elif defined CONFIG_CCIC_S2MU106
+ s2mu106_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_DRP);
+#elif defined CONFIG_CCIC_S2MU205
+ s2mu205_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_DRP);
+#endif
+ enable_irq(usbpd_data->irq);
+ }
+}
+
+int typec_port_type_set(const struct typec_capability *cap, enum typec_port_type port_type)
+{
+#if defined CONFIG_CCIC_S2MU004
+ struct s2mu004_usbpd_data *usbpd_data = container_of(cap, struct s2mu004_usbpd_data, typec_cap);
+#elif defined CONFIG_CCIC_S2MU106
+ struct s2mu106_usbpd_data *usbpd_data = container_of(cap, struct s2mu106_usbpd_data, typec_cap);
+#elif defined CONFIG_CCIC_S2MU205
+ struct s2mu205_usbpd_data *usbpd_data = container_of(cap, struct s2mu205_usbpd_data, typec_cap);
+#endif
+
+ int timeout = 0;
+
+ if (!usbpd_data) {
+ pr_err("%s : usbpd_data is null\n", __func__);
+ return -EINVAL;
+ }
+
+ pr_info("%s : typec_power_role=%d, typec_data_role=%d, port_type=%d\n",
+ __func__, usbpd_data->typec_power_role, usbpd_data->typec_data_role, port_type);
+
+ switch (port_type) {
+ case TYPEC_PORT_DFP:
+ pr_info("%s : try reversing, from UFP(Sink) to DFP(Source)\n", __func__);
+ usbpd_data->typec_try_state_change = TYPE_C_ATTACH_DFP;
+#if defined CONFIG_CCIC_S2MU004
+ s2mu004_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_DFP);
+#elif defined CONFIG_CCIC_S2MU106
+ s2mu106_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_DFP);
+#elif defined CONFIG_CCIC_S2MU205
+ s2mu205_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_DFP);
+#endif
+
+ break;
+ case TYPEC_PORT_UFP:
+ pr_info("%s : try reversing, from DFP(Source) to UFP(Sink)\n", __func__);
+ /* turns off VBUS first */
+ vbus_turn_on_ctrl(usbpd_data, 0);
+#if defined(CONFIG_CCIC_NOTIFIER)
+ ccic_event_work(usbpd_data,
+ CCIC_NOTIFY_DEV_MUIC, CCIC_NOTIFY_ID_ATTACH,
+ 0/*attach*/, 0/*rprd*/);
+#endif
+ usbpd_data->typec_try_state_change = TYPE_C_ATTACH_UFP;
+#if defined CONFIG_CCIC_S2MU004
+ s2mu004_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_UFP);
+#elif defined CONFIG_CCIC_S2MU106
+ s2mu106_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_UFP);
+#elif defined CONFIG_CCIC_S2MU205
+ s2mu205_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_UFP);
+#endif
+
+ break;
+ case TYPEC_PORT_DRP:
+ pr_info("%s : set to DRP (No action)\n", __func__);
+ return 0;
+ default :
+ pr_info("%s : invalid typec_role\n", __func__);
+ return -EINVAL;
+ }
+
+ if (usbpd_data->typec_try_state_change) {
+ reinit_completion(&usbpd_data->role_reverse_completion);
+ timeout =
+ wait_for_completion_timeout(&usbpd_data->role_reverse_completion,
+ msecs_to_jiffies
+ (DUAL_ROLE_SET_MODE_WAIT_MS));
+
+ if (!timeout) {
+ pr_err("%s: reverse failed, set mode to DRP\n", __func__);
+ disable_irq(usbpd_data->irq);
+ /* exit from Disabled state and set mode to DRP */
+ usbpd_data->typec_try_state_change = 0;
+#if defined CONFIG_CCIC_S2MU004
+ s2mu004_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_DRP);
+#elif defined CONFIG_CCIC_S2MU106
+ s2mu106_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_DRP);
+#elif defined CONFIG_CCIC_S2MU205
+ s2mu205_rprd_mode_change(usbpd_data, TYPE_C_ATTACH_DRP);
+#endif
+
+ enable_irq(usbpd_data->irq);
+ return -EIO;
+ } else {
+ pr_err("%s: reverse success, one more check\n", __func__);
+ schedule_delayed_work(&usbpd_data->typec_role_swap_work, msecs_to_jiffies(DUAL_ROLE_SET_MODE_WAIT_MS));
+ }
+ }
+
+ return 0;
+}
+
+int typec_get_pd_support(void *_data)
+{
+ return TYPEC_PWR_MODE_USB;
+}
+
+int typec_init(void *_data)
+{
+#if defined CONFIG_CCIC_S2MU004
+ struct s2mu004_usbpd_data *pdic_data = _data;
+#elif defined CONFIG_CCIC_S2MU106
+ struct s2mu106_usbpd_data *pdic_data = _data;
+#elif defined CONFIG_CCIC_S2MU205
+ struct s2mu205_usbpd_data *pdic_data = _data;
+#endif
+
+ pdic_data->typec_cap.revision = USB_TYPEC_REV_1_2;
+ pdic_data->typec_cap.pd_revision = 0x300;
+ pdic_data->typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
+ pdic_data->typec_cap.port_type_set = typec_port_type_set;
+ pdic_data->typec_cap.type = TYPEC_PORT_DRP;
+ pdic_data->port = typec_register_port(pdic_data->dev, &pdic_data->typec_cap);
+ if (IS_ERR(pdic_data->port)) {
+ pr_err("%s : unable to register typec_register_port\n", __func__);
+ return -1;
+ } else
+ pr_err("%s : success typec_register_port port=%pK\n", __func__, pdic_data->port);
+
+ init_completion(&pdic_data->role_reverse_completion);
+ INIT_DELAYED_WORK(&pdic_data->typec_role_swap_work, typec_role_swap_check);
+
+ return 0;
+}
#endif
//pr_info("Rx Request Current : %dmA\n", max_min*10);
/* Compare Pdo and Rdo */
- if ((src_max_current >= max_min) && (pos == 1))
+ if ((src_max_current >= op) && (pos == 1))
return 0;
else
return -1;
ccic->attached_dev = 0;
ccic->ccic_evt_rid = 0;
ccic->ccic_evt_rprd = 0;
- ccic->ccic_evt_roleswap = 0;
+ //ccic->ccic_evt_roleswap = 0;
ccic->ccic_evt_dcdcnt = 0;
ccic->ccic_evt_attached = MUIC_CCIC_NOTI_UNDEFINED;
{
#ifdef CONFIG_IFCONN_NOTIFIER
struct ifconn_notifier_template *pnoti = (struct ifconn_notifier_template *)data;
-#else
- CC_NOTI_TYPEDEF *pnoti = (CC_NOTI_TYPEDEF *)data;
-#endif
+
struct ccic_desc_t *ccic = muic_if->ccic;
-
- pr_info("%s: src:%d dest:%d sub1:%d\n", __func__,
- pnoti->src, pnoti->dest, pnoti->sub1);
-
- if (pnoti->sub1 == true) {
- /* sink -> src */
- ccic->ccic_evt_rprd = 1;
- ccic->ccic_evt_roleswap = 1;
- ccic->attached_dev = ATTACHED_DEV_OTG_MUIC;
- if (muic_if->set_cable_state)
- muic_if->set_cable_state(muic_if->muic_data, ccic->attached_dev);
- } else {
- /* src -> sink */
- muic_manager_handle_ccic_detach(muic_if);
- ccic->ccic_evt_attached = MUIC_CCIC_NOTI_ATTACH;
- ccic->ccic_evt_rprd = 1;
- ccic->ccic_evt_roleswap = 1;
- ccic->attached_dev = ATTACHED_DEV_TYPE3_CHARGER_MUIC;
- if (muic_if->set_cable_state)
- muic_if->set_cable_state(muic_if->muic_data, ccic->attached_dev);
- }
+ pr_info("%s: event:%d\n", __func__, pnoti->event);
- return 0;
+ if (pnoti->event == IFCONN_NOTIFY_EVENT_USB_ATTACH_UFP)
+ ccic->ccic_evt_roleswap = 1;
+#endif
+ return 0;
}
static int muic_manager_handle_otg(struct muic_interface_t *muic_if, void *data)
{
- int ret = MUIC_NORMAL_OTG;
struct ccic_desc_t *ccic = muic_if->ccic;
#ifdef CONFIG_IFCONN_NOTIFIER
struct ifconn_notifier_template *pnoti = (struct ifconn_notifier_template *)data;
#ifndef CONFIG_IFCONN_NOTIFIER
if (pnoti->sub1 == true) {
#endif
- /* OTG Attach */
- if (muic_if->check_usb_killer) {
- ret = muic_if->check_usb_killer(muic_if->muic_data);
- }
-
- if (ret == MUIC_NORMAL_OTG) {
- MUIC_SEND_NOTI_TO_CCIC_ATTACH(ATTACHED_DEV_OTG_MUIC);
- ccic->ccic_evt_rprd = 1;
- ccic->attached_dev = ATTACHED_DEV_OTG_MUIC;
- if (muic_if->set_cable_state)
- muic_if->set_cable_state(muic_if->muic_data, ccic->attached_dev);
- muic_manager_switch_path(muic_if, MUIC_PATH_USB_AP);
- } else
- pr_info("[MUIC] %s USB Killer Detected!!!\n", __func__);
+ MUIC_SEND_NOTI_TO_CCIC_ATTACH(ATTACHED_DEV_OTG_MUIC);
+ ccic->ccic_evt_rprd = 1;
+ ccic->attached_dev = ATTACHED_DEV_OTG_MUIC;
+ if (muic_if->set_cable_state)
+ muic_if->set_cable_state(muic_if->muic_data, ccic->attached_dev);
+ muic_manager_switch_path(muic_if, MUIC_PATH_USB_AP);
#ifndef CONFIG_IFCONN_NOTIFIER
}
#endif
POWER_SUPPLY_ATTR(co_enable),
POWER_SUPPLY_ATTR(rr_enable),
POWER_SUPPLY_ATTR(usbpd_reset),
+ POWER_SUPPLY_ATTR(usbpd_test_read),
};
static struct attribute *
int buck_state = ENABLE;
union power_supply_propval value;
int ret;
+ u8 data = 0;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
}
break;
case POWER_SUPPLY_PROP_FUELGAUGE_RESET:
- s2mu106_update_reg(charger->i2c, 0xE3, 0x03 << 6, 0x03 << 6);
+ s2mu106_read_reg(charger->i2c, 0xE3, &data);
+ data |= 0x03 << 6;
+ s2mu106_write_reg(charger->i2c, 0xE3, data);
msleep(1000);
- s2mu106_update_reg(charger->i2c, 0xE3, 0x00 << 6, 0x03 << 6);
+ data &= ~(0x03 << 6);
+ s2mu106_write_reg(charger->i2c, 0xE3, data);
msleep(50);
pr_info("%s: reset fuelgauge when surge occur!\n", __func__);
break;
+ case POWER_SUPPLY_PROP_USBPD_TEST_READ:
+ s2mu106_test_read(charger->i2c);
+ s2mu106_read_reg(charger->i2c, 0xEC, &data);
+ pr_info("%s, charger 0xEC=(%x)\n", __func__, data);
+ break;
default:
return -EINVAL;
}
s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_ICHGIN, &data1);
s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_ICHGIN, &data2);
-
+
if (data1 < 0 || data2 < 0)
return -EINVAL;
charge_current = (int)((data1 << 4) | (data2 >> 4));
+#if 0
pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, current = %d\n",
__func__, data1, data2, charge_current);
+#endif
return charge_current;
}
#include <soc/samsung/exynos-pm.h>
#endif
-#if defined(CONFIG_TYPEC)
-#include <linux/usb/typec.h>
-#endif
-
#include "core.h"
#include "otg.h"
#include "io.h"
/* -------------------------------------------------------------------------- */
-#if defined(CONFIG_TYPEC)
-struct intf_typec {
- /* struct mutex lock; */ /* device lock */
- struct device *dev;
- struct typec_port *port;
- struct typec_capability cap;
- struct typec_partner *partner;
-};
-#endif
-
int otg_connection;
static int dwc3_otg_statemachine(struct otg_fsm *fsm)
{
struct dwc3_otg *dotg;
struct dwc3_ext_otg_ops *ops = NULL;
int ret = 0;
-#if defined(CONFIG_TYPEC)
- struct intf_typec *typec;
- struct typec_partner_desc partner;
-#endif
-
dev_info(dwc->dev, "%s\n", __func__);
}
}
-#if defined(CONFIG_TYPEC)
- typec = devm_kzalloc(dwc->dev, sizeof(*typec), GFP_KERNEL);
- if (!typec)
- return -ENOMEM;
-
- /* mutex_init(&md05->lock); */
- typec->dev = dwc->dev;
-
- typec->cap.type = TYPEC_PORT_DRP;
- typec->cap.revision = USB_TYPEC_REV_1_1;
- typec->cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
-
- typec->port = typec_register_port(dwc->dev, &typec->cap);
- if (!typec->port)
- return -ENODEV;
-
- typec_set_data_role(typec->port, TYPEC_DEVICE);
- typec_set_pwr_role(typec->port, TYPEC_SINK);
- typec_set_pwr_opmode(typec->port, TYPEC_PWR_MODE_USB);
-
- dotg->typec = typec;
-
- typec->partner = typec_register_partner(typec->port, &partner);
- if (!dotg->typec->partner)
- dev_err(dwc->dev, "failed register partner\n");
-#endif
-
-
wake_lock_init(&dotg->wakelock, WAKE_LOCK_SUSPEND, "dwc3-otg");
ret = sysfs_create_group(&dwc->dev->kobj, &dwc3_otg_attr_group);
if (!dotg->ext_otg_ops)
return;
-#if defined(CONFIG_TYPEC)
- typec_unregister_partner(dotg->typec->partner);
- typec_unregister_port(dotg->typec->port);
-#endif
-
dwc3_ext_otg_exit(dotg);
sysfs_remove_group(&dwc->dev->kobj, &dwc3_otg_attr_group);
#if defined CONFIG_IFCONN_NOTIFIER
#include <linux/ifconn/ifconn_notifier.h>
#endif
+#if defined(CONFIG_TYPEC)
+#include <linux/usb/typec.h>
+#endif
#include <linux/power_supply.h>
#define S2MU106_HARD_RESET_DELAY_MS (300)
#define S2MU106_WAIT_RD_DETACH_DELAY_MS (200)
#define S2MU106_WAIT_ATTACH_DELAY_MS (30)
-#if defined(CONFIG_DUAL_ROLE_USB_INTF)
#define DUAL_ROLE_SET_MODE_WAIT_MS (2000)
-#endif
#define S2MU106_WATER_CHK_INTERVAL_TIME (300)
#define S2MU106_ATTACH_STATE_CHECK_TIME (1000)
struct completion reverse_completion;
int try_state_change;
struct delayed_work role_swap_work;
+#elif defined(CONFIG_TYPEC)
+ struct typec_port *port;
+ struct typec_partner *partner;
+ struct usb_pd_identity partner_identity;
+ struct typec_capability typec_cap;
+ struct completion role_reverse_completion;
+ int typec_power_role;
+ int typec_data_role;
+ int typec_try_state_change;
+ struct delayed_work typec_role_swap_work;
#endif
struct notifier_block type3_nb;
struct workqueue_struct *pdic_queue;
int pm_cc1;
int pm_cc2;
int pm_chgin;
+ int pm_chgin_i;
struct power_supply_desc ccic_desc;
struct power_supply *psy_pm;
struct power_supply *psy_ccic;
#if defined(CONFIG_CCIC_NOTIFIER)
extern void s2mu106_control_option_command(struct s2mu106_usbpd_data *usbpd_data, int cmd);
#endif
-#if defined(CONFIG_DUAL_ROLE_USB_INTF)
extern void s2mu106_rprd_mode_change(struct s2mu106_usbpd_data *usbpd_data, u8 mode);
-#endif
extern void vbus_turn_on_ctrl(struct s2mu106_usbpd_data *usbpd_data, bool enable);
extern int s2mu106_set_lpm_mode(struct s2mu106_usbpd_data *pdic_data);
extern int s2mu106_set_normal_mode(struct s2mu106_usbpd_data *pdic_data);
#endif
#if defined(CONFIG_DUAL_ROLE_USB_INTF)
#include <linux/usb/class-dual-role.h>
+#elif defined(CONFIG_TYPEC)
+#include <linux/usb/typec.h>
#endif
#ifndef __USBPD_EXT_H__
enum dual_role_property prop,
const unsigned int *val);
extern int dual_role_init(void *_data);
+#elif defined(CONFIG_TYPEC)
+extern void typec_role_swap_check(struct work_struct *wk);
+extern int typec_port_type_set(const struct typec_capability *cap,
+ enum typec_port_type port_type);
+extern int typec_get_pd_support(void *_data);
+extern int typec_init(void *_data);
#endif
#endif
POWER_SUPPLY_PROP_CO_ENABLE,
POWER_SUPPLY_PROP_RR_ENABLE,
POWER_SUPPLY_PROP_USBPD_RESET,
+ POWER_SUPPLY_PROP_USBPD_TEST_READ,
};
enum power_supply_type {