Загрузка данных


static int sysconfig_i2c_bitstream_burst_write(struct sysconfig_priv *priv, const char *buf, size_t len)
{
    struct i2c_client *client = to_i2c_client(priv->dev);
    struct i2c_msg msg;
    const u8 lsc_bitstream_burst[] = SYSCONFIG_LSC_BITSTREAM_BURST; // 0x7A, 0x00, 0x00, 0x00
    size_t cmd_len = sizeof(lsc_bitstream_burst);
    size_t tx_buffer_len;
    u8 *tx_buffer;
    int ret;

    if (len == 0)
        return 0;

    size_t aligned_data_len = (len + 3) & ~3;
    size_t padding_bytes = aligned_data_len - len;
    tx_buffer_len = cmd_len + aligned_data_len;

    /* Выделяем монолитный буфер для всей сессии */
    tx_buffer = kmalloc(tx_buffer_len, GFP_KERNEL);
    if (!tx_buffer)
        return -ENOMEM;

    /* Собираем пакет: Сначала команда BURST, затем тело бинарника */
    memcpy(tx_buffer, lsc_bitstream_burst, cmd_len);
    memcpy(tx_buffer + cmd_len, buf, len);

    if (padding_bytes > 0)
        memset(tx_buffer + cmd_len + len, 0xFF, padding_bytes);

    /* ОДНО стандартное сообщение, без NOSTART */
    msg.addr = client->addr;
    msg.flags = client->flags & I2C_M_TEN; 
    msg.len = tx_buffer_len;
    msg.buf = tx_buffer;

    printk("%s(%d) Submitting single FLAT I2C transfer. Total size = %zu bytes.\n", 
            __FUNCTION__, __LINE__, tx_buffer_len);

    /* Вызов уйдет в чистый PIO режим благодаря модификации Шага 1 */
    ret = i2c_transfer(client->adapter, &msg, 1);

    kfree(tx_buffer);

    if (ret == 1) {
        printk("%s(%d) Burst stream successfully transmitted via flat PIO\n", __FUNCTION__, __LINE__);
        return 0;
    } else {
        dev_err(priv->dev, "Flat I2C burst transfer failed: %d\n", ret);
        return (ret < 0) ? ret : -EIO;
    }
}