Merge branch 'pd'

parents 053a3b3d 3b0a6d32
......@@ -44,10 +44,13 @@
#define TPS_REG_DATA_STATUS 0x5f
#define TPS_USB_500mA 500000
#define TPS_USB_900mA 900000
#define TPS_TYPEC_1500mA 1500000
#define TPS_TYPEC_3000mA 3000000
#define TPS_USB_5V 5000000
#define CC_INT_MASK TPS_REG_INT_STATUS_UPDATE
/* TPS_REG_SYSTEM_CONF bits */
#define TPS_SYSCONF_PORTINFO(c) ((c) & 7)
......@@ -303,6 +306,9 @@ static int tps6598x_connect(struct tps6598x *tps, u32 status)
struct typec_partner_desc desc;
enum typec_pwr_opmode mode;
int ret;
u64 mask;
dev_dbg(tps->dev, "%s: status %x", __func__, status);
if (tps->partner)
return 0;
......@@ -332,6 +338,16 @@ static int tps6598x_connect(struct tps6598x *tps, u32 status)
if (desc.identity)
typec_partner_set_identity(tps->partner);
ret = tps6598x_read64(tps, TPS_REG_INT_MASK1, &mask);
if (ret < 0)
return ret;
mask |= CC_INT_MASK;
ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask);
if (ret < 0)
return ret;
dev_dbg(tps->dev, "interrupt mask updated %llx", mask);
power_supply_changed(tps->psy);
return 0;
......@@ -357,6 +373,11 @@ tps6598x_update_data_status(struct tps6598x *tps, u32 status)
static void tps6598x_disconnect(struct tps6598x *tps, u32 status)
{
int ret;
u64 mask;
dev_dbg(tps->dev, "%s: status %x", __func__, status);
if (!IS_ERR(tps->partner))
typec_unregister_partner(tps->partner);
tps->partner = NULL;
......@@ -367,6 +388,19 @@ static void tps6598x_disconnect(struct tps6598x *tps, u32 status)
memset(&tps->terms, 0, sizeof(struct tps6598x_pdo));
ret = tps6598x_read64(tps, TPS_REG_INT_MASK1, &mask);
if (ret < 0) {
dev_err(tps->dev, "Reading interrupt mask failed");
return;
}
mask &= ~CC_INT_MASK;
ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask);
if (ret < 0) {
dev_err(tps->dev, "Writing interrupt mask failed");
return;
}
dev_dbg(tps->dev, "interrupt mask updated %llx", mask);
power_supply_changed(tps->psy);
}
......@@ -546,6 +580,7 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data)
u16 pwr_status;
bool psy_changed = false;
int ret;
u64 mask;
mutex_lock(&tps->lock);
......@@ -610,6 +645,26 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data)
psy_changed = true;
}
if ((event1 | event2) & TPS_REG_INT_STATUS_UPDATE) {
ret = tps6598x_read64(tps, TPS_REG_INT_MASK1, &mask);
if (ret < 0)
dev_err( tps->dev, "Reading interrupt mask failed");
dev_dbg(tps->dev, "Status update: %x %llx", status, mask);
if (!(mask & TPS_REG_INT_STATUS_UPDATE))
dev_err( tps->dev, "The interrupt is masked , how did it fire ?? %llx", mask);
if (!(status & TPS_STATUS_PLUG_PRESENT) || ((status & 0xc) != 0xc)) {
/* the status update register can fire even when masked so try
and mask it again */
mask &= ~TPS_REG_INT_STATUS_UPDATE;
ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask);
if (ret < 0)
dev_err( tps->dev, "Writing interrupt mask failed");
else
dev_dbg( tps->dev, "interrupt mask updated %llx", mask);
}
}
err_clear_ints:
tps6598x_write64(tps, TPS_REG_INT_CLEAR1, event1);
tps6598x_write64(tps, TPS_REG_INT_CLEAR2, event2);
......@@ -682,11 +737,11 @@ static int tps6598x_psy_get_max_current(struct tps6598x *tps,
val->intval = TPS_TYPEC_3000mA;
break;
case TYPEC_PWR_MODE_PD:
val->intval = tps->terms.max_current ?: TPS_USB_500mA;
val->intval = tps->terms.max_current ?: TPS_USB_900mA;
break;
default:
case TYPEC_PWR_MODE_USB:
val->intval = TPS_USB_500mA;
val->intval = TPS_USB_900mA;
}
return 0;
}
......@@ -784,6 +839,7 @@ static int tps6598x_probe(struct i2c_client *client)
u32 conf;
u32 vid;
int ret;
u64 mask;
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
......@@ -897,6 +953,10 @@ static int tps6598x_probe(struct i2c_client *client)
/* set initial state */
extcon_set_state_sync(tps->extcon, EXTCON_DISP_DP, false);
ret = tps6598x_read64(tps, TPS_REG_INT_MASK1, &mask);
if (ret < 0)
dev_err(&client->dev, "failed to read irq mask%d\n", ret);
if (status & TPS_STATUS_PLUG_PRESENT) {
ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &tps->pwr_status);
if (ret < 0) {
......@@ -906,8 +966,15 @@ static int tps6598x_probe(struct i2c_client *client)
ret = tps6598x_connect(tps, status);
if (ret)
dev_err(&client->dev, "failed to register partner\n");
} else {
mask &= ~CC_INT_MASK;
}
ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask);
ret |= tps6598x_write64(tps, TPS_REG_INT_MASK2, 0);
if (ret < 0)
dev_err(&client->dev, "failed to write irq mask%d\n", ret);
ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
tps6598x_interrupt,
IRQF_SHARED | IRQF_ONESHOT,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment