Skip to content

Commit 9a0eb8d

Browse files
committed
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]>
1 parent 3250077 commit 9a0eb8d

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,26 +95,35 @@ 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
{
103110
u64 val;
104-
u32 reg_pwr;
111+
u32 reg_pwr = (dw9719->model == DW9718S) ? DW9718S_PD : DW9719_CONTROL;
105112
int ret;
106113

107114
ret = regulator_enable(dw9719->regulator);
108115
if (ret)
109116
return ret;
110117

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

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

0 commit comments

Comments
 (0)