mirror of
https://github.com/pine64/bl_iot_sdk.git
synced 2024-11-20 08:10:00 +00:00
144 lines
3.4 KiB
C
144 lines
3.4 KiB
C
/*
|
|
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
|
*/
|
|
|
|
#include "device/vfs_i2c.h"
|
|
#include "hal/soc/soc.h"
|
|
#include "vfs_err.h"
|
|
|
|
/* i2c driver struct */
|
|
const struct file_ops i2c_ops =
|
|
{
|
|
.open = vfs_i2c_open,
|
|
.close = vfs_i2c_close,
|
|
.read = vfs_i2c_read,
|
|
.write = vfs_i2c_write
|
|
};
|
|
|
|
int vfs_i2c_open(inode_t *inode, file_t *fp)
|
|
{
|
|
int ret = -1; /* return value */
|
|
i2c_dev_t *i2c_dev = NULL; /* device pointer */
|
|
|
|
/* check empty pointer. */
|
|
if ((fp != NULL) && (fp->node != NULL)) {
|
|
|
|
/* Initialize if the device is first opened. */
|
|
if (fp->node->refs == 1) {
|
|
|
|
/* get the device pointer. */
|
|
i2c_dev = (i2c_dev_t *)(fp->node->i_arg);
|
|
|
|
/* init i2c device. */
|
|
ret = hal_i2c_init(i2c_dev);
|
|
} else {
|
|
ret = VFS_SUCCESS;
|
|
}
|
|
} else {
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int vfs_i2c_close(file_t *fp)
|
|
{
|
|
int ret = -1; /* return value */
|
|
i2c_dev_t *i2c_dev = NULL; /* device pointer */
|
|
|
|
/* check empty pointer. */
|
|
if ((fp != NULL) && (fp->node != NULL)) {
|
|
|
|
/* close device if the device is last closed. */
|
|
if (fp->node->refs == 1) {
|
|
|
|
/* get the device pointer. */
|
|
i2c_dev = (i2c_dev_t *)(fp->node->i_arg);
|
|
|
|
if (i2c_dev != NULL) {
|
|
|
|
/* turns off hardware. */
|
|
ret = hal_i2c_finalize(i2c_dev);
|
|
} else {
|
|
ret = -EINVAL;
|
|
}
|
|
} else {
|
|
ret = VFS_SUCCESS;
|
|
}
|
|
} else {
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
ssize_t vfs_i2c_read(file_t *fp, void *buf, size_t nbytes)
|
|
{
|
|
int ret = -1; /* return value */
|
|
i2c_dev_t *i2c_dev = NULL; /* device pointer */
|
|
uint16_t dev_addr = 0; /* dev address */
|
|
|
|
/* check empty pointer. */
|
|
if ((fp != NULL) && (fp->node != NULL)) {
|
|
|
|
/* get the device pointer. */
|
|
i2c_dev = (i2c_dev_t *)(fp->node->i_arg);
|
|
|
|
/* get the device address. */
|
|
dev_addr = i2c_dev->config.dev_addr;
|
|
|
|
if (dev_addr != NULL) {
|
|
|
|
/* get data from i2c. */
|
|
ret = hal_i2c_master_recv(i2c_dev, dev_addr, (uint8_t *)buf, nbytes, HAL_WAIT_FOREVER);
|
|
|
|
/* If the data is read correctly, the return
|
|
value is set to read bytes. */
|
|
if (ret == 0) {
|
|
ret = nbytes;
|
|
}
|
|
} else {
|
|
ret = -EINVAL;
|
|
}
|
|
} else {
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
ssize_t vfs_i2c_write(file_t *fp, const void *buf, size_t nbytes)
|
|
{
|
|
int ret = -1; /* return value */
|
|
i2c_dev_t *i2c_dev = NULL; /* device pointer */
|
|
uint16_t dev_addr = 0; /* dev address */
|
|
|
|
/* check empty pointer. */
|
|
if ((fp != NULL) && (fp->node != NULL)) {
|
|
|
|
/* get the device pointer. */
|
|
i2c_dev = (i2c_dev_t *)(fp->node->i_arg);
|
|
|
|
/* get the device address. */
|
|
dev_addr = i2c_dev->config.dev_addr;
|
|
|
|
if (dev_addr != NULL) {
|
|
|
|
/* send data from i2c. */
|
|
ret = hal_i2c_master_send(i2c_dev, dev_addr, (const uint8_t *)buf, nbytes, HAL_WAIT_FOREVER);
|
|
|
|
/* If the data is sent successfully, set the return
|
|
value to nbytes. */
|
|
if (ret == 0) {
|
|
ret = nbytes;
|
|
}
|
|
} else {
|
|
ret = -EINVAL;
|
|
}
|
|
} else {
|
|
ret = -EINVAL;
|
|
}
|
|
|
|
return ret;
|
|
}
|