xref: /haiku/src/add-ons/kernel/bus_managers/mmc/mmc_module.cpp (revision 215b685f7fd7d2f9a04260bb164be31ddc001ea2)
125b6a6f1Skrish_iyer /*
27a160a86SAdrien Destugues  * Copyright 2018-2021 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
77a160a86SAdrien Destugues  *		Adrien Destugues, pulkomandy@pulkomandy.tk
825b6a6f1Skrish_iyer  */
925b6a6f1Skrish_iyer #include "mmc_bus.h"
1025b6a6f1Skrish_iyer 
1125b6a6f1Skrish_iyer 
12ff76d2dfSAdrien Destugues #define	MMC_BUS_DEVICE_NAME "bus_managers/mmc_bus/device/v1"
13ff76d2dfSAdrien Destugues 
14ff76d2dfSAdrien Destugues 
1525b6a6f1Skrish_iyer device_manager_info* gDeviceManager = NULL;
1625b6a6f1Skrish_iyer 
1725b6a6f1Skrish_iyer 
1825b6a6f1Skrish_iyer static status_t
mmc_bus_init(device_node * node,void ** _device)1925b6a6f1Skrish_iyer mmc_bus_init(device_node* node, void** _device)
2025b6a6f1Skrish_iyer {
2125b6a6f1Skrish_iyer 	CALLED();
2225b6a6f1Skrish_iyer 	MMCBus* device = new(std::nothrow) MMCBus(node);
2325b6a6f1Skrish_iyer 	if (device == NULL) {
2425b6a6f1Skrish_iyer 		ERROR("Unable to allocate MMC bus\n");
2525b6a6f1Skrish_iyer 		return B_NO_MEMORY;
2625b6a6f1Skrish_iyer 	}
2725b6a6f1Skrish_iyer 
2825b6a6f1Skrish_iyer 	status_t result = device->InitCheck();
2925b6a6f1Skrish_iyer 	if (result != B_OK) {
3025b6a6f1Skrish_iyer 		TRACE("failed to set up mmc bus device object\n");
3125b6a6f1Skrish_iyer 		return result;
3225b6a6f1Skrish_iyer 	}
3325b6a6f1Skrish_iyer 	TRACE("MMC bus object created\n");
3425b6a6f1Skrish_iyer 
3525b6a6f1Skrish_iyer 	*_device = device;
3625b6a6f1Skrish_iyer 	return B_OK;
3725b6a6f1Skrish_iyer }
3825b6a6f1Skrish_iyer 
3925b6a6f1Skrish_iyer 
4025b6a6f1Skrish_iyer static void
mmc_bus_uninit(void * _device)4125b6a6f1Skrish_iyer mmc_bus_uninit(void* _device)
4225b6a6f1Skrish_iyer {
4325b6a6f1Skrish_iyer 	CALLED();
4425b6a6f1Skrish_iyer 	MMCBus* device = (MMCBus*)_device;
4525b6a6f1Skrish_iyer 	delete device;
4625b6a6f1Skrish_iyer }
4725b6a6f1Skrish_iyer 
4825b6a6f1Skrish_iyer 
49dedbe94eSAdrien Destugues static status_t
mmc_bus_register_child(void * _device)50dedbe94eSAdrien Destugues mmc_bus_register_child(void* _device)
51dedbe94eSAdrien Destugues {
5224136793SAdrien Destugues 	// Nothing to do, child devices are registered by the scanning thread
53dedbe94eSAdrien Destugues 	return B_OK;
54dedbe94eSAdrien Destugues }
55dedbe94eSAdrien Destugues 
56dedbe94eSAdrien Destugues 
5725b6a6f1Skrish_iyer static void
mmc_bus_removed(void * _device)5825b6a6f1Skrish_iyer mmc_bus_removed(void* _device)
5925b6a6f1Skrish_iyer {
6025b6a6f1Skrish_iyer 	CALLED();
6125b6a6f1Skrish_iyer }
6225b6a6f1Skrish_iyer 
6325b6a6f1Skrish_iyer 
6425b6a6f1Skrish_iyer status_t
mmc_bus_added_device(device_node * parent)6525b6a6f1Skrish_iyer mmc_bus_added_device(device_node* parent)
6625b6a6f1Skrish_iyer {
6725b6a6f1Skrish_iyer 	CALLED();
6825b6a6f1Skrish_iyer 
6925b6a6f1Skrish_iyer 	device_attr attributes[] = {
70*215b685fSX512 		{ B_DEVICE_BUS, B_STRING_TYPE, { .string = "mmc"}},
71*215b685fSX512 		{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { .string = "MMC bus root"}},
7225b6a6f1Skrish_iyer 		{ NULL }
7325b6a6f1Skrish_iyer 	};
7425b6a6f1Skrish_iyer 
75ff76d2dfSAdrien Destugues 	return gDeviceManager->register_node(parent, MMC_BUS_DEVICE_NAME,
7625b6a6f1Skrish_iyer 		attributes, NULL, NULL);
7725b6a6f1Skrish_iyer }
7825b6a6f1Skrish_iyer 
7925b6a6f1Skrish_iyer 
8025b6a6f1Skrish_iyer static status_t
mmc_bus_execute_command(device_node * node,void * cookie,uint16_t rca,uint8_t command,uint32_t argument,uint32_t * result)815ec64c5cSAdrien Destugues mmc_bus_execute_command(device_node* node, void* cookie, uint16_t rca,
825ec64c5cSAdrien Destugues 	uint8_t command, uint32_t argument, uint32_t* result)
8362eaf4c0SAdrien Destugues {
8462eaf4c0SAdrien Destugues 	TRACE("In mmc_bus_execute_command\n");
8562eaf4c0SAdrien Destugues 
8674b60970SAnarchos 	MMCBus* bus = (MMCBus*)cookie;
8774b60970SAnarchos 
8874b60970SAnarchos 	bus->AcquireBus();
89522c141dSAdrien Destugues 	status_t error = bus->ExecuteCommand(rca, command, argument, result);
9074b60970SAnarchos 	bus->ReleaseBus();
915ec64c5cSAdrien Destugues 
9274b60970SAnarchos 	return error;
9374b60970SAnarchos }
9474b60970SAnarchos 
9574b60970SAnarchos 
9674b60970SAnarchos static status_t
mmc_bus_do_io(device_node * node,void * cookie,uint16_t rca,uint8_t command,IOOperation * operation,bool offsetAsSectors)975ec64c5cSAdrien Destugues mmc_bus_do_io(device_node* node, void* cookie, uint16_t rca, uint8_t command,
98d1fee57dSAdrien Destugues 	IOOperation* operation, bool offsetAsSectors)
9974b60970SAnarchos {
10074b60970SAnarchos 	MMCBus* bus = (MMCBus*)cookie;
1017a160a86SAdrien Destugues 	status_t result = B_OK;
1027a160a86SAdrien Destugues 
1035ec64c5cSAdrien Destugues 	bus->AcquireBus();
104d1fee57dSAdrien Destugues 	result = bus->DoIO(rca, command, operation, offsetAsSectors);
10574b60970SAnarchos 	bus->ReleaseBus();
1065ec64c5cSAdrien Destugues 
10774b60970SAnarchos 	return result;
10862eaf4c0SAdrien Destugues }
10962eaf4c0SAdrien Destugues 
11062eaf4c0SAdrien Destugues 
11134552f8eSAdrien Destugues static void
mmc_bus_set_width(device_node * node,void * cookie,int width)1125ec64c5cSAdrien Destugues mmc_bus_set_width(device_node* node, void* cookie, int width)
11334552f8eSAdrien Destugues {
11434552f8eSAdrien Destugues 	MMCBus* bus = (MMCBus*)cookie;
11534552f8eSAdrien Destugues 
11634552f8eSAdrien Destugues 	bus->AcquireBus();
11734552f8eSAdrien Destugues 	bus->SetBusWidth(width);
11834552f8eSAdrien Destugues 	bus->ReleaseBus();
11934552f8eSAdrien Destugues }
12034552f8eSAdrien Destugues 
12134552f8eSAdrien Destugues 
12262eaf4c0SAdrien Destugues static status_t
std_ops(int32 op,...)12325b6a6f1Skrish_iyer std_ops(int32 op, ...)
12425b6a6f1Skrish_iyer {
12525b6a6f1Skrish_iyer 	switch (op) {
12625b6a6f1Skrish_iyer 		case B_MODULE_INIT:
12725b6a6f1Skrish_iyer 			// Nothing to do
12825b6a6f1Skrish_iyer 		case B_MODULE_UNINIT:
12925b6a6f1Skrish_iyer 			return B_OK;
13025b6a6f1Skrish_iyer 
13125b6a6f1Skrish_iyer 		default:
13225b6a6f1Skrish_iyer 			break;
13325b6a6f1Skrish_iyer 	}
13425b6a6f1Skrish_iyer 
13525b6a6f1Skrish_iyer 	return B_ERROR;
13625b6a6f1Skrish_iyer }
13725b6a6f1Skrish_iyer 
13825b6a6f1Skrish_iyer 
13925b6a6f1Skrish_iyer driver_module_info mmc_bus_device_module = {
14025b6a6f1Skrish_iyer 	{
141ff76d2dfSAdrien Destugues 		MMC_BUS_DEVICE_NAME,
14225b6a6f1Skrish_iyer 		0,
14325b6a6f1Skrish_iyer 		std_ops
14425b6a6f1Skrish_iyer 	},
14525b6a6f1Skrish_iyer 	NULL, // supported devices
14625b6a6f1Skrish_iyer 	NULL, // register node
14725b6a6f1Skrish_iyer 	mmc_bus_init,
14825b6a6f1Skrish_iyer 	mmc_bus_uninit,
149dedbe94eSAdrien Destugues 	mmc_bus_register_child,
15025b6a6f1Skrish_iyer 	NULL, // rescan
15125b6a6f1Skrish_iyer 	mmc_bus_removed,
15225b6a6f1Skrish_iyer 	NULL, // suspend
15325b6a6f1Skrish_iyer 	NULL // resume
15425b6a6f1Skrish_iyer };
15525b6a6f1Skrish_iyer 
15625b6a6f1Skrish_iyer 
15762eaf4c0SAdrien Destugues mmc_device_interface mmc_bus_controller_module = {
15862eaf4c0SAdrien Destugues 	{
15925b6a6f1Skrish_iyer 		{
160ff76d2dfSAdrien Destugues 			MMC_BUS_MODULE_NAME,
16125b6a6f1Skrish_iyer 			0,
16225b6a6f1Skrish_iyer 			&std_ops
16325b6a6f1Skrish_iyer 		},
16425b6a6f1Skrish_iyer 
16525b6a6f1Skrish_iyer 		NULL, // supported devices
16625b6a6f1Skrish_iyer 		mmc_bus_added_device,
16725b6a6f1Skrish_iyer 		NULL,
16825b6a6f1Skrish_iyer 		NULL,
16925b6a6f1Skrish_iyer 		NULL
17062eaf4c0SAdrien Destugues 	},
17174b60970SAnarchos 	mmc_bus_execute_command,
17234552f8eSAdrien Destugues 	mmc_bus_do_io,
17334552f8eSAdrien Destugues 	mmc_bus_set_width
17425b6a6f1Skrish_iyer };
17525b6a6f1Skrish_iyer 
17625b6a6f1Skrish_iyer 
17725b6a6f1Skrish_iyer module_dependency module_dependencies[] = {
17825b6a6f1Skrish_iyer 	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
17925b6a6f1Skrish_iyer 	{}
18025b6a6f1Skrish_iyer };
18125b6a6f1Skrish_iyer 
18225b6a6f1Skrish_iyer 
18325b6a6f1Skrish_iyer module_info* modules[] = {
18425b6a6f1Skrish_iyer 	(module_info*)&mmc_bus_controller_module,
18525b6a6f1Skrish_iyer 	(module_info*)&mmc_bus_device_module,
18625b6a6f1Skrish_iyer 	NULL
18725b6a6f1Skrish_iyer };
188