xref: /haiku/src/add-ons/kernel/bus_managers/mmc/mmc_module.cpp (revision 74b60970787e901984a6bc0518cbe2d58b092589)
125b6a6f1Skrish_iyer /*
225b6a6f1Skrish_iyer  * Copyright 2018 Haiku, Inc. All rights reserved.
325b6a6f1Skrish_iyer  * Distributed under the terms of the MIT License.
425b6a6f1Skrish_iyer  *
525b6a6f1Skrish_iyer  * Authors:
625b6a6f1Skrish_iyer  *		B Krishnan Iyer, krishnaniyer97@gmail.com
725b6a6f1Skrish_iyer  */
825b6a6f1Skrish_iyer #include "mmc_bus.h"
925b6a6f1Skrish_iyer 
1025b6a6f1Skrish_iyer 
11ff76d2dfSAdrien Destugues #define	MMC_BUS_DEVICE_NAME "bus_managers/mmc_bus/device/v1"
12ff76d2dfSAdrien Destugues 
13ff76d2dfSAdrien Destugues 
1425b6a6f1Skrish_iyer device_manager_info* gDeviceManager = NULL;
1525b6a6f1Skrish_iyer 
1625b6a6f1Skrish_iyer 
1725b6a6f1Skrish_iyer static status_t
1825b6a6f1Skrish_iyer mmc_bus_init(device_node* node, void** _device)
1925b6a6f1Skrish_iyer {
2025b6a6f1Skrish_iyer 	CALLED();
2125b6a6f1Skrish_iyer 	MMCBus* device = new(std::nothrow) MMCBus(node);
2225b6a6f1Skrish_iyer 	if (device == NULL) {
2325b6a6f1Skrish_iyer 		ERROR("Unable to allocate MMC bus\n");
2425b6a6f1Skrish_iyer 		return B_NO_MEMORY;
2525b6a6f1Skrish_iyer 	}
2625b6a6f1Skrish_iyer 
2725b6a6f1Skrish_iyer 	status_t result = device->InitCheck();
2825b6a6f1Skrish_iyer 	if (result != B_OK) {
2925b6a6f1Skrish_iyer 		TRACE("failed to set up mmc bus device object\n");
3025b6a6f1Skrish_iyer 		return result;
3125b6a6f1Skrish_iyer 	}
3225b6a6f1Skrish_iyer 	TRACE("MMC bus object created\n");
3325b6a6f1Skrish_iyer 
3425b6a6f1Skrish_iyer 	*_device = device;
3525b6a6f1Skrish_iyer 	return B_OK;
3625b6a6f1Skrish_iyer }
3725b6a6f1Skrish_iyer 
3825b6a6f1Skrish_iyer 
3925b6a6f1Skrish_iyer static void
4025b6a6f1Skrish_iyer mmc_bus_uninit(void* _device)
4125b6a6f1Skrish_iyer {
4225b6a6f1Skrish_iyer 	CALLED();
4325b6a6f1Skrish_iyer 	MMCBus* device = (MMCBus*)_device;
4425b6a6f1Skrish_iyer 	delete device;
4525b6a6f1Skrish_iyer }
4625b6a6f1Skrish_iyer 
4725b6a6f1Skrish_iyer 
48dedbe94eSAdrien Destugues static status_t
49dedbe94eSAdrien Destugues mmc_bus_register_child(void* _device)
50dedbe94eSAdrien Destugues {
51dedbe94eSAdrien Destugues 	CALLED();
52dedbe94eSAdrien Destugues 	MMCBus* device = (MMCBus*)_device;
53dedbe94eSAdrien Destugues 	device->Rescan();
54dedbe94eSAdrien Destugues 	return B_OK;
55dedbe94eSAdrien Destugues }
56dedbe94eSAdrien Destugues 
57dedbe94eSAdrien Destugues 
5825b6a6f1Skrish_iyer static void
5925b6a6f1Skrish_iyer mmc_bus_removed(void* _device)
6025b6a6f1Skrish_iyer {
6125b6a6f1Skrish_iyer 	CALLED();
6225b6a6f1Skrish_iyer }
6325b6a6f1Skrish_iyer 
6425b6a6f1Skrish_iyer 
6525b6a6f1Skrish_iyer status_t
6625b6a6f1Skrish_iyer mmc_bus_added_device(device_node* parent)
6725b6a6f1Skrish_iyer {
6825b6a6f1Skrish_iyer 	CALLED();
6925b6a6f1Skrish_iyer 
7025b6a6f1Skrish_iyer 	device_attr attributes[] = {
71dedbe94eSAdrien Destugues 		{ B_DEVICE_BUS, B_STRING_TYPE, { string: "mmc"}},
72dedbe94eSAdrien Destugues 		{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "MMC bus root"}},
7325b6a6f1Skrish_iyer 		{ NULL }
7425b6a6f1Skrish_iyer 	};
7525b6a6f1Skrish_iyer 
76ff76d2dfSAdrien Destugues 	return gDeviceManager->register_node(parent, MMC_BUS_DEVICE_NAME,
7725b6a6f1Skrish_iyer 		attributes, NULL, NULL);
7825b6a6f1Skrish_iyer }
7925b6a6f1Skrish_iyer 
8025b6a6f1Skrish_iyer 
8125b6a6f1Skrish_iyer static status_t
8262eaf4c0SAdrien Destugues mmc_bus_execute_command(device_node* node, uint8_t command, uint32_t argument,
8362eaf4c0SAdrien Destugues 	uint32_t* result)
8462eaf4c0SAdrien Destugues {
85*74b60970SAnarchos 	// FIXME store the parent cookie in the bus cookie or something instead of
86*74b60970SAnarchos 	// getting/putting the parent each time.
87*74b60970SAnarchos 	driver_module_info* mmc;
8862eaf4c0SAdrien Destugues 	void* cookie;
8962eaf4c0SAdrien Destugues 
9062eaf4c0SAdrien Destugues 	TRACE("In mmc_bus_execute_command\n");
9162eaf4c0SAdrien Destugues 	device_node* parent = gDeviceManager->get_parent_node(node);
92*74b60970SAnarchos 	gDeviceManager->get_driver(parent, &mmc, &cookie);
9362eaf4c0SAdrien Destugues 	gDeviceManager->put_node(parent);
9462eaf4c0SAdrien Destugues 
95*74b60970SAnarchos 	MMCBus* bus = (MMCBus*)cookie;
96*74b60970SAnarchos 
97*74b60970SAnarchos 	bus->AcquireBus();
98*74b60970SAnarchos 	status_t error = bus->ExecuteCommand(command, argument, result);
99*74b60970SAnarchos 	bus->ReleaseBus();
100*74b60970SAnarchos 	return error;
101*74b60970SAnarchos }
102*74b60970SAnarchos 
103*74b60970SAnarchos 
104*74b60970SAnarchos static status_t
105*74b60970SAnarchos mmc_bus_read_naive(device_node* node, uint16_t rca, off_t pos, void* buffer,
106*74b60970SAnarchos 	size_t* _length)
107*74b60970SAnarchos {
108*74b60970SAnarchos 	// FIXME store the parent cookie in the bus cookie or something instead of
109*74b60970SAnarchos 	// getting/putting the parent each time.
110*74b60970SAnarchos 	driver_module_info* mmc;
111*74b60970SAnarchos 	void* cookie;
112*74b60970SAnarchos 
113*74b60970SAnarchos 	device_node* parent = gDeviceManager->get_parent_node(node);
114*74b60970SAnarchos 	gDeviceManager->get_driver(parent, &mmc, &cookie);
115*74b60970SAnarchos 	gDeviceManager->put_node(parent);
116*74b60970SAnarchos 
117*74b60970SAnarchos 	MMCBus* bus = (MMCBus*)cookie;
118*74b60970SAnarchos 	bus->AcquireBus();
119*74b60970SAnarchos 	status_t result = bus->Read(rca, pos, buffer, _length);
120*74b60970SAnarchos 	bus->ReleaseBus();
121*74b60970SAnarchos 	return result;
12262eaf4c0SAdrien Destugues }
12362eaf4c0SAdrien Destugues 
12462eaf4c0SAdrien Destugues 
12562eaf4c0SAdrien Destugues static status_t
12625b6a6f1Skrish_iyer std_ops(int32 op, ...)
12725b6a6f1Skrish_iyer {
12825b6a6f1Skrish_iyer 	switch (op) {
12925b6a6f1Skrish_iyer 		case B_MODULE_INIT:
13025b6a6f1Skrish_iyer 			// Nothing to do
13125b6a6f1Skrish_iyer 		case B_MODULE_UNINIT:
13225b6a6f1Skrish_iyer 			return B_OK;
13325b6a6f1Skrish_iyer 
13425b6a6f1Skrish_iyer 		default:
13525b6a6f1Skrish_iyer 			break;
13625b6a6f1Skrish_iyer 	}
13725b6a6f1Skrish_iyer 
13825b6a6f1Skrish_iyer 	return B_ERROR;
13925b6a6f1Skrish_iyer }
14025b6a6f1Skrish_iyer 
14125b6a6f1Skrish_iyer 
14225b6a6f1Skrish_iyer driver_module_info mmc_bus_device_module = {
14325b6a6f1Skrish_iyer 	{
144ff76d2dfSAdrien Destugues 		MMC_BUS_DEVICE_NAME,
14525b6a6f1Skrish_iyer 		0,
14625b6a6f1Skrish_iyer 		std_ops
14725b6a6f1Skrish_iyer 	},
14825b6a6f1Skrish_iyer 	NULL, // supported devices
14925b6a6f1Skrish_iyer 	NULL, // register node
15025b6a6f1Skrish_iyer 	mmc_bus_init,
15125b6a6f1Skrish_iyer 	mmc_bus_uninit,
152dedbe94eSAdrien Destugues 	mmc_bus_register_child,
15325b6a6f1Skrish_iyer 	NULL, // rescan
15425b6a6f1Skrish_iyer 	mmc_bus_removed,
15525b6a6f1Skrish_iyer 	NULL, // suspend
15625b6a6f1Skrish_iyer 	NULL // resume
15725b6a6f1Skrish_iyer };
15825b6a6f1Skrish_iyer 
15925b6a6f1Skrish_iyer 
16062eaf4c0SAdrien Destugues mmc_device_interface mmc_bus_controller_module = {
16162eaf4c0SAdrien Destugues 	{
16225b6a6f1Skrish_iyer 		{
163ff76d2dfSAdrien Destugues 			MMC_BUS_MODULE_NAME,
16425b6a6f1Skrish_iyer 			0,
16525b6a6f1Skrish_iyer 			&std_ops
16625b6a6f1Skrish_iyer 		},
16725b6a6f1Skrish_iyer 
16825b6a6f1Skrish_iyer 		NULL, // supported devices
16925b6a6f1Skrish_iyer 		mmc_bus_added_device,
17025b6a6f1Skrish_iyer 		NULL,
17125b6a6f1Skrish_iyer 		NULL,
17225b6a6f1Skrish_iyer 		NULL
17362eaf4c0SAdrien Destugues 	},
174*74b60970SAnarchos 	mmc_bus_execute_command,
175*74b60970SAnarchos 	mmc_bus_read_naive
17625b6a6f1Skrish_iyer };
17725b6a6f1Skrish_iyer 
17825b6a6f1Skrish_iyer 
17925b6a6f1Skrish_iyer module_dependency module_dependencies[] = {
18025b6a6f1Skrish_iyer 	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
18125b6a6f1Skrish_iyer 	{}
18225b6a6f1Skrish_iyer };
18325b6a6f1Skrish_iyer 
18425b6a6f1Skrish_iyer 
18525b6a6f1Skrish_iyer module_info* modules[] = {
18625b6a6f1Skrish_iyer 	(module_info*)&mmc_bus_controller_module,
18725b6a6f1Skrish_iyer 	(module_info*)&mmc_bus_device_module,
18825b6a6f1Skrish_iyer 	NULL
18925b6a6f1Skrish_iyer };
190