xref: /haiku/src/add-ons/kernel/bus_managers/mmc/mmc_module.cpp (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
1 /*
2  * Copyright 2018-2021 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		B Krishnan Iyer, krishnaniyer97@gmail.com
7  *		Adrien Destugues, pulkomandy@pulkomandy.tk
8  */
9 #include "mmc_bus.h"
10 
11 
12 #define	MMC_BUS_DEVICE_NAME "bus_managers/mmc_bus/device/v1"
13 
14 
15 device_manager_info* gDeviceManager = NULL;
16 
17 
18 static status_t
19 mmc_bus_init(device_node* node, void** _device)
20 {
21 	CALLED();
22 	MMCBus* device = new(std::nothrow) MMCBus(node);
23 	if (device == NULL) {
24 		ERROR("Unable to allocate MMC bus\n");
25 		return B_NO_MEMORY;
26 	}
27 
28 	status_t result = device->InitCheck();
29 	if (result != B_OK) {
30 		TRACE("failed to set up mmc bus device object\n");
31 		return result;
32 	}
33 	TRACE("MMC bus object created\n");
34 
35 	*_device = device;
36 	return B_OK;
37 }
38 
39 
40 static void
41 mmc_bus_uninit(void* _device)
42 {
43 	CALLED();
44 	MMCBus* device = (MMCBus*)_device;
45 	delete device;
46 }
47 
48 
49 static status_t
50 mmc_bus_register_child(void* _device)
51 {
52 	// Nothing to do, child devices are registered by the scanning thread
53 	return B_OK;
54 }
55 
56 
57 static void
58 mmc_bus_removed(void* _device)
59 {
60 	CALLED();
61 }
62 
63 
64 status_t
65 mmc_bus_added_device(device_node* parent)
66 {
67 	CALLED();
68 
69 	device_attr attributes[] = {
70 		{ B_DEVICE_BUS, B_STRING_TYPE, { string: "mmc"}},
71 		{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "MMC bus root"}},
72 		{ NULL }
73 	};
74 
75 	return gDeviceManager->register_node(parent, MMC_BUS_DEVICE_NAME,
76 		attributes, NULL, NULL);
77 }
78 
79 
80 static status_t
81 mmc_bus_execute_command(device_node* node, void* cookie, uint16_t rca,
82 	uint8_t command, uint32_t argument, uint32_t* result)
83 {
84 	TRACE("In mmc_bus_execute_command\n");
85 
86 	MMCBus* bus = (MMCBus*)cookie;
87 
88 	bus->AcquireBus();
89 	status_t error = bus->ExecuteCommand(rca, command, argument, result);
90 	bus->ReleaseBus();
91 
92 	return error;
93 }
94 
95 
96 static status_t
97 mmc_bus_do_io(device_node* node, void* cookie, uint16_t rca, uint8_t command,
98 	IOOperation* operation, bool offsetAsSectors)
99 {
100 	MMCBus* bus = (MMCBus*)cookie;
101 	status_t result = B_OK;
102 
103 	bus->AcquireBus();
104 	result = bus->DoIO(rca, command, operation, offsetAsSectors);
105 	bus->ReleaseBus();
106 
107 	return result;
108 }
109 
110 
111 static void
112 mmc_bus_set_width(device_node* node, void* cookie, int width)
113 {
114 	MMCBus* bus = (MMCBus*)cookie;
115 
116 	bus->AcquireBus();
117 	bus->SetBusWidth(width);
118 	bus->ReleaseBus();
119 }
120 
121 
122 static status_t
123 std_ops(int32 op, ...)
124 {
125 	switch (op) {
126 		case B_MODULE_INIT:
127 			// Nothing to do
128 		case B_MODULE_UNINIT:
129 			return B_OK;
130 
131 		default:
132 			break;
133 	}
134 
135 	return B_ERROR;
136 }
137 
138 
139 driver_module_info mmc_bus_device_module = {
140 	{
141 		MMC_BUS_DEVICE_NAME,
142 		0,
143 		std_ops
144 	},
145 	NULL, // supported devices
146 	NULL, // register node
147 	mmc_bus_init,
148 	mmc_bus_uninit,
149 	mmc_bus_register_child,
150 	NULL, // rescan
151 	mmc_bus_removed,
152 	NULL, // suspend
153 	NULL // resume
154 };
155 
156 
157 mmc_device_interface mmc_bus_controller_module = {
158 	{
159 		{
160 			MMC_BUS_MODULE_NAME,
161 			0,
162 			&std_ops
163 		},
164 
165 		NULL, // supported devices
166 		mmc_bus_added_device,
167 		NULL,
168 		NULL,
169 		NULL
170 	},
171 	mmc_bus_execute_command,
172 	mmc_bus_do_io,
173 	mmc_bus_set_width
174 };
175 
176 
177 module_dependency module_dependencies[] = {
178 	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
179 	{}
180 };
181 
182 
183 module_info* modules[] = {
184 	(module_info*)&mmc_bus_controller_module,
185 	(module_info*)&mmc_bus_device_module,
186 	NULL
187 };
188