Open the kernel configuration entry config_i2c_chardev and load the I2c-dev module.
Device node:/dev/i2c-x.
User space accesses any I2C device mounted to the I2C adapter through the device node.
The Read/write function of the I2c-dev module does not support block transport, which transmits up to 8 bytes of data at a time.
Modifying the Read/write function supports DMA transfers for block transfer. The limit for DMA transfer BUFFER size is 255 bytes.
Code modified as follows: I2C-DEV.C
#include <linux/dma-mapping.h>
#define MAX_BUFFER_SIZE 255
Static ssize_t i2cdev_write_dma (struct file *file,const char __user *buf, size_t count, loff_t *offset)
{
int ret;
struct I2c_client *client = file->private_data;
char *pi2cdmawritebuf = NULL;
unsigned int phyaddrfordmabuf = 0;
if (Count > Max_buffer_size)
Count = max_buffer_size;
PI2CDMAWRITEBUF = (char *) dma_alloc_coherent (NULL, Max_buffer_size, &phyaddrfordmabuf, Gfp_kernel);
if (pi2cdmawritebuf = NULL)
{
Return-enomem;
}
if (Copyt_from_user (Pi2cdmawritebuf, buf, Count))
{
Error
Dma_free_coherent (NULL, Max_buffer_size, Pi2cdmawritebuf, phyaddrfordmabuf);
Pi2cdmawritebuf = NULL;
phyaddrfordmabuf = 0;
Return-efault;
}
Client->addr &= I2c_mask_flag;
Client->ext_flag |= I2c_dma_flag;
Client->ext_flag |= i2c_a_filter_msg;
RET = i2c_master_sent (client, (unsigned char *) phyaddrfordmabuf, count);
Dma_free_coherent (NULL, Max_buffer_size, Pi2cdmawritebuf, phyaddrfordmabuf);
Pi2cdmawritebuf = NULL;
phyaddrfordmabuf = 0;
return ret;
}
Static ssize_t i2cdev_write_dma (struct file *file,const char __user *buf, size_t count, loff_t *offset)
{
int ret;
struct I2c_client *client = file->private_data;
char *pi2cdmareadbuf = NULL;
unsigned int phyaddrfordmabuf = 0;
if (Count > Max_buffer_size)
Count = max_buffer_size;
PI2CDMAREADBUF = (char *) dma_alloc_coherent (NULL, Max_buffer_size, &phyaddrfordmabuf, Gfp_kernel);
if (pi2cdmareadbuf = NULL)
{
Return-enomem;
}
Client->addr &= I2c_mask_flag;
Client->ext_flag |= I2c_dma_flag;
Client->ext_flag |= i2c_a_filter_msg;
RET = I2C_MASTER_RECV (client, (unsigned char *) phyaddrfordmabuf, count);
if (ret >= 0)
{
if (Copy_to_user (buf, PI2CDMAREADBUF, ret))
{
ret =-efault;
}
}
Dma_free_coherent (NULL, Max_buffer_size, Pi2cdmareadbuf, phyaddrfordmabuf);
Pi2cdmawritebuf = NULL;
phyaddrfordmabuf = 0;
return ret;
}
static const struct File_operations I2cdev_fops = {
...
. read= I2CDEV_READ_DMA,
. write = I2CDEV_WRITE_DMA,
};