1*10465441SEvalZero /*
2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero *
4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date Author Notes
8*10465441SEvalZero * 2012-04-25 weety first version
9*10465441SEvalZero * 2014-08-03 bernard fix some compiling warning
10*10465441SEvalZero */
11*10465441SEvalZero
12*10465441SEvalZero #include <rtdevice.h>
13*10465441SEvalZero
i2c_bus_device_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t count)14*10465441SEvalZero static rt_size_t i2c_bus_device_read(rt_device_t dev,
15*10465441SEvalZero rt_off_t pos,
16*10465441SEvalZero void *buffer,
17*10465441SEvalZero rt_size_t count)
18*10465441SEvalZero {
19*10465441SEvalZero rt_uint16_t addr;
20*10465441SEvalZero rt_uint16_t flags;
21*10465441SEvalZero struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data;
22*10465441SEvalZero
23*10465441SEvalZero RT_ASSERT(bus != RT_NULL);
24*10465441SEvalZero RT_ASSERT(buffer != RT_NULL);
25*10465441SEvalZero
26*10465441SEvalZero i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", dev->parent.name, count);
27*10465441SEvalZero
28*10465441SEvalZero addr = pos & 0xffff;
29*10465441SEvalZero flags = (pos >> 16) & 0xffff;
30*10465441SEvalZero
31*10465441SEvalZero return rt_i2c_master_recv(bus, addr, flags, buffer, count);
32*10465441SEvalZero }
33*10465441SEvalZero
i2c_bus_device_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t count)34*10465441SEvalZero static rt_size_t i2c_bus_device_write(rt_device_t dev,
35*10465441SEvalZero rt_off_t pos,
36*10465441SEvalZero const void *buffer,
37*10465441SEvalZero rt_size_t count)
38*10465441SEvalZero {
39*10465441SEvalZero rt_uint16_t addr;
40*10465441SEvalZero rt_uint16_t flags;
41*10465441SEvalZero struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data;
42*10465441SEvalZero
43*10465441SEvalZero RT_ASSERT(bus != RT_NULL);
44*10465441SEvalZero RT_ASSERT(buffer != RT_NULL);
45*10465441SEvalZero
46*10465441SEvalZero i2c_dbg("I2C bus dev [%s] writing %u bytes.\n", dev->parent.name, count);
47*10465441SEvalZero
48*10465441SEvalZero addr = pos & 0xffff;
49*10465441SEvalZero flags = (pos >> 16) & 0xffff;
50*10465441SEvalZero
51*10465441SEvalZero return rt_i2c_master_send(bus, addr, flags, buffer, count);
52*10465441SEvalZero }
53*10465441SEvalZero
i2c_bus_device_control(rt_device_t dev,int cmd,void * args)54*10465441SEvalZero static rt_err_t i2c_bus_device_control(rt_device_t dev,
55*10465441SEvalZero int cmd,
56*10465441SEvalZero void *args)
57*10465441SEvalZero {
58*10465441SEvalZero rt_err_t ret;
59*10465441SEvalZero struct rt_i2c_priv_data *priv_data;
60*10465441SEvalZero struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data;
61*10465441SEvalZero
62*10465441SEvalZero RT_ASSERT(bus != RT_NULL);
63*10465441SEvalZero
64*10465441SEvalZero switch (cmd)
65*10465441SEvalZero {
66*10465441SEvalZero /* set 10-bit addr mode */
67*10465441SEvalZero case RT_I2C_DEV_CTRL_10BIT:
68*10465441SEvalZero bus->flags |= RT_I2C_ADDR_10BIT;
69*10465441SEvalZero break;
70*10465441SEvalZero case RT_I2C_DEV_CTRL_ADDR:
71*10465441SEvalZero bus->addr = *(rt_uint16_t *)args;
72*10465441SEvalZero break;
73*10465441SEvalZero case RT_I2C_DEV_CTRL_TIMEOUT:
74*10465441SEvalZero bus->timeout = *(rt_uint32_t *)args;
75*10465441SEvalZero break;
76*10465441SEvalZero case RT_I2C_DEV_CTRL_RW:
77*10465441SEvalZero priv_data = (struct rt_i2c_priv_data *)args;
78*10465441SEvalZero ret = rt_i2c_transfer(bus, priv_data->msgs, priv_data->number);
79*10465441SEvalZero if (ret < 0)
80*10465441SEvalZero {
81*10465441SEvalZero return -RT_EIO;
82*10465441SEvalZero }
83*10465441SEvalZero break;
84*10465441SEvalZero default:
85*10465441SEvalZero break;
86*10465441SEvalZero }
87*10465441SEvalZero
88*10465441SEvalZero return RT_EOK;
89*10465441SEvalZero }
90*10465441SEvalZero
91*10465441SEvalZero #ifdef RT_USING_DEVICE_OPS
92*10465441SEvalZero const static struct rt_device_ops i2c_ops =
93*10465441SEvalZero {
94*10465441SEvalZero RT_NULL,
95*10465441SEvalZero RT_NULL,
96*10465441SEvalZero RT_NULL,
97*10465441SEvalZero i2c_bus_device_read,
98*10465441SEvalZero i2c_bus_device_write,
99*10465441SEvalZero i2c_bus_device_control
100*10465441SEvalZero };
101*10465441SEvalZero #endif
102*10465441SEvalZero
rt_i2c_bus_device_device_init(struct rt_i2c_bus_device * bus,const char * name)103*10465441SEvalZero rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus,
104*10465441SEvalZero const char *name)
105*10465441SEvalZero {
106*10465441SEvalZero struct rt_device *device;
107*10465441SEvalZero RT_ASSERT(bus != RT_NULL);
108*10465441SEvalZero
109*10465441SEvalZero device = &bus->parent;
110*10465441SEvalZero
111*10465441SEvalZero device->user_data = bus;
112*10465441SEvalZero
113*10465441SEvalZero /* set device type */
114*10465441SEvalZero device->type = RT_Device_Class_I2CBUS;
115*10465441SEvalZero /* initialize device interface */
116*10465441SEvalZero #ifdef RT_USING_DEVICE_OPS
117*10465441SEvalZero device->ops = &i2c_ops;
118*10465441SEvalZero #else
119*10465441SEvalZero device->init = RT_NULL;
120*10465441SEvalZero device->open = RT_NULL;
121*10465441SEvalZero device->close = RT_NULL;
122*10465441SEvalZero device->read = i2c_bus_device_read;
123*10465441SEvalZero device->write = i2c_bus_device_write;
124*10465441SEvalZero device->control = i2c_bus_device_control;
125*10465441SEvalZero #endif
126*10465441SEvalZero
127*10465441SEvalZero /* register to device manager */
128*10465441SEvalZero rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
129*10465441SEvalZero
130*10465441SEvalZero return RT_EOK;
131*10465441SEvalZero }
132