brintos

brintos / linux-shallow public Read only

0
0
Text · 15.2 KiB · efafc05 Raw
609 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P. */3 4#include <linux/err.h>5#include <linux/io.h>6#include <linux/i2c.h>7#include <linux/mod_devicetable.h>8#include <linux/module.h>9#include <linux/platform_device.h>10#include <linux/regmap.h>11#include <linux/mfd/syscon.h>12 13#define GXP_MAX_I2C_ENGINE 1014static const char * const gxp_i2c_name[] = {15	"gxp-i2c0", "gxp-i2c1", "gxp-i2c2", "gxp-i2c3",16	"gxp-i2c4", "gxp-i2c5", "gxp-i2c6", "gxp-i2c7",17	"gxp-i2c8", "gxp-i2c9" };18 19/* GXP I2C Global interrupt status/enable register*/20#define GXP_I2CINTSTAT		0x0021#define GXP_I2CINTEN		0x0422 23/* GXP I2C registers */24#define GXP_I2CSTAT		0x0025#define MASK_STOP_EVENT		0x2026#define MASK_ACK		0x0827#define MASK_RW			0x0428#define GXP_I2CEVTERR		0x0129#define MASK_SLAVE_CMD_EVENT	0x0130#define MASK_SLAVE_DATA_EVENT	0x0231#define MASK_MASTER_EVENT	0x1032#define GXP_I2CSNPDAT		0x0233#define GXP_I2CMCMD		0x0434#define GXP_I2CSCMD		0x0635#define GXP_I2CSNPAA		0x0936#define GXP_I2CADVFEAT		0x0A37#define GXP_I2COWNADR		0x0B38#define GXP_I2CFREQDIV		0x0C39#define GXP_I2CFLTFAIR		0x0D40#define GXP_I2CTMOEDG		0x0E41#define GXP_I2CCYCTIM		0x0F42 43/* I2CSCMD Bits */44#define SNOOP_EVT_CLR		0x8045#define SLAVE_EVT_CLR		0x4046#define	SNOOP_EVT_MASK		0x2047#define SLAVE_EVT_MASK		0x1048#define SLAVE_ACK_ENAB		0x0849#define SLAVE_EVT_STALL		0x0150 51/* I2CMCMD Bits */52#define MASTER_EVT_CLR		0x8053#define MASTER_ACK_ENAB		0x0854#define RW_CMD			0x0455#define STOP_CMD		0x0256#define START_CMD		0x0157 58/* I2CTMOEDG value */59#define GXP_DATA_EDGE_RST_CTRL	0x0a /* 30ns */60 61/* I2CFLTFAIR Bits */62#define FILTER_CNT		0x3063#define FAIRNESS_CNT		0x0264 65enum {66	GXP_I2C_IDLE = 0,67	GXP_I2C_ADDR_PHASE,68	GXP_I2C_RDATA_PHASE,69	GXP_I2C_WDATA_PHASE,70	GXP_I2C_ADDR_NACK,71	GXP_I2C_DATA_NACK,72	GXP_I2C_ERROR,73	GXP_I2C_COMP74};75 76struct gxp_i2c_drvdata {77	struct device *dev;78	void __iomem *base;79	struct i2c_timings t;80	u32 engine;81	int irq;82	struct completion completion;83	struct i2c_adapter adapter;84	struct i2c_msg *curr_msg;85	int msgs_remaining;86	int msgs_num;87	u8 *buf;88	size_t buf_remaining;89	unsigned char state;90	struct i2c_client *slave;91	unsigned char stopped;92};93 94static struct regmap *i2cg_map;95 96static void gxp_i2c_start(struct gxp_i2c_drvdata *drvdata)97{98	u16 value;99 100	drvdata->buf = drvdata->curr_msg->buf;101	drvdata->buf_remaining = drvdata->curr_msg->len;102 103	/* Note: Address in struct i2c_msg is 7 bits */104	value = drvdata->curr_msg->addr << 9;105 106	/* Read or Write */107	value |= drvdata->curr_msg->flags & I2C_M_RD ? RW_CMD | START_CMD : START_CMD;108 109	drvdata->state = GXP_I2C_ADDR_PHASE;110	writew(value, drvdata->base + GXP_I2CMCMD);111}112 113static int gxp_i2c_master_xfer(struct i2c_adapter *adapter,114			       struct i2c_msg *msgs, int num)115{116	int ret;117	struct gxp_i2c_drvdata *drvdata = i2c_get_adapdata(adapter);118	unsigned long time_left;119 120	drvdata->msgs_remaining = num;121	drvdata->curr_msg = msgs;122	drvdata->msgs_num = num;123	reinit_completion(&drvdata->completion);124 125	gxp_i2c_start(drvdata);126 127	time_left = wait_for_completion_timeout(&drvdata->completion,128						adapter->timeout);129	ret = num - drvdata->msgs_remaining;130	if (time_left == 0)131		return -ETIMEDOUT;132 133	if (drvdata->state == GXP_I2C_ADDR_NACK)134		return -ENXIO;135 136	if (drvdata->state == GXP_I2C_DATA_NACK)137		return -EIO;138 139	return ret;140}141 142static u32 gxp_i2c_func(struct i2c_adapter *adap)143{144	if (IS_ENABLED(CONFIG_I2C_SLAVE))145		return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SLAVE;146 147	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;148}149 150#if IS_ENABLED(CONFIG_I2C_SLAVE)151static int gxp_i2c_reg_slave(struct i2c_client *slave)152{153	struct gxp_i2c_drvdata *drvdata = i2c_get_adapdata(slave->adapter);154 155	if (drvdata->slave)156		return -EBUSY;157 158	if (slave->flags & I2C_CLIENT_TEN)159		return -EAFNOSUPPORT;160 161	drvdata->slave = slave;162 163	writeb(slave->addr << 1, drvdata->base + GXP_I2COWNADR);164	writeb(SLAVE_EVT_CLR | SNOOP_EVT_MASK | SLAVE_ACK_ENAB |165	       SLAVE_EVT_STALL, drvdata->base + GXP_I2CSCMD);166 167	return 0;168}169 170static int gxp_i2c_unreg_slave(struct i2c_client *slave)171{172	struct gxp_i2c_drvdata *drvdata = i2c_get_adapdata(slave->adapter);173 174	WARN_ON(!drvdata->slave);175 176	writeb(0x00, drvdata->base + GXP_I2COWNADR);177	writeb(SNOOP_EVT_CLR | SLAVE_EVT_CLR | SNOOP_EVT_MASK |178	       SLAVE_EVT_MASK, drvdata->base + GXP_I2CSCMD);179 180	drvdata->slave = NULL;181 182	return 0;183}184#endif185 186static const struct i2c_algorithm gxp_i2c_algo = {187	.master_xfer   = gxp_i2c_master_xfer,188	.functionality = gxp_i2c_func,189#if IS_ENABLED(CONFIG_I2C_SLAVE)190	.reg_slave     = gxp_i2c_reg_slave,191	.unreg_slave   = gxp_i2c_unreg_slave,192#endif193};194 195static void gxp_i2c_stop(struct gxp_i2c_drvdata *drvdata)196{197	/* Clear event and send stop */198	writeb(MASTER_EVT_CLR | STOP_CMD, drvdata->base + GXP_I2CMCMD);199 200	complete(&drvdata->completion);201}202 203static void gxp_i2c_restart(struct gxp_i2c_drvdata *drvdata)204{205	u16 value;206 207	drvdata->buf = drvdata->curr_msg->buf;208	drvdata->buf_remaining = drvdata->curr_msg->len;209 210	value = drvdata->curr_msg->addr << 9;211 212	if (drvdata->curr_msg->flags & I2C_M_RD) {213		/* Read and clear master event */214		value |= MASTER_EVT_CLR | RW_CMD | START_CMD;215	} else {216		/* Write and clear master event */217		value |= MASTER_EVT_CLR | START_CMD;218	}219 220	drvdata->state = GXP_I2C_ADDR_PHASE;221 222	writew(value, drvdata->base + GXP_I2CMCMD);223}224 225static void gxp_i2c_chk_addr_ack(struct gxp_i2c_drvdata *drvdata)226{227	u16 value;228 229	value = readb(drvdata->base + GXP_I2CSTAT);230	if (!(value & MASK_ACK)) {231		/* Got no ack, stop */232		drvdata->state = GXP_I2C_ADDR_NACK;233		gxp_i2c_stop(drvdata);234		return;235	}236 237	if (drvdata->curr_msg->flags & I2C_M_RD) {238		/* Start to read data from slave */239		if (drvdata->buf_remaining == 0) {240			/* No more data to read, stop */241			drvdata->msgs_remaining--;242			drvdata->state = GXP_I2C_COMP;243			gxp_i2c_stop(drvdata);244			return;245		}246		drvdata->state = GXP_I2C_RDATA_PHASE;247 248		if (drvdata->buf_remaining == 1) {249			/* The last data, do not ack */250			writeb(MASTER_EVT_CLR | RW_CMD,251			       drvdata->base + GXP_I2CMCMD);252		} else {253			/* Read data and ack it */254			writeb(MASTER_EVT_CLR | MASTER_ACK_ENAB |255			       RW_CMD, drvdata->base + GXP_I2CMCMD);256		}257	} else {258		/* Start to write first data to slave */259		if (drvdata->buf_remaining == 0) {260			/* No more data to write, stop */261			drvdata->msgs_remaining--;262			drvdata->state = GXP_I2C_COMP;263			gxp_i2c_stop(drvdata);264			return;265		}266		value = *drvdata->buf;267		value = value << 8;268		/* Clear master event */269		value |= MASTER_EVT_CLR;270		drvdata->buf++;271		drvdata->buf_remaining--;272		drvdata->state = GXP_I2C_WDATA_PHASE;273		writew(value, drvdata->base + GXP_I2CMCMD);274	}275}276 277static void gxp_i2c_ack_data(struct gxp_i2c_drvdata *drvdata)278{279	u8 value;280 281	/* Store the data returned */282	value = readb(drvdata->base + GXP_I2CSNPDAT);283	*drvdata->buf = value;284	drvdata->buf++;285	drvdata->buf_remaining--;286 287	if (drvdata->buf_remaining == 0) {288		/* No more data, this message is completed. */289		drvdata->msgs_remaining--;290 291		if (drvdata->msgs_remaining == 0) {292			/* No more messages, stop */293			drvdata->state = GXP_I2C_COMP;294			gxp_i2c_stop(drvdata);295			return;296		}297		/* Move to next message and start transfer */298		drvdata->curr_msg++;299		gxp_i2c_restart(drvdata);300		return;301	}302 303	/* Ack the slave to make it send next byte */304	drvdata->state = GXP_I2C_RDATA_PHASE;305	if (drvdata->buf_remaining == 1) {306		/* The last data, do not ack */307		writeb(MASTER_EVT_CLR | RW_CMD,308		       drvdata->base + GXP_I2CMCMD);309	} else {310		/* Read data and ack it */311		writeb(MASTER_EVT_CLR | MASTER_ACK_ENAB |312		       RW_CMD, drvdata->base + GXP_I2CMCMD);313	}314}315 316static void gxp_i2c_chk_data_ack(struct gxp_i2c_drvdata *drvdata)317{318	u16 value;319 320	value = readb(drvdata->base + GXP_I2CSTAT);321	if (!(value & MASK_ACK)) {322		/* Received No ack, stop */323		drvdata->state = GXP_I2C_DATA_NACK;324		gxp_i2c_stop(drvdata);325		return;326	}327 328	/* Got ack, check if there is more data to write */329	if (drvdata->buf_remaining == 0) {330		/* No more data, this message is completed */331		drvdata->msgs_remaining--;332 333		if (drvdata->msgs_remaining == 0) {334			/* No more messages, stop */335			drvdata->state = GXP_I2C_COMP;336			gxp_i2c_stop(drvdata);337			return;338		}339		/* Move to next message and start transfer */340		drvdata->curr_msg++;341		gxp_i2c_restart(drvdata);342		return;343	}344 345	/* Write data to slave */346	value = *drvdata->buf;347	value = value << 8;348 349	/* Clear master event */350	value |= MASTER_EVT_CLR;351	drvdata->buf++;352	drvdata->buf_remaining--;353	drvdata->state = GXP_I2C_WDATA_PHASE;354	writew(value, drvdata->base + GXP_I2CMCMD);355}356 357static bool gxp_i2c_slave_irq_handler(struct gxp_i2c_drvdata *drvdata)358{359	u8 value;360	u8 buf;361	int ret;362 363	value = readb(drvdata->base + GXP_I2CEVTERR);364 365	/* Received start or stop event */366	if (value & MASK_SLAVE_CMD_EVENT) {367		value = readb(drvdata->base + GXP_I2CSTAT);368		/* Master sent stop */369		if (value & MASK_STOP_EVENT) {370			if (drvdata->stopped == 0)371				i2c_slave_event(drvdata->slave, I2C_SLAVE_STOP, &buf);372			writeb(SLAVE_EVT_CLR | SNOOP_EVT_MASK |373			       SLAVE_ACK_ENAB | SLAVE_EVT_STALL, drvdata->base + GXP_I2CSCMD);374			drvdata->stopped = 1;375		} else {376			/* Master sent start and  wants to read */377			drvdata->stopped = 0;378			if (value & MASK_RW) {379				i2c_slave_event(drvdata->slave,380						I2C_SLAVE_READ_REQUESTED, &buf);381				value = buf << 8 | (SLAVE_EVT_CLR | SNOOP_EVT_MASK |382						    SLAVE_EVT_STALL);383				writew(value, drvdata->base + GXP_I2CSCMD);384			} else {385				/* Master wants to write to us */386				ret = i2c_slave_event(drvdata->slave,387						      I2C_SLAVE_WRITE_REQUESTED, &buf);388				if (!ret) {389					/* Ack next byte from master */390					writeb(SLAVE_EVT_CLR | SNOOP_EVT_MASK |391					       SLAVE_ACK_ENAB | SLAVE_EVT_STALL,392					       drvdata->base + GXP_I2CSCMD);393				} else {394					/* Nack next byte from master */395					writeb(SLAVE_EVT_CLR | SNOOP_EVT_MASK |396					       SLAVE_EVT_STALL, drvdata->base + GXP_I2CSCMD);397				}398			}399		}400	} else if (value & MASK_SLAVE_DATA_EVENT) {401		value = readb(drvdata->base + GXP_I2CSTAT);402		/* Master wants to read */403		if (value & MASK_RW) {404			/* Master wants another byte */405			if (value & MASK_ACK) {406				i2c_slave_event(drvdata->slave,407						I2C_SLAVE_READ_PROCESSED, &buf);408				value = buf << 8 | (SLAVE_EVT_CLR | SNOOP_EVT_MASK |409						    SLAVE_EVT_STALL);410				writew(value, drvdata->base + GXP_I2CSCMD);411			} else {412				/* No more bytes needed */413				writew(SLAVE_EVT_CLR | SNOOP_EVT_MASK |414				       SLAVE_ACK_ENAB | SLAVE_EVT_STALL,415				       drvdata->base + GXP_I2CSCMD);416			}417		} else {418			/* Master wants to write to us */419			value = readb(drvdata->base + GXP_I2CSNPDAT);420			buf = (uint8_t)value;421			ret = i2c_slave_event(drvdata->slave,422					      I2C_SLAVE_WRITE_RECEIVED, &buf);423			if (!ret) {424				/* Ack next byte from master */425				writeb(SLAVE_EVT_CLR | SNOOP_EVT_MASK |426				       SLAVE_ACK_ENAB | SLAVE_EVT_STALL,427				       drvdata->base + GXP_I2CSCMD);428			} else {429				/* Nack next byte from master */430				writeb(SLAVE_EVT_CLR | SNOOP_EVT_MASK |431				       SLAVE_EVT_STALL, drvdata->base + GXP_I2CSCMD);432			}433		}434	} else {435		return false;436	}437 438	return true;439}440 441static irqreturn_t gxp_i2c_irq_handler(int irq, void *_drvdata)442{443	struct gxp_i2c_drvdata *drvdata = (struct gxp_i2c_drvdata *)_drvdata;444	u32 value;445 446	/* Check if the interrupt is for the current engine */447	regmap_read(i2cg_map, GXP_I2CINTSTAT, &value);448	if (!(value & BIT(drvdata->engine)))449		return IRQ_NONE;450 451	value = readb(drvdata->base + GXP_I2CEVTERR);452 453	/* Error */454	if (value & ~(MASK_MASTER_EVENT | MASK_SLAVE_CMD_EVENT |455				MASK_SLAVE_DATA_EVENT)) {456		/* Clear all events */457		writeb(0x00, drvdata->base + GXP_I2CEVTERR);458		drvdata->state = GXP_I2C_ERROR;459		gxp_i2c_stop(drvdata);460		return IRQ_HANDLED;461	}462 463	if (IS_ENABLED(CONFIG_I2C_SLAVE)) {464		/* Slave mode */465		if (value & (MASK_SLAVE_CMD_EVENT | MASK_SLAVE_DATA_EVENT)) {466			if (gxp_i2c_slave_irq_handler(drvdata))467				return IRQ_HANDLED;468			return IRQ_NONE;469		}470	}471 472	/*  Master mode */473	switch (drvdata->state) {474	case GXP_I2C_ADDR_PHASE:475		gxp_i2c_chk_addr_ack(drvdata);476		break;477 478	case GXP_I2C_RDATA_PHASE:479		gxp_i2c_ack_data(drvdata);480		break;481 482	case GXP_I2C_WDATA_PHASE:483		gxp_i2c_chk_data_ack(drvdata);484		break;485	}486 487	return IRQ_HANDLED;488}489 490static void gxp_i2c_init(struct gxp_i2c_drvdata *drvdata)491{492	drvdata->state = GXP_I2C_IDLE;493	writeb(2000000 / drvdata->t.bus_freq_hz,494	       drvdata->base + GXP_I2CFREQDIV);495	writeb(FILTER_CNT | FAIRNESS_CNT,496	       drvdata->base + GXP_I2CFLTFAIR);497	writeb(GXP_DATA_EDGE_RST_CTRL, drvdata->base + GXP_I2CTMOEDG);498	writeb(0x00, drvdata->base + GXP_I2CCYCTIM);499	writeb(0x00, drvdata->base + GXP_I2CSNPAA);500	writeb(0x00, drvdata->base + GXP_I2CADVFEAT);501	writeb(SNOOP_EVT_CLR | SLAVE_EVT_CLR | SNOOP_EVT_MASK |502	       SLAVE_EVT_MASK, drvdata->base + GXP_I2CSCMD);503	writeb(MASTER_EVT_CLR, drvdata->base + GXP_I2CMCMD);504	writeb(0x00, drvdata->base + GXP_I2CEVTERR);505	writeb(0x00, drvdata->base + GXP_I2COWNADR);506}507 508static int gxp_i2c_probe(struct platform_device *pdev)509{510	struct gxp_i2c_drvdata *drvdata;511	int rc;512	struct i2c_adapter *adapter;513 514	if (!i2cg_map) {515		i2cg_map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,516							   "hpe,sysreg");517		if (IS_ERR(i2cg_map)) {518			return dev_err_probe(&pdev->dev, PTR_ERR(i2cg_map),519					     "failed to map i2cg_handle\n");520		}521 522		/* Disable interrupt */523		regmap_update_bits(i2cg_map, GXP_I2CINTEN, 0x00000FFF, 0);524	}525 526	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata),527			       GFP_KERNEL);528	if (!drvdata)529		return -ENOMEM;530 531	platform_set_drvdata(pdev, drvdata);532	drvdata->dev = &pdev->dev;533	init_completion(&drvdata->completion);534 535	drvdata->base = devm_platform_ioremap_resource(pdev, 0);536	if (IS_ERR(drvdata->base))537		return PTR_ERR(drvdata->base);538 539	/* Use physical memory address to determine which I2C engine this is. */540	drvdata->engine = ((size_t)drvdata->base & 0xf00) >> 8;541 542	if (drvdata->engine >= GXP_MAX_I2C_ENGINE) {543		return dev_err_probe(&pdev->dev, -EINVAL, "i2c engine% is unsupported\n",544			drvdata->engine);545	}546 547	rc = platform_get_irq(pdev, 0);548	if (rc < 0)549		return rc;550 551	drvdata->irq = rc;552	rc = devm_request_irq(&pdev->dev, drvdata->irq, gxp_i2c_irq_handler,553			      IRQF_SHARED, gxp_i2c_name[drvdata->engine], drvdata);554	if (rc < 0)555		return dev_err_probe(&pdev->dev, rc, "irq request failed\n");556 557	i2c_parse_fw_timings(&pdev->dev, &drvdata->t, true);558 559	gxp_i2c_init(drvdata);560 561	/* Enable interrupt */562	regmap_update_bits(i2cg_map, GXP_I2CINTEN, BIT(drvdata->engine),563			   BIT(drvdata->engine));564 565	adapter = &drvdata->adapter;566	i2c_set_adapdata(adapter, drvdata);567 568	adapter->owner = THIS_MODULE;569	strscpy(adapter->name, "HPE GXP I2C adapter", sizeof(adapter->name));570	adapter->algo = &gxp_i2c_algo;571	adapter->dev.parent = &pdev->dev;572	adapter->dev.of_node = pdev->dev.of_node;573 574	rc = i2c_add_adapter(adapter);575	if (rc)576		return dev_err_probe(&pdev->dev, rc, "i2c add adapter failed\n");577 578	return 0;579}580 581static void gxp_i2c_remove(struct platform_device *pdev)582{583	struct gxp_i2c_drvdata *drvdata = platform_get_drvdata(pdev);584 585	/* Disable interrupt */586	regmap_update_bits(i2cg_map, GXP_I2CINTEN, BIT(drvdata->engine), 0);587	i2c_del_adapter(&drvdata->adapter);588}589 590static const struct of_device_id gxp_i2c_of_match[] = {591	{ .compatible = "hpe,gxp-i2c" },592	{},593};594MODULE_DEVICE_TABLE(of, gxp_i2c_of_match);595 596static struct platform_driver gxp_i2c_driver = {597	.probe	= gxp_i2c_probe,598	.remove_new = gxp_i2c_remove,599	.driver = {600		.name = "gxp-i2c",601		.of_match_table = gxp_i2c_of_match,602	},603};604module_platform_driver(gxp_i2c_driver);605 606MODULE_AUTHOR("Nick Hawkins <nick.hawkins@hpe.com>");607MODULE_DESCRIPTION("HPE GXP I2C bus driver");608MODULE_LICENSE("GPL");609