#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/usb/pd.h>
#include <linux/usb/tcpci.h>
#include <linux/usb/tcpm.h>
*/
#define TCPC_RECEIVE_BUFFER_LEN 32
-#define MAX_BUCK_BOOST_SID 0x69
-#define MAX_BUCK_BOOST_OP 0xb9
-#define MAX_BUCK_BOOST_OFF 0
-#define MAX_BUCK_BOOST_SOURCE 0xa
-#define MAX_BUCK_BOOST_SINK 0x5
-
static const struct regmap_range max_tcpci_tcpci_range[] = {
regmap_reg_range(0x00, 0x95)
};
tcpm_pd_receive(chip->port, &msg, rx_type);
}
+static int get_vbus_regulator_handle(struct max_tcpci_chip *chip)
+{
+ if (IS_ERR_OR_NULL(chip->vbus_reg)) {
+ chip->vbus_reg = devm_regulator_get_exclusive(chip->dev,
+ "vbus");
+ if (IS_ERR_OR_NULL(chip->vbus_reg)) {
+ dev_err(chip->dev,
+ "Failed to get vbus regulator handle\n");
+ return -ENODEV;
+ }
+ }
+
+ return 0;
+}
+
static int max_tcpci_set_vbus(struct tcpci *tcpci, struct tcpci_data *tdata, bool source, bool sink)
{
struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata);
- u8 buffer_source[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SOURCE};
- u8 buffer_sink[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SINK};
- u8 buffer_none[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_OFF};
- struct i2c_client *i2c = chip->client;
int ret;
- struct i2c_msg msgs[] = {
- {
- .addr = MAX_BUCK_BOOST_SID,
- .flags = i2c->flags & I2C_M_TEN,
- .len = 2,
- .buf = source ? buffer_source : sink ? buffer_sink : buffer_none,
- },
- };
-
if (source && sink) {
dev_err(chip->dev, "Both source and sink set\n");
return -EINVAL;
}
- ret = i2c_transfer(i2c->adapter, msgs, 1);
+ ret = get_vbus_regulator_handle(chip);
+ if (ret) {
+ /*
+ * Regulator is not necessary for sink only applications. Return
+ * success in cases where sink mode is being modified.
+ */
+ return source ? ret : 1;
+ }
+
+ if (source) {
+ if (!regulator_is_enabled(chip->vbus_reg))
+ ret = regulator_enable(chip->vbus_reg);
+ } else {
+ if (regulator_is_enabled(chip->vbus_reg))
+ ret = regulator_disable(chip->vbus_reg);
+ }
- return ret < 0 ? ret : 1;
+ return ret < 0 ? ret : 1;
}
static void process_power_status(struct max_tcpci_chip *chip)