Skip to content

Commit 5665eee

Browse files
6by9broonie
authored andcommitted
regulator: rpi-panel: Handle I2C errors/timing to the Atmel
The Atmel is doing some things in the I2C ISR, during which period it will not respond to further commands. This is particularly true of the POWERON command. Increase delays appropriately, and retry should I2C errors be reported. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> Link: https://lore.kernel.org/r/20220124220129.158891-3-detlev.casanova@collabora.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 7291e7d commit 5665eee

1 file changed

Lines changed: 46 additions & 10 deletions

File tree

drivers/regulator/rpi-panel-attiny-regulator.c

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,24 @@ static const struct regmap_config attiny_regmap_config = {
3737
static int attiny_lcd_power_enable(struct regulator_dev *rdev)
3838
{
3939
unsigned int data;
40+
int ret, i;
4041

4142
regmap_write(rdev->regmap, REG_POWERON, 1);
43+
msleep(80);
44+
4245
/* Wait for nPWRDWN to go low to indicate poweron is done. */
43-
regmap_read_poll_timeout(rdev->regmap, REG_PORTB, data,
44-
data & BIT(0), 10, 1000000);
46+
for (i = 0; i < 20; i++) {
47+
ret = regmap_read(rdev->regmap, REG_PORTB, &data);
48+
if (!ret) {
49+
if (data & BIT(0))
50+
break;
51+
}
52+
usleep_range(10000, 12000);
53+
}
54+
usleep_range(10000, 12000);
55+
56+
if (ret)
57+
pr_err("%s: regmap_read_poll_timeout failed %d\n", __func__, ret);
4558

4659
/* Default to the same orientation as the closed source
4760
* firmware used for the panel. Runtime rotation
@@ -57,23 +70,34 @@ static int attiny_lcd_power_disable(struct regulator_dev *rdev)
5770
{
5871
regmap_write(rdev->regmap, REG_PWM, 0);
5972
regmap_write(rdev->regmap, REG_POWERON, 0);
60-
udelay(1);
73+
msleep(30);
6174
return 0;
6275
}
6376

6477
static int attiny_lcd_power_is_enabled(struct regulator_dev *rdev)
6578
{
6679
unsigned int data;
67-
int ret;
80+
int ret, i;
6881

69-
ret = regmap_read(rdev->regmap, REG_POWERON, &data);
82+
for (i = 0; i < 10; i++) {
83+
ret = regmap_read(rdev->regmap, REG_POWERON, &data);
84+
if (!ret)
85+
break;
86+
usleep_range(10000, 12000);
87+
}
7088
if (ret < 0)
7189
return ret;
7290

7391
if (!(data & BIT(0)))
7492
return 0;
7593

76-
ret = regmap_read(rdev->regmap, REG_PORTB, &data);
94+
for (i = 0; i < 10; i++) {
95+
ret = regmap_read(rdev->regmap, REG_PORTB, &data);
96+
if (!ret)
97+
break;
98+
usleep_range(10000, 12000);
99+
}
100+
77101
if (ret < 0)
78102
return ret;
79103

@@ -103,20 +127,32 @@ static int attiny_update_status(struct backlight_device *bl)
103127
{
104128
struct regmap *regmap = bl_get_data(bl);
105129
int brightness = bl->props.brightness;
130+
int ret, i;
106131

107132
if (bl->props.power != FB_BLANK_UNBLANK ||
108133
bl->props.fb_blank != FB_BLANK_UNBLANK)
109134
brightness = 0;
110135

111-
return regmap_write(regmap, REG_PWM, brightness);
136+
for (i = 0; i < 10; i++) {
137+
ret = regmap_write(regmap, REG_PWM, brightness);
138+
if (!ret)
139+
break;
140+
}
141+
142+
return ret;
112143
}
113144

114145
static int attiny_get_brightness(struct backlight_device *bl)
115146
{
116147
struct regmap *regmap = bl_get_data(bl);
117-
int ret, brightness;
148+
int ret, brightness, i;
149+
150+
for (i = 0; i < 10; i++) {
151+
ret = regmap_read(regmap, REG_PWM, &brightness);
152+
if (!ret)
153+
break;
154+
}
118155

119-
ret = regmap_read(regmap, REG_PWM, &brightness);
120156
if (ret)
121157
return ret;
122158

@@ -166,7 +202,7 @@ static int attiny_i2c_probe(struct i2c_client *i2c,
166202
}
167203

168204
regmap_write(regmap, REG_POWERON, 0);
169-
mdelay(1);
205+
msleep(30);
170206

171207
config.dev = &i2c->dev;
172208
config.regmap = regmap;

0 commit comments

Comments
 (0)