#define MCP_TYPE_S17 1
#define MCP_TYPE_008 2
#define MCP_TYPE_017 3
+#define MCP_TYPE_S18 4
/* Registers are all 8 bits wide.
*
# define IOCON_HAEN (1 << 3)
# define IOCON_ODR (1 << 2)
# define IOCON_INTPOL (1 << 1)
+# define IOCON_INTCC (1)
#define MCP_GPPU 0x06
#define MCP_INTF 0x07
#define MCP_INTCAP 0x08
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23s17";
break;
+
+ case MCP_TYPE_S18:
+ mcp->ops = &mcp23s17_ops;
+ mcp->chip.ngpio = 16;
+ mcp->chip.label = "mcp23s18";
+ break;
#endif /* CONFIG_SPI_MASTER */
#if IS_ENABLED(CONFIG_I2C)
of_property_read_bool(mcp->chip.parent->of_node,
"microchip,irq-active-high");
- if (type == MCP_TYPE_017)
- mirror = pdata->mirror;
+ mirror = pdata->mirror;
}
if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror ||
if (mirror)
status |= IOCON_MIRROR | (IOCON_MIRROR << 8);
+ if (type == MCP_TYPE_S18)
+ status |= IOCON_INTCC | (IOCON_INTCC << 8);
+
status = mcp->ops->write(mcp, MCP_IOCON, status);
if (status < 0)
goto fail;
.compatible = "microchip,mcp23s17",
.data = (void *) MCP_TYPE_S17,
},
+ {
+ .compatible = "microchip,mcp23s18",
+ .data = (void *) MCP_TYPE_S18,
+ },
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
{
.compatible = "mcp,mcp23s08",
pdata = devm_kzalloc(&client->dev,
sizeof(struct mcp23s08_platform_data),
GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
pdata->base = -1;
}
}
goto fail;
if (pdata->base != -1)
- pdata->base += (type == MCP_TYPE_S17) ? 16 : 8;
- ngpio += (type == MCP_TYPE_S17) ? 16 : 8;
+ pdata->base += data->mcp[addr]->chip.ngpio;
+ ngpio += data->mcp[addr]->chip.ngpio;
}
data->ngpio = ngpio;
static const struct spi_device_id mcp23s08_ids[] = {
{ "mcp23s08", MCP_TYPE_S08 },
{ "mcp23s17", MCP_TYPE_S17 },
+ { "mcp23s18", MCP_TYPE_S18 },
{ },
};
MODULE_DEVICE_TABLE(spi, mcp23s08_ids);