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

Commit d62b98f3 authored by Peter Korsgaard's avatar Peter Korsgaard Committed by Grant Likely
Browse files

mcp23s08: isolate spi specific parts



Change spi member of struct mcp23s08 to be a ops-specific opaque data
pointer, and move spi specific knowledge out of mcp23s08_probe_one().

No functional change, but is needed to add i2c support.

Signed-off-by: default avatarPeter Korsgaard <jacmet@sunsite.dk>
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
parent 1bb6f9b0
Loading
Loading
Loading
Loading
+57 −24
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ struct mcp23s08_ops {
};

struct mcp23s08 {
	struct spi_device	*spi;
	u8			addr;

	u16			cache[11];
@@ -60,6 +59,7 @@ struct mcp23s08 {
	struct gpio_chip	chip;

	const struct mcp23s08_ops	*ops;
	void			*data; /* ops specific data */
};

/* A given spi_device can represent up to eight mcp23sxx chips
@@ -73,6 +73,8 @@ struct mcp23s08_driver_data {
	struct mcp23s08		chip[];
};

#ifdef CONFIG_SPI_MASTER

static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
{
	u8	tx[2], rx[1];
@@ -80,7 +82,7 @@ static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)

	tx[0] = mcp->addr | 0x01;
	tx[1] = reg;
	status = spi_write_then_read(mcp->spi, tx, sizeof tx, rx, sizeof rx);
	status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx);
	return (status < 0) ? status : rx[0];
}

@@ -91,7 +93,7 @@ static int mcp23s08_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
	tx[0] = mcp->addr;
	tx[1] = reg;
	tx[2] = val;
	return spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0);
	return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0);
}

static int
@@ -106,7 +108,7 @@ mcp23s08_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
	tx[1] = reg;

	tmp = (u8 *)vals;
	status = spi_write_then_read(mcp->spi, tx, sizeof tx, tmp, n);
	status = spi_write_then_read(mcp->data, tx, sizeof tx, tmp, n);
	if (status >= 0) {
		while (n--)
			vals[n] = tmp[n]; /* expand to 16bit */
@@ -121,7 +123,7 @@ static int mcp23s17_read(struct mcp23s08 *mcp, unsigned reg)

	tx[0] = mcp->addr | 0x01;
	tx[1] = reg << 1;
	status = spi_write_then_read(mcp->spi, tx, sizeof tx, rx, sizeof rx);
	status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx);
	return (status < 0) ? status : (rx[0] | (rx[1] << 8));
}

@@ -133,7 +135,7 @@ static int mcp23s17_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
	tx[1] = reg << 1;
	tx[2] = val;
	tx[3] = val >> 8;
	return spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0);
	return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0);
}

static int
@@ -147,7 +149,7 @@ mcp23s17_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
	tx[0] = mcp->addr | 0x01;
	tx[1] = reg << 1;

	status = spi_write_then_read(mcp->spi, tx, sizeof tx,
	status = spi_write_then_read(mcp->data, tx, sizeof tx,
				     (u8 *)vals, n * 2);
	if (status >= 0) {
		while (n--)
@@ -169,6 +171,7 @@ static const struct mcp23s08_ops mcp23s17_ops = {
	.read_regs	= mcp23s17_read_regs,
};

#endif /* CONFIG_SPI_MASTER */

/*----------------------------------------------------------------------*/

@@ -296,17 +299,16 @@ done:

/*----------------------------------------------------------------------*/

static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
			      void *data, unsigned addr,
			      unsigned type, unsigned base, unsigned pullups)
{
	struct mcp23s08_driver_data	*data = spi_get_drvdata(spi);
	struct mcp23s08			*mcp = data->mcp[addr];
	int status;

	mutex_init(&mcp->lock);

	mcp->spi = spi;
	mcp->addr = 0x40 | (addr << 1);
	mcp->data = data;
	mcp->addr = addr;

	mcp->chip.direction_input = mcp23s08_direction_input;
	mcp->chip.get = mcp23s08_get;
@@ -314,18 +316,29 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
	mcp->chip.set = mcp23s08_set;
	mcp->chip.dbg_show = mcp23s08_dbg_show;

	if (type == MCP_TYPE_S17) {
		mcp->ops = &mcp23s17_ops;
		mcp->chip.ngpio = 16;
		mcp->chip.label = "mcp23s17";
	} else {
	switch (type) {
#ifdef CONFIG_SPI_MASTER
	case MCP_TYPE_S08:
		mcp->ops = &mcp23s08_ops;
		mcp->chip.ngpio = 8;
		mcp->chip.label = "mcp23s08";
		break;

	case MCP_TYPE_S17:
		mcp->ops = &mcp23s17_ops;
		mcp->chip.ngpio = 16;
		mcp->chip.label = "mcp23s17";
		break;
#endif /* CONFIG_SPI_MASTER */

	default:
		dev_err(dev, "invalid device type (%d)\n", type);
		return -EINVAL;
	}

	mcp->chip.base = base;
	mcp->chip.can_sleep = 1;
	mcp->chip.dev = &spi->dev;
	mcp->chip.dev = dev;
	mcp->chip.owner = THIS_MODULE;

	/* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
@@ -371,11 +384,13 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
	status = gpiochip_add(&mcp->chip);
fail:
	if (status < 0)
		dev_dbg(&spi->dev, "can't setup chip %d, --> %d\n",
		dev_dbg(dev, "can't setup chip %d, --> %d\n",
			addr, status);
	return status;
}

#ifdef CONFIG_SPI_MASTER

static int mcp23s08_probe(struct spi_device *spi)
{
	struct mcp23s08_platform_data	*pdata;
@@ -418,7 +433,8 @@ static int mcp23s08_probe(struct spi_device *spi)
			continue;
		chips--;
		data->mcp[addr] = &data->chip[chips];
		status = mcp23s08_probe_one(spi, addr, type, base,
		status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
					    0x40 | (addr << 1), type, base,
					    pdata->chip[addr].pullups);
		if (status < 0)
			goto fail;
@@ -488,11 +504,28 @@ static struct spi_driver mcp23s08_driver = {
	},
};

static int __init mcp23s08_spi_init(void)
{
	return spi_register_driver(&mcp23s08_driver);
}

static void mcp23s08_spi_exit(void)
{
	spi_unregister_driver(&mcp23s08_driver);
}

#else

static int __init mcp23s08_spi_init(void) { return 0; }
static void mcp23s08_spi_exit(void) { }

#endif /* CONFIG_SPI_MASTER */

/*----------------------------------------------------------------------*/

static int __init mcp23s08_init(void)
{
	return spi_register_driver(&mcp23s08_driver);
	return mcp23s08_spi_init();
}
/* register after spi postcore initcall and before
 * subsys initcalls that may rely on these GPIOs
@@ -501,7 +534,7 @@ subsys_initcall(mcp23s08_init);

static void __exit mcp23s08_exit(void)
{
	spi_unregister_driver(&mcp23s08_driver);
	mcp23s08_spi_exit();
}
module_exit(mcp23s08_exit);