Hi All,
I am developing a WDF GPIO controller driver for our own ACPI GPIO. However, the ACPI document about the GPIO pins are all marked as PMIO instead of MMIO.
Our Linux team uses inb/outb to read/write the registers. I am wondering how the WDF GPIO controller driver read/write such registers.
From the sample code, the GPIO controller driver would read/write GPIO registers in the way CmResourceTypeMemory and CmResourceTypeCollection. In my case, I think CmResourceTypeCollection would be returned by calling WdfCmResourceListGetDescriptor. Do I need to call READ_PORT_*** API to read the registers?
Thanks,
Marshall
You should be able to do something like this:
// Walk through the resource list and store each GPIO in `pDevExt->ConnectionIds`.
resource_count = WdfCmResourceListGetCount(ResourcesTranslated);
for (index = 0; index < resource_count; ++index)
{
descriptor = WdfCmResourceListGetDescriptor(ResourcesTranslated, index);
switch (descriptor->Type)
{
// This memory resource supplies the base of the device registers.
case CmResourceTypeConnection:
// Check against expected connection type
if ((descriptor->u.Connection.Class ==
CM_RESOURCE_CONNECTION_CLASS_GPIO) &&
(descriptor->u.Connection.Type ==
CM_RESOURCE_CONNECTION_TYPE_GPIO_IO))
{
pDevExt->ConnectionIds[io_resource_index].LowPart =
descriptor->u.Connection.IdLowPart;
pDevExt->ConnectionIds[io_resource_index].HighPart =
descriptor->u.Connection.IdHighPart;
}
break;
default:
break;
}
}
Then when you want to read/write from one you’ll need to find the RESOURCE_HUB request string for the GPIO by doing something like:
// Find the RESOURCE_HUB request string for this GPIO pin
RtlInitEmptyUnicodeString(&resource_string,
resource_string_buffer,
sizeof(resource_string_buffer));
status = RESOURCE_HUB_CREATE_PATH_FROM_ID(
&resource_string,
pDevExt->ConnectionIds[pin_number].LowPart,
pDevExt->ConnectionIds[pin_number].HighPart);
Once you have the request string you’ll have to open the IoTarget by name with WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME
.
From there you can use WdfIoTargetFormatRequestForIoctl
with the IOCTL_GPIO_READ_PINS/IOCTL_GPIO_WRITE_PINS
ioctls do the equivalent of your Linux teams inb/outb IO.
Once you’ve formated the request you can use WdfRequestSend
to send it.
1 Like
It is difficult for me to believe that any modern product is still using the x86 I/O ports. How do you even handle that on an ARM system that doesn’t have the special instructions?
1 Like