Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab88b97c authored by Peter Rosin's avatar Peter Rosin Committed by Wolfram Sang
Browse files

i2c: i2c-mux-pca9541: convert to use an explicit i2c mux core



Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.

Signed-off-by: default avatarPeter Rosin <peda@axentia.se>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 8aacd901
Loading
Loading
Loading
Loading
+27 −31
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@
#define SELECT_DELAY_LONG	1000

struct pca9541 {
	struct i2c_adapter *mux_adap;
	struct i2c_client *client;
	unsigned long select_timeout;
	unsigned long arb_timeout;
};
@@ -217,7 +217,8 @@ static const u8 pca9541_control[16] = {
 */
static int pca9541_arbitrate(struct i2c_client *client)
{
	struct pca9541 *data = i2c_get_clientdata(client);
	struct i2c_mux_core *muxc = i2c_get_clientdata(client);
	struct pca9541 *data = i2c_mux_priv(muxc);
	int reg;

	reg = pca9541_reg_read(client, PCA9541_CONTROL);
@@ -285,9 +286,10 @@ static int pca9541_arbitrate(struct i2c_client *client)
	return 0;
}

static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan)
static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
{
	struct pca9541 *data = i2c_get_clientdata(client);
	struct pca9541 *data = i2c_mux_priv(muxc);
	struct i2c_client *client = data->client;
	int ret;
	unsigned long timeout = jiffies + ARB2_TIMEOUT;
		/* give up after this time */
@@ -309,9 +311,11 @@ static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 chan)
	return -ETIMEDOUT;
}

static int pca9541_release_chan(struct i2c_adapter *adap,
				void *client, u32 chan)
static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
{
	struct pca9541 *data = i2c_mux_priv(muxc);
	struct i2c_client *client = data->client;

	pca9541_release_bus(client);
	return 0;
}
@@ -324,20 +328,13 @@ static int pca9541_probe(struct i2c_client *client,
{
	struct i2c_adapter *adap = client->adapter;
	struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
	struct i2c_mux_core *muxc;
	struct pca9541 *data;
	int force;
	int ret = -ENODEV;
	int ret;

	if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
		goto err;

	data = kzalloc(sizeof(struct pca9541), GFP_KERNEL);
	if (!data) {
		ret = -ENOMEM;
		goto err;
	}

	i2c_set_clientdata(client, data);
		return -ENODEV;

	/*
	 * I2C accesses are unprotected here.
@@ -352,34 +349,33 @@ static int pca9541_probe(struct i2c_client *client,
	force = 0;
	if (pdata)
		force = pdata->modes[0].adap_id;
	data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client,
					     force, 0, 0,
					     pca9541_select_chan,
					     pca9541_release_chan);
	muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), 0,
			     pca9541_select_chan, pca9541_release_chan);
	if (!muxc)
		return -ENOMEM;

	data = i2c_mux_priv(muxc);
	data->client = client;

	if (data->mux_adap == NULL) {
	i2c_set_clientdata(client, muxc);

	ret = i2c_mux_add_adapter(muxc, force, 0, 0);
	if (ret) {
		dev_err(&client->dev, "failed to register master selector\n");
		goto exit_free;
		return ret;
	}

	dev_info(&client->dev, "registered master selector for I2C %s\n",
		 client->name);

	return 0;

exit_free:
	kfree(data);
err:
	return ret;
}

static int pca9541_remove(struct i2c_client *client)
{
	struct pca9541 *data = i2c_get_clientdata(client);

	i2c_del_mux_adapter(data->mux_adap);
	struct i2c_mux_core *muxc = i2c_get_clientdata(client);

	kfree(data);
	i2c_mux_del_adapters(muxc);
	return 0;
}