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

drm/bridge: sii902x: Enable I/O and core VCC supplies if present

On the SII9022, the IOVCC and CVCC12 supplies must reach the correct
voltage before the reset sequence is initiated. On most boards, this
assumption is true at boot-up, so initialization succeeds.

However, when we try to initialize the chip with incorrect supply
voltages, it will not respond to I2C requests. sii902x_probe() fails
with -ENXIO.

To resolve this, look for the "iovcc" and "cvcc12" regulators, and
make sure they are enabled before starting the reset sequence. If
these supplies are not available in devicetree, then they will default
to dummy-regulator. In that case everything will work like before.

This was observed on a STM32MP157C-DK2 booting in u-boot falcon mode.
On this board, the supplies would be set by the second stage
bootloader, which does not run in falcon mode.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
[Fix checkpatch warnings]
Link: https://patchwork.freedesktop.org/patch/msgid/20201020221501.260025-2-mr.nuke.me@gmail.com

authored by

Alexandru Gagniuc and committed by
Sam Ravnborg
cc5f7e2f 4c1e0543

+23
+23
drivers/gpu/drm/bridge/sii902x.c
··· 17 17 #include <linux/i2c.h> 18 18 #include <linux/module.h> 19 19 #include <linux/regmap.h> 20 + #include <linux/regulator/consumer.h> 20 21 #include <linux/clk.h> 21 22 22 23 #include <drm/drm_atomic_helper.h> ··· 169 168 struct drm_connector connector; 170 169 struct gpio_desc *reset_gpio; 171 170 struct i2c_mux_core *i2cmux; 171 + struct regulator_bulk_data supplies[2]; 172 172 /* 173 173 * Mutex protects audio and video functions from interfering 174 174 * each other, by keeping their i2c command sequences atomic. ··· 1051 1049 1052 1050 mutex_init(&sii902x->mutex); 1053 1051 1052 + sii902x->supplies[0].supply = "iovcc"; 1053 + sii902x->supplies[1].supply = "cvcc12"; 1054 + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sii902x->supplies), 1055 + sii902x->supplies); 1056 + if (ret < 0) 1057 + return ret; 1058 + 1059 + ret = regulator_bulk_enable(ARRAY_SIZE(sii902x->supplies), 1060 + sii902x->supplies); 1061 + if (ret < 0) { 1062 + dev_err_probe(dev, ret, "Failed to enable supplies"); 1063 + return ret; 1064 + } 1065 + 1054 1066 ret = sii902x_init(sii902x); 1067 + if (ret < 0) { 1068 + regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies), 1069 + sii902x->supplies); 1070 + } 1071 + 1055 1072 return ret; 1056 1073 } 1057 1074 ··· 1081 1060 1082 1061 i2c_mux_del_adapters(sii902x->i2cmux); 1083 1062 drm_bridge_remove(&sii902x->bridge); 1063 + regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies), 1064 + sii902x->supplies); 1084 1065 1085 1066 return 0; 1086 1067 }