diff options
Diffstat (limited to 'components/drivers/i2c/dev_i2c_dev.c')
| -rw-r--r-- | components/drivers/i2c/dev_i2c_dev.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/components/drivers/i2c/dev_i2c_dev.c b/components/drivers/i2c/dev_i2c_dev.c new file mode 100644 index 0000000000..96110b9e7d --- /dev/null +++ b/components/drivers/i2c/dev_i2c_dev.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2012-04-25 weety first version + * 2014-08-03 bernard fix some compiling warning + * 2021-04-20 RiceChen added support for bus clock control + */ + +#include <rtdevice.h> + +#define DBG_TAG "I2C" +#ifdef RT_I2C_DEBUG +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_INFO +#endif +#include <rtdbg.h> + +static rt_ssize_t i2c_bus_device_read(rt_device_t dev, + rt_off_t pos, + void *buffer, + rt_size_t count) +{ + rt_uint16_t addr; + rt_uint16_t flags; + struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; + + RT_ASSERT(bus != RT_NULL); + RT_ASSERT(buffer != RT_NULL); + + LOG_D("I2C bus dev [%s] reading %u bytes.", dev->parent.name, count); + + addr = pos & 0xffff; + flags = (pos >> 16) & 0xffff; + + return rt_i2c_master_recv(bus, addr, flags, (rt_uint8_t *)buffer, count); +} + +static rt_ssize_t i2c_bus_device_write(rt_device_t dev, + rt_off_t pos, + const void *buffer, + rt_size_t count) +{ + rt_uint16_t addr; + rt_uint16_t flags; + struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; + + RT_ASSERT(bus != RT_NULL); + RT_ASSERT(buffer != RT_NULL); + + LOG_D("I2C bus dev [%s] writing %u bytes.", dev->parent.name, count); + + addr = pos & 0xffff; + flags = (pos >> 16) & 0xffff; + + return rt_i2c_master_send(bus, addr, flags, (const rt_uint8_t *)buffer, count); +} + +static rt_err_t i2c_bus_device_control(rt_device_t dev, + int cmd, + void *args) +{ + rt_err_t ret; + struct rt_i2c_priv_data *priv_data; + struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; + + RT_ASSERT(bus != RT_NULL); + + switch (cmd) + { + /* set 10-bit addr mode */ + case RT_I2C_DEV_CTRL_10BIT: + bus->flags |= RT_I2C_ADDR_10BIT; + break; + case RT_I2C_DEV_CTRL_TIMEOUT: + bus->timeout = *(rt_uint32_t *)args; + break; + case RT_I2C_DEV_CTRL_RW: + priv_data = (struct rt_i2c_priv_data *)args; + ret = rt_i2c_transfer(bus, priv_data->msgs, priv_data->number); + if (ret < 0) + { + return -RT_EIO; + } + break; + default: + return rt_i2c_control(bus, cmd, args); + } + + return RT_EOK; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops i2c_ops = +{ + RT_NULL, + RT_NULL, + RT_NULL, + i2c_bus_device_read, + i2c_bus_device_write, + i2c_bus_device_control +}; +#endif + +rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus, + const char *name) +{ + struct rt_device *device; + RT_ASSERT(bus != RT_NULL); + + device = &bus->parent; + + device->user_data = bus; + + /* set device type */ + device->type = RT_Device_Class_I2CBUS; + /* initialize device interface */ +#ifdef RT_USING_DEVICE_OPS + device->ops = &i2c_ops; +#else + device->init = RT_NULL; + device->open = RT_NULL; + device->close = RT_NULL; + device->read = i2c_bus_device_read; + device->write = i2c_bus_device_write; + device->control = i2c_bus_device_control; +#endif + + /* register to device manager */ + rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); + + return RT_EOK; +} |
