Lines Matching +full:i2c +full:- +full:protocol

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Linux I2C core SMBus and SMBus emulation code
5 * This file contains the SMBus functions which are always included in the I2C
6 * core because they can be emulated via I2C. SMBus specific extensions
7 * (e.g. smbalert) are handled in a separate i2c-smbus module.
9 * All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
15 #include <linux/i2c.h>
16 #include <linux/i2c-smbus.h>
21 #include "i2c-core.h"
43 * i2c_smbus_pec - Incremental CRC8 over the given input data array
60 /* Assume a 7-bit address, which is reasonable for SMBus */
68 return i2c_smbus_pec(pec, msg->buf, msg->len); in i2c_smbus_msg_pec()
74 msg->buf[msg->len] = i2c_smbus_msg_pec(0, msg); in i2c_smbus_add_pec()
75 msg->len++; in i2c_smbus_add_pec()
85 u8 rpec = msg->buf[--msg->len]; in i2c_smbus_check_pec()
91 return -EBADMSG; in i2c_smbus_check_pec()
97 * i2c_smbus_read_byte - SMBus "receive byte" protocol
100 * This executes the SMBus "receive byte" protocol, returning negative errno
108 status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_read_byte()
116 * i2c_smbus_write_byte - SMBus "send byte" protocol
120 * This executes the SMBus "send byte" protocol, returning negative errno
125 return i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_write_byte()
131 * i2c_smbus_read_byte_data - SMBus "read byte" protocol
135 * This executes the SMBus "read byte" protocol, returning negative errno
143 status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_read_byte_data()
151 * i2c_smbus_write_byte_data - SMBus "write byte" protocol
156 * This executes the SMBus "write byte" protocol, returning negative errno
164 return i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_write_byte_data()
171 * i2c_smbus_read_word_data - SMBus "read word" protocol
175 * This executes the SMBus "read word" protocol, returning negative errno
176 * else a 16-bit unsigned "word" received from the device.
183 status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_read_word_data()
191 * i2c_smbus_write_word_data - SMBus "write word" protocol
194 * @value: 16-bit "word" being written
196 * This executes the SMBus "write word" protocol, returning negative errno
204 return i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_write_word_data()
211 * i2c_smbus_read_block_data - SMBus "block read" protocol
217 * This executes the SMBus "block read" protocol, returning negative errno
222 * support this; its emulation through I2C messaging relies on a specific
231 status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_read_block_data()
243 * i2c_smbus_write_block_data - SMBus "block write" protocol
249 * This executes the SMBus "block write" protocol, returning negative errno
261 return i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_write_block_data()
277 status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_read_i2c_block_data()
297 return i2c_smbus_xfer(client->adapter, client->addr, client->flags, in i2c_smbus_write_i2c_block_data()
305 bool is_read = msg->flags & I2C_M_RD; in i2c_smbus_try_get_dmabuf()
312 msg->buf = dma_buf; in i2c_smbus_try_get_dmabuf()
313 msg->flags |= I2C_M_DMA_SAFE; in i2c_smbus_try_get_dmabuf()
316 msg->buf[0] = init_val; in i2c_smbus_try_get_dmabuf()
320 * Simulate a SMBus command using the I2C protocol.
376 msgbuf0[1] = data->byte; in i2c_smbus_xfer_emulated()
384 msgbuf0[1] = data->word & 0xff; in i2c_smbus_xfer_emulated()
385 msgbuf0[2] = data->word >> 8; in i2c_smbus_xfer_emulated()
393 msgbuf0[1] = data->word & 0xff; in i2c_smbus_xfer_emulated()
394 msgbuf0[2] = data->word >> 8; in i2c_smbus_xfer_emulated()
403 msg[0].len = data->block[0] + 2; in i2c_smbus_xfer_emulated()
405 dev_err(&adapter->dev, in i2c_smbus_xfer_emulated()
407 data->block[0]); in i2c_smbus_xfer_emulated()
408 return -EINVAL; in i2c_smbus_xfer_emulated()
412 memcpy(msg[0].buf + 1, data->block, msg[0].len - 1); in i2c_smbus_xfer_emulated()
418 if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { in i2c_smbus_xfer_emulated()
419 dev_err(&adapter->dev, in i2c_smbus_xfer_emulated()
421 data->block[0]); in i2c_smbus_xfer_emulated()
422 return -EINVAL; in i2c_smbus_xfer_emulated()
425 msg[0].len = data->block[0] + 2; in i2c_smbus_xfer_emulated()
427 memcpy(msg[0].buf + 1, data->block, msg[0].len - 1); in i2c_smbus_xfer_emulated()
435 if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { in i2c_smbus_xfer_emulated()
436 dev_err(&adapter->dev, "Invalid block %s size %d\n", in i2c_smbus_xfer_emulated()
438 data->block[0]); in i2c_smbus_xfer_emulated()
439 return -EINVAL; in i2c_smbus_xfer_emulated()
443 msg[1].len = data->block[0]; in i2c_smbus_xfer_emulated()
446 msg[0].len = data->block[0] + 1; in i2c_smbus_xfer_emulated()
449 memcpy(msg[0].buf + 1, data->block + 1, data->block[0]); in i2c_smbus_xfer_emulated()
453 dev_err(&adapter->dev, "Unsupported transaction %d\n", size); in i2c_smbus_xfer_emulated()
454 return -EOPNOTSUPP; in i2c_smbus_xfer_emulated()
466 if (msg[nmsgs - 1].flags & I2C_M_RD) in i2c_smbus_xfer_emulated()
467 msg[nmsgs - 1].len++; in i2c_smbus_xfer_emulated()
474 status = -EIO; in i2c_smbus_xfer_emulated()
480 if (wants_pec && (msg[nmsgs - 1].flags & I2C_M_RD)) { in i2c_smbus_xfer_emulated()
481 status = i2c_smbus_check_pec(partial_pec, &msg[nmsgs - 1]); in i2c_smbus_xfer_emulated()
489 data->byte = msgbuf0[0]; in i2c_smbus_xfer_emulated()
492 data->byte = msgbuf1[0]; in i2c_smbus_xfer_emulated()
496 data->word = msgbuf1[0] | (msgbuf1[1] << 8); in i2c_smbus_xfer_emulated()
499 memcpy(data->block + 1, msg[1].buf, data->block[0]); in i2c_smbus_xfer_emulated()
504 dev_err(&adapter->dev, in i2c_smbus_xfer_emulated()
507 status = -EPROTO; in i2c_smbus_xfer_emulated()
510 memcpy(data->block, msg[1].buf, msg[1].buf[0] + 1); in i2c_smbus_xfer_emulated()
524 * i2c_smbus_xfer - execute SMBus protocol operations
525 * @adapter: Handle to I2C bus
530 * @protocol: SMBus protocol operation to execute, such as I2C_SMBUS_PROC_CALL
533 * This executes an SMBus protocol operation, and returns a negative
538 u8 command, int protocol, union i2c_smbus_data *data) in i2c_smbus_xfer() argument
547 command, protocol, data); in i2c_smbus_xfer()
556 u8 command, int protocol, union i2c_smbus_data *data) in __i2c_smbus_xfer() argument
570 * read_write and protocol. in __i2c_smbus_xfer()
573 command, protocol, data); in __i2c_smbus_xfer()
575 command, protocol); in __i2c_smbus_xfer()
579 xfer_func = adapter->algo->smbus_xfer; in __i2c_smbus_xfer()
581 if (adapter->algo->smbus_xfer_atomic) in __i2c_smbus_xfer()
582 xfer_func = adapter->algo->smbus_xfer_atomic; in __i2c_smbus_xfer()
583 else if (adapter->algo->master_xfer_atomic) in __i2c_smbus_xfer()
584 xfer_func = NULL; /* fallback to I2C emulation */ in __i2c_smbus_xfer()
590 for (res = 0, try = 0; try <= adapter->retries; try++) { in __i2c_smbus_xfer()
592 command, protocol, data); in __i2c_smbus_xfer()
593 if (res != -EAGAIN) in __i2c_smbus_xfer()
596 orig_jiffies + adapter->timeout)) in __i2c_smbus_xfer()
600 if (res != -EOPNOTSUPP || !adapter->algo->master_xfer) in __i2c_smbus_xfer()
609 command, protocol, data); in __i2c_smbus_xfer()
614 command, protocol, data, res); in __i2c_smbus_xfer()
616 command, protocol, res); in __i2c_smbus_xfer()
623 * i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate
631 * This executes the SMBus "block read" protocol if supported by the adapter.
635 * The addresses of the I2C slave device that are accessed with this function
637 * effect as a byte read. Before using this function you must double-check
638 * if the I2C slave does support exchanging a block transfer with a byte
650 if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) in i2c_smbus_read_i2c_block_data_or_emulated()
653 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) in i2c_smbus_read_i2c_block_data_or_emulated()
654 return -EOPNOTSUPP; in i2c_smbus_read_i2c_block_data_or_emulated()
656 if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) { in i2c_smbus_read_i2c_block_data_or_emulated()
680 * i2c_new_smbus_alert_device - get ara client for SMBus alert support
685 * Setup handling of the SMBus alert protocol on a given I2C bus segment.
709 struct device *parent = adapter->dev.parent; in i2c_setup_smbus_alert()
717 irq = device_property_match_string(parent, "interrupt-names", "smbus_alert"); in i2c_setup_smbus_alert()
718 if (irq < 0 && irq != -EINVAL && irq != -ENODATA) in i2c_setup_smbus_alert()
722 if (irq < 0 && !device_property_present(parent, "smbalert-gpios")) in i2c_setup_smbus_alert()