Lines Matching +full:stop +full:- +full:ack

1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P. */
15 "gxp-i2c0", "gxp-i2c1", "gxp-i2c2", "gxp-i2c3",
16 "gxp-i2c4", "gxp-i2c5", "gxp-i2c6", "gxp-i2c7",
17 "gxp-i2c8", "gxp-i2c9" };
100 drvdata->buf = drvdata->curr_msg->buf; in gxp_i2c_start()
101 drvdata->buf_remaining = drvdata->curr_msg->len; in gxp_i2c_start()
104 value = drvdata->curr_msg->addr << 9; in gxp_i2c_start()
107 value |= drvdata->curr_msg->flags & I2C_M_RD ? RW_CMD | START_CMD : START_CMD; in gxp_i2c_start()
109 drvdata->state = GXP_I2C_ADDR_PHASE; in gxp_i2c_start()
110 writew(value, drvdata->base + GXP_I2CMCMD); in gxp_i2c_start()
120 drvdata->msgs_remaining = num; in gxp_i2c_master_xfer()
121 drvdata->curr_msg = msgs; in gxp_i2c_master_xfer()
122 drvdata->msgs_num = num; in gxp_i2c_master_xfer()
123 reinit_completion(&drvdata->completion); in gxp_i2c_master_xfer()
127 time_left = wait_for_completion_timeout(&drvdata->completion, in gxp_i2c_master_xfer()
128 adapter->timeout); in gxp_i2c_master_xfer()
129 ret = num - drvdata->msgs_remaining; in gxp_i2c_master_xfer()
131 return -ETIMEDOUT; in gxp_i2c_master_xfer()
133 if (drvdata->state == GXP_I2C_ADDR_NACK) in gxp_i2c_master_xfer()
134 return -ENXIO; in gxp_i2c_master_xfer()
136 if (drvdata->state == GXP_I2C_DATA_NACK) in gxp_i2c_master_xfer()
137 return -EIO; in gxp_i2c_master_xfer()
153 struct gxp_i2c_drvdata *drvdata = i2c_get_adapdata(slave->adapter); in gxp_i2c_reg_slave()
155 if (drvdata->slave) in gxp_i2c_reg_slave()
156 return -EBUSY; in gxp_i2c_reg_slave()
158 if (slave->flags & I2C_CLIENT_TEN) in gxp_i2c_reg_slave()
159 return -EAFNOSUPPORT; in gxp_i2c_reg_slave()
161 drvdata->slave = slave; in gxp_i2c_reg_slave()
163 writeb(slave->addr << 1, drvdata->base + GXP_I2COWNADR); in gxp_i2c_reg_slave()
165 SLAVE_EVT_STALL, drvdata->base + GXP_I2CSCMD); in gxp_i2c_reg_slave()
172 struct gxp_i2c_drvdata *drvdata = i2c_get_adapdata(slave->adapter); in gxp_i2c_unreg_slave()
174 WARN_ON(!drvdata->slave); in gxp_i2c_unreg_slave()
176 writeb(0x00, drvdata->base + GXP_I2COWNADR); in gxp_i2c_unreg_slave()
178 SLAVE_EVT_MASK, drvdata->base + GXP_I2CSCMD); in gxp_i2c_unreg_slave()
180 drvdata->slave = NULL; in gxp_i2c_unreg_slave()
197 /* Clear event and send stop */ in gxp_i2c_stop()
198 writeb(MASTER_EVT_CLR | STOP_CMD, drvdata->base + GXP_I2CMCMD); in gxp_i2c_stop()
200 complete(&drvdata->completion); in gxp_i2c_stop()
207 drvdata->buf = drvdata->curr_msg->buf; in gxp_i2c_restart()
208 drvdata->buf_remaining = drvdata->curr_msg->len; in gxp_i2c_restart()
210 value = drvdata->curr_msg->addr << 9; in gxp_i2c_restart()
212 if (drvdata->curr_msg->flags & I2C_M_RD) { in gxp_i2c_restart()
220 drvdata->state = GXP_I2C_ADDR_PHASE; in gxp_i2c_restart()
222 writew(value, drvdata->base + GXP_I2CMCMD); in gxp_i2c_restart()
229 value = readb(drvdata->base + GXP_I2CSTAT); in gxp_i2c_chk_addr_ack()
231 /* Got no ack, stop */ in gxp_i2c_chk_addr_ack()
232 drvdata->state = GXP_I2C_ADDR_NACK; in gxp_i2c_chk_addr_ack()
237 if (drvdata->curr_msg->flags & I2C_M_RD) { in gxp_i2c_chk_addr_ack()
239 if (drvdata->buf_remaining == 0) { in gxp_i2c_chk_addr_ack()
240 /* No more data to read, stop */ in gxp_i2c_chk_addr_ack()
241 drvdata->msgs_remaining--; in gxp_i2c_chk_addr_ack()
242 drvdata->state = GXP_I2C_COMP; in gxp_i2c_chk_addr_ack()
246 drvdata->state = GXP_I2C_RDATA_PHASE; in gxp_i2c_chk_addr_ack()
248 if (drvdata->buf_remaining == 1) { in gxp_i2c_chk_addr_ack()
249 /* The last data, do not ack */ in gxp_i2c_chk_addr_ack()
251 drvdata->base + GXP_I2CMCMD); in gxp_i2c_chk_addr_ack()
253 /* Read data and ack it */ in gxp_i2c_chk_addr_ack()
255 RW_CMD, drvdata->base + GXP_I2CMCMD); in gxp_i2c_chk_addr_ack()
259 if (drvdata->buf_remaining == 0) { in gxp_i2c_chk_addr_ack()
260 /* No more data to write, stop */ in gxp_i2c_chk_addr_ack()
261 drvdata->msgs_remaining--; in gxp_i2c_chk_addr_ack()
262 drvdata->state = GXP_I2C_COMP; in gxp_i2c_chk_addr_ack()
266 value = *drvdata->buf; in gxp_i2c_chk_addr_ack()
270 drvdata->buf++; in gxp_i2c_chk_addr_ack()
271 drvdata->buf_remaining--; in gxp_i2c_chk_addr_ack()
272 drvdata->state = GXP_I2C_WDATA_PHASE; in gxp_i2c_chk_addr_ack()
273 writew(value, drvdata->base + GXP_I2CMCMD); in gxp_i2c_chk_addr_ack()
282 value = readb(drvdata->base + GXP_I2CSNPDAT); in gxp_i2c_ack_data()
283 *drvdata->buf = value; in gxp_i2c_ack_data()
284 drvdata->buf++; in gxp_i2c_ack_data()
285 drvdata->buf_remaining--; in gxp_i2c_ack_data()
287 if (drvdata->buf_remaining == 0) { in gxp_i2c_ack_data()
289 drvdata->msgs_remaining--; in gxp_i2c_ack_data()
291 if (drvdata->msgs_remaining == 0) { in gxp_i2c_ack_data()
292 /* No more messages, stop */ in gxp_i2c_ack_data()
293 drvdata->state = GXP_I2C_COMP; in gxp_i2c_ack_data()
298 drvdata->curr_msg++; in gxp_i2c_ack_data()
303 /* Ack the slave to make it send next byte */ in gxp_i2c_ack_data()
304 drvdata->state = GXP_I2C_RDATA_PHASE; in gxp_i2c_ack_data()
305 if (drvdata->buf_remaining == 1) { in gxp_i2c_ack_data()
306 /* The last data, do not ack */ in gxp_i2c_ack_data()
308 drvdata->base + GXP_I2CMCMD); in gxp_i2c_ack_data()
310 /* Read data and ack it */ in gxp_i2c_ack_data()
312 RW_CMD, drvdata->base + GXP_I2CMCMD); in gxp_i2c_ack_data()
320 value = readb(drvdata->base + GXP_I2CSTAT); in gxp_i2c_chk_data_ack()
322 /* Received No ack, stop */ in gxp_i2c_chk_data_ack()
323 drvdata->state = GXP_I2C_DATA_NACK; in gxp_i2c_chk_data_ack()
328 /* Got ack, check if there is more data to write */ in gxp_i2c_chk_data_ack()
329 if (drvdata->buf_remaining == 0) { in gxp_i2c_chk_data_ack()
331 drvdata->msgs_remaining--; in gxp_i2c_chk_data_ack()
333 if (drvdata->msgs_remaining == 0) { in gxp_i2c_chk_data_ack()
334 /* No more messages, stop */ in gxp_i2c_chk_data_ack()
335 drvdata->state = GXP_I2C_COMP; in gxp_i2c_chk_data_ack()
340 drvdata->curr_msg++; in gxp_i2c_chk_data_ack()
346 value = *drvdata->buf; in gxp_i2c_chk_data_ack()
351 drvdata->buf++; in gxp_i2c_chk_data_ack()
352 drvdata->buf_remaining--; in gxp_i2c_chk_data_ack()
353 drvdata->state = GXP_I2C_WDATA_PHASE; in gxp_i2c_chk_data_ack()
354 writew(value, drvdata->base + GXP_I2CMCMD); in gxp_i2c_chk_data_ack()
363 value = readb(drvdata->base + GXP_I2CEVTERR); in gxp_i2c_slave_irq_handler()
365 /* Received start or stop event */ in gxp_i2c_slave_irq_handler()
367 value = readb(drvdata->base + GXP_I2CSTAT); in gxp_i2c_slave_irq_handler()
368 /* Master sent stop */ in gxp_i2c_slave_irq_handler()
370 if (drvdata->stopped == 0) in gxp_i2c_slave_irq_handler()
371 i2c_slave_event(drvdata->slave, I2C_SLAVE_STOP, &buf); in gxp_i2c_slave_irq_handler()
373 SLAVE_ACK_ENAB | SLAVE_EVT_STALL, drvdata->base + GXP_I2CSCMD); in gxp_i2c_slave_irq_handler()
374 drvdata->stopped = 1; in gxp_i2c_slave_irq_handler()
377 drvdata->stopped = 0; in gxp_i2c_slave_irq_handler()
379 i2c_slave_event(drvdata->slave, in gxp_i2c_slave_irq_handler()
383 writew(value, drvdata->base + GXP_I2CSCMD); in gxp_i2c_slave_irq_handler()
386 ret = i2c_slave_event(drvdata->slave, in gxp_i2c_slave_irq_handler()
389 /* Ack next byte from master */ in gxp_i2c_slave_irq_handler()
392 drvdata->base + GXP_I2CSCMD); in gxp_i2c_slave_irq_handler()
396 SLAVE_EVT_STALL, drvdata->base + GXP_I2CSCMD); in gxp_i2c_slave_irq_handler()
401 value = readb(drvdata->base + GXP_I2CSTAT); in gxp_i2c_slave_irq_handler()
406 i2c_slave_event(drvdata->slave, in gxp_i2c_slave_irq_handler()
410 writew(value, drvdata->base + GXP_I2CSCMD); in gxp_i2c_slave_irq_handler()
415 drvdata->base + GXP_I2CSCMD); in gxp_i2c_slave_irq_handler()
419 value = readb(drvdata->base + GXP_I2CSNPDAT); in gxp_i2c_slave_irq_handler()
421 ret = i2c_slave_event(drvdata->slave, in gxp_i2c_slave_irq_handler()
424 /* Ack next byte from master */ in gxp_i2c_slave_irq_handler()
427 drvdata->base + GXP_I2CSCMD); in gxp_i2c_slave_irq_handler()
431 SLAVE_EVT_STALL, drvdata->base + GXP_I2CSCMD); in gxp_i2c_slave_irq_handler()
448 if (!(value & BIT(drvdata->engine))) in gxp_i2c_irq_handler()
451 value = readb(drvdata->base + GXP_I2CEVTERR); in gxp_i2c_irq_handler()
457 writeb(0x00, drvdata->base + GXP_I2CEVTERR); in gxp_i2c_irq_handler()
458 drvdata->state = GXP_I2C_ERROR; in gxp_i2c_irq_handler()
473 switch (drvdata->state) { in gxp_i2c_irq_handler()
492 drvdata->state = GXP_I2C_IDLE; in gxp_i2c_init()
493 writeb(2000000 / drvdata->t.bus_freq_hz, in gxp_i2c_init()
494 drvdata->base + GXP_I2CFREQDIV); in gxp_i2c_init()
496 drvdata->base + GXP_I2CFLTFAIR); in gxp_i2c_init()
497 writeb(GXP_DATA_EDGE_RST_CTRL, drvdata->base + GXP_I2CTMOEDG); in gxp_i2c_init()
498 writeb(0x00, drvdata->base + GXP_I2CCYCTIM); in gxp_i2c_init()
499 writeb(0x00, drvdata->base + GXP_I2CSNPAA); in gxp_i2c_init()
500 writeb(0x00, drvdata->base + GXP_I2CADVFEAT); in gxp_i2c_init()
502 SLAVE_EVT_MASK, drvdata->base + GXP_I2CSCMD); in gxp_i2c_init()
503 writeb(MASTER_EVT_CLR, drvdata->base + GXP_I2CMCMD); in gxp_i2c_init()
504 writeb(0x00, drvdata->base + GXP_I2CEVTERR); in gxp_i2c_init()
505 writeb(0x00, drvdata->base + GXP_I2COWNADR); in gxp_i2c_init()
515 i2cg_map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, in gxp_i2c_probe()
518 return dev_err_probe(&pdev->dev, PTR_ERR(i2cg_map), in gxp_i2c_probe()
526 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), in gxp_i2c_probe()
529 return -ENOMEM; in gxp_i2c_probe()
532 drvdata->dev = &pdev->dev; in gxp_i2c_probe()
533 init_completion(&drvdata->completion); in gxp_i2c_probe()
535 drvdata->base = devm_platform_ioremap_resource(pdev, 0); in gxp_i2c_probe()
536 if (IS_ERR(drvdata->base)) in gxp_i2c_probe()
537 return PTR_ERR(drvdata->base); in gxp_i2c_probe()
540 drvdata->engine = ((size_t)drvdata->base & 0xf00) >> 8; in gxp_i2c_probe()
542 if (drvdata->engine >= GXP_MAX_I2C_ENGINE) { in gxp_i2c_probe()
543 return dev_err_probe(&pdev->dev, -EINVAL, "i2c engine% is unsupported\n", in gxp_i2c_probe()
544 drvdata->engine); in gxp_i2c_probe()
551 drvdata->irq = rc; in gxp_i2c_probe()
552 rc = devm_request_irq(&pdev->dev, drvdata->irq, gxp_i2c_irq_handler, in gxp_i2c_probe()
553 IRQF_SHARED, gxp_i2c_name[drvdata->engine], drvdata); in gxp_i2c_probe()
555 return dev_err_probe(&pdev->dev, rc, "irq request failed\n"); in gxp_i2c_probe()
557 i2c_parse_fw_timings(&pdev->dev, &drvdata->t, true); in gxp_i2c_probe()
562 regmap_update_bits(i2cg_map, GXP_I2CINTEN, BIT(drvdata->engine), in gxp_i2c_probe()
563 BIT(drvdata->engine)); in gxp_i2c_probe()
565 adapter = &drvdata->adapter; in gxp_i2c_probe()
568 adapter->owner = THIS_MODULE; in gxp_i2c_probe()
569 strscpy(adapter->name, "HPE GXP I2C adapter", sizeof(adapter->name)); in gxp_i2c_probe()
570 adapter->algo = &gxp_i2c_algo; in gxp_i2c_probe()
571 adapter->dev.parent = &pdev->dev; in gxp_i2c_probe()
572 adapter->dev.of_node = pdev->dev.of_node; in gxp_i2c_probe()
576 return dev_err_probe(&pdev->dev, rc, "i2c add adapter failed\n"); in gxp_i2c_probe()
586 regmap_update_bits(i2cg_map, GXP_I2CINTEN, BIT(drvdata->engine), 0); in gxp_i2c_remove()
587 i2c_del_adapter(&drvdata->adapter); in gxp_i2c_remove()
591 { .compatible = "hpe,gxp-i2c" },
600 .name = "gxp-i2c",