/* * Note that the following SMBus, CAUSE, GPIO and PLL register addresses * refer to their respective offsets relative to the corresponding * memory-mapped region whose addresses are specified in either the DT or * the ACPI tables or above.
*/
/* * SMBus Master core clock frequency. Timing configurations are * strongly dependent on the core clock frequency of the SMBus * Master. Default value is set to 400MHz.
*/ #define MLXBF_I2C_TYU_PLL_OUT_FREQ (400 * 1000 * 1000) /* Reference clock for Bluefield - 156 MHz. */ #define MLXBF_I2C_PLL_IN_FREQ 156250000ULL
/* Constant used to determine the PLL frequency. */ #define MLNXBF_I2C_COREPLL_CONST 16384ULL
/* * Defines SMBus operating frequency and core clock frequency. * According to ADB files, default values are compliant to 100KHz SMBus * @ 400MHz core clock. The driver should be able to calculate core * frequency based on PLL parameters.
*/ #define MLXBF_I2C_COREPLL_FREQ MLXBF_I2C_TYU_PLL_OUT_FREQ
/* SMBus slave GW. */ #define MLXBF_I2C_SMBUS_SLAVE_GW 0x0 /* Number of bytes received and sent from/to master. */ #define MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES 0x100 /* Packet error check (PEC) value. */ #define MLXBF_I2C_SMBUS_SLAVE_PEC 0x104 /* SMBus slave Finite State Machine (FSM). */ #define MLXBF_I2C_SMBUS_SLAVE_FSM 0x110 /* * Should be set when all raised causes handled, and cleared by HW on * every new cause.
*/ #define MLXBF_I2C_SMBUS_SLAVE_READY 0x12c
/* SMBus slave GW control bits offset in MLXBF_I2C_SMBUS_SLAVE_GW[31:19]. */ #define MLXBF_I2C_SLAVE_BUSY_BIT BIT(30) /* Busy bit. */ #define MLXBF_I2C_SLAVE_WRITE_BIT BIT(29) /* Control write enable. */
/* * Timeout is given in microsends. Note also that timeout handling is not * exact.
*/ #define MLXBF_I2C_SMBUS_TIMEOUT (300 * 1000) /* 300ms */ #define MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT (300 * 1000) /* 300ms */
/* Polling frequency in microseconds. */ #define MLXBF_I2C_POLL_FREQ_IN_USEC 200
/* List of chip resources that are being accessed by the driver. */ enum {
MLXBF_I2C_SMBUS_RES,
MLXBF_I2C_MST_CAUSE_RES,
MLXBF_I2C_SLV_CAUSE_RES,
MLXBF_I2C_COALESCE_RES,
MLXBF_I2C_SMBUS_TIMER_RES,
MLXBF_I2C_SMBUS_MST_RES,
MLXBF_I2C_SMBUS_SLV_RES,
MLXBF_I2C_COREPLL_RES,
MLXBF_I2C_GPIO_RES,
MLXBF_I2C_END_RES
};
/* Encapsulates timing parameters. */ struct mlxbf_i2c_timings {
u16 scl_high; /* Clock high period. */
u16 scl_low; /* Clock low period. */
u8 sda_rise; /* Data rise time. */
u8 sda_fall; /* Data fall time. */
u8 scl_rise; /* Clock rise time. */
u8 scl_fall; /* Clock fall time. */
u16 hold_start; /* Hold time after (REPEATED) START. */
u16 hold_data; /* Data hold time. */
u16 setup_start; /* REPEATED START condition setup time. */
u16 setup_stop; /* STOP condition setup time. */
u16 setup_data; /* Data setup time. */
u16 pad; /* Padding. */
u16 buf; /* Bus free time between STOP and START. */
u16 thigh_max; /* Thigh max. */
u32 timeout; /* Detect clock low timeout. */
};
struct mlxbf_i2c_chip_info { enum mlxbf_i2c_chip_type type; /* Chip shared resources that are being used by the I2C controller. */ struct mlxbf_i2c_resource *shared_res[MLXBF_I2C_SHARED_RES_MAX];
/* Callback to calculate the core PLL frequency. */
u64 (*calculate_freq)(struct mlxbf_i2c_resource *corepll_res);
staticbool mlxbf_i2c_smbus_transaction_success(u32 master_status,
u32 cause_status)
{ /* * When transaction ended with STOP, all bytes were transmitted, * and no NACK received, then the transaction ended successfully. * On the other hand, when the GW is configured with the stop bit * de-asserted then the SMBus expects the following GW configuration * for transfer continuation.
*/ if ((cause_status & MLXBF_I2C_CAUSE_WAIT_FOR_FW_DATA) ||
((cause_status & MLXBF_I2C_CAUSE_TRANSACTION_ENDED) &&
(master_status & MLXBF_I2C_SMBUS_STATUS_BYTE_CNT_DONE) &&
!(master_status & MLXBF_I2C_SMBUS_STATUS_NACK_RCV))) returntrue;
returnfalse;
}
/* * Poll SMBus master status and return transaction status, * i.e. whether succeeded or failed. I2C and SMBus fault codes * are returned as negative numbers from most calls, with zero * or some positive number indicating a non-fault return.
*/ staticint mlxbf_i2c_smbus_check_status(struct mlxbf_i2c_priv *priv)
{
u32 master_status_bits;
u32 cause_status_bits;
u32 bits;
/* * GW busy bit is raised by the driver and cleared by the HW * when the transaction is completed. The busy bit is a good * indicator of transaction status. So poll the busy bit, and * then read the cause and master status bits to determine if * errors occurred during the transaction.
*/
readl_poll_timeout_atomic(priv->mst->io + MLXBF_I2C_SMBUS_MASTER_GW,
bits, !(bits & MLXBF_I2C_MASTER_BUSY_BIT),
MLXBF_I2C_POLL_FREQ_IN_USEC, MLXBF_I2C_SMBUS_TIMEOUT);
/* Read cause status bits. */
cause_status_bits = readl(priv->mst_cause->io +
MLXBF_I2C_CAUSE_ARBITER);
cause_status_bits &= MLXBF_I2C_CAUSE_MASTER_ARBITER_BITS_MASK;
/* * Parse both Cause and Master GW bits, then return transaction status.
*/
if (mlxbf_i2c_smbus_transaction_success(master_status_bits,
cause_status_bits)) return 0;
/* * In case of timeout on GW busy, the ISR will clear busy bit but * transaction ended bits cause will not be set so the transaction * fails. Then, we must check Master GW status bits.
*/ if ((master_status_bits & MLXBF_I2C_SMBUS_MASTER_STATUS_ERROR) &&
(cause_status_bits & (MLXBF_I2C_CAUSE_TRANSACTION_ENDED |
MLXBF_I2C_CAUSE_M_GW_BUSY_FALL))) return -EIO;
if (cause_status_bits & MLXBF_I2C_CAUSE_MASTER_STATUS_ERROR) return -EAGAIN;
/* * Copy data bytes from 4-byte aligned source buffer. * Data copied to the Master GW Data Descriptor MUST be shifted * left so the data starts at the MSB of the descriptor registers * as required by the underlying hardware. Enable byte swapping * when writing data bytes to the 32 * 32-bit HW Data registers * a.k.a Master GW Data Descriptor.
*/ for (offset = 0; offset < aligned_length; offset += sizeof(u32)) {
data32 = *((u32 *)(data + offset)); if (is_master)
iowrite32be(data32, priv->mst->io + addr + offset); else
iowrite32be(data32, priv->slv->io + addr + offset);
}
}
/* * Data bytes in the Master GW Data Descriptor are shifted left * so the data starts at the MSB of the descriptor registers as * set by the underlying hardware. Enable byte swapping while * reading data bytes from the 32 * 32-bit HW Data registers * a.k.a Master GW Data Descriptor.
*/
/* * Poll master status and check status bits. An ACK is sent when * completing writing data to the bus (Master 'byte_count_done' bit * is set to 1).
*/ return mlxbf_i2c_smbus_check_status(priv);
}
/* * Try to acquire the smbus gw lock before any reads of the GW register since * a read sets the lock.
*/
ret = readl_poll_timeout_atomic(priv->mst->io + MLXBF_I2C_SMBUS_MASTER_GW,
bits, !(bits & MLXBF_I2C_MASTER_LOCK_BIT),
MLXBF_I2C_POLL_FREQ_IN_USEC,
MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT); if (WARN_ON(ret)) return -EBUSY;
/* * SW must make sure that the SMBus Master GW is idle before starting * a transaction. Accordingly, this call polls the Master FSM stop bit; * it returns -ETIMEDOUT when the bit is asserted, 0 if not.
*/
ret = readl_poll_timeout_atomic(priv->mst->io + priv->chip->smbus_master_fsm_off,
bits, !(bits & MLXBF_I2C_SMBUS_MASTER_FSM_STOP_MASK),
MLXBF_I2C_POLL_FREQ_IN_USEC, MLXBF_I2C_SMBUS_TIMEOUT); if (WARN_ON(ret)) {
ret = -EBUSY; goto out_unlock;
}
/* Set first byte. */
data_desc[data_idx++] = addr;
/* * Note that read and write operations might be handled by a * single command. If the MLXBF_I2C_F_SMBUS_OPERATION is set * then write command byte and set the optional SMBus specific * bits such as block_en and pec_en. These bits MUST be * submitted by the first operation only.
*/ if (op_idx == 0 && flags & MLXBF_I2C_F_SMBUS_OPERATION) {
block_en = flags & MLXBF_I2C_F_SMBUS_BLOCK;
pec_en = flags & MLXBF_I2C_F_SMBUS_PEC;
}
/* * The stop condition can be skipped when writing on the bus * to implement a repeated start condition on the next read * as required for several SMBus and I2C operations.
*/ if (flags & MLXBF_I2C_F_WRITE_WITHOUT_STOP)
stop_after_write = false;
}
/* * We assume that read operations are performed only once per * SMBus transaction. *TBD* protect this statement so it won't * be executed twice? or return an error if we try to read more * than once?
*/ if (flags & MLXBF_I2C_F_READ) {
read_en = 1; /* Subtract 1 as required by HW. */
read_len = operation->length - 1;
read_buf = operation->buffer;
}
}
/* Set Master GW data descriptor. */
data_len = write_len + 1; /* Add one byte of the slave address. */ /* * Note that data_len cannot be 0. Indeed, the slave address byte * must be written to the data registers.
*/
mlxbf_i2c_smbus_write_data(priv, (const u8 *)data_desc, data_len,
MLXBF_I2C_MASTER_DATA_DESC_ADDR, true);
if (write_en) {
ret = mlxbf_i2c_smbus_enable(priv, slave, write_len, block_en,
pec_en, 0, stop_after_write); if (ret) goto out_unlock;
}
if (read_en) { /* Write slave address to Master GW data descriptor. */
mlxbf_i2c_smbus_write_data(priv, (const u8 *)&addr, 1,
MLXBF_I2C_MASTER_DATA_DESC_ADDR, true);
ret = mlxbf_i2c_smbus_enable(priv, slave, read_len, block_en,
pec_en, 1, true); if (!ret) { /* Get Master GW data descriptor. */
mlxbf_i2c_smbus_read_data(priv, data_desc, read_len + 1,
MLXBF_I2C_MASTER_DATA_DESC_ADDR, true);
/* Get data from Master GW data descriptor. */
memcpy(read_buf, data_desc, read_len + 1);
}
/* * After a read operation the SMBus FSM ps (present state) * needs to be 'manually' reset. This should be removed in * next tag integration.
*/
writel(MLXBF_I2C_SMBUS_MASTER_FSM_PS_STATE_MASK,
priv->mst->io + priv->chip->smbus_master_fsm_off);
}
out_unlock: /* Clear the gw to clear the lock */
writel(0, priv->mst->io + MLXBF_I2C_SMBUS_MASTER_GW);
if (read)
request->operation[0].flags |= MLXBF_I2C_F_WRITE_WITHOUT_STOP;
/* * As specified in the standard, the max number of bytes to read/write * per block operation is 32 bytes. In Golan code, the controller can * read up to 128 bytes and write up to 127 bytes.
*/
request->operation[1].length =
(*data_len + pec_check > I2C_SMBUS_BLOCK_MAX) ?
I2C_SMBUS_BLOCK_MAX : *data_len + pec_check;
request->operation[1].flags = read ?
MLXBF_I2C_F_READ : MLXBF_I2C_F_WRITE; /* * Skip the first data byte, which corresponds to the number of bytes * to read/write.
*/
request->operation[1].buffer = data + 1;
*data_len = request->operation[1].length;
/* Set the number of byte to read. This will be used by userspace. */ if (read)
data[0] = *data_len;
}
/* * Compute ticks as follow: * * Ticks * Time = --------- x 10^9 => Ticks = Time x Frequency x 10^-9 * Frequency
*/
frequency = priv->frequency;
ticks = div_u64(nanoseconds * frequency, MLXBF_I2C_FREQUENCY_1GHZ); /* * The number of ticks is rounded down and if minimum is equal to 1 * then add one tick.
*/ if (minimum)
ticks++;
gpio_res = mlxbf_i2c_get_shared_resource(priv, MLXBF_I2C_GPIO_RES); if (!gpio_res) return -EPERM;
/* * The GPIO region in TYU space is shared among I2C busses. * This function MUST be serialized to avoid racing when * claiming the memory region and/or setting up the GPIO.
*/
lockdep_assert_held(gpio_res->lock);
/* Check whether the memory map exist. */ if (gpio_res->io) return 0;
corepll_res = mlxbf_i2c_get_shared_resource(priv,
MLXBF_I2C_COREPLL_RES); if (!corepll_res) return -EPERM;
/* * The COREPLL region in TYU space is shared among I2C busses. * This function MUST be serialized to avoid racing when * claiming the memory region.
*/
lockdep_assert_held(corepll_res->lock);
/* Check whether the memory map exist. */ if (corepll_res->io) return 0;
/* This configuration is only needed for BlueField 1. */ if (!mlxbf_i2c_has_chip_type(priv, MLXBF_I2C_CHIP_TYPE_1)) return 0;
gpio_res = mlxbf_i2c_get_shared_resource(priv, MLXBF_I2C_GPIO_RES); if (!gpio_res) return -EPERM;
/* * The GPIO region in TYU space is shared among I2C busses. * This function MUST be serialized to avoid racing when * claiming the memory region and/or setting up the GPIO.
*/
mutex_lock(gpio_res->lock);
ret = mlxbf_i2c_get_gpio(pdev, priv); if (ret < 0) {
dev_err(dev, "Failed to get gpio resource");
mutex_unlock(gpio_res->lock); return ret;
}
/* * TYU - Configuration for GPIO pins. Those pins must be asserted in * MLXBF_I2C_GPIO_0_FUNC_EN_0, i.e. GPIO 0 is controlled by HW, and must * be reset in MLXBF_I2C_GPIO_0_FORCE_OE_EN, i.e. GPIO_OE will be driven * instead of HW_OE. * For now, we do not reset the GPIO state when the driver is removed. * First, it is not necessary to disable the bus since we are using * the same busses. Then, some busses might be shared among Linux and * platform firmware; disabling the bus might compromise the system * functionality.
*/
config_reg = readl(gpio_res->io + MLXBF_I2C_GPIO_0_FUNC_EN_0);
config_reg = MLXBF_I2C_GPIO_SMBUS_GW_ASSERT_PINS(priv->bus,
config_reg);
writel(config_reg, gpio_res->io + MLXBF_I2C_GPIO_0_FUNC_EN_0);
corepll_res = mlxbf_i2c_get_shared_resource(priv,
MLXBF_I2C_COREPLL_RES); if (!corepll_res) return -EPERM;
/* * First, check whether the TYU core Clock frequency is set. * The TYU core frequency is the same for all I2C busses; when * the first device gets probed the frequency is determined and * stored into a globally visible variable. So, first of all, * check whether the frequency is already set. Here, we assume * that the frequency is expected to be greater than 0.
*/
mutex_lock(corepll_res->lock); if (!mlxbf_i2c_corepll_frequency) { if (!chip->calculate_freq) {
mutex_unlock(corepll_res->lock); return -EPERM;
}
ret = mlxbf_i2c_get_corepll(pdev, priv); if (ret < 0) {
dev_err(dev, "Failed to get corePLL resource");
mutex_unlock(corepll_res->lock); return ret;
}
/* * Read the slave registers. There are 4 * 32-bit slave registers. * Each slave register can hold up to 4 * 8-bit slave configuration: * 1) A 7-bit address * 2) And a status bit (1 if enabled, 0 if not). * Look for the next available slave register slot.
*/ for (reg = 0; reg < reg_cnt; reg++) {
slave_reg = readl(priv->slv->io +
MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + reg * 0x4); /* * Each register holds 4 slave addresses. So, we have to keep * the byte order consistent with the value read in order to * update the register correctly, if needed.
*/
slave_reg_tmp = slave_reg; for (byte = 0; byte < 4; byte++) {
addr_tmp = slave_reg_tmp & GENMASK(7, 0);
/* * If an enable bit is not set in the * MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG register, then the * slave address slot associated with that bit is * free. So set the enable bit and write the * slave address bits.
*/ if (!(addr_tmp & MLXBF_I2C_SMBUS_SLAVE_ADDR_EN_BIT)) {
slave_reg &= ~(MLXBF_I2C_SMBUS_SLAVE_ADDR_MASK << (byte * 8));
slave_reg |= (slave->addr << (byte * 8));
slave_reg |= MLXBF_I2C_SMBUS_SLAVE_ADDR_EN_BIT << (byte * 8);
writel(slave_reg, priv->slv->io +
MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG +
(reg * 0x4));
/* * Set the slave at the corresponding index.
*/
priv->slave[(reg * 4) + byte] = slave;
/* * Read the slave registers. There are 4 * 32-bit slave registers. * Each slave register can hold up to 4 * 8-bit slave configuration: * 1) A 7-bit address * 2) And a status bit (1 if enabled, 0 if not). * Check if addr is present in the registers.
*/ for (reg = 0; reg < reg_cnt; reg++) {
slave_reg = readl(priv->slv->io +
MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + reg * 0x4);
/* Check whether the address slots are empty. */ if (!slave_reg) continue;
/* * Check if addr matches any of the 4 slave addresses * in the register.
*/
slave_reg_tmp = slave_reg; for (byte = 0; byte < 4; byte++) {
addr_tmp = slave_reg_tmp & MLXBF_I2C_SMBUS_SLAVE_ADDR_MASK; /* * Parse slave address bytes and check whether the * slave address already exists.
*/ if (addr_tmp == addr) { /* Clear the slave address slot. */
slave_reg &= ~(GENMASK(7, 0) << (byte * 8));
writel(slave_reg, priv->slv->io +
MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG +
(reg * 0x4)); /* Free slave at the corresponding index */
priv->slave[(reg * 4) + byte] = NULL;
return 0;
}
/* Parse next byte. */
slave_reg_tmp >>= 8;
}
}
return -ENXIO;
}
staticint mlxbf_i2c_init_coalesce(struct platform_device *pdev, struct mlxbf_i2c_priv *priv)
{ struct mlxbf_i2c_resource *coalesce_res; struct resource *params;
resource_size_t size; int ret = 0;
/* * Unlike BlueField-1 platform, the coalesce registers is a dedicated * resource in the next generations of BlueField.
*/ if (mlxbf_i2c_has_chip_type(priv, MLXBF_I2C_CHIP_TYPE_1)) {
coalesce_res = mlxbf_i2c_get_shared_resource(priv,
MLXBF_I2C_COALESCE_RES); if (!coalesce_res) return -EPERM;
/* * The Cause Coalesce group in TYU space is shared among * I2C busses. This function MUST be serialized to avoid * racing when claiming the memory region.
*/
lockdep_assert_held(mlxbf_i2c_gpio_res->lock);
/* Check whether the memory map exist. */ if (coalesce_res->io) {
priv->coalesce = coalesce_res; return 0;
}
/* * Enable slave cause interrupt bits. Drive * MLXBF_I2C_CAUSE_READ_WAIT_FW_RESPONSE and * MLXBF_I2C_CAUSE_WRITE_SUCCESS, these are enabled when an external * masters issue a Read and Write, respectively. But, clear all * interrupts first.
*/
writel(~0, priv->slv_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR);
int_reg = MLXBF_I2C_CAUSE_READ_WAIT_FW_RESPONSE;
int_reg |= MLXBF_I2C_CAUSE_WRITE_SUCCESS;
writel(int_reg, priv->slv_cause->io + MLXBF_I2C_CAUSE_OR_EVTEN0);
/* Finally, set the 'ready' bit to start handling transactions. */
writel(0x1, priv->slv->io + MLXBF_I2C_SMBUS_SLAVE_READY);
/* Initialize the cause coalesce resource. */
ret = mlxbf_i2c_init_coalesce(pdev, priv); if (ret < 0) {
dev_err(dev, "failed to initialize cause coalesce\n"); return ret;
}
/* Check the source of the interrupt, i.e. whether a Read or Write. */
cause_reg = readl(priv->slv_cause->io + MLXBF_I2C_CAUSE_ARBITER); if (cause_reg & MLXBF_I2C_CAUSE_READ_WAIT_FW_RESPONSE)
*read = true; elseif (cause_reg & MLXBF_I2C_CAUSE_WRITE_SUCCESS)
*write = true;
/* Clear cause bits. */
writel(~0x0, priv->slv_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR);
for (i = 0; i < MLXBF_I2C_SMBUS_SLAVE_ADDR_CNT; i++) { if (!priv->slave[i]) continue;
if (priv->slave[i]->addr == addr) return priv->slave[i];
}
return NULL;
}
/* * Send byte to 'external' smbus master. This function is executed when * an external smbus master wants to read data from the BlueField.
*/ staticint mlxbf_i2c_irq_send(struct mlxbf_i2c_priv *priv, u8 recv_bytes)
{
u8 data_desc[MLXBF_I2C_SLAVE_DATA_DESC_SIZE] = { 0 };
u8 write_size, pec_en, addr, value, byte_cnt; struct i2c_client *slave;
u32 control32, data32; int ret = 0;
/* * Read the first byte received from the external master to * determine the slave address. This byte is located in the * first data descriptor register of the slave GW.
*/
data32 = ioread32be(priv->slv->io +
MLXBF_I2C_SLAVE_DATA_DESC_ADDR);
addr = (data32 & GENMASK(7, 0)) >> 1;
/* * Check if the slave address received in the data descriptor register * matches any of the slave addresses registered. If there is a match, * set the slave.
*/
slave = mlxbf_i2c_get_slave_from_addr(priv, addr); if (!slave) {
ret = -ENXIO; goto clear_csr;
}
/* * An I2C read can consist of a WRITE bit transaction followed by * a READ bit transaction. Indeed, slave devices often expect * the slave address to be followed by the internal address. * So, write the internal address byte first, and then, send the * requested data to the master.
*/ if (recv_bytes > 1) {
i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value);
value = (data32 >> 8) & GENMASK(7, 0);
ret = i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED,
&value);
i2c_slave_event(slave, I2C_SLAVE_STOP, &value);
if (ret < 0) goto clear_csr;
}
/* * Send data to the master. Currently, the driver supports * READ_BYTE, READ_WORD and BLOCK READ protocols. The * hardware can send up to 128 bytes per transfer which is * the total size of the data registers.
*/
i2c_slave_event(slave, I2C_SLAVE_READ_REQUESTED, &value);
/* * Wait until the transfer is completed; the driver will wait * until the GW is idle, a cause will rise on fall of GW busy.
*/
readl_poll_timeout_atomic(priv->slv_cause->io + MLXBF_I2C_CAUSE_ARBITER,
data32, data32 & MLXBF_I2C_CAUSE_S_GW_BUSY_FALL,
MLXBF_I2C_POLL_FREQ_IN_USEC, MLXBF_I2C_SMBUS_TIMEOUT);
/* * Receive bytes from 'external' smbus master. This function is executed when * an external smbus master wants to write data to the BlueField.
*/ staticint mlxbf_i2c_irq_recv(struct mlxbf_i2c_priv *priv, u8 recv_bytes)
{
u8 data_desc[MLXBF_I2C_SLAVE_DATA_DESC_SIZE] = { 0 }; struct i2c_client *slave;
u8 value, byte, addr; int ret = 0;
/* Read data from Slave GW data descriptor. */
mlxbf_i2c_smbus_read_data(priv, data_desc, recv_bytes,
MLXBF_I2C_SLAVE_DATA_DESC_ADDR, false);
addr = data_desc[0] >> 1;
/* * Check if the slave address received in the data descriptor register * matches any of the slave addresses registered.
*/
slave = mlxbf_i2c_get_slave_from_addr(priv, addr); if (!slave) {
ret = -EINVAL; goto clear_csr;
}
/* * Notify the slave backend that an smbus master wants to write data * to the BlueField.
*/
i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value);
/* Send the received data to the slave backend. */ for (byte = 1; byte < recv_bytes; byte++) {
value = data_desc[byte];
ret = i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED,
&value); if (ret < 0) break;
}
/* * Send a stop event to the slave backend, to signal * the end of the write transactions.
*/
i2c_slave_event(slave, I2C_SLAVE_STOP, &value);
/* * Read TYU interrupt register and determine the source of the * interrupt. Based on the source of the interrupt one of the * following actions are performed: * - Receive data and send response to master. * - Send data and release slave GW. * * Handle read/write transaction only. CRmaster and Iarp requests * are ignored for now.
*/
irq_is_set = mlxbf_i2c_has_coalesce(priv, &read, &write); if (!irq_is_set || (!read && !write)) { /* Nothing to do here, interrupt was not from this device. */ return IRQ_NONE;
}
/* * The MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES includes the number of * bytes from/to master. These are defined by 8-bits each. If the lower * 8 bits are set, then the master expect to read N bytes from the * slave, if the higher 8 bits are sent then the slave expect N bytes * from the master.
*/
rw_bytes_reg = readl(priv->slv->io +
MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES);
recv_bytes = (rw_bytes_reg >> 8) & GENMASK(7, 0);
/* * For now, the slave supports 128 bytes transfer. Discard remaining * data bytes if the master wrote more than * MLXBF_I2C_SLAVE_DATA_DESC_SIZE, i.e, the actual size of the slave * data descriptor. * * Note that we will never expect to transfer more than 128 bytes; as * specified in the SMBus standard, block transactions cannot exceed * 32 bytes.
*/
recv_bytes = recv_bytes > MLXBF_I2C_SLAVE_DATA_DESC_SIZE ?
MLXBF_I2C_SLAVE_DATA_DESC_SIZE : recv_bytes;
if (read)
mlxbf_i2c_irq_send(priv, recv_bytes); else
mlxbf_i2c_irq_recv(priv, recv_bytes);
/* * Do not support ten bit chip address and do not use Packet Error * Checking (PEC).
*/ if (slave->flags & (I2C_CLIENT_TEN | I2C_CLIENT_PEC)) {
dev_err(dev, "SMBus PEC and 10 bit address not supported\n"); return -EAFNOSUPPORT;
}
ret = mlxbf_i2c_slave_enable(priv, slave); if (ret)
dev_err(dev, "Surpassed max number of registered slaves allowed\n");
/* * Unregister slave by: * 1) Disabling the slave address in hardware * 2) Freeing priv->slave at the corresponding index
*/
ret = mlxbf_i2c_slave_disable(priv, slave->addr); if (ret)
dev_err(dev, "Unable to find slave 0x%x\n", slave->addr);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.