gpio-mcp23s08.c 24.2 KB
Newer Older
1
/*
2 3 4 5 6 7 8 9 10
 * MCP23S08 SPI/I2C GPIO gpio expander driver
 *
 * The inputs and outputs of the mcp23s08, mcp23s17, mcp23008 and mcp23017 are
 * supported.
 * For the I2C versions of the chips (mcp23008 and mcp23017) generation of
 * interrupts is also supported.
 * The hardware of the SPI versions of the chips (mcp23s08 and mcp23s17) is
 * also capable of generating interrupts, but the linux driver does not
 * support that yet.
11 12 13 14 15
 */

#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/mutex.h>
16
#include <linux/module.h>
17
#include <linux/gpio.h>
P
Peter Korsgaard 已提交
18
#include <linux/i2c.h>
19 20
#include <linux/spi/spi.h>
#include <linux/spi/mcp23s08.h>
21
#include <linux/slab.h>
22
#include <asm/byteorder.h>
23 24
#include <linux/interrupt.h>
#include <linux/of_irq.h>
25
#include <linux/of_device.h>
26

27 28 29 30 31
/**
 * MCP types supported by driver
 */
#define MCP_TYPE_S08	0
#define MCP_TYPE_S17	1
P
Peter Korsgaard 已提交
32 33
#define MCP_TYPE_008	2
#define MCP_TYPE_017	3
34 35 36 37 38 39 40 41 42 43 44 45

/* Registers are all 8 bits wide.
 *
 * The mcp23s17 has twice as many bits, and can be configured to work
 * with either 16 bit registers or with two adjacent 8 bit banks.
 */
#define MCP_IODIR	0x00		/* init/reset:  all ones */
#define MCP_IPOL	0x01
#define MCP_GPINTEN	0x02
#define MCP_DEFVAL	0x03
#define MCP_INTCON	0x04
#define MCP_IOCON	0x05
46
#	define IOCON_MIRROR	(1 << 6)
47 48 49 50 51 52 53 54 55 56
#	define IOCON_SEQOP	(1 << 5)
#	define IOCON_HAEN	(1 << 3)
#	define IOCON_ODR	(1 << 2)
#	define IOCON_INTPOL	(1 << 1)
#define MCP_GPPU	0x06
#define MCP_INTF	0x07
#define MCP_INTCAP	0x08
#define MCP_GPIO	0x09
#define MCP_OLAT	0x0a

57 58 59 60 61 62 63 64 65
struct mcp23s08;

struct mcp23s08_ops {
	int	(*read)(struct mcp23s08 *mcp, unsigned reg);
	int	(*write)(struct mcp23s08 *mcp, unsigned reg, unsigned val);
	int	(*read_regs)(struct mcp23s08 *mcp, unsigned reg,
			     u16 *vals, unsigned n);
};

66 67 68
struct mcp23s08 {
	u8			addr;

69
	u16			cache[11];
70 71 72 73
	u16			irq_rise;
	u16			irq_fall;
	int			irq;
	bool			irq_controller;
74 75
	/* lock protects the cached values */
	struct mutex		lock;
76 77
	struct mutex		irq_lock;
	struct irq_domain	*irq_domain;
78 79 80

	struct gpio_chip	chip;

81
	const struct mcp23s08_ops	*ops;
82
	void			*data; /* ops specific data */
83 84
};

85
/* A given spi_device can represent up to eight mcp23sxx chips
86 87 88 89 90 91
 * sharing the same chipselect but using different addresses
 * (e.g. chips #0 and #3 might be populated, but not #1 or $2).
 * Driver data holds all the per-chip data.
 */
struct mcp23s08_driver_data {
	unsigned		ngpio;
92
	struct mcp23s08		*mcp[8];
93 94 95
	struct mcp23s08		chip[];
};

96 97 98 99 100
/* This lock class tells lockdep that GPIO irqs are in a different
 * category than their parents, so it won't report false recursion.
 */
static struct lock_class_key gpio_lock_class;

P
Peter Korsgaard 已提交
101 102
/*----------------------------------------------------------------------*/

103
#if IS_ENABLED(CONFIG_I2C)
P
Peter Korsgaard 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166

static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg)
{
	return i2c_smbus_read_byte_data(mcp->data, reg);
}

static int mcp23008_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
{
	return i2c_smbus_write_byte_data(mcp->data, reg, val);
}

static int
mcp23008_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
{
	while (n--) {
		int ret = mcp23008_read(mcp, reg++);
		if (ret < 0)
			return ret;
		*vals++ = ret;
	}

	return 0;
}

static int mcp23017_read(struct mcp23s08 *mcp, unsigned reg)
{
	return i2c_smbus_read_word_data(mcp->data, reg << 1);
}

static int mcp23017_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
{
	return i2c_smbus_write_word_data(mcp->data, reg << 1, val);
}

static int
mcp23017_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
{
	while (n--) {
		int ret = mcp23017_read(mcp, reg++);
		if (ret < 0)
			return ret;
		*vals++ = ret;
	}

	return 0;
}

static const struct mcp23s08_ops mcp23008_ops = {
	.read		= mcp23008_read,
	.write		= mcp23008_write,
	.read_regs	= mcp23008_read_regs,
};

static const struct mcp23s08_ops mcp23017_ops = {
	.read		= mcp23017_read,
	.write		= mcp23017_write,
	.read_regs	= mcp23017_read_regs,
};

#endif /* CONFIG_I2C */

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

167 168
#ifdef CONFIG_SPI_MASTER

169 170 171 172 173 174 175
static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
{
	u8	tx[2], rx[1];
	int	status;

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

180
static int mcp23s08_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
181 182 183 184 185 186
{
	u8	tx[3];

	tx[0] = mcp->addr;
	tx[1] = reg;
	tx[2] = val;
187
	return spi_write_then_read(mcp->data, tx, sizeof(tx), NULL, 0);
188 189 190
}

static int
191
mcp23s08_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
192
{
193 194
	u8	tx[2], *tmp;
	int	status;
195

196
	if ((n + reg) > sizeof(mcp->cache))
197 198 199
		return -EINVAL;
	tx[0] = mcp->addr | 0x01;
	tx[1] = reg;
200 201

	tmp = (u8 *)vals;
202
	status = spi_write_then_read(mcp->data, tx, sizeof(tx), tmp, n);
203 204 205 206 207 208 209 210 211 212 213 214 215 216
	if (status >= 0) {
		while (n--)
			vals[n] = tmp[n]; /* expand to 16bit */
	}
	return status;
}

static int mcp23s17_read(struct mcp23s08 *mcp, unsigned reg)
{
	u8	tx[2], rx[2];
	int	status;

	tx[0] = mcp->addr | 0x01;
	tx[1] = reg << 1;
217
	status = spi_write_then_read(mcp->data, tx, sizeof(tx), rx, sizeof(rx));
218 219 220 221 222 223 224 225 226 227 228
	return (status < 0) ? status : (rx[0] | (rx[1] << 8));
}

static int mcp23s17_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
{
	u8	tx[4];

	tx[0] = mcp->addr;
	tx[1] = reg << 1;
	tx[2] = val;
	tx[3] = val >> 8;
229
	return spi_write_then_read(mcp->data, tx, sizeof(tx), NULL, 0);
230 231 232 233 234 235 236 237
}

static int
mcp23s17_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
{
	u8	tx[2];
	int	status;

238
	if ((n + reg) > sizeof(mcp->cache))
239 240 241 242
		return -EINVAL;
	tx[0] = mcp->addr | 0x01;
	tx[1] = reg << 1;

243
	status = spi_write_then_read(mcp->data, tx, sizeof(tx),
244 245 246 247 248 249 250
				     (u8 *)vals, n * 2);
	if (status >= 0) {
		while (n--)
			vals[n] = __le16_to_cpu((__le16)vals[n]);
	}

	return status;
251 252
}

253 254 255 256 257 258 259 260 261 262 263 264
static const struct mcp23s08_ops mcp23s08_ops = {
	.read		= mcp23s08_read,
	.write		= mcp23s08_write,
	.read_regs	= mcp23s08_read_regs,
};

static const struct mcp23s08_ops mcp23s17_ops = {
	.read		= mcp23s17_read,
	.write		= mcp23s17_write,
	.read_regs	= mcp23s17_read_regs,
};

265
#endif /* CONFIG_SPI_MASTER */
266

267 268 269 270 271 272 273 274 275
/*----------------------------------------------------------------------*/

static int mcp23s08_direction_input(struct gpio_chip *chip, unsigned offset)
{
	struct mcp23s08	*mcp = container_of(chip, struct mcp23s08, chip);
	int status;

	mutex_lock(&mcp->lock);
	mcp->cache[MCP_IODIR] |= (1 << offset);
276
	status = mcp->ops->write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]);
277 278 279 280 281 282 283 284 285 286 287 288
	mutex_unlock(&mcp->lock);
	return status;
}

static int mcp23s08_get(struct gpio_chip *chip, unsigned offset)
{
	struct mcp23s08	*mcp = container_of(chip, struct mcp23s08, chip);
	int status;

	mutex_lock(&mcp->lock);

	/* REVISIT reading this clears any IRQ ... */
289
	status = mcp->ops->read(mcp, MCP_GPIO);
290 291 292 293 294 295 296 297 298 299 300 301
	if (status < 0)
		status = 0;
	else {
		mcp->cache[MCP_GPIO] = status;
		status = !!(status & (1 << offset));
	}
	mutex_unlock(&mcp->lock);
	return status;
}

static int __mcp23s08_set(struct mcp23s08 *mcp, unsigned mask, int value)
{
302
	unsigned olat = mcp->cache[MCP_OLAT];
303 304 305 306 307 308

	if (value)
		olat |= mask;
	else
		olat &= ~mask;
	mcp->cache[MCP_OLAT] = olat;
309
	return mcp->ops->write(mcp, MCP_OLAT, olat);
310 311 312 313 314
}

static void mcp23s08_set(struct gpio_chip *chip, unsigned offset, int value)
{
	struct mcp23s08	*mcp = container_of(chip, struct mcp23s08, chip);
315
	unsigned mask = 1 << offset;
316 317 318 319 320 321 322 323 324 325

	mutex_lock(&mcp->lock);
	__mcp23s08_set(mcp, mask, value);
	mutex_unlock(&mcp->lock);
}

static int
mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value)
{
	struct mcp23s08	*mcp = container_of(chip, struct mcp23s08, chip);
326
	unsigned mask = 1 << offset;
327 328 329 330 331 332
	int status;

	mutex_lock(&mcp->lock);
	status = __mcp23s08_set(mcp, mask, value);
	if (status == 0) {
		mcp->cache[MCP_IODIR] &= ~mask;
333
		status = mcp->ops->write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]);
334 335 336 337 338
	}
	mutex_unlock(&mcp->lock);
	return status;
}

339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
/*----------------------------------------------------------------------*/
static irqreturn_t mcp23s08_irq(int irq, void *data)
{
	struct mcp23s08 *mcp = data;
	int intcap, intf, i;
	unsigned int child_irq;

	mutex_lock(&mcp->lock);
	intf = mcp->ops->read(mcp, MCP_INTF);
	if (intf < 0) {
		mutex_unlock(&mcp->lock);
		return IRQ_HANDLED;
	}

	mcp->cache[MCP_INTF] = intf;

	intcap = mcp->ops->read(mcp, MCP_INTCAP);
	if (intcap < 0) {
		mutex_unlock(&mcp->lock);
		return IRQ_HANDLED;
	}

	mcp->cache[MCP_INTCAP] = intcap;
	mutex_unlock(&mcp->lock);


	for (i = 0; i < mcp->chip.ngpio; i++) {
		if ((BIT(i) & mcp->cache[MCP_INTF]) &&
		    ((BIT(i) & intcap & mcp->irq_rise) ||
		     (mcp->irq_fall & ~intcap & BIT(i)))) {
			child_irq = irq_find_mapping(mcp->irq_domain, i);
			handle_nested_irq(child_irq);
		}
	}

	return IRQ_HANDLED;
}

static int mcp23s08_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
	struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip);

	return irq_find_mapping(mcp->irq_domain, offset);
}

static void mcp23s08_irq_mask(struct irq_data *data)
{
	struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
	unsigned int pos = data->hwirq;

	mcp->cache[MCP_GPINTEN] &= ~BIT(pos);
}

static void mcp23s08_irq_unmask(struct irq_data *data)
{
	struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
	unsigned int pos = data->hwirq;

	mcp->cache[MCP_GPINTEN] |= BIT(pos);
}

static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type)
{
	struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);
	unsigned int pos = data->hwirq;
	int status = 0;

	if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
		mcp->cache[MCP_INTCON] &= ~BIT(pos);
		mcp->irq_rise |= BIT(pos);
		mcp->irq_fall |= BIT(pos);
	} else if (type & IRQ_TYPE_EDGE_RISING) {
		mcp->cache[MCP_INTCON] &= ~BIT(pos);
		mcp->irq_rise |= BIT(pos);
		mcp->irq_fall &= ~BIT(pos);
	} else if (type & IRQ_TYPE_EDGE_FALLING) {
		mcp->cache[MCP_INTCON] &= ~BIT(pos);
		mcp->irq_rise &= ~BIT(pos);
		mcp->irq_fall |= BIT(pos);
	} else
		return -EINVAL;

	return status;
}

static void mcp23s08_irq_bus_lock(struct irq_data *data)
{
	struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);

	mutex_lock(&mcp->irq_lock);
}

static void mcp23s08_irq_bus_unlock(struct irq_data *data)
{
	struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);

	mutex_lock(&mcp->lock);
	mcp->ops->write(mcp, MCP_GPINTEN, mcp->cache[MCP_GPINTEN]);
	mcp->ops->write(mcp, MCP_DEFVAL, mcp->cache[MCP_DEFVAL]);
	mcp->ops->write(mcp, MCP_INTCON, mcp->cache[MCP_INTCON]);
	mutex_unlock(&mcp->lock);
	mutex_unlock(&mcp->irq_lock);
}

443
static int mcp23s08_irq_reqres(struct irq_data *data)
444 445 446
{
	struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);

447
	if (gpiochip_lock_as_irq(&mcp->chip, data->hwirq)) {
448 449 450
		dev_err(mcp->chip.dev,
			"unable to lock HW IRQ %lu for IRQ usage\n",
			data->hwirq);
451 452
		return -EINVAL;
	}
453 454 455 456

	return 0;
}

457
static void mcp23s08_irq_relres(struct irq_data *data)
458 459 460
{
	struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data);

461
	gpiochip_unlock_as_irq(&mcp->chip, data->hwirq);
462 463 464 465 466 467 468 469 470
}

static struct irq_chip mcp23s08_irq_chip = {
	.name = "gpio-mcp23xxx",
	.irq_mask = mcp23s08_irq_mask,
	.irq_unmask = mcp23s08_irq_unmask,
	.irq_set_type = mcp23s08_irq_set_type,
	.irq_bus_lock = mcp23s08_irq_bus_lock,
	.irq_bus_sync_unlock = mcp23s08_irq_bus_unlock,
471 472
	.irq_request_resources = mcp23s08_irq_reqres,
	.irq_release_resources = mcp23s08_irq_relres,
473 474 475 476 477 478 479 480 481
};

static int mcp23s08_irq_setup(struct mcp23s08 *mcp)
{
	struct gpio_chip *chip = &mcp->chip;
	int err, irq, j;

	mutex_init(&mcp->irq_lock);

482
	mcp->irq_domain = irq_domain_add_linear(chip->dev->of_node, chip->ngpio,
483 484 485 486 487
						&irq_domain_simple_ops, mcp);
	if (!mcp->irq_domain)
		return -ENODEV;

	err = devm_request_threaded_irq(chip->dev, mcp->irq, NULL, mcp23s08_irq,
488 489
					IRQF_TRIGGER_LOW | IRQF_ONESHOT |
					IRQF_SHARED,
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
					dev_name(chip->dev), mcp);
	if (err != 0) {
		dev_err(chip->dev, "unable to request IRQ#%d: %d\n",
			mcp->irq, err);
		return err;
	}

	chip->to_irq = mcp23s08_gpio_to_irq;

	for (j = 0; j < mcp->chip.ngpio; j++) {
		irq = irq_create_mapping(mcp->irq_domain, j);
		irq_set_lockdep_class(irq, &gpio_lock_class);
		irq_set_chip_data(irq, mcp);
		irq_set_chip(irq, &mcp23s08_irq_chip);
		irq_set_nested_thread(irq, true);
#ifdef CONFIG_ARM
		set_irq_flags(irq, IRQF_VALID);
#else
		irq_set_noprobe(irq);
#endif
	}
	return 0;
}

static void mcp23s08_irq_teardown(struct mcp23s08 *mcp)
{
	unsigned int irq, i;

	for (i = 0; i < mcp->chip.ngpio; i++) {
		irq = irq_find_mapping(mcp->irq_domain, i);
		if (irq > 0)
			irq_dispose_mapping(irq);
	}

	irq_domain_remove(mcp->irq_domain);
}

527 528 529 530 531 532 533 534 535 536 537 538 539 540
/*----------------------------------------------------------------------*/

#ifdef CONFIG_DEBUG_FS

#include <linux/seq_file.h>

/*
 * This shows more info than the generic gpio dump code:
 * pullups, deglitching, open drain drive.
 */
static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
	struct mcp23s08	*mcp;
	char		bank;
R
Roel Kluin 已提交
541
	int		t;
542 543 544 545 546
	unsigned	mask;

	mcp = container_of(chip, struct mcp23s08, chip);

	/* NOTE: we only handle one bank for now ... */
547
	bank = '0' + ((mcp->addr >> 1) & 0x7);
548 549

	mutex_lock(&mcp->lock);
550
	t = mcp->ops->read_regs(mcp, 0, mcp->cache, ARRAY_SIZE(mcp->cache));
551 552 553 554 555
	if (t < 0) {
		seq_printf(s, " I/O ERROR %d\n", t);
		goto done;
	}

556
	for (t = 0, mask = 1; t < chip->ngpio; t++, mask <<= 1) {
557 558 559 560 561 562 563 564 565 566
		const char	*label;

		label = gpiochip_is_requested(chip, t);
		if (!label)
			continue;

		seq_printf(s, " gpio-%-3d P%c.%d (%-12s) %s %s %s",
			chip->base + t, bank, t, label,
			(mcp->cache[MCP_IODIR] & mask) ? "in " : "out",
			(mcp->cache[MCP_GPIO] & mask) ? "hi" : "lo",
567
			(mcp->cache[MCP_GPPU] & mask) ? "up" : "  ");
568
		/* NOTE:  ignoring the irq-related registers */
569
		seq_puts(s, "\n");
570 571 572 573 574 575 576 577 578 579 580
	}
done:
	mutex_unlock(&mcp->lock);
}

#else
#define mcp23s08_dbg_show	NULL
#endif

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

581
static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
582
			      void *data, unsigned addr, unsigned type,
583
			      struct mcp23s08_platform_data *pdata, int cs)
584
{
585
	int status;
586
	bool mirror = false;
587 588 589

	mutex_init(&mcp->lock);

590 591
	mcp->data = data;
	mcp->addr = addr;
592 593 594 595 596 597

	mcp->chip.direction_input = mcp23s08_direction_input;
	mcp->chip.get = mcp23s08_get;
	mcp->chip.direction_output = mcp23s08_direction_output;
	mcp->chip.set = mcp23s08_set;
	mcp->chip.dbg_show = mcp23s08_dbg_show;
598 599 600 601
#ifdef CONFIG_OF
	mcp->chip.of_gpio_n_cells = 2;
	mcp->chip.of_node = dev->of_node;
#endif
602

603 604 605
	switch (type) {
#ifdef CONFIG_SPI_MASTER
	case MCP_TYPE_S08:
606 607 608
		mcp->ops = &mcp23s08_ops;
		mcp->chip.ngpio = 8;
		mcp->chip.label = "mcp23s08";
609 610 611 612 613 614 615 616 617
		break;

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

618
#if IS_ENABLED(CONFIG_I2C)
P
Peter Korsgaard 已提交
619 620 621 622 623 624 625 626 627 628 629 630 631
	case MCP_TYPE_008:
		mcp->ops = &mcp23008_ops;
		mcp->chip.ngpio = 8;
		mcp->chip.label = "mcp23008";
		break;

	case MCP_TYPE_017:
		mcp->ops = &mcp23017_ops;
		mcp->chip.ngpio = 16;
		mcp->chip.label = "mcp23017";
		break;
#endif /* CONFIG_I2C */

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

637
	mcp->chip.base = pdata->base;
638
	mcp->chip.can_sleep = true;
639
	mcp->chip.dev = dev;
640
	mcp->chip.owner = THIS_MODULE;
641

642 643 644
	/* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
	 * and MCP_IOCON.HAEN = 1, so we work with all chips.
	 */
645

646
	status = mcp->ops->read(mcp, MCP_IOCON);
647 648
	if (status < 0)
		goto fail;
649

650
	mcp->irq_controller = pdata->irq_controller;
651
	if (mcp->irq && mcp->irq_controller && (type == MCP_TYPE_017))
652
		mirror = pdata->mirror;
653 654

	if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror) {
655 656 657
		/* mcp23s17 has IOCON twice, make sure they are in sync */
		status &= ~(IOCON_SEQOP | (IOCON_SEQOP << 8));
		status |= IOCON_HAEN | (IOCON_HAEN << 8);
658 659 660 661
		status &= ~(IOCON_INTPOL | (IOCON_INTPOL << 8));
		if (mirror)
			status |= IOCON_MIRROR | (IOCON_MIRROR << 8);

662
		status = mcp->ops->write(mcp, MCP_IOCON, status);
663 664 665 666 667
		if (status < 0)
			goto fail;
	}

	/* configure ~100K pullups */
668
	status = mcp->ops->write(mcp, MCP_GPPU, pdata->chip[cs].pullups);
669 670 671
	if (status < 0)
		goto fail;

672
	status = mcp->ops->read_regs(mcp, 0, mcp->cache, ARRAY_SIZE(mcp->cache));
673 674 675 676 677 678
	if (status < 0)
		goto fail;

	/* disable inverter on input */
	if (mcp->cache[MCP_IPOL] != 0) {
		mcp->cache[MCP_IPOL] = 0;
679 680 681
		status = mcp->ops->write(mcp, MCP_IPOL, 0);
		if (status < 0)
			goto fail;
682 683 684 685 686
	}

	/* disable irqs */
	if (mcp->cache[MCP_GPINTEN] != 0) {
		mcp->cache[MCP_GPINTEN] = 0;
687
		status = mcp->ops->write(mcp, MCP_GPINTEN, 0);
688 689
		if (status < 0)
			goto fail;
690 691 692
	}

	status = gpiochip_add(&mcp->chip);
693 694 695 696 697 698 699 700 701 702
	if (status < 0)
		goto fail;

	if (mcp->irq && mcp->irq_controller) {
		status = mcp23s08_irq_setup(mcp);
		if (status) {
			mcp23s08_irq_teardown(mcp);
			goto fail;
		}
	}
703 704
fail:
	if (status < 0)
705 706
		dev_dbg(dev, "can't setup chip %d, --> %d\n",
			addr, status);
707 708 709
	return status;
}

P
Peter Korsgaard 已提交
710 711
/*----------------------------------------------------------------------*/

712 713
#ifdef CONFIG_OF
#ifdef CONFIG_SPI_MASTER
714
static const struct of_device_id mcp23s08_spi_of_match[] = {
715
	{
716 717
		.compatible = "microchip,mcp23s08",
		.data = (void *) MCP_TYPE_S08,
718 719
	},
	{
720 721 722 723 724 725 726 727 728 729 730
		.compatible = "microchip,mcp23s17",
		.data = (void *) MCP_TYPE_S17,
	},
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
	{
		.compatible = "mcp,mcp23s08",
		.data = (void *) MCP_TYPE_S08,
	},
	{
		.compatible = "mcp,mcp23s17",
		.data = (void *) MCP_TYPE_S17,
731 732 733 734 735 736 737
	},
	{ },
};
MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match);
#endif

#if IS_ENABLED(CONFIG_I2C)
738
static const struct of_device_id mcp23s08_i2c_of_match[] = {
739
	{
740 741
		.compatible = "microchip,mcp23008",
		.data = (void *) MCP_TYPE_008,
742 743
	},
	{
744 745 746 747 748 749 750 751 752 753 754
		.compatible = "microchip,mcp23017",
		.data = (void *) MCP_TYPE_017,
	},
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
	{
		.compatible = "mcp,mcp23008",
		.data = (void *) MCP_TYPE_008,
	},
	{
		.compatible = "mcp,mcp23017",
		.data = (void *) MCP_TYPE_017,
755 756 757 758 759 760 761 762
	},
	{ },
};
MODULE_DEVICE_TABLE(of, mcp23s08_i2c_of_match);
#endif
#endif /* CONFIG_OF */


763
#if IS_ENABLED(CONFIG_I2C)
P
Peter Korsgaard 已提交
764

B
Bill Pemberton 已提交
765
static int mcp230xx_probe(struct i2c_client *client,
P
Peter Korsgaard 已提交
766 767
				    const struct i2c_device_id *id)
{
768
	struct mcp23s08_platform_data *pdata, local_pdata;
P
Peter Korsgaard 已提交
769
	struct mcp23s08 *mcp;
770
	int status;
771 772 773 774
	const struct of_device_id *match;

	match = of_match_device(of_match_ptr(mcp23s08_i2c_of_match),
					&client->dev);
775 776 777 778 779 780 781 782 783
	if (match) {
		pdata = &local_pdata;
		pdata->base = -1;
		pdata->chip[0].pullups = 0;
		pdata->irq_controller =	of_property_read_bool(
					client->dev.of_node,
					"interrupt-controller");
		pdata->mirror = of_property_read_bool(client->dev.of_node,
						      "microchip,irq-mirror");
784
		client->irq = irq_of_parse_and_map(client->dev.of_node, 0);
785
	} else {
786 787
		pdata = dev_get_platdata(&client->dev);
		if (!pdata || !gpio_is_valid(pdata->base)) {
788
			dev_dbg(&client->dev, "invalid platform data\n");
789 790
			return -EINVAL;
		}
P
Peter Korsgaard 已提交
791 792
	}

793
	mcp = kzalloc(sizeof(*mcp), GFP_KERNEL);
P
Peter Korsgaard 已提交
794 795 796
	if (!mcp)
		return -ENOMEM;

797
	mcp->irq = client->irq;
P
Peter Korsgaard 已提交
798
	status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr,
799
				    id->driver_data, pdata, 0);
P
Peter Korsgaard 已提交
800 801 802 803 804 805 806 807 808 809 810 811 812
	if (status)
		goto fail;

	i2c_set_clientdata(client, mcp);

	return 0;

fail:
	kfree(mcp);

	return status;
}

B
Bill Pemberton 已提交
813
static int mcp230xx_remove(struct i2c_client *client)
P
Peter Korsgaard 已提交
814 815 816
{
	struct mcp23s08 *mcp = i2c_get_clientdata(client);

817 818 819
	if (client->irq && mcp->irq_controller)
		mcp23s08_irq_teardown(mcp);

820 821
	gpiochip_remove(&mcp->chip);
	kfree(mcp);
P
Peter Korsgaard 已提交
822

823
	return 0;
P
Peter Korsgaard 已提交
824 825 826 827 828 829 830 831 832 833 834 835 836
}

static const struct i2c_device_id mcp230xx_id[] = {
	{ "mcp23008", MCP_TYPE_008 },
	{ "mcp23017", MCP_TYPE_017 },
	{ },
};
MODULE_DEVICE_TABLE(i2c, mcp230xx_id);

static struct i2c_driver mcp230xx_driver = {
	.driver = {
		.name	= "mcp230xx",
		.owner	= THIS_MODULE,
837
		.of_match_table = of_match_ptr(mcp23s08_i2c_of_match),
P
Peter Korsgaard 已提交
838 839
	},
	.probe		= mcp230xx_probe,
B
Bill Pemberton 已提交
840
	.remove		= mcp230xx_remove,
P
Peter Korsgaard 已提交
841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862
	.id_table	= mcp230xx_id,
};

static int __init mcp23s08_i2c_init(void)
{
	return i2c_add_driver(&mcp230xx_driver);
}

static void mcp23s08_i2c_exit(void)
{
	i2c_del_driver(&mcp230xx_driver);
}

#else

static int __init mcp23s08_i2c_init(void) { return 0; }
static void mcp23s08_i2c_exit(void) { }

#endif /* CONFIG_I2C */

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

863 864
#ifdef CONFIG_SPI_MASTER

865 866
static int mcp23s08_probe(struct spi_device *spi)
{
867
	struct mcp23s08_platform_data	*pdata, local_pdata;
868
	unsigned			addr;
869
	int				chips = 0;
870
	struct mcp23s08_driver_data	*data;
871
	int				status, type;
872
	unsigned			ngpio = 0;
873 874 875 876 877
	const struct			of_device_id *match;
	u32				spi_present_mask = 0;

	match = of_match_device(of_match_ptr(mcp23s08_spi_of_match), &spi->dev);
	if (match) {
878
		type = (int)(uintptr_t)match->data;
879
		status = of_property_read_u32(spi->dev.of_node,
880
			    "microchip,spi-present-mask", &spi_present_mask);
881
		if (status) {
882 883 884 885 886 887 888
			status = of_property_read_u32(spi->dev.of_node,
				    "mcp,spi-present-mask", &spi_present_mask);
			if (status) {
				dev_err(&spi->dev,
					"DT has no spi-present-mask\n");
				return -ENODEV;
			}
889 890 891 892 893
		}
		if ((spi_present_mask <= 0) || (spi_present_mask >= 256)) {
			dev_err(&spi->dev, "invalid spi-present-mask\n");
			return -ENODEV;
		}
894

895 896
		pdata = &local_pdata;
		pdata->base = -1;
897
		for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
898
			pdata->chip[addr].pullups = 0;
899 900
			if (spi_present_mask & (1 << addr))
				chips++;
901
		}
902 903 904 905 906
		pdata->irq_controller =	of_property_read_bool(
					spi->dev.of_node,
					"interrupt-controller");
		pdata->mirror = of_property_read_bool(spi->dev.of_node,
						      "microchip,irq-mirror");
907 908
	} else {
		type = spi_get_device_id(spi)->driver_data;
J
Jingoo Han 已提交
909
		pdata = dev_get_platdata(&spi->dev);
910 911 912
		if (!pdata || !gpio_is_valid(pdata->base)) {
			dev_dbg(&spi->dev,
					"invalid or missing platform data\n");
913 914
			return -EINVAL;
		}
915 916 917 918 919 920 921 922 923 924 925 926

		for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
			if (!pdata->chip[addr].is_present)
				continue;
			chips++;
			if ((type == MCP_TYPE_S08) && (addr > 3)) {
				dev_err(&spi->dev,
					"mcp23s08 only supports address 0..3\n");
				return -EINVAL;
			}
			spi_present_mask |= 1 << addr;
		}
927 928
	}

929 930 931
	if (!chips)
		return -ENODEV;

932
	data = kzalloc(sizeof(*data) + chips * sizeof(struct mcp23s08),
933 934 935 936 937
			GFP_KERNEL);
	if (!data)
		return -ENOMEM;
	spi_set_drvdata(spi, data);

938
	for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
939
		if (!(spi_present_mask & (1 << addr)))
940 941 942
			continue;
		chips--;
		data->mcp[addr] = &data->chip[chips];
943
		status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
944 945
					    0x40 | (addr << 1), type, pdata,
					    addr);
946 947
		if (status < 0)
			goto fail;
948

949 950
		if (pdata->base != -1)
			pdata->base += (type == MCP_TYPE_S17) ? 16 : 8;
951
		ngpio += (type == MCP_TYPE_S17) ? 16 : 8;
952
	}
953
	data->ngpio = ngpio;
954 955 956 957 958 959 960 961 962

	/* NOTE:  these chips have a relatively sane IRQ framework, with
	 * per-signal masking and level/edge triggering.  It's not yet
	 * handled here...
	 */

	return 0;

fail:
963
	for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
964 965 966

		if (!data->mcp[addr])
			continue;
967
		gpiochip_remove(&data->mcp[addr]->chip);
968 969
	}
	kfree(data);
970 971 972 973 974
	return status;
}

static int mcp23s08_remove(struct spi_device *spi)
{
975 976
	struct mcp23s08_driver_data	*data = spi_get_drvdata(spi);
	unsigned			addr;
977

978
	for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
979 980 981 982

		if (!data->mcp[addr])
			continue;

983
		gpiochip_remove(&data->mcp[addr]->chip);
984
	}
985 986
	kfree(data);
	return 0;
987 988
}

989 990 991 992 993 994 995
static const struct spi_device_id mcp23s08_ids[] = {
	{ "mcp23s08", MCP_TYPE_S08 },
	{ "mcp23s17", MCP_TYPE_S17 },
	{ },
};
MODULE_DEVICE_TABLE(spi, mcp23s08_ids);

996 997 998
static struct spi_driver mcp23s08_driver = {
	.probe		= mcp23s08_probe,
	.remove		= mcp23s08_remove,
999
	.id_table	= mcp23s08_ids,
1000 1001 1002
	.driver = {
		.name	= "mcp23s08",
		.owner	= THIS_MODULE,
1003
		.of_match_table = of_match_ptr(mcp23s08_spi_of_match),
1004 1005 1006
	},
};

1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
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 */

1024 1025 1026 1027
/*----------------------------------------------------------------------*/

static int __init mcp23s08_init(void)
{
P
Peter Korsgaard 已提交
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
	int ret;

	ret = mcp23s08_spi_init();
	if (ret)
		goto spi_fail;

	ret = mcp23s08_i2c_init();
	if (ret)
		goto i2c_fail;

	return 0;

 i2c_fail:
	mcp23s08_spi_exit();
 spi_fail:
	return ret;
1044
}
P
Peter Korsgaard 已提交
1045
/* register after spi/i2c postcore initcall and before
1046 1047 1048
 * subsys initcalls that may rely on these GPIOs
 */
subsys_initcall(mcp23s08_init);
1049 1050 1051

static void __exit mcp23s08_exit(void)
{
1052
	mcp23s08_spi_exit();
P
Peter Korsgaard 已提交
1053
	mcp23s08_i2c_exit();
1054 1055 1056 1057
}
module_exit(mcp23s08_exit);

MODULE_LICENSE("GPL");