Lines Matching +full:x +full:- +full:gene
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * X-Gene SLIMpro I2C Driver
9 * This driver provides support for X-Gene SLIMpro I2C device access
10 * using the APM X-Gene SLIMpro mailbox driver.
14 #include <linux/dma-mapping.h>
62 * dev - Controller number (0-based)
63 * chip - I2C chip address
64 * op - SLIMPRO_IIC_READ or SLIMPRO_IIC_WRITE
65 * proto - SLIMPRO_IIC_SMB_PROTOCOL or SLIMPRO_IIC_I2C_PROTOCOL
66 * addrlen - Length of the address field
67 * datalen - Length of the data field
139 if (ctx->resp_msg) in slimpro_i2c_rx_cb()
140 *ctx->resp_msg = ((u32 *)mssg)[1]; in slimpro_i2c_rx_cb()
142 if (ctx->mbox_client.tx_block) in slimpro_i2c_rx_cb()
143 complete(&ctx->rd_complete); in slimpro_i2c_rx_cb()
150 ctx->pcc_chan->shmem; in slimpro_i2c_pcc_rx_cb()
153 if (!xgene_word_tst_and_clr(&generic_comm_base->status, in slimpro_i2c_pcc_rx_cb()
157 if (xgene_word_tst_and_clr(&generic_comm_base->status, in slimpro_i2c_pcc_rx_cb()
162 if (ctx->resp_msg) in slimpro_i2c_pcc_rx_cb()
163 *ctx->resp_msg = ((u32 *)msg)[1]; in slimpro_i2c_pcc_rx_cb()
165 complete(&ctx->rd_complete); in slimpro_i2c_pcc_rx_cb()
172 ctx->pcc_chan->shmem; in slimpro_i2c_pcc_tx_prepare()
177 WRITE_ONCE(generic_comm_base->signature, in slimpro_i2c_pcc_tx_prepare()
178 cpu_to_le32(PCC_SIGNATURE | ctx->mbox_idx)); in slimpro_i2c_pcc_tx_prepare()
180 WRITE_ONCE(generic_comm_base->command, in slimpro_i2c_pcc_tx_prepare()
183 status = le16_to_cpu(READ_ONCE(generic_comm_base->status)); in slimpro_i2c_pcc_tx_prepare()
185 WRITE_ONCE(generic_comm_base->status, cpu_to_le16(status)); in slimpro_i2c_pcc_tx_prepare()
194 if (ctx->mbox_client.tx_block || !acpi_disabled) { in start_i2c_msg_xfer()
195 if (!wait_for_completion_timeout(&ctx->rd_complete, in start_i2c_msg_xfer()
197 return -ETIMEDOUT; in start_i2c_msg_xfer()
201 if (*ctx->resp_msg == 0xffffffff) in start_i2c_msg_xfer()
202 return -ENODEV; in start_i2c_msg_xfer()
213 ctx->resp_msg = data; in slimpro_i2c_send_msg()
216 reinit_completion(&ctx->rd_complete); in slimpro_i2c_send_msg()
220 rc = mbox_send_message(ctx->mbox_chan, msg); in slimpro_i2c_send_msg()
228 mbox_chan_txdone(ctx->mbox_chan, 0); in slimpro_i2c_send_msg()
230 ctx->resp_msg = NULL; in slimpro_i2c_send_msg()
271 paddr = dma_map_single(ctx->dev, ctx->dma_buffer, readlen, DMA_FROM_DEVICE); in slimpro_i2c_blkrd()
272 if (dma_mapping_error(ctx->dev, paddr)) { in slimpro_i2c_blkrd()
273 dev_err(&ctx->adapter.dev, "Error in mapping dma buffer %p\n", in slimpro_i2c_blkrd()
274 ctx->dma_buffer); in slimpro_i2c_blkrd()
275 return -ENOMEM; in slimpro_i2c_blkrd()
289 memcpy(data, ctx->dma_buffer, readlen); in slimpro_i2c_blkrd()
291 dma_unmap_single(ctx->dev, paddr, readlen, DMA_FROM_DEVICE); in slimpro_i2c_blkrd()
304 return -EINVAL; in slimpro_i2c_blkwr()
306 memcpy(ctx->dma_buffer, data, writelen); in slimpro_i2c_blkwr()
307 paddr = dma_map_single(ctx->dev, ctx->dma_buffer, writelen, in slimpro_i2c_blkwr()
309 if (dma_mapping_error(ctx->dev, paddr)) { in slimpro_i2c_blkwr()
310 dev_err(&ctx->adapter.dev, "Error in mapping dma buffer %p\n", in slimpro_i2c_blkwr()
311 ctx->dma_buffer); in slimpro_i2c_blkwr()
312 return -ENOMEM; in slimpro_i2c_blkwr()
322 if (ctx->mbox_client.tx_block) in slimpro_i2c_blkwr()
323 reinit_completion(&ctx->rd_complete); in slimpro_i2c_blkwr()
327 dma_unmap_single(ctx->dev, paddr, writelen, DMA_TO_DEVICE); in slimpro_i2c_blkwr()
337 int ret = -EOPNOTSUPP; in xgene_slimpro_i2c_xfer()
346 data->byte = val; in xgene_slimpro_i2c_xfer()
358 data->byte = val; in xgene_slimpro_i2c_xfer()
360 val = data->byte; in xgene_slimpro_i2c_xfer()
371 data->word = val; in xgene_slimpro_i2c_xfer()
373 val = data->word; in xgene_slimpro_i2c_xfer()
386 &data->block[0]); in xgene_slimpro_i2c_xfer()
392 data->block[0] + 1, in xgene_slimpro_i2c_xfer()
393 &data->block[0]); in xgene_slimpro_i2c_xfer()
404 &data->block[1]); in xgene_slimpro_i2c_xfer()
409 data->block[0], in xgene_slimpro_i2c_xfer()
410 &data->block[1]); in xgene_slimpro_i2c_xfer()
443 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); in xgene_slimpro_i2c_probe()
445 return -ENOMEM; in xgene_slimpro_i2c_probe()
447 ctx->dev = &pdev->dev; in xgene_slimpro_i2c_probe()
449 cl = &ctx->mbox_client; in xgene_slimpro_i2c_probe()
452 cl->dev = &pdev->dev; in xgene_slimpro_i2c_probe()
453 init_completion(&ctx->rd_complete); in xgene_slimpro_i2c_probe()
454 cl->tx_tout = MAILBOX_OP_TIMEOUT; in xgene_slimpro_i2c_probe()
455 cl->knows_txdone = false; in xgene_slimpro_i2c_probe()
457 cl->tx_block = true; in xgene_slimpro_i2c_probe()
458 cl->rx_callback = slimpro_i2c_rx_cb; in xgene_slimpro_i2c_probe()
459 ctx->mbox_chan = mbox_request_channel(cl, MAILBOX_I2C_INDEX); in xgene_slimpro_i2c_probe()
460 if (IS_ERR(ctx->mbox_chan)) in xgene_slimpro_i2c_probe()
461 return dev_err_probe(&pdev->dev, PTR_ERR(ctx->mbox_chan), in xgene_slimpro_i2c_probe()
467 acpi_id = acpi_match_device(pdev->dev.driver->acpi_match_table, in xgene_slimpro_i2c_probe()
468 &pdev->dev); in xgene_slimpro_i2c_probe()
470 return -EINVAL; in xgene_slimpro_i2c_probe()
472 if (device_property_read_u32(&pdev->dev, "pcc-channel", in xgene_slimpro_i2c_probe()
473 &ctx->mbox_idx)) in xgene_slimpro_i2c_probe()
474 ctx->mbox_idx = MAILBOX_I2C_INDEX; in xgene_slimpro_i2c_probe()
476 cl->tx_block = false; in xgene_slimpro_i2c_probe()
477 cl->rx_callback = slimpro_i2c_pcc_rx_cb; in xgene_slimpro_i2c_probe()
478 pcc_chan = pcc_mbox_request_channel(cl, ctx->mbox_idx); in xgene_slimpro_i2c_probe()
480 return dev_err_probe(&pdev->dev, PTR_ERR(pcc_chan), in xgene_slimpro_i2c_probe()
483 ctx->pcc_chan = pcc_chan; in xgene_slimpro_i2c_probe()
484 ctx->mbox_chan = pcc_chan->mchan; in xgene_slimpro_i2c_probe()
486 if (!ctx->mbox_chan->mbox->txdone_irq) { in xgene_slimpro_i2c_probe()
487 rc = dev_err_probe(&pdev->dev, -ENOENT, in xgene_slimpro_i2c_probe()
493 rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); in xgene_slimpro_i2c_probe()
495 dev_warn(&pdev->dev, "Unable to set dma mask\n"); in xgene_slimpro_i2c_probe()
498 adapter = &ctx->adapter; in xgene_slimpro_i2c_probe()
499 snprintf(adapter->name, sizeof(adapter->name), "MAILBOX I2C"); in xgene_slimpro_i2c_probe()
500 adapter->algo = &xgene_slimpro_i2c_algorithm; in xgene_slimpro_i2c_probe()
501 adapter->class = I2C_CLASS_HWMON; in xgene_slimpro_i2c_probe()
502 adapter->dev.parent = &pdev->dev; in xgene_slimpro_i2c_probe()
503 adapter->dev.of_node = pdev->dev.of_node; in xgene_slimpro_i2c_probe()
504 ACPI_COMPANION_SET(&adapter->dev, ACPI_COMPANION(&pdev->dev)); in xgene_slimpro_i2c_probe()
510 dev_info(&pdev->dev, "Mailbox I2C Adapter registered\n"); in xgene_slimpro_i2c_probe()
515 mbox_free_channel(ctx->mbox_chan); in xgene_slimpro_i2c_probe()
517 pcc_mbox_free_channel(ctx->pcc_chan); in xgene_slimpro_i2c_probe()
526 i2c_del_adapter(&ctx->adapter); in xgene_slimpro_i2c_remove()
529 mbox_free_channel(ctx->mbox_chan); in xgene_slimpro_i2c_remove()
531 pcc_mbox_free_channel(ctx->pcc_chan); in xgene_slimpro_i2c_remove()
535 {.compatible = "apm,xgene-slimpro-i2c" },
553 .name = "xgene-slimpro-i2c",
561 MODULE_DESCRIPTION("APM X-Gene SLIMpro I2C driver");