Skip to content

Commit dfc323c

Browse files
valpackettAndré Apitzsch
authored andcommitted
media: i2c: dw9719: Fix power on/off sequence
The "jiggle" code was not actually expecting failure, which it should because that's what actually happens when the device wasn't already woken up by the regulator power-on (i.e. in the case of a shared regulator). Also, do actually enter the internal suspend mode on shutdown, to save power in the case of a shared regulator. Also, wait a bit longer (2x tOPR) on waking up, 1x is not enough at least on the DW9718S as found on the motorola-nora smartphone. Signed-off-by: Val Packett <[email protected]> Signed-off-by: André Apitzsch <[email protected]>
1 parent fdbccac commit dfc323c

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

drivers/media/i2c/dw9719.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,19 @@ struct dw9719_device {
9595

9696
static int dw9719_power_down(struct dw9719_device *dw9719)
9797
{
98+
u32 reg_pwr = (dw9719->model == DW9718S) ? DW9718S_PD : DW9719_CONTROL;
99+
100+
/*
101+
* Worth engaging the internal SHUTDOWN mode especially due to the
102+
* regulator being potentially shared with other devices.
103+
*/
104+
cci_write(dw9719->regmap, reg_pwr, DW9719_SHUTDOWN, NULL);
98105
return regulator_disable(dw9719->regulator);
99106
}
100107

101108
static int dw9719_power_up(struct dw9719_device *dw9719, bool detect)
102109
{
103-
u32 reg_pwr;
110+
u32 reg_pwr = (dw9719->model == DW9718S) ? DW9718S_PD : DW9719_CONTROL;
104111
u64 val;
105112
int ret;
106113
int err;
@@ -109,13 +116,15 @@ static int dw9719_power_up(struct dw9719_device *dw9719, bool detect)
109116
if (ret)
110117
return ret;
111118

112-
/* Jiggle SCL pin to wake up device */
113-
reg_pwr = (dw9719->model == DW9718S) ? DW9718S_PD : DW9719_CONTROL;
114-
cci_write(dw9719->regmap, reg_pwr, DW9719_SHUTDOWN, &ret);
115-
fsleep(100);
119+
/*
120+
* Need 100us to transition from SHUTDOWN to STANDBY.
121+
* Jiggle the SCL pin to wake up the device (even when the regulator
122+
* is shared) and wait double the time to be sure, then retry the write.
123+
*/
124+
cci_write(dw9719->regmap, reg_pwr, DW9719_STANDBY, &ret);
125+
ret = 0; /* the jiggle is expected to fail, don't even log that as error */
126+
fsleep(200);
116127
cci_write(dw9719->regmap, reg_pwr, DW9719_STANDBY, &ret);
117-
/* Need 100us to transit from SHUTDOWN to STANDBY */
118-
fsleep(100);
119128

120129
if (detect) {
121130
/* This model does not have an INFO register */

0 commit comments

Comments
 (0)