xref: /haiku/src/add-ons/kernel/bus_managers/i2c/I2CDevice.cpp (revision 01990a00e8ffa3bda55324a0931ae386860d12c9)
1 /*
2  * Copyright 2020, Jérôme Duval, jerome.duval@gmail.com.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "I2CPrivate.h"
8 
9 
I2CDevice(device_node * node,I2CBus * bus,i2c_addr slaveAddress)10 I2CDevice::I2CDevice(device_node *node, I2CBus* bus, i2c_addr slaveAddress)
11 	:
12 	fNode(node),
13 	fBus(bus),
14 	fSlaveAddress(slaveAddress)
15 {
16 	CALLED();
17 }
18 
19 
~I2CDevice()20 I2CDevice::~I2CDevice()
21 {
22 }
23 
24 
25 status_t
InitCheck()26 I2CDevice::InitCheck()
27 {
28 	return B_OK;
29 }
30 
31 
32 status_t
ExecCommand(i2c_op op,const void * cmdBuffer,size_t cmdLength,void * dataBuffer,size_t dataLength)33 I2CDevice::ExecCommand(i2c_op op, const void *cmdBuffer,
34 	size_t cmdLength, void* dataBuffer, size_t dataLength)
35 {
36 	CALLED();
37 	return fBus->ExecCommand(op, fSlaveAddress, cmdBuffer, cmdLength,
38 		dataBuffer, dataLength);
39 }
40 
41 
42 status_t
AcquireBus()43 I2CDevice::AcquireBus()
44 {
45 	CALLED();
46 	return fBus->AcquireBus();
47 }
48 
49 
50 void
ReleaseBus()51 I2CDevice::ReleaseBus()
52 {
53 	CALLED();
54 	fBus->ReleaseBus();
55 }
56 
57 
58 static status_t
i2c_init_device(device_node * node,void ** _device)59 i2c_init_device(device_node *node, void **_device)
60 {
61 	CALLED();
62 	I2CBus* bus;
63 
64 	{
65 		device_node *parent = gDeviceManager->get_parent_node(node);
66 		gDeviceManager->get_driver(parent, NULL, (void **)&bus);
67 		gDeviceManager->put_node(parent);
68 	}
69 
70 	uint16 slaveAddress;
71 	if (gDeviceManager->get_attr_uint16(node, I2C_DEVICE_SLAVE_ADDR_ITEM,
72 		&slaveAddress, false) != B_OK) {
73 		return B_ERROR;
74 	}
75 
76 
77 	I2CDevice *device = new(std::nothrow) I2CDevice(node, bus, slaveAddress);
78 	if (device == NULL)
79 		return B_NO_MEMORY;
80 
81 	status_t result = device->InitCheck();
82 	if (result != B_OK) {
83 		ERROR("failed to set up i2c device object\n");
84 		return result;
85 	}
86 
87 	*_device = device;
88 
89 	return B_OK;
90 }
91 
92 
93 static void
i2c_uninit_device(void * _device)94 i2c_uninit_device(void *_device)
95 {
96 	CALLED();
97 	I2CDevice *device = (I2CDevice *)_device;
98 	delete device;
99 }
100 
101 
102 static void
i2c_device_removed(void * _device)103 i2c_device_removed(void *_device)
104 {
105 	CALLED();
106 	//I2CDevice *device = (I2CDevice *)_device;
107 }
108 
109 
110 static status_t
i2c_exec_command(i2c_device _device,i2c_op op,const void * cmdBuffer,size_t cmdLength,void * dataBuffer,size_t dataLength)111 i2c_exec_command(i2c_device _device, i2c_op op, const void *cmdBuffer,
112 	size_t cmdLength, void* dataBuffer, size_t dataLength)
113 {
114 	I2CDevice *device = (I2CDevice *)_device;
115 	return device->ExecCommand(op, cmdBuffer, cmdLength, dataBuffer, dataLength);
116 }
117 
118 
119 static status_t
i2c_acquire_bus(i2c_device _device)120 i2c_acquire_bus(i2c_device _device)
121 {
122 	I2CDevice *device = (I2CDevice *)_device;
123 	return device->AcquireBus();
124 }
125 
126 
127 static void
i2c_release_bus(i2c_device _device)128 i2c_release_bus(i2c_device _device)
129 {
130 	I2CDevice *device = (I2CDevice *)_device;
131 	return device->ReleaseBus();
132 }
133 
134 
135 static status_t
std_ops(int32 op,...)136 std_ops(int32 op, ...)
137 {
138 	switch (op) {
139 		case B_MODULE_INIT:
140 		{
141 			// Link to I2C bus.
142 			// I2C device driver must have I2C bus loaded, but it calls its
143 			// functions directly instead via official interface, so this
144 			// pointer is never read.
145 			module_info *dummy;
146 			return get_module(I2C_BUS_MODULE_NAME, &dummy);
147 		}
148 		case B_MODULE_UNINIT:
149 			return put_module(I2C_BUS_MODULE_NAME);
150 
151 		default:
152 			return B_ERROR;
153 	}
154 }
155 
156 
157 i2c_device_interface gI2CDeviceModule = {
158 	{
159 		{
160 			I2C_DEVICE_MODULE_NAME,
161 			0,
162 			std_ops
163 		},
164 
165 		NULL,	// supported devices
166 		NULL,	// register node
167 		i2c_init_device,
168 		(void (*)(void *)) i2c_uninit_device,
169 		NULL,	// register child devices
170 		NULL,	// rescan
171 		(void (*)(void *)) i2c_device_removed
172 	},
173 	i2c_exec_command,
174 	i2c_acquire_bus,
175 	i2c_release_bus,
176 };
177