On 2019-10-15 06:48, Biwen Li wrote: > This adds property idle-state > > Signed-off-by: Biwen Li <biwen.li@xxxxxxx> > --- > Change in v2: > - update subject and description > - add property idle-state > > drivers/i2c/muxes/i2c-mux-pca954x.c | 47 ++++++++++++++++++----------- > 1 file changed, 30 insertions(+), 17 deletions(-) > > diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c > index 923aa3a5a3dc..8ec586342b92 100644 > --- a/drivers/i2c/muxes/i2c-mux-pca954x.c > +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c > @@ -86,7 +86,7 @@ struct pca954x { > > u8 last_chan; /* last register value */ > /* MUX_IDLE_AS_IS, MUX_IDLE_DISCONNECT or >= 0 for channel */ > - s8 idle_state; > + s32 idle_state; > > struct i2c_client *client; > > @@ -256,7 +256,7 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) > { > struct pca954x *data = i2c_mux_priv(muxc); > struct i2c_client *client = data->client; > - s8 idle_state; > + s32 idle_state; > > idle_state = READ_ONCE(data->idle_state); > if (idle_state >= 0) > @@ -402,6 +402,25 @@ static void pca954x_cleanup(struct i2c_mux_core *muxc) > i2c_mux_del_adapters(muxc); > } > > +static int pca954x_init(struct i2c_client *client, struct pca954x *data) > +{ > + /* > + * Write the mux register at addr to verify > + * that the mux is in fact present. This also > + * initializes the mux to disconnected state. > + */ This comment belongs in pca954x_probe, before the call to this function. However, the comment may now be be wrong since the mux is not always initialized to the disconnected state. > + if (data->idle_state >= 0) { > + /* Always enable multiplexer */ While I understand that it is important for your case that the mux is always enabled, this is just a side effect of having a specific idle-state. I suggest that you remove this comment. > + if (data->chip->muxtype == pca954x_ismux) > + data->last_chan = data->idle_state | data->chip->enable; > + else > + data->last_chan = 1 << data->idle_state; The meat of this "if" is still duplicated, I was suggesting a helper that only did the regval calculation so that the new helper could also be used from pca954x_select_chan. > + } else { > + /* Disconnect multiplexer */ > + data->last_chan = 0; /* force the first selection */ These two comments should be combined. > + } > + return i2c_smbus_write_byte(client, data->last_chan); > +} > /* > * I2C init/probing/exit functions > */ > @@ -411,7 +430,6 @@ static int pca954x_probe(struct i2c_client *client, > struct i2c_adapter *adap = client->adapter; > struct device *dev = &client->dev; > struct device_node *np = dev->of_node; > - bool idle_disconnect_dt; > struct gpio_desc *gpio; > struct i2c_mux_core *muxc; > struct pca954x *data; > @@ -462,22 +480,18 @@ static int pca954x_probe(struct i2c_client *client, > } > } > > - /* Write the mux register at addr to verify > - * that the mux is in fact present. This also > - * initializes the mux to disconnected state. > - */ > - if (i2c_smbus_write_byte(client, 0) < 0) { > + if (of_property_read_u32(np, "idle-state", &data->idle_state)) > + data->idle_state = MUX_IDLE_AS_IS; > + > + if (of_property_read_bool(np, "i2c-mux-idle-disconnect")) > + data->idle_state = MUX_IDLE_DISCONNECT; I think you should ignore i2c-mux-idle-disconnect if idle-state is present. I.e. move this "if" statement into the body of the former "if". Also, you have broken things if np is NULL. Cheers, Peter > + > + ret = pca954x_init(client, data); > + if (ret < 0) { > dev_warn(dev, "probe failed\n"); > return -ENODEV; > } > > - data->last_chan = 0; /* force the first selection */ > - data->idle_state = MUX_IDLE_AS_IS; > - > - idle_disconnect_dt = np && > - of_property_read_bool(np, "i2c-mux-idle-disconnect"); > - if (idle_disconnect_dt) > - data->idle_state = MUX_IDLE_DISCONNECT; > > ret = pca954x_irq_setup(muxc); > if (ret) > @@ -531,8 +545,7 @@ static int pca954x_resume(struct device *dev) > struct i2c_mux_core *muxc = i2c_get_clientdata(client); > struct pca954x *data = i2c_mux_priv(muxc); > > - data->last_chan = 0; > - return i2c_smbus_write_byte(client, 0); > + return pca954x_init(client, data); > } > #endif > >