extcon: add MAX14526 MUIC support
MAX14526 is a powerful extcon chip which allows detection of various plugs like usb, mhl, uart, headset etc. This version of driver implements support of AP-usb and CP-usb/uart paths. Tested-by: Andreas Westman Dorcsak <hedmoo@yahoo.com> # LG P880 T30 Tested-by: Svyatoslav Ryhel <clamor95@gmail.com> # LG P895 T30 Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
8b215e10fe
commit
488d3dae24
3 changed files with 161 additions and 0 deletions
|
@ -19,4 +19,13 @@ config EXTCON_SANDBOX
|
||||||
Enable extcon support for sandbox. This is an emulation of a real
|
Enable extcon support for sandbox. This is an emulation of a real
|
||||||
extcon. Currectly all configuration is done in the probe.
|
extcon. Currectly all configuration is done in the probe.
|
||||||
|
|
||||||
|
config EXTCON_MAX14526
|
||||||
|
bool "Maxim MAX14526 EXTCON Support"
|
||||||
|
depends on DM_I2C
|
||||||
|
depends on EXTCON
|
||||||
|
help
|
||||||
|
If you say yes here you get support for the MUIC device of
|
||||||
|
Maxim MAX14526. The MAX14526 MUIC is a USB port accessory
|
||||||
|
detector and switch.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -4,3 +4,4 @@
|
||||||
|
|
||||||
obj-$(CONFIG_EXTCON) += extcon-uclass.o
|
obj-$(CONFIG_EXTCON) += extcon-uclass.o
|
||||||
obj-$(CONFIG_EXTCON_SANDBOX) += extcon-sandbox.o
|
obj-$(CONFIG_EXTCON_SANDBOX) += extcon-sandbox.o
|
||||||
|
obj-$(CONFIG_EXTCON_MAX14526) += extcon-max14526.o
|
||||||
|
|
151
drivers/extcon/extcon-max14526.c
Normal file
151
drivers/extcon/extcon-max14526.c
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Svyatoslav Ryhel <clamor95@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <i2c.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <log.h>
|
||||||
|
#include <extcon.h>
|
||||||
|
#include <asm/gpio.h>
|
||||||
|
|
||||||
|
#define CONTROL_1 0x01
|
||||||
|
#define SW_CONTROL 0x03
|
||||||
|
|
||||||
|
#define ID_200 0x10
|
||||||
|
#define ADC_EN 0x02
|
||||||
|
#define CP_EN 0x01
|
||||||
|
|
||||||
|
#define DP_USB 0x00
|
||||||
|
#define DP_UART 0x08
|
||||||
|
#define DP_AUDIO 0x10
|
||||||
|
#define DP_OPEN 0x38
|
||||||
|
|
||||||
|
#define DM_USB 0x00
|
||||||
|
#define DM_UART 0x01
|
||||||
|
#define DM_AUDIO 0x02
|
||||||
|
#define DM_OPEN 0x07
|
||||||
|
|
||||||
|
#define AP_USB BIT(0)
|
||||||
|
#define CP_USB BIT(1)
|
||||||
|
#define CP_UART BIT(2)
|
||||||
|
|
||||||
|
struct max14526_priv {
|
||||||
|
struct gpio_desc usif_gpio;
|
||||||
|
struct gpio_desc dp2t_gpio;
|
||||||
|
struct gpio_desc ifx_usb_vbus_gpio;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void max14526_set_mode(struct udevice *dev, int mode)
|
||||||
|
{
|
||||||
|
struct max14526_priv *priv = dev_get_priv(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ((mode & AP_USB) || (mode & CP_USB)) {
|
||||||
|
/* Connect CP UART signals to AP */
|
||||||
|
ret = dm_gpio_set_value(&priv->usif_gpio, 0);
|
||||||
|
if (ret)
|
||||||
|
log_debug("cp-uart > ap failed (%d)\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode & CP_UART) {
|
||||||
|
/* Connect CP UART signals to DP2T */
|
||||||
|
ret = dm_gpio_set_value(&priv->usif_gpio, 1);
|
||||||
|
if (ret)
|
||||||
|
log_debug("cp-uart > dp2t failed (%d)\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode & CP_USB) {
|
||||||
|
/* Connect CP USB to MUIC UART */
|
||||||
|
ret = dm_gpio_set_value(&priv->ifx_usb_vbus_gpio, 1);
|
||||||
|
if (ret)
|
||||||
|
log_debug("usb-vbus-gpio enable failed (%d)\n", ret);
|
||||||
|
|
||||||
|
ret = dm_gpio_set_value(&priv->dp2t_gpio, 1);
|
||||||
|
if (ret)
|
||||||
|
log_debug("cp-usb > muic-uart failed (%d)\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode & AP_USB) || (mode & CP_UART)) {
|
||||||
|
/* Connect CP UART to MUIC UART */
|
||||||
|
ret = dm_gpio_set_value(&priv->dp2t_gpio, 0);
|
||||||
|
if (ret)
|
||||||
|
log_debug("cp-uart > muic-uart failed (%d)\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode & AP_USB) {
|
||||||
|
/* Enables USB Path */
|
||||||
|
ret = dm_i2c_reg_write(dev, SW_CONTROL, DP_USB | DM_USB);
|
||||||
|
if (ret)
|
||||||
|
log_debug("USB path set failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode & CP_USB) || (mode & CP_UART)) {
|
||||||
|
/* Enables UART Path */
|
||||||
|
ret = dm_i2c_reg_write(dev, SW_CONTROL, DP_UART | DM_UART);
|
||||||
|
if (ret)
|
||||||
|
log_debug("UART path set failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enables 200K, Charger Pump, and ADC */
|
||||||
|
ret = dm_i2c_reg_write(dev, CONTROL_1, ID_200 | ADC_EN | CP_EN);
|
||||||
|
if (ret)
|
||||||
|
log_debug("200K, Charger Pump, and ADC set failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max14526_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct max14526_priv *priv = dev_get_priv(dev);
|
||||||
|
int ret, mode = 0;
|
||||||
|
|
||||||
|
ret = gpio_request_by_name(dev, "usif-gpios", 0,
|
||||||
|
&priv->usif_gpio, GPIOD_IS_OUT);
|
||||||
|
if (ret) {
|
||||||
|
log_err("could not decode usif-gpios (%d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gpio_request_by_name(dev, "dp2t-gpios", 0,
|
||||||
|
&priv->dp2t_gpio, GPIOD_IS_OUT);
|
||||||
|
if (ret) {
|
||||||
|
log_err("could not decode dp2t-gpios (%d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev_read_bool(dev, "maxim,ap-usb"))
|
||||||
|
mode |= AP_USB;
|
||||||
|
|
||||||
|
if (dev_read_bool(dev, "maxim,cp-usb")) {
|
||||||
|
mode |= CP_USB;
|
||||||
|
|
||||||
|
ret = gpio_request_by_name(dev, "usb-vbus-gpios", 0,
|
||||||
|
&priv->ifx_usb_vbus_gpio, GPIOD_IS_OUT);
|
||||||
|
if (ret) {
|
||||||
|
log_err("could not decode usb-vbus-gpios (%d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev_read_bool(dev, "maxim,cp-uart"))
|
||||||
|
mode |= CP_UART;
|
||||||
|
|
||||||
|
max14526_set_mode(dev, mode);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct udevice_id max14526_ids[] = {
|
||||||
|
{ .compatible = "maxim,max14526-muic" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(extcon_max14526) = {
|
||||||
|
.name = "extcon_max14526",
|
||||||
|
.id = UCLASS_EXTCON,
|
||||||
|
.of_match = max14526_ids,
|
||||||
|
.probe = max14526_probe,
|
||||||
|
.priv_auto = sizeof(struct max14526_priv),
|
||||||
|
};
|
Loading…
Reference in a new issue