[RFC] RPMI pin control specification
From: Charles Perry
Date: Tue Oct 27 2026 - 17:43:21 EST
Hello,
There is currently a spec under review for adding a pin control service to
Risc-V Platform Management Interface (RPMI). RPMI is a messaging interface
between an application processor and a platform controller for riscv.
I would like to invite Linux reviewers and anybody who see this message to
take a look at the spec and make comments. Your feedback is valuable as
there will eventually be a pinctrl driver for Linux which will have to plug
into Linux's pinctrl API.
You can consult the RPMI pin control spec on github and make comments in
github:
https://github.com/riscv-non-isa/riscv-rpmi/pull/163/commits
I've also copied the spec at commit 9f35c1fca06a ("pinctrl: Add PIN_CONTROL
service group") in this email for your convenience. You can make comments
here if you prefer.
Thanks,
Charles
PIN_CONTROL RPMI spec follows:
=== Service Group - PIN_CONTROL (SERVICEGROUP_ID: 0x0012)
This service group is used to discover and control the pins (or pads) of the
system. Services defined in this group are used to enumerate pins and pin
functions, to select the function performed by a pin, and to set or get the
electrical configuration of a pin.
A pin is a physical interface of the system to the outside world. Since the
number of pins in a system is limited, a pin is generally multiplexed and can
perform one of several functions at a time. A function represents a single
signal which a pin can carry, for example the clock or data signal of an I2C
interface, or a general purpose input/output (GPIO).
A function may provide GPIO capability which is indicated in the function
attributes. Once a GPIO capable function is enabled on a pin, the application
processor can control the direction of the pin using the `INPUT_MODE` and
`OUTPUT_MODE` configuration types, drive the pin level using the
`OUTPUT_VALUE` configuration type, and read the pin level using the
`INPUT_VALUE` configuration type. The configuration types are listed in
<<pinctrl-config-types>>. The application processor can discover the GPIO
capable functions of a pin by retrieving the functions of the pin through
the `PINCTRL_GET_PIN_FUNCTIONS` service and then checking the GPIO
capability flag of each function through the
`PINCTRL_GET_FUNCTION_ATTRIBUTES` service. A platform should define a GPIO
capable function for each pin which the application processor can control
directly.
The platform controls which clients can access each pin and function. A
client can claim exclusive control of a pin at runtime, as described in
<<pinctrl-ownership>>, and the event of this service group notifies a client
when another client claims or releases a pin.
During initialization, the application processor must first discover the
optional services implemented by the platform microcontroller through the
`PINCTRL_GET_ATTRIBUTES` service. It can then enable the event of this
service group, claim exclusive control of the pins it needs, and set their
functions and configurations.
[#pinctrl-pin-organization]
==== Pin Organization
Each pin is identified by a `PIN_ID` and each function by a `FUNCTION_ID`.
These are separate identifier spaces, and each identifier is a 32-bit integer
which is sequential and starts from `0`.
The pins on which a function can be enabled are the candidate pins of the
function, and the functions which a pin can perform are the candidate
functions of the pin. The `PINCTRL_GET_PIN_FUNCTIONS` service returns the
candidate functions of a pin, and the application processor obtains the
candidate pins of a function from the candidate functions of each pin.
Each function represents a single signal, for example `i2c0_sda` or
`uart0_tx`, and each signal is represented by one function. A function has
more than one candidate pin when the platform can route its signal to
different pads. For example, if the platform can route the transmit signal
of `uart0` to either the pad `gpio0_4` or the pad `gpio1_2`, then the function
`uart0_tx` has both pads as candidate pins. The pin on which the application
processor enables each function is described through hardware description
mechanisms such as device tree or ACPI.
Enabling a function on a pin replaces the function currently enabled on the
pin, and the application processor does not need to disable the current
function first. Enabling a function on a pin must not change the function of
any other pin, except when the force flag of the `PINCTRL_SET_FUNCTION`
service is set as described below.
A function is enabled on at most one pin at a time, unless the platform
needs to route its signal to more than one pin, for example to drive the same
output signal on several pads. In that case, the platform indicates through
the multiple pins flag returned by the `PINCTRL_GET_FUNCTION_ATTRIBUTES`
service that the function can be enabled on more than one of its candidate
pins at the same time.
If the multiple pins flag of a function is not set and the function is
already enabled on another pin, then the result of the `PINCTRL_SET_FUNCTION`
service depends on the force flag passed in the request:
* If the force flag is not set, then the platform microcontroller must fail
the service with `RPMI_ERR_INVALID_STATE`, and the function remains enabled
on the other pin.
* If the force flag is set, then the platform microcontroller disables the
function on the other pin, which is left with no function enabled, and
enables the function on the requested pin.
In both cases, the platform microcontroller fails the service with
`RPMI_ERR_DENIED` if the calling client is not allowed to access the other
pin, so that a client never learns about the function enabled on a pin which
it is not allowed to access. The force flag never removes a function from a
pin which is claimed by another client, and the platform microcontroller
fails the service with `RPMI_ERR_BUSY` in that case.
The services of this service group reference a pin or a function only through
its numeric identifier. Pins and functions also have names which are
NULL-terminated ASCII strings up to 32-bytes. Names are informational and
implementation defined, and the platform may choose any naming scheme. The
recommended naming convention is:
* Pin names identify the physical pad of the system, for example the pad
name defined in the system datasheet such as `gpio0_0`, and should not
encode a function which the pin can perform.
* Function names identify the signal, for example `i2c0_sda` or
`uart0_tx`.
* Function names which provide GPIO capability should include `gpio` in the
name, for example `gpio0_0`.
[#pinctrl-ownership]
==== Pin Ownership
Ownership provides exclusive control of a pin at runtime. A client can claim
exclusive control of a pin through the `PINCTRL_REQUEST` service and release
it through the `PINCTRL_RELEASE` service. The platform defines which pins a
client is allowed to access, whereas ownership defines which client is
currently using a pin. The ownership services are optional, and the rules
below apply only if the `PINCTRL_GET_ATTRIBUTES` service indicates that they
are implemented. Otherwise, pins are never claimed and the event described in
<<pinctrl-notifications>> is not supported.
A pin which is not claimed can be used by any client which is allowed to
access it, but the pin is not protected against the other clients, so a
client should claim a pin before it sets the function or the configuration
of the pin. While a pin is claimed by a client, the pin is unavailable to all
other clients. The `PINCTRL_REQUEST`, `PINCTRL_GET_FUNCTION`,
`PINCTRL_SET_FUNCTION`, `PINCTRL_GET_CONFIG`, and `PINCTRL_SET_CONFIG`
services requested by another client for the pin fail with `RPMI_ERR_BUSY`.
The services which discover pins and functions, including the
`PINCTRL_GET_SUPPORTED_CONFIG` and `PINCTRL_GET_SUPPORTED_CONFIG_VALUES`
services, are not affected by claims. If
the calling client is not allowed to access the pin, then the platform
microcontroller fails the service with `RPMI_ERR_DENIED` instead of
`RPMI_ERR_BUSY`, so that a client never learns about the claims on a pin
which it is not allowed to access.
Claiming and releasing a pin do not change the function or the configuration
of the pin. A client which claims a pin sets the function and the
configuration which it requires, since another client may have changed them
while the pin was not claimed by the client.
A client learns when another client claims or releases a pin through the
event described in <<pinctrl-notifications>>. The event informs the
application processor, but the status returned by the services remains
authoritative, since notifications are delivered only if the RPMI transport
provides the P2A channel and the client has enabled them.
[#pinctrl-config-types]
==== Pin Configuration Types
The configuration of a pin is expressed as a list of configuration type and
configuration value pairs. The following table lists the standard
configuration types and the encoding of their corresponding configuration
values. The platform microcontroller must apply the configuration according
to the configuration value. For configuration types with enable/disable
semantics, the configuration value `0` must disable the configuration and the
configuration value `1` must enable it.
The configuration types which a pin supports are returned by the
`PINCTRL_GET_SUPPORTED_CONFIG` service. The supported values of a
configuration type for a particular pin are platform specific. The
application processor can discover them
through the optional `PINCTRL_GET_SUPPORTED_CONFIG_VALUES` service, or
through hardware description mechanisms such as device tree or ACPI.
The configuration types are classified into fixed-value and range-value
configuration types based on their configuration type value as listed in
<<table_pinctrl_config_types>>. This classification applies to both the
standard and the implementation specific configuration types.
* *Fixed-value* configuration types (`0x00000000 - 0x3FFFFFFF` and
`0x80000000 - 0xBFFFFFFF`) have a fixed set of configuration values, such
as enable/disable. The application processor does not need to discover the
supported values of these configuration types. The implementation specific
fixed-value configuration types must only support the configuration value
`0` to disable and `1` to enable the configuration.
* *Range-value* configuration types (`0x40000000 - 0x7FFFFFFF` and
`0xC0000000 - 0xFFFFFFFF`) have numeric or implementation defined
configuration values. The supported values of these configuration types
are platform specific and can be discovered as described above.
[#table_pinctrl_config_types]
.Pin Configuration Types
[cols="2,3,5", width=100%, align="center", options="header"]
|===
| Value
| Configuration Type
| Configuration Value
| 0x0
| DEFAULT
| `1`: Set the pin to the implementation defined default configuration. +
This configuration type is write-only and valid only with the
`PINCTRL_SET_CONFIG` service. The `PINCTRL_GET_CONFIG` service must fail
with `RPMI_ERR_INVALID_PARAM` if this configuration type is passed.
| 0x1
| BIAS_BUS_HOLD
| `0`: Disable +
`1`: Enable
| 0x2
| BIAS_DISABLE
| `0`: Disable +
`1`: Enable
| 0x3
| BIAS_HIGH_IMPEDANCE
| `0`: Disable +
`1`: Enable
| 0x4
| BIAS_PULL_DEFAULT
| `0`: Disable +
`1`: Enable
| 0x5
| DRIVE_OPEN_DRAIN
| `0`: Disable +
`1`: Enable
| 0x6
| DRIVE_OPEN_SOURCE
| `0`: Disable +
`1`: Enable
| 0x7
| DRIVE_PUSH_PULL
| `0`: Disable +
`1`: Enable
| 0x8
| INPUT_MODE
| `0`: Disable +
`1`: Enable
| 0x9
| PULL_MODE
| `0`: Implementation defined default +
`1`: Pull-up +
`2`: Pull-down +
`3`: None
| 0xA
| INPUT_VALUE
| `0`: Low +
`1`: High +
This configuration type is read-only and valid only with the
`PINCTRL_GET_CONFIG` service. The `PINCTRL_SET_CONFIG` service must fail
with `RPMI_ERR_INVALID_PARAM` if this configuration type is passed.
| 0xB
| INPUT_SCHMITT
| `0`: Disable +
`1`: Enable
| 0xC
| LOW_POWER_MODE
| `0`: Disable +
`1`: Enable
| 0xD
| OUTPUT_MODE
| `0`: Disable +
`1`: Enable
| 0xE
| OUTPUT_VALUE
| `0`: Low +
`1`: High
| 0xF - 0x3FFFFFFF
| _Reserved_
|
| 0x40000000
| BIAS_PULL_UP
| Pull-up strength in ohms. +
`0`: Implementation defined default strength.
| 0x40000001
| BIAS_PULL_DOWN
| Pull-down strength in ohms. +
`0`: Implementation defined default strength.
| 0x40000002
| DRIVE_STRENGTH
| Drive strength in microamperes (uA).
| 0x40000003
| INPUT_DEBOUNCE
| Debounce time in microseconds (us).
| 0x40000004
| POWER_SOURCE
| Implementation defined power source selector.
| 0x40000005
| SLEW_RATE
| Implementation defined slew rate value. +
`0`: Slowest implementation defined slew rate.
| 0x40000006 - 0x7FFFFFFF
| _Reserved_
|
| 0x80000000 - 0xBFFFFFFF
| Implementation specific fixed-value
| `0`: Disable +
`1`: Enable
| 0xC0000000 - 0xFFFFFFFF
| Implementation specific range-value
| Implementation defined.
|===
The following table lists the services in the PIN_CONTROL service group:
[#table_pinctrl_services]
.PIN_CONTROL Services
[cols="1, 3, 2, 1", width=100%, align="center", options="header"]
|===
| Service ID
| Service Name
| Request Type
| RPMI Version
| 0x01
| PINCTRL_ENABLE_NOTIFICATION
| NORMAL_REQUEST
| 2.0
| 0x02
| PINCTRL_GET_ATTRIBUTES
| NORMAL_REQUEST
| 2.0
| 0x03
| PINCTRL_GET_PIN_ATTRIBUTES
| NORMAL_REQUEST
| 2.0
| 0x04
| PINCTRL_GET_FUNCTION_ATTRIBUTES
| NORMAL_REQUEST
| 2.0
| 0x05
| PINCTRL_GET_PIN_FUNCTIONS
| NORMAL_REQUEST
| 2.0
| 0x06
| PINCTRL_REQUEST
| NORMAL_REQUEST
| 2.0
| 0x07
| PINCTRL_RELEASE
| NORMAL_REQUEST
| 2.0
| 0x08
| PINCTRL_GET_FUNCTION
| NORMAL_REQUEST
| 2.0
| 0x09
| PINCTRL_SET_FUNCTION
| NORMAL_REQUEST
| 2.0
| 0x0A
| PINCTRL_GET_SUPPORTED_CONFIG
| NORMAL_REQUEST
| 2.0
| 0x0B
| PINCTRL_GET_SUPPORTED_CONFIG_VALUES
| NORMAL_REQUEST
| 2.0
| 0x0C
| PINCTRL_GET_CONFIG
| NORMAL_REQUEST
| 2.0
| 0x0D
| PINCTRL_SET_CONFIG
| NORMAL_REQUEST
| 2.0
|===
The services `PINCTRL_REQUEST`, `PINCTRL_RELEASE`, and
`PINCTRL_GET_SUPPORTED_CONFIG_VALUES` are optional. The application processor
can discover whether these services are implemented through the `FLAGS` field
returned by the `PINCTRL_GET_ATTRIBUTES` service.
[#pinctrl-notifications]
==== Notifications
The platform microcontroller notifies a client when another client claims or
releases a pin which the client is allowed to access, so that the client
knows which pins are currently claimed by the other clients. A client is not
notified about the pins which it claims or releases itself. The event is
supported only if the ownership services are implemented, and the platform
microcontroller sends it to a client only if the client has enabled it
through the `PINCTRL_ENABLE_NOTIFICATION` service.
The `PINCTRL_CLAIM_CHANGE` event reports for each pin whether the pin is
currently claimed or released, rather than each individual claim and release,
so that the event remains correct when the platform microcontroller merges
the claims and releases which occur before it sends a notification message.
Each event reports all the pins which were claimed or released since the
platform microcontroller last sent the event to the client. If the pins do
not fit into a single notification message, then the platform microcontroller
sends them in multiple notification messages.
[#table_pinctrl_events]
.PIN_CONTROL Notification Events
[cols="1, 2, 6a, 2", width=100%, align="center", options="header"]
|===
| Event ID
| Name
| Event Data
| Description
| 0x01
| PINCTRL_CLAIM_CHANGE
|
[cols="1,1,5a", options="header"]
!===
! Word
! Type
! Description
! 0
! uint32[2 * N]
! Array of `N` pairs where each pair is composed of two words in the
following format:
`PAIR[0]`: `PIN_ID`, the pin ID of a pin which another client has claimed
or released.
`PAIR[1]`: `CLAIM_STATE`, the current claim state of the pin.
----
0x0: Released. The pin is not claimed by any client.
0x1: Claimed. The pin is claimed by another client.
0x2 - 0xFFFFFFFF: Reserved.
----
The value `N` is specified by the `EVENT_DATALEN` field of the RPMI
notification event divided by `8`.
!===
| One or more pins have been claimed or released by another client.
|===
==== Service: PINCTRL_ENABLE_NOTIFICATION (SERVICE_ID: 0x01)
This service allows the application processor to subscribe to `PIN_CONTROL`
service group notifications. The platform may optionally support notifications
for events that may occur. The platform microcontroller can send these
notification messages to the application processor if they are implemented and
the application processor has subscribed to them. The supported events are
described in <<pinctrl-notifications>>.
Refer to <<table_common_ennotification_request_data>> for Request Data and
<<table_common_ennotification_response_data>> for Response Data.
==== Service: PINCTRL_GET_ATTRIBUTES (SERVICE_ID: 0x02)
This service is used to discover the number of pins and functions available
in the system, and the optional services implemented by the platform
microcontroller.
[#table_pinctrl_getattrs_request_data]
.Request Data
[cols="1", width=100%, align="center", options="header"]
|===
| NA
|===
[#table_pinctrl_getattrs_response_data]
.Response Data
[cols="1, 3, 1, 7a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="4,6", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Service completed successfully.
!===
- Other errors <<table_error_codes>>.
| 1
| FLAGS
| uint32
|
[cols="1,5a", options="header"]
!===
! Bits
! Description
! [31:2]
! _Reserved_ and must be `0`.
! [1]
! Configuration value discovery service support.
----
0b0: PINCTRL_GET_SUPPORTED_CONFIG_VALUES service is not implemented.
0b1: PINCTRL_GET_SUPPORTED_CONFIG_VALUES service is implemented.
----
! [0]
! Ownership services support.
----
0b0: PINCTRL_REQUEST and PINCTRL_RELEASE services are not implemented,
and pins are never claimed.
0b1: PINCTRL_REQUEST and PINCTRL_RELEASE services are implemented.
----
!===
| 2
| NUM_PINS
| uint32
| Number of pins available in the system.
| 3
| NUM_FUNCTIONS
| uint32
| Number of functions available in the system.
|===
==== Service: PINCTRL_GET_PIN_ATTRIBUTES (SERVICE_ID: 0x03)
This service provides the attributes of a pin, including its name, represented
as a 32-byte array of ASCII strings, and the physical location of its pad on
the package.
[#table_pinctrl_getpinattrs_request_data]
.Request Data
[cols="1, 3, 2, 10", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
|===
[#table_pinctrl_getpinattrs_response_data]
.Response Data
[cols="1, 3, 2, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Service completed successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID` is invalid.
! RPMI_ERR_DENIED
! The application processor is not allowed to access this pin.
!===
- Other errors <<table_error_codes>>.
| 1
| FLAGS
| uint32
| _Reserved_ and must be `0`.
| 2:9
| PIN_NAME
| uint8[32]
| Pin name, a NULL-terminated ASCII string up to 32-bytes.
| 10:13
| PAD_LOCATION
| uint8[16]
| Physical pad location of the pin on the package, a NULL-terminated ASCII
string up to 16-bytes, for example `5` for a numbered pin package or
`AE10` for a ball grid array package. An empty string implies the pad
location is not provided.
|===
==== Service: PINCTRL_GET_FUNCTION_ATTRIBUTES (SERVICE_ID: 0x04)
This service provides the attributes of a function, including the number of
candidate pins of the function and its name, represented as a 32-byte array
of ASCII strings.
[#table_pinctrl_getfuncattrs_request_data]
.Request Data
[cols="1, 3, 2, 10", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| FUNCTION_ID
| uint32
| Function ID.
|===
[#table_pinctrl_getfuncattrs_response_data]
.Response Data
[cols="1, 3, 2, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Service completed successfully.
! RPMI_ERR_INVALID_PARAM
! `FUNCTION_ID` is invalid.
! RPMI_ERR_DENIED
! The application processor is not allowed to access this function.
!===
- Other errors <<table_error_codes>>.
| 1
| FLAGS
| uint32
|
[cols="1,5a", options="header"]
!===
! Bits
! Description
! [31:2]
! _Reserved_ and must be `0`.
! [1]
! Multiple pins.
----
0b0: Function can be enabled on at most one pin at a time.
0b1: Function can be enabled on more than one of its candidate
pins at the same time.
----
! [0]
! GPIO capability.
----
0b0: Function does not provide GPIO capability.
0b1: Function provides GPIO capability.
----
!===
| 2
| NUM_PINS
| uint32
| Number of candidate pins of this function.
| 3:10
| FUNCTION_NAME
| uint8[32]
| Function name, a NULL-terminated ASCII string up to 32-bytes.
|===
==== Service: PINCTRL_GET_PIN_FUNCTIONS (SERVICE_ID: 0x05)
This service is used to get the list of candidate functions of a pin, which
are the functions which the pin can perform. For example, if the pin
`gpio0_0` can perform the functions `i2c0_sda`, `pwm0`, and `gpio0_0`, then
this service returns the function IDs of these three functions.
The message can pass the `FUNCTION_INDEX` which is the index to the first
function ID to be described in the returned function ID array. If all
function IDs are required, then this index value can be `0`.
If the total number of words required to store all function IDs exceeds the
available words in the message DATA field, then the platform microcontroller
will return the function IDs which can be accommodated in one message and set
the `RETURNED` field to the number of function IDs returned and the
`REMAINING` field to the number of remaining function IDs.
When the `REMAINING` field is not `0`, the application processor must call
this service again with the appropriate `FUNCTION_INDEX` set to get the
remaining function IDs.
[#table_pinctrl_getpinfuncs_request_data]
.Request Data
[cols="1, 3, 2, 10", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
| 1
| FUNCTION_INDEX
| uint32
| Index of the first function ID to be returned in the function ID array.
|===
[#table_pinctrl_getpinfuncs_response_data]
.Response Data
[cols="1, 3, 2, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Service completed successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID` or `FUNCTION_INDEX` is invalid.
! RPMI_ERR_DENIED
! The application processor is not allowed to access this pin.
!===
- Other errors <<table_error_codes>>.
| 1
| FLAGS
| uint32
| _Reserved_ and must be `0`.
| 2
| REMAINING
| uint32
| Remaining number of function IDs.
| 3
| RETURNED
| uint32
| Number of function IDs returned, which is `N`.
| 4
| FUNCTION_ID[N]
| uint32[N]
| Function IDs of the candidate functions of this pin, in numerically
increasing order.
|===
==== Service: PINCTRL_REQUEST (SERVICE_ID: 0x06)
This service is used to request exclusive control of a pin. On success, the
pin becomes unavailable to any other client until it is released through the
`PINCTRL_RELEASE` service.
This service is optional. The application processor can discover whether this
service is implemented through the `FLAGS` field returned by the
`PINCTRL_GET_ATTRIBUTES` service.
[#table_pinctrl_request_request_data]
.Request Data
[cols="1, 2, 2, 11", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
|===
[#table_pinctrl_request_response_data]
.Response Data
[cols="1, 2, 2, 11a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Exclusive control of the pin granted successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID` is invalid.
! RPMI_ERR_NOT_SUPPORTED
! This service is not implemented.
! RPMI_ERR_DENIED
! The application processor is not allowed to access this pin.
! RPMI_ERR_BUSY
! The pin is claimed by another client.
! RPMI_ERR_ALREADY
! The calling client already has exclusive control of this pin.
!===
- Other errors <<table_error_codes>>.
|===
==== Service: PINCTRL_RELEASE (SERVICE_ID: 0x07)
This service is used to release exclusive control of a pin which was
previously acquired through the `PINCTRL_REQUEST` service. The platform
microcontroller must fail this service with `RPMI_ERR_INVALID_STATE` if the
calling client does not have exclusive control of the pin.
This service is optional. The application processor can discover whether this
service is implemented through the `FLAGS` field returned by the
`PINCTRL_GET_ATTRIBUTES` service.
[#table_pinctrl_release_request_data]
.Request Data
[cols="1, 2, 2, 11", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
|===
[#table_pinctrl_release_response_data]
.Response Data
[cols="1, 2, 2, 11a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Pin released successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID` is invalid.
! RPMI_ERR_NOT_SUPPORTED
! This service is not implemented.
! RPMI_ERR_DENIED
! The application processor is not allowed to access this pin.
! RPMI_ERR_INVALID_STATE
! The calling client does not have exclusive control of this pin.
!===
- Other errors <<table_error_codes>>.
|===
==== Service: PINCTRL_GET_FUNCTION (SERVICE_ID: 0x08)
This service is used to get the function currently enabled on a pin.
[#table_pinctrl_getfunction_request_data]
.Request Data
[cols="1, 3, 1, 10", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
|===
[#table_pinctrl_getfunction_response_data]
.Response Data
[cols="1, 3, 1, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Service completed successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID` is invalid.
! RPMI_ERR_DENIED
! The application processor is not allowed to access this pin.
! RPMI_ERR_BUSY
! The pin is claimed by another client.
!===
- Other errors <<table_error_codes>>.
| 1
| FUNCTION_ID
| uint32
| Function ID of the function currently enabled on the pin, or `0xFFFFFFFF`
if no function is currently enabled.
|===
==== Service: PINCTRL_SET_FUNCTION (SERVICE_ID: 0x09)
This service is used to select the function to be enabled on a pin. Enabling
a function on a pin replaces the function currently enabled on the pin, and
enabling the function which is already enabled on the pin completes
successfully without any change. If the function is already enabled on
another pin and its multiple pins flag is not set, then the force flag
selects whether the service fails or moves the function to this pin. The
rules which apply when the function of a pin changes are described in
<<pinctrl-pin-organization>>.
[#table_pinctrl_setfunction_request_data]
.Request Data
[cols="1, 3, 1, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
| 1
| FLAGS
| uint32
|
[cols="1,6a", options="header"]
!===
! Bits
! Description
! [31:1]
! _Reserved_ and must be `0`.
! [0]
! Force.
----
0b0: Fail if the function is already enabled on another pin and
its multiple pins flag is not set.
0b1: Disable the function on the other pin on which it is enabled,
and enable it on this pin.
----
!===
| 2
| FUNCTION_ID
| uint32
| Function ID of the function to be enabled on the pin. A value `0xFFFFFFFF`
implies no function to be enabled on the pin.
|===
[#table_pinctrl_setfunction_response_data]
.Response Data
[cols="1, 3, 1, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,6", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Service completed successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID` or `FUNCTION_ID` is invalid.
! RPMI_ERR_NOT_SUPPORTED
! The function is not a candidate function of the pin, or this service is
not implemented.
! RPMI_ERR_DENIED
! The application processor is not allowed to access this pin, this
function, or another pin on which the function is already enabled while the
multiple pins flag of the function is not set.
! RPMI_ERR_BUSY
! The pin is claimed by another client, or the force flag is set and the
function is enabled on another pin which is claimed by another client.
! RPMI_ERR_INVALID_STATE
! The function is already enabled on another pin which the application
processor is allowed to access, the multiple pins flag of the function is
not set, and the force flag is not set.
!===
- Other errors <<table_error_codes>>.
|===
==== Service: PINCTRL_GET_SUPPORTED_CONFIG (SERVICE_ID: 0x0A)
This service is used to get the list of configuration types which are
supported by a pin, including the implementation specific configuration
types. The application processor gets and sets only the configuration types
which this service returns for the pin.
The message can pass the `TYPE_INDEX` which is the index to the first
configuration type to be described in the returned array. If all
configuration types are required, then this index value can be `0`.
If the total number of words required to store all configuration types
exceeds the available words in the message DATA field, then the platform
microcontroller will return the configuration types which can be
accommodated in one message and set the `RETURNED` field to the number of
configuration types returned and the `REMAINING` field to the number of
remaining configuration types.
When the `REMAINING` field is not `0`, the application processor must call
this service again with the appropriate `TYPE_INDEX` set to get the remaining
configuration types.
[#table_pinctrl_getsuppconfig_request_data]
.Request Data
[cols="1, 3, 1, 10", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
| 1
| TYPE_INDEX
| uint32
| Index of the first configuration type to be returned in the array.
|===
[#table_pinctrl_getsuppconfig_response_data]
.Response Data
[cols="1, 3, 1, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Service completed successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID` or `TYPE_INDEX` is invalid.
! RPMI_ERR_DENIED
! The application processor is not allowed to access this pin.
!===
- Other errors <<table_error_codes>>.
| 1
| FLAGS
| uint32
| _Reserved_ and must be `0`.
| 2
| REMAINING
| uint32
| Remaining number of configuration types.
| 3
| RETURNED
| uint32
| Number of configuration types returned, which is `N`.
| 4
| CONFIG_TYPE[N]
| uint32[N]
| Configuration types supported by this pin as listed in
<<table_pinctrl_config_types>>, in numerically increasing order.
|===
==== Service: PINCTRL_GET_SUPPORTED_CONFIG_VALUES (SERVICE_ID: 0x0B)
This service is used to get the values of a configuration type which are
supported by a pin. For example, this service can return the drive strength
values supported by a pin.
This service is optional. The application processor can discover whether
this service is implemented through the `FLAGS` field returned by the
`PINCTRL_GET_ATTRIBUTES` service. If this service is not implemented, then
the supported values must be discovered through hardware description
mechanisms such as device tree or ACPI.
The supported values are returned either as a discrete list of values or
as a linear range. The linear range is returned as three words which are
the minimum value, the maximum value, and the step between two successive
values. The value format flag in the `FLAGS` field of the response
indicates the format of the returned values.
The message can pass the `VALUE_INDEX` which is the index to the first
value to be described in the returned array. If all values are required,
then this index value can be `0`. For the linear range format, the
`VALUE_INDEX` must be `0`.
If the total number of words required to store all values exceeds the
available words in the message DATA field, then the platform
microcontroller will return the values which can be accommodated in one
message and set the `RETURNED` field to the number of values returned and
the `REMAINING` field to the number of remaining values.
[#table_pinctrl_getsuppconfigvals_request_data]
.Request Data
[cols="1, 3, 1, 10", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
| 1
| CONFIG_TYPE
| uint32
| Configuration type as listed in <<table_pinctrl_config_types>>.
| 2
| VALUE_INDEX
| uint32
| Index of the first supported value to be described in the returned
array.
|===
[#table_pinctrl_getsuppconfigvals_response_data]
.Response Data
[cols="1, 2, 1, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Supported values returned successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID`, `CONFIG_TYPE`, or `VALUE_INDEX` is invalid.
! RPMI_ERR_NOT_SUPPORTED
! The configuration type is not supported by the pin, or this service is
not implemented.
! RPMI_ERR_DENIED
! The application processor is not allowed to access this pin.
!===
- Other errors <<table_error_codes>>.
| 1
| FLAGS
| uint32
|
[cols="1,5a", options="header"]
!===
! Bits
! Description
! [31:1]
! _Reserved_ and must be `0`.
! [0]
! Value format.
----
0b0: Discrete list of values.
0b1: Linear range.
----
!===
| 2
| REMAINING
| uint32
| Remaining number of supported values to be returned.
| 3
| RETURNED
| uint32
| Number of supported values returned in this request, which is `N`. For
the linear range format, this field is `3`.
| 4
| VALUE[N]
| uint32[N]
| Array of `N` supported values in numerically increasing order for the
discrete list format, or three words which are the minimum value, the
maximum value, and the step for the linear range format.
|===
==== Service: PINCTRL_GET_CONFIG (SERVICE_ID: 0x0C)
This service is used to get the value of a configuration type of a pin. The
application processor requests only the configuration types which the
`PINCTRL_GET_SUPPORTED_CONFIG` service returns for the pin. The function
currently enabled on the pin is returned by the `PINCTRL_GET_FUNCTION`
service.
[#table_pinctrl_getconfig_request_data]
.Request Data
[cols="1, 3, 1, 10", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
| 1
| CONFIG_TYPE
| uint32
| Configuration type whose value is to be returned as listed in
<<table_pinctrl_config_types>>.
|===
[#table_pinctrl_getconfig_response_data]
.Response Data
[cols="1, 3, 1, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Service completed successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID` or `CONFIG_TYPE` is invalid, including the write-only `DEFAULT`
configuration type.
! RPMI_ERR_NOT_SUPPORTED
! The configuration type passed in `CONFIG_TYPE` is not supported by the
pin, or this service is not implemented.
! RPMI_ERR_DENIED
! The application processor is not allowed to get the configuration of
this pin.
! RPMI_ERR_BUSY
! The pin is claimed by another client.
!===
- Other errors <<table_error_codes>>.
| 1
| CONFIG_VALUE
| uint32
| Configuration value of the configuration type passed in `CONFIG_TYPE`.
|===
==== Service: PINCTRL_SET_CONFIG (SERVICE_ID: 0x0D)
This service is used to set the configuration of a pin. The service allows
multiple configurations to be set in a single request through an array of
configuration type and value pairs. The application processor sets only the
configuration types which the `PINCTRL_GET_SUPPORTED_CONFIG` service returns
for the pin.
If the total number of words required to store all configuration type and
value pairs exceeds the available words in the message DATA field, then the
application processor must send multiple requests. The `FLAGS` field must
have the final request flag set to `1` in the last request of such a sequence
and set to `0` in all preceding requests. If all pairs fit in a single
request, then the final request flag must be set to `1`.
If this service fails, then the configurations already applied by previous
requests of the sequence and by the preceding pairs of the failing request
remain applied. The platform microcontroller does not revert previously
applied configurations.
[#table_pinctrl_setconfig_request_data]
.Request Data
[cols="1, 3, 2, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| PIN_ID
| uint32
| Pin ID.
| 1
| FLAGS
| uint32
|
[cols="1,5a", options="header"]
!===
! Bits
! Description
! [31:1]
! _Reserved_ and must be `0`.
! [0]
! Final request.
----
0b0: More configuration requests for this pin will follow.
0b1: This is the final configuration request for this pin.
----
!===
| 2
| NUM_CONFIGS
| uint32
| Number of configuration type and value pairs in this request, which is
`N`.
| 3
| CONFIG[N]
| uint32[2 * N]
| Array of `N` pairs sorted in numerically increasing configuration type
order where each pair is composed of two words in the following format:
`PAIR[0]`: `CONFIG_TYPE`, the configuration type as listed in
<<table_pinctrl_config_types>>.
`PAIR[1]`: `CONFIG_VALUE`, the configuration value.
|===
[#table_pinctrl_setconfig_response_data]
.Response Data
[cols="1, 2, 1, 10a", width=100%, align="center", options="header"]
|===
| Word
| Name
| Type
| Description
| 0
| STATUS
| int32
| Return error code.
[cols="5,5", options="header"]
!===
! Error Code
! Description
! RPMI_SUCCESS
! Service completed successfully.
! RPMI_ERR_INVALID_PARAM
! `PIN_ID`, `NUM_CONFIGS`, or a configuration type or value is invalid,
including the read-only `INPUT_VALUE` configuration type.
! RPMI_ERR_NOT_SUPPORTED
! One or more configuration types are not supported by the pin, or this
service is not implemented.
! RPMI_ERR_DENIED
! The application processor is not allowed to set the configuration of
this pin.
! RPMI_ERR_BUSY
! The pin is claimed by another client.
!===
- Other errors <<table_error_codes>>.
|===
--
Thanks,
Charles