Lines Matching +full:lpc +full:- +full:io +full:- +full:reg

1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
5 * Copyright (C) 2016-2020 Mellanox Technologies
11 #include <linux/io.h>
32 /* LPC I2C registers */
43 /* LPC I2C masks and parametres */
82 for (i = 0; i < len - len % 4; i += 4) in mlxcpld_i2c_lpc_write_buf()
92 for (i = 0; i < len - len % 4; i += 4) in mlxcpld_i2c_lpc_read_buf()
101 u32 addr = priv->base_addr + offs; in mlxcpld_i2c_read_comm()
126 u32 addr = priv->base_addr + offs; in mlxcpld_i2c_write_comm()
150 * Returns 0 if OK, other - in case of invalid parameters.
158 dev_err(priv->dev, "Incorrect 0 num of messages\n"); in mlxcpld_i2c_check_msg_params()
159 return -EINVAL; in mlxcpld_i2c_check_msg_params()
163 dev_err(priv->dev, "Invalid address 0x%03x\n", in mlxcpld_i2c_check_msg_params()
165 return -EINVAL; in mlxcpld_i2c_check_msg_params()
170 dev_err(priv->dev, "Invalid buf in msg[%d]\n", in mlxcpld_i2c_check_msg_params()
172 return -EINVAL; in mlxcpld_i2c_check_msg_params()
175 dev_err(priv->dev, "Invalid addr in msg[%d]\n", in mlxcpld_i2c_check_msg_params()
177 return -EINVAL; in mlxcpld_i2c_check_msg_params()
186 * Returns 0 - transfer completed (both ACK or NACK),
187 * negative - transfer isn't finished.
209 return -EIO; in mlxcpld_i2c_check_status()
216 priv->xfer.msg = msgs; in mlxcpld_i2c_set_transf_data()
217 priv->xfer.msg_num = num; in mlxcpld_i2c_set_transf_data()
225 priv->xfer.cmd = msgs[num - 1].flags & I2C_M_RD; in mlxcpld_i2c_set_transf_data()
227 if (priv->xfer.cmd == I2C_M_RD && comm_len != msgs[0].len) { in mlxcpld_i2c_set_transf_data()
228 priv->xfer.addr_width = msgs[0].len; in mlxcpld_i2c_set_transf_data()
229 priv->xfer.data_len = comm_len - priv->xfer.addr_width; in mlxcpld_i2c_set_transf_data()
231 priv->xfer.addr_width = 0; in mlxcpld_i2c_set_transf_data()
232 priv->xfer.data_len = comm_len; in mlxcpld_i2c_set_transf_data()
241 mutex_lock(&priv->lock); in mlxcpld_i2c_reset()
247 mutex_unlock(&priv->lock); in mlxcpld_i2c_reset()
260 return -EIO; in mlxcpld_i2c_check_busy()
275 return -ETIMEDOUT; in mlxcpld_i2c_wait_for_free()
299 return -ETIMEDOUT; in mlxcpld_i2c_wait_for_tc()
302 if (priv->xfer.cmd != I2C_M_RD) in mlxcpld_i2c_wait_for_tc()
303 return (priv->xfer.addr_width + priv->xfer.data_len); in mlxcpld_i2c_wait_for_tc()
305 if (priv->xfer.msg_num == 1) in mlxcpld_i2c_wait_for_tc()
310 if (!priv->xfer.msg[i].buf) in mlxcpld_i2c_wait_for_tc()
311 return -EINVAL; in mlxcpld_i2c_wait_for_tc()
315 * requested len. 0xff (line pull-up) will be returned in mlxcpld_i2c_wait_for_tc()
317 * MLXCPLD_LPCI2C_NUM_DAT_REG reg from CPLD. Only in case of in mlxcpld_i2c_wait_for_tc()
323 if (priv->smbus_block && (val & MLXCPLD_I2C_SMBUS_BLK_BIT)) { in mlxcpld_i2c_wait_for_tc()
327 dev_err(priv->dev, "Incorrect smbus block read message len\n"); in mlxcpld_i2c_wait_for_tc()
328 return -EPROTO; in mlxcpld_i2c_wait_for_tc()
331 datalen = priv->xfer.data_len; in mlxcpld_i2c_wait_for_tc()
335 priv->xfer.msg[i].buf, datalen); in mlxcpld_i2c_wait_for_tc()
340 return -ENXIO; in mlxcpld_i2c_wait_for_tc()
343 return -EINVAL; in mlxcpld_i2c_wait_for_tc()
353 &priv->xfer.data_len, 1); in mlxcpld_i2c_xfer_msg()
355 val = priv->xfer.addr_width; in mlxcpld_i2c_xfer_msg()
357 if (priv->smbus_block && priv->xfer.msg_num >= 2 && in mlxcpld_i2c_xfer_msg()
358 priv->xfer.msg[1].len == 1 && in mlxcpld_i2c_xfer_msg()
359 (priv->xfer.msg[1].flags & I2C_M_RECV_LEN) && in mlxcpld_i2c_xfer_msg()
360 (priv->xfer.msg[1].flags & I2C_M_RD)) in mlxcpld_i2c_xfer_msg()
365 for (i = 0; i < priv->xfer.msg_num; i++) { in mlxcpld_i2c_xfer_msg()
366 if ((priv->xfer.msg[i].flags & I2C_M_RD) != I2C_M_RD) { in mlxcpld_i2c_xfer_msg()
369 len, priv->xfer.msg[i].buf, in mlxcpld_i2c_xfer_msg()
370 priv->xfer.msg[i].len); in mlxcpld_i2c_xfer_msg()
371 len += priv->xfer.msg[i].len; in mlxcpld_i2c_xfer_msg()
379 cmd = (priv->xfer.msg[0].addr << 1) | priv->xfer.cmd; in mlxcpld_i2c_xfer_msg()
384 * Generic lpc-i2c transfer.
396 dev_err(priv->dev, "Incorrect message\n"); in mlxcpld_i2c_xfer()
405 dev_err(priv->dev, "LPCI2C bridge is busy\n"); in mlxcpld_i2c_xfer()
413 * The only reasonable thing - is soft reset. in mlxcpld_i2c_xfer()
417 dev_err(priv->dev, "LPCI2C bridge is busy after reset\n"); in mlxcpld_i2c_xfer()
418 return -EIO; in mlxcpld_i2c_xfer()
424 mutex_lock(&priv->lock); in mlxcpld_i2c_xfer()
432 mutex_unlock(&priv->lock); in mlxcpld_i2c_xfer()
441 if (priv->smbus_block) in mlxcpld_i2c_func()
456 .max_read_len = MLXCPLD_I2C_DATA_REG_SZ - MLXCPLD_I2C_MAX_ADDR_LEN,
463 .max_read_len = MLXCPLD_I2C_DATA_REG_SZ * 2 - MLXCPLD_I2C_MAX_ADDR_LEN,
470 .name = "i2c-mlxcpld",
482 struct mlxreg_core_item *item = pdata->items; in mlxcpld_i2c_set_frequency()
492 data = item->data; in mlxcpld_i2c_set_frequency()
493 err = regmap_read(pdata->regmap, data->reg, &regval); in mlxcpld_i2c_set_frequency()
498 switch ((regval & data->mask) >> data->bit) { in mlxcpld_i2c_set_frequency()
521 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in mlxcpld_i2c_probe()
523 return -ENOMEM; in mlxcpld_i2c_probe()
525 mutex_init(&priv->lock); in mlxcpld_i2c_probe()
528 priv->dev = &pdev->dev; in mlxcpld_i2c_probe()
529 priv->base_addr = MLXPLAT_CPLD_LPC_I2C_BASE_ADDR; in mlxcpld_i2c_probe()
532 pdata = dev_get_platdata(&pdev->dev); in mlxcpld_i2c_probe()
548 priv->smbus_block = true; in mlxcpld_i2c_probe()
549 if (pdev->id >= -1) in mlxcpld_i2c_probe()
550 mlxcpld_i2c_adapter.nr = pdev->id; in mlxcpld_i2c_probe()
551 priv->adap = mlxcpld_i2c_adapter; in mlxcpld_i2c_probe()
552 priv->adap.dev.parent = &pdev->dev; in mlxcpld_i2c_probe()
553 i2c_set_adapdata(&priv->adap, priv); in mlxcpld_i2c_probe()
555 err = i2c_add_numbered_adapter(&priv->adap); in mlxcpld_i2c_probe()
562 mutex_destroy(&priv->lock); in mlxcpld_i2c_probe()
570 i2c_del_adapter(&priv->adap); in mlxcpld_i2c_remove()
571 mutex_destroy(&priv->lock); in mlxcpld_i2c_remove()
587 MODULE_DESCRIPTION("Mellanox I2C-CPLD controller driver");
589 MODULE_ALIAS("platform:i2c-mlxcpld");