Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

extcon: int3496: Add support for controlling Vbus through a regulator

On some boards the 5V vboost-regulator for powering devices connected to
the micro USB connector is not controlled through a GPIO. This happens
for example when the 5V vboost-regulator is integrated into the charger IC
and controlled over I2C.

Add support for controlling the 5V vboost-regulator through the regulator
framework for such boards.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>

authored by

Hans de Goede and committed by
Chanwoo Choi
4c018cc8 c26aef6d

+29 -1
+29 -1
drivers/extcon/extcon-intel-int3496.c
··· 17 17 #include <linux/interrupt.h> 18 18 #include <linux/module.h> 19 19 #include <linux/platform_device.h> 20 + #include <linux/regulator/consumer.h> 20 21 21 22 #define INT3496_GPIO_USB_ID 0 22 23 #define INT3496_GPIO_VBUS_EN 1 ··· 31 30 struct gpio_desc *gpio_usb_id; 32 31 struct gpio_desc *gpio_vbus_en; 33 32 struct gpio_desc *gpio_usb_mux; 33 + struct regulator *vbus_boost; 34 34 int usb_id_irq; 35 + bool vbus_boost_enabled; 35 36 }; 36 37 37 38 static const unsigned int int3496_cable[] = { ··· 56 53 { }, 57 54 }; 58 55 56 + static void int3496_set_vbus_boost(struct int3496_data *data, bool enable) 57 + { 58 + int ret; 59 + 60 + if (IS_ERR_OR_NULL(data->vbus_boost)) 61 + return; 62 + 63 + if (data->vbus_boost_enabled == enable) 64 + return; 65 + 66 + if (enable) 67 + ret = regulator_enable(data->vbus_boost); 68 + else 69 + ret = regulator_disable(data->vbus_boost); 70 + 71 + if (ret == 0) 72 + data->vbus_boost_enabled = enable; 73 + else 74 + dev_err(data->dev, "Error updating Vbus boost regulator: %d\n", ret); 75 + } 76 + 59 77 static void int3496_do_usb_id(struct work_struct *work) 60 78 { 61 79 struct int3496_data *data = ··· 95 71 96 72 if (!IS_ERR(data->gpio_vbus_en)) 97 73 gpiod_direction_output(data->gpio_vbus_en, !id); 74 + else 75 + int3496_set_vbus_boost(data, !id); 98 76 99 77 extcon_set_state_sync(data->edev, EXTCON_USB_HOST, !id); 100 78 } ··· 149 123 } 150 124 151 125 data->gpio_vbus_en = devm_gpiod_get(dev, "vbus", GPIOD_ASIS); 152 - if (IS_ERR(data->gpio_vbus_en)) 126 + if (IS_ERR(data->gpio_vbus_en)) { 153 127 dev_dbg(dev, "can't request VBUS EN GPIO\n"); 128 + data->vbus_boost = devm_regulator_get_optional(dev, "vbus"); 129 + } 154 130 155 131 data->gpio_usb_mux = devm_gpiod_get(dev, "mux", GPIOD_ASIS); 156 132 if (IS_ERR(data->gpio_usb_mux))